@angular/core 17.0.0-next.8 → 17.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/src/application_init.mjs +3 -2
- package/esm2022/src/application_ref.mjs +4 -3
- package/esm2022/src/application_tokens.mjs +1 -11
- package/esm2022/src/core.mjs +2 -2
- package/esm2022/src/core_private_export.mjs +5 -4
- package/esm2022/src/core_render3_private_export.mjs +2 -2
- package/esm2022/src/debug/debug_node.mjs +5 -9
- package/esm2022/src/defer/cleanup.mjs +40 -0
- package/esm2022/src/defer/discovery.mjs +47 -0
- package/esm2022/src/defer/dom_triggers.mjs +256 -0
- package/esm2022/src/defer/idle_scheduler.mjs +112 -0
- package/esm2022/src/defer/instructions.mjs +662 -0
- package/esm2022/src/defer/interfaces.mjs +81 -0
- package/esm2022/src/defer/timer_scheduler.mjs +201 -0
- package/esm2022/src/defer/utils.mjs +122 -0
- package/esm2022/src/di/r3_injector.mjs +6 -1
- package/esm2022/src/errors.mjs +1 -1
- package/esm2022/src/hydration/api.mjs +2 -4
- package/esm2022/src/hydration/skip_hydration.mjs +7 -7
- package/esm2022/src/hydration/utils.mjs +2 -2
- package/esm2022/src/linker/view_container_ref.mjs +4 -6
- package/esm2022/src/metadata/directives.mjs +1 -1
- package/esm2022/src/render/api.mjs +1 -1
- package/esm2022/src/render3/after_render_hooks.mjs +55 -21
- package/esm2022/src/render3/debug/injector_profiler.mjs +26 -8
- package/esm2022/src/render3/index.mjs +3 -2
- package/esm2022/src/render3/instructions/all.mjs +2 -2
- package/esm2022/src/render3/instructions/change_detection.mjs +24 -3
- package/esm2022/src/render3/instructions/control_flow.mjs +25 -15
- package/esm2022/src/render3/interfaces/container.mjs +1 -4
- package/esm2022/src/render3/interfaces/definition.mjs +2 -4
- package/esm2022/src/render3/interfaces/i18n.mjs +1 -4
- package/esm2022/src/render3/interfaces/injector.mjs +1 -4
- package/esm2022/src/render3/interfaces/node.mjs +1 -4
- package/esm2022/src/render3/interfaces/projection.mjs +2 -4
- package/esm2022/src/render3/interfaces/query.mjs +2 -4
- package/esm2022/src/render3/interfaces/renderer.mjs +2 -4
- package/esm2022/src/render3/interfaces/renderer_dom.mjs +2 -4
- package/esm2022/src/render3/interfaces/view.mjs +1 -4
- package/esm2022/src/render3/list_reconciliation.mjs +58 -34
- package/esm2022/src/render3/reactive_lview_consumer.mjs +2 -7
- package/esm2022/src/render3/util/injector_discovery_utils.mjs +26 -2
- package/esm2022/src/render3/util/view_utils.mjs +1 -4
- package/esm2022/src/version.mjs +1 -1
- package/esm2022/testing/src/defer.mjs +6 -3
- package/esm2022/testing/src/logger.mjs +3 -3
- package/fesm2022/core.mjs +1015 -932
- package/fesm2022/core.mjs.map +1 -1
- package/fesm2022/primitives/signals.mjs +1 -1
- package/fesm2022/rxjs-interop.mjs +1 -1
- package/fesm2022/testing.mjs +6 -3
- package/fesm2022/testing.mjs.map +1 -1
- package/index.d.ts +54 -18
- package/package.json +1 -1
- package/primitives/signals/index.d.ts +1 -1
- package/rxjs-interop/index.d.ts +1 -1
- package/schematics/migrations/block-template-entities/bundle.js +1051 -467
- package/schematics/migrations/block-template-entities/bundle.js.map +4 -4
- package/schematics/migrations/compiler-options/bundle.js +13 -13
- package/schematics/migrations/transfer-state/bundle.js +13 -13
- package/schematics/ng-generate/control-flow-migration/bundle.js +1284 -612
- package/schematics/ng-generate/control-flow-migration/bundle.js.map +4 -4
- package/schematics/ng-generate/standalone-migration/bundle.js +1300 -708
- package/schematics/ng-generate/standalone-migration/bundle.js.map +4 -4
- package/testing/index.d.ts +1 -1
- package/esm2022/src/render3/instructions/defer.mjs +0 -1225
- package/esm2022/src/render3/instructions/defer_events.mjs +0 -174
- package/esm2022/src/render3/interfaces/defer.mjs +0 -79
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
/**
|
|
9
|
+
* Describes the state of defer block dependency loading.
|
|
10
|
+
*/
|
|
11
|
+
export var DeferDependenciesLoadingState;
|
|
12
|
+
(function (DeferDependenciesLoadingState) {
|
|
13
|
+
/** Initial state, dependency loading is not yet triggered */
|
|
14
|
+
DeferDependenciesLoadingState[DeferDependenciesLoadingState["NOT_STARTED"] = 0] = "NOT_STARTED";
|
|
15
|
+
/** Dependency loading is in progress */
|
|
16
|
+
DeferDependenciesLoadingState[DeferDependenciesLoadingState["IN_PROGRESS"] = 1] = "IN_PROGRESS";
|
|
17
|
+
/** Dependency loading has completed successfully */
|
|
18
|
+
DeferDependenciesLoadingState[DeferDependenciesLoadingState["COMPLETE"] = 2] = "COMPLETE";
|
|
19
|
+
/** Dependency loading has failed */
|
|
20
|
+
DeferDependenciesLoadingState[DeferDependenciesLoadingState["FAILED"] = 3] = "FAILED";
|
|
21
|
+
})(DeferDependenciesLoadingState || (DeferDependenciesLoadingState = {}));
|
|
22
|
+
/** Slot index where `minimum` parameter value is stored. */
|
|
23
|
+
export const MINIMUM_SLOT = 0;
|
|
24
|
+
/** Slot index where `after` parameter value is stored. */
|
|
25
|
+
export const LOADING_AFTER_SLOT = 1;
|
|
26
|
+
/**
|
|
27
|
+
* Describes the current state of this defer block instance.
|
|
28
|
+
*
|
|
29
|
+
* @publicApi
|
|
30
|
+
* @developerPreview
|
|
31
|
+
*/
|
|
32
|
+
export var DeferBlockState;
|
|
33
|
+
(function (DeferBlockState) {
|
|
34
|
+
/** The placeholder block content is rendered */
|
|
35
|
+
DeferBlockState[DeferBlockState["Placeholder"] = 0] = "Placeholder";
|
|
36
|
+
/** The loading block content is rendered */
|
|
37
|
+
DeferBlockState[DeferBlockState["Loading"] = 1] = "Loading";
|
|
38
|
+
/** The main content block content is rendered */
|
|
39
|
+
DeferBlockState[DeferBlockState["Complete"] = 2] = "Complete";
|
|
40
|
+
/** The error block content is rendered */
|
|
41
|
+
DeferBlockState[DeferBlockState["Error"] = 3] = "Error";
|
|
42
|
+
})(DeferBlockState || (DeferBlockState = {}));
|
|
43
|
+
/**
|
|
44
|
+
* Describes the initial state of this defer block instance.
|
|
45
|
+
*
|
|
46
|
+
* Note: this state is internal only and *must* be represented
|
|
47
|
+
* with a number lower than any value in the `DeferBlockState` enum.
|
|
48
|
+
*/
|
|
49
|
+
export var DeferBlockInternalState;
|
|
50
|
+
(function (DeferBlockInternalState) {
|
|
51
|
+
/** Initial state. Nothing is rendered yet. */
|
|
52
|
+
DeferBlockInternalState[DeferBlockInternalState["Initial"] = -1] = "Initial";
|
|
53
|
+
})(DeferBlockInternalState || (DeferBlockInternalState = {}));
|
|
54
|
+
export const NEXT_DEFER_BLOCK_STATE = 0;
|
|
55
|
+
// Note: it's *important* to keep the state in this slot, because this slot
|
|
56
|
+
// is used by runtime logic to differentiate between LViews, LContainers and
|
|
57
|
+
// other types (see `isLView` and `isLContainer` functions). In case of defer
|
|
58
|
+
// blocks, this slot would always be a number.
|
|
59
|
+
export const DEFER_BLOCK_STATE = 1;
|
|
60
|
+
export const STATE_IS_FROZEN_UNTIL = 2;
|
|
61
|
+
export const LOADING_AFTER_CLEANUP_FN = 3;
|
|
62
|
+
export const TRIGGER_CLEANUP_FNS = 4;
|
|
63
|
+
export const PREFETCH_TRIGGER_CLEANUP_FNS = 5;
|
|
64
|
+
/**
|
|
65
|
+
* Options for configuring defer blocks behavior.
|
|
66
|
+
* @publicApi
|
|
67
|
+
* @developerPreview
|
|
68
|
+
*/
|
|
69
|
+
export var DeferBlockBehavior;
|
|
70
|
+
(function (DeferBlockBehavior) {
|
|
71
|
+
/**
|
|
72
|
+
* Manual triggering mode for defer blocks. Provides control over when defer blocks render
|
|
73
|
+
* and which state they render. This is the default behavior in test environments.
|
|
74
|
+
*/
|
|
75
|
+
DeferBlockBehavior[DeferBlockBehavior["Manual"] = 0] = "Manual";
|
|
76
|
+
/**
|
|
77
|
+
* Playthrough mode for defer blocks. This mode behaves like defer blocks would in a browser.
|
|
78
|
+
*/
|
|
79
|
+
DeferBlockBehavior[DeferBlockBehavior["Playthrough"] = 1] = "Playthrough";
|
|
80
|
+
})(DeferBlockBehavior || (DeferBlockBehavior = {}));
|
|
81
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJmYWNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvcmUvc3JjL2RlZmVyL2ludGVyZmFjZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBeUJIOztHQUVHO0FBQ0gsTUFBTSxDQUFOLElBQVksNkJBWVg7QUFaRCxXQUFZLDZCQUE2QjtJQUN2Qyw2REFBNkQ7SUFDN0QsK0ZBQVcsQ0FBQTtJQUVYLHdDQUF3QztJQUN4QywrRkFBVyxDQUFBO0lBRVgsb0RBQW9EO0lBQ3BELHlGQUFRLENBQUE7SUFFUixvQ0FBb0M7SUFDcEMscUZBQU0sQ0FBQTtBQUNSLENBQUMsRUFaVyw2QkFBNkIsS0FBN0IsNkJBQTZCLFFBWXhDO0FBRUQsNERBQTREO0FBQzVELE1BQU0sQ0FBQyxNQUFNLFlBQVksR0FBRyxDQUFDLENBQUM7QUFFOUIsMERBQTBEO0FBQzFELE1BQU0sQ0FBQyxNQUFNLGtCQUFrQixHQUFHLENBQUMsQ0FBQztBQTZEcEM7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQU4sSUFBWSxlQVlYO0FBWkQsV0FBWSxlQUFlO0lBQ3pCLGdEQUFnRDtJQUNoRCxtRUFBZSxDQUFBO0lBRWYsNENBQTRDO0lBQzVDLDJEQUFXLENBQUE7SUFFWCxpREFBaUQ7SUFDakQsNkRBQVksQ0FBQTtJQUVaLDBDQUEwQztJQUMxQyx1REFBUyxDQUFBO0FBQ1gsQ0FBQyxFQVpXLGVBQWUsS0FBZixlQUFlLFFBWTFCO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQU4sSUFBWSx1QkFHWDtBQUhELFdBQVksdUJBQXVCO0lBQ2pDLDhDQUE4QztJQUM5Qyw0RUFBWSxDQUFBO0FBQ2QsQ0FBQyxFQUhXLHVCQUF1QixLQUF2Qix1QkFBdUIsUUFHbEM7QUFFRCxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDLENBQUM7QUFDeEMsMkVBQTJFO0FBQzNFLDRFQUE0RTtBQUM1RSw2RUFBNkU7QUFDN0UsOENBQThDO0FBQzlDLE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLENBQUMsQ0FBQztBQUNuQyxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxDQUFDLENBQUM7QUFDdkMsTUFBTSxDQUFDLE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxDQUFDO0FBQzFDLE1BQU0sQ0FBQyxNQUFNLG1CQUFtQixHQUFHLENBQUMsQ0FBQztBQUNyQyxNQUFNLENBQUMsTUFBTSw0QkFBNEIsR0FBRyxDQUFDLENBQUM7QUFtRDlDOzs7O0dBSUc7QUFDSCxNQUFNLENBQU4sSUFBWSxrQkFXWDtBQVhELFdBQVksa0JBQWtCO0lBQzVCOzs7T0FHRztJQUNILCtEQUFNLENBQUE7SUFFTjs7T0FFRztJQUNILHlFQUFXLENBQUE7QUFDYixDQUFDLEVBWFcsa0JBQWtCLEtBQWxCLGtCQUFrQixRQVc3QiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQgdHlwZSB7RGVwZW5kZW5jeVR5cGV9IGZyb20gJy4uL3JlbmRlcjMvaW50ZXJmYWNlcy9kZWZpbml0aW9uJztcblxuLyoqXG4gKiBEZXNjcmliZXMgdGhlIHNoYXBlIG9mIGEgZnVuY3Rpb24gZ2VuZXJhdGVkIGJ5IHRoZSBjb21waWxlclxuICogdG8gZG93bmxvYWQgZGVwZW5kZW5jaWVzIHRoYXQgY2FuIGJlIGRlZmVyLWxvYWRlZC5cbiAqL1xuZXhwb3J0IHR5cGUgRGVwZW5kZW5jeVJlc29sdmVyRm4gPSAoKSA9PiBBcnJheTxQcm9taXNlPERlcGVuZGVuY3lUeXBlPj47XG5cbi8qKlxuICogRGVmaW5lcyB0eXBlcyBvZiBkZWZlciBibG9jayB0cmlnZ2Vycy5cbiAqL1xuZXhwb3J0IGNvbnN0IGVudW0gVHJpZ2dlclR5cGUge1xuICAvKipcbiAgICogUmVwcmVzZW50cyByZWd1bGFyIHRyaWdnZXJzIChlLmcuIGBAZGVmZXIgKG9uIGlkbGUpIHsgLi4uIH1gKS5cbiAgICovXG4gIFJlZ3VsYXIsXG5cbiAgLyoqXG4gICAqIFJlcHJlc2VudHMgcHJlZmV0Y2ggdHJpZ2dlcnMgKGUuZy4gYEBkZWZlciAocHJlZmV0Y2ggb24gaWRsZSkgeyAuLi4gfWApLlxuICAgKi9cbiAgUHJlZmV0Y2gsXG59XG5cbi8qKlxuICogRGVzY3JpYmVzIHRoZSBzdGF0ZSBvZiBkZWZlciBibG9jayBkZXBlbmRlbmN5IGxvYWRpbmcuXG4gKi9cbmV4cG9ydCBlbnVtIERlZmVyRGVwZW5kZW5jaWVzTG9hZGluZ1N0YXRlIHtcbiAgLyoqIEluaXRpYWwgc3RhdGUsIGRlcGVuZGVuY3kgbG9hZGluZyBpcyBub3QgeWV0IHRyaWdnZXJlZCAqL1xuICBOT1RfU1RBUlRFRCxcblxuICAvKiogRGVwZW5kZW5jeSBsb2FkaW5nIGlzIGluIHByb2dyZXNzICovXG4gIElOX1BST0dSRVNTLFxuXG4gIC8qKiBEZXBlbmRlbmN5IGxvYWRpbmcgaGFzIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHkgKi9cbiAgQ09NUExFVEUsXG5cbiAgLyoqIERlcGVuZGVuY3kgbG9hZGluZyBoYXMgZmFpbGVkICovXG4gIEZBSUxFRCxcbn1cblxuLyoqIFNsb3QgaW5kZXggd2hlcmUgYG1pbmltdW1gIHBhcmFtZXRlciB2YWx1ZSBpcyBzdG9yZWQuICovXG5leHBvcnQgY29uc3QgTUlOSU1VTV9TTE9UID0gMDtcblxuLyoqIFNsb3QgaW5kZXggd2hlcmUgYGFmdGVyYCBwYXJhbWV0ZXIgdmFsdWUgaXMgc3RvcmVkLiAqL1xuZXhwb3J0IGNvbnN0IExPQURJTkdfQUZURVJfU0xPVCA9IDE7XG5cbi8qKiBDb25maWd1cmF0aW9uIG9iamVjdCBmb3IgYSBsb2FkaW5nIGJsb2NrIGFzIGl0IGlzIHN0b3JlZCBpbiB0aGUgY29tcG9uZW50IGNvbnN0YW50cy4gKi9cbmV4cG9ydCB0eXBlIERlZmVycmVkTG9hZGluZ0Jsb2NrQ29uZmlnID0gW21pbmltdW1UaW1lOiBudW1iZXJ8bnVsbCwgYWZ0ZXJUaW1lOiBudW1iZXJ8bnVsbF07XG5cbi8qKiBDb25maWd1cmF0aW9uIG9iamVjdCBmb3IgYSBwbGFjZWhvbGRlciBibG9jayBhcyBpdCBpcyBzdG9yZWQgaW4gdGhlIGNvbXBvbmVudCBjb25zdGFudHMuICovXG5leHBvcnQgdHlwZSBEZWZlcnJlZFBsYWNlaG9sZGVyQmxvY2tDb25maWcgPSBbbWluaW11bVRpbWU6IG51bWJlcnxudWxsXTtcblxuLyoqXG4gKiBEZXNjcmliZXMgdGhlIGRhdGEgc2hhcmVkIGFjcm9zcyBhbGwgaW5zdGFuY2VzIG9mIGEgZGVmZXIgYmxvY2suXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVERlZmVyQmxvY2tEZXRhaWxzIHtcbiAgLyoqXG4gICAqIEluZGV4IGluIGFuIExWaWV3IGFuZCBURGF0YSBhcnJheXMgd2hlcmUgYSB0ZW1wbGF0ZSBmb3IgdGhlIHByaW1hcnkgY29udGVudFxuICAgKiBjYW4gYmUgZm91bmQuXG4gICAqL1xuICBwcmltYXJ5VG1wbEluZGV4OiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEluZGV4IGluIGFuIExWaWV3IGFuZCBURGF0YSBhcnJheXMgd2hlcmUgYSB0ZW1wbGF0ZSBmb3IgdGhlIGxvYWRpbmcgYmxvY2sgY2FuIGJlIGZvdW5kLlxuICAgKi9cbiAgbG9hZGluZ1RtcGxJbmRleDogbnVtYmVyfG51bGw7XG5cbiAgLyoqXG4gICAqIEV4dHJhIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVycyAoc3VjaCBhcyBgYWZ0ZXJgIGFuZCBgbWluaW11bWApIGZvciB0aGUgbG9hZGluZyBibG9jay5cbiAgICovXG4gIGxvYWRpbmdCbG9ja0NvbmZpZzogRGVmZXJyZWRMb2FkaW5nQmxvY2tDb25maWd8bnVsbDtcblxuICAvKipcbiAgICogSW5kZXggaW4gYW4gTFZpZXcgYW5kIFREYXRhIGFycmF5cyB3aGVyZSBhIHRlbXBsYXRlIGZvciB0aGUgcGxhY2Vob2xkZXIgYmxvY2sgY2FuIGJlIGZvdW5kLlxuICAgKi9cbiAgcGxhY2Vob2xkZXJUbXBsSW5kZXg6IG51bWJlcnxudWxsO1xuXG4gIC8qKlxuICAgKiBFeHRyYSBjb25maWd1cmF0aW9uIHBhcmFtZXRlcnMgKHN1Y2ggYXMgYGFmdGVyYCBhbmQgYG1pbmltdW1gKSBmb3IgdGhlIHBsYWNlaG9sZGVyIGJsb2NrLlxuICAgKi9cbiAgcGxhY2Vob2xkZXJCbG9ja0NvbmZpZzogRGVmZXJyZWRQbGFjZWhvbGRlckJsb2NrQ29uZmlnfG51bGw7XG5cbiAgLyoqXG4gICAqIEluZGV4IGluIGFuIExWaWV3IGFuZCBURGF0YSBhcnJheXMgd2hlcmUgYSB0ZW1wbGF0ZSBmb3IgdGhlIGVycm9yIGJsb2NrIGNhbiBiZSBmb3VuZC5cbiAgICovXG4gIGVycm9yVG1wbEluZGV4OiBudW1iZXJ8bnVsbDtcblxuICAvKipcbiAgICogQ29tcGlsZXItZ2VuZXJhdGVkIGZ1bmN0aW9uIHRoYXQgbG9hZHMgYWxsIGRlcGVuZGVuY2llcyBmb3IgYSBkZWZlciBibG9jay5cbiAgICovXG4gIGRlcGVuZGVuY3lSZXNvbHZlckZuOiBEZXBlbmRlbmN5UmVzb2x2ZXJGbnxudWxsO1xuXG4gIC8qKlxuICAgKiBLZWVwcyB0cmFjayBvZiB0aGUgY3VycmVudCBsb2FkaW5nIHN0YXRlIG9mIGRlZmVyIGJsb2NrIGRlcGVuZGVuY2llcy5cbiAgICovXG4gIGxvYWRpbmdTdGF0ZTogRGVmZXJEZXBlbmRlbmNpZXNMb2FkaW5nU3RhdGU7XG5cbiAgLyoqXG4gICAqIERlcGVuZGVuY3kgbG9hZGluZyBQcm9taXNlLiBUaGlzIFByb21pc2UgaXMgaGVscGZ1bCBmb3IgY2FzZXMgd2hlbiB0aGVyZVxuICAgKiBhcmUgbXVsdGlwbGUgaW5zdGFuY2VzIG9mIGEgZGVmZXIgYmxvY2sgKGUuZy4gaWYgaXQgd2FzIHVzZWQgaW5zaWRlIG9mIGFuICpuZ0ZvciksXG4gICAqIHdoaWNoIGFsbCBhd2FpdCB0aGUgc2FtZSBzZXQgb2YgZGVwZW5kZW5jaWVzLlxuICAgKi9cbiAgbG9hZGluZ1Byb21pc2U6IFByb21pc2U8dW5rbm93bj58bnVsbDtcbn1cblxuLyoqXG4gKiBEZXNjcmliZXMgdGhlIGN1cnJlbnQgc3RhdGUgb2YgdGhpcyBkZWZlciBibG9jayBpbnN0YW5jZS5cbiAqXG4gKiBAcHVibGljQXBpXG4gKiBAZGV2ZWxvcGVyUHJldmlld1xuICovXG5leHBvcnQgZW51bSBEZWZlckJsb2NrU3RhdGUge1xuICAvKiogVGhlIHBsYWNlaG9sZGVyIGJsb2NrIGNvbnRlbnQgaXMgcmVuZGVyZWQgKi9cbiAgUGxhY2Vob2xkZXIgPSAwLFxuXG4gIC8qKiBUaGUgbG9hZGluZyBibG9jayBjb250ZW50IGlzIHJlbmRlcmVkICovXG4gIExvYWRpbmcgPSAxLFxuXG4gIC8qKiBUaGUgbWFpbiBjb250ZW50IGJsb2NrIGNvbnRlbnQgaXMgcmVuZGVyZWQgKi9cbiAgQ29tcGxldGUgPSAyLFxuXG4gIC8qKiBUaGUgZXJyb3IgYmxvY2sgY29udGVudCBpcyByZW5kZXJlZCAqL1xuICBFcnJvciA9IDMsXG59XG5cbi8qKlxuICogRGVzY3JpYmVzIHRoZSBpbml0aWFsIHN0YXRlIG9mIHRoaXMgZGVmZXIgYmxvY2sgaW5zdGFuY2UuXG4gKlxuICogTm90ZTogdGhpcyBzdGF0ZSBpcyBpbnRlcm5hbCBvbmx5IGFuZCAqbXVzdCogYmUgcmVwcmVzZW50ZWRcbiAqIHdpdGggYSBudW1iZXIgbG93ZXIgdGhhbiBhbnkgdmFsdWUgaW4gdGhlIGBEZWZlckJsb2NrU3RhdGVgIGVudW0uXG4gKi9cbmV4cG9ydCBlbnVtIERlZmVyQmxvY2tJbnRlcm5hbFN0YXRlIHtcbiAgLyoqIEluaXRpYWwgc3RhdGUuIE5vdGhpbmcgaXMgcmVuZGVyZWQgeWV0LiAqL1xuICBJbml0aWFsID0gLTEsXG59XG5cbmV4cG9ydCBjb25zdCBORVhUX0RFRkVSX0JMT0NLX1NUQVRFID0gMDtcbi8vIE5vdGU6IGl0J3MgKmltcG9ydGFudCogdG8ga2VlcCB0aGUgc3RhdGUgaW4gdGhpcyBzbG90LCBiZWNhdXNlIHRoaXMgc2xvdFxuLy8gaXMgdXNlZCBieSBydW50aW1lIGxvZ2ljIHRvIGRpZmZlcmVudGlhdGUgYmV0d2VlbiBMVmlld3MsIExDb250YWluZXJzIGFuZFxuLy8gb3RoZXIgdHlwZXMgKHNlZSBgaXNMVmlld2AgYW5kIGBpc0xDb250YWluZXJgIGZ1bmN0aW9ucykuIEluIGNhc2Ugb2YgZGVmZXJcbi8vIGJsb2NrcywgdGhpcyBzbG90IHdvdWxkIGFsd2F5cyBiZSBhIG51bWJlci5cbmV4cG9ydCBjb25zdCBERUZFUl9CTE9DS19TVEFURSA9IDE7XG5leHBvcnQgY29uc3QgU1RBVEVfSVNfRlJPWkVOX1VOVElMID0gMjtcbmV4cG9ydCBjb25zdCBMT0FESU5HX0FGVEVSX0NMRUFOVVBfRk4gPSAzO1xuZXhwb3J0IGNvbnN0IFRSSUdHRVJfQ0xFQU5VUF9GTlMgPSA0O1xuZXhwb3J0IGNvbnN0IFBSRUZFVENIX1RSSUdHRVJfQ0xFQU5VUF9GTlMgPSA1O1xuXG4vKipcbiAqIERlc2NyaWJlcyBpbnN0YW5jZS1zcGVjaWZpYyBkZWZlciBibG9jayBkYXRhLlxuICpcbiAqIE5vdGU6IGN1cnJlbnRseSB0aGVyZSBpcyBvbmx5IHRoZSBgc3RhdGVgIHNsb3QsIGJ1dCBtb3JlIHNsb3RzXG4gKiB3b3VsZCBiZSBhZGRlZCBsYXRlciB0byBrZWVwIHRyYWNrIG9mIGBhZnRlcmAgYW5kIGBtYXhpbXVtYCBmZWF0dXJlc1xuICogKHdoaWNoIHdvdWxkIHJlcXVpcmUgcGVyLWluc3RhbmNlIHN0YXRlKS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBMRGVmZXJCbG9ja0RldGFpbHMgZXh0ZW5kcyBBcnJheTx1bmtub3duPiB7XG4gIC8qKlxuICAgKiBDdXJyZW50bHkgcmVuZGVyZWQgYmxvY2sgc3RhdGUuXG4gICAqL1xuICBbREVGRVJfQkxPQ0tfU1RBVEVdOiBEZWZlckJsb2NrU3RhdGV8RGVmZXJCbG9ja0ludGVybmFsU3RhdGU7XG5cbiAgLyoqXG4gICAqIEJsb2NrIHN0YXRlIHRoYXQgd2FzIHJlcXVlc3RlZCB3aGVuIGFub3RoZXIgc3RhdGUgd2FzIHJlbmRlcmVkLlxuICAgKi9cbiAgW05FWFRfREVGRVJfQkxPQ0tfU1RBVEVdOiBEZWZlckJsb2NrU3RhdGV8bnVsbDtcblxuICAvKipcbiAgICogVGltZXN0YW1wIGluZGljYXRpbmcgd2hlbiB0aGUgY3VycmVudCBzdGF0ZSBjYW4gYmUgc3dpdGNoZWQgdG9cbiAgICogdGhlIG5leHQgb25lLCBpbiBjYXNlIHRlaCBjdXJyZW50IHN0YXRlIGhhcyBgbWluaW11bWAgcGFyYW1ldGVyLlxuICAgKi9cbiAgW1NUQVRFX0lTX0ZST1pFTl9VTlRJTF06IG51bWJlcnxudWxsO1xuXG4gIC8qKlxuICAgKiBDb250YWlucyBhIHJlZmVyZW5jZSB0byBhIGNsZWFudXAgZnVuY3Rpb24gd2hpY2ggY2FuY2VscyBhIHRpbWVvdXRcbiAgICogd2hlbiBBbmd1bGFyIHdhaXRzIGJlZm9yZSByZW5kZXJpbmcgbG9hZGluZyBzdGF0ZS4gVGhpcyBpcyB1c2VkIHdoZW5cbiAgICogdGhlIGxvYWRpbmcgYmxvY2sgaGFzIHRoZSBgYWZ0ZXJgIHBhcmFtZXRlciBjb25maWd1cmVkLlxuICAgKi9cbiAgW0xPQURJTkdfQUZURVJfQ0xFQU5VUF9GTl06IFZvaWRGdW5jdGlvbnxudWxsO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIGNsZWFudXAgZnVuY3Rpb25zIGZvciByZWd1bGFyIHRyaWdnZXJzLlxuICAgKi9cbiAgW1RSSUdHRVJfQ0xFQU5VUF9GTlNdOiBWb2lkRnVuY3Rpb25bXXxudWxsO1xuXG4gIC8qKlxuICAgKiBMaXN0IG9mIGNsZWFudXAgZnVuY3Rpb25zIGZvciBwcmVmZXRjaCB0cmlnZ2Vycy5cbiAgICovXG4gIFtQUkVGRVRDSF9UUklHR0VSX0NMRUFOVVBfRk5TXTogVm9pZEZ1bmN0aW9uW118bnVsbDtcbn1cblxuLyoqXG4gKiBJbnRlcm5hbCBzdHJ1Y3R1cmUgdXNlZCBmb3IgY29uZmlndXJhdGlvbiBvZiBkZWZlciBibG9jayBiZWhhdmlvci5cbiAqICovXG5leHBvcnQgaW50ZXJmYWNlIERlZmVyQmxvY2tDb25maWcge1xuICBiZWhhdmlvcjogRGVmZXJCbG9ja0JlaGF2aW9yO1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIGNvbmZpZ3VyaW5nIGRlZmVyIGJsb2NrcyBiZWhhdmlvci5cbiAqIEBwdWJsaWNBcGlcbiAqIEBkZXZlbG9wZXJQcmV2aWV3XG4gKi9cbmV4cG9ydCBlbnVtIERlZmVyQmxvY2tCZWhhdmlvciB7XG4gIC8qKlxuICAgKiBNYW51YWwgdHJpZ2dlcmluZyBtb2RlIGZvciBkZWZlciBibG9ja3MuIFByb3ZpZGVzIGNvbnRyb2wgb3ZlciB3aGVuIGRlZmVyIGJsb2NrcyByZW5kZXJcbiAgICogYW5kIHdoaWNoIHN0YXRlIHRoZXkgcmVuZGVyLiBUaGlzIGlzIHRoZSBkZWZhdWx0IGJlaGF2aW9yIGluIHRlc3QgZW52aXJvbm1lbnRzLlxuICAgKi9cbiAgTWFudWFsLFxuXG4gIC8qKlxuICAgKiBQbGF5dGhyb3VnaCBtb2RlIGZvciBkZWZlciBibG9ja3MuIFRoaXMgbW9kZSBiZWhhdmVzIGxpa2UgZGVmZXIgYmxvY2tzIHdvdWxkIGluIGEgYnJvd3Nlci5cbiAgICovXG4gIFBsYXl0aHJvdWdoLFxufVxuXG4vKipcbiAqICoqSU5URVJOQUwqKiwgYXZvaWQgcmVmZXJlbmNpbmcgaXQgaW4gYXBwbGljYXRpb24gY29kZS5cbiAqXG4gKiBEZXNjcmliZXMgYSBoZWxwZXIgY2xhc3MgdGhhdCBhbGxvd3MgdG8gaW50ZXJjZXB0IGEgY2FsbCB0byByZXRyaWV2ZSBjdXJyZW50XG4gKiBkZXBlbmRlbmN5IGxvYWRpbmcgZnVuY3Rpb24gYW5kIHJlcGxhY2UgaXQgd2l0aCBhIGRpZmZlcmVudCBpbXBsZW1lbnRhdGlvbi5cbiAqIFRoaXMgaW50ZXJjZXB0b3IgY2xhc3MgaXMgbmVlZGVkIHRvIGFsbG93IHRlc3RpbmcgYmxvY2tzIGluIGRpZmZlcmVudCBzdGF0ZXNcbiAqIGJ5IHNpbXVsYXRpbmcgbG9hZGluZyByZXNwb25zZS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZWZlckJsb2NrRGVwZW5kZW5jeUludGVyY2VwdG9yIHtcbiAgLyoqXG4gICAqIEludm9rZWQgZm9yIGVhY2ggZGVmZXIgYmxvY2sgd2hlbiBkZXBlbmRlbmN5IGxvYWRpbmcgZnVuY3Rpb24gaXMgYWNjZXNzZWQuXG4gICAqL1xuICBpbnRlcmNlcHQoZGVwZW5kZW5jeUZuOiBEZXBlbmRlbmN5UmVzb2x2ZXJGbnxudWxsKTogRGVwZW5kZW5jeVJlc29sdmVyRm58bnVsbDtcblxuICAvKipcbiAgICogQWxsb3dzIHRvIGNvbmZpZ3VyZSBhbiBpbnRlcmNlcHRvciBmdW5jdGlvbi5cbiAgICovXG4gIHNldEludGVyY2VwdG9yKGludGVyY2VwdG9yRm46IChjdXJyZW50OiBEZXBlbmRlbmN5UmVzb2x2ZXJGbikgPT4gRGVwZW5kZW5jeVJlc29sdmVyRm4pOiB2b2lkO1xufVxuIl19
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import { ɵɵdefineInjectable } from '../di';
|
|
9
|
+
import { INJECTOR } from '../render3/interfaces/view';
|
|
10
|
+
import { arrayInsert2, arraySplice } from '../util/array_utils';
|
|
11
|
+
/**
|
|
12
|
+
* Returns a function that captures a provided delay.
|
|
13
|
+
* Invoking the returned function schedules a trigger.
|
|
14
|
+
*/
|
|
15
|
+
export function onTimer(delay) {
|
|
16
|
+
return (callback, lView) => scheduleTimerTrigger(delay, callback, lView);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Schedules a callback to be invoked after a given timeout.
|
|
20
|
+
*
|
|
21
|
+
* @param delay A number of ms to wait until firing a callback.
|
|
22
|
+
* @param callback A function to be invoked after a timeout.
|
|
23
|
+
* @param lView LView that hosts an instance of a defer block.
|
|
24
|
+
*/
|
|
25
|
+
export function scheduleTimerTrigger(delay, callback, lView) {
|
|
26
|
+
const injector = lView[INJECTOR];
|
|
27
|
+
const scheduler = injector.get(TimerScheduler);
|
|
28
|
+
const cleanupFn = () => scheduler.remove(callback);
|
|
29
|
+
scheduler.add(delay, callback);
|
|
30
|
+
return cleanupFn;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Helper service to schedule `setTimeout`s for batches of defer blocks,
|
|
34
|
+
* to avoid calling `setTimeout` for each defer block (e.g. if defer blocks
|
|
35
|
+
* are created inside a for loop).
|
|
36
|
+
*/
|
|
37
|
+
export class TimerScheduler {
|
|
38
|
+
constructor() {
|
|
39
|
+
// Indicates whether current callbacks are being invoked.
|
|
40
|
+
this.executingCallbacks = false;
|
|
41
|
+
// Currently scheduled `setTimeout` id.
|
|
42
|
+
this.timeoutId = null;
|
|
43
|
+
// When currently scheduled timer would fire.
|
|
44
|
+
this.invokeTimerAt = null;
|
|
45
|
+
// List of callbacks to be invoked.
|
|
46
|
+
// For each callback we also store a timestamp on when the callback
|
|
47
|
+
// should be invoked. We store timestamps and callback functions
|
|
48
|
+
// in a flat array to avoid creating new objects for each entry.
|
|
49
|
+
// [timestamp1, callback1, timestamp2, callback2, ...]
|
|
50
|
+
this.current = [];
|
|
51
|
+
// List of callbacks collected while invoking current set of callbacks.
|
|
52
|
+
// Those callbacks are added to the "current" queue at the end of
|
|
53
|
+
// the current callback invocation. The shape of this list is the same
|
|
54
|
+
// as the shape of the `current` list.
|
|
55
|
+
this.deferred = [];
|
|
56
|
+
}
|
|
57
|
+
add(delay, callback) {
|
|
58
|
+
const target = this.executingCallbacks ? this.deferred : this.current;
|
|
59
|
+
this.addToQueue(target, Date.now() + delay, callback);
|
|
60
|
+
this.scheduleTimer();
|
|
61
|
+
}
|
|
62
|
+
remove(callback) {
|
|
63
|
+
const { current, deferred } = this;
|
|
64
|
+
const callbackIndex = this.removeFromQueue(current, callback);
|
|
65
|
+
if (callbackIndex === -1) {
|
|
66
|
+
// Try cleaning up deferred queue only in case
|
|
67
|
+
// we didn't find a callback in the "current" queue.
|
|
68
|
+
this.removeFromQueue(deferred, callback);
|
|
69
|
+
}
|
|
70
|
+
// If the last callback was removed and there is a pending timeout - cancel it.
|
|
71
|
+
if (current.length === 0 && deferred.length === 0) {
|
|
72
|
+
this.clearTimeout();
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
addToQueue(target, invokeAt, callback) {
|
|
76
|
+
let insertAtIndex = target.length;
|
|
77
|
+
for (let i = 0; i < target.length; i += 2) {
|
|
78
|
+
const invokeQueuedCallbackAt = target[i];
|
|
79
|
+
if (invokeQueuedCallbackAt > invokeAt) {
|
|
80
|
+
// We've reached a first timer that is scheduled
|
|
81
|
+
// for a later time than what we are trying to insert.
|
|
82
|
+
// This is the location at which we need to insert,
|
|
83
|
+
// no need to iterate further.
|
|
84
|
+
insertAtIndex = i;
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
arrayInsert2(target, insertAtIndex, invokeAt, callback);
|
|
89
|
+
}
|
|
90
|
+
removeFromQueue(target, callback) {
|
|
91
|
+
let index = -1;
|
|
92
|
+
for (let i = 0; i < target.length; i += 2) {
|
|
93
|
+
const queuedCallback = target[i + 1];
|
|
94
|
+
if (queuedCallback === callback) {
|
|
95
|
+
index = i;
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (index > -1) {
|
|
100
|
+
// Remove 2 elements: a timestamp slot and
|
|
101
|
+
// the following slot with a callback function.
|
|
102
|
+
arraySplice(target, index, 2);
|
|
103
|
+
}
|
|
104
|
+
return index;
|
|
105
|
+
}
|
|
106
|
+
scheduleTimer() {
|
|
107
|
+
const callback = () => {
|
|
108
|
+
this.clearTimeout();
|
|
109
|
+
this.executingCallbacks = true;
|
|
110
|
+
// Clone the current state of the queue, since it might be altered
|
|
111
|
+
// as we invoke callbacks.
|
|
112
|
+
const current = [...this.current];
|
|
113
|
+
// Invoke callbacks that were scheduled to run before the current time.
|
|
114
|
+
const now = Date.now();
|
|
115
|
+
for (let i = 0; i < current.length; i += 2) {
|
|
116
|
+
const invokeAt = current[i];
|
|
117
|
+
const callback = current[i + 1];
|
|
118
|
+
if (invokeAt <= now) {
|
|
119
|
+
callback();
|
|
120
|
+
}
|
|
121
|
+
else {
|
|
122
|
+
// We've reached a timer that should not be invoked yet.
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// The state of the queue might've changed after callbacks invocation,
|
|
127
|
+
// run the cleanup logic based on the *current* state of the queue.
|
|
128
|
+
let lastCallbackIndex = -1;
|
|
129
|
+
for (let i = 0; i < this.current.length; i += 2) {
|
|
130
|
+
const invokeAt = this.current[i];
|
|
131
|
+
if (invokeAt <= now) {
|
|
132
|
+
// Add +1 to account for a callback function that
|
|
133
|
+
// goes after the timestamp in events array.
|
|
134
|
+
lastCallbackIndex = i + 1;
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
// We've reached a timer that should not be invoked yet.
|
|
138
|
+
break;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
if (lastCallbackIndex >= 0) {
|
|
142
|
+
arraySplice(this.current, 0, lastCallbackIndex + 1);
|
|
143
|
+
}
|
|
144
|
+
this.executingCallbacks = false;
|
|
145
|
+
// If there are any callbacks added during an invocation
|
|
146
|
+
// of the current ones - move them over to the "current"
|
|
147
|
+
// queue.
|
|
148
|
+
if (this.deferred.length > 0) {
|
|
149
|
+
for (let i = 0; i < this.deferred.length; i += 2) {
|
|
150
|
+
const invokeAt = this.deferred[i];
|
|
151
|
+
const callback = this.deferred[i + 1];
|
|
152
|
+
this.addToQueue(this.current, invokeAt, callback);
|
|
153
|
+
}
|
|
154
|
+
this.deferred.length = 0;
|
|
155
|
+
}
|
|
156
|
+
this.scheduleTimer();
|
|
157
|
+
};
|
|
158
|
+
// Avoid running timer callbacks more than once per
|
|
159
|
+
// average frame duration. This is needed for better
|
|
160
|
+
// batching and to avoid kicking off excessive change
|
|
161
|
+
// detection cycles.
|
|
162
|
+
const FRAME_DURATION_MS = 16; // 1000ms / 60fps
|
|
163
|
+
if (this.current.length > 0) {
|
|
164
|
+
const now = Date.now();
|
|
165
|
+
// First element in the queue points at the timestamp
|
|
166
|
+
// of the first (earliest) event.
|
|
167
|
+
const invokeAt = this.current[0];
|
|
168
|
+
if (this.timeoutId === null ||
|
|
169
|
+
// Reschedule a timer in case a queue contains an item with
|
|
170
|
+
// an earlier timestamp and the delta is more than an average
|
|
171
|
+
// frame duration.
|
|
172
|
+
(this.invokeTimerAt && (this.invokeTimerAt - invokeAt > FRAME_DURATION_MS))) {
|
|
173
|
+
// There was a timeout already, but an earlier event was added
|
|
174
|
+
// into the queue. In this case we drop an old timer and setup
|
|
175
|
+
// a new one with an updated (smaller) timeout.
|
|
176
|
+
this.clearTimeout();
|
|
177
|
+
const timeout = Math.max(invokeAt - now, FRAME_DURATION_MS);
|
|
178
|
+
this.invokeTimerAt = invokeAt;
|
|
179
|
+
this.timeoutId = setTimeout(callback, timeout);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
clearTimeout() {
|
|
184
|
+
if (this.timeoutId !== null) {
|
|
185
|
+
clearTimeout(this.timeoutId);
|
|
186
|
+
this.timeoutId = null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
ngOnDestroy() {
|
|
190
|
+
this.clearTimeout();
|
|
191
|
+
this.current.length = 0;
|
|
192
|
+
this.deferred.length = 0;
|
|
193
|
+
}
|
|
194
|
+
/** @nocollapse */
|
|
195
|
+
static { this.ɵprov = ɵɵdefineInjectable({
|
|
196
|
+
token: TimerScheduler,
|
|
197
|
+
providedIn: 'root',
|
|
198
|
+
factory: () => new TimerScheduler(),
|
|
199
|
+
}); }
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZXJfc2NoZWR1bGVyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29yZS9zcmMvZGVmZXIvdGltZXJfc2NoZWR1bGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRztBQUVILE9BQU8sRUFBQyxrQkFBa0IsRUFBQyxNQUFNLE9BQU8sQ0FBQztBQUN6QyxPQUFPLEVBQUMsUUFBUSxFQUFRLE1BQU0sNEJBQTRCLENBQUM7QUFDM0QsT0FBTyxFQUFDLFlBQVksRUFBRSxXQUFXLEVBQUMsTUFBTSxxQkFBcUIsQ0FBQztBQUU5RDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsT0FBTyxDQUFDLEtBQWE7SUFDbkMsT0FBTyxDQUFDLFFBQXNCLEVBQUUsS0FBWSxFQUFFLEVBQUUsQ0FBQyxvQkFBb0IsQ0FBQyxLQUFLLEVBQUUsUUFBUSxFQUFFLEtBQUssQ0FBQyxDQUFDO0FBQ2hHLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsb0JBQW9CLENBQUMsS0FBYSxFQUFFLFFBQXNCLEVBQUUsS0FBWTtJQUN0RixNQUFNLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFFLENBQUM7SUFDbEMsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQztJQUMvQyxNQUFNLFNBQVMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ25ELFNBQVMsQ0FBQyxHQUFHLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQy9CLE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLGNBQWM7SUFBM0I7UUFDRSx5REFBeUQ7UUFDekQsdUJBQWtCLEdBQUcsS0FBSyxDQUFDO1FBRTNCLHVDQUF1QztRQUN2QyxjQUFTLEdBQWdCLElBQUksQ0FB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aWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge8m1ybVkZWZpbmVJbmplY3RhYmxlfSBmcm9tICcuLi9kaSc7XG5pbXBvcnQge0lOSkVDVE9SLCBMVmlld30gZnJvbSAnLi4vcmVuZGVyMy9pbnRlcmZhY2VzL3ZpZXcnO1xuaW1wb3J0IHthcnJheUluc2VydDIsIGFycmF5U3BsaWNlfSBmcm9tICcuLi91dGlsL2FycmF5X3V0aWxzJztcblxuLyoqXG4gKiBSZXR1cm5zIGEgZnVuY3Rpb24gdGhhdCBjYXB0dXJlcyBhIHByb3ZpZGVkIGRlbGF5LlxuICogSW52b2tpbmcgdGhlIHJldHVybmVkIGZ1bmN0aW9uIHNjaGVkdWxlcyBhIHRyaWdnZXIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvblRpbWVyKGRlbGF5OiBudW1iZXIpIHtcbiAgcmV0dXJuIChjYWxsYmFjazogVm9pZEZ1bmN0aW9uLCBsVmlldzogTFZpZXcpID0+IHNjaGVkdWxlVGltZXJUcmlnZ2VyKGRlbGF5LCBjYWxsYmFjaywgbFZpZXcpO1xufVxuXG4vKipcbiAqIFNjaGVkdWxlcyBhIGNhbGxiYWNrIHRvIGJlIGludm9rZWQgYWZ0ZXIgYSBnaXZlbiB0aW1lb3V0LlxuICpcbiAqIEBwYXJhbSBkZWxheSBBIG51bWJlciBvZiBtcyB0byB3YWl0IHVudGlsIGZpcmluZyBhIGNhbGxiYWNrLlxuICogQHBhcmFtIGNhbGxiYWNrIEEgZnVuY3Rpb24gdG8gYmUgaW52b2tlZCBhZnRlciBhIHRpbWVvdXQuXG4gKiBAcGFyYW0gbFZpZXcgTFZpZXcgdGhhdCBob3N0cyBhbiBpbnN0YW5jZSBvZiBhIGRlZmVyIGJsb2NrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2NoZWR1bGVUaW1lclRyaWdnZXIoZGVsYXk6IG51bWJlciwgY2FsbGJhY2s6IFZvaWRGdW5jdGlvbiwgbFZpZXc6IExWaWV3KSB7XG4gIGNvbnN0IGluamVjdG9yID0gbFZpZXdbSU5KRUNUT1JdITtcbiAgY29uc3Qgc2NoZWR1bGVyID0gaW5qZWN0b3IuZ2V0KFRpbWVyU2NoZWR1bGVyKTtcbiAgY29uc3QgY2xlYW51cEZuID0gKCkgPT4gc2NoZWR1bGVyLnJlbW92ZShjYWxsYmFjayk7XG4gIHNjaGVkdWxlci5hZGQoZGVsYXksIGNhbGxiYWNrKTtcbiAgcmV0dXJuIGNsZWFudXBGbjtcbn1cblxuLyoqXG4gKiBIZWxwZXIgc2VydmljZSB0byBzY2hlZHVsZSBgc2V0VGltZW91dGBzIGZvciBiYXRjaGVzIG9mIGRlZmVyIGJsb2NrcyxcbiAqIHRvIGF2b2lkIGNhbGxpbmcgYHNldFRpbWVvdXRgIGZvciBlYWNoIGRlZmVyIGJsb2NrIChlLmcuIGlmIGRlZmVyIGJsb2Nrc1xuICogYXJlIGNyZWF0ZWQgaW5zaWRlIGEgZm9yIGxvb3ApLlxuICovXG5leHBvcnQgY2xhc3MgVGltZXJTY2hlZHVsZXIge1xuICAvLyBJbmRpY2F0ZXMgd2hldGhlciBjdXJyZW50IGNhbGxiYWNrcyBhcmUgYmVpbmcgaW52b2tlZC5cbiAgZXhlY3V0aW5nQ2FsbGJhY2tzID0gZmFsc2U7XG5cbiAgLy8gQ3VycmVudGx5IHNjaGVkdWxlZCBgc2V0VGltZW91dGAgaWQuXG4gIHRpbWVvdXRJZDogbnVtYmVyfG51bGwgPSBudWxsO1xuXG4gIC8vIFdoZW4gY3VycmVudGx5IHNjaGVkdWxlZCB0aW1lciB3b3VsZCBmaXJlLlxuICBpbnZva2VUaW1lckF0OiBudW1iZXJ8bnVsbCA9IG51bGw7XG5cbiAgLy8gTGlzdCBvZiBjYWxsYmFja3MgdG8gYmUgaW52b2tlZC5cbiAgLy8gRm9yIGVhY2ggY2FsbGJhY2sgd2UgYWxzbyBzdG9yZSBhIHRpbWVzdGFtcCBvbiB3aGVuIHRoZSBjYWxsYmFja1xuICAvLyBzaG91bGQgYmUgaW52b2tlZC4gV2Ugc3RvcmUgdGltZXN0YW1wcyBhbmQgY2FsbGJhY2sgZnVuY3Rpb25zXG4gIC8vIGluIGEgZmxhdCBhcnJheSB0byBhdm9pZCBjcmVhdGluZyBuZXcgb2JqZWN0cyBmb3IgZWFjaCBlbnRyeS5cbiAgLy8gW3RpbWVzdGFtcDEsIGNhbGxiYWNrMSwgdGltZXN0YW1wMiwgY2FsbGJhY2syLCAuLi5dXG4gIGN1cnJlbnQ6IEFycmF5PG51bWJlcnxWb2lkRnVuY3Rpb24+ID0gW107XG5cbiAgLy8gTGlzdCBvZiBjYWxsYmFja3MgY29sbGVjdGVkIHdoaWxlIGludm9raW5nIGN1cnJlbnQgc2V0IG9mIGNhbGxiYWNrcy5cbiAgLy8gVGhvc2UgY2FsbGJhY2tzIGFyZSBhZGRlZCB0byB0aGUgXCJjdXJyZW50XCIgcXVldWUgYXQgdGhlIGVuZCBvZlxuICAvLyB0aGUgY3VycmVudCBjYWxsYmFjayBpbnZvY2F0aW9uLiBUaGUgc2hhcGUgb2YgdGhpcyBsaXN0IGlzIHRoZSBzYW1lXG4gIC8vIGFzIHRoZSBzaGFwZSBvZiB0aGUgYGN1cnJlbnRgIGxpc3QuXG4gIGRlZmVycmVkOiBBcnJheTxudW1iZXJ8Vm9pZEZ1bmN0aW9uPiA9IFtdO1xuXG4gIGFkZChkZWxheTogbnVtYmVyLCBjYWxsYmFjazogVm9pZEZ1bmN0aW9uKSB7XG4gICAgY29uc3QgdGFyZ2V0ID0gdGhpcy5leGVjdXRpbmdDYWxsYmFja3MgPyB0aGlzLmRlZmVycmVkIDogdGhpcy5jdXJyZW50O1xuICAgIHRoaXMuYWRkVG9RdWV1ZSh0YXJnZXQsIERhdGUubm93KCkgKyBkZWxheSwgY2FsbGJhY2spO1xuICAgIHRoaXMuc2NoZWR1bGVUaW1lcigpO1xuICB9XG5cbiAgcmVtb3ZlKGNhbGxiYWNrOiBWb2lkRnVuY3Rpb24pIHtcbiAgICBjb25zdCB7Y3VycmVudCwgZGVmZXJyZWR9ID0gdGhpcztcbiAgICBjb25zdCBjYWxsYmFja0luZGV4ID0gdGhpcy5yZW1vdmVGcm9tUXVldWUoY3VycmVudCwgY2FsbGJhY2spO1xuICAgIGlmIChjYWxsYmFja0luZGV4ID09PSAtMSkge1xuICAgICAgLy8gVHJ5IGNsZWFuaW5nIHVwIGRlZmVycmVkIHF1ZXVlIG9ubHkgaW4gY2FzZVxuICAgICAgLy8gd2UgZGlkbid0IGZpbmQgYSBjYWxsYmFjayBpbiB0aGUgXCJjdXJyZW50XCIgcXVldWUuXG4gICAgICB0aGlzLnJlbW92ZUZyb21RdWV1ZShkZWZlcnJlZCwgY2FsbGJhY2spO1xuICAgIH1cbiAgICAvLyBJZiB0aGUgbGFzdCBjYWxsYmFjayB3YXMgcmVtb3ZlZCBhbmQgdGhlcmUgaXMgYSBwZW5kaW5nIHRpbWVvdXQgLSBjYW5jZWwgaXQuXG4gICAgaWYgKGN1cnJlbnQubGVuZ3RoID09PSAwICYmIGRlZmVycmVkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhpcy5jbGVhclRpbWVvdXQoKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGFkZFRvUXVldWUodGFyZ2V0OiBBcnJheTxudW1iZXJ8Vm9pZEZ1bmN0aW9uPiwgaW52b2tlQXQ6IG51bWJlciwgY2FsbGJhY2s6IFZvaWRGdW5jdGlvbikge1xuICAgIGxldCBpbnNlcnRBdEluZGV4ID0gdGFyZ2V0Lmxlbmd0aDtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHRhcmdldC5sZW5ndGg7IGkgKz0gMikge1xuICAgICAgY29uc3QgaW52b2tlUXVldWVkQ2FsbGJhY2tBdCA9IHRhcmdldFtpXSBhcyBudW1iZXI7XG4gICAgICBpZiAoaW52b2tlUXVldWVkQ2FsbGJhY2tBdCA+IGludm9rZUF0KSB7XG4gICAgICAgIC8vIFdlJ3ZlIHJlYWNoZWQgYSBmaXJzdCB0aW1lciB0aGF0IGlzIHNjaGVkdWxlZFxuICAgICAgICAvLyBmb3IgYSBsYXRlciB0aW1lIHRoYW4gd2hhdCB3ZSBhcmUgdHJ5aW5nIHRvIGluc2VydC5cbiAgICAgICAgLy8gVGhpcyBpcyB0aGUgbG9jYXRpb24gYXQgd2hpY2ggd2UgbmVlZCB0byBpbnNlcnQsXG4gICAgICAgIC8vIG5vIG5lZWQgdG8gaXRlcmF0ZSBmdXJ0aGVyLlxuICAgICAgICBpbnNlcnRBdEluZGV4ID0gaTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGFycmF5SW5zZXJ0Mih0YXJnZXQsIGluc2VydEF0SW5kZXgsIGludm9rZUF0LCBjYWxsYmFjayk7XG4gIH1cblxuICBwcml2YXRlIHJlbW92ZUZyb21RdWV1ZSh0YXJnZXQ6IEFycmF5PG51bWJlcnxWb2lkRnVuY3Rpb24+LCBjYWxsYmFjazogVm9pZEZ1bmN0aW9uKSB7XG4gICAgbGV0IGluZGV4ID0gLTE7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0YXJnZXQubGVuZ3RoOyBpICs9IDIpIHtcbiAgICAgIGNvbnN0IHF1ZXVlZENhbGxiYWNrID0gdGFyZ2V0W2kgKyAxXTtcbiAgICAgIGlmIChxdWV1ZWRDYWxsYmFjayA9PT0gY2FsbGJhY2spIHtcbiAgICAgICAgaW5kZXggPSBpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGluZGV4ID4gLTEpIHtcbiAgICAgIC8vIFJlbW92ZSAyIGVsZW1lbnRzOiBhIHRpbWVzdGFtcCBzbG90IGFuZFxuICAgICAgLy8gdGhlIGZvbGxvd2luZyBzbG90IHdpdGggYSBjYWxsYmFjayBmdW5jdGlvbi5cbiAgICAgIGFycmF5U3BsaWNlKHRhcmdldCwgaW5kZXgsIDIpO1xuICAgIH1cbiAgICByZXR1cm4gaW5kZXg7XG4gIH1cblxuICBwcml2YXRlIHNjaGVkdWxlVGltZXIoKSB7XG4gICAgY29uc3QgY2FsbGJhY2sgPSAoKSA9PiB7XG4gICAgICB0aGlzLmNsZWFyVGltZW91dCgpO1xuXG4gICAgICB0aGlzLmV4ZWN1dGluZ0NhbGxiYWNrcyA9IHRydWU7XG5cbiAgICAgIC8vIENsb25lIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBxdWV1ZSwgc2luY2UgaXQgbWlnaHQgYmUgYWx0ZXJlZFxuICAgICAgLy8gYXMgd2UgaW52b2tlIGNhbGxiYWNrcy5cbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBbLi4udGhpcy5jdXJyZW50XTtcblxuICAgICAgLy8gSW52b2tlIGNhbGxiYWNrcyB0aGF0IHdlcmUgc2NoZWR1bGVkIHRvIHJ1biBiZWZvcmUgdGhlIGN1cnJlbnQgdGltZS5cbiAgICAgIGNvbnN0IG5vdyA9IERhdGUubm93KCk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGN1cnJlbnQubGVuZ3RoOyBpICs9IDIpIHtcbiAgICAgICAgY29uc3QgaW52b2tlQXQgPSBjdXJyZW50W2ldIGFzIG51bWJlcjtcbiAgICAgICAgY29uc3QgY2FsbGJhY2sgPSBjdXJyZW50W2kgKyAxXSBhcyBWb2lkRnVuY3Rpb247XG4gICAgICAgIGlmIChpbnZva2VBdCA8PSBub3cpIHtcbiAgICAgICAgICBjYWxsYmFjaygpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIFdlJ3ZlIHJlYWNoZWQgYSB0aW1lciB0aGF0IHNob3VsZCBub3QgYmUgaW52b2tlZCB5ZXQuXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIFRoZSBzdGF0ZSBvZiB0aGUgcXVldWUgbWlnaHQndmUgY2hhbmdlZCBhZnRlciBjYWxsYmFja3MgaW52b2NhdGlvbixcbiAgICAgIC8vIHJ1biB0aGUgY2xlYW51cCBsb2dpYyBiYXNlZCBvbiB0aGUgKmN1cnJlbnQqIHN0YXRlIG9mIHRoZSBxdWV1ZS5cbiAgICAgIGxldCBsYXN0Q2FsbGJhY2tJbmRleCA9IC0xO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmN1cnJlbnQubGVuZ3RoOyBpICs9IDIpIHtcbiAgICAgICAgY29uc3QgaW52b2tlQXQgPSB0aGlzLmN1cnJlbnRbaV0gYXMgbnVtYmVyO1xuICAgICAgICBpZiAoaW52b2tlQXQgPD0gbm93KSB7XG4gICAgICAgICAgLy8gQWRkICsxIHRvIGFjY291bnQgZm9yIGEgY2FsbGJhY2sgZnVuY3Rpb24gdGhhdFxuICAgICAgICAgIC8vIGdvZXMgYWZ0ZXIgdGhlIHRpbWVzdGFtcCBpbiBldmVudHMgYXJyYXkuXG4gICAgICAgICAgbGFzdENhbGxiYWNrSW5kZXggPSBpICsgMTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBXZSd2ZSByZWFjaGVkIGEgdGltZXIgdGhhdCBzaG91bGQgbm90IGJlIGludm9rZWQgeWV0LlxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAobGFzdENhbGxiYWNrSW5kZXggPj0gMCkge1xuICAgICAgICBhcnJheVNwbGljZSh0aGlzLmN1cnJlbnQsIDAsIGxhc3RDYWxsYmFja0luZGV4ICsgMSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuZXhlY3V0aW5nQ2FsbGJhY2tzID0gZmFsc2U7XG5cbiAgICAgIC8vIElmIHRoZXJlIGFyZSBhbnkgY2FsbGJhY2tzIGFkZGVkIGR1cmluZyBhbiBpbnZvY2F0aW9uXG4gICAgICAvLyBvZiB0aGUgY3VycmVudCBvbmVzIC0gbW92ZSB0aGVtIG92ZXIgdG8gdGhlIFwiY3VycmVudFwiXG4gICAgICAvLyBxdWV1ZS5cbiAgICAgIGlmICh0aGlzLmRlZmVycmVkLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmRlZmVycmVkLmxlbmd0aDsgaSArPSAyKSB7XG4gICAgICAgICAgY29uc3QgaW52b2tlQXQgPSB0aGlzLmRlZmVycmVkW2ldIGFzIG51bWJlcjtcbiAgICAgICAgICBjb25zdCBjYWxsYmFjayA9IHRoaXMuZGVmZXJyZWRbaSArIDFdIGFzIFZvaWRGdW5jdGlvbjtcbiAgICAgICAgICB0aGlzLmFkZFRvUXVldWUodGhpcy5jdXJyZW50LCBpbnZva2VBdCwgY2FsbGJhY2spO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuZGVmZXJyZWQubGVuZ3RoID0gMDtcbiAgICAgIH1cbiAgICAgIHRoaXMuc2NoZWR1bGVUaW1lcigpO1xuICAgIH07XG5cbiAgICAvLyBBdm9pZCBydW5uaW5nIHRpbWVyIGNhbGxiYWNrcyBtb3JlIHRoYW4gb25jZSBwZXJcbiAgICAvLyBhdmVyYWdlIGZyYW1lIGR1cmF0aW9uLiBUaGlzIGlzIG5lZWRlZCBmb3IgYmV0dGVyXG4gICAgLy8gYmF0Y2hpbmcgYW5kIHRvIGF2b2lkIGtpY2tpbmcgb2ZmIGV4Y2Vzc2l2ZSBjaGFuZ2VcbiAgICAvLyBkZXRlY3Rpb24gY3ljbGVzLlxuICAgIGNvbnN0IEZSQU1FX0RVUkFUSU9OX01TID0gMTY7ICAvLyAxMDAwbXMgLyA2MGZwc1xuXG4gICAgaWYgKHRoaXMuY3VycmVudC5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICAgICAgLy8gRmlyc3QgZWxlbWVudCBpbiB0aGUgcXVldWUgcG9pbnRzIGF0IHRoZSB0aW1lc3RhbXBcbiAgICAgIC8vIG9mIHRoZSBmaXJzdCAoZWFybGllc3QpIGV2ZW50LlxuICAgICAgY29uc3QgaW52b2tlQXQgPSB0aGlzLmN1cnJlbnRbMF0gYXMgbnVtYmVyO1xuICAgICAgaWYgKHRoaXMudGltZW91dElkID09PSBudWxsIHx8XG4gICAgICAgICAgLy8gUmVzY2hlZHVsZSBhIHRpbWVyIGluIGNhc2UgYSBxdWV1ZSBjb250YWlucyBhbiBpdGVtIHdpdGhcbiAgICAgICAgICAvLyBhbiBlYXJsaWVyIHRpbWVzdGFtcCBhbmQgdGhlIGRlbHRhIGlzIG1vcmUgdGhhbiBhbiBhdmVyYWdlXG4gICAgICAgICAgLy8gZnJhbWUgZHVyYXRpb24uXG4gICAgICAgICAgKHRoaXMuaW52b2tlVGltZXJBdCAmJiAodGhpcy5pbnZva2VUaW1lckF0IC0gaW52b2tlQXQgPiBGUkFNRV9EVVJBVElPTl9NUykpKSB7XG4gICAgICAgIC8vIFRoZXJlIHdhcyBhIHRpbWVvdXQgYWxyZWFkeSwgYnV0IGFuIGVhcmxpZXIgZXZlbnQgd2FzIGFkZGVkXG4gICAgICAgIC8vIGludG8gdGhlIHF1ZXVlLiBJbiB0aGlzIGNhc2Ugd2UgZHJvcCBhbiBvbGQgdGltZXIgYW5kIHNldHVwXG4gICAgICAgIC8vIGEgbmV3IG9uZSB3aXRoIGFuIHVwZGF0ZWQgKHNtYWxsZXIpIHRpbWVvdXQuXG4gICAgICAgIHRoaXMuY2xlYXJUaW1lb3V0KCk7XG5cbiAgICAgICAgY29uc3QgdGltZW91dCA9IE1hdGgubWF4KGludm9rZUF0IC0gbm93LCBGUkFNRV9EVVJBVElPTl9NUyk7XG4gICAgICAgIHRoaXMuaW52b2tlVGltZXJBdCA9IGludm9rZUF0O1xuICAgICAgICB0aGlzLnRpbWVvdXRJZCA9IHNldFRpbWVvdXQoY2FsbGJhY2ssIHRpbWVvdXQpIGFzIHVua25vd24gYXMgbnVtYmVyO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgY2xlYXJUaW1lb3V0KCkge1xuICAgIGlmICh0aGlzLnRpbWVvdXRJZCAhPT0gbnVsbCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHRoaXMudGltZW91dElkKTtcbiAgICAgIHRoaXMudGltZW91dElkID0gbnVsbDtcbiAgICB9XG4gIH1cblxuICBuZ09uRGVzdHJveSgpIHtcbiAgICB0aGlzLmNsZWFyVGltZW91dCgpO1xuICAgIHRoaXMuY3VycmVudC5sZW5ndGggPSAwO1xuICAgIHRoaXMuZGVmZXJyZWQubGVuZ3RoID0gMDtcbiAgfVxuXG4gIC8qKiBAbm9jb2xsYXBzZSAqL1xuICBzdGF0aWMgybVwcm92ID0gLyoqIEBwdXJlT3JCcmVha015Q29kZSAqLyDJtcm1ZGVmaW5lSW5qZWN0YWJsZSh7XG4gICAgdG9rZW46IFRpbWVyU2NoZWR1bGVyLFxuICAgIHByb3ZpZGVkSW46ICdyb290JyxcbiAgICBmYWN0b3J5OiAoKSA9PiBuZXcgVGltZXJTY2hlZHVsZXIoKSxcbiAgfSk7XG59XG4iXX0=
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import { assertIndexInDeclRange } from '../render3/assert';
|
|
9
|
+
import { HEADER_OFFSET, TVIEW } from '../render3/interfaces/view';
|
|
10
|
+
import { getTNode } from '../render3/util/view_utils';
|
|
11
|
+
import { assertEqual, throwError } from '../util/assert';
|
|
12
|
+
import { DeferBlockState, DeferDependenciesLoadingState, LOADING_AFTER_SLOT, MINIMUM_SLOT } from './interfaces';
|
|
13
|
+
/**
|
|
14
|
+
* Calculates a data slot index for defer block info (either static or
|
|
15
|
+
* instance-specific), given an index of a defer instruction.
|
|
16
|
+
*/
|
|
17
|
+
export function getDeferBlockDataIndex(deferBlockIndex) {
|
|
18
|
+
// Instance state is located at the *next* position
|
|
19
|
+
// after the defer block slot in an LView or TView.data.
|
|
20
|
+
return deferBlockIndex + 1;
|
|
21
|
+
}
|
|
22
|
+
/** Retrieves a defer block state from an LView, given a TNode that represents a block. */
|
|
23
|
+
export function getLDeferBlockDetails(lView, tNode) {
|
|
24
|
+
const tView = lView[TVIEW];
|
|
25
|
+
const slotIndex = getDeferBlockDataIndex(tNode.index);
|
|
26
|
+
ngDevMode && assertIndexInDeclRange(tView, slotIndex);
|
|
27
|
+
return lView[slotIndex];
|
|
28
|
+
}
|
|
29
|
+
/** Stores a defer block instance state in LView. */
|
|
30
|
+
export function setLDeferBlockDetails(lView, deferBlockIndex, lDetails) {
|
|
31
|
+
const tView = lView[TVIEW];
|
|
32
|
+
const slotIndex = getDeferBlockDataIndex(deferBlockIndex);
|
|
33
|
+
ngDevMode && assertIndexInDeclRange(tView, slotIndex);
|
|
34
|
+
lView[slotIndex] = lDetails;
|
|
35
|
+
}
|
|
36
|
+
/** Retrieves static info about a defer block, given a TView and a TNode that represents a block. */
|
|
37
|
+
export function getTDeferBlockDetails(tView, tNode) {
|
|
38
|
+
const slotIndex = getDeferBlockDataIndex(tNode.index);
|
|
39
|
+
ngDevMode && assertIndexInDeclRange(tView, slotIndex);
|
|
40
|
+
return tView.data[slotIndex];
|
|
41
|
+
}
|
|
42
|
+
/** Stores a defer block static info in `TView.data`. */
|
|
43
|
+
export function setTDeferBlockDetails(tView, deferBlockIndex, deferBlockConfig) {
|
|
44
|
+
const slotIndex = getDeferBlockDataIndex(deferBlockIndex);
|
|
45
|
+
ngDevMode && assertIndexInDeclRange(tView, slotIndex);
|
|
46
|
+
tView.data[slotIndex] = deferBlockConfig;
|
|
47
|
+
}
|
|
48
|
+
export function getTemplateIndexForState(newState, hostLView, tNode) {
|
|
49
|
+
const tView = hostLView[TVIEW];
|
|
50
|
+
const tDetails = getTDeferBlockDetails(tView, tNode);
|
|
51
|
+
switch (newState) {
|
|
52
|
+
case DeferBlockState.Complete:
|
|
53
|
+
return tDetails.primaryTmplIndex;
|
|
54
|
+
case DeferBlockState.Loading:
|
|
55
|
+
return tDetails.loadingTmplIndex;
|
|
56
|
+
case DeferBlockState.Error:
|
|
57
|
+
return tDetails.errorTmplIndex;
|
|
58
|
+
case DeferBlockState.Placeholder:
|
|
59
|
+
return tDetails.placeholderTmplIndex;
|
|
60
|
+
default:
|
|
61
|
+
ngDevMode && throwError(`Unexpected defer block state: ${newState}`);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Returns a minimum amount of time that a given state should be rendered for,
|
|
67
|
+
* taking into account `minimum` parameter value. If the `minimum` value is
|
|
68
|
+
* not specified - returns `null`.
|
|
69
|
+
*/
|
|
70
|
+
export function getMinimumDurationForState(tDetails, currentState) {
|
|
71
|
+
if (currentState === DeferBlockState.Placeholder) {
|
|
72
|
+
return tDetails.placeholderBlockConfig?.[MINIMUM_SLOT] ?? null;
|
|
73
|
+
}
|
|
74
|
+
else if (currentState === DeferBlockState.Loading) {
|
|
75
|
+
return tDetails.loadingBlockConfig?.[MINIMUM_SLOT] ?? null;
|
|
76
|
+
}
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
/** Retrieves the value of the `after` parameter on the @loading block. */
|
|
80
|
+
export function getLoadingBlockAfter(tDetails) {
|
|
81
|
+
return tDetails.loadingBlockConfig?.[LOADING_AFTER_SLOT] ?? null;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Adds downloaded dependencies into a directive or a pipe registry,
|
|
85
|
+
* making sure that a dependency doesn't yet exist in the registry.
|
|
86
|
+
*/
|
|
87
|
+
export function addDepsToRegistry(currentDeps, newDeps) {
|
|
88
|
+
if (!currentDeps || currentDeps.length === 0) {
|
|
89
|
+
return newDeps;
|
|
90
|
+
}
|
|
91
|
+
const currentDepSet = new Set(currentDeps);
|
|
92
|
+
for (const dep of newDeps) {
|
|
93
|
+
currentDepSet.add(dep);
|
|
94
|
+
}
|
|
95
|
+
// If `currentDeps` is the same length, there were no new deps and can
|
|
96
|
+
// return the original array.
|
|
97
|
+
return (currentDeps.length === currentDepSet.size) ? currentDeps : Array.from(currentDepSet);
|
|
98
|
+
}
|
|
99
|
+
/** Retrieves a TNode that represents main content of a defer block. */
|
|
100
|
+
export function getPrimaryBlockTNode(tView, tDetails) {
|
|
101
|
+
const adjustedIndex = tDetails.primaryTmplIndex + HEADER_OFFSET;
|
|
102
|
+
return getTNode(tView, adjustedIndex);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Asserts whether all dependencies for a defer block are loaded.
|
|
106
|
+
* Always run this function (in dev mode) before rendering a defer
|
|
107
|
+
* block in completed state.
|
|
108
|
+
*/
|
|
109
|
+
export function assertDeferredDependenciesLoaded(tDetails) {
|
|
110
|
+
assertEqual(tDetails.loadingState, DeferDependenciesLoadingState.COMPLETE, 'Expecting all deferred dependencies to be loaded.');
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Determines if a given value matches the expected structure of a defer block
|
|
114
|
+
*
|
|
115
|
+
* We can safely rely on the primaryTmplIndex because every defer block requires
|
|
116
|
+
* that a primary template exists. All the other template options are optional.
|
|
117
|
+
*/
|
|
118
|
+
export function isTDeferBlockDetails(value) {
|
|
119
|
+
return (typeof value === 'object') &&
|
|
120
|
+
(typeof value.primaryTmplIndex === 'number');
|
|
121
|
+
}
|
|
122
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9kZWZlci91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUd6RCxPQUFPLEVBQUMsYUFBYSxFQUFTLEtBQUssRUFBUSxNQUFNLDRCQUE0QixDQUFDO0FBQzlFLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRCxPQUFPLEVBQUMsV0FBVyxFQUFFLFVBQVUsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBRXZELE9BQU8sRUFBQyxlQUFlLEVBQUUsNkJBQTZCLEVBQXNCLGtCQUFrQixFQUFFLFlBQVksRUFBcUIsTUFBTSxjQUFjLENBQUM7QUFHdEo7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLHNCQUFzQixDQUFDLGVBQXVCO0lBQzVELG1EQUFtRDtJQUNuRCx3REFBd0Q7SUFDeEQsT0FBTyxlQUFlLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFFRCwwRkFBMEY7QUFDMUYsTUFBTSxVQUFVLHFCQUFxQixDQUFDLEtBQVksRUFBRSxLQUFZO0lBQzlELE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQixNQUFNLFNBQVMsR0FBRyxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdEQsU0FBUyxJQUFJLHNCQUFzQixDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztJQUN0RCxPQUFPLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUMxQixDQUFDO0FBRUQsb0RBQW9EO0FBQ3BELE1BQU0sVUFBVSxxQkFBcUIsQ0FDakMsS0FBWSxFQUFFLGVBQXVCLEVBQUUsUUFBNEI7SUFDckUsTUFBTSxLQUFLLEdBQUcsS0FBSyxDQUFDLEtBQUss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QUFHLENBQUMsR0FBRyxDQUFDLENBQUM7S0FDeEI7SUFFRCxzRUFBc0U7SUFDdEUsNkJBQTZCO0lBQzdCLE9BQU8sQ0FBQyxXQUFXLENBQUMsTUFBTSxLQUFLLGFBQWEsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBTSxDQUFDO0FBQ3BHLENBQUM7QUFFRCx1RUFBdUU7QUFDdkUsTUFBTSxVQUFVLG9CQUFvQixDQUFDLEtBQVksRUFBRSxRQUE0QjtJQUM3RSxNQUFNLGFBQWEsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLEdBQUcsYUFBYSxDQUFDO0lBQ2hFLE9BQU8sUUFBUSxDQUFDLEtBQUssRUFBRSxhQUFhLENBQW1CLENBQUM7QUFDMUQsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsZ0NBQWdDLENBQUMsUUFBNEI7SUFDM0UsV0FBVyxDQUNQLFFBQVEsQ0FBQyxZQUFZLEVBQUUsNkJBQTZCLENBQUMsUUFBUSxFQUM3RCxtREFBbUQsQ0FBQyxDQUFDO0FBQzNELENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FBQyxLQUFjO0lBQ2pELE9BQU8sQ0FBQyxPQUFPLEtBQUssS0FBSyxRQUFRLENBQUM7UUFDOUIsQ0FBQyxPQUFRLEtBQTRCLENBQUMsZ0JBQWdCLEtBQUssUUFBUSxDQUFDLENBQUM7QUFDM0UsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge2Fzc2VydEluZGV4SW5EZWNsUmFuZ2V9IGZyb20gJy4uL3JlbmRlcjMvYXNzZXJ0JztcbmltcG9ydCB7RGVwZW5kZW5jeURlZn0gZnJvbSAnLi4vcmVuZGVyMy9pbnRlcmZhY2VzL2RlZmluaXRpb24nO1xuaW1wb3J0IHtUQ29udGFpbmVyTm9kZSwgVE5vZGV9IGZyb20gJy4uL3JlbmRlcjMvaW50ZXJmYWNlcy9ub2RlJztcbmltcG9ydCB7SEVBREVSX09GRlNFVCwgTFZpZXcsIFRWSUVXLCBUVmlld30gZnJvbSAnLi4vcmVuZGVyMy9pbnRlcmZhY2VzL3ZpZXcnO1xuaW1wb3J0IHtnZXRUTm9kZX0gZnJvbSAnLi4vcmVuZGVyMy91dGlsL3ZpZXdfdXRpbHMnO1xuaW1wb3J0IHthc3NlcnRFcXVhbCwgdGhyb3dFcnJvcn0gZnJvbSAnLi4vdXRpbC9hc3NlcnQnO1xuXG5pbXBvcnQge0RlZmVyQmxvY2tTdGF0ZSwgRGVmZXJEZXBlbmRlbmNpZXNMb2FkaW5nU3RhdGUsIExEZWZlckJsb2NrRGV0YWlscywgTE9BRElOR19BRlRFUl9TTE9ULCBNSU5JTVVNX1NMT1QsIFREZWZlckJsb2NrRGV0YWlsc30gZnJvbSAnLi9pbnRlcmZhY2VzJztcblxuXG4vKipcbiAqIENhbGN1bGF0ZXMgYSBkYXRhIHNsb3QgaW5kZXggZm9yIGRlZmVyIGJsb2NrIGluZm8gKGVpdGhlciBzdGF0aWMgb3JcbiAqIGluc3RhbmNlLXNwZWNpZmljKSwgZ2l2ZW4gYW4gaW5kZXggb2YgYSBkZWZlciBpbnN0cnVjdGlvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlZmVyQmxvY2tEYXRhSW5kZXgoZGVmZXJCbG9ja0luZGV4OiBudW1iZXIpIHtcbiAgLy8gSW5zdGFuY2Ugc3RhdGUgaXMgbG9jYXRlZCBhdCB0aGUgKm5leHQqIHBvc2l0aW9uXG4gIC8vIGFmdGVyIHRoZSBkZWZlciBibG9jayBzbG90IGluIGFuIExWaWV3IG9yIFRWaWV3LmRhdGEuXG4gIHJldHVybiBkZWZlckJsb2NrSW5kZXggKyAxO1xufVxuXG4vKiogUmV0cmlldmVzIGEgZGVmZXIgYmxvY2sgc3RhdGUgZnJvbSBhbiBMVmlldywgZ2l2ZW4gYSBUTm9kZSB0aGF0IHJlcHJlc2VudHMgYSBibG9jay4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRMRGVmZXJCbG9ja0RldGFpbHMobFZpZXc6IExWaWV3LCB0Tm9kZTogVE5vZGUpOiBMRGVmZXJCbG9ja0RldGFpbHMge1xuICBjb25zdCB0VmlldyA9IGxWaWV3W1RWSUVXXTtcbiAgY29uc3Qgc2xvdEluZGV4ID0gZ2V0RGVmZXJCbG9ja0RhdGFJbmRleCh0Tm9kZS5pbmRleCk7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnRJbmRleEluRGVjbFJhbmdlKHRWaWV3LCBzbG90SW5kZXgpO1xuICByZXR1cm4gbFZpZXdbc2xvdEluZGV4XTtcbn1cblxuLyoqIFN0b3JlcyBhIGRlZmVyIGJsb2NrIGluc3RhbmNlIHN0YXRlIGluIExWaWV3LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldExEZWZlckJsb2NrRGV0YWlscyhcbiAgICBsVmlldzogTFZpZXcsIGRlZmVyQmxvY2tJbmRleDogbnVtYmVyLCBsRGV0YWlsczogTERlZmVyQmxvY2tEZXRhaWxzKSB7XG4gIGNvbnN0IHRWaWV3ID0gbFZpZXdbVFZJRVddO1xuICBjb25zdCBzbG90SW5kZXggPSBnZXREZWZlckJsb2NrRGF0YUluZGV4KGRlZmVyQmxvY2tJbmRleCk7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnRJbmRleEluRGVjbFJhbmdlKHRWaWV3LCBzbG90SW5kZXgpO1xuICBsVmlld1tzbG90SW5kZXhdID0gbERldGFpbHM7XG59XG5cbi8qKiBSZXRyaWV2ZXMgc3RhdGljIGluZm8gYWJvdXQgYSBkZWZlciBibG9jaywgZ2l2ZW4gYSBUVmlldyBhbmQgYSBUTm9kZSB0aGF0IHJlcHJlc2VudHMgYSBibG9jay4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRURGVmZXJCbG9ja0RldGFpbHModFZpZXc6IFRWaWV3LCB0Tm9kZTogVE5vZGUpOiBURGVmZXJCbG9ja0RldGFpbHMge1xuICBjb25zdCBzbG90SW5kZXggPSBnZXREZWZlckJsb2NrRGF0YUluZGV4KHROb2RlLmluZGV4KTtcbiAgbmdEZXZNb2RlICYmIGFzc2VydEluZGV4SW5EZWNsUmFuZ2UodFZpZXcsIHNsb3RJbmRleCk7XG4gIHJldHVybiB0Vmlldy5kYXRhW3Nsb3RJbmRleF0gYXMgVERlZmVyQmxvY2tEZXRhaWxzO1xufVxuXG4vKiogU3RvcmVzIGEgZGVmZXIgYmxvY2sgc3RhdGljIGluZm8gaW4gYFRWaWV3LmRhdGFgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFREZWZlckJsb2NrRGV0YWlscyhcbiAgICB0VmlldzogVFZpZXcsIGRlZmVyQmxvY2tJbmRleDogbnVtYmVyLCBkZWZlckJsb2NrQ29uZmlnOiBURGVmZXJCbG9ja0RldGFpbHMpIHtcbiAgY29uc3Qgc2xvdEluZGV4ID0gZ2V0RGVmZXJCbG9ja0RhdGFJbmRleChkZWZlckJsb2NrSW5kZXgpO1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0SW5kZXhJbkRlY2xSYW5nZSh0Vmlldywgc2xvdEluZGV4KTtcbiAgdFZpZXcuZGF0YVtzbG90SW5kZXhdID0gZGVmZXJCbG9ja0NvbmZpZztcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFRlbXBsYXRlSW5kZXhGb3JTdGF0ZShcbiAgICBuZXdTdGF0ZTogRGVmZXJCbG9ja1N0YXRlLCBob3N0TFZpZXc6IExWaWV3LCB0Tm9kZTogVE5vZGUpOiBudW1iZXJ8bnVsbCB7XG4gIGNvbnN0IHRWaWV3ID0gaG9zdExWaWV3W1RWSUVXXTtcbiAgY29uc3QgdERldGFpbHMgPSBnZXRURGVmZXJCbG9ja0RldGFpbHModFZpZXcsIHROb2RlKTtcblxuICBzd2l0Y2ggKG5ld1N0YXRlKSB7XG4gICAgY2FzZSBEZWZlckJsb2NrU3RhdGUuQ29tcGxldGU6XG4gICAgICByZXR1cm4gdERldGFpbHMucHJpbWFyeVRtcGxJbmRleDtcbiAgICBjYXNlIERlZmVyQmxvY2tTdGF0ZS5Mb2FkaW5nOlxuICAgICAgcmV0dXJuIHREZXRhaWxzLmxvYWRpbmdUbXBsSW5kZXg7XG4gICAgY2FzZSBEZWZlckJsb2NrU3RhdGUuRXJyb3I6XG4gICAgICByZXR1cm4gdERldGFpbHMuZXJyb3JUbXBsSW5kZXg7XG4gICAgY2FzZSBEZWZlckJsb2NrU3RhdGUuUGxhY2Vob2xkZXI6XG4gICAgICByZXR1cm4gdERldGFpbHMucGxhY2Vob2xkZXJUbXBsSW5kZXg7XG4gICAgZGVmYXVsdDpcbiAgICAgIG5nRGV2TW9kZSAmJiB0aHJvd0Vycm9yKGBVbmV4cGVjdGVkIGRlZmVyIGJsb2NrIHN0YXRlOiAke25ld1N0YXRlfWApO1xuICAgICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgbWluaW11bSBhbW91bnQgb2YgdGltZSB0aGF0IGEgZ2l2ZW4gc3RhdGUgc2hvdWxkIGJlIHJlbmRlcmVkIGZvcixcbiAqIHRha2luZyBpbnRvIGFjY291bnQgYG1pbmltdW1gIHBhcmFtZXRlciB2YWx1ZS4gSWYgdGhlIGBtaW5pbXVtYCB2YWx1ZSBpc1xuICogbm90IHNwZWNpZmllZCAtIHJldHVybnMgYG51bGxgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0TWluaW11bUR1cmF0aW9uRm9yU3RhdGUoXG4gICAgdERldGFpbHM6IFREZWZlckJsb2NrRGV0YWlscywgY3VycmVudFN0YXRlOiBEZWZlckJsb2NrU3RhdGUpOiBudW1iZXJ8bnVsbCB7XG4gIGlmIChjdXJyZW50U3RhdGUgPT09IERlZmVyQmxvY2tTdGF0ZS5QbGFjZWhvbGRlcikge1xuICAgIHJldHVybiB0RGV0YWlscy5wbGFjZWhvbGRlckJsb2NrQ29uZmlnPy5bTUlOSU1VTV9TTE9UXSA/PyBudWxsO1xuICB9IGVsc2UgaWYgKGN1cnJlbnRTdGF0ZSA9PT0gRGVmZXJCbG9ja1N0YXRlLkxvYWRpbmcpIHtcbiAgICByZXR1cm4gdERldGFpbHMubG9hZGluZ0Jsb2NrQ29uZmlnPy5bTUlOSU1VTV9TTE9UXSA/PyBudWxsO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKiogUmV0cmlldmVzIHRoZSB2YWx1ZSBvZiB0aGUgYGFmdGVyYCBwYXJhbWV0ZXIgb24gdGhlIEBsb2FkaW5nIGJsb2NrLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExvYWRpbmdCbG9ja0FmdGVyKHREZXRhaWxzOiBURGVmZXJCbG9ja0RldGFpbHMpOiBudW1iZXJ8bnVsbCB7XG4gIHJldHVybiB0RGV0YWlscy5sb2FkaW5nQmxvY2tDb25maWc/LltMT0FESU5HX0FGVEVSX1NMT1RdID8/IG51bGw7XG59XG5cbi8qKlxuICogQWRkcyBkb3dubG9hZGVkIGRlcGVuZGVuY2llcyBpbnRvIGEgZGlyZWN0aXZlIG9yIGEgcGlwZSByZWdpc3RyeSxcbiAqIG1ha2luZyBzdXJlIHRoYXQgYSBkZXBlbmRlbmN5IGRvZXNuJ3QgeWV0IGV4aXN0IGluIHRoZSByZWdpc3RyeS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZERlcHNUb1JlZ2lzdHJ5PFQgZXh0ZW5kcyBEZXBlbmRlbmN5RGVmW10+KGN1cnJlbnREZXBzOiBUfG51bGwsIG5ld0RlcHM6IFQpOiBUIHtcbiAgaWYgKCFjdXJyZW50RGVwcyB8fCBjdXJyZW50RGVwcy5sZW5ndGggPT09IDApIHtcbiAgICByZXR1cm4gbmV3RGVwcztcbiAgfVxuXG4gIGNvbnN0IGN1cnJlbnREZXBTZXQgPSBuZXcgU2V0KGN1cnJlbnREZXBzKTtcbiAgZm9yIChjb25zdCBkZXAgb2YgbmV3RGVwcykge1xuICAgIGN1cnJlbnREZXBTZXQuYWRkKGRlcCk7XG4gIH1cblxuICAvLyBJZiBgY3VycmVudERlcHNgIGlzIHRoZSBzYW1lIGxlbmd0aCwgdGhlcmUgd2VyZSBubyBuZXcgZGVwcyBhbmQgY2FuXG4gIC8vIHJldHVybiB0aGUgb3JpZ2luYWwgYXJyYXkuXG4gIHJldHVybiAoY3VycmVudERlcHMubGVuZ3RoID09PSBjdXJyZW50RGVwU2V0LnNpemUpID8gY3VycmVudERlcHMgOiBBcnJheS5mcm9tKGN1cnJlbnREZXBTZXQpIGFzIFQ7XG59XG5cbi8qKiBSZXRyaWV2ZXMgYSBUTm9kZSB0aGF0IHJlcHJlc2VudHMgbWFpbiBjb250ZW50IG9mIGEgZGVmZXIgYmxvY2suICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UHJpbWFyeUJsb2NrVE5vZGUodFZpZXc6IFRWaWV3LCB0RGV0YWlsczogVERlZmVyQmxvY2tEZXRhaWxzKTogVENvbnRhaW5lck5vZGUge1xuICBjb25zdCBhZGp1c3RlZEluZGV4ID0gdERldGFpbHMucHJpbWFyeVRtcGxJbmRleCArIEhFQURFUl9PRkZTRVQ7XG4gIHJldHVybiBnZXRUTm9kZSh0VmlldywgYWRqdXN0ZWRJbmRleCkgYXMgVENvbnRhaW5lck5vZGU7XG59XG5cbi8qKlxuICogQXNzZXJ0cyB3aGV0aGVyIGFsbCBkZXBlbmRlbmNpZXMgZm9yIGEgZGVmZXIgYmxvY2sgYXJlIGxvYWRlZC5cbiAqIEFsd2F5cyBydW4gdGhpcyBmdW5jdGlvbiAoaW4gZGV2IG1vZGUpIGJlZm9yZSByZW5kZXJpbmcgYSBkZWZlclxuICogYmxvY2sgaW4gY29tcGxldGVkIHN0YXRlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0RGVmZXJyZWREZXBlbmRlbmNpZXNMb2FkZWQodERldGFpbHM6IFREZWZlckJsb2NrRGV0YWlscykge1xuICBhc3NlcnRFcXVhbChcbiAgICAgIHREZXRhaWxzLmxvYWRpbmdTdGF0ZSwgRGVmZXJEZXBlbmRlbmNpZXNMb2FkaW5nU3RhdGUuQ09NUExFVEUsXG4gICAgICAnRXhwZWN0aW5nIGFsbCBkZWZlcnJlZCBkZXBlbmRlbmNpZXMgdG8gYmUgbG9hZGVkLicpO1xufVxuXG4vKipcbiAqIERldGVybWluZXMgaWYgYSBnaXZlbiB2YWx1ZSBtYXRjaGVzIHRoZSBleHBlY3RlZCBzdHJ1Y3R1cmUgb2YgYSBkZWZlciBibG9ja1xuICpcbiAqIFdlIGNhbiBzYWZlbHkgcmVseSBvbiB0aGUgcHJpbWFyeVRtcGxJbmRleCBiZWNhdXNlIGV2ZXJ5IGRlZmVyIGJsb2NrIHJlcXVpcmVzXG4gKiB0aGF0IGEgcHJpbWFyeSB0ZW1wbGF0ZSBleGlzdHMuIEFsbCB0aGUgb3RoZXIgdGVtcGxhdGUgb3B0aW9ucyBhcmUgb3B0aW9uYWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1REZWZlckJsb2NrRGV0YWlscyh2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIFREZWZlckJsb2NrRGV0YWlscyB7XG4gIHJldHVybiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JykgJiZcbiAgICAgICh0eXBlb2YgKHZhbHVlIGFzIFREZWZlckJsb2NrRGV0YWlscykucHJpbWFyeVRtcGxJbmRleCA9PT0gJ251bWJlcicpO1xufVxuIl19
|