package.esm2022.src.defer.utils.mjs Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of core Show documentation
Show all versions of core Show documentation
Angular - the core framework
/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.dev/license
*/
import { assertIndexInDeclRange } from '../render3/assert';
import { HEADER_OFFSET, TVIEW } from '../render3/interfaces/view';
import { getTNode } from '../render3/util/view_utils';
import { assertEqual, throwError } from '../util/assert';
import { DeferBlockState, DeferDependenciesLoadingState, LOADING_AFTER_SLOT, MINIMUM_SLOT, } from './interfaces';
/**
* Calculates a data slot index for defer block info (either static or
* instance-specific), given an index of a defer instruction.
*/
export function getDeferBlockDataIndex(deferBlockIndex) {
// Instance state is located at the *next* position
// after the defer block slot in an LView or TView.data.
return deferBlockIndex + 1;
}
/** Retrieves a defer block state from an LView, given a TNode that represents a block. */
export function getLDeferBlockDetails(lView, tNode) {
const tView = lView[TVIEW];
const slotIndex = getDeferBlockDataIndex(tNode.index);
ngDevMode && assertIndexInDeclRange(tView, slotIndex);
return lView[slotIndex];
}
/** Stores a defer block instance state in LView. */
export function setLDeferBlockDetails(lView, deferBlockIndex, lDetails) {
const tView = lView[TVIEW];
const slotIndex = getDeferBlockDataIndex(deferBlockIndex);
ngDevMode && assertIndexInDeclRange(tView, slotIndex);
lView[slotIndex] = lDetails;
}
/** Retrieves static info about a defer block, given a TView and a TNode that represents a block. */
export function getTDeferBlockDetails(tView, tNode) {
const slotIndex = getDeferBlockDataIndex(tNode.index);
ngDevMode && assertIndexInDeclRange(tView, slotIndex);
return tView.data[slotIndex];
}
/** Stores a defer block static info in `TView.data`. */
export function setTDeferBlockDetails(tView, deferBlockIndex, deferBlockConfig) {
const slotIndex = getDeferBlockDataIndex(deferBlockIndex);
ngDevMode && assertIndexInDeclRange(tView, slotIndex);
tView.data[slotIndex] = deferBlockConfig;
}
export function getTemplateIndexForState(newState, hostLView, tNode) {
const tView = hostLView[TVIEW];
const tDetails = getTDeferBlockDetails(tView, tNode);
switch (newState) {
case DeferBlockState.Complete:
return tDetails.primaryTmplIndex;
case DeferBlockState.Loading:
return tDetails.loadingTmplIndex;
case DeferBlockState.Error:
return tDetails.errorTmplIndex;
case DeferBlockState.Placeholder:
return tDetails.placeholderTmplIndex;
default:
ngDevMode && throwError(`Unexpected defer block state: ${newState}`);
return null;
}
}
/**
* Returns a minimum amount of time that a given state should be rendered for,
* taking into account `minimum` parameter value. If the `minimum` value is
* not specified - returns `null`.
*/
export function getMinimumDurationForState(tDetails, currentState) {
if (currentState === DeferBlockState.Placeholder) {
return tDetails.placeholderBlockConfig?.[MINIMUM_SLOT] ?? null;
}
else if (currentState === DeferBlockState.Loading) {
return tDetails.loadingBlockConfig?.[MINIMUM_SLOT] ?? null;
}
return null;
}
/** Retrieves the value of the `after` parameter on the @loading block. */
export function getLoadingBlockAfter(tDetails) {
return tDetails.loadingBlockConfig?.[LOADING_AFTER_SLOT] ?? null;
}
/**
* Adds downloaded dependencies into a directive or a pipe registry,
* making sure that a dependency doesn't yet exist in the registry.
*/
export function addDepsToRegistry(currentDeps, newDeps) {
if (!currentDeps || currentDeps.length === 0) {
return newDeps;
}
const currentDepSet = new Set(currentDeps);
for (const dep of newDeps) {
currentDepSet.add(dep);
}
// If `currentDeps` is the same length, there were no new deps and can
// return the original array.
return currentDeps.length === currentDepSet.size ? currentDeps : Array.from(currentDepSet);
}
/** Retrieves a TNode that represents main content of a defer block. */
export function getPrimaryBlockTNode(tView, tDetails) {
const adjustedIndex = tDetails.primaryTmplIndex + HEADER_OFFSET;
return getTNode(tView, adjustedIndex);
}
/**
* Asserts whether all dependencies for a defer block are loaded.
* Always run this function (in dev mode) before rendering a defer
* block in completed state.
*/
export function assertDeferredDependenciesLoaded(tDetails) {
assertEqual(tDetails.loadingState, DeferDependenciesLoadingState.COMPLETE, 'Expecting all deferred dependencies to be loaded.');
}
/**
* Determines if a given value matches the expected structure of a defer block
*
* We can safely rely on the primaryTmplIndex because every defer block requires
* that a primary template exists. All the other template options are optional.
*/
export function isTDeferBlockDetails(value) {
return (value !== null &&
typeof value === 'object' &&
typeof value.primaryTmplIndex === 'number');
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9kZWZlci91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUd6RCxPQUFPLEVBQUMsYUFBYSxFQUFTLEtBQUssRUFBUSxNQUFNLDRCQUE0QixDQUFDO0FBQzlFLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSw0QkFBNEIsQ0FBQztBQUNwRCxPQUFPLEVBQUMsV0FBVyxFQUFFLFVBQVUsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBRXZELE9BQU8sRUFDTCxlQUFlLEVBQ2YsNkJBQTZCLEVBRTdCLGtCQUFrQixFQUNsQixZQUFZLEdBRWIsTUFBTSxjQUFjLENBQUM7QUFFdEI7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLHNCQUFzQixDQUFDLGVBQXVCO0lBQzVELG1EQUFtRDtJQUNuRCx3REFBd0Q7SUFDeEQsT0FBTyxlQUFlLEdBQUcsQ0FBQyxDQUFDO0FBQzdCLENBQUM7QUFFRCwwRkFBMEY7QUFDMUYsTUFBTSxVQUFVLHFCQUFxQixDQUFDLEtBQVksRUFBRSxLQUFZO0lBQzlELE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMzQixNQUFNLFNBQVMsR0FBRyxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdEQsU0FBUyxJQUFJLHNCQUFzQixDQUFDLEtBQUssRUFBRSxTQUFTLENBQUMsQ0FBQztJQUN0RCxPQUFPLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUMxQixDQUFDO0FBRUQsb0RBQW9EO0FBQ3BELE1BQU0sVUFBVSxxQkFBcUIsQ0FDbkMsS0FBWSxFQUNaLGVBQXVCLEVBQ3ZCLFFBQTRCO0lBRTVCLE1BQU0sS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFL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QUssTUFBTSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDMUIsYUFBYSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN6QixDQUFDO0lBRUQsc0VBQXNFO0lBQ3RFLDZCQUE2QjtJQUM3QixPQUFPLFdBQVcsQ0FBQyxNQUFNLEtBQUssYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBRSxLQUFLLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBTyxDQUFDO0FBQ3BHLENBQUM7QUFFRCx1RUFBdUU7QUFDdkUsTUFBTSxVQUFVLG9CQUFvQixDQUFDLEtBQVksRUFBRSxRQUE0QjtJQUM3RSxNQUFNLGFBQWEsR0FBRyxRQUFRLENBQUMsZ0JBQWdCLEdBQUcsYUFBYSxDQUFDO0lBQ2hFLE9BQU8sUUFBUSxDQUFDLEtBQUssRUFBRSxhQUFhLENBQW1CLENBQUM7QUFDMUQsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLFVBQVUsZ0NBQWdDLENBQUMsUUFBNEI7SUFDM0UsV0FBVyxDQUNULFFBQVEsQ0FBQyxZQUFZLEVBQ3JCLDZCQUE2QixDQUFDLFFBQVEsRUFDdEMsbURBQW1ELENBQ3BELENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsb0JBQW9CLENBQUMsS0FBYztJQUNqRCxPQUFPLENBQ0wsS0FBSyxLQUFLLElBQUk7UUFDZCxPQUFPLEtBQUssS0FBSyxRQUFRO1FBQ3pCLE9BQVEsS0FBNEIsQ0FBQyxnQkFBZ0IsS0FBSyxRQUFRLENBQ25FLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuZGV2L2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQge2Fzc2VydEluZGV4SW5EZWNsUmFuZ2V9IGZyb20gJy4uL3JlbmRlcjMvYXNzZXJ0JztcbmltcG9ydCB7RGVwZW5kZW5jeURlZn0gZnJvbSAnLi4vcmVuZGVyMy9pbnRlcmZhY2VzL2RlZmluaXRpb24nO1xuaW1wb3J0IHtUQ29udGFpbmVyTm9kZSwgVE5vZGV9IGZyb20gJy4uL3JlbmRlcjMvaW50ZXJmYWNlcy9ub2RlJztcbmltcG9ydCB7SEVBREVSX09GRlNFVCwgTFZpZXcsIFRWSUVXLCBUVmlld30gZnJvbSAnLi4vcmVuZGVyMy9pbnRlcmZhY2VzL3ZpZXcnO1xuaW1wb3J0IHtnZXRUTm9kZX0gZnJvbSAnLi4vcmVuZGVyMy91dGlsL3ZpZXdfdXRpbHMnO1xuaW1wb3J0IHthc3NlcnRFcXVhbCwgdGhyb3dFcnJvcn0gZnJvbSAnLi4vdXRpbC9hc3NlcnQnO1xuXG5pbXBvcnQge1xuICBEZWZlckJsb2NrU3RhdGUsXG4gIERlZmVyRGVwZW5kZW5jaWVzTG9hZGluZ1N0YXRlLFxuICBMRGVmZXJCbG9ja0RldGFpbHMsXG4gIExPQURJTkdfQUZURVJfU0xPVCxcbiAgTUlOSU1VTV9TTE9ULFxuICBURGVmZXJCbG9ja0RldGFpbHMsXG59IGZyb20gJy4vaW50ZXJmYWNlcyc7XG5cbi8qKlxuICogQ2FsY3VsYXRlcyBhIGRhdGEgc2xvdCBpbmRleCBmb3IgZGVmZXIgYmxvY2sgaW5mbyAoZWl0aGVyIHN0YXRpYyBvclxuICogaW5zdGFuY2Utc3BlY2lmaWMpLCBnaXZlbiBhbiBpbmRleCBvZiBhIGRlZmVyIGluc3RydWN0aW9uLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVmZXJCbG9ja0RhdGFJbmRleChkZWZlckJsb2NrSW5kZXg6IG51bWJlcikge1xuICAvLyBJbnN0YW5jZSBzdGF0ZSBpcyBsb2NhdGVkIGF0IHRoZSAqbmV4dCogcG9zaXRpb25cbiAgLy8gYWZ0ZXIgdGhlIGRlZmVyIGJsb2NrIHNsb3QgaW4gYW4gTFZpZXcgb3IgVFZpZXcuZGF0YS5cbiAgcmV0dXJuIGRlZmVyQmxvY2tJbmRleCArIDE7XG59XG5cbi8qKiBSZXRyaWV2ZXMgYSBkZWZlciBibG9jayBzdGF0ZSBmcm9tIGFuIExWaWV3LCBnaXZlbiBhIFROb2RlIHRoYXQgcmVwcmVzZW50cyBhIGJsb2NrLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldExEZWZlckJsb2NrRGV0YWlscyhsVmlldzogTFZpZXcsIHROb2RlOiBUTm9kZSk6IExEZWZlckJsb2NrRGV0YWlscyB7XG4gIGNvbnN0IHRWaWV3ID0gbFZpZXdbVFZJRVddO1xuICBjb25zdCBzbG90SW5kZXggPSBnZXREZWZlckJsb2NrRGF0YUluZGV4KHROb2RlLmluZGV4KTtcbiAgbmdEZXZNb2RlICYmIGFzc2VydEluZGV4SW5EZWNsUmFuZ2UodFZpZXcsIHNsb3RJbmRleCk7XG4gIHJldHVybiBsVmlld1tzbG90SW5kZXhdO1xufVxuXG4vKiogU3RvcmVzIGEgZGVmZXIgYmxvY2sgaW5zdGFuY2Ugc3RhdGUgaW4gTFZpZXcuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0TERlZmVyQmxvY2tEZXRhaWxzKFxuICBsVmlldzogTFZpZXcsXG4gIGRlZmVyQmxvY2tJbmRleDogbnVtYmVyLFxuICBsRGV0YWlsczogTERlZmVyQmxvY2tEZXRhaWxzLFxuKSB7XG4gIGNvbnN0IHRWaWV3ID0gbFZpZXdbVFZJRVddO1xuICBjb25zdCBzbG90SW5kZXggPSBnZXREZWZlckJsb2NrRGF0YUluZGV4KGRlZmVyQmxvY2tJbmRleCk7XG4gIG5nRGV2TW9kZSAmJiBhc3NlcnRJbmRleEluRGVjbFJhbmdlKHRWaWV3LCBzbG90SW5kZXgpO1xuICBsVmlld1tzbG90SW5kZXhdID0gbERldGFpbHM7XG59XG5cbi8qKiBSZXRyaWV2ZXMgc3RhdGljIGluZm8gYWJvdXQgYSBkZWZlciBibG9jaywgZ2l2ZW4gYSBUVmlldyBhbmQgYSBUTm9kZSB0aGF0IHJlcHJlc2VudHMgYSBibG9jay4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRURGVmZXJCbG9ja0RldGFpbHModFZpZXc6IFRWaWV3LCB0Tm9kZTogVE5vZGUpOiBURGVmZXJCbG9ja0RldGFpbHMge1xuICBjb25zdCBzbG90SW5kZXggPSBnZXREZWZlckJsb2NrRGF0YUluZGV4KHROb2RlLmluZGV4KTtcbiAgbmdEZXZNb2RlICYmIGFzc2VydEluZGV4SW5EZWNsUmFuZ2UodFZpZXcsIHNsb3RJbmRleCk7XG4gIHJldHVybiB0Vmlldy5kYXRhW3Nsb3RJbmRleF0gYXMgVERlZmVyQmxvY2tEZXRhaWxzO1xufVxuXG4vKiogU3RvcmVzIGEgZGVmZXIgYmxvY2sgc3RhdGljIGluZm8gaW4gYFRWaWV3LmRhdGFgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFREZWZlckJsb2NrRGV0YWlscyhcbiAgdFZpZXc6IFRWaWV3LFxuICBkZWZlckJsb2NrSW5kZXg6IG51bWJlcixcbiAgZGVmZXJCbG9ja0NvbmZpZzogVERlZmVyQmxvY2tEZXRhaWxzLFxuKSB7XG4gIGNvbnN0IHNsb3RJbmRleCA9IGdldERlZmVyQmxvY2tEYXRhSW5kZXgoZGVmZXJCbG9ja0luZGV4KTtcbiAgbmdEZXZNb2RlICYmIGFzc2VydEluZGV4SW5EZWNsUmFuZ2UodFZpZXcsIHNsb3RJbmRleCk7XG4gIHRWaWV3LmRhdGFbc2xvdEluZGV4XSA9IGRlZmVyQmxvY2tDb25maWc7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRUZW1wbGF0ZUluZGV4Rm9yU3RhdGUoXG4gIG5ld1N0YXRlOiBEZWZlckJsb2NrU3RhdGUsXG4gIGhvc3RMVmlldzogTFZpZXcsXG4gIHROb2RlOiBUTm9kZSxcbik6IG51bWJlciB8IG51bGwge1xuICBjb25zdCB0VmlldyA9IGhvc3RMVmlld1tUVklFV107XG4gIGNvbnN0IHREZXRhaWxzID0gZ2V0VERlZmVyQmxvY2tEZXRhaWxzKHRWaWV3LCB0Tm9kZSk7XG5cbiAgc3dpdGNoIChuZXdTdGF0ZSkge1xuICAgIGNhc2UgRGVmZXJCbG9ja1N0YXRlLkNvbXBsZXRlOlxuICAgICAgcmV0dXJuIHREZXRhaWxzLnByaW1hcnlUbXBsSW5kZXg7XG4gICAgY2FzZSBEZWZlckJsb2NrU3RhdGUuTG9hZGluZzpcbiAgICAgIHJldHVybiB0RGV0YWlscy5sb2FkaW5nVG1wbEluZGV4O1xuICAgIGNhc2UgRGVmZXJCbG9ja1N0YXRlLkVycm9yOlxuICAgICAgcmV0dXJuIHREZXRhaWxzLmVycm9yVG1wbEluZGV4O1xuICAgIGNhc2UgRGVmZXJCbG9ja1N0YXRlLlBsYWNlaG9sZGVyOlxuICAgICAgcmV0dXJuIHREZXRhaWxzLnBsYWNlaG9sZGVyVG1wbEluZGV4O1xuICAgIGRlZmF1bHQ6XG4gICAgICBuZ0Rldk1vZGUgJiYgdGhyb3dFcnJvcihgVW5leHBlY3RlZCBkZWZlciBibG9jayBzdGF0ZTogJHtuZXdTdGF0ZX1gKTtcbiAgICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyBhIG1pbmltdW0gYW1vdW50IG9mIHRpbWUgdGhhdCBhIGdpdmVuIHN0YXRlIHNob3VsZCBiZSByZW5kZXJlZCBmb3IsXG4gKiB0YWtpbmcgaW50byBhY2NvdW50IGBtaW5pbXVtYCBwYXJhbWV0ZXIgdmFsdWUuIElmIHRoZSBgbWluaW11bWAgdmFsdWUgaXNcbiAqIG5vdCBzcGVjaWZpZWQgLSByZXR1cm5zIGBudWxsYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE1pbmltdW1EdXJhdGlvbkZvclN0YXRlKFxuICB0RGV0YWlsczogVERlZmVyQmxvY2tEZXRhaWxzLFxuICBjdXJyZW50U3RhdGU6IERlZmVyQmxvY2tTdGF0ZSxcbik6IG51bWJlciB8IG51bGwge1xuICBpZiAoY3VycmVudFN0YXRlID09PSBEZWZlckJsb2NrU3RhdGUuUGxhY2Vob2xkZXIpIHtcbiAgICByZXR1cm4gdERldGFpbHMucGxhY2Vob2xkZXJCbG9ja0NvbmZpZz8uW01JTklNVU1fU0xPVF0gPz8gbnVsbDtcbiAgfSBlbHNlIGlmIChjdXJyZW50U3RhdGUgPT09IERlZmVyQmxvY2tTdGF0ZS5Mb2FkaW5nKSB7XG4gICAgcmV0dXJuIHREZXRhaWxzLmxvYWRpbmdCbG9ja0NvbmZpZz8uW01JTklNVU1fU0xPVF0gPz8gbnVsbDtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuLyoqIFJldHJpZXZlcyB0aGUgdmFsdWUgb2YgdGhlIGBhZnRlcmAgcGFyYW1ldGVyIG9uIHRoZSBAbG9hZGluZyBibG9jay4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRMb2FkaW5nQmxvY2tBZnRlcih0RGV0YWlsczogVERlZmVyQmxvY2tEZXRhaWxzKTogbnVtYmVyIHwgbnVsbCB7XG4gIHJldHVybiB0RGV0YWlscy5sb2FkaW5nQmxvY2tDb25maWc/LltMT0FESU5HX0FGVEVSX1NMT1RdID8/IG51bGw7XG59XG5cbi8qKlxuICogQWRkcyBkb3dubG9hZGVkIGRlcGVuZGVuY2llcyBpbnRvIGEgZGlyZWN0aXZlIG9yIGEgcGlwZSByZWdpc3RyeSxcbiAqIG1ha2luZyBzdXJlIHRoYXQgYSBkZXBlbmRlbmN5IGRvZXNuJ3QgeWV0IGV4aXN0IGluIHRoZSByZWdpc3RyeS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFkZERlcHNUb1JlZ2lzdHJ5PFQgZXh0ZW5kcyBEZXBlbmRlbmN5RGVmW10+KGN1cnJlbnREZXBzOiBUIHwgbnVsbCwgbmV3RGVwczogVCk6IFQge1xuICBpZiAoIWN1cnJlbnREZXBzIHx8IGN1cnJlbnREZXBzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBuZXdEZXBzO1xuICB9XG5cbiAgY29uc3QgY3VycmVudERlcFNldCA9IG5ldyBTZXQoY3VycmVudERlcHMpO1xuICBmb3IgKGNvbnN0IGRlcCBvZiBuZXdEZXBzKSB7XG4gICAgY3VycmVudERlcFNldC5hZGQoZGVwKTtcbiAgfVxuXG4gIC8vIElmIGBjdXJyZW50RGVwc2AgaXMgdGhlIHNhbWUgbGVuZ3RoLCB0aGVyZSB3ZXJlIG5vIG5ldyBkZXBzIGFuZCBjYW5cbiAgLy8gcmV0dXJuIHRoZSBvcmlnaW5hbCBhcnJheS5cbiAgcmV0dXJuIGN1cnJlbnREZXBzLmxlbmd0aCA9PT0gY3VycmVudERlcFNldC5zaXplID8gY3VycmVudERlcHMgOiAoQXJyYXkuZnJvbShjdXJyZW50RGVwU2V0KSBhcyBUKTtcbn1cblxuLyoqIFJldHJpZXZlcyBhIFROb2RlIHRoYXQgcmVwcmVzZW50cyBtYWluIGNvbnRlbnQgb2YgYSBkZWZlciBibG9jay4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRQcmltYXJ5QmxvY2tUTm9kZSh0VmlldzogVFZpZXcsIHREZXRhaWxzOiBURGVmZXJCbG9ja0RldGFpbHMpOiBUQ29udGFpbmVyTm9kZSB7XG4gIGNvbnN0IGFkanVzdGVkSW5kZXggPSB0RGV0YWlscy5wcmltYXJ5VG1wbEluZGV4ICsgSEVBREVSX09GRlNFVDtcbiAgcmV0dXJuIGdldFROb2RlKHRWaWV3LCBhZGp1c3RlZEluZGV4KSBhcyBUQ29udGFpbmVyTm9kZTtcbn1cblxuLyoqXG4gKiBBc3NlcnRzIHdoZXRoZXIgYWxsIGRlcGVuZGVuY2llcyBmb3IgYSBkZWZlciBibG9jayBhcmUgbG9hZGVkLlxuICogQWx3YXlzIHJ1biB0aGlzIGZ1bmN0aW9uIChpbiBkZXYgbW9kZSkgYmVmb3JlIHJlbmRlcmluZyBhIGRlZmVyXG4gKiBibG9jayBpbiBjb21wbGV0ZWQgc3RhdGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnREZWZlcnJlZERlcGVuZGVuY2llc0xvYWRlZCh0RGV0YWlsczogVERlZmVyQmxvY2tEZXRhaWxzKSB7XG4gIGFzc2VydEVxdWFsKFxuICAgIHREZXRhaWxzLmxvYWRpbmdTdGF0ZSxcbiAgICBEZWZlckRlcGVuZGVuY2llc0xvYWRpbmdTdGF0ZS5DT01QTEVURSxcbiAgICAnRXhwZWN0aW5nIGFsbCBkZWZlcnJlZCBkZXBlbmRlbmNpZXMgdG8gYmUgbG9hZGVkLicsXG4gICk7XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyBpZiBhIGdpdmVuIHZhbHVlIG1hdGNoZXMgdGhlIGV4cGVjdGVkIHN0cnVjdHVyZSBvZiBhIGRlZmVyIGJsb2NrXG4gKlxuICogV2UgY2FuIHNhZmVseSByZWx5IG9uIHRoZSBwcmltYXJ5VG1wbEluZGV4IGJlY2F1c2UgZXZlcnkgZGVmZXIgYmxvY2sgcmVxdWlyZXNcbiAqIHRoYXQgYSBwcmltYXJ5IHRlbXBsYXRlIGV4aXN0cy4gQWxsIHRoZSBvdGhlciB0ZW1wbGF0ZSBvcHRpb25zIGFyZSBvcHRpb25hbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVERlZmVyQmxvY2tEZXRhaWxzKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgVERlZmVyQmxvY2tEZXRhaWxzIHtcbiAgcmV0dXJuIChcbiAgICB2YWx1ZSAhPT0gbnVsbCAmJlxuICAgIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiZcbiAgICB0eXBlb2YgKHZhbHVlIGFzIFREZWZlckJsb2NrRGV0YWlscykucHJpbWFyeVRtcGxJbmRleCA9PT0gJ251bWJlcidcbiAgKTtcbn1cbiJdfQ==