source: trip-planner-front/node_modules/@angular/compiler/src/render3/view/styling_builder.js

Last change on this file was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 70.9 KB
Line 
1(function (factory) {
2 if (typeof module === "object" && typeof module.exports === "object") {
3 var v = factory(require, exports);
4 if (v !== undefined) module.exports = v;
5 }
6 else if (typeof define === "function" && define.amd) {
7 define("@angular/compiler/src/render3/view/styling_builder", ["require", "exports", "tslib", "@angular/compiler/src/expression_parser/ast", "@angular/compiler/src/output/output_ast", "@angular/compiler/src/template_parser/template_parser", "@angular/compiler/src/render3/r3_identifiers", "@angular/compiler/src/render3/view/style_parser", "@angular/compiler/src/render3/view/util"], factory);
8 }
9})(function (require, exports) {
10 "use strict";
11 Object.defineProperty(exports, "__esModule", { value: true });
12 exports.parseProperty = exports.StylingBuilder = exports.MIN_STYLING_BINDING_SLOTS_REQUIRED = void 0;
13 var tslib_1 = require("tslib");
14 var ast_1 = require("@angular/compiler/src/expression_parser/ast");
15 var o = require("@angular/compiler/src/output/output_ast");
16 var template_parser_1 = require("@angular/compiler/src/template_parser/template_parser");
17 var r3_identifiers_1 = require("@angular/compiler/src/render3/r3_identifiers");
18 var style_parser_1 = require("@angular/compiler/src/render3/view/style_parser");
19 var util_1 = require("@angular/compiler/src/render3/view/util");
20 var IMPORTANT_FLAG = '!important';
21 /**
22 * Minimum amount of binding slots required in the runtime for style/class bindings.
23 *
24 * Styling in Angular uses up two slots in the runtime LView/TData data structures to
25 * record binding data, property information and metadata.
26 *
27 * When a binding is registered it will place the following information in the `LView`:
28 *
29 * slot 1) binding value
30 * slot 2) cached value (all other values collected before it in string form)
31 *
32 * When a binding is registered it will place the following information in the `TData`:
33 *
34 * slot 1) prop name
35 * slot 2) binding index that points to the previous style/class binding (and some extra config
36 * values)
37 *
38 * Let's imagine we have a binding that looks like so:
39 *
40 * ```
41 * <div [style.width]="x" [style.height]="y">
42 * ```
43 *
44 * Our `LView` and `TData` data-structures look like so:
45 *
46 * ```typescript
47 * LView = [
48 * // ...
49 * x, // value of x
50 * "width: x",
51 *
52 * y, // value of y
53 * "width: x; height: y",
54 * // ...
55 * ];
56 *
57 * TData = [
58 * // ...
59 * "width", // binding slot 20
60 * 0,
61 *
62 * "height",
63 * 20,
64 * // ...
65 * ];
66 * ```
67 *
68 * */
69 exports.MIN_STYLING_BINDING_SLOTS_REQUIRED = 2;
70 /**
71 * Produces creation/update instructions for all styling bindings (class and style)
72 *
73 * It also produces the creation instruction to register all initial styling values
74 * (which are all the static class="..." and style="..." attribute values that exist
75 * on an element within a template).
76 *
77 * The builder class below handles producing instructions for the following cases:
78 *
79 * - Static style/class attributes (style="..." and class="...")
80 * - Dynamic style/class map bindings ([style]="map" and [class]="map|string")
81 * - Dynamic style/class property bindings ([style.prop]="exp" and [class.name]="exp")
82 *
83 * Due to the complex relationship of all of these cases, the instructions generated
84 * for these attributes/properties/bindings must be done so in the correct order. The
85 * order which these must be generated is as follows:
86 *
87 * if (createMode) {
88 * styling(...)
89 * }
90 * if (updateMode) {
91 * styleMap(...)
92 * classMap(...)
93 * styleProp(...)
94 * classProp(...)
95 * }
96 *
97 * The creation/update methods within the builder class produce these instructions.
98 */
99 var StylingBuilder = /** @class */ (function () {
100 function StylingBuilder(_directiveExpr) {
101 this._directiveExpr = _directiveExpr;
102 /** Whether or not there are any static styling values present */
103 this._hasInitialValues = false;
104 /**
105 * Whether or not there are any styling bindings present
106 * (i.e. `[style]`, `[class]`, `[style.prop]` or `[class.name]`)
107 */
108 this.hasBindings = false;
109 this.hasBindingsWithPipes = false;
110 /** the input for [class] (if it exists) */
111 this._classMapInput = null;
112 /** the input for [style] (if it exists) */
113 this._styleMapInput = null;
114 /** an array of each [style.prop] input */
115 this._singleStyleInputs = null;
116 /** an array of each [class.name] input */
117 this._singleClassInputs = null;
118 this._lastStylingInput = null;
119 this._firstStylingInput = null;
120 // maps are used instead of hash maps because a Map will
121 // retain the ordering of the keys
122 /**
123 * Represents the location of each style binding in the template
124 * (e.g. `<div [style.width]="w" [style.height]="h">` implies
125 * that `width=0` and `height=1`)
126 */
127 this._stylesIndex = new Map();
128 /**
129 * Represents the location of each class binding in the template
130 * (e.g. `<div [class.big]="b" [class.hidden]="h">` implies
131 * that `big=0` and `hidden=1`)
132 */
133 this._classesIndex = new Map();
134 this._initialStyleValues = [];
135 this._initialClassValues = [];
136 }
137 /**
138 * Registers a given input to the styling builder to be later used when producing AOT code.
139 *
140 * The code below will only accept the input if it is somehow tied to styling (whether it be
141 * style/class bindings or static style/class attributes).
142 */
143 StylingBuilder.prototype.registerBoundInput = function (input) {
144 // [attr.style] or [attr.class] are skipped in the code below,
145 // they should not be treated as styling-based bindings since
146 // they are intended to be written directly to the attr and
147 // will therefore skip all style/class resolution that is present
148 // with style="", [style]="" and [style.prop]="", class="",
149 // [class.prop]="". [class]="" assignments
150 var binding = null;
151 var name = input.name;
152 switch (input.type) {
153 case 0 /* Property */:
154 binding = this.registerInputBasedOnName(name, input.value, input.sourceSpan);
155 break;
156 case 3 /* Style */:
157 binding = this.registerStyleInput(name, false, input.value, input.sourceSpan, input.unit);
158 break;
159 case 2 /* Class */:
160 binding = this.registerClassInput(name, false, input.value, input.sourceSpan);
161 break;
162 }
163 return binding ? true : false;
164 };
165 StylingBuilder.prototype.registerInputBasedOnName = function (name, expression, sourceSpan) {
166 var binding = null;
167 var prefix = name.substring(0, 6);
168 var isStyle = name === 'style' || prefix === 'style.' || prefix === 'style!';
169 var isClass = !isStyle && (name === 'class' || prefix === 'class.' || prefix === 'class!');
170 if (isStyle || isClass) {
171 var isMapBased = name.charAt(5) !== '.'; // style.prop or class.prop makes this a no
172 var property = name.substr(isMapBased ? 5 : 6); // the dot explains why there's a +1
173 if (isStyle) {
174 binding = this.registerStyleInput(property, isMapBased, expression, sourceSpan);
175 }
176 else {
177 binding = this.registerClassInput(property, isMapBased, expression, sourceSpan);
178 }
179 }
180 return binding;
181 };
182 StylingBuilder.prototype.registerStyleInput = function (name, isMapBased, value, sourceSpan, suffix) {
183 if (template_parser_1.isEmptyExpression(value)) {
184 return null;
185 }
186 // CSS custom properties are case-sensitive so we shouldn't normalize them.
187 // See: https://www.w3.org/TR/css-variables-1/#defining-variables
188 if (!isCssCustomProperty(name)) {
189 name = style_parser_1.hyphenate(name);
190 }
191 var _a = parseProperty(name), property = _a.property, hasOverrideFlag = _a.hasOverrideFlag, bindingSuffix = _a.suffix;
192 suffix = typeof suffix === 'string' && suffix.length !== 0 ? suffix : bindingSuffix;
193 var entry = { name: property, suffix: suffix, value: value, sourceSpan: sourceSpan, hasOverrideFlag: hasOverrideFlag };
194 if (isMapBased) {
195 this._styleMapInput = entry;
196 }
197 else {
198 (this._singleStyleInputs = this._singleStyleInputs || []).push(entry);
199 registerIntoMap(this._stylesIndex, property);
200 }
201 this._lastStylingInput = entry;
202 this._firstStylingInput = this._firstStylingInput || entry;
203 this._checkForPipes(value);
204 this.hasBindings = true;
205 return entry;
206 };
207 StylingBuilder.prototype.registerClassInput = function (name, isMapBased, value, sourceSpan) {
208 if (template_parser_1.isEmptyExpression(value)) {
209 return null;
210 }
211 var _a = parseProperty(name), property = _a.property, hasOverrideFlag = _a.hasOverrideFlag;
212 var entry = { name: property, value: value, sourceSpan: sourceSpan, hasOverrideFlag: hasOverrideFlag, suffix: null };
213 if (isMapBased) {
214 this._classMapInput = entry;
215 }
216 else {
217 (this._singleClassInputs = this._singleClassInputs || []).push(entry);
218 registerIntoMap(this._classesIndex, property);
219 }
220 this._lastStylingInput = entry;
221 this._firstStylingInput = this._firstStylingInput || entry;
222 this._checkForPipes(value);
223 this.hasBindings = true;
224 return entry;
225 };
226 StylingBuilder.prototype._checkForPipes = function (value) {
227 if ((value instanceof ast_1.ASTWithSource) && (value.ast instanceof ast_1.BindingPipe)) {
228 this.hasBindingsWithPipes = true;
229 }
230 };
231 /**
232 * Registers the element's static style string value to the builder.
233 *
234 * @param value the style string (e.g. `width:100px; height:200px;`)
235 */
236 StylingBuilder.prototype.registerStyleAttr = function (value) {
237 this._initialStyleValues = style_parser_1.parse(value);
238 this._hasInitialValues = true;
239 };
240 /**
241 * Registers the element's static class string value to the builder.
242 *
243 * @param value the className string (e.g. `disabled gold zoom`)
244 */
245 StylingBuilder.prototype.registerClassAttr = function (value) {
246 this._initialClassValues = value.trim().split(/\s+/g);
247 this._hasInitialValues = true;
248 };
249 /**
250 * Appends all styling-related expressions to the provided attrs array.
251 *
252 * @param attrs an existing array where each of the styling expressions
253 * will be inserted into.
254 */
255 StylingBuilder.prototype.populateInitialStylingAttrs = function (attrs) {
256 // [CLASS_MARKER, 'foo', 'bar', 'baz' ...]
257 if (this._initialClassValues.length) {
258 attrs.push(o.literal(1 /* Classes */));
259 for (var i = 0; i < this._initialClassValues.length; i++) {
260 attrs.push(o.literal(this._initialClassValues[i]));
261 }
262 }
263 // [STYLE_MARKER, 'width', '200px', 'height', '100px', ...]
264 if (this._initialStyleValues.length) {
265 attrs.push(o.literal(2 /* Styles */));
266 for (var i = 0; i < this._initialStyleValues.length; i += 2) {
267 attrs.push(o.literal(this._initialStyleValues[i]), o.literal(this._initialStyleValues[i + 1]));
268 }
269 }
270 };
271 /**
272 * Builds an instruction with all the expressions and parameters for `elementHostAttrs`.
273 *
274 * The instruction generation code below is used for producing the AOT statement code which is
275 * responsible for registering initial styles (within a directive hostBindings' creation block),
276 * as well as any of the provided attribute values, to the directive host element.
277 */
278 StylingBuilder.prototype.assignHostAttrs = function (attrs, definitionMap) {
279 if (this._directiveExpr && (attrs.length || this._hasInitialValues)) {
280 this.populateInitialStylingAttrs(attrs);
281 definitionMap.set('hostAttrs', o.literalArr(attrs));
282 }
283 };
284 /**
285 * Builds an instruction with all the expressions and parameters for `classMap`.
286 *
287 * The instruction data will contain all expressions for `classMap` to function
288 * which includes the `[class]` expression params.
289 */
290 StylingBuilder.prototype.buildClassMapInstruction = function (valueConverter) {
291 if (this._classMapInput) {
292 return this._buildMapBasedInstruction(valueConverter, true, this._classMapInput);
293 }
294 return null;
295 };
296 /**
297 * Builds an instruction with all the expressions and parameters for `styleMap`.
298 *
299 * The instruction data will contain all expressions for `styleMap` to function
300 * which includes the `[style]` expression params.
301 */
302 StylingBuilder.prototype.buildStyleMapInstruction = function (valueConverter) {
303 if (this._styleMapInput) {
304 return this._buildMapBasedInstruction(valueConverter, false, this._styleMapInput);
305 }
306 return null;
307 };
308 StylingBuilder.prototype._buildMapBasedInstruction = function (valueConverter, isClassBased, stylingInput) {
309 // each styling binding value is stored in the LView
310 // map-based bindings allocate two slots: one for the
311 // previous binding value and another for the previous
312 // className or style attribute value.
313 var totalBindingSlotsRequired = exports.MIN_STYLING_BINDING_SLOTS_REQUIRED;
314 // these values must be outside of the update block so that they can
315 // be evaluated (the AST visit call) during creation time so that any
316 // pipes can be picked up in time before the template is built
317 var mapValue = stylingInput.value.visit(valueConverter);
318 var reference;
319 if (mapValue instanceof ast_1.Interpolation) {
320 totalBindingSlotsRequired += mapValue.expressions.length;
321 reference = isClassBased ? getClassMapInterpolationExpression(mapValue) :
322 getStyleMapInterpolationExpression(mapValue);
323 }
324 else {
325 reference = isClassBased ? r3_identifiers_1.Identifiers.classMap : r3_identifiers_1.Identifiers.styleMap;
326 }
327 return {
328 reference: reference,
329 calls: [{
330 supportsInterpolation: true,
331 sourceSpan: stylingInput.sourceSpan,
332 allocateBindingSlots: totalBindingSlotsRequired,
333 params: function (convertFn) {
334 var convertResult = convertFn(mapValue);
335 var params = Array.isArray(convertResult) ? convertResult : [convertResult];
336 return params;
337 }
338 }]
339 };
340 };
341 StylingBuilder.prototype._buildSingleInputs = function (reference, inputs, valueConverter, getInterpolationExpressionFn, isClassBased) {
342 var instructions = [];
343 inputs.forEach(function (input) {
344 var previousInstruction = instructions[instructions.length - 1];
345 var value = input.value.visit(valueConverter);
346 var referenceForCall = reference;
347 // each styling binding value is stored in the LView
348 // but there are two values stored for each binding:
349 // 1) the value itself
350 // 2) an intermediate value (concatenation of style up to this point).
351 // We need to store the intermediate value so that we don't allocate
352 // the strings on each CD.
353 var totalBindingSlotsRequired = exports.MIN_STYLING_BINDING_SLOTS_REQUIRED;
354 if (value instanceof ast_1.Interpolation) {
355 totalBindingSlotsRequired += value.expressions.length;
356 if (getInterpolationExpressionFn) {
357 referenceForCall = getInterpolationExpressionFn(value);
358 }
359 }
360 var call = {
361 sourceSpan: input.sourceSpan,
362 allocateBindingSlots: totalBindingSlotsRequired,
363 supportsInterpolation: !!getInterpolationExpressionFn,
364 params: function (convertFn) {
365 // params => stylingProp(propName, value, suffix)
366 var params = [];
367 params.push(o.literal(input.name));
368 var convertResult = convertFn(value);
369 if (Array.isArray(convertResult)) {
370 params.push.apply(params, tslib_1.__spreadArray([], tslib_1.__read(convertResult)));
371 }
372 else {
373 params.push(convertResult);
374 }
375 // [style.prop] bindings may use suffix values (e.g. px, em, etc...), therefore,
376 // if that is detected then we need to pass that in as an optional param.
377 if (!isClassBased && input.suffix !== null) {
378 params.push(o.literal(input.suffix));
379 }
380 return params;
381 }
382 };
383 // If we ended up generating a call to the same instruction as the previous styling property
384 // we can chain the calls together safely to save some bytes, otherwise we have to generate
385 // a separate instruction call. This is primarily a concern with interpolation instructions
386 // where we may start off with one `reference`, but end up using another based on the
387 // number of interpolations.
388 if (previousInstruction && previousInstruction.reference === referenceForCall) {
389 previousInstruction.calls.push(call);
390 }
391 else {
392 instructions.push({ reference: referenceForCall, calls: [call] });
393 }
394 });
395 return instructions;
396 };
397 StylingBuilder.prototype._buildClassInputs = function (valueConverter) {
398 if (this._singleClassInputs) {
399 return this._buildSingleInputs(r3_identifiers_1.Identifiers.classProp, this._singleClassInputs, valueConverter, null, true);
400 }
401 return [];
402 };
403 StylingBuilder.prototype._buildStyleInputs = function (valueConverter) {
404 if (this._singleStyleInputs) {
405 return this._buildSingleInputs(r3_identifiers_1.Identifiers.styleProp, this._singleStyleInputs, valueConverter, getStylePropInterpolationExpression, false);
406 }
407 return [];
408 };
409 /**
410 * Constructs all instructions which contain the expressions that will be placed
411 * into the update block of a template function or a directive hostBindings function.
412 */
413 StylingBuilder.prototype.buildUpdateLevelInstructions = function (valueConverter) {
414 var instructions = [];
415 if (this.hasBindings) {
416 var styleMapInstruction = this.buildStyleMapInstruction(valueConverter);
417 if (styleMapInstruction) {
418 instructions.push(styleMapInstruction);
419 }
420 var classMapInstruction = this.buildClassMapInstruction(valueConverter);
421 if (classMapInstruction) {
422 instructions.push(classMapInstruction);
423 }
424 instructions.push.apply(instructions, tslib_1.__spreadArray([], tslib_1.__read(this._buildStyleInputs(valueConverter))));
425 instructions.push.apply(instructions, tslib_1.__spreadArray([], tslib_1.__read(this._buildClassInputs(valueConverter))));
426 }
427 return instructions;
428 };
429 return StylingBuilder;
430 }());
431 exports.StylingBuilder = StylingBuilder;
432 function registerIntoMap(map, key) {
433 if (!map.has(key)) {
434 map.set(key, map.size);
435 }
436 }
437 function parseProperty(name) {
438 var hasOverrideFlag = false;
439 var overrideIndex = name.indexOf(IMPORTANT_FLAG);
440 if (overrideIndex !== -1) {
441 name = overrideIndex > 0 ? name.substring(0, overrideIndex) : '';
442 hasOverrideFlag = true;
443 }
444 var suffix = null;
445 var property = name;
446 var unitIndex = name.lastIndexOf('.');
447 if (unitIndex > 0) {
448 suffix = name.substr(unitIndex + 1);
449 property = name.substring(0, unitIndex);
450 }
451 return { property: property, suffix: suffix, hasOverrideFlag: hasOverrideFlag };
452 }
453 exports.parseProperty = parseProperty;
454 /**
455 * Gets the instruction to generate for an interpolated class map.
456 * @param interpolation An Interpolation AST
457 */
458 function getClassMapInterpolationExpression(interpolation) {
459 switch (util_1.getInterpolationArgsLength(interpolation)) {
460 case 1:
461 return r3_identifiers_1.Identifiers.classMap;
462 case 3:
463 return r3_identifiers_1.Identifiers.classMapInterpolate1;
464 case 5:
465 return r3_identifiers_1.Identifiers.classMapInterpolate2;
466 case 7:
467 return r3_identifiers_1.Identifiers.classMapInterpolate3;
468 case 9:
469 return r3_identifiers_1.Identifiers.classMapInterpolate4;
470 case 11:
471 return r3_identifiers_1.Identifiers.classMapInterpolate5;
472 case 13:
473 return r3_identifiers_1.Identifiers.classMapInterpolate6;
474 case 15:
475 return r3_identifiers_1.Identifiers.classMapInterpolate7;
476 case 17:
477 return r3_identifiers_1.Identifiers.classMapInterpolate8;
478 default:
479 return r3_identifiers_1.Identifiers.classMapInterpolateV;
480 }
481 }
482 /**
483 * Gets the instruction to generate for an interpolated style map.
484 * @param interpolation An Interpolation AST
485 */
486 function getStyleMapInterpolationExpression(interpolation) {
487 switch (util_1.getInterpolationArgsLength(interpolation)) {
488 case 1:
489 return r3_identifiers_1.Identifiers.styleMap;
490 case 3:
491 return r3_identifiers_1.Identifiers.styleMapInterpolate1;
492 case 5:
493 return r3_identifiers_1.Identifiers.styleMapInterpolate2;
494 case 7:
495 return r3_identifiers_1.Identifiers.styleMapInterpolate3;
496 case 9:
497 return r3_identifiers_1.Identifiers.styleMapInterpolate4;
498 case 11:
499 return r3_identifiers_1.Identifiers.styleMapInterpolate5;
500 case 13:
501 return r3_identifiers_1.Identifiers.styleMapInterpolate6;
502 case 15:
503 return r3_identifiers_1.Identifiers.styleMapInterpolate7;
504 case 17:
505 return r3_identifiers_1.Identifiers.styleMapInterpolate8;
506 default:
507 return r3_identifiers_1.Identifiers.styleMapInterpolateV;
508 }
509 }
510 /**
511 * Gets the instruction to generate for an interpolated style prop.
512 * @param interpolation An Interpolation AST
513 */
514 function getStylePropInterpolationExpression(interpolation) {
515 switch (util_1.getInterpolationArgsLength(interpolation)) {
516 case 1:
517 return r3_identifiers_1.Identifiers.styleProp;
518 case 3:
519 return r3_identifiers_1.Identifiers.stylePropInterpolate1;
520 case 5:
521 return r3_identifiers_1.Identifiers.stylePropInterpolate2;
522 case 7:
523 return r3_identifiers_1.Identifiers.stylePropInterpolate3;
524 case 9:
525 return r3_identifiers_1.Identifiers.stylePropInterpolate4;
526 case 11:
527 return r3_identifiers_1.Identifiers.stylePropInterpolate5;
528 case 13:
529 return r3_identifiers_1.Identifiers.stylePropInterpolate6;
530 case 15:
531 return r3_identifiers_1.Identifiers.stylePropInterpolate7;
532 case 17:
533 return r3_identifiers_1.Identifiers.stylePropInterpolate8;
534 default:
535 return r3_identifiers_1.Identifiers.stylePropInterpolateV;
536 }
537 }
538 /**
539 * Checks whether property name is a custom CSS property.
540 * See: https://www.w3.org/TR/css-variables-1
541 */
542 function isCssCustomProperty(name) {
543 return name.startsWith('--');
544 }
545});
546//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3R5bGluZ19idWlsZGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL3JlbmRlcjMvdmlldy9zdHlsaW5nX2J1aWxkZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7OztJQVFBLG1FQUF3RztJQUN4RywyREFBNkM7SUFFN0MseUZBQXdFO0lBRXhFLCtFQUFvRDtJQUVwRCxnRkFBOEQ7SUFFOUQsZ0VBQWlFO0lBRWpFLElBQU0sY0FBYyxHQUFHLFlBQVksQ0FBQztJQUVwQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7U0ErQ0s7SUFDUSxRQUFBLGtDQUFrQyxHQUFHLENBQUMsQ0FBQztJQTZCcEQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0E0Qkc7SUFDSDtRQXdDRSx3QkFBb0IsY0FBaUM7WUFBakMsbUJBQWMsR0FBZCxjQUFjLENBQW1CO1lBdkNyRCxpRUFBaUU7WUFDekQsc0JBQWlCLEdBQUcsS0FBSyxDQUFDO1lBQ2xDOzs7ZUFHRztZQUNJLGdCQUFXLEdBQUcsS0FBSyxDQUFDO1lBQ3BCLHlCQUFvQixHQUFHLEtBQUssQ0FBQztZQUVwQywyQ0FBMkM7WUFDbkMsbUJBQWMsR0FBMkIsSUFBSSxDQUFDO1lBQ3RELDJDQUEyQztZQUNuQyxtQkFBYyxHQUEyQixJQUFJLENBQUM7WUFDdEQsMENBQTBDO1lBQ2xDLHVCQUFrQixHQUE2QixJQUFJLENBQUM7WUFDNUQsMENBQTBDO1lBQ2xDLHVCQUFrQixHQUE2QixJQUFJLENBQUM7WUFDcEQsc0JBQWlCLEdBQTJCLElBQUksQ0FBQztZQUNqRCx1QkFBa0IsR0FBMkIsSUFBSSxDQUFDO1lBRTFELHdEQUF3RDtZQUN4RCxrQ0FBa0M7WUFFbEM7Ozs7ZUFJRztZQUNLLGlCQUFZLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7WUFFakQ7Ozs7ZUFJRztZ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OztPQUdHO0lBQ0gsU0FBUyxtQ0FBbUMsQ0FBQyxhQUE0QjtRQUN2RSxRQUFRLGlDQUEwQixDQUFDLGFBQWEsQ0FBQyxFQUFFO1lBQ2pELEtBQUssQ0FBQztnQkFDSixPQUFPLDRCQUFFLENBQUMsU0FBUyxDQUFDO1lBQ3RCLEtBQUssQ0FBQztnQkFDSixPQUFPLDRCQUFFLENBQUMscUJBQXFCLENBQUM7WUFDbEMsS0FBSyxDQUFDO2dCQUNKLE9BQU8sNEJBQUUsQ0FBQyxxQkFBcUIsQ0FBQztZQUNsQyxLQUFLLENBQUM7Z0JBQ0osT0FBTyw0QkFBRSxDQUFDLHFCQUFxQixDQUFDO1lBQ2xDLEtBQUssQ0FBQztnQkFDSixPQUFPLDRCQUFFLENBQUMscUJBQXFCLENBQUM7WUFDbEMsS0FBSyxFQUFFO2dCQUNMLE9BQU8sNEJBQUUsQ0FBQyxxQkFBcUIsQ0FBQztZQUNsQyxLQUFLLEVBQUU7Z0JBQ0wsT0FBTyw0QkFBRSxDQUFDLHFCQUFxQixDQUFDO1lBQ2xDLEtBQUssRUFBRTtnQkFDTCxPQUFPLDRCQUFFLENBQUMscUJBQXFCLENBQUM7WUFDbEMsS0FBSyxFQUFFO2dCQUNMLE9BQU8sNEJBQUUsQ0FBQyxxQkFBcUIsQ0FBQztZQUNsQztnQkFDRSxPQUFPLDRCQUFFLENBQUMscUJBQXFCLENBQUM7U0FDbkM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsU0FBUyxtQkFBbUIsQ0FBQyxJQUFZO1FBQ3ZDLE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMvQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5pbXBvcnQge0F0dHJpYnV0ZU1hcmtlcn0gZnJvbSAnLi4vLi4vY29yZSc7XG5pbXBvcnQge0FTVCwgQVNUV2l0aFNvdXJjZSwgQmluZGluZ1BpcGUsIEJpbmRpbmdUeXBlLCBJbnRlcnBvbGF0aW9ufSBmcm9tICcuLi8uLi9leHByZXNzaW9uX3BhcnNlci9hc3QnO1xuaW1wb3J0ICogYXMgbyBmcm9tICcuLi8uLi9vdXRwdXQvb3V0cHV0X2FzdCc7XG5pbXBvcnQge1BhcnNlU291cmNlU3Bhbn0gZnJvbSAnLi4vLi4vcGFyc2VfdXRpbCc7XG5pbXBvcnQge2lzRW1wdHlFeHByZXNzaW9ufSBmcm9tICcuLi8uLi90ZW1wbGF0ZV9wYXJzZXIvdGVtcGxhdGVfcGFyc2VyJztcbmltcG9ydCAqIGFzIHQgZnJvbSAnLi4vcjNfYXN0JztcbmltcG9ydCB7SWRlbnRpZmllcnMgYXMgUjN9IGZyb20gJy4uL3IzX2lkZW50aWZpZXJzJztcblxuaW1wb3J0IHtoeXBoZW5hdGUsIHBhcnNlIGFzIHBhcnNlU3R5bGV9IGZyb20gJy4vc3R5bGVfcGFyc2VyJztcbmltcG9ydCB7VmFsdWVDb252ZXJ0ZXJ9IGZyb20gJy4vdGVtcGxhdGUnO1xuaW1wb3J0IHtEZWZpbml0aW9uTWFwLCBnZXRJbnRlcnBvbGF0aW9uQXJnc0xlbmd0aH0gZnJvbSAnLi91dGlsJztcblxuY29uc3QgSU1QT1JUQU5UX0ZMQUcgPSAnIWltcG9ydGFudCc7XG5cbi8qKlxuICogTWluaW11bSBhbW91bnQgb2YgYmluZGluZyBzbG90cyByZXF1aXJlZCBpbiB0aGUgcnVudGltZSBmb3Igc3R5bGUvY2xhc3MgYmluZGluZ3MuXG4gKlxuICogU3R5bGluZyBpbiBBbmd1bGFyIHVzZXMgdXAgdHdvIHNsb3RzIGluIHRoZSBydW50aW1lIExWaWV3L1REYXRhIGRhdGEgc3RydWN0dXJlcyB0b1xuICogcmVjb3JkIGJpbmRpbmcgZGF0YSwgcHJvcGVydHkgaW5mb3JtYXRpb24gYW5kIG1ldGFkYXRhLlxuICpcbiAqIFdoZW4gYSBiaW5kaW5nIGlzIHJlZ2lzdGVyZWQgaXQgd2lsbCBwbGFjZSB0aGUgZm9sbG93aW5nIGluZm9ybWF0aW9uIGluIHRoZSBgTFZpZXdgOlxuICpcbiAqIHNsb3QgMSkgYmluZGluZyB2YWx1ZVxuICogc2xvdCAyKSBjYWNoZWQgdmFsdWUgKGFsbCBvdGhlciB2YWx1ZXMgY29sbGVjdGVkIGJlZm9yZSBpdCBpbiBzdHJpbmcgZm9ybSlcbiAqXG4gKiBXaGVuIGEgYmluZGluZyBpcyByZWdpc3RlcmVkIGl0IHdpbGwgcGxhY2UgdGhlIGZvbGxvd2luZyBpbmZvcm1hdGlvbiBpbiB0aGUgYFREYXRhYDpcbiAqXG4gKiBzbG90IDEpIHByb3AgbmFtZVxuICogc2xvdCAyKSBiaW5kaW5nIGluZGV4IHRoYXQgcG9pbnRzIHRvIHRoZSBwcmV2aW91cyBzdHlsZS9jbGFzcyBiaW5kaW5nIChhbmQgc29tZSBleHRyYSBjb25maWdcbiAqIHZhbHVlcylcbiAqXG4gKiBMZXQncyBpbWFnaW5lIHdlIGhhdmUgYSBiaW5kaW5nIHRoYXQgbG9va3MgbGlrZSBzbzpcbiAqXG4gKiBgYGBcbiAqIDxkaXYgW3N0eWxlLndpZHRoXT1cInhcIiBbc3R5bGUuaGVpZ2h0XT1cInlcIj5cbiAqIGBgYFxuICpcbiAqIE91ciBgTFZpZXdgIGFuZCBgVERhdGFgIGRhdGEtc3RydWN0dXJlcyBsb29rIGxpa2Ugc286XG4gKlxuICogYGBgdHlwZXNjcmlwdFxuICogTFZpZXcgPSBbXG4gKiAgIC8vIC4uLlxuICogICB4LCAvLyB2YWx1ZSBvZiB4XG4gKiAgIFwid2lkdGg6IHhcIixcbiAqXG4gKiAgIHksIC8vIHZhbHVlIG9mIHlcbiAqICAgXCJ3aWR0aDogeDsgaGVpZ2h0OiB5XCIsXG4gKiAgIC8vIC4uLlxuICogXTtcbiAqXG4gKiBURGF0YSA9IFtcbiAqICAgLy8gLi4uXG4gKiAgIFwid2lkdGhcIiwgLy8gYmluZGluZyBzbG90IDIwXG4gKiAgIDAsXG4gKlxuICogICBcImhlaWdodFwiLFxuICogICAyMCxcbiAqICAgLy8gLi4uXG4gKiBdO1xuICogYGBgXG4gKlxuICogKi9cbmV4cG9ydCBjb25zdCBNSU5fU1RZTElOR19CSU5ESU5HX1NMT1RTX1JFUVVJUkVEID0gMjtcblxuLyoqXG4gKiBBIHN0eWxpbmcgZXhwcmVzc2lvbiBzdW1tYXJ5IHRoYXQgaXMgdG8gYmUgcHJvY2Vzc2VkIGJ5IHRoZSBjb21waWxlclxuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0eWxpbmdJbnN0cnVjdGlvbiB7XG4gIHJlZmVyZW5jZTogby5FeHRlcm5hbFJlZmVyZW5jZTtcbiAgLyoqIENhbGxzIHRvIGluZGl2aWR1YWwgc3R5bGluZyBpbnN0cnVjdGlvbnMuIFVzZWQgd2hlbiBjaGFpbmluZyBjYWxscyB0byB0aGUgc2FtZSBpbnN0cnVjdGlvbi4gKi9cbiAgY2FsbHM6IFN0eWxpbmdJbnN0cnVjdGlvbkNhbGxbXTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTdHlsaW5nSW5zdHJ1Y3Rpb25DYWxsIHtcbiAgc291cmNlU3BhbjogUGFyc2VTb3VyY2VTcGFufG51bGw7XG4gIHN1cHBvcnRzSW50ZXJwb2xhdGlvbjogYm9vbGVhbjtcbiAgYWxsb2NhdGVCaW5kaW5nU2xvdHM6IG51bWJlcjtcbiAgcGFyYW1zOiAoKGNvbnZlcnRGbjogKHZhbHVlOiBhbnkpID0+IG8uRXhwcmVzc2lvbiB8IG8uRXhwcmVzc2lvbltdKSA9PiBvLkV4cHJlc3Npb25bXSk7XG59XG5cbi8qKlxuICogQW4gaW50ZXJuYWwgcmVjb3JkIG9mIHRoZSBpbnB1dCBkYXRhIGZvciBhIHN0eWxpbmcgYmluZGluZ1xuICovXG5pbnRlcmZhY2UgQm91bmRTdHlsaW5nRW50cnkge1xuICBoYXNPdmVycmlkZUZsYWc6IGJvb2xlYW47XG4gIG5hbWU6IHN0cmluZ3xudWxsO1xuICBzdWZmaXg6IHN0cmluZ3xudWxsO1xuICBzb3VyY2VTcGFuOiBQYXJzZVNvdXJjZVNwYW47XG4gIHZhbHVlOiBBU1Q7XG59XG5cbi8qKlxuICogUHJvZHVjZXMgY3JlYXRpb24vdXBkYXRlIGluc3RydWN0aW9ucyBmb3IgYWxsIHN0eWxpbmcgYmluZGluZ3MgKGNsYXNzIGFuZCBzdHlsZSlcbiAqXG4gKiBJdCBhbHNvIHByb2R1Y2VzIHRoZSBjcmVhdGlvbiBpbnN0cnVjdGlvbiB0byByZWdpc3RlciBhbGwgaW5pdGlhbCBzdHlsaW5nIHZhbHVlc1xuICogKHdoaWNoIGFyZSBhbGwgdGhlIHN0YXRpYyBjbGFzcz1cIi4uLlwiIGFuZCBzdHlsZT1cIi4uLlwiIGF0dHJpYnV0ZSB2YWx1ZXMgdGhhdCBleGlzdFxuICogb24gYW4gZWxlbWVudCB3aXRoaW4gYSB0ZW1wbGF0ZSkuXG4gKlxuICogVGhlIGJ1aWxkZXIgY2xhc3MgYmVsb3cgaGFuZGxlcyBwcm9kdWNpbmcgaW5zdHJ1Y3Rpb25zIGZvciB0aGUgZm9sbG93aW5nIGNhc2VzOlxuICpcbiAqIC0gU3RhdGljIHN0eWxlL2NsYXNzIGF0dHJpYnV0ZXMgKHN0eWxlPVwiLi4uXCIgYW5kIGNsYXNzPVwiLi4uXCIpXG4gKiAtIER5bmFtaWMgc3R5bGUvY2xhc3MgbWFwIGJpbmRpbmdzIChbc3R5bGVdPVwibWFwXCIgYW5kIFtjbGFzc109XCJtYXB8c3RyaW5nXCIpXG4gKiAtIER5bmFtaWMgc3R5bGUvY2xhc3MgcHJvcGVydHkgYmluZGluZ3MgKFtzdHlsZS5wcm9wXT1cImV4cFwiIGFuZCBbY2xhc3MubmFtZV09XCJleHBcIilcbiAqXG4gKiBEdWUgdG8gdGhlIGNvbXBsZXggcmVsYXRpb25zaGlwIG9mIGFsbCBvZiB0aGVzZSBjYXNlcywgdGhlIGluc3RydWN0aW9ucyBnZW5lcmF0ZWRcbiAqIGZvciB0aGVzZSBhdHRyaWJ1dGVzL3Byb3BlcnRpZXMvYmluZGluZ3MgbXVzdCBiZSBkb25lIHNvIGluIHRoZSBjb3JyZWN0IG9yZGVyLiBUaGVcbiAqIG9yZGVyIHdoaWNoIHRoZXNlIG11c3QgYmUgZ2VuZXJhdGVkIGlzIGFzIGZvbGxvd3M6XG4gKlxuICogaWYgKGNyZWF0ZU1vZGUpIHtcbiAqICAgc3R5bGluZyguLi4pXG4gKiB9XG4gKiBpZiAodXBkYXRlTW9kZSkge1xuICogICBzdHlsZU1hcCguLi4pXG4gKiAgIGNsYXNzTWFwKC4uLilcbiAqICAgc3R5bGVQcm9wKC4uLilcbiAqICAgY2xhc3NQcm9wKC4uLilcbiAqIH1cbiAqXG4gKiBUaGUgY3JlYXRpb24vdXBkYXRlIG1ldGhvZHMgd2l0aGluIHRoZSBidWlsZGVyIGNsYXNzIHByb2R1Y2UgdGhlc2UgaW5zdHJ1Y3Rpb25zLlxuICovXG5leHBvcnQgY2xhc3MgU3R5bGluZ0J1aWxkZXIge1xuICAvKiogV2hldGhlciBvciBub3QgdGhlcmUgYXJlIGFueSBzdGF0aWMgc3R5bGluZyB2YWx1ZXMgcHJlc2VudCAqL1xuICBwcml2YXRlIF9oYXNJbml0aWFsVmFsdWVzID0gZmFsc2U7XG4gIC8qKlxuICAgKiAgV2hldGhlciBvciBub3QgdGhlcmUgYXJlIGFueSBzdHlsaW5nIGJpbmRpbmdzIHByZXNlbnRcbiAgICogIChpLmUuIGBbc3R5bGVdYCwgYFtjbGFzc11gLCBgW3N0eWxlLnByb3BdYCBvciBgW2NsYXNzLm5hbWVdYClcbiAgICovXG4gIHB1YmxpYyBoYXNCaW5kaW5ncyA9IGZhbHNlO1xuICBwdWJsaWMgaGFzQmluZGluZ3NXaXRoUGlwZXMgPSBmYWxzZTtcblxuICAvKiogdGhlIGlucHV0IGZvciBbY2xhc3NdIChpZiBpdCBleGlzdHMpICovXG4gIHByaXZhdGUgX2NsYXNzTWFwSW5wdXQ6IEJvdW5kU3R5bGluZ0VudHJ5fG51bGwgPSBudWxsO1xuICAvKiogdGhlIGlucHV0IGZvciBbc3R5bGVdIChpZiBpdCBleGlzdHMpICovXG4gIHByaXZhdGUgX3N0eWxlTWFwSW5wdXQ6IEJvdW5kU3R5bGluZ0VudHJ5fG51bGwgPSBudWxsO1xuICAvKiogYW4gYXJyYXkgb2YgZWFjaCBbc3R5bGUucHJvcF0gaW5wdXQgKi9cbiAgcHJpdmF0ZSBfc2luZ2xlU3R5bGVJbnB1dHM6IEJvdW5kU3R5bGluZ0VudHJ5W118bnVsbCA9IG51bGw7XG4gIC8qKiBhbiBhcnJheSBvZiBlYWNoIFtjbGFzcy5uYW1lXSBpbnB1dCAqL1xuICBwcml2YXRlIF9zaW5nbGVDbGFzc0lucHV0czogQm91bmRTdHlsaW5nRW50cnlbXXxudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBfbGFzdFN0eWxpbmdJbnB1dDogQm91bmRTdHlsaW5nRW50cnl8bnVsbCA9IG51bGw7XG4gIHByaXZhdGUgX2ZpcnN0U3R5bGluZ0lucHV0OiBCb3VuZFN0eWxpbmdFbnRyeXxudWxsID0gbnVsbDtcblxuICAvLyBtYXBzIGFyZSB1c2VkIGluc3RlYWQgb2YgaGFzaCBtYXBzIGJlY2F1c2UgYSBNYXAgd2lsbFxuICAvLyByZXRhaW4gdGhlIG9yZGVyaW5nIG9mIHRoZSBrZXlzXG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgdGhlIGxvY2F0aW9uIG9mIGVhY2ggc3R5bGUgYmluZGluZyBpbiB0aGUgdGVtcGxhdGVcbiAgICogKGUuZy4gYDxkaXYgW3N0eWxlLndpZHRoXT1cIndcIiBbc3R5bGUuaGVpZ2h0XT1cImhcIj5gIGltcGxpZXNcbiAgICogdGhhdCBgd2lkdGg9MGAgYW5kIGBoZWlnaHQ9MWApXG4gICAqL1xuICBwcml2YXRlIF9zdHlsZXNJbmRleCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgdGhlIGxvY2F0aW9uIG9mIGVhY2ggY2xhc3MgYmluZGluZyBpbiB0aGUgdGVtcGxhdGVcbiAgICogKGUuZy4gYDxkaXYgW2NsYXNzLmJpZ109XCJiXCIgW2NsYXNzLmhpZGRlbl09XCJoXCI+YCBpbXBsaWVzXG4gICAqIHRoYXQgYGJpZz0wYCBhbmQgYGhpZGRlbj0xYClcbiAgICovXG4gIHByaXZhdGUgX2NsYXNzZXNJbmRleCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIHByaXZhdGUgX2luaXRpYWxTdHlsZVZhbHVlczogc3RyaW5nW10gPSBbXTtcbiAgcHJpdmF0ZSBfaW5pdGlhbENsYXNzVmFsdWVzOiBzdHJpbmdbXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2RpcmVjdGl2ZUV4cHI6IG8uRXhwcmVzc2lvbnxudWxsKSB7fVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYSBnaXZlbiBpbnB1dCB0byB0aGUgc3R5bGluZyBidWlsZGVyIHRvIGJlIGxhdGVyIHVzZWQgd2hlbiBwcm9kdWNpbmcgQU9UIGNvZGUuXG4gICAqXG4gICAqIFRoZSBjb2RlIGJlbG93IHdpbGwgb25seSBhY2NlcHQgdGhlIGlucHV0IGlmIGl0IGlzIHNvbWVob3cgdGllZCB0byBzdHlsaW5nICh3aGV0aGVyIGl0IGJlXG4gICAqIHN0eWxlL2NsYXNzIGJpbmRpbmdzIG9yIHN0YXRpYyBzdHlsZS9jbGFzcyBhdHRyaWJ1dGVzKS5cbiAgICovXG4gIHJlZ2lzdGVyQm91bmRJbnB1dChpbnB1dDogdC5Cb3VuZEF0dHJpYnV0ZSk6IGJvb2xlYW4ge1xuICAgIC8vIFthdHRyLnN0eWxlXSBvciBbYXR0ci5jbGFzc10gYXJlIHNraXBwZWQgaW4gdGhlIGNvZGUgYmVsb3csXG4gICAgLy8gdGhleSBzaG91bGQgbm90IGJlIHRyZWF0ZWQgYXMgc3R5bGluZy1iYXNlZCBiaW5kaW5ncyBzaW5jZVxuICAgIC8vIHRoZXkgYXJlIGludGVuZGVkIHRvIGJlIHdyaXR0ZW4gZGlyZWN0bHkgdG8gdGhlIGF0dHIgYW5kXG4gICAgLy8gd2lsbCB0aGVyZWZvcmUgc2tpcCBhbGwgc3R5bGUvY2xhc3MgcmVzb2x1dGlvbiB0aGF0IGlzIHByZXNlbnRcbiAgICAvLyB3aXRoIHN0eWxlPVwiXCIsIFtzdHlsZV09XCJcIiBhbmQgW3N0eWxlLnByb3BdPVwiXCIsIGNsYXNzPVwiXCIsXG4gICAgLy8gW2NsYXNzLnByb3BdPVwiXCIuIFtjbGFzc109XCJcIiBhc3NpZ25tZW50c1xuICAgIGxldCBiaW5kaW5nOiBCb3VuZFN0eWxpbmdFbnRyeXxudWxsID0gbnVsbDtcbiAgICBsZXQgbmFtZSA9IGlucHV0Lm5hbWU7XG4gICAgc3dpdGNoIChpbnB1dC50eXBlKSB7XG4gICAgICBjYXNlIEJpbmRpbmdUeXBlLlByb3BlcnR5OlxuICAgICAgICBiaW5kaW5nID0gdGhpcy5yZWdpc3RlcklucHV0QmFzZWRPbk5hbWUobmFtZSwgaW5wdXQudmFsdWUsIGlucHV0LnNvdXJjZVNwYW4pO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQmluZGluZ1R5cGUuU3R5bGU6XG4gICAgICAgIGJpbmRpbmcgPSB0aGlzLnJlZ2lzdGVyU3R5bGVJbnB1dChuYW1lLCBmYWxzZSwgaW5wdXQudmFsdWUsIGlucHV0LnNvdXJjZVNwYW4sIGlucHV0LnVuaXQpO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgQmluZGluZ1R5cGUuQ2xhc3M6XG4gICAgICAgIGJpbmRpbmcgPSB0aGlzLnJlZ2lzdGVyQ2xhc3NJbnB1dChuYW1lLCBmYWxzZSwgaW5wdXQudmFsdWUsIGlucHV0LnNvdXJjZVNwYW4pO1xuICAgICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIGJpbmRpbmcgPyB0cnVlIDogZmFsc2U7XG4gIH1cblxuICByZWdpc3RlcklucHV0QmFzZWRPbk5hbWUobmFtZTogc3RyaW5nLCBleHByZXNzaW9uOiBBU1QsIHNvdXJjZVNwYW46IFBhcnNlU291cmNlU3Bhbikge1xuICAgIGxldCBiaW5kaW5nOiBCb3VuZFN0eWxpbmdFbnRyeXxudWxsID0gbnVsbDtcbiAgICBjb25zdCBwcmVmaXggPSBuYW1lLnN1YnN0cmluZygwLCA2KTtcbiAgICBjb25zdCBpc1N0eWxlID0gbmFtZSA9PT0gJ3N0eWxlJyB8fCBwcmVmaXggPT09ICdzdHlsZS4nIHx8IHByZWZpeCA9PT0gJ3N0eWxlISc7XG4gICAgY29uc3QgaXNDbGFzcyA9ICFpc1N0eWxlICYmIChuYW1lID09PSAnY2xhc3MnIHx8IHByZWZpeCA9PT0gJ2NsYXNzLicgfHwgcHJlZml4ID09PSAnY2xhc3MhJyk7XG4gICAgaWYgKGlzU3R5bGUgfHwgaXNDbGFzcykge1xuICAgICAgY29uc3QgaXNNYXBCYXNlZCA9IG5hbWUuY2hhckF0KDUpICE9PSAnLic7ICAgICAgICAgLy8gc3R5bGUucHJvcCBvciBjbGFzcy5wcm9wIG1ha2VzIHRoaXMgYSBub1xuICAgICAgY29uc3QgcHJvcGVydHkgPSBuYW1lLnN1YnN0cihpc01hcEJhc2VkID8gNSA6IDYpOyAgLy8gdGhlIGRvdCBleHBsYWlucyB3aHkgdGhlcmUncyBhICsxXG4gICAgICBpZiAoaXNTdHlsZSkge1xuICAgICAgICBiaW5kaW5nID0gdGhpcy5yZWdpc3RlclN0eWxlSW5wdXQocHJvcGVydHksIGlzTWFwQmFzZWQsIGV4cHJlc3Npb24sIHNvdXJjZVNwYW4pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYmluZGluZyA9IHRoaXMucmVnaXN0ZXJDbGFzc0lucHV0KHByb3BlcnR5LCBpc01hcEJhc2VkLCBleHByZXNzaW9uLCBzb3VyY2VTcGFuKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGJpbmRpbmc7XG4gIH1cblxuICByZWdpc3RlclN0eWxlSW5wdXQoXG4gICAgICBuYW1lOiBzdHJpbmcsIGlzTWFwQmFzZWQ6IGJvb2xlYW4sIHZhbHVlOiBBU1QsIHNvdXJjZVNwYW46IFBhcnNlU291cmNlU3BhbixcbiAgICAgIHN1ZmZpeD86IHN0cmluZ3xudWxsKTogQm91bmRTdHlsaW5nRW50cnl8bnVsbCB7XG4gICAgaWYgKGlzRW1wdHlFeHByZXNzaW9uKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIC8vIENTUyBjdXN0b20gcHJvcGVydGllcyBhcmUgY2FzZS1zZW5zaXRpdmUgc28gd2Ugc2hvdWxkbid0IG5vcm1hbGl6ZSB0aGVtLlxuICAgIC8vIFNlZTogaHR0cHM6Ly93d3cudzMub3JnL1RSL2Nzcy12YXJpYWJsZXMtMS8jZGVmaW5pbmctdmFyaWFibGVzXG4gICAgaWYgKCFpc0Nzc0N1c3RvbVByb3BlcnR5KG5hbWUpKSB7XG4gICAgICBuYW1lID0gaHlwaGVuYXRlKG5hbWUpO1xuICAgIH1cbiAgICBjb25zdCB7cHJvcGVydHksIGhhc092ZXJyaWRlRmxhZywgc3VmZml4OiBiaW5kaW5nU3VmZml4fSA9IHBhcnNlUHJvcGVydHkobmFtZSk7XG4gICAgc3VmZml4ID0gdHlwZW9mIHN1ZmZpeCA9PT0gJ3N0cmluZycgJiYgc3VmZml4Lmxlbmd0aCAhPT0gMCA/IHN1ZmZpeCA6IGJpbmRpbmdTdWZmaXg7XG4gICAgY29uc3QgZW50cnk6XG4gICAgICAgIEJvdW5kU3R5bGluZ0VudHJ5ID0ge25hbWU6IHByb3BlcnR5LCBzdWZmaXg6IHN1ZmZpeCwgdmFsdWUsIHNvdXJjZVNwYW4sIGhhc092ZXJyaWRlRmxhZ307XG4gICAgaWYgKGlzTWFwQmFzZWQpIHtcbiAgICAgIHRoaXMuX3N0eWxlTWFwSW5wdXQgPSBlbnRyeTtcbiAgICB9IGVsc2Uge1xuICAgICAgKHRoaXMuX3NpbmdsZVN0eWxlSW5wdXRzID0gdGhpcy5fc2luZ2xlU3R5bGVJbnB1dHMgfHwgW10pLnB1c2goZW50cnkpO1xuICAgICAgcmVnaXN0ZXJJbnRvTWFwKHRoaXMuX3N0eWxlc0luZGV4LCBwcm9wZXJ0eSk7XG4gICAgfVxuICAgIHRoaXMuX2xhc3RTdHlsaW5nSW5wdXQgPSBlbnRyeTtcbiAgICB0aGlzLl9maXJzdFN0eWxpbmdJbnB1dCA9IHRoaXMuX2ZpcnN0U3R5bGluZ0lucHV0IHx8IGVudHJ5O1xuICAgIHRoaXMuX2NoZWNrRm9yUGlwZXModmFsdWUpO1xuICAgIHRoaXMuaGFzQmluZGluZ3MgPSB0cnVlO1xuICAgIHJldHVybiBlbnRyeTtcbiAgfVxuXG4gIHJlZ2lzdGVyQ2xhc3NJbnB1dChuYW1lOiBzdHJpbmcsIGlzTWFwQmFzZWQ6IGJvb2xlYW4sIHZhbHVlOiBBU1QsIHNvdXJjZVNwYW46IFBhcnNlU291cmNlU3Bhbik6XG4gICAgICBCb3VuZFN0eWxpbmdFbnRyeXxudWxsIHtcbiAgICBpZiAoaXNFbXB0eUV4cHJlc3Npb24odmFsdWUpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3Qge3Byb3BlcnR5LCBoYXNPdmVycmlkZUZsYWd9ID0gcGFyc2VQcm9wZXJ0eShuYW1lKTtcbiAgICBjb25zdCBlbnRyeTpcbiAgICAgICAgQm91bmRTdHlsaW5nRW50cnkgPSB7bmFtZTogcHJvcGVydHksIHZhbHVlLCBzb3VyY2VTcGFuLCBoYXNPdmVycmlkZUZsYWcsIHN1ZmZpeDogbnVsbH07XG4gICAgaWYgKGlzTWFwQmFzZWQpIHtcbiAgICAgIHRoaXMuX2NsYXNzTWFwSW5wdXQgPSBlbnRyeTtcbiAgICB9IGVsc2Uge1xuICAgICAgKHRoaXMuX3NpbmdsZUNsYXNzSW5wdXRzID0gdGhpcy5fc2luZ2xlQ2xhc3NJbnB1dHMgfHwgW10pLnB1c2goZW50cnkpO1xuICAgICAgcmVnaXN0ZXJJbnRvTWFwKHRoaXMuX2NsYXNzZXNJbmRleCwgcHJvcGVydHkpO1xuICAgIH1cbiAgICB0aGlzLl9sYXN0U3R5bGluZ0lucHV0ID0gZW50cnk7XG4gICAgdGhpcy5fZmlyc3RTdHlsaW5nSW5wdXQgPSB0aGlzLl9maXJzdFN0eWxpbmdJbnB1dCB8fCBlbnRyeTtcbiAgICB0aGlzLl9jaGVja0ZvclBpcGVzKHZhbHVlKTtcbiAgICB0aGlzLmhhc0JpbmRpbmdzID0gdHJ1ZTtcbiAgICByZXR1cm4gZW50cnk7XG4gIH1cblxuICBwcml2YXRlIF9jaGVja0ZvclBpcGVzKHZhbHVlOiBBU1QpIHtcbiAgICBpZiAoKHZhbHVlIGluc3RhbmNlb2YgQVNUV2l0aFNvdXJjZSkgJiYgKHZhbHVlLmFzdCBpbnN0YW5jZW9mIEJpbmRpbmdQaXBlKSkge1xuICAgICAgdGhpcy5oYXNCaW5kaW5nc1dpdGhQaXBlcyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyB0aGUgZWxlbWVudCdzIHN0YXRpYyBzdHlsZSBzdHJpbmcgdmFsdWUgdG8gdGhlIGJ1aWxkZXIuXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSB0aGUgc3R5bGUgc3RyaW5nIChlLmcuIGB3aWR0aDoxMDBweDsgaGVpZ2h0OjIwMHB4O2ApXG4gICAqL1xuICByZWdpc3RlclN0eWxlQXR0cih2YWx1ZTogc3RyaW5nKSB7XG4gICAgdGhpcy5faW5pdGlhbFN0eWxlVmFsdWVzID0gcGFyc2VTdHlsZSh2YWx1ZSk7XG4gICAgdGhpcy5faGFzSW5pdGlhbFZhbHVlcyA9IHRydWU7XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIHRoZSBlbGVtZW50J3Mgc3RhdGljIGNsYXNzIHN0cmluZyB2YWx1ZSB0byB0aGUgYnVpbGRlci5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIHRoZSBjbGFzc05hbWUgc3RyaW5nIChlLmcuIGBkaXNhYmxlZCBnb2xkIHpvb21gKVxuICAgKi9cbiAgcmVnaXN0ZXJDbGFzc0F0dHIodmFsdWU6IHN0cmluZykge1xuICAgIHRoaXMuX2luaXRpYWxDbGFzc1ZhbHVlcyA9IHZhbHVlLnRyaW0oKS5zcGxpdCgvXFxzKy9nKTtcbiAgICB0aGlzLl9oYXNJbml0aWFsVmFsdWVzID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBlbmRzIGFsbCBzdHlsaW5nLXJlbGF0ZWQgZXhwcmVzc2lvbnMgdG8gdGhlIHByb3ZpZGVkIGF0dHJzIGFycmF5LlxuICAgKlxuICAgKiBAcGFyYW0gYXR0cnMgYW4gZXhpc3RpbmcgYXJyYXkgd2hlcmUgZWFjaCBvZiB0aGUgc3R5bGluZyBleHByZXNzaW9uc1xuICAgKiB3aWxsIGJlIGluc2VydGVkIGludG8uXG4gICAqL1xuICBwb3B1bGF0ZUluaXRpYWxTdHlsaW5nQXR0cnMoYXR0cnM6IG8uRXhwcmVzc2lvbltdKTogdm9pZCB7XG4gICAgLy8gW0NMQVNTX01BUktFUiwgJ2ZvbycsICdiYXInLCAnYmF6JyAuLi5dXG4gICAgaWYgKHRoaXMuX2luaXRpYWxDbGFzc1ZhbHVlcy5sZW5ndGgpIHtcbiAgICAgIGF0dHJzLnB1c2goby5saXRlcmFsKEF0dHJpYnV0ZU1hcmtlci5DbGFzc2VzKSk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2luaXRpYWxDbGFzc1ZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICBhdHRycy5wdXNoKG8ubGl0ZXJhbCh0aGlzLl9pbml0aWFsQ2xhc3NWYWx1ZXNbaV0pKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBbU1RZTEVfTUFSS0VSLCAnd2lkdGgnLCAnMjAwcHgnLCAnaGVpZ2h0JywgJzEwMHB4JywgLi4uXVxuICAgIGlmICh0aGlzLl9pbml0aWFsU3R5bGVWYWx1ZXMubGVuZ3RoKSB7XG4gICAgICBhdHRycy5wdXNoKG8ubGl0ZXJhbChBdHRyaWJ1dGVNYXJrZXIuU3R5bGVzKSk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRoaXMuX2luaXRpYWxTdHlsZVZhbHVlcy5sZW5ndGg7IGkgKz0gMikge1xuICAgICAgICBhdHRycy5wdXNoKFxuICAgICAgICAgICAgby5saXRlcmFsKHRoaXMuX2luaXRpYWxTdHlsZVZhbHVlc1tpXSksIG8ubGl0ZXJhbCh0aGlzLl9pbml0aWFsU3R5bGVWYWx1ZXNbaSArIDFdKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhbiBpbnN0cnVjdGlvbiB3aXRoIGFsbCB0aGUgZXhwcmVzc2lvbnMgYW5kIHBhcmFtZXRlcnMgZm9yIGBlbGVtZW50SG9zdEF0dHJzYC5cbiAgICpcbiAgICogVGhlIGluc3RydWN0aW9uIGdlbmVyYXRpb24gY29kZSBiZWxvdyBpcyB1c2VkIGZvciBwcm9kdWNpbmcgdGhlIEFPVCBzdGF0ZW1lbnQgY29kZSB3aGljaCBpc1xuICAgKiByZXNwb25zaWJsZSBmb3IgcmVnaXN0ZXJpbmcgaW5pdGlhbCBzdHlsZXMgKHdpdGhpbiBhIGRpcmVjdGl2ZSBob3N0QmluZGluZ3MnIGNyZWF0aW9uIGJsb2NrKSxcbiAgICogYXMgd2VsbCBhcyBhbnkgb2YgdGhlIHByb3ZpZGVkIGF0dHJpYnV0ZSB2YWx1ZXMsIHRvIHRoZSBkaXJlY3RpdmUgaG9zdCBlbGVtZW50LlxuICAgKi9cbiAgYXNzaWduSG9zdEF0dHJzKGF0dHJzOiBvLkV4cHJlc3Npb25bXSwgZGVmaW5pdGlvbk1hcDogRGVmaW5pdGlvbk1hcCk6IHZvaWQge1xuICAgIGlmICh0aGlzLl9kaXJlY3RpdmVFeHByICYmIChhdHRycy5sZW5ndGggfHwgdGhpcy5faGFzSW5pdGlhbFZhbHVlcykpIHtcbiAgICAgIHRoaXMucG9wdWxhdGVJbml0aWFsU3R5bGluZ0F0dHJzKGF0dHJzKTtcbiAgICAgIGRlZmluaXRpb25NYXAuc2V0KCdob3N0QXR0cnMnLCBvLmxpdGVyYWxBcnIoYXR0cnMpKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIGFuIGluc3RydWN0aW9uIHdpdGggYWxsIHRoZSBleHByZXNzaW9ucyBhbmQgcGFyYW1ldGVycyBmb3IgYGNsYXNzTWFwYC5cbiAgICpcbiAgICogVGhlIGluc3RydWN0aW9uIGRhdGEgd2lsbCBjb250YWluIGFsbCBleHByZXNzaW9ucyBmb3IgYGNsYXNzTWFwYCB0byBmdW5jdGlvblxuICAgKiB3aGljaCBpbmNsdWRlcyB0aGUgYFtjbGFzc11gIGV4cHJlc3Npb24gcGFyYW1zLlxuICAgKi9cbiAgYnVpbGRDbGFzc01hcEluc3RydWN0aW9uKHZhbHVlQ29udmVydGVyOiBWYWx1ZUNvbnZlcnRlcik6IFN0eWxpbmdJbnN0cnVjdGlvbnxudWxsIHtcbiAgICBpZiAodGhpcy5fY2xhc3NNYXBJbnB1dCkge1xuICAgICAgcmV0dXJuIHRoaXMuX2J1aWxkTWFwQmFzZWRJbnN0cnVjdGlvbih2YWx1ZUNvbnZlcnRlciwgdHJ1ZSwgdGhpcy5fY2xhc3NNYXBJbnB1dCk7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhbiBpbnN0cnVjdGlvbiB3aXRoIGFsbCB0aGUgZXhwcmVzc2lvbnMgYW5kIHBhcmFtZXRlcnMgZm9yIGBzdHlsZU1hcGAuXG4gICAqXG4gICAqIFRoZSBpbnN0cnVjdGlvbiBkYXRhIHdpbGwgY29udGFpbiBhbGwgZXhwcmVzc2lvbnMgZm9yIGBzdHlsZU1hcGAgdG8gZnVuY3Rpb25cbiAgICogd2hpY2ggaW5jbHVkZXMgdGhlIGBbc3R5bGVdYCBleHByZXNzaW9uIHBhcmFtcy5cbiAgICovXG4gIGJ1aWxkU3R5bGVNYXBJbnN0cnVjdGlvbih2YWx1ZUNvbnZlcnRlcjogVmFsdWVDb252ZXJ0ZXIpOiBTdHlsaW5nSW5zdHJ1Y3Rpb258bnVsbCB7XG4gICAgaWYgKHRoaXMuX3N0eWxlTWFwSW5wdXQpIHtcbiAgICAgIHJldHVybiB0aGlzLl9idWlsZE1hcEJhc2VkSW5zdHJ1Y3Rpb24odmFsdWVDb252ZXJ0ZXIsIGZhbHNlLCB0aGlzLl9zdHlsZU1hcElucHV0KTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIF9idWlsZE1hcEJhc2VkSW5zdHJ1Y3Rpb24oXG4gICAgICB2YWx1ZUNvbnZlcnRlcjogVmFsdWVDb252ZXJ0ZXIsIGlzQ2xhc3NCYXNlZDogYm9vbGVhbixcbiAgICAgIHN0eWxpbmdJbnB1dDogQm91bmRTdHlsaW5nRW50cnkpOiBTdHlsaW5nSW5zdHJ1Y3Rpb24ge1xuICAgIC8vIGVhY2ggc3R5bGluZyBiaW5kaW5nIHZhbHVlIGlzIHN0b3JlZCBpbiB0aGUgTFZpZXdcbiAgICAvLyBtYXAtYmFzZWQgYmluZGluZ3MgYWxsb2NhdGUgdHdvIHNsb3RzOiBvbmUgZm9yIHRoZVxuICAgIC8vIHByZXZpb3VzIGJpbmRpbmcgdmFsdWUgYW5kIGFub3RoZXIgZm9yIHRoZSBwcmV2aW91c1xuICAgIC8vIGNsYXNzTmFtZSBvciBzdHlsZSBhdHRyaWJ1dGUgdmFsdWUuXG4gICAgbGV0IHRvdGFsQmluZGluZ1Nsb3RzUmVxdWlyZWQgPSBNSU5fU1RZTElOR19CSU5ESU5HX1NMT1RTX1JFUVVJUkVEO1xuXG4gICAgLy8gdGhlc2UgdmFsdWVzIG11c3QgYmUgb3V0c2lkZSBvZiB0aGUgdXBkYXRlIGJsb2NrIHNvIHRoYXQgdGhleSBjYW5cbiAgICAvLyBiZSBldmFsdWF0ZWQgKHRoZSBBU1QgdmlzaXQgY2FsbCkgZHVyaW5nIGNyZWF0aW9uIHRpbWUgc28gdGhhdCBhbnlcbiAgICAvLyBwaXBlcyBjYW4gYmUgcGlja2VkIHVwIGluIHRpbWUgYmVmb3JlIHRoZSB0ZW1wbGF0ZSBpcyBidWlsdFxuICAgIGNvbnN0IG1hcFZhbHVlID0gc3R5bGluZ0lucHV0LnZhbHVlLnZpc2l0KHZhbHVlQ29udmVydGVyKTtcbiAgICBsZXQgcmVmZXJlbmNlOiBvLkV4dGVybmFsUmVmZXJlbmNlO1xuICAgIGlmIChtYXBWYWx1ZSBpbnN0YW5jZW9mIEludGVycG9sYXRpb24pIHtcbiAgICAgIHRvdGFsQmluZGluZ1Nsb3RzUmVxdWlyZWQgKz0gbWFwVmFsdWUuZXhwcmVzc2lvbnMubGVuZ3RoO1xuICAgICAgcmVmZXJlbmNlID0gaXNDbGFzc0Jhc2VkID8gZ2V0Q2xhc3NNYXBJbnRlcnBvbGF0aW9uRXhwcmVzc2lvbihtYXBWYWx1ZSkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0U3R5bGVNYXBJbnRlcnBvbGF0aW9uRXhwcmVzc2lvbihtYXBWYWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlZmVyZW5jZSA9IGlzQ2xhc3NCYXNlZCA/IFIzLmNsYXNzTWFwIDogUjMuc3R5bGVNYXA7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIHJlZmVyZW5jZSxcbiAgICAgIGNhbGxzOiBbe1xuICAgICAgICBzdXBwb3J0c0ludGVycG9sYXRpb246IHRydWUsXG4gICAgICAgIHNvdXJjZVNwYW46IHN0eWxpbmdJbnB1dC5zb3VyY2VTcGFuLFxuICAgICAgICBhbGxvY2F0ZUJpbmRpbmdTbG90czogdG90YWxCaW5kaW5nU2xvdHNSZXF1aXJlZCxcbiAgICAgICAgcGFyYW1zOiAoY29udmVydEZuOiAodmFsdWU6IGFueSkgPT4gby5FeHByZXNzaW9ufG8uRXhwcmVzc2lvbltdKSA9PiB7XG4gICAgICAgICAgY29uc3QgY29udmVydFJlc3VsdCA9IGNvbnZlcnRGbihtYXBWYWx1ZSk7XG4gICAgICAgICAgY29uc3QgcGFyYW1zID0gQXJyYXkuaXNBcnJheShjb252ZXJ0UmVzdWx0KSA/IGNvbnZlcnRSZXN1bHQgOiBbY29udmVydFJlc3VsdF07XG4gICAgICAgICAgcmV0dXJuIHBhcmFtcztcbiAgICAgICAgfVxuICAgICAgfV1cbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBfYnVpbGRTaW5nbGVJbnB1dHMoXG4gICAgICByZWZlcmVuY2U6IG8uRXh0ZXJuYWxSZWZlcmVuY2UsIGlucHV0czogQm91bmRTdHlsaW5nRW50cnlbXSwgdmFsdWVDb252ZXJ0ZXI6IFZhbHVlQ29udmVydGVyLFxuICAgICAgZ2V0SW50ZXJwb2xhdGlvbkV4cHJlc3Npb25GbjogKCh2YWx1ZTogSW50ZXJwb2xhdGlvbikgPT4gby5FeHRlcm5hbFJlZmVyZW5jZSl8bnVsbCxcbiAgICAgIGlzQ2xhc3NCYXNlZDogYm9vbGVhbik6IFN0eWxpbmdJbnN0cnVjdGlvbltdIHtcbiAgICBjb25zdCBpbnN0cnVjdGlvbnM6IFN0eWxpbmdJbnN0cnVjdGlvbltdID0gW107XG5cbiAgICBpbnB1dHMuZm9yRWFjaChpbnB1dCA9PiB7XG4gICAgICBjb25zdCBwcmV2aW91c0luc3RydWN0aW9uOiBTdHlsaW5nSW5zdHJ1Y3Rpb258dW5kZWZpbmVkID1cbiAgICAgICAgICBpbnN0cnVjdGlvbnNbaW5zdHJ1Y3Rpb25zLmxlbmd0aCAtIDFdO1xuICAgICAgY29uc3QgdmFsdWUgPSBpbnB1dC52YWx1ZS52aXNpdCh2YWx1ZUNvbnZlcnRlcik7XG4gICAgICBsZXQgcmVmZXJlbmNlRm9yQ2FsbCA9IHJlZmVyZW5jZTtcblxuICAgICAgLy8gZWFjaCBzdHlsaW5nIGJpbmRpbmcgdmFsdWUgaXMgc3RvcmVkIGluIHRoZSBMVmlld1xuICAgICAgLy8gYnV0IHRoZXJlIGFyZSB0d28gdmFsdWVzIHN0b3JlZCBmb3IgZWFjaCBiaW5kaW5nOlxuICAgICAgLy8gICAxKSB0aGUgdmFsdWUgaXRzZWxmXG4gICAgICAvLyAgIDIpIGFuIGludGVybWVkaWF0ZSB2YWx1ZSAoY29uY2F0ZW5hdGlvbiBvZiBzdHlsZSB1cCB0byB0aGlzIHBvaW50KS5cbiAgICAgIC8vICAgICAgV2UgbmVlZCB0byBzdG9yZSB0aGUgaW50ZXJtZWRpYXRlIHZhbHVlIHNvIHRoYXQgd2UgZG9uJ3QgYWxsb2NhdGVcbiAgICAgIC8vICAgICAgdGhlIHN0cmluZ3Mgb24gZWFjaCBDRC5cbiAgICAgIGxldCB0b3RhbEJpbmRpbmdTbG90c1JlcXVpcmVkID0gTUlOX1NUWUxJTkdfQklORElOR19TTE9UU19SRVFVSVJFRDtcblxuICAgICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgSW50ZXJwb2xhdGlvbikge1xuICAgICAgICB0b3RhbEJpbmRpbmdTbG90c1JlcXVpcmVkICs9IHZhbHVlLmV4cHJlc3Npb25zLmxlbmd0aDtcblxuICAgICAgICBpZiAoZ2V0SW50ZXJwb2xhdGlvbkV4cHJlc3Npb25Gbikge1xuICAgICAgICAgIHJlZmVyZW5jZUZvckNhbGwgPSBnZXRJbnRlcnBvbGF0aW9uRXhwcmVzc2lvbkZuKHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBjb25zdCBjYWxsID0ge1xuICAgICAgICBzb3VyY2VTcGFuOiBpbnB1dC5zb3VyY2VTcGFuLFxuICAgICAgICBhbGxvY2F0ZUJpbmRpbmdTbG90czogdG90YWxCaW5kaW5nU2xvdHNSZXF1aXJlZCxcbiAgICAgICAgc3VwcG9ydHNJbnRlcnBvbGF0aW9uOiAhIWdldEludGVycG9sYXRpb25FeHByZXNzaW9uRm4sXG4gICAgICAgIHBhcmFtczogKGNvbnZlcnRGbjogKHZhbHVlOiBhbnkpID0+IG8uRXhwcmVzc2lvbiB8IG8uRXhwcmVzc2lvbltdKSA9PiB7XG4gICAgICAgICAgLy8gcGFyYW1zID0+IHN0eWxpbmdQcm9wKHByb3BOYW1lLCB2YWx1ZSwgc3VmZml4KVxuICAgICAgICAgIGNvbnN0IHBhcmFtczogby5FeHByZXNzaW9uW10gPSBbXTtcbiAgICAgICAgICBwYXJhbXMucHVzaChvLmxpdGVyYWwoaW5wdXQubmFtZSkpO1xuXG4gICAgICAgICAgY29uc3QgY29udmVydFJlc3VsdCA9IGNvbnZlcnRGbih2YWx1ZSk7XG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkoY29udmVydFJlc3VsdCkpIHtcbiAgICAgICAgICAgIHBhcmFtcy5wdXNoKC4uLmNvbnZlcnRSZXN1bHQpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBwYXJhbXMucHVzaChjb252ZXJ0UmVzdWx0KTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBbc3R5bGUucHJvcF0gYmluZGluZ3MgbWF5IHVzZSBzdWZmaXggdmFsdWVzIChlLmcuIHB4LCBlbSwgZXRjLi4uKSwgdGhlcmVmb3JlLFxuICAgICAgICAgIC8vIGlmIHRoYXQgaXMgZGV0ZWN0ZWQgdGhlbiB3ZSBuZWVkIHRvIHBhc3MgdGhhdCBpbiBhcyBhbiBvcHRpb25hbCBwYXJhbS5cbiAgICAgICAgICBpZiAoIWlzQ2xhc3NCYXNlZCAmJiBpbnB1dC5zdWZmaXggIT09IG51bGwpIHtcbiAgICAgICAgICAgIHBhcmFtcy5wdXNoKG8ubGl0ZXJhbChpbnB1dC5zdWZmaXgpKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICByZXR1cm4gcGFyYW1zO1xuICAgICAgICB9XG4gICAgICB9O1xuXG4gICAgICAvLyBJZiB3ZSBlbmRlZCB1cCBnZW5lcmF0aW5nIGEgY2FsbCB0byB0aGUgc2FtZSBpbnN0cnVjdGlvbiBhcyB0aGUgcHJldmlvdXMgc3R5bGluZyBwcm9wZXJ0eVxuICAgICAgLy8gd2UgY2FuIGNoYWluIHRoZSBjYWxscyB0b2dldGhlciBzYWZlbHkgdG8gc2F2ZSBzb21lIGJ5dGVzLCBvdGhlcndpc2Ugd2UgaGF2ZSB0byBnZW5lcmF0ZVxuICAgICAgLy8gYSBzZXBhcmF0ZSBpbnN0cnVjdGlvbiBjYWxsLiBUaGlzIGlzIHByaW1hcmlseSBhIGNvbmNlcm4gd2l0aCBpbnRlcnBvbGF0aW9uIGluc3RydWN0aW9uc1xuICAgICAgLy8gd2hlcmUgd2UgbWF5IHN0YXJ0IG9mZiB3aXRoIG9uZSBgcmVmZXJlbmNlYCwgYnV0IGVuZCB1cCB1c2luZyBhbm90aGVyIGJhc2VkIG9uIHRoZVxuICAgICAgLy8gbnVtYmVyIG9mIGludGVycG9sYXRpb25zLlxuICAgICAgaWYgKHByZXZpb3VzSW5zdHJ1Y3Rpb24gJiYgcHJldmlvdXNJbnN0cnVjdGlvbi5yZWZlcmVuY2UgPT09IHJlZmVyZW5jZUZvckNhbGwpIHtcbiAgICAgICAgcHJldmlvdXNJbnN0cnVjdGlvbi5jYWxscy5wdXNoKGNhbGwpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaW5zdHJ1Y3Rpb25zLnB1c2goe3JlZmVyZW5jZTogcmVmZXJlbmNlRm9yQ2FsbCwgY2FsbHM6IFtjYWxsXX0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIGluc3RydWN0aW9ucztcbiAgfVxuXG4gIHByaXZhdGUgX2J1aWxkQ2xhc3NJbnB1dHModmFsdWVDb252ZXJ0ZXI6IFZhbHVlQ29udmVydGVyKTogU3R5bGluZ0luc3RydWN0aW9uW10ge1xuICAgIGlmICh0aGlzLl9zaW5nbGVDbGFzc0lucHV0cykge1xuICAgICAgcmV0dXJuIHRoaXMuX2J1aWxkU2luZ2xlSW5wdXRzKFxuICAgICAgICAgIFIzLmNsYXNzUHJvcCwgdGhpcy5fc2luZ2xlQ2xhc3NJbnB1dHMsIHZhbHVlQ29udmVydGVyLCBudWxsLCB0cnVlKTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgcHJpdmF0ZSBfYnVpbGRTdHlsZUlucHV0cyh2YWx1ZUNvbnZlcnRlcjogVmFsdWVDb252ZXJ0ZXIpOiBTdHlsaW5nSW5zdHJ1Y3Rpb25bXSB7XG4gICAgaWYgKHRoaXMuX3NpbmdsZVN0eWxlSW5wdXRzKSB7XG4gICAgICByZXR1cm4gdGhpcy5fYnVpbGRTaW5nbGVJbnB1dHMoXG4gICAgICAgICAgUjMuc3R5bGVQcm9wLCB0aGlzLl9zaW5nbGVTdHlsZUlucHV0cywgdmFsdWVDb252ZXJ0ZXIsXG4gICAgICAgICAgZ2V0U3R5bGVQcm9wSW50ZXJwb2xhdGlvbkV4cHJlc3Npb24sIGZhbHNlKTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgLyoqXG4gICAqIENvbnN0cnVjdHMgYWxsIGluc3RydWN0aW9ucyB3aGljaCBjb250YWluIHRoZSBleHByZXNzaW9ucyB0aGF0IHdpbGwgYmUgcGxhY2VkXG4gICAqIGludG8gdGhlIHVwZGF0ZSBibG9jayBvZiBhIHRlbXBsYXRlIGZ1bmN0aW9uIG9yIGEgZGlyZWN0aXZlIGhvc3RCaW5kaW5ncyBmdW5jdGlvbi5cbiAgICovXG4gIGJ1aWxkVXBkYXRlTGV2ZWxJbnN0cnVjdGlvbnModmFsdWVDb252ZXJ0ZXI6IFZhbHVlQ29udmVydGVyKSB7XG4gICAgY29uc3QgaW5zdHJ1Y3Rpb25zOiBTdHlsaW5nSW5zdHJ1Y3Rpb25bXSA9IFtdO1xuICAgIGlmICh0aGlzLmhhc0JpbmRpbmdzKSB7XG4gICAgICBjb25zdCBzdHlsZU1hcEluc3RydWN0aW9uID0gdGhpcy5idWlsZFN0eWxlTWFwSW5zdHJ1Y3Rpb24odmFsdWVDb252ZXJ0ZXIpO1xuICAgICAgaWYgKHN0eWxlTWFwSW5zdHJ1Y3Rpb24pIHtcbiAgICAgICAgaW5zdHJ1Y3Rpb25zLnB1c2goc3R5bGVNYXBJbnN0cnVjdGlvbik7XG4gICAgICB9XG4gICAgICBjb25zdCBjbGFzc01hcEluc3RydWN0aW9uID0gdGhpcy5idWlsZENsYXNzTWFwSW5zdHJ1Y3Rpb24odmFsdWVDb252ZXJ0ZXIpO1xuICAgICAgaWYgKGNsYXNzTWFwSW5zdHJ1Y3Rpb24pIHtcbiAgICAgICAgaW5zdHJ1Y3Rpb25zLnB1c2goY2xhc3NNYXBJbnN0cnVjdGlvbik7XG4gICAgICB9XG4gICAgICBpbnN0cnVjdGlvbnMucHVzaCguLi50aGlzLl9idWlsZFN0eWxlSW5wdXRzKHZhbHVlQ29udmVydGVyKSk7XG4gICAgICBpbnN0cnVjdGlvbnMucHVzaCguLi50aGlzLl9idWlsZENsYXNzSW5wdXRzKHZhbHVlQ29udmVydGVyKSk7XG4gICAgfVxuICAgIHJldHVybiBpbnN0cnVjdGlvbnM7XG4gIH1cbn1cblxuZnVuY3Rpb24gcmVnaXN0ZXJJbnRvTWFwKG1hcDogTWFwPHN0cmluZywgbnVtYmVyPiwga2V5OiBzdHJpbmcpIHtcbiAgaWYgKCFtYXAuaGFzKGtleSkpIHtcbiAgICBtYXAuc2V0KGtleSwgbWFwLnNpemUpO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVByb3BlcnR5KG5hbWU6IHN0cmluZyk6XG4gICAge3Byb3BlcnR5OiBzdHJpbmcsIHN1ZmZpeDogc3RyaW5nfG51bGwsIGhhc092ZXJyaWRlRmxhZzogYm9vbGVhbn0ge1xuICBsZXQgaGFzT3ZlcnJpZGVGbGFnID0gZmFsc2U7XG4gIGNvbnN0IG92ZXJyaWRlSW5kZXggPSBuYW1lLmluZGV4T2YoSU1QT1JUQU5UX0ZMQUcpO1xuICBpZiAob3ZlcnJpZGVJbmRleCAhPT0gLTEpIHtcbiAgICBuYW1lID0gb3ZlcnJpZGVJbmRleCA+IDAgPyBuYW1lLnN1YnN0cmluZygwLCBvdmVycmlkZUluZGV4KSA6ICcnO1xuICAgIGhhc092ZXJyaWRlRmxhZyA9IHRydWU7XG4gIH1cblxuICBsZXQgc3VmZml4OiBzdHJpbmd8bnVsbCA9IG51bGw7XG4gIGxldCBwcm9wZXJ0eSA9IG5hbWU7XG4gIGNvbnN0IHVuaXRJbmRleCA9IG5hbWUubGFzdEluZGV4T2YoJy4nKTtcbiAgaWYgKHVuaXRJbmRleCA+IDApIHtcbiAgICBzdWZmaXggPSBuYW1lLnN1YnN0cih1bml0SW5kZXggKyAxKTtcbiAgICBwcm9wZXJ0eSA9IG5hbWUuc3Vic3RyaW5nKDAsIHVuaXRJbmRleCk7XG4gIH1cblxuICByZXR1cm4ge3Byb3BlcnR5LCBzdWZmaXgsIGhhc092ZXJyaWRlRmxhZ307XG59XG5cbi8qKlxuICogR2V0cyB0aGUgaW5zdHJ1Y3Rpb24gdG8gZ2VuZXJhdGUgZm9yIGFuIGludGVycG9sYXRlZCBjbGFzcyBtYXAuXG4gKiBAcGFyYW0gaW50ZXJwb2xhdGlvbiBBbiBJbnRlcnBvbGF0aW9uIEFTVFxuICovXG5mdW5jdGlvbiBnZXRDbGFzc01hcEludGVycG9sYXRpb25FeHByZXNzaW9uKGludGVycG9sYXRpb246IEludGVycG9sYXRpb24pOiBvLkV4dGVybmFsUmVmZXJlbmNlIHtcbiAgc3dpdGNoIChnZXRJbnRlcnBvbGF0aW9uQXJnc0xlbmd0aChpbnRlcnBvbGF0aW9uKSkge1xuICAgIGNhc2UgMTpcbiAgICAgIHJldHVybiBSMy5jbGFzc01hcDtcbiAgICBjYXNlIDM6XG4gICAgICByZXR1cm4gUjMuY2xhc3NNYXBJbnRlcnBvbGF0ZTE7XG4gICAgY2FzZSA1OlxuICAgICAgcmV0dXJuIFIzLmNsYXNzTWFwSW50ZXJwb2xhdGUyO1xuICAgIGNhc2UgNzpcbiAgICAgIHJldHVybiBSMy5jbGFzc01hcEludGVycG9sYXRlMztcbiAgICBjYXNlIDk6XG4gICAgICByZXR1cm4gUjMuY2xhc3NNYXBJbnRlcnBvbGF0ZTQ7XG4gICAgY2FzZSAxMTpcbiAgICAgIHJldHVybiBSMy5jbGFzc01hcEludGVycG9sYXRlNTtcbiAgICBjYXNlIDEzOlxuICAgICAgcmV0dXJuIFIzLmNsYXNzTWFwSW50ZXJwb2xhdGU2O1xuICAgIGNhc2UgMTU6XG4gICAgICByZXR1cm4gUjMuY2xhc3NNYXBJbnRlcnBvbGF0ZTc7XG4gICAgY2FzZSAxNzpcbiAgICAgIHJldHVybiBSMy5jbGFzc01hcEludGVycG9sYXRlODtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIFIzLmNsYXNzTWFwSW50ZXJwb2xhdGVWO1xuICB9XG59XG5cbi8qKlxuICogR2V0cyB0aGUgaW5zdHJ1Y3Rpb24gdG8gZ2VuZXJhdGUgZm9yIGFuIGludGVycG9sYXRlZCBzdHlsZSBtYXAuXG4gKiBAcGFyYW0gaW50ZXJwb2xhdGlvbiBBbiBJbnRlcnBvbGF0aW9uIEFTVFxuICovXG5mdW5jdGlvbiBnZXRTdHlsZU1hcEludGVycG9sYXRpb25FeHByZXNzaW9uKGludGVycG9sYXRpb246IEludGVycG9sYXRpb24pOiBvLkV4dGVybmFsUmVmZXJlbmNlIHtcbiAgc3dpdGNoIChnZXRJbnRlcnBvbGF0aW9uQXJnc0xlbmd0aChpbnRlcnBvbGF0aW9uKSkge1xuICAgIGNhc2UgMTpcbiAgICAgIHJldHVybiBSMy5zdHlsZU1hcDtcbiAgICBjYXNlIDM6XG4gICAgICByZXR1cm4gUjMuc3R5bGVNYXBJbnRlcnBvbGF0ZTE7XG4gICAgY2FzZSA1OlxuICAgICAgcmV0dXJuIFIzLnN0eWxlTWFwSW50ZXJwb2xhdGUyO1xuICAgIGNhc2UgNzpcbiAgICAgIHJldHVybiBSMy5zdHlsZU1hcEludGVycG9sYXRlMztcbiAgICBjYXNlIDk6XG4gICAgICByZXR1cm4gUjMuc3R5bGVNYXBJbnRlcnBvbGF0ZTQ7XG4gICAgY2FzZSAxMTpcbiAgICAgIHJldHVybiBSMy5zdHlsZU1hcEludGVycG9sYXRlNTtcbiAgICBjYXNlIDEzOlxuICAgICAgcmV0dXJuIFIzLnN0eWxlTWFwSW50ZXJwb2xhdGU2O1xuICAgIGNhc2UgMTU6XG4gICAgICByZXR1cm4gUjMuc3R5bGVNYXBJbnRlcnBvbGF0ZTc7XG4gICAgY2FzZSAxNzpcbiAgICAgIHJldHVybiBSMy5zdHlsZU1hcEludGVycG9sYXRlODtcbiAgICBkZWZhdWx0OlxuICAgICAgcmV0dXJuIFIzLnN0eWxlTWFwSW50ZXJwb2xhdGVWO1xuICB9XG59XG5cbi8qKlxuICogR2V0cyB0aGUgaW5zdHJ1Y3Rpb24gdG8gZ2VuZXJhdGUgZm9yIGFuIGludGVycG9sYXRlZCBzdHlsZSBwcm9wLlxuICogQHBhcmFtIGludGVycG9sYXRpb24gQW4gSW50ZXJwb2xhdGlvbiBBU1RcbiAqL1xuZnVuY3Rpb24gZ2V0U3R5bGVQcm9wSW50ZXJwb2xhdGlvbkV4cHJlc3Npb24oaW50ZXJwb2xhdGlvbjogSW50ZXJwb2xhdGlvbikge1xuICBzd2l0Y2ggKGdldEludGVycG9sYXRpb25BcmdzTGVuZ3RoKGludGVycG9sYXRpb24pKSB7XG4gICAgY2FzZSAxOlxuICAgICAgcmV0dXJuIFIzLnN0eWxlUHJvcDtcbiAgICBjYXNlIDM6XG4gICAgICByZXR1cm4gUjMuc3R5bGVQcm9wSW50ZXJwb2xhdGUxO1xuICAgIGNhc2UgNTpcbiAgICAgIHJldHVybiBSMy5zdHlsZVByb3BJbnRlcnBvbGF0ZTI7XG4gICAgY2FzZSA3OlxuICAgICAgcmV0dXJuIFIzLnN0eWxlUHJvcEludGVycG9sYXRlMztcbiAgICBjYXNlIDk6XG4gICAgICByZXR1cm4gUjMuc3R5bGVQcm9wSW50ZXJwb2xhdGU0O1xuICAgIGNhc2UgMTE6XG4gICAgICByZXR1cm4gUjMuc3R5bGVQcm9wSW50ZXJwb2xhdGU1O1xuICAgIGNhc2UgMTM6XG4gICAgICByZXR1cm4gUjMuc3R5bGVQcm9wSW50ZXJwb2xhdGU2O1xuICAgIGNhc2UgMTU6XG4gICAgICByZXR1cm4gUjMuc3R5bGVQcm9wSW50ZXJwb2xhdGU3O1xuICAgIGNhc2UgMTc6XG4gICAgICByZXR1cm4gUjMuc3R5bGVQcm9wSW50ZXJwb2xhdGU4O1xuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gUjMuc3R5bGVQcm9wSW50ZXJwb2xhdGVWO1xuICB9XG59XG5cbi8qKlxuICogQ2hlY2tzIHdoZXRoZXIgcHJvcGVydHkgbmFtZSBpcyBhIGN1c3RvbSBDU1MgcHJvcGVydHkuXG4gKiBTZWU6IGh0dHBzOi8vd3d3LnczLm9yZy9UUi9jc3MtdmFyaWFibGVzLTFcbiAqL1xuZnVuY3Rpb24gaXNDc3NDdXN0b21Qcm9wZXJ0eShuYW1lOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIG5hbWUuc3RhcnRzV2l0aCgnLS0nKTtcbn1cbiJdfQ==
Note: See TracBrowser for help on using the repository browser.