valtech-components 4.0.442 → 4.0.444
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/lib/components/organisms/mini-games/chessimals-challenge-progress.service.mjs +145 -0
- package/esm2022/lib/components/organisms/mini-games/chessimals-game.component.mjs +533 -6
- package/esm2022/lib/components/organisms/mini-games/christianity-game.component.mjs +176 -30
- package/esm2022/lib/components/organisms/mini-games/mini-games.i18n.mjs +81 -1
- package/esm2022/lib/components/organisms/mini-games/types.mjs +1 -1
- package/esm2022/lib/services/firebase/analytics.service.mjs +6 -4
- package/esm2022/lib/services/preferences/preferences.service.mjs +2 -2
- package/esm2022/lib/version.mjs +2 -2
- package/fesm2022/valtech-components.mjs +932 -39
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/organisms/mini-games/chessimals-challenge-progress.service.d.ts +30 -0
- package/lib/components/organisms/mini-games/chessimals-game.component.d.ts +36 -2
- package/lib/components/organisms/mini-games/christianity-game.component.d.ts +2 -0
- package/lib/components/organisms/mini-games/types.d.ts +65 -0
- package/lib/version.d.ts +1 -1
- package/package.json +1 -2
- package/src/lib/services/firebase/scripts/generate-sw-config.js +0 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { Injectable, inject } from '@angular/core';
|
|
2
|
+
import { Auth } from '@angular/fire/auth';
|
|
3
|
+
import { Firestore, collection, doc, getDoc, limit, onSnapshot, orderBy, query, serverTimestamp, setDoc, } from '@angular/fire/firestore';
|
|
4
|
+
import { Observable, of } from 'rxjs';
|
|
5
|
+
import { FirebaseService } from '../../../services/firebase/firebase.service';
|
|
6
|
+
import * as i0 from "@angular/core";
|
|
7
|
+
const EMPTY_POWERS = { eagle: 0, bull: 0, kangaroo: 0, lion: 0 };
|
|
8
|
+
export class ChessimalsChallengeProgressService {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.firebaseAuth = inject(Auth);
|
|
11
|
+
this.firestore = inject(Firestore);
|
|
12
|
+
this.firebase = inject(FirebaseService);
|
|
13
|
+
}
|
|
14
|
+
get currentUid() {
|
|
15
|
+
return this.firebaseAuth.currentUser?.uid;
|
|
16
|
+
}
|
|
17
|
+
watchStats() {
|
|
18
|
+
const uid = this.currentUid;
|
|
19
|
+
if (!uid)
|
|
20
|
+
return of(undefined);
|
|
21
|
+
return new Observable((subscriber) => {
|
|
22
|
+
const unsubscribe = onSnapshot(this.statsRef(uid), (snapshot) => subscriber.next(snapshot.exists() ? this.normalizeStats(snapshot.data()) : undefined), (error) => subscriber.error(error));
|
|
23
|
+
return unsubscribe;
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
watchRecentRuns(limitCount = 4) {
|
|
27
|
+
const uid = this.currentUid;
|
|
28
|
+
if (!uid)
|
|
29
|
+
return of([]);
|
|
30
|
+
const runsQuery = query(collection(this.firestore, this.runsPath(uid)), orderBy('updatedAt', 'desc'), limit(limitCount));
|
|
31
|
+
return new Observable((subscriber) => {
|
|
32
|
+
const unsubscribe = onSnapshot(runsQuery, (snapshot) => subscriber.next(snapshot.docs.map((item) => item.data())), (error) => subscriber.error(error));
|
|
33
|
+
return unsubscribe;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
async saveRun(run) {
|
|
37
|
+
const uid = await this.ensureUser();
|
|
38
|
+
await setDoc(this.runRef(uid, run.id), this.withoutUndefined({
|
|
39
|
+
...run,
|
|
40
|
+
userId: uid,
|
|
41
|
+
updatedAt: new Date().toISOString(),
|
|
42
|
+
updatedAtServer: serverTimestamp(),
|
|
43
|
+
}), { merge: true });
|
|
44
|
+
}
|
|
45
|
+
async recordChallengeStarted(run) {
|
|
46
|
+
const uid = await this.ensureUser();
|
|
47
|
+
const current = await this.readStats(uid);
|
|
48
|
+
await setDoc(this.statsRef(uid), {
|
|
49
|
+
...current,
|
|
50
|
+
userId: uid,
|
|
51
|
+
challengesPlayed: current.challengesPlayed + 1,
|
|
52
|
+
updatedAt: new Date().toISOString(),
|
|
53
|
+
updatedAtServer: serverTimestamp(),
|
|
54
|
+
}, { merge: true });
|
|
55
|
+
await this.saveRun(run);
|
|
56
|
+
}
|
|
57
|
+
async applyRoundResult(args) {
|
|
58
|
+
const uid = await this.ensureUser();
|
|
59
|
+
const current = await this.readStats(uid);
|
|
60
|
+
const next = {
|
|
61
|
+
userId: uid,
|
|
62
|
+
challengesPlayed: current.challengesPlayed,
|
|
63
|
+
challengesCompleted: current.challengesCompleted + (args.completed ? 1 : 0),
|
|
64
|
+
bestWinStreak: Math.max(current.bestWinStreak, args.run.bestStreakInRun),
|
|
65
|
+
bestRoundReached: Math.max(current.bestRoundReached, args.roundReached),
|
|
66
|
+
totalWins: current.totalWins + (args.won ? 1 : 0),
|
|
67
|
+
totalLosses: current.totalLosses + (args.won ? 0 : 1),
|
|
68
|
+
botsDefeated: current.botsDefeated + (args.won ? 1 : 0),
|
|
69
|
+
powersUsed: {
|
|
70
|
+
eagle: current.powersUsed.eagle + args.roundStats.powersUsed.eagle,
|
|
71
|
+
bull: current.powersUsed.bull + args.roundStats.powersUsed.bull,
|
|
72
|
+
kangaroo: current.powersUsed.kangaroo + args.roundStats.powersUsed.kangaroo,
|
|
73
|
+
lion: current.powersUsed.lion + args.roundStats.powersUsed.lion,
|
|
74
|
+
},
|
|
75
|
+
powerCaptures: current.powerCaptures + args.roundStats.powerCaptures,
|
|
76
|
+
promotions: current.promotions + args.roundStats.promotions,
|
|
77
|
+
updatedAt: new Date().toISOString(),
|
|
78
|
+
};
|
|
79
|
+
await setDoc(this.statsRef(uid), { ...next, updatedAtServer: serverTimestamp() }, { merge: true });
|
|
80
|
+
await this.saveRun(args.run);
|
|
81
|
+
}
|
|
82
|
+
emptyStats() {
|
|
83
|
+
return {
|
|
84
|
+
challengesPlayed: 0,
|
|
85
|
+
challengesCompleted: 0,
|
|
86
|
+
bestWinStreak: 0,
|
|
87
|
+
bestRoundReached: 0,
|
|
88
|
+
totalWins: 0,
|
|
89
|
+
totalLosses: 0,
|
|
90
|
+
botsDefeated: 0,
|
|
91
|
+
powersUsed: { ...EMPTY_POWERS },
|
|
92
|
+
powerCaptures: 0,
|
|
93
|
+
promotions: 0,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
async readStats(uid) {
|
|
97
|
+
// Firestore's web SDK does not need a transaction for these casual game stats.
|
|
98
|
+
// Last-write-wins is acceptable for this first version because one run is active per browser.
|
|
99
|
+
const snapshot = await getDoc(this.statsRef(uid));
|
|
100
|
+
return snapshot.exists() ? this.normalizeStats(snapshot.data()) : this.emptyStats();
|
|
101
|
+
}
|
|
102
|
+
normalizeStats(value) {
|
|
103
|
+
const empty = this.emptyStats();
|
|
104
|
+
return {
|
|
105
|
+
...empty,
|
|
106
|
+
...value,
|
|
107
|
+
powersUsed: {
|
|
108
|
+
...EMPTY_POWERS,
|
|
109
|
+
...(value.powersUsed ?? {}),
|
|
110
|
+
},
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
async ensureUser() {
|
|
114
|
+
await this.firebase.whenFirebaseAuthReady();
|
|
115
|
+
const user = this.firebaseAuth.currentUser;
|
|
116
|
+
if (user?.uid) {
|
|
117
|
+
await user.getIdToken();
|
|
118
|
+
return user.uid;
|
|
119
|
+
}
|
|
120
|
+
throw new Error('CHESSIMALS_CHALLENGE_LOGIN_REQUIRED');
|
|
121
|
+
}
|
|
122
|
+
statsRef(uid) {
|
|
123
|
+
return doc(this.firestore, `users/${uid}/miniGames/chessimals/challenge/stats`);
|
|
124
|
+
}
|
|
125
|
+
runRef(uid, runId) {
|
|
126
|
+
return doc(this.firestore, `${this.runsPath(uid)}/${runId}`);
|
|
127
|
+
}
|
|
128
|
+
runsPath(uid) {
|
|
129
|
+
return `users/${uid}/miniGames/chessimals/challengeRuns`;
|
|
130
|
+
}
|
|
131
|
+
withoutUndefined(value) {
|
|
132
|
+
return Object.entries(value).reduce((acc, [key, entry]) => {
|
|
133
|
+
if (entry !== undefined)
|
|
134
|
+
acc[key] = entry;
|
|
135
|
+
return acc;
|
|
136
|
+
}, {});
|
|
137
|
+
}
|
|
138
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChessimalsChallengeProgressService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
139
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChessimalsChallengeProgressService, providedIn: 'root' }); }
|
|
140
|
+
}
|
|
141
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: ChessimalsChallengeProgressService, decorators: [{
|
|
142
|
+
type: Injectable,
|
|
143
|
+
args: [{ providedIn: 'root' }]
|
|
144
|
+
}] });
|
|
145
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2hlc3NpbWFscy1jaGFsbGVuZ2UtcHJvZ3Jlc3Muc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9saWIvY29tcG9uZW50cy9vcmdhbmlzbXMvbWluaS1nYW1lcy9jaGVzc2ltYWxzLWNoYWxsZW5nZS1wcm9ncmVzcy5zZXJ2aWNlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxJQUFJLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUMxQyxPQUFPLEVBQ0wsU0FBUyxFQUNULFVBQVUsRUFDVixHQUFHLEVBQ0gsTUFBTSxFQUNOLEtBQUssRUFDTCxVQUFVLEVBQ1YsT0FBTyxFQUNQLEtBQUssRUFDTCxlQUFlLEVBQ2YsTUFBTSxHQUNQLE1BQU0seUJBQXlCLENBQUM7QUFDakMsT0FBTyxFQUFFLFVBQVUsRUFBRSxFQUFFLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFFdEMsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLDZDQUE2QyxDQUFDOztBQU85RSxNQUFNLFlBQVksR0FBRyxFQUFFLEtBQUssRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsQ0FBQztBQUdqRSxNQUFNLE9BQU8sa0NBQWtDO0lBRC9DO1FBRW1CLGlCQUFZLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzVCLGNBQVMsR0FBRyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDOUIsYUFBUSxHQUFHLE1BQU0sQ0FBQyxlQUFlLENBQUMsQ0FBQztLQTRKckQ7SUExSkMsSUFBSSxVQUFVO1FBQ1osT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsRUFBRSxHQUFHLENBQUM7SUFDNUMsQ0FBQztJQUVELFVBQVU7UUFD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USxDQUFDLEdBQVc7UUFDMUIsT0FBTyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxTQUFTLEdBQUcsdUNBQXVDLENBQUMsQ0FBQztJQUNsRixDQUFDO0lBRU8sTUFBTSxDQUFDLEdBQVcsRUFBRSxLQUFhO1FBQ3ZDLE9BQU8sR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDL0QsQ0FBQztJQUVPLFFBQVEsQ0FBQyxHQUFXO1FBQzFCLE9BQU8sU0FBUyxHQUFHLHFDQUFxQyxDQUFDO0lBQzNELENBQUM7SUFFTyxnQkFBZ0IsQ0FBb0MsS0FBUTtRQUNsRSxPQUFPLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUU7WUFDeEQsSUFBSSxLQUFLLEtBQUssU0FBUztnQkFBRSxHQUFHLENBQUMsR0FBYyxDQUFDLEdBQUcsS0FBbUIsQ0FBQztZQUNuRSxPQUFPLEdBQUcsQ0FBQztRQUNiLENBQUMsRUFBRSxFQUFPLENBQUMsQ0FBQztJQUNkLENBQUM7K0dBOUpVLGtDQUFrQzttSEFBbEMsa0NBQWtDLGNBRHJCLE1BQU07OzRGQUNuQixrQ0FBa0M7a0JBRDlDLFVBQVU7bUJBQUMsRUFBRSxVQUFVLEVBQUUsTUFBTSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0YWJsZSwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBBdXRoIH0gZnJvbSAnQGFuZ3VsYXIvZmlyZS9hdXRoJztcbmltcG9ydCB7XG4gIEZpcmVzdG9yZSxcbiAgY29sbGVjdGlvbixcbiAgZG9jLFxuICBnZXREb2MsXG4gIGxpbWl0LFxuICBvblNuYXBzaG90LFxuICBvcmRlckJ5LFxuICBxdWVyeSxcbiAgc2VydmVyVGltZXN0YW1wLFxuICBzZXREb2MsXG59IGZyb20gJ0Bhbmd1bGFyL2ZpcmUvZmlyZXN0b3JlJztcbmltcG9ydCB7IE9ic2VydmFibGUsIG9mIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IEZpcmViYXNlU2VydmljZSB9IGZyb20gJy4uLy4uLy4uL3NlcnZpY2VzL2ZpcmViYXNlL2ZpcmViYXNlLnNlcnZpY2UnO1xuaW1wb3J0IHtcbiAgQ2hlc3NpbWFsc0NoYWxsZW5nZVJvdW5kU3RhdHMsXG4gIENoZXNzaW1hbHNDaGFsbGVuZ2VSdW4sXG4gIENoZXNzaW1hbHNDaGFsbGVuZ2VTdGF0cyxcbn0gZnJvbSAnLi90eXBlcyc7XG5cbmNvbnN0IEVNUFRZX1BPV0VSUyA9IHsgZWFnbGU6IDAsIGJ1bGw6IDAsIGthbmdhcm9vOiAwLCBsaW9uOiAwIH07XG5cbkBJbmplY3RhYmxlKHsgcHJvdmlkZWRJbjogJ3Jvb3QnIH0pXG5leHBvcnQgY2xhc3MgQ2hlc3NpbWFsc0NoYWxsZW5nZVByb2dyZXNzU2VydmljZSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmlyZWJhc2VBdXRoID0gaW5qZWN0KEF1dGgpO1xuICBwcml2YXRlIHJlYWRvbmx5IGZpcmVzdG9yZSA9IGluamVjdChGaXJlc3RvcmUpO1xuICBwcml2YXRlIHJlYWRvbmx5IGZpcmViYXNlID0gaW5qZWN0KEZpcmViYXNlU2VydmljZSk7XG5cbiAgZ2V0IGN1cnJlbnRVaWQoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5maXJlYmFzZUF1dGguY3VycmVudFVzZXI/LnVpZDtcbiAgfVxuXG4gIHdhdGNoU3RhdHMoKTogT2JzZXJ2YWJsZTxDaGVzc2ltYWxzQ2hhbGxlbmdlU3RhdHMgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCB1aWQgPSB0aGlzLmN1cnJlbnRVaWQ7XG4gICAgaWYgKCF1aWQpIHJldHVybiBvZih1bmRlZmluZWQpO1xuICAgIHJldHVybiBuZXcgT2JzZXJ2YWJsZSgoc3Vic2NyaWJlcikgPT4ge1xuICAgICAgY29uc3QgdW5zdWJzY3JpYmUgPSBvblNuYXBzaG90KFxuICAgICAgICB0aGlzLnN0YXRzUmVmKHVpZCksXG4gICAgICAgIChzbmFwc2hvdCkgPT4gc3Vic2NyaWJlci5uZXh0KFxuICAgICAgICAgIHNuYXBzaG90LmV4aXN0cygpID8gdGhpcy5ub3JtYWxpemVTdGF0cyhzbmFwc2hvdC5kYXRhKCkgYXMgUGFydGlhbDxDaGVzc2ltYWxzQ2hhbGxlbmdlU3RhdHM+KSA6IHVuZGVmaW5lZCxcbiAgICAgICAgKSxcbiAgICAgICAgKGVycm9yKSA9PiBzdWJzY3JpYmVyLmVycm9yKGVycm9yKSxcbiAgICAgICk7XG4gICAgICByZXR1cm4gdW5zdWJzY3JpYmU7XG4gICAgfSk7XG4gIH1cblxuICB3YXRjaFJlY2VudFJ1bnMobGltaXRDb3VudCA9IDQpOiBPYnNlcnZhYmxlPENoZXNzaW1hbHNDaGFsbGVuZ2VSdW5bXT4ge1xuICAgIGNvbnN0IHVpZCA9IHRoaXMuY3VycmVudFVpZDtcbiAgICBpZiAoIXVpZCkgcmV0dXJuIG9mKFtdKTtcbiAgICBjb25zdCBydW5zUXVlcnkgPSBxdWVyeShcbiAgICAgIGNvbGxlY3Rpb24odGhpcy5maXJlc3RvcmUsIHRoaXMucnVuc1BhdGgodWlkKSksXG4gICAgICBvcmRlckJ5KCd1cGRhdGVkQXQnLCAnZGVzYycpLFxuICAgICAgbGltaXQobGltaXRDb3VudCksXG4gICAgKTtcbiAgICByZXR1cm4gbmV3IE9ic2VydmFibGUoKHN1YnNjcmliZXIpID0+IHtcbiAgICAgIGNvbnN0IHVuc3Vic2NyaWJlID0gb25TbmFwc2hvdChcbiAgICAgICAgcnVuc1F1ZXJ5LFxuICAgICAgICAoc25hcHNob3QpID0+IHN1YnNjcmliZXIubmV4dChzbmFwc2hvdC5kb2NzLm1hcCgoaXRlbSkgPT4gaXRlbS5kYXRhKCkgYXMgQ2hlc3NpbWFsc0NoYWxsZW5nZVJ1bikpLFxuICAgICAgICAoZXJyb3IpID0+IHN1YnNjcmliZXIuZXJyb3IoZXJyb3IpLFxuICAgICAgKTtcbiAgICAgIHJldHVybiB1bnN1YnNjcmliZTtcbiAgICB9KTtcbiAgfVxuXG4gIGFzeW5jIHNhdmVSdW4ocnVuOiBDaGVzc2ltYWxzQ2hhbGxlbmdlUnVuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgdWlkID0gYXdhaXQgdGhpcy5lbnN1cmVVc2VyKCk7XG4gICAgYXdhaXQgc2V0RG9jKHRoaXMucnVuUmVmKHVpZCwgcnVuLmlkKSwgdGhpcy53aXRob3V0VW5kZWZpbmVkKHtcbiAgICAgIC4uLnJ1bixcbiAgICAgIHVzZXJJZDogdWlkLFxuICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICB1cGRhdGVkQXRTZXJ2ZXI6IHNlcnZlclRpbWVzdGFtcCgpLFxuICAgIH0pLCB7IG1lcmdlOiB0cnVlIH0pO1xuICB9XG5cbiAgYXN5bmMgcmVjb3JkQ2hhbGxlbmdlU3RhcnRlZChydW46IENoZXNzaW1hbHNDaGFsbGVuZ2VSdW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB1aWQgPSBhd2FpdCB0aGlzLmVuc3VyZVVzZXIoKTtcbiAgICBjb25zdCBjdXJyZW50ID0gYXdhaXQgdGhpcy5yZWFkU3RhdHModWlkKTtcbiAgICBhd2FpdCBzZXREb2ModGhpcy5zdGF0c1JlZih1aWQpLCB7XG4gICAgICAuLi5jdXJyZW50LFxuICAgICAgdXNlcklkOiB1aWQsXG4gICAgICBjaGFsbGVuZ2VzUGxheWVkOiBjdXJyZW50LmNoYWxsZW5nZXNQbGF5ZWQgKyAxLFxuICAgICAgdXBkYXRlZEF0OiBuZXcgRGF0ZSgpLnRvSVNPU3RyaW5nKCksXG4gICAgICB1cGRhdGVkQXRTZXJ2ZXI6IHNlcnZlclRpbWVzdGFtcCgpLFxuICAgIH0sIHsgbWVyZ2U6IHRydWUgfSk7XG4gICAgYXdhaXQgdGhpcy5zYXZlUnVuKHJ1bik7XG4gIH1cblxuICBhc3luYyBhcHBseVJvdW5kUmVzdWx0KGFyZ3M6IHtcbiAgICBydW46IENoZXNzaW1hbHNDaGFsbGVuZ2VSdW47XG4gICAgcm91bmRSZWFjaGVkOiBudW1iZXI7XG4gICAgd29uOiBib29sZWFuO1xuICAgIGNvbXBsZXRlZDogYm9vbGVhbjtcbiAgICByb3VuZFN0YXRzOiBDaGVzc2ltYWxzQ2hhbGxlbmdlUm91bmRTdGF0cztcbiAgfSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHVpZCA9IGF3YWl0IHRoaXMuZW5zdXJlVXNlcigpO1xuICAgIGNvbnN0IGN1cnJlbnQgPSBhd2FpdCB0aGlzLnJlYWRTdGF0cyh1aWQpO1xuICAgIGNvbnN0IG5leHQ6IENoZXNzaW1hbHNDaGFsbGVuZ2VTdGF0cyA9IHtcbiAgICAgIHVzZXJJZDogdWlkLFxuICAgICAgY2hhbGxlbmdlc1BsYXllZDogY3VycmVudC5jaGFsbGVuZ2VzUGxheWVkLFxuICAgICAgY2hhbGxlbmdlc0NvbXBsZXRlZDogY3VycmVudC5jaGFsbGVuZ2VzQ29tcGxldGVkICsgKGFyZ3MuY29tcGxldGVkID8gMSA6IDApLFxuICAgICAgYmVzdFdpblN0cmVhazogTWF0aC5tYXgoY3VycmVudC5iZXN0V2luU3RyZWFrLCBhcmdzLnJ1bi5iZXN0U3RyZWFrSW5SdW4pLFxuICAgICAgYmVzdFJvdW5kUmVhY2hlZDogTWF0aC5tYXgoY3VycmVudC5iZXN0Um91bmRSZWFjaGVkLCBhcmdzLnJvdW5kUmVhY2hlZCksXG4gICAgICB0b3RhbFdpbnM6IGN1cnJlbnQudG90YWxXaW5zICsgKGFyZ3Mud29uID8gMSA6IDApLFxuICAgICAgdG90YWxMb3NzZXM6IGN1cnJlbnQudG90YWxMb3NzZXMgKyAoYXJncy53b24gPyAwIDogMSksXG4gICAgICBib3RzRGVmZWF0ZWQ6IGN1cnJlbnQuYm90c0RlZmVhdGVkICsgKGFyZ3Mud29uID8gMSA6IDApLFxuICAgICAgcG93ZXJzVXNlZDoge1xuICAgICAgICBlYWdsZTogY3VycmVudC5wb3dlcnNVc2VkLmVhZ2xlICsgYXJncy5yb3VuZFN0YXRzLnBvd2Vyc1VzZWQuZWFnbGUsXG4gICAgICAgIGJ1bGw6IGN1cnJlbnQucG93ZXJzVXNlZC5idWxsICsgYXJncy5yb3VuZFN0YXRzLnBvd2Vyc1VzZWQuYnVsbCxcbiAgICAgICAga2FuZ2Fyb286IGN1cnJlbnQucG93ZXJzVXNlZC5rYW5nYXJvbyArIGFyZ3Mucm91bmRTdGF0cy5wb3dlcnNVc2VkLmthbmdhcm9vLFxuICAgICAgICBsaW9uOiBjdXJyZW50LnBvd2Vyc1VzZWQubGlvbiArIGFyZ3Mucm91bmRTdGF0cy5wb3dlcnNVc2VkLmxpb24sXG4gICAgICB9LFxuICAgICAgcG93ZXJDYXB0dXJlczogY3VycmVudC5wb3dlckNhcHR1cmVzICsgYXJncy5yb3VuZFN0YXRzLnBvd2VyQ2FwdHVyZXMsXG4gICAgICBwcm9tb3Rpb25zOiBjdXJyZW50LnByb21vdGlvbnMgKyBhcmdzLnJvdW5kU3RhdHMucHJvbW90aW9ucyxcbiAgICAgIHVwZGF0ZWRBdDogbmV3IERhdGUoKS50b0lTT1N0cmluZygpLFxuICAgIH07XG4gICAgYXdhaXQgc2V0RG9jKHRoaXMuc3RhdHNSZWYodWlkKSwgeyAuLi5uZXh0LCB1cGRhdGVkQXRTZXJ2ZXI6IHNlcnZlclRpbWVzdGFtcCgpIH0sIHsgbWVyZ2U6IHRydWUgfSk7XG4gICAgYXdhaXQgdGhpcy5zYXZlUnVuKGFyZ3MucnVuKTtcbiAgfVxuXG4gIGVtcHR5U3RhdHMoKTogQ2hlc3NpbWFsc0NoYWxsZW5nZVN0YXRzIHtcbiAgICByZXR1cm4ge1xuICAgICAgY2hhbGxlbmdlc1BsYXllZDogMCxcbiAgICAgIGNoYWxsZW5nZXNDb21wbGV0ZWQ6IDAsXG4gICAgICBiZXN0V2luU3RyZWFrOiAwLFxuICAgICAgYmVzdFJvdW5kUmVhY2hlZDogMCxcbiAgICAgIHRvdGFsV2luczogMCxcbiAgICAgIHRvdGFsTG9zc2VzOiAwLFxuICAgICAgYm90c0RlZmVhdGVkOiAwLFxuICAgICAgcG93ZXJzVXNlZDogeyAuLi5FTVBUWV9QT1dFUlMgfSxcbiAgICAgIHBvd2VyQ2FwdHVyZXM6IDAsXG4gICAgICBwcm9tb3Rpb25zOiAwLFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlYWRTdGF0cyh1aWQ6IHN0cmluZyk6IFByb21pc2U8Q2hlc3NpbWFsc0NoYWxsZW5nZVN0YXRzPiB7XG4gICAgLy8gRmlyZXN0b3JlJ3Mgd2ViIFNESyBkb2VzIG5vdCBuZWVkIGEgdHJhbnNhY3Rpb24gZm9yIHRoZXNlIGNhc3VhbCBnYW1lIHN0YXRzLlxuICAgIC8vIExhc3Qtd3JpdGUtd2lucyBpcyBhY2NlcHRhYmxlIGZvciB0aGlzIGZpcnN0IHZlcnNpb24gYmVjYXVzZSBvbmUgcnVuIGlzIGFjdGl2ZSBwZXIgYnJvd3Nlci5cbiAgICBjb25zdCBzbmFwc2hvdCA9IGF3YWl0IGdldERvYyh0aGlzLnN0YXRzUmVmKHVpZCkpO1xuICAgIHJldHVybiBzbmFwc2hvdC5leGlzdHMoKSA/IHRoaXMubm9ybWFsaXplU3RhdHMoc25hcHNob3QuZGF0YSgpIGFzIFBhcnRpYWw8Q2hlc3NpbWFsc0NoYWxsZW5nZVN0YXRzPikgOiB0aGlzLmVtcHR5U3RhdHMoKTtcbiAgfVxuXG4gIHByaXZhdGUgbm9ybWFsaXplU3RhdHModmFsdWU6IFBhcnRpYWw8Q2hlc3NpbWFsc0NoYWxsZW5nZVN0YXRzPik6IENoZXNzaW1hbHNDaGFsbGVuZ2VTdGF0cyB7XG4gICAgY29uc3QgZW1wdHkgPSB0aGlzLmVtcHR5U3RhdHMoKTtcbiAgICByZXR1cm4ge1xuICAgICAgLi4uZW1wdHksXG4gICAgICAuLi52YWx1ZSxcbiAgICAgIHBvd2Vyc1VzZWQ6IHtcbiAgICAgICAgLi4uRU1QVFlfUE9XRVJTLFxuICAgICAgICAuLi4odmFsdWUucG93ZXJzVXNlZCA/PyB7fSksXG4gICAgICB9LFxuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGVuc3VyZVVzZXIoKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBhd2FpdCB0aGlzLmZpcmViYXNlLndoZW5GaXJlYmFzZUF1dGhSZWFkeSgpO1xuICAgIGNvbnN0IHVzZXIgPSB0aGlzLmZpcmViYXNlQXV0aC5jdXJyZW50VXNlcjtcbiAgICBpZiAodXNlcj8udWlkKSB7XG4gICAgICBhd2FpdCB1c2VyLmdldElkVG9rZW4oKTtcbiAgICAgIHJldHVybiB1c2VyLnVpZDtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKCdDSEVTU0lNQUxTX0NIQUxMRU5HRV9MT0dJTl9SRVFVSVJFRCcpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0c1JlZih1aWQ6IHN0cmluZykge1xuICAgIHJldHVybiBkb2ModGhpcy5maXJlc3RvcmUsIGB1c2Vycy8ke3VpZH0vbWluaUdhbWVzL2NoZXNzaW1hbHMvY2hhbGxlbmdlL3N0YXRzYCk7XG4gIH1cblxuICBwcml2YXRlIHJ1blJlZih1aWQ6IHN0cmluZywgcnVuSWQ6IHN0cmluZykge1xuICAgIHJldHVybiBkb2ModGhpcy5maXJlc3RvcmUsIGAke3RoaXMucnVuc1BhdGgodWlkKX0vJHtydW5JZH1gKTtcbiAgfVxuXG4gIHByaXZhdGUgcnVuc1BhdGgodWlkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiBgdXNlcnMvJHt1aWR9L21pbmlHYW1lcy9jaGVzc2ltYWxzL2NoYWxsZW5nZVJ1bnNgO1xuICB9XG5cbiAgcHJpdmF0ZSB3aXRob3V0VW5kZWZpbmVkPFQgZXh0ZW5kcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4odmFsdWU6IFQpOiBUIHtcbiAgICByZXR1cm4gT2JqZWN0LmVudHJpZXModmFsdWUpLnJlZHVjZSgoYWNjLCBba2V5LCBlbnRyeV0pID0+IHtcbiAgICAgIGlmIChlbnRyeSAhPT0gdW5kZWZpbmVkKSBhY2Nba2V5IGFzIGtleW9mIFRdID0gZW50cnkgYXMgVFtrZXlvZiBUXTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30gYXMgVCk7XG4gIH1cbn1cbiJdfQ==
|