dbctx 1.5.0 → 2.0.1

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 (141) hide show
  1. package/dist/app/assemble.d.mts.map +1 -1
  2. package/dist/app/assemble.mjs +20 -4
  3. package/dist/app/list.d.mts +4 -0
  4. package/dist/app/list.d.mts.map +1 -0
  5. package/dist/app/list.mjs +93 -0
  6. package/dist/app/load-introspection.d.mts +26 -0
  7. package/dist/app/load-introspection.d.mts.map +1 -0
  8. package/dist/app/load-introspection.mjs +89 -0
  9. package/dist/app/login.d.mts +2 -0
  10. package/dist/app/login.d.mts.map +1 -0
  11. package/dist/app/login.mjs +69 -0
  12. package/dist/app/open-url.d.mts +2 -0
  13. package/dist/app/open-url.d.mts.map +1 -1
  14. package/dist/app/open-url.mjs +8 -3
  15. package/dist/app/sample.d.mts +24 -0
  16. package/dist/app/sample.d.mts.map +1 -0
  17. package/dist/app/sample.mjs +257 -0
  18. package/dist/app/session.d.mts +1 -0
  19. package/dist/app/session.d.mts.map +1 -1
  20. package/dist/app/session.mjs +44 -4
  21. package/dist/app/tail.d.mts +13 -0
  22. package/dist/app/tail.d.mts.map +1 -0
  23. package/dist/app/tail.mjs +168 -0
  24. package/dist/db/check-constraints.d.mts +9 -0
  25. package/dist/db/check-constraints.d.mts.map +1 -0
  26. package/dist/db/check-constraints.mjs +17 -0
  27. package/dist/db/custom-types.d.mts +26 -0
  28. package/dist/db/custom-types.d.mts.map +1 -0
  29. package/dist/db/custom-types.mjs +61 -0
  30. package/dist/db/extensions.d.mts +8 -0
  31. package/dist/db/extensions.d.mts.map +1 -0
  32. package/dist/db/extensions.mjs +14 -0
  33. package/dist/db/functions.d.mts +11 -0
  34. package/dist/db/functions.d.mts.map +1 -0
  35. package/dist/db/functions.mjs +23 -0
  36. package/dist/db/index.d.mts +9 -0
  37. package/dist/db/index.d.mts.map +1 -1
  38. package/dist/db/index.mjs +10 -1
  39. package/dist/db/planner-stats.d.mts +33 -0
  40. package/dist/db/planner-stats.d.mts.map +1 -0
  41. package/dist/db/planner-stats.mjs +103 -0
  42. package/dist/db/rls.d.mts +21 -0
  43. package/dist/db/rls.d.mts.map +1 -0
  44. package/dist/db/rls.mjs +48 -0
  45. package/dist/db/sample.d.mts +16 -0
  46. package/dist/db/sample.d.mts.map +1 -0
  47. package/dist/db/sample.mjs +73 -0
  48. package/dist/db/sequences.d.mts +15 -0
  49. package/dist/db/sequences.d.mts.map +1 -0
  50. package/dist/db/sequences.mjs +31 -0
  51. package/dist/db/triggers.d.mts +11 -0
  52. package/dist/db/triggers.d.mts.map +1 -0
  53. package/dist/db/triggers.mjs +21 -0
  54. package/dist/flow/events.d.mts +115 -0
  55. package/dist/flow/events.d.mts.map +1 -0
  56. package/dist/flow/events.mjs +2 -0
  57. package/dist/flow/interpreter.d.mts +21 -0
  58. package/dist/flow/interpreter.d.mts.map +1 -0
  59. package/dist/flow/interpreter.mjs +605 -0
  60. package/dist/flow/projection.d.mts +17 -0
  61. package/dist/flow/projection.d.mts.map +1 -0
  62. package/dist/flow/projection.mjs +83 -0
  63. package/dist/flow/projection.test.d.mts +2 -0
  64. package/dist/flow/projection.test.d.mts.map +1 -0
  65. package/dist/flow/projection.test.mjs +162 -0
  66. package/dist/flow/reducer.d.mts +5 -0
  67. package/dist/flow/reducer.d.mts.map +1 -0
  68. package/dist/flow/reducer.mjs +306 -0
  69. package/dist/flow/reducer.test.d.mts +2 -0
  70. package/dist/flow/reducer.test.d.mts.map +1 -0
  71. package/dist/flow/reducer.test.mjs +479 -0
  72. package/dist/flow/run.d.mts +3 -0
  73. package/dist/flow/run.d.mts.map +1 -0
  74. package/dist/flow/run.mjs +89 -0
  75. package/dist/flow/states.d.mts +54 -0
  76. package/dist/flow/states.d.mts.map +1 -0
  77. package/dist/flow/states.mjs +39 -0
  78. package/dist/index.d.mts +7 -1
  79. package/dist/index.d.mts.map +1 -1
  80. package/dist/index.mjs +112 -13
  81. package/dist/lib/atomic-write.d.mts +4 -0
  82. package/dist/lib/atomic-write.d.mts.map +1 -0
  83. package/dist/lib/atomic-write.mjs +75 -0
  84. package/dist/lib/stream-job.d.mts +19 -0
  85. package/dist/lib/stream-job.d.mts.map +1 -0
  86. package/dist/lib/stream-job.mjs +55 -0
  87. package/dist/lib/trpc-url.mjs +2 -2
  88. package/dist/lib/trpc.mjs +2 -2
  89. package/dist/logger.d.mts.map +1 -1
  90. package/dist/logger.mjs +6 -3
  91. package/dist/providers/TrpcProvider.js +3 -3
  92. package/dist/store.d.mts +95 -2
  93. package/dist/store.d.mts.map +1 -1
  94. package/dist/store.mjs +64 -1
  95. package/dist/ui/App.d.ts +1 -1
  96. package/dist/ui/App.d.ts.map +1 -1
  97. package/dist/ui/App.js +22 -4
  98. package/dist/ui/components/Analyze.d.ts +10 -0
  99. package/dist/ui/components/Analyze.d.ts.map +1 -0
  100. package/dist/ui/components/Analyze.js +54 -0
  101. package/dist/ui/components/Billing.d.ts +10 -0
  102. package/dist/ui/components/Billing.d.ts.map +1 -0
  103. package/dist/ui/components/Billing.js +40 -0
  104. package/dist/ui/components/DB.d.ts.map +1 -1
  105. package/dist/ui/components/DB.js +2 -2
  106. package/dist/ui/components/DatabasePicker.d.ts +13 -0
  107. package/dist/ui/components/DatabasePicker.d.ts.map +1 -0
  108. package/dist/ui/components/DatabasePicker.js +79 -0
  109. package/dist/ui/components/Enrich.d.ts +10 -0
  110. package/dist/ui/components/Enrich.d.ts.map +1 -0
  111. package/dist/ui/components/Enrich.js +41 -0
  112. package/dist/ui/components/Gate.js +2 -2
  113. package/dist/ui/components/Introspect.d.ts.map +1 -1
  114. package/dist/ui/components/Introspect.js +2 -2
  115. package/dist/ui/components/IntrospectionUpload.d.ts +10 -0
  116. package/dist/ui/components/IntrospectionUpload.d.ts.map +1 -0
  117. package/dist/ui/components/IntrospectionUpload.js +30 -0
  118. package/dist/ui/components/Login.d.ts +19 -0
  119. package/dist/ui/components/Login.d.ts.map +1 -0
  120. package/dist/ui/components/Login.js +38 -0
  121. package/dist/ui/components/OutputJson.d.ts.map +1 -1
  122. package/dist/ui/components/OutputJson.js +2 -2
  123. package/dist/ui/components/SSH.d.ts.map +1 -1
  124. package/dist/ui/components/SSH.js +2 -2
  125. package/dist/ui/components/SamplesUpload.d.ts +10 -0
  126. package/dist/ui/components/SamplesUpload.d.ts.map +1 -0
  127. package/dist/ui/components/SamplesUpload.js +24 -0
  128. package/dist/ui/components/Sampling.d.ts +10 -0
  129. package/dist/ui/components/Sampling.d.ts.map +1 -0
  130. package/dist/ui/components/Sampling.js +58 -0
  131. package/dist/ui/components/Session.d.ts.map +1 -1
  132. package/dist/ui/components/Session.js +4 -4
  133. package/dist/ui/components/Spinner.d.ts.map +1 -1
  134. package/dist/ui/components/Spinner.js +17 -5
  135. package/dist/validatePaths.d.mts +1 -1
  136. package/dist/validatePaths.d.mts.map +1 -1
  137. package/dist/validatePaths.mjs +5 -1
  138. package/package.json +7 -7
  139. package/dist/app/index.d.mts +0 -3
  140. package/dist/app/index.d.mts.map +0 -1
  141. package/dist/app/index.mjs +0 -156
