AppState.tsx
state/AppState.tsx
No strong subsystem tag
200
Lines
23480
Bytes
13
Exports
12
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 general runtime concerns. It contains 200 lines, 12 detected imports, and 13 detected exports.
Important relationships
Detected exports
AppStoreContextAppStateProvideruseAppStateuseSetAppStateuseAppStateStoreuseAppStateMaybeOutsideOfProvidertype AppStatetype AppStateStoretype CompletionBoundarygetDefaultAppStateIDLE_SPECULATION_STATEtype SpeculationResulttype SpeculationState
Keywords
storeselectorreactchildrenelseappstatestoreuseappstateappstatehasappstatecontextappstateprovider
Detected imports
react/compiler-runtimebun:bundlereact../context/mailbox.js../hooks/useSettingsChange.js../utils/debug.js../utils/permissions/permissionSetup.js../utils/settings/applySettingsChange.js../utils/settings/constants.js./store.js./AppStateStore.js./AppStateStore.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 { c as _c } from "react/compiler-runtime";
import { feature } from 'bun:bundle';
import React, { useContext, useEffect, useEffectEvent, useState, useSyncExternalStore } from 'react';
import { MailboxProvider } from '../context/mailbox.js';
import { useSettingsChange } from '../hooks/useSettingsChange.js';
import { logForDebugging } from '../utils/debug.js';
import { createDisabledBypassPermissionsContext, isBypassPermissionsModeDisabled } from '../utils/permissions/permissionSetup.js';
import { applySettingsChange } from '../utils/settings/applySettingsChange.js';
import type { SettingSource } from '../utils/settings/constants.js';
import { createStore } from './store.js';
// DCE: voice context is ant-only. External builds get a passthrough.
/* eslint-disable @typescript-eslint/no-require-imports */
const VoiceProvider: (props: {
children: React.ReactNode;
}) => React.ReactNode = feature('VOICE_MODE') ? require('../context/voice.js').VoiceProvider : ({
children
}) => children;
/* eslint-enable @typescript-eslint/no-require-imports */
import { type AppState, type AppStateStore, getDefaultAppState } from './AppStateStore.js';
// TODO: Remove these re-exports once all callers import directly from
// ./AppStateStore.js. Kept for back-compat during migration so .ts callers
// can incrementally move off the .tsx import and stop pulling React.
export { type AppState, type AppStateStore, type CompletionBoundary, getDefaultAppState, IDLE_SPECULATION_STATE, type SpeculationResult, type SpeculationState } from './AppStateStore.js';
export const AppStoreContext = React.createContext<AppStateStore | null>(null);
type Props = {
children: React.ReactNode;
initialState?: AppState;
onChangeAppState?: (args: {
newState: AppState;
oldState: AppState;
}) => void;
};
const HasAppStateContext = React.createContext<boolean>(false);
export function AppStateProvider(t0) {
const $ = _c(13);
const {
children,
initialState,
onChangeAppState
} = t0;
const hasAppStateContext = useContext(HasAppStateContext);
if (hasAppStateContext) {
throw new Error("AppStateProvider can not be nested within another AppStateProvider");
}
let t1;
if ($[0] !== initialState || $[1] !== onChangeAppState) {
t1 = () => createStore(initialState ?? getDefaultAppState(), onChangeAppState);
$[0] = initialState;
$[1] = onChangeAppState;
$[2] = t1;
} else {
t1 = $[2];
}
const [store] = useState(t1);
let t2;
if ($[3] !== store) {
t2 = () => {
const {
toolPermissionContext
} = store.getState();
if (toolPermissionContext.isBypassPermissionsModeAvailable && isBypassPermissionsModeDisabled()) {
logForDebugging("Disabling bypass permissions mode on mount (remote settings loaded before mount)");
store.setState(_temp);
}
};
$[3] = store;
$[4] = t2;
} else {
t2 = $[4];
}
let t3;
if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
t3 = [];
$[5] = t3;
} else {
t3 = $[5];
}
useEffect(t2, t3);
let t4;
if ($[6] !== store.setState) {
t4 = source => applySettingsChange(source, store.setState);
$[6] = store.setState;
$[7] = t4;
} else {
t4 = $[7];
}
const onSettingsChange = useEffectEvent(t4);
useSettingsChange(onSettingsChange);
let t5;
if ($[8] !== children) {
t5 = <MailboxProvider><VoiceProvider>{children}</VoiceProvider></MailboxProvider>;
$[8] = children;
$[9] = t5;
} else {
t5 = $[9];
}
let t6;
if ($[10] !== store || $[11] !== t5) {
t6 = <HasAppStateContext.Provider value={true}><AppStoreContext.Provider value={store}>{t5}</AppStoreContext.Provider></HasAppStateContext.Provider>;
$[10] = store;
$[11] = t5;
$[12] = t6;
} else {
t6 = $[12];
}
return t6;
}
function _temp(prev) {
return {
...prev,
toolPermissionContext: createDisabledBypassPermissionsContext(prev.toolPermissionContext)
};
}
function useAppStore(): AppStateStore {
// eslint-disable-next-line react-hooks/rules-of-hooks
const store = useContext(AppStoreContext);
if (!store) {
throw new ReferenceError('useAppState/useSetAppState cannot be called outside of an <AppStateProvider />');
}
return store;
}
/**
* Subscribe to a slice of AppState. Only re-renders when the selected value
* changes (compared via Object.is).
*
* For multiple independent fields, call the hook multiple times:
* ```
* const verbose = useAppState(s => s.verbose)
* const model = useAppState(s => s.mainLoopModel)
* ```
*
* Do NOT return new objects from the selector -- Object.is will always see
* them as changed. Instead, select an existing sub-object reference:
* ```
* const { text, promptId } = useAppState(s => s.promptSuggestion) // good
* ```
*/
export function useAppState(selector) {
const $ = _c(3);
const store = useAppStore();
let t0;
if ($[0] !== selector || $[1] !== store) {
t0 = () => {
const state = store.getState();
const selected = selector(state);
if (false && state === selected) {
throw new Error(`Your selector in \`useAppState(${selector.toString()})\` returned the original state, which is not allowed. You must instead return a property for optimised rendering.`);
}
return selected;
};
$[0] = selector;
$[1] = store;
$[2] = t0;
} else {
t0 = $[2];
}
const get = t0;
return useSyncExternalStore(store.subscribe, get, get);
}
/**
* Get the setAppState updater without subscribing to any state.
* Returns a stable reference that never changes -- components using only
* this hook will never re-render from state changes.
*/
export function useSetAppState() {
return useAppStore().setState;
}
/**
* Get the store directly (for passing getState/setState to non-React code).
*/
export function useAppStateStore() {
return useAppStore();
}
const NOOP_SUBSCRIBE = () => () => {};
/**
* Safe version of useAppState that returns undefined if called outside of AppStateProvider.
* Useful for components that may be rendered in contexts where AppStateProvider isn't available.
*/
export function useAppStateMaybeOutsideOfProvider(selector) {
const $ = _c(3);
const store = useContext(AppStoreContext);
let t0;
if ($[0] !== selector || $[1] !== store) {
t0 = () => store ? selector(store.getState()) : undefined;
$[0] = selector;
$[1] = store;
$[2] = t0;
} else {
t0 = $[2];
}
return useSyncExternalStore(store ? store.subscribe : NOOP_SUBSCRIBE, t0);
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJmZWF0dXJlIiwiUmVhY3QiLCJ1c2VDb250ZXh0IiwidXNlRWZmZWN0IiwidXNlRWZmZWN0RXZlbnQiLCJ1c2VTdGF0ZSIsInVzZVN5bmNFeHRlcm5hbFN0b3JlIiwiTWFpbGJveFByb3ZpZGVyIiwidXNlU2V0dGluZ3NDaGFuZ2UiLCJsb2dGb3JEZWJ1Z2dpbmciLCJjcmVhdGVEaXNhYmxlZEJ5cGFzc1Blcm1pc3Npb25zQ29udGV4dCIsImlzQnlwYXNzUGVybWlzc2lvbnNNb2RlRGlzYWJsZWQiLCJhcHBseVNldHRpbmdzQ2hhbmdlIiwiU2V0dGluZ1NvdXJjZSIsImNyZWF0ZVN0b3JlIiwiVm9pY2VQcm92aWRlciIsInByb3BzIiwiY2hpbGRyZW4iLCJSZWFjdE5vZGUiLCJyZXF1aXJlIiwiQXBwU3RhdGUiLCJBcHBTdGF0ZVN0b3JlIiwiZ2V0RGVmYXVsdEFwcFN0YXRlIiwiQ29tcGxldGlvbkJvdW5kYXJ5IiwiSURMRV9TUEVDVUxBVElPTl9TVEFURSIsIlNwZWN1bGF0aW9uUmVzdWx0IiwiU3BlY3VsYXRpb25TdGF0ZSIsIkFwcFN0b3JlQ29udGV4dCIsImNyZWF0ZUNvbnRleHQiLCJQcm9wcyIsImluaXRpYWxTdGF0ZSIsIm9uQ2hhbmdlQXBwU3RhdGUiLCJhcmdzIiwibmV3U3RhdGUiLCJvbGRTdGF0ZSIsIkhhc0FwcFN0YXRlQ29udGV4dCIsIkFwcFN0YXRlUHJvdmlkZXIiLCJ0MCIsIiQiLCJfYyIsImhhc0FwcFN0YXRlQ29udGV4dCIsIkVycm9yIiwidDEiLCJzdG9yZSIsInQyIiwidG9vbFBlcm1pc3Npb25Db250ZXh0IiwiZ2V0U3RhdGUiLCJpc0J5cGFzc1Blcm1pc3Npb25zTW9kZUF2YWlsYWJsZSIsInNldFN0YXRlIiwiX3RlbXAiLCJ0MyIsIlN5bWJvbCIsImZvciIsInQ0Iiwic291cmNlIiwib25TZXR0aW5nc0NoYW5nZSIsInQ1IiwidDYiLCJwcmV2IiwidXNlQXBwU3RvcmUiLCJSZWZlcmVuY2VFcnJvciIsInVzZUFwcFN0YXRlIiwic2VsZWN0b3IiLCJzdGF0ZSIsInNlbGVjdGVkIiwidG9TdHJpbmciLCJnZXQiLCJzdWJzY3JpYmUiLCJ1c2VTZXRBcHBTdGF0ZSIsInVzZUFwcFN0YXRlU3RvcmUiLCJOT09QX1NVQlNDUklCRSIsInVzZUFwcFN0YXRlTWF5YmVPdXRzaWRlT2ZQcm92aWRlciIsInVuZGVmaW5lZCJdLCJzb3VyY2VzIjpbIkFwcFN0YXRlLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBmZWF0dXJlIH0gZnJvbSAnYnVuOmJ1bmRsZSdcbmltcG9ydCBSZWFjdCwge1xuICB1c2VDb250ZXh0LFxuICB1c2VFZmZlY3QsXG4gIHVzZUVmZmVjdEV2ZW50LFxuICB1c2VTdGF0ZSxcbiAgdXNlU3luY0V4dGVybmFsU3RvcmUsXG59IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHsgTWFpbGJveFByb3ZpZGVyIH0gZnJvbSAnLi4vY29udGV4dC9tYWlsYm94LmpzJ1xuaW1wb3J0IHsgdXNlU2V0dGluZ3NDaGFuZ2UgfSBmcm9tICcuLi9ob29rcy91c2VTZXR0aW5nc0NoYW5nZS5qcydcbmltcG9ydCB7IGxvZ0ZvckRlYnVnZ2luZyB9IGZyb20gJy4uL3V0aWxzL2RlYnVnLmpzJ1xuaW1wb3J0IHtcbiAgY3JlYXRlRGlzYWJsZWRCeXBhc3NQZXJtaXNzaW9uc0NvbnRleHQsXG4gIGlzQnlwYXNzUGVybWlzc2lvbnNNb2RlRGlzYWJsZWQsXG59IGZyb20gJy4uL3V0aWxzL3Blcm1pc3Npb25zL3Blcm1pc3Npb25TZXR1cC5qcydcbmltcG9ydCB7IGFwcGx5U2V0dGluZ3NDaGFuZ2UgfSBmcm9tICcuLi91dGlscy9zZXR0aW5ncy9hcHBseVNldHRpbmdzQ2hhbmdlLmpzJ1xuaW1wb3J0IHR5cGUgeyBTZXR0aW5nU291cmNlIH0gZnJvbSAnLi4vdXRpbHMvc2V0dGluZ3MvY29uc3RhbnRzLmpzJ1xuaW1wb3J0IHsgY3JlYXRlU3RvcmUgfSBmcm9tICcuL3N0b3JlLmpzJ1xuXG4vLyBEQ0U6IHZvaWNlIGNvbnRleHQgaXMgYW50LW9ubHkuIEV4dGVybmFsIGJ1aWxkcyBnZXQgYSBwYXNzdGhyb3VnaC5cbi8qIGVzbGludC1kaXNhYmxlIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHMgKi9cbmNvbnN0IFZvaWNlUHJvdmlkZXI6IChwcm9wczogeyBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlIH0pID0+IFJlYWN0LlJlYWN0Tm9kZSA9XG4gIGZlYXR1cmUoJ1ZPSUNFX01PREUnKVxuICAgID8gcmVxdWlyZSgnLi4vY29udGV4dC92b2ljZS5qcycpLlZvaWNlUHJvdmlkZXJcbiAgICA6ICh7IGNoaWxkcmVuIH0pID0+IGNoaWxkcmVuXG5cbi8qIGVzbGludC1lbmFibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXJlcXVpcmUtaW1wb3J0cyAqL1xuaW1wb3J0IHtcbiAgdHlwZSBBcHBTdGF0ZSxcbiAgdHlwZSBBcHBTdGF0ZVN0b3JlLFxuICBnZXREZWZhdWx0QXBwU3RhdGUsXG59IGZyb20gJy4vQXBwU3RhdGVTdG9yZS5qcydcblxuLy8gVE9ETzogUmVtb3ZlIHRoZXNlIHJlLWV4cG9ydHMgb25jZSBhbGwgY2FsbGVycyBpbXBvcnQgZGlyZWN0bHkgZnJvbVxuLy8gLi9BcHBTdGF0ZVN0b3JlLmpzLiBLZXB0IGZvciBiYWNrLWNvbXBhdCBkdXJpbmcgbWlncmF0aW9uIHNvIC50cyBjYWxsZXJzXG4vLyBjYW4gaW5jcmVtZW50YWxseSBtb3ZlIG9mZiB0aGUgLnRzeCBpbXBvcnQgYW5kIHN0b3AgcHVsbGluZyBSZWFjdC5cbmV4cG9ydCB7XG4gIHR5cGUgQXBwU3RhdGUsXG4gIHR5cGUgQXBwU3RhdGVTdG9yZSxcbiAgdHlwZSBDb21wbGV0aW9uQm91bmRhcnksXG4gIGdldERlZmF1bHRBcHBTdGF0ZSxcbiAgSURMRV9TUEVDVUxBVElPTl9TVEFURSxcbiAgdHlwZSBTcGVjdWxhdGlvblJlc3VsdCxcbiAgdHlwZSBTcGVjdWxhdGlvblN0YXRlLFxufSBmcm9tICcuL0FwcFN0YXRlU3RvcmUuanMnXG5cbmV4cG9ydCBjb25zdCBBcHBTdG9yZUNvbnRleHQgPSBSZWFjdC5jcmVhdGVDb250ZXh0PEFwcFN0YXRlU3RvcmUgfCBudWxsPihudWxsKVxuXG50eXBlIFByb3BzID0ge1xuICBjaGlsZHJlbjogUmVhY3QuUmVhY3ROb2RlXG4gIGluaXRpYWxTdGF0ZT86IEFwcFN0YXRlXG4gIG9uQ2hhbmdlQXBwU3RhdGU/OiAoYXJnczogeyBuZXdTdGF0ZTogQXBwU3RhdGU7IG9sZFN0YXRlOiBBcHBTdGF0ZSB9KSA9PiB2b2lkXG59XG5cbmNvbnN0IEhhc0FwcFN0YXRlQ29udGV4dCA9IFJlYWN0LmNyZWF0ZUNvbnRleHQ8Ym9vbGVhbj4oZmFsc2UpXG5cbmV4cG9ydCBmdW5jdGlvbiBBcHBTdGF0ZVByb3ZpZGVyKHtcbiAgY2hpbGRyZW4sXG4gIGluaXRpYWxTdGF0ZSxcbiAgb25DaGFuZ2VBcHBTdGF0ZSxcbn06IFByb3BzKTogUmVhY3QuUmVhY3ROb2RlIHtcbiAgLy8gRG9uJ3QgYWxsb3cgbmVzdGVkIEFwcFN0YXRlUHJvdmlkZXJzLlxuICBjb25zdCBoYXNBcHBTdGF0ZUNvbnRleHQgPSB1c2VDb250ZXh0KEhhc0FwcFN0YXRlQ29udGV4dClcbiAgaWYgKGhhc0FwcFN0YXRlQ29udGV4dCkge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdBcHBTdGF0ZVByb3ZpZGVyIGNhbiBub3QgYmUgbmVzdGVkIHdpdGhpbiBhbm90aGVyIEFwcFN0YXRlUHJvdmlkZXInLFxuICAgIClcbiAgfVxuXG4gIC8vIFN0b3JlIGlzIGNyZWF0ZWQgb25jZSBhbmQgbmV2ZXIgY2hhbmdlcyAtLSBzdGFibGUgY29udGV4dCB2YWx1ZSBtZWFuc1xuICAvLyB0aGUgcHJvdmlkZXIgbmV2ZXIgdHJpZ2dlcnMgcmUtcmVuZGVycy4gQ29uc3VtZXJzIHN1YnNjcmliZSB0byBzbGljZXNcbiAgLy8gdmlhIHVzZVN5bmNFeHRlcm5hbFN0b3JlIGluIHVzZUFwcFN0YXRlKHNlbGVjdG9yKS5cbiAgY29uc3QgW3N0b3JlXSA9IHVzZVN0YXRlKCgpID0+XG4gICAgY3JlYXRlU3RvcmU8QXBwU3RhdGU+KFxuICAgICAgaW5pdGlhbFN0YXRlID8/IGdldERlZmF1bHRBcHBTdGF0ZSgpLFxuICAgICAgb25DaGFuZ2VBcHBTdGF0ZSxcbiAgICApLFxuICApXG5cbiAgLy8gQ2hlY2sgb24gbW91bnQgaWYgYnlwYXNzIG1vZGUgc2hvdWxkIGJlIGRpc2FibGVkXG4gIC8vIFRoaXMgaGFuZGxlcyB0aGUgcmFjZSBjb25kaXRpb24gd2hlcmUgcmVtb3RlIHNldHRpbmdzIGxvYWQgQkVGT1JFIHRoaXMgY29tcG9uZW50IG1vdW50cyxcbiAgLy8gbWVhbmluZyB0aGUgc2V0dGluZ3MgY2hhbmdlIG5vdGlmaWNhdGlvbiB3YXMgc2VudCB3aGVuIG5vIGxpc3RlbmVycyB3ZXJlIHN1YnNjcmliZWQuXG4gIC8vIE9uIHN1YnNlcXVlbnQgc2Vzc2lvbnMsIHRoZSBjYWNoZWQgcmVtb3RlLXNldHRpbmdzLmpzb24gaXMgcmVhZCBkdXJpbmcgaW5pdGlhbCBzZXR1cCxcbiAgLy8gYnV0IG9uIHRoZSBmaXJzdCBzZXNzaW9uIHRoZSByZW1vdGUgZmV0Y2ggbWF5IGNvbXBsZXRlIGJlZm9yZSBSZWFjdCBtb3VudHMuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgeyB0b29sUGVybWlzc2lvbkNvbnRleHQgfSA9IHN0b3JlLmdldFN0YXRlKClcbiAgICBpZiAoXG4gICAgICB0b29sUGVybWlzc2lvbkNvbnRleHQuaXNCeXBhc3NQZXJtaXNzaW9uc01vZGVBdmFpbGFibGUgJiZcbiAgICAgIGlzQnlwYXNzUGVybWlzc2lvbnNNb2RlRGlzYWJsZWQoKVxuICAgICkge1xuICAgICAgbG9nRm9yRGVidWdnaW5nKFxuICAgICAgICAnRGlzYWJsaW5nIGJ5cGFzcyBwZXJtaXNzaW9ucyBtb2RlIG9uIG1vdW50IChyZW1vdGUgc2V0dGluZ3MgbG9hZGVkIGJlZm9yZSBtb3VudCknLFxuICAgICAgKVxuICAgICAgc3RvcmUuc2V0U3RhdGUocHJldiA9PiAoe1xuICAgICAgICAuLi5wcmV2LFxuICAgICAgICB0b29sUGVybWlzc2lvbkNvbnRleHQ6IGNyZWF0ZURpc2FibGVkQnlwYXNzUGVybWlzc2lvbnNDb250ZXh0KFxuICAgICAgICAgIHByZXYudG9vbFBlcm1pc3Npb25Db250ZXh0LFxuICAgICAgICApLFxuICAgICAgfSkpXG4gICAgfVxuICAgIC8vIGJpb21lLWlnbm9yZSBsaW50L2NvcnJlY3RuZXNzL3VzZUV4aGF1c3RpdmVEZXBlbmRlbmNpZXM6IGludGVudGlvbmFsIG1vdW50LW9ubHkgZWZmZWN0XG4gIH0sIFtdKVxuXG4gIC8vIExpc3RlbiBmb3IgZXh0ZXJuYWwgc2V0dGluZ3MgY2hhbmdlcyBhbmQgc3luYyB0byBBcHBTdGF0ZS5cbiAgLy8gVGhpcyBlbnN1cmVzIGZpbGUgd2F0Y2hlciBjaGFuZ2VzIHByb3BhZ2F0ZSB0aHJvdWdoIHRoZSBhcHAgLS1cbiAgLy8gc2hhcmVkIHdpdGggdGhlIGhlYWRsZXNzL1NESyBwYXRoIHZpYSBhcHBseVNldHRpbmdzQ2hhbmdlLlxuICBjb25zdCBvblNldHRpbmdzQ2hhbmdlID0gdXNlRWZmZWN0RXZlbnQoKHNvdXJjZTogU2V0dGluZ1NvdXJjZSkgPT5cbiAgICBhcHBseVNldHRpbmdzQ2hhbmdlKHNvdXJjZSwgc3RvcmUuc2V0U3RhdGUpLFxuICApXG4gIHVzZVNldHRpbmdzQ2hhbmdlKG9uU2V0dGluZ3NDaGFuZ2UpXG5cbiAgcmV0dXJuIChcbiAgICA8SGFzQXBwU3RhdGVDb250ZXh0LlByb3ZpZGVyIHZhbHVlPXt0cnVlfT5cbiAgICAgIDxBcHBTdG9yZUNvbnRleHQuUHJvdmlkZXIgdmFsdWU9e3N0b3JlfT5cbiAgICAgICAgPE1haWxib3hQcm92aWRlcj5cbiAgICAgICAgICA8Vm9pY2VQcm92aWRlcj57Y2hpbGRyZW59PC9Wb2ljZVByb3ZpZGVyPlxuICAgICAgICA8L01haWxib3hQcm92aWRlcj5cbiAgICAgIDwvQXBwU3RvcmVDb250ZXh0LlByb3ZpZGVyPlxuICAgIDwvSGFzQXBwU3RhdGVDb250ZXh0LlByb3ZpZGVyPlxuICApXG59XG5cbmZ1bmN0aW9uIHVzZUFwcFN0b3JlKCk6IEFwcFN0YXRlU3RvcmUge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgcmVhY3QtaG9va3MvcnVsZXMtb2YtaG9va3NcbiAgY29uc3Qgc3RvcmUgPSB1c2VDb250ZXh0KEFwcFN0b3JlQ29udGV4dClcbiAgaWYgKCFzdG9yZSkge1xuICAgIHRocm93IG5ldyBSZWZlcmVuY2VFcnJvcihcbiAgICAgICd1c2VBcHBTdGF0ZS91c2VTZXRBcHBTdGF0ZSBjYW5ub3QgYmUgY2FsbGVkIG91dHNpZGUgb2YgYW4gPEFwcFN0YXRlUHJvdmlkZXIgLz4nLFxuICAgIClcbiAgfVxuICByZXR1cm4gc3RvcmVcbn1cblxuLyoqXG4gKiBTdWJzY3JpYmUgdG8gYSBzbGljZSBvZiBBcHBTdGF0ZS4gT25seSByZS1yZW5kZXJzIHdoZW4gdGhlIHNlbGVjdGVkIHZhbHVlXG4gKiBjaGFuZ2VzIChjb21wYXJlZCB2aWEgT2JqZWN0LmlzKS5cbiAqXG4gKiBGb3IgbXVsdGlwbGUgaW5kZXBlbmRlbnQgZmllbGRzLCBjYWxsIHRoZSBob29rIG11bHRpcGxlIHRpbWVzOlxuICogYGBgXG4gKiBjb25zdCB2ZXJib3NlID0gdXNlQXBwU3RhdGUocyA9PiBzLnZlcmJvc2UpXG4gKiBjb25zdCBtb2RlbCA9IHVzZUFwcFN0YXRlKHMgPT4gcy5tYWluTG9vcE1vZGVsKVxuICogYGBgXG4gKlxuICogRG8gTk9UIHJldHVybiBuZXcgb2JqZWN0cyBmcm9tIHRoZSBzZWxlY3RvciAtLSBPYmplY3QuaXMgd2lsbCBhbHdheXMgc2VlXG4gKiB0aGVtIGFzIGNoYW5nZWQuIEluc3RlYWQsIHNlbGVjdCBhbiBleGlzdGluZyBzdWItb2JqZWN0IHJlZmVyZW5jZTpcbiAqIGBgYFxuICogY29uc3QgeyB0ZXh0LCBwcm9tcHRJZCB9ID0gdXNlQXBwU3RhdGUocyA9PiBzLnByb21wdFN1Z2dlc3Rpb24pIC8vIGdvb2RcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlQXBwU3RhdGU8VD4oc2VsZWN0b3I6IChzdGF0ZTogQXBwU3RhdGUpID0+IFQpOiBUIHtcbiAgY29uc3Qgc3RvcmUgPSB1c2VBcHBTdG9yZSgpXG5cbiAgY29uc3QgZ2V0ID0gKCkgPT4ge1xuICAgIGNvbnN0IHN0YXRlID0gc3RvcmUuZ2V0U3RhdGUoKVxuICAgIGNvbnN0IHNlbGVjdGVkID0gc2VsZWN0b3Ioc3RhdGUpXG5cbiAgICBpZiAoXCJleHRlcm5hbFwiID09PSAnYW50JyAmJiBzdGF0ZSA9PT0gc2VsZWN0ZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYFlvdXIgc2VsZWN0b3IgaW4gXFxgdXNlQXBwU3RhdGUoJHtzZWxlY3Rvci50b1N0cmluZygpfSlcXGAgcmV0dXJuZWQgdGhlIG9yaWdpbmFsIHN0YXRlLCB3aGljaCBpcyBub3QgYWxsb3dlZC4gWW91IG11c3QgaW5zdGVhZCByZXR1cm4gYSBwcm9wZXJ0eSBmb3Igb3B0aW1pc2VkIHJlbmRlcmluZy5gLFxuICAgICAgKVxuICAgIH1cblxuICAgIHJldHVybiBzZWxlY3RlZFxuICB9XG5cbiAgcmV0dXJuIHVzZVN5bmNFeHRlcm5hbFN0b3JlKHN0b3JlLnN1YnNjcmliZSwgZ2V0LCBnZXQpXG59XG5cbi8qKlxuICogR2V0IHRoZSBzZXRBcHBTdGF0ZSB1cGRhdGVyIHdpdGhvdXQgc3Vic2NyaWJpbmcgdG8gYW55IHN0YXRlLlxuICogUmV0dXJucyBhIHN0YWJsZSByZWZlcmVuY2UgdGhhdCBuZXZlciBjaGFuZ2VzIC0tIGNvbXBvbmVudHMgdXNpbmcgb25seVxuICogdGhpcyBob29rIHdpbGwgbmV2ZXIgcmUtcmVuZGVyIGZyb20gc3RhdGUgY2hhbmdlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZVNldEFwcFN0YXRlKCk6IChcbiAgdXBkYXRlcjogKHByZXY6IEFwcFN0YXRlKSA9PiBBcHBTdGF0ZSxcbikgPT4gdm9pZCB7XG4gIHJldHVybiB1c2VBcHBTdG9yZSgpLnNldFN0YXRlXG59XG5cbi8qKlxuICogR2V0IHRoZSBzdG9yZSBkaXJlY3RseSAoZm9yIHBhc3NpbmcgZ2V0U3RhdGUvc2V0U3RhdGUgdG8gbm9uLVJlYWN0IGNvZGUpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlQXBwU3RhdGVTdG9yZSgpOiBBcHBTdGF0ZVN0b3JlIHtcbiAgcmV0dXJuIHVzZUFwcFN0b3JlKClcbn1cblxuY29uc3QgTk9PUF9TVUJTQ1JJQkUgPSAoKSA9PiAoKSA9PiB7fVxuXG4vKipcbiAqIFNhZmUgdmVyc2lvbiBvZiB1c2VBcHBTdGF0ZSB0aGF0IHJldHVybnMgdW5kZWZpbmVkIGlmIGNhbGxlZCBvdXRzaWRlIG9mIEFwcFN0YXRlUHJvdmlkZXIuXG4gKiBVc2VmdWwgZm9yIGNvbXBvbmVudHMgdGhhdCBtYXkgYmUgcmVuZGVyZWQgaW4gY29udGV4dHMgd2hlcmUgQXBwU3RhdGVQcm92aWRlciBpc24ndCBhdmFpbGFibGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VBcHBTdGF0ZU1heWJlT3V0c2lkZU9mUHJvdmlkZXI8VD4oXG4gIHNlbGVjdG9yOiAoc3RhdGU6IEFwcFN0YXRlKSA9PiBULFxuKTogVCB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IHN0b3JlID0gdXNlQ29udGV4dChBcHBTdG9yZUNvbnRleHQpXG4gIHJldHVybiB1c2VTeW5jRXh0ZXJuYWxTdG9yZShzdG9yZSA/IHN0b3JlLnN1YnNjcmliZSA6IE5PT1BfU1VCU0NSSUJFLCAoKSA9PlxuICAgIHN0b3JlID8gc2VsZWN0b3Ioc3RvcmUuZ2V0U3RhdGUoKSkgOiB1bmRlZmluZWQsXG4gIClcbn1cbiJdLCJtYXBwaW5ncyI6IjtBQUFBLFNBQVNBLE9BQU8sUUFBUSxZQUFZO0FBQ3BDLE9BQU9DLEtBQUssSUFDVkMsVUFBVSxFQUNWQyxTQUFTLEVBQ1RDLGNBQWMsRUFDZEMsUUFBUSxFQUNSQyxvQkFBb0IsUUFDZixPQUFPO0FBQ2QsU0FBU0MsZUFBZSxRQUFRLHVCQUF1QjtBQUN2RCxTQUFTQyxpQkFBaUIsUUFBUSwrQkFB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