mirror of
http://10.0.2.1:3031/sauer/claude-code.git
synced 2026-06-30 14:16:58 +10:00
368 lines
44 KiB
TypeScript
368 lines
44 KiB
TypeScript
|
|
import { c as _c } from "react/compiler-runtime";
|
||
|
|
import type { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs';
|
||
|
|
import React, { useMemo } from 'react';
|
||
|
|
import { useTerminalSize } from 'src/hooks/useTerminalSize.js';
|
||
|
|
import type { ThemeName } from 'src/utils/theme.js';
|
||
|
|
import type { Command } from '../../commands.js';
|
||
|
|
import { BLACK_CIRCLE } from '../../constants/figures.js';
|
||
|
|
import { stringWidth } from '../../ink/stringWidth.js';
|
||
|
|
import { Box, Text, useTheme } from '../../ink.js';
|
||
|
|
import { useAppStateMaybeOutsideOfProvider } from '../../state/AppState.js';
|
||
|
|
import { findToolByName, type Tool, type ToolProgressData, type Tools } from '../../Tool.js';
|
||
|
|
import type { ProgressMessage } from '../../types/message.js';
|
||
|
|
import { useIsClassifierChecking } from '../../utils/classifierApprovalsHook.js';
|
||
|
|
import { logError } from '../../utils/log.js';
|
||
|
|
import type { buildMessageLookups } from '../../utils/messages.js';
|
||
|
|
import { MessageResponse } from '../MessageResponse.js';
|
||
|
|
import { useSelectedMessageBg } from '../messageActions.js';
|
||
|
|
import { SentryErrorBoundary } from '../SentryErrorBoundary.js';
|
||
|
|
import { ToolUseLoader } from '../ToolUseLoader.js';
|
||
|
|
import { HookProgressMessage } from './HookProgressMessage.js';
|
||
|
|
type Props = {
|
||
|
|
param: ToolUseBlockParam;
|
||
|
|
addMargin: boolean;
|
||
|
|
tools: Tools;
|
||
|
|
commands: Command[];
|
||
|
|
verbose: boolean;
|
||
|
|
inProgressToolUseIDs: Set<string>;
|
||
|
|
progressMessagesForMessage: ProgressMessage[];
|
||
|
|
shouldAnimate: boolean;
|
||
|
|
shouldShowDot: boolean;
|
||
|
|
inProgressToolCallCount?: number;
|
||
|
|
lookups: ReturnType<typeof buildMessageLookups>;
|
||
|
|
isTranscriptMode?: boolean;
|
||
|
|
};
|
||
|
|
export function AssistantToolUseMessage(t0) {
|
||
|
|
const $ = _c(81);
|
||
|
|
const {
|
||
|
|
param,
|
||
|
|
addMargin,
|
||
|
|
tools,
|
||
|
|
commands,
|
||
|
|
verbose,
|
||
|
|
inProgressToolUseIDs,
|
||
|
|
progressMessagesForMessage,
|
||
|
|
shouldAnimate,
|
||
|
|
shouldShowDot,
|
||
|
|
inProgressToolCallCount,
|
||
|
|
lookups,
|
||
|
|
isTranscriptMode
|
||
|
|
} = t0;
|
||
|
|
const terminalSize = useTerminalSize();
|
||
|
|
const [theme] = useTheme();
|
||
|
|
const bg = useSelectedMessageBg();
|
||
|
|
const pendingWorkerRequest = useAppStateMaybeOutsideOfProvider(_temp);
|
||
|
|
const isClassifierCheckingRaw = useIsClassifierChecking(param.id);
|
||
|
|
const permissionMode = useAppStateMaybeOutsideOfProvider(_temp2);
|
||
|
|
const hasStrippedRules = useAppStateMaybeOutsideOfProvider(_temp3);
|
||
|
|
const isAutoClassifier = permissionMode === "auto" || permissionMode === "plan" && hasStrippedRules;
|
||
|
|
const isClassifierChecking = false && isClassifierCheckingRaw && permissionMode !== "auto";
|
||
|
|
let t1;
|
||
|
|
if ($[0] !== param.input || $[1] !== param.name || $[2] !== tools) {
|
||
|
|
bb0: {
|
||
|
|
if (!tools) {
|
||
|
|
t1 = null;
|
||
|
|
break bb0;
|
||
|
|
}
|
||
|
|
const tool = findToolByName(tools, param.name);
|
||
|
|
if (!tool) {
|
||
|
|
t1 = null;
|
||
|
|
break bb0;
|
||
|
|
}
|
||
|
|
const input = tool.inputSchema.safeParse(param.input);
|
||
|
|
const data = input.success ? input.data : undefined;
|
||
|
|
t1 = {
|
||
|
|
tool,
|
||
|
|
input,
|
||
|
|
userFacingToolName: tool.userFacingName(data),
|
||
|
|
userFacingToolNameBackgroundColor: tool.userFacingNameBackgroundColor?.(data),
|
||
|
|
isTransparentWrapper: tool.isTransparentWrapper?.() ?? false
|
||
|
|
};
|
||
|
|
}
|
||
|
|
$[0] = param.input;
|
||
|
|
$[1] = param.name;
|
||
|
|
$[2] = tools;
|
||
|
|
$[3] = t1;
|
||
|
|
} else {
|
||
|
|
t1 = $[3];
|
||
|
|
}
|
||
|
|
const parsed = t1;
|
||
|
|
if (!parsed) {
|
||
|
|
logError(new Error(tools ? `Tool ${param.name} not found` : `Tools array is undefined for tool ${param.name}`));
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
const {
|
||
|
|
tool: tool_0,
|
||
|
|
input: input_0,
|
||
|
|
userFacingToolName,
|
||
|
|
userFacingToolNameBackgroundColor,
|
||
|
|
isTransparentWrapper
|
||
|
|
} = parsed;
|
||
|
|
let t2;
|
||
|
|
if ($[4] !== lookups.resolvedToolUseIDs || $[5] !== param.id) {
|
||
|
|
t2 = lookups.resolvedToolUseIDs.has(param.id);
|
||
|
|
$[4] = lookups.resolvedToolUseIDs;
|
||
|
|
$[5] = param.id;
|
||
|
|
$[6] = t2;
|
||
|
|
} else {
|
||
|
|
t2 = $[6];
|
||
|
|
}
|
||
|
|
const isResolved = t2;
|
||
|
|
let t3;
|
||
|
|
if ($[7] !== inProgressToolUseIDs || $[8] !== isResolved || $[9] !== param.id) {
|
||
|
|
t3 = !inProgressToolUseIDs.has(param.id) && !isResolved;
|
||
|
|
$[7] = inProgressToolUseIDs;
|
||
|
|
$[8] = isResolved;
|
||
|
|
$[9] = param.id;
|
||
|
|
$[10] = t3;
|
||
|
|
} else {
|
||
|
|
t3 = $[10];
|
||
|
|
}
|
||
|
|
const isQueued = t3;
|
||
|
|
const isWaitingForPermission = pendingWorkerRequest?.toolUseId === param.id;
|
||
|
|
if (isTransparentWrapper) {
|
||
|
|
if (isQueued || isResolved) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
let t4;
|
||
|
|
if ($[11] !== inProgressToolCallCount || $[12] !== isTranscriptMode || $[13] !== lookups || $[14] !== param.id || $[15] !== progressMessagesForMessage || $[16] !== terminalSize || $[17] !== tool_0 || $[18] !== tools || $[19] !== verbose) {
|
||
|
|
t4 = renderToolUseProgressMessage(tool_0, tools, lookups, param.id, progressMessagesForMessage, {
|
||
|
|
verbose,
|
||
|
|
inProgressToolCallCount,
|
||
|
|
isTranscriptMode
|
||
|
|
}, terminalSize);
|
||
|
|
$[11] = inProgressToolCallCount;
|
||
|
|
$[12] = isTranscriptMode;
|
||
|
|
$[13] = lookups;
|
||
|
|
$[14] = param.id;
|
||
|
|
$[15] = progressMessagesForMessage;
|
||
|
|
$[16] = terminalSize;
|
||
|
|
$[17] = tool_0;
|
||
|
|
$[18] = tools;
|
||
|
|
$[19] = verbose;
|
||
|
|
$[20] = t4;
|
||
|
|
} else {
|
||
|
|
t4 = $[20];
|
||
|
|
}
|
||
|
|
let t5;
|
||
|
|
if ($[21] !== bg || $[22] !== t4) {
|
||
|
|
t5 = <Box flexDirection="column" width="100%" backgroundColor={bg}>{t4}</Box>;
|
||
|
|
$[21] = bg;
|
||
|
|
$[22] = t4;
|
||
|
|
$[23] = t5;
|
||
|
|
} else {
|
||
|
|
t5 = $[23];
|
||
|
|
}
|
||
|
|
return t5;
|
||
|
|
}
|
||
|
|
if (userFacingToolName === "") {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
let t4;
|
||
|
|
if ($[24] !== commands || $[25] !== input_0.data || $[26] !== input_0.success || $[27] !== theme || $[28] !== tool_0 || $[29] !== verbose) {
|
||
|
|
t4 = input_0.success ? renderToolUseMessage(tool_0, input_0.data, {
|
||
|
|
theme,
|
||
|
|
verbose,
|
||
|
|
commands
|
||
|
|
}) : null;
|
||
|
|
$[24] = commands;
|
||
|
|
$[25] = input_0.data;
|
||
|
|
$[26] = input_0.success;
|
||
|
|
$[27] = theme;
|
||
|
|
$[28] = tool_0;
|
||
|
|
$[29] = verbose;
|
||
|
|
$[30] = t4;
|
||
|
|
} else {
|
||
|
|
t4 = $[30];
|
||
|
|
}
|
||
|
|
const renderedToolUseMessage = t4;
|
||
|
|
if (renderedToolUseMessage === null) {
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
const t5 = addMargin ? 1 : 0;
|
||
|
|
const t6 = stringWidth(userFacingToolName) + (shouldShowDot ? 2 : 0);
|
||
|
|
let t7;
|
||
|
|
if ($[31] !== isQueued || $[32] !== isResolved || $[33] !== lookups.erroredToolUseIDs || $[34] !== param.id || $[35] !== shouldAnimate || $[36] !== shouldShowDot) {
|
||
|
|
t7 = shouldShowDot && (isQueued ? <Box minWidth={2}><Text dimColor={isQueued}>{BLACK_CIRCLE}</Text></Box> : <ToolUseLoader shouldAnimate={shouldAnimate} isUnresolved={!isResolved} isError={lookups.erroredToolUseIDs.has(param.id)} />);
|
||
|
|
$[31] = isQueued;
|
||
|
|
$[32] = isResolved;
|
||
|
|
$[33] = lookups.erroredToolUseIDs;
|
||
|
|
$[34] = param.id;
|
||
|
|
$[35] = shouldAnimate;
|
||
|
|
$[36] = shouldShowDot;
|
||
|
|
$[37] = t7;
|
||
|
|
} else {
|
||
|
|
t7 = $[37];
|
||
|
|
}
|
||
|
|
const t8 = userFacingToolNameBackgroundColor ? "inverseText" : undefined;
|
||
|
|
let t9;
|
||
|
|
if ($[38] !== t8 || $[39] !== userFacingToolName || $[40] !== userFacingToolNameBackgroundColor) {
|
||
|
|
t9 = <Box flexShrink={0}><Text bold={true} wrap="truncate-end" backgroundColor={userFacingToolNameBackgroundColor} color={t8}>{userFacingToolName}</Text></Box>;
|
||
|
|
$[38] = t8;
|
||
|
|
$[39] = userFacingToolName;
|
||
|
|
$[40] = userFacingToolNameBackgroundColor;
|
||
|
|
$[41] = t9;
|
||
|
|
} else {
|
||
|
|
t9 = $[41];
|
||
|
|
}
|
||
|
|
let t10;
|
||
|
|
if ($[42] !== renderedToolUseMessage) {
|
||
|
|
t10 = renderedToolUseMessage !== "" && <Box flexWrap="nowrap"><Text>({renderedToolUseMessage})</Text></Box>;
|
||
|
|
$[42] = renderedToolUseMessage;
|
||
|
|
$[43] = t10;
|
||
|
|
} else {
|
||
|
|
t10 = $[43];
|
||
|
|
}
|
||
|
|
let t11;
|
||
|
|
if ($[44] !== input_0.data || $[45] !== input_0.success || $[46] !== tool_0) {
|
||
|
|
t11 = input_0.success && tool_0.renderToolUseTag && tool_0.renderToolUseTag(input_0.data);
|
||
|
|
$[44] = input_0.data;
|
||
|
|
$[45] = input_0.success;
|
||
|
|
$[46] = tool_0;
|
||
|
|
$[47] = t11;
|
||
|
|
} else {
|
||
|
|
t11 = $[47];
|
||
|
|
}
|
||
|
|
let t12;
|
||
|
|
if ($[48] !== t10 || $[49] !== t11 || $[50] !== t6 || $[51] !== t7 || $[52] !== t9) {
|
||
|
|
t12 = <Box flexDirection="row" flexWrap="nowrap" minWidth={t6}>{t7}{t9}{t10}{t11}</Box>;
|
||
|
|
$[48] = t10;
|
||
|
|
$[49] = t11;
|
||
|
|
$[50] = t6;
|
||
|
|
$[51] = t7;
|
||
|
|
$[52] = t9;
|
||
|
|
$[53] = t12;
|
||
|
|
} else {
|
||
|
|
t12 = $[53];
|
||
|
|
}
|
||
|
|
let t13;
|
||
|
|
if ($[54] !== inProgressToolCallCount || $[55] !== isAutoClassifier || $[56] !== isClassifierChecking || $[57] !== isQueued || $[58] !== isResolved || $[59] !== isTranscriptMode || $[60] !== isWaitingForPermission || $[61] !== lookups || $[62] !== param.id || $[63] !== progressMessagesForMessage || $[64] !== terminalSize || $[65] !== tool_0 || $[66] !== tools || $[67] !== verbose) {
|
||
|
|
t13 = !isResolved && !isQueued && (isClassifierChecking ? <MessageResponse height={1}><Text dimColor={true}>{isAutoClassifier ? "Auto classifier checking\u2026" : "Bash classifier checking\u2026"}</Text></MessageResponse> : isWaitingForPermission ? <MessageResponse height={1}><Text dimColor={true}>Waiting for permission…</Text></MessageResponse> : renderToolUseProgressMessage(tool_0, tools, lookups, param.id, progressMessagesForMessage, {
|
||
|
|
verbose,
|
||
|
|
inProgressToolCallCount,
|
||
|
|
isTranscriptMode
|
||
|
|
}, terminalSize));
|
||
|
|
$[54] = inProgressToolCallCount;
|
||
|
|
$[55] = isAutoClassifier;
|
||
|
|
$[56] = isClassifierChecking;
|
||
|
|
$[57] = isQueued;
|
||
|
|
$[58] = isResolved;
|
||
|
|
$[59] = isTranscriptMode;
|
||
|
|
$[60] = isWaitingForPermission;
|
||
|
|
$[61] = lookups;
|
||
|
|
$[62] = param.id;
|
||
|
|
$[63] = progressMessagesForMessage;
|
||
|
|
$[64] = terminalSize;
|
||
|
|
$[65] = tool_0;
|
||
|
|
$[66] = tools;
|
||
|
|
$[67] = verbose;
|
||
|
|
$[68] = t13;
|
||
|
|
} else {
|
||
|
|
t13 = $[68];
|
||
|
|
}
|
||
|
|
let t14;
|
||
|
|
if ($[69] !== isQueued || $[70] !== isResolved || $[71] !== tool_0) {
|
||
|
|
t14 = !isResolved && isQueued && renderToolUseQueuedMessage(tool_0);
|
||
|
|
$[69] = isQueued;
|
||
|
|
$[70] = isResolved;
|
||
|
|
$[71] = tool_0;
|
||
|
|
$[72] = t14;
|
||
|
|
} else {
|
||
|
|
t14 = $[72];
|
||
|
|
}
|
||
|
|
let t15;
|
||
|
|
if ($[73] !== t12 || $[74] !== t13 || $[75] !== t14) {
|
||
|
|
t15 = <Box flexDirection="column">{t12}{t13}{t14}</Box>;
|
||
|
|
$[73] = t12;
|
||
|
|
$[74] = t13;
|
||
|
|
$[75] = t14;
|
||
|
|
$[76] = t15;
|
||
|
|
} else {
|
||
|
|
t15 = $[76];
|
||
|
|
}
|
||
|
|
let t16;
|
||
|
|
if ($[77] !== bg || $[78] !== t15 || $[79] !== t5) {
|
||
|
|
t16 = <Box flexDirection="row" justifyContent="space-between" marginTop={t5} width="100%" backgroundColor={bg}>{t15}</Box>;
|
||
|
|
$[77] = bg;
|
||
|
|
$[78] = t15;
|
||
|
|
$[79] = t5;
|
||
|
|
$[80] = t16;
|
||
|
|
} else {
|
||
|
|
t16 = $[80];
|
||
|
|
}
|
||
|
|
return t16;
|
||
|
|
}
|
||
|
|
function _temp3(state_1) {
|
||
|
|
return !!state_1.toolPermissionContext.strippedDangerousRules;
|
||
|
|
}
|
||
|
|
function _temp2(state_0) {
|
||
|
|
return state_0.toolPermissionContext.mode;
|
||
|
|
}
|
||
|
|
function _temp(state) {
|
||
|
|
return state.pendingWorkerRequest;
|
||
|
|
}
|
||
|
|
function renderToolUseMessage(tool: Tool, input: unknown, {
|
||
|
|
theme,
|
||
|
|
verbose,
|
||
|
|
commands
|
||
|
|
}: {
|
||
|
|
theme: ThemeName;
|
||
|
|
verbose: boolean;
|
||
|
|
commands: Command[];
|
||
|
|
}): React.ReactNode {
|
||
|
|
try {
|
||
|
|
const parsed = tool.inputSchema.safeParse(input);
|
||
|
|
if (!parsed.success) {
|
||
|
|
return '';
|
||
|
|
}
|
||
|
|
return tool.renderToolUseMessage(parsed.data, {
|
||
|
|
theme,
|
||
|
|
verbose,
|
||
|
|
commands
|
||
|
|
});
|
||
|
|
} catch (error) {
|
||
|
|
logError(new Error(`Error rendering tool use message for ${tool.name}: ${error}`));
|
||
|
|
return '';
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function renderToolUseProgressMessage(tool: Tool, tools: Tools, lookups: ReturnType<typeof buildMessageLookups>, toolUseID: string, progressMessagesForMessage: ProgressMessage[], {
|
||
|
|
verbose,
|
||
|
|
inProgressToolCallCount,
|
||
|
|
isTranscriptMode
|
||
|
|
}: {
|
||
|
|
verbose: boolean;
|
||
|
|
inProgressToolCallCount?: number;
|
||
|
|
isTranscriptMode?: boolean;
|
||
|
|
}, terminalSize: {
|
||
|
|
columns: number;
|
||
|
|
rows: number;
|
||
|
|
}): React.ReactNode {
|
||
|
|
const toolProgressMessages = progressMessagesForMessage.filter((msg): msg is ProgressMessage<ToolProgressData> => msg.data.type !== 'hook_progress');
|
||
|
|
try {
|
||
|
|
const toolMessages = tool.renderToolUseProgressMessage?.(toolProgressMessages, {
|
||
|
|
tools,
|
||
|
|
verbose,
|
||
|
|
terminalSize,
|
||
|
|
inProgressToolCallCount: inProgressToolCallCount ?? 1,
|
||
|
|
isTranscriptMode
|
||
|
|
}) ?? null;
|
||
|
|
return <>
|
||
|
|
<SentryErrorBoundary>
|
||
|
|
<HookProgressMessage hookEvent="PreToolUse" lookups={lookups} toolUseID={toolUseID} verbose={verbose} isTranscriptMode={isTranscriptMode} />
|
||
|
|
</SentryErrorBoundary>
|
||
|
|
{toolMessages}
|
||
|
|
</>;
|
||
|
|
} catch (error) {
|
||
|
|
logError(new Error(`Error rendering tool use progress message for ${tool.name}: ${error}`));
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
function renderToolUseQueuedMessage(tool: Tool): React.ReactNode {
|
||
|
|
try {
|
||
|
|
return tool.renderToolUseQueuedMessage?.();
|
||
|
|
} catch (error) {
|
||
|
|
logError(new Error(`Error rendering tool use queued message for ${tool.name}: ${error}`));
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJUb29sVXNlQmxvY2tQYXJhbSIsIlJlYWN0IiwidXNlTWVtbyIsInVzZVRlcm1pbmFsU2l6ZSIsIlRoZW1lTmFtZSIsIkNvbW1hbmQiLCJCTEFDS19DSVJDTEUiLCJzdHJpbmdXaWR0aCIsIkJveCIsIlRleHQiLCJ1c2VUaGVtZSIsInVzZUFwcFN0YXRlTWF5YmVPdXRzaWRlT2ZQcm92aWRlciIsImZpbmRUb29sQnlOYW1lIiwiVG9vbCIsIlRvb2xQcm9ncmVzc0RhdGEiLCJUb29scyIsIlByb2dyZXNzTWVzc2FnZSIsInVzZUlzQ2xhc3NpZmllckNoZWNraW5nIiwibG9nRXJyb3IiLCJidWlsZE1lc3NhZ2VMb29rdXBzIiwiTWVzc2FnZVJlc3BvbnNlIiwidXNlU2VsZWN0ZWRNZXNzYWdlQmciLCJTZW50cnlFcnJvckJvdW5kYXJ5IiwiVG9vbFVzZUxvYWRlciIsIkhvb2tQcm9ncmVzc01lc3NhZ2UiLCJQcm9wcyIsInBhcmFtIiwiYWRkTWFyZ2luIiwidG9vbHMiLCJjb21tYW5kcyIsInZlcmJvc2UiLCJpblByb2dyZXNzVG9vbFVzZUlEcyIsIlNldCIsInByb2dyZXNzTWVzc2FnZXNGb3JNZXNzYWdlIiwic2hvdWxkQW5pbWF0ZSIsInNob3VsZFNob3dEb3QiLCJpblByb2dyZXNzVG9vbENhbGxDb3VudCIsImxvb2t1cHMiLCJSZXR1cm5UeXBlIiwiaXNUcmFuc2NyaXB0TW9kZSIsIkFzc2lzdGFudFRvb2xVc2VNZXNzYWdlIiwidDAiLCIkIiwiX2MiLCJ0ZXJtaW5hbFNpemUiLCJ0aGVtZSIsImJnIiwicGVuZGluZ1dvcmtlclJlcXVlc3QiLCJfdGVtcCIsImlzQ2xhc3NpZmllckNoZWNraW5nUmF3IiwiaWQiLCJwZXJtaXNzaW9uTW9kZSIsIl90ZW1wMiIsImhhc1N0cmlwcGVkUnVsZXMiLCJfdGVtcDMiLCJpc0F1dG9DbGFzc2lmaWVyIiwiaXNDbGFzc2lmaWVyQ2hlY2tpbmciLCJ0MSIsImlucHV0IiwibmFtZSIsImJiMCIsInRvb2wiLCJpbnB1dFNjaGVtYSIsInNhZmVQYXJzZSIsImRhdGEiLCJzdWNjZXNzIiwidW5kZWZpbmVkIiwidXNlckZhY2luZ1Rvb2xOYW1lIiwidXNlckZhY2luZ05hbWUiLCJ1c2VyRmFjaW5nVG9vbE5hbWVCYWNrZ3JvdW5kQ29sb3IiLCJ1c2VyRmFjaW5nTmFtZUJhY2tncm91bmRDb2xvciIsImlzVHJhbnNwYXJlbnRXcmFwcGVyIiwicGFyc2VkIiwiRXJyb3IiLCJ0b29sXzAiLCJpbnB1dF8wIiwidDIiLCJyZXNvbHZlZFRvb2xVc2VJRHMiLCJoYXMiLCJpc1Jlc29sdmVkIiwidDMiLCJpc1F1ZXVlZCIsImlzV2FpdGluZ0ZvclBlcm1pc3Npb24iLCJ0b29sVXNlSWQiLCJ0NCIsInJlbmRlclRvb2xVc2VQcm9ncmVzc01lc3NhZ2UiLCJ0NSIsInJlbmRlclRvb2xVc2VNZXNzYWdlIiwicmVuZGVyZWRUb29sVXNlTWVzc2FnZSIsInQ2IiwidDciLCJlcnJvcmVkVG9vbFVzZUlEcyIsInQ4IiwidDkiLCJ0MTAiLCJ0MTEiLCJyZW5kZXJUb29sVXNlVGFnIiwidDEyIiwidDEzIiwidDE0IiwicmVuZGVyVG9vbFVzZVF1ZXVlZE1lc3NhZ2UiLCJ0MTUiLCJ0MTYiLCJzdGF0ZV8xIiwic3RhdGUiLCJ0b29sUGVybWlzc2lvbkNvbnRleHQiLCJzdHJpcHBlZERhbmdlcm91c1J1bGVzIiwic3RhdGVfMCIsIm1vZGUiLCJSZWFjdE5vZGUiLCJlcnJvciIsInRvb2xVc2VJRCIsImNvbHVtbnMiLCJyb3dzIiwidG9vbFByb2dyZXNzTWVzc2FnZXMiLCJmaWx0ZXIiLCJtc2ciLCJ0eXBlIiwidG9vbE1lc3NhZ2VzIl0sInNvdXJjZXMiOlsiQXNzaXN0YW50VG9vbFVzZU1lc3NhZ2UudHN4Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB0eXBlIHsgVG9vbFVzZUJsb2NrUGFyYW0gfSBmcm9tICdAYW50aHJvcGljLWFpL3Nkay9yZXNvdXJjZXMvaW5kZXgubWpzJ1xuaW1wb3J0IFJlYWN0LCB7IHVzZU1lbW8gfSBmcm9tICdyZWFjdCdcbmltcG9ydCB7IHVzZVRlcm1pbmFsU2l6ZSB9IGZyb20gJ3NyYy9ob29rcy91c2VUZXJtaW5hbFNpemUuanMnXG5pbXBvcnQgdHlwZSB7IFRoZW1lTmFtZSB9IGZyb20gJ3NyYy91dGlscy90aGVtZS5qcydcbmltcG9ydCB0eXBlIHsgQ29tbWFuZCB9IGZyb20gJy4uLy4uL2NvbW1hbmRzLmpzJ1xuaW1wb3J0IHsgQkxBQ0tfQ0lSQ0xFIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzL2ZpZ3VyZXMuanMnXG5pbXBvcnQgeyBzdHJpbmdXaWR0aCB9IGZyb20gJy4uLy4uL2luay9zdHJpbmdXaWR0aC5qcydcbmltcG9ydCB7IEJveCwgVGV4dCwgdXNlVGhlbWUgfSBmcm9tICcuLi8uLi9pbmsuanMnXG5pbXBvcnQgeyB1c2VBcHBTdGF0ZU1heWJlT3V0c2lkZU9mUHJvdmlkZXIgfSBmcm9tICcuLi8uLi9zdGF0ZS9BcHBTdGF0ZS5qcydcbmltcG9ydCB7XG4gIGZpbmRUb29sQnlOYW1lLFxuICB0eXBlIFRvb2wsXG4gIHR5cGUgVG9vbFByb2dyZXNzRGF0YSxcbiAgdHlwZSBUb29scyxcbn0gZnJvbSAnLi4vLi4vVG9vbC5qcydcbmltcG9ydCB0eXBlIHsgUHJvZ3Jlc3NNZXNzYWdlIH0gZnJvbSAnLi4vLi4vdHlwZXMvbWVzc2FnZS5qcydcbmltcG9ydCB7IHVzZUlzQ2xhc3NpZmllckNoZWNraW5nIH0gZnJvbSAnLi4vLi4vdXRpbHMvY2xhc3NpZmllckFwcHJvdmFsc0hvb2suanMnXG5pbXBvcnQgeyBsb2dFcnJvciB9IGZyb20gJy4uLy4uL3V0aWxzL2xvZy5qcydcbmltcG9ydCB0eXBlIHsgYnVpbGRNZXNzYWdlTG9va3VwcyB9IGZyb20gJy4uLy4uL3V0aWxzL21lc3NhZ2VzLmpzJ1xuaW1wb3J0IHsgTWVzc2FnZVJlc3BvbnNlIH0gZnJvbSAnLi4vTWVzc2FnZVJlc3BvbnNlLmpzJ1xuaW1wb3J0IHsgdXNlU2VsZWN0ZWRNZXNzYWdlQmcgfSBmcm9tICcuLi9tZXNzYWdlQWN0aW9ucy5qcydcbmltcG9ydCB7IFNlbnRyeUVycm9yQm91bmRhcnkgfSBmcm9tICcuLi9TZW50cnlFcnJvckJvdW5kYXJ5LmpzJ1xuaW1wb3J0IHsgVG9vbFVzZUxvYWRlciB9IGZyb20gJy4uL1Rvb2xVc2VMb2FkZXIuanMnXG5pbXBvcnQgeyBIb29rUHJvZ3Jlc3NNZXNzYWdlIH0gZnJvbSAnLi9Ib29rUHJvZ3Jlc3NNZXNzYWdlLmpzJ1xuXG50eXBlIFByb3BzID0ge1xuICBwYXJhbTogVG9vbFVzZUJsb2NrUGFyYW1cbiAgYWRkTWFyZ2luOiBib29sZWFuXG4gIHRvb2xzOiBUb29sc1xuICBjb21tYW5kczogQ29tbWFuZFtdXG4gIHZlcmJvc2U6IGJvb2xlYW5cbiAgaW5Qcm9ncmVzc1R
|