@okeyamy/lua 5.0.4

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.
@@ -0,0 +1,376 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
5
+ /**
6
+ * Tests for Weighted History Manager
7
+ * Tests localStorage management, exponential decay, and visit tracking
8
+ */
9
+
10
+ // Mock localStorage
11
+ var localStorageMock = function () {
12
+ var store = {};
13
+ return {
14
+ getItem: jest.fn(function (key) {
15
+ return store[key] || null;
16
+ }),
17
+ setItem: jest.fn(function (key, val) {
18
+ store[key] = String(val);
19
+ }),
20
+ removeItem: jest.fn(function (key) {
21
+ delete store[key];
22
+ }),
23
+ clear: jest.fn(function () {
24
+ store = {};
25
+ }),
26
+ get length() {
27
+ return Object.keys(store).length;
28
+ },
29
+ key: jest.fn(function (i) {
30
+ return Object.keys(store)[i] || null;
31
+ }),
32
+ _getStore: function _getStore() {
33
+ return store;
34
+ }
35
+ };
36
+ }();
37
+ Object.defineProperty(global, 'localStorage', {
38
+ value: localStorageMock
39
+ });
40
+
41
+ // Mock crypto for UUID generation
42
+ Object.defineProperty(global, 'crypto', {
43
+ value: {
44
+ getRandomValues: function getRandomValues(buf) {
45
+ for (var i = 0; i < buf.length; i++) {
46
+ buf[i] = Math.floor(Math.random() * 256);
47
+ }
48
+ return buf;
49
+ }
50
+ }
51
+ });
52
+
53
+ // Load the module (IIFE registers on global)
54
+ require('../storage/weighted-history');
55
+ var LuaWeightedHistory = global.LuaWeightedHistory;
56
+ beforeEach(function () {
57
+ localStorageMock.clear();
58
+ jest.clearAllMocks();
59
+ });
60
+ describe('LuaWeightedHistory', function () {
61
+ it('should be registered on global', function () {
62
+ expect(LuaWeightedHistory).toBeDefined();
63
+ expect((0, _typeof2.default)(LuaWeightedHistory.getHistory)).toBe('function');
64
+ expect((0, _typeof2.default)(LuaWeightedHistory.recordVisit)).toBe('function');
65
+ });
66
+ describe('generateUUID', function () {
67
+ it('should generate a valid UUID format', function () {
68
+ var uuid = LuaWeightedHistory.generateUUID();
69
+ expect(uuid).toMatch(/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/);
70
+ });
71
+ it('should generate unique UUIDs', function () {
72
+ var uuids = new Set();
73
+ for (var i = 0; i < 100; i++) {
74
+ uuids.add(LuaWeightedHistory.generateUUID());
75
+ }
76
+ expect(uuids.size).toBe(100);
77
+ });
78
+ });
79
+ describe('getHistory', function () {
80
+ it('should create a new history if none exists', function () {
81
+ var history = LuaWeightedHistory.getHistory();
82
+ expect(history).toBeDefined();
83
+ expect(history.userId).toBeDefined();
84
+ expect(Array.isArray(history.visits)).toBe(true);
85
+ expect(history.visits.length).toBe(0);
86
+ expect(history.createdAt).toBeDefined();
87
+ });
88
+ it('should return existing history', function () {
89
+ var first = LuaWeightedHistory.getHistory();
90
+ var second = LuaWeightedHistory.getHistory();
91
+ expect(first.userId).toBe(second.userId);
92
+ });
93
+ it('should persist to localStorage', function () {
94
+ LuaWeightedHistory.getHistory();
95
+ expect(localStorageMock.setItem).toHaveBeenCalledWith('lua_personalize_history', expect.any(String));
96
+ });
97
+ });
98
+ describe('recordVisit', function () {
99
+ it('should add a visit to history', function () {
100
+ var history = LuaWeightedHistory.recordVisit({
101
+ context: {
102
+ utm: {
103
+ utm_source: 'google'
104
+ },
105
+ referrer: {
106
+ source: 'google',
107
+ category: 'search'
108
+ },
109
+ userAgent: {
110
+ isMobile: false,
111
+ isTablet: false,
112
+ isDesktop: true
113
+ }
114
+ },
115
+ intent: 'search-optimized',
116
+ selectedVariant: 'search-optimized',
117
+ source: 'utm',
118
+ aiDecision: false
119
+ });
120
+ expect(history.visits.length).toBe(1);
121
+ expect(history.visits[0].intent).toBe('search-optimized');
122
+ expect(history.visits[0].source).toBe('utm');
123
+ expect(history.visits[0].aiDecision).toBe(false);
124
+ });
125
+ it('should store minimal context data', function () {
126
+ var history = LuaWeightedHistory.recordVisit({
127
+ context: {
128
+ utm: {
129
+ utm_source: 'facebook',
130
+ utm_campaign: 'gaming'
131
+ },
132
+ referrer: {
133
+ source: 'facebook',
134
+ category: 'social',
135
+ url: 'https://facebook.com/long-url'
136
+ },
137
+ userAgent: {
138
+ isMobile: true,
139
+ isTablet: false,
140
+ isDesktop: false,
141
+ raw: 'Mozilla/5.0...'
142
+ }
143
+ },
144
+ intent: 'gaming',
145
+ selectedVariant: 'gaming',
146
+ source: 'ai',
147
+ aiDecision: true
148
+ });
149
+ var visit = history.visits[0];
150
+ expect(visit.context.utm.utm_source).toBe('facebook');
151
+ expect(visit.context.referrer.source).toBe('facebook');
152
+ expect(visit.context.device).toBe('mobile');
153
+ // Should NOT store raw user agent
154
+ expect(visit.context.userAgent).toBeUndefined();
155
+ });
156
+ it('should trim history to max size', function () {
157
+ for (var i = 0; i < 15; i++) {
158
+ LuaWeightedHistory.recordVisit({
159
+ context: {},
160
+ intent: 'visit-' + i,
161
+ source: 'test'
162
+ }, {
163
+ maxHistorySize: 5
164
+ });
165
+ }
166
+ var history = LuaWeightedHistory.getHistory();
167
+ expect(history.visits.length).toBe(5);
168
+ // Should keep the most recent ones
169
+ expect(history.visits[0].intent).toBe('visit-10');
170
+ expect(history.visits[4].intent).toBe('visit-14');
171
+ });
172
+ it('should update preferences', function () {
173
+ LuaWeightedHistory.recordVisit({
174
+ context: {},
175
+ intent: 'gaming',
176
+ source: 'utm'
177
+ });
178
+ LuaWeightedHistory.recordVisit({
179
+ context: {},
180
+ intent: 'gaming',
181
+ source: 'utm'
182
+ });
183
+ LuaWeightedHistory.recordVisit({
184
+ context: {},
185
+ intent: 'professional',
186
+ source: 'utm'
187
+ });
188
+ var history = LuaWeightedHistory.getHistory();
189
+ expect(history.preferences).toBeDefined();
190
+ expect(history.preferences['gaming']).toBeGreaterThan(0);
191
+ expect(history.preferences['professional']).toBeGreaterThan(0);
192
+ });
193
+ });
194
+ describe('calculateWeight', function () {
195
+ it('should return 1.0 for current timestamp', function () {
196
+ var weight = LuaWeightedHistory.calculateWeight(Date.now());
197
+ expect(weight).toBeCloseTo(1.0, 1);
198
+ });
199
+ it('should decay over time', function () {
200
+ var oneDayAgo = Date.now() - 24 * 60 * 60 * 1000;
201
+ var weight = LuaWeightedHistory.calculateWeight(oneDayAgo, 0.9);
202
+ expect(weight).toBeCloseTo(0.9, 1);
203
+ });
204
+ it('should decay significantly over a week', function () {
205
+ var sevenDaysAgo = Date.now() - 7 * 24 * 60 * 60 * 1000;
206
+ var weight = LuaWeightedHistory.calculateWeight(sevenDaysAgo, 0.9);
207
+ expect(weight).toBeCloseTo(Math.pow(0.9, 7), 2);
208
+ expect(weight).toBeLessThan(0.5);
209
+ });
210
+ it('should use default decay rate', function () {
211
+ var oneDayAgo = Date.now() - 24 * 60 * 60 * 1000;
212
+ var weight = LuaWeightedHistory.calculateWeight(oneDayAgo);
213
+ expect(weight).toBeCloseTo(0.9, 1);
214
+ });
215
+ });
216
+ describe('buildWeightedContext', function () {
217
+ it('should return empty array for empty history', function () {
218
+ var result = LuaWeightedHistory.buildWeightedContext({
219
+ visits: []
220
+ });
221
+ expect(result).toEqual([]);
222
+ });
223
+ it('should return empty array for null history', function () {
224
+ var result = LuaWeightedHistory.buildWeightedContext(null);
225
+ expect(result).toEqual([]);
226
+ });
227
+ it('should return weighted visits sorted by weight', function () {
228
+ var now = Date.now();
229
+ var history = {
230
+ visits: [{
231
+ timestamp: now - 3 * 24 * 60 * 60 * 1000,
232
+ intent: 'old',
233
+ source: 'utm'
234
+ }, {
235
+ timestamp: now,
236
+ intent: 'new',
237
+ source: 'ai'
238
+ }, {
239
+ timestamp: now - 1 * 24 * 60 * 60 * 1000,
240
+ intent: 'mid',
241
+ source: 'referrer'
242
+ }]
243
+ };
244
+ var result = LuaWeightedHistory.buildWeightedContext(history);
245
+ expect(result[0].intent).toBe('new');
246
+ expect(result[1].intent).toBe('mid');
247
+ expect(result[2].intent).toBe('old');
248
+ expect(result[0].weight).toBeGreaterThan(result[1].weight);
249
+ expect(result[1].weight).toBeGreaterThan(result[2].weight);
250
+ });
251
+ it('should limit to maxWeighted results', function () {
252
+ var now = Date.now();
253
+ var visits = [];
254
+ for (var i = 0; i < 10; i++) {
255
+ visits.push({
256
+ timestamp: now - i * 24 * 60 * 60 * 1000,
257
+ intent: 'visit-' + i,
258
+ source: 'test'
259
+ });
260
+ }
261
+ var result = LuaWeightedHistory.buildWeightedContext({
262
+ visits: visits
263
+ }, {
264
+ maxWeighted: 3
265
+ });
266
+ expect(result.length).toBe(3);
267
+ });
268
+ });
269
+ describe('aggregatePreferences', function () {
270
+ it('should sum weights by intent', function () {
271
+ var weighted = [{
272
+ intent: 'gaming',
273
+ weight: 0.9
274
+ }, {
275
+ intent: 'gaming',
276
+ weight: 0.8
277
+ }, {
278
+ intent: 'professional',
279
+ weight: 0.7
280
+ }];
281
+ var prefs = LuaWeightedHistory.aggregatePreferences(weighted);
282
+ expect(prefs['gaming']).toBeCloseTo(1.7, 1);
283
+ expect(prefs['professional']).toBeCloseTo(0.7, 1);
284
+ });
285
+ it('should skip unknown and default intents', function () {
286
+ var weighted = [{
287
+ intent: 'unknown',
288
+ weight: 0.9
289
+ }, {
290
+ intent: 'default',
291
+ weight: 0.8
292
+ }, {
293
+ intent: 'gaming',
294
+ weight: 0.7
295
+ }];
296
+ var prefs = LuaWeightedHistory.aggregatePreferences(weighted);
297
+ expect(prefs['unknown']).toBeUndefined();
298
+ expect(prefs['default']).toBeUndefined();
299
+ expect(prefs['gaming']).toBeCloseTo(0.7, 1);
300
+ });
301
+ });
302
+ describe('formatForPrompt', function () {
303
+ it('should return new visitor message for empty history', function () {
304
+ var result = LuaWeightedHistory.formatForPrompt([]);
305
+ expect(result).toContain('new visitor');
306
+ });
307
+ it('should format visits with details', function () {
308
+ var weighted = [{
309
+ timestamp: Date.now(),
310
+ intent: 'gaming',
311
+ selectedVariant: 'gaming-promo',
312
+ source: 'utm',
313
+ weight: 0.95,
314
+ context: {
315
+ utm: {
316
+ utm_source: 'reddit'
317
+ }
318
+ }
319
+ }];
320
+ var result = LuaWeightedHistory.formatForPrompt(weighted);
321
+ expect(result).toContain('gaming');
322
+ expect(result).toContain('utm');
323
+ expect(result).toContain('0.95');
324
+ expect(result).toContain('reddit');
325
+ });
326
+ });
327
+ describe('utility functions', function () {
328
+ it('isReturningUser should return false for new users', function () {
329
+ expect(LuaWeightedHistory.isReturningUser()).toBe(false);
330
+ });
331
+ it('isReturningUser should return true after recording a visit', function () {
332
+ LuaWeightedHistory.recordVisit({
333
+ context: {},
334
+ intent: 'test',
335
+ source: 'test'
336
+ });
337
+ expect(LuaWeightedHistory.isReturningUser()).toBe(true);
338
+ });
339
+ it('getUserId should return consistent ID', function () {
340
+ var id1 = LuaWeightedHistory.getUserId();
341
+ var id2 = LuaWeightedHistory.getUserId();
342
+ expect(id1).toBe(id2);
343
+ });
344
+ it('getLastVisit should return null for empty history', function () {
345
+ expect(LuaWeightedHistory.getLastVisit()).toBeNull();
346
+ });
347
+ it('getLastVisit should return most recent visit', function () {
348
+ LuaWeightedHistory.recordVisit({
349
+ context: {},
350
+ intent: 'first',
351
+ source: 'test'
352
+ });
353
+ LuaWeightedHistory.recordVisit({
354
+ context: {},
355
+ intent: 'second',
356
+ source: 'test'
357
+ });
358
+ var last = LuaWeightedHistory.getLastVisit();
359
+ expect(last.intent).toBe('second');
360
+ });
361
+ it('clearHistory should remove all data', function () {
362
+ LuaWeightedHistory.recordVisit({
363
+ context: {},
364
+ intent: 'test',
365
+ source: 'test'
366
+ });
367
+ expect(LuaWeightedHistory.isReturningUser()).toBe(true);
368
+ LuaWeightedHistory.clearHistory();
369
+ expect(LuaWeightedHistory.isReturningUser()).toBe(false);
370
+ });
371
+ it('isLocalStorageAvailable should return true', function () {
372
+ expect(LuaWeightedHistory.isLocalStorageAvailable()).toBe(true);
373
+ });
374
+ });
375
+ });
376
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJsb2NhbFN0b3JhZ2VNb2NrIiwic3RvcmUiLCJnZXRJdGVtIiwiamVzdCIsImZuIiwia2V5Iiwic2V0SXRlbSIsInZhbCIsIlN0cmluZyIsInJlbW92ZUl0ZW0iLCJjbGVhciIsImxlbmd0aCIsIk9iamVjdCIsImtleXMiLCJpIiwiX2dldFN0b3JlIiwiZGVmaW5lUHJvcGVydHkiLCJnbG9iYWwiLCJ2YWx1ZSIsImdldFJhbmRvbVZhbHVlcyIsImJ1ZiIsIk1hdGgiLCJmbG9vciIsInJhbmRvbSIsInJlcXVpcmUiLCJMdWFXZWlnaHRlZEhpc3RvcnkiLCJiZWZvcmVFYWNoIiwiY2xlYXJBbGxNb2NrcyIsImRlc2NyaWJlIiwiaXQiLCJleHBlY3QiLCJ0b0JlRGVmaW5lZCIsIl90eXBlb2YyIiwiZGVmYXVsdCIsImdldEhpc3RvcnkiLCJ0b0JlIiwicmVjb3JkVmlzaXQiLCJ1dWlkIiwiZ2VuZXJhdGVVVUlEIiwidG9NYXRjaCIsInV1aWRzIiwiU2V0IiwiYWRkIiwic2l6ZSIsImhpc3RvcnkiLCJ1c2VySWQiLCJBcnJheSIsImlzQXJyYXkiLCJ2aXNpdHMiLCJjcmVhdGVkQXQiLCJmaXJzdCIsInNlY29uZCIsInRvSGF2ZUJlZW5DYWxsZWRXaXRoIiwiYW55IiwiY29udGV4dCIsInV0bSIsInV0bV9zb3VyY2UiLCJyZWZlcnJlciIsInNvdXJjZSIsImNhdGVnb3J5IiwidXNlckFnZW50IiwiaXNNb2JpbGUiLCJpc1RhYmxldCIsImlzRGVza3RvcCIsImludGVudCIsInNlbGVjdGVkVmFyaWFudCIsImFpRGVjaXNpb24iLCJ1dG1fY2FtcGFpZ24iLCJ1cmwiLCJyYXciLCJ2aXNpdCIsImRldmljZSIsInRvQmVVbmRlZmluZWQiLCJtYXhIaXN0b3J5U2l6ZSIsInByZWZlcmVuY2VzIiwidG9CZUdyZWF0ZXJUaGFuIiwid2VpZ2h0IiwiY2FsY3VsYXRlV2VpZ2h0IiwiRGF0ZSIsIm5vdyIsInRvQmVDbG9zZVRvIiwib25lRGF5QWdvIiwic2V2ZW5EYXlzQWdvIiwicG93IiwidG9CZUxlc3NUaGFuIiwicmVzdWx0IiwiYnVpbGRXZWlnaHRlZENvbnRleHQiLCJ0b0VxdWFsIiwidGltZXN0YW1wIiwicHVzaCIsIm1heFdlaWdodGVkIiwid2VpZ2h0ZWQiLCJwcmVmcyIsImFnZ3JlZ2F0ZVByZWZlcmVuY2VzIiwiZm9ybWF0Rm9yUHJvbXB0IiwidG9Db250YWluIiwiaXNSZXR1cm5pbmdVc2VyIiwiaWQxIiwiZ2V0VXNlcklkIiwiaWQyIiwiZ2V0TGFzdFZpc2l0IiwidG9CZU51bGwiLCJsYXN0IiwiY2xlYXJIaXN0b3J5IiwiaXNMb2NhbFN0b3JhZ2VBdmFpbGFibGUiXSwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvX190ZXN0c19fL3dlaWdodGVkLWhpc3RvcnkudGVzdC5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogVGVzdHMgZm9yIFdlaWdodGVkIEhpc3RvcnkgTWFuYWdlclxuICogVGVzdHMgbG9jYWxTdG9yYWdlIG1hbmFnZW1lbnQsIGV4cG9uZW50aWFsIGRlY2F5LCBhbmQgdmlzaXQgdHJhY2tpbmdcbiAqL1xuXG4vLyBNb2NrIGxvY2FsU3RvcmFnZVxuY29uc3QgbG9jYWxTdG9yYWdlTW9jayA9IChmdW5jdGlvbiAoKSB7XG4gICAgbGV0IHN0b3JlID0ge31cbiAgICByZXR1cm4ge1xuICAgICAgICBnZXRJdGVtOiBqZXN0LmZuKGZ1bmN0aW9uIChrZXkpIHsgcmV0dXJuIHN0b3JlW2tleV0gfHwgbnVsbCB9KSxcbiAgICAgICAgc2V0SXRlbTogamVzdC5mbihmdW5jdGlvbiAoa2V5LCB2YWwpIHsgc3RvcmVba2V5XSA9IFN0cmluZyh2YWwpIH0pLFxuICAgICAgICByZW1vdmVJdGVtOiBqZXN0LmZuKGZ1bmN0aW9uIChrZXkpIHsgZGVsZXRlIHN0b3JlW2tleV0gfSksXG4gICAgICAgIGNsZWFyOiBqZXN0LmZuKGZ1bmN0aW9uICgpIHsgc3RvcmUgPSB7fSB9KSxcbiAgICAgICAgZ2V0IGxlbmd0aCgpIHsgcmV0dXJuIE9iamVjdC5rZXlzKHN0b3JlKS5sZW5ndGggfSxcbiAgICAgICAga2V5OiBqZXN0LmZuKGZ1bmN0aW9uIChpKSB7IHJldHVybiBPYmplY3Qua2V5cyhzdG9yZSlbaV0gfHwgbnVsbCB9KSxcbiAgICAgICAgX2dldFN0b3JlOiBmdW5jdGlvbiAoKSB7IHJldHVybiBzdG9yZSB9XG4gICAgfVxufSkoKVxuXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsLCAnbG9jYWxTdG9yYWdlJywgeyB2YWx1ZTogbG9jYWxTdG9yYWdlTW9jayB9KVxuXG4vLyBNb2NrIGNyeXB0byBmb3IgVVVJRCBnZW5lcmF0aW9uXG5PYmplY3QuZGVmaW5lUHJvcGVydHkoZ2xvYmFsLCAnY3J5cHRvJywge1xuICAgIHZhbHVlOiB7XG4gICAgICAgIGdldFJhbmRvbVZhbHVlczogZnVuY3Rpb24gKGJ1Zikge1xuICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBidWYubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBidWZbaV0gPSBNYXRoLmZsb29yKE1hdGgucmFuZG9tKCkgKiAyNTYpXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gYnVmXG4gICAgICAgIH1cbiAgICB9XG59KVxuXG4vLyBMb2FkIHRoZSBtb2R1bGUgKElJRkUgcmVnaXN0ZXJzIG9uIGdsb2JhbClcbnJlcXVpcmUoJy4uL3N0b3JhZ2Uvd2VpZ2h0ZWQtaGlzdG9yeScpXG5cbmNvbnN0IEx1YVdlaWdodGVkSGlzdG9yeSA9IGdsb2JhbC5MdWFXZWlnaHRlZEhpc3RvcnlcblxuYmVmb3JlRWFjaCgoKSA9PiB7XG4gICAgbG9jYWxTdG9yYWdlTW9jay5jbGVhcigpXG4gICAgamVzdC5jbGVhckFsbE1vY2tzKClcbn0pXG5cbmRlc2NyaWJlKCdMdWFXZWlnaHRlZEhpc3RvcnknLCAoKSA9PiB7XG4gICAgaXQoJ3Nob3VsZCBiZSByZWdpc3RlcmVkIG9uIGdsb2JhbCcsICgpID0+IHtcbiAgICAgICAgZXhwZWN0KEx1YVdlaWdodGVkSGlzdG9yeSkudG9CZURlZmluZWQoKVxuICAgICAgICBleHBlY3QodHlwZW9mIEx1YVdlaWdodGVkSGlzdG9yeS5nZXRIaXN0b3J5KS50b0JlKCdmdW5jdGlvbicpXG4gICAgICAgIGV4cGVjdCh0eXBlb2YgTHVhV2VpZ2h0ZWRIaXN0b3J5LnJlY29yZFZpc2l0KS50b0JlKCdmdW5jdGlvbicpXG4gICAgfSlcblxuICAgIGRlc2NyaWJlKCdnZW5lcmF0ZVVVSUQnLCAoKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgYSB2YWxpZCBVVUlEIGZvcm1hdCcsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHV1aWQgPSBMdWFXZWlnaHRlZEhpc3RvcnkuZ2VuZXJhdGVVVUlEKClcbiAgICAgICAgICAgIGV4cGVjdCh1dWlkKS50b01hdGNoKC9eWzAtOWEtZl17OH0tWzAtOWEtZl17NH0tNFswLTlhLWZdezN9LVs4OWFiXVswLTlhLWZdezN9LVswLTlhLWZdezEyfSQvKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgZ2VuZXJhdGUgdW5pcXVlIFVVSURzJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgdXVpZHMgPSBuZXcgU2V0KClcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMTAwOyBpKyspIHtcbiAgICAgICAgICAgICAgICB1dWlkcy5hZGQoTHVhV2VpZ2h0ZWRIaXN0b3J5LmdlbmVyYXRlVVVJRCgpKVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZXhwZWN0KHV1aWRzLnNpemUpLnRvQmUoMTAwKVxuICAgICAgICB9KVxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnZ2V0SGlzdG9yeScsICgpID0+IHtcbiAgICAgICAgaXQoJ3Nob3VsZCBjcmVhdGUgYSBuZXcgaGlzdG9yeSBpZiBub25lIGV4aXN0cycsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGhpc3RvcnkgPSBMdWFXZWlnaHRlZEhpc3RvcnkuZ2V0SGlzdG9yeSgpXG4gICAgICAgICAgICBleHBlY3QoaGlzdG9yeSkudG9CZURlZmluZWQoKVxuICAgICAgICAgICAgZXhwZWN0KGhpc3RvcnkudXNlcklkKS50b0JlRGVmaW5lZCgpXG4gICAgICAgICAgICBleHBlY3QoQXJyYXkuaXNBcnJheShoaXN0b3J5LnZpc2l0cykpLnRvQmUodHJ1ZSlcbiAgICAgICAgICAgIGV4cGVjdChoaXN0b3J5LnZpc2l0cy5sZW5ndGgpLnRvQmUoMClcbiAgICAgICAgICAgIGV4cGVjdChoaXN0b3J5LmNyZWF0ZWRBdCkudG9CZURlZmluZWQoKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGV4aXN0aW5nIGhpc3RvcnknLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBmaXJzdCA9IEx1YVdlaWdodGVkSGlzdG9yeS5nZXRIaXN0b3J5KClcbiAgICAgICAgICAgIGNvbnN0IHNlY29uZCA9IEx1YVdlaWdodGVkSGlzdG9yeS5nZXRIaXN0b3J5KClcbiAgICAgICAgICAgIGV4cGVjdChmaXJzdC51c2VySWQpLnRvQmUoc2Vjb25kLnVzZXJJZClcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIHBlcnNpc3QgdG8gbG9jYWxTdG9yYWdlJywgKCkgPT4ge1xuICAgICAgICAgICAgTHVhV2VpZ2h0ZWRIaXN0b3J5LmdldEhpc3RvcnkoKVxuICAgICAgICAgICAgZXhwZWN0KGxvY2FsU3RvcmFnZU1vY2suc2V0SXRlbSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoXG4gICAgICAgICAgICAgICAgJ2x1YV9wZXJzb25hbGl6ZV9oaXN0b3J5JyxcbiAgICAgICAgICAgICAgICBleHBlY3QuYW55KFN0cmluZylcbiAgICAgICAgICAgIClcbiAgICAgICAgfSlcbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ3JlY29yZFZpc2l0JywgKCkgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIGFkZCBhIHZpc2l0IHRvIGhpc3RvcnknLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBoaXN0b3J5ID0gTHVhV2VpZ2h0ZWRIaXN0b3J5LnJlY29yZFZpc2l0KHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB7XG4gICAgICAgICAgICAgICAgICAgIHV0bTogeyB1dG1fc291cmNlOiAnZ29vZ2xlJyB9LFxuICAgICAgICAgICAgICAgICAgICByZWZlcnJlcjogeyBzb3VyY2U6ICdnb29nbGUnLCBjYXRlZ29yeTogJ3NlYXJjaCcgfSxcbiAgICAgICAgICAgICAgICAgICAgdXNlckFnZW50OiB7IGlzTW9iaWxlOiBmYWxzZSwgaXNUYWJsZXQ6IGZhbHNlLCBpc0Rlc2t0b3A6IHRydWUgfVxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgaW50ZW50OiAnc2VhcmNoLW9wdGltaXplZCcsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRWYXJpYW50OiAnc2VhcmNoLW9wdGltaXplZCcsXG4gICAgICAgICAgICAgICAgc291cmNlOiAndXRtJyxcbiAgICAgICAgICAgICAgICBhaURlY2lzaW9uOiBmYWxzZVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgZXhwZWN0KGhpc3RvcnkudmlzaXRzLmxlbmd0aCkudG9CZSgxKVxuICAgICAgICAgICAgZXhwZWN0KGhpc3RvcnkudmlzaXRzWzBdLmludGVudCkudG9CZSgnc2VhcmNoLW9wdGltaXplZCcpXG4gICAgICAgICAgICBleHBlY3QoaGlzdG9yeS52aXNpdHNbMF0uc291cmNlKS50b0JlKCd1dG0nKVxuICAgICAgICAgICAgZXhwZWN0KGhpc3RvcnkudmlzaXRzWzBdLmFpRGVjaXNpb24pLnRvQmUoZmFsc2UpXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3Nob3VsZCBzdG9yZSBtaW5pbWFsIGNvbnRleHQgZGF0YScsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGhpc3RvcnkgPSBMdWFXZWlnaHRlZEhpc3RvcnkucmVjb3JkVmlzaXQoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHtcbiAgICAgICAgICAgICAgICAgICAgdXRtOiB7IHV0bV9zb3VyY2U6ICdmYWNlYm9vaycsIHV0bV9jYW1wYWlnbjogJ2dhbWluZycgfSxcbiAgICAgICAgICAgICAgICAgICAgcmVmZXJyZXI6IHsgc291cmNlOiAnZmFjZWJvb2snLCBjYXRlZ29yeTogJ3NvY2lhbCcsIHVybDogJ2h0dHBzOi8vZmFjZWJvb2suY29tL2xvbmctdXJsJyB9LFxuICAgICAgICAgICAgICAgICAgICB1c2VyQWdlbnQ6IHsgaXNNb2JpbGU6IHRydWUsIGlzVGFibGV0OiBmYWxzZSwgaXNEZXNrdG9wOiBmYWxzZSwgcmF3OiAnTW96aWxsYS81LjAuLi4nIH1cbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgIGludGVudDogJ2dhbWluZycsXG4gICAgICAgICAgICAgICAgc2VsZWN0ZWRWYXJpYW50OiAnZ2FtaW5nJyxcbiAgICAgICAgICAgICAgICBzb3VyY2U6ICdhaScsXG4gICAgICAgICAgICAgICAgYWlEZWNpc2lvbjogdHJ1ZVxuICAgICAgICAgICAgfSlcblxuICAgICAgICAgICAgY29uc3QgdmlzaXQgPSBoaXN0b3J5LnZpc2l0c1swXVxuICAgICAgICAgICAgZXhwZWN0KHZpc2l0LmNvbnRleHQudXRtLnV0bV9zb3VyY2UpLnRvQmUoJ2ZhY2Vib29rJylcbiAgICAgICAgICAgIGV4cGVjdCh2aXNpdC5jb250ZXh0LnJlZmVycmVyLnNvdXJjZSkudG9CZSgnZmFjZWJvb2snKVxuICAgICAgICAgICAgZXhwZWN0KHZpc2l0LmNvbnRleHQuZGV2aWNlKS50b0JlKCdtb2JpbGUnKVxuICAgICAgICAgICAgLy8gU2hvdWxkIE5PVCBzdG9yZSByYXcgdXNlciBhZ2VudFxuICAgICAgICAgICAgZXhwZWN0KHZpc2l0LmNvbnRleHQudXNlckFnZW50KS50b0JlVW5kZWZpbmVkKClcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIHRyaW0gaGlzdG9yeSB0byBtYXggc2l6ZScsICgpID0+IHtcbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMTU7IGkrKykge1xuICAgICAgICAgICAgICAgIEx1YVdlaWdodGVkSGlzdG9yeS5yZWNvcmRWaXNpdCh7XG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6IHt9LFxuICAgICAgICAgICAgICAgICAgICBpbnRlbnQ6ICd2aXNpdC0nICsgaSxcbiAgICAgICAgICAgICAgICAgICAgc291cmNlOiAndGVzdCdcbiAgICAgICAgICAgICAgICB9LCB7IG1heEhpc3RvcnlTaXplOiA1IH0pXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGNvbnN0IGhpc3RvcnkgPSBMdWFXZWlnaHRlZEhpc3RvcnkuZ2V0SGlzdG9yeSgpXG4gICAgICAgICAgICBleHBlY3QoaGlzdG9yeS52aXNpdHMubGVuZ3RoKS50b0JlKDUpXG4gICAgICAgICAgICAvLyBTaG91bGQga2VlcCB0aGUgbW9zdCByZWNlbnQgb25lc1xuICAgICAgICAgICAgZXhwZWN0KGhpc3RvcnkudmlzaXRzWzBdLmludGVudCkudG9CZSgndmlzaXQtMTAnKVxuICAgICAgICAgICAgZXhwZWN0KGhpc3RvcnkudmlzaXRzWzRdLmludGVudCkudG9CZSgndmlzaXQtMTQnKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgdXBkYXRlIHByZWZlcmVuY2VzJywgKCkgPT4ge1xuICAgICAgICAgICAgTHVhV2VpZ2h0ZWRIaXN0b3J5LnJlY29yZFZpc2l0KHtcbiAgICAgICAgICAgICAgICBjb250ZXh0OiB7fSxcbiAgICAgICAgICAgICAgICBpbnRlbnQ6ICdnYW1pbmcnLFxuICAgICAgICAgICAgICAgIHNvdXJjZTogJ3V0bSdcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBMdWFXZWlnaHRlZEhpc3RvcnkucmVjb3JkVmlzaXQoe1xuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHt9LFxuICAgICAgICAgICAgICAgIGludGVudDogJ2dhbWluZycsXG4gICAgICAgICAgICAgICAgc291cmNlOiAndXRtJ1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIEx1YVdlaWdodGVkSGlzdG9yeS5yZWNvcmRWaXNpdCh7XG4gICAgICAgICAgICAgICAgY29udGV4dDoge30sXG4gICAgICAgICAgICAgICAgaW50ZW50OiAncHJvZmVzc2lvbmFsJyxcbiAgICAgICAgICAgICAgICBzb3VyY2U6ICd1dG0nXG4gICAgICAgICAgICB9KVxuXG4gICAgICAgICAgICBjb25zdCBoaXN0b3J5ID0gTHVhV2VpZ2h0ZWRIaXN0b3J5LmdldEhpc3RvcnkoKVxuICAgICAgICAgICAgZXhwZWN0KGhpc3RvcnkucHJlZmVyZW5jZXMpLnRvQmVEZWZpbmVkKClcbiAgICAgICAgICAgIGV4cGVjdChoaXN0b3J5LnByZWZlcmVuY2VzWydnYW1pbmcnXSkudG9CZUdyZWF0ZXJUaGFuKDApXG4gICAgICAgICAgICBleHBlY3QoaGlzdG9yeS5wcmVmZXJlbmNlc1sncHJvZmVzc2lvbmFsJ10pLnRvQmVHcmVhdGVyVGhhbigwKVxuICAgICAgICB9KVxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnY2FsY3VsYXRlV2VpZ2h0JywgKCkgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiAxLjAgZm9yIGN1cnJlbnQgdGltZXN0YW1wJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgd2VpZ2h0ID0gTHVhV2VpZ2h0ZWRIaXN0b3J5LmNhbGN1bGF0ZVdlaWdodChEYXRlLm5vdygpKVxuICAgICAgICAgICAgZXhwZWN0KHdlaWdodCkudG9CZUNsb3NlVG8oMS4wLCAxKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgZGVjYXkgb3ZlciB0aW1lJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgb25lRGF5QWdvID0gRGF0ZS5ub3coKSAtICgyNCAqIDYwICogNjAgKiAxMDAwKVxuICAgICAgICAgICAgY29uc3Qgd2VpZ2h0ID0gTHVhV2VpZ2h0ZWRIaXN0b3J5LmNhbGN1bGF0ZVdlaWdodChvbmVEYXlBZ28sIDAuOSlcbiAgICAgICAgICAgIGV4cGVjdCh3ZWlnaHQpLnRvQmVDbG9zZVRvKDAuOSwgMSlcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIGRlY2F5IHNpZ25pZmljYW50bHkgb3ZlciBhIHdlZWsnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzZXZlbkRheXNBZ28gPSBEYXRlLm5vdygpIC0gKDcgKiAyNCAqIDYwICogNjAgKiAxMDAwKVxuICAgICAgICAgICAgY29uc3Qgd2VpZ2h0ID0gTHVhV2VpZ2h0ZWRIaXN0b3J5LmNhbGN1bGF0ZVdlaWdodChzZXZlbkRheXNBZ28sIDAuOSlcbiAgICAgICAgICAgIGV4cGVjdCh3ZWlnaHQpLnRvQmVDbG9zZVRvKE1hdGgucG93KDAuOSwgNyksIDIpXG4gICAgICAgICAgICBleHBlY3Qod2VpZ2h0KS50b0JlTGVzc1RoYW4oMC41KVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgdXNlIGRlZmF1bHQgZGVjYXkgcmF0ZScsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IG9uZURheUFnbyA9IERhdGUubm93KCkgLSAoMjQgKiA2MCAqIDYwICogMTAwMClcbiAgICAgICAgICAgIGNvbnN0IHdlaWdodCA9IEx1YVdlaWdodGVkSGlzdG9yeS5jYWxjdWxhdGVXZWlnaHQob25lRGF5QWdvKVxuICAgICAgICAgICAgZXhwZWN0KHdlaWdodCkudG9CZUNsb3NlVG8oMC45LCAxKVxuICAgICAgICB9KVxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnYnVpbGRXZWlnaHRlZENvbnRleHQnLCAoKSA9PiB7XG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIGVtcHR5IGFycmF5IGZvciBlbXB0eSBoaXN0b3J5JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gTHVhV2VpZ2h0ZWRIaXN0b3J5LmJ1aWxkV2VpZ2h0ZWRDb250ZXh0KHsgdmlzaXRzOiBbXSB9KVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG9FcXVhbChbXSlcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBlbXB0eSBhcnJheSBmb3IgbnVsbCBoaXN0b3J5JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gTHVhV2VpZ2h0ZWRIaXN0b3J5LmJ1aWxkV2VpZ2h0ZWRDb250ZXh0KG51bGwpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50b0VxdWFsKFtdKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgcmV0dXJuIHdlaWdodGVkIHZpc2l0cyBzb3J0ZWQgYnkgd2VpZ2h0JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKVxuICAgICAgICAgICAgY29uc3QgaGlzdG9yeSA9IHtcbiAgICAgICAgICAgICAgICB2aXNpdHM6IFtcbiAgICAgICAgICAgICAgICAgICAgeyB0aW1lc3RhbXA6IG5vdyAtICgzICogMjQgKiA2MCAqIDYwICogMTAwMCksIGludGVudDogJ29sZCcsIHNvdXJjZTogJ3V0bScgfSxcbiAgICAgICAgICAgICAgICAgICAgeyB0aW1lc3RhbXA6IG5vdywgaW50ZW50OiAnbmV3Jywgc291cmNlOiAnYWknIH0sXG4gICAgICAgICAgICAgICAgICAgIHsgdGltZXN0YW1wOiBub3cgLSAoMSAqIDI0ICogNjAgKiA2MCAqIDEwMDApLCBpbnRlbnQ6ICdtaWQnLCBzb3VyY2U6ICdyZWZlcnJlcicgfVxuICAgICAgICAgICAgICAgIF1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gTHVhV2VpZ2h0ZWRIaXN0b3J5LmJ1aWxkV2VpZ2h0ZWRDb250ZXh0KGhpc3RvcnkpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WzBdLmludGVudCkudG9CZSgnbmV3JylcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHRbMV0uaW50ZW50KS50b0JlKCdtaWQnKVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdFsyXS5pbnRlbnQpLnRvQmUoJ29sZCcpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WzBdLndlaWdodCkudG9CZUdyZWF0ZXJUaGFuKHJlc3VsdFsxXS53ZWlnaHQpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0WzFdLndlaWdodCkudG9CZUdyZWF0ZXJUaGFuKHJlc3VsdFsyXS53ZWlnaHQpXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ3Nob3VsZCBsaW1pdCB0byBtYXhXZWlnaHRlZCByZXN1bHRzJywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKVxuICAgICAgICAgICAgY29uc3QgdmlzaXRzID0gW11cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgMTA7IGkrKykge1xuICAgICAgICAgICAgICAgIHZpc2l0cy5wdXNoKHtcbiAgICAgICAgICAgICAgICAgICAgdGltZXN0YW1wOiBub3cgLSAoaSAqIDI0ICogNjAgKiA2MCAqIDEwMDApLFxuICAgICAgICAgICAgICAgICAgICBpbnRlbnQ6ICd2aXNpdC0nICsgaSxcbiAgICAgICAgICAgICAgICAgICAgc291cmNlOiAndGVzdCdcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSBMdWFXZWlnaHRlZEhpc3RvcnkuYnVpbGRXZWlnaHRlZENvbnRleHQoXG4gICAgICAgICAgICAgICAgeyB2aXNpdHM6IHZpc2l0cyB9LFxuICAgICAgICAgICAgICAgIHsgbWF4V2VpZ2h0ZWQ6IDMgfVxuICAgICAgICAgICAgKVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdC5sZW5ndGgpLnRvQmUoMylcbiAgICAgICAgfSlcbiAgICB9KVxuXG4gICAgZGVzY3JpYmUoJ2FnZ3JlZ2F0ZVByZWZlcmVuY2VzJywgKCkgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIHN1bSB3ZWlnaHRzIGJ5IGludGVudCcsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHdlaWdodGVkID0gW1xuICAgICAgICAgICAgICAgIHsgaW50ZW50OiAnZ2FtaW5nJywgd2VpZ2h0OiAwLjkgfSxcbiAgICAgICAgICAgICAgICB7IGludGVudDogJ2dhbWluZycsIHdlaWdodDogMC44IH0sXG4gICAgICAgICAgICAgICAgeyBpbnRlbnQ6ICdwcm9mZXNzaW9uYWwnLCB3ZWlnaHQ6IDAuNyB9XG4gICAgICAgICAgICBdXG5cbiAgICAgICAgICAgIGNvbnN0IHByZWZzID0gTHVhV2VpZ2h0ZWRIaXN0b3J5LmFnZ3JlZ2F0ZVByZWZlcmVuY2VzKHdlaWdodGVkKVxuICAgICAgICAgICAgZXhwZWN0KHByZWZzWydnYW1pbmcnXSkudG9CZUNsb3NlVG8oMS43LCAxKVxuICAgICAgICAgICAgZXhwZWN0KHByZWZzWydwcm9mZXNzaW9uYWwnXSkudG9CZUNsb3NlVG8oMC43LCAxKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgc2tpcCB1bmtub3duIGFuZCBkZWZhdWx0IGludGVudHMnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB3ZWlnaHRlZCA9IFtcbiAgICAgICAgICAgICAgICB7IGludGVudDogJ3Vua25vd24nLCB3ZWlnaHQ6IDAuOSB9LFxuICAgICAgICAgICAgICAgIHsgaW50ZW50OiAnZGVmYXVsdCcsIHdlaWdodDogMC44IH0sXG4gICAgICAgICAgICAgICAgeyBpbnRlbnQ6ICdnYW1pbmcnLCB3ZWlnaHQ6IDAuNyB9XG4gICAgICAgICAgICBdXG5cbiAgICAgICAgICAgIGNvbnN0IHByZWZzID0gTHVhV2VpZ2h0ZWRIaXN0b3J5LmFnZ3JlZ2F0ZVByZWZlcmVuY2VzKHdlaWdodGVkKVxuICAgICAgICAgICAgZXhwZWN0KHByZWZzWyd1bmtub3duJ10pLnRvQmVVbmRlZmluZWQoKVxuICAgICAgICAgICAgZXhwZWN0KHByZWZzWydkZWZhdWx0J10pLnRvQmVVbmRlZmluZWQoKVxuICAgICAgICAgICAgZXhwZWN0KHByZWZzWydnYW1pbmcnXSkudG9CZUNsb3NlVG8oMC43LCAxKVxuICAgICAgICB9KVxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgnZm9ybWF0Rm9yUHJvbXB0JywgKCkgPT4ge1xuICAgICAgICBpdCgnc2hvdWxkIHJldHVybiBuZXcgdmlzaXRvciBtZXNzYWdlIGZvciBlbXB0eSBoaXN0b3J5JywgKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gTHVhV2VpZ2h0ZWRIaXN0b3J5LmZvcm1hdEZvclByb21wdChbXSlcbiAgICAgICAgICAgIGV4cGVjdChyZXN1bHQpLnRvQ29udGFpbignbmV3IHZpc2l0b3InKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdzaG91bGQgZm9ybWF0IHZpc2l0cyB3aXRoIGRldGFpbHMnLCAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCB3ZWlnaHRlZCA9IFtcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgICAgICAgaW50ZW50OiAnZ2FtaW5nJyxcbiAgICAgICAgICAgICAgICAgICAgc2VsZWN0ZWRWYXJpYW50OiAnZ2FtaW5nLXByb21vJyxcbiAgICAgICAgICAgICAgICAgICAgc291cmNlOiAndXRtJyxcbiAgICAgICAgICAgICAgICAgICAgd2VpZ2h0OiAwLjk1LFxuICAgICAgICAgICAgICAgICAgICBjb250ZXh0OiB7IHV0bTogeyB1dG1fc291cmNlOiAncmVkZGl0JyB9IH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICBdXG5cbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IEx1YVdlaWdodGVkSGlzdG9yeS5mb3JtYXRGb3JQcm9tcHQod2VpZ2h0ZWQpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oJ2dhbWluZycpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oJ3V0bScpXG4gICAgICAgICAgICBleHBlY3QocmVzdWx0KS50b0NvbnRhaW4oJzAuOTUnKVxuICAgICAgICAgICAgZXhwZWN0KHJlc3VsdCkudG9Db250YWluKCdyZWRkaXQnKVxuICAgICAgICB9KVxuICAgIH0pXG5cbiAgICBkZXNjcmliZSgndXRpbGl0eSBmdW5jdGlvbnMnLCAoKSA9PiB7XG4gICAgICAgIGl0KCdpc1JldHVybmluZ1VzZXIgc2hvdWxkIHJldHVybiBmYWxzZSBmb3IgbmV3IHVzZXJzJywgKCkgPT4ge1xuICAgICAgICAgICAgZXhwZWN0KEx1YVdlaWdodGVkSGlzdG9yeS5pc1JldHVybmluZ1VzZXIoKSkudG9CZShmYWxzZSlcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnaXNSZXR1cm5pbmdVc2VyIHNob3VsZCByZXR1cm4gdHJ1ZSBhZnRlciByZWNvcmRpbmcgYSB2aXNpdCcsICgpID0+IHtcbiAgICAgICAgICAgIEx1YVdlaWdodGVkSGlzdG9yeS5yZWNvcmRWaXNpdCh7IGNvbnRleHQ6IHt9LCBpbnRlbnQ6ICd0ZXN0Jywgc291cmNlOiAndGVzdCcgfSlcbiAgICAgICAgICAgIGV4cGVjdChMdWFXZWlnaHRlZEhpc3RvcnkuaXNSZXR1cm5pbmdVc2VyKCkpLnRvQmUodHJ1ZSlcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnZ2V0VXNlcklkIHNob3VsZCByZXR1cm4gY29uc2lzdGVudCBJRCcsICgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGlkMSA9IEx1YVdlaWdodGVkSGlzdG9yeS5nZXRVc2VySWQoKVxuICAgICAgICAgICAgY29uc3QgaWQyID0gTHVhV2VpZ2h0ZWRIaXN0b3J5LmdldFVzZXJJZCgpXG4gICAgICAgICAgICBleHBlY3QoaWQxKS50b0JlKGlkMilcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnZ2V0TGFzdFZpc2l0IHNob3VsZCByZXR1cm4gbnVsbCBmb3IgZW1wdHkgaGlzdG9yeScsICgpID0+IHtcbiAgICAgICAgICAgIGV4cGVjdChMdWFXZWlnaHRlZEhpc3RvcnkuZ2V0TGFzdFZpc2l0KCkpLnRvQmVOdWxsKClcbiAgICAgICAgfSlcblxuICAgICAgICBpdCgnZ2V0TGFzdFZpc2l0IHNob3VsZCByZXR1cm4gbW9zdCByZWNlbnQgdmlzaXQnLCAoKSA9PiB7XG4gICAgICAgICAgICBMdWFXZWlnaHRlZEhpc3RvcnkucmVjb3JkVmlzaXQoeyBjb250ZXh0OiB7fSwgaW50ZW50OiAnZmlyc3QnLCBzb3VyY2U6ICd0ZXN0JyB9KVxuICAgICAgICAgICAgTHVhV2VpZ2h0ZWRIaXN0b3J5LnJlY29yZFZpc2l0KHsgY29udGV4dDoge30sIGludGVudDogJ3NlY29uZCcsIHNvdXJjZTogJ3Rlc3QnIH0pXG4gICAgICAgICAgICBjb25zdCBsYXN0ID0gTHVhV2VpZ2h0ZWRIaXN0b3J5LmdldExhc3RWaXNpdCgpXG4gICAgICAgICAgICBleHBlY3QobGFzdC5pbnRlbnQpLnRvQmUoJ3NlY29uZCcpXG4gICAgICAgIH0pXG5cbiAgICAgICAgaXQoJ2NsZWFySGlzdG9yeSBzaG91bGQgcmVtb3ZlIGFsbCBkYXRhJywgKCkgPT4ge1xuICAgICAgICAgICAgTHVhV2VpZ2h0ZWRIaXN0b3J5LnJlY29yZFZpc2l0KHsgY29udGV4dDoge30sIGludGVudDogJ3Rlc3QnLCBzb3VyY2U6ICd0ZXN0JyB9KVxuICAgICAgICAgICAgZXhwZWN0KEx1YVdlaWdodGVkSGlzdG9yeS5pc1JldHVybmluZ1VzZXIoKSkudG9CZSh0cnVlKVxuICAgICAgICAgICAgTHVhV2VpZ2h0ZWRIaXN0b3J5LmNsZWFySGlzdG9yeSgpXG4gICAgICAgICAgICBleHBlY3QoTHVhV2VpZ2h0ZWRIaXN0b3J5LmlzUmV0dXJuaW5nVXNlcigpKS50b0JlKGZhbHNlKVxuICAgICAgICB9KVxuXG4gICAgICAgIGl0KCdpc0xvY2FsU3RvcmFnZUF2YWlsYWJsZSBzaG91bGQgcmV0dXJuIHRydWUnLCAoKSA9PiB7XG4gICAgICAgICAgICBleHBlY3QoTHVhV2VpZ2h0ZWRIaXN0b3J5LmlzTG9jYWxTdG9yYWdlQXZhaWxhYmxlKCkpLnRvQmUodHJ1ZSlcbiAgICAgICAgfSlcbiAgICB9KVxufSlcbiJdLCJtYXBw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QUFHLENBQUM7SUFDekIsQ0FBQyxDQUFDO0lBRUZ0RSxFQUFFLENBQUMsbURBQW1ELEVBQUUsWUFBTTtNQUMxREMsTUFBTSxDQUFDTCxrQkFBa0IsQ0FBQzJFLFlBQVksQ0FBQyxDQUFDLENBQUMsQ0FBQ0MsUUFBUSxDQUFDLENBQUM7SUFDeEQsQ0FBQyxDQUFDO0lBRUZ4RSxFQUFFLENBQUMsOENBQThDLEVBQUUsWUFBTTtNQUNyREosa0JBQWtCLENBQUNXLFdBQVcsQ0FBQztRQUFFa0IsT0FBTyxFQUFFLENBQUMsQ0FBQztRQUFFVSxNQUFNLEVBQUUsT0FBTztRQUFFTixNQUFNLEVBQUU7TUFBTyxDQUFDLENBQUM7TUFDaEZqQyxrQkFBa0IsQ0FBQ1csV0FBVyxDQUFDO1FBQUVrQixPQUFPLEVBQUUsQ0FBQyxDQUFDO1FBQUVVLE1BQU0sRUFBRSxRQUFRO1FBQUVOLE1BQU0sRUFBRTtNQUFPLENBQUMsQ0FBQztNQUNqRixJQUFNNEMsSUFBSSxHQUFHN0Usa0JBQWtCLENBQUMyRSxZQUFZLENBQUMsQ0FBQztNQUM5Q3RFLE1BQU0sQ0FBQ3dFLElBQUksQ0FBQ3RDLE1BQU0sQ0FBQyxDQUFDN0IsSUFBSSxDQUFDLFFBQVEsQ0FBQztJQUN0QyxDQUFDLENBQUM7SUFFRk4sRUFBRSxDQUFDLHFDQUFxQyxFQUFFLFlBQU07TUFDNUNKLGtCQUFrQixDQUFDVyxXQUFXLENBQUM7UUFBRWtCLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFBRVUsTUFBTSxFQUFFLE1BQU07UUFBRU4sTUFBTSxFQUFFO01BQU8sQ0FBQyxDQUFDO01BQy9FNUIsTUFBTSxDQUFDTCxrQkFBa0IsQ0FBQ3VFLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQzdELElBQUksQ0FBQyxJQUFJLENBQUM7TUFDdkRWLGtCQUFrQixDQUFDOEUsWUFBWSxDQUFDLENBQUM7TUFDakN6RSxNQUFNLENBQUNMLGtCQUFrQixDQUFDdUUsZUFBZSxDQUFDLENBQUMsQ0FBQyxDQUFDN0QsSUFBSSxDQUFDLEtBQUssQ0FBQztJQUM1RCxDQUFDLENBQUM7SUFFRk4sRUFBRSxDQUFDLDRDQUE0QyxFQUFFLFlBQU07TUFDbkRDLE1BQU0sQ0FBQ0wsa0JBQWtCLENBQUMrRSx1QkFBdUIsQ0FBQyxDQUFDLENBQUMsQ0FBQ3JFLElBQUksQ0FBQyxJQUFJLENBQUM7SUFDbkUsQ0FBQyxDQUFDO0VBQ04sQ0FBQyxDQUFDO0FBQ04sQ0FBQyxDQUFDIiwiaWdub3JlTGlzdCI6W119