sliftutils 1.7.97 → 1.7.99

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.
@@ -1,8 +1,9 @@
1
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
- //exports.StorageClientController = exports.onServerRoutingChanged = void 0;
3
+ //exports.StorageClientController = exports.trackChainConfig = exports.onServerRoutingChanged = void 0;
4
4
  const SocketFunction_1 = require("socket-function/SocketFunction");
5
- // The client half of routing-change broadcasts: the storage server tracks its connected clients (see trackCaller in storageController) and calls routingConfigChanged on every one of them the moment a routing config changes - clients react immediately instead of waiting for a poll.
5
+ const remoteConfig_1 = require("./remoteConfig");
6
+ // The client half of the storage protocol: the storage server tracks its connected clients (see trackCaller in storageController) and calls back into them - routingConfigChanged the moment a routing config changes (clients react immediately instead of waiting for a poll), and getRoutingConfigForName when a store one of our requests created needs the config we intended for it.
6
7
  const listeners = new Set();
7
8
  /** Subscribe to server-pushed routing change notifications. Returns the unsubscribe function. */
8
9
  function onServerRoutingChanged(listener) {
@@ -12,6 +13,32 @@ function onServerRoutingChanged(listener) {
12
13
  };
13
14
  }
14
15
  exports.onServerRoutingChanged = onServerRoutingChanged;
16
+ const chainConfigs = new Set();
17
+ /** Every chain tracks its configs here (see ChainStateManager), so a server can ask what config was intended for a store name. Returns the untrack function. */
18
+ function trackChainConfig(entry) {
19
+ chainConfigs.add(entry);
20
+ return () => {
21
+ chainConfigs.delete(entry);
22
+ };
23
+ }
24
+ exports.trackChainConfig = trackChainConfig;
25
+ function configNamesStore(config, account, bucketName, name) {
26
+ for (let source of config.sources) {
27
+ if (typeof source === "string" || source.type !== "remote")
28
+ continue;
29
+ if (source.name !== name)
30
+ continue;
31
+ try {
32
+ let parsed = (0, remoteConfig_1.parseHostedUrl)(source.url);
33
+ if (parsed.account === account && parsed.bucketName === bucketName)
34
+ return true;
35
+ }
36
+ catch (_a) {
37
+ continue;
38
+ }
39
+ }
40
+ return false;
41
+ }
15
42
  class StorageClientControllerBase {
16
43
  async routingConfigChanged() {
17
44
  var _a;
@@ -24,9 +51,23 @@ class StorageClientControllerBase {
24
51
  }
25
52
  }
26
53
  }
54
+ /** A storage server asks: what routing config did this client INTEND for this store name? This is how a store our requests created - before any config ever reached its folder - configures itself: the same information as passing the config on every call, fetched lazily instead (the config is kilobytes and the calls are many). Preference: the synchronized config (adopted from the stored routing files); when that no longer names the store, the initial in-code config - older, but it MATCHES the name, which is what the asking store needs. */
55
+ async getRoutingConfigForName(config) {
56
+ for (let entry of [...chainConfigs]) {
57
+ let active = entry.active();
58
+ if (configNamesStore(active, config.account, config.bucketName, config.name))
59
+ return active;
60
+ }
61
+ for (let entry of [...chainConfigs]) {
62
+ if (configNamesStore(entry.configured, config.account, config.bucketName, config.name))
63
+ return entry.configured;
64
+ }
65
+ return undefined;
66
+ }
27
67
  }
28
68
  exports.StorageClientController = SocketFunction_1.SocketFunction.register("StorageClientController-remoteStorage-2b8f1a6d", new StorageClientControllerBase(), () => ({
29
69
  routingConfigChanged: {},
70
+ getRoutingConfigForName: {},
30
71
  }));
31
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZUNsaWVudENvbnRyb2xsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzdG9yYWdlQ2xpZW50Q29udHJvbGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtRUFBZ0U7QUFFaEUsMFJBQTBSO0FBRTFSLE1BQU0sU0FBUyxHQUFHLElBQUksR0FBRyxFQUFjLENBQUM7QUFFeEMsaUdBQWlHO0FBQ2pHLFNBQWdCLHNCQUFzQixDQUFDLFFBQW9CO0lBQ3ZELFNBQVMsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDeEIsT0FBTyxHQUFHLEVBQUU7UUFDUixTQUFTLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQy9CLENBQUMsQ0FBQztBQUNOLENBQUM7QUFMRCx3REFLQztBQUVELE1BQU0sMkJBQTJCO0lBQzdCLEtBQUssQ0FBQyxvQkFBb0I7O1FBQ3RCLEtBQUssSUFBSSxRQUFRLElBQUksQ0FBQyxHQUFHLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDO2dCQUNELFFBQVEsRUFBRSxDQUFDO1lBQ2YsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1QsT0FBTyxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsTUFBQyxDQUFXLENBQUMsS0FBSyxtQ0FBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hGLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQztDQUNKO0FBRVksUUFBQSx1QkFBdUIsR0FBRywrQkFBYyxDQUFDLFFBQVEsQ0FDMUQsZ0RBQWdELEVBQ2hELElBQUksMkJBQTJCLEVBQUUsRUFDakMsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNILG9CQUFvQixFQUFFLEVBQUU7Q0FDM0IsQ0FBQyxDQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTb2NrZXRGdW5jdGlvbiB9IGZyb20gXCJzb2NrZXQtZnVuY3Rpb24vU29ja2V0RnVuY3Rpb25cIjtcblxuLy8gVGhlIGNsaWVudCBoYWxmIG9mIHJvdXRpbmctY2hhbmdlIGJyb2FkY2FzdHM6IHRoZSBzdG9yYWdlIHNlcnZlciB0cmFja3MgaXRzIGNvbm5lY3RlZCBjbGllbnRzIChzZWUgdHJhY2tDYWxsZXIgaW4gc3RvcmFnZUNvbnRyb2xsZXIpIGFuZCBjYWxscyByb3V0aW5nQ29uZmlnQ2hhbmdlZCBvbiBldmVyeSBvbmUgb2YgdGhlbSB0aGUgbW9tZW50IGEgcm91dGluZyBjb25maWcgY2hhbmdlcyAtIGNsaWVudHMgcmVhY3QgaW1tZWRpYXRlbHkgaW5zdGVhZCBvZiB3YWl0aW5nIGZvciBhIHBvbGwuXG5cbmNvbnN0IGxpc3RlbmVycyA9IG5ldyBTZXQ8KCkgPT4gdm9pZD4oKTtcblxuLyoqIFN1YnNjcmliZSB0byBzZXJ2ZXItcHVzaGVkIHJvdXRpbmcgY2hhbmdlIG5vdGlmaWNhdGlvbnMuIFJldHVybnMgdGhlIHVuc3Vic2NyaWJlIGZ1bmN0aW9uLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uU2VydmVyUm91dGluZ0NoYW5nZWQobGlzdGVuZXI6ICgpID0+IHZvaWQpOiAoKSA9PiB2b2lkIHtcbiAgICBsaXN0ZW5lcnMuYWRkKGxpc3RlbmVyKTtcbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgICBsaXN0ZW5lcnMuZGVsZXRlKGxpc3RlbmVyKTtcbiAgICB9O1xufVxuXG5jbGFzcyBTdG9yYWdlQ2xpZW50Q29udHJvbGxlckJhc2Uge1xuICAgIGFzeW5jIHJvdXRpbmdDb25maWdDaGFuZ2VkKCk6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICBmb3IgKGxldCBsaXN0ZW5lciBvZiBbLi4ubGlzdGVuZXJzXSkge1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBsaXN0ZW5lcigpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIGNvbnNvbGUuZXJyb3IoYFJvdXRpbmcgY2hhbmdlIGxpc3RlbmVyIGZhaWxlZDogJHsoZSBhcyBFcnJvcikuc3RhY2sgPz8gZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGNvbnN0IFN0b3JhZ2VDbGllbnRDb250cm9sbGVyID0gU29ja2V0RnVuY3Rpb24ucmVnaXN0ZXIoXG4gICAgXCJTdG9yYWdlQ2xpZW50Q29udHJvbGxlci1yZW1vdGVTdG9yYWdlLTJiOGYxYTZkXCIsXG4gICAgbmV3IFN0b3JhZ2VDbGllbnRDb250cm9sbGVyQmFzZSgpLFxuICAgICgpID0+ICh7XG4gICAgICAgIHJvdXRpbmdDb25maWdDaGFuZ2VkOiB7fSxcbiAgICB9KSxcbik7XG4iXX0=
32
- /* _JS_SOURCE_HASH = "7ef96e2ea624c351032e8ff3e59b3ea4728adf24566c77b9cc46367a3605832a"; */
72
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZUNsaWVudENvbnRyb2xsZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzdG9yYWdlQ2xpZW50Q29udHJvbGxlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtRUFBZ0U7QUFFaEUsaURBQWdEO0FBRWhELDJYQUEyWDtBQUUzWCxNQUFNLFNBQVMsR0FBRyxJQUFJLEdBQUcsRUFBYyxDQUFDO0FBRXhDLGlHQUFpRztBQUNqRyxTQUFnQixzQkFBc0IsQ0FBQyxRQUFvQjtJQUN2RCxTQUFTLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ3hCLE9BQU8sR0FBRyxFQUFFO1FBQ1IsU0FBUyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQztJQUMvQixDQUFDLENBQUM7QUFDTixDQUFDO0FBTEQsd0RBS0M7QUFJRCxNQUFNLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBc0IsQ0FBQztBQUVuRCxnS0FBZ0s7QUFDaEssU0FBZ0IsZ0JBQWdCLENBQUMsS0FBeUI7SUFDdEQsWUFBWSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN4QixPQUFPLEdBQUcsRUFBRTtRQUNSLFlBQVksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDL0IsQ0FBQyxDQUFDO0FBQ04sQ0FBQztBQUxELDRDQUtDO0FBRUQsU0FBUyxnQkFBZ0IsQ0FBQyxNQUFvQixFQUFFLE9BQWUsRUFBRSxVQUFrQixFQUFFLElBQVk7SUFDN0YsS0FBSyxJQUFJLE1BQU0sSUFBSSxNQUFNLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDaEMsSUFBSSxPQUFPLE1BQU0sS0FBSyxRQUFRLElBQUksTUFBTSxDQUFDLElBQUksS0FBSyxRQUFRO1lBQUUsU0FBUztRQUNyRSxJQUFJLE1BQU0sQ0FBQyxJQUFJLEtBQUssSUFBSTtZQUFFLFNBQVM7UUFDbkMsSUFBSSxDQUFDO1lBQ0QsSUFBSSxNQUFNLEdBQUcsSUFBQSw2QkFBYyxFQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN4QyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEtBQUssT0FBTyxJQUFJLE1BQU0sQ0FBQyxVQUFVLEtBQUssVUFBVTtnQkFBRSxPQUFPLElBQUksQ0FBQztRQUNwRixDQUFDO1FBQUMsV0FBTSxDQUFDO1lBQ0wsU0FBUztRQUNiLENBQUM7SUFDTCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDakIsQ0FBQztBQUVELE1BQU0sMkJBQTJCO0lBQzdCLEtBQUssQ0FBQyxvQkFBb0I7O1FBQ3RCLEtBQUssSUFBSSxRQUFRLElBQUksQ0FBQyxHQUFHLFNBQVMsQ0FBQyxFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDO2dCQUNELFFBQVEsRUFBRSxDQUFDO1lBQ2YsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1QsT0FBTyxDQUFDLEtBQUssQ0FBQyxtQ0FBbUMsTUFBQyxDQUFXLENBQUMsS0FBSyxtQ0FBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2hGLENBQUM7UUFDTCxDQUFDO0lBQ0wsQ0FBQztJQUVELCtoQkFBK2hCO0lBQy9oQixLQUFLLENBQUMsdUJBQXVCLENBQUMsTUFBNkQ7UUFDdkYsS0FBSyxJQUFJLEtBQUssSUFBSSxDQUFDLEdBQUcsWUFBWSxDQUFDLEVBQUUsQ0FBQztZQUNsQyxJQUFJLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDNUIsSUFBSSxnQkFBZ0IsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLE9BQU8sRUFBRSxNQUFNLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUM7Z0JBQUUsT0FBTyxNQUFNLENBQUM7UUFDaEcsQ0FBQztRQUNELEtBQUssSUFBSSxLQUFLLElBQUksQ0FBQyxHQUFHLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDbEMsSUFBSSxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLFVBQVUsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDO2dCQUFFLE9BQU8sS0FBSyxDQUFDLFVBQVUsQ0FBQztRQUNwSCxDQUFDO1FBQ0QsT0FBTyxTQUFTLENBQUM7SUFDckIsQ0FBQztDQUNKO0FBRVksUUFBQSx1QkFBdUIsR0FBRywrQkFBYyxDQUFDLFFBQVEsQ0FDMUQsZ0RBQWdELEVBQ2hELElBQUksMkJBQTJCLEVBQUUsRUFDakMsR0FBRyxFQUFFLENBQUMsQ0FBQztJQUNILG9CQUFvQixFQUFFLEVBQUU7SUFDeEIsdUJBQXVCLEVBQUUsRUFBRTtDQUM5QixDQUFDLENBQ0wsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNvY2tldEZ1bmN0aW9uIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9Tb2NrZXRGdW5jdGlvblwiO1xuaW1wb3J0IHsgUmVtb3RlQ29uZmlnIH0gZnJvbSBcIi4uL0lBcmNoaXZlc1wiO1xuaW1wb3J0IHsgcGFyc2VIb3N0ZWRVcmwgfSBmcm9tIFwiLi9yZW1vdGVDb25maWdcIjtcblxuLy8gVGhlIGNsaWVudCBoYWxmIG9mIHRoZSBzdG9yYWdlIHByb3RvY29sOiB0aGUgc3RvcmFnZSBzZXJ2ZXIgdHJhY2tzIGl0cyBjb25uZWN0ZWQgY2xpZW50cyAoc2VlIHRyYWNrQ2FsbGVyIGluIHN0b3JhZ2VDb250cm9sbGVyKSBhbmQgY2FsbHMgYmFjayBpbnRvIHRoZW0gLSByb3V0aW5nQ29uZmlnQ2hhbmdlZCB0aGUgbW9tZW50IGEgcm91dGluZyBjb25maWcgY2hhbmdlcyAoY2xpZW50cyByZWFjdCBpbW1lZGlhdGVseSBpbnN0ZWFkIG9mIHdhaXRpbmcgZm9yIGEgcG9sbCksIGFuZCBnZXRSb3V0aW5nQ29uZmlnRm9yTmFtZSB3aGVuIGEgc3RvcmUgb25lIG9mIG91ciByZXF1ZXN0cyBjcmVhdGVkIG5lZWRzIHRoZSBjb25maWcgd2UgaW50ZW5kZWQgZm9yIGl0LlxuXG5jb25zdCBsaXN0ZW5lcnMgPSBuZXcgU2V0PCgpID0+IHZvaWQ+KCk7XG5cbi8qKiBTdWJzY3JpYmUgdG8gc2VydmVyLXB1c2hlZCByb3V0aW5nIGNoYW5nZSBub3RpZmljYXRpb25zLiBSZXR1cm5zIHRoZSB1bnN1YnNjcmliZSBmdW5jdGlvbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvblNlcnZlclJvdXRpbmdDaGFuZ2VkKGxpc3RlbmVyOiAoKSA9PiB2b2lkKTogKCkgPT4gdm9pZCB7XG4gICAgbGlzdGVuZXJzLmFkZChsaXN0ZW5lcik7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgbGlzdGVuZXJzLmRlbGV0ZShsaXN0ZW5lcik7XG4gICAgfTtcbn1cblxuLyoqIE9uZSBjaGFpbidzIGNvbmZpZ3MsIGFzIGdldFJvdXRpbmdDb25maWdGb3JOYW1lIGFuc3dlcnMgZnJvbSB0aGVtOiB0aGUgaW5pdGlhbCBpbi1jb2RlIGNvbmZpZywgYW5kIGEgZ2V0dGVyIGZvciB0aGUgc3luY2hyb25pemVkIG9uZSAoYWRvcHRlZCBmcm9tIHRoZSBzdG9yZWQgcm91dGluZyBmaWxlcywgc28gaXQgY2hhbmdlcyBvdmVyIHRpbWUpLiAqL1xudHlwZSBUcmFja2VkQ2hhaW5Db25maWcgPSB7IGNvbmZpZ3VyZWQ6IFJlbW90ZUNvbmZpZzsgYWN0aXZlOiAoKSA9PiBSZW1vdGVDb25maWcgfTtcbmNvbnN0IGNoYWluQ29uZmlncyA9IG5ldyBTZXQ8VHJhY2tlZENoYWluQ29uZmlnPigpO1xuXG4vKiogRXZlcnkgY2hhaW4gdHJhY2tzIGl0cyBjb25maWdzIGhlcmUgKHNlZSBDaGFpblN0YXRlTWFuYWdlciksIHNvIGEgc2VydmVyIGNhbiBhc2sgd2hhdCBjb25maWcgd2FzIGludGVuZGVkIGZvciBhIHN0b3JlIG5hbWUuIFJldHVybnMgdGhlIHVudHJhY2sgZnVuY3Rpb24uICovXG5leHBvcnQgZnVuY3Rpb24gdHJhY2tDaGFpbkNvbmZpZyhlbnRyeTogVHJhY2tlZENoYWluQ29uZmlnKTogKCkgPT4gdm9pZCB7XG4gICAgY2hhaW5Db25maWdzLmFkZChlbnRyeSk7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgICAgY2hhaW5Db25maWdzLmRlbGV0ZShlbnRyeSk7XG4gICAgfTtcbn1cblxuZnVuY3Rpb24gY29uZmlnTmFtZXNTdG9yZShjb25maWc6IFJlbW90ZUNvbmZpZywgYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGZvciAobGV0IHNvdXJjZSBvZiBjb25maWcuc291cmNlcykge1xuICAgICAgICBpZiAodHlwZW9mIHNvdXJjZSA9PT0gXCJzdHJpbmdcIiB8fCBzb3VyY2UudHlwZSAhPT0gXCJyZW1vdGVcIikgY29udGludWU7XG4gICAgICAgIGlmIChzb3VyY2UubmFtZSAhPT0gbmFtZSkgY29udGludWU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBsZXQgcGFyc2VkID0gcGFyc2VIb3N0ZWRVcmwoc291cmNlLnVybCk7XG4gICAgICAgICAgICBpZiAocGFyc2VkLmFjY291bnQgPT09IGFjY291bnQgJiYgcGFyc2VkLmJ1Y2tldE5hbWUgPT09IGJ1Y2tldE5hbWUpIHJldHVybiB0cnVlO1xuICAgICAgICB9IGNhdGNoIHtcbiAgICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbn1cblxuY2xhc3MgU3RvcmFnZUNsaWVudENvbnRyb2xsZXJCYXNlIHtcbiAgICBhc3luYyByb3V0aW5nQ29uZmlnQ2hhbmdlZCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICAgICAgZm9yIChsZXQgbGlzdGVuZXIgb2YgWy4uLmxpc3RlbmVyc10pIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbGlzdGVuZXIoKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICBjb25zb2xlLmVycm9yKGBSb3V0aW5nIGNoYW5nZSBsaXN0ZW5lciBmYWlsZWQ6ICR7KGUgYXMgRXJyb3IpLnN0YWNrID8/IGV9YCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQSBzdG9yYWdlIHNlcnZlciBhc2tzOiB3aGF0IHJvdXRpbmcgY29uZmlnIGRpZCB0aGlzIGNsaWVudCBJTlRFTkQgZm9yIHRoaXMgc3RvcmUgbmFtZT8gVGhpcyBpcyBob3cgYSBzdG9yZSBvdXIgcmVxdWVzdHMgY3JlYXRlZCAtIGJlZm9yZSBhbnkgY29uZmlnIGV2ZXIgcmVhY2hlZCBpdHMgZm9sZGVyIC0gY29uZmlndXJlcyBpdHNlbGY6IHRoZSBzYW1lIGluZm9ybWF0aW9uIGFzIHBhc3NpbmcgdGhlIGNvbmZpZyBvbiBldmVyeSBjYWxsLCBmZXRjaGVkIGxhemlseSBpbnN0ZWFkICh0aGUgY29uZmlnIGlzIGtpbG9ieXRlcyBhbmQgdGhlIGNhbGxzIGFyZSBtYW55KS4gUHJlZmVyZW5jZTogdGhlIHN5bmNocm9uaXplZCBjb25maWcgKGFkb3B0ZWQgZnJvbSB0aGUgc3RvcmVkIHJvdXRpbmcgZmlsZXMpOyB3aGVuIHRoYXQgbm8gbG9uZ2VyIG5hbWVzIHRoZSBzdG9yZSwgdGhlIGluaXRpYWwgaW4tY29kZSBjb25maWcgLSBvbGRlciwgYnV0IGl0IE1BVENIRVMgdGhlIG5hbWUsIHdoaWNoIGlzIHdoYXQgdGhlIGFza2luZyBzdG9yZSBuZWVkcy4gKi9cbiAgICBhc3luYyBnZXRSb3V0aW5nQ29uZmlnRm9yTmFtZShjb25maWc6IHsgYWNjb3VudDogc3RyaW5nOyBidWNrZXROYW1lOiBzdHJpbmc7IG5hbWU6IHN0cmluZyB9KTogUHJvbWlzZTxSZW1vdGVDb25maWcgfCB1bmRlZmluZWQ+IHtcbiAgICAgICAgZm9yIChsZXQgZW50cnkgb2YgWy4uLmNoYWluQ29uZmlnc10pIHtcbiAgICAgICAgICAgIGxldCBhY3RpdmUgPSBlbnRyeS5hY3RpdmUoKTtcbiAgICAgICAgICAgIGlmIChjb25maWdOYW1lc1N0b3JlKGFjdGl2ZSwgY29uZmlnLmFjY291bnQsIGNvbmZpZy5idWNrZXROYW1lLCBjb25maWcubmFtZSkpIHJldHVybiBhY3RpdmU7XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgZW50cnkgb2YgWy4uLmNoYWluQ29uZmlnc10pIHtcbiAgICAgICAgICAgIGlmIChjb25maWdOYW1lc1N0b3JlKGVudHJ5LmNvbmZpZ3VyZWQsIGNvbmZpZy5hY2NvdW50LCBjb25maWcuYnVja2V0TmFtZSwgY29uZmlnLm5hbWUpKSByZXR1cm4gZW50cnkuY29uZmlndXJlZDtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH1cbn1cblxuZXhwb3J0IGNvbnN0IFN0b3JhZ2VDbGllbnRDb250cm9sbGVyID0gU29ja2V0RnVuY3Rpb24ucmVnaXN0ZXIoXG4gICAgXCJTdG9yYWdlQ2xpZW50Q29udHJvbGxlci1yZW1vdGVTdG9yYWdlLTJiOGYxYTZkXCIsXG4gICAgbmV3IFN0b3JhZ2VDbGllbnRDb250cm9sbGVyQmFzZSgpLFxuICAgICgpID0+ICh7XG4gICAgICAgIHJvdXRpbmdDb25maWdDaGFuZ2VkOiB7fSxcbiAgICAgICAgZ2V0Um91dGluZ0NvbmZpZ0Zvck5hbWU6IHt9LFxuICAgIH0pLFxuKTtcbiJdfQ==
73
+ /* _JS_SOURCE_HASH = "43686cff5a8e71fe5c0cb34eca098b2c8404798bf822c5b97aa5b26f71439a6e"; */
@@ -9,6 +9,8 @@ const serverConfig_1 = require("./serverConfig");
9
9
  const validation_1 = require("./validation");
