@ethlete/query 5.17.0 → 5.18.0
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/CHANGELOG.md +6 -0
- package/esm2022/index.mjs +2 -1
- package/esm2022/lib/devtools/components/query-devtools/query-devtools.component.mjs +3 -3
- package/esm2022/lib/devtools/pipes/query-short-name.pipe.mjs +3 -3
- package/esm2022/lib/directives/infinity-query-trigger.directive.mjs +3 -3
- package/esm2022/lib/directives/infinity-query.directive.mjs +3 -3
- package/esm2022/lib/directives/query.directive.mjs +3 -3
- package/esm2022/lib/experimental/bearer-auth-provider-config.mjs +19 -0
- package/esm2022/lib/experimental/bearer-auth-provider.mjs +245 -0
- package/esm2022/lib/experimental/http-request.mjs +153 -0
- package/esm2022/lib/experimental/index.mjs +21 -0
- package/esm2022/lib/experimental/query-client-config.mjs +13 -0
- package/esm2022/lib/experimental/query-client.mjs +16 -0
- package/esm2022/lib/experimental/query-creator-templates.mjs +33 -0
- package/esm2022/lib/experimental/query-creator.mjs +28 -0
- package/esm2022/lib/experimental/query-dependencies.mjs +14 -0
- package/esm2022/lib/experimental/query-errors.mjs +55 -0
- package/esm2022/lib/experimental/query-execute-utils.mjs +57 -0
- package/esm2022/lib/experimental/query-execute.mjs +12 -0
- package/esm2022/lib/experimental/query-features.mjs +126 -0
- package/esm2022/lib/experimental/query-repository.mjs +91 -0
- package/esm2022/lib/experimental/query-snapshot.mjs +44 -0
- package/esm2022/lib/experimental/query-state.mjs +20 -0
- package/esm2022/lib/experimental/query-utils.mjs +148 -0
- package/esm2022/lib/experimental/query.mjs +37 -0
- package/esm2022/lib/experimental/secure-query-creator.mjs +15 -0
- package/esm2022/lib/experimental/secure-query-execute.mjs +77 -0
- package/esm2022/lib/experimental/secure-query.mjs +41 -0
- package/esm2022/lib/query/query.types.mjs +1 -1
- package/fesm2022/ethlete-query.mjs +1283 -23
- package/fesm2022/ethlete-query.mjs.map +1 -1
- package/index.d.ts +1 -0
- package/lib/experimental/bearer-auth-provider-config.d.ts +111 -0
- package/lib/experimental/bearer-auth-provider.d.ts +63 -0
- package/lib/experimental/http-request.d.ts +55 -0
- package/lib/experimental/index.d.ts +20 -0
- package/lib/experimental/query-client-config.d.ts +18 -0
- package/lib/experimental/query-client.d.ts +10 -0
- package/lib/experimental/query-creator-templates.d.ts +14 -0
- package/lib/experimental/query-creator.d.ts +39 -0
- package/lib/experimental/query-dependencies.d.ts +12 -0
- package/lib/experimental/query-errors.d.ts +39 -0
- package/lib/experimental/query-execute-utils.d.ts +20 -0
- package/lib/experimental/query-execute.d.ts +16 -0
- package/lib/experimental/query-features.d.ts +45 -0
- package/lib/experimental/query-repository.d.ts +31 -0
- package/lib/experimental/query-snapshot.d.ts +8 -0
- package/lib/experimental/query-state.d.ts +14 -0
- package/lib/experimental/query-utils.d.ts +41 -0
- package/lib/experimental/query.d.ts +41 -0
- package/lib/experimental/secure-query-creator.d.ts +7 -0
- package/lib/experimental/secure-query-execute.d.ts +7 -0
- package/lib/experimental/secure-query.d.ts +6 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @ethlete/query
|
|
2
2
|
|
|
3
|
+
## 5.18.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`211bd8d`](https://github.com/ethlete-io/ethdk/commit/211bd8db1ea19f222743155b9185e2910c9662ac) Thanks [@TomTomB](https://github.com/TomTomB)! - Expose the reworked query api via `ExperimentalQuery` import. The new api makes rxjs optional.
|
|
8
|
+
|
|
3
9
|
## 5.17.0
|
|
4
10
|
|
|
5
11
|
### Minor Changes
|
package/esm2022/index.mjs
CHANGED
|
@@ -5,6 +5,7 @@ export * from './lib/devtools/pipes';
|
|
|
5
5
|
export * from './lib/devtools/utils';
|
|
6
6
|
export * from './lib/directives';
|
|
7
7
|
export * from './lib/entity';
|
|
8
|
+
export * as ExperimentalQuery from './lib/experimental';
|
|
8
9
|
export * from './lib/gql';
|
|
9
10
|
export * from './lib/infinite-query';
|
|
10
11
|
export * from './lib/logger';
|
|
@@ -17,4 +18,4 @@ export * from './lib/request';
|
|
|
17
18
|
export * from './lib/symfony';
|
|
18
19
|
export * from './lib/utils';
|
|
19
20
|
// Burst cache
|
|
20
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9saWJzL3F1ZXJ5L3NyYy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLFlBQVksQ0FBQztBQUMzQixjQUFjLHVCQUF1QixDQUFDO0FBQ3RDLGNBQWMsMENBQTBDLENBQUM7QUFDekQsY0FBYyxzQkFBc0IsQ0FBQztBQUNyQyxjQUFjLHNCQUFzQixDQUFDO0FBQ3JDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyxjQUFjLENBQUM7QUFDN0IsT0FBTyxLQUFLLGlCQUFpQixNQUFNLG9CQUFvQixDQUFDO0FBQ3hELGNBQWMsV0FBVyxDQUFDO0FBQzFCLGNBQWMsc0JBQXNCLENBQUM7QUFDckMsY0FBYyxjQUFjLENBQUM7QUFDN0IsY0FBYyxhQUFhLENBQUM7QUFDNUIsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyxtQkFBbUIsQ0FBQztBQUNsQyxjQUFjLGVBQWUsQ0FBQztBQUM5QixjQUFjLGVBQWUsQ0FBQztBQUM5QixjQUFjLGFBQWEsQ0FBQztBQUU1QixjQUFjIiwic291cmNlc0NvbnRlbnQiOlsiZXhwb3J0ICogZnJvbSAnLi9saWIvYXV0aCc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9jbGFzcy12YWxpZGF0b3InO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvZGV2dG9vbHMvY29tcG9uZW50cy9xdWVyeS1kZXZ0b29scyc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9kZXZ0b29scy9waXBlcyc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9kZXZ0b29scy91dGlscyc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9kaXJlY3RpdmVzJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2VudGl0eSc7XG5leHBvcnQgKiBhcyBFeHBlcmltZW50YWxRdWVyeSBmcm9tICcuL2xpYi9leHBlcmltZW50YWwnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvZ3FsJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2luZmluaXRlLXF1ZXJ5JztcbmV4cG9ydCAqIGZyb20gJy4vbGliL2xvZ2dlcic7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9xdWVyeSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9xdWVyeS1jbGllbnQnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvcXVlcnktY3JlYXRvcic7XG5leHBvcnQgKiBmcm9tICcuL2xpYi9xdWVyeS1mb3JtJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3F1ZXJ5LXN0b3JlJztcbmV4cG9ydCAqIGZyb20gJy4vbGliL3JlcXVlc3QnO1xuZXhwb3J0ICogZnJvbSAnLi9saWIvc3ltZm9ueSc7XG5leHBvcnQgKiBmcm9tICcuL2xpYi91dGlscyc7XG5cbi8vIEJ1cnN0IGNhY2hlXG4iXX0=
|
|
@@ -285,10 +285,10 @@ export class QueryDevtoolsComponent {
|
|
|
285
285
|
clearQueryHistory() {
|
|
286
286
|
this.queryHistory$.next([]);
|
|
287
287
|
}
|
|
288
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.
|
|
289
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.1", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Query Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Inspector</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('live'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live Queries ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('history'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Query History ({{ (queryHistory$ | async)?.length ?? 0 }}/50)\n </button>\n @if (queryListMode() === 'history' && viewMode() === 'query') {\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n }\n\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': viewMode() !== 'authProvider' }\"\n (click)=\"selectViewMode('authProvider')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Auth Provider\n </button>\n </div>\n\n @if (viewMode() === 'query') {\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n } @else if (viewMode() === 'authProvider') {\n <div class=\"et-qd-auth-provider__viewer\">\n @if (authProviderDetails(); as details) {\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>Type</p>\n <pre>{{ details.type }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Header value</p>\n <pre>{{ details.header() | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Config</p>\n <pre>{{ details.config | json }}</pre>\n </div>\n\n @if (details.type === 'BearerAuthProvider') {\n <div class=\"et-qd-list-item\">\n <p>Tokens</p>\n <pre>{{ details.provider.tokens$ | async | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Should refresh on unauthorized response</p>\n <pre>{{ details.provider.shouldRefreshOnUnauthorizedResponse }}</pre>\n </div>\n\n <ng-container\n *etQuery=\"\n details.provider.currentRefreshQuery$ | async as response;\n loading as loading;\n error as error;\n query as query\n \"\n >\n <div class=\"et-qd-list-item\">\n <p>Refresh query response</p>\n\n <div>\n <button (click)=\"details.provider._refreshQuery()\" class=\"et-qd-chip et-qd-chip-bordered\">\n Refresh\n </button>\n </div>\n <pre>{{ response | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query loading</p>\n <pre>{{ loading }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query error</p>\n <pre>{{ error ?? 'null' }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <pre>{{ query?.state$ | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}button.et-query-devtools-open-btn{position:fixed;inset-inline-end:20px;inset-block-end:0;z-index:9999;font-family:monospace;border-radius:3px 3px 0 0;line-height:14px;font-size:12px}.et-qd-header{background-color:#00ffa1;padding:12px;display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center}.et-qd-header__title{color:#25292e;margin:0;font-size:22px}.et-qd-header__select{display:grid;background-color:#25292e;border-radius:10px;overflow:hidden}.et-qd-header__select select{width:250px;color:#fff;padding:3px 10px 2px;border:none;background-color:#25292e;font-family:monospace}.et-qd-header__select label{padding:3px 10px;color:#25292e;font-size:12px;font-weight:700;color:#fff;border-bottom:1px solid gray}.et-qd-sub-header{background-color:#00b371;padding:12px;display:flex;gap:12px;flex-wrap:wrap}.et-qd-sub-header__divider{width:1px;background-color:#25292e}.et-qd-btn{background-color:#00ffa1;color:#25292e;border:none;padding:12px;cursor:pointer;font-size:14px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;width:100%;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-btn:hover{background-color:#00cc81}.et-qd-btn.et-qd-btn-secondary{background-color:#25292e;color:#00ffa1}.et-qd-btn.et-qd-btn-secondary:hover{background-color:#3c424a}.et-qd-chip{background-color:#00ffa1;color:#25292e;border:none;padding:4px 9px;cursor:pointer;font-size:12px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-chip:hover{background-color:#00cc81}.et-qd-chip.et-qd-chip-secondary{background-color:#25292e;color:#00ffa1}.et-qd-chip.et-qd-chip-secondary:hover{background-color:#3c424a}.et-qd-chip.et-qd-chip-bordered{border:1px solid rgb(0,255,161)}.et-qd-translucent-clickable{pointer-events:all}.et-qd-client{border-bottom:1px solid #3c424a;padding:12px}.et-qd-client__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-client__actions{display:flex;gap:12px;margin-top:12px}.et-qd-queries{padding:12px;display:grid;grid-template-rows:auto auto minmax(0,1fr)}.et-qd-queries__actions{display:flex;gap:12px;margin-top:12px;margin-bottom:16px}.et-qd-queries__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-queries__divider{width:1px;background-color:#3c424a}.et-qd-queries__browser{display:grid;grid-template-columns:1fr minmax(0,3fr);margin-left:-12px;margin-right:-12px;border-top:1px solid #3c424a;margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid #3c424a;list-style:none;padding:0;margin:0;display:grid;grid-auto-flow:row;grid-auto-rows:55px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-list li{margin:0}.et-qd-queries__browser-list li button{all:unset;font-family:monospace;box-sizing:border-box;width:100%;border:none;border-bottom:1px solid #3c424a;background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer;display:grid;grid-template-columns:auto minmax(0,1fr);gap:2px;display:block}.et-qd-queries__browser-list li button span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.et-qd-queries__browser-list li button span:first-of-type{font-weight:700}.et-qd-queries__browser-list li button:hover,.et-qd-queries__browser-list li button.et-qd-query--active{background-color:#30363c}.et-qd-queries__browser-detail{padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-detail__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-auth-provider__viewer{border-top:1px solid #3c424a;margin-left:-12px;margin-right:-12px;margin-bottom:-12px;padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-list{display:grid;gap:12px}.et-qd-list-item{display:grid}.et-qd-list-item p{font-weight:700;margin:0;padding-bottom:8px}.et-qd-list-item p+p{margin-top:-8px}.et-qd-list-item div+pre{margin-top:8px}.et-qd-list-item pre{margin:0;padding:4px;background-color:#0e1012;border-radius:4px;max-height:450px;overflow:auto}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: QueryShortNamePipe, name: "queryShortName" }, { kind: "directive", type: QueryDirective, selector: "[etQuery]", inputs: ["etQuery", "etQueryCache"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom }); }
|
|
288
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: QueryDevtoolsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
289
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.1.4", type: QueryDevtoolsComponent, isStandalone: true, selector: "et-query-devtools", host: { classAttribute: "et-query-devtools" }, ngImport: i0, template: "@if (!isOpen()) {\n <button (click)=\"toggleOpen()\" class=\"et-query-devtools-open-btn et-qd-chip\">Query Devtools</button>\n}\n\n@if (isOpen()) {\n <div\n [class.et-query-devtools-container--transparent]=\"isTranslucent()\"\n class=\"et-query-devtools-container et-query-devtools-container--snap-{{ snapLayout() }}\"\n >\n <header class=\"et-qd-header\">\n <h3 class=\"et-qd-header__title\">Query Devtools</h3>\n\n <div class=\"et-qd-header__select\">\n <label for=\"et-query-client-instance\">Client instance</label>\n <select [formControl]=\"selectedClientIdCtrl\" id=\"et-query-client-instance\">\n @for (clientConfig of queryClientConfigs; track trackByClient(i, clientConfig); let i = $index) {\n <option [value]=\"i\">\n {{ clientConfig.displayName ?? clientConfig.client.config.baseRoute }}\n </option>\n }\n </select>\n </div>\n\n <button (click)=\"toggleOpen()\" class=\"et-qd-btn et-qd-btn-secondary\">Close</button>\n </header>\n\n <div class=\"et-qd-sub-header\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !isTranslucent() }\"\n (click)=\"toggleTranslucent()\"\n class=\"et-qd-chip et-qd-translucent-clickable\"\n >\n Translucent\n </button>\n <div class=\"et-qd-sub-header__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'full' }\"\n (click)=\"selectSnapLayout('full')\"\n class=\"et-qd-chip\"\n >\n Fullscreen\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'top' }\"\n (click)=\"selectSnapLayout('top')\"\n class=\"et-qd-chip\"\n >\n Top\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'bottom' }\"\n (click)=\"selectSnapLayout('bottom')\"\n class=\"et-qd-chip\"\n >\n Bottom\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'left' }\"\n (click)=\"selectSnapLayout('left')\"\n class=\"et-qd-chip\"\n >\n Left\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': snapLayout() !== 'right' }\"\n (click)=\"selectSnapLayout('right')\"\n class=\"et-qd-chip\"\n >\n Right\n </button>\n </div>\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-client\">\n <p class=\"et-qd-client__title\">{{ cfg.displayName ?? cfg.client.config.baseRoute }}</p>\n\n <div class=\"et-qd-client__actions\">\n <button (click)=\"cfg.client._store.refreshQueriesInUse()\" class=\"et-qd-chip\">Refresh all</button>\n <button (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true })\" class=\"et-qd-chip\">\n Refresh all (ignore caches)\n </button>\n <button\n (click)=\"cfg.client._store.refreshQueriesInUse({ ignoreCacheValidity: true, purgeUnused: true })\"\n class=\"et-qd-chip\"\n >\n Refresh all (ignore caches & purge unused)\n </button>\n </div>\n </div>\n }\n\n @if (selectedClientConfig(); as cfg) {\n <div class=\"et-qd-queries\">\n <p class=\"et-qd-queries__title\">Inspector</p>\n <div class=\"et-qd-queries__actions\">\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'live' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('live'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Live Queries ({{ queries()?.length ?? 0 }})\n </button>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': queryListMode() !== 'history' || viewMode() !== 'query' }\"\n (click)=\"selectQueryListMode('history'); selectViewMode('query')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Query History ({{ (queryHistory$ | async)?.length ?? 0 }}/50)\n </button>\n @if (queryListMode() === 'history' && viewMode() === 'query') {\n <div class=\"et-qd-queries__divider\"></div>\n <button (click)=\"clearQueryHistory()\" class=\"et-qd-chip et-qd-chip-bordered\">Clear history</button>\n }\n\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': viewMode() !== 'authProvider' }\"\n (click)=\"selectViewMode('authProvider')\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Auth Provider\n </button>\n </div>\n\n @if (viewMode() === 'query') {\n <div class=\"et-qd-queries__browser\">\n @if (queryListMode() === 'live') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queries(); track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n @if (queryListMode() === 'history') {\n <ul class=\"et-qd-queries__browser-list\">\n @for (query of queryHistory$ | async; track trackByQuery($index, query)) {\n <li>\n <button\n [class.et-qd-query--active]=\"selectedQuery()?._id === query._id\"\n (click)=\"selectQuery(query)\"\n >\n <span> {{ query._queryConfig.method }}</span>\n <span> {{ query | queryShortName }}</span>\n </button>\n </li>\n }\n </ul>\n }\n <div class=\"et-qd-queries__browser-detail\">\n @if (selectedQuery(); as query) {\n <p class=\"et-qd-queries__browser-detail__title\">\n {{ query._queryConfig.method }} {{ query._routeWithParams }}\n </p>\n\n <div class=\"et-qd-queries__actions\">\n <button (click)=\"query.execute()\" class=\"et-qd-chip et-qd-chip-bordered\">Execute</button>\n <button (click)=\"query.execute({ skipCache: true })\" class=\"et-qd-chip et-qd-chip-bordered\">\n Execute (ignore cache)\n </button>\n\n <button (click)=\"query.abort()\" class=\"et-qd-chip et-qd-chip-bordered\">Abort</button>\n <div class=\"et-qd-queries__divider\"></div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !query.isPolling }\"\n (click)=\"query.poll({ interval: 5000, takeUntil: _destroy$ })\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Poll\n </button>\n\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': query.isPolling }\"\n (click)=\"query.stopPolling()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Stop polling\n </button>\n @if (query.isPolling || query._isPollingPaused) {\n <button (click)=\"query.pausePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Pause polling\n </button>\n <button (click)=\"query.resumePolling()\" class=\"et-qd-chip et-qd-chip-secondary et-qd-chip-bordered\">\n Resume polling\n </button>\n }\n </div>\n\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>State type</p>\n <pre>{{ query.rawState.type }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Dependents</p>\n <pre>{{ query._dependents | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is expired</p>\n <pre>{{ query.isExpired }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is in use</p>\n <pre>{{ query.isInUse }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Subscriber count</p>\n <pre>{{ query._subscriberCount }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling</p>\n <pre>{{ query.isPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Is polling paused</p>\n <pre>{{ query._isPollingPaused }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Enable smart polling</p>\n <pre>{{ query._enableSmartPolling }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query store key</p>\n <pre>{{ query._queryStoreKey }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Arguments</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showArguments() }\"\n (click)=\"toggleShowArguments()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showArguments()) {\n <pre>{{ query._arguments | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <p><i> Warning, this will cause a subscription if shown!</i></p>\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showResponse() }\"\n (click)=\"toggleShowResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showResponse()) {\n <pre>{{ query.state$ | async | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Raw state</p>\n <p><i> The query state unaffected by entity stores</i></p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showRawResponse() }\"\n (click)=\"toggleShowRawResponse()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showRawResponse()) {\n <pre>{{ query.rawState | json }}</pre>\n }\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Query config</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showQueryConfig() }\"\n (click)=\"toggleShowQueryConfig()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showQueryConfig()) {\n <pre>{{ stringifiedQueryConfig() | json }}</pre>\n }\n </div>\n\n @if (!!query._queryConfig.entity) {\n <div class=\"et-qd-list-item\">\n <p>Entity store value</p>\n\n <div>\n <button\n [ngClass]=\"{ 'et-qd-chip-secondary': !showEntityStoreValue() }\"\n (click)=\"toggleShowEntityStoreValue()\"\n class=\"et-qd-chip et-qd-chip-bordered\"\n >\n Toggle\n </button>\n </div>\n @if (showEntityStoreValue()) {\n <pre>{{ selectedQueryEntityStoreValue$ | async | json }}</pre>\n }\n </div>\n }\n </div>\n }\n </div>\n </div>\n } @else if (viewMode() === 'authProvider') {\n <div class=\"et-qd-auth-provider__viewer\">\n @if (authProviderDetails(); as details) {\n <div class=\"et-qd-list\">\n <div class=\"et-qd-list-item\">\n <p>Type</p>\n <pre>{{ details.type }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Header value</p>\n <pre>{{ details.header() | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Config</p>\n <pre>{{ details.config | json }}</pre>\n </div>\n\n @if (details.type === 'BearerAuthProvider') {\n <div class=\"et-qd-list-item\">\n <p>Tokens</p>\n <pre>{{ details.provider.tokens$ | async | json }}</pre>\n </div>\n\n <div class=\"et-qd-list-item\">\n <p>Should refresh on unauthorized response</p>\n <pre>{{ details.provider.shouldRefreshOnUnauthorizedResponse }}</pre>\n </div>\n\n <ng-container\n *etQuery=\"\n details.provider.currentRefreshQuery$ | async as response;\n loading as loading;\n error as error;\n query as query\n \"\n >\n <div class=\"et-qd-list-item\">\n <p>Refresh query response</p>\n\n <div>\n <button (click)=\"details.provider._refreshQuery()\" class=\"et-qd-chip et-qd-chip-bordered\">\n Refresh\n </button>\n </div>\n <pre>{{ response | json }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query loading</p>\n <pre>{{ loading }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>Refresh query error</p>\n <pre>{{ error ?? 'null' }}</pre>\n </div>\n <div class=\"et-qd-list-item\">\n <p>State</p>\n <pre>{{ query?.state$ | async | json }}</pre>\n </div>\n </ng-container>\n }\n </div>\n } @else {\n <p>No auth provider set</p>\n }\n </div>\n }\n </div>\n }\n </div>\n}\n", styles: [":host{position:fixed;top:0;z-index:1000000;font-size:14px;color:#fff}.et-query-devtools-container{position:fixed;inset:0;background-color:#25292e;z-index:10000;overflow:auto;font-family:monospace;display:grid;grid-template-rows:auto auto auto minmax(0,1fr)}.et-query-devtools-container.et-query-devtools-container--transparent{opacity:.25;pointer-events:none}.et-query-devtools-container.et-query-devtools-container--transparent .et-query-devtools-translucent-btn{pointer-events:all}.et-query-devtools-container.et-query-devtools-container--snap-left{inset-inline-start:0;inset-block-start:0;inset-block-end:0;width:50%;border-right:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-right{inset-inline-start:unset;inset-inline-end:0;inset-block-start:0;inset-block-end:0;width:50%;border-left:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-top{inset-inline-start:0;inset-block-start:0;inset-inline-end:0;height:50%;border-bottom:1px solid rgb(37,41,46)}.et-query-devtools-container.et-query-devtools-container--snap-bottom{inset-inline-start:0;inset-block-start:unset;inset-block-end:0;inset-inline-end:0;height:50%;border-top:1px solid rgb(37,41,46)}button.et-query-devtools-open-btn{position:fixed;inset-inline-end:20px;inset-block-end:0;z-index:9999;font-family:monospace;border-radius:3px 3px 0 0;line-height:14px;font-size:12px}.et-qd-header{background-color:#00ffa1;padding:12px;display:grid;grid-template-columns:1fr auto auto;gap:12px;align-items:center}.et-qd-header__title{color:#25292e;margin:0;font-size:22px}.et-qd-header__select{display:grid;background-color:#25292e;border-radius:10px;overflow:hidden}.et-qd-header__select select{width:250px;color:#fff;padding:3px 10px 2px;border:none;background-color:#25292e;font-family:monospace}.et-qd-header__select label{padding:3px 10px;color:#25292e;font-size:12px;font-weight:700;color:#fff;border-bottom:1px solid gray}.et-qd-sub-header{background-color:#00b371;padding:12px;display:flex;gap:12px;flex-wrap:wrap}.et-qd-sub-header__divider{width:1px;background-color:#25292e}.et-qd-btn{background-color:#00ffa1;color:#25292e;border:none;padding:12px;cursor:pointer;font-size:14px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;width:100%;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-btn:hover{background-color:#00cc81}.et-qd-btn.et-qd-btn-secondary{background-color:#25292e;color:#00ffa1}.et-qd-btn.et-qd-btn-secondary:hover{background-color:#3c424a}.et-qd-chip{background-color:#00ffa1;color:#25292e;border:none;padding:4px 9px;cursor:pointer;font-size:12px;font-weight:700;text-align:center;text-decoration:none;display:inline-block;transition:all .3s ease-in-out;font-family:monospace;border-radius:10px}.et-qd-chip:hover{background-color:#00cc81}.et-qd-chip.et-qd-chip-secondary{background-color:#25292e;color:#00ffa1}.et-qd-chip.et-qd-chip-secondary:hover{background-color:#3c424a}.et-qd-chip.et-qd-chip-bordered{border:1px solid rgb(0,255,161)}.et-qd-translucent-clickable{pointer-events:all}.et-qd-client{border-bottom:1px solid #3c424a;padding:12px}.et-qd-client__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-client__actions{display:flex;gap:12px;margin-top:12px}.et-qd-queries{padding:12px;display:grid;grid-template-rows:auto auto minmax(0,1fr)}.et-qd-queries__actions{display:flex;gap:12px;margin-top:12px;margin-bottom:16px}.et-qd-queries__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-queries__divider{width:1px;background-color:#3c424a}.et-qd-queries__browser{display:grid;grid-template-columns:1fr minmax(0,3fr);margin-left:-12px;margin-right:-12px;border-top:1px solid #3c424a;margin-bottom:-12px}.et-qd-queries__browser-list{border-right:1px solid #3c424a;list-style:none;padding:0;margin:0;display:grid;grid-auto-flow:row;grid-auto-rows:55px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-list li{margin:0}.et-qd-queries__browser-list li button{all:unset;font-family:monospace;box-sizing:border-box;width:100%;border:none;border-bottom:1px solid #3c424a;background-color:#25292e;color:#fff;text-align:left;padding:12px;height:100%;transition:all .3s ease-in-out;cursor:pointer;display:grid;grid-template-columns:auto minmax(0,1fr);gap:2px;display:block}.et-qd-queries__browser-list li button span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.et-qd-queries__browser-list li button span:first-of-type{font-weight:700}.et-qd-queries__browser-list li button:hover,.et-qd-queries__browser-list li button.et-qd-query--active{background-color:#30363c}.et-qd-queries__browser-detail{padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-queries__browser-detail__title{margin:0;font-size:14px;color:#fff;font-weight:700}.et-qd-auth-provider__viewer{border-top:1px solid #3c424a;margin-left:-12px;margin-right:-12px;margin-bottom:-12px;padding:12px;overflow-y:auto;overflow-x:hidden}.et-qd-list{display:grid;gap:12px}.et-qd-list-item{display:grid}.et-qd-list-item p{font-weight:700;margin:0;padding-bottom:8px}.et-qd-list-item p+p{margin-top:-8px}.et-qd-list-item div+pre{margin-top:8px}.et-qd-list-item pre{margin:0;padding:4px;background-color:#0e1012;border-radius:4px;max-height:450px;overflow:auto}\n"], dependencies: [{ kind: "pipe", type: AsyncPipe, name: "async" }, { kind: "pipe", type: JsonPipe, name: "json" }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i1.SelectControlValueAccessor, selector: "select:not([multiple])[formControlName],select:not([multiple])[formControl],select:not([multiple])[ngModel]", inputs: ["compareWith"] }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "pipe", type: QueryShortNamePipe, name: "queryShortName" }, { kind: "directive", type: QueryDirective, selector: "[etQuery]", inputs: ["etQuery", "etQueryCache"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.ShadowDom }); }
|
|
290
290
|
}
|
|
291
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.
|
|
291
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: QueryDevtoolsComponent, decorators: [{
|
|
292
292
|
type: Component,
|
|
293
293
|
args: [{ selector: 'et-query-devtools', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.ShadowDom, host: {
|
|
294
294
|
class: 'et-query-devtools',
|
|
@@ -14,10 +14,10 @@ export class QueryShortNamePipe {
|
|
|
14
14
|
}
|
|
15
15
|
return route;
|
|
16
16
|
}
|
|
17
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.
|
|
18
|
-
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.1.
|
|
17
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: QueryShortNamePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
|
|
18
|
+
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "18.1.4", ngImport: i0, type: QueryShortNamePipe, isStandalone: true, name: "queryShortName" }); }
|
|
19
19
|
}
|
|
20
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.
|
|
20
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: QueryShortNamePipe, decorators: [{
|
|
21
21
|
type: Pipe,
|
|
22
22
|
args: [{ name: 'queryShortName', standalone: true }]
|
|
23
23
|
}] });
|
|
@@ -40,10 +40,10 @@ export class InfinityQueryTriggerDirective {
|
|
|
40
40
|
});
|
|
41
41
|
this._observer.observe(this._elementRef.nativeElement);
|
|
42
42
|
}
|
|
43
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.
|
|
44
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.
|
|
43
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: InfinityQueryTriggerDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
44
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.4", type: InfinityQueryTriggerDirective, isStandalone: true, selector: "[etInfinityQueryTrigger], et-infinity-query-trigger", inputs: { scrollContainerSelector: "scrollContainerSelector" }, ngImport: i0 }); }
|
|
45
45
|
}
|
|
46
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.
|
|
46
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: InfinityQueryTriggerDirective, decorators: [{
|
|
47
47
|
type: Directive,
|
|
48
48
|
args: [{
|
|
49
49
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
@@ -127,10 +127,10 @@ export class InfinityQueryDirective {
|
|
|
127
127
|
this._viewContext.currentQuery = null;
|
|
128
128
|
this._data$.next([]);
|
|
129
129
|
}
|
|
130
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.
|
|
131
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.
|
|
130
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: InfinityQueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
131
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.4", type: InfinityQueryDirective, isStandalone: true, selector: "[etInfinityQuery]", inputs: { infinityQuery: ["etInfinityQuery", "infinityQuery"] }, providers: [{ provide: INFINITY_QUERY_TOKEN, useExisting: InfinityQueryDirective }], exportAs: ["etInfinityQuery"], hostDirectives: [{ directive: i1.DelayableDirective }], ngImport: i0 }); }
|
|
132
132
|
}
|
|
133
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.
|
|
133
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: InfinityQueryDirective, decorators: [{
|
|
134
134
|
type: Directive,
|
|
135
135
|
args: [{
|
|
136
136
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
@@ -103,10 +103,10 @@ export class QueryDirective {
|
|
|
103
103
|
this._viewContainerRef.createEmbeddedView(this._mainTemplateRef, this._viewContext);
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.
|
|
107
|
-
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.
|
|
106
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: QueryDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
107
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.1.4", type: QueryDirective, isStandalone: true, selector: "[etQuery]", inputs: { query: ["etQuery", "query"], cache: ["etQueryCache", "cache"] }, ngImport: i0 }); }
|
|
108
108
|
}
|
|
109
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.
|
|
109
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.1.4", ngImport: i0, type: QueryDirective, decorators: [{
|
|
110
110
|
type: Directive,
|
|
111
111
|
args: [{
|
|
112
112
|
// eslint-disable-next-line @angular-eslint/directive-selector
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { InjectionToken } from '@angular/core';
|
|
2
|
+
export const createBearerAuthProviderConfig = (options) => {
|
|
3
|
+
const token = new InjectionToken(`BearerAuthProvider_${options.name}`);
|
|
4
|
+
const bearerAuthProviderConfig = {
|
|
5
|
+
name: options.name,
|
|
6
|
+
queryClientRef: options.queryClientRef,
|
|
7
|
+
token,
|
|
8
|
+
cookie: options.cookie,
|
|
9
|
+
expiresInPropertyName: options.expiresInPropertyName ?? 'exp',
|
|
10
|
+
refreshBuffer: options.refreshBuffer ?? 300000,
|
|
11
|
+
refreshOnUnauthorizedResponse: options.refreshOnUnauthorizedResponse ?? true,
|
|
12
|
+
login: options.login,
|
|
13
|
+
selectRole: options.selectRole,
|
|
14
|
+
tokenLogin: options.tokenLogin,
|
|
15
|
+
tokenRefresh: options.tokenRefresh,
|
|
16
|
+
};
|
|
17
|
+
return bearerAuthProviderConfig;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmVhcmVyLWF1dGgtcHJvdmlkZXItY29uZmlnLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9xdWVyeS9zcmMvbGliL2V4cGVyaW1lbnRhbC9iZWFyZXItYXV0aC1wcm92aWRlci1jb25maWcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQXNKL0MsTUFBTSxDQUFDLE1BQU0sOEJBQThCLEdBQUcsQ0FNNUMsT0FBK0csRUFDL0csRUFBRTtJQUNGLE1BQU0sS0FBSyxHQUFHLElBQUksY0FBYyxDQUU5QixzQkFBc0IsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7SUFFeEMsTUFBTSx3QkFBd0IsR0FLMUI7UUFDRixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7UUFDbEIsY0FBYyxFQUFFLE9BQU8sQ0FBQyxjQUFjO1FBQ3RDLEtBQUs7UUFDTCxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU07UUFDdEIscUJBQXFCLEVBQUUsT0FBTyxDQUFDLHFCQUFxQixJQUFJLEtBQUs7UUFDN0QsYUFBYSxFQUFFLE9BQU8sQ0FBQyxhQUFhLElBQUksTUFBTTtRQUM5Qyw2QkFBNkIsRUFBRSxPQUFPLENBQUMsNkJBQTZCLElBQUksSUFBSTtRQUM1RSxLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUs7UUFDcEIsVUFBVSxFQUFFLE9BQU8sQ0FBQyxVQUFVO1FBQzlCLFVBQVUsRUFBRSxPQUFPLENBQUMsVUFBVTtRQUM5QixZQUFZLEVBQUUsT0FBTyxDQUFDLFlBQVk7S0FDbkMsQ0FBQztJQUVGLE9BQU8sd0JBQXdCLENBQUM7QUFDbEMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSW5qZWN0aW9uVG9rZW4gfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEJlYXJlckF1dGhQcm92aWRlciB9IGZyb20gJy4vYmVhcmVyLWF1dGgtcHJvdmlkZXInO1xuaW1wb3J0IHsgUXVlcnlBcmdzLCBSZXF1ZXN0QXJncywgUmVzcG9uc2VUeXBlIH0gZnJvbSAnLi9xdWVyeSc7XG5pbXBvcnQgeyBRdWVyeUNsaWVudFJlZiB9IGZyb20gJy4vcXVlcnktY2xpZW50LWNvbmZpZyc7XG5pbXBvcnQgeyBRdWVyeUNyZWF0b3IgfSBmcm9tICcuL3F1ZXJ5LWNyZWF0b3InO1xuXG5leHBvcnQgdHlwZSBCZWFyZXJBdXRoUHJvdmlkZXJUb2tlbnMgPSB7XG4gIGFjY2Vzc1Rva2VuOiBzdHJpbmc7XG4gIHJlZnJlc2hUb2tlbjogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgQmVhcmVyQXV0aFByb3ZpZGVyUm91dGVDb25maWc8VEFyZ3MgZXh0ZW5kcyBRdWVyeUFyZ3M+ID0ge1xuICBxdWVyeUNyZWF0b3I6IFF1ZXJ5Q3JlYXRvcjxUQXJncz47XG5cbiAgLyoqXG4gICAqIEEgZnVuY3Rpb24gdGhhdCB0cmFuc2Zvcm1zIHRoZSByZXNwb25zZSBpbnRvIHRoZSBmb3JtYXQgdGhhdCB0aGUgYXV0aCBwcm92aWRlciBleHBlY3RzXG4gICAqXG4gICAqIFRoZSBleHBlY3RlZCBmb3JtYXQgaXMgYW4gb2JqZWN0IHdpdGggdGhlIGBhY2Nlc3NUb2tlbmAgYW5kIGByZWZyZXNoVG9rZW5gIHByb3BlcnRpZXMuXG4gICAqXG4gICAqIEBkZWZhdWx0IChyZXNwb25zZSkgPT4gcmVzcG9uc2VcbiAgICovXG4gIHJlc3BvbnNlVHJhbnNmb3JtZXI/OiAocmVzcG9uc2U6IFJlc3BvbnNlVHlwZTxUQXJncz4pID0+IEJlYXJlckF1dGhQcm92aWRlclRva2Vucztcbn07XG5cbmV4cG9ydCB0eXBlIEJlYXJlckF1dGhQcm92aWRlckNvb2tpZUNvbmZpZzxUVG9rZW5SZWZyZXNoQXJncyBleHRlbmRzIFF1ZXJ5QXJncz4gPSB7XG4gIC8qKlxuICAgKiBUaGUgY29va2llIG5hbWUgd2hlcmUgdGhlIHJlZnJlc2ggdG9rZW4gaXMgc3RvcmVkXG4gICAqIEBkZWZhdWx0ICdldEF1dGgnXG4gICAqL1xuICBuYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZG9tYWluIG9mIHRoZSBjb29raWUuIElmIG5vdCBzZXQsIHRoZSBjdXJyZW50IG9yaWdpbiB3aWxsIGJlIHVzZWQuXG4gICAqXG4gICAqIEBleGFtcGxlXG4gICAqIFwiaHR0cHM6Ly9leGFtcGxlLmNvbVwiIC0+IFwiZXhhbXBsZS5jb21cIlxuICAgKiBcImh0dHBzOi8vc3ViLmV4YW1wbGUuY29tXCIgLT4gXCJleGFtcGxlLmNvbVwiXG4gICAqL1xuICBkb21haW4/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBkYXlzIHVudGlsIHRoZSBjb29raWUgZXhwaXJlc1xuICAgKiBAZGVmYXVsdCAzMFxuICAgKi9cbiAgZXhwaXJlc0luRGF5cz86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIHBhdGggb2YgdGhlIGNvb2tpZVxuICAgKiBAZGVmYXVsdCAnLydcbiAgICovXG4gIHBhdGg/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEVuYWJsZSBvciBkaXNhYmxlIHRoZSBjb29raWVcbiAgICogQGRlZmF1bHQgdHJ1ZVxuICAgKi9cbiAgZW5hYmxlZD86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBzYW1lIHNpdGUgcHJvcGVydHkgb2YgdGhlIGNvb2tpZVxuICAgKiBAZGVmYXVsdCAnbGF4J1xuICAgKi9cbiAgc2FtZVNpdGU/OiAnc3RyaWN0JyB8ICdub25lJyB8ICdsYXgnO1xuXG4gIC8qKlxuICAgKiBBIGZ1bmN0aW9uIHRoYXQgdHVybnMgdGhlIHRva2VuIGdvdHRlbiBmcm9tIHRoZSBjb29raWUgaW50byB0aGUgYm9keSBmb3IgdGhlIHJlZnJlc2ggdG9rZW4gcmVxdWVzdFxuICAgKiBAZGVmYXVsdCAodG9rZW4pID0+ICh7IHRva2VuIH0pXG4gICAqL1xuICByZWZyZXNoQXJnc1RyYW5zZm9ybWVyPzogKHRva2VuOiBzdHJpbmcpID0+IFJlcXVlc3RBcmdzPFRUb2tlblJlZnJlc2hBcmdzPjtcbn07XG5cbmV4cG9ydCB0eXBlIENyZWF0ZUJlYXJlckF1dGhQcm92aWRlckNvbmZpZ09wdGlvbnM8XG4gIFRMb2dpbkFyZ3MgZXh0ZW5kcyBRdWVyeUFyZ3MsXG4gIFRUb2tlbkxvZ2luQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbiAgVFRva2VuUmVmcmVzaEFyZ3MgZXh0ZW5kcyBRdWVyeUFyZ3MsXG4gIFRTZWxlY3RSb2xlQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbj4gPSB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgYXV0aCBwcm92aWRlclxuICAgKi9cbiAgbmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcXVlcnkgY2xpZW50IHJlZmVyZW5jZVxuICAgKi9cbiAgcXVlcnlDbGllbnRSZWY6IFF1ZXJ5Q2xpZW50UmVmO1xuXG4gIC8qKlxuICAgKiBUaGUgbG9naW4gcm91dGUgY29uZmlndXJhdGlvblxuICAgKi9cbiAgbG9naW4/OiBCZWFyZXJBdXRoUHJvdmlkZXJSb3V0ZUNvbmZpZzxUTG9naW5BcmdzPjtcblxuICAvKipcbiAgICogVGhlIHRva2VuIGxvZ2luIHJvdXRlIGNvbmZpZ3VyYXRpb25cbiAgICovXG4gIHRva2VuTG9naW4/OiBCZWFyZXJBdXRoUHJvdmlkZXJSb3V0ZUNvbmZpZzxUVG9rZW5Mb2dpbkFyZ3M+O1xuXG4gIC8qKlxuICAgKiBUaGUgdG9rZW4gcmVmcmVzaCByb3V0ZSBjb25maWd1cmF0aW9uXG4gICAqL1xuICB0b2tlblJlZnJlc2g/OiBCZWFyZXJBdXRoUHJvdmlkZXJSb3V0ZUNvbmZpZzxUVG9rZW5SZWZyZXNoQXJncz47XG5cbiAgLyoqXG4gICAqIFRoZSBzZWxlY3Qgcm9sZSByb3V0ZSBjb25maWd1cmF0aW9uXG4gICAqL1xuICBzZWxlY3RSb2xlPzogQmVhcmVyQXV0aFByb3ZpZGVyUm91dGVDb25maWc8VFNlbGVjdFJvbGVBcmdzPjtcblxuICAvKipcbiAgICogVGhlIGNvb2tpZSBjb25maWd1cmF0aW9uIGZvciB0aGUgYXV0aCBwcm92aWRlclxuICAgKi9cbiAgY29va2llPzogQmVhcmVyQXV0aFByb3ZpZGVyQ29va2llQ29uZmlnPFRUb2tlblJlZnJlc2hBcmdzPjtcblxuICAvKipcbiAgICogVGhlIHRpbWUgaW4gbWlsbGlzZWNvbmRzIGJlZm9yZSB0aGUgdG9rZW4gZXhwaXJlcyB3aGVuIHRoZSByZWZyZXNoIHNob3VsZCBiZSB0cmlnZ2VyZWQuXG4gICAqIEBkZWZhdWx0IDMwMDAwMCAvLyAoNSBtaW51dGVzKVxuICAgKi9cbiAgcmVmcmVzaEJ1ZmZlcj86IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGV4cGlyZXMgaW4gcHJvcGVydHkgbmFtZSBpbnNpZGUgdGhlIGp3dCBib2R5XG4gICAqIEBkZWZhdWx0ICdleHAnXG4gICAqL1xuICBleHBpcmVzSW5Qcm9wZXJ0eU5hbWU/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIERldGVybWluZXMgaWYgdGhlIHRva2VuIHNob3VsZCBiZSByZWZyZXNoZWQgaWYgKiphbnkqKiBxdWVyeSByZXR1cm5zIGEgNDAxIHJlc3BvbnNlLlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWZyZXNoT25VbmF1dGhvcml6ZWRSZXNwb25zZT86IGJvb2xlYW47XG59O1xuXG5leHBvcnQgdHlwZSBCZWFyZXJBdXRoUHJvdmlkZXJDb25maWc8XG4gIFRMb2dpbkFyZ3MgZXh0ZW5kcyBRdWVyeUFyZ3MsXG4gIFRUb2tlbkxvZ2luQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbiAgVFRva2VuUmVmcmVzaEFyZ3MgZXh0ZW5kcyBRdWVyeUFyZ3MsXG4gIFRTZWxlY3RSb2xlQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbj4gPSBDcmVhdGVCZWFyZXJBdXRoUHJvdmlkZXJDb25maWdPcHRpb25zPFRMb2dpbkFyZ3MsIFRUb2tlbkxvZ2luQXJncywgVFRva2VuUmVmcmVzaEFyZ3MsIFRTZWxlY3RSb2xlQXJncz4gJiB7XG4gIHRva2VuOiBCZWFyZXJBdXRoUHJvdmlkZXJSZWY8VExvZ2luQXJncywgVFRva2VuTG9naW5BcmdzLCBUVG9rZW5SZWZyZXNoQXJncywgVFNlbGVjdFJvbGVBcmdzPjtcbn07XG5cbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55XG5leHBvcnQgdHlwZSBBbnlCZWFyZXJBdXRoUHJvdmlkZXJDb25maWcgPSBCZWFyZXJBdXRoUHJvdmlkZXJDb25maWc8YW55LCBhbnksIGFueSwgYW55PjtcblxuZXhwb3J0IHR5cGUgQmVhcmVyQXV0aFByb3ZpZGVyUmVmPFxuICBUTG9naW5BcmdzIGV4dGVuZHMgUXVlcnlBcmdzLFxuICBUVG9rZW5Mb2dpbkFyZ3MgZXh0ZW5kcyBRdWVyeUFyZ3MsXG4gIFRUb2tlblJlZnJlc2hBcmdzIGV4dGVuZHMgUXVlcnlBcmdzLFxuICBUU2VsZWN0Um9sZUFyZ3MgZXh0ZW5kcyBRdWVyeUFyZ3MsXG4+ID0gSW5qZWN0aW9uVG9rZW48QmVhcmVyQXV0aFByb3ZpZGVyPFRMb2dpbkFyZ3MsIFRUb2tlbkxvZ2luQXJncywgVFRva2VuUmVmcmVzaEFyZ3MsIFRTZWxlY3RSb2xlQXJncz4+O1xuXG5leHBvcnQgY29uc3QgY3JlYXRlQmVhcmVyQXV0aFByb3ZpZGVyQ29uZmlnID0gPFxuICBUTG9naW5BcmdzIGV4dGVuZHMgUXVlcnlBcmdzLFxuICBUVG9rZW5Mb2dpbkFyZ3MgZXh0ZW5kcyBRdWVyeUFyZ3MsXG4gIFRUb2tlblJlZnJlc2hBcmdzIGV4dGVuZHMgUXVlcnlBcmdzLFxuICBUU2VsZWN0Um9sZUFyZ3MgZXh0ZW5kcyBRdWVyeUFyZ3MsXG4+KFxuICBvcHRpb25zOiBDcmVhdGVCZWFyZXJBdXRoUHJvdmlkZXJDb25maWdPcHRpb25zPFRMb2dpbkFyZ3MsIFRUb2tlbkxvZ2luQXJncywgVFRva2VuUmVmcmVzaEFyZ3MsIFRTZWxlY3RSb2xlQXJncz4sXG4pID0+IHtcbiAgY29uc3QgdG9rZW4gPSBuZXcgSW5qZWN0aW9uVG9rZW48XG4gICAgQmVhcmVyQXV0aFByb3ZpZGVyQ29uZmlnPFRMb2dpbkFyZ3MsIFRUb2tlbkxvZ2luQXJncywgVFRva2VuUmVmcmVzaEFyZ3MsIFRTZWxlY3RSb2xlQXJncz5cbiAgPihgQmVhcmVyQXV0aFByb3ZpZGVyXyR7b3B0aW9ucy5uYW1lfWApO1xuXG4gIGNvbnN0IGJlYXJlckF1dGhQcm92aWRlckNvbmZpZzogQmVhcmVyQXV0aFByb3ZpZGVyQ29uZmlnPFxuICAgIFRMb2dpbkFyZ3MsXG4gICAgVFRva2VuTG9naW5BcmdzLFxuICAgIFRUb2tlblJlZnJlc2hBcmdzLFxuICAgIFRTZWxlY3RSb2xlQXJnc1xuICA+ID0ge1xuICAgIG5hbWU6IG9wdGlvbnMubmFtZSxcbiAgICBxdWVyeUNsaWVudFJlZjogb3B0aW9ucy5xdWVyeUNsaWVudFJlZixcbiAgICB0b2tlbixcbiAgICBjb29raWU6IG9wdGlvbnMuY29va2llLFxuICAgIGV4cGlyZXNJblByb3BlcnR5TmFtZTogb3B0aW9ucy5leHBpcmVzSW5Qcm9wZXJ0eU5hbWUgPz8gJ2V4cCcsXG4gICAgcmVmcmVzaEJ1ZmZlcjogb3B0aW9ucy5yZWZyZXNoQnVmZmVyID8/IDMwMDAwMCxcbiAgICByZWZyZXNoT25VbmF1dGhvcml6ZWRSZXNwb25zZTogb3B0aW9ucy5yZWZyZXNoT25VbmF1dGhvcml6ZWRSZXNwb25zZSA/PyB0cnVlLFxuICAgIGxvZ2luOiBvcHRpb25zLmxvZ2luLFxuICAgIHNlbGVjdFJvbGU6IG9wdGlvbnMuc2VsZWN0Um9sZSxcbiAgICB0b2tlbkxvZ2luOiBvcHRpb25zLnRva2VuTG9naW4sXG4gICAgdG9rZW5SZWZyZXNoOiBvcHRpb25zLnRva2VuUmVmcmVzaCxcbiAgfTtcblxuICByZXR1cm4gYmVhcmVyQXV0aFByb3ZpZGVyQ29uZmlnO1xufTtcbiJdfQ==
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
2
|
+
import { computed, effect, isDevMode, signal, untracked } from '@angular/core';
|
|
3
|
+
import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop';
|
|
4
|
+
import { deleteCookie as coreDeleteCookie, getCookie, getDomain, isObject, setCookie } from '@ethlete/core';
|
|
5
|
+
import { of, switchMap, tap, timer } from 'rxjs';
|
|
6
|
+
import { decryptBearer } from '../auth';
|
|
7
|
+
import { bearerExpiresInPropertyNotNumber, cookieLoginTriedButCookieDisabled, defaultResponseTransformerResponseNotContainingAccessToken, defaultResponseTransformerResponseNotContainingRefreshToken, defaultResponseTransformerResponseNotObject, disableCookieCalledWithoutCookieConfig, enableCookieCalledWithoutCookieConfig, loginCalledWithoutConfig, loginWithTokenCalledWithoutConfig, refreshTokenCalledWithoutConfig, selectRoleCalledWithoutConfig, unableToDecryptBearerToken, } from './query-errors';
|
|
8
|
+
const defaultResponseTransformer = (response) => {
|
|
9
|
+
if (!isObject(response)) {
|
|
10
|
+
throw defaultResponseTransformerResponseNotObject(typeof response);
|
|
11
|
+
}
|
|
12
|
+
if (!('accessToken' in response)) {
|
|
13
|
+
throw defaultResponseTransformerResponseNotContainingAccessToken();
|
|
14
|
+
}
|
|
15
|
+
if (!('refreshToken' in response)) {
|
|
16
|
+
throw defaultResponseTransformerResponseNotContainingRefreshToken();
|
|
17
|
+
}
|
|
18
|
+
return response;
|
|
19
|
+
};
|
|
20
|
+
const FIVE_MINUTES = 5 * 60 * 1000;
|
|
21
|
+
const createAuthProviderQuery = (config, authProviderConfig) => {
|
|
22
|
+
const query = config.queryCreator();
|
|
23
|
+
const triggeredInternally = signal(false);
|
|
24
|
+
const tokens = computed(() => {
|
|
25
|
+
const res = query.response();
|
|
26
|
+
if (!res)
|
|
27
|
+
return null;
|
|
28
|
+
const transformed = config.responseTransformer?.(res) ?? defaultResponseTransformer(res);
|
|
29
|
+
const bearerValue = decryptBearer(transformed.accessToken);
|
|
30
|
+
if (!bearerValue)
|
|
31
|
+
throw unableToDecryptBearerToken(transformed.accessToken);
|
|
32
|
+
return {
|
|
33
|
+
bearer: bearerValue,
|
|
34
|
+
tokens: transformed,
|
|
35
|
+
};
|
|
36
|
+
});
|
|
37
|
+
const expiresIn = computed(() => {
|
|
38
|
+
const res = tokens();
|
|
39
|
+
if (!res)
|
|
40
|
+
return null;
|
|
41
|
+
const expiresIn = res.bearer[authProviderConfig.expiresInPropertyName ?? 'exp'];
|
|
42
|
+
const refreshBuffer = authProviderConfig.refreshBuffer ?? FIVE_MINUTES;
|
|
43
|
+
if (typeof expiresIn !== 'number') {
|
|
44
|
+
throw bearerExpiresInPropertyNotNumber(expiresIn);
|
|
45
|
+
}
|
|
46
|
+
// const dummyRemainingTime = (query.lastTimeExecutedAt() ?? 0) + 5000 - new Date().getTime();
|
|
47
|
+
const remainingTime = new Date(expiresIn * 1000).getTime() - refreshBuffer - new Date().getTime();
|
|
48
|
+
return remainingTime;
|
|
49
|
+
});
|
|
50
|
+
const execute = (newArgs, options) => {
|
|
51
|
+
query.execute(newArgs);
|
|
52
|
+
triggeredInternally.set(options?.triggeredInternally ?? false);
|
|
53
|
+
};
|
|
54
|
+
return {
|
|
55
|
+
execute,
|
|
56
|
+
query,
|
|
57
|
+
tokens,
|
|
58
|
+
expiresIn,
|
|
59
|
+
triggeredInternally: triggeredInternally.asReadonly(),
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
export const createBearerAuthProvider = (options) => {
|
|
63
|
+
const cookieEnabled = signal(options.cookie === undefined ? false : (options.cookie.enabled ?? true));
|
|
64
|
+
const cookieOptions = {
|
|
65
|
+
expiresInDays: 30,
|
|
66
|
+
name: 'etAuth',
|
|
67
|
+
path: '/',
|
|
68
|
+
sameSite: 'lax',
|
|
69
|
+
domain: getDomain() ?? 'localhost',
|
|
70
|
+
refreshArgsTransformer: (token) => ({ body: { token } }),
|
|
71
|
+
...(options.cookie ?? {}),
|
|
72
|
+
};
|
|
73
|
+
const loginQuery = options.login ? createAuthProviderQuery(options.login, options) : null;
|
|
74
|
+
const tokenLoginQuery = options.tokenLogin ? createAuthProviderQuery(options.tokenLogin, options) : null;
|
|
75
|
+
const tokenRefreshQuery = options.tokenRefresh ? createAuthProviderQuery(options.tokenRefresh, options) : null;
|
|
76
|
+
const selectRoleQuery = options.selectRole ? createAuthProviderQuery(options.selectRole, options) : null;
|
|
77
|
+
const queries = [
|
|
78
|
+
{ type: 'login', query: loginQuery },
|
|
79
|
+
{ type: 'tokenLogin', query: tokenLoginQuery },
|
|
80
|
+
{ type: 'tokenRefresh', query: tokenRefreshQuery },
|
|
81
|
+
{ type: 'selectRole', query: selectRoleQuery },
|
|
82
|
+
];
|
|
83
|
+
const latestExecutedQuery = computed(() => {
|
|
84
|
+
const relevantQueries = queries.filter((q) => q.query && q.query.query.lastTimeExecutedAt() !== null);
|
|
85
|
+
return findMostRecentQuery(relevantQueries);
|
|
86
|
+
});
|
|
87
|
+
const tokens = computed(() => {
|
|
88
|
+
const query = latestExecutedQuery();
|
|
89
|
+
return query?.query?.tokens()?.tokens ?? null;
|
|
90
|
+
});
|
|
91
|
+
toObservable(computed(() => {
|
|
92
|
+
const query = latestExecutedQuery();
|
|
93
|
+
const expiresIn = query?.query?.expiresIn() ?? null;
|
|
94
|
+
const tokens = query?.query?.tokens() ?? null;
|
|
95
|
+
return { expiresIn, tokens, query };
|
|
96
|
+
}))
|
|
97
|
+
.pipe(switchMap((res) => {
|
|
98
|
+
if (!res.tokens || res.expiresIn === null || !options.tokenRefresh)
|
|
99
|
+
return of(null);
|
|
100
|
+
const expIn = res.expiresIn;
|
|
101
|
+
const tokens = res.tokens;
|
|
102
|
+
if (!expIn || !tokens)
|
|
103
|
+
return of(null);
|
|
104
|
+
return timer(expIn).pipe(tap(() => refreshToken({
|
|
105
|
+
...cookieOptions.refreshArgsTransformer(tokens.tokens.refreshToken),
|
|
106
|
+
}, { triggeredInternally: true })));
|
|
107
|
+
}), takeUntilDestroyed())
|
|
108
|
+
.subscribe();
|
|
109
|
+
const latestNonInternalQuery = signal(null);
|
|
110
|
+
effect(() => {
|
|
111
|
+
const relevantQueries = queries.filter((q) => q.query && !q.query.triggeredInternally() && q.query.query.lastTimeExecutedAt() !== null);
|
|
112
|
+
const lastQuery = findMostRecentQuery(relevantQueries);
|
|
113
|
+
untracked(() => {
|
|
114
|
+
if (!lastQuery || !lastQuery.query?.query)
|
|
115
|
+
return;
|
|
116
|
+
latestNonInternalQuery.set({
|
|
117
|
+
type: lastQuery.type,
|
|
118
|
+
...lastQuery.query.query.createSnapshot(),
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
// Cookie writing
|
|
123
|
+
effect(() => {
|
|
124
|
+
const isCookieEnabled = cookieEnabled();
|
|
125
|
+
const res = latestExecutedQuery();
|
|
126
|
+
const error = res?.query?.query.error();
|
|
127
|
+
if (!isCookieEnabled || (error && error.status === 401)) {
|
|
128
|
+
deleteCookie();
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
if (!res?.query)
|
|
132
|
+
return;
|
|
133
|
+
const { tokens } = res.query;
|
|
134
|
+
const rt = tokens()?.tokens.refreshToken;
|
|
135
|
+
if (!rt)
|
|
136
|
+
return;
|
|
137
|
+
writeCookie(rt);
|
|
138
|
+
});
|
|
139
|
+
const login = (args) => {
|
|
140
|
+
if (!loginQuery) {
|
|
141
|
+
throw loginCalledWithoutConfig();
|
|
142
|
+
}
|
|
143
|
+
loginQuery.execute(args);
|
|
144
|
+
return loginQuery.query.createSnapshot();
|
|
145
|
+
};
|
|
146
|
+
const loginWithToken = (args) => {
|
|
147
|
+
if (!tokenLoginQuery) {
|
|
148
|
+
throw loginWithTokenCalledWithoutConfig();
|
|
149
|
+
}
|
|
150
|
+
tokenLoginQuery.execute(args);
|
|
151
|
+
return tokenLoginQuery.query.createSnapshot();
|
|
152
|
+
};
|
|
153
|
+
const refreshToken = (args, options) => {
|
|
154
|
+
if (!tokenRefreshQuery) {
|
|
155
|
+
throw refreshTokenCalledWithoutConfig();
|
|
156
|
+
}
|
|
157
|
+
tokenRefreshQuery.execute(args, { triggeredInternally: options?.triggeredInternally });
|
|
158
|
+
return tokenRefreshQuery.query.createSnapshot();
|
|
159
|
+
};
|
|
160
|
+
const selectRole = (args) => {
|
|
161
|
+
if (!selectRoleQuery) {
|
|
162
|
+
throw selectRoleCalledWithoutConfig();
|
|
163
|
+
}
|
|
164
|
+
selectRoleQuery.execute(args);
|
|
165
|
+
return selectRoleQuery.query.createSnapshot();
|
|
166
|
+
};
|
|
167
|
+
const logout = () => {
|
|
168
|
+
deleteCookie();
|
|
169
|
+
loginQuery?.query.execute.reset();
|
|
170
|
+
tokenLoginQuery?.query.execute.reset();
|
|
171
|
+
tokenRefreshQuery?.query.execute.reset();
|
|
172
|
+
selectRoleQuery?.query.execute.reset();
|
|
173
|
+
latestNonInternalQuery.set(null);
|
|
174
|
+
};
|
|
175
|
+
const enableCookie = () => {
|
|
176
|
+
if (isDevMode() && !options.cookie) {
|
|
177
|
+
throw enableCookieCalledWithoutCookieConfig();
|
|
178
|
+
}
|
|
179
|
+
cookieEnabled.set(true);
|
|
180
|
+
};
|
|
181
|
+
const disableCookie = () => {
|
|
182
|
+
if (isDevMode() && !options.cookie) {
|
|
183
|
+
throw disableCookieCalledWithoutCookieConfig();
|
|
184
|
+
}
|
|
185
|
+
cookieEnabled.set(false);
|
|
186
|
+
deleteCookie();
|
|
187
|
+
};
|
|
188
|
+
const tryLoginWithCookie = () => {
|
|
189
|
+
const isCookieEnabled = cookieEnabled();
|
|
190
|
+
if (!isCookieEnabled) {
|
|
191
|
+
if (isDevMode()) {
|
|
192
|
+
throw cookieLoginTriedButCookieDisabled();
|
|
193
|
+
}
|
|
194
|
+
return false;
|
|
195
|
+
}
|
|
196
|
+
const cookie = getCookie(cookieOptions.name);
|
|
197
|
+
if (!cookie) {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
200
|
+
refreshToken(cookieOptions.refreshArgsTransformer(cookie));
|
|
201
|
+
return true;
|
|
202
|
+
};
|
|
203
|
+
const writeCookie = (refreshToken) => {
|
|
204
|
+
const { name, expiresInDays, domain, path, sameSite } = cookieOptions;
|
|
205
|
+
setCookie(name, refreshToken, expiresInDays, domain, path, sameSite);
|
|
206
|
+
};
|
|
207
|
+
const deleteCookie = () => {
|
|
208
|
+
const { name, path, domain } = cookieOptions;
|
|
209
|
+
coreDeleteCookie(name, path, domain);
|
|
210
|
+
};
|
|
211
|
+
const findMostRecentQuery = (queriesToSearch) => {
|
|
212
|
+
return queriesToSearch.reduce((acc, curr) => {
|
|
213
|
+
if (!acc)
|
|
214
|
+
return curr;
|
|
215
|
+
const accExp = acc.query?.query.lastTimeExecutedAt() ?? null;
|
|
216
|
+
const currExp = curr.query?.query.lastTimeExecutedAt() ?? null;
|
|
217
|
+
if (currExp === null || accExp === null)
|
|
218
|
+
return acc;
|
|
219
|
+
return accExp > currExp ? acc : curr;
|
|
220
|
+
}, null);
|
|
221
|
+
};
|
|
222
|
+
const bearerAuthProvider = {
|
|
223
|
+
login,
|
|
224
|
+
loginWithToken,
|
|
225
|
+
refreshToken,
|
|
226
|
+
selectRole,
|
|
227
|
+
logout,
|
|
228
|
+
enableCookie,
|
|
229
|
+
disableCookie,
|
|
230
|
+
tryLoginWithCookie,
|
|
231
|
+
latestExecutedQuery: latestNonInternalQuery.asReadonly(),
|
|
232
|
+
tokens,
|
|
233
|
+
};
|
|
234
|
+
if (cookieEnabled()) {
|
|
235
|
+
tryLoginWithCookie();
|
|
236
|
+
}
|
|
237
|
+
return bearerAuthProvider;
|
|
238
|
+
};
|
|
239
|
+
export const provideBearerAuthProvider = (config) => {
|
|
240
|
+
return {
|
|
241
|
+
provide: config.token,
|
|
242
|
+
useFactory: () => createBearerAuthProvider(config),
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmVhcmVyLWF1dGgtcHJvdmlkZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9saWJzL3F1ZXJ5L3NyYy9saWIvZXhwZXJpbWVudGFsL2JlYXJlci1hdXRoLXByb3ZpZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLHlEQUF5RDtBQUd6RCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQVUsTUFBTSxFQUFFLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN2RixPQUFPLEVBQUUsa0JBQWtCLEVBQUUsWUFBWSxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUUsT0FBTyxFQUFFLFlBQVksSUFBSSxnQkFBZ0IsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUcsT0FBTyxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLEtBQUssRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNqRCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sU0FBUyxDQUFDO0FBUXhDLE9BQU8sRUFDTCxnQ0FBZ0MsRUFDaEMsaUNBQWlDLEVBQ2pDLDBEQUEwRCxFQUMxRCwyREFBMkQsRUFDM0QsMkNBQTJDLEVBQzNDLHNDQUFzQyxFQUN0QyxxQ0FBcUMsRUFDckMsd0JBQXdCLEVBQ3hCLGlDQUFpQyxFQUNqQywrQkFBK0IsRUFDL0IsNkJBQTZCLEVBQzdCLDBCQUEwQixHQUMzQixNQUFNLGdCQUFnQixDQUFDO0FBaUh4QixNQUFNLDBCQUEwQixHQUFHLENBQUksUUFBVyxFQUFFLEVBQUU7SUFDcEQsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsRUFBRSxDQUFDO1FBQ3hCLE1BQU0sMkNBQTJDLENBQUMsT0FBTyxRQUFRLENBQUMsQ0FBQztJQUNyRSxDQUFDO0lBRUQsSUFBSSxDQUFDLENBQUMsYUFBYSxJQUFJLFFBQVEsQ0FBQyxF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QUFjO1FBQ2QsWUFBWTtRQUNaLFVBQVU7UUFDVixNQUFNO1FBQ04sWUFBWTtRQUNaLGFBQWE7UUFDYixrQkFBa0I7UUFDbEIsbUJBQW1CLEVBQUUsc0JBQXNCLENBQUMsVUFBVSxFQUFFO1FBQ3hELE1BQU07S0FDUCxDQUFDO0lBRUYsSUFBSSxhQUFhLEVBQUUsRUFBRSxDQUFDO1FBQ3BCLGtCQUFrQixFQUFFLENBQUM7SUFDdkIsQ0FBQztJQUVELE9BQU8sa0JBQWtCLENBQUM7QUFDNUIsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQUcsQ0FNdkMsTUFBaUcsRUFDakcsRUFBRTtJQUNGLE9BQU87UUFDTCxPQUFPLEVBQUUsTUFBTSxDQUFDLEtBQUs7UUFDckIsVUFBVSxFQUFFLEdBQUcsRUFBRSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sQ0FBQztLQUNuRCxDQUFDO0FBQ0osQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgQHR5cGVzY3JpcHQtZXNsaW50L25vLWVtcHR5LWZ1bmN0aW9uICovXG5cbmltcG9ydCB7IEh0dHBFcnJvclJlc3BvbnNlIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uL2h0dHAnO1xuaW1wb3J0IHsgY29tcHV0ZWQsIGVmZmVjdCwgaXNEZXZNb2RlLCBTaWduYWwsIHNpZ25hbCwgdW50cmFja2VkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyB0YWtlVW50aWxEZXN0cm95ZWQsIHRvT2JzZXJ2YWJsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUvcnhqcy1pbnRlcm9wJztcbmltcG9ydCB7IGRlbGV0ZUNvb2tpZSBhcyBjb3JlRGVsZXRlQ29va2llLCBnZXRDb29raWUsIGdldERvbWFpbiwgaXNPYmplY3QsIHNldENvb2tpZSB9IGZyb20gJ0BldGhsZXRlL2NvcmUnO1xuaW1wb3J0IHsgb2YsIHN3aXRjaE1hcCwgdGFwLCB0aW1lciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVjcnlwdEJlYXJlciB9IGZyb20gJy4uL2F1dGgnO1xuaW1wb3J0IHtcbiAgQmVhcmVyQXV0aFByb3ZpZGVyQ29uZmlnLFxuICBCZWFyZXJBdXRoUHJvdmlkZXJDb29raWVDb25maWcsXG4gIEJlYXJlckF1dGhQcm92aWRlclJvdXRlQ29uZmlnLFxuICBCZWFyZXJBdXRoUHJvdmlkZXJUb2tlbnMsXG59IGZyb20gJy4vYmVhcmVyLWF1dGgtcHJvdmlkZXItY29uZmlnJztcbmltcG9ydCB7IFF1ZXJ5QXJncywgUXVlcnlTbmFwc2hvdCwgUmVxdWVzdEFyZ3MgfSBmcm9tICcuL3F1ZXJ5JztcbmltcG9ydCB7XG4gIGJlYXJlckV4cGlyZXNJblByb3BlcnR5Tm90TnVtYmVyLFxuICBjb29raWVMb2dpblRyaWVkQnV0Q29va2llRGlzYWJsZWQsXG4gIGRlZmF1bHRSZXNwb25zZVRyYW5zZm9ybWVyUmVzcG9uc2VOb3RDb250YWluaW5nQWNjZXNzVG9rZW4sXG4gIGRlZmF1bHRSZXNwb25zZVRyYW5zZm9ybWVyUmVzcG9uc2VOb3RDb250YWluaW5nUmVmcmVzaFRva2VuLFxuICBkZWZhdWx0UmVzcG9uc2VUcmFuc2Zvcm1lclJlc3BvbnNlTm90T2JqZWN0LFxuICBkaXNhYmxlQ29va2llQ2FsbGVkV2l0aG91dENvb2tpZUNvbmZpZyxcbiAgZW5hYmxlQ29va2llQ2FsbGVkV2l0aG91dENvb2tpZUNvbmZpZyxcbiAgbG9naW5DYWxsZWRXaXRob3V0Q29uZmlnLFxuICBsb2dpbldpdGhUb2tlbkNhbGxlZFdpdGhvdXRDb25maWcsXG4gIHJlZnJlc2hUb2tlbkNhbGxlZFdpdGhvdXRDb25maWcsXG4gIHNlbGVjdFJvbGVDYWxsZWRXaXRob3V0Q29uZmlnLFxuICB1bmFibGVUb0RlY3J5cHRCZWFyZXJUb2tlbixcbn0gZnJvbSAnLi9xdWVyeS1lcnJvcnMnO1xuXG50eXBlIEludGVybmFsUXVlcnlFeGVjdXRlT3B0aW9ucyA9IHtcbiAgdHJpZ2dlcmVkSW50ZXJuYWxseT86IGJvb2xlYW47XG59O1xuXG50eXBlIEF1dGhQcm92aWRlclF1ZXJ5V2l0aFR5cGU8XG4gIFRMb2dpbkFyZ3MgZXh0ZW5kcyBRdWVyeUFyZ3MsXG4gIFRUb2tlbkxvZ2luQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbiAgVFRva2VuUmVmcmVzaEFyZ3MgZXh0ZW5kcyBRdWVyeUFyZ3MsXG4gIFRTZWxlY3RSb2xlQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbj4gPVxuICB8IHtcbiAgICAgIHR5cGU6ICdsb2dpbic7XG4gICAgICBxdWVyeTogUmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlQXV0aFByb3ZpZGVyUXVlcnk8VExvZ2luQXJncz4+IHwgbnVsbDtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rva2VuTG9naW4nO1xuICAgICAgcXVlcnk6IFJldHVyblR5cGU8dHlwZW9mIGNyZWF0ZUF1dGhQcm92aWRlclF1ZXJ5PFRUb2tlbkxvZ2luQXJncz4+IHwgbnVsbDtcbiAgICB9XG4gIHwge1xuICAgICAgdHlwZTogJ3Rva2VuUmVmcmVzaCc7XG4gICAgICBxdWVyeTogUmV0dXJuVHlwZTx0eXBlb2YgY3JlYXRlQXV0aFByb3ZpZGVyUXVlcnk8VFRva2VuUmVmcmVzaEFyZ3M+PiB8IG51bGw7XG4gICAgfVxuICB8IHtcbiAgICAgIHR5cGU6ICdzZWxlY3RSb2xlJztcbiAgICAgIHF1ZXJ5OiBSZXR1cm5UeXBlPHR5cGVvZiBjcmVhdGVBdXRoUHJvdmlkZXJRdWVyeTxUU2VsZWN0Um9sZUFyZ3M+PiB8IG51bGw7XG4gICAgfTtcblxudHlwZSBRdWVyeVNuYXBzaG90V2l0aFR5cGU8XG4gIFRMb2dpbkFyZ3MgZXh0ZW5kcyBRdWVyeUFyZ3MsXG4gIFRUb2tlbkxvZ2luQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbiAgVFRva2VuUmVmcmVzaEFyZ3MgZXh0ZW5kcyBRdWVyeUFyZ3MsXG4gIFRTZWxlY3RSb2xlQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbj4gPVxuICB8ICh7XG4gICAgICB0eXBlOiAnbG9naW4nO1xuICAgIH0gJiBRdWVyeVNuYXBzaG90PFRMb2dpbkFyZ3M+KVxuICB8ICh7XG4gICAgICB0eXBlOiAndG9rZW5Mb2dpbic7XG4gICAgfSAmIFF1ZXJ5U25hcHNob3Q8VFRva2VuTG9naW5BcmdzPilcbiAgfCAoe1xuICAgICAgdHlwZTogJ3Rva2VuUmVmcmVzaCc7XG4gICAgfSAmIFF1ZXJ5U25hcHNob3Q8VFRva2VuUmVmcmVzaEFyZ3M+KVxuICB8ICh7XG4gICAgICB0eXBlOiAnc2VsZWN0Um9sZSc7XG4gICAgfSAmIFF1ZXJ5U25hcHNob3Q8VFNlbGVjdFJvbGVBcmdzPik7XG5cbmV4cG9ydCB0eXBlIEJlYXJlckF1dGhQcm92aWRlcjxcbiAgVExvZ2luQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbiAgVFRva2VuTG9naW5BcmdzIGV4dGVuZHMgUXVlcnlBcmdzLFxuICBUVG9rZW5SZWZyZXNoQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbiAgVFNlbGVjdFJvbGVBcmdzIGV4dGVuZHMgUXVlcnlBcmdzLFxuPiA9IHtcbiAgLyoqXG4gICAqIExvZ3MgaW4gdGhlIHVzZXIgd2l0aCB0aGUgZ2l2ZW4gYXJncy5cbiAgICovXG4gIGxvZ2luOiAoYXJnczogUmVxdWVzdEFyZ3M8VExvZ2luQXJncz4pID0+IFF1ZXJ5U25hcHNob3Q8VExvZ2luQXJncz47XG5cbiAgLyoqXG4gICAqIExvZ3MgaW4gdGhlIHVzZXIgd2l0aCB0aGUgZ2l2ZW4gdG9rZW4uXG4gICAqL1xuICBsb2dpbldpdGhUb2tlbjogKGFyZ3M6IFJlcXVlc3RBcmdzPFRUb2tlbkxvZ2luQXJncz4pID0+IFF1ZXJ5U25hcHNob3Q8VFRva2VuTG9naW5BcmdzPjtcblxuICAvKipcbiAgICogUmVmcmVzaGVzIHRoZSB0b2tlbiB3aXRoIHRoZSBnaXZlbiByZWZyZXNoIHRva2VuLlxuICAgKi9cbiAgcmVmcmVzaFRva2VuOiAoYXJnczogUmVxdWVzdEFyZ3M8VFRva2VuUmVmcmVzaEFyZ3M+KSA9PiBRdWVyeVNuYXBzaG90PFRUb2tlblJlZnJlc2hBcmdzPjtcblxuICAvKipcbiAgICogU2VsZWN0cyB0aGUgcm9sZSBmb3IgdGhlIHVzZXIuXG4gICAqL1xuICBzZWxlY3RSb2xlOiAoYXJnczogUmVxdWVzdEFyZ3M8VFNlbGVjdFJvbGVBcmdzPikgPT4gUXVlcnlTbmFwc2hvdDxUU2VsZWN0Um9sZUFyZ3M+O1xuXG4gIC8qKlxuICAgKiBMb2dzIG91dCB0aGUgdXNlciBhbmQgcmVtb3ZlcyB0aGUgY29va2llLlxuICAgKi9cbiAgbG9nb3V0OiAoKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBFbmFibGVzIGNvb2tpZSB1c2FnZSBmb3IgdGhlIGF1dGggcHJvdmlkZXIuXG4gICAqL1xuICBlbmFibGVDb29raWU6ICgpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIERpc2FibGVzIGNvb2tpZSB1c2FnZSBmb3IgdGhlIGF1dGggcHJvdmlkZXIgYW5kIHJlbW92ZXMgdGhlIGNvb2tpZS5cbiAgICovXG4gIGRpc2FibGVDb29raWU6ICgpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIFRyaWVzIHRvIGxvZ2luIHdpdGggdGhlIGdpdmVuIGNvb2tpZSBjb25maWcuXG4gICAqIFJldHVybnMgYHRydWVgIGlmIGEgY29va2llIHdhcyBmb3VuZCwgYGZhbHNlYCBvdGhlcndpc2UuXG4gICAqL1xuICB0cnlMb2dpbldpdGhDb29raWU6ICgpID0+IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIFRoZSBsYXRlc3QgZXhlY3V0ZWQgcXVlcnkgdGhhdCB3YXMgbm90IHRyaWdnZXJlZCBpbnRlcm5hbGx5LlxuICAgKi9cbiAgbGF0ZXN0RXhlY3V0ZWRRdWVyeTogU2lnbmFsPFF1ZXJ5U25hcHNob3RXaXRoVHlwZTxcbiAgICBUTG9naW5BcmdzLFxuICAgIFRUb2tlbkxvZ2luQXJncyxcbiAgICBUVG9rZW5SZWZyZXNoQXJncyxcbiAgICBUU2VsZWN0Um9sZUFyZ3NcbiAgPiB8IG51bGw+O1xuXG4gIG9uUmVmcmVzaEZhaWx1cmU/OiAoY2FsbGJhY2s6IChlcnJvcjogSHR0cEVycm9yUmVzcG9uc2UpID0+IHZvaWQpID0+IHZvaWQ7XG5cbiAgLyoqXG4gICAqIEEgc2lnbmFsIHRoYXQgY29udGFpbnMgdGhlIGN1cnJlbnQgYWNjZXNzIGFuZCByZWZyZXNoIHRva2Vucy5cbiAgICovXG4gIHRva2VuczogU2lnbmFsPEJlYXJlckF1dGhQcm92aWRlclRva2VucyB8IG51bGw+O1xufTtcblxuY29uc3QgZGVmYXVsdFJlc3BvbnNlVHJhbnNmb3JtZXIgPSA8VD4ocmVzcG9uc2U6IFQpID0+IHtcbiAgaWYgKCFpc09iamVjdChyZXNwb25zZSkpIHtcbiAgICB0aHJvdyBkZWZhdWx0UmVzcG9uc2VUcmFuc2Zvcm1lclJlc3BvbnNlTm90T2JqZWN0KHR5cGVvZiByZXNwb25zZSk7XG4gIH1cblxuICBpZiAoISgnYWNjZXNzVG9rZW4nIGluIHJlc3BvbnNlKSkge1xuICAgIHRocm93IGRlZmF1bHRSZXNwb25zZVRyYW5zZm9ybWVyUmVzcG9uc2VOb3RDb250YWluaW5nQWNjZXNzVG9rZW4oKTtcbiAgfVxuXG4gIGlmICghKCdyZWZyZXNoVG9rZW4nIGluIHJlc3BvbnNlKSkge1xuICAgIHRocm93IGRlZmF1bHRSZXNwb25zZVRyYW5zZm9ybWVyUmVzcG9uc2VOb3RDb250YWluaW5nUmVmcmVzaFRva2VuKCk7XG4gIH1cblxuICByZXR1cm4gcmVzcG9uc2UgYXMgdW5rbm93biBhcyBCZWFyZXJBdXRoUHJvdmlkZXJUb2tlbnM7XG59O1xuXG5jb25zdCBGSVZFX01JTlVURVMgPSA1ICogNjAgKiAxMDAwO1xuXG5jb25zdCBjcmVhdGVBdXRoUHJvdmlkZXJRdWVyeSA9IDxUIGV4dGVuZHMgUXVlcnlBcmdzPihcbiAgY29uZmlnOiBCZWFyZXJBdXRoUHJvdmlkZXJSb3V0ZUNvbmZpZzxUPixcbiAgYXV0aFByb3ZpZGVyQ29uZmlnOiB7XG4gICAgLyoqXG4gICAgICogVGhlIHRpbWUgaW4gbWlsbGlzZWNvbmRzIGJlZm9yZSB0aGUgdG9rZW4gZXhwaXJlcyB3aGVuIHRoZSByZWZyZXNoIHNob3VsZCBiZSB0cmlnZ2VyZWQuXG4gICAgICogQGRlZmF1bHQgMzAwMDAwIC8vICg1IG1pbnV0ZXMpXG4gICAgICovXG4gICAgcmVmcmVzaEJ1ZmZlcj86IG51bWJlcjtcblxuICAgIC8qKlxuICAgICAqIFRoZSBleHBpcmVzIGluIHByb3BlcnR5IG5hbWUgaW5zaWRlIHRoZSBqd3QgYm9keVxuICAgICAqIEBkZWZhdWx0ICdleHAnXG4gICAgICovXG4gICAgZXhwaXJlc0luUHJvcGVydHlOYW1lPzogc3RyaW5nO1xuICB9LFxuKSA9PiB7XG4gIGNvbnN0IHF1ZXJ5ID0gY29uZmlnLnF1ZXJ5Q3JlYXRvcigpO1xuXG4gIGNvbnN0IHRyaWdnZXJlZEludGVybmFsbHkgPSBzaWduYWwoZmFsc2UpO1xuXG4gIGNvbnN0IHRva2VucyA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCByZXMgPSBxdWVyeS5yZXNwb25zZSgpO1xuXG4gICAgaWYgKCFyZXMpIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgdHJhbnNmb3JtZWQgPSBjb25maWcucmVzcG9uc2VUcmFuc2Zvcm1lcj8uKHJlcykgPz8gZGVmYXVsdFJlc3BvbnNlVHJhbnNmb3JtZXIocmVzKTtcblxuICAgIGNvbnN0IGJlYXJlclZhbHVlID0gZGVjcnlwdEJlYXJlcih0cmFuc2Zvcm1lZC5hY2Nlc3NUb2tlbik7XG5cbiAgICBpZiAoIWJlYXJlclZhbHVlKSB0aHJvdyB1bmFibGVUb0RlY3J5cHRCZWFyZXJUb2tlbih0cmFuc2Zvcm1lZC5hY2Nlc3NUb2tlbik7XG5cbiAgICByZXR1cm4ge1xuICAgICAgYmVhcmVyOiBiZWFyZXJWYWx1ZSxcbiAgICAgIHRva2VuczogdHJhbnNmb3JtZWQsXG4gICAgfTtcbiAgfSk7XG5cbiAgY29uc3QgZXhwaXJlc0luID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IHJlcyA9IHRva2VucygpO1xuXG4gICAgaWYgKCFyZXMpIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgZXhwaXJlc0luID0gcmVzLmJlYXJlclthdXRoUHJvdmlkZXJDb25maWcuZXhwaXJlc0luUHJvcGVydHlOYW1lID8/ICdleHAnXTtcbiAgICBjb25zdCByZWZyZXNoQnVmZmVyID0gYXV0aFByb3ZpZGVyQ29uZmlnLnJlZnJlc2hCdWZmZXIgPz8gRklWRV9NSU5VVEVTO1xuXG4gICAgaWYgKHR5cGVvZiBleHBpcmVzSW4gIT09ICdudW1iZXInKSB7XG4gICAgICB0aHJvdyBiZWFyZXJFeHBpcmVzSW5Qcm9wZXJ0eU5vdE51bWJlcihleHBpcmVzSW4pO1xuICAgIH1cblxuICAgIC8vIGNvbnN0IGR1bW15UmVtYWluaW5nVGltZSA9IChxdWVyeS5sYXN0VGltZUV4ZWN1dGVkQXQoKSA/PyAwKSArIDUwMDAgLSBuZXcgRGF0ZSgpLmdldFRpbWUoKTtcbiAgICBjb25zdCByZW1haW5pbmdUaW1lID0gbmV3IERhdGUoZXhwaXJlc0luICogMTAwMCkuZ2V0VGltZSgpIC0gcmVmcmVzaEJ1ZmZlciAtIG5ldyBEYXRlKCkuZ2V0VGltZSgpO1xuXG4gICAgcmV0dXJuIHJlbWFpbmluZ1RpbWU7XG4gIH0pO1xuXG4gIGNvbnN0IGV4ZWN1dGUgPSAobmV3QXJnczogUmVxdWVzdEFyZ3M8VD4sIG9wdGlvbnM/OiBJbnRlcm5hbFF1ZXJ5RXhlY3V0ZU9wdGlvbnMpID0+IHtcbiAgICBxdWVyeS5leGVjdXRlKG5ld0FyZ3MpO1xuICAgIHRyaWdnZXJlZEludGVybmFsbHkuc2V0KG9wdGlvbnM/LnRyaWdnZXJlZEludGVybmFsbHkgPz8gZmFsc2UpO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgZXhlY3V0ZSxcbiAgICBxdWVyeSxcbiAgICB0b2tlbnMsXG4gICAgZXhwaXJlc0luLFxuICAgIHRyaWdnZXJlZEludGVybmFsbHk6IHRyaWdnZXJlZEludGVybmFsbHkuYXNSZWFkb25seSgpLFxuICB9O1xufTtcblxuZXhwb3J0IGNvbnN0IGNyZWF0ZUJlYXJlckF1dGhQcm92aWRlciA9IDxcbiAgVExvZ2luQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbiAgVFRva2VuTG9naW5BcmdzIGV4dGVuZHMgUXVlcnlBcmdzLFxuICBUVG9rZW5SZWZyZXNoQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbiAgVFNlbGVjdFJvbGVBcmdzIGV4dGVuZHMgUXVlcnlBcmdzLFxuPihcbiAgb3B0aW9uczogQmVhcmVyQXV0aFByb3ZpZGVyQ29uZmlnPFRMb2dpbkFyZ3MsIFRUb2tlbkxvZ2luQXJncywgVFRva2VuUmVmcmVzaEFyZ3MsIFRTZWxlY3RSb2xlQXJncz4sXG4pOiBCZWFyZXJBdXRoUHJvdmlkZXI8VExvZ2luQXJncywgVFRva2VuTG9naW5BcmdzLCBUVG9rZW5SZWZyZXNoQXJncywgVFNlbGVjdFJvbGVBcmdzPiA9PiB7XG4gIGNvbnN0IGNvb2tpZUVuYWJsZWQgPSBzaWduYWwob3B0aW9ucy5jb29raWUgPT09IHVuZGVmaW5lZCA/IGZhbHNlIDogKG9wdGlvbnMuY29va2llLmVuYWJsZWQgPz8gdHJ1ZSkpO1xuICBjb25zdCBjb29raWVPcHRpb25zOiBSZXF1aXJlZDxPbWl0PEJlYXJlckF1dGhQcm92aWRlckNvb2tpZUNvbmZpZzxUVG9rZW5SZWZyZXNoQXJncz4sICdlbmFibGVkJz4+ID0ge1xuICAgIGV4cGlyZXNJbkRheXM6IDMwLFxuICAgIG5hbWU6ICdldEF1dGgnLFxuICAgIHBhdGg6ICcvJyxcbiAgICBzYW1lU2l0ZTogJ2xheCcsXG4gICAgZG9tYWluOiBnZXREb21haW4oKSA/PyAnbG9jYWxob3N0JyxcbiAgICByZWZyZXNoQXJnc1RyYW5zZm9ybWVyOiAodG9rZW4pID0+ICh7IGJvZHk6IHsgdG9rZW4gfSB9KSBhcyBSZXF1ZXN0QXJnczxUVG9rZW5SZWZyZXNoQXJncz4sXG4gICAgLi4uKG9wdGlvbnMuY29va2llID8/IHt9KSxcbiAgfTtcblxuICBjb25zdCBsb2dpblF1ZXJ5ID0gb3B0aW9ucy5sb2dpbiA/IGNyZWF0ZUF1dGhQcm92aWRlclF1ZXJ5KG9wdGlvbnMubG9naW4sIG9wdGlvbnMpIDogbnVsbDtcbiAgY29uc3QgdG9rZW5Mb2dpblF1ZXJ5ID0gb3B0aW9ucy50b2tlbkxvZ2luID8gY3JlYXRlQXV0aFByb3ZpZGVyUXVlcnkob3B0aW9ucy50b2tlbkxvZ2luLCBvcHRpb25zKSA6IG51bGw7XG4gIGNvbnN0IHRva2VuUmVmcmVzaFF1ZXJ5ID0gb3B0aW9ucy50b2tlblJlZnJlc2ggPyBjcmVhdGVBdXRoUHJvdmlkZXJRdWVyeShvcHRpb25zLnRva2VuUmVmcmVzaCwgb3B0aW9ucykgOiBudWxsO1xuICBjb25zdCBzZWxlY3RSb2xlUXVlcnkgPSBvcHRpb25zLnNlbGVjdFJvbGUgPyBjcmVhdGVBdXRoUHJvdmlkZXJRdWVyeShvcHRpb25zLnNlbGVjdFJvbGUsIG9wdGlvbnMpIDogbnVsbDtcblxuICBjb25zdCBxdWVyaWVzOiBBdXRoUHJvdmlkZXJRdWVyeVdpdGhUeXBlPFRMb2dpbkFyZ3MsIFRUb2tlbkxvZ2luQXJncywgVFRva2VuUmVmcmVzaEFyZ3MsIFRTZWxlY3RSb2xlQXJncz5bXSA9IFtcbiAgICB7IHR5cGU6ICdsb2dpbicsIHF1ZXJ5OiBsb2dpblF1ZXJ5IH0sXG4gICAgeyB0eXBlOiAndG9rZW5Mb2dpbicsIHF1ZXJ5OiB0b2tlbkxvZ2luUXVlcnkgfSxcbiAgICB7IHR5cGU6ICd0b2tlblJlZnJlc2gnLCBxdWVyeTogdG9rZW5SZWZyZXNoUXVlcnkgfSxcbiAgICB7IHR5cGU6ICdzZWxlY3RSb2xlJywgcXVlcnk6IHNlbGVjdFJvbGVRdWVyeSB9LFxuICBdO1xuXG4gIGNvbnN0IGxhdGVzdEV4ZWN1dGVkUXVlcnkgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgcmVsZXZhbnRRdWVyaWVzID0gcXVlcmllcy5maWx0ZXIoKHEpID0+IHEucXVlcnkgJiYgcS5xdWVyeS5xdWVyeS5sYXN0VGltZUV4ZWN1dGVkQXQoKSAhPT0gbnVsbCk7XG5cbiAgICByZXR1cm4gZmluZE1vc3RSZWNlbnRRdWVyeShyZWxldmFudFF1ZXJpZXMpO1xuICB9KTtcblxuICBjb25zdCB0b2tlbnMgPSBjb21wdXRlZCgoKSA9PiB7XG4gICAgY29uc3QgcXVlcnkgPSBsYXRlc3RFeGVjdXRlZFF1ZXJ5KCk7XG5cbiAgICByZXR1cm4gcXVlcnk/LnF1ZXJ5Py50b2tlbnMoKT8udG9rZW5zID8/IG51bGw7XG4gIH0pO1xuXG4gIHRvT2JzZXJ2YWJsZShcbiAgICBjb21wdXRlZCgoKSA9PiB7XG4gICAgICBjb25zdCBxdWVyeSA9IGxhdGVzdEV4ZWN1dGVkUXVlcnkoKTtcbiAgICAgIGNvbnN0IGV4cGlyZXNJbiA9IHF1ZXJ5Py5xdWVyeT8uZXhwaXJlc0luKCkgPz8gbnVsbDtcbiAgICAgIGNvbnN0IHRva2VucyA9IHF1ZXJ5Py5xdWVyeT8udG9rZW5zKCkgPz8gbnVsbDtcblxuICAgICAgcmV0dXJuIHsgZXhwaXJlc0luLCB0b2tlbnMsIHF1ZXJ5IH07XG4gICAgfSksXG4gIClcbiAgICAucGlwZShcbiAgICAgIHN3aXRjaE1hcCgocmVzKSA9PiB7XG4gICAgICAgIGlmICghcmVzLnRva2VucyB8fCByZXMuZXhwaXJlc0luID09PSBudWxsIHx8ICFvcHRpb25zLnRva2VuUmVmcmVzaCkgcmV0dXJuIG9mKG51bGwpO1xuXG4gICAgICAgIGNvbnN0IGV4cEluID0gcmVzLmV4cGlyZXNJbjtcbiAgICAgICAgY29uc3QgdG9rZW5zID0gcmVzLnRva2VucztcblxuICAgICAgICBpZiAoIWV4cEluIHx8ICF0b2tlbnMpIHJldHVybiBvZihudWxsKTtcblxuICAgICAgICByZXR1cm4gdGltZXIoZXhwSW4pLnBpcGUoXG4gICAgICAgICAgdGFwKCgpID0+XG4gICAgICAgICAgICByZWZyZXNoVG9rZW4oXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAuLi5jb29raWVPcHRpb25zLnJlZnJlc2hBcmdzVHJhbnNmb3JtZXIodG9rZW5zLnRva2Vucy5yZWZyZXNoVG9rZW4pLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7IHRyaWdnZXJlZEludGVybmFsbHk6IHRydWUgfSxcbiAgICAgICAgICAgICksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgIH0pLFxuICAgICAgdGFrZVVudGlsRGVzdHJveWVkKCksXG4gICAgKVxuICAgIC5zdWJzY3JpYmUoKTtcblxuICBjb25zdCBsYXRlc3ROb25JbnRlcm5hbFF1ZXJ5ID0gc2lnbmFsPFF1ZXJ5U25hcHNob3RXaXRoVHlwZTxcbiAgICBUTG9naW5BcmdzLFxuICAgIFRUb2tlbkxvZ2luQXJncyxcbiAgICBUVG9rZW5SZWZyZXNoQXJncyxcbiAgICBUU2VsZWN0Um9sZUFyZ3NcbiAgPiB8IG51bGw+KG51bGwpO1xuXG4gIGVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgcmVsZXZhbnRRdWVyaWVzID0gcXVlcmllcy5maWx0ZXIoXG4gICAgICAocSkgPT4gcS5xdWVyeSAmJiAhcS5xdWVyeS50cmlnZ2VyZWRJbnRlcm5hbGx5KCkgJiYgcS5xdWVyeS5xdWVyeS5sYXN0VGltZUV4ZWN1dGVkQXQoKSAhPT0gbnVsbCxcbiAgICApO1xuXG4gICAgY29uc3QgbGFzdFF1ZXJ5ID0gZmluZE1vc3RSZWNlbnRRdWVyeShyZWxldmFudFF1ZXJpZXMpO1xuXG4gICAgdW50cmFja2VkKCgpID0+IHtcbiAgICAgIGlmICghbGFzdFF1ZXJ5IHx8ICFsYXN0UXVlcnkucXVlcnk/LnF1ZXJ5KSByZXR1cm47XG5cbiAgICAgIGxhdGVzdE5vbkludGVybmFsUXVlcnkuc2V0KHtcbiAgICAgICAgdHlwZTogbGFzdFF1ZXJ5LnR5cGUsXG4gICAgICAgIC4uLmxhc3RRdWVyeS5xdWVyeS5xdWVyeS5jcmVhdGVTbmFwc2hvdCgpLFxuICAgICAgfSBhcyBRdWVyeVNuYXBzaG90V2l0aFR5cGU8VExvZ2luQXJncywgVFRva2VuTG9naW5BcmdzLCBUVG9rZW5SZWZyZXNoQXJncywgVFNlbGVjdFJvbGVBcmdzPik7XG4gICAgfSk7XG4gIH0pO1xuXG4gIC8vIENvb2tpZSB3cml0aW5nXG4gIGVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgaXNDb29raWVFbmFibGVkID0gY29va2llRW5hYmxlZCgpO1xuICAgIGNvbnN0IHJlcyA9IGxhdGVzdEV4ZWN1dGVkUXVlcnkoKTtcbiAgICBjb25zdCBlcnJvciA9IHJlcz8ucXVlcnk/LnF1ZXJ5LmVycm9yKCk7XG5cbiAgICBpZiAoIWlzQ29va2llRW5hYmxlZCB8fCAoZXJyb3IgJiYgZXJyb3Iuc3RhdHVzID09PSA0MDEpKSB7XG4gICAgICBkZWxldGVDb29raWUoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIXJlcz8ucXVlcnkpIHJldHVybjtcblxuICAgIGNvbnN0IHsgdG9rZW5zIH0gPSByZXMucXVlcnk7XG5cbiAgICBjb25zdCBydCA9IHRva2VucygpPy50b2tlbnMucmVmcmVzaFRva2VuO1xuXG4gICAgaWYgKCFydCkgcmV0dXJuO1xuXG4gICAgd3JpdGVDb29raWUocnQpO1xuICB9KTtcblxuICBjb25zdCBsb2dpbiA9IChhcmdzOiBSZXF1ZXN0QXJnczxUTG9naW5BcmdzPikgPT4ge1xuICAgIGlmICghbG9naW5RdWVyeSkge1xuICAgICAgdGhyb3cgbG9naW5DYWxsZWRXaXRob3V0Q29uZmlnKCk7XG4gICAgfVxuXG4gICAgbG9naW5RdWVyeS5leGVjdXRlKGFyZ3MpO1xuXG4gICAgcmV0dXJuIGxvZ2luUXVlcnkucXVlcnkuY3JlYXRlU25hcHNob3QoKTtcbiAgfTtcblxuICBjb25zdCBsb2dpbldpdGhUb2tlbiA9IChhcmdzOiBSZXF1ZXN0QXJnczxUVG9rZW5Mb2dpbkFyZ3M+KSA9PiB7XG4gICAgaWYgKCF0b2tlbkxvZ2luUXVlcnkpIHtcbiAgICAgIHRocm93IGxvZ2luV2l0aFRva2VuQ2FsbGVkV2l0aG91dENvbmZpZygpO1xuICAgIH1cblxuICAgIHRva2VuTG9naW5RdWVyeS5leGVjdXRlKGFyZ3MpO1xuXG4gICAgcmV0dXJuIHRva2VuTG9naW5RdWVyeS5xdWVyeS5jcmVhdGVTbmFwc2hvdCgpO1xuICB9O1xuXG4gIGNvbnN0IHJlZnJlc2hUb2tlbiA9IChhcmdzOiBSZXF1ZXN0QXJnczxUVG9rZW5SZWZyZXNoQXJncz4sIG9wdGlvbnM/OiBJbnRlcm5hbFF1ZXJ5RXhlY3V0ZU9wdGlvbnMpID0+IHtcbiAgICBpZiAoIXRva2VuUmVmcmVzaFF1ZXJ5KSB7XG4gICAgICB0aHJvdyByZWZyZXNoVG9rZW5DYWxsZWRXaXRob3V0Q29uZmlnKCk7XG4gICAgfVxuXG4gICAgdG9rZW5SZWZyZXNoUXVlcnkuZXhlY3V0ZShhcmdzLCB7IHRyaWdnZXJlZEludGVybmFsbHk6IG9wdGlvbnM/LnRyaWdnZXJlZEludGVybmFsbHkgfSk7XG5cbiAgICByZXR1cm4gdG9rZW5SZWZyZXNoUXVlcnkucXVlcnkuY3JlYXRlU25hcHNob3QoKTtcbiAgfTtcblxuICBjb25zdCBzZWxlY3RSb2xlID0gKGFyZ3M6IFJlcXVlc3RBcmdzPFRTZWxlY3RSb2xlQXJncz4pID0+IHtcbiAgICBpZiAoIXNlbGVjdFJvbGVRdWVyeSkge1xuICAgICAgdGhyb3cgc2VsZWN0Um9sZUNhbGxlZFdpdGhvdXRDb25maWcoKTtcbiAgICB9XG5cbiAgICBzZWxlY3RSb2xlUXVlcnkuZXhlY3V0ZShhcmdzKTtcblxuICAgIHJldHVybiBzZWxlY3RSb2xlUXVlcnkucXVlcnkuY3JlYXRlU25hcHNob3QoKTtcbiAgfTtcblxuICBjb25zdCBsb2dvdXQgPSAoKSA9PiB7XG4gICAgZGVsZXRlQ29va2llKCk7XG4gICAgbG9naW5RdWVyeT8ucXVlcnkuZXhlY3V0ZS5yZXNldCgpO1xuICAgIHRva2VuTG9naW5RdWVyeT8ucXVlcnkuZXhlY3V0ZS5yZXNldCgpO1xuICAgIHRva2VuUmVmcmVzaFF1ZXJ5Py5xdWVyeS5leGVjdXRlLnJlc2V0KCk7XG4gICAgc2VsZWN0Um9sZVF1ZXJ5Py5xdWVyeS5leGVjdXRlLnJlc2V0KCk7XG4gICAgbGF0ZXN0Tm9uSW50ZXJuYWxRdWVyeS5zZXQobnVsbCk7XG4gIH07XG5cbiAgY29uc3QgZW5hYmxlQ29va2llID0gKCkgPT4ge1xuICAgIGlmIChpc0Rldk1vZGUoKSAmJiAhb3B0aW9ucy5jb29raWUpIHtcbiAgICAgIHRocm93IGVuYWJsZUNvb2tpZUNhbGxlZFdpdGhvdXRDb29raWVDb25maWcoKTtcbiAgICB9XG5cbiAgICBjb29raWVFbmFibGVkLnNldCh0cnVlKTtcbiAgfTtcblxuICBjb25zdCBkaXNhYmxlQ29va2llID0gKCkgPT4ge1xuICAgIGlmIChpc0Rldk1vZGUoKSAmJiAhb3B0aW9ucy5jb29raWUpIHtcbiAgICAgIHRocm93IGRpc2FibGVDb29raWVDYWxsZWRXaXRob3V0Q29va2llQ29uZmlnKCk7XG4gICAgfVxuXG4gICAgY29va2llRW5hYmxlZC5zZXQoZmFsc2UpO1xuICAgIGRlbGV0ZUNvb2tpZSgpO1xuICB9O1xuXG4gIGNvbnN0IHRyeUxvZ2luV2l0aENvb2tpZSA9ICgpID0+IHtcbiAgICBjb25zdCBpc0Nvb2tpZUVuYWJsZWQgPSBjb29raWVFbmFibGVkKCk7XG5cbiAgICBpZiAoIWlzQ29va2llRW5hYmxlZCkge1xuICAgICAgaWYgKGlzRGV2TW9kZSgpKSB7XG4gICAgICAgIHRocm93IGNvb2tpZUxvZ2luVHJpZWRCdXRDb29raWVEaXNhYmxlZCgpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cblxuICAgIGNvbnN0IGNvb2tpZSA9IGdldENvb2tpZShjb29raWVPcHRpb25zLm5hbWUpO1xuXG4gICAgaWYgKCFjb29raWUpIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG5cbiAgICByZWZyZXNoVG9rZW4oY29va2llT3B0aW9ucy5yZWZyZXNoQXJnc1RyYW5zZm9ybWVyKGNvb2tpZSkpO1xuXG4gICAgcmV0dXJuIHRydWU7XG4gIH07XG5cbiAgY29uc3Qgd3JpdGVDb29raWUgPSAocmVmcmVzaFRva2VuOiBzdHJpbmcpID0+IHtcbiAgICBjb25zdCB7IG5hbWUsIGV4cGlyZXNJbkRheXMsIGRvbWFpbiwgcGF0aCwgc2FtZVNpdGUgfSA9IGNvb2tpZU9wdGlvbnM7XG5cbiAgICBzZXRDb29raWUobmFtZSwgcmVmcmVzaFRva2VuLCBleHBpcmVzSW5EYXlzLCBkb21haW4sIHBhdGgsIHNhbWVTaXRlKTtcbiAgfTtcblxuICBjb25zdCBkZWxldGVDb29raWUgPSAoKSA9PiB7XG4gICAgY29uc3QgeyBuYW1lLCBwYXRoLCBkb21haW4gfSA9IGNvb2tpZU9wdGlvbnM7XG5cbiAgICBjb3JlRGVsZXRlQ29va2llKG5hbWUsIHBhdGgsIGRvbWFpbik7XG4gIH07XG5cbiAgY29uc3QgZmluZE1vc3RSZWNlbnRRdWVyeSA9IChcbiAgICBxdWVyaWVzVG9TZWFyY2g6IEF1dGhQcm92aWRlclF1ZXJ5V2l0aFR5cGU8VExvZ2luQXJncywgVFRva2VuTG9naW5BcmdzLCBUVG9rZW5SZWZyZXNoQXJncywgVFNlbGVjdFJvbGVBcmdzPltdLFxuICApID0+IHtcbiAgICByZXR1cm4gcXVlcmllc1RvU2VhcmNoLnJlZHVjZShcbiAgICAgIChhY2MsIGN1cnIpID0+IHtcbiAgICAgICAgaWYgKCFhY2MpIHJldHVybiBjdXJyO1xuXG4gICAgICAgIGNvbnN0IGFjY0V4cCA9IGFjYy5xdWVyeT8ucXVlcnkubGFzdFRpbWVFeGVjdXRlZEF0KCkgPz8gbnVsbDtcbiAgICAgICAgY29uc3QgY3VyckV4cCA9IGN1cnIucXVlcnk/LnF1ZXJ5Lmxhc3RUaW1lRXhlY3V0ZWRBdCgpID8/IG51bGw7XG5cbiAgICAgICAgaWYgKGN1cnJFeHAgPT09IG51bGwgfHwgYWNjRXhwID09PSBudWxsKSByZXR1cm4gYWNjO1xuXG4gICAgICAgIHJldHVybiBhY2NFeHAgPiBjdXJyRXhwID8gYWNjIDogY3VycjtcbiAgICAgIH0sXG4gICAgICBudWxsIGFzIEF1dGhQcm92aWRlclF1ZXJ5V2l0aFR5cGU8VExvZ2luQXJncywgVFRva2VuTG9naW5BcmdzLCBUVG9rZW5SZWZyZXNoQXJncywgVFNlbGVjdFJvbGVBcmdzPiB8IG51bGwsXG4gICAgKTtcbiAgfTtcblxuICBjb25zdCBiZWFyZXJBdXRoUHJvdmlkZXI6IEJlYXJlckF1dGhQcm92aWRlcjxUTG9naW5BcmdzLCBUVG9rZW5Mb2dpbkFyZ3MsIFRUb2tlblJlZnJlc2hBcmdzLCBUU2VsZWN0Um9sZUFyZ3M+ID0ge1xuICAgIGxvZ2luLFxuICAgIGxvZ2luV2l0aFRva2VuLFxuICAgIHJlZnJlc2hUb2tlbixcbiAgICBzZWxlY3RSb2xlLFxuICAgIGxvZ291dCxcbiAgICBlbmFibGVDb29raWUsXG4gICAgZGlzYWJsZUNvb2tpZSxcbiAgICB0cnlMb2dpbldpdGhDb29raWUsXG4gICAgbGF0ZXN0RXhlY3V0ZWRRdWVyeTogbGF0ZXN0Tm9uSW50ZXJuYWxRdWVyeS5hc1JlYWRvbmx5KCksXG4gICAgdG9rZW5zLFxuICB9O1xuXG4gIGlmIChjb29raWVFbmFibGVkKCkpIHtcbiAgICB0cnlMb2dpbldpdGhDb29raWUoKTtcbiAgfVxuXG4gIHJldHVybiBiZWFyZXJBdXRoUHJvdmlkZXI7XG59O1xuXG5leHBvcnQgY29uc3QgcHJvdmlkZUJlYXJlckF1dGhQcm92aWRlciA9IDxcbiAgVExvZ2luQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbiAgVFRva2VuTG9naW5BcmdzIGV4dGVuZHMgUXVlcnlBcmdzLFxuICBUVG9rZW5SZWZyZXNoQXJncyBleHRlbmRzIFF1ZXJ5QXJncyxcbiAgVFNlbGVjdFJvbGVBcmdzIGV4dGVuZHMgUXVlcnlBcmdzLFxuPihcbiAgY29uZmlnOiBCZWFyZXJBdXRoUHJvdmlkZXJDb25maWc8VExvZ2luQXJncywgVFRva2VuTG9naW5BcmdzLCBUVG9rZW5SZWZyZXNoQXJncywgVFNlbGVjdFJvbGVBcmdzPixcbikgPT4ge1xuICByZXR1cm4ge1xuICAgIHByb3ZpZGU6IGNvbmZpZy50b2tlbixcbiAgICB1c2VGYWN0b3J5OiAoKSA9PiBjcmVhdGVCZWFyZXJBdXRoUHJvdmlkZXIoY29uZmlnKSxcbiAgfTtcbn07XG4iXX0=
|