@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.
Files changed (85) hide show
  1. package/.env.example +22 -0
  2. package/.github/workflows/publish.yml +20 -0
  3. package/LICENSE.txt +201 -0
  4. package/README.md +621 -0
  5. package/babel.config.js +29 -0
  6. package/dist/adapters/__tests__/expo-router-adapter.test.d.ts +1 -0
  7. package/dist/adapters/expo-router-adapter.d.ts +16 -0
  8. package/dist/adapters/expo-router-adapter.js +521 -0
  9. package/dist/adapters/navigation-adapter.d.ts +20 -0
  10. package/dist/adapters/navigation-adapter.js +137 -0
  11. package/dist/audio-visualizer.d.ts +14 -0
  12. package/dist/audio-visualizer.js +123 -0
  13. package/dist/current-selection.d.ts +27 -0
  14. package/dist/current-selection.js +94 -0
  15. package/dist/errors.d.ts +19 -0
  16. package/dist/errors.js +37 -0
  17. package/dist/genie/DateTime.d.ts +66 -0
  18. package/dist/genie/DateTime.js +399 -0
  19. package/dist/genie/TimeDelta.d.ts +35 -0
  20. package/dist/genie/TimeDelta.js +169 -0
  21. package/dist/genie-view-wrapper.d.ts +1 -0
  22. package/dist/genie-view-wrapper.js +377 -0
  23. package/dist/hooks/__tests__/useSpeechRecognition.test.d.ts +1 -0
  24. package/dist/hooks/useSpeechRecognition.d.ts +28 -0
  25. package/dist/hooks/useSpeechRecognition.js +118 -0
  26. package/dist/index.d.ts +30 -0
  27. package/dist/index.js +469 -0
  28. package/dist/logger.d.ts +23 -0
  29. package/dist/logger.js +597 -0
  30. package/dist/logger.remote.test.d.ts +0 -0
  31. package/dist/modality-provider-v2.d.ts +28 -0
  32. package/dist/modality-provider-v2.js +1321 -0
  33. package/dist/modality-provider.d.ts +22 -0
  34. package/dist/modality-provider.js +373 -0
  35. package/dist/native-visibility.d.ts +28 -0
  36. package/dist/native-visibility.js +50 -0
  37. package/dist/platform/VoiceRecognitionBar.d.ts +17 -0
  38. package/dist/platform/VoiceRecognitionBar.js +332 -0
  39. package/dist/platform/components.d.ts +32 -0
  40. package/dist/platform/components.js +351 -0
  41. package/dist/platform/events.d.ts +31 -0
  42. package/dist/platform/events.js +274 -0
  43. package/dist/platform/index.d.ts +3 -0
  44. package/dist/platform/index.js +39 -0
  45. package/dist/platform/types.d.ts +79 -0
  46. package/dist/platform/types.js +97 -0
  47. package/dist/react-decorators.d.ts +87 -0
  48. package/dist/react-decorators.js +368 -0
  49. package/dist/shared-store.d.ts +74 -0
  50. package/dist/shared-store.js +589 -0
  51. package/dist/speech-recognition/__tests__/speech-recognition-groq-transport.test.d.ts +1 -0
  52. package/dist/speech-recognition/__tests__/speech-recognition-native.test.d.ts +1 -0
  53. package/dist/speech-recognition/__tests__/speech-recognition-openai-native.test.d.ts +1 -0
  54. package/dist/speech-recognition/__tests__/speech-recognition-openai.test.d.ts +1 -0
  55. package/dist/speech-recognition/__tests__/speech-recognition-unified-import.test.d.ts +0 -0
  56. package/dist/speech-recognition/__tests__/speech-recognition-unified.test.d.ts +1 -0
  57. package/dist/speech-recognition/speech-recognition-groq.d.ts +21 -0
  58. package/dist/speech-recognition/speech-recognition-groq.js +409 -0
  59. package/dist/speech-recognition/speech-recognition-mlx.d.ts +15 -0
  60. package/dist/speech-recognition/speech-recognition-mlx.js +393 -0
  61. package/dist/speech-recognition/speech-recognition-native.d.ts +24 -0
  62. package/dist/speech-recognition/speech-recognition-native.js +632 -0
  63. package/dist/speech-recognition/speech-recognition-openai-native.d.ts +40 -0
  64. package/dist/speech-recognition/speech-recognition-openai-native.js +653 -0
  65. package/dist/speech-recognition/speech-recognition-openai.d.ts +39 -0
  66. package/dist/speech-recognition/speech-recognition-openai.js +718 -0
  67. package/dist/speech-recognition/speech-recognition-unified.d.ts +93 -0
  68. package/dist/speech-recognition/speech-recognition-unified.js +589 -0
  69. package/dist/speech-recognition/utils/groq-transcription.d.ts +41 -0
  70. package/dist/speech-recognition/utils/groq-transcription.js +382 -0
  71. package/dist/speech-recognition.d.ts +7 -0
  72. package/dist/speech-recognition.js +61 -0
  73. package/dist/voice-pipeline-telemetry.d.ts +26 -0
  74. package/dist/voice-pipeline-telemetry.js +15 -0
  75. package/garrix82-reactgenie-lib-1.3.0.tgz +0 -0
  76. package/metro/index.js +3 -0
  77. package/metro/with-genie-registry.js +47 -0
  78. package/package.json +111 -0
  79. package/scripts/dry-run.js +23 -0
  80. package/scripts/generate-genie-registry.js +278 -0
  81. package/scripts/log-file-test.js +51 -0
  82. package/scripts/parse.js +26 -0
  83. package/scripts/prompt.js +19 -0
  84. package/scripts/set-script.js +200 -0
  85. package/tsconfig.json +36 -0
