@angular/core 8.0.3 → 8.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundles/core-testing.umd.js +35 -9
- package/bundles/core-testing.umd.js.map +1 -1
- package/bundles/core-testing.umd.min.js +10 -10
- package/bundles/core-testing.umd.min.js.map +1 -1
- package/bundles/core.umd.js +11379 -9387
- package/bundles/core.umd.js.map +1 -1
- package/bundles/core.umd.min.js +205 -135
- package/bundles/core.umd.min.js.map +1 -1
- package/core.d.ts +1286 -406
- package/core.metadata.json +1 -1
- package/esm2015/core.js +2 -3
- package/esm2015/index.js +2 -2
- package/esm2015/public_api.js +2 -2
- package/esm2015/src/application_ref.js +7 -1
- package/esm2015/src/codegen_private_exports.js +2 -2
- package/esm2015/src/compiler/compiler_facade_interface.js +1 -1
- package/esm2015/src/core.js +4 -4
- package/esm2015/src/core_private_export.js +3 -1
- package/esm2015/src/core_render3_private_export.js +5 -3
- package/esm2015/src/debug/debug_node.js +4 -4
- package/esm2015/src/di/index.js +3 -3
- package/esm2015/src/di/injectable.js +1 -1
- package/esm2015/src/di/injector.js +24 -96
- package/esm2015/src/di/injector_compatibility.js +103 -6
- package/esm2015/src/di/interface/defs.js +24 -3
- package/esm2015/src/di/interface/provider.js +1 -1
- package/esm2015/src/di/r3_injector.js +82 -49
- package/esm2015/src/di/reflective_injector.js +3 -2
- package/esm2015/src/di.js +1 -1
- package/esm2015/src/i18n/locale_data.js +61 -0
- package/esm2015/src/i18n/locale_data_api.js +53 -0
- package/esm2015/src/i18n/locale_en.js +51 -0
- package/esm2015/src/i18n/localization.js +37 -0
- package/esm2015/src/linker/ng_module_factory_loader.js +4 -52
- package/esm2015/src/linker/ng_module_factory_registration.js +83 -0
- package/esm2015/src/metadata/directives.js +2 -2
- package/esm2015/src/metadata/ng_module.js +6 -1
- package/esm2015/src/metadata/resource_loading.js +2 -2
- package/esm2015/src/reflection/reflection_capabilities.js +14 -3
- package/esm2015/src/render3/assert.js +3 -2
- package/esm2015/src/render3/component.js +11 -5
- package/esm2015/src/render3/component_ref.js +4 -2
- package/esm2015/src/render3/debug.js +23 -15
- package/esm2015/src/render3/definition.js +12 -2
- package/esm2015/src/render3/errors.js +29 -1
- package/esm2015/src/render3/features/inherit_definition_feature.js +51 -37
- package/esm2015/src/render3/fields.js +3 -1
- package/esm2015/src/render3/i18n.js +76 -465
- package/esm2015/src/render3/index.js +3 -3
- package/esm2015/src/render3/instructions/all.js +10 -5
- package/esm2015/src/render3/instructions/attribute.js +28 -0
- package/esm2015/src/render3/instructions/attribute_interpolation.js +376 -0
- package/esm2015/src/render3/instructions/container.js +17 -16
- package/esm2015/src/render3/instructions/element.js +57 -35
- package/esm2015/src/render3/instructions/element_container.js +9 -8
- package/esm2015/src/render3/instructions/embedded_view.js +9 -12
- package/esm2015/src/render3/instructions/interpolation.js +375 -0
- package/esm2015/src/render3/instructions/listener.js +3 -2
- package/esm2015/src/render3/instructions/projection.js +18 -57
- package/esm2015/src/render3/instructions/property.js +10 -4
- package/esm2015/src/render3/instructions/property_interpolation.js +49 -382
- package/esm2015/src/render3/instructions/shared.js +82 -118
- package/esm2015/src/render3/instructions/styling.js +189 -236
- package/esm2015/src/render3/instructions/text.js +8 -7
- package/esm2015/src/render3/instructions/text_interpolation.js +357 -0
- package/esm2015/src/render3/interfaces/container.js +9 -5
- package/esm2015/src/render3/interfaces/definition.js +12 -6
- package/esm2015/src/render3/interfaces/node.js +20 -8
- package/esm2015/src/render3/interfaces/projection.js +1 -1
- package/esm2015/src/render3/interfaces/styling.js +16 -15
- package/esm2015/src/render3/interfaces/view.js +2 -2
- package/esm2015/src/render3/jit/directive.js +14 -5
- package/esm2015/src/render3/jit/environment.js +30 -15
- package/esm2015/src/render3/jit/module.js +38 -19
- package/esm2015/src/render3/ng_module_ref.js +39 -3
- package/esm2015/src/render3/node_manipulation.js +45 -43
- package/esm2015/src/render3/node_selector_matcher.js +40 -14
- package/esm2015/src/render3/query.js +77 -61
- package/esm2015/src/render3/state.js +33 -6
- package/esm2015/src/render3/styling/class_and_style_bindings.js +92 -80
- package/esm2015/src/render3/styling/host_instructions_queue.js +8 -5
- package/esm2015/src/render3/styling/shared.js +2 -2
- package/esm2015/src/render3/styling/util.js +2 -2
- package/esm2015/src/render3/styling_next/bindings.js +602 -0
- package/esm2015/src/render3/styling_next/instructions.js +366 -0
- package/esm2015/src/render3/styling_next/interfaces.js +374 -0
- package/esm2015/src/render3/styling_next/map_based_bindings.js +408 -0
- package/esm2015/src/render3/styling_next/state.js +51 -0
- package/esm2015/src/render3/styling_next/styling_debug.js +291 -0
- package/esm2015/src/render3/styling_next/util.js +259 -0
- package/esm2015/src/render3/util/attrs_utils.js +4 -3
- package/esm2015/src/render3/util/debug_utils.js +18 -0
- package/esm2015/src/render3/util/view_traversal_utils.js +2 -2
- package/esm2015/src/render3/view_engine_compatibility.js +24 -10
- package/esm2015/src/sanitization/sanitization.js +17 -7
- package/esm2015/src/sanitization/style_sanitizer.js +11 -1
- package/esm2015/src/util/ng_dev_mode.js +7 -3
- package/esm2015/src/version.js +1 -1
- package/esm2015/src/view/ng_module.js +3 -3
- package/esm2015/src/view/util.js +2 -2
- package/esm2015/testing/src/r3_test_bed_compiler.js +44 -12
- package/esm2015/testing/src/test_bed_common.js +2 -5
- package/esm5/core.js +2 -3
- package/esm5/src/application_ref.js +6 -1
- package/esm5/src/codegen_private_exports.js +2 -2
- package/esm5/src/compiler/compiler_facade_interface.js +1 -1
- package/esm5/src/core_private_export.js +3 -1
- package/esm5/src/core_render3_private_export.js +5 -3
- package/esm5/src/debug/debug_node.js +4 -4
- package/esm5/src/di/index.js +3 -3
- package/esm5/src/di/injectable.js +1 -1
- package/esm5/src/di/injector.js +14 -74
- package/esm5/src/di/injector_compatibility.js +77 -6
- package/esm5/src/di/interface/defs.js +24 -3
- package/esm5/src/di/interface/provider.js +1 -1
- package/esm5/src/di/r3_injector.js +60 -37
- package/esm5/src/di/reflective_injector.js +3 -2
- package/esm5/src/i18n/locale_data.js +38 -0
- package/esm5/src/i18n/locale_data_api.js +46 -0
- package/esm5/src/i18n/locale_en.js +39 -0
- package/esm5/src/i18n/localization.js +29 -0
- package/esm5/src/linker/ng_module_factory_loader.js +4 -32
- package/esm5/src/linker/ng_module_factory_registration.js +50 -0
- package/esm5/src/metadata/directives.js +2 -2
- package/esm5/src/metadata/ng_module.js +1 -1
- package/esm5/src/metadata/resource_loading.js +2 -2
- package/esm5/src/reflection/reflection_capabilities.js +14 -3
- package/esm5/src/render3/assert.js +2 -1
- package/esm5/src/render3/component.js +10 -4
- package/esm5/src/render3/component_ref.js +4 -2
- package/esm5/src/render3/debug.js +17 -10
- package/esm5/src/render3/definition.js +8 -2
- package/esm5/src/render3/errors.js +14 -1
- package/esm5/src/render3/features/inherit_definition_feature.js +41 -36
- package/esm5/src/render3/fields.js +2 -1
- package/esm5/src/render3/i18n.js +67 -437
- package/esm5/src/render3/index.js +3 -3
- package/esm5/src/render3/instructions/all.js +6 -1
- package/esm5/src/render3/instructions/attribute.js +22 -0
- package/esm5/src/render3/instructions/attribute_interpolation.js +346 -0
- package/esm5/src/render3/instructions/container.js +16 -15
- package/esm5/src/render3/instructions/element.js +43 -32
- package/esm5/src/render3/instructions/element_container.js +9 -8
- package/esm5/src/render3/instructions/embedded_view.js +8 -11
- package/esm5/src/render3/instructions/interpolation.js +243 -0
- package/esm5/src/render3/instructions/listener.js +3 -2
- package/esm5/src/render3/instructions/projection.js +19 -54
- package/esm5/src/render3/instructions/property.js +10 -4
- package/esm5/src/render3/instructions/property_interpolation.js +40 -254
- package/esm5/src/render3/instructions/shared.js +70 -105
- package/esm5/src/render3/instructions/styling.js +167 -209
- package/esm5/src/render3/instructions/text.js +8 -7
- package/esm5/src/render3/instructions/text_interpolation.js +264 -0
- package/esm5/src/render3/interfaces/container.js +8 -2
- package/esm5/src/render3/interfaces/definition.js +1 -1
- package/esm5/src/render3/interfaces/node.js +1 -8
- package/esm5/src/render3/interfaces/projection.js +1 -1
- package/esm5/src/render3/interfaces/styling.js +2 -2
- package/esm5/src/render3/interfaces/view.js +1 -1
- package/esm5/src/render3/jit/directive.js +12 -5
- package/esm5/src/render3/jit/environment.js +30 -15
- package/esm5/src/render3/jit/module.js +23 -18
- package/esm5/src/render3/ng_module_ref.js +37 -3
- package/esm5/src/render3/node_manipulation.js +39 -38
- package/esm5/src/render3/node_selector_matcher.js +36 -14
- package/esm5/src/render3/query.js +75 -53
- package/esm5/src/render3/state.js +29 -5
- package/esm5/src/render3/styling/class_and_style_bindings.js +80 -66
- package/esm5/src/render3/styling/host_instructions_queue.js +6 -3
- package/esm5/src/render3/styling/shared.js +2 -2
- package/esm5/src/render3/styling/util.js +2 -2
- package/esm5/src/render3/styling_next/bindings.js +446 -0
- package/esm5/src/render3/styling_next/instructions.js +277 -0
- package/esm5/src/render3/styling_next/interfaces.js +1 -0
- package/esm5/src/render3/styling_next/map_based_bindings.js +324 -0
- package/esm5/src/render3/styling_next/state.js +23 -0
- package/esm5/src/render3/styling_next/styling_debug.js +130 -0
- package/esm5/src/render3/styling_next/util.js +147 -0
- package/esm5/src/render3/util/attrs_utils.js +4 -3
- package/esm5/src/render3/util/debug_utils.js +11 -0
- package/esm5/src/render3/util/view_traversal_utils.js +2 -2
- package/esm5/src/render3/view_engine_compatibility.js +23 -10
- package/esm5/src/sanitization/sanitization.js +14 -6
- package/esm5/src/sanitization/style_sanitizer.js +1 -1
- package/esm5/src/util/ng_dev_mode.js +7 -3
- package/esm5/src/version.js +1 -1
- package/esm5/src/view/ng_module.js +3 -3
- package/esm5/src/view/util.js +2 -2
- package/esm5/testing/src/r3_test_bed_compiler.js +37 -11
- package/esm5/testing/src/test_bed_common.js +1 -1
- package/fesm2015/core.js +13604 -10868
- package/fesm2015/core.js.map +1 -1
- package/fesm2015/testing.js +43 -11
- package/fesm2015/testing.js.map +1 -1
- package/fesm5/core.js +11279 -9305
- package/fesm5/core.js.map +1 -1
- package/fesm5/testing.js +36 -10
- package/fesm5/testing.js.map +1 -1
- package/package.json +1 -1
- package/schematics/migrations/injectable-pipe/index.js +2 -5
- package/schematics/migrations/move-document/index.js +2 -5
- package/schematics/migrations/static-queries/index.js +2 -5
- package/schematics/migrations/template-var-assignment/index.js +2 -5
- package/src/r3_symbols.d.ts +24 -18
- package/testing/testing.d.ts +2 -5
- package/testing.d.ts +1 -1
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import { RendererStyleFlags3, isProceduralRenderer } from '../interfaces/renderer';
|
|
2
|
+
import { allowStylingFlush, getBindingValue, getGuardMask, getProp, getPropValuesStartPosition, getValuesCount, hasValueChanged, isContextLocked, isSanitizationRequired, isStylingValueDefined, lockContext, setGuardMask } from './util';
|
|
3
|
+
/**
|
|
4
|
+
* --------
|
|
5
|
+
*
|
|
6
|
+
* This file contains the core logic for styling in Angular.
|
|
7
|
+
*
|
|
8
|
+
* All styling bindings (i.e. `[style]`, `[style.prop]`, `[class]` and `[class.name]`)
|
|
9
|
+
* will have their values be applied through the logic in this file.
|
|
10
|
+
*
|
|
11
|
+
* When a binding is encountered (e.g. `<div [style.width]="w">`) then
|
|
12
|
+
* the binding data will be populated into a `TStylingContext` data-structure.
|
|
13
|
+
* There is only one `TStylingContext` per `TNode` and each element instance
|
|
14
|
+
* will update its style/class binding values in concert with the styling
|
|
15
|
+
* context.
|
|
16
|
+
*
|
|
17
|
+
* To learn more about the algorithm see `TStylingContext`.
|
|
18
|
+
*
|
|
19
|
+
* --------
|
|
20
|
+
*/
|
|
21
|
+
var DEFAULT_BINDING_VALUE = null;
|
|
22
|
+
var DEFAULT_SIZE_VALUE = 1;
|
|
23
|
+
// The first bit value reflects a map-based binding value's bit.
|
|
24
|
+
// The reason why it's always activated for every entry in the map
|
|
25
|
+
// is so that if any map-binding values update then all other prop
|
|
26
|
+
// based bindings will pass the guard check automatically without
|
|
27
|
+
// any extra code or flags.
|
|
28
|
+
export var DEFAULT_GUARD_MASK_VALUE = 1;
|
|
29
|
+
var STYLING_INDEX_FOR_MAP_BINDING = 0;
|
|
30
|
+
var STYLING_INDEX_START_VALUE = 1;
|
|
31
|
+
// the values below are global to all styling code below. Each value
|
|
32
|
+
// will either increment or mutate each time a styling instruction is
|
|
33
|
+
// executed. Do not modify the values below.
|
|
34
|
+
var currentStyleIndex = STYLING_INDEX_START_VALUE;
|
|
35
|
+
var currentClassIndex = STYLING_INDEX_START_VALUE;
|
|
36
|
+
var stylesBitMask = 0;
|
|
37
|
+
var classesBitMask = 0;
|
|
38
|
+
var deferredBindingQueue = [];
|
|
39
|
+
/**
|
|
40
|
+
* Visits a class-based binding and updates the new value (if changed).
|
|
41
|
+
*
|
|
42
|
+
* This function is called each time a class-based styling instruction
|
|
43
|
+
* is executed. It's important that it's always called (even if the value
|
|
44
|
+
* has not changed) so that the inner counter index value is incremented.
|
|
45
|
+
* This way, each instruction is always guaranteed to get the same counter
|
|
46
|
+
* state each time it's called (which then allows the `TStylingContext`
|
|
47
|
+
* and the bit mask values to be in sync).
|
|
48
|
+
*/
|
|
49
|
+
export function updateClassBinding(context, data, prop, bindingIndex, value, deferRegistration, forceUpdate) {
|
|
50
|
+
var isMapBased = !prop;
|
|
51
|
+
var index = isMapBased ? STYLING_INDEX_FOR_MAP_BINDING : currentClassIndex++;
|
|
52
|
+
var updated = updateBindingData(context, data, index, prop, bindingIndex, value, deferRegistration, forceUpdate, false);
|
|
53
|
+
if (updated || forceUpdate) {
|
|
54
|
+
classesBitMask |= 1 << index;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Visits a style-based binding and updates the new value (if changed).
|
|
59
|
+
*
|
|
60
|
+
* This function is called each time a style-based styling instruction
|
|
61
|
+
* is executed. It's important that it's always called (even if the value
|
|
62
|
+
* has not changed) so that the inner counter index value is incremented.
|
|
63
|
+
* This way, each instruction is always guaranteed to get the same counter
|
|
64
|
+
* state each time it's called (which then allows the `TStylingContext`
|
|
65
|
+
* and the bit mask values to be in sync).
|
|
66
|
+
*/
|
|
67
|
+
export function updateStyleBinding(context, data, prop, bindingIndex, value, sanitizer, deferRegistration, forceUpdate) {
|
|
68
|
+
var isMapBased = !prop;
|
|
69
|
+
var index = isMapBased ? STYLING_INDEX_FOR_MAP_BINDING : currentStyleIndex++;
|
|
70
|
+
var sanitizationRequired = isMapBased ?
|
|
71
|
+
true :
|
|
72
|
+
(sanitizer ? sanitizer(prop, null, 1 /* ValidateProperty */) : false);
|
|
73
|
+
var updated = updateBindingData(context, data, index, prop, bindingIndex, value, deferRegistration, forceUpdate, sanitizationRequired);
|
|
74
|
+
if (updated || forceUpdate) {
|
|
75
|
+
stylesBitMask |= 1 << index;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Called each time a binding value has changed within the provided `TStylingContext`.
|
|
80
|
+
*
|
|
81
|
+
* This function is designed to be called from `updateStyleBinding` and `updateClassBinding`.
|
|
82
|
+
* If called during the first update pass, the binding will be registered in the context.
|
|
83
|
+
* If the binding does get registered and the `deferRegistration` flag is true then the
|
|
84
|
+
* binding data will be queued up until the context is later flushed in `applyStyling`.
|
|
85
|
+
*
|
|
86
|
+
* This function will also update binding slot in the provided `LStylingData` with the
|
|
87
|
+
* new binding entry (if it has changed).
|
|
88
|
+
*
|
|
89
|
+
* @returns whether or not the binding value was updated in the `LStylingData`.
|
|
90
|
+
*/
|
|
91
|
+
function updateBindingData(context, data, counterIndex, prop, bindingIndex, value, deferRegistration, forceUpdate, sanitizationRequired) {
|
|
92
|
+
if (!isContextLocked(context)) {
|
|
93
|
+
if (deferRegistration) {
|
|
94
|
+
deferBindingRegistration(context, counterIndex, prop, bindingIndex, sanitizationRequired);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
deferredBindingQueue.length && flushDeferredBindings();
|
|
98
|
+
// this will only happen during the first update pass of the
|
|
99
|
+
// context. The reason why we can't use `tNode.firstTemplatePass`
|
|
100
|
+
// here is because its not guaranteed to be true when the first
|
|
101
|
+
// update pass is executed (remember that all styling instructions
|
|
102
|
+
// are run in the update phase, and, as a result, are no more
|
|
103
|
+
// styling instructions that are run in the creation phase).
|
|
104
|
+
registerBinding(context, counterIndex, prop, bindingIndex, sanitizationRequired);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
var changed = forceUpdate || hasValueChanged(data[bindingIndex], value);
|
|
108
|
+
if (changed) {
|
|
109
|
+
data[bindingIndex] = value;
|
|
110
|
+
}
|
|
111
|
+
return changed;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Schedules a binding registration to be run at a later point.
|
|
115
|
+
*
|
|
116
|
+
* The reasoning for this feature is to ensure that styling
|
|
117
|
+
* bindings are registered in the correct order for when
|
|
118
|
+
* directives/components have a super/sub class inheritance
|
|
119
|
+
* chains. Each directive's styling bindings must be
|
|
120
|
+
* registered into the context in reverse order. Therefore all
|
|
121
|
+
* bindings will be buffered in reverse order and then applied
|
|
122
|
+
* after the inheritance chain exits.
|
|
123
|
+
*/
|
|
124
|
+
function deferBindingRegistration(context, counterIndex, prop, bindingIndex, sanitizationRequired) {
|
|
125
|
+
deferredBindingQueue.unshift(context, counterIndex, prop, bindingIndex, sanitizationRequired);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Flushes the collection of deferred bindings and causes each entry
|
|
129
|
+
* to be registered into the context.
|
|
130
|
+
*/
|
|
131
|
+
function flushDeferredBindings() {
|
|
132
|
+
var i = 0;
|
|
133
|
+
while (i < deferredBindingQueue.length) {
|
|
134
|
+
var context = deferredBindingQueue[i++];
|
|
135
|
+
var count = deferredBindingQueue[i++];
|
|
136
|
+
var prop = deferredBindingQueue[i++];
|
|
137
|
+
var bindingIndex = deferredBindingQueue[i++];
|
|
138
|
+
var sanitizationRequired = deferredBindingQueue[i++];
|
|
139
|
+
registerBinding(context, count, prop, bindingIndex, sanitizationRequired);
|
|
140
|
+
}
|
|
141
|
+
deferredBindingQueue.length = 0;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Registers the provided binding (prop + bindingIndex) into the context.
|
|
145
|
+
*
|
|
146
|
+
* This function is shared between bindings that are assigned immediately
|
|
147
|
+
* (via `updateBindingData`) and at a deferred stage. When called, it will
|
|
148
|
+
* figure out exactly where to place the binding data in the context.
|
|
149
|
+
*
|
|
150
|
+
* It is needed because it will either update or insert a styling property
|
|
151
|
+
* into the context at the correct spot.
|
|
152
|
+
*
|
|
153
|
+
* When called, one of two things will happen:
|
|
154
|
+
*
|
|
155
|
+
* 1) If the property already exists in the context then it will just add
|
|
156
|
+
* the provided `bindingValue` to the end of the binding sources region
|
|
157
|
+
* for that particular property.
|
|
158
|
+
*
|
|
159
|
+
* - If the binding value is a number then it will be added as a new
|
|
160
|
+
* binding index source next to the other binding sources for the property.
|
|
161
|
+
*
|
|
162
|
+
* - Otherwise, if the binding value is a string/boolean/null type then it will
|
|
163
|
+
* replace the default value for the property if the default value is `null`.
|
|
164
|
+
*
|
|
165
|
+
* 2) If the property does not exist then it will be inserted into the context.
|
|
166
|
+
* The styling context relies on all properties being stored in alphabetical
|
|
167
|
+
* order, so it knows exactly where to store it.
|
|
168
|
+
*
|
|
169
|
+
* When inserted, a default `null` value is created for the property which exists
|
|
170
|
+
* as the default value for the binding. If the bindingValue property is inserted
|
|
171
|
+
* and it is either a string, number or null value then that will replace the default
|
|
172
|
+
* value.
|
|
173
|
+
*
|
|
174
|
+
* Note that this function is also used for map-based styling bindings. They are treated
|
|
175
|
+
* much the same as prop-based bindings, but, because they do not have a property value
|
|
176
|
+
* (since it's a map), all map-based entries are stored in an already populated area of
|
|
177
|
+
* the context at the top (which is reserved for map-based entries).
|
|
178
|
+
*/
|
|
179
|
+
export function registerBinding(context, countId, prop, bindingValue, sanitizationRequired) {
|
|
180
|
+
// prop-based bindings (e.g `<div [style.width]="w" [class.foo]="f">`)
|
|
181
|
+
if (prop) {
|
|
182
|
+
var found = false;
|
|
183
|
+
var i = getPropValuesStartPosition(context);
|
|
184
|
+
while (i < context.length) {
|
|
185
|
+
var valuesCount = getValuesCount(context, i);
|
|
186
|
+
var p = getProp(context, i);
|
|
187
|
+
found = prop <= p;
|
|
188
|
+
if (found) {
|
|
189
|
+
// all style/class bindings are sorted by property name
|
|
190
|
+
if (prop < p) {
|
|
191
|
+
allocateNewContextEntry(context, i, prop, sanitizationRequired);
|
|
192
|
+
}
|
|
193
|
+
addBindingIntoContext(context, false, i, bindingValue, countId);
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
i += 3 /* BindingsStartOffset */ + valuesCount;
|
|
197
|
+
}
|
|
198
|
+
if (!found) {
|
|
199
|
+
allocateNewContextEntry(context, context.length, prop, sanitizationRequired);
|
|
200
|
+
addBindingIntoContext(context, false, i, bindingValue, countId);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
// map-based bindings (e.g `<div [style]="s" [class]="{className:true}">`)
|
|
205
|
+
// there is no need to allocate the map-based binding region into the context
|
|
206
|
+
// since it is already there when the context is first created.
|
|
207
|
+
addBindingIntoContext(context, true, 2 /* MapBindingsPosition */, bindingValue, countId);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
function allocateNewContextEntry(context, index, prop, sanitizationRequired) {
|
|
211
|
+
// 1,2: splice index locations
|
|
212
|
+
// 3: each entry gets a config value (guard mask + flags)
|
|
213
|
+
// 4. each entry gets a size value (which is always one because there is always a default binding
|
|
214
|
+
// value)
|
|
215
|
+
// 5. the property that is getting allocated into the context
|
|
216
|
+
// 6. the default binding value (usually `null`)
|
|
217
|
+
var config = sanitizationRequired ? 1 /* SanitizationRequired */ :
|
|
218
|
+
0 /* Default */;
|
|
219
|
+
context.splice(index, 0, config, DEFAULT_SIZE_VALUE, prop, DEFAULT_BINDING_VALUE);
|
|
220
|
+
setGuardMask(context, index, DEFAULT_GUARD_MASK_VALUE);
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Inserts a new binding value into a styling property tuple in the `TStylingContext`.
|
|
224
|
+
*
|
|
225
|
+
* A bindingValue is inserted into a context during the first update pass
|
|
226
|
+
* of a template or host bindings function. When this occurs, two things
|
|
227
|
+
* happen:
|
|
228
|
+
*
|
|
229
|
+
* - If the bindingValue value is a number then it is treated as a bindingIndex
|
|
230
|
+
* value (a index in the `LView`) and it will be inserted next to the other
|
|
231
|
+
* binding index entries.
|
|
232
|
+
*
|
|
233
|
+
* - Otherwise the binding value will update the default value for the property
|
|
234
|
+
* and this will only happen if the default value is `null`.
|
|
235
|
+
*
|
|
236
|
+
* Note that this function also handles map-based bindings and will insert them
|
|
237
|
+
* at the top of the context.
|
|
238
|
+
*/
|
|
239
|
+
function addBindingIntoContext(context, isMapBased, index, bindingValue, countId) {
|
|
240
|
+
var valuesCount = getValuesCount(context, index);
|
|
241
|
+
var lastValueIndex = index + 3 /* BindingsStartOffset */ + valuesCount;
|
|
242
|
+
if (!isMapBased) {
|
|
243
|
+
// prop-based values all have default values, but map-based entries do not.
|
|
244
|
+
// we want to access the index for the default value in this case and not just
|
|
245
|
+
// the bindings...
|
|
246
|
+
lastValueIndex--;
|
|
247
|
+
}
|
|
248
|
+
if (typeof bindingValue === 'number') {
|
|
249
|
+
context.splice(lastValueIndex, 0, bindingValue);
|
|
250
|
+
context[index + 1 /* ValuesCountOffset */]++;
|
|
251
|
+
// now that a new binding index has been added to the property
|
|
252
|
+
// the guard mask bit value (at the `countId` position) needs
|
|
253
|
+
// to be included into the existing mask value.
|
|
254
|
+
var guardMask = getGuardMask(context, index) | (1 << countId);
|
|
255
|
+
setGuardMask(context, index, guardMask);
|
|
256
|
+
}
|
|
257
|
+
else if (typeof bindingValue === 'string' && context[lastValueIndex] == null) {
|
|
258
|
+
context[lastValueIndex] = bindingValue;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Applies all class entries in the provided context to the provided element and resets
|
|
263
|
+
* any counter and/or bitMask values associated with class bindings.
|
|
264
|
+
*
|
|
265
|
+
* @returns whether or not the classes were flushed to the element.
|
|
266
|
+
*/
|
|
267
|
+
export function applyClasses(renderer, data, context, element, directiveIndex) {
|
|
268
|
+
var classesFlushed = false;
|
|
269
|
+
if (allowStylingFlush(context, directiveIndex)) {
|
|
270
|
+
var isFirstPass = !isContextLocked(context);
|
|
271
|
+
isFirstPass && lockContext(context);
|
|
272
|
+
if (classesBitMask) {
|
|
273
|
+
// there is no way to sanitize a class value therefore `sanitizer=null`
|
|
274
|
+
applyStyling(context, renderer, element, data, classesBitMask, setClass, null);
|
|
275
|
+
classesBitMask = 0;
|
|
276
|
+
classesFlushed = true;
|
|
277
|
+
}
|
|
278
|
+
currentClassIndex = STYLING_INDEX_START_VALUE;
|
|
279
|
+
}
|
|
280
|
+
return classesFlushed;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Applies all style entries in the provided context to the provided element and resets
|
|
284
|
+
* any counter and/or bitMask values associated with style bindings.
|
|
285
|
+
*
|
|
286
|
+
* @returns whether or not the styles were flushed to the element.
|
|
287
|
+
*/
|
|
288
|
+
export function applyStyles(renderer, data, context, element, directiveIndex, sanitizer) {
|
|
289
|
+
var stylesFlushed = false;
|
|
290
|
+
if (allowStylingFlush(context, directiveIndex)) {
|
|
291
|
+
var isFirstPass = !isContextLocked(context);
|
|
292
|
+
isFirstPass && lockContext(context);
|
|
293
|
+
if (stylesBitMask) {
|
|
294
|
+
applyStyling(context, renderer, element, data, stylesBitMask, setStyle, sanitizer);
|
|
295
|
+
stylesBitMask = 0;
|
|
296
|
+
stylesFlushed = true;
|
|
297
|
+
}
|
|
298
|
+
currentStyleIndex = STYLING_INDEX_START_VALUE;
|
|
299
|
+
return true;
|
|
300
|
+
}
|
|
301
|
+
return stylesFlushed;
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Runs through the provided styling context and applies each value to
|
|
305
|
+
* the provided element (via the renderer) if one or more values are present.
|
|
306
|
+
*
|
|
307
|
+
* This function will iterate over all entries present in the provided
|
|
308
|
+
* `TStylingContext` array (both prop-based and map-based bindings).-
|
|
309
|
+
*
|
|
310
|
+
* Each entry, within the `TStylingContext` array, is stored alphabetically
|
|
311
|
+
* and this means that each prop/value entry will be applied in order
|
|
312
|
+
* (so long as it is marked dirty in the provided `bitMask` value).
|
|
313
|
+
*
|
|
314
|
+
* If there are any map-based entries present (which are applied to the
|
|
315
|
+
* element via the `[style]` and `[class]` bindings) then those entries
|
|
316
|
+
* will be applied as well. However, the code for that is not apart of
|
|
317
|
+
* this function. Instead, each time a property is visited, then the
|
|
318
|
+
* code below will call an external function called `stylingMapsSyncFn`
|
|
319
|
+
* and, if present, it will keep the application of styling values in
|
|
320
|
+
* map-based bindings up to sync with the application of prop-based
|
|
321
|
+
* bindings.
|
|
322
|
+
*
|
|
323
|
+
* Visit `styling_next/map_based_bindings.ts` to learn more about how the
|
|
324
|
+
* algorithm works for map-based styling bindings.
|
|
325
|
+
*
|
|
326
|
+
* Note that this function is not designed to be called in isolation (use
|
|
327
|
+
* `applyClasses` and `applyStyles` to actually apply styling values).
|
|
328
|
+
*/
|
|
329
|
+
export function applyStyling(context, renderer, element, bindingData, bitMaskValue, applyStylingFn, sanitizer) {
|
|
330
|
+
deferredBindingQueue.length && flushDeferredBindings();
|
|
331
|
+
var bitMask = normalizeBitMaskValue(bitMaskValue);
|
|
332
|
+
var stylingMapsSyncFn = getStylingMapsSyncFn();
|
|
333
|
+
var mapsGuardMask = getGuardMask(context, 2 /* MapBindingsPosition */);
|
|
334
|
+
var applyAllValues = (bitMask & mapsGuardMask) > 0;
|
|
335
|
+
var mapsMode = applyAllValues ? 1 /* ApplyAllValues */ : 0 /* TraverseValues */;
|
|
336
|
+
var i = getPropValuesStartPosition(context);
|
|
337
|
+
while (i < context.length) {
|
|
338
|
+
var valuesCount = getValuesCount(context, i);
|
|
339
|
+
var guardMask = getGuardMask(context, i);
|
|
340
|
+
if (bitMask & guardMask) {
|
|
341
|
+
var valueApplied = false;
|
|
342
|
+
var prop = getProp(context, i);
|
|
343
|
+
var valuesCountUpToDefault = valuesCount - 1;
|
|
344
|
+
var defaultValue = getBindingValue(context, i, valuesCountUpToDefault);
|
|
345
|
+
// case 1: apply prop-based values
|
|
346
|
+
// try to apply the binding values and see if a non-null
|
|
347
|
+
// value gets set for the styling binding
|
|
348
|
+
for (var j = 0; j < valuesCountUpToDefault; j++) {
|
|
349
|
+
var bindingIndex = getBindingValue(context, i, j);
|
|
350
|
+
var value = bindingData[bindingIndex];
|
|
351
|
+
if (isStylingValueDefined(value)) {
|
|
352
|
+
var finalValue = sanitizer && isSanitizationRequired(context, i) ?
|
|
353
|
+
sanitizer(prop, value, 2 /* SanitizeOnly */) :
|
|
354
|
+
value;
|
|
355
|
+
applyStylingFn(renderer, element, prop, finalValue, bindingIndex);
|
|
356
|
+
valueApplied = true;
|
|
357
|
+
break;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
// case 2: apply map-based values
|
|
361
|
+
// traverse through each map-based styling binding and update all values up to
|
|
362
|
+
// the provided `prop` value. If the property was not applied in the loop above
|
|
363
|
+
// then it will be attempted to be applied in the maps sync code below.
|
|
364
|
+
if (stylingMapsSyncFn) {
|
|
365
|
+
// determine whether or not to apply the target property or to skip it
|
|
366
|
+
var mode = mapsMode | (valueApplied ? 4 /* SkipTargetProp */ :
|
|
367
|
+
2 /* ApplyTargetProp */);
|
|
368
|
+
var valueAppliedWithinMap = stylingMapsSyncFn(context, renderer, element, bindingData, applyStylingFn, sanitizer, mode, prop, defaultValue);
|
|
369
|
+
valueApplied = valueApplied || valueAppliedWithinMap;
|
|
370
|
+
}
|
|
371
|
+
// case 3: apply the default value
|
|
372
|
+
// if the value has not yet been applied then a truthy value does not exist in the
|
|
373
|
+
// prop-based or map-based bindings code. If and when this happens, just apply the
|
|
374
|
+
// default value (even if the default value is `null`).
|
|
375
|
+
if (!valueApplied) {
|
|
376
|
+
applyStylingFn(renderer, element, prop, defaultValue);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
i += 3 /* BindingsStartOffset */ + valuesCount;
|
|
380
|
+
}
|
|
381
|
+
// the map-based styling entries may have not applied all their
|
|
382
|
+
// values. For this reason, one more call to the sync function
|
|
383
|
+
// needs to be issued at the end.
|
|
384
|
+
if (stylingMapsSyncFn) {
|
|
385
|
+
stylingMapsSyncFn(context, renderer, element, bindingData, applyStylingFn, sanitizer, mapsMode);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
function normalizeBitMaskValue(value) {
|
|
389
|
+
// if pass => apply all values (-1 implies that all bits are flipped to true)
|
|
390
|
+
if (value === true)
|
|
391
|
+
return -1;
|
|
392
|
+
// if pass => skip all values
|
|
393
|
+
if (value === false)
|
|
394
|
+
return 0;
|
|
395
|
+
// return the bit mask value as is
|
|
396
|
+
return value;
|
|
397
|
+
}
|
|
398
|
+
var _activeStylingMapApplyFn = null;
|
|
399
|
+
export function getStylingMapsSyncFn() {
|
|
400
|
+
return _activeStylingMapApplyFn;
|
|
401
|
+
}
|
|
402
|
+
export function setStylingMapsSyncFn(fn) {
|
|
403
|
+
_activeStylingMapApplyFn = fn;
|
|
404
|
+
}
|
|
405
|
+
/**
|
|
406
|
+
* Assigns a style value to a style property for the given element.
|
|
407
|
+
*/
|
|
408
|
+
var setStyle = function (renderer, native, prop, value) {
|
|
409
|
+
if (value) {
|
|
410
|
+
// opacity, z-index and flexbox all have number values
|
|
411
|
+
// and these need to be converted into strings so that
|
|
412
|
+
// they can be assigned properly.
|
|
413
|
+
value = value.toString();
|
|
414
|
+
ngDevMode && ngDevMode.rendererSetStyle++;
|
|
415
|
+
renderer && isProceduralRenderer(renderer) ?
|
|
416
|
+
renderer.setStyle(native, prop, value, RendererStyleFlags3.DashCase) :
|
|
417
|
+
native.style.setProperty(prop, value);
|
|
418
|
+
}
|
|
419
|
+
else {
|
|
420
|
+
ngDevMode && ngDevMode.rendererRemoveStyle++;
|
|
421
|
+
renderer && isProceduralRenderer(renderer) ?
|
|
422
|
+
renderer.removeStyle(native, prop, RendererStyleFlags3.DashCase) :
|
|
423
|
+
native.style.removeProperty(prop);
|
|
424
|
+
}
|
|
425
|
+
};
|
|
426
|
+
var ɵ0 = setStyle;
|
|
427
|
+
/**
|
|
428
|
+
* Adds/removes the provided className value to the provided element.
|
|
429
|
+
*/
|
|
430
|
+
var setClass = function (renderer, native, className, value) {
|
|
431
|
+
if (className !== '') {
|
|
432
|
+
if (value) {
|
|
433
|
+
ngDevMode && ngDevMode.rendererAddClass++;
|
|
434
|
+
renderer && isProceduralRenderer(renderer) ? renderer.addClass(native, className) :
|
|
435
|
+
native.classList.add(className);
|
|
436
|
+
}
|
|
437
|
+
else {
|
|
438
|
+
ngDevMode && ngDevMode.rendererRemoveClass++;
|
|
439
|
+
renderer && isProceduralRenderer(renderer) ? renderer.removeClass(native, className) :
|
|
440
|
+
native.classList.remove(className);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
};
|
|
444
|
+
var ɵ1 = setClass;
|
|
445
|
+
export { ɵ0, ɵ1 };
|
|
446
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmluZGluZ3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9yZW5kZXIzL3N0eWxpbmdfbmV4dC9iaW5kaW5ncy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFRQSxPQUFPLEVBQTJDLG1CQUFtQixFQUFFLG9CQUFvQixFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFHM0gsT0FBTyxFQUFDLGlCQUFpQixFQUFFLGVBQWUsRUFBRSxZQUFZLEVBQUUsT0FBTyxFQUFFLDBCQUEwQixFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLHNCQUFzQixFQUFFLHFCQUFxQixFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUMsTUFBTSxRQUFRLENBQUM7QUFHek87Ozs7Ozs7Ozs7Ozs7Ozs7O0dBaUJHO0FBRUgsSUFBTSxxQkFBcUIsR0FBRyxJQUFJLENBQUM7QUFDbkMsSUFBTSxrQkFBa0IsR0FBRyxDQUFDLENBQUM7QUFFN0IsZ0VBQWdFO0FBQ2hFLGtFQUFrRTtBQUNsRSxrRUFBa0U7QUFDbEUsaUVBQWlFO0FBQ2pFLDJCQUEyQjtBQUMzQixNQUFNLENBQUMsSUFBTSx3QkFBd0IsR0FBRyxDQUFHLENBQUM7QUFDNUMsSUFBTSw2QkFBNkIsR0FBRyxDQUFDLENBQUM7QUFDeEMsSUFBTSx5QkFBeUIsR0FBRyxDQUFDLENBQUM7QUFFcEMsb0VBQW9FO0FBQ3BFLHFFQUFxRTtBQUNyRSw0Q0FBNEM7QUFDNUMsSUFBSSxpQkFBaUIsR0FBRyx5QkFBeUIsQ0FBQztBQUNsRCxJQUFJLGlCQUFpQixHQUFHLHlCQUF5QixDQUFDO0FBQ2xELElBQUksYUFBYSxHQUFHLENBQUMsQ0FBQztBQUN0QixJQUFJLGNBQWMsR0FBRyxDQUFDLENBQUM7QUFDdkIsSUFBSSxvQkFBb0IsR0FBMkQsRUFBRSxDQUFDO0FBRXRGOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sVUFBVSxrQkFBa0Is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QUFDLG1CQUFtQixFQUFFLENBQUM7WUFDN0MsUUFBUSxJQUFJLG9CQUFvQixDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLE1BQU0sRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUN6QyxNQUFNLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsQ0FBQztTQUNqRjtLQUNGO0FBQ0gsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4qIEBsaWNlbnNlXG4qIENvcHlyaWdodCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuKlxuKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4qL1xuaW1wb3J0IHtTdHlsZVNhbml0aXplRm4sIFN0eWxlU2FuaXRpemVNb2RlfSBmcm9tICcuLi8uLi9zYW5pdGl6YXRpb24vc3R5bGVfc2FuaXRpemVyJztcbmltcG9ydCB7UHJvY2VkdXJhbFJlbmRlcmVyMywgUkVsZW1lbnQsIFJlbmRlcmVyMywgUmVuZGVyZXJTdHlsZUZsYWdzMywgaXNQcm9jZWR1cmFsUmVuZGVyZXJ9IGZyb20gJy4uL2ludGVyZmFjZXMvcmVuZGVyZXInO1xuXG5pbXBvcnQge0FwcGx5U3R5bGluZ0ZuLCBMU3R5bGluZ0RhdGEsIExTdHlsaW5nTWFwLCBTdHlsaW5nTWFwc1N5bmNNb2RlLCBTeW5jU3R5bGluZ01hcHNGbiwgVFN0eWxpbmdDb250ZXh0LCBUU3R5bGluZ0NvbnRleHRJbmRleCwgVFN0eWxpbmdDb250ZXh0UHJvcENvbmZpZ0ZsYWdzfSBmcm9tICcuL2ludGVyZmFjZXMnO1xuaW1wb3J0IHthbGxvd1N0eWxpbmdGbHVzaCwgZ2V0QmluZGluZ1ZhbHVlLCBnZXRHdWFyZE1hc2ssIGdldFByb3AsIGdldFByb3BWYWx1ZXNTdGFydFBvc2l0aW9uLCBnZXRWYWx1ZXNDb3VudCwgaGFzVmFsdWVDaGFuZ2VkLCBpc0NvbnRleHRMb2NrZWQsIGlzU2FuaXRpemF0aW9uUmVxdWlyZWQsIGlzU3R5bGluZ1ZhbHVlRGVmaW5lZCwgbG9ja0NvbnRleHQsIHNldEd1YXJkTWFza30gZnJvbSAnLi91dGlsJztcblxuXG4vKipcbiAqIC0tLS0tLS0tXG4gKlxuICogVGhpcyBmaWxlIGNvbnRhaW5zIHRoZSBjb3JlIGxvZ2ljIGZvciBzdHlsaW5nIGluIEFuZ3VsYXIuXG4gKlxuICogQWxsIHN0eWxpbmcgYmluZGluZ3MgKGkuZS4gYFtzdHlsZV1gLCBgW3N0eWxlLnByb3BdYCwgYFtjbGFzc11gIGFuZCBgW2NsYXNzLm5hbWVdYClcbiAqIHdpbGwgaGF2ZSB0aGVpciB2YWx1ZXMgYmUgYXBwbGllZCB0aHJvdWdoIHRoZSBsb2dpYyBpbiB0aGlzIGZpbGUuXG4gKlxuICogV2hlbiBhIGJpbmRpbmcgaXMgZW5jb3VudGVyZWQgKGUuZy4gYDxkaXYgW3N0eWxlLndpZHRoXT1cIndcIj5gKSB0aGVuXG4gKiB0aGUgYmluZGluZyBkYXRhIHdpbGwgYmUgcG9wdWxhdGVkIGludG8gYSBgVFN0eWxpbmdDb250ZXh0YCBkYXRhLXN0cnVjdHVyZS5cbiAqIFRoZXJlIGlzIG9ubHkgb25lIGBUU3R5bGluZ0NvbnRleHRgIHBlciBgVE5vZGVgIGFuZCBlYWNoIGVsZW1lbnQgaW5zdGFuY2VcbiAqIHdpbGwgdXBkYXRlIGl0cyBzdHlsZS9jbGFzcyBiaW5kaW5nIHZhbHVlcyBpbiBjb25jZXJ0IHdpdGggdGhlIHN0eWxpbmdcbiAqIGNvbnRleHQuXG4gKlxuICogVG8gbGVhcm4gbW9yZSBhYm91dCB0aGUgYWxnb3JpdGhtIHNlZSBgVFN0eWxpbmdDb250ZXh0YC5cbiAqXG4gKiAtLS0tLS0tLVxuICovXG5cbmNvbnN0IERFRkFVTFRfQklORElOR19WQUxVRSA9IG51bGw7XG5jb25zdCBERUZBVUxUX1NJWkVfVkFMVUUgPSAxO1xuXG4vLyBUaGUgZmlyc3QgYml0IHZhbHVlIHJlZmxlY3RzIGEgbWFwLWJhc2VkIGJpbmRpbmcgdmFsdWUncyBiaXQuXG4vLyBUaGUgcmVhc29uIHdoeSBpdCdzIGFsd2F5cyBhY3RpdmF0ZWQgZm9yIGV2ZXJ5IGVudHJ5IGluIHRoZSBtYXBcbi8vIGlzIHNvIHRoYXQgaWYgYW55IG1hcC1iaW5kaW5nIHZhbHVlcyB1cGRhdGUgdGhlbiBhbGwgb3RoZXIgcHJvcFxuLy8gYmFzZWQgYmluZGluZ3Mgd2lsbCBwYXNzIHRoZSBndWFyZCBjaGVjayBhdXRvbWF0aWNhbGx5IHdpdGhvdXRcbi8vIGFueSBleHRyYSBjb2RlIG9yIGZsYWdzLlxuZXhwb3J0IGNvbnN0IERFRkFVTFRfR1VBUkRfTUFTS19WQUxVRSA9IDBiMTtcbmNvbnN0IFNUWUxJTkdfSU5ERVhfRk9SX01BUF9CSU5ESU5HID0gMDtcbmNvbnN0IFNUWUxJTkdfSU5ERVhfU1RBUlRfVkFMVUUgPSAxO1xuXG4vLyB0aGUgdmFsdWVzIGJlbG93IGFyZSBnbG9iYWwgdG8gYWxsIHN0eWxpbmcgY29kZSBiZWxvdy4gRWFjaCB2YWx1ZVxuLy8gd2lsbCBlaXRoZXIgaW5jcmVtZW50IG9yIG11dGF0ZSBlYWNoIHRpbWUgYSBzdHlsaW5nIGluc3RydWN0aW9uIGlzXG4vLyBleGVjdXRlZC4gRG8gbm90IG1vZGlmeSB0aGUgdmFsdWVzIGJlbG93LlxubGV0IGN1cnJlbnRTdHlsZUluZGV4ID0gU1RZTElOR19JTkRFWF9TVEFSVF9WQUxVRTtcbmxldCBjdXJyZW50Q2xhc3NJbmRleCA9IFNUWUxJTkdfSU5ERVhfU1RBUlRfVkFMVUU7XG5sZXQgc3R5bGVzQml0TWFzayA9IDA7XG5sZXQgY2xhc3Nlc0JpdE1hc2sgPSAwO1xubGV0IGRlZmVycmVkQmluZGluZ1F1ZXVlOiAoVFN0eWxpbmdDb250ZXh0IHwgbnVtYmVyIHwgc3RyaW5nIHwgbnVsbCB8IGJvb2xlYW4pW10gPSBbXTtcblxuLyoqXG4gKiBWaXNpdHMgYSBjbGFzcy1iYXNlZCBiaW5kaW5nIGFuZCB1cGRhdGVzIHRoZSBuZXcgdmFsdWUgKGlmIGNoYW5nZWQpLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGVhY2ggdGltZSBhIGNsYXNzLWJhc2VkIHN0eWxpbmcgaW5zdHJ1Y3Rpb25cbiAqIGlzIGV4ZWN1dGVkLiBJdCdzIGltcG9ydGFudCB0aGF0IGl0J3MgYWx3YXlzIGNhbGxlZCAoZXZlbiBpZiB0aGUgdmFsdWVcbiAqIGhhcyBub3QgY2hhbmdlZCkgc28gdGhhdCB0aGUgaW5uZXIgY291bnRlciBpbmRleCB2YWx1ZSBpcyBpbmNyZW1lbnRlZC5cbiAqIFRoaXMgd2F5LCBlYWNoIGluc3RydWN0aW9uIGlzIGFsd2F5cyBndWFyYW50ZWVkIHRvIGdldCB0aGUgc2FtZSBjb3VudGVyXG4gKiBzdGF0ZSBlYWNoIHRpbWUgaXQncyBjYWxsZWQgKHdoaWNoIHRoZW4gYWxsb3dzIHRoZSBgVFN0eWxpbmdDb250ZXh0YFxuICogYW5kIHRoZSBiaXQgbWFzayB2YWx1ZXMgdG8gYmUgaW4gc3luYykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVDbGFzc0JpbmRpbmcoXG4gICAgY29udGV4dDogVFN0eWxpbmdDb250ZXh0LCBkYXRhOiBMU3R5bGluZ0RhdGEsIHByb3A6IHN0cmluZyB8IG51bGwsIGJpbmRpbmdJbmRleDogbnVtYmVyLFxuICAgIHZhbHVlOiBib29sZWFuIHwgc3RyaW5nIHwgbnVsbCB8IHVuZGVmaW5lZCB8IExTdHlsaW5nTWFwLCBkZWZlclJlZ2lzdHJhdGlvbjogYm9vbGVhbixcbiAgICBmb3JjZVVwZGF0ZTogYm9vbGVhbik6IHZvaWQge1xuICBjb25zdCBpc01hcEJhc2VkID0gIXByb3A7XG4gIGNvbnN0IGluZGV4ID0gaXNNYXBCYXNlZCA/IFNUWUxJTkdfSU5ERVhfRk9SX01BUF9CSU5ESU5HIDogY3VycmVudENsYXNzSW5kZXgrKztcbiAgY29uc3QgdXBkYXRlZCA9IHVwZGF0ZUJpbmRpbmdEYXRhKFxuICAgICAgY29udGV4dCwgZGF0YSwgaW5kZXgsIHByb3AsIGJpbmRpbmdJbmRleCwgdmFsdWUsIGRlZmVyUmVnaXN0cmF0aW9uLCBmb3JjZVVwZGF0ZSwgZmFsc2UpO1xuICBpZiAodXBkYXRlZCB8fCBmb3JjZVVwZGF0ZSkge1xuICAgIGNsYXNzZXNCaXRNYXNrIHw9IDEgPDwgaW5kZXg7XG4gIH1cbn1cblxuLyoqXG4gKiBWaXNpdHMgYSBzdHlsZS1iYXNlZCBiaW5kaW5nIGFuZCB1cGRhdGVzIHRoZSBuZXcgdmFsdWUgKGlmIGNoYW5nZWQpLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGVhY2ggdGltZSBhIHN0eWxlLWJhc2VkIHN0eWxpbmcgaW5zdHJ1Y3Rpb25cbiAqIGlzIGV4ZWN1dGVkLiBJdCdzIGltcG9ydGFudCB0aGF0IGl0J3MgYWx3YXlzIGNhbGxlZCAoZXZlbiBpZiB0aGUgdmFsdWVcbiAqIGhhcyBub3QgY2hhbmdlZCkgc28gdGhhdCB0aGUgaW5uZXIgY291bnRlciBpbmRleCB2YWx1ZSBpcyBpbmNyZW1lbnRlZC5cbiAqIFRoaXMgd2F5LCBlYWNoIGluc3RydWN0aW9uIGlzIGFsd2F5cyBndWFyYW50ZWVkIHRvIGdldCB0aGUgc2FtZSBjb3VudGVyXG4gKiBzdGF0ZSBlYWNoIHRpbWUgaXQncyBjYWxsZWQgKHdoaWNoIHRoZW4gYWxsb3dzIHRoZSBgVFN0eWxpbmdDb250ZXh0YFxuICogYW5kIHRoZSBiaXQgbWFzayB2YWx1ZXMgdG8gYmUgaW4gc3luYykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1cGRhdGVTdHlsZUJpbmRpbmcoXG4gICAgY29udGV4dDogVFN0eWxpbmdDb250ZXh0LCBkYXRhOiBMU3R5bGluZ0RhdGEsIHByb3A6IHN0cmluZyB8IG51bGwsIGJpbmRpbmdJbmRleDogbnVtYmVyLFxuICAgIHZhbHVlOiBTdHJpbmcgfCBzdHJpbmcgfCBudW1iZXIgfCBudWxsIHwgdW5kZWZpbmVkIHwgTFN0eWxpbmdNYXAsXG4gICAgc2FuaXRpemVyOiBTdHlsZVNhbml0aXplRm4gfCBudWxsLCBkZWZlclJlZ2lzdHJhdGlvbjogYm9vbGVhbiwgZm9yY2VVcGRhdGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgY29uc3QgaXNNYXBCYXNlZCA9ICFwcm9wO1xuICBjb25zdCBpbmRleCA9IGlzTWFwQmFzZWQgPyBTVFlMSU5HX0lOREVYX0ZPUl9NQVBfQklORElORyA6IGN1cnJlbnRTdHlsZUluZGV4Kys7XG4gIGNvbnN0IHNhbml0aXphdGlvblJlcXVpcmVkID0gaXNNYXBCYXNlZCA/XG4gICAgICB0cnVlIDpcbiAgICAgIChzYW5pdGl6ZXIgPyBzYW5pdGl6ZXIocHJvcCAhLCBudWxsLCBTdHlsZVNhbml0aXplTW9kZS5WYWxpZGF0ZVByb3BlcnR5KSA6IGZhbHNlKTtcbiAgY29uc3QgdXBkYXRlZCA9IHVwZGF0ZUJpbmRpbmdEYXRhKFxuICAgICAgY29udGV4dCwgZGF0YSwgaW5kZXgsIHByb3AsIGJpbmRpbmdJbmRleCwgdmFsdWUsIGRlZmVyUmVnaXN0cmF0aW9uLCBmb3JjZVVwZGF0ZSxcbiAgICAgIHNhbml0aXphdGlvblJlcXVpcmVkKTtcbiAgaWYgKHVwZGF0ZWQgfHwgZm9yY2VVcGRhdGUpIHtcbiAgICBzdHlsZXNCaXRNYXNrIHw9IDEgPDwgaW5kZXg7XG4gIH1cbn1cblxuLyoqXG4gKiBDYWxsZWQgZWFjaCB0aW1lIGEgYmluZGluZyB2YWx1ZSBoYXMgY2hhbmdlZCB3aXRoaW4gdGhlIHByb3ZpZGVkIGBUU3R5bGluZ0NvbnRleHRgLlxuICpcbiAqIFRoaXMgZnVuY3Rpb24gaXMgZGVzaWduZWQgdG8gYmUgY2FsbGVkIGZyb20gYHVwZGF0ZVN0eWxlQmluZGluZ2AgYW5kIGB1cGRhdGVDbGFzc0JpbmRpbmdgLlxuICogSWYgY2FsbGVkIGR1cmluZyB0aGUgZmlyc3QgdXBkYXRlIHBhc3MsIHRoZSBiaW5kaW5nIHdpbGwgYmUgcmVnaXN0ZXJlZCBpbiB0aGUgY29udGV4dC5cbiAqIElmIHRoZSBiaW5kaW5nIGRvZXMgZ2V0IHJlZ2lzdGVyZWQgYW5kIHRoZSBgZGVmZXJSZWdpc3RyYXRpb25gIGZsYWcgaXMgdHJ1ZSB0aGVuIHRoZVxuICogYmluZGluZyBkYXRhIHdpbGwgYmUgcXVldWVkIHVwIHVudGlsIHRoZSBjb250ZXh0IGlzIGxhdGVyIGZsdXNoZWQgaW4gYGFwcGx5U3R5bGluZ2AuXG4gKlxuICogVGhpcyBmdW5jdGlvbiB3aWxsIGFsc28gdXBkYXRlIGJpbmRpbmcgc2xvdCBpbiB0aGUgcHJvdmlkZWQgYExTdHlsaW5nRGF0YWAgd2l0aCB0aGVcbiAqIG5ldyBiaW5kaW5nIGVudHJ5IChpZiBpdCBoYXMgY2hhbmdlZCkuXG4gKlxuICogQHJldHVybnMgd2hldGhlciBvciBub3QgdGhlIGJpbmRpbmcgdmFsdWUgd2FzIHVwZGF0ZWQgaW4gdGhlIGBMU3R5bGluZ0RhdGFgLlxuICovXG5mdW5jdGlvbiB1cGRhdGVCaW5kaW5nRGF0YShcbiAgICBjb250ZXh0OiBUU3R5bGluZ0NvbnRleHQsIGRhdGE6IExTdHlsaW5nRGF0YSwgY291bnRlckluZGV4OiBudW1iZXIsIHByb3A6IHN0cmluZyB8IG51bGwsXG4gICAgYmluZGluZ0luZGV4OiBudW1iZXIsXG4gICAgdmFsdWU6IHN0cmluZyB8IFN0cmluZyB8IG51bWJlciB8IGJvb2xlYW4gfCBudWxsIHwgdW5kZWZpbmVkIHwgTFN0eWxpbmdNYXAsXG4gICAgZGVmZXJSZWdpc3RyYXRpb246IGJvb2xlYW4sIGZvcmNlVXBkYXRlOiBib29sZWFuLCBzYW5pdGl6YXRpb25SZXF1aXJlZDogYm9vbGVhbik6IGJvb2xlYW4ge1xuICBpZiAoIWlzQ29udGV4dExvY2tlZChjb250ZXh0KSkge1xuICAgIGlmIChkZWZlclJlZ2lzdHJhdGlvbikge1xuICAgICAgZGVmZXJCaW5kaW5nUmVnaXN0cmF0aW9uKGNvbnRleHQsIGNvdW50ZXJJbmRleCwgcHJvcCwgYmluZGluZ0luZGV4LCBzYW5pdGl6YXRpb25SZXF1aXJlZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRlZmVycmVkQmluZGluZ1F1ZXVlLmxlbmd0aCAmJiBmbHVzaERlZmVycmVkQmluZGluZ3MoKTtcblxuICAgICAgLy8gdGhpcyB3aWxsIG9ubHkgaGFwcGVuIGR1cmluZyB0aGUgZmlyc3QgdXBkYXRlIHBhc3Mgb2YgdGhlXG4gICAgICAvLyBjb250ZXh0LiBUaGUgcmVhc29uIHdoeSB3ZSBjYW4ndCB1c2UgYHROb2RlLmZpcnN0VGVtcGxhdGVQYXNzYFxuICAgICAgLy8gaGVyZSBpcyBiZWNhdXNlIGl0cyBub3QgZ3VhcmFudGVlZCB0byBiZSB0cnVlIHdoZW4gdGhlIGZpcnN0XG4gICAgICAvLyB1cGRhdGUgcGFzcyBpcyBleGVjdXRlZCAocmVtZW1iZXIgdGhhdCBhbGwgc3R5bGluZyBpbnN0cnVjdGlvbnNcbiAgICAgIC8vIGFyZSBydW4gaW4gdGhlIHVwZGF0ZSBwaGFzZSwgYW5kLCBhcyBhIHJlc3VsdCwgYXJlIG5vIG1vcmVcbiAgICAgIC8vIHN0eWxpbmcgaW5zdHJ1Y3Rpb25zIHRoYXQgYXJlIHJ1biBpbiB0aGUgY3JlYXRpb24gcGhhc2UpLlxuICAgICAgcmVnaXN0ZXJCaW5kaW5nKGNvbnRleHQsIGNvdW50ZXJJbmRleCwgcHJvcCwgYmluZGluZ0luZGV4LCBzYW5pdGl6YXRpb25SZXF1aXJlZCk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgY2hhbmdlZCA9IGZvcmNlVXBkYXRlIHx8IGhhc1ZhbHVlQ2hhbmdlZChkYXRhW2JpbmRpbmdJbmRleF0sIHZhbHVlKTtcbiAgaWYgKGNoYW5nZWQpIHtcbiAgICBkYXRhW2JpbmRpbmdJbmRleF0gPSB2YWx1ZTtcbiAgfVxuICByZXR1cm4gY2hhbmdlZDtcbn1cblxuLyoqXG4gKiBTY2hlZHVsZXMgYSBiaW5kaW5nIHJlZ2lzdHJhdGlvbiB0byBiZSBydW4gYXQgYSBsYXRlciBwb2ludC5cbiAqXG4gKiBUaGUgcmVhc29uaW5nIGZvciB0aGlzIGZlYXR1cmUgaXMgdG8gZW5zdXJlIHRoYXQgc3R5bGluZ1xuICogYmluZGluZ3MgYXJlIHJlZ2lzdGVyZWQgaW4gdGhlIGNvcnJlY3Qgb3JkZXIgZm9yIHdoZW5cbiAqIGRpcmVjdGl2ZXMvY29tcG9uZW50cyBoYXZlIGEgc3VwZXIvc3ViIGNsYXNzIGluaGVyaXRhbmNlXG4gKiBjaGFpbnMuIEVhY2ggZGlyZWN0aXZlJ3Mgc3R5bGluZyBiaW5kaW5ncyBtdXN0IGJlXG4gKiByZWdpc3RlcmVkIGludG8gdGhlIGNvbnRleHQgaW4gcmV2ZXJzZSBvcmRlci4gVGhlcmVmb3JlIGFsbFxuICogYmluZGluZ3Mgd2lsbCBiZSBidWZmZXJlZCBpbiByZXZlcnNlIG9yZGVyIGFuZCB0aGVuIGFwcGxpZWRcbiAqIGFmdGVyIHRoZSBpbmhlcml0YW5jZSBjaGFpbiBleGl0cy5cbiAqL1xuZnVuY3Rpb24gZGVmZXJCaW5kaW5nUmVnaXN0cmF0aW9uKFxuICAgIGNvbnRleHQ6IFRTdHlsaW5nQ29udGV4dCwgY291bnRlckluZGV4OiBudW1iZXIsIHByb3A6IHN0cmluZyB8IG51bGwsIGJpbmRpbmdJbmRleDogbnVtYmVyLFxuICAgIHNhbml0aXphdGlvblJlcXVpcmVkOiBib29sZWFuKSB7XG4gIGRlZmVycmVkQmluZGluZ1F1ZXVlLnVuc2hpZnQoY29udGV4dCwgY291bnRlckluZGV4LCBwcm9wLCBiaW5kaW5nSW5kZXgsIHNhbml0aXphdGlvblJlcXVpcmVkKTtcbn1cblxuLyoqXG4gKiBGbHVzaGVzIHRoZSBjb2xsZWN0aW9uIG9mIGRlZmVycmVkIGJpbmRpbmdzIGFuZCBjYXVzZXMgZWFjaCBlbnRyeVxuICogdG8gYmUgcmVnaXN0ZXJlZCBpbnRvIHRoZSBjb250ZXh0LlxuICovXG5mdW5jdGlvbiBmbHVzaERlZmVycmVkQmluZGluZ3MoKSB7XG4gIGxldCBpID0gMDtcbiAgd2hpbGUgKGkgPCBkZWZlcnJlZEJpbmRpbmdRdWV1ZS5sZW5ndGgpIHtcbiAgICBjb25zdCBjb250ZXh0ID0gZGVmZXJyZWRCaW5kaW5nUXVldWVbaSsrXSBhcyBUU3R5bGluZ0NvbnRleHQ7XG4gICAgY29uc3QgY291bnQgPSBkZWZlcnJlZEJpbmRpbmdRdWV1ZVtpKytdIGFzIG51bWJlcjtcbiAgICBjb25zdCBwcm9wID0gZGVmZXJyZWRCaW5kaW5nUXVldWVbaSsrXSBhcyBzdHJpbmc7XG4gICAgY29uc3QgYmluZGluZ0luZGV4ID0gZGVmZXJyZWRCaW5kaW5nUXVldWVbaSsrXSBhcyBudW1iZXIgfCBudWxsO1xuICAgIGNvbnN0IHNhbml0aXphdGlvblJlcXVpcmVkID0gZGVmZXJyZWRCaW5kaW5nUXVldWVbaSsrXSBhcyBib29sZWFuO1xuICAgIHJlZ2lzdGVyQmluZGluZyhjb250ZXh0LCBjb3VudCwgcHJvcCwgYmluZGluZ0luZGV4LCBzYW5pdGl6YXRpb25SZXF1aXJlZCk7XG4gIH1cbiAgZGVmZXJyZWRCaW5kaW5nUXVldWUubGVuZ3RoID0gMDtcbn1cblxuLyoqXG4gKiBSZWdpc3RlcnMgdGhlIHByb3ZpZGVkIGJpbmRpbmcgKHByb3AgKyBiaW5kaW5nSW5kZXgpIGludG8gdGhlIGNvbnRleHQuXG4gKlxuICogVGhpcyBmdW5jdGlvbiBpcyBzaGFyZWQgYmV0d2VlbiBiaW5kaW5ncyB0aGF0IGFyZSBhc3NpZ25lZCBpbW1lZGlhdGVseVxuICogKHZpYSBgdXBkYXRlQmluZGluZ0RhdGFgKSBhbmQgYXQgYSBkZWZlcnJlZCBzdGFnZS4gV2hlbiBjYWxsZWQsIGl0IHdpbGxcbiAqIGZpZ3VyZSBvdXQgZXhhY3RseSB3aGVyZSB0byBwbGFjZSB0aGUgYmluZGluZyBkYXRhIGluIHRoZSBjb250ZXh0LlxuICpcbiAqIEl0IGlzIG5lZWRlZCBiZWNhdXNlIGl0IHdpbGwgZWl0aGVyIHVwZGF0ZSBvciBpbnNlcnQgYSBzdHlsaW5nIHByb3BlcnR5XG4gKiBpbnRvIHRoZSBjb250ZXh0IGF0IHRoZSBjb3JyZWN0IHNwb3QuXG4gKlxuICogV2hlbiBjYWxsZWQsIG9uZSBvZiB0d28gdGhpbmdzIHdpbGwgaGFwcGVuOlxuICpcbiAqIDEpIElmIHRoZSBwcm9wZXJ0eSBhbHJlYWR5IGV4aXN0cyBpbiB0aGUgY29udGV4dCB0aGVuIGl0IHdpbGwganVzdCBhZGRcbiAqICAgIHRoZSBwcm92aWRlZCBgYmluZGluZ1ZhbHVlYCB0byB0aGUgZW5kIG9mIHRoZSBiaW5kaW5nIHNvdXJjZXMgcmVnaW9uXG4gKiAgICBmb3IgdGhhdCBwYXJ0aWN1bGFyIHByb3BlcnR5LlxuICpcbiAqICAgIC0gSWYgdGhlIGJpbmRpbmcgdmFsdWUgaXMgYSBudW1iZXIgdGhlbiBpdCB3aWxsIGJlIGFkZGVkIGFzIGEgbmV3XG4gKiAgICAgIGJpbmRpbmcgaW5kZXggc291cmNlIG5leHQgdG8gdGhlIG90aGVyIGJpbmRpbmcgc291cmNlcyBmb3IgdGhlIHByb3BlcnR5LlxuICpcbiAqICAgIC0gT3RoZXJ3aXNlLCBpZiB0aGUgYmluZGluZyB2YWx1ZSBpcyBhIHN0cmluZy9ib29sZWFuL251bGwgdHlwZSB0aGVuIGl0IHdpbGxcbiAqICAgICAgcmVwbGFjZSB0aGUgZGVmYXVsdCB2YWx1ZSBmb3IgdGhlIHByb3BlcnR5IGlmIHRoZSBkZWZhdWx0IHZhbHVlIGlzIGBudWxsYC5cbiAqXG4gKiAyKSBJZiB0aGUgcHJvcGVydHkgZG9lcyBub3QgZXhpc3QgdGhlbiBpdCB3aWxsIGJlIGluc2VydGVkIGludG8gdGhlIGNvbnRleHQuXG4gKiAgICBUaGUgc3R5bGluZyBjb250ZXh0IHJlbGllcyBvbiBhbGwgcHJvcGVydGllcyBiZWluZyBzdG9yZWQgaW4gYWxwaGFiZXRpY2FsXG4gKiAgICBvcmRlciwgc28gaXQga25vd3MgZXhhY3RseSB3aGVyZSB0byBzdG9yZSBpdC5cbiAqXG4gKiAgICBXaGVuIGluc2VydGVkLCBhIGRlZmF1bHQgYG51bGxgIHZhbHVlIGlzIGNyZWF0ZWQgZm9yIHRoZSBwcm9wZXJ0eSB3aGljaCBleGlzdHNcbiAqICAgIGFzIHRoZSBkZWZhdWx0IHZhbHVlIGZvciB0aGUgYmluZGluZy4gSWYgdGhlIGJpbmRpbmdWYWx1ZSBwcm9wZXJ0eSBpcyBpbnNlcnRlZFxuICogICAgYW5kIGl0IGlzIGVpdGhlciBhIHN0cmluZywgbnVtYmVyIG9yIG51bGwgdmFsdWUgdGhlbiB0aGF0IHdpbGwgcmVwbGFjZSB0aGUgZGVmYXVsdFxuICogICAgdmFsdWUuXG4gKlxuICogTm90ZSB0aGF0IHRoaXMgZnVuY3Rpb24gaXMgYWxzbyB1c2VkIGZvciBtYXAtYmFzZWQgc3R5bGluZyBiaW5kaW5ncy4gVGhleSBhcmUgdHJlYXRlZFxuICogbXVjaCB0aGUgc2FtZSBhcyBwcm9wLWJhc2VkIGJpbmRpbmdzLCBidXQsIGJlY2F1c2UgdGhleSBkbyBub3QgaGF2ZSBhIHByb3BlcnR5IHZhbHVlXG4gKiAoc2luY2UgaXQncyBhIG1hcCksIGFsbCBtYXAtYmFzZWQgZW50cmllcyBhcmUgc3RvcmVkIGluIGFuIGFscmVhZHkgcG9wdWxhdGVkIGFyZWEgb2ZcbiAqIHRoZSBjb250ZXh0IGF0IHRoZSB0b3AgKHdoaWNoIGlzIHJlc2VydmVkIGZvciBtYXAtYmFzZWQgZW50cmllcykuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWdpc3RlckJpbmRpbmcoXG4gICAgY29udGV4dDogVFN0eWxpbmdDb250ZXh0LCBjb3VudElkOiBudW1iZXIsIHByb3A6IHN0cmluZyB8IG51bGwsXG4gICAgYmluZGluZ1ZhbHVlOiBudW1iZXIgfCBudWxsIHwgc3RyaW5nIHwgYm9vbGVhbiwgc2FuaXRpemF0aW9uUmVxdWlyZWQ/OiBib29sZWFuKSB7XG4gIC8vIHByb3AtYmFzZWQgYmluZGluZ3MgKGUuZyBgPGRpdiBbc3R5bGUud2lkdGhdPVwid1wiIFtjbGFzcy5mb29dPVwiZlwiPmApXG4gIGlmIChwcm9wKSB7XG4gICAgbGV0IGZvdW5kID0gZmFsc2U7XG4gICAgbGV0IGkgPSBnZXRQcm9wVmFsdWVzU3RhcnRQb3NpdGlvbihjb250ZXh0KTtcbiAgICB3aGlsZSAoaSA8IGNvbnRleHQubGVuZ3RoKSB7XG4gICAgICBjb25zdCB2YWx1ZXNDb3VudCA9IGdldFZhbHVlc0NvdW50KGNvbnRleHQsIGkpO1xuICAgICAgY29uc3QgcCA9IGdldFByb3AoY29udGV4dCwgaSk7XG4gICAgICBmb3VuZCA9IHByb3AgPD0gcDtcbiAgICAgIGlmIChmb3VuZCkge1xuICAgICAgICAvLyBhbGwgc3R5bGUvY2xhc3MgYmluZGluZ3MgYXJlIHNvcnRlZCBieSBwcm9wZXJ0eSBuYW1lXG4gICAgICAgIGlmIChwcm9wIDwgcCkge1xuICAgICAgICAgIGFsbG9jYXRlTmV3Q29udGV4dEVudHJ5KGNvbnRleHQsIGksIHByb3AsIHNhbml0aXphdGlvblJlcXVpcmVkKTtcbiAgICAgICAgfVxuICAgICAgICBhZGRCaW5kaW5nSW50b0NvbnRleHQoY29udGV4dCwgZmFsc2UsIGksIGJpbmRpbmdWYWx1ZSwgY291bnRJZCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaSArPSBUU3R5bGluZ0NvbnRleHRJbmRleC5CaW5kaW5nc1N0YXJ0T2Zmc2V0ICsgdmFsdWVzQ291bnQ7XG4gICAgfVxuXG4gICAgaWYgKCFmb3VuZCkge1xuICAgICAgYWxsb2NhdGVOZXdDb250ZXh0RW50cnkoY29udGV4dCwgY29udGV4dC5sZW5ndGgsIHByb3AsIHNhbml0aXphdGlvblJlcXVpcmVkKTtcbiAgICAgIGFkZEJpbmRpbmdJbnRvQ29udGV4dChjb250ZXh0LCBmYWxzZSwgaSwgYmluZGluZ1ZhbHVlLCBjb3VudElkKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gbWFwLWJhc2VkIGJpbmRpbmdzIChlLmcgYDxkaXYgW3N0eWxlXT1cInNcIiBbY2xhc3NdPVwie2NsYXNzTmFtZTp0cnVlfVwiPmApXG4gICAgLy8gdGhlcmUgaXMgbm8gbmVlZCB0byBhbGxvY2F0ZSB0aGUgbWFwLWJhc2VkIGJpbmRpbmcgcmVnaW9uIGludG8gdGhlIGNvbnRleHRcbiAgICAvLyBzaW5jZSBpdCBpcyBhbHJlYWR5IHRoZXJlIHdoZW4gdGhlIGNvbnRleHQgaXMgZmlyc3QgY3JlYXRlZC5cbiAgICBhZGRCaW5kaW5nSW50b0NvbnRleHQoXG4gICAgICAgIGNvbnRleHQsIHRydWUsIFRTdHlsaW5nQ29udGV4dEluZGV4Lk1hcEJpbmRpbmdzUG9zaXRpb24sIGJpbmRpbmdWYWx1ZSwgY291bnRJZCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gYWxsb2NhdGVOZXdDb250ZXh0RW50cnkoXG4gICAgY29udGV4dDogVFN0eWxpbmdDb250ZXh0LCBpbmRleDogbnVtYmVyLCBwcm9wOiBzdHJpbmcsIHNhbml0aXphdGlvblJlcXVpcmVkPzogYm9vbGVhbikge1xuICAvLyAxLDI6IHNwbGljZSBpbmRleCBsb2NhdGlvbnNcbiAgLy8gMzogZWFjaCBlbnRyeSBnZXRzIGEgY29uZmlnIHZhbHVlIChndWFyZCBtYXNrICsgZmxhZ3MpXG4gIC8vIDQuIGVhY2ggZW50cnkgZ2V0cyBhIHNpemUgdmFsdWUgKHdoaWNoIGlzIGFsd2F5cyBvbmUgYmVjYXVzZSB0aGVyZSBpcyBhbHdheXMgYSBkZWZhdWx0IGJpbmRpbmdcbiAgLy8gdmFsdWUpXG4gIC8vIDUuIHRoZSBwcm9wZXJ0eSB0aGF0IGlzIGdldHRpbmcgYWxsb2NhdGVkIGludG8gdGhlIGNvbnRleHRcbiAgLy8gNi4gdGhlIGRlZmF1bHQgYmluZGluZyB2YWx1ZSAodXN1YWxseSBgbnVsbGApXG4gIGNvbnN0IGNvbmZpZyA9IHNhbml0aXphdGlvblJlcXVpcmVkID8gVFN0eWxpbmdDb250ZXh0UHJvcENvbmZpZ0ZsYWdzLlNhbml0aXphdGlvblJlcXVpcmVkIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUU3R5bGluZ0NvbnRleHRQcm9wQ29uZmlnRmxhZ3MuRGVmYXVsdDtcbiAgY29udGV4dC5zcGxpY2UoaW5kZXgsIDAsIGNvbmZpZywgREVGQVVMVF9TSVpFX1ZBTFVFLCBwcm9wLCBERUZBVUxUX0JJTkRJTkdfVkFMVUUpO1xuICBzZXRHdWFyZE1hc2soY29udGV4dCwgaW5kZXgsIERFRkFVTFRfR1VBUkRfTUFTS19WQUxVRSk7XG59XG5cbi8qKlxuICogSW5zZXJ0cyBhIG5ldyBiaW5kaW5nIHZhbHVlIGludG8gYSBzdHlsaW5nIHByb3BlcnR5IHR1cGxlIGluIHRoZSBgVFN0eWxpbmdDb250ZXh0YC5cbiAqXG4gKiBBIGJpbmRpbmdWYWx1ZSBpcyBpbnNlcnRlZCBpbnRvIGEgY29udGV4dCBkdXJpbmcgdGhlIGZpcnN0IHVwZGF0ZSBwYXNzXG4gKiBvZiBhIHRlbXBsYXRlIG9yIGhvc3QgYmluZGluZ3MgZnVuY3Rpb24uIFdoZW4gdGhpcyBvY2N1cnMsIHR3byB0aGluZ3NcbiAqIGhhcHBlbjpcbiAqXG4gKiAtIElmIHRoZSBiaW5kaW5nVmFsdWUgdmFsdWUgaXMgYSBudW1iZXIgdGhlbiBpdCBpcyB0cmVhdGVkIGFzIGEgYmluZGluZ0luZGV4XG4gKiAgIHZhbHVlIChhIGluZGV4IGluIHRoZSBgTFZpZXdgKSBhbmQgaXQgd2lsbCBiZSBpbnNlcnRlZCBuZXh0IHRvIHRoZSBvdGhlclxuICogICBiaW5kaW5nIGluZGV4IGVudHJpZXMuXG4gKlxuICogLSBPdGhlcndpc2UgdGhlIGJpbmRpbmcgdmFsdWUgd2lsbCB1cGRhdGUgdGhlIGRlZmF1bHQgdmFsdWUgZm9yIHRoZSBwcm9wZXJ0eVxuICogICBhbmQgdGhpcyB3aWxsIG9ubHkgaGFwcGVuIGlmIHRoZSBkZWZhdWx0IHZhbHVlIGlzIGBudWxsYC5cbiAqXG4gKiBOb3RlIHRoYXQgdGhpcyBmdW5jdGlvbiBhbHNvIGhhbmRsZXMgbWFwLWJhc2VkIGJpbmRpbmdzIGFuZCB3aWxsIGluc2VydCB0aGVtXG4gKiBhdCB0aGUgdG9wIG9mIHRoZSBjb250ZXh0LlxuICovXG5mdW5jdGlvbiBhZGRCaW5kaW5nSW50b0NvbnRleHQoXG4gICAgY29udGV4dDogVFN0eWxpbmdDb250ZXh0LCBpc01hcEJhc2VkOiBib29sZWFuLCBpbmRleDogbnVtYmVyLFxuICAgIGJpbmRpbmdWYWx1ZTogbnVtYmVyIHwgc3RyaW5nIHwgYm9vbGVhbiB8IG51bGwsIGNvdW50SWQ6IG51bWJlcikge1xuICBjb25zdCB2YWx1ZXNDb3VudCA9IGdldFZhbHVlc0NvdW50KGNvbnRleHQsIGluZGV4KTtcblxuICBsZXQgbGFzdFZhbHVlSW5kZXggPSBpbmRleCArIFRTdHlsaW5nQ29udGV4dEluZGV4LkJpbmRpbmdzU3RhcnRPZmZzZXQgKyB2YWx1ZXNDb3VudDtcbiAgaWYgKCFpc01hcEJhc2VkKSB7XG4gICAgLy8gcHJvcC1iYXNlZCB2YWx1ZXMgYWxsIGhhdmUgZGVmYXVsdCB2YWx1ZXMsIGJ1dCBtYXAtYmFzZWQgZW50cmllcyBkbyBub3QuXG4gICAgLy8gd2Ugd2FudCB0byBhY2Nlc3MgdGhlIGluZGV4IGZvciB0aGUgZGVmYXVsdCB2YWx1ZSBpbiB0aGlzIGNhc2UgYW5kIG5vdCBqdXN0XG4gICAgLy8gdGhlIGJpbmRpbmdzLi4uXG4gICAgbGFzdFZhbHVlSW5kZXgtLTtcbiAgfVxuXG4gIGlmICh0eXBlb2YgYmluZGluZ1ZhbHVlID09PSAnbnVtYmVyJykge1xuICAgIGNvbnRleHQuc3BsaWNlKGxhc3RWYWx1ZUluZGV4LCAwLCBiaW5kaW5nVmFsdWUpO1xuICAgIChjb250ZXh0W2luZGV4ICsgVFN0eWxpbmdDb250ZXh0SW5kZXguVmFsdWVzQ291bnRPZmZzZXRdIGFzIG51bWJlcikrKztcblxuICAgIC8vIG5vdyB0aGF0IGEgbmV3IGJpbmRpbmcgaW5kZXggaGFzIGJlZW4gYWRkZWQgdG8gdGhlIHByb3BlcnR5XG4gICAgLy8gdGhlIGd1YXJkIG1hc2sgYml0IHZhbHVlIChhdCB0aGUgYGNvdW50SWRgIHBvc2l0aW9uKSBuZWVkc1xuICAgIC8vIHRvIGJlIGluY2x1ZGVkIGludG8gdGhlIGV4aXN0aW5nIG1hc2sgdmFsdWUuXG4gICAgY29uc3QgZ3VhcmRNYXNrID0gZ2V0R3VhcmRNYXNrKGNvbnRleHQsIGluZGV4KSB8ICgxIDw8IGNvdW50SWQpO1xuICAgIHNldEd1YXJkTWFzayhjb250ZXh0LCBpbmRleCwgZ3VhcmRNYXNrKTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgYmluZGluZ1ZhbHVlID09PSAnc3RyaW5nJyAmJiBjb250ZXh0W2xhc3RWYWx1ZUluZGV4XSA9PSBudWxsKSB7XG4gICAgY29udGV4dFtsYXN0VmFsdWVJbmRleF0gPSBiaW5kaW5nVmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBBcHBsaWVzIGFsbCBjbGFzcyBlbnRyaWVzIGluIHRoZSBwcm92aWRlZCBjb250ZXh0IHRvIHRoZSBwcm92aWRlZCBlbGVtZW50IGFuZCByZXNldHNcbiAqIGFueSBjb3VudGVyIGFuZC9vciBiaXRNYXNrIHZhbHVlcyBhc3NvY2lhdGVkIHdpdGggY2xhc3MgYmluZGluZ3MuXG4gKlxuICogQHJldHVybnMgd2hldGhlciBvciBub3QgdGhlIGNsYXNzZXMgd2VyZSBmbHVzaGVkIHRvIHRoZSBlbGVtZW50LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlDbGFzc2VzKFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjMgfCBQcm9jZWR1cmFsUmVuZGVyZXIzIHwgbnVsbCwgZGF0YTogTFN0eWxpbmdEYXRhLCBjb250ZXh0OiBUU3R5bGluZ0NvbnRleHQsXG4gICAgZWxlbWVudDogUkVsZW1lbnQsIGRpcmVjdGl2ZUluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgbGV0IGNsYXNzZXNGbHVzaGVkID0gZmFsc2U7XG4gIGlmIChhbGxvd1N0eWxpbmdGbHVzaChjb250ZXh0LCBkaXJlY3RpdmVJbmRleCkpIHtcbiAgICBjb25zdCBpc0ZpcnN0UGFzcyA9ICFpc0NvbnRleHRMb2NrZWQoY29udGV4dCk7XG4gICAgaXNGaXJzdFBhc3MgJiYgbG9ja0NvbnRleHQoY29udGV4dCk7XG4gICAgaWYgKGNsYXNzZXNCaXRNYXNrKSB7XG4gICAgICAvLyB0aGVyZSBpcyBubyB3YXkgdG8gc2FuaXRpemUgYSBjbGFzcyB2YWx1ZSB0aGVyZWZvcmUgYHNhbml0aXplcj1udWxsYFxuICAgICAgYXBwbHlTdHlsaW5nKGNvbnRleHQsIHJlbmRlcmVyLCBlbGVtZW50LCBkYXRhLCBjbGFzc2VzQml0TWFzaywgc2V0Q2xhc3MsIG51bGwpO1xuICAgICAgY2xhc3Nlc0JpdE1hc2sgPSAwO1xuICAgICAgY2xhc3Nlc0ZsdXNoZWQgPSB0cnVlO1xuICAgIH1cbiAgICBjdXJyZW50Q2xhc3NJbmRleCA9IFNUWUxJTkdfSU5ERVhfU1RBUlRfVkFMVUU7XG4gIH1cbiAgcmV0dXJuIGNsYXNzZXNGbHVzaGVkO1xufVxuXG4vKipcbiAqIEFwcGxpZXMgYWxsIHN0eWxlIGVudHJpZXMgaW4gdGhlIHByb3ZpZGVkIGNvbnRleHQgdG8gdGhlIHByb3ZpZGVkIGVsZW1lbnQgYW5kIHJlc2V0c1xuICogYW55IGNvdW50ZXIgYW5kL29yIGJpdE1hc2sgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCBzdHlsZSBiaW5kaW5ncy5cbiAqXG4gKiBAcmV0dXJucyB3aGV0aGVyIG9yIG5vdCB0aGUgc3R5bGVzIHdlcmUgZmx1c2hlZCB0byB0aGUgZWxlbWVudC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5U3R5bGVzKFxuICAgIHJlbmRlcmVyOiBSZW5kZXJlcjMgfCBQcm9jZWR1cmFsUmVuZGVyZXIzIHwgbnVsbCwgZGF0YTogTFN0eWxpbmdEYXRhLCBjb250ZXh0OiBUU3R5bGluZ0NvbnRleHQsXG4gICAgZWxlbWVudDogUkVsZW1lbnQsIGRpcmVjdGl2ZUluZGV4OiBudW1iZXIsIHNhbml0aXplcjogU3R5bGVTYW5pdGl6ZUZuIHwgbnVsbCk6IGJvb2xlYW4ge1xuICBsZXQgc3R5bGVzRmx1c2hlZCA9IGZhbHNlO1xuICBpZiAoYWxsb3dTdHlsaW5nRmx1c2goY29udGV4dCwgZGlyZWN0aXZlSW5kZXgpKSB7XG4gICAgY29uc3QgaXNGaXJzdFBhc3MgPSAhaXNDb250ZXh0TG9ja2VkKGNvbnRleHQpO1xuICAgIGlzRmlyc3RQYXNzICYmIGxvY2tDb250ZXh0KGNvbnRleHQpO1xuICAgIGlmIChzdHlsZXNCaXRNYXNrKSB7XG4gICAgICBhcHBseVN0eWxpbmcoY29udGV4dCwgcmVuZGVyZXIsIGVsZW1lbnQsIGRhdGEsIHN0eWxlc0JpdE1hc2ssIHNldFN0eWxlLCBzYW5pdGl6ZXIpO1xuICAgICAgc3R5bGVzQml0TWFzayA9IDA7XG4gICAgICBzdHlsZXNGbHVzaGVkID0gdHJ1ZTtcbiAgICB9XG4gICAgY3VycmVudFN0eWxlSW5kZXggPSBTVFlMSU5HX0lOREVYX1NUQVJUX1ZBTFVFO1xuICAgIHJldHVybiB0cnVlO1xuICB9XG4gIHJldHVybiBzdHlsZXNGbHVzaGVkO1xufVxuXG4vKipcbiAqIFJ1bnMgdGhyb3VnaCB0aGUgcHJvdmlkZWQgc3R5bGluZyBjb250ZXh0IGFuZCBhcHBsaWVzIGVhY2ggdmFsdWUgdG9cbiAqIHRoZSBwcm92aWRlZCBlbGVtZW50ICh2aWEgdGhlIHJlbmRlcmVyKSBpZiBvbmUgb3IgbW9yZSB2YWx1ZXMgYXJlIHByZXNlbnQuXG4gKlxuICogVGhpcyBmdW5jdGlvbiB3aWxsIGl0ZXJhdGUgb3ZlciBhbGwgZW50cmllcyBwcmVzZW50IGluIHRoZSBwcm92aWRlZFxuICogYFRTdHlsaW5nQ29udGV4dGAgYXJyYXkgKGJvdGggcHJvcC1iYXNlZCBhbmQgbWFwLWJhc2VkIGJpbmRpbmdzKS4tXG4gKlxuICogRWFjaCBlbnRyeSwgd2l0aGluIHRoZSBgVFN0eWxpbmdDb250ZXh0YCBhcnJheSwgaXMgc3RvcmVkIGFscGhhYmV0aWNhbGx5XG4gKiBhbmQgdGhpcyBtZWFucyB0aGF0IGVhY2ggcHJvcC92YWx1ZSBlbnRyeSB3aWxsIGJlIGFwcGxpZWQgaW4gb3JkZXJcbiAqIChzbyBsb25nIGFzIGl0IGlzIG1hcmtlZCBkaXJ0eSBpbiB0aGUgcHJvdmlkZWQgYGJpdE1hc2tgIHZhbHVlKS5cbiAqXG4gKiBJZiB0aGVyZSBhcmUgYW55IG1hcC1iYXNlZCBlbnRyaWVzIHByZXNlbnQgKHdoaWNoIGFyZSBhcHBsaWVkIHRvIHRoZVxuICogZWxlbWVudCB2aWEgdGhlIGBbc3R5bGVdYCBhbmQgYFtjbGFzc11gIGJpbmRpbmdzKSB0aGVuIHRob3NlIGVudHJpZXNcbiAqIHdpbGwgYmUgYXBwbGllZCBhcyB3ZWxsLiBIb3dldmVyLCB0aGUgY29kZSBmb3IgdGhhdCBpcyBub3QgYXBhcnQgb2ZcbiAqIHRoaXMgZnVuY3Rpb24uIEluc3RlYWQsIGVhY2ggdGltZSBhIHByb3BlcnR5IGlzIHZpc2l0ZWQsIHRoZW4gdGhlXG4gKiBjb2RlIGJlbG93IHdpbGwgY2FsbCBhbiBleHRlcm5hbCBmdW5jdGlvbiBjYWxsZWQgYHN0eWxpbmdNYXBzU3luY0ZuYFxuICogYW5kLCBpZiBwcmVzZW50LCBpdCB3aWxsIGtlZXAgdGhlIGFwcGxpY2F0aW9uIG9mIHN0eWxpbmcgdmFsdWVzIGluXG4gKiBtYXAtYmFzZWQgYmluZGluZ3MgdXAgdG8gc3luYyB3aXRoIHRoZSBhcHBsaWNhdGlvbiBvZiBwcm9wLWJhc2VkXG4gKiBiaW5kaW5ncy5cbiAqXG4gKiBWaXNpdCBgc3R5bGluZ19uZXh0L21hcF9iYXNlZF9iaW5kaW5ncy50c2AgdG8gbGVhcm4gbW9yZSBhYm91dCBob3cgdGhlXG4gKiBhbGdvcml0aG0gd29ya3MgZm9yIG1hcC1iYXNlZCBzdHlsaW5nIGJpbmRpbmdzLlxuICpcbiAqIE5vdGUgdGhhdCB0aGlzIGZ1bmN0aW9uIGlzIG5vdCBkZXNpZ25lZCB0byBiZSBjYWxsZWQgaW4gaXNvbGF0aW9uICh1c2VcbiAqIGBhcHBseUNsYXNzZXNgIGFuZCBgYXBwbHlTdHlsZXNgIHRvIGFjdHVhbGx5IGFwcGx5IHN0eWxpbmcgdmFsdWVzKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5U3R5bGluZyhcbiAgICBjb250ZXh0OiBUU3R5bGluZ0NvbnRleHQsIHJlbmRlcmVyOiBSZW5kZXJlcjMgfCBQcm9jZWR1cmFsUmVuZGVyZXIzIHwgbnVsbCwgZWxlbWVudDogUkVsZW1lbnQsXG4gICAgYmluZGluZ0RhdGE6IExTdHlsaW5nRGF0YSwgYml0TWFza1ZhbHVlOiBudW1iZXIgfCBib29sZWFuLCBhcHBseVN0eWxpbmdGbjogQXBwbHlTdHlsaW5nRm4sXG4gICAgc2FuaXRpemVyOiBTdHlsZVNhbml0aXplRm4gfCBudWxsKSB7XG4gIGRlZmVycmVkQmluZGluZ1F1ZXVlLmxlbmd0aCAmJiBmbHVzaERlZmVycmVkQmluZGluZ3MoKTtcblxuICBjb25zdCBiaXRNYXNrID0gbm9ybWFsaXplQml0TWFza1ZhbHVlKGJpdE1hc2tWYWx1ZSk7XG4gIGNvbnN0IHN0eWxpbmdNYXBzU3luY0ZuID0gZ2V0U3R5bGluZ01hcHNTeW5jRm4oKTtcbiAgY29uc3QgbWFwc0d1YXJkTWFzayA9IGdldEd1YXJkTWFzayhjb250ZXh0LCBUU3R5bGluZ0NvbnRleHRJbmRleC5NYXBCaW5kaW5nc1Bvc2l0aW9uKTtcbiAgY29uc3QgYXBwbHlBbGxWYWx1ZXMgPSAoYml0TWFzayAmIG1hcHNHdWFyZE1hc2spID4gMDtcbiAgY29uc3QgbWFwc01vZGUgPVxuICAgICAgYXBwbHlBbGxWYWx1ZXMgPyBTdHlsaW5nTWFwc1N5bmNNb2RlLkFwcGx5QWxsVmFsdWVzIDogU3R5bGluZ01hcHNTeW5jTW9kZS5UcmF2ZXJzZVZhbHVlcztcblxuICBsZXQgaSA9IGdldFByb3BWYWx1ZXNTdGFydFBvc2l0aW9uKGNvbnRleHQpO1xuICB3aGlsZSAoaSA8IGNvbnRleHQubGVuZ3RoKSB7XG4gICAgY29uc3QgdmFsdWVzQ291bnQgPSBnZXRWYWx1ZXNDb3VudChjb250ZXh0LCBpKTtcbiAgICBjb25zdCBndWFyZE1hc2sgPSBnZXRHdWFyZE1hc2soY29udGV4dCwgaSk7XG4gICAgaWYgKGJpdE1hc2sgJiBndWFyZE1hc2spIHtcbiAgICAgIGxldCB2YWx1ZUFwcGxpZWQgPSBmYWxzZTtcbiAgICAgIGNvbnN0IHByb3AgPSBnZXRQcm9wKGNvbnRleHQsIGkpO1xuICAgICAgY29uc3QgdmFsdWVzQ291bnRVcFRvRGVmYXVsdCA9IHZhbHVlc0NvdW50IC0gMTtcbiAgICAgIGNvbnN0IGRlZmF1bHRWYWx1ZSA9IGdldEJpbmRpbmdWYWx1ZShjb250ZXh0LCBpLCB2YWx1ZXNDb3VudFVwVG9EZWZhdWx0KSBhcyBzdHJpbmcgfCBudWxsO1xuXG4gICAgICAvLyBjYXNlIDE6IGFwcGx5IHByb3AtYmFzZWQgdmFsdWVzXG4gICAgICAvLyB0cnkgdG8gYXBwbHkgdGhlIGJpbmRpbmcgdmFsdWVzIGFuZCBzZWUgaWYgYSBub24tbnVsbFxuICAgICAgLy8gdmFsdWUgZ2V0cyBzZXQgZm9yIHRoZSBzdHlsaW5nIGJpbmRpbmdcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdmFsdWVzQ291bnRVcFRvRGVmYXVsdDsgaisrKSB7XG4gICAgICAgIGNvbnN0IGJpbmRpbmdJbmRleCA9IGdldEJpbmRpbmdWYWx1ZShjb250ZXh0LCBpLCBqKSBhcyBudW1iZXI7XG4gICAgICAgIGNvbnN0IHZhbHVlID0gYmluZGluZ0RhdGFbYmluZGluZ0luZGV4XTtcbiAgICAgICAgaWYgKGlzU3R5bGluZ1ZhbHVlRGVmaW5lZCh2YWx1ZSkpIHtcbiAgICAgICAgICBjb25zdCBmaW5hbFZhbHVlID0gc2FuaXRpemVyICYmIGlzU2FuaXRpemF0aW9uUmVxdWlyZWQoY29udGV4dCwgaSkgP1xuICAgICAgICAgICAgICBzYW5pdGl6ZXIocHJvcCwgdmFsdWUsIFN0eWxlU2FuaXRpemVNb2RlLlNhbml0aXplT25seSkgOlxuICAgICAgICAgICAgICB2YWx1ZTtcbiAgICAgICAgICBhcHBseVN0eWxpbmdGbihyZW5kZXJlciwgZWxlbWVudCwgcHJvcCwgZmluYWxWYWx1ZSwgYmluZGluZ0luZGV4KTtcbiAgICAgICAgICB2YWx1ZUFwcGxpZWQgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIGNhc2UgMjogYXBwbHkgbWFwLWJhc2VkIHZhbHVlc1xuICAgICAgLy8gdHJhdmVyc2UgdGhyb3VnaCBlYWNoIG1hcC1iYXNlZCBzdHlsaW5nIGJpbmRpbmcgYW5kIHVwZGF0ZSBhbGwgdmFsdWVzIHVwIHRvXG4gICAgICAvLyB0aGUgcHJvdmlkZWQgYHByb3BgIHZhbHVlLiBJZiB0aGUgcHJvcGVydHkgd2FzIG5vdCBhcHBsaWVkIGluIHRoZSBsb29wIGFib3ZlXG4gICAgICAvLyB0aGVuIGl0IHdpbGwgYmUgYXR0ZW1wdGVkIHRvIGJlIGFwcGxpZWQgaW4gdGhlIG1hcHMgc3luYyBjb2RlIGJlbG93LlxuICAgICAgaWYgKHN0eWxpbmdNYXBzU3luY0ZuKSB7XG4gICAgICAgIC8vIGRldGVybWluZSB3aGV0aGVyIG9yIG5vdCB0byBhcHBseSB0aGUgdGFyZ2V0IHByb3BlcnR5IG9yIHRvIHNraXAgaXRcbiAgICAgICAgY29uc3QgbW9kZSA9IG1hcHNNb2RlIHwgKHZhbHVlQXBwbGllZCA/IFN0eWxpbmdNYXBzU3luY01vZGUuU2tpcFRhcmdldFByb3AgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3R5bGluZ01hcHNTeW5jTW9kZS5BcHBseVRhcmdldFByb3ApO1xuICAgICAgICBjb25zdCB2YWx1ZUFwcGxpZWRXaXRoaW5NYXAgPSBzdHlsaW5nTWFwc1N5bmNGbihcbiAgICAgICAgICAgIGNvbnRleHQsIHJlbmRlcmVyLCBlbGVtZW50LCBiaW5kaW5nRGF0YSwgYXBwbHlTdHlsaW5nRm4sIHNhbml0aXplciwgbW9kZSwgcHJvcCxcbiAgICAgICAgICAgIGRlZmF1bHRWYWx1ZSk7XG4gICAgICAgIHZhbHVlQXBwbGllZCA9IHZhbHVlQXBwbGllZCB8fCB2YWx1ZUFwcGxpZWRXaXRoaW5NYXA7XG4gICAgICB9XG5cbiAgICAgIC8vIGNhc2UgMzogYXBwbHkgdGhlIGRlZmF1bHQgdmFsdWVcbiAgICAgIC8vIGlmIHRoZSB2YWx1ZSBoYXMgbm90IHlldCBiZWVuIGFwcGxpZWQgdGhlbiBhIHRydXRoeSB2YWx1ZSBkb2VzIG5vdCBleGlzdCBpbiB0aGVcbiAgICAgIC8vIHByb3AtYmFzZWQgb3IgbWFwLWJhc2VkIGJpbmRpbmdzIGNvZGUuIElmIGFuZCB3aGVuIHRoaXMgaGFwcGVucywganVzdCBhcHBseSB0aGVcbiAgICAgIC8vIGRlZmF1bHQgdmFsdWUgKGV2ZW4gaWYgdGhlIGRlZmF1bHQgdmFsdWUgaXMgYG51bGxgKS5cbiAgICAgIGlmICghdmFsdWVBcHBsaWVkKSB7XG4gICAgICAgIGFwcGx5U3R5bGluZ0ZuKHJlbmRlcmVyLCBlbGVtZW50LCBwcm9wLCBkZWZhdWx0VmFsdWUpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGkgKz0gVFN0eWxpbmdDb250ZXh0SW5kZXguQmluZGluZ3NTdGFydE9mZnNldCArIHZhbHVlc0NvdW50O1xuICB9XG5cbiAgLy8gdGhlIG1hcC1iYXNlZCBzdHlsaW5nIGVudHJpZXMgbWF5IGhhdmUgbm90IGFwcGxpZWQgYWxsIHRoZWlyXG4gIC8vIHZhbHVlcy4gRm9yIHRoaXMgcmVhc29uLCBvbmUgbW9yZSBjYWxsIHRvIHRoZSBzeW5jIGZ1bmN0aW9uXG4gIC8vIG5lZWRzIHRvIGJlIGlzc3VlZCBhdCB0aGUgZW5kLlxuICBpZiAoc3R5bGluZ01hcHNTeW5jRm4pIHtcbiAgICBzdHlsaW5nTWFwc1N5bmNGbihjb250ZXh0LCByZW5kZXJlciwgZWxlbWVudCwgYmluZGluZ0RhdGEsIGFwcGx5U3R5bGluZ0ZuLCBzYW5pdGl6ZXIsIG1hcHNNb2RlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBub3JtYWxpemVCaXRNYXNrVmFsdWUodmFsdWU6IG51bWJlciB8IGJvb2xlYW4pOiBudW1iZXIge1xuICAvLyBpZiBwYXNzID0+IGFwcGx5IGFsbCB2YWx1ZXMgKC0xIGltcGxpZXMgdGhhdCBhbGwgYml0cyBhcmUgZmxpcHBlZCB0byB0cnVlKVxuICBpZiAodmFsdWUgPT09IHRydWUpIHJldHVybiAtMTtcblxuICAvLyBpZiBwYXNzID0+IHNraXAgYWxsIHZhbHVlc1xuICBpZiAodmFsdWUgPT09IGZhbHNlKSByZXR1cm4gMDtcblxuICAvLyByZXR1cm4gdGhlIGJpdCBtYXNrIHZhbHVlIGFzIGlzXG4gIHJldHVybiB2YWx1ZTtcbn1cblxubGV0IF9hY3RpdmVTdHlsaW5nTWFwQXBwbHlGbjogU3luY1N0eWxpbmdNYXBzRm58bnVsbCA9IG51bGw7XG5leHBvcnQgZnVuY3Rpb24gZ2V0U3R5bGluZ01hcHNTeW5jRm4oKSB7XG4gIHJldHVybiBfYWN0aXZlU3R5bGluZ01hcEFwcGx5Rm47XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRTdHlsaW5nTWFwc1N5bmNGbihmbjogU3luY1N0eWxpbmdNYXBzRm4pIHtcbiAgX2FjdGl2ZVN0eWxpbmdNYXBBcHBseUZuID0gZm47XG59XG5cbi8qKlxuICogQXNzaWducyBhIHN0eWxlIHZhbHVlIHRvIGEgc3R5bGUgcHJvcGVydHkgZm9yIHRoZSBnaXZlbiBlbGVtZW50LlxuICovXG5jb25zdCBzZXRTdHlsZTogQXBwbHlTdHlsaW5nRm4gPVxuICAgIChyZW5kZXJlcjogUmVuZGVyZXIzIHwgbnVsbCwgbmF0aXZlOiBhbnksIHByb3A6IHN0cmluZywgdmFsdWU6IHN0cmluZyB8IG51bGwpID0+IHtcbiAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAvLyBvcGFjaXR5LCB6LWluZGV4IGFuZCBmbGV4Ym94IGFsbCBoYXZlIG51bWJlciB2YWx1ZXNcbiAgICAgICAgLy8gYW5kIHRoZXNlIG5lZWQgdG8gYmUgY29udmVydGVkIGludG8gc3RyaW5ncyBzbyB0aGF0XG4gICAgICAgIC8vIHRoZXkgY2FuIGJlIGFzc2lnbmVkIHByb3Blcmx5LlxuICAgICAgICB2YWx1ZSA9IHZhbHVlLnRvU3RyaW5nKCk7XG4gICAgICAgIG5nRGV2TW9kZSAmJiBuZ0Rldk1vZGUucmVuZGVyZXJTZXRTdHlsZSsrO1xuICAgICAgICByZW5kZXJlciAmJiBpc1Byb2NlZHVyYWxSZW5kZXJlcihyZW5kZXJlcikgP1xuICAgICAgICAgICAgcmVuZGVyZXIuc2V0U3R5bGUobmF0aXZlLCBwcm9wLCB2YWx1ZSwgUmVuZGVyZXJTdHlsZUZsYWdzMy5EYXNoQ2FzZSkgOlxuICAgICAgICAgICAgbmF0aXZlLnN0eWxlLnNldFByb3BlcnR5KHByb3AsIHZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5nRGV2TW9kZSAmJiBuZ0Rldk1vZGUucmVuZGVyZXJSZW1vdmVTdHlsZSsrO1xuICAgICAgICByZW5kZXJlciAmJiBpc1Byb2NlZHVyYWxSZW5kZXJlcihyZW5kZXJlcikgP1xuICAgICAgICAgICAgcmVuZGVyZXIucmVtb3ZlU3R5bGUobmF0aXZlLCBwcm9wLCBSZW5kZXJlclN0eWxlRmxhZ3MzLkRhc2hDYXNlKSA6XG4gICAgICAgICAgICBuYXRpdmUuc3R5bGUucmVtb3ZlUHJvcGVydHkocHJvcCk7XG4gICAgICB9XG4gICAgfTtcblxuLyoqXG4gKiBBZGRzL3JlbW92ZXMgdGhlIHByb3ZpZGVkIGNsYXNzTmFtZSB2YWx1ZSB0byB0aGUgcHJvdmlkZWQgZWxlbWVudC5cbiAqL1xuY29uc3Qgc2V0Q2xhc3M6IEFwcGx5U3R5bGluZ0ZuID1cbiAgICAocmVuZGVyZXI6IFJlbmRlcmVyMyB8IG51bGwsIG5hdGl2ZTogYW55LCBjbGFzc05hbWU6IHN0cmluZywgdmFsdWU6IGFueSkgPT4ge1xuICAgICAgaWYgKGNsYXNzTmFtZSAhPT0gJycpIHtcbiAgICAgICAgaWYgKHZhbHVlKSB7XG4gICAgICAgICAgbmdEZXZNb2RlICYmIG5nRGV2TW9kZS5yZW5kZXJlckFkZENsYXNzKys7XG4gICAgICAgICAgcmVuZGVyZXIgJiYgaXNQcm9jZWR1cmFsUmVuZGVyZXIocmVuZGVyZXIpID8gcmVuZGVyZXIuYWRkQ2xhc3MobmF0aXZlLCBjbGFzc05hbWUpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYXRpdmUuY2xhc3NMaXN0LmFkZChjbGFzc05hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG5nRGV2TW9kZSAmJiBuZ0Rldk1vZGUucmVuZGVyZXJSZW1vdmVDbGFzcysrO1xuICAgICAgICAgIHJlbmRlcmVyICYmIGlzUHJvY2VkdXJhbFJlbmRlcmVyKHJlbmRlcmVyKSA/IHJlbmRlcmVyLnJlbW92ZUNsYXNzKG5hdGl2ZSwgY2xhc3NOYW1lKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmF0aXZlLmNsYXNzTGlzdC5yZW1vdmUoY2xhc3NOYW1lKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG4iXX0=
|