source dump of claude code
at main 162 lines 22 kB view raw
1import * as React from 'react'; 2import { useEffect, useRef, useState } from 'react'; 3import { type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, logEvent } from 'src/services/analytics/index.js'; 4import { ConfigurableShortcutHint } from '../../components/ConfigurableShortcutHint.js'; 5import { Byline } from '../../components/design-system/Byline.js'; 6import { KeyboardShortcutHint } from '../../components/design-system/KeyboardShortcutHint.js'; 7import { Spinner } from '../../components/Spinner.js'; 8import TextInput from '../../components/TextInput.js'; 9import { Box, Text } from '../../ink.js'; 10import { toError } from '../../utils/errors.js'; 11import { logError } from '../../utils/log.js'; 12import { clearAllCaches } from '../../utils/plugins/cacheUtils.js'; 13import { addMarketplaceSource, saveMarketplaceToSettings } from '../../utils/plugins/marketplaceManager.js'; 14import { parseMarketplaceInput } from '../../utils/plugins/parseMarketplaceInput.js'; 15import type { ViewState } from './types.js'; 16type Props = { 17 inputValue: string; 18 setInputValue: (value: string) => void; 19 cursorOffset: number; 20 setCursorOffset: (offset: number) => void; 21 error: string | null; 22 setError: (error: string | null) => void; 23 result: string | null; 24 setResult: (result: string | null) => void; 25 setViewState: (state: ViewState) => void; 26 onAddComplete?: () => void | Promise<void>; 27 cliMode?: boolean; 28}; 29export function AddMarketplace({ 30 inputValue, 31 setInputValue, 32 cursorOffset, 33 setCursorOffset, 34 error, 35 setError, 36 result, 37 setResult, 38 setViewState, 39 onAddComplete, 40 cliMode = false 41}: Props): React.ReactNode { 42 const hasAttemptedAutoAdd = useRef(false); 43 const [isLoading, setLoading] = useState(false); 44 const [progressMessage, setProgressMessage] = useState<string>(''); 45 const handleAdd = async () => { 46 const input = inputValue.trim(); 47 if (!input) { 48 setError('Please enter a marketplace source'); 49 return; 50 } 51 const parsed = await parseMarketplaceInput(input); 52 if (!parsed) { 53 setError('Invalid marketplace source format. Try: owner/repo, https://..., or ./path'); 54 return; 55 } 56 57 // Check if parseMarketplaceInput returned an error 58 if ('error' in parsed) { 59 setError(parsed.error); 60 return; 61 } 62 setError(null); 63 try { 64 setLoading(true); 65 setProgressMessage(''); 66 const { 67 name, 68 resolvedSource 69 } = await addMarketplaceSource(parsed, message => { 70 setProgressMessage(message); 71 }); 72 saveMarketplaceToSettings(name, { 73 source: resolvedSource 74 }); 75 clearAllCaches(); 76 let sourceType = parsed.source; 77 if (parsed.source === 'github') { 78 sourceType = parsed.repo as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS; 79 } 80 logEvent('tengu_marketplace_added', { 81 source_type: sourceType as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS 82 }); 83 if (onAddComplete) { 84 await onAddComplete(); 85 } 86 setProgressMessage(''); 87 setLoading(false); 88 if (cliMode) { 89 // In CLI mode, set result to trigger completion 90 setResult(`Successfully added marketplace: ${name}`); 91 } else { 92 // In interactive mode, switch to browse view 93 setViewState({ 94 type: 'browse-marketplace', 95 targetMarketplace: name 96 }); 97 } 98 } catch (err) { 99 const error = toError(err); 100 logError(error); 101 setError(error.message); 102 setProgressMessage(''); 103 setLoading(false); 104 if (cliMode) { 105 // In CLI mode, set result with error to trigger completion 106 setResult(`Error: ${error.message}`); 107 } else { 108 setResult(null); 109 } 110 } 111 }; 112 113 // Auto-add if inputValue is provided 114 useEffect(() => { 115 if (inputValue && !hasAttemptedAutoAdd.current && !error && !result) { 116 hasAttemptedAutoAdd.current = true; 117 void handleAdd(); 118 } 119 // eslint-disable-next-line react-hooks/exhaustive-deps 120 // biome-ignore lint/correctness/useExhaustiveDependencies: intentional 121 }, []); // Only run once on mount 122 123 return <Box flexDirection="column"> 124 <Box flexDirection="column" paddingX={1} borderStyle="round"> 125 <Box marginBottom={1}> 126 <Text bold>Add Marketplace</Text> 127 </Box> 128 <Box flexDirection="column"> 129 <Text>Enter marketplace source:</Text> 130 <Text dimColor>Examples:</Text> 131 <Text dimColor> · owner/repo (GitHub)</Text> 132 <Text dimColor> · git@github.com:owner/repo.git (SSH)</Text> 133 <Text dimColor> · https://example.com/marketplace.json</Text> 134 <Text dimColor> · ./path/to/marketplace</Text> 135 <Box marginTop={1}> 136 <TextInput value={inputValue} onChange={setInputValue} onSubmit={handleAdd} columns={80} cursorOffset={cursorOffset} onChangeCursorOffset={setCursorOffset} focus showCursor /> 137 </Box> 138 </Box> 139 {isLoading && <Box marginTop={1}> 140 <Spinner /> 141 <Text> 142 {progressMessage || 'Adding marketplace to configuration…'} 143 </Text> 144 </Box>} 145 {error && <Box marginTop={1}> 146 <Text color="error">{error}</Text> 147 </Box>} 148 {result && <Box marginTop={1}> 149 <Text>{result}</Text> 150 </Box>} 151 </Box> 152 <Box marginLeft={3}> 153 <Text dimColor italic> 154 <Byline> 155 <KeyboardShortcutHint shortcut="Enter" action="add" /> 156 <ConfigurableShortcutHint action="confirm:no" context="Settings" fallback="Esc" description="cancel" /> 157 </Byline> 158 </Text> 159 </Box> 160 </Box>; 161} 162//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsInVzZUVmZmVjdCIsInVzZVJlZiIsInVzZVN0YXRlIiwiQW5hbHl0aWNzTWV0YWRhdGFfSV9WRVJJRklFRF9USElTX0lTX05PVF9DT0RFX09SX0ZJTEVQQVRIUyIsImxvZ0V2ZW50IiwiQ29uZmlndXJhYmxlU2hvcnRjdXRIaW50IiwiQnlsaW5lIiwiS2V5Ym9hcmRTaG9ydGN1dEhpbnQiLCJTcGlubmVyIiwiVGV4dElucHV0IiwiQm94IiwiVGV4dCIsInRvRXJyb3IiLCJsb2dFcnJvciIsImNsZWFyQWxsQ2FjaGVzIiwiYWRkTWFya2V0cGxhY2VTb3VyY2UiLCJzYXZlTWFya2V0cGxhY2VUb1NldHRpbmdzIiwicGFyc2VNYXJrZXRwbGFjZUlucHV0IiwiVmlld1N0YXRlIiwiUHJvcHMiLCJpbnB1dFZhbHVlIiwic2V0SW5wdXRWYWx1ZSIsInZhbHVlIiwiY3Vyc29yT2Zmc2V0Iiwic2V0Q3Vyc29yT2Zmc2V0Iiwib2Zmc2V0IiwiZXJyb3IiLCJzZXRFcnJvciIsInJlc3VsdCIsInNldFJlc3VsdCIsInNldFZpZXdTdGF0ZSIsInN0YXRlIiwib25BZGRDb21wbGV0ZSIsIlByb21pc2UiLCJjbGlNb2RlIiwiQWRkTWFya2V0cGxhY2UiLCJSZWFjdE5vZGUiLCJoYXNBdHRlbXB0ZWRBdXRvQWRkIiwiaXNMb2FkaW5nIiwic2V0TG9hZGluZyIsInByb2dyZXNzTWVzc2FnZSIsInNldFByb2dyZXNzTWVzc2FnZSIsImhhbmRsZUFkZCIsImlucHV0IiwidHJpbSIsInBhcnNlZCIsIm5hbWUiLCJyZXNvbHZlZFNvdXJjZSIsIm1lc3NhZ2UiLCJzb3VyY2UiLCJzb3VyY2VUeXBlIiwicmVwbyIsInNvdXJjZV90eXBlIiwidHlwZSIsInRhcmdldE1hcmtldHBsYWNlIiwiZXJyIiwiY3VycmVudCJdLCJzb3VyY2VzIjpbIkFkZE1hcmtldHBsYWNlLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCdcbmltcG9ydCB7IHVzZUVmZmVjdCwgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHtcbiAgdHlwZSBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICBsb2dFdmVudCxcbn0gZnJvbSAnc3JjL3NlcnZpY2VzL2FuYWx5dGljcy9pbmRleC5qcydcbmltcG9ydCB7IENvbmZpZ3VyYWJsZVNob3J0Y3V0SGludCB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvQ29uZmlndXJhYmxlU2hvcnRjdXRIaW50LmpzJ1xuaW1wb3J0IHsgQnlsaW5lIH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9kZXNpZ24tc3lzdGVtL0J5bGluZS5qcydcbmltcG9ydCB7IEtleWJvYXJkU2hvcnRjdXRIaW50IH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9kZXNpZ24tc3lzdGVtL0tleWJvYXJkU2hvcnRjdXRIaW50LmpzJ1xuaW1wb3J0IHsgU3Bpbm5lciB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvU3Bpbm5lci5qcydcbmltcG9ydCBUZXh0SW5wdXQgZnJvbSAnLi4vLi4vY29tcG9uZW50cy9UZXh0SW5wdXQuanMnXG5pbXBvcnQgeyBCb3gsIFRleHQgfSBmcm9tICcuLi8uLi9pbmsuanMnXG5pbXBvcnQgeyB0b0Vycm9yIH0gZnJvbSAnLi4vLi4vdXRpbHMvZXJyb3JzLmpzJ1xuaW1wb3J0IHsgbG9nRXJyb3IgfSBmcm9tICcuLi8uLi91dGlscy9sb2cuanMnXG5pbXBvcnQgeyBjbGVhckFsbENhY2hlcyB9IGZyb20gJy4uLy4uL3V0aWxzL3BsdWdpbnMvY2FjaGVVdGlscy5qcydcbmltcG9ydCB7XG4gIGFkZE1hcmtldHBsYWNlU291cmNlLFxuICBzYXZlTWFya2V0cGxhY2VUb1NldHRpbmdzLFxufSBmcm9tICcuLi8uLi91dGlscy9wbHVnaW5zL21hcmtldHBsYWNlTWFuYWdlci5qcydcbmltcG9ydCB7IHBhcnNlTWFya2V0cGxhY2VJbnB1dCB9IGZyb20gJy4uLy4uL3V0aWxzL3BsdWdpbnMvcGFyc2VNYXJrZXRwbGFjZUlucHV0LmpzJ1xuaW1wb3J0IHR5cGUgeyBWaWV3U3RhdGUgfSBmcm9tICcuL3R5cGVzLmpzJ1xuXG50eXBlIFByb3BzID0ge1xuICBpbnB1dFZhbHVlOiBzdHJpbmdcbiAgc2V0SW5wdXRWYWx1ZTogKHZhbHVlOiBzdHJpbmcpID0+IHZvaWRcbiAgY3Vyc29yT2Zmc2V0OiBudW1iZXJcbiAgc2V0Q3Vyc29yT2Zmc2V0OiAob2Zmc2V0OiBudW1iZXIpID0+IHZvaWRcbiAgZXJyb3I6IHN0cmluZyB8IG51bGxcbiAgc2V0RXJyb3I6IChlcnJvcjogc3RyaW5nIHwgbnVsbCkgPT4gdm9pZFxuICByZXN1bHQ6IHN0cmluZyB8IG51bGxcbiAgc2V0UmVzdWx0OiAocmVzdWx0OiBzdHJpbmcgfCBudWxsKSA9PiB2b2lkXG4gIHNldFZpZXdTdGF0ZTogKHN0YXRlOiBWaWV3U3RhdGUpID0+IHZvaWRcbiAgb25BZGRDb21wbGV0ZT86ICgpID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+XG4gIGNsaU1vZGU/OiBib29sZWFuXG59XG5cbmV4cG9ydCBmdW5jdGlvbiBBZGRNYXJrZXRwbGFjZSh7XG4gIGlucHV0VmFsdWUsXG4gIHNldElucHV0VmFsdWUsXG4gIGN1cnNvck9mZnNldCxcbiAgc2V0Q3Vyc29yT2Zmc2V0LFxuICBlcnJvcixcbiAgc2V0RXJyb3IsXG4gIHJlc3VsdCxcbiAgc2V0UmVzdWx0LFxuICBzZXRWaWV3U3RhdGUsXG4gIG9uQWRkQ29tcGxldGUsXG4gIGNsaU1vZGUgPSBmYWxzZSxcbn06IFByb3BzKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgY29uc3QgaGFzQXR0ZW1wdGVkQXV0b0FkZCA9IHVzZVJlZihmYWxzZSlcbiAgY29uc3QgW2lzTG9hZGluZywgc2V0TG9hZGluZ10gPSB1c2VTdGF0ZShmYWxzZSlcbiAgY29uc3QgW3Byb2dyZXNzTWVzc2FnZSwgc2V0UHJvZ3Jlc3NNZXNzYWdlXSA9IHVzZVN0YXRlPHN0cmluZz4oJycpXG5cbiAgY29uc3QgaGFuZGxlQWRkID0gYXN5bmMgKCkgPT4ge1xuICAgIGNvbnN0IGlucHV0ID0gaW5wdXRWYWx1ZS50cmltKClcbiAgICBpZiAoIWlucHV0KSB7XG4gICAgICBzZXRFcnJvcignUGxlYXNlIGVudGVyIGEgbWFya2V0cGxhY2Ugc291cmNlJylcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IHBhcnNlZCA9IGF3YWl0IHBhcnNlTWFya2V0cGxhY2VJbnB1dChpbnB1dClcbiAgICBpZiAoIXBhcnNlZCkge1xuICAgICAgc2V0RXJyb3IoXG4gICAgICAgICdJbnZhbGlkIG1hcmtldHBsYWNlIHNvdXJjZSBmb3JtYXQuIFRyeTogb3duZXIvcmVwbywgaHR0cHM6Ly8uLi4sIG9yIC4vcGF0aCcsXG4gICAgICApXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBwYXJzZU1hcmtldHBsYWNlSW5wdXQgcmV0dXJuZWQgYW4gZXJyb3JcbiAgICBpZiAoJ2Vycm9yJyBpbiBwYXJzZWQpIHtcbiAgICAgIHNldEVycm9yKHBhcnNlZC5lcnJvcilcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHNldEVycm9yKG51bGwpXG5cbiAgICB0cnkge1xuICAgICAgc2V0TG9hZGluZyh0cnVlKVxuICAgICAgc2V0UHJvZ3Jlc3NNZXNzYWdlKCcnKVxuICAgICAgY29uc3QgeyBuYW1lLCByZXNvbHZlZFNvdXJjZSB9ID0gYXdhaXQgYWRkTWFya2V0cGxhY2VTb3VyY2UoXG4gICAgICAgIHBhcnNlZCxcbiAgICAgICAgbWVzc2FnZSA9PiB7XG4gICAgICAgICAgc2V0UHJvZ3Jlc3NNZXNzYWdlKG1lc3NhZ2UpXG4gICAgICAgIH0sXG4gICAgICApXG4gICAgICBzYXZlTWFya2V0cGxhY2VUb1NldHRpbmdzKG5hbWUsIHsgc291cmNlOiByZXNvbHZlZFNvdXJjZSB9KVxuICAgICAgY2xlYXJBbGxDYWNoZXMoKVxuXG4gICAgICBsZXQgc291cmNlVHlwZSA9IHBhcnNlZC5zb3VyY2VcbiAgICAgIGlmIChwYXJzZWQuc291cmNlID09PSAnZ2l0aHViJykge1xuICAgICAgICBzb3VyY2VUeXBlID1cbiAgICAgICAgICBwYXJzZWQucmVwbyBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTXG4gICAgICB9XG5cbiAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9tYXJrZXRwbGFjZV9hZGRlZCcsIHtcbiAgICAgICAgc291cmNlX3R5cGU6XG4gICAgICAgICAgc291cmNlVHlwZSBhcyBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICAgICAgfSlcblxuICAgICAgaWYgKG9uQWRkQ29tcGxldGUpIHtcbiAgICAgICAgYXdhaXQgb25BZGRDb21wbGV0ZSgpXG4gICAgICB9XG5cbiAgICAgIHNldFByb2dyZXNzTWVzc2FnZSgnJylcbiAgICAgIHNldExvYWRpbmcoZmFsc2UpXG5cbiAgICAgIGlmIChjbGlNb2RlKSB7XG4gICAgICAgIC8vIEluIENMSSBtb2RlLCBzZXQgcmVzdWx0IHRvIHRyaWdnZXIgY29tcGxldGlvblxuICAgICAgICBzZXRSZXN1bHQoYFN1Y2Nlc3NmdWxseSBhZGRlZCBtYXJrZXRwbGFjZTogJHtuYW1lfWApXG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJbiBpbnRlcmFjdGl2ZSBtb2RlLCBzd2l0Y2ggdG8gYnJvd3NlIHZpZXdcbiAgICAgICAgc2V0Vmlld1N0YXRlKHsgdHlwZTogJ2Jyb3dzZS1tYXJrZXRwbGFjZScsIHRhcmdldE1hcmtldHBsYWNlOiBuYW1lIH0pXG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zdCBlcnJvciA9IHRvRXJyb3IoZXJyKVxuICAgICAgbG9nRXJyb3IoZXJyb3IpXG4gICAgICBzZXRFcnJvcihlcnJvci5tZXNzYWdlKVxuICAgICAgc2V0UHJvZ3Jlc3NNZXNzYWdlKCcnKVxuICAgICAgc2V0TG9hZGluZyhmYWxzZSlcblxuICAgICAgaWYgKGNsaU1vZGUpIHtcbiAgICAgICAgLy8gSW4gQ0xJIG1vZGUsIHNldCByZXN1bHQgd2l0aCBlcnJvciB0byB0cmlnZ2VyIGNvbXBsZXRpb25cbiAgICAgICAgc2V0UmVzdWx0KGBFcnJvcjogJHtlcnJvci5tZXNzYWdlfWApXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXRSZXN1bHQobnVsbClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBBdXRvLWFkZCBpZiBpbnB1dFZhbHVlIGlzIHByb3ZpZGVkXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgaWYgKGlucHV0VmFsdWUgJiYgIWhhc0F0dGVtcHRlZEF1dG9BZGQuY3VycmVudCAmJiAhZXJyb3IgJiYgIXJlc3VsdCkge1xuICAgICAgaGFzQXR0ZW1wdGVkQXV0b0FkZC5jdXJyZW50ID0gdHJ1ZVxuICAgICAgdm9pZCBoYW5kbGVBZGQoKVxuICAgIH1cbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvZXhoYXVzdGl2ZS1kZXBzXG4gICAgLy8gYmlvbWUtaWdub3JlIGxpbnQvY29ycmVjdG5lc3MvdXNlRXhoYXVzdGl2ZURlcGVuZGVuY2llczogaW50ZW50aW9uYWxcbiAgfSwgW10pIC8vIE9ubHkgcnVuIG9uY2Ugb24gbW91bnRcblxuICByZXR1cm4gKFxuICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiPlxuICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCIgcGFkZGluZ1g9ezF9IGJvcmRlclN0eWxlPVwicm91bmRcIj5cbiAgICAgICAgPEJveCBtYXJnaW5Cb3R0b209ezF9PlxuICAgICAgICAgIDxUZXh0IGJvbGQ+QWRkIE1hcmtldHBsYWNlPC9UZXh0PlxuICAgICAgICA8L0JveD5cbiAgICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCI+XG4gICAgICAgICAgPFRleHQ+RW50ZXIgbWFya2V0cGxhY2Ugc291cmNlOjwvVGV4dD5cbiAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5FeGFtcGxlczo8L1RleHQ+XG4gICAgICAgICAgPFRleHQgZGltQ29sb3I+IMK3IG93bmVyL3JlcG8gKEdpdEh1Yik8L1RleHQ+XG4gICAgICAgICAgPFRleHQgZGltQ29sb3I+IMK3IGdpdEBnaXRodWIuY29tOm93bmVyL3JlcG8uZ2l0IChTU0gpPC9UZXh0PlxuICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPiDCtyBodHRwczovL2V4YW1wbGUuY29tL21hcmtldHBsYWNlLmpzb248L1RleHQ+XG4gICAgICAgICAgPFRleHQgZGltQ29sb3I+IMK3IC4vcGF0aC90by9tYXJrZXRwbGFjZTwvVGV4dD5cbiAgICAgICAgICA8Qm94IG1hcmdpblRvcD17MX0+XG4gICAgICAgICAgICA8VGV4dElucHV0XG4gICAgICAgICAgICAgIHZhbHVlPXtpbnB1dFZhbHVlfVxuICAgICAgICAgICAgICBvbkNoYW5nZT17c2V0SW5wdXRWYWx1ZX1cbiAgICAgICAgICAgICAgb25TdWJtaXQ9e2hhbmRsZUFkZH1cbiAgICAgICAgICAgICAgY29sdW1ucz17ODB9XG4gICAgICAgICAgICAgIGN1cnNvck9mZnNldD17Y3Vyc29yT2Zmc2V0fVxuICAgICAgICAgICAgICBvbkNoYW5nZUN1cnNvck9mZnNldD17c2V0Q3Vyc29yT2Zmc2V0fVxuICAgICAgICAgICAgICBmb2N1c1xuICAgICAgICAgICAgICBzaG93Q3Vyc29yXG4gICAgICAgICAgICAvPlxuICAgICAgICAgIDwvQm94PlxuICAgICAgICA8L0JveD5cbiAgICAgICAge2lzTG9hZGluZyAmJiAoXG4gICAgICAgICAgPEJveCBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgICAgPFNwaW5uZXIgLz5cbiAgICAgICAgICAgIDxUZXh0PlxuICAgICAgICAgICAgICB7cHJvZ3Jlc3NNZXNzYWdlIHx8ICdBZGRpbmcgbWFya2V0cGxhY2UgdG8gY29uZmlndXJhdGlvbuKApid9XG4gICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgPC9Cb3g+XG4gICAgICAgICl9XG4gICAgICAgIHtlcnJvciAmJiAoXG4gICAgICAgICAgPEJveCBtYXJnaW5Ub3A9ezF9PlxuICAgICAgICAgICAgPFRleHQgY29sb3I9XCJlcnJvclwiPntlcnJvcn08L1RleHQ+XG4gICAgICAgICAgPC9Cb3g+XG4gICAgICAgICl9XG4gICAgICAgIHtyZXN1bHQgJiYgKFxuICAgICAgICAgIDxCb3ggbWFyZ2luVG9wPXsxfT5cbiAgICAgICAgICAgIDxUZXh0PntyZXN1bHR9PC9UZXh0PlxuICAgICAgICAgIDwvQm94PlxuICAgICAgICApfVxuICAgICAgPC9Cb3g+XG4gICAgICA8Qm94IG1hcmdpbkxlZnQ9ezN9PlxuICAgICAgICA8VGV4dCBkaW1Db2xvciBpdGFsaWM+XG4gICAgICAgICAgPEJ5bGluZT5cbiAgICAgICAgICAgIDxLZXlib2FyZFNob3J0Y3V0SGludCBzaG9ydGN1dD1cIkVudGVyXCIgYWN0aW9uPVwiYWRkXCIgLz5cbiAgICAgICAgICAgIDxDb25maWd1cmFibGVTaG9ydGN1dEhpbnRcbiAgICAgICAgICAgICAgYWN0aW9uPVwiY29uZmlybTpub1wiXG4gICAgICAgICAgICAgIGNvbnRleHQ9XCJTZXR0aW5nc1wiXG4gICAgICAgICAgICAgIGZhbGxiYWNrPVwiRXNjXCJcbiAgICAgICAgICAgICAgZGVzY3JpcHRpb249XCJjYW5jZWxcIlxuICAgICAgICAgICAgLz5cbiAgICAgICAgICA8L0J5bGluZT5cbiAgICAgICAgPC9UZXh0PlxuICAgICAgPC9Cb3g+XG4gICAgPC9Cb3g+XG4gIClcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLQSxLQUFLLE1BQU0sT0FBTztBQUM5QixTQUFTQyxTQUFTLEVBQUVDLE1BQU0sRUFBRUMsUUFBUSxRQUFRLE9BQU87QUFDbkQsU0FDRSxLQUFLQywwREFBMEQsRUFDL0RDLFFBQVEsUUFDSCxpQ0FBaUM7QUFDeEMsU0FBU0Msd0JBQXdCLFFBQVEsOENBQThD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