import React, { useCallback, useEffect, useRef, useState } from 'react';
import { type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS, logEvent } from 'src/services/analytics/index.js';
import { KeyboardShortcutHint } from '../../components/design-system/KeyboardShortcutHint.js';
import { Spinner } from '../../components/Spinner.js';
import TextInput from '../../components/TextInput.js';
import { useTerminalSize } from '../../hooks/useTerminalSize.js';
import type { KeyboardEvent } from '../../ink/events/keyboard-event.js';
import { setClipboard } from '../../ink/termio/osc.js';
import { Box, Link, Text } from '../../ink.js';
import { OAuthService } from '../../services/oauth/index.js';
import { saveOAuthTokensIfNeeded } from '../../utils/auth.js';
import { logError } from '../../utils/log.js';
interface OAuthFlowStepProps {
  onSuccess: (token: string) => void;
  onCancel: () => void;
}
type OAuthStatus = {
  state: 'starting';
} | {
  state: 'waiting_for_login';
  url: string;
} | {
  state: 'processing';
} | {
  state: 'success';
  token: string;
} | {
  state: 'error';
  message: string;
  toRetry?: OAuthStatus;
} | {
  state: 'about_to_retry';
  nextState: OAuthStatus;
};
const PASTE_HERE_MSG = 'Paste code here if prompted > ';
export function OAuthFlowStep({
  onSuccess,
  onCancel
}: OAuthFlowStepProps): React.ReactNode {
  const [oauthStatus, setOAuthStatus] = useState<OAuthStatus>({
    state: 'starting'
  });
  const [oauthService] = useState(() => new OAuthService());
  const [pastedCode, setPastedCode] = useState('');
  const [cursorOffset, setCursorOffset] = useState(0);
  const [showPastePrompt, setShowPastePrompt] = useState(false);
  const [urlCopied, setUrlCopied] = useState(false);
  const timersRef = useRef<Set<NodeJS.Timeout>>(new Set());
  // Separate ref so startOAuth's timer clear doesn't cancel the urlCopied reset
  const urlCopiedTimerRef = useRef<NodeJS.Timeout | undefined>(undefined);
  const terminalSize = useTerminalSize();
  const textInputColumns = Math.max(50, terminalSize.columns - PASTE_HERE_MSG.length - 4);
  function handleKeyDown(e: KeyboardEvent): void {
    if (oauthStatus.state !== 'error') return;
    e.preventDefault();
    if (e.key === 'return' && oauthStatus.toRetry) {
      setPastedCode('');
      setCursorOffset(0);
      setOAuthStatus({
        state: 'about_to_retry',
        nextState: oauthStatus.toRetry
      });
    } else {
      onCancel();
    }
  }
  async function handleSubmitCode(value: string, url: string) {
    try {
      // Expecting format "authorizationCode#state" from the authorization callback URL
      const [authorizationCode, state] = value.split('#');
      if (!authorizationCode || !state) {
        setOAuthStatus({
          state: 'error',
          message: 'Invalid code. Please make sure the full code was copied',
          toRetry: {
            state: 'waiting_for_login',
            url
          }
        });
        return;
      }

      // Track which path the user is taking (manual code entry)
      logEvent('tengu_oauth_manual_entry', {});
      oauthService.handleManualAuthCodeInput({
        authorizationCode,
        state
      });
    } catch (err: unknown) {
      logError(err);
      setOAuthStatus({
        state: 'error',
        message: (err as Error).message,
        toRetry: {
          state: 'waiting_for_login',
          url
        }
      });
    }
  }
  const startOAuth = useCallback(async () => {
    // Clear any existing timers when starting new OAuth flow
    timersRef.current.forEach(timer => clearTimeout(timer));
    timersRef.current.clear();
    try {
      const result = await oauthService.startOAuthFlow(async url_0 => {
        setOAuthStatus({
          state: 'waiting_for_login',
          url: url_0
        });
        const timer_0 = setTimeout(setShowPastePrompt, 3000, true);
        timersRef.current.add(timer_0);
      }, {
        loginWithClaudeAi: true,
        // Always use Claude AI for subscription tokens
        inferenceOnly: true,
        expiresIn: 365 * 24 * 60 * 60 // 1 year
      });

      // Show processing state
      setOAuthStatus({
        state: 'processing'
      });

      // OAuthFlowStep creates inference-only tokens for GitHub Actions, not a
      // replacement login. Use saveOAuthTokensIfNeeded directly to avoid
      // performLogout which would destroy the user's existing auth session.
      saveOAuthTokensIfNeeded(result);

      // For OAuth flow, the access token can be used as an API key
      const timer1 = setTimeout((setOAuthStatus_0, accessToken, onSuccess_0, timersRef_0) => {
        setOAuthStatus_0({
          state: 'success',
          token: accessToken
        });
        // Auto-continue after brief delay to show success
        const timer2 = setTimeout(onSuccess_0, 1000, accessToken);
        timersRef_0.current.add(timer2);
      }, 100, setOAuthStatus, result.accessToken, onSuccess, timersRef);
      timersRef.current.add(timer1);
    } catch (err_0) {
      const errorMessage = (err_0 as Error).message;
      setOAuthStatus({
        state: 'error',
        message: errorMessage,
        toRetry: {
          state: 'starting'
        } // Allow retry by starting fresh OAuth flow
      });
      logError(err_0);
      logEvent('tengu_oauth_error', {
        error: errorMessage as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
      });
    }
  }, [oauthService, onSuccess]);
  useEffect(() => {
    if (oauthStatus.state === 'starting') {
      void startOAuth();
    }
  }, [oauthStatus.state, startOAuth]);

  // Retry logic
  useEffect(() => {
    if (oauthStatus.state === 'about_to_retry') {
      const timer_1 = setTimeout((nextState, setShowPastePrompt_0, setOAuthStatus_1) => {
        // Only show paste prompt when retrying to waiting_for_login
        setShowPastePrompt_0(nextState.state === 'waiting_for_login');
        setOAuthStatus_1(nextState);
      }, 500, oauthStatus.nextState, setShowPastePrompt, setOAuthStatus);
      timersRef.current.add(timer_1);
    }
  }, [oauthStatus]);
  useEffect(() => {
    if (pastedCode === 'c' && oauthStatus.state === 'waiting_for_login' && showPastePrompt && !urlCopied) {
      void setClipboard(oauthStatus.url).then(raw => {
        if (raw) process.stdout.write(raw);
        setUrlCopied(true);
        clearTimeout(urlCopiedTimerRef.current);
        urlCopiedTimerRef.current = setTimeout(setUrlCopied, 2000, false);
      });
      setPastedCode('');
    }
  }, [pastedCode, oauthStatus, showPastePrompt, urlCopied]);

  // Cleanup OAuth service and timers when component unmounts
  useEffect(() => {
    const timers = timersRef.current;
    return () => {
      oauthService.cleanup();
      // Clear all timers
      timers.forEach(timer_2 => clearTimeout(timer_2));
      timers.clear();
      clearTimeout(urlCopiedTimerRef.current);
    };
  }, [oauthService]);

  // Helper function to render the appropriate status message
  function renderStatusMessage(): React.ReactNode {
    switch (oauthStatus.state) {
      case 'starting':
        return <Box>
            <Spinner />
            <Text>Starting authentication…</Text>
          </Box>;
      case 'waiting_for_login':
        return <Box flexDirection="column" gap={1}>
            {!showPastePrompt && <Box>
                <Spinner />
                <Text>
                  Opening browser to sign in with your Claude account…
                </Text>
              </Box>}

            {showPastePrompt && <Box>
                <Text>{PASTE_HERE_MSG}</Text>
                <TextInput value={pastedCode} onChange={setPastedCode} onSubmit={(value_0: string) => handleSubmitCode(value_0, oauthStatus.url)} cursorOffset={cursorOffset} onChangeCursorOffset={setCursorOffset} columns={textInputColumns} />
              </Box>}
          </Box>;
      case 'processing':
        return <Box>
            <Spinner />
            <Text>Processing authentication…</Text>
          </Box>;
      case 'success':
        return <Box flexDirection="column" gap={1}>
            <Text color="success">
              ✓ Authentication token created successfully!
            </Text>
            <Text dimColor>Using token for GitHub Actions setup…</Text>
          </Box>;
      case 'error':
        return <Box flexDirection="column" gap={1}>
            <Text color="error">OAuth error: {oauthStatus.message}</Text>
            {oauthStatus.toRetry ? <Text dimColor>
                Press Enter to try again, or any other key to cancel
              </Text> : <Text dimColor>Press any key to return to API key selection</Text>}
          </Box>;
      case 'about_to_retry':
        return <Box flexDirection="column" gap={1}>
            <Text color="permission">Retrying…</Text>
          </Box>;
      default:
        return null;
    }
  }
  return <Box flexDirection="column" gap={1} tabIndex={0} autoFocus onKeyDown={handleKeyDown}>
      {/* Show header inline only for initial starting state */}
      {oauthStatus.state === 'starting' && <Box flexDirection="column" gap={1} paddingBottom={1}>
          <Text bold>Create Authentication Token</Text>
          <Text dimColor>Creating a long-lived token for GitHub Actions</Text>
        </Box>}
      {/* Show header for non-starting states (to avoid duplicate with inline header)*/}
      {oauthStatus.state !== 'success' && oauthStatus.state !== 'starting' && oauthStatus.state !== 'processing' && <Box key="header" flexDirection="column" gap={1} paddingBottom={1}>
            <Text bold>Create Authentication Token</Text>
            <Text dimColor>Creating a long-lived token for GitHub Actions</Text>
          </Box>}
      {/* Show URL when paste prompt is visible */}
      {oauthStatus.state === 'waiting_for_login' && showPastePrompt && <Box flexDirection="column" key="urlToCopy" gap={1} paddingBottom={1}>
          <Box paddingX={1}>
            <Text dimColor>
              Browser didn&apos;t open? Use the url below to sign in{' '}
            </Text>
            {urlCopied ? <Text color="success">(Copied!)</Text> : <Text dimColor>
                <KeyboardShortcutHint shortcut="c" action="copy" parens />
              </Text>}
          </Box>
          <Link url={oauthStatus.url}>
            <Text dimColor>{oauthStatus.url}</Text>
          </Link>
        </Box>}
      <Box paddingLeft={1} flexDirection="column" gap={1}>
        {renderStatusMessage()}
      </Box>
    </Box>;
}
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJSZWFjdCIsInVzZUNhbGxiYWNrIiwidXNlRWZmZWN0IiwidXNlUmVmIiwidXNlU3RhdGUiLCJBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTIiwibG9nRXZlbnQiLCJLZXlib2FyZFNob3J0Y3V0SGludCIsIlNwaW5uZXIiLCJUZXh0SW5wdXQiLCJ1c2VUZXJtaW5hbFNpemUiLCJLZXlib2FyZEV2ZW50Iiwic2V0Q2xpcGJvYXJkIiwiQm94IiwiTGluayIsIlRleHQiLCJPQXV0aFNlcnZpY2UiLCJzYXZlT0F1dGhUb2tlbnNJZk5lZWRlZCIsImxvZ0Vycm9yIiwiT0F1dGhGbG93U3RlcFByb3BzIiwib25TdWNjZXNzIiwidG9rZW4iLCJvbkNhbmNlbCIsIk9BdXRoU3RhdHVzIiwic3RhdGUiLCJ1cmwiLCJtZXNzYWdlIiwidG9SZXRyeSIsIm5leHRTdGF0ZSIsIlBBU1RFX0hFUkVfTVNHIiwiT0F1dGhGbG93U3RlcCIsIlJlYWN0Tm9kZSIsIm9hdXRoU3RhdHVzIiwic2V0T0F1dGhTdGF0dXMiLCJvYXV0aFNlcnZpY2UiLCJwYXN0ZWRDb2RlIiwic2V0UGFzdGVkQ29kZSIsImN1cnNvck9mZnNldCIsInNldEN1cnNvck9mZnNldCIsInNob3dQYXN0ZVByb21wdCIsInNldFNob3dQYXN0ZVByb21wdCIsInVybENvcGllZCIsInNldFVybENvcGllZCIsInRpbWVyc1JlZiIsIlNldCIsIk5vZGVKUyIsIlRpbWVvdXQiLCJ1cmxDb3BpZWRUaW1lclJlZiIsInVuZGVmaW5lZCIsInRlcm1pbmFsU2l6ZSIsInRleHRJbnB1dENvbHVtbnMiLCJNYXRoIiwibWF4IiwiY29sdW1ucyIsImxlbmd0aCIsImhhbmRsZUtleURvd24iLCJlIiwicHJldmVudERlZmF1bHQiLCJrZXkiLCJoYW5kbGVTdWJtaXRDb2RlIiwidmFsdWUiLCJhdXRob3JpemF0aW9uQ29kZSIsInNwbGl0IiwiaGFuZGxlTWFudWFsQXV0aENvZGVJbnB1dCIsImVyciIsIkVycm9yIiwic3RhcnRPQXV0aCIsImN1cnJlbnQiLCJmb3JFYWNoIiwidGltZXIiLCJjbGVhclRpbWVvdXQiLCJjbGVhciIsInJlc3VsdCIsInN0YXJ0T0F1dGhGbG93Iiwic2V0VGltZW91dCIsImFkZCIsImxvZ2luV2l0aENsYXVkZUFpIiwiaW5mZXJlbmNlT25seSIsImV4cGlyZXNJbiIsInRpbWVyMSIsImFjY2Vzc1Rva2VuIiwidGltZXIyIiwiZXJyb3JNZXNzYWdlIiwiZXJyb3IiLCJ0aGVuIiwicmF3IiwicHJvY2VzcyIsInN0ZG91dCIsIndyaXRlIiwidGltZXJzIiwiY2xlYW51cCIsInJlbmRlclN0YXR1c01lc3NhZ2UiXSwic291cmNlcyI6WyJPQXV0aEZsb3dTdGVwLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHsgdXNlQ2FsbGJhY2ssIHVzZUVmZmVjdCwgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHtcbiAgdHlwZSBBbmFseXRpY3NNZXRhZGF0YV9JX1ZFUklGSUVEX1RISVNfSVNfTk9UX0NPREVfT1JfRklMRVBBVEhTLFxuICBsb2dFdmVudCxcbn0gZnJvbSAnc3JjL3NlcnZpY2VzL2FuYWx5dGljcy9pbmRleC5qcydcbmltcG9ydCB7IEtleWJvYXJkU2hvcnRjdXRIaW50IH0gZnJvbSAnLi4vLi4vY29tcG9uZW50cy9kZXNpZ24tc3lzdGVtL0tleWJvYXJkU2hvcnRjdXRIaW50LmpzJ1xuaW1wb3J0IHsgU3Bpbm5lciB9IGZyb20gJy4uLy4uL2NvbXBvbmVudHMvU3Bpbm5lci5qcydcbmltcG9ydCBUZXh0SW5wdXQgZnJvbSAnLi4vLi4vY29tcG9uZW50cy9UZXh0SW5wdXQuanMnXG5pbXBvcnQgeyB1c2VUZXJtaW5hbFNpemUgfSBmcm9tICcuLi8uLi9ob29rcy91c2VUZXJtaW5hbFNpemUuanMnXG5pbXBvcnQgdHlwZSB7IEtleWJvYXJkRXZlbnQgfSBmcm9tICcuLi8uLi9pbmsvZXZlbnRzL2tleWJvYXJkLWV2ZW50LmpzJ1xuaW1wb3J0IHsgc2V0Q2xpcGJvYXJkIH0gZnJvbSAnLi4vLi4vaW5rL3Rlcm1pby9vc2MuanMnXG5pbXBvcnQgeyBCb3gsIExpbmssIFRleHQgfSBmcm9tICcuLi8uLi9pbmsuanMnXG5pbXBvcnQgeyBPQXV0aFNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9vYXV0aC9pbmRleC5qcydcbmltcG9ydCB7IHNhdmVPQXV0aFRva2Vuc0lmTmVlZGVkIH0gZnJvbSAnLi4vLi4vdXRpbHMvYXV0aC5qcydcbmltcG9ydCB7IGxvZ0Vycm9yIH0gZnJvbSAnLi4vLi4vdXRpbHMvbG9nLmpzJ1xuXG5pbnRlcmZhY2UgT0F1dGhGbG93U3RlcFByb3BzIHtcbiAgb25TdWNjZXNzOiAodG9rZW46IHN0cmluZykgPT4gdm9pZFxuICBvbkNhbmNlbDogKCkgPT4gdm9pZFxufVxuXG50eXBlIE9BdXRoU3RhdHVzID1cbiAgfCB7IHN0YXRlOiAnc3RhcnRpbmcnIH1cbiAgfCB7IHN0YXRlOiAnd2FpdGluZ19mb3JfbG9naW4nOyB1cmw6IHN0cmluZyB9XG4gIHwgeyBzdGF0ZTogJ3Byb2Nlc3NpbmcnIH1cbiAgfCB7IHN0YXRlOiAnc3VjY2Vzcyc7IHRva2VuOiBzdHJpbmcgfVxuICB8IHsgc3RhdGU6ICdlcnJvcic7IG1lc3NhZ2U6IHN0cmluZzsgdG9SZXRyeT86IE9BdXRoU3RhdHVzIH1cbiAgfCB7IHN0YXRlOiAnYWJvdXRfdG9fcmV0cnknOyBuZXh0U3RhdGU6IE9BdXRoU3RhdHVzIH1cblxuY29uc3QgUEFTVEVfSEVSRV9NU0cgPSAnUGFzdGUgY29kZSBoZXJlIGlmIHByb21wdGVkID4gJ1xuXG5leHBvcnQgZnVuY3Rpb24gT0F1dGhGbG93U3RlcCh7XG4gIG9uU3VjY2VzcyxcbiAgb25DYW5jZWwsXG59OiBPQXV0aEZsb3dTdGVwUHJvcHMpOiBSZWFjdC5SZWFjdE5vZGUge1xuICBjb25zdCBbb2F1dGhTdGF0dXMsIHNldE9BdXRoU3RhdHVzXSA9IHVzZVN0YXRlPE9BdXRoU3RhdHVzPih7XG4gICAgc3RhdGU6ICdzdGFydGluZycsXG4gIH0pXG4gIGNvbnN0IFtvYXV0aFNlcnZpY2VdID0gdXNlU3RhdGUoKCkgPT4gbmV3IE9BdXRoU2VydmljZSgpKVxuICBjb25zdCBbcGFzdGVkQ29kZSwgc2V0UGFzdGVkQ29kZV0gPSB1c2VTdGF0ZSgnJylcbiAgY29uc3QgW2N1cnNvck9mZnNldCwgc2V0Q3Vyc29yT2Zmc2V0XSA9IHVzZVN0YXRlKDApXG4gIGNvbnN0IFtzaG93UGFzdGVQcm9tcHQsIHNldFNob3dQYXN0ZVByb21wdF0gPSB1c2VTdGF0ZShmYWxzZSlcbiAgY29uc3QgW3VybENvcGllZCwgc2V0VXJsQ29waWVkXSA9IHVzZVN0YXRlKGZhbHNlKVxuICBjb25zdCB0aW1lcnNSZWYgPSB1c2VSZWY8U2V0PE5vZGVKUy5UaW1lb3V0Pj4obmV3IFNldCgpKVxuICAvLyBTZXBhcmF0ZSByZWYgc28gc3RhcnRPQXV0aCdzIHRpbWVyIGNsZWFyIGRvZXNuJ3QgY2FuY2VsIHRoZSB1cmxDb3BpZWQgcmVzZXRcbiAgY29uc3QgdXJsQ29waWVkVGltZXJSZWYgPSB1c2VSZWY8Tm9kZUpTLlRpbWVvdXQgfCB1bmRlZmluZWQ+KHVuZGVmaW5lZClcblxuICBjb25zdCB0ZXJtaW5hbFNpemUgPSB1c2VUZXJtaW5hbFNpemUoKVxuICBjb25zdCB0ZXh0SW5wdXRDb2x1bW5zID0gTWF0aC5tYXgoXG4gICAgNTAsXG4gICAgdGVybWluYWxTaXplLmNvbHVtbnMgLSBQQVNURV9IRVJFX01TRy5sZW5ndGggLSA0LFxuICApXG5cbiAgZnVuY3Rpb24gaGFuZGxlS2V5RG93bihlOiBLZXlib2FyZEV2ZW50KTogdm9pZCB7XG4gICAgaWYgKG9hdXRoU3RhdHVzLnN0YXRlICE9PSAnZXJyb3InKSByZXR1cm5cbiAgICBlLnByZXZlbnREZWZhdWx0KClcbiAgICBpZiAoZS5rZXkgPT09ICdyZXR1cm4nICYmIG9hdXRoU3RhdHVzLnRvUmV0cnkpIHtcbiAgICAgIHNldFBhc3RlZENvZGUoJycpXG4gICAgICBzZXRDdXJzb3JPZmZzZXQoMClcbiAgICAgIHNldE9BdXRoU3RhdHVzKHtcbiAgICAgICAgc3RhdGU6ICdhYm91dF90b19yZXRyeScsXG4gICAgICAgIG5leHRTdGF0ZTogb2F1dGhTdGF0dXMudG9SZXRyeSxcbiAgICAgIH0pXG4gICAgfSBlbHNlIHtcbiAgICAgIG9uQ2FuY2VsKClcbiAgICB9XG4gIH1cblxuICBhc3luYyBmdW5jdGlvbiBoYW5kbGVTdWJtaXRDb2RlKHZhbHVlOiBzdHJpbmcsIHVybDogc3RyaW5nKSB7XG4gICAgdHJ5IHtcbiAgICAgIC8vIEV4cGVjdGluZyBmb3JtYXQgXCJhdXRob3JpemF0aW9uQ29kZSNzdGF0ZVwiIGZyb20gdGhlIGF1dGhvcml6YXRpb24gY2FsbGJhY2sgVVJMXG4gICAgICBjb25zdCBbYXV0aG9yaXphdGlvbkNvZGUsIHN0YXRlXSA9IHZhbHVlLnNwbGl0KCcjJylcblxuICAgICAgaWYgKCFhdXRob3JpemF0aW9uQ29kZSB8fCAhc3RhdGUpIHtcbiAgICAgICAgc2V0T0F1dGhTdGF0dXMoe1xuICAgICAgICAgIHN0YXRlOiAnZXJyb3InLFxuICAgICAgICAgIG1lc3NhZ2U6ICdJbnZhbGlkIGNvZGUuIFBsZWFzZSBtYWtlIHN1cmUgdGhlIGZ1bGwgY29kZSB3YXMgY29waWVkJyxcbiAgICAgICAgICB0b1JldHJ5OiB7IHN0YXRlOiAnd2FpdGluZ19mb3JfbG9naW4nLCB1cmwgfSxcbiAgICAgICAgfSlcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIC8vIFRyYWNrIHdoaWNoIHBhdGggdGhlIHVzZXIgaXMgdGFraW5nIChtYW51YWwgY29kZSBlbnRyeSlcbiAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9vYXV0aF9tYW51YWxfZW50cnknLCB7fSlcbiAgICAgIG9hdXRoU2VydmljZS5oYW5kbGVNYW51YWxBdXRoQ29kZUlucHV0KHtcbiAgICAgICAgYXV0aG9yaXphdGlvbkNvZGUsXG4gICAgICAgIHN0YXRlLFxuICAgICAgfSlcbiAgICB9IGNhdGNoIChlcnI6IHVua25vd24pIHtcbiAgICAgIGxvZ0Vycm9yKGVycilcbiAgICAgIHNldE9BdXRoU3RhdHVzKHtcbiAgICAgICAgc3RhdGU6ICdlcnJvcicsXG4gICAgICAgIG1lc3NhZ2U6IChlcnIgYXMgRXJyb3IpLm1lc3NhZ2UsXG4gICAgICAgIHRvUmV0cnk6IHsgc3RhdGU6ICd3YWl0aW5nX2Zvcl9sb2dpbicsIHVybCB9LFxuICAgICAgfSlcbiAgICB9XG4gIH1cblxuICBjb25zdCBzdGFydE9BdXRoID0gdXNlQ2FsbGJhY2soYXN5bmMgKCkgPT4ge1xuICAgIC8vIENsZWFyIGFueSBleGlzdGluZyB0aW1lcnMgd2hlbiBzdGFydGluZyBuZXcgT0F1dGggZmxvd1xuICAgIHRpbWVyc1JlZi5jdXJyZW50LmZvckVhY2godGltZXIgPT4gY2xlYXJUaW1lb3V0KHRpbWVyKSlcbiAgICB0aW1lcnNSZWYuY3VycmVudC5jbGVhcigpXG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgb2F1dGhTZXJ2aWNlLnN0YXJ0T0F1dGhGbG93KFxuICAgICAgICBhc3luYyB1cmwgPT4ge1xuICAgICAgICAgIHNldE9BdXRoU3RhdHVzKHsgc3RhdGU6ICd3YWl0aW5nX2Zvcl9sb2dpbicsIHVybCB9KVxuICAgICAgICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dChzZXRTaG93UGFzdGVQcm9tcHQsIDMwMDAsIHRydWUpXG4gICAgICAgICAgdGltZXJzUmVmLmN1cnJlbnQuYWRkKHRpbWVyKVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgbG9naW5XaXRoQ2xhdWRlQWk6IHRydWUsIC8vIEFsd2F5cyB1c2UgQ2xhdWRlIEFJIGZvciBzdWJzY3JpcHRpb24gdG9rZW5zXG4gICAgICAgICAgaW5mZXJlbmNlT25seTogdHJ1ZSxcbiAgICAgICAgICBleHBpcmVzSW46IDM2NSAqIDI0ICogNjAgKiA2MCwgLy8gMSB5ZWFyXG4gICAgICAgIH0sXG4gICAgICApXG5cbiAgICAgIC8vIFNob3cgcHJvY2Vzc2luZyBzdGF0ZVxuICAgICAgc2V0T0F1dGhTdGF0dXMoeyBzdGF0ZTogJ3Byb2Nlc3NpbmcnIH0pXG5cbiAgICAgIC8vIE9BdXRoRmxvd1N0ZXAgY3JlYXRlcyBpbmZlcmVuY2Utb25seSB0b2tlbnMgZm9yIEdpdEh1YiBBY3Rpb25zLCBub3QgYVxuICAgICAgLy8gcmVwbGFjZW1lbnQgbG9naW4uIFVzZSBzYXZlT0F1dGhUb2tlbnNJZk5lZWRlZCBkaXJlY3RseSB0byBhdm9pZFxuICAgICAgLy8gcGVyZm9ybUxvZ291dCB3aGljaCB3b3VsZCBkZXN0cm95IHRoZSB1c2VyJ3MgZXhpc3RpbmcgYXV0aCBzZXNzaW9uLlxuICAgICAgc2F2ZU9BdXRoVG9rZW5zSWZOZWVkZWQocmVzdWx0KVxuXG4gICAgICAvLyBGb3IgT0F1dGggZmxvdywgdGhlIGFjY2VzcyB0b2tlbiBjYW4gYmUgdXNlZCBhcyBhbiBBUEkga2V5XG4gICAgICBjb25zdCB0aW1lcjEgPSBzZXRUaW1lb3V0KFxuICAgICAgICAoc2V0T0F1dGhTdGF0dXMsIGFjY2Vzc1Rva2VuLCBvblN1Y2Nlc3MsIHRpbWVyc1JlZikgPT4ge1xuICAgICAgICAgIHNldE9BdXRoU3RhdHVzKHsgc3RhdGU6ICdzdWNjZXNzJywgdG9rZW46IGFjY2Vzc1Rva2VuIH0pXG4gICAgICAgICAgLy8gQXV0by1jb250aW51ZSBhZnRlciBicmllZiBkZWxheSB0byBzaG93IHN1Y2Nlc3NcbiAgICAgICAgICBjb25zdCB0aW1lcjIgPSBzZXRUaW1lb3V0KG9uU3VjY2VzcywgMTAwMCwgYWNjZXNzVG9rZW4pXG4gICAgICAgICAgdGltZXJzUmVmLmN1cnJlbnQuYWRkKHRpbWVyMilcbiAgICAgICAgfSxcbiAgICAgICAgMTAwLFxuICAgICAgICBzZXRPQXV0aFN0YXR1cyxcbiAgICAgICAgcmVzdWx0LmFjY2Vzc1Rva2VuLFxuICAgICAgICBvblN1Y2Nlc3MsXG4gICAgICAgIHRpbWVyc1JlZixcbiAgICAgIClcbiAgICAgIHRpbWVyc1JlZi5jdXJyZW50LmFkZCh0aW1lcjEpXG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSAoZXJyIGFzIEVycm9yKS5tZXNzYWdlXG4gICAgICBzZXRPQXV0aFN0YXR1cyh7XG4gICAgICAgIHN0YXRlOiAnZXJyb3InLFxuICAgICAgICBtZXNzYWdlOiBlcnJvck1lc3NhZ2UsXG4gICAgICAgIHRvUmV0cnk6IHsgc3RhdGU6ICdzdGFydGluZycgfSwgLy8gQWxsb3cgcmV0cnkgYnkgc3RhcnRpbmcgZnJlc2ggT0F1dGggZmxvd1xuICAgICAgfSlcbiAgICAgIGxvZ0Vycm9yKGVycilcbiAgICAgIGxvZ0V2ZW50KCd0ZW5ndV9vYXV0aF9lcnJvcicsIHtcbiAgICAgICAgZXJyb3I6XG4gICAgICAgICAgZXJyb3JNZXNzYWdlIGFzIEFuYWx5dGljc01ldGFkYXRhX0lfVkVSSUZJRURfVEhJU19JU19OT1RfQ09ERV9PUl9GSUxFUEFUSFMsXG4gICAgICB9KVxuICAgIH1cbiAgfSwgW29hdXRoU2VydmljZSwgb25TdWNjZXNzXSlcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChvYXV0aFN0YXR1cy5zdGF0ZSA9PT0gJ3N0YXJ0aW5nJykge1xuICAgICAgdm9pZCBzdGFydE9BdXRoKClcbiAgICB9XG4gIH0sIFtvYXV0aFN0YXR1cy5zdGF0ZSwgc3RhcnRPQXV0aF0pXG5cbiAgLy8gUmV0cnkgbG9naWNcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAob2F1dGhTdGF0dXMuc3RhdGUgPT09ICdhYm91dF90b19yZXRyeScpIHtcbiAgICAgIGNvbnN0IHRpbWVyID0gc2V0VGltZW91dChcbiAgICAgICAgKG5leHRTdGF0ZSwgc2V0U2hvd1Bhc3RlUHJvbXB0LCBzZXRPQXV0aFN0YXR1cykgPT4ge1xuICAgICAgICAgIC8vIE9ubHkgc2hvdyBwYXN0ZSBwcm9tcHQgd2hlbiByZXRyeWluZyB0byB3YWl0aW5nX2Zvcl9sb2dpblxuICAgICAgICAgIHNldFNob3dQYXN0ZVByb21wdChuZXh0U3RhdGUuc3RhdGUgPT09ICd3YWl0aW5nX2Zvcl9sb2dpbicpXG4gICAgICAgICAgc2V0T0F1dGhTdGF0dXMobmV4dFN0YXRlKVxuICAgICAgICB9LFxuICAgICAgICA1MDAsXG4gICAgICAgIG9hdXRoU3RhdHVzLm5leHRTdGF0ZSxcbiAgICAgICAgc2V0U2hvd1Bhc3RlUHJvbXB0LFxuICAgICAgICBzZXRPQXV0aFN0YXR1cyxcbiAgICAgIClcbiAgICAgIHRpbWVyc1JlZi5jdXJyZW50LmFkZCh0aW1lcilcbiAgICB9XG4gIH0sIFtvYXV0aFN0YXR1c10pXG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpZiAoXG4gICAgICBwYXN0ZWRDb2RlID09PSAnYycgJiZcbiAgICAgIG9hdXRoU3RhdHVzLnN0YXRlID09PSAnd2FpdGluZ19mb3JfbG9naW4nICYmXG4gICAgICBzaG93UGFzdGVQcm9tcHQgJiZcbiAgICAgICF1cmxDb3BpZWRcbiAgICApIHtcbiAgICAgIHZvaWQgc2V0Q2xpcGJvYXJkKG9hdXRoU3RhdHVzLnVybCkudGhlbihyYXcgPT4ge1xuICAgICAgICBpZiAocmF3KSBwcm9jZXNzLnN0ZG91dC53cml0ZShyYXcpXG4gICAgICAgIHNldFVybENvcGllZCh0cnVlKVxuICAgICAgICBjbGVhclRpbWVvdXQodXJsQ29waWVkVGltZXJSZWYuY3VycmVudClcbiAgICAgICAgdXJsQ29waWVkVGltZXJSZWYuY3VycmVudCA9IHNldFRpbWVvdXQoc2V0VXJsQ29waWVkLCAyMDAwLCBmYWxzZSlcbiAgICAgIH0pXG4gICAgICBzZXRQYXN0ZWRDb2RlKCcnKVxuICAgIH1cbiAgfSwgW3Bhc3RlZENvZGUsIG9hdXRoU3RhdHVzLCBzaG93UGFzdGVQcm9tcHQsIHVybENvcGllZF0pXG5cbiAgLy8gQ2xlYW51cCBPQXV0aCBzZXJ2aWNlIGFuZCB0aW1lcnMgd2hlbiBjb21wb25lbnQgdW5tb3VudHNcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBjb25zdCB0aW1lcnMgPSB0aW1lcnNSZWYuY3VycmVudFxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBvYXV0aFNlcnZpY2UuY2xlYW51cCgpXG4gICAgICAvLyBDbGVhciBhbGwgdGltZXJzXG4gICAgICB0aW1lcnMuZm9yRWFjaCh0aW1lciA9PiBjbGVhclRpbWVvdXQodGltZXIpKVxuICAgICAgdGltZXJzLmNsZWFyKClcbiAgICAgIGNsZWFyVGltZW91dCh1cmxDb3BpZWRUaW1lclJlZi5jdXJyZW50KVxuICAgIH1cbiAgfSwgW29hdXRoU2VydmljZV0pXG5cbiAgLy8gSGVscGVyIGZ1bmN0aW9uIHRvIHJlbmRlciB0aGUgYXBwcm9wcmlhdGUgc3RhdHVzIG1lc3NhZ2VcbiAgZnVuY3Rpb24gcmVuZGVyU3RhdHVzTWVzc2FnZSgpOiBSZWFjdC5SZWFjdE5vZGUge1xuICAgIHN3aXRjaCAob2F1dGhTdGF0dXMuc3RhdGUpIHtcbiAgICAgIGNhc2UgJ3N0YXJ0aW5nJzpcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICA8Qm94PlxuICAgICAgICAgICAgPFNwaW5uZXIgLz5cbiAgICAgICAgICAgIDxUZXh0PlN0YXJ0aW5nIGF1dGhlbnRpY2F0aW9u4oCmPC9UZXh0PlxuICAgICAgICAgIDwvQm94PlxuICAgICAgICApXG5cbiAgICAgIGNhc2UgJ3dhaXRpbmdfZm9yX2xvZ2luJzpcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICA8Qm94IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBnYXA9ezF9PlxuICAgICAgICAgICAgeyFzaG93UGFzdGVQcm9tcHQgJiYgKFxuICAgICAgICAgICAgICA8Qm94PlxuICAgICAgICAgICAgICAgIDxTcGlubmVyIC8+XG4gICAgICAgICAgICAgICAgPFRleHQ+XG4gICAgICAgICAgICAgICAgICBPcGVuaW5nIGJyb3dzZXIgdG8gc2lnbiBpbiB3aXRoIHlvdXIgQ2xhdWRlIGFjY291bnTigKZcbiAgICAgICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgICAgIDwvQm94PlxuICAgICAgICAgICAgKX1cblxuICAgICAgICAgICAge3Nob3dQYXN0ZVByb21wdCAmJiAoXG4gICAgICAgICAgICAgIDxCb3g+XG4gICAgICAgICAgICAgICAgPFRleHQ+e1BBU1RFX0hFUkVfTVNHfTwvVGV4dD5cbiAgICAgICAgICAgICAgICA8VGV4dElucHV0XG4gICAgICAgICAgICAgICAgICB2YWx1ZT17cGFzdGVkQ29kZX1cbiAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlPXtzZXRQYXN0ZWRDb2RlfVxuICAgICAgICAgICAgICAgICAgb25TdWJtaXQ9eyh2YWx1ZTogc3RyaW5nKSA9PlxuICAgICAgICAgICAgICAgICAgICBoYW5kbGVTdWJtaXRDb2RlKHZhbHVlLCBvYXV0aFN0YXR1cy51cmwpXG4gICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICBjdXJzb3JPZmZzZXQ9e2N1cnNvck9mZnNldH1cbiAgICAgICAgICAgICAgICAgIG9uQ2hhbmdlQ3Vyc29yT2Zmc2V0PXtzZXRDdXJzb3JPZmZzZXR9XG4gICAgICAgICAgICAgICAgICBjb2x1bW5zPXt0ZXh0SW5wdXRDb2x1bW5zfVxuICAgICAgICAgICAgICAgIC8+XG4gICAgICAgICAgICAgIDwvQm94PlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICA8L0JveD5cbiAgICAgICAgKVxuXG4gICAgICBjYXNlICdwcm9jZXNzaW5nJzpcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICA8Qm94PlxuICAgICAgICAgICAgPFNwaW5uZXIgLz5cbiAgICAgICAgICAgIDxUZXh0PlByb2Nlc3NpbmcgYXV0aGVudGljYXRpb27igKY8L1RleHQ+XG4gICAgICAgICAgPC9Cb3g+XG4gICAgICAgIClcblxuICAgICAgY2FzZSAnc3VjY2Vzcyc6XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCIgZ2FwPXsxfT5cbiAgICAgICAgICAgIDxUZXh0IGNvbG9yPVwic3VjY2Vzc1wiPlxuICAgICAgICAgICAgICDinJMgQXV0aGVudGljYXRpb24gdG9rZW4gY3JlYXRlZCBzdWNjZXNzZnVsbHkhXG4gICAgICAgICAgICA8L1RleHQ+XG4gICAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5Vc2luZyB0b2tlbiBmb3IgR2l0SHViIEFjdGlvbnMgc2V0dXDigKY8L1RleHQ+XG4gICAgICAgICAgPC9Cb3g+XG4gICAgICAgIClcblxuICAgICAgY2FzZSAnZXJyb3InOlxuICAgICAgICByZXR1cm4gKFxuICAgICAgICAgIDxCb3ggZmxleERpcmVjdGlvbj1cImNvbHVtblwiIGdhcD17MX0+XG4gICAgICAgICAgICA8VGV4dCBjb2xvcj1cImVycm9yXCI+T0F1dGggZXJyb3I6IHtvYXV0aFN0YXR1cy5tZXNzYWdlfTwvVGV4dD5cbiAgICAgICAgICAgIHtvYXV0aFN0YXR1cy50b1JldHJ5ID8gKFxuICAgICAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5cbiAgICAgICAgICAgICAgICBQcmVzcyBFbnRlciB0byB0cnkgYWdhaW4sIG9yIGFueSBvdGhlciBrZXkgdG8gY2FuY2VsXG4gICAgICAgICAgICAgIDwvVGV4dD5cbiAgICAgICAgICAgICkgOiAoXG4gICAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPlByZXNzIGFueSBrZXkgdG8gcmV0dXJuIHRvIEFQSSBrZXkgc2VsZWN0aW9uPC9UZXh0PlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICA8L0JveD5cbiAgICAgICAgKVxuXG4gICAgICBjYXNlICdhYm91dF90b19yZXRyeSc6XG4gICAgICAgIHJldHVybiAoXG4gICAgICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCIgZ2FwPXsxfT5cbiAgICAgICAgICAgIDxUZXh0IGNvbG9yPVwicGVybWlzc2lvblwiPlJldHJ5aW5n4oCmPC9UZXh0PlxuICAgICAgICAgIDwvQm94PlxuICAgICAgICApXG5cbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIChcbiAgICA8Qm94XG4gICAgICBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCJcbiAgICAgIGdhcD17MX1cbiAgICAgIHRhYkluZGV4PXswfVxuICAgICAgYXV0b0ZvY3VzXG4gICAgICBvbktleURvd249e2hhbmRsZUtleURvd259XG4gICAgPlxuICAgICAgey8qIFNob3cgaGVhZGVyIGlubGluZSBvbmx5IGZvciBpbml0aWFsIHN0YXJ0aW5nIHN0YXRlICovfVxuICAgICAge29hdXRoU3RhdHVzLnN0YXRlID09PSAnc3RhcnRpbmcnICYmIChcbiAgICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCIgZ2FwPXsxfSBwYWRkaW5nQm90dG9tPXsxfT5cbiAgICAgICAgICA8VGV4dCBib2xkPkNyZWF0ZSBBdXRoZW50aWNhdGlvbiBUb2tlbjwvVGV4dD5cbiAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5DcmVhdGluZyBhIGxvbmctbGl2ZWQgdG9rZW4gZm9yIEdpdEh1YiBBY3Rpb25zPC9UZXh0PlxuICAgICAgICA8L0JveD5cbiAgICAgICl9XG4gICAgICB7LyogU2hvdyBoZWFkZXIgZm9yIG5vbi1zdGFydGluZyBzdGF0ZXMgKHRvIGF2b2lkIGR1cGxpY2F0ZSB3aXRoIGlubGluZSBoZWFkZXIpKi99XG4gICAgICB7b2F1dGhTdGF0dXMuc3RhdGUgIT09ICdzdWNjZXNzJyAmJlxuICAgICAgICBvYXV0aFN0YXR1cy5zdGF0ZSAhPT0gJ3N0YXJ0aW5nJyAmJlxuICAgICAgICBvYXV0aFN0YXR1cy5zdGF0ZSAhPT0gJ3Byb2Nlc3NpbmcnICYmIChcbiAgICAgICAgICA8Qm94IGtleT1cImhlYWRlclwiIGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBnYXA9ezF9IHBhZGRpbmdCb3R0b209ezF9PlxuICAgICAgICAgICAgPFRleHQgYm9sZD5DcmVhdGUgQXV0aGVudGljYXRpb24gVG9rZW48L1RleHQ+XG4gICAgICAgICAgICA8VGV4dCBkaW1Db2xvcj5DcmVhdGluZyBhIGxvbmctbGl2ZWQgdG9rZW4gZm9yIEdpdEh1YiBBY3Rpb25zPC9UZXh0PlxuICAgICAgICAgIDwvQm94PlxuICAgICAgICApfVxuICAgICAgey8qIFNob3cgVVJMIHdoZW4gcGFzdGUgcHJvbXB0IGlzIHZpc2libGUgKi99XG4gICAgICB7b2F1dGhTdGF0dXMuc3RhdGUgPT09ICd3YWl0aW5nX2Zvcl9sb2dpbicgJiYgc2hvd1Bhc3RlUHJvbXB0ICYmIChcbiAgICAgICAgPEJveCBmbGV4RGlyZWN0aW9uPVwiY29sdW1uXCIga2V5PVwidXJsVG9Db3B5XCIgZ2FwPXsxfSBwYWRkaW5nQm90dG9tPXsxfT5cbiAgICAgICAgICA8Qm94IHBhZGRpbmdYPXsxfT5cbiAgICAgICAgICAgIDxUZXh0IGRpbUNvbG9yPlxuICAgICAgICAgICAgICBCcm93c2VyIGRpZG4mYXBvczt0IG9wZW4/IFVzZSB0aGUgdXJsIGJlbG93IHRvIHNpZ24gaW57JyAnfVxuICAgICAgICAgICAgPC9UZXh0PlxuICAgICAgICAgICAge3VybENvcGllZCA/IChcbiAgICAgICAgICAgICAgPFRleHQgY29sb3I9XCJzdWNjZXNzXCI+KENvcGllZCEpPC9UZXh0PlxuICAgICAgICAgICAgKSA6IChcbiAgICAgICAgICAgICAgPFRleHQgZGltQ29sb3I+XG4gICAgICAgICAgICAgICAgPEtleWJvYXJkU2hvcnRjdXRIaW50IHNob3J0Y3V0PVwiY1wiIGFjdGlvbj1cImNvcHlcIiBwYXJlbnMgLz5cbiAgICAgICAgICAgICAgPC9UZXh0PlxuICAgICAgICAgICAgKX1cbiAgICAgICAgICA8L0JveD5cbiAgICAgICAgICA8TGluayB1cmw9e29hdXRoU3RhdHVzLnVybH0+XG4gICAgICAgICAgICA8VGV4dCBkaW1Db2xvcj57b2F1dGhTdGF0dXMudXJsfTwvVGV4dD5cbiAgICAgICAgICA8L0xpbms+XG4gICAgICAgIDwvQm94PlxuICAgICAgKX1cbiAgICAgIDxCb3ggcGFkZGluZ0xlZnQ9ezF9IGZsZXhEaXJlY3Rpb249XCJjb2x1bW5cIiBnYXA9ezF9PlxuICAgICAgICB7cmVuZGVyU3RhdHVzTWVzc2FnZSgpfVxuICAgICAgPC9Cb3g+XG4gICAgPC9Cb3g+XG4gIClcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsT0FBT0EsS0FBSyxJQUFJQyxXQUFXLEVBQUVDLFNBQVMsRUFBRUMsTUFBTSxFQUFFQyxRQUFRLFFBQVEsT0FBTztBQUN2RSxTQUNFLEtBQUtDLDBEQUEwRCxFQUMvREMsUUFBUSxRQUNILGlDQUFpQztBQUN4QyxTQUFTQyxvQkFBb0IsUUFBUSx3REFBd0Q7QUFDN0YsU0FBU0MsT0FBTyxRQUFRLDZCQUE2QjtBQUNyRCxPQUFPQyxTQUFTLE1BQU0sK0JBQStCO0FBQ3JELFNBQVNDLGVBQWUsUUFBUSxnQ0FBZ0M7QUFDaEUsY0FBY0MsYUFBYSxRQUFRLG9DQUFvQztBQUN2RSxTQUFTQyxZQUFZLFFBQVEseUJBQXlCO0FBQ3RELFNBQVNDLEdBQUcsRUFBRUMsSUFBSSxFQUFFQyxJQUFJLFFBQVEsY0FBYztBQUM5QyxTQUFTQyxZQUFZLFFBQVEsK0JBQStCO0FBQzVELFNBQVNDLHVCQUF1QixRQUFRLHFCQUFxQjtBQUM3RCxTQUFTQyxRQUFRLFFBQVEsb0JBQW9CO0FBRTdDLFVBQVVDLGtCQUFrQixDQUFDO0VBQzNCQyxTQUFTLEVBQUUsQ0FBQ0MsS0FBSyxFQUFFLE1BQU0sRUFBRSxHQUFHLElBQUk7RUFDbENDLFFBQVEsRUFBRSxHQUFHLEdBQUcsSUFBSTtBQUN0QjtBQUVBLEtBQUtDLFdBQVcsR0FDWjtFQUFFQyxLQUFLLEVBQUUsVUFBVTtBQUFDLENBQUMsR0FDckI7RUFBRUEsS0FBSyxFQUFFLG1CQUFtQjtFQUFFQyxHQUFHLEVBQUUsTUFBTTtBQUFDLENBQUMsR0FDM0M7RUFBRUQsS0FBSyxFQUFFLFlBQVk7QUFBQyxDQUFDLEdBQ3ZCO0VBQUVBLEtBQUssRUFBRSxTQUFTO0VBQUVILEtBQUssRUFBRSxNQUFNO0FBQUMsQ0FBQyxHQUNuQztFQUFFRyxLQUFLLEVBQUUsT0FBTztFQUFFRSxPQUFPLEVBQUUsTUFBTTtFQUFF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