@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,817 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
5
+ /**
6
+ * Lua UTM Personalization - Standalone Bundle
7
+ * ============================================
8
+ * Self-contained script combining:
9
+ * - URLSearchParams-based UTM extraction
10
+ * - Referrer & user agent detection
11
+ * - Intent inference engine
12
+ * - DOMPurify-style HTML sanitizer
13
+ * - DOM personalization via data-personalize attributes
14
+ * - Random A/B test fallback when no UTM params present
15
+ *
16
+ * Usage:
17
+ * <script src="utm-personalize.js" defer></script>
18
+ *
19
+ * <!-- Then in your HTML use data-personalize attributes: -->
20
+ * <div data-personalize="hero">
21
+ * <h1 data-personalize="headline">Default Headline</h1>
22
+ * <p data-personalize="subheadline">Default subheadline</p>
23
+ * <a href="#" data-personalize="ctaLink">
24
+ * <span data-personalize="ctaLabel">Default CTA</span>
25
+ * </a>
26
+ * </div>
27
+ *
28
+ * The script auto-initializes on DOMContentLoaded.
29
+ * Access the API via window.LuaUTMPersonalize
30
+ *
31
+ * Size target: < 50KB
32
+ * No imports. No dependencies. No build step required.
33
+ */
34
+ ;
35
+ (function (root) {
36
+ 'use strict';
37
+
38
+ // ===================================================================
39
+ // 1. UTM PARAMETER EXTRACTION (URLSearchParams API)
40
+ // ===================================================================
41
+ var UTM_TIMEOUT_MS = 1000;
42
+ var UTM_PARAMS = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
43
+ var REFERRER_PATTERNS = {
44
+ google: /google\./i,
45
+ bing: /bing\./i,
46
+ yahoo: /yahoo\./i,
47
+ duckduckgo: /duckduckgo\./i,
48
+ facebook: /facebook\.com|fb\.com/i,
49
+ twitter: /twitter\.com|t\.co|x\.com/i,
50
+ instagram: /instagram\.com/i,
51
+ linkedin: /linkedin\.com/i,
52
+ pinterest: /pinterest\./i,
53
+ tiktok: /tiktok\.com/i,
54
+ youtube: /youtube\.com|youtu\.be/i,
55
+ reddit: /reddit\.com/i
56
+ };
57
+ var REFERRER_CATEGORIES = {
58
+ search: ['google', 'bing', 'yahoo', 'duckduckgo'],
59
+ social: ['facebook', 'twitter', 'instagram', 'linkedin', 'pinterest', 'tiktok', 'youtube', 'reddit']
60
+ };
61
+
62
+ /**
63
+ * Sanitize a UTM parameter value to prevent XSS
64
+ * @param {string} value - Raw parameter value
65
+ * @returns {string} - Sanitized value
66
+ */
67
+ function sanitizeParam(value) {
68
+ if (typeof value !== 'string') return '';
69
+ return value.replace(/<[^>]*>/g, '').replace(/[^\w\s\-_.]/g, '').substring(0, 100).trim();
70
+ }
71
+
72
+ /**
73
+ * Extract UTM parameters from URL using native URLSearchParams API
74
+ * @param {string} [url] - URL search string (defaults to window.location.search)
75
+ * @returns {Object} - Object containing UTM parameters
76
+ */
77
+ function extractUTMParams(url) {
78
+ var result = {};
79
+ try {
80
+ var searchString = url || (typeof root.location !== 'undefined' ? root.location.search : '');
81
+ if (!searchString) return result;
82
+ var params = new URLSearchParams(searchString);
83
+ UTM_PARAMS.forEach(function (param) {
84
+ var value = params.get(param);
85
+ if (value) {
86
+ result[param] = sanitizeParam(value);
87
+ }
88
+ });
89
+ } catch (e) {
90
+ console.warn('[Lua UTM] Error extracting UTM params:', e);
91
+ }
92
+ return result;
93
+ }
94
+
95
+ /**
96
+ * Detect referrer type from document.referrer
97
+ * @returns {Object} - { source, category, url }
98
+ */
99
+ function detectReferrer() {
100
+ var result = {
101
+ source: 'direct',
102
+ category: 'direct',
103
+ url: ''
104
+ };
105
+ try {
106
+ if (typeof document === 'undefined' || !document.referrer) return result;
107
+ result.url = document.referrer;
108
+ if (/mail\.|email\.|newsletter/i.test(document.referrer)) {
109
+ result.source = 'email';
110
+ result.category = 'email';
111
+ return result;
112
+ }
113
+ for (var source in REFERRER_PATTERNS) {
114
+ if (REFERRER_PATTERNS[source].test(document.referrer)) {
115
+ result.source = source;
116
+ for (var category in REFERRER_CATEGORIES) {
117
+ if (REFERRER_CATEGORIES[category].indexOf(source) !== -1) {
118
+ result.category = category;
119
+ break;
120
+ }
121
+ }
122
+ return result;
123
+ }
124
+ }
125
+ result.source = 'external';
126
+ result.category = 'other';
127
+ } catch (e) {
128
+ console.warn('[Lua UTM] Error detecting referrer:', e);
129
+ }
130
+ return result;
131
+ }
132
+
133
+ /**
134
+ * Get user agent info for device detection
135
+ * @returns {Object} - { raw, isMobile, isTablet, isDesktop }
136
+ */
137
+ function getUserAgentInfo() {
138
+ var result = {
139
+ raw: '',
140
+ isMobile: false,
141
+ isTablet: false,
142
+ isDesktop: true
143
+ };
144
+ try {
145
+ if (typeof navigator === 'undefined' || !navigator.userAgent) return result;
146
+ result.raw = navigator.userAgent;
147
+ result.isMobile = /Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
148
+ result.isTablet = /iPad|Android(?!.*Mobile)/i.test(navigator.userAgent);
149
+ result.isDesktop = !result.isMobile && !result.isTablet;
150
+ } catch (e) {
151
+ console.warn('[Lua UTM] Error getting user agent:', e);
152
+ }
153
+ return result;
154
+ }
155
+
156
+ /**
157
+ * Infer user intent from context
158
+ * Priority: UTM campaign > UTM source > Referrer category
159
+ * @param {Object} context - Full context object
160
+ * @returns {string} - Inferred intent key
161
+ */
162
+ function inferIntent(context) {
163
+ if (context.utm.utm_campaign) {
164
+ var campaign = context.utm.utm_campaign.toLowerCase();
165
+ if (/sale|discount|offer|promo/i.test(campaign)) return 'price-focused';
166
+ if (/gaming|game|esport/i.test(campaign)) return 'gaming';
167
+ if (/work|office|professional|productivity/i.test(campaign)) return 'professional';
168
+ if (/creative|design|art|studio/i.test(campaign)) return 'creative';
169
+ if (/brand|story|about/i.test(campaign)) return 'brand-story';
170
+ }
171
+ if (context.utm.utm_source) {
172
+ var source = context.utm.utm_source.toLowerCase();
173
+ if (/google|bing|yahoo/i.test(source)) return 'search-optimized';
174
+ if (/facebook|instagram|tiktok/i.test(source)) return 'social-visual';
175
+ if (/twitter|x$/i.test(source)) return 'social-brief';
176
+ if (/email|newsletter/i.test(source)) return 'returning-user';
177
+ if (/youtube/i.test(source)) return 'video-engaged';
178
+ }
179
+ if (context.referrer.category === 'search') return 'search-optimized';
180
+ if (context.referrer.category === 'social') return 'social-visual';
181
+ if (context.referrer.category === 'email') return 'returning-user';
182
+ return 'default';
183
+ }
184
+
185
+ /**
186
+ * Build full personalization context
187
+ * @param {Object} [options] - { url: string }
188
+ * @returns {Object} - Complete context object
189
+ */
190
+ function getContext(options) {
191
+ options = options || {};
192
+ var context = {
193
+ utm: extractUTMParams(options.url),
194
+ referrer: detectReferrer(),
195
+ userAgent: getUserAgentInfo(),
196
+ timestamp: Date.now(),
197
+ hasUTM: false,
198
+ primaryIntent: 'unknown'
199
+ };
200
+ context.hasUTM = Object.keys(context.utm).length > 0;
201
+ context.primaryIntent = inferIntent(context);
202
+ return context;
203
+ }
204
+
205
+ /**
206
+ * Async context with timeout fallback (1 second max)
207
+ * @param {Object} [options] - { timeout: number, url: string }
208
+ * @returns {Promise<Object>} - Context object
209
+ */
210
+ function getContextAsync(options) {
211
+ options = options || {};
212
+ var timeout = options.timeout || UTM_TIMEOUT_MS;
213
+ return new Promise(function (resolve) {
214
+ var timer = setTimeout(function () {
215
+ resolve({
216
+ utm: {},
217
+ referrer: {
218
+ source: 'direct',
219
+ category: 'direct',
220
+ url: ''
221
+ },
222
+ userAgent: {
223
+ raw: '',
224
+ isMobile: false,
225
+ isTablet: false,
226
+ isDesktop: true
227
+ },
228
+ timestamp: Date.now(),
229
+ hasUTM: false,
230
+ primaryIntent: 'default',
231
+ timedOut: true
232
+ });
233
+ }, timeout);
234
+ try {
235
+ var context = getContext(options);
236
+ clearTimeout(timer);
237
+ context.timedOut = false;
238
+ resolve(context);
239
+ } catch (e) {
240
+ clearTimeout(timer);
241
+ resolve({
242
+ utm: {},
243
+ referrer: {
244
+ source: 'direct',
245
+ category: 'direct',
246
+ url: ''
247
+ },
248
+ userAgent: {
249
+ raw: '',
250
+ isMobile: false,
251
+ isTablet: false,
252
+ isDesktop: true
253
+ },
254
+ timestamp: Date.now(),
255
+ hasUTM: false,
256
+ primaryIntent: 'default',
257
+ error: e.message
258
+ });
259
+ }
260
+ });
261
+ }
262
+
263
+ // ===================================================================
264
+ // 2. DOMPURIFY-STYLE HTML SANITIZER
265
+ // ===================================================================
266
+
267
+ var Sanitizer = function () {
268
+ var ALLOWED_TAGS = {
269
+ 'p': true,
270
+ 'span': true,
271
+ 'strong': true,
272
+ 'em': true,
273
+ 'b': true,
274
+ 'i': true,
275
+ 'br': true,
276
+ 'a': true,
277
+ 'img': true,
278
+ 'h1': true,
279
+ 'h2': true,
280
+ 'h3': true,
281
+ 'h4': true,
282
+ 'h5': true,
283
+ 'h6': true,
284
+ 'div': true,
285
+ 'section': true,
286
+ 'ul': true,
287
+ 'ol': true,
288
+ 'li': true,
289
+ 'blockquote': true,
290
+ 'figure': true,
291
+ 'figcaption': true
292
+ };
293
+ var ALLOWED_ATTRS = {
294
+ 'href': true,
295
+ 'src': true,
296
+ 'alt': true,
297
+ 'class': true,
298
+ 'id': true,
299
+ 'title': true,
300
+ 'target': true,
301
+ 'rel': true,
302
+ 'width': true,
303
+ 'height': true,
304
+ 'loading': true
305
+ };
306
+ var DANGEROUS_URI = /^(javascript|vbscript|data):/i;
307
+ var EVENT_HANDLER = /^on/i;
308
+ function hasDOMParser() {
309
+ try {
310
+ return typeof DOMParser !== 'undefined' && new DOMParser();
311
+ } catch (e) {
312
+ return false;
313
+ }
314
+ }
315
+ function escapeText(text) {
316
+ if (!text) return '';
317
+ return text.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
318
+ }
319
+ function escapeAttr(value) {
320
+ if (!value) return '';
321
+ return value.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
322
+ }
323
+ function cleanAttributes(element) {
324
+ var attrStr = '';
325
+ var attrs = element.attributes;
326
+ for (var i = 0; i < attrs.length; i++) {
327
+ var name = attrs[i].name.toLowerCase();
328
+ var value = attrs[i].value;
329
+ if (EVENT_HANDLER.test(name)) continue;
330
+ if (!ALLOWED_ATTRS[name]) continue;
331
+ if ((name === 'href' || name === 'src') && DANGEROUS_URI.test(value.trim())) continue;
332
+ if (name === 'target' && value === '_blank') {
333
+ attrStr += ' target="_blank" rel="noopener noreferrer"';
334
+ continue;
335
+ }
336
+ attrStr += ' ' + name + '="' + escapeAttr(value) + '"';
337
+ }
338
+ return attrStr;
339
+ }
340
+ function walkAndClean(node) {
341
+ var output = '';
342
+ for (var i = 0; i < node.childNodes.length; i++) {
343
+ var child = node.childNodes[i];
344
+ if (child.nodeType === 3) {
345
+ output += escapeText(child.textContent);
346
+ continue;
347
+ }
348
+ if (child.nodeType === 1) {
349
+ var tag = child.tagName.toLowerCase();
350
+ if (tag === 'script' || tag === 'style' || tag === 'iframe' || tag === 'object' || tag === 'embed' || tag === 'form' || tag === 'input' || tag === 'textarea') continue;
351
+ if (ALLOWED_TAGS[tag]) {
352
+ output += '<' + tag + cleanAttributes(child) + '>';
353
+ if (tag !== 'br' && tag !== 'img') {
354
+ output += walkAndClean(child);
355
+ output += '</' + tag + '>';
356
+ }
357
+ } else {
358
+ output += walkAndClean(child);
359
+ }
360
+ }
361
+ }
362
+ return output;
363
+ }
364
+ function sanitizeWithDOMParser(dirty) {
365
+ try {
366
+ var doc = new DOMParser().parseFromString(dirty, 'text/html');
367
+ return doc.body ? walkAndClean(doc.body) : '';
368
+ } catch (e) {
369
+ return sanitizeWithRegex(dirty);
370
+ }
371
+ }
372
+ function sanitizeWithRegex(html) {
373
+ var patterns = [/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi, /<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi, /<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi, /<embed\b[^>]*>/gi, /<link\b[^>]*>/gi, /<style\b[^<]*(?:(?!<\/style>)<[^<]*)*<\/style>/gi, /<form\b[^<]*(?:(?!<\/form>)<[^<]*)*<\/form>/gi, /javascript:/gi, /vbscript:/gi, /data:/gi, /on\w+\s*=/gi];
374
+ var sanitized = html;
375
+ patterns.forEach(function (p) {
376
+ sanitized = sanitized.replace(p, '');
377
+ });
378
+ sanitized = sanitized.replace(/<\/?(\w+)([^>]*)>/g, function (match, tagName, attrs) {
379
+ var tag = tagName.toLowerCase();
380
+ if (!ALLOWED_TAGS[tag]) return '';
381
+ if (match.charAt(1) === '/') return '</' + tag + '>';
382
+ var cleanAttrs = '';
383
+ var re = /(\w+)=['"]([^'"]*)['"]/g;
384
+ var m;
385
+ while ((m = re.exec(attrs)) !== null) {
386
+ var n = m[1].toLowerCase();
387
+ if (ALLOWED_ATTRS[n] && !EVENT_HANDLER.test(n)) {
388
+ if ((n === 'href' || n === 'src') && DANGEROUS_URI.test(m[2])) continue;
389
+ cleanAttrs += ' ' + n + '="' + m[2] + '"';
390
+ }
391
+ }
392
+ return '<' + tag + cleanAttrs + '>';
393
+ });
394
+ return sanitized;
395
+ }
396
+ return {
397
+ sanitize: function sanitize(dirty) {
398
+ if (typeof dirty !== 'string' || !dirty.trim()) return '';
399
+ return hasDOMParser() ? sanitizeWithDOMParser(dirty) : sanitizeWithRegex(dirty);
400
+ },
401
+ escapeText: escapeText,
402
+ escapeAttr: escapeAttr
403
+ };
404
+ }();
405
+
406
+ // ===================================================================
407
+ // 3. TEMPLATES & ASSETS
408
+ // ===================================================================
409
+ // NOTE: Templates are NOT provided by this package.
410
+ // Users must provide their own templates via options.templates
411
+ // This keeps the package modular and allows users full control
412
+ // over their content, assets, and personalization strategy.
413
+
414
+ // ===================================================================
415
+ // 4. DOM PERSONALIZATION ENGINE
416
+ // ===================================================================
417
+
418
+ function safeSetText(element, text) {
419
+ if (!element) return;
420
+ element.textContent = text;
421
+ }
422
+ function safeSetHTML(element, html) {
423
+ if (!element) return;
424
+ element.innerHTML = Sanitizer.sanitize(html);
425
+ }
426
+ function findPersonalizeElements(key, searchRoot) {
427
+ searchRoot = searchRoot || (typeof document !== 'undefined' ? document : null);
428
+ if (!searchRoot) return [];
429
+ var selector = key ? '[data-personalize="' + key + '"]' : '[data-personalize]';
430
+ return searchRoot.querySelectorAll(selector);
431
+ }
432
+ function getTemplate(intent, userTemplates) {
433
+ if (!userTemplates || (0, _typeof2.default)(userTemplates) !== 'object') {
434
+ console.warn('[Lua Personalize] No templates provided. Templates must be passed via options.templates');
435
+ return null;
436
+ }
437
+ if (userTemplates[intent]) return userTemplates[intent];
438
+ if (userTemplates['default']) return userTemplates['default'];
439
+ var firstKey = Object.keys(userTemplates)[0];
440
+ if (firstKey) {
441
+ console.warn('[Lua Personalize] Intent "' + intent + '" not found, using first available template:', firstKey);
442
+ return userTemplates[firstKey];
443
+ }
444
+ return null;
445
+ }
446
+
447
+ // ===================================================================
448
+ // 5. RANDOM A/B FALLBACK
449
+ // ===================================================================
450
+
451
+ function chooseWeightedRandom(names, weights) {
452
+ if (names.length !== weights.length) return names[0];
453
+ var sum = 0;
454
+ var i;
455
+ for (i = 0; i < weights.length; i++) {
456
+ sum += weights[i];
457
+ }
458
+ var n = Math.random() * sum;
459
+ var limit = 0;
460
+ for (i = 0; i < names.length; i++) {
461
+ limit += weights[i];
462
+ if (n <= limit) return names[i];
463
+ }
464
+ return names[names.length - 1];
465
+ }
466
+ function getRandomFallbackIntent(userTemplates) {
467
+ if (!userTemplates || (0, _typeof2.default)(userTemplates) !== 'object') return null;
468
+ var names = Object.keys(userTemplates);
469
+ if (names.length === 0) return null;
470
+ var weights = [];
471
+ for (var i = 0; i < names.length; i++) {
472
+ weights.push(1);
473
+ }
474
+ return chooseWeightedRandom(names, weights);
475
+ }
476
+
477
+ // ===================================================================
478
+ // 6. DECISION ENGINE
479
+ // ===================================================================
480
+
481
+ var DecisionEngine = {
482
+ /**
483
+ * Standard (non-AI) decision logic
484
+ * Priority: Custom rules > UTM params > Referrer > Random A/B
485
+ */
486
+ standardDecide: function standardDecide(context, options) {
487
+ options = options || {};
488
+ var customRules = options.rules || {};
489
+ var userTemplates = options.templates;
490
+ var enableRandomFallback = options.randomFallback !== false;
491
+ if (!userTemplates || (0, _typeof2.default)(userTemplates) !== 'object' || Object.keys(userTemplates).length === 0) {
492
+ console.warn('[Lua Personalize] No templates provided. Templates must be passed via options.templates');
493
+ return {
494
+ template: null,
495
+ intent: 'default',
496
+ source: 'error',
497
+ context: context,
498
+ error: 'No templates provided'
499
+ };
500
+ }
501
+ var intent = context.primaryIntent;
502
+ var source = 'default';
503
+ if (context.hasUTM) {
504
+ source = 'utm';
505
+ } else if (context.referrer && context.referrer.category !== 'direct') {
506
+ source = 'referrer';
507
+ }
508
+ for (var ruleKey in customRules) {
509
+ var rule = customRules[ruleKey];
510
+ if (typeof rule.match === 'function' && rule.match(context)) {
511
+ intent = rule.intent || ruleKey;
512
+ source = 'custom-rule';
513
+ break;
514
+ }
515
+ }
516
+ if (intent === 'default' && source === 'default' && enableRandomFallback) {
517
+ var randomIntent = getRandomFallbackIntent(userTemplates);
518
+ if (randomIntent) {
519
+ intent = randomIntent;
520
+ source = 'random-ab';
521
+ }
522
+ }
523
+
524
+ // Record visit to history if available
525
+ if (root.LuaWeightedHistory && typeof root.LuaWeightedHistory.recordVisit === 'function') {
526
+ root.LuaWeightedHistory.recordVisit({
527
+ context: context,
528
+ intent: intent,
529
+ selectedVariant: intent,
530
+ source: source,
531
+ aiDecision: false
532
+ });
533
+ }
534
+ return {
535
+ template: getTemplate(intent, userTemplates),
536
+ intent: intent,
537
+ source: source,
538
+ context: context
539
+ };
540
+ },
541
+ /**
542
+ * Main decide function - routes to AI or standard engine
543
+ * @param {Object} context - UTM context
544
+ * @param {Object} [options] - Configuration options
545
+ * @param {boolean} [options.enableAI] - Enable AI-powered decisions
546
+ * @param {Object} [options.aiConfig] - AI configuration
547
+ * @returns {Object|Promise<Object>} - Decision result
548
+ */
549
+ decide: function decide(context, options) {
550
+ options = options || {};
551
+
552
+ // If AI is enabled and configured, try AI decision first
553
+ if (options.enableAI && options.aiConfig && root.LuaAIPersonalize) {
554
+ var self = this;
555
+ var aiModule = root.LuaAIPersonalize;
556
+ var readiness = aiModule.isReady(options.aiConfig);
557
+ if (readiness.ready) {
558
+ return aiModule.decide(context, options).catch(function (error) {
559
+ var fallback = options.aiConfig.fallbackToStandard !== false;
560
+ if (fallback) {
561
+ console.warn('[Lua Personalize] AI failed, using standard engine:', error.message);
562
+ return self.standardDecide(context, options);
563
+ }
564
+ throw error;
565
+ });
566
+ } else {
567
+ console.warn('[Lua Personalize] AI not ready:', readiness.error, '- using standard engine');
568
+ }
569
+ }
570
+ return this.standardDecide(context, options);
571
+ }
572
+ };
573
+
574
+ // ===================================================================
575
+ // 7. DOM APPLICATION (extracted for reuse)
576
+ // ===================================================================
577
+
578
+ /**
579
+ * Apply a decision to the DOM
580
+ * @param {Object} decision - Decision object { template, intent, source, context }
581
+ * @param {Object} [options] - Configuration options
582
+ * @returns {Object} - The decision (pass-through)
583
+ */
584
+ function applyDecisionToDOM(decision, options) {
585
+ options = options || {};
586
+ var template = decision.template;
587
+ var context = decision.context || {};
588
+ var log = options.log !== false;
589
+ if (!template) {
590
+ console.warn('[Lua Personalize] No template in decision, skipping DOM update');
591
+ return decision;
592
+ }
593
+ var slots = ['image', 'headline', 'subheadline', 'ctaLabel', 'ctaLink'];
594
+ slots.forEach(function (slot) {
595
+ var elements = findPersonalizeElements(slot);
596
+ for (var i = 0; i < elements.length; i++) {
597
+ var el = elements[i];
598
+ var value = template[slot];
599
+ if (!value) continue;
600
+ if (slot === 'image') {
601
+ if (el.tagName === 'IMG') {
602
+ el.src = value;
603
+ el.alt = template.headline || 'Personalized image';
604
+ } else {
605
+ el.style.backgroundImage = 'url(' + value + ')';
606
+ }
607
+ } else if (slot === 'ctaLink') {
608
+ el.href = value;
609
+ } else {
610
+ safeSetText(el, value);
611
+ }
612
+ }
613
+ });
614
+
615
+ // Apply to data-personalize="hero" elements
616
+ var heroElements = findPersonalizeElements('hero');
617
+ for (var h = 0; h < heroElements.length; h++) {
618
+ var heroEl = heroElements[h];
619
+ heroEl.setAttribute('data-intent', decision.intent);
620
+ heroEl.setAttribute('data-source', decision.source);
621
+ if (template.image && !heroEl.querySelector('[data-personalize="image"]')) {
622
+ heroEl.style.backgroundImage = 'url(' + template.image + ')';
623
+ }
624
+ }
625
+ if (log && typeof console !== 'undefined') {
626
+ console.log('[Lua Personalize] Applied:', {
627
+ intent: decision.intent,
628
+ source: decision.source,
629
+ headline: template.headline,
630
+ hasUTM: context.hasUTM,
631
+ utmParams: context.utm || {},
632
+ aiPowered: decision.source === 'ai' || decision.source === 'ai-cached'
633
+ });
634
+ }
635
+ return decision;
636
+ }
637
+
638
+ // ===================================================================
639
+ // 8. MAIN PERSONALIZATION FUNCTION
640
+ // ===================================================================
641
+
642
+ /**
643
+ * Apply personalization to the page
644
+ * Scans for data-personalize attributes and injects content
645
+ * Supports AI-powered decisions when enableAI is true
646
+ *
647
+ * @param {Object} [options] - Configuration
648
+ * @param {Object} [options.context] - Pre-computed context
649
+ * @param {Object} [options.rules] - Custom rules
650
+ * @param {Object} options.templates - User-provided templates (REQUIRED)
651
+ * @param {boolean} [options.enableAI] - Enable AI-powered decisions
652
+ * @param {Object} [options.aiConfig] - AI configuration
653
+ * @param {boolean} [options.randomFallback] - Enable random A/B (default: true)
654
+ * @param {boolean} [options.log] - Enable logging (default: true)
655
+ * @returns {Object|Promise<Object>} - Decision result (Promise if AI enabled)
656
+ */
657
+ function personalize(options) {
658
+ options = options || {};
659
+
660
+ // Templates are required
661
+ if (!options.templates || (0, _typeof2.default)(options.templates) !== 'object' || Object.keys(options.templates).length === 0) {
662
+ console.error('[Lua Personalize] Templates are required. Provide templates via options.templates');
663
+ return {
664
+ template: null,
665
+ intent: 'default',
666
+ source: 'error',
667
+ context: {},
668
+ error: 'No templates provided'
669
+ };
670
+ }
671
+ var context = options.context || getContext(options);
672
+ var decision = DecisionEngine.decide(context, options);
673
+
674
+ // If decision is a Promise (AI path), handle async
675
+ if (decision && typeof decision.then === 'function') {
676
+ return decision.then(function (aiDecision) {
677
+ return applyDecisionToDOM(aiDecision, options);
678
+ }).catch(function (err) {
679
+ console.warn('[Lua Personalize] AI decision failed, using standard:', err.message);
680
+ var fallbackDecision = DecisionEngine.standardDecide(context, options);
681
+ return applyDecisionToDOM(fallbackDecision, options);
682
+ });
683
+ }
684
+
685
+ // Synchronous path
686
+ return applyDecisionToDOM(decision, options);
687
+ }
688
+
689
+ /**
690
+ * Async personalization with timeout fallback
691
+ * Automatically handles AI decisions (which are always async)
692
+ */
693
+ function personalizeAsync(options) {
694
+ options = options || {};
695
+ return getContextAsync(options).then(function (context) {
696
+ options.context = context;
697
+ return personalize(options);
698
+ }).then(function (decision) {
699
+ return decision;
700
+ }).catch(function (err) {
701
+ console.warn('[Lua Personalize] Async error, using default:', err);
702
+ var ctx = getContext(options);
703
+ var fallback = DecisionEngine.standardDecide(ctx, {
704
+ templates: options.templates
705
+ });
706
+ return applyDecisionToDOM(fallback, options);
707
+ });
708
+ }
709
+
710
+ // ===================================================================
711
+ // 9. AUTO-INITIALIZATION
712
+ // ===================================================================
713
+
714
+ /**
715
+ * Auto-initialize personalization on DOMContentLoaded
716
+ * Only runs if data-personalize elements exist in the DOM
717
+ */
718
+ function autoInit(options) {
719
+ options = options || {};
720
+ function run() {
721
+ var elements = findPersonalizeElements();
722
+ if (elements.length > 0) {
723
+ personalize(options);
724
+ }
725
+ }
726
+ if (typeof document !== 'undefined') {
727
+ if (document.readyState === 'loading') {
728
+ document.addEventListener('DOMContentLoaded', run);
729
+ } else {
730
+ run();
731
+ }
732
+ }
733
+ }
734
+
735
+ // ===================================================================
736
+ // 10. PUBLIC API
737
+ // ===================================================================
738
+
739
+ var LuaUTMPersonalize = {
740
+ // UTM extraction
741
+ extractUTMParams: extractUTMParams,
742
+ sanitizeParam: sanitizeParam,
743
+ detectReferrer: detectReferrer,
744
+ getUserAgentInfo: getUserAgentInfo,
745
+ getContext: getContext,
746
+ getContextAsync: getContextAsync,
747
+ inferIntent: inferIntent,
748
+ // Sanitizer
749
+ sanitizer: Sanitizer,
750
+ sanitizeHTML: function sanitizeHTML(html) {
751
+ return Sanitizer.sanitize(html);
752
+ },
753
+ // DOM helpers
754
+ safeSetText: safeSetText,
755
+ safeSetHTML: safeSetHTML,
756
+ findElements: findPersonalizeElements,
757
+ applyDecisionToDOM: applyDecisionToDOM,
758
+ // Templates (users must provide their own via options.templates)
759
+ getTemplate: getTemplate,
760
+ // Decision engine
761
+ engine: DecisionEngine,
762
+ chooseWeightedRandom: chooseWeightedRandom,
763
+ getRandomFallbackIntent: getRandomFallbackIntent,
764
+ // Main API
765
+ personalize: personalize,
766
+ personalizeAsync: personalizeAsync,
767
+ autoInit: autoInit,
768
+ // Constants
769
+ UTM_PARAMS: UTM_PARAMS,
770
+ UTM_TIMEOUT_MS: UTM_TIMEOUT_MS,
771
+ REFERRER_PATTERNS: REFERRER_PATTERNS,
772
+ REFERRER_CATEGORIES: REFERRER_CATEGORIES
773
+ };
774
+
775
+ // Register globally
776
+ root.LuaUTMPersonalize = LuaUTMPersonalize;
777
+
778
+ // Also register individual modules for compatibility
779
+ if (!root.LuaUTM) {
780
+ root.LuaUTM = {
781
+ extractUTMParams: extractUTMParams,
782
+ sanitizeParam: sanitizeParam,
783
+ detectReferrer: detectReferrer,
784
+ getUserAgentInfo: getUserAgentInfo,
785
+ getContext: getContext,
786
+ getContextAsync: getContextAsync,
787
+ inferIntent: inferIntent,
788
+ UTM_PARAMS: UTM_PARAMS,
789
+ UTM_TIMEOUT_MS: UTM_TIMEOUT_MS,
790
+ REFERRER_PATTERNS: REFERRER_PATTERNS,
791
+ REFERRER_CATEGORIES: REFERRER_CATEGORIES
792
+ };
793
+ }
794
+ if (!root.LuaPersonalize) {
795
+ root.LuaPersonalize = {
796
+ sanitizer: Sanitizer,
797
+ sanitizeHTML: function sanitizeHTML(html) {
798
+ return Sanitizer.sanitize(html);
799
+ },
800
+ safeSetText: safeSetText,
801
+ safeSetHTML: safeSetHTML,
802
+ findElements: findPersonalizeElements,
803
+ applyDecisionToDOM: applyDecisionToDOM,
804
+ getTemplate: getTemplate,
805
+ engine: DecisionEngine,
806
+ personalize: personalize,
807
+ personalizeAsync: personalizeAsync,
808
+ autoInit: autoInit,
809
+ chooseWeightedRandom: chooseWeightedRandom,
810
+ getRandomFallbackIntent: getRandomFallbackIntent
811
+ };
812
+ }
813
+
814
+ // Note: autoInit() is NOT called automatically because templates are required
815
+ // Users must call personalize() or personalizeAsync() with their templates
816
+ })(typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : void 0);
817
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJyb290IiwiVVRNX1RJTUVPVVRfTVMiLCJVVE1fUEFSQU1TIiwiUkVGRVJSRVJfUEFUVEVSTlMiLCJnb29nbGUiLCJiaW5nIiwieWFob28iLCJkdWNrZHVja2dvIiwiZmFjZWJvb2siLCJ0d2l0dGVyIiwiaW5zdGFncmFtIiwibGlua2VkaW4iLCJwaW50ZXJlc3QiLCJ0aWt0b2siLCJ5b3V0dWJlIiwicmVkZGl0IiwiUkVGRVJSRVJfQ0FURUdPUklFUyIsInNlYXJjaCIsInNvY2lhbCIsInNhbml0aXplUGFyYW0iLCJ2YWx1ZSIsInJlcGxhY2UiLCJzdWJzdHJpbmciLCJ0cmltIiwiZXh0cmFjdFVUTVBhcmFtcyIsInVybCIsInJlc3VsdCIsInNlYXJjaFN0cmluZyIsImxvY2F0aW9uIiwicGFyYW1zIiwiVVJMU2VhcmNoUGFyYW1zIiwiZm9yRWFjaCIsInBhcmFtIiwiZ2V0IiwiZSIsImNvbnNvbGUiLCJ3YXJuIiwiZGV0ZWN0UmVmZXJyZXIiLCJzb3VyY2UiLCJjYXRlZ29yeSIsImRvY3VtZW50IiwicmVmZXJyZXIiLCJ0ZXN0IiwiaW5kZXhPZiIsImdldFVzZXJBZ2VudEluZm8iLCJyYXciLCJpc01vYmlsZSIsImlzVGFibGV0IiwiaXNEZXNrdG9wIiwibmF2aWdhdG9yIiwidXNlckFnZW50IiwiaW5mZXJJbnRlbnQiLCJjb250ZXh0IiwidXRtIiwidXRtX2NhbXBhaWduIiwiY2FtcGFpZ24iLCJ0b0xvd2VyQ2FzZSIsInV0bV9zb3VyY2UiLCJnZXRDb250ZXh0Iiwib3B0aW9ucyIsInRpbWVzdGFtcCIsIkRhdGUiLCJub3ciLCJoYXNVVE0iLCJwcmltYXJ5SW50ZW50IiwiT2JqZWN0Iiwia2V5cyIsImxlbmd0aCIsImdldENvbnRleHRBc3luYyIsInRpbWVvdXQiLCJQcm9taXNlIiwicmVzb2x2ZSIsInRpbWVyIiwic2V0VGltZW91dCIsInRpbWVkT3V0IiwiY2xlYXJUaW1lb3V0IiwiZXJyb3IiLCJtZXNzYWdlIiwiU2FuaXRpemVyIiwiQUxMT1dFRF9UQUdTIiwiQUxMT1dFRF9BVFRSUyIsIkRBTkdFUk9VU19VUkkiLCJFVkVOVF9IQU5ETEVSIiwiaGFzRE9NUGFyc2VyIiwiRE9NUGFyc2VyIiwiZXNjYXBlVGV4dCIsInRleHQiLCJlc2NhcGVBdHRyIiwiY2xlYW5BdHRyaWJ1dGVzIiwiZWxlbWVudCIsImF0dHJTdHIiLCJhdHRycyIsImF0dHJpYnV0ZXMiLCJpIiwibmFtZSIsIndhbGtBbmRDbGVhbiIsIm5vZGUiLCJvdXRwdXQiLCJjaGlsZE5vZGVzIiwiY2hpbGQiLCJub2RlVHlwZSIsInRleHRDb250ZW50IiwidGFnIiwidGFnTmFtZSIsInNhbml0aXplV2l0aERPTVBhcnNlciIsImRpcnR5IiwiZG9jIiwicGFyc2VGcm9tU3RyaW5nIiwiYm9keSIsInNhbml0aXplV2l0aFJlZ2V4IiwiaHRtbCIsInBhdHRlcm5zIiwic2FuaXRpemVkIiwicCIsIm1hdGNoIiwiY2hhckF0IiwiY2xlYW5BdHRycyIsInJlIiwibSIsImV4ZWMiLCJuIiwic2FuaXRpemUiLCJzYWZlU2V0VGV4dCIsInNhZmVTZXRIVE1MIiwiaW5uZXJIVE1MIiwiZmluZFBlcnNvbmFsaXplRWxlbWVudHMiLCJrZXkiLCJzZWFyY2hSb290Iiwic2VsZWN0b3IiLCJxdWVyeVNlbGVjdG9yQWxsIiwiZ2V0VGVtcGxhdGUiLCJpbnRlbnQiLCJ1c2VyVGVtcGxhdGVzIiwiX3R5cGVvZjIiLCJkZWZhdWx0IiwiZmlyc3RLZXkiLCJjaG9vc2VXZWlnaHRlZFJhbmRvbSIsIm5hbWVzIiwid2VpZ2h0cyIsInN1bSIsIk1hdGgiLCJyYW5kb20iLCJsaW1pdCIsImdldFJhbmRvbUZhbGxiYWNrSW50ZW50IiwicHVzaCIsIkRlY2lzaW9uRW5naW5lIiwic3RhbmRhcmREZWNpZGUiLCJjdXN0b21SdWxlcyIsInJ1bGVzIiwidGVtcGxhdGVzIiwiZW5hYmxlUmFuZG9tRmFsbGJhY2siLCJyYW5kb21GYWxsYmFjayIsInRlbXBsYXRlIiwicnVsZUtleSIsInJ1bGUiLCJyYW5kb21JbnRlbnQiLCJMdWFXZWlnaHRlZEhpc3RvcnkiLCJyZWNvcmRWaXNpdCIsInNlbGVjdGVkVmFyaWFudCIsImFpRGVjaXNpb24iLCJkZWNpZGUiLCJlbmFibGVBSSIsImFpQ29uZmlnIiwiTHVhQUlQZXJzb25hbGl6ZSIsInNlbGYiLCJhaU1vZHVsZSIsInJlYWRpbmVzcyIsImlzUmVhZHkiLCJyZWFkeSIsImNhdGNoIiwiZmFsbGJhY2siLCJmYWxsYmFja1RvU3RhbmRhcmQiLCJhcHBseURlY2lzaW9uVG9ET00iLCJkZWNpc2lvbiIsImxvZyIsInNsb3RzIiwic2xvdCIsImVsZW1lbnRzIiwiZWwiLCJzcmMiLCJhbHQiLCJoZWFkbGluZSIsInN0eWxlIiwiYmFja2dyb3VuZEltYWdlIiwiaHJlZiIsImhlcm9FbGVtZW50cyIsImgiLCJoZXJvRWwiLCJzZXRBdHRyaWJ1dGUiLCJpbWFnZSIsInF1ZXJ5U2VsZWN0b3IiLCJ1dG1QYXJhbXMiLCJhaVBvd2VyZWQiLCJwZXJzb25hbGl6ZSIsInRoZW4iLCJlcnIiLCJmYWxsYmFja0RlY2lzaW9uIiwicGVyc29uYWxpemVBc3luYyIsImN0eCIsImF1dG9Jbml0IiwicnVuIiwicmVhZHlTdGF0ZSIsImFkZEV2ZW50TGlzdGVuZXIiLCJMdWFVVE1QZXJzb25hbGl6ZSIsInNhbml0aXplciIsInNhbml0aXplSFRNTCIsImZpbmRFbGVtZW50cyIsImVuZ2luZSIsIkx1YVVUTSIsIkx1YVBlcnNvbmFsaXplIiwid2luZG93IiwiZ2xvYmFsIl0sInNvdXJjZXMiOlsiLi4vLi4vc3JjL3V0bS1wZXJzb25hbGl6ZS5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyJcbi8qKlxuICogTHVhIFVUTSBQZXJzb25hbGl6YXRpb24gLSBTdGFuZGFsb25lIEJ1bmRsZVxuICogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAqIFNlbGYtY29udGFpbmVkIHNjcmlwdCBjb21iaW5pbmc6XG4gKiAgIC0gVVJMU2VhcmNoUGFyYW1zLWJhc2VkIFVUTSBleHRyYWN0aW9uXG4gKiAgIC0gUmVmZXJyZXIgJiB1c2VyIGFnZW50IGRldGVjdGlvblxuICogICAtIEludGVudCBpbmZlcmVuY2UgZW5naW5lXG4gKiAgIC0gRE9NUHVyaWZ5LXN0eWxlIEhUTUwgc2FuaXRpemVyXG4gKiAgIC0gRE9NIHBlcnNvbmFsaXphdGlvbiB2aWEgZGF0YS1wZXJzb25hbGl6ZSBhdHRyaWJ1dGVzXG4gKiAgIC0gUmFuZG9tIEEvQiB0ZXN0IGZhbGxiYWNrIHdoZW4gbm8gVVRNIHBhcmFtcyBwcmVzZW50XG4gKlxuICogVXNhZ2U6XG4gKiAgIDxzY3JpcHQgc3JjPVwidXRtLXBlcnNvbmFsaXplLmpzXCIgZGVmZXI+PC9zY3JpcHQ+XG4gKlxuICogICA8IS0tIFRoZW4gaW4geW91ciBIVE1MIHVzZSBkYXRhLXBlcnNvbmFsaXplIGF0dHJpYnV0ZXM6IC0tPlxuICogICA8ZGl2IGRhdGEtcGVyc29uYWxpemU9XCJoZXJvXCI+XG4gKiAgICAgPGgxIGRhdGEtcGVyc29uYWxpemU9XCJoZWFkbGluZVwiPkRlZmF1bHQgSGVhZGxpbmU8L2gxPlxuICogICAgIDxwIGRhdGEtcGVyc29uYWxpemU9XCJzdWJoZWFkbGluZVwiPkRlZmF1bHQgc3ViaGVhZGxpbmU8L3A+XG4gKiAgICAgPGEgaHJlZj1cIiNcIiBkYXRhLXBlcnNvbmFsaXplPVwiY3RhTGlua1wiPlxuICogICAgICAgPHNwYW4gZGF0YS1wZXJzb25hbGl6ZT1cImN0YUxhYmVsXCI+RGVmYXVsdCBDVEE8L3NwYW4+XG4gKiAgICAgPC9hPlxuICogICA8L2Rpdj5cbiAqXG4gKiBUaGUgc2NyaXB0IGF1dG8taW5pdGlhbGl6ZXMgb24gRE9NQ29udGVudExvYWRlZC5cbiAqIEFjY2VzcyB0aGUgQVBJIHZpYSB3aW5kb3cuTHVhVVRNUGVyc29uYWxpemVcbiAqXG4gKiBTaXplIHRhcmdldDogPCA1MEtCXG4gKiBObyBpbXBvcnRzLiBObyBkZXBlbmRlbmNpZXMuIE5vIGJ1aWxkIHN0ZXAgcmVxdWlyZWQuXG4gKi9cbjsoZnVuY3Rpb24gKHJvb3QpIHtcbiAgICAndXNlIHN0cmljdCdcblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyAxLiBVVE0gUEFSQU1FVEVSIEVYVFJBQ1RJT04gKFVSTFNlYXJjaFBhcmFtcyBBUEkpXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgdmFyIFVUTV9USU1FT1VUX01TID0gMTAwMFxuXG4gICAgdmFyIFVUTV9QQVJBTVMgPSBbJ3V0bV9zb3VyY2UnLCAndXRtX21lZGl1bScsICd1dG1fY2FtcGFpZ24nLCAndXRtX2NvbnRlbnQnLCAndXRtX3Rlcm0nXVxuXG4gICAgdmFyIFJFRkVSUkVSX1BBVFRFUk5TID0ge1xuICAgICAgICBnb29nbGU6IC9nb29nbGVcXC4vaSxcbiAgICAgICAgYmluZzogL2JpbmdcXC4vaSxcbiAgICAgICAgeWFob286IC95YWhvb1xcLi9pLFxuICAgICAgICBkdWNrZHVja2dvOiAvZHVja2R1Y2tnb1xcLi9pLFxuICAgICAgICBmYWNlYm9vazogL2ZhY2Vib29rXFwuY29tfGZiXFwuY29tL2ksXG4gICAgICAgIHR3aXR0ZXI6IC90d2l0dGVyXFwuY29tfHRcXC5jb3x4XFwuY29tL2ksXG4gICAgICAgIGluc3RhZ3JhbTogL2luc3RhZ3JhbVxcLmNvbS9pLFxuICAgICAgICBsaW5rZWRpbjogL2xpbmtlZGluXFwuY29tL2ksXG4gICAgICAgIHBpbnRlcmVzdDogL3BpbnRlcmVzdFxcLi9pLFxuICAgICAgICB0aWt0b2s6IC90aWt0b2tcXC5jb20vaSxcbiAgICAgICAgeW91dHViZTogL3lvdXR1YmVcXC5jb218eW91dHVcXC5iZS9pLFxuICAgICAgICByZWRkaXQ6IC9yZWRkaXRcXC5jb20vaVxuICAgIH1cblxuICAgIHZhciBSRUZFUlJFUl9DQVRFR09SSUVTID0ge1xuICAgICAgICBzZWFyY2g6IFsnZ29vZ2xlJywgJ2JpbmcnLCAneWFob28nLCAnZHVja2R1Y2tnbyddLFxuICAgICAgICBzb2NpYWw6IFsnZmFjZWJvb2snLCAndHdpdHRlcicsICdpbnN0YWdyYW0nLCAnbGlua2VkaW4nLCAncGludGVyZXN0JywgJ3Rpa3RvaycsICd5b3V0dWJlJywgJ3JlZGRpdCddXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2FuaXRpemUgYSBVVE0gcGFyYW1ldGVyIHZhbHVlIHRvIHByZXZlbnQgWFNTXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IHZhbHVlIC0gUmF3IHBhcmFtZXRlciB2YWx1ZVxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gU2FuaXRpemVkIHZhbHVlXG4gICAgICovXG4gICAgZnVuY3Rpb24gc2FuaXRpemVQYXJhbSh2YWx1ZSkge1xuICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykgcmV0dXJuICcnXG4gICAgICAgIHJldHVybiB2YWx1ZVxuICAgICAgICAgICAgLnJlcGxhY2UoLzxbXj5dKj4vZywgJycpXG4gICAgICAgICAgICAucmVwbGFjZSgvW15cXHdcXHNcXC1fLl0vZywgJycpXG4gICAgICAgICAgICAuc3Vic3RyaW5nKDAsIDEwMClcbiAgICAgICAgICAgIC50cmltKClcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBFeHRyYWN0IFVUTSBwYXJhbWV0ZXJzIGZyb20gVVJMIHVzaW5nIG5hdGl2ZSBVUkxTZWFyY2hQYXJhbXMgQVBJXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFt1cmxdIC0gVVJMIHNlYXJjaCBzdHJpbmcgKGRlZmF1bHRzIHRvIHdpbmRvdy5sb2NhdGlvbi5zZWFyY2gpXG4gICAgICogQHJldHVybnMge09iamVjdH0gLSBPYmplY3QgY29udGFpbmluZyBVVE0gcGFyYW1ldGVyc1xuICAgICAqL1xuICAgIGZ1bmN0aW9uIGV4dHJhY3RVVE1QYXJhbXModXJsKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSB7fVxuICAgICAgICB0cnkge1xuICAgICAgICAgICAgdmFyIHNlYXJjaFN0cmluZyA9IHVybCB8fCAodHlwZW9mIHJvb3QubG9jYXRpb24gIT09ICd1bmRlZmluZWQnID8gcm9vdC5sb2NhdGlvbi5zZWFyY2ggOiAnJylcbiAgICAgICAgICAgIGlmICghc2VhcmNoU3RyaW5nKSByZXR1cm4gcmVzdWx0XG5cbiAgICAgICAgICAgIHZhciBwYXJhbXMgPSBuZXcgVVJMU2VhcmNoUGFyYW1zKHNlYXJjaFN0cmluZylcblxuICAgICAgICAgICAgVVRNX1BBUkFNUy5mb3JFYWNoKGZ1bmN0aW9uIChwYXJhbSkge1xuICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IHBhcmFtcy5nZXQocGFyYW0pXG4gICAgICAgICAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdFtwYXJhbV0gPSBzYW5pdGl6ZVBhcmFtKHZhbHVlKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignW0x1YSBVVE1dIEVycm9yIGV4dHJhY3RpbmcgVVRNIHBhcmFtczonLCBlKVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiByZXN1bHRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZXRlY3QgcmVmZXJyZXIgdHlwZSBmcm9tIGRvY3VtZW50LnJlZmVycmVyXG4gICAgICogQHJldHVybnMge09iamVjdH0gLSB7IHNvdXJjZSwgY2F0ZWdvcnksIHVybCB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gZGV0ZWN0UmVmZXJyZXIoKSB7XG4gICAgICAgIHZhciByZXN1bHQgPSB7IHNvdXJjZTogJ2RpcmVjdCcsIGNhdGVnb3J5OiAnZGlyZWN0JywgdXJsOiAnJyB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIGRvY3VtZW50ID09PSAndW5kZWZpbmVkJyB8fCAhZG9jdW1lbnQucmVmZXJyZXIpIHJldHVybiByZXN1bHRcblxuICAgICAgICAgICAgcmVzdWx0LnVybCA9IGRvY3VtZW50LnJlZmVycmVyXG5cbiAgICAgICAgICAgIGlmICgvbWFpbFxcLnxlbWFpbFxcLnxuZXdzbGV0dGVyL2kudGVzdChkb2N1bWVudC5yZWZlcnJlcikpIHtcbiAgICAgICAgICAgICAgICByZXN1bHQuc291cmNlID0gJ2VtYWlsJ1xuICAgICAgICAgICAgICAgIHJlc3VsdC5jYXRlZ29yeSA9ICdlbWFpbCdcbiAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZvciAodmFyIHNvdXJjZSBpbiBSRUZFUlJFUl9QQVRURVJOUykge1xuICAgICAgICAgICAgICAgIGlmIChSRUZFUlJFUl9QQVRURVJOU1tzb3VyY2VdLnRlc3QoZG9jdW1lbnQucmVmZXJyZXIpKSB7XG4gICAgICAgICAgICAgICAgICAgIHJlc3VsdC5zb3VyY2UgPSBzb3VyY2VcbiAgICAgICAgICAgICAgICAgICAgZm9yICh2YXIgY2F0ZWdvcnkgaW4gUkVGRVJSRVJfQ0FURUdPUklFUykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFJFRkVSUkVSX0NBVEVHT1JJRVNbY2F0ZWdvcnldLmluZGV4T2Yoc291cmNlKSAhPT0gLTEpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQuY2F0ZWdvcnkgPSBjYXRlZ29yeVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmVzdWx0LnNvdXJjZSA9ICdleHRlcm5hbCdcbiAgICAgICAgICAgIHJlc3VsdC5jYXRlZ29yeSA9ICdvdGhlcidcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdbTHVhIFVUTV0gRXJyb3IgZGV0ZWN0aW5nIHJlZmVycmVyOicsIGUpXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHJlc3VsdFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldCB1c2VyIGFnZW50IGluZm8gZm9yIGRldmljZSBkZXRlY3Rpb25cbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fSAtIHsgcmF3LCBpc01vYmlsZSwgaXNUYWJsZXQsIGlzRGVza3RvcCB9XG4gICAgICovXG4gICAgZnVuY3Rpb24gZ2V0VXNlckFnZW50SW5mbygpIHtcbiAgICAgICAgdmFyIHJlc3VsdCA9IHsgcmF3OiAnJywgaXNNb2JpbGU6IGZhbHNlLCBpc1RhYmxldDogZmFsc2UsIGlzRGVza3RvcDogdHJ1ZSB9XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBpZiAodHlwZW9mIG5hdmlnYXRvciA9PT0gJ3VuZGVmaW5lZCcgfHwgIW5hdmlnYXRvci51c2VyQWdlbnQpIHJldHVybiByZXN1bHRcbiAgICAgICAgICAgIHJlc3VsdC5yYXcgPSBuYXZpZ2F0b3IudXNlckFnZW50XG4gICAgICAgICAgICByZXN1bHQuaXNNb2JpbGUgPSAvQW5kcm9pZHx3ZWJPU3xpUGhvbmV8aVBvZHxCbGFja0JlcnJ5fElFTW9iaWxlfE9wZXJhIE1pbmkvaS50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpXG4gICAgICAgICAgICByZXN1bHQuaXNUYWJsZXQgPSAvaVBhZHxBbmRyb2lkKD8hLipNb2JpbGUpL2kudGVzdChuYXZpZ2F0b3IudXNlckFnZW50KVxuICAgICAgICAgICAgcmVzdWx0LmlzRGVza3RvcCA9ICFyZXN1bHQuaXNNb2JpbGUgJiYgIXJlc3VsdC5pc1RhYmxldFxuICAgICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1tMdWEgVVRNXSBFcnJvciBnZXR0aW5nIHVzZXIgYWdlbnQ6JywgZSlcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gcmVzdWx0XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogSW5mZXIgdXNlciBpbnRlbnQgZnJvbSBjb250ZXh0XG4gICAgICogUHJpb3JpdHk6IFVUTSBjYW1wYWlnbiA+IFVUTSBzb3VyY2UgPiBSZWZlcnJlciBjYXRlZ29yeVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0IC0gRnVsbCBjb250ZXh0IG9iamVjdFxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IC0gSW5mZXJyZWQgaW50ZW50IGtleVxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGluZmVySW50ZW50KGNvbnRleHQpIHtcbiAgICAgICAgaWYgKGNvbnRleHQudXRtLnV0bV9jYW1wYWlnbikge1xuICAgICAgICAgICAgdmFyIGNhbXBhaWduID0gY29udGV4dC51dG0udXRtX2NhbXBhaWduLnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgIGlmICgvc2FsZXxkaXNjb3VudHxvZmZlcnxwcm9tby9pLnRlc3QoY2FtcGFpZ24pKSByZXR1cm4gJ3ByaWNlLWZvY3VzZWQnXG4gICAgICAgICAgICBpZiAoL2dhbWluZ3xnYW1lfGVzcG9ydC9pLnRlc3QoY2FtcGFpZ24pKSByZXR1cm4gJ2dhbWluZydcbiAgICAgICAgICAgIGlmICgvd29ya3xvZmZpY2V8cHJvZmVzc2lvbmFsfHByb2R1Y3Rpdml0eS9pLnRlc3QoY2FtcGFpZ24pKSByZXR1cm4gJ3Byb2Zlc3Npb25hbCdcbiAgICAgICAgICAgIGlmICgvY3JlYXRpdmV8ZGVzaWdufGFydHxzdHVkaW8vaS50ZXN0KGNhbXBhaWduKSkgcmV0dXJuICdjcmVhdGl2ZSdcbiAgICAgICAgICAgIGlmICgvYnJhbmR8c3Rvcnl8YWJvdXQvaS50ZXN0KGNhbXBhaWduKSkgcmV0dXJuICdicmFuZC1zdG9yeSdcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb250ZXh0LnV0bS51dG1fc291cmNlKSB7XG4gICAgICAgICAgICB2YXIgc291cmNlID0gY29udGV4dC51dG0udXRtX3NvdXJjZS50b0xvd2VyQ2FzZSgpXG4gICAgICAgICAgICBpZiAoL2dvb2dsZXxiaW5nfHlhaG9vL2kudGVzdChzb3VyY2UpKSByZXR1cm4gJ3NlYXJjaC1vcHRpbWl6ZWQnXG4gICAgICAgICAgICBpZiAoL2ZhY2Vib29rfGluc3RhZ3JhbXx0aWt0b2svaS50ZXN0KHNvdXJjZSkpIHJldHVybiAnc29jaWFsLXZpc3VhbCdcbiAgICAgICAgICAgIGlmICgvdHdpdHRlcnx4JC9pLnRlc3Qoc291cmNlKSkgcmV0dXJuICdzb2NpYWwtYnJpZWYnXG4gICAgICAgICAgICBpZiAoL2VtYWlsfG5ld3NsZXR0ZXIvaS50ZXN0KHNvdXJjZSkpIHJldHVybiAncmV0dXJuaW5nLXVzZXInXG4gICAgICAgICAgICBpZiAoL3lvdXR1YmUvaS50ZXN0KHNvdXJjZSkpIHJldHVybiAndmlkZW8tZW5nYWdlZCdcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChjb250ZXh0LnJlZmVycmVyLmNhdGVnb3J5ID09PSAnc2VhcmNoJykgcmV0dXJuICdzZWFyY2gtb3B0aW1pemVkJ1xuICAgICAgICBpZiAoY29udGV4dC5yZWZlcnJlci5jYXRlZ29yeSA9PT0gJ3NvY2lhbCcpIHJldHVybiAnc29jaWFsLXZpc3VhbCdcbiAgICAgICAgaWYgKGNvbnRleHQucmVmZXJyZXIuY2F0ZWdvcnkgPT09ICdlbWFpbCcpIHJldHVybiAncmV0dXJuaW5nLXVzZXInXG5cbiAgICAgICAgcmV0dXJuICdkZWZhdWx0J1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEJ1aWxkIGZ1bGwgcGVyc29uYWxpemF0aW9uIGNvbnRleHRcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIC0geyB1cmw6IHN0cmluZyB9XG4gICAgICogQHJldHVybnMge09iamVjdH0gLSBDb21wbGV0ZSBjb250ZXh0IG9iamVjdFxuICAgICAqL1xuICAgIGZ1bmN0aW9uIGdldENvbnRleHQob3B0aW9ucykge1xuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICAgICAgICB2YXIgY29udGV4dCA9IHtcbiAgICAgICAgICAgIHV0bTogZXh0cmFjdFVUTVBhcmFtcyhvcHRpb25zLnVybCksXG4gICAgICAgICAgICByZWZlcnJlcjogZGV0ZWN0UmVmZXJyZXIoKSxcbiAgICAgICAgICAgIHVzZXJBZ2VudDogZ2V0VXNlckFnZW50SW5mbygpLFxuICAgICAgICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpLFxuICAgICAgICAgICAgaGFzVVRNOiBmYWxzZSxcbiAgICAgICAgICAgIHByaW1hcnlJbnRlbnQ6ICd1bmtub3duJ1xuICAgICAgICB9XG4gICAgICAgIGNvbnRleHQuaGFzVVRNID0gT2JqZWN0LmtleXMoY29udGV4dC51dG0pLmxlbmd0aCA+IDBcbiAgICAgICAgY29udGV4dC5wcmltYXJ5SW50ZW50ID0gaW5mZXJJbnRlbnQoY29udGV4dClcbiAgICAgICAgcmV0dXJuIGNvbnRleHRcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBBc3luYyBjb250ZXh0IHdpdGggdGltZW91dCBmYWxsYmFjayAoMSBzZWNvbmQgbWF4KVxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9uc10gLSB7IHRpbWVvdXQ6IG51bWJlciwgdXJsOiBzdHJpbmcgfVxuICAgICAqIEByZXR1cm5zIHtQcm9taXNlPE9iamVjdD59IC0gQ29udGV4dCBvYmplY3RcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBnZXRDb250ZXh0QXN5bmMob3B0aW9ucykge1xuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICAgICAgICB2YXIgdGltZW91dCA9IG9wdGlvbnMudGltZW91dCB8fCBVVE1fVElNRU9VVF9NU1xuXG4gICAgICAgIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbiAocmVzb2x2ZSkge1xuICAgICAgICAgICAgdmFyIHRpbWVyID0gc2V0VGltZW91dChmdW5jdGlvbiAoKSB7XG4gICAgICAgICAgICAgICAgcmVzb2x2ZSh7XG4gICAgICAgICAgICAgICAgICAgIHV0bToge30sXG4gICAgICAgICAgICAgICAgICAgIHJlZmVycmVyOiB7IHNvdXJjZTogJ2RpcmVjdCcsIGNhdGVnb3J5OiAnZGlyZWN0JywgdXJsOiAnJyB9LFxuICAgICAgICAgICAgICAgICAgICB1c2VyQWdlbnQ6IHsgcmF3OiAnJywgaXNNb2JpbGU6IGZhbHNlLCBpc1RhYmxldDogZmFsc2UsIGlzRGVza3RvcDogdHJ1ZSB9LFxuICAgICAgICAgICAgICAgICAgICB0aW1lc3RhbXA6IERhdGUubm93KCksXG4gICAgICAgICAgICAgICAgICAgIGhhc1VUTTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHByaW1hcnlJbnRlbnQ6ICdkZWZhdWx0JyxcbiAgICAgICAgICAgICAgICAgICAgdGltZWRPdXQ6IHRydWVcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfSwgdGltZW91dClcblxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICB2YXIgY29udGV4dCA9IGdldENvbnRleHQob3B0aW9ucylcbiAgICAgICAgICAgICAgICBjbGVhclRpbWVvdXQodGltZXIpXG4gICAgICAgICAgICAgICAgY29udGV4dC50aW1lZE91dCA9IGZhbHNlXG4gICAgICAgICAgICAgICAgcmVzb2x2ZShjb250ZXh0KVxuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNsZWFyVGltZW91dCh0aW1lcilcbiAgICAgICAgICAgICAgICByZXNvbHZlKHtcbiAgICAgICAgICAgICAgICAgICAgdXRtOiB7fSxcbiAgICAgICAgICAgICAgICAgICAgcmVmZXJyZXI6IHsgc291cmNlOiAnZGlyZWN0JywgY2F0ZWdvcnk6ICdkaXJlY3QnLCB1cmw6ICcnIH0sXG4gICAgICAgICAgICAgICAgICAgIHVzZXJBZ2VudDogeyByYXc6ICcnLCBpc01vYmlsZTogZmFsc2UsIGlzVGFibGV0OiBmYWxzZSwgaXNEZXNrdG9wOiB0cnVlIH0sXG4gICAgICAgICAgICAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgICAgICAgICAgICAgaGFzVVRNOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgcHJpbWFyeUludGVudDogJ2RlZmF1bHQnLFxuICAgICAgICAgICAgICAgICAgICBlcnJvcjogZS5tZXNzYWdlXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSlcbiAgICB9XG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gMi4gRE9NUFVSSUZZLVNUWUxFIEhUTUwgU0FOSVRJWkVSXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgdmFyIFNhbml0aXplciA9IChmdW5jdGlvbiAoKSB7XG4gICAgICAgIHZhciBBTExPV0VEX1RBR1MgPSB7XG4gICAgICAgICAgICAncCc6IHRydWUsICdzcGFuJzogdHJ1ZSwgJ3N0cm9uZyc6IHRydWUsICdlbSc6IHRydWUsXG4gICAgICAgICAgICAnYic6IHRydWUsICdpJzogdHJ1ZSwgJ2JyJzogdHJ1ZSwgJ2EnOiB0cnVlLCAnaW1nJzogdHJ1ZSxcbiAgICAgICAgICAgICdoMSc6IHRydWUsICdoMic6IHRydWUsICdoMyc6IHRydWUsICdoNCc6IHRydWUsICdoNSc6IHRydWUsICdoNic6IHRydWUsXG4gICAgICAgICAgICAnZGl2JzogdHJ1ZSwgJ3NlY3Rpb24nOiB0cnVlLCAndWwnOiB0cnVlLCAnb2wnOiB0cnVlLCAnbGknOiB0cnVlLFxuICAgICAgICAgICAgJ2Jsb2NrcXVvdGUnOiB0cnVlLCAnZmlndXJlJzogdHJ1ZSwgJ2ZpZ2NhcHRpb24nOiB0cnVlXG4gICAgICAgIH1cblxuICAgICAgICB2YXIgQUxMT1dFRF9BVFRSUyA9IHtcbiAgICAgICAgICAgICdocmVmJzogdHJ1ZSwgJ3NyYyc6IHRydWUsICdhbHQnOiB0cnVlLCAnY2xhc3MnOiB0cnVlLFxuICAgICAgICAgICAgJ2lkJzogdHJ1ZSwgJ3RpdGxlJzogdHJ1ZSwgJ3RhcmdldCc6IHRydWUsICdyZWwnOiB0cnVlLFxuICAgICAgICAgICAgJ3dpZHRoJzogdHJ1ZSwgJ2hlaWdodCc6IHRydWUsICdsb2FkaW5nJzogdHJ1ZVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIERBTkdFUk9VU19VUkkgPSAvXihqYXZhc2NyaXB0fHZic2NyaXB0fGRhdGEpOi9pXG4gICAgICAgIHZhciBFVkVOVF9IQU5ETEVSID0gL15vbi9pXG5cbiAgICAgICAgZnVuY3Rpb24gaGFzRE9NUGFyc2VyKCkge1xuICAgICAgICAgICAgdHJ5IHsgcmV0dXJuIHR5cGVvZiBET01QYXJzZXIgIT09ICd1bmRlZmluZWQnICYmIG5ldyBET01QYXJzZXIoKSB9XG4gICAgICAgICAgICBjYXRjaCAoZSkgeyByZXR1cm4gZmFsc2UgfVxuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gZXNjYXBlVGV4dCh0ZXh0KSB7XG4gICAgICAgICAgICBpZiAoIXRleHQpIHJldHVybiAnJ1xuICAgICAgICAgICAgcmV0dXJuIHRleHQucmVwbGFjZSgvJi9nLCAnJmFtcDsnKS5yZXBsYWNlKC88L2csICcmbHQ7JykucmVwbGFjZSgvPi9nLCAnJmd0OycpXG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBlc2NhcGVBdHRyKHZhbHVlKSB7XG4gICAgICAgICAgICBpZiAoIXZhbHVlKSByZXR1cm4gJydcbiAgICAgICAgICAgIHJldHVybiB2YWx1ZS5yZXBsYWNlKC8mL2csICcmYW1wOycpLnJlcGxhY2UoL1wiL2csICcmcXVvdDsnKS5yZXBsYWNlKC8nL2csICcmIzM5OycpLnJlcGxhY2UoLzwvZywgJyZsdDsnKS5yZXBsYWNlKC8+L2csICcmZ3Q7JylcbiAgICAgICAgfVxuXG4gICAgICAgIGZ1bmN0aW9uIGNsZWFuQXR0cmlidXRlcyhlbGVtZW50KSB7XG4gICAgICAgICAgICB2YXIgYXR0clN0ciA9ICcnXG4gICAgICAgICAgICB2YXIgYXR0cnMgPSBlbGVtZW50LmF0dHJpYnV0ZXNcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgYXR0cnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICB2YXIgbmFtZSA9IGF0dHJzW2ldLm5hbWUudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgICAgIHZhciB2YWx1ZSA9IGF0dHJzW2ldLnZhbHVlXG4gICAgICAgICAgICAgICAgaWYgKEVWRU5UX0hBTkRMRVIudGVzdChuYW1lKSkgY29udGludWVcbiAgICAgICAgICAgICAgICBpZiAoIUFMTE9XRURfQVRUUlNbbmFtZV0pIGNvbnRpbnVlXG4gICAgICAgICAgICAgICAgaWYgKChuYW1lID09PSAnaHJlZicgfHwgbmFtZSA9PT0gJ3NyYycpICYmIERBTkdFUk9VU19VUkkudGVzdCh2YWx1ZS50cmltKCkpKSBjb250aW51ZVxuICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSAndGFyZ2V0JyAmJiB2YWx1ZSA9PT0gJ19ibGFuaycpIHtcbiAgICAgICAgICAgICAgICAgICAgYXR0clN0ciArPSAnIHRhcmdldD1cIl9ibGFua1wiIHJlbD1cIm5vb3BlbmVyIG5vcmVmZXJyZXJcIidcbiAgICAgICAgICAgICAgICAgICAgY29udGludWVcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgYXR0clN0ciArPSAnICcgKyBuYW1lICsgJz1cIicgKyBlc2NhcGVBdHRyKHZhbHVlKSArICdcIidcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBhdHRyU3RyXG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiB3YWxrQW5kQ2xlYW4obm9kZSkge1xuICAgICAgICAgICAgdmFyIG91dHB1dCA9ICcnXG4gICAgICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IG5vZGUuY2hpbGROb2Rlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBjaGlsZCA9IG5vZGUuY2hpbGROb2Rlc1tpXVxuICAgICAgICAgICAgICAgIGlmIChjaGlsZC5ub2RlVHlwZSA9PT0gMykgeyBvdXRwdXQgKz0gZXNjYXBlVGV4dChjaGlsZC50ZXh0Q29udGVudCk7IGNvbnRpbnVlIH1cbiAgICAgICAgICAgICAgICBpZiAoY2hpbGQubm9kZVR5cGUgPT09IDEpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIHRhZyA9IGNoaWxkLnRhZ05hbWUudG9Mb3dlckNhc2UoKVxuICAgICAgICAgICAgICAgICAgICBpZiAodGFnID09PSAnc2NyaXB0JyB8fCB0YWcgPT09ICdzdHlsZScgfHwgdGFnID09PSAnaWZyYW1lJyB8fCB0YWcgPT09ICdvYmplY3QnIHx8IHRhZyA9PT0gJ2VtYmVkJyB8fCB0YWcgPT09ICdmb3JtJyB8fCB0YWcgPT09ICdpbnB1dCcgfHwgdGFnID09PSAndGV4dGFyZWEnKSBjb250aW51ZVxuICAgICAgICAgICAgICAgICAgICBpZiAoQUxMT1dFRF9UQUdTW3RhZ10pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dCArPSAnPCcgKyB0YWcgKyBjbGVhbkF0dHJpYnV0ZXMoY2hpbGQpICsgJz4nXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodGFnICE9PSAnYnInICYmIHRhZyAhPT0gJ2ltZycpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQgKz0gd2Fsa0FuZENsZWFuKGNoaWxkKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dHB1dCArPSAnPC8nICsgdGFnICsgJz4nXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvdXRwdXQgKz0gd2Fsa0FuZENsZWFuKGNoaWxkKVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIG91dHB1dFxuICAgICAgICB9XG5cbiAgICAgICAgZnVuY3Rpb24gc2FuaXRpemVXaXRoRE9NUGFyc2VyKGRpcnR5KSB7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIHZhciBkb2MgPSBuZXcgRE9NUGFyc2VyKCkucGFyc2VGcm9tU3RyaW5nKGRpcnR5LCAndGV4dC9odG1sJylcbiAgICAgICAgICAgICAgICByZXR1cm4gZG9jLmJvZHkgPyB3YWxrQW5kQ2xlYW4oZG9jLmJvZHkpIDogJydcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4gc2FuaXRpemVXaXRoUmVnZXgoZGlydHkpXG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBmdW5jdGlvbiBzYW5pdGl6ZVdpdGhSZWdleChodG1sKSB7XG4gICAgICAgICAgICB2YXIgcGF0dGVybnMgPSBbXG4gICAgICAgICAgICAgICAgLzxzY3JpcHRcXGJbXjxdKig/Oig/ITxcXC9zY3JpcHQ+KTxbXjxdKikqPFxcL3NjcmlwdD4vZ2ksXG4gICAgICAgICAgICAgICAgLzxpZnJhbWVcXGJbXjxdKig/Oig/ITxcXC9pZnJhbWU+KTxbXjxdKikqPFxcL2lmcmFtZT4vZ2ksXG4gICAgICAgICAgICAgICAgLzxvYmplY3RcXGJbXjxdKig/Oig/ITxcXC9vYmplY3Q+KTxbXjxdKikqPFxcL29iamVjdD4vZ2ksXG4gICAgICAgICAgICAgICAgLzxlbWJlZFxcYltePl0qPi9naSwgLzxsaW5rXFxiW14+XSo+L2dpLFxuICAgICAgICAgICAgICAgIC88c3R5bGVcXGJbXjxdKig/Oig/ITxcXC9zdHlsZT4pPFtePF0qKSo8XFwvc3R5bGU+L2dpLFxuICAgICAgICAgICAgICAgIC88Zm9ybVxcYltePF0qKD86KD8hPFxcL2Zvcm0+KTxbXjxdKikqPFxcL2Zvcm0+L2dpLFxuICAgICAgICAgICAgICAgIC9qYXZhc2NyaXB0Oi9naSwgL3Zic2NyaXB0Oi9naSwgL2RhdGE6L2dpLCAvb25cXHcrXFxzKj0vZ2lcbiAgICAgICAgICAgIF1cbiAgICAgICAgICAgIHZhciBzYW5pdGl6ZWQgPSBodG1sXG4gICAgICAgICAgICBwYXR0ZXJucy5mb3JFYWNoKGZ1bmN0aW9uIChwKSB7IHNhbml0aXplZCA9IHNhbml0aXplZC5yZXBsYWNlKHAsICcnKSB9KVxuICAgICAgICAgICAgc2FuaXRpemVkID0gc2FuaXRpemVkLnJlcGxhY2UoLzxcXC8/KFxcdyspKFtePl0qKT4vZywgZnVuY3Rpb24gKG1hdGNoLCB0YWdOYW1lLCBhdHRycykge1xuICAgICAgICAgICAgICAgIHZhciB0YWcgPSB0YWdOYW1lLnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgICAgICBpZiAoIUFMTE9XRURfVEFHU1t0YWddKSByZXR1cm4gJydcbiAgICAgICAgICAgICAgICBpZiAobWF0Y2guY2hhckF0KDEpID09PSAnLycpIHJldHVybiAnPC8nICsgdGFnICsgJz4nXG4gICAgICAgICAgICAgICAgdmFyIGNsZWFuQXR0cnMgPSAnJ1xuICAgICAgICAgICAgICAgIHZhciByZSA9IC8oXFx3Kyk9WydcIl0oW14nXCJdKilbJ1wiXS9nXG4gICAgICAgICAgICAgICAgdmFyIG1cbiAgICAgICAgICAgICAgICB3aGlsZSAoKG0gPSByZS5leGVjKGF0dHJzKSkgIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgICAgICAgdmFyIG4gPSBtWzFdLnRvTG93ZXJDYXNlKClcbiAgICAgICAgICAgICAgICAgICAgaWYgKEFMTE9XRURfQVRUUlNbbl0gJiYgIUVWRU5UX0hBTkRMRVIudGVzdChuKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKChuID09PSAnaHJlZicgfHwgbiA9PT0gJ3NyYycpICYmIERBTkdFUk9VU19VUkkudGVzdChtWzJdKSkgY29udGludWVcbiAgICAgICAgICAgICAgICAgICAgICAgIGNsZWFuQXR0cnMgKz0gJyAnICsgbiArICc9XCInICsgbVsyXSArICdcIidcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4gJzwnICsgdGFnICsgY2xlYW5BdHRycyArICc+J1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIHJldHVybiBzYW5pdGl6ZWRcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICBzYW5pdGl6ZTogZnVuY3Rpb24gKGRpcnR5KSB7XG4gICAgICAgICAgICAgICAgaWYgKHR5cGVvZiBkaXJ0eSAhPT0gJ3N0cmluZycgfHwgIWRpcnR5LnRyaW0oKSkgcmV0dXJuICcnXG4gICAgICAgICAgICAgICAgcmV0dXJuIGhhc0RPTVBhcnNlcigpID8gc2FuaXRpemVXaXRoRE9NUGFyc2VyKGRpcnR5KSA6IHNhbml0aXplV2l0aFJlZ2V4KGRpcnR5KVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGVzY2FwZVRleHQ6IGVzY2FwZVRleHQsXG4gICAgICAgICAgICBlc2NhcGVBdHRyOiBlc2NhcGVBdHRyXG4gICAgICAgIH1cbiAgICB9KSgpXG5cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG4gICAgLy8gMy4gVEVNUExBVEVTICYgQVNTRVRTXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIE5PVEU6IFRlbXBsYXRlcyBhcmUgTk9UIHByb3ZpZGVkIGJ5IHRoaXMgcGFja2FnZS5cbiAgICAvLyBVc2VycyBtdXN0IHByb3ZpZGUgdGhlaXIgb3duIHRlbXBsYXRlcyB2aWEgb3B0aW9ucy50ZW1wbGF0ZXNcbiAgICAvLyBUaGlzIGtlZXBzIHRoZSBwYWNrYWdlIG1vZHVsYXIgYW5kIGFsbG93cyB1c2VycyBmdWxsIGNvbnRyb2xcbiAgICAvLyBvdmVyIHRoZWlyIGNvbnRlbnQsIGFzc2V0cywgYW5kIHBlcnNvbmFsaXphdGlvbiBzdHJhdGVneS5cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyA0LiBET00gUEVSU09OQUxJWkFUSU9OIEVOR0lORVxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIGZ1bmN0aW9uIHNhZmVTZXRUZXh0KGVsZW1lbnQsIHRleHQpIHtcbiAgICAgICAgaWYgKCFlbGVtZW50KSByZXR1cm5cbiAgICAgICAgZWxlbWVudC50ZXh0Q29udGVudCA9IHRleHRcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBzYWZlU2V0SFRNTChlbGVtZW50LCBodG1sKSB7XG4gICAgICAgIGlmICghZWxlbWVudCkgcmV0dXJuXG4gICAgICAgIGVsZW1lbnQuaW5uZXJIVE1MID0gU2FuaXRpemVyLnNhbml0aXplKGh0bWwpXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZmluZFBlcnNvbmFsaXplRWxlbWVudHMoa2V5LCBzZWFyY2hSb290KSB7XG4gICAgICAgIHNlYXJjaFJvb3QgPSBzZWFyY2hSb290IHx8ICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnID8gZG9jdW1lbnQgOiBudWxsKVxuICAgICAgICBpZiAoIXNlYXJjaFJvb3QpIHJldHVybiBbXVxuICAgICAgICB2YXIgc2VsZWN0b3IgPSBrZXkgPyAnW2RhdGEtcGVyc29uYWxpemU9XCInICsga2V5ICsgJ1wiXScgOiAnW2RhdGEtcGVyc29uYWxpemVdJ1xuICAgICAgICByZXR1cm4gc2VhcmNoUm9vdC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKVxuICAgIH1cblxuICAgIGZ1bmN0aW9uIGdldFRlbXBsYXRlKGludGVudCwgdXNlclRlbXBsYXRlcykge1xuICAgICAgICBpZiAoIXVzZXJUZW1wbGF0ZXMgfHwgdHlwZW9mIHVzZXJUZW1wbGF0ZXMgIT09ICdvYmplY3QnKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1tMdWEgUGVyc29uYWxpemVdIE5vIHRlbXBsYXRlcyBwcm92aWRlZC4gVGVtcGxhdGVzIG11c3QgYmUgcGFzc2VkIHZpYSBvcHRpb25zLnRlbXBsYXRlcycpXG4gICAgICAgICAgICByZXR1cm4gbnVsbFxuICAgICAgICB9XG4gICAgICAgIGlmICh1c2VyVGVtcGxhdGVzW2ludGVudF0pIHJldHVybiB1c2VyVGVtcGxhdGVzW2ludGVudF1cbiAgICAgICAgaWYgKHVzZXJUZW1wbGF0ZXNbJ2RlZmF1bHQnXSkgcmV0dXJuIHVzZXJUZW1wbGF0ZXNbJ2RlZmF1bHQnXVxuICAgICAgICB2YXIgZmlyc3RLZXkgPSBPYmplY3Qua2V5cyh1c2VyVGVtcGxhdGVzKVswXVxuICAgICAgICBpZiAoZmlyc3RLZXkpIHtcbiAgICAgICAgICAgIGNvbnNvbGUud2FybignW0x1YSBQZXJzb25hbGl6ZV0gSW50ZW50IFwiJyArIGludGVudCArICdcIiBub3QgZm91bmQsIHVzaW5nIGZpcnN0IGF2YWlsYWJsZSB0ZW1wbGF0ZTonLCBmaXJzdEtleSlcbiAgICAgICAgICAgIHJldHVybiB1c2VyVGVtcGxhdGVzW2ZpcnN0S2V5XVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBudWxsXG4gICAgfVxuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIDUuIFJBTkRPTSBBL0IgRkFMTEJBQ0tcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgICBmdW5jdGlvbiBjaG9vc2VXZWlnaHRlZFJhbmRvbShuYW1lcywgd2VpZ2h0cykge1xuICAgICAgICBpZiAobmFtZXMubGVuZ3RoICE9PSB3ZWlnaHRzLmxlbmd0aCkgcmV0dXJuIG5hbWVzWzBdXG4gICAgICAgIHZhciBzdW0gPSAwXG4gICAgICAgIHZhciBpXG4gICAgICAgIGZvciAoaSA9IDA7IGkgPCB3ZWlnaHRzLmxlbmd0aDsgaSsrKSB7IHN1bSArPSB3ZWlnaHRzW2ldIH1cbiAgICAgICAgdmFyIG4gPSBNYXRoLnJhbmRvbSgpICogc3VtXG4gICAgICAgIHZhciBsaW1pdCA9IDBcbiAgICAgICAgZm9yIChpID0gMDsgaSA8IG5hbWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICBsaW1pdCArPSB3ZWlnaHRzW2ldXG4gICAgICAgICAgICBpZiAobiA8PSBsaW1pdCkgcmV0dXJuIG5hbWVzW2ldXG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIG5hbWVzW25hbWVzLmxlbmd0aCAtIDFdXG4gICAgfVxuXG4gICAgZnVuY3Rpb24gZ2V0UmFuZG9tRmFsbGJhY2tJbnRlbnQodXNlclRlbXBsYXRlcykge1xuICAgICAgICBpZiAoIXVzZXJUZW1wbGF0ZXMgfHwgdHlwZW9mIHVzZXJUZW1wbGF0ZXMgIT09ICdvYmplY3QnKSByZXR1cm4gbnVsbFxuICAgICAgICB2YXIgbmFtZXMgPSBPYmplY3Qua2V5cyh1c2VyVGVtcGxhdGVzKVxuICAgICAgICBpZiAobmFtZXMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbFxuICAgICAgICB2YXIgd2VpZ2h0cyA9IFtdXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgbmFtZXMubGVuZ3RoOyBpKyspIHsgd2VpZ2h0cy5wdXNoKDEpIH1cbiAgICAgICAgcmV0dXJuIGNob29zZVdlaWdodGVkUmFuZG9tKG5hbWVzLCB3ZWlnaHRzKVxuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyA2LiBERUNJU0lPTiBFTkdJTkVcbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgICB2YXIgRGVjaXNpb25FbmdpbmUgPSB7XG4gICAgICAgIC8qKlxuICAgICAgICAgKiBTdGFuZGFyZCAobm9uLUFJKSBkZWNpc2lvbiBsb2dpY1xuICAgICAgICAgKiBQcmlvcml0eTogQ3VzdG9tIHJ1bGVzID4gVVRNIHBhcmFtcyA+IFJlZmVycmVyID4gUmFuZG9tIEEvQlxuICAgICAgICAgKi9cbiAgICAgICAgc3RhbmRhcmREZWNpZGU6IGZ1bmN0aW9uIChjb250ZXh0LCBvcHRpb25zKSB7XG4gICAgICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuICAgICAgICAgICAgdmFyIGN1c3RvbVJ1bGVzID0gb3B0aW9ucy5ydWxlcyB8fCB7fVxuICAgICAgICAgICAgdmFyIHVzZXJUZW1wbGF0ZXMgPSBvcHRpb25zLnRlbXBsYXRlc1xuICAgICAgICAgICAgdmFyIGVuYWJsZVJhbmRvbUZhbGxiYWNrID0gb3B0aW9ucy5yYW5kb21GYWxsYmFjayAhPT0gZmFsc2VcblxuICAgICAgICAgICAgaWYgKCF1c2VyVGVtcGxhdGVzIHx8IHR5cGVvZiB1c2VyVGVtcGxhdGVzICE9PSAnb2JqZWN0JyB8fCBPYmplY3Qua2V5cyh1c2VyVGVtcGxhdGVzKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1tMdWEgUGVyc29uYWxpemVdIE5vIHRlbXBsYXRlcyBwcm92aWRlZC4gVGVtcGxhdGVzIG11c3QgYmUgcGFzc2VkIHZpYSBvcHRpb25zLnRlbXBsYXRlcycpXG4gICAgICAgICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGU6IG51bGwsXG4gICAgICAgICAgICAgICAgICAgIGludGVudDogJ2RlZmF1bHQnLFxuICAgICAgICAgICAgICAgICAgICBzb3VyY2U6ICdlcnJvcicsXG4gICAgICAgICAgICAgICAgICAgIGNvbnRleHQ6IGNvbnRleHQsXG4gICAgICAgICAgICAgICAgICAgIGVycm9yOiAnTm8gdGVtcGxhdGVzIHByb3ZpZGVkJ1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgdmFyIGludGVudCA9IGNvbnRleHQucHJpbWFyeUludGVudFxuICAgICAgICAgICAgdmFyIHNvdXJjZSA9ICdkZWZhdWx0J1xuXG4gICAgICAgICAgICBpZiAoY29udGV4dC5oYXNVVE0pIHtcbiAgICAgICAgICAgICAgICBzb3VyY2UgPSAndXRtJ1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjb250ZXh0LnJlZmVycmVyICYmIGNvbnRleHQucmVmZXJyZXIuY2F0ZWdvcnkgIT09ICdkaXJlY3QnKSB7XG4gICAgICAgICAgICAgICAgc291cmNlID0gJ3JlZmVycmVyJ1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmb3IgKHZhciBydWxlS2V5IGluIGN1c3RvbVJ1bGVzKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJ1bGUgPSBjdXN0b21SdWxlc1tydWxlS2V5XVxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgcnVsZS5tYXRjaCA9PT0gJ2Z1bmN0aW9uJyAmJiBydWxlLm1hdGNoKGNvbnRleHQpKSB7XG4gICAgICAgICAgICAgICAgICAgIGludGVudCA9IHJ1bGUuaW50ZW50IHx8IHJ1bGVLZXlcbiAgICAgICAgICAgICAgICAgICAgc291cmNlID0gJ2N1c3RvbS1ydWxlJ1xuICAgICAgICAgICAgICAgICAgICBicmVha1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKGludGVudCA9PT0gJ2RlZmF1bHQnICYmIHNvdXJjZSA9PT0gJ2RlZmF1bHQnICYmIGVuYWJsZVJhbmRvbUZhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgdmFyIHJhbmRvbUludGVudCA9IGdldFJhbmRvbUZhbGxiYWNrSW50ZW50KHVzZXJUZW1wbGF0ZXMpXG4gICAgICAgICAgICAgICAgaWYgKHJhbmRvbUludGVudCkge1xuICAgICAgICAgICAgICAgICAgICBpbnRlbnQgPSByYW5kb21JbnRlbnRcbiAgICAgICAgICAgICAgICAgICAgc291cmNlID0gJ3JhbmRvbS1hYidcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFJlY29yZCB2aXNpdCB0byBoaXN0b3J5IGlmIGF2YWlsYWJsZVxuICAgICAgICAgICAgaWYgKHJvb3QuTHVhV2VpZ2h0ZWRIaXN0b3J5ICYmIHR5cGVvZiByb290Lkx1YVdlaWdodGVkSGlzdG9yeS5yZWNvcmRWaXNpdCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICAgIHJvb3QuTHVhV2VpZ2h0ZWRIaXN0b3J5LnJlY29yZFZpc2l0KHtcbiAgICAgICAgICAgICAgICAgICAgY29udGV4dDogY29udGV4dCxcbiAgICAgICAgICAgICAgICAgICAgaW50ZW50OiBpbnRlbnQsXG4gICAgICAgICAgICAgICAgICAgIHNlbGVjdGVkVmFyaWFudDogaW50ZW50LFxuICAgICAgICAgICAgICAgICAgICBzb3VyY2U6IHNvdXJjZSxcbiAgICAgICAgICAgICAgICAgICAgYWlEZWNpc2lvbjogZmFsc2VcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHRlbXBsYXRlOiBnZXRUZW1wbGF0ZShpbnRlbnQsIHVzZXJUZW1wbGF0ZXMpLFxuICAgICAgICAgICAgICAgIGludGVudDogaW50ZW50LFxuICAgICAgICAgICAgICAgIHNvdXJjZTogc291cmNlLFxuICAgICAgICAgICAgICAgIGNvbnRleHQ6IGNvbnRleHRcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSxcblxuICAgICAgICAvKipcbiAgICAgICAgICogTWFpbiBkZWNpZGUgZnVuY3Rpb24gLSByb3V0ZXMgdG8gQUkgb3Igc3RhbmRhcmQgZW5naW5lXG4gICAgICAgICAqIEBwYXJhbSB7T2JqZWN0fSBjb250ZXh0IC0gVVRNIGNvbnRleHRcbiAgICAgICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zXSAtIENvbmZpZ3VyYXRpb24gb3B0aW9uc1xuICAgICAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmVuYWJsZUFJXSAtIEVuYWJsZSBBSS1wb3dlcmVkIGRlY2lzaW9uc1xuICAgICAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnMuYWlDb25maWddIC0gQUkgY29uZmlndXJhdGlvblxuICAgICAgICAgKiBAcmV0dXJucyB7T2JqZWN0fFByb21pc2U8T2JqZWN0Pn0gLSBEZWNpc2lvbiByZXN1bHRcbiAgICAgICAgICovXG4gICAgICAgIGRlY2lkZTogZnVuY3Rpb24gKGNvbnRleHQsIG9wdGlvbnMpIHtcbiAgICAgICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG5cbiAgICAgICAgICAgIC8vIElmIEFJIGlzIGVuYWJsZWQgYW5kIGNvbmZpZ3VyZWQsIHRyeSBBSSBkZWNpc2lvbiBmaXJzdFxuICAgICAgICAgICAgaWYgKG9wdGlvbnMuZW5hYmxlQUkgJiYgb3B0aW9ucy5haUNvbmZpZyAmJiByb290Lkx1YUFJUGVyc29uYWxpemUpIHtcbiAgICAgICAgICAgICAgICB2YXIgc2VsZiA9IHRoaXNcbiAgICAgICAgICAgICAgICB2YXIgYWlNb2R1bGUgPSByb290Lkx1YUFJUGVyc29uYWxpemVcbiAgICAgICAgICAgICAgICB2YXIgcmVhZGluZXNzID0gYWlNb2R1bGUuaXNSZWFkeShvcHRpb25zLmFpQ29uZmlnKVxuXG4gICAgICAgICAgICAgICAgaWYgKHJlYWRpbmVzcy5yZWFkeSkge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYWlNb2R1bGUuZGVjaWRlKGNvbnRleHQsIG9wdGlvbnMpXG4gICAgICAgICAgICAgICAgICAgICAgICAuY2F0Y2goZnVuY3Rpb24gKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyIGZhbGxiYWNrID0gb3B0aW9ucy5haUNvbmZpZy5mYWxsYmFja1RvU3RhbmRhcmQgIT09IGZhbHNlXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGZhbGxiYWNrKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybignW0x1YSBQZXJzb25hbGl6ZV0gQUkgZmFpbGVkLCB1c2luZyBzdGFuZGFyZCBlbmdpbmU6JywgZXJyb3IubWVzc2FnZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHNlbGYuc3RhbmRhcmREZWNpZGUoY29udGV4dCwgb3B0aW9ucylcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgZXJyb3JcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKCdbTHVhIFBlcnNvbmFsaXplXSBBSSBub3QgcmVhZHk6JywgcmVhZGluZXNzLmVycm9yLCAnLSB1c2luZyBzdGFuZGFyZCBlbmdpbmUnKVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuc3RhbmRhcmREZWNpZGUoY29udGV4dCwgb3B0aW9ucylcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyA3LiBET00gQVBQTElDQVRJT04gKGV4dHJhY3RlZCBmb3IgcmV1c2UpXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgLyoqXG4gICAgICogQXBwbHkgYSBkZWNpc2lvbiB0byB0aGUgRE9NXG4gICAgICogQHBhcmFtIHtPYmplY3R9IGRlY2lzaW9uIC0gRGVjaXNpb24gb2JqZWN0IHsgdGVtcGxhdGUsIGludGVudCwgc291cmNlLCBjb250ZXh0IH1cbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIC0gQ29uZmlndXJhdGlvbiBvcHRpb25zXG4gICAgICogQHJldHVybnMge09iamVjdH0gLSBUaGUgZGVjaXNpb24gKHBhc3MtdGhyb3VnaClcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBhcHBseURlY2lzaW9uVG9ET00oZGVjaXNpb24sIG9wdGlvbnMpIHtcbiAgICAgICAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge31cbiAgICAgICAgdmFyIHRlbXBsYXRlID0gZGVjaXNpb24udGVtcGxhdGVcbiAgICAgICAgdmFyIGNvbnRleHQgPSBkZWNpc2lvbi5jb250ZXh0IHx8IHt9XG4gICAgICAgIHZhciBsb2cgPSBvcHRpb25zLmxvZyAhPT0gZmFsc2VcblxuICAgICAgICBpZiAoIXRlbXBsYXRlKSB7XG4gICAgICAgICAgICBjb25zb2xlLndhcm4oJ1tMdWEgUGVyc29uYWxpemVdIE5vIHRlbXBsYXRlIGluIGRlY2lzaW9uLCBza2lwcGluZyBET00gdXBkYXRlJylcbiAgICAgICAgICAgIHJldHVybiBkZWNpc2lvblxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIHNsb3RzID0gWydpbWFnZScsICdoZWFkbGluZScsICdzdWJoZWFkbGluZScsICdjdGFMYWJlbCcsICdjdGFMaW5rJ11cblxuICAgICAgICBzbG90cy5mb3JFYWNoKGZ1bmN0aW9uIChzbG90KSB7XG4gICAgICAgICAgICB2YXIgZWxlbWVudHMgPSBmaW5kUGVyc29uYWxpemVFbGVtZW50cyhzbG90KVxuICAgICAgICAgICAgZm9yICh2YXIgaSA9IDA7IGkgPCBlbGVtZW50cy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgICAgIHZhciBlbCA9IGVsZW1lbnRzW2ldXG4gICAgICAgICAgICAgICAgdmFyIHZhbHVlID0gdGVtcGxhdGVbc2xvdF1cbiAgICAgICAgICAgICAgICBpZiAoIXZhbHVlKSBjb250aW51ZVxuXG4gICAgICAgICAgICAgICAgaWYgKHNsb3QgPT09ICdpbWFnZScpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGVsLnRhZ05hbWUgPT09ICdJTUcnKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBlbC5zcmMgPSB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgZWwuYWx0ID0gdGVtcGxhdGUuaGVhZGxpbmUgfHwgJ1BlcnNvbmFsaXplZCBpbWFnZSdcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGVsLnN0eWxlLmJhY2tncm91bmRJbWFnZSA9ICd1cmwoJyArIHZhbHVlICsgJyknXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKHNsb3QgPT09ICdjdGFMaW5rJykge1xuICAgICAgICAgICAgICAgICAgICBlbC5ocmVmID0gdmFsdWVcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzYWZlU2V0VGV4dChlbCwgdmFsdWUpXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9KVxuXG4gICAgICAgIC8vIEFwcGx5IHRvIGRhdGEtcGVyc29uYWxpemU9XCJoZXJvXCIgZWxlbWVudHNcbiAgICAgICAgdmFyIGhlcm9FbGVtZW50cyA9IGZpbmRQZXJzb25hbGl6ZUVsZW1lbnRzKCdoZXJvJylcbiAgICAgICAgZm9yICh2YXIgaCA9IDA7IGggPCBoZXJvRWxlbWVudHMubGVuZ3RoOyBoKyspIHtcbiAgICAgICAgICAgIHZhciBoZXJvRWwgPSBoZXJvRWxlbWVudHNbaF1cbiAgICAgICAgICAgIGhlcm9FbC5zZXRBdHRyaWJ1dGUoJ2RhdGEtaW50ZW50JywgZGVjaXNpb24uaW50ZW50KVxuICAgICAgICAgICAgaGVyb0VsLnNldEF0dHJpYnV0ZSgnZGF0YS1zb3VyY2UnLCBkZWNpc2lvbi5zb3VyY2UpXG4gICAgICAgICAgICBpZiAodGVtcGxhdGUuaW1hZ2UgJiYgIWhlcm9FbC5xdWVyeVNlbGVjdG9yKCdbZGF0YS1wZXJzb25hbGl6ZT1cImltYWdlXCJdJykpIHtcbiAgICAgICAgICAgICAgICBoZXJvRWwuc3R5bGUuYmFja2dyb3VuZEltYWdlID0gJ3VybCgnICsgdGVtcGxhdGUuaW1hZ2UgKyAnKSdcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChsb2cgJiYgdHlwZW9mIGNvbnNvbGUgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBjb25zb2xlLmxvZygnW0x1YSBQZXJzb25hbGl6ZV0gQXBwbGllZDonLCB7XG4gICAgICAgICAgICAgICAgaW50ZW50OiBkZWNpc2lvbi5pbnRlbnQsXG4gICAgICAgICAgICAgICAgc291cmNlOiBkZWNpc2lvbi5zb3VyY2UsXG4gICAgICAgICAgICAgICAgaGVhZGxpbmU6IHRlbXBsYXRlLmhlYWRsaW5lLFxuICAgICAgICAgICAgICAgIGhhc1VUTTogY29udGV4dC5oYXNVVE0sXG4gICAgICAgICAgICAgICAgdXRtUGFyYW1zOiBjb250ZXh0LnV0bSB8fCB7fSxcbiAgICAgICAgICAgICAgICBhaVBvd2VyZWQ6IGRlY2lzaW9uLnNvdXJjZSA9PT0gJ2FpJyB8fCBkZWNpc2lvbi5zb3VyY2UgPT09ICdhaS1jYWNoZWQnXG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGRlY2lzaW9uXG4gICAgfVxuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIDguIE1BSU4gUEVSU09OQUxJWkFUSU9OIEZVTkNUSU9OXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG4gICAgLyoqXG4gICAgICogQXBwbHkgcGVyc29uYWxpemF0aW9uIHRvIHRoZSBwYWdlXG4gICAgICogU2NhbnMgZm9yIGRhdGEtcGVyc29uYWxpemUgYXR0cmlidXRlcyBhbmQgaW5qZWN0cyBjb250ZW50XG4gICAgICogU3VwcG9ydHMgQUktcG93ZXJlZCBkZWNpc2lvbnMgd2hlbiBlbmFibGVBSSBpcyB0cnVlXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge09iamVjdH0gW29wdGlvbnNdIC0gQ29uZmlndXJhdGlvblxuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5jb250ZXh0XSAtIFByZS1jb21wdXRlZCBjb250ZXh0XG4gICAgICogQHBhcmFtIHtPYmplY3R9IFtvcHRpb25zLnJ1bGVzXSAtIEN1c3RvbSBydWxlc1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBvcHRpb25zLnRlbXBsYXRlcyAtIFVzZXItcHJvdmlkZWQgdGVtcGxhdGVzIChSRVFVSVJFRClcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmVuYWJsZUFJXSAtIEVuYWJsZSBBSS1wb3dlcmVkIGRlY2lzaW9uc1xuICAgICAqIEBwYXJhbSB7T2JqZWN0fSBbb3B0aW9ucy5haUNvbmZpZ10gLSBBSSBjb25maWd1cmF0aW9uXG4gICAgICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5yYW5kb21GYWxsYmFja10gLSBFbmFibGUgcmFuZG9tIEEvQiAoZGVmYXVsdDogdHJ1ZSlcbiAgICAgKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLmxvZ10gLSBFbmFibGUgbG9nZ2luZyAoZGVmYXVsdDogdHJ1ZSlcbiAgICAgKiBAcmV0dXJucyB7T2JqZWN0fFByb21pc2U8T2JqZWN0Pn0gLSBEZWNpc2lvbiByZXN1bHQgKFByb21pc2UgaWYgQUkgZW5hYmxlZClcbiAgICAgKi9cbiAgICBmdW5jdGlvbiBwZXJzb25hbGl6ZShvcHRpb25zKSB7XG4gICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG5cbiAgICAgICAgLy8gVGVtcGxhdGVzIGFyZSByZXF1aXJlZFxuICAgICAgICBpZiAoIW9wdGlvbnMudGVtcGxhdGVzIHx8IHR5cGVvZiBvcHRpb25zLnRlbXBsYXRlcyAhPT0gJ29iamVjdCcgfHwgT2JqZWN0LmtleXMob3B0aW9ucy50ZW1wbGF0ZXMpLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignW0x1YSBQZXJzb25hbGl6ZV0gVGVtcGxhdGVzIGFyZSByZXF1aXJlZC4gUHJvdmlkZSB0ZW1wbGF0ZXMgdmlhIG9wdGlvbnMudGVtcGxhdGVzJylcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdGVtcGxhdGU6IG51bGwsXG4gICAgICAgICAgICAgICAgaW50ZW50OiAnZGVmYXVsdCcsXG4gICAgICAgICAgICAgICAgc291cmNlOiAnZXJyb3InLFxuICAgICAgICAgICAgICAgIGNvbnRleHQ6IHt9LFxuICAgICAgICAgICAgICAgIGVycm9yOiAnTm8gdGVtcGxhdGVzIHByb3ZpZGVkJ1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdmFyIGNvbnRleHQgPSBvcHRpb25zLmNvbnRleHQgfHwgZ2V0Q29udGV4dChvcHRpb25zKVxuICAgICAgICB2YXIgZGVjaXNpb24gPSBEZWNpc2lvbkVuZ2luZS5kZWNpZGUoY29udGV4dCwgb3B0aW9ucylcblxuICAgICAgICAvLyBJZiBkZWNpc2lvbiBpcyBhIFByb21pc2UgKEFJIHBhdGgpLCBoYW5kbGUgYXN5bmNcbiAgICAgICAgaWYgKGRlY2lzaW9uICYmIHR5cGVvZiBkZWNpc2lvbi50aGVuID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVjaXNpb24udGhlbihmdW5jdGlvbiAoYWlEZWNpc2lvbikge1xuICAgICAgICAgICAgICAgIHJldHVybiBhcHBseURlY2lzaW9uVG9ET00oYWlEZWNpc2lvbiwgb3B0aW9ucylcbiAgICAgICAgICAgIH0pLmNhdGNoKGZ1bmN0aW9uIChlcnIpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLndhcm4oJ1tMdWEgUGVyc29uYWxpemVdIEFJIGRlY2lzaW9uIGZhaWxlZCwgdXNpbmcgc3RhbmRhcmQ6JywgZXJyLm1lc3NhZ2UpXG4gICAgICAgICAgICAgICAgdmFyIGZhbGxiYWNrRGVjaXNpb24gPSBEZWNpc2lvbkVuZ2luZS5zdGFuZGFyZERlY2lkZShjb250ZXh0LCBvcHRpb25zKVxuICAgICAgICAgICAgICAgIHJldHVybiBhcHBseURlY2lzaW9uVG9ET00oZmFsbGJhY2tEZWNpc2lvbiwgb3B0aW9ucylcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICAvLyBTeW5jaHJvbm91cyBwYXRoXG4gICAgICAgIHJldHVybiBhcHBseURlY2lzaW9uVG9ET00oZGVjaXNpb24sIG9wdGlvbnMpXG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQXN5bmMgcGVyc29uYWxpemF0aW9uIHdpdGggdGltZW91dCBmYWxsYmFja1xuICAgICAqIEF1dG9tYXRpY2FsbHkgaGFuZGxlcyBBSSBkZWNpc2lvbnMgKHdoaWNoIGFyZSBhbHdheXMgYXN5bmMpXG4gICAgICovXG4gICAgZnVuY3Rpb24gcGVyc29uYWxpemVBc3luYyhvcHRpb25zKSB7XG4gICAgICAgIG9wdGlvbnMgPSBvcHRpb25zIHx8IHt9XG4gICAgICAgIHJldHVybiBnZXRDb250ZXh0QXN5bmMob3B0aW9ucykudGhlbihmdW5jdGlvbiAoY29udGV4dCkge1xuICAgICAgICAgICAgb3B0aW9ucy5jb250ZXh0ID0gY29udGV4dFxuICAgICAgICAgICAgcmV0dXJuIHBlcnNvbmFsaXplKG9wdGlvbnMpXG4gICAgICAgIH0pLnRoZW4oZnVuY3Rpb24gKGRlY2lzaW9uKSB7XG4gICAgICAgICAgICByZXR1cm4gZGVjaXNpb25cbiAgICAgICAgfSkuY2F0Y2goZnVuY3Rpb24gKGVycikge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKCdbTHVhIFBlcnNvbmFsaXplXSBBc3luYyBlcnJvciwgdXNpbmcgZGVmYXVsdDonLCBlcnIpXG4gICAgICAgICAgICB2YXIgY3R4ID0gZ2V0Q29udGV4dChvcHRpb25zKVxuICAgICAgICAgICAgdmFyIGZhbGxiYWNrID0gRGVjaXNpb25FbmdpbmUuc3RhbmRhcmREZWNpZGUoY3R4LCB7IHRlbXBsYXRlczogb3B0aW9ucy50ZW1wbGF0ZXMgfSlcbiAgICAgICAgICAgIHJldHVybiBhcHBseURlY2lzaW9uVG9ET00oZmFsbGJhY2ssIG9wdGlvbnMpXG4gICAgICAgIH0pXG4gICAgfVxuXG4gICAgLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuICAgIC8vIDkuIEFVVE8tSU5JVElBTElaQVRJT05cbiAgICAvLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09XG5cbiAgICAvKipcbiAgICAgKiBBdXRvLWluaXRpYWxpemUgcGVyc29uYWxpemF0aW9uIG9uIERPTUNvbnRlbnRMb2FkZWRcbiAgICAgKiBPbmx5IHJ1bnMgaWYgZGF0YS1wZXJzb25hbGl6ZSBlbGVtZW50cyBleGlzdCBpbiB0aGUgRE9NXG4gICAgICovXG4gICAgZnVuY3Rpb24gYXV0b0luaXQob3B0aW9ucykge1xuICAgICAgICBvcHRpb25zID0gb3B0aW9ucyB8fCB7fVxuXG4gICAgICAgIGZ1bmN0aW9uIHJ1bigpIHtcbiAgICAgICAgICAgIHZhciBlbGVtZW50cyA9IGZpbmRQZXJzb25hbGl6ZUVsZW1lbnRzKClcbiAgICAgICAgICAgIGlmIChlbGVtZW50cy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgcGVyc29uYWxpemUob3B0aW9ucylcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgICAgICAgICBpZiAoZG9jdW1lbnQucmVhZHlTdGF0ZSA9PT0gJ2xvYWRpbmcnKSB7XG4gICAgICAgICAgICAgICAgZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignRE9NQ29udGVudExvYWRlZCcsIHJ1bilcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgcnVuKClcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbiAgICAvLyAxMC4gUFVCTElDIEFQSVxuICAgIC8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuICAgIHZhciBMdWFVVE1QZXJzb25hbGl6ZSA9IHtcbiAgICAgICAgLy8gVVRNIGV4dHJhY3Rpb25cbiAgICAgICAgZXh0cmFjdFVUTVBhcmFtczogZXh0cmFjdFVUTVBhcmFtcyxcbiAgICAgICAgc2FuaXRpemVQYXJhbTogc2FuaXRpemVQYXJhbSxcbiAgICAgICAgZGV0ZWN0UmVmZXJyZXI6IGRldGVjdFJlZmVycmVyLFxuICAgICAgICBnZXRVc2VyQWdlbnRJbmZvOiBnZXRVc2VyQWdlbnRJbmZvLFxuICAgICAgICBnZXRDb250ZXh0OiBnZXRDb250ZXh0LFxuICAgICAgICBnZXRDb250ZXh0QXN5bmM6IGdldENvbnRleHRBc3luYyxcbiAgICAgICAgaW5mZXJJbnRlbnQ6IGluZmVySW50ZW50LFxuXG4gICAgICAgIC8vIFNhbml0aXplclxuICAgICAgICBzYW5pdGl6ZXI6IFNhbml0aXplcixcbiAgICAgICAgc2FuaXRpemVIVE1MOiBmdW5jdGlvbiAoaHRtbCkgeyByZXR1cm4gU2FuaXRpemVyLnNhbml0aXplKGh0bWwpIH0sXG5cbiAgICAgICAgLy8gRE9NIGhlbHBlcnNcbiAgICAgICAgc2FmZVNldFRleHQ6IHNhZmVTZXRUZXh0LFxuICAgICAgICBzYWZlU2V0SFRNTDogc2FmZVNldEhUTUwsXG4gICAgICAgIGZpbmRFbGVtZW50czogZmluZFBlcnNvbmFsaXplRWxlbWVudHMsXG4gICAgICAgIGFwcGx5RGVjaXNpb25Ub0RPTTogYXBwbHlEZWNpc2lvblRvRE9NLFxuXG4gICAgICAgIC8vIFRlbXBsYXRlcyAodXNlcnMgbXVzdCBwcm92aWRlIHRoZWlyIG93biB2aWEgb3B0aW9ucy50ZW1wbGF0ZXMpXG4gICAgICAgIGdldFRlbXBsYXRlOiBnZXRUZW1wbGF0ZSxcblxuICAgICAgICAvLyBEZWNpc2lvbiBlbmdpbmVcbiAgICAgICAgZW5naW5lOiBEZWNpc2lvbkVuZ2luZSxcbiAgICAgICAgY2hvb3NlV2VpZ2h0ZWRSYW5kb206IGNob29zZVdlaWdodGVkUmFuZG9tLFxuICAgICAgICBnZXRSYW5kb21GYWxsYmFja0ludGVudDogZ2V0UmFuZG9tRmFsbGJhY2tJbnRlbnQsXG5cbiAgICAgICAgLy8gTWFpbiBBUElcbiAgICAgICAgcGVyc29uYWxpemU6IHBlcnNvbmFsaXplLFxuICAgICAgICBwZXJzb25hbGl6ZUFzeW5jOiBwZXJzb25hbGl6ZUFzeW5jLFxuICAgICAgICBhdXRvSW5pdDogYXV0b0luaXQsXG5cbiAgICAgICAgLy8gQ29uc3RhbnRzXG4gICAgICAgIFVUTV9QQVJBTVM6IFVUTV9QQVJBTVMsXG4gICAgICAgIFVUTV9USU1FT1VUX01TOiBVVE1fVElNRU9VVF9NUyxcbiAgICAgICAgUkVGRVJSRVJfUEFUVEVSTlM6IFJFRkVSUkVSX1BBVFRFUk5TLFxuICAgICAgICBSRUZFUlJFUl9DQVRFR09SSUVTOiBSRUZFUlJFUl9DQVRFR09SSUVTXG4gICAgfVxuXG4gICAgLy8gUmVnaXN0ZXIgZ2xvYmFsbHlcbiAgICByb290Lkx1YVVUTVBlcnNvbmFsaXplID0gTHVhVVRNUGVyc29uYWxpemVcblxuICAgIC8vIEFsc28gcmVnaXN0ZXIgaW5kaXZpZHVhbCBtb2R1bGVzIGZvciBjb21wYXRpYmlsaXR5XG4gICAgaWYgKCFyb290Lkx1YVVUTSkge1xuICAgICAgICByb290Lkx1YVVUTSA9IHtcbiAgICAgICAgICAgIGV4dHJhY3RVVE1QYXJhbXM6IGV4dHJhY3RVVE1QYXJhbXMsXG4gICAgICAgICAgICBzYW5pdGl6ZVBhcmFtOiBzYW5pdGl6ZVBhcmFtLFxuICAgICAgICAgICAgZGV0ZWN0UmVmZXJyZXI6IGRldGVjdFJlZmVycmVyLFxuICAgICAgICAgICAgZ2V0VXNlckFnZW50SW5mbzogZ2V0VXNlckFnZW50SW5mbyxcbiAgICAgICAgICAgIGdldENvbnRleHQ6IGdldENvbnRleHQsXG4gICAgICAgICAgICBnZXRDb250ZXh0QXN5bmM6IGdldENvbnRleHRBc3luYyxcbiAgICAgICAgICAgIGluZmVySW50ZW50OiBpbmZlckludGVudCxcbiAgICAgICAgICAgIFVUTV9QQVJBTVM6IFVUTV9QQVJBTVMsXG4gICAgICAgICAgICBVVE1fVElNRU9VVF9NUzogVVRNX1RJTUVPVVRfTVMsXG4gICAgICAgICAgICBSRUZFUlJFUl9QQVRURVJOUzogUkVGRVJSRVJfUEFUVEVSTlMsXG4gICAgICAgICAgICBSRUZFUlJFUl9DQVRFR09SSUVTOiBSRUZFUlJFUl9DQVRFR09SSUVTXG4gICAgICAgIH1cbiAgICB9XG4gICAgaWYgKCFyb290Lkx1YVBlcnNvbmFsaXplKSB7XG4gICAgICAgIHJvb3QuTHVhUGVyc29uYWxpemUgPSB7XG4gICAgICAgICAgICBzYW5pdGl6ZXI6IFNhbml0aXplcixcbiAgICAgICAgICAgIHNhbml0aXplSFRNTDogZnVuY3Rpb24gKGh0bWwpIHsgcmV0dXJuIFNhbml0aXplci5zYW5pdGl6ZShodG1sKSB9LFxuICAgICAgICAgICAgc2FmZVNldFRleHQ6IHNhZmVTZXRUZXh0LFxuICAgICAgICAgICAgc2FmZVNldEhUTUw6IHNhZmVTZXRIVE1MLFxuICAgICAgICAgICAgZmluZEVsZW1lbnRzOiBmaW5kUGVyc29uYWxpemVFbGVtZW50cyxcbiAgICAgICAgICAgIGFwcGx5RGVjaXNpb25Ub0RPTTogYXBwbHlEZWNpc2lvblRvRE9NLFxuICAgICAgICAgICAgZ2V0VGVtcGxhdGU6IGdldFRlbXBsYXRlLFxuICAgICAgICAgICAgZW5naW5lOiBEZWNpc2lvbkVuZ2luZSxcbiAgICAgICAgICAgIHBlcnNvbmFsaXplOiBwZXJzb25hbGl6ZSxcbiAgICAgICAgICAgIHBlcnNvbmFsaXplQXN5bmM6IHBlcnNvbmFsaXplQXN5bmMsXG4gICAgICAgICAgICBhdXRvSW5pdDogYXV0b0luaXQsXG4gICAgICAgICAgICBjaG9vc2VXZWlnaHRlZFJhbmRvbTogY2hvb3NlV2VpZ2h0ZWRSYW5kb20sXG4gICAgICAgICAgICBnZXRSYW5kb21GYWxsYmFja0ludGVudDogZ2V0UmFuZG9tRmFsbGJhY2tJbnRlbnRcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIE5vdGU6IGF1dG9Jbml0KCkgaXMgTk9UIGNhbGxlZCBhdXRvbWF0aWNhbGx5IGJlY2F1c2UgdGVtcGxhdGVzIGFyZSByZXF1aXJlZFxuICAgIC8vIFVzZXJzIG11c3QgY2FsbCBwZXJzb25hbGl6ZSgpIG9yIHBlcnNvbmFsaXplQXN5bmMoKSB3aXRoIHRoZWlyIHRlbXBsYXRlc1xuXG59KSh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyA/IHdpbmRvdyA6IHR5cGVvZiBnbG9iYWwgIT09ICd1bmRlZmluZWQnID8gZ2xvYmFsIDogdGhpcylcbiJdLCJtYXBwaW5ncyI6Ijs7OztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUFDLENBQUMsVUFBVUEsSUFBSSxFQUFFO0VBQ2QsWUFBWTs7RUFFWjtFQUNBO0VBQ0E7RUFFQSxJQUFJQyxjQUFjLEdBQUcsSUFBSTtFQUV6QixJQUFJQyxVQUFVLEdBQUcsQ0FBQyxZQUFZLEVBQUUsWUFBWSxFQUFFLGNBQWMsRUFBRSxhQUFhLEVBQUUsVUFBVSxDQUFDO0VBRXhGLElBQUlDLGlCQUFpQixHQUFHO0lBQ3BCQyxNQUFNLEVBQUUsV0FBVztJQUNuQkMsSUFBSSxFQUFFLFNBQVM7SUFDZkMsS0FBSyxFQUFFLFVBQVU7SUFDakJDLFVBQVUsRUFBRSxlQUFlO0lBQzNCQyxRQUFRLEVBQUUsd0JBQXdCO0lBQ2xDQyxPQUFPLEVBQUUsNEJBQTRCO0lBQ3JDQyxTQUFTLEVBQUUsaUJBQWlCO0lBQzVCQyxRQUFRLEVBQUUsZ0JBQWdCO0lBQzFCQyxTQUFTLEVBQUUsY0FBYztJQUN6QkMsTUFBTSxFQUFFLGNBQWM7SUFDdEJDLE9BQU8sRUFBRSx5QkFBeUI7SUFDbENDLE1BQU0sRUFBRTtFQUNaLENBQUM7RUFFRCxJQUFJQyxtQkFBbUIsR0FBRztJQUN0QkMsTUFBTSxFQUFFLENBQUMsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsWUFBWSxDQUFDO0lBQ2pEQyxNQUFNLEVBQUUsQ0FBQyxVQUFVLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsUUFBUTtFQUN2RyxDQUFDOztFQUVEO0FBQ0o7QUFDQTtBQUNBO0FBQ0E7RUFDSSxTQUFTQyxhQUFhQSxDQUFDQyxLQUFLLEVBQUU7SUFDMUIsSUFBSSxPQUFPQSxLQUFLLEtBQUssUUFBUSxFQUFFLE9BQU8sRUFBRTtJQUN4QyxPQUFPQSxLQUFLLENBQ1BDLE9BQU8sQ0FBQyxVQUFVLEVBQUUsRUFBRSxDQUFDLENBQ3ZCQSxPQUFPLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQyxDQUMzQkMsU0FBUyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FDakJDLElBQUksQ0FBQyxDQUFDO0VBQ2Y7O0VBRUE7QUFDSjtBQUNBO0FBQ0E7QUFDQTtFQUNJLFNBQVNDLGdCQUFnQkEsQ0FBQ0MsR0FBRyxFQUFFO0lBQzNCLElBQUlDLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDZixJQUFJO01BQ0EsSUFBSUMsWUFBWSxHQUFHRixHQUFHLEtBQUssT0FBT3pCLElBQUksQ0FBQzRCLFFBQVEsS0FBSyxXQUFXLEdBQUc1QixJQUFJLENBQUM0QixRQUFRLENBQUNYLE1BQU0sR0FBRyxFQUFFLENBQUM7TUFDNUYsSUFBSSxDQUFDVSxZQUFZLEVBQUUsT0FBT0QsTUFBTTtNQUVoQyxJQUFJRyxNQUFNLEdBQUcsSUFBSUMsZUFBZSxDQUFDSCxZQUFZLENBQUM7TUFFOUN6QixVQUFVLENBQUM2QixPQUFPLENBQUMsVUFBVUMsS0FBSyxFQUFFO1FBQ2hDLElBQUlaLEtBQUssR0FBR1MsTUFBTSxDQUFDSSxHQUFHLENBQUNELEtBQUssQ0FBQztRQUM3QixJQUFJWixLQUFLLEVBQUU7VUFDUE0sTUFBTSxDQUFDTSxLQUFLLENBQUMsR0FBR2IsYUFBYSxDQUFDQyxLQUFLLENBQUM7UUFDeEM7TUFDSixDQUFDLENBQUM7SUFDTixDQUFDLENBQUMsT0FBT2MsQ0FBQyxFQUFFO01BQ1JDLE9BQU8sQ0FBQ0MsSUFBSSxDQUFDLHdDQUF3QyxFQUFFRixDQUFDLENBQUM7SUFDN0Q7SUFDQSxPQUFPUixNQUFNO0VBQ2pCOztFQUVBO0FBQ0o7QUFDQTtBQUNBO0VBQ0ksU0FBU1csY0FBY0EsQ0FBQSxFQUFHO0lBQ3RCLElBQUlYLE1BQU0sR0FBRztNQUFFWSxNQUFNLEVBQUUsUUFBUTtNQUFFQyxRQUFRLEVBQUUsUUFBUTtNQUFFZCxHQUFHLEVBQUU7SUFBRyxDQUFDO0lBQzlELElBQUk7TUFDQSxJQUFJLE9BQU9lLFFBQVEsS0FBSyxXQUFXLElBQUksQ0FBQ0EsUUFBUSxDQUFDQyxRQUFRLEVBQUUsT0FBT2YsTUFBTTtNQUV4RUEsTUFBTSxDQUFDRCxHQUFHLEdBQUdlLFFBQVEsQ0FBQ0MsUUFBUTtNQUU5QixJQUFJLDRCQUE0QixDQUFDQyxJQUFJLENBQUNGLFFBQVEsQ0FBQ0MsUUFBUSxDQUFDLEVBQUU7UUFDdERmLE1BQU0sQ0FBQ1ksTUFBTSxHQUFHLE9BQU87UUFDdkJaLE1BQU0sQ0FBQ2EsUUFBUSxHQUFHLE9BQU87UUFDekIsT0FBT2IsTUFBTTtNQUNqQjtNQUVBLEtBQUssSUFBSVksTUFBTSxJQUFJbkMsaUJBQWlCLEVBQUU7UUFDbEMsSUFBSUEsaUJBQWlCLENBQUNtQyxNQUFNLENBQUMsQ0FBQ0ksSUFBSSxDQUFDRixRQUFRLENBQUNDLFFBQVEsQ0FBQyxFQUFFO1VBQ25EZixNQUFNLENBQUNZLE1BQU0sR0FBR0EsTUFBTTtVQUN0QixLQUFLLElBQUlDLFFBQVEsSUFBSXZCLG1CQUFtQixFQUFFO1lBQ3RDLElBQUlBLG1CQUFtQixDQUFDdUIsUUFBUSxDQUFDLENBQUNJLE9BQU8sQ0FBQ0wsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQUU7Y0FDdERaLE1BQU0sQ0FBQ2EsUUFBUSxHQUFHQSxRQUFRO2NBQzFCO1lBQ0o7VUFDSjtVQUNBLE9BQU9iLE1BQU07UUFDakI7TUFDSjtNQUVBQSxNQUFNLENBQUNZLE1BQU0sR0FBRyxVQUFVO01BQzFCWixNQUFNLENBQUNhLFFBQVEsR0FBRyxPQUFPO0lBQzdCLENBQUMsQ0FBQyxPQUFPTCxDQUFDLEVBQUU7TUFDUkMsT0FBTyxDQUFDQyxJQUFJLENBQUMscUNBQXFDLEVBQUVGLENBQUMsQ0FBQztJQUMxRDtJQUNBLE9BQU9SLE1BQU07RUFDakI7O0VBRUE7QUFDSjtBQUNBO0FBQ0E7RUFDSSxTQUFTa0IsZ0JBQWdCQSxDQUFBLEVBQUc7SUFDeEIsSUFBSWxCLE1BQU0sR0FBRztNQUFFbUIsR0FBRyxFQUFFLEVBQUU7TUFBRUMsUUFBUSxFQUFFLEtBQUs7TUFBRUMsUUFBUSxFQUFFLEtBQUs7TUFBRUMsU0FBUyxFQUFFO0lBQUssQ0FBQztJQUMzRSxJQUFJO01BQ0EsSUFBSSxPQUFPQyxTQUFTLEtBQUssV0FBVyxJQUFJLENBQUNBLFNBQVMsQ0FBQ0MsU0FBUyxFQUFFLE9BQU94QixNQUFNO01BQzNFQSxNQUFNLENBQUNtQixHQUFHLEdBQUdJLFNBQVMsQ0FBQ0MsU0FBUztNQUNoQ3hCLE1BQU0sQ0FBQ29CLFFBQVEsR0FBRywyREFBMkQsQ0FBQ0osSUFBSSxDQUFDTyxTQUFTLENBQUNDLFNBQVMsQ0FBQztNQUN2R3hCLE1BQU0sQ0FBQ3FCLFFBQVEsR0FBRywyQkFBMkIsQ0FBQ0wsSUFBSSxDQUFDTyxTQUFTLENBQUNDLFNBQVMsQ0FBQztNQUN2RXhCLE1BQU0sQ0FBQ3NCLFNBQVMsR0FBRyxDQUFDdEIsTUFBTSxDQUFDb0IsUUFBUSxJQUFJLENBQUNwQixNQUFNLENBQUNxQixRQUFRO0lBQzNELENBQUMsQ0FBQyxPQUFPYixDQUFDLEVBQUU7TUFDUkMsT0FBTyxDQUFDQyxJQUFJLENBQUMscUNBQXFDLEVBQUVGLENBQUMsQ0FBQztJQUMxRDtJQUNBLE9BQU9SLE1BQU07RUFDakI7O0VBRUE7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ0ksU0FBU3lCLFdBQVdBLENBQUNDLE9BQU8sRUFBRTtJQUMxQixJQUFJQSxPQUFPLENBQUNDLEdBQUcsQ0FBQ0MsWUFBWSxFQUFFO01BQzFCLElBQUlDLFFBQVEsR0FBR0gsT0FBTyxDQUFDQyxHQUFHLENBQUNDLFlBQVksQ0FBQ0UsV0FBVyxDQUFDLENBQUM7TUFDckQsSUFBSSw0QkFBNEIsQ0FBQ2QsSUFBSSxDQUFDYSxRQUFRLENBQUMsRUFBRSxPQUFPLGVBQWU7TUFDdkUsSUFBSSxxQkFBcUIsQ0FBQ2IsSUFBSSxDQUFDYSxRQUFRLENBQUMsRUFBRSxPQUFPLFFBQVE7TUFDekQsSUFBSSx3Q0FBd0MsQ0FBQ2IsSUFBSSxDQUFDYSxRQUFRLENBQUMsRUFBRSxPQUFPLGNBQWM7TUFDbEYsSUFBSSw2QkFBNkIsQ0FBQ2IsSUFBSSxDQUFDYSxRQUFRLENBQUMsRUFBRSxPQUFPLFVBQVU7TUFDbkUsSUFBSSxvQkFBb0IsQ0FBQ2IsSUFBSSxDQUFDYSxRQUFRLENBQUMsRUFBRSxPQUFPLGFBQWE7SUFDakU7SUFFQSxJQUFJSCxPQUFPLENBQUNDLEdBQUcsQ0FBQ0ksVUFBVSxFQUFFO01BQ3hCLElBQUluQixNQUFNLEdBQUdjLE9BQU8sQ0FBQ0MsR0FBRyxDQUFDSSxVQUFVLENBQUNELFdBQVcsQ0FBQyxDQUFDO01BQ2pELElBQUksb0JBQW9CLENBQUNkLElBQUksQ0FBQ0osTUFBTSxDQUFDLEVBQUUsT0FBTyxrQkFBa0I7TUFDaEUsSUFBSSw0QkFBNEIsQ0FBQ0ksSUFBSSxDQUFDSixNQUFNLENBQUMsRUFBRSxPQUFPLGVBQWU7TUFDckUsSUFBSSxhQUFhLENBQUNJLElBQUksQ0FBQ0osTUFBTSxDQUFDLEVBQUUsT0FBTyxjQUFjO01BQ3JELElBQUksbUJBQW1CLENBQUNJLElBQUksQ0FBQ0osTUFBTSxDQUFDLEVBQUUsT0FBTyxnQkFBZ0I7TUFDN0QsSUFBSSxVQUFVLENBQUNJLElBQUksQ0FBQ0osTUFBTSxDQUFDLEVBQUUsT0FBTyxlQUFlO0lBQ3ZEO0lBRUEsSUFBSWMsT0FBTyxDQUFDWCxRQUFRLENBQUNGLFFBQVEsS0FBSyxRQUFRLEVBQUUsT0FBTyxrQkFBa0I7SUFDckUsSUFBSWEsT0FBTyxDQUFDWCxRQUFRLENBQUNGLFFBQVEsS0FBSyxRQUFRLEVBQUUsT0FBTyxlQUFlO0lBQ2xFLElBQUlhLE9BQU8sQ0FBQ1gsUUFBUSxDQUFDRixRQUFRLEtBQUssT0FBTyxFQUFFLE9BQU8sZ0JBQWdCO0lBRWxFLE9BQU8sU0FBUztFQUNwQjs7RUFFQTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0VBQ0ksU0FBU21CLFVBQVVBLENBQUNDLE9BQU8sRUFBRTtJQUN6QkEsT0FBTyxHQUFHQSxPQUFPLElBQUksQ0FBQyxDQUFDO0lBQ3ZCLElBQUlQLE9BQU8sR0FBRztNQUNWQyxHQUFHLEVBQUU3QixnQkFBZ0IsQ0FBQ21DLE9BQU8sQ0FBQ2xDLEdBQUcsQ0FBQztNQUNsQ2dCLFFBQVEsRUFBRUosY0FBYyxDQUFDLENBQUM7TUFDMUJhLFNBQVMsRUFBRU4sZ0JBQWdCLENBQUMsQ0FBQztNQUM3QmdCLFNBQVMsRUFBRUMsSUFBSSxDQUFDQyxHQUFHLENBQUMsQ0FBQztNQUNyQkMsTUFBTSxFQUFFLEtBQUs7TUFDYkMsYUFBYSxFQUFFO0lBQ25CLENBQUM7SUFDRFosT0FBTyxDQUFDVyxNQUFNLEdBQUdFLE1BQU0sQ0FBQ0MsSUFBSSxDQUFDZCxPQUFPLENBQUNDLEdBQUcsQ0FBQyxDQUFDYyxNQUFNLEdBQUcsQ0FBQztJQUNwRGYsT0FBTyxDQUFDWSxhQUFhLEdBQUdiLFdBQVcsQ0FBQ0MsT0FBTyxDQUFDO0lBQzVDLE9BQU9BLE9BQU87RUFDbEI7O0VBRUE7QUFDSjtBQUNBO0FBQ0E7QUFDQTtFQUNJLFNBQVNnQixlQUFlQSxDQUFDVCxPQUFPLEVBQUU7SUFDOUJBLE9BQU8sR0FBR0EsT0FBTyxJQUFJLENBQUMsQ0FBQztJQUN2QixJQUFJVSxPQUFPLEdBQUdWLE9BQU8sQ0FBQ1UsT0FBTyxJQUFJcEUsY0FBYztJQUUvQyxPQUFPLElBQUlxRSxPQUFPLENBQUMsVUFBVUMsT0FBTyxFQUFFO01BQ2xDLElBQUlDLEtBQUssR0FBR0MsVUFBVSxDQUFDLFlBQVk7UUFDL0JGLE9BQU8sQ0FBQztVQUNKbEIsR0FBRyxFQUFFLENBQUMsQ0FBQztVQUNQWixRQUFRLEVBQUU7WUFBRUgsTUFBTSxFQUFFLFFBQVE7WUFBRUMsUUFBUSxFQUFFLFFBQVE7WUFBRWQsR0FBRyxFQUFFO1VBQUcsQ0FBQztVQUMzRHlCLFNBQVMsRUFBRTtZQUFFTCxHQUFHLEVBQUUsRUFBRTtZQUFFQyxRQUFRLEVBQUUsS0FBSztZQUFFQyxRQUFRLEVBQUUsS0FBSztZQUFFQyxTQUFTLEVBQUU7VUFBSyxDQUFDO1VBQ3pFWSxTQUFTLEVBQUVDLElBQUksQ0FBQ0MsR0FBRyxDQUFDLENBQUM7VUFDckJDLE1BQU0sRUFBRSxLQUFLO1VBQ2JDLGFBQWEsRUFBRSxTQUFTO1VBQ3hCVSxRQUFRLEVBQUU7UUFDZCxDQUFDLENBQUM7TUFDTixDQUFDLEVBQUVMLE9BQU8sQ0FBQztNQUVYLElBQUk7UUFDQSxJQUFJakIsT0FBTyxHQUFHTSxVQUFVLENBQUNDLE9BQU8sQ0FBQztRQUNqQ2dCLFlBQVksQ0FBQ0gsS0FBSyxDQUFDO1FBQ25CcEIsT0FBTyxDQUFDc0IsUUFBUSxHQUFHLEtBQUs7UUFDeEJILE9BQU8sQ0FBQ25CLE9BQU8sQ0FBQztNQUNwQixDQUFDLENBQUMsT0FBT2xCLENBQUMsRUFBRTtRQUNSeUMsWUFBWSxDQUFDSCxLQUFLLENBQUM7UUFDbkJELE9BQU8sQ0FBQztVQUNKbEIsR0FBRyxFQUFFLENBQUMsQ0FBQztVQUNQWixRQUFRLEVBQUU7WUFBRUgsTUFBTSxFQUFFLFFBQVE7WUFBRUMsUUFBUSxFQUFFLFFBQVE7WUFBRWQsR0FBRyxFQUFFO1VBQUcsQ0FBQztVQUMzRHlCLFNBQVMsRUFBRTtZQUFFTCxHQUFHLEVBQUUsRUFBRTtZQUFFQyxRQUFRLEVBQUUsS0FBSztZQUFFQyxRQUFRLEVBQUUsS0FBSztZQUFFQyxTQUFTLEVBQUU7VUFBSyxDQUFDO1VBQ3pFWSxTQUFTLEVBQUVDLElBQUksQ0FBQ0MsR0FBRyxDQUFDLENBQUM7VUFDckJDLE1BQU0sRUFBRSxLQUFLO1VBQ2JDLGFBQWEsRUFBRSxTQUFTO1VBQ3hCWSxLQUFLLEVBQUUxQyxDQUFDLENBQUMyQztRQUNiLENBQUMsQ0FBQztNQUNOO0lBQ0osQ0FBQyxDQUFDO0VBQ047O0VBRUE7RUFDQTtFQUNBOztFQUVBLElBQUlDLFNBQVMsR0FBSSxZQUFZO0lBQ3pCLElBQUlDLFlBQVksR0FBRztNQUNmLEdBQUcsRUFBRSxJQUFJO01BQUUsTUFBTSxFQUFFLElBQUk7TUFBRSxRQUFRLEVBQUUsSUFBSTtNQUFFLElBQUksRUFBRSxJQUFJO01BQ25ELEdBQUcsRUFBRSxJQUFJO01BQUUsR0FBRyxFQUFFLElBQUk7TUFBRSxJQUFJLEVBQUUsSUFBSTtNQUFFLEdBQUcsRUFBRSxJQUFJO01BQUUsS0FBSyxFQUFFLElBQUk7TUFDeEQsSUFBSSxFQUFFLElBQUk7TUFBRSxJQUFJLEVBQUUsSUFBSTtNQUFFLElBQUksRUFBRSxJQUFJO01BQUUsSUFBSSxFQUFFLElBQUk7TUFBRSxJQUFJLEVBQUUsSUFBSTtNQUFFLElBQUksRUFBRSxJQUFJO01BQ3RFLEtBQUssRUFBRSxJQUFJO01BQUUsU0FBUyxFQUFFLElBQUk7TUFBRSxJQUFJLEVBQUUsSUFBSTtNQUFFLElBQUksRUFBRSxJQUFJO01BQUUsSUFBSSxFQUFFLElBQUk7TUFDaEUsWUFBWSxFQUFFLElBQUk7TUFBRSxRQUFRLEVBQUUsSUFBSTtNQUFFLFlBQVksRUFBRTtJQUN0RCxDQUFDO0lBRUQsSUFBSUMsYUFBYSxHQUFHO01BQ2hCLE1BQU0sRUFBRSxJQUFJO01BQUUsS0FBSyxFQUFFLElBQUk7TUFBRSxLQUFLLEVBQUUsSUFBSTtNQUFFLE9BQU8sRUFBRSxJQUFJO01BQ3JELElBQUksRUFBRSxJQUFJO01BQUUsT0FBTyxFQUFFLElBQUk7TUFBRSxRQUFRLEVBQUUsSUFBSTtNQUFFLEtBQUssRUFBRSxJQUFJO01BQ3RELE9BQU8sRUFBRSxJQUFJO01BQUUsUUFBUSxFQUFFLElBQUk7TUFBRSxTQUFTLEVBQUU7SUFDOUMsQ0FBQztJQUVELElBQUlDLGFBQWEsR0FBRywrQkFBK0I7SUFDbkQsSUFBSUMsYUFBYSxHQUFHLE1BQU07SUFFMUIsU0FBU0MsWUFBWUEsQ0FBQSxFQUFHO01BQ3BCLElBQUk7UUFBRSxPQUFPLE9BQU9DLFNBQVMsS0FBSyxXQUFXLElBQUksSUFBSUEsU0FBUyxDQUFDLENBQUM7TUFBQyxDQUFDLENBQ2xFLE9BQU9sRCxDQUFDLEVBQUU7UUFBRSxPQUFPLEtBQUs7TUFBQztJQUM3QjtJQUVBLFNBQVNtRCxVQUFVQSxDQUFDQyxJQUFJLEVBQUU7TUFDdEIsSUFBSSxDQUFDQSxJQUFJLEVBQUUsT0FBTyxFQUFFO01BQ3BCLE9BQU9BLElBQUksQ0FBQ2pFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLENBQUNBLE9BQU8sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUNBLE9BQU8sQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDO0lBQ2xGO0lBRUEsU0FBU2tFLFVBQVVBLENBQUNuRSxLQUFLLEVBQUU7TUFDdkIsSUFBSSxDQUFDQSxLQUFLLEVBQUUsT0FBTyxFQUFFO01BQ3JCLE9BQU9BLEtBQUssQ0FBQ0MsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQ0EsT0FBTyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQ0EsT0FBTyxDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQ0EsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUMsQ0FBQ0EsT0FBTyxDQUFDLElBQUksRUFBRSxNQUFNLENBQUM7SUFDbEk7SUFFQSxTQUFTbUUsZUFBZUEsQ0FBQ0MsT0FBTyxFQUFFO01BQzlCLElBQUlDLE9BQU8sR0FBRyxFQUFFO01BQ2hCLElBQUlDLEtBQUssR0FBR0YsT0FBTyxDQUFDRyxVQUFVO01BQzlCLEtBQUssSUFBSUMsQ0FBQyxHQUFHLENBQUMsRUFBRUEsQ0FBQyxHQUFHRixLQUFLLENBQUN4QixNQUFNLEVBQUUwQixDQUFDLEVBQUUsRUFBRTtRQUNuQyxJQUFJQyxJQUFJLEdBQUdILEtBQUssQ0FBQ0UsQ0FBQyxDQUFDLENBQUNDLElBQUksQ0FBQ3RDLFdBQVcsQ0FBQyxDQUFDO1FBQ3RDLElBQUlwQyxLQUFLLEdBQUd1RSxLQUFLLENBQUNFLENBQUMsQ0FBQyxDQUFDekUsS0FBSztRQUMxQixJQUFJOEQsYUFBYSxDQUFDeEMsSUFBSSxDQUFDb0QsSUFBSSxDQUFDLEVBQUU7UUFDOUIsSUFBSSxDQUFDZCxhQUFhLENBQUNjLElBQUksQ0FBQyxFQUFFO1FBQzFCLElBQUksQ0FBQ0EsSUFBSSxLQUFLLE1BQU0sSUFBSUEsSUFBSSxLQUFLLEtBQUssS0FBS2IsYUFBYSxDQUFDdkMsSUFBSSxDQUFDdEIsS0FBSyxDQUFDRyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDN0UsSUFBSXVFLElBQUksS0FBSyxRQUFRLElBQUkxRSxLQUFLLEtBQUssUUFBUSxFQUFFO1VBQ3pDc0UsT0FBTyxJQUFJLDRDQUE0QztVQUN2RDtRQUNKO1FBQ0FBLE9BQU8sSUFBSSxHQUFHLEdBQUdJLElBQUksR0FBRyxJQUFJLEdBQUdQLFVBQVUsQ0FBQ25FLEtBQUssQ0FBQyxHQUFHLEdBQUc7TUFDMUQ7TUFDQSxPQUFPc0UsT0FBTztJQUNsQjtJQUVBLFNBQVNLLFlBQVlBLENBQUNDLElBQUksRUFBRTtNQUN4QixJQUFJQyxNQUFNLEdBQUcsRUFBRTtNQUNmLEtBQUssSUFBSUosQ0FBQyxHQUFHLENBQUMsRUFBRUEsQ0FBQyxHQUFHRyxJQUFJLENBQUNFLFVBQVUsQ0FBQy9CLE1BQU0sRUFBRTBCLENBQUMsRUFBRSxFQUFFO1FBQzdDLElBQUlNLEtBQUssR0FBR0gsSUFBSSxDQUFDRSxVQUFVLENBQUNMLENBQUMsQ0FBQztRQUM5QixJQUFJTSxLQUFLLENBQUNDLFFBQVEsS0FBSyxDQUFDLEVBQUU7VUFBRUgsTUFBTSxJQUFJWixVQUFVLENBQUNjLEtBQUssQ0FBQ0UsV0FBVyxDQUFDO1VBQUU7UUFBUztRQUM5RSxJQUFJRixLQUFLLENBQUNDLFFBQVEsS0FBSyxDQUFDLEVBQUU7VUFDdEIsSUFBSUUsR0FBRyxHQUFHSCxLQUFLLENBQUNJLE9BQU8sQ0FBQy9DLFdBQVcsQ0FBQyxDQUFDO1VBQ3JDLElBQUk4QyxHQUFHLEtBQUssUUFBUSxJQUFJQSxHQUFHLEtBQUssT0FBTyxJQUFJQSxHQUFHLEtBQUssUUFBUSxJQUFJQSxHQUFHLEtBQUssUUFBUSxJQUFJQSxHQUFHLEtBQUssT0FBTyxJQUFJQSxHQUFHLEtBQUssTUFBTSxJQUFJQSxHQUFHLEtBQUssT0FBTyxJQUFJQSxHQUFHLEtBQUssVUFBVSxFQUFFO1VBQy9KLElBQUl2QixZQUFZLENBQUN1QixHQUFHLENBQUMsRUFBRTtZQUNuQkwsTUFBTSxJQUFJLEdBQUcsR0FBR0ssR0FBRyxHQUFHZCxlQUFlLENBQUNXLEtBQUssQ0FBQyxHQUFHLEdBQUc7WUFDbEQsSUFBSUcsR0FBRyxLQUFLLElBQUksSUFBSUEsR0FBRyxLQUFLLEtBQUssRUFBRTtjQUMvQkwsTUFBTSxJQUFJRixZQUFZLENBQUNJLEtBQUssQ0FBQztjQUM3QkYsTUFBTSxJQUFJLElBQUksR0FBR0ssR0FBRyxHQUFHLEdBQUc7WUFDOUI7VUFDSixDQUFDLE1BQU07WUFDSEwsTUFBTSxJQUFJRixZQUFZLENBQUNJLEtBQUssQ0FBQztVQUNqQztRQUNKO01BQ0o7TUFDQSxPQUFPRixNQUFNO0lBQ2pCO0lBRUEsU0FBU08scUJBQXFCQSxDQUFDQyxLQUFLLEVBQUU7TUFDbEMsSUFBSTtRQUNBLElBQUlDLEdBQUcsR0FBRyxJQUFJdEIsU0FBUyxDQUFDLENBQUMsQ0FBQ3VCLGVBQWUsQ0FBQ0YsS0FBSyxFQUFFLFdBQVcsQ0FBQztRQUM3RCxPQUFPQyxHQUFHLENBQUNFLElBQUksR0FBR2IsWUFBWSxDQUFDVyxHQUFHLENBQUNFLElBQUksQ0FBQyxHQUFHLEVBQUU7TUFDakQsQ0FBQyxDQUFDLE9BQU8xRSxDQUFDLEVBQUU7UUFDUixPQUFPMkUsaUJBQWlCLENBQUNKLEtBQUssQ0FBQztNQUNuQztJQUNKO0lBRUEsU0FBU0ksaUJBQWlCQSxDQUFDQyxJQUFJLEVBQUU7TUFDN0IsSUFBSUMsUUFBUSxHQUFHLENBQ1gscURBQXFELEVBQ3JELHFEQUFxRCxFQUNyRCxxREFBcUQsRUFDckQsa0JBQWtCLEVBQUUsaUJBQWlCLEVBQ3JDLGtEQUFrRCxFQUNsRCwrQ0FBK0MsRUFDL0MsZUFBZSxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsYUFBYSxDQUMzRDtNQUNELElBQUlDLFNBQVMsR0FBR0YsSUFBSTtNQUNwQkMsUUFBUSxDQUFDaEYsT0FBTyxDQUFDLFVBQVVrRixDQUFDLEVBQUU7UUFBRUQsU0FBUyxHQUFHQSxTQUFTLENBQUMzRixPQUFPLENBQUM0RixDQUFDLEVBQUUsRUFBRSxDQUFDO01BQUMsQ0FBQyxDQUFDO01BQ3ZFRCxTQUFTLEdBQUdBLFNBQVMsQ0FBQzNGLE9BQU8sQ0FBQyxvQkFBb0IsRUFBRSxVQUFVNkYsS0FBSyxFQUFFWCxPQUFPLEVBQUVaLEtBQUssRUFBRTtRQUNqRixJQUFJVyxHQUFHLEdBQUdDLE9BQU8sQ0FBQy9DLFdBQVcsQ0FBQyxDQUFDO1FBQy9CLElBQUksQ0FBQ3VCLFlBQVksQ0FBQ3VCLEdBQUcsQ0FBQyxFQUFFLE9BQU8sRUFBRTtRQUNqQyxJQUFJWSxLQUFLLENBQUNDLE1BQU0sQ0FBQyxDQUFDLENBQUMsS0FBSyxHQUFHLEVBQUUsT0FBTyxJQUFJLEdBQUdiLEdBQUcsR0FBRyxHQUFHO1FBQ3BELElBQUljLFVBQVUsR0FBRyxFQUFFO1FBQ25CLElBQUlDLEVBQUUsR0FBRyx5QkFBeUI7UUFDbEMsSUFBSUMsQ0FBQztRQUNMLE9BQU8sQ0FBQ0EsQ0FBQyxHQUFHRCxFQUFFLENBQUNFLElBQUksQ0FBQzVCLEtBQUssQ0FBQyxNQUFNLElBQUksRUFBRTtVQUNsQyxJQUFJNkIsQ0FBQyxHQUFHRixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM5RCxXQUFXLENBQUMsQ0FBQztVQUMxQixJQUFJd0IsYUFBYSxDQUFDd0MsQ0FBQyxDQUFDLElBQUksQ0FBQ3RDLGFBQWEsQ0FBQ3hDLElBQUksQ0FBQzhFLENBQUMsQ0FBQyxFQUFFO1lBQzVDLElBQUksQ0FBQ0EsQ0FBQyxLQUFLLE1BQU0sSUFBSUEsQ0FBQyxLQUFLLEtBQUssS0FBS3ZDLGFBQWEsQ0FBQ3ZDLElBQUksQ0FBQzRFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQy9ERixVQUFVLElBQUksR0FBRyxHQUFHSSxDQUFDLEdBQUcsSUFBSSxHQUFHRixDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRztVQUM3QztRQUNKO1FBQ0EsT0FBTyxHQUFHLEdBQUdoQixHQUFHLEdBQUdjLFVBQVUsR0FBRyxHQUFHO01BQ3ZDLENBQUMsQ0FBQztNQUNGLE9BQU9KLFNBQVM7SUFDcEI7SUFFQSxPQUFPO01BQ0hTLFFBQVEsRUFBRSxTQUFWQSxRQUFRQSxDQUFZaEIsS0FBSyxFQUFFO1FBQ3ZCLElBQUksT0FBT0EsS0FBSyxLQUFLLFFBQVEsSUFBSSxDQUFDQSxLQUFLLENBQUNsRixJQUFJLENBQUMsQ0FBQyxFQUFFLE9BQU8sRUFBRTtRQUN6RCxPQUFPNEQsWUFBWSxDQUFDLENBQUMsR0FBR3FCLHFCQUFxQixDQUFDQyxLQUFLLENBQUMsR0FBR0ksaUJBQWlCLENBQUNKLEtBQUssQ0FBQztNQUNuRixDQUFDO01BQ0RwQixVQUFVLEVBQUVBLFVBQVU7TUFDdEJFLFVBQVUsRUFBRUE7SUFDaEIsQ0FBQztFQUNMLENBQUMsQ0FBRSxDQUFDOztFQUVKO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOztFQUVBO0VBQ0E7RUFDQTs7RUFFQSxTQUFTbUMsV0FBV0EsQ0FBQ2pDLE9BQU8sRUFBRUgsSUFBSSxFQUFFO0lBQ2hDLElBQUksQ0FBQ0csT0FBTyxFQUFFO0lBQ2RBLE9BQU8sQ0FBQ1ksV0FBVyxHQUFHZixJQUFJO0VBQzlCO0VBRUEsU0FBU3FDLFdBQVdBLENBQUNsQyxPQUFPLEVBQUVxQixJQUFJLEVBQUU7SUFDaEMsSUFBSSxDQUFDckIsT0FBTyxFQUFFO0lBQ2RBLE9BQU8sQ0FBQ21DLFNBQVMsR0FBRzlDLFNBQVMsQ0FBQzJDLFFBQVEsQ0FBQ1gsSUFBSSxDQUFDO0VBQ2hEO0VBRUEsU0FBU2UsdUJBQXVCQSxDQUFDQyxHQUFHLEVBQUVDLFVBQVUsRUFBRTtJQUM5Q0EsVUFBVSxHQUFHQSxVQUFVLEtBQUssT0FBT3ZGLFFBQVEsS0FBSyxXQUFXLEdBQUdBLFFBQVEsR0FBRyxJQUFJLENBQUM7SUFDOUUsSUFBSSxDQUFDdUYsVUFBVSxFQUFFLE9BQU8sRUFBRTtJQUMxQixJQUFJQyxRQUFRLEdBQUdGLEdBQUcsR0FBRyxxQkFBcUIsR0FBR0EsR0FBRyxHQUFHLElBQUksR0FBRyxvQkFBb0I7SUFDOUUsT0FBT0MsVUFBVSxDQUFDRSxnQkFBZ0IsQ0FBQ0QsUUFBUSxDQUFDO0VBQ2hEO0VBRUEsU0FBU0UsV0FBV0EsQ0FBQ0MsTUFBTSxFQUFFQyxhQUFhLEVBQUU7SUFDeEMsSUFBSSxDQUFDQSxhQUFhLElBQUksSUFBQUMsUUFBQSxDQUFBQyxPQUFBLEVBQU9GLGFBQWEsTUFBSyxRQUFRLEVBQUU7TUFDckRqRyxPQUFPLENBQUNDLElBQUksQ0FBQyx5RkFBeUYsQ0FBQztNQUN2RyxPQUFPLElBQUk7SUFDZjtJQUNBLElBQUlnRyxhQUFhLENBQUNELE1BQU0sQ0FBQyxFQUFFLE9BQU9DLGFBQWEsQ0FBQ0QsTUFBTSxDQUFDO0lBQ3ZELElBQUlDLGFBQWEsQ0FBQyxTQUFTLENBQUMsRUFBRSxPQUFPQSxhQUFhLENBQUMsU0FBUyxDQUFDO0lBQzdELElBQUlHLFFBQVEsR0FBR3RFLE1BQU0sQ0FBQ0MsSUFBSSxDQUFDa0UsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVDLElBQUlHLFFBQVEsRUFBRTtNQUNWcEcsT0FBTyxDQUFDQyxJQUFJLENBQUMsNEJBQTRCLEdBQUcrRixNQUFNLEdBQUcsOENBQThDLEVBQUVJLFFBQVEsQ0FBQztNQUM5RyxPQUFPSCxhQUFhLENBQUNHLFFBQVEsQ0FBQztJQUNsQztJQUNBLE9BQU8sSUFBSTtFQUNmOztFQUVBO0VBQ0E7RUFDQTs7RUFFQSxTQUFTQyxvQkFBb0JBLENBQUNDLEtBQUssRUFBRUMsT0FBTyxFQUFFO0lBQzFDLElBQUlELEtBQUssQ0FBQ3RFLE1BQU0sS0FBS3VFLE9BQU8sQ0FBQ3ZFLE1BQU0sRUFBRSxPQUFPc0UsS0FBSyxDQUFDLENBQUMsQ0FBQztJQUNwRCxJQUFJRSxHQUFHLEdBQUcsQ0FBQztJQUNYLElBQUk5QyxDQUFDO0lBQ0wsS0FBS0EsQ0FBQyxHQUFHLENBQUMsRUFBRUEsQ0FBQyxHQUFHNkMsT0FBTyxDQUFDdkUsTUFBTSxFQUFFMEIsQ0FBQyxFQUFFLEVBQUU7TUFBRThDLEdBQUcsSUFBSUQsT0FBTyxDQUFDN0MsQ0FBQyxDQUFDO0lBQUM7SUFDekQsSUFBSTJCLENBQUMsR0FBR29CLElBQUksQ0FBQ0MsTUFBTSxDQUFDLENBQUMsR0FBR0YsR0FBRztJQUMzQixJQUFJRyxLQUFLLEdBQUcsQ0FBQztJQUNiLEtBQUtqRCxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUc0QyxLQUFLLENBQUN0RSxNQUFNLEVBQUUwQixDQUFDLEVBQUUsRUFBRTtNQUMvQmlELEtBQUssSUFBSUosT0FBTyxDQUFDN0MsQ0FBQyxDQUFDO01BQ25CLElBQUkyQixDQUFDLElBQUlzQixLQUFLLEVBQUUsT0FBT0wsS0FBSyxDQUFDNUMsQ0FBQyxDQUFDO0lBQ25DO0lBQ0EsT0FBTzRDLEtBQUssQ0FBQ0EsS0FBSyxDQUFDdEUsTUFBTSxHQUFHLENBQUMsQ0FBQztFQUNsQztFQUVBLFNBQVM0RSx1QkFBdUJBLENBQUNYLGFBQWEsRUFBRTtJQUM1QyxJQUFJLENBQUNBLGFBQWEsSUFBSSxJQUFBQyxRQUFBLENBQUFDLE9BQUEsRUFBT0YsYUFBYSxNQUFLLFFBQVEsRUFBRSxPQUFPLElBQUk7SUFDcEUsSUFBSUssS0FBSyxHQUFHeEUsTUFBTSxDQUFDQyxJQUFJLENBQUNrRSxhQUFhLENBQUM7SUFDdEMsSUFBSUssS0FBSyxDQUFDdEUsTUFBTSxLQUFLLENBQUMsRUFBRSxPQUFPLElBQUk7SUFDbkMsSUFBSXVFLE9BQU8sR0FBRyxFQUFFO0lBQ2hCLEtBQUssSUFBSTdDLENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBRzRDLEtBQUssQ0FBQ3RFLE1BQU0sRUFBRTBCLENBQUMsRUFBRSxFQUFFO01BQUU2QyxPQUFPLENBQUNNLElBQUksQ0FBQyxDQUFDLENBQUM7SUFBQztJQUN6RCxPQUFPUixvQkFBb0IsQ0FBQ0MsS0FBSyxFQUFFQyxPQUFPLENBQUM7RUFDL0M7O0VBRUE7RUFDQTtFQUNBOztFQUVBLElBQUlPLGNBQWMsR0FBRztJQUNqQjtBQUNSO0FBQ0E7QUFDQTtJQUNRQyxjQUFjLEVBQUUsU0FBaEJBLGNBQWNBLENBQVk5RixPQUFPLEVBQUVPLE9BQU8sRUFBRTtNQUN4Q0EsT0FBTyxHQUFHQSxPQUFPLElBQUksQ0FBQyxDQUFDO01BQ3ZCLElBQUl3RixXQUFXLEdBQUd4RixPQUFPLENBQUN5RixLQUFLLElBQUksQ0FBQyxDQUFDO01BQ3JDLElBQUloQixhQUFhLEdBQUd6RSxPQUFPLENBQUMwRixTQUFTO01BQ3JDLElBQUlDLG9CQUFvQixHQUFHM0YsT0FBTyxDQUFDNEYsY0FBYyxLQUFLLEtBQUs7TUFFM0QsSUFBSSxDQUFDbkIsYUFBYSxJQUFJLElBQUFDLFFBQUEsQ0FBQUMsT0FBQSxFQUFPRixhQUFhLE1BQUssUUFBUSxJQUFJbkUsTUFBTSxDQUFDQyxJQUFJLENBQUNrRSxhQUFhLENBQUMsQ0FBQ2pFLE1BQU0sS0FBSyxDQUFDLEVBQUU7UUFDaEdoQyxPQUFPLENBQUNDLElBQUksQ0FBQyx5RkFBeUYsQ0FBQztRQUN2RyxPQUFPO1VBQ0hvSCxRQUFRLEVBQUUsSUFBSTtVQUNkckIsTUFBTSxFQUFFLFNBQVM7VUFDakI3RixNQUFNLEVBQUUsT0FBTztVQUNmYyxPQUFPLEVBQUVBLE9BQU87VUFDaEJ3QixLQUFLLEVBQUU7UUFDWCxDQUFDO01BQ0w7TUFFQSxJQUFJdUQsTUFBTSxHQUFHL0UsT0FBTyxDQUFDWSxhQUFhO01BQ2xDLElBQUkxQixNQUFNLEdBQUcsU0FBUztNQUV0QixJQUFJYyxPQUFPLENBQUNXLE1BQU0sRUFBRTtRQUNoQnpCLE1BQU0sR0FBRyxLQUFLO01BQ2xCLENBQUMsTUFBTSxJQUFJYyxPQUFPLENBQUNYLFFBQVEsSUFBSVcsT0FBTyxDQUFDWCxRQUFRLENBQUNGLFFBQVEsS0FBSyxRQUFRLEVBQUU7UUFDbkVELE1BQU0sR0FBRyxVQUFVO01BQ3ZCO01BRUEsS0FBSyxJQUFJbUgsT0FBTyxJQUFJTixXQUFXLEVBQUU7UUFDN0IsSUFBSU8sSUFBSSxHQUFHUCxXQUFXLENBQUNNLE9BQU8sQ0FBQztRQUMvQixJQUFJLE9BQU9DLElBQUksQ0FBQ3hDLEtBQUssS0FBSyxVQUFVLElBQUl3QyxJQUFJLENBQUN4QyxLQUFLLENBQUM5RCxPQUFPLENBQUMsRUFBRTtVQUN6RCtFLE1BQU0sR0FBR3VCLElBQUksQ0FBQ3ZCLE1BQU0sSUFBSXNCLE9BQU87VUFDL0JuSCxNQUFNLEdBQUcsYUFBYTtVQUN0QjtRQUNKO01BQ0o7TUFFQSxJQUFJNkYsTUFBTSxLQUFLLFNBQVMsSUFBSTdGLE1BQU0sS0FBSyxTQUFTLElBQUlnSCxvQkFBb0IsRUFBRTtRQUN0RSxJQUFJSyxZQUFZLEdBQUdaLHVCQUF1QixDQUFDWCxhQUFhLENBQUM7UUFDekQsSUFBSXVCLFlBQVksRUFBRTtVQUNkeEIsTUFBTSxHQUFHd0IsWUFBWTtVQUNyQnJILE1BQU0sR0FBRyxXQUFXO1FBQ3hCO01BQ0o7O01BRUE7TUFDQSxJQUFJdEMsSUFBSSxDQUFDNEosa0JBQWtCLElBQUksT0FBTzVKLElBQUksQ0FBQzRKLGtCQUFrQixDQUFDQyxXQUFXLEtBQUssVUFBVSxFQUFFO1FBQ3RGN0osSUFBSSxDQUFDNEosa0JBQWtCLENBQUNDLFdBQVcsQ0FBQztVQUNoQ3pHLE9BQU8sRUFBRUEsT0FBTztVQUNoQitFLE1BQU0sRUFBRUEsTUFBTTtVQUNkMkIsZUFBZSxFQUFFM0IsTUFBTTtVQUN2QjdGLE1BQU0sRUFBRUEsTUFBTTtVQUNkeUgsVUFBVSxFQUFFO1FBQ2hCLENBQUMsQ0FBQztNQUNOO01BRUEsT0FBTztRQUNIUCxRQUFRLEVBQUV0QixXQUFXLENBQUNDLE1BQU0sRUFBRUMsYUFBYSxDQUFDO1FBQzVDRCxNQUFNLEVBQUVBLE1BQU07UUFDZDdGLE1BQU0sRUFBRUEsTUFBTTtRQUNkYyxPQUFPLEVBQUVBO01BQ2IsQ0FBQztJQUNMLENBQUM7SUFFRDtBQUNSO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0lBQ1E0RyxNQUFNLEVBQUUsU0FBUkEsTUFBTUEsQ0FBWTVHLE9BQU8sRUFBRU8sT0FBTyxFQUFFO01BQ2hDQSxPQUFPLEdBQUdBLE9BQU8sSUFBSSxDQUFDLENBQUM7O01BRXZCO01BQ0EsSUFBSUEsT0FBTyxDQUFDc0csUUFBUSxJQUFJdEcsT0FBTyxDQUFDdUcsUUFBUSxJQUFJbEssSUFBSSxDQUFDbUssZ0JBQWdCLEVBQUU7UUFDL0QsSUFBSUMsSUFBSSxHQUFHLElBQUk7UUFDZixJQUFJQyxRQUFRLEdBQUdySyxJQUFJLENBQUNtSyxnQkFBZ0I7UUFDcEMsSUFBSUcsU0FBUyxHQUFHRCxRQUFRLENBQUNFLE9BQU8sQ0FBQzVHLE9BQU8sQ0FBQ3VHLFFBQVEsQ0FBQztRQUVsRCxJQUFJSSxTQUFTLENBQUNFLEtBQUssRUFBRTtVQUNqQixPQUFPSCxRQUFRLENBQUNMLE1BQU0sQ0FBQzVHLE9BQU8sRUFBRU8sT0FBTyxDQUFDLENBQ25DOEcsS0FBSyxDQUFDLFVBQVU3RixLQUFLLEVBQUU7WUFDcEIsSUFBSThGLFFBQVEsR0FBRy9HLE9BQU8sQ0FBQ3VHLFFBQVEsQ0FBQ1Msa0JBQWtCLEtBQUssS0FBSztZQUM1RCxJQUFJRCxRQUFRLEVBQUU7Y0FDVnZJLE9BQU8sQ0FBQ0MsSUFBSSxDQUFDLHFEQUFxRCxFQUFFd0MsS0FBSyxDQUFDQyxPQUFPLENBQUM7Y0FDbEYsT0FBT3VGLElBQUksQ0FBQ2xCLGNBQWMsQ0FBQzlGLE9BQU8sRUFBRU8sT0FBTyxDQUFDO1lBQ2hEO1lBQ0EsTUFBTWlCLEtBQUs7VUFDZixDQUFDLENBQUM7UUFDVixDQUFDLE1BQU07VUFDSHpDLE9BQU8sQ0FBQ0MsSUFBSSxDQUFDLGlDQUFpQyxFQUFFa0ksU0FBUyxDQUFDMUYsS0FBSyxFQUFFLHlCQUF5QixDQUFDO1FBQy9GO01BQ0o7TUFFQSxPQUFPLElBQUksQ0FBQ3NFLGNBQWMsQ0FBQzlGLE9BQU8sRUFBRU8sT0FBTyxDQUFDO0lBQ2hEO0VBQ0osQ0FBQzs7RUFFRDtFQUNBO0VBQ0E7O0VBRUE7QUFDSjtBQUNBO0FBQ0E7QUFDQTtBQUNBO0VBQ0ksU0FBU2lILGtCQUFrQkEsQ0FBQ0MsUUFBUSxFQUFFbEgsT0FBTyxFQUFFO0lBQzNDQSxPQUFPLEdBQUdBLE9BQU8sSUFBSSxDQUFDLENBQUM7SUFDdkIsSUFBSTZGLFFBQVEsR0FBR3FCLFFBQVEsQ0FBQ3JCLFFBQVE7SUFDaEMsSUFBSXBHLE9BQU8sR0FBR3lILFFBQVEsQ0FBQ3pILE9BQU8sSUFBSSxDQUFDLENBQUM7SUFDcEMsSUFBSTBILEdBQUcsR0FBR25ILE9BQU8sQ0FBQ21ILEdBQUcsS0FBSyxLQUFLO0lBRS9CLElBQUksQ0FBQ3RCLFFBQVEsRUFBRTtNQUNYckgsT0FBTyxDQUFDQyxJQUFJLENBQUMsZ0VBQWdFLENBQUM7TUFDOUUsT0FBT3lJLFFBQVE7SUFDbkI7SUFFQSxJQUFJRSxLQUFLLEdBQUcsQ0FBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxVQUFVLEVBQUUsU0FBUyxDQUFDO0lBRXZFQSxLQUFLLENBQUNoSixPQUFPLENBQUMsVUFBVWlKLElBQUksRUFBRTtNQUMxQixJQUFJQyxRQUFRLEdBQUdwRCx1QkFBdUIsQ0FBQ21ELElBQUksQ0FBQztNQUM1QyxLQUFLLElBQUluRixDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdvRixRQUFRLENBQUM5RyxNQUFNLEVBQUUwQixDQUFDLEVBQUUsRUFBRTtRQUN0QyxJQUFJcUYsRUFBRSxHQUFHRCxRQUFRLENBQUNwRixDQUFDLENBQUM7UUFDcEIsSUFBSXpFLEtBQUssR0FBR29JLFFBQVEsQ0FBQ3dCLElBQUksQ0FBQztRQUMxQixJQUFJLENBQUM1SixLQUFLLEVBQUU7UUFFWixJQUFJNEosSUFBSSxLQUFLLE9BQU8sRUFBRTtVQUNsQixJQUFJRSxFQUFFLENBQUMzRSxPQUFPLEtBQUssS0FBSyxFQUFFO1lBQ3RCMkUsRUFBRSxDQUFDQyxHQUFHLEdBQUcvSixLQUFLO1lBQ2Q4SixFQUFFLENBQUNFLEdBQUcsR0FBRzVCLFFBQVEsQ0FBQzZCLFFBQVEsSUFBSSxvQkFBb0I7VUFDdEQsQ0FBQyxNQUFNO1lBQ0hILEVBQUUsQ0FBQ0ksS0FBSyxDQUFDQyxlQUFlLEdBQUcsTUFBTSxHQUFHbkssS0FBSyxHQUFHLEdBQUc7VUFDbkQ7UUFDSixDQUFDLE1BQU0sSUFBSTRKLElBQUksS0FBSyxTQUFTLEVBQUU7VUFDM0JFLEVBQUUsQ0FBQ00sSUFBSSxHQUFHcEssS0FBSztRQUNuQixDQUFDLE1BQU07VUFDSHNHLFdBQVcsQ0FBQ3dELEVBQUUsRUFBRTlKLEtBQUssQ0FBQztRQUMxQjtNQUNKO0lBQ0osQ0FBQyxDQUFDOztJQUVGO0lBQ0EsSUFBSXFLLFlBQVksR0FBRzVELHVCQUF1QixDQUFDLE1BQU0sQ0FBQztJQUNsRCxLQUFLLElBQUk2RCxDQUFDLEdBQUcsQ0FBQyxFQUFFQSxDQUFDLEdBQUdELFlBQVksQ0FBQ3RILE1BQU0sRUFBRXVILENBQUMsRUFBRSxFQUFFO01BQzFDLElBQUlDLE1BQU0sR0FBR0YsWUFBWSxDQUFDQyxDQUFDLENBQUM7TUFDNUJDLE1BQU0sQ0FBQ0MsWUFBWSxDQUFDLGFBQWEsRUFBRWYsUUFBUSxDQUFDMUMsTUFBTSxDQUFDO01BQ25Ed0QsTUFBTSxDQUFDQyxZQUFZLENBQUMsYUFBYSxFQUFFZixRQUFRLENBQUN2SSxNQUFNLENBQUM7TUFDbkQsSUFBSWtILFFBQVEsQ0FBQ3FDLEtBQUssSUFBSSxDQUFDRixNQUFNLENBQUNHLGFBQWEsQ0FBQyw0QkFBNEIsQ0FBQyxFQUFFO1FBQ3ZFSCxNQUFNLENBQUNMLEtBQUssQ0FBQ0MsZUFBZSxHQUFHLE1BQU0sR0FBRy9CLFFBQVEsQ0FBQ3FDLEtBQUssR0FBRyxHQUFHO01BQ2hFO0lBQ0o7SUFFQSxJQUFJZixHQUFHLElBQUksT0FBTzNJLE9BQU8sS0FBSyxXQUFXLEVBQUU7TUFDdkNBLE9BQU8sQ0FBQzJJLEdBQUcsQ0FBQyw0QkFBNEIsRUFBRTtRQUN0QzNDLE1BQU0sRUFBRTBDLFFBQVEsQ0FBQzFDLE1BQU07UUFDdkI3RixNQUFNLEVBQUV1SSxRQUFRLENBQUN2SSxNQUFNO1FBQ3ZCK0ksUUFBUSxFQUFFN0IsUUFBUSxDQUFDNkIsUUFBUTtRQUMzQnRILE1BQU0sRUFBRVgsT0FBTyxDQUFDVyxNQUFNO1FBQ3RCZ0ksU0FBUyxFQUFFM0ksT0FBTyxDQUFDQyxHQUFHLElBQUksQ0FBQyxDQUFDO1FBQzVCMkksU0FBUyxFQUFFbkIsUUFBUSxDQUFDdkksTUFBTSxLQUFLLElBQUksSUFBSXVJLFFBQVEsQ0FBQ3ZJLE1BQU0sS0FBSztNQUMvRCxDQUFDLENBQUM7SUFDTjtJQUVBLE9BQU91SSxRQUFRO0VBQ25COztFQUVBO0VBQ0E7RUFDQTs7RUFFQTtBQUNKO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDSSxTQUFTb0IsV0FBV0EsQ0FBQ3RJLE9BQU8sRUFBRTtJQUMxQkEsT0FBTyxHQUFHQSxPQUFPLElBQUksQ0FBQyxDQUFDOztJQUV2QjtJQUNBLElBQUksQ0FBQ0EsT0FBTyxDQUFDMEYsU0FBUyxJQUFJLElBQUFoQixRQUFBLENBQUFDLE9BQUEsRUFBTzNFLE9BQU8sQ0FBQzBGLFNBQVMsTUFBSyxRQUFRLElBQUlwRixNQUFNLENBQUNDLElBQUksQ0FBQ1AsT0FBTyxDQUFDMEYsU0FBUyxDQUFDLENBQUNsRixNQUFNLEtBQUssQ0FBQyxFQUFFO01BQzVHaEMsT0FBTyxDQUFDeUMsS0FBSyxDQUFDLG1GQUFtRixDQUFDO01BQ2xHLE9BQU87UUFDSDRFLFFBQVEsRUFBRSxJQUFJO1FBQ2RyQixNQUFNLEVBQUUsU0FBUztRQUNqQjdGLE1BQU0sRUFBRSxPQUFPO1FBQ2ZjLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFDWHdCLEtBQUssRUFBRTtNQUNYLENBQUM7SUFDTDtJQUVBLElBQUl4QixPQUFPLEdBQUdPLE9BQU8sQ0FBQ1AsT0FBTyxJQUFJTSxVQUFVLENBQUNDLE9BQU8sQ0FBQztJQUNwRCxJQUFJa0gsUUFBUSxHQUFHNUIsY0FBYyxDQUFDZSxNQUFNLENBQUM1RyxPQUFPLEVBQUVPLE9BQU8sQ0FBQzs7SUFFdEQ7SUFDQSxJQUFJa0gsUUFBUSxJQUFJLE9BQU9BLFFBQVEsQ0FBQ3FCLElBQUksS0FBSyxVQUFVLEVBQUU7TUFDakQsT0FBT3JCLFFBQVEsQ0FBQ3FCLElBQUksQ0FBQyxVQUFVbkMsVUFBVSxFQUFFO1FBQ3ZDLE9BQU9hLGtCQUFrQixDQUFDYixVQUFVLEVBQUVwRyxPQUFPLENBQUM7TUFDbEQsQ0FBQyxDQUFDLENBQUM4RyxLQUFLLENBQUMsVUFBVTBCLEdBQUcsRUFBRTtRQUNwQmhLLE9BQU8sQ0FBQ0MsSUFBSSxDQUFDLHVEQUF1RCxFQUFFK0osR0FBRyxDQUFDdEgsT0FBTyxDQUFDO1FBQ2xGLElBQUl1SCxnQkFBZ0IsR0FBR25ELGNBQWMsQ0FBQ0MsY0FBYyxDQUFDOUYsT0FBTyxFQUFFTyxPQUFPLENBQUM7UUFDdEUsT0FBT2lILGtCQUFrQixDQUFDd0IsZ0JBQWdCLEVBQUV6SSxPQUFPLENBQUM7TUFDeEQsQ0FBQyxDQUFDO0lBQ047O0lBRUE7SUFDQSxPQUFPaUgsa0JBQWtCLENBQUNDLFFBQVEsRUFBRWxILE9BQU8sQ0FBQztFQUNoRDs7RUFFQTtBQUNKO0FBQ0E7QUFDQTtFQUNJLFNBQVMwSSxnQkFBZ0JBLENBQUMxSSxPQUFPLEVBQUU7SUFDL0JBLE9BQU8sR0FBR0EsT0FBTyxJQUFJLENBQUMsQ0FBQztJQUN2QixPQUFPUyxlQUFlLENBQUNULE9BQU8sQ0FBQyxDQUFDdUksSUFBSSxDQUFDLFVBQVU5SSxPQUFPLEVBQUU7TUFDcERPLE9BQU8sQ0FBQ1AsT0FBTyxHQUFHQSxPQUFPO01BQ3pCLE9BQU82SSxXQUFXLENBQUN0SSxPQUFPLENBQUM7SUFDL0IsQ0FBQyxDQUFDLENBQUN1SSxJQUFJLENBQUMsVUFBVXJCLFFBQVEsRUFBRTtNQUN4QixPQUFPQSxRQUFRO0lBQ25CLENBQUMsQ0FBQyxDQUFDSixLQUFLLENBQUMsVUFBVTBCLEdBQUcsRUFBRTtNQUNwQmhLLE9BQU8sQ0FBQ0MsSUFBSSxDQUFDLCtDQUErQyxFQUFFK0osR0FBRyxDQUFDO01BQ2xFLElBQUlHLEdBQUcsR0FBRzVJLFVBQVUsQ0FBQ0MsT0FBTyxDQUFDO01BQzdCLElBQUkrRyxRQUFRLEdBQUd6QixjQUFjLENBQUNDLGNBQWMsQ0FBQ29ELEdBQUcsRUFBRTtRQUFFakQsU0FBUyxFQUFFMUYsT0FBTyxDQUFDMEY7TUFBVSxDQUFDLENBQUM7TUFDbkYsT0FBT3VCLGtCQUFrQixDQUFDRixRQUFRLEVBQUUvRyxPQUFPLENBQUM7SUFDaEQsQ0FBQyxDQUFDO0VBQ047O0VBRUE7RUFDQTtFQUNBOztFQUVBO0FBQ0o7QUFDQTtBQUNBO0VBQ0ksU0FBUzRJLFFBQVFBLENBQUM1SSxPQUFPLEVBQUU7SUFDdkJBLE9BQU8sR0FBR0EsT0FBTyxJQUFJLENBQUMsQ0FBQztJQUV2QixTQUFTNkksR0FBR0EsQ0FBQSxFQUFHO01BQ1gsSUFBSXZCLFFBQVEsR0FBR3BELHVCQUF1QixDQUFDLENBQUM7TUFDeEMsSUFBSW9ELFFBQVEsQ0FBQzlHLE1BQU0sR0FBRyxDQUFDLEVBQUU7UUFDckI4SCxXQUFXLENBQUN0SSxPQUFPLENBQUM7TUFDeEI7SUFDSjtJQUVBLElBQUksT0FBT25CLFFBQVEsS0FBSyxXQUFXLEVBQUU7TUFDakMsSUFBSUEsUUFBUSxDQUFDaUssVUFBVSxLQUFLLFNBQVMsRUFBRTtRQUNuQ2pLLFFBQVEsQ0FBQ2tLLGdCQUFnQixDQUFDLGtCQUFrQixFQUFFRixHQUFHLENBQUM7TUFDdEQsQ0FBQyxNQUFNO1FBQ0hBLEdBQUcsQ0FBQyxDQUFDO01BQ1Q7SUFDSjtFQUNKOztFQUVBO0VBQ0E7RUFDQTs7RUFFQSxJQUFJRyxpQkFBaUIsR0FBRztJQUNwQjtJQUNBbkwsZ0JBQWdCLEVBQUVBLGdCQUFnQjtJQUNsQ0wsYUFBYSxFQUFFQSxhQUFhO0lBQzVCa0IsY0FBYyxFQUFFQSxjQUFjO0lBQzlCTyxnQkFBZ0IsRUFBRUEsZ0JBQWdCO0lBQ2xDYyxVQUFVLEVBQUVBLFVBQVU7SUFDdEJVLGVBQWUsRUFBRUEsZUFBZTtJQUNoQ2pCLFdBQVcsRUFBRUEsV0FBVztJQUV4QjtJQUNBeUosU0FBUyxFQUFFOUgsU0FBUztJQUNwQitILFlBQVksRUFBRSxTQUFkQSxZQUFZQSxDQUFZL0YsSUFBSSxFQUFFO01BQUUsT0FBT2hDLFNBQVMsQ0FBQzJDLFFBQVEsQ0FBQ1gsSUFBSSxDQUFDO0lBQUMsQ0FBQztJQUVqRTtJQUNBWSxXQUFXLEVBQUVBLFdBQVc7SUFDeEJDLFdBQVcsRUFBRUEsV0FBVztJQUN4Qm1GLFlBQVksRUFBRWpGLHVCQUF1QjtJQUNyQytDLGtCQUFrQixFQUFFQSxrQkFBa0I7SUFFdEM7SUFDQTFDLFdBQVcsRUFBRUEsV0FBVztJQUV4QjtJQUNBNkUsTUFBTSxFQUFFOUQsY0FBYztJQUN0QlQsb0JBQW9CLEVBQUVBLG9CQUFvQjtJQUMxQ08sdUJBQXVCLEVBQUVBLHVCQUF1QjtJQUVoRDtJQUNBa0QsV0FBVyxFQUFFQSxXQUFXO0lBQ3hCSSxnQkFBZ0IsRUFBRUEsZ0JBQWdCO0lBQ2xDRSxRQUFRLEVBQUVBLFFBQVE7SUFFbEI7SUFDQXJNLFVBQVUsRUFBRUEsVUFBVTtJQUN0QkQsY0FBYyxFQUFFQSxjQUFjO0lBQzlCRSxpQkFBaUIsRUFBRUEsaUJBQWlCO0lBQ3BDYSxtQkFBbUIsRUFBRUE7RUFDekIsQ0FBQzs7RUFFRDtFQUNBaEIsSUFBSSxDQUFDMk0saUJBQWlCLEdBQUdBLGlCQUFpQjs7RUFFMUM7RUFDQSxJQUFJLENBQUMzTSxJQUFJLENBQUNnTixNQUFNLEVBQUU7SUFDZGhOLElBQUksQ0FBQ2dOLE1BQU0sR0FBRztNQUNWeEwsZ0JBQWdCLEVBQUVBLGdCQUFnQjtNQUNsQ0wsYUFBYSxFQUFFQSxhQUFhO01BQzVCa0IsY0FBYyxFQUFFQSxjQUFjO01BQzlCTyxnQkFBZ0IsRUFBRUEsZ0JBQWdCO01BQ2xDYyxVQUFVLEVBQUVBLFVBQVU7TUFDdEJVLGVBQWUsRUFBRUEsZUFBZTtNQUNoQ2pCLFdBQVcsRUFBRUEsV0FBVztNQUN4QmpELFVBQVUsRUFBRUEsVUFBVTtNQUN0QkQsY0FBYyxFQUFFQSxjQUFjO01BQzlCRSxpQkFBaUIsRUFBRUEsaUJBQWlCO01BQ3BDYSxtQkFBbUIsRUFBRUE7SUFDekIsQ0FBQztFQUNMO0VBQ0EsSUFBSSxDQUFDaEIsSUFBSSxDQUFDaU4sY0FBYyxFQUFFO0lBQ3RCak4sSUFBSSxDQUFDaU4sY0FBYyxHQUFHO01BQ2xCTCxTQUFTLEVBQUU5SCxTQUFTO01BQ3BCK0gsWUFBWSxFQUFFLFNBQWRBLFlBQVlBLENBQVkvRixJQUFJLEVBQUU7UUFBRSxPQUFPaEMsU0FBUyxDQUFDMkMsUUFBUSxDQUFDWCxJQUFJLENBQUM7TUFBQyxDQUFDO01BQ2pFWSxXQUFXLEVBQUVBLFdBQVc7TUFDeEJDLFdBQVcsRUFBRUEsV0FBVztNQUN4Qm1GLFlBQVksRUFBRWpGLHVCQUF1QjtNQUNyQytDLGtCQUFrQixFQUFFQSxrQkFBa0I7TUFDdEMxQyxXQUFXLEVBQUVBLFdBQVc7TUFDeEI2RSxNQUFNLEVBQUU5RCxjQUFjO01BQ3RCZ0QsV0FBVyxFQUFFQSxXQUFXO01BQ3hCSSxnQkFBZ0IsRUFBRUEsZ0JBQWdCO01BQ2xDRSxRQUFRLEVBQUVBLFFBQVE7TUFDbEIvRCxvQkFBb0IsRUFBRUEsb0JBQW9CO01BQzFDTyx1QkFBdUIsRUFBRUE7SUFDN0IsQ0FBQztFQUNMOztFQUVBO0VBQ0E7QUFFSixDQUFDLEVBQUUsT0FBT21FLE1BQU0sS0FBSyxXQUFXLEdBQUdBLE1BQU0sR0FBRyxPQUFPQyxNQUFNLEtBQUssV0FBVyxHQUFHQSxNQUFNLFNBQU8sQ0FBQyIsImlnbm9yZUxpc3QiOltdfQ==