| import { c as _c } from "react/compiler-runtime"; | |
| import * as React from 'react'; | |
| import { useEffect, useState } from 'react'; | |
| import { useSearchInput } from '../../hooks/useSearchInput.js'; | |
| import { useTerminalSize } from '../../hooks/useTerminalSize.js'; | |
| import type { KeyboardEvent } from '../../ink/events/keyboard-event.js'; | |
| import { clamp } from '../../ink/layout/geometry.js'; | |
| import { Box, Text, useTerminalFocus } from '../../ink.js'; | |
| import { SearchBox } from '../SearchBox.js'; | |
| import { Byline } from './Byline.js'; | |
| import { KeyboardShortcutHint } from './KeyboardShortcutHint.js'; | |
| import { ListItem } from './ListItem.js'; | |
| import { Pane } from './Pane.js'; | |
| type PickerAction<T> = { | |
| /** Hint label shown in the byline, e.g. "mention" → "Tab to mention". */ | |
| action: string; | |
| handler: (item: T) => void; | |
| }; | |
| type Props<T> = { | |
| title: string; | |
| placeholder?: string; | |
| initialQuery?: string; | |
| items: readonly T[]; | |
| getKey: (item: T) => string; | |
| /** Keep to one line — preview handles overflow. */ | |
| renderItem: (item: T, isFocused: boolean) => React.ReactNode; | |
| renderPreview?: (item: T) => React.ReactNode; | |
| /** 'right' keeps hints stable (no bounce), but needs width. */ | |
| previewPosition?: 'bottom' | 'right'; | |
| visibleCount?: number; | |
| /** | |
| * 'up' puts items[0] at the bottom next to the input (atuin-style). Arrows | |
| * always match screen direction — ↑ walks visually up regardless. | |
| */ | |
| direction?: 'down' | 'up'; | |
| /** Caller owns filtering: re-filter on each call and pass new items. */ | |
| onQueryChange: (query: string) => void; | |
| /** Enter key. Primary action. */ | |
| onSelect: (item: T) => void; | |
| /** | |
| * Tab key. If provided, Tab no longer aliases Enter — it gets its own | |
| * handler and hint. Shift+Tab falls through to this if onShiftTab is unset. | |
| */ | |
| onTab?: PickerAction<T>; | |
| /** Shift+Tab key. Gets its own hint. */ | |
| onShiftTab?: PickerAction<T>; | |
| /** | |
| * Fires when the focused item changes (via arrows or when items reset). | |
| * Useful for async preview loading — keeps I/O out of renderPreview. | |
| */ | |
| onFocus?: (item: T | undefined) => void; | |
| onCancel: () => void; | |
| /** Shown when items is empty. Caller bakes loading/searching state into this. */ | |
| emptyMessage?: string | ((query: string) => string); | |
| /** | |
| * Status line below the list, e.g. "500+ matches" or "42 matches…". | |
| * Caller decides when to show it — pass undefined to hide. | |
| */ | |
| matchLabel?: string; | |
| selectAction?: string; | |
| extraHints?: React.ReactNode; | |
| }; | |
| const DEFAULT_VISIBLE = 8; | |
| // Pane (paddingTop + Divider) + title + 3 gaps + SearchBox (rounded border = 3 | |
| // rows) + hints. matchLabel adds +1 when present, accounted for separately. | |
| const CHROME_ROWS = 10; | |
| const MIN_VISIBLE = 2; | |
| export function FuzzyPicker<T>({ | |
| title, | |
| placeholder = 'Type to search…', | |
| initialQuery, | |
| items, | |
| getKey, | |
| renderItem, | |
| renderPreview, | |
| previewPosition = 'bottom', | |
| visibleCount: requestedVisible = DEFAULT_VISIBLE, | |
| direction = 'down', | |
| onQueryChange, | |
| onSelect, | |
| onTab, | |
| onShiftTab, | |
| onFocus, | |
| onCancel, | |
| emptyMessage = 'No results', | |
| matchLabel, | |
| selectAction = 'select', | |
| extraHints | |
| }: Props<T>): React.ReactNode { | |
| const isTerminalFocused = useTerminalFocus(); | |
| const { | |
| rows, | |
| columns | |
| } = useTerminalSize(); | |
| const [focusedIndex, setFocusedIndex] = useState(0); | |
| // Cap visibleCount so the picker never exceeds the terminal height. When it | |
| // overflows, each re-render (arrow key, ctrl+p) mis-positions the cursor-up | |
| // by the overflow amount and a previously-drawn line flashes blank. | |
| const visibleCount = Math.max(MIN_VISIBLE, Math.min(requestedVisible, rows - CHROME_ROWS - (matchLabel ? 1 : 0))); | |
| // Full hint row with onTab+onShiftTab is ~100 chars and wraps inconsistently | |
| // below that. Compact mode drops shift+tab and shortens labels. | |
| const compact = columns < 120; | |
| const step = (delta: 1 | -1) => { | |
| setFocusedIndex(i => clamp(i + delta, 0, items.length - 1)); | |
| }; | |
| // onKeyDown fires after useSearchInput's useInput, so onExit must be a | |
| // no-op — return/downArrow are handled by handleKeyDown below. onCancel | |
| // still covers escape/ctrl+c/ctrl+d. Backspace-on-empty is disabled so | |
| // a held backspace doesn't eject the user from the dialog. | |
| const { | |
| query, | |
| cursorOffset | |
| } = useSearchInput({ | |
| isActive: true, | |
| onExit: () => {}, | |
| onCancel, | |
| initialQuery, | |
| backspaceExitsOnEmpty: false | |
| }); | |
| const handleKeyDown = (e: KeyboardEvent) => { | |
| if (e.key === 'up' || e.ctrl && e.key === 'p') { | |
| e.preventDefault(); | |
| e.stopImmediatePropagation(); | |
| step(direction === 'up' ? 1 : -1); | |
| return; | |
| } | |
| if (e.key === 'down' || e.ctrl && e.key === 'n') { | |
| e.preventDefault(); | |
| e.stopImmediatePropagation(); | |
| step(direction === 'up' ? -1 : 1); | |
| return; | |
| } | |
| if (e.key === 'return') { | |
| e.preventDefault(); | |
| e.stopImmediatePropagation(); | |
| const selected = items[focusedIndex]; | |
| if (selected) onSelect(selected); | |
| return; | |
| } | |
| if (e.key === 'tab') { | |
| e.preventDefault(); | |
| e.stopImmediatePropagation(); | |
| const selected = items[focusedIndex]; | |
| if (!selected) return; | |
| const tabAction = e.shift ? onShiftTab ?? onTab : onTab; | |
| if (tabAction) { | |
| tabAction.handler(selected); | |
| } else { | |
| onSelect(selected); | |
| } | |
| } | |
| }; | |
| useEffect(() => { | |
| onQueryChange(query); | |
| setFocusedIndex(0); | |
| // eslint-disable-next-line react-hooks/exhaustive-deps | |
| }, [query]); | |
| useEffect(() => { | |
| setFocusedIndex(i => clamp(i, 0, items.length - 1)); | |
| }, [items.length]); | |
| const focused = items[focusedIndex]; | |
| useEffect(() => { | |
| onFocus?.(focused); | |
| // eslint-disable-next-line react-hooks/exhaustive-deps | |
| }, [focused]); | |
| const windowStart = clamp(focusedIndex - visibleCount + 1, 0, items.length - visibleCount); | |
| const visible = items.slice(windowStart, windowStart + visibleCount); | |
| const emptyText = typeof emptyMessage === 'function' ? emptyMessage(query) : emptyMessage; | |
| const searchBox = <SearchBox query={query} cursorOffset={cursorOffset} placeholder={placeholder} isFocused isTerminalFocused={isTerminalFocused} />; | |
| const listBlock = <List visible={visible} windowStart={windowStart} visibleCount={visibleCount} total={items.length} focusedIndex={focusedIndex} direction={direction} getKey={getKey} renderItem={renderItem} emptyText={emptyText} />; | |
| const preview = renderPreview && focused ? <Box flexDirection="column" flexGrow={1}> | |
| {renderPreview(focused)} | |
| </Box> : null; | |
| // Structure must not depend on preview truthiness — when focused goes | |
| // undefined (e.g. delete clears matches), switching row→fragment would | |
| // change both layout AND gap count, bouncing the searchBox below. | |
| const listGroup = renderPreview && previewPosition === 'right' ? <Box flexDirection="row" gap={2} height={visibleCount + (matchLabel ? 1 : 0)}> | |
| <Box flexDirection="column" flexShrink={0}> | |
| {listBlock} | |
| {matchLabel && <Text dimColor>{matchLabel}</Text>} | |
| </Box> | |
| {preview ?? <Box flexGrow={1} />} | |
| </Box> : | |
| // Box (not fragment) so the outer gap={1} doesn't insert a blank line | |
| // between list/matchLabel/preview — that read as extra space above the | |
| // prompt in direction='up'. | |
| <Box flexDirection="column"> | |
| {listBlock} | |
| {matchLabel && <Text dimColor>{matchLabel}</Text>} | |
| {preview} | |
| </Box>; | |
| const inputAbove = direction !== 'up'; | |
| return <Pane color="permission"> | |
| <Box flexDirection="column" gap={1} tabIndex={0} autoFocus onKeyDown={handleKeyDown}> | |
| <Text bold color="permission"> | |
| {title} | |
| </Text> | |
| {inputAbove && searchBox} | |
| {listGroup} | |
| {!inputAbove && searchBox} | |
| <Text dimColor> | |
| <Byline> | |
| <KeyboardShortcutHint shortcut="↑/↓" action={compact ? 'nav' : 'navigate'} /> | |
| <KeyboardShortcutHint shortcut="Enter" action={compact ? firstWord(selectAction) : selectAction} /> | |
| {onTab && <KeyboardShortcutHint shortcut="Tab" action={onTab.action} />} | |
| {onShiftTab && !compact && <KeyboardShortcutHint shortcut="shift+tab" action={onShiftTab.action} />} | |
| <KeyboardShortcutHint shortcut="Esc" action="cancel" /> | |
| {extraHints} | |
| </Byline> | |
| </Text> | |
| </Box> | |
| </Pane>; | |
| } | |
| type ListProps<T> = Pick<Props<T>, 'visibleCount' | 'direction' | 'getKey' | 'renderItem'> & { | |
| visible: readonly T[]; | |
| windowStart: number; | |
| total: number; | |
| focusedIndex: number; | |
| emptyText: string; | |
| }; | |
| function List(t0) { | |
| const $ = _c(27); | |
| const { | |
| visible, | |
| windowStart, | |
| visibleCount, | |
| total, | |
| focusedIndex, | |
| direction, | |
| getKey, | |
| renderItem, | |
| emptyText | |
| } = t0; | |
| if (visible.length === 0) { | |
| let t1; | |
| if ($[0] !== emptyText) { | |
| t1 = <Text dimColor={true}>{emptyText}</Text>; | |
| $[0] = emptyText; | |
| $[1] = t1; | |
| } else { | |
| t1 = $[1]; | |
| } | |
| let t2; | |
| if ($[2] !== t1 || $[3] !== visibleCount) { | |
| t2 = <Box height={visibleCount} flexShrink={0}>{t1}</Box>; | |
| $[2] = t1; | |
| $[3] = visibleCount; | |
| $[4] = t2; | |
| } else { | |
| t2 = $[4]; | |
| } | |
| return t2; | |
| } | |
| let t1; | |
| if ($[5] !== direction || $[6] !== focusedIndex || $[7] !== getKey || $[8] !== renderItem || $[9] !== total || $[10] !== visible || $[11] !== visibleCount || $[12] !== windowStart) { | |
| let t2; | |
| if ($[14] !== direction || $[15] !== focusedIndex || $[16] !== getKey || $[17] !== renderItem || $[18] !== total || $[19] !== visible.length || $[20] !== visibleCount || $[21] !== windowStart) { | |
| t2 = (item, i) => { | |
| const actualIndex = windowStart + i; | |
| const isFocused = actualIndex === focusedIndex; | |
| const atLowEdge = i === 0 && windowStart > 0; | |
| const atHighEdge = i === visible.length - 1 && windowStart + visibleCount < total; | |
| return <ListItem key={getKey(item)} isFocused={isFocused} showScrollUp={direction === "up" ? atHighEdge : atLowEdge} showScrollDown={direction === "up" ? atLowEdge : atHighEdge} styled={false}>{renderItem(item, isFocused)}</ListItem>; | |
| }; | |
| $[14] = direction; | |
| $[15] = focusedIndex; | |
| $[16] = getKey; | |
| $[17] = renderItem; | |
| $[18] = total; | |
| $[19] = visible.length; | |
| $[20] = visibleCount; | |
| $[21] = windowStart; | |
| $[22] = t2; | |
| } else { | |
| t2 = $[22]; | |
| } | |
| t1 = visible.map(t2); | |
| $[5] = direction; | |
| $[6] = focusedIndex; | |
| $[7] = getKey; | |
| $[8] = renderItem; | |
| $[9] = total; | |
| $[10] = visible; | |
| $[11] = visibleCount; | |
| $[12] = windowStart; | |
| $[13] = t1; | |
| } else { | |
| t1 = $[13]; | |
| } | |
| const rows = t1; | |
| const t2 = direction === "up" ? "column-reverse" : "column"; | |
| let t3; | |
| if ($[23] !== rows || $[24] !== t2 || $[25] !== visibleCount) { | |
| t3 = <Box height={visibleCount} flexShrink={0} flexDirection={t2}>{rows}</Box>; | |
| $[23] = rows; | |
| $[24] = t2; | |
| $[25] = visibleCount; | |
| $[26] = t3; | |
| } else { | |
| t3 = $[26]; | |
| } | |
| return t3; | |
| } | |
| function firstWord(s: string): string { | |
| const i = s.indexOf(' '); | |
| return i === -1 ? s : s.slice(0, i); | |
| } | |
| //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsInVzZUVmZmVjdCIsInVzZVN0YXRlIiwidXNlU2VhcmNoSW5wdXQiLCJ1c2VUZXJtaW5hbFNpemUiLCJLZXlib2FyZEV2ZW50IiwiY2xhbXAiLCJCb3giLCJUZXh0IiwidXNlVGVybWluYWxGb2N1cyIsIlNlYXJjaEJveCIsIkJ5bGluZSIsIktleWJvYXJkU2hvcnRjdXRIaW50IiwiTGlzdEl0ZW0iLCJQYW5lIiwiUGlja2VyQWN0aW9uIiwiYWN0aW9uIiwiaGFuZGxlciIsIml0ZW0iLCJUIiwiUHJvcHMiLCJ0aXRsZSIsInBsYWNlaG9sZGVyIiwiaW5pdGlhbFF1ZXJ5IiwiaXRlbXMiLCJnZXRLZXkiLCJyZW5kZXJJdGVtIiwiaXNGb2N1c2VkIiwiUmVhY3ROb2RlIiwicmVuZGVyUHJldmlldyIsInByZXZpZXdQb3NpdGlvbiIsInZpc2libGVDb3VudCIsImRpcmVjdGlvbiIsIm9uUXVlcnlDaGFuZ2UiLCJxdWVyeSIsIm9uU2VsZWN0Iiwib25UYWIiLCJvblNoaWZ0VGFiIiwib25Gb2N1cyIsIm9uQ2FuY2VsIiwiZW1wdHlNZXNzYWdlIiwibWF0Y2hMYWJlbCIsInNlbGVjdEFjdGlvbiIsImV4dHJhSGludHMiLCJERUZBVUxUX1ZJU0lCTEUiLCJDSFJPTUVfUk9XUyIsIk1JTl9WSVNJQkxFIiwiRnV6enlQaWNrZXIiLCJyZXF1ZXN0ZWRWaXNpYmxlIiwiaXNUZXJtaW5hbEZvY3VzZWQiLCJyb3dzIiwiY29sdW1ucyIsImZvY3VzZWRJbmRleCIsInNldEZvY3VzZWRJbmRleCIsIk1hdGgiLCJtYXgiLCJtaW4iLCJjb21wYWN0Iiwic3RlcCIsImRlbHRhIiwiaSIsImxlbmd0aCIsImN1cnNvck9mZnNldCIsImlzQWN0aXZlIiwib25FeGl0IiwiYmFja3NwYWNlRXhpdHNPbkVtcHR5IiwiaGFuZGxlS2V5RG93biIsImUiLCJrZXkiLCJjdHJsIiwicHJldmVudERlZmF1bHQiLCJzdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24iLCJzZWxlY3RlZCIsInRhYkFjdGlvbiIsInNoaWZ0IiwiZm9jdXNlZCIsIndpbmRvd1N0YXJ0IiwidmlzaWJsZSIsInNsaWNlIiwiZW1wdHlUZXh0Iiwic2VhcmNoQm94IiwibGlzdEJsb2NrIiwicHJldmlldyIsImxpc3RHcm91cCIsImlucHV0QWJvdmUiLCJmaXJzdFdvcmQiLCJMaXN0UHJvcHMiLCJQaWNrIiwidG90YWwiLCJMaXN0IiwidDAiLCIkIiwiX2MiLCJ0MSIsInQyIiwiYWN0dWFsSW5kZXgiLCJhdExvd0VkZ2UiLCJhdEhpZ2hFZGdlIiwibWFwIiwidDMiLCJzIiwiaW5kZXhPZiJdLCJzb3VyY2VzIjpbIkZ1enp5UGlja2VyLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBSZWFjdCBmcm9tICdyZWFjdCdcbmltcG9ydCB7IHVzZUVmZmVjdCwgdXNlU3RhdGUgfSBmcm9tICdyZWFjdCdcbmltcG9ydCB7IHVzZVNlYXJjaElucHV0IH0gZnJvbSAnLi4vLi4vaG9va3MvdXNlU2VhcmNoSW5wdXQuanMnXG5pbXBvcnQgeyB1c2VUZXJtaW5hbFNpemUgfSBmcm9tICcuLi8uLi9ob29rcy91c2VUZXJtaW5hbFNpemUuanMnXG5pbXBvcnQgdHlwZSB7IEtleWJvYXJkRXZlbnQgfSBmcm9tICcuLi8uLi9pbmsvZXZlbnRzL2tleWJvYXJkLWV2ZW50LmpzJ1xuaW1wb3J0IHsgY2xhbXAgfSBmcm9tICcuLi8uLi9pbmsvbGF5b3V0L2dlb21ldHJ5LmpzJ1xuaW1wb3J0IHsgQm94LCBUZXh0LCB1c2VUZXJtaW5hbEZvY3VzIH0gZnJvbSAnLi4vLi4vaW5rLmpzJ1xuaW1wb3J0IHsgU2VhcmNoQm94IH0gZnJvbSAnLi4vU2VhcmNoQm94LmpzJ1xuaW1wb3J0IHsgQnlsaW5lIH0gZnJvbSAnLi9CeWxpbmUuanMnXG5pbXBvcnQgeyBLZXlib2FyZFNob3J0Y3V0SGludCB9IGZyb20gJy4vS2V5Ym9hcmRTaG9ydGN1dEhpbnQuanMnXG5pbXBvcnQgeyBMaXN0SXRlbSB9IGZyb20gJy4vTGlzdEl0ZW0uanMnXG5pbXBvcnQgeyBQYW5lIH0gZnJvbSAnLi9QYW5lLmpzJ1xuXG50eXBlIFBpY2tlckFjdGlvbjxUPiA9IHtcbiAgLyoqIEhpbnQgbGFiZWwgc2hvd24gaW4gdGhlIGJ5bGluZSwgZS5nLiBcIm1lbnRpb25cIiDihpIgXCJUYWIgdG8gbWVudGlvblwiLiAqL1xuICBhY3Rpb246IHN0cmluZ1xuICBoYW5kbGVyOiAoaXRlbTogVCkgPT4gdm9pZFxufVxuXG50eXBlIFByb3BzPFQ+ID0ge1xuICB0aXRsZTogc3RyaW5nXG4gIHBsYWNlaG9sZGVyPzogc3RyaW5nXG4gIGluaXRpYWxRdWVyeT86IHN0cmluZ1xuICBpdGVtczogcmVhZG9ubHkgVFtdXG4gIGdldEtleTogKGl0ZW06IFQpID0+IHN0cmluZ1xuICAvKiogS2VlcCB0byBvbmUgbGluZSDigJQgcHJldmlldyBoYW5kbGVzIG92ZXJmbG93LiAqL1xuICByZW5kZXJJdGVtOiAoaXRlbTogVCwgaXNGb2N1c2VkOiBib29sZWFuKSA9PiBSZWFjdC5SZWFjdE5vZGVcbiAgcmVuZGVyUHJldmlldz86IChpdGVtOiBUKSA9PiBSZWFjdC5SZWFjdE5vZGVcbiAgLyoqICdyaWdodCcga2VlcHMgaGludHMgc3RhYmxlIChubyBib3VuY2UpLCBidXQgbmVlZHMgd2lkdGguICovXG4gIHByZXZpZXdQb3NpdGlvbj86ICdib3R0b20nIHwgJ3JpZ2h0J1xuICB2aXNpYmxlQ291bnQ/OiBudW1iZXJcbiAgLyoqXG4gICAqICd1cCcgcHV0cyBpdGVtc1swXSBhdCB0aGUgYm90dG9tIG5leHQgdG8gdGhlIGlucHV0IChhdHVpbi1zdHlsZSkuIEFycm93c1xuICAgKiBhbHdheXMgbWF0Y2ggc2NyZWVuIGRpcmVjdGlvbiDigJQg4oaRIHdhbGtzIHZpc3VhbGx5IHVwIHJlZ2FyZGxlc3MuXG4gICAqL1xuICBkaXJlY3Rpb24/OiAnZG93bicgfCAndXAnXG4gIC8qKiBDYWxsZXIgb3ducyBmaWx0ZXJpbmc6IHJlLWZpbHRlciBvbiBlYWNoIGNhbGwgYW5kIHBhc3MgbmV3IGl0ZW1zLiAqL1xuICBvblF1ZXJ5Q2hhbmdlOiAocXVlcnk6IHN0cmluZykgPT4gdm9pZFxuICAvKiogRW50ZXIga2V5LiBQcmltYXJ5IGFjdGlvbi4gKi9cbiAgb25TZWxlY3Q6IChpdGVtOiBUKSA9PiB2b2lkXG4gIC8qKlxuICAgKiBUYWIga2V5LiBJZiBwcm92aWRlZCwgVGFiIG5vIGxvbmdlciBhbGlhc2VzIEVudGVyIOKAlCBpdCBnZXRzIGl0cyBvd25cbiAgICogaGFuZGxlciBhbmQgaGludC4gU2hpZnQrVGFiIGZhbGxzIHRocm91Z2ggdG8gdGhpcyBpZiBvblNoaWZ0VGFiIGlzIHVuc2V0LlxuICAgKi9cbiAgb25UYWI/OiBQaWNrZXJBY3Rpb248VD5cbiAgLyoqIFNoaWZ0K1RhYiBrZXkuIEdldHMgaXRzIG93biBoaW50LiAqL1xuICBvblNoaWZ0VGFiPzogUGlja2VyQWN0aW9uPFQ+XG4gIC8qKlxuICAgKiBGaXJlcyB3aGVuIHRoZSBmb2N1c2VkIGl0ZW0gY2hhbmdlcyAodmlhIGFycm93cyBvciB3aGVuIGl0ZW1zIHJlc2V0KS5cbiAgICogVXNlZnVsIGZvciBhc3luYyBwcmV2aWV3IGxvYWRpbmcg4oCUIGtlZXBzIEkvTyBvdXQgb2YgcmVuZGVyUHJldmlldy5cbiAgICovXG4gIG9uRm9jdXM/OiAoaXRlbTogVCB8IHVuZGVmaW5lZCkgPT4gdm9pZFxuICBvbkNhbmNlbDogKCkgPT4gdm9pZFxuICAvKiogU2hvd24gd2hlbiBpdGVtcyBpcyBlbXB0eS4gQ2FsbGVyIGJha2VzIGxvYWRpbmcvc2VhcmNoaW5nIHN0YXRlIGludG8gdGhpcy4gKi9cbiAgZW1wdHlNZXNzYWdlPzogc3RyaW5nIHwgKChxdWVyeTogc3RyaW5nKSA9PiBzdHJpbmcpXG4gIC8qKlxuICAgKiBTdGF0dXMgbGluZSBiZWxvdyB0aGUgbGlzdCwgZS5nLiBcIjUwMCsgbWF0Y2hlc1wiIG9yIFwiNDIgbWF0Y2hlc+KAplwiLlxuICAgKiBDYWxsZXIgZGVjaWRlcyB3aGVuIHRvIHNob3cgaXQg4oCUIHBhc3MgdW5kZWZpbmVkIHRvIGhpZGUuXG4gICAqL1xuICBtYXRjaExhYmVsPzogc3RyaW5nXG4gIHNlbGVjdEFjdGlvbj86IHN0cmluZ1xuICBleHRyYUhpbnRzPzogUmVhY3QuUmVhY3ROb2RlXG59XG5cbmNvbnN0IERFRkFVTFRfVklTSUJMRSA9IDhcbi8vIFBhbmUgKHBhZGRpbmdUb3AgKyBEaXZpZGVyKSArIHRpdGxlICsgMyBnYXBzICsgU2VhcmNoQm94IChyb3VuZGVkIGJvcmRlciA9IDNcbi8vIHJvd3MpICsgaGludHMuIG1hdGNoTGFiZWwgYWRkcyArMSB3aGVuIHByZXNlbnQsIGFjY291bnRlZCBmb3Igc2VwYXJhdGVseS5cbmNvbnN0IENIUk9NRV9ST1dTID0gMTBcbmNvbnN0IE1JTl9WSVNJQkxFID0gMlxuXG5leHBvcnQgZnVuY3Rpb24gRnV6enlQaWNrZXI8VD4oe1xuICB0aXRsZSxcbiAgcGxhY2Vob2xkZXIgPSAnVHlwZSB0byBzZWFyY2jigKYnLFxuICBpbml0aWFsUXVlcnksXG4gIGl0ZW1zLFxuICBnZXRLZXksXG4gIHJlbmRlckl0ZW0sXG4gIHJlbmRlclByZXZpZXcsXG4gIHByZXZpZXdQb3NpdGlvbiA9ICdib3R0b20nLFxuICB2aXNpYmxlQ291bnQ6IHJlcXVlc3RlZFZpc2libGUgPSBERUZBVUxUX1ZJU0lCTEUsXG4gIGRpcmVjdGlvbiA9ICdkb3duJyxcbiAgb25RdWVyeUNoYW5nZSxcbiAgb25TZWxlY3QsXG4gIG9uVGFiLFxuICBvblNoaWZ0VGFiLFxuICBvbkZvY3VzLFxuICBvbkNhbmNlbCxcbiAgZW1wdHlNZXNzYWdlID0gJ05vIHJlc3VsdHMnLFxuICBtYXRjaExhYmVsLFxuICBzZWxlY3RBY3Rpb24gPSAnc2VsZWN0JyxcbiAgZXh0cmFIaW50cyxcbn06IFByb3BzPFQ+KTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgY29uc3QgaXNUZXJtaW5hbEZvY3VzZWQgPSB1c2VUZXJtaW5hbEZvY3VzKClcbiAgY29uc3QgeyByb3dzLCBjb2x1bW5zIH0gPSB1c2VUZXJtaW5hbFNpemUoKVxuICBjb25zdCBbZm9jdXNlZEluZGV4LCBzZXRGb2N1c2VkSW5kZXhdID0gdXNlU3RhdGUoMClcblxuICAvLyBDYXAgdmlzaWJsZUNvdW50IHNvIHRoZSBwaWNrZXIgbmV2ZXIgZXhjZWVkcyB0aGUgdGVybWluYWwgaGVpZ2h0LiBXaGVuIGl0XG4gIC8vIG92ZXJmbG93cywgZWFjaCByZS1yZW5kZXIgKGFycm93IGtleSwgY3RybCtwKSBtaXMtcG9zaXRpb25zIHRoZSBjdXJzb3ItdXBcbiAgLy8gYnkgdGhlIG92ZXJmbG93IGFtb3VudCBhbmQgYSBwcmV2aW91c2x5LWRyYXduIGxpbmUgZmxhc2hlcyBibGFuay5cbiAgY29uc3QgdmlzaWJsZUNvdW50ID0gTWF0aC5tYXgoXG4gICAgTUlOX1ZJU0lCTEUsXG4gICAgTWF0aC5taW4ocmVxdWVzdGVkVmlzaWJsZSwgcm93cyAtIENIUk9NRV9ST1dTIC0gKG1hdGNoTGFiZWwgPyAxIDogMCkpLFxuICApXG5cbiAgLy8gRnVsbCBoaW50IHJvdyB3aXRoIG9uVGFiK29uU2hpZnRUYWIgaXMgfjEwMCBjaGFycyBhbmQgd3JhcHMgaW5jb25zaXN0ZW50bHlcbiAgLy8gYmVsb3cgdGhhdC4gQ29tcGFjdCBtb2RlIGRyb3BzIHNoaWZ0K3RhYiBhbmQgc2hvcnRlbnMgbGFiZWxzLlxuICBjb25zdCBjb21wYWN0ID0gY29sdW1ucyA8IDEyMFxuXG4gIGNvbnN0IHN0ZXAgPSAoZGVsdGE6IDEgfCAtMSkgPT4ge1xuICAgIHNldEZvY3VzZWRJbmRleChpID0+IGNsYW1wKGkgKyBkZWx0YSwgMCwgaXRlbXMubGVuZ3RoIC0gMSkpXG4gIH1cblxuICAvLyBvbktleURvd24gZmlyZXMgYWZ0ZXIgdXNlU2VhcmNoSW5wdXQncyB1c2VJbnB1dCwgc28gb25FeGl0IG11c3QgYmUgYVxuICAvLyBuby1vcCDigJQgcmV0dXJuL2Rvd25BcnJvdyBhcmUgaGFuZGxlZCBieSBoYW5kbGVLZXlEb3duIGJlbG93LiBvbkNhbmNlbFxuICAvLyBzdGlsbCBjb3ZlcnMgZXNjYXBlL2N0cmwrYy9jdHJsK2QuIEJhY2tzcGFjZS1vbi1lbXB0eSBpcyBkaXNhYmxlZCBzb1xuICAvLyBhIGhlbGQgYmFja3NwYWNlIGRvZXNuJ3QgZWplY3QgdGhlIHVzZXIgZnJvbSB0aGUgZGlhbG9nLlxuICBjb25zdCB7IHF1ZXJ5LCBjdXJzb3JPZmZzZXQgfSA9IHVzZVNlYXJjaElucHV0KHtcbiAgICBpc0FjdGl2ZTogdHJ1ZSxcbiAgICBvbkV4aXQ6ICgpID0+IHt9LFxuICAgIG9uQ2FuY2VsLFxuICAgIGluaXRpYWxRdWVyeSxcbiAgICBiYWNrc3BhY2VFeGl0c09uRW1wdHk6IGZhbHNlLFxuICB9KVxuXG4gIGNvbnN0IGhhbmRsZUtleURvd24gPSAoZTogS2V5Ym9hcmRFdmVudCkgPT4ge1xuICAgIGlmIChlLmtleSA9PT0gJ3VwJyB8fCAoZS5jdHJsICYmIGUua2V5ID09PSAncCcpKSB7XG4gICAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICAgIGUuc3RvcEltbWVkaWF0ZVByb3BhZ2F0aW9uKClcbiAgICAgIHN0ZXAoZGlyZWN0aW9uID09PSAndXAnID8gMSA6IC0xKVxuICAgICAgcmV0dXJuXG4gICAgfVxuICAgIGlmIChlLmtleSA9PT0gJ2Rvd24nIHx8IChlLmN0cmwgJiYgZS5rZXkgPT09ICduJykpIHtcbiAgICAgIGUucHJldmVudERlZmF1bHQoKVxuICAgICAgZS5zdG9wSW1tZWRpYXRlUHJvcGFnYXRpb24oKVxuICAgICAgc3RlcChkaXJlY3Rpb24gPT09ICd1cCcgPyAtMSA6IDEpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGUua2V5ID09PSAncmV0dXJuJykge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpXG4gICAgICBjb25zdCBzZWxlY3RlZCA9IGl0ZW1zW2ZvY3VzZWRJbmRleF1cbiAgICAgIGlmIChzZWxlY3RlZCkgb25TZWxlY3Qoc2VsZWN0ZWQpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgaWYgKGUua2V5ID09PSAndGFiJykge1xuICAgICAgZS5wcmV2ZW50RGVmYXVsdCgpXG4gICAgICBlLnN0b3BJbW1lZGlhdGVQcm9wYWdhdGlvbigpXG4gICAgICBjb25zdCBzZWxlY3RlZCA9IGl0ZW1zW2ZvY3VzZWRJbmRleF1cbiAgICAgIGlmICghc2VsZWN0ZWQpIHJldHVyblxuICAgICAgY29uc3QgdGFiQWN0aW9uID0gZS5zaGlmdCA/IChvblNoaWZ0VGFiID8/IG9uVGFiKSA6IG9uVGFiXG4gICAgICBpZiAodGFiQWN0aW9uKSB7XG4gICAgICAgIHRhYkFjdGlvbi5oYW5kbGVyKHNlbGVjdGVkKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb25TZWxlY3Qoc2VsZWN0ZWQpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBvblF1ZXJ5Q2hhbmdlKHF1ZXJ5KVxuICAgIHNldEZvY3VzZWRJbmRleCgwKVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgfSwgW3F1ZXJ5XSlcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIHNldEZvY3VzZWRJbmRleChpID0+IGNsYW1wKGksIDAsIGl0ZW1zLmxlbmd0aCAtIDEpKVxuICB9LCBbaXRlbXMubGVuZ3RoXSlcblxuICBjb25zdCBmb2N1c2VkID0gaXRlbXNbZm9jdXNlZEluZGV4XVxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIG9uRm9jdXM/Lihmb2N1c2VkKVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgfSwgW2ZvY3VzZWRdKVxuXG4gIGNvbnN0IHdpbmRvd1N0YXJ0ID0gY2xhbXAoXG4gICAgZm9jdXNlZEluZGV4IC0gdmlzaWJsZUNvdW50ICsgMSxcbiAgICAwLFxuICAgIGl0ZW1zLmxlbmd0aCAtIHZpc2libGVDb3VudCxcbiAgKVxuICBjb25zdCB2aXNpYmxlID0gaXRlbXMuc2xpY2Uod2luZG93U3RhcnQsIHdpbmRvd1N0YXJ0ICsgdmlzaWJsZUNvdW50KVxuXG4gIGNvbnN0IGVtcHR5VGV4dCA9XG4gICAgdHlwZW9mIGVtcHR5TWVzc2FnZSA9PT0gJ2Z1bmN0aW9uJyA/IGVtcHR5TWVzc2FnZShxdWVyeSkgOiBlbXB0eU1lc3NhZ2VcblxuICBjb25zdCBzZWFyY2hCb3ggPSAoXG4gICAgPFNlYXJjaEJveFxuICAgICAgcXVlcnk9e3F1ZXJ5fVxuICAgICAgY3Vyc29yT2Zmc2V0PXtjdXJzb3JPZmZzZXR9XG4gICAgICBwbGFjZWhvbGRlcj17cGxhY2Vob2xkZXJ9XG4gICAgICBpc0ZvY3VzZWRcbiAgICAgIGlzVGVybWluYWxGb2N1c2VkPXtpc1Rlcm1pbmFsRm9jdXNlZH1cbiAgICAvPlxuICApXG5cbiAgY29uc3QgbGlzdEJsb2NrID0gKFxuICAgIDxMaXN0XG4gICAgICB2aXNpYmxlPXt2aXNpYmxlfVxuICAgICAgd2luZG93U3RhcnQ9e3dpbmRvd1N0YXJ0fVxuICAgICAgdmlzaWJsZUNvdW50PXt2aXNpYmxlQ291bnR9XG4gICAgICB0b3RhbD17aXRlbXMubGVuZ3RofVxuICAgICAgZm9jdXNlZEluZGV4PXtmb2N1c2VkSW5kZXh9XG4gICAgICBkaXJlY3Rpb249e2RpcmVjdGlvbn1cbiAgICAgIGdldEtleT17Z2V0S2V5fVxuICAgICAgcmVuZGVySXRlbT17cmVuZGVySXRlbX1cbiAgICAgIGVtcHR5VGV4dD17ZW1wdHlUZXh0fVxuICAgIC8+XG4gIClcblxuICBjb25zdCBwcmV2aWV3ID1cbiAgICByZW5kZXJQcmV2aWV3ICYmIGZvY3VzZWQgPyAoXG4gICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBmbGV4R3Jvdz17MX0+XG4gICAgICAgIHtyZW5kZXJQcmV2aWV3KGZvY3VzZWQpfVxuICAgICAgPC9Cb3g+XG4gICAgKSA6IG51bGxcblxuICAvLyBTdHJ1Y3R1cmUgbXVzdCBub3QgZGVwZW5kIG9uIHByZXZpZXcgdHJ1dGhpbmVzcyDigJQgd2hlbiBmb2N1c2VkIGdvZXNcbiAgLy8gdW5kZWZpbmVkIChlLmcuIGRlbGV0ZSBjbGVhcnMgbWF0Y2hlcyksIHN3aXRjaGluZyByb3fihpJmcmFnbWVudCB3b3VsZFxuICAvLyBjaGFuZ2UgYm90aCBsYXlvdXQgQU5EIGdhcCBjb3VudCwgYm91bmNpbmcgdGhlIHNlYXJjaEJveCBiZWxvdy5cbiAgY29uc3QgbGlzdEdyb3VwID1cbiAgICByZW5kZXJQcmV2aWV3ICYmIHByZXZpZXdQb3NpdGlvbiA9PT0gJ3JpZ2h0JyA/IChcbiAgICAgIDxCb3hcbiAgICAgICAgZmxleERpcmVjdGlvbj1cInJvd1wiXG4gICAgICAgIGdhcD17Mn1cbiAgICAgICAgaGVpZ2h0PXt2aXNpYmxlQ291bnQgKyAobWF0Y2hMYWJlbCA/IDEgOiAwKX1cbiAgICAgID5cbiAgICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCIgZmxleFNocmluaz17MH0+XG4gICAgICAgICAge2xpc3RCbG9ja31cbiAgICAgICAgICB7bWF0Y2hMYWJlbCAmJiA8VGV4dCBkaW1Db2xvcj57bWF0Y2hMYWJlbH08L1RleHQ+fVxuICAgICAgICA8L0JveD5cbiAgICAgICAge3ByZXZpZXcgPz8gPEJveCBmbGV4R3Jvdz17MX0gLz59XG4gICAgICA8L0JveD5cbiAgICApIDogKFxuICAgICAgLy8gQm94IChub3QgZnJhZ21lbnQpIHNvIHRoZSBvdXRlciBnYXA9ezF9IGRvZXNuJ3QgaW5zZXJ0IGEgYmxhbmsgbGluZVxuICAgICAgLy8gYmV0d2VlbiBsaXN0L21hdGNoTGFiZWwvcHJldmlldyDigJQgdGhhdCByZWFkIGFzIGV4dHJhIHNwYWNlIGFib3ZlIHRoZVxuICAgICAgLy8gcHJvbXB0IGluIGRpcmVjdGlvbj0ndXAnLlxuICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCI+XG4gICAgICAgIHtsaXN0QmxvY2t9XG4gICAgICAgIHttYXRjaExhYmVsICYmIDxUZXh0IGRpbUNvbG9yPnttYXRjaExhYmVsfTwvVGV4dD59XG4gICAgICAgIHtwcmV2aWV3fVxuICAgICAgPC9Cb3g+XG4gICAgKVxuXG4gIGNvbnN0IGlucHV0QWJvdmUgPSBkaXJlY3Rpb24gIT09ICd1cCdcbiAgcmV0dXJuIChcbiAgICA8UGFuZSBjb2xvcj1cInBlcm1pc3Npb25cIj5cbiAgICAgIDxCb3hcbiAgICAgICAgZmxleERpcmVjdGlvbj1cImNvbHVtblwiXG4gICAgICAgIGdhcD17MX1cbiAgICAgICAgdGFiSW5kZXg9ezB9XG4gICAgICAgIGF1dG9Gb2N1c1xuICAgICAgICBvbktleURvd249e2hhbmRsZUtleURvd259XG4gICAgICA+XG4gICAgICAgIDxUZXh0IGJvbGQgY29sb3I9XCJwZXJtaXNzaW9uXCI+XG4gICAgICAgICAge3RpdGxlfVxuICAgICAgICA8L1RleHQ+XG4gICAgICAgIHtpbnB1dEFib3ZlICYmIHNlYXJjaEJveH1cbiAgICAgICAge2xpc3RHcm91cH1cbiAgICAgICAgeyFpbnB1dEFib3ZlICYmIHNlYXJjaEJveH1cbiAgICAgICAgPFRleHQgZGltQ29sb3I+XG4gICAgICAgICAgPEJ5bGluZT5cbiAgICAgICAgICAgIDxLZXlib2FyZFNob3J0Y3V0SGludFxuICAgICAgICAgICAgICBzaG9ydGN1dD1cIuKGkS/ihpNcIlxuICAgICAgICAgICAgICBhY3Rpb249e2NvbXBhY3QgPyAnbmF2JyA6ICduYXZpZ2F0ZSd9XG4gICAgICAgICAgICAvPlxuICAgICAgICAgICAgPEtleWJvYXJkU2hvcnRjdXRIaW50XG4gICAgICAgICAgICAgIHNob3J0Y3V0PVwiRW50ZXJcIlxuICAgICAgICAgICAgICBhY3Rpb249e2NvbXBhY3QgPyBmaXJzdFdvcmQoc2VsZWN0QWN0aW9uKSA6IHNlbGVjdEFjdGlvbn1cbiAgICAgICAgICAgIC8+XG4gICAgICAgICAgICB7b25UYWIgJiYgKFxuICAgICAgICAgICAgICA8S2V5Ym9hcmRTaG9ydGN1dEhpbnQgc2hvcnRjdXQ9XCJUYWJcIiBhY3Rpb249e29uVGFiLmFjdGlvbn0gLz5cbiAgICAgICAgICAgICl9XG4gICAgICAgICAgICB7b25TaGlmdFRhYiAmJiAhY29tcGFjdCAmJiAoXG4gICAgICAgICAgICAgIDxLZXlib2FyZFNob3J0Y3V0SGludFxuICAgICAgICAgICAgICAgIHNob3J0Y3V0PVwic2hpZnQrdGFiXCJcbiAgICAgICAgICAgICAgICBhY3Rpb249e29uU2hpZnRUYWIuYWN0aW9ufVxuICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICAgIDxLZXlib2FyZFNob3J0Y3V0SGludCBzaG9ydGN1dD1cIkVzY1wiIGFjdGlvbj1cImNhbmNlbFwiIC8+XG4gICAgICAgICAgICB7ZXh0cmFIaW50c31cbiAgICAgICAgICA8L0J5bGluZT5cbiAgICAgICAgPC9UZXh0PlxuICAgICAgPC9Cb3g+XG4gICAgPC9QYW5lPlxuICApXG59XG5cbnR5cGUgTGlzdFByb3BzPFQ+ID0gUGljazxcbiAgUHJvcHM8VD4sXG4gICd2aXNpYmxlQ291bnQnIHwgJ2RpcmVjdGlvbicgfCAnZ2V0S2V5JyB8ICdyZW5kZXJJdGVtJ1xuPiAmIHtcbiAgdmlzaWJsZTogcmVhZG9ubHkgVFtdXG4gIHdpbmRvd1N0YXJ0OiBudW1iZXJcbiAgdG90YWw6IG51bWJlclxuICBmb2N1c2VkSW5kZXg6IG51bWJlclxuICBlbXB0eVRleHQ6IHN0cmluZ1xufVxuXG5mdW5jdGlvbiBMaXN0PFQ+KHtcbiAgdmlzaWJsZSxcbiAgd2luZG93U3RhcnQsXG4gIHZpc2libGVDb3VudCxcbiAgdG90YWwsXG4gIGZvY3VzZWRJbmRleCxcbiAgZGlyZWN0aW9uLFxuICBnZXRLZXksXG4gIHJlbmRlckl0ZW0sXG4gIGVtcHR5VGV4dCxcbn06IExpc3RQcm9wczxUPik6IFJlYWN0LlJlYWN0Tm9kZSB7XG4gIGlmICh2aXNpYmxlLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiAoXG4gICAgICA8Qm94IGhlaWdodD17dmlzaWJsZUNvdW50fSBmbGV4U2hyaW5rPXswfT5cbiAgICAgICAgPFRleHQgZGltQ29sb3I+e2VtcHR5VGV4dH08L1RleHQ+XG4gICAgICA8L0JveD5cbiAgICApXG4gIH1cblxuICBjb25zdCByb3dzID0gdmlzaWJsZS5tYXAoKGl0ZW0sIGkpID0+IHtcbiAgICBjb25zdCBhY3R1YWxJbmRleCA9IHdpbmRvd1N0YXJ0ICsgaVxuICAgIGNvbnN0IGlzRm9jdXNlZCA9IGFjdHVhbEluZGV4ID09PSBmb2N1c2VkSW5kZXhcbiAgICBjb25zdCBhdExvd0VkZ2UgPSBpID09PSAwICYmIHdpbmRvd1N0YXJ0ID4gMFxuICAgIGNvbnN0IGF0SGlnaEVkZ2UgPVxuICAgICAgaSA9PT0gdmlzaWJsZS5sZW5ndGggLSAxICYmIHdpbmRvd1N0YXJ0ICsgdmlzaWJsZUNvdW50ISA8IHRvdGFsXG4gICAgcmV0dXJuIChcbiAgICAgIDxMaXN0SXRlbVxuICAgICAgICBrZXk9e2dldEtleShpdGVtKX1cbiAgICAgICAgaXNGb2N1c2VkPXtpc0ZvY3VzZWR9XG4gICAgICAgIHNob3dTY3JvbGxVcD17ZGlyZWN0aW9uID09PSAndXAnID8gYXRIaWdoRWRnZSA6IGF0TG93RWRnZX1cbiAgICAgICAgc2hvd1Njcm9sbERvd249e2RpcmVjdGlvbiA9PT0gJ3VwJyA/IGF0TG93RWRnZSA6IGF0SGlnaEVkZ2V9XG4gICAgICAgIHN0eWxlZD17ZmFsc2V9XG4gICAgICA+XG4gICAgICAgIHtyZW5kZXJJdGVtKGl0ZW0sIGlzRm9jdXNlZCl9XG4gICAgICA8L0xpc3RJdGVtPlxuICAgIClcbiAgfSlcblxuICByZXR1cm4gKFxuICAgIDxCb3hcbiAgICAgIGhlaWdodD17dmlzaWJsZUNvdW50fVxuICAgICAgZmxleFNocmluaz17MH1cbiAgICAgIGZsZXhEaXJlY3Rpb249e2RpcmVjdGlvbiA9PT0gJ3VwJyA/ICdjb2x1bW4tcmV2ZXJzZScgOiAnY29sdW1uJ31cbiAgICA+XG4gICAgICB7cm93c31cbiAgICA8L0JveD5cbiAgKVxufVxuXG5mdW5jdGlvbiBmaXJzdFdvcmQoczogc3RyaW5nKTogc3RyaW5nIHtcbiAgY29uc3QgaSA9IHMuaW5kZXhPZignICcpXG4gIHJldHVybiBpID09PSAtMSA/IHMgOiBzLnNsaWNlKDAsIGkpXG59XG4iXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEtBQUtBLEtBQUssTUFBTSxPQUFPO0FBQzlCLFNBQVNDLFNBQVMsRUFBRUMsUUFBUSxRQUFRLE9BQU87QUFDM0MsU0FBU0MsY0FBYyxRQUFRLCtCQUErQjtBQUM5RCxTQUFTQyxlQUFlLFFBQVEsZ0NBQWdDO0FBQ2hFLGNBQWNDLGFBQWEsUUFBUSxvQ0FBb0M7QUFDdkUsU0FBU0MsS0FBSyxRQUFRLDhCQUE4QjtBQUNwRCxTQUFTQyxHQUFHLEVBQUVDLElBQUksRUFBRUMsZ0JBQWdCLFFBQVEsY0FBYztBQUMxRCxTQUFTQyxTQUFTLFFBQVEsaUJBQWlCO0FBQzNDLFNBQVNDLE1BQU0sUUFBUSxhQUFhO0FBQ3BDLFNBQVNDLG9CQUFvQixRQUFRLDJCQUEyQjtBQUNoRSxTQUFTQyxRQUFRLFFBQVEsZUFBZTtBQUN4QyxTQUFTQyxJQUFJLFFBQVEsV0FBVztBQUVoQyxLQUFLQyxZQUFZLENBQUMsQ0FBQyxDQUFDLEdBQUc7RUFDckI7RUFDQUMsTUFBTSxFQUFFLE1BQU07RUFDZEMsT0FBTyxFQUFFLENBQUNDLElBQUksRUFBRUMsQ0FBQyxFQUFFLEdBQUcsSUFBSTtBQUM1QixDQUFDO0FBRUQsS0FBS0MsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHO0VBQ2RDLEtBQUssRUFBRSxNQUFNO0VBQ2JDLFdBQVcsQ0FBQyxFQUFFLE1BQU07RUFDcEJDLFlBQVksQ0FBQyxFQUFFLE1BQU07RUFDckJDLEtBQUssRUFBRSxTQUFTTCxDQUFDLEVBQUU7RUFDbkJNLE1BQU0sRUFBRSxDQUFDUCxJQUFJLEVBQUVDLENBQUMsRUFBRSxHQUFHLE1BQU07RUFDM0I7RUFDQU8sVUFBVSxFQUFFLENBQUNSLElBQUksRUFBRUMsQ0FBQyxFQUFFUSxTQUFTLEVBQUUsT0FBTyxFQUFFLEdBQUczQixLQUFLLENBQUM0QixTQUFTO0VBQzVEQyxhQUFhLENBQUMsRUFBRSxDQUFD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 |