sliftutils 1.7.21 → 1.7.23

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/index.d.ts CHANGED
@@ -2147,6 +2147,7 @@ declare module "sliftutils/storage/IArchives" {
2147
2147
  url: string;
2148
2148
  public?: boolean;
2149
2149
  immutable?: boolean;
2150
+ allowedOrigins?: string[];
2150
2151
  };
2151
2152
  export declare const FULL_VALID_WINDOW: [number, number];
2152
2153
  export type ArchiveFileInfo = {
@@ -2988,8 +2989,9 @@ declare module "sliftutils/storage/remoteStorage/accessPage" {
2988
2989
  declare module "sliftutils/storage/remoteStorage/blobStore" {
2989
2990
  /// <reference types="node" />
2990
2991
  /// <reference types="node" />
2991
- import { ArchiveFileInfo, ArchivesSource, ArchivesSyncStatus, SyncActivity } from "../IArchives";
2992
+ import { IArchives, ArchiveFileInfo, ArchivesSource, ArchivesSyncStatus, SyncActivity } from "../IArchives";
2992
2993
  export declare const DEFAULT_FAST_WRITE_DELAY: number;
2994
+ export declare const WINDOW_END_FLUSH_MARGIN: number;
2993
2995
  export type WriteConfig = {
2994
2996
  fast?: boolean;
2995
2997
  writeDelay?: number;
@@ -3058,7 +3060,6 @@ declare module "sliftutils/storage/remoteStorage/blobStore" {
3058
3060
  constructor(folder: string, sources: ArchivesSource[], config?: {
3059
3061
  onIndexChanged?: ((key: string) => void) | undefined;
3060
3062
  readerDiskLimit?: number | undefined;
3061
- getFlushDeadline?: (() => number | undefined) | undefined;
3062
3063
  } | undefined);
3063
3064
  private stopped;
3064
3065
  private index;
@@ -3081,9 +3082,16 @@ declare module "sliftutils/storage/remoteStorage/blobStore" {
3081
3082
  private countEntry;
3082
3083
  private setIndexEntry;
3083
3084
  private deleteIndexEntry;
3084
- /** Rescans our own disk's metadata into the index - used around deploy switchovers, where the
3085
- * other process wrote files to the shared folder that our index hasn't seen. */
3085
+ /** Rescans our own disk's metadata into the index - used around valid window handoffs, where
3086
+ * another process wrote files to the shared folder that our index hasn't seen. */
3086
3087
  rescanBase(): Promise<void>;
3088
+ /** A boundary scan of the node that owned (part of) our route in the valid window before ours,
3089
+ * when that node is different storage (a disk rescan can't see its writes): just its changes
3090
+ * since the boundary neighborhood, with matching values pulled onto our own disk. */
3091
+ boundaryScanRemote(source: IArchives, config: {
3092
+ since: number;
3093
+ route?: [number, number];
3094
+ }): Promise<void>;
3087
3095
  /** The cheap always-current totals plus any in-progress background synchronization. */
3088
3096
  getSyncProgress(): {
3089
3097
  index: {
@@ -3157,7 +3165,6 @@ declare module "sliftutils/storage/remoteStorage/blobStore" {
3157
3165
  cancelLargeUpload(id: string): Promise<void>;
3158
3166
  private flushOverlay;
3159
3167
  private evicting;
3160
- private loggedFlushDeadline;
3161
3168
  private enforceDiskLimit;
3162
3169
  private cleanupTombstones;
3163
3170
  }
@@ -3281,10 +3288,10 @@ declare module "sliftutils/storage/remoteStorage/createArchives" {
3281
3288
 
3282
3289
  declare module "sliftutils/storage/remoteStorage/deployTakeover" {
3283
3290
  import { RemoteConfig } from "../IArchives";
3284
- export type TakeoverEvent = "remapChanged" | "diskScan";
3291
+ export type TakeoverEvent = "remapChanged";
3285
3292
  /** Starts the takeover machinery. Port fallback (alternate port + registry + acquisition polling)
3286
3293
  * works regardless; without a deploy timeline folder the switchover-specific parts (the remap,
3287
- * the flush deadline, the tighter acquisition pacing) simply stay inert. */
3294
+ * the tighter acquisition pacing) simply stay inert. */
3288
3295
  export declare function initDeployTakeover(config: {
3289
3296
  domain: string;
3290
3297
  mainPort: number;
@@ -3302,9 +3309,9 @@ declare module "sliftutils/storage/remoteStorage/deployTakeover" {
3302
3309
  * client learns of a takeover within one ping interval, instead of waiting for its config poll
3303
3310
  * or a write rejection. */
3304
3311
  export declare function getTakeoverStamp(): string | undefined;
3305
- /** For the dying process: fast-write flush delays must never extend past this time, and after it
3306
- * fast writes flush immediately - so nothing is left in memory when the write window transfers. */
3307
- export declare function getFlushDeadline(): number | undefined;
3312
+ /** The middle-window alternate port of an active remap. The OTHER process of the takeover lives on
3313
+ * this port on OUR machine (same disk!), so sources pointing at it are self, never sync targets. */
3314
+ export declare function getTakeoverAltPort(): number | undefined;
3308
3315
  /** How long to wait between main-port acquisition attempts: tight around the predecessor's
3309
3316
  * scheduled death (when the port actually frees), relaxed otherwise. */
3310
3317
  export declare function getMainPortAcquireDelay(): number;
@@ -3413,10 +3420,15 @@ declare module "sliftutils/storage/remoteStorage/storageController" {
3413
3420
  export declare const STORAGE_AUTH_PURPOSE = "remoteStorage-auth-1";
3414
3421
  export declare const STORAGE_NOT_AUTHENTICATED = "REMOTE_STORAGE_NOT_AUTHENTICATED_cf2f7b1e";
3415
3422
  export declare const STORAGE_ACCESS_DENIED = "REMOTE_STORAGE_ACCESS_DENIED_9d81a4c0";
3423
+ export type AuthTokenData = {
3424
+ purpose: string;
3425
+ time: number;
3426
+ server: string;
3427
+ };
3416
3428
  export type AuthToken = {
3417
3429
  certPem: string;
3418
- time: number;
3419
3430
  signature: string;
3431
+ data: AuthTokenData;
3420
3432
  };
3421
3433
  export type AccessRequest = {
3422
3434
  requestId: string;
@@ -3565,7 +3577,6 @@ declare module "sliftutils/storage/remoteStorage/storageServerState" {
3565
3577
  }): Promise<void>;
3566
3578
  export declare function getBucketConfig(bucket: LoadedBucket): ArchivesConfig;
3567
3579
  export declare function rebuildAllLoadedBuckets(): Promise<void>;
3568
- export declare function rescanAllLoadedBucketDisks(): Promise<void>;
3569
3580
  export type ServerBucketInfo = {
3570
3581
  bucketName: string;
3571
3582
  active: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sliftutils",
3
- "version": "1.7.21",
3
+ "version": "1.7.23",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -44,6 +44,7 @@ export type BackblazeConfig = CommonConfig & {
44
44
  url: string;
45
45
  public?: boolean;
46
46
  immutable?: boolean;
47
+ allowedOrigins?: string[];
47
48
  };
48
49
  export declare const FULL_VALID_WINDOW: [number, number];
49
50
  export type ArchiveFileInfo = {
@@ -81,6 +81,10 @@ export type BackblazeConfig = CommonConfig & {
81
81
  // NOTE: This isn't enforced on the backblaze level, so this is just a client-side guarantee. This can change how we cache files.
82
82
  // - Backblaze does support immutability. However, apparently, once we enable it on a bucket, we can't disable it, which is really bad, as it means if our code could ever enable it and we accidentally enable it on an important bucket, we essentially just bricked that bucket. So we should never write any code that ever tries to use backblaze to make things immutable.
83
83
  immutable?: boolean;
84
+ // CORS origins allowed to consume the bucket's files in a browser. Not a security boundary
85
+ // (access is gated by the API key / signed URLs, neither of which rides in cookies) - it only
86
+ // controls which sites' in-page JavaScript can read responses. Defaults to any HTTPS origin.
87
+ allowedOrigins?: string[];
84
88
 
85
89
  // NOTE: We will access the api key from getSecret, see backblaze.ts for the specific keys.
86
90
  };
@@ -1,4 +1,4 @@
1
- "use strict";
1
+ "use strict"; var console = (function shimConsole() { let baseConsole = globalThis.console; if (typeof window !== "undefined") return baseConsole; let name = __filename.replaceAll("\\", "/").split("/").pop(); let dirName = __dirname.replaceAll("\\", "/").split("/").pop(); let context = { __FILE__: __filename, __DIR__: __dirname, __NAME__: name, __DIRNAME__: dirName }; let newConsole = { ...baseConsole }; for (let shim of ["log", "info", "warn", "error"]) { newConsole[shim] = (...args) => { args.push(context); baseConsole[shim](...args); }; } newConsole.__context = context; return newConsole; })(); "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true , configurable: true});
3
3
  //exports.windowAcceptsWrites = exports.VARIABLE_SHARD = exports.FULL_ROUTE = exports.STORAGE_WRONG_ROUTE = exports.STORAGE_WRONG_VALID_WINDOW = exports.WRITE_PAST_WINDOW_GRACE = exports.FULL_VALID_WINDOW = exports.assertValidLastModified = exports.IMMUTABLE_CACHE_TIME = exports.MAX_LAST_MODIFIED_FUTURE = void 0;
4
4
  module.allowclient = true;
@@ -40,5 +40,5 @@ function windowAcceptsWrites(validWindow) {
40
40
  return validWindow[1] + exports.WRITE_PAST_WINDOW_GRACE > Date.now();
41
41
  }
42
42
  exports.windowAcceptsWrites = windowAcceptsWrites;
43
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSUFyY2hpdmVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiSUFyY2hpdmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLE1BQU0sQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO0FBRTFCLDZGQUE2RjtBQUM3Riw2RUFBNkU7QUFFN0UsOEZBQThGO0FBQzlGLDBEQUEwRDtBQUM3QyxRQUFBLHdCQUF3QixHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRXZELGtHQUFrRztBQUNsRyx5RkFBeUY7QUFDNUUsUUFBQSxvQkFBb0IsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDO0FBQ2pELFNBQWdCLHVCQUF1QixDQUFDLFlBQW9CO0lBQ3hELElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxnQ0FBd0IsQ0FBQztJQUNoRCxJQUFJLFlBQVksR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUNyQixNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxZQUFZLE1BQU0sR0FBRyxxQkFBcUIsQ0FBQyxDQUFDO0lBQzFHLENBQUM7QUFDTCxDQUFDO0FBTEQsMERBS0M7QUF1RVksUUFBQSxpQkFBaUIsR0FBcUIsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUEwRGhGLG1HQUFtRztBQUNuRywrRUFBK0U7QUFDbEUsUUFBQSx1QkFBdUIsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUVyRCxtR0FBbUc7QUFDbkcsaUdBQWlHO0FBQ2pHLG1HQUFtRztBQUNuRyx1RkFBdUY7QUFDMUUsUUFBQSwwQkFBMEIsR0FBRyw0Q0FBNEMsQ0FBQztBQUV2RixtR0FBbUc7QUFDbkcsNkZBQTZGO0FBQ2hGLFFBQUEsbUJBQW1CLEdBQUcscUNBQXFDLENBQUM7QUFFNUQsUUFBQSxVQUFVLEdBQXFCLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBRW5ELGdHQUFnRztBQUNoRyxpR0FBaUc7QUFDakcsOEZBQThGO0FBQ2pGLFFBQUEsY0FBYyxHQUFHLDZDQUE2QyxDQUFDO0FBQzVFLFNBQWdCLG1CQUFtQixDQUFDLFdBQXlDO0lBQ3pFLElBQUksQ0FBQyxXQUFXO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDOUIsT0FBTyxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsK0JBQXVCLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pFLENBQUM7QUFIRCxrREFHQyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5hbGxvd2NsaWVudCA9IHRydWU7XG5cbi8vIFRoZSBpbXBvcnRhbnQgb3BlcmF0aW9ucyBvZiBhbiBhcmNoaXZlIGJ1Y2tldCAoZXh0cmFjdGVkIGZyb20gQXJjaGl2ZXNCYWNrYmxhemUpLCBzbyBvdGhlclxuLy8gYmFja2VuZHMgKGUuZy4gb3VyIG93biByZW1vdGUgc3RvcmFnZSBzZXJ2ZXIpIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseS5cblxuLy8gQSB3cml0ZSBtYXkgbm90IGJlIHN0YW1wZWQgbW9yZSB0aGFuIHRoaXMgZmFyIGluIHRoZSBmdXR1cmUsIG9yIGNsb2NrIHNrZXcgYmV0d2VlbiBtYWNoaW5lc1xuLy8gd291bGQgbGV0IGEgYmFkIHRpbWVzdGFtcCBibG9jayB3cml0ZXMgZm9yIGEgbG9uZyB0aW1lLlxuZXhwb3J0IGNvbnN0IE1BWF9MQVNUX01PRElGSUVEX0ZVVFVSRSA9IDE1ICogNjAgKiAxMDAwO1xuXG4vLyBIb3cgbG9uZyBicm93c2VycyBtYXkgY2FjaGUgZmlsZXMgZnJvbSBpbW11dGFibGUgYnVja2V0cyAodGhlIENhY2hlLUNvbnRyb2wgbWF4LWFnZSksIHNoYXJlZCBieVxuLy8gZXZlcnkgaG9zdGluZyBwYXRoIChiYWNrYmxhemUgYnVja2V0IHNldHRpbmdzIGFuZCBvdXIgb3duIHN0b3JhZ2Ugc2VydmVyJ3MgSFRUUCByb3V0ZSlcbmV4cG9ydCBjb25zdCBJTU1VVEFCTEVfQ0FDSEVfVElNRSA9IDg2NDAwICogMTAwMDtcbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRWYWxpZExhc3RNb2RpZmllZChsYXN0TW9kaWZpZWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGxldCBtYXggPSBEYXRlLm5vdygpICsgTUFYX0xBU1RfTU9ESUZJRURfRlVUVVJFO1xuICAgIGlmIChsYXN0TW9kaWZpZWQgPiBtYXgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBsYXN0TW9kaWZpZWQgaXMgdG9vIGZhciBpbiB0aGUgZnV0dXJlOiAke2xhc3RNb2RpZmllZH0gPiAke21heH0gKG5vdyArIDE1IG1pbnV0ZXMpYCk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB0eXBlIFJlbW90ZUNvbmZpZyA9IHtcbiAgICAvLyBOT1RFOiBWZXJzaW9uIGlzIHVzZWQgd2hlbiB1cGRhdGluZyB0aGUgY29uZmlndXJhdGlvbi4gVGhlIG5ld2VyIHZlcnNpb24gaXMgYWx3YXlzIHRha2VuLiBBIG1pc3NpbmcgdmVyc2lvbiBjb3VudHMgYXMgdmVyc2lvbiAtMS5cbiAgICB2ZXJzaW9uPzogbnVtYmVyO1xuICAgIHNvdXJjZXM6IFJlbW90ZUNvbmZpZ0Jhc2VbXTtcbn07XG5cbi8qKlxuICAgIHN0cmluZyBhcmd1bWVudHMgd2lsbCBiZSBhIHVybCwgbG9va2luZyBsaWtlOlxuICAgICAgICBodHRwczovL3N0b3JhZ2UyLnZpZGdyaWR3ZWIuY29tOjQ0NDUvZmlsZS9leGFtcGxlYWNjb3VudC9leGFtcGxlYnVja2V0L3N0b3JhZ2Uvc3RvcmFnZXJvdXRpbmcuanNvblxuICAgICAgICBodHRwczovL2YwMDIuYmFja2JsYXplYjIuY29tL2ZpbGUvcXVlcnlzdWJ0ZXN0LWNvbS1wdWJsaWMtaW1tdXRhYmxlL3N0b3JhZ2Uvc3RvcmFnZXJvdXRpbmcuanNvblxuICAgICAgICAtIFRoZXNlIG1hcCB0byB7IHVybCB9LCB3aXRoIHRoZSB0eXBlIGluZmVycmVkIGZyb20gdGhlIHVybFxuICAgICAgICAtIEhvc3RlZCB1cmxzIGFyZSAvZmlsZS88YWNjb3VudD4vPGJ1Y2tldE5hbWU+Ly4uLiwgYmFja2JsYXplIHVybHMgYXJlIC9maWxlLzxidWNrZXROYW1lPi8uLi5cblxuICAgIE5PVEU6IElmIHdlIGRvIG5vdCBoYXZlIHJpZ2h0IGFjY2VzcyB0byB0aGVzZSwgdGhlbiBpdCBiZWNvbWVzIGEgcmVhZC1vbmx5IElBcmNoaXZlcywgd2hlcmUgd2Ugc29sZWx5IHJlYWQgdXNpbmcgdGhlIHVybCBmb3JtICh3aGljaCBtaWdodCB0aHJvdyBkdWUgdG8gbm90IGhhdmluZyBhY2Nlc3MgYXMgd2VsbCkuIFVOTEVTUyBPdXIgY29uZmlndXJhdGlvbiBleHBsaWNpdGx5IGhhcyBwdWJsaWM6IGZhbHNlLCBpbiB3aGljaCBjYXNlLCB3ZSBkb24ndCBldmVuIGhpdCB0aGUgVVJMIGFuZCB3ZSB0aHJvdyBvbiBhY2Nlc3MuXG5cbiAgICBOT1RFOiBJZiB3ZSdyZSBpbiB0aGUgYnJvd3Nlciwgd2Ugc2hvdWxkIGFsbG93IGRvd25sb2FkaW5nIHRoZSBmaWxlcyB2aWEgdGhlIFVSTCBmb3JtIChpZiBpdCdzIGEgcHVibGljIGJ1Y2tldCksIGhvd2V2ZXIsIHdlIHdvbid0IGFsbG93IHdyaXRpbmcsIGJlY2F1c2UgdGhlaXIgc2VydmVycyBkbyBub3QgYWxsb3cgc2VjdXJlIGJyb3dzZXIgd3JpdGVzLlxuKi9cbmV4cG9ydCB0eXBlIFJlbW90ZUNvbmZpZ0Jhc2UgPSBzdHJpbmcgfCBIb3N0ZWRDb25maWcgfCBCYWNrYmxhemVDb25maWc7XG5cbmV4cG9ydCB0eXBlIENvbW1vbkNvbmZpZyA9IHtcbiAgICAvKiogQnkgZGVmYXVsdCBhIHNlcnZlciBob3N0aW5nIHRoaXMgYnVja2V0IGVhZ2VybHkgY29waWVzIHRoaXMgc291cmNlJ3MgZnVsbCBjb250ZW50cyBvbnRvIGl0cyBvd24gZGlzayAob24gdG9wIG9mIHRoZSBsYXp5IHJlYWQtdGhyb3VnaCBjYWNoaW5nKS4gU2V0IHRoaXMgdG8gYmUgYSBmcm9udCBlbmQgZm9yIGEgdmVyeSBsYXJnZSBkYXRhYmFzZSB3aXRob3V0IGNvcHlpbmcgdGhlIGZ1bGwgZGF0YWJhc2UgLSByZWFkcyBzdGlsbCBkb3duLWNhY2hlIGluZGl2aWR1YWwgZmlsZXMgb24gZGVtYW5kLiAqL1xuICAgIG5vRnVsbFN5bmM/OiBib29sZWFuO1xuICAgIC8qKiBCeXRlcyBvZiByZWFkLWNhY2hlIHRoaXMgc2VydmVyJ3MgZGlzayBtYXkgaG9sZDsgbGVhc3QtcmVjZW50bHktdXNlZCBmaWxlcyBhcmUgZGVsZXRlZCBmcm9tIGRpc2sgdG8gc3RheSB1bmRlciBpdCAob25seSBldmVyIHdoZW4gYW5vdGhlciBzb3VyY2UgdmVyaWZpYWJseSBob2xkcyB0aGUgZmlsZSAtIHRoZSBvbmx5IGNvcHkgaXMgbmV2ZXIgZGVsZXRlZCkuIFJlcXVpcmVzIG5vRnVsbFN5bmMgKGEgZnVsbCBjb3B5IGNhbid0IGJlIGJvdW5kZWQpLiAqL1xuICAgIHJlYWRlckRpc2tMaW1pdD86IG51bWJlcjtcbiAgICAvKiogVGhlIHdyaXRlIHRpbWVzIChbc3RhcnRNcywgZW5kTXNdKSB0aGlzIHNvdXJjZSBpcyB2YWxpZCBmb3IgKHNlZSBBcmNoaXZlc1NvdXJjZS52YWxpZFdpbmRvdyBmb3IgdGhlIHN5bmNocm9uaXphdGlvbiBzZW1hbnRpY3MpLiBSZXF1aXJlZCBvbiBvYmplY3QgY29uZmlnczogY29uZmlndXJhdGlvbiBjaGFuZ2VzIG11c3QgYmUgU0NIRURVTEVEIChhIG5ldyBzb3VyY2UgYmVjb21lcyB2YWxpZCBhdCBhIGZ1dHVyZSB0aW1lIHdoaWxlIHRoZSBvbGQgb25lJ3Mgd2luZG93IGVuZHMpLCBub3QgZmxpcHBlZCBpbnN0YW50bHkuIFBsYWluIFVSTC1zdHJpbmcgc291cmNlcyBkZWZhdWx0IHRvIEZVTExfVkFMSURfV0lORE9XIC0gb25jZSB5b3UncmUgd3JpdGluZyBvYmplY3QgY29uZmlncywgeW91J3JlIGRvaW5nIHNvbWV0aGluZyBjb21wbGljYXRlZCBlbm91Z2ggdG8gdGhpbmsgYWJvdXQgd2hlbiB0aGluZ3MgY2hhbmdlLiAqL1xuICAgIHZhbGlkV2luZG93OiBbbnVtYmVyLCBudW1iZXJdO1xuICAgIC8qKiBTaGFyZGluZzogdGhlIGZyYWN0aW9uIG9mIHRoZSBrZXkgc3BhY2UgdGhpcyBzb3VyY2UgaGFuZGxlcywgYXMgW3N0YXJ0LCBlbmQpIG92ZXIgWzAsIDEpIChrZXlzIGFyZSByb3V0ZWQgYnkgZ2V0Um91dGUgaW4gcmVtb3RlQ29uZmlnLnRzKS4gRGVmYXVsdHMgdG8gRlVMTF9ST1VURSAodW5zaGFyZGVkKS4gQXQgZXZlcnkgcG9pbnQgaW4gdGltZSB0aGUgc291cmNlcycgcm91dGVzIG11c3QgZnVsbHkgY292ZXIgWzAsIDEpLCBvciBzb21lIGtleXMgY291bGQgbmV2ZXIgYmUgcmVhZC4gKi9cbiAgICByb3V0ZT86IFtudW1iZXIsIG51bWJlcl07XG59O1xuXG5leHBvcnQgdHlwZSBIb3N0ZWRDb25maWcgPSBDb21tb25Db25maWcgJiB7XG4gICAgdHlwZTogXCJyZW1vdGVcIjtcblxuICAgIC8vIEV4OiBodHRwczovLzk5LTI1MC0xMjQtOTEucXVlcnlzdWJ0ZXN0LmNvbTo1MjMzL2ZpbGUvcm9vdC91bmlxdWVidWNrZXRuYW1lL3N0b3JhZ2Uvc3RvcmFnZXJvdXRpbmcuanNvblxuICAgIC8vIE5PVEU6IFRoZSBhY2NvdW50IGFuZCBidWNrZXQgbmFtZSBhcmUgb2J0YWluZWQgZnJvbSB0aGUgVVJMLlxuICAgIHVybDogc3RyaW5nO1xuXG4gICAgLy8gTk9URTogQXV0aGVudGljYXRpb24gaXMgaGFuZGxlZCBieSBjZXJ0LnRzLCB2aWEgaGF2aW5nIHlvdXIgbWFjaGluZSB0cnVzdGVkIHRvIGFjY2VzcyB0aGlzIGFjY291bnQuIFxuICAgIGFjY291bnROYW1lPzogc3RyaW5nO1xuXG4gICAgcHVibGljPzogYm9vbGVhbjtcbiAgICAvLyBGYXN0IG1vZGU6IHRoZSBzZXJ2ZXIgYWNrbm93bGVkZ2VzIHdyaXRlcyBvbmNlIHRoZXkgYXJlIGluIG1lbW9yeSwgZmx1c2hpbmcgdG8gZGlzayBhZnRlclxuICAgIC8vIHdyaXRlRGVsYXkgKGRlZmF1bHQgNSBtaW51dGVzKSBhbmQgY29hbGVzY2luZyB3cml0ZXMgdG8gdGhlIHNhbWUgZmlsZS4gQSBzZXJ2ZXIgY3Jhc2ggbG9zZXNcbiAgICAvLyB3cml0ZXMgdGhhdCBoYXZlbid0IGZsdXNoZWQgeWV0LlxuICAgIGZhc3Q/OiBib29sZWFuO1xuICAgIHdyaXRlRGVsYXk/OiBudW1iZXI7XG4gICAgLy8gVGhlIGJ1Y2tldCBpcyBzZXJ2ZWQgc3RyYWlnaHQgZnJvbSB0aGUgc2VydmVyJ3MgZGlzaywgd2l0aCBubyBpbmRleCDigJQgc28gbm8gZmFzdCB3cml0ZXMgYW5kXG4gICAgLy8gbm8gZ2V0Q2hhbmdlc0FmdGVyL2dldFN5bmNTdGF0dXMuXG4gICAgcmF3RGlzaz86IGJvb2xlYW47XG4gICAgLy8gV3JpdGVzIHRvIHBhdGhzIHRoYXQgYWxyZWFkeSBleGlzdCBhcmUgZGlzYWxsb3dlZCAoZGVsZXRlcyBzdGlsbCB3b3JrKS5cbiAgICBpbW11dGFibGU/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IHR5cGUgQmFja2JsYXplQ29uZmlnID0gQ29tbW9uQ29uZmlnICYge1xuICAgIHR5cGU6IFwiYmFja2JsYXplXCI7XG4gICAgLy8gRXg6IGh0dHBzOi8vZjAwMi5iYWNrYmxhemViMi5jb20vZmlsZS9xdWVyeXN1YnRlc3QtY29tLXB1YmxpYy1pbW11dGFibGUvc3RvcmFnZS9zdG9yYWdlcm91dGluZy5qc29uXG4gICAgLy8gTk9URTogVGhlIGJ1Y2tldCBuYW1lIGlzIG9idGFpbmVkIGZyb20gdGhlIFVSTC5cbiAgICB1cmw6IHN0cmluZztcbiAgICAvLyBQdWJsaWMgYnVja2V0cyBhcmUgc2VydmVkIG92ZXIgcGxhaW4gSFRUUFMgR0VUcyAoZ2V0VVJMKS4gUHJpdmF0ZSBidWNrZXRzIGFyZSBBUEktYWNjZXNzIG9ubHkuXG4gICAgcHVibGljPzogYm9vbGVhbjtcbiAgICAvLyBOT1RFOiBUaGlzIGlzbid0IGVuZm9yY2VkIG9uIHRoZSBiYWNrYmxhemUgbGV2ZWwsIHNvIHRoaXMgaXMganVzdCBhIGNsaWVudC1zaWRlIGd1YXJhbnRlZS4gVGhpcyBjYW4gY2hhbmdlIGhvdyB3ZSBjYWNoZSBmaWxlcy5cbiAgICAvLyAgLSBCYWNrYmxhemUgZG9lcyBzdXBwb3J0IGltbXV0YWJpbGl0eS4gSG93ZXZlciwgYXBwYXJlbnRseSwgb25jZSB3ZSBlbmFibGUgaXQgb24gYSBidWNrZXQsIHdlIGNhbid0IGRpc2FibGUgaXQsIHdoaWNoIGlzIHJlYWxseSBiYWQsIGFzIGl0IG1lYW5zIGlmIG91ciBjb2RlIGNvdWxkIGV2ZXIgZW5hYmxlIGl0IGFuZCB3ZSBhY2NpZGVudGFsbHkgZW5hYmxlIGl0IG9uIGFuIGltcG9ydGFudCBidWNrZXQsIHdlIGVzc2VudGlhbGx5IGp1c3QgYnJpY2tlZCB0aGF0IGJ1Y2tldC4gU28gd2Ugc2hvdWxkIG5ldmVyIHdyaXRlIGFueSBjb2RlIHRoYXQgZXZlciB0cmllcyB0byB1c2UgYmFja2JsYXplIHRvIG1ha2UgdGhpbmdzIGltbXV0YWJsZS4gXG4gICAgaW1tdXRhYmxlPzogYm9vbGVhbjtcblxuICAgIC8vIE5PVEU6IFdlIHdpbGwgYWNjZXNzIHRoZSBhcGkga2V5IGZyb20gZ2V0U2VjcmV0LCBzZWUgYmFja2JsYXplLnRzIGZvciB0aGUgc3BlY2lmaWMga2V5cy5cbn07XG5cblxuZXhwb3J0IGNvbnN0IEZVTExfVkFMSURfV0lORE9XOiBbbnVtYmVyLCBudW1iZXJdID0gWzAsIE51bWJlci5NQVhfU0FGRV9JTlRFR0VSXTtcblxuXG5cblxuLy8gY3JlYXRlVGltZSBpcyBhIG1pc25vbWVyIGtlcHQgZm9yIGNvbXBhdGliaWxpdHkg4oCUIGl0IGlzIHJlYWxseSB0aGUgTEFTVC1XUklURSB0aW1lLCBzYW1lIGFzXG4vLyBnZXRJbmZvJ3Mgd3JpdGVUaW1lLiBOZWl0aGVyIEJhY2tibGF6ZSBub3Igb3VyIHJlbW90ZSBzdG9yYWdlIHRyYWNrcyBhIGRpc3RpbmN0IGNyZWF0aW9uIGRhdGU6XG4vLyBlYWNoIHdyaXRlIHN0YW1wcyBhIGZyZXNoIHRpbWVzdGFtcCBvbiB0aGUgY3VycmVudCB2ZXJzaW9uLCBzbyBib3RoIGZpZWxkcyBhcmUganVzdCBcIndoZW4gdGhlXG4vLyBieXRlcyBzZXJ2ZWQgYnkgZ2V0KCkgd2VyZSBtb3N0IHJlY2VudGx5IHdyaXR0ZW5cIi5cbmV4cG9ydCB0eXBlIEFyY2hpdmVGaWxlSW5mbyA9IHsgcGF0aDogc3RyaW5nOyBjcmVhdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9O1xuXG4vLyBBbiBpbi1wcm9ncmVzcyBiYWNrZ3JvdW5kIHN5bmNocm9uaXphdGlvbiB0YXNrIChzZWUgQXJjaGl2ZXNDb25maWcuc3luY2luZylcbmV4cG9ydCB0eXBlIFN5bmNBY3Rpdml0eSA9IHtcbiAgICAvLyBBIG1ldGFkYXRhIHNjYW4gaXMgYSBzaW5nbGUgbGlzdGluZyBjYWxsLCBzbyBpdCBoYXMgbm8gaW5jcmVtZW50YWwgcHJvZ3Jlc3MgLSBqdXN0IHRoYXQgaXQnc1xuICAgIC8vIHJ1bm5pbmcgYW5kIHNpbmNlIHdoZW4uIEEgZnVsbCBzeW5jIGtub3dzIGl0cyBleGFjdCBmaWxlL2J5dGUgcHJvZ3Jlc3MuXG4gICAgdHlwZTogXCJtZXRhZGF0YVNjYW5cIiB8IFwiZnVsbFN5bmNcIjtcbiAgICBzb3VyY2VEZWJ1Z05hbWU6IHN0cmluZztcbiAgICBzdGFydFRpbWU6IG51bWJlcjtcbiAgICBkb25lRmlsZXM/OiBudW1iZXI7XG4gICAgdG90YWxGaWxlcz86IG51bWJlcjtcbiAgICBkb25lQnl0ZXM/OiBudW1iZXI7XG4gICAgdG90YWxCeXRlcz86IG51bWJlcjtcbn07XG5cbmV4cG9ydCB0eXBlIEFyY2hpdmVzQ29uZmlnID0ge1xuICAgIC8vIFdoZXRoZXIgZ2V0Q2hhbmdlc0FmdGVyIGlzIGltcGxlbWVudGVkIChmYXN0IGNoYW5nZSBwb2xsaW5nLCBpbnN0ZWFkIG9mIGZ1bGwgcmVzY2FucylcbiAgICBzdXBwb3J0c0NoYW5nZXNBZnRlcj86IGJvb2xlYW47XG4gICAgLy8gVGhlIGJ1Y2tldCdzIGZ1bGwgcm91dGluZyBjb25maWcgKFJPVVRJTkdfRklMRSkuIEFic2VudCBmb3Igc291cmNlcyB0aGF0IGRvbid0IGhhdmUgb25lIChhXG4gICAgLy8gYmFyZSBkaXNrIHNvdXJjZSwgb3IgYSBidWNrZXQgdGhhdCBkb2Vzbid0IGV4aXN0IHlldCkuXG4gICAgcmVtb3RlQ29uZmlnPzogUmVtb3RlQ29uZmlnO1xuICAgIC8vIExpdmUgaW5kZXggdG90YWxzICh0b21ic3RvbmVzIGV4Y2x1ZGVkKSwga2VwdCB1cCB0byBkYXRlIGluIG1lbW9yeSBvbiBldmVyeSBtdXRhdGlvbiBhbmRcbiAgICAvLyByZWNvbXB1dGVkIG9uIGxvYWQgLSBzbyBhbnkgZHJpZnQgaGVhbHMgb24gcmVzdGFydFxuICAgIGluZGV4PzogeyBmaWxlQ291bnQ6IG51bWJlcjsgYnl0ZUNvdW50OiBudW1iZXIgfTtcbiAgICAvLyBUaGUgc2FtZSB0b3RhbHMgYnJva2VuIGRvd24gYnkgd2hpY2ggc291cmNlIGN1cnJlbnRseSBob2xkcyBlYWNoIGZpbGUncyBieXRlcyAodGhlIGZpcnN0XG4gICAgLy8gZW50cnkgaXMgdGhlIHNlcnZlcidzIG93biBkaXNrKVxuICAgIGluZGV4U291cmNlcz86IHsgZGVidWdOYW1lOiBzdHJpbmc7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlciB9W107XG4gICAgLy8gVGhlIHNlcnZlcidzIGNvbmZpZ3VyZWQgcmVhZGVyRGlza0xpbWl0LCB3aGVuIGl0IHJ1bnMgYXMgYSBib3VuZGVkIHJlYWQgY2FjaGVcbiAgICByZWFkZXJEaXNrTGltaXQ/OiBudW1iZXI7XG4gICAgLy8gQmFja2dyb3VuZCBzeW5jaHJvbml6YXRpb24gY3VycmVudGx5IGluIHByb2dyZXNzIChlbXB0eSB3aGVuIGlkbGUpXG4gICAgc3luY2luZz86IFN5bmNBY3Rpdml0eVtdO1xufTtcblxuLy8gQSBzeW5jaHJvbml6YXRpb24gc291cmNlIG9mIGEgQmxvYlN0b3JlICh3aGljaCBzeW5jaHJvbml6ZXMgYW4gaW5kZXggKyBsb2NhbCBjYWNoZSBmcm9tIHRoZW0pXG5leHBvcnQgdHlwZSBBcmNoaXZlc1NvdXJjZSA9IHtcbiAgICBzb3VyY2U6IElBcmNoaXZlcztcbiAgICAvLyBGcm9tIHRoZSBzb3VyY2UncyBDb21tb25Db25maWcuIFZhbHVlcyB3aXRoIHdyaXRlIHRpbWVzIG91dHNpZGUgdGhlIHdpbmRvdyBhcmUgaWdub3JlZCB3aGVuXG4gICAgLy8gc2Nhbm5pbmcsIGFuZCBvbmNlIGl0cyBlbmQgaXMgc3VmZmljaWVudGx5IHBhc3QgKHNlZSB3aW5kb3dBY2NlcHRzV3JpdGVzKSB0aGUgc291cmNlIHN0b3BzXG4gICAgLy8gcmVjZWl2aW5nIHdyaXRlcyBlbnRpcmVseSAtIHN0aWxsIHNjYW5uZWQgKGl0IGhvbGRzIHRoZSBhdXRob3JpdGF0aXZlIGRhdGEgZm9yIGl0cyB3aW5kb3cpLFxuICAgIC8vIGl0IGp1c3Qgc3RvcHMgZ3Jvd2luZy5cbiAgICB2YWxpZFdpbmRvdzogW251bWJlciwgbnVtYmVyXTtcbiAgICAvLyBGcm9tIHRoZSBzb3VyY2UncyBDb21tb25Db25maWcgKGludGVyc2VjdGVkIHdpdGggdGhlIG93bmluZyBzdG9yZSdzIG93biByb3V0ZSk6IG9ubHkga2V5c1xuICAgIC8vIHJvdXRpbmcgaW50byBbc3RhcnQsIGVuZCkgYXJlIGFjY2VwdGVkIGZyb20gdGhpcyBzb3VyY2UncyBzY2FucyBhbmQgc2VudCB0byBpdCBpblxuICAgIC8vIHdyaXRlcy9yZWNvbmNpbGlhdGlvbi4gVGhlIHJvdXRpbmcgZmlsZSBpcyBleGVtcHQgLSBjb25maWcgZmxvd3MgZXZlcnl3aGVyZS4gQWJzZW50ID0gYWxsIGtleXMuXG4gICAgcm91dGU/OiBbbnVtYmVyLCBudW1iZXJdO1xuICAgIC8vIEZyb20gdGhlIHNvdXJjZSdzIENvbW1vbkNvbmZpZzsgc2VlIHRoZXJlLlxuICAgIG5vRnVsbFN5bmM/OiBib29sZWFuO1xufTtcblxuLy8gVGhlIGdyYWNlIGNvdmVycyBjbG9jayB1bmNlcnRhaW50eSBhcm91bmQgdGhlIHdpbmRvdyBlZGdlOiBhIHdyaXRlIHNsaWdodGx5IHBhc3QgdGhlIGVuZCBkb2Vzbid0XG4vLyBodXJ0LCBidXQgb25jZSBjbGVhcmx5IHBhc3QsIHRoZSBzb3VyY2UgaXMgYW4gYXJjaGl2ZSBhbmQgbXVzdCBzdG9wIGdyb3dpbmcuXG5leHBvcnQgY29uc3QgV1JJVEVfUEFTVF9XSU5ET1dfR1JBQ0UgPSA1ICogNjAgKiAxMDAwO1xuXG4vLyBFcnJvciBtYXJrZXIgYSBzZXJ2ZXIgaW5jbHVkZXMgd2hlbiBhIGZyZXNobHktc3RhbXBlZCB3cml0ZSByZWFjaGVzIGl0IG91dHNpZGUgaXRzIHZhbGlkIHdpbmRvd3Ncbi8vICh0aGUgY2xpZW50IHJlc29sdmVkIGl0cyB0YXJnZXQsIHRoZW4gdGltZSBjcm9zc2VkIGEgd2luZG93IGJvdW5kYXJ5IGJlZm9yZSB0aGUgd3JpdGUgbGFuZGVkKS5cbi8vIENsaWVudHMgZGV0ZWN0IHRoaXMgbWFya2VyIGFuZCByZS1yZXNvbHZlIHRoZSBjdXJyZW50bHktdmFsaWQgc291cmNlLCByZXRyeWluZyBPTkNFIC0gYm91bmRhcmllc1xuLy8gYXJlIGZhciBhcGFydCwgc28gaGl0dGluZyBpdCB0d2ljZSBpbiBvbmUgYXR0ZW1wdCBtZWFucyBzb21ldGhpbmcgaXMgYWN0dWFsbHkgd3JvbmcuXG5leHBvcnQgY29uc3QgU1RPUkFHRV9XUk9OR19WQUxJRF9XSU5ET1cgPSBcIlJFTU9URV9TVE9SQUdFX1dST05HX1ZBTElEX1dJTkRPV19hN2MxZjA0ZVwiO1xuXG4vLyBFcnJvciBtYXJrZXIgYSBzZXJ2ZXIgaW5jbHVkZXMgd2hlbiBhIGZyZXNobHktc3RhbXBlZCB3cml0ZSdzIGtleSByb3V0ZXMgb3V0c2lkZSB0aGUgc2hhcmRzIHRoaXNcbi8vIHNlcnZlciBoYW5kbGVzICh0aGUgY2xpZW50J3MgY29uZmlnIGRpc2FncmVlcyB3aXRoIHRoZSBzZXJ2ZXIncyAtIGNsaWVudHMgcmUtcmVzb2x2ZSBvbmNlKVxuZXhwb3J0IGNvbnN0IFNUT1JBR0VfV1JPTkdfUk9VVEUgPSBcIlJFTU9URV9TVE9SQUdFX1dST05HX1JPVVRFX2M5NGQyZTE3XCI7XG5cbmV4cG9ydCBjb25zdCBGVUxMX1JPVVRFOiBbbnVtYmVyLCBudW1iZXJdID0gWzAsIDFdO1xuXG4vLyBBIGtleSBjb250YWluaW5nIHRoaXMgc2VudGluZWwgZG9lc24ndCBoYXZlIGEgZml4ZWQgc2hhcmQ6IHNldFZhcmlhYmxlU2hhcmQgcGlja3MgdGhlIChsb3dlc3Rcbi8vIGxhdGVuY3ksIHVwKSB3cml0ZSBzaGFyZCwgYXBwZW5kcyBcIl88dmFsdWUgaW4gdGhlIHNoYXJkJ3Mgcm91dGU+XCIgZGlyZWN0bHkgYWZ0ZXIgdGhlIHNlbnRpbmVsLFxuLy8gYW5kIHJldHVybnMgdGhlIG1hdGVyaWFsaXplZCBrZXkuIGdldFJvdXRlIHRyZWF0cyB0aGF0IHN1ZmZpeCBhcyBhIGNvbXBsZXRlIHJvdXRlIG92ZXJyaWRlLlxuZXhwb3J0IGNvbnN0IFZBUklBQkxFX1NIQVJEID0gXCJWQVJJQUJMRV9TSEFSRF9mMDIzNGpmYWgwOGZneWhmZ3lzc2Rkczgzbm1wXCI7XG5leHBvcnQgZnVuY3Rpb24gd2luZG93QWNjZXB0c1dyaXRlcyh2YWxpZFdpbmRvdzogW251bWJlciwgbnVtYmVyXSB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICAgIGlmICghdmFsaWRXaW5kb3cpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiB2YWxpZFdpbmRvd1sxXSArIFdSSVRFX1BBU1RfV0lORE9XX0dSQUNFID4gRGF0ZS5ub3coKTtcbn1cblxuZXhwb3J0IHR5cGUgQXJjaGl2ZXNTeW5jU291cmNlU3RhdHVzID0ge1xuICAgIGRlYnVnTmFtZTogc3RyaW5nO1xuICAgIHZhbGlkV2luZG93OiBbbnVtYmVyLCBudW1iZXJdO1xuICAgIHJvdXRlPzogW251bWJlciwgbnVtYmVyXTtcbiAgICBub0Z1bGxTeW5jPzogYm9vbGVhbjtcbiAgICBzdXBwb3J0c0NoYW5nZXNBZnRlcjogYm9vbGVhbjtcbiAgICBpbml0aWFsU2NhbkNvbXBsZXRlOiBib29sZWFuO1xuICAgIC8vIEZpbGVzIHNlZW4gaW4gdGhpcyBzb3VyY2UncyBzY2FucyAvIGNoYW5nZSBwb2xscyBzbyBmYXJcbiAgICBzY2FubmVkQ291bnQ6IG51bWJlcjtcbn07XG5leHBvcnQgdHlwZSBBcmNoaXZlc1N5bmNTdGF0dXMgPSB7XG4gICAgYWxsU2NhbnNDb21wbGV0ZTogYm9vbGVhbjtcbiAgICAvLyBOdW1iZXIgb2YgZmlsZXMgaW4gdGhlIGluZGV4XG4gICAgaW5kZXhTaXplOiBudW1iZXI7XG4gICAgc291cmNlczogQXJjaGl2ZXNTeW5jU291cmNlU3RhdHVzW107XG59O1xuXG5leHBvcnQgaW50ZXJmYWNlIElBcmNoaXZlcyB7XG4gICAgZ2V0RGVidWdOYW1lKCk6IHN0cmluZztcbiAgICAvKiogV2hldGhlciB3cml0ZXMgd291bGQgYmUgYWNjZXB0ZWQgKGNyZWRlbnRpYWxzIGV4aXN0LCB0aGUgYWNjb3VudCB0cnVzdHMgdGhpcyBtYWNoaW5lLCBldGMpLlxuICAgICAqICBDaGVja2VkIHdpdGhvdXQgd3JpdGluZyBhbnl0aGluZy4gKi9cbiAgICBoYXNXcml0ZUFjY2VzcygpOiBQcm9taXNlPGJvb2xlYW4+O1xuICAgIGdldChmaWxlTmFtZTogc3RyaW5nLCBjb25maWc/OiB7IHJhbmdlPzogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlciB9IH0pOiBQcm9taXNlPEJ1ZmZlciB8IHVuZGVmaW5lZD47XG4gICAgZ2V0MihmaWxlTmFtZTogc3RyaW5nLCBjb25maWc/OiB7IHJhbmdlPzogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlciB9IH0pOiBQcm9taXNlPHsgZGF0YTogQnVmZmVyOyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ+O1xuICAgIC8qKlxuICAgICAqIGxhc3RNb2RpZmllZCBzdGFtcHMgdGhlIHdyaXRlIHdpdGggdGhhdCBsYXN0LXdyaXRlIHRpbWUgaW5zdGVhZCBvZiBub3cuIElmIGl0IGlzIE9MREVSIHRoYW5cbiAgICAgKiB0aGUgZmlsZSdzIGN1cnJlbnQgbGFzdC13cml0ZSB0aW1lIHRoZSB3cml0ZSBuby1vcHMgKHNvIGRlbGF5ZWQgLyBzeW5jaHJvbml6ZWQgd3JpdGVzIGNhblxuICAgICAqIG5ldmVyIGNsb2JiZXIgbmV3ZXIgZGF0YSkuIFRpbWVzIG1vcmUgdGhhbiAxNSBtaW51dGVzIGluIHRoZSBmdXR1cmUgYXJlIHJlamVjdGVkLlxuICAgICAqXG4gICAgICogUmV0dXJucyB0aGUgZnVsbCBrZXkgYWN0dWFsbHkgd3JpdHRlbiAtIGlkZW50aWNhbCB0byBmaWxlTmFtZSwgRVhDRVBUIGZvciBrZXlzIGNvbnRhaW5pbmdcbiAgICAgKiBWQVJJQUJMRV9TSEFSRCwgd2hlcmUgdGhlIHNoYXJkIHZhbHVlIGlzIG1hdGVyaWFsaXplZCBpbnRvIHRoZSBrZXkgKHBpY2tlZCBieSBzaGFyZCBsYXRlbmN5LFxuICAgICAqIHNlZSBBcmNoaXZlc0NoYWluKSBhbmQgdGhlIGNhbGxlciBuZWVkcyB0aGUgcmV0dXJuZWQga2V5IHRvIGV2ZXIgcmVhZCB0aGUgdmFsdWUgYmFjay5cbiAgICAgKi9cbiAgICBzZXQoZmlsZU5hbWU6IHN0cmluZywgZGF0YTogQnVmZmVyLCBjb25maWc/OiB7IGxhc3RNb2RpZmllZD86IG51bWJlciB9KTogUHJvbWlzZTxzdHJpbmc+O1xuICAgIGRlbChmaWxlTmFtZTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPjtcbiAgICAvKiogU3RyZWFtcyBhIGZpbGUgdG9vIGxhcmdlIHRvIGhvbGQgaW4gbWVtb3J5LiBnZXROZXh0RGF0YSByZXR1cm5zIHVuZGVmaW5lZCB3aGVuIGRvbmUuICovXG4gICAgc2V0TGFyZ2VGaWxlKGNvbmZpZzogeyBwYXRoOiBzdHJpbmc7IGdldE5leHREYXRhKCk6IFByb21pc2U8QnVmZmVyIHwgdW5kZWZpbmVkPiB9KTogUHJvbWlzZTx2b2lkPjtcbiAgICAvKiogd3JpdGVUaW1lIGlzIHRoZSBsYXN0LXdyaXRlIHRpbWUg4oCUIHNlZSBBcmNoaXZlRmlsZUluZm8uY3JlYXRlVGltZSwgd2hpY2ggaXMgdGhlIHNhbWUgdmFsdWUuICovXG4gICAgZ2V0SW5mbyhmaWxlTmFtZTogc3RyaW5nKTogUHJvbWlzZTx7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfSB8IHVuZGVmaW5lZD47XG4gICAgZmluZChwcmVmaXg6IHN0cmluZywgY29uZmlnPzogeyBzaGFsbG93PzogYm9vbGVhbjsgdHlwZTogXCJmaWxlc1wiIHwgXCJmb2xkZXJzXCIgfSk6IFByb21pc2U8c3RyaW5nW10+O1xuICAgIGZpbmRJbmZvKHByZWZpeDogc3RyaW5nLCBjb25maWc/OiB7IHNoYWxsb3c/OiBib29sZWFuOyB0eXBlOiBcImZpbGVzXCIgfCBcImZvbGRlcnNcIiB9KTogUHJvbWlzZTxBcmNoaXZlRmlsZUluZm9bXT47XG4gICAgLyoqIE9ubHkgd29ya3MgZm9yIHB1YmxpYyBidWNrZXRzIChwcml2YXRlIGJ1Y2tldHMgYXJlIEFQSS1hY2Nlc3Mgb25seSkuICovXG4gICAgZ2V0VVJMKHBhdGg6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPjtcbiAgICAvKiogVGhlIGJ1Y2tldCdzIGNvbmZpZ3VyYXRpb24sIHdoaWNoIHRlbGxzIHdoZXRoZXIgdGhlIG9wdGlvbmFsIGZ1bmN0aW9ucyBhcmUgc3VwcG9ydGVkLiAqL1xuICAgIGdldENvbmZpZygpOiBQcm9taXNlPEFyY2hpdmVzQ29uZmlnPjtcbiAgICAvKipcbiAgICAgKiBBbGwgZmlsZXMgY2hhbmdlZCBhZnRlciB0aGUgZ2l2ZW4gdGltZS4gT25seSBleGlzdHMgd2hlbiBnZXRDb25maWcoKS5zdXBwb3J0c0NoYW5nZXNBZnRlcjtcbiAgICAgKiBiYWNrZWQgYnkgYW4gaW5kZXgsIHNvIGl0IGlzIGZhc3QgKHVubGlrZSBhIGZ1bGwgZmluZEluZm8gc2NhbikuIERlbGV0aW9ucyBhcmUgbm90IHJlcG9ydGVkLlxuICAgICAqL1xuICAgIGdldENoYW5nZXNBZnRlcj8odGltZTogbnVtYmVyKTogUHJvbWlzZTxBcmNoaXZlRmlsZUluZm9bXT47XG4gICAgLyoqIFN5bmNocm9uaXphdGlvbiBpbnRyb3NwZWN0aW9uLCBmb3IgYmFja2VuZHMgdGhhdCBzeW5jaHJvbml6ZSBmcm9tIHNvdXJjZXMgKHNlZSBCbG9iU3RvcmUpLiAqL1xuICAgIGdldFN5bmNTdGF0dXM/KCk6IFByb21pc2U8QXJjaGl2ZXNTeW5jU3RhdHVzPjtcbn1cbiJdfQ==
44
- /* _JS_SOURCE_HASH = "0bc402f342369e16f7c6d63adb88361a2f38d7143c82053becbd479b0640b6f9"; */
43
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiSUFyY2hpdmVzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiSUFyY2hpdmVzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLE1BQU0sQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDO0FBRTFCLDZGQUE2RjtBQUM3Riw2RUFBNkU7QUFFN0UsOEZBQThGO0FBQzlGLDBEQUEwRDtBQUM3QyxRQUFBLHdCQUF3QixHQUFHLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRXZELGtHQUFrRztBQUNsRyx5RkFBeUY7QUFDNUUsUUFBQSxvQkFBb0IsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDO0FBQ2pELFNBQWdCLHVCQUF1QixDQUFDLFlBQW9CO0lBQ3hELElBQUksR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxnQ0FBd0IsQ0FBQztJQUNoRCxJQUFJLFlBQVksR0FBRyxHQUFHLEVBQUUsQ0FBQztRQUNyQixNQUFNLElBQUksS0FBSyxDQUFDLDBDQUEwQyxZQUFZLE1BQU0sR0FBRyxxQkFBcUIsQ0FBQyxDQUFDO0lBQzFHLENBQUM7QUFDTCxDQUFDO0FBTEQsMERBS0M7QUEyRVksUUFBQSxpQkFBaUIsR0FBcUIsQ0FBQyxDQUFDLEVBQUUsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUEwRGhGLG1HQUFtRztBQUNuRywrRUFBK0U7QUFDbEUsUUFBQSx1QkFBdUIsR0FBRyxDQUFDLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztBQUVyRCxtR0FBbUc7QUFDbkcsaUdBQWlHO0FBQ2pHLG1HQUFtRztBQUNuRyx1RkFBdUY7QUFDMUUsUUFBQSwwQkFBMEIsR0FBRyw0Q0FBNEMsQ0FBQztBQUV2RixtR0FBbUc7QUFDbkcsNkZBQTZGO0FBQ2hGLFFBQUEsbUJBQW1CLEdBQUcscUNBQXFDLENBQUM7QUFFNUQsUUFBQSxVQUFVLEdBQXFCLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBRW5ELGdHQUFnRztBQUNoRyxpR0FBaUc7QUFDakcsOEZBQThGO0FBQ2pGLFFBQUEsY0FBYyxHQUFHLDZDQUE2QyxDQUFDO0FBQzVFLFNBQWdCLG1CQUFtQixDQUFDLFdBQXlDO0lBQ3pFLElBQUksQ0FBQyxXQUFXO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDOUIsT0FBTyxXQUFXLENBQUMsQ0FBQyxDQUFDLEdBQUcsK0JBQXVCLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBQ2pFLENBQUM7QUFIRCxrREFHQyIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5hbGxvd2NsaWVudCA9IHRydWU7XG5cbi8vIFRoZSBpbXBvcnRhbnQgb3BlcmF0aW9ucyBvZiBhbiBhcmNoaXZlIGJ1Y2tldCAoZXh0cmFjdGVkIGZyb20gQXJjaGl2ZXNCYWNrYmxhemUpLCBzbyBvdGhlclxuLy8gYmFja2VuZHMgKGUuZy4gb3VyIG93biByZW1vdGUgc3RvcmFnZSBzZXJ2ZXIpIGNhbiBiZSB1c2VkIGludGVyY2hhbmdlYWJseS5cblxuLy8gQSB3cml0ZSBtYXkgbm90IGJlIHN0YW1wZWQgbW9yZSB0aGFuIHRoaXMgZmFyIGluIHRoZSBmdXR1cmUsIG9yIGNsb2NrIHNrZXcgYmV0d2VlbiBtYWNoaW5lc1xuLy8gd291bGQgbGV0IGEgYmFkIHRpbWVzdGFtcCBibG9jayB3cml0ZXMgZm9yIGEgbG9uZyB0aW1lLlxuZXhwb3J0IGNvbnN0IE1BWF9MQVNUX01PRElGSUVEX0ZVVFVSRSA9IDE1ICogNjAgKiAxMDAwO1xuXG4vLyBIb3cgbG9uZyBicm93c2VycyBtYXkgY2FjaGUgZmlsZXMgZnJvbSBpbW11dGFibGUgYnVja2V0cyAodGhlIENhY2hlLUNvbnRyb2wgbWF4LWFnZSksIHNoYXJlZCBieVxuLy8gZXZlcnkgaG9zdGluZyBwYXRoIChiYWNrYmxhemUgYnVja2V0IHNldHRpbmdzIGFuZCBvdXIgb3duIHN0b3JhZ2Ugc2VydmVyJ3MgSFRUUCByb3V0ZSlcbmV4cG9ydCBjb25zdCBJTU1VVEFCTEVfQ0FDSEVfVElNRSA9IDg2NDAwICogMTAwMDtcbmV4cG9ydCBmdW5jdGlvbiBhc3NlcnRWYWxpZExhc3RNb2RpZmllZChsYXN0TW9kaWZpZWQ6IG51bWJlcik6IHZvaWQge1xuICAgIGxldCBtYXggPSBEYXRlLm5vdygpICsgTUFYX0xBU1RfTU9ESUZJRURfRlVUVVJFO1xuICAgIGlmIChsYXN0TW9kaWZpZWQgPiBtYXgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBsYXN0TW9kaWZpZWQgaXMgdG9vIGZhciBpbiB0aGUgZnV0dXJlOiAke2xhc3RNb2RpZmllZH0gPiAke21heH0gKG5vdyArIDE1IG1pbnV0ZXMpYCk7XG4gICAgfVxufVxuXG5cbmV4cG9ydCB0eXBlIFJlbW90ZUNvbmZpZyA9IHtcbiAgICAvLyBOT1RFOiBWZXJzaW9uIGlzIHVzZWQgd2hlbiB1cGRhdGluZyB0aGUgY29uZmlndXJhdGlvbi4gVGhlIG5ld2VyIHZlcnNpb24gaXMgYWx3YXlzIHRha2VuLiBBIG1pc3NpbmcgdmVyc2lvbiBjb3VudHMgYXMgdmVyc2lvbiAtMS5cbiAgICB2ZXJzaW9uPzogbnVtYmVyO1xuICAgIHNvdXJjZXM6IFJlbW90ZUNvbmZpZ0Jhc2VbXTtcbn07XG5cbi8qKlxuICAgIHN0cmluZyBhcmd1bWVudHMgd2lsbCBiZSBhIHVybCwgbG9va2luZyBsaWtlOlxuICAgICAgICBodHRwczovL3N0b3JhZ2UyLnZpZGdyaWR3ZWIuY29tOjQ0NDUvZmlsZS9leGFtcGxlYWNjb3VudC9leGFtcGxlYnVja2V0L3N0b3JhZ2Uvc3RvcmFnZXJvdXRpbmcuanNvblxuICAgICAgICBodHRwczovL2YwMDIuYmFja2JsYXplYjIuY29tL2ZpbGUvcXVlcnlzdWJ0ZXN0LWNvbS1wdWJsaWMtaW1tdXRhYmxlL3N0b3JhZ2Uvc3RvcmFnZXJvdXRpbmcuanNvblxuICAgICAgICAtIFRoZXNlIG1hcCB0byB7IHVybCB9LCB3aXRoIHRoZSB0eXBlIGluZmVycmVkIGZyb20gdGhlIHVybFxuICAgICAgICAtIEhvc3RlZCB1cmxzIGFyZSAvZmlsZS88YWNjb3VudD4vPGJ1Y2tldE5hbWU+Ly4uLiwgYmFja2JsYXplIHVybHMgYXJlIC9maWxlLzxidWNrZXROYW1lPi8uLi5cblxuICAgIE5PVEU6IElmIHdlIGRvIG5vdCBoYXZlIHJpZ2h0IGFjY2VzcyB0byB0aGVzZSwgdGhlbiBpdCBiZWNvbWVzIGEgcmVhZC1vbmx5IElBcmNoaXZlcywgd2hlcmUgd2Ugc29sZWx5IHJlYWQgdXNpbmcgdGhlIHVybCBmb3JtICh3aGljaCBtaWdodCB0aHJvdyBkdWUgdG8gbm90IGhhdmluZyBhY2Nlc3MgYXMgd2VsbCkuIFVOTEVTUyBPdXIgY29uZmlndXJhdGlvbiBleHBsaWNpdGx5IGhhcyBwdWJsaWM6IGZhbHNlLCBpbiB3aGljaCBjYXNlLCB3ZSBkb24ndCBldmVuIGhpdCB0aGUgVVJMIGFuZCB3ZSB0aHJvdyBvbiBhY2Nlc3MuXG5cbiAgICBOT1RFOiBJZiB3ZSdyZSBpbiB0aGUgYnJvd3Nlciwgd2Ugc2hvdWxkIGFsbG93IGRvd25sb2FkaW5nIHRoZSBmaWxlcyB2aWEgdGhlIFVSTCBmb3JtIChpZiBpdCdzIGEgcHVibGljIGJ1Y2tldCksIGhvd2V2ZXIsIHdlIHdvbid0IGFsbG93IHdyaXRpbmcsIGJlY2F1c2UgdGhlaXIgc2VydmVycyBkbyBub3QgYWxsb3cgc2VjdXJlIGJyb3dzZXIgd3JpdGVzLlxuKi9cbmV4cG9ydCB0eXBlIFJlbW90ZUNvbmZpZ0Jhc2UgPSBzdHJpbmcgfCBIb3N0ZWRDb25maWcgfCBCYWNrYmxhemVDb25maWc7XG5cbmV4cG9ydCB0eXBlIENvbW1vbkNvbmZpZyA9IHtcbiAgICAvKiogQnkgZGVmYXVsdCBhIHNlcnZlciBob3N0aW5nIHRoaXMgYnVja2V0IGVhZ2VybHkgY29waWVzIHRoaXMgc291cmNlJ3MgZnVsbCBjb250ZW50cyBvbnRvIGl0cyBvd24gZGlzayAob24gdG9wIG9mIHRoZSBsYXp5IHJlYWQtdGhyb3VnaCBjYWNoaW5nKS4gU2V0IHRoaXMgdG8gYmUgYSBmcm9udCBlbmQgZm9yIGEgdmVyeSBsYXJnZSBkYXRhYmFzZSB3aXRob3V0IGNvcHlpbmcgdGhlIGZ1bGwgZGF0YWJhc2UgLSByZWFkcyBzdGlsbCBkb3duLWNhY2hlIGluZGl2aWR1YWwgZmlsZXMgb24gZGVtYW5kLiAqL1xuICAgIG5vRnVsbFN5bmM/OiBib29sZWFuO1xuICAgIC8qKiBCeXRlcyBvZiByZWFkLWNhY2hlIHRoaXMgc2VydmVyJ3MgZGlzayBtYXkgaG9sZDsgbGVhc3QtcmVjZW50bHktdXNlZCBmaWxlcyBhcmUgZGVsZXRlZCBmcm9tIGRpc2sgdG8gc3RheSB1bmRlciBpdCAob25seSBldmVyIHdoZW4gYW5vdGhlciBzb3VyY2UgdmVyaWZpYWJseSBob2xkcyB0aGUgZmlsZSAtIHRoZSBvbmx5IGNvcHkgaXMgbmV2ZXIgZGVsZXRlZCkuIFJlcXVpcmVzIG5vRnVsbFN5bmMgKGEgZnVsbCBjb3B5IGNhbid0IGJlIGJvdW5kZWQpLiAqL1xuICAgIHJlYWRlckRpc2tMaW1pdD86IG51bWJlcjtcbiAgICAvKiogVGhlIHdyaXRlIHRpbWVzIChbc3RhcnRNcywgZW5kTXNdKSB0aGlzIHNvdXJjZSBpcyB2YWxpZCBmb3IgKHNlZSBBcmNoaXZlc1NvdXJjZS52YWxpZFdpbmRvdyBmb3IgdGhlIHN5bmNocm9uaXphdGlvbiBzZW1hbnRpY3MpLiBSZXF1aXJlZCBvbiBvYmplY3QgY29uZmlnczogY29uZmlndXJhdGlvbiBjaGFuZ2VzIG11c3QgYmUgU0NIRURVTEVEIChhIG5ldyBzb3VyY2UgYmVjb21lcyB2YWxpZCBhdCBhIGZ1dHVyZSB0aW1lIHdoaWxlIHRoZSBvbGQgb25lJ3Mgd2luZG93IGVuZHMpLCBub3QgZmxpcHBlZCBpbnN0YW50bHkuIFBsYWluIFVSTC1zdHJpbmcgc291cmNlcyBkZWZhdWx0IHRvIEZVTExfVkFMSURfV0lORE9XIC0gb25jZSB5b3UncmUgd3JpdGluZyBvYmplY3QgY29uZmlncywgeW91J3JlIGRvaW5nIHNvbWV0aGluZyBjb21wbGljYXRlZCBlbm91Z2ggdG8gdGhpbmsgYWJvdXQgd2hlbiB0aGluZ3MgY2hhbmdlLiAqL1xuICAgIHZhbGlkV2luZG93OiBbbnVtYmVyLCBudW1iZXJdO1xuICAgIC8qKiBTaGFyZGluZzogdGhlIGZyYWN0aW9uIG9mIHRoZSBrZXkgc3BhY2UgdGhpcyBzb3VyY2UgaGFuZGxlcywgYXMgW3N0YXJ0LCBlbmQpIG92ZXIgWzAsIDEpIChrZXlzIGFyZSByb3V0ZWQgYnkgZ2V0Um91dGUgaW4gcmVtb3RlQ29uZmlnLnRzKS4gRGVmYXVsdHMgdG8gRlVMTF9ST1VURSAodW5zaGFyZGVkKS4gQXQgZXZlcnkgcG9pbnQgaW4gdGltZSB0aGUgc291cmNlcycgcm91dGVzIG11c3QgZnVsbHkgY292ZXIgWzAsIDEpLCBvciBzb21lIGtleXMgY291bGQgbmV2ZXIgYmUgcmVhZC4gKi9cbiAgICByb3V0ZT86IFtudW1iZXIsIG51bWJlcl07XG59O1xuXG5leHBvcnQgdHlwZSBIb3N0ZWRDb25maWcgPSBDb21tb25Db25maWcgJiB7XG4gICAgdHlwZTogXCJyZW1vdGVcIjtcblxuICAgIC8vIEV4OiBodHRwczovLzk5LTI1MC0xMjQtOTEucXVlcnlzdWJ0ZXN0LmNvbTo1MjMzL2ZpbGUvcm9vdC91bmlxdWVidWNrZXRuYW1lL3N0b3JhZ2Uvc3RvcmFnZXJvdXRpbmcuanNvblxuICAgIC8vIE5PVEU6IFRoZSBhY2NvdW50IGFuZCBidWNrZXQgbmFtZSBhcmUgb2J0YWluZWQgZnJvbSB0aGUgVVJMLlxuICAgIHVybDogc3RyaW5nO1xuXG4gICAgLy8gTk9URTogQXV0aGVudGljYXRpb24gaXMgaGFuZGxlZCBieSBjZXJ0LnRzLCB2aWEgaGF2aW5nIHlvdXIgbWFjaGluZSB0cnVzdGVkIHRvIGFjY2VzcyB0aGlzIGFjY291bnQuIFxuICAgIGFjY291bnROYW1lPzogc3RyaW5nO1xuXG4gICAgcHVibGljPzogYm9vbGVhbjtcbiAgICAvLyBGYXN0IG1vZGU6IHRoZSBzZXJ2ZXIgYWNrbm93bGVkZ2VzIHdyaXRlcyBvbmNlIHRoZXkgYXJlIGluIG1lbW9yeSwgZmx1c2hpbmcgdG8gZGlzayBhZnRlclxuICAgIC8vIHdyaXRlRGVsYXkgKGRlZmF1bHQgNSBtaW51dGVzKSBhbmQgY29hbGVzY2luZyB3cml0ZXMgdG8gdGhlIHNhbWUgZmlsZS4gQSBzZXJ2ZXIgY3Jhc2ggbG9zZXNcbiAgICAvLyB3cml0ZXMgdGhhdCBoYXZlbid0IGZsdXNoZWQgeWV0LlxuICAgIGZhc3Q/OiBib29sZWFuO1xuICAgIHdyaXRlRGVsYXk/OiBudW1iZXI7XG4gICAgLy8gVGhlIGJ1Y2tldCBpcyBzZXJ2ZWQgc3RyYWlnaHQgZnJvbSB0aGUgc2VydmVyJ3MgZGlzaywgd2l0aCBubyBpbmRleCDigJQgc28gbm8gZmFzdCB3cml0ZXMgYW5kXG4gICAgLy8gbm8gZ2V0Q2hhbmdlc0FmdGVyL2dldFN5bmNTdGF0dXMuXG4gICAgcmF3RGlzaz86IGJvb2xlYW47XG4gICAgLy8gV3JpdGVzIHRvIHBhdGhzIHRoYXQgYWxyZWFkeSBleGlzdCBhcmUgZGlzYWxsb3dlZCAoZGVsZXRlcyBzdGlsbCB3b3JrKS5cbiAgICBpbW11dGFibGU/OiBib29sZWFuO1xufTtcblxuZXhwb3J0IHR5cGUgQmFja2JsYXplQ29uZmlnID0gQ29tbW9uQ29uZmlnICYge1xuICAgIHR5cGU6IFwiYmFja2JsYXplXCI7XG4gICAgLy8gRXg6IGh0dHBzOi8vZjAwMi5iYWNrYmxhemViMi5jb20vZmlsZS9xdWVyeXN1YnRlc3QtY29tLXB1YmxpYy1pbW11dGFibGUvc3RvcmFnZS9zdG9yYWdlcm91dGluZy5qc29uXG4gICAgLy8gTk9URTogVGhlIGJ1Y2tldCBuYW1lIGlzIG9idGFpbmVkIGZyb20gdGhlIFVSTC5cbiAgICB1cmw6IHN0cmluZztcbiAgICAvLyBQdWJsaWMgYnVja2V0cyBhcmUgc2VydmVkIG92ZXIgcGxhaW4gSFRUUFMgR0VUcyAoZ2V0VVJMKS4gUHJpdmF0ZSBidWNrZXRzIGFyZSBBUEktYWNjZXNzIG9ubHkuXG4gICAgcHVibGljPzogYm9vbGVhbjtcbiAgICAvLyBOT1RFOiBUaGlzIGlzbid0IGVuZm9yY2VkIG9uIHRoZSBiYWNrYmxhemUgbGV2ZWwsIHNvIHRoaXMgaXMganVzdCBhIGNsaWVudC1zaWRlIGd1YXJhbnRlZS4gVGhpcyBjYW4gY2hhbmdlIGhvdyB3ZSBjYWNoZSBmaWxlcy5cbiAgICAvLyAgLSBCYWNrYmxhemUgZG9lcyBzdXBwb3J0IGltbXV0YWJpbGl0eS4gSG93ZXZlciwgYXBwYXJlbnRseSwgb25jZSB3ZSBlbmFibGUgaXQgb24gYSBidWNrZXQsIHdlIGNhbid0IGRpc2FibGUgaXQsIHdoaWNoIGlzIHJlYWxseSBiYWQsIGFzIGl0IG1lYW5zIGlmIG91ciBjb2RlIGNvdWxkIGV2ZXIgZW5hYmxlIGl0IGFuZCB3ZSBhY2NpZGVudGFsbHkgZW5hYmxlIGl0IG9uIGFuIGltcG9ydGFudCBidWNrZXQsIHdlIGVzc2VudGlhbGx5IGp1c3QgYnJpY2tlZCB0aGF0IGJ1Y2tldC4gU28gd2Ugc2hvdWxkIG5ldmVyIHdyaXRlIGFueSBjb2RlIHRoYXQgZXZlciB0cmllcyB0byB1c2UgYmFja2JsYXplIHRvIG1ha2UgdGhpbmdzIGltbXV0YWJsZS4gXG4gICAgaW1tdXRhYmxlPzogYm9vbGVhbjtcbiAgICAvLyBDT1JTIG9yaWdpbnMgYWxsb3dlZCB0byBjb25zdW1lIHRoZSBidWNrZXQncyBmaWxlcyBpbiBhIGJyb3dzZXIuIE5vdCBhIHNlY3VyaXR5IGJvdW5kYXJ5XG4gICAgLy8gKGFjY2VzcyBpcyBnYXRlZCBieSB0aGUgQVBJIGtleSAvIHNpZ25lZCBVUkxzLCBuZWl0aGVyIG9mIHdoaWNoIHJpZGVzIGluIGNvb2tpZXMpIC0gaXQgb25seVxuICAgIC8vIGNvbnRyb2xzIHdoaWNoIHNpdGVzJyBpbi1wYWdlIEphdmFTY3JpcHQgY2FuIHJlYWQgcmVzcG9uc2VzLiBEZWZhdWx0cyB0byBhbnkgSFRUUFMgb3JpZ2luLlxuICAgIGFsbG93ZWRPcmlnaW5zPzogc3RyaW5nW107XG5cbiAgICAvLyBOT1RFOiBXZSB3aWxsIGFjY2VzcyB0aGUgYXBpIGtleSBmcm9tIGdldFNlY3JldCwgc2VlIGJhY2tibGF6ZS50cyBmb3IgdGhlIHNwZWNpZmljIGtleXMuXG59O1xuXG5cbmV4cG9ydCBjb25zdCBGVUxMX1ZBTElEX1dJTkRPVzogW251bWJlciwgbnVtYmVyXSA9IFswLCBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUl07XG5cblxuXG5cbi8vIGNyZWF0ZVRpbWUgaXMgYSBtaXNub21lciBrZXB0IGZvciBjb21wYXRpYmlsaXR5IOKAlCBpdCBpcyByZWFsbHkgdGhlIExBU1QtV1JJVEUgdGltZSwgc2FtZSBhc1xuLy8gZ2V0SW5mbydzIHdyaXRlVGltZS4gTmVpdGhlciBCYWNrYmxhemUgbm9yIG91ciByZW1vdGUgc3RvcmFnZSB0cmFja3MgYSBkaXN0aW5jdCBjcmVhdGlvbiBkYXRlOlxuLy8gZWFjaCB3cml0ZSBzdGFtcHMgYSBmcmVzaCB0aW1lc3RhbXAgb24gdGhlIGN1cnJlbnQgdmVyc2lvbiwgc28gYm90aCBmaWVsZHMgYXJlIGp1c3QgXCJ3aGVuIHRoZVxuLy8gYnl0ZXMgc2VydmVkIGJ5IGdldCgpIHdlcmUgbW9zdCByZWNlbnRseSB3cml0dGVuXCIuXG5leHBvcnQgdHlwZSBBcmNoaXZlRmlsZUluZm8gPSB7IHBhdGg6IHN0cmluZzsgY3JlYXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfTtcblxuLy8gQW4gaW4tcHJvZ3Jlc3MgYmFja2dyb3VuZCBzeW5jaHJvbml6YXRpb24gdGFzayAoc2VlIEFyY2hpdmVzQ29uZmlnLnN5bmNpbmcpXG5leHBvcnQgdHlwZSBTeW5jQWN0aXZpdHkgPSB7XG4gICAgLy8gQSBtZXRhZGF0YSBzY2FuIGlzIGEgc2luZ2xlIGxpc3RpbmcgY2FsbCwgc28gaXQgaGFzIG5vIGluY3JlbWVudGFsIHByb2dyZXNzIC0ganVzdCB0aGF0IGl0J3NcbiAgICAvLyBydW5uaW5nIGFuZCBzaW5jZSB3aGVuLiBBIGZ1bGwgc3luYyBrbm93cyBpdHMgZXhhY3QgZmlsZS9ieXRlIHByb2dyZXNzLlxuICAgIHR5cGU6IFwibWV0YWRhdGFTY2FuXCIgfCBcImZ1bGxTeW5jXCI7XG4gICAgc291cmNlRGVidWdOYW1lOiBzdHJpbmc7XG4gICAgc3RhcnRUaW1lOiBudW1iZXI7XG4gICAgZG9uZUZpbGVzPzogbnVtYmVyO1xuICAgIHRvdGFsRmlsZXM/OiBudW1iZXI7XG4gICAgZG9uZUJ5dGVzPzogbnVtYmVyO1xuICAgIHRvdGFsQnl0ZXM/OiBudW1iZXI7XG59O1xuXG5leHBvcnQgdHlwZSBBcmNoaXZlc0NvbmZpZyA9IHtcbiAgICAvLyBXaGV0aGVyIGdldENoYW5nZXNBZnRlciBpcyBpbXBsZW1lbnRlZCAoZmFzdCBjaGFuZ2UgcG9sbGluZywgaW5zdGVhZCBvZiBmdWxsIHJlc2NhbnMpXG4gICAgc3VwcG9ydHNDaGFuZ2VzQWZ0ZXI/OiBib29sZWFuO1xuICAgIC8vIFRoZSBidWNrZXQncyBmdWxsIHJvdXRpbmcgY29uZmlnIChST1VUSU5HX0ZJTEUpLiBBYnNlbnQgZm9yIHNvdXJjZXMgdGhhdCBkb24ndCBoYXZlIG9uZSAoYVxuICAgIC8vIGJhcmUgZGlzayBzb3VyY2UsIG9yIGEgYnVja2V0IHRoYXQgZG9lc24ndCBleGlzdCB5ZXQpLlxuICAgIHJlbW90ZUNvbmZpZz86IFJlbW90ZUNvbmZpZztcbiAgICAvLyBMaXZlIGluZGV4IHRvdGFscyAodG9tYnN0b25lcyBleGNsdWRlZCksIGtlcHQgdXAgdG8gZGF0ZSBpbiBtZW1vcnkgb24gZXZlcnkgbXV0YXRpb24gYW5kXG4gICAgLy8gcmVjb21wdXRlZCBvbiBsb2FkIC0gc28gYW55IGRyaWZ0IGhlYWxzIG9uIHJlc3RhcnRcbiAgICBpbmRleD86IHsgZmlsZUNvdW50OiBudW1iZXI7IGJ5dGVDb3VudDogbnVtYmVyIH07XG4gICAgLy8gVGhlIHNhbWUgdG90YWxzIGJyb2tlbiBkb3duIGJ5IHdoaWNoIHNvdXJjZSBjdXJyZW50bHkgaG9sZHMgZWFjaCBmaWxlJ3MgYnl0ZXMgKHRoZSBmaXJzdFxuICAgIC8vIGVudHJ5IGlzIHRoZSBzZXJ2ZXIncyBvd24gZGlzaylcbiAgICBpbmRleFNvdXJjZXM/OiB7IGRlYnVnTmFtZTogc3RyaW5nOyBmaWxlQ291bnQ6IG51bWJlcjsgYnl0ZUNvdW50OiBudW1iZXIgfVtdO1xuICAgIC8vIFRoZSBzZXJ2ZXIncyBjb25maWd1cmVkIHJlYWRlckRpc2tMaW1pdCwgd2hlbiBpdCBydW5zIGFzIGEgYm91bmRlZCByZWFkIGNhY2hlXG4gICAgcmVhZGVyRGlza0xpbWl0PzogbnVtYmVyO1xuICAgIC8vIEJhY2tncm91bmQgc3luY2hyb25pemF0aW9uIGN1cnJlbnRseSBpbiBwcm9ncmVzcyAoZW1wdHkgd2hlbiBpZGxlKVxuICAgIHN5bmNpbmc/OiBTeW5jQWN0aXZpdHlbXTtcbn07XG5cbi8vIEEgc3luY2hyb25pemF0aW9uIHNvdXJjZSBvZiBhIEJsb2JTdG9yZSAod2hpY2ggc3luY2hyb25pemVzIGFuIGluZGV4ICsgbG9jYWwgY2FjaGUgZnJvbSB0aGVtKVxuZXhwb3J0IHR5cGUgQXJjaGl2ZXNTb3VyY2UgPSB7XG4gICAgc291cmNlOiBJQXJjaGl2ZXM7XG4gICAgLy8gRnJvbSB0aGUgc291cmNlJ3MgQ29tbW9uQ29uZmlnLiBWYWx1ZXMgd2l0aCB3cml0ZSB0aW1lcyBvdXRzaWRlIHRoZSB3aW5kb3cgYXJlIGlnbm9yZWQgd2hlblxuICAgIC8vIHNjYW5uaW5nLCBhbmQgb25jZSBpdHMgZW5kIGlzIHN1ZmZpY2llbnRseSBwYXN0IChzZWUgd2luZG93QWNjZXB0c1dyaXRlcykgdGhlIHNvdXJjZSBzdG9wc1xuICAgIC8vIHJlY2VpdmluZyB3cml0ZXMgZW50aXJlbHkgLSBzdGlsbCBzY2FubmVkIChpdCBob2xkcyB0aGUgYXV0aG9yaXRhdGl2ZSBkYXRhIGZvciBpdHMgd2luZG93KSxcbiAgICAvLyBpdCBqdXN0IHN0b3BzIGdyb3dpbmcuXG4gICAgdmFsaWRXaW5kb3c6IFtudW1iZXIsIG51bWJlcl07XG4gICAgLy8gRnJvbSB0aGUgc291cmNlJ3MgQ29tbW9uQ29uZmlnIChpbnRlcnNlY3RlZCB3aXRoIHRoZSBvd25pbmcgc3RvcmUncyBvd24gcm91dGUpOiBvbmx5IGtleXNcbiAgICAvLyByb3V0aW5nIGludG8gW3N0YXJ0LCBlbmQpIGFyZSBhY2NlcHRlZCBmcm9tIHRoaXMgc291cmNlJ3Mgc2NhbnMgYW5kIHNlbnQgdG8gaXQgaW5cbiAgICAvLyB3cml0ZXMvcmVjb25jaWxpYXRpb24uIFRoZSByb3V0aW5nIGZpbGUgaXMgZXhlbXB0IC0gY29uZmlnIGZsb3dzIGV2ZXJ5d2hlcmUuIEFic2VudCA9IGFsbCBrZXlzLlxuICAgIHJvdXRlPzogW251bWJlciwgbnVtYmVyXTtcbiAgICAvLyBGcm9tIHRoZSBzb3VyY2UncyBDb21tb25Db25maWc7IHNlZSB0aGVyZS5cbiAgICBub0Z1bGxTeW5jPzogYm9vbGVhbjtcbn07XG5cbi8vIFRoZSBncmFjZSBjb3ZlcnMgY2xvY2sgdW5jZXJ0YWludHkgYXJvdW5kIHRoZSB3aW5kb3cgZWRnZTogYSB3cml0ZSBzbGlnaHRseSBwYXN0IHRoZSBlbmQgZG9lc24ndFxuLy8gaHVydCwgYnV0IG9uY2UgY2xlYXJseSBwYXN0LCB0aGUgc291cmNlIGlzIGFuIGFyY2hpdmUgYW5kIG11c3Qgc3RvcCBncm93aW5nLlxuZXhwb3J0IGNvbnN0IFdSSVRFX1BBU1RfV0lORE9XX0dSQUNFID0gNSAqIDYwICogMTAwMDtcblxuLy8gRXJyb3IgbWFya2VyIGEgc2VydmVyIGluY2x1ZGVzIHdoZW4gYSBmcmVzaGx5LXN0YW1wZWQgd3JpdGUgcmVhY2hlcyBpdCBvdXRzaWRlIGl0cyB2YWxpZCB3aW5kb3dzXG4vLyAodGhlIGNsaWVudCByZXNvbHZlZCBpdHMgdGFyZ2V0LCB0aGVuIHRpbWUgY3Jvc3NlZCBhIHdpbmRvdyBib3VuZGFyeSBiZWZvcmUgdGhlIHdyaXRlIGxhbmRlZCkuXG4vLyBDbGllbnRzIGRldGVjdCB0aGlzIG1hcmtlciBhbmQgcmUtcmVzb2x2ZSB0aGUgY3VycmVudGx5LXZhbGlkIHNvdXJjZSwgcmV0cnlpbmcgT05DRSAtIGJvdW5kYXJpZXNcbi8vIGFyZSBmYXIgYXBhcnQsIHNvIGhpdHRpbmcgaXQgdHdpY2UgaW4gb25lIGF0dGVtcHQgbWVhbnMgc29tZXRoaW5nIGlzIGFjdHVhbGx5IHdyb25nLlxuZXhwb3J0IGNvbnN0IFNUT1JBR0VfV1JPTkdfVkFMSURfV0lORE9XID0gXCJSRU1PVEVfU1RPUkFHRV9XUk9OR19WQUxJRF9XSU5ET1dfYTdjMWYwNGVcIjtcblxuLy8gRXJyb3IgbWFya2VyIGEgc2VydmVyIGluY2x1ZGVzIHdoZW4gYSBmcmVzaGx5LXN0YW1wZWQgd3JpdGUncyBrZXkgcm91dGVzIG91dHNpZGUgdGhlIHNoYXJkcyB0aGlzXG4vLyBzZXJ2ZXIgaGFuZGxlcyAodGhlIGNsaWVudCdzIGNvbmZpZyBkaXNhZ3JlZXMgd2l0aCB0aGUgc2VydmVyJ3MgLSBjbGllbnRzIHJlLXJlc29sdmUgb25jZSlcbmV4cG9ydCBjb25zdCBTVE9SQUdFX1dST05HX1JPVVRFID0gXCJSRU1PVEVfU1RPUkFHRV9XUk9OR19ST1VURV9jOTRkMmUxN1wiO1xuXG5leHBvcnQgY29uc3QgRlVMTF9ST1VURTogW251bWJlciwgbnVtYmVyXSA9IFswLCAxXTtcblxuLy8gQSBrZXkgY29udGFpbmluZyB0aGlzIHNlbnRpbmVsIGRvZXNuJ3QgaGF2ZSBhIGZpeGVkIHNoYXJkOiBzZXRWYXJpYWJsZVNoYXJkIHBpY2tzIHRoZSAobG93ZXN0XG4vLyBsYXRlbmN5LCB1cCkgd3JpdGUgc2hhcmQsIGFwcGVuZHMgXCJfPHZhbHVlIGluIHRoZSBzaGFyZCdzIHJvdXRlPlwiIGRpcmVjdGx5IGFmdGVyIHRoZSBzZW50aW5lbCxcbi8vIGFuZCByZXR1cm5zIHRoZSBtYXRlcmlhbGl6ZWQga2V5LiBnZXRSb3V0ZSB0cmVhdHMgdGhhdCBzdWZmaXggYXMgYSBjb21wbGV0ZSByb3V0ZSBvdmVycmlkZS5cbmV4cG9ydCBjb25zdCBWQVJJQUJMRV9TSEFSRCA9IFwiVkFSSUFCTEVfU0hBUkRfZjAyMzRqZmFoMDhmZ3loZmd5c3NkZHM4M25tcFwiO1xuZXhwb3J0IGZ1bmN0aW9uIHdpbmRvd0FjY2VwdHNXcml0ZXModmFsaWRXaW5kb3c6IFtudW1iZXIsIG51bWJlcl0gfCB1bmRlZmluZWQpOiBib29sZWFuIHtcbiAgICBpZiAoIXZhbGlkV2luZG93KSByZXR1cm4gdHJ1ZTtcbiAgICByZXR1cm4gdmFsaWRXaW5kb3dbMV0gKyBXUklURV9QQVNUX1dJTkRPV19HUkFDRSA+IERhdGUubm93KCk7XG59XG5cbmV4cG9ydCB0eXBlIEFyY2hpdmVzU3luY1NvdXJjZVN0YXR1cyA9IHtcbiAgICBkZWJ1Z05hbWU6IHN0cmluZztcbiAgICB2YWxpZFdpbmRvdzogW251bWJlciwgbnVtYmVyXTtcbiAgICByb3V0ZT86IFtudW1iZXIsIG51bWJlcl07XG4gICAgbm9GdWxsU3luYz86IGJvb2xlYW47XG4gICAgc3VwcG9ydHNDaGFuZ2VzQWZ0ZXI6IGJvb2xlYW47XG4gICAgaW5pdGlhbFNjYW5Db21wbGV0ZTogYm9vbGVhbjtcbiAgICAvLyBGaWxlcyBzZWVuIGluIHRoaXMgc291cmNlJ3Mgc2NhbnMgLyBjaGFuZ2UgcG9sbHMgc28gZmFyXG4gICAgc2Nhbm5lZENvdW50OiBudW1iZXI7XG59O1xuZXhwb3J0IHR5cGUgQXJjaGl2ZXNTeW5jU3RhdHVzID0ge1xuICAgIGFsbFNjYW5zQ29tcGxldGU6IGJvb2xlYW47XG4gICAgLy8gTnVtYmVyIG9mIGZpbGVzIGluIHRoZSBpbmRleFxuICAgIGluZGV4U2l6ZTogbnVtYmVyO1xuICAgIHNvdXJjZXM6IEFyY2hpdmVzU3luY1NvdXJjZVN0YXR1c1tdO1xufTtcblxuZXhwb3J0IGludGVyZmFjZSBJQXJjaGl2ZXMge1xuICAgIGdldERlYnVnTmFtZSgpOiBzdHJpbmc7XG4gICAgLyoqIFdoZXRoZXIgd3JpdGVzIHdvdWxkIGJlIGFjY2VwdGVkIChjcmVkZW50aWFscyBleGlzdCwgdGhlIGFjY291bnQgdHJ1c3RzIHRoaXMgbWFjaGluZSwgZXRjKS5cbiAgICAgKiAgQ2hlY2tlZCB3aXRob3V0IHdyaXRpbmcgYW55dGhpbmcuICovXG4gICAgaGFzV3JpdGVBY2Nlc3MoKTogUHJvbWlzZTxib29sZWFuPjtcbiAgICBnZXQoZmlsZU5hbWU6IHN0cmluZywgY29uZmlnPzogeyByYW5nZT86IHsgc3RhcnQ6IG51bWJlcjsgZW5kOiBudW1iZXIgfSB9KTogUHJvbWlzZTxCdWZmZXIgfCB1bmRlZmluZWQ+O1xuICAgIGdldDIoZmlsZU5hbWU6IHN0cmluZywgY29uZmlnPzogeyByYW5nZT86IHsgc3RhcnQ6IG51bWJlcjsgZW5kOiBudW1iZXIgfSB9KTogUHJvbWlzZTx7IGRhdGE6IEJ1ZmZlcjsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPjtcbiAgICAvKipcbiAgICAgKiBsYXN0TW9kaWZpZWQgc3RhbXBzIHRoZSB3cml0ZSB3aXRoIHRoYXQgbGFzdC13cml0ZSB0aW1lIGluc3RlYWQgb2Ygbm93LiBJZiBpdCBpcyBPTERFUiB0aGFuXG4gICAgICogdGhlIGZpbGUncyBjdXJyZW50IGxhc3Qtd3JpdGUgdGltZSB0aGUgd3JpdGUgbm8tb3BzIChzbyBkZWxheWVkIC8gc3luY2hyb25pemVkIHdyaXRlcyBjYW5cbiAgICAgKiBuZXZlciBjbG9iYmVyIG5ld2VyIGRhdGEpLiBUaW1lcyBtb3JlIHRoYW4gMTUgbWludXRlcyBpbiB0aGUgZnV0dXJlIGFyZSByZWplY3RlZC5cbiAgICAgKlxuICAgICAqIFJldHVybnMgdGhlIGZ1bGwga2V5IGFjdHVhbGx5IHdyaXR0ZW4gLSBpZGVudGljYWwgdG8gZmlsZU5hbWUsIEVYQ0VQVCBmb3Iga2V5cyBjb250YWluaW5nXG4gICAgICogVkFSSUFCTEVfU0hBUkQsIHdoZXJlIHRoZSBzaGFyZCB2YWx1ZSBpcyBtYXRlcmlhbGl6ZWQgaW50byB0aGUga2V5IChwaWNrZWQgYnkgc2hhcmQgbGF0ZW5jeSxcbiAgICAgKiBzZWUgQXJjaGl2ZXNDaGFpbikgYW5kIHRoZSBjYWxsZXIgbmVlZHMgdGhlIHJldHVybmVkIGtleSB0byBldmVyIHJlYWQgdGhlIHZhbHVlIGJhY2suXG4gICAgICovXG4gICAgc2V0KGZpbGVOYW1lOiBzdHJpbmcsIGRhdGE6IEJ1ZmZlciwgY29uZmlnPzogeyBsYXN0TW9kaWZpZWQ/OiBudW1iZXIgfSk6IFByb21pc2U8c3RyaW5nPjtcbiAgICBkZWwoZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8dm9pZD47XG4gICAgLyoqIFN0cmVhbXMgYSBmaWxlIHRvbyBsYXJnZSB0byBob2xkIGluIG1lbW9yeS4gZ2V0TmV4dERhdGEgcmV0dXJucyB1bmRlZmluZWQgd2hlbiBkb25lLiAqL1xuICAgIHNldExhcmdlRmlsZShjb25maWc6IHsgcGF0aDogc3RyaW5nOyBnZXROZXh0RGF0YSgpOiBQcm9taXNlPEJ1ZmZlciB8IHVuZGVmaW5lZD4gfSk6IFByb21pc2U8dm9pZD47XG4gICAgLyoqIHdyaXRlVGltZSBpcyB0aGUgbGFzdC13cml0ZSB0aW1lIOKAlCBzZWUgQXJjaGl2ZUZpbGVJbmZvLmNyZWF0ZVRpbWUsIHdoaWNoIGlzIHRoZSBzYW1lIHZhbHVlLiAqL1xuICAgIGdldEluZm8oZmlsZU5hbWU6IHN0cmluZyk6IFByb21pc2U8eyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ+O1xuICAgIGZpbmQocHJlZml4OiBzdHJpbmcsIGNvbmZpZz86IHsgc2hhbGxvdz86IGJvb2xlYW47IHR5cGU6IFwiZmlsZXNcIiB8IFwiZm9sZGVyc1wiIH0pOiBQcm9taXNlPHN0cmluZ1tdPjtcbiAgICBmaW5kSW5mbyhwcmVmaXg6IHN0cmluZywgY29uZmlnPzogeyBzaGFsbG93PzogYm9vbGVhbjsgdHlwZTogXCJmaWxlc1wiIHwgXCJmb2xkZXJzXCIgfSk6IFByb21pc2U8QXJjaGl2ZUZpbGVJbmZvW10+O1xuICAgIC8qKiBPbmx5IHdvcmtzIGZvciBwdWJsaWMgYnVja2V0cyAocHJpdmF0ZSBidWNrZXRzIGFyZSBBUEktYWNjZXNzIG9ubHkpLiAqL1xuICAgIGdldFVSTChwYXRoOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz47XG4gICAgLyoqIFRoZSBidWNrZXQncyBjb25maWd1cmF0aW9uLCB3aGljaCB0ZWxscyB3aGV0aGVyIHRoZSBvcHRpb25hbCBmdW5jdGlvbnMgYXJlIHN1cHBvcnRlZC4gKi9cbiAgICBnZXRDb25maWcoKTogUHJvbWlzZTxBcmNoaXZlc0NvbmZpZz47XG4gICAgLyoqXG4gICAgICogQWxsIGZpbGVzIGNoYW5nZWQgYWZ0ZXIgdGhlIGdpdmVuIHRpbWUuIE9ubHkgZXhpc3RzIHdoZW4gZ2V0Q29uZmlnKCkuc3VwcG9ydHNDaGFuZ2VzQWZ0ZXI7XG4gICAgICogYmFja2VkIGJ5IGFuIGluZGV4LCBzbyBpdCBpcyBmYXN0ICh1bmxpa2UgYSBmdWxsIGZpbmRJbmZvIHNjYW4pLiBEZWxldGlvbnMgYXJlIG5vdCByZXBvcnRlZC5cbiAgICAgKi9cbiAgICBnZXRDaGFuZ2VzQWZ0ZXI/KHRpbWU6IG51bWJlcik6IFByb21pc2U8QXJjaGl2ZUZpbGVJbmZvW10+O1xuICAgIC8qKiBTeW5jaHJvbml6YXRpb24gaW50cm9zcGVjdGlvbiwgZm9yIGJhY2tlbmRzIHRoYXQgc3luY2hyb25pemUgZnJvbSBzb3VyY2VzIChzZWUgQmxvYlN0b3JlKS4gKi9cbiAgICBnZXRTeW5jU3RhdHVzPygpOiBQcm9taXNlPEFyY2hpdmVzU3luY1N0YXR1cz47XG59XG4iXX0=
44
+ /* _JS_SOURCE_HASH = "7472343913c05ea655ed8fded8c2af230d118ac5592f093ebfe70d45579266c7"; */
@@ -46,13 +46,13 @@ export async function authenticateStorage(config: { address: string; port: numbe
46
46
  let rootDomain = config.address.split(".").slice(-2).join(".");
47
47
  await loadIdentityCA(rootDomain);
48
48
  let ca = getIdentityCA(rootDomain);
49
- let time = Date.now();
50
- let signature = sign({ key: ca.key }, {
49
+ let data = {
51
50
  purpose: STORAGE_AUTH_PURPOSE,
52
- time,
51
+ time: Date.now(),
53
52
  server: `${config.address}:${config.port}`,
54
- });
55
- return await RemoteStorageController.nodes[config.nodeId].authenticate({ certPem: ca.cert.toString(), time, signature });
53
+ };
54
+ let signature = sign({ key: ca.key }, data);
55
+ return await RemoteStorageController.nodes[config.nodeId].authenticate({ certPem: ca.cert.toString(), signature, data });
56
56
  }
57
57
 
58
58
  export class ArchivesRemote implements IArchives {
@@ -1,7 +1,8 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { ArchiveFileInfo, ArchivesSource, ArchivesSyncStatus, SyncActivity } from "../IArchives";
3
+ import { IArchives, ArchiveFileInfo, ArchivesSource, ArchivesSyncStatus, SyncActivity } from "../IArchives";
4
4
  export declare const DEFAULT_FAST_WRITE_DELAY: number;
5
+ export declare const WINDOW_END_FLUSH_MARGIN: number;
5
6
  export type WriteConfig = {
6
7
  fast?: boolean;
7
8
  writeDelay?: number;
@@ -70,7 +71,6 @@ export declare class BlobStore implements IBucketStore {
70
71
  constructor(folder: string, sources: ArchivesSource[], config?: {
71
72
  onIndexChanged?: ((key: string) => void) | undefined;
72
73
  readerDiskLimit?: number | undefined;
73
- getFlushDeadline?: (() => number | undefined) | undefined;
74
74
  } | undefined);
75
75
  private stopped;
76
76
  private index;
@@ -93,9 +93,16 @@ export declare class BlobStore implements IBucketStore {
93
93
  private countEntry;
94
94
  private setIndexEntry;
95
95
  private deleteIndexEntry;
96
- /** Rescans our own disk's metadata into the index - used around deploy switchovers, where the
97
- * other process wrote files to the shared folder that our index hasn't seen. */
96
+ /** Rescans our own disk's metadata into the index - used around valid window handoffs, where
97
+ * another process wrote files to the shared folder that our index hasn't seen. */
98
98
  rescanBase(): Promise<void>;
99
+ /** A boundary scan of the node that owned (part of) our route in the valid window before ours,
100
+ * when that node is different storage (a disk rescan can't see its writes): just its changes
101
+ * since the boundary neighborhood, with matching values pulled onto our own disk. */
102
+ boundaryScanRemote(source: IArchives, config: {
103
+ since: number;
104
+ route?: [number, number];
105
+ }): Promise<void>;
99
106
  /** The cheap always-current totals plus any in-progress background synchronization. */
100
107
  getSyncProgress(): {
101
108
  index: {
@@ -169,7 +176,6 @@ export declare class BlobStore implements IBucketStore {
169
176
  cancelLargeUpload(id: string): Promise<void>;
170
177
  private flushOverlay;
171
178
  private evicting;
172
- private loggedFlushDeadline;
173
179
  private enforceDiskLimit;
174
180
  private cleanupTombstones;
175
181
  }