/ components / messages / AttachmentMessage.tsx
AttachmentMessage.tsx
  1  import { c as _c } from "react/compiler-runtime";
  2  // biome-ignore-all assist/source/organizeImports: ANT-ONLY import markers must not be reordered
  3  import React, { useMemo } from 'react';
  4  import { Ansi, Box, Text } from '../../ink.js';
  5  import type { Attachment } from 'src/utils/attachments.js';
  6  import type { NullRenderingAttachmentType } from './nullRenderingAttachments.js';
  7  import { useAppState } from '../../state/AppState.js';
  8  import { getDisplayPath } from 'src/utils/file.js';
  9  import { formatFileSize } from 'src/utils/format.js';
 10  import { MessageResponse } from '../MessageResponse.js';
 11  import { basename, sep } from 'path';
 12  import { UserTextMessage } from './UserTextMessage.js';
 13  import { DiagnosticsDisplay } from '../DiagnosticsDisplay.js';
 14  import { getContentText } from 'src/utils/messages.js';
 15  import type { Theme } from 'src/utils/theme.js';
 16  import { UserImageMessage } from './UserImageMessage.js';
 17  import { toInkColor } from '../../utils/ink.js';
 18  import { jsonParse } from '../../utils/slowOperations.js';
 19  import { plural } from '../../utils/stringUtils.js';
 20  import { isEnvTruthy } from '../../utils/envUtils.js';
 21  import { isAgentSwarmsEnabled } from '../../utils/agentSwarmsEnabled.js';
 22  import { tryRenderPlanApprovalMessage, formatTeammateMessageContent } from './PlanApprovalMessage.js';
 23  import { BLACK_CIRCLE } from '../../constants/figures.js';
 24  import { TeammateMessageContent } from './UserTeammateMessage.js';
 25  import { isShutdownApproved } from '../../utils/teammateMailbox.js';
 26  import { CtrlOToExpand } from '../CtrlOToExpand.js';
 27  import { FilePathLink } from '../FilePathLink.js';
 28  import { feature } from 'bun:bundle';
 29  import { useSelectedMessageBg } from '../messageActions.js';
 30  type Props = {
 31    addMargin: boolean;
 32    attachment: Attachment;
 33    verbose: boolean;
 34    isTranscriptMode?: boolean;
 35  };
 36  export function AttachmentMessage({
 37    attachment,
 38    addMargin,
 39    verbose,
 40    isTranscriptMode
 41  }: Props): React.ReactNode {
 42    const bg = useSelectedMessageBg();
 43    // Hoisted to mount-time — per-message component, re-renders on every scroll.
 44    const isDemoEnv = feature('EXPERIMENTAL_SKILL_SEARCH') ?
 45    // biome-ignore lint/correctness/useHookAtTopLevel: feature() is a compile-time constant
 46    useMemo(() => isEnvTruthy(process.env.IS_DEMO), []) : false;
 47    // Handle teammate_mailbox BEFORE switch
 48    if (isAgentSwarmsEnabled() && attachment.type === 'teammate_mailbox') {
 49      // Filter out idle notifications BEFORE counting - they are hidden in the UI
 50      // so showing them in the count would be confusing ("2 messages in mailbox:" with nothing shown)
 51      const visibleMessages = attachment.messages.filter(msg => {
 52        if (isShutdownApproved(msg.text)) {
 53          return false;
 54        }
 55        try {
 56          const parsed = jsonParse(msg.text);
 57          return parsed?.type !== 'idle_notification' && parsed?.type !== 'teammate_terminated';
 58        } catch {
 59          return true; // Non-JSON messages are visible
 60        }
 61      });
 62      if (visibleMessages.length === 0) {
 63        return null;
 64      }
 65      return <Box flexDirection="column">
 66          {visibleMessages.map((msg_0, idx) => {
 67          // Try to parse as JSON for task_assignment messages
 68          let parsedMsg: {
 69            type?: string;
 70            taskId?: string;
 71            subject?: string;
 72            assignedBy?: string;
 73          } | null = null;
 74          try {
 75            parsedMsg = jsonParse(msg_0.text);
 76          } catch {
 77            // Not JSON, treat as plain text
 78          }
 79          if (parsedMsg?.type === 'task_assignment') {
 80            return <Box key={idx} paddingLeft={2}>
 81                  <Text>{BLACK_CIRCLE} </Text>
 82                  <Text>Task assigned: </Text>
 83                  <Text bold>#{parsedMsg.taskId}</Text>
 84                  <Text> - {parsedMsg.subject}</Text>
 85                  <Text dimColor> (from {parsedMsg.assignedBy || msg_0.from})</Text>
 86                </Box>;
 87          }
 88  
 89          // Note: idle_notification messages already filtered out above
 90  
 91          // Try to render as plan approval message (request or response)
 92          const planApprovalElement = tryRenderPlanApprovalMessage(msg_0.text, msg_0.from);
 93          if (planApprovalElement) {
 94            return <React.Fragment key={idx}>{planApprovalElement}</React.Fragment>;
 95          }
 96  
 97          // Plain text message - sender header with chevron, truncated content
 98          const inkColor = toInkColor(msg_0.color);
 99          const formattedContent = formatTeammateMessageContent(msg_0.text) ?? msg_0.text;
100          return <TeammateMessageContent key={idx} displayName={msg_0.from} inkColor={inkColor} content={formattedContent} summary={msg_0.summary} isTranscriptMode={isTranscriptMode} />;
101        })}
102        </Box>;
103    }
104  
105    // skill_discovery rendered here (not in the switch) so the 'skill_discovery'
106    // string literal stays inside a feature()-guarded block. A case label can't
107    // be conditionally eliminated; an if-body can.
108    if (feature('EXPERIMENTAL_SKILL_SEARCH')) {
109      if (attachment.type === 'skill_discovery') {
110        if (attachment.skills.length === 0) return null;
111        // Ant users get shortIds inline so they can /skill-feedback while the
112        // turn is still fresh. External users (when this un-gates) just see
113        // names — shortId is undefined outside ant builds anyway.
114        const names = attachment.skills.map(s => s.shortId ? `${s.name} [${s.shortId}]` : s.name).join(', ');
115        const firstId = attachment.skills[0]?.shortId;
116        const hint = "external" === 'ant' && !isDemoEnv && firstId ? ` · /skill-feedback ${firstId} 1=wrong 2=noisy 3=good [comment]` : '';
117        return <Line>
118            <Text bold>{attachment.skills.length}</Text> relevant{' '}
119            {plural(attachment.skills.length, 'skill')}: {names}
120            {hint && <Text dimColor>{hint}</Text>}
121          </Line>;
122      }
123    }
124  
125    // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check -- teammate_mailbox/skill_discovery handled before switch
126    switch (attachment.type) {
127      case 'directory':
128        return <Line>
129            Listed directory <Text bold>{attachment.displayPath + sep}</Text>
130          </Line>;
131      case 'file':
132      case 'already_read_file':
133        if (attachment.content.type === 'notebook') {
134          return <Line>
135              Read <Text bold>{attachment.displayPath}</Text> (
136              {attachment.content.file.cells.length} cells)
137            </Line>;
138        }
139        if (attachment.content.type === 'file_unchanged') {
140          return <Line>
141              Read <Text bold>{attachment.displayPath}</Text> (unchanged)
142            </Line>;
143        }
144        return <Line>
145            Read <Text bold>{attachment.displayPath}</Text> (
146            {attachment.content.type === 'text' ? `${attachment.content.file.numLines}${attachment.truncated ? '+' : ''} lines` : formatFileSize(attachment.content.file.originalSize)}
147            )
148          </Line>;
149      case 'compact_file_reference':
150        return <Line>
151            Referenced file <Text bold>{attachment.displayPath}</Text>
152          </Line>;
153      case 'pdf_reference':
154        return <Line>
155            Referenced PDF <Text bold>{attachment.displayPath}</Text> (
156            {attachment.pageCount} pages)
157          </Line>;
158      case 'selected_lines_in_ide':
159        return <Line>
160            ⧉ Selected{' '}
161            <Text bold>{attachment.lineEnd - attachment.lineStart + 1}</Text>{' '}
162            lines from <Text bold>{attachment.displayPath}</Text> in{' '}
163            {attachment.ideName}
164          </Line>;
165      case 'nested_memory':
166        return <Line>
167            Loaded <Text bold>{attachment.displayPath}</Text>
168          </Line>;
169      case 'relevant_memories':
170        // Usually absorbed into a CollapsedReadSearchGroup (collapseReadSearch.ts)
171        // so this only renders when the preceding tool was non-collapsible (Edit,
172        // Write) and no group was open. Match CollapsedReadSearchContent's style:
173        // 2-space gutter, dim text, count only — filenames/content in ctrl+o.
174        return <Box flexDirection="column" marginTop={addMargin ? 1 : 0} backgroundColor={bg}>
175            <Box flexDirection="row">
176              <Box minWidth={2} />
177              <Text dimColor>
178                Recalled <Text bold>{attachment.memories.length}</Text>{' '}
179                {attachment.memories.length === 1 ? 'memory' : 'memories'}
180                {!isTranscriptMode && <>
181                    {' '}
182                    <CtrlOToExpand />
183                  </>}
184              </Text>
185            </Box>
186            {(verbose || isTranscriptMode) && attachment.memories.map(m => <Box key={m.path} flexDirection="column">
187                  <MessageResponse>
188                    <Text dimColor>
189                      <FilePathLink filePath={m.path}>
190                        {basename(m.path)}
191                      </FilePathLink>
192                    </Text>
193                  </MessageResponse>
194                  {isTranscriptMode && <Box paddingLeft={5}>
195                      <Text>
196                        <Ansi>{m.content}</Ansi>
197                      </Text>
198                    </Box>}
199                </Box>)}
200          </Box>;
201      case 'dynamic_skill':
202        {
203          const skillCount = attachment.skillNames.length;
204          return <Line>
205            Loaded{' '}
206            <Text bold>
207              {skillCount} {plural(skillCount, 'skill')}
208            </Text>{' '}
209            from <Text bold>{attachment.displayPath}</Text>
210          </Line>;
211        }
212      case 'skill_listing':
213        {
214          if (attachment.isInitial) {
215            return null;
216          }
217          return <Line>
218            <Text bold>{attachment.skillCount}</Text>{' '}
219            {plural(attachment.skillCount, 'skill')} available
220          </Line>;
221        }
222      case 'agent_listing_delta':
223        {
224          if (attachment.isInitial || attachment.addedTypes.length === 0) {
225            return null;
226          }
227          const count = attachment.addedTypes.length;
228          return <Line>
229            <Text bold>{count}</Text> agent {plural(count, 'type')} available
230          </Line>;
231        }
232      case 'queued_command':
233        {
234          const text = typeof attachment.prompt === 'string' ? attachment.prompt : getContentText(attachment.prompt) || '';
235          const hasImages = attachment.imagePasteIds && attachment.imagePasteIds.length > 0;
236          return <Box flexDirection="column">
237            <UserTextMessage addMargin={addMargin} param={{
238              text,
239              type: 'text'
240            }} verbose={verbose} isTranscriptMode={isTranscriptMode} />
241            {hasImages && attachment.imagePasteIds?.map(id => <UserImageMessage key={id} imageId={id} />)}
242          </Box>;
243        }
244      case 'plan_file_reference':
245        return <Line>
246            Plan file referenced ({getDisplayPath(attachment.planFilePath)})
247          </Line>;
248      case 'invoked_skills':
249        {
250          if (attachment.skills.length === 0) {
251            return null;
252          }
253          const skillNames = attachment.skills.map(s_0 => s_0.name).join(', ');
254          return <Line>Skills restored ({skillNames})</Line>;
255        }
256      case 'diagnostics':
257        return <DiagnosticsDisplay attachment={attachment} verbose={verbose} />;
258      case 'mcp_resource':
259        return <Line>
260            Read MCP resource <Text bold>{attachment.name}</Text> from{' '}
261            {attachment.server}
262          </Line>;
263      case 'command_permissions':
264        // The skill success message is rendered by SkillTool's renderToolResultMessage,
265        // so we don't render anything here to avoid duplicate messages.
266        return null;
267      case 'async_hook_response':
268        {
269          // SessionStart hook completions are only shown in verbose mode
270          if (attachment.hookEvent === 'SessionStart' && !verbose) {
271            return null;
272          }
273          // Generally hide async hook completion messages unless in verbose mode
274          if (!verbose && !isTranscriptMode) {
275            return null;
276          }
277          return <Line>
278            Async hook <Text bold>{attachment.hookEvent}</Text> completed
279          </Line>;
280        }
281      case 'hook_blocking_error':
282        {
283          // Stop hooks are rendered as a summary in SystemStopHookSummaryMessage
284          if (attachment.hookEvent === 'Stop' || attachment.hookEvent === 'SubagentStop') {
285            return null;
286          }
287          // Show stderr to the user so they can understand why the hook blocked
288          const stderr = attachment.blockingError.blockingError.trim();
289          return <>
290            <Line color="error">
291              {attachment.hookName} hook returned blocking error
292            </Line>
293            {stderr ? <Line color="error">{stderr}</Line> : null}
294          </>;
295        }
296      case 'hook_non_blocking_error':
297        {
298          // Stop hooks are rendered as a summary in SystemStopHookSummaryMessage
299          if (attachment.hookEvent === 'Stop' || attachment.hookEvent === 'SubagentStop') {
300            return null;
301          }
302          // Full hook output is logged to debug log via hookEvents.ts
303          return <Line color="error">{attachment.hookName} hook error</Line>;
304        }
305      case 'hook_error_during_execution':
306        // Stop hooks are rendered as a summary in SystemStopHookSummaryMessage
307        if (attachment.hookEvent === 'Stop' || attachment.hookEvent === 'SubagentStop') {
308          return null;
309        }
310        // Full hook output is logged to debug log via hookEvents.ts
311        return <Line>{attachment.hookName} hook warning</Line>;
312      case 'hook_success':
313        // Full hook output is logged to debug log via hookEvents.ts
314        return null;
315      case 'hook_stopped_continuation':
316        // Stop hooks are rendered as a summary in SystemStopHookSummaryMessage
317        if (attachment.hookEvent === 'Stop' || attachment.hookEvent === 'SubagentStop') {
318          return null;
319        }
320        return <Line color="warning">
321            {attachment.hookName} hook stopped continuation: {attachment.message}
322          </Line>;
323      case 'hook_system_message':
324        return <Line>
325            {attachment.hookName} says: {attachment.content}
326          </Line>;
327      case 'hook_permission_decision':
328        {
329          const action = attachment.decision === 'allow' ? 'Allowed' : 'Denied';
330          return <Line>
331            {action} by <Text bold>{attachment.hookEvent}</Text> hook
332          </Line>;
333        }
334      case 'task_status':
335        return <TaskStatusMessage attachment={attachment} />;
336      case 'teammate_shutdown_batch':
337        return <Box flexDirection="row" width="100%" marginTop={1} backgroundColor={bg}>
338            <Text dimColor>{BLACK_CIRCLE} </Text>
339            <Text dimColor>
340              {attachment.count} {plural(attachment.count, 'teammate')} shut down
341              gracefully
342            </Text>
343          </Box>;
344      default:
345        // Exhaustiveness: every type reaching here must be in NULL_RENDERING_TYPES.
346        // If TS errors, a new Attachment type was added without a case above AND
347        // without an entry in NULL_RENDERING_TYPES — decide: render something (add
348        // a case) or render nothing (add to the array). Messages.tsx pre-filters
349        // these so this branch is defense-in-depth for other render paths.
350        //
351        // skill_discovery and teammate_mailbox are handled BEFORE the switch in
352        // runtime-gated blocks (feature() / isAgentSwarmsEnabled()) that TS can't
353        // narrow through — excluded here via type union (compile-time only, no emit).
354        attachment.type satisfies NullRenderingAttachmentType | 'skill_discovery' | 'teammate_mailbox';
355        return null;
356    }
357  }
358  type TaskStatusAttachment = Extract<Attachment, {
359    type: 'task_status';
360  }>;
361  function TaskStatusMessage(t0) {
362    const $ = _c(4);
363    const {
364      attachment
365    } = t0;
366    if (false && attachment.status === "killed") {
367      return null;
368    }
369    if (isAgentSwarmsEnabled() && attachment.taskType === "in_process_teammate") {
370      let t1;
371      if ($[0] !== attachment) {
372        t1 = <TeammateTaskStatus attachment={attachment} />;
373        $[0] = attachment;
374        $[1] = t1;
375      } else {
376        t1 = $[1];
377      }
378      return t1;
379    }
380    let t1;
381    if ($[2] !== attachment) {
382      t1 = <GenericTaskStatus attachment={attachment} />;
383      $[2] = attachment;
384      $[3] = t1;
385    } else {
386      t1 = $[3];
387    }
388    return t1;
389  }
390  function GenericTaskStatus(t0) {
391    const $ = _c(9);
392    const {
393      attachment
394    } = t0;
395    const bg = useSelectedMessageBg();
396    const statusText = attachment.status === "completed" ? "completed in background" : attachment.status === "killed" ? "stopped" : attachment.status === "running" ? "still running in background" : attachment.status;
397    let t1;
398    if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
399      t1 = <Text dimColor={true}>{BLACK_CIRCLE} </Text>;
400      $[0] = t1;
401    } else {
402      t1 = $[0];
403    }
404    let t2;
405    if ($[1] !== attachment.description) {
406      t2 = <Text bold={true}>{attachment.description}</Text>;
407      $[1] = attachment.description;
408      $[2] = t2;
409    } else {
410      t2 = $[2];
411    }
412    let t3;
413    if ($[3] !== statusText || $[4] !== t2) {
414      t3 = <Text dimColor={true}>Task "{t2}" {statusText}</Text>;
415      $[3] = statusText;
416      $[4] = t2;
417      $[5] = t3;
418    } else {
419      t3 = $[5];
420    }
421    let t4;
422    if ($[6] !== bg || $[7] !== t3) {
423      t4 = <Box flexDirection="row" width="100%" marginTop={1} backgroundColor={bg}>{t1}{t3}</Box>;
424      $[6] = bg;
425      $[7] = t3;
426      $[8] = t4;
427    } else {
428      t4 = $[8];
429    }
430    return t4;
431  }
432  function TeammateTaskStatus(t0) {
433    const $ = _c(16);
434    const {
435      attachment
436    } = t0;
437    const bg = useSelectedMessageBg();
438    let t1;
439    if ($[0] !== attachment.taskId) {
440      t1 = s => s.tasks[attachment.taskId];
441      $[0] = attachment.taskId;
442      $[1] = t1;
443    } else {
444      t1 = $[1];
445    }
446    const task = useAppState(t1);
447    if (task?.type !== "in_process_teammate") {
448      let t2;
449      if ($[2] !== attachment) {
450        t2 = <GenericTaskStatus attachment={attachment} />;
451        $[2] = attachment;
452        $[3] = t2;
453      } else {
454        t2 = $[3];
455      }
456      return t2;
457    }
458    let t2;
459    if ($[4] !== task.identity.color) {
460      t2 = toInkColor(task.identity.color);
461      $[4] = task.identity.color;
462      $[5] = t2;
463    } else {
464      t2 = $[5];
465    }
466    const agentColor = t2;
467    const statusText = attachment.status === "completed" ? "shut down gracefully" : attachment.status;
468    let t3;
469    if ($[6] === Symbol.for("react.memo_cache_sentinel")) {
470      t3 = <Text dimColor={true}>{BLACK_CIRCLE} </Text>;
471      $[6] = t3;
472    } else {
473      t3 = $[6];
474    }
475    let t4;
476    if ($[7] !== agentColor || $[8] !== task.identity.agentName) {
477      t4 = <Text color={agentColor} bold={true} dimColor={false}>@{task.identity.agentName}</Text>;
478      $[7] = agentColor;
479      $[8] = task.identity.agentName;
480      $[9] = t4;
481    } else {
482      t4 = $[9];
483    }
484    let t5;
485    if ($[10] !== statusText || $[11] !== t4) {
486      t5 = <Text dimColor={true}>Teammate{" "}{t4}{" "}{statusText}</Text>;
487      $[10] = statusText;
488      $[11] = t4;
489      $[12] = t5;
490    } else {
491      t5 = $[12];
492    }
493    let t6;
494    if ($[13] !== bg || $[14] !== t5) {
495      t6 = <Box flexDirection="row" width="100%" marginTop={1} backgroundColor={bg}>{t3}{t5}</Box>;
496      $[13] = bg;
497      $[14] = t5;
498      $[15] = t6;
499    } else {
500      t6 = $[15];
501    }
502    return t6;
503  }
504  // We allow setting dimColor to false here to help work around the dim-bold bug.
505  // https://github.com/chalk/chalk/issues/290
506  function Line(t0) {
507    const $ = _c(7);
508    const {
509      dimColor: t1,
510      children,
511      color
512    } = t0;
513    const dimColor = t1 === undefined ? true : t1;
514    const bg = useSelectedMessageBg();
515    let t2;
516    if ($[0] !== children || $[1] !== color || $[2] !== dimColor) {
517      t2 = <MessageResponse><Text color={color} dimColor={dimColor} wrap="wrap">{children}</Text></MessageResponse>;
518      $[0] = children;
519      $[1] = color;
520      $[2] = dimColor;
521      $[3] = t2;
522    } else {
523      t2 = $[3];
524    }
525    let t3;
526    if ($[4] !== bg || $[5] !== t2) {
527      t3 = <Box backgroundColor={bg}>{t2}</Box>;
528      $[4] = bg;
529      $[5] = t2;
530      $[6] = t3;
531    } else {
532      t3 = $[6];
533    }
534    return t3;
535  }
536  //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsInVzZU1lbW8iLCJBbnNpIiwiQm94IiwiVGV4dCIsIkF0dGFjaG1lbnQiLCJOdWxsUmVuZGVyaW5nQXR0YWNobWVudFR5cGUiLCJ1c2VBcHBTdGF0ZSIsImdldERpc3BsYXlQYXRoIiwiZm9ybWF0RmlsZVNpemUiLCJNZXNzYWdlUmVzcG9uc2UiLCJiYXNlbmFtZSIsInNlcCIsIlVzZXJUZXh0TWVzc2FnZSIsIkRpYWdub3N0aWNzRGlzcGxheSIsImdldENvbnRlbnRUZXh0IiwiVGhlbWUiLCJVc2VySW1hZ2VNZXNzYWdlIiwidG9JbmtDb2xvciIsImpzb25QYXJzZSIsInBsdXJhbCIsImlzRW52VHJ1dGh5IiwiaXNBZ2VudFN3YXJtc0VuYWJsZWQiLCJ0cnlSZW5kZXJQbGFuQXBwcm92YWxNZXNzYWdlIiwiZm9ybWF0VGVhbW1hdGVNZXNzYWdlQ29udGVudCIsIkJMQUNLX0NJUkNMRSIsIlRlYW1tYXRlTWVzc2FnZUNvbnRlbnQiLCJpc1NodXRkb3duQXBwcm92ZWQiLCJDdHJsT1RvRXhwYW5kIiwiRmlsZVBhdGhMaW5rIiwiZmVhdHVyZSIsInVzZVNlbGVjdGVkTWVzc2FnZUJnIiwiUHJvcHMiLCJhZGRNYXJnaW4iLCJhdHRhY2htZW50IiwidmVyYm9zZSIsImlzVHJhbnNjcmlwdE1vZGUiLCJBdHRhY2htZW50TWVzc2FnZSIsIlJlYWN0Tm9kZSIsImJnIiwiaXNEZW1vRW52IiwicHJvY2VzcyIsImVudiIsIklTX0RFTU8iLCJ0eXBlIiwidmlzaWJsZU1lc3NhZ2VzIiwibWVzc2FnZXMiLCJmaWx0ZXIiLCJtc2ciLCJ0ZXh0IiwicGFyc2VkIiwibGVuZ3RoIiwibWFwIiwiaWR4IiwicGFyc2VkTXNnIiwidGFza0lkIiwic3ViamVjdCIsImFzc2lnbmVkQnkiLCJmcm9tIiwicGxhbkFwcHJvdmFsRWxlbWVudCIsImlua0NvbG9yIiwiY29sb3IiLCJmb3JtYXR0ZWRDb250ZW50Iiwic3VtbWFyeSIsInNraWxscyIsIm5hbWVzIiwicyIsInNob3J0SWQiLCJuYW1lIiwiam9pbiIsImZpcnN0SWQiLCJoaW50IiwiZGlzcGxheVBhdGgiLCJjb250ZW50IiwiZmlsZSIsImNlbGxzIiwibnVtTGluZXMiLCJ0cnVuY2F0ZWQiLCJvcmlnaW5hbFNpemUiLCJwYWdlQ291bnQiLCJsaW5lRW5kIiwibGluZVN0YXJ0IiwiaWRlTmFtZSIsIm1lbW9yaWVzIiwibSIsInBhdGgiLCJza2lsbENvdW50Iiwic2tpbGxOYW1lcyIsImlzSW5pdGlhbCIsImFkZGVkVHlwZXMiLCJjb3VudCIsInByb21wdCIsImhhc0ltYWdlcyIsImltYWdlUGFzdGVJZHMiLCJpZCIsInBsYW5GaWxlUGF0aCIsInNlcnZlciIsImhvb2tFdmVudCIsInN0ZGVyciIsImJsb2NraW5nRXJyb3IiLCJ0cmltIiwiaG9va05hbWUiLCJtZXNzYWdlIiwiYWN0aW9uIiwiZGVjaXNpb24iLCJUYXNrU3RhdHVzQXR0YWNobWVudCIsIkV4dHJhY3QiLCJUYXNrU3RhdHVzTWVzc2FnZSIsInQwIiwiJCIsIl9jIiwic3RhdHVzIiwidGFza1R5cGUiLCJ0MSIsIkdlbmVyaWNUYXNrU3RhdHVzIiwic3RhdHVzVGV4dCIsIlN5bWJvbCIsImZvciIsInQyIiwiZGVzY3JpcHRpb24iLCJ0MyIsInQ0IiwiVGVhbW1hdGVUYXNrU3RhdHVzIiwidGFza3MiLCJ0YXNrIiwiaWRlbnRpdHkiLCJhZ2VudENvbG9yIiwiYWdlbnROYW1lIiwidDUiLCJ0NiIsIkxpbmUiLCJkaW1Db2xvciIsImNoaWxkcmVuIiwidW5kZWZpbmVkIl0sInNvdXJjZXMiOlsiQXR0YWNobWVudE1lc3NhZ2UudHN4Il0sInNvdXJjZXNDb250ZW50IjpbIi8vIGJpb21lLWlnbm9yZS1hbGwgYXNzaXN0L3NvdXJjZS9vcmdhbml6ZUltcG9ydHM6IEFOVC1PTkxZIGltcG9ydCBtYXJrZXJzIG11c3Qgbm90IGJlIHJlb3JkZXJlZFxuaW1wb3J0IFJlYWN0LCB7IHVzZU1lbW8gfSBmcm9tICdyZWFjdCdcbmltcG9ydCB7IEFuc2ksIEJveCwgVGV4dCB9IGZyb20gJy4uLy4uL2luay5qcydcbmltcG9ydCB0eXBlIHsgQXR0YWNobWVudCB9IGZyb20gJ3NyYy91dGlscy9hdHRhY2htZW50cy5qcydcbmltcG9ydCB0eXBlIHsgTnVsbFJlbmRlcmluZ0F0dGFjaG1lbnRUeXBlIH0gZnJvbSAnLi9udWxsUmVuZGVyaW5nQXR0YWNobWVudHMuanMnXG5pbXBvcnQgeyB1c2VBcHBTdGF0ZSB9IGZyb20gJy4uLy4uL3N0YXRlL0FwcFN0YXRlLmpzJ1xuaW1wb3J0IHsgZ2V0RGlzcGxheVBhdGggfSBmcm9tICdzcmMvdXRpbHMvZmlsZS5qcydcbmltcG9ydCB7IGZvcm1hdEZpbGVTaXplIH0gZnJvbSAnc3JjL3V0aWxzL2Zvcm1hdC5qcydcbmltcG9ydCB7IE1lc3NhZ2VSZXNwb25zZSB9IGZyb20gJy4uL01lc3NhZ2VSZXNwb25zZS5qcydcbmltcG9ydCB7IGJhc2VuYW1lLCBzZXAgfSBmcm9tICdwYXRoJ1xuaW1wb3J0IHsgVXNlclRleHRNZXNzYWdlIH0gZnJvbSAnLi9Vc2VyVGV4dE1lc3NhZ2UuanMnXG5pbXBvcnQgeyBEaWFnbm9zdGljc0Rpc3BsYXkgfSBmcm9tICcuLi9EaWFnbm9zdGljc0Rpc3BsYXkuanMnXG5pbXBvcnQgeyBnZXRDb250ZW50VGV4dCB9IGZyb20gJ3NyYy91dGlscy9tZXNzYWdlcy5qcydcbmltcG9ydCB0eXBlIHsgVGhlbWUgfSBmcm9tICdzcmMvdXRpbHMvdGhlbWUuanMnXG5pbXBvcnQgeyBVc2VySW1hZ2VNZXNzYWdlIH0gZnJvbSAnLi9Vc2VySW1hZ2VNZXNzYWdlLmpzJ1xuaW1wb3J0IHsgdG9JbmtDb2xvciB9IGZyb20gJy4uLy4uL3V0aWxzL2luay5qcydcbmltcG9ydCB7IGpzb25QYXJzZSB9IGZyb20gJy4uLy4uL3V0aWxzL3Nsb3dPcGVyYXRpb25zLmpzJ1xuaW1wb3J0IHsgcGx1cmFsIH0gZnJvbSAnLi4vLi4vdXRpbHMvc3RyaW5nVXRpbHMuanMnXG5pbXBvcnQgeyBpc0VudlRydXRoeSB9IGZyb20gJy4uLy4uL3V0aWxzL2VudlV0aWxzLmpzJ1xuaW1wb3J0IHsgaXNBZ2VudFN3YXJtc0VuYWJsZWQgfSBmcm9tICcuLi8uLi91dGlscy9hZ2VudFN3YXJtc0VuYWJsZWQuanMnXG5pbXBvcnQge1xuICB0cnlSZW5kZXJQbGFuQXBwcm92YWxNZXNzYWdlLFxuICBmb3JtYXRUZWFtbWF0ZU1lc3NhZ2VDb250ZW50LFxufSBmcm9tICcuL1BsYW5BcHByb3ZhbE1lc3NhZ2UuanMnXG5pbXBvcnQgeyBCTEFDS19DSVJDTEUgfSBmcm9tICcuLi8uLi9jb25zdGFudHMvZmlndXJlcy5qcydcbmltcG9ydCB7IFRlYW1tYXRlTWVzc2FnZUNvbnRlbnQgfSBmcm9tICcuL1VzZXJUZWFtbWF0ZU1lc3NhZ2UuanMnXG5pbXBvcnQgeyBpc1NodXRkb3duQXBwcm92ZWQgfSBmcm9tICcuLi8uLi91dGlscy90ZWFtbWF0ZU1haWxib3guanMnXG5pbXBvcnQgeyBDdHJsT1RvRXhwYW5kIH0gZnJvbSAnLi4vQ3RybE9Ub0V4cGFuZC5qcydcbmltcG9ydCB7IEZpbGVQYXRoTGluayB9IGZyb20gJy4uL0ZpbGVQYXRoTGluay5qcydcbmltcG9ydCB7IGZlYXR1cmUgfSBmcm9tICdidW46YnVuZGxlJ1xuaW1wb3J0IHsgdXNlU2VsZWN0ZWRNZXNzYWdlQmcgfSBmcm9tICcuLi9tZXNzYWdlQWN0aW9ucy5qcydcblxudHlwZSBQcm9wcyA9IHtcbiAgYWRkTWFyZ2luOiBib29sZWFuXG4gIGF0dGFjaG1lbnQ6IEF0dGFjaG1lbnRcbiAgdmVyYm9zZTogYm9vbGVhblxuICBpc1RyYW5zY3JpcHRNb2RlPzogYm9vbGVhblxufVxuXG5leHBvcnQgZnVuY3Rpb24gQXR0YWNobWVudE1lc3NhZ2Uoe1xuICBhdHRhY2htZW50LFxuICBhZGRNYXJnaW4sXG4gIHZlcmJvc2UsXG4gIGlzVHJhbnNjcmlwdE1vZGUsXG59OiBQcm9wcyk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIGNvbnN0IGJnID0gdXNlU2VsZWN0ZWRNZXNzYWdlQmcoKVxuICAvLyBIb2lzdGVkIHRvIG1vdW50LXRpbWUg4oCUIHBlci1tZXNzYWdlIGNvbXBvbmVudCwgcmUtcmVuZGVycyBvbiBldmVyeSBzY3JvbGwuXG4gIGNvbnN0IGlzRGVtb0VudiA9IGZlYXR1cmUoJ0VYUEVSSU1FTlRBTF9TS0lMTF9TRUFSQ0gnKVxuICAgID8gLy8gYmlvbWUtaWdub3JlIGxpbnQvY29ycmVjdG5lc3MvdXNlSG9va0F0VG9wTGV2ZWw6IGZlYXR1cmUoKSBpcyBhIGNvbXBpbGUtdGltZSBjb25zdGFudFxuICAgICAgdXNlTWVtbygoKSA9PiBpc0VudlRydXRoeShwcm9jZXNzLmVudi5JU19ERU1PKSwgW10pXG4gICAgOiBmYWxzZVxuICAvLyBIYW5kbGUgdGVhbW1hdGVfbWFpbGJveCBCRUZPUkUgc3dpdGNoXG4gIGlmIChpc0FnZW50U3dhcm1zRW5hYmxlZCgpICYmIGF0dGFjaG1lbnQudHlwZSA9PT0gJ3RlYW1tYXRlX21haWxib3gnKSB7XG4gICAgLy8gRmlsdGVyIG91dCBpZGxlIG5vdGlmaWNhdGlvbnMgQkVGT1JFIGNvdW50aW5nIC0gdGhleSBhcmUgaGlkZGVuIGluIHRoZSBVSVxuICAgIC8vIHNvIHNob3dpbmcgdGhlbSBpbiB0aGUgY291bnQgd291bGQgYmUgY29uZnVzaW5nIChcIjIgbWVzc2FnZXMgaW4gbWFpbGJveDpcIiB3aXRoIG5vdGhpbmcgc2hvd24pXG4gICAgY29uc3QgdmlzaWJsZU1lc3NhZ2VzID0gYXR0YWNobWVudC5tZXNzYWdlcy5maWx0ZXIobXNnID0+IHtcbiAgICAgIGlmIChpc1NodXRkb3duQXBwcm92ZWQobXNnLnRleHQpKSB7XG4gICAgICAgIHJldHVybiBmYWxzZVxuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGFyc2VkID0ganNvblBhcnNlKG1zZy50ZXh0KVxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIHBhcnNlZD8udHlwZSAhPT0gJ2lkbGVfbm90aWZpY2F0aW9uJyAmJlxuICAgICAgICAgIHBhcnNlZD8udHlwZSAhPT0gJ3RlYW1tYXRlX3Rlcm1pbmF0ZWQnXG4gICAgICAgIClcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICByZXR1cm4gdHJ1ZSAvLyBOb24tSlNPTiBtZXNzYWdlcyBhcmUgdmlzaWJsZVxuICAgICAgfVxuICAgIH0pXG5cbiAgICBpZiAodmlzaWJsZU1lc3NhZ2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIG51bGxcbiAgICB9XG4gICAgcmV0dXJuIChcbiAgICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiPlxuICAgICAgICB7dmlzaWJsZU1lc3NhZ2VzLm1hcCgobXNnLCBpZHgpID0+IHtcbiAgICAgICAgICAvLyBUcnkgdG8gcGFyc2UgYXMgSlNPTiBmb3IgdGFza19hc3NpZ25tZW50IG1lc3NhZ2VzXG4gICAgICAgICAgbGV0IHBhcnNlZE1zZzoge1xuICAgICAgICAgICAgdHlwZT86IHN0cmluZ1xuICAgICAgICAgICAgdGFza0lkPzogc3RyaW5nXG4gICAgICAgICAgICBzdWJqZWN0Pzogc3RyaW5nXG4gICAgICAgICAgICBhc3NpZ25lZEJ5Pzogc3RyaW5nXG4gICAgICAgICAgfSB8IG51bGwgPSBudWxsXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHBhcnNlZE1zZyA9IGpzb25QYXJzZShtc2cudGV4dClcbiAgICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIC8vIE5vdCBKU09OLCB0cmVhdCBhcyBwbGFpbiB0ZXh0XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKHBhcnNlZE1zZz8udHlwZSA9PT0gJ3Rhc2tfYXNzaWdubWVudCcpIHtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgIDxCb3gga2V5PXtpZHh9IHBhZGRpbmdMZWZ0PXsyfT5cbiAgICAgICAgICAgICAgICA8VGV4dD57QkxBQ0tfQ0lSQ0xFfSA8L1RleHQ+XG4gICAgICAgICAgICAgICAgPFRleHQ+VGFzayBhc3NpZ25lZDogPC9UZXh0PlxuICAgICAgICAgICAgICAgIDxUZXh0IGJvbGQ+I3twYXJzZWRNc2cudGFza0lkfTwvVGV4dD5cbiAgICAgICAgICAgICAgICA8VGV4dD4gLSB7cGFyc2VkTXNnLnN1YmplY3R9PC9UZXh0PlxuICAgICAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPiAoZnJvbSB7cGFyc2VkTXNnLmFzc2lnbmVkQnkgfHwgbXNnLmZyb219KTwvVGV4dD5cbiAgICAgICAgICAgICAgPC9Cb3g+XG4gICAgICAgICAgICApXG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gTm90ZTogaWRsZV9ub3RpZmljYXRpb24gbWVzc2FnZXMgYWxyZWFkeSBmaWx0ZXJlZCBvdXQgYWJvdmVcblxuICAgICAgICAgIC8vIFRyeSB0byByZW5kZXIgYXMgcGxhbiBhcHByb3ZhbCBtZXNzYWdlIChyZXF1ZXN0IG9yIHJlc3BvbnNlKVxuICAgICAgICAgIGNvbnN0IHBsYW5BcHByb3ZhbEVsZW1lbnQgPSB0cnlSZW5kZXJQbGFuQXBwcm92YWxNZXNzYWdlKFxuICAgICAgICAgICAgbXNnLnRleHQsXG4gICAgICAgICAgICBtc2cuZnJvbSxcbiAgICAgICAgICApXG4gICAgICAgICAgaWYgKHBsYW5BcHByb3ZhbEVsZW1lbnQpIHtcbiAgICAgICAgICAgIHJldHVybiAoXG4gICAgICAgICAgICAgIDxSZWFjdC5GcmFnbWVudCBrZXk9e2lkeH0+e3BsYW5BcHByb3ZhbEVsZW1lbnR9PC9SZWFjdC5GcmFnbWVudD5cbiAgICAgICAgICAgIClcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBQbGFpbiB0ZXh0IG1lc3NhZ2UgLSBzZW5kZXIgaGVhZGVyIHdpdGggY2hldnJvbiwgdHJ1bmNhdGVkIGNvbnRlbnRcbiAgICAgICAgICBjb25zdCBpbmtDb2xvciA9IHRvSW5rQ29sb3IobXNnLmNvbG9yKVxuICAgICAgICAgIGNvbnN0IGZvcm1hdHRlZENvbnRlbnQgPVxuICAgICAgICAgICAgZm9ybWF0VGVhbW1hdGVNZXNzYWdlQ29udGVudChtc2cudGV4dCkgPz8gbXNnLnRleHRcbiAgICAgICAgICByZXR1cm4gKFxuICAgICAgICAgICAgPFRlYW1tYXRlTWVzc2FnZUNvbnRlbnRcbiAgICAgICAgICAgICAga2V5PXtpZHh9XG4gICAgICAgICAgICAgIGRpc3BsYXlOYW1lPXttc2cuZnJvbX1cbiAgICAgICAgICAgICAgaW5rQ29sb3I9e2lua0NvbG9yfVxuICAgICAgICAgICAgICBjb250ZW50PXtmb3JtYXR0ZWRDb250ZW50fVxuICAgICAgICAgICAgICBzdW1tYXJ5PXttc2cuc3VtbWFyeX1cbiAgICAgICAgICAgICAgaXNUcmFuc2NyaXB0TW9kZT17aXNUcmFuc2NyaXB0TW9kZX1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgKVxuICAgICAgICB9KX1cbiAgICAgIDwvQm94PlxuICAgIClcbiAgfVxuXG4gIC8vIHNraWxsX2Rpc2NvdmVyeSByZW5kZXJlZCBoZXJlIChub3QgaW4gdGhlIHN3aXRjaCkgc28gdGhlICdza2lsbF9kaXNjb3ZlcnknXG4gIC8vIHN0cmluZyBsaXRlcmFsIHN0YXlzIGluc2lkZSBhIGZlYXR1cmUoKS1ndWFyZGVkIGJsb2NrLiBBIGNhc2UgbGFiZWwgY2FuJ3RcbiAgLy8gYmUgY29uZGl0aW9uYWxseSBlbGltaW5hdGVkOyBhbiBpZi1ib2R5IGNhbi5cbiAgaWYgKGZlYXR1cmUoJ0VYUEVSSU1FTlRBTF9TS0lMTF9TRUFSQ0gnKSkge1xuICAgIGlmIChhdHRhY2htZW50LnR5cGUgPT09ICdza2lsbF9kaXNjb3ZlcnknKSB7XG4gICAgICBpZiAoYXR0YWNobWVudC5za2lsbHMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbFxuICAgICAgLy8gQW50IHVzZXJzIGdldCBzaG9ydElkcyBpbmxpbmUgc28gdGhleSBjYW4gL3NraWxsLWZlZWRiYWNrIHdoaWxlIHRoZVxuICAgICAgLy8gdHVybiBpcyBzdGlsbCBmcmVzaC4gRXh0ZXJuYWwgdXNlcnMgKHdoZW4gdGhpcyB1bi1nYXRlcykganVzdCBzZWVcbiAgICAgIC8vIG5hbWVzIOKAlCBzaG9ydElkIGlzIHVuZGVmaW5lZCBvdXRzaWRlIGFudCBidWlsZHMgYW55d2F5LlxuICAgICAgY29uc3QgbmFtZXMgPSBhdHRhY2htZW50LnNraWxsc1xuICAgICAgICAubWFwKHMgPT4gKHMuc2hvcnRJZCA/IGAke3MubmFtZX0gWyR7cy5zaG9ydElkfV1gIDogcy5uYW1lKSlcbiAgICAgICAgLmpvaW4oJywgJylcbiAgICAgIGNvbnN0IGZpcnN0SWQgPSBhdHRhY2htZW50LnNraWxsc1swXT8uc2hvcnRJZFxuICAgICAgY29uc3QgaGludCA9XG4gICAgICAgIFwiZXh0ZXJuYWxcIiA9PT0gJ2FudCcgJiYgIWlzRGVtb0VudiAmJiBmaXJzdElkXG4gICAgICAgICAgPyBgIMK3IC9za2lsbC1mZWVkYmFjayAke2ZpcnN0SWR9IDE9d3JvbmcgMj1ub2lzeSAzPWdvb2QgW2NvbW1lbnRdYFxuICAgICAgICAgIDogJydcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxMaW5lPlxuICAgICAgICAgIDxUZXh0IGJvbGQ+e2F0dGFjaG1lbnQuc2tpbGxzLmxlbmd0aH08L1RleHQ+IHJlbGV2YW50eycgJ31cbiAgICAgICAgICB7cGx1cmFsKGF0dGFjaG1lbnQuc2tpbGxzLmxlbmd0aCwgJ3NraWxsJyl9OiB7bmFtZXN9XG4gICAgICAgICAge2hpbnQgJiYgPFRleHQgZGltQ29sb3I+e2hpbnR9PC9UZXh0Pn1cbiAgICAgICAgPC9MaW5lPlxuICAgICAgKVxuICAgIH1cbiAgfVxuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvc3dpdGNoLWV4aGF1c3RpdmVuZXNzLWNoZWNrIC0tIHRlYW1tYXRlX21haWxib3gvc2tpbGxfZGlzY292ZXJ5IGhhbmRsZWQgYmVmb3JlIHN3aXRjaFxuICBzd2l0Y2ggKGF0dGFjaG1lbnQudHlwZSkge1xuICAgIGNhc2UgJ2RpcmVjdG9yeSc6XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8TGluZT5cbiAgICAgICAgICBMaXN0ZWQgZGlyZWN0b3J5IDxUZXh0IGJvbGQ+e2F0dGFjaG1lbnQuZGlzcGxheVBhdGggKyBzZXB9PC9UZXh0PlxuICAgICAgICA8L0xpbmU+XG4gICAgICApXG4gICAgY2FzZSAnZmlsZSc6XG4gICAgY2FzZSAnYWxyZWFkeV9yZWFkX2ZpbGUnOlxuICAgICAgaWYgKGF0dGFjaG1lbnQuY29udGVudC50eXBlID09PSAnbm90ZWJvb2snKSB7XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgPExpbmU+XG4gICAgICAgICAgICBSZWFkIDxUZXh0IGJvbGQ+e2F0dGFjaG1lbnQuZGlzcGxheVBhdGh9PC9UZXh0PiAoXG4gICAgICAgICAgICB7YXR0YWNobWVudC5jb250ZW50LmZpbGUuY2VsbHMubGVuZ3RofSBjZWxscylcbiAgICAgICAgICA8L0xpbmU+XG4gICAgICAgIClcbiAgICAgIH1cbiAgICAgIGlmIChhdHRhY2htZW50LmNvbnRlbnQudHlwZSA9PT0gJ2ZpbGVfdW5jaGFuZ2VkJykge1xuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIDxMaW5lPlxuICAgICAgICAgICAgUmVhZCA8VGV4dCBib2xkPnthdHRhY2htZW50LmRpc3BsYXlQYXRofTwvVGV4dD4gKHVuY2hhbmdlZClcbiAgICAgICAgICA8L0xpbmU+XG4gICAgICAgIClcbiAgICAgIH1cbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxMaW5lPlxuICAgICAgICAgIFJlYWQgPFRleHQgYm9sZD57YXR0YWNobWVudC5kaXNwbGF5UGF0aH08L1RleHQ+IChcbiAgICAgICAgICB7YXR0YWNobWVudC5jb250ZW50LnR5cGUgPT09ICd0ZXh0J1xuICAgICAgICAgICAgPyBgJHthdHRhY2htZW50LmNvbnRlbnQuZmlsZS5udW1MaW5lc30ke2F0dGFjaG1lbnQudHJ1bmNhdGVkID8gJysnIDogJyd9IGxpbmVzYFxuICAgICAgICAgICAgOiBmb3JtYXRGaWxlU2l6ZShhdHRhY2htZW50LmNvbnRlbnQuZmlsZS5vcmlnaW5hbFNpemUpfVxuICAgICAgICAgIClcbiAgICAgICAgPC9MaW5lPlxuICAgICAgKVxuICAgIGNhc2UgJ2NvbXBhY3RfZmlsZV9yZWZlcmVuY2UnOlxuICAgICAgcmV0dXJuIChcbiAgICAgICAgPExpbmU+XG4gICAgICAgICAgUmVmZXJlbmNlZCBmaWxlIDxUZXh0IGJvbGQ+e2F0dGFjaG1lbnQuZGlzcGxheVBhdGh9PC9UZXh0PlxuICAgICAgICA8L0xpbmU+XG4gICAgICApXG4gICAgY2FzZSAncGRmX3JlZmVyZW5jZSc6XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8TGluZT5cbiAgICAgICAgICBSZWZlcmVuY2VkIFBERiA8VGV4dCBib2xkPnthdHRhY2htZW50LmRpc3BsYXlQYXRofTwvVGV4dD4gKFxuICAgICAgICAgIHthdHRhY2htZW50LnBhZ2VDb3VudH0gcGFnZXMpXG4gICAgICAgIDwvTGluZT5cbiAgICAgIClcbiAgICBjYXNlICdzZWxlY3RlZF9saW5lc19pbl9pZGUnOlxuICAgICAgcmV0dXJuIChcbiAgICAgICAgPExpbmU+XG4gICAgICAgICAg4qeJIFNlbGVjdGVkeycgJ31cbiAgICAgICAgICA8VGV4dCBib2xkPnthdHRhY2htZW50LmxpbmVFbmQgLSBhdHRhY2htZW50LmxpbmVTdGFydCArIDF9PC9UZXh0PnsnICd9XG4gICAgICAgICAgbGluZXMgZnJvbSA8VGV4dCBib2xkPnthdHRhY2htZW50LmRpc3BsYXlQYXRofTwvVGV4dD4gaW57JyAnfVxuICAgICAgICAgIHthdHRhY2htZW50LmlkZU5hbWV9XG4gICAgICAgIDwvTGluZT5cbiAgICAgIClcbiAgICBjYXNlICduZXN0ZWRfbWVtb3J5JzpcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxMaW5lPlxuICAgICAgICAgIExvYWRlZCA8VGV4dCBib2xkPnthdHRhY2htZW50LmRpc3BsYXlQYXRofTwvVGV4dD5cbiAgICAgICAgPC9MaW5lPlxuICAgICAgKVxuICAgIGNhc2UgJ3JlbGV2YW50X21lbW9yaWVzJzpcbiAgICAgIC8vIFVzdWFsbHkgYWJzb3JiZWQgaW50byBhIENvbGxhcHNlZFJlYWRTZWFyY2hHcm91cCAoY29sbGFwc2VSZWFkU2VhcmNoLnRzKVxuICAgICAgLy8gc28gdGhpcyBvbmx5IHJlbmRlcnMgd2hlbiB0aGUgcHJlY2VkaW5nIHRvb2wgd2FzIG5vbi1jb2xsYXBzaWJsZSAoRWRpdCxcbiAgICAgIC8vIFdyaXRlKSBhbmQgbm8gZ3JvdXAgd2FzIG9wZW4uIE1hdGNoIENvbGxhcHNlZFJlYWRTZWFyY2hDb250ZW50J3Mgc3R5bGU6XG4gICAgICAvLyAyLXNwYWNlIGd1dHRlciwgZGltIHRleHQsIGNvdW50IG9ubHkg4oCUIGZpbGVuYW1lcy9jb250ZW50IGluIGN0cmwrby5cbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxCb3hcbiAgICAgICAgICBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCJcbiAgICAgICAgICBtYXJnaW5Ub3A9e2FkZE1hcmdpbiA/IDEgOiAwfVxuICAgICAgICAgIGJhY2tncm91bmRDb2xvcj17Ymd9XG4gICAgICAgID5cbiAgICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJyb3dcIj5cbiAgICAgICAgICAgIDxCb3ggbWluV2lkdGg9ezJ9IC8+XG4gICAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5cbiAgICAgICAgICAgICAgUmVjYWxsZWQgPFRleHQgYm9sZD57YXR0YWNobWVudC5tZW1vcmllcy5sZW5ndGh9PC9UZXh0PnsnICd9XG4gICAgICAgICAgICAgIHthdHRhY2htZW50Lm1lbW9yaWVzLmxlbmd0aCA9PT0gMSA/ICdtZW1vcnknIDogJ21lbW9yaWVzJ31cbiAgICAgICAgICAgICAgeyFpc1RyYW5zY3JpcHRNb2RlICYmIChcbiAgICAgICAgICAgICAgICA8PlxuICAgICAgICAgICAgICAgICAgeycgJ31cbiAgICAgICAgICAgICAgICAgIDxDdHJsT1RvRXhwYW5kIC8+XG4gICAgICAgICAgICAgICAgPC8+XG4gICAgICAgICAgICAgICl9XG4gICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgPC9Cb3g+XG4gICAgICAgICAgeyh2ZXJib3NlIHx8IGlzVHJhbnNjcmlwdE1vZGUpICYmXG4gICAgICAgICAgICBhdHRhY2htZW50Lm1lbW9yaWVzLm1hcChtID0+IChcbiAgICAgICAgICAgICAgPEJveCBrZXk9e20ucGF0aH0gZmxleERpcmVjdGlvbj1cImNvbHVtblwiPlxuICAgICAgICAgICAgICAgIDxNZXNzYWdlUmVzcG9uc2U+XG4gICAgICAgICAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5cbiAgICAgICAgICAgICAgICAgICAgPEZpbGVQYXRoTGluayBmaWxlUGF0aD17bS5wYXRofT5cbiAgICAgICAgICAgICAgICAgICAgICB7YmFzZW5hbWUobS5wYXRoKX1cbiAgICAgICAgICAgICAgICAgICAgPC9GaWxlUGF0aExpbms+XG4gICAgICAgICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgICAgICAgPC9NZXNzYWdlUmVzcG9uc2U+XG4gICAgICAgICAgICAgICAge2lzVHJhbnNjcmlwdE1vZGUgJiYgKFxuICAgICAgICAgICAgICAgICAgPEJveCBwYWRkaW5nTGVmdD17NX0+XG4gICAgICAgICAgICAgICAgICAgIDxUZXh0PlxuICAgICAgICAgICAgICAgICAgICAgIDxBbnNpPnttLmNvbnRlbnR9PC9BbnNpPlxuICAgICAgICAgICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgICAgICAgICA8L0JveD5cbiAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICA8L0JveD5cbiAgICAgICAgICAgICkpfVxuICAgICAgICA8L0JveD5cbiAgICAgIClcbiAgICBjYXNlICdkeW5hbWljX3NraWxsJzoge1xuICAgICAgY29uc3Qgc2tpbGxDb3VudCA9IGF0dGFjaG1lbnQuc2tpbGxOYW1lcy5sZW5ndGhcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxMaW5lPlxuICAgICAgICAgIExvYWRlZHsnICd9XG4gICAgICAgICAgPFRleHQgYm9sZD5cbiAgICAgICAgICAgIHtza2lsbENvdW50fSB7cGx1cmFsKHNraWxsQ291bnQsICdza2lsbCcpfVxuICAgICAgICAgIDwvVGV4dD57JyAnfVxuICAgICAgICAgIGZyb20gPFRleHQgYm9sZD57YXR0YWNobWVudC5kaXNwbGF5UGF0aH08L1RleHQ+XG4gICAgICAgIDwvTGluZT5cbiAgICAgIClcbiAgICB9XG4gICAgY2FzZSAnc2tpbGxfbGlzdGluZyc6IHtcbiAgICAgIGlmIChhdHRhY2htZW50LmlzSW5pdGlhbCkge1xuICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgfVxuICAgICAgcmV0dXJuIChcbiAgICAgICAgPExpbmU+XG4gICAgICAgICAgPFRleHQgYm9sZD57YXR0YWNobWVudC5za2lsbENvdW50fTwvVGV4dD57JyAnfVxuICAgICAgICAgIHtwbHVyYWwoYXR0YWNobWVudC5za2lsbENvdW50LCAnc2tpbGwnKX0gYXZhaWxhYmxlXG4gICAgICAgIDwvTGluZT5cbiAgICAgIClcbiAgICB9XG4gICAgY2FzZSAnYWdlbnRfbGlzdGluZ19kZWx0YSc6IHtcbiAgICAgIGlmIChhdHRhY2htZW50LmlzSW5pdGlhbCB8fCBhdHRhY2htZW50LmFkZGVkVHlwZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICB9XG4gICAgICBjb25zdCBjb3VudCA9IGF0dGFjaG1lbnQuYWRkZWRUeXBlcy5sZW5ndGhcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxMaW5lPlxuICAgICAgICAgIDxUZXh0IGJvbGQ+e2NvdW50fTwvVGV4dD4gYWdlbnQge3BsdXJhbChjb3VudCwgJ3R5cGUnKX0gYXZhaWxhYmxlXG4gICAgICAgIDwvTGluZT5cbiAgICAgIClcbiAgICB9XG4gICAgY2FzZSAncXVldWVkX2NvbW1hbmQnOiB7XG4gICAgICBjb25zdCB0ZXh0ID1cbiAgICAgICAgdHlwZW9mIGF0dGFjaG1lbnQucHJvbXB0ID09PSAnc3RyaW5nJ1xuICAgICAgICAgID8gYXR0YWNobWVudC5wcm9tcHRcbiAgICAgICAgICA6IGdldENvbnRlbnRUZXh0KGF0dGFjaG1lbnQucHJvbXB0KSB8fCAnJ1xuICAgICAgY29uc3QgaGFzSW1hZ2VzID1cbiAgICAgICAgYXR0YWNobWVudC5pbWFnZVBhc3RlSWRzICYmIGF0dGFjaG1lbnQuaW1hZ2VQYXN0ZUlkcy5sZW5ndGggPiAwXG4gICAgICByZXR1cm4gKFxuICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIj5cbiAgICAgICAgICA8VXNlclRleHRNZXNzYWdlXG4gICAgICAgICAgICBhZGRNYXJnaW49e2FkZE1hcmdpbn1cbiAgICAgICAgICAgIHBhcmFtPXt7IHRleHQsIHR5cGU6ICd0ZXh0JyB9fVxuICAgICAgICAgICAgdmVyYm9zZT17dmVyYm9zZX1cbiAgICAgICAgICAgIGlzVHJhbnNjcmlwdE1vZGU9e2lzVHJhbnNjcmlwdE1vZGV9XG4gICAgICAgICAgLz5cbiAgICAgICAgICB7aGFzSW1hZ2VzICYmXG4gICAgICAgICAgICBhdHRhY2htZW50LmltYWdlUGFzdGVJZHM/Lm1hcChpZCA9PiAoXG4gICAgICAgICAgICAgIDxVc2VySW1hZ2VNZXNzYWdlIGtleT17aWR9IGltYWdlSWQ9e2lkfSAvPlxuICAgICAgICAgICAgKSl9XG4gICAgICAgIDwvQm94PlxuICAgICAgKVxuICAgIH1cbiAgICBjYXNlICdwbGFuX2ZpbGVfcmVmZXJlbmNlJzpcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxMaW5lPlxuICAgICAgICAgIFBsYW4gZmlsZSByZWZlcmVuY2VkICh7Z2V0RGlzcGxheVBhdGgoYXR0YWNobWVudC5wbGFuRmlsZVBhdGgpfSlcbiAgICAgICAgPC9MaW5lPlxuICAgICAgKVxuICAgIGNhc2UgJ2ludm9rZWRfc2tpbGxzJzoge1xuICAgICAgaWYgKGF0dGFjaG1lbnQuc2tpbGxzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgfVxuICAgICAgY29uc3Qgc2tpbGxOYW1lcyA9IGF0dGFjaG1lbnQuc2tpbGxzLm1hcChzID0+IHMubmFtZSkuam9pbignLCAnKVxuICAgICAgcmV0dXJuIDxMaW5lPlNraWxscyByZXN0b3JlZCAoe3NraWxsTmFtZXN9KTwvTGluZT5cbiAgICB9XG4gICAgY2FzZSAnZGlhZ25vc3RpY3MnOlxuICAgICAgcmV0dXJuIDxEaWFnbm9zdGljc0Rpc3BsYXkgYXR0YWNobWVudD17YXR0YWNobWVudH0gdmVyYm9zZT17dmVyYm9zZX0gLz5cbiAgICBjYXNlICdtY3BfcmVzb3VyY2UnOlxuICAgICAgcmV0dXJuIChcbiAgICAgICAgPExpbmU+XG4gICAgICAgICAgUmVhZCBNQ1AgcmVzb3VyY2UgPFRleHQgYm9sZD57YXR0YWNobWVudC5uYW1lfTwvVGV4dD4gZnJvbXsnICd9XG4gICAgICAgICAge2F0dGFjaG1lbnQuc2VydmVyfVxuICAgICAgICA8L0xpbmU+XG4gICAgICApXG4gICAgY2FzZSAnY29tbWFuZF9wZXJtaXNzaW9ucyc6XG4gICAgICAvLyBUaGUgc2tpbGwgc3VjY2VzcyBtZXNzYWdlIGlzIHJlbmRlcmVkIGJ5IFNraWxsVG9vbCdzIHJlbmRlclRvb2xSZXN1bHRNZXNzYWdlLFxuICAgICAgLy8gc28gd2UgZG9uJ3QgcmVuZGVyIGFueXRoaW5nIGhlcmUgdG8gYXZvaWQgZHVwbGljYXRlIG1lc3NhZ2VzLlxuICAgICAgcmV0dXJuIG51bGxcbiAgICBjYXNlICdhc3luY19ob29rX3Jlc3BvbnNlJzoge1xuICAgICAgLy8gU2Vzc2lvblN0YXJ0IGhvb2sgY29tcGxldGlvbnMgYXJlIG9ubHkgc2hvd24gaW4gdmVyYm9zZSBtb2RlXG4gICAgICBpZiAoYXR0YWNobWVudC5ob29rRXZlbnQgPT09ICdTZXNzaW9uU3RhcnQnICYmICF2ZXJib3NlKSB7XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICB9XG4gICAgICAvLyBHZW5lcmFsbHkgaGlkZSBhc3luYyBob29rIGNvbXBsZXRpb24gbWVzc2FnZXMgdW5sZXNzIGluIHZlcmJvc2UgbW9kZVxuICAgICAgaWYgKCF2ZXJib3NlICYmICFpc1RyYW5zY3JpcHRNb2RlKSB7XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgICB9XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8TGluZT5cbiAgICAgICAgICBBc3luYyBob29rIDxUZXh0IGJvbGQ+e2F0dGFjaG1lbnQuaG9va0V2ZW50fTwvVGV4dD4gY29tcGxldGVkXG4gICAgICAgIDwvTGluZT5cbiAgICAgIClcbiAgICB9XG4gICAgY2FzZSAnaG9va19ibG9ja2luZ19lcnJvcic6IHtcbiAgICAgIC8vIFN0b3AgaG9va3MgYXJlIHJlbmRlcmVkIGFzIGEgc3VtbWFyeSBpbiBTeXN0ZW1TdG9wSG9va1N1bW1hcnlNZXNzYWdlXG4gICAgICBpZiAoXG4gICAgICAgIGF0dGFjaG1lbnQuaG9va0V2ZW50ID09PSAnU3RvcCcgfHxcbiAgICAgICAgYXR0YWNobWVudC5ob29rRXZlbnQgPT09ICdTdWJhZ2VudFN0b3AnXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cbiAgICAgIC8vIFNob3cgc3RkZXJyIHRvIHRoZSB1c2VyIHNvIHRoZXkgY2FuIHVuZGVyc3RhbmQgd2h5IHRoZSBob29rIGJsb2NrZWRcbiAgICAgIGNvbnN0IHN0ZGVyciA9IGF0dGFjaG1lbnQuYmxvY2tpbmdFcnJvci5ibG9ja2luZ0Vycm9yLnRyaW0oKVxuICAgICAgcmV0dXJuIChcbiAgICAgICAgPD5cbiAgICAgICAgICA8TGluZSBjb2xvcj1cImVycm9yXCI+XG4gICAgICAgICAgICB7YXR0YWNobWVudC5ob29rTmFtZX0gaG9vayByZXR1cm5lZCBibG9ja2luZyBlcnJvclxuICAgICAgICAgIDwvTGluZT5cbiAgICAgICAgICB7c3RkZXJyID8gPExpbmUgY29sb3I9XCJlcnJvclwiPntzdGRlcnJ9PC9MaW5lPiA6IG51bGx9XG4gICAgICAgIDwvPlxuICAgICAgKVxuICAgIH1cbiAgICBjYXNlICdob29rX25vbl9ibG9ja2luZ19lcnJvcic6IHtcbiAgICAgIC8vIFN0b3AgaG9va3MgYXJlIHJlbmRlcmVkIGFzIGEgc3VtbWFyeSBpbiBTeXN0ZW1TdG9wSG9va1N1bW1hcnlNZXNzYWdlXG4gICAgICBpZiAoXG4gICAgICAgIGF0dGFjaG1lbnQuaG9va0V2ZW50ID09PSAnU3RvcCcgfHxcbiAgICAgICAgYXR0YWNobWVudC5ob29rRXZlbnQgPT09ICdTdWJhZ2VudFN0b3AnXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cbiAgICAgIC8vIEZ1bGwgaG9vayBvdXRwdXQgaXMgbG9nZ2VkIHRvIGRlYnVnIGxvZyB2aWEgaG9va0V2ZW50cy50c1xuICAgICAgcmV0dXJuIDxMaW5lIGNvbG9yPVwiZXJyb3JcIj57YXR0YWNobWVudC5ob29rTmFtZX0gaG9vayBlcnJvcjwvTGluZT5cbiAgICB9XG4gICAgY2FzZSAnaG9va19lcnJvcl9kdXJpbmdfZXhlY3V0aW9uJzpcbiAgICAgIC8vIFN0b3AgaG9va3MgYXJlIHJlbmRlcmVkIGFzIGEgc3VtbWFyeSBpbiBTeXN0ZW1TdG9wSG9va1N1bW1hcnlNZXNzYWdlXG4gICAgICBpZiAoXG4gICAgICAgIGF0dGFjaG1lbnQuaG9va0V2ZW50ID09PSAnU3RvcCcgfHxcbiAgICAgICAgYXR0YWNobWVudC5ob29rRXZlbnQgPT09ICdTdWJhZ2VudFN0b3AnXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cbiAgICAgIC8vIEZ1bGwgaG9vayBvdXRwdXQgaXMgbG9nZ2VkIHRvIGRlYnVnIGxvZyB2aWEgaG9va0V2ZW50cy50c1xuICAgICAgcmV0dXJuIDxMaW5lPnthdHRhY2htZW50Lmhvb2tOYW1lfSBob29rIHdhcm5pbmc8L0xpbmU+XG4gICAgY2FzZSAnaG9va19zdWNjZXNzJzpcbiAgICAgIC8vIEZ1bGwgaG9vayBvdXRwdXQgaXMgbG9nZ2VkIHRvIGRlYnVnIGxvZyB2aWEgaG9va0V2ZW50cy50c1xuICAgICAgcmV0dXJuIG51bGxcbiAgICBjYXNlICdob29rX3N0b3BwZWRfY29udGludWF0aW9uJzpcbiAgICAgIC8vIFN0b3AgaG9va3MgYXJlIHJlbmRlcmVkIGFzIGEgc3VtbWFyeSBpbiBTeXN0ZW1TdG9wSG9va1N1bW1hcnlNZXNzYWdlXG4gICAgICBpZiAoXG4gICAgICAgIGF0dGFjaG1lbnQuaG9va0V2ZW50ID09PSAnU3RvcCcgfHxcbiAgICAgICAgYXR0YWNobWVudC5ob29rRXZlbnQgPT09ICdTdWJhZ2VudFN0b3AnXG4gICAgICApIHtcbiAgICAgICAgcmV0dXJuIG51bGxcbiAgICAgIH1cbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxMaW5lIGNvbG9yPVwid2FybmluZ1wiPlxuICAgICAgICAgIHthdHRhY2htZW50Lmhvb2tOYW1lfSBob29rIHN0b3BwZWQgY29udGludWF0aW9uOiB7YXR0YWNobWVudC5tZXNzYWdlfVxuICAgICAgICA8L0xpbmU+XG4gICAgICApXG4gICAgY2FzZSAnaG9va19zeXN0ZW1fbWVzc2FnZSc6XG4gICAgICByZXR1cm4gKFxuICAgICAgICA8TGluZT5cbiAgICAgICAgICB7YXR0YWNobWVudC5ob29rTmFtZX0gc2F5czoge2F0dGFjaG1lbnQuY29udGVudH1cbiAgICAgICAgPC9MaW5lPlxuICAgICAgKVxuICAgIGNhc2UgJ2hvb2tfcGVybWlzc2lvbl9kZWNpc2lvbic6IHtcbiAgICAgIGNvbnN0IGFjdGlvbiA9IGF0dGFjaG1lbnQuZGVjaXNpb24gPT09ICdhbGxvdycgPyAnQWxsb3dlZCcgOiAnRGVuaWVkJ1xuICAgICAgcmV0dXJuIChcbiAgICAgICAgPExpbmU+XG4gICAgICAgICAge2FjdGlvbn0gYnkgPFRleHQgYm9sZD57YXR0YWNobWVudC5ob29rRXZlbnR9PC9UZXh0PiBob29rXG4gICAgICAgIDwvTGluZT5cbiAgICAgIClcbiAgICB9XG4gICAgY2FzZSAndGFza19zdGF0dXMnOlxuICAgICAgcmV0dXJuIDxUYXNrU3RhdHVzTWVzc2FnZSBhdHRhY2htZW50PXthdHRhY2htZW50fSAvPlxuICAgIGNhc2UgJ3RlYW1tYXRlX3NodXRkb3duX2JhdGNoJzpcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxCb3hcbiAgICAgICAgICBmbGV4RGlyZWN0aW9uPVwicm93XCJcbiAgICAgICAgICB3aWR0aD1cIjEwMCVcIlxuICAgICAgICAgIG1hcmdpblRvcD17MX1cbiAgICAgICAgICBiYWNrZ3JvdW5kQ29sb3I9e2JnfVxuICAgICAgICA+XG4gICAgICAgICAgPFRleHQgZGltQ29sb3I+e0JMQUNLX0NJUkNMRX0gPC9UZXh0PlxuICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPlxuICAgICAgICAgICAge2F0dGFjaG1lbnQuY291bnR9IHtwbHVyYWwoYXR0YWNobWVudC5jb3VudCwgJ3RlYW1tYXRlJyl9IHNodXQgZG93blxuICAgICAgICAgICAgZ3JhY2VmdWxseVxuICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgPC9Cb3g+XG4gICAgICApXG4gICAgZGVmYXVsdDpcbiAgICAgIC8vIEV4aGF1c3RpdmVuZXNzOiBldmVyeSB0eXBlIHJlYWNoaW5nIGhlcmUgbXVzdCBiZSBpbiBOVUxMX1JFTkRFUklOR19UWVBFUy5cbiAgICAgIC8vIElmIFRTIGVycm9ycywgYSBuZXcgQXR0YWNobWVudCB0eXBlIHdhcyBhZGRlZCB3aXRob3V0IGEgY2FzZSBhYm92ZSBBTkRcbiAgICAgIC8vIHdpdGhvdXQgYW4gZW50cnkgaW4gTlVMTF9SRU5ERVJJTkdfVFlQRVMg4oCUIGRlY2lkZTogcmVuZGVyIHNvbWV0aGluZyAoYWRkXG4gICAgICAvLyBhIGNhc2UpIG9yIHJlbmRlciBub3RoaW5nIChhZGQgdG8gdGhlIGFycmF5KS4gTWVzc2FnZXMudHN4IHByZS1maWx0ZXJzXG4gICAgICAvLyB0aGVzZSBzbyB0aGlzIGJyYW5jaCBpcyBkZWZlbnNlLWluLWRlcHRoIGZvciBvdGhlciByZW5kZXIgcGF0aHMuXG4gICAgICAvL1xuICAgICAgLy8gc2tpbGxfZGlzY292ZXJ5IGFuZCB0ZWFtbWF0ZV9tYWlsYm94IGFyZSBoYW5kbGVkIEJFRk9SRSB0aGUgc3dpdGNoIGluXG4gICAgICAvLyBydW50aW1lLWdhdGVkIGJsb2NrcyAoZmVhdHVyZSgpIC8gaXNBZ2VudFN3YXJtc0VuYWJsZWQoKSkgdGhhdCBUUyBjYW4ndFxuICAgICAgLy8gbmFycm93IHRocm91Z2gg4oCUIGV4Y2x1ZGVkIGhlcmUgdmlhIHR5cGUgdW5pb24gKGNvbXBpbGUtdGltZSBvbmx5LCBubyBlbWl0KS5cbiAgICAgIGF0dGFjaG1lbnQudHlwZSBzYXRpc2ZpZXNcbiAgICAgICAgfCBOdWxsUmVuZGVyaW5nQXR0YWNobWVudFR5cGVcbiAgICAgICAgfCAnc2tpbGxfZGlzY292ZXJ5J1xuICAgICAgICB8ICd0ZWFtbWF0ZV9tYWlsYm94J1xuICAgICAgcmV0dXJuIG51bGxcbiAgfVxufVxuXG50eXBlIFRhc2tTdGF0dXNBdHRhY2htZW50ID0gRXh0cmFjdDxBdHRhY2htZW50LCB7IHR5cGU6ICd0YXNrX3N0YXR1cycgfT5cblxuZnVuY3Rpb24gVGFza1N0YXR1c01lc3NhZ2Uoe1xuICBhdHRhY2htZW50LFxufToge1xuICBhdHRhY2htZW50OiBUYXNrU3RhdHVzQXR0YWNobWVudFxufSk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIC8vIEZvciBhbnRzLCBraWxsZWQgdGFzayBzdGF0dXMgaXMgc2hvd24gaW4gdGhlIENvb3JkaW5hdG9yVGFza1BhbmVsLlxuICAvLyBEb24ndCByZW5kZXIgaXQgYWdhaW4gaW4gdGhlIGNoYXQuXG4gIGlmIChcImV4dGVybmFsXCIgPT09ICdhbnQnICYmIGF0dGFjaG1lbnQuc3RhdHVzID09PSAna2lsbGVkJykge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICAvLyBPbmx5IGFjY2VzcyB0ZWFtbWF0ZS1zcGVjaWZpYyBjb2RlIHdoZW4gc3dhcm1zIGFyZSBlbmFibGVkLlxuICAvLyBUZWFtbWF0ZVRhc2tTdGF0dXMgc3Vic2NyaWJlcyB0byBBcHBTdGF0ZTsgYnkgZ2F0aW5nIHRoZSBtb3VudCB3ZVxuICAvLyBhdm9pZCBhZGRpbmcgYSBzdG9yZSBsaXN0ZW5lciBmb3IgZXZlcnkgbm9uLXRlYW1tYXRlIGF0dGFjaG1lbnQuXG4gIGlmIChpc0FnZW50U3dhcm1zRW5hYmxlZCgpICYmIGF0dGFjaG1lbnQudGFza1R5cGUgPT09ICdpbl9wcm9jZXNzX3RlYW1tYXRlJykge1xuICAgIHJldHVybiA8VGVhbW1hdGVUYXNrU3RhdHVzIGF0dGFjaG1lbnQ9e2F0dGFjaG1lbnR9IC8+XG4gIH1cblxuICByZXR1cm4gPEdlbmVyaWNUYXNrU3RhdHVzIGF0dGFjaG1lbnQ9e2F0dGFjaG1lbnR9IC8+XG59XG5cbmZ1bmN0aW9uIEdlbmVyaWNUYXNrU3RhdHVzKHtcbiAgYXR0YWNobWVudCxcbn06IHtcbiAgYXR0YWNobWVudDogVGFza1N0YXR1c0F0dGFjaG1lbnRcbn0pOiBSZWFjdC5SZWFjdE5vZGUge1xuICBjb25zdCBiZyA9IHVzZVNlbGVjdGVkTWVzc2FnZUJnKClcbiAgY29uc3Qgc3RhdHVzVGV4dCA9XG4gICAgYXR0YWNobWVudC5zdGF0dXMgPT09ICdjb21wbGV0ZWQnXG4gICAgICA/ICdjb21wbGV0ZWQgaW4gYmFja2dyb3VuZCdcbiAgICAgIDogYXR0YWNobWVudC5zdGF0dXMgPT09ICdraWxsZWQnXG4gICAgICAgID8gJ3N0b3BwZWQnXG4gICAgICAgIDogYXR0YWNobWVudC5zdGF0dXMgPT09ICdydW5uaW5nJ1xuICAgICAgICAgID8gJ3N0aWxsIHJ1bm5pbmcgaW4gYmFja2dyb3VuZCdcbiAgICAgICAgICA6IGF0dGFjaG1lbnQuc3RhdHVzXG4gIHJldHVybiAoXG4gICAgPEJveCBmbGV4RGlyZWN0aW9uPVwicm93XCIgd2lkdGg9XCIxMDAlXCIgbWFyZ2luVG9wPXsxfSBiYWNrZ3JvdW5kQ29sb3I9e2JnfT5cbiAgICAgIDxUZXh0IGRpbUNvbG9yPntCTEFDS19DSVJDTEV9IDwvVGV4dD5cbiAgICAgIDxUZXh0IGRpbUNvbG9yPlxuICAgICAgICBUYXNrICZxdW90OzxUZXh0IGJvbGQ+e2F0dGFjaG1lbnQuZGVzY3JpcHRpb259PC9UZXh0PiZxdW90OyB7c3RhdHVzVGV4dH1cbiAgICAgIDwvVGV4dD5cbiAgICA8L0JveD5cbiAgKVxufVxuXG5mdW5jdGlvbiBUZWFtbWF0ZVRhc2tTdGF0dXMoe1xuICBhdHRhY2htZW50LFxufToge1xuICBhdHRhY2htZW50OiBUYXNrU3RhdHVzQXR0YWNobWVudFxufSk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIGNvbnN0IGJnID0gdXNlU2VsZWN0ZWRNZXNzYWdlQmcoKVxuICAvLyBOYXJyb3cgc2VsZWN0b3I6IG9ubHkgcmUtcmVuZGVyIHdoZW4gdGhpcyBzcGVjaWZpYyB0YXNrIGNoYW5nZXMuXG4gIGNvbnN0IHRhc2sgPSB1c2VBcHBTdGF0ZShzID0+IHMudGFza3NbYXR0YWNobWVudC50YXNrSWRdKVxuICBpZiAodGFzaz8udHlwZSAhPT0gJ2luX3Byb2Nlc3NfdGVhbW1hdGUnKSB7XG4gICAgLy8gRmFsbCB0aHJvdWdoIHRvIGdlbmVyaWMgcmVuZGVyaW5nICh0YXNrIG5vdCB5ZXQgaW4gc3RvcmUsIG9yIHdyb25nIHR5cGUpXG4gICAgcmV0dXJuIDxHZW5lcmljVGFza1N0YXR1cyBhdHRhY2htZW50PXthdHRhY2htZW50fSAvPlxuICB9XG4gIGNvbnN0IGFnZW50Q29sb3IgPSB0b0lua0NvbG9yKHRhc2suaWRlbnRpdHkuY29sb3IpXG4gIGNvbnN0IHN0YXR1c1RleHQgPVxuICAgIGF0dGFjaG1lbnQuc3RhdHVzID09PSAnY29tcGxldGVkJ1xuICAgICAgPyAnc2h1dCBkb3duIGdyYWNlZnVsbHknXG4gICAgICA6IGF0dGFjaG1lbnQuc3RhdHVzXG4gIHJldHVybiAoXG4gICAgPEJveCBmbGV4RGlyZWN0aW9uPVwicm93XCIgd2lkdGg9XCIxMDAlXCIgbWFyZ2luVG9wPXsxfSBiYWNrZ3JvdW5kQ29sb3I9e2JnfT5cbiAgICAgIDxUZXh0IGRpbUNvbG9yPntCTEFDS19DSVJDTEV9IDwvVGV4dD5cbiAgICAgIDxUZXh0IGRpbUNvbG9yPlxuICAgICAgICBUZWFtbWF0ZXsnICd9XG4gICAgICAgIDxUZXh0IGNvbG9yPXthZ2VudENvbG9yfSBib2xkIGRpbUNvbG9yPXtmYWxzZX0+XG4gICAgICAgICAgQHt0YXNrLmlkZW50aXR5LmFnZW50TmFtZX1cbiAgICAgICAgPC9UZXh0PnsnICd9XG4gICAgICAgIHtzdGF0dXNUZXh0fVxuICAgICAgPC9UZXh0PlxuICAgIDwvQm94PlxuICApXG59XG4vLyBXZSBhbGxvdyBzZXR0aW5nIGRpbUNvbG9yIHRvIGZhbHNlIGhlcmUgdG8gaGVscCB3b3JrIGFyb3VuZCB0aGUgZGltLWJvbGQgYnVnLlxuLy8gaHR0cHM6Ly9naXRodWIuY29tL2NoYWxrL2NoYWxrL2lzc3Vlcy8yOTBcbmZ1bmN0aW9uIExpbmUoe1xuICBkaW1Db2xvciA9IHRydWUsXG4gIGNoaWxkcmVuLFxuICBjb2xvcixcbn06IHtcbiAgZGltQ29sb3I/OiBib29sZWFuXG4gIGNoaWxkcmVuOiBSZWFjdC5SZWFjdE5vZGVcbiAgY29sb3I/OiBrZXlvZiBUaGVtZVxufSk6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIGNvbnN0IGJnID0gdXNlU2VsZWN0ZWRNZXNzYWdlQmcoKVxuICByZXR1cm4gKFxuICAgIDxCb3ggYmFja2dyb3VuZENvbG9yPXtiZ30+XG4gICAgICA8TWVzc2FnZVJlc3BvbnNlPlxuICAgICAgICA8VGV4dCBjb2xvcj17Y29sb3J9IGRpbUNvbG9yPXtkaW1Db2xvcn0gd3JhcD1cIndyYXBcIj5cbiAgICAgICAgICB7Y2hpbGRyZW59XG4gICAgICAgIDwvVGV4dD5cbiAgICAgIDwvTWVzc2FnZVJlc3BvbnNlPlxuICAgIDwvQm94PlxuICApXG59XG4iXSwibWFwcGluZ3MiOiI7QUFBQTtBQUNBLE9BQU9BLEtBQUssSUFBSUMsT0FBTyxRQUFRLE9BQU87QUFDdEMsU0FBU0MsSUFBSSxFQUFFQyxHQUFHLEVBQUVDLElBQUksUUFBUSxjQUFjO0FBQzlDLGNBQWNDLFVBQVUsUUFBUSwwQkFBMEI7QUFDMUQsY0FBY0MsMkJBQTJCLFFBQVEsK0JBQStCO0FBQ2hGLFNBQVNDLFdBQVcsUUFBUSx5QkFBeUI7QUFDckQsU0FBU0MsY0FBYyxRQUFRLG1CQUFtQjtBQUNsRCxTQUFTQyxjQUFjLFFBQVEscUJBQXFCO0FBQ3BELFNBQVNDLGVBQWUsUUFBUSx1QkFBdUI7QUFDdkQsU0FBU0MsUUFBUSxFQUFFQyxHQUFHLFFBQVEsTUFBTTtBQUNwQyxTQUFTQyxlQUFlLFFBQVEsc0JBQXNCO0FBQ3RELFNBQVNDLGtCQUFrQixRQUFRLDBCQUEwQjtBQUM3RCxTQUFTQyxjQUFjLFFBQVEsdUJBQXVCO0FBQ3RELGNBQWNDLEtBQUssUUFBUSxvQkFBb0I7QUFDL0MsU0FBU0MsZ0JBQWdCLFFBQVEsdUJBQXVCO0FBQ3hELFNBQVNDLFVBQVUsUUFBUSxvQkFBb0I7QUFDL0MsU0FBU0MsU0FBUyxRQUFRLCtCQUErQjtBQUN6RCxTQUFTQyxNQUFNLFFBQVEsNEJBQTRCO0FBQ25ELFNBQVNDLFdBQVcsUUFBUSx5QkFBeUI7QUFDckQsU0FBU0Msb0JBQW9CLFFBQVEsbUNBQW1DO0FBQ3hFLFNBQ0VDLDRCQUE0QixFQUM1QkMsNEJBQTRCLFFBQ3ZCLDBCQUEwQjtBQUNqQyxTQUFTQyxZQUFZLFFBQVEsNEJBQTRCO0FBQ3pELFNBQVNDLHNCQUFzQixRQUFRLDBCQUEwQjtBQUNqRSxTQUFTQyxrQkFBa0IsUUFBUSxnQ0FBZ0M7QUFDbkUsU0FBU0MsYUFBYSxRQUFRLHFCQUFxQjtBQUNuRCxTQUFTQyxZQUFZLFFBQVEsb0JBQW9CO0FBQ2pELFNBQVNDLE9BQU8sUUFBUSxZQUFZO0FBQ3BDLFNBQVNDLG9CQUFvQixRQUFRLHNCQUFzQjtBQUUzRCxLQUFLQyxLQUFLLEdBQUc7RUFDWEMsU0FBUyxFQUFFLE9BQU87RUFDbEJDLFVBQVUsRUFBRTdCLFVBQVU7RUFDdEI4QixPQUFPLEVBQUUsT0FBTztFQUNoQkMsZ0JBQWdCLENBQUMsRUFBRSxPQUFPO0FBQzVCLENBQUM7QUFFRCxPQUFPLFNBQVNDLGlCQUFpQkEsQ0FBQztFQUNoQ0gsVUFBVTtFQUNWRCxTQUFTO0VBQ1RFLE9BQU87RUFDUEM7QUFDSyxDQUFOLEVBQUVKLEtBQUssQ0FBQyxFQUFFaEMsS0FBSyxDQUFDc0MsU0FBUyxDQUFDO0VBQ3pCLE1BQU1DLEVBQUUsR0FBR1Isb0JBQW9CLENBQUMsQ0FBQztFQUNqQztFQUNBLE1BQU1TLFNBQVMsR0FBR1YsT0FBTyxDQUFDLDJCQUEyQixDQUFDO0VBQ2xEO0VBQ0E3QixPQUFPLENBQUMsTUFBTW9CLFdBQVcsQ0FBQ29CLE9BQU8sQ0FBQ0MsR0FBRyxDQUFDQyxPQUFPLENBQUMsRUFBRSxFQUFFLENBQUMsR0FDbkQsS0FBSztFQUNUO0VBQ0EsSUFBSXJCLG9CQUFvQixDQUFDLENBQUMsSUFBSVksVUFBVSxDQUFDVSxJQUFJLEtBQUssa0JBQWtCLEVBQUU7SUFDcEU7SUFDQTtJQUNBLE1BQU1DLGVBQWUsR0FBR1gsVUFBVSxDQUFDWSxRQUFRLENBQUNDLE1BQU0sQ0FBQ0MsR0FBRyxJQUFJO01BQ3hELElBQUlyQixrQkFBa0IsQ0FBQ3FCLEdBQUcsQ0FBQ0MsSUFBSSxDQUFDLEVBQUU7UUFDaEMsT0FBTyxLQUFLO01BQ2Q7TUFDQSxJQUFJO1FBQ0YsTUFBTUMsTUFBTSxHQUFHL0IsU0FBUyxDQUFDNkIsR0FBRyxDQUFDQyxJQUFJLENBQUM7UUFDbEMsT0FDRUMsTUFBTSxFQUFFTixJQUFJLEtBQUssbUJBQW1CLElBQ3BDTSxNQUFNLEVBQUVOLElBQUksS0FBSyxxQkFBcUI7TUFFMUMsQ0FBQyxDQUFDLE1BQU07UUFDTixPQUFPLElBQUksRUFBQztNQUNkO0lBQ0YsQ0FBQyxDQUFDO0lBRUYsSUFBSUMsZUFBZSxDQUFDTSxNQUFNLEtBQUssQ0FBQyxFQUFFO01BQ2hDLE9BQU8sSUFBSTtJQUNiO0lBQ0EsT0FDRSxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsUUFBUTtBQUNqQyxRQUFRLENBQUNOLGVBQWUsQ0FBQ08sR0FBRyxDQUFDLENBQUNKLEtBQUcsRUFBRUssR0FBRyxLQUFLO1FBQ2pDO1FBQ0EsSUFBSUMsU0FBUyxFQUFFO1VBQ2JWLElBQUksQ0FBQyxFQUFFLE1BQU07VUFDYlcsTUFBTSxDQUFDLEVBQUUsTUFBTTtVQUNmQyxPQUFPLENBQUMsRUFBRSxNQUFNO1VBQ2hCQyxVQUFVLENBQUMsRUFBRSxNQUFNO1FBQ3JCLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSTtRQUNmLElBQUk7VUFDRkgsU0FBUyxHQUFHbkMsU0FBUyxDQUFDNkIsS0FBRyxDQUFDQyxJQUFJLENBQUM7UUFDakMsQ0FBQyxDQUFDLE1BQU07VUFDTjtRQUFBO1FBR0YsSUFBSUssU0FBUyxFQUFFVixJQUFJLEtBQUssaUJBQWlCLEVBQUU7VUFDekMsT0FDRSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQ1MsR0FBRyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQzVDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDNUIsWUFBWSxDQUFDLENBQUMsRUFBRSxJQUFJO0FBQzNDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxlQUFlLEVBQUUsSUFBSTtBQUMzQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQzZCLFNBQVMsQ0FBQ0MsTUFBTSxDQUFDLEVBQUUsSUFBSTtBQUNwRCxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDRCxTQUFTLENBQUNFLE9BQU8sQ0FBQyxFQUFFLElBQUk7QUFDbEQsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUNGLFNBQVMsQ0FBQ0csVUFBVSxJQUFJVCxLQUFHLENBQUNVLElBQUksQ0FBQyxDQUFDLEVBQUUsSUFBSTtBQUMvRSxjQUFjLEVBQUUsR0FBRyxDQUFDO1FBRVY7O1FBRUE7O1FBRUE7UUFDQSxNQUFNQyxtQkFBbUIsR0FBR3BDLDRCQUE0QixDQUN0RHlCLEtBQUcsQ0FBQ0MsSUFBSSxFQUNSRCxLQUFHLENBQUNVLElBQ04sQ0FBQztRQUNELElBQUlDLG1CQUFtQixFQUFFO1VBQ3ZCLE9BQ0UsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDTixHQUFHLENBQUMsQ0FBQyxDQUFDTSxtQkFBbUIsQ0FBQyxFQUFFLEtBQUssQ0FBQyxRQUFRLENBQUM7UUFFcEU7O1FBRUE7UUFDQSxNQUFNQyxRQUFRLEdBQUcxQyxVQUFVLENBQUM4QixLQUFHLENBQUNhLEtBQUssQ0FBQztRQUN0QyxNQUFNQyxnQkFBZ0IsR0FDcEJ0Qyw0QkFBNEIsQ0FBQ3dCLEtBQUcsQ0FBQ0MsSUFBSSxDQUFDLElBQUlELEtBQUcsQ0FBQ0MsSUFBSTtRQUNwRCxPQUNFLENBQUMsc0JBQXNCLENBQ3JCLEdBQUcsQ0FBQyxDQUFDSSxHQUFHLENBQUMsQ0FDVCxXQUFXLENBQUMsQ0FBQ0wsS0FBRyxDQUFDVSxJQUFJLENBQUMsQ0FDdEIsUUFBUSxDQUFDLENBQUNFLFFBQVEsQ0FBQyxDQUNuQixPQUFPLENBQUMsQ0FBQ0UsZ0JBQWdCLENBQUMsQ0FDMUIsT0FBTyxDQUFDLENBQUNkLEtBQUcsQ0FBQ2UsT0FBTyxDQUFDLENBQ3JCLGdCQUFnQixDQUFDLENBQUMzQixnQkFBZ0IsQ0FBQyxHQUNuQztNQUVOLENBQUMsQ0FBQztBQUNWLE1BQU0sRUFBRSxHQUFHLENBQUM7RUFFVjs7RUFFQTtFQUNBO0VBQ0E7RUFDQSxJQUFJTixPQUFPLENBQUMsMkJBQTJCLENBQUMsRUFBRTtJQUN4QyxJQUFJSSxVQUFVLENBQUNVLElBQUksS0FBSyxpQkFBaUIsRUFBRTtNQUN6QyxJQUFJVixVQUFVLENBQUM4QixNQUFNLENBQUNiLE1BQU0sS0FBSyxDQUFDLEVBQUUsT0FBTyxJQUFJO01BQy9DO01BQ0E7TUFDQTtNQUNBLE1BQU1jLEtBQUssR0FBRy9CLFVBQVUsQ0FBQzhCLE1BQU0sQ0FDNUJaLEdBQUcsQ0FBQ2MsQ0FBQyxJQUFLQSxDQUFDLENBQUNDLE9BQU8sR0FBRyxHQUFHRCxDQUFDLENBQUNFLElBQUksS0FBS0YsQ0FBQyxDQUFDQyxPQUFPLEdBQUcsR0FBR0QsQ0FBQyxDQUFDRSxJQUFLLENBQUMsQ0FDM0RDLElBQUksQ0FBQyxJQUFJLENBQUM7TUFDYixNQUFNQyxPQUFPLEdBQUdwQyxVQUFVLENBQUM4QixNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUVHLE9BQU87TUFDN0MsTUFBTUksSUFBSSxHQUNSLFVBQVUsS0FBSyxLQUFLLElBQUksQ0FBQy9CLFNBQVMsSUFBSThCLE9BQU8sR0FDekMsc0JBQXNCQSxPQUFPLG1DQUFtQyxHQUNoRSxFQUFFO01BQ1IsT0FDRSxDQUFDLElBQUk7QUFDYixVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDcEMsVUFBVSxDQUFDOEIsTUFBTSxDQUFDYixNQUFNLENBQUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUc7QUFDbkUsVUFBVSxDQUFDL0IsTUFBTSxDQUFDYyxVQUFVLENBQUM4QixNQUFNLENBQUNiLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQyxFQUFFLENBQUNjLEtBQUs7QUFDN0QsVUFBVSxDQUFDTSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUNBLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQztBQUMvQyxRQUFRLEVBQUUsSUFBSSxDQUFDO0lBRVg7RUFDRjs7RUFFQTtFQUNBLFFBQVFyQyxVQUFVLENBQUNVLElBQUk7SUFDckIsS0FBSyxXQUFXO01BQ2QsT0FDRSxDQUFDLElBQUk7QUFDYiwyQkFBMkIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUNWLFVBQVUsQ0FBQ3NDLFdBQVcsR0FBRzVELEdBQUcsQ0FBQyxFQUFFLElBQUk7QUFDMUUsUUFBUSxFQUFFLElBQUksQ0FBQztJQUVYLEtBQUssTUFBTTtJQUNYLEtBQUssbUJBQW1CO01BQ3RCLElBQUlzQixVQUFVLENBQUN1QyxPQUFPLENBQUM3QixJQUFJLEtBQUssVUFBVSxFQUFFO1FBQzFDLE9BQ0UsQ0FBQyxJQUFJO0FBQ2YsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDVixVQUFVLENBQUNzQyxXQUFXLENBQUMsRUFBRSxJQUFJLENBQUM7QUFDM0QsWUFBWSxDQUFDdEMsVUFBVSxDQUFDdUMsT0FBTyxDQUFDQyxJQUFJLENBQUNDLEtBQUssQ0FBQ3hCLE1BQU0sQ0FBQztBQUNsRCxVQUFVLEVBQUUsSUFBSSxDQUFDO01BRVg7TUFDQSxJQUFJakIsVUFBVSxDQUFDdUMsT0FBTyxDQUFDN0IsSUFBSSxLQUFLLGdCQUFnQixFQUFFO1FBQ2hELE9BQ0UsQ0FBQyxJQUFJO0FBQ2YsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDVixVQUFVLENBQUNzQyxXQUFXLENBQUMsRUFBRSxJQUFJLENBQUM7QUFDM0QsVUFBVSxFQUFFLElBQUksQ0FBQztNQUVYO01BQ0EsT0FDRSxDQUFDLElBQUk7QUFDYixlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDdEMsVUFBVSxDQUFDc0MsV0FBVyxDQUFDLEVBQUUsSUFBSSxDQUFDO0FBQ3pELFVBQVUsQ0FBQ3RDLFVBQVUsQ0FBQ3VDLE9BQU8sQ0FBQzdCLElBQUksS0FBSyxNQUFNLEdBQy9CLEdBQUdWLFVBQVUsQ0FBQ3VDLE9BQU8sQ0FBQ0MsSUFBSSxDQUFDRSxRQUFRLEdBQUcxQyxVQUFVLENBQUMyQyxTQUFTLEdBQUcsR0FBRyxHQUFHLEVBQUUsUUFBUSxHQUM3RXBFLGNBQWMsQ0FBQ3lCLFVBQVUsQ0FBQ3VDLE9BQU8sQ0FBQ0MsSUFBSSxDQUFDSSxZQUFZLENBQUM7QUFDbEU7QUFDQSxRQUFRLEVBQUUsSUFBSSxDQUFDO0lBRVgsS0FBSyx3QkFBd0I7TUFDM0IsT0FDRSxDQUFDLElBQUk7QUFDYiwwQkFBMEIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM1QyxVQUFVLENBQUNzQyxXQUFXLENBQUMsRUFBRSxJQUFJO0FBQ25FLFFBQVEsRUFBRSxJQUFJLENBQUM7SUFFWCxLQUFLLGVBQWU7TUFDbEIsT0FDRSxDQUFDLElBQUk7QUFDYix5QkFBeUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUN0QyxVQUFVLENBQUNzQyxXQUFXLENBQUMsRUFBRSxJQUFJLENBQUM7QUFDbkUsVUFBVSxDQUFDdEMsVUFBVSxDQUFDNkMsU0FBUyxDQUFDO0FBQ2hDLFFBQVEsRUFBRSxJQUFJLENBQUM7SUFFWCxLQUFLLHVCQUF1QjtNQUMxQixPQUNFLENBQUMsSUFBSTtBQUNiLG9CQUFvQixDQUFDLEdBQUc7QUFDeEIsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQzdDLFVBQVUsQ0FBQzhDLE9BQU8sR0FBRzlDLFVBQVUsQ0FBQytDLFNBQVMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHO0FBQy9FLHFCQUFxQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQy9DLFVBQVUsQ0FBQ3NDLFdBQVcsQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRztBQUN0RSxVQUFVLENBQUN0QyxVQUFVLENBQUNnRCxPQUFPO0FBQzdCLFFBQVEsRUFBRSxJQUFJLENBQUM7SUFFWCxLQUFLLGVBQWU7TUFDbEIsT0FDRSxDQUFDLElBQUk7QUFDYixpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUNoRCxVQUFVLENBQUNzQyxXQUFXLENBQUMsRUFBRSxJQUFJO0FBQzFELFFBQVEsRUFBRSxJQUFJLENBQUM7SUFFWCxLQUFLLG1CQUFtQjtNQUN0QjtNQUNBO01BQ0E7TUFDQTtNQUNBLE9BQ0UsQ0FBQyxHQUFHLENBQ0YsYUFBYSxDQUFDLFFBQVEsQ0FDdEIsU0FBUyxDQUFDLENBQUN2QyxTQUFTLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUM3QixlQUFlLENBQUMsQ0FBQ00sRUFBRSxDQUFDO0FBRTlCLFVBQVUsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEtBQUs7QUFDbEMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDN0IsWUFBWSxDQUFDLElBQUksQ0FBQyxRQUFRO0FBQzFCLHVCQUF1QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQ0wsVUFBVSxDQUFDaUQsUUFBUSxDQUFDaEMsTUFBTSxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsR0FBRztBQUN6RSxjQUFjLENBQUNqQixVQUFVLENBQUNpRCxRQUFRLENBQUNoQyxNQUFNLEtBQUssQ0FBQyxHQUFHLFFBQVEsR0FBRyxVQUFVO0FBQ3ZFLGNBQWMsQ0FBQyxDQUFDZixnQkFBZ0IsSUFDaEI7QUFDaEIsa0JBQWtCLENBQUMsR0FBRztBQUN0QixrQkFBa0IsQ0FBQyxhQUFhO0FBQ2hDLGdCQUFnQixHQUNEO0FBQ2YsWUFBWSxFQUFFLElBQUk7QUFDbEIsVUFBVSxFQUFFLEdBQUc7QUFDZixVQUFVLENBQUMsQ0FBQ0QsT0FBTyxJQUFJQyxnQkFBZ0IsS0FDM0JGLFVBQVUsQ0FBQ2lELFFBQVEsQ0FBQy9CLEdBQUcsQ0FBQ2dDLENBQUMsSUFDdkIsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUNBLENBQUMsQ0FBQ0MsSUFBSSxDQUFDLENBQUMsYUFBYSxDQUFDLFFBQVE7QUFDdEQsZ0JBQWdCLENBQUMsZUFBZTtBQUNoQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsUUFBUTtBQUNoQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLENBQUNELENBQUMsQ0FBQ0MsSUFBSSxDQUFDO0FBQ25ELHNCQUFzQixDQUFDMUUsUUFBUSxDQUFDeUUsQ0FBQyxDQUFDQyxJQUFJLENBQUM7QUFDdkMsb0JBQW9CLEVBQUUsWUFBWTtBQUNsQyxrQkFBa0IsRUFBRSxJQUFJO0FBQ3hCLGdCQUFnQixFQUFFLGVBQWU7QUFDakMsZ0JBQWdCLENBQUNqRCxnQkFBZ0IsSUFDZixDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDdEMsb0JBQW9CLENBQUMsSUFBSTtBQUN6QixzQkFBc0IsQ0FBQyxJQUFJLENBQUMsQ0FBQ2dELENBQUMsQ0FBQ1gsT0FBTyxDQUFDLEVBQUUsSUFBSTtBQUM3QyxvQkFBb0IsRUFBRSxJQUFJO0FBQzFCLGtCQUFrQixFQUFFLEdBQUcsQ0FDTjtBQUNqQixjQUFjLEVBQUUsR0FBRyxDQUNOLENBQUM7QUFDZCxRQUFRLEVBQUUsR0FBRyxDQUFDO0lBRVYsS0FBSyxlQUFlO01BQUU7UUFDcEIsTUFBTWEsVUFBVSxHQUFHcEQsVUFBVSxDQUFDcUQsVUFBVSxDQUFDcEMsTUFBTTtRQUMvQyxPQUNFLENBQUMsSUFBSTtBQUNiLGdCQUFnQixDQUFDLEdBQUc7QUFDcEIsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJO0FBQ3BCLFlBQVksQ0FBQ21DLFVBQVUsQ0FBQyxDQUFDLENBQUNsRSxNQUFNLENBQUNrRSxVQUFVLEVBQUUsT0FBTyxDQUFDO0FBQ3JELFVBQVUsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHO0FBQ3JCLGVBQWUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUNwRCxVQUFVLENBQUNzQyxXQUFXLENBQUMsRUFBRSxJQUFJO0FBQ3hELFFBQVEsRUFBRSxJQUFJLENBQUM7TUFFWDtJQUNBLEtBQUssZUFBZTtNQUFFO1FBQ3BCLElBQUl0QyxVQUFVLENBQUNzRCxTQUFTLEVBQUU7VUFDeEIsT0FBTyxJQUFJO1FBQ2I7UUFDQSxPQUNFLENBQUMsSUFBSTtBQUNiLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUN0RCxVQUFVLENBQUNvRCxVQUFVLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQyxHQUFHO0FBQ3ZELFVBQVUsQ0FBQ2xFLE1BQU0sQ0FBQ2MsVUFBVSxDQUFDb0QsVUFBVSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0FBQ2xELFFBQVEsRUFBRSxJQUFJLENBQUM7TUFFWDtJQUNBLEtBQUsscUJBQXFCO01BQUU7UUFDMUIsSUFBSXBELFVBQVUsQ0FBQ3NELFNBQVMsSUFBSXRELFVBQVUsQ0FBQ3VELFVBQVUsQ0FBQ3RDLE1BQU0sS0FBSyxDQUFDLEVBQUU7VUFDOUQsT0FBTyxJQUFJO1FBQ2I7UUFDQSxNQUFNdUMsS0FBSyxHQUFHeEQsVUFBVSxDQUFDdUQsVUFBVSxDQUFDdEMsTUFBTTtRQUMxQyxPQUNFLENBQUMsSUFBSTtBQUNiLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUN1QyxLQUFLLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDdEUsTUFBTSxDQUFDc0UsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO0FBQ2pFLFFBQVEsRUFBRSxJQUFJLENBQUM7TUFFWDtJQUNBLEtBQUssZ0JBQWdCO01BQUU7UUFDckIsTUFBTXpDLElBQUksR0FDUixPQUFPZixVQUFVLENBQUN5RCxNQUFNLEtBQUssUUFBUSxHQUNqQ3pELFVBQVUsQ0FBQ3lELE1BQU0sR0FDakI1RSxjQUFjLENBQUNtQixVQUFVLENBQUN5RCxNQUFNLENBQUMsSUFBSSxFQUFFO1FBQzdDLE1BQU1DLFNBQVMsR0FDYjFELFVBQVUsQ0FBQzJELGFBQWEsSUFBSTNELFVBQVUsQ0FBQzJELGFBQWEsQ0FBQzFDLE1BQU0sR0FBRyxDQUFDO1FBQ2pFLE9BQ0UsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLFFBQVE7QUFDbkMsVUFBVSxDQUFDLGVBQWUsQ0FDZCxTQUFTLENBQUMsQ0FBQ2xCLFNBQVMsQ0FBQyxDQUNyQixLQUFLLENBQUMsQ0FBQztZQUFFZ0IsSUFBSTtZQUFFTCxJQUFJLEVBQUU7VUFBTyxDQUFDLENBQUMsQ0FDOUIsT0FBTyxDQUFDLENBQUNULE9BQU8sQ0FBQyxDQUNqQixnQkFBZ0IsQ0FBQyxDQUFDQyxnQkFBZ0IsQ0FBQztBQUUvQyxVQUFVLENBQUN3RCxTQUFTLElBQ1IxRCxVQUFVLENBQUMyRCxhQUFhLEVBQUV6QyxHQUFHLENBQUMwQyxFQUFFLElBQzlCLENBQUMsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUNBLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDQSxFQUFFLENBQUMsR0FDeEMsQ0FBQztBQUNkLFFBQVEsRUFBRSxHQUFHLENBQUM7TUFFVjtJQUNBLEtBQUsscUJBQXFCO01BQ3hCLE9BQ0UsQ0FBQyxJQUFJO0FBQ2IsZ0NBQWdDLENBQUN0RixjQUFjLENBQUMwQixVQUFVLENBQUM2RCxZQUFZLENBQUMsQ0FBQztBQUN6RSxRQUFRLEVBQUUsSUFBSSxDQUFDO0lBRVgsS0FBSyxnQkFBZ0I7TUFBRTtRQUNyQixJQUFJN0QsVUFBVSxDQUFDOEIsTUFBTSxDQUFDYixNQUFNLEtBQUssQ0FBQyxFQUFFO1VBQ2xDLE9BQU8sSUFBSTtRQUNiO1FBQ0EsTUFBTW9DLFVBQVUsR0FBR3JELFVBQVUsQ0FBQzhCLE1BQU0sQ0FBQ1osR0FBRyxDQUFDYyxHQUFDLElBQUlBLEdBQUMsQ0FBQ0UsSUFBSSxDQUFDLENBQUNDLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDaEUsT0FBTyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQ2tCLFVBQVUsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDO01BQ3BEO0lBQ0EsS0FBSyxhQUFhO01BQ2hCLE9BQU8sQ0FBQyxrQkFBa0IsQ0FBQyxVQUFVLENBQUMsQ0FBQ3JELFVBQVUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDQyxPQUFPLENBQUMsR0FBRztJQUN6RSxLQUFLLGNBQWM7TUFDakIsT0FDRSxDQUFDLElBQUk7QUFDYiw0QkFBNEIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUNELFVBQVUsQ0FBQ2tDLElBQUksQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRztBQUN4RSxVQUFVLENBQUNsQyxVQUFVLENBQUM4RCxNQUFNO0FBQzVCLFFBQVEsRUFBRSxJQUFJLENBQUM7SUFFWCxLQUFLLHFCQUFxQjtNQUN4QjtNQUNBO01BQ0EsT0FBTyxJQUFJO0lBQ2IsS0FBSyxxQkFBcUI7TUFBRTtRQUMxQjtRQUNBLElBQUk5RCxVQUFVLENBQUMrRCxTQUFTLEtBQUssY0FBYyxJQUFJLENBQUM5RCxPQUFPLEVBQUU7VUFDdkQsT0FBTyxJQUFJO1FBQ2I7UUFDQTtRQUNBLElBQUksQ0FBQ0EsT0FBTyxJQUFJLENBQUNDLGdCQUFnQixFQUFFO1VBQ2pDLE9BQU8sSUFBSTtRQUNiO1FBQ0EsT0FDRSxDQUFDLElBQUk7QUFDYixxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUNGLFVBQVUsQ0FBQytELFNBQVMsQ0FBQyxFQUFFLElBQUksQ0FBQztBQUM3RCxRQUFRLEVBQUUsSUFBSSxDQUFDO01BRVg7SUFDQSxLQUFLLHFCQUFxQjtNQUFFO1FBQzFCO1FBQ0EsSUFDRS9ELFVBQVUsQ0FBQytELFNBQVMsS0FBSyxNQUFNLElBQy9CL0QsVUFBVSxDQUFDK0QsU0FBUyxLQUFLLGNBQWMsRUFDdkM7VUFDQSxPQUFPLElBQUk7UUFDYjtRQUNBO1FBQ0EsTUFBTUMsTUFBTSxHQUFHaEUsVUFBVSxDQUFDaUUsYUFBYSxDQUFDQSxhQUFhLENBQUNDLElBQUksQ0FBQyxDQUFDO1FBQzVELE9BQ0U7QUFDUixVQUFVLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPO0FBQzdCLFlBQVksQ0FBQ2xFLFVBQVUsQ0FBQ21FLFFBQVEsQ0FBQztBQUNqQyxVQUFVLEVBQUUsSUFBSTtBQUNoQixVQUFVLENBQUNILE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUNBLE1BQU0sQ0FBQyxFQUFFLElBQUksQ0FBQyxHQUFHLElBQUk7QUFDOUQsUUFBUSxHQUFHO01BRVA7SUFDQSxLQUFLLHlCQUF5QjtNQUFFO1FBQzlCO1FBQ0EsSUFDRWhFLFVBQVUsQ0FBQytELFNBQVMsS0FBSyxNQUFNLElBQy9CL0QsVUFBVSxDQUFDK0QsU0FBUyxLQUFLLGNBQWMsRUFDdkM7VUFDQSxPQUFPLElBQUk7UUFDYjtRQUNBO1FBQ0EsT0FBTyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMvRCxVQUFVLENBQUNtRSxRQUFRLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQztNQUNwRTtJQUNBLEtBQUssNkJBQTZCO01BQ2hDO01BQ0EsSUFDRW5FLFVBQVUsQ0FBQytELFNBQVMsS0FBSyxNQUFNLElBQy9CL0QsVUFBVSxDQUFDK0QsU0FBUyxLQUFLLGNBQWMsRUFDdkM7UUFDQSxPQUFPLElBQUk7TUFDYjtNQUNBO01BQ0EsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDL0QsVUFBVSxDQUFDbUUsUUFBUSxDQUFDLGFBQWEsRUFBRSxJQUFJLENBQUM7SUFDeEQsS0FBSyxjQUFjO01BQ2pCO01BQ0EsT0FBTyxJQUFJO0lBQ2IsS0FBSywyQkFBMkI7TUFDOUI7TUFDQSxJQUNFbkUsVUFBVSxDQUFDK0QsU0FBUyxLQUFLLE1BQU0sSUFDL0IvRCxVQUFVLENBQUMrRCxTQUFTLEtBQUssY0FBYyxFQUN2QztRQUNBLE9BQU8sSUFBSTtNQUNiO01BQ0EsT0FDRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUztBQUM3QixVQUFVLENBQUMvRCxVQUFVLENBQUNtRSxRQUFRLENBQUMsNEJBQTRCLENBQUNuRSxVQUFVLENBQUNvRSxPQUFPO0FBQzlFLFFBQVEsRUFBRSxJQUFJLENBQUM7SUFFWCxLQUFLLHFCQUFxQjtNQUN4QixPQUNFLENBQUMsSUFBSTtBQUNiLFVBQVUsQ0FBQ3BFLFVBQVUsQ0FBQ21FLFFBQVEsQ0FBQyxPQUFPLENBQUNuRSxVQUFVLENBQUN1QyxPQUFPO0FBQ3pELFFBQVEsRUFBRSxJQUFJLENBQUM7SUFFWCxLQUFLLDBCQUEwQjtNQUFFO1FBQy9CLE1BQU04QixNQUFNLEdBQUdyRSxVQUFVLENBQUNzRSxRQUFRLEtBQUssT0FBTyxHQUFHLFNBQVMsR0FBRyxRQUFRO1FBQ3JFLE9BQ0UsQ0FBQyxJQUFJO0FBQ2IsVUFBVSxDQUFDRCxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQ3JFLFVBQVUsQ0FBQytELFNBQVMsQ0FBQyxFQUFFLElBQUksQ0FBQztBQUM5RCxRQUFRLEVBQUUsSUFBSSxDQUFDO01BRVg7SUFDQSxLQUFLLGFBQWE7TUFDaEIsT0FBTyxDQUFDLGlCQUFpQixDQUFDLFVBQVUsQ0FBQyxDQUFDL0QsVUFBVSxDQUFDLEdBQUc7SUFDdEQsS0FBSyx5QkFBeUI7TUFDNUIsT0FDRSxDQUFDLEdBQUcsQ0FDRixhQUFhLENBQUMsS0FBSyxDQUNuQixLQUFLLENBQUMsTUFBTSxDQUNaLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUNiLGVBQWUsQ0FBQyxDQUFDSyxFQUFFLENBQUM7QUFFOUIsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQ2QsWUFBWSxDQUFDLENBQUMsRUFBRSxJQUFJO0FBQzlDLFVBQVUsQ0FBQyxJQUFJLENBQUMsUUFBUTtBQUN4QixZQUFZLENBQUNTLFVBQVUsQ0FBQ3dELEtBQUssQ0FBQyxDQUFDLENBQUN0RSxNQUFNLENBQUNjLFVBQVUsQ0FBQ3dELEtBQUssRUFBRSxVQUFVLENBQUMsQ0FBQztBQUNyRTtBQUNBLFVBQVUsRUFBRSxJQUFJO0FBQ2hCLFFBQVEsRUFBRSxHQUFHLENBQUM7SUFFVjtNQUNFO01BQ0E7TUFDQTtNQUNBO01BQ0E7TUFDQTtNQUNBO01BQ0E7TUFDQTtNQUNBeEQsVUFBVSxDQUFDVSxJQUFJLFdBQ1h0QywyQkFBMkIsR0FDM0IsaUJBQWlCLEdBQ2pCLGtCQUFrQjtNQUN0QixPQUFPLElBQUk7RUFDZjtBQUNGO0FBRUEsS0FBS21HLG9CQUFvQixHQUFHQyxPQUFPLENBQUNyRyxVQUFVLEVBQUU7RUFBRXVDLElBQUksRUFBRSxhQUFhO0FBQUMsQ0FBQyxDQUFDO0FBRXhFLFNBQUErRCxrQkFBQUMsRUFBQTtFQUFBLE1BQUFDLENBQUEsR0FBQUMsRUFBQTtFQUEyQjtJQUFBNUU7RUFBQSxJQUFBMEUsRUFJMUI7RUFHQyxJQUFJLEtBQXNELElBQTlCMUUsVUFBVSxDQUFBNkUsTUFBTyxLQUFLLFFBQVE7SUFBQSxPQUNqRCxJQUFJO0VBQUE7RUFNYixJQUFJekYsb0JBQW9CLENBQWtELENBQUMsSUFBN0NZLFVBQVUsQ0FBQThFLFFBQVMsS0FBSyxxQkFBcUI7SUFBQSxJQUFBQyxFQUFBO0lBQUEsSUFBQUosQ0FBQSxRQUFBM0UsVUFBQTtNQUNsRStFLEVBQUEsSUFBQyxrQkFBa0IsQ0FBYS9FLFVBQVUsQ0FBVkEsV0FBUyxDQUFDLEdBQUk7TUFBQTJFLENBQUEsTUFBQTNFLFVBQUE7TUFBQTJFLENBQUEsTUFBQUksRUFBQTtJQUFBO01BQUFBLEVBQUEsR0FBQUosQ0FBQTtJQUFBO0lBQUEsT0FBOUNJLEVBQThDO0VBQUE7RUFDdEQsSUFBQUEsRUFBQTtFQUFBLElBQUFKLENBQUEsUUFBQTNFLFVBQUE7SUFFTStFLEVBQUEsSUFBQyxpQkFBaUIsQ0FBYS9FLFVBQVUsQ0FBVkEsV0FBUyxDQUFDLEdBQUk7SUFBQTJFLENBQUEsTUFBQTNFLFVBQUE7SUFBQTJFLENBQUEsTUFBQUksRUFBQTtFQUFBO0lBQUFBLEVBQUEsR0FBQUosQ0FBQTtFQUFBO0VBQUEsT0FBN0NJLEVBQTZDO0FBQUE7QUFHdEQsU0FBQUMsa0JBQUFOLEVBQUE7RUFBQSxNQUFBQyxDQUFBLEdBQUFDLEVBQUE7RUFBMkI7SUFBQTVFO0VBQUEsSUFBQTBFLEVBSTFCO0VBQ0MsTUFBQXJFLEVBQUEsR0FBV1Isb0JBQW9CLENBQUMsQ0FBQztFQUNqQyxNQUFBb0YsVUFBQSxHQUNFakYsVUFBVSxDQUFBNkUsTUFBTyxLQUFLLFdBTUcsR0FOekIseUJBTXlCLEdBSnJCN0UsVUFBVSxDQUFBNkUsTUFBTyxLQUFLLFFBSUQsR0FKckIsU0FJcUIsR0FGbkI3RSxVQUFVLENBQUE2RSxNQUFPLEtBQUssU0FFSCxHQUZuQiw2QkFFbUIsR0FBakI3RSxVQUFVLENBQUE2RSxNQUFPO0VBQUEsSUFBQUUsRUFBQTtFQUFBLElBQUFKLENBQUEsUUFBQU8sTUFBQSxDQUFBQyxHQUFBO0lBR3ZCSixFQUFBLElBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBUixLQUFPLENBQUMsQ0FBRXhGLGFBQVcsQ0FBRSxDQUFDLEVBQTdCLElBQUksQ0FBZ0M7SUFBQW9GLENBQUEsTUFBQUksRUFBQTtFQUFBO0lBQUFBLEVBQUEsR0FBQUosQ0FBQTtFQUFBO0VBQUEsSUFBQVMsRUFBQTtFQUFBLElBQUFULENBQUEsUUFBQTNFLFVBQUEsQ0FBQXFGLFdBQUE7SUFFeEJELEVBQUEsSUFBQyxJQUFJLENBQUMsSUFBSSxDQUFKLEtBQUcsQ0FBQyxDQUFFLENBQUFwRixVQUFVLENBQUFxRixXQUFXLENBQUUsRUFBbEMsSUFBSSxDQUFxQztJQUFBVixDQUFBLE1BQUEzRSxVQUFBLENBQUFxRixXQUFBO0lBQUFWLENBQUEsTUFBQVMsRUFBQTtFQUFBO0lBQUFBLEVBQUEsR0FBQVQsQ0FBQTtFQUFBO0VBQUEsSUFBQVcsRUFBQTtFQUFBLElBQUFYLENBQUEsUUFBQU0sVUFBQSxJQUFBTixDQUFBLFFBQUFTLEVBQUE7SUFEdkRFLEVBQUEsSUFBQyxJQUFJLENBQUMsUUFBUSxDQUFSLEtBQU8sQ0FBQyxDQUFDLE1BQ0YsQ0FBQUYsRUFBeUMsQ0FBQyxFQUFRSCxXQUFTLENBQ3hFLEVBRkMsSUFBSSxDQUVFO0lBQUFOLENBQUEsTUFBQU0sVUFBQTtJQUFBTixDQUFBLE1BQUFTLEVBQUE7SUFBQVQsQ0FBQSxNQUFBVyxFQUFBO0VBQUE7SUFBQUEsRUFBQSxHQUFBWCxDQUFBO0VBQUE7RUFBQSxJQUFBWSxFQUFBO0VBQUEsSUFBQVosQ0FBQSxRQUFBdEUsRUFBQSxJQUFBc0UsQ0FBQSxRQUFBVyxFQUFBO0lBSlRDLEVBQUEsSUFBQyxHQUFHLENBQWUsYUFBSyxDQUFMLEtBQUssQ0FBTyxLQUFNLENBQU4sTUFBTSxDQUFZLFNBQUMsQ0FBRCxHQUFDLENBQW1CbEYsZUFBRSxDQUFGQSxHQUFDLENBQUMsQ0FDckUsQ0FBQTBFLEVBQW9DLENBQ3BDLENBQUFPLEVBRU0sQ0FDUixFQUxDLEdBQUcsQ0FLRTtJQUFBWCxDQUFBLE1BQUF0RSxFQUFBO0lBQUFzRSxDQUFBLE1BQUFXLEVBQUE7SUFBQVgsQ0FBQSxNQUFBWSxFQUFBO0VBQUE7SUFBQUEsRUFBQSxHQUFBWixDQUFBO0VBQUE7RUFBQSxPQUxOWSxFQUtNO0FBQUE7QUFJVixTQUFBQyxtQkFBQWQsRUFBQTtFQUFBLE1BQUFDLENBQUEsR0FBQUMsRUFBQTtFQUE0QjtJQUFBNUU7RUFBQSxJQUFBMEUsRUFJM0I7RUFDQyxNQUFBckUsRUFBQSxHQUFXUixvQkFBb0IsQ0FBQyxDQUFDO0VBQUEsSUFBQWtGLEVBQUE7RUFBQSxJQUFBSixDQUFBLFFBQUEzRSxVQUFBLENBQUFxQixNQUFBO0lBRVIwRCxFQUFBLEdBQUEvQyxDQUFBLElBQUtBLENBQUMsQ0FBQXlELEtBQU0sQ0FBQ3pGLFVBQVUsQ0FBQXFCLE1BQU8sQ0FBQztJQUFBc0QsQ0FBQSxNQUFBM0UsVUFBQSxDQUFBcUIsTUFBQTtJQUFBc0QsQ0FBQSxNQUFBSSxFQUFBO0VBQUE7SUFBQUEsRUFBQSxHQUFBSixDQUFBO0VBQUE7RUFBeEQsTUFBQWUsSUFBQSxHQUFhckgsV0FBVyxDQUFDMEcsRUFBK0IsQ0FBQztFQUN6RCxJQUFJVyxJQUFJLEVBQUFoRixJQUFNLEtBQUsscUJBQXFCO0lBQUEsSUFBQTBFLEVBQUE7SUFBQSxJQUFBVCxDQUFBLFFBQUEzRSxVQUFBO01BRS9Cb0YsRUFBQSxJQUFDLGlCQUFpQixDQUFhcEYsVUFBVSxDQUFWQSxXQUFTLENBQUMsR0FBSTtNQUFBMkUsQ0FBQSxNQUFBM0UsVUFBQTtNQUFBMkUsQ0FBQSxNQUFBUyxFQUFBO0lBQUE7TUFBQUEsRUFBQSxHQUFBVCxDQUFBO0lBQUE7SUFBQSxPQUE3Q1MsRUFBNkM7RUFBQTtFQUNyRCxJQUFBQSxFQUFBO0VBQUEsSUFBQVQsQ0FBQSxRQUFBZSxJQUFBLENBQUFDLFFBQUEsQ0FBQWhFLEtBQUE7SUFDa0J5RCxFQUFBLEdBQUFwRyxVQUFVLENBQUMwRyxJQUFJLENBQUFDLFFBQVMsQ0FBQWhFLEtBQU0sQ0FBQztJQUFBZ0QsQ0FBQSxNQUFBZSxJQUFBLENBQUFDLFFBQUEsQ0FBQWhFLEtBQUE7SUFBQWdELENBQUEsTUFBQVMsRUFBQTtFQUFBO0lBQUFBLEVBQUEsR0FBQVQsQ0FBQTtFQUFBO0VBQWxELE1BQUFpQixVQUFBLEdBQW1CUixFQUErQjtFQUNsRCxNQUFBSCxVQUFBLEdBQ0VqRixVQUFVLENBQUE2RSxNQUFPLEtBQUssV0FFRCxHQUZyQixzQkFFcUIsR0FBakI3RSxVQUFVLENBQUE2RSxNQUFPO0VBQUEsSUFBQVMsRUFBQTtFQUFBLElBQUFYLENBQUEsUUFBQU8sTUFBQSxDQUFBQyxHQUFBO0lBR25CRyxFQUFBLElBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBUixLQUFPLENBQUMsQ0FBRS9GLGFBQVcsQ0FBRSxDQUFDLEVBQTdCLElBQUksQ0FBZ0M7SUFBQW9GLENBQUEsTUFBQVcsRUFBQTtFQUFBO0lBQUFBLEVBQUEsR0FBQVgsQ0FBQTtFQUFBO0VBQUEsSUFBQVksRUFBQTtFQUFBLElBQUFaLENBQUEsUUFBQWlCLFVBQUEsSUFBQWpCLENBQUEsUUFBQWUsSUFBQSxDQUFBQyxRQUFBLENBQUFFLFNBQUE7SUFHbkNOLEVBQUEsSUFBQyxJQUFJLENBQVFLLEtBQVUsQ0FBVkEsV0FBUyxDQUFDLENBQUUsSUFBSSxDQUFKLEtBQUcsQ0FBQyxDQUFXLFFBQUssQ0FBTCxNQUFJLENBQUMsQ0FBRSxDQUMzQyxDQUFBRixJQUFJLENBQUFDLFFBQVMsQ0FBQUUsU0FBUyxDQUMxQixFQUZDLElBQUksQ0FFRTtJQUFBbEIsQ0FBQSxNQUFBaUIsVUFBQTtJQUFBakIsQ0FBQSxNQUFBZSxJQUFBLENBQUFDLFFBQUEsQ0FBQUUsU0FBQTtJQUFBbEIsQ0FBQSxNQUFBWSxFQUFBO0VBQUE7SUFBQUEsRUFBQSxHQUFBWixDQUFBO0VBQUE7RUFBQSxJQUFBbUIsRUFBQTtFQUFBLElBQUFuQixDQUFBLFNBQUFNLFVBQUEsSUFBQU4sQ0FBQSxTQUFBWSxFQUFBO0lBSlRPLEVBQUEsSUFBQyxJQUFJLENBQUMsUUFBUSxDQUFSLEtBQU8sQ0FBQyxDQUFDLFFBQ0osSUFBRSxDQUNYLENBQUFQLEVBRU0sQ0FBRSxJQUFFLENBQ1ROLFdBQVMsQ0FDWixFQU5DLElBQUksQ0FNRTtJQUFBTixDQUFBLE9BQUFNLFVBQUE7SUFBQU4sQ0FBQSxPQUFBWSxFQUFBO0lBQUFaLENBQUEsT0FBQW1CLEVBQUE7RUFBQTtJQUFBQSxFQUFBLEdBQUFuQixDQUFBO0VBQUE7RUFBQSxJQUFBb0IsRUFBQTtFQUFBLElBQUFwQixDQUFBLFNBQUF0RSxFQUFBLElBQUFzRSxDQUFBLFNBQUFtQixFQUFBO0lBUlRDLEVBQUEsSUFBQyxHQUFHLENBQWUsYUFBSyxDQUFMLEtBQUssQ0FBTyxLQUFNLENBQU4sTUFBTSxDQUFZLFNBQUMsQ0FBRCxHQUFDLENBQW1CMUYsZUFBRSxDQUFGQSxHQUFDLENBQUMsQ0FDckUsQ0FBQWlGLEVBQW9DLENBQ3BDLENBQUFRLEVBTU0sQ0FDUixFQVRDLEdBQUcsQ0FTRTtJQUFBbkIsQ0FBQSxPQUFBdEUsRUFBQTtJQUFBc0UsQ0FBQSxPQUFBbUIsRUFBQTtJQUFBbkIsQ0FBQSxPQUFBb0IsRUFBQTtFQUFBO0lBQUFBLEVBQUEsR0FBQXBCLENBQUE7RUFBQTtFQUFBLE9BVE5vQixFQVNNO0FBQUE7QUFHVjtBQUNBO0FBQ0EsU0FBQUMsS0FBQXRCLEVBQUE7RUFBQSxNQUFBQyxDQUFBLEdBQUFDLEVBQUE7RUFBYztJQUFBcUIsUUFBQSxFQUFBbEIsRUFBQTtJQUFBbUIsUUFBQTtJQUFBdkU7RUFBQSxJQUFBK0MsRUFRYjtFQVBDLE1BQUF1QixRQUFBLEdBQUFsQixFQUFlLEtBQWZvQixTQUFlLEdBQWYsSUFBZSxHQUFmcEIsRUFBZTtFQVFmLE1BQUExRSxFQUFBLEdBQVdSLG9CQUFvQixDQUFDLENBQUM7RUFBQSxJQUFBdUYsRUFBQTtFQUFBLElBQUFULENBQUEsUUFBQXVCLFFBQUEsSUFBQXZCLENBQUEsUUFBQWhELEtBQUEsSUFBQWdELENBQUEsUUFBQXNCLFFBQUE7SUFHN0JiLEVBQUEsSUFBQyxlQUFlLENBQ2QsQ0FBQyxJQUFJLENBQVF6RCxLQUFLLENBQUxBLE1BQUksQ0FBQyxDQUFZc0UsUUFBUSxDQUFSQSxTQUFPLENBQUMsQ0FBTyxJQUFNLENBQU4sTUFBTSxDQUNoREMsU0FBTyxDQUNWLEVBRkMsSUFBSSxDQUdQLEVBSkMsZUFBZSxDQUlFO0lBQUF2QixDQUFBLE1BQUF1QixRQUFBO0lBQUF2QixDQUFBLE1BQUFoRCxLQUFBO0lBQUFnRCxDQUFBLE1BQUFzQixRQUFBO0lBQUF0QixDQUFBLE1BQUFTLEVBQUE7RUFBQTtJQUFBQSxFQUFBLEdBQUFULENBQUE7RUFBQTtFQUFBLElBQUFXLEVBQUE7RUFBQSxJQUFBWCxDQUFBLFFBQUF0RSxFQUFBLElBQUFzRSxDQUFBLFFBQUFTLEVBQUE7SUFMcEJFLEVBQUEsSUFBQyxHQUFHLENBQWtCakYsZUFBRSxDQUFGQSxHQUFDLENBQUMsQ0FDdEIsQ0FBQStFLEVBSWlCLENBQ25CLEVBTkMsR0FBRyxDQU1FO0lBQUFULENBQUEsTUFBQXRFLEVBQUE7SUFBQXNFLENBQUEsTUFBQVMsRUFBQTtJQUFBVCxDQUFBLE1BQUFXLEVBQUE7RUFBQTtJQUFBQSxFQUFBLEdBQUFYLENBQUE7RUFBQTtFQUFBLE9BTk5XLEVBTU07QUFBQSIsImlnbm9yZUxpc3QiOltdfQ==