UNPKG

29.6 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const utils_1 = require("@neo-one/utils");
4const rxjs_1 = require("rxjs");
5const operators_1 = require("rxjs/operators");
6const tasks_1 = require("./tasks");
7class TaskWrapper {
8 constructor({ task, taskList, collapse, }) {
9 this.task = task;
10 this.taskList = taskList;
11 this.status$ = new rxjs_1.BehaviorSubject({
12 id: task.title,
13 title: task.title,
14 collapse,
15 });
16 this.skip = task.skip === undefined ? (_ctx) => false : task.skip;
17 this.getEnabled = task.enabled === undefined ? (_ctx) => true : task.enabled;
18 this.mutableAborted = false;
19 }
20 check(ctx) {
21 if (this.enabled && !this.pending && !this.done && !this.getEnabled(ctx)) {
22 this.status$.next(undefined);
23 }
24 }
25 get enabled() {
26 return this.status$.getValue() !== undefined;
27 }
28 get pending() {
29 const status = this.status$.getValue();
30 return status !== undefined && status.pending === true;
31 }
32 get done() {
33 const status = this.status$.getValue();
34 return status !== undefined && tasks_1.isTaskDone(status);
35 }
36 get error() {
37 const status = this.status$.getValue();
38 return status === undefined ? undefined : tasks_1.getTaskError(status);
39 }
40 abort() {
41 this.mutableAborted = true;
42 const status = this.status$.getValue();
43 if (status !== undefined) {
44 this.status$.next(Object.assign({}, status, { skipped: 'Aborted' }));
45 }
46 this.status$.complete();
47 }
48 complete() {
49 this.status$.complete();
50 }
51 async run(ctx) {
52 const statusIn = this.status$.getValue();
53 if (statusIn === undefined) {
54 this.status$.complete();
55 return;
56 }
57 if (this.mutableAborted) {
58 return;
59 }
60 let status = Object.assign({}, statusIn, { pending: true });
61 const onError = (error) => {
62 this.taskList.onError(error, ctx);
63 this.taskList.mutableSuperOnError(error);
64 };
65 try {
66 const skip = this.skip(ctx);
67 if (skip !== false) {
68 status = Object.assign({}, status, { pending: false, skipped: skip });
69 this.status$.next(status);
70 }
71 else {
72 this.status$.next(status);
73 // tslint:disable-next-line rxjs-finnish
74 const result = this.task.task(ctx);
75 let error;
76 let message;
77 if (result instanceof rxjs_1.Observable) {
78 await result
79 .pipe(operators_1.map((msg) => {
80 status = Object.assign({}, status, { message: msg });
81 this.status$.next(status);
82 }))
83 .toPromise();
84 }
85 else if (result instanceof Promise) {
86 message = await result;
87 }
88 else if (result instanceof TaskList) {
89 result.setSuperOnError(onError);
90 // tslint:disable-next-line no-floating-promises
91 result.run(ctx);
92 const finalSubtasks = await result.status$
93 .pipe(operators_1.map((subtasks) => {
94 status = Object.assign({}, status, { subtasks });
95 this.status$.next(status);
96 return subtasks;
97 }))
98 .toPromise();
99 error = tasks_1.getTasksError(finalSubtasks);
100 }
101 this.status$.next(Object.assign({}, status, { pending: false, complete: error === undefined, message: message === undefined ? undefined : message, error }));
102 }
103 }
104 catch (error) {
105 const message = error.stack == undefined ? error.message : error.stack;
106 this.status$.next(Object.assign({}, status, { pending: false, error: message == undefined || message === '' ? 'Something went wrong.' : message }));
107 onError(error);
108 }
109 this.status$.complete();
110 }
111}
112class TaskList {
113 constructor({ tasks, concurrent = false, onError, onComplete, onDone, initialContext = {}, freshContext = false, collapse = true, }) {
114 this.tasks = tasks.map((task) => new TaskWrapper({
115 task,
116 taskList: this,
117 collapse,
118 }));
119 this.concurrent = concurrent;
120 this.onError =
121 onError === undefined
122 ? (_error, _ctx) => {
123 // do nothing
124 }
125 : onError;
126 this.onComplete =
127 onComplete === undefined
128 ? () => {
129 // do nothing
130 }
131 : onComplete;
132 this.onDone =
133 onDone === undefined
134 ? (_failed) => {
135 // do nothing
136 }
137 : onDone;
138 this.initialContext = initialContext;
139 this.freshContext = freshContext;
140 this.mutableSuperOnError = (_error) => {
141 // do nothing
142 };
143 this.statusInternal$ = new rxjs_1.ReplaySubject(1);
144 }
145 get status$() {
146 this.run().catch((error) => this.onError(error, {}));
147 return this.statusInternal$;
148 }
149 async toPromise() {
150 const result = await this.status$.toPromise();
151 const error = tasks_1.getTasksError(result);
152 if (error !== undefined) {
153 throw new Error(error);
154 }
155 }
156 async abort() {
157 await this.abort$().toPromise();
158 }
159 abort$() {
160 this.tasks.forEach((task) => task.abort());
161 return this.status$;
162 }
163 setSuperOnError(onError) {
164 this.mutableSuperOnError = onError;
165 }
166 async run(ctxIn = {}) {
167 if (this.mutableSubscription !== undefined) {
168 return;
169 }
170 const ctx = this.freshContext ? {} : ctxIn;
171 Object.entries(this.initialContext).forEach(([key, value]) => {
172 // tslint:disable-next-line no-object-mutation
173 ctx[key] = value;
174 });
175 this.checkAll(ctx);
176 this.mutableSubscription = rxjs_1.combineLatest(this.tasks.map((task) => task.status$))
177 .pipe(operators_1.map((statuses) => statuses.filter(utils_1.utils.notNull)))
178 .subscribe(this.statusInternal$);
179 await this.runTasks(ctx);
180 const err = tasks_1.getTasksError(this.tasks.map((task) => task.status$.getValue()).filter(utils_1.utils.notNull));
181 if (err === undefined) {
182 this.onComplete();
183 }
184 this.onDone(err !== undefined);
185 }
186 async runTasks(ctx) {
187 if (this.tasks.length === 0) {
188 this.statusInternal$.next([]);
189 return;
190 }
191 if (this.concurrent) {
192 await Promise.all(this.tasks.map(async (task) => task.run(ctx)));
193 }
194 else {
195 let error;
196 // tslint:disable-next-line no-loop-statement
197 for (const task of this.tasks) {
198 if (error === undefined) {
199 await task.run(ctx);
200 }
201 else {
202 task.complete();
203 }
204 error = task.error;
205 }
206 }
207 }
208 checkAll(ctx) {
209 this.tasks.forEach((task) => task.check(ctx));
210 }
211}
212exports.TaskList = TaskList;
213
214//# sourceMappingURL=data:application/json;charset=utf8;base64,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QUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDaEQsQ0FBQztDQUNGO0FBMUlELDRCQTBJQyIsImZpbGUiOiJuZW8tb25lLXNlcnZlci1wbHVnaW4vc3JjL1Rhc2tMaXN0LmpzIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgdXRpbHMgfSBmcm9tICdAbmVvLW9uZS91dGlscyc7XG5pbXBvcnQgeyBCZWhhdmlvclN1YmplY3QsIGNvbWJpbmVMYXRlc3QsIE9ic2VydmFibGUsIFJlcGxheVN1YmplY3QsIFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgbWFwIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgZ2V0VGFza0Vycm9yLCBnZXRUYXNrc0Vycm9yLCBpc1Rhc2tEb25lIH0gZnJvbSAnLi90YXNrcyc7XG5pbXBvcnQgeyBUYXNrU3RhdHVzIH0gZnJvbSAnLi90eXBlcyc7XG5cbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1hbnlcbmV4cG9ydCB0eXBlIFRhc2tDb250ZXh0ID0gYW55O1xudHlwZSBTa2lwRm4gPSAoY3R4OiBUYXNrQ29udGV4dCkgPT4gc3RyaW5nIHwgYm9vbGVhbjtcbnR5cGUgRW5hYmxlZEZuID0gKGN0eDogVGFza0NvbnRleHQpID0+IGJvb2xlYW47XG50eXBlIE9uRXJyb3JGbiA9IChlcnJvcjogRXJyb3IsIGN0eDogVGFza0NvbnRleHQpID0+IHZvaWQ7XG50eXBlIE9uRG9uZUZuID0gKGZhaWxlZDogYm9vbGVhbikgPT4gdm9pZDtcblxuZXhwb3J0IGludGVyZmFjZSBUYXNrIHtcbiAgcmVhZG9ubHkgc2tpcD86IFNraXBGbjtcbiAgcmVhZG9ubHkgZW5hYmxlZD86IEVuYWJsZWRGbjtcbiAgcmVhZG9ubHkgdGFzazogKGN0eDogVGFza0NvbnRleHQpID0+IFByb21pc2U8dm9pZD4gfCBQcm9taXNlPHN0cmluZz4gfCBPYnNlcnZhYmxlPHN0cmluZz4gfCBUYXNrTGlzdCB8IHZvaWQ7XG4gIHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgVGFza0xpc3RPcHRpb25zIHtcbiAgcmVhZG9ubHkgdGFza3M6IFJlYWRvbmx5QXJyYXk8VGFzaz47XG4gIHJlYWRvbmx5IGNvbmN1cnJlbnQ/OiBib29sZWFuO1xuICByZWFkb25seSBvbkVycm9yPzogT25FcnJvckZuO1xuICByZWFkb25seSBvbkNvbXBsZXRlPzogKCkgPT4gdm9pZDtcbiAgcmVhZG9ubHkgb25Eb25lPzogT25Eb25lRm47XG4gIHJlYWRvbmx5IGluaXRpYWxDb250ZXh0PzogVGFza0NvbnRleHQ7XG4gIHJlYWRvbmx5IGZyZXNoQ29udGV4dD86IGJvb2xlYW47XG4gIHJlYWRvbmx5IGNvbGxhcHNlPzogYm9vbGVhbjtcbn1cblxuY2xhc3MgVGFza1dyYXBwZXIge1xuICBwdWJsaWMgcmVhZG9ubHkgc3RhdHVzJDogQmVoYXZpb3JTdWJqZWN0PFRhc2tTdGF0dXMgfCB1bmRlZmluZWQ+O1xuICBwcml2YXRlIHJlYWRvbmx5IHRhc2s6IFRhc2s7XG4gIHByaXZhdGUgcmVhZG9ubHkgdGFza0xpc3Q6IFRhc2tMaXN0O1xuICBwcml2YXRlIHJlYWRvbmx5IHNraXA6IFNraXBGbjtcbiAgcHJpdmF0ZSByZWFkb25seSBnZXRFbmFibGVkOiBFbmFibGVkRm47XG4gIHByaXZhdGUgbXV0YWJsZUFib3J0ZWQ6IGJvb2xlYW47XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKHtcbiAgICB0YXNrLFxuICAgIHRhc2tMaXN0LFxuICAgIGNvbGxhcHNlLFxuICB9OiB7XG4gICAgcmVhZG9ubHkgdGFzazogVGFzaztcbiAgICByZWFkb25seSB0YXNrTGlzdDogVGFza0xpc3Q7XG4gICAgcmVhZG9ubHkgY29sbGFwc2U6IGJvb2xlYW47XG4gIH0pIHtcbiAgICB0aGlzLnRhc2sgPSB0YXNrO1xuICAgIHRoaXMudGFza0xpc3QgPSB0YXNrTGlzdDtcbiAgICB0aGlzLnN0YXR1cyQgPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFRhc2tTdGF0dXMgfCB1bmRlZmluZWQ+KHtcbiAgICAgIGlkOiB0YXNrLnRpdGxlLFxuICAgICAgdGl0bGU6IHRhc2sudGl0bGUsXG4gICAgICBjb2xsYXBzZSxcbiAgICB9KTtcblxuICAgIHRoaXMuc2tpcCA9IHRhc2suc2tpcCA9PT0gdW5kZWZpbmVkID8gKF9jdHgpID0+IGZhbHNlIDogdGFzay5za2lwO1xuICAgIHRoaXMuZ2V0RW5hYmxlZCA9IHRhc2suZW5hYmxlZCA9PT0gdW5kZWZpbmVkID8gKF9jdHgpID0+IHRydWUgOiB0YXNrLmVuYWJsZWQ7XG4gICAgdGhpcy5tdXRhYmxlQWJvcnRlZCA9IGZhbHNlO1xuICB9XG5cbiAgcHVibGljIGNoZWNrKGN0eDogVGFza0NvbnRleHQpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5lbmFibGVkICYmICF0aGlzLnBlbmRpbmcgJiYgIXRoaXMuZG9uZSAmJiAhdGhpcy5nZXRFbmFibGVkKGN0eCkpIHtcbiAgICAgIHRoaXMuc3RhdHVzJC5uZXh0KHVuZGVmaW5lZCk7XG4gICAgfVxuICB9XG5cbiAgcHVibGljIGdldCBlbmFibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnN0YXR1cyQuZ2V0VmFsdWUoKSAhPT0gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHVibGljIGdldCBwZW5kaW5nKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHN0YXR1cyA9IHRoaXMuc3RhdHVzJC5nZXRWYWx1ZSgpO1xuXG4gICAgcmV0dXJuIHN0YXR1cyAhPT0gdW5kZWZpbmVkICYmIHN0YXR1cy5wZW5kaW5nID09PSB0cnVlO1xuICB9XG5cbiAgcHVibGljIGdldCBkb25lKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHN0YXR1cyA9IHRoaXMuc3RhdHVzJC5nZXRWYWx1ZSgpO1xuXG4gICAgcmV0dXJuIHN0YXR1cyAhPT0gdW5kZWZpbmVkICYmIGlzVGFza0RvbmUoc3RhdHVzKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXQgZXJyb3IoKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBzdGF0dXMgPSB0aGlzLnN0YXR1cyQuZ2V0VmFsdWUoKTtcblxuICAgIHJldHVybiBzdGF0dXMgPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IGdldFRhc2tFcnJvcihzdGF0dXMpO1xuICB9XG5cbiAgcHVibGljIGFib3J0KCk6IHZvaWQge1xuICAgIHRoaXMubXV0YWJsZUFib3J0ZWQgPSB0cnVlO1xuICAgIGNvbnN0IHN0YXR1cyA9IHRoaXMuc3RhdHVzJC5nZXRWYWx1ZSgpO1xuICAgIGlmIChzdGF0dXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5zdGF0dXMkLm5leHQoeyAuLi5zdGF0dXMsIHNraXBwZWQ6ICdBYm9ydGVkJyB9KTtcbiAgICB9XG4gICAgdGhpcy5zdGF0dXMkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBwdWJsaWMgY29tcGxldGUoKTogdm9pZCB7XG4gICAgdGhpcy5zdGF0dXMkLmNvbXBsZXRlKCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcnVuKGN0eDogVGFza0NvbnRleHQpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzdGF0dXNJbiA9IHRoaXMuc3RhdHVzJC5nZXRWYWx1ZSgpO1xuICAgIGlmIChzdGF0dXNJbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLnN0YXR1cyQuY29tcGxldGUoKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5tdXRhYmxlQWJvcnRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGxldCBzdGF0dXMgPSB7IC4uLnN0YXR1c0luLCBwZW5kaW5nOiB0cnVlIH07XG5cbiAgICBjb25zdCBvbkVycm9yID0gKGVycm9yOiBFcnJvcikgPT4ge1xuICAgICAgdGhpcy50YXNrTGlzdC5vbkVycm9yKGVycm9yLCBjdHgpO1xuICAgICAgdGhpcy50YXNrTGlzdC5tdXRhYmxlU3VwZXJPbkVycm9yKGVycm9yKTtcbiAgICB9O1xuXG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHNraXAgPSB0aGlzLnNraXAoY3R4KTtcbiAgICAgIGlmIChza2lwICE9PSBmYWxzZSkge1xuICAgICAgICBzdGF0dXMgPSB7IC4uLnN0YXR1cywgcGVuZGluZzogZmFsc2UsIHNraXBwZWQ6IHNraXAgfTtcbiAgICAgICAgdGhpcy5zdGF0dXMkLm5leHQoc3RhdHVzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuc3RhdHVzJC5uZXh0KHN0YXR1cyk7XG5cbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIHJ4anMtZmlubmlzaFxuICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLnRhc2sudGFzayhjdHgpO1xuXG4gICAgICAgIGxldCBlcnJvcjtcbiAgICAgICAgbGV0IG1lc3NhZ2U6IHN0cmluZyB8IHVuZGVmaW5lZCB8IHZvaWQ7XG4gICAgICAgIGlmIChyZXN1bHQgaW5zdGFuY2VvZiBPYnNlcnZhYmxlKSB7XG4gICAgICAgICAgYXdhaXQgcmVzdWx0XG4gICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgbWFwKChtc2cpID0+IHtcbiAgICAgICAgICAgICAgICBzdGF0dXMgPSB7IC4uLnN0YXR1cywgbWVzc2FnZTogbXNnIH07XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0dXMkLm5leHQoc3RhdHVzKTtcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAudG9Qcm9taXNlKCk7XG4gICAgICAgIH0gZWxzZSBpZiAocmVzdWx0IGluc3RhbmNlb2YgUHJvbWlzZSkge1xuICAgICAgICAgIG1lc3NhZ2UgPSBhd2FpdCByZXN1bHQ7XG4gICAgICAgIH0gZWxzZSBpZiAocmVzdWx0IGluc3RhbmNlb2YgVGFza0xpc3QpIHtcbiAgICAgICAgICByZXN1bHQuc2V0U3VwZXJPbkVycm9yKG9uRXJyb3IpO1xuICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1mbG9hdGluZy1wcm9taXNlc1xuICAgICAgICAgIHJlc3VsdC5ydW4oY3R4KTtcbiAgICAgICAgICBjb25zdCBmaW5hbFN1YnRhc2tzID0gYXdhaXQgcmVzdWx0LnN0YXR1cyRcbiAgICAgICAgICAgIC5waXBlKFxuICAgICAgICAgICAgICBtYXAoKHN1YnRhc2tzKSA9PiB7XG4gICAgICAgICAgICAgICAgc3RhdHVzID0geyAuLi5zdGF0dXMsIHN1YnRhc2tzIH07XG4gICAgICAgICAgICAgICAgdGhpcy5zdGF0dXMkLm5leHQoc3RhdHVzKTtcblxuICAgICAgICAgICAgICAgIHJldHVybiBzdWJ0YXNrcztcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICApXG4gICAgICAgICAgICAudG9Qcm9taXNlKCk7XG4gICAgICAgICAgZXJyb3IgPSBnZXRUYXNrc0Vycm9yKGZpbmFsU3VidGFza3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5zdGF0dXMkLm5leHQoe1xuICAgICAgICAgIC4uLnN0YXR1cyxcbiAgICAgICAgICBwZW5kaW5nOiBmYWxzZSxcbiAgICAgICAgICBjb21wbGV0ZTogZXJyb3IgPT09IHVuZGVmaW5lZCxcbiAgICAgICAgICBtZXNzYWdlOiBtZXNzYWdlID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBtZXNzYWdlLFxuICAgICAgICAgIGVycm9yLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc3QgbWVzc2FnZSA9IGVycm9yLnN0YWNrID09IHVuZGVmaW5lZCA/IGVycm9yLm1lc3NhZ2UgOiBlcnJvci5zdGFjaztcbiAgICAgIHRoaXMuc3RhdHVzJC5uZXh0KHtcbiAgICAgICAgLi4uc3RhdHVzLFxuICAgICAgICBwZW5kaW5nOiBmYWxzZSxcbiAgICAgICAgZXJyb3I6IG1lc3NhZ2UgPT0gdW5kZWZpbmVkIHx8IG1lc3NhZ2UgPT09ICcnID8gJ1NvbWV0aGluZyB3ZW50IHdyb25nLicgOiBtZXNzYWdlLFxuICAgICAgfSk7XG5cbiAgICAgIG9uRXJyb3IoZXJyb3IpO1xuICAgIH1cblxuICAgIHRoaXMuc3RhdHVzJC5jb21wbGV0ZSgpO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBUYXNrTGlzdCB7XG4gIHB1YmxpYyBtdXRhYmxlU3VwZXJPbkVycm9yOiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkO1xuICBwdWJsaWMgcmVhZG9ubHkgb25FcnJvcjogT25FcnJvckZuO1xuICBwcml2YXRlIHJlYWRvbmx5IHRhc2tzOiBSZWFkb25seUFycmF5PFRhc2tXcmFwcGVyPjtcbiAgcHJpdmF0ZSByZWFkb25seSBjb25jdXJyZW50OiBib29sZWFuO1xuICBwcml2YXRlIHJlYWRvbmx5IG9uQ29tcGxldGU6ICgpID0+IHZvaWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgb25Eb25lOiBPbkRvbmVGbjtcbiAgcHJpdmF0ZSByZWFkb25seSBpbml0aWFsQ29udGV4dDogVGFza0NvbnRleHQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgZnJlc2hDb250ZXh0OiBib29sZWFuO1xuICBwcml2YXRlIHJlYWRvbmx5IHN0YXR1c0ludGVybmFsJDogUmVwbGF5U3ViamVjdDxSZWFkb25seUFycmF5PFRhc2tTdGF0dXM+PjtcbiAgcHJpdmF0ZSBtdXRhYmxlU3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gfCB1bmRlZmluZWQ7XG5cbiAgcHVibGljIGNvbnN0cnVjdG9yKHtcbiAgICB0YXNrcyxcbiAgICBjb25jdXJyZW50ID0gZmFsc2UsXG4gICAgb25FcnJvcixcbiAgICBvbkNvbXBsZXRlLFxuICAgIG9uRG9uZSxcbiAgICBpbml0aWFsQ29udGV4dCA9IHt9LFxuICAgIGZyZXNoQ29udGV4dCA9IGZhbHNlLFxuICAgIGNvbGxhcHNlID0gdHJ1ZSxcbiAgfTogVGFza0xpc3RPcHRpb25zKSB7XG4gICAgdGhpcy50YXNrcyA9IHRhc2tzLm1hcChcbiAgICAgICh0YXNrKSA9PlxuICAgICAgICBuZXcgVGFza1dyYXBwZXIoe1xuICAgICAgICAgIHRhc2ssXG4gICAgICAgICAgdGFza0xpc3Q6IHRoaXMsXG4gICAgICAgICAgY29sbGFwc2UsXG4gICAgICAgIH0pLFxuICAgICk7XG5cbiAgICB0aGlzLmNvbmN1cnJlbnQgPSBjb25jdXJyZW50O1xuICAgIHRoaXMub25FcnJvciA9XG4gICAgICBvbkVycm9yID09PSB1bmRlZmluZWRcbiAgICAgICAgPyAoX2Vycm9yLCBfY3R4KSA9PiB7XG4gICAgICAgICAgICAvLyBkbyBub3RoaW5nXG4gICAgICAgICAgfVxuICAgICAgICA6IG9uRXJyb3I7XG4gICAgdGhpcy5vbkNvbXBsZXRlID1cbiAgICAgIG9uQ29tcGxldGUgPT09IHVuZGVmaW5lZFxuICAgICAgICA/ICgpID0+IHtcbiAgICAgICAgICAgIC8vIGRvIG5vdGhpbmdcbiAgICAgICAgICB9XG4gICAgICAgIDogb25Db21wbGV0ZTtcbiAgICB0aGlzLm9uRG9uZSA9XG4gICAgICBvbkRvbmUgPT09IHVuZGVmaW5lZFxuICAgICAgICA/IChfZmFpbGVkKSA9PiB7XG4gICAgICAgICAgICAvLyBkbyBub3RoaW5nXG4gICAgICAgICAgfVxuICAgICAgICA6IG9uRG9uZTtcbiAgICB0aGlzLmluaXRpYWxDb250ZXh0ID0gaW5pdGlhbENvbnRleHQ7XG4gICAgdGhpcy5mcmVzaENvbnRleHQgPSBmcmVzaENvbnRleHQ7XG4gICAgdGhpcy5tdXRhYmxlU3VwZXJPbkVycm9yID0gKF9lcnJvcikgPT4ge1xuICAgICAgLy8gZG8gbm90aGluZ1xuICAgIH07XG5cbiAgICB0aGlzLnN0YXR1c0ludGVybmFsJCA9IG5ldyBSZXBsYXlTdWJqZWN0KDEpO1xuICB9XG5cbiAgcHVibGljIGdldCBzdGF0dXMkKCk6IE9ic2VydmFibGU8UmVhZG9ubHlBcnJheTxUYXNrU3RhdHVzPj4ge1xuICAgIHRoaXMucnVuKCkuY2F0Y2goKGVycm9yKSA9PiB0aGlzLm9uRXJyb3IoZXJyb3IsIHt9KSk7XG5cbiAgICByZXR1cm4gdGhpcy5zdGF0dXNJbnRlcm5hbCQ7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgdG9Qcm9taXNlKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuc3RhdHVzJC50b1Byb21pc2UoKTtcbiAgICBjb25zdCBlcnJvciA9IGdldFRhc2tzRXJyb3IocmVzdWx0KTtcbiAgICBpZiAoZXJyb3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgYWJvcnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5hYm9ydCQoKS50b1Byb21pc2UoKTtcbiAgfVxuXG4gIHB1YmxpYyBhYm9ydCQoKTogT2JzZXJ2YWJsZTxSZWFkb25seUFycmF5PFRhc2tTdGF0dXM+PiB7XG4gICAgdGhpcy50YXNrcy5mb3JFYWNoKCh0YXNrKSA9PiB0YXNrLmFib3J0KCkpO1xuXG4gICAgcmV0dXJuIHRoaXMuc3RhdHVzJDtcbiAgfVxuXG4gIHB1YmxpYyBzZXRTdXBlck9uRXJyb3Iob25FcnJvcjogKGVycm9yOiBFcnJvcikgPT4gdm9pZCk6IHZvaWQge1xuICAgIHRoaXMubXV0YWJsZVN1cGVyT25FcnJvciA9IG9uRXJyb3I7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgcnVuKGN0eEluOiBUYXNrQ29udGV4dCA9IHt9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMubXV0YWJsZVN1YnNjcmlwdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgY3R4ID0gdGhpcy5mcmVzaENvbnRleHQgPyB7fSA6IGN0eEluO1xuICAgIE9iamVjdC5lbnRyaWVzKHRoaXMuaW5pdGlhbENvbnRleHQpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLW9iamVjdC1tdXRhdGlvblxuICAgICAgY3R4W2tleV0gPSB2YWx1ZTtcbiAgICB9KTtcbiAgICB0aGlzLmNoZWNrQWxsKGN0eCk7XG5cbiAgICB0aGlzLm11dGFibGVTdWJzY3JpcHRpb24gPSBjb21iaW5lTGF0ZXN0KHRoaXMudGFza3MubWFwKCh0YXNrKSA9PiB0YXNrLnN0YXR1cyQpKVxuICAgICAgLnBpcGUobWFwKChzdGF0dXNlcyk6IFJlYWRvbmx5QXJyYXk8VGFza1N0YXR1cz4gPT4gc3RhdHVzZXMuZmlsdGVyKHV0aWxzLm5vdE51bGwpKSlcbiAgICAgIC5zdWJzY3JpYmUodGhpcy5zdGF0dXNJbnRlcm5hbCQpO1xuXG4gICAgYXdhaXQgdGhpcy5ydW5UYXNrcyhjdHgpO1xuICAgIGNvbnN0IGVyciA9IGdldFRhc2tzRXJyb3IodGhpcy50YXNrcy5tYXAoKHRhc2spID0+IHRhc2suc3RhdHVzJC5nZXRWYWx1ZSgpKS5maWx0ZXIodXRpbHMubm90TnVsbCkpO1xuXG4gICAgaWYgKGVyciA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aGlzLm9uQ29tcGxldGUoKTtcbiAgICB9XG4gICAgdGhpcy5vbkRvbmUoZXJyICE9PSB1bmRlZmluZWQpO1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBydW5UYXNrcyhjdHg6IFRhc2tDb250ZXh0KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMudGFza3MubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLnN0YXR1c0ludGVybmFsJC5uZXh0KFtdKTtcblxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbmN1cnJlbnQpIHtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsKHRoaXMudGFza3MubWFwKGFzeW5jICh0YXNrKSA9PiB0YXNrLnJ1bihjdHgpKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGxldCBlcnJvcjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWxvb3Atc3RhdGVtZW50XG4gICAgICBmb3IgKGNvbnN0IHRhc2sgb2YgdGhpcy50YXNrcykge1xuICAgICAgICBpZiAoZXJyb3IgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGF3YWl0IHRhc2sucnVuKGN0eCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGFzay5jb21wbGV0ZSgpO1xuICAgICAgICB9XG4gICAgICAgIGVycm9yID0gdGFzay5lcnJvcjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGNoZWNrQWxsKGN0eDogVGFza0NvbnRleHQpOiB2b2lkIHtcbiAgICB0aGlzLnRhc2tzLmZvckVhY2goKHRhc2spID0+IHRhc2suY2hlY2soY3R4KSk7XG4gIH1cbn1cbiJdfQ==