UNPKG

angular-archwizard

Version:

An Angular 9+ module containing a wizard component and its supporting components and directives

164 lines 22.3 kB
import { MovingDirection } from '../util/moving-direction.enum'; /** * Base implementation of [[NavigationMode]] * * Note: Built-in [[NavigationMode]] classes should be stateless, allowing the library user to easily create * an instance of a particular [[NavigationMode]] class and pass it to `<aw-wizard [navigationMode]="...">`. * * @author Marc Arndt */ export class BaseNavigationMode { /** * Checks, whether a wizard step, as defined by the given destination index, can be transitioned to. * * This method controls navigation by [[goToStep]], [[goToPreviousStep]], and [[goToNextStep]] directives. * Navigation by navigation bar is governed by [[isNavigable]]. * * In this implementation, a destination wizard step can be entered if: * - it exists * - the current step can be exited in the direction of the destination step * - the destination step can be entered in the direction from the current step * * Subclasses can impose additional restrictions, see [[canTransitionToStep]]. * * @param wizard The wizard component to operate on * @param destinationIndex The index of the destination step * @returns A [[Promise]] containing `true`, if the destination step can be transitioned to and `false` otherwise */ canGoToStep(wizard, destinationIndex) { const hasStep = wizard.hasStep(destinationIndex); const movingDirection = wizard.getMovingDirection(destinationIndex); const canExitCurrentStep = (previous) => { return previous && wizard.currentStep.canExitStep(movingDirection); }; const canEnterDestinationStep = (previous) => { return previous && wizard.getStepAtIndex(destinationIndex).canEnterStep(movingDirection); }; const canTransitionToStep = (previous) => { return previous && this.canTransitionToStep(wizard, destinationIndex); }; return Promise.resolve(hasStep) .then(canTransitionToStep) // Apply user-defined checks at the end. They can involve user interaction // which is better to be avoided if navigation mode does not actually allow the transition // (`canTransitionToStep` returns `false`). .then(canExitCurrentStep) .then(canEnterDestinationStep); } /** * Imposes additional restrictions for `canGoToStep` in current navigation mode. * * The base implementation allows transition iff the given step is navigable from the navigation bar (see `isNavigable`). * However, in some navigation modes `canTransitionToStep` can be more relaxed to allow navigation to certain steps * by previous/next buttons, but not using the navigation bar. * * @param wizard The wizard component to operate on * @param destinationIndex The index of the destination step * @returns `true`, if the destination step can be transitioned to and `false` otherwise */ canTransitionToStep(wizard, destinationIndex) { return this.isNavigable(wizard, destinationIndex); } /** * Tries to transition to the wizard step, as denoted by the given destination index. * * When entering the destination step, the following actions are done: * - the old current step is set as completed * - the old current step is set as unselected * - the old current step is exited * - the destination step is set as selected * - the destination step is entered * * When the destination step couldn't be entered, the following actions are done: * - the current step is exited and entered in the direction `MovingDirection.Stay` * * @param wizard The wizard component to operate on * @param destinationIndex The index of the destination wizard step, which should be entered * @param preFinalize An event emitter, to be called before the step has been transitioned * @param postFinalize An event emitter, to be called after the step has been transitioned */ goToStep(wizard, destinationIndex, preFinalize, postFinalize) { this.canGoToStep(wizard, destinationIndex).then(navigationAllowed => { if (navigationAllowed) { // the current step can be exited in the given direction const movingDirection = wizard.getMovingDirection(destinationIndex); /* istanbul ignore if */ if (preFinalize) { preFinalize.emit(); } // leave current step wizard.currentStep.completed = true; wizard.currentStep.exit(movingDirection); wizard.currentStep.editing = false; wizard.currentStep.selected = false; this.transition(wizard, destinationIndex); // remember if the next step is already completed before entering it to properly set `editing` flag const wasCompleted = wizard.completed || wizard.currentStep.completed; // go to next step wizard.currentStep.enter(movingDirection); wizard.currentStep.selected = true; if (wasCompleted) { wizard.currentStep.editing = true; } /* istanbul ignore if */ if (postFinalize) { postFinalize.emit(); } } else { // if the current step can't be left, reenter the current step wizard.currentStep.exit(MovingDirection.Stay); wizard.currentStep.enter(MovingDirection.Stay); } }); } /** * Transitions the wizard to the given step index. * * Can perform additional actions in particular navigation mode implementations. * * @param wizard The wizard component to operate on * @param destinationIndex The index of the destination wizard step */ transition(wizard, destinationIndex) { wizard.currentStepIndex = destinationIndex; } /** * Resets the state of this wizard. * * A reset transitions the wizard automatically to the first step and sets all steps as incomplete. * In addition the whole wizard is set as incomplete. * * @param wizard The wizard component to operate on */ reset(wizard) { this.ensureCanReset(wizard); // reset the step internal state wizard.wizardSteps.forEach(step => { step.completed = step.initiallyCompleted; step.selected = false; step.editing = false; }); // set the first step as the current step wizard.currentStepIndex = wizard.defaultStepIndex; wizard.currentStep.selected = true; wizard.currentStep.enter(MovingDirection.Forwards); } /** * Checks if wizard configuration allows to perform reset. * * A check failure is indicated by throwing an `Error` with the message discribing the discovered misconfiguration issue. * * Can include additional checks in particular navigation mode implementations. * * @param wizard The wizard component to operate on * @throws An `Error` is thrown, if a micconfiguration issue is discovered. */ ensureCanReset(wizard) { // the wizard doesn't contain a step with the default step index if (!wizard.hasStep(wizard.defaultStepIndex)) { throw new Error(`The wizard doesn't contain a step with index ${wizard.defaultStepIndex}`); } } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFzZS1uYXZpZ2F0aW9uLW1vZGUuaW50ZXJmYWNlLmpzIiwic291cmNlUm9vdCI6Im5nOi8vYW5ndWxhci1hcmNod2l6YXJkLyIsInNvdXJjZXMiOlsibGliL25hdmlnYXRpb24vYmFzZS1uYXZpZ2F0aW9uLW1vZGUuaW50ZXJmYWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSwrQkFBK0IsQ0FBQztBQUk5RDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxPQUFnQixrQkFBa0I7SUFFdEM7Ozs7Ozs7Ozs7Ozs7Ozs7T0FnQkc7SUFDSSxXQUFXLENBQUMsTUFBdUIsRUFBRSxnQkFBd0I7UUFDbEUsTUFBTSxPQUFPLEdBQUcsTUFBTSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBRWpELE1BQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxrQkFBa0IsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1FBRXBFLE1BQU0sa0JBQWtCLEdBQUcsQ0FBQyxRQUFpQixFQUFFLEVBQUU7WUFDL0MsT0FBTyxRQUFRLElBQUksTUFBTSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsZUFBZSxDQUFDLENBQUM7UUFDckUsQ0FBQyxDQUFDO1FBRUYsTUFBTSx1QkFBdUIsR0FBRyxDQUFDLFFBQWlCLEVBQUUsRUFBRTtZQUNwRCxPQUFPLFFBQVEsSUFBSSxNQUFNLENBQUMsY0FBYyxDQUFDLGdCQUFnQixDQUFDLENBQUMsWUFBWSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzNGLENBQUMsQ0FBQztRQUVGLE1BQU0sbUJBQW1CLEdBQUcsQ0FBQyxRQUFpQixFQUFFLEVBQUU7WUFDaEQsT0FBTyxRQUFRLElBQUksSUFBSSxDQUFDLG1CQUFtQixDQUFDLE1BQU0sRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3hFLENBQUMsQ0FBQztRQUVGLE9BQU8sT0FBTyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUM7YUFDNUIsSUFBSSxDQUFDLG1CQUFt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Q0FBQyxnQkFBZ0IsQ0FBQztRQUNsRCxNQUFNLENBQUMsV0FBVyxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUM7UUFDbkMsTUFBTSxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3JELENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDTyxjQUFjLENBQUMsTUFBdUI7UUFDOUMsZ0VBQWdFO1FBQ2hFLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxFQUFFO1lBQzVDLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELE1BQU0sQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7U0FDNUY7SUFDSCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0V2ZW50RW1pdHRlcn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQge01vdmluZ0RpcmVjdGlvbn0gZnJvbSAnLi4vdXRpbC9tb3ZpbmctZGlyZWN0aW9uLmVudW0nO1xuaW1wb3J0IHtOYXZpZ2F0aW9uTW9kZX0gZnJvbSAnLi9uYXZpZ2F0aW9uLW1vZGUuaW50ZXJmYWNlJztcbmltcG9ydCB7V2l6YXJkQ29tcG9uZW50fSBmcm9tICcuLi9jb21wb25lbnRzL3dpemFyZC5jb21wb25lbnQnO1xuXG4vKipcbiAqIEJhc2UgaW1wbGVtZW50YXRpb24gb2YgW1tOYXZpZ2F0aW9uTW9kZV1dXG4gKlxuICogTm90ZTogQnVpbHQtaW4gW1tOYXZpZ2F0aW9uTW9kZV1dIGNsYXNzZXMgc2hvdWxkIGJlIHN0YXRlbGVzcywgYWxsb3dpbmcgdGhlIGxpYnJhcnkgdXNlciB0byBlYXNpbHkgY3JlYXRlXG4gKiBhbiBpbnN0YW5jZSBvZiBhIHBhcnRpY3VsYXIgW1tOYXZpZ2F0aW9uTW9kZV1dIGNsYXNzIGFuZCBwYXNzIGl0IHRvIGA8YXctd2l6YXJkIFtuYXZpZ2F0aW9uTW9kZV09XCIuLi5cIj5gLlxuICpcbiAqIEBhdXRob3IgTWFyYyBBcm5kdFxuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZU5hdmlnYXRpb25Nb2RlIGltcGxlbWVudHMgTmF2aWdhdGlvbk1vZGUge1xuXG4gIC8qKlxuICAgKiBDaGVja3MsIHdoZXRoZXIgYSB3aXphcmQgc3RlcCwgYXMgZGVmaW5lZCBieSB0aGUgZ2l2ZW4gZGVzdGluYXRpb24gaW5kZXgsIGNhbiBiZSB0cmFuc2l0aW9uZWQgdG8uXG4gICAqXG4gICAqIFRoaXMgbWV0aG9kIGNvbnRyb2xzIG5hdmlnYXRpb24gYnkgW1tnb1RvU3RlcF1dLCBbW2dvVG9QcmV2aW91c1N0ZXBdXSwgYW5kIFtbZ29Ub05leHRTdGVwXV0gZGlyZWN0aXZlcy5cbiAgICogTmF2aWdhdGlvbiBieSBuYXZpZ2F0aW9uIGJhciBpcyBnb3Zlcm5lZCBieSBbW2lzTmF2aWdhYmxlXV0uXG4gICAqXG4gICAqIEluIHRoaXMgaW1wbGVtZW50YXRpb24sIGEgZGVzdGluYXRpb24gd2l6YXJkIHN0ZXAgY2FuIGJlIGVudGVyZWQgaWY6XG4gICAqIC0gaXQgZXhpc3RzXG4gICAqIC0gdGhlIGN1cnJlbnQgc3RlcCBjYW4gYmUgZXhpdGVkIGluIHRoZSBkaXJlY3Rpb24gb2YgdGhlIGRlc3RpbmF0aW9uIHN0ZXBcbiAgICogLSB0aGUgZGVzdGluYXRpb24gc3RlcCBjYW4gYmUgZW50ZXJlZCBpbiB0aGUgZGlyZWN0aW9uIGZyb20gdGhlIGN1cnJlbnQgc3RlcFxuICAgKlxuICAgKiBTdWJjbGFzc2VzIGNhbiBpbXBvc2UgYWRkaXRpb25hbCByZXN0cmljdGlvbnMsIHNlZSBbW2NhblRyYW5zaXRpb25Ub1N0ZXBdXS5cbiAgICpcbiAgICogQHBhcmFtIHdpemFyZCBUaGUgd2l6YXJkIGNvbXBvbmVudCB0byBvcGVyYXRlIG9uXG4gICAqIEBwYXJhbSBkZXN0aW5hdGlvbkluZGV4IFRoZSBpbmRleCBvZiB0aGUgZGVzdGluYXRpb24gc3RlcFxuICAgKiBAcmV0dXJucyBBIFtbUHJvbWlzZV1dIGNvbnRhaW5pbmcgYHRydWVgLCBpZiB0aGUgZGVzdGluYXRpb24gc3RlcCBjYW4gYmUgdHJhbnNpdGlvbmVkIHRvIGFuZCBgZmFsc2VgIG90aGVyd2lzZVxuICAgKi9cbiAgcHVibGljIGNhbkdvVG9TdGVwKHdpemFyZDogV2l6YXJkQ29tcG9uZW50LCBkZXN0aW5hdGlvbkluZGV4OiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBoYXNTdGVwID0gd2l6YXJkLmhhc1N0ZXAoZGVzdGluYXRpb25JbmRleCk7XG5cbiAgICBjb25zdCBtb3ZpbmdEaXJlY3Rpb24gPSB3aXphcmQuZ2V0TW92aW5nRGlyZWN0aW9uKGRlc3RpbmF0aW9uSW5kZXgpO1xuXG4gICAgY29uc3QgY2FuRXhpdEN1cnJlbnRTdGVwID0gKHByZXZpb3VzOiBib29sZWFuKSA9PiB7XG4gICAgICByZXR1cm4gcHJldmlvdXMgJiYgd2l6YXJkLmN1cnJlbnRTdGVwLmNhbkV4aXRTdGVwKG1vdmluZ0RpcmVjdGlvbik7XG4gICAgfTtcblxuICAgIGNvbnN0IGNhbkVudGVyRGVzdGluYXRpb25TdGVwID0gKHByZXZpb3VzOiBib29sZWFuKSA9PiB7XG4gICAgICByZXR1cm4gcHJldmlvdXMgJiYgd2l6YXJkLmdldFN0ZXBBdEluZGV4KGRlc3RpbmF0aW9uSW5kZXgpLmNhbkVudGVyU3RlcChtb3ZpbmdEaXJlY3Rpb24pO1xuICAgIH07XG5cbiAgICBjb25zdCBjYW5UcmFuc2l0aW9uVG9TdGVwID0gKHByZXZpb3VzOiBib29sZWFuKSA9PiB7XG4gICAgICByZXR1cm4gcHJldmlvdXMgJiYgdGhpcy5jYW5UcmFuc2l0aW9uVG9TdGVwKHdpemFyZCwgZGVzdGluYXRpb25JbmRleCk7XG4gICAgfTtcblxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoaGFzU3RlcClcbiAgICAgIC50aGVuKGNhblRyYW5zaXRpb25Ub1N0ZXApXG4gICAgICAvLyBBcHBseSB1c2VyLWRlZmluZWQgY2hlY2tzIGF0IHRoZSBlbmQuICBUaGV5IGNhbiBpbnZvbHZlIHVzZXIgaW50ZXJhY3Rpb25cbiAgICAgIC8vIHdoaWNoIGlzIGJldHRlciB0byBiZSBhdm9pZGVkIGlmIG5hdmlnYXRpb24gbW9kZSBkb2VzIG5vdCBhY3R1YWxseSBhbGxvdyB0aGUgdHJhbnNpdGlvblxuICAgICAgLy8gKGBjYW5UcmFuc2l0aW9uVG9TdGVwYCByZXR1cm5zIGBmYWxzZWApLlxuICAgICAgLnRoZW4oY2FuRXhpdEN1cnJlbnRTdGVwKVxuICAgICAgLnRoZW4oY2FuRW50ZXJEZXN0aW5hdGlvblN0ZXApO1xuICB9XG5cbiAgLyoqXG4gICAqIEltcG9zZXMgYWRkaXRpb25hbCByZXN0cmljdGlvbnMgZm9yIGBjYW5Hb1RvU3RlcGAgaW4gY3VycmVudCBuYXZpZ2F0aW9uIG1vZGUuXG4gICAqXG4gICAqIFRoZSBiYXNlIGltcGxlbWVudGF0aW9uIGFsbG93cyB0cmFuc2l0aW9uIGlmZiB0aGUgZ2l2ZW4gc3RlcCBpcyBuYXZpZ2FibGUgZnJvbSB0aGUgbmF2aWdhdGlvbiBiYXIgKHNlZSBgaXNOYXZpZ2FibGVgKS5cbiAgICogSG93ZXZlciwgaW4gc29tZSBuYXZpZ2F0aW9uIG1vZGVzIGBjYW5UcmFuc2l0aW9uVG9TdGVwYCBjYW4gYmUgbW9yZSByZWxheGVkIHRvIGFsbG93IG5hdmlnYXRpb24gdG8gY2VydGFpbiBzdGVwc1xuICAgKiBieSBwcmV2aW91cy9uZXh0IGJ1dHRvbnMsIGJ1dCBub3QgdXNpbmcgdGhlIG5hdmlnYXRpb24gYmFyLlxuICAgKlxuICAgKiBAcGFyYW0gd2l6YXJkIFRoZSB3aXphcmQgY29tcG9uZW50IHRvIG9wZXJhdGUgb25cbiAgICogQHBhcmFtIGRlc3RpbmF0aW9uSW5kZXggVGhlIGluZGV4IG9mIHRoZSBkZXN0aW5hdGlvbiBzdGVwXG4gICAqIEByZXR1cm5zIGB0cnVlYCwgaWYgdGhlIGRlc3RpbmF0aW9uIHN0ZXAgY2FuIGJlIHRyYW5zaXRpb25lZCB0byBhbmQgYGZhbHNlYCBvdGhlcndpc2VcbiAgICovXG4gIHByb3RlY3RlZCBjYW5UcmFuc2l0aW9uVG9TdGVwKHdpemFyZDogV2l6YXJkQ29tcG9uZW50LCBkZXN0aW5hdGlvbkluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5pc05hdmlnYWJsZSh3aXphcmQsIGRlc3RpbmF0aW9uSW5kZXgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyaWVzIHRvIHRyYW5zaXRpb24gdG8gdGhlIHdpemFyZCBzdGVwLCBhcyBkZW5vdGVkIGJ5IHRoZSBnaXZlbiBkZXN0aW5hdGlvbiBpbmRleC5cbiAgICpcbiAgICogV2hlbiBlbnRlcmluZyB0aGUgZGVzdGluYXRpb24gc3RlcCwgdGhlIGZvbGxvd2luZyBhY3Rpb25zIGFyZSBkb25lOlxuICAgKiAtIHRoZSBvbGQgY3VycmVudCBzdGVwIGlzIHNldCBhcyBjb21wbGV0ZWRcbiAgICogLSB0aGUgb2xkIGN1cnJlbnQgc3RlcCBpcyBzZXQgYXMgdW5zZWxlY3RlZFxuICAgKiAtIHRoZSBvbGQgY3VycmVudCBzdGVwIGlzIGV4aXRlZFxuICAgKiAtIHRoZSBkZXN0aW5hdGlvbiBzdGVwIGlzIHNldCBhcyBzZWxlY3RlZFxuICAgKiAtIHRoZSBkZXN0aW5hdGlvbiBzdGVwIGlzIGVudGVyZWRcbiAgICpcbiAgICogV2hlbiB0aGUgZGVzdGluYXRpb24gc3RlcCBjb3VsZG4ndCBiZSBlbnRlcmVkLCB0aGUgZm9sbG93aW5nIGFjdGlvbnMgYXJlIGRvbmU6XG4gICAqIC0gdGhlIGN1cnJlbnQgc3RlcCBpcyBleGl0ZWQgYW5kIGVudGVyZWQgaW4gdGhlIGRpcmVjdGlvbiBgTW92aW5nRGlyZWN0aW9uLlN0YXlgXG4gICAqXG4gICAqIEBwYXJhbSB3aXphcmQgVGhlIHdpemFyZCBjb21wb25lbnQgdG8gb3BlcmF0ZSBvblxuICAgKiBAcGFyYW0gZGVzdGluYXRpb25JbmRleCBUaGUgaW5kZXggb2YgdGhlIGRlc3RpbmF0aW9uIHdpemFyZCBzdGVwLCB3aGljaCBzaG91bGQgYmUgZW50ZXJlZFxuICAgKiBAcGFyYW0gcHJlRmluYWxpemUgQW4gZXZlbnQgZW1pdHRlciwgdG8gYmUgY2FsbGVkIGJlZm9yZSB0aGUgc3RlcCBoYXMgYmVlbiB0cmFuc2l0aW9uZWRcbiAgICogQHBhcmFtIHBvc3RGaW5hbGl6ZSBBbiBldmVudCBlbWl0dGVyLCB0byBiZSBjYWxsZWQgYWZ0ZXIgdGhlIHN0ZXAgaGFzIGJlZW4gdHJhbnNpdGlvbmVkXG4gICAqL1xuICBwdWJsaWMgZ29Ub1N0ZXAoXG4gICAgd2l6YXJkOiBXaXphcmRDb21wb25lbnQsXG4gICAgZGVzdGluYXRpb25JbmRleDogbnVtYmVyLFxuICAgIHByZUZpbmFsaXplPzogRXZlbnRFbWl0dGVyPHZvaWQ+LFxuICAgIHBvc3RGaW5hbGl6ZT86IEV2ZW50RW1pdHRlcjx2b2lkPik6IHZvaWQge1xuXG4gICAgdGhpcy5jYW5Hb1RvU3RlcCh3aXphcmQsIGRlc3RpbmF0aW9uSW5kZXgpLnRoZW4obmF2aWdhdGlvbkFsbG93ZWQgPT4ge1xuICAgICAgaWYgKG5hdmlnYXRpb25BbGxvd2VkKSB7XG4gICAgICAgIC8vIHRoZSBjdXJyZW50IHN0ZXAgY2FuIGJlIGV4aXRlZCBpbiB0aGUgZ2l2ZW4gZGlyZWN0aW9uXG4gICAgICAgIGNvbnN0IG1vdmluZ0RpcmVjdGlvbjogTW92aW5nRGlyZWN0aW9uID0gd2l6YXJkLmdldE1vdmluZ0RpcmVjdGlvbihkZXN0aW5hdGlvbkluZGV4KTtcblxuICAgICAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgaWYgKi9cbiAgICAgICAgaWYgKHByZUZpbmFsaXplKSB7XG4gICAgICAgICAgcHJlRmluYWxpemUuZW1pdCgpO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gbGVhdmUgY3VycmVudCBzdGVwXG4gICAgICAgIHdpemFyZC5jdXJyZW50U3RlcC5jb21wbGV0ZWQgPSB0cnVlO1xuICAgICAgICB3aXphcmQuY3VycmVudFN0ZXAuZXhpdChtb3ZpbmdEaXJlY3Rpb24pO1xuICAgICAgICB3aXphcmQuY3VycmVudFN0ZXAuZWRpdGluZyA9IGZhbHNlO1xuICAgICAgICB3aXphcmQuY3VycmVudFN0ZXAuc2VsZWN0ZWQgPSBmYWxzZTtcblxuICAgICAgICB0aGlzLnRyYW5zaXRpb24od2l6YXJkLCBkZXN0aW5hdGlvbkluZGV4KTtcblxuICAgICAgICAvLyByZW1lbWJlciBpZiB0aGUgbmV4dCBzdGVwIGlzIGFscmVhZHkgY29tcGxldGVkIGJlZm9yZSBlbnRlcmluZyBpdCB0byBwcm9wZXJseSBzZXQgYGVkaXRpbmdgIGZsYWdcbiAgICAgICAgY29uc3Qgd2FzQ29tcGxldGVkID0gd2l6YXJkLmNvbXBsZXRlZCB8fCB3aXphcmQuY3VycmVudFN0ZXAuY29tcGxldGVkO1xuXG4gICAgICAgIC8vIGdvIHRvIG5leHQgc3RlcFxuICAgICAgICB3aXphcmQuY3VycmVudFN0ZXAuZW50ZXIobW92aW5nRGlyZWN0aW9uKTtcbiAgICAgICAgd2l6YXJkLmN1cnJlbnRTdGVwLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICAgICAgaWYgKHdhc0NvbXBsZXRlZCkge1xuICAgICAgICAgIHdpemFyZC5jdXJyZW50U3RlcC5lZGl0aW5nID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBpZiAqL1xuICAgICAgICBpZiAocG9zdEZpbmFsaXplKSB7XG4gICAgICAgICAgcG9zdEZpbmFsaXplLmVtaXQoKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gaWYgdGhlIGN1cnJlbnQgc3RlcCBjYW4ndCBiZSBsZWZ0LCByZWVudGVyIHRoZSBjdXJyZW50IHN0ZXBcbiAgICAgICAgd2l6YXJkLmN1cnJlbnRTdGVwLmV4aXQoTW92aW5nRGlyZWN0aW9uLlN0YXkpO1xuICAgICAgICB3aXphcmQuY3VycmVudFN0ZXAuZW50ZXIoTW92aW5nRGlyZWN0aW9uLlN0YXkpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYW5zaXRpb25zIHRoZSB3aXphcmQgdG8gdGhlIGdpdmVuIHN0ZXAgaW5kZXguXG4gICAqXG4gICAqIENhbiBwZXJmb3JtIGFkZGl0aW9uYWwgYWN0aW9ucyBpbiBwYXJ0aWN1bGFyIG5hdmlnYXRpb24gbW9kZSBpbXBsZW1lbnRhdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSB3aXphcmQgVGhlIHdpemFyZCBjb21wb25lbnQgdG8gb3BlcmF0ZSBvblxuICAgKiBAcGFyYW0gZGVzdGluYXRpb25JbmRleCBUaGUgaW5kZXggb2YgdGhlIGRlc3RpbmF0aW9uIHdpemFyZCBzdGVwXG4gICAqL1xuICBwcm90ZWN0ZWQgdHJhbnNpdGlvbih3aXphcmQ6IFdpemFyZENvbXBvbmVudCwgZGVzdGluYXRpb25JbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgd2l6YXJkLmN1cnJlbnRTdGVwSW5kZXggPSBkZXN0aW5hdGlvbkluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICBwdWJsaWMgYWJzdHJhY3QgaXNOYXZpZ2FibGUoV2l6YXJkQ29tcG9uZW50OiBXaXphcmRDb21wb25lbnQsIGRlc3RpbmF0aW9uSW5kZXg6IG51bWJlcik6IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFJlc2V0cyB0aGUgc3RhdGUgb2YgdGhpcyB3aXphcmQuXG4gICAqXG4gICAqIEEgcmVzZXQgdHJhbnNpdGlvbnMgdGhlIHdpemFyZCBhdXRvbWF0aWNhbGx5IHRvIHRoZSBmaXJzdCBzdGVwIGFuZCBzZXRzIGFsbCBzdGVwcyBhcyBpbmNvbXBsZXRlLlxuICAgKiBJbiBhZGRpdGlvbiB0aGUgd2hvbGUgd2l6YXJkIGlzIHNldCBhcyBpbmNvbXBsZXRlLlxuICAgKlxuICAgKiBAcGFyYW0gd2l6YXJkIFRoZSB3aXphcmQgY29tcG9uZW50IHRvIG9wZXJhdGUgb25cbiAgICovXG4gIHB1YmxpYyByZXNldCh3aXphcmQ6IFdpemFyZENvbXBvbmVudCk6IHZvaWQge1xuICAgIHRoaXMuZW5zdXJlQ2FuUmVzZXQod2l6YXJkKTtcblxuICAgIC8vIHJlc2V0IHRoZSBzdGVwIGludGVybmFsIHN0YXRlXG4gICAgd2l6YXJkLndpemFyZFN0ZXBzLmZvckVhY2goc3RlcCA9PiB7XG4gICAgICBzdGVwLmNvbXBsZXRlZCA9IHN0ZXAuaW5pdGlhbGx5Q29tcGxldGVkO1xuICAgICAgc3RlcC5zZWxlY3RlZCA9IGZhbHNlO1xuICAgICAgc3RlcC5lZGl0aW5nID0gZmFsc2U7XG4gICAgfSk7XG5cbiAgICAvLyBzZXQgdGhlIGZpcnN0IHN0ZXAgYXMgdGhlIGN1cnJlbnQgc3RlcFxuICAgIHdpemFyZC5jdXJyZW50U3RlcEluZGV4ID0gd2l6YXJkLmRlZmF1bHRTdGVwSW5kZXg7XG4gICAgd2l6YXJkLmN1cnJlbnRTdGVwLnNlbGVjdGVkID0gdHJ1ZTtcbiAgICB3aXphcmQuY3VycmVudFN0ZXAuZW50ZXIoTW92aW5nRGlyZWN0aW9uLkZvcndhcmRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3MgaWYgd2l6YXJkIGNvbmZpZ3VyYXRpb24gYWxsb3dzIHRvIHBlcmZvcm0gcmVzZXQuXG4gICAqXG4gICAqIEEgY2hlY2sgZmFpbHVyZSBpcyBpbmRpY2F0ZWQgYnkgdGhyb3dpbmcgYW4gYEVycm9yYCB3aXRoIHRoZSBtZXNzYWdlIGRpc2NyaWJpbmcgdGhlIGRpc2NvdmVyZWQgbWlzY29uZmlndXJhdGlvbiBpc3N1ZS5cbiAgICpcbiAgICogQ2FuIGluY2x1ZGUgYWRkaXRpb25hbCBjaGVja3MgaW4gcGFydGljdWxhciBuYXZpZ2F0aW9uIG1vZGUgaW1wbGVtZW50YXRpb25zLlxuICAgKlxuICAgKiBAcGFyYW0gd2l6YXJkIFRoZSB3aXphcmQgY29tcG9uZW50IHRvIG9wZXJhdGUgb25cbiAgICogQHRocm93cyBBbiBgRXJyb3JgIGlzIHRocm93biwgaWYgYSBtaWNjb25maWd1cmF0aW9uIGlzc3VlIGlzIGRpc2NvdmVyZWQuXG4gICAqL1xuICBwcm90ZWN0ZWQgZW5zdXJlQ2FuUmVzZXQod2l6YXJkOiBXaXphcmRDb21wb25lbnQpOiB2b2lkIHtcbiAgICAvLyB0aGUgd2l6YXJkIGRvZXNuJ3QgY29udGFpbiBhIHN0ZXAgd2l0aCB0aGUgZGVmYXVsdCBzdGVwIGluZGV4XG4gICAgaWYgKCF3aXphcmQuaGFzU3RlcCh3aXphcmQuZGVmYXVsdFN0ZXBJbmRleCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgVGhlIHdpemFyZCBkb2Vzbid0IGNvbnRhaW4gYSBzdGVwIHdpdGggaW5kZXggJHt3aXphcmQuZGVmYXVsdFN0ZXBJbmRleH1gKTtcbiAgICB9XG4gIH1cbn1cbiJdfQ==