@@ -0,0 +1,479 @@
1
+ import { describe, test } from 'node:test';
2
+ import assert from 'node:assert/strict';
3
+ import { reduce } from './reducer.mjs';
4
+ import { initialFlowState } from './states.mjs';
5
+ const baseInit = (overrides = {}) => initialFlowState({
6
+ stopAfter: null,
7
+ sshEnabled: false,
8
+ fileMaskPath: null,
9
+ fromIntrospectionFile: false,
10
+ outputJSONPath: null,
11
+ outputSamplesDir: null,
12
+ explanation: null,
13
+ ...overrides,
14
+ });
15
+ const fold = (state, events) => events.reduce(reduce, state);
16
+ // ── start / SSH branch ─────────────────────────────────────────────
17
+ describe('reducer: start + SSH', () => {
18
+ test('start with SSH disabled → connecting-db', () => {
19
+ const next = reduce(baseInit(), { kind: 'start' });
20
+ assert.equal(next.phase, 'connecting-db');
21
+ });
22
+ test('start with SSH enabled → connecting-ssh', () => {
23
+ const next = reduce(baseInit({ sshEnabled: true }), { kind: 'start' });
24
+ assert.equal(next.phase, 'connecting-ssh');
25
+ });
26
+ test('ssh-connected → connecting-db', () => {
27
+ const s1 = reduce(baseInit({ sshEnabled: true }), { kind: 'start' });
28
+ const s2 = reduce(s1, { kind: 'ssh-connected' });
29
+ assert.equal(s2.phase, 'connecting-db');
30
+ });
31
+ test('ssh-failed → terminal error', () => {
32
+ const s1 = reduce(baseInit({ sshEnabled: true }), { kind: 'start' });
33
+ const s2 = reduce(s1, { kind: 'ssh-failed', error: 'auth refused' });
34
+ assert.equal(s2.phase, 'error');
35
+ assert.equal(s2.errorPhase, 'connecting-ssh');
36
+ assert.equal(s2.errorMessage, 'auth refused');
37
+ });
38
+ test('stop-after ssh-connect → done after SSH connects', () => {
39
+ const s = fold(baseInit({ sshEnabled: true, stopAfter: 'ssh-connect' }), [
40
+ { kind: 'start' },
41
+ { kind: 'ssh-connected' },
42
+ ]);
43
+ assert.equal(s.phase, 'done');
44
+ });
45
+ });
46
+ // ── DB connect ─────────────────────────────────────────────────────
47
+ describe('reducer: DB connect', () => {
48
+ test('db-connected → introspecting', () => {
49
+ const s = fold(baseInit(), [{ kind: 'start' }, { kind: 'db-connected' }]);
50
+ assert.equal(s.phase, 'introspecting');
51
+ });
52
+ test('stop-after db-connect → done', () => {
53
+ const s = fold(baseInit({ stopAfter: 'db-connect' }), [
54
+ { kind: 'start' },
55
+ { kind: 'db-connected' },
56
+ ]);
57
+ assert.equal(s.phase, 'done');
58
+ });
59
+ test('db-failed → terminal error', () => {
60
+ const s = fold(baseInit(), [
61
+ { kind: 'start' },
62
+ { kind: 'db-failed', error: 'auth fail' },
63
+ ]);
64
+ assert.equal(s.phase, 'error');
65
+ assert.equal(s.errorPhase, 'connecting-db');
66
+ });
67
+ });
68
+ // ── introspection ──────────────────────────────────────────────────
69
+ describe('reducer: introspection', () => {
70
+ test('introspection-loaded with no output JSON → creating-session', () => {
71
+ const s = fold(baseInit(), [
72
+ { kind: 'start' },
73
+ { kind: 'db-connected' },
74
+ { kind: 'introspection-loaded' },
75
+ ]);
76
+ assert.equal(s.phase, 'creating-session');
77
+ });
78
+ test('introspection-loaded with output JSON → output-json phase', () => {
79
+ const s = fold(baseInit({ outputJSONPath: '/tmp/x.json' }), [
80
+ { kind: 'start' },
81
+ { kind: 'db-connected' },
82
+ { kind: 'introspection-loaded' },
83
+ ]);
84
+ assert.equal(s.phase, 'output-json');
85
+ });
86
+ test('stop-after introspection (no output JSON) → done', () => {
87
+ const s = fold(baseInit({ stopAfter: 'introspection' }), [
88
+ { kind: 'start' },
89
+ { kind: 'db-connected' },
90
+ { kind: 'introspection-loaded' },
91
+ ]);
92
+ assert.equal(s.phase, 'done');
93
+ });
94
+ test('stop-after introspection with output JSON → output-json then done', () => {
95
+ const s = fold(baseInit({
96
+ stopAfter: 'introspection',
97
+ outputJSONPath: '/tmp/x.json',
98
+ }), [
99
+ { kind: 'start' },
100
+ { kind: 'db-connected' },
101
+ { kind: 'introspection-loaded' },
102
+ { kind: 'output-json-written' },
103
+ ]);
104
+ assert.equal(s.phase, 'done');
105
+ });
106
+ test('introspection-failed → terminal error', () => {
107
+ const s = fold(baseInit(), [
108
+ { kind: 'start' },
109
+ { kind: 'db-connected' },
110
+ { kind: 'introspection-failed', error: 'pg unreachable' },
111
+ ]);
112
+ assert.equal(s.phase, 'error');
113
+ assert.equal(s.errorPhase, 'introspecting');
114
+ });
115
+ });
116
+ // ── auth ───────────────────────────────────────────────────────────
117
+ describe('reducer: auth', () => {
118
+ test('session-created → awaiting-authorization', () => {
119
+ const s = fold(baseInit(), [
120
+ { kind: 'start' },
121
+ { kind: 'db-connected' },
122
+ { kind: 'introspection-loaded' },
123
+ { kind: 'session-created', sessionId: 'sess_a' },
124
+ ]);
125
+ assert.equal(s.phase, 'awaiting-authorization');
126
+ assert.equal(s.sessionId, 'sess_a');
127
+ });
128
+ test('auth-confirmed without explanation flag → awaiting-explanation', () => {
129
+ const s = fold(baseInit(), [
130
+ { kind: 'start' },
131
+ { kind: 'db-connected' },
132
+ { kind: 'introspection-loaded' },
133
+ { kind: 'session-created', sessionId: 'sess_a' },
134
+ { kind: 'auth-confirmed', token: 'tok_x' },
135
+ ]);
136
+ assert.equal(s.phase, 'awaiting-explanation');
137
+ assert.equal(s.authToken, 'tok_x');
138
+ });
139
+ test('auth-confirmed with explanation flag → preflight-checking', () => {
140
+ const s = fold(baseInit({ explanation: 'analytics warehouse' }), [
141
+ { kind: 'start' },
142
+ { kind: 'db-connected' },
143
+ { kind: 'introspection-loaded' },
144
+ { kind: 'session-created', sessionId: 'sess_a' },
145
+ { kind: 'auth-confirmed', token: 'tok_x' },
146
+ ]);
147
+ assert.equal(s.phase, 'preflight-checking');
148
+ });
149
+ test('auth-failed → terminal error', () => {
150
+ const s = fold(baseInit(), [
151
+ { kind: 'start' },
152
+ { kind: 'db-connected' },
153
+ { kind: 'introspection-loaded' },
154
+ { kind: 'session-created', sessionId: 'sess_a' },
155
+ { kind: 'auth-failed', error: 'expired' },
156
+ ]);
157
+ assert.equal(s.phase, 'error');
158
+ });
159
+ test('fast-path-completed without explanation flag → awaiting-explanation, skips awaiting-authorization', () => {
160
+ const s = fold(baseInit(), [
161
+ { kind: 'start' },
162
+ { kind: 'db-connected' },
163
+ { kind: 'introspection-loaded' },
164
+ {
165
+ kind: 'fast-path-completed',
166
+ sessionId: 'sess_a',
167
+ token: 'tok_x',
168
+ },
169
+ ]);
170
+ assert.equal(s.phase, 'awaiting-explanation');
171
+ assert.equal(s.sessionId, 'sess_a');
172
+ assert.equal(s.authToken, 'tok_x');
173
+ });
174
+ test('fast-path-completed with explanation flag → preflight-checking', () => {
175
+ const s = fold(baseInit({ explanation: 'analytics warehouse' }), [
176
+ { kind: 'start' },
177
+ { kind: 'db-connected' },
178
+ { kind: 'introspection-loaded' },
179
+ {
180
+ kind: 'fast-path-completed',
181
+ sessionId: 'sess_a',
182
+ token: 'tok_x',
183
+ },
184
+ ]);
185
+ assert.equal(s.phase, 'preflight-checking');
186
+ assert.equal(s.sessionId, 'sess_a');
187
+ assert.equal(s.authToken, 'tok_x');
188
+ });
189
+ });
190
+ // ── preflight + ingest ─────────────────────────────────────────────
191
+ describe('reducer: preflight + ingest', () => {
192
+ const upToPreflight = (init = baseInit({ explanation: 'x' })) => fold(init, [
193
+ { kind: 'start' },
194
+ { kind: 'db-connected' },
195
+ { kind: 'introspection-loaded' },
196
+ { kind: 'session-created', sessionId: 'sess_a' },
197
+ { kind: 'auth-confirmed', token: 'tok_x' },
198
+ ]);
199
+ test('check-introspection-hit with samples → awaiting-post-sampling', () => {
200
+ const s = reduce(upToPreflight(), {
201
+ kind: 'check-introspection-hit',
202
+ revisionId: 'rev_a',
203
+ samplesExist: true,
204
+ tablesNeedingSamples: [],
205
+ postIntrospectionJobId: null,
206
+ });
207
+ assert.equal(s.phase, 'awaiting-post-sampling');
208
+ assert.equal(s.preflightHit, true);
209
+ assert.equal(s.samplesAlreadyIngested, true);
210
+ assert.equal(s.postIntrospection.state, 'done');
211
+ assert.equal(s.postIntrospection.reused, true);
212
+ });
213
+ test('check-introspection-hit without samples → sampling-mask-resolving', () => {
214
+ const s = reduce(upToPreflight(), {
215
+ kind: 'check-introspection-hit',
216
+ revisionId: 'rev_a',
217
+ samplesExist: false,
218
+ tablesNeedingSamples: [],
219
+ postIntrospectionJobId: 'pi-job-1',
220
+ });
221
+ assert.equal(s.phase, 'sampling-mask-resolving');
222
+ assert.equal(s.postIntrospection.state, 'queued');
223
+ assert.equal(s.postIntrospection.jobId, 'pi-job-1');
224
+ });
225
+ test('check-introspection-miss → ingesting-introspection', () => {
226
+ const s = reduce(upToPreflight(), { kind: 'check-introspection-miss' });
227
+ assert.equal(s.phase, 'ingesting-introspection');
228
+ });
229
+ test('introspection-ingested with no PI job → post-introspection done', () => {
230
+ const s = fold(upToPreflight(), [
231
+ { kind: 'check-introspection-miss' },
232
+ {
233
+ kind: 'introspection-ingested',
234
+ revisionId: 'rev_b',
235
+ samplesExist: false,
236
+ tablesNeedingSamples: [],
237
+ postIntrospectionJobId: null,
238
+ },
239
+ ]);
240
+ assert.equal(s.phase, 'sampling-mask-resolving');
241
+ assert.equal(s.postIntrospection.state, 'done');
242
+ });
243
+ test('ingest-failed → terminal error', () => {
244
+ const s = fold(upToPreflight(), [
245
+ { kind: 'check-introspection-miss' },
246
+ { kind: 'ingest-failed', error: 'pg conflict' },
247
+ ]);
248
+ assert.equal(s.phase, 'error');
249
+ });
250
+ });
251
+ // ── sampling + upload ──────────────────────────────────────────────
252
+ describe('reducer: sampling + upload', () => {
253
+ const upToSampling = () => fold(baseInit({ explanation: 'x' }), [
254
+ { kind: 'start' },
255
+ { kind: 'db-connected' },
256
+ { kind: 'introspection-loaded' },
257
+ { kind: 'session-created', sessionId: 'sess_a' },
258
+ { kind: 'auth-confirmed', token: 'tok_x' },
259
+ {
260
+ kind: 'check-introspection-hit',
261
+ revisionId: 'rev_a',
262
+ samplesExist: false,
263
+ tablesNeedingSamples: [],
264
+ postIntrospectionJobId: 'pi-job',
265
+ },
266
+ {
267
+ kind: 'mask-loaded',
268
+ mask: { users: ['email'] },
269
+ },
270
+ ]);
271
+ test('mask-loaded → sampling phase with mask captured', () => {
272
+ const s = upToSampling();
273
+ assert.equal(s.phase, 'sampling');
274
+ assert.deepEqual(s.sampling.mask, { users: ['email'] });
275
+ });
276
+ test('sample-table-yielded accumulates events', () => {
277
+ const evt = { tableName: 'users', samples: { columns: {} } };
278
+ const s = reduce(upToSampling(), {
279
+ kind: 'sample-table-yielded',
280
+ event: evt,
281
+ });
282
+ assert.equal(s.sampling.collected.length, 1);
283
+ });
284
+ test('sampling-completed → uploading-samples + sets totalTables', () => {
285
+ const evt = { tableName: 'users', samples: { columns: {} } };
286
+ const s = fold(upToSampling(), [
287
+ { kind: 'sample-table-yielded', event: evt },
288
+ { kind: 'sample-table-yielded', event: evt },
289
+ { kind: 'sampling-completed' },
290
+ ]);
291
+ assert.equal(s.phase, 'uploading-samples');
292
+ assert.equal(s.sampling.totalTables, 2);
293
+ });
294
+ test('stop-after sampling → terminal done', () => {
295
+ const init = {
296
+ ...baseInit({ stopAfter: 'sampling', explanation: 'x' }),
297
+ };
298
+ const s = fold(fold(init, [
299
+ { kind: 'start' },
300
+ { kind: 'db-connected' },
301
+ { kind: 'introspection-loaded' },
302
+ { kind: 'session-created', sessionId: 'sess_a' },
303
+ { kind: 'auth-confirmed', token: 'tok_x' },
304
+ {
305
+ kind: 'check-introspection-hit',
306
+ revisionId: 'rev_a',
307
+ samplesExist: false,
308
+ tablesNeedingSamples: [],
309
+ postIntrospectionJobId: 'pi-job',
310
+ },
311
+ { kind: 'mask-loaded', mask: {} },
312
+ ]), [{ kind: 'sampling-completed' }]);
313
+ assert.equal(s.phase, 'done');
314
+ });
315
+ test('sampling-failed → terminal error', () => {
316
+ const s = reduce(upToSampling(), {
317
+ kind: 'sampling-failed',
318
+ error: 'oom',
319
+ });
320
+ assert.equal(s.phase, 'error');
321
+ });
322
+ test('sample-chunk-uploaded accumulates uploadedTables', () => {
323
+ const s = fold({ ...upToSampling(), phase: 'uploading-samples' }, [
324
+ { kind: 'sample-chunk-uploaded', chunkSize: 10 },
325
+ { kind: 'sample-chunk-uploaded', chunkSize: 5 },
326
+ ]);
327
+ assert.equal(s.sampling.uploadedTables, 15);
328
+ });
329
+ test('samples-upload-completed → awaiting-post-sampling', () => {
330
+ const s = fold({ ...upToSampling(), phase: 'uploading-samples' }, [{ kind: 'samples-upload-completed' }]);
331
+ assert.equal(s.phase, 'awaiting-post-sampling');
332
+ });
333
+ test('samples-upload-not-needed → awaiting-post-sampling', () => {
334
+ const s = fold({ ...upToSampling(), phase: 'uploading-samples' }, [{ kind: 'samples-upload-not-needed' }]);
335
+ assert.equal(s.phase, 'awaiting-post-sampling');
336
+ });
337
+ });
338
+ // ── post-introspection sub-status (side-channel) ───────────────────
339
+ describe('reducer: post-introspection side-channel', () => {
340
+ test('post-introspection-progress updates sub-status only', () => {
341
+ const init = baseInit();
342
+ const s = reduce(init, {
343
+ kind: 'post-introspection-progress',
344
+ stage: 'classifying',
345
+ tokensIn: 100,
346
+ tokensOut: 50,
347
+ columnsDone: 10,
348
+ columnsTotal: 100,
349
+ });
350
+ assert.equal(s.phase, init.phase);
351
+ assert.equal(s.postIntrospection.state, 'running');
352
+ assert.equal(s.postIntrospection.stage, 'classifying');
353
+ assert.equal(s.postIntrospection.tokensIn, 100);
354
+ });
355
+ test('post-introspection-completed updates sub-status only', () => {
356
+ const s = reduce(baseInit(), { kind: 'post-introspection-completed' });
357
+ assert.equal(s.postIntrospection.state, 'done');
358
+ });
359
+ test('post-introspection-failed sets error sub-status, primary phase unchanged', () => {
360
+ const init = { ...baseInit(), phase: 'sampling' };
361
+ const s = reduce(init, {
362
+ kind: 'post-introspection-failed',
363
+ error: 'gemini timeout',
364
+ });
365
+ assert.equal(s.phase, 'sampling');
366
+ assert.equal(s.postIntrospection.state, 'error');
367
+ assert.equal(s.postIntrospection.error, 'gemini timeout');
368
+ });
369
+ });
370
+ // ── post-sampling ──────────────────────────────────────────────────
371
+ describe('reducer: post-sampling', () => {
372
+ test('post-sampling-completed in awaiting-post-sampling → done', () => {
373
+ const init = { ...baseInit(), phase: 'awaiting-post-sampling' };
374
+ const s = reduce(init, { kind: 'post-sampling-completed' });
375
+ assert.equal(s.phase, 'done');
376
+ });
377
+ test('post-sampling-failed → terminal error', () => {
378
+ const init = { ...baseInit(), phase: 'awaiting-post-sampling' };
379
+ const s = reduce(init, {
380
+ kind: 'post-sampling-failed',
381
+ error: 'voyage rate limit',
382
+ });
383
+ assert.equal(s.phase, 'error');
384
+ });
385
+ });
386
+ // ── invariants ─────────────────────────────────────────────────────
387
+ describe('reducer: invariants', () => {
388
+ test('terminal states ignore further events', () => {
389
+ const done = { ...baseInit(), phase: 'done' };
390
+ const next = reduce(done, { kind: 'db-connected' });
391
+ assert.equal(next.phase, 'done');
392
+ const err = { ...baseInit(), phase: 'error' };
393
+ const next2 = reduce(err, { kind: 'introspection-loaded' });
394
+ assert.equal(next2.phase, 'error');
395
+ });
396
+ test('unrelated event in arbitrary phase leaves primary phase unchanged', () => {
397
+ // Apply db-connected while in introspecting (mismatched). Phase stays.
398
+ const s = fold(baseInit(), [{ kind: 'start' }, { kind: 'db-connected' }]);
399
+ assert.equal(s.phase, 'introspecting');
400
+ const noop = reduce(s, { kind: 'sample-chunk-uploaded', chunkSize: 5 });
401
+ assert.equal(noop.phase, 'introspecting');
402
+ // Sub-status fields untouched (uploadedTables stayed at 0).
403
+ assert.equal(noop.sampling.uploadedTables, 0);
404
+ });
405
+ test('stop-after-reached from any phase → done', () => {
406
+ const phases = [
407
+ 'connecting-ssh',
408
+ 'connecting-db',
409
+ 'introspecting',
410
+ 'sampling',
411
+ ];
412
+ for (const phase of phases) {
413
+ const s = reduce({ ...baseInit(), phase }, {
414
+ kind: 'stop-after-reached',
415
+ });
416
+ assert.equal(s.phase, 'done');
417
+ }
418
+ });
419
+ });
420
+ // ── golden flow snapshots ──────────────────────────────────────────
421
+ describe('reducer: golden flows', () => {
422
+ test('happyPath_freshRevision_full', () => {
423
+ const s = fold(baseInit({ outputSamplesDir: '/tmp/samples' }), [
424
+ { kind: 'start' },
425
+ { kind: 'db-connected' },
426
+ { kind: 'introspection-loaded' },
427
+ { kind: 'session-created', sessionId: 'sess_a' },
428
+ { kind: 'auth-confirmed', token: 'tok_x' },
429
+ { kind: 'explanation-given', value: 'analytics' },
430
+ { kind: 'check-introspection-miss' },
431
+ {
432
+ kind: 'introspection-ingested',
433
+ revisionId: 'rev_a',
434
+ samplesExist: false,
435
+ tablesNeedingSamples: [],
436
+ postIntrospectionJobId: 'pi-1',
437
+ },
438
+ { kind: 'mask-loaded', mask: {} },
439
+ { kind: 'sampling-completed' },
440
+ { kind: 'samples-upload-completed' },
441
+ { kind: 'post-introspection-completed' },
442
+ { kind: 'post-sampling-completed' },
443
+ ]);
444
+ assert.equal(s.phase, 'done');
445
+ assert.equal(s.revisionId, 'rev_a');
446
+ assert.equal(s.postIntrospection.state, 'done');
447
+ });
448
+ test('happyPath_reusedRevision_samplesExist skips sampling + upload', () => {
449
+ const s = fold(baseInit(), [
450
+ { kind: 'start' },
451
+ { kind: 'db-connected' },
452
+ { kind: 'introspection-loaded' },
453
+ { kind: 'session-created', sessionId: 'sess_a' },
454
+ { kind: 'auth-confirmed', token: 'tok_x' },
455
+ { kind: 'explanation-given', value: 'analytics' },
456
+ {
457
+ kind: 'check-introspection-hit',
458
+ revisionId: 'rev_a',
459
+ samplesExist: true,
460
+ tablesNeedingSamples: [],
461
+ postIntrospectionJobId: null,
462
+ },
463
+ { kind: 'post-sampling-completed' },
464
+ ]);
465
+ assert.equal(s.phase, 'done');
466
+ assert.equal(s.preflightHit, true);
467
+ assert.equal(s.samplesAlreadyIngested, true);
468
+ });
469
+ test('stopAfter_introspection short-circuits before auth', () => {
470
+ const s = fold(baseInit({ stopAfter: 'introspection' }), [
471
+ { kind: 'start' },
472
+ { kind: 'db-connected' },
473
+ { kind: 'introspection-loaded' },
474
+ ]);
475
+ assert.equal(s.phase, 'done');
476
+ assert.equal(s.sessionId, null);
477
+ });
478
+ });
479
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVkdWNlci50ZXN0Lm1qcyIsInNvdXJjZVJvb3QiOiIuL3NyYy8iLCJzb3VyY2VzIjpbImZsb3cvcmVkdWNlci50ZXN0Lm10cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsUUFBUSxFQUFFLElBQUksRUFBQyxNQUFNLFdBQVcsQ0FBQztBQUN6QyxPQUFPLE1BQU0sTUFBTSxvQkFBb0IsQ0FBQztBQUN4QyxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBQ3JDLE9BQU8sRUFBQyxnQkFBZ0IsRUFBa0IsTUFBTSxjQUFjLENBQUM7QUFHL0QsTUFBTSxRQUFRLEdBQUcsQ0FDYixZQUE2RCxFQUFFLEVBQ3JELEVBQUUsQ0FDWixnQkFBZ0IsQ0FBQztJQUNiLFNBQVMsRUFBRSxJQUFJO0lBQ2YsVUFBVSxFQUFFLEtBQUs7SUFDakIsWUFBWSxFQUFFLElBQUk7SUFDbEIscUJBQXFCLEVBQUUsS0FBSztJQUM1QixjQUFjLEVBQUUsSUFBSTtJQUNwQixnQkFBZ0IsRUFBRSxJQUFJO0lBQ3RCLFdBQVcsRUFBRSxJQUFJO0lBQ2pCLEdBQUcsU0FBUztDQUNmLENBQUMsQ0FBQztBQUVQLE1BQU0sSUFBSSxHQUFHLENBQUMsS0FBaUIsRUFBRSxNQUE2QixFQUFjLEVBQUUsQ0FDMUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7QUFFakMsc0VBQXNFO0FBRXRFLFFBQVEsQ0FBQyxzQkFBc0IsRUFBRSxHQUFHLEVBQUU7SUFDbEMsSUFBSSxDQUFDLHlDQUF5QyxFQUFFLEdBQUcsRUFBRTtRQUNqRCxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsUUFBUSxFQUFFLEVBQUUsRUFBQyxJQUFJLEVBQUUsT0FBTyxFQUFDLENBQUMsQ0FBQztRQUNqRCxNQUFNLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFDOUMsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENB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QUFDLEtBQUssRUFBRSxNQUFNLENBQUMsQ0FBQztRQUM5QixNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDbkMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsc0JBQXNCLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDakQsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsb0RBQW9ELEVBQUUsR0FBRyxFQUFFO1FBQzVELE1BQU0sQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsRUFBQyxTQUFTLEVBQUUsZUFBZSxFQUFDLENBQUMsRUFBRTtZQUNuRCxFQUFDLElBQUksRUFBRSxPQUFPLEVBQUM7WUFDZixFQUFDLElBQUksRUFBRSxjQUFjLEVBQUM7WUFDdEIsRUFBQyxJQUFJLEVBQUUsc0JBQXNCLEVBQUM7U0FDakMsQ0FBQyxDQUFDO1FBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQzlCLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQztJQUNwQyxDQUFDLENBQUMsQ0FBQztBQUNQLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtkZXNjcmliZSwgdGVzdH0gZnJvbSAnbm9kZTp0ZXN0JztcbmltcG9ydCBhc3NlcnQgZnJvbSAnbm9kZTphc3NlcnQvc3RyaWN0JztcbmltcG9ydCB7cmVkdWNlfSBmcm9tICcuL3JlZHVjZXIubWpzJztcbmltcG9ydCB7aW5pdGlhbEZsb3dTdGF0ZSwgdHlwZSBURmxvd1N0YXRlfSBmcm9tICcuL3N0YXRlcy5tanMnO1xuaW1wb3J0IHR5cGUge1RGbG93RXZlbnR9IGZyb20gJy4vZXZlbnRzLm1qcyc7XG5cbmNvbnN0IGJhc2VJbml0ID0gKFxuICAgIG92ZXJyaWRlczogUGFydGlhbDxQYXJhbWV0ZXJzPHR5cGVvZiBpbml0aWFsRmxvd1N0YXRlPlswXT4gPSB7fSxcbik6IFRGbG93U3RhdGUgPT5cbiAgICBpbml0aWFsRmxvd1N0YXRlKHtcbiAgICAgICAgc3RvcEFmdGVyOiBudWxsLFxuICAgICAgICBzc2hFbmFibGVkOiBmYWxzZSxcbiAgICAgICAgZmlsZU1hc2tQYXRoOiBudWxsLFxuICAgICAgICBmcm9tSW50cm9zcGVjdGlvbkZpbGU6IGZhbHNlLFxuICAgICAgICBvdXRwdXRKU09OUGF0aDogbnVsbCxcbiAgICAgICAgb3V0cHV0U2FtcGxlc0RpcjogbnVsbCxcbiAgICAgICAgZXhwbGFuYXRpb246IG51bGwsXG4gICAgICAgIC4uLm92ZXJyaWRlcyxcbiAgICB9KTtcblxuY29uc3QgZm9sZCA9IChzdGF0ZTogVEZsb3dTdGF0ZSwgZXZlbnRzOiByZWFkb25seSBURmxvd0V2ZW50W10pOiBURmxvd1N0YXRlID0+XG4gICAgZXZlbnRzLnJlZHVjZShyZWR1Y2UsIHN0YXRlKTtcblxuLy8g4pSA4pSAIHN0YXJ0IC8gU1NIIGJyYW5jaCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZGVzY3JpYmUoJ3JlZHVjZXI6IHN0YXJ0ICsgU1NIJywgKCkgPT4ge1xuICAgIHRlc3QoJ3N0YXJ0IHdpdGggU1NIIGRpc2FibGVkIOKGkiBjb25uZWN0aW5nLWRiJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBuZXh0ID0gcmVkdWNlKGJhc2VJbml0KCksIHtraW5kOiAnc3RhcnQnfSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChuZXh0LnBoYXNlLCAnY29ubmVjdGluZy1kYicpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc3RhcnQgd2l0aCBTU0ggZW5hYmxlZCDihpIgY29ubmVjdGluZy1zc2gnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IG5leHQgPSByZWR1Y2UoYmFzZUluaXQoe3NzaEVuYWJsZWQ6IHRydWV9KSwge2tpbmQ6ICdzdGFydCd9KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKG5leHQucGhhc2UsICdjb25uZWN0aW5nLXNzaCcpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc3NoLWNvbm5lY3RlZCDihpIgY29ubmVjdGluZy1kYicsICgpID0+IHtcbiAgICAgICAgY29uc3QgczEgPSByZWR1Y2UoYmFzZUluaXQoe3NzaEVuYWJsZWQ6IHRydWV9KSwge2tpbmQ6ICdzdGFydCd9KTtcbiAgICAgICAgY29uc3QgczIgPSByZWR1Y2UoczEsIHtraW5kOiAnc3NoLWNvbm5lY3RlZCd9KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMyLnBoYXNlLCAnY29ubmVjdGluZy1kYicpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc3NoLWZhaWxlZCDihpIgdGVybWluYWwgZXJyb3InLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHMxID0gcmVkdWNlKGJhc2VJbml0KHtzc2hFbmFibGVkOiB0cnVlfSksIHtraW5kOiAnc3RhcnQnfSk7XG4gICAgICAgIGNvbnN0IHMyID0gcmVkdWNlKHMxLCB7a2luZDogJ3NzaC1mYWlsZWQnLCBlcnJvcjogJ2F1dGggcmVmdXNlZCd9KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMyLnBoYXNlLCAnZXJyb3InKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMyLmVycm9yUGhhc2UsICdjb25uZWN0aW5nLXNzaCcpO1xuICAgICAgICBhc3NlcnQuZXF1YWwoczIuZXJyb3JNZXNzYWdlLCAnYXV0aCByZWZ1c2VkJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzdG9wLWFmdGVyIHNzaC1jb25uZWN0IOKGkiBkb25lIGFmdGVyIFNTSCBjb25uZWN0cycsICgpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IGZvbGQoYmFzZUluaXQoe3NzaEVuYWJsZWQ6IHRydWUsIHN0b3BBZnRlcjogJ3NzaC1jb25uZWN0J30pLCBbXG4gICAgICAgICAgICB7a2luZDogJ3N0YXJ0J30sXG4gICAgICAgICAgICB7a2luZDogJ3NzaC1jb25uZWN0ZWQnfSxcbiAgICAgICAgXSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLnBoYXNlLCAnZG9uZScpO1xuICAgIH0pO1xufSk7XG5cbi8vIOKUgOKUgCBEQiBjb25uZWN0IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5kZXNjcmliZSgncmVkdWNlcjogREIgY29ubmVjdCcsICgpID0+IHtcbiAgICB0ZXN0KCdkYi1jb25uZWN0ZWQg4oaSIGludHJvc3BlY3RpbmcnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHMgPSBmb2xkKGJhc2VJbml0KCksIFt7a2luZDogJ3N0YXJ0J30sIHtraW5kOiAnZGItY29ubmVjdGVkJ31dKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucGhhc2UsICdpbnRyb3NwZWN0aW5nJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzdG9wLWFmdGVyIGRiLWNvbm5lY3Qg4oaSIGRvbmUnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHMgPSBmb2xkKGJhc2VJbml0KHtzdG9wQWZ0ZXI6ICdkYi1jb25uZWN0J30pLCBbXG4gICAgICAgICAgICB7a2luZDogJ3N0YXJ0J30sXG4gICAgICAgICAgICB7a2luZDogJ2RiLWNvbm5lY3RlZCd9LFxuICAgICAgICBdKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucGhhc2UsICdkb25lJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdkYi1mYWlsZWQg4oaSIHRlcm1pbmFsIGVycm9yJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBzID0gZm9sZChiYXNlSW5pdCgpLCBbXG4gICAgICAgICAgICB7a2luZDogJ3N0YXJ0J30sXG4gICAgICAgICAgICB7a2luZDogJ2RiLWZhaWxlZCcsIGVycm9yOiAnYXV0aCBmYWlsJ30sXG4gICAgICAgIF0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ2Vycm9yJyk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLmVycm9yUGhhc2UsICdjb25uZWN0aW5nLWRiJyk7XG4gICAgfSk7XG59KTtcblxuLy8g4pSA4pSAIGludHJvc3BlY3Rpb24g4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmRlc2NyaWJlKCdyZWR1Y2VyOiBpbnRyb3NwZWN0aW9uJywgKCkgPT4ge1xuICAgIHRlc3QoJ2ludHJvc3BlY3Rpb24tbG9hZGVkIHdpdGggbm8gb3V0cHV0IEpTT04g4oaSIGNyZWF0aW5nLXNlc3Npb24nLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHMgPSBmb2xkKGJhc2VJbml0KCksIFtcbiAgICAgICAgICAgIHtraW5kOiAnc3RhcnQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnZGItY29ubmVjdGVkJ30sXG4gICAgICAgICAgICB7a2luZDogJ2ludHJvc3BlY3Rpb24tbG9hZGVkJ30sXG4gICAgICAgIF0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ2NyZWF0aW5nLXNlc3Npb24nKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2ludHJvc3BlY3Rpb24tbG9hZGVkIHdpdGggb3V0cHV0IEpTT04g4oaSIG91dHB1dC1qc29uIHBoYXNlJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBzID0gZm9sZChiYXNlSW5pdCh7b3V0cHV0SlNPTlBhdGg6ICcvdG1wL3guanNvbid9KSwgW1xuICAgICAgICAgICAge2tpbmQ6ICdzdGFydCd9LFxuICAgICAgICAgICAge2tpbmQ6ICdkYi1jb25uZWN0ZWQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnaW50cm9zcGVjdGlvbi1sb2FkZWQnfSxcbiAgICAgICAgXSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLnBoYXNlLCAnb3V0cHV0LWpzb24nKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3N0b3AtYWZ0ZXIgaW50cm9zcGVjdGlvbiAobm8gb3V0cHV0IEpTT04pIOKGkiBkb25lJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBzID0gZm9sZChiYXNlSW5pdCh7c3RvcEFmdGVyOiAnaW50cm9zcGVjdGlvbid9KSwgW1xuICAgICAgICAgICAge2tpbmQ6ICdzdGFydCd9LFxuICAgICAgICAgICAge2tpbmQ6ICdkYi1jb25uZWN0ZWQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnaW50cm9zcGVjdGlvbi1sb2FkZWQnfSxcbiAgICAgICAgXSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLnBoYXNlLCAnZG9uZScpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc3RvcC1hZnRlciBpbnRyb3NwZWN0aW9uIHdpdGggb3V0cHV0IEpTT04g4oaSIG91dHB1dC1qc29uIHRoZW4gZG9uZScsICgpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IGZvbGQoXG4gICAgICAgICAgICBiYXNlSW5pdCh7XG4gICAgICAgICAgICAgICAgc3RvcEFmdGVyOiAnaW50cm9zcGVjdGlvbicsXG4gICAgICAgICAgICAgICAgb3V0cHV0SlNPTlBhdGg6ICcvdG1wL3guanNvbicsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIFtcbiAgICAgICAgICAgICAgICB7a2luZDogJ3N0YXJ0J30sXG4gICAgICAgICAgICAgICAge2tpbmQ6ICdkYi1jb25uZWN0ZWQnfSxcbiAgICAgICAgICAgICAgICB7a2luZDogJ2ludHJvc3BlY3Rpb24tbG9hZGVkJ30sXG4gICAgICAgICAgICAgICAge2tpbmQ6ICdvdXRwdXQtanNvbi13cml0dGVuJ30sXG4gICAgICAgICAgICBdLFxuICAgICAgICApO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ2RvbmUnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2ludHJvc3BlY3Rpb24tZmFpbGVkIOKGkiB0ZXJtaW5hbCBlcnJvcicsICgpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IGZvbGQoYmFzZUluaXQoKSwgW1xuICAgICAgICAgICAge2tpbmQ6ICdzdGFydCd9LFxuICAgICAgICAgICAge2tpbmQ6ICdkYi1jb25uZWN0ZWQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnaW50cm9zcGVjdGlvbi1mYWlsZWQnLCBlcnJvcjogJ3BnIHVucmVhY2hhYmxlJ30sXG4gICAgICAgIF0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ2Vycm9yJyk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLmVycm9yUGhhc2UsICdpbnRyb3NwZWN0aW5nJyk7XG4gICAgfSk7XG59KTtcblxuLy8g4pSA4pSAIGF1dGgg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmRlc2NyaWJlKCdyZWR1Y2VyOiBhdXRoJywgKCkgPT4ge1xuICAgIHRlc3QoJ3Nlc3Npb24tY3JlYXRlZCDihpIgYXdhaXRpbmctYXV0aG9yaXphdGlvbicsICgpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IGZvbGQoYmFzZUluaXQoKSwgW1xuICAgICAgICAgICAge2tpbmQ6ICdzdGFydCd9LFxuICAgICAgICAgICAge2tpbmQ6ICdkYi1jb25uZWN0ZWQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnaW50cm9zcGVjdGlvbi1sb2FkZWQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnc2Vzc2lvbi1jcmVhdGVkJywgc2Vzc2lvbklkOiAnc2Vzc19hJ30sXG4gICAgICAgIF0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ2F3YWl0aW5nLWF1dGhvcml6YXRpb24nKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMuc2Vzc2lvbklkLCAnc2Vzc19hJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdhdXRoLWNvbmZpcm1lZCB3aXRob3V0IGV4cGxhbmF0aW9uIGZsYWcg4oaSIGF3YWl0aW5nLWV4cGxhbmF0aW9uJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBzID0gZm9sZChiYXNlSW5pdCgpLCBbXG4gICAgICAgICAgICB7a2luZDogJ3N0YXJ0J30sXG4gICAgICAgICAgICB7a2luZDogJ2RiLWNvbm5lY3RlZCd9LFxuICAgICAgICAgICAge2tpbmQ6ICdpbnRyb3NwZWN0aW9uLWxvYWRlZCd9LFxuICAgICAgICAgICAge2tpbmQ6ICdzZXNzaW9uLWNyZWF0ZWQnLCBzZXNzaW9uSWQ6ICdzZXNzX2EnfSxcbiAgICAgICAgICAgIHtraW5kOiAnYXV0aC1jb25maXJtZWQnLCB0b2tlbjogJ3Rva194J30sXG4gICAgICAgIF0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ2F3YWl0aW5nLWV4cGxhbmF0aW9uJyk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLmF1dGhUb2tlbiwgJ3Rva194Jyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdhdXRoLWNvbmZpcm1lZCB3aXRoIGV4cGxhbmF0aW9uIGZsYWcg4oaSIHByZWZsaWdodC1jaGVja2luZycsICgpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IGZvbGQoYmFzZUluaXQoe2V4cGxhbmF0aW9uOiAnYW5hbHl0aWNzIHdhcmVob3VzZSd9KSwgW1xuICAgICAgICAgICAge2tpbmQ6ICdzdGFydCd9LFxuICAgICAgICAgICAge2tpbmQ6ICdkYi1jb25uZWN0ZWQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnaW50cm9zcGVjdGlvbi1sb2FkZWQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnc2Vzc2lvbi1jcmVhdGVkJywgc2Vzc2lvbklkOiAnc2Vzc19hJ30sXG4gICAgICAgICAgICB7a2luZDogJ2F1dGgtY29uZmlybWVkJywgdG9rZW46ICd0b2tfeCd9LFxuICAgICAgICBdKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucGhhc2UsICdwcmVmbGlnaHQtY2hlY2tpbmcnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2F1dGgtZmFpbGVkIOKGkiB0ZXJtaW5hbCBlcnJvcicsICgpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IGZvbGQoYmFzZUluaXQoKSwgW1xuICAgICAgICAgICAge2tpbmQ6ICdzdGFydCd9LFxuICAgICAgICAgICAge2tpbmQ6ICdkYi1jb25uZWN0ZWQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnaW50cm9zcGVjdGlvbi1sb2FkZWQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnc2Vzc2lvbi1jcmVhdGVkJywgc2Vzc2lvbklkOiAnc2Vzc19hJ30sXG4gICAgICAgICAgICB7a2luZDogJ2F1dGgtZmFpbGVkJywgZXJyb3I6ICdleHBpcmVkJ30sXG4gICAgICAgIF0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ2Vycm9yJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdmYXN0LXBhdGgtY29tcGxldGVkIHdpdGhvdXQgZXhwbGFuYXRpb24gZmxhZyDihpIgYXdhaXRpbmctZXhwbGFuYXRpb24sIHNraXBzIGF3YWl0aW5nLWF1dGhvcml6YXRpb24nLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHMgPSBmb2xkKGJhc2VJbml0KCksIFtcbiAgICAgICAgICAgIHtraW5kOiAnc3RhcnQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnZGItY29ubmVjdGVkJ30sXG4gICAgICAgICAgICB7a2luZDogJ2ludHJvc3BlY3Rpb24tbG9hZGVkJ30sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAga2luZDogJ2Zhc3QtcGF0aC1jb21wbGV0ZWQnLFxuICAgICAgICAgICAgICAgIHNlc3Npb25JZDogJ3Nlc3NfYScsXG4gICAgICAgICAgICAgICAgdG9rZW46ICd0b2tfeCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICBdKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucGhhc2UsICdhd2FpdGluZy1leHBsYW5hdGlvbicpO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5zZXNzaW9uSWQsICdzZXNzX2EnKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMuYXV0aFRva2VuLCAndG9rX3gnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2Zhc3QtcGF0aC1jb21wbGV0ZWQgd2l0aCBleHBsYW5hdGlvbiBmbGFnIOKGkiBwcmVmbGlnaHQtY2hlY2tpbmcnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHMgPSBmb2xkKGJhc2VJbml0KHtleHBsYW5hdGlvbjogJ2FuYWx5dGljcyB3YXJlaG91c2UnfSksIFtcbiAgICAgICAgICAgIHtraW5kOiAnc3RhcnQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnZGItY29ubmVjdGVkJ30sXG4gICAgICAgICAgICB7a2luZDogJ2ludHJvc3BlY3Rpb24tbG9hZGVkJ30sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAga2luZDogJ2Zhc3QtcGF0aC1jb21wbGV0ZWQnLFxuICAgICAgICAgICAgICAgIHNlc3Npb25JZDogJ3Nlc3NfYScsXG4gICAgICAgICAgICAgICAgdG9rZW46ICd0b2tfeCcsXG4gICAgICAgICAgICB9LFxuICAgICAgICBdKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucGhhc2UsICdwcmVmbGlnaHQtY2hlY2tpbmcnKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMuc2Vzc2lvbklkLCAnc2Vzc19hJyk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLmF1dGhUb2tlbiwgJ3Rva194Jyk7XG4gICAgfSk7XG59KTtcblxuLy8g4pSA4pSAIHByZWZsaWdodCArIGluZ2VzdCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZGVzY3JpYmUoJ3JlZHVjZXI6IHByZWZsaWdodCArIGluZ2VzdCcsICgpID0+IHtcbiAgICBjb25zdCB1cFRvUHJlZmxpZ2h0ID0gKGluaXQgPSBiYXNlSW5pdCh7ZXhwbGFuYXRpb246ICd4J30pKSA9PlxuICAgICAgICBmb2xkKGluaXQsIFtcbiAgICAgICAgICAgIHtraW5kOiAnc3RhcnQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnZGItY29ubmVjdGVkJ30sXG4gICAgICAgICAgICB7a2luZDogJ2ludHJvc3BlY3Rpb24tbG9hZGVkJ30sXG4gICAgICAgICAgICB7a2luZDogJ3Nlc3Npb24tY3JlYXRlZCcsIHNlc3Npb25JZDogJ3Nlc3NfYSd9LFxuICAgICAgICAgICAge2tpbmQ6ICdhdXRoLWNvbmZpcm1lZCcsIHRva2VuOiAndG9rX3gnfSxcbiAgICAgICAgXSk7XG5cbiAgICB0ZXN0KCdjaGVjay1pbnRyb3NwZWN0aW9uLWhpdCB3aXRoIHNhbXBsZXMg4oaSIGF3YWl0aW5nLXBvc3Qtc2FtcGxpbmcnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHMgPSByZWR1Y2UodXBUb1ByZWZsaWdodCgpLCB7XG4gICAgICAgICAgICBraW5kOiAnY2hlY2staW50cm9zcGVjdGlvbi1oaXQnLFxuICAgICAgICAgICAgcmV2aXNpb25JZDogJ3Jldl9hJyxcbiAgICAgICAgICAgIHNhbXBsZXNFeGlzdDogdHJ1ZSxcbiAgICAgICAgICAgIHRhYmxlc05lZWRpbmdTYW1wbGVzOiBbXSxcbiAgICAgICAgICAgIHBvc3RJbnRyb3NwZWN0aW9uSm9iSWQ6IG51bGwsXG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ2F3YWl0aW5nLXBvc3Qtc2FtcGxpbmcnKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucHJlZmxpZ2h0SGl0LCB0cnVlKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMuc2FtcGxlc0FscmVhZHlJbmdlc3RlZCwgdHJ1ZSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLnBvc3RJbnRyb3NwZWN0aW9uLnN0YXRlLCAnZG9uZScpO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5wb3N0SW50cm9zcGVjdGlvbi5yZXVzZWQsIHRydWUpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnY2hlY2staW50cm9zcGVjdGlvbi1oaXQgd2l0aG91dCBzYW1wbGVzIOKGkiBzYW1wbGluZy1tYXNrLXJlc29sdmluZycsICgpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IHJlZHVjZSh1cFRvUHJlZmxpZ2h0KCksIHtcbiAgICAgICAgICAgIGtpbmQ6ICdjaGVjay1pbnRyb3NwZWN0aW9uLWhpdCcsXG4gICAgICAgICAgICByZXZpc2lvbklkOiAncmV2X2EnLFxuICAgICAgICAgICAgc2FtcGxlc0V4aXN0OiBmYWxzZSxcbiAgICAgICAgICAgIHRhYmxlc05lZWRpbmdTYW1wbGVzOiBbXSxcbiAgICAgICAgICAgIHBvc3RJbnRyb3NwZWN0aW9uSm9iSWQ6ICdwaS1qb2ItMScsXG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ3NhbXBsaW5nLW1hc2stcmVzb2x2aW5nJyk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLnBvc3RJbnRyb3NwZWN0aW9uLnN0YXRlLCAncXVldWVkJyk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLnBvc3RJbnRyb3NwZWN0aW9uLmpvYklkLCAncGktam9iLTEnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ2NoZWNrLWludHJvc3BlY3Rpb24tbWlzcyDihpIgaW5nZXN0aW5nLWludHJvc3BlY3Rpb24nLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHMgPSByZWR1Y2UodXBUb1ByZWZsaWdodCgpLCB7a2luZDogJ2NoZWNrLWludHJvc3BlY3Rpb24tbWlzcyd9KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucGhhc2UsICdpbmdlc3RpbmctaW50cm9zcGVjdGlvbicpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnaW50cm9zcGVjdGlvbi1pbmdlc3RlZCB3aXRoIG5vIFBJIGpvYiDihpIgcG9zdC1pbnRyb3NwZWN0aW9uIGRvbmUnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHMgPSBmb2xkKHVwVG9QcmVmbGlnaHQoKSwgW1xuICAgICAgICAgICAge2tpbmQ6ICdjaGVjay1pbnRyb3NwZWN0aW9uLW1pc3MnfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBraW5kOiAnaW50cm9zcGVjdGlvbi1pbmdlc3RlZCcsXG4gICAgICAgICAgICAgICAgcmV2aXNpb25JZDogJ3Jldl9iJyxcbiAgICAgICAgICAgICAgICBzYW1wbGVzRXhpc3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHRhYmxlc05lZWRpbmdTYW1wbGVzOiBbXSxcbiAgICAgICAgICAgICAgICBwb3N0SW50cm9zcGVjdGlvbkpvYklkOiBudWxsLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgXSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLnBoYXNlLCAnc2FtcGxpbmctbWFzay1yZXNvbHZpbmcnKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucG9zdEludHJvc3BlY3Rpb24uc3RhdGUsICdkb25lJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdpbmdlc3QtZmFpbGVkIOKGkiB0ZXJtaW5hbCBlcnJvcicsICgpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IGZvbGQodXBUb1ByZWZsaWdodCgpLCBbXG4gICAgICAgICAgICB7a2luZDogJ2NoZWNrLWludHJvc3BlY3Rpb24tbWlzcyd9LFxuICAgICAgICAgICAge2tpbmQ6ICdpbmdlc3QtZmFpbGVkJywgZXJyb3I6ICdwZyBjb25mbGljdCd9LFxuICAgICAgICBdKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucGhhc2UsICdlcnJvcicpO1xuICAgIH0pO1xufSk7XG5cbi8vIOKUgOKUgCBzYW1wbGluZyArIHVwbG9hZCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZGVzY3JpYmUoJ3JlZHVjZXI6IHNhbXBsaW5nICsgdXBsb2FkJywgKCkgPT4ge1xuICAgIGNvbnN0IHVwVG9TYW1wbGluZyA9ICgpID0+XG4gICAgICAgIGZvbGQoYmFzZUluaXQoe2V4cGxhbmF0aW9uOiAneCd9KSwgW1xuICAgICAgICAgICAge2tpbmQ6ICdzdGFydCd9LFxuICAgICAgICAgICAge2tpbmQ6ICdkYi1jb25uZWN0ZWQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnaW50cm9zcGVjdGlvbi1sb2FkZWQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnc2Vzc2lvbi1jcmVhdGVkJywgc2Vzc2lvbklkOiAnc2Vzc19hJ30sXG4gICAgICAgICAgICB7a2luZDogJ2F1dGgtY29uZmlybWVkJywgdG9rZW46ICd0b2tfeCd9LFxuICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIGtpbmQ6ICdjaGVjay1pbnRyb3NwZWN0aW9uLWhpdCcsXG4gICAgICAgICAgICAgICAgcmV2aXNpb25JZDogJ3Jldl9hJyxcbiAgICAgICAgICAgICAgICBzYW1wbGVzRXhpc3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHRhYmxlc05lZWRpbmdTYW1wbGVzOiBbXSxcbiAgICAgICAgICAgICAgICBwb3N0SW50cm9zcGVjdGlvbkpvYklkOiAncGktam9iJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAga2luZDogJ21hc2stbG9hZGVkJyxcbiAgICAgICAgICAgICAgICBtYXNrOiB7dXNlcnM6IFsnZW1haWwnXX0sXG4gICAgICAgICAgICB9LFxuICAgICAgICBdKTtcblxuICAgIHRlc3QoJ21hc2stbG9hZGVkIOKGkiBzYW1wbGluZyBwaGFzZSB3aXRoIG1hc2sgY2FwdHVyZWQnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHMgPSB1cFRvU2FtcGxpbmcoKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucGhhc2UsICdzYW1wbGluZycpO1xuICAgICAgICBhc3NlcnQuZGVlcEVxdWFsKHMuc2FtcGxpbmcubWFzaywge3VzZXJzOiBbJ2VtYWlsJ119KTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3NhbXBsZS10YWJsZS15aWVsZGVkIGFjY3VtdWxhdGVzIGV2ZW50cycsICgpID0+IHtcbiAgICAgICAgY29uc3QgZXZ0ID0ge3RhYmxlTmFtZTogJ3VzZXJzJywgc2FtcGxlczoge2NvbHVtbnM6IHt9fX0gYXMgbmV2ZXI7XG4gICAgICAgIGNvbnN0IHMgPSByZWR1Y2UodXBUb1NhbXBsaW5nKCksIHtcbiAgICAgICAgICAgIGtpbmQ6ICdzYW1wbGUtdGFibGUteWllbGRlZCcsXG4gICAgICAgICAgICBldmVudDogZXZ0LFxuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMuc2FtcGxpbmcuY29sbGVjdGVkLmxlbmd0aCwgMSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzYW1wbGluZy1jb21wbGV0ZWQg4oaSIHVwbG9hZGluZy1zYW1wbGVzICsgc2V0cyB0b3RhbFRhYmxlcycsICgpID0+IHtcbiAgICAgICAgY29uc3QgZXZ0ID0ge3RhYmxlTmFtZTogJ3VzZXJzJywgc2FtcGxlczoge2NvbHVtbnM6IHt9fX0gYXMgbmV2ZXI7XG4gICAgICAgIGNvbnN0IHMgPSBmb2xkKHVwVG9TYW1wbGluZygpLCBbXG4gICAgICAgICAgICB7a2luZDogJ3NhbXBsZS10YWJsZS15aWVsZGVkJywgZXZlbnQ6IGV2dH0sXG4gICAgICAgICAgICB7a2luZDogJ3NhbXBsZS10YWJsZS15aWVsZGVkJywgZXZlbnQ6IGV2dH0sXG4gICAgICAgICAgICB7a2luZDogJ3NhbXBsaW5nLWNvbXBsZXRlZCd9LFxuICAgICAgICBdKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucGhhc2UsICd1cGxvYWRpbmctc2FtcGxlcycpO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5zYW1wbGluZy50b3RhbFRhYmxlcywgMik7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzdG9wLWFmdGVyIHNhbXBsaW5nIOKGkiB0ZXJtaW5hbCBkb25lJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbml0ID0ge1xuICAgICAgICAgICAgLi4uYmFzZUluaXQoe3N0b3BBZnRlcjogJ3NhbXBsaW5nJywgZXhwbGFuYXRpb246ICd4J30pLFxuICAgICAgICB9O1xuICAgICAgICBjb25zdCBzID0gZm9sZChcbiAgICAgICAgICAgIGZvbGQoaW5pdCwgW1xuICAgICAgICAgICAgICAgIHtraW5kOiAnc3RhcnQnfSxcbiAgICAgICAgICAgICAgICB7a2luZDogJ2RiLWNvbm5lY3RlZCd9LFxuICAgICAgICAgICAgICAgIHtraW5kOiAnaW50cm9zcGVjdGlvbi1sb2FkZWQnfSxcbiAgICAgICAgICAgICAgICB7a2luZDogJ3Nlc3Npb24tY3JlYXRlZCcsIHNlc3Npb25JZDogJ3Nlc3NfYSd9LFxuICAgICAgICAgICAgICAgIHtraW5kOiAnYXV0aC1jb25maXJtZWQnLCB0b2tlbjogJ3Rva194J30sXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBraW5kOiAnY2hlY2staW50cm9zcGVjdGlvbi1oaXQnLFxuICAgICAgICAgICAgICAgICAgICByZXZpc2lvbklkOiAncmV2X2EnLFxuICAgICAgICAgICAgICAgICAgICBzYW1wbGVzRXhpc3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICB0YWJsZXNOZWVkaW5nU2FtcGxlczogW10sXG4gICAgICAgICAgICAgICAgICAgIHBvc3RJbnRyb3NwZWN0aW9uSm9iSWQ6ICdwaS1qb2InLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAge2tpbmQ6ICdtYXNrLWxvYWRlZCcsIG1hc2s6IHt9fSxcbiAgICAgICAgICAgIF0pLFxuICAgICAgICAgICAgW3traW5kOiAnc2FtcGxpbmctY29tcGxldGVkJ31dLFxuICAgICAgICApO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ2RvbmUnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3NhbXBsaW5nLWZhaWxlZCDihpIgdGVybWluYWwgZXJyb3InLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHMgPSByZWR1Y2UodXBUb1NhbXBsaW5nKCksIHtcbiAgICAgICAgICAgIGtpbmQ6ICdzYW1wbGluZy1mYWlsZWQnLFxuICAgICAgICAgICAgZXJyb3I6ICdvb20nLFxuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucGhhc2UsICdlcnJvcicpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2FtcGxlLWNodW5rLXVwbG9hZGVkIGFjY3VtdWxhdGVzIHVwbG9hZGVkVGFibGVzJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBzID0gZm9sZChcbiAgICAgICAgICAgIHsuLi51cFRvU2FtcGxpbmcoKSwgcGhhc2U6ICd1cGxvYWRpbmctc2FtcGxlcyd9IGFzIFRGbG93U3RhdGUsXG4gICAgICAgICAgICBbXG4gICAgICAgICAgICAgICAge2tpbmQ6ICdzYW1wbGUtY2h1bmstdXBsb2FkZWQnLCBjaHVua1NpemU6IDEwfSxcbiAgICAgICAgICAgICAgICB7a2luZDogJ3NhbXBsZS1jaHVuay11cGxvYWRlZCcsIGNodW5rU2l6ZTogNX0sXG4gICAgICAgICAgICBdLFxuICAgICAgICApO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5zYW1wbGluZy51cGxvYWRlZFRhYmxlcywgMTUpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2FtcGxlcy11cGxvYWQtY29tcGxldGVkIOKGkiBhd2FpdGluZy1wb3N0LXNhbXBsaW5nJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBzID0gZm9sZChcbiAgICAgICAgICAgIHsuLi51cFRvU2FtcGxpbmcoKSwgcGhhc2U6ICd1cGxvYWRpbmctc2FtcGxlcyd9IGFzIFRGbG93U3RhdGUsXG4gICAgICAgICAgICBbe2tpbmQ6ICdzYW1wbGVzLXVwbG9hZC1jb21wbGV0ZWQnfV0sXG4gICAgICAgICk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLnBoYXNlLCAnYXdhaXRpbmctcG9zdC1zYW1wbGluZycpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnc2FtcGxlcy11cGxvYWQtbm90LW5lZWRlZCDihpIgYXdhaXRpbmctcG9zdC1zYW1wbGluZycsICgpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IGZvbGQoXG4gICAgICAgICAgICB7Li4udXBUb1NhbXBsaW5nKCksIHBoYXNlOiAndXBsb2FkaW5nLXNhbXBsZXMnfSBhcyBURmxvd1N0YXRlLFxuICAgICAgICAgICAgW3traW5kOiAnc2FtcGxlcy11cGxvYWQtbm90LW5lZWRlZCd9XSxcbiAgICAgICAgKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucGhhc2UsICdhd2FpdGluZy1wb3N0LXNhbXBsaW5nJyk7XG4gICAgfSk7XG59KTtcblxuLy8g4pSA4pSAIHBvc3QtaW50cm9zcGVjdGlvbiBzdWItc3RhdHVzIChzaWRlLWNoYW5uZWwpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5kZXNjcmliZSgncmVkdWNlcjogcG9zdC1pbnRyb3NwZWN0aW9uIHNpZGUtY2hhbm5lbCcsICgpID0+IHtcbiAgICB0ZXN0KCdwb3N0LWludHJvc3BlY3Rpb24tcHJvZ3Jlc3MgdXBkYXRlcyBzdWItc3RhdHVzIG9ubHknLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IGluaXQgPSBiYXNlSW5pdCgpO1xuICAgICAgICBjb25zdCBzID0gcmVkdWNlKGluaXQsIHtcbiAgICAgICAgICAgIGtpbmQ6ICdwb3N0LWludHJvc3BlY3Rpb24tcHJvZ3Jlc3MnLFxuICAgICAgICAgICAgc3RhZ2U6ICdjbGFzc2lmeWluZycsXG4gICAgICAgICAgICB0b2tlbnNJbjogMTAwLFxuICAgICAgICAgICAgdG9rZW5zT3V0OiA1MCxcbiAgICAgICAgICAgIGNvbHVtbnNEb25lOiAxMCxcbiAgICAgICAgICAgIGNvbHVtbnNUb3RhbDogMTAwLFxuICAgICAgICB9KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucGhhc2UsIGluaXQucGhhc2UpO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5wb3N0SW50cm9zcGVjdGlvbi5zdGF0ZSwgJ3J1bm5pbmcnKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucG9zdEludHJvc3BlY3Rpb24uc3RhZ2UsICdjbGFzc2lmeWluZycpO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5wb3N0SW50cm9zcGVjdGlvbi50b2tlbnNJbiwgMTAwKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Bvc3QtaW50cm9zcGVjdGlvbi1jb21wbGV0ZWQgdXBkYXRlcyBzdWItc3RhdHVzIG9ubHknLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHMgPSByZWR1Y2UoYmFzZUluaXQoKSwge2tpbmQ6ICdwb3N0LWludHJvc3BlY3Rpb24tY29tcGxldGVkJ30pO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5wb3N0SW50cm9zcGVjdGlvbi5zdGF0ZSwgJ2RvbmUnKTtcbiAgICB9KTtcblxuICAgIHRlc3QoJ3Bvc3QtaW50cm9zcGVjdGlvbi1mYWlsZWQgc2V0cyBlcnJvciBzdWItc3RhdHVzLCBwcmltYXJ5IHBoYXNlIHVuY2hhbmdlZCcsICgpID0+IHtcbiAgICAgICAgY29uc3QgaW5pdCA9IHsuLi5iYXNlSW5pdCgpLCBwaGFzZTogJ3NhbXBsaW5nJyBhcyBjb25zdH07XG4gICAgICAgIGNvbnN0IHMgPSByZWR1Y2UoaW5pdCwge1xuICAgICAgICAgICAga2luZDogJ3Bvc3QtaW50cm9zcGVjdGlvbi1mYWlsZWQnLFxuICAgICAgICAgICAgZXJyb3I6ICdnZW1pbmkgdGltZW91dCcsXG4gICAgICAgIH0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ3NhbXBsaW5nJyk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLnBvc3RJbnRyb3NwZWN0aW9uLnN0YXRlLCAnZXJyb3InKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucG9zdEludHJvc3BlY3Rpb24uZXJyb3IsICdnZW1pbmkgdGltZW91dCcpO1xuICAgIH0pO1xufSk7XG5cbi8vIOKUgOKUgCBwb3N0LXNhbXBsaW5nIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG5kZXNjcmliZSgncmVkdWNlcjogcG9zdC1zYW1wbGluZycsICgpID0+IHtcbiAgICB0ZXN0KCdwb3N0LXNhbXBsaW5nLWNvbXBsZXRlZCBpbiBhd2FpdGluZy1wb3N0LXNhbXBsaW5nIOKGkiBkb25lJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbml0ID0gey4uLmJhc2VJbml0KCksIHBoYXNlOiAnYXdhaXRpbmctcG9zdC1zYW1wbGluZycgYXMgY29uc3R9O1xuICAgICAgICBjb25zdCBzID0gcmVkdWNlKGluaXQsIHtraW5kOiAncG9zdC1zYW1wbGluZy1jb21wbGV0ZWQnfSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLnBoYXNlLCAnZG9uZScpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgncG9zdC1zYW1wbGluZy1mYWlsZWQg4oaSIHRlcm1pbmFsIGVycm9yJywgKCkgPT4ge1xuICAgICAgICBjb25zdCBpbml0ID0gey4uLmJhc2VJbml0KCksIHBoYXNlOiAnYXdhaXRpbmctcG9zdC1zYW1wbGluZycgYXMgY29uc3R9O1xuICAgICAgICBjb25zdCBzID0gcmVkdWNlKGluaXQsIHtcbiAgICAgICAgICAgIGtpbmQ6ICdwb3N0LXNhbXBsaW5nLWZhaWxlZCcsXG4gICAgICAgICAgICBlcnJvcjogJ3ZveWFnZSByYXRlIGxpbWl0JyxcbiAgICAgICAgfSk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLnBoYXNlLCAnZXJyb3InKTtcbiAgICB9KTtcbn0pO1xuXG4vLyDilIDilIAgaW52YXJpYW50cyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuZGVzY3JpYmUoJ3JlZHVjZXI6IGludmFyaWFudHMnLCAoKSA9PiB7XG4gICAgdGVzdCgndGVybWluYWwgc3RhdGVzIGlnbm9yZSBmdXJ0aGVyIGV2ZW50cycsICgpID0+IHtcbiAgICAgICAgY29uc3QgZG9uZTogVEZsb3dTdGF0ZSA9IHsuLi5iYXNlSW5pdCgpLCBwaGFzZTogJ2RvbmUnfTtcbiAgICAgICAgY29uc3QgbmV4dCA9IHJlZHVjZShkb25lLCB7a2luZDogJ2RiLWNvbm5lY3RlZCd9KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKG5leHQucGhhc2UsICdkb25lJyk7XG5cbiAgICAgICAgY29uc3QgZXJyOiBURmxvd1N0YXRlID0gey4uLmJhc2VJbml0KCksIHBoYXNlOiAnZXJyb3InfTtcbiAgICAgICAgY29uc3QgbmV4dDIgPSByZWR1Y2UoZXJyLCB7a2luZDogJ2ludHJvc3BlY3Rpb24tbG9hZGVkJ30pO1xuICAgICAgICBhc3NlcnQuZXF1YWwobmV4dDIucGhhc2UsICdlcnJvcicpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgndW5yZWxhdGVkIGV2ZW50IGluIGFyYml0cmFyeSBwaGFzZSBsZWF2ZXMgcHJpbWFyeSBwaGFzZSB1bmNoYW5nZWQnLCAoKSA9PiB7XG4gICAgICAgIC8vIEFwcGx5IGRiLWNvbm5lY3RlZCB3aGlsZSBpbiBpbnRyb3NwZWN0aW5nIChtaXNtYXRjaGVkKS4gUGhhc2Ugc3RheXMuXG4gICAgICAgIGNvbnN0IHMgPSBmb2xkKGJhc2VJbml0KCksIFt7a2luZDogJ3N0YXJ0J30sIHtraW5kOiAnZGItY29ubmVjdGVkJ31dKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucGhhc2UsICdpbnRyb3NwZWN0aW5nJyk7XG4gICAgICAgIGNvbnN0IG5vb3AgPSByZWR1Y2Uocywge2tpbmQ6ICdzYW1wbGUtY2h1bmstdXBsb2FkZWQnLCBjaHVua1NpemU6IDV9KTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKG5vb3AucGhhc2UsICdpbnRyb3NwZWN0aW5nJyk7XG4gICAgICAgIC8vIFN1Yi1zdGF0dXMgZmllbGRzIHVudG91Y2hlZCAodXBsb2FkZWRUYWJsZXMgc3RheWVkIGF0IDApLlxuICAgICAgICBhc3NlcnQuZXF1YWwobm9vcC5zYW1wbGluZy51cGxvYWRlZFRhYmxlcywgMCk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzdG9wLWFmdGVyLXJlYWNoZWQgZnJvbSBhbnkgcGhhc2Ug4oaSIGRvbmUnLCAoKSA9PiB7XG4gICAgICAgIGNvbnN0IHBoYXNlcyA9IFtcbiAgICAgICAgICAgICdjb25uZWN0aW5nLXNzaCcsXG4gICAgICAgICAgICAnY29ubmVjdGluZy1kYicsXG4gICAgICAgICAgICAnaW50cm9zcGVjdGluZycsXG4gICAgICAgICAgICAnc2FtcGxpbmcnLFxuICAgICAgICBdIGFzIGNvbnN0O1xuICAgICAgICBmb3IgKGNvbnN0IHBoYXNlIG9mIHBoYXNlcykge1xuICAgICAgICAgICAgY29uc3QgcyA9IHJlZHVjZShcbiAgICAgICAgICAgICAgICB7Li4uYmFzZUluaXQoKSwgcGhhc2V9LFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAga2luZDogJ3N0b3AtYWZ0ZXItcmVhY2hlZCcsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ2RvbmUnKTtcbiAgICAgICAgfVxuICAgIH0pO1xufSk7XG5cbi8vIOKUgOKUgCBnb2xkZW4gZmxvdyBzbmFwc2hvdHMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbmRlc2NyaWJlKCdyZWR1Y2VyOiBnb2xkZW4gZmxvd3MnLCAoKSA9PiB7XG4gICAgdGVzdCgnaGFwcHlQYXRoX2ZyZXNoUmV2aXNpb25fZnVsbCcsICgpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IGZvbGQoYmFzZUluaXQoe291dHB1dFNhbXBsZXNEaXI6ICcvdG1wL3NhbXBsZXMnfSksIFtcbiAgICAgICAgICAgIHtraW5kOiAnc3RhcnQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnZGItY29ubmVjdGVkJ30sXG4gICAgICAgICAgICB7a2luZDogJ2ludHJvc3BlY3Rpb24tbG9hZGVkJ30sXG4gICAgICAgICAgICB7a2luZDogJ3Nlc3Npb24tY3JlYXRlZCcsIHNlc3Npb25JZDogJ3Nlc3NfYSd9LFxuICAgICAgICAgICAge2tpbmQ6ICdhdXRoLWNvbmZpcm1lZCcsIHRva2VuOiAndG9rX3gnfSxcbiAgICAgICAgICAgIHtraW5kOiAnZXhwbGFuYXRpb24tZ2l2ZW4nLCB2YWx1ZTogJ2FuYWx5dGljcyd9LFxuICAgICAgICAgICAge2tpbmQ6ICdjaGVjay1pbnRyb3NwZWN0aW9uLW1pc3MnfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICBraW5kOiAnaW50cm9zcGVjdGlvbi1pbmdlc3RlZCcsXG4gICAgICAgICAgICAgICAgcmV2aXNpb25JZDogJ3Jldl9hJyxcbiAgICAgICAgICAgICAgICBzYW1wbGVzRXhpc3Q6IGZhbHNlLFxuICAgICAgICAgICAgICAgIHRhYmxlc05lZWRpbmdTYW1wbGVzOiBbXSxcbiAgICAgICAgICAgICAgICBwb3N0SW50cm9zcGVjdGlvbkpvYklkOiAncGktMScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgICAge2tpbmQ6ICdtYXNrLWxvYWRlZCcsIG1hc2s6IHt9fSxcbiAgICAgICAgICAgIHtraW5kOiAnc2FtcGxpbmctY29tcGxldGVkJ30sXG4gICAgICAgICAgICB7a2luZDogJ3NhbXBsZXMtdXBsb2FkLWNvbXBsZXRlZCd9LFxuICAgICAgICAgICAge2tpbmQ6ICdwb3N0LWludHJvc3BlY3Rpb24tY29tcGxldGVkJ30sXG4gICAgICAgICAgICB7a2luZDogJ3Bvc3Qtc2FtcGxpbmctY29tcGxldGVkJ30sXG4gICAgICAgIF0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ2RvbmUnKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucmV2aXNpb25JZCwgJ3Jldl9hJyk7XG4gICAgICAgIGFzc2VydC5lcXVhbChzLnBvc3RJbnRyb3NwZWN0aW9uLnN0YXRlLCAnZG9uZScpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnaGFwcHlQYXRoX3JldXNlZFJldmlzaW9uX3NhbXBsZXNFeGlzdCBza2lwcyBzYW1wbGluZyArIHVwbG9hZCcsICgpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IGZvbGQoYmFzZUluaXQoKSwgW1xuICAgICAgICAgICAge2tpbmQ6ICdzdGFydCd9LFxuICAgICAgICAgICAge2tpbmQ6ICdkYi1jb25uZWN0ZWQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnaW50cm9zcGVjdGlvbi1sb2FkZWQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnc2Vzc2lvbi1jcmVhdGVkJywgc2Vzc2lvbklkOiAnc2Vzc19hJ30sXG4gICAgICAgICAgICB7a2luZDogJ2F1dGgtY29uZmlybWVkJywgdG9rZW46ICd0b2tfeCd9LFxuICAgICAgICAgICAge2tpbmQ6ICdleHBsYW5hdGlvbi1naXZlbicsIHZhbHVlOiAnYW5hbHl0aWNzJ30sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAga2luZDogJ2NoZWNrLWludHJvc3BlY3Rpb24taGl0JyxcbiAgICAgICAgICAgICAgICByZXZpc2lvbklkOiAncmV2X2EnLFxuICAgICAgICAgICAgICAgIHNhbXBsZXNFeGlzdDogdHJ1ZSxcbiAgICAgICAgICAgICAgICB0YWJsZXNOZWVkaW5nU2FtcGxlczogW10sXG4gICAgICAgICAgICAgICAgcG9zdEludHJvc3BlY3Rpb25Kb2JJZDogbnVsbCxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7a2luZDogJ3Bvc3Qtc2FtcGxpbmctY29tcGxldGVkJ30sXG4gICAgICAgIF0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ2RvbmUnKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMucHJlZmxpZ2h0SGl0LCB0cnVlKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMuc2FtcGxlc0FscmVhZHlJbmdlc3RlZCwgdHJ1ZSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdzdG9wQWZ0ZXJfaW50cm9zcGVjdGlvbiBzaG9ydC1jaXJjdWl0cyBiZWZvcmUgYXV0aCcsICgpID0+IHtcbiAgICAgICAgY29uc3QgcyA9IGZvbGQoYmFzZUluaXQoe3N0b3BBZnRlcjogJ2ludHJvc3BlY3Rpb24nfSksIFtcbiAgICAgICAgICAgIHtraW5kOiAnc3RhcnQnfSxcbiAgICAgICAgICAgIHtraW5kOiAnZGItY29ubmVjdGVkJ30sXG4gICAgICAgICAgICB7a2luZDogJ2ludHJvc3BlY3Rpb24tbG9hZGVkJ30sXG4gICAgICAgIF0pO1xuICAgICAgICBhc3NlcnQuZXF1YWwocy5waGFzZSwgJ2RvbmUnKTtcbiAgICAgICAgYXNzZXJ0LmVxdWFsKHMuc2Vzc2lvbklkLCBudWxsKTtcbiAgICB9KTtcbn0pO1xuIl19
@@ -0,0 +1,3 @@
1
+ import type { TStore } from '../store.mjs';
2
+ export declare const runFlow: (store: TStore) => Promise<void>;
3
+ //# sourceMappingURL=run.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.mts","sourceRoot":"./src/","sources":["flow/run.mts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,cAAc,CAAC;AAkCzC,eAAO,MAAM,OAAO,GAAU,OAAO,MAAM,KAAG,OAAO,CAAC,IAAI,CAgEzD,CAAC"}