10
10
  const bucketDisk_1 = require("./bucketDisk");
11
11
  const intermediateManagement_1 = require("./intermediateManagement");
12
+ const SocketFunction_1 = require("socket-function/SocketFunction");
13
+ const storageClientController_1 = require("./storageClientController");
12
14
  const storePlan_1 = require("./storePlan");
13
15
  const accessStats_1 = require("./accessStats");
14
16
  /**
@@ -25,7 +27,7 @@ const accessStats_1 = require("./accessStats");
25
27
  const stores = new Map();
26
28
  // The opened stores of each `${account}/${bucketName}`, by name - which buckets are ACTIVE (something touched them), for deploy handoffs and the debug pages. Purely a registry of what getStore already made.
27
29
  const activeStores = new Map();
28
- function getStore(account, bucketName, name) {
30
+ function getStore(account, bucketName, name, callerNodeId) {
29
31
  // The one place a name becomes a folder, so the one place it is validated (it can come straight off the wire)
30
32
  (0, validation_1.assertValidSourceName)(name);
31
33
  let folder = (0, bucketDisk_1.getBucketFolder)(name, account, bucketName);
@@ -42,6 +44,8 @@ function getStore(account, bucketName, name) {
42
44
  resolveSourceUrl: resolveSourceArchives,
43
45
  // The store is the one that knows when a config landed, and a config with upcoming windows is what boundary scans are armed from
44
46
  onRoutingApplied: routing => (0, intermediateManagement_1.scheduleBoundaryWork)(account, bucketName, routing),
47
+ // The store was created by this caller's request, so the caller knows exactly what config it intended for this name - the store asks it when its own folder holds no configuration (see BlobStore.init)
48
+ requestRoutingConfig: callerNodeId && (async () => await storageClientController_1.StorageClientController.nodes[callerNodeId].getRoutingConfigForName({ account, bucketName, name })) || undefined,
45
49
  });
46
50
  stores.set(folder, store);
47
51
  let key = `${account}/${bucketName}`;
@@ -58,10 +62,17 @@ function getStore(account, bucketName, name) {
58
62
  exports.getStore = getStore;
59
63
  /** The store serving a request: the one the client's selected entry NAMES. Account, name, and bucket ARE the folder, so this is a direct lookup, never a search of what exists - and a name this server has never seen is CREATED, never rejected, because asking for a name is the instruction to have that store (one name, one folder, one index; it configures itself once the routing config lands in it). Nothing else about the request is compared - not the window, not the route, not the flags - which is the whole point of naming it: a client a config version behind on some flag still reaches the right store. */
60
64
  function findBucketStore(account, bucketName, sourceConfig) {
65
+ var _a;
61
66
  if (!sourceConfig) {
62
67
  throw new Error(`No remote source configuration was provided for bucket ${account}/${bucketName}: every request must say which configured source it selected`);
63
68
  }
64
- return getStore(account, bucketName, sourceConfig.name);
69
+ // The caller's id, so a store this request CREATES can ask that caller for the config it intended (a store only ever exists because a config names it, and the requester holds that config)
70
+ let callerNodeId;
71
+ try {
72
+ callerNodeId = (_a = SocketFunction_1.SocketFunction.getCaller()) === null || _a === void 0 ? void 0 : _a.nodeId;
73
+ }
74
+ catch (_b) { }
75
+ return getStore(account, bucketName, sourceConfig.name, callerNodeId);
65
76
  }
66
77
  exports.findBucketStore = findBucketStore;
67
78
  /** The stores of a bucket as the DISK records them (a bucket is nothing more than the store folders sharing its name), opened - so the ones that weren't running yet start synchronizing. Empty when the bucket does not exist here. */
@@ -257,5 +268,5 @@ async function debugListAccountBuckets(account) {
257
268
  }
258
269
  }
259
270
  exports.debugListAccountBuckets = debugListAccountBuckets;
