descope 1.0.4 → 1.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yaml +15 -27
  3. data/.github/workflows/publish-gem.yaml +36 -0
  4. data/Gemfile +12 -14
  5. data/Gemfile.lock +40 -87
  6. data/README.md +39 -17
  7. data/examples/ruby/access_key_app.rb +4 -2
  8. data/examples/ruby/management/Gemfile.lock +2 -2
  9. data/examples/ruby/management/role_app.rb +8 -3
  10. data/examples/ruby-on-rails-api/descope/.gitignore +58 -28
  11. data/examples/ruby-on-rails-api/descope/Gemfile.lock +3 -3
  12. data/examples/ruby-on-rails-api/descope/app/assets/builds/App.css +62 -0
  13. data/examples/ruby-on-rails-api/descope/app/assets/builds/App.css.map +7 -0
  14. data/examples/ruby-on-rails-api/descope/app/assets/builds/application.css +62 -0
  15. data/examples/ruby-on-rails-api/descope/app/assets/builds/application.css.map +7 -0
  16. data/examples/ruby-on-rails-api/descope/app/assets/builds/application.js +40369 -0
  17. data/examples/ruby-on-rails-api/descope/app/assets/builds/application.js.map +7 -0
  18. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/App.css +62 -0
  19. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/App.css.map +7 -0
  20. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/App.js +27979 -0
  21. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/App.js.map +7 -0
  22. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Dashboard.css +62 -0
  23. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Dashboard.css.map +7 -0
  24. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Dashboard.js +27118 -0
  25. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Dashboard.js.map +7 -0
  26. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Home.css +62 -0
  27. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Home.css.map +7 -0
  28. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Home.js +27113 -0
  29. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Home.js.map +7 -0
  30. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Login.css +62 -0
  31. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Login.css.map +7 -0
  32. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Login.js +27131 -0
  33. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Login.js.map +7 -0
  34. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Profile.css +62 -0
  35. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Profile.css.map +7 -0
  36. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Profile.js +27168 -0
  37. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/Profile.js.map +7 -0
  38. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/index.css +62 -0
  39. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/index.css.map +7 -0
  40. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/index.js +28250 -0
  41. data/examples/ruby-on-rails-api/descope/app/assets/builds/components/index.js.map +7 -0
  42. data/examples/ruby-on-rails-api/descope/app/assets/builds/controllers/application.js +2456 -0
  43. data/examples/ruby-on-rails-api/descope/app/assets/builds/controllers/application.js.map +7 -0
  44. data/examples/ruby-on-rails-api/descope/app/assets/builds/controllers/index.js +2453 -0
  45. data/examples/ruby-on-rails-api/descope/app/assets/builds/controllers/index.js.map +7 -0
  46. data/examples/ruby-on-rails-api/descope/app/assets/builds/reportWebVitals.js +211 -0
  47. data/examples/ruby-on-rails-api/descope/app/assets/builds/reportWebVitals.js.map +7 -0
  48. data/examples/ruby-on-rails-api/descope/app/assets/builds/routes/index.css +62 -0
  49. data/examples/ruby-on-rails-api/descope/app/assets/builds/routes/index.css.map +7 -0
  50. data/examples/ruby-on-rails-api/descope/app/assets/builds/routes/index.js +27973 -0
  51. data/examples/ruby-on-rails-api/descope/app/assets/builds/routes/index.js.map +7 -0
  52. data/examples/ruby-on-rails-api/descope/package-lock.json +7 -8
  53. data/examples/ruby-on-rails-api/descope/yarn.lock +3 -3
  54. data/lib/descope/api/v1/auth.rb +21 -6
  55. data/lib/descope/api/v1/management/access_key.rb +5 -4
  56. data/lib/descope/api/v1/management/common.rb +4 -1
  57. data/lib/descope/api/v1/management/role.rb +22 -6
  58. data/lib/descope/api/v1/management/user.rb +17 -0
  59. data/lib/descope/mixins/common.rb +2 -12
  60. data/lib/descope/mixins/http.rb +1 -1
  61. data/lib/descope/version.rb +1 -1
  62. data/spec/integration/lib.descope/api/v1/auth/enchantedlink_spec.rb +81 -0
  63. data/spec/integration/lib.descope/api/v1/auth/magiclink_spec.rb +49 -0
  64. data/spec/integration/lib.descope/api/v1/auth/otp_spec.rb +38 -0
  65. data/spec/integration/lib.descope/api/v1/auth/password_spec.rb +41 -0
  66. data/spec/integration/lib.descope/api/v1/auth/totp_spec.rb +76 -0
  67. data/spec/integration/lib.descope/api/v1/management/access_key_spec.rb +62 -0
  68. data/spec/integration/lib.descope/api/v1/management/audit_spec.rb +16 -0
  69. data/spec/integration/lib.descope/api/v1/management/authz_spec.rb +187 -0
  70. data/spec/integration/lib.descope/api/v1/management/flow_spec.rb +44 -0
  71. data/spec/integration/lib.descope/api/v1/management/permissions_spec.rb +27 -0
  72. data/spec/integration/lib.descope/api/v1/management/project_spec.rb +29 -0
  73. data/spec/integration/lib.descope/api/v1/management/roles_spec.rb +116 -0
  74. data/spec/integration/lib.descope/api/v1/management/user_spec.rb +262 -0
  75. data/spec/lib.descope/api/v1/auth_spec.rb +50 -1
  76. data/spec/lib.descope/api/v1/management/access_key_spec.rb +4 -2
  77. data/spec/lib.descope/api/v1/management/role_spec.rb +35 -6
  78. data/spec/lib.descope/api/v1/management/user_spec.rb +40 -0
  79. data/spec/spec_helper.rb +9 -38
  80. data/spec/support/client_config.rb +5 -1
  81. data/spec/support/dummy_class.rb +15 -1
  82. data/spec/support/utils.rb +1 -1
  83. metadata +56 -4
  84. data/examples/ruby-on-rails-api/descope/tmp/pids/.keep +0 -0
  85. data/examples/ruby-on-rails-api/descope/tmp/storage/.keep +0 -0
@@ -0,0 +1,2453 @@
1
+ // node_modules/@hotwired/stimulus/dist/stimulus.js
2
+ var EventListener = class {
3
+ constructor(eventTarget, eventName, eventOptions) {
4
+ this.eventTarget = eventTarget;
5
+ this.eventName = eventName;
6
+ this.eventOptions = eventOptions;
7
+ this.unorderedBindings = /* @__PURE__ */ new Set();
8
+ }
9
+ connect() {
10
+ this.eventTarget.addEventListener(this.eventName, this, this.eventOptions);
11
+ }
12
+ disconnect() {
13
+ this.eventTarget.removeEventListener(this.eventName, this, this.eventOptions);
14
+ }
15
+ bindingConnected(binding) {
16
+ this.unorderedBindings.add(binding);
17
+ }
18
+ bindingDisconnected(binding) {
19
+ this.unorderedBindings.delete(binding);
20
+ }
21
+ handleEvent(event) {
22
+ const extendedEvent = extendEvent(event);
23
+ for (const binding of this.bindings) {
24
+ if (extendedEvent.immediatePropagationStopped) {
25
+ break;
26
+ } else {
27
+ binding.handleEvent(extendedEvent);
28
+ }
29
+ }
30
+ }
31
+ hasBindings() {
32
+ return this.unorderedBindings.size > 0;
33
+ }
34
+ get bindings() {
35
+ return Array.from(this.unorderedBindings).sort((left, right) => {
36
+ const leftIndex = left.index, rightIndex = right.index;
37
+ return leftIndex < rightIndex ? -1 : leftIndex > rightIndex ? 1 : 0;
38
+ });
39
+ }
40
+ };
41
+ function extendEvent(event) {
42
+ if ("immediatePropagationStopped" in event) {
43
+ return event;
44
+ } else {
45
+ const { stopImmediatePropagation } = event;
46
+ return Object.assign(event, {
47
+ immediatePropagationStopped: false,
48
+ stopImmediatePropagation() {
49
+ this.immediatePropagationStopped = true;
50
+ stopImmediatePropagation.call(this);
51
+ }
52
+ });
53
+ }
54
+ }
55
+ var Dispatcher = class {
56
+ constructor(application2) {
57
+ this.application = application2;
58
+ this.eventListenerMaps = /* @__PURE__ */ new Map();
59
+ this.started = false;
60
+ }
61
+ start() {
62
+ if (!this.started) {
63
+ this.started = true;
64
+ this.eventListeners.forEach((eventListener) => eventListener.connect());
65
+ }
66
+ }
67
+ stop() {
68
+ if (this.started) {
69
+ this.started = false;
70
+ this.eventListeners.forEach((eventListener) => eventListener.disconnect());
71
+ }
72
+ }
73
+ get eventListeners() {
74
+ return Array.from(this.eventListenerMaps.values()).reduce((listeners, map) => listeners.concat(Array.from(map.values())), []);
75
+ }
76
+ bindingConnected(binding) {
77
+ this.fetchEventListenerForBinding(binding).bindingConnected(binding);
78
+ }
79
+ bindingDisconnected(binding, clearEventListeners = false) {
80
+ this.fetchEventListenerForBinding(binding).bindingDisconnected(binding);
81
+ if (clearEventListeners)
82
+ this.clearEventListenersForBinding(binding);
83
+ }
84
+ handleError(error2, message, detail = {}) {
85
+ this.application.handleError(error2, `Error ${message}`, detail);
86
+ }
87
+ clearEventListenersForBinding(binding) {
88
+ const eventListener = this.fetchEventListenerForBinding(binding);
89
+ if (!eventListener.hasBindings()) {
90
+ eventListener.disconnect();
91
+ this.removeMappedEventListenerFor(binding);
92
+ }
93
+ }
94
+ removeMappedEventListenerFor(binding) {
95
+ const { eventTarget, eventName, eventOptions } = binding;
96
+ const eventListenerMap = this.fetchEventListenerMapForEventTarget(eventTarget);
97
+ const cacheKey = this.cacheKey(eventName, eventOptions);
98
+ eventListenerMap.delete(cacheKey);
99
+ if (eventListenerMap.size == 0)
100
+ this.eventListenerMaps.delete(eventTarget);
101
+ }
102
+ fetchEventListenerForBinding(binding) {
103
+ const { eventTarget, eventName, eventOptions } = binding;
104
+ return this.fetchEventListener(eventTarget, eventName, eventOptions);
105
+ }
106
+ fetchEventListener(eventTarget, eventName, eventOptions) {
107
+ const eventListenerMap = this.fetchEventListenerMapForEventTarget(eventTarget);
108
+ const cacheKey = this.cacheKey(eventName, eventOptions);
109
+ let eventListener = eventListenerMap.get(cacheKey);
110
+ if (!eventListener) {
111
+ eventListener = this.createEventListener(eventTarget, eventName, eventOptions);
112
+ eventListenerMap.set(cacheKey, eventListener);
113
+ }
114
+ return eventListener;
115
+ }
116
+ createEventListener(eventTarget, eventName, eventOptions) {
117
+ const eventListener = new EventListener(eventTarget, eventName, eventOptions);
118
+ if (this.started) {
119
+ eventListener.connect();
120
+ }
121
+ return eventListener;
122
+ }
123
+ fetchEventListenerMapForEventTarget(eventTarget) {
124
+ let eventListenerMap = this.eventListenerMaps.get(eventTarget);
125
+ if (!eventListenerMap) {
126
+ eventListenerMap = /* @__PURE__ */ new Map();
127
+ this.eventListenerMaps.set(eventTarget, eventListenerMap);
128
+ }
129
+ return eventListenerMap;
130
+ }
131
+ cacheKey(eventName, eventOptions) {
132
+ const parts = [eventName];
133
+ Object.keys(eventOptions).sort().forEach((key) => {
134
+ parts.push(`${eventOptions[key] ? "" : "!"}${key}`);
135
+ });
136
+ return parts.join(":");
137
+ }
138
+ };
139
+ var defaultActionDescriptorFilters = {
140
+ stop({ event, value }) {
141
+ if (value)
142
+ event.stopPropagation();
143
+ return true;
144
+ },
145
+ prevent({ event, value }) {
146
+ if (value)
147
+ event.preventDefault();
148
+ return true;
149
+ },
150
+ self({ event, value, element }) {
151
+ if (value) {
152
+ return element === event.target;
153
+ } else {
154
+ return true;
155
+ }
156
+ }
157
+ };
158
+ var descriptorPattern = /^(?:(?:([^.]+?)\+)?(.+?)(?:\.(.+?))?(?:@(window|document))?->)?(.+?)(?:#([^:]+?))(?::(.+))?$/;
159
+ function parseActionDescriptorString(descriptorString) {
160
+ const source = descriptorString.trim();
161
+ const matches = source.match(descriptorPattern) || [];
162
+ let eventName = matches[2];
163
+ let keyFilter = matches[3];
164
+ if (keyFilter && !["keydown", "keyup", "keypress"].includes(eventName)) {
165
+ eventName += `.${keyFilter}`;
166
+ keyFilter = "";
167
+ }
168
+ return {
169
+ eventTarget: parseEventTarget(matches[4]),
170
+ eventName,
171
+ eventOptions: matches[7] ? parseEventOptions(matches[7]) : {},
172
+ identifier: matches[5],
173
+ methodName: matches[6],
174
+ keyFilter: matches[1] || keyFilter
175
+ };
176
+ }
177
+ function parseEventTarget(eventTargetName) {
178
+ if (eventTargetName == "window") {
179
+ return window;
180
+ } else if (eventTargetName == "document") {
181
+ return document;
182
+ }
183
+ }
184
+ function parseEventOptions(eventOptions) {
185
+ return eventOptions.split(":").reduce((options, token) => Object.assign(options, { [token.replace(/^!/, "")]: !/^!/.test(token) }), {});
186
+ }
187
+ function stringifyEventTarget(eventTarget) {
188
+ if (eventTarget == window) {
189
+ return "window";
190
+ } else if (eventTarget == document) {
191
+ return "document";
192
+ }
193
+ }
194
+ function camelize(value) {
195
+ return value.replace(/(?:[_-])([a-z0-9])/g, (_, char) => char.toUpperCase());
196
+ }
197
+ function namespaceCamelize(value) {
198
+ return camelize(value.replace(/--/g, "-").replace(/__/g, "_"));
199
+ }
200
+ function capitalize(value) {
201
+ return value.charAt(0).toUpperCase() + value.slice(1);
202
+ }
203
+ function dasherize(value) {
204
+ return value.replace(/([A-Z])/g, (_, char) => `-${char.toLowerCase()}`);
205
+ }
206
+ function tokenize(value) {
207
+ return value.match(/[^\s]+/g) || [];
208
+ }
209
+ function isSomething(object) {
210
+ return object !== null && object !== void 0;
211
+ }
212
+ function hasProperty(object, property) {
213
+ return Object.prototype.hasOwnProperty.call(object, property);
214
+ }
215
+ var allModifiers = ["meta", "ctrl", "alt", "shift"];
216
+ var Action = class {
217
+ constructor(element, index, descriptor, schema) {
218
+ this.element = element;
219
+ this.index = index;
220
+ this.eventTarget = descriptor.eventTarget || element;
221
+ this.eventName = descriptor.eventName || getDefaultEventNameForElement(element) || error("missing event name");
222
+ this.eventOptions = descriptor.eventOptions || {};
223
+ this.identifier = descriptor.identifier || error("missing identifier");
224
+ this.methodName = descriptor.methodName || error("missing method name");
225
+ this.keyFilter = descriptor.keyFilter || "";
226
+ this.schema = schema;
227
+ }
228
+ static forToken(token, schema) {
229
+ return new this(token.element, token.index, parseActionDescriptorString(token.content), schema);
230
+ }
231
+ toString() {
232
+ const eventFilter = this.keyFilter ? `.${this.keyFilter}` : "";
233
+ const eventTarget = this.eventTargetName ? `@${this.eventTargetName}` : "";
234
+ return `${this.eventName}${eventFilter}${eventTarget}->${this.identifier}#${this.methodName}`;
235
+ }
236
+ shouldIgnoreKeyboardEvent(event) {
237
+ if (!this.keyFilter) {
238
+ return false;
239
+ }
240
+ const filters = this.keyFilter.split("+");
241
+ if (this.keyFilterDissatisfied(event, filters)) {
242
+ return true;
243
+ }
244
+ const standardFilter = filters.filter((key) => !allModifiers.includes(key))[0];
245
+ if (!standardFilter) {
246
+ return false;
247
+ }
248
+ if (!hasProperty(this.keyMappings, standardFilter)) {
249
+ error(`contains unknown key filter: ${this.keyFilter}`);
250
+ }
251
+ return this.keyMappings[standardFilter].toLowerCase() !== event.key.toLowerCase();
252
+ }
253
+ shouldIgnoreMouseEvent(event) {
254
+ if (!this.keyFilter) {
255
+ return false;
256
+ }
257
+ const filters = [this.keyFilter];
258
+ if (this.keyFilterDissatisfied(event, filters)) {
259
+ return true;
260
+ }
261
+ return false;
262
+ }
263
+ get params() {
264
+ const params = {};
265
+ const pattern = new RegExp(`^data-${this.identifier}-(.+)-param$`, "i");
266
+ for (const { name, value } of Array.from(this.element.attributes)) {
267
+ const match = name.match(pattern);
268
+ const key = match && match[1];
269
+ if (key) {
270
+ params[camelize(key)] = typecast(value);
271
+ }
272
+ }
273
+ return params;
274
+ }
275
+ get eventTargetName() {
276
+ return stringifyEventTarget(this.eventTarget);
277
+ }
278
+ get keyMappings() {
279
+ return this.schema.keyMappings;
280
+ }
281
+ keyFilterDissatisfied(event, filters) {
282
+ const [meta, ctrl, alt, shift] = allModifiers.map((modifier) => filters.includes(modifier));
283
+ return event.metaKey !== meta || event.ctrlKey !== ctrl || event.altKey !== alt || event.shiftKey !== shift;
284
+ }
285
+ };
286
+ var defaultEventNames = {
287
+ a: () => "click",
288
+ button: () => "click",
289
+ form: () => "submit",
290
+ details: () => "toggle",
291
+ input: (e) => e.getAttribute("type") == "submit" ? "click" : "input",
292
+ select: () => "change",
293
+ textarea: () => "input"
294
+ };
295
+ function getDefaultEventNameForElement(element) {
296
+ const tagName = element.tagName.toLowerCase();
297
+ if (tagName in defaultEventNames) {
298
+ return defaultEventNames[tagName](element);
299
+ }
300
+ }
301
+ function error(message) {
302
+ throw new Error(message);
303
+ }
304
+ function typecast(value) {
305
+ try {
306
+ return JSON.parse(value);
307
+ } catch (o_O) {
308
+ return value;
309
+ }
310
+ }
311
+ var Binding = class {
312
+ constructor(context, action) {
313
+ this.context = context;
314
+ this.action = action;
315
+ }
316
+ get index() {
317
+ return this.action.index;
318
+ }
319
+ get eventTarget() {
320
+ return this.action.eventTarget;
321
+ }
322
+ get eventOptions() {
323
+ return this.action.eventOptions;
324
+ }
325
+ get identifier() {
326
+ return this.context.identifier;
327
+ }
328
+ handleEvent(event) {
329
+ const actionEvent = this.prepareActionEvent(event);
330
+ if (this.willBeInvokedByEvent(event) && this.applyEventModifiers(actionEvent)) {
331
+ this.invokeWithEvent(actionEvent);
332
+ }
333
+ }
334
+ get eventName() {
335
+ return this.action.eventName;
336
+ }
337
+ get method() {
338
+ const method = this.controller[this.methodName];
339
+ if (typeof method == "function") {
340
+ return method;
341
+ }
342
+ throw new Error(`Action "${this.action}" references undefined method "${this.methodName}"`);
343
+ }
344
+ applyEventModifiers(event) {
345
+ const { element } = this.action;
346
+ const { actionDescriptorFilters } = this.context.application;
347
+ const { controller } = this.context;
348
+ let passes = true;
349
+ for (const [name, value] of Object.entries(this.eventOptions)) {
350
+ if (name in actionDescriptorFilters) {
351
+ const filter = actionDescriptorFilters[name];
352
+ passes = passes && filter({ name, value, event, element, controller });
353
+ } else {
354
+ continue;
355
+ }
356
+ }
357
+ return passes;
358
+ }
359
+ prepareActionEvent(event) {
360
+ return Object.assign(event, { params: this.action.params });
361
+ }
362
+ invokeWithEvent(event) {
363
+ const { target, currentTarget } = event;
364
+ try {
365
+ this.method.call(this.controller, event);
366
+ this.context.logDebugActivity(this.methodName, { event, target, currentTarget, action: this.methodName });
367
+ } catch (error2) {
368
+ const { identifier, controller, element, index } = this;
369
+ const detail = { identifier, controller, element, index, event };
370
+ this.context.handleError(error2, `invoking action "${this.action}"`, detail);
371
+ }
372
+ }
373
+ willBeInvokedByEvent(event) {
374
+ const eventTarget = event.target;
375
+ if (event instanceof KeyboardEvent && this.action.shouldIgnoreKeyboardEvent(event)) {
376
+ return false;
377
+ }
378
+ if (event instanceof MouseEvent && this.action.shouldIgnoreMouseEvent(event)) {
379
+ return false;
380
+ }
381
+ if (this.element === eventTarget) {
382
+ return true;
383
+ } else if (eventTarget instanceof Element && this.element.contains(eventTarget)) {
384
+ return this.scope.containsElement(eventTarget);
385
+ } else {
386
+ return this.scope.containsElement(this.action.element);
387
+ }
388
+ }
389
+ get controller() {
390
+ return this.context.controller;
391
+ }
392
+ get methodName() {
393
+ return this.action.methodName;
394
+ }
395
+ get element() {
396
+ return this.scope.element;
397
+ }
398
+ get scope() {
399
+ return this.context.scope;
400
+ }
401
+ };
402
+ var ElementObserver = class {
403
+ constructor(element, delegate) {
404
+ this.mutationObserverInit = { attributes: true, childList: true, subtree: true };
405
+ this.element = element;
406
+ this.started = false;
407
+ this.delegate = delegate;
408
+ this.elements = /* @__PURE__ */ new Set();
409
+ this.mutationObserver = new MutationObserver((mutations) => this.processMutations(mutations));
410
+ }
411
+ start() {
412
+ if (!this.started) {
413
+ this.started = true;
414
+ this.mutationObserver.observe(this.element, this.mutationObserverInit);
415
+ this.refresh();
416
+ }
417
+ }
418
+ pause(callback) {
419
+ if (this.started) {
420
+ this.mutationObserver.disconnect();
421
+ this.started = false;
422
+ }
423
+ callback();
424
+ if (!this.started) {
425
+ this.mutationObserver.observe(this.element, this.mutationObserverInit);
426
+ this.started = true;
427
+ }
428
+ }
429
+ stop() {
430
+ if (this.started) {
431
+ this.mutationObserver.takeRecords();
432
+ this.mutationObserver.disconnect();
433
+ this.started = false;
434
+ }
435
+ }
436
+ refresh() {
437
+ if (this.started) {
438
+ const matches = new Set(this.matchElementsInTree());
439
+ for (const element of Array.from(this.elements)) {
440
+ if (!matches.has(element)) {
441
+ this.removeElement(element);
442
+ }
443
+ }
444
+ for (const element of Array.from(matches)) {
445
+ this.addElement(element);
446
+ }
447
+ }
448
+ }
449
+ processMutations(mutations) {
450
+ if (this.started) {
451
+ for (const mutation of mutations) {
452
+ this.processMutation(mutation);
453
+ }
454
+ }
455
+ }
456
+ processMutation(mutation) {
457
+ if (mutation.type == "attributes") {
458
+ this.processAttributeChange(mutation.target, mutation.attributeName);
459
+ } else if (mutation.type == "childList") {
460
+ this.processRemovedNodes(mutation.removedNodes);
461
+ this.processAddedNodes(mutation.addedNodes);
462
+ }
463
+ }
464
+ processAttributeChange(element, attributeName) {
465
+ if (this.elements.has(element)) {
466
+ if (this.delegate.elementAttributeChanged && this.matchElement(element)) {
467
+ this.delegate.elementAttributeChanged(element, attributeName);
468
+ } else {
469
+ this.removeElement(element);
470
+ }
471
+ } else if (this.matchElement(element)) {
472
+ this.addElement(element);
473
+ }
474
+ }
475
+ processRemovedNodes(nodes) {
476
+ for (const node of Array.from(nodes)) {
477
+ const element = this.elementFromNode(node);
478
+ if (element) {
479
+ this.processTree(element, this.removeElement);
480
+ }
481
+ }
482
+ }
483
+ processAddedNodes(nodes) {
484
+ for (const node of Array.from(nodes)) {
485
+ const element = this.elementFromNode(node);
486
+ if (element && this.elementIsActive(element)) {
487
+ this.processTree(element, this.addElement);
488
+ }
489
+ }
490
+ }
491
+ matchElement(element) {
492
+ return this.delegate.matchElement(element);
493
+ }
494
+ matchElementsInTree(tree = this.element) {
495
+ return this.delegate.matchElementsInTree(tree);
496
+ }
497
+ processTree(tree, processor) {
498
+ for (const element of this.matchElementsInTree(tree)) {
499
+ processor.call(this, element);
500
+ }
501
+ }
502
+ elementFromNode(node) {
503
+ if (node.nodeType == Node.ELEMENT_NODE) {
504
+ return node;
505
+ }
506
+ }
507
+ elementIsActive(element) {
508
+ if (element.isConnected != this.element.isConnected) {
509
+ return false;
510
+ } else {
511
+ return this.element.contains(element);
512
+ }
513
+ }
514
+ addElement(element) {
515
+ if (!this.elements.has(element)) {
516
+ if (this.elementIsActive(element)) {
517
+ this.elements.add(element);
518
+ if (this.delegate.elementMatched) {
519
+ this.delegate.elementMatched(element);
520
+ }
521
+ }
522
+ }
523
+ }
524
+ removeElement(element) {
525
+ if (this.elements.has(element)) {
526
+ this.elements.delete(element);
527
+ if (this.delegate.elementUnmatched) {
528
+ this.delegate.elementUnmatched(element);
529
+ }
530
+ }
531
+ }
532
+ };
533
+ var AttributeObserver = class {
534
+ constructor(element, attributeName, delegate) {
535
+ this.attributeName = attributeName;
536
+ this.delegate = delegate;
537
+ this.elementObserver = new ElementObserver(element, this);
538
+ }
539
+ get element() {
540
+ return this.elementObserver.element;
541
+ }
542
+ get selector() {
543
+ return `[${this.attributeName}]`;
544
+ }
545
+ start() {
546
+ this.elementObserver.start();
547
+ }
548
+ pause(callback) {
549
+ this.elementObserver.pause(callback);
550
+ }
551
+ stop() {
552
+ this.elementObserver.stop();
553
+ }
554
+ refresh() {
555
+ this.elementObserver.refresh();
556
+ }
557
+ get started() {
558
+ return this.elementObserver.started;
559
+ }
560
+ matchElement(element) {
561
+ return element.hasAttribute(this.attributeName);
562
+ }
563
+ matchElementsInTree(tree) {
564
+ const match = this.matchElement(tree) ? [tree] : [];
565
+ const matches = Array.from(tree.querySelectorAll(this.selector));
566
+ return match.concat(matches);
567
+ }
568
+ elementMatched(element) {
569
+ if (this.delegate.elementMatchedAttribute) {
570
+ this.delegate.elementMatchedAttribute(element, this.attributeName);
571
+ }
572
+ }
573
+ elementUnmatched(element) {
574
+ if (this.delegate.elementUnmatchedAttribute) {
575
+ this.delegate.elementUnmatchedAttribute(element, this.attributeName);
576
+ }
577
+ }
578
+ elementAttributeChanged(element, attributeName) {
579
+ if (this.delegate.elementAttributeValueChanged && this.attributeName == attributeName) {
580
+ this.delegate.elementAttributeValueChanged(element, attributeName);
581
+ }
582
+ }
583
+ };
584
+ function add(map, key, value) {
585
+ fetch(map, key).add(value);
586
+ }
587
+ function del(map, key, value) {
588
+ fetch(map, key).delete(value);
589
+ prune(map, key);
590
+ }
591
+ function fetch(map, key) {
592
+ let values = map.get(key);
593
+ if (!values) {
594
+ values = /* @__PURE__ */ new Set();
595
+ map.set(key, values);
596
+ }
597
+ return values;
598
+ }
599
+ function prune(map, key) {
600
+ const values = map.get(key);
601
+ if (values != null && values.size == 0) {
602
+ map.delete(key);
603
+ }
604
+ }
605
+ var Multimap = class {
606
+ constructor() {
607
+ this.valuesByKey = /* @__PURE__ */ new Map();
608
+ }
609
+ get keys() {
610
+ return Array.from(this.valuesByKey.keys());
611
+ }
612
+ get values() {
613
+ const sets = Array.from(this.valuesByKey.values());
614
+ return sets.reduce((values, set) => values.concat(Array.from(set)), []);
615
+ }
616
+ get size() {
617
+ const sets = Array.from(this.valuesByKey.values());
618
+ return sets.reduce((size, set) => size + set.size, 0);
619
+ }
620
+ add(key, value) {
621
+ add(this.valuesByKey, key, value);
622
+ }
623
+ delete(key, value) {
624
+ del(this.valuesByKey, key, value);
625
+ }
626
+ has(key, value) {
627
+ const values = this.valuesByKey.get(key);
628
+ return values != null && values.has(value);
629
+ }
630
+ hasKey(key) {
631
+ return this.valuesByKey.has(key);
632
+ }
633
+ hasValue(value) {
634
+ const sets = Array.from(this.valuesByKey.values());
635
+ return sets.some((set) => set.has(value));
636
+ }
637
+ getValuesForKey(key) {
638
+ const values = this.valuesByKey.get(key);
639
+ return values ? Array.from(values) : [];
640
+ }
641
+ getKeysForValue(value) {
642
+ return Array.from(this.valuesByKey).filter(([_key, values]) => values.has(value)).map(([key, _values]) => key);
643
+ }
644
+ };
645
+ var SelectorObserver = class {
646
+ constructor(element, selector, delegate, details) {
647
+ this._selector = selector;
648
+ this.details = details;
649
+ this.elementObserver = new ElementObserver(element, this);
650
+ this.delegate = delegate;
651
+ this.matchesByElement = new Multimap();
652
+ }
653
+ get started() {
654
+ return this.elementObserver.started;
655
+ }
656
+ get selector() {
657
+ return this._selector;
658
+ }
659
+ set selector(selector) {
660
+ this._selector = selector;
661
+ this.refresh();
662
+ }
663
+ start() {
664
+ this.elementObserver.start();
665
+ }
666
+ pause(callback) {
667
+ this.elementObserver.pause(callback);
668
+ }
669
+ stop() {
670
+ this.elementObserver.stop();
671
+ }
672
+ refresh() {
673
+ this.elementObserver.refresh();
674
+ }
675
+ get element() {
676
+ return this.elementObserver.element;
677
+ }
678
+ matchElement(element) {
679
+ const { selector } = this;
680
+ if (selector) {
681
+ const matches = element.matches(selector);
682
+ if (this.delegate.selectorMatchElement) {
683
+ return matches && this.delegate.selectorMatchElement(element, this.details);
684
+ }
685
+ return matches;
686
+ } else {
687
+ return false;
688
+ }
689
+ }
690
+ matchElementsInTree(tree) {
691
+ const { selector } = this;
692
+ if (selector) {
693
+ const match = this.matchElement(tree) ? [tree] : [];
694
+ const matches = Array.from(tree.querySelectorAll(selector)).filter((match2) => this.matchElement(match2));
695
+ return match.concat(matches);
696
+ } else {
697
+ return [];
698
+ }
699
+ }
700
+ elementMatched(element) {
701
+ const { selector } = this;
702
+ if (selector) {
703
+ this.selectorMatched(element, selector);
704
+ }
705
+ }
706
+ elementUnmatched(element) {
707
+ const selectors = this.matchesByElement.getKeysForValue(element);
708
+ for (const selector of selectors) {
709
+ this.selectorUnmatched(element, selector);
710
+ }
711
+ }
712
+ elementAttributeChanged(element, _attributeName) {
713
+ const { selector } = this;
714
+ if (selector) {
715
+ const matches = this.matchElement(element);
716
+ const matchedBefore = this.matchesByElement.has(selector, element);
717
+ if (matches && !matchedBefore) {
718
+ this.selectorMatched(element, selector);
719
+ } else if (!matches && matchedBefore) {
720
+ this.selectorUnmatched(element, selector);
721
+ }
722
+ }
723
+ }
724
+ selectorMatched(element, selector) {
725
+ this.delegate.selectorMatched(element, selector, this.details);
726
+ this.matchesByElement.add(selector, element);
727
+ }
728
+ selectorUnmatched(element, selector) {
729
+ this.delegate.selectorUnmatched(element, selector, this.details);
730
+ this.matchesByElement.delete(selector, element);
731
+ }
732
+ };
733
+ var StringMapObserver = class {
734
+ constructor(element, delegate) {
735
+ this.element = element;
736
+ this.delegate = delegate;
737
+ this.started = false;
738
+ this.stringMap = /* @__PURE__ */ new Map();
739
+ this.mutationObserver = new MutationObserver((mutations) => this.processMutations(mutations));
740
+ }
741
+ start() {
742
+ if (!this.started) {
743
+ this.started = true;
744
+ this.mutationObserver.observe(this.element, { attributes: true, attributeOldValue: true });
745
+ this.refresh();
746
+ }
747
+ }
748
+ stop() {
749
+ if (this.started) {
750
+ this.mutationObserver.takeRecords();
751
+ this.mutationObserver.disconnect();
752
+ this.started = false;
753
+ }
754
+ }
755
+ refresh() {
756
+ if (this.started) {
757
+ for (const attributeName of this.knownAttributeNames) {
758
+ this.refreshAttribute(attributeName, null);
759
+ }
760
+ }
761
+ }
762
+ processMutations(mutations) {
763
+ if (this.started) {
764
+ for (const mutation of mutations) {
765
+ this.processMutation(mutation);
766
+ }
767
+ }
768
+ }
769
+ processMutation(mutation) {
770
+ const attributeName = mutation.attributeName;
771
+ if (attributeName) {
772
+ this.refreshAttribute(attributeName, mutation.oldValue);
773
+ }
774
+ }
775
+ refreshAttribute(attributeName, oldValue) {
776
+ const key = this.delegate.getStringMapKeyForAttribute(attributeName);
777
+ if (key != null) {
778
+ if (!this.stringMap.has(attributeName)) {
779
+ this.stringMapKeyAdded(key, attributeName);
780
+ }
781
+ const value = this.element.getAttribute(attributeName);
782
+ if (this.stringMap.get(attributeName) != value) {
783
+ this.stringMapValueChanged(value, key, oldValue);
784
+ }
785
+ if (value == null) {
786
+ const oldValue2 = this.stringMap.get(attributeName);
787
+ this.stringMap.delete(attributeName);
788
+ if (oldValue2)
789
+ this.stringMapKeyRemoved(key, attributeName, oldValue2);
790
+ } else {
791
+ this.stringMap.set(attributeName, value);
792
+ }
793
+ }
794
+ }
795
+ stringMapKeyAdded(key, attributeName) {
796
+ if (this.delegate.stringMapKeyAdded) {
797
+ this.delegate.stringMapKeyAdded(key, attributeName);
798
+ }
799
+ }
800
+ stringMapValueChanged(value, key, oldValue) {
801
+ if (this.delegate.stringMapValueChanged) {
802
+ this.delegate.stringMapValueChanged(value, key, oldValue);
803
+ }
804
+ }
805
+ stringMapKeyRemoved(key, attributeName, oldValue) {
806
+ if (this.delegate.stringMapKeyRemoved) {
807
+ this.delegate.stringMapKeyRemoved(key, attributeName, oldValue);
808
+ }
809
+ }
810
+ get knownAttributeNames() {
811
+ return Array.from(new Set(this.currentAttributeNames.concat(this.recordedAttributeNames)));
812
+ }
813
+ get currentAttributeNames() {
814
+ return Array.from(this.element.attributes).map((attribute) => attribute.name);
815
+ }
816
+ get recordedAttributeNames() {
817
+ return Array.from(this.stringMap.keys());
818
+ }
819
+ };
820
+ var TokenListObserver = class {
821
+ constructor(element, attributeName, delegate) {
822
+ this.attributeObserver = new AttributeObserver(element, attributeName, this);
823
+ this.delegate = delegate;
824
+ this.tokensByElement = new Multimap();
825
+ }
826
+ get started() {
827
+ return this.attributeObserver.started;
828
+ }
829
+ start() {
830
+ this.attributeObserver.start();
831
+ }
832
+ pause(callback) {
833
+ this.attributeObserver.pause(callback);
834
+ }
835
+ stop() {
836
+ this.attributeObserver.stop();
837
+ }
838
+ refresh() {
839
+ this.attributeObserver.refresh();
840
+ }
841
+ get element() {
842
+ return this.attributeObserver.element;
843
+ }
844
+ get attributeName() {
845
+ return this.attributeObserver.attributeName;
846
+ }
847
+ elementMatchedAttribute(element) {
848
+ this.tokensMatched(this.readTokensForElement(element));
849
+ }
850
+ elementAttributeValueChanged(element) {
851
+ const [unmatchedTokens, matchedTokens] = this.refreshTokensForElement(element);
852
+ this.tokensUnmatched(unmatchedTokens);
853
+ this.tokensMatched(matchedTokens);
854
+ }
855
+ elementUnmatchedAttribute(element) {
856
+ this.tokensUnmatched(this.tokensByElement.getValuesForKey(element));
857
+ }
858
+ tokensMatched(tokens) {
859
+ tokens.forEach((token) => this.tokenMatched(token));
860
+ }
861
+ tokensUnmatched(tokens) {
862
+ tokens.forEach((token) => this.tokenUnmatched(token));
863
+ }
864
+ tokenMatched(token) {
865
+ this.delegate.tokenMatched(token);
866
+ this.tokensByElement.add(token.element, token);
867
+ }
868
+ tokenUnmatched(token) {
869
+ this.delegate.tokenUnmatched(token);
870
+ this.tokensByElement.delete(token.element, token);
871
+ }
872
+ refreshTokensForElement(element) {
873
+ const previousTokens = this.tokensByElement.getValuesForKey(element);
874
+ const currentTokens = this.readTokensForElement(element);
875
+ const firstDifferingIndex = zip(previousTokens, currentTokens).findIndex(([previousToken, currentToken]) => !tokensAreEqual(previousToken, currentToken));
876
+ if (firstDifferingIndex == -1) {
877
+ return [[], []];
878
+ } else {
879
+ return [previousTokens.slice(firstDifferingIndex), currentTokens.slice(firstDifferingIndex)];
880
+ }
881
+ }
882
+ readTokensForElement(element) {
883
+ const attributeName = this.attributeName;
884
+ const tokenString = element.getAttribute(attributeName) || "";
885
+ return parseTokenString(tokenString, element, attributeName);
886
+ }
887
+ };
888
+ function parseTokenString(tokenString, element, attributeName) {
889
+ return tokenString.trim().split(/\s+/).filter((content) => content.length).map((content, index) => ({ element, attributeName, content, index }));
890
+ }
891
+ function zip(left, right) {
892
+ const length = Math.max(left.length, right.length);
893
+ return Array.from({ length }, (_, index) => [left[index], right[index]]);
894
+ }
895
+ function tokensAreEqual(left, right) {
896
+ return left && right && left.index == right.index && left.content == right.content;
897
+ }
898
+ var ValueListObserver = class {
899
+ constructor(element, attributeName, delegate) {
900
+ this.tokenListObserver = new TokenListObserver(element, attributeName, this);
901
+ this.delegate = delegate;
902
+ this.parseResultsByToken = /* @__PURE__ */ new WeakMap();
903
+ this.valuesByTokenByElement = /* @__PURE__ */ new WeakMap();
904
+ }
905
+ get started() {
906
+ return this.tokenListObserver.started;
907
+ }
908
+ start() {
909
+ this.tokenListObserver.start();
910
+ }
911
+ stop() {
912
+ this.tokenListObserver.stop();
913
+ }
914
+ refresh() {
915
+ this.tokenListObserver.refresh();
916
+ }
917
+ get element() {
918
+ return this.tokenListObserver.element;
919
+ }
920
+ get attributeName() {
921
+ return this.tokenListObserver.attributeName;
922
+ }
923
+ tokenMatched(token) {
924
+ const { element } = token;
925
+ const { value } = this.fetchParseResultForToken(token);
926
+ if (value) {
927
+ this.fetchValuesByTokenForElement(element).set(token, value);
928
+ this.delegate.elementMatchedValue(element, value);
929
+ }
930
+ }
931
+ tokenUnmatched(token) {
932
+ const { element } = token;
933
+ const { value } = this.fetchParseResultForToken(token);
934
+ if (value) {
935
+ this.fetchValuesByTokenForElement(element).delete(token);
936
+ this.delegate.elementUnmatchedValue(element, value);
937
+ }
938
+ }
939
+ fetchParseResultForToken(token) {
940
+ let parseResult = this.parseResultsByToken.get(token);
941
+ if (!parseResult) {
942
+ parseResult = this.parseToken(token);
943
+ this.parseResultsByToken.set(token, parseResult);
944
+ }
945
+ return parseResult;
946
+ }
947
+ fetchValuesByTokenForElement(element) {
948
+ let valuesByToken = this.valuesByTokenByElement.get(element);
949
+ if (!valuesByToken) {
950
+ valuesByToken = /* @__PURE__ */ new Map();
951
+ this.valuesByTokenByElement.set(element, valuesByToken);
952
+ }
953
+ return valuesByToken;
954
+ }
955
+ parseToken(token) {
956
+ try {
957
+ const value = this.delegate.parseValueForToken(token);
958
+ return { value };
959
+ } catch (error2) {
960
+ return { error: error2 };
961
+ }
962
+ }
963
+ };
964
+ var BindingObserver = class {
965
+ constructor(context, delegate) {
966
+ this.context = context;
967
+ this.delegate = delegate;
968
+ this.bindingsByAction = /* @__PURE__ */ new Map();
969
+ }
970
+ start() {
971
+ if (!this.valueListObserver) {
972
+ this.valueListObserver = new ValueListObserver(this.element, this.actionAttribute, this);
973
+ this.valueListObserver.start();
974
+ }
975
+ }
976
+ stop() {
977
+ if (this.valueListObserver) {
978
+ this.valueListObserver.stop();
979
+ delete this.valueListObserver;
980
+ this.disconnectAllActions();
981
+ }
982
+ }
983
+ get element() {
984
+ return this.context.element;
985
+ }
986
+ get identifier() {
987
+ return this.context.identifier;
988
+ }
989
+ get actionAttribute() {
990
+ return this.schema.actionAttribute;
991
+ }
992
+ get schema() {
993
+ return this.context.schema;
994
+ }
995
+ get bindings() {
996
+ return Array.from(this.bindingsByAction.values());
997
+ }
998
+ connectAction(action) {
999
+ const binding = new Binding(this.context, action);
1000
+ this.bindingsByAction.set(action, binding);
1001
+ this.delegate.bindingConnected(binding);
1002
+ }
1003
+ disconnectAction(action) {
1004
+ const binding = this.bindingsByAction.get(action);
1005
+ if (binding) {
1006
+ this.bindingsByAction.delete(action);
1007
+ this.delegate.bindingDisconnected(binding);
1008
+ }
1009
+ }
1010
+ disconnectAllActions() {
1011
+ this.bindings.forEach((binding) => this.delegate.bindingDisconnected(binding, true));
1012
+ this.bindingsByAction.clear();
1013
+ }
1014
+ parseValueForToken(token) {
1015
+ const action = Action.forToken(token, this.schema);
1016
+ if (action.identifier == this.identifier) {
1017
+ return action;
1018
+ }
1019
+ }
1020
+ elementMatchedValue(element, action) {
1021
+ this.connectAction(action);
1022
+ }
1023
+ elementUnmatchedValue(element, action) {
1024
+ this.disconnectAction(action);
1025
+ }
1026
+ };
1027
+ var ValueObserver = class {
1028
+ constructor(context, receiver) {
1029
+ this.context = context;
1030
+ this.receiver = receiver;
1031
+ this.stringMapObserver = new StringMapObserver(this.element, this);
1032
+ this.valueDescriptorMap = this.controller.valueDescriptorMap;
1033
+ }
1034
+ start() {
1035
+ this.stringMapObserver.start();
1036
+ this.invokeChangedCallbacksForDefaultValues();
1037
+ }
1038
+ stop() {
1039
+ this.stringMapObserver.stop();
1040
+ }
1041
+ get element() {
1042
+ return this.context.element;
1043
+ }
1044
+ get controller() {
1045
+ return this.context.controller;
1046
+ }
1047
+ getStringMapKeyForAttribute(attributeName) {
1048
+ if (attributeName in this.valueDescriptorMap) {
1049
+ return this.valueDescriptorMap[attributeName].name;
1050
+ }
1051
+ }
1052
+ stringMapKeyAdded(key, attributeName) {
1053
+ const descriptor = this.valueDescriptorMap[attributeName];
1054
+ if (!this.hasValue(key)) {
1055
+ this.invokeChangedCallback(key, descriptor.writer(this.receiver[key]), descriptor.writer(descriptor.defaultValue));
1056
+ }
1057
+ }
1058
+ stringMapValueChanged(value, name, oldValue) {
1059
+ const descriptor = this.valueDescriptorNameMap[name];
1060
+ if (value === null)
1061
+ return;
1062
+ if (oldValue === null) {
1063
+ oldValue = descriptor.writer(descriptor.defaultValue);
1064
+ }
1065
+ this.invokeChangedCallback(name, value, oldValue);
1066
+ }
1067
+ stringMapKeyRemoved(key, attributeName, oldValue) {
1068
+ const descriptor = this.valueDescriptorNameMap[key];
1069
+ if (this.hasValue(key)) {
1070
+ this.invokeChangedCallback(key, descriptor.writer(this.receiver[key]), oldValue);
1071
+ } else {
1072
+ this.invokeChangedCallback(key, descriptor.writer(descriptor.defaultValue), oldValue);
1073
+ }
1074
+ }
1075
+ invokeChangedCallbacksForDefaultValues() {
1076
+ for (const { key, name, defaultValue, writer } of this.valueDescriptors) {
1077
+ if (defaultValue != void 0 && !this.controller.data.has(key)) {
1078
+ this.invokeChangedCallback(name, writer(defaultValue), void 0);
1079
+ }
1080
+ }
1081
+ }
1082
+ invokeChangedCallback(name, rawValue, rawOldValue) {
1083
+ const changedMethodName = `${name}Changed`;
1084
+ const changedMethod = this.receiver[changedMethodName];
1085
+ if (typeof changedMethod == "function") {
1086
+ const descriptor = this.valueDescriptorNameMap[name];
1087
+ try {
1088
+ const value = descriptor.reader(rawValue);
1089
+ let oldValue = rawOldValue;
1090
+ if (rawOldValue) {
1091
+ oldValue = descriptor.reader(rawOldValue);
1092
+ }
1093
+ changedMethod.call(this.receiver, value, oldValue);
1094
+ } catch (error2) {
1095
+ if (error2 instanceof TypeError) {
1096
+ error2.message = `Stimulus Value "${this.context.identifier}.${descriptor.name}" - ${error2.message}`;
1097
+ }
1098
+ throw error2;
1099
+ }
1100
+ }
1101
+ }
1102
+ get valueDescriptors() {
1103
+ const { valueDescriptorMap } = this;
1104
+ return Object.keys(valueDescriptorMap).map((key) => valueDescriptorMap[key]);
1105
+ }
1106
+ get valueDescriptorNameMap() {
1107
+ const descriptors = {};
1108
+ Object.keys(this.valueDescriptorMap).forEach((key) => {
1109
+ const descriptor = this.valueDescriptorMap[key];
1110
+ descriptors[descriptor.name] = descriptor;
1111
+ });
1112
+ return descriptors;
1113
+ }
1114
+ hasValue(attributeName) {
1115
+ const descriptor = this.valueDescriptorNameMap[attributeName];
1116
+ const hasMethodName = `has${capitalize(descriptor.name)}`;
1117
+ return this.receiver[hasMethodName];
1118
+ }
1119
+ };
1120
+ var TargetObserver = class {
1121
+ constructor(context, delegate) {
1122
+ this.context = context;
1123
+ this.delegate = delegate;
1124
+ this.targetsByName = new Multimap();
1125
+ }
1126
+ start() {
1127
+ if (!this.tokenListObserver) {
1128
+ this.tokenListObserver = new TokenListObserver(this.element, this.attributeName, this);
1129
+ this.tokenListObserver.start();
1130
+ }
1131
+ }
1132
+ stop() {
1133
+ if (this.tokenListObserver) {
1134
+ this.disconnectAllTargets();
1135
+ this.tokenListObserver.stop();
1136
+ delete this.tokenListObserver;
1137
+ }
1138
+ }
1139
+ tokenMatched({ element, content: name }) {
1140
+ if (this.scope.containsElement(element)) {
1141
+ this.connectTarget(element, name);
1142
+ }
1143
+ }
1144
+ tokenUnmatched({ element, content: name }) {
1145
+ this.disconnectTarget(element, name);
1146
+ }
1147
+ connectTarget(element, name) {
1148
+ var _a;
1149
+ if (!this.targetsByName.has(name, element)) {
1150
+ this.targetsByName.add(name, element);
1151
+ (_a = this.tokenListObserver) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.targetConnected(element, name));
1152
+ }
1153
+ }
1154
+ disconnectTarget(element, name) {
1155
+ var _a;
1156
+ if (this.targetsByName.has(name, element)) {
1157
+ this.targetsByName.delete(name, element);
1158
+ (_a = this.tokenListObserver) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.targetDisconnected(element, name));
1159
+ }
1160
+ }
1161
+ disconnectAllTargets() {
1162
+ for (const name of this.targetsByName.keys) {
1163
+ for (const element of this.targetsByName.getValuesForKey(name)) {
1164
+ this.disconnectTarget(element, name);
1165
+ }
1166
+ }
1167
+ }
1168
+ get attributeName() {
1169
+ return `data-${this.context.identifier}-target`;
1170
+ }
1171
+ get element() {
1172
+ return this.context.element;
1173
+ }
1174
+ get scope() {
1175
+ return this.context.scope;
1176
+ }
1177
+ };
1178
+ function readInheritableStaticArrayValues(constructor, propertyName) {
1179
+ const ancestors = getAncestorsForConstructor(constructor);
1180
+ return Array.from(ancestors.reduce((values, constructor2) => {
1181
+ getOwnStaticArrayValues(constructor2, propertyName).forEach((name) => values.add(name));
1182
+ return values;
1183
+ }, /* @__PURE__ */ new Set()));
1184
+ }
1185
+ function readInheritableStaticObjectPairs(constructor, propertyName) {
1186
+ const ancestors = getAncestorsForConstructor(constructor);
1187
+ return ancestors.reduce((pairs, constructor2) => {
1188
+ pairs.push(...getOwnStaticObjectPairs(constructor2, propertyName));
1189
+ return pairs;
1190
+ }, []);
1191
+ }
1192
+ function getAncestorsForConstructor(constructor) {
1193
+ const ancestors = [];
1194
+ while (constructor) {
1195
+ ancestors.push(constructor);
1196
+ constructor = Object.getPrototypeOf(constructor);
1197
+ }
1198
+ return ancestors.reverse();
1199
+ }
1200
+ function getOwnStaticArrayValues(constructor, propertyName) {
1201
+ const definition = constructor[propertyName];
1202
+ return Array.isArray(definition) ? definition : [];
1203
+ }
1204
+ function getOwnStaticObjectPairs(constructor, propertyName) {
1205
+ const definition = constructor[propertyName];
1206
+ return definition ? Object.keys(definition).map((key) => [key, definition[key]]) : [];
1207
+ }
1208
+ var OutletObserver = class {
1209
+ constructor(context, delegate) {
1210
+ this.started = false;
1211
+ this.context = context;
1212
+ this.delegate = delegate;
1213
+ this.outletsByName = new Multimap();
1214
+ this.outletElementsByName = new Multimap();
1215
+ this.selectorObserverMap = /* @__PURE__ */ new Map();
1216
+ this.attributeObserverMap = /* @__PURE__ */ new Map();
1217
+ }
1218
+ start() {
1219
+ if (!this.started) {
1220
+ this.outletDefinitions.forEach((outletName) => {
1221
+ this.setupSelectorObserverForOutlet(outletName);
1222
+ this.setupAttributeObserverForOutlet(outletName);
1223
+ });
1224
+ this.started = true;
1225
+ this.dependentContexts.forEach((context) => context.refresh());
1226
+ }
1227
+ }
1228
+ refresh() {
1229
+ this.selectorObserverMap.forEach((observer) => observer.refresh());
1230
+ this.attributeObserverMap.forEach((observer) => observer.refresh());
1231
+ }
1232
+ stop() {
1233
+ if (this.started) {
1234
+ this.started = false;
1235
+ this.disconnectAllOutlets();
1236
+ this.stopSelectorObservers();
1237
+ this.stopAttributeObservers();
1238
+ }
1239
+ }
1240
+ stopSelectorObservers() {
1241
+ if (this.selectorObserverMap.size > 0) {
1242
+ this.selectorObserverMap.forEach((observer) => observer.stop());
1243
+ this.selectorObserverMap.clear();
1244
+ }
1245
+ }
1246
+ stopAttributeObservers() {
1247
+ if (this.attributeObserverMap.size > 0) {
1248
+ this.attributeObserverMap.forEach((observer) => observer.stop());
1249
+ this.attributeObserverMap.clear();
1250
+ }
1251
+ }
1252
+ selectorMatched(element, _selector, { outletName }) {
1253
+ const outlet = this.getOutlet(element, outletName);
1254
+ if (outlet) {
1255
+ this.connectOutlet(outlet, element, outletName);
1256
+ }
1257
+ }
1258
+ selectorUnmatched(element, _selector, { outletName }) {
1259
+ const outlet = this.getOutletFromMap(element, outletName);
1260
+ if (outlet) {
1261
+ this.disconnectOutlet(outlet, element, outletName);
1262
+ }
1263
+ }
1264
+ selectorMatchElement(element, { outletName }) {
1265
+ const selector = this.selector(outletName);
1266
+ const hasOutlet = this.hasOutlet(element, outletName);
1267
+ const hasOutletController = element.matches(`[${this.schema.controllerAttribute}~=${outletName}]`);
1268
+ if (selector) {
1269
+ return hasOutlet && hasOutletController && element.matches(selector);
1270
+ } else {
1271
+ return false;
1272
+ }
1273
+ }
1274
+ elementMatchedAttribute(_element, attributeName) {
1275
+ const outletName = this.getOutletNameFromOutletAttributeName(attributeName);
1276
+ if (outletName) {
1277
+ this.updateSelectorObserverForOutlet(outletName);
1278
+ }
1279
+ }
1280
+ elementAttributeValueChanged(_element, attributeName) {
1281
+ const outletName = this.getOutletNameFromOutletAttributeName(attributeName);
1282
+ if (outletName) {
1283
+ this.updateSelectorObserverForOutlet(outletName);
1284
+ }
1285
+ }
1286
+ elementUnmatchedAttribute(_element, attributeName) {
1287
+ const outletName = this.getOutletNameFromOutletAttributeName(attributeName);
1288
+ if (outletName) {
1289
+ this.updateSelectorObserverForOutlet(outletName);
1290
+ }
1291
+ }
1292
+ connectOutlet(outlet, element, outletName) {
1293
+ var _a;
1294
+ if (!this.outletElementsByName.has(outletName, element)) {
1295
+ this.outletsByName.add(outletName, outlet);
1296
+ this.outletElementsByName.add(outletName, element);
1297
+ (_a = this.selectorObserverMap.get(outletName)) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.outletConnected(outlet, element, outletName));
1298
+ }
1299
+ }
1300
+ disconnectOutlet(outlet, element, outletName) {
1301
+ var _a;
1302
+ if (this.outletElementsByName.has(outletName, element)) {
1303
+ this.outletsByName.delete(outletName, outlet);
1304
+ this.outletElementsByName.delete(outletName, element);
1305
+ (_a = this.selectorObserverMap.get(outletName)) === null || _a === void 0 ? void 0 : _a.pause(() => this.delegate.outletDisconnected(outlet, element, outletName));
1306
+ }
1307
+ }
1308
+ disconnectAllOutlets() {
1309
+ for (const outletName of this.outletElementsByName.keys) {
1310
+ for (const element of this.outletElementsByName.getValuesForKey(outletName)) {
1311
+ for (const outlet of this.outletsByName.getValuesForKey(outletName)) {
1312
+ this.disconnectOutlet(outlet, element, outletName);
1313
+ }
1314
+ }
1315
+ }
1316
+ }
1317
+ updateSelectorObserverForOutlet(outletName) {
1318
+ const observer = this.selectorObserverMap.get(outletName);
1319
+ if (observer) {
1320
+ observer.selector = this.selector(outletName);
1321
+ }
1322
+ }
1323
+ setupSelectorObserverForOutlet(outletName) {
1324
+ const selector = this.selector(outletName);
1325
+ const selectorObserver = new SelectorObserver(document.body, selector, this, { outletName });
1326
+ this.selectorObserverMap.set(outletName, selectorObserver);
1327
+ selectorObserver.start();
1328
+ }
1329
+ setupAttributeObserverForOutlet(outletName) {
1330
+ const attributeName = this.attributeNameForOutletName(outletName);
1331
+ const attributeObserver = new AttributeObserver(this.scope.element, attributeName, this);
1332
+ this.attributeObserverMap.set(outletName, attributeObserver);
1333
+ attributeObserver.start();
1334
+ }
1335
+ selector(outletName) {
1336
+ return this.scope.outlets.getSelectorForOutletName(outletName);
1337
+ }
1338
+ attributeNameForOutletName(outletName) {
1339
+ return this.scope.schema.outletAttributeForScope(this.identifier, outletName);
1340
+ }
1341
+ getOutletNameFromOutletAttributeName(attributeName) {
1342
+ return this.outletDefinitions.find((outletName) => this.attributeNameForOutletName(outletName) === attributeName);
1343
+ }
1344
+ get outletDependencies() {
1345
+ const dependencies = new Multimap();
1346
+ this.router.modules.forEach((module) => {
1347
+ const constructor = module.definition.controllerConstructor;
1348
+ const outlets = readInheritableStaticArrayValues(constructor, "outlets");
1349
+ outlets.forEach((outlet) => dependencies.add(outlet, module.identifier));
1350
+ });
1351
+ return dependencies;
1352
+ }
1353
+ get outletDefinitions() {
1354
+ return this.outletDependencies.getKeysForValue(this.identifier);
1355
+ }
1356
+ get dependentControllerIdentifiers() {
1357
+ return this.outletDependencies.getValuesForKey(this.identifier);
1358
+ }
1359
+ get dependentContexts() {
1360
+ const identifiers = this.dependentControllerIdentifiers;
1361
+ return this.router.contexts.filter((context) => identifiers.includes(context.identifier));
1362
+ }
1363
+ hasOutlet(element, outletName) {
1364
+ return !!this.getOutlet(element, outletName) || !!this.getOutletFromMap(element, outletName);
1365
+ }
1366
+ getOutlet(element, outletName) {
1367
+ return this.application.getControllerForElementAndIdentifier(element, outletName);
1368
+ }
1369
+ getOutletFromMap(element, outletName) {
1370
+ return this.outletsByName.getValuesForKey(outletName).find((outlet) => outlet.element === element);
1371
+ }
1372
+ get scope() {
1373
+ return this.context.scope;
1374
+ }
1375
+ get schema() {
1376
+ return this.context.schema;
1377
+ }
1378
+ get identifier() {
1379
+ return this.context.identifier;
1380
+ }
1381
+ get application() {
1382
+ return this.context.application;
1383
+ }
1384
+ get router() {
1385
+ return this.application.router;
1386
+ }
1387
+ };
1388
+ var Context = class {
1389
+ constructor(module, scope) {
1390
+ this.logDebugActivity = (functionName, detail = {}) => {
1391
+ const { identifier, controller, element } = this;
1392
+ detail = Object.assign({ identifier, controller, element }, detail);
1393
+ this.application.logDebugActivity(this.identifier, functionName, detail);
1394
+ };
1395
+ this.module = module;
1396
+ this.scope = scope;
1397
+ this.controller = new module.controllerConstructor(this);
1398
+ this.bindingObserver = new BindingObserver(this, this.dispatcher);
1399
+ this.valueObserver = new ValueObserver(this, this.controller);
1400
+ this.targetObserver = new TargetObserver(this, this);
1401
+ this.outletObserver = new OutletObserver(this, this);
1402
+ try {
1403
+ this.controller.initialize();
1404
+ this.logDebugActivity("initialize");
1405
+ } catch (error2) {
1406
+ this.handleError(error2, "initializing controller");
1407
+ }
1408
+ }
1409
+ connect() {
1410
+ this.bindingObserver.start();
1411
+ this.valueObserver.start();
1412
+ this.targetObserver.start();
1413
+ this.outletObserver.start();
1414
+ try {
1415
+ this.controller.connect();
1416
+ this.logDebugActivity("connect");
1417
+ } catch (error2) {
1418
+ this.handleError(error2, "connecting controller");
1419
+ }
1420
+ }
1421
+ refresh() {
1422
+ this.outletObserver.refresh();
1423
+ }
1424
+ disconnect() {
1425
+ try {
1426
+ this.controller.disconnect();
1427
+ this.logDebugActivity("disconnect");
1428
+ } catch (error2) {
1429
+ this.handleError(error2, "disconnecting controller");
1430
+ }
1431
+ this.outletObserver.stop();
1432
+ this.targetObserver.stop();
1433
+ this.valueObserver.stop();
1434
+ this.bindingObserver.stop();
1435
+ }
1436
+ get application() {
1437
+ return this.module.application;
1438
+ }
1439
+ get identifier() {
1440
+ return this.module.identifier;
1441
+ }
1442
+ get schema() {
1443
+ return this.application.schema;
1444
+ }
1445
+ get dispatcher() {
1446
+ return this.application.dispatcher;
1447
+ }
1448
+ get element() {
1449
+ return this.scope.element;
1450
+ }
1451
+ get parentElement() {
1452
+ return this.element.parentElement;
1453
+ }
1454
+ handleError(error2, message, detail = {}) {
1455
+ const { identifier, controller, element } = this;
1456
+ detail = Object.assign({ identifier, controller, element }, detail);
1457
+ this.application.handleError(error2, `Error ${message}`, detail);
1458
+ }
1459
+ targetConnected(element, name) {
1460
+ this.invokeControllerMethod(`${name}TargetConnected`, element);
1461
+ }
1462
+ targetDisconnected(element, name) {
1463
+ this.invokeControllerMethod(`${name}TargetDisconnected`, element);
1464
+ }
1465
+ outletConnected(outlet, element, name) {
1466
+ this.invokeControllerMethod(`${namespaceCamelize(name)}OutletConnected`, outlet, element);
1467
+ }
1468
+ outletDisconnected(outlet, element, name) {
1469
+ this.invokeControllerMethod(`${namespaceCamelize(name)}OutletDisconnected`, outlet, element);
1470
+ }
1471
+ invokeControllerMethod(methodName, ...args) {
1472
+ const controller = this.controller;
1473
+ if (typeof controller[methodName] == "function") {
1474
+ controller[methodName](...args);
1475
+ }
1476
+ }
1477
+ };
1478
+ function bless(constructor) {
1479
+ return shadow(constructor, getBlessedProperties(constructor));
1480
+ }
1481
+ function shadow(constructor, properties) {
1482
+ const shadowConstructor = extend(constructor);
1483
+ const shadowProperties = getShadowProperties(constructor.prototype, properties);
1484
+ Object.defineProperties(shadowConstructor.prototype, shadowProperties);
1485
+ return shadowConstructor;
1486
+ }
1487
+ function getBlessedProperties(constructor) {
1488
+ const blessings = readInheritableStaticArrayValues(constructor, "blessings");
1489
+ return blessings.reduce((blessedProperties, blessing) => {
1490
+ const properties = blessing(constructor);
1491
+ for (const key in properties) {
1492
+ const descriptor = blessedProperties[key] || {};
1493
+ blessedProperties[key] = Object.assign(descriptor, properties[key]);
1494
+ }
1495
+ return blessedProperties;
1496
+ }, {});
1497
+ }
1498
+ function getShadowProperties(prototype, properties) {
1499
+ return getOwnKeys(properties).reduce((shadowProperties, key) => {
1500
+ const descriptor = getShadowedDescriptor(prototype, properties, key);
1501
+ if (descriptor) {
1502
+ Object.assign(shadowProperties, { [key]: descriptor });
1503
+ }
1504
+ return shadowProperties;
1505
+ }, {});
1506
+ }
1507
+ function getShadowedDescriptor(prototype, properties, key) {
1508
+ const shadowingDescriptor = Object.getOwnPropertyDescriptor(prototype, key);
1509
+ const shadowedByValue = shadowingDescriptor && "value" in shadowingDescriptor;
1510
+ if (!shadowedByValue) {
1511
+ const descriptor = Object.getOwnPropertyDescriptor(properties, key).value;
1512
+ if (shadowingDescriptor) {
1513
+ descriptor.get = shadowingDescriptor.get || descriptor.get;
1514
+ descriptor.set = shadowingDescriptor.set || descriptor.set;
1515
+ }
1516
+ return descriptor;
1517
+ }
1518
+ }
1519
+ var getOwnKeys = (() => {
1520
+ if (typeof Object.getOwnPropertySymbols == "function") {
1521
+ return (object) => [...Object.getOwnPropertyNames(object), ...Object.getOwnPropertySymbols(object)];
1522
+ } else {
1523
+ return Object.getOwnPropertyNames;
1524
+ }
1525
+ })();
1526
+ var extend = (() => {
1527
+ function extendWithReflect(constructor) {
1528
+ function extended() {
1529
+ return Reflect.construct(constructor, arguments, new.target);
1530
+ }
1531
+ extended.prototype = Object.create(constructor.prototype, {
1532
+ constructor: { value: extended }
1533
+ });
1534
+ Reflect.setPrototypeOf(extended, constructor);
1535
+ return extended;
1536
+ }
1537
+ function testReflectExtension() {
1538
+ const a = function() {
1539
+ this.a.call(this);
1540
+ };
1541
+ const b = extendWithReflect(a);
1542
+ b.prototype.a = function() {
1543
+ };
1544
+ return new b();
1545
+ }
1546
+ try {
1547
+ testReflectExtension();
1548
+ return extendWithReflect;
1549
+ } catch (error2) {
1550
+ return (constructor) => class extended extends constructor {
1551
+ };
1552
+ }
1553
+ })();
1554
+ function blessDefinition(definition) {
1555
+ return {
1556
+ identifier: definition.identifier,
1557
+ controllerConstructor: bless(definition.controllerConstructor)
1558
+ };
1559
+ }
1560
+ var Module = class {
1561
+ constructor(application2, definition) {
1562
+ this.application = application2;
1563
+ this.definition = blessDefinition(definition);
1564
+ this.contextsByScope = /* @__PURE__ */ new WeakMap();
1565
+ this.connectedContexts = /* @__PURE__ */ new Set();
1566
+ }
1567
+ get identifier() {
1568
+ return this.definition.identifier;
1569
+ }
1570
+ get controllerConstructor() {
1571
+ return this.definition.controllerConstructor;
1572
+ }
1573
+ get contexts() {
1574
+ return Array.from(this.connectedContexts);
1575
+ }
1576
+ connectContextForScope(scope) {
1577
+ const context = this.fetchContextForScope(scope);
1578
+ this.connectedContexts.add(context);
1579
+ context.connect();
1580
+ }
1581
+ disconnectContextForScope(scope) {
1582
+ const context = this.contextsByScope.get(scope);
1583
+ if (context) {
1584
+ this.connectedContexts.delete(context);
1585
+ context.disconnect();
1586
+ }
1587
+ }
1588
+ fetchContextForScope(scope) {
1589
+ let context = this.contextsByScope.get(scope);
1590
+ if (!context) {
1591
+ context = new Context(this, scope);
1592
+ this.contextsByScope.set(scope, context);
1593
+ }
1594
+ return context;
1595
+ }
1596
+ };
1597
+ var ClassMap = class {
1598
+ constructor(scope) {
1599
+ this.scope = scope;
1600
+ }
1601
+ has(name) {
1602
+ return this.data.has(this.getDataKey(name));
1603
+ }
1604
+ get(name) {
1605
+ return this.getAll(name)[0];
1606
+ }
1607
+ getAll(name) {
1608
+ const tokenString = this.data.get(this.getDataKey(name)) || "";
1609
+ return tokenize(tokenString);
1610
+ }
1611
+ getAttributeName(name) {
1612
+ return this.data.getAttributeNameForKey(this.getDataKey(name));
1613
+ }
1614
+ getDataKey(name) {
1615
+ return `${name}-class`;
1616
+ }
1617
+ get data() {
1618
+ return this.scope.data;
1619
+ }
1620
+ };
1621
+ var DataMap = class {
1622
+ constructor(scope) {
1623
+ this.scope = scope;
1624
+ }
1625
+ get element() {
1626
+ return this.scope.element;
1627
+ }
1628
+ get identifier() {
1629
+ return this.scope.identifier;
1630
+ }
1631
+ get(key) {
1632
+ const name = this.getAttributeNameForKey(key);
1633
+ return this.element.getAttribute(name);
1634
+ }
1635
+ set(key, value) {
1636
+ const name = this.getAttributeNameForKey(key);
1637
+ this.element.setAttribute(name, value);
1638
+ return this.get(key);
1639
+ }
1640
+ has(key) {
1641
+ const name = this.getAttributeNameForKey(key);
1642
+ return this.element.hasAttribute(name);
1643
+ }
1644
+ delete(key) {
1645
+ if (this.has(key)) {
1646
+ const name = this.getAttributeNameForKey(key);
1647
+ this.element.removeAttribute(name);
1648
+ return true;
1649
+ } else {
1650
+ return false;
1651
+ }
1652
+ }
1653
+ getAttributeNameForKey(key) {
1654
+ return `data-${this.identifier}-${dasherize(key)}`;
1655
+ }
1656
+ };
1657
+ var Guide = class {
1658
+ constructor(logger) {
1659
+ this.warnedKeysByObject = /* @__PURE__ */ new WeakMap();
1660
+ this.logger = logger;
1661
+ }
1662
+ warn(object, key, message) {
1663
+ let warnedKeys = this.warnedKeysByObject.get(object);
1664
+ if (!warnedKeys) {
1665
+ warnedKeys = /* @__PURE__ */ new Set();
1666
+ this.warnedKeysByObject.set(object, warnedKeys);
1667
+ }
1668
+ if (!warnedKeys.has(key)) {
1669
+ warnedKeys.add(key);
1670
+ this.logger.warn(message, object);
1671
+ }
1672
+ }
1673
+ };
1674
+ function attributeValueContainsToken(attributeName, token) {
1675
+ return `[${attributeName}~="${token}"]`;
1676
+ }
1677
+ var TargetSet = class {
1678
+ constructor(scope) {
1679
+ this.scope = scope;
1680
+ }
1681
+ get element() {
1682
+ return this.scope.element;
1683
+ }
1684
+ get identifier() {
1685
+ return this.scope.identifier;
1686
+ }
1687
+ get schema() {
1688
+ return this.scope.schema;
1689
+ }
1690
+ has(targetName) {
1691
+ return this.find(targetName) != null;
1692
+ }
1693
+ find(...targetNames) {
1694
+ return targetNames.reduce((target, targetName) => target || this.findTarget(targetName) || this.findLegacyTarget(targetName), void 0);
1695
+ }
1696
+ findAll(...targetNames) {
1697
+ return targetNames.reduce((targets, targetName) => [
1698
+ ...targets,
1699
+ ...this.findAllTargets(targetName),
1700
+ ...this.findAllLegacyTargets(targetName)
1701
+ ], []);
1702
+ }
1703
+ findTarget(targetName) {
1704
+ const selector = this.getSelectorForTargetName(targetName);
1705
+ return this.scope.findElement(selector);
1706
+ }
1707
+ findAllTargets(targetName) {
1708
+ const selector = this.getSelectorForTargetName(targetName);
1709
+ return this.scope.findAllElements(selector);
1710
+ }
1711
+ getSelectorForTargetName(targetName) {
1712
+ const attributeName = this.schema.targetAttributeForScope(this.identifier);
1713
+ return attributeValueContainsToken(attributeName, targetName);
1714
+ }
1715
+ findLegacyTarget(targetName) {
1716
+ const selector = this.getLegacySelectorForTargetName(targetName);
1717
+ return this.deprecate(this.scope.findElement(selector), targetName);
1718
+ }
1719
+ findAllLegacyTargets(targetName) {
1720
+ const selector = this.getLegacySelectorForTargetName(targetName);
1721
+ return this.scope.findAllElements(selector).map((element) => this.deprecate(element, targetName));
1722
+ }
1723
+ getLegacySelectorForTargetName(targetName) {
1724
+ const targetDescriptor = `${this.identifier}.${targetName}`;
1725
+ return attributeValueContainsToken(this.schema.targetAttribute, targetDescriptor);
1726
+ }
1727
+ deprecate(element, targetName) {
1728
+ if (element) {
1729
+ const { identifier } = this;
1730
+ const attributeName = this.schema.targetAttribute;
1731
+ const revisedAttributeName = this.schema.targetAttributeForScope(identifier);
1732
+ this.guide.warn(element, `target:${targetName}`, `Please replace ${attributeName}="${identifier}.${targetName}" with ${revisedAttributeName}="${targetName}". The ${attributeName} attribute is deprecated and will be removed in a future version of Stimulus.`);
1733
+ }
1734
+ return element;
1735
+ }
1736
+ get guide() {
1737
+ return this.scope.guide;
1738
+ }
1739
+ };
1740
+ var OutletSet = class {
1741
+ constructor(scope, controllerElement) {
1742
+ this.scope = scope;
1743
+ this.controllerElement = controllerElement;
1744
+ }
1745
+ get element() {
1746
+ return this.scope.element;
1747
+ }
1748
+ get identifier() {
1749
+ return this.scope.identifier;
1750
+ }
1751
+ get schema() {
1752
+ return this.scope.schema;
1753
+ }
1754
+ has(outletName) {
1755
+ return this.find(outletName) != null;
1756
+ }
1757
+ find(...outletNames) {
1758
+ return outletNames.reduce((outlet, outletName) => outlet || this.findOutlet(outletName), void 0);
1759
+ }
1760
+ findAll(...outletNames) {
1761
+ return outletNames.reduce((outlets, outletName) => [...outlets, ...this.findAllOutlets(outletName)], []);
1762
+ }
1763
+ getSelectorForOutletName(outletName) {
1764
+ const attributeName = this.schema.outletAttributeForScope(this.identifier, outletName);
1765
+ return this.controllerElement.getAttribute(attributeName);
1766
+ }
1767
+ findOutlet(outletName) {
1768
+ const selector = this.getSelectorForOutletName(outletName);
1769
+ if (selector)
1770
+ return this.findElement(selector, outletName);
1771
+ }
1772
+ findAllOutlets(outletName) {
1773
+ const selector = this.getSelectorForOutletName(outletName);
1774
+ return selector ? this.findAllElements(selector, outletName) : [];
1775
+ }
1776
+ findElement(selector, outletName) {
1777
+ const elements = this.scope.queryElements(selector);
1778
+ return elements.filter((element) => this.matchesElement(element, selector, outletName))[0];
1779
+ }
1780
+ findAllElements(selector, outletName) {
1781
+ const elements = this.scope.queryElements(selector);
1782
+ return elements.filter((element) => this.matchesElement(element, selector, outletName));
1783
+ }
1784
+ matchesElement(element, selector, outletName) {
1785
+ const controllerAttribute = element.getAttribute(this.scope.schema.controllerAttribute) || "";
1786
+ return element.matches(selector) && controllerAttribute.split(" ").includes(outletName);
1787
+ }
1788
+ };
1789
+ var Scope = class _Scope {
1790
+ constructor(schema, element, identifier, logger) {
1791
+ this.targets = new TargetSet(this);
1792
+ this.classes = new ClassMap(this);
1793
+ this.data = new DataMap(this);
1794
+ this.containsElement = (element2) => {
1795
+ return element2.closest(this.controllerSelector) === this.element;
1796
+ };
1797
+ this.schema = schema;
1798
+ this.element = element;
1799
+ this.identifier = identifier;
1800
+ this.guide = new Guide(logger);
1801
+ this.outlets = new OutletSet(this.documentScope, element);
1802
+ }
1803
+ findElement(selector) {
1804
+ return this.element.matches(selector) ? this.element : this.queryElements(selector).find(this.containsElement);
1805
+ }
1806
+ findAllElements(selector) {
1807
+ return [
1808
+ ...this.element.matches(selector) ? [this.element] : [],
1809
+ ...this.queryElements(selector).filter(this.containsElement)
1810
+ ];
1811
+ }
1812
+ queryElements(selector) {
1813
+ return Array.from(this.element.querySelectorAll(selector));
1814
+ }
1815
+ get controllerSelector() {
1816
+ return attributeValueContainsToken(this.schema.controllerAttribute, this.identifier);
1817
+ }
1818
+ get isDocumentScope() {
1819
+ return this.element === document.documentElement;
1820
+ }
1821
+ get documentScope() {
1822
+ return this.isDocumentScope ? this : new _Scope(this.schema, document.documentElement, this.identifier, this.guide.logger);
1823
+ }
1824
+ };
1825
+ var ScopeObserver = class {
1826
+ constructor(element, schema, delegate) {
1827
+ this.element = element;
1828
+ this.schema = schema;
1829
+ this.delegate = delegate;
1830
+ this.valueListObserver = new ValueListObserver(this.element, this.controllerAttribute, this);
1831
+ this.scopesByIdentifierByElement = /* @__PURE__ */ new WeakMap();
1832
+ this.scopeReferenceCounts = /* @__PURE__ */ new WeakMap();
1833
+ }
1834
+ start() {
1835
+ this.valueListObserver.start();
1836
+ }
1837
+ stop() {
1838
+ this.valueListObserver.stop();
1839
+ }
1840
+ get controllerAttribute() {
1841
+ return this.schema.controllerAttribute;
1842
+ }
1843
+ parseValueForToken(token) {
1844
+ const { element, content: identifier } = token;
1845
+ return this.parseValueForElementAndIdentifier(element, identifier);
1846
+ }
1847
+ parseValueForElementAndIdentifier(element, identifier) {
1848
+ const scopesByIdentifier = this.fetchScopesByIdentifierForElement(element);
1849
+ let scope = scopesByIdentifier.get(identifier);
1850
+ if (!scope) {
1851
+ scope = this.delegate.createScopeForElementAndIdentifier(element, identifier);
1852
+ scopesByIdentifier.set(identifier, scope);
1853
+ }
1854
+ return scope;
1855
+ }
1856
+ elementMatchedValue(element, value) {
1857
+ const referenceCount = (this.scopeReferenceCounts.get(value) || 0) + 1;
1858
+ this.scopeReferenceCounts.set(value, referenceCount);
1859
+ if (referenceCount == 1) {
1860
+ this.delegate.scopeConnected(value);
1861
+ }
1862
+ }
1863
+ elementUnmatchedValue(element, value) {
1864
+ const referenceCount = this.scopeReferenceCounts.get(value);
1865
+ if (referenceCount) {
1866
+ this.scopeReferenceCounts.set(value, referenceCount - 1);
1867
+ if (referenceCount == 1) {
1868
+ this.delegate.scopeDisconnected(value);
1869
+ }
1870
+ }
1871
+ }
1872
+ fetchScopesByIdentifierForElement(element) {
1873
+ let scopesByIdentifier = this.scopesByIdentifierByElement.get(element);
1874
+ if (!scopesByIdentifier) {
1875
+ scopesByIdentifier = /* @__PURE__ */ new Map();
1876
+ this.scopesByIdentifierByElement.set(element, scopesByIdentifier);
1877
+ }
1878
+ return scopesByIdentifier;
1879
+ }
1880
+ };
1881
+ var Router = class {
1882
+ constructor(application2) {
1883
+ this.application = application2;
1884
+ this.scopeObserver = new ScopeObserver(this.element, this.schema, this);
1885
+ this.scopesByIdentifier = new Multimap();
1886
+ this.modulesByIdentifier = /* @__PURE__ */ new Map();
1887
+ }
1888
+ get element() {
1889
+ return this.application.element;
1890
+ }
1891
+ get schema() {
1892
+ return this.application.schema;
1893
+ }
1894
+ get logger() {
1895
+ return this.application.logger;
1896
+ }
1897
+ get controllerAttribute() {
1898
+ return this.schema.controllerAttribute;
1899
+ }
1900
+ get modules() {
1901
+ return Array.from(this.modulesByIdentifier.values());
1902
+ }
1903
+ get contexts() {
1904
+ return this.modules.reduce((contexts, module) => contexts.concat(module.contexts), []);
1905
+ }
1906
+ start() {
1907
+ this.scopeObserver.start();
1908
+ }
1909
+ stop() {
1910
+ this.scopeObserver.stop();
1911
+ }
1912
+ loadDefinition(definition) {
1913
+ this.unloadIdentifier(definition.identifier);
1914
+ const module = new Module(this.application, definition);
1915
+ this.connectModule(module);
1916
+ const afterLoad = definition.controllerConstructor.afterLoad;
1917
+ if (afterLoad) {
1918
+ afterLoad.call(definition.controllerConstructor, definition.identifier, this.application);
1919
+ }
1920
+ }
1921
+ unloadIdentifier(identifier) {
1922
+ const module = this.modulesByIdentifier.get(identifier);
1923
+ if (module) {
1924
+ this.disconnectModule(module);
1925
+ }
1926
+ }
1927
+ getContextForElementAndIdentifier(element, identifier) {
1928
+ const module = this.modulesByIdentifier.get(identifier);
1929
+ if (module) {
1930
+ return module.contexts.find((context) => context.element == element);
1931
+ }
1932
+ }
1933
+ proposeToConnectScopeForElementAndIdentifier(element, identifier) {
1934
+ const scope = this.scopeObserver.parseValueForElementAndIdentifier(element, identifier);
1935
+ if (scope) {
1936
+ this.scopeObserver.elementMatchedValue(scope.element, scope);
1937
+ } else {
1938
+ console.error(`Couldn't find or create scope for identifier: "${identifier}" and element:`, element);
1939
+ }
1940
+ }
1941
+ handleError(error2, message, detail) {
1942
+ this.application.handleError(error2, message, detail);
1943
+ }
1944
+ createScopeForElementAndIdentifier(element, identifier) {
1945
+ return new Scope(this.schema, element, identifier, this.logger);
1946
+ }
1947
+ scopeConnected(scope) {
1948
+ this.scopesByIdentifier.add(scope.identifier, scope);
1949
+ const module = this.modulesByIdentifier.get(scope.identifier);
1950
+ if (module) {
1951
+ module.connectContextForScope(scope);
1952
+ }
1953
+ }
1954
+ scopeDisconnected(scope) {
1955
+ this.scopesByIdentifier.delete(scope.identifier, scope);
1956
+ const module = this.modulesByIdentifier.get(scope.identifier);
1957
+ if (module) {
1958
+ module.disconnectContextForScope(scope);
1959
+ }
1960
+ }
1961
+ connectModule(module) {
1962
+ this.modulesByIdentifier.set(module.identifier, module);
1963
+ const scopes = this.scopesByIdentifier.getValuesForKey(module.identifier);
1964
+ scopes.forEach((scope) => module.connectContextForScope(scope));
1965
+ }
1966
+ disconnectModule(module) {
1967
+ this.modulesByIdentifier.delete(module.identifier);
1968
+ const scopes = this.scopesByIdentifier.getValuesForKey(module.identifier);
1969
+ scopes.forEach((scope) => module.disconnectContextForScope(scope));
1970
+ }
1971
+ };
1972
+ var defaultSchema = {
1973
+ controllerAttribute: "data-controller",
1974
+ actionAttribute: "data-action",
1975
+ targetAttribute: "data-target",
1976
+ targetAttributeForScope: (identifier) => `data-${identifier}-target`,
1977
+ outletAttributeForScope: (identifier, outlet) => `data-${identifier}-${outlet}-outlet`,
1978
+ keyMappings: Object.assign(Object.assign({ enter: "Enter", tab: "Tab", esc: "Escape", space: " ", up: "ArrowUp", down: "ArrowDown", left: "ArrowLeft", right: "ArrowRight", home: "Home", end: "End", page_up: "PageUp", page_down: "PageDown" }, objectFromEntries("abcdefghijklmnopqrstuvwxyz".split("").map((c) => [c, c]))), objectFromEntries("0123456789".split("").map((n) => [n, n])))
1979
+ };
1980
+ function objectFromEntries(array) {
1981
+ return array.reduce((memo, [k, v]) => Object.assign(Object.assign({}, memo), { [k]: v }), {});
1982
+ }
1983
+ var Application = class {
1984
+ constructor(element = document.documentElement, schema = defaultSchema) {
1985
+ this.logger = console;
1986
+ this.debug = false;
1987
+ this.logDebugActivity = (identifier, functionName, detail = {}) => {
1988
+ if (this.debug) {
1989
+ this.logFormattedMessage(identifier, functionName, detail);
1990
+ }
1991
+ };
1992
+ this.element = element;
1993
+ this.schema = schema;
1994
+ this.dispatcher = new Dispatcher(this);
1995
+ this.router = new Router(this);
1996
+ this.actionDescriptorFilters = Object.assign({}, defaultActionDescriptorFilters);
1997
+ }
1998
+ static start(element, schema) {
1999
+ const application2 = new this(element, schema);
2000
+ application2.start();
2001
+ return application2;
2002
+ }
2003
+ async start() {
2004
+ await domReady();
2005
+ this.logDebugActivity("application", "starting");
2006
+ this.dispatcher.start();
2007
+ this.router.start();
2008
+ this.logDebugActivity("application", "start");
2009
+ }
2010
+ stop() {
2011
+ this.logDebugActivity("application", "stopping");
2012
+ this.dispatcher.stop();
2013
+ this.router.stop();
2014
+ this.logDebugActivity("application", "stop");
2015
+ }
2016
+ register(identifier, controllerConstructor) {
2017
+ this.load({ identifier, controllerConstructor });
2018
+ }
2019
+ registerActionOption(name, filter) {
2020
+ this.actionDescriptorFilters[name] = filter;
2021
+ }
2022
+ load(head, ...rest) {
2023
+ const definitions = Array.isArray(head) ? head : [head, ...rest];
2024
+ definitions.forEach((definition) => {
2025
+ if (definition.controllerConstructor.shouldLoad) {
2026
+ this.router.loadDefinition(definition);
2027
+ }
2028
+ });
2029
+ }
2030
+ unload(head, ...rest) {
2031
+ const identifiers = Array.isArray(head) ? head : [head, ...rest];
2032
+ identifiers.forEach((identifier) => this.router.unloadIdentifier(identifier));
2033
+ }
2034
+ get controllers() {
2035
+ return this.router.contexts.map((context) => context.controller);
2036
+ }
2037
+ getControllerForElementAndIdentifier(element, identifier) {
2038
+ const context = this.router.getContextForElementAndIdentifier(element, identifier);
2039
+ return context ? context.controller : null;
2040
+ }
2041
+ handleError(error2, message, detail) {
2042
+ var _a;
2043
+ this.logger.error(`%s
2044
+
2045
+ %o
2046
+
2047
+ %o`, message, error2, detail);
2048
+ (_a = window.onerror) === null || _a === void 0 ? void 0 : _a.call(window, message, "", 0, 0, error2);
2049
+ }
2050
+ logFormattedMessage(identifier, functionName, detail = {}) {
2051
+ detail = Object.assign({ application: this }, detail);
2052
+ this.logger.groupCollapsed(`${identifier} #${functionName}`);
2053
+ this.logger.log("details:", Object.assign({}, detail));
2054
+ this.logger.groupEnd();
2055
+ }
2056
+ };
2057
+ function domReady() {
2058
+ return new Promise((resolve) => {
2059
+ if (document.readyState == "loading") {
2060
+ document.addEventListener("DOMContentLoaded", () => resolve());
2061
+ } else {
2062
+ resolve();
2063
+ }
2064
+ });
2065
+ }
2066
+ function ClassPropertiesBlessing(constructor) {
2067
+ const classes = readInheritableStaticArrayValues(constructor, "classes");
2068
+ return classes.reduce((properties, classDefinition) => {
2069
+ return Object.assign(properties, propertiesForClassDefinition(classDefinition));
2070
+ }, {});
2071
+ }
2072
+ function propertiesForClassDefinition(key) {
2073
+ return {
2074
+ [`${key}Class`]: {
2075
+ get() {
2076
+ const { classes } = this;
2077
+ if (classes.has(key)) {
2078
+ return classes.get(key);
2079
+ } else {
2080
+ const attribute = classes.getAttributeName(key);
2081
+ throw new Error(`Missing attribute "${attribute}"`);
2082
+ }
2083
+ }
2084
+ },
2085
+ [`${key}Classes`]: {
2086
+ get() {
2087
+ return this.classes.getAll(key);
2088
+ }
2089
+ },
2090
+ [`has${capitalize(key)}Class`]: {
2091
+ get() {
2092
+ return this.classes.has(key);
2093
+ }
2094
+ }
2095
+ };
2096
+ }
2097
+ function OutletPropertiesBlessing(constructor) {
2098
+ const outlets = readInheritableStaticArrayValues(constructor, "outlets");
2099
+ return outlets.reduce((properties, outletDefinition) => {
2100
+ return Object.assign(properties, propertiesForOutletDefinition(outletDefinition));
2101
+ }, {});
2102
+ }
2103
+ function getOutletController(controller, element, identifier) {
2104
+ return controller.application.getControllerForElementAndIdentifier(element, identifier);
2105
+ }
2106
+ function getControllerAndEnsureConnectedScope(controller, element, outletName) {
2107
+ let outletController = getOutletController(controller, element, outletName);
2108
+ if (outletController)
2109
+ return outletController;
2110
+ controller.application.router.proposeToConnectScopeForElementAndIdentifier(element, outletName);
2111
+ outletController = getOutletController(controller, element, outletName);
2112
+ if (outletController)
2113
+ return outletController;
2114
+ }
2115
+ function propertiesForOutletDefinition(name) {
2116
+ const camelizedName = namespaceCamelize(name);
2117
+ return {
2118
+ [`${camelizedName}Outlet`]: {
2119
+ get() {
2120
+ const outletElement = this.outlets.find(name);
2121
+ const selector = this.outlets.getSelectorForOutletName(name);
2122
+ if (outletElement) {
2123
+ const outletController = getControllerAndEnsureConnectedScope(this, outletElement, name);
2124
+ if (outletController)
2125
+ return outletController;
2126
+ throw new Error(`The provided outlet element is missing an outlet controller "${name}" instance for host controller "${this.identifier}"`);
2127
+ }
2128
+ throw new Error(`Missing outlet element "${name}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${selector}".`);
2129
+ }
2130
+ },
2131
+ [`${camelizedName}Outlets`]: {
2132
+ get() {
2133
+ const outlets = this.outlets.findAll(name);
2134
+ if (outlets.length > 0) {
2135
+ return outlets.map((outletElement) => {
2136
+ const outletController = getControllerAndEnsureConnectedScope(this, outletElement, name);
2137
+ if (outletController)
2138
+ return outletController;
2139
+ console.warn(`The provided outlet element is missing an outlet controller "${name}" instance for host controller "${this.identifier}"`, outletElement);
2140
+ }).filter((controller) => controller);
2141
+ }
2142
+ return [];
2143
+ }
2144
+ },
2145
+ [`${camelizedName}OutletElement`]: {
2146
+ get() {
2147
+ const outletElement = this.outlets.find(name);
2148
+ const selector = this.outlets.getSelectorForOutletName(name);
2149
+ if (outletElement) {
2150
+ return outletElement;
2151
+ } else {
2152
+ throw new Error(`Missing outlet element "${name}" for host controller "${this.identifier}". Stimulus couldn't find a matching outlet element using selector "${selector}".`);
2153
+ }
2154
+ }
2155
+ },
2156
+ [`${camelizedName}OutletElements`]: {
2157
+ get() {
2158
+ return this.outlets.findAll(name);
2159
+ }
2160
+ },
2161
+ [`has${capitalize(camelizedName)}Outlet`]: {
2162
+ get() {
2163
+ return this.outlets.has(name);
2164
+ }
2165
+ }
2166
+ };
2167
+ }
2168
+ function TargetPropertiesBlessing(constructor) {
2169
+ const targets = readInheritableStaticArrayValues(constructor, "targets");
2170
+ return targets.reduce((properties, targetDefinition) => {
2171
+ return Object.assign(properties, propertiesForTargetDefinition(targetDefinition));
2172
+ }, {});
2173
+ }
2174
+ function propertiesForTargetDefinition(name) {
2175
+ return {
2176
+ [`${name}Target`]: {
2177
+ get() {
2178
+ const target = this.targets.find(name);
2179
+ if (target) {
2180
+ return target;
2181
+ } else {
2182
+ throw new Error(`Missing target element "${name}" for "${this.identifier}" controller`);
2183
+ }
2184
+ }
2185
+ },
2186
+ [`${name}Targets`]: {
2187
+ get() {
2188
+ return this.targets.findAll(name);
2189
+ }
2190
+ },
2191
+ [`has${capitalize(name)}Target`]: {
2192
+ get() {
2193
+ return this.targets.has(name);
2194
+ }
2195
+ }
2196
+ };
2197
+ }
2198
+ function ValuePropertiesBlessing(constructor) {
2199
+ const valueDefinitionPairs = readInheritableStaticObjectPairs(constructor, "values");
2200
+ const propertyDescriptorMap = {
2201
+ valueDescriptorMap: {
2202
+ get() {
2203
+ return valueDefinitionPairs.reduce((result, valueDefinitionPair) => {
2204
+ const valueDescriptor = parseValueDefinitionPair(valueDefinitionPair, this.identifier);
2205
+ const attributeName = this.data.getAttributeNameForKey(valueDescriptor.key);
2206
+ return Object.assign(result, { [attributeName]: valueDescriptor });
2207
+ }, {});
2208
+ }
2209
+ }
2210
+ };
2211
+ return valueDefinitionPairs.reduce((properties, valueDefinitionPair) => {
2212
+ return Object.assign(properties, propertiesForValueDefinitionPair(valueDefinitionPair));
2213
+ }, propertyDescriptorMap);
2214
+ }
2215
+ function propertiesForValueDefinitionPair(valueDefinitionPair, controller) {
2216
+ const definition = parseValueDefinitionPair(valueDefinitionPair, controller);
2217
+ const { key, name, reader: read, writer: write } = definition;
2218
+ return {
2219
+ [name]: {
2220
+ get() {
2221
+ const value = this.data.get(key);
2222
+ if (value !== null) {
2223
+ return read(value);
2224
+ } else {
2225
+ return definition.defaultValue;
2226
+ }
2227
+ },
2228
+ set(value) {
2229
+ if (value === void 0) {
2230
+ this.data.delete(key);
2231
+ } else {
2232
+ this.data.set(key, write(value));
2233
+ }
2234
+ }
2235
+ },
2236
+ [`has${capitalize(name)}`]: {
2237
+ get() {
2238
+ return this.data.has(key) || definition.hasCustomDefaultValue;
2239
+ }
2240
+ }
2241
+ };
2242
+ }
2243
+ function parseValueDefinitionPair([token, typeDefinition], controller) {
2244
+ return valueDescriptorForTokenAndTypeDefinition({
2245
+ controller,
2246
+ token,
2247
+ typeDefinition
2248
+ });
2249
+ }
2250
+ function parseValueTypeConstant(constant) {
2251
+ switch (constant) {
2252
+ case Array:
2253
+ return "array";
2254
+ case Boolean:
2255
+ return "boolean";
2256
+ case Number:
2257
+ return "number";
2258
+ case Object:
2259
+ return "object";
2260
+ case String:
2261
+ return "string";
2262
+ }
2263
+ }
2264
+ function parseValueTypeDefault(defaultValue) {
2265
+ switch (typeof defaultValue) {
2266
+ case "boolean":
2267
+ return "boolean";
2268
+ case "number":
2269
+ return "number";
2270
+ case "string":
2271
+ return "string";
2272
+ }
2273
+ if (Array.isArray(defaultValue))
2274
+ return "array";
2275
+ if (Object.prototype.toString.call(defaultValue) === "[object Object]")
2276
+ return "object";
2277
+ }
2278
+ function parseValueTypeObject(payload) {
2279
+ const { controller, token, typeObject } = payload;
2280
+ const hasType = isSomething(typeObject.type);
2281
+ const hasDefault = isSomething(typeObject.default);
2282
+ const fullObject = hasType && hasDefault;
2283
+ const onlyType = hasType && !hasDefault;
2284
+ const onlyDefault = !hasType && hasDefault;
2285
+ const typeFromObject = parseValueTypeConstant(typeObject.type);
2286
+ const typeFromDefaultValue = parseValueTypeDefault(payload.typeObject.default);
2287
+ if (onlyType)
2288
+ return typeFromObject;
2289
+ if (onlyDefault)
2290
+ return typeFromDefaultValue;
2291
+ if (typeFromObject !== typeFromDefaultValue) {
2292
+ const propertyPath = controller ? `${controller}.${token}` : token;
2293
+ throw new Error(`The specified default value for the Stimulus Value "${propertyPath}" must match the defined type "${typeFromObject}". The provided default value of "${typeObject.default}" is of type "${typeFromDefaultValue}".`);
2294
+ }
2295
+ if (fullObject)
2296
+ return typeFromObject;
2297
+ }
2298
+ function parseValueTypeDefinition(payload) {
2299
+ const { controller, token, typeDefinition } = payload;
2300
+ const typeObject = { controller, token, typeObject: typeDefinition };
2301
+ const typeFromObject = parseValueTypeObject(typeObject);
2302
+ const typeFromDefaultValue = parseValueTypeDefault(typeDefinition);
2303
+ const typeFromConstant = parseValueTypeConstant(typeDefinition);
2304
+ const type = typeFromObject || typeFromDefaultValue || typeFromConstant;
2305
+ if (type)
2306
+ return type;
2307
+ const propertyPath = controller ? `${controller}.${typeDefinition}` : token;
2308
+ throw new Error(`Unknown value type "${propertyPath}" for "${token}" value`);
2309
+ }
2310
+ function defaultValueForDefinition(typeDefinition) {
2311
+ const constant = parseValueTypeConstant(typeDefinition);
2312
+ if (constant)
2313
+ return defaultValuesByType[constant];
2314
+ const hasDefault = hasProperty(typeDefinition, "default");
2315
+ const hasType = hasProperty(typeDefinition, "type");
2316
+ const typeObject = typeDefinition;
2317
+ if (hasDefault)
2318
+ return typeObject.default;
2319
+ if (hasType) {
2320
+ const { type } = typeObject;
2321
+ const constantFromType = parseValueTypeConstant(type);
2322
+ if (constantFromType)
2323
+ return defaultValuesByType[constantFromType];
2324
+ }
2325
+ return typeDefinition;
2326
+ }
2327
+ function valueDescriptorForTokenAndTypeDefinition(payload) {
2328
+ const { token, typeDefinition } = payload;
2329
+ const key = `${dasherize(token)}-value`;
2330
+ const type = parseValueTypeDefinition(payload);
2331
+ return {
2332
+ type,
2333
+ key,
2334
+ name: camelize(key),
2335
+ get defaultValue() {
2336
+ return defaultValueForDefinition(typeDefinition);
2337
+ },
2338
+ get hasCustomDefaultValue() {
2339
+ return parseValueTypeDefault(typeDefinition) !== void 0;
2340
+ },
2341
+ reader: readers[type],
2342
+ writer: writers[type] || writers.default
2343
+ };
2344
+ }
2345
+ var defaultValuesByType = {
2346
+ get array() {
2347
+ return [];
2348
+ },
2349
+ boolean: false,
2350
+ number: 0,
2351
+ get object() {
2352
+ return {};
2353
+ },
2354
+ string: ""
2355
+ };
2356
+ var readers = {
2357
+ array(value) {
2358
+ const array = JSON.parse(value);
2359
+ if (!Array.isArray(array)) {
2360
+ throw new TypeError(`expected value of type "array" but instead got value "${value}" of type "${parseValueTypeDefault(array)}"`);
2361
+ }
2362
+ return array;
2363
+ },
2364
+ boolean(value) {
2365
+ return !(value == "0" || String(value).toLowerCase() == "false");
2366
+ },
2367
+ number(value) {
2368
+ return Number(value.replace(/_/g, ""));
2369
+ },
2370
+ object(value) {
2371
+ const object = JSON.parse(value);
2372
+ if (object === null || typeof object != "object" || Array.isArray(object)) {
2373
+ throw new TypeError(`expected value of type "object" but instead got value "${value}" of type "${parseValueTypeDefault(object)}"`);
2374
+ }
2375
+ return object;
2376
+ },
2377
+ string(value) {
2378
+ return value;
2379
+ }
2380
+ };
2381
+ var writers = {
2382
+ default: writeString,
2383
+ array: writeJSON,
2384
+ object: writeJSON
2385
+ };
2386
+ function writeJSON(value) {
2387
+ return JSON.stringify(value);
2388
+ }
2389
+ function writeString(value) {
2390
+ return `${value}`;
2391
+ }
2392
+ var Controller = class {
2393
+ constructor(context) {
2394
+ this.context = context;
2395
+ }
2396
+ static get shouldLoad() {
2397
+ return true;
2398
+ }
2399
+ static afterLoad(_identifier, _application) {
2400
+ return;
2401
+ }
2402
+ get application() {
2403
+ return this.context.application;
2404
+ }
2405
+ get scope() {
2406
+ return this.context.scope;
2407
+ }
2408
+ get element() {
2409
+ return this.scope.element;
2410
+ }
2411
+ get identifier() {
2412
+ return this.scope.identifier;
2413
+ }
2414
+ get targets() {
2415
+ return this.scope.targets;
2416
+ }
2417
+ get outlets() {
2418
+ return this.scope.outlets;
2419
+ }
2420
+ get classes() {
2421
+ return this.scope.classes;
2422
+ }
2423
+ get data() {
2424
+ return this.scope.data;
2425
+ }
2426
+ initialize() {
2427
+ }
2428
+ connect() {
2429
+ }
2430
+ disconnect() {
2431
+ }
2432
+ dispatch(eventName, { target = this.element, detail = {}, prefix = this.identifier, bubbles = true, cancelable = true } = {}) {
2433
+ const type = prefix ? `${prefix}:${eventName}` : eventName;
2434
+ const event = new CustomEvent(type, { detail, bubbles, cancelable });
2435
+ target.dispatchEvent(event);
2436
+ return event;
2437
+ }
2438
+ };
2439
+ Controller.blessings = [
2440
+ ClassPropertiesBlessing,
2441
+ TargetPropertiesBlessing,
2442
+ ValuePropertiesBlessing,
2443
+ OutletPropertiesBlessing
2444
+ ];
2445
+ Controller.targets = [];
2446
+ Controller.outlets = [];
2447
+ Controller.values = {};
2448
+
2449
+ // app/javascript/controllers/application.js
2450
+ var application = Application.start();
2451
+ application.debug = false;
2452
+ window.Stimulus = application;
2453
+ //# sourceMappingURL=/assets/controllers/index.js.map