All Downloads are FREE. Search and download functionalities are using the official Maven repository.

package.esm2022.src.utils.view_transition.mjs Maven / Gradle / Ivy

There is a newer version: 18.2.5
Show newest version
/**
 * @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.io/license
 */
/// 
import { DOCUMENT } from '@angular/common';
import { afterNextRender, InjectionToken, NgZone, runInInjectionContext, } from '@angular/core';
export const CREATE_VIEW_TRANSITION = new InjectionToken(ngDevMode ? 'view transition helper' : '');
export const VIEW_TRANSITION_OPTIONS = new InjectionToken(ngDevMode ? 'view transition options' : '');
/**
 * A helper function for using browser view transitions. This function skips the call to
 * `startViewTransition` if the browser does not support it.
 *
 * @returns A Promise that resolves when the view transition callback begins.
 */
export function createViewTransition(injector, from, to) {
    const transitionOptions = injector.get(VIEW_TRANSITION_OPTIONS);
    const document = injector.get(DOCUMENT);
    // Create promises outside the Angular zone to avoid causing extra change detections
    return injector.get(NgZone).runOutsideAngular(() => {
        if (!document.startViewTransition || transitionOptions.skipNextTransition) {
            transitionOptions.skipNextTransition = false;
            // The timing of `startViewTransition` is closer to a macrotask. It won't be called
            // until the current event loop exits so we use a promise resolved in a timeout instead
            // of Promise.resolve().
            return new Promise((resolve) => setTimeout(resolve));
        }
        let resolveViewTransitionStarted;
        const viewTransitionStarted = new Promise((resolve) => {
            resolveViewTransitionStarted = resolve;
        });
        const transition = document.startViewTransition(() => {
            resolveViewTransitionStarted();
            // We don't actually update dom within the transition callback. The resolving of the above
            // promise unblocks the Router navigation, which synchronously activates and deactivates
            // routes (the DOM update). This view transition waits for the next change detection to
            // complete (below), which includes the update phase of the routed components.
            return createRenderPromise(injector);
        });
        const { onViewTransitionCreated } = transitionOptions;
        if (onViewTransitionCreated) {
            runInInjectionContext(injector, () => onViewTransitionCreated({ transition, from, to }));
        }
        return viewTransitionStarted;
    });
}
/**
 * Creates a promise that resolves after next render.
 */
