@garrix82/reactgenie-lib 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +22 -0
- package/.github/workflows/publish.yml +20 -0
- package/LICENSE.txt +201 -0
- package/README.md +621 -0
- package/babel.config.js +29 -0
- package/dist/adapters/__tests__/expo-router-adapter.test.d.ts +1 -0
- package/dist/adapters/expo-router-adapter.d.ts +16 -0
- package/dist/adapters/expo-router-adapter.js +521 -0
- package/dist/adapters/navigation-adapter.d.ts +20 -0
- package/dist/adapters/navigation-adapter.js +137 -0
- package/dist/audio-visualizer.d.ts +14 -0
- package/dist/audio-visualizer.js +123 -0
- package/dist/current-selection.d.ts +27 -0
- package/dist/current-selection.js +94 -0
- package/dist/errors.d.ts +19 -0
- package/dist/errors.js +37 -0
- package/dist/genie/DateTime.d.ts +66 -0
- package/dist/genie/DateTime.js +399 -0
- package/dist/genie/TimeDelta.d.ts +35 -0
- package/dist/genie/TimeDelta.js +169 -0
- package/dist/genie-view-wrapper.d.ts +1 -0
- package/dist/genie-view-wrapper.js +377 -0
- package/dist/hooks/__tests__/useSpeechRecognition.test.d.ts +1 -0
- package/dist/hooks/useSpeechRecognition.d.ts +28 -0
- package/dist/hooks/useSpeechRecognition.js +118 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +469 -0
- package/dist/logger.d.ts +23 -0
- package/dist/logger.js +597 -0
- package/dist/logger.remote.test.d.ts +0 -0
- package/dist/modality-provider-v2.d.ts +28 -0
- package/dist/modality-provider-v2.js +1321 -0
- package/dist/modality-provider.d.ts +22 -0
- package/dist/modality-provider.js +373 -0
- package/dist/native-visibility.d.ts +28 -0
- package/dist/native-visibility.js +50 -0
- package/dist/platform/VoiceRecognitionBar.d.ts +17 -0
- package/dist/platform/VoiceRecognitionBar.js +332 -0
- package/dist/platform/components.d.ts +32 -0
- package/dist/platform/components.js +351 -0
- package/dist/platform/events.d.ts +31 -0
- package/dist/platform/events.js +274 -0
- package/dist/platform/index.d.ts +3 -0
- package/dist/platform/index.js +39 -0
- package/dist/platform/types.d.ts +79 -0
- package/dist/platform/types.js +97 -0
- package/dist/react-decorators.d.ts +87 -0
- package/dist/react-decorators.js +368 -0
- package/dist/shared-store.d.ts +74 -0
- package/dist/shared-store.js +589 -0
- package/dist/speech-recognition/__tests__/speech-recognition-groq-transport.test.d.ts +1 -0
- package/dist/speech-recognition/__tests__/speech-recognition-native.test.d.ts +1 -0
- package/dist/speech-recognition/__tests__/speech-recognition-openai-native.test.d.ts +1 -0
- package/dist/speech-recognition/__tests__/speech-recognition-openai.test.d.ts +1 -0
- package/dist/speech-recognition/__tests__/speech-recognition-unified-import.test.d.ts +0 -0
- package/dist/speech-recognition/__tests__/speech-recognition-unified.test.d.ts +1 -0
- package/dist/speech-recognition/speech-recognition-groq.d.ts +21 -0
- package/dist/speech-recognition/speech-recognition-groq.js +409 -0
- package/dist/speech-recognition/speech-recognition-mlx.d.ts +15 -0
- package/dist/speech-recognition/speech-recognition-mlx.js +393 -0
- package/dist/speech-recognition/speech-recognition-native.d.ts +24 -0
- package/dist/speech-recognition/speech-recognition-native.js +632 -0
- package/dist/speech-recognition/speech-recognition-openai-native.d.ts +40 -0
- package/dist/speech-recognition/speech-recognition-openai-native.js +653 -0
- package/dist/speech-recognition/speech-recognition-openai.d.ts +39 -0
- package/dist/speech-recognition/speech-recognition-openai.js +718 -0
- package/dist/speech-recognition/speech-recognition-unified.d.ts +93 -0
- package/dist/speech-recognition/speech-recognition-unified.js +589 -0
- package/dist/speech-recognition/utils/groq-transcription.d.ts +41 -0
- package/dist/speech-recognition/utils/groq-transcription.js +382 -0
- package/dist/speech-recognition.d.ts +7 -0
- package/dist/speech-recognition.js +61 -0
- package/dist/voice-pipeline-telemetry.d.ts +26 -0
- package/dist/voice-pipeline-telemetry.js +15 -0
- package/garrix82-reactgenie-lib-1.3.0.tgz +0 -0
- package/metro/index.js +3 -0
- package/metro/with-genie-registry.js +47 -0
- package/package.json +111 -0
- package/scripts/dry-run.js +23 -0
- package/scripts/generate-genie-registry.js +278 -0
- package/scripts/log-file-test.js +51 -0
- package/scripts/parse.js +26 -0
- package/scripts/prompt.js +19 -0
- package/scripts/set-script.js +200 -0
- package/tsconfig.json +36 -0
|
@@ -0,0 +1,718 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = exports.OpenAISpeechRecognizer = void 0;
|
|
7
|
+
exports.getOpenAISpeechCapabilities = getOpenAISpeechCapabilities;
|
|
8
|
+
exports.isOpenAISpeechAvailable = isOpenAISpeechAvailable;
|
|
9
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
10
|
+
var _reactNative = require("react-native");
|
|
11
|
+
var _logger = _interopRequireDefault(require("../logger"));
|
|
12
|
+
var _groqTranscription = require("./utils/groq-transcription");
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
|
+
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
15
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
16
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
17
|
+
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
|
|
18
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
|
|
19
|
+
function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
20
|
+
const DEFAULT_REALTIME_MODEL = "gpt-4o-transcribe";
|
|
21
|
+
const DEFAULT_REALTIME_WEBRTC_URL = "https://api.openai.com/v1/realtime?intent=transcription";
|
|
22
|
+
const DATA_CHANNEL_OPEN_TIMEOUT_MS = 6000;
|
|
23
|
+
const SESSION_CACHE_RELEASE_DELAY_MS = 45_000;
|
|
24
|
+
const ENABLE_SESSION_CACHE = typeof process === "undefined" ? true : process.env.NODE_ENV !== "test";
|
|
25
|
+
const cachedWebRtcSession = {
|
|
26
|
+
pc: null,
|
|
27
|
+
dataChannel: null,
|
|
28
|
+
stream: null,
|
|
29
|
+
releaseTimer: null
|
|
30
|
+
};
|
|
31
|
+
function clearCachedReleaseTimer() {
|
|
32
|
+
if (!ENABLE_SESSION_CACHE) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
if (cachedWebRtcSession.releaseTimer) {
|
|
36
|
+
clearTimeout(cachedWebRtcSession.releaseTimer);
|
|
37
|
+
cachedWebRtcSession.releaseTimer = null;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function closeWebRtcSessionResources(session) {
|
|
41
|
+
if (session.dataChannel) {
|
|
42
|
+
try {
|
|
43
|
+
session.dataChannel.close();
|
|
44
|
+
} catch (error) {
|
|
45
|
+
_logger.default.warn("[OpenAI SR] close data channel warning:", error);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
if (session.pc) {
|
|
49
|
+
try {
|
|
50
|
+
session.pc.close();
|
|
51
|
+
} catch (error) {
|
|
52
|
+
_logger.default.warn("[OpenAI SR] close peer warning:", error);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (session.stream) {
|
|
56
|
+
try {
|
|
57
|
+
session.stream.getTracks().forEach(track => track.stop());
|
|
58
|
+
} catch (error) {
|
|
59
|
+
_logger.default.warn("[OpenAI SR] stop stream warning:", error);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function scheduleCachedSessionRelease() {
|
|
64
|
+
if (!ENABLE_SESSION_CACHE) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
clearCachedReleaseTimer();
|
|
68
|
+
cachedWebRtcSession.releaseTimer = setTimeout(() => {
|
|
69
|
+
closeWebRtcSessionResources(cachedWebRtcSession);
|
|
70
|
+
cachedWebRtcSession.pc = null;
|
|
71
|
+
cachedWebRtcSession.dataChannel = null;
|
|
72
|
+
cachedWebRtcSession.stream = null;
|
|
73
|
+
cachedWebRtcSession.releaseTimer = null;
|
|
74
|
+
}, SESSION_CACHE_RELEASE_DELAY_MS);
|
|
75
|
+
}
|
|
76
|
+
function hydrateFromSessionCache() {
|
|
77
|
+
if (!ENABLE_SESSION_CACHE) {
|
|
78
|
+
return {
|
|
79
|
+
pc: null,
|
|
80
|
+
dataChannel: null,
|
|
81
|
+
stream: null
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
pc: cachedWebRtcSession.pc,
|
|
86
|
+
dataChannel: cachedWebRtcSession.dataChannel,
|
|
87
|
+
stream: cachedWebRtcSession.stream
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function persistSessionCache(pc, dataChannel, stream) {
|
|
91
|
+
if (!ENABLE_SESSION_CACHE) {
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
cachedWebRtcSession.pc = pc;
|
|
95
|
+
cachedWebRtcSession.dataChannel = dataChannel;
|
|
96
|
+
cachedWebRtcSession.stream = stream;
|
|
97
|
+
}
|
|
98
|
+
const OpenAISpeechRecognizer = ({
|
|
99
|
+
shouldListen,
|
|
100
|
+
speechStatusCallback,
|
|
101
|
+
speechResultCallback,
|
|
102
|
+
speechTranslationCallback,
|
|
103
|
+
speechReadyCallback,
|
|
104
|
+
clientSecret,
|
|
105
|
+
openaiTranscriptionSessionEndpoint,
|
|
106
|
+
openaiTranslationEndpoint,
|
|
107
|
+
openaiRealtimeWebRtcUrl = DEFAULT_REALTIME_WEBRTC_URL,
|
|
108
|
+
openaiRealtimeModel = DEFAULT_REALTIME_MODEL,
|
|
109
|
+
openaiTranslationModel = "gpt-4.1-mini",
|
|
110
|
+
openaiVadEnabled = true,
|
|
111
|
+
openaiAutoStopOnVadSilence = false,
|
|
112
|
+
openaiVadThreshold = 0.7,
|
|
113
|
+
openaiVadPrefixPaddingMs = 400,
|
|
114
|
+
openaiVadSilenceDurationMs = 1000,
|
|
115
|
+
openaiVadIdleTimeoutMs = 6000,
|
|
116
|
+
openaiPrewarmOnMount = false,
|
|
117
|
+
language = "en",
|
|
118
|
+
requestContextProvider,
|
|
119
|
+
onError
|
|
120
|
+
}) => {
|
|
121
|
+
const proxyAuthToken = clientSecret;
|
|
122
|
+
const [isRecording, setIsRecording] = (0, _react.useState)(false);
|
|
123
|
+
const [sessionRecoveryToken, setSessionRecoveryToken] = (0, _react.useState)(0);
|
|
124
|
+
const cachedSessionRef = (0, _react.useRef)(hydrateFromSessionCache());
|
|
125
|
+
const pcRef = (0, _react.useRef)(cachedSessionRef.current.pc);
|
|
126
|
+
const dataChannelRef = (0, _react.useRef)(cachedSessionRef.current.dataChannel);
|
|
127
|
+
const streamRef = (0, _react.useRef)(cachedSessionRef.current.stream);
|
|
128
|
+
const sessionInitRef = (0, _react.useRef)(null);
|
|
129
|
+
const finalTranscriptRef = (0, _react.useRef)("");
|
|
130
|
+
const interimTranscriptRef = (0, _react.useRef)("");
|
|
131
|
+
const stopInFlightRef = (0, _react.useRef)(false);
|
|
132
|
+
const finalizedRef = (0, _react.useRef)(false);
|
|
133
|
+
const awaitingCommitFinalRef = (0, _react.useRef)(false);
|
|
134
|
+
const commitFinalTimeoutRef = (0, _react.useRef)(null);
|
|
135
|
+
const didPrewarmRef = (0, _react.useRef)(false);
|
|
136
|
+
const isRecordingRef = (0, _react.useRef)(false);
|
|
137
|
+
const shouldListenRef = (0, _react.useRef)(shouldListen);
|
|
138
|
+
const openaiPrewarmOnMountRef = (0, _react.useRef)(openaiPrewarmOnMount);
|
|
139
|
+
const sessionRecoveryModeRef = (0, _react.useRef)(null);
|
|
140
|
+
const sessionRecoveryInFlightRef = (0, _react.useRef)(false);
|
|
141
|
+
const suppressedChannelErrorRef = (0, _react.useRef)(null);
|
|
142
|
+
const emitError = (0, _react.useCallback)(error => {
|
|
143
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
144
|
+
_logger.default.error("[OpenAI SR] error:", err);
|
|
145
|
+
onError?.(err);
|
|
146
|
+
}, [onError]);
|
|
147
|
+
const resetTranscriptRefs = (0, _react.useCallback)(() => {
|
|
148
|
+
finalTranscriptRef.current = "";
|
|
149
|
+
interimTranscriptRef.current = "";
|
|
150
|
+
finalizedRef.current = false;
|
|
151
|
+
}, []);
|
|
152
|
+
const getBufferedTranscript = (0, _react.useCallback)(() => {
|
|
153
|
+
return (finalTranscriptRef.current || interimTranscriptRef.current).trim();
|
|
154
|
+
}, []);
|
|
155
|
+
const clearCommitFinalWait = (0, _react.useCallback)(() => {
|
|
156
|
+
awaitingCommitFinalRef.current = false;
|
|
157
|
+
if (commitFinalTimeoutRef.current) {
|
|
158
|
+
clearTimeout(commitFinalTimeoutRef.current);
|
|
159
|
+
commitFinalTimeoutRef.current = null;
|
|
160
|
+
}
|
|
161
|
+
}, []);
|
|
162
|
+
const notifyReady = (0, _react.useCallback)(ready => {
|
|
163
|
+
speechReadyCallback?.(ready);
|
|
164
|
+
}, [speechReadyCallback]);
|
|
165
|
+
const setAudioCaptureEnabled = (0, _react.useCallback)(enabled => {
|
|
166
|
+
const stream = streamRef.current;
|
|
167
|
+
if (!stream) {
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
try {
|
|
171
|
+
const tracks = typeof stream.getAudioTracks === "function" ? stream.getAudioTracks() : typeof stream.getTracks === "function" ? stream.getTracks().filter(track => track?.kind === "audio") : [];
|
|
172
|
+
tracks.forEach(track => {
|
|
173
|
+
try {
|
|
174
|
+
track.enabled = enabled;
|
|
175
|
+
} catch (error) {
|
|
176
|
+
_logger.default.warn("[OpenAI SR] toggle audio track warning:", error);
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
} catch (error) {
|
|
180
|
+
_logger.default.warn("[OpenAI SR] enumerate audio tracks warning:", error);
|
|
181
|
+
}
|
|
182
|
+
}, []);
|
|
183
|
+
const clearRealtimeInputBuffer = (0, _react.useCallback)(reason => {
|
|
184
|
+
if (dataChannelRef.current?.readyState !== "open") {
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
try {
|
|
188
|
+
dataChannelRef.current.send(JSON.stringify({
|
|
189
|
+
type: "input_audio_buffer.clear"
|
|
190
|
+
}));
|
|
191
|
+
_logger.default.debug(`[OpenAI SR] cleared input buffer (${reason})`);
|
|
192
|
+
} catch (error) {
|
|
193
|
+
_logger.default.warn("[OpenAI SR] clear input buffer warning:", error);
|
|
194
|
+
}
|
|
195
|
+
}, []);
|
|
196
|
+
const getRequestContextHeaders = (0, _react.useCallback)(() => {
|
|
197
|
+
const context = requestContextProvider?.();
|
|
198
|
+
if (!context) return {};
|
|
199
|
+
const headers = {};
|
|
200
|
+
if (context.threadId) {
|
|
201
|
+
headers["x-thread-id"] = String(context.threadId);
|
|
202
|
+
}
|
|
203
|
+
if (context.turnId) {
|
|
204
|
+
headers["x-turn-id"] = String(context.turnId);
|
|
205
|
+
}
|
|
206
|
+
if (context.sessionId !== undefined && context.sessionId !== null) {
|
|
207
|
+
headers["x-voice-session-id"] = String(context.sessionId);
|
|
208
|
+
}
|
|
209
|
+
if (context.sentryTrace) {
|
|
210
|
+
headers["sentry-trace"] = String(context.sentryTrace);
|
|
211
|
+
}
|
|
212
|
+
if (context.baggage) {
|
|
213
|
+
headers.baggage = String(context.baggage);
|
|
214
|
+
}
|
|
215
|
+
return headers;
|
|
216
|
+
}, [requestContextProvider]);
|
|
217
|
+
(0, _react.useEffect)(() => {
|
|
218
|
+
clearCachedReleaseTimer();
|
|
219
|
+
if (dataChannelRef.current?.readyState === "open") {
|
|
220
|
+
notifyReady(true);
|
|
221
|
+
}
|
|
222
|
+
}, [notifyReady]);
|
|
223
|
+
(0, _react.useEffect)(() => {
|
|
224
|
+
isRecordingRef.current = isRecording;
|
|
225
|
+
}, [isRecording]);
|
|
226
|
+
(0, _react.useEffect)(() => {
|
|
227
|
+
shouldListenRef.current = shouldListen;
|
|
228
|
+
}, [shouldListen]);
|
|
229
|
+
(0, _react.useEffect)(() => {
|
|
230
|
+
openaiPrewarmOnMountRef.current = openaiPrewarmOnMount;
|
|
231
|
+
}, [openaiPrewarmOnMount]);
|
|
232
|
+
const handleExpiredSession = (0, _react.useCallback)((channel, pc) => {
|
|
233
|
+
if (sessionRecoveryInFlightRef.current) {
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
if (dataChannelRef.current !== channel) {
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
sessionRecoveryInFlightRef.current = true;
|
|
240
|
+
suppressedChannelErrorRef.current = channel;
|
|
241
|
+
sessionRecoveryModeRef.current = shouldListenRef.current ? "listen" : openaiPrewarmOnMountRef.current ? "prewarm" : null;
|
|
242
|
+
clearCommitFinalWait();
|
|
243
|
+
resetTranscriptRefs();
|
|
244
|
+
setAudioCaptureEnabled(false);
|
|
245
|
+
sessionInitRef.current = null;
|
|
246
|
+
closeWebRtcSessionResources({
|
|
247
|
+
dataChannel: channel,
|
|
248
|
+
pc,
|
|
249
|
+
stream: streamRef.current
|
|
250
|
+
});
|
|
251
|
+
if (dataChannelRef.current === channel) {
|
|
252
|
+
dataChannelRef.current = null;
|
|
253
|
+
}
|
|
254
|
+
if (cachedWebRtcSession.dataChannel === channel) {
|
|
255
|
+
cachedWebRtcSession.dataChannel = null;
|
|
256
|
+
}
|
|
257
|
+
if (pcRef.current === pc) {
|
|
258
|
+
pcRef.current = null;
|
|
259
|
+
}
|
|
260
|
+
streamRef.current = null;
|
|
261
|
+
persistSessionCache(null, null, null);
|
|
262
|
+
setIsRecording(false);
|
|
263
|
+
notifyReady(false);
|
|
264
|
+
speechStatusCallback(false, "");
|
|
265
|
+
if (sessionRecoveryModeRef.current) {
|
|
266
|
+
setSessionRecoveryToken(value => value + 1);
|
|
267
|
+
} else {
|
|
268
|
+
sessionRecoveryInFlightRef.current = false;
|
|
269
|
+
suppressedChannelErrorRef.current = null;
|
|
270
|
+
}
|
|
271
|
+
}, [clearCommitFinalWait, notifyReady, resetTranscriptRefs, setAudioCaptureEnabled, speechStatusCallback]);
|
|
272
|
+
const buildTurnDetection = (0, _react.useCallback)(() => {
|
|
273
|
+
if (!openaiVadEnabled) return null;
|
|
274
|
+
return {
|
|
275
|
+
type: "server_vad",
|
|
276
|
+
threshold: openaiVadThreshold,
|
|
277
|
+
prefix_padding_ms: openaiVadPrefixPaddingMs,
|
|
278
|
+
silence_duration_ms: openaiVadSilenceDurationMs
|
|
279
|
+
};
|
|
280
|
+
}, [openaiVadEnabled, openaiVadThreshold, openaiVadPrefixPaddingMs, openaiVadSilenceDurationMs]);
|
|
281
|
+
const waitForDataChannelOpen = (0, _react.useCallback)(async channel => {
|
|
282
|
+
const readState = () => String(channel.readyState);
|
|
283
|
+
if (readState() === "open") {
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const start = Date.now();
|
|
287
|
+
while (Date.now() - start < DATA_CHANNEL_OPEN_TIMEOUT_MS) {
|
|
288
|
+
if (readState() === "open") {
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
await new Promise(resolve => setTimeout(resolve, 50));
|
|
292
|
+
}
|
|
293
|
+
throw new Error(`OpenAI realtime data channel did not open within ${DATA_CHANNEL_OPEN_TIMEOUT_MS}ms (state=${readState()})`);
|
|
294
|
+
}, []);
|
|
295
|
+
const translateToEnglish = (0, _react.useCallback)(async text => {
|
|
296
|
+
const input = text.trim();
|
|
297
|
+
if (!input || !openaiTranslationEndpoint) return "";
|
|
298
|
+
if (language.toLowerCase().startsWith("en")) return "";
|
|
299
|
+
const headers = _objectSpread({
|
|
300
|
+
"content-type": "application/json"
|
|
301
|
+
}, getRequestContextHeaders());
|
|
302
|
+
if (proxyAuthToken) {
|
|
303
|
+
headers.Authorization = `Bearer ${proxyAuthToken}`;
|
|
304
|
+
}
|
|
305
|
+
const response = await fetch(openaiTranslationEndpoint, {
|
|
306
|
+
method: "POST",
|
|
307
|
+
headers,
|
|
308
|
+
body: JSON.stringify({
|
|
309
|
+
text: input,
|
|
310
|
+
sourceLanguage: language,
|
|
311
|
+
model: openaiTranslationModel
|
|
312
|
+
})
|
|
313
|
+
});
|
|
314
|
+
if (!response.ok) {
|
|
315
|
+
const body = await response.text().catch(() => "");
|
|
316
|
+
throw new Error(`translation failed (${response.status}): ${body}`);
|
|
317
|
+
}
|
|
318
|
+
const payload = await response.json().catch(() => null);
|
|
319
|
+
const translated = typeof payload?.text === "string" ? payload.text.trim() : "";
|
|
320
|
+
if (translated) {
|
|
321
|
+
speechTranslationCallback?.(translated);
|
|
322
|
+
}
|
|
323
|
+
return translated;
|
|
324
|
+
}, [proxyAuthToken, language, getRequestContextHeaders, openaiTranslationEndpoint, openaiTranslationModel, speechTranslationCallback]);
|
|
325
|
+
const emitFinal = (0, _react.useCallback)(async () => {
|
|
326
|
+
if (finalizedRef.current) return;
|
|
327
|
+
finalizedRef.current = true;
|
|
328
|
+
const finalText = (finalTranscriptRef.current || interimTranscriptRef.current).trim();
|
|
329
|
+
let parseText = finalText;
|
|
330
|
+
try {
|
|
331
|
+
const translated = await translateToEnglish(finalText);
|
|
332
|
+
if (translated) {
|
|
333
|
+
parseText = translated;
|
|
334
|
+
}
|
|
335
|
+
} catch (error) {
|
|
336
|
+
_logger.default.warn("[OpenAI SR] translation failed:", error);
|
|
337
|
+
} finally {
|
|
338
|
+
speechStatusCallback(false, "");
|
|
339
|
+
if (parseText) {
|
|
340
|
+
speechResultCallback(parseText);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}, [speechResultCallback, speechStatusCallback, translateToEnglish]);
|
|
344
|
+
const finalizeAndReset = (0, _react.useCallback)(async () => {
|
|
345
|
+
clearCommitFinalWait();
|
|
346
|
+
await emitFinal();
|
|
347
|
+
resetTranscriptRefs();
|
|
348
|
+
}, [clearCommitFinalWait, emitFinal, resetTranscriptRefs]);
|
|
349
|
+
const handleRealtimeMessage = (0, _react.useCallback)(payload => {
|
|
350
|
+
const type = String(payload?.type || "");
|
|
351
|
+
const acceptsTranscript = isRecordingRef.current || awaitingCommitFinalRef.current;
|
|
352
|
+
if (!acceptsTranscript) {
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
const shouldPublishInterim = isRecordingRef.current;
|
|
356
|
+
const delta = extractDeltaText(payload);
|
|
357
|
+
const completed = extractCompletedText(payload);
|
|
358
|
+
if (delta) {
|
|
359
|
+
interimTranscriptRef.current = (0, _groqTranscription.mergeTranscriptParts)(finalTranscriptRef.current, delta);
|
|
360
|
+
if (shouldPublishInterim) {
|
|
361
|
+
speechStatusCallback(true, interimTranscriptRef.current);
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
if (completed) {
|
|
365
|
+
finalTranscriptRef.current = (0, _groqTranscription.mergeTranscriptParts)(finalTranscriptRef.current, completed);
|
|
366
|
+
interimTranscriptRef.current = finalTranscriptRef.current;
|
|
367
|
+
if (shouldPublishInterim) {
|
|
368
|
+
speechStatusCallback(true, finalTranscriptRef.current);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
const looksCompleted = !!completed || type.includes("completed");
|
|
372
|
+
if (awaitingCommitFinalRef.current && looksCompleted && getBufferedTranscript()) {
|
|
373
|
+
finalizeAndReset().catch(error => emitError(error));
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
if (openaiAutoStopOnVadSilence && type === "input_audio_buffer.speech_stopped") {
|
|
377
|
+
const pauseTranscript = getBufferedTranscript();
|
|
378
|
+
speechStatusCallback(false, pauseTranscript);
|
|
379
|
+
}
|
|
380
|
+
}, [emitError, finalizeAndReset, getBufferedTranscript, openaiAutoStopOnVadSilence, speechStatusCallback]);
|
|
381
|
+
const startWebRtcSession = (0, _react.useCallback)(async token => {
|
|
382
|
+
clearCachedReleaseTimer();
|
|
383
|
+
if (typeof RTCPeerConnection === "undefined") {
|
|
384
|
+
throw new Error("RTCPeerConnection is unavailable on web runtime");
|
|
385
|
+
}
|
|
386
|
+
if (!navigator.mediaDevices?.getUserMedia) {
|
|
387
|
+
throw new Error("navigator.mediaDevices.getUserMedia is unavailable");
|
|
388
|
+
}
|
|
389
|
+
const stream = await navigator.mediaDevices.getUserMedia({
|
|
390
|
+
audio: {
|
|
391
|
+
echoCancellation: true,
|
|
392
|
+
noiseSuppression: true,
|
|
393
|
+
autoGainControl: true
|
|
394
|
+
}
|
|
395
|
+
});
|
|
396
|
+
streamRef.current = stream;
|
|
397
|
+
persistSessionCache(pcRef.current, dataChannelRef.current, streamRef.current);
|
|
398
|
+
setAudioCaptureEnabled(false);
|
|
399
|
+
const pc = new RTCPeerConnection();
|
|
400
|
+
pcRef.current = pc;
|
|
401
|
+
persistSessionCache(pcRef.current, dataChannelRef.current, streamRef.current);
|
|
402
|
+
stream.getTracks().forEach(track => pc.addTrack(track, stream));
|
|
403
|
+
const dataChannel = pc.createDataChannel("oai-events");
|
|
404
|
+
dataChannelRef.current = dataChannel;
|
|
405
|
+
persistSessionCache(pcRef.current, dataChannelRef.current, streamRef.current);
|
|
406
|
+
dataChannel.onopen = () => {
|
|
407
|
+
notifyReady(true);
|
|
408
|
+
};
|
|
409
|
+
dataChannel.onmessage = event => {
|
|
410
|
+
try {
|
|
411
|
+
const payload = JSON.parse(String(event.data || "{}"));
|
|
412
|
+
if (payload?.type === "error") {
|
|
413
|
+
const message = String(payload?.error?.message || "OpenAI realtime error");
|
|
414
|
+
if (isCommitBufferTooSmallError(message)) {
|
|
415
|
+
// Ignore commit buffer-too-small errors for low-latency fast-stop path.
|
|
416
|
+
return;
|
|
417
|
+
}
|
|
418
|
+
if (isSessionDurationLimitError(message)) {
|
|
419
|
+
handleExpiredSession(dataChannel, pc);
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
throw new Error(message);
|
|
423
|
+
}
|
|
424
|
+
handleRealtimeMessage(payload);
|
|
425
|
+
} catch (error) {
|
|
426
|
+
emitError(error);
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
dataChannel.onerror = () => {
|
|
430
|
+
if (suppressedChannelErrorRef.current === dataChannel) {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
notifyReady(false);
|
|
434
|
+
emitError(new Error("OpenAI realtime data channel error"));
|
|
435
|
+
};
|
|
436
|
+
dataChannel.onclose = () => {
|
|
437
|
+
if (dataChannelRef.current === dataChannel) {
|
|
438
|
+
dataChannelRef.current = null;
|
|
439
|
+
}
|
|
440
|
+
if (cachedWebRtcSession.dataChannel === dataChannel) {
|
|
441
|
+
cachedWebRtcSession.dataChannel = null;
|
|
442
|
+
}
|
|
443
|
+
notifyReady(false);
|
|
444
|
+
};
|
|
445
|
+
const offer = await pc.createOffer();
|
|
446
|
+
await pc.setLocalDescription(offer);
|
|
447
|
+
const response = await fetch(openaiRealtimeWebRtcUrl, {
|
|
448
|
+
method: "POST",
|
|
449
|
+
headers: {
|
|
450
|
+
Authorization: `Bearer ${token}`,
|
|
451
|
+
"content-type": "application/sdp"
|
|
452
|
+
},
|
|
453
|
+
body: offer.sdp || ""
|
|
454
|
+
});
|
|
455
|
+
if (!response.ok) {
|
|
456
|
+
const body = await response.text().catch(() => "");
|
|
457
|
+
throw new Error(`webrtc negotiation failed (${response.status}): ${body}`);
|
|
458
|
+
}
|
|
459
|
+
const answerSdp = await response.text();
|
|
460
|
+
await pc.setRemoteDescription({
|
|
461
|
+
type: "answer",
|
|
462
|
+
sdp: answerSdp
|
|
463
|
+
});
|
|
464
|
+
await waitForDataChannelOpen(dataChannel);
|
|
465
|
+
}, [emitError, handleRealtimeMessage, notifyReady, openaiRealtimeWebRtcUrl, setAudioCaptureEnabled, waitForDataChannelOpen]);
|
|
466
|
+
const getEphemeralToken = (0, _react.useCallback)(async () => {
|
|
467
|
+
const headers = _objectSpread({
|
|
468
|
+
"content-type": "application/json"
|
|
469
|
+
}, getRequestContextHeaders());
|
|
470
|
+
if (proxyAuthToken) {
|
|
471
|
+
headers.Authorization = `Bearer ${proxyAuthToken}`;
|
|
472
|
+
}
|
|
473
|
+
const response = await fetch(openaiTranscriptionSessionEndpoint, {
|
|
474
|
+
method: "POST",
|
|
475
|
+
headers,
|
|
476
|
+
body: JSON.stringify({
|
|
477
|
+
input_audio_format: "pcm16",
|
|
478
|
+
input_audio_transcription: {
|
|
479
|
+
model: openaiRealtimeModel,
|
|
480
|
+
language
|
|
481
|
+
},
|
|
482
|
+
turn_detection: buildTurnDetection() || undefined
|
|
483
|
+
})
|
|
484
|
+
});
|
|
485
|
+
if (!response.ok) {
|
|
486
|
+
const body = await response.text().catch(() => "");
|
|
487
|
+
throw new Error(`transcription session request failed (${response.status}): ${body}`);
|
|
488
|
+
}
|
|
489
|
+
const payload = await response.json().catch(() => ({}));
|
|
490
|
+
const token = payload?.client_secret?.value || payload?.client_secret || payload?.value || "";
|
|
491
|
+
if (!token) {
|
|
492
|
+
throw new Error("No ephemeral token returned from transcription session endpoint");
|
|
493
|
+
}
|
|
494
|
+
return token;
|
|
495
|
+
}, [buildTurnDetection, getRequestContextHeaders, proxyAuthToken, language, openaiRealtimeModel, openaiTranscriptionSessionEndpoint]);
|
|
496
|
+
const hasReusableSession = (0, _react.useCallback)(() => {
|
|
497
|
+
return !!pcRef.current && !!streamRef.current && dataChannelRef.current?.readyState === "open";
|
|
498
|
+
}, []);
|
|
499
|
+
const ensureWebRtcSession = (0, _react.useCallback)(async () => {
|
|
500
|
+
if (hasReusableSession()) {
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
if (sessionInitRef.current) {
|
|
504
|
+
await sessionInitRef.current;
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
sessionInitRef.current = (async () => {
|
|
508
|
+
const token = await getEphemeralToken();
|
|
509
|
+
await startWebRtcSession(token);
|
|
510
|
+
})();
|
|
511
|
+
try {
|
|
512
|
+
await sessionInitRef.current;
|
|
513
|
+
} finally {
|
|
514
|
+
sessionInitRef.current = null;
|
|
515
|
+
}
|
|
516
|
+
}, [getEphemeralToken, hasReusableSession, startWebRtcSession]);
|
|
517
|
+
const cleanup = (0, _react.useCallback)(async () => {
|
|
518
|
+
sessionInitRef.current = null;
|
|
519
|
+
clearCachedReleaseTimer();
|
|
520
|
+
closeWebRtcSessionResources({
|
|
521
|
+
dataChannel: dataChannelRef.current,
|
|
522
|
+
pc: pcRef.current,
|
|
523
|
+
stream: streamRef.current
|
|
524
|
+
});
|
|
525
|
+
dataChannelRef.current = null;
|
|
526
|
+
pcRef.current = null;
|
|
527
|
+
streamRef.current = null;
|
|
528
|
+
persistSessionCache(null, null, null);
|
|
529
|
+
}, []);
|
|
530
|
+
(0, _react.useEffect)(() => {
|
|
531
|
+
if (sessionRecoveryToken === 0 || !sessionRecoveryModeRef.current) {
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
let cancelled = false;
|
|
535
|
+
const recoveryMode = sessionRecoveryModeRef.current;
|
|
536
|
+
(async () => {
|
|
537
|
+
try {
|
|
538
|
+
await ensureWebRtcSession();
|
|
539
|
+
if (cancelled) {
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
if (recoveryMode === "listen" && shouldListenRef.current) {
|
|
543
|
+
setAudioCaptureEnabled(true);
|
|
544
|
+
setIsRecording(true);
|
|
545
|
+
}
|
|
546
|
+
notifyReady(dataChannelRef.current?.readyState === "open");
|
|
547
|
+
} catch (error) {
|
|
548
|
+
if (cancelled) {
|
|
549
|
+
return;
|
|
550
|
+
}
|
|
551
|
+
emitError(error);
|
|
552
|
+
setAudioCaptureEnabled(false);
|
|
553
|
+
await cleanup();
|
|
554
|
+
setIsRecording(false);
|
|
555
|
+
notifyReady(false);
|
|
556
|
+
speechStatusCallback(false, "");
|
|
557
|
+
} finally {
|
|
558
|
+
if (cancelled) {
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
sessionRecoveryModeRef.current = null;
|
|
562
|
+
sessionRecoveryInFlightRef.current = false;
|
|
563
|
+
suppressedChannelErrorRef.current = null;
|
|
564
|
+
}
|
|
565
|
+
})();
|
|
566
|
+
return () => {
|
|
567
|
+
cancelled = true;
|
|
568
|
+
};
|
|
569
|
+
}, [cleanup, emitError, ensureWebRtcSession, notifyReady, sessionRecoveryToken, setAudioCaptureEnabled, speechStatusCallback]);
|
|
570
|
+
const startRecording = (0, _react.useCallback)(async () => {
|
|
571
|
+
if (isRecording || stopInFlightRef.current || sessionRecoveryInFlightRef.current) {
|
|
572
|
+
return;
|
|
573
|
+
}
|
|
574
|
+
try {
|
|
575
|
+
clearCommitFinalWait();
|
|
576
|
+
notifyReady(false);
|
|
577
|
+
resetTranscriptRefs();
|
|
578
|
+
const reusingWarmSession = hasReusableSession();
|
|
579
|
+
await ensureWebRtcSession();
|
|
580
|
+
if (reusingWarmSession) {
|
|
581
|
+
clearRealtimeInputBuffer("start_recording");
|
|
582
|
+
}
|
|
583
|
+
if (!shouldListenRef.current) {
|
|
584
|
+
setAudioCaptureEnabled(false);
|
|
585
|
+
notifyReady(dataChannelRef.current?.readyState === "open");
|
|
586
|
+
return;
|
|
587
|
+
}
|
|
588
|
+
setAudioCaptureEnabled(true);
|
|
589
|
+
setIsRecording(true);
|
|
590
|
+
notifyReady(dataChannelRef.current?.readyState === "open");
|
|
591
|
+
} catch (error) {
|
|
592
|
+
emitError(error);
|
|
593
|
+
setAudioCaptureEnabled(false);
|
|
594
|
+
await cleanup();
|
|
595
|
+
setIsRecording(false);
|
|
596
|
+
notifyReady(false);
|
|
597
|
+
speechStatusCallback(false, "");
|
|
598
|
+
}
|
|
599
|
+
}, [cleanup, clearRealtimeInputBuffer, clearCommitFinalWait, ensureWebRtcSession, emitError, hasReusableSession, isRecording, notifyReady, resetTranscriptRefs, setAudioCaptureEnabled, speechStatusCallback]);
|
|
600
|
+
const stopRecording = (0, _react.useCallback)(async () => {
|
|
601
|
+
if (!isRecording || stopInFlightRef.current) return;
|
|
602
|
+
stopInFlightRef.current = true;
|
|
603
|
+
setIsRecording(false);
|
|
604
|
+
setAudioCaptureEnabled(false);
|
|
605
|
+
notifyReady(false);
|
|
606
|
+
try {
|
|
607
|
+
if (dataChannelRef.current?.readyState === "open") {
|
|
608
|
+
dataChannelRef.current.send(JSON.stringify({
|
|
609
|
+
type: "input_audio_buffer.commit"
|
|
610
|
+
}));
|
|
611
|
+
}
|
|
612
|
+
const buffered = getBufferedTranscript();
|
|
613
|
+
if (buffered) {
|
|
614
|
+
await finalizeAndReset();
|
|
615
|
+
} else {
|
|
616
|
+
speechStatusCallback(false, "");
|
|
617
|
+
awaitingCommitFinalRef.current = true;
|
|
618
|
+
if (commitFinalTimeoutRef.current) {
|
|
619
|
+
clearTimeout(commitFinalTimeoutRef.current);
|
|
620
|
+
}
|
|
621
|
+
// Short fallback: if no post-commit transcript arrives, reset state and exit.
|
|
622
|
+
commitFinalTimeoutRef.current = setTimeout(() => {
|
|
623
|
+
if (!awaitingCommitFinalRef.current) return;
|
|
624
|
+
clearCommitFinalWait();
|
|
625
|
+
resetTranscriptRefs();
|
|
626
|
+
}, 1500);
|
|
627
|
+
}
|
|
628
|
+
} catch (error) {
|
|
629
|
+
emitError(error);
|
|
630
|
+
speechStatusCallback(false, "");
|
|
631
|
+
} finally {
|
|
632
|
+
stopInFlightRef.current = false;
|
|
633
|
+
notifyReady(false);
|
|
634
|
+
}
|
|
635
|
+
}, [emitError, finalizeAndReset, getBufferedTranscript, isRecording, notifyReady, clearCommitFinalWait, resetTranscriptRefs, setAudioCaptureEnabled, speechStatusCallback]);
|
|
636
|
+
(0, _react.useEffect)(() => {
|
|
637
|
+
if (!openaiPrewarmOnMount || didPrewarmRef.current) {
|
|
638
|
+
return;
|
|
639
|
+
}
|
|
640
|
+
didPrewarmRef.current = true;
|
|
641
|
+
ensureWebRtcSession().then(() => {
|
|
642
|
+
notifyReady(true);
|
|
643
|
+
}).catch(error => {
|
|
644
|
+
emitError(error);
|
|
645
|
+
});
|
|
646
|
+
}, [emitError, ensureWebRtcSession, notifyReady, openaiPrewarmOnMount]);
|
|
647
|
+
(0, _react.useEffect)(() => {
|
|
648
|
+
if (shouldListen && !isRecording) {
|
|
649
|
+
startRecording();
|
|
650
|
+
} else if (!shouldListen && isRecording) {
|
|
651
|
+
stopRecording();
|
|
652
|
+
}
|
|
653
|
+
}, [isRecording, shouldListen, startRecording, stopRecording]);
|
|
654
|
+
(0, _react.useEffect)(() => {
|
|
655
|
+
return () => {
|
|
656
|
+
notifyReady(false);
|
|
657
|
+
clearCommitFinalWait();
|
|
658
|
+
setAudioCaptureEnabled(false);
|
|
659
|
+
if (ENABLE_SESSION_CACHE && openaiPrewarmOnMountRef.current && !isRecordingRef.current) {
|
|
660
|
+
scheduleCachedSessionRelease();
|
|
661
|
+
} else {
|
|
662
|
+
cleanup().catch(() => undefined);
|
|
663
|
+
}
|
|
664
|
+
};
|
|
665
|
+
}, [cleanup, notifyReady, clearCommitFinalWait, setAudioCaptureEnabled]);
|
|
666
|
+
return /*#__PURE__*/_react.default.createElement(_reactNative.View, null);
|
|
667
|
+
};
|
|
668
|
+
exports.OpenAISpeechRecognizer = OpenAISpeechRecognizer;
|
|
669
|
+
function extractDeltaText(payload) {
|
|
670
|
+
const type = String(payload?.type || "");
|
|
671
|
+
if (!type.includes("delta")) return "";
|
|
672
|
+
const candidates = [payload?.delta, payload?.text_delta, payload?.transcript_delta, payload?.item?.content?.[0]?.transcript];
|
|
673
|
+
for (const value of candidates) {
|
|
674
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
675
|
+
}
|
|
676
|
+
return "";
|
|
677
|
+
}
|
|
678
|
+
function extractCompletedText(payload) {
|
|
679
|
+
const type = String(payload?.type || "");
|
|
680
|
+
if (!type.includes("completed")) return "";
|
|
681
|
+
const candidates = [payload?.transcript, payload?.text, payload?.item?.content?.[0]?.transcript, payload?.item?.transcript];
|
|
682
|
+
for (const value of candidates) {
|
|
683
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
684
|
+
}
|
|
685
|
+
return "";
|
|
686
|
+
}
|
|
687
|
+
function extractItemId(payload) {
|
|
688
|
+
const candidates = [payload?.item_id, payload?.item?.id];
|
|
689
|
+
for (const value of candidates) {
|
|
690
|
+
if (typeof value === "string" && value.trim()) {
|
|
691
|
+
return value.trim();
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
return null;
|
|
695
|
+
}
|
|
696
|
+
function isCommitBufferTooSmallError(message) {
|
|
697
|
+
const normalized = message.toLowerCase();
|
|
698
|
+
return normalized.includes("input audio buffer") && normalized.includes("buffer too small");
|
|
699
|
+
}
|
|
700
|
+
function isSessionDurationLimitError(message) {
|
|
701
|
+
const normalized = message.toLowerCase();
|
|
702
|
+
return normalized.includes("session") && (normalized.includes("maximum duration") || normalized.includes("max duration"));
|
|
703
|
+
}
|
|
704
|
+
function isOpenAISpeechAvailable() {
|
|
705
|
+
if (_reactNative.Platform.OS !== "web") return false;
|
|
706
|
+
if (typeof window === "undefined") return false;
|
|
707
|
+
return typeof navigator !== "undefined" && !!navigator.mediaDevices?.getUserMedia && typeof RTCPeerConnection !== "undefined";
|
|
708
|
+
}
|
|
709
|
+
function getOpenAISpeechCapabilities() {
|
|
710
|
+
return {
|
|
711
|
+
available: isOpenAISpeechAvailable(),
|
|
712
|
+
platform: _reactNative.Platform.OS,
|
|
713
|
+
supportsServerVAD: true,
|
|
714
|
+
transport: "webrtc"
|
|
715
|
+
};
|
|
716
|
+
}
|
|
717
|
+
var _default = exports.default = OpenAISpeechRecognizer;
|
|
718
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfcmVhY3ROYXRpdmUiLCJfbG9nZ2VyIiwiX2ludGVyb3BSZXF1aXJlRGVmYXVsdCIsIl9ncm9xVHJhbnNjcmlwdGlvbiIsImUiLCJfX2VzTW9kdWxlIiwiZGVmYXVsdCIsInQiLCJXZWFrTWFwIiwiciIsIm4iLCJvIiwiaSIsImYiLCJfX3Byb3RvX18iLCJoYXMiLCJnZXQiLCJzZXQiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsIm93bktleXMiLCJrZXlzIiwiZ2V0T3duUHJvcGVydHlTeW1ib2xzIiwiZmlsdGVyIiwiZW51bWVyYWJsZSIsInB1c2giLCJhcHBseSIsIl9vYmplY3RTcHJlYWQiLCJhcmd1bWVudHMiLCJsZW5ndGgiLCJmb3JFYWNoIiwiX2RlZmluZVByb3BlcnR5IiwiZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9ycyIsImRlZmluZVByb3BlcnRpZXMiLCJfdG9Qcm9wZXJ0eUtleSIsInZhbHVlIiwiY29uZmlndXJhYmxlIiwid3JpdGFibGUiLCJfdG9QcmltaXRpdmUiLCJTeW1ib2wiLCJ0b1ByaW1pdGl2ZSIsIlR5cGVFcnJvciIsIlN0cmluZyIsIk51bWJlciIsIkRFRkFVTFRfUkVBTFRJTUVfTU9ERUwiLCJERUZBVUxUX1JFQUxUSU1FX1dFQlJUQ19VUkwiLCJEQVRBX0NIQU5ORUxfT1BFTl9USU1FT1VUX01TIiwiU0VTU0lPTl9DQUNIRV9SRUxFQVNFX0RFTEFZX01TIiwiRU5BQkxFX1NFU1NJT05fQ0FDSEUiLCJwcm9jZXNzIiwiZW52IiwiTk9ERV9FTlYiLCJjYWNoZWRXZWJSdGNTZXNzaW9uIiwicGMiLCJkYXRhQ2hhbm5lbCIsInN0cmVhbSIsInJlbGVhc2VUaW1lciIsImNsZWFyQ2FjaGVkUmVsZWFzZVRpbWVyIiwiY2xlYXJUaW1lb3V0IiwiY2xvc2VXZWJSdGNTZXNzaW9uUmVzb3VyY2VzIiwic2Vzc2lvbiIsImNsb3NlIiwiZXJyb3IiLCJsb2dnZXIiLCJ3YXJuIiwiZ2V0VHJhY2tzIiwidHJhY2siLCJzdG9wIiwic2NoZWR1bGVDYWNoZWRTZXNzaW9uUmVsZWFzZSIsInNldFRpbWVvdXQiLCJoeWRyYXRlRnJvbVNlc3Npb25DYWNoZSIsInBlcnNpc3RTZXNzaW9uQ2FjaGUiLCJPcGVuQUlTcGVlY2hSZWNvZ25pemVyIiwic2hvdWxkTGlzdGVuIiwic3BlZWNoU3RhdHVzQ2FsbGJhY2siLCJzcGVlY2hSZXN1bHRDYWxsYmFjayIsInNwZWVjaFRyYW5zbGF0aW9uQ2FsbGJhY2siLCJzcGVlY2hSZWFkeUNhbGxiYWNrIiwiY2xpZW50U2VjcmV0Iiwib3BlbmFpVHJhbnNjcmlwdGlvblNlc3Npb25FbmRwb2ludCIsIm9wZW5haVRyYW5zbGF0aW9uRW5kcG9pbnQiLCJvcGVuYWlSZWFsdGltZVdlYlJ0Y1VybCIsIm9wZW5haVJlYWx0aW1lTW9kZWwiLCJvcGVuYWlUcmFuc2xhdGlvbk1vZGVsIiwib3BlbmFpVmFkRW5hYmxlZCIsIm9wZW5haUF1dG9TdG9wT25WYWRTaWxlbmNlIiwib3BlbmFpVmFkVGhyZXNob2xkIiwib3BlbmFpVmFkUHJlZml4UGFkZGluZ01zIiwib3BlbmFpVmFkU2lsZW5jZUR1cmF0aW9uTXMiLCJvcGVuYWlWYWRJZGxlVGltZW91dE1zIiwib3BlbmFpUHJld2FybU9uTW91bnQiLCJsYW5ndWFnZSIsInJlcXVlc3RDb250ZXh0UHJvdmlkZXIiLCJvbkVycm9yIiwicHJveHlBdXRoVG9rZW4iLCJpc1JlY29yZGluZyIsInNldElzUmVjb3JkaW5nIiwidXNlU3RhdGUiLCJzZXNzaW9uUmVjb3ZlcnlUb2tlbiIsInNldFNlc3Npb25SZWNvdmVyeVRva2VuIiwiY2FjaGVkU2Vzc2lvblJlZiIsInVzZVJlZiIsInBjUmVmIiwiY3VycmVudCIsImRhdGFDaGFubmVsUmVmIiwic3RyZWFtUmVmIiwic2Vzc2lvbkluaXRSZWYiLCJmaW5hbFRyYW5zY3JpcHRSZWYiLCJpbnRlcmltVHJhbnNjcmlwdFJlZiIsInN0b3BJbkZsaWdodFJlZiIsImZpbmFsaXplZFJlZiIsImF3YWl0aW5nQ29tbWl0RmluYWxSZWYiLCJjb21taXRGaW5hbFRpbWVvdXRSZWYiLCJkaWRQcmV3YXJtUmVmIiwiaXNSZWNvcmRpbmdSZWYiLCJzaG91bGRMaXN0ZW5SZWYiLCJvcGVuYWlQcmV3YXJtT25Nb3VudFJlZiIsInNlc3Npb25SZWNvdmVyeU1vZGVSZWYiLCJzZXNzaW9uUmVjb3ZlcnlJbkZsaWdodFJlZiIsInN1cHByZXNzZWRDaGFubmVsRXJyb3JSZWYiLCJlbWl0RXJyb3IiLCJ1c2VDYWxsYmFjayIsImVyciIsIkVycm9yIiwicmVzZXRUcmFuc2NyaXB0UmVmcyIsImdldEJ1ZmZlcmVkVHJhbnNjcmlwdCIsInRyaW0iLCJjbGVhckNvbW1pdEZpbmFsV2FpdCIsIm5vdGlmeVJlYWR5IiwicmVhZHkiLCJzZXRBdWRpb0NhcHR1cmVFbmFibGVkIiwiZW5hYmxlZCIsInRyYWNrcyIsImdldEF1ZGlvVHJhY2tzIiwia2luZCIsImNsZWFyUmVhbHRpbWVJbnB1dEJ1ZmZlciIsInJlYXNvbiIsInJlYWR5U3RhdGUiLCJzZW5kIiwiSlNPTiIsInN0cmluZ2lmeSIsInR5cGUiLCJkZWJ1ZyIsImdldFJlcXVlc3RDb250ZXh0SGVhZGVycyIsImNvbnRleHQiLCJoZWFkZXJzIiwidGhyZWFkSWQiLCJ0dXJuSWQiLCJzZXNzaW9uSWQiLCJ1bmRlZmluZWQiLCJzZW50cnlUcmFjZSIsImJhZ2dhZ2UiLCJ1c2VFZmZlY3QiLCJoYW5kbGVFeHBpcmVkU2Vzc2lvbiIsImNoYW5uZWwiLCJidWlsZFR1cm5EZXRlY3Rpb24iLCJ0aHJlc2hvbGQiLCJwcmVmaXhfcGFkZGluZ19tcyIsInNpbGVuY2VfZHVyYXRpb25fbXMiLCJ3YWl0Rm9yRGF0YUNoYW5uZWxPcGVuIiwicmVhZFN0YXRlIiwic3RhcnQiLCJEYXRlIiwibm93IiwiUHJvbWlzZSIsInJlc29sdmUiLCJ0cmFuc2xhdGVUb0VuZ2xpc2giLCJ0ZXh0IiwiaW5wdXQiLCJ0b0xvd2VyQ2FzZSIsInN0YXJ0c1dpdGgiLCJBdXRob3JpemF0aW9uIiwicmVzcG9uc2UiLCJmZXRjaCIsIm1ldGhvZCIsImJvZHkiLCJzb3VyY2VMYW5ndWFnZSIsIm1vZGVsIiwib2siLCJjYXRjaCIsInN0YXR1cyIsInBheWxvYWQiLCJqc29uIiwidHJhbnNsYXRlZCIsImVtaXRGaW5hbCIsImZpbmFsVGV4dCIsInBhcnNlVGV4dCIsImZpbmFsaXplQW5kUmVzZXQiLCJoYW5kbGVSZWFsdGltZU1lc3NhZ2UiLCJhY2NlcHRzVHJhbnNjcmlwdCIsInNob3VsZFB1Ymxpc2hJbnRlcmltIiwiZGVsdGEiLCJleHRyYWN0RGVsdGFUZXh0IiwiY29tcGxldGVkIiwiZXh0cmFjdENvbXBsZXRlZFRleHQiLCJtZXJnZVRyYW5zY3JpcHRQYXJ0cyIsImxvb2tzQ29tcGxldGVkIiwiaW5jbHVkZXMiLCJwYXVzZVRyYW5zY3JpcHQiLCJzdGFydFdlYlJ0Y1Nlc3Npb24iLCJ0b2tlbiIsIlJUQ1BlZXJDb25uZWN0aW9uIiwibmF2aWdhdG9yIiwibWVkaWFEZXZpY2VzIiwiZ2V0VXNlck1lZGlhIiwiYXVkaW8iLCJlY2hvQ2FuY2VsbGF0aW9uIiwibm9pc2VTdXBwcmVzc2lvbiIsImF1dG9HYWluQ29udHJvbCIsImFkZFRyYWNrIiwiY3JlYXRlRGF0YUNoYW5uZWwiLCJvbm9wZW4iLCJvbm1lc3NhZ2UiLCJldmVudCIsInBhcnNlIiwiZGF0YSIsIm1lc3NhZ2UiLCJpc0NvbW1pdEJ1ZmZlclRvb1NtYWxsRXJyb3IiLCJpc1Nlc3Npb25EdXJhdGlvbkxpbWl0RXJyb3IiLCJvbmVycm9yIiwib25jbG9zZSIsIm9mZmVyIiwiY3JlYXRlT2ZmZXIiLCJzZXRMb2NhbERlc2NyaXB0aW9uIiwic2RwIiwiYW5zd2VyU2RwIiwic2V0UmVtb3RlRGVzY3JpcHRpb24iLCJnZXRFcGhlbWVyYWxUb2tlbiIsImlucHV0X2F1ZGlvX2Zvcm1hdCIsImlucHV0X2F1ZGlvX3RyYW5zY3JpcHRpb24iLCJ0dXJuX2RldGVjdGlvbiIsImNsaWVudF9zZWNyZXQiLCJoYXNSZXVzYWJsZVNlc3Npb24iLCJlbnN1cmVXZWJSdGNTZXNzaW9uIiwiY2xlYW51cCIsImNhbmNlbGxlZCIsInJlY292ZXJ5TW9kZSIsInN0YXJ0UmVjb3JkaW5nIiwicmV1c2luZ1dhcm1TZXNzaW9uIiwic3RvcFJlY29yZGluZyIsImJ1ZmZlcmVkIiwidGhlbiIsImNyZWF0ZUVsZW1lbnQiLCJWaWV3IiwiZXhwb3J0cyIsImNhbmRpZGF0ZXMiLCJ0ZXh0X2RlbHRhIiwidHJhbnNjcmlwdF9kZWx0YSIsIml0ZW0iLCJjb250ZW50IiwidHJhbnNjcmlwdCIsImV4dHJhY3RJdGVtSWQiLCJpdGVtX2lkIiwiaWQiLCJub3JtYWxpemVkIiwiaXNPcGVuQUlTcGVlY2hBdmFpbGFibGUiLCJQbGF0Zm9ybSIsIk9TIiwid2luZG93IiwiZ2V0T3BlbkFJU3BlZWNoQ2FwYWJpbGl0aWVzIiwiYXZhaWxhYmxlIiwicGxhdGZvcm0iLCJzdXBwb3J0c1NlcnZlclZBRCIsInRyYW5zcG9ydCIsIl9kZWZhdWx0Il0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NwZWVjaC1yZWNvZ25pdGlvbi9zcGVlY2gtcmVjb2duaXRpb24tb3BlbmFpLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgUmVhY3QsIHsgdXNlQ2FsbGJhY2ssIHVzZUVmZmVjdCwgdXNlUmVmLCB1c2VTdGF0ZSB9IGZyb20gXCJyZWFjdFwiO1xuaW1wb3J0IHsgUGxhdGZvcm0sIFZpZXcgfSBmcm9tIFwicmVhY3QtbmF0aXZlXCI7XG5pbXBvcnQgbG9nZ2VyIGZyb20gXCIuLi9sb2dnZXJcIjtcbmltcG9ydCB7IG1lcmdlVHJhbnNjcmlwdFBhcnRzIH0gZnJvbSBcIi4vdXRpbHMvZ3JvcS10cmFuc2NyaXB0aW9uXCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgT3BlbkFJU3BlZWNoUmVjb2duaXplclByb3BzIHtcbiAgc2hvdWxkTGlzdGVuOiBib29sZWFuO1xuICBzcGVlY2hTdGF0dXNDYWxsYmFjazogKHN0YXR1czogYm9vbGVhbiwgdHJhbnNjcmlwdDogc3RyaW5nKSA9PiB2b2lkO1xuICBzcGVlY2hSZXN1bHRDYWxsYmFjazogKHJlc3VsdDogc3RyaW5nKSA9PiB2b2lkO1xuICBzcGVlY2hUcmFuc2xhdGlvbkNhbGxiYWNrPzogKHRyYW5zbGF0aW9uOiBzdHJpbmcpID0+IHZvaWQ7XG4gIHNwZWVjaFJlYWR5Q2FsbGJhY2s/OiAocmVhZHk6IGJvb2xlYW4pID0+IHZvaWQ7XG4gIGNsaWVudFNlY3JldD86IHN0cmluZztcbiAgb3BlbmFpVHJhbnNjcmlwdGlvblNlc3Npb25FbmRwb2ludDogc3RyaW5nO1xuICBvcGVuYWlUcmFuc2xhdGlvbkVuZHBvaW50Pzogc3RyaW5nO1xuICBvcGVuYWlSZWFsdGltZVdlYlJ0Y1VybD86IHN0cmluZztcbiAgb3BlbmFpUmVhbHRpbWVNb2RlbD86IFwiZ3B0LTRvLXRyYW5zY3JpYmVcIiB8IFwiZ3B0LTRvLW1pbmktdHJhbnNjcmliZVwiO1xuICBvcGVuYWlUcmFuc2xhdGlvbk1vZGVsPzogc3RyaW5nO1xuICBvcGVuYWlWYWRFbmFibGVkPzogYm9vbGVhbjtcbiAgb3BlbmFpQXV0b1N0b3BPblZhZFNpbGVuY2U/OiBib29sZWFuO1xuICBvcGVuYWlWYWRUaHJlc2hvbGQ/OiBudW1iZXI7XG4gIG9wZW5haVZhZFByZWZpeFBhZGRpbmdNcz86IG51bWJlcjtcbiAgb3BlbmFpVmFkU2lsZW5jZUR1cmF0aW9uTXM/OiBudW1iZXI7XG4gIG9wZW5haVZhZElkbGVUaW1lb3V0TXM/OiBudW1iZXI7XG4gIG9wZW5haVByZXdhcm1Pbk1vdW50PzogYm9vbGVhbjtcbiAgbGFuZ3VhZ2U/OiBzdHJpbmc7XG4gIHJlcXVlc3RDb250ZXh0UHJvdmlkZXI/OiAoKSA9PlxuICAgIHwge1xuICAgICAgICB0aHJlYWRJZD86IHN0cmluZyB8IG51bGw7XG4gICAgICAgIHR1cm5JZD86IHN0cmluZyB8IG51bGw7XG4gICAgICAgIHNlc3Npb25JZD86IHN0cmluZyB8IG51bWJlciB8IG51bGw7XG4gICAgICAgIHNlbnRyeVRyYWNlPzogc3RyaW5nIHwgbnVsbDtcbiAgICAgICAgYmFnZ2FnZT86IHN0cmluZyB8IG51bGw7XG4gICAgICB9XG4gICAgfCBudWxsXG4gICAgfCB1bmRlZmluZWQ7XG4gIG9uRXJyb3I/OiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkO1xufVxuXG5jb25zdCBERUZBVUxUX1JFQUxUSU1FX01PREVMID0gXCJncHQtNG8tdHJhbnNjcmliZVwiO1xuY29uc3QgREVGQVVMVF9SRUFMVElNRV9XRUJSVENfVVJMID1cbiAgXCJodHRwczovL2FwaS5vcGVuYWkuY29tL3YxL3JlYWx0aW1lP2ludGVudD10cmFuc2NyaXB0aW9uXCI7XG5jb25zdCBEQVRBX0NIQU5ORUxfT1BFTl9USU1FT1VUX01TID0gNjAwMDtcbmNvbnN0IFNFU1NJT05fQ0FDSEVfUkVMRUFTRV9ERUxBWV9NUyA9IDQ1XzAwMDtcbmNvbnN0IEVOQUJMRV9TRVNTSU9OX0NBQ0hFID1cbiAgdHlwZW9mIHByb2Nlc3MgPT09IFwidW5kZWZpbmVkXCIgPyB0cnVlIDogcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT09IFwidGVzdFwiO1xuXG50eXBlIENhY2hlZFdlYlJ0Y1Nlc3Npb24gPSB7XG4gIHBjOiBSVENQZWVyQ29ubmVjdGlvbiB8IG51bGw7XG4gIGRhdGFDaGFubmVsOiBSVENEYXRhQ2hhbm5lbCB8IG51bGw7XG4gIHN0cmVhbTogTWVkaWFTdHJlYW0gfCBudWxsO1xuICByZWxlYXNlVGltZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbDtcbn07XG5cbmNvbnN0IGNhY2hlZFdlYlJ0Y1Nlc3Npb246IENhY2hlZFdlYlJ0Y1Nlc3Npb24gPSB7XG4gIHBjOiBudWxsLFxuICBkYXRhQ2hhbm5lbDogbnVsbCxcbiAgc3RyZWFtOiBudWxsLFxuICByZWxlYXNlVGltZXI6IG51bGwsXG59O1xuXG5mdW5jdGlvbiBjbGVhckNhY2hlZFJlbGVhc2VUaW1lcigpIHtcbiAgaWYgKCFFTkFCTEVfU0VTU0lPTl9DQUNIRSkge1xuICAgIHJldHVybjtcbiAgfVxuICBpZiAoY2FjaGVkV2ViUnRjU2Vzc2lvbi5yZWxlYXNlVGltZXIpIHtcbiAgICBjbGVhclRpbWVvdXQoY2FjaGVkV2ViUnRjU2Vzc2lvbi5yZWxlYXNlVGltZXIpO1xuICAgIGNhY2hlZFdlYlJ0Y1Nlc3Npb24ucmVsZWFzZVRpbWVyID0gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBjbG9zZVdlYlJ0Y1Nlc3Npb25SZXNvdXJjZXMoXG4gIHNlc3Npb246IFBpY2s8Q2FjaGVkV2ViUnRjU2Vzc2lvbiwgXCJwY1wiIHwgXCJkYXRhQ2hhbm5lbFwiIHwgXCJzdHJlYW1cIj5cbikge1xuICBpZiAoc2Vzc2lvbi5kYXRhQ2hhbm5lbCkge1xuICAgIHRyeSB7XG4gICAgICBzZXNzaW9uLmRhdGFDaGFubmVsLmNsb3NlKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKFwiW09wZW5BSSBTUl0gY2xvc2UgZGF0YSBjaGFubmVsIHdhcm5pbmc6XCIsIGVycm9yKTtcbiAgICB9XG4gIH1cblxuICBpZiAoc2Vzc2lvbi5wYykge1xuICAgIHRyeSB7XG4gICAgICBzZXNzaW9uLnBjLmNsb3NlKCk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKFwiW09wZW5BSSBTUl0gY2xvc2UgcGVlciB3YXJuaW5nOlwiLCBlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgaWYgKHNlc3Npb24uc3RyZWFtKSB7XG4gICAgdHJ5IHtcbiAgICAgIHNlc3Npb24uc3RyZWFtLmdldFRyYWNrcygpLmZvckVhY2goKHRyYWNrKSA9PiB0cmFjay5zdG9wKCkpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBsb2dnZXIud2FybihcIltPcGVuQUkgU1JdIHN0b3Agc3RyZWFtIHdhcm5pbmc6XCIsIGVycm9yKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gc2NoZWR1bGVDYWNoZWRTZXNzaW9uUmVsZWFzZSgpIHtcbiAgaWYgKCFFTkFCTEVfU0VTU0lPTl9DQUNIRSkge1xuICAgIHJldHVybjtcbiAgfVxuICBjbGVhckNhY2hlZFJlbGVhc2VUaW1lcigpO1xuICBjYWNoZWRXZWJSdGNTZXNzaW9uLnJlbGVhc2VUaW1lciA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgIGNsb3NlV2ViUnRjU2Vzc2lvblJlc291cmNlcyhjYWNoZWRXZWJSdGNTZXNzaW9uKTtcbiAgICBjYWNoZWRXZWJSdGNTZXNzaW9uLnBjID0gbnVsbDtcbiAgICBjYWNoZWRXZWJSdGNTZXNzaW9uLmRhdGFDaGFubmVsID0gbnVsbDtcbiAgICBjYWNoZWRXZWJSdGNTZXNzaW9uLnN0cmVhbSA9IG51bGw7XG4gICAgY2FjaGVkV2ViUnRjU2Vzc2lvbi5yZWxlYXNlVGltZXIgPSBudWxsO1xuICB9LCBTRVNTSU9OX0NBQ0hFX1JFTEVBU0VfREVMQVlfTVMpO1xufVxuXG5mdW5jdGlvbiBoeWRyYXRlRnJvbVNlc3Npb25DYWNoZSgpIHtcbiAgaWYgKCFFTkFCTEVfU0VTU0lPTl9DQUNIRSkge1xuICAgIHJldHVybiB7XG4gICAgICBwYzogbnVsbCxcbiAgICAgIGRhdGFDaGFubmVsOiBudWxsLFxuICAgICAgc3RyZWFtOiBudWxsLFxuICAgIH07XG4gIH1cbiAgcmV0dXJuIHtcbiAgICBwYzogY2FjaGVkV2ViUnRjU2Vzc2lvbi5wYyxcbiAgICBkYXRhQ2hhbm5lbDogY2FjaGVkV2ViUnRjU2Vzc2lvbi5kYXRhQ2hhbm5lbCxcbiAgICBzdHJlYW06IGNhY2hlZFdlYlJ0Y1Nlc3Npb24uc3RyZWFtLFxuICB9O1xufVxuXG5mdW5jdGlvbiBwZXJzaXN0U2Vzc2lvbkNhY2hlKFxuICBwYzogUlRDUGVlckNvbm5lY3Rpb24gfCBudWxsLFxuICBkYXRhQ2hhbm5lbDogUlRDRGF0YUNoYW5uZWwgfCBudWxsLFxuICBzdHJlYW06IE1lZGlhU3RyZWFtIHwgbnVsbFxuKSB7XG4gIGlmICghRU5BQkxFX1NFU1NJT05fQ0FDSEUpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgY2FjaGVkV2ViUnRjU2Vzc2lvbi5wYyA9IHBjO1xuICBjYWNoZWRXZWJSdGNTZXNzaW9uLmRhdGFDaGFubmVsID0gZGF0YUNoYW5uZWw7XG4gIGNhY2hlZFdlYlJ0Y1Nlc3Npb24uc3RyZWFtID0gc3RyZWFtO1xufVxuXG5leHBvcnQgY29uc3QgT3BlbkFJU3BlZWNoUmVjb2duaXplcjogUmVhY3QuRkM8T3BlbkFJU3BlZWNoUmVjb2duaXplclByb3BzPiA9ICh7XG4gIHNob3VsZExpc3RlbixcbiAgc3BlZWNoU3RhdHVzQ2FsbGJhY2ssXG4gIHNwZWVjaFJlc3VsdENhbGxiYWNrLFxuICBzcGVlY2hUcmFuc2xhdGlvbkNhbGxiYWNrLFxuICBzcGVlY2hSZWFkeUNhbGxiYWNrLFxuICBjbGllbnRTZWNyZXQsXG4gIG9wZW5haVRyYW5zY3JpcHRpb25TZXNzaW9uRW5kcG9pbnQsXG4gIG9wZW5haVRyYW5zbGF0aW9uRW5kcG9pbnQsXG4gIG9wZW5haVJlYWx0aW1lV2ViUnRjVXJsID0gREVGQVVMVF9SRUFMVElNRV9XRUJSVENfVVJMLFxuICBvcGVuYWlSZWFsdGltZU1vZGVsID0gREVGQVVMVF9SRUFMVElNRV9NT0RFTCxcbiAgb3BlbmFpVHJhbnNsYXRpb25Nb2RlbCA9IFwiZ3B0LTQuMS1taW5pXCIsXG4gIG9wZW5haVZhZEVuYWJsZWQgPSB0cnVlLFxuICBvcGVuYWlBdXRvU3RvcE9uVmFkU2lsZW5jZSA9IGZhbHNlLFxuICBvcGVuYWlWYWRUaHJlc2hvbGQgPSAwLjcsXG4gIG9wZW5haVZhZFByZWZpeFBhZGRpbmdNcyA9IDQwMCxcbiAgb3BlbmFpVmFkU2lsZW5jZUR1cmF0aW9uTXMgPSAxMDAwLFxuICBvcGVuYWlWYWRJZGxlVGltZW91dE1zID0gNjAwMCxcbiAgb3BlbmFpUHJld2FybU9uTW91bnQgPSBmYWxzZSxcbiAgbGFuZ3VhZ2UgPSBcImVuXCIsXG4gIHJlcXVlc3RDb250ZXh0UHJvdmlkZXIsXG4gIG9uRXJyb3IsXG59KSA9PiB7XG4gIGNvbnN0IHByb3h5QXV0aFRva2VuID0gY2xpZW50U2VjcmV0O1xuICBjb25zdCBbaXNSZWNvcmRpbmcsIHNldElzUmVjb3JkaW5nXSA9IHVzZVN0YXRlKGZhbHNlKTtcbiAgY29uc3QgW3Nlc3Npb25SZWNvdmVyeVRva2VuLCBzZXRTZXNzaW9uUmVjb3ZlcnlUb2tlbl0gPSB1c2VTdGF0ZSgwKTtcbiAgY29uc3QgY2FjaGVkU2Vzc2lvblJlZiA9IHVzZVJlZihoeWRyYXRlRnJvbVNlc3Npb25DYWNoZSgpKTtcbiAgY29uc3QgcGNSZWYgPSB1c2VSZWY8UlRDUGVlckNvbm5lY3Rpb24gfCBudWxsPihjYWNoZWRTZXNzaW9uUmVmLmN1cnJlbnQucGMpO1xuICBjb25zdCBkYXRhQ2hhbm5lbFJlZiA9IHVzZVJlZjxSVENEYXRhQ2hhbm5lbCB8IG51bGw+KFxuICAgIGNhY2hlZFNlc3Npb25SZWYuY3VycmVudC5kYXRhQ2hhbm5lbFxuICApO1xuICBjb25zdCBzdHJlYW1SZWYgPSB1c2VSZWY8TWVkaWFTdHJlYW0gfCBudWxsPihjYWNoZWRTZXNzaW9uUmVmLmN1cnJlbnQuc3RyZWFtKTtcbiAgY29uc3Qgc2Vzc2lvbkluaXRSZWYgPSB1c2VSZWY8UHJvbWlzZTx2b2lkPiB8IG51bGw+KG51bGwpO1xuICBjb25zdCBmaW5hbFRyYW5zY3JpcHRSZWYgPSB1c2VSZWYoXCJcIik7XG4gIGNvbnN0IGludGVyaW1UcmFuc2NyaXB0UmVmID0gdXNlUmVmKFwiXCIpO1xuICBjb25zdCBzdG9wSW5GbGlnaHRSZWYgPSB1c2VSZWYoZmFsc2UpO1xuICBjb25zdCBmaW5hbGl6ZWRSZWYgPSB1c2VSZWYoZmFsc2UpO1xuICBjb25zdCBhd2FpdGluZ0NvbW1pdEZpbmFsUmVmID0gdXNlUmVmKGZhbHNlKTtcbiAgY29uc3QgY29tbWl0RmluYWxUaW1lb3V0UmVmID0gdXNlUmVmPFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IGRpZFByZXdhcm1SZWYgPSB1c2VSZWYoZmFsc2UpO1xuICBjb25zdCBpc1JlY29yZGluZ1JlZiA9IHVzZVJlZihmYWxzZSk7XG4gIGNvbnN0IHNob3VsZExpc3RlblJlZiA9IHVzZVJlZihzaG91bGRMaXN0ZW4pO1xuICBjb25zdCBvcGVuYWlQcmV3YXJtT25Nb3VudFJlZiA9IHVzZVJlZihvcGVuYWlQcmV3YXJtT25Nb3VudCk7XG4gIGNvbnN0IHNlc3Npb25SZWNvdmVyeU1vZGVSZWYgPSB1c2VSZWY8XCJsaXN0ZW5cIiB8IFwicHJld2FybVwiIHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IHNlc3Npb25SZWNvdmVyeUluRmxpZ2h0UmVmID0gdXNlUmVmKGZhbHNlKTtcbiAgY29uc3Qgc3VwcHJlc3NlZENoYW5uZWxFcnJvclJlZiA9IHVzZVJlZjxSVENEYXRhQ2hhbm5lbCB8IG51bGw+KG51bGwpO1xuXG4gIGNvbnN0IGVtaXRFcnJvciA9IHVzZUNhbGxiYWNrKFxuICAgIChlcnJvcjogdW5rbm93bikgPT4ge1xuICAgICAgY29uc3QgZXJyID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpO1xuICAgICAgbG9nZ2VyLmVycm9yKFwiW09wZW5BSSBTUl0gZXJyb3I6XCIsIGVycik7XG4gICAgICBvbkVycm9yPy4oZXJyKTtcbiAgICB9LFxuICAgIFtvbkVycm9yXVxuICApO1xuXG4gIGNvbnN0IHJlc2V0VHJhbnNjcmlwdFJlZnMgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgZmluYWxUcmFuc2NyaXB0UmVmLmN1cnJlbnQgPSBcIlwiO1xuICAgIGludGVyaW1UcmFuc2NyaXB0UmVmLmN1cnJlbnQgPSBcIlwiO1xuICAgIGZpbmFsaXplZFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gIH0sIFtdKTtcblxuICBjb25zdCBnZXRCdWZmZXJlZFRyYW5zY3JpcHQgPSB1c2VDYWxsYmFjaygoKSA9PiB7XG4gICAgcmV0dXJuIChcbiAgICAgIGZpbmFsVHJhbnNjcmlwdFJlZi5jdXJyZW50IHx8XG4gICAgICBpbnRlcmltVHJhbnNjcmlwdFJlZi5jdXJyZW50XG4gICAgKS50cmltKCk7XG4gIH0sIFtdKTtcblxuICBjb25zdCBjbGVhckNvbW1pdEZpbmFsV2FpdCA9IHVzZUNhbGxiYWNrKCgpID0+IHtcbiAgICBhd2FpdGluZ0NvbW1pdEZpbmFsUmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICBpZiAoY29tbWl0RmluYWxUaW1lb3V0UmVmLmN1cnJlbnQpIHtcbiAgICAgIGNsZWFyVGltZW91dChjb21taXRGaW5hbFRpbWVvdXRSZWYuY3VycmVudCk7XG4gICAgICBjb21taXRGaW5hbFRpbWVvdXRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgfVxuICB9LCBbXSk7XG5cbiAgY29uc3Qgbm90aWZ5UmVhZHkgPSB1c2VDYWxsYmFjayhcbiAgICAocmVhZHk6IGJvb2xlYW4pID0+IHtcbiAgICAgIHNwZWVjaFJlYWR5Q2FsbGJhY2s/LihyZWFkeSk7XG4gICAgfSxcbiAgICBbc3BlZWNoUmVhZHlDYWxsYmFja11cbiAgKTtcblxuICBjb25zdCBzZXRBdWRpb0NhcHR1cmVFbmFibGVkID0gdXNlQ2FsbGJhY2soKGVuYWJsZWQ6IGJvb2xlYW4pID0+IHtcbiAgICBjb25zdCBzdHJlYW0gPSBzdHJlYW1SZWYuY3VycmVudDtcbiAgICBpZiAoIXN0cmVhbSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRyeSB7XG4gICAgICBjb25zdCB0cmFja3MgPVxuICAgICAgICB0eXBlb2YgKHN0cmVhbSBhcyBhbnkpLmdldEF1ZGlvVHJhY2tzID09PSBcImZ1bmN0aW9uXCJcbiAgICAgICAgICA/IChzdHJlYW0gYXMgYW55KS5nZXRBdWRpb1RyYWNrcygpXG4gICAgICAgICAgOiB0eXBlb2YgKHN0cmVhbSBhcyBhbnkpLmdldFRyYWNrcyA9PT0gXCJmdW5jdGlvblwiXG4gICAgICAgICAgICA/IChzdHJlYW0gYXMgYW55KVxuICAgICAgICAgICAgICAgIC5nZXRUcmFja3MoKVxuICAgICAgICAgICAgICAgIC5maWx0ZXIoKHRyYWNrOiBhbnkpID0+IHRyYWNrPy5raW5kID09PSBcImF1ZGlvXCIpXG4gICAgICAgICAgICA6IFtdO1xuXG4gICAgICB0cmFja3MuZm9yRWFjaCgodHJhY2s6IGFueSkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHRyYWNrLmVuYWJsZWQgPSBlbmFibGVkO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGxvZ2dlci53YXJuKFwiW09wZW5BSSBTUl0gdG9nZ2xlIGF1ZGlvIHRyYWNrIHdhcm5pbmc6XCIsIGVycm9yKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKFwiW09wZW5BSSBTUl0gZW51bWVyYXRlIGF1ZGlvIHRyYWNrcyB3YXJuaW5nOlwiLCBlcnJvcik7XG4gICAgfVxuICB9LCBbXSk7XG5cbiAgY29uc3QgY2xlYXJSZWFsdGltZUlucHV0QnVmZmVyID0gdXNlQ2FsbGJhY2soKHJlYXNvbjogc3RyaW5nKSA9PiB7XG4gICAgaWYgKGRhdGFDaGFubmVsUmVmLmN1cnJlbnQ/LnJlYWR5U3RhdGUgIT09IFwib3BlblwiKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICBkYXRhQ2hhbm5lbFJlZi5jdXJyZW50LnNlbmQoXG4gICAgICAgIEpTT04uc3RyaW5naWZ5KHsgdHlwZTogXCJpbnB1dF9hdWRpb19idWZmZXIuY2xlYXJcIiB9KVxuICAgICAgKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgW09wZW5BSSBTUl0gY2xlYXJlZCBpbnB1dCBidWZmZXIgKCR7cmVhc29ufSlgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgbG9nZ2VyLndhcm4oXCJbT3BlbkFJIFNSXSBjbGVhciBpbnB1dCBidWZmZXIgd2FybmluZzpcIiwgZXJyb3IpO1xuICAgIH1cbiAgfSwgW10pO1xuXG4gIGNvbnN0IGdldFJlcXVlc3RDb250ZXh0SGVhZGVycyA9IHVzZUNhbGxiYWNrKCgpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0+IHtcbiAgICBjb25zdCBjb250ZXh0ID0gcmVxdWVzdENvbnRleHRQcm92aWRlcj8uKCk7XG4gICAgaWYgKCFjb250ZXh0KSByZXR1cm4ge307XG5cbiAgICBjb25zdCBoZWFkZXJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+ID0ge307XG4gICAgaWYgKGNvbnRleHQudGhyZWFkSWQpIHtcbiAgICAgIGhlYWRlcnNbXCJ4LXRocmVhZC1pZFwiXSA9IFN0cmluZyhjb250ZXh0LnRocmVhZElkKTtcbiAgICB9XG4gICAgaWYgKGNvbnRleHQudHVybklkKSB7XG4gICAgICBoZWFkZXJzW1wieC10dXJuLWlkXCJdID0gU3RyaW5nKGNvbnRleHQudHVybklkKTtcbiAgICB9XG4gICAgaWYgKGNvbnRleHQuc2Vzc2lvbklkICE9PSB1bmRlZmluZWQgJiYgY29udGV4dC5zZXNzaW9uSWQgIT09IG51bGwpIHtcbiAgICAgIGhlYWRlcnNbXCJ4LXZvaWNlLXNlc3Npb24taWRcIl0gPSBTdHJpbmcoY29udGV4dC5zZXNzaW9uSWQpO1xuICAgIH1cbiAgICBpZiAoY29udGV4dC5zZW50cnlUcmFjZSkge1xuICAgICAgaGVhZGVyc1tcInNlbnRyeS10cmFjZVwiXSA9IFN0cmluZyhjb250ZXh0LnNlbnRyeVRyYWNlKTtcbiAgICB9XG4gICAgaWYgKGNvbnRleHQuYmFnZ2FnZSkge1xuICAgICAgaGVhZGVycy5iYWdnYWdlID0gU3RyaW5nKGNvbnRleHQuYmFnZ2FnZSk7XG4gICAgfVxuICAgIHJldHVybiBoZWFkZXJzO1xuICB9LCBbcmVxdWVzdENvbnRleHRQcm92aWRlcl0pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY2xlYXJDYWNoZWRSZWxlYXNlVGltZXIoKTtcbiAgICBpZiAoZGF0YUNoYW5uZWxSZWYuY3VycmVudD8ucmVhZHlTdGF0ZSA9PT0gXCJvcGVuXCIpIHtcbiAgICAgIG5vdGlmeVJlYWR5KHRydWUpO1xuICAgIH1cbiAgfSwgW25vdGlmeVJlYWR5XSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBpc1JlY29yZGluZ1JlZi5jdXJyZW50ID0gaXNSZWNvcmRpbmc7XG4gIH0sIFtpc1JlY29yZGluZ10pO1xuXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgc2hvdWxkTGlzdGVuUmVmLmN1cnJlbnQgPSBzaG91bGRMaXN0ZW47XG4gIH0sIFtzaG91bGRMaXN0ZW5dKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIG9wZW5haVByZXdhcm1Pbk1vdW50UmVmLmN1cnJlbnQgPSBvcGVuYWlQcmV3YXJtT25Nb3VudDtcbiAgfSwgW29wZW5haVByZXdhcm1Pbk1vdW50XSk7XG5cbiAgY29uc3QgaGFuZGxlRXhwaXJlZFNlc3Npb24gPSB1c2VDYWxsYmFjayhcbiAgICAoY2hhbm5lbDogUlRDRGF0YUNoYW5uZWwsIHBjOiBSVENQZWVyQ29ubmVjdGlvbikgPT4ge1xuICAgICAgaWYgKHNlc3Npb25SZWNvdmVyeUluRmxpZ2h0UmVmLmN1cnJlbnQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgaWYgKGRhdGFDaGFubmVsUmVmLmN1cnJlbnQgIT09IGNoYW5uZWwpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBzZXNzaW9uUmVjb3ZlcnlJbkZsaWdodFJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgIHN1cHByZXNzZWRDaGFubmVsRXJyb3JSZWYuY3VycmVudCA9IGNoYW5uZWw7XG4gICAgICBzZXNzaW9uUmVjb3ZlcnlNb2RlUmVmLmN1cnJlbnQgPSBzaG91bGRMaXN0ZW5SZWYuY3VycmVudFxuICAgICAgICA/IFwibGlzdGVuXCJcbiAgICAgICAgOiBvcGVuYWlQcmV3YXJtT25Nb3VudFJlZi5jdXJyZW50XG4gICAgICAgICAgPyBcInByZXdhcm1cIlxuICAgICAgICAgIDogbnVsbDtcblxuICAgICAgY2xlYXJDb21taXRGaW5hbFdhaXQoKTtcbiAgICAgIHJlc2V0VHJhbnNjcmlwdFJlZnMoKTtcbiAgICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQoZmFsc2UpO1xuICAgICAgc2Vzc2lvbkluaXRSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICBjbG9zZVdlYlJ0Y1Nlc3Npb25SZXNvdXJjZXMoe1xuICAgICAgICBkYXRhQ2hhbm5lbDogY2hhbm5lbCxcbiAgICAgICAgcGMsXG4gICAgICAgIHN0cmVhbTogc3RyZWFtUmVmLmN1cnJlbnQsXG4gICAgICB9KTtcblxuICAgICAgaWYgKGRhdGFDaGFubmVsUmVmLmN1cnJlbnQgPT09IGNoYW5uZWwpIHtcbiAgICAgICAgZGF0YUNoYW5uZWxSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICB9XG4gICAgICBpZiAoY2FjaGVkV2ViUnRjU2Vzc2lvbi5kYXRhQ2hhbm5lbCA9PT0gY2hhbm5lbCkge1xuICAgICAgICBjYWNoZWRXZWJSdGNTZXNzaW9uLmRhdGFDaGFubmVsID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIGlmIChwY1JlZi5jdXJyZW50ID09PSBwYykge1xuICAgICAgICBwY1JlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIH1cbiAgICAgIHN0cmVhbVJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIHBlcnNpc3RTZXNzaW9uQ2FjaGUobnVsbCwgbnVsbCwgbnVsbCk7XG5cbiAgICAgIHNldElzUmVjb3JkaW5nKGZhbHNlKTtcbiAgICAgIG5vdGlmeVJlYWR5KGZhbHNlKTtcbiAgICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrKGZhbHNlLCBcIlwiKTtcblxuICAgICAgaWYgKHNlc3Npb25SZWNvdmVyeU1vZGVSZWYuY3VycmVudCkge1xuICAgICAgICBzZXRTZXNzaW9uUmVjb3ZlcnlUb2tlbigodmFsdWUpID0+IHZhbHVlICsgMSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBzZXNzaW9uUmVjb3ZlcnlJbkZsaWdodFJlZi5jdXJyZW50ID0gZmFsc2U7XG4gICAgICAgIHN1cHByZXNzZWRDaGFubmVsRXJyb3JSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICB9XG4gICAgfSxcbiAgICBbXG4gICAgICBjbGVhckNvbW1pdEZpbmFsV2FpdCxcbiAgICAgIG5vdGlmeVJlYWR5LFxuICAgICAgcmVzZXRUcmFuc2NyaXB0UmVmcyxcbiAgICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQsXG4gICAgICBzcGVlY2hTdGF0dXNDYWxsYmFjayxcbiAgICBdXG4gICk7XG5cbiAgY29uc3QgYnVpbGRUdXJuRGV0ZWN0aW9uID0gdXNlQ2FsbGJhY2soKCkgPT4ge1xuICAgIGlmICghb3BlbmFpVmFkRW5hYmxlZCkgcmV0dXJuIG51bGw7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IFwic2VydmVyX3ZhZFwiLFxuICAgICAgdGhyZXNob2xkOiBvcGVuYWlWYWRUaHJlc2hvbGQsXG4gICAgICBwcmVmaXhfcGFkZGluZ19tczogb3BlbmFpVmFkUHJlZml4UGFkZGluZ01zLFxuICAgICAgc2lsZW5jZV9kdXJhdGlvbl9tczogb3BlbmFpVmFkU2lsZW5jZUR1cmF0aW9uTXMsXG4gICAgfTtcbiAgfSwgW1xuICAgIG9wZW5haVZhZEVuYWJsZWQsXG4gICAgb3BlbmFpVmFkVGhyZXNob2xkLFxuICAgIG9wZW5haVZhZFByZWZpeFBhZGRpbmdNcyxcbiAgICBvcGVuYWlWYWRTaWxlbmNlRHVyYXRpb25NcyxcbiAgXSk7XG5cbiAgY29uc3Qgd2FpdEZvckRhdGFDaGFubmVsT3BlbiA9IHVzZUNhbGxiYWNrKFxuICAgIGFzeW5jIChjaGFubmVsOiBSVENEYXRhQ2hhbm5lbCk6IFByb21pc2U8dm9pZD4gPT4ge1xuICAgICAgY29uc3QgcmVhZFN0YXRlID0gKCkgPT4gU3RyaW5nKGNoYW5uZWwucmVhZHlTdGF0ZSk7XG4gICAgICBpZiAocmVhZFN0YXRlKCkgPT09IFwib3BlblwiKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAgIHdoaWxlIChEYXRlLm5vdygpIC0gc3RhcnQgPCBEQVRBX0NIQU5ORUxfT1BFTl9USU1FT1VUX01TKSB7XG4gICAgICAgIGlmIChyZWFkU3RhdGUoKSA9PT0gXCJvcGVuXCIpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHNldFRpbWVvdXQocmVzb2x2ZSwgNTApKTtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYE9wZW5BSSByZWFsdGltZSBkYXRhIGNoYW5uZWwgZGlkIG5vdCBvcGVuIHdpdGhpbiAke0RBVEFfQ0hBTk5FTF9PUEVOX1RJTUVPVVRfTVN9bXMgKHN0YXRlPSR7cmVhZFN0YXRlKCl9KWBcbiAgICAgICk7XG4gICAgfSxcbiAgICBbXVxuICApO1xuXG4gIGNvbnN0IHRyYW5zbGF0ZVRvRW5nbGlzaCA9IHVzZUNhbGxiYWNrKFxuICAgIGFzeW5jICh0ZXh0OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgICAgY29uc3QgaW5wdXQgPSB0ZXh0LnRyaW0oKTtcbiAgICAgIGlmICghaW5wdXQgfHwgIW9wZW5haVRyYW5zbGF0aW9uRW5kcG9pbnQpIHJldHVybiBcIlwiO1xuICAgICAgaWYgKGxhbmd1YWdlLnRvTG93ZXJDYXNlKCkuc3RhcnRzV2l0aChcImVuXCIpKSByZXR1cm4gXCJcIjtcblxuICAgICAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgICAgXCJjb250ZW50LXR5cGVcIjogXCJhcHBsaWNhdGlvbi9qc29uXCIsXG4gICAgICAgIC4uLmdldFJlcXVlc3RDb250ZXh0SGVhZGVycygpLFxuICAgICAgfTtcbiAgICAgIGlmIChwcm94eUF1dGhUb2tlbikge1xuICAgICAgICBoZWFkZXJzLkF1dGhvcml6YXRpb24gPSBgQmVhcmVyICR7cHJveHlBdXRoVG9rZW59YDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCBmZXRjaChvcGVuYWlUcmFuc2xhdGlvbkVuZHBvaW50LCB7XG4gICAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICAgIGhlYWRlcnMsXG4gICAgICAgIGJvZHk6IEpTT04uc3RyaW5naWZ5KHtcbiAgICAgICAgICB0ZXh0OiBpbnB1dCxcbiAgICAgICAgICBzb3VyY2VMYW5ndWFnZTogbGFuZ3VhZ2UsXG4gICAgICAgICAgbW9kZWw6IG9wZW5haVRyYW5zbGF0aW9uTW9kZWwsXG4gICAgICAgIH0pLFxuICAgICAgfSk7XG5cbiAgICAgIGlmICghcmVzcG9uc2Uub2spIHtcbiAgICAgICAgY29uc3QgYm9keSA9IGF3YWl0IHJlc3BvbnNlLnRleHQoKS5jYXRjaCgoKSA9PiBcIlwiKTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGB0cmFuc2xhdGlvbiBmYWlsZWQgKCR7cmVzcG9uc2Uuc3RhdHVzfSk6ICR7Ym9keX1gKTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgcGF5bG9hZCA9IGF3YWl0IHJlc3BvbnNlLmpzb24oKS5jYXRjaCgoKSA9PiBudWxsKTtcbiAgICAgIGNvbnN0IHRyYW5zbGF0ZWQgPVxuICAgICAgICB0eXBlb2YgcGF5bG9hZD8udGV4dCA9PT0gXCJzdHJpbmdcIiA/IHBheWxvYWQudGV4dC50cmltKCkgOiBcIlwiO1xuICAgICAgaWYgKHRyYW5zbGF0ZWQpIHtcbiAgICAgICAgc3BlZWNoVHJhbnNsYXRpb25DYWxsYmFjaz8uKHRyYW5zbGF0ZWQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRyYW5zbGF0ZWQ7XG4gICAgfSxcbiAgICBbXG4gICAgICBwcm94eUF1dGhUb2tlbixcbiAgICAgIGxhbmd1YWdlLFxuICAgICAgZ2V0UmVxdWVzdENvbnRleHRIZWFkZXJzLFxuICAgICAgb3BlbmFpVHJhbnNsYXRpb25FbmRwb2ludCxcbiAgICAgIG9wZW5haVRyYW5zbGF0aW9uTW9kZWwsXG4gICAgICBzcGVlY2hUcmFuc2xhdGlvbkNhbGxiYWNrLFxuICAgIF1cbiAgKTtcblxuICBjb25zdCBlbWl0RmluYWwgPSB1c2VDYWxsYmFjayhhc3luYyAoKSA9PiB7XG4gICAgaWYgKGZpbmFsaXplZFJlZi5jdXJyZW50KSByZXR1cm47XG4gICAgZmluYWxpemVkUmVmLmN1cnJlbnQgPSB0cnVlO1xuXG4gICAgY29uc3QgZmluYWxUZXh0ID0gKFxuICAgICAgZmluYWxUcmFuc2NyaXB0UmVmLmN1cnJlbnQgfHxcbiAgICAgIGludGVyaW1UcmFuc2NyaXB0UmVmLmN1cnJlbnRcbiAgICApLnRyaW0oKTtcblxuICAgIGxldCBwYXJzZVRleHQgPSBmaW5hbFRleHQ7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRyYW5zbGF0ZWQgPSBhd2FpdCB0cmFuc2xhdGVUb0VuZ2xpc2goZmluYWxUZXh0KTtcbiAgICAgIGlmICh0cmFuc2xhdGVkKSB7XG4gICAgICAgIHBhcnNlVGV4dCA9IHRyYW5zbGF0ZWQ7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGxvZ2dlci53YXJuKFwiW09wZW5BSSBTUl0gdHJhbnNsYXRpb24gZmFpbGVkOlwiLCBlcnJvcik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrKGZhbHNlLCBcIlwiKTtcbiAgICAgIGlmIChwYXJzZVRleHQpIHtcbiAgICAgICAgc3BlZWNoUmVzdWx0Q2FsbGJhY2socGFyc2VUZXh0KTtcbiAgICAgIH1cbiAgICB9XG4gIH0sIFtzcGVlY2hSZXN1bHRDYWxsYmFjaywgc3BlZWNoU3RhdHVzQ2FsbGJhY2ssIHRyYW5zbGF0ZVRvRW5nbGlzaF0pO1xuXG4gIGNvbnN0IGZpbmFsaXplQW5kUmVzZXQgPSB1c2VDYWxsYmFjayhhc3luYyAoKSA9PiB7XG4gICAgY2xlYXJDb21taXRGaW5hbFdhaXQoKTtcbiAgICBhd2FpdCBlbWl0RmluYWwoKTtcbiAgICByZXNldFRyYW5zY3JpcHRSZWZzKCk7XG4gIH0sIFtjbGVhckNvbW1pdEZpbmFsV2FpdCwgZW1pdEZpbmFsLCByZXNldFRyYW5zY3JpcHRSZWZzXSk7XG5cbiAgY29uc3QgaGFuZGxlUmVhbHRpbWVNZXNzYWdlID0gdXNlQ2FsbGJhY2soXG4gICAgKHBheWxvYWQ6IGFueSkgPT4ge1xuICAgICAgY29uc3QgdHlwZSA9IFN0cmluZyhwYXlsb2FkPy50eXBlIHx8IFwiXCIpO1xuICAgICAgY29uc3QgYWNjZXB0c1RyYW5zY3JpcHQgPVxuICAgICAgICBpc1JlY29yZGluZ1JlZi5jdXJyZW50IHx8IGF3YWl0aW5nQ29tbWl0RmluYWxSZWYuY3VycmVudDtcbiAgICAgIGlmICghYWNjZXB0c1RyYW5zY3JpcHQpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzaG91bGRQdWJsaXNoSW50ZXJpbSA9IGlzUmVjb3JkaW5nUmVmLmN1cnJlbnQ7XG4gICAgICBjb25zdCBkZWx0YSA9IGV4dHJhY3REZWx0YVRleHQocGF5bG9hZCk7XG4gICAgICBjb25zdCBjb21wbGV0ZWQgPSBleHRyYWN0Q29tcGxldGVkVGV4dChwYXlsb2FkKTtcblxuICAgICAgaWYgKGRlbHRhKSB7XG4gICAgICAgIGludGVyaW1UcmFuc2NyaXB0UmVmLmN1cnJlbnQgPSBtZXJnZVRyYW5zY3JpcHRQYXJ0cyhcbiAgICAgICAgICBmaW5hbFRyYW5zY3JpcHRSZWYuY3VycmVudCxcbiAgICAgICAgICBkZWx0YVxuICAgICAgICApO1xuICAgICAgICBpZiAoc2hvdWxkUHVibGlzaEludGVyaW0pIHtcbiAgICAgICAgICBzcGVlY2hTdGF0dXNDYWxsYmFjayh0cnVlLCBpbnRlcmltVHJhbnNjcmlwdFJlZi5jdXJyZW50KTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBpZiAoY29tcGxldGVkKSB7XG4gICAgICAgIGZpbmFsVHJhbnNjcmlwdFJlZi5jdXJyZW50ID0gbWVyZ2VUcmFuc2NyaXB0UGFydHMoXG4gICAgICAgICAgZmluYWxUcmFuc2NyaXB0UmVmLmN1cnJlbnQsXG4gICAgICAgICAgY29tcGxldGVkXG4gICAgICAgICk7XG4gICAgICAgIGludGVyaW1UcmFuc2NyaXB0UmVmLmN1cnJlbnQgPSBmaW5hbFRyYW5zY3JpcHRSZWYuY3VycmVudDtcbiAgICAgICAgaWYgKHNob3VsZFB1Ymxpc2hJbnRlcmltKSB7XG4gICAgICAgICAgc3BlZWNoU3RhdHVzQ2FsbGJhY2sodHJ1ZSwgZmluYWxUcmFuc2NyaXB0UmVmLmN1cnJlbnQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGxvb2tzQ29tcGxldGVkID0gISFjb21wbGV0ZWQgfHwgdHlwZS5pbmNsdWRlcyhcImNvbXBsZXRlZFwiKTtcbiAgICAgIGlmIChcbiAgICAgICAgYXdhaXRpbmdDb21taXRGaW5hbFJlZi5jdXJyZW50ICYmXG4gICAgICAgIGxvb2tzQ29tcGxldGVkICYmXG4gICAgICAgIGdldEJ1ZmZlcmVkVHJhbnNjcmlwdCgpXG4gICAgICApIHtcbiAgICAgICAgZmluYWxpemVBbmRSZXNldCgpLmNhdGNoKChlcnJvcikgPT4gZW1pdEVycm9yKGVycm9yKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKG9wZW5haUF1dG9TdG9wT25WYWRTaWxlbmNlICYmIHR5cGUgPT09IFwiaW5wdXRfYXVkaW9fYnVmZmVyLnNwZWVjaF9zdG9wcGVkXCIpIHtcbiAgICAgICAgY29uc3QgcGF1c2VUcmFuc2NyaXB0ID0gZ2V0QnVmZmVyZWRUcmFuc2NyaXB0KCk7XG4gICAgICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrKGZhbHNlLCBwYXVzZVRyYW5zY3JpcHQpO1xuICAgICAgfVxuICAgIH0sXG4gICAgW1xuICAgICAgZW1pdEVycm9yLFxuICAgICAgZmluYWxpemVBbmRSZXNldCxcbiAgICAgIGdldEJ1ZmZlcmVkVHJhbnNjcmlwdCxcbiAgICAgIG9wZW5haUF1dG9TdG9wT25WYWRTaWxlbmNlLFxuICAgICAgc3BlZWNoU3RhdHVzQ2FsbGJhY2ssXG4gICAgXVxuICApO1xuXG4gIGNvbnN0IHN0YXJ0V2ViUnRjU2Vzc2lvbiA9IHVzZUNhbGxiYWNrKFxuICAgIGFzeW5jICh0b2tlbjogc3RyaW5nKSA9PiB7XG4gICAgICBjbGVhckNhY2hlZFJlbGVhc2VUaW1lcigpO1xuICAgICAgaWYgKHR5cGVvZiBSVENQZWVyQ29ubmVjdGlvbiA9PT0gXCJ1bmRlZmluZWRcIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJSVENQZWVyQ29ubmVjdGlvbiBpcyB1bmF2YWlsYWJsZSBvbiB3ZWIgcnVudGltZVwiKTtcbiAgICAgIH1cbiAgICAgIGlmICghbmF2aWdhdG9yLm1lZGlhRGV2aWNlcz8uZ2V0VXNlck1lZGlhKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIm5hdmlnYXRvci5tZWRpYURldmljZXMuZ2V0VXNlck1lZGlhIGlzIHVuYXZhaWxhYmxlXCIpO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdHJlYW0gPSBhd2FpdCBuYXZpZ2F0b3IubWVkaWFEZXZpY2VzLmdldFVzZXJNZWRpYSh7XG4gICAgICAgIGF1ZGlvOiB7XG4gICAgICAgICAgZWNob0NhbmNlbGxhdGlvbjogdHJ1ZSxcbiAgICAgICAgICBub2lzZVN1cHByZXNzaW9uOiB0cnVlLFxuICAgICAgICAgIGF1dG9HYWluQ29udHJvbDogdHJ1ZSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgc3RyZWFtUmVmLmN1cnJlbnQgPSBzdHJlYW07XG4gICAgICBwZXJzaXN0U2Vzc2lvbkNhY2hlKHBjUmVmLmN1cnJlbnQsIGRhdGFDaGFubmVsUmVmLmN1cnJlbnQsIHN0cmVhbVJlZi5jdXJyZW50KTtcbiAgICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQoZmFsc2UpO1xuXG4gICAgICBjb25zdCBwYyA9IG5ldyBSVENQZWVyQ29ubmVjdGlvbigpO1xuICAgICAgcGNSZWYuY3VycmVudCA9IHBjO1xuICAgICAgcGVyc2lzdFNlc3Npb25DYWNoZShwY1JlZi5jdXJyZW50LCBkYXRhQ2hhbm5lbFJlZi5jdXJyZW50LCBzdHJlYW1SZWYuY3VycmVudCk7XG4gICAgICBzdHJlYW0uZ2V0VHJhY2tzKCkuZm9yRWFjaCgodHJhY2spID0+IHBjLmFkZFRyYWNrKHRyYWNrLCBzdHJlYW0pKTtcblxuICAgICAgY29uc3QgZGF0YUNoYW5uZWwgPSBwYy5jcmVhdGVEYXRhQ2hhbm5lbChcIm9haS1ldmVudHNcIik7XG4gICAgICBkYXRhQ2hhbm5lbFJlZi5jdXJyZW50ID0gZGF0YUNoYW5uZWw7XG4gICAgICBwZXJzaXN0U2Vzc2lvbkNhY2hlKHBjUmVmLmN1cnJlbnQsIGRhdGFDaGFubmVsUmVmLmN1cnJlbnQsIHN0cmVhbVJlZi5jdXJyZW50KTtcbiAgICAgIGRhdGFDaGFubmVsLm9ub3BlbiA9ICgpID0+IHtcbiAgICAgICAgbm90aWZ5UmVhZHkodHJ1ZSk7XG4gICAgICB9O1xuICAgICAgZGF0YUNoYW5uZWwub25tZXNzYWdlID0gKGV2ZW50OiBNZXNzYWdlRXZlbnQpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBwYXlsb2FkID0gSlNPTi5wYXJzZShTdHJpbmcoZXZlbnQuZGF0YSB8fCBcInt9XCIpKTtcbiAgICAgICAgICBpZiAocGF5bG9hZD8udHlwZSA9PT0gXCJlcnJvclwiKSB7XG4gICAgICAgICAgICBjb25zdCBtZXNzYWdlID0gU3RyaW5nKFxuICAgICAgICAgICAgICBwYXlsb2FkPy5lcnJvcj8ubWVzc2FnZSB8fCBcIk9wZW5BSSByZWFsdGltZSBlcnJvclwiXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKGlzQ29tbWl0QnVmZmVyVG9vU21hbGxFcnJvcihtZXNzYWdlKSkge1xuICAgICAgICAgICAgICAvLyBJZ25vcmUgY29tbWl0IGJ1ZmZlci10b28tc21hbGwgZXJyb3JzIGZvciBsb3ctbGF0ZW5jeSBmYXN0LXN0b3AgcGF0aC5cbiAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGlzU2Vzc2lvbkR1cmF0aW9uTGltaXRFcnJvcihtZXNzYWdlKSkge1xuICAgICAgICAgICAgICBoYW5kbGVFeHBpcmVkU2Vzc2lvbihkYXRhQ2hhbm5lbCwgcGMpO1xuICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IobWVzc2FnZSk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGhhbmRsZVJlYWx0aW1lTWVzc2FnZShwYXlsb2FkKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBlbWl0RXJyb3IoZXJyb3IpO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgICAgZGF0YUNoYW5uZWwub25lcnJvciA9ICgpID0+IHtcbiAgICAgICAgaWYgKHN1cHByZXNzZWRDaGFubmVsRXJyb3JSZWYuY3VycmVudCA9PT0gZGF0YUNoYW5uZWwpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgbm90aWZ5UmVhZHkoZmFsc2UpO1xuICAgICAgICBlbWl0RXJyb3IobmV3IEVycm9yKFwiT3BlbkFJIHJlYWx0aW1lIGRhdGEgY2hhbm5lbCBlcnJvclwiKSk7XG4gICAgICB9O1xuICAgICAgZGF0YUNoYW5uZWwub25jbG9zZSA9ICgpID0+IHtcbiAgICAgICAgaWYgKGRhdGFDaGFubmVsUmVmLmN1cnJlbnQgPT09IGRhdGFDaGFubmVsKSB7XG4gICAgICAgICAgZGF0YUNoYW5uZWxSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGNhY2hlZFdlYlJ0Y1Nlc3Npb24uZGF0YUNoYW5uZWwgPT09IGRhdGFDaGFubmVsKSB7XG4gICAgICAgICAgY2FjaGVkV2ViUnRjU2Vzc2lvbi5kYXRhQ2hhbm5lbCA9IG51bGw7XG4gICAgICAgIH1cbiAgICAgICAgbm90aWZ5UmVhZHkoZmFsc2UpO1xuICAgICAgfTtcblxuICAgICAgY29uc3Qgb2ZmZXIgPSBhd2FpdCBwYy5jcmVhdGVPZmZlcigpO1xuICAgICAgYXdhaXQgcGMuc2V0TG9jYWxEZXNjcmlwdGlvbihvZmZlcik7XG5cbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgZmV0Y2gob3BlbmFpUmVhbHRpbWVXZWJSdGNVcmwsIHtcbiAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgaGVhZGVyczoge1xuICAgICAgICAgIEF1dGhvcml6YXRpb246IGBCZWFyZXIgJHt0b2tlbn1gLFxuICAgICAgICAgIFwiY29udGVudC10eXBlXCI6IFwiYXBwbGljYXRpb24vc2RwXCIsXG4gICAgICAgIH0sXG4gICAgICAgIGJvZHk6IG9mZmVyLnNkcCB8fCBcIlwiLFxuICAgICAgfSk7XG4gICAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICAgIGNvbnN0IGJvZHkgPSBhd2FpdCByZXNwb25zZS50ZXh0KCkuY2F0Y2goKCkgPT4gXCJcIik7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgd2VicnRjIG5lZ290aWF0aW9uIGZhaWxlZCAoJHtyZXNwb25zZS5zdGF0dXN9KTogJHtib2R5fWApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBhbnN3ZXJTZHAgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG4gICAgICBhd2FpdCBwYy5zZXRSZW1vdGVEZXNjcmlwdGlvbih7XG4gICAgICAgIHR5cGU6IFwiYW5zd2VyXCIsXG4gICAgICAgIHNkcDogYW5zd2VyU2RwLFxuICAgICAgfSBhcyBSVENTZXNzaW9uRGVzY3JpcHRpb25Jbml0KTtcbiAgICAgIGF3YWl0IHdhaXRGb3JEYXRhQ2hhbm5lbE9wZW4oZGF0YUNoYW5uZWwpO1xuICAgIH0sXG4gICAgW1xuICAgICAgZW1pdEVycm9yLFxuICAgICAgaGFuZGxlUmVhbHRpbWVNZXNzYWdlLFxuICAgICAgbm90aWZ5UmVhZHksXG4gICAgICBvcGVuYWlSZWFsdGltZVdlYlJ0Y1VybCxcbiAgICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQsXG4gICAgICB3YWl0Rm9yRGF0YUNoYW5uZWxPcGVuLFxuICAgIF1cbiAgKTtcblxuICBjb25zdCBnZXRFcGhlbWVyYWxUb2tlbiA9IHVzZUNhbGxiYWNrKGFzeW5jICgpOiBQcm9taXNlPHN0cmluZz4gPT4ge1xuICAgIGNvbnN0IGhlYWRlcnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7XG4gICAgICBcImNvbnRlbnQtdHlwZVwiOiBcImFwcGxpY2F0aW9uL2pzb25cIixcbiAgICAgIC4uLmdldFJlcXVlc3RDb250ZXh0SGVhZGVycygpLFxuICAgIH07XG4gICAgaWYgKHByb3h5QXV0aFRva2VuKSB7XG4gICAgICBoZWFkZXJzLkF1dGhvcml6YXRpb24gPSBgQmVhcmVyICR7cHJveHlBdXRoVG9rZW59YDtcbiAgICB9XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGZldGNoKG9wZW5haVRyYW5zY3JpcHRpb25TZXNzaW9uRW5kcG9pbnQsIHtcbiAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICBoZWFkZXJzLFxuICAgICAgYm9keTogSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgICBpbnB1dF9hdWRpb19mb3JtYXQ6IFwicGNtMTZcIixcbiAgICAgICAgaW5wdXRfYXVkaW9fdHJhbnNjcmlwdGlvbjoge1xuICAgICAgICAgIG1vZGVsOiBvcGVuYWlSZWFsdGltZU1vZGVsLFxuICAgICAgICAgIGxhbmd1YWdlLFxuICAgICAgICB9LFxuICAgICAgICB0dXJuX2RldGVjdGlvbjogYnVpbGRUdXJuRGV0ZWN0aW9uKCkgfHwgdW5kZWZpbmVkLFxuICAgICAgfSksXG4gICAgfSk7XG5cbiAgICBpZiAoIXJlc3BvbnNlLm9rKSB7XG4gICAgICBjb25zdCBib2R5ID0gYXdhaXQgcmVzcG9uc2UudGV4dCgpLmNhdGNoKCgpID0+IFwiXCIpO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgdHJhbnNjcmlwdGlvbiBzZXNzaW9uIHJlcXVlc3QgZmFpbGVkICgke3Jlc3BvbnNlLnN0YXR1c30pOiAke2JvZHl9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBjb25zdCBwYXlsb2FkID0gYXdhaXQgcmVzcG9uc2UuanNvbigpLmNhdGNoKCgpID0+ICh7fSkpO1xuICAgIGNvbnN0IHRva2VuID1cbiAgICAgIHBheWxvYWQ/LmNsaWVudF9zZWNyZXQ/LnZhbHVlIHx8XG4gICAgICBwYXlsb2FkPy5jbGllbnRfc2VjcmV0IHx8XG4gICAgICBwYXlsb2FkPy52YWx1ZSB8fFxuICAgICAgXCJcIjtcbiAgICBpZiAoIXRva2VuKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIFwiTm8gZXBoZW1lcmFsIHRva2VuIHJldHVybmVkIGZyb20gdHJhbnNjcmlwdGlvbiBzZXNzaW9uIGVuZHBvaW50XCJcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRva2VuO1xuICB9LCBbXG4gICAgYnVpbGRUdXJuRGV0ZWN0aW9uLFxuICAgIGdldFJlcXVlc3RDb250ZXh0SGVhZGVycyxcbiAgICBwcm94eUF1dGhUb2tlbixcbiAgICBsYW5ndWFnZSxcbiAgICBvcGVuYWlSZWFsdGltZU1vZGVsLFxuICAgIG9wZW5haVRyYW5zY3JpcHRpb25TZXNzaW9uRW5kcG9pbnQsXG4gIF0pO1xuXG4gIGNvbnN0IGhhc1JldXNhYmxlU2Vzc2lvbiA9IHVzZUNhbGxiYWNrKCgpOiBib29sZWFuID0+IHtcbiAgICByZXR1cm4gKFxuICAgICAgISFwY1JlZi5jdXJyZW50ICYmXG4gICAgICAhIXN0cmVhbVJlZi5jdXJyZW50ICYmXG4gICAgICBkYXRhQ2hhbm5lbFJlZi5jdXJyZW50Py5yZWFkeVN0YXRlID09PSBcIm9wZW5cIlxuICAgICk7XG4gIH0sIFtdKTtcblxuICBjb25zdCBlbnN1cmVXZWJSdGNTZXNzaW9uID0gdXNlQ2FsbGJhY2soYXN5bmMgKCkgPT4ge1xuICAgIGlmIChoYXNSZXVzYWJsZVNlc3Npb24oKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAoc2Vzc2lvbkluaXRSZWYuY3VycmVudCkge1xuICAgICAgYXdhaXQgc2Vzc2lvbkluaXRSZWYuY3VycmVudDtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZXNzaW9uSW5pdFJlZi5jdXJyZW50ID0gKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHRva2VuID0gYXdhaXQgZ2V0RXBoZW1lcmFsVG9rZW4oKTtcbiAgICAgIGF3YWl0IHN0YXJ0V2ViUnRjU2Vzc2lvbih0b2tlbik7XG4gICAgfSkoKTtcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBzZXNzaW9uSW5pdFJlZi5jdXJyZW50O1xuICAgIH0gZmluYWxseSB7XG4gICAgICBzZXNzaW9uSW5pdFJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICB9XG4gIH0sIFtnZXRFcGhlbWVyYWxUb2tlbiwgaGFzUmV1c2FibGVTZXNzaW9uLCBzdGFydFdlYlJ0Y1Nlc3Npb25dKTtcblxuICBjb25zdCBjbGVhbnVwID0gdXNlQ2FsbGJhY2soYXN5bmMgKCkgPT4ge1xuICAgIHNlc3Npb25Jbml0UmVmLmN1cnJlbnQgPSBudWxsO1xuICAgIGNsZWFyQ2FjaGVkUmVsZWFzZVRpbWVyKCk7XG5cbiAgICBjbG9zZVdlYlJ0Y1Nlc3Npb25SZXNvdXJjZXMoe1xuICAgICAgZGF0YUNoYW5uZWw6IGRhdGFDaGFubmVsUmVmLmN1cnJlbnQsXG4gICAgICBwYzogcGNSZWYuY3VycmVudCxcbiAgICAgIHN0cmVhbTogc3RyZWFtUmVmLmN1cnJlbnQsXG4gICAgfSk7XG4gICAgZGF0YUNoYW5uZWxSZWYuY3VycmVudCA9IG51bGw7XG4gICAgcGNSZWYuY3VycmVudCA9IG51bGw7XG4gICAgc3RyZWFtUmVmLmN1cnJlbnQgPSBudWxsO1xuICAgIHBlcnNpc3RTZXNzaW9uQ2FjaGUobnVsbCwgbnVsbCwgbnVsbCk7XG4gIH0sIFtdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChzZXNzaW9uUmVjb3ZlcnlUb2tlbiA9PT0gMCB8fCAhc2Vzc2lvblJlY292ZXJ5TW9kZVJlZi5jdXJyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IGNhbmNlbGxlZCA9IGZhbHNlO1xuICAgIGNvbnN0IHJlY292ZXJ5TW9kZSA9IHNlc3Npb25SZWNvdmVyeU1vZGVSZWYuY3VycmVudDtcblxuICAgIChhc3luYyAoKSA9PiB7XG4gICAgICB0cnkge1xuICAgICAgICBhd2FpdCBlbnN1cmVXZWJSdGNTZXNzaW9uKCk7XG4gICAgICAgIGlmIChjYW5jZWxsZWQpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBpZiAocmVjb3ZlcnlNb2RlID09PSBcImxpc3RlblwiICYmIHNob3VsZExpc3RlblJlZi5jdXJyZW50KSB7XG4gICAgICAgICAgc2V0QXVkaW9DYXB0dXJlRW5hYmxlZCh0cnVlKTtcbiAgICAgICAgICBzZXRJc1JlY29yZGluZyh0cnVlKTtcbiAgICAgICAgfVxuICAgICAgICBub3RpZnlSZWFkeShkYXRhQ2hhbm5lbFJlZi5jdXJyZW50Py5yZWFkeVN0YXRlID09PSBcIm9wZW5cIik7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoY2FuY2VsbGVkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIGVtaXRFcnJvcihlcnJvcik7XG4gICAgICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQoZmFsc2UpO1xuICAgICAgICBhd2FpdCBjbGVhbnVwKCk7XG4gICAgICAgIHNldElzUmVjb3JkaW5nKGZhbHNlKTtcbiAgICAgICAgbm90aWZ5UmVhZHkoZmFsc2UpO1xuICAgICAgICBzcGVlY2hTdGF0dXNDYWxsYmFjayhmYWxzZSwgXCJcIik7XG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBpZiAoY2FuY2VsbGVkKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHNlc3Npb25SZWNvdmVyeU1vZGVSZWYuY3VycmVudCA9IG51bGw7XG4gICAgICAgIHNlc3Npb25SZWNvdmVyeUluRmxpZ2h0UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgICAgc3VwcHJlc3NlZENoYW5uZWxFcnJvclJlZi5jdXJyZW50ID0gbnVsbDtcbiAgICAgIH1cbiAgICB9KSgpO1xuXG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIGNhbmNlbGxlZCA9IHRydWU7XG4gICAgfTtcbiAgfSwgW1xuICAgIGNsZWFudXAsXG4gICAgZW1pdEVycm9yLFxuICAgIGVuc3VyZVdlYlJ0Y1Nlc3Npb24sXG4gICAgbm90aWZ5UmVhZHksXG4gICAgc2Vzc2lvblJlY292ZXJ5VG9rZW4sXG4gICAgc2V0QXVkaW9DYXB0dXJlRW5hYmxlZCxcbiAgICBzcGVlY2hTdGF0dXNDYWxsYmFjayxcbiAgXSk7XG5cbiAgY29uc3Qgc3RhcnRSZWNvcmRpbmcgPSB1c2VDYWxsYmFjayhhc3luYyAoKSA9PiB7XG4gICAgaWYgKGlzUmVjb3JkaW5nIHx8IHN0b3BJbkZsaWdodFJlZi5jdXJyZW50IHx8IHNlc3Npb25SZWNvdmVyeUluRmxpZ2h0UmVmLmN1cnJlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdHJ5IHtcbiAgICAgIGNsZWFyQ29tbWl0RmluYWxXYWl0KCk7XG4gICAgICBub3RpZnlSZWFkeShmYWxzZSk7XG4gICAgICByZXNldFRyYW5zY3JpcHRSZWZzKCk7XG4gICAgICBjb25zdCByZXVzaW5nV2FybVNlc3Npb24gPSBoYXNSZXVzYWJsZVNlc3Npb24oKTtcbiAgICAgIGF3YWl0IGVuc3VyZVdlYlJ0Y1Nlc3Npb24oKTtcbiAgICAgIGlmIChyZXVzaW5nV2FybVNlc3Npb24pIHtcbiAgICAgICAgY2xlYXJSZWFsdGltZUlucHV0QnVmZmVyKFwic3RhcnRfcmVjb3JkaW5nXCIpO1xuICAgICAgfVxuICAgICAgaWYgKCFzaG91bGRMaXN0ZW5SZWYuY3VycmVudCkge1xuICAgICAgICBzZXRBdWRpb0NhcHR1cmVFbmFibGVkKGZhbHNlKTtcbiAgICAgICAgbm90aWZ5UmVhZHkoZGF0YUNoYW5uZWxSZWYuY3VycmVudD8ucmVhZHlTdGF0ZSA9PT0gXCJvcGVuXCIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICBzZXRBdWRpb0NhcHR1cmVFbmFibGVkKHRydWUpO1xuICAgICAgc2V0SXNSZWNvcmRpbmcodHJ1ZSk7XG4gICAgICBub3RpZnlSZWFkeShkYXRhQ2hhbm5lbFJlZi5jdXJyZW50Py5yZWFkeVN0YXRlID09PSBcIm9wZW5cIik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGVtaXRFcnJvcihlcnJvcik7XG4gICAgICBzZXRBdWRpb0NhcHR1cmVFbmFibGVkKGZhbHNlKTtcbiAgICAgIGF3YWl0IGNsZWFudXAoKTtcbiAgICAgIHNldElzUmVjb3JkaW5nKGZhbHNlKTtcbiAgICAgIG5vdGlmeVJlYWR5KGZhbHNlKTtcbiAgICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrKGZhbHNlLCBcIlwiKTtcbiAgICB9XG4gIH0sIFtcbiAgICBjbGVhbnVwLFxuICAgIGNsZWFyUmVhbHRpbWVJbnB1dEJ1ZmZlcixcbiAgICBjbGVhckNvbW1pdEZpbmFsV2FpdCxcbiAgICBlbnN1cmVXZWJSdGNTZXNzaW9uLFxuICAgIGVtaXRFcnJvcixcbiAgICBoYXNSZXVzYWJsZVNlc3Npb24sXG4gICAgaXNSZWNvcmRpbmcsXG4gICAgbm90aWZ5UmVhZHksXG4gICAgcmVzZXRUcmFuc2NyaXB0UmVmcyxcbiAgICBzZXRBdWRpb0NhcHR1cmVFbmFibGVkLFxuICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrLFxuICBdKTtcblxuICBjb25zdCBzdG9wUmVjb3JkaW5nID0gdXNlQ2FsbGJhY2soYXN5bmMgKCkgPT4ge1xuICAgIGlmICghaXNSZWNvcmRpbmcgfHwgc3RvcEluRmxpZ2h0UmVmLmN1cnJlbnQpIHJldHVybjtcbiAgICBzdG9wSW5GbGlnaHRSZWYuY3VycmVudCA9IHRydWU7XG4gICAgc2V0SXNSZWNvcmRpbmcoZmFsc2UpO1xuICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQoZmFsc2UpO1xuICAgIG5vdGlmeVJlYWR5KGZhbHNlKTtcbiAgICB0cnkge1xuICAgICAgaWYgKGRhdGFDaGFubmVsUmVmLmN1cnJlbnQ/LnJlYWR5U3RhdGUgPT09IFwib3BlblwiKSB7XG4gICAgICAgIGRhdGFDaGFubmVsUmVmLmN1cnJlbnQuc2VuZChcbiAgICAgICAgICBKU09OLnN0cmluZ2lmeSh7IHR5cGU6IFwiaW5wdXRfYXVkaW9fYnVmZmVyLmNvbW1pdFwiIH0pXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICBjb25zdCBidWZmZXJlZCA9IGdldEJ1ZmZlcmVkVHJhbnNjcmlwdCgpO1xuICAgICAgaWYgKGJ1ZmZlcmVkKSB7XG4gICAgICAgIGF3YWl0IGZpbmFsaXplQW5kUmVzZXQoKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrKGZhbHNlLCBcIlwiKTtcbiAgICAgICAgYXdhaXRpbmdDb21taXRGaW5hbFJlZi5jdXJyZW50ID0gdHJ1ZTtcbiAgICAgICAgaWYgKGNvbW1pdEZpbmFsVGltZW91dFJlZi5jdXJyZW50KSB7XG4gICAgICAgICAgY2xlYXJUaW1lb3V0KGNvbW1pdEZpbmFsVGltZW91dFJlZi5jdXJyZW50KTtcbiAgICAgICAgfVxuICAgICAgICAvLyBTaG9ydCBmYWxsYmFjazogaWYgbm8gcG9zdC1jb21taXQgdHJhbnNjcmlwdCBhcnJpdmVzLCByZXNldCBzdGF0ZSBhbmQgZXhpdC5cbiAgICAgICAgY29tbWl0RmluYWxUaW1lb3V0UmVmLmN1cnJlbnQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgICBpZiAoIWF3YWl0aW5nQ29tbWl0RmluYWxSZWYuY3VycmVudCkgcmV0dXJuO1xuICAgICAgICAgIGNsZWFyQ29tbWl0RmluYWxXYWl0KCk7XG4gICAgICAgICAgcmVzZXRUcmFuc2NyaXB0UmVmcygpO1xuICAgICAgICB9LCAxNTAwKTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgZW1pdEVycm9yKGVycm9yKTtcbiAgICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrKGZhbHNlLCBcIlwiKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgc3RvcEluRmxpZ2h0UmVmLmN1cnJlbnQgPSBmYWxzZTtcbiAgICAgIG5vdGlmeVJlYWR5KGZhbHNlKTtcbiAgICB9XG4gIH0sIFtcbiAgICBlbWl0RXJyb3IsXG4gICAgZmluYWxpemVBbmRSZXNldCxcbiAgICBnZXRCdWZmZXJlZFRyYW5zY3JpcHQsXG4gICAgaXNSZWNvcmRpbmcsXG4gICAgbm90aWZ5UmVhZHksXG4gICAgY2xlYXJDb21taXRGaW5hbFdhaXQsXG4gICAgcmVzZXRUcmFuc2NyaXB0UmVmcyxcbiAgICBzZXRBdWRpb0NhcHR1cmVFbmFibGVkLFxuICAgIHNwZWVjaFN0YXR1c0NhbGxiYWNrLFxuICBdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghb3BlbmFpUHJld2FybU9uTW91bnQgfHwgZGlkUHJld2FybVJlZi5jdXJyZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGRpZFByZXdhcm1SZWYuY3VycmVudCA9IHRydWU7XG4gICAgZW5zdXJlV2ViUnRjU2Vzc2lvbigpXG4gICAgICAudGhlbigoKSA9PiB7XG4gICAgICAgIG5vdGlmeVJlYWR5KHRydWUpO1xuICAgICAgfSlcbiAgICAgIC5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgZW1pdEVycm9yKGVycm9yKTtcbiAgICAgIH0pO1xuICB9LCBbZW1pdEVycm9yLCBlbnN1cmVXZWJSdGNTZXNzaW9uLCBub3RpZnlSZWFkeSwgb3BlbmFpUHJld2FybU9uTW91bnRdKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmIChzaG91bGRMaXN0ZW4gJiYgIWlzUmVjb3JkaW5nKSB7XG4gICAgICBzdGFydFJlY29yZGluZygpO1xuICAgIH0gZWxzZSBpZiAoIXNob3VsZExpc3RlbiAmJiBpc1JlY29yZGluZykge1xuICAgICAgc3RvcFJlY29yZGluZygpO1xuICAgIH1cbiAgfSwgW2lzUmVjb3JkaW5nLCBzaG91bGRMaXN0ZW4sIHN0YXJ0UmVjb3JkaW5nLCBzdG9wUmVjb3JkaW5nXSk7XG5cbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgbm90aWZ5UmVhZHkoZmFsc2UpO1xuICAgICAgY2xlYXJDb21taXRGaW5hbFdhaXQoKTtcbiAgICAgIHNldEF1ZGlvQ2FwdHVyZUVuYWJsZWQoZmFsc2UpO1xuICAgICAgaWYgKFxuICAgICAgICBFTkFCTEVfU0VTU0lPTl9DQUNIRSAmJlxuICAgICAgICBvcGVuYWlQcmV3YXJtT25Nb3VudFJlZi5jdXJyZW50ICYmXG4gICAgICAgICFpc1JlY29yZGluZ1JlZi5jdXJyZW50XG4gICAgICApIHtcbiAgICAgICAgc2NoZWR1bGVDYWNoZWRTZXNzaW9uUmVsZWFzZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY2xlYW51cCgpLmNhdGNoKCgpID0+IHVuZGVmaW5lZCk7XG4gICAgICB9XG4gICAgfTtcbiAgfSwgW2NsZWFudXAsIG5vdGlmeVJlYWR5LCBjbGVhckNvbW1pdEZpbmFsV2FpdCwgc2V0QXVkaW9DYXB0dXJlRW5hYmxlZF0pO1xuXG4gIHJldHVybiA8VmlldyAvPjtcbn07XG5cbmZ1bmN0aW9uIGV4dHJhY3REZWx0YVRleHQocGF5bG9hZDogYW55KTogc3RyaW5nIHtcbiAgY29uc3QgdHlwZSA9IFN0cmluZyhwYXlsb2FkPy50eXBlIHx8IFwiXCIpO1xuICBpZiAoIXR5cGUuaW5jbHVkZXMoXCJkZWx0YVwiKSkgcmV0dXJuIFwiXCI7XG4gIGNvbnN0IGNhbmRpZGF0ZXMgPSBbXG4gICAgcGF5bG9hZD8uZGVsdGEsXG4gICAgcGF5bG9hZD8udGV4dF9kZWx0YSxcbiAgICBwYXlsb2FkPy50cmFuc2NyaXB0X2RlbHRhLFxuICAgIHBheWxvYWQ/Lml0ZW0/LmNvbnRlbnQ/LlswXT8udHJhbnNjcmlwdCxcbiAgXTtcbiAgZm9yIChjb25zdCB2YWx1ZSBvZiBjYW5kaWRhdGVzKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZS50cmltKCkpIHJldHVybiB2YWx1ZS50cmltKCk7XG4gIH1cbiAgcmV0dXJuIFwiXCI7XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RDb21wbGV0ZWRUZXh0KHBheWxvYWQ6IGFueSk6IHN0cmluZyB7XG4gIGNvbnN0IHR5cGUgPSBTdHJpbmcocGF5bG9hZD8udHlwZSB8fCBcIlwiKTtcbiAgaWYgKCF0eXBlLmluY2x1ZGVzKFwiY29tcGxldGVkXCIpKSByZXR1cm4gXCJcIjtcbiAgY29uc3QgY2FuZGlkYXRlcyA9IFtcbiAgICBwYXlsb2FkPy50cmFuc2NyaXB0LFxuICAgIHBheWxvYWQ/LnRleHQsXG4gICAgcGF5bG9hZD8uaXRlbT8uY29udGVudD8uWzBdPy50cmFuc2NyaXB0LFxuICAgIHBheWxvYWQ/Lml0ZW0/LnRyYW5zY3JpcHQsXG4gIF07XG4gIGZvciAoY29uc3QgdmFsdWUgb2YgY2FuZGlkYXRlcykge1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIgJiYgdmFsdWUudHJpbSgpKSByZXR1cm4gdmFsdWUudHJpbSgpO1xuICB9XG4gIHJldHVybiBcIlwiO1xufVxuXG5mdW5jdGlvbiBleHRyYWN0SXRlbUlkKHBheWxvYWQ6IGFueSk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBjYW5kaWRhdGVzID0gW3BheWxvYWQ/Lml0ZW1faWQsIHBheWxvYWQ/Lml0ZW0/LmlkXTtcbiAgZm9yIChjb25zdCB2YWx1ZSBvZiBjYW5kaWRhdGVzKSB7XG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZS50cmltKCkpIHtcbiAgICAgIHJldHVybiB2YWx1ZS50cmltKCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBpc0NvbW1pdEJ1ZmZlclRvb1NtYWxsRXJyb3IobWVzc2FnZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGNvbnN0IG5vcm1hbGl6ZWQgPSBtZXNzYWdlLnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiAoXG4gICAgbm9ybWFsaXplZC5pbmNsdWRlcyhcImlucHV0IGF1ZGlvIGJ1ZmZlclwiKSAmJlxuICAgIG5vcm1hbGl6ZWQuaW5jbHVkZXMoXCJidWZmZXIgdG9vIHNtYWxsXCIpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGlzU2Vzc2lvbkR1cmF0aW9uTGltaXRFcnJvcihtZXNzYWdlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IG1lc3NhZ2UudG9Mb3dlckNhc2UoKTtcbiAgcmV0dXJuIChcbiAgICBub3JtYWxpemVkLmluY2x1ZGVzKFwic2Vzc2lvblwiKSAmJlxuICAgIChub3JtYWxpemVkLmluY2x1ZGVzKFwibWF4aW11bSBkdXJhdGlvblwiKSB8fFxuICAgICAgbm9ybWFsaXplZC5pbmNsdWRlcyhcIm1heCBkdXJhdGlvblwiKSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzT3BlbkFJU3BlZWNoQXZhaWxhYmxlKCk6IGJvb2xlYW4ge1xuICBpZiAoUGxhdGZvcm0uT1MgIT09IFwid2ViXCIpIHJldHVybiBmYWxzZTtcbiAgaWYgKHR5cGVvZiB3aW5kb3cgPT09IFwidW5kZWZpbmVkXCIpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIChcbiAgICB0eXBlb2YgbmF2aWdhdG9yICE9PSBcInVuZGVmaW5lZFwiICYmXG4gICAgISFuYXZpZ2F0b3IubWVkaWFEZXZpY2VzPy5nZXRVc2VyTWVkaWEgJiZcbiAgICB0eXBlb2YgUlRDUGVlckNvbm5lY3Rpb24gIT09IFwidW5kZWZpbmVkXCJcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldE9wZW5BSVNwZWVjaENhcGFiaWxpdGllcygpIHtcbiAgcmV0dXJuIHtcbiAgICBhdmFpbGFibGU6IGlzT3BlbkFJU3BlZWNoQXZhaWxhYmxlKCksXG4gICAgcGxhdGZvcm06IFBsYXRmb3JtLk9TLFxuICAgIHN1cHBvcnRzU2VydmVyVkFEOiB0cnVlLFxuICAgIHRyYW5zcG9ydDogXCJ3ZWJydGNcIixcbiAgfTtcbn1cblxuZXhwb3J0IGRlZmF1bHQgT3BlbkFJU3BlZWNoUmVjb2duaXplcjtcbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7QUFBQSxJQUFBQSxNQUFBLEdBQUFDLHVC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QVM2SCxhQUFhQSxDQUFDdEUsT0FBWSxFQUFpQjtFQUNsRCxNQUFNZ0UsVUFBVSxHQUFHLENBQUNoRSxPQUFPLEVBQUV1RSxPQUFPLEVBQUV2RSxPQUFPLEVBQUVtRSxJQUFJLEVBQUVLLEVBQUUsQ0FBQztFQUN4RCxLQUFLLE1BQU0xTixLQUFLLElBQUlrTixVQUFVLEVBQUU7SUFDOUIsSUFBSSxPQUFPbE4sS0FBSyxLQUFLLFFBQVEsSUFBSUEsS0FBSyxDQUFDMkYsSUFBSSxDQUFDLENBQUMsRUFBRTtNQUM3QyxPQUFPM0YsS0FBSyxDQUFDMkYsSUFBSSxDQUFDLENBQUM7SUFDckI7RUFDRjtFQUNBLE9BQU8sSUFBSTtBQUNiO0FBRUEsU0FBUzJGLDJCQUEyQkEsQ0FBQ0QsT0FBZSxFQUFXO0VBQzdELE1BQU1zQyxVQUFVLEdBQUd0QyxPQUFPLENBQUMvQyxXQUFXLENBQUMsQ0FBQztFQUN4QyxPQUNFcUYsVUFBVSxDQUFDekQsUUFBUSxDQUFDLG9CQUFvQixDQUFDLElBQ3pDeUQsVUFBVSxDQUFDekQsUUFBUSxDQUFDLGtCQUFrQixDQUFDO0FBRTNDO0FBRUEsU0FBU3FCLDJCQUEyQkEsQ0FBQ0YsT0FBZSxFQUFXO0VBQzdELE1BQU1zQyxVQUFVLEdBQUd0QyxPQUFPLENBQUMvQyxXQUFXLENBQUMsQ0FBQztFQUN4QyxPQUNFcUYsVUFBVSxDQUFDekQsUUFBUSxDQUFDLFNBQVMsQ0FBQyxLQUM3QnlELFVBQVUsQ0FBQ3pELFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQyxJQUN0Q3lELFVBQVUsQ0FBQ3pELFFBQVEsQ0FBQyxjQUFjLENBQUMsQ0FBQztBQUUxQztBQUVPLFNBQVMwRCx1QkFBdUJBLENBQUEsRUFBWTtFQUNqRCxJQUFJQyxxQkFBUSxDQUFDQyxFQUFFLEtBQUssS0FBSyxFQUFFLE9BQU8sS0FBSztFQUN2QyxJQUFJLE9BQU9DLE1BQU0sS0FBSyxXQUFXLEVBQUUsT0FBTyxLQUFLO0VBQy9DLE9BQ0UsT0FBT3hELFNBQVMsS0FBSyxXQUFXLElBQ2hDLENBQUMsQ0FBQ0EsU0FBUyxDQUFDQyxZQUFZLEVBQUVDLFlBQVksSUFDdEMsT0FBT0gsaUJBQWlCLEtBQUssV0FBVztBQUU1QztBQUVPLFNBQVMwRCwyQkFBMkJBLENBQUEsRUFBRztFQUM1QyxPQUFPO0lBQ0xDLFNBQVMsRUFBRUwsdUJBQXVCLENBQUMsQ0FBQztJQUNwQ00sUUFBUSxFQUFFTCxxQkFBUSxDQUFDQyxFQUFFO0lBQ3JCSyxpQkFBaUIsRUFBRSxJQUFJO0lBQ3ZCQyxTQUFTLEVBQUU7RUFDYixDQUFDO0FBQ0g7QUFBQyxJQUFBQyxRQUFBLEdBQUFwQixPQUFBLENBQUFqUCxPQUFBLEdBRWNxRSxzQkFBc0IiLCJpZ25vcmVMaXN0IjpbXX0=
|