obsidian-dev-utils 86.1.3 → 87.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/lib/cjs/__merged.cjs +34 -3
  3. package/dist/lib/cjs/__merged.d.cts +5 -4
  4. package/dist/lib/cjs/async-events.cjs +32 -3
  5. package/dist/lib/cjs/async-events.d.cts +63 -0
  6. package/dist/lib/cjs/disposable.cjs +103 -115
  7. package/dist/lib/cjs/disposable.d.cts +81 -57
  8. package/dist/lib/cjs/generated-during-build.cjs +2 -2
  9. package/dist/lib/cjs/obsidian/command-handlers/command-handler-component.cjs +48 -21
  10. package/dist/lib/cjs/obsidian/command-handlers/command-handler-component.d.cts +11 -8
  11. package/dist/lib/cjs/obsidian/command-handlers/open-demo-vault-command-handler.cjs +1 -1
  12. package/dist/lib/cjs/obsidian/community-plugins.cjs +109 -9
  13. package/dist/lib/cjs/obsidian/community-plugins.d.cts +175 -3
  14. package/dist/lib/cjs/obsidian/components/component-ex.cjs +18 -1
  15. package/dist/lib/cjs/obsidian/components/component-ex.d.cts +12 -0
  16. package/dist/lib/cjs/obsidian/components/menu-event-registrar-component.cjs +8 -4
  17. package/dist/lib/cjs/obsidian/components/menu-event-registrar-component.d.cts +7 -3
  18. package/dist/lib/cjs/obsidian/components/plugin-notice-component.cjs +80 -38
  19. package/dist/lib/cjs/obsidian/components/plugin-notice-component.d.cts +81 -19
  20. package/dist/lib/cjs/obsidian/css-class.cjs +4 -2
  21. package/dist/lib/cjs/obsidian/css-class.d.cts +12 -3
  22. package/dist/lib/cjs/obsidian/desktop-demo-vault-opener.cjs +2 -7
  23. package/dist/lib/cjs/obsidian/events.cjs +165 -0
  24. package/dist/lib/cjs/obsidian/events.d.cts +98 -0
  25. package/dist/lib/cjs/obsidian/i18n/locales/en.cjs +1 -2
  26. package/dist/lib/cjs/obsidian/i18n/locales/en.d.cts +0 -1
  27. package/dist/lib/cjs/obsidian/i18n/locales/translations-map.d.cts +0 -1
  28. package/dist/lib/cjs/obsidian/index.cjs +4 -1
  29. package/dist/lib/cjs/obsidian/index.d.cts +1 -0
  30. package/dist/lib/cjs/obsidian/menu-event-registrar.cjs +1 -1
  31. package/dist/lib/cjs/obsidian/menu-event-registrar.d.cts +7 -3
  32. package/dist/lib/cjs/script-utils/bundlers/esbuild-impl/change-extension-plugin.cjs +31 -33
  33. package/dist/lib/cjs/script-utils/bundlers/esbuild-impl/change-extension-plugin.d.cts +11 -0
  34. package/dist/lib/cjs/script-utils/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.cjs +39 -52
  35. package/dist/lib/cjs/script-utils/linters/eslint-no-restricted-syntax.cjs +1 -5
  36. package/dist/lib/cjs/type.cjs +31 -12
  37. package/dist/lib/cjs/type.d.cts +56 -36
  38. package/dist/lib/esm/__merged.d.mts +5 -4
  39. package/dist/lib/esm/__merged.mjs +39 -5
  40. package/dist/lib/esm/async-events.d.mts +63 -0
  41. package/dist/lib/esm/async-events.mjs +29 -2
  42. package/dist/lib/esm/disposable.d.mts +81 -57
  43. package/dist/lib/esm/disposable.mjs +101 -115
  44. package/dist/lib/esm/generated-during-build.mjs +2 -2
  45. package/dist/lib/esm/obsidian/command-handlers/command-handler-component.d.mts +11 -8
  46. package/dist/lib/esm/obsidian/command-handlers/command-handler-component.mjs +49 -22
  47. package/dist/lib/esm/obsidian/command-handlers/open-demo-vault-command-handler.mjs +1 -1
  48. package/dist/lib/esm/obsidian/community-plugins.d.mts +175 -3
  49. package/dist/lib/esm/obsidian/community-plugins.mjs +100 -8
  50. package/dist/lib/esm/obsidian/components/component-ex.d.mts +12 -0
  51. package/dist/lib/esm/obsidian/components/component-ex.mjs +18 -1
  52. package/dist/lib/esm/obsidian/components/menu-event-registrar-component.d.mts +7 -3
  53. package/dist/lib/esm/obsidian/components/menu-event-registrar-component.mjs +8 -4
  54. package/dist/lib/esm/obsidian/components/plugin-notice-component.d.mts +81 -19
  55. package/dist/lib/esm/obsidian/components/plugin-notice-component.mjs +80 -38
  56. package/dist/lib/esm/obsidian/css-class.d.mts +12 -3
  57. package/dist/lib/esm/obsidian/css-class.mjs +4 -2
  58. package/dist/lib/esm/obsidian/desktop-demo-vault-opener.mjs +5 -7
  59. package/dist/lib/esm/obsidian/events.d.mts +98 -0
  60. package/dist/lib/esm/obsidian/events.mjs +55 -0
  61. package/dist/lib/esm/obsidian/i18n/locales/en.d.mts +0 -1
  62. package/dist/lib/esm/obsidian/i18n/locales/en.mjs +1 -2
  63. package/dist/lib/esm/obsidian/i18n/locales/translations-map.d.mts +0 -1
  64. package/dist/lib/esm/obsidian/index.d.mts +1 -0
  65. package/dist/lib/esm/obsidian/index.mjs +3 -1
  66. package/dist/lib/esm/obsidian/menu-event-registrar.d.mts +7 -3
  67. package/dist/lib/esm/script-utils/bundlers/esbuild-impl/change-extension-plugin.d.mts +11 -0
  68. package/dist/lib/esm/script-utils/bundlers/esbuild-impl/change-extension-plugin.mjs +29 -32
  69. package/dist/lib/esm/script-utils/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.mjs +40 -55
  70. package/dist/lib/esm/script-utils/linters/eslint-no-restricted-syntax.mjs +1 -5
  71. package/dist/lib/esm/type.d.mts +56 -36
  72. package/dist/lib/esm/type.mjs +30 -11
  73. package/dist/styles.css +5 -18
  74. package/obsidian/events/package.json +6 -0
  75. package/package.json +18 -15
@@ -4,6 +4,7 @@
4
4
  *
5
5
  * Component that registers {@link CommandHandler}s with Obsidian and ties their removal to its lifecycle.
6
6
  */
7
+ import type { DisposableEx } from '../../disposable.mjs';
7
8
  import type { ActiveFileProvider } from '../active-file-provider.mjs';
8
9
  import type { CommandRegistrar } from '../command-registrar.mjs';
9
10
  import type { MenuEventRegistrar } from '../menu-event-registrar.mjs';
@@ -19,8 +20,9 @@ interface CommandHandlerComponentConstructorParams {
19
20
  * Registers {@link CommandHandler}s with Obsidian and manages their lifecycle.
20
21
  *
21
22
  * Call {@link registerCommandHandlers} to register a batch of handlers on demand (as many times as
22
- * needed while the component is alive); dispose the returned {@link Disposable} to unregister exactly
23
- * those handlers, or let the component unload to remove every command still registered through it.
23
+ * needed while the component is alive); dispose the returned {@link DisposableEx} to unregister exactly
24
+ * those handlers — including any menu events they registered — or let the component unload to remove every
25
+ * command still registered through it.
24
26
  */
25
27
  export declare class CommandHandlerComponent extends ComponentEx {
26
28
  /**
@@ -46,14 +48,15 @@ export declare class CommandHandlerComponent extends ComponentEx {
46
48
  */
47
49
  constructor(params: CommandHandlerComponentConstructorParams);
48
50
  /**
49
- * Registers the given command handlers with Obsidian and provides each its runtime registration
50
- * context. Each handler's command is added immediately; the returned {@link Disposable} removes the
51
- * commands registered by this call when disposed. Any command still registered when the component
52
- * unloads is removed automatically.
51
+ * Registers the given command handlers with Obsidian and provides each its own runtime registration
52
+ * context. Each handler's command is added immediately; the returned {@link DisposableEx} removes the
53
+ * commands registered by this call and any menu events those handlers registered via their context's
54
+ * {@link MenuEventRegistrar} when disposed. Any command still registered when the component unloads is
55
+ * removed automatically.
53
56
  *
54
57
  * @param commandHandlers - The command handlers to register.
55
- * @returns A {@link Disposable} that unregisters the handlers passed to this call.
58
+ * @returns A {@link DisposableEx} that unregisters the handlers (commands + menu events) passed to this call.
56
59
  */
57
- registerCommandHandlers(commandHandlers: CommandHandler[]): Disposable;
60
+ registerCommandHandlers(commandHandlers: CommandHandler[]): DisposableEx;
58
61
  }
59
62
  export {};
@@ -25,9 +25,40 @@ import { invokeAsyncSafely } from "../../async.mjs";
25
25
  import {
26
26
  CallbackDisposable,
27
27
  CombineDisposable,
28
- MultipleDisposeBehavior
28
+ DisposableBase
29
29
  } from "../../disposable.mjs";
30
30
  import { ComponentEx } from "../components/component-ex.mjs";
31
+ class CommandMenuEventScope extends DisposableBase {
32
+ constructor(inner) {
33
+ super();
34
+ this.inner = inner;
35
+ }
36
+ inner;
37
+ disposables = [];
38
+ registerEditorMenuEventHandler(handler) {
39
+ return this.collect(this.inner.registerEditorMenuEventHandler(handler));
40
+ }
41
+ registerFileMenuEventHandler(handler) {
42
+ return this.collect(this.inner.registerFileMenuEventHandler(handler));
43
+ }
44
+ registerFilesMenuEventHandler(handler) {
45
+ return this.collect(this.inner.registerFilesMenuEventHandler(handler));
46
+ }
47
+ performDispose() {
48
+ for (const disposable of this.disposables) {
49
+ disposable.dispose();
50
+ }
51
+ this.disposables.length = 0;
52
+ }
53
+ collect(disposable) {
54
+ if (this.isDisposed) {
55
+ disposable.dispose();
56
+ } else {
57
+ this.disposables.push(disposable);
58
+ }
59
+ return disposable;
60
+ }
61
+ }
31
62
  class CommandHandlerComponent extends ComponentEx {
32
63
  /**
33
64
  * Provider for accessing the currently active file.
@@ -58,44 +89,40 @@ class CommandHandlerComponent extends ComponentEx {
58
89
  this.pluginName = params.pluginName;
59
90
  }
60
91
  /**
61
- * Registers the given command handlers with Obsidian and provides each its runtime registration
62
- * context. Each handler's command is added immediately; the returned {@link Disposable} removes the
63
- * commands registered by this call when disposed. Any command still registered when the component
64
- * unloads is removed automatically.
92
+ * Registers the given command handlers with Obsidian and provides each its own runtime registration
93
+ * context. Each handler's command is added immediately; the returned {@link DisposableEx} removes the
94
+ * commands registered by this call and any menu events those handlers registered via their context's
95
+ * {@link MenuEventRegistrar} when disposed. Any command still registered when the component unloads is
96
+ * removed automatically.
65
97
  *
66
98
  * @param commandHandlers - The command handlers to register.
67
- * @returns A {@link Disposable} that unregisters the handlers passed to this call.
99
+ * @returns A {@link DisposableEx} that unregisters the handlers (commands + menu events) passed to this call.
68
100
  */
69
101
  registerCommandHandlers(commandHandlers) {
70
- const context = {
71
- activeFileProvider: this.activeFileProvider,
72
- menuEventRegistrar: this.menuEventRegistrar,
73
- pluginName: this.pluginName
74
- };
75
102
  const disposables = [];
76
103
  for (const commandHandler of commandHandlers) {
77
104
  const command = commandHandler.buildCommand();
78
105
  const commandId = command.id;
79
106
  this.commandRegistrar.addCommand(command);
107
+ const menuEventScope = new CommandMenuEventScope(this.menuEventRegistrar);
108
+ const context = {
109
+ activeFileProvider: this.activeFileProvider,
110
+ menuEventRegistrar: menuEventScope,
111
+ pluginName: this.pluginName
112
+ };
80
113
  const disposable = new CallbackDisposable({
81
114
  callback: () => {
82
115
  this.commandRegistrar.removeCommand(commandId);
83
- },
84
- multipleDisposeBehavior: MultipleDisposeBehavior.Ignore
85
- });
86
- disposables.push(disposable);
87
- this.register(() => {
88
- disposable.dispose();
116
+ menuEventScope.dispose();
117
+ }
89
118
  });
119
+ disposables.push(this.registerDisposable(disposable));
90
120
  invokeAsyncSafely(() => commandHandler.onRegistered(context));
91
121
  }
92
- return new CombineDisposable({
93
- disposables,
94
- multipleDisposeBehavior: MultipleDisposeBehavior.Ignore
95
- });
122
+ return new CombineDisposable({ disposables });
96
123
  }
97
124
  }
98
125
  export {
99
126
  CommandHandlerComponent
100
127
  };