function createRenderPromise(injector) {
    return new Promise((resolve) => {
        // Wait for the microtask queue to empty after the next render happens (by waiting a macrotask).
        // This ensures any follow-up renders in the microtask queue are completed before the
        // view transition starts animating.
        afterNextRender({ read: () => setTimeout(resolve) }, { injector });
    });
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmlld190cmFuc2l0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvcm91dGVyL3NyYy91dGlscy92aWV3X3RyYW5zaXRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsOENBQThDO0FBRTlDLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQ0wsZUFBZSxFQUNmLGNBQWMsRUFFZCxNQUFNLEVBQ04scUJBQXFCLEdBQ3RCLE1BQU0sZUFBZSxDQUFDO0FBSXZCLE1BQU0sQ0FBQyxNQUFNLHNCQUFzQixHQUFHLElBQUksY0FBYyxDQUN0RCxTQUFTLENBQUMsQ0FBQyxDQUFDLHdCQUF3QixDQUFDLENBQUMsQ0FBQyxFQUFFLENBQzFDLENBQUM7QUFDRixNQUFNLENBQUMsTUFBTSx1QkFBdUIsR0FBRyxJQUFJLGNBQWMsQ0FFdkQsU0FBUyxDQUFDLENBQUMsQ0FBQyx5QkFBeUIsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7QUFtRTlDOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxRQUFrQixFQUNsQixJQUE0QixFQUM1QixFQUEwQjtJQUUxQixNQUFNLGlCQUFpQixHQUFHLFFBQVEsQ0FBQyxHQUFHLENBQUMsdUJBQXVCLENBQUMsQ0FBQztJQUNoRSxNQUFNLFFBQVEsR0FBRyxRQUFRLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3hDLG9GQUFvRjtJQUNwRixPQUFPLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsaUJBQWlCLENBQUMsR0FBRyxFQUFFO1FBQ2pELElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLElBQUksaUJBQWlCLENBQUMsa0JBQWtCLEVBQUUsQ0FBQztZQUMxRSxpQkFBaUIsQ0FBQyxrQkFBa0IsR0FBRyxLQUFLLENBQUM7WUFDN0MsbUZBQW1GO1lBQ25GLHVGQUF1RjtZQUN2Rix3QkFBd0I7WUFDeEIsT0FBTyxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7UUFDdkQsQ0FBQztRQUVELElBQUksNEJBQXdDLENBQUM7UUFDN0MsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLE9BQU8sQ0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQzFELDRCQUE0QixHQUFHLE9BQU8sQ0FBQztRQUN6QyxDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sVUFBVSxHQUFHLFFBQVEsQ0FBQyxtQkFBbUIsQ0FBQyxHQUFHLEVBQUU7WUFDbkQsNEJBQTRCLEVBQUUsQ0FBQztZQUMvQiwwRkFBMEY7WUFDMUYsd0ZBQXdGO1lBQ3hGLHVGQUF1RjtZQUN2Riw4RUFBOEU7WUFDOUUsT0FBTyxtQkFBbUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN2QyxDQUFDLENBQUMsQ0FBQztRQUNILE1BQU0sRUFBQyx1QkFBdUIsRUFBQyxHQUFHLGlCQUFpQixDQUFDO1FBQ3BELElBQUksdUJBQXVCLEVBQUUsQ0FBQztZQUM1QixxQkFBcUIsQ0FBQyxRQUFRLEVBQUUsR0FBRyxFQUFFLENBQUMsdUJBQXVCLENBQUMsRUFBQyxVQUFVLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBQyxDQUFDLENBQUMsQ0FBQztRQUN6RixDQUFDO1FBQ0QsT0FBTyxxQkFBcUIsQ0FBQztJQUMvQixDQUFDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRDs7R0FFRztBQUNILFNBQVMsbUJBQW1CLENBQUMsUUFBa0I7SUFDN0MsT0FBTyxJQUFJLE9BQU8sQ0FBTyxDQUFDLE9BQU8sRUFBRSxFQUFFO1FBQ25DLGdHQUFnRztRQUNoRyxxRkFBcUY7UUFDckYsb0NBQW9DO1FBQ3BDLGVBQWUsQ0FBQyxFQUFDLElBQUksRUFBRSxHQUFHLEVBQUUsQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLEVBQUMsRUFBRSxFQUFDLFFBQVEsRUFBQyxDQUFDLENBQUM7SUFDakUsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbi8vLyA8cmVmZXJlbmNlIHR5cGVzPVwiZG9tLXZpZXctdHJhbnNpdGlvbnNcIiAvPlxuXG5pbXBvcnQge0RPQ1VNRU5UfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHtcbiAgYWZ0ZXJOZXh0UmVuZGVyLFxuICBJbmplY3Rpb25Ub2tlbixcbiAgSW5qZWN0b3IsXG4gIE5nWm9uZSxcbiAgcnVuSW5JbmplY3Rpb25Db250ZXh0LFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHtBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90fSBmcm9tICcuLi9yb3V0ZXJfc3RhdGUnO1xuXG5leHBvcnQgY29uc3QgQ1JFQVRFX1ZJRVdfVFJBTlNJVElPTiA9IG5ldyBJbmplY3Rpb25Ub2tlbjx0eXBlb2YgY3JlYXRlVmlld1RyYW5zaXRpb24+KFxuICBuZ0Rldk1vZGUgPyAndmlldyB0cmFuc2l0aW9uIGhlbHBlcicgOiAnJyxcbik7XG5leHBvcnQgY29uc3QgVklFV19UUkFOU0lUSU9OX09QVElPTlMgPSBuZXcgSW5qZWN0aW9uVG9rZW48XG4gIFZpZXdUcmFuc2l0aW9uc0ZlYXR1cmVPcHRpb25zICYge3NraXBOZXh0VHJhbnNpdGlvbjogYm9vbGVhbn1cbj4obmdEZXZNb2RlID8gJ3ZpZXcgdHJhbnNpdGlvbiBvcHRpb25zJyA6ICcnKTtcblxuLyoqXG4gKiBPcHRpb25zIHRvIGNvbmZpZ3VyZSB0aGUgVmlldyBUcmFuc2l0aW9ucyBpbnRlZ3JhdGlvbiBpbiB0aGUgUm91dGVyLlxuICpcbiAqIEBleHBlcmltZW50YWxcbiAqIEBwdWJsaWNBcGlcbiAqIEBzZWUgd2l0aFZpZXdUcmFuc2l0aW9uc1xuICovXG5leHBvcnQgaW50ZXJmYWNlIFZpZXdUcmFuc2l0aW9uc0ZlYXR1cmVPcHRpb25zIHtcbiAgLyoqXG4gICAqIFNraXBzIHRoZSB2ZXJ5IGZpcnN0IGNhbGwgdG8gYHN0YXJ0Vmlld1RyYW5zaXRpb25gLiBUaGlzIGNhbiBiZSB1c2VmdWwgZm9yIGRpc2FibGluZyB0aGVcbiAgICogYW5pbWF0aW9uIGR1cmluZyB0aGUgYXBwbGljYXRpb24ncyBpbml0aWFsIGxvYWRpbmcgcGhhc2UuXG4gICAqL1xuICBza2lwSW5pdGlhbFRyYW5zaXRpb24/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBBIGZ1bmN0aW9uIHRvIHJ1biBhZnRlciB0aGUgYFZpZXdUcmFuc2l0aW9uYCBpcyBjcmVhdGVkLlxuICAgKlxuICAgKiBUaGlzIGZ1bmN0aW9uIGlzIHJ1biBpbiBhbiBpbmplY3Rpb24gY29udGV4dCBhbmQgY2FuIHVzZSBgaW5qZWN0YC5cbiAgICovXG4gIG9uVmlld1RyYW5zaXRpb25DcmVhdGVkPzogKHRyYW5zaXRpb25JbmZvOiBWaWV3VHJhbnNpdGlvbkluZm8pID0+IHZvaWQ7XG59XG5cbi8qKlxuICogVGhlIGluZm9ybWF0aW9uIHBhc3NlZCB0byB0aGUgYG9uVmlld1RyYW5zaXRpb25DcmVhdGVkYCBmdW5jdGlvbiBwcm92aWRlZCBpbiB0aGVcbiAqIGB3aXRoVmlld1RyYW5zaXRpb25zYCBmZWF0dXJlIG9wdGlvbnMuXG4gKlxuICogQHB1YmxpY0FwaVxuICogQGV4cGVyaW1lbnRhbFxuICovXG5leHBvcnQgaW50ZXJmYWNlIFZpZXdUcmFuc2l0aW9uSW5mbyB7XG4gIC8vIFRPRE8oYXRzY290dCk6IFRoaXMgdHlwZSBjYW4vc2hvdWxkIGJlIHRoZSBidWlsdC1pbiBgVmlld1RyYW5zaXRpb25gIHR5cGVcbiAgLy8gZnJvbSBAdHlwZXMvZG9tLXZpZXctdHJhbnNpdGlvbnMgYnV0IGV4cG9ydGluZyB0aGF0IHR5cGUgZnJvbSB0aGUgcHVibGljIEFQSSBpcyBjdXJyZW50bHkgbm90XG4gIC8vIHN1cHBvcnRlZCBieSB0b29saW5nLlxuICAvKipcbiAgICogVGhlIGBWaWV3VHJhbnNpdGlvbmAgcmV0dXJuZWQgYnkgdGhlIGNhbGwgdG8gYHN0YXJ0Vmlld1RyYW5zaXRpb25gLlxuICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9WaWV3VHJhbnNpdGlvblxuICAgKi9cbiAgdHJhbnNpdGlvbjoge1xuICAgIC8qKlxuICAgICAqIEBzZWUgaHR0cHM6Ly9kZXZlbG9wZXIubW96aWxsYS5vcmcvZW4tVVMvZG9jcy9XZWIvQVBJL1ZpZXdUcmFuc2l0aW9uL2ZpbmlzaGVkXG4gICAgICovXG4gICAgZmluaXNoZWQ6IFByb21pc2U8dm9pZD47XG4gICAgLyoqXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvVmlld1RyYW5zaXRpb24vcmVhZHlcbiAgICAgKi9cbiAgICByZWFkeTogUHJvbWlzZTx2b2lkPjtcbiAgICAvKipcbiAgICAgKiBAc2VlIGh0dHBzOi8vZGV2ZWxvcGVyLm1vemlsbGEub3JnL2VuLVVTL2RvY3MvV2ViL0FQSS9WaWV3VHJhbnNpdGlvbi91cGRhdGVDYWxsYmFja0RvbmVcbiAgICAgKi9cbiAgICB1cGRhdGVDYWxsYmFja0RvbmU6IFByb21pc2U8dm9pZD47XG4gICAgLyoqXG4gICAgICogQHNlZSBodHRwczovL2RldmVsb3Blci5tb3ppbGxhLm9yZy9lbi1VUy9kb2NzL1dlYi9BUEkvVmlld1RyYW5zaXRpb24vc2tpcFRyYW5zaXRpb25cbiAgICAgKi9cbiAgICBza2lwVHJhbnNpdGlvbigpOiB2b2lkO1xuICB9O1xuICAvKipcbiAgICogVGhlIGBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90YCB0aGF0IHRoZSBuYXZpZ2F0aW9uIGlzIHRyYW5zaXRpb25pbmcgZnJvbS5cbiAgICovXG4gIGZyb206IEFjdGl2YXRlZFJvdXRlU25hcHNob3Q7XG4gIC8qKlxuICAgKiBUaGUgYEFjdGl2YXRlZFJvdXRlU25hcHNob3RgIHRoYXQgdGhlIG5hdmlnYXRpb24gaXMgdHJhbnNpdGlvbmluZyB0by5cbiAgICovXG4gIHRvOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90O1xufVxuXG4vKipcbiAqIEEgaGVscGVyIGZ1bmN0aW9uIGZvciB1c2luZyBicm93c2VyIHZpZXcgdHJhbnNpdGlvbnMuIFRoaXMgZnVuY3Rpb24gc2tpcHMgdGhlIGNhbGwgdG9cbiAqIGBzdGFydFZpZXdUcmFuc2l0aW9uYCBpZiB0aGUgYnJvd3NlciBkb2VzIG5vdCBzdXBwb3J0IGl0LlxuICpcbiAqIEByZXR1cm5zIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIHZpZXcgdHJhbnNpdGlvbiBjYWxsYmFjayBiZWdpbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVWaWV3VHJhbnNpdGlvbihcbiAgaW5qZWN0b3I6IEluamVjdG9yLFxuICBmcm9tOiBBY3RpdmF0ZWRSb3V0ZVNuYXBzaG90LFxuICB0bzogQWN0aXZhdGVkUm91dGVTbmFwc2hvdCxcbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB0cmFuc2l0aW9uT3B0aW9ucyA9IGluamVjdG9yLmdldChWSUVXX1RSQU5TSVRJT05fT1BUSU9OUyk7XG4gIGNvbnN0IGRvY3VtZW50ID0gaW5qZWN0b3IuZ2V0KERPQ1VNRU5UKTtcbiAgLy8gQ3JlYXRlIHByb21pc2VzIG91dHNpZGUgdGhlIEFuZ3VsYXIgem9uZSB0byBhdm9pZCBjYXVzaW5nIGV4dHJhIGNoYW5nZSBkZXRlY3Rpb25zXG4gIHJldHVybiBpbmplY3Rvci5nZXQoTmdab25lKS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgaWYgKCFkb2N1bWVudC5zdGFydFZpZXdUcmFuc2l0aW9uIHx8IHRyYW5zaXRpb25PcHRpb25zLnNraXBOZXh0VHJhbnNpdGlvbikge1xuICAgICAgdHJhbnNpdGlvbk9wdGlvbnMuc2tpcE5leHRUcmFuc2l0aW9uID0gZmFsc2U7XG4gICAgICAvLyBUaGUgdGltaW5nIG9mIGBzdGFydFZpZXdUcmFuc2l0aW9uYCBpcyBjbG9zZXIgdG8gYSBtYWNyb3Rhc2suIEl0IHdvbid0IGJlIGNhbGxlZFxuICAgICAgLy8gdW50aWwgdGhlIGN1cnJlbnQgZXZlbnQgbG9vcCBleGl0cyBzbyB3ZSB1c2UgYSBwcm9taXNlIHJlc29sdmVkIGluIGEgdGltZW91dCBpbnN0ZWFkXG4gICAgICAvLyBvZiBQcm9taXNlLnJlc29sdmUoKS5cbiAgICAgIHJldHVybiBuZXcgUHJvbWlzZSgocmVzb2x2ZSkgPT4gc2V0VGltZW91dChyZXNvbHZlKSk7XG4gICAgfVxuXG4gICAgbGV0IHJlc29sdmVWaWV3VHJhbnNpdGlvblN0YXJ0ZWQ6ICgpID0+IHZvaWQ7XG4gICAgY29uc3Qgdmlld1RyYW5zaXRpb25TdGFydGVkID0gbmV3IFByb21pc2U8dm9pZD4oKHJlc29sdmUpID0+IHtcbiAgICAgIHJlc29sdmVWaWV3VHJhbnNpdGlvblN0YXJ0ZWQgPSByZXNvbHZlO1xuICAgIH0pO1xuICAgIGNvbnN0IHRyYW5zaXRpb24gPSBkb2N1bWVudC5zdGFydFZpZXdUcmFuc2l0aW9uKCgpID0+IHtcbiAgICAgIHJlc29sdmVWaWV3VHJhbnNpdGlvblN0YXJ0ZWQoKTtcbiAgICAgIC8vIFdlIGRvbid0IGFjdHVhbGx5IHVwZGF0ZSBkb20gd2l0aGluIHRoZSB0cmFuc2l0aW9uIGNhbGxiYWNrLiBUaGUgcmVzb2x2aW5nIG9mIHRoZSBhYm92ZVxuICAgICAgLy8gcHJvbWlzZSB1bmJsb2NrcyB0aGUgUm91dGVyIG5hdmlnYXRpb24sIHdoaWNoIHN5bmNocm9ub3VzbHkgYWN0aXZhdGVzIGFuZCBkZWFjdGl2YXRlc1xuICAgICAgLy8gcm91dGVzICh0aGUgRE9NIHVwZGF0ZSkuIFRoaXMgdmlldyB0cmFuc2l0aW9uIHdhaXRzIGZvciB0aGUgbmV4dCBjaGFuZ2UgZGV0ZWN0aW9uIHRvXG4gICAgICAvLyBjb21wbGV0ZSAoYmVsb3cpLCB3aGljaCBpbmNsdWRlcyB0aGUgdXBkYXRlIHBoYXNlIG9mIHRoZSByb3V0ZWQgY29tcG9uZW50cy5cbiAgICAgIHJldHVybiBjcmVhdGVSZW5kZXJQcm9taXNlKGluamVjdG9yKTtcbiAgICB9KTtcbiAgICBjb25zdCB7b25WaWV3VHJhbnNpdGlvbkNyZWF0ZWR9ID0gdHJhbnNpdGlvbk9wdGlvbnM7XG4gICAgaWYgKG9uVmlld1RyYW5zaXRpb25DcmVhdGVkKSB7XG4gICAgICBydW5JbkluamVjdGlvbkNvbnRleHQoaW5qZWN0b3IsICgpID0+IG9uVmlld1RyYW5zaXRpb25DcmVhdGVkKHt0cmFuc2l0aW9uLCBmcm9tLCB0b30pKTtcbiAgICB9XG4gICAgcmV0dXJuIHZpZXdUcmFuc2l0aW9uU3RhcnRlZDtcbiAgfSk7XG59XG5cbi8qKlxuICogQ3JlYXRlcyBhIHByb21pc2UgdGhhdCByZXNvbHZlcyBhZnRlciBuZXh0IHJlbmRlci5cbiAqL1xuZnVuY3Rpb24gY3JlYXRlUmVuZGVyUHJvbWlzZShpbmplY3RvcjogSW5qZWN0b3IpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlPHZvaWQ+KChyZXNvbHZlKSA9PiB7XG4gICAgLy8gV2FpdCBmb3IgdGhlIG1pY3JvdGFzayBxdWV1ZSB0byBlbXB0eSBhZnRlciB0aGUgbmV4dCByZW5kZXIgaGFwcGVucyAoYnkgd2FpdGluZyBhIG1hY3JvdGFzaykuXG4gICAgLy8gVGhpcyBlbnN1cmVzIGFueSBmb2xsb3ctdXAgcmVuZGVycyBpbiB0aGUgbWljcm90YXNrIHF1ZXVlIGFyZSBjb21wbGV0ZWQgYmVmb3JlIHRoZVxuICAgIC8vIHZpZXcgdHJhbnNpdGlvbiBzdGFydHMgYW5pbWF0aW5nLlxuICAgIGFmdGVyTmV4dFJlbmRlcih7cmVhZDogKCkgPT4gc2V0VGltZW91dChyZXNvbHZlKX0sIHtpbmplY3Rvcn0pO1xuICB9KTtcbn1cbiJdfQ==




© 2015 - 2024 Weber Informatics LLC | Privacy Policy