@@ -0,0 +1,521 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.buildQueryParamsFromNavState = buildQueryParamsFromNavState;
7
+ exports.getRegisteredRoutes = getRegisteredRoutes;
8
+ exports.getRouteMap = getRouteMap;
9
+ exports.isExpoRouterAvailable = isExpoRouterAvailable;
10
+ exports.registerGenieRoute = registerGenieRoute;
11
+ exports.useExpoRouterAdapter = useExpoRouterAdapter;
12
+ exports.useRegisterGenieRoute = useRegisterGenieRoute;
13
+ exports.withExpoRouterAdapter = withExpoRouterAdapter;
14
+ var _react = _interopRequireWildcard(require("react"));
15
+ var _sharedStore = require("../shared-store");
16
+ var _reactgenieDsl = require("@garrix82/reactgenie-dsl");
17
+ var _logger = require("../logger");
18
+ 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); }
19
+ 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; }
20
+ 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; }
21
+ 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; }
22
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
23
+ 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); } /**
24
+ * Expo Router Adapter for ReactGenie
25
+ *
26
+ * Automatically handles navigation compatibility between ReactGenie's
27
+ * programmatic navigation and expo-router's file-based routing.
28
+ *
29
+ * Routes are auto-discovered from the actual file paths where components are used,
30
+ * not inferred from component names.
31
+ */
32
+ // Try to import expo-router dynamically (optional peer dependency)
33
+ let useRouter = null;
34
+ let useSegments = null;
35
+ let usePathname = null;
36
+ let useLocalSearchParams = null;
37
+ try {
38
+ const expoRouter = require('expo-router');
39
+ useRouter = expoRouter.useRouter;
40
+ useSegments = expoRouter.useSegments;
41
+ usePathname = expoRouter.usePathname;
42
+ useLocalSearchParams = expoRouter.useLocalSearchParams;
43
+ } catch (e) {
44
+ // expo-router not available, adapter will be no-op
45
+ }
46
+
47
+ /**
48
+ * Route registration info with metadata for duplicate detection
49
+ */
50
+
51
+ /**
52
+ * Internal function to reset navigation state
53
+ * Prevents infinite navigation loops by clearing navState after routing
54
+ */
55
+ function resetGenieNavigation() {
56
+ (0, _reactgenieDsl.genieDispatch)(() => {
57
+ const reactGenieState = _reactgenieDsl.sharedState;
58
+ reactGenieState.navState = {
59
+ objectViewClassName: null,
60
+ objectConstructorParams: null,
61
+ queryIntent: null,
62
+ resultRef: null,
63
+ resultObjectType: null
64
+ };
65
+ });
66
+ }
67
+
68
+ /**
69
+ * Auto-discovered route registry built from actual file paths
70
+ * Maps decorator class names to their actual route file locations
71
+ *
72
+ * Key: View class name (e.g., "CounterView")
73
+ * Value: Route registration info with path and duplicate detection
74
+ */
75
+ const AUTO_ROUTE_REGISTRY = new Map();
76
+
77
+ /**
78
+ * Extract dynamic segment names from an expo-router path.
79
+ * Examples:
80
+ * - /probes/[probeId] -> ["probeId"]
81
+ * - /files/[...path] -> ["path"]
82
+ * - /blog/[[...slug]] -> ["slug"]
83
+ */
84
+ function getDynamicParamNames(routePath) {
85
+ if (!routePath) {
86
+ return [];
87
+ }
88
+
89
+ // Normalize optional catch-all segments: [[...slug]] -> [...slug]
90
+ const normalized = routePath.replace(/\[\[/g, '[').replace(/\]\]/g, ']');
91
+ const matches = normalized.match(/\[([^\]]+)\]/g) || [];
92
+ return matches.map(segment => segment.slice(1, -1).replace(/^\.\.\./, '')).filter(name => name.length > 0);
93
+ }
94
+
95
+ /**
96
+ * Keep only params that map to dynamic segments in the route path.
97
+ * This prevents extra Genie params from becoming query strings.
98
+ */
99
+ function filterParamsForRoute(routePath, params) {
100
+ if (!params || typeof params !== 'object') {
101
+ return {};
102
+ }
103
+ const paramNames = getDynamicParamNames(routePath);
104
+ if (paramNames.length === 0) {
105
+ return {};
106
+ }
107
+ const filtered = {};
108
+ for (const name of paramNames) {
109
+ if (params[name] !== undefined && params[name] !== null) {
110
+ filtered[name] = params[name];
111
+ }
112
+ }
113
+ return filtered;
114
+ }
115
+ function sanitizeFieldName(field) {
116
+ return field.replace(/[^a-zA-Z0-9_.-]/g, '_');
117
+ }
118
+ function toQueryParamValue(value) {
119
+ if (value === null || value === undefined) return null;
120
+ if (typeof value === 'string') return value;
121
+ if (typeof value === 'number' || typeof value === 'boolean') return String(value);
122
+ return null;
123
+ }
124
+ function setQueryParam(params, key, value) {
125
+ const normalized = toQueryParamValue(value);
126
+ if (normalized === null) return;
127
+ let candidate = key;
128
+ let i = 1;
129
+ while (params[candidate] !== undefined) {
130
+ candidate = `${key}_${i}`;
131
+ i += 1;
132
+ }
133
+ params[candidate] = normalized;
134
+ }
135
+ function buildQueryParamsFromNavState(navState) {
136
+ const params = {};
137
+ if (navState.resultRef) {
138
+ params.rg_result = String(navState.resultRef);
139
+ }
140
+ if (navState.queryIntent?.hash) {
141
+ params.rg_qh = navState.queryIntent.hash;
142
+ }
143
+ const ops = navState.queryIntent?.ops ?? [];
144
+ for (const op of ops) {
145
+ if (op.kind === 'matching' || op.kind === 'contains' || op.kind === 'equals') {
146
+ setQueryParam(params, `q_${op.kind}_${sanitizeFieldName(op.field)}`, op.value);
147
+ continue;
148
+ }
149
+ if (op.kind === 'between') {
150
+ setQueryParam(params, `q_between_${sanitizeFieldName(op.field)}_from`, op.from);
151
+ setQueryParam(params, `q_between_${sanitizeFieldName(op.field)}_to`, op.to);
152
+ continue;
153
+ }
154
+ if (op.kind === 'sort') {
155
+ setQueryParam(params, 'q_sort', `${sanitizeFieldName(op.field)}:${op.ascending ? 'asc' : 'desc'}`);
156
+ continue;
157
+ }
158
+ if (op.kind === 'index') {
159
+ setQueryParam(params, 'q_index', op.value);
160
+ continue;
161
+ }
162
+ if (op.kind === 'length') {
163
+ setQueryParam(params, 'q_length', 'true');
164
+ continue;
165
+ }
166
+ }
167
+ return Object.keys(params).sort((a, b) => a.localeCompare(b)).reduce((acc, key) => {
168
+ acc[key] = params[key];
169
+ return acc;
170
+ }, {});
171
+ }
172
+
173
+ /**
174
+ * Type guard to check if a view class name has already been registered
175
+ */
176
+ function isViewClassRegistered(viewClassName) {
177
+ return AUTO_ROUTE_REGISTRY.has(viewClassName);
178
+ }
179
+
180
+ /**
181
+ * Get registration info for a view class (for error messages)
182
+ */
183
+ function getRegistrationInfo(viewClassName) {
184
+ return AUTO_ROUTE_REGISTRY.get(viewClassName);
185
+ }
186
+
187
+ /**
188
+ * Generate unique view class name for dynamic routes
189
+ *
190
+ * Handles dynamic segments by appending normalized segment names:
191
+ * - /probes → "ProbeView"
192
+ * - /probes/[id] → "ProbeView_id"
193
+ * - /probes/[id]/edit → "ProbeView_id_edit"
194
+ * - /probes/[slug]/comments/[commentId] → "ProbeView_slug_comments_commentId"
195
+ *
196
+ * @param baseClassName - The base view class name (e.g., "ProbeView")
197
+ * @param routePath - The route path (e.g., "/probes/[id]")
198
+ * @returns Unique view class name
199
+ */
200
+ function generateUniqueViewClassName(baseClassName, routePath) {
201
+ // Extract dynamic segments: [id], [slug], etc.
202
+ const dynamicSegments = routePath.match(/\[([^\]]+)\]/g);
203
+ if (!dynamicSegments || dynamicSegments.length === 0) {
204
+ // No dynamic segments, return base name
205
+ return baseClassName;
206
+ }
207
+
208
+ // Remove brackets and join with underscore
209
+ // [id] → id, [slug] → slug
210
+ const segmentNames = dynamicSegments.map(seg => seg.replace(/[\[\]]/g, '')).join('_');
211
+ return `${baseClassName}_${segmentNames}`;
212
+ }
213
+
214
+ /**
215
+ * Registers a route with its actual file path from expo-router
216
+ *
217
+ * This should be called from route files (app directory), not from component files.
218
+ * The route path is auto-discovered from the file location.
219
+ *
220
+ * **Duplicate Detection**: If a view class is already registered to a different route,
221
+ * a runtime error will be thrown with details about both registrations.
222
+ *
223
+ * @param viewClassName - The name of the view class being rendered on this route
224
+ * @param routePath - Optional explicit path, otherwise auto-discovered from current route
225
+ *
226
+ * @throws Error if viewClassName is already registered to a different route
227
+ *
228
+ * @example
229
+ * // In app/genie/counter.tsx
230
+ * import { useRegisterGenieRoute } from '@garrix82/reactgenie-lib';
231
+ *
232
+ * export default function CounterRoute() {
233
+ * useRegisterGenieRoute('CounterView'); // Auto-discovers: /genie/counter
234
+ * return <CounterView />;
235
+ * }
236
+ *
237
+ * @example
238
+ * // Dynamic route: app/genie/[id].tsx
239
+ * export default function DynamicCounterRoute() {
240
+ * useRegisterGenieRoute('CounterView'); // Auto-discovers: /genie/[id]
241
+ * return <CounterView />;
242
+ * }
243
+ */
244
+ function useRegisterGenieRoute(baseViewClassName, routePath) {
245
+ // Only works if expo-router is available
246
+ if (!usePathname) {
247
+ return;
248
+ }
249
+ const pathname = usePathname();
250
+ (0, _react.useEffect)(() => {
251
+ const path = routePath || pathname;
252
+ if (path && baseViewClassName) {
253
+ // Generate unique view class name for dynamic routes
254
+ const viewClassName = generateUniqueViewClassName(baseViewClassName, path);
255
+ const existingRegistration = getRegistrationInfo(viewClassName);
256
+
257
+ // Auto registry already owns this view class; ignore runtime registration.
258
+ if (existingRegistration && existingRegistration.source === "auto") {
259
+ if (routePath && existingRegistration.routePath !== path) {
260
+ console.warn(`[ReactGenie] Skipping runtime registration for "${viewClassName}" ` + `(${path}). Auto registry already mapped it to "${existingRegistration.routePath}".`);
261
+ }
262
+ return;
263
+ }
264
+
265
+ // Check for duplicate runtime registration
266
+ if (existingRegistration && existingRegistration.routePath !== path) {
267
+ const errorMsg = `[ReactGenie] ERROR: Duplicate registration detected!\n` + `View class "${viewClassName}" is already registered.\n\n` + `Existing registration:\n` + ` Route: ${existingRegistration.routePath}\n` + ` File: ${existingRegistration.registeredAt}\n\n` + `New registration attempt:\n` + ` Route: ${path}\n\n` + `Each view class can only be registered to ONE route.\n` + `Please use a different view class name for the second route,\n` + `or remove one of the registrations.`;
268
+ console.error(errorMsg);
269
+ throw new Error(errorMsg);
270
+ }
271
+
272
+ // Register the route with metadata
273
+ AUTO_ROUTE_REGISTRY.set(viewClassName, {
274
+ viewClassName,
275
+ routePath: path,
276
+ registeredAt: path,
277
+ // Use pathname as "file location"
278
+ source: "runtime"
279
+ });
280
+
281
+ // console.log(`[ReactGenie] Registered route: ${viewClassName} → ${path}`);
282
+ }
283
+ }, [baseViewClassName, pathname, routePath]);
284
+ }
285
+
286
+ /**
287
+ * Alternative: Register route without hook (for use outside React components)
288
+ *
289
+ * **Duplicate Detection**: Throws error if view class already registered to different route.
290
+ *
291
+ * @param viewClassName - The name of the view class
292
+ * @param routePath - The file-based route path where this view is used
293
+ * @throws Error if viewClassName is already registered to a different route
294
+ */
295
+ function registerGenieRoute(viewClassName, routePath) {
296
+ // Check for duplicate registration
297
+ const existingRegistration = getRegistrationInfo(viewClassName);
298
+ if (existingRegistration && existingRegistration.routePath !== routePath) {
299
+ const errorMsg = `[ReactGenie] ERROR: Duplicate registration detected!\n` + `View class "${viewClassName}" is already registered.\n\n` + `Existing registration:\n` + ` Route: ${existingRegistration.routePath}\n` + ` File: ${existingRegistration.registeredAt}\n\n` + `New registration attempt:\n` + ` Route: ${routePath}\n\n` + `Each view class can only be registered to ONE route.\n` + `Please use a different view class name for the second route,\n` + `or remove one of the registrations.`;
300
+ console.error(errorMsg);
301
+ throw new Error(errorMsg);
302
+ }
303
+ AUTO_ROUTE_REGISTRY.set(viewClassName, {
304
+ viewClassName,
305
+ routePath,
306
+ registeredAt: routePath,
307
+ source: "auto"
308
+ });
309
+ // console.log(`[ReactGenie] Registered route: ${viewClassName} → ${routePath}`);
310
+ }
311
+
312
+ /**
313
+ * Gets the route path for a view class name
314
+ */
315
+ function getRouteForView(viewClassName) {
316
+ const registration = AUTO_ROUTE_REGISTRY.get(viewClassName);
317
+ return registration?.routePath || null;
318
+ }
319
+ function splitRouteSegments(path) {
320
+ if (!path || path === '/') {
321
+ return [];
322
+ }
323
+ return path.split('/').filter(segment => segment.length > 0);
324
+ }
325
+ function isDynamicSegment(segment) {
326
+ return segment.startsWith('[') && segment.endsWith(']');
327
+ }
328
+ function isCatchAllSegment(segment) {
329
+ return segment.startsWith('[...') && segment.endsWith(']');
330
+ }
331
+ function isOptionalCatchAllSegment(segment) {
332
+ return segment.startsWith('[[...') && segment.endsWith(']]');
333
+ }
334
+ function routeTemplateMatchesPath(routeTemplate, pathname) {
335
+ const templateSegments = splitRouteSegments(routeTemplate);
336
+ const pathSegments = splitRouteSegments(pathname);
337
+ let templateIndex = 0;
338
+ let pathIndex = 0;
339
+ while (templateIndex < templateSegments.length) {
340
+ const templateSegment = templateSegments[templateIndex];
341
+ if (isOptionalCatchAllSegment(templateSegment)) {
342
+ return true;
343
+ }
344
+ if (isCatchAllSegment(templateSegment)) {
345
+ return pathIndex < pathSegments.length;
346
+ }
347
+ const pathSegment = pathSegments[pathIndex];
348
+ if (pathSegment === undefined) {
349
+ return false;
350
+ }
351
+ if (isDynamicSegment(templateSegment)) {
352
+ templateIndex += 1;
353
+ pathIndex += 1;
354
+ continue;
355
+ }
356
+ if (templateSegment !== pathSegment) {
357
+ return false;
358
+ }
359
+ templateIndex += 1;
360
+ pathIndex += 1;
361
+ }
362
+ return pathIndex === pathSegments.length;
363
+ }
364
+ function getRouteSpecificity(routeTemplate) {
365
+ const segments = splitRouteSegments(routeTemplate);
366
+ const staticSegments = segments.filter(segment => !isDynamicSegment(segment)).length;
367
+ return staticSegments * 100 + segments.length;
368
+ }
369
+ function getCurrentRouteTemplate(pathname) {
370
+ const candidates = [];
371
+ AUTO_ROUTE_REGISTRY.forEach(info => {
372
+ if (routeTemplateMatchesPath(info.routePath, pathname)) {
373
+ candidates.push(info.routePath);
374
+ }
375
+ });
376
+ if (candidates.length === 0) {
377
+ return null;
378
+ }
379
+ candidates.sort((a, b) => getRouteSpecificity(b) - getRouteSpecificity(a));
380
+ return candidates[0];
381
+ }
382
+
383
+ /**
384
+ * Hook that automatically intercepts ReactGenie navigation and routes via expo-router
385
+ *
386
+ * Routes are auto-discovered from where components are actually used, not inferred.
387
+ *
388
+ * Usage: Import and call in your root _layout.tsx (inside Provider context):
389
+ * ```tsx
390
+ * import { useExpoRouterAdapter } from '@garrix82/reactgenie-lib';
391
+ *
392
+ * function RootLayoutContent() {
393
+ * useExpoRouterAdapter(); // <- Add this line
394
+ * // ... rest of layout
395
+ * }
396
+ * ```
397
+ */
398
+ function useExpoRouterAdapter() {
399
+ // Check if expo-router is available
400
+ if (!useRouter || !useSegments) {
401
+ // No expo-router, navigation will fall back to react-navigation
402
+ return;
403
+ }
404
+ const router = useRouter();
405
+ const pathname = usePathname ? usePathname() : '';
406
+ const localSearchParams = useLocalSearchParams ? useLocalSearchParams() : {};
407
+ const navState = (0, _sharedStore.useGenieSelector)(state => state.navState);
408
+ const navStack = (0, _sharedStore.useGenieSelector)(state => state.navStack);
409
+ const lastHandledNavStackRef = (0, _react.useRef)(0);
410
+ (0, _react.useEffect)(() => {
411
+ if (!navState?.objectViewClassName) {
412
+ return;
413
+ }
414
+ if (navStack <= lastHandledNavStackRef.current) {
415
+ _logger.logger.debug(`[ReactGenieNav] reason=ignored_duplicate_event navStack=${navStack} lastHandled=${lastHandledNavStackRef.current}`);
416
+ return;
417
+ }
418
+ const eventId = navStack;
419
+ const viewClassName = navState.objectViewClassName;
420
+ const params = navState.objectConstructorParams;
421
+ try {
422
+ const routePath = getRouteForView(viewClassName);
423
+ if (!routePath) {
424
+ _logger.logger.warn(`[ReactGenieNav] reason=skipped_unregistered_view event=${eventId} view=${viewClassName}`);
425
+ return;
426
+ }
427
+ _logger.logger.debug(`[ReactGenie] Auto-routing: ${viewClassName} → ${routePath}`);
428
+ _logger.logger.debug(`[ReactGenie] Navigation params:`, params);
429
+ const routeParams = filterParamsForRoute(routePath, params);
430
+ const queryParams = buildQueryParamsFromNavState(navState);
431
+ const dynamicParamNames = getDynamicParamNames(routePath);
432
+ const missingParams = dynamicParamNames.filter(name => routeParams[name] === undefined || routeParams[name] === null);
433
+ if (dynamicParamNames.length > 0 && missingParams.length > 0) {
434
+ _logger.logger.warn(`[ReactGenieNav] reason=skipped_missing_params event=${eventId} view=${viewClassName} missing=${missingParams.join(',')}`);
435
+ return;
436
+ }
437
+ const activeTemplate = getCurrentRouteTemplate(pathname || '');
438
+ const dynamicParamsUnchanged = dynamicParamNames.every(name => {
439
+ const current = Array.isArray(localSearchParams?.[name]) ? localSearchParams[name][0] : localSearchParams?.[name];
440
+ return String(current ?? '') === String(routeParams[name] ?? '');
441
+ });
442
+ const shouldReplace = activeTemplate !== null && activeTemplate === routePath && dynamicParamsUnchanged;
443
+ const destinationParams = _objectSpread(_objectSpread({}, routeParams), queryParams);
444
+ const hasParams = Object.keys(destinationParams).length > 0;
445
+ if (hasParams) {
446
+ const destination = {
447
+ pathname: routePath,
448
+ params: destinationParams
449
+ };
450
+ if (shouldReplace && typeof router.replace === 'function') {
451
+ router.replace(destination);
452
+ } else {
453
+ router.push(destination);
454
+ }
455
+ } else if (shouldReplace && typeof router.replace === 'function') {
456
+ router.replace(routePath);
457
+ } else {
458
+ router.push(routePath);
459
+ }
460
+ _logger.logger.info(`[ReactGenieNav] reason=${shouldReplace ? 'handled_replace' : 'handled_push'} event=${eventId} view=${viewClassName} route=${routePath}`);
461
+ } catch (error) {
462
+ console.error(`[ReactGenie] Navigation error:`, error);
463
+ } finally {
464
+ lastHandledNavStackRef.current = eventId;
465
+ // Reset navigation state to prevent infinite loops after handling this event.
466
+ resetGenieNavigation();
467
+ }
468
+ }, [navStack, navState, pathname, localSearchParams, router]);
469
+ }
470
+
471
+ /**
472
+ * Higher-order component that wraps your root layout with expo-router adapter
473
+ *
474
+ * Usage:
475
+ * ```tsx
476
+ * import { withExpoRouterAdapter } from '@garrix82/reactgenie-lib';
477
+ *
478
+ * function RootLayout() {
479
+ * return (
480
+ * <Provider store={reactGenieStore}>
481
+ * <Stack>...</Stack>
482
+ * </Provider>
483
+ * );
484
+ * }
485
+ *
486
+ * export default withExpoRouterAdapter(RootLayout);
487
+ * ```
488
+ */
489
+ function withExpoRouterAdapter(Component) {
490
+ return function ExpoRouterAdapterWrapper(props) {
491
+ useExpoRouterAdapter();
492
+ return /*#__PURE__*/_react.default.createElement(Component, props);
493
+ };
494
+ }
495
+
496
+ /**
497
+ * Utility to check if expo-router is available
498
+ */
499
+ function isExpoRouterAvailable() {
500
+ return useRouter !== null && useSegments !== null;
501
+ }
502
+
503
+ /**
504
+ * Get all registered routes (for debugging)
505
+ * Returns a copy of the registration map with full metadata
506
+ */
507
+ function getRegisteredRoutes() {
508
+ return new Map(AUTO_ROUTE_REGISTRY);
509
+ }
510
+
511
+ /**
512
+ * Get simple route map (viewClassName → routePath) for debugging
513
+ */
514
+ function getRouteMap() {
515
+ const simpleMap = new Map();
516
+ AUTO_ROUTE_REGISTRY.forEach((info, viewClassName) => {
517
+ simpleMap.set(viewClassName, info.routePath);
518
+ });
519
+ return simpleMap;
520
+ }
521
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJfcmVhY3QiLCJfaW50ZXJvcFJlcXVpcmVXaWxkY2FyZCIsInJlcXVpcmUiLCJfc2hhcmVkU3RvcmUiLCJfcmVhY3RnZW5pZURzbCIsIl9sb2dnZXIiLCJlIiwidCIsIldlYWtNYXAiLCJyIiwibiIsIl9fZXNNb2R1bGUiLCJvIiwiaSIsImYiLCJfX3Byb3RvX18iLCJkZWZhdWx0IiwiaGFzIiwiZ2V0Iiwic2V0IiwiaGFzT3duUHJvcGVydHkiLCJjYWxsIiwiT2JqZWN0IiwiZGVmaW5lUHJvcGVydHkiLCJnZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IiLCJvd25LZXlzIiwia2V5cyIsImdldE93blByb3BlcnR5U3ltYm9scyIsImZpbHRlciIsImVudW1lcmFibGUiLCJwdXNoIiwiYXBwbHkiLCJfb2JqZWN0U3ByZWFkIiwiYXJndW1lbnRzIiwibGVuZ3RoIiwiZm9yRWFjaCIsIl9kZWZpbmVQcm9wZXJ0eSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvcnMiLCJkZWZpbmVQcm9wZXJ0aWVzIiwiX3RvUHJvcGVydHlLZXkiLCJ2YWx1ZSIsImNvbmZpZ3VyYWJsZSIsIndyaXRhYmxlIiwiX3RvUHJpbWl0aXZlIiwiU3ltYm9sIiwidG9QcmltaXRpdmUiLCJUeXBlRXJyb3IiLCJTdHJpbmciLCJOdW1iZXIiLCJ1c2VSb3V0ZXIiLCJ1c2VTZWdtZW50cyIsInVzZVBhdGhuYW1lIiwidXNlTG9jYWxTZWFyY2hQYXJhbXMiLCJleHBvUm91dGVyIiwicmVzZXRHZW5pZU5hdmlnYXRpb24iLCJnZW5pZURpc3BhdGNoIiwicmVhY3RHZW5pZVN0YXRlIiwic2hhcmVkU3RhdGUiLCJuYXZTdGF0ZSIsIm9iamVjdFZpZXdDbGFzc05hbWUiLCJvYmplY3RDb25zdHJ1Y3RvclBhcmFtcyIsInF1ZXJ5SW50ZW50IiwicmVzdWx0UmVmIiwicmVzdWx0T2JqZWN0VHlwZSIsIkFVVE9fUk9VVEVfUkVHSVNUUlkiLCJNYXAiLCJnZXREeW5hbWljUGFyYW1OYW1lcyIsInJvdXRlUGF0aCIsIm5vcm1hbGl6ZWQiLCJyZXBsYWNlIiwibWF0Y2hlcyIsIm1hdGNoIiwibWFwIiwic2VnbWVudCIsInNsaWNlIiwibmFtZSIsImZpbHRlclBhcmFtc0ZvclJvdXRlIiwicGFyYW1zIiwicGFyYW1OYW1lcyIsImZpbHRlcmVkIiwidW5kZWZpbmVkIiwic2FuaXRpemVGaWVsZE5hbWUiLCJmaWVsZCIsInRvUXVlcnlQYXJhbVZhbHVlIiwic2V0UXVlcnlQYXJhbSIsImtleSIsImNhbmRpZGF0ZSIsImJ1aWxkUXVlcnlQYXJhbXNGcm9tTmF2U3RhdGUiLCJyZ19yZXN1bHQiLCJoYXNoIiwicmdfcWgiLCJvcHMiLCJvcCIsImtpbmQiLCJmcm9tIiwidG8iLCJhc2NlbmRpbmciLCJzb3J0IiwiYSIsImIiLCJsb2NhbGVDb21wYXJlIiwicmVkdWNlIiwiYWNjIiwiaXNWaWV3Q2xhc3NSZWdpc3RlcmVkIiwidmlld0NsYXNzTmFtZSIsImdldFJlZ2lzdHJhdGlvbkluZm8iLCJnZW5lcmF0ZVVuaXF1ZVZpZXdDbGFzc05hbWUiLCJiYXNlQ2xhc3NOYW1lIiwiZHluYW1pY1NlZ21lbnRzIiwic2VnbWVudE5hbWVzIiwic2VnIiwiam9pbiIsInVzZVJlZ2lzdGVyR2VuaWVSb3V0ZSIsImJhc2VWaWV3Q2xhc3NOYW1lIiwicGF0aG5hbWUiLCJ1c2VFZmZlY3QiLCJwYXRoIiwiZXhpc3RpbmdSZWdpc3RyYXRpb24iLCJzb3VyY2UiLCJjb25zb2xlIiwid2FybiIsImVycm9yTXNnIiwicmVnaXN0ZXJlZEF0IiwiZXJyb3IiLCJFcnJvciIsInJlZ2lzdGVyR2VuaWVSb3V0ZSIsImdldFJvdXRlRm9yVmlldyIsInJlZ2lzdHJhdGlvbiIsInNwbGl0Um91dGVTZWdtZW50cyIsInNwbGl0IiwiaXNEeW5hbWljU2VnbWVudCIsInN0YXJ0c1dpdGgiLCJlbmRzV2l0aCIsImlzQ2F0Y2hBbGxTZWdtZW50IiwiaXNPcHRpb25hbENhdGNoQWxsU2VnbWVudCIsInJvdXRlVGVtcGxhdGVNYXRjaGVzUGF0aCIsInJvdXRlVGVtcGxhdGUiLCJ0ZW1wbGF0ZVNlZ21lbnRzIiwicGF0aFNlZ21lbnRzIiwidGVtcGxhdGVJbmRleCIsInBhdGhJbmRleCIsInRlbXBsYXRlU2VnbWVudCIsInBhdGhTZWdtZW50IiwiZ2V0Um91dGVTcGVjaWZpY2l0eSIsInNlZ21lbnRzIiwic3RhdGljU2VnbWVudHMiLCJnZXRDdXJyZW50Um91dGVUZW1wbGF0ZSIsImNhbmRpZGF0ZXMiLCJpbmZvIiwidXNlRXhwb1JvdXRlckFkYXB0ZXIiLCJyb3V0ZXIiLCJsb2NhbFNlYXJjaFBhcmFtcyIsInVzZUdlbmllU2VsZWN0b3IiLCJzdGF0ZSIsIm5hdlN0YWNrIiwibGFzdEhhbmRsZWROYXZTdGFja1JlZiIsInVzZVJlZiIsImN1cnJlbnQiLCJsb2dnZXIiLCJkZWJ1ZyIsImV2ZW50SWQiLCJyb3V0ZVBhcmFtcyIsInF1ZXJ5UGFyYW1zIiwiZHluYW1pY1BhcmFtTmFtZXMiLCJtaXNzaW5nUGFyYW1zIiwiYWN0aXZlVGVtcGxhdGUiLCJkeW5hbWljUGFyYW1zVW5jaGFuZ2VkIiwiZXZlcnkiLCJBcnJheSIsImlzQXJyYXkiLCJzaG91bGRSZXBsYWNlIiwiZGVzdGluYXRpb25QYXJhbXMiLCJoYXNQYXJhbXMiLCJkZXN0aW5hdGlvbiIsIndpdGhFeHBvUm91dGVyQWRhcHRlciIsIkNvbXBvbmVudCIsIkV4cG9Sb3V0ZXJBZGFwdGVyV3JhcHBlciIsInByb3BzIiwiY3JlYXRlRWxlbWVudCIsImlzRXhwb1JvdXRlckF2YWlsYWJsZSIsImdldFJlZ2lzdGVyZWRSb3V0ZXMiLCJnZXRSb3V0ZU1hcCIsInNpbXBsZU1hcCJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9hZGFwdGVycy9leHBvLXJvdXRlci1hZGFwdGVyLnRzeCJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEV4cG8gUm91dGVyIEFkYXB0ZXIgZm9yIFJlYWN0R2VuaWVcbiAqIFxuICogQXV0b21hdGljYWxseSBoYW5kbGVzIG5hdmlnYXRpb24gY29tcGF0aWJpbGl0eSBiZXR3ZWVuIFJlYWN0R2VuaWUnc1xuICogcHJvZ3JhbW1hdGljIG5hdmlnYXRpb24gYW5kIGV4cG8tcm91dGVyJ3MgZmlsZS1iYXNlZCByb3V0aW5nLlxuICogXG4gKiBSb3V0ZXMgYXJlIGF1dG8tZGlzY292ZXJlZCBmcm9tIHRoZSBhY3R1YWwgZmlsZSBwYXRocyB3aGVyZSBjb21wb25lbnRzIGFyZSB1c2VkLFxuICogbm90IGluZmVycmVkIGZyb20gY29tcG9uZW50IG5hbWVzLlxuICovXG5cbmltcG9ydCBSZWFjdCwgeyB1c2VFZmZlY3QsIHVzZVJlZiB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHVzZUdlbmllU2VsZWN0b3IgfSBmcm9tICcuLi9zaGFyZWQtc3RvcmUnO1xuaW1wb3J0IHsgZ2VuaWVEaXNwYXRjaCwgc2hhcmVkU3RhdGUgfSBmcm9tICdAZ2Fycml4ODIvcmVhY3RnZW5pZS1kc2wnO1xuaW1wb3J0IHR5cGUgeyBSZWFjdEdlbmllU3RhdGUsIE5hdmlnYXRvclN0YXRlIH0gZnJvbSAnLi4vc2hhcmVkLXN0b3JlJztcbmltcG9ydCB7IGxvZ2dlciB9IGZyb20gJy4uL2xvZ2dlcic7XG5cbi8vIFRyeSB0byBpbXBvcnQgZXhwby1yb3V0ZXIgZHluYW1pY2FsbHkgKG9wdGlvbmFsIHBlZXIgZGVwZW5kZW5jeSlcbmxldCB1c2VSb3V0ZXI6IGFueSA9IG51bGw7XG5sZXQgdXNlU2VnbWVudHM6IGFueSA9IG51bGw7XG5sZXQgdXNlUGF0aG5hbWU6IGFueSA9IG51bGw7XG5sZXQgdXNlTG9jYWxTZWFyY2hQYXJhbXM6IGFueSA9IG51bGw7XG5cbnRyeSB7XG4gIGNvbnN0IGV4cG9Sb3V0ZXIgPSByZXF1aXJlKCdleHBvLXJvdXRlcicpO1xuICB1c2VSb3V0ZXIgPSBleHBvUm91dGVyLnVzZVJvdXRlcjtcbiAgdXNlU2VnbWVudHMgPSBleHBvUm91dGVyLnVzZVNlZ21lbnRzO1xuICB1c2VQYXRobmFtZSA9IGV4cG9Sb3V0ZXIudXNlUGF0aG5hbWU7XG4gIHVzZUxvY2FsU2VhcmNoUGFyYW1zID0gZXhwb1JvdXRlci51c2VMb2NhbFNlYXJjaFBhcmFtcztcbn0gY2F0Y2ggKGUpIHtcbiAgLy8gZXhwby1yb3V0ZXIgbm90IGF2YWlsYWJsZSwgYWRhcHRlciB3aWxsIGJlIG5vLW9wXG59XG5cbi8qKlxuICogUm91dGUgcmVnaXN0cmF0aW9uIGluZm8gd2l0aCBtZXRhZGF0YSBmb3IgZHVwbGljYXRlIGRldGVjdGlvblxuICovXG5leHBvcnQgdHlwZSBSb3V0ZVJlZ2lzdHJhdGlvbkluZm8gPSB7XG4gIHJlYWRvbmx5IHZpZXdDbGFzc05hbWU6IHN0cmluZztcbiAgcmVhZG9ubHkgcm91dGVQYXRoOiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJlZ2lzdGVyZWRBdDogc3RyaW5nO1xuICByZWFkb25seSBzb3VyY2U6IFwiYXV0b1wiIHwgXCJydW50aW1lXCI7XG59O1xuXG4vKipcbiAqIEludGVybmFsIGZ1bmN0aW9uIHRvIHJlc2V0IG5hdmlnYXRpb24gc3RhdGVcbiAqIFByZXZlbnRzIGluZmluaXRlIG5hdmlnYXRpb24gbG9vcHMgYnkgY2xlYXJpbmcgbmF2U3RhdGUgYWZ0ZXIgcm91dGluZ1xuICovXG5mdW5jdGlvbiByZXNldEdlbmllTmF2aWdhdGlvbigpIHtcbiAgZ2VuaWVEaXNwYXRjaCgoKSA9PiB7XG4gICAgY29uc3QgcmVhY3RHZW5pZVN0YXRlID0gc2hhcmVkU3RhdGUgYXMgUmVhY3RHZW5pZVN0YXRlO1xuICAgIHJlYWN0R2VuaWVTdGF0ZS5uYXZTdGF0ZSA9IHtcbiAgICAgIG9iamVjdFZpZXdDbGFzc05hbWU6IG51bGwsXG4gICAgICBvYmplY3RDb25zdHJ1Y3RvclBhcmFtczogbnVsbCxcbiAgICAgIHF1ZXJ5SW50ZW50OiBudWxsLFxuICAgICAgcmVzdWx0UmVmOiBudWxsLFxuICAgICAgcmVzdWx0T2JqZWN0VHlwZTogbnVsbCxcbiAgICB9O1xuICB9KTtcbn1cblxuLyoqXG4gKiBBdXRvLWRpc2NvdmVyZWQgcm91dGUgcmVnaXN0cnkgYnVpbHQgZnJvbSBhY3R1YWwgZmlsZSBwYXRoc1xuICogTWFwcyBkZWNvcmF0b3IgY2xhc3MgbmFtZXMgdG8gdGhlaXIgYWN0dWFsIHJvdXRlIGZpbGUgbG9jYXRpb25zXG4gKiBcbiAqIEtleTogVmlldyBjbGFzcyBuYW1lIChlLmcuLCBcIkNvdW50ZXJWaWV3XCIpXG4gKiBWYWx1ZTogUm91dGUgcmVnaXN0cmF0aW9uIGluZm8gd2l0aCBwYXRoIGFuZCBkdXBsaWNhdGUgZGV0ZWN0aW9uXG4gKi9cbmNvbnN0IEFVVE9fUk9VVEVfUkVHSVNUUlkgPSBuZXcgTWFwPHN0cmluZywgUm91dGVSZWdpc3RyYXRpb25JbmZvPigpO1xuXG4vKipcbiAqIEV4dHJhY3QgZHluYW1pYyBzZWdtZW50IG5hbWVzIGZyb20gYW4gZXhwby1yb3V0ZXIgcGF0aC5cbiAqIEV4YW1wbGVzOlxuICogLSAvcHJvYmVzL1twcm9iZUlkXSAtPiBbXCJwcm9iZUlkXCJdXG4gKiAtIC9maWxlcy9bLi4ucGF0aF0gLT4gW1wicGF0aFwiXVxuICogLSAvYmxvZy9bWy4uLnNsdWddXSAtPiBbXCJzbHVnXCJdXG4gKi9cbmZ1bmN0aW9uIGdldER5bmFtaWNQYXJhbU5hbWVzKHJvdXRlUGF0aDogc3RyaW5nKTogc3RyaW5nW10ge1xuICBpZiAoIXJvdXRlUGF0aCkge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIC8vIE5vcm1hbGl6ZSBvcHRpb25hbCBjYXRjaC1hbGwgc2VnbWVudHM6IFtbLi4uc2x1Z11dIC0+IFsuLi5zbHVnXVxuICBjb25zdCBub3JtYWxpemVkID0gcm91dGVQYXRoLnJlcGxhY2UoL1xcW1xcWy9nLCAnWycpLnJlcGxhY2UoL1xcXVxcXS9nLCAnXScpO1xuICBjb25zdCBtYXRjaGVzID0gbm9ybWFsaXplZC5tYXRjaCgvXFxbKFteXFxdXSspXFxdL2cpIHx8IFtdO1xuXG4gIHJldHVybiBtYXRjaGVzXG4gICAgLm1hcCgoc2VnbWVudCkgPT4gc2VnbWVudC5zbGljZSgxLCAtMSkucmVwbGFjZSgvXlxcLlxcLlxcLi8sICcnKSlcbiAgICAuZmlsdGVyKChuYW1lKSA9PiBuYW1lLmxlbmd0aCA+IDApO1xufVxuXG4vKipcbiAqIEtlZXAgb25seSBwYXJhbXMgdGhhdCBtYXAgdG8gZHluYW1pYyBzZWdtZW50cyBpbiB0aGUgcm91dGUgcGF0aC5cbiAqIFRoaXMgcHJldmVudHMgZXh0cmEgR2VuaWUgcGFyYW1zIGZyb20gYmVjb21pbmcgcXVlcnkgc3RyaW5ncy5cbiAqL1xuZnVuY3Rpb24gZmlsdGVyUGFyYW1zRm9yUm91dGUocm91dGVQYXRoOiBzdHJpbmcsIHBhcmFtczogYW55KTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gIGlmICghcGFyYW1zIHx8IHR5cGVvZiBwYXJhbXMgIT09ICdvYmplY3QnKSB7XG4gICAgcmV0dXJuIHt9O1xuICB9XG5cbiAgY29uc3QgcGFyYW1OYW1lcyA9IGdldER5bmFtaWNQYXJhbU5hbWVzKHJvdXRlUGF0aCk7XG4gIGlmIChwYXJhbU5hbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB7fTtcbiAgfVxuXG4gIGNvbnN0IGZpbHRlcmVkOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gIGZvciAoY29uc3QgbmFtZSBvZiBwYXJhbU5hbWVzKSB7XG4gICAgaWYgKHBhcmFtc1tuYW1lXSAhPT0gdW5kZWZpbmVkICYmIHBhcmFtc1tuYW1lXSAhPT0gbnVsbCkge1xuICAgICAgZmlsdGVyZWRbbmFtZV0gPSBwYXJhbXNbbmFtZV07XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZpbHRlcmVkO1xufVxuXG5mdW5jdGlvbiBzYW5pdGl6ZUZpZWxkTmFtZShmaWVsZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGZpZWxkLnJlcGxhY2UoL1teYS16QS1aMC05Xy4tXS9nLCAnXycpO1xufVxuXG5mdW5jdGlvbiB0b1F1ZXJ5UGFyYW1WYWx1ZSh2YWx1ZTogdW5rbm93bik6IHN0cmluZyB8IG51bGwge1xuICBpZiAodmFsdWUgPT09IG51bGwgfHwgdmFsdWUgPT09IHVuZGVmaW5lZCkgcmV0dXJuIG51bGw7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSByZXR1cm4gdmFsdWU7XG4gIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInIHx8IHR5cGVvZiB2YWx1ZSA9PT0gJ2Jvb2xlYW4nKSByZXR1cm4gU3RyaW5nKHZhbHVlKTtcbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIHNldFF1ZXJ5UGFyYW0ocGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+LCBrZXk6IHN0cmluZywgdmFsdWU6IHVua25vd24pIHtcbiAgY29uc3Qgbm9ybWFsaXplZCA9IHRvUXVlcnlQYXJhbVZhbHVlKHZhbHVlKTtcbiAgaWYgKG5vcm1hbGl6ZWQgPT09IG51bGwpIHJldHVybjtcbiAgbGV0IGNhbmRpZGF0ZSA9IGtleTtcbiAgbGV0IGkgPSAxO1xuICB3aGlsZSAocGFyYW1zW2NhbmRpZGF0ZV0gIT09IHVuZGVmaW5lZCkge1xuICAgIGNhbmRpZGF0ZSA9IGAke2tleX1fJHtpfWA7XG4gICAgaSArPSAxO1xuICB9XG4gIHBhcmFtc1tjYW5kaWRhdGVdID0gbm9ybWFsaXplZDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUXVlcnlQYXJhbXNGcm9tTmF2U3RhdGUoXG4gIG5hdlN0YXRlOiBOYXZpZ2F0b3JTdGF0ZSxcbik6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBwYXJhbXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcblxuICBpZiAobmF2U3RhdGUucmVzdWx0UmVmKSB7XG4gICAgcGFyYW1zLnJnX3Jlc3VsdCA9IFN0cmluZyhuYXZTdGF0ZS5yZXN1bHRSZWYpO1xuICB9XG5cbiAgaWYgKG5hdlN0YXRlLnF1ZXJ5SW50ZW50Py5oYXNoKSB7XG4gICAgcGFyYW1zLnJnX3FoID0gbmF2U3RhdGUucXVlcnlJbnRlbnQuaGFzaDtcbiAgfVxuXG4gIGNvbnN0IG9wcyA9IG5hdlN0YXRlLnF1ZXJ5SW50ZW50Py5vcHMgPz8gW107XG4gIGZvciAoY29uc3Qgb3Agb2Ygb3BzKSB7XG4gICAgaWYgKG9wLmtpbmQgPT09ICdtYXRjaGluZycgfHwgb3Aua2luZCA9PT0gJ2NvbnRhaW5zJyB8fCBvcC5raW5kID09PSAnZXF1YWxzJykge1xuICAgICAgc2V0UXVlcnlQYXJhbShwYXJhbXMsIGBxXyR7b3Aua2luZH1fJHtzYW5pdGl6ZUZpZWxkTmFtZShvcC5maWVsZCl9YCwgb3AudmFsdWUpO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKG9wLmtpbmQgPT09ICdiZXR3ZWVuJykge1xuICAgICAgc2V0UXVlcnlQYXJhbShwYXJhbXMsIGBxX2JldHdlZW5fJHtzYW5pdGl6ZUZpZWxkTmFtZShvcC5maWVsZCl9X2Zyb21gLCBvcC5mcm9tKTtcbiAgICAgIHNldFF1ZXJ5UGFyYW0ocGFyYW1zLCBgcV9iZXR3ZWVuXyR7c2FuaXRpemVGaWVsZE5hbWUob3AuZmllbGQpfV90b2AsIG9wLnRvKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChvcC5raW5kID09PSAnc29ydCcpIHtcbiAgICAgIHNldFF1ZXJ5UGFyYW0oXG4gICAgICAgIHBhcmFtcyxcbiAgICAgICAgJ3Ffc29ydCcsXG4gICAgICAgIGAke3Nhbml0aXplRmllbGROYW1lKG9wLmZpZWxkKX06JHtvcC5hc2NlbmRpbmcgPyAnYXNjJyA6ICdkZXNjJ31gXG4gICAgICApO1xuICAgICAgY29udGludWU7XG4gICAgfVxuXG4gICAgaWYgKG9wLmtpbmQgPT09ICdpbmRleCcpIHtcbiAgICAgIHNldFF1ZXJ5UGFyYW0ocGFyYW1zLCAncV9pbmRleCcsIG9wLnZhbHVlKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmIChvcC5raW5kID09PSAnbGVuZ3RoJykge1xuICAgICAgc2V0UXVlcnlQYXJhbShwYXJhbXMsICdxX2xlbmd0aCcsICd0cnVlJyk7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gT2JqZWN0LmtleXMocGFyYW1zKVxuICAgIC5zb3J0KChhLCBiKSA9PiBhLmxvY2FsZUNvbXBhcmUoYikpXG4gICAgLnJlZHVjZTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PigoYWNjLCBrZXkpID0+IHtcbiAgICAgIGFjY1trZXldID0gcGFyYW1zW2tleV07XG4gICAgICByZXR1cm4gYWNjO1xuICAgIH0sIHt9KTtcbn1cblxuLyoqXG4gKiBUeXBlIGd1YXJkIHRvIGNoZWNrIGlmIGEgdmlldyBjbGFzcyBuYW1lIGhhcyBhbHJlYWR5IGJlZW4gcmVnaXN0ZXJlZFxuICovXG5mdW5jdGlvbiBpc1ZpZXdDbGFzc1JlZ2lzdGVyZWQodmlld0NsYXNzTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBBVVRPX1JPVVRFX1JFR0lTVFJZLmhhcyh2aWV3Q2xhc3NOYW1lKTtcbn1cblxuLyoqXG4gKiBHZXQgcmVnaXN0cmF0aW9uIGluZm8gZm9yIGEgdmlldyBjbGFzcyAoZm9yIGVycm9yIG1lc3NhZ2VzKVxuICovXG5mdW5jdGlvbiBnZXRSZWdpc3RyYXRpb25JbmZvKHZpZXdDbGFzc05hbWU6IHN0cmluZyk6IFJvdXRlUmVnaXN0cmF0aW9uSW5mbyB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiBBVVRPX1JPVVRFX1JFR0lTVFJZLmdldCh2aWV3Q2xhc3NOYW1lKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSB1bmlxdWUgdmlldyBjbGFzcyBuYW1lIGZvciBkeW5hbWljIHJvdXRlc1xuICogXG4gKiBIYW5kbGVzIGR5bmFtaWMgc2VnbWVudHMgYnkgYXBwZW5kaW5nIG5vcm1hbGl6ZWQgc2VnbWVudCBuYW1lczpcbiAqIC0gL3Byb2JlcyDihpIgXCJQcm9iZVZpZXdcIlxuICogLSAvcHJvYmVzL1tpZF0g4oaSIFwiUHJvYmVWaWV3X2lkXCIgIFxuICogLSAvcHJvYmVzL1tpZF0vZWRpdCDihpIgXCJQcm9iZVZpZXdfaWRfZWRpdFwiXG4gKiAtIC9wcm9iZXMvW3NsdWddL2NvbW1lbnRzL1tjb21tZW50SWRdIOKGkiBcIlByb2JlVmlld19zbHVnX2NvbW1lbnRzX2NvbW1lbnRJZFwiXG4gKiBcbiAqIEBwYXJhbSBiYXNlQ2xhc3NOYW1lIC0gVGhlIGJhc2UgdmlldyBjbGFzcyBuYW1lIChlLmcuLCBcIlByb2JlVmlld1wiKVxuICogQHBhcmFtIHJvdXRlUGF0aCAtIFRoZSByb3V0ZSBwYXRoIChlLmcuLCBcIi9wcm9iZXMvW2lkXVwiKVxuICogQHJldHVybnMgVW5pcXVlIHZpZXcgY2xhc3MgbmFtZVxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZVVuaXF1ZVZpZXdDbGFzc05hbWUoYmFzZUNsYXNzTmFtZTogc3RyaW5nLCByb3V0ZVBhdGg6IHN0cmluZyk6IHN0cmluZyB7XG4gIC8vIEV4dHJhY3QgZHluYW1pYyBzZWdtZW50czogW2lkXSwgW3NsdWddLCBldGMuXG4gIGNvbnN0IGR5bmFtaWNTZWdtZW50cyA9IHJvdXRlUGF0aC5tYXRjaCgvXFxbKFteXFxdXSspXFxdL2cpO1xuICBcbiAgaWYgKCFkeW5hbWljU2VnbWVudHMgfHwgZHluYW1pY1NlZ21lbnRzLmxlbmd0aCA9PT0gMCkge1xuICAgIC8vIE5vIGR5bmFtaWMgc2VnbWVudHMsIHJldHVybiBiYXNlIG5hbWVcbiAgICByZXR1cm4gYmFzZUNsYXNzTmFtZTtcbiAgfVxuICBcbiAgLy8gUmVtb3ZlIGJyYWNrZXRzIGFuZCBqb2luIHdpdGggdW5kZXJzY29yZVxuICAvLyBbaWRdIOKGkiBpZCwgW3NsdWddIOKGkiBzbHVnXG4gIGNvbnN0IHNlZ21lbnROYW1lcyA9IGR5bmFtaWNTZWdtZW50c1xuICAgIC5tYXAoc2VnID0+IHNlZy5yZXBsYWNlKC9bXFxbXFxdXS9nLCAnJykpXG4gICAgLmpvaW4oJ18nKTtcbiAgXG4gIHJldHVybiBgJHtiYXNlQ2xhc3NOYW1lfV8ke3NlZ21lbnROYW1lc31gO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyBhIHJvdXRlIHdpdGggaXRzIGFjdHVhbCBmaWxlIHBhdGggZnJvbSBleHBvLXJvdXRlclxuICogXG4gKiBUaGlzIHNob3VsZCBiZSBjYWxsZWQgZnJvbSByb3V0ZSBmaWxlcyAoYXBwIGRpcmVjdG9yeSksIG5vdCBmcm9tIGNvbXBvbmVudCBmaWxlcy5cbiAqIFRoZSByb3V0ZSBwYXRoIGlzIGF1dG8tZGlzY292ZXJlZCBmcm9tIHRoZSBmaWxlIGxvY2F0aW9uLlxuICogXG4gKiAqKkR1cGxpY2F0ZSBEZXRlY3Rpb24qKjogSWYgYSB2aWV3IGNsYXNzIGlzIGFscmVhZHkgcmVnaXN0ZXJlZCB0byBhIGRpZmZlcmVudCByb3V0ZSxcbiAqIGEgcnVudGltZSBlcnJvciB3aWxsIGJlIHRocm93biB3aXRoIGRldGFpbHMgYWJvdXQgYm90aCByZWdpc3RyYXRpb25zLlxuICogXG4gKiBAcGFyYW0gdmlld0NsYXNzTmFtZSAtIFRoZSBuYW1lIG9mIHRoZSB2aWV3IGNsYXNzIGJlaW5nIHJlbmRlcmVkIG9uIHRoaXMgcm91dGVcbiAqIEBwYXJhbSByb3V0ZVBhdGggLSBPcHRpb25hbCBleHBsaWNpdCBwYXRoLCBvdGhlcndpc2UgYXV0by1kaXNjb3ZlcmVkIGZyb20gY3VycmVudCByb3V0ZVxuICogXG4gKiBAdGhyb3dzIEVycm9yIGlmIHZpZXdDbGFzc05hbWUgaXMgYWxyZWFkeSByZWdpc3RlcmVkIHRvIGEgZGlmZmVyZW50IHJvdXRlXG4gKiBcbiAqIEBleGFtcGxlXG4gKiAvLyBJbiBhcHAvZ2VuaWUvY291bnRlci50c3hcbiAqIGltcG9ydCB7IHVzZVJlZ2lzdGVyR2VuaWVSb3V0ZSB9IGZyb20gJ0BnYXJyaXg4Mi9yZWFjdGdlbmllLWxpYic7XG4gKiBcbiAqIGV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIENvdW50ZXJSb3V0ZSgpIHtcbiAqICAgdXNlUmVnaXN0ZXJHZW5pZVJvdXRlKCdDb3VudGVyVmlldycpOyAvLyBBdXRvLWRpc2NvdmVyczogL2dlbmllL2NvdW50ZXJcbiAqICAgcmV0dXJuIDxDb3VudGVyVmlldyAvPjtcbiAqIH1cbiAqIFxuICogQGV4YW1wbGVcbiAqIC8vIER5bmFtaWMgcm91dGU6IGFwcC9nZW5pZS9baWRdLnRzeFxuICogZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gRHluYW1pY0NvdW50ZXJSb3V0ZSgpIHtcbiAqICAgdXNlUmVnaXN0ZXJHZW5pZVJvdXRlKCdDb3VudGVyVmlldycpOyAvLyBBdXRvLWRpc2NvdmVyczogL2dlbmllL1tpZF1cbiAqICAgcmV0dXJuIDxDb3VudGVyVmlldyAvPjtcbiAqIH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZVJlZ2lzdGVyR2VuaWVSb3V0ZShiYXNlVmlld0NsYXNzTmFtZTogc3RyaW5nLCByb3V0ZVBhdGg/OiBzdHJpbmcpIHtcbiAgLy8gT25seSB3b3JrcyBpZiBleHBvLXJvdXRlciBpcyBhdmFpbGFibGVcbiAgaWYgKCF1c2VQYXRobmFtZSkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHBhdGhuYW1lID0gdXNlUGF0aG5hbWUoKTtcbiAgXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgcGF0aCA9IHJvdXRlUGF0aCB8fCBwYXRobmFtZTtcbiAgICBcbiAgICBpZiAocGF0aCAmJiBiYXNlVmlld0NsYXNzTmFtZSkge1xuICAgICAgLy8gR2VuZXJhdGUgdW5pcXVlIHZpZXcgY2xhc3MgbmFtZSBmb3IgZHluYW1pYyByb3V0ZXNcbiAgICAgIGNvbnN0IHZpZXdDbGFzc05hbWUgPSBnZW5lcmF0ZVVuaXF1ZVZpZXdDbGFzc05hbWUoYmFzZVZpZXdDbGFzc05hbWUsIHBhdGgpO1xuICAgICAgXG4gICAgICBjb25zdCBleGlzdGluZ1JlZ2lzdHJhdGlvbiA9IGdldFJlZ2lzdHJhdGlvbkluZm8odmlld0NsYXNzTmFtZSk7XG5cbiAgICAgIC8vIEF1dG8gcmVnaXN0cnkgYWxyZWFkeSBvd25zIHRoaXMgdmlldyBjbGFzczsgaWdub3JlIHJ1bnRpbWUgcmVnaXN0cmF0aW9uLlxuICAgICAgaWYgKGV4aXN0aW5nUmVnaXN0cmF0aW9uICYmIGV4aXN0aW5nUmVnaXN0cmF0aW9uLnNvdXJjZSA9PT0gXCJhdXRvXCIpIHtcbiAgICAgICAgaWYgKHJvdXRlUGF0aCAmJiBleGlzdGluZ1JlZ2lzdHJhdGlvbi5yb3V0ZVBhdGggIT09IHBhdGgpIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oXG4gICAgICAgICAgICBgW1JlYWN0R2VuaWVdIFNraXBwaW5nIHJ1bnRpbWUgcmVnaXN0cmF0aW9uIGZvciBcIiR7dmlld0NsYXNzTmFtZX1cIiBgICtcbiAgICAgICAgICAgIGAoJHtwYXRofSkuIEF1dG8gcmVnaXN0cnkgYWxyZWFkeSBtYXBwZWQgaXQgdG8gXCIke2V4aXN0aW5nUmVnaXN0cmF0aW9uLnJvdXRlUGF0aH1cIi5gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIENoZWNrIGZvciBkdXBsaWNhdGUgcnVudGltZSByZWdpc3RyYXRpb25cbiAgICAgIGlmIChleGlzdGluZ1JlZ2lzdHJhdGlvbiAmJiBleGlzdGluZ1JlZ2lzdHJhdGlvbi5yb3V0ZVBhdGggIT09IHBhdGgpIHtcbiAgICAgICAgY29uc3QgZXJyb3JNc2cgPSBcbiAgICAgICAgICBgW1JlYWN0R2VuaWVdIEVSUk9SOiBEdXBsaWNhdGUgcmVnaXN0cmF0aW9uIGRldGVjdGVkIVxcbmAgK1xuICAgICAgICAgIGBWaWV3IGNsYXNzIFwiJHt2aWV3Q2xhc3NOYW1lfVwiIGlzIGFscmVhZHkgcmVnaXN0ZXJlZC5cXG5cXG5gICtcbiAgICAgICAgICBgRXhpc3RpbmcgcmVnaXN0cmF0aW9uOlxcbmAgK1xuICAgICAgICAgIGAgIFJvdXRlOiAke2V4aXN0aW5nUmVnaXN0cmF0aW9uLnJvdXRlUGF0aH1cXG5gICtcbiAgICAgICAgICBgICBGaWxlOiAke2V4aXN0aW5nUmVnaXN0cmF0aW9uLnJlZ2lzdGVyZWRBdH1cXG5cXG5gICtcbiAgICAgICAgICBgTmV3IHJlZ2lzdHJhdGlvbiBhdHRlbXB0OlxcbmAgK1xuICAgICAgICAgIGAgIFJvdXRlOiAke3BhdGh9XFxuXFxuYCArXG4gICAgICAgICAgYEVhY2ggdmlldyBjbGFzcyBjYW4gb25seSBiZSByZWdpc3RlcmVkIHRvIE9ORSByb3V0ZS5cXG5gICtcbiAgICAgICAgICBgUGxlYXNlIHVzZSBhIGRpZmZlcmVudCB2aWV3IGNsYXNzIG5hbWUgZm9yIHRoZSBzZWNvbmQgcm91dGUsXFxuYCArXG4gICAgICAgICAgYG9yIHJlbW92ZSBvbmUgb2YgdGhlIHJlZ2lzdHJhdGlvbnMuYDtcbiAgICAgICAgXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoZXJyb3JNc2cpO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICAgICAgfVxuICAgICAgXG4gICAgICAvLyBSZWdpc3RlciB0aGUgcm91dGUgd2l0aCBtZXRhZGF0YVxuICAgICAgQVVUT19ST1VURV9SRUdJU1RSWS5zZXQodmlld0NsYXNzTmFtZSwge1xuICAgICAgICB2aWV3Q2xhc3NOYW1lLFxuICAgICAgICByb3V0ZVBhdGg6IHBhdGgsXG4gICAgICAgIHJlZ2lzdGVyZWRBdDogcGF0aCwgLy8gVXNlIHBhdGhuYW1lIGFzIFwiZmlsZSBsb2NhdGlvblwiXG4gICAgICAgIHNvdXJjZTogXCJydW50aW1lXCIsXG4gICAgICB9KTtcbiAgICAgIFxuICAgICAgLy8gY29uc29sZS5sb2coYFtSZWFjdEdlbmllXSBSZWdpc3RlcmVkIHJvdXRlOiAke3ZpZXdDbGFzc05hbWV9IOKGkiAke3BhdGh9YCk7XG4gICAgfVxuICB9LCBbYmFzZVZpZXdDbGFzc05hbWUsIHBhdGhuYW1lLCByb3V0ZVBhdGhdKTtcbn1cblxuLyoqXG4gKiBBbHRlcm5hdGl2ZTogUmVnaXN0ZXIgcm91dGUgd2l0aG91dCBob29rIChmb3IgdXNlIG91dHNpZGUgUmVhY3QgY29tcG9uZW50cylcbiAqIFxuICogKipEdXBsaWNhdGUgRGV0ZWN0aW9uKio6IFRocm93cyBlcnJvciBpZiB2aWV3IGNsYXNzIGFscmVhZHkgcmVnaXN0ZXJlZCB0byBkaWZmZXJlbnQgcm91dGUuXG4gKiBcbiAqIEBwYXJhbSB2aWV3Q2xhc3NOYW1lIC0gVGhlIG5hbWUgb2YgdGhlIHZpZXcgY2xhc3NcbiAqIEBwYXJhbSByb3V0ZVBhdGggLSBUaGUgZmlsZS1iYXNlZCByb3V0ZSBwYXRoIHdoZXJlIHRoaXMgdmlldyBpcyB1c2VkXG4gKiBAdGhyb3dzIEVycm9yIGlmIHZpZXdDbGFzc05hbWUgaXMgYWxyZWFkeSByZWdpc3RlcmVkIHRvIGEgZGlmZmVyZW50IHJvdXRlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckdlbmllUm91dGUodmlld0NsYXNzTmFtZTogc3RyaW5nLCByb3V0ZVBhdGg6IHN0cmluZykge1xuICAvLyBDaGVjayBmb3IgZHVwbGljYXRlIHJlZ2lzdHJhdGlvblxuICBjb25zdCBleGlzdGluZ1JlZ2lzdHJhdGlvbiA9IGdldFJlZ2lzdHJhdGlvbkluZm8odmlld0NsYXNzTmFtZSk7XG4gIFxuICBpZiAoZXhpc3RpbmdSZWdpc3RyYXRpb24gJiYgZXhpc3RpbmdSZWdpc3RyYXRpb24ucm91dGVQYXRoICE9PSByb3V0ZVBhdGgpIHtcbiAgICBjb25zdCBlcnJvck1zZyA9IFxuICAgICAgYFtSZWFjdEdlbmllXSBFUlJPUjogRHVwbGljYXRlIHJlZ2lzdHJhdGlvbiBkZXRlY3RlZCFcXG5gICtcbiAgICAgIGBWaWV3IGNsYXNzIFwiJHt2aWV3Q2xhc3NOYW1lfVwiIGlzIGFscmVhZHkgcmVnaXN0ZXJlZC5cXG5cXG5gICtcbiAgICAgIGBFeGlzdGluZyByZWdpc3RyYXRpb246XFxuYCArXG4gICAgICBgICBSb3V0ZTogJHtleGlzdGluZ1JlZ2lzdHJhdGlvbi5yb3V0ZVBhdGh9XFxuYCArXG4gICAgICBgICBGaWxlOiAke2V4aXN0aW5nUmVnaXN0cmF0aW9uLnJlZ2lzdGVyZWRBdH1cXG5cXG5gICtcbiAgICAgIGBOZXcgcmVnaXN0cmF0aW9uIGF0dGVtcHQ6XFxuYCArXG4gICAgICBgICBSb3V0ZTogJHtyb3V0ZVBhdGh9XFxuXFxuYCArXG4gICAgICBgRWFjaCB2aWV3IGNsYXNzIGNhbiBvbmx5IGJlIHJlZ2lzdGVyZWQgdG8gT05FIHJvdXRlLlxcbmAgK1xuICAgICAgYFBsZWFzZSB1c2UgYSBkaWZmZXJlbnQgdmlldyBjbGFzcyBuYW1lIGZvciB0aGUgc2Vjb25kIHJvdXRlLFxcbmAgK1xuICAgICAgYG9yIHJlbW92ZSBvbmUgb2YgdGhlIHJlZ2lzdHJhdGlvbnMuYDtcbiAgICBcbiAgICBjb25zb2xlLmVycm9yKGVycm9yTXNnKTtcbiAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNc2cpO1xuICB9XG4gIFxuICBBVVRPX1JPVVRFX1JFR0lTVFJZLnNldCh2aWV3Q2xhc3NOYW1lLCB7XG4gICAgdmlld0NsYXNzTmFtZSxcbiAgICByb3V0ZVBhdGgsXG4gICAgcmVnaXN0ZXJlZEF0OiByb3V0ZVBhdGgsXG4gICAgc291cmNlOiBcImF1dG9cIixcbiAgfSk7XG4gIC8vIGNvbnNvbGUubG9nKGBbUmVhY3RHZW5pZV0gUmVnaXN0ZXJlZCByb3V0ZTogJHt2aWV3Q2xhc3NOYW1lfSDihpIgJHtyb3V0ZVBhdGh9YCk7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgcm91dGUgcGF0aCBmb3IgYSB2aWV3IGNsYXNzIG5hbWVcbiAqL1xuZnVuY3Rpb24gZ2V0Um91dGVGb3JWaWV3KHZpZXdDbGFzc05hbWU6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCByZWdpc3RyYXRpb24gPSBBVVRPX1JPVVRFX1JFR0lTVFJZLmdldCh2aWV3Q2xhc3NOYW1lKTtcbiAgcmV0dXJuIHJlZ2lzdHJhdGlvbj8ucm91dGVQYXRoIHx8IG51bGw7XG59XG5cbmZ1bmN0aW9uIHNwbGl0Um91dGVTZWdtZW50cyhwYXRoOiBzdHJpbmcpOiBzdHJpbmdbXSB7XG4gIGlmICghcGF0aCB8fCBwYXRoID09PSAnLycpIHtcbiAgICByZXR1cm4gW107XG4gIH1cbiAgcmV0dXJuIHBhdGhcbiAgICAuc3BsaXQoJy8nKVxuICAgIC5maWx0ZXIoKHNlZ21lbnQpID0+IHNlZ21lbnQubGVuZ3RoID4gMCk7XG59XG5cbmZ1bmN0aW9uIGlzRHluYW1pY1NlZ21lbnQoc2VnbWVudDogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBzZWdtZW50LnN0YXJ0c1dpdGgoJ1snKSAmJiBzZWdtZW50LmVuZHNXaXRoKCddJyk7XG59XG5cbmZ1bmN0aW9uIGlzQ2F0Y2hBbGxTZWdtZW50KHNlZ21lbnQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gc2VnbWVudC5zdGFydHNXaXRoKCdbLi4uJykgJiYgc2VnbWVudC5lbmRzV2l0aCgnXScpO1xufVxuXG5mdW5jdGlvbiBpc09wdGlvbmFsQ2F0Y2hBbGxTZWdtZW50KHNlZ21lbnQ6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gc2VnbWVudC5zdGFydHNXaXRoKCdbWy4uLicpICYmIHNlZ21lbnQuZW5kc1dpdGgoJ11dJyk7XG59XG5cbmZ1bmN0aW9uIHJvdXRlVGVtcGxhdGVNYXRjaGVzUGF0aChyb3V0ZVRlbXBsYXRlOiBzdHJpbmcsIHBhdGhuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgdGVtcGxhdGVTZWdtZW50cyA9IHNwbGl0Um91dGVTZWdtZW50cyhyb3V0ZVRlbXBsYXRlKTtcbiAgY29uc3QgcGF0aFNlZ21lbnRzID0gc3BsaXRSb3V0ZVNlZ21lbnRzKHBhdGhuYW1lKTtcblxuICBsZXQgdGVtcGxhdGVJbmRleCA9IDA7XG4gIGxldCBwYXRoSW5kZXggPSAwO1xuXG4gIHdoaWxlICh0ZW1wbGF0ZUluZGV4IDwgdGVtcGxhdGVTZWdtZW50cy5sZW5ndGgpIHtcbiAgICBjb25zdCB0ZW1wbGF0ZVNlZ21lbnQgPSB0ZW1wbGF0ZVNlZ21lbnRzW3RlbXBsYXRlSW5kZXhdO1xuXG4gICAgaWYgKGlzT3B0aW9uYWxDYXRjaEFsbFNlZ21lbnQodGVtcGxhdGVTZWdtZW50KSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuXG4gICAgaWYgKGlzQ2F0Y2hBbGxTZWdtZW50KHRlbXBsYXRlU2VnbWVudCkpIHtcbiAgICAgIHJldHVybiBwYXRoSW5kZXggPCBwYXRoU2VnbWVudHMubGVuZ3RoO1xuICAgIH1cblxuICAgIGNvbnN0IHBhdGhTZWdtZW50ID0gcGF0aFNlZ21lbnRzW3BhdGhJbmRleF07XG4gICAgaWYgKHBhdGhTZWdtZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICBpZiAoaXNEeW5hbWljU2VnbWVudCh0ZW1wbGF0ZVNlZ21lbnQpKSB7XG4gICAgICB0ZW1wbGF0ZUluZGV4ICs9IDE7XG4gICAgICBwYXRoSW5kZXggKz0gMTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGlmICh0ZW1wbGF0ZVNlZ21lbnQgIT09IHBhdGhTZWdtZW50KSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuXG4gICAgdGVtcGxhdGVJbmRleCArPSAxO1xuICAgIHBhdGhJbmRleCArPSAxO1xuICB9XG5cbiAgcmV0dXJuIHBhdGhJbmRleCA9PT0gcGF0aFNlZ21lbnRzLmxlbmd0aDtcbn1cblxuZnVuY3Rpb24gZ2V0Um91dGVTcGVjaWZpY2l0eShyb3V0ZVRlbXBsYXRlOiBzdHJpbmcpOiBudW1iZXIge1xuICBjb25zdCBzZWdtZW50cyA9IHNwbGl0Um91dGVTZWdtZW50cyhyb3V0ZVRlbXBsYXRlKTtcbiAgY29uc3Qgc3RhdGljU2VnbWVudHMgPSBzZWdtZW50cy5maWx0ZXIoKHNlZ21lbnQpID0+ICFpc0R5bmFtaWNTZWdtZW50KHNlZ21lbnQpKS5sZW5ndGg7XG4gIHJldHVybiBzdGF0aWNTZWdtZW50cyAqIDEwMCArIHNlZ21lbnRzLmxlbmd0aDtcbn1cblxuZnVuY3Rpb24gZ2V0Q3VycmVudFJvdXRlVGVtcGxhdGUocGF0aG5hbWU6IHN0cmluZyk6IHN0cmluZyB8IG51bGwge1xuICBjb25zdCBjYW5kaWRhdGVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIEFVVE9fUk9VVEVfUkVHSVNUUlkuZm9yRWFjaCgoaW5mbykgPT4ge1xuICAgIGlmIChyb3V0ZVRlbXBsYXRlTWF0Y2hlc1BhdGgoaW5mby5yb3V0ZVBhdGgsIHBhdGhuYW1lKSkge1xuICAgICAgY2FuZGlkYXRlcy5wdXNoKGluZm8ucm91dGVQYXRoKTtcbiAgICB9XG4gIH0pO1xuXG4gIGlmIChjYW5kaWRhdGVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY2FuZGlkYXRlcy5zb3J0KChhLCBiKSA9PiBnZXRSb3V0ZVNwZWNpZmljaXR5KGIpIC0gZ2V0Um91dGVTcGVjaWZpY2l0eShhKSk7XG4gIHJldHVybiBjYW5kaWRhdGVzWzBdO1xufVxuXG4vKipcbiAqIEhvb2sgdGhhdCBhdXRvbWF0aWNhbGx5IGludGVyY2VwdHMgUmVhY3RHZW5pZSBuYXZpZ2F0aW9uIGFuZCByb3V0ZXMgdmlhIGV4cG8tcm91dGVyXG4gKiBcbiAqIFJvdXRlcyBhcmUgYXV0by1kaXNjb3ZlcmVkIGZyb20gd2hlcmUgY29tcG9uZW50cyBhcmUgYWN0dWFsbHkgdXNlZCwgbm90IGluZmVycmVkLlxuICogXG4gKiBVc2FnZTogSW1wb3J0IGFuZCBjYWxsIGluIHlvdXIgcm9vdCBfbGF5b3V0LnRzeCAoaW5zaWRlIFByb3ZpZGVyIGNvbnRleHQpOlxuICogYGBgdHN4XG4gKiBpbXBvcnQgeyB1c2VFeHBvUm91dGVyQWRhcHRlciB9IGZyb20gJ0BnYXJyaXg4Mi9yZWFjdGdlbmllLWxpYic7XG4gKiBcbiAqIGZ1bmN0aW9uIFJvb3RMYXlvdXRDb250ZW50KCkge1xuICogICB1c2VFeHBvUm91dGVyQWRhcHRlcigpOyAvLyA8LSBBZGQgdGhpcyBsaW5lXG4gKiAgIC8vIC4uLiByZXN0IG9mIGxheW91dFxuICogfVxuICogYGBgXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VFeHBvUm91dGVyQWRhcHRlcigpIHtcbiAgLy8gQ2hlY2sgaWYgZXhwby1yb3V0ZXIgaXMgYXZhaWxhYmxlXG4gIGlmICghdXNlUm91dGVyIHx8ICF1c2VTZWdtZW50cykge1xuICAgIC8vIE5vIGV4cG8tcm91dGVyLCBuYXZpZ2F0aW9uIHdpbGwgZmFsbCBiYWNrIHRvIHJlYWN0LW5hdmlnYXRpb25cbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCByb3V0ZXIgPSB1c2VSb3V0ZXIoKTtcbiAgY29uc3QgcGF0aG5hbWUgPSB1c2VQYXRobmFtZSA/IHVzZVBhdGhuYW1lKCkgOiAnJztcbiAgY29uc3QgbG9jYWxTZWFyY2hQYXJhbXMgPSB1c2VMb2NhbFNlYXJjaFBhcmFtcyA/IHVzZUxvY2FsU2VhcmNoUGFyYW1zKCkgOiB7fTtcbiAgY29uc3QgbmF2U3RhdGUgPSB1c2VHZW5pZVNlbGVjdG9yKChzdGF0ZTogYW55KSA9PiBzdGF0ZS5uYXZTdGF0ZSBhcyBOYXZpZ2F0b3JTdGF0ZSB8IG51bGwpO1xuICBjb25zdCBuYXZTdGFjayA9IHVzZUdlbmllU2VsZWN0b3IoKHN0YXRlOiBhbnkpID0+IHN0YXRlLm5hdlN0YWNrIGFzIG51bWJlcik7XG4gIGNvbnN0IGxhc3RIYW5kbGVkTmF2U3RhY2tSZWYgPSB1c2VSZWY8bnVtYmVyPigwKTtcblxuICB1c2VFZmZlY3QoKCkgPT4ge1xuICAgIGlmICghbmF2U3RhdGU/Lm9iamVjdFZpZXdDbGFzc05hbWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAobmF2U3RhY2sgPD0gbGFzdEhhbmRsZWROYXZTdGFja1JlZi5jdXJyZW50KSB7XG4gICAgICBsb2dnZXIuZGVidWcoXG4gICAgICAgIGBbUmVhY3RHZW5pZU5hdl0gcmVhc29uPWlnbm9yZWRfZHVwbGljYXRlX2V2ZW50IG5hdlN0YWNrPSR7bmF2U3RhY2t9IGxhc3RIYW5kbGVkPSR7bGFzdEhhbmRsZWROYXZTdGFja1JlZi5jdXJyZW50fWBcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZXZlbnRJZCA9IG5hdlN0YWNrO1xuICAgIGNvbnN0IHZpZXdDbGFzc05hbWUgPSBuYXZTdGF0ZS5vYmplY3RWaWV3Q2xhc3NOYW1lO1xuICAgIGNvbnN0IHBhcmFtcyA9IG5hdlN0YXRlLm9iamVjdENvbnN0cnVjdG9yUGFyYW1zO1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJvdXRlUGF0aCA9IGdldFJvdXRlRm9yVmlldyh2aWV3Q2xhc3NOYW1lKTtcbiAgICAgIGlmICghcm91dGVQYXRoKSB7XG4gICAgICAgIGxvZ2dlci53YXJuKFxuICAgICAgICAgIGBbUmVhY3RHZW5pZU5hdl0gcmVhc29uPXNraXBwZWRfdW5yZWdpc3RlcmVkX3ZpZXcgZXZlbnQ9JHtldmVudElkfSB2aWV3PSR7dmlld0NsYXNzTmFtZX1gXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgbG9nZ2VyLmRlYnVnKGBbUmVhY3RHZW5pZV0gQXV0by1yb3V0aW5nOiAke3ZpZXdDbGFzc05hbWV9IOKGkiAke3JvdXRlUGF0aH1gKTtcbiAgICAgIGxvZ2dlci5kZWJ1ZyhgW1JlYWN0R2VuaWVdIE5hdmlnYXRpb24gcGFyYW1zOmAsIHBhcmFtcyk7XG5cbiAgICAgIGNvbnN0IHJvdXRlUGFyYW1zID0gZmlsdGVyUGFyYW1zRm9yUm91dGUocm91dGVQYXRoLCBwYXJhbXMpO1xuICAgICAgY29uc3QgcXVlcnlQYXJhbXMgPSBidWlsZFF1ZXJ5UGFyYW1zRnJvbU5hdlN0YXRlKG5hdlN0YXRlKTtcbiAgICAgIGNvbnN0IGR5bmFtaWNQYXJhbU5hbWVzID0gZ2V0RHluYW1pY1BhcmFtTmFtZXMocm91dGVQYXRoKTtcbiAgICAgIGNvbnN0IG1pc3NpbmdQYXJhbXMgPSBkeW5hbWljUGFyYW1OYW1lcy5maWx0ZXIoXG4gICAgICAgIChuYW1lKSA9PiByb3V0ZVBhcmFtc1tuYW1lXSA9PT0gdW5kZWZpbmVkIHx8IHJvdXRlUGFyYW1zW25hbWVdID09PSBudWxsXG4gICAgICApO1xuXG4gICAgICBpZiAoZHluYW1pY1BhcmFtTmFtZXMubGVuZ3RoID4gMCAmJiBtaXNzaW5nUGFyYW1zLmxlbmd0aCA+IDApIHtcbiAgICAgICAgbG9nZ2VyLndhcm4oXG4gICAgICAgICAgYFtSZWFjdEdlbmllTmF2XSByZWFzb249c2tpcHBlZF9taXNzaW5nX3BhcmFtcyBldmVudD0ke2V2ZW50SWR9IHZpZXc9JHt2aWV3Q2xhc3NOYW1lfSBtaXNzaW5nPSR7bWlzc2luZ1BhcmFtcy5qb2luKCcsJyl9YFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFjdGl2ZVRlbXBsYXRlID0gZ2V0Q3VycmVudFJvdXRlVGVtcGxhdGUocGF0aG5hbWUgfHwgJycpO1xuICAgICAgY29uc3QgZHluYW1pY1BhcmFtc1VuY2hhbmdlZCA9IGR5bmFtaWNQYXJhbU5hbWVzLmV2ZXJ5KChuYW1lKSA9PiB7XG4gICAgICAgIGNvbnN0IGN1cnJlbnQgPSBBcnJheS5pc0FycmF5KChsb2NhbFNlYXJjaFBhcmFtcyBhcyBhbnkpPy5bbmFtZV0pXG4gICAgICAgICAgPyAobG9jYWxTZWFyY2hQYXJhbXMgYXMgYW55KVtuYW1lXVswXVxuICAgICAgICAgIDogKGxvY2FsU2VhcmNoUGFyYW1zIGFzIGFueSk/LltuYW1lXTtcbiAgICAgICAgcmV0dXJuIFN0cmluZyhjdXJyZW50ID8/ICcnKSA9PT0gU3RyaW5nKHJvdXRlUGFyYW1zW25hbWVdID8/ICcnKTtcbiAgICAgIH0pO1xuICAgICAgY29uc3Qgc2hvdWxkUmVwbGFjZSA9XG4gICAgICAgIGFjdGl2ZVRlbXBsYXRlICE9PSBudWxsICYmXG4gICAgICAgIGFjdGl2ZVRlbXBsYXRlID09PSByb3V0ZVBhdGggJiZcbiAgICAgICAgZHluYW1pY1BhcmFtc1VuY2hhbmdlZDtcblxuICAgICAgY29uc3QgZGVzdGluYXRpb25QYXJhbXMgPSB7XG4gICAgICAgIC4uLnJvdXRlUGFyYW1zLFxuICAgICAgICAuLi5xdWVyeVBhcmFtcyxcbiAgICAgIH07XG4gICAgICBjb25zdCBoYXNQYXJhbXMgPSBPYmplY3Qua2V5cyhkZXN0aW5hdGlvblBhcmFtcykubGVuZ3RoID4gMDtcblxuICAgICAgaWYgKGhhc1BhcmFtcykge1xuICAgICAgICBjb25zdCBkZXN0aW5hdGlvbiA9IHtcbiAgICAgICAgICBwYXRobmFtZTogcm91dGVQYXRoIGFzIGFueSxcbiAgICAgICAgICBwYXJhbXM6IGRlc3RpbmF0aW9uUGFyYW1zLFxuICAgICAgICB9O1xuICAgICAgICBpZiAoc2hvdWxkUmVwbGFjZSAmJiB0eXBlb2Ygcm91dGVyLnJlcGxhY2UgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICByb3V0ZXIucmVwbGFjZShkZXN0aW5hdGlvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcm91dGVyLnB1c2goZGVzdGluYXRpb24pO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKHNob3VsZFJlcGxhY2UgJiYgdHlwZW9mIHJvdXRlci5yZXBsYWNlID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgIHJvdXRlci5yZXBsYWNlKHJvdXRlUGF0aCBhcyBhbnkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcm91dGVyLnB1c2gocm91dGVQYXRoIGFzIGFueSk7XG4gICAgICB9XG5cbiAgICAgIGxvZ2dlci5pbmZvKFxuICAgICAgICBgW1JlYWN0R2VuaWVOYXZdIHJlYXNvbj0ke3Nob3VsZFJlcGxhY2UgPyAnaGFuZGxlZF9yZXBsYWNlJyA6ICdoYW5kbGVkX3B1c2gnfSBldmVudD0ke2V2ZW50SWR9IHZpZXc9JHt2aWV3Q2xhc3NOYW1lfSByb3V0ZT0ke3JvdXRlUGF0aH1gXG4gICAgICApO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKGBbUmVhY3RHZW5pZV0gTmF2aWdhdGlvbiBlcnJvcjpgLCBlcnJvcik7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGxhc3RIYW5kbGVkTmF2U3RhY2tSZWYuY3VycmVudCA9IGV2ZW50SWQ7XG4gICAgICAvLyBSZXNldCBuYXZpZ2F0aW9uIHN0YXRlIHRvIHByZXZlbnQgaW5maW5pdGUgbG9vcHMgYWZ0ZXIgaGFuZGxpbmcgdGhpcyBldmVudC5cbiAgICAgIHJlc2V0R2VuaWVOYXZpZ2F0aW9uKCk7XG4gICAgfVxuICB9LCBbbmF2U3RhY2ssIG5hdlN0YXRlLCBwYXRobmFtZSwgbG9jYWxTZWFyY2hQYXJhbXMsIHJvdXRlcl0pO1xufVxuXG4vKipcbiAqIEhpZ2hlci1vcmRlciBjb21wb25lbnQgdGhhdCB3cmFwcyB5b3VyIHJvb3QgbGF5b3V0IHdpdGggZXhwby1yb3V0ZXIgYWRhcHRlclxuICogXG4gKiBVc2FnZTpcbiAqIGBgYHRzeFxuICogaW1wb3J0IHsgd2l0aEV4cG9Sb3V0ZXJBZGFwdGVyIH0gZnJvbSAnQGdhcnJpeDgyL3JlYWN0Z2VuaWUtbGliJztcbiAqIFxuICogZnVuY3Rpb24gUm9vdExheW91dCgpIHtcbiAqICAgcmV0dXJuIChcbiAqICAgICA8UHJvdmlkZXIgc3RvcmU9e3JlYWN0R2VuaWVTdG9yZX0+XG4gKiAgICAgICA8U3RhY2s+Li4uPC9TdGFjaz5cbiAqICAgICA8L1Byb3ZpZGVyPlxuICogICApO1xuICogfVxuICogXG4gKiBleHBvcnQgZGVmYXVsdCB3aXRoRXhwb1JvdXRlckFkYXB0ZXIoUm9vdExheW91dCk7XG4gKiBgYGBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhFeHBvUm91dGVyQWRhcHRlcjxQIGV4dGVuZHMgb2JqZWN0PihcbiAgQ29tcG9uZW50OiBSZWFjdC5Db21wb25lbnRUeXBlPFA+XG4pOiBSZWFjdC5Db21wb25lbnRUeXBlPFA+IHtcbiAgcmV0dXJuIGZ1bmN0aW9uIEV4cG9Sb3V0ZXJBZGFwdGVyV3JhcHBlcihwcm9wczogUCkge1xuICAgIHVzZUV4cG9Sb3V0ZXJBZGFwdGVyKCk7XG4gICAgcmV0dXJuIDxDb21wb25lbnQgey4uLnByb3BzfSAvPjtcbiAgfTtcbn1cblxuLyoqXG4gKiBVdGlsaXR5IHRvIGNoZWNrIGlmIGV4cG8tcm91dGVyIGlzIGF2YWlsYWJsZVxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFeHBvUm91dGVyQXZhaWxhYmxlKCk6IGJvb2xlYW4ge1xuICByZXR1cm4gdXNlUm91dGVyICE9PSBudWxsICYmIHVzZVNlZ21lbnRzICE9PSBudWxsO1xufVxuXG4vKipcbiAqIEdldCBhbGwgcmVnaXN0ZXJlZCByb3V0ZXMgKGZvciBkZWJ1Z2dpbmcpXG4gKiBSZXR1cm5zIGEgY29weSBvZiB0aGUgcmVnaXN0cmF0aW9uIG1hcCB3aXRoIGZ1bGwgbWV0YWRhdGFcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJlZ2lzdGVyZWRSb3V0ZXMoKTogTWFwPHN0cmluZywgUm91dGVSZWdpc3RyYXRpb25JbmZvPiB7XG4gIHJldHVybiBuZXcgTWFwKEFVVE9fUk9VVEVfUkVHSVNUUlkpO1xufVxuXG4vKipcbiAqIEdldCBzaW1wbGUgcm91dGUgbWFwICh2aWV3Q2xhc3NOYW1lIOKGkiByb3V0ZVBhdGgpIGZvciBkZWJ1Z2dpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFJvdXRlTWFwKCk6IE1hcDxzdHJpbmcsIHN0cmluZz4ge1xuICBjb25zdCBzaW1wbGVNYXAgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuICBBVVRPX1JPVVRFX1JFR0lTVFJZLmZvckVhY2goKGluZm8sIHZpZXdDbGFzc05hbWUpID0+IHtcbiAgICBzaW1wbGVNYXAuc2V0KHZpZXdDbGFzc05hbWUsIGluZm8ucm91dGVQYXRoKTtcbiAgfSk7XG4gIHJldHVybiBzaW1wbGVNYXA7XG59XG4iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7QUFVQSxJQUFBQSxNQUFBLEdBQUFDLHVCQUFBLENBQUFDLE9BQUE7QUFDQSxJQUFBQyxZQUFBLEdBQUFELE9BQUE7QUFDQSxJQUFBRSxjQUFBLEdBQUFGLE9BQUE7QUFFQSxJQUFBRyxPQUFBLEdBQUFILE9BQUE7QUFBbUMsU0FBQUQsd0JBQUFLLENBQUEsRUFBQUMsQ0FBQSw2QkFBQUMsT0FBQSxNQUFBQyxDQUFBLE9BQUFELE9BQUEsSUFBQUUsQ0FBQSxPQUFBRixPQUFBLFlBQUFQLHVCQUFBLFlBQUFBLENBQUFLLENBQUEsRUFBQUMsQ0FBQSxTQUFBQSxDQUFBLElBQUFELENBQUEsSUFBQUEsQ0FBQSxDQUFBSyxVQUFBLFNBQUFMLENBQUEsTUFBQU0sQ0FBQSxFQUFBQyxDQUFBLEVBQUFDLENBQUEsS0FBQUMsU0FBQSxRQUFBQyxPQUFBLEVBQUFWLENBQUEsaUJBQUFB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
@@ -0,0 +1,20 @@
1
+ import React from 'react';
2
+ export interface NavigationAdapter {
3
+ push: (routeName: string, params?: any) => void;
4
+ navigate: (routeName: string, params?: any) => void;
5
+ goBack: () => void;
6
+ canGoBack: () => boolean;
7
+ setOptions: (options: any) => void;
8
+ getState: () => any;
9
+ }
10
+ export declare function useNavigationAdapter(): NavigationAdapter;
11
+ export declare function withNavigationAdapter<P extends object>(Component: React.ComponentType<P & {
12
+ navigation: NavigationAdapter;
13
+ }>): React.FC<P>;
14
+ export declare function useRouteParams<T = any>(): T;
15
+ export declare function createScreenWrapper(Screen: React.ComponentType<any>, options?: {
16
+ title?: (params?: any) => string;
17
+ headerShown?: boolean;
18
+ }): (props: any) => any;
19
+ export declare function isExpoRouter(): boolean;
20
+ export type { NavigationAdapter as Navigation };