@firestitch/system 18.0.42 → 18.0.44
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/app/modules/system/components/dashboard/dashboard.component.d.ts +47 -3
- package/app/modules/system/interfaces/index.d.ts +1 -0
- package/app/modules/system/interfaces/upgrade-event.d.ts +25 -0
- package/esm2022/app/modules/system/components/dashboard/dashboard.component.mjs +101 -7
- package/esm2022/app/modules/system/interfaces/index.mjs +2 -1
- package/esm2022/app/modules/system/interfaces/upgrade-event.mjs +2 -0
- package/esm2022/public_api.mjs +1 -1
- package/fesm2022/firestitch-system.mjs +98 -6
- package/fesm2022/firestitch-system.mjs.map +1 -1
- package/package.json +1 -1
- package/public_api.d.ts +1 -1
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
import { OnDestroy, OnInit } from '@angular/core';
|
|
2
2
|
import { BuildData } from '@firestitch/build';
|
|
3
|
+
import { Observable } from 'rxjs';
|
|
3
4
|
import { DashboardAction } from './../../interfaces/dashboard-action';
|
|
4
5
|
import * as i0 from "@angular/core";
|
|
5
6
|
export declare class DashboardComponent implements OnInit, OnDestroy {
|
|
6
7
|
private _message;
|
|
7
8
|
private _cdRef;
|
|
8
9
|
private _buildService;
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
private _process;
|
|
11
|
+
private _api;
|
|
12
|
+
/**
|
|
13
|
+
* All three are optional. Left unset, the component reads the standard system
|
|
14
|
+
* endpoints itself — the paths every application using this library already
|
|
15
|
+
* serves. One is supplied only to point the component somewhere else.
|
|
16
|
+
*/
|
|
17
|
+
init: () => Observable<any>;
|
|
18
|
+
upgrade: () => Observable<any>;
|
|
19
|
+
load: () => Observable<any>;
|
|
12
20
|
actions: DashboardAction[];
|
|
13
21
|
dashboard: any;
|
|
14
22
|
buttonActions: DashboardAction[];
|
|
@@ -19,7 +27,43 @@ export declare class DashboardComponent implements OnInit, OnDestroy {
|
|
|
19
27
|
ngOnDestroy(): void;
|
|
20
28
|
actionClick(action: any): void;
|
|
21
29
|
initClick(): void;
|
|
30
|
+
/**
|
|
31
|
+
* Run the pending upgrades as a process rather than behind a spinner.
|
|
32
|
+
*
|
|
33
|
+
* A spinner says the same thing for ten seconds and for ten minutes, which is
|
|
34
|
+
* the whole problem: an upgrade that rebuilds the largest table in a schema
|
|
35
|
+
* looks exactly like one that has hung, and the only way anybody found out
|
|
36
|
+
* which was to wait for a proxy to give up.
|
|
37
|
+
*
|
|
38
|
+
* Works whether or not the application's endpoint streams. Where it does, each
|
|
39
|
+
* NDJSON event becomes a line in the process log — which function is running,
|
|
40
|
+
* how far through it is, what each one cost. Where it does not, the single
|
|
41
|
+
* reply produces no lines and the process is simply a labelled spinner, which
|
|
42
|
+
* is what every application had before this.
|
|
43
|
+
*/
|
|
22
44
|
upgradeClick(): void;
|
|
45
|
+
/**
|
|
46
|
+
* One emission off the upgrade endpoint, as a line for the process log — or
|
|
47
|
+
* null for anything with nothing to say, which is dropped rather than logged.
|
|
48
|
+
*
|
|
49
|
+
* `FsApi.stream()` wraps every NDJSON line in a `StreamEventData`, and
|
|
50
|
+
* `FsProcess` logs a string emission verbatim. So the mapping happens here: an
|
|
51
|
+
* object handed to the log renders as `[object Object]`.
|
|
52
|
+
*
|
|
53
|
+
* `ping` is deliberately silent. It is the heartbeat that stops a proxy
|
|
54
|
+
* closing a run that is still working, it fires after every statement, and it
|
|
55
|
+
* would bury the events worth reading.
|
|
56
|
+
*/
|
|
57
|
+
private _upgradeLine;
|
|
58
|
+
private _dashboardGet;
|
|
59
|
+
private _init;
|
|
60
|
+
/**
|
|
61
|
+
* The upgrade endpoint is read as a stream by default, which is what fills the
|
|
62
|
+
* process log line by line while the run is still going. An application that
|
|
63
|
+
* supplies its own `upgrade` decides for itself — a plain request emits once,
|
|
64
|
+
* produces no lines, and the process is a labelled spinner.
|
|
65
|
+
*/
|
|
66
|
+
private _upgrade;
|
|
23
67
|
private _load;
|
|
24
68
|
static ɵfac: i0.ɵɵFactoryDeclaration<DashboardComponent, never>;
|
|
25
69
|
static ɵcmp: i0.ɵɵComponentDeclaration<DashboardComponent, "fs-system-dashboard", never, { "init": { "alias": "init"; "required": false; }; "upgrade": { "alias": "upgrade"; "required": false; }; "load": { "alias": "load"; "required": false; }; "actions": { "alias": "actions"; "required": false; }; }, {}, never, never, true, never>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One NDJSON line off a streaming upgrade endpoint.
|
|
3
|
+
*
|
|
4
|
+
* The framework's system view streams these only when the caller asks for a
|
|
5
|
+
* stream, so an application that has not opted in emits an ordinary reply and
|
|
6
|
+
* none of this applies — see `DashboardComponent._upgradeLine()`, which treats
|
|
7
|
+
* anything unrecognised as having nothing to log.
|
|
8
|
+
*
|
|
9
|
+
* `start` arrives once with the full list of pending functions, because "working
|
|
10
|
+
* on 2 of 9" is only meaningful to somebody who was told there were 9. `upgrade`
|
|
11
|
+
* arrives twice per function, on either side of it, carrying what it cost.
|
|
12
|
+
* `ping` is the heartbeat and says nothing.
|
|
13
|
+
*/
|
|
14
|
+
export interface UpgradeEvent {
|
|
15
|
+
type: 'start' | 'upgrade' | 'log' | 'ping' | 'done';
|
|
16
|
+
state?: 'started' | 'completed' | 'failed';
|
|
17
|
+
name?: string;
|
|
18
|
+
index?: number;
|
|
19
|
+
total?: number;
|
|
20
|
+
completed?: number;
|
|
21
|
+
duration?: string;
|
|
22
|
+
seconds?: number;
|
|
23
|
+
message?: string;
|
|
24
|
+
functions?: string[];
|
|
25
|
+
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, inject } from '@angular/core';
|
|
2
|
+
import { FsApi, StreamEventData } from '@firestitch/api';
|
|
2
3
|
import { FsBuildService } from '@firestitch/build';
|
|
3
4
|
import { FsMessage } from '@firestitch/message';
|
|
5
|
+
import { FsProcess, ProcessState } from '@firestitch/process';
|
|
4
6
|
import { Subject } from 'rxjs';
|
|
5
|
-
import { takeUntil } from 'rxjs/operators';
|
|
7
|
+
import { filter, map, take, takeUntil } from 'rxjs/operators';
|
|
6
8
|
import { differenceInMinutes } from 'date-fns';
|
|
7
9
|
import { FsSkeletonModule } from '@firestitch/skeleton';
|
|
8
10
|
import { FsLabelModule } from '@firestitch/label';
|
|
@@ -21,6 +23,13 @@ export class DashboardComponent {
|
|
|
21
23
|
_message = inject(FsMessage);
|
|
22
24
|
_cdRef = inject(ChangeDetectorRef);
|
|
23
25
|
_buildService = inject(FsBuildService);
|
|
26
|
+
_process = inject(FsProcess);
|
|
27
|
+
_api = inject(FsApi);
|
|
28
|
+
/**
|
|
29
|
+
* All three are optional. Left unset, the component reads the standard system
|
|
30
|
+
* endpoints itself — the paths every application using this library already
|
|
31
|
+
* serves. One is supplied only to point the component somewhere else.
|
|
32
|
+
*/
|
|
24
33
|
init;
|
|
25
34
|
upgrade;
|
|
26
35
|
load;
|
|
@@ -54,20 +63,105 @@ export class DashboardComponent {
|
|
|
54
63
|
action.click();
|
|
55
64
|
}
|
|
56
65
|
initClick() {
|
|
57
|
-
this.
|
|
66
|
+
this._init()
|
|
58
67
|
.subscribe(() => {
|
|
59
68
|
this._message.success('Successfully initialized the system');
|
|
60
69
|
});
|
|
61
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Run the pending upgrades as a process rather than behind a spinner.
|
|
73
|
+
*
|
|
74
|
+
* A spinner says the same thing for ten seconds and for ten minutes, which is
|
|
75
|
+
* the whole problem: an upgrade that rebuilds the largest table in a schema
|
|
76
|
+
* looks exactly like one that has hung, and the only way anybody found out
|
|
77
|
+
* which was to wait for a proxy to give up.
|
|
78
|
+
*
|
|
79
|
+
* Works whether or not the application's endpoint streams. Where it does, each
|
|
80
|
+
* NDJSON event becomes a line in the process log — which function is running,
|
|
81
|
+
* how far through it is, what each one cost. Where it does not, the single
|
|
82
|
+
* reply produces no lines and the process is simply a labelled spinner, which
|
|
83
|
+
* is what every application had before this.
|
|
84
|
+
*/
|
|
62
85
|
upgradeClick() {
|
|
63
|
-
this.upgrade()
|
|
64
|
-
.
|
|
86
|
+
const process = this._process.run('System upgrade', this._upgrade()
|
|
87
|
+
.pipe(map((event) => this._upgradeLine(event)), filter((line) => line !== null)));
|
|
88
|
+
// The pending-upgrade count on this screen is the thing the button was
|
|
89
|
+
// pressed to change, so it is re-read when the run settles — including when
|
|
90
|
+
// it FAILS, because a run that stopped halfway still completed everything
|
|
91
|
+
// before the one that broke.
|
|
92
|
+
process.completed$
|
|
93
|
+
.pipe(take(1), takeUntil(this._destroy$))
|
|
94
|
+
.subscribe((state) => {
|
|
65
95
|
this._load();
|
|
66
|
-
|
|
96
|
+
if (state === ProcessState.Success) {
|
|
97
|
+
this._message.success('Successfully upgraded the system');
|
|
98
|
+
}
|
|
67
99
|
});
|
|
68
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* One emission off the upgrade endpoint, as a line for the process log — or
|
|
103
|
+
* null for anything with nothing to say, which is dropped rather than logged.
|
|
104
|
+
*
|
|
105
|
+
* `FsApi.stream()` wraps every NDJSON line in a `StreamEventData`, and
|
|
106
|
+
* `FsProcess` logs a string emission verbatim. So the mapping happens here: an
|
|
107
|
+
* object handed to the log renders as `[object Object]`.
|
|
108
|
+
*
|
|
109
|
+
* `ping` is deliberately silent. It is the heartbeat that stops a proxy
|
|
110
|
+
* closing a run that is still working, it fires after every statement, and it
|
|
111
|
+
* would bury the events worth reading.
|
|
112
|
+
*/
|
|
113
|
+
_upgradeLine(event) {
|
|
114
|
+
const data = (event instanceof StreamEventData ? event.data : event);
|
|
115
|
+
if (typeof data === 'string') {
|
|
116
|
+
return data;
|
|
117
|
+
}
|
|
118
|
+
if (!data || !data.type || data.type === 'ping') {
|
|
119
|
+
return null;
|
|
120
|
+
}
|
|
121
|
+
const step = `${data.index} of ${data.total}`;
|
|
122
|
+
switch (data.type) {
|
|
123
|
+
case 'start':
|
|
124
|
+
return data.total
|
|
125
|
+
? `${data.total} upgrade(s) to run: ${(data.functions || []).join(', ')}`
|
|
126
|
+
: 'Nothing to upgrade';
|
|
127
|
+
case 'upgrade':
|
|
128
|
+
if (data.state === 'started') {
|
|
129
|
+
return `${step} ${data.name}…`;
|
|
130
|
+
}
|
|
131
|
+
return data.state === 'completed'
|
|
132
|
+
? `${step} ${data.name} — ${data.duration}`
|
|
133
|
+
: `${step} ${data.name} FAILED — ${data.message}`;
|
|
134
|
+
case 'done':
|
|
135
|
+
return data.completed
|
|
136
|
+
? `Completed ${data.completed} upgrade(s)`
|
|
137
|
+
: 'Nothing to upgrade';
|
|
138
|
+
default:
|
|
139
|
+
return data.message || null;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
_dashboardGet() {
|
|
143
|
+
return this.load
|
|
144
|
+
? this.load()
|
|
145
|
+
: this._api.get('system/dashboard', {}, { key: 'dashboard' });
|
|
146
|
+
}
|
|
147
|
+
_init() {
|
|
148
|
+
return this.init
|
|
149
|
+
? this.init()
|
|
150
|
+
: this._api.get('system/init', {}, { key: '' });
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* The upgrade endpoint is read as a stream by default, which is what fills the
|
|
154
|
+
* process log line by line while the run is still going. An application that
|
|
155
|
+
* supplies its own `upgrade` decides for itself — a plain request emits once,
|
|
156
|
+
* produces no lines, and the process is a labelled spinner.
|
|
157
|
+
*/
|
|
158
|
+
_upgrade() {
|
|
159
|
+
return this.upgrade
|
|
160
|
+
? this.upgrade()
|
|
161
|
+
: this._api.stream('GET', 'system/upgrade', { stream: true }, { key: '' });
|
|
162
|
+
}
|
|
69
163
|
_load() {
|
|
70
|
-
this.
|
|
164
|
+
this._dashboardGet()
|
|
71
165
|
.subscribe((dashboard) => {
|
|
72
166
|
this.dashboard = dashboard;
|
|
73
167
|
this.dashboard.cronRanAttention = !dashboard.cronRan ||
|
|
@@ -99,4 +193,4 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.7", ngImpor
|
|
|
99
193
|
}], actions: [{
|
|
100
194
|
type: Input
|
|
101
195
|
}] } });
|
|
102
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvbW9kdWxlcy9zeXN0ZW0vY29tcG9uZW50cy9kYXNoYm9hcmQvZGFzaGJvYXJkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvbW9kdWxlcy9zeXN0ZW0vY29tcG9uZW50cy9kYXNoYm9hcmQvZGFzaGJvYXJkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFxQixNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFeEgsT0FBTyxFQUFhLGNBQWMsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQzlELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVoRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxVQUFVLENBQUM7QUFHL0MsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDeEQsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLG1CQUFtQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUMxQyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDakQsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ3ZELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDaEQsT0FBTyxFQUFFLFlBQVks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QWtCLCtKQ3RDL0Isc3dJQXlLTSw4a0JEN0lFLGdCQUFnQixpS0FDaEIsYUFBYSxnUkFDYixPQUFPLG9GQUNQLE9BQU8sMklBQ1AsVUFBVSxpUkFDVixTQUFTLGdMQUNULFlBQVksaVNBQ1osWUFBWTs7MkZBR1Asa0JBQWtCO2tCQWpCOUIsU0FBUzsrQkFDSSxxQkFBcUIsbUJBR2QsdUJBQXVCLENBQUMsTUFBTSxjQUNuQyxJQUFJLFdBQ1A7d0JBQ0wsZ0JBQWdCO3dCQUNoQixhQUFhO3dCQUNiLE9BQU87d0JBQ1AsT0FBTzt3QkFDUCxVQUFVO3dCQUNWLFNBQVM7d0JBQ1QsWUFBWTt3QkFDWixZQUFZO3FCQUNmOzhCQVFhLElBQUk7c0JBQW5CLEtBQUs7Z0JBQ1UsT0FBTztzQkFBdEIsS0FBSztnQkFDVSxJQUFJO3NCQUFuQixLQUFLO2dCQUVVLE9BQU87c0JBQXRCLEtBQUsiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ2hhbmdlRGV0ZWN0b3JSZWYsIENvbXBvbmVudCwgSW5wdXQsIE9uRGVzdHJveSwgT25Jbml0LCBpbmplY3QgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgQnVpbGREYXRhLCBGc0J1aWxkU2VydmljZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2J1aWxkJztcbmltcG9ydCB7IEZzTWVzc2FnZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lc3NhZ2UnO1xuXG5pbXBvcnQgeyBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IGRpZmZlcmVuY2VJbk1pbnV0ZXMgfSBmcm9tICdkYXRlLWZucyc7XG5cbmltcG9ydCB7IERhc2hib2FyZEFjdGlvbiB9IGZyb20gJy4vLi4vLi4vaW50ZXJmYWNlcy9kYXNoYm9hcmQtYWN0aW9uJztcbmltcG9ydCB7IEZzU2tlbGV0b25Nb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9za2VsZXRvbic7XG5pbXBvcnQgeyBGc0xhYmVsTW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbGFiZWwnO1xuaW1wb3J0IHsgTmdDbGFzcyB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQgeyBNYXRJY29uIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvaWNvbic7XG5pbXBvcnQgeyBNYXRUb29sdGlwIH0gZnJvbSAnQGFuZ3VsYXIvbWF0ZXJpYWwvdG9vbHRpcCc7XG5pbXBvcnQgeyBNYXRCdXR0b24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9idXR0b24nO1xuaW1wb3J0IHsgRnNNZW51TW9kdWxlIH0gZnJvbSAnQGZpcmVzdGl0Y2gvbWVudSc7XG5pbXBvcnQgeyBGc0RhdGVNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9kYXRlJztcblxuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ2ZzLXN5c3RlbS1kYXNoYm9hcmQnLFxuICAgIHRlbXBsYXRlVXJsOiAnLi9kYXNoYm9hcmQuY29tcG9uZW50Lmh0bWwnLFxuICAgIHN0eWxlVXJsczogWycuL2Rhc2hib2FyZC5jb21wb25lbnQuc2NzcyddLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICAgIHN0YW5kYWxvbmU6IHRydWUsXG4gICAgaW1wb3J0czogW1xuICAgICAgICBGc1NrZWxldG9uTW9kdWxlLFxuICAgICAgICBGc0xhYmVsTW9kdWxlLFxuICAgICAgICBOZ0NsYXNzLFxuICAgICAgICBNYXRJY29uLFxuICAgICAgICBNYXRUb29sdGlwLFxuICAgICAgICBNYXRCdXR0b24sXG4gICAgICAgIEZzTWVudU1vZHVsZSxcbiAgICAgICAgRnNEYXRlTW9kdWxlLFxuICAgIF0sXG59KVxuZXhwb3J0IGNsYXNzIERhc2hib2FyZENvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSBfbWVzc2FnZSA9IGluamVjdChGc01lc3NhZ2UpO1xuICBwcml2YXRlIF9jZFJlZiA9IGluamVjdChDaGFuZ2VEZXRlY3RvclJlZik7XG4gIHByaXZhdGUgX2J1aWxkU2VydmljZSA9IGluamVjdChGc0J1aWxkU2VydmljZSk7XG5cblxuICBASW5wdXQoKSBwdWJsaWMgaW5pdDogKCkgPT4gYW55O1xuICBASW5wdXQoKSBwdWJsaWMgdXBncmFkZTogKCkgPT4gYW55O1xuICBASW5wdXQoKSBwdWJsaWMgbG9hZDogKCkgPT4gYW55O1xuXG4gIEBJbnB1dCgpIHB1YmxpYyBhY3Rpb25zOiBEYXNoYm9hcmRBY3Rpb25bXSA9IFtdO1xuXG4gIHB1YmxpYyBkYXNoYm9hcmQ7XG4gIHB1YmxpYyBidXR0b25BY3Rpb25zOiBEYXNoYm9hcmRBY3Rpb25bXSA9IFtdO1xuICBwdWJsaWMgYnVpbGQ6IEJ1aWxkRGF0YTtcbiAgcHVibGljIG1lbnVBY3Rpb25zOiBEYXNoYm9hcmRBY3Rpb25bXSA9IFtdO1xuXG4gIHByaXZhdGUgX2Rlc3Ryb3kkID0gbmV3IFN1YmplY3QoKTtcblxuICBwdWJsaWMgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5fbG9hZCgpO1xuICAgIHRoaXMuYnV0dG9uQWN0aW9ucyA9IHRoaXMuYWN0aW9ucy5maWx0ZXIoKGl0ZW0pID0+IHtcbiAgICAgIHJldHVybiAhaXRlbS5tZW51OyBcbiAgICB9KTtcbiAgICB0aGlzLm1lbnVBY3Rpb25zID0gdGhpcy5hY3Rpb25zLmZpbHRlcigoaXRlbSkgPT4ge1xuICAgICAgcmV0dXJuIGl0ZW0ubWVudTsgXG4gICAgfSk7XG5cbiAgICB0aGlzLmJ1aWxkID0gdGhpcy5fYnVpbGRTZXJ2aWNlLmJ1aWxkO1xuICAgIHRoaXMuX2J1aWxkU2VydmljZS5idWlsZCRcbiAgICAgIC5waXBlKFxuICAgICAgICB0YWtlVW50aWwodGhpcy5fZGVzdHJveSQpLFxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoYnVpbGQ6IEJ1aWxkRGF0YSkgPT4ge1xuICAgICAgICB0aGlzLmJ1aWxkID0gYnVpbGQ7XG4gICAgICAgIHRoaXMuX2NkUmVmLm1hcmtGb3JDaGVjaygpO1xuICAgICAgfSk7XG4gIH1cblxuICBwdWJsaWMgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5fZGVzdHJveSQubmV4dChudWxsKTtcbiAgICB0aGlzLl9kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgcHVibGljIGFjdGlvbkNsaWNrKGFjdGlvbikge1xuICAgIGFjdGlvbi5jbGljaygpO1xuICB9XG5cbiAgcHVibGljIGluaXRDbGljaygpIHtcbiAgICB0aGlzLmluaXQoKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuX21lc3NhZ2Uuc3VjY2VzcygnU3VjY2Vzc2Z1bGx5IGluaXRpYWxpemVkIHRoZSBzeXN0ZW0nKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHVwZ3JhZGVDbGljaygpIHtcbiAgICB0aGlzLnVwZ3JhZGUoKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuX2xvYWQoKTtcbiAgICAgICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdTdWNjZXNzZnVsbHkgdXBncmFkZWQgdGhlIHN5c3RlbScpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9sb2FkKCkge1xuICAgIHRoaXMubG9hZCgpXG4gICAgICAuc3Vic2NyaWJlKChkYXNoYm9hcmQpID0+IHtcbiAgICAgICAgdGhpcy5kYXNoYm9hcmQgPSBkYXNoYm9hcmQ7XG4gICAgICAgIHRoaXMuZGFzaGJvYXJkLmNyb25SYW5BdHRlbnRpb24gPSAhZGFzaGJvYXJkLmNyb25SYW4gfHxcbiAgICAgICAgIGRpZmZlcmVuY2VJbk1pbnV0ZXMobmV3IERhdGUoKSwgbmV3IERhdGUoZGFzaGJvYXJkLmNyb25SYW4pKSA+IDE1O1xuICAgICAgICB0aGlzLl9jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICB9XG59XG4iLCI8ZGl2ICpmc1NrZWxldG9uPVwiZGFzaGJvYXJkXCI+XG4gIDxkaXYgY2xhc3M9XCJmcy1yb3cuZ2FwLWxnLndyYXAuYWxpZ24tc3RhcnRcIj5cbiAgICA8ZGl2PlxuICAgICAgPGgyPlxuICAgICAgICBTZXJ2ZXJcbiAgICAgIDwvaDI+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBEYXRlL1RpbWVcbiAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAge3sgZGFzaGJvYXJkLnNlcnZlclRpbWUgfCBmc0RhdGVGb3JtYXQ6ICdkYXRlLXRpbWUnIH19XG4gICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgVGltZXpvbmVcbiAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAge3sgZGFzaGJvYXJkLnNlcnZlclRpbWV6b25lIH19XG4gICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgSG9zdG5hbWVcbiAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAge3sgZGFzaGJvYXJkLnNlcnZlckhvc3RuYW1lIH19XG4gICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgRGlyZWN0b3J5XG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IGRhc2hib2FyZC5hcHBEaXJlY3RvcnkgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgPC9kaXY+XG4gICAgPGRpdj5cbiAgICAgIDxoMj5cbiAgICAgICAgU3lzdGVtXG4gICAgICA8L2gyPlxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgTW9kZVxuICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICB7eyBkYXNoYm9hcmQuYXBwTW9kZSB9fVxuICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgIE5vdGlmaWNhdGlvbiBSZWNpcGllbnRzXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IGRhc2hib2FyZC5ub3RpZnlSZWNpcGllbnRzLmpvaW4oJywgJykgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgPC9kaXY+XG4gICAgPGRpdj5cbiAgICAgIDxoMj5cbiAgICAgICAgRGF0YWJhc2VcbiAgICAgIDwvaDI+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBOYW1lXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IGRhc2hib2FyZC5kYXRhYmFzZU5hbWUgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBEYXRlL1RpbWVcbiAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAge3sgZGFzaGJvYXJkLmRhdGFiYXNlVGltZSB8IGZzRGF0ZUZvcm1hdDogJ2RhdGUtdGltZScgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBUaW1lem9uZVxuICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICB7eyBkYXNoYm9hcmQuZGF0YWJhc2VUaW1lem9uZSB9fVxuICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICA8L2Rpdj5cbiAgICBAaWYgKGJ1aWxkIHx8IGRhc2hib2FyZC51cGdyYWRlcy5sZW5ndGgpIHtcbiAgICAgIDxkaXY+XG4gICAgICAgIEBpZiAoYnVpbGQpIHtcbiAgICAgICAgICA8aDI+XG4gICAgICAgICAgICBCdWlsZFxuICAgICAgICAgIDwvaDI+XG4gICAgICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgICAgICBWZXJzaW9uXG4gICAgICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICAgICAge3sgYnVpbGQudmVyc2lvbiB8fCAnVW5rbm93bicgfX1cbiAgICAgICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICAgICAgRGF0ZVxuICAgICAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAgICAgIHt7IChidWlsZC5kYXRlIHwgZnNEYXRlRm9ybWF0OiAnZGF0ZS10aW1lJykgfHwgJ1Vua25vd24nIH19XG4gICAgICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgICAgfVxuICAgICAgICBAaWYgKGRhc2hib2FyZC51cGdyYWRlcy5sZW5ndGgpIHtcbiAgICAgICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgICAgIFBlbmRpbmcgVXBncmFkZXNcbiAgICAgICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgICAgICA8c3BhblxuICAgICAgICAgICAgICBjbGFzcz1cImF0dGVudGlvblwiXG4gICAgICAgICAgICAgIFtuZ0NsYXNzXT1cInsgJ25lZWRzLWF0dGVudGlvbic6ICEhZGFzaGJvYXJkLnVwZ3JhZGVzLmxlbmd0aCB9XCI+XG4gICAgICAgICAgICAgIHt7IGRhc2hib2FyZC51cGdyYWRlcy5sZW5ndGggfX1cbiAgICAgICAgICAgICAgPG1hdC1pY29uXG4gICAgICAgICAgICAgICAgW21hdFRvb2x0aXBdPVwiZGFzaGJvYXJkLnVwZ3JhZGVzLmpvaW4oJ1xcbicpXCJcbiAgICAgICAgICAgICAgICBtYXRUb29sdGlwQ2xhc3M9XCJ0b29sdGlwLXBlbmRpbmctdXBncmFkZXNcIj5cbiAgICAgICAgICAgICAgICB3YXJuaW5nXG4gICAgICAgICAgICAgIDwvbWF0LWljb24+XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgICAgfVxuICAgICAgPC9kaXY+XG4gICAgfVxuICAgIDxkaXY+XG4gICAgICA8aDI+XG4gICAgICAgIENyb25cbiAgICAgIDwvaDI+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBMYXN0IFJhblxuICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICA8c3BhblxuICAgICAgICAgIGNsYXNzPVwiYXR0ZW50aW9uXCJcbiAgICAgICAgICBbbmdDbGFzc109XCJ7ICduZWVkcy1hdHRlbnRpb24nOiBkYXNoYm9hcmQuY3JvblJhbkF0dGVudGlvbiB9XCI+XG4gICAgICAgICAgQGlmICghZGFzaGJvYXJkLmNyb25SYW4pIHtcbiAgICAgICAgICAgIDxzcGFuPlxuICAgICAgICAgICAgICBOZXZlclxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgICBAaWYgKGRhc2hib2FyZC5jcm9uUmFuKSB7XG4gICAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgICAge3sgZGFzaGJvYXJkLmNyb25SYW4gfCBmc0RhdGVGb3JtYXQ6ICdkYXRlLXRpbWUnIH19XG4gICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgfVxuICAgICAgICAgIDxtYXQtaWNvbj5cbiAgICAgICAgICAgIHdhcm5pbmdcbiAgICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgIDwvZGl2PlxuICA8L2Rpdj5cbiAgPGRpdj5cbiAgICA8ZGl2IGNsYXNzPVwiYWN0aW9uc1wiPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBtYXQtc3Ryb2tlZC1idXR0b25cbiAgICAgICAgKGNsaWNrKT1cInVwZ3JhZGVDbGljaygpXCI+XG4gICAgICAgIFJ1biBVcGdyYWRlc1xuICAgICAgPC9idXR0b24+XG4gICAgICA8YnV0dG9uXG4gICAgICAgIG1hdC1zdHJva2VkLWJ1dHRvblxuICAgICAgICAoY2xpY2spPVwiaW5pdENsaWNrKClcIj5cbiAgICAgICAgSW5pdCBTeXN0ZW1cbiAgICAgIDwvYnV0dG9uPlxuICAgICAgQGZvciAoYWN0aW9uIG9mIGJ1dHRvbkFjdGlvbnM7IHRyYWNrIGFjdGlvbikge1xuICAgICAgICA8YnV0dG9uXG4gICAgICAgICAgbWF0LXN0cm9rZWQtYnV0dG9uXG4gICAgICAgICAgKGNsaWNrKT1cImFjdGlvbkNsaWNrKGFjdGlvbilcIj5cbiAgICAgICAgICB7eyBhY3Rpb24ubGFiZWwgfX1cbiAgICAgICAgPC9idXR0b24+XG4gICAgICB9XG4gICAgICBAaWYgKG1lbnVBY3Rpb25zLmxlbmd0aCkge1xuICAgICAgICA8ZnMtbWVudSBidXR0b25DbGFzcz1cIm1hdC1zdHJva2VkLWJ1dHRvbiBtZW51LWJ1dHRvblwiPlxuICAgICAgICAgIEBmb3IgKGFjdGlvbiBvZiBtZW51QWN0aW9uczsgdHJhY2sgYWN0aW9uKSB7XG4gICAgICAgICAgICA8bmctdGVtcGxhdGVcbiAgICAgICAgICAgICAgZnMtbWVudS1pdGVtXG4gICAgICAgICAgICAgIChjbGljayk9XCJhY3Rpb25DbGljayhhY3Rpb24pXCI+XG4gICAgICAgICAgICAgIHt7IGFjdGlvbi5sYWJlbCB9fVxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICB9XG4gICAgICAgIDwvZnMtbWVudT5cbiAgICAgIH1cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj4iXX0=
|
|
196
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGFzaGJvYXJkLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvbW9kdWxlcy9zeXN0ZW0vY29tcG9uZW50cy9kYXNoYm9hcmQvZGFzaGJvYXJkLmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvbW9kdWxlcy9zeXN0ZW0vY29tcG9uZW50cy9kYXNoYm9hcmQvZGFzaGJvYXJkLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFxQixNQUFNLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFeEgsT0FBTyxFQUFFLEtBQUssRUFBRSxlQUFlLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUN6RCxPQUFPLEVBQWEsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDOUQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ2hELE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFFOUQsT0FBTyxFQUFjLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUMzQyxPQUFPLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFOUQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sVUFBVSxDQUFDO0FBRy9DLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ3hELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUNsRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDMUMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQ2pELE9BQU8sRUFB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QUFuQixLQUFLO2dCQUNVLE9BQU87c0JBQXRCLEtBQUs7Z0JBQ1UsSUFBSTtzQkFBbkIsS0FBSztnQkFFVSxPQUFPO3NCQUF0QixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENoYW5nZURldGVjdG9yUmVmLCBDb21wb25lbnQsIElucHV0LCBPbkRlc3Ryb3ksIE9uSW5pdCwgaW5qZWN0IH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbmltcG9ydCB7IEZzQXBpLCBTdHJlYW1FdmVudERhdGEgfSBmcm9tICdAZmlyZXN0aXRjaC9hcGknO1xuaW1wb3J0IHsgQnVpbGREYXRhLCBGc0J1aWxkU2VydmljZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2J1aWxkJztcbmltcG9ydCB7IEZzTWVzc2FnZSB9IGZyb20gJ0BmaXJlc3RpdGNoL21lc3NhZ2UnO1xuaW1wb3J0IHsgRnNQcm9jZXNzLCBQcm9jZXNzU3RhdGUgfSBmcm9tICdAZmlyZXN0aXRjaC9wcm9jZXNzJztcblxuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZmlsdGVyLCBtYXAsIHRha2UsIHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHsgZGlmZmVyZW5jZUluTWludXRlcyB9IGZyb20gJ2RhdGUtZm5zJztcblxuaW1wb3J0IHsgRGFzaGJvYXJkQWN0aW9uIH0gZnJvbSAnLi8uLi8uLi9pbnRlcmZhY2VzL2Rhc2hib2FyZC1hY3Rpb24nO1xuaW1wb3J0IHsgRnNTa2VsZXRvbk1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL3NrZWxldG9uJztcbmltcG9ydCB7IEZzTGFiZWxNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9sYWJlbCc7XG5pbXBvcnQgeyBOZ0NsYXNzIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IE1hdEljb24gfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC9pY29uJztcbmltcG9ydCB7IE1hdFRvb2x0aXAgfSBmcm9tICdAYW5ndWxhci9tYXRlcmlhbC90b29sdGlwJztcbmltcG9ydCB7IE1hdEJ1dHRvbiB9IGZyb20gJ0Bhbmd1bGFyL21hdGVyaWFsL2J1dHRvbic7XG5pbXBvcnQgeyBGc01lbnVNb2R1bGUgfSBmcm9tICdAZmlyZXN0aXRjaC9tZW51JztcbmltcG9ydCB7IEZzRGF0ZU1vZHVsZSB9IGZyb20gJ0BmaXJlc3RpdGNoL2RhdGUnO1xuaW1wb3J0IHsgVXBncmFkZUV2ZW50IH0gZnJvbSAnLi8uLi8uLi9pbnRlcmZhY2VzL3VwZ3JhZGUtZXZlbnQnO1xuXG5cbkBDb21wb25lbnQoe1xuICAgIHNlbGVjdG9yOiAnZnMtc3lzdGVtLWRhc2hib2FyZCcsXG4gICAgdGVtcGxhdGVVcmw6ICcuL2Rhc2hib2FyZC5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vZGFzaGJvYXJkLmNvbXBvbmVudC5zY3NzJ10sXG4gICAgY2hhbmdlRGV0ZWN0aW9uOiBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneS5PblB1c2gsXG4gICAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgICBpbXBvcnRzOiBbXG4gICAgICAgIEZzU2tlbGV0b25Nb2R1bGUsXG4gICAgICAgIEZzTGFiZWxNb2R1bGUsXG4gICAgICAgIE5nQ2xhc3MsXG4gICAgICAgIE1hdEljb24sXG4gICAgICAgIE1hdFRvb2x0aXAsXG4gICAgICAgIE1hdEJ1dHRvbixcbiAgICAgICAgRnNNZW51TW9kdWxlLFxuICAgICAgICBGc0RhdGVNb2R1bGUsXG4gICAgXSxcbn0pXG5leHBvcnQgY2xhc3MgRGFzaGJvYXJkQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkRlc3Ryb3kge1xuICBwcml2YXRlIF9tZXNzYWdlID0gaW5qZWN0KEZzTWVzc2FnZSk7XG4gIHByaXZhdGUgX2NkUmVmID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcbiAgcHJpdmF0ZSBfYnVpbGRTZXJ2aWNlID0gaW5qZWN0KEZzQnVpbGRTZXJ2aWNlKTtcbiAgcHJpdmF0ZSBfcHJvY2VzcyA9IGluamVjdChGc1Byb2Nlc3MpO1xuICBwcml2YXRlIF9hcGkgPSBpbmplY3QoRnNBcGkpO1xuXG5cbiAgLyoqXG4gICAqIEFsbCB0aHJlZSBhcmUgb3B0aW9uYWwuIExlZnQgdW5zZXQsIHRoZSBjb21wb25lbnQgcmVhZHMgdGhlIHN0YW5kYXJkIHN5c3RlbVxuICAgKiBlbmRwb2ludHMgaXRzZWxmIOKAlCB0aGUgcGF0aHMgZXZlcnkgYXBwbGljYXRpb24gdXNpbmcgdGhpcyBsaWJyYXJ5IGFscmVhZHlcbiAgICogc2VydmVzLiBPbmUgaXMgc3VwcGxpZWQgb25seSB0byBwb2ludCB0aGUgY29tcG9uZW50IHNvbWV3aGVyZSBlbHNlLlxuICAgKi9cbiAgQElucHV0KCkgcHVibGljIGluaXQ6ICgpID0+IE9ic2VydmFibGU8YW55PjtcbiAgQElucHV0KCkgcHVibGljIHVwZ3JhZGU6ICgpID0+IE9ic2VydmFibGU8YW55PjtcbiAgQElucHV0KCkgcHVibGljIGxvYWQ6ICgpID0+IE9ic2VydmFibGU8YW55PjtcblxuICBASW5wdXQoKSBwdWJsaWMgYWN0aW9uczogRGFzaGJvYXJkQWN0aW9uW10gPSBbXTtcblxuICBwdWJsaWMgZGFzaGJvYXJkO1xuICBwdWJsaWMgYnV0dG9uQWN0aW9uczogRGFzaGJvYXJkQWN0aW9uW10gPSBbXTtcbiAgcHVibGljIGJ1aWxkOiBCdWlsZERhdGE7XG4gIHB1YmxpYyBtZW51QWN0aW9uczogRGFzaGJvYXJkQWN0aW9uW10gPSBbXTtcblxuICBwcml2YXRlIF9kZXN0cm95JCA9IG5ldyBTdWJqZWN0KCk7XG5cbiAgcHVibGljIG5nT25Jbml0KCkge1xuICAgIHRoaXMuX2xvYWQoKTtcbiAgICB0aGlzLmJ1dHRvbkFjdGlvbnMgPSB0aGlzLmFjdGlvbnMuZmlsdGVyKChpdGVtKSA9PiB7XG4gICAgICByZXR1cm4gIWl0ZW0ubWVudTsgXG4gICAgfSk7XG4gICAgdGhpcy5tZW51QWN0aW9ucyA9IHRoaXMuYWN0aW9ucy5maWx0ZXIoKGl0ZW0pID0+IHtcbiAgICAgIHJldHVybiBpdGVtLm1lbnU7IFxuICAgIH0pO1xuXG4gICAgdGhpcy5idWlsZCA9IHRoaXMuX2J1aWxkU2VydmljZS5idWlsZDtcbiAgICB0aGlzLl9idWlsZFNlcnZpY2UuYnVpbGQkXG4gICAgICAucGlwZShcbiAgICAgICAgdGFrZVVudGlsKHRoaXMuX2Rlc3Ryb3kkKSxcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKGJ1aWxkOiBCdWlsZERhdGEpID0+IHtcbiAgICAgICAgdGhpcy5idWlsZCA9IGJ1aWxkO1xuICAgICAgICB0aGlzLl9jZFJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHVibGljIG5nT25EZXN0cm95KCkge1xuICAgIHRoaXMuX2Rlc3Ryb3kkLm5leHQobnVsbCk7XG4gICAgdGhpcy5fZGVzdHJveSQuY29tcGxldGUoKTtcbiAgfVxuXG4gIHB1YmxpYyBhY3Rpb25DbGljayhhY3Rpb24pIHtcbiAgICBhY3Rpb24uY2xpY2soKTtcbiAgfVxuXG4gIHB1YmxpYyBpbml0Q2xpY2soKSB7XG4gICAgdGhpcy5faW5pdCgpXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdTdWNjZXNzZnVsbHkgaW5pdGlhbGl6ZWQgdGhlIHN5c3RlbScpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUnVuIHRoZSBwZW5kaW5nIHVwZ3JhZGVzIGFzIGEgcHJvY2VzcyByYXRoZXIgdGhhbiBiZWhpbmQgYSBzcGlubmVyLlxuICAgKlxuICAgKiBBIHNwaW5uZXIgc2F5cyB0aGUgc2FtZSB0aGluZyBmb3IgdGVuIHNlY29uZHMgYW5kIGZvciB0ZW4gbWludXRlcywgd2hpY2ggaXNcbiAgICogdGhlIHdob2xlIHByb2JsZW06IGFuIHVwZ3JhZGUgdGhhdCByZWJ1aWxkcyB0aGUgbGFyZ2VzdCB0YWJsZSBpbiBhIHNjaGVtYVxuICAgKiBsb29rcyBleGFjdGx5IGxpa2Ugb25lIHRoYXQgaGFzIGh1bmcsIGFuZCB0aGUgb25seSB3YXkgYW55Ym9keSBmb3VuZCBvdXRcbiAgICogd2hpY2ggd2FzIHRvIHdhaXQgZm9yIGEgcHJveHkgdG8gZ2l2ZSB1cC5cbiAgICpcbiAgICogV29ya3Mgd2hldGhlciBvciBub3QgdGhlIGFwcGxpY2F0aW9uJ3MgZW5kcG9pbnQgc3RyZWFtcy4gV2hlcmUgaXQgZG9lcywgZWFjaFxuICAgKiBOREpTT04gZXZlbnQgYmVjb21lcyBhIGxpbmUgaW4gdGhlIHByb2Nlc3MgbG9nIOKAlCB3aGljaCBmdW5jdGlvbiBpcyBydW5uaW5nLFxuICAgKiBob3cgZmFyIHRocm91Z2ggaXQgaXMsIHdoYXQgZWFjaCBvbmUgY29zdC4gV2hlcmUgaXQgZG9lcyBub3QsIHRoZSBzaW5nbGVcbiAgICogcmVwbHkgcHJvZHVjZXMgbm8gbGluZXMgYW5kIHRoZSBwcm9jZXNzIGlzIHNpbXBseSBhIGxhYmVsbGVkIHNwaW5uZXIsIHdoaWNoXG4gICAqIGlzIHdoYXQgZXZlcnkgYXBwbGljYXRpb24gaGFkIGJlZm9yZSB0aGlzLlxuICAgKi9cbiAgcHVibGljIHVwZ3JhZGVDbGljaygpIHtcbiAgICBjb25zdCBwcm9jZXNzID0gdGhpcy5fcHJvY2Vzcy5ydW4oXG4gICAgICAnU3lzdGVtIHVwZ3JhZGUnLFxuICAgICAgdGhpcy5fdXBncmFkZSgpXG4gICAgICAgIC5waXBlKFxuICAgICAgICAgIG1hcCgoZXZlbnQpID0+IHRoaXMuX3VwZ3JhZGVMaW5lKGV2ZW50KSksXG4gICAgICAgICAgZmlsdGVyKChsaW5lKTogbGluZSBpcyBzdHJpbmcgPT4gbGluZSAhPT0gbnVsbCksXG4gICAgICAgICksXG4gICAgKTtcblxuICAgIC8vIFRoZSBwZW5kaW5nLXVwZ3JhZGUgY291bnQgb24gdGhpcyBzY3JlZW4gaXMgdGhlIHRoaW5nIHRoZSBidXR0b24gd2FzXG4gICAgLy8gcHJlc3NlZCB0byBjaGFuZ2UsIHNvIGl0IGlzIHJlLXJlYWQgd2hlbiB0aGUgcnVuIHNldHRsZXMg4oCUIGluY2x1ZGluZyB3aGVuXG4gICAgLy8gaXQgRkFJTFMsIGJlY2F1c2UgYSBydW4gdGhhdCBzdG9wcGVkIGhhbGZ3YXkgc3RpbGwgY29tcGxldGVkIGV2ZXJ5dGhpbmdcbiAgICAvLyBiZWZvcmUgdGhlIG9uZSB0aGF0IGJyb2tlLlxuICAgIHByb2Nlc3MuY29tcGxldGVkJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2UoMSksXG4gICAgICAgIHRha2VVbnRpbCh0aGlzLl9kZXN0cm95JCksXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKChzdGF0ZTogUHJvY2Vzc1N0YXRlKSA9PiB7XG4gICAgICAgIHRoaXMuX2xvYWQoKTtcblxuICAgICAgICBpZiAoc3RhdGUgPT09IFByb2Nlc3NTdGF0ZS5TdWNjZXNzKSB7XG4gICAgICAgICAgdGhpcy5fbWVzc2FnZS5zdWNjZXNzKCdTdWNjZXNzZnVsbHkgdXBncmFkZWQgdGhlIHN5c3RlbScpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPbmUgZW1pc3Npb24gb2ZmIHRoZSB1cGdyYWRlIGVuZHBvaW50LCBhcyBhIGxpbmUgZm9yIHRoZSBwcm9jZXNzIGxvZyDigJQgb3JcbiAgICogbnVsbCBmb3IgYW55dGhpbmcgd2l0aCBub3RoaW5nIHRvIHNheSwgd2hpY2ggaXMgZHJvcHBlZCByYXRoZXIgdGhhbiBsb2dnZWQuXG4gICAqXG4gICAqIGBGc0FwaS5zdHJlYW0oKWAgd3JhcHMgZXZlcnkgTkRKU09OIGxpbmUgaW4gYSBgU3RyZWFtRXZlbnREYXRhYCwgYW5kXG4gICAqIGBGc1Byb2Nlc3NgIGxvZ3MgYSBzdHJpbmcgZW1pc3Npb24gdmVyYmF0aW0uIFNvIHRoZSBtYXBwaW5nIGhhcHBlbnMgaGVyZTogYW5cbiAgICogb2JqZWN0IGhhbmRlZCB0byB0aGUgbG9nIHJlbmRlcnMgYXMgYFtvYmplY3QgT2JqZWN0XWAuXG4gICAqXG4gICAqIGBwaW5nYCBpcyBkZWxpYmVyYXRlbHkgc2lsZW50LiBJdCBpcyB0aGUgaGVhcnRiZWF0IHRoYXQgc3RvcHMgYSBwcm94eVxuICAgKiBjbG9zaW5nIGEgcnVuIHRoYXQgaXMgc3RpbGwgd29ya2luZywgaXQgZmlyZXMgYWZ0ZXIgZXZlcnkgc3RhdGVtZW50LCBhbmQgaXRcbiAgICogd291bGQgYnVyeSB0aGUgZXZlbnRzIHdvcnRoIHJlYWRpbmcuXG4gICAqL1xuICBwcml2YXRlIF91cGdyYWRlTGluZShldmVudDogdW5rbm93bik6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IGRhdGE6IFVwZ3JhZGVFdmVudCA9IChldmVudCBpbnN0YW5jZW9mIFN0cmVhbUV2ZW50RGF0YSA/IGV2ZW50LmRhdGEgOiBldmVudCkgYXMgVXBncmFkZUV2ZW50O1xuXG4gICAgaWYgKHR5cGVvZiBkYXRhID09PSAnc3RyaW5nJykge1xuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuXG4gICAgaWYgKCFkYXRhIHx8ICFkYXRhLnR5cGUgfHwgZGF0YS50eXBlID09PSAncGluZycpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIGNvbnN0IHN0ZXAgPSBgJHtkYXRhLmluZGV4fSBvZiAke2RhdGEudG90YWx9YDtcblxuICAgIHN3aXRjaCAoZGF0YS50eXBlKSB7XG4gICAgICBjYXNlICdzdGFydCc6XG4gICAgICAgIHJldHVybiBkYXRhLnRvdGFsXG4gICAgICAgICAgPyBgJHtkYXRhLnRvdGFsfSB1cGdyYWRlKHMpIHRvIHJ1bjogJHsoZGF0YS5mdW5jdGlvbnMgfHwgW10pLmpvaW4oJywgJyl9YFxuICAgICAgICAgIDogJ05vdGhpbmcgdG8gdXBncmFkZSc7XG5cbiAgICAgIGNhc2UgJ3VwZ3JhZGUnOlxuICAgICAgICBpZiAoZGF0YS5zdGF0ZSA9PT0gJ3N0YXJ0ZWQnKSB7XG4gICAgICAgICAgcmV0dXJuIGAke3N0ZXB9ICR7ZGF0YS5uYW1lfeKApmA7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZGF0YS5zdGF0ZSA9PT0gJ2NvbXBsZXRlZCdcbiAgICAgICAgICA/IGAke3N0ZXB9ICR7ZGF0YS5uYW1lfSDigJQgJHtkYXRhLmR1cmF0aW9ufWBcbiAgICAgICAgICA6IGAke3N0ZXB9ICR7ZGF0YS5uYW1lfSBGQUlMRUQg4oCUICR7ZGF0YS5tZXNzYWdlfWA7XG5cbiAgICAgIGNhc2UgJ2RvbmUnOlxuICAgICAgICByZXR1cm4gZGF0YS5jb21wbGV0ZWRcbiAgICAgICAgICA/IGBDb21wbGV0ZWQgJHtkYXRhLmNvbXBsZXRlZH0gdXBncmFkZShzKWBcbiAgICAgICAgICA6ICdOb3RoaW5nIHRvIHVwZ3JhZGUnO1xuXG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZGF0YS5tZXNzYWdlIHx8IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfZGFzaGJvYXJkR2V0KCk6IE9ic2VydmFibGU8YW55PiB7XG4gICAgcmV0dXJuIHRoaXMubG9hZFxuICAgICAgPyB0aGlzLmxvYWQoKVxuICAgICAgOiB0aGlzLl9hcGkuZ2V0KCdzeXN0ZW0vZGFzaGJvYXJkJywge30sIHsga2V5OiAnZGFzaGJvYXJkJyB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2luaXQoKTogT2JzZXJ2YWJsZTxhbnk+IHtcbiAgICByZXR1cm4gdGhpcy5pbml0XG4gICAgICA/IHRoaXMuaW5pdCgpXG4gICAgICA6IHRoaXMuX2FwaS5nZXQoJ3N5c3RlbS9pbml0Jywge30sIHsga2V5OiAnJyB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdXBncmFkZSBlbmRwb2ludCBpcyByZWFkIGFzIGEgc3RyZWFtIGJ5IGRlZmF1bHQsIHdoaWNoIGlzIHdoYXQgZmlsbHMgdGhlXG4gICAqIHByb2Nlc3MgbG9nIGxpbmUgYnkgbGluZSB3aGlsZSB0aGUgcnVuIGlzIHN0aWxsIGdvaW5nLiBBbiBhcHBsaWNhdGlvbiB0aGF0XG4gICAqIHN1cHBsaWVzIGl0cyBvd24gYHVwZ3JhZGVgIGRlY2lkZXMgZm9yIGl0c2VsZiDigJQgYSBwbGFpbiByZXF1ZXN0IGVtaXRzIG9uY2UsXG4gICAqIHByb2R1Y2VzIG5vIGxpbmVzLCBhbmQgdGhlIHByb2Nlc3MgaXMgYSBsYWJlbGxlZCBzcGlubmVyLlxuICAgKi9cbiAgcHJpdmF0ZSBfdXBncmFkZSgpOiBPYnNlcnZhYmxlPGFueT4ge1xuICAgIHJldHVybiB0aGlzLnVwZ3JhZGVcbiAgICAgID8gdGhpcy51cGdyYWRlKClcbiAgICAgIDogdGhpcy5fYXBpLnN0cmVhbSgnR0VUJywgJ3N5c3RlbS91cGdyYWRlJywgeyBzdHJlYW06IHRydWUgfSwgeyBrZXk6ICcnIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfbG9hZCgpIHtcbiAgICB0aGlzLl9kYXNoYm9hcmRHZXQoKVxuICAgICAgLnN1YnNjcmliZSgoZGFzaGJvYXJkKSA9PiB7XG4gICAgICAgIHRoaXMuZGFzaGJvYXJkID0gZGFzaGJvYXJkO1xuICAgICAgICB0aGlzLmRhc2hib2FyZC5jcm9uUmFuQXR0ZW50aW9uID0gIWRhc2hib2FyZC5jcm9uUmFuIHx8XG4gICAgICAgICBkaWZmZXJlbmNlSW5NaW51dGVzKG5ldyBEYXRlKCksIG5ldyBEYXRlKGRhc2hib2FyZC5jcm9uUmFuKSkgPiAxNTtcbiAgICAgICAgdGhpcy5fY2RSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgICB9KTtcbiAgfVxufVxuIiwiPGRpdiAqZnNTa2VsZXRvbj1cImRhc2hib2FyZFwiPlxuICA8ZGl2IGNsYXNzPVwiZnMtcm93LmdhcC1sZy53cmFwLmFsaWduLXN0YXJ0XCI+XG4gICAgPGRpdj5cbiAgICAgIDxoMj5cbiAgICAgICAgU2VydmVyXG4gICAgICA8L2gyPlxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgRGF0ZS9UaW1lXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IGRhc2hib2FyZC5zZXJ2ZXJUaW1lIHwgZnNEYXRlRm9ybWF0OiAnZGF0ZS10aW1lJyB9fVxuICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgIFRpbWV6b25lXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IGRhc2hib2FyZC5zZXJ2ZXJUaW1lem9uZSB9fVxuICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgIEhvc3RuYW1lXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IGRhc2hib2FyZC5zZXJ2ZXJIb3N0bmFtZSB9fVxuICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgIERpcmVjdG9yeVxuICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICB7eyBkYXNoYm9hcmQuYXBwRGlyZWN0b3J5IH19XG4gICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgIDwvZGl2PlxuICAgIDxkaXY+XG4gICAgICA8aDI+XG4gICAgICAgIFN5c3RlbVxuICAgICAgPC9oMj5cbiAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgIE1vZGVcbiAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAge3sgZGFzaGJvYXJkLmFwcE1vZGUgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICBOb3RpZmljYXRpb24gUmVjaXBpZW50c1xuICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICB7eyBkYXNoYm9hcmQubm90aWZ5UmVjaXBpZW50cy5qb2luKCcsICcpIH19XG4gICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgIDwvZGl2PlxuICAgIDxkaXY+XG4gICAgICA8aDI+XG4gICAgICAgIERhdGFiYXNlXG4gICAgICA8L2gyPlxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgTmFtZVxuICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICB7eyBkYXNoYm9hcmQuZGF0YWJhc2VOYW1lIH19XG4gICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgRGF0ZS9UaW1lXG4gICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgIHt7IGRhc2hib2FyZC5kYXRhYmFzZVRpbWUgfCBmc0RhdGVGb3JtYXQ6ICdkYXRlLXRpbWUnIH19XG4gICAgICA8L2ZzLWxhYmVsLWZpZWxkPlxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgVGltZXpvbmVcbiAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAge3sgZGFzaGJvYXJkLmRhdGFiYXNlVGltZXpvbmUgfX1cbiAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgPC9kaXY+XG4gICAgQGlmIChidWlsZCB8fCBkYXNoYm9hcmQudXBncmFkZXMubGVuZ3RoKSB7XG4gICAgICA8ZGl2PlxuICAgICAgICBAaWYgKGJ1aWxkKSB7XG4gICAgICAgICAgPGgyPlxuICAgICAgICAgICAgQnVpbGRcbiAgICAgICAgICA8L2gyPlxuICAgICAgICAgIDxmcy1sYWJlbC1maWVsZD5cbiAgICAgICAgICAgIDxmcy1sYWJlbD5cbiAgICAgICAgICAgICAgVmVyc2lvblxuICAgICAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAgICAgIHt7IGJ1aWxkLnZlcnNpb24gfHwgJ1Vua25vd24nIH19XG4gICAgICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICAgICAgICA8ZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgICAgIERhdGVcbiAgICAgICAgICAgIDwvZnMtbGFiZWw+XG4gICAgICAgICAgICB7eyAoYnVpbGQuZGF0ZSB8IGZzRGF0ZUZvcm1hdDogJ2RhdGUtdGltZScpIHx8ICdVbmtub3duJyB9fVxuICAgICAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIH1cbiAgICAgICAgQGlmIChkYXNoYm9hcmQudXBncmFkZXMubGVuZ3RoKSB7XG4gICAgICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICAgICAgPGZzLWxhYmVsPlxuICAgICAgICAgICAgICBQZW5kaW5nIFVwZ3JhZGVzXG4gICAgICAgICAgICA8L2ZzLWxhYmVsPlxuICAgICAgICAgICAgPHNwYW5cbiAgICAgICAgICAgICAgY2xhc3M9XCJhdHRlbnRpb25cIlxuICAgICAgICAgICAgICBbbmdDbGFzc109XCJ7ICduZWVkcy1hdHRlbnRpb24nOiAhIWRhc2hib2FyZC51cGdyYWRlcy5sZW5ndGggfVwiPlxuICAgICAgICAgICAgICB7eyBkYXNoYm9hcmQudXBncmFkZXMubGVuZ3RoIH19XG4gICAgICAgICAgICAgIDxtYXQtaWNvblxuICAgICAgICAgICAgICAgIFttYXRUb29sdGlwXT1cImRhc2hib2FyZC51cGdyYWRlcy5qb2luKCdcXG4nKVwiXG4gICAgICAgICAgICAgICAgbWF0VG9vbHRpcENsYXNzPVwidG9vbHRpcC1wZW5kaW5nLXVwZ3JhZGVzXCI+XG4gICAgICAgICAgICAgICAgd2FybmluZ1xuICAgICAgICAgICAgICA8L21hdC1pY29uPlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvZnMtbGFiZWwtZmllbGQ+XG4gICAgICAgIH1cbiAgICAgIDwvZGl2PlxuICAgIH1cbiAgICA8ZGl2PlxuICAgICAgPGgyPlxuICAgICAgICBDcm9uXG4gICAgICA8L2gyPlxuICAgICAgPGZzLWxhYmVsLWZpZWxkPlxuICAgICAgICA8ZnMtbGFiZWw+XG4gICAgICAgICAgTGFzdCBSYW5cbiAgICAgICAgPC9mcy1sYWJlbD5cbiAgICAgICAgPHNwYW5cbiAgICAgICAgICBjbGFzcz1cImF0dGVudGlvblwiXG4gICAgICAgICAgW25nQ2xhc3NdPVwieyAnbmVlZHMtYXR0ZW50aW9uJzogZGFzaGJvYXJkLmNyb25SYW5BdHRlbnRpb24gfVwiPlxuICAgICAgICAgIEBpZiAoIWRhc2hib2FyZC5jcm9uUmFuKSB7XG4gICAgICAgICAgICA8c3Bhbj5cbiAgICAgICAgICAgICAgTmV2ZXJcbiAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICB9XG4gICAgICAgICAgQGlmIChkYXNoYm9hcmQuY3JvblJhbikge1xuICAgICAgICAgICAgPHNwYW4+XG4gICAgICAgICAgICAgIHt7IGRhc2hib2FyZC5jcm9uUmFuIHwgZnNEYXRlRm9ybWF0OiAnZGF0ZS10aW1lJyB9fVxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIH1cbiAgICAgICAgICA8bWF0LWljb24+XG4gICAgICAgICAgICB3YXJuaW5nXG4gICAgICAgICAgPC9tYXQtaWNvbj5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9mcy1sYWJlbC1maWVsZD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDxkaXY+XG4gICAgPGRpdiBjbGFzcz1cImFjdGlvbnNcIj5cbiAgICAgIDxidXR0b25cbiAgICAgICAgbWF0LXN0cm9rZWQtYnV0dG9uXG4gICAgICAgIChjbGljayk9XCJ1cGdyYWRlQ2xpY2soKVwiPlxuICAgICAgICBSdW4gVXBncmFkZXNcbiAgICAgIDwvYnV0dG9uPlxuICAgICAgPGJ1dHRvblxuICAgICAgICBtYXQtc3Ryb2tlZC1idXR0b25cbiAgICAgICAgKGNsaWNrKT1cImluaXRDbGljaygpXCI+XG4gICAgICAgIEluaXQgU3lzdGVtXG4gICAgICA8L2J1dHRvbj5cbiAgICAgIEBmb3IgKGFjdGlvbiBvZiBidXR0b25BY3Rpb25zOyB0cmFjayBhY3Rpb24pIHtcbiAgICAgICAgPGJ1dHRvblxuICAgICAgICAgIG1hdC1zdHJva2VkLWJ1dHRvblxuICAgICAgICAgIChjbGljayk9XCJhY3Rpb25DbGljayhhY3Rpb24pXCI+XG4gICAgICAgICAge3sgYWN0aW9uLmxhYmVsIH19XG4gICAgICAgIDwvYnV0dG9uPlxuICAgICAgfVxuICAgICAgQGlmIChtZW51QWN0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgPGZzLW1lbnUgYnV0dG9uQ2xhc3M9XCJtYXQtc3Ryb2tlZC1idXR0b24gbWVudS1idXR0b25cIj5cbiAgICAgICAgICBAZm9yIChhY3Rpb24gb2YgbWVudUFjdGlvbnM7IHRyYWNrIGFjdGlvbikge1xuICAgICAgICAgICAgPG5nLXRlbXBsYXRlXG4gICAgICAgICAgICAgIGZzLW1lbnUtaXRlbVxuICAgICAgICAgICAgICAoY2xpY2spPVwiYWN0aW9uQ2xpY2soYWN0aW9uKVwiPlxuICAgICAgICAgICAgICB7eyBhY3Rpb24ubGFiZWwgfX1cbiAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgfVxuICAgICAgICA8L2ZzLW1lbnU+XG4gICAgICB9XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuPC9kaXY+Il19
|
|
@@ -2,4 +2,5 @@ export * from './dashboard-action';
|
|
|
2
2
|
export * from './process-action';
|
|
3
3
|
export * from './process';
|
|
4
4
|
export * from './system-config';
|
|
5
|
-
|
|
5
|
+
export * from './upgrade-event';
|
|
6
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvYXBwL21vZHVsZXMvc3lzdGVtL2ludGVyZmFjZXMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLGtCQUFrQixDQUFDO0FBQ2pDLGNBQWMsV0FBVyxDQUFDO0FBQzFCLGNBQWMsaUJBQWlCLENBQUM7QUFDaEMsY0FBYyxpQkFBaUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCAqIGZyb20gJy4vZGFzaGJvYXJkLWFjdGlvbic7XG5leHBvcnQgKiBmcm9tICcuL3Byb2Nlc3MtYWN0aW9uJztcbmV4cG9ydCAqIGZyb20gJy4vcHJvY2Vzcyc7XG5leHBvcnQgKiBmcm9tICcuL3N5c3RlbS1jb25maWcnO1xuZXhwb3J0ICogZnJvbSAnLi91cGdyYWRlLWV2ZW50JztcbiJdfQ==
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export {};
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBncmFkZS1ldmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uL3NyYy9hcHAvbW9kdWxlcy9zeXN0ZW0vaW50ZXJmYWNlcy91cGdyYWRlLWV2ZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIE9uZSBOREpTT04gbGluZSBvZmYgYSBzdHJlYW1pbmcgdXBncmFkZSBlbmRwb2ludC5cbiAqXG4gKiBUaGUgZnJhbWV3b3JrJ3Mgc3lzdGVtIHZpZXcgc3RyZWFtcyB0aGVzZSBvbmx5IHdoZW4gdGhlIGNhbGxlciBhc2tzIGZvciBhXG4gKiBzdHJlYW0sIHNvIGFuIGFwcGxpY2F0aW9uIHRoYXQgaGFzIG5vdCBvcHRlZCBpbiBlbWl0cyBhbiBvcmRpbmFyeSByZXBseSBhbmRcbiAqIG5vbmUgb2YgdGhpcyBhcHBsaWVzIOKAlCBzZWUgYERhc2hib2FyZENvbXBvbmVudC5fdXBncmFkZUxpbmUoKWAsIHdoaWNoIHRyZWF0c1xuICogYW55dGhpbmcgdW5yZWNvZ25pc2VkIGFzIGhhdmluZyBub3RoaW5nIHRvIGxvZy5cbiAqXG4gKiBgc3RhcnRgIGFycml2ZXMgb25jZSB3aXRoIHRoZSBmdWxsIGxpc3Qgb2YgcGVuZGluZyBmdW5jdGlvbnMsIGJlY2F1c2UgXCJ3b3JraW5nXG4gKiBvbiAyIG9mIDlcIiBpcyBvbmx5IG1lYW5pbmdmdWwgdG8gc29tZWJvZHkgd2hvIHdhcyB0b2xkIHRoZXJlIHdlcmUgOS4gYHVwZ3JhZGVgXG4gKiBhcnJpdmVzIHR3aWNlIHBlciBmdW5jdGlvbiwgb24gZWl0aGVyIHNpZGUgb2YgaXQsIGNhcnJ5aW5nIHdoYXQgaXQgY29zdC5cbiAqIGBwaW5nYCBpcyB0aGUgaGVhcnRiZWF0IGFuZCBzYXlzIG5vdGhpbmcuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVXBncmFkZUV2ZW50IHtcbiAgdHlwZTogJ3N0YXJ0JyB8ICd1cGdyYWRlJyB8ICdsb2cnIHwgJ3BpbmcnIHwgJ2RvbmUnO1xuICBzdGF0ZT86ICdzdGFydGVkJyB8ICdjb21wbGV0ZWQnIHwgJ2ZhaWxlZCc7XG4gIG5hbWU/OiBzdHJpbmc7XG4gIGluZGV4PzogbnVtYmVyO1xuICB0b3RhbD86IG51bWJlcjtcbiAgY29tcGxldGVkPzogbnVtYmVyO1xuICBkdXJhdGlvbj86IHN0cmluZztcbiAgc2Vjb25kcz86IG51bWJlcjtcbiAgbWVzc2FnZT86IHN0cmluZztcbiAgZnVuY3Rpb25zPzogc3RyaW5nW107XG59XG4iXX0=
|
package/esm2022/public_api.mjs
CHANGED
|
@@ -17,4 +17,4 @@ export { LinkifyPipe } from './app/modules/system/pipes/linkify.pipe';
|
|
|
17
17
|
export { ApiLogStates, CronStates, ProcessStates } from './app/modules/system/consts';
|
|
18
18
|
export { ApiLogState, CronState, ProcessState } from './app/modules/system/enums';
|
|
19
19
|
export { FS_SYSTEM_CONFIG } from './app/modules/system/injectors/system-config.injector';
|
|
20
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
20
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHVibGljX2FwaS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wdWJsaWNfYXBpLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUV2RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUN6RSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDMUUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDNUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLHNDQUFzQyxDQUFDO0FBQ3JFLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLDBDQUEwQyxDQUFDO0FBQzVFLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQztBQUN2RSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSwyQ0FBMkMsQ0FBQztBQUMvRSxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDckUsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0seUNBQXlDLENBQUM7QUFDM0UsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sMkNBQTJDLENBQUM7QUFDL0UsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sNkNBQTZDLENBQUM7QUFDbEYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0sMENBQTBDLENBQUM7QUFDN0UsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sOENBQThDLENBQUM7QUFDcEYsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sZ0RBQWdELENBQUM7QUFDbEYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHlDQUF5QyxDQUFDO0FBRXRFLE9BQU8sRUFBRSxZQUFZLEVBQUUsVUFBVSxFQUFFLGFBQWEsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3RGLE9BQU8sRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLFlBQVksRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBSWxGLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHVEQUF1RCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiXG5leHBvcnQgeyBGc1N5c3RlbU1vZHVsZSB9IGZyb20gJy4vYXBwL21vZHVsZXMvc3lzdGVtL2ZzLXN5c3RlbS5tb2R1bGUnO1xuXG5leHBvcnQgeyBRdWVyeUxvZ3NDb21wb25lbnQgfSBmcm9tICcuL2FwcC9tb2R1bGVzL3F1ZXJ5LWxvZ3MvY29tcG9uZW50cyc7XG5leHBvcnQgeyBBcGlMb2dDb21wb25lbnQgfSBmcm9tICcuL2FwcC9tb2R1bGVzL3N5c3RlbS9jb21wb25lbnRzL2FwaS1sb2cnO1xuZXhwb3J0IHsgQXBpTG9nc0NvbXBvbmVudCB9IGZyb20gJy4vYXBwL21vZHVsZXMvc3lzdGVtL2NvbXBvbmVudHMvYXBpLWxvZ3MnO1xuZXhwb3J0IHsgQ3JvbkNvbXBvbmVudCB9IGZyb20gJy4vYXBwL21vZHVsZXMvc3lzdGVtL2NvbXBvbmVudHMvY3Jvbic7XG5leHBvcnQgeyBDcm9uTG9nQ29tcG9uZW50IH0gZnJvbSAnLi9hcHAvbW9kdWxlcy9zeXN0ZW0vY29tcG9uZW50cy9jcm9uLWxvZyc7XG5leHBvcnQgeyBDcm9uc0NvbXBvbmVudCB9IGZyb20gJy4vYXBwL21vZHVsZXMvc3lzdGVtL2NvbXBvbmVudHMvY3JvbnMnO1xuZXhwb3J0IHsgRGFzaGJvYXJkQ29tcG9uZW50IH0gZnJvbSAnLi9hcHAvbW9kdWxlcy9zeXN0ZW0vY29tcG9uZW50cy9kYXNoYm9hcmQnO1xuZXhwb3J0IHsgSW5mb0NvbXBvbmVudCB9IGZyb20gJy4vYXBwL21vZHVsZXMvc3lzdGVtL2NvbXBvbmVudHMvaW5mbyc7XG5leHBvcnQgeyBQcm9jZXNzQ29tcG9uZW50IH0gZnJvbSAnLi9hcHAvbW9kdWxlcy9zeXN0ZW0vY29tcG9uZW50cy9wcm9jZXNzJztcbmV4cG9ydCB7IFByb2Nlc3Nlc0NvbXBvbmVudCB9IGZyb20gJy4vYXBwL21vZHVsZXMvc3lzdGVtL2NvbXBvbmVudHMvcHJvY2Vzc2VzJztcbmV4cG9ydCB7IFNlcnZlckxvZ3NDb21wb25lbnQgfSBmcm9tICcuL2FwcC9tb2R1bGVzL3N5c3RlbS9jb21wb25lbnRzL3NlcnZlci1sb2dzJztcbmV4cG9ydCB7IFNldHRpbmdzQ29tcG9uZW50IH0gZnJvbSAnLi9hcHAvbW9kdWxlcy9zeXN0ZW0vY29tcG9uZW50cy9zZXR0aW5ncyc7XG5leHBvcnQgeyBVcGdyYWRlTG9nc0NvbXBvbmVudCB9IGZyb20gJy4vYXBwL21vZHVsZXMvc3lzdGVtL2NvbXBvbmVudHMvdXBncmFkZS1sb2dzJztcbmV4cG9ydCB7IEtleU5hbWVWYWx1ZVBpcGUgfSBmcm9tICcuL2FwcC9tb2R1bGVzL3N5c3RlbS9waXBlcy9rZXktbmFtZS12YWx1ZS5waXBlJztcbmV4cG9ydCB7IExpbmtpZnlQaXBlIH0gZnJvbSAnLi9hcHAvbW9kdWxlcy9zeXN0ZW0vcGlwZXMvbGlua2lmeS5waXBlJztcblxuZXhwb3J0IHsgQXBpTG9nU3RhdGVzLCBDcm9uU3RhdGVzLCBQcm9jZXNzU3RhdGVzIH0gZnJvbSAnLi9hcHAvbW9kdWxlcy9zeXN0ZW0vY29uc3RzJztcbmV4cG9ydCB7IEFwaUxvZ1N0YXRlLCBDcm9uU3RhdGUsIFByb2Nlc3NTdGF0ZSB9IGZyb20gJy4vYXBwL21vZHVsZXMvc3lzdGVtL2VudW1zJztcblxuZXhwb3J0IHsgRGFzaGJvYXJkQWN0aW9uLCBGc1N5c3RlbUNvbmZpZywgUHJvY2Vzc0FjdGlvbiwgVXBncmFkZUV2ZW50IH0gZnJvbSAnLi9hcHAvbW9kdWxlcy9zeXN0ZW0vaW50ZXJmYWNlcyc7XG5cbmV4cG9ydCB7IEZTX1NZU1RFTV9DT05GSUcgfSBmcm9tICcuL2FwcC9tb2R1bGVzL3N5c3RlbS9pbmplY3RvcnMvc3lzdGVtLWNvbmZpZy5pbmplY3Rvcic7XG4iXX0=
|
|
@@ -47,7 +47,7 @@ import { FsApi, RequestMethod, StreamEventData, StreamEventType } from '@firesti
|
|
|
47
47
|
import { Subject, timer, Observable } from 'rxjs';
|
|
48
48
|
import { addMinutes, addHours, addDays, subSeconds, differenceInSeconds, getDaysInMonth, differenceInMinutes } from 'date-fns';
|
|
49
49
|
import { FsMessage } from '@firestitch/message';
|
|
50
|
-
import { FsProcess } from '@firestitch/process';
|
|
50
|
+
import { FsProcess, ProcessState as ProcessState$1 } from '@firestitch/process';
|
|
51
51
|
import { FsPrompt } from '@firestitch/prompt';
|
|
52
52
|
import { SelectionActionType } from '@firestitch/selection';
|
|
53
53
|
import { FsBuildService } from '@firestitch/build';
|
|
@@ -848,6 +848,13 @@ class DashboardComponent {
|
|
|
848
848
|
_message = inject(FsMessage);
|
|
849
849
|
_cdRef = inject(ChangeDetectorRef);
|
|
850
850
|
_buildService = inject(FsBuildService);
|
|
851
|
+
_process = inject(FsProcess);
|
|
852
|
+
_api = inject(FsApi);
|
|
853
|
+
/**
|
|
854
|
+
* All three are optional. Left unset, the component reads the standard system
|
|
855
|
+
* endpoints itself — the paths every application using this library already
|
|
856
|
+
* serves. One is supplied only to point the component somewhere else.
|
|
857
|
+
*/
|
|
851
858
|
init;
|
|
852
859
|
upgrade;
|
|
853
860
|
load;
|
|
@@ -881,20 +888,105 @@ class DashboardComponent {
|
|
|
881
888
|
action.click();
|
|
882
889
|
}
|
|
883
890
|
initClick() {
|
|
884
|
-
this.
|
|
891
|
+
this._init()
|
|
885
892
|
.subscribe(() => {
|
|
886
893
|
this._message.success('Successfully initialized the system');
|
|
887
894
|
});
|
|
888
895
|
}
|
|
896
|
+
/**
|
|
897
|
+
* Run the pending upgrades as a process rather than behind a spinner.
|
|
898
|
+
*
|
|
899
|
+
* A spinner says the same thing for ten seconds and for ten minutes, which is
|
|
900
|
+
* the whole problem: an upgrade that rebuilds the largest table in a schema
|
|
901
|
+
* looks exactly like one that has hung, and the only way anybody found out
|
|
902
|
+
* which was to wait for a proxy to give up.
|
|
903
|
+
*
|
|
904
|
+
* Works whether or not the application's endpoint streams. Where it does, each
|
|
905
|
+
* NDJSON event becomes a line in the process log — which function is running,
|
|
906
|
+
* how far through it is, what each one cost. Where it does not, the single
|
|
907
|
+
* reply produces no lines and the process is simply a labelled spinner, which
|
|
908
|
+
* is what every application had before this.
|
|
909
|
+
*/
|
|
889
910
|
upgradeClick() {
|
|
890
|
-
this.upgrade()
|
|
891
|
-
.
|
|
911
|
+
const process = this._process.run('System upgrade', this._upgrade()
|
|
912
|
+
.pipe(map((event) => this._upgradeLine(event)), filter((line) => line !== null)));
|
|
913
|
+
// The pending-upgrade count on this screen is the thing the button was
|
|
914
|
+
// pressed to change, so it is re-read when the run settles — including when
|
|
915
|
+
// it FAILS, because a run that stopped halfway still completed everything
|
|
916
|
+
// before the one that broke.
|
|
917
|
+
process.completed$
|
|
918
|
+
.pipe(take(1), takeUntil(this._destroy$))
|
|
919
|
+
.subscribe((state) => {
|
|
892
920
|
this._load();
|
|
893
|
-
|
|
921
|
+
if (state === ProcessState$1.Success) {
|
|
922
|
+
this._message.success('Successfully upgraded the system');
|
|
923
|
+
}
|
|
894
924
|
});
|
|
895
925
|
}
|
|
926
|
+
/**
|
|
927
|
+
* One emission off the upgrade endpoint, as a line for the process log — or
|
|
928
|
+
* null for anything with nothing to say, which is dropped rather than logged.
|
|
929
|
+
*
|
|
930
|
+
* `FsApi.stream()` wraps every NDJSON line in a `StreamEventData`, and
|
|
931
|
+
* `FsProcess` logs a string emission verbatim. So the mapping happens here: an
|
|
932
|
+
* object handed to the log renders as `[object Object]`.
|
|
933
|
+
*
|
|
934
|
+
* `ping` is deliberately silent. It is the heartbeat that stops a proxy
|
|
935
|
+
* closing a run that is still working, it fires after every statement, and it
|
|
936
|
+
* would bury the events worth reading.
|
|
937
|
+
*/
|
|
938
|
+
_upgradeLine(event) {
|
|
939
|
+
const data = (event instanceof StreamEventData ? event.data : event);
|
|
940
|
+
if (typeof data === 'string') {
|
|
941
|
+
return data;
|
|
942
|
+
}
|
|
943
|
+
if (!data || !data.type || data.type === 'ping') {
|
|
944
|
+
return null;
|
|
945
|
+
}
|
|
946
|
+
const step = `${data.index} of ${data.total}`;
|
|
947
|
+
switch (data.type) {
|
|
948
|
+
case 'start':
|
|
949
|
+
return data.total
|
|
950
|
+
? `${data.total} upgrade(s) to run: ${(data.functions || []).join(', ')}`
|
|
951
|
+
: 'Nothing to upgrade';
|
|
952
|
+
case 'upgrade':
|
|
953
|
+
if (data.state === 'started') {
|
|
954
|
+
return `${step} ${data.name}…`;
|
|
955
|
+
}
|
|
956
|
+
return data.state === 'completed'
|
|
957
|
+
? `${step} ${data.name} — ${data.duration}`
|
|
958
|
+
: `${step} ${data.name} FAILED — ${data.message}`;
|
|
959
|
+
case 'done':
|
|
960
|
+
return data.completed
|
|
961
|
+
? `Completed ${data.completed} upgrade(s)`
|
|
962
|
+
: 'Nothing to upgrade';
|
|
963
|
+
default:
|
|
964
|
+
return data.message || null;
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
_dashboardGet() {
|
|
968
|
+
return this.load
|
|
969
|
+
? this.load()
|
|
970
|
+
: this._api.get('system/dashboard', {}, { key: 'dashboard' });
|
|
971
|
+
}
|
|
972
|
+
_init() {
|
|
973
|
+
return this.init
|
|
974
|
+
? this.init()
|
|
975
|
+
: this._api.get('system/init', {}, { key: '' });
|
|
976
|
+
}
|
|
977
|
+
/**
|
|
978
|
+
* The upgrade endpoint is read as a stream by default, which is what fills the
|
|
979
|
+
* process log line by line while the run is still going. An application that
|
|
980
|
+
* supplies its own `upgrade` decides for itself — a plain request emits once,
|
|
981
|
+
* produces no lines, and the process is a labelled spinner.
|
|
982
|
+
*/
|
|
983
|
+
_upgrade() {
|
|
984
|
+
return this.upgrade
|
|
985
|
+
? this.upgrade()
|
|
986
|
+
: this._api.stream('GET', 'system/upgrade', { stream: true }, { key: '' });
|
|
987
|
+
}
|
|
896
988
|
_load() {
|
|
897
|
-
this.
|
|
989
|
+
this._dashboardGet()
|
|
898
990
|
.subscribe((dashboard) => {
|
|
899
991
|
this.dashboard = dashboard;
|
|
900
992
|
this.dashboard.cronRanAttention = !dashboard.cronRan ||
|