260
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZVNlcnZlclN0YXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3RvcmFnZVNlcnZlclN0YXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDJDQUF3QztBQUl4QyxpREFBd0c7QUFDeEcsaURBQXNFO0FBQ3RFLDJEQUE4RDtBQUM5RCxpREFBcUQ7QUFDckQsNkNBQXFEO0FBQ3JELDZDQUFrSjtBQUNsSixxRUFBdUY7QUFDdkYsMkNBQTJDO0FBQzNDLCtDQUF3RjtBQUV4Rjs7Ozs7R0FLRztBQUVIOzs7O0dBSUc7QUFDSCxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBcUIsQ0FBQztBQUM1QywrTUFBK007QUFDL00sTUFBTSxZQUFZLEdBQUcsSUFBSSxHQUFHLEVBQWtDLENBQUM7QUFFL0QsU0FBZ0IsUUFBUSxDQUFDLE9BQWUsRUFBRSxVQUFrQixFQUFFLElBQVk7SUFDdEUsOEdBQThHO0lBQzlHLElBQUEsa0NBQXFCLEVBQUMsSUFBSSxDQUFDLENBQUM7SUFDNUIsSUFBSSxNQUFNLEdBQUcsSUFBQSw0QkFBZSxFQUFDLElBQUksRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDLENBQUM7SUFDeEQsSUFBSSxRQUFRLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNsQyxJQUFJLFFBQVE7UUFBRSxPQUFPLFFBQVEsQ0FBQztJQUM5QixPQUFPLENBQUMsR0FBRyxDQUFDLGlCQUFpQixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxjQUFjLE9BQU8sSUFBSSxVQUFVLFlBQVksTUFBTSxHQUFHLENBQUMsQ0FBQztJQUMzRyxJQUFJLEtBQUssR0FBRyxJQUFJLHFCQUFTLENBQUMsTUFBTSxFQUFFLElBQUksRUFBRTtRQUNwQyxtRUFBbUU7UUFDbkUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUMsSUFBQSx3QkFBWSxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsVUFBVSxDQUFDO1FB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LEtBQUssRUFBRSxvQkFBb0IsMkJBQVksd0JBQXdCLEVBQUUsQ0FBQztnQkFDeEYsQ0FBQztnQkFDRCxPQUFPLEVBQUUsR0FBRyxJQUFJLEVBQUUsTUFBTSxFQUFFLEVBQUUsWUFBWSxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDMUQsQ0FBQztZQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUM7Z0JBQ1QsT0FBTyxFQUFFLEdBQUcsSUFBSSxFQUFFLEtBQUssRUFBRSxNQUFNLENBQUMsTUFBQyxDQUFXLENBQUMsS0FBSyxtQ0FBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDN0UsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDUixDQUFDO1lBQVMsQ0FBQztRQUNQLE9BQU8sQ0FBQyxHQUFHLENBQUMsMkJBQTJCLE9BQU8sVUFBVSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsS0FBSyxVQUFVLEtBQUssQ0FBQyxNQUFNLFVBQVUsQ0FBQyxDQUFDO0lBQ2hILENBQUM7QUFDTCxDQUFDO0FBckNELDBEQXFDQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEJsb2JTdG9yZSB9IGZyb20gXCIuL2Jsb2JTdG9yZVwiO1xuaW1wb3J0IHtcbiAgICBSZW1vdGVDb25maWcsIFNvdXJjZUNvbmZpZywgSUFyY2hpdmVzLCBBcmNoaXZlc0NvbmZpZywgQXJjaGl2ZXNTeW5jU3RhdHVzLCBTeW5jQWN0aXZpdHksXG59IGZyb20gXCIuLi9JQXJjaGl2ZXNcIjtcbmltcG9ydCB7IFJPVVRJTkdfRklMRSwgcGFyc2VSb3V0aW5nRGF0YSwgc2VyaWFsaXplUmVtb3RlQ29uZmlnLCBub3JtYWxpemVTb3VyY2UgfSBmcm9tIFwiLi9yZW1vdGVDb25maWdcIjtcbmltcG9ydCB7IGNyZWF0ZVN0b3JlU291cmNlLCBhcHBseVNvdXJjZUNvbmZpZyB9IGZyb20gXCIuL3N0b3JlU291cmNlc1wiO1xuaW1wb3J0IHsgYnJvYWRjYXN0Um91dGluZ0NoYW5nZWQgfSBmcm9tIFwiLi9zdG9yYWdlQ29udHJvbGxlclwiO1xuaW1wb3J0IHsgYXNzZXJ0V3JpdGVzQWxsb3dlZCB9IGZyb20gXCIuL3NlcnZlckNvbmZpZ1wiO1xuaW1wb3J0IHsgYXNzZXJ0VmFsaWRTb3VyY2VOYW1lIH0gZnJvbSBcIi4vdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgZ2V0QnVja2V0Rm9sZGVyLCBsaXN0QWNjb3VudFN0b3JlRm9sZGVycywgbGlzdEJ1Y2tldFN0b3JlRm9sZGVycywgcmVhZFJvdXRpbmdGcm9tRGlzaywgZ2V0RGlza0luZm8sIEJ1Y2tldERpc2tJbmZvIH0gZnJvbSBcIi4vYnVja2V0RGlza1wiO1xuaW1wb3J0IHsgc2NoZWR1bGVCb3VuZGFyeVdvcmssIHJlaW5qZWN0SW50ZXJtZWRpYXRlcyB9IGZyb20gXCIuL2ludGVybWVkaWF0ZU1hbmFnZW1lbnRcIjtcbmltcG9ydCB7IGlzU2VsZlNvdXJjZSB9IGZyb20gXCIuL3N0b3JlUGxhblwiO1xuaW1wb3J0IHsgY291bnRCdWNrZXRXcml0ZSwgZ2V0QnVja2V0V3JpdGVTdGF0cywgQnVja2V0V3JpdGVTdGF0cyB9IGZyb20gXCIuL2FjY2Vzc1N0YXRzXCI7XG5cbi8qKlxuICogV2hhdCB0aGlzIHNlcnZlciBIQVM6IHRoZSBzdG9yZXMsIGJ5IG5hbWUgKGdldFN0b3JlKSAtIG1hZGUgb25jZSwgc2VsZi1jb25maWd1cmluZyBmcm9tIHRoZXJlIC1cbiAqIGFuZCB0aGUgdGhyZWUgZW50cnkgcG9pbnRzIGEgcmVxdWVzdCByZXNvbHZlcyB0aHJvdWdoIChmaW5kQnVja2V0U3RvcmUsIHJlYWRCdWNrZXRJbnRlcm5hbCxcbiAqIHdyaXRlUm91dGluZ0NvbmZpZykuIFRoZXJlIGlzIG5vIGNhY2hlZCBidWNrZXQgc3RhdGU6IGEgYnVja2V0IGlzIG5vdGhpbmcgYnV0IHRoZSBzdG9yZXMgd2hvc2VcbiAqIGZvbGRlcnMgc2hhcmUgaXRzIG5hbWUsIGxpc3RlZCBvZmYgdGhlIGRpc2sgd2hlbiBzb21ldGhpbmcgZ2VudWluZWx5IG5lZWRzIGFsbCBvZiB0aGVtLlxuICovXG5cbi8qKlxuICogRXZlcnkgc3RvcmUgdGhpcyBwcm9jZXNzIHJ1bnMsIGJ5IGZvbGRlciAtIHdoaWNoIElTIHRoZSBzdG9yZSdzIGlkZW50aXR5OiBhY2NvdW50LCBuYW1lLCBidWNrZXQuXG4gKiBBIHN0b3JlIGlzIG1hZGUgb25jZSwgY29uZmlndXJlcyBpdHNlbGYgZnJvbSB0aGUgcm91dGluZyBjb25maWcgaXQgaG9sZHMsIGFuZCBzdGF5czsgbm90aGluZyBoZXJlXG4gKiBkZWNpZGVzIHdoYXQgaXQgaXMsIG9ubHkgdGhhdCBpdCBleGlzdHMuXG4gKi9cbmNvbnN0IHN0b3JlcyA9IG5ldyBNYXA8c3RyaW5nLCBCbG9iU3RvcmU+KCk7XG4vLyBUaGUgb3BlbmVkIHN0b3JlcyBvZiBlYWNoIGAke2FjY291bnR9LyR7YnVja2V0TmFtZX1gLCBieSBuYW1lIC0gd2hpY2ggYnVja2V0cyBhcmUgQUNUSVZFIChzb21ldGhpbmcgdG91Y2hlZCB0aGVtKSwgZm9yIGRlcGxveSBoYW5kb2ZmcyBhbmQgdGhlIGRlYnVnIHBhZ2VzLiBQdXJlbHkgYSByZWdpc3RyeSBvZiB3aGF0IGdldFN0b3JlIGFscmVhZHkgbWFkZS5cbmNvbnN0IGFjdGl2ZVN0b3JlcyA9IG5ldyBNYXA8c3RyaW5nLCBNYXA8c3RyaW5nLCBCbG9iU3RvcmU+PigpO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3RvcmUoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IEJsb2JTdG9yZSB7XG4gICAgLy8gVGhlIG9uZSBwbGFjZSBhIG5hbWUgYmVjb21lcyBhIGZvbGRlciwgc28gdGhlIG9uZSBwbGFjZSBpdCBpcyB2YWxpZGF0ZWQgKGl0IGNhbiBjb21lIHN0cmFpZ2h0IG9mZiB0aGUgd2lyZSlcbiAgICBhc3NlcnRWYWxpZFNvdXJjZU5hbWUobmFtZSk7XG4gICAgbGV0IGZvbGRlciA9IGdldEJ1Y2tldEZvbGRlcihuYW1lLCBhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICBsZXQgZXhpc3RpbmcgPSBzdG9yZXMuZ2V0KGZvbGRlcik7XG4gICAgaWYgKGV4aXN0aW5nKSByZXR1cm4gZXhpc3Rpbmc7XG4gICAgY29uc29sZS5sb2coYE9wZW5pbmcgc3RvcmUgJHtKU09OLnN0cmluZ2lmeShuYW1lKX0gb2YgYnVja2V0ICR7YWNjb3VudH0vJHtidWNrZXROYW1lfSAoZm9sZGVyICR7Zm9sZGVyfSlgKTtcbiAgICBsZXQgc3RvcmUgPSBuZXcgQmxvYlN0b3JlKGZvbGRlciwgbmFtZSwge1xuICAgICAgICAvLyBXaGljaCBlbnRyaWVzIGluIElUUyByb3V0aW5nIGNvbmZpZyBhcmUgdGhpcyBzZXJ2ZXIncyBjb3B5IG9mIGl0XG4gICAgICAgIGlzU2VsZjogc291cmNlID0+IGlzU2VsZlNvdXJjZShzb3VyY2UsIGFjY291bnQsIGJ1Y2tldE5hbWUpLFxuICAgICAgICBjcmVhdGVTb3VyY2U6IGNvbmZpZyA9PiBjcmVhdGVTdG9yZVNvdXJjZSh7IHNvdXJjZUNvbmZpZzogY29uZmlnLnNvdXJjZUNvbmZpZywgZm9sZGVyLCB3cml0ZURlbGF5OiBjb25maWcud3JpdGVEZWxheSB9KSxcbiAgICAgICAgYXBwbHlTb3VyY2U6IChzb3VyY2UsIHNvdXJjZUNvbmZpZywgd3JpdGVEZWxheSkgPT4gYXBwbHlTb3VyY2VDb25maWcoc291cmNlLCBzb3VyY2VDb25maWcsIHdyaXRlRGVsYXkpLFxuICAgICAgICBvbldyaXRlQ291bnRlZDogKGtpbmQsIGJ5dGVzKSA9PiBjb3VudEJ1Y2tldFdyaXRlKGAke2FjY291bnR9LyR7YnVja2V0TmFtZX1gLCBraW5kLCBieXRlcyksXG4gICAgICAgIHJlc29sdmVTb3VyY2VVcmw6IHJlc29sdmVTb3VyY2VBcmNoaXZlcyxcbiAgICAgICAgLy8gVGhlIHN0b3JlIGlzIHRoZSBvbmUgdGhhdCBrbm93cyB3aGVuIGEgY29uZmlnIGxhbmRlZCwgYW5kIGEgY29uZmlnIHdpdGggdXBjb21pbmcgd2luZG93cyBpcyB3aGF0IGJvdW5kYXJ5IHNjYW5zIGFyZSBhcm1lZCBmcm9tXG4gICAgICAgIG9uUm91dGluZ0FwcGxpZWQ6IHJvdXRpbmcgPT4gc2NoZWR1bGVCb3VuZGFyeVdvcmsoYWNjb3VudCwgYnVja2V0TmFtZSwgcm91dGluZyksXG4gICAgfSk7XG4gICAgc3RvcmVzLnNldChmb2xkZXIsIHN0b3JlKTtcbiAgICBsZXQga2V5ID0gYCR7YWNjb3VudH0vJHtidWNrZXROYW1lfWA7XG4gICAgbGV0IGJ5TmFtZSA9IGFjdGl2ZVN0b3Jlcy5nZXQoa2V5KTtcbiAgICBpZiAoIWJ5TmFtZSkge1xuICAgICAgICBieU5hbWUgPSBuZXcgTWFwKCk7XG4gICAgICAgIGFjdGl2ZVN0b3Jlcy5zZXQoa2V5LCBieU5hbWUpO1xuICAgIH1cbiAgICBieU5hbWUuc2V0KG5hbWUsIHN0b3JlKTtcbiAgICAvLyBMYXp5IGluaXQgd291bGQgbGVhdmUgYSBzdG9yZSBub3RoaW5nIGhhcyB0b3VjaGVkIHNpdHRpbmcgaW5lcnQgLSBubyBpbmRleCBsb2FkZWQsIG5vIGNvbmZpZyBhcHBsaWVkLCBub3RoaW5nIHN5bmNocm9uaXppbmcgLSB3aGlsZSBpdHMgZm9sZGVyIGlzIGZ1bGwgb2YgZmlsZXNcbiAgICB2b2lkIHN0b3JlLmluaXQoKS5jYXRjaCgoZTogRXJyb3IpID0+IGNvbnNvbGUuZXJyb3IoYEluaXRpYWxpemluZyBzdG9yZSAke0pTT04uc3RyaW5naWZ5KG5hbWUpfSBvZiBidWNrZXQgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9IGZhaWxlZDogJHtlLnN0YWNrID8/IGV9YCkpO1xuICAgIHJldHVybiBzdG9yZTtcbn1cblxuLyoqIFRoZSBzdG9yZSBzZXJ2aW5nIGEgcmVxdWVzdDogdGhlIG9uZSB0aGUgY2xpZW50J3Mgc2VsZWN0ZWQgZW50cnkgTkFNRVMuIEFjY291bnQsIG5hbWUsIGFuZCBidWNrZXQgQVJFIHRoZSBmb2xkZXIsIHNvIHRoaXMgaXMgYSBkaXJlY3QgbG9va3VwLCBuZXZlciBhIHNlYXJjaCBvZiB3aGF0IGV4aXN0cyAtIGFuZCBhIG5hbWUgdGhpcyBzZXJ2ZXIgaGFzIG5ldmVyIHNlZW4gaXMgQ1JFQVRFRCwgbmV2ZXIgcmVqZWN0ZWQsIGJlY2F1c2UgYXNraW5nIGZvciBhIG5hbWUgaXMgdGhlIGluc3RydWN0aW9uIHRvIGhhdmUgdGhhdCBzdG9yZSAob25lIG5hbWUsIG9uZSBmb2xkZXIsIG9uZSBpbmRleDsgaXQgY29uZmlndXJlcyBpdHNlbGYgb25jZSB0aGUgcm91dGluZyBjb25maWcgbGFuZHMgaW4gaXQpLiBOb3RoaW5nIGVsc2UgYWJvdXQgdGhlIHJlcXVlc3QgaXMgY29tcGFyZWQgLSBub3QgdGhlIHdpbmRvdywgbm90IHRoZSByb3V0ZSwgbm90IHRoZSBmbGFncyAtIHdoaWNoIGlzIHRoZSB3aG9sZSBwb2ludCBvZiBuYW1pbmcgaXQ6IGEgY2xpZW50IGEgY29uZmlnIHZlcnNpb24gYmVoaW5kIG9uIHNvbWUgZmxhZyBzdGlsbCByZWFjaGVzIHRoZSByaWdodCBzdG9yZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kQnVja2V0U3RvcmUoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcsIHNvdXJjZUNvbmZpZzogU291cmNlQ29uZmlnIHwgdW5kZWZpbmVkKTogQmxvYlN0b3JlIHtcbiAgICBpZiAoIXNvdXJjZUNvbmZpZykge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE5vIHJlbW90ZSBzb3VyY2UgY29uZmlndXJhdGlvbiB3YXMgcHJvdmlkZWQgZm9yIGJ1Y2tldCAke2FjY291bnR9LyR7YnVja2V0TmFtZX06IGV2ZXJ5IHJlcXVlc3QgbXVzdCBzYXkgd2hpY2ggY29uZmlndXJlZCBzb3VyY2UgaXQgc2VsZWN0ZWRgKTtcbiAgICB9XG4gICAgcmV0dXJuIGdldFN0b3JlKGFjY291bnQsIGJ1Y2tldE5hbWUsIHNvdXJjZUNvbmZpZy5uYW1lKTtcbn1cblxuLyoqIFRoZSBzdG9yZXMgb2YgYSBidWNrZXQgYXMgdGhlIERJU0sgcmVjb3JkcyB0aGVtIChhIGJ1Y2tldCBpcyBub3RoaW5nIG1vcmUgdGhhbiB0aGUgc3RvcmUgZm9sZGVycyBzaGFyaW5nIGl0cyBuYW1lKSwgb3BlbmVkIC0gc28gdGhlIG9uZXMgdGhhdCB3ZXJlbid0IHJ1bm5pbmcgeWV0IHN0YXJ0IHN5bmNocm9uaXppbmcuIEVtcHR5IHdoZW4gdGhlIGJ1Y2tldCBkb2VzIG5vdCBleGlzdCBoZXJlLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldEJ1Y2tldFN0b3JlcyhhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZyk6IFByb21pc2U8eyBuYW1lOiBzdHJpbmc7IHN0b3JlOiBCbG9iU3RvcmUgfVtdPiB7XG4gICAgbGV0IGZvbGRlcnMgPSBhd2FpdCBsaXN0QnVja2V0U3RvcmVGb2xkZXJzKGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIHJldHVybiBmb2xkZXJzLm1hcCh4ID0+ICh7IG5hbWU6IHgubmFtZSwgc3RvcmU6IGdldFN0b3JlKGFjY291bnQsIGJ1Y2tldE5hbWUsIHgubmFtZSkgfSkpO1xufVxuXG5hc3luYyBmdW5jdGlvbiByZXF1aXJlQnVja2V0U3RvcmVzKGFjY291bnQ6IHN0cmluZywgYnVja2V0TmFtZTogc3RyaW5nKTogUHJvbWlzZTx7IG5hbWU6IHN0cmluZzsgc3RvcmU6IEJsb2JTdG9yZSB9W10+IHtcbiAgICBsZXQgbGlzdCA9IGF3YWl0IGdldEJ1Y2tldFN0b3JlcyhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICBpZiAoIWxpc3QubGVuZ3RoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgQnVja2V0ICR7YWNjb3VudH0vJHtidWNrZXROYW1lfSBkb2VzIG5vdCBleGlzdCBvbiB0aGlzIHNlcnZlci4gV3JpdGUgaXRzIHJvdXRpbmcgY29uZmlnIHRvICR7SlNPTi5zdHJpbmdpZnkoUk9VVElOR19GSUxFKX0gdG8gY3JlYXRlIGl0LmApO1xuICAgIH1cbiAgICByZXR1cm4gbGlzdDtcbn1cblxuLyoqIEludGVybmFsIChzdG9yZS10by1zdG9yZSkgcmVhZHMgc2tpcCBzdG9yZSBzZWxlY3Rpb24gZW50aXJlbHk6IHRoZSBjYWxsZXIgaXMgYW5vdGhlciBzdG9yZSB3aG9zZSBpbmRleCBzYXlzIHRoaXMgTUFDSElORSBob2xkcyB0aGUgYnl0ZXMgLSB0aGUgcGVyc2lzdGVkIGhvbGRlciBpZGVudGl0eSBpcyBqdXN0IGEgVVJMLCB3aGljaCBjYW5ub3QgbmFtZSBhIHN0b3JlLiBXaGljaGV2ZXIgc3RvcmUncyBmb2xkZXIgaGFzIHRoZSBuZXdlc3QgY29weSBhbnN3ZXJzLiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlYWRCdWNrZXRJbnRlcm5hbChhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZywgY29uZmlnOiB7IHBhdGg6IHN0cmluZzsgcmFuZ2U/OiB7IHN0YXJ0OiBudW1iZXI7IGVuZDogbnVtYmVyIH07IGluY2x1ZGVUb21ic3RvbmVzPzogYm9vbGVhbiB9KTogUHJvbWlzZTx7IGRhdGE6IEJ1ZmZlcjsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkPiB7XG4gICAgbGV0IGJ1Y2tldFN0b3JlcyA9IGF3YWl0IHJlcXVpcmVCdWNrZXRTdG9yZXMoYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgbGV0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChidWNrZXRTdG9yZXMubWFwKHMgPT4gcy5zdG9yZS5nZXQyKHsgcGF0aDogY29uZmlnLnBhdGgsIHJhbmdlOiBjb25maWcucmFuZ2UsIGluY2x1ZGVUb21ic3RvbmVzOiBjb25maWcuaW5jbHVkZVRvbWJzdG9uZXMsIGludGVybmFsOiB0cnVlIH0pKSk7XG4gICAgbGV0IGJlc3Q6IHsgZGF0YTogQnVmZmVyOyB3cml0ZVRpbWU6IG51bWJlcjsgc2l6ZTogbnVtYmVyIH0gfCB1bmRlZmluZWQ7XG4gICAgZm9yIChsZXQgcmVzdWx0IG9mIHJlc3VsdHMpIHtcbiAgICAgICAgaWYgKHJlc3VsdCAmJiAoIWJlc3QgfHwgcmVzdWx0LndyaXRlVGltZSA+IGJlc3Qud3JpdGVUaW1lKSkge1xuICAgICAgICAgICAgYmVzdCA9IHJlc3VsdDtcbiAgICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYmVzdDtcbn1cblxuZnVuY3Rpb24gYWdncmVnYXRlQXJjaGl2ZXNDb25maWcoYnVja2V0U3RvcmVzOiBCbG9iU3RvcmVbXSwgcm91dGluZzogUmVtb3RlQ29uZmlnIHwgdW5kZWZpbmVkKTogQXJjaGl2ZXNDb25maWcge1xuICAgIGxldCBpbmRleCA9IHsgZmlsZUNvdW50OiAwLCBieXRlQ291bnQ6IDAgfTtcbiAgICBsZXQgaW5kZXhTb3VyY2VzOiB7IGRlYnVnTmFtZTogc3RyaW5nOyBmaWxlQ291bnQ6IG51bWJlcjsgYnl0ZUNvdW50OiBudW1iZXIgfVtdID0gW107XG4gICAgbGV0IHN5bmNpbmc6IFN5bmNBY3Rpdml0eVtdID0gW107XG4gICAgbGV0IHJlYWRlckRpc2tMaW1pdDogbnVtYmVyIHwgdW5kZWZpbmVkO1xuICAgIGZvciAobGV0IHN0b3JlIG9mIGJ1Y2tldFN0b3Jlcykge1xuICAgICAgICBsZXQgcHJvZ3Jlc3MgPSBzdG9yZS5nZXRTeW5jUHJvZ3Jlc3MoKTtcbiAgICAgICAgaW5kZXguZmlsZUNvdW50ICs9IHByb2dyZXNzLmluZGV4LmZpbGVDb3VudDtcbiAgICAgICAgaW5kZXguYnl0ZUNvdW50ICs9IHByb2dyZXNzLmluZGV4LmJ5dGVDb3VudDtcbiAgICAgICAgaW5kZXhTb3VyY2VzLnB1c2goLi4ucHJvZ3Jlc3Muc291cmNlcyk7XG4gICAgICAgIHN5bmNpbmcucHVzaCguLi5wcm9ncmVzcy5zeW5jaW5nKTtcbiAgICAgICAgcmVhZGVyRGlza0xpbWl0ID0gcmVhZGVyRGlza0xpbWl0IHx8IHByb2dyZXNzLnJlYWRlckRpc2tMaW1pdDtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgICAgLy8gRXZlcnkgc3RvcmUgaXMgaW5kZXgtYmFja2VkLCBzbyB0aGUgY2hhbmdlIGZlZWQgaXMgYWx3YXlzIG5hdGl2ZVxuICAgICAgICBzdXBwb3J0c0NoYW5nZXNBZnRlcjogdHJ1ZSxcbiAgICAgICAgcmVtb3RlQ29uZmlnOiByb3V0aW5nLFxuICAgICAgICBpbmRleCxcbiAgICAgICAgaW5kZXhTb3VyY2VzLFxuICAgICAgICByZWFkZXJEaXNrTGltaXQsXG4gICAgICAgIHN5bmNpbmcsXG4gICAgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldEJ1Y2tldEFyY2hpdmVzQ29uZmlnKGFjY291bnQ6IHN0cmluZywgYnVja2V0TmFtZTogc3RyaW5nKTogUHJvbWlzZTxBcmNoaXZlc0NvbmZpZz4ge1xuICAgIGxldCBidWNrZXRTdG9yZXMgPSBhd2FpdCByZXF1aXJlQnVja2V0U3RvcmVzKGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIGxldCByb3V0aW5nID0gYXdhaXQgcmVhZFJvdXRpbmdGcm9tRGlzayhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICByZXR1cm4gYWdncmVnYXRlQXJjaGl2ZXNDb25maWcoYnVja2V0U3RvcmVzLm1hcCh4ID0+IHguc3RvcmUpLCByb3V0aW5nKTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGJ1Y2tldFN5bmNTdGF0dXMoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcpOiBQcm9taXNlPEFyY2hpdmVzU3luY1N0YXR1cz4ge1xuICAgIGxldCBidWNrZXRTdG9yZXMgPSBhd2FpdCByZXF1aXJlQnVja2V0U3RvcmVzKGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIGxldCBzdGF0dXNlcyA9IGF3YWl0IFByb21pc2UuYWxsKGJ1Y2tldFN0b3Jlcy5tYXAocyA9PiBzLnN0b3JlLmdldFN5bmNTdGF0dXMoKSkpO1xuICAgIHJldHVybiB7XG4gICAgICAgIGFsbFNjYW5zQ29tcGxldGU6IHN0YXR1c2VzLmV2ZXJ5KHggPT4geC5hbGxTY2Fuc0NvbXBsZXRlKSxcbiAgICAgICAgaW5kZXhTaXplOiBzdGF0dXNlcy5yZWR1Y2UoKHN1bSwgeCkgPT4gc3VtICsgeC5pbmRleFNpemUsIDApLFxuICAgICAgICBzb3VyY2VzOiBzdGF0dXNlcy5mbGF0TWFwKHggPT4geC5zb3VyY2VzKSxcbiAgICB9O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVidWdCdWNrZXRJbmRleFRvdGFscyhhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZyk6IFByb21pc2U8eyBmaWxlQ291bnQ6IG51bWJlcjsgYnl0ZUNvdW50OiBudW1iZXI7IHNvdXJjZXM6IHsgZGVidWdOYW1lOiBzdHJpbmc7IGZpbGVDb3VudDogbnVtYmVyOyBieXRlQ291bnQ6IG51bWJlciB9W10gfT4ge1xuICAgIGxldCBidWNrZXRTdG9yZXMgPSBhd2FpdCByZXF1aXJlQnVja2V0U3RvcmVzKGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIGxldCB0b3RhbHMgPSBhd2FpdCBQcm9taXNlLmFsbChidWNrZXRTdG9yZXMubWFwKHMgPT4gcy5zdG9yZS5jb21wdXRlSW5kZXhUb3RhbHMoKSkpO1xuICAgIHJldHVybiB7XG4gICAgICAgIGZpbGVDb3VudDogdG90YWxzLnJlZHVjZSgoc3VtLCB4KSA9PiBzdW0gKyB4LmZpbGVDb3VudCwgMCksXG4gICAgICAgIGJ5dGVDb3VudDogdG90YWxzLnJlZHVjZSgoc3VtLCB4KSA9PiBzdW0gKyB4LmJ5dGVDb3VudCwgMCksXG4gICAgICAgIHNvdXJjZXM6IHRvdGFscy5mbGF0TWFwKHggPT4geC5zb3VyY2VzKSxcbiAgICB9O1xufVxuXG5jb25zdCByZXNvbHZlZFNvdXJjZUFyY2hpdmVzID0gbmV3IE1hcDxzdHJpbmcsIElBcmNoaXZlcz4oKTtcbi8qKiBBIGNhY2hlZCBJQXJjaGl2ZXMgZm9yIGEgcGVyc2lzdGVkIHNvdXJjZSBpZGVudGl0eTogYSByb3V0aW5nIFVSTCAoaG9zdGVkL2JhY2tibGF6ZSkgb3IgYSBkaXNrIGZvbGRlciBwYXRoIC0gdGhlIGZvcm0gQmxvYlN0b3JlJ3Mgc291cmNlcyBsaXN0IHN0b3Jlcy4gQ29uZmlndXJhdGlvbiAodmFsaWQgd2luZG93cywgcm91dGVzKSBkZWNpZGVzIFdIRU4gYSBzb3VyY2Ugc2hvdWxkIGJlIHVzZWQ7IGZvciByZWFkaW5nIGJ5dGVzIHRoZSBpbmRleCBzYXlzIGEgc291cmNlIGhvbGRzLCB0aGUgVVJMIGFsb25lIGlzIGVub3VnaCAtIGV2ZW4gZm9yIHNvdXJjZXMgbm8gbG9uZ2VyIGluIGFueSBjb25maWcuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZVNvdXJjZUFyY2hpdmVzKHVybDogc3RyaW5nKTogSUFyY2hpdmVzIHtcbiAgICBsZXQgZXhpc3RpbmcgPSByZXNvbHZlZFNvdXJjZUFyY2hpdmVzLmdldCh1cmwpO1xuICAgIGlmIChleGlzdGluZykgcmV0dXJuIGV4aXN0aW5nO1xuICAgIGxldCBzb3VyY2VDb25maWc6IFNvdXJjZUNvbmZpZyB8IHVuZGVmaW5lZDtcbiAgICBpZiAodXJsLnN0YXJ0c1dpdGgoXCJodHRwczovL1wiKSkge1xuICAgICAgICAvLyBUaGUgY29uZmlnIGlzIGZhYnJpY2F0ZWQgZnJvbSB0aGUgYmFyZSBVUkwgYW5kIGNhbiBuZXZlciBleGFjdC1tYXRjaCBhIHNlcnZlcidzIGVudHJpZXMgLSB3aGljaCBpcyBmaW5lLCBiZWNhdXNlIGhvbGRlciByZWFkcyBhcmUgaW50ZXJuYWwgcmVhZHMsIGFuZCBpbnRlcm5hbCByZWFkcyBuZXZlciBzZWxlY3QgYSBzdG9yZSAoc2VlIHJlYWRCdWNrZXRJbnRlcm5hbClcbiAgICAgICAgc291cmNlQ29uZmlnID0gbm9ybWFsaXplU291cmNlKHVybCk7XG4gICAgfVxuICAgIGxldCBhcmNoaXZlcyA9IGNyZWF0ZVN0b3JlU291cmNlKHsgc291cmNlQ29uZmlnLCBmb2xkZXI6IHVybCB9KTtcbiAgICByZXNvbHZlZFNvdXJjZUFyY2hpdmVzLnNldCh1cmwsIGFyY2hpdmVzKTtcbiAgICByZXR1cm4gYXJjaGl2ZXM7XG59XG5cbi8qKlxuICogV3JpdGluZyB0aGUgcm91dGluZyBjb25maWcgaXMgYSB3cml0ZSBsaWtlIGFueSBvdGhlcjogaXQgZ29lcyBpbnRvIGEgc3RvcmUsIGFuZCB0aGUgc3RvcmUgYXBwbGllc1xuICogaXQgdG8gaXRzZWxmIGFuZCBsZXRzIGl0cyBwZWVycyBwdWxsIGl0LiBUaGUgb25seSB0aGluZyB0aGF0IGhhcHBlbnMgaGVyZSBpcyBwaWNraW5nIFdISUNIIHN0b3JlLFxuICogYmVjYXVzZSB0aGUgd3JpdGVyIG5hbWVzIGEgc291cmNlIGFuZCBhIHNvdXJjZSBuYW1lcyBhIHN0b3JlLlxuICpcbiAqIEluLWZsaWdodCBzd2l0Y2hvdmVyIHdpbmRvd3MgYXJlIHJlLWluamVjdGVkIGZpcnN0IChzZWUgaW50ZXJtZWRpYXRlTWFuYWdlbWVudCk6IGFuIG9wZXJhdG9yJ3NcbiAqIGNvbmZpZyBrbm93cyBub3RoaW5nIGFib3V0IGEgc3dpdGNob3ZlciB0aGF0IGlzIGhhcHBlbmluZyByaWdodCBub3csIGFuZCB3cml0aW5nIGl0IGFzLWlzIHdvdWxkXG4gKiBjYW5jZWwgaXQgbWlkLWZsaWdodC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHdyaXRlUm91dGluZ0NvbmZpZyhhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBkYXRhOiBCdWZmZXIsIGNvbmZpZz86IHsgbGFzdE1vZGlmaWVkPzogbnVtYmVyIH0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhc3NlcnRXcml0ZXNBbGxvd2VkKCk7XG4gICAgbGV0IHN0b3JlID0gZ2V0U3RvcmUoYWNjb3VudCwgYnVja2V0TmFtZSwgbmFtZSk7XG4gICAgbGV0IGluY29taW5nID0gcGFyc2VSb3V0aW5nRGF0YShkYXRhKTtcbiAgICBsZXQgY3VycmVudCA9IGF3YWl0IHJlYWRSb3V0aW5nRnJvbURpc2soYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgbGV0IHN0b3JlZCA9IHJlaW5qZWN0SW50ZXJtZWRpYXRlcyhjdXJyZW50LCBpbmNvbWluZyk7XG4gICAgYXdhaXQgc3RvcmUuc2V0KHsgcGF0aDogUk9VVElOR19GSUxFLCBkYXRhOiBCdWZmZXIuZnJvbShzZXJpYWxpemVSZW1vdGVDb25maWcoc3RvcmVkKSksIGxhc3RNb2RpZmllZDogY29uZmlnPy5sYXN0TW9kaWZpZWQgfSk7XG4gICAgYnJvYWRjYXN0Um91dGluZ0NoYW5nZWQoKTtcbn1cblxuLyoqIFdoaWNoIGJ1Y2tldHMgdGhpcyBwcm9jZXNzIGN1cnJlbnRseSBoYXMgYWN0aXZlIChzb21lIHN0b3JlIG9mIHRoZWlycyB3YXMgb3BlbmVkKSAtIHdoYXQgYSBkZXBsb3kgc3VjY2Vzc29yIGFza3MgaXRzIHByZWRlY2Vzc29yIGZvciwgc28gaXQgYWN0aXZhdGVzIGV4YWN0bHkgdGhlIGJ1Y2tldHMgdGhhdCBhcmUgYWN0dWFsbHkgaW4gdXNlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldEFjdGl2ZUJ1Y2tldEtleXMoKTogeyBhY2NvdW50OiBzdHJpbmc7IGJ1Y2tldE5hbWU6IHN0cmluZyB9W10ge1xuICAgIHJldHVybiBbLi4uYWN0aXZlU3RvcmVzLmtleXMoKV0ubWFwKGtleSA9PiB7XG4gICAgICAgIGxldCBzbGFzaCA9IGtleS5pbmRleE9mKFwiL1wiKTtcbiAgICAgICAgcmV0dXJuIHsgYWNjb3VudDoga2V5LnNsaWNlKDAsIHNsYXNoKSwgYnVja2V0TmFtZToga2V5LnNsaWNlKHNsYXNoICsgMSkgfTtcbiAgICB9KTtcbn1cblxuZXhwb3J0IHR5cGUgU2VydmVyQnVja2V0SW5mbyA9IHtcbiAgICBidWNrZXROYW1lOiBzdHJpbmc7XG4gICAgYWN0aXZlOiBib29sZWFuO1xuICAgIC8qKiBXaGVyZSB0aGUgYnVja2V0J3MgZGF0YSBsaXZlcyBvbiB0aGlzIHNlcnZlciAqL1xuICAgIGZvbGRlcjogc3RyaW5nO1xuICAgIC8qKiBUaGUgZHJpdmUgdGhhdCBmb2xkZXIgaXMgb24uIEJ1Y2tldHMgc2hhcmluZyBhIGRyaXZlIHJlcG9ydCB0aGUgc2FtZSBudW1iZXJzLiAqL1xuICAgIGRpc2s/OiBCdWNrZXREaXNrSW5mbztcbiAgICBkaXNrRXJyb3I/OiBzdHJpbmc7XG4gICAgd3JpdGVTdGF0cz86IEJ1Y2tldFdyaXRlU3RhdHM7XG4gICAgY29uZmlnPzogQXJjaGl2ZXNDb25maWc7XG4gICAgZXJyb3I/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgdHlwZSBBY3RpdmVCdWNrZXRJbmZvID0ge1xuICAgIGZvbGRlcjogc3RyaW5nO1xuICAgIC8qKiBUaGUgYnVja2V0J3Mgcm91dGluZyBjb25maWcsIHRoZSBuZXdlc3QgY29weSBhbW9uZyBpdHMgc3RvcmVzLiBBYnNlbnQgd2hlbiBub25lIG9mIHRoZW0gaGFzIG9uZSB5ZXQuICovXG4gICAgcm91dGluZz86IFJlbW90ZUNvbmZpZztcbiAgICBjb25maWc6IEFyY2hpdmVzQ29uZmlnO1xufTtcblxuLyoqIFRoZSBzdGF0ZSBvZiBPTkUgYWN0aXZlIGJ1Y2tldC4gUmV0dXJucyBhbiBlcnJvciBzdHJpbmcgd2hlbiB0aGUgYnVja2V0IGlzIG5vdCBhY3RpdmUgaGVyZSwgd2hpY2ggaXMgdGhlIG5vcm1hbCBzdGF0ZSBmb3IgYSBidWNrZXQgbm90aGluZyBoYXMgYWNjZXNzZWQgc2luY2Ugc3RhcnR1cC4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWJ1Z0dldEFjdGl2ZUJ1Y2tldChhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZyk6IFByb21pc2U8QWN0aXZlQnVja2V0SW5mbyB8IHN0cmluZz4ge1xuICAgIGxldCBrZXkgPSBgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9YDtcbiAgICBsZXQgb3BlbmVkID0gYWN0aXZlU3RvcmVzLmdldChrZXkpO1xuICAgIGlmICghb3BlbmVkIHx8ICFvcGVuZWQuc2l6ZSkge1xuICAgICAgICByZXR1cm4gYEJ1Y2tldCAke2tleX0gaXMgbm90IGFjdGl2ZSBvbiB0aGlzIHNlcnZlciAoYSBidWNrZXQgYWN0aXZhdGVzIG9uIGZpcnN0IGFjY2VzcylgO1xuICAgIH1cbiAgICBsZXQgYnVja2V0U3RvcmVzID0gWy4uLm9wZW5lZC52YWx1ZXMoKV07XG4gICAgbGV0IHJvdXRpbmcgPSBhd2FpdCByZWFkUm91dGluZ0Zyb21EaXNrKGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIHJldHVybiB7IGZvbGRlcjogYnVja2V0U3RvcmVzWzBdLmZvbGRlciwgcm91dGluZywgY29uZmlnOiBhZ2dyZWdhdGVBcmNoaXZlc0NvbmZpZyhidWNrZXRTdG9yZXMsIHJvdXRpbmcpIH07XG59XG5cbi8qKiBMb2FkcyBldmVyeSBzdG9yZSBvZiBhIGJ1Y2tldCB0aGF0IGV4aXN0cyBvbiB0aGlzIHNlcnZlcidzIGRpc2sgaW50byBtZW1vcnksIHdoaWNoIHN0YXJ0cyB0aGVpciBzeW5jaHJvbml6YXRpb24gYW5kIHdpbmRvdyB0aW1lcnMsIGFuZCByZXR1cm5zIHRoZSBidWNrZXQncyBzdGF0ZS4gTm90aGluZyBpcyB3cml0dGVuIGFuZCBubyBvdGhlciBzZXJ2ZXIgaXMgY29udGFjdGVkIC0gdW5saWtlIGJ1aWxkaW5nIGFuIEFyY2hpdmVzQ2hhaW4gZm9yIGl0LCB3aGljaCB3b3VsZCBwcm9iZSBldmVyeSBzb3VyY2UgYW5kIGNvdWxkIHdyaXRlIHRoZSByb3V0aW5nIGNvbmZpZy4gQWxyZWFkeS1hY3RpdmUgYnVja2V0cyBqdXN0IHJldHVybiB0aGVpciBzdGF0ZS4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBhY3RpdmF0ZUJ1Y2tldChhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZyk6IFByb21pc2U8QWN0aXZlQnVja2V0SW5mbyB8IHN0cmluZz4ge1xuICAgIGxldCBrZXkgPSBgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9YDtcbiAgICBsZXQgd2FzQWN0aXZlID0gYWN0aXZlU3RvcmVzLmhhcyhrZXkpO1xuICAgIGxldCBidWNrZXRTdG9yZXMgPSBhd2FpdCBnZXRCdWNrZXRTdG9yZXMoYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgaWYgKCFidWNrZXRTdG9yZXMubGVuZ3RoKSB7XG4gICAgICAgIHJldHVybiBgQnVja2V0ICR7a2V5fSBkb2VzIG5vdCBleGlzdCBvbiB0aGlzIHNlcnZlciAoaXQgaGFzIG5vIHN0b3JlIGZvbGRlcnMgdW5kZXIgJHtnZXRCdWNrZXRGb2xkZXIoXCI8bmFtZT5cIiwgYWNjb3VudCwgYnVja2V0TmFtZSl9KWA7XG4gICAgfVxuICAgIC8vIFdhaXQgZm9yIHRoZSBpbmRleGVzIHRvIGxvYWQsIHNvIHRoZSB0b3RhbHMgd2UgcmV0dXJuIGFyZSB0aGUgcmVhbCBvbmVzIHJhdGhlciB0aGFuIHplcm9lcyBmcm9tIHN0b3JlcyB0aGF0IGhhdmUgbm90IHJlYWQgdGhlaXIgaW5kZXggeWV0LiBUaGUgc291cmNlIHNjYW5zIGtlZXAgcnVubmluZyBpbiB0aGUgYmFja2dyb3VuZC5cbiAgICBmb3IgKGxldCBzIG9mIGJ1Y2tldFN0b3Jlcykge1xuICAgICAgICBhd2FpdCBzLnN0b3JlLmluaXQoKTtcbiAgICB9XG4gICAgaWYgKCF3YXNBY3RpdmUpIHtcbiAgICAgICAgY29uc29sZS5sb2coYEFjdGl2YXRlZCBidWNrZXQgJHtrZXl9IG9uIHJlcXVlc3Q6IGl0cyAke2J1Y2tldFN0b3Jlcy5sZW5ndGh9IHN0b3JlKHMpIGFyZSBub3cgbG9hZGVkIGFuZCBzeW5jaHJvbml6aW5nYCk7XG4gICAgfVxuICAgIGxldCByb3V0aW5nID0gYXdhaXQgcmVhZFJvdXRpbmdGcm9tRGlzayhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICByZXR1cm4geyBmb2xkZXI6IGJ1Y2tldFN0b3Jlc1swXS5zdG9yZS5mb2xkZXIsIHJvdXRpbmcsIGNvbmZpZzogYWdncmVnYXRlQXJjaGl2ZXNDb25maWcoYnVja2V0U3RvcmVzLm1hcCh4ID0+IHguc3RvcmUpLCByb3V0aW5nKSB9O1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVidWdMaXN0QWNjb3VudEJ1Y2tldHMoYWNjb3VudDogc3RyaW5nKTogUHJvbWlzZTxTZXJ2ZXJCdWNrZXRJbmZvW10+IHtcbiAgICBsZXQgc3RhcnQgPSBEYXRlLm5vdygpO1xuICAgIC8vIFRoZSBkaXNrIGlzIHRoZSByZWNvcmQ6IGEgYnVja2V0IGV4aXN0cyBoZXJlIHdoZW4gaXQgaGFzIGF0IGxlYXN0IG9uZSBzdG9yZSBmb2xkZXIsIGFuZCBzZXZlcmFsIG5hbWVzIGZvciBvbmUgYnVja2V0IGFyZSBzdGlsbCBvbmUgYnVja2V0XG4gICAgbGV0IGZvbGRlcnMgPSBhd2FpdCBsaXN0QWNjb3VudFN0b3JlRm9sZGVycyhhY2NvdW50KTtcbiAgICBsZXQgYnlCdWNrZXQgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuICAgIGZvciAobGV0IHN0b3JlIG9mIGZvbGRlcnMpIHtcbiAgICAgICAgaWYgKGJ5QnVja2V0LmhhcyhzdG9yZS5idWNrZXROYW1lKSkgY29udGludWU7XG4gICAgICAgIGJ5QnVja2V0LnNldChzdG9yZS5idWNrZXROYW1lLCBzdG9yZS5mb2xkZXIpO1xuICAgIH1cbiAgICBsZXQgbmFtZXMgPSBbLi4uYnlCdWNrZXQua2V5cygpXTtcbiAgICB0cnkge1xuICAgICAgICByZXR1cm4gYXdhaXQgUHJvbWlzZS5hbGwobmFtZXMubWFwKGFzeW5jIGJ1Y2tldE5hbWUgPT4ge1xuICAgICAgICAgICAgbGV0IGtleSA9IGAke2FjY291bnR9LyR7YnVja2V0TmFtZX1gO1xuICAgICAgICAgICAgbGV0IGZvbGRlciA9IGJ5QnVja2V0LmdldChidWNrZXROYW1lKSB8fCBcIlwiO1xuICAgICAgICAgICAgbGV0IGJhc2U6IFNlcnZlckJ1Y2tldEluZm8gPSB7IGJ1Y2tldE5hbWUsIGFjdGl2ZTogYWN0aXZlU3RvcmVzLmhhcyhrZXkpLCBmb2xkZXIgfTtcbiAgICAgICAgICAgIGJhc2UuZGlzayA9IGF3YWl0IGdldERpc2tJbmZvKGZvbGRlcikuY2F0Y2goKGU6IEVycm9yKSA9PiB7XG4gICAgICAgICAgICAgICAgYmFzZS5kaXNrRXJyb3IgPSBTdHJpbmcoZS5zdGFjayA/PyBlKS5zbGljZSgwLCA1MDApO1xuICAgICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIGJhc2Uud3JpdGVTdGF0cyA9IGdldEJ1Y2tldFdyaXRlU3RhdHMoa2V5KTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbGV0IHJvdXRpbmcgPSBhd2FpdCByZWFkUm91dGluZ0Zyb21EaXNrKGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgICAgICAgICAgICAgIGlmIChiYXNlLmFjdGl2ZSkge1xuICAgICAgICAgICAgICAgICAgICBsZXQgb3BlbmVkID0gWy4uLihhY3RpdmVTdG9yZXMuZ2V0KGtleSk/LnZhbHVlcygpIHx8IFtdKV07XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7IC4uLmJhc2UsIGNvbmZpZzogYWdncmVnYXRlQXJjaGl2ZXNDb25maWcob3BlbmVkLCByb3V0aW5nKSB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoIXJvdXRpbmcpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHsgLi4uYmFzZSwgZXJyb3I6IGBObyByb3V0aW5nIGZpbGUgKCR7Uk9VVElOR19GSUxFfSkgaW4gYW55IG9mIGl0cyBzdG9yZXNgIH07XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHJldHVybiB7IC4uLmJhc2UsIGNvbmZpZzogeyByZW1vdGVDb25maWc6IHJvdXRpbmcgfSB9O1xuICAgICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgICAgIHJldHVybiB7IC4uLmJhc2UsIGVycm9yOiBTdHJpbmcoKGUgYXMgRXJyb3IpLnN0YWNrID8/IGUpLnNsaWNlKDAsIDUwMCkgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSkpO1xuICAgIH0gZmluYWxseSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBkZWJ1Z0xpc3RBY2NvdW50QnVja2V0cygke2FjY291bnR9KSB0b29rICR7RGF0ZS5ub3coKSAtIHN0YXJ0fW1zIGZvciAke25hbWVzLmxlbmd0aH0gYnVja2V0c2ApO1xuICAgIH1cbn1cbiJdfQ==
261
- /* _JS_SOURCE_HASH = "fc74365631c687bdfdba02f69da0ffcbce3f6e32d9a07b83aa318b993edb4bec"; */
271
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmFnZVNlcnZlclN0YXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3RvcmFnZVNlcnZlclN0YXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDJDQUF3QztBQUl4QyxpREFBd0c7QUFDeEcsaURBQXNFO0FBQ3RFLDJEQUE4RDtBQUM5RCxpREFBcUQ7QUFDckQsNkNBQXFEO0FBQ3JELDZDQUFrSjtBQUNsSixxRUFBdUY7QUFDdkYsbUVBQWdFO0FBQ2hFLHVFQUFvRTtBQUNwRSwyQ0FBMkM7QUFDM0MsK0NBQXdGO0FBRXhGOzs7OztHQUtHO0FBRUg7Ozs7R0FJRztBQUNILE1BQU0sTUFBTSxHQUFHLElBQUksR0FBRyxFQUFxQixDQUFDO0FBQzVDLCtNQUErTTtBQUMvTSxNQUFNLFlBQVksR0FBRyxJQUFJLEdBQUcsRUFBa0MsQ0FBQztBQUUvRCxTQUFnQixRQUFRLENBQUMsT0FBZSxFQUFFLFVBQWtCLEVBQUUsSUFBWSxFQUFFLFlBQXFCO0lBQzdGLDhHQUE4RztJQUM5RyxJQUFBLGtDQUFxQixFQUFDLElBQUksQ0FBQyxDQUFDO0lBQzVCLElBQUksTUFBTSxHQUFHLElBQUEsNEJBQWUsRUFBQyxJQUFJLEVBQUUsT0FBTyxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQ3hELElBQUksUUFBUSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbEMsSUFBSSxRQUFRO1FBQUUsT0FBTyxRQUFRLENBQUM7SUFDOUIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQkFBaUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsY0FBYyxPQUFPLElBQUksVUFBVSxZQUFZLE1BQU0sR0FBRyxDQUFDLENBQUM7SUFDM0csSUFBSSxLQUFLLEdBQUcsSUFBSSxxQkFBUyxDQUFDLE1BQU0sRUFBRSxJQUFJLEVBQUU7UUFDcEMsbUVBQW1FO1FBQ25FLE1BQU0sRUFBRSxNQUFNLENBQUMsRUFBRSxDQUFDLElBQUEsd0JBQVks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IGZyb20gXCIuL2Jsb2JTdG9yZVwiO1xuaW1wb3J0IHtcbiAgICBSZW1vdGVDb25maWcsIFNvdXJjZUNvbmZpZywgSUFyY2hpdmVzLCBBcmNoaXZlc0NvbmZpZywgQXJjaGl2ZXNTeW5jU3RhdHVzLCBTeW5jQWN0aXZpdHksXG59IGZyb20gXCIuLi9JQXJjaGl2ZXNcIjtcbmltcG9ydCB7IFJPVVRJTkdfRklMRSwgcGFyc2VSb3V0aW5nRGF0YSwgc2VyaWFsaXplUmVtb3RlQ29uZmlnLCBub3JtYWxpemVTb3VyY2UgfSBmcm9tIFwiLi9yZW1vdGVDb25maWdcIjtcbmltcG9ydCB7IGNyZWF0ZVN0b3JlU291cmNlLCBhcHBseVNvdXJjZUNvbmZpZyB9IGZyb20gXCIuL3N0b3JlU291cmNlc1wiO1xuaW1wb3J0IHsgYnJvYWRjYXN0Um91dGluZ0NoYW5nZWQgfSBmcm9tIFwiLi9zdG9yYWdlQ29udHJvbGxlclwiO1xuaW1wb3J0IHsgYXNzZXJ0V3JpdGVzQWxsb3dlZCB9IGZyb20gXCIuL3NlcnZlckNvbmZpZ1wiO1xuaW1wb3J0IHsgYXNzZXJ0VmFsaWRTb3VyY2VOYW1lIH0gZnJvbSBcIi4vdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgZ2V0QnVja2V0Rm9sZGVyLCBsaXN0QWNjb3VudFN0b3JlRm9sZGVycywgbGlzdEJ1Y2tldFN0b3JlRm9sZGVycywgcmVhZFJvdXRpbmdGcm9tRGlzaywgZ2V0RGlza0luZm8sIEJ1Y2tldERpc2tJbmZvIH0gZnJvbSBcIi4vYnVja2V0RGlza1wiO1xuaW1wb3J0IHsgc2NoZWR1bGVCb3VuZGFyeVdvcmssIHJlaW5qZWN0SW50ZXJtZWRpYXRlcyB9IGZyb20gXCIuL2ludGVybWVkaWF0ZU1hbmFnZW1lbnRcIjtcbmltcG9ydCB7IFNvY2tldEZ1bmN0aW9uIH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9Tb2NrZXRGdW5jdGlvblwiO1xuaW1wb3J0IHsgU3RvcmFnZUNsaWVudENvbnRyb2xsZXIgfSBmcm9tIFwiLi9zdG9yYWdlQ2xpZW50Q29udHJvbGxlclwiO1xuaW1wb3J0IHsgaXNTZWxmU291cmNlIH0gZnJvbSBcIi4vc3RvcmVQbGFuXCI7XG5pbXBvcnQgeyBjb3VudEJ1Y2tldFdyaXRlLCBnZXRCdWNrZXRXcml0ZVN0YXRzLCBCdWNrZXRXcml0ZVN0YXRzIH0gZnJvbSBcIi4vYWNjZXNzU3RhdHNcIjtcblxuLyoqXG4gKiBXaGF0IHRoaXMgc2VydmVyIEhBUzogdGhlIHN0b3JlcywgYnkgbmFtZSAoZ2V0U3RvcmUpIC0gbWFkZSBvbmNlLCBzZWxmLWNvbmZpZ3VyaW5nIGZyb20gdGhlcmUgLVxuICogYW5kIHRoZSB0aHJlZSBlbnRyeSBwb2ludHMgYSByZXF1ZXN0IHJlc29sdmVzIHRocm91Z2ggKGZpbmRCdWNrZXRTdG9yZSwgcmVhZEJ1Y2tldEludGVybmFsLFxuICogd3JpdGVSb3V0aW5nQ29uZmlnKS4gVGhlcmUgaXMgbm8gY2FjaGVkIGJ1Y2tldCBzdGF0ZTogYSBidWNrZXQgaXMgbm90aGluZyBidXQgdGhlIHN0b3JlcyB3aG9zZVxuICogZm9sZGVycyBzaGFyZSBpdHMgbmFtZSwgbGlzdGVkIG9mZiB0aGUgZGlzayB3aGVuIHNvbWV0aGluZyBnZW51aW5lbHkgbmVlZHMgYWxsIG9mIHRoZW0uXG4gKi9cblxuLyoqXG4gKiBFdmVyeSBzdG9yZSB0aGlzIHByb2Nlc3MgcnVucywgYnkgZm9sZGVyIC0gd2hpY2ggSVMgdGhlIHN0b3JlJ3MgaWRlbnRpdHk6IGFjY291bnQsIG5hbWUsIGJ1Y2tldC5cbiAqIEEgc3RvcmUgaXMgbWFkZSBvbmNlLCBjb25maWd1cmVzIGl0c2VsZiBmcm9tIHRoZSByb3V0aW5nIGNvbmZpZyBpdCBob2xkcywgYW5kIHN0YXlzOyBub3RoaW5nIGhlcmVcbiAqIGRlY2lkZXMgd2hhdCBpdCBpcywgb25seSB0aGF0IGl0IGV4aXN0cy5cbiAqL1xuY29uc3Qgc3RvcmVzID0gbmV3IE1hcDxzdHJpbmcsIEJsb2JTdG9yZT4oKTtcbi8vIFRoZSBvcGVuZWQgc3RvcmVzIG9mIGVhY2ggYCR7YWNjb3VudH0vJHtidWNrZXROYW1lfWAsIGJ5IG5hbWUgLSB3aGljaCBidWNrZXRzIGFyZSBBQ1RJVkUgKHNvbWV0aGluZyB0b3VjaGVkIHRoZW0pLCBmb3IgZGVwbG95IGhhbmRvZmZzIGFuZCB0aGUgZGVidWcgcGFnZXMuIFB1cmVseSBhIHJlZ2lzdHJ5IG9mIHdoYXQgZ2V0U3RvcmUgYWxyZWFkeSBtYWRlLlxuY29uc3QgYWN0aXZlU3RvcmVzID0gbmV3IE1hcDxzdHJpbmcsIE1hcDxzdHJpbmcsIEJsb2JTdG9yZT4+KCk7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRTdG9yZShhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZywgbmFtZTogc3RyaW5nLCBjYWxsZXJOb2RlSWQ/OiBzdHJpbmcpOiBCbG9iU3RvcmUge1xuICAgIC8vIFRoZSBvbmUgcGxhY2UgYSBuYW1lIGJlY29tZXMgYSBmb2xkZXIsIHNvIHRoZSBvbmUgcGxhY2UgaXQgaXMgdmFsaWRhdGVkIChpdCBjYW4gY29tZSBzdHJhaWdodCBvZmYgdGhlIHdpcmUpXG4gICAgYXNzZXJ0VmFsaWRTb3VyY2VOYW1lKG5hbWUpO1xuICAgIGxldCBmb2xkZXIgPSBnZXRCdWNrZXRGb2xkZXIobmFtZSwgYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgbGV0IGV4aXN0aW5nID0gc3RvcmVzLmdldChmb2xkZXIpO1xuICAgIGlmIChleGlzdGluZykgcmV0dXJuIGV4aXN0aW5nO1xuICAgIGNvbnNvbGUubG9nKGBPcGVuaW5nIHN0b3JlICR7SlNPTi5zdHJpbmdpZnkobmFtZSl9IG9mIGJ1Y2tldCAke2FjY291bnR9LyR7YnVja2V0TmFtZX0gKGZvbGRlciAke2ZvbGRlcn0pYCk7XG4gICAgbGV0IHN0b3JlID0gbmV3IEJsb2JTdG9yZShmb2xkZXIsIG5hbWUsIHtcbiAgICAgICAgLy8gV2hpY2ggZW50cmllcyBpbiBJVFMgcm91dGluZyBjb25maWcgYXJlIHRoaXMgc2VydmVyJ3MgY29weSBvZiBpdFxuICAgICAgICBpc1NlbGY6IHNvdXJjZSA9PiBpc1NlbGZTb3VyY2Uoc291cmNlLCBhY2NvdW50LCBidWNrZXROYW1lKSxcbiAgICAgICAgY3JlYXRlU291cmNlOiBjb25maWcgPT4gY3JlYXRlU3RvcmVTb3VyY2UoeyBzb3VyY2VDb25maWc6IGNvbmZpZy5zb3VyY2VDb25maWcsIGZvbGRlciwgd3JpdGVEZWxheTogY29uZmlnLndyaXRlRGVsYXkgfSksXG4gICAgICAgIGFwcGx5U291cmNlOiAoc291cmNlLCBzb3VyY2VDb25maWcsIHdyaXRlRGVsYXkpID0+IGFwcGx5U291cmNlQ29uZmlnKHNvdXJjZSwgc291cmNlQ29uZmlnLCB3cml0ZURlbGF5KSxcbiAgICAgICAgb25Xcml0ZUNvdW50ZWQ6IChraW5kLCBieXRlcykgPT4gY291bnRCdWNrZXRXcml0ZShgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9YCwga2luZCwgYnl0ZXMpLFxuICAgICAgICByZXNvbHZlU291cmNlVXJsOiByZXNvbHZlU291cmNlQXJjaGl2ZXMsXG4gICAgICAgIC8vIFRoZSBzdG9yZSBpcyB0aGUgb25lIHRoYXQga25vd3Mgd2hlbiBhIGNvbmZpZyBsYW5kZWQsIGFuZCBhIGNvbmZpZyB3aXRoIHVwY29taW5nIHdpbmRvd3MgaXMgd2hhdCBib3VuZGFyeSBzY2FucyBhcmUgYXJtZWQgZnJvbVxuICAgICAgICBvblJvdXRpbmdBcHBsaWVkOiByb3V0aW5nID0+IHNjaGVkdWxlQm91bmRhcnlXb3JrKGFjY291bnQsIGJ1Y2tldE5hbWUsIHJvdXRpbmcpLFxuICAgICAgICAvLyBUaGUgc3RvcmUgd2FzIGNyZWF0ZWQgYnkgdGhpcyBjYWxsZXIncyByZXF1ZXN0LCBzbyB0aGUgY2FsbGVyIGtub3dzIGV4YWN0bHkgd2hhdCBjb25maWcgaXQgaW50ZW5kZWQgZm9yIHRoaXMgbmFtZSAtIHRoZSBzdG9yZSBhc2tzIGl0IHdoZW4gaXRzIG93biBmb2xkZXIgaG9sZHMgbm8gY29uZmlndXJhdGlvbiAoc2VlIEJsb2JTdG9yZS5pbml0KVxuICAgICAgICByZXF1ZXN0Um91dGluZ0NvbmZpZzogY2FsbGVyTm9kZUlkICYmIChhc3luYyAoKSA9PiBhd2FpdCBTdG9yYWdlQ2xpZW50Q29udHJvbGxlci5ub2Rlc1tjYWxsZXJOb2RlSWRdLmdldFJvdXRpbmdDb25maWdGb3JOYW1lKHsgYWNjb3VudCwgYnVja2V0TmFtZSwgbmFtZSB9KSkgfHwgdW5kZWZpbmVkLFxuICAgIH0pO1xuICAgIHN0b3Jlcy5zZXQoZm9sZGVyLCBzdG9yZSk7XG4gICAgbGV0IGtleSA9IGAke2FjY291bnR9LyR7YnVja2V0TmFtZX1gO1xuICAgIGxldCBieU5hbWUgPSBhY3RpdmVTdG9yZXMuZ2V0KGtleSk7XG4gICAgaWYgKCFieU5hbWUpIHtcbiAgICAgICAgYnlOYW1lID0gbmV3IE1hcCgpO1xuICAgICAgICBhY3RpdmVTdG9yZXMuc2V0KGtleSwgYnlOYW1lKTtcbiAgICB9XG4gICAgYnlOYW1lLnNldChuYW1lLCBzdG9yZSk7XG4gICAgLy8gTGF6eSBpbml0IHdvdWxkIGxlYXZlIGEgc3RvcmUgbm90aGluZyBoYXMgdG91Y2hlZCBzaXR0aW5nIGluZXJ0IC0gbm8gaW5kZXggbG9hZGVkLCBubyBjb25maWcgYXBwbGllZCwgbm90aGluZyBzeW5jaHJvbml6aW5nIC0gd2hpbGUgaXRzIGZvbGRlciBpcyBmdWxsIG9mIGZpbGVzXG4gICAgdm9pZCBzdG9yZS5pbml0KCkuY2F0Y2goKGU6IEVycm9yKSA9PiBjb25zb2xlLmVycm9yKGBJbml0aWFsaXppbmcgc3RvcmUgJHtKU09OLnN0cmluZ2lmeShuYW1lKX0gb2YgYnVja2V0ICR7YWNjb3VudH0vJHtidWNrZXROYW1lfSBmYWlsZWQ6ICR7ZS5zdGFjayA/PyBlfWApKTtcbiAgICByZXR1cm4gc3RvcmU7XG59XG5cbi8qKiBUaGUgc3RvcmUgc2VydmluZyBhIHJlcXVlc3Q6IHRoZSBvbmUgdGhlIGNsaWVudCdzIHNlbGVjdGVkIGVudHJ5IE5BTUVTLiBBY2NvdW50LCBuYW1lLCBhbmQgYnVja2V0IEFSRSB0aGUgZm9sZGVyLCBzbyB0aGlzIGlzIGEgZGlyZWN0IGxvb2t1cCwgbmV2ZXIgYSBzZWFyY2ggb2Ygd2hhdCBleGlzdHMgLSBhbmQgYSBuYW1lIHRoaXMgc2VydmVyIGhhcyBuZXZlciBzZWVuIGlzIENSRUFURUQsIG5ldmVyIHJlamVjdGVkLCBiZWNhdXNlIGFza2luZyBmb3IgYSBuYW1lIGlzIHRoZSBpbnN0cnVjdGlvbiB0byBoYXZlIHRoYXQgc3RvcmUgKG9uZSBuYW1lLCBvbmUgZm9sZGVyLCBvbmUgaW5kZXg7IGl0IGNvbmZpZ3VyZXMgaXRzZWxmIG9uY2UgdGhlIHJvdXRpbmcgY29uZmlnIGxhbmRzIGluIGl0KS4gTm90aGluZyBlbHNlIGFib3V0IHRoZSByZXF1ZXN0IGlzIGNvbXBhcmVkIC0gbm90IHRoZSB3aW5kb3csIG5vdCB0aGUgcm91dGUsIG5vdCB0aGUgZmxhZ3MgLSB3aGljaCBpcyB0aGUgd2hvbGUgcG9pbnQgb2YgbmFtaW5nIGl0OiBhIGNsaWVudCBhIGNvbmZpZyB2ZXJzaW9uIGJlaGluZCBvbiBzb21lIGZsYWcgc3RpbGwgcmVhY2hlcyB0aGUgcmlnaHQgc3RvcmUuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZEJ1Y2tldFN0b3JlKGFjY291bnQ6IHN0cmluZywgYnVja2V0TmFtZTogc3RyaW5nLCBzb3VyY2VDb25maWc6IFNvdXJjZUNvbmZpZyB8IHVuZGVmaW5lZCk6IEJsb2JTdG9yZSB7XG4gICAgaWYgKCFzb3VyY2VDb25maWcpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBObyByZW1vdGUgc291cmNlIGNvbmZpZ3VyYXRpb24gd2FzIHByb3ZpZGVkIGZvciBidWNrZXQgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9OiBldmVyeSByZXF1ZXN0IG11c3Qgc2F5IHdoaWNoIGNvbmZpZ3VyZWQgc291cmNlIGl0IHNlbGVjdGVkYCk7XG4gICAgfVxuICAgIC8vIFRoZSBjYWxsZXIncyBpZCwgc28gYSBzdG9yZSB0aGlzIHJlcXVlc3QgQ1JFQVRFUyBjYW4gYXNrIHRoYXQgY2FsbGVyIGZvciB0aGUgY29uZmlnIGl0IGludGVuZGVkIChhIHN0b3JlIG9ubHkgZXZlciBleGlzdHMgYmVjYXVzZSBhIGNvbmZpZyBuYW1lcyBpdCwgYW5kIHRoZSByZXF1ZXN0ZXIgaG9sZHMgdGhhdCBjb25maWcpXG4gICAgbGV0IGNhbGxlck5vZGVJZDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIHRyeSB7XG4gICAgICAgIGNhbGxlck5vZGVJZCA9IFNvY2tldEZ1bmN0aW9uLmdldENhbGxlcigpPy5ub2RlSWQ7XG4gICAgfSBjYXRjaCB7IH1cbiAgICByZXR1cm4gZ2V0U3RvcmUoYWNjb3VudCwgYnVja2V0TmFtZSwgc291cmNlQ29uZmlnLm5hbWUsIGNhbGxlck5vZGVJZCk7XG59XG5cbi8qKiBUaGUgc3RvcmVzIG9mIGEgYnVja2V0IGFzIHRoZSBESVNLIHJlY29yZHMgdGhlbSAoYSBidWNrZXQgaXMgbm90aGluZyBtb3JlIHRoYW4gdGhlIHN0b3JlIGZvbGRlcnMgc2hhcmluZyBpdHMgbmFtZSksIG9wZW5lZCAtIHNvIHRoZSBvbmVzIHRoYXQgd2VyZW4ndCBydW5uaW5nIHlldCBzdGFydCBzeW5jaHJvbml6aW5nLiBFbXB0eSB3aGVuIHRoZSBidWNrZXQgZG9lcyBub3QgZXhpc3QgaGVyZS4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRCdWNrZXRTdG9yZXMoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcpOiBQcm9taXNlPHsgbmFtZTogc3RyaW5nOyBzdG9yZTogQmxvYlN0b3JlIH1bXT4ge1xuICAgIGxldCBmb2xkZXJzID0gYXdhaXQgbGlzdEJ1Y2tldFN0b3JlRm9sZGVycyhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICByZXR1cm4gZm9sZGVycy5tYXAoeCA9PiAoeyBuYW1lOiB4Lm5hbWUsIHN0b3JlOiBnZXRTdG9yZShhY2NvdW50LCBidWNrZXROYW1lLCB4Lm5hbWUpIH0pKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gcmVxdWlyZUJ1Y2tldFN0b3JlcyhhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZyk6IFByb21pc2U8eyBuYW1lOiBzdHJpbmc7IHN0b3JlOiBCbG9iU3RvcmUgfVtdPiB7XG4gICAgbGV0IGxpc3QgPSBhd2FpdCBnZXRCdWNrZXRTdG9yZXMoYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgaWYgKCFsaXN0Lmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEJ1Y2tldCAke2FjY291bnR9LyR7YnVja2V0TmFtZX0gZG9lcyBub3QgZXhpc3Qgb24gdGhpcyBzZXJ2ZXIuIFdyaXRlIGl0cyByb3V0aW5nIGNvbmZpZyB0byAke0pTT04uc3RyaW5naWZ5KFJPVVRJTkdfRklMRSl9IHRvIGNyZWF0ZSBpdC5gKTtcbiAgICB9XG4gICAgcmV0dXJuIGxpc3Q7XG59XG5cbi8qKiBJbnRlcm5hbCAoc3RvcmUtdG8tc3RvcmUpIHJlYWRzIHNraXAgc3RvcmUgc2VsZWN0aW9uIGVudGlyZWx5OiB0aGUgY2FsbGVyIGlzIGFub3RoZXIgc3RvcmUgd2hvc2UgaW5kZXggc2F5cyB0aGlzIE1BQ0hJTkUgaG9sZHMgdGhlIGJ5dGVzIC0gdGhlIHBlcnNpc3RlZCBob2xkZXIgaWRlbnRpdHkgaXMganVzdCBhIFVSTCwgd2hpY2ggY2Fubm90IG5hbWUgYSBzdG9yZS4gV2hpY2hldmVyIHN0b3JlJ3MgZm9sZGVyIGhhcyB0aGUgbmV3ZXN0IGNvcHkgYW5zd2Vycy4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZWFkQnVja2V0SW50ZXJuYWwoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcsIGNvbmZpZzogeyBwYXRoOiBzdHJpbmc7IHJhbmdlPzogeyBzdGFydDogbnVtYmVyOyBlbmQ6IG51bWJlciB9OyBpbmNsdWRlVG9tYnN0b25lcz86IGJvb2xlYW4gfSk6IFByb21pc2U8eyBkYXRhOiBCdWZmZXI7IHdyaXRlVGltZTogbnVtYmVyOyBzaXplOiBudW1iZXIgfSB8IHVuZGVmaW5lZD4ge1xuICAgIGxldCBidWNrZXRTdG9yZXMgPSBhd2FpdCByZXF1aXJlQnVja2V0U3RvcmVzKGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIGxldCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoYnVja2V0U3RvcmVzLm1hcChzID0+IHMuc3RvcmUuZ2V0Mih7IHBhdGg6IGNvbmZpZy5wYXRoLCByYW5nZTogY29uZmlnLnJhbmdlLCBpbmNsdWRlVG9tYnN0b25lczogY29uZmlnLmluY2x1ZGVUb21ic3RvbmVzLCBpbnRlcm5hbDogdHJ1ZSB9KSkpO1xuICAgIGxldCBiZXN0OiB7IGRhdGE6IEJ1ZmZlcjsgd3JpdGVUaW1lOiBudW1iZXI7IHNpemU6IG51bWJlciB9IHwgdW5kZWZpbmVkO1xuICAgIGZvciAobGV0IHJlc3VsdCBvZiByZXN1bHRzKSB7XG4gICAgICAgIGlmIChyZXN1bHQgJiYgKCFiZXN0IHx8IHJlc3VsdC53cml0ZVRpbWUgPiBiZXN0LndyaXRlVGltZSkpIHtcbiAgICAgICAgICAgIGJlc3QgPSByZXN1bHQ7XG4gICAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGJlc3Q7XG59XG5cbmZ1bmN0aW9uIGFnZ3JlZ2F0ZUFyY2hpdmVzQ29uZmlnKGJ1Y2tldFN0b3JlczogQmxvYlN0b3JlW10sIHJvdXRpbmc6IFJlbW90ZUNvbmZpZyB8IHVuZGVmaW5lZCk6IEFyY2hpdmVzQ29uZmlnIHtcbiAgICBsZXQgaW5kZXggPSB7IGZpbGVDb3VudDogMCwgYnl0ZUNvdW50OiAwIH07XG4gICAgbGV0IGluZGV4U291cmNlczogeyBkZWJ1Z05hbWU6IHN0cmluZzsgZmlsZUNvdW50OiBudW1iZXI7IGJ5dGVDb3VudDogbnVtYmVyIH1bXSA9IFtdO1xuICAgIGxldCBzeW5jaW5nOiBTeW5jQWN0aXZpdHlbXSA9IFtdO1xuICAgIGxldCByZWFkZXJEaXNrTGltaXQ6IG51bWJlciB8IHVuZGVmaW5lZDtcbiAgICBmb3IgKGxldCBzdG9yZSBvZiBidWNrZXRTdG9yZXMpIHtcbiAgICAgICAgbGV0IHByb2dyZXNzID0gc3RvcmUuZ2V0U3luY1Byb2dyZXNzKCk7XG4gICAgICAgIGluZGV4LmZpbGVDb3VudCArPSBwcm9ncmVzcy5pbmRleC5maWxlQ291bnQ7XG4gICAgICAgIGluZGV4LmJ5dGVDb3VudCArPSBwcm9ncmVzcy5pbmRleC5ieXRlQ291bnQ7XG4gICAgICAgIGluZGV4U291cmNlcy5wdXNoKC4uLnByb2dyZXNzLnNvdXJjZXMpO1xuICAgICAgICBzeW5jaW5nLnB1c2goLi4ucHJvZ3Jlc3Muc3luY2luZyk7XG4gICAgICAgIHJlYWRlckRpc2tMaW1pdCA9IHJlYWRlckRpc2tMaW1pdCB8fCBwcm9ncmVzcy5yZWFkZXJEaXNrTGltaXQ7XG4gICAgfVxuICAgIHJldHVybiB7XG4gICAgICAgIC8vIEV2ZXJ5IHN0b3JlIGlzIGluZGV4LWJhY2tlZCwgc28gdGhlIGNoYW5nZSBmZWVkIGlzIGFsd2F5cyBuYXRpdmVcbiAgICAgICAgc3VwcG9ydHNDaGFuZ2VzQWZ0ZXI6IHRydWUsXG4gICAgICAgIHJlbW90ZUNvbmZpZzogcm91dGluZyxcbiAgICAgICAgaW5kZXgsXG4gICAgICAgIGluZGV4U291cmNlcyxcbiAgICAgICAgcmVhZGVyRGlza0xpbWl0LFxuICAgICAgICBzeW5jaW5nLFxuICAgIH07XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRCdWNrZXRBcmNoaXZlc0NvbmZpZyhhY2NvdW50OiBzdHJpbmcsIGJ1Y2tldE5hbWU6IHN0cmluZyk6IFByb21pc2U8QXJjaGl2ZXNDb25maWc+IHtcbiAgICBsZXQgYnVja2V0U3RvcmVzID0gYXdhaXQgcmVxdWlyZUJ1Y2tldFN0b3JlcyhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICBsZXQgcm91dGluZyA9IGF3YWl0IHJlYWRSb3V0aW5nRnJvbURpc2soYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgcmV0dXJuIGFnZ3JlZ2F0ZUFyY2hpdmVzQ29uZmlnKGJ1Y2tldFN0b3Jlcy5tYXAoeCA9PiB4LnN0b3JlKSwgcm91dGluZyk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBidWNrZXRTeW5jU3RhdHVzKGFjY291bnQ6IHN0cmluZywgYnVja2V0TmFtZTogc3RyaW5nKTogUHJvbWlzZTxBcmNoaXZlc1N5bmNTdGF0dXM+IHtcbiAgICBsZXQgYnVja2V0U3RvcmVzID0gYXdhaXQgcmVxdWlyZUJ1Y2tldFN0b3JlcyhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICBsZXQgc3RhdHVzZXMgPSBhd2FpdCBQcm9taXNlLmFsbChidWNrZXRTdG9yZXMubWFwKHMgPT4gcy5zdG9yZS5nZXRTeW5jU3RhdHVzKCkpKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBhbGxTY2Fuc0NvbXBsZXRlOiBzdGF0dXNlcy5ldmVyeSh4ID0+IHguYWxsU2NhbnNDb21wbGV0ZSksXG4gICAgICAgIGluZGV4U2l6ZTogc3RhdHVzZXMucmVkdWNlKChzdW0sIHgpID0+IHN1bSArIHguaW5kZXhTaXplLCAwKSxcbiAgICAgICAgc291cmNlczogc3RhdHVzZXMuZmxhdE1hcCh4ID0+IHguc291cmNlcyksXG4gICAgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlYnVnQnVja2V0SW5kZXhUb3RhbHMoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcpOiBQcm9taXNlPHsgZmlsZUNvdW50OiBudW1iZXI7IGJ5dGVDb3VudDogbnVtYmVyOyBzb3VyY2VzOiB7IGRlYnVnTmFtZTogc3RyaW5nOyBmaWxlQ291bnQ6IG51bWJlcjsgYnl0ZUNvdW50OiBudW1iZXIgfVtdIH0+IHtcbiAgICBsZXQgYnVja2V0U3RvcmVzID0gYXdhaXQgcmVxdWlyZUJ1Y2tldFN0b3JlcyhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICBsZXQgdG90YWxzID0gYXdhaXQgUHJvbWlzZS5hbGwoYnVja2V0U3RvcmVzLm1hcChzID0+IHMuc3RvcmUuY29tcHV0ZUluZGV4VG90YWxzKCkpKTtcbiAgICByZXR1cm4ge1xuICAgICAgICBmaWxlQ291bnQ6IHRvdGFscy5yZWR1Y2UoKHN1bSwgeCkgPT4gc3VtICsgeC5maWxlQ291bnQsIDApLFxuICAgICAgICBieXRlQ291bnQ6IHRvdGFscy5yZWR1Y2UoKHN1bSwgeCkgPT4gc3VtICsgeC5ieXRlQ291bnQsIDApLFxuICAgICAgICBzb3VyY2VzOiB0b3RhbHMuZmxhdE1hcCh4ID0+IHguc291cmNlcyksXG4gICAgfTtcbn1cblxuY29uc3QgcmVzb2x2ZWRTb3VyY2VBcmNoaXZlcyA9IG5ldyBNYXA8c3RyaW5nLCBJQXJjaGl2ZXM+KCk7XG4vKiogQSBjYWNoZWQgSUFyY2hpdmVzIGZvciBhIHBlcnNpc3RlZCBzb3VyY2UgaWRlbnRpdHk6IGEgcm91dGluZyBVUkwgKGhvc3RlZC9iYWNrYmxhemUpIG9yIGEgZGlzayBmb2xkZXIgcGF0aCAtIHRoZSBmb3JtIEJsb2JTdG9yZSdzIHNvdXJjZXMgbGlzdCBzdG9yZXMuIENvbmZpZ3VyYXRpb24gKHZhbGlkIHdpbmRvd3MsIHJvdXRlcykgZGVjaWRlcyBXSEVOIGEgc291cmNlIHNob3VsZCBiZSB1c2VkOyBmb3IgcmVhZGluZyBieXRlcyB0aGUgaW5kZXggc2F5cyBhIHNvdXJjZSBob2xkcywgdGhlIFVSTCBhbG9uZSBpcyBlbm91Z2ggLSBldmVuIGZvciBzb3VyY2VzIG5vIGxvbmdlciBpbiBhbnkgY29uZmlnLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVTb3VyY2VBcmNoaXZlcyh1cmw6IHN0cmluZyk6IElBcmNoaXZlcyB7XG4gICAgbGV0IGV4aXN0aW5nID0gcmVzb2x2ZWRTb3VyY2VBcmNoaXZlcy5nZXQodXJsKTtcbiAgICBpZiAoZXhpc3RpbmcpIHJldHVybiBleGlzdGluZztcbiAgICBsZXQgc291cmNlQ29uZmlnOiBTb3VyY2VDb25maWcgfCB1bmRlZmluZWQ7XG4gICAgaWYgKHVybC5zdGFydHNXaXRoKFwiaHR0cHM6Ly9cIikpIHtcbiAgICAgICAgLy8gVGhlIGNvbmZpZyBpcyBmYWJyaWNhdGVkIGZyb20gdGhlIGJhcmUgVVJMIGFuZCBjYW4gbmV2ZXIgZXhhY3QtbWF0Y2ggYSBzZXJ2ZXIncyBlbnRyaWVzIC0gd2hpY2ggaXMgZmluZSwgYmVjYXVzZSBob2xkZXIgcmVhZHMgYXJlIGludGVybmFsIHJlYWRzLCBhbmQgaW50ZXJuYWwgcmVhZHMgbmV2ZXIgc2VsZWN0IGEgc3RvcmUgKHNlZSByZWFkQnVja2V0SW50ZXJuYWwpXG4gICAgICAgIHNvdXJjZUNvbmZpZyA9IG5vcm1hbGl6ZVNvdXJjZSh1cmwpO1xuICAgIH1cbiAgICBsZXQgYXJjaGl2ZXMgPSBjcmVhdGVTdG9yZVNvdXJjZSh7IHNvdXJjZUNvbmZpZywgZm9sZGVyOiB1cmwgfSk7XG4gICAgcmVzb2x2ZWRTb3VyY2VBcmNoaXZlcy5zZXQodXJsLCBhcmNoaXZlcyk7XG4gICAgcmV0dXJuIGFyY2hpdmVzO1xufVxuXG4vKipcbiAqIFdyaXRpbmcgdGhlIHJvdXRpbmcgY29uZmlnIGlzIGEgd3JpdGUgbGlrZSBhbnkgb3RoZXI6IGl0IGdvZXMgaW50byBhIHN0b3JlLCBhbmQgdGhlIHN0b3JlIGFwcGxpZXNcbiAqIGl0IHRvIGl0c2VsZiBhbmQgbGV0cyBpdHMgcGVlcnMgcHVsbCBpdC4gVGhlIG9ubHkgdGhpbmcgdGhhdCBoYXBwZW5zIGhlcmUgaXMgcGlja2luZyBXSElDSCBzdG9yZSxcbiAqIGJlY2F1c2UgdGhlIHdyaXRlciBuYW1lcyBhIHNvdXJjZSBhbmQgYSBzb3VyY2UgbmFtZXMgYSBzdG9yZS5cbiAqXG4gKiBJbi1mbGlnaHQgc3dpdGNob3ZlciB3aW5kb3dzIGFyZSByZS1pbmplY3RlZCBmaXJzdCAoc2VlIGludGVybWVkaWF0ZU1hbmFnZW1lbnQpOiBhbiBvcGVyYXRvcidzXG4gKiBjb25maWcga25vd3Mgbm90aGluZyBhYm91dCBhIHN3aXRjaG92ZXIgdGhhdCBpcyBoYXBwZW5pbmcgcmlnaHQgbm93LCBhbmQgd3JpdGluZyBpdCBhcy1pcyB3b3VsZFxuICogY2FuY2VsIGl0IG1pZC1mbGlnaHQuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3cml0ZVJvdXRpbmdDb25maWcoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcsIG5hbWU6IHN0cmluZywgZGF0YTogQnVmZmVyLCBjb25maWc/OiB7IGxhc3RNb2RpZmllZD86IG51bWJlciB9KTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXNzZXJ0V3JpdGVzQWxsb3dlZCgpO1xuICAgIGxldCBzdG9yZSA9IGdldFN0b3JlKGFjY291bnQsIGJ1Y2tldE5hbWUsIG5hbWUpO1xuICAgIGxldCBpbmNvbWluZyA9IHBhcnNlUm91dGluZ0RhdGEoZGF0YSk7XG4gICAgbGV0IGN1cnJlbnQgPSBhd2FpdCByZWFkUm91dGluZ0Zyb21EaXNrKGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIGxldCBzdG9yZWQgPSByZWluamVjdEludGVybWVkaWF0ZXMoY3VycmVudCwgaW5jb21pbmcpO1xuICAgIGF3YWl0IHN0b3JlLnNldCh7IHBhdGg6IFJPVVRJTkdfRklMRSwgZGF0YTogQnVmZmVyLmZyb20oc2VyaWFsaXplUmVtb3RlQ29uZmlnKHN0b3JlZCkpLCBsYXN0TW9kaWZpZWQ6IGNvbmZpZz8ubGFzdE1vZGlmaWVkIH0pO1xuICAgIGJyb2FkY2FzdFJvdXRpbmdDaGFuZ2VkKCk7XG59XG5cbi8qKiBXaGljaCBidWNrZXRzIHRoaXMgcHJvY2VzcyBjdXJyZW50bHkgaGFzIGFjdGl2ZSAoc29tZSBzdG9yZSBvZiB0aGVpcnMgd2FzIG9wZW5lZCkgLSB3aGF0IGEgZGVwbG95IHN1Y2Nlc3NvciBhc2tzIGl0cyBwcmVkZWNlc3NvciBmb3IsIHNvIGl0IGFjdGl2YXRlcyBleGFjdGx5IHRoZSBidWNrZXRzIHRoYXQgYXJlIGFjdHVhbGx5IGluIHVzZS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRBY3RpdmVCdWNrZXRLZXlzKCk6IHsgYWNjb3VudDogc3RyaW5nOyBidWNrZXROYW1lOiBzdHJpbmcgfVtdIHtcbiAgICByZXR1cm4gWy4uLmFjdGl2ZVN0b3Jlcy5rZXlzKCldLm1hcChrZXkgPT4ge1xuICAgICAgICBsZXQgc2xhc2ggPSBrZXkuaW5kZXhPZihcIi9cIik7XG4gICAgICAgIHJldHVybiB7IGFjY291bnQ6IGtleS5zbGljZSgwLCBzbGFzaCksIGJ1Y2tldE5hbWU6IGtleS5zbGljZShzbGFzaCArIDEpIH07XG4gICAgfSk7XG59XG5cbmV4cG9ydCB0eXBlIFNlcnZlckJ1Y2tldEluZm8gPSB7XG4gICAgYnVja2V0TmFtZTogc3RyaW5nO1xuICAgIGFjdGl2ZTogYm9vbGVhbjtcbiAgICAvKiogV2hlcmUgdGhlIGJ1Y2tldCdzIGRhdGEgbGl2ZXMgb24gdGhpcyBzZXJ2ZXIgKi9cbiAgICBmb2xkZXI6IHN0cmluZztcbiAgICAvKiogVGhlIGRyaXZlIHRoYXQgZm9sZGVyIGlzIG9uLiBCdWNrZXRzIHNoYXJpbmcgYSBkcml2ZSByZXBvcnQgdGhlIHNhbWUgbnVtYmVycy4gKi9cbiAgICBkaXNrPzogQnVja2V0RGlza0luZm87XG4gICAgZGlza0Vycm9yPzogc3RyaW5nO1xuICAgIHdyaXRlU3RhdHM/OiBCdWNrZXRXcml0ZVN0YXRzO1xuICAgIGNvbmZpZz86IEFyY2hpdmVzQ29uZmlnO1xuICAgIGVycm9yPzogc3RyaW5nO1xufTtcblxuZXhwb3J0IHR5cGUgQWN0aXZlQnVja2V0SW5mbyA9IHtcbiAgICBmb2xkZXI6IHN0cmluZztcbiAgICAvKiogVGhlIGJ1Y2tldCdzIHJvdXRpbmcgY29uZmlnLCB0aGUgbmV3ZXN0IGNvcHkgYW1vbmcgaXRzIHN0b3Jlcy4gQWJzZW50IHdoZW4gbm9uZSBvZiB0aGVtIGhhcyBvbmUgeWV0LiAqL1xuICAgIHJvdXRpbmc/OiBSZW1vdGVDb25maWc7XG4gICAgY29uZmlnOiBBcmNoaXZlc0NvbmZpZztcbn07XG5cbi8qKiBUaGUgc3RhdGUgb2YgT05FIGFjdGl2ZSBidWNrZXQuIFJldHVybnMgYW4gZXJyb3Igc3RyaW5nIHdoZW4gdGhlIGJ1Y2tldCBpcyBub3QgYWN0aXZlIGhlcmUsIHdoaWNoIGlzIHRoZSBub3JtYWwgc3RhdGUgZm9yIGEgYnVja2V0IG5vdGhpbmcgaGFzIGFjY2Vzc2VkIHNpbmNlIHN0YXJ0dXAuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVidWdHZXRBY3RpdmVCdWNrZXQoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcpOiBQcm9taXNlPEFjdGl2ZUJ1Y2tldEluZm8gfCBzdHJpbmc+IHtcbiAgICBsZXQga2V5ID0gYCR7YWNjb3VudH0vJHtidWNrZXROYW1lfWA7XG4gICAgbGV0IG9wZW5lZCA9IGFjdGl2ZVN0b3Jlcy5nZXQoa2V5KTtcbiAgICBpZiAoIW9wZW5lZCB8fCAhb3BlbmVkLnNpemUpIHtcbiAgICAgICAgcmV0dXJuIGBCdWNrZXQgJHtrZXl9IGlzIG5vdCBhY3RpdmUgb24gdGhpcyBzZXJ2ZXIgKGEgYnVja2V0IGFjdGl2YXRlcyBvbiBmaXJzdCBhY2Nlc3MpYDtcbiAgICB9XG4gICAgbGV0IGJ1Y2tldFN0b3JlcyA9IFsuLi5vcGVuZWQudmFsdWVzKCldO1xuICAgIGxldCByb3V0aW5nID0gYXdhaXQgcmVhZFJvdXRpbmdGcm9tRGlzayhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICByZXR1cm4geyBmb2xkZXI6IGJ1Y2tldFN0b3Jlc1swXS5mb2xkZXIsIHJvdXRpbmcsIGNvbmZpZzogYWdncmVnYXRlQXJjaGl2ZXNDb25maWcoYnVja2V0U3RvcmVzLCByb3V0aW5nKSB9O1xufVxuXG4vKiogTG9hZHMgZXZlcnkgc3RvcmUgb2YgYSBidWNrZXQgdGhhdCBleGlzdHMgb24gdGhpcyBzZXJ2ZXIncyBkaXNrIGludG8gbWVtb3J5LCB3aGljaCBzdGFydHMgdGhlaXIgc3luY2hyb25pemF0aW9uIGFuZCB3aW5kb3cgdGltZXJzLCBhbmQgcmV0dXJucyB0aGUgYnVja2V0J3Mgc3RhdGUuIE5vdGhpbmcgaXMgd3JpdHRlbiBhbmQgbm8gb3RoZXIgc2VydmVyIGlzIGNvbnRhY3RlZCAtIHVubGlrZSBidWlsZGluZyBhbiBBcmNoaXZlc0NoYWluIGZvciBpdCwgd2hpY2ggd291bGQgcHJvYmUgZXZlcnkgc291cmNlIGFuZCBjb3VsZCB3cml0ZSB0aGUgcm91dGluZyBjb25maWcuIEFscmVhZHktYWN0aXZlIGJ1Y2tldHMganVzdCByZXR1cm4gdGhlaXIgc3RhdGUuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gYWN0aXZhdGVCdWNrZXQoYWNjb3VudDogc3RyaW5nLCBidWNrZXROYW1lOiBzdHJpbmcpOiBQcm9taXNlPEFjdGl2ZUJ1Y2tldEluZm8gfCBzdHJpbmc+IHtcbiAgICBsZXQga2V5ID0gYCR7YWNjb3VudH0vJHtidWNrZXROYW1lfWA7XG4gICAgbGV0IHdhc0FjdGl2ZSA9IGFjdGl2ZVN0b3Jlcy5oYXMoa2V5KTtcbiAgICBsZXQgYnVja2V0U3RvcmVzID0gYXdhaXQgZ2V0QnVja2V0U3RvcmVzKGFjY291bnQsIGJ1Y2tldE5hbWUpO1xuICAgIGlmICghYnVja2V0U3RvcmVzLmxlbmd0aCkge1xuICAgICAgICByZXR1cm4gYEJ1Y2tldCAke2tleX0gZG9lcyBub3QgZXhpc3Qgb24gdGhpcyBzZXJ2ZXIgKGl0IGhhcyBubyBzdG9yZSBmb2xkZXJzIHVuZGVyICR7Z2V0QnVja2V0Rm9sZGVyKFwiPG5hbWU+XCIsIGFjY291bnQsIGJ1Y2tldE5hbWUpfSlgO1xuICAgIH1cbiAgICAvLyBXYWl0IGZvciB0aGUgaW5kZXhlcyB0byBsb2FkLCBzbyB0aGUgdG90YWxzIHdlIHJldHVybiBhcmUgdGhlIHJlYWwgb25lcyByYXRoZXIgdGhhbiB6ZXJvZXMgZnJvbSBzdG9yZXMgdGhhdCBoYXZlIG5vdCByZWFkIHRoZWlyIGluZGV4IHlldC4gVGhlIHNvdXJjZSBzY2FucyBrZWVwIHJ1bm5pbmcgaW4gdGhlIGJhY2tncm91bmQuXG4gICAgZm9yIChsZXQgcyBvZiBidWNrZXRTdG9yZXMpIHtcbiAgICAgICAgYXdhaXQgcy5zdG9yZS5pbml0KCk7XG4gICAgfVxuICAgIGlmICghd2FzQWN0aXZlKSB7XG4gICAgICAgIGNvbnNvbGUubG9nKGBBY3RpdmF0ZWQgYnVja2V0ICR7a2V5fSBvbiByZXF1ZXN0OiBpdHMgJHtidWNrZXRTdG9yZXMubGVuZ3RofSBzdG9yZShzKSBhcmUgbm93IGxvYWRlZCBhbmQgc3luY2hyb25pemluZ2ApO1xuICAgIH1cbiAgICBsZXQgcm91dGluZyA9IGF3YWl0IHJlYWRSb3V0aW5nRnJvbURpc2soYWNjb3VudCwgYnVja2V0TmFtZSk7XG4gICAgcmV0dXJuIHsgZm9sZGVyOiBidWNrZXRTdG9yZXNbMF0uc3RvcmUuZm9sZGVyLCByb3V0aW5nLCBjb25maWc6IGFnZ3JlZ2F0ZUFyY2hpdmVzQ29uZmlnKGJ1Y2tldFN0b3Jlcy5tYXAoeCA9PiB4LnN0b3JlKSwgcm91dGluZykgfTtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlYnVnTGlzdEFjY291bnRCdWNrZXRzKGFjY291bnQ6IHN0cmluZyk6IFByb21pc2U8U2VydmVyQnVja2V0SW5mb1tdPiB7XG4gICAgbGV0IHN0YXJ0ID0gRGF0ZS5ub3coKTtcbiAgICAvLyBUaGUgZGlzayBpcyB0aGUgcmVjb3JkOiBhIGJ1Y2tldCBleGlzdHMgaGVyZSB3aGVuIGl0IGhhcyBhdCBsZWFzdCBvbmUgc3RvcmUgZm9sZGVyLCBhbmQgc2V2ZXJhbCBuYW1lcyBmb3Igb25lIGJ1Y2tldCBhcmUgc3RpbGwgb25lIGJ1Y2tldFxuICAgIGxldCBmb2xkZXJzID0gYXdhaXQgbGlzdEFjY291bnRTdG9yZUZvbGRlcnMoYWNjb3VudCk7XG4gICAgbGV0IGJ5QnVja2V0ID0gbmV3IE1hcDxzdHJpbmcsIHN0cmluZz4oKTtcbiAgICBmb3IgKGxldCBzdG9yZSBvZiBmb2xkZXJzKSB7XG4gICAgICAgIGlmIChieUJ1Y2tldC5oYXMoc3RvcmUuYnVja2V0TmFtZSkpIGNvbnRpbnVlO1xuICAgICAgICBieUJ1Y2tldC5zZXQoc3RvcmUuYnVja2V0TmFtZSwgc3RvcmUuZm9sZGVyKTtcbiAgICB9XG4gICAgbGV0IG5hbWVzID0gWy4uLmJ5QnVja2V0LmtleXMoKV07XG4gICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IFByb21pc2UuYWxsKG5hbWVzLm1hcChhc3luYyBidWNrZXROYW1lID0+IHtcbiAgICAgICAgICAgIGxldCBrZXkgPSBgJHthY2NvdW50fS8ke2J1Y2tldE5hbWV9YDtcbiAgICAgICAgICAgIGxldCBmb2xkZXIgPSBieUJ1Y2tldC5nZXQoYnVja2V0TmFtZSkgfHwgXCJcIjtcbiAgICAgICAgICAgIGxldCBiYXNlOiBTZXJ2ZXJCdWNrZXRJbmZvID0geyBidWNrZXROYW1lLCBhY3RpdmU6IGFjdGl2ZVN0b3Jlcy5oYXMoa2V5KSwgZm9sZGVyIH07XG4gICAgICAgICAgICBiYXNlLmRpc2sgPSBhd2FpdCBnZXREaXNrSW5mbyhmb2xkZXIpLmNhdGNoKChlOiBFcnJvcikgPT4ge1xuICAgICAgICAgICAgICAgIGJhc2UuZGlza0Vycm9yID0gU3RyaW5nKGUuc3RhY2sgPz8gZSkuc2xpY2UoMCwgNTAwKTtcbiAgICAgICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBiYXNlLndyaXRlU3RhdHMgPSBnZXRCdWNrZXRXcml0ZVN0YXRzKGtleSk7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGxldCByb3V0aW5nID0gYXdhaXQgcmVhZFJvdXRpbmdGcm9tRGlzayhhY2NvdW50LCBidWNrZXROYW1lKTtcbiAgICAgICAgICAgICAgICBpZiAoYmFzZS5hY3RpdmUpIHtcbiAgICAgICAgICAgICAgICAgICAgbGV0IG9wZW5lZCA9IFsuLi4oYWN0aXZlU3RvcmVzLmdldChrZXkpPy52YWx1ZXMoKSB8fCBbXSldO1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4geyAuLi5iYXNlLCBjb25maWc6IGFnZ3JlZ2F0ZUFyY2hpdmVzQ29uZmlnKG9wZW5lZCwgcm91dGluZykgfTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKCFyb3V0aW5nKSB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB7IC4uLmJhc2UsIGVycm9yOiBgTm8gcm91dGluZyBmaWxlICgke1JPVVRJTkdfRklMRX0pIGluIGFueSBvZiBpdHMgc3RvcmVzYCB9O1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICByZXR1cm4geyAuLi5iYXNlLCBjb25maWc6IHsgcmVtb3RlQ29uZmlnOiByb3V0aW5nIH0gfTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICAgICAgICByZXR1cm4geyAuLi5iYXNlLCBlcnJvcjogU3RyaW5nKChlIGFzIEVycm9yKS5zdGFjayA/PyBlKS5zbGljZSgwLCA1MDApIH07XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgICBjb25zb2xlLmxvZyhgZGVidWdMaXN0QWNjb3VudEJ1Y2tldHMoJHthY2NvdW50fSkgdG9vayAke0RhdGUubm93KCkgLSBzdGFydH1tcyBmb3IgJHtuYW1lcy5sZW5ndGh9IGJ1Y2tldHNgKTtcbiAgICB9XG59XG4iXX0=
272
+ /* _JS_SOURCE_HASH = "ef365f1af12c4104ea625baa65c7d68910a5acf5d8e70e7de958bba523cedded"; */
@@ -14,6 +14,11 @@ class StoreConfig {
14
14
  /** The routing config changed. Same store either way: its name did not change, so neither did its folder, its index, or the data in it. */
15
15
  /** No entries is a real state, not an error: a store exists as soon as its folder does, and it may never have heard of a configuration (see StorePolicy). */
16
16
  update(entries) {
17
+ // Never go from configured back to UNCONFIGURED: keep the last configuration that worked. There is no point in emptying it - if this store was genuinely removed from the config, nobody will request it again, and the stale entries are not worth cleaning up (they are tiny, named stores are rarely removed, and a service restart clears them eventually). Keeping them is REQUIRED for the out-of-sync cases: a bad config that stops naming us would otherwise leave the store rejecting every write, including the ones that would let the configuration converge - it just won't update until a restart, and a restart can't complete against an out-of-date configuration, which is an infinite loop.
18
+ if (!entries.length && this.entries.length) {
19
+ console.warn(`Ignoring a routing config update that would leave store ${JSON.stringify(this.name)} with NO entries: keeping its current ${this.entries.length} entr${this.entries.length === 1 && "y" || "ies"} ${JSON.stringify(this.entries.map(x => ({ validWindow: x.validWindow, route: x.route })))}`);
20
+ return;
21
+ }
17
22
  let ordered = [...entries];
18
23
  (0, misc_1.sort)(ordered, x => x.validWindow[0]);
19
24
  this.entries = ordered;
@@ -48,5 +53,5 @@ class StoreConfig {
48
53
  exports.StoreConfig = StoreConfig;
49
54
  // A store nobody has configured: always valid, the whole key space, no delays and no limits. Every one of these is the answer that does the least - it holds its own data and nothing else happens to it - which is what makes a store usable before it has ever seen a config.
50
55
  const UNCONFIGURED = { validWindow: IArchives_1.FULL_VALID_WINDOW };
51
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmVDb25maWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzdG9yZUNvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtREFBZ0Q7QUFDaEQsNENBQStEO0FBRS9ELDJZQUEyWTtBQUUzWSxNQUFhLFdBQVc7SUFDcEIsWUFDb0IsSUFBWSxFQUM1QixPQUF1QjtRQURQLFNBQUksR0FBSixJQUFJLENBQVE7UUFNaEMsc0tBQXNLO1FBQzlKLFlBQU8sR0FBbUIsRUFBRSxDQUFDO1FBSmpDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUtELDJJQUEySTtJQUMzSSw2SkFBNko7SUFDdEosTUFBTSxDQUFDLE9BQXVCO1FBQ2pDLElBQUksT0FBTyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUMzQixJQUFBLFdBQUksRUFBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDM0IsQ0FBQztJQUVNLEdBQUc7UUFDTixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDeEIsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLE9BQU87UUFDVixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDckIsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNGLElBQUksVUFBVTtZQUFFLE9BQU8sVUFBVSxDQUFDO1FBQ2xDLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUM5RCxJQUFJLFFBQVE7WUFBRSxPQUFPLFFBQVEsQ0FBQztRQUM5QixJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2pELElBQUksSUFBSTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ3RCLE9BQU8sWUFBWSxDQUFDO0lBQ3hCLENBQUM7Q0FDSjtBQTNDRCxrQ0EyQ0M7QUFjRCxnUkFBZ1I7QUFDaFIsTUFBTSxZQUFZLEdBQWdCLEVBQUUsV0FBVyxFQUFFLDZCQUFpQixFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBzb3J0IH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvbWlzY1wiO1xuaW1wb3J0IHsgSG9zdGVkQ29uZmlnLCBGVUxMX1ZBTElEX1dJTkRPVyB9IGZyb20gXCIuLi9JQXJjaGl2ZXNcIjtcblxuLy8gVGhlIGNvbmZpZ3VyYXRpb24gb2YgT05FIHN0b3JlLCBrZXB0IGN1cnJlbnQuIEEgc3RvcmUgaXMgbmFtZWQgYnkgaXRzIGVudHJpZXMgKHNlZSBDb21tb25Db25maWcubmFtZSksIGFuZCBhdCBhbnkgaW5zdGFudCBleGFjdGx5IG9uZSBvZiB0aGVtIGlzIGluIGVmZmVjdCAtIHRoZSBjb25maWcgd3JpdGUgcGF0aCBlbmZvcmNlcyB0aGF0IC0gc28gXCJ0aGUgY29uZmlndXJhdGlvbiBvZiB0aGlzIHN0b3JlIHJpZ2h0IG5vd1wiIGlzIGEgc2luZ2xlIGVudHJ5LCBhbmQgZXZlcnl0aGluZyB0aGUgc3RvcmUgZG9lcyB3aXRoIHJvdXRlcywgZmxhZ3MgYW5kIGxpbWl0cyByZWFkcyBpdCBmcm9tIGhlcmUgcmF0aGVyIHRoYW4gYmVpbmcgaGFuZGVkIGEgc25hcHNob3QgdGhhdCBnb2VzIHN0YWxlLlxuXG5leHBvcnQgY2xhc3MgU3RvcmVDb25maWcge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogc3RyaW5nLFxuICAgICAgICBlbnRyaWVzOiBIb3N0ZWRDb25maWdbXSxcbiAgICApIHtcbiAgICAgICAgdGhpcy51cGRhdGUoZW50cmllcyk7XG4gICAgfVxuXG4gICAgLy8gRXZlcnkgZW50cnkgbmFtaW5nIHRoaXMgc3RvcmUsIG9sZGVzdCB3aW5kb3cgZmlyc3QgLSBwYXN0IG9uZXMgaW5jbHVkZWQsIGJlY2F1c2UgYSBzdGFtcGVkIHdyaXRlIG9yIGEgc2NhbiBjYW4gbGVnaXRpbWF0ZWx5IGNvbmNlcm4gYSB3aW5kb3cgdGhhdCBoYXMgYWxyZWFkeSBlbmRlZFxuICAgIHByaXZhdGUgZW50cmllczogSG9zdGVkQ29uZmlnW10gPSBbXTtcblxuICAgIC8qKiBUaGUgcm91dGluZyBjb25maWcgY2hhbmdlZC4gU2FtZSBzdG9yZSBlaXRoZXIgd2F5OiBpdHMgbmFtZSBkaWQgbm90IGNoYW5nZSwgc28gbmVpdGhlciBkaWQgaXRzIGZvbGRlciwgaXRzIGluZGV4LCBvciB0aGUgZGF0YSBpbiBpdC4gKi9cbiAgICAvKiogTm8gZW50cmllcyBpcyBhIHJlYWwgc3RhdGUsIG5vdCBhbiBlcnJvcjogYSBzdG9yZSBleGlzdHMgYXMgc29vbiBhcyBpdHMgZm9sZGVyIGRvZXMsIGFuZCBpdCBtYXkgbmV2ZXIgaGF2ZSBoZWFyZCBvZiBhIGNvbmZpZ3VyYXRpb24gKHNlZSBTdG9yZVBvbGljeSkuICovXG4gICAgcHVibGljIHVwZGF0ZShlbnRyaWVzOiBIb3N0ZWRDb25maWdbXSk6IHZvaWQge1xuICAgICAgICBsZXQgb3JkZXJlZCA9IFsuLi5lbnRyaWVzXTtcbiAgICAgICAgc29ydChvcmRlcmVkLCB4ID0+IHgudmFsaWRXaW5kb3dbMF0pO1xuICAgICAgICB0aGlzLmVudHJpZXMgPSBvcmRlcmVkO1xuICAgIH1cblxuICAgIHB1YmxpYyBhbGwoKTogSG9zdGVkQ29uZmlnW10ge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnRyaWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoYXQgdGhpcyBzdG9yZSBpcyBjb25maWd1cmVkIHRvIGJlIHJpZ2h0IG5vdzogdGhlIGVudHJ5IHdob3NlIHdpbmRvdyBjb250YWlucyB0aGlzIG1vbWVudDtcbiAgICAgKiBmYWlsaW5nIHRoYXQgdGhlIG5leHQgb25lIGR1ZSB0byBzdGFydDsgZmFpbGluZyB0aGF0IHRoZSBsYXN0IG9uZSB0byBoYXZlIGVuZGVkLlxuICAgICAqXG4gICAgICogVGhlcmUgaXMgYWx3YXlzIGFuIGFuc3dlciwgYW5kIGl0IG1hdHRlcnMgdGhhdCB0aGVyZSBpczogYSBzdG9yZSBiZXR3ZWVuIHdpbmRvd3Mgc3RpbGwgaG9sZHNcbiAgICAgKiBkYXRhIGFuZCBzdGlsbCBoYXMgdG8gYW5zd2VyIGZvciBpdCwgc28gaXQgbmVlZHMgYSByb3V0ZSBhbmQgZmxhZ3MgZXZlbiB3aGVuIG5vdGhpbmcgaXNcbiAgICAgKiBjdXJyZW50bHkgcG9pbnRpbmcgd3JpdGVzIGF0IGl0LiBXaGljaCBvZiB0aGUgdGhyZWUgY2FzZXMgcHJvZHVjZWQgdGhlIGFuc3dlciBpcyBkZWxpYmVyYXRlbHlcbiAgICAgKiBub3QgZXhwb3NlZCAtIHRoZSB2YWxpZCB3aW5kb3cgaXRzZWxmIGlzIHdoYXQgc2F5cyB3aGV0aGVyIHdyaXRlcyBiZWxvbmcgaGVyZSwgYW5kIGV2ZXJ5IHdyaXRlXG4gICAgICogaXMgY2hlY2tlZCBhZ2FpbnN0IGl0IHNlcGFyYXRlbHkuXG4gICAgICovXG4gICAgcHVibGljIGN1cnJlbnQoKTogU3RvcmVQb2xpY3kge1xuICAgICAgICBsZXQgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgbGV0IGNvbnRhaW5pbmcgPSB0aGlzLmVudHJpZXMuZmluZCh4ID0+IHgudmFsaWRXaW5kb3dbMF0gPD0gbm93ICYmIG5vdyA8IHgudmFsaWRXaW5kb3dbMV0pO1xuICAgICAgICBpZiAoY29udGFpbmluZykgcmV0dXJuIGNvbnRhaW5pbmc7XG4gICAgICAgIGxldCB1cGNvbWluZyA9IHRoaXMuZW50cmllcy5maW5kKHggPT4geC52YWxpZFdpbmRvd1swXSA+IG5vdyk7XG4gICAgICAgIGlmICh1cGNvbWluZykgcmV0dXJuIHVwY29taW5nO1xuICAgICAgICBsZXQgbGFzdCA9IHRoaXMuZW50cmllc1t0aGlzLmVudHJpZXMubGVuZ3RoIC0gMV07XG4gICAgICAgIGlmIChsYXN0KSByZXR1cm4gbGFzdDtcbiAgICAgICAgcmV0dXJuIFVOQ09ORklHVVJFRDtcbiAgICB9XG59XG5cbi8qKiBUaGUgcGFydHMgb2YgYSBjb25maWcgZW50cnkgdGhhdCBkZXNjcmliZSB3aGF0IGEgc3RvcmUgSVMgLSBhcyBvcHBvc2VkIHRvIHdoaWNoIGVudHJ5IHNhaWQgc28uIEtlcHQgc2VwYXJhdGUgYmVjYXVzZSBhIHN0b3JlIHdpdGggbm8gZW50cmllcyBzdGlsbCBoYXMgYWxsIG9mIHRoZW0uICovXG5leHBvcnQgdHlwZSBTdG9yZVBvbGljeSA9IHtcbiAgICB2YWxpZFdpbmRvdzogW251bWJlciwgbnVtYmVyXTtcbiAgICByb3V0ZT86IFtudW1iZXIsIG51bWJlcl07XG4gICAgcHVibGljPzogYm9vbGVhbjtcbiAgICBpbW11dGFibGU/OiBib29sZWFuO1xuICAgIGZhc3Q/OiBib29sZWFuO1xuICAgIHdyaXRlRGVsYXk/OiBudW1iZXI7XG4gICAgbm9GdWxsU3luYz86IGJvb2xlYW47XG4gICAgcmVhZGVyRGlza0xpbWl0PzogbnVtYmVyO1xufTtcblxuLy8gQSBzdG9yZSBub2JvZHkgaGFzIGNvbmZpZ3VyZWQ6IGFsd2F5cyB2YWxpZCwgdGhlIHdob2xlIGtleSBzcGFjZSwgbm8gZGVsYXlzIGFuZCBubyBsaW1pdHMuIEV2ZXJ5IG9uZSBvZiB0aGVzZSBpcyB0aGUgYW5zd2VyIHRoYXQgZG9lcyB0aGUgbGVhc3QgLSBpdCBob2xkcyBpdHMgb3duIGRhdGEgYW5kIG5vdGhpbmcgZWxzZSBoYXBwZW5zIHRvIGl0IC0gd2hpY2ggaXMgd2hhdCBtYWtlcyBhIHN0b3JlIHVzYWJsZSBiZWZvcmUgaXQgaGFzIGV2ZXIgc2VlbiBhIGNvbmZpZy5cbmNvbnN0IFVOQ09ORklHVVJFRDogU3RvcmVQb2xpY3kgPSB7IHZhbGlkV2luZG93OiBGVUxMX1ZBTElEX1dJTkRPVyB9O1xuIl19
52
- /* _JS_SOURCE_HASH = "685db5d01482183243c0f55d67f2b62ade2a472a3720019a17af08d567f3e98a"; */
56
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RvcmVDb25maWcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJzdG9yZUNvbmZpZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7QUFBQSxtREFBZ0Q7QUFDaEQsNENBQStEO0FBRS9ELDJZQUEyWTtBQUUzWSxNQUFhLFdBQVc7SUFDcEIsWUFDb0IsSUFBWSxFQUM1QixPQUF1QjtRQURQLFNBQUksR0FBSixJQUFJLENBQVE7UUFNaEMsc0tBQXNLO1FBQzlKLFlBQU8sR0FBbUIsRUFBRSxDQUFDO1FBSmpDLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7SUFDekIsQ0FBQztJQUtELDJJQUEySTtJQUMzSSw2SkFBNko7SUFDdEosTUFBTSxDQUFDLE9BQXVCO1FBQ2pDLGdyQkFBZ3JCO1FBQ2hyQixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ3pDLE9BQU8sQ0FBQyxJQUFJLENBQUMsMkRBQTJELElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyx5Q0FBeUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEtBQUssQ0FBQyxJQUFJLEdBQUcsSUFBSSxLQUFLLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDLFdBQVcsRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUM3UyxPQUFPO1FBQ1gsQ0FBQztRQUNELElBQUksT0FBTyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQztRQUMzQixJQUFBLFdBQUksRUFBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDckMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUM7SUFDM0IsQ0FBQztJQUVNLEdBQUc7UUFDTixPQUFPLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDeEIsQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLE9BQU87UUFDVixJQUFJLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDckIsSUFBSSxVQUFVLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLEdBQUcsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNGLElBQUksVUFBVTtZQUFFLE9BQU8sVUFBVSxDQUFDO1FBQ2xDLElBQUksUUFBUSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQztRQUM5RCxJQUFJLFFBQVE7WUFBRSxPQUFPLFFBQVEsQ0FBQztRQUM5QixJQUFJLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2pELElBQUksSUFBSTtZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ3RCLE9BQU8sWUFBWSxDQUFDO0lBQ3hCLENBQUM7Q0FDSjtBQWhERCxrQ0FnREM7QUFjRCxnUkFBZ1I7QUFDaFIsTUFBTSxZQUFZLEdBQWdCLEVBQUUsV0FBVyxFQUFFLDZCQUFpQixFQUFFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBzb3J0IH0gZnJvbSBcInNvY2tldC1mdW5jdGlvbi9zcmMvbWlzY1wiO1xuaW1wb3J0IHsgSG9zdGVkQ29uZmlnLCBGVUxMX1ZBTElEX1dJTkRPVyB9IGZyb20gXCIuLi9JQXJjaGl2ZXNcIjtcblxuLy8gVGhlIGNvbmZpZ3VyYXRpb24gb2YgT05FIHN0b3JlLCBrZXB0IGN1cnJlbnQuIEEgc3RvcmUgaXMgbmFtZWQgYnkgaXRzIGVudHJpZXMgKHNlZSBDb21tb25Db25maWcubmFtZSksIGFuZCBhdCBhbnkgaW5zdGFudCBleGFjdGx5IG9uZSBvZiB0aGVtIGlzIGluIGVmZmVjdCAtIHRoZSBjb25maWcgd3JpdGUgcGF0aCBlbmZvcmNlcyB0aGF0IC0gc28gXCJ0aGUgY29uZmlndXJhdGlvbiBvZiB0aGlzIHN0b3JlIHJpZ2h0IG5vd1wiIGlzIGEgc2luZ2xlIGVudHJ5LCBhbmQgZXZlcnl0aGluZyB0aGUgc3RvcmUgZG9lcyB3aXRoIHJvdXRlcywgZmxhZ3MgYW5kIGxpbWl0cyByZWFkcyBpdCBmcm9tIGhlcmUgcmF0aGVyIHRoYW4gYmVpbmcgaGFuZGVkIGEgc25hcHNob3QgdGhhdCBnb2VzIHN0YWxlLlxuXG5leHBvcnQgY2xhc3MgU3RvcmVDb25maWcge1xuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICBwdWJsaWMgcmVhZG9ubHkgbmFtZTogc3RyaW5nLFxuICAgICAgICBlbnRyaWVzOiBIb3N0ZWRDb25maWdbXSxcbiAgICApIHtcbiAgICAgICAgdGhpcy51cGRhdGUoZW50cmllcyk7XG4gICAgfVxuXG4gICAgLy8gRXZlcnkgZW50cnkgbmFtaW5nIHRoaXMgc3RvcmUsIG9sZGVzdCB3aW5kb3cgZmlyc3QgLSBwYXN0IG9uZXMgaW5jbHVkZWQsIGJlY2F1c2UgYSBzdGFtcGVkIHdyaXRlIG9yIGEgc2NhbiBjYW4gbGVnaXRpbWF0ZWx5IGNvbmNlcm4gYSB3aW5kb3cgdGhhdCBoYXMgYWxyZWFkeSBlbmRlZFxuICAgIHByaXZhdGUgZW50cmllczogSG9zdGVkQ29uZmlnW10gPSBbXTtcblxuICAgIC8qKiBUaGUgcm91dGluZyBjb25maWcgY2hhbmdlZC4gU2FtZSBzdG9yZSBlaXRoZXIgd2F5OiBpdHMgbmFtZSBkaWQgbm90IGNoYW5nZSwgc28gbmVpdGhlciBkaWQgaXRzIGZvbGRlciwgaXRzIGluZGV4LCBvciB0aGUgZGF0YSBpbiBpdC4gKi9cbiAgICAvKiogTm8gZW50cmllcyBpcyBhIHJlYWwgc3RhdGUsIG5vdCBhbiBlcnJvcjogYSBzdG9yZSBleGlzdHMgYXMgc29vbiBhcyBpdHMgZm9sZGVyIGRvZXMsIGFuZCBpdCBtYXkgbmV2ZXIgaGF2ZSBoZWFyZCBvZiBhIGNvbmZpZ3VyYXRpb24gKHNlZSBTdG9yZVBvbGljeSkuICovXG4gICAgcHVibGljIHVwZGF0ZShlbnRyaWVzOiBIb3N0ZWRDb25maWdbXSk6IHZvaWQge1xuICAgICAgICAvLyBOZXZlciBnbyBmcm9tIGNvbmZpZ3VyZWQgYmFjayB0byBVTkNPTkZJR1VSRUQ6IGtlZXAgdGhlIGxhc3QgY29uZmlndXJhdGlvbiB0aGF0IHdvcmtlZC4gVGhlcmUgaXMgbm8gcG9pbnQgaW4gZW1wdHlpbmcgaXQgLSBpZiB0aGlzIHN0b3JlIHdhcyBnZW51aW5lbHkgcmVtb3ZlZCBmcm9tIHRoZSBjb25maWcsIG5vYm9keSB3aWxsIHJlcXVlc3QgaXQgYWdhaW4sIGFuZCB0aGUgc3RhbGUgZW50cmllcyBhcmUgbm90IHdvcnRoIGNsZWFuaW5nIHVwICh0aGV5IGFyZSB0aW55LCBuYW1lZCBzdG9yZXMgYXJlIHJhcmVseSByZW1vdmVkLCBhbmQgYSBzZXJ2aWNlIHJlc3RhcnQgY2xlYXJzIHRoZW0gZXZlbnR1YWxseSkuIEtlZXBpbmcgdGhlbSBpcyBSRVFVSVJFRCBmb3IgdGhlIG91dC1vZi1zeW5jIGNhc2VzOiBhIGJhZCBjb25maWcgdGhhdCBzdG9wcyBuYW1pbmcgdXMgd291bGQgb3RoZXJ3aXNlIGxlYXZlIHRoZSBzdG9yZSByZWplY3RpbmcgZXZlcnkgd3JpdGUsIGluY2x1ZGluZyB0aGUgb25lcyB0aGF0IHdvdWxkIGxldCB0aGUgY29uZmlndXJhdGlvbiBjb252ZXJnZSAtIGl0IGp1c3Qgd29uJ3QgdXBkYXRlIHVudGlsIGEgcmVzdGFydCwgYW5kIGEgcmVzdGFydCBjYW4ndCBjb21wbGV0ZSBhZ2FpbnN0IGFuIG91dC1vZi1kYXRlIGNvbmZpZ3VyYXRpb24sIHdoaWNoIGlzIGFuIGluZmluaXRlIGxvb3AuXG4gICAgICAgIGlmICghZW50cmllcy5sZW5ndGggJiYgdGhpcy5lbnRyaWVzLmxlbmd0aCkge1xuICAgICAgICAgICAgY29uc29sZS53YXJuKGBJZ25vcmluZyBhIHJvdXRpbmcgY29uZmlnIHVwZGF0ZSB0aGF0IHdvdWxkIGxlYXZlIHN0b3JlICR7SlNPTi5zdHJpbmdpZnkodGhpcy5uYW1lKX0gd2l0aCBOTyBlbnRyaWVzOiBrZWVwaW5nIGl0cyBjdXJyZW50ICR7dGhpcy5lbnRyaWVzLmxlbmd0aH0gZW50ciR7dGhpcy5lbnRyaWVzLmxlbmd0aCA9PT0gMSAmJiBcInlcIiB8fCBcImllc1wifSAke0pTT04uc3RyaW5naWZ5KHRoaXMuZW50cmllcy5tYXAoeCA9PiAoeyB2YWxpZFdpbmRvdzogeC52YWxpZFdpbmRvdywgcm91dGU6IHgucm91dGUgfSkpKX1gKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgICAgICBsZXQgb3JkZXJlZCA9IFsuLi5lbnRyaWVzXTtcbiAgICAgICAgc29ydChvcmRlcmVkLCB4ID0+IHgudmFsaWRXaW5kb3dbMF0pO1xuICAgICAgICB0aGlzLmVudHJpZXMgPSBvcmRlcmVkO1xuICAgIH1cblxuICAgIHB1YmxpYyBhbGwoKTogSG9zdGVkQ29uZmlnW10ge1xuICAgICAgICByZXR1cm4gdGhpcy5lbnRyaWVzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFdoYXQgdGhpcyBzdG9yZSBpcyBjb25maWd1cmVkIHRvIGJlIHJpZ2h0IG5vdzogdGhlIGVudHJ5IHdob3NlIHdpbmRvdyBjb250YWlucyB0aGlzIG1vbWVudDtcbiAgICAgKiBmYWlsaW5nIHRoYXQgdGhlIG5leHQgb25lIGR1ZSB0byBzdGFydDsgZmFpbGluZyB0aGF0IHRoZSBsYXN0IG9uZSB0byBoYXZlIGVuZGVkLlxuICAgICAqXG4gICAgICogVGhlcmUgaXMgYWx3YXlzIGFuIGFuc3dlciwgYW5kIGl0IG1hdHRlcnMgdGhhdCB0aGVyZSBpczogYSBzdG9yZSBiZXR3ZWVuIHdpbmRvd3Mgc3RpbGwgaG9sZHNcbiAgICAgKiBkYXRhIGFuZCBzdGlsbCBoYXMgdG8gYW5zd2VyIGZvciBpdCwgc28gaXQgbmVlZHMgYSByb3V0ZSBhbmQgZmxhZ3MgZXZlbiB3aGVuIG5vdGhpbmcgaXNcbiAgICAgKiBjdXJyZW50bHkgcG9pbnRpbmcgd3JpdGVzIGF0IGl0LiBXaGljaCBvZiB0aGUgdGhyZWUgY2FzZXMgcHJvZHVjZWQgdGhlIGFuc3dlciBpcyBkZWxpYmVyYXRlbHlcbiAgICAgKiBub3QgZXhwb3NlZCAtIHRoZSB2YWxpZCB3aW5kb3cgaXRzZWxmIGlzIHdoYXQgc2F5cyB3aGV0aGVyIHdyaXRlcyBiZWxvbmcgaGVyZSwgYW5kIGV2ZXJ5IHdyaXRlXG4gICAgICogaXMgY2hlY2tlZCBhZ2FpbnN0IGl0IHNlcGFyYXRlbHkuXG4gICAgICovXG4gICAgcHVibGljIGN1cnJlbnQoKTogU3RvcmVQb2xpY3kge1xuICAgICAgICBsZXQgbm93ID0gRGF0ZS5ub3coKTtcbiAgICAgICAgbGV0IGNvbnRhaW5pbmcgPSB0aGlzLmVudHJpZXMuZmluZCh4ID0+IHgudmFsaWRXaW5kb3dbMF0gPD0gbm93ICYmIG5vdyA8IHgudmFsaWRXaW5kb3dbMV0pO1xuICAgICAgICBpZiAoY29udGFpbmluZykgcmV0dXJuIGNvbnRhaW5pbmc7XG4gICAgICAgIGxldCB1cGNvbWluZyA9IHRoaXMuZW50cmllcy5maW5kKHggPT4geC52YWxpZFdpbmRvd1swXSA+IG5vdyk7XG4gICAgICAgIGlmICh1cGNvbWluZykgcmV0dXJuIHVwY29taW5nO1xuICAgICAgICBsZXQgbGFzdCA9IHRoaXMuZW50cmllc1t0aGlzLmVudHJpZXMubGVuZ3RoIC0gMV07XG4gICAgICAgIGlmIChsYXN0KSByZXR1cm4gbGFzdDtcbiAgICAgICAgcmV0dXJuIFVOQ09ORklHVVJFRDtcbiAgICB9XG59XG5cbi8qKiBUaGUgcGFydHMgb2YgYSBjb25maWcgZW50cnkgdGhhdCBkZXNjcmliZSB3aGF0IGEgc3RvcmUgSVMgLSBhcyBvcHBvc2VkIHRvIHdoaWNoIGVudHJ5IHNhaWQgc28uIEtlcHQgc2VwYXJhdGUgYmVjYXVzZSBhIHN0b3JlIHdpdGggbm8gZW50cmllcyBzdGlsbCBoYXMgYWxsIG9mIHRoZW0uICovXG5leHBvcnQgdHlwZSBTdG9yZVBvbGljeSA9IHtcbiAgICB2YWxpZFdpbmRvdzogW251bWJlciwgbnVtYmVyXTtcbiAgICByb3V0ZT86IFtudW1iZXIsIG51bWJlcl07XG4gICAgcHVibGljPzogYm9vbGVhbjtcbiAgICBpbW11dGFibGU/OiBib29sZWFuO1xuICAgIGZhc3Q/OiBib29sZWFuO1xuICAgIHdyaXRlRGVsYXk/OiBudW1iZXI7XG4gICAgbm9GdWxsU3luYz86IGJvb2xlYW47XG4gICAgcmVhZGVyRGlza0xpbWl0PzogbnVtYmVyO1xufTtcblxuLy8gQSBzdG9yZSBub2JvZHkgaGFzIGNvbmZpZ3VyZWQ6IGFsd2F5cyB2YWxpZCwgdGhlIHdob2xlIGtleSBzcGFjZSwgbm8gZGVsYXlzIGFuZCBubyBsaW1pdHMuIEV2ZXJ5IG9uZSBvZiB0aGVzZSBpcyB0aGUgYW5zd2VyIHRoYXQgZG9lcyB0aGUgbGVhc3QgLSBpdCBob2xkcyBpdHMgb3duIGRhdGEgYW5kIG5vdGhpbmcgZWxzZSBoYXBwZW5zIHRvIGl0IC0gd2hpY2ggaXMgd2hhdCBtYWtlcyBhIHN0b3JlIHVzYWJsZSBiZWZvcmUgaXQgaGFzIGV2ZXIgc2VlbiBhIGNvbmZpZy5cbmNvbnN0IFVOQ09ORklHVVJFRDogU3RvcmVQb2xpY3kgPSB7IHZhbGlkV2luZG93OiBGVUxMX1ZBTElEX1dJTkRPVyB9O1xuIl19
57
+ /* _JS_SOURCE_HASH = "b7b2f29d5b992b4aa2fb3890c73960bc15bae51aac380537934083b376729446"; */
@@ -1,5 +1,19 @@
1
+ import { RemoteConfig } from "../IArchives";
1
2
  /** Subscribe to server-pushed routing change notifications. Returns the unsubscribe function. */
2
3
  export declare function onServerRoutingChanged(listener: () => void): () => void;
4
+ /** One chain's configs, as getRoutingConfigForName answers from them: the initial in-code config, and a getter for the synchronized one (adopted from the stored routing files, so it changes over time). */
5
+ type TrackedChainConfig = {
6
+ configured: RemoteConfig;
7
+ active: () => RemoteConfig;
8
+ };
9
+ /** Every chain tracks its configs here (see ChainStateManager), so a server can ask what config was intended for a store name. Returns the untrack function. */
10
+ export declare function trackChainConfig(entry: TrackedChainConfig): () => void;
3
11
  export declare const StorageClientController: import("socket-function/SocketFunctionTypes").SocketRegistered<{
4
12
  routingConfigChanged: () => Promise<void>;
13
+ getRoutingConfigForName: (config: {
14
+ account: string;
15
+ bucketName: string;
16
+ name: string;
17
+ }) => Promise<RemoteConfig | undefined>;
5
18
  }>;
19
+ export {};
@@ -1,6 +1,8 @@
1
1
  import { SocketFunction } from "socket-function/SocketFunction";
2
+ import { RemoteConfig } from "../IArchives";
3
+ import { parseHostedUrl } from "./remoteConfig";
2
4
 
3
- // The client half of routing-change broadcasts: the storage server tracks its connected clients (see trackCaller in storageController) and calls routingConfigChanged on every one of them the moment a routing config changes - clients react immediately instead of waiting for a poll.
5
+ // The client half of the storage protocol: the storage server tracks its connected clients (see trackCaller in storageController) and calls back into them - routingConfigChanged the moment a routing config changes (clients react immediately instead of waiting for a poll), and getRoutingConfigForName when a store one of our requests created needs the config we intended for it.
4
6
 
5
7
  const listeners = new Set<() => void>();
6
8
 
@@ -12,6 +14,32 @@ export function onServerRoutingChanged(listener: () => void): () => void {
12
14
  };
13
15
  }
14
16
 
17
+ /** One chain's configs, as getRoutingConfigForName answers from them: the initial in-code config, and a getter for the synchronized one (adopted from the stored routing files, so it changes over time). */
18
+ type TrackedChainConfig = { configured: RemoteConfig; active: () => RemoteConfig };
19
+ const chainConfigs = new Set<TrackedChainConfig>();
20
+
21
+ /** Every chain tracks its configs here (see ChainStateManager), so a server can ask what config was intended for a store name. Returns the untrack function. */
22
+ export function trackChainConfig(entry: TrackedChainConfig): () => void {
23
+ chainConfigs.add(entry);
24
+ return () => {
25
+ chainConfigs.delete(entry);
26
+ };
27
+ }
28
+
29
+ function configNamesStore(config: RemoteConfig, account: string, bucketName: string, name: string): boolean {
30
+ for (let source of config.sources) {
31
+ if (typeof source === "string" || source.type !== "remote") continue;
32
+ if (source.name !== name) continue;
33
+ try {
34
+ let parsed = parseHostedUrl(source.url);
35
+ if (parsed.account === account && parsed.bucketName === bucketName) return true;
36
+ } catch {
37
+ continue;
38
+ }
39
+ }
40
+ return false;
41
+ }
42
+
15
43
  class StorageClientControllerBase {
16
44
  async routingConfigChanged(): Promise<void> {
17
45
  for (let listener of [...listeners]) {
@@ -22,6 +50,18 @@ class StorageClientControllerBase {
22
50
  }
23
51
  }
24
52
  }
53
+
54
+ /** A storage server asks: what routing config did this client INTEND for this store name? This is how a store our requests created - before any config ever reached its folder - configures itself: the same information as passing the config on every call, fetched lazily instead (the config is kilobytes and the calls are many). Preference: the synchronized config (adopted from the stored routing files); when that no longer names the store, the initial in-code config - older, but it MATCHES the name, which is what the asking store needs. */
55
+ async getRoutingConfigForName(config: { account: string; bucketName: string; name: string }): Promise<RemoteConfig | undefined> {
56
+ for (let entry of [...chainConfigs]) {
57
+ let active = entry.active();
58
+ if (configNamesStore(active, config.account, config.bucketName, config.name)) return active;
59
+ }
60
+ for (let entry of [...chainConfigs]) {
61
+ if (configNamesStore(entry.configured, config.account, config.bucketName, config.name)) return entry.configured;
62
+ }
63
+ return undefined;
64
+ }
25
65
  }
26
66
 
27
67
  export const StorageClientController = SocketFunction.register(
@@ -29,5 +69,6 @@ export const StorageClientController = SocketFunction.register(
29
69
  new StorageClientControllerBase(),
30
70
  () => ({
31
71
  routingConfigChanged: {},
72
+ getRoutingConfigForName: {},
32
73
  }),
33
74
  );
@@ -4,7 +4,7 @@ import { BlobStore } from "./blobStore";
4
4
  import { RemoteConfig, SourceConfig, IArchives, ArchivesConfig, ArchivesSyncStatus } from "../IArchives";
5
5
  import { BucketDiskInfo } from "./bucketDisk";
6
6
  import { BucketWriteStats } from "./accessStats";
7
- export declare function getStore(account: string, bucketName: string, name: string): BlobStore;
7
+ export declare function getStore(account: string, bucketName: string, name: string, callerNodeId?: string): BlobStore;
8
8
  /** The store serving a request: the one the client's selected entry NAMES. Account, name, and bucket ARE the folder, so this is a direct lookup, never a search of what exists - and a name this server has never seen is CREATED, never rejected, because asking for a name is the instruction to have that store (one name, one folder, one index; it configures itself once the routing config lands in it). Nothing else about the request is compared - not the window, not the route, not the flags - which is the whole point of naming it: a client a config version behind on some flag still reaches the right store. */
9
9
  export declare function findBucketStore(account: string, bucketName: string, sourceConfig: SourceConfig | undefined): BlobStore;
10
10
  /** The stores of a bucket as the DISK records them (a bucket is nothing more than the store folders sharing its name), opened - so the ones that weren't running yet start synchronizing. Empty when the bucket does not exist here. */
@@ -9,6 +9,8 @@ import { assertWritesAllowed } from "./serverConfig";
9
9
  import { assertValidSourceName } from "./validation";
10
10
  import { getBucketFolder, listAccountStoreFolders, listBucketStoreFolders, readRoutingFromDisk, getDiskInfo, BucketDiskInfo } from "./bucketDisk";
11
11
  import { scheduleBoundaryWork, reinjectIntermediates } from "./intermediateManagement";
12
+ import { SocketFunction } from "socket-function/SocketFunction";
13
+ import { StorageClientController } from "./storageClientController";
12
14
  import { isSelfSource } from "./storePlan";
13
15
  import { countBucketWrite, getBucketWriteStats, BucketWriteStats } from "./accessStats";
14
16
 
@@ -28,7 +30,7 @@ const stores = new Map<string, BlobStore>();
28
30
  // The opened stores of each `${account}/${bucketName}`, by name - which buckets are ACTIVE (something touched them), for deploy handoffs and the debug pages. Purely a registry of what getStore already made.
29
31
  const activeStores = new Map<string, Map<string, BlobStore>>();
30
32
 
31
- export function getStore(account: string, bucketName: string, name: string): BlobStore {
33
+ export function getStore(account: string, bucketName: string, name: string, callerNodeId?: string): BlobStore {
32
34
  // The one place a name becomes a folder, so the one place it is validated (it can come straight off the wire)
33
35
  assertValidSourceName(name);
34
36
  let folder = getBucketFolder(name, account, bucketName);
@@ -44,6 +46,8 @@ export function getStore(account: string, bucketName: string, name: string): Blo
44
46
  resolveSourceUrl: resolveSourceArchives,
45
47
  // The store is the one that knows when a config landed, and a config with upcoming windows is what boundary scans are armed from
46
48
  onRoutingApplied: routing => scheduleBoundaryWork(account, bucketName, routing),
49
+ // The store was created by this caller's request, so the caller knows exactly what config it intended for this name - the store asks it when its own folder holds no configuration (see BlobStore.init)
50
+ requestRoutingConfig: callerNodeId && (async () => await StorageClientController.nodes[callerNodeId].getRoutingConfigForName({ account, bucketName, name })) || undefined,
47
51
  });
48
52
  stores.set(folder, store);
49
53
  let key = `${account}/${bucketName}`;
@@ -63,7 +67,12 @@ export function findBucketStore(account: string, bucketName: string, sourceConfi
63
67
  if (!sourceConfig) {
64
68
  throw new Error(`No remote source configuration was provided for bucket ${account}/${bucketName}: every request must say which configured source it selected`);
65
69
  }
66
- return getStore(account, bucketName, sourceConfig.name);
70
+ // The caller's id, so a store this request CREATES can ask that caller for the config it intended (a store only ever exists because a config names it, and the requester holds that config)
71
+ let callerNodeId: string | undefined;
72
+ try {
73
+ callerNodeId = SocketFunction.getCaller()?.nodeId;
74
+ } catch { }
75
+ return getStore(account, bucketName, sourceConfig.name, callerNodeId);
67
76
  }
68
77
 
69
78
  /** The stores of a bucket as the DISK records them (a bucket is nothing more than the store folders sharing its name), opened - so the ones that weren't running yet start synchronizing. Empty when the bucket does not exist here. */
@@ -17,6 +17,11 @@ export class StoreConfig {
17
17
  /** The routing config changed. Same store either way: its name did not change, so neither did its folder, its index, or the data in it. */
18
18
  /** No entries is a real state, not an error: a store exists as soon as its folder does, and it may never have heard of a configuration (see StorePolicy). */
19
19
  public update(entries: HostedConfig[]): void {
20
+ // Never go from configured back to UNCONFIGURED: keep the last configuration that worked. There is no point in emptying it - if this store was genuinely removed from the config, nobody will request it again, and the stale entries are not worth cleaning up (they are tiny, named stores are rarely removed, and a service restart clears them eventually). Keeping them is REQUIRED for the out-of-sync cases: a bad config that stops naming us would otherwise leave the store rejecting every write, including the ones that would let the configuration converge - it just won't update until a restart, and a restart can't complete against an out-of-date configuration, which is an infinite loop.
21
+ if (!entries.length && this.entries.length) {
22
+ console.warn(`Ignoring a routing config update that would leave store ${JSON.stringify(this.name)} with NO entries: keeping its current ${this.entries.length} entr${this.entries.length === 1 && "y" || "ies"} ${JSON.stringify(this.entries.map(x => ({ validWindow: x.validWindow, route: x.route })))}`);
23
+ return;
24
+ }
20
25
  let ordered = [...entries];
21
26
  sort(ordered, x => x.validWindow[0]);
22
27
  this.entries = ordered;