101
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL2NvbW1hbmQtaGFuZGxlcnMvY29tbWFuZC1oYW5kbGVyLWNvbXBvbmVudC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIENvbXBvbmVudCB0aGF0IHJlZ2lzdGVycyB7QGxpbmsgQ29tbWFuZEhhbmRsZXJ9cyB3aXRoIE9ic2lkaWFuIGFuZCB0aWVzIHRoZWlyIHJlbW92YWwgdG8gaXRzIGxpZmVjeWNsZS5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IEFjdGl2ZUZpbGVQcm92aWRlciB9IGZyb20gJy4uL2FjdGl2ZS1maWxlLXByb3ZpZGVyLnRzJztcbmltcG9ydCB0eXBlIHsgQ29tbWFuZFJlZ2lzdHJhciB9IGZyb20gJy4uL2NvbW1hbmQtcmVnaXN0cmFyLnRzJztcbmltcG9ydCB0eXBlIHsgTWVudUV2ZW50UmVnaXN0cmFyIH0gZnJvbSAnLi4vbWVudS1ldmVudC1yZWdpc3RyYXIudHMnO1xuaW1wb3J0IHR5cGUge1xuICBDb21tYW5kSGFuZGxlcixcbiAgQ29tbWFuZEhhbmRsZXJSZWdpc3RyYXRpb25Db250ZXh0XG59IGZyb20gJy4vY29tbWFuZC1oYW5kbGVyLnRzJztcblxuaW1wb3J0IHsgaW52b2tlQXN5bmNTYWZlbHkgfSBmcm9tICcuLi8uLi9hc3luYy50cyc7XG5pbXBvcnQge1xuICBDYWxsYmFja0Rpc3Bvc2FibGUsXG4gIENvbWJpbmVEaXNwb3NhYmxlLFxuICBNdWx0aXBsZURpc3Bvc2VCZWhhdmlvclxufSBmcm9tICcuLi8uLi9kaXNwb3NhYmxlLnRzJztcbmltcG9ydCB7IENvbXBvbmVudEV4IH0gZnJvbSAnLi4vY29tcG9uZW50cy9jb21wb25lbnQtZXgudHMnO1xuXG5pbnRlcmZhY2UgQ29tbWFuZEhhbmRsZXJDb21wb25lbnRDb25zdHJ1Y3RvclBhcmFtcyB7XG4gIHJlYWRvbmx5IGFjdGl2ZUZpbGVQcm92aWRlcjogQWN0aXZlRmlsZVByb3ZpZGVyO1xuICByZWFkb25seSBjb21tYW5kUmVnaXN0cmFyOiBDb21tYW5kUmVnaXN0cmFyO1xuICByZWFkb25seSBtZW51RXZlbnRSZWdpc3RyYXI6IE1lbnVFdmVudFJlZ2lzdHJhcjtcbiAgcmVhZG9ubHkgcGx1Z2luTmFtZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIFJlZ2lzdGVycyB7QGxpbmsgQ29tbWFuZEhhbmRsZXJ9cyB3aXRoIE9ic2lkaWFuIGFuZCBtYW5hZ2VzIHRoZWlyIGxpZmVjeWNsZS5cbiAqXG4gKiBDYWxsIHtAbGluayByZWdpc3RlckNvbW1hbmRIYW5kbGVyc30gdG8gcmVnaXN0ZXIgYSBiYXRjaCBvZiBoYW5kbGVycyBvbiBkZW1hbmQgKGFzIG1hbnkgdGltZXMgYXNcbiAqIG5lZWRlZCB3aGlsZSB0aGUgY29tcG9uZW50IGlzIGFsaXZlKTsgZGlzcG9zZSB0aGUgcmV0dXJuZWQge0BsaW5rIERpc3Bvc2FibGV9IHRvIHVucmVnaXN0ZXIgZXhhY3RseVxuICogdGhvc2UgaGFuZGxlcnMsIG9yIGxldCB0aGUgY29tcG9uZW50IHVubG9hZCB0byByZW1vdmUgZXZlcnkgY29tbWFuZCBzdGlsbCByZWdpc3RlcmVkIHRocm91Z2ggaXQuXG4gKi9cbmV4cG9ydCBjbGFzcyBDb21tYW5kSGFuZGxlckNvbXBvbmVudCBleHRlbmRzIENvbXBvbmVudEV4IHtcbiAgLyoqXG4gICAqIFByb3ZpZGVyIGZvciBhY2Nlc3NpbmcgdGhlIGN1cnJlbnRseSBhY3RpdmUgZmlsZS5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBhY3RpdmVGaWxlUHJvdmlkZXI6IEFjdGl2ZUZpbGVQcm92aWRlcjtcblxuICAvKipcbiAgICogUmVnaXN0cmFyIHVzZWQgdG8gYWRkIGFuZCByZW1vdmUgY29tbWFuZHMgd2l0aCBPYnNpZGlhbi5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBjb21tYW5kUmVnaXN0cmFyOiBDb21tYW5kUmVnaXN0cmFyO1xuXG4gIC8qKlxuICAgKiBSZWdpc3RyYXIgZm9yIG1lbnUgZXZlbnQgaGFuZGxlcnMuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgbWVudUV2ZW50UmVnaXN0cmFyOiBNZW51RXZlbnRSZWdpc3RyYXI7XG5cbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBwbHVnaW4gdGhhdCBvd25zIHRoZSBjb21tYW5kcy5cbiAgICovXG4gIHByb3RlY3RlZCByZWFkb25seSBwbHVnaW5OYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgY29tbWFuZCBoYW5kbGVyIGNvbXBvbmVudC5cbiAgICpcbiAgICogQHBhcmFtIHBhcmFtcyAtIFRoZSBjb25zdHJ1Y3RvciBwYXJhbWV0ZXJzLlxuICAgKi9cbiAgcHVibGljIGNvbnN0cnVjdG9yKHBhcmFtczogQ29tbWFuZEhhbmRsZXJDb21wb25lbnRDb25zdHJ1Y3RvclBhcmFtcykge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5hY3RpdmVGaWxlUHJvdmlkZXIgPSBwYXJhbXMuYWN0aXZlRmlsZVByb3ZpZGVyO1xuICAgIHRoaXMubWVudUV2ZW50UmVnaXN0cmFyID0gcGFyYW1zLm1lbnVFdmVudFJlZ2lzdHJhcjtcbiAgICB0aGlzLmNvbW1hbmRSZWdpc3RyYXIgPSBwYXJhbXMuY29tbWFuZFJlZ2lzdHJhcjtcbiAgICB0aGlzLnBsdWdpbk5hbWUgPSBwYXJhbXMucGx1Z2luTmFtZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgdGhlIGdpdmVuIGNvbW1hbmQgaGFuZGxlcnMgd2l0aCBPYnNpZGlhbiBhbmQgcHJvdmlkZXMgZWFjaCBpdHMgcnVudGltZSByZWdpc3RyYXRpb25cbiAgICogY29udGV4dC4gRWFjaCBoYW5kbGVyJ3MgY29tbWFuZCBpcyBhZGRlZCBpbW1lZGlhdGVseTsgdGhlIHJldHVybmVkIHtAbGluayBEaXNwb3NhYmxlfSByZW1vdmVzIHRoZVxuICAgKiBjb21tYW5kcyByZWdpc3RlcmVkIGJ5IHRoaXMgY2FsbCB3aGVuIGRpc3Bvc2VkLiBBbnkgY29tbWFuZCBzdGlsbCByZWdpc3RlcmVkIHdoZW4gdGhlIGNvbXBvbmVudFxuICAgKiB1bmxvYWRzIGlzIHJlbW92ZWQgYXV0b21hdGljYWxseS5cbiAgICpcbiAgICogQHBhcmFtIGNvbW1hbmRIYW5kbGVycyAtIFRoZSBjb21tYW5kIGhhbmRsZXJzIHRvIHJlZ2lzdGVyLlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBEaXNwb3NhYmxlfSB0aGF0IHVucmVnaXN0ZXJzIHRoZSBoYW5kbGVycyBwYXNzZWQgdG8gdGhpcyBjYWxsLlxuICAgKi9cbiAgcHVibGljIHJlZ2lzdGVyQ29tbWFuZEhhbmRsZXJzKGNvbW1hbmRIYW5kbGVyczogQ29tbWFuZEhhbmRsZXJbXSk6IERpc3Bvc2FibGUge1xuICAgIGNvbnN0IGNvbnRleHQ6IENvbW1hbmRIYW5kbGVyUmVnaXN0cmF0aW9uQ29udGV4dCA9IHtcbiAgICAgIGFjdGl2ZUZpbGVQcm92aWRlcjogdGhpcy5hY3RpdmVGaWxlUHJvdmlkZXIsXG4gICAgICBtZW51RXZlbnRSZWdpc3RyYXI6IHRoaXMubWVudUV2ZW50UmVnaXN0cmFyLFxuICAgICAgcGx1Z2luTmFtZTogdGhpcy5wbHVnaW5OYW1lXG4gICAgfTtcblxuICAgIGNvbnN0IGRpc3Bvc2FibGVzOiBEaXNwb3NhYmxlW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IGNvbW1hbmRIYW5kbGVyIG9mIGNvbW1hbmRIYW5kbGVycykge1xuICAgICAgY29uc3QgY29tbWFuZCA9IGNvbW1hbmRIYW5kbGVyLmJ1aWxkQ29tbWFuZCgpO1xuICAgICAgLy8gQ2FwdHVyZSB0aGUgaWQgYmVmb3JlIHJlZ2lzdGVyaW5nLiBgUGx1Z2luLmFkZENvbW1hbmRgIG11dGF0ZXMgYGNvbW1hbmQuaWRgIChwcmVmaXhpbmcgaXQgd2l0aFxuICAgICAgLy8gYHRoaXMubWFuaWZlc3QuaWRgKSwgd2hpbGUgYFBsdWdpbi5yZW1vdmVDb21tYW5kYCByZS1wcmVmaXhlcyBcdTIwMTQgc28gcmVtb3ZhbCBuZWVkcyB0aGUgb3JpZ2luYWwgaWQuXG4gICAgICAvLyBSZWFkaW5nIGBjb21tYW5kLmlkYCBhZnRlciBgYWRkQ29tbWFuZGAgd291bGQgZG91YmxlLXByZWZpeCBpdCwgc28gdGhlIGNvbW1hbmQgaXMgbmV2ZXIgcmVtb3ZlZC5cbiAgICAgIGNvbnN0IGNvbW1hbmRJZCA9IGNvbW1hbmQuaWQ7XG4gICAgICB0aGlzLmNvbW1hbmRSZWdpc3RyYXIuYWRkQ29tbWFuZChjb21tYW5kKTtcbiAgICAgIGNvbnN0IGRpc3Bvc2FibGUgPSBuZXcgQ2FsbGJhY2tEaXNwb3NhYmxlKHtcbiAgICAgICAgY2FsbGJhY2s6ICgpOiB2b2lkID0+IHtcbiAgICAgICAgICB0aGlzLmNvbW1hbmRSZWdpc3RyYXIucmVtb3ZlQ29tbWFuZChjb21tYW5kSWQpO1xuICAgICAgICB9LFxuICAgICAgICBtdWx0aXBsZURpc3Bvc2VCZWhhdmlvcjogTXVsdGlwbGVEaXNwb3NlQmVoYXZpb3IuSWdub3JlXG4gICAgICB9KTtcbiAgICAgIGRpc3Bvc2FibGVzLnB1c2goZGlzcG9zYWJsZSk7XG4gICAgICAvLyBUaWUgcmVtb3ZhbCB0byB0aGUgY29tcG9uZW50J3MgdW5sb2FkLCBzbyBhIGNvbW1hbmQgbmV2ZXIgb3V0bGl2ZXMgdGhlIGNvbXBvbmVudC5cbiAgICAgIHRoaXMucmVnaXN0ZXIoKCkgPT4ge1xuICAgICAgICBkaXNwb3NhYmxlLmRpc3Bvc2UoKTtcbiAgICAgIH0pO1xuICAgICAgaW52b2tlQXN5bmNTYWZlbHkoKCkgPT4gY29tbWFuZEhhbmRsZXIub25SZWdpc3RlcmVkKGNvbnRleHQpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IENvbWJpbmVEaXNwb3NhYmxlKHtcbiAgICAgIGRpc3Bvc2FibGVzLFxuICAgICAgbXVsdGlwbGVEaXNwb3NlQmVoYXZpb3I6IE11bHRpcGxlRGlzcG9zZUJlaGF2aW9yLklnbm9yZVxuICAgIH0pO1xuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQWNBLFNBQVMseUJBQXlCO0FBQ2xDO0FBQUEsRUFDRTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsT0FDSztBQUNQLFNBQVMsbUJBQW1CO0FBZ0JyQixNQUFNLGdDQUFnQyxZQUFZO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFJcEM7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUtBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFLQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBS0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPWixZQUFZLFFBQWtEO0FBQ25FLFVBQU07QUFDTixTQUFLLHFCQUFxQixPQUFPO0FBQ2pDLFNBQUsscUJBQXFCLE9BQU87QUFDakMsU0FBSyxtQkFBbUIsT0FBTztBQUMvQixTQUFLLGFBQWEsT0FBTztBQUFBLEVBQzNCO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFXTyx3QkFBd0IsaUJBQStDO0FBQzVFLFVBQU0sVUFBNkM7QUFBQSxNQUNqRCxvQkFBb0IsS0FBSztBQUFBLE1BQ3pCLG9CQUFvQixLQUFLO0FBQUEsTUFDekIsWUFBWSxLQUFLO0FBQUEsSUFDbkI7QUFFQSxVQUFNLGNBQTRCLENBQUM7QUFDbkMsZUFBVyxrQkFBa0IsaUJBQWlCO0FBQzVDLFlBQU0sVUFBVSxlQUFlLGFBQWE7QUFJNUMsWUFBTSxZQUFZLFFBQVE7QUFDMUIsV0FBSyxpQkFBaUIsV0FBVyxPQUFPO0FBQ3hDLFlBQU0sYUFBYSxJQUFJLG1CQUFtQjtBQUFBLFFBQ3hDLFVBQVUsTUFBWTtBQUNwQixlQUFLLGlCQUFpQixjQUFjLFNBQVM7QUFBQSxRQUMvQztBQUFBLFFBQ0EseUJBQXlCLHdCQUF3QjtBQUFBLE1BQ25ELENBQUM7QUFDRCxrQkFBWSxLQUFLLFVBQVU7QUFFM0IsV0FBSyxTQUFTLE1BQU07QUFDbEIsbUJBQVcsUUFBUTtBQUFBLE1BQ3JCLENBQUM7QUFDRCx3QkFBa0IsTUFBTSxlQUFlLGFBQWEsT0FBTyxDQUFDO0FBQUEsSUFDOUQ7QUFFQSxXQUFPLElBQUksa0JBQWtCO0FBQUEsTUFDM0I7QUFBQSxNQUNBLHlCQUF5Qix3QkFBd0I7QUFBQSxJQUNuRCxDQUFDO0FBQUEsRUFDSDtBQUNGOyIsCiAgIm5hbWVzIjogW10KfQo=
128
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL2NvbW1hbmQtaGFuZGxlcnMvY29tbWFuZC1oYW5kbGVyLWNvbXBvbmVudC50cyJdLAogICJzb3VyY2VzQ29udGVudCI6IFsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIENvbXBvbmVudCB0aGF0IHJlZ2lzdGVycyB7QGxpbmsgQ29tbWFuZEhhbmRsZXJ9cyB3aXRoIE9ic2lkaWFuIGFuZCB0aWVzIHRoZWlyIHJlbW92YWwgdG8gaXRzIGxpZmVjeWNsZS5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IERpc3Bvc2FibGVFeCB9IGZyb20gJy4uLy4uL2Rpc3Bvc2FibGUudHMnO1xuaW1wb3J0IHR5cGUgeyBBY3RpdmVGaWxlUHJvdmlkZXIgfSBmcm9tICcuLi9hY3RpdmUtZmlsZS1wcm92aWRlci50cyc7XG5pbXBvcnQgdHlwZSB7IENvbW1hbmRSZWdpc3RyYXIgfSBmcm9tICcuLi9jb21tYW5kLXJlZ2lzdHJhci50cyc7XG5pbXBvcnQgdHlwZSB7XG4gIEVkaXRvck1lbnVFdmVudEhhbmRsZXIsXG4gIEZpbGVNZW51RXZlbnRIYW5kbGVyLFxuICBGaWxlc01lbnVFdmVudEhhbmRsZXIsXG4gIE1lbnVFdmVudFJlZ2lzdHJhclxufSBmcm9tICcuLi9tZW51LWV2ZW50LXJlZ2lzdHJhci50cyc7XG5pbXBvcnQgdHlwZSB7XG4gIENvbW1hbmRIYW5kbGVyLFxuICBDb21tYW5kSGFuZGxlclJlZ2lzdHJhdGlvbkNvbnRleHRcbn0gZnJvbSAnLi9jb21tYW5kLWhhbmRsZXIudHMnO1xuXG5pbXBvcnQgeyBpbnZva2VBc3luY1NhZmVseSB9IGZyb20gJy4uLy4uL2FzeW5jLnRzJztcbmltcG9ydCB7XG4gIENhbGxiYWNrRGlzcG9zYWJsZSxcbiAgQ29tYmluZURpc3Bvc2FibGUsXG4gIERpc3Bvc2FibGVCYXNlXG59IGZyb20gJy4uLy4uL2Rpc3Bvc2FibGUudHMnO1xuaW1wb3J0IHsgQ29tcG9uZW50RXggfSBmcm9tICcuLi9jb21wb25lbnRzL2NvbXBvbmVudC1leC50cyc7XG5cbmludGVyZmFjZSBDb21tYW5kSGFuZGxlckNvbXBvbmVudENvbnN0cnVjdG9yUGFyYW1zIHtcbiAgcmVhZG9ubHkgYWN0aXZlRmlsZVByb3ZpZGVyOiBBY3RpdmVGaWxlUHJvdmlkZXI7XG4gIHJlYWRvbmx5IGNvbW1hbmRSZWdpc3RyYXI6IENvbW1hbmRSZWdpc3RyYXI7XG4gIHJlYWRvbmx5IG1lbnVFdmVudFJlZ2lzdHJhcjogTWVudUV2ZW50UmVnaXN0cmFyO1xuICByZWFkb25seSBwbHVnaW5OYW1lOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSBwZXItY29tbWFuZCB7QGxpbmsgTWVudUV2ZW50UmVnaXN0cmFyfSB0aGF0IGRlbGVnYXRlcyB0byBhIHNoYXJlZCByZWdpc3RyYXIgd2hpbGUgY29sbGVjdGluZyB0aGVcbiAqIHtAbGluayBEaXNwb3NhYmxlRXh9IGVhY2ggcmVnaXN0cmF0aW9uIHJldHVybnMsIHNvIGRpc3Bvc2luZyB0aGlzIHNjb3BlIHVucmVnaXN0ZXJzIGV4YWN0bHkgdGhhdCBjb21tYW5kJ3NcbiAqIG1lbnUgZXZlbnRzLiBCZWNhdXNlIHtAbGluayBDb21tYW5kSGFuZGxlci5vblJlZ2lzdGVyZWR9IHJ1bnMgZmlyZS1hbmQtZm9yZ2V0IChpdCBtYXkgcmVnaXN0ZXIgbWVudSBldmVudHNcbiAqIGFmdGVyIHRoaXMgc2NvcGUgaGFzIGFscmVhZHkgYmVlbiBkaXNwb3NlZCksIGEgcmVnaXN0cmF0aW9uIHRoYXQgYXJyaXZlcyBwb3N0LWRpc3Bvc2UgaXMgZGlzcG9zZWQgaW1tZWRpYXRlbHlcbiAqIGluc3RlYWQgb2YgbGVha2luZy5cbiAqL1xuY2xhc3MgQ29tbWFuZE1lbnVFdmVudFNjb3BlIGV4dGVuZHMgRGlzcG9zYWJsZUJhc2UgaW1wbGVtZW50cyBNZW51RXZlbnRSZWdpc3RyYXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGRpc3Bvc2FibGVzOiBEaXNwb3NhYmxlRXhbXSA9IFtdO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGlubmVyOiBNZW51RXZlbnRSZWdpc3RyYXIpIHtcbiAgICBzdXBlcigpO1xuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyRWRpdG9yTWVudUV2ZW50SGFuZGxlcihoYW5kbGVyOiBFZGl0b3JNZW51RXZlbnRIYW5kbGVyKTogRGlzcG9zYWJsZUV4IHtcbiAgICByZXR1cm4gdGhpcy5jb2xsZWN0KHRoaXMuaW5uZXIucmVnaXN0ZXJFZGl0b3JNZW51RXZlbnRIYW5kbGVyKGhhbmRsZXIpKTtcbiAgfVxuXG4gIHB1YmxpYyByZWdpc3RlckZpbGVNZW51RXZlbnRIYW5kbGVyKGhhbmRsZXI6IEZpbGVNZW51RXZlbnRIYW5kbGVyKTogRGlzcG9zYWJsZUV4IHtcbiAgICByZXR1cm4gdGhpcy5jb2xsZWN0KHRoaXMuaW5uZXIucmVnaXN0ZXJGaWxlTWVudUV2ZW50SGFuZGxlcihoYW5kbGVyKSk7XG4gIH1cblxuICBwdWJsaWMgcmVnaXN0ZXJGaWxlc01lbnVFdmVudEhhbmRsZXIoaGFuZGxlcjogRmlsZXNNZW51RXZlbnRIYW5kbGVyKTogRGlzcG9zYWJsZUV4IHtcbiAgICByZXR1cm4gdGhpcy5jb2xsZWN0KHRoaXMuaW5uZXIucmVnaXN0ZXJGaWxlc01lbnVFdmVudEhhbmRsZXIoaGFuZGxlcikpO1xuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIHBlcmZvcm1EaXNwb3NlKCk6IHZvaWQge1xuICAgIGZvciAoY29uc3QgZGlzcG9zYWJsZSBvZiB0aGlzLmRpc3Bvc2FibGVzKSB7XG4gICAgICBkaXNwb3NhYmxlLmRpc3Bvc2UoKTtcbiAgICB9XG4gICAgdGhpcy5kaXNwb3NhYmxlcy5sZW5ndGggPSAwO1xuICB9XG5cbiAgcHJpdmF0ZSBjb2xsZWN0KGRpc3Bvc2FibGU6IERpc3Bvc2FibGVFeCk6IERpc3Bvc2FibGVFeCB7XG4gICAgaWYgKHRoaXMuaXNEaXNwb3NlZCkge1xuICAgICAgZGlzcG9zYWJsZS5kaXNwb3NlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZGlzcG9zYWJsZXMucHVzaChkaXNwb3NhYmxlKTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGlzcG9zYWJsZTtcbiAgfVxufVxuXG4vKipcbiAqIFJlZ2lzdGVycyB7QGxpbmsgQ29tbWFuZEhhbmRsZXJ9cyB3aXRoIE9ic2lkaWFuIGFuZCBtYW5hZ2VzIHRoZWlyIGxpZmVjeWNsZS5cbiAqXG4gKiBDYWxsIHtAbGluayByZWdpc3RlckNvbW1hbmRIYW5kbGVyc30gdG8gcmVnaXN0ZXIgYSBiYXRjaCBvZiBoYW5kbGVycyBvbiBkZW1hbmQgKGFzIG1hbnkgdGltZXMgYXNcbiAqIG5lZWRlZCB3aGlsZSB0aGUgY29tcG9uZW50IGlzIGFsaXZlKTsgZGlzcG9zZSB0aGUgcmV0dXJuZWQge0BsaW5rIERpc3Bvc2FibGVFeH0gdG8gdW5yZWdpc3RlciBleGFjdGx5XG4gKiB0aG9zZSBoYW5kbGVycyBcdTIwMTQgaW5jbHVkaW5nIGFueSBtZW51IGV2ZW50cyB0aGV5IHJlZ2lzdGVyZWQgXHUyMDE0IG9yIGxldCB0aGUgY29tcG9uZW50IHVubG9hZCB0byByZW1vdmUgZXZlcnlcbiAqIGNvbW1hbmQgc3RpbGwgcmVnaXN0ZXJlZCB0aHJvdWdoIGl0LlxuICovXG5leHBvcnQgY2xhc3MgQ29tbWFuZEhhbmRsZXJDb21wb25lbnQgZXh0ZW5kcyBDb21wb25lbnRFeCB7XG4gIC8qKlxuICAgKiBQcm92aWRlciBmb3IgYWNjZXNzaW5nIHRoZSBjdXJyZW50bHkgYWN0aXZlIGZpbGUuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgYWN0aXZlRmlsZVByb3ZpZGVyOiBBY3RpdmVGaWxlUHJvdmlkZXI7XG5cbiAgLyoqXG4gICAqIFJlZ2lzdHJhciB1c2VkIHRvIGFkZCBhbmQgcmVtb3ZlIGNvbW1hbmRzIHdpdGggT2JzaWRpYW4uXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgY29tbWFuZFJlZ2lzdHJhcjogQ29tbWFuZFJlZ2lzdHJhcjtcblxuICAvKipcbiAgICogUmVnaXN0cmFyIGZvciBtZW51IGV2ZW50IGhhbmRsZXJzLlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IG1lbnVFdmVudFJlZ2lzdHJhcjogTWVudUV2ZW50UmVnaXN0cmFyO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGUgcGx1Z2luIHRoYXQgb3ducyB0aGUgY29tbWFuZHMuXG4gICAqL1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgcGx1Z2luTmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgbmV3IGNvbW1hbmQgaGFuZGxlciBjb21wb25lbnQuXG4gICAqXG4gICAqIEBwYXJhbSBwYXJhbXMgLSBUaGUgY29uc3RydWN0b3IgcGFyYW1ldGVycy5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcihwYXJhbXM6IENvbW1hbmRIYW5kbGVyQ29tcG9uZW50Q29uc3RydWN0b3JQYXJhbXMpIHtcbiAgICBzdXBlcigpO1xuICAgIHRoaXMuYWN0aXZlRmlsZVByb3ZpZGVyID0gcGFyYW1zLmFjdGl2ZUZpbGVQcm92aWRlcjtcbiAgICB0aGlzLm1lbnVFdmVudFJlZ2lzdHJhciA9IHBhcmFtcy5tZW51RXZlbnRSZWdpc3RyYXI7XG4gICAgdGhpcy5jb21tYW5kUmVnaXN0cmFyID0gcGFyYW1zLmNvbW1hbmRSZWdpc3RyYXI7XG4gICAgdGhpcy5wbHVnaW5OYW1lID0gcGFyYW1zLnBsdWdpbk5hbWU7XG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIHRoZSBnaXZlbiBjb21tYW5kIGhhbmRsZXJzIHdpdGggT2JzaWRpYW4gYW5kIHByb3ZpZGVzIGVhY2ggaXRzIG93biBydW50aW1lIHJlZ2lzdHJhdGlvblxuICAgKiBjb250ZXh0LiBFYWNoIGhhbmRsZXIncyBjb21tYW5kIGlzIGFkZGVkIGltbWVkaWF0ZWx5OyB0aGUgcmV0dXJuZWQge0BsaW5rIERpc3Bvc2FibGVFeH0gcmVtb3ZlcyB0aGVcbiAgICogY29tbWFuZHMgcmVnaXN0ZXJlZCBieSB0aGlzIGNhbGwgXHUyMDE0IGFuZCBhbnkgbWVudSBldmVudHMgdGhvc2UgaGFuZGxlcnMgcmVnaXN0ZXJlZCB2aWEgdGhlaXIgY29udGV4dCdzXG4gICAqIHtAbGluayBNZW51RXZlbnRSZWdpc3RyYXJ9IFx1MjAxNCB3aGVuIGRpc3Bvc2VkLiBBbnkgY29tbWFuZCBzdGlsbCByZWdpc3RlcmVkIHdoZW4gdGhlIGNvbXBvbmVudCB1bmxvYWRzIGlzXG4gICAqIHJlbW92ZWQgYXV0b21hdGljYWxseS5cbiAgICpcbiAgICogQHBhcmFtIGNvbW1hbmRIYW5kbGVycyAtIFRoZSBjb21tYW5kIGhhbmRsZXJzIHRvIHJlZ2lzdGVyLlxuICAgKiBAcmV0dXJucyBBIHtAbGluayBEaXNwb3NhYmxlRXh9IHRoYXQgdW5yZWdpc3RlcnMgdGhlIGhhbmRsZXJzIChjb21tYW5kcyArIG1lbnUgZXZlbnRzKSBwYXNzZWQgdG8gdGhpcyBjYWxsLlxuICAgKi9cbiAgcHVibGljIHJlZ2lzdGVyQ29tbWFuZEhhbmRsZXJzKGNvbW1hbmRIYW5kbGVyczogQ29tbWFuZEhhbmRsZXJbXSk6IERpc3Bvc2FibGVFeCB7XG4gICAgY29uc3QgZGlzcG9zYWJsZXM6IERpc3Bvc2FibGVbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgY29tbWFuZEhhbmRsZXIgb2YgY29tbWFuZEhhbmRsZXJzKSB7XG4gICAgICBjb25zdCBjb21tYW5kID0gY29tbWFuZEhhbmRsZXIuYnVpbGRDb21tYW5kKCk7XG4gICAgICAvLyBDYXB0dXJlIHRoZSBpZCBiZWZvcmUgcmVnaXN0ZXJpbmcuIGBQbHVnaW4uYWRkQ29tbWFuZGAgbXV0YXRlcyBgY29tbWFuZC5pZGAgKHByZWZpeGluZyBpdCB3aXRoXG4gICAgICAvLyBgdGhpcy5tYW5pZmVzdC5pZGApLCB3aGlsZSBgUGx1Z2luLnJlbW92ZUNvbW1hbmRgIHJlLXByZWZpeGVzIFx1MjAxNCBzbyByZW1vdmFsIG5lZWRzIHRoZSBvcmlnaW5hbCBpZC5cbiAgICAgIC8vIFJlYWRpbmcgYGNvbW1hbmQuaWRgIGFmdGVyIGBhZGRDb21tYW5kYCB3b3VsZCBkb3VibGUtcHJlZml4IGl0LCBzbyB0aGUgY29tbWFuZCBpcyBuZXZlciByZW1vdmVkLlxuICAgICAgY29uc3QgY29tbWFuZElkID0gY29tbWFuZC5pZDtcbiAgICAgIHRoaXMuY29tbWFuZFJlZ2lzdHJhci5hZGRDb21tYW5kKGNvbW1hbmQpO1xuXG4gICAgICAvLyBFYWNoIGNvbW1hbmQgZ2V0cyBpdHMgb3duIHJlZ2lzdHJhdGlvbiBjb250ZXh0IHdpdGggYSBwZXItY29tbWFuZCBtZW51LWV2ZW50IHNjb3BlLCBzbyBkaXNwb3Npbmcgb25lXG4gICAgICAvLyBDb21tYW5kIHRlYXJzIGRvd24gaXRzIG93biBtZW51IGV2ZW50cyB3aXRob3V0IGFmZmVjdGluZyB0aGUgb3RoZXJzLlxuICAgICAgY29uc3QgbWVudUV2ZW50U2NvcGUgPSBuZXcgQ29tbWFuZE1lbnVFdmVudFNjb3BlKHRoaXMubWVudUV2ZW50UmVnaXN0cmFyKTtcbiAgICAgIGNvbnN0IGNvbnRleHQ6IENvbW1hbmRIYW5kbGVyUmVnaXN0cmF0aW9uQ29udGV4dCA9IHtcbiAgICAgICAgYWN0aXZlRmlsZVByb3ZpZGVyOiB0aGlzLmFjdGl2ZUZpbGVQcm92aWRlcixcbiAgICAgICAgbWVudUV2ZW50UmVnaXN0cmFyOiBtZW51RXZlbnRTY29wZSxcbiAgICAgICAgcGx1Z2luTmFtZTogdGhpcy5wbHVnaW5OYW1lXG4gICAgICB9O1xuXG4gICAgICBjb25zdCBkaXNwb3NhYmxlID0gbmV3IENhbGxiYWNrRGlzcG9zYWJsZSh7XG4gICAgICAgIGNhbGxiYWNrOiAoKTogdm9pZCA9PiB7XG4gICAgICAgICAgdGhpcy5jb21tYW5kUmVnaXN0cmFyLnJlbW92ZUNvbW1hbmQoY29tbWFuZElkKTtcbiAgICAgICAgICBtZW51RXZlbnRTY29wZS5kaXNwb3NlKCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgLy8gVGllIHJlbW92YWwgdG8gdGhlIGNvbXBvbmVudCdzIHVubG9hZCwgc28gYSBjb21tYW5kIG5ldmVyIG91dGxpdmVzIHRoZSBjb21wb25lbnQuXG4gICAgICBkaXNwb3NhYmxlcy5wdXNoKHRoaXMucmVnaXN0ZXJEaXNwb3NhYmxlKGRpc3Bvc2FibGUpKTtcbiAgICAgIGludm9rZUFzeW5jU2FmZWx5KCgpID0+IGNvbW1hbmRIYW5kbGVyLm9uUmVnaXN0ZXJlZChjb250ZXh0KSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBDb21iaW5lRGlzcG9zYWJsZSh7IGRpc3Bvc2FibGVzIH0pO1xuICB9XG59XG4iXSwKICAibWFwcGluZ3MiOiAiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQW9CQSxTQUFTLHlCQUF5QjtBQUNsQztBQUFBLEVBQ0U7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLE9BQ0s7QUFDUCxTQUFTLG1CQUFtQjtBQWdCNUIsTUFBTSw4QkFBOEIsZUFBNkM7QUFBQSxFQUd4RSxZQUE2QixPQUEyQjtBQUM3RCxVQUFNO0FBRDRCO0FBQUEsRUFFcEM7QUFBQSxFQUZvQztBQUFBLEVBRm5CLGNBQThCLENBQUM7QUFBQSxFQU16QywrQkFBK0IsU0FBK0M7QUFDbkYsV0FBTyxLQUFLLFFBQVEsS0FBSyxNQUFNLCtCQUErQixPQUFPLENBQUM7QUFBQSxFQUN4RTtBQUFBLEVBRU8sNkJBQTZCLFNBQTZDO0FBQy9FLFdBQU8sS0FBSyxRQUFRLEtBQUssTUFBTSw2QkFBNkIsT0FBTyxDQUFDO0FBQUEsRUFDdEU7QUFBQSxFQUVPLDhCQUE4QixTQUE4QztBQUNqRixXQUFPLEtBQUssUUFBUSxLQUFLLE1BQU0sOEJBQThCLE9BQU8sQ0FBQztBQUFBLEVBQ3ZFO0FBQUEsRUFFbUIsaUJBQXVCO0FBQ3hDLGVBQVcsY0FBYyxLQUFLLGFBQWE7QUFDekMsaUJBQVcsUUFBUTtBQUFBLElBQ3JCO0FBQ0EsU0FBSyxZQUFZLFNBQVM7QUFBQSxFQUM1QjtBQUFBLEVBRVEsUUFBUSxZQUF3QztBQUN0RCxRQUFJLEtBQUssWUFBWTtBQUNuQixpQkFBVyxRQUFRO0FBQUEsSUFDckIsT0FBTztBQUNMLFdBQUssWUFBWSxLQUFLLFVBQVU7QUFBQSxJQUNsQztBQUVBLFdBQU87QUFBQSxFQUNUO0FBQ0Y7QUFVTyxNQUFNLGdDQUFnQyxZQUFZO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFJcEM7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUtBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFLQTtBQUFBO0FBQUE7QUFBQTtBQUFBLEVBS0E7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsRUFPWixZQUFZLFFBQWtEO0FBQ25FLFVBQU07QUFDTixTQUFLLHFCQUFxQixPQUFPO0FBQ2pDLFNBQUsscUJBQXFCLE9BQU87QUFDakMsU0FBSyxtQkFBbUIsT0FBTztBQUMvQixTQUFLLGFBQWEsT0FBTztBQUFBLEVBQzNCO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQVlPLHdCQUF3QixpQkFBaUQ7QUFDOUUsVUFBTSxjQUE0QixDQUFDO0FBQ25DLGVBQVcsa0JBQWtCLGlCQUFpQjtBQUM1QyxZQUFNLFVBQVUsZUFBZSxhQUFhO0FBSTVDLFlBQU0sWUFBWSxRQUFRO0FBQzFCLFdBQUssaUJBQWlCLFdBQVcsT0FBTztBQUl4QyxZQUFNLGlCQUFpQixJQUFJLHNCQUFzQixLQUFLLGtCQUFrQjtBQUN4RSxZQUFNLFVBQTZDO0FBQUEsUUFDakQsb0JBQW9CLEtBQUs7QUFBQSxRQUN6QixvQkFBb0I7QUFBQSxRQUNwQixZQUFZLEtBQUs7QUFBQSxNQUNuQjtBQUVBLFlBQU0sYUFBYSxJQUFJLG1CQUFtQjtBQUFBLFFBQ3hDLFVBQVUsTUFBWTtBQUNwQixlQUFLLGlCQUFpQixjQUFjLFNBQVM7QUFDN0MseUJBQWUsUUFBUTtBQUFBLFFBQ3pCO0FBQUEsTUFDRixDQUFDO0FBRUQsa0JBQVksS0FBSyxLQUFLLG1CQUFtQixVQUFVLENBQUM7QUFDcEQsd0JBQWtCLE1BQU0sZUFBZSxhQUFhLE9BQU8sQ0FBQztBQUFBLElBQzlEO0FBRUEsV0FBTyxJQUFJLGtCQUFrQixFQUFFLFlBQVksQ0FBQztBQUFBLEVBQzlDO0FBQ0Y7IiwKICAibmFtZXMiOiBbXQp9Cg==
@@ -55,7 +55,7 @@ class OpenDemoVaultCommandHandler extends GlobalCommandHandler {
55
55
  * Executes the command, opening the plugin's demo vault.
56
56
  */
57
57
  async execute() {
58
- const { openDemoVault } = await import("../desktop-demo-vault-opener.ts");
58
+ const { openDemoVault } = await import("../desktop-demo-vault-opener.mjs");
59
59
  await openDemoVault({
60
60
  app: this.app,
61
61
  manifest: this.manifest,
@@ -2,12 +2,128 @@
2
2
  /**
3
3
  * @file
4
4
  *
5
- * Resolves a community plugin's GitHub repository from Obsidian's public plugin registry.
5
+ * Resolves, searches and manages community plugins through Obsidian's public plugin registry and
6
+ * store-install path.
6
7
  *
7
8
  * Obsidian's `community-plugins.json` is the authoritative source that maps a plugin `id` to its
8
- * `owner/name` GitHub repository — the plugin manifest itself carries no repository. This is used to
9
- * locate a plugin's GitHub releases (e.g. to download its shipped demo-vault archive).
9
+ * `owner/name` GitHub repository — the plugin manifest itself carries no repository. This module uses
10
+ * it to search the registry, to locate a plugin's GitHub releases (e.g. to download its shipped
11
+ * demo-vault archive), and to install/uninstall/enable/disable an arbitrary community plugin — selected
12
+ * by either its `id` or its display `name` — via Obsidian's own store path (`app.plugins.installPlugin`
13
+ * + `enablePluginAndSave`), so any dev/deploy or tooling flow can reuse it.
10
14
  */
15
+ import type { App } from 'obsidian';
16
+ /**
17
+ * Selects a community plugin either by its id ({@link CommunityPluginByIdRef}) or by its display name
18
+ * ({@link CommunityPluginByNameRef}).
19
+ */
20
+ export type CommunityPluginRef = CommunityPluginByIdRef | CommunityPluginByNameRef;
21
+ /**
22
+ * A single result of {@link searchCommunityPlugins}.
23
+ */
24
+ export interface CommunityPluginSearchResult {
25
+ /**
26
+ * The plugin id.
27
+ */
28
+ readonly id: string;
29
+ /**
30
+ * The plugin display name.
31
+ */
32
+ readonly name: string;
33
+ }
34
+ /**
35
+ * Parameters for {@link disableCommunityPlugin}. Selects the plugin by either `pluginId` or
36
+ * `pluginName`.
37
+ */
38
+ export type DisableCommunityPluginParams = CommunityPluginOperationContext & CommunityPluginRef;
39
+ /**
40
+ * Parameters for {@link enableCommunityPlugin}. Selects the plugin by either `pluginId` or
41
+ * `pluginName`.
42
+ */
43
+ export type EnableCommunityPluginParams = CommunityPluginOperationContext & CommunityPluginRef;
44
+ /**
45
+ * Parameters for {@link installCommunityPlugin}. Selects the plugin by either `pluginId` or
46
+ * `pluginName`.
47
+ */
48
+ export type InstallCommunityPluginParams = CommunityPluginOperationContext & CommunityPluginRef;
49
+ /**
50
+ * Parameters for {@link toggleEnableCommunityPlugin}. Selects the plugin by either `pluginId` or
51
+ * `pluginName`.
52
+ */
53
+ export type ToggleEnableCommunityPluginParams = CommunityPluginOperationContext & CommunityPluginRef & CommunityPluginToggleEnableState;
54
+ /**
55
+ * Parameters for {@link toggleInstallCommunityPlugin}. Selects the plugin by either `pluginId` or
56
+ * `pluginName`.
57
+ */
58
+ export type ToggleInstallCommunityPluginParams = CommunityPluginOperationContext & CommunityPluginRef & CommunityPluginToggleInstallState;
59
+ /**
60
+ * Parameters for {@link uninstallCommunityPlugin}. Selects the plugin by either `pluginId` or
61
+ * `pluginName`.
62
+ */
63
+ export type UninstallCommunityPluginParams = CommunityPluginOperationContext & CommunityPluginRef;
64
+ /**
65
+ * Selects a community plugin by its id.
66
+ */
67
+ interface CommunityPluginByIdRef {
68
+ /**
69
+ * The plugin id.
70
+ */
71
+ readonly pluginId: string;
72
+ }
73
+ /**
74
+ * Selects a community plugin by its display name (as listed in Obsidian's community registry).
75
+ */
76
+ interface CommunityPluginByNameRef {
77
+ /**
78
+ * The plugin display name.
79
+ */
80
+ readonly pluginName: string;
81
+ }
82
+ /**
83
+ * The Obsidian app instance a community-plugin operation runs against.
84
+ */
85
+ interface CommunityPluginOperationContext {
86
+ /**
87
+ * The Obsidian app instance.
88
+ */
89
+ readonly app: App;
90
+ }
91
+ /**
92
+ * The desired enabled state for {@link toggleEnableCommunityPlugin}.
93
+ */
94
+ interface CommunityPluginToggleEnableState {
95
+ /**
96
+ * The desired enabled state: `true` enables the plugin, `false` disables it.
97
+ */
98
+ readonly isEnabled: boolean;
99
+ }
100
+ /**
101
+ * The desired installed state for {@link toggleInstallCommunityPlugin}.
102
+ */
103
+ interface CommunityPluginToggleInstallState {
104
+ /**
105
+ * The desired installed state: `true` installs the plugin, `false` uninstalls it.
106
+ */
107
+ readonly isInstalled: boolean;
108
+ }
109
+ /**
110
+ * Disables a community plugin (persisting the change) if it is currently enabled. Idempotent — a no-op
111
+ * when the plugin is already disabled.
112
+ *
113
+ * @param params - The {@link DisableCommunityPluginParams}.
114
+ * @returns A {@link Promise} that resolves once the plugin is disabled.
115
+ * @throws If selected by `pluginName` and the name is not listed in Obsidian's community plugins registry.
116
+ */
117
+ export declare function disableCommunityPlugin(params: DisableCommunityPluginParams): Promise<void>;
118
+ /**
119
+ * Enables a community plugin (persisting the change) if it is not already enabled. Idempotent — a no-op
120
+ * when the plugin is already enabled.
121
+ *
122
+ * @param params - The {@link EnableCommunityPluginParams}.
123
+ * @returns A {@link Promise} that resolves once the plugin is enabled.
124
+ * @throws If selected by `pluginName` and the name is not listed in Obsidian's community plugins registry.
125
+ */
126
+ export declare function enableCommunityPlugin(params: EnableCommunityPluginParams): Promise<void>;
11
127
  /**
12
128
  * Resolves the `owner/name` GitHub repository of a community plugin from Obsidian's public
13
129
  * `community-plugins.json` registry.
@@ -20,3 +136,59 @@
20
136
  * plugin is not listed in the registry.
21
137
  */
22
138
  export declare function getCommunityPluginRepo(pluginId: string): Promise<null | string>;
139
+ /**
140
+ * Resolves the latest release version (the release `tag_name`, a bare version such as `1.2.3`) of a
141
+ * GitHub repository.
142
+ *
143
+ * @param repo - The `owner/name` GitHub repository.
144
+ * @returns A {@link Promise} resolving to the latest release version.
145
+ */
146
+ export declare function getLatestReleaseVersion(repo: string): Promise<string>;
147
+ /**
148
+ * Installs a community plugin from the official store if it is not already installed. Idempotent — a
149
+ * no-op when the plugin is already installed. Resolves the plugin's repository from Obsidian's
150
+ * community registry, reads the latest release version and its manifest, and installs it through
151
+ * Obsidian's own `installPlugin` path.
152
+ *
153
+ * @param params - The {@link InstallCommunityPluginParams}.
154
+ * @returns A {@link Promise} that resolves once the plugin is installed.
155
+ * @throws If the plugin is not listed in Obsidian's community plugins registry.
156
+ */
157
+ export declare function installCommunityPlugin(params: InstallCommunityPluginParams): Promise<void>;
158
+ /**
159
+ * Searches Obsidian's public community plugins registry, returning the id and display name of every
160
+ * plugin whose id, name, author or description contains the query (case-insensitive). An empty query
161
+ * matches every plugin.
162
+ *
163
+ * @param query - The search query.
164
+ * @returns A {@link Promise} resolving to the matching plugins' {@link CommunityPluginSearchResult}s.
165
+ */
166
+ export declare function searchCommunityPlugins(query: string): Promise<CommunityPluginSearchResult[]>;
167
+ /**
168
+ * Enables or disables a community plugin to match the desired state. Delegates to
169
+ * {@link enableCommunityPlugin} / {@link disableCommunityPlugin}, so it is idempotent.
170
+ *
171
+ * @param params - The {@link ToggleEnableCommunityPluginParams}.
172
+ * @returns A {@link Promise} that resolves once the plugin matches the desired enabled state.
173
+ * @throws If selected by `pluginName` and the name is not listed in Obsidian's community plugins registry.
174
+ */
175
+ export declare function toggleEnableCommunityPlugin(params: ToggleEnableCommunityPluginParams): Promise<void>;
176
+ /**
177
+ * Installs or uninstalls a community plugin to match the desired state. Delegates to
178
+ * {@link installCommunityPlugin} / {@link uninstallCommunityPlugin}, so it is idempotent.
179
+ *
180
+ * @param params - The {@link ToggleInstallCommunityPluginParams}.
181
+ * @returns A {@link Promise} that resolves once the plugin matches the desired installed state.
182
+ * @throws If installing and the plugin is not listed in Obsidian's community plugins registry.
183
+ */
184
+ export declare function toggleInstallCommunityPlugin(params: ToggleInstallCommunityPluginParams): Promise<void>;
185
+ /**
186
+ * Uninstalls a community plugin if it is currently installed. Idempotent — a no-op when the plugin is
187
+ * not installed.
188
+ *
189
+ * @param params - The {@link UninstallCommunityPluginParams}.
190
+ * @returns A {@link Promise} that resolves once the plugin is uninstalled.
191
+ * @throws If selected by `pluginName` and the name is not listed in Obsidian's community plugins registry.
192
+ */
193
+ export declare function uninstallCommunityPlugin(params: UninstallCommunityPluginParams): Promise<void>;
194
+ export {};
@@ -25,24 +25,116 @@ import { requestUrl } from "obsidian";
25
25
  import { getObsidianDevUtilsState } from "../obsidian-dev-utils-state.mjs";
26
26
  const COMMUNITY_PLUGINS_STATE_KEY = "communityPluginEntriesPromise";
27
27
  const COMMUNITY_PLUGINS_URL = "https://raw.githubusercontent.com/obsidianmd/obsidian-releases/HEAD/community-plugins.json";
28
+ async function disableCommunityPlugin(params) {
29
+ const { app } = params;
30
+ const pluginId = await resolveCommunityPluginId(params);
31
+ if (!app.plugins.enabledPlugins.has(pluginId)) {
32
+ return;
33
+ }
34
+ await app.plugins.disablePluginAndSave(pluginId);
35
+ }
36
+ async function enableCommunityPlugin(params) {
37
+ const { app } = params;
38
+ const pluginId = await resolveCommunityPluginId(params);
39
+ if (app.plugins.enabledPlugins.has(pluginId)) {
40
+ return;
41
+ }
42
+ await app.plugins.enablePluginAndSave(pluginId);
43
+ }
28
44
  async function getCommunityPluginRepo(pluginId) {
45
+ const entries = await getCommunityPluginEntries();
46
+ const entry = entries.find((candidate) => candidate.id === pluginId);
47
+ return entry?.repo ?? null;
48
+ }
49
+ async function getLatestReleaseVersion(repo) {
50
+ const response = await requestUrl(`https://api.github.com/repos/${repo}/releases/latest`);
51
+ const release = response.json;
52
+ return release.tag_name;
53
+ }
54
+ async function installCommunityPlugin(params) {
55
+ const { app } = params;
56
+ const pluginId = await resolveCommunityPluginId(params);
57
+ if (app.plugins.manifests[pluginId]) {
58
+ return;
59
+ }
60
+ const repo = await getCommunityPluginRepo(pluginId);
61
+ if (!repo) {
62
+ throw new Error(`Plugin '${pluginId}' was not found in the Obsidian community plugins registry.`);
63
+ }
64
+ const version = await getLatestReleaseVersion(repo);
65
+ const manifest = await getPluginManifest(repo, version);
66
+ await app.plugins.installPlugin(repo, version, manifest);
67
+ }
68
+ async function searchCommunityPlugins(query) {
69
+ const entries = await getCommunityPluginEntries();
70
+ const normalizedQuery = query.toLowerCase();
71
+ return entries.filter(
72
+ (entry) => entry.id.toLowerCase().includes(normalizedQuery) || entry.name.toLowerCase().includes(normalizedQuery) || entry.author.toLowerCase().includes(normalizedQuery) || entry.description.toLowerCase().includes(normalizedQuery)
73
+ ).map((entry) => ({
74
+ id: entry.id,
75
+ name: entry.name
76
+ }));
77
+ }
78
+ async function toggleEnableCommunityPlugin(params) {
79
+ if (params.isEnabled) {
80
+ await enableCommunityPlugin(params);
81
+ } else {
82
+ await disableCommunityPlugin(params);
83
+ }
84
+ }
85
+ async function toggleInstallCommunityPlugin(params) {
86
+ if (params.isInstalled) {
87
+ await installCommunityPlugin(params);
88
+ } else {
89
+ await uninstallCommunityPlugin(params);
90
+ }
91
+ }
92
+ async function uninstallCommunityPlugin(params) {
93
+ const { app } = params;
94
+ const pluginId = await resolveCommunityPluginId(params);
95
+ if (!app.plugins.manifests[pluginId]) {
96
+ return;
97
+ }
98
+ await app.plugins.uninstallPlugin(pluginId);
99
+ }
100
+ async function fetchCommunityPluginEntries() {
101
+ const response = await requestUrl(COMMUNITY_PLUGINS_URL);
102
+ return response.json;
103
+ }
104
+ async function getCommunityPluginEntries() {
29
105
  const cache = getObsidianDevUtilsState(COMMUNITY_PLUGINS_STATE_KEY, null);
30
106
  cache.value ??= fetchCommunityPluginEntries();
31
- let entries;
32
107
  try {
33
- entries = await cache.value;
108
+ return await cache.value;
34
109
  } catch (error) {
35
110
  cache.value = null;
36
111
  throw error;
37
112
  }
38
- const entry = entries.find((candidate) => candidate.id === pluginId);
39
- return entry?.repo ?? null;
40
113
  }
41
- async function fetchCommunityPluginEntries() {
42
- const response = await requestUrl(COMMUNITY_PLUGINS_URL);
114
+ async function getPluginManifest(repo, version) {
115
+ const response = await requestUrl(`https://github.com/${repo}/releases/download/${version}/manifest.json`);
43
116
  return response.json;
44
117
  }
118
+ async function resolveCommunityPluginId(ref) {
119
+ if ("pluginId" in ref) {
120
+ return ref.pluginId;
121
+ }
122
+ const entries = await getCommunityPluginEntries();
123
+ const entry = entries.find((candidate) => candidate.name === ref.pluginName);
124
+ if (!entry) {
125
+ throw new Error(`Plugin named '${ref.pluginName}' was not found in the Obsidian community plugins registry.`);
126
+ }
127
+ return entry.id;
128
+ }
45
129
  export {
46
- getCommunityPluginRepo
130
+ disableCommunityPlugin,
131
+ enableCommunityPlugin,
132
+ getCommunityPluginRepo,
133
+ getLatestReleaseVersion,
134
+ installCommunityPlugin,
135
+ searchCommunityPlugins,
136
+ toggleEnableCommunityPlugin,
137
+ toggleInstallCommunityPlugin,
138
+ uninstallCommunityPlugin
47
139
  };
48
- //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL2NvbW11bml0eS1wbHVnaW5zLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogUmVzb2x2ZXMgYSBjb21tdW5pdHkgcGx1Z2luJ3MgR2l0SHViIHJlcG9zaXRvcnkgZnJvbSBPYnNpZGlhbidzIHB1YmxpYyBwbHVnaW4gcmVnaXN0cnkuXG4gKlxuICogT2JzaWRpYW4ncyBgY29tbXVuaXR5LXBsdWdpbnMuanNvbmAgaXMgdGhlIGF1dGhvcml0YXRpdmUgc291cmNlIHRoYXQgbWFwcyBhIHBsdWdpbiBgaWRgIHRvIGl0c1xuICogYG93bmVyL25hbWVgIEdpdEh1YiByZXBvc2l0b3J5IFx1MjAxNCB0aGUgcGx1Z2luIG1hbmlmZXN0IGl0c2VsZiBjYXJyaWVzIG5vIHJlcG9zaXRvcnkuIFRoaXMgaXMgdXNlZCB0b1xuICogbG9jYXRlIGEgcGx1Z2luJ3MgR2l0SHViIHJlbGVhc2VzIChlLmcuIHRvIGRvd25sb2FkIGl0cyBzaGlwcGVkIGRlbW8tdmF1bHQgYXJjaGl2ZSkuXG4gKi9cblxuaW1wb3J0IHsgcmVxdWVzdFVybCB9IGZyb20gJ29ic2lkaWFuJztcblxuaW1wb3J0IHsgZ2V0T2JzaWRpYW5EZXZVdGlsc1N0YXRlIH0gZnJvbSAnLi4vb2JzaWRpYW4tZGV2LXV0aWxzLXN0YXRlLnRzJztcblxuLyoqXG4gKiBBIHNpbmdsZSBlbnRyeSBpbiBPYnNpZGlhbidzIGBjb21tdW5pdHktcGx1Z2lucy5qc29uYCByZWdpc3RyeS5cbiAqL1xuaW50ZXJmYWNlIENvbW11bml0eVBsdWdpbkVudHJ5IHtcbiAgLyoqXG4gICAqIFRoZSBwbHVnaW4gYXV0aG9yLlxuICAgKi9cbiAgcmVhZG9ubHkgYXV0aG9yOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwbHVnaW4gZGVzY3JpcHRpb24uXG4gICAqL1xuICByZWFkb25seSBkZXNjcmlwdGlvbjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcGx1Z2luIGlkLlxuICAgKi9cbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHBsdWdpbiBkaXNwbGF5IG5hbWUuXG4gICAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwbHVnaW4ncyBgb3duZXIvbmFtZWAgR2l0SHViIHJlcG9zaXRvcnkuXG4gICAqL1xuICByZWFkb25seSByZXBvOiBzdHJpbmc7XG59XG5cbmNvbnN0IENPTU1VTklUWV9QTFVHSU5TX1NUQVRFX0tFWSA9ICdjb21tdW5pdHlQbHVnaW5FbnRyaWVzUHJvbWlzZSc7XG5jb25zdCBDT01NVU5JVFlfUExVR0lOU19VUkwgPSAnaHR0cHM6Ly9yYXcuZ2l0aHVidXNlcmNvbnRlbnQuY29tL29ic2lkaWFubWQvb2JzaWRpYW4tcmVsZWFzZXMvSEVBRC9jb21tdW5pdHktcGx1Z2lucy5qc29uJztcblxuLyoqXG4gKiBSZXNvbHZlcyB0aGUgYG93bmVyL25hbWVgIEdpdEh1YiByZXBvc2l0b3J5IG9mIGEgY29tbXVuaXR5IHBsdWdpbiBmcm9tIE9ic2lkaWFuJ3MgcHVibGljXG4gKiBgY29tbXVuaXR5LXBsdWdpbnMuanNvbmAgcmVnaXN0cnkuXG4gKlxuICogVGhlIHJlZ2lzdHJ5IGlzIGZldGNoZWQgb25jZSBhbmQgY2FjaGVkIG9uIHRoZSBzaGFyZWQgcGx1Z2luIHN0YXRlIGZvciBzdWJzZXF1ZW50IGNhbGxzOyBhIGZhaWxlZFxuICogZmV0Y2ggaXMgbm90IGNhY2hlZCwgc28gYSBsYXRlciBjYWxsIHJldHJpZXMuXG4gKlxuICogQHBhcmFtIHBsdWdpbklkIC0gVGhlIHBsdWdpbiBpZCB0byBsb29rIHVwLlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gcmVzb2x2aW5nIHRvIHRoZSBwbHVnaW4ncyBgb3duZXIvbmFtZWAgcmVwb3NpdG9yeSwgb3IgYG51bGxgIGlmIHRoZVxuICogcGx1Z2luIGlzIG5vdCBsaXN0ZWQgaW4gdGhlIHJlZ2lzdHJ5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0Q29tbXVuaXR5UGx1Z2luUmVwbyhwbHVnaW5JZDogc3RyaW5nKTogUHJvbWlzZTxudWxsIHwgc3RyaW5nPiB7XG4gIGNvbnN0IGNhY2hlID0gZ2V0T2JzaWRpYW5EZXZVdGlsc1N0YXRlPG51bGwgfCBQcm9taXNlPENvbW11bml0eVBsdWdpbkVudHJ5W10+PihDT01NVU5JVFlfUExVR0lOU19TVEFURV9LRVksIG51bGwpO1xuICBjYWNoZS52YWx1ZSA/Pz0gZmV0Y2hDb21tdW5pdHlQbHVnaW5FbnRyaWVzKCk7XG5cbiAgbGV0IGVudHJpZXM6IENvbW11bml0eVBsdWdpbkVudHJ5W107XG4gIHRyeSB7XG4gICAgZW50cmllcyA9IGF3YWl0IGNhY2hlLnZhbHVlO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNhY2hlLnZhbHVlID0gbnVsbDtcbiAgICB0aHJvdyBlcnJvcjtcbiAgfVxuXG4gIGNvbnN0IGVudHJ5ID0gZW50cmllcy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5pZCA9PT0gcGx1Z2luSWQpO1xuICByZXR1cm4gZW50cnk/LnJlcG8gPz8gbnVsbDtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmV0Y2hDb21tdW5pdHlQbHVnaW5FbnRyaWVzKCk6IFByb21pc2U8Q29tbXVuaXR5UGx1Z2luRW50cnlbXT4ge1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHJlcXVlc3RVcmwoQ09NTVVOSVRZX1BMVUdJTlNfVVJMKTtcbiAgcmV0dXJuIHJlc3BvbnNlLmpzb24gYXMgQ29tbXVuaXR5UGx1Z2luRW50cnlbXTtcbn1cbiJdLAogICJtYXBwaW5ncyI6ICI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBVUEsU0FBUyxrQkFBa0I7QUFFM0IsU0FBUyxnQ0FBZ0M7QUFnQ3pDLE1BQU0sOEJBQThCO0FBQ3BDLE1BQU0sd0JBQXdCO0FBYTlCLGVBQXNCLHVCQUF1QixVQUEwQztBQUNyRixRQUFNLFFBQVEseUJBQWlFLDZCQUE2QixJQUFJO0FBQ2hILFFBQU0sVUFBVSw0QkFBNEI7QUFFNUMsTUFBSTtBQUNKLE1BQUk7QUFDRixjQUFVLE1BQU0sTUFBTTtBQUFBLEVBQ3hCLFNBQVMsT0FBTztBQUNkLFVBQU0sUUFBUTtBQUNkLFVBQU07QUFBQSxFQUNSO0FBRUEsUUFBTSxRQUFRLFFBQVEsS0FBSyxDQUFDLGNBQWMsVUFBVSxPQUFPLFFBQVE7QUFDbkUsU0FBTyxPQUFPLFFBQVE7QUFDeEI7QUFFQSxlQUFlLDhCQUErRDtBQUM1RSxRQUFNLFdBQVcsTUFBTSxXQUFXLHFCQUFxQjtBQUN2RCxTQUFPLFNBQVM7QUFDbEI7IiwKICAibmFtZXMiOiBbXQp9Cg==
140
+ //# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsiLi4vLi4vLi4vLi4vc3JjL29ic2lkaWFuL2NvbW11bml0eS1wbHVnaW5zLnRzIl0sCiAgInNvdXJjZXNDb250ZW50IjogWyIvKipcbiAqIEBmaWxlXG4gKlxuICogUmVzb2x2ZXMsIHNlYXJjaGVzIGFuZCBtYW5hZ2VzIGNvbW11bml0eSBwbHVnaW5zIHRocm91Z2ggT2JzaWRpYW4ncyBwdWJsaWMgcGx1Z2luIHJlZ2lzdHJ5IGFuZFxuICogc3RvcmUtaW5zdGFsbCBwYXRoLlxuICpcbiAqIE9ic2lkaWFuJ3MgYGNvbW11bml0eS1wbHVnaW5zLmpzb25gIGlzIHRoZSBhdXRob3JpdGF0aXZlIHNvdXJjZSB0aGF0IG1hcHMgYSBwbHVnaW4gYGlkYCB0byBpdHNcbiAqIGBvd25lci9uYW1lYCBHaXRIdWIgcmVwb3NpdG9yeSBcdTIwMTQgdGhlIHBsdWdpbiBtYW5pZmVzdCBpdHNlbGYgY2FycmllcyBubyByZXBvc2l0b3J5LiBUaGlzIG1vZHVsZSB1c2VzXG4gKiBpdCB0byBzZWFyY2ggdGhlIHJlZ2lzdHJ5LCB0byBsb2NhdGUgYSBwbHVnaW4ncyBHaXRIdWIgcmVsZWFzZXMgKGUuZy4gdG8gZG93bmxvYWQgaXRzIHNoaXBwZWRcbiAqIGRlbW8tdmF1bHQgYXJjaGl2ZSksIGFuZCB0byBpbnN0YWxsL3VuaW5zdGFsbC9lbmFibGUvZGlzYWJsZSBhbiBhcmJpdHJhcnkgY29tbXVuaXR5IHBsdWdpbiBcdTIwMTQgc2VsZWN0ZWRcbiAqIGJ5IGVpdGhlciBpdHMgYGlkYCBvciBpdHMgZGlzcGxheSBgbmFtZWAgXHUyMDE0IHZpYSBPYnNpZGlhbidzIG93biBzdG9yZSBwYXRoIChgYXBwLnBsdWdpbnMuaW5zdGFsbFBsdWdpbmBcbiAqICsgYGVuYWJsZVBsdWdpbkFuZFNhdmVgKSwgc28gYW55IGRldi9kZXBsb3kgb3IgdG9vbGluZyBmbG93IGNhbiByZXVzZSBpdC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7XG4gIEFwcCxcbiAgUGx1Z2luTWFuaWZlc3Rcbn0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQgeyByZXF1ZXN0VXJsIH0gZnJvbSAnb2JzaWRpYW4nO1xuXG5pbXBvcnQgeyBnZXRPYnNpZGlhbkRldlV0aWxzU3RhdGUgfSBmcm9tICcuLi9vYnNpZGlhbi1kZXYtdXRpbHMtc3RhdGUudHMnO1xuXG4vKipcbiAqIFNlbGVjdHMgYSBjb21tdW5pdHkgcGx1Z2luIGVpdGhlciBieSBpdHMgaWQgKHtAbGluayBDb21tdW5pdHlQbHVnaW5CeUlkUmVmfSkgb3IgYnkgaXRzIGRpc3BsYXkgbmFtZVxuICogKHtAbGluayBDb21tdW5pdHlQbHVnaW5CeU5hbWVSZWZ9KS5cbiAqL1xuZXhwb3J0IHR5cGUgQ29tbXVuaXR5UGx1Z2luUmVmID0gQ29tbXVuaXR5UGx1Z2luQnlJZFJlZiB8IENvbW11bml0eVBsdWdpbkJ5TmFtZVJlZjtcblxuLyoqXG4gKiBBIHNpbmdsZSByZXN1bHQgb2Yge0BsaW5rIHNlYXJjaENvbW11bml0eVBsdWdpbnN9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbW11bml0eVBsdWdpblNlYXJjaFJlc3VsdCB7XG4gIC8qKlxuICAgKiBUaGUgcGx1Z2luIGlkLlxuICAgKi9cbiAgcmVhZG9ubHkgaWQ6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHBsdWdpbiBkaXNwbGF5IG5hbWUuXG4gICAqL1xuICByZWFkb25seSBuYW1lOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGRpc2FibGVDb21tdW5pdHlQbHVnaW59LiBTZWxlY3RzIHRoZSBwbHVnaW4gYnkgZWl0aGVyIGBwbHVnaW5JZGAgb3JcbiAqIGBwbHVnaW5OYW1lYC5cbiAqL1xuZXhwb3J0IHR5cGUgRGlzYWJsZUNvbW11bml0eVBsdWdpblBhcmFtcyA9IENvbW11bml0eVBsdWdpbk9wZXJhdGlvbkNvbnRleHQgJiBDb21tdW5pdHlQbHVnaW5SZWY7XG5cbi8qKlxuICogUGFyYW1ldGVycyBmb3Ige0BsaW5rIGVuYWJsZUNvbW11bml0eVBsdWdpbn0uIFNlbGVjdHMgdGhlIHBsdWdpbiBieSBlaXRoZXIgYHBsdWdpbklkYCBvclxuICogYHBsdWdpbk5hbWVgLlxuICovXG5leHBvcnQgdHlwZSBFbmFibGVDb21tdW5pdHlQbHVnaW5QYXJhbXMgPSBDb21tdW5pdHlQbHVnaW5PcGVyYXRpb25Db250ZXh0ICYgQ29tbXVuaXR5UGx1Z2luUmVmO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBpbnN0YWxsQ29tbXVuaXR5UGx1Z2lufS4gU2VsZWN0cyB0aGUgcGx1Z2luIGJ5IGVpdGhlciBgcGx1Z2luSWRgIG9yXG4gKiBgcGx1Z2luTmFtZWAuXG4gKi9cbmV4cG9ydCB0eXBlIEluc3RhbGxDb21tdW5pdHlQbHVnaW5QYXJhbXMgPSBDb21tdW5pdHlQbHVnaW5PcGVyYXRpb25Db250ZXh0ICYgQ29tbXVuaXR5UGx1Z2luUmVmO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayB0b2dnbGVFbmFibGVDb21tdW5pdHlQbHVnaW59LiBTZWxlY3RzIHRoZSBwbHVnaW4gYnkgZWl0aGVyIGBwbHVnaW5JZGAgb3JcbiAqIGBwbHVnaW5OYW1lYC5cbiAqL1xuZXhwb3J0IHR5cGUgVG9nZ2xlRW5hYmxlQ29tbXVuaXR5UGx1Z2luUGFyYW1zID0gQ29tbXVuaXR5UGx1Z2luT3BlcmF0aW9uQ29udGV4dCAmIENvbW11bml0eVBsdWdpblJlZiAmIENvbW11bml0eVBsdWdpblRvZ2dsZUVuYWJsZVN0YXRlO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayB0b2dnbGVJbnN0YWxsQ29tbXVuaXR5UGx1Z2lufS4gU2VsZWN0cyB0aGUgcGx1Z2luIGJ5IGVpdGhlciBgcGx1Z2luSWRgIG9yXG4gKiBgcGx1Z2luTmFtZWAuXG4gKi9cbmV4cG9ydCB0eXBlIFRvZ2dsZUluc3RhbGxDb21tdW5pdHlQbHVnaW5QYXJhbXMgPSBDb21tdW5pdHlQbHVnaW5PcGVyYXRpb25Db250ZXh0ICYgQ29tbXVuaXR5UGx1Z2luUmVmICYgQ29tbXVuaXR5UGx1Z2luVG9nZ2xlSW5zdGFsbFN0YXRlO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayB1bmluc3RhbGxDb21tdW5pdHlQbHVnaW59LiBTZWxlY3RzIHRoZSBwbHVnaW4gYnkgZWl0aGVyIGBwbHVnaW5JZGAgb3JcbiAqIGBwbHVnaW5OYW1lYC5cbiAqL1xuZXhwb3J0IHR5cGUgVW5pbnN0YWxsQ29tbXVuaXR5UGx1Z2luUGFyYW1zID0gQ29tbXVuaXR5UGx1Z2luT3BlcmF0aW9uQ29udGV4dCAmIENvbW11bml0eVBsdWdpblJlZjtcblxuLyoqXG4gKiBTZWxlY3RzIGEgY29tbXVuaXR5IHBsdWdpbiBieSBpdHMgaWQuXG4gKi9cbmludGVyZmFjZSBDb21tdW5pdHlQbHVnaW5CeUlkUmVmIHtcbiAgLyoqXG4gICAqIFRoZSBwbHVnaW4gaWQuXG4gICAqL1xuICByZWFkb25seSBwbHVnaW5JZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIFNlbGVjdHMgYSBjb21tdW5pdHkgcGx1Z2luIGJ5IGl0cyBkaXNwbGF5IG5hbWUgKGFzIGxpc3RlZCBpbiBPYnNpZGlhbidzIGNvbW11bml0eSByZWdpc3RyeSkuXG4gKi9cbmludGVyZmFjZSBDb21tdW5pdHlQbHVnaW5CeU5hbWVSZWYge1xuICAvKipcbiAgICogVGhlIHBsdWdpbiBkaXNwbGF5IG5hbWUuXG4gICAqL1xuICByZWFkb25seSBwbHVnaW5OYW1lOiBzdHJpbmc7XG59XG5cbi8qKlxuICogQSBzaW5nbGUgZW50cnkgaW4gT2JzaWRpYW4ncyBgY29tbXVuaXR5LXBsdWdpbnMuanNvbmAgcmVnaXN0cnkuXG4gKi9cbmludGVyZmFjZSBDb21tdW5pdHlQbHVnaW5FbnRyeSB7XG4gIC8qKlxuICAgKiBUaGUgcGx1Z2luIGF1dGhvci5cbiAgICovXG4gIHJlYWRvbmx5IGF1dGhvcjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcGx1Z2luIGRlc2NyaXB0aW9uLlxuICAgKi9cbiAgcmVhZG9ubHkgZGVzY3JpcHRpb246IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHBsdWdpbiBpZC5cbiAgICovXG4gIHJlYWRvbmx5IGlkOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwbHVnaW4gZGlzcGxheSBuYW1lLlxuICAgKi9cbiAgcmVhZG9ubHkgbmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcGx1Z2luJ3MgYG93bmVyL25hbWVgIEdpdEh1YiByZXBvc2l0b3J5LlxuICAgKi9cbiAgcmVhZG9ubHkgcmVwbzogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRoZSBPYnNpZGlhbiBhcHAgaW5zdGFuY2UgYSBjb21tdW5pdHktcGx1Z2luIG9wZXJhdGlvbiBydW5zIGFnYWluc3QuXG4gKi9cbmludGVyZmFjZSBDb21tdW5pdHlQbHVnaW5PcGVyYXRpb25Db250ZXh0IHtcbiAgLyoqXG4gICAqIFRoZSBPYnNpZGlhbiBhcHAgaW5zdGFuY2UuXG4gICAqL1xuICByZWFkb25seSBhcHA6IEFwcDtcbn1cblxuLyoqXG4gKiBUaGUgZGVzaXJlZCBlbmFibGVkIHN0YXRlIGZvciB7QGxpbmsgdG9nZ2xlRW5hYmxlQ29tbXVuaXR5UGx1Z2lufS5cbiAqL1xuaW50ZXJmYWNlIENvbW11bml0eVBsdWdpblRvZ2dsZUVuYWJsZVN0YXRlIHtcbiAgLyoqXG4gICAqIFRoZSBkZXNpcmVkIGVuYWJsZWQgc3RhdGU6IGB0cnVlYCBlbmFibGVzIHRoZSBwbHVnaW4sIGBmYWxzZWAgZGlzYWJsZXMgaXQuXG4gICAqL1xuICByZWFkb25seSBpc0VuYWJsZWQ6IGJvb2xlYW47XG59XG5cbi8qKlxuICogVGhlIGRlc2lyZWQgaW5zdGFsbGVkIHN0YXRlIGZvciB7QGxpbmsgdG9nZ2xlSW5zdGFsbENvbW11bml0eVBsdWdpbn0uXG4gKi9cbmludGVyZmFjZSBDb21tdW5pdHlQbHVnaW5Ub2dnbGVJbnN0YWxsU3RhdGUge1xuICAvKipcbiAgICogVGhlIGRlc2lyZWQgaW5zdGFsbGVkIHN0YXRlOiBgdHJ1ZWAgaW5zdGFsbHMgdGhlIHBsdWdpbiwgYGZhbHNlYCB1bmluc3RhbGxzIGl0LlxuICAgKi9cbiAgcmVhZG9ubHkgaXNJbnN0YWxsZWQ6IGJvb2xlYW47XG59XG5cbi8qKlxuICogVGhlIHN1YnNldCBvZiBhIEdpdEh1YiByZWxlYXNlIHdlIHJlYWQuXG4gKi9cbmludGVyZmFjZSBHaXRIdWJSZWxlYXNlIHtcbiAgLyoqXG4gICAqIFRoZSByZWxlYXNlIHRhZywgYSBiYXJlIHZlcnNpb24gc3VjaCBhcyBgMS4yLjNgLlxuICAgKi9cbiAgcmVhZG9ubHkgdGFnX25hbWU6IHN0cmluZztcbn1cblxuY29uc3QgQ09NTVVOSVRZX1BMVUdJTlNfU1RBVEVfS0VZID0gJ2NvbW11bml0eVBsdWdpbkVudHJpZXNQcm9taXNlJztcbmNvbnN0IENPTU1VTklUWV9QTFVHSU5TX1VSTCA9ICdodHRwczovL3Jhdy5naXRodWJ1c2VyY29udGVudC5jb20vb2JzaWRpYW5tZC9vYnNpZGlhbi1yZWxlYXNlcy9IRUFEL2NvbW11bml0eS1wbHVnaW5zLmpzb24nO1xuXG4vKipcbiAqIERpc2FibGVzIGEgY29tbXVuaXR5IHBsdWdpbiAocGVyc2lzdGluZyB0aGUgY2hhbmdlKSBpZiBpdCBpcyBjdXJyZW50bHkgZW5hYmxlZC4gSWRlbXBvdGVudCBcdTIwMTQgYSBuby1vcFxuICogd2hlbiB0aGUgcGx1Z2luIGlzIGFscmVhZHkgZGlzYWJsZWQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSB7QGxpbmsgRGlzYWJsZUNvbW11bml0eVBsdWdpblBhcmFtc30uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIHBsdWdpbiBpcyBkaXNhYmxlZC5cbiAqIEB0aHJvd3MgSWYgc2VsZWN0ZWQgYnkgYHBsdWdpbk5hbWVgIGFuZCB0aGUgbmFtZSBpcyBub3QgbGlzdGVkIGluIE9ic2lkaWFuJ3MgY29tbXVuaXR5IHBsdWdpbnMgcmVnaXN0cnkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkaXNhYmxlQ29tbXVuaXR5UGx1Z2luKHBhcmFtczogRGlzYWJsZUNvbW11bml0eVBsdWdpblBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IGFwcCB9ID0gcGFyYW1zO1xuICBjb25zdCBwbHVnaW5JZCA9IGF3YWl0IHJlc29sdmVDb21tdW5pdHlQbHVnaW5JZChwYXJhbXMpO1xuICBpZiAoIWFwcC5wbHVnaW5zLmVuYWJsZWRQbHVnaW5zLmhhcyhwbHVnaW5JZCkpIHtcbiAgICByZXR1cm47XG4gIH1cbiAgYXdhaXQgYXBwLnBsdWdpbnMuZGlzYWJsZVBsdWdpbkFuZFNhdmUocGx1Z2luSWQpO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgYSBjb21tdW5pdHkgcGx1Z2luIChwZXJzaXN0aW5nIHRoZSBjaGFuZ2UpIGlmIGl0IGlzIG5vdCBhbHJlYWR5IGVuYWJsZWQuIElkZW1wb3RlbnQgXHUyMDE0IGEgbm8tb3BcbiAqIHdoZW4gdGhlIHBsdWdpbiBpcyBhbHJlYWR5IGVuYWJsZWQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSB7QGxpbmsgRW5hYmxlQ29tbXVuaXR5UGx1Z2luUGFyYW1zfS5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgcGx1Z2luIGlzIGVuYWJsZWQuXG4gKiBAdGhyb3dzIElmIHNlbGVjdGVkIGJ5IGBwbHVnaW5OYW1lYCBhbmQgdGhlIG5hbWUgaXMgbm90IGxpc3RlZCBpbiBPYnNpZGlhbidzIGNvbW11bml0eSBwbHVnaW5zIHJlZ2lzdHJ5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW5hYmxlQ29tbXVuaXR5UGx1Z2luKHBhcmFtczogRW5hYmxlQ29tbXVuaXR5UGx1Z2luUGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IHsgYXBwIH0gPSBwYXJhbXM7XG4gIGNvbnN0IHBsdWdpbklkID0gYXdhaXQgcmVzb2x2ZUNvbW11bml0eVBsdWdpbklkKHBhcmFtcyk7XG4gIGlmIChhcHAucGx1Z2lucy5lbmFibGVkUGx1Z2lucy5oYXMocGx1Z2luSWQpKSB7XG4gICAgcmV0dXJuO1xuICB9XG4gIGF3YWl0IGFwcC5wbHVnaW5zLmVuYWJsZVBsdWdpbkFuZFNhdmUocGx1Z2luSWQpO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBgb3duZXIvbmFtZWAgR2l0SHViIHJlcG9zaXRvcnkgb2YgYSBjb21tdW5pdHkgcGx1Z2luIGZyb20gT2JzaWRpYW4ncyBwdWJsaWNcbiAqIGBjb21tdW5pdHktcGx1Z2lucy5qc29uYCByZWdpc3RyeS5cbiAqXG4gKiBUaGUgcmVnaXN0cnkgaXMgZmV0Y2hlZCBvbmNlIGFuZCBjYWNoZWQgb24gdGhlIHNoYXJlZCBwbHVnaW4gc3RhdGUgZm9yIHN1YnNlcXVlbnQgY2FsbHM7IGEgZmFpbGVkXG4gKiBmZXRjaCBpcyBub3QgY2FjaGVkLCBzbyBhIGxhdGVyIGNhbGwgcmV0cmllcy5cbiAqXG4gKiBAcGFyYW0gcGx1Z2luSWQgLSBUaGUgcGx1Z2luIGlkIHRvIGxvb2sgdXAuXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSByZXNvbHZpbmcgdG8gdGhlIHBsdWdpbidzIGBvd25lci9uYW1lYCByZXBvc2l0b3J5LCBvciBgbnVsbGAgaWYgdGhlXG4gKiBwbHVnaW4gaXMgbm90IGxpc3RlZCBpbiB0aGUgcmVnaXN0cnkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRDb21tdW5pdHlQbHVnaW5SZXBvKHBsdWdpbklkOiBzdHJpbmcpOiBQcm9taXNlPG51bGwgfCBzdHJpbmc+IHtcbiAgY29uc3QgZW50cmllcyA9IGF3YWl0IGdldENvbW11bml0eVBsdWdpbkVudHJpZXMoKTtcbiAgY29uc3QgZW50cnkgPSBlbnRyaWVzLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLmlkID09PSBwbHVnaW5JZCk7XG4gIHJldHVybiBlbnRyeT8ucmVwbyA/PyBudWxsO1xufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBsYXRlc3QgcmVsZWFzZSB2ZXJzaW9uICh0aGUgcmVsZWFzZSBgdGFnX25hbWVgLCBhIGJhcmUgdmVyc2lvbiBzdWNoIGFzIGAxLjIuM2ApIG9mIGFcbiAqIEdpdEh1YiByZXBvc2l0b3J5LlxuICpcbiAqIEBwYXJhbSByZXBvIC0gVGhlIGBvd25lci9uYW1lYCBHaXRIdWIgcmVwb3NpdG9yeS5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHJlc29sdmluZyB0byB0aGUgbGF0ZXN0IHJlbGVhc2UgdmVyc2lvbi5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGdldExhdGVzdFJlbGVhc2VWZXJzaW9uKHJlcG86IHN0cmluZyk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFVybChgaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXBvcy8ke3JlcG99L3JlbGVhc2VzL2xhdGVzdGApO1xuICBjb25zdCByZWxlYXNlID0gcmVzcG9uc2UuanNvbiBhcyBHaXRIdWJSZWxlYXNlO1xuICByZXR1cm4gcmVsZWFzZS50YWdfbmFtZTtcbn1cblxuLyoqXG4gKiBJbnN0YWxscyBhIGNvbW11bml0eSBwbHVnaW4gZnJvbSB0aGUgb2ZmaWNpYWwgc3RvcmUgaWYgaXQgaXMgbm90IGFscmVhZHkgaW5zdGFsbGVkLiBJZGVtcG90ZW50IFx1MjAxNCBhXG4gKiBuby1vcCB3aGVuIHRoZSBwbHVnaW4gaXMgYWxyZWFkeSBpbnN0YWxsZWQuIFJlc29sdmVzIHRoZSBwbHVnaW4ncyByZXBvc2l0b3J5IGZyb20gT2JzaWRpYW4nc1xuICogY29tbXVuaXR5IHJlZ2lzdHJ5LCByZWFkcyB0aGUgbGF0ZXN0IHJlbGVhc2UgdmVyc2lvbiBhbmQgaXRzIG1hbmlmZXN0LCBhbmQgaW5zdGFsbHMgaXQgdGhyb3VnaFxuICogT2JzaWRpYW4ncyBvd24gYGluc3RhbGxQbHVnaW5gIHBhdGguXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSB7QGxpbmsgSW5zdGFsbENvbW11bml0eVBsdWdpblBhcmFtc30uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIHBsdWdpbiBpcyBpbnN0YWxsZWQuXG4gKiBAdGhyb3dzIElmIHRoZSBwbHVnaW4gaXMgbm90IGxpc3RlZCBpbiBPYnNpZGlhbidzIGNvbW11bml0eSBwbHVnaW5zIHJlZ2lzdHJ5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW5zdGFsbENvbW11bml0eVBsdWdpbihwYXJhbXM6IEluc3RhbGxDb21tdW5pdHlQbHVnaW5QYXJhbXMpOiBQcm9taXNlPHZvaWQ+IHtcbiAgY29uc3QgeyBhcHAgfSA9IHBhcmFtcztcbiAgY29uc3QgcGx1Z2luSWQgPSBhd2FpdCByZXNvbHZlQ29tbXVuaXR5UGx1Z2luSWQocGFyYW1zKTtcbiAgaWYgKGFwcC5wbHVnaW5zLm1hbmlmZXN0c1twbHVnaW5JZF0pIHtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCByZXBvID0gYXdhaXQgZ2V0Q29tbXVuaXR5UGx1Z2luUmVwbyhwbHVnaW5JZCk7XG4gIGlmICghcmVwbykge1xuICAgIHRocm93IG5ldyBFcnJvcihgUGx1Z2luICcke3BsdWdpbklkfScgd2FzIG5vdCBmb3VuZCBpbiB0aGUgT2JzaWRpYW4gY29tbXVuaXR5IHBsdWdpbnMgcmVnaXN0cnkuYCk7XG4gIH1cblxuICBjb25zdCB2ZXJzaW9uID0gYXdhaXQgZ2V0TGF0ZXN0UmVsZWFzZVZlcnNpb24ocmVwbyk7XG4gIGNvbnN0IG1hbmlmZXN0ID0gYXdhaXQgZ2V0UGx1Z2luTWFuaWZlc3QocmVwbywgdmVyc2lvbik7XG4gIGF3YWl0IGFwcC5wbHVnaW5zLmluc3RhbGxQbHVnaW4ocmVwbywgdmVyc2lvbiwgbWFuaWZlc3QpO1xufVxuXG4vKipcbiAqIFNlYXJjaGVzIE9ic2lkaWFuJ3MgcHVibGljIGNvbW11bml0eSBwbHVnaW5zIHJlZ2lzdHJ5LCByZXR1cm5pbmcgdGhlIGlkIGFuZCBkaXNwbGF5IG5hbWUgb2YgZXZlcnlcbiAqIHBsdWdpbiB3aG9zZSBpZCwgbmFtZSwgYXV0aG9yIG9yIGRlc2NyaXB0aW9uIGNvbnRhaW5zIHRoZSBxdWVyeSAoY2FzZS1pbnNlbnNpdGl2ZSkuIEFuIGVtcHR5IHF1ZXJ5XG4gKiBtYXRjaGVzIGV2ZXJ5IHBsdWdpbi5cbiAqXG4gKiBAcGFyYW0gcXVlcnkgLSBUaGUgc2VhcmNoIHF1ZXJ5LlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gcmVzb2x2aW5nIHRvIHRoZSBtYXRjaGluZyBwbHVnaW5zJyB7QGxpbmsgQ29tbXVuaXR5UGx1Z2luU2VhcmNoUmVzdWx0fXMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZWFyY2hDb21tdW5pdHlQbHVnaW5zKHF1ZXJ5OiBzdHJpbmcpOiBQcm9taXNlPENvbW11bml0eVBsdWdpblNlYXJjaFJlc3VsdFtdPiB7XG4gIGNvbnN0IGVudHJpZXMgPSBhd2FpdCBnZXRDb21tdW5pdHlQbHVnaW5FbnRyaWVzKCk7XG4gIGNvbnN0IG5vcm1hbGl6ZWRRdWVyeSA9IHF1ZXJ5LnRvTG93ZXJDYXNlKCk7XG4gIHJldHVybiBlbnRyaWVzXG4gICAgLmZpbHRlcigoZW50cnkpID0+XG4gICAgICBlbnRyeS5pZC50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKG5vcm1hbGl6ZWRRdWVyeSlcbiAgICAgIHx8IGVudHJ5Lm5hbWUudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhub3JtYWxpemVkUXVlcnkpXG4gICAgICB8fCBlbnRyeS5hdXRob3IudG9Mb3dlckNhc2UoKS5pbmNsdWRlcyhub3JtYWxpemVkUXVlcnkpXG4gICAgICB8fCBlbnRyeS5kZXNjcmlwdGlvbi50b0xvd2VyQ2FzZSgpLmluY2x1ZGVzKG5vcm1hbGl6ZWRRdWVyeSlcbiAgICApXG4gICAgLm1hcCgoZW50cnkpID0+ICh7XG4gICAgICBpZDogZW50cnkuaWQsXG4gICAgICBuYW1lOiBlbnRyeS5uYW1lXG4gICAgfSkpO1xufVxuXG4vKipcbiAqIEVuYWJsZXMgb3IgZGlzYWJsZXMgYSBjb21tdW5pdHkgcGx1Z2luIHRvIG1hdGNoIHRoZSBkZXNpcmVkIHN0YXRlLiBEZWxlZ2F0ZXMgdG9cbiAqIHtAbGluayBlbmFibGVDb21tdW5pdHlQbHVnaW59IC8ge0BsaW5rIGRpc2FibGVDb21tdW5pdHlQbHVnaW59LCBzbyBpdCBpcyBpZGVtcG90ZW50LlxuICpcbiAqIEBwYXJhbSBwYXJhbXMgLSBUaGUge0BsaW5rIFRvZ2dsZUVuYWJsZUNvbW11bml0eVBsdWdpblBhcmFtc30uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIHBsdWdpbiBtYXRjaGVzIHRoZSBkZXNpcmVkIGVuYWJsZWQgc3RhdGUuXG4gKiBAdGhyb3dzIElmIHNlbGVjdGVkIGJ5IGBwbHVnaW5OYW1lYCBhbmQgdGhlIG5hbWUgaXMgbm90IGxpc3RlZCBpbiBPYnNpZGlhbidzIGNvbW11bml0eSBwbHVnaW5zIHJlZ2lzdHJ5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdG9nZ2xlRW5hYmxlQ29tbXVuaXR5UGx1Z2luKHBhcmFtczogVG9nZ2xlRW5hYmxlQ29tbXVuaXR5UGx1Z2luUGFyYW1zKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChwYXJhbXMuaXNFbmFibGVkKSB7XG4gICAgYXdhaXQgZW5hYmxlQ29tbXVuaXR5UGx1Z2luKHBhcmFtcyk7XG4gIH0gZWxzZSB7XG4gICAgYXdhaXQgZGlzYWJsZUNvbW11bml0eVBsdWdpbihwYXJhbXMpO1xuICB9XG59XG5cbi8qKlxuICogSW5zdGFsbHMgb3IgdW5pbnN0YWxscyBhIGNvbW11bml0eSBwbHVnaW4gdG8gbWF0Y2ggdGhlIGRlc2lyZWQgc3RhdGUuIERlbGVnYXRlcyB0b1xuICoge0BsaW5rIGluc3RhbGxDb21tdW5pdHlQbHVnaW59IC8ge0BsaW5rIHVuaW5zdGFsbENvbW11bml0eVBsdWdpbn0sIHNvIGl0IGlzIGlkZW1wb3RlbnQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSB7QGxpbmsgVG9nZ2xlSW5zdGFsbENvbW11bml0eVBsdWdpblBhcmFtc30uXG4gKiBAcmV0dXJucyBBIHtAbGluayBQcm9taXNlfSB0aGF0IHJlc29sdmVzIG9uY2UgdGhlIHBsdWdpbiBtYXRjaGVzIHRoZSBkZXNpcmVkIGluc3RhbGxlZCBzdGF0ZS5cbiAqIEB0aHJvd3MgSWYgaW5zdGFsbGluZyBhbmQgdGhlIHBsdWdpbiBpcyBub3QgbGlzdGVkIGluIE9ic2lkaWFuJ3MgY29tbXVuaXR5IHBsdWdpbnMgcmVnaXN0cnkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB0b2dnbGVJbnN0YWxsQ29tbXVuaXR5UGx1Z2luKHBhcmFtczogVG9nZ2xlSW5zdGFsbENvbW11bml0eVBsdWdpblBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAocGFyYW1zLmlzSW5zdGFsbGVkKSB7XG4gICAgYXdhaXQgaW5zdGFsbENvbW11bml0eVBsdWdpbihwYXJhbXMpO1xuICB9IGVsc2Uge1xuICAgIGF3YWl0IHVuaW5zdGFsbENvbW11bml0eVBsdWdpbihwYXJhbXMpO1xuICB9XG59XG5cbi8qKlxuICogVW5pbnN0YWxscyBhIGNvbW11bml0eSBwbHVnaW4gaWYgaXQgaXMgY3VycmVudGx5IGluc3RhbGxlZC4gSWRlbXBvdGVudCBcdTIwMTQgYSBuby1vcCB3aGVuIHRoZSBwbHVnaW4gaXNcbiAqIG5vdCBpbnN0YWxsZWQuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSB7QGxpbmsgVW5pbnN0YWxsQ29tbXVuaXR5UGx1Z2luUGFyYW1zfS5cbiAqIEByZXR1cm5zIEEge0BsaW5rIFByb21pc2V9IHRoYXQgcmVzb2x2ZXMgb25jZSB0aGUgcGx1Z2luIGlzIHVuaW5zdGFsbGVkLlxuICogQHRocm93cyBJZiBzZWxlY3RlZCBieSBgcGx1Z2luTmFtZWAgYW5kIHRoZSBuYW1lIGlzIG5vdCBsaXN0ZWQgaW4gT2JzaWRpYW4ncyBjb21tdW5pdHkgcGx1Z2lucyByZWdpc3RyeS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVuaW5zdGFsbENvbW11bml0eVBsdWdpbihwYXJhbXM6IFVuaW5zdGFsbENvbW11bml0eVBsdWdpblBhcmFtcyk6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCB7IGFwcCB9ID0gcGFyYW1zO1xuICBjb25zdCBwbHVnaW5JZCA9IGF3YWl0IHJlc29sdmVDb21tdW5pdHlQbHVnaW5JZChwYXJhbXMpO1xuICBpZiAoIWFwcC5wbHVnaW5zLm1hbmlmZXN0c1twbHVnaW5JZF0pIHtcbiAgICByZXR1cm47XG4gIH1cbiAgYXdhaXQgYXBwLnBsdWdpbnMudW5pbnN0YWxsUGx1Z2luKHBsdWdpbklkKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZmV0Y2hDb21tdW5pdHlQbHVnaW5FbnRyaWVzKCk6IFByb21pc2U8Q29tbXVuaXR5UGx1Z2luRW50cnlbXT4ge1xuICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHJlcXVlc3RVcmwoQ09NTVVOSVRZX1BMVUdJTlNfVVJMKTtcbiAgcmV0dXJuIHJlc3BvbnNlLmpzb24gYXMgQ29tbXVuaXR5UGx1Z2luRW50cnlbXTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0Q29tbXVuaXR5UGx1Z2luRW50cmllcygpOiBQcm9taXNlPENvbW11bml0eVBsdWdpbkVudHJ5W10+IHtcbiAgY29uc3QgY2FjaGUgPSBnZXRPYnNpZGlhbkRldlV0aWxzU3RhdGU8bnVsbCB8IFByb21pc2U8Q29tbXVuaXR5UGx1Z2luRW50cnlbXT4+KENPTU1VTklUWV9QTFVHSU5TX1NUQVRFX0tFWSwgbnVsbCk7XG4gIGNhY2hlLnZhbHVlID8/PSBmZXRjaENvbW11bml0eVBsdWdpbkVudHJpZXMoKTtcblxuICB0cnkge1xuICAgIHJldHVybiBhd2FpdCBjYWNoZS52YWx1ZTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICBjYWNoZS52YWx1ZSA9IG51bGw7XG4gICAgdGhyb3cgZXJyb3I7XG4gIH1cbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0UGx1Z2luTWFuaWZlc3QocmVwbzogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcpOiBQcm9taXNlPFBsdWdpbk1hbmlmZXN0PiB7XG4gIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgcmVxdWVzdFVybChgaHR0cHM6Ly9naXRodWIuY29tLyR7cmVwb30vcmVsZWFzZXMvZG93bmxvYWQvJHt2ZXJzaW9ufS9tYW5pZmVzdC5qc29uYCk7XG4gIHJldHVybiByZXNwb25zZS5qc29uIGFzIFBsdWdpbk1hbmlmZXN0O1xufVxuXG5hc3luYyBmdW5jdGlvbiByZXNvbHZlQ29tbXVuaXR5UGx1Z2luSWQocmVmOiBDb21tdW5pdHlQbHVnaW5SZWYpOiBQcm9taXNlPHN0cmluZz4ge1xuICBpZiAoJ3BsdWdpbklkJyBpbiByZWYpIHtcbiAgICByZXR1cm4gcmVmLnBsdWdpbklkO1xuICB9XG5cbiAgY29uc3QgZW50cmllcyA9IGF3YWl0IGdldENvbW11bml0eVBsdWdpbkVudHJpZXMoKTtcbiAgY29uc3QgZW50cnkgPSBlbnRyaWVzLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLm5hbWUgPT09IHJlZi5wbHVnaW5OYW1lKTtcbiAgaWYgKCFlbnRyeSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgUGx1Z2luIG5hbWVkICcke3JlZi5wbHVnaW5OYW1lfScgd2FzIG5vdCBmb3VuZCBpbiB0aGUgT2JzaWRpYW4gY29tbXVuaXR5IHBsdWdpbnMgcmVnaXN0cnkuYCk7XG4gIH1cbiAgcmV0dXJuIGVudHJ5LmlkO1xufVxuIl0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFtQkEsU0FBUyxrQkFBa0I7QUFFM0IsU0FBUyxnQ0FBZ0M7QUFxSnpDLE1BQU0sOEJBQThCO0FBQ3BDLE1BQU0sd0JBQXdCO0FBVTlCLGVBQXNCLHVCQUF1QixRQUFxRDtBQUNoRyxRQUFNLEVBQUUsSUFBSSxJQUFJO0FBQ2hCLFFBQU0sV0FBVyxNQUFNLHlCQUF5QixNQUFNO0FBQ3RELE1BQUksQ0FBQyxJQUFJLFFBQVEsZUFBZSxJQUFJLFFBQVEsR0FBRztBQUM3QztBQUFBLEVBQ0Y7QUFDQSxRQUFNLElBQUksUUFBUSxxQkFBcUIsUUFBUTtBQUNqRDtBQVVBLGVB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
@@ -48,6 +48,18 @@ export declare class ComponentEx extends Component implements Disposable {
48
48
  * @returns A {@link Promise} that resolves when the component is loaded.
49
49
  */
50
50
  onloadAsync(): Promise<void>;
51
+ /**
52
+ * Registers a {@link Disposable} so it is disposed when this component unloads, and returns it unchanged.
53
+ *
54
+ * The recurring "tie a disposable to the component's lifecycle, then keep using it" idiom: the disposable is
55
+ * disposed on {@link Component.unload} (or earlier, if the caller disposes it directly — dispose is expected to
56
+ * be idempotent). Guard with {@link ensureLoaded} at the call site when registering before load would be unsafe.
57
+ *
58
+ * @typeParam TDisposable - The type of the disposable.
59
+ * @param disposable - The disposable to register.
60
+ * @returns The same disposable, for chaining.
61
+ */
62
+ registerDisposable<TDisposable extends Disposable>(disposable: TDisposable): TDisposable;
51
63
  /**
52
64
  * Removes a child component.
53
65
  *