PromptInputQueuedCommands.tsx
components/PromptInput/PromptInputQueuedCommands.tsx
117
Lines
19587
Bytes
1
Exports
13
Imports
10
Keywords
What this is
This page documents one file from the repository and includes its full source so you can read it without leaving the docs site.
Beginner explanation
This file is one piece of the larger system. Its name, directory, imports, and exports show where it fits. Start by reading the exports and related files first.
How it is used
Start from the exports list and related files. Those are the easiest clues for where this file fits into the system.
Expert explanation
Architecturally, this file intersects with commands, ui-flow. It contains 117 lines, 13 detected imports, and 1 detected exports.
Important relationships
- components/PromptInput/HistorySearchInput.tsx
- components/PromptInput/IssueFlagBanner.tsx
- components/PromptInput/Notifications.tsx
- components/PromptInput/PromptInput.tsx
- components/PromptInput/PromptInputFooter.tsx
- components/PromptInput/PromptInputFooterLeftSide.tsx
- components/PromptInput/PromptInputFooterSuggestions.tsx
- components/PromptInput/PromptInputHelpMenu.tsx
Detected exports
PromptInputQueuedCommands
Keywords
messagenotificationsmessagesmax_visible_notificationscommandsqueuedcommandsreactfiltertasknotificationscontent
Detected imports
bun:bundlereactreactsrc/ink.jssrc/state/AppState.js../../constants/xml.js../../context/QueuedMessageContext.js../../hooks/useCommandQueue.js../../types/textInputTypes.js../../utils/messageQueueManager.js../../utils/messages.js../../utils/slowOperations.js../Message.js
Source notes
This page embeds the full file contents. Small or leaf files are still indexed honestly instead of being over-explained.
Full source
import { feature } from 'bun:bundle';
import * as React from 'react';
import { useMemo } from 'react';
import { Box } from 'src/ink.js';
import { useAppState } from 'src/state/AppState.js';
import { STATUS_TAG, SUMMARY_TAG, TASK_NOTIFICATION_TAG } from '../../constants/xml.js';
import { QueuedMessageProvider } from '../../context/QueuedMessageContext.js';
import { useCommandQueue } from '../../hooks/useCommandQueue.js';
import type { QueuedCommand } from '../../types/textInputTypes.js';
import { isQueuedCommandVisible } from '../../utils/messageQueueManager.js';
import { createUserMessage, EMPTY_LOOKUPS, normalizeMessages } from '../../utils/messages.js';
import { jsonParse } from '../../utils/slowOperations.js';
import { Message } from '../Message.js';
const EMPTY_SET = new Set<string>();
/**
* Check if a command value is an idle notification that should be hidden.
* Idle notifications are processed silently without showing to the user.
*/
function isIdleNotification(value: string): boolean {
try {
const parsed = jsonParse(value);
return parsed?.type === 'idle_notification';
} catch {
return false;
}
}
// Maximum number of task notification lines to show
const MAX_VISIBLE_NOTIFICATIONS = 3;
/**
* Create a synthetic overflow notification message for capped task notifications.
*/
function createOverflowNotificationMessage(count: number): string {
return `<${TASK_NOTIFICATION_TAG}>
<${SUMMARY_TAG}>+${count} more tasks completed</${SUMMARY_TAG}>
<${STATUS_TAG}>completed</${STATUS_TAG}>
</${TASK_NOTIFICATION_TAG}>`;
}
/**
* Process queued commands to cap task notifications at MAX_VISIBLE_NOTIFICATIONS lines.
* Other command types are always shown in full.
* Idle notifications are filtered out entirely.
*/
function processQueuedCommands(queuedCommands: QueuedCommand[]): QueuedCommand[] {
// Filter out idle notifications - they are processed silently
const filteredCommands = queuedCommands.filter(cmd => typeof cmd.value !== 'string' || !isIdleNotification(cmd.value));
// Separate task notifications from other commands
const taskNotifications = filteredCommands.filter(cmd => cmd.mode === 'task-notification');
const otherCommands = filteredCommands.filter(cmd => cmd.mode !== 'task-notification');
// If notifications fit within limit, return all commands as-is
if (taskNotifications.length <= MAX_VISIBLE_NOTIFICATIONS) {
return [...otherCommands, ...taskNotifications];
}
// Show first (MAX_VISIBLE_NOTIFICATIONS - 1) notifications, then a summary
const visibleNotifications = taskNotifications.slice(0, MAX_VISIBLE_NOTIFICATIONS - 1);
const overflowCount = taskNotifications.length - (MAX_VISIBLE_NOTIFICATIONS - 1);
// Create synthetic overflow message
const overflowCommand: QueuedCommand = {
value: createOverflowNotificationMessage(overflowCount),
mode: 'task-notification'
};
return [...otherCommands, ...visibleNotifications, overflowCommand];
}
function PromptInputQueuedCommandsImpl(): React.ReactNode {
const queuedCommands = useCommandQueue();
const viewingAgent = useAppState(s => !!s.viewingAgentTaskId);
// Brief layout: dim queue items + skip the paddingX (brief messages
// already indent themselves). Gate mirrors the brief-spinner/message
// check elsewhere — no teammate-view override needed since this
// component early-returns when viewing a teammate.
const useBriefLayout = feature('KAIROS') || feature('KAIROS_BRIEF') ?
// biome-ignore lint/correctness/useHookAtTopLevel: feature() is a compile-time constant
useAppState(s_0 => s_0.isBriefOnly) : false;
// createUserMessage mints a fresh UUID per call; without memoization, streaming
// re-renders defeat Message's areMessagePropsEqual (compares uuid) → flicker.
const messages = useMemo(() => {
if (queuedCommands.length === 0) return null;
// task-notification is shown via useInboxNotification; most isMeta commands
// (scheduled tasks, proactive ticks) are system-generated and hidden.
// Channel messages are the exception — isMeta but shown so the keyboard
// user sees what arrived.
const visibleCommands = queuedCommands.filter(isQueuedCommandVisible);
if (visibleCommands.length === 0) return null;
const processedCommands = processQueuedCommands(visibleCommands);
return normalizeMessages(processedCommands.map(cmd => {
let content = cmd.value;
if (cmd.mode === 'bash' && typeof content === 'string') {
content = `<bash-input>${content}</bash-input>`;
}
// [Image #N] placeholders are inline in the text value (inserted at
// paste time), so the queue preview shows them without stub blocks.
return createUserMessage({
content
});
}));
}, [queuedCommands]);
// Don't show leader's queued commands when viewing any agent's transcript
if (viewingAgent || messages === null) {
return null;
}
return <Box marginTop={1} flexDirection="column">
{messages.map((message, i) => <QueuedMessageProvider key={i} isFirst={i === 0} useBriefLayout={useBriefLayout}>
<Message message={message} lookups={EMPTY_LOOKUPS} addMargin={false} tools={[]} commands={[]} verbose={false} inProgressToolUseIDs={EMPTY_SET} progressMessagesForMessage={[]} shouldAnimate={false} shouldShowDot={false} isTranscriptMode={false} isStatic={true} />
</QueuedMessageProvider>)}
</Box>;
}
export const PromptInputQueuedCommands = React.memo(PromptInputQueuedCommandsImpl);
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmZWF0dXJlIiwiUmVhY3QiLCJ1c2VNZW1vIiwiQm94IiwidXNlQXBwU3RhdGUiLCJTVEFUVVNfVEFHIiwiU1VNTUFSWV9UQUciLCJUQVNLX05PVElGSUNBVElPTl9UQUciLCJRdWV1ZWRNZXNzYWdlUHJvdmlkZXIiLCJ1c2VDb21tYW5kUXVldWUiLCJRdWV1ZWRDb21tYW5kIiwiaXNRdWV1ZWRDb21tYW5kVmlzaWJsZSIsImNyZWF0ZVVzZXJNZXNzYWdlIiwiRU1QVFlfTE9PS1VQUyIsIm5vcm1hbGl6ZU1lc3NhZ2VzIiwianNvblBhcnNlIiwiTWVzc2FnZSIsIkVNUFRZX1NFVCIsIlNldCIsImlzSWRsZU5vdGlmaWNhdGlvbiIsInZhbHVlIiwicGFyc2VkIiwidHlwZSIsIk1BWF9WSVNJQkxFX05PVElGSUNBVElPTlMiLCJjcmVhdGVPdmVyZmxvd05vdGlmaWNhdGlvbk1lc3NhZ2UiLCJjb3VudCIsInByb2Nlc3NRdWV1ZWRDb21tYW5kcyIsInF1ZXVlZENvbW1hbmRzIiwiZmlsdGVyZWRDb21tYW5kcyIsImZpbHRlciIsImNtZCIsInRhc2tOb3RpZmljYXRpb25zIiwibW9kZSIsIm90aGVyQ29tbWFuZHMiLCJsZW5ndGgiLCJ2aXNpYmxlTm90aWZpY2F0aW9ucyIsInNsaWNlIiwib3ZlcmZsb3dDb3VudCIsIm92ZXJmbG93Q29tbWFuZCIsIlByb21wdElucHV0UXVldWVkQ29tbWFuZHNJbXBsIiwiUmVhY3ROb2RlIiwidmlld2luZ0FnZW50IiwicyIsInZpZXdpbmdBZ2VudFRhc2tJZCIsInVzZUJyaWVmTGF5b3V0IiwiaXNCcmllZk9ubHkiLCJtZXNzYWdlcyIsInZpc2libGVDb21tYW5kcyIsInByb2Nlc3NlZENvbW1hbmRzIiwibWFwIiwiY29udGVudCIsIm1lc3NhZ2UiLCJpIiwiUHJvbXB0SW5wdXRRdWV1ZWRDb21tYW5kcyIsIm1lbW8iXSwic291cmNlcyI6WyJQcm9tcHRJbnB1dFF1ZXVlZENvbW1hbmRzLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmZWF0dXJlIH0gZnJvbSAnYnVuOmJ1bmRsZSdcbmltcG9ydCAqIGFzIFJlYWN0IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgdXNlTWVtbyB9IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgQm94IH0gZnJvbSAnc3JjL2luay5qcydcbmltcG9ydCB7IHVzZUFwcFN0YXRlIH0gZnJvbSAnc3JjL3N0YXRlL0FwcFN0YXRlLmpzJ1xuaW1wb3J0IHtcbiAgU1RBVFVTX1RBRyxcbiAgU1VNTUFSWV9UQUcsXG4gIFRBU0tfTk9USUZJQ0FUSU9OX1RBRyxcbn0gZnJvbSAnLi4vLi4vY29uc3RhbnRzL3htbC5qcydcbmltcG9ydCB7IFF1ZXVlZE1lc3NhZ2VQcm92aWRlciB9IGZyb20gJy4uLy4uL2NvbnRleHQvUXVldWVkTWVzc2FnZUNvbnRleHQuanMnXG5pbXBvcnQgeyB1c2VDb21tYW5kUXVldWUgfSBmcm9tICcuLi8uLi9ob29rcy91c2VDb21tYW5kUXVldWUuanMnXG5pbXBvcnQgdHlwZSB7IFF1ZXVlZENvbW1hbmQgfSBmcm9tICcuLi8uLi90eXBlcy90ZXh0SW5wdXRUeXBlcy5qcydcbmltcG9ydCB7IGlzUXVldWVkQ29tbWFuZFZpc2libGUgfSBmcm9tICcuLi8uLi91dGlscy9tZXNzYWdlUXVldWVNYW5hZ2VyLmpzJ1xuaW1wb3J0IHtcbiAgY3JlYXRlVXNlck1lc3NhZ2UsXG4gIEVNUFRZX0xPT0tVUFMsXG4gIG5vcm1hbGl6ZU1lc3NhZ2VzLFxufSBmcm9tICcuLi8uLi91dGlscy9tZXNzYWdlcy5qcydcbmltcG9ydCB7IGpzb25QYXJzZSB9IGZyb20gJy4uLy4uL3V0aWxzL3Nsb3dPcGVyYXRpb25zLmpzJ1xuaW1wb3J0IHsgTWVzc2FnZSB9IGZyb20gJy4uL01lc3NhZ2UuanMnXG5cbmNvbnN0IEVNUFRZX1NFVCA9IG5ldyBTZXQ8c3RyaW5nPigpXG5cbi8qKlxuICogQ2hlY2sgaWYgYSBjb21tYW5kIHZhbHVlIGlzIGFuIGlkbGUgbm90aWZpY2F0aW9uIHRoYXQgc2hvdWxkIGJlIGhpZGRlbi5cbiAqIElkbGUgbm90aWZpY2F0aW9ucyBhcmUgcHJvY2Vzc2VkIHNpbGVudGx5IHdpdGhvdXQgc2hvd2luZyB0byB0aGUgdXNlci5cbiAqL1xuZnVuY3Rpb24gaXNJZGxlTm90aWZpY2F0aW9uKHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgdHJ5IHtcbiAgICBjb25zdCBwYXJzZWQgPSBqc29uUGFyc2UodmFsdWUpXG4gICAgcmV0dXJuIHBhcnNlZD8udHlwZSA9PT0gJ2lkbGVfbm90aWZpY2F0aW9uJ1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gZmFsc2VcbiAgfVxufVxuXG4vLyBNYXhpbXVtIG51bWJlciBvZiB0YXNrIG5vdGlmaWNhdGlvbiBsaW5lcyB0byBzaG93XG5jb25zdCBNQVhfVklTSUJMRV9OT1RJRklDQVRJT05TID0gM1xuXG4vKipcbiAqIENyZWF0ZSBhIHN5bnRoZXRpYyBvdmVyZmxvdyBub3RpZmljYXRpb24gbWVzc2FnZSBmb3IgY2FwcGVkIHRhc2sgbm90aWZpY2F0aW9ucy5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlT3ZlcmZsb3dOb3RpZmljYXRpb25NZXNzYWdlKGNvdW50OiBudW1iZXIpOiBzdHJpbmcge1xuICByZXR1cm4gYDwke1RBU0tfTk9USUZJQ0FUSU9OX1RBR30+XG48JHtTVU1NQVJZX1RBR30+KyR7Y291bnR9IG1vcmUgdGFza3MgY29tcGxldGVkPC8ke1NVTU1BUllfVEFHfT5cbjwke1NUQVRVU19UQUd9PmNvbXBsZXRlZDwvJHtTVEFUVVNfVEFHfT5cbjwvJHtUQVNLX05PVElGSUNBVElPTl9UQUd9PmBcbn1cblxuLyoqXG4gKiBQcm9jZXNzIHF1ZXVlZCBjb21tYW5kcyB0byBjYXAgdGFzayBub3RpZmljYXRpb25zIGF0IE1BWF9WSVNJQkxFX05PVElGSUNBVElPTlMgbGluZXMuXG4gKiBPdGhlciBjb21tYW5kIHR5cGVzIGFyZSBhbHdheXMgc2hvd24gaW4gZnVsbC5cbiAqIElkbGUgbm90aWZpY2F0aW9ucyBhcmUgZmlsdGVyZWQgb3V0IGVudGlyZWx5LlxuICovXG5mdW5jdGlvbiBwcm9jZXNzUXVldWVkQ29tbWFuZHMoXG4gIHF1ZXVlZENvbW1hbmRzOiBRdWV1ZWRDb21tYW5kW10sXG4pOiBRdWV1ZWRDb21tYW5kW10ge1xuICAvLyBGaWx0ZXIgb3V0IGlkbGUgbm90aWZpY2F0aW9ucyAtIHRoZXkgYXJlIHByb2Nlc3NlZCBzaWxlbnRseVxuICBjb25zdCBmaWx0ZXJlZENvbW1hbmRzID0gcXVldWVkQ29tbWFuZHMuZmlsdGVyKFxuICAgIGNtZCA9PiB0eXBlb2YgY21kLnZhbHVlICE9PSAnc3RyaW5nJyB8fCAhaXNJZGxlTm90aWZpY2F0aW9uKGNtZC52YWx1ZSksXG4gIClcblxuICAvLyBTZXBhcmF0ZSB0YXNrIG5vdGlmaWNhdGlvbnMgZnJvbSBvdGhlciBjb21tYW5kc1xuICBjb25zdCB0YXNrTm90aWZpY2F0aW9ucyA9IGZpbHRlcmVkQ29tbWFuZHMuZmlsdGVyKFxuICAgIGNtZCA9PiBjbWQubW9kZSA9PT0gJ3Rhc2stbm90aWZpY2F0aW9uJyxcbiAgKVxuICBjb25zdCBvdGhlckNvbW1hbmRzID0gZmlsdGVyZWRDb21tYW5kcy5maWx0ZXIoXG4gICAgY21kID0+IGNtZC5tb2RlICE9PSAndGFzay1ub3RpZmljYXRpb24nLFxuICApXG5cbiAgLy8gSWYgbm90aWZpY2F0aW9ucyBmaXQgd2l0aGluIGxpbWl0LCByZXR1cm4gYWxsIGNvbW1hbmRzIGFzLWlzXG4gIGlmICh0YXNrTm90aWZpY2F0aW9ucy5sZW5ndGggPD0gTUFYX1ZJU0lCTEVfTk9USUZJQ0FUSU9OUykge1xuICAgIHJldHVybiBbLi4ub3RoZXJDb21tYW5kcywgLi4udGFza05vdGlmaWNhdGlvbnNdXG4gIH1cblxuICAvLyBTaG93IGZpcnN0IChNQVhfVklTSUJMRV9OT1RJRklDQVRJT05TIC0gMSkgbm90aWZpY2F0aW9ucywgdGhlbiBhIHN1bW1hcnlcbiAgY29uc3QgdmlzaWJsZU5vdGlmaWNhdGlvbnMgPSB0YXNrTm90aWZpY2F0aW9ucy5zbGljZShcbiAgICAwLFxuICAgIE1BWF9WSVNJQkxFX05PVElGSUNBVElPTlMgLSAxLFxuICApXG4gIGNvbnN0IG92ZXJmbG93Q291bnQgPVxuICAgIHRhc2tOb3RpZmljYXRpb25zLmxlbmd0aCAtIChNQVhfVklTSUJMRV9OT1RJRklDQVRJT05TIC0gMSlcblxuICAvLyBDcmVhdGUgc3ludGhldGljIG92ZXJmbG93IG1lc3NhZ2VcbiAgY29uc3Qgb3ZlcmZsb3dDb21tYW5kOiBRdWV1ZWRDb21tYW5kID0ge1xuICAgIHZhbHVlOiBjcmVhdGVPdmVyZmxvd05vdGlmaWNhdGlvbk1lc3NhZ2Uob3ZlcmZsb3dDb3VudCksXG4gICAgbW9kZTogJ3Rhc2stbm90aWZpY2F0aW9uJyxcbiAgfVxuXG4gIHJldHVybiBbLi4ub3RoZXJDb21tYW5kcywgLi4udmlzaWJsZU5vdGlmaWNhdGlvbnMsIG92ZXJmbG93Q29tbWFuZF1cbn1cblxuZnVuY3Rpb24gUHJvbXB0SW5wdXRRdWV1ZWRDb21tYW5kc0ltcGwoKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgY29uc3QgcXVldWVkQ29tbWFuZHMgPSB1c2VDb21tYW5kUXVldWUoKVxuICBjb25zdCB2aWV3aW5nQWdlbnQgPSB1c2VBcHBTdGF0ZShzID0+ICEhcy52aWV3aW5nQWdlbnRUYXNrSWQpXG4gIC8vIEJyaWVmIGxheW91dDogZGltIHF1ZXVlIGl0ZW1zICsgc2tpcCB0aGUgcGFkZGluZ1ggKGJyaWVmIG1lc3NhZ2VzXG4gIC8vIGFscmVhZHkgaW5kZW50IHRoZW1zZWx2ZXMpLiBHYXRlIG1pcnJvcnMgdGhlIGJyaWVmLXNwaW5uZXIvbWVzc2FnZVxuICAvLyBjaGVjayBlbHNld2hlcmUg4oCUIG5vIHRlYW1tYXRlLXZpZXcgb3ZlcnJpZGUgbmVlZGVkIHNpbmNlIHRoaXNcbiAgLy8gY29tcG9uZW50IGVhcmx5LXJldHVybnMgd2hlbiB2aWV3aW5nIGEgdGVhbW1hdGUuXG4gIGNvbnN0IHVzZUJyaWVmTGF5b3V0ID1cbiAgICBmZWF0dXJlKCdLQUlST1MnKSB8fCBmZWF0dXJlKCdLQUlST1NfQlJJRUYnKVxuICAgICAgPyAvLyBiaW9tZS1pZ25vcmUgbGludC9jb3JyZWN0bmVzcy91c2VIb29rQXRUb3BMZXZlbDogZmVhdHVyZSgpIGlzIGEgY29tcGlsZS10aW1lIGNvbnN0YW50XG4gICAgICAgIHVzZUFwcFN0YXRlKHMgPT4gcy5pc0JyaWVmT25seSlcbiAgICAgIDogZmFsc2VcblxuICAvLyBjcmVhdGVVc2VyTWVzc2FnZSBtaW50cyBhIGZyZXNoIFVVSUQgcGVyIGNhbGw7IHdpdGhvdXQgbWVtb2l6YXRpb24sIHN0cmVhbWluZ1xuICAvLyByZS1yZW5kZXJzIGRlZmVhdCBNZXNzYWdlJ3MgYXJlTWVzc2FnZVByb3BzRXF1YWwgKGNvbXBhcmVzIHV1aWQpIOKGkiBmbGlja2VyLlxuICBjb25zdCBtZXNzYWdlcyA9IHVzZU1lbW8oKCkgPT4ge1xuICAgIGlmIChxdWV1ZWRDb21tYW5kcy5sZW5ndGggPT09IDApIHJldHVybiBudWxsXG4gICAgLy8gdGFzay1ub3RpZmljYXRpb24gaXMgc2hvd24gdmlhIHVzZUluYm94Tm90aWZpY2F0aW9uOyBtb3N0IGlzTWV0YSBjb21tYW5kc1xuICAgIC8vIChzY2hlZHVsZWQgdGFza3MsIHByb2FjdGl2ZSB0aWNrcykgYXJlIHN5c3RlbS1nZW5lcmF0ZWQgYW5kIGhpZGRlbi5cbiAgICAvLyBDaGFubmVsIG1lc3NhZ2VzIGFyZSB0aGUgZXhjZXB0aW9uIOKAlCBpc01ldGEgYnV0IHNob3duIHNvIHRoZSBrZXlib2FyZFxuICAgIC8vIHVzZXIgc2VlcyB3aGF0IGFycml2ZWQuXG4gICAgY29uc3QgdmlzaWJsZUNvbW1hbmRzID0gcXVldWVkQ29tbWFuZHMuZmlsdGVyKGlzUXVldWVkQ29tbWFuZFZpc2libGUpXG4gICAgaWYgKHZpc2libGVDb21tYW5kcy5sZW5ndGggPT09IDApIHJldHVybiBudWxsXG4gICAgY29uc3QgcHJvY2Vzc2VkQ29tbWFuZHMgPSBwcm9jZXNzUXVldWVkQ29tbWFuZHModmlzaWJsZUNvbW1hbmRzKVxuICAgIHJldHVybiBub3JtYWxpemVNZXNzYWdlcyhcbiAgICAgIHByb2Nlc3NlZENvbW1hbmRzLm1hcChjbWQgPT4ge1xuICAgICAgICBsZXQgY29udGVudCA9IGNtZC52YWx1ZVxuICAgICAgICBpZiAoY21kLm1vZGUgPT09ICdiYXNoJyAmJiB0eXBlb2YgY29udGVudCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgICBjb250ZW50ID0gYDxiYXNoLWlucHV0PiR7Y29udGVudH08L2Jhc2gtaW5wdXQ+YFxuICAgICAgICB9XG4gICAgICAgIC8vIFtJbWFnZSAjTl0gcGxhY2Vob2xkZXJzIGFyZSBpbmxpbmUgaW4gdGhlIHRleHQgdmFsdWUgKGluc2VydGVkIGF0XG4gICAgICAgIC8vIHBhc3RlIHRpbWUpLCBzbyB0aGUgcXVldWUgcHJldmlldyBzaG93cyB0aGVtIHdpdGhvdXQgc3R1YiBibG9ja3MuXG4gICAgICAgIHJldHVybiBjcmVhdGVVc2VyTWVzc2FnZSh7IGNvbnRlbnQgfSlcbiAgICAgIH0pLFxuICAgIClcbiAgfSwgW3F1ZXVlZENvbW1hbmRzXSlcblxuICAvLyBEb24ndCBzaG93IGxlYWRlcidzIHF1ZXVlZCBjb21tYW5kcyB3aGVuIHZpZXdpbmcgYW55IGFnZW50J3MgdHJhbnNjcmlwdFxuICBpZiAodmlld2luZ0FnZW50IHx8IG1lc3NhZ2VzID09PSBudWxsKSB7XG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgPEJveCBtYXJnaW5Ub3A9ezF9IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIj5cbiAgICAgIHttZXNzYWdlcy5tYXAoKG1lc3NhZ2UsIGkpID0+IChcbiAgICAgICAgPFF1ZXVlZE1lc3NhZ2VQcm92aWRlclxuICAgICAgICAgIGtleT17aX1cbiAgICAgICAgICBpc0ZpcnN0PXtpID09PSAwfVxuICAgICAgICAgIHVzZUJyaWVmTGF5b3V0PXt1c2VCcmllZkxheW91dH1cbiAgICAgICAgPlxuICAgICAgICAgIDxNZXNzYWdlXG4gICAgICAgICAgICBtZXNzYWdlPXttZXNzYWdlfVxuICAgICAgICAgICAgbG9va3Vwcz17RU1QVFlfTE9PS1VQU31cbiAgICAgICAgICAgIGFkZE1hcmdpbj17ZmFsc2V9XG4gICAgICAgICAgICB0b29scz17W119XG4gICAgICAgICAgICBjb21tYW5kcz17W119XG4gICAgICAgICAgICB2ZXJib3NlPXtmYWxzZX1cbiAgICAgICAgICAgIGluUHJvZ3Jlc3NUb29sVXNlSURzPXtFTVBUWV9TRVR9XG4gICAgICAgICAgICBwcm9ncmVzc01lc3NhZ2VzRm9yTWVzc2FnZT17W119XG4gICAgICAgICAgICBzaG91bGRBbmltYXRlPXtmYWxzZX1cbiAgICAgICAgICAgIHNob3VsZFNob3dEb3Q9e2ZhbHNlfVxuICAgICAgICAgICAgaXNUcmFuc2NyaXB0TW9kZT17ZmFsc2V9XG4gICAgICAgICAgICBpc1N0YXRpYz17dHJ1ZX1cbiAgICAgICAgICAvPlxuICAgICAgICA8L1F1ZXVlZE1lc3NhZ2VQcm92aWRlcj5cbiAgICAgICkpfVxuICAgIDwvQm94PlxuICApXG59XG5cbmV4cG9ydCBjb25zdCBQcm9tcHRJbnB1dFF1ZXVlZENvbW1hbmRzID0gUmVhY3QubWVtbyhcbiAgUHJvbXB0SW5wdXRRdWV1ZWRDb21tYW5kc0ltcGwsXG4pXG4iXSwibWFwcGluZ3MiOiJBQUFBLFNBQVNBLE9BQU8sUUFBUSxZQUFZO0FBQ3BDLE9BQU8sS0FBS0MsS0FBSyxNQUFNLE9BQU87QUFDOUIsU0FBU0MsT0FBTyxRQUFRLE9BQU87QUFDL0IsU0FBU0MsR0FBRyxRQUFRLFlBQVk7QUFDaEMsU0FBU0MsV0FBVyxRQUFRLHVCQUF1QjtBQUNuRCxTQUNFQyxVQUFVLEVBQ1ZDLFdBQVcsRUFDWEMscUJBQXFCLFFBQ2hCLHdCQUF3QjtBQUMvQixTQUFTQyxxQkFBcUIsUUFBUSx1Q0FBdUM7QUFDN0UsU0FBU0MsZUFBZSxRQUFRLGdDQUFnQztBQUNoRSxjQUFjQyxhQUFhLFFBQVEsK0JBQStCO0FBQ2xFLFNBQVNDLHNCQUFzQixRQUFRLG9DQUFvQztBQUMzRSxTQUNFQyxp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