bp-prism-game
Version:
The BP Prism Game
257 lines • 33.3 kB
JavaScript
import { AlienBaseClass } from '../base/alien-base/alien-base.class';
import { Alien1Class } from '../aliens/alien-1/alien-1.class';
import { ObservableTypeEnum } from '../enum/observable-type.enum';
import { AssetClass } from '../asset/asset.class';
import { Alien2Class } from '../aliens/alien-2/alien-2.class';
import { PathService } from './path.service';
import { AlienDropshipClass } from '../aliens/alien-dropship/alien-dropship.class';
/**
* The invasion service
*/
export class InvasionService extends AssetClass {
/**
* The constructor
*/
constructor(gameService, ctx) {
super(gameService, ctx, 0);
this.bases = [];
this.baseAliens = [];
this.alienDropships = [];
this.waveTotal = 0;
this.dropshipCounter = 0;
this.pathService = new PathService();
this.setup();
}
/**
* Initialize the board
*/
setup() {
this.basePositions = this.gameService.getAlienBasePositions();
this.basePositions.map((position) => {
const alienBase = new AlienBaseClass(this.gameService, this.ctx, 1);
alienBase.move(position);
this.bases.push(alienBase);
});
this.gameService.getMasterObservable().subscribe((event) => {
if (event.type === ObservableTypeEnum.alienDestroyed) {
this.isLevelCompleted();
}
});
}
/**
* Build the creep
*/
buildCreep() {
let alienUid = 0;
let baseAlienPosition = 0;
this.baseAliens.map((alienWave) => {
alienWave.aliens.map((alien) => {
alienUid++;
alien.isAnimated = false;
alien.isDestroyed = false;
});
});
this.alienDropships.map((alienDropship) => {
alienDropship.isDestroyed = false;
alienDropship.isAnimated = false;
});
for (let wave = 0; wave < this.waves; wave++) {
this.basePositions.map((position) => {
if (!this.alienDropships[baseAlienPosition]) {
this.alienDropships.push(new AlienDropshipClass(this.gameService, this.ctx, this.alienDropships.length));
}
if (!this.baseAliens[baseAlienPosition]) {
this.baseAliens.push({
startingPoint: position,
aliens: []
});
}
for (let index = this.baseAliens[baseAlienPosition].aliens.length; index < this.aliensPerWave; index++) {
let alien;
if (baseAlienPosition % 2 === 0) {
alien = new Alien1Class(this.gameService, this.ctx, alienUid++);
}
else {
alien = new Alien2Class(this.gameService, this.ctx, alienUid++);
}
alien.isAnimated = false;
alien.isDestroyed = false;
this.baseAliens[baseAlienPosition].aliens.push(alien);
}
baseAlienPosition++;
});
}
}
/**
* Shuffle the waves
*/
shuffle() {
let currentIndex = this.basePositions.length;
let temporaryValue;
let randomIndex;
// While there remain elements to shuffle...
while (0 !== currentIndex) {
// Pick a remaining element...
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
// And swap it with the current element.
temporaryValue = this.basePositions[currentIndex];
this.basePositions[currentIndex] = this.basePositions[randomIndex];
this.basePositions[randomIndex] = temporaryValue;
}
}
/**
* Configure the Alien drop ship
* @param index the index of the dropship
* @param position the position of the base
*/
configureAlienDropship(index, position) {
this.alienDropships[index].setAlienDropshipToDeploy();
this.alienDropships[index].move(position);
this.alienDropships[index].setCreepPath(this.pathService.getAlienDropShipPath({
x: 0,
y: position.y
}, position));
}
/**
* position the aliens at the starting point
*/
positionAliens() {
this.shuffle();
let basePosition = 0;
for (let wave = 0; wave < this.waves; wave++) {
this.basePositions.map((position) => {
this.configureAlienDropship(basePosition, position);
this.baseAliens[basePosition].aliens.map((alien) => {
alien.setCreepSpeed(this.alienSpeed);
alien.setCreepPath(this.pathService.findShortestPath(this.gameService.convertIAssetToGameboardIAsset(position), this.gameService.getGameBoard()));
});
basePosition++;
});
}
}
/**
* Determine if the level is completed
*/
isLevelCompleted() {
this.totalAliens--;
if (this.totalAliens === 0) {
this.gameService.emitMasterObservableEvent({
type: ObservableTypeEnum.levelCompleted,
booleanData: true
});
}
}
/**
* Animate the bases
*/
animateBases() {
this.basePositions = this.gameService.getAlienBasePositions();
let basePositionCounter = 0;
if (this.bases.length > 0) {
this.basePositions.map((position) => {
this.bases[basePositionCounter].move(position);
basePositionCounter++;
});
}
}
/**
* Start the animations
*
* @param invasionSetup Set up the invasion
*/
initInvasion(invasionSetup) {
this.aliensPerWave = invasionSetup.alienPerWave ? invasionSetup.alienPerWave : 10;
this.waves = invasionSetup.waves ? invasionSetup.waves : 2;
this.alienSpeed = invasionSetup.alienSpeed ? invasionSetup.alienSpeed : 500;
this.waveTotal = this.basePositions.length * this.waves;
this.dropshipCounter = 0;
this.totalAliens = this.aliensPerWave * this.waveTotal;
this.animateBases();
this.buildCreep();
this.positionAliens();
this.waveCounter = 0;
this.alienReleaseCounter = 0;
this.launchNextAlienDropship();
}
/**
* Start Alien Creep
*/
startAlienCreep(baseIndex, alienIndex) {
if (this.baseAliens.length > 0) {
this.baseAliens[baseIndex].aliens[alienIndex].isAnimated = true;
}
}
/**
* Get All Active Aliens
*/
getActiveAliens() {
let activeAliens = [];
this.baseAliens.map((alienWave) => {
activeAliens = activeAliens.concat(alienWave.aliens.filter((alien) => alien.isDestroyed === false));
});
return activeAliens;
}
/**
* Animate
* @param now the current time
*/
animate(now = 0) {
this.bases.map((base) => {
base.animate();
});
if (this.stopAnimation()) {
return;
}
this.baseAliens.map((alienWave) => {
alienWave.aliens
.filter((alien) => alien.isAnimated && alien.isDestroyed === false)
.map((alien) => {
alien.animate(now);
});
});
}
/**
* Launch the next drop ship
* @param index The index of the drop ship
*/
launchNextAlienDropship() {
if (this.alienDropships[this.dropshipCounter]) {
this.alienDropships[this.dropshipCounter].isAnimated = true;
}
}
/**
* Animate
*
* @param now The current animation time
*/
animateDropships(now = 0) {
this.assetTimer.elapsed = now - this.assetTimer.start;
if (this.stopAnimation()) {
return;
}
this.alienDropships
.filter((alienDropship) => alienDropship.isAnimated && alienDropship.isDestroyed === false)
.map((alienDropship) => {
alienDropship.animate(now);
});
if (this.dropshipCounter === this.alienDropships.length) {
return;
}
if (this.alienDropships[this.dropshipCounter].canLandAliens()) {
if (this.assetTimer.elapsed > this.alienSpeed) {
this.assetTimer.start = now;
if (this.alienReleaseCounter === this.aliensPerWave) {
this.alienDropships[this.dropshipCounter++].setAliensLanded();
this.launchNextAlienDropship();
this.waveCounter++;
this.alienReleaseCounter = 0;
}
else {
this.startAlienCreep(this.waveCounter, this.alienReleaseCounter++);
}
}
}
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW52YXNpb24uc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL3ByaXNtL3NyYy9saWIvc2VydmljZS9pbnZhc2lvbi5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUNyRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0saUNBQWlDLENBQUM7QUFFOUQsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDbEUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBSWxELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUM5RCxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0MsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sK0NBQStDLENBQUM7QUFFbkY7O0dBRUc7QUFDSCxNQUFNLE9BQU8sZUFBZ0IsU0FBUSxVQUFVO0lBa0U3Qzs7T0FFRztJQUNILFlBQVksV0FBd0IsRUFBRSxHQUE2QjtRQUNqRSxLQUFLLENBQUMsV0FBVyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQztRQUNoQixJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsY0FBYyxHQUFHLEVBQUUsQ0FBQztRQUN6QixJQUFJLENBQUMsU0FBUyxHQUFHLENBQUMsQ0FBQztRQUNuQixJQUFJLENBQUMsZUFBZSxHQUFHLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7UUFFckMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ2YsQ0FBQztJQUVEOztPQUVHO0lBQ0ssS0FBSztRQUNYLElBQUksQ0FB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RyxDQUFDLENBQUMsYUFBaUMsRUFBRSxFQUFFO1lBQ3pDLGFBQWEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDN0IsQ0FBQyxDQUFDLENBQUM7UUFFTCxJQUFJLElBQUksQ0FBQyxlQUFlLEtBQUssSUFBSSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUU7WUFDdkQsT0FBTztTQUNSO1FBRUQsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQyxhQUFhLEVBQUUsRUFBRTtZQUM3RCxJQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQzdDLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQztnQkFDNUIsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEtBQUssSUFBSSxDQUFDLGFBQWEsRUFBRTtvQkFDbkQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsZUFBZSxFQUFFLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztvQkFDOUQsSUFBSSxDQUFDLHVCQUF1QixFQUFFLENBQUM7b0JBQy9CLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztvQkFDbkIsSUFBSSxDQUFDLG1CQUFtQixHQUFHLENBQUMsQ0FBQztpQkFDOUI7cUJBQU07b0JBQ0wsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDLENBQUM7aUJBQ3BFO2FBQ0Y7U0FDRjtJQUNILENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IElBc3NldCB9IGZyb20gJy4uL2ludGVyZmFjZS9hc3NldC5pbnRlcmZhY2UnO1xuaW1wb3J0IHsgR2FtZVNlcnZpY2UgfSBmcm9tICcuL2dhbWUuc2VydmljZSc7XG5pbXBvcnQgeyBBbGllbkNsYXNzIH0gZnJvbSAnLi4vYWxpZW5zL2FsaWVuL2FsaWVuLmNsYXNzJztcbmltcG9ydCB7IEFsaWVuQmFzZUNsYXNzIH0gZnJvbSAnLi4vYmFzZS9hbGllbi1iYXNlL2FsaWVuLWJhc2UuY2xhc3MnO1xuaW1wb3J0IHsgQWxpZW4xQ2xhc3MgfSBmcm9tICcuLi9hbGllbnMvYWxpZW4tMS9hbGllbi0xLmNsYXNzJztcbmltcG9ydCB7IE9ic2VydmFibGVNb2RlbCB9IGZyb20gJy4uL21vZGVsL29ic2VydmFibGUubW9kZWwnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZVR5cGVFbnVtIH0gZnJvbSAnLi4vZW51bS9vYnNlcnZhYmxlLXR5cGUuZW51bSc7XG5pbXBvcnQgeyBBc3NldENsYXNzIH0gZnJvbSAnLi4vYXNzZXQvYXNzZXQuY2xhc3MnO1xuaW1wb3J0IHsgQWxpZW5XYXZlTW9kZWwgfSBmcm9tICcuLi9tb2RlbC9hbGllbi9hbGllbi13YXZlLm1vZGVsJztcbmltcG9ydCB7IEludmFzaW9uU2V0dXBNb2RlbCB9IGZyb20gJy4uL21vZGVsL2ludmFzaW9uLXNldHVwLm1vZGVsJztcbmltcG9ydCB7IEJhc2VDbGFzcyB9IGZyb20gJy4uL2Jhc2UvYmFzZS5jbGFzcyc7XG5pbXBvcnQgeyBBbGllbjJDbGFzcyB9IGZyb20gJy4uL2FsaWVucy9hbGllbi0yL2FsaWVuLTIuY2xhc3MnO1xuaW1wb3J0IHsgUGF0aFNlcnZpY2UgfSBmcm9tICcuL3BhdGguc2VydmljZSc7XG5pbXBvcnQgeyBBbGllbkRyb3BzaGlwQ2xhc3MgfSBmcm9tICcuLi9hbGllbnMvYWxpZW4tZHJvcHNoaXAvYWxpZW4tZHJvcHNoaXAuY2xhc3MnO1xuXG4vKipcbiAqIFRoZSBpbnZhc2lvbiBzZXJ2aWNlXG4gKi9cbmV4cG9ydCBjbGFzcyBJbnZhc2lvblNlcnZpY2UgZXh0ZW5kcyBBc3NldENsYXNzIHtcbiAgLyoqXG4gICAqIFRoZSBhbGllbiBiYXNlc1xuICAgKi9cbiAgcHJpdmF0ZSBiYXNlczogQWxpZW5CYXNlQ2xhc3NbXTtcblxuICAvKipcbiAgICogQWxpZW5zIGF0IGVhY2ggYmFzZVxuICAgKi9cbiAgcHJpdmF0ZSBiYXNlQWxpZW5zOiBBbGllbldhdmVNb2RlbFtdO1xuXG4gIC8qKlxuICAgKiBBbGllbnMgZHJvcCBzaGlwc1xuICAgKi9cbiAgcHJpdmF0ZSBhbGllbkRyb3BzaGlwczogQWxpZW5Ecm9wc2hpcENsYXNzW107XG5cbiAgLyoqXG4gICAqIFRoZSBhbGllbiBSZWxlYXNlIENvdW50ZXJcbiAgICovXG4gIHByaXZhdGUgYWxpZW5SZWxlYXNlQ291bnRlcjogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgd2F2ZSBjb3VudGVyXG4gICAqL1xuICBwcml2YXRlIHdhdmVDb3VudGVyOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSB0b3RhbCB3YXZlc1xuICAgKi9cbiAgcHJpdmF0ZSB3YXZlVG90YWw6IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGFsaWVucyBQZXIgV2F2ZVxuICAgKi9cbiAgcHJpdmF0ZSBhbGllbnNQZXJXYXZlOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBkcm9wc2hpcCBjb3VudGVyXG4gICAqL1xuICBwcml2YXRlIGRyb3BzaGlwQ291bnRlcjogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgV2F2ZVxuICAgKi9cbiAgcHJpdmF0ZSB3YXZlczogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgQWxpZW4gU3BlZWRcbiAgICovXG4gIHByaXZhdGUgYWxpZW5TcGVlZDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBUaGUgVG90YWwgQWxpZW5zXG4gICAqL1xuICBwcml2YXRlIHRvdGFsQWxpZW5zOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIFRoZSBCYXNlIFBvc2l0aW9uc1xuICAgKi9cbiAgcHJpdmF0ZSBiYXNlUG9zaXRpb25zOiBJQXNzZXRbXTtcblxuICAvKipcbiAgICogVGhlIHBhdGggc2VydmljZVxuICAgKi9cbiAgcHJpdmF0ZSBwYXRoU2VydmljZTogUGF0aFNlcnZpY2U7XG5cbiAgLyoqXG4gICAqIFRoZSBjb25zdHJ1Y3RvclxuICAgKi9cbiAgY29uc3RydWN0b3IoZ2FtZVNlcnZpY2U6IEdhbWVTZXJ2aWNlLCBjdHg6IENhbnZhc1JlbmRlcmluZ0NvbnRleHQyRCkge1xuICAgIHN1cGVyKGdhbWVTZXJ2aWNlLCBjdHgsIDApO1xuICAgIHRoaXMuYmFzZXMgPSBbXTtcbiAgICB0aGlzLmJhc2VBbGllbnMgPSBbXTtcbiAgICB0aGlzLmFsaWVuRHJvcHNoaXBzID0gW107XG4gICAgdGhpcy53YXZlVG90YWwgPSAwO1xuICAgIHRoaXMuZHJvcHNoaXBDb3VudGVyID0gMDtcbiAgICB0aGlzLnBhdGhTZXJ2aWNlID0gbmV3IFBhdGhTZXJ2aWNlKCk7XG5cbiAgICB0aGlzLnNldHVwKCk7XG4gIH1cblxuICAvKipcbiAgICogSW5pdGlhbGl6ZSB0aGUgYm9hcmRcbiAgICovXG4gIHByaXZhdGUgc2V0dXAoKTogdm9pZCB7XG4gICAgdGhpcy5iYXNlUG9zaXRpb25zID0gdGhpcy5nYW1lU2VydmljZS5nZXRBbGllbkJhc2VQb3NpdGlvbnMoKTtcblxuICAgIHRoaXMuYmFzZVBvc2l0aW9ucy5tYXAoKHBvc2l0aW9uOiBJQXNzZXQpID0+IHtcbiAgICAgIGNvbnN0IGFsaWVuQmFzZSA9IG5ldyBBbGllbkJhc2VDbGFzcyh0aGlzLmdhbWVTZXJ2aWNlLCB0aGlzLmN0eCwgMSk7XG4gICAgICBhbGllbkJhc2UubW92ZShwb3NpdGlvbik7XG4gICAgICB0aGlzLmJhc2VzLnB1c2goYWxpZW5CYXNlKTtcbiAgICB9KTtcblxuICAgIHRoaXMuZ2FtZVNlcnZpY2UuZ2V0TWFzdGVyT2JzZXJ2YWJsZSgpLnN1YnNjcmliZSgoZXZlbnQ6IE9ic2VydmFibGVNb2RlbCkgPT4ge1xuICAgICAgaWYgKGV2ZW50LnR5cGUgPT09IE9ic2VydmFibGVUeXBlRW51bS5hbGllbkRlc3Ryb3llZCkge1xuICAgICAgICB0aGlzLmlzTGV2ZWxDb21wbGV0ZWQoKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZCB0aGUgY3JlZXBcbiAgICovXG4gIHByaXZhdGUgYnVpbGRDcmVlcCgpOiB2b2lkIHtcbiAgICBsZXQgYWxpZW5VaWQgPSAwO1xuICAgIGxldCBiYXNlQWxpZW5Qb3NpdGlvbiA9IDA7XG5cbiAgICB0aGlzLmJhc2VBbGllbnMubWFwKChhbGllbldhdmU6IEFsaWVuV2F2ZU1vZGVsKSA9PiB7XG4gICAgICBhbGllbldhdmUuYWxpZW5zLm1hcCgoYWxpZW46IEFsaWVuQ2xhc3MpID0+IHtcbiAgICAgICAgYWxpZW5VaWQrKztcbiAgICAgICAgYWxpZW4uaXNBbmltYXRlZCA9IGZhbHNlO1xuICAgICAgICBhbGllbi5pc0Rlc3Ryb3llZCA9IGZhbHNlO1xuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0aGlzLmFsaWVuRHJvcHNoaXBzLm1hcCgoYWxpZW5Ecm9wc2hpcDogQWxpZW5Ecm9wc2hpcENsYXNzKSA9PiB7XG4gICAgICBhbGllbkRyb3BzaGlwLmlzRGVzdHJveWVkID0gZmFsc2U7XG4gICAgICBhbGllbkRyb3BzaGlwLmlzQW5pbWF0ZWQgPSBmYWxzZTtcbiAgICB9KTtcblxuICAgIGZvciAobGV0IHdhdmUgPSAwOyB3YXZlIDwgdGhpcy53YXZlczsgd2F2ZSsrKSB7XG4gICAgICB0aGlzLmJhc2VQb3NpdGlvbnMubWFwKChwb3NpdGlvbjogSUFzc2V0KSA9PiB7XG4gICAgICAgIGlmICghdGhpcy5hbGllbkRyb3BzaGlwc1tiYXNlQWxpZW5Qb3NpdGlvbl0pIHtcbiAgICAgICAgICB0aGlzLmFsaWVuRHJvcHNoaXBzLnB1c2gobmV3IEFsaWVuRHJvcHNoaXBDbGFzcyh0aGlzLmdhbWVTZXJ2aWNlLCB0aGlzLmN0eCwgdGhpcy5hbGllbkRyb3BzaGlwcy5sZW5ndGgpKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICghdGhpcy5iYXNlQWxpZW5zW2Jhc2VBbGllblBvc2l0aW9uXSkge1xuICAgICAgICAgIHRoaXMuYmFzZUFsaWVucy5wdXNoKHtcbiAgICAgICAgICAgIHN0YXJ0aW5nUG9pbnQ6IHBvc2l0aW9uLFxuICAgICAgICAgICAgYWxpZW5zOiBbXVxuICAgICAgICAgIH0gYXMgQWxpZW5XYXZlTW9kZWwpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm9yIChsZXQgaW5kZXggPSB0aGlzLmJhc2VBbGllbnNbYmFzZUFsaWVuUG9zaXRpb25dLmFsaWVucy5sZW5ndGg7IGluZGV4IDwgdGhpcy5hbGllbnNQZXJXYXZlOyBpbmRleCsrKSB7XG4gICAgICAgICAgbGV0IGFsaWVuOiBBbGllbkNsYXNzO1xuICAgICAgICAgIGlmIChiYXNlQWxpZW5Qb3NpdGlvbiAlIDIgPT09IDApIHtcbiAgICAgICAgICAgIGFsaWVuID0gbmV3IEFsaWVuMUNsYXNzKHRoaXMuZ2FtZVNlcnZpY2UsIHRoaXMuY3R4LCBhbGllblVpZCsrKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgYWxpZW4gPSBuZXcgQWxpZW4yQ2xhc3ModGhpcy5nYW1lU2VydmljZSwgdGhpcy5jdHgsIGFsaWVuVWlkKyspO1xuICAgICAgICAgIH1cbiAgICAgICAgICBhbGllbi5pc0FuaW1hdGVkID0gZmFsc2U7XG4gICAgICAgICAgYWxpZW4uaXNEZXN0cm95ZWQgPSBmYWxzZTtcblxuICAgICAgICAgIHRoaXMuYmFzZUFsaWVuc1tiYXNlQWxpZW5Qb3NpdGlvbl0uYWxpZW5zLnB1c2goYWxpZW4pO1xuICAgICAgICB9XG5cbiAgICAgICAgYmFzZUFsaWVuUG9zaXRpb24rKztcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTaHVmZmxlIHRoZSB3YXZlc1xuICAgKi9cbiAgcHJpdmF0ZSBzaHVmZmxlKCk6IHZvaWQge1xuICAgIGxldCBjdXJyZW50SW5kZXggPSB0aGlzLmJhc2VQb3NpdGlvbnMubGVuZ3RoO1xuICAgIGxldCB0ZW1wb3JhcnlWYWx1ZTogSUFzc2V0O1xuICAgIGxldCByYW5kb21JbmRleDogbnVtYmVyO1xuXG4gICAgLy8gV2hpbGUgdGhlcmUgcmVtYWluIGVsZW1lbnRzIHRvIHNodWZmbGUuLi5cbiAgICB3aGlsZSAoMCAhPT0gY3VycmVudEluZGV4KSB7XG4gICAgICAvLyBQaWNrIGEgcmVtYWluaW5nIGVsZW1lbnQuLi5cbiAgICAgIHJhbmRvbUluZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogY3VycmVudEluZGV4KTtcbiAgICAgIGN1cnJlbnRJbmRleCAtPSAxO1xuXG4gICAgICAvLyBBbmQgc3dhcCBpdCB3aXRoIHRoZSBjdXJyZW50IGVsZW1lbnQuXG4gICAgICB0ZW1wb3JhcnlWYWx1ZSA9IHRoaXMuYmFzZVBvc2l0aW9uc1tjdXJyZW50SW5kZXhdO1xuICAgICAgdGhpcy5iYXNlUG9zaXRpb25zW2N1cnJlbnRJbmRleF0gPSB0aGlzLmJhc2VQb3NpdGlvbnNbcmFuZG9tSW5kZXhdO1xuICAgICAgdGhpcy5iYXNlUG9zaXRpb25zW3JhbmRvbUluZGV4XSA9IHRlbXBvcmFyeVZhbHVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maWd1cmUgdGhlIEFsaWVuIGRyb3Agc2hpcFxuICAgKiBAcGFyYW0gaW5kZXggdGhlIGluZGV4IG9mIHRoZSBkcm9wc2hpcFxuICAgKiBAcGFyYW0gcG9zaXRpb24gdGhlIHBvc2l0aW9uIG9mIHRoZSBiYXNlXG4gICAqL1xuICBwcml2YXRlIGNvbmZpZ3VyZUFsaWVuRHJvcHNoaXAoaW5kZXg6IG51bWJlciwgcG9zaXRpb246IElBc3NldCk6IHZvaWQge1xuICAgIHRoaXMuYWxpZW5Ecm9wc2hpcHNbaW5kZXhdLnNldEFsaWVuRHJvcHNoaXBUb0RlcGxveSgpO1xuICAgIHRoaXMuYWxpZW5Ecm9wc2hpcHNbaW5kZXhdLm1vdmUocG9zaXRpb24pO1xuICAgIHRoaXMuYWxpZW5Ecm9wc2hpcHNbaW5kZXhdLnNldENyZWVwUGF0aChcbiAgICAgIHRoaXMucGF0aFNlcnZpY2UuZ2V0QWxpZW5Ecm9wU2hpcFBhdGgoXG4gICAgICAgIHtcbiAgICAgICAgICB4OiAwLFxuICAgICAgICAgIHk6IHBvc2l0aW9uLnlcbiAgICAgICAgfSBhcyBJQXNzZXQsXG4gICAgICAgIHBvc2l0aW9uXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBwb3NpdGlvbiB0aGUgYWxpZW5zIGF0IHRoZSBzdGFydGluZyBwb2ludFxuICAgKi9cbiAgcHJpdmF0ZSBwb3NpdGlvbkFsaWVucygpOiB2b2lkIHtcbiAgICB0aGlzLnNodWZmbGUoKTtcbiAgICBsZXQgYmFzZVBvc2l0aW9uID0gMDtcblxuICAgIGZvciAobGV0IHdhdmUgPSAwOyB3YXZlIDwgdGhpcy53YXZlczsgd2F2ZSsrKSB7XG4gICAgICB0aGlzLmJhc2VQb3NpdGlvbnMubWFwKChwb3NpdGlvbjogSUFzc2V0KSA9PiB7XG4gICAgICAgIHRoaXMuY29uZmlndXJlQWxpZW5Ecm9wc2hpcChiYXNlUG9zaXRpb24sIHBvc2l0aW9uKTtcblxuICAgICAgICB0aGlzLmJhc2VBbGllbnNbYmFzZVBvc2l0aW9uXS5hbGllbnMubWFwKChhbGllbjogQWxpZW5DbGFzcykgPT4ge1xuICAgICAgICAgIGFsaWVuLnNldENyZWVwU3BlZWQodGhpcy5hbGllblNwZWVkKTtcbiAgICAgICAgICBhbGllbi5zZXRDcmVlcFBhdGgoXG4gICAgICAgICAgICB0aGlzLnBhdGhTZXJ2aWNlLmZpbmRTaG9ydGVzdFBhdGgoXG4gICAgICAgICAgICAgIHRoaXMuZ2FtZVNlcnZpY2UuY29udmVydElBc3NldFRvR2FtZWJvYXJkSUFzc2V0KHBvc2l0aW9uKSxcbiAgICAgICAgICAgICAgdGhpcy5nYW1lU2VydmljZS5nZXRHYW1lQm9hcmQoKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGJhc2VQb3NpdGlvbisrO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERldGVybWluZSBpZiB0aGUgbGV2ZWwgaXMgY29tcGxldGVkXG4gICAqL1xuICBwcml2YXRlIGlzTGV2ZWxDb21wbGV0ZWQoKTogdm9pZCB7XG4gICAgdGhpcy50b3RhbEFsaWVucy0tO1xuXG4gICAgaWYgKHRoaXMudG90YWxBbGllbnMgPT09IDApIHtcbiAgICAgIHRoaXMuZ2FtZVNlcnZpY2UuZW1pdE1hc3Rlck9ic2VydmFibGVFdmVudCh7XG4gICAgICAgIHR5cGU6IE9ic2VydmFibGVUeXBlRW51bS5sZXZlbENvbXBsZXRlZCxcbiAgICAgICAgYm9vbGVhbkRhdGE6IHRydWVcbiAgICAgIH0gYXMgT2JzZXJ2YWJsZU1vZGVsKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQW5pbWF0ZSB0aGUgYmFzZXNcbiAgICovXG4gIHByaXZhdGUgYW5pbWF0ZUJhc2VzKCk6IHZvaWQge1xuICAgIHRoaXMuYmFzZVBvc2l0aW9ucyA9IHRoaXMuZ2FtZVNlcnZpY2UuZ2V0QWxpZW5CYXNlUG9zaXRpb25zKCk7XG4gICAgbGV0IGJhc2VQb3NpdGlvbkNvdW50ZXIgPSAwO1xuICAgIGlmICh0aGlzLmJhc2VzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuYmFzZVBvc2l0aW9ucy5tYXAoKHBvc2l0aW9uOiBJQXNzZXQpID0+IHtcbiAgICAgICAgdGhpcy5iYXNlc1tiYXNlUG9zaXRpb25Db3VudGVyXS5tb3ZlKHBvc2l0aW9uKTtcbiAgICAgICAgYmFzZVBvc2l0aW9uQ291bnRlcisrO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IHRoZSBhbmltYXRpb25zXG4gICAqXG4gICAqIEBwYXJhbSBpbnZhc2lvblNldHVwIFNldCB1cCB0aGUgaW52YXNpb25cbiAgICovXG4gIHB1YmxpYyBpbml0SW52YXNpb24oaW52YXNpb25TZXR1cDogSW52YXNpb25TZXR1cE1vZGVsKTogdm9pZCB7XG4gICAgdGhpcy5hbGllbnNQZXJXYXZlID0gaW52YXNpb25TZXR1cC5hbGllblBlcldhdmUgPyBpbnZhc2lvblNldHVwLmFsaWVuUGVyV2F2ZSA6IDEwO1xuICAgIHRoaXMud2F2ZXMgPSBpbnZhc2lvblNldHVwLndhdmVzID8gaW52YXNpb25TZXR1cC53YXZlcyA6IDI7XG4gICAgdGhpcy5hbGllblNwZWVkID0gaW52YXNpb25TZXR1cC5hbGllblNwZWVkID8gaW52YXNpb25TZXR1cC5hbGllblNwZWVkIDogNTAwO1xuICAgIHRoaXMud2F2ZVRvdGFsID0gdGhpcy5iYXNlUG9zaXRpb25zLmxlbmd0aCAqIHRoaXMud2F2ZXM7XG4gICAgdGhpcy5kcm9wc2hpcENvdW50ZXIgPSAwO1xuICAgIHRoaXMudG90YWxBbGllbnMgPSB0aGlzLmFsaWVuc1BlcldhdmUgKiB0aGlzLndhdmVUb3RhbDtcblxuICAgIHRoaXMuYW5pbWF0ZUJhc2VzKCk7XG4gICAgdGhpcy5idWlsZENyZWVwKCk7XG4gICAgdGhpcy5wb3NpdGlvbkFsaWVucygpO1xuICAgIHRoaXMud2F2ZUNvdW50ZXIgPSAwO1xuICAgIHRoaXMuYWxpZW5SZWxlYXNlQ291bnRlciA9IDA7XG4gICAgdGhpcy5sYXVuY2hOZXh0QWxpZW5Ecm9wc2hpcCgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IEFsaWVuIENyZWVwXG4gICAqL1xuICBwcml2YXRlIHN0YXJ0QWxpZW5DcmVlcChiYXNlSW5kZXg6IG51bWJlciwgYWxpZW5JbmRleDogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuYmFzZUFsaWVucy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmJhc2VBbGllbnNbYmFzZUluZGV4XS5hbGllbnNbYWxpZW5JbmRleF0uaXNBbmltYXRlZCA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEdldCBBbGwgQWN0aXZlIEFsaWVuc1xuICAgKi9cbiAgcHVibGljIGdldEFjdGl2ZUFsaWVucygpOiBBbGllbkNsYXNzW10ge1xuICAgIGxldCBhY3RpdmVBbGllbnM6IEFsaWVuQ2xhc3NbXSA9IFtdO1xuXG4gICAgdGhpcy5iYXNlQWxpZW5zLm1hcCgoYWxpZW5XYXZlOiBBbGllbldhdmVNb2RlbCkgPT4ge1xuICAgICAgYWN0aXZlQWxpZW5zID0gYWN0aXZlQWxpZW5zLmNvbmNhdChhbGllbldhdmUuYWxpZW5zLmZpbHRlcigoYWxpZW46IEFsaWVuQ2xhc3MpID0+IGFsaWVuLmlzRGVzdHJveWVkID09PSBmYWxzZSkpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIGFjdGl2ZUFsaWVucztcbiAgfVxuXG4gIC8qKlxuICAgKiBBbmltYXRlXG4gICAqIEBwYXJhbSBub3cgdGhlIGN1cnJlbnQgdGltZVxuICAgKi9cbiAgcHVibGljIGFuaW1hdGUobm93ID0gMCk6IHZvaWQge1xuICAgIHRoaXMuYmFzZXMubWFwKChiYXNlOiBCYXNlQ2xhc3MpID0+IHtcbiAgICAgIGJhc2UuYW5pbWF0ZSgpO1xuICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuc3RvcEFuaW1hdGlvbigpKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5iYXNlQWxpZW5zLm1hcCgoYWxpZW5XYXZlOiBBbGllbldhdmVNb2RlbCkgPT4ge1xuICAgICAgYWxpZW5XYXZlLmFsaWVuc1xuICAgICAgICAuZmlsdGVyKChhbGllbjogQWxpZW5DbGFzcykgPT4gYWxpZW4uaXNBbmltYXRlZCAmJiBhbGllbi5pc0Rlc3Ryb3llZCA9PT0gZmFsc2UpXG4gICAgICAgIC5tYXAoKGFsaWVuOiBBbGllbkNsYXNzKSA9PiB7XG4gICAgICAgICAgYWxpZW4uYW5pbWF0ZShub3cpO1xuICAgICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMYXVuY2ggdGhlIG5leHQgZHJvcCBzaGlwXG4gICAqIEBwYXJhbSBpbmRleCBUaGUgaW5kZXggb2YgdGhlIGRyb3Agc2hpcFxuICAgKi9cbiAgcHJpdmF0ZSBsYXVuY2hOZXh0QWxpZW5Ecm9wc2hpcCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5hbGllbkRyb3BzaGlwc1t0aGlzLmRyb3BzaGlwQ291bnRlcl0pIHtcbiAgICAgIHRoaXMuYWxpZW5Ecm9wc2hpcHNbdGhpcy5kcm9wc2hpcENvdW50ZXJdLmlzQW5pbWF0ZWQgPSB0cnVlO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBbmltYXRlXG4gICAqXG4gICAqIEBwYXJhbSBub3cgVGhlIGN1cnJlbnQgYW5pbWF0aW9uIHRpbWVcbiAgICovXG4gIHB1YmxpYyBhbmltYXRlRHJvcHNoaXBzKG5vdyA9IDApOiB2b2lkIHtcbiAgICB0aGlzLmFzc2V0VGltZXIuZWxhcHNlZCA9IG5vdyAtIHRoaXMuYXNzZXRUaW1lci5zdGFydDtcbiAgICBpZiAodGhpcy5zdG9wQW5pbWF0aW9uKCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmFsaWVuRHJvcHNoaXBzXG4gICAgICAuZmlsdGVyKChhbGllbkRyb3BzaGlwOiBBbGllbkRyb3BzaGlwQ2xhc3MpID0+IGFsaWVuRHJvcHNoaXAuaXNBbmltYXRlZCAmJiBhbGllbkRyb3BzaGlwLmlzRGVzdHJveWVkID09PSBmYWxzZSlcbiAgICAgIC5tYXAoKGFsaWVuRHJvcHNoaXA6IEFsaWVuRHJvcHNoaXBDbGFzcykgPT4ge1xuICAgICAgICBhbGllbkRyb3BzaGlwLmFuaW1hdGUobm93KTtcbiAgICAgIH0pO1xuXG4gICAgaWYgKHRoaXMuZHJvcHNoaXBDb3VudGVyID09PSB0aGlzLmFsaWVuRHJvcHNoaXBzLmxlbmd0aCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmFsaWVuRHJvcHNoaXBzW3RoaXMuZHJvcHNoaXBDb3VudGVyXS5jYW5MYW5kQWxpZW5zKCkpIHtcbiAgICAgIGlmICh0aGlzLmFzc2V0VGltZXIuZWxhcHNlZCA+IHRoaXMuYWxpZW5TcGVlZCkge1xuICAgICAgICB0aGlzLmFzc2V0VGltZXIuc3RhcnQgPSBub3c7XG4gICAgICAgIGlmICh0aGlzLmFsaWVuUmVsZWFzZUNvdW50ZXIgPT09IHRoaXMuYWxpZW5zUGVyV2F2ZSkge1xuICAgICAgICAgIHRoaXMuYWxpZW5Ecm9wc2hpcHNbdGhpcy5kcm9wc2hpcENvdW50ZXIrK10uc2V0QWxpZW5zTGFuZGVkKCk7XG4gICAgICAgICAgdGhpcy5sYXVuY2hOZXh0QWxpZW5Ecm9wc2hpcCgpO1xuICAgICAgICAgIHRoaXMud2F2ZUNvdW50ZXIrKztcbiAgICAgICAgICB0aGlzLmFsaWVuUmVsZWFzZUNvdW50ZXIgPSAwO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuc3RhcnRBbGllbkNyZWVwKHRoaXMud2F2ZUNvdW50ZXIsIHRoaXMuYWxpZW5SZWxlYXNlQ291bnRlcisrKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuIl19