panoptic 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,4509 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropNames = Object.getOwnPropertyNames;
3
+ var __esm = (fn, res) => function __init() {
4
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
5
+ };
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+
11
+ // node_modules/@rails/actioncable/src/adapters.js
12
+ var adapters_default;
13
+ var init_adapters = __esm({
14
+ "node_modules/@rails/actioncable/src/adapters.js"() {
15
+ adapters_default = {
16
+ logger: typeof console !== "undefined" ? console : void 0,
17
+ WebSocket: typeof WebSocket !== "undefined" ? WebSocket : void 0
18
+ };
19
+ }
20
+ });
21
+
22
+ // node_modules/@rails/actioncable/src/logger.js
23
+ var logger_default;
24
+ var init_logger = __esm({
25
+ "node_modules/@rails/actioncable/src/logger.js"() {
26
+ init_adapters();
27
+ logger_default = {
28
+ log(...messages) {
29
+ if (this.enabled) {
30
+ messages.push(Date.now());
31
+ adapters_default.logger.log("[ActionCable]", ...messages);
32
+ }
33
+ }
34
+ };
35
+ }
36
+ });
37
+
38
+ // node_modules/@rails/actioncable/src/connection_monitor.js
39
+ var now, secondsSince, ConnectionMonitor, connection_monitor_default;
40
+ var init_connection_monitor = __esm({
41
+ "node_modules/@rails/actioncable/src/connection_monitor.js"() {
42
+ init_logger();
43
+ now = () => (/* @__PURE__ */ new Date()).getTime();
44
+ secondsSince = (time) => (now() - time) / 1e3;
45
+ ConnectionMonitor = class {
46
+ constructor(connection) {
47
+ this.visibilityDidChange = this.visibilityDidChange.bind(this);
48
+ this.connection = connection;
49
+ this.reconnectAttempts = 0;
50
+ }
51
+ start() {
52
+ if (!this.isRunning()) {
53
+ this.startedAt = now();
54
+ delete this.stoppedAt;
55
+ this.startPolling();
56
+ addEventListener("visibilitychange", this.visibilityDidChange);
57
+ logger_default.log(`ConnectionMonitor started. stale threshold = ${this.constructor.staleThreshold} s`);
58
+ }
59
+ }
60
+ stop() {
61
+ if (this.isRunning()) {
62
+ this.stoppedAt = now();
63
+ this.stopPolling();
64
+ removeEventListener("visibilitychange", this.visibilityDidChange);
65
+ logger_default.log("ConnectionMonitor stopped");
66
+ }
67
+ }
68
+ isRunning() {
69
+ return this.startedAt && !this.stoppedAt;
70
+ }
71
+ recordPing() {
72
+ this.pingedAt = now();
73
+ }
74
+ recordConnect() {
75
+ this.reconnectAttempts = 0;
76
+ this.recordPing();
77
+ delete this.disconnectedAt;
78
+ logger_default.log("ConnectionMonitor recorded connect");
79
+ }
80
+ recordDisconnect() {
81
+ this.disconnectedAt = now();
82
+ logger_default.log("ConnectionMonitor recorded disconnect");
83
+ }
84
+ // Private
85
+ startPolling() {
86
+ this.stopPolling();
87
+ this.poll();
88
+ }
89
+ stopPolling() {
90
+ clearTimeout(this.pollTimeout);
91
+ }
92
+ poll() {
93
+ this.pollTimeout = setTimeout(
94
+ () => {
95
+ this.reconnectIfStale();
96
+ this.poll();
97
+ },
98
+ this.getPollInterval()
99
+ );
100
+ }
101
+ getPollInterval() {
102
+ const { staleThreshold, reconnectionBackoffRate } = this.constructor;
103
+ const backoff = Math.pow(1 + reconnectionBackoffRate, Math.min(this.reconnectAttempts, 10));
104
+ const jitterMax = this.reconnectAttempts === 0 ? 1 : reconnectionBackoffRate;
105
+ const jitter = jitterMax * Math.random();
106
+ return staleThreshold * 1e3 * backoff * (1 + jitter);
107
+ }
108
+ reconnectIfStale() {
109
+ if (this.connectionIsStale()) {
110
+ logger_default.log(`ConnectionMonitor detected stale connection. reconnectAttempts = ${this.reconnectAttempts}, time stale = ${secondsSince(this.refreshedAt)} s, stale threshold = ${this.constructor.staleThreshold} s`);
111
+ this.reconnectAttempts++;
112
+ if (this.disconnectedRecently()) {
113
+ logger_default.log(`ConnectionMonitor skipping reopening recent disconnect. time disconnected = ${secondsSince(this.disconnectedAt)} s`);
114
+ } else {
115
+ logger_default.log("ConnectionMonitor reopening");
116
+ this.connection.reopen();
117
+ }
118
+ }
119
+ }
120
+ get refreshedAt() {
121
+ return this.pingedAt ? this.pingedAt : this.startedAt;
122
+ }
123
+ connectionIsStale() {
124
+ return secondsSince(this.refreshedAt) > this.constructor.staleThreshold;
125
+ }
126
+ disconnectedRecently() {
127
+ return this.disconnectedAt && secondsSince(this.disconnectedAt) < this.constructor.staleThreshold;
128
+ }
129
+ visibilityDidChange() {
130
+ if (document.visibilityState === "visible") {
131
+ setTimeout(
132
+ () => {
133
+ if (this.connectionIsStale() || !this.connection.isOpen()) {
134
+ logger_default.log(`ConnectionMonitor reopening stale connection on visibilitychange. visibilityState = ${document.visibilityState}`);
135
+ this.connection.reopen();
136
+ }
137
+ },
138
+ 200
139
+ );
140
+ }
141
+ }
142
+ };
143
+ ConnectionMonitor.staleThreshold = 6;
144
+ ConnectionMonitor.reconnectionBackoffRate = 0.15;
145
+ connection_monitor_default = ConnectionMonitor;
146
+ }
147
+ });
148
+
149
+ // node_modules/@rails/actioncable/src/internal.js
150
+ var internal_default;
151
+ var init_internal = __esm({
152
+ "node_modules/@rails/actioncable/src/internal.js"() {
153
+ internal_default = {
154
+ "message_types": {
155
+ "welcome": "welcome",
156
+ "disconnect": "disconnect",
157
+ "ping": "ping",
158
+ "confirmation": "confirm_subscription",
159
+ "rejection": "reject_subscription"
160
+ },
161
+ "disconnect_reasons": {
162
+ "unauthorized": "unauthorized",
163
+ "invalid_request": "invalid_request",
164
+ "server_restart": "server_restart",
165
+ "remote": "remote"
166
+ },
167
+ "default_mount_path": "/cable",
168
+ "protocols": [
169
+ "actioncable-v1-json",
170
+ "actioncable-unsupported"
171
+ ]
172
+ };
173
+ }
174
+ });
175
+
176
+ // node_modules/@rails/actioncable/src/connection.js
177
+ var message_types, protocols, supportedProtocols, indexOf, Connection, connection_default;
178
+ var init_connection = __esm({
179
+ "node_modules/@rails/actioncable/src/connection.js"() {
180
+ init_adapters();
181
+ init_connection_monitor();
182
+ init_internal();
183
+ init_logger();
184
+ ({ message_types, protocols } = internal_default);
185
+ supportedProtocols = protocols.slice(0, protocols.length - 1);
186
+ indexOf = [].indexOf;
187
+ Connection = class {
188
+ constructor(consumer2) {
189
+ this.open = this.open.bind(this);
190
+ this.consumer = consumer2;
191
+ this.subscriptions = this.consumer.subscriptions;
192
+ this.monitor = new connection_monitor_default(this);
193
+ this.disconnected = true;
194
+ }
195
+ send(data) {
196
+ if (this.isOpen()) {
197
+ this.webSocket.send(JSON.stringify(data));
198
+ return true;
199
+ } else {
200
+ return false;
201
+ }
202
+ }
203
+ open() {
204
+ if (this.isActive()) {
205
+ logger_default.log(`Attempted to open WebSocket, but existing socket is ${this.getState()}`);
206
+ return false;
207
+ } else {
208
+ const socketProtocols = [...protocols, ...this.consumer.subprotocols || []];
209
+ logger_default.log(`Opening WebSocket, current state is ${this.getState()}, subprotocols: ${socketProtocols}`);
210
+ if (this.webSocket) {
211
+ this.uninstallEventHandlers();
212
+ }
213
+ this.webSocket = new adapters_default.WebSocket(this.consumer.url, socketProtocols);
214
+ this.installEventHandlers();
215
+ this.monitor.start();
216
+ return true;
217
+ }
218
+ }
219
+ close({ allowReconnect } = { allowReconnect: true }) {
220
+ if (!allowReconnect) {
221
+ this.monitor.stop();
222
+ }
223
+ if (this.isOpen()) {
224
+ return this.webSocket.close();
225
+ }
226
+ }
227
+ reopen() {
228
+ logger_default.log(`Reopening WebSocket, current state is ${this.getState()}`);
229
+ if (this.isActive()) {
230
+ try {
231
+ return this.close();
232
+ } catch (error) {
233
+ logger_default.log("Failed to reopen WebSocket", error);
234
+ } finally {
235
+ logger_default.log(`Reopening WebSocket in ${this.constructor.reopenDelay}ms`);
236
+ setTimeout(this.open, this.constructor.reopenDelay);
237
+ }
238
+ } else {
239
+ return this.open();
240
+ }
241
+ }
242
+ getProtocol() {
243
+ if (this.webSocket) {
244
+ return this.webSocket.protocol;
245
+ }
246
+ }
247
+ isOpen() {
248
+ return this.isState("open");
249
+ }
250
+ isActive() {
251
+ return this.isState("open", "connecting");
252
+ }
253
+ triedToReconnect() {
254
+ return this.monitor.reconnectAttempts > 0;
255
+ }
256
+ // Private
257
+ isProtocolSupported() {
258
+ return indexOf.call(supportedProtocols, this.getProtocol()) >= 0;
259
+ }
260
+ isState(...states) {
261
+ return indexOf.call(states, this.getState()) >= 0;
262
+ }
263
+ getState() {
264
+ if (this.webSocket) {
265
+ for (let state in adapters_default.WebSocket) {
266
+ if (adapters_default.WebSocket[state] === this.webSocket.readyState) {
267
+ return state.toLowerCase();
268
+ }
269
+ }
270
+ }
271
+ return null;
272
+ }
273
+ installEventHandlers() {
274
+ for (let eventName in this.events) {
275
+ const handler = this.events[eventName].bind(this);
276
+ this.webSocket[`on${eventName}`] = handler;
277
+ }
278
+ }
279
+ uninstallEventHandlers() {
280
+ for (let eventName in this.events) {
281
+ this.webSocket[`on${eventName}`] = function() {
282
+ };
283
+ }
284
+ }
285
+ };
286
+ Connection.reopenDelay = 500;
287
+ Connection.prototype.events = {
288
+ message(event) {
289
+ if (!this.isProtocolSupported()) {
290
+ return;
291
+ }
292
+ const { identifier, message, reason, reconnect, type } = JSON.parse(event.data);
293
+ switch (type) {
294
+ case message_types.welcome:
295
+ if (this.triedToReconnect()) {
296
+ this.reconnectAttempted = true;
297
+ }
298
+ this.monitor.recordConnect();
299
+ return this.subscriptions.reload();
300
+ case message_types.disconnect:
301
+ logger_default.log(`Disconnecting. Reason: ${reason}`);
302
+ return this.close({ allowReconnect: reconnect });
303
+ case message_types.ping:
304
+ return this.monitor.recordPing();
305
+ case message_types.confirmation:
306
+ this.subscriptions.confirmSubscription(identifier);
307
+ if (this.reconnectAttempted) {
308
+ this.reconnectAttempted = false;
309
+ return this.subscriptions.notify(identifier, "connected", { reconnected: true });
310
+ } else {
311
+ return this.subscriptions.notify(identifier, "connected", { reconnected: false });
312
+ }
313
+ case message_types.rejection:
314
+ return this.subscriptions.reject(identifier);
315
+ default:
316
+ return this.subscriptions.notify(identifier, "received", message);
317
+ }
318
+ },
319
+ open() {
320
+ logger_default.log(`WebSocket onopen event, using '${this.getProtocol()}' subprotocol`);
321
+ this.disconnected = false;
322
+ if (!this.isProtocolSupported()) {
323
+ logger_default.log("Protocol is unsupported. Stopping monitor and disconnecting.");
324
+ return this.close({ allowReconnect: false });
325
+ }
326
+ },
327
+ close(event) {
328
+ logger_default.log("WebSocket onclose event");
329
+ if (this.disconnected) {
330
+ return;
331
+ }
332
+ this.disconnected = true;
333
+ this.monitor.recordDisconnect();
334
+ return this.subscriptions.notifyAll("disconnected", { willAttemptReconnect: this.monitor.isRunning() });
335
+ },
336
+ error() {
337
+ logger_default.log("WebSocket onerror event");
338
+ }
339
+ };
340
+ connection_default = Connection;
341
+ }
342
+ });
343
+
344
+ // node_modules/@rails/actioncable/src/subscription.js
345
+ var extend, Subscription;
346
+ var init_subscription = __esm({
347
+ "node_modules/@rails/actioncable/src/subscription.js"() {
348
+ extend = function(object, properties) {
349
+ if (properties != null) {
350
+ for (let key in properties) {
351
+ const value = properties[key];
352
+ object[key] = value;
353
+ }
354
+ }
355
+ return object;
356
+ };
357
+ Subscription = class {
358
+ constructor(consumer2, params = {}, mixin) {
359
+ this.consumer = consumer2;
360
+ this.identifier = JSON.stringify(params);
361
+ extend(this, mixin);
362
+ }
363
+ // Perform a channel action with the optional data passed as an attribute
364
+ perform(action, data = {}) {
365
+ data.action = action;
366
+ return this.send(data);
367
+ }
368
+ send(data) {
369
+ return this.consumer.send({ command: "message", identifier: this.identifier, data: JSON.stringify(data) });
370
+ }
371
+ unsubscribe() {
372
+ return this.consumer.subscriptions.remove(this);
373
+ }
374
+ };
375
+ }
376
+ });
377
+
378
+ // node_modules/@rails/actioncable/src/subscription_guarantor.js
379
+ var SubscriptionGuarantor, subscription_guarantor_default;
380
+ var init_subscription_guarantor = __esm({
381
+ "node_modules/@rails/actioncable/src/subscription_guarantor.js"() {
382
+ init_logger();
383
+ SubscriptionGuarantor = class {
384
+ constructor(subscriptions) {
385
+ this.subscriptions = subscriptions;
386
+ this.pendingSubscriptions = [];
387
+ }
388
+ guarantee(subscription) {
389
+ if (this.pendingSubscriptions.indexOf(subscription) == -1) {
390
+ logger_default.log(`SubscriptionGuarantor guaranteeing ${subscription.identifier}`);
391
+ this.pendingSubscriptions.push(subscription);
392
+ } else {
393
+ logger_default.log(`SubscriptionGuarantor already guaranteeing ${subscription.identifier}`);
394
+ }
395
+ this.startGuaranteeing();
396
+ }
397
+ forget(subscription) {
398
+ logger_default.log(`SubscriptionGuarantor forgetting ${subscription.identifier}`);
399
+ this.pendingSubscriptions = this.pendingSubscriptions.filter((s) => s !== subscription);
400
+ }
401
+ startGuaranteeing() {
402
+ this.stopGuaranteeing();
403
+ this.retrySubscribing();
404
+ }
405
+ stopGuaranteeing() {
406
+ clearTimeout(this.retryTimeout);
407
+ }
408
+ retrySubscribing() {
409
+ this.retryTimeout = setTimeout(
410
+ () => {
411
+ if (this.subscriptions && typeof this.subscriptions.subscribe === "function") {
412
+ this.pendingSubscriptions.map((subscription) => {
413
+ logger_default.log(`SubscriptionGuarantor resubscribing ${subscription.identifier}`);
414
+ this.subscriptions.subscribe(subscription);
415
+ });
416
+ }
417
+ },
418
+ 500
419
+ );
420
+ }
421
+ };
422
+ subscription_guarantor_default = SubscriptionGuarantor;
423
+ }
424
+ });
425
+
426
+ // node_modules/@rails/actioncable/src/subscriptions.js
427
+ var Subscriptions;
428
+ var init_subscriptions = __esm({
429
+ "node_modules/@rails/actioncable/src/subscriptions.js"() {
430
+ init_subscription();
431
+ init_subscription_guarantor();
432
+ init_logger();
433
+ Subscriptions = class {
434
+ constructor(consumer2) {
435
+ this.consumer = consumer2;
436
+ this.guarantor = new subscription_guarantor_default(this);
437
+ this.subscriptions = [];
438
+ }
439
+ create(channelName, mixin) {
440
+ const channel = channelName;
441
+ const params = typeof channel === "object" ? channel : { channel };
442
+ const subscription = new Subscription(this.consumer, params, mixin);
443
+ return this.add(subscription);
444
+ }
445
+ // Private
446
+ add(subscription) {
447
+ this.subscriptions.push(subscription);
448
+ this.consumer.ensureActiveConnection();
449
+ this.notify(subscription, "initialized");
450
+ this.subscribe(subscription);
451
+ return subscription;
452
+ }
453
+ remove(subscription) {
454
+ this.forget(subscription);
455
+ if (!this.findAll(subscription.identifier).length) {
456
+ this.sendCommand(subscription, "unsubscribe");
457
+ }
458
+ return subscription;
459
+ }
460
+ reject(identifier) {
461
+ return this.findAll(identifier).map((subscription) => {
462
+ this.forget(subscription);
463
+ this.notify(subscription, "rejected");
464
+ return subscription;
465
+ });
466
+ }
467
+ forget(subscription) {
468
+ this.guarantor.forget(subscription);
469
+ this.subscriptions = this.subscriptions.filter((s) => s !== subscription);
470
+ return subscription;
471
+ }
472
+ findAll(identifier) {
473
+ return this.subscriptions.filter((s) => s.identifier === identifier);
474
+ }
475
+ reload() {
476
+ return this.subscriptions.map((subscription) => this.subscribe(subscription));
477
+ }
478
+ notifyAll(callbackName, ...args) {
479
+ return this.subscriptions.map((subscription) => this.notify(subscription, callbackName, ...args));
480
+ }
481
+ notify(subscription, callbackName, ...args) {
482
+ let subscriptions;
483
+ if (typeof subscription === "string") {
484
+ subscriptions = this.findAll(subscription);
485
+ } else {
486
+ subscriptions = [subscription];
487
+ }
488
+ return subscriptions.map((subscription2) => typeof subscription2[callbackName] === "function" ? subscription2[callbackName](...args) : void 0);
489
+ }
490
+ subscribe(subscription) {
491
+ if (this.sendCommand(subscription, "subscribe")) {
492
+ this.guarantor.guarantee(subscription);
493
+ }
494
+ }
495
+ confirmSubscription(identifier) {
496
+ logger_default.log(`Subscription confirmed ${identifier}`);
497
+ this.findAll(identifier).map((subscription) => this.guarantor.forget(subscription));
498
+ }
499
+ sendCommand(subscription, command) {
500
+ const { identifier } = subscription;
501
+ return this.consumer.send({ command, identifier });
502
+ }
503
+ };
504
+ }
505
+ });
506
+
507
+ // node_modules/@rails/actioncable/src/consumer.js
508
+ function createWebSocketURL(url) {
509
+ if (typeof url === "function") {
510
+ url = url();
511
+ }
512
+ if (url && !/^wss?:/i.test(url)) {
513
+ const a = document.createElement("a");
514
+ a.href = url;
515
+ a.href = a.href;
516
+ a.protocol = a.protocol.replace("http", "ws");
517
+ return a.href;
518
+ } else {
519
+ return url;
520
+ }
521
+ }
522
+ var Consumer;
523
+ var init_consumer = __esm({
524
+ "node_modules/@rails/actioncable/src/consumer.js"() {
525
+ init_connection();
526
+ init_subscriptions();
527
+ Consumer = class {
528
+ constructor(url) {
529
+ this._url = url;
530
+ this.subscriptions = new Subscriptions(this);
531
+ this.connection = new connection_default(this);
532
+ this.subprotocols = [];
533
+ }
534
+ get url() {
535
+ return createWebSocketURL(this._url);
536
+ }
537
+ send(data) {
538
+ return this.connection.send(data);
539
+ }
540
+ connect() {
541
+ return this.connection.open();
542
+ }
543
+ disconnect() {
544
+ return this.connection.close({ allowReconnect: false });
545
+ }
546
+ ensureActiveConnection() {
547
+ if (!this.connection.isActive()) {
548
+ return this.connection.open();
549
+ }
550
+ }
551
+ addSubProtocol(subprotocol) {
552
+ this.subprotocols = [...this.subprotocols, subprotocol];
553
+ }
554
+ };
555
+ }
556
+ });
557
+
558
+ // node_modules/@rails/actioncable/src/index.js
559
+ var src_exports = {};
560
+ __export(src_exports, {
561
+ Connection: () => connection_default,
562
+ ConnectionMonitor: () => connection_monitor_default,
563
+ Consumer: () => Consumer,
564
+ INTERNAL: () => internal_default,
565
+ Subscription: () => Subscription,
566
+ SubscriptionGuarantor: () => subscription_guarantor_default,
567
+ Subscriptions: () => Subscriptions,
568
+ adapters: () => adapters_default,
569
+ createConsumer: () => createConsumer,
570
+ createWebSocketURL: () => createWebSocketURL,
571
+ getConfig: () => getConfig,
572
+ logger: () => logger_default
573
+ });
574
+ function createConsumer(url = getConfig("url") || internal_default.default_mount_path) {
575
+ return new Consumer(url);
576
+ }
577
+ function getConfig(name) {
578
+ const element = document.head.querySelector(`meta[name='action-cable-${name}']`);
579
+ if (element) {
580
+ return element.getAttribute("content");
581
+ }
582
+ }
583
+ var init_src = __esm({
584
+ "node_modules/@rails/actioncable/src/index.js"() {
585
+ init_connection();
586
+ init_connection_monitor();
587
+ init_consumer();
588
+ init_internal();
589
+ init_subscription();
590
+ init_subscriptions();
591
+ init_subscription_guarantor();
592
+ init_adapters();
593
+ init_logger();
594
+ }
595
+ });
596
+
597
+ // node_modules/@hotwired/turbo/dist/turbo.es2017-esm.js
598
+ (function() {
599
+ if (window.Reflect === void 0 || window.customElements === void 0 || window.customElements.polyfillWrapFlushCallback) {
600
+ return;
601
+ }
602
+ const BuiltInHTMLElement = HTMLElement;
603
+ const wrapperForTheName = {
604
+ HTMLElement: function HTMLElement2() {
605
+ return Reflect.construct(BuiltInHTMLElement, [], this.constructor);
606
+ }
607
+ };
608
+ window.HTMLElement = wrapperForTheName["HTMLElement"];
609
+ HTMLElement.prototype = BuiltInHTMLElement.prototype;
610
+ HTMLElement.prototype.constructor = HTMLElement;
611
+ Object.setPrototypeOf(HTMLElement, BuiltInHTMLElement);
612
+ })();
613
+ (function(prototype) {
614
+ if (typeof prototype.requestSubmit == "function")
615
+ return;
616
+ prototype.requestSubmit = function(submitter) {
617
+ if (submitter) {
618
+ validateSubmitter(submitter, this);
619
+ submitter.click();
620
+ } else {
621
+ submitter = document.createElement("input");
622
+ submitter.type = "submit";
623
+ submitter.hidden = true;
624
+ this.appendChild(submitter);
625
+ submitter.click();
626
+ this.removeChild(submitter);
627
+ }
628
+ };
629
+ function validateSubmitter(submitter, form) {
630
+ submitter instanceof HTMLElement || raise(TypeError, "parameter 1 is not of type 'HTMLElement'");
631
+ submitter.type == "submit" || raise(TypeError, "The specified element is not a submit button");
632
+ submitter.form == form || raise(DOMException, "The specified element is not owned by this form element", "NotFoundError");
633
+ }
634
+ function raise(errorConstructor, message, name) {
635
+ throw new errorConstructor("Failed to execute 'requestSubmit' on 'HTMLFormElement': " + message + ".", name);
636
+ }
637
+ })(HTMLFormElement.prototype);
638
+ var submittersByForm = /* @__PURE__ */ new WeakMap();
639
+ function findSubmitterFromClickTarget(target) {
640
+ const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
641
+ const candidate = element ? element.closest("input, button") : null;
642
+ return (candidate === null || candidate === void 0 ? void 0 : candidate.type) == "submit" ? candidate : null;
643
+ }
644
+ function clickCaptured(event) {
645
+ const submitter = findSubmitterFromClickTarget(event.target);
646
+ if (submitter && submitter.form) {
647
+ submittersByForm.set(submitter.form, submitter);
648
+ }
649
+ }
650
+ (function() {
651
+ if ("submitter" in Event.prototype)
652
+ return;
653
+ let prototype = window.Event.prototype;
654
+ if ("SubmitEvent" in window && /Apple Computer/.test(navigator.vendor)) {
655
+ prototype = window.SubmitEvent.prototype;
656
+ } else if ("SubmitEvent" in window) {
657
+ return;
658
+ }
659
+ addEventListener("click", clickCaptured, true);
660
+ Object.defineProperty(prototype, "submitter", {
661
+ get() {
662
+ if (this.type == "submit" && this.target instanceof HTMLFormElement) {
663
+ return submittersByForm.get(this.target);
664
+ }
665
+ }
666
+ });
667
+ })();
668
+ var FrameLoadingStyle;
669
+ (function(FrameLoadingStyle2) {
670
+ FrameLoadingStyle2["eager"] = "eager";
671
+ FrameLoadingStyle2["lazy"] = "lazy";
672
+ })(FrameLoadingStyle || (FrameLoadingStyle = {}));
673
+ var FrameElement = class _FrameElement extends HTMLElement {
674
+ static get observedAttributes() {
675
+ return ["disabled", "complete", "loading", "src"];
676
+ }
677
+ constructor() {
678
+ super();
679
+ this.loaded = Promise.resolve();
680
+ this.delegate = new _FrameElement.delegateConstructor(this);
681
+ }
682
+ connectedCallback() {
683
+ this.delegate.connect();
684
+ }
685
+ disconnectedCallback() {
686
+ this.delegate.disconnect();
687
+ }
688
+ reload() {
689
+ return this.delegate.sourceURLReloaded();
690
+ }
691
+ attributeChangedCallback(name) {
692
+ if (name == "loading") {
693
+ this.delegate.loadingStyleChanged();
694
+ } else if (name == "complete") {
695
+ this.delegate.completeChanged();
696
+ } else if (name == "src") {
697
+ this.delegate.sourceURLChanged();
698
+ } else {
699
+ this.delegate.disabledChanged();
700
+ }
701
+ }
702
+ get src() {
703
+ return this.getAttribute("src");
704
+ }
705
+ set src(value) {
706
+ if (value) {
707
+ this.setAttribute("src", value);
708
+ } else {
709
+ this.removeAttribute("src");
710
+ }
711
+ }
712
+ get loading() {
713
+ return frameLoadingStyleFromString(this.getAttribute("loading") || "");
714
+ }
715
+ set loading(value) {
716
+ if (value) {
717
+ this.setAttribute("loading", value);
718
+ } else {
719
+ this.removeAttribute("loading");
720
+ }
721
+ }
722
+ get disabled() {
723
+ return this.hasAttribute("disabled");
724
+ }
725
+ set disabled(value) {
726
+ if (value) {
727
+ this.setAttribute("disabled", "");
728
+ } else {
729
+ this.removeAttribute("disabled");
730
+ }
731
+ }
732
+ get autoscroll() {
733
+ return this.hasAttribute("autoscroll");
734
+ }
735
+ set autoscroll(value) {
736
+ if (value) {
737
+ this.setAttribute("autoscroll", "");
738
+ } else {
739
+ this.removeAttribute("autoscroll");
740
+ }
741
+ }
742
+ get complete() {
743
+ return !this.delegate.isLoading;
744
+ }
745
+ get isActive() {
746
+ return this.ownerDocument === document && !this.isPreview;
747
+ }
748
+ get isPreview() {
749
+ var _a, _b;
750
+ return (_b = (_a = this.ownerDocument) === null || _a === void 0 ? void 0 : _a.documentElement) === null || _b === void 0 ? void 0 : _b.hasAttribute("data-turbo-preview");
751
+ }
752
+ };
753
+ function frameLoadingStyleFromString(style) {
754
+ switch (style.toLowerCase()) {
755
+ case "lazy":
756
+ return FrameLoadingStyle.lazy;
757
+ default:
758
+ return FrameLoadingStyle.eager;
759
+ }
760
+ }
761
+ function expandURL(locatable) {
762
+ return new URL(locatable.toString(), document.baseURI);
763
+ }
764
+ function getAnchor(url) {
765
+ let anchorMatch;
766
+ if (url.hash) {
767
+ return url.hash.slice(1);
768
+ } else if (anchorMatch = url.href.match(/#(.*)$/)) {
769
+ return anchorMatch[1];
770
+ }
771
+ }
772
+ function getAction(form, submitter) {
773
+ const action = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formaction")) || form.getAttribute("action") || form.action;
774
+ return expandURL(action);
775
+ }
776
+ function getExtension(url) {
777
+ return (getLastPathComponent(url).match(/\.[^.]*$/) || [])[0] || "";
778
+ }
779
+ function isHTML(url) {
780
+ return !!getExtension(url).match(/^(?:|\.(?:htm|html|xhtml|php))$/);
781
+ }
782
+ function isPrefixedBy(baseURL, url) {
783
+ const prefix = getPrefix(url);
784
+ return baseURL.href === expandURL(prefix).href || baseURL.href.startsWith(prefix);
785
+ }
786
+ function locationIsVisitable(location2, rootLocation) {
787
+ return isPrefixedBy(location2, rootLocation) && isHTML(location2);
788
+ }
789
+ function getRequestURL(url) {
790
+ const anchor = getAnchor(url);
791
+ return anchor != null ? url.href.slice(0, -(anchor.length + 1)) : url.href;
792
+ }
793
+ function toCacheKey(url) {
794
+ return getRequestURL(url);
795
+ }
796
+ function urlsAreEqual(left, right) {
797
+ return expandURL(left).href == expandURL(right).href;
798
+ }
799
+ function getPathComponents(url) {
800
+ return url.pathname.split("/").slice(1);
801
+ }
802
+ function getLastPathComponent(url) {
803
+ return getPathComponents(url).slice(-1)[0];
804
+ }
805
+ function getPrefix(url) {
806
+ return addTrailingSlash(url.origin + url.pathname);
807
+ }
808
+ function addTrailingSlash(value) {
809
+ return value.endsWith("/") ? value : value + "/";
810
+ }
811
+ var FetchResponse = class {
812
+ constructor(response) {
813
+ this.response = response;
814
+ }
815
+ get succeeded() {
816
+ return this.response.ok;
817
+ }
818
+ get failed() {
819
+ return !this.succeeded;
820
+ }
821
+ get clientError() {
822
+ return this.statusCode >= 400 && this.statusCode <= 499;
823
+ }
824
+ get serverError() {
825
+ return this.statusCode >= 500 && this.statusCode <= 599;
826
+ }
827
+ get redirected() {
828
+ return this.response.redirected;
829
+ }
830
+ get location() {
831
+ return expandURL(this.response.url);
832
+ }
833
+ get isHTML() {
834
+ return this.contentType && this.contentType.match(/^(?:text\/([^\s;,]+\b)?html|application\/xhtml\+xml)\b/);
835
+ }
836
+ get statusCode() {
837
+ return this.response.status;
838
+ }
839
+ get contentType() {
840
+ return this.header("Content-Type");
841
+ }
842
+ get responseText() {
843
+ return this.response.clone().text();
844
+ }
845
+ get responseHTML() {
846
+ if (this.isHTML) {
847
+ return this.response.clone().text();
848
+ } else {
849
+ return Promise.resolve(void 0);
850
+ }
851
+ }
852
+ header(name) {
853
+ return this.response.headers.get(name);
854
+ }
855
+ };
856
+ function activateScriptElement(element) {
857
+ if (element.getAttribute("data-turbo-eval") == "false") {
858
+ return element;
859
+ } else {
860
+ const createdScriptElement = document.createElement("script");
861
+ const cspNonce = getMetaContent("csp-nonce");
862
+ if (cspNonce) {
863
+ createdScriptElement.nonce = cspNonce;
864
+ }
865
+ createdScriptElement.textContent = element.textContent;
866
+ createdScriptElement.async = false;
867
+ copyElementAttributes(createdScriptElement, element);
868
+ return createdScriptElement;
869
+ }
870
+ }
871
+ function copyElementAttributes(destinationElement, sourceElement) {
872
+ for (const { name, value } of sourceElement.attributes) {
873
+ destinationElement.setAttribute(name, value);
874
+ }
875
+ }
876
+ function createDocumentFragment(html) {
877
+ const template = document.createElement("template");
878
+ template.innerHTML = html;
879
+ return template.content;
880
+ }
881
+ function dispatch(eventName, { target, cancelable, detail } = {}) {
882
+ const event = new CustomEvent(eventName, {
883
+ cancelable,
884
+ bubbles: true,
885
+ composed: true,
886
+ detail
887
+ });
888
+ if (target && target.isConnected) {
889
+ target.dispatchEvent(event);
890
+ } else {
891
+ document.documentElement.dispatchEvent(event);
892
+ }
893
+ return event;
894
+ }
895
+ function nextAnimationFrame() {
896
+ return new Promise((resolve) => requestAnimationFrame(() => resolve()));
897
+ }
898
+ function nextEventLoopTick() {
899
+ return new Promise((resolve) => setTimeout(() => resolve(), 0));
900
+ }
901
+ function nextMicrotask() {
902
+ return Promise.resolve();
903
+ }
904
+ function parseHTMLDocument(html = "") {
905
+ return new DOMParser().parseFromString(html, "text/html");
906
+ }
907
+ function unindent(strings, ...values) {
908
+ const lines = interpolate(strings, values).replace(/^\n/, "").split("\n");
909
+ const match = lines[0].match(/^\s+/);
910
+ const indent = match ? match[0].length : 0;
911
+ return lines.map((line) => line.slice(indent)).join("\n");
912
+ }
913
+ function interpolate(strings, values) {
914
+ return strings.reduce((result, string, i) => {
915
+ const value = values[i] == void 0 ? "" : values[i];
916
+ return result + string + value;
917
+ }, "");
918
+ }
919
+ function uuid() {
920
+ return Array.from({ length: 36 }).map((_, i) => {
921
+ if (i == 8 || i == 13 || i == 18 || i == 23) {
922
+ return "-";
923
+ } else if (i == 14) {
924
+ return "4";
925
+ } else if (i == 19) {
926
+ return (Math.floor(Math.random() * 4) + 8).toString(16);
927
+ } else {
928
+ return Math.floor(Math.random() * 15).toString(16);
929
+ }
930
+ }).join("");
931
+ }
932
+ function getAttribute(attributeName, ...elements) {
933
+ for (const value of elements.map((element) => element === null || element === void 0 ? void 0 : element.getAttribute(attributeName))) {
934
+ if (typeof value == "string")
935
+ return value;
936
+ }
937
+ return null;
938
+ }
939
+ function hasAttribute(attributeName, ...elements) {
940
+ return elements.some((element) => element && element.hasAttribute(attributeName));
941
+ }
942
+ function markAsBusy(...elements) {
943
+ for (const element of elements) {
944
+ if (element.localName == "turbo-frame") {
945
+ element.setAttribute("busy", "");
946
+ }
947
+ element.setAttribute("aria-busy", "true");
948
+ }
949
+ }
950
+ function clearBusyState(...elements) {
951
+ for (const element of elements) {
952
+ if (element.localName == "turbo-frame") {
953
+ element.removeAttribute("busy");
954
+ }
955
+ element.removeAttribute("aria-busy");
956
+ }
957
+ }
958
+ function waitForLoad(element, timeoutInMilliseconds = 2e3) {
959
+ return new Promise((resolve) => {
960
+ const onComplete = () => {
961
+ element.removeEventListener("error", onComplete);
962
+ element.removeEventListener("load", onComplete);
963
+ resolve();
964
+ };
965
+ element.addEventListener("load", onComplete, { once: true });
966
+ element.addEventListener("error", onComplete, { once: true });
967
+ setTimeout(resolve, timeoutInMilliseconds);
968
+ });
969
+ }
970
+ function getHistoryMethodForAction(action) {
971
+ switch (action) {
972
+ case "replace":
973
+ return history.replaceState;
974
+ case "advance":
975
+ case "restore":
976
+ return history.pushState;
977
+ }
978
+ }
979
+ function isAction(action) {
980
+ return action == "advance" || action == "replace" || action == "restore";
981
+ }
982
+ function getVisitAction(...elements) {
983
+ const action = getAttribute("data-turbo-action", ...elements);
984
+ return isAction(action) ? action : null;
985
+ }
986
+ function getMetaElement(name) {
987
+ return document.querySelector(`meta[name="${name}"]`);
988
+ }
989
+ function getMetaContent(name) {
990
+ const element = getMetaElement(name);
991
+ return element && element.content;
992
+ }
993
+ function setMetaContent(name, content) {
994
+ let element = getMetaElement(name);
995
+ if (!element) {
996
+ element = document.createElement("meta");
997
+ element.setAttribute("name", name);
998
+ document.head.appendChild(element);
999
+ }
1000
+ element.setAttribute("content", content);
1001
+ return element;
1002
+ }
1003
+ function findClosestRecursively(element, selector) {
1004
+ var _a;
1005
+ if (element instanceof Element) {
1006
+ return element.closest(selector) || findClosestRecursively(element.assignedSlot || ((_a = element.getRootNode()) === null || _a === void 0 ? void 0 : _a.host), selector);
1007
+ }
1008
+ }
1009
+ var FetchMethod;
1010
+ (function(FetchMethod2) {
1011
+ FetchMethod2[FetchMethod2["get"] = 0] = "get";
1012
+ FetchMethod2[FetchMethod2["post"] = 1] = "post";
1013
+ FetchMethod2[FetchMethod2["put"] = 2] = "put";
1014
+ FetchMethod2[FetchMethod2["patch"] = 3] = "patch";
1015
+ FetchMethod2[FetchMethod2["delete"] = 4] = "delete";
1016
+ })(FetchMethod || (FetchMethod = {}));
1017
+ function fetchMethodFromString(method) {
1018
+ switch (method.toLowerCase()) {
1019
+ case "get":
1020
+ return FetchMethod.get;
1021
+ case "post":
1022
+ return FetchMethod.post;
1023
+ case "put":
1024
+ return FetchMethod.put;
1025
+ case "patch":
1026
+ return FetchMethod.patch;
1027
+ case "delete":
1028
+ return FetchMethod.delete;
1029
+ }
1030
+ }
1031
+ var FetchRequest = class {
1032
+ constructor(delegate, method, location2, body = new URLSearchParams(), target = null) {
1033
+ this.abortController = new AbortController();
1034
+ this.resolveRequestPromise = (_value) => {
1035
+ };
1036
+ this.delegate = delegate;
1037
+ this.method = method;
1038
+ this.headers = this.defaultHeaders;
1039
+ this.body = body;
1040
+ this.url = location2;
1041
+ this.target = target;
1042
+ }
1043
+ get location() {
1044
+ return this.url;
1045
+ }
1046
+ get params() {
1047
+ return this.url.searchParams;
1048
+ }
1049
+ get entries() {
1050
+ return this.body ? Array.from(this.body.entries()) : [];
1051
+ }
1052
+ cancel() {
1053
+ this.abortController.abort();
1054
+ }
1055
+ async perform() {
1056
+ const { fetchOptions } = this;
1057
+ this.delegate.prepareRequest(this);
1058
+ await this.allowRequestToBeIntercepted(fetchOptions);
1059
+ try {
1060
+ this.delegate.requestStarted(this);
1061
+ const response = await fetch(this.url.href, fetchOptions);
1062
+ return await this.receive(response);
1063
+ } catch (error) {
1064
+ if (error.name !== "AbortError") {
1065
+ if (this.willDelegateErrorHandling(error)) {
1066
+ this.delegate.requestErrored(this, error);
1067
+ }
1068
+ throw error;
1069
+ }
1070
+ } finally {
1071
+ this.delegate.requestFinished(this);
1072
+ }
1073
+ }
1074
+ async receive(response) {
1075
+ const fetchResponse = new FetchResponse(response);
1076
+ const event = dispatch("turbo:before-fetch-response", {
1077
+ cancelable: true,
1078
+ detail: { fetchResponse },
1079
+ target: this.target
1080
+ });
1081
+ if (event.defaultPrevented) {
1082
+ this.delegate.requestPreventedHandlingResponse(this, fetchResponse);
1083
+ } else if (fetchResponse.succeeded) {
1084
+ this.delegate.requestSucceededWithResponse(this, fetchResponse);
1085
+ } else {
1086
+ this.delegate.requestFailedWithResponse(this, fetchResponse);
1087
+ }
1088
+ return fetchResponse;
1089
+ }
1090
+ get fetchOptions() {
1091
+ var _a;
1092
+ return {
1093
+ method: FetchMethod[this.method].toUpperCase(),
1094
+ credentials: "same-origin",
1095
+ headers: this.headers,
1096
+ redirect: "follow",
1097
+ body: this.isSafe ? null : this.body,
1098
+ signal: this.abortSignal,
1099
+ referrer: (_a = this.delegate.referrer) === null || _a === void 0 ? void 0 : _a.href
1100
+ };
1101
+ }
1102
+ get defaultHeaders() {
1103
+ return {
1104
+ Accept: "text/html, application/xhtml+xml"
1105
+ };
1106
+ }
1107
+ get isSafe() {
1108
+ return this.method === FetchMethod.get;
1109
+ }
1110
+ get abortSignal() {
1111
+ return this.abortController.signal;
1112
+ }
1113
+ acceptResponseType(mimeType) {
1114
+ this.headers["Accept"] = [mimeType, this.headers["Accept"]].join(", ");
1115
+ }
1116
+ async allowRequestToBeIntercepted(fetchOptions) {
1117
+ const requestInterception = new Promise((resolve) => this.resolveRequestPromise = resolve);
1118
+ const event = dispatch("turbo:before-fetch-request", {
1119
+ cancelable: true,
1120
+ detail: {
1121
+ fetchOptions,
1122
+ url: this.url,
1123
+ resume: this.resolveRequestPromise
1124
+ },
1125
+ target: this.target
1126
+ });
1127
+ if (event.defaultPrevented)
1128
+ await requestInterception;
1129
+ }
1130
+ willDelegateErrorHandling(error) {
1131
+ const event = dispatch("turbo:fetch-request-error", {
1132
+ target: this.target,
1133
+ cancelable: true,
1134
+ detail: { request: this, error }
1135
+ });
1136
+ return !event.defaultPrevented;
1137
+ }
1138
+ };
1139
+ var AppearanceObserver = class {
1140
+ constructor(delegate, element) {
1141
+ this.started = false;
1142
+ this.intersect = (entries) => {
1143
+ const lastEntry = entries.slice(-1)[0];
1144
+ if (lastEntry === null || lastEntry === void 0 ? void 0 : lastEntry.isIntersecting) {
1145
+ this.delegate.elementAppearedInViewport(this.element);
1146
+ }
1147
+ };
1148
+ this.delegate = delegate;
1149
+ this.element = element;
1150
+ this.intersectionObserver = new IntersectionObserver(this.intersect);
1151
+ }
1152
+ start() {
1153
+ if (!this.started) {
1154
+ this.started = true;
1155
+ this.intersectionObserver.observe(this.element);
1156
+ }
1157
+ }
1158
+ stop() {
1159
+ if (this.started) {
1160
+ this.started = false;
1161
+ this.intersectionObserver.unobserve(this.element);
1162
+ }
1163
+ }
1164
+ };
1165
+ var StreamMessage = class {
1166
+ static wrap(message) {
1167
+ if (typeof message == "string") {
1168
+ return new this(createDocumentFragment(message));
1169
+ } else {
1170
+ return message;
1171
+ }
1172
+ }
1173
+ constructor(fragment) {
1174
+ this.fragment = importStreamElements(fragment);
1175
+ }
1176
+ };
1177
+ StreamMessage.contentType = "text/vnd.turbo-stream.html";
1178
+ function importStreamElements(fragment) {
1179
+ for (const element of fragment.querySelectorAll("turbo-stream")) {
1180
+ const streamElement = document.importNode(element, true);
1181
+ for (const inertScriptElement of streamElement.templateElement.content.querySelectorAll("script")) {
1182
+ inertScriptElement.replaceWith(activateScriptElement(inertScriptElement));
1183
+ }
1184
+ element.replaceWith(streamElement);
1185
+ }
1186
+ return fragment;
1187
+ }
1188
+ var FormSubmissionState;
1189
+ (function(FormSubmissionState2) {
1190
+ FormSubmissionState2[FormSubmissionState2["initialized"] = 0] = "initialized";
1191
+ FormSubmissionState2[FormSubmissionState2["requesting"] = 1] = "requesting";
1192
+ FormSubmissionState2[FormSubmissionState2["waiting"] = 2] = "waiting";
1193
+ FormSubmissionState2[FormSubmissionState2["receiving"] = 3] = "receiving";
1194
+ FormSubmissionState2[FormSubmissionState2["stopping"] = 4] = "stopping";
1195
+ FormSubmissionState2[FormSubmissionState2["stopped"] = 5] = "stopped";
1196
+ })(FormSubmissionState || (FormSubmissionState = {}));
1197
+ var FormEnctype;
1198
+ (function(FormEnctype2) {
1199
+ FormEnctype2["urlEncoded"] = "application/x-www-form-urlencoded";
1200
+ FormEnctype2["multipart"] = "multipart/form-data";
1201
+ FormEnctype2["plain"] = "text/plain";
1202
+ })(FormEnctype || (FormEnctype = {}));
1203
+ function formEnctypeFromString(encoding) {
1204
+ switch (encoding.toLowerCase()) {
1205
+ case FormEnctype.multipart:
1206
+ return FormEnctype.multipart;
1207
+ case FormEnctype.plain:
1208
+ return FormEnctype.plain;
1209
+ default:
1210
+ return FormEnctype.urlEncoded;
1211
+ }
1212
+ }
1213
+ var FormSubmission = class _FormSubmission {
1214
+ static confirmMethod(message, _element, _submitter) {
1215
+ return Promise.resolve(confirm(message));
1216
+ }
1217
+ constructor(delegate, formElement, submitter, mustRedirect = false) {
1218
+ this.state = FormSubmissionState.initialized;
1219
+ this.delegate = delegate;
1220
+ this.formElement = formElement;
1221
+ this.submitter = submitter;
1222
+ this.formData = buildFormData(formElement, submitter);
1223
+ this.location = expandURL(this.action);
1224
+ if (this.method == FetchMethod.get) {
1225
+ mergeFormDataEntries(this.location, [...this.body.entries()]);
1226
+ }
1227
+ this.fetchRequest = new FetchRequest(this, this.method, this.location, this.body, this.formElement);
1228
+ this.mustRedirect = mustRedirect;
1229
+ }
1230
+ get method() {
1231
+ var _a;
1232
+ const method = ((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute("formmethod")) || this.formElement.getAttribute("method") || "";
1233
+ return fetchMethodFromString(method.toLowerCase()) || FetchMethod.get;
1234
+ }
1235
+ get action() {
1236
+ var _a;
1237
+ const formElementAction = typeof this.formElement.action === "string" ? this.formElement.action : null;
1238
+ if ((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.hasAttribute("formaction")) {
1239
+ return this.submitter.getAttribute("formaction") || "";
1240
+ } else {
1241
+ return this.formElement.getAttribute("action") || formElementAction || "";
1242
+ }
1243
+ }
1244
+ get body() {
1245
+ if (this.enctype == FormEnctype.urlEncoded || this.method == FetchMethod.get) {
1246
+ return new URLSearchParams(this.stringFormData);
1247
+ } else {
1248
+ return this.formData;
1249
+ }
1250
+ }
1251
+ get enctype() {
1252
+ var _a;
1253
+ return formEnctypeFromString(((_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute("formenctype")) || this.formElement.enctype);
1254
+ }
1255
+ get isSafe() {
1256
+ return this.fetchRequest.isSafe;
1257
+ }
1258
+ get stringFormData() {
1259
+ return [...this.formData].reduce((entries, [name, value]) => {
1260
+ return entries.concat(typeof value == "string" ? [[name, value]] : []);
1261
+ }, []);
1262
+ }
1263
+ async start() {
1264
+ const { initialized, requesting } = FormSubmissionState;
1265
+ const confirmationMessage = getAttribute("data-turbo-confirm", this.submitter, this.formElement);
1266
+ if (typeof confirmationMessage === "string") {
1267
+ const answer = await _FormSubmission.confirmMethod(confirmationMessage, this.formElement, this.submitter);
1268
+ if (!answer) {
1269
+ return;
1270
+ }
1271
+ }
1272
+ if (this.state == initialized) {
1273
+ this.state = requesting;
1274
+ return this.fetchRequest.perform();
1275
+ }
1276
+ }
1277
+ stop() {
1278
+ const { stopping, stopped } = FormSubmissionState;
1279
+ if (this.state != stopping && this.state != stopped) {
1280
+ this.state = stopping;
1281
+ this.fetchRequest.cancel();
1282
+ return true;
1283
+ }
1284
+ }
1285
+ prepareRequest(request) {
1286
+ if (!request.isSafe) {
1287
+ const token = getCookieValue(getMetaContent("csrf-param")) || getMetaContent("csrf-token");
1288
+ if (token) {
1289
+ request.headers["X-CSRF-Token"] = token;
1290
+ }
1291
+ }
1292
+ if (this.requestAcceptsTurboStreamResponse(request)) {
1293
+ request.acceptResponseType(StreamMessage.contentType);
1294
+ }
1295
+ }
1296
+ requestStarted(_request) {
1297
+ var _a;
1298
+ this.state = FormSubmissionState.waiting;
1299
+ (_a = this.submitter) === null || _a === void 0 ? void 0 : _a.setAttribute("disabled", "");
1300
+ this.setSubmitsWith();
1301
+ dispatch("turbo:submit-start", {
1302
+ target: this.formElement,
1303
+ detail: { formSubmission: this }
1304
+ });
1305
+ this.delegate.formSubmissionStarted(this);
1306
+ }
1307
+ requestPreventedHandlingResponse(request, response) {
1308
+ this.result = { success: response.succeeded, fetchResponse: response };
1309
+ }
1310
+ requestSucceededWithResponse(request, response) {
1311
+ if (response.clientError || response.serverError) {
1312
+ this.delegate.formSubmissionFailedWithResponse(this, response);
1313
+ } else if (this.requestMustRedirect(request) && responseSucceededWithoutRedirect(response)) {
1314
+ const error = new Error("Form responses must redirect to another location");
1315
+ this.delegate.formSubmissionErrored(this, error);
1316
+ } else {
1317
+ this.state = FormSubmissionState.receiving;
1318
+ this.result = { success: true, fetchResponse: response };
1319
+ this.delegate.formSubmissionSucceededWithResponse(this, response);
1320
+ }
1321
+ }
1322
+ requestFailedWithResponse(request, response) {
1323
+ this.result = { success: false, fetchResponse: response };
1324
+ this.delegate.formSubmissionFailedWithResponse(this, response);
1325
+ }
1326
+ requestErrored(request, error) {
1327
+ this.result = { success: false, error };
1328
+ this.delegate.formSubmissionErrored(this, error);
1329
+ }
1330
+ requestFinished(_request) {
1331
+ var _a;
1332
+ this.state = FormSubmissionState.stopped;
1333
+ (_a = this.submitter) === null || _a === void 0 ? void 0 : _a.removeAttribute("disabled");
1334
+ this.resetSubmitterText();
1335
+ dispatch("turbo:submit-end", {
1336
+ target: this.formElement,
1337
+ detail: Object.assign({ formSubmission: this }, this.result)
1338
+ });
1339
+ this.delegate.formSubmissionFinished(this);
1340
+ }
1341
+ setSubmitsWith() {
1342
+ if (!this.submitter || !this.submitsWith)
1343
+ return;
1344
+ if (this.submitter.matches("button")) {
1345
+ this.originalSubmitText = this.submitter.innerHTML;
1346
+ this.submitter.innerHTML = this.submitsWith;
1347
+ } else if (this.submitter.matches("input")) {
1348
+ const input = this.submitter;
1349
+ this.originalSubmitText = input.value;
1350
+ input.value = this.submitsWith;
1351
+ }
1352
+ }
1353
+ resetSubmitterText() {
1354
+ if (!this.submitter || !this.originalSubmitText)
1355
+ return;
1356
+ if (this.submitter.matches("button")) {
1357
+ this.submitter.innerHTML = this.originalSubmitText;
1358
+ } else if (this.submitter.matches("input")) {
1359
+ const input = this.submitter;
1360
+ input.value = this.originalSubmitText;
1361
+ }
1362
+ }
1363
+ requestMustRedirect(request) {
1364
+ return !request.isSafe && this.mustRedirect;
1365
+ }
1366
+ requestAcceptsTurboStreamResponse(request) {
1367
+ return !request.isSafe || hasAttribute("data-turbo-stream", this.submitter, this.formElement);
1368
+ }
1369
+ get submitsWith() {
1370
+ var _a;
1371
+ return (_a = this.submitter) === null || _a === void 0 ? void 0 : _a.getAttribute("data-turbo-submits-with");
1372
+ }
1373
+ };
1374
+ function buildFormData(formElement, submitter) {
1375
+ const formData = new FormData(formElement);
1376
+ const name = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("name");
1377
+ const value = submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("value");
1378
+ if (name) {
1379
+ formData.append(name, value || "");
1380
+ }
1381
+ return formData;
1382
+ }
1383
+ function getCookieValue(cookieName) {
1384
+ if (cookieName != null) {
1385
+ const cookies = document.cookie ? document.cookie.split("; ") : [];
1386
+ const cookie = cookies.find((cookie2) => cookie2.startsWith(cookieName));
1387
+ if (cookie) {
1388
+ const value = cookie.split("=").slice(1).join("=");
1389
+ return value ? decodeURIComponent(value) : void 0;
1390
+ }
1391
+ }
1392
+ }
1393
+ function responseSucceededWithoutRedirect(response) {
1394
+ return response.statusCode == 200 && !response.redirected;
1395
+ }
1396
+ function mergeFormDataEntries(url, entries) {
1397
+ const searchParams = new URLSearchParams();
1398
+ for (const [name, value] of entries) {
1399
+ if (value instanceof File)
1400
+ continue;
1401
+ searchParams.append(name, value);
1402
+ }
1403
+ url.search = searchParams.toString();
1404
+ return url;
1405
+ }
1406
+ var Snapshot = class {
1407
+ constructor(element) {
1408
+ this.element = element;
1409
+ }
1410
+ get activeElement() {
1411
+ return this.element.ownerDocument.activeElement;
1412
+ }
1413
+ get children() {
1414
+ return [...this.element.children];
1415
+ }
1416
+ hasAnchor(anchor) {
1417
+ return this.getElementForAnchor(anchor) != null;
1418
+ }
1419
+ getElementForAnchor(anchor) {
1420
+ return anchor ? this.element.querySelector(`[id='${anchor}'], a[name='${anchor}']`) : null;
1421
+ }
1422
+ get isConnected() {
1423
+ return this.element.isConnected;
1424
+ }
1425
+ get firstAutofocusableElement() {
1426
+ const inertDisabledOrHidden = "[inert], :disabled, [hidden], details:not([open]), dialog:not([open])";
1427
+ for (const element of this.element.querySelectorAll("[autofocus]")) {
1428
+ if (element.closest(inertDisabledOrHidden) == null)
1429
+ return element;
1430
+ else
1431
+ continue;
1432
+ }
1433
+ return null;
1434
+ }
1435
+ get permanentElements() {
1436
+ return queryPermanentElementsAll(this.element);
1437
+ }
1438
+ getPermanentElementById(id) {
1439
+ return getPermanentElementById(this.element, id);
1440
+ }
1441
+ getPermanentElementMapForSnapshot(snapshot) {
1442
+ const permanentElementMap = {};
1443
+ for (const currentPermanentElement of this.permanentElements) {
1444
+ const { id } = currentPermanentElement;
1445
+ const newPermanentElement = snapshot.getPermanentElementById(id);
1446
+ if (newPermanentElement) {
1447
+ permanentElementMap[id] = [currentPermanentElement, newPermanentElement];
1448
+ }
1449
+ }
1450
+ return permanentElementMap;
1451
+ }
1452
+ };
1453
+ function getPermanentElementById(node, id) {
1454
+ return node.querySelector(`#${id}[data-turbo-permanent]`);
1455
+ }
1456
+ function queryPermanentElementsAll(node) {
1457
+ return node.querySelectorAll("[id][data-turbo-permanent]");
1458
+ }
1459
+ var FormSubmitObserver = class {
1460
+ constructor(delegate, eventTarget) {
1461
+ this.started = false;
1462
+ this.submitCaptured = () => {
1463
+ this.eventTarget.removeEventListener("submit", this.submitBubbled, false);
1464
+ this.eventTarget.addEventListener("submit", this.submitBubbled, false);
1465
+ };
1466
+ this.submitBubbled = (event) => {
1467
+ if (!event.defaultPrevented) {
1468
+ const form = event.target instanceof HTMLFormElement ? event.target : void 0;
1469
+ const submitter = event.submitter || void 0;
1470
+ if (form && submissionDoesNotDismissDialog(form, submitter) && submissionDoesNotTargetIFrame(form, submitter) && this.delegate.willSubmitForm(form, submitter)) {
1471
+ event.preventDefault();
1472
+ event.stopImmediatePropagation();
1473
+ this.delegate.formSubmitted(form, submitter);
1474
+ }
1475
+ }
1476
+ };
1477
+ this.delegate = delegate;
1478
+ this.eventTarget = eventTarget;
1479
+ }
1480
+ start() {
1481
+ if (!this.started) {
1482
+ this.eventTarget.addEventListener("submit", this.submitCaptured, true);
1483
+ this.started = true;
1484
+ }
1485
+ }
1486
+ stop() {
1487
+ if (this.started) {
1488
+ this.eventTarget.removeEventListener("submit", this.submitCaptured, true);
1489
+ this.started = false;
1490
+ }
1491
+ }
1492
+ };
1493
+ function submissionDoesNotDismissDialog(form, submitter) {
1494
+ const method = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formmethod")) || form.getAttribute("method");
1495
+ return method != "dialog";
1496
+ }
1497
+ function submissionDoesNotTargetIFrame(form, submitter) {
1498
+ if ((submitter === null || submitter === void 0 ? void 0 : submitter.hasAttribute("formtarget")) || form.hasAttribute("target")) {
1499
+ const target = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("formtarget")) || form.target;
1500
+ for (const element of document.getElementsByName(target)) {
1501
+ if (element instanceof HTMLIFrameElement)
1502
+ return false;
1503
+ }
1504
+ return true;
1505
+ } else {
1506
+ return true;
1507
+ }
1508
+ }
1509
+ var View = class {
1510
+ constructor(delegate, element) {
1511
+ this.resolveRenderPromise = (_value) => {
1512
+ };
1513
+ this.resolveInterceptionPromise = (_value) => {
1514
+ };
1515
+ this.delegate = delegate;
1516
+ this.element = element;
1517
+ }
1518
+ scrollToAnchor(anchor) {
1519
+ const element = this.snapshot.getElementForAnchor(anchor);
1520
+ if (element) {
1521
+ this.scrollToElement(element);
1522
+ this.focusElement(element);
1523
+ } else {
1524
+ this.scrollToPosition({ x: 0, y: 0 });
1525
+ }
1526
+ }
1527
+ scrollToAnchorFromLocation(location2) {
1528
+ this.scrollToAnchor(getAnchor(location2));
1529
+ }
1530
+ scrollToElement(element) {
1531
+ element.scrollIntoView();
1532
+ }
1533
+ focusElement(element) {
1534
+ if (element instanceof HTMLElement) {
1535
+ if (element.hasAttribute("tabindex")) {
1536
+ element.focus();
1537
+ } else {
1538
+ element.setAttribute("tabindex", "-1");
1539
+ element.focus();
1540
+ element.removeAttribute("tabindex");
1541
+ }
1542
+ }
1543
+ }
1544
+ scrollToPosition({ x, y }) {
1545
+ this.scrollRoot.scrollTo(x, y);
1546
+ }
1547
+ scrollToTop() {
1548
+ this.scrollToPosition({ x: 0, y: 0 });
1549
+ }
1550
+ get scrollRoot() {
1551
+ return window;
1552
+ }
1553
+ async render(renderer) {
1554
+ const { isPreview, shouldRender, newSnapshot: snapshot } = renderer;
1555
+ if (shouldRender) {
1556
+ try {
1557
+ this.renderPromise = new Promise((resolve) => this.resolveRenderPromise = resolve);
1558
+ this.renderer = renderer;
1559
+ await this.prepareToRenderSnapshot(renderer);
1560
+ const renderInterception = new Promise((resolve) => this.resolveInterceptionPromise = resolve);
1561
+ const options = { resume: this.resolveInterceptionPromise, render: this.renderer.renderElement };
1562
+ const immediateRender = this.delegate.allowsImmediateRender(snapshot, options);
1563
+ if (!immediateRender)
1564
+ await renderInterception;
1565
+ await this.renderSnapshot(renderer);
1566
+ this.delegate.viewRenderedSnapshot(snapshot, isPreview);
1567
+ this.delegate.preloadOnLoadLinksForView(this.element);
1568
+ this.finishRenderingSnapshot(renderer);
1569
+ } finally {
1570
+ delete this.renderer;
1571
+ this.resolveRenderPromise(void 0);
1572
+ delete this.renderPromise;
1573
+ }
1574
+ } else {
1575
+ this.invalidate(renderer.reloadReason);
1576
+ }
1577
+ }
1578
+ invalidate(reason) {
1579
+ this.delegate.viewInvalidated(reason);
1580
+ }
1581
+ async prepareToRenderSnapshot(renderer) {
1582
+ this.markAsPreview(renderer.isPreview);
1583
+ await renderer.prepareToRender();
1584
+ }
1585
+ markAsPreview(isPreview) {
1586
+ if (isPreview) {
1587
+ this.element.setAttribute("data-turbo-preview", "");
1588
+ } else {
1589
+ this.element.removeAttribute("data-turbo-preview");
1590
+ }
1591
+ }
1592
+ async renderSnapshot(renderer) {
1593
+ await renderer.render();
1594
+ }
1595
+ finishRenderingSnapshot(renderer) {
1596
+ renderer.finishRendering();
1597
+ }
1598
+ };
1599
+ var FrameView = class extends View {
1600
+ missing() {
1601
+ this.element.innerHTML = `<strong class="turbo-frame-error">Content missing</strong>`;
1602
+ }
1603
+ get snapshot() {
1604
+ return new Snapshot(this.element);
1605
+ }
1606
+ };
1607
+ var LinkInterceptor = class {
1608
+ constructor(delegate, element) {
1609
+ this.clickBubbled = (event) => {
1610
+ if (this.respondsToEventTarget(event.target)) {
1611
+ this.clickEvent = event;
1612
+ } else {
1613
+ delete this.clickEvent;
1614
+ }
1615
+ };
1616
+ this.linkClicked = (event) => {
1617
+ if (this.clickEvent && this.respondsToEventTarget(event.target) && event.target instanceof Element) {
1618
+ if (this.delegate.shouldInterceptLinkClick(event.target, event.detail.url, event.detail.originalEvent)) {
1619
+ this.clickEvent.preventDefault();
1620
+ event.preventDefault();
1621
+ this.delegate.linkClickIntercepted(event.target, event.detail.url, event.detail.originalEvent);
1622
+ }
1623
+ }
1624
+ delete this.clickEvent;
1625
+ };
1626
+ this.willVisit = (_event) => {
1627
+ delete this.clickEvent;
1628
+ };
1629
+ this.delegate = delegate;
1630
+ this.element = element;
1631
+ }
1632
+ start() {
1633
+ this.element.addEventListener("click", this.clickBubbled);
1634
+ document.addEventListener("turbo:click", this.linkClicked);
1635
+ document.addEventListener("turbo:before-visit", this.willVisit);
1636
+ }
1637
+ stop() {
1638
+ this.element.removeEventListener("click", this.clickBubbled);
1639
+ document.removeEventListener("turbo:click", this.linkClicked);
1640
+ document.removeEventListener("turbo:before-visit", this.willVisit);
1641
+ }
1642
+ respondsToEventTarget(target) {
1643
+ const element = target instanceof Element ? target : target instanceof Node ? target.parentElement : null;
1644
+ return element && element.closest("turbo-frame, html") == this.element;
1645
+ }
1646
+ };
1647
+ var LinkClickObserver = class {
1648
+ constructor(delegate, eventTarget) {
1649
+ this.started = false;
1650
+ this.clickCaptured = () => {
1651
+ this.eventTarget.removeEventListener("click", this.clickBubbled, false);
1652
+ this.eventTarget.addEventListener("click", this.clickBubbled, false);
1653
+ };
1654
+ this.clickBubbled = (event) => {
1655
+ if (event instanceof MouseEvent && this.clickEventIsSignificant(event)) {
1656
+ const target = event.composedPath && event.composedPath()[0] || event.target;
1657
+ const link = this.findLinkFromClickTarget(target);
1658
+ if (link && doesNotTargetIFrame(link)) {
1659
+ const location2 = this.getLocationForLink(link);
1660
+ if (this.delegate.willFollowLinkToLocation(link, location2, event)) {
1661
+ event.preventDefault();
1662
+ this.delegate.followedLinkToLocation(link, location2);
1663
+ }
1664
+ }
1665
+ }
1666
+ };
1667
+ this.delegate = delegate;
1668
+ this.eventTarget = eventTarget;
1669
+ }
1670
+ start() {
1671
+ if (!this.started) {
1672
+ this.eventTarget.addEventListener("click", this.clickCaptured, true);
1673
+ this.started = true;
1674
+ }
1675
+ }
1676
+ stop() {
1677
+ if (this.started) {
1678
+ this.eventTarget.removeEventListener("click", this.clickCaptured, true);
1679
+ this.started = false;
1680
+ }
1681
+ }
1682
+ clickEventIsSignificant(event) {
1683
+ return !(event.target && event.target.isContentEditable || event.defaultPrevented || event.which > 1 || event.altKey || event.ctrlKey || event.metaKey || event.shiftKey);
1684
+ }
1685
+ findLinkFromClickTarget(target) {
1686
+ return findClosestRecursively(target, "a[href]:not([target^=_]):not([download])");
1687
+ }
1688
+ getLocationForLink(link) {
1689
+ return expandURL(link.getAttribute("href") || "");
1690
+ }
1691
+ };
1692
+ function doesNotTargetIFrame(anchor) {
1693
+ if (anchor.hasAttribute("target")) {
1694
+ for (const element of document.getElementsByName(anchor.target)) {
1695
+ if (element instanceof HTMLIFrameElement)
1696
+ return false;
1697
+ }
1698
+ return true;
1699
+ } else {
1700
+ return true;
1701
+ }
1702
+ }
1703
+ var FormLinkClickObserver = class {
1704
+ constructor(delegate, element) {
1705
+ this.delegate = delegate;
1706
+ this.linkInterceptor = new LinkClickObserver(this, element);
1707
+ }
1708
+ start() {
1709
+ this.linkInterceptor.start();
1710
+ }
1711
+ stop() {
1712
+ this.linkInterceptor.stop();
1713
+ }
1714
+ willFollowLinkToLocation(link, location2, originalEvent) {
1715
+ return this.delegate.willSubmitFormLinkToLocation(link, location2, originalEvent) && link.hasAttribute("data-turbo-method");
1716
+ }
1717
+ followedLinkToLocation(link, location2) {
1718
+ const form = document.createElement("form");
1719
+ const type = "hidden";
1720
+ for (const [name, value] of location2.searchParams) {
1721
+ form.append(Object.assign(document.createElement("input"), { type, name, value }));
1722
+ }
1723
+ const action = Object.assign(location2, { search: "" });
1724
+ form.setAttribute("data-turbo", "true");
1725
+ form.setAttribute("action", action.href);
1726
+ form.setAttribute("hidden", "");
1727
+ const method = link.getAttribute("data-turbo-method");
1728
+ if (method)
1729
+ form.setAttribute("method", method);
1730
+ const turboFrame = link.getAttribute("data-turbo-frame");
1731
+ if (turboFrame)
1732
+ form.setAttribute("data-turbo-frame", turboFrame);
1733
+ const turboAction = getVisitAction(link);
1734
+ if (turboAction)
1735
+ form.setAttribute("data-turbo-action", turboAction);
1736
+ const turboConfirm = link.getAttribute("data-turbo-confirm");
1737
+ if (turboConfirm)
1738
+ form.setAttribute("data-turbo-confirm", turboConfirm);
1739
+ const turboStream = link.hasAttribute("data-turbo-stream");
1740
+ if (turboStream)
1741
+ form.setAttribute("data-turbo-stream", "");
1742
+ this.delegate.submittedFormLinkToLocation(link, location2, form);
1743
+ document.body.appendChild(form);
1744
+ form.addEventListener("turbo:submit-end", () => form.remove(), { once: true });
1745
+ requestAnimationFrame(() => form.requestSubmit());
1746
+ }
1747
+ };
1748
+ var Bardo = class {
1749
+ static async preservingPermanentElements(delegate, permanentElementMap, callback) {
1750
+ const bardo = new this(delegate, permanentElementMap);
1751
+ bardo.enter();
1752
+ await callback();
1753
+ bardo.leave();
1754
+ }
1755
+ constructor(delegate, permanentElementMap) {
1756
+ this.delegate = delegate;
1757
+ this.permanentElementMap = permanentElementMap;
1758
+ }
1759
+ enter() {
1760
+ for (const id in this.permanentElementMap) {
1761
+ const [currentPermanentElement, newPermanentElement] = this.permanentElementMap[id];
1762
+ this.delegate.enteringBardo(currentPermanentElement, newPermanentElement);
1763
+ this.replaceNewPermanentElementWithPlaceholder(newPermanentElement);
1764
+ }
1765
+ }
1766
+ leave() {
1767
+ for (const id in this.permanentElementMap) {
1768
+ const [currentPermanentElement] = this.permanentElementMap[id];
1769
+ this.replaceCurrentPermanentElementWithClone(currentPermanentElement);
1770
+ this.replacePlaceholderWithPermanentElement(currentPermanentElement);
1771
+ this.delegate.leavingBardo(currentPermanentElement);
1772
+ }
1773
+ }
1774
+ replaceNewPermanentElementWithPlaceholder(permanentElement) {
1775
+ const placeholder = createPlaceholderForPermanentElement(permanentElement);
1776
+ permanentElement.replaceWith(placeholder);
1777
+ }
1778
+ replaceCurrentPermanentElementWithClone(permanentElement) {
1779
+ const clone = permanentElement.cloneNode(true);
1780
+ permanentElement.replaceWith(clone);
1781
+ }
1782
+ replacePlaceholderWithPermanentElement(permanentElement) {
1783
+ const placeholder = this.getPlaceholderById(permanentElement.id);
1784
+ placeholder === null || placeholder === void 0 ? void 0 : placeholder.replaceWith(permanentElement);
1785
+ }
1786
+ getPlaceholderById(id) {
1787
+ return this.placeholders.find((element) => element.content == id);
1788
+ }
1789
+ get placeholders() {
1790
+ return [...document.querySelectorAll("meta[name=turbo-permanent-placeholder][content]")];
1791
+ }
1792
+ };
1793
+ function createPlaceholderForPermanentElement(permanentElement) {
1794
+ const element = document.createElement("meta");
1795
+ element.setAttribute("name", "turbo-permanent-placeholder");
1796
+ element.setAttribute("content", permanentElement.id);
1797
+ return element;
1798
+ }
1799
+ var Renderer = class {
1800
+ constructor(currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) {
1801
+ this.activeElement = null;
1802
+ this.currentSnapshot = currentSnapshot;
1803
+ this.newSnapshot = newSnapshot;
1804
+ this.isPreview = isPreview;
1805
+ this.willRender = willRender;
1806
+ this.renderElement = renderElement;
1807
+ this.promise = new Promise((resolve, reject) => this.resolvingFunctions = { resolve, reject });
1808
+ }
1809
+ get shouldRender() {
1810
+ return true;
1811
+ }
1812
+ get reloadReason() {
1813
+ return;
1814
+ }
1815
+ prepareToRender() {
1816
+ return;
1817
+ }
1818
+ finishRendering() {
1819
+ if (this.resolvingFunctions) {
1820
+ this.resolvingFunctions.resolve();
1821
+ delete this.resolvingFunctions;
1822
+ }
1823
+ }
1824
+ async preservingPermanentElements(callback) {
1825
+ await Bardo.preservingPermanentElements(this, this.permanentElementMap, callback);
1826
+ }
1827
+ focusFirstAutofocusableElement() {
1828
+ const element = this.connectedSnapshot.firstAutofocusableElement;
1829
+ if (elementIsFocusable(element)) {
1830
+ element.focus();
1831
+ }
1832
+ }
1833
+ enteringBardo(currentPermanentElement) {
1834
+ if (this.activeElement)
1835
+ return;
1836
+ if (currentPermanentElement.contains(this.currentSnapshot.activeElement)) {
1837
+ this.activeElement = this.currentSnapshot.activeElement;
1838
+ }
1839
+ }
1840
+ leavingBardo(currentPermanentElement) {
1841
+ if (currentPermanentElement.contains(this.activeElement) && this.activeElement instanceof HTMLElement) {
1842
+ this.activeElement.focus();
1843
+ this.activeElement = null;
1844
+ }
1845
+ }
1846
+ get connectedSnapshot() {
1847
+ return this.newSnapshot.isConnected ? this.newSnapshot : this.currentSnapshot;
1848
+ }
1849
+ get currentElement() {
1850
+ return this.currentSnapshot.element;
1851
+ }
1852
+ get newElement() {
1853
+ return this.newSnapshot.element;
1854
+ }
1855
+ get permanentElementMap() {
1856
+ return this.currentSnapshot.getPermanentElementMapForSnapshot(this.newSnapshot);
1857
+ }
1858
+ };
1859
+ function elementIsFocusable(element) {
1860
+ return element && typeof element.focus == "function";
1861
+ }
1862
+ var FrameRenderer = class extends Renderer {
1863
+ static renderElement(currentElement, newElement) {
1864
+ var _a;
1865
+ const destinationRange = document.createRange();
1866
+ destinationRange.selectNodeContents(currentElement);
1867
+ destinationRange.deleteContents();
1868
+ const frameElement = newElement;
1869
+ const sourceRange = (_a = frameElement.ownerDocument) === null || _a === void 0 ? void 0 : _a.createRange();
1870
+ if (sourceRange) {
1871
+ sourceRange.selectNodeContents(frameElement);
1872
+ currentElement.appendChild(sourceRange.extractContents());
1873
+ }
1874
+ }
1875
+ constructor(delegate, currentSnapshot, newSnapshot, renderElement, isPreview, willRender = true) {
1876
+ super(currentSnapshot, newSnapshot, renderElement, isPreview, willRender);
1877
+ this.delegate = delegate;
1878
+ }
1879
+ get shouldRender() {
1880
+ return true;
1881
+ }
1882
+ async render() {
1883
+ await nextAnimationFrame();
1884
+ this.preservingPermanentElements(() => {
1885
+ this.loadFrameElement();
1886
+ });
1887
+ this.scrollFrameIntoView();
1888
+ await nextAnimationFrame();
1889
+ this.focusFirstAutofocusableElement();
1890
+ await nextAnimationFrame();
1891
+ this.activateScriptElements();
1892
+ }
1893
+ loadFrameElement() {
1894
+ this.delegate.willRenderFrame(this.currentElement, this.newElement);
1895
+ this.renderElement(this.currentElement, this.newElement);
1896
+ }
1897
+ scrollFrameIntoView() {
1898
+ if (this.currentElement.autoscroll || this.newElement.autoscroll) {
1899
+ const element = this.currentElement.firstElementChild;
1900
+ const block = readScrollLogicalPosition(this.currentElement.getAttribute("data-autoscroll-block"), "end");
1901
+ const behavior = readScrollBehavior(this.currentElement.getAttribute("data-autoscroll-behavior"), "auto");
1902
+ if (element) {
1903
+ element.scrollIntoView({ block, behavior });
1904
+ return true;
1905
+ }
1906
+ }
1907
+ return false;
1908
+ }
1909
+ activateScriptElements() {
1910
+ for (const inertScriptElement of this.newScriptElements) {
1911
+ const activatedScriptElement = activateScriptElement(inertScriptElement);
1912
+ inertScriptElement.replaceWith(activatedScriptElement);
1913
+ }
1914
+ }
1915
+ get newScriptElements() {
1916
+ return this.currentElement.querySelectorAll("script");
1917
+ }
1918
+ };
1919
+ function readScrollLogicalPosition(value, defaultValue) {
1920
+ if (value == "end" || value == "start" || value == "center" || value == "nearest") {
1921
+ return value;
1922
+ } else {
1923
+ return defaultValue;
1924
+ }
1925
+ }
1926
+ function readScrollBehavior(value, defaultValue) {
1927
+ if (value == "auto" || value == "smooth") {
1928
+ return value;
1929
+ } else {
1930
+ return defaultValue;
1931
+ }
1932
+ }
1933
+ var ProgressBar = class _ProgressBar {
1934
+ static get defaultCSS() {
1935
+ return unindent`
1936
+ .turbo-progress-bar {
1937
+ position: fixed;
1938
+ display: block;
1939
+ top: 0;
1940
+ left: 0;
1941
+ height: 3px;
1942
+ background: #0076ff;
1943
+ z-index: 2147483647;
1944
+ transition:
1945
+ width ${_ProgressBar.animationDuration}ms ease-out,
1946
+ opacity ${_ProgressBar.animationDuration / 2}ms ${_ProgressBar.animationDuration / 2}ms ease-in;
1947
+ transform: translate3d(0, 0, 0);
1948
+ }
1949
+ `;
1950
+ }
1951
+ constructor() {
1952
+ this.hiding = false;
1953
+ this.value = 0;
1954
+ this.visible = false;
1955
+ this.trickle = () => {
1956
+ this.setValue(this.value + Math.random() / 100);
1957
+ };
1958
+ this.stylesheetElement = this.createStylesheetElement();
1959
+ this.progressElement = this.createProgressElement();
1960
+ this.installStylesheetElement();
1961
+ this.setValue(0);
1962
+ }
1963
+ show() {
1964
+ if (!this.visible) {
1965
+ this.visible = true;
1966
+ this.installProgressElement();
1967
+ this.startTrickling();
1968
+ }
1969
+ }
1970
+ hide() {
1971
+ if (this.visible && !this.hiding) {
1972
+ this.hiding = true;
1973
+ this.fadeProgressElement(() => {
1974
+ this.uninstallProgressElement();
1975
+ this.stopTrickling();
1976
+ this.visible = false;
1977
+ this.hiding = false;
1978
+ });
1979
+ }
1980
+ }
1981
+ setValue(value) {
1982
+ this.value = value;
1983
+ this.refresh();
1984
+ }
1985
+ installStylesheetElement() {
1986
+ document.head.insertBefore(this.stylesheetElement, document.head.firstChild);
1987
+ }
1988
+ installProgressElement() {
1989
+ this.progressElement.style.width = "0";
1990
+ this.progressElement.style.opacity = "1";
1991
+ document.documentElement.insertBefore(this.progressElement, document.body);
1992
+ this.refresh();
1993
+ }
1994
+ fadeProgressElement(callback) {
1995
+ this.progressElement.style.opacity = "0";
1996
+ setTimeout(callback, _ProgressBar.animationDuration * 1.5);
1997
+ }
1998
+ uninstallProgressElement() {
1999
+ if (this.progressElement.parentNode) {
2000
+ document.documentElement.removeChild(this.progressElement);
2001
+ }
2002
+ }
2003
+ startTrickling() {
2004
+ if (!this.trickleInterval) {
2005
+ this.trickleInterval = window.setInterval(this.trickle, _ProgressBar.animationDuration);
2006
+ }
2007
+ }
2008
+ stopTrickling() {
2009
+ window.clearInterval(this.trickleInterval);
2010
+ delete this.trickleInterval;
2011
+ }
2012
+ refresh() {
2013
+ requestAnimationFrame(() => {
2014
+ this.progressElement.style.width = `${10 + this.value * 90}%`;
2015
+ });
2016
+ }
2017
+ createStylesheetElement() {
2018
+ const element = document.createElement("style");
2019
+ element.type = "text/css";
2020
+ element.textContent = _ProgressBar.defaultCSS;
2021
+ if (this.cspNonce) {
2022
+ element.nonce = this.cspNonce;
2023
+ }
2024
+ return element;
2025
+ }
2026
+ createProgressElement() {
2027
+ const element = document.createElement("div");
2028
+ element.className = "turbo-progress-bar";
2029
+ return element;
2030
+ }
2031
+ get cspNonce() {
2032
+ return getMetaContent("csp-nonce");
2033
+ }
2034
+ };
2035
+ ProgressBar.animationDuration = 300;
2036
+ var HeadSnapshot = class extends Snapshot {
2037
+ constructor() {
2038
+ super(...arguments);
2039
+ this.detailsByOuterHTML = this.children.filter((element) => !elementIsNoscript(element)).map((element) => elementWithoutNonce(element)).reduce((result, element) => {
2040
+ const { outerHTML } = element;
2041
+ const details = outerHTML in result ? result[outerHTML] : {
2042
+ type: elementType(element),
2043
+ tracked: elementIsTracked(element),
2044
+ elements: []
2045
+ };
2046
+ return Object.assign(Object.assign({}, result), { [outerHTML]: Object.assign(Object.assign({}, details), { elements: [...details.elements, element] }) });
2047
+ }, {});
2048
+ }
2049
+ get trackedElementSignature() {
2050
+ return Object.keys(this.detailsByOuterHTML).filter((outerHTML) => this.detailsByOuterHTML[outerHTML].tracked).join("");
2051
+ }
2052
+ getScriptElementsNotInSnapshot(snapshot) {
2053
+ return this.getElementsMatchingTypeNotInSnapshot("script", snapshot);
2054
+ }
2055
+ getStylesheetElementsNotInSnapshot(snapshot) {
2056
+ return this.getElementsMatchingTypeNotInSnapshot("stylesheet", snapshot);
2057
+ }
2058
+ getElementsMatchingTypeNotInSnapshot(matchedType, snapshot) {
2059
+ return Object.keys(this.detailsByOuterHTML).filter((outerHTML) => !(outerHTML in snapshot.detailsByOuterHTML)).map((outerHTML) => this.detailsByOuterHTML[outerHTML]).filter(({ type }) => type == matchedType).map(({ elements: [element] }) => element);
2060
+ }
2061
+ get provisionalElements() {
2062
+ return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => {
2063
+ const { type, tracked, elements } = this.detailsByOuterHTML[outerHTML];
2064
+ if (type == null && !tracked) {
2065
+ return [...result, ...elements];
2066
+ } else if (elements.length > 1) {
2067
+ return [...result, ...elements.slice(1)];
2068
+ } else {
2069
+ return result;
2070
+ }
2071
+ }, []);
2072
+ }
2073
+ getMetaValue(name) {
2074
+ const element = this.findMetaElementByName(name);
2075
+ return element ? element.getAttribute("content") : null;
2076
+ }
2077
+ findMetaElementByName(name) {
2078
+ return Object.keys(this.detailsByOuterHTML).reduce((result, outerHTML) => {
2079
+ const { elements: [element] } = this.detailsByOuterHTML[outerHTML];
2080
+ return elementIsMetaElementWithName(element, name) ? element : result;
2081
+ }, void 0);
2082
+ }
2083
+ };
2084
+ function elementType(element) {
2085
+ if (elementIsScript(element)) {
2086
+ return "script";
2087
+ } else if (elementIsStylesheet(element)) {
2088
+ return "stylesheet";
2089
+ }
2090
+ }
2091
+ function elementIsTracked(element) {
2092
+ return element.getAttribute("data-turbo-track") == "reload";
2093
+ }
2094
+ function elementIsScript(element) {
2095
+ const tagName = element.localName;
2096
+ return tagName == "script";
2097
+ }
2098
+ function elementIsNoscript(element) {
2099
+ const tagName = element.localName;
2100
+ return tagName == "noscript";
2101
+ }
2102
+ function elementIsStylesheet(element) {
2103
+ const tagName = element.localName;
2104
+ return tagName == "style" || tagName == "link" && element.getAttribute("rel") == "stylesheet";
2105
+ }
2106
+ function elementIsMetaElementWithName(element, name) {
2107
+ const tagName = element.localName;
2108
+ return tagName == "meta" && element.getAttribute("name") == name;
2109
+ }
2110
+ function elementWithoutNonce(element) {
2111
+ if (element.hasAttribute("nonce")) {
2112
+ element.setAttribute("nonce", "");
2113
+ }
2114
+ return element;
2115
+ }
2116
+ var PageSnapshot = class _PageSnapshot extends Snapshot {
2117
+ static fromHTMLString(html = "") {
2118
+ return this.fromDocument(parseHTMLDocument(html));
2119
+ }
2120
+ static fromElement(element) {
2121
+ return this.fromDocument(element.ownerDocument);
2122
+ }
2123
+ static fromDocument({ head, body }) {
2124
+ return new this(body, new HeadSnapshot(head));
2125
+ }
2126
+ constructor(element, headSnapshot) {
2127
+ super(element);
2128
+ this.headSnapshot = headSnapshot;
2129
+ }
2130
+ clone() {
2131
+ const clonedElement = this.element.cloneNode(true);
2132
+ const selectElements = this.element.querySelectorAll("select");
2133
+ const clonedSelectElements = clonedElement.querySelectorAll("select");
2134
+ for (const [index, source] of selectElements.entries()) {
2135
+ const clone = clonedSelectElements[index];
2136
+ for (const option of clone.selectedOptions)
2137
+ option.selected = false;
2138
+ for (const option of source.selectedOptions)
2139
+ clone.options[option.index].selected = true;
2140
+ }
2141
+ for (const clonedPasswordInput of clonedElement.querySelectorAll('input[type="password"]')) {
2142
+ clonedPasswordInput.value = "";
2143
+ }
2144
+ return new _PageSnapshot(clonedElement, this.headSnapshot);
2145
+ }
2146
+ get headElement() {
2147
+ return this.headSnapshot.element;
2148
+ }
2149
+ get rootLocation() {
2150
+ var _a;
2151
+ const root = (_a = this.getSetting("root")) !== null && _a !== void 0 ? _a : "/";
2152
+ return expandURL(root);
2153
+ }
2154
+ get cacheControlValue() {
2155
+ return this.getSetting("cache-control");
2156
+ }
2157
+ get isPreviewable() {
2158
+ return this.cacheControlValue != "no-preview";
2159
+ }
2160
+ get isCacheable() {
2161
+ return this.cacheControlValue != "no-cache";
2162
+ }
2163
+ get isVisitable() {
2164
+ return this.getSetting("visit-control") != "reload";
2165
+ }
2166
+ getSetting(name) {
2167
+ return this.headSnapshot.getMetaValue(`turbo-${name}`);
2168
+ }
2169
+ };
2170
+ var TimingMetric;
2171
+ (function(TimingMetric2) {
2172
+ TimingMetric2["visitStart"] = "visitStart";
2173
+ TimingMetric2["requestStart"] = "requestStart";
2174
+ TimingMetric2["requestEnd"] = "requestEnd";
2175
+ TimingMetric2["visitEnd"] = "visitEnd";
2176
+ })(TimingMetric || (TimingMetric = {}));
2177
+ var VisitState;
2178
+ (function(VisitState2) {
2179
+ VisitState2["initialized"] = "initialized";
2180
+ VisitState2["started"] = "started";
2181
+ VisitState2["canceled"] = "canceled";
2182
+ VisitState2["failed"] = "failed";
2183
+ VisitState2["completed"] = "completed";
2184
+ })(VisitState || (VisitState = {}));
2185
+ var defaultOptions = {
2186
+ action: "advance",
2187
+ historyChanged: false,
2188
+ visitCachedSnapshot: () => {
2189
+ },
2190
+ willRender: true,
2191
+ updateHistory: true,
2192
+ shouldCacheSnapshot: true,
2193
+ acceptsStreamResponse: false
2194
+ };
2195
+ var SystemStatusCode;
2196
+ (function(SystemStatusCode2) {
2197
+ SystemStatusCode2[SystemStatusCode2["networkFailure"] = 0] = "networkFailure";
2198
+ SystemStatusCode2[SystemStatusCode2["timeoutFailure"] = -1] = "timeoutFailure";
2199
+ SystemStatusCode2[SystemStatusCode2["contentTypeMismatch"] = -2] = "contentTypeMismatch";
2200
+ })(SystemStatusCode || (SystemStatusCode = {}));
2201
+ var Visit = class {
2202
+ constructor(delegate, location2, restorationIdentifier, options = {}) {
2203
+ this.identifier = uuid();
2204
+ this.timingMetrics = {};
2205
+ this.followedRedirect = false;
2206
+ this.historyChanged = false;
2207
+ this.scrolled = false;
2208
+ this.shouldCacheSnapshot = true;
2209
+ this.acceptsStreamResponse = false;
2210
+ this.snapshotCached = false;
2211
+ this.state = VisitState.initialized;
2212
+ this.delegate = delegate;
2213
+ this.location = location2;
2214
+ this.restorationIdentifier = restorationIdentifier || uuid();
2215
+ const { action, historyChanged, referrer, snapshot, snapshotHTML, response, visitCachedSnapshot, willRender, updateHistory, shouldCacheSnapshot, acceptsStreamResponse } = Object.assign(Object.assign({}, defaultOptions), options);
2216
+ this.action = action;
2217
+ this.historyChanged = historyChanged;
2218
+ this.referrer = referrer;
2219
+ this.snapshot = snapshot;
2220
+ this.snapshotHTML = snapshotHTML;
2221
+ this.response = response;
2222
+ this.isSamePage = this.delegate.locationWithActionIsSamePage(this.location, this.action);
2223
+ this.visitCachedSnapshot = visitCachedSnapshot;
2224
+ this.willRender = willRender;
2225
+ this.updateHistory = updateHistory;
2226
+ this.scrolled = !willRender;
2227
+ this.shouldCacheSnapshot = shouldCacheSnapshot;
2228
+ this.acceptsStreamResponse = acceptsStreamResponse;
2229
+ }
2230
+ get adapter() {
2231
+ return this.delegate.adapter;
2232
+ }
2233
+ get view() {
2234
+ return this.delegate.view;
2235
+ }
2236
+ get history() {
2237
+ return this.delegate.history;
2238
+ }
2239
+ get restorationData() {
2240
+ return this.history.getRestorationDataForIdentifier(this.restorationIdentifier);
2241
+ }
2242
+ get silent() {
2243
+ return this.isSamePage;
2244
+ }
2245
+ start() {
2246
+ if (this.state == VisitState.initialized) {
2247
+ this.recordTimingMetric(TimingMetric.visitStart);
2248
+ this.state = VisitState.started;
2249
+ this.adapter.visitStarted(this);
2250
+ this.delegate.visitStarted(this);
2251
+ }
2252
+ }
2253
+ cancel() {
2254
+ if (this.state == VisitState.started) {
2255
+ if (this.request) {
2256
+ this.request.cancel();
2257
+ }
2258
+ this.cancelRender();
2259
+ this.state = VisitState.canceled;
2260
+ }
2261
+ }
2262
+ complete() {
2263
+ if (this.state == VisitState.started) {
2264
+ this.recordTimingMetric(TimingMetric.visitEnd);
2265
+ this.state = VisitState.completed;
2266
+ this.followRedirect();
2267
+ if (!this.followedRedirect) {
2268
+ this.adapter.visitCompleted(this);
2269
+ this.delegate.visitCompleted(this);
2270
+ }
2271
+ }
2272
+ }
2273
+ fail() {
2274
+ if (this.state == VisitState.started) {
2275
+ this.state = VisitState.failed;
2276
+ this.adapter.visitFailed(this);
2277
+ }
2278
+ }
2279
+ changeHistory() {
2280
+ var _a;
2281
+ if (!this.historyChanged && this.updateHistory) {
2282
+ const actionForHistory = this.location.href === ((_a = this.referrer) === null || _a === void 0 ? void 0 : _a.href) ? "replace" : this.action;
2283
+ const method = getHistoryMethodForAction(actionForHistory);
2284
+ this.history.update(method, this.location, this.restorationIdentifier);
2285
+ this.historyChanged = true;
2286
+ }
2287
+ }
2288
+ issueRequest() {
2289
+ if (this.hasPreloadedResponse()) {
2290
+ this.simulateRequest();
2291
+ } else if (this.shouldIssueRequest() && !this.request) {
2292
+ this.request = new FetchRequest(this, FetchMethod.get, this.location);
2293
+ this.request.perform();
2294
+ }
2295
+ }
2296
+ simulateRequest() {
2297
+ if (this.response) {
2298
+ this.startRequest();
2299
+ this.recordResponse();
2300
+ this.finishRequest();
2301
+ }
2302
+ }
2303
+ startRequest() {
2304
+ this.recordTimingMetric(TimingMetric.requestStart);
2305
+ this.adapter.visitRequestStarted(this);
2306
+ }
2307
+ recordResponse(response = this.response) {
2308
+ this.response = response;
2309
+ if (response) {
2310
+ const { statusCode } = response;
2311
+ if (isSuccessful(statusCode)) {
2312
+ this.adapter.visitRequestCompleted(this);
2313
+ } else {
2314
+ this.adapter.visitRequestFailedWithStatusCode(this, statusCode);
2315
+ }
2316
+ }
2317
+ }
2318
+ finishRequest() {
2319
+ this.recordTimingMetric(TimingMetric.requestEnd);
2320
+ this.adapter.visitRequestFinished(this);
2321
+ }
2322
+ loadResponse() {
2323
+ if (this.response) {
2324
+ const { statusCode, responseHTML } = this.response;
2325
+ this.render(async () => {
2326
+ if (this.shouldCacheSnapshot)
2327
+ this.cacheSnapshot();
2328
+ if (this.view.renderPromise)
2329
+ await this.view.renderPromise;
2330
+ if (isSuccessful(statusCode) && responseHTML != null) {
2331
+ await this.view.renderPage(PageSnapshot.fromHTMLString(responseHTML), false, this.willRender, this);
2332
+ this.performScroll();
2333
+ this.adapter.visitRendered(this);
2334
+ this.complete();
2335
+ } else {
2336
+ await this.view.renderError(PageSnapshot.fromHTMLString(responseHTML), this);
2337
+ this.adapter.visitRendered(this);
2338
+ this.fail();
2339
+ }
2340
+ });
2341
+ }
2342
+ }
2343
+ getCachedSnapshot() {
2344
+ const snapshot = this.view.getCachedSnapshotForLocation(this.location) || this.getPreloadedSnapshot();
2345
+ if (snapshot && (!getAnchor(this.location) || snapshot.hasAnchor(getAnchor(this.location)))) {
2346
+ if (this.action == "restore" || snapshot.isPreviewable) {
2347
+ return snapshot;
2348
+ }
2349
+ }
2350
+ }
2351
+ getPreloadedSnapshot() {
2352
+ if (this.snapshotHTML) {
2353
+ return PageSnapshot.fromHTMLString(this.snapshotHTML);
2354
+ }
2355
+ }
2356
+ hasCachedSnapshot() {
2357
+ return this.getCachedSnapshot() != null;
2358
+ }
2359
+ loadCachedSnapshot() {
2360
+ const snapshot = this.getCachedSnapshot();
2361
+ if (snapshot) {
2362
+ const isPreview = this.shouldIssueRequest();
2363
+ this.render(async () => {
2364
+ this.cacheSnapshot();
2365
+ if (this.isSamePage) {
2366
+ this.adapter.visitRendered(this);
2367
+ } else {
2368
+ if (this.view.renderPromise)
2369
+ await this.view.renderPromise;
2370
+ await this.view.renderPage(snapshot, isPreview, this.willRender, this);
2371
+ this.performScroll();
2372
+ this.adapter.visitRendered(this);
2373
+ if (!isPreview) {
2374
+ this.complete();
2375
+ }
2376
+ }
2377
+ });
2378
+ }
2379
+ }
2380
+ followRedirect() {
2381
+ var _a;
2382
+ if (this.redirectedToLocation && !this.followedRedirect && ((_a = this.response) === null || _a === void 0 ? void 0 : _a.redirected)) {
2383
+ this.adapter.visitProposedToLocation(this.redirectedToLocation, {
2384
+ action: "replace",
2385
+ response: this.response,
2386
+ shouldCacheSnapshot: false,
2387
+ willRender: false
2388
+ });
2389
+ this.followedRedirect = true;
2390
+ }
2391
+ }
2392
+ goToSamePageAnchor() {
2393
+ if (this.isSamePage) {
2394
+ this.render(async () => {
2395
+ this.cacheSnapshot();
2396
+ this.performScroll();
2397
+ this.changeHistory();
2398
+ this.adapter.visitRendered(this);
2399
+ });
2400
+ }
2401
+ }
2402
+ prepareRequest(request) {
2403
+ if (this.acceptsStreamResponse) {
2404
+ request.acceptResponseType(StreamMessage.contentType);
2405
+ }
2406
+ }
2407
+ requestStarted() {
2408
+ this.startRequest();
2409
+ }
2410
+ requestPreventedHandlingResponse(_request, _response) {
2411
+ }
2412
+ async requestSucceededWithResponse(request, response) {
2413
+ const responseHTML = await response.responseHTML;
2414
+ const { redirected, statusCode } = response;
2415
+ if (responseHTML == void 0) {
2416
+ this.recordResponse({
2417
+ statusCode: SystemStatusCode.contentTypeMismatch,
2418
+ redirected
2419
+ });
2420
+ } else {
2421
+ this.redirectedToLocation = response.redirected ? response.location : void 0;
2422
+ this.recordResponse({ statusCode, responseHTML, redirected });
2423
+ }
2424
+ }
2425
+ async requestFailedWithResponse(request, response) {
2426
+ const responseHTML = await response.responseHTML;
2427
+ const { redirected, statusCode } = response;
2428
+ if (responseHTML == void 0) {
2429
+ this.recordResponse({
2430
+ statusCode: SystemStatusCode.contentTypeMismatch,
2431
+ redirected
2432
+ });
2433
+ } else {
2434
+ this.recordResponse({ statusCode, responseHTML, redirected });
2435
+ }
2436
+ }
2437
+ requestErrored(_request, _error) {
2438
+ this.recordResponse({
2439
+ statusCode: SystemStatusCode.networkFailure,
2440
+ redirected: false
2441
+ });
2442
+ }
2443
+ requestFinished() {
2444
+ this.finishRequest();
2445
+ }
2446
+ performScroll() {
2447
+ if (!this.scrolled && !this.view.forceReloaded) {
2448
+ if (this.action == "restore") {
2449
+ this.scrollToRestoredPosition() || this.scrollToAnchor() || this.view.scrollToTop();
2450
+ } else {
2451
+ this.scrollToAnchor() || this.view.scrollToTop();
2452
+ }
2453
+ if (this.isSamePage) {
2454
+ this.delegate.visitScrolledToSamePageLocation(this.view.lastRenderedLocation, this.location);
2455
+ }
2456
+ this.scrolled = true;
2457
+ }
2458
+ }
2459
+ scrollToRestoredPosition() {
2460
+ const { scrollPosition } = this.restorationData;
2461
+ if (scrollPosition) {
2462
+ this.view.scrollToPosition(scrollPosition);
2463
+ return true;
2464
+ }
2465
+ }
2466
+ scrollToAnchor() {
2467
+ const anchor = getAnchor(this.location);
2468
+ if (anchor != null) {
2469
+ this.view.scrollToAnchor(anchor);
2470
+ return true;
2471
+ }
2472
+ }
2473
+ recordTimingMetric(metric) {
2474
+ this.timingMetrics[metric] = (/* @__PURE__ */ new Date()).getTime();
2475
+ }
2476
+ getTimingMetrics() {
2477
+ return Object.assign({}, this.timingMetrics);
2478
+ }
2479
+ getHistoryMethodForAction(action) {
2480
+ switch (action) {
2481
+ case "replace":
2482
+ return history.replaceState;
2483
+ case "advance":
2484
+ case "restore":
2485
+ return history.pushState;
2486
+ }
2487
+ }
2488
+ hasPreloadedResponse() {
2489
+ return typeof this.response == "object";
2490
+ }
2491
+ shouldIssueRequest() {
2492
+ if (this.isSamePage) {
2493
+ return false;
2494
+ } else if (this.action == "restore") {
2495
+ return !this.hasCachedSnapshot();
2496
+ } else {
2497
+ return this.willRender;
2498
+ }
2499
+ }
2500
+ cacheSnapshot() {
2501
+ if (!this.snapshotCached) {
2502
+ this.view.cacheSnapshot(this.snapshot).then((snapshot) => snapshot && this.visitCachedSnapshot(snapshot));
2503
+ this.snapshotCached = true;
2504
+ }
2505
+ }
2506
+ async render(callback) {
2507
+ this.cancelRender();
2508
+ await new Promise((resolve) => {
2509
+ this.frame = requestAnimationFrame(() => resolve());
2510
+ });
2511
+ await callback();
2512
+ delete this.frame;
2513
+ }
2514
+ cancelRender() {
2515
+ if (this.frame) {
2516
+ cancelAnimationFrame(this.frame);
2517
+ delete this.frame;
2518
+ }
2519
+ }
2520
+ };
2521
+ function isSuccessful(statusCode) {
2522
+ return statusCode >= 200 && statusCode < 300;
2523
+ }
2524
+ var BrowserAdapter = class {
2525
+ constructor(session2) {
2526
+ this.progressBar = new ProgressBar();
2527
+ this.showProgressBar = () => {
2528
+ this.progressBar.show();
2529
+ };
2530
+ this.session = session2;
2531
+ }
2532
+ visitProposedToLocation(location2, options) {
2533
+ this.navigator.startVisit(location2, (options === null || options === void 0 ? void 0 : options.restorationIdentifier) || uuid(), options);
2534
+ }
2535
+ visitStarted(visit2) {
2536
+ this.location = visit2.location;
2537
+ visit2.loadCachedSnapshot();
2538
+ visit2.issueRequest();
2539
+ visit2.goToSamePageAnchor();
2540
+ }
2541
+ visitRequestStarted(visit2) {
2542
+ this.progressBar.setValue(0);
2543
+ if (visit2.hasCachedSnapshot() || visit2.action != "restore") {
2544
+ this.showVisitProgressBarAfterDelay();
2545
+ } else {
2546
+ this.showProgressBar();
2547
+ }
2548
+ }
2549
+ visitRequestCompleted(visit2) {
2550
+ visit2.loadResponse();
2551
+ }
2552
+ visitRequestFailedWithStatusCode(visit2, statusCode) {
2553
+ switch (statusCode) {
2554
+ case SystemStatusCode.networkFailure:
2555
+ case SystemStatusCode.timeoutFailure:
2556
+ case SystemStatusCode.contentTypeMismatch:
2557
+ return this.reload({
2558
+ reason: "request_failed",
2559
+ context: {
2560
+ statusCode
2561
+ }
2562
+ });
2563
+ default:
2564
+ return visit2.loadResponse();
2565
+ }
2566
+ }
2567
+ visitRequestFinished(_visit) {
2568
+ this.progressBar.setValue(1);
2569
+ this.hideVisitProgressBar();
2570
+ }
2571
+ visitCompleted(_visit) {
2572
+ }
2573
+ pageInvalidated(reason) {
2574
+ this.reload(reason);
2575
+ }
2576
+ visitFailed(_visit) {
2577
+ }
2578
+ visitRendered(_visit) {
2579
+ }
2580
+ formSubmissionStarted(_formSubmission) {
2581
+ this.progressBar.setValue(0);
2582
+ this.showFormProgressBarAfterDelay();
2583
+ }
2584
+ formSubmissionFinished(_formSubmission) {
2585
+ this.progressBar.setValue(1);
2586
+ this.hideFormProgressBar();
2587
+ }
2588
+ showVisitProgressBarAfterDelay() {
2589
+ this.visitProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);
2590
+ }
2591
+ hideVisitProgressBar() {
2592
+ this.progressBar.hide();
2593
+ if (this.visitProgressBarTimeout != null) {
2594
+ window.clearTimeout(this.visitProgressBarTimeout);
2595
+ delete this.visitProgressBarTimeout;
2596
+ }
2597
+ }
2598
+ showFormProgressBarAfterDelay() {
2599
+ if (this.formProgressBarTimeout == null) {
2600
+ this.formProgressBarTimeout = window.setTimeout(this.showProgressBar, this.session.progressBarDelay);
2601
+ }
2602
+ }
2603
+ hideFormProgressBar() {
2604
+ this.progressBar.hide();
2605
+ if (this.formProgressBarTimeout != null) {
2606
+ window.clearTimeout(this.formProgressBarTimeout);
2607
+ delete this.formProgressBarTimeout;
2608
+ }
2609
+ }
2610
+ reload(reason) {
2611
+ var _a;
2612
+ dispatch("turbo:reload", { detail: reason });
2613
+ window.location.href = ((_a = this.location) === null || _a === void 0 ? void 0 : _a.toString()) || window.location.href;
2614
+ }
2615
+ get navigator() {
2616
+ return this.session.navigator;
2617
+ }
2618
+ };
2619
+ var CacheObserver = class {
2620
+ constructor() {
2621
+ this.selector = "[data-turbo-temporary]";
2622
+ this.deprecatedSelector = "[data-turbo-cache=false]";
2623
+ this.started = false;
2624
+ this.removeTemporaryElements = (_event) => {
2625
+ for (const element of this.temporaryElements) {
2626
+ element.remove();
2627
+ }
2628
+ };
2629
+ }
2630
+ start() {
2631
+ if (!this.started) {
2632
+ this.started = true;
2633
+ addEventListener("turbo:before-cache", this.removeTemporaryElements, false);
2634
+ }
2635
+ }
2636
+ stop() {
2637
+ if (this.started) {
2638
+ this.started = false;
2639
+ removeEventListener("turbo:before-cache", this.removeTemporaryElements, false);
2640
+ }
2641
+ }
2642
+ get temporaryElements() {
2643
+ return [...document.querySelectorAll(this.selector), ...this.temporaryElementsWithDeprecation];
2644
+ }
2645
+ get temporaryElementsWithDeprecation() {
2646
+ const elements = document.querySelectorAll(this.deprecatedSelector);
2647
+ if (elements.length) {
2648
+ console.warn(`The ${this.deprecatedSelector} selector is deprecated and will be removed in a future version. Use ${this.selector} instead.`);
2649
+ }
2650
+ return [...elements];
2651
+ }
2652
+ };
2653
+ var FrameRedirector = class {
2654
+ constructor(session2, element) {
2655
+ this.session = session2;
2656
+ this.element = element;
2657
+ this.linkInterceptor = new LinkInterceptor(this, element);
2658
+ this.formSubmitObserver = new FormSubmitObserver(this, element);
2659
+ }
2660
+ start() {
2661
+ this.linkInterceptor.start();
2662
+ this.formSubmitObserver.start();
2663
+ }
2664
+ stop() {
2665
+ this.linkInterceptor.stop();
2666
+ this.formSubmitObserver.stop();
2667
+ }
2668
+ shouldInterceptLinkClick(element, _location, _event) {
2669
+ return this.shouldRedirect(element);
2670
+ }
2671
+ linkClickIntercepted(element, url, event) {
2672
+ const frame = this.findFrameElement(element);
2673
+ if (frame) {
2674
+ frame.delegate.linkClickIntercepted(element, url, event);
2675
+ }
2676
+ }
2677
+ willSubmitForm(element, submitter) {
2678
+ return element.closest("turbo-frame") == null && this.shouldSubmit(element, submitter) && this.shouldRedirect(element, submitter);
2679
+ }
2680
+ formSubmitted(element, submitter) {
2681
+ const frame = this.findFrameElement(element, submitter);
2682
+ if (frame) {
2683
+ frame.delegate.formSubmitted(element, submitter);
2684
+ }
2685
+ }
2686
+ shouldSubmit(form, submitter) {
2687
+ var _a;
2688
+ const action = getAction(form, submitter);
2689
+ const meta = this.element.ownerDocument.querySelector(`meta[name="turbo-root"]`);
2690
+ const rootLocation = expandURL((_a = meta === null || meta === void 0 ? void 0 : meta.content) !== null && _a !== void 0 ? _a : "/");
2691
+ return this.shouldRedirect(form, submitter) && locationIsVisitable(action, rootLocation);
2692
+ }
2693
+ shouldRedirect(element, submitter) {
2694
+ const isNavigatable = element instanceof HTMLFormElement ? this.session.submissionIsNavigatable(element, submitter) : this.session.elementIsNavigatable(element);
2695
+ if (isNavigatable) {
2696
+ const frame = this.findFrameElement(element, submitter);
2697
+ return frame ? frame != element.closest("turbo-frame") : false;
2698
+ } else {
2699
+ return false;
2700
+ }
2701
+ }
2702
+ findFrameElement(element, submitter) {
2703
+ const id = (submitter === null || submitter === void 0 ? void 0 : submitter.getAttribute("data-turbo-frame")) || element.getAttribute("data-turbo-frame");
2704
+ if (id && id != "_top") {
2705
+ const frame = this.element.querySelector(`#${id}:not([disabled])`);
2706
+ if (frame instanceof FrameElement) {
2707
+ return frame;
2708
+ }
2709
+ }
2710
+ }
2711
+ };
2712
+ var History = class {
2713
+ constructor(delegate) {
2714
+ this.restorationIdentifier = uuid();
2715
+ this.restorationData = {};
2716
+ this.started = false;
2717
+ this.pageLoaded = false;
2718
+ this.onPopState = (event) => {
2719
+ if (this.shouldHandlePopState()) {
2720
+ const { turbo } = event.state || {};
2721
+ if (turbo) {
2722
+ this.location = new URL(window.location.href);
2723
+ const { restorationIdentifier } = turbo;
2724
+ this.restorationIdentifier = restorationIdentifier;
2725
+ this.delegate.historyPoppedToLocationWithRestorationIdentifier(this.location, restorationIdentifier);
2726
+ }
2727
+ }
2728
+ };
2729
+ this.onPageLoad = async (_event) => {
2730
+ await nextMicrotask();
2731
+ this.pageLoaded = true;
2732
+ };
2733
+ this.delegate = delegate;
2734
+ }
2735
+ start() {
2736
+ if (!this.started) {
2737
+ addEventListener("popstate", this.onPopState, false);
2738
+ addEventListener("load", this.onPageLoad, false);
2739
+ this.started = true;
2740
+ this.replace(new URL(window.location.href));
2741
+ }
2742
+ }
2743
+ stop() {
2744
+ if (this.started) {
2745
+ removeEventListener("popstate", this.onPopState, false);
2746
+ removeEventListener("load", this.onPageLoad, false);
2747
+ this.started = false;
2748
+ }
2749
+ }
2750
+ push(location2, restorationIdentifier) {
2751
+ this.update(history.pushState, location2, restorationIdentifier);
2752
+ }
2753
+ replace(location2, restorationIdentifier) {
2754
+ this.update(history.replaceState, location2, restorationIdentifier);
2755
+ }
2756
+ update(method, location2, restorationIdentifier = uuid()) {
2757
+ const state = { turbo: { restorationIdentifier } };
2758
+ method.call(history, state, "", location2.href);
2759
+ this.location = location2;
2760
+ this.restorationIdentifier = restorationIdentifier;
2761
+ }
2762
+ getRestorationDataForIdentifier(restorationIdentifier) {
2763
+ return this.restorationData[restorationIdentifier] || {};
2764
+ }
2765
+ updateRestorationData(additionalData) {
2766
+ const { restorationIdentifier } = this;
2767
+ const restorationData = this.restorationData[restorationIdentifier];
2768
+ this.restorationData[restorationIdentifier] = Object.assign(Object.assign({}, restorationData), additionalData);
2769
+ }
2770
+ assumeControlOfScrollRestoration() {
2771
+ var _a;
2772
+ if (!this.previousScrollRestoration) {
2773
+ this.previousScrollRestoration = (_a = history.scrollRestoration) !== null && _a !== void 0 ? _a : "auto";
2774
+ history.scrollRestoration = "manual";
2775
+ }
2776
+ }
2777
+ relinquishControlOfScrollRestoration() {
2778
+ if (this.previousScrollRestoration) {
2779
+ history.scrollRestoration = this.previousScrollRestoration;
2780
+ delete this.previousScrollRestoration;
2781
+ }
2782
+ }
2783
+ shouldHandlePopState() {
2784
+ return this.pageIsLoaded();
2785
+ }
2786
+ pageIsLoaded() {
2787
+ return this.pageLoaded || document.readyState == "complete";
2788
+ }
2789
+ };
2790
+ var Navigator = class {
2791
+ constructor(delegate) {
2792
+ this.delegate = delegate;
2793
+ }
2794
+ proposeVisit(location2, options = {}) {
2795
+ if (this.delegate.allowsVisitingLocationWithAction(location2, options.action)) {
2796
+ if (locationIsVisitable(location2, this.view.snapshot.rootLocation)) {
2797
+ this.delegate.visitProposedToLocation(location2, options);
2798
+ } else {
2799
+ window.location.href = location2.toString();
2800
+ }
2801
+ }
2802
+ }
2803
+ startVisit(locatable, restorationIdentifier, options = {}) {
2804
+ this.stop();
2805
+ this.currentVisit = new Visit(this, expandURL(locatable), restorationIdentifier, Object.assign({ referrer: this.location }, options));
2806
+ this.currentVisit.start();
2807
+ }
2808
+ submitForm(form, submitter) {
2809
+ this.stop();
2810
+ this.formSubmission = new FormSubmission(this, form, submitter, true);
2811
+ this.formSubmission.start();
2812
+ }
2813
+ stop() {
2814
+ if (this.formSubmission) {
2815
+ this.formSubmission.stop();
2816
+ delete this.formSubmission;
2817
+ }
2818
+ if (this.currentVisit) {
2819
+ this.currentVisit.cancel();
2820
+ delete this.currentVisit;
2821
+ }
2822
+ }
2823
+ get adapter() {
2824
+ return this.delegate.adapter;
2825
+ }
2826
+ get view() {
2827
+ return this.delegate.view;
2828
+ }
2829
+ get history() {
2830
+ return this.delegate.history;
2831
+ }
2832
+ formSubmissionStarted(formSubmission) {
2833
+ if (typeof this.adapter.formSubmissionStarted === "function") {
2834
+ this.adapter.formSubmissionStarted(formSubmission);
2835
+ }
2836
+ }
2837
+ async formSubmissionSucceededWithResponse(formSubmission, fetchResponse) {
2838
+ if (formSubmission == this.formSubmission) {
2839
+ const responseHTML = await fetchResponse.responseHTML;
2840
+ if (responseHTML) {
2841
+ const shouldCacheSnapshot = formSubmission.isSafe;
2842
+ if (!shouldCacheSnapshot) {
2843
+ this.view.clearSnapshotCache();
2844
+ }
2845
+ const { statusCode, redirected } = fetchResponse;
2846
+ const action = this.getActionForFormSubmission(formSubmission);
2847
+ const visitOptions = {
2848
+ action,
2849
+ shouldCacheSnapshot,
2850
+ response: { statusCode, responseHTML, redirected }
2851
+ };
2852
+ this.proposeVisit(fetchResponse.location, visitOptions);
2853
+ }
2854
+ }
2855
+ }
2856
+ async formSubmissionFailedWithResponse(formSubmission, fetchResponse) {
2857
+ const responseHTML = await fetchResponse.responseHTML;
2858
+ if (responseHTML) {
2859
+ const snapshot = PageSnapshot.fromHTMLString(responseHTML);
2860
+ if (fetchResponse.serverError) {
2861
+ await this.view.renderError(snapshot, this.currentVisit);
2862
+ } else {
2863
+ await this.view.renderPage(snapshot, false, true, this.currentVisit);
2864
+ }
2865
+ this.view.scrollToTop();
2866
+ this.view.clearSnapshotCache();
2867
+ }
2868
+ }
2869
+ formSubmissionErrored(formSubmission, error) {
2870
+ console.error(error);
2871
+ }
2872
+ formSubmissionFinished(formSubmission) {
2873
+ if (typeof this.adapter.formSubmissionFinished === "function") {
2874
+ this.adapter.formSubmissionFinished(formSubmission);
2875
+ }
2876
+ }
2877
+ visitStarted(visit2) {
2878
+ this.delegate.visitStarted(visit2);
2879
+ }
2880
+ visitCompleted(visit2) {
2881
+ this.delegate.visitCompleted(visit2);
2882
+ }
2883
+ locationWithActionIsSamePage(location2, action) {
2884
+ const anchor = getAnchor(location2);
2885
+ const currentAnchor = getAnchor(this.view.lastRenderedLocation);
2886
+ const isRestorationToTop = action === "restore" && typeof anchor === "undefined";
2887
+ return action !== "replace" && getRequestURL(location2) === getRequestURL(this.view.lastRenderedLocation) && (isRestorationToTop || anchor != null && anchor !== currentAnchor);
2888
+ }
2889
+ visitScrolledToSamePageLocation(oldURL, newURL) {
2890
+ this.delegate.visitScrolledToSamePageLocation(oldURL, newURL);
2891
+ }
2892
+ get location() {
2893
+ return this.history.location;
2894
+ }
2895
+ get restorationIdentifier() {
2896
+ return this.history.restorationIdentifier;
2897
+ }
2898
+ getActionForFormSubmission({ submitter, formElement }) {
2899
+ return getVisitAction(submitter, formElement) || "advance";
2900
+ }
2901
+ };
2902
+ var PageStage;
2903
+ (function(PageStage2) {
2904
+ PageStage2[PageStage2["initial"] = 0] = "initial";
2905
+ PageStage2[PageStage2["loading"] = 1] = "loading";
2906
+ PageStage2[PageStage2["interactive"] = 2] = "interactive";
2907
+ PageStage2[PageStage2["complete"] = 3] = "complete";
2908
+ })(PageStage || (PageStage = {}));
2909
+ var PageObserver = class {
2910
+ constructor(delegate) {
2911
+ this.stage = PageStage.initial;
2912
+ this.started = false;
2913
+ this.interpretReadyState = () => {
2914
+ const { readyState } = this;
2915
+ if (readyState == "interactive") {
2916
+ this.pageIsInteractive();
2917
+ } else if (readyState == "complete") {
2918
+ this.pageIsComplete();
2919
+ }
2920
+ };
2921
+ this.pageWillUnload = () => {
2922
+ this.delegate.pageWillUnload();
2923
+ };
2924
+ this.delegate = delegate;
2925
+ }
2926
+ start() {
2927
+ if (!this.started) {
2928
+ if (this.stage == PageStage.initial) {
2929
+ this.stage = PageStage.loading;
2930
+ }
2931
+ document.addEventListener("readystatechange", this.interpretReadyState, false);
2932
+ addEventListener("pagehide", this.pageWillUnload, false);
2933
+ this.started = true;
2934
+ }
2935
+ }
2936
+ stop() {
2937
+ if (this.started) {
2938
+ document.removeEventListener("readystatechange", this.interpretReadyState, false);
2939
+ removeEventListener("pagehide", this.pageWillUnload, false);
2940
+ this.started = false;
2941
+ }
2942
+ }
2943
+ pageIsInteractive() {
2944
+ if (this.stage == PageStage.loading) {
2945
+ this.stage = PageStage.interactive;
2946
+ this.delegate.pageBecameInteractive();
2947
+ }
2948
+ }
2949
+ pageIsComplete() {
2950
+ this.pageIsInteractive();
2951
+ if (this.stage == PageStage.interactive) {
2952
+ this.stage = PageStage.complete;
2953
+ this.delegate.pageLoaded();
2954
+ }
2955
+ }
2956
+ get readyState() {
2957
+ return document.readyState;
2958
+ }
2959
+ };
2960
+ var ScrollObserver = class {
2961
+ constructor(delegate) {
2962
+ this.started = false;
2963
+ this.onScroll = () => {
2964
+ this.updatePosition({ x: window.pageXOffset, y: window.pageYOffset });
2965
+ };
2966
+ this.delegate = delegate;
2967
+ }
2968
+ start() {
2969
+ if (!this.started) {
2970
+ addEventListener("scroll", this.onScroll, false);
2971
+ this.onScroll();
2972
+ this.started = true;
2973
+ }
2974
+ }
2975
+ stop() {
2976
+ if (this.started) {
2977
+ removeEventListener("scroll", this.onScroll, false);
2978
+ this.started = false;
2979
+ }
2980
+ }
2981
+ updatePosition(position) {
2982
+ this.delegate.scrollPositionChanged(position);
2983
+ }
2984
+ };
2985
+ var StreamMessageRenderer = class {
2986
+ render({ fragment }) {
2987
+ Bardo.preservingPermanentElements(this, getPermanentElementMapForFragment(fragment), () => document.documentElement.appendChild(fragment));
2988
+ }
2989
+ enteringBardo(currentPermanentElement, newPermanentElement) {
2990
+ newPermanentElement.replaceWith(currentPermanentElement.cloneNode(true));
2991
+ }
2992
+ leavingBardo() {
2993
+ }
2994
+ };
2995
+ function getPermanentElementMapForFragment(fragment) {
2996
+ const permanentElementsInDocument = queryPermanentElementsAll(document.documentElement);
2997
+ const permanentElementMap = {};
2998
+ for (const permanentElementInDocument of permanentElementsInDocument) {
2999
+ const { id } = permanentElementInDocument;
3000
+ for (const streamElement of fragment.querySelectorAll("turbo-stream")) {
3001
+ const elementInStream = getPermanentElementById(streamElement.templateElement.content, id);
3002
+ if (elementInStream) {
3003
+ permanentElementMap[id] = [permanentElementInDocument, elementInStream];
3004
+ }
3005
+ }
3006
+ }
3007
+ return permanentElementMap;
3008
+ }
3009
+ var StreamObserver = class {
3010
+ constructor(delegate) {
3011
+ this.sources = /* @__PURE__ */ new Set();
3012
+ this.started = false;
3013
+ this.inspectFetchResponse = (event) => {
3014
+ const response = fetchResponseFromEvent(event);
3015
+ if (response && fetchResponseIsStream(response)) {
3016
+ event.preventDefault();
3017
+ this.receiveMessageResponse(response);
3018
+ }
3019
+ };
3020
+ this.receiveMessageEvent = (event) => {
3021
+ if (this.started && typeof event.data == "string") {
3022
+ this.receiveMessageHTML(event.data);
3023
+ }
3024
+ };
3025
+ this.delegate = delegate;
3026
+ }
3027
+ start() {
3028
+ if (!this.started) {
3029
+ this.started = true;
3030
+ addEventListener("turbo:before-fetch-response", this.inspectFetchResponse, false);
3031
+ }
3032
+ }
3033
+ stop() {
3034
+ if (this.started) {
3035
+ this.started = false;
3036
+ removeEventListener("turbo:before-fetch-response", this.inspectFetchResponse, false);
3037
+ }
3038
+ }
3039
+ connectStreamSource(source) {
3040
+ if (!this.streamSourceIsConnected(source)) {
3041
+ this.sources.add(source);
3042
+ source.addEventListener("message", this.receiveMessageEvent, false);
3043
+ }
3044
+ }
3045
+ disconnectStreamSource(source) {
3046
+ if (this.streamSourceIsConnected(source)) {
3047
+ this.sources.delete(source);
3048
+ source.removeEventListener("message", this.receiveMessageEvent, false);
3049
+ }
3050
+ }
3051
+ streamSourceIsConnected(source) {
3052
+ return this.sources.has(source);
3053
+ }
3054
+ async receiveMessageResponse(response) {
3055
+ const html = await response.responseHTML;
3056
+ if (html) {
3057
+ this.receiveMessageHTML(html);
3058
+ }
3059
+ }
3060
+ receiveMessageHTML(html) {
3061
+ this.delegate.receivedMessageFromStream(StreamMessage.wrap(html));
3062
+ }
3063
+ };
3064
+ function fetchResponseFromEvent(event) {
3065
+ var _a;
3066
+ const fetchResponse = (_a = event.detail) === null || _a === void 0 ? void 0 : _a.fetchResponse;
3067
+ if (fetchResponse instanceof FetchResponse) {
3068
+ return fetchResponse;
3069
+ }
3070
+ }
3071
+ function fetchResponseIsStream(response) {
3072
+ var _a;
3073
+ const contentType = (_a = response.contentType) !== null && _a !== void 0 ? _a : "";
3074
+ return contentType.startsWith(StreamMessage.contentType);
3075
+ }
3076
+ var ErrorRenderer = class extends Renderer {
3077
+ static renderElement(currentElement, newElement) {
3078
+ const { documentElement, body } = document;
3079
+ documentElement.replaceChild(newElement, body);
3080
+ }
3081
+ async render() {
3082
+ this.replaceHeadAndBody();
3083
+ this.activateScriptElements();
3084
+ }
3085
+ replaceHeadAndBody() {
3086
+ const { documentElement, head } = document;
3087
+ documentElement.replaceChild(this.newHead, head);
3088
+ this.renderElement(this.currentElement, this.newElement);
3089
+ }
3090
+ activateScriptElements() {
3091
+ for (const replaceableElement of this.scriptElements) {
3092
+ const parentNode = replaceableElement.parentNode;
3093
+ if (parentNode) {
3094
+ const element = activateScriptElement(replaceableElement);
3095
+ parentNode.replaceChild(element, replaceableElement);
3096
+ }
3097
+ }
3098
+ }
3099
+ get newHead() {
3100
+ return this.newSnapshot.headSnapshot.element;
3101
+ }
3102
+ get scriptElements() {
3103
+ return document.documentElement.querySelectorAll("script");
3104
+ }
3105
+ };
3106
+ var PageRenderer = class extends Renderer {
3107
+ static renderElement(currentElement, newElement) {
3108
+ if (document.body && newElement instanceof HTMLBodyElement) {
3109
+ document.body.replaceWith(newElement);
3110
+ } else {
3111
+ document.documentElement.appendChild(newElement);
3112
+ }
3113
+ }
3114
+ get shouldRender() {
3115
+ return this.newSnapshot.isVisitable && this.trackedElementsAreIdentical;
3116
+ }
3117
+ get reloadReason() {
3118
+ if (!this.newSnapshot.isVisitable) {
3119
+ return {
3120
+ reason: "turbo_visit_control_is_reload"
3121
+ };
3122
+ }
3123
+ if (!this.trackedElementsAreIdentical) {
3124
+ return {
3125
+ reason: "tracked_element_mismatch"
3126
+ };
3127
+ }
3128
+ }
3129
+ async prepareToRender() {
3130
+ await this.mergeHead();
3131
+ }
3132
+ async render() {
3133
+ if (this.willRender) {
3134
+ await this.replaceBody();
3135
+ }
3136
+ }
3137
+ finishRendering() {
3138
+ super.finishRendering();
3139
+ if (!this.isPreview) {
3140
+ this.focusFirstAutofocusableElement();
3141
+ }
3142
+ }
3143
+ get currentHeadSnapshot() {
3144
+ return this.currentSnapshot.headSnapshot;
3145
+ }
3146
+ get newHeadSnapshot() {
3147
+ return this.newSnapshot.headSnapshot;
3148
+ }
3149
+ get newElement() {
3150
+ return this.newSnapshot.element;
3151
+ }
3152
+ async mergeHead() {
3153
+ const mergedHeadElements = this.mergeProvisionalElements();
3154
+ const newStylesheetElements = this.copyNewHeadStylesheetElements();
3155
+ this.copyNewHeadScriptElements();
3156
+ await mergedHeadElements;
3157
+ await newStylesheetElements;
3158
+ }
3159
+ async replaceBody() {
3160
+ await this.preservingPermanentElements(async () => {
3161
+ this.activateNewBody();
3162
+ await this.assignNewBody();
3163
+ });
3164
+ }
3165
+ get trackedElementsAreIdentical() {
3166
+ return this.currentHeadSnapshot.trackedElementSignature == this.newHeadSnapshot.trackedElementSignature;
3167
+ }
3168
+ async copyNewHeadStylesheetElements() {
3169
+ const loadingElements = [];
3170
+ for (const element of this.newHeadStylesheetElements) {
3171
+ loadingElements.push(waitForLoad(element));
3172
+ document.head.appendChild(element);
3173
+ }
3174
+ await Promise.all(loadingElements);
3175
+ }
3176
+ copyNewHeadScriptElements() {
3177
+ for (const element of this.newHeadScriptElements) {
3178
+ document.head.appendChild(activateScriptElement(element));
3179
+ }
3180
+ }
3181
+ async mergeProvisionalElements() {
3182
+ const newHeadElements = [...this.newHeadProvisionalElements];
3183
+ for (const element of this.currentHeadProvisionalElements) {
3184
+ if (!this.isCurrentElementInElementList(element, newHeadElements)) {
3185
+ document.head.removeChild(element);
3186
+ }
3187
+ }
3188
+ for (const element of newHeadElements) {
3189
+ document.head.appendChild(element);
3190
+ }
3191
+ }
3192
+ isCurrentElementInElementList(element, elementList) {
3193
+ for (const [index, newElement] of elementList.entries()) {
3194
+ if (element.tagName == "TITLE") {
3195
+ if (newElement.tagName != "TITLE") {
3196
+ continue;
3197
+ }
3198
+ if (element.innerHTML == newElement.innerHTML) {
3199
+ elementList.splice(index, 1);
3200
+ return true;
3201
+ }
3202
+ }
3203
+ if (newElement.isEqualNode(element)) {
3204
+ elementList.splice(index, 1);
3205
+ return true;
3206
+ }
3207
+ }
3208
+ return false;
3209
+ }
3210
+ removeCurrentHeadProvisionalElements() {
3211
+ for (const element of this.currentHeadProvisionalElements) {
3212
+ document.head.removeChild(element);
3213
+ }
3214
+ }
3215
+ copyNewHeadProvisionalElements() {
3216
+ for (const element of this.newHeadProvisionalElements) {
3217
+ document.head.appendChild(element);
3218
+ }
3219
+ }
3220
+ activateNewBody() {
3221
+ document.adoptNode(this.newElement);
3222
+ this.activateNewBodyScriptElements();
3223
+ }
3224
+ activateNewBodyScriptElements() {
3225
+ for (const inertScriptElement of this.newBodyScriptElements) {
3226
+ const activatedScriptElement = activateScriptElement(inertScriptElement);
3227
+ inertScriptElement.replaceWith(activatedScriptElement);
3228
+ }
3229
+ }
3230
+ async assignNewBody() {
3231
+ await this.renderElement(this.currentElement, this.newElement);
3232
+ }
3233
+ get newHeadStylesheetElements() {
3234
+ return this.newHeadSnapshot.getStylesheetElementsNotInSnapshot(this.currentHeadSnapshot);
3235
+ }
3236
+ get newHeadScriptElements() {
3237
+ return this.newHeadSnapshot.getScriptElementsNotInSnapshot(this.currentHeadSnapshot);
3238
+ }
3239
+ get currentHeadProvisionalElements() {
3240
+ return this.currentHeadSnapshot.provisionalElements;
3241
+ }
3242
+ get newHeadProvisionalElements() {
3243
+ return this.newHeadSnapshot.provisionalElements;
3244
+ }
3245
+ get newBodyScriptElements() {
3246
+ return this.newElement.querySelectorAll("script");
3247
+ }
3248
+ };
3249
+ var SnapshotCache = class {
3250
+ constructor(size) {
3251
+ this.keys = [];
3252
+ this.snapshots = {};
3253
+ this.size = size;
3254
+ }
3255
+ has(location2) {
3256
+ return toCacheKey(location2) in this.snapshots;
3257
+ }
3258
+ get(location2) {
3259
+ if (this.has(location2)) {
3260
+ const snapshot = this.read(location2);
3261
+ this.touch(location2);
3262
+ return snapshot;
3263
+ }
3264
+ }
3265
+ put(location2, snapshot) {
3266
+ this.write(location2, snapshot);
3267
+ this.touch(location2);
3268
+ return snapshot;
3269
+ }
3270
+ clear() {
3271
+ this.snapshots = {};
3272
+ }
3273
+ read(location2) {
3274
+ return this.snapshots[toCacheKey(location2)];
3275
+ }
3276
+ write(location2, snapshot) {
3277
+ this.snapshots[toCacheKey(location2)] = snapshot;
3278
+ }
3279
+ touch(location2) {
3280
+ const key = toCacheKey(location2);
3281
+ const index = this.keys.indexOf(key);
3282
+ if (index > -1)
3283
+ this.keys.splice(index, 1);
3284
+ this.keys.unshift(key);
3285
+ this.trim();
3286
+ }
3287
+ trim() {
3288
+ for (const key of this.keys.splice(this.size)) {
3289
+ delete this.snapshots[key];
3290
+ }
3291
+ }
3292
+ };
3293
+ var PageView = class extends View {
3294
+ constructor() {
3295
+ super(...arguments);
3296
+ this.snapshotCache = new SnapshotCache(10);
3297
+ this.lastRenderedLocation = new URL(location.href);
3298
+ this.forceReloaded = false;
3299
+ }
3300
+ renderPage(snapshot, isPreview = false, willRender = true, visit2) {
3301
+ const renderer = new PageRenderer(this.snapshot, snapshot, PageRenderer.renderElement, isPreview, willRender);
3302
+ if (!renderer.shouldRender) {
3303
+ this.forceReloaded = true;
3304
+ } else {
3305
+ visit2 === null || visit2 === void 0 ? void 0 : visit2.changeHistory();
3306
+ }
3307
+ return this.render(renderer);
3308
+ }
3309
+ renderError(snapshot, visit2) {
3310
+ visit2 === null || visit2 === void 0 ? void 0 : visit2.changeHistory();
3311
+ const renderer = new ErrorRenderer(this.snapshot, snapshot, ErrorRenderer.renderElement, false);
3312
+ return this.render(renderer);
3313
+ }
3314
+ clearSnapshotCache() {
3315
+ this.snapshotCache.clear();
3316
+ }
3317
+ async cacheSnapshot(snapshot = this.snapshot) {
3318
+ if (snapshot.isCacheable) {
3319
+ this.delegate.viewWillCacheSnapshot();
3320
+ const { lastRenderedLocation: location2 } = this;
3321
+ await nextEventLoopTick();
3322
+ const cachedSnapshot = snapshot.clone();
3323
+ this.snapshotCache.put(location2, cachedSnapshot);
3324
+ return cachedSnapshot;
3325
+ }
3326
+ }
3327
+ getCachedSnapshotForLocation(location2) {
3328
+ return this.snapshotCache.get(location2);
3329
+ }
3330
+ get snapshot() {
3331
+ return PageSnapshot.fromElement(this.element);
3332
+ }
3333
+ };
3334
+ var Preloader = class {
3335
+ constructor(delegate) {
3336
+ this.selector = "a[data-turbo-preload]";
3337
+ this.delegate = delegate;
3338
+ }
3339
+ get snapshotCache() {
3340
+ return this.delegate.navigator.view.snapshotCache;
3341
+ }
3342
+ start() {
3343
+ if (document.readyState === "loading") {
3344
+ return document.addEventListener("DOMContentLoaded", () => {
3345
+ this.preloadOnLoadLinksForView(document.body);
3346
+ });
3347
+ } else {
3348
+ this.preloadOnLoadLinksForView(document.body);
3349
+ }
3350
+ }
3351
+ preloadOnLoadLinksForView(element) {
3352
+ for (const link of element.querySelectorAll(this.selector)) {
3353
+ this.preloadURL(link);
3354
+ }
3355
+ }
3356
+ async preloadURL(link) {
3357
+ const location2 = new URL(link.href);
3358
+ if (this.snapshotCache.has(location2)) {
3359
+ return;
3360
+ }
3361
+ try {
3362
+ const response = await fetch(location2.toString(), { headers: { "VND.PREFETCH": "true", Accept: "text/html" } });
3363
+ const responseText = await response.text();
3364
+ const snapshot = PageSnapshot.fromHTMLString(responseText);
3365
+ this.snapshotCache.put(location2, snapshot);
3366
+ } catch (_) {
3367
+ }
3368
+ }
3369
+ };
3370
+ var Session = class {
3371
+ constructor() {
3372
+ this.navigator = new Navigator(this);
3373
+ this.history = new History(this);
3374
+ this.preloader = new Preloader(this);
3375
+ this.view = new PageView(this, document.documentElement);
3376
+ this.adapter = new BrowserAdapter(this);
3377
+ this.pageObserver = new PageObserver(this);
3378
+ this.cacheObserver = new CacheObserver();
3379
+ this.linkClickObserver = new LinkClickObserver(this, window);
3380
+ this.formSubmitObserver = new FormSubmitObserver(this, document);
3381
+ this.scrollObserver = new ScrollObserver(this);
3382
+ this.streamObserver = new StreamObserver(this);
3383
+ this.formLinkClickObserver = new FormLinkClickObserver(this, document.documentElement);
3384
+ this.frameRedirector = new FrameRedirector(this, document.documentElement);
3385
+ this.streamMessageRenderer = new StreamMessageRenderer();
3386
+ this.drive = true;
3387
+ this.enabled = true;
3388
+ this.progressBarDelay = 500;
3389
+ this.started = false;
3390
+ this.formMode = "on";
3391
+ }
3392
+ start() {
3393
+ if (!this.started) {
3394
+ this.pageObserver.start();
3395
+ this.cacheObserver.start();
3396
+ this.formLinkClickObserver.start();
3397
+ this.linkClickObserver.start();
3398
+ this.formSubmitObserver.start();
3399
+ this.scrollObserver.start();
3400
+ this.streamObserver.start();
3401
+ this.frameRedirector.start();
3402
+ this.history.start();
3403
+ this.preloader.start();
3404
+ this.started = true;
3405
+ this.enabled = true;
3406
+ }
3407
+ }
3408
+ disable() {
3409
+ this.enabled = false;
3410
+ }
3411
+ stop() {
3412
+ if (this.started) {
3413
+ this.pageObserver.stop();
3414
+ this.cacheObserver.stop();
3415
+ this.formLinkClickObserver.stop();
3416
+ this.linkClickObserver.stop();
3417
+ this.formSubmitObserver.stop();
3418
+ this.scrollObserver.stop();
3419
+ this.streamObserver.stop();
3420
+ this.frameRedirector.stop();
3421
+ this.history.stop();
3422
+ this.started = false;
3423
+ }
3424
+ }
3425
+ registerAdapter(adapter) {
3426
+ this.adapter = adapter;
3427
+ }
3428
+ visit(location2, options = {}) {
3429
+ const frameElement = options.frame ? document.getElementById(options.frame) : null;
3430
+ if (frameElement instanceof FrameElement) {
3431
+ frameElement.src = location2.toString();
3432
+ frameElement.loaded;
3433
+ } else {
3434
+ this.navigator.proposeVisit(expandURL(location2), options);
3435
+ }
3436
+ }
3437
+ connectStreamSource(source) {
3438
+ this.streamObserver.connectStreamSource(source);
3439
+ }
3440
+ disconnectStreamSource(source) {
3441
+ this.streamObserver.disconnectStreamSource(source);
3442
+ }
3443
+ renderStreamMessage(message) {
3444
+ this.streamMessageRenderer.render(StreamMessage.wrap(message));
3445
+ }
3446
+ clearCache() {
3447
+ this.view.clearSnapshotCache();
3448
+ }
3449
+ setProgressBarDelay(delay) {
3450
+ this.progressBarDelay = delay;
3451
+ }
3452
+ setFormMode(mode) {
3453
+ this.formMode = mode;
3454
+ }
3455
+ get location() {
3456
+ return this.history.location;
3457
+ }
3458
+ get restorationIdentifier() {
3459
+ return this.history.restorationIdentifier;
3460
+ }
3461
+ historyPoppedToLocationWithRestorationIdentifier(location2, restorationIdentifier) {
3462
+ if (this.enabled) {
3463
+ this.navigator.startVisit(location2, restorationIdentifier, {
3464
+ action: "restore",
3465
+ historyChanged: true
3466
+ });
3467
+ } else {
3468
+ this.adapter.pageInvalidated({
3469
+ reason: "turbo_disabled"
3470
+ });
3471
+ }
3472
+ }
3473
+ scrollPositionChanged(position) {
3474
+ this.history.updateRestorationData({ scrollPosition: position });
3475
+ }
3476
+ willSubmitFormLinkToLocation(link, location2) {
3477
+ return this.elementIsNavigatable(link) && locationIsVisitable(location2, this.snapshot.rootLocation);
3478
+ }
3479
+ submittedFormLinkToLocation() {
3480
+ }
3481
+ willFollowLinkToLocation(link, location2, event) {
3482
+ return this.elementIsNavigatable(link) && locationIsVisitable(location2, this.snapshot.rootLocation) && this.applicationAllowsFollowingLinkToLocation(link, location2, event);
3483
+ }
3484
+ followedLinkToLocation(link, location2) {
3485
+ const action = this.getActionForLink(link);
3486
+ const acceptsStreamResponse = link.hasAttribute("data-turbo-stream");
3487
+ this.visit(location2.href, { action, acceptsStreamResponse });
3488
+ }
3489
+ allowsVisitingLocationWithAction(location2, action) {
3490
+ return this.locationWithActionIsSamePage(location2, action) || this.applicationAllowsVisitingLocation(location2);
3491
+ }
3492
+ visitProposedToLocation(location2, options) {
3493
+ extendURLWithDeprecatedProperties(location2);
3494
+ this.adapter.visitProposedToLocation(location2, options);
3495
+ }
3496
+ visitStarted(visit2) {
3497
+ if (!visit2.acceptsStreamResponse) {
3498
+ markAsBusy(document.documentElement);
3499
+ }
3500
+ extendURLWithDeprecatedProperties(visit2.location);
3501
+ if (!visit2.silent) {
3502
+ this.notifyApplicationAfterVisitingLocation(visit2.location, visit2.action);
3503
+ }
3504
+ }
3505
+ visitCompleted(visit2) {
3506
+ clearBusyState(document.documentElement);
3507
+ this.notifyApplicationAfterPageLoad(visit2.getTimingMetrics());
3508
+ }
3509
+ locationWithActionIsSamePage(location2, action) {
3510
+ return this.navigator.locationWithActionIsSamePage(location2, action);
3511
+ }
3512
+ visitScrolledToSamePageLocation(oldURL, newURL) {
3513
+ this.notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL);
3514
+ }
3515
+ willSubmitForm(form, submitter) {
3516
+ const action = getAction(form, submitter);
3517
+ return this.submissionIsNavigatable(form, submitter) && locationIsVisitable(expandURL(action), this.snapshot.rootLocation);
3518
+ }
3519
+ formSubmitted(form, submitter) {
3520
+ this.navigator.submitForm(form, submitter);
3521
+ }
3522
+ pageBecameInteractive() {
3523
+ this.view.lastRenderedLocation = this.location;
3524
+ this.notifyApplicationAfterPageLoad();
3525
+ }
3526
+ pageLoaded() {
3527
+ this.history.assumeControlOfScrollRestoration();
3528
+ }
3529
+ pageWillUnload() {
3530
+ this.history.relinquishControlOfScrollRestoration();
3531
+ }
3532
+ receivedMessageFromStream(message) {
3533
+ this.renderStreamMessage(message);
3534
+ }
3535
+ viewWillCacheSnapshot() {
3536
+ var _a;
3537
+ if (!((_a = this.navigator.currentVisit) === null || _a === void 0 ? void 0 : _a.silent)) {
3538
+ this.notifyApplicationBeforeCachingSnapshot();
3539
+ }
3540
+ }
3541
+ allowsImmediateRender({ element }, options) {
3542
+ const event = this.notifyApplicationBeforeRender(element, options);
3543
+ const { defaultPrevented, detail: { render } } = event;
3544
+ if (this.view.renderer && render) {
3545
+ this.view.renderer.renderElement = render;
3546
+ }
3547
+ return !defaultPrevented;
3548
+ }
3549
+ viewRenderedSnapshot(_snapshot, _isPreview) {
3550
+ this.view.lastRenderedLocation = this.history.location;
3551
+ this.notifyApplicationAfterRender();
3552
+ }
3553
+ preloadOnLoadLinksForView(element) {
3554
+ this.preloader.preloadOnLoadLinksForView(element);
3555
+ }
3556
+ viewInvalidated(reason) {
3557
+ this.adapter.pageInvalidated(reason);
3558
+ }
3559
+ frameLoaded(frame) {
3560
+ this.notifyApplicationAfterFrameLoad(frame);
3561
+ }
3562
+ frameRendered(fetchResponse, frame) {
3563
+ this.notifyApplicationAfterFrameRender(fetchResponse, frame);
3564
+ }
3565
+ applicationAllowsFollowingLinkToLocation(link, location2, ev) {
3566
+ const event = this.notifyApplicationAfterClickingLinkToLocation(link, location2, ev);
3567
+ return !event.defaultPrevented;
3568
+ }
3569
+ applicationAllowsVisitingLocation(location2) {
3570
+ const event = this.notifyApplicationBeforeVisitingLocation(location2);
3571
+ return !event.defaultPrevented;
3572
+ }
3573
+ notifyApplicationAfterClickingLinkToLocation(link, location2, event) {
3574
+ return dispatch("turbo:click", {
3575
+ target: link,
3576
+ detail: { url: location2.href, originalEvent: event },
3577
+ cancelable: true
3578
+ });
3579
+ }
3580
+ notifyApplicationBeforeVisitingLocation(location2) {
3581
+ return dispatch("turbo:before-visit", {
3582
+ detail: { url: location2.href },
3583
+ cancelable: true
3584
+ });
3585
+ }
3586
+ notifyApplicationAfterVisitingLocation(location2, action) {
3587
+ return dispatch("turbo:visit", { detail: { url: location2.href, action } });
3588
+ }
3589
+ notifyApplicationBeforeCachingSnapshot() {
3590
+ return dispatch("turbo:before-cache");
3591
+ }
3592
+ notifyApplicationBeforeRender(newBody, options) {
3593
+ return dispatch("turbo:before-render", {
3594
+ detail: Object.assign({ newBody }, options),
3595
+ cancelable: true
3596
+ });
3597
+ }
3598
+ notifyApplicationAfterRender() {
3599
+ return dispatch("turbo:render");
3600
+ }
3601
+ notifyApplicationAfterPageLoad(timing = {}) {
3602
+ return dispatch("turbo:load", {
3603
+ detail: { url: this.location.href, timing }
3604
+ });
3605
+ }
3606
+ notifyApplicationAfterVisitingSamePageLocation(oldURL, newURL) {
3607
+ dispatchEvent(new HashChangeEvent("hashchange", {
3608
+ oldURL: oldURL.toString(),
3609
+ newURL: newURL.toString()
3610
+ }));
3611
+ }
3612
+ notifyApplicationAfterFrameLoad(frame) {
3613
+ return dispatch("turbo:frame-load", { target: frame });
3614
+ }
3615
+ notifyApplicationAfterFrameRender(fetchResponse, frame) {
3616
+ return dispatch("turbo:frame-render", {
3617
+ detail: { fetchResponse },
3618
+ target: frame,
3619
+ cancelable: true
3620
+ });
3621
+ }
3622
+ submissionIsNavigatable(form, submitter) {
3623
+ if (this.formMode == "off") {
3624
+ return false;
3625
+ } else {
3626
+ const submitterIsNavigatable = submitter ? this.elementIsNavigatable(submitter) : true;
3627
+ if (this.formMode == "optin") {
3628
+ return submitterIsNavigatable && form.closest('[data-turbo="true"]') != null;
3629
+ } else {
3630
+ return submitterIsNavigatable && this.elementIsNavigatable(form);
3631
+ }
3632
+ }
3633
+ }
3634
+ elementIsNavigatable(element) {
3635
+ const container = findClosestRecursively(element, "[data-turbo]");
3636
+ const withinFrame = findClosestRecursively(element, "turbo-frame");
3637
+ if (this.drive || withinFrame) {
3638
+ if (container) {
3639
+ return container.getAttribute("data-turbo") != "false";
3640
+ } else {
3641
+ return true;
3642
+ }
3643
+ } else {
3644
+ if (container) {
3645
+ return container.getAttribute("data-turbo") == "true";
3646
+ } else {
3647
+ return false;
3648
+ }
3649
+ }
3650
+ }
3651
+ getActionForLink(link) {
3652
+ return getVisitAction(link) || "advance";
3653
+ }
3654
+ get snapshot() {
3655
+ return this.view.snapshot;
3656
+ }
3657
+ };
3658
+ function extendURLWithDeprecatedProperties(url) {
3659
+ Object.defineProperties(url, deprecatedLocationPropertyDescriptors);
3660
+ }
3661
+ var deprecatedLocationPropertyDescriptors = {
3662
+ absoluteURL: {
3663
+ get() {
3664
+ return this.toString();
3665
+ }
3666
+ }
3667
+ };
3668
+ var Cache = class {
3669
+ constructor(session2) {
3670
+ this.session = session2;
3671
+ }
3672
+ clear() {
3673
+ this.session.clearCache();
3674
+ }
3675
+ resetCacheControl() {
3676
+ this.setCacheControl("");
3677
+ }
3678
+ exemptPageFromCache() {
3679
+ this.setCacheControl("no-cache");
3680
+ }
3681
+ exemptPageFromPreview() {
3682
+ this.setCacheControl("no-preview");
3683
+ }
3684
+ setCacheControl(value) {
3685
+ setMetaContent("turbo-cache-control", value);
3686
+ }
3687
+ };
3688
+ var StreamActions = {
3689
+ after() {
3690
+ this.targetElements.forEach((e) => {
3691
+ var _a;
3692
+ return (_a = e.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(this.templateContent, e.nextSibling);
3693
+ });
3694
+ },
3695
+ append() {
3696
+ this.removeDuplicateTargetChildren();
3697
+ this.targetElements.forEach((e) => e.append(this.templateContent));
3698
+ },
3699
+ before() {
3700
+ this.targetElements.forEach((e) => {
3701
+ var _a;
3702
+ return (_a = e.parentElement) === null || _a === void 0 ? void 0 : _a.insertBefore(this.templateContent, e);
3703
+ });
3704
+ },
3705
+ prepend() {
3706
+ this.removeDuplicateTargetChildren();
3707
+ this.targetElements.forEach((e) => e.prepend(this.templateContent));
3708
+ },
3709
+ remove() {
3710
+ this.targetElements.forEach((e) => e.remove());
3711
+ },
3712
+ replace() {
3713
+ this.targetElements.forEach((e) => e.replaceWith(this.templateContent));
3714
+ },
3715
+ update() {
3716
+ this.targetElements.forEach((targetElement) => {
3717
+ targetElement.innerHTML = "";
3718
+ targetElement.append(this.templateContent);
3719
+ });
3720
+ }
3721
+ };
3722
+ var session = new Session();
3723
+ var cache = new Cache(session);
3724
+ var { navigator: navigator$1 } = session;
3725
+ function start() {
3726
+ session.start();
3727
+ }
3728
+ function registerAdapter(adapter) {
3729
+ session.registerAdapter(adapter);
3730
+ }
3731
+ function visit(location2, options) {
3732
+ session.visit(location2, options);
3733
+ }
3734
+ function connectStreamSource(source) {
3735
+ session.connectStreamSource(source);
3736
+ }
3737
+ function disconnectStreamSource(source) {
3738
+ session.disconnectStreamSource(source);
3739
+ }
3740
+ function renderStreamMessage(message) {
3741
+ session.renderStreamMessage(message);
3742
+ }
3743
+ function clearCache() {
3744
+ console.warn("Please replace `Turbo.clearCache()` with `Turbo.cache.clear()`. The top-level function is deprecated and will be removed in a future version of Turbo.`");
3745
+ session.clearCache();
3746
+ }
3747
+ function setProgressBarDelay(delay) {
3748
+ session.setProgressBarDelay(delay);
3749
+ }
3750
+ function setConfirmMethod(confirmMethod) {
3751
+ FormSubmission.confirmMethod = confirmMethod;
3752
+ }
3753
+ function setFormMode(mode) {
3754
+ session.setFormMode(mode);
3755
+ }
3756
+ var Turbo = /* @__PURE__ */ Object.freeze({
3757
+ __proto__: null,
3758
+ navigator: navigator$1,
3759
+ session,
3760
+ cache,
3761
+ PageRenderer,
3762
+ PageSnapshot,
3763
+ FrameRenderer,
3764
+ start,
3765
+ registerAdapter,
3766
+ visit,
3767
+ connectStreamSource,
3768
+ disconnectStreamSource,
3769
+ renderStreamMessage,
3770
+ clearCache,
3771
+ setProgressBarDelay,
3772
+ setConfirmMethod,
3773
+ setFormMode,
3774
+ StreamActions
3775
+ });
3776
+ var TurboFrameMissingError = class extends Error {
3777
+ };
3778
+ var FrameController = class {
3779
+ constructor(element) {
3780
+ this.fetchResponseLoaded = (_fetchResponse) => {
3781
+ };
3782
+ this.currentFetchRequest = null;
3783
+ this.resolveVisitPromise = () => {
3784
+ };
3785
+ this.connected = false;
3786
+ this.hasBeenLoaded = false;
3787
+ this.ignoredAttributes = /* @__PURE__ */ new Set();
3788
+ this.action = null;
3789
+ this.visitCachedSnapshot = ({ element: element2 }) => {
3790
+ const frame = element2.querySelector("#" + this.element.id);
3791
+ if (frame && this.previousFrameElement) {
3792
+ frame.replaceChildren(...this.previousFrameElement.children);
3793
+ }
3794
+ delete this.previousFrameElement;
3795
+ };
3796
+ this.element = element;
3797
+ this.view = new FrameView(this, this.element);
3798
+ this.appearanceObserver = new AppearanceObserver(this, this.element);
3799
+ this.formLinkClickObserver = new FormLinkClickObserver(this, this.element);
3800
+ this.linkInterceptor = new LinkInterceptor(this, this.element);
3801
+ this.restorationIdentifier = uuid();
3802
+ this.formSubmitObserver = new FormSubmitObserver(this, this.element);
3803
+ }
3804
+ connect() {
3805
+ if (!this.connected) {
3806
+ this.connected = true;
3807
+ if (this.loadingStyle == FrameLoadingStyle.lazy) {
3808
+ this.appearanceObserver.start();
3809
+ } else {
3810
+ this.loadSourceURL();
3811
+ }
3812
+ this.formLinkClickObserver.start();
3813
+ this.linkInterceptor.start();
3814
+ this.formSubmitObserver.start();
3815
+ }
3816
+ }
3817
+ disconnect() {
3818
+ if (this.connected) {
3819
+ this.connected = false;
3820
+ this.appearanceObserver.stop();
3821
+ this.formLinkClickObserver.stop();
3822
+ this.linkInterceptor.stop();
3823
+ this.formSubmitObserver.stop();
3824
+ }
3825
+ }
3826
+ disabledChanged() {
3827
+ if (this.loadingStyle == FrameLoadingStyle.eager) {
3828
+ this.loadSourceURL();
3829
+ }
3830
+ }
3831
+ sourceURLChanged() {
3832
+ if (this.isIgnoringChangesTo("src"))
3833
+ return;
3834
+ if (this.element.isConnected) {
3835
+ this.complete = false;
3836
+ }
3837
+ if (this.loadingStyle == FrameLoadingStyle.eager || this.hasBeenLoaded) {
3838
+ this.loadSourceURL();
3839
+ }
3840
+ }
3841
+ sourceURLReloaded() {
3842
+ const { src } = this.element;
3843
+ this.ignoringChangesToAttribute("complete", () => {
3844
+ this.element.removeAttribute("complete");
3845
+ });
3846
+ this.element.src = null;
3847
+ this.element.src = src;
3848
+ return this.element.loaded;
3849
+ }
3850
+ completeChanged() {
3851
+ if (this.isIgnoringChangesTo("complete"))
3852
+ return;
3853
+ this.loadSourceURL();
3854
+ }
3855
+ loadingStyleChanged() {
3856
+ if (this.loadingStyle == FrameLoadingStyle.lazy) {
3857
+ this.appearanceObserver.start();
3858
+ } else {
3859
+ this.appearanceObserver.stop();
3860
+ this.loadSourceURL();
3861
+ }
3862
+ }
3863
+ async loadSourceURL() {
3864
+ if (this.enabled && this.isActive && !this.complete && this.sourceURL) {
3865
+ this.element.loaded = this.visit(expandURL(this.sourceURL));
3866
+ this.appearanceObserver.stop();
3867
+ await this.element.loaded;
3868
+ this.hasBeenLoaded = true;
3869
+ }
3870
+ }
3871
+ async loadResponse(fetchResponse) {
3872
+ if (fetchResponse.redirected || fetchResponse.succeeded && fetchResponse.isHTML) {
3873
+ this.sourceURL = fetchResponse.response.url;
3874
+ }
3875
+ try {
3876
+ const html = await fetchResponse.responseHTML;
3877
+ if (html) {
3878
+ const document2 = parseHTMLDocument(html);
3879
+ const pageSnapshot = PageSnapshot.fromDocument(document2);
3880
+ if (pageSnapshot.isVisitable) {
3881
+ await this.loadFrameResponse(fetchResponse, document2);
3882
+ } else {
3883
+ await this.handleUnvisitableFrameResponse(fetchResponse);
3884
+ }
3885
+ }
3886
+ } finally {
3887
+ this.fetchResponseLoaded = () => {
3888
+ };
3889
+ }
3890
+ }
3891
+ elementAppearedInViewport(element) {
3892
+ this.proposeVisitIfNavigatedWithAction(element, element);
3893
+ this.loadSourceURL();
3894
+ }
3895
+ willSubmitFormLinkToLocation(link) {
3896
+ return this.shouldInterceptNavigation(link);
3897
+ }
3898
+ submittedFormLinkToLocation(link, _location, form) {
3899
+ const frame = this.findFrameElement(link);
3900
+ if (frame)
3901
+ form.setAttribute("data-turbo-frame", frame.id);
3902
+ }
3903
+ shouldInterceptLinkClick(element, _location, _event) {
3904
+ return this.shouldInterceptNavigation(element);
3905
+ }
3906
+ linkClickIntercepted(element, location2) {
3907
+ this.navigateFrame(element, location2);
3908
+ }
3909
+ willSubmitForm(element, submitter) {
3910
+ return element.closest("turbo-frame") == this.element && this.shouldInterceptNavigation(element, submitter);
3911
+ }
3912
+ formSubmitted(element, submitter) {
3913
+ if (this.formSubmission) {
3914
+ this.formSubmission.stop();
3915
+ }
3916
+ this.formSubmission = new FormSubmission(this, element, submitter);
3917
+ const { fetchRequest } = this.formSubmission;
3918
+ this.prepareRequest(fetchRequest);
3919
+ this.formSubmission.start();
3920
+ }
3921
+ prepareRequest(request) {
3922
+ var _a;
3923
+ request.headers["Turbo-Frame"] = this.id;
3924
+ if ((_a = this.currentNavigationElement) === null || _a === void 0 ? void 0 : _a.hasAttribute("data-turbo-stream")) {
3925
+ request.acceptResponseType(StreamMessage.contentType);
3926
+ }
3927
+ }
3928
+ requestStarted(_request) {
3929
+ markAsBusy(this.element);
3930
+ }
3931
+ requestPreventedHandlingResponse(_request, _response) {
3932
+ this.resolveVisitPromise();
3933
+ }
3934
+ async requestSucceededWithResponse(request, response) {
3935
+ await this.loadResponse(response);
3936
+ this.resolveVisitPromise();
3937
+ }
3938
+ async requestFailedWithResponse(request, response) {
3939
+ await this.loadResponse(response);
3940
+ this.resolveVisitPromise();
3941
+ }
3942
+ requestErrored(request, error) {
3943
+ console.error(error);
3944
+ this.resolveVisitPromise();
3945
+ }
3946
+ requestFinished(_request) {
3947
+ clearBusyState(this.element);
3948
+ }
3949
+ formSubmissionStarted({ formElement }) {
3950
+ markAsBusy(formElement, this.findFrameElement(formElement));
3951
+ }
3952
+ formSubmissionSucceededWithResponse(formSubmission, response) {
3953
+ const frame = this.findFrameElement(formSubmission.formElement, formSubmission.submitter);
3954
+ frame.delegate.proposeVisitIfNavigatedWithAction(frame, formSubmission.formElement, formSubmission.submitter);
3955
+ frame.delegate.loadResponse(response);
3956
+ if (!formSubmission.isSafe) {
3957
+ session.clearCache();
3958
+ }
3959
+ }
3960
+ formSubmissionFailedWithResponse(formSubmission, fetchResponse) {
3961
+ this.element.delegate.loadResponse(fetchResponse);
3962
+ session.clearCache();
3963
+ }
3964
+ formSubmissionErrored(formSubmission, error) {
3965
+ console.error(error);
3966
+ }
3967
+ formSubmissionFinished({ formElement }) {
3968
+ clearBusyState(formElement, this.findFrameElement(formElement));
3969
+ }
3970
+ allowsImmediateRender({ element: newFrame }, options) {
3971
+ const event = dispatch("turbo:before-frame-render", {
3972
+ target: this.element,
3973
+ detail: Object.assign({ newFrame }, options),
3974
+ cancelable: true
3975
+ });
3976
+ const { defaultPrevented, detail: { render } } = event;
3977
+ if (this.view.renderer && render) {
3978
+ this.view.renderer.renderElement = render;
3979
+ }
3980
+ return !defaultPrevented;
3981
+ }
3982
+ viewRenderedSnapshot(_snapshot, _isPreview) {
3983
+ }
3984
+ preloadOnLoadLinksForView(element) {
3985
+ session.preloadOnLoadLinksForView(element);
3986
+ }
3987
+ viewInvalidated() {
3988
+ }
3989
+ willRenderFrame(currentElement, _newElement) {
3990
+ this.previousFrameElement = currentElement.cloneNode(true);
3991
+ }
3992
+ async loadFrameResponse(fetchResponse, document2) {
3993
+ const newFrameElement = await this.extractForeignFrameElement(document2.body);
3994
+ if (newFrameElement) {
3995
+ const snapshot = new Snapshot(newFrameElement);
3996
+ const renderer = new FrameRenderer(this, this.view.snapshot, snapshot, FrameRenderer.renderElement, false, false);
3997
+ if (this.view.renderPromise)
3998
+ await this.view.renderPromise;
3999
+ this.changeHistory();
4000
+ await this.view.render(renderer);
4001
+ this.complete = true;
4002
+ session.frameRendered(fetchResponse, this.element);
4003
+ session.frameLoaded(this.element);
4004
+ this.fetchResponseLoaded(fetchResponse);
4005
+ } else if (this.willHandleFrameMissingFromResponse(fetchResponse)) {
4006
+ this.handleFrameMissingFromResponse(fetchResponse);
4007
+ }
4008
+ }
4009
+ async visit(url) {
4010
+ var _a;
4011
+ const request = new FetchRequest(this, FetchMethod.get, url, new URLSearchParams(), this.element);
4012
+ (_a = this.currentFetchRequest) === null || _a === void 0 ? void 0 : _a.cancel();
4013
+ this.currentFetchRequest = request;
4014
+ return new Promise((resolve) => {
4015
+ this.resolveVisitPromise = () => {
4016
+ this.resolveVisitPromise = () => {
4017
+ };
4018
+ this.currentFetchRequest = null;
4019
+ resolve();
4020
+ };
4021
+ request.perform();
4022
+ });
4023
+ }
4024
+ navigateFrame(element, url, submitter) {
4025
+ const frame = this.findFrameElement(element, submitter);
4026
+ frame.delegate.proposeVisitIfNavigatedWithAction(frame, element, submitter);
4027
+ this.withCurrentNavigationElement(element, () => {
4028
+ frame.src = url;
4029
+ });
4030
+ }
4031
+ proposeVisitIfNavigatedWithAction(frame, element, submitter) {
4032
+ this.action = getVisitAction(submitter, element, frame);
4033
+ if (this.action) {
4034
+ const pageSnapshot = PageSnapshot.fromElement(frame).clone();
4035
+ const { visitCachedSnapshot } = frame.delegate;
4036
+ frame.delegate.fetchResponseLoaded = (fetchResponse) => {
4037
+ if (frame.src) {
4038
+ const { statusCode, redirected } = fetchResponse;
4039
+ const responseHTML = frame.ownerDocument.documentElement.outerHTML;
4040
+ const response = { statusCode, redirected, responseHTML };
4041
+ const options = {
4042
+ response,
4043
+ visitCachedSnapshot,
4044
+ willRender: false,
4045
+ updateHistory: false,
4046
+ restorationIdentifier: this.restorationIdentifier,
4047
+ snapshot: pageSnapshot
4048
+ };
4049
+ if (this.action)
4050
+ options.action = this.action;
4051
+ session.visit(frame.src, options);
4052
+ }
4053
+ };
4054
+ }
4055
+ }
4056
+ changeHistory() {
4057
+ if (this.action) {
4058
+ const method = getHistoryMethodForAction(this.action);
4059
+ session.history.update(method, expandURL(this.element.src || ""), this.restorationIdentifier);
4060
+ }
4061
+ }
4062
+ async handleUnvisitableFrameResponse(fetchResponse) {
4063
+ console.warn(`The response (${fetchResponse.statusCode}) from <turbo-frame id="${this.element.id}"> is performing a full page visit due to turbo-visit-control.`);
4064
+ await this.visitResponse(fetchResponse.response);
4065
+ }
4066
+ willHandleFrameMissingFromResponse(fetchResponse) {
4067
+ this.element.setAttribute("complete", "");
4068
+ const response = fetchResponse.response;
4069
+ const visit2 = async (url, options = {}) => {
4070
+ if (url instanceof Response) {
4071
+ this.visitResponse(url);
4072
+ } else {
4073
+ session.visit(url, options);
4074
+ }
4075
+ };
4076
+ const event = dispatch("turbo:frame-missing", {
4077
+ target: this.element,
4078
+ detail: { response, visit: visit2 },
4079
+ cancelable: true
4080
+ });
4081
+ return !event.defaultPrevented;
4082
+ }
4083
+ handleFrameMissingFromResponse(fetchResponse) {
4084
+ this.view.missing();
4085
+ this.throwFrameMissingError(fetchResponse);
4086
+ }
4087
+ throwFrameMissingError(fetchResponse) {
4088
+ const message = `The response (${fetchResponse.statusCode}) did not contain the expected <turbo-frame id="${this.element.id}"> and will be ignored. To perform a full page visit instead, set turbo-visit-control to reload.`;
4089
+ throw new TurboFrameMissingError(message);
4090
+ }
4091
+ async visitResponse(response) {
4092
+ const wrapped = new FetchResponse(response);
4093
+ const responseHTML = await wrapped.responseHTML;
4094
+ const { location: location2, redirected, statusCode } = wrapped;
4095
+ return session.visit(location2, { response: { redirected, statusCode, responseHTML } });
4096
+ }
4097
+ findFrameElement(element, submitter) {
4098
+ var _a;
4099
+ const id = getAttribute("data-turbo-frame", submitter, element) || this.element.getAttribute("target");
4100
+ return (_a = getFrameElementById(id)) !== null && _a !== void 0 ? _a : this.element;
4101
+ }
4102
+ async extractForeignFrameElement(container) {
4103
+ let element;
4104
+ const id = CSS.escape(this.id);
4105
+ try {
4106
+ element = activateElement(container.querySelector(`turbo-frame#${id}`), this.sourceURL);
4107
+ if (element) {
4108
+ return element;
4109
+ }
4110
+ element = activateElement(container.querySelector(`turbo-frame[src][recurse~=${id}]`), this.sourceURL);
4111
+ if (element) {
4112
+ await element.loaded;
4113
+ return await this.extractForeignFrameElement(element);
4114
+ }
4115
+ } catch (error) {
4116
+ console.error(error);
4117
+ return new FrameElement();
4118
+ }
4119
+ return null;
4120
+ }
4121
+ formActionIsVisitable(form, submitter) {
4122
+ const action = getAction(form, submitter);
4123
+ return locationIsVisitable(expandURL(action), this.rootLocation);
4124
+ }
4125
+ shouldInterceptNavigation(element, submitter) {
4126
+ const id = getAttribute("data-turbo-frame", submitter, element) || this.element.getAttribute("target");
4127
+ if (element instanceof HTMLFormElement && !this.formActionIsVisitable(element, submitter)) {
4128
+ return false;
4129
+ }
4130
+ if (!this.enabled || id == "_top") {
4131
+ return false;
4132
+ }
4133
+ if (id) {
4134
+ const frameElement = getFrameElementById(id);
4135
+ if (frameElement) {
4136
+ return !frameElement.disabled;
4137
+ }
4138
+ }
4139
+ if (!session.elementIsNavigatable(element)) {
4140
+ return false;
4141
+ }
4142
+ if (submitter && !session.elementIsNavigatable(submitter)) {
4143
+ return false;
4144
+ }
4145
+ return true;
4146
+ }
4147
+ get id() {
4148
+ return this.element.id;
4149
+ }
4150
+ get enabled() {
4151
+ return !this.element.disabled;
4152
+ }
4153
+ get sourceURL() {
4154
+ if (this.element.src) {
4155
+ return this.element.src;
4156
+ }
4157
+ }
4158
+ set sourceURL(sourceURL) {
4159
+ this.ignoringChangesToAttribute("src", () => {
4160
+ this.element.src = sourceURL !== null && sourceURL !== void 0 ? sourceURL : null;
4161
+ });
4162
+ }
4163
+ get loadingStyle() {
4164
+ return this.element.loading;
4165
+ }
4166
+ get isLoading() {
4167
+ return this.formSubmission !== void 0 || this.resolveVisitPromise() !== void 0;
4168
+ }
4169
+ get complete() {
4170
+ return this.element.hasAttribute("complete");
4171
+ }
4172
+ set complete(value) {
4173
+ this.ignoringChangesToAttribute("complete", () => {
4174
+ if (value) {
4175
+ this.element.setAttribute("complete", "");
4176
+ } else {
4177
+ this.element.removeAttribute("complete");
4178
+ }
4179
+ });
4180
+ }
4181
+ get isActive() {
4182
+ return this.element.isActive && this.connected;
4183
+ }
4184
+ get rootLocation() {
4185
+ var _a;
4186
+ const meta = this.element.ownerDocument.querySelector(`meta[name="turbo-root"]`);
4187
+ const root = (_a = meta === null || meta === void 0 ? void 0 : meta.content) !== null && _a !== void 0 ? _a : "/";
4188
+ return expandURL(root);
4189
+ }
4190
+ isIgnoringChangesTo(attributeName) {
4191
+ return this.ignoredAttributes.has(attributeName);
4192
+ }
4193
+ ignoringChangesToAttribute(attributeName, callback) {
4194
+ this.ignoredAttributes.add(attributeName);
4195
+ callback();
4196
+ this.ignoredAttributes.delete(attributeName);
4197
+ }
4198
+ withCurrentNavigationElement(element, callback) {
4199
+ this.currentNavigationElement = element;
4200
+ callback();
4201
+ delete this.currentNavigationElement;
4202
+ }
4203
+ };
4204
+ function getFrameElementById(id) {
4205
+ if (id != null) {
4206
+ const element = document.getElementById(id);
4207
+ if (element instanceof FrameElement) {
4208
+ return element;
4209
+ }
4210
+ }
4211
+ }
4212
+ function activateElement(element, currentURL) {
4213
+ if (element) {
4214
+ const src = element.getAttribute("src");
4215
+ if (src != null && currentURL != null && urlsAreEqual(src, currentURL)) {
4216
+ throw new Error(`Matching <turbo-frame id="${element.id}"> element has a source URL which references itself`);
4217
+ }
4218
+ if (element.ownerDocument !== document) {
4219
+ element = document.importNode(element, true);
4220
+ }
4221
+ if (element instanceof FrameElement) {
4222
+ element.connectedCallback();
4223
+ element.disconnectedCallback();
4224
+ return element;
4225
+ }
4226
+ }
4227
+ }
4228
+ var StreamElement = class _StreamElement extends HTMLElement {
4229
+ static async renderElement(newElement) {
4230
+ await newElement.performAction();
4231
+ }
4232
+ async connectedCallback() {
4233
+ try {
4234
+ await this.render();
4235
+ } catch (error) {
4236
+ console.error(error);
4237
+ } finally {
4238
+ this.disconnect();
4239
+ }
4240
+ }
4241
+ async render() {
4242
+ var _a;
4243
+ return (_a = this.renderPromise) !== null && _a !== void 0 ? _a : this.renderPromise = (async () => {
4244
+ const event = this.beforeRenderEvent;
4245
+ if (this.dispatchEvent(event)) {
4246
+ await nextAnimationFrame();
4247
+ await event.detail.render(this);
4248
+ }
4249
+ })();
4250
+ }
4251
+ disconnect() {
4252
+ try {
4253
+ this.remove();
4254
+ } catch (_a) {
4255
+ }
4256
+ }
4257
+ removeDuplicateTargetChildren() {
4258
+ this.duplicateChildren.forEach((c) => c.remove());
4259
+ }
4260
+ get duplicateChildren() {
4261
+ var _a;
4262
+ const existingChildren = this.targetElements.flatMap((e) => [...e.children]).filter((c) => !!c.id);
4263
+ const newChildrenIds = [...((_a = this.templateContent) === null || _a === void 0 ? void 0 : _a.children) || []].filter((c) => !!c.id).map((c) => c.id);
4264
+ return existingChildren.filter((c) => newChildrenIds.includes(c.id));
4265
+ }
4266
+ get performAction() {
4267
+ if (this.action) {
4268
+ const actionFunction = StreamActions[this.action];
4269
+ if (actionFunction) {
4270
+ return actionFunction;
4271
+ }
4272
+ this.raise("unknown action");
4273
+ }
4274
+ this.raise("action attribute is missing");
4275
+ }
4276
+ get targetElements() {
4277
+ if (this.target) {
4278
+ return this.targetElementsById;
4279
+ } else if (this.targets) {
4280
+ return this.targetElementsByQuery;
4281
+ } else {
4282
+ this.raise("target or targets attribute is missing");
4283
+ }
4284
+ }
4285
+ get templateContent() {
4286
+ return this.templateElement.content.cloneNode(true);
4287
+ }
4288
+ get templateElement() {
4289
+ if (this.firstElementChild === null) {
4290
+ const template = this.ownerDocument.createElement("template");
4291
+ this.appendChild(template);
4292
+ return template;
4293
+ } else if (this.firstElementChild instanceof HTMLTemplateElement) {
4294
+ return this.firstElementChild;
4295
+ }
4296
+ this.raise("first child element must be a <template> element");
4297
+ }
4298
+ get action() {
4299
+ return this.getAttribute("action");
4300
+ }
4301
+ get target() {
4302
+ return this.getAttribute("target");
4303
+ }
4304
+ get targets() {
4305
+ return this.getAttribute("targets");
4306
+ }
4307
+ raise(message) {
4308
+ throw new Error(`${this.description}: ${message}`);
4309
+ }
4310
+ get description() {
4311
+ var _a, _b;
4312
+ return (_b = ((_a = this.outerHTML.match(/<[^>]+>/)) !== null && _a !== void 0 ? _a : [])[0]) !== null && _b !== void 0 ? _b : "<turbo-stream>";
4313
+ }
4314
+ get beforeRenderEvent() {
4315
+ return new CustomEvent("turbo:before-stream-render", {
4316
+ bubbles: true,
4317
+ cancelable: true,
4318
+ detail: { newStream: this, render: _StreamElement.renderElement }
4319
+ });
4320
+ }
4321
+ get targetElementsById() {
4322
+ var _a;
4323
+ const element = (_a = this.ownerDocument) === null || _a === void 0 ? void 0 : _a.getElementById(this.target);
4324
+ if (element !== null) {
4325
+ return [element];
4326
+ } else {
4327
+ return [];
4328
+ }
4329
+ }
4330
+ get targetElementsByQuery() {
4331
+ var _a;
4332
+ const elements = (_a = this.ownerDocument) === null || _a === void 0 ? void 0 : _a.querySelectorAll(this.targets);
4333
+ if (elements.length !== 0) {
4334
+ return Array.prototype.slice.call(elements);
4335
+ } else {
4336
+ return [];
4337
+ }
4338
+ }
4339
+ };
4340
+ var StreamSourceElement = class extends HTMLElement {
4341
+ constructor() {
4342
+ super(...arguments);
4343
+ this.streamSource = null;
4344
+ }
4345
+ connectedCallback() {
4346
+ this.streamSource = this.src.match(/^ws{1,2}:/) ? new WebSocket(this.src) : new EventSource(this.src);
4347
+ connectStreamSource(this.streamSource);
4348
+ }
4349
+ disconnectedCallback() {
4350
+ if (this.streamSource) {
4351
+ disconnectStreamSource(this.streamSource);
4352
+ }
4353
+ }
4354
+ get src() {
4355
+ return this.getAttribute("src") || "";
4356
+ }
4357
+ };
4358
+ FrameElement.delegateConstructor = FrameController;
4359
+ if (customElements.get("turbo-frame") === void 0) {
4360
+ customElements.define("turbo-frame", FrameElement);
4361
+ }
4362
+ if (customElements.get("turbo-stream") === void 0) {
4363
+ customElements.define("turbo-stream", StreamElement);
4364
+ }
4365
+ if (customElements.get("turbo-stream-source") === void 0) {
4366
+ customElements.define("turbo-stream-source", StreamSourceElement);
4367
+ }
4368
+ (() => {
4369
+ let element = document.currentScript;
4370
+ if (!element)
4371
+ return;
4372
+ if (element.hasAttribute("data-turbo-suppress-warning"))
4373
+ return;
4374
+ element = element.parentElement;
4375
+ while (element) {
4376
+ if (element == document.body) {
4377
+ return console.warn(unindent`
4378
+ You are loading Turbo from a <script> element inside the <body> element. This is probably not what you meant to do!
4379
+
4380
+ Load your application’s JavaScript bundle inside the <head> element instead. <script> elements in <body> are evaluated with each page change.
4381
+
4382
+ For more information, see: https://turbo.hotwired.dev/handbook/building#working-with-script-elements
4383
+
4384
+ ——
4385
+ Suppress this warning by adding a "data-turbo-suppress-warning" attribute to: %s
4386
+ `, element.outerHTML);
4387
+ }
4388
+ element = element.parentElement;
4389
+ }
4390
+ })();
4391
+ window.Turbo = Turbo;
4392
+ start();
4393
+
4394
+ // node_modules/@hotwired/turbo-rails/app/javascript/turbo/cable.js
4395
+ var consumer;
4396
+ async function getConsumer() {
4397
+ return consumer || setConsumer(createConsumer2().then(setConsumer));
4398
+ }
4399
+ function setConsumer(newConsumer) {
4400
+ return consumer = newConsumer;
4401
+ }
4402
+ async function createConsumer2() {
4403
+ const { createConsumer: createConsumer3 } = await Promise.resolve().then(() => (init_src(), src_exports));
4404
+ return createConsumer3();
4405
+ }
4406
+ async function subscribeTo(channel, mixin) {
4407
+ const { subscriptions } = await getConsumer();
4408
+ return subscriptions.create(channel, mixin);
4409
+ }
4410
+
4411
+ // node_modules/@hotwired/turbo-rails/app/javascript/turbo/snakeize.js
4412
+ function walk(obj) {
4413
+ if (!obj || typeof obj !== "object")
4414
+ return obj;
4415
+ if (obj instanceof Date || obj instanceof RegExp)
4416
+ return obj;
4417
+ if (Array.isArray(obj))
4418
+ return obj.map(walk);
4419
+ return Object.keys(obj).reduce(function(acc, key) {
4420
+ var camel = key[0].toLowerCase() + key.slice(1).replace(/([A-Z]+)/g, function(m, x) {
4421
+ return "_" + x.toLowerCase();
4422
+ });
4423
+ acc[camel] = walk(obj[key]);
4424
+ return acc;
4425
+ }, {});
4426
+ }
4427
+
4428
+ // node_modules/@hotwired/turbo-rails/app/javascript/turbo/cable_stream_source_element.js
4429
+ var TurboCableStreamSourceElement = class extends HTMLElement {
4430
+ async connectedCallback() {
4431
+ connectStreamSource(this);
4432
+ this.subscription = await subscribeTo(this.channel, {
4433
+ received: this.dispatchMessageEvent.bind(this),
4434
+ connected: this.subscriptionConnected.bind(this),
4435
+ disconnected: this.subscriptionDisconnected.bind(this)
4436
+ });
4437
+ }
4438
+ disconnectedCallback() {
4439
+ disconnectStreamSource(this);
4440
+ if (this.subscription)
4441
+ this.subscription.unsubscribe();
4442
+ }
4443
+ dispatchMessageEvent(data) {
4444
+ const event = new MessageEvent("message", { data });
4445
+ return this.dispatchEvent(event);
4446
+ }
4447
+ subscriptionConnected() {
4448
+ this.setAttribute("connected", "");
4449
+ }
4450
+ subscriptionDisconnected() {
4451
+ this.removeAttribute("connected");
4452
+ }
4453
+ get channel() {
4454
+ const channel = this.getAttribute("channel");
4455
+ const signed_stream_name = this.getAttribute("signed-stream-name");
4456
+ return { channel, signed_stream_name, ...walk({ ...this.dataset }) };
4457
+ }
4458
+ };
4459
+ if (customElements.get("turbo-cable-stream-source") === void 0) {
4460
+ customElements.define("turbo-cable-stream-source", TurboCableStreamSourceElement);
4461
+ }
4462
+
4463
+ // node_modules/@hotwired/turbo-rails/app/javascript/turbo/fetch_requests.js
4464
+ function encodeMethodIntoRequestBody(event) {
4465
+ if (event.target instanceof HTMLFormElement) {
4466
+ const { target: form, detail: { fetchOptions } } = event;
4467
+ form.addEventListener("turbo:submit-start", ({ detail: { formSubmission: { submitter } } }) => {
4468
+ const body = isBodyInit(fetchOptions.body) ? fetchOptions.body : new URLSearchParams();
4469
+ const method = determineFetchMethod(submitter, body, form);
4470
+ if (!/get/i.test(method)) {
4471
+ if (/post/i.test(method)) {
4472
+ body.delete("_method");
4473
+ } else {
4474
+ body.set("_method", method);
4475
+ }
4476
+ fetchOptions.method = "post";
4477
+ }
4478
+ }, { once: true });
4479
+ }
4480
+ }
4481
+ function determineFetchMethod(submitter, body, form) {
4482
+ const formMethod = determineFormMethod(submitter);
4483
+ const overrideMethod = body.get("_method");
4484
+ const method = form.getAttribute("method") || "get";
4485
+ if (typeof formMethod == "string") {
4486
+ return formMethod;
4487
+ } else if (typeof overrideMethod == "string") {
4488
+ return overrideMethod;
4489
+ } else {
4490
+ return method;
4491
+ }
4492
+ }
4493
+ function determineFormMethod(submitter) {
4494
+ if (submitter instanceof HTMLButtonElement || submitter instanceof HTMLInputElement) {
4495
+ if (submitter.hasAttribute("formmethod")) {
4496
+ return submitter.formMethod;
4497
+ } else {
4498
+ return null;
4499
+ }
4500
+ } else {
4501
+ return null;
4502
+ }
4503
+ }
4504
+ function isBodyInit(body) {
4505
+ return body instanceof FormData || body instanceof URLSearchParams;
4506
+ }
4507
+
4508
+ // node_modules/@hotwired/turbo-rails/app/javascript/turbo/index.js
4509
+ addEventListener("turbo:before-fetch-request", encodeMethodIntoRequestBody);