haori 0.5.0 → 0.6.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.
package/dist/haori.es.js CHANGED
@@ -1,23 +1,23 @@
1
- const B = class B {
1
+ const H = class H {
2
2
  /**
3
3
  * 開発モードの状態を取得します。
4
4
  *
5
5
  * @returns 開発モードならtrue、そうでなければfalse
6
6
  */
7
7
  static isEnabled() {
8
- return B.devMode;
8
+ return H.devMode;
9
9
  }
10
10
  /**
11
11
  * 開発モードを有効化します。
12
12
  */
13
13
  static enable() {
14
- B.devMode = !0;
14
+ H.devMode = !0;
15
15
  }
16
16
  /**
17
17
  * 開発モードを無効化します。
18
18
  */
19
19
  static disable() {
20
- B.devMode = !1;
20
+ H.devMode = !1;
21
21
  }
22
22
  /**
23
23
  * 開発モードを切り替えます。
@@ -25,17 +25,17 @@ const B = class B {
25
25
  * @param enabled trueで有効化、falseで無効化
26
26
  */
27
27
  static set(t) {
28
- B.devMode = t;
28
+ H.devMode = t;
29
29
  }
30
30
  };
31
- B.devMode = !1;
32
- let U = B;
33
- const Z = "embedded";
34
- function it(E) {
31
+ H.devMode = !1;
32
+ let L = H;
33
+ const _ = "embedded";
34
+ function st(E) {
35
35
  return E === "embedded" || E === "demo";
36
36
  }
37
- function nt(E) {
38
- return E === null ? null : it(E) ? E : Z;
37
+ function at(E) {
38
+ return E === null ? null : st(E) ? E : _;
39
39
  }
40
40
  const k = class k {
41
41
  /**
@@ -53,7 +53,7 @@ const k = class k {
53
53
  * @return 戻り値はありません。
54
54
  */
55
55
  static setRuntime(t) {
56
- k._runtime = it(t) ? t : Z;
56
+ k._runtime = st(t) ? t : _;
57
57
  }
58
58
  /**
59
59
  * 実行環境からプレフィックスと開発モードかどうかを自動検出します。
@@ -67,21 +67,21 @@ const k = class k {
67
67
  if (t instanceof HTMLScriptElement) {
68
68
  const r = t.getAttribute("data-prefix") || k._prefix;
69
69
  k._prefix = r.endsWith("-") ? r : r + "-";
70
- const s = nt(
70
+ const s = at(
71
71
  t.getAttribute("data-runtime")
72
72
  );
73
73
  s !== null && (k._runtime = s);
74
74
  }
75
75
  if (t instanceof HTMLScriptElement && t.hasAttribute(`${k._prefix}dev`)) {
76
- U.set(!0);
76
+ L.set(!0);
77
77
  return;
78
78
  }
79
79
  const e = window.location.hostname;
80
80
  if (e === "localhost" || e.endsWith(".localhost") || e === "127.0.0.1" || e === "::1" || e.endsWith(".local")) {
81
- U.set(!0);
81
+ L.set(!0);
82
82
  return;
83
83
  }
84
- U.set(!1);
84
+ L.set(!1);
85
85
  } catch {
86
86
  }
87
87
  }
@@ -94,9 +94,9 @@ const k = class k {
94
94
  return k._prefix;
95
95
  }
96
96
  };
97
- k._prefix = "data-", k._runtime = Z;
98
- let c = k;
99
- document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", c.detect) : c.detect();
97
+ k._prefix = "data-", k._runtime = _;
98
+ let u = k;
99
+ document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", u.detect) : u.detect();
100
100
  class m {
101
101
  /**
102
102
  * 開発モードでのみコンソールに情報を出力します。
@@ -105,7 +105,7 @@ class m {
105
105
  * @param args 追加の引数
106
106
  */
107
107
  static info(t, ...e) {
108
- U.isEnabled() && console.log && console.log(t, ...e);
108
+ L.isEnabled() && console.log && console.log(t, ...e);
109
109
  }
110
110
  /**
111
111
  * 開発モードでのみコンソールに警告を出力します。
@@ -114,7 +114,7 @@ class m {
114
114
  * @param args 追加の引数
115
115
  */
116
116
  static warn(t, ...e) {
117
- U.isEnabled() && console.warn && console.warn(t, ...e);
117
+ L.isEnabled() && console.warn && console.warn(t, ...e);
118
118
  }
119
119
  /**
120
120
  * モードに関係なくコンソールにエラーを出力します。
@@ -126,1165 +126,1165 @@ class m {
126
126
  console.error(t, ...e);
127
127
  }
128
128
  }
129
- class at {
130
- constructor() {
131
- this.MAX_BUDGET = 8, this.queue = [], this.processing = !1;
132
- }
133
- /**
134
- * 処理をキューに追加します
135
- *
136
- * @param task 実行する処理
137
- * @param prepend trueの場合はキューの先頭に追加、falseの場合は末尾に追加
138
- * @returns 処理完了Promise
139
- */
140
- enqueue(t, e = !1) {
141
- let r, s;
142
- const i = new Promise((a, o) => {
143
- r = a, s = o;
144
- }), n = {
145
- task: t,
146
- timestamp: performance.now(),
147
- promise: i,
148
- resolve: r,
149
- reject: s
150
- };
151
- return e ? this.queue.unshift(n) : this.queue.push(n), this.scheduleProcessing(), i;
152
- }
153
- /**
154
- * キューを処理します。
155
- *
156
- * @returns 処理完了Promise
157
- */
158
- async processQueue() {
159
- if (!(this.processing || this.queue.length === 0)) {
160
- this.processing = !0;
161
- try {
162
- const t = performance.now();
163
- for (; this.queue.length > 0; ) {
164
- const e = this.queue.shift();
165
- if (!e)
166
- return;
167
- try {
168
- const r = await e.task();
169
- e.resolve(r);
170
- } catch (r) {
171
- e.reject(r), m.error("[Haori]", `Task ${e.timestamp} failed:`, r);
172
- }
173
- if (performance.now() - t > this.MAX_BUDGET)
174
- break;
175
- }
176
- } catch (t) {
177
- m.error("[Haori]", "Error processing queue:", t);
178
- } finally {
179
- this.processing = !1, this.queue.length > 0 && this.scheduleProcessing();
180
- }
181
- }
182
- }
183
- /**
184
- * 処理をスケジュールします。
185
- */
186
- scheduleProcessing() {
187
- this.processing || (typeof requestAnimationFrame < "u" ? requestAnimationFrame(() => {
188
- this.processQueue();
189
- }) : setTimeout(() => {
190
- this.processQueue();
191
- }, 16));
192
- }
129
+ const x = class x {
193
130
  /**
194
- * キューが空になるまで待機します。
131
+ * 明示バインド内に持ち込まれてはならない危険値を返します。
195
132
  *
196
- * @returns キューが空になったら解決されるPromise
133
+ * @returns 危険値の配列
197
134
  */
198
- async wait() {
199
- if (this.queue.length === 0 && !this.processing)
200
- return;
201
- const t = this.queue.map((e) => e.promise);
202
- t.length > 0 && await Promise.allSettled(t);
135
+ static getForbiddenBindingValues() {
136
+ const t = globalThis, e = [
137
+ t,
138
+ t.window,
139
+ t.document,
140
+ t.navigator,
141
+ t.history,
142
+ t.localStorage,
143
+ t.sessionStorage,
144
+ t.fetch,
145
+ t.Function,
146
+ t.setTimeout,
147
+ t.setInterval,
148
+ t.requestAnimationFrame,
149
+ t.alert,
150
+ t.confirm,
151
+ t.prompt
152
+ ];
153
+ return t.window?.location && e.push(t.window.location), e.filter((r) => r != null);
203
154
  }
204
- }
205
- const et = class et {
206
155
  /**
207
- * タスクをキューに追加します。
156
+ * 現在のバインド識別子に含まれない禁止グローバルを遮断するコードを生成します。
208
157
  *
209
- * @param task 実行する処理
210
- * @param prepend trueの場合はキューの先頭に追加、falseの場合は末尾に追加
211
- * @returns 処理完了Promise
212
- */
213
- static enqueue(t, e = !1) {
214
- return this.ASYNC_QUEUE.enqueue(t, e);
215
- }
216
- /**
217
- * 全てのキュー処理が完了するまで待機します。
158
+ * @param bindKeys 現在の式で利用するバインド識別子一覧
159
+ * @returns 評価前に挿入する初期化コード
218
160
  */
219
- static wait() {
220
- return this.ASYNC_QUEUE.wait();
161
+ static buildAssignments(t) {
162
+ const e = new Set(t);
163
+ return this.FORBIDDEN_NAMES.filter((r) => !e.has(r)).map((r) => `const ${r} = undefined`).join(`;
164
+ `);
221
165
  }
222
- };
223
- et.ASYNC_QUEUE = new at();
224
- let N = et;
225
- class Y {
226
166
  /**
227
- * 実行モードを取得します。
167
+ * 式を評価します。
228
168
  *
229
- * @return 実行モード。
169
+ * @param expression 評価する式文字列
170
+ * @param bindedValue バインドされた値のオブジェクト
230
171
  */
231
- static get runtime() {
232
- return c.runtime;
172
+ static evaluate(t, e = {}) {
173
+ return this.evaluateDetailed(t, e).value;
233
174
  }
234
175
  /**
235
- * 実行モードを設定します。
176
+ * 式を評価し、未解決参照の有無を含む詳細結果を返します。
236
177
  *
237
- * @param runtime 設定する実行モード。
238
- * @return 戻り値はありません。
178
+ * @param expression 評価する式文字列
179
+ * @param bindedValues バインドされた値のオブジェクト
180
+ * @returns 評価結果と未解決参照の有無
239
181
  */
240
- static setRuntime(t) {
241
- c.setRuntime(t);
182
+ static evaluateDetailed(t, e = {}) {
183
+ if (t.trim() === "")
184
+ return m.warn("[Haori]", t, "Expression is empty"), { value: null, unresolvedReference: !1 };
185
+ if (this.containsDangerousPatterns(t))
186
+ return m.warn("[Haori]", t, "Expression contains dangerous patterns"), { value: null, unresolvedReference: !1 };
187
+ if (this.containsForbiddenKeys(e))
188
+ return m.warn("[Haori]", e, "Binded values contain forbidden keys"), { value: null, unresolvedReference: !1 };
189
+ if (this.containsForbiddenBindingValues(e))
190
+ return m.warn(
191
+ "[Haori]",
192
+ e,
193
+ "Binded values contain forbidden values"
194
+ ), { value: null, unresolvedReference: !1 };
195
+ const r = Object.keys(e).filter((n) => !this.FORBIDDEN_BINDING_NAMES.has(n)).sort(), s = `${t}:${r.join(",")}`;
196
+ let i = this.EXPRESSION_CACHE.get(s);
197
+ if (!i) {
198
+ const n = this.buildAssignments(r), a = n ? `"use strict";
199
+ ${n};
200
+ return (${t});` : `"use strict";
201
+ return (${t});`;
202
+ try {
203
+ i = new Function(...r, a), this.EXPRESSION_CACHE.set(s, i);
204
+ } catch (o) {
205
+ return m.error(
206
+ "[Haori]",
207
+ "Failed to compile expression:",
208
+ t,
209
+ o
210
+ ), { value: null, unresolvedReference: !1 };
211
+ }
212
+ }
213
+ try {
214
+ const n = [], a = this.wrapBoundValues(e);
215
+ return r.forEach((o) => {
216
+ n.push(a[o]);
217
+ }), {
218
+ value: this.withBlockedPropertyAccess(() => i(...n)),
219
+ unresolvedReference: !1
220
+ };
221
+ } catch (n) {
222
+ return m.error("[Haori]", "Expression evaluation error:", t, n), n instanceof ReferenceError ? { value: void 0, unresolvedReference: !0 } : { value: null, unresolvedReference: !1 };
223
+ }
242
224
  }
243
225
  /**
244
- * 通知ダイアログを表示します。
226
+ * 式にevalや危険な構文が含まれているかチェックします。
245
227
  *
246
- * @param message 表示メッセージ
247
- * @returns 通知が閉じられると解決されるPromise
228
+ * @param expression チェック対象の式文字列
229
+ * @return 危険なパターンが含まれている場合はtrue
248
230
  */
249
- static dialog(t) {
250
- return N.enqueue(() => {
251
- window.alert(t);
252
- }, !0);
231
+ static containsDangerousPatterns(t) {
232
+ return this.hasAllowedSyntax(t) ? [
233
+ /\beval\s*\(/,
234
+ // eval(...)
235
+ /\barguments\s*\[/,
236
+ // arguments[...]
237
+ /\barguments\s*\./
238
+ // arguments.xxx
239
+ ].some((r) => r.test(t)) : !0;
253
240
  }
254
241
  /**
255
- * 通知トーストを表示します。
242
+ * 許可する式構文かどうかを検証します。
256
243
  *
257
- * @param message 表示メッセージ
258
- * @param level メッセージのレベル(省略時は 'info')
259
- * @return 通知が表示されると解決されるPromise
244
+ * @param expression 検証対象の式
245
+ * @returns 許可する構文であればtrue
260
246
  */
261
- static async toast(t, e = "info") {
262
- const r = document.createElement("div");
263
- r.className = `haori-toast haori-toast-${e}`, r.textContent = t, r.setAttribute("popover", "manual"), r.setAttribute("role", "status"), r.setAttribute("aria-live", e === "error" ? "assertive" : "polite"), document.body.appendChild(r), r.showPopover(), setTimeout(() => {
264
- try {
265
- r.hidePopover();
266
- } finally {
267
- r.remove();
247
+ static hasAllowedSyntax(t) {
248
+ const e = this.tokenizeExpression(t);
249
+ if (e === null || e.length === 0)
250
+ return !1;
251
+ const r = [];
252
+ let s = null;
253
+ for (let i = 0; i < e.length; i++) {
254
+ const n = e[i], a = e[i + 1] || null, o = r[r.length - 1] || null, d = e[i - 2] || null, p = e[i - 3] || null;
255
+ if (this.startsObjectKey(
256
+ o,
257
+ s,
258
+ d,
259
+ p
260
+ ) && (n.value === "[" || n.type === "identifier" && this.FORBIDDEN_PROPERTY_NAMES.has(n.value) || n.type === "string" && this.FORBIDDEN_PROPERTY_NAMES.has(
261
+ this.decodeStringLiteral(n.value)
262
+ )) || n.type === "identifier" && (this.DISALLOWED_KEYWORDS.has(n.value) || this.STRICT_FORBIDDEN_NAMES.includes(n.value) || (s?.value === "." || s?.value === "?.") && this.FORBIDDEN_PROPERTY_NAMES.has(n.value)) || o === "member" && n.value !== "]" && n.type === "string" && this.FORBIDDEN_PROPERTY_NAMES.has(
263
+ this.decodeStringLiteral(n.value)
264
+ ) || n.value === "." && a?.type !== "identifier" || n.value === "?." && a?.type !== "identifier" && a?.value !== "[" && a?.value !== "(")
265
+ return !1;
266
+ switch (n.value) {
267
+ case "(":
268
+ r.push("paren");
269
+ break;
270
+ case ")": {
271
+ if (r.pop() !== "paren")
272
+ return !1;
273
+ break;
274
+ }
275
+ case "[": {
276
+ const g = this.startsMemberAccess(s) ? "member" : "array";
277
+ r.push(g);
278
+ break;
279
+ }
280
+ case "{":
281
+ r.push("object");
282
+ break;
283
+ case "]": {
284
+ if (r.pop() === void 0)
285
+ return !1;
286
+ break;
287
+ }
288
+ case "}": {
289
+ if (r.pop() !== "object")
290
+ return !1;
291
+ break;
292
+ }
268
293
  }
269
- }, 3e3);
294
+ s = n;
295
+ }
296
+ return r.length === 0;
270
297
  }
271
298
  /**
272
- * 確認ダイアログを表示します。
299
+ * 式をトークン列に分解します。
273
300
  *
274
- * @param message 確認メッセージ
275
- * @returns ユーザーがOKをクリックした場合はtrue、キャンセルした場合はfalseが解決されるPromise
301
+ * @param expression 評価前に検証する式
302
+ * @returns 分解結果。未対応構文を含む場合はnull
276
303
  */
277
- static confirm(t) {
278
- return N.enqueue(() => window.confirm(t), !0);
304
+ static tokenizeExpression(t) {
305
+ const e = [], r = [
306
+ "===",
307
+ "!==",
308
+ "...",
309
+ "?.",
310
+ "&&",
311
+ "||",
312
+ ">=",
313
+ "<=",
314
+ "==",
315
+ "!=",
316
+ "=>"
317
+ ], s = /* @__PURE__ */ new Set([
318
+ "(",
319
+ ")",
320
+ "{",
321
+ "}",
322
+ "[",
323
+ "]",
324
+ ".",
325
+ ",",
326
+ "?",
327
+ ":",
328
+ "+",
329
+ "-",
330
+ "*",
331
+ "/",
332
+ "%",
333
+ "!",
334
+ ">",
335
+ "<"
336
+ ]);
337
+ let i = 0;
338
+ for (; i < t.length; ) {
339
+ const n = t[i];
340
+ if (/\s/.test(n)) {
341
+ i += 1;
342
+ continue;
343
+ }
344
+ if (n === "/" && (t[i + 1] === "/" || t[i + 1] === "*"))
345
+ return null;
346
+ if (n === '"' || n === "'") {
347
+ const o = this.readStringToken(t, i);
348
+ if (o === null)
349
+ return null;
350
+ e.push(o.token), i = o.nextIndex;
351
+ continue;
352
+ }
353
+ const a = r.find(
354
+ (o) => t.startsWith(o, i)
355
+ );
356
+ if (a) {
357
+ e.push({ type: "operator", value: a, position: i }), i += a.length;
358
+ continue;
359
+ }
360
+ if (/[0-9]/.test(n)) {
361
+ const o = this.readNumberToken(t, i);
362
+ e.push(o.token), i = o.nextIndex;
363
+ continue;
364
+ }
365
+ if (/[A-Za-z_$]/.test(n)) {
366
+ const o = this.readIdentifierToken(t, i);
367
+ e.push(o.token), i = o.nextIndex;
368
+ continue;
369
+ }
370
+ if (s.has(n)) {
371
+ e.push({ type: "operator", value: n, position: i }), i += 1;
372
+ continue;
373
+ }
374
+ return null;
375
+ }
376
+ return e;
279
377
  }
280
378
  /**
281
- * ダイアログを開きます。
379
+ * 文字列リテラルを読み取ります。
282
380
  *
283
- * @param element 開くダイアログのHTML要素
381
+ * @param expression 式全体
382
+ * @param start 開始位置
383
+ * @returns トークンと次の位置
284
384
  */
285
- static openDialog(t) {
286
- return N.enqueue(() => {
287
- t instanceof HTMLDialogElement ? t.showModal() : m.error("[Haori]", "Element is not a dialog: ", t);
288
- }, !0);
385
+ static readStringToken(t, e) {
386
+ const r = t[e];
387
+ let s = e + 1;
388
+ for (; s < t.length; ) {
389
+ const i = t[s];
390
+ if (i === "\\") {
391
+ s += 2;
392
+ continue;
393
+ }
394
+ if (i === r)
395
+ return {
396
+ token: {
397
+ type: "string",
398
+ value: t.slice(e, s + 1),
399
+ position: e
400
+ },
401
+ nextIndex: s + 1
402
+ };
403
+ s += 1;
404
+ }
405
+ return null;
289
406
  }
290
407
  /**
291
- * ダイアログを閉じます。
408
+ * 数値リテラルを読み取ります。
292
409
  *
293
- * @param element 閉じるダイアログのHTML要素
410
+ * @param expression 式全体
411
+ * @param start 開始位置
412
+ * @returns トークンと次の位置
294
413
  */
295
- static closeDialog(t) {
296
- return N.enqueue(() => {
297
- t instanceof HTMLDialogElement ? t.close() : m.error("[Haori]", "Element is not a dialog: ", t);
298
- }, !0);
414
+ static readNumberToken(t, e) {
415
+ let r = e;
416
+ for (; r < t.length && /[0-9_]/.test(t[r]); )
417
+ r += 1;
418
+ if (t[r] === ".")
419
+ for (r += 1; r < t.length && /[0-9_]/.test(t[r]); )
420
+ r += 1;
421
+ return {
422
+ token: {
423
+ type: "number",
424
+ value: t.slice(e, r),
425
+ position: e
426
+ },
427
+ nextIndex: r
428
+ };
299
429
  }
300
430
  /**
301
- * エラーメッセージを追加します。
431
+ * 識別子を読み取ります。
302
432
  *
303
- * @param target メッセージを表示する要素
304
- * @param message エラーメッセージ
433
+ * @param expression 式全体
434
+ * @param start 開始位置
435
+ * @returns トークンと次の位置
305
436
  */
306
- static addErrorMessage(t, e) {
307
- return Y.addMessage(t, e, "error");
437
+ static readIdentifierToken(t, e) {
438
+ let r = e;
439
+ for (; r < t.length && /[A-Za-z0-9_$]/.test(t[r]); )
440
+ r += 1;
441
+ return {
442
+ token: {
443
+ type: "identifier",
444
+ value: t.slice(e, r),
445
+ position: e
446
+ },
447
+ nextIndex: r
448
+ };
308
449
  }
309
450
  /**
310
- * メッセージをレベル付きで追加します。
451
+ * 角括弧がメンバーアクセスかどうかを判定します。
311
452
  *
312
- * @param target メッセージを表示する要素
313
- * @param message メッセージ
314
- * @param level メッセージのレベル(省略可能)
453
+ * @param previous 直前のトークン
454
+ * @returns メンバーアクセスであればtrue
315
455
  */
316
- static addMessage(t, e, r) {
317
- return N.enqueue(() => {
318
- const s = t instanceof HTMLFormElement ? t : t.parentElement ?? t;
319
- s.setAttribute("data-message", e), r !== void 0 ? s.setAttribute("data-message-level", r) : s.removeAttribute("data-message-level");
320
- }, !0);
456
+ static startsMemberAccess(t) {
457
+ return t === null ? !1 : t.type === "identifier" || t.type === "number" ? !0 : t.value === ")" || t.value === "]" || t.value === "?.";
321
458
  }
322
459
  /**
323
- * 対象のエレメントおよびその子要素のメッセージをクリアします。
460
+ * object literal 内で次のトークンがキー位置かどうかを判定します。
324
461
  *
325
- * @param parent メッセージをクリアする親要素
462
+ * @param activeGroup 現在のグループ種別
463
+ * @param previous 直前のトークン
464
+ * @returns object literal のキー位置であれば true
326
465
  */
327
- static clearMessages(t) {
328
- return N.enqueue(() => {
329
- t.removeAttribute("data-message"), t.removeAttribute("data-message-level"), t.querySelectorAll("[data-message]").forEach((e) => {
330
- e.removeAttribute("data-message"), e.removeAttribute("data-message-level");
331
- });
332
- }, !0);
466
+ static startsObjectKey(t, e, r, s) {
467
+ return t !== "object" ? !1 : e?.value === "{" || e?.value === "," || e?.type === "identifier" && this.OBJECT_PROPERTY_MODIFIERS.has(e.value) && (r?.value === "{" || r?.value === ",") ? !0 : e?.value !== "*" ? !1 : r?.value === "{" || r?.value === "," ? !0 : r?.type === "identifier" && r.value === "async" && (s?.value === "{" || s?.value === ",");
333
468
  }
334
- }
335
- const ot = ["addErrorMessage", "clearMessages"];
336
- function st() {
337
- const t = globalThis.window?.Haori;
338
- return ot.every(
339
- (r) => typeof t?.[r] == "function"
340
- ) ? t : Y;
341
- }
342
- class v {
343
469
  /**
344
- * フォーム内にある入力エレメントの値をオブジェクトとして取得します。
345
- * data-form-object属性があると、そのエレメント内の値はオブジェクトとして処理されます。
346
- * 入力エレメントにdata-form-list属性があると、そのエレメントの値はリストとして処理されます。
347
- * 入力エレメント以外にdata-form-list属性があると、そのエレメントの値はオブジェクトのリストとして処理されます。
470
+ * 文字列リテラルをプレーン文字列へ変換します。
348
471
  *
349
- * @param form フォームのElementFragment
472
+ * @param literal 文字列リテラル
473
+ * @returns デコード後の文字列
350
474
  */
351
- static getValues(t) {
352
- const e = {};
353
- return v.getPartValues(t, e);
475
+ static decodeStringLiteral(t) {
476
+ return t.slice(1, -1).replace(
477
+ /\\u\{([0-9a-fA-F]+)\}/g,
478
+ (e, r) => String.fromCodePoint(parseInt(r, 16))
479
+ ).replace(
480
+ /\\u([0-9a-fA-F]{4})/g,
481
+ (e, r) => String.fromCharCode(parseInt(r, 16))
482
+ ).replace(
483
+ /\\x([0-9a-fA-F]{2})/g,
484
+ (e, r) => String.fromCharCode(parseInt(r, 16))
485
+ ).replace(/\\(["'\\bfnrtv0])/g, (e, r) => {
486
+ switch (r) {
487
+ case "b":
488
+ return "\b";
489
+ case "f":
490
+ return "\f";
491
+ case "n":
492
+ return `
493
+ `;
494
+ case "r":
495
+ return "\r";
496
+ case "t":
497
+ return " ";
498
+ case "v":
499
+ return "\v";
500
+ case "0":
501
+ return "\0";
502
+ default:
503
+ return r;
504
+ }
505
+ });
354
506
  }
355
507
  /**
356
- * フォーム内の各入力エレメントから値を取得し、オブジェクトとして返します。
357
- * 入力エレメントのname属性、data-form-object属性、data-form-list属性に基づいて値を整理します。
508
+ * バインド値を安全なProxyでラップします。
358
509
  *
359
- * @param fragment 対象のElementFragment
360
- * @param values オブジェクトに追加する値のオブジェクト
361
- * @returns values と同じオブジェクト
510
+ * @param bindedValues バインド値
511
+ * @returns ラップ済みのバインド値
362
512
  */
363
- static getPartValues(t, e) {
364
- const r = t.getAttribute("name"), s = t.getAttribute(`${c.prefix}form-object`), i = t.getAttribute(`${c.prefix}form-list`);
365
- if (r) {
366
- i ? Array.isArray(e[String(r)]) ? e[String(r)].push(t.getValue()) : e[String(r)] = [t.getValue()] : e[String(r)] = t.getValue(), s && m.warn(
367
- "Haori",
368
- `Element cannot have both ${c.prefix}form-object and name attributes.`
369
- );
370
- for (const n of t.getChildElementFragments())
371
- v.getPartValues(n, e);
372
- } else if (s) {
373
- const n = {};
374
- for (const a of t.getChildElementFragments())
375
- v.getPartValues(a, n);
376
- Object.keys(n).length > 0 && (e[String(s)] = n), i && m.warn(
377
- "Haori",
378
- `Element cannot have both ${c.prefix}form-list and ${c.prefix}form-object attributes.`
379
- );
380
- } else if (i) {
381
- const n = [];
382
- for (const a of t.getChildElementFragments()) {
383
- const o = {};
384
- v.getPartValues(a, o), Object.keys(o).length > 0 && n.push(o);
385
- }
386
- n.length > 0 && (e[String(i)] = n);
387
- } else
388
- for (const n of t.getChildElementFragments())
389
- v.getPartValues(n, e);
390
- return e;
391
- }
392
- /**
393
- * フォーム内にある入力エレメントに値を設定します。
394
- * フォームのdata-bind属性に値が反映されます。
395
- *
396
- * @param form フォームのElementFragment
397
- * @param values フォームに設定する値のオブジェクト
398
- * @param force data-form-detach属性があるエレメントにも値を反映するかどうか
399
- * @returns Promise(DOMの更新が完了したら解決される)
400
- */
401
- static setValues(t, e, r = !1) {
402
- return v.setPartValues(t, e, null, r, !0);
403
- }
404
- /**
405
- * フォーム内にある入力エレメントに値をイベントなしで設定します。
406
- * フォーム bindingData からの内部同期に利用します。
407
- *
408
- * @param form フォームのElementFragment
409
- * @param values フォームに設定する値のオブジェクト
410
- * @param force data-form-detach属性があるエレメントにも値を反映するかどうか
411
- * @returns Promise(DOMの更新が完了したら解決される)
412
- */
413
- static syncValues(t, e, r = !1) {
414
- return v.setPartValues(t, e, null, r, !1);
415
- }
416
- /**
417
- * 単一フラグメントへ値を設定します。
418
- *
419
- * @param fragment 対象フラグメント
420
- * @param value 設定する値
421
- * @param emitEvents input/change イベントを発火するかどうか
422
- * @returns Promise(DOMの更新が完了したら解決される)
423
- */
424
- static applyFragmentValue(t, e, r) {
425
- return r ? t.setValue(e) : t.syncBindingValue(e);
513
+ static wrapBoundValues(t) {
514
+ const e = /* @__PURE__ */ new WeakMap(), r = {};
515
+ return Object.entries(t).forEach(([s, i]) => {
516
+ r[s] = this.wrapBoundValue(i, e);
517
+ }), r;
426
518
  }
427
519
  /**
428
- * フラグメント内にある各入力エレメントに値を設定します。
520
+ * 危険なプロパティアクセスを防ぐために値を再帰的にラップします。
429
521
  *
430
- * @param fragment 対象フラグメント
431
- * @param values フラグメントに設定する値のオブジェクト
432
- * @param index 配列の場合のインデックス
433
- * @param force data-form-detach属性があるエレメントにも値を反映するかどうか
434
- * @returns Promise(DOMの更新が完了したら解決される)
522
+ * @param value ラップ対象の値
523
+ * @param cache 既存Proxyのキャッシュ
524
+ * @returns ラップ済みの値
435
525
  */
436
- static setPartValues(t, e, r = null, s = !1, i = !0) {
437
- const n = [], a = t.getAttribute("name"), o = t.getAttribute(`${c.prefix}form-object`), f = t.getAttribute(`${c.prefix}form-list`), p = t.getAttribute(`${c.prefix}form-detach`);
438
- if (a) {
439
- if (!p || s) {
440
- const g = e[String(a)];
441
- f && Array.isArray(g) && r !== null ? n.push(
442
- v.applyFragmentValue(t, g[r] ?? null, i)
443
- ) : typeof g > "u" || (typeof g == "string" || typeof g == "number" || typeof g == "boolean" || g === null ? n.push(v.applyFragmentValue(t, g, i)) : n.push(
444
- v.applyFragmentValue(t, String(g), i)
445
- ));
446
- }
447
- } else if (o) {
448
- const g = e[String(o)];
449
- if (g && typeof g == "object")
450
- for (const y of t.getChildElementFragments())
451
- n.push(
452
- v.setPartValues(
453
- y,
454
- g,
455
- null,
456
- s,
457
- i
458
- )
459
- );
460
- } else if (f) {
461
- const g = e[String(f)];
462
- if (Array.isArray(g)) {
463
- const y = t.getChildElementFragments();
464
- for (let b = 0; b < y.length; b++) {
465
- const l = y[b];
466
- g.length > b ? n.push(
467
- v.setPartValues(
468
- l,
469
- g[b],
470
- b,
471
- s,
472
- i
473
- )
474
- ) : n.push(v.setPartValues(l, {}, b, s, i));
475
- }
476
- }
477
- } else
478
- for (const g of t.getChildElementFragments())
479
- n.push(
480
- v.setPartValues(g, e, null, s, i)
526
+ static wrapBoundValue(t, e) {
527
+ if (!this.shouldWrapValue(t))
528
+ return t;
529
+ const r = t, s = e.get(r);
530
+ if (s !== void 0)
531
+ return s;
532
+ const i = new Proxy(r, {
533
+ get: (n, a, o) => {
534
+ if (typeof a == "string" && this.FORBIDDEN_PROPERTY_NAMES.has(a))
535
+ return;
536
+ const d = Reflect.get(n, a, o);
537
+ return typeof a == "symbol" ? d : this.wrapBoundValue(
538
+ d,
539
+ e
481
540
  );
482
- return Promise.all(n).then(() => {
541
+ },
542
+ has: (n, a) => typeof a == "string" && this.FORBIDDEN_PROPERTY_NAMES.has(a) ? !1 : Reflect.has(n, a),
543
+ getOwnPropertyDescriptor: (n, a) => {
544
+ if (!(typeof a == "string" && this.FORBIDDEN_PROPERTY_NAMES.has(a)))
545
+ return Reflect.getOwnPropertyDescriptor(n, a);
546
+ },
547
+ apply: (n, a, o) => {
548
+ const d = Reflect.apply(
549
+ n,
550
+ a,
551
+ o
552
+ );
553
+ return this.isIteratorLike(d) ? d : this.wrapBoundValue(d, e);
554
+ },
555
+ construct: (n, a, o) => this.wrapBoundValue(
556
+ Reflect.construct(
557
+ n,
558
+ a,
559
+ o
560
+ ),
561
+ e
562
+ )
483
563
  });
564
+ return e.set(r, i), i;
484
565
  }
485
566
  /**
486
- * 対象フラグメントとその子孫要素の値を初期化します。
487
- * 値の初期化とメッセージのクリアを行います。
567
+ * Proxy ラップ対象の値かどうかを判定します。
488
568
  *
489
- * @param fragment 対象フラグメント
490
- * @returns すべての初期化処理が完了するPromise
569
+ * @param value 判定対象
570
+ * @returns ラップ対象であればtrue
491
571
  */
492
- static async reset(t) {
493
- v.clearValues(t), await Promise.all([
494
- v.clearMessages(t),
495
- v.clearEachClones(t)
496
- ]), await N.enqueue(() => {
497
- const e = t.getTarget();
498
- if (e instanceof HTMLFormElement)
499
- e.reset();
500
- else {
501
- const r = e.parentElement;
502
- if (r) {
503
- const s = e.nextElementSibling, i = document.createElement("form");
504
- i.appendChild(e), i.reset(), r.insertBefore(e, s);
505
- }
506
- }
507
- }), await P.evaluateAll(t);
572
+ static shouldWrapValue(t) {
573
+ if (typeof t == "function")
574
+ return !0;
575
+ if (t === null || typeof t != "object")
576
+ return !1;
577
+ if (Array.isArray(t))
578
+ return !0;
579
+ const e = Object.getPrototypeOf(t);
580
+ return e === Object.prototype || e === null;
508
581
  }
509
582
  /**
510
- * data-each によって生成された複製(テンプレート以外)を削除します。
511
- * 既存のテンプレートは保持し、その後の再評価で必要に応じて再生成されます。
512
- * 対象エレメント自体がdata-eachを持つ場合はその子の複製を削除しますが、
513
- * 対象エレメント自体は削除しません。
583
+ * 評価中のみ prototype 系プロパティへの生アクセスを抑止します。
584
+ *
585
+ * @param callback 実行する処理
586
+ * @returns 処理結果
514
587
  */
515
- static clearEachClones(t) {
516
- const e = [], r = (i) => {
517
- if (i.hasAttribute(`${c.prefix}each`))
518
- for (const n of i.getChildElementFragments()) {
519
- const a = n.hasAttribute(`${c.prefix}each-before`), o = n.hasAttribute(`${c.prefix}each-after`);
520
- !a && !o && e.push(n.remove());
588
+ static withBlockedPropertyAccess(t) {
589
+ const r = [
590
+ { target: Object.prototype, property: "constructor" },
591
+ { target: Function.prototype, property: "constructor" },
592
+ { target: Object.prototype, property: "__proto__" }
593
+ ].map((s) => ({
594
+ ...s,
595
+ descriptor: Object.getOwnPropertyDescriptor(s.target, s.property)
596
+ })).filter((s) => s.descriptor?.configurable === !0);
597
+ r.forEach(({ target: s, property: i }) => {
598
+ Object.defineProperty(s, i, {
599
+ configurable: !0,
600
+ enumerable: !1,
601
+ get: () => {
602
+ },
603
+ set: () => {
521
604
  }
522
- }, s = (i) => {
523
- r(i);
524
- for (const n of i.getChildElementFragments())
525
- s(n);
526
- };
527
- r(t);
528
- for (const i of t.getChildElementFragments())
529
- s(i);
530
- return Promise.all(e).then(() => {
605
+ });
531
606
  });
607
+ try {
608
+ return t();
609
+ } finally {
610
+ r.forEach(({ target: s, property: i, descriptor: n }) => {
611
+ n !== void 0 && Object.defineProperty(s, i, n);
612
+ });
613
+ }
532
614
  }
533
615
  /**
534
- * 再帰的に値を初期化します。
535
- *
536
- * @param fragment 対象フラグメント
537
- */
538
- static clearValues(t) {
539
- t.clearValue();
540
- for (const e of t.getChildElementFragments())
541
- v.clearValues(e);
542
- }
543
- /**
544
- * フラグメントとその子要素のメッセージをクリアします。
616
+ * イテレータ互換オブジェクトかどうかを判定します。
545
617
  *
546
- * @param fragment 対象フラグメント
547
- * @returns Promise(メッセージのクリアが完了したら解決される)
618
+ * @param value 判定対象
619
+ * @returns イテレータ互換であればtrue
548
620
  */
549
- static clearMessages(t) {
550
- return st().clearMessages(
551
- t.getTarget()
552
- );
621
+ static isIteratorLike(t) {
622
+ return t === null || typeof t != "object" ? !1 : typeof t.next == "function";
553
623
  }
554
624
  /**
555
- * キーに一致するフラグメントにエラーメッセージを追加します。
556
- * キーに一致するフラグメントが見つからない場合は、指定されたフラグメントにメッセージを追加します。
625
+ * トップレベルのバインド識別子に拒否対象名が含まれていないかを判定します。
626
+ * ネストしたオブジェクトのプロパティ名は識別子として評価されないため、ここでは拒否しません。
557
627
  *
558
- * @param fragment 対象フラグメント
559
- * @param key キー(ドット区切りの文字列)
560
- * @param message 追加するエラーメッセージ
561
- * @return Promise(メッセージの追加が完了したら解決される)
628
+ * @param obj チェック対象のオブジェクト
629
+ * @return 禁止識別子が含まれていればtrue
562
630
  */
563
- static addErrorMessage(t, e, r) {
564
- return v.addMessage(t, e, r, "error");
631
+ static containsForbiddenKeys(t) {
632
+ if (!t || typeof t != "object")
633
+ return !1;
634
+ for (const e of Object.keys(t))
635
+ if (this.FORBIDDEN_BINDING_NAMES.has(e))
636
+ return !0;
637
+ return !1;
565
638
  }
566
639
  /**
567
- * キーに一致するフラグメントにレベル付きメッセージを追加します。
568
- * キーに一致するフラグメントが見つからない場合は、指定されたフラグメントにメッセージを追加します。
640
+ * バインド値に危険なホストオブジェクトやグローバル関数が含まれていないかを再帰的に判定します。
569
641
  *
570
- * @param fragment 対象フラグメント
571
- * @param key キー(ドット区切りの文字列)
572
- * @param message 追加するメッセージ
573
- * @param level メッセージのレベル(省略可能)
574
- * @return Promise(メッセージの追加が完了したら解決される)
642
+ * @param obj チェック対象の値
643
+ * @param seen 循環参照検出用の訪問済み集合
644
+ * @return 危険値が含まれていればtrue
575
645
  */
576
- static addMessage(t, e, r, s) {
577
- const i = [], n = st(), a = n.addMessage, o = (p) => typeof a == "function" ? a.call(n, p, r, s) : n.addErrorMessage(p, r), f = v.findFragmentsByKey(t, e);
578
- return f.forEach((p) => {
579
- i.push(o(p.getTarget()));
580
- }), f.length === 0 && i.push(o(t.getTarget())), Promise.all(i).then(() => {
581
- });
646
+ static containsForbiddenBindingValues(t, e = /* @__PURE__ */ new WeakSet()) {
647
+ if (!t || typeof t != "object" || e.has(t))
648
+ return !1;
649
+ if (e.add(t), this.getForbiddenBindingValues().some((r) => r === t))
650
+ return !0;
651
+ for (const r of Object.values(t)) {
652
+ if (typeof r == "function") {
653
+ if (this.getForbiddenBindingValues().some(
654
+ (s) => s === r
655
+ ))
656
+ return !0;
657
+ continue;
658
+ }
659
+ if (this.containsForbiddenBindingValues(r, e))
660
+ return !0;
661
+ }
662
+ return !1;
582
663
  }
583
- /**
584
- * 指定されたキーに一致するフラグメントを検索します。
585
- *
586
- * @param fragment 対象フラグメント
587
- * @param key キー(ドット区切りの文字列)
588
- * @returns 一致するフラグメントの配列
664
+ };
665
+ x.FORBIDDEN_NAMES = [
666
+ // グローバルオブジェクト
667
+ "window",
668
+ "self",
669
+ "globalThis",
670
+ "frames",
671
+ "parent",
672
+ "top",
673
+ // 危険な関数/オブジェクト
674
+ "Function",
675
+ "setTimeout",
676
+ "setInterval",
677
+ "requestAnimationFrame",
678
+ "alert",
679
+ "confirm",
680
+ "prompt",
681
+ "fetch",
682
+ "XMLHttpRequest",
683
+ "Reflect",
684
+ // 脱出経路・プロトタイプ
685
+ "constructor",
686
+ "__proto__",
687
+ "prototype",
688
+ "Object",
689
+ // その他
690
+ "document",
691
+ "location",
692
+ "navigator",
693
+ "localStorage",
694
+ "sessionStorage",
695
+ "IndexedDB",
696
+ "history"
697
+ ], x.STRICT_FORBIDDEN_NAMES = ["eval", "arguments"], x.REBINDABLE_FORBIDDEN_NAMES = /* @__PURE__ */ new Set(["location"]), x.FORBIDDEN_BINDING_NAMES = /* @__PURE__ */ new Set([
698
+ ...x.FORBIDDEN_NAMES.filter(
699
+ (t) => !x.REBINDABLE_FORBIDDEN_NAMES.has(t)
700
+ ),
701
+ "constructor",
702
+ "__proto__",
703
+ "prototype",
704
+ ...x.STRICT_FORBIDDEN_NAMES
705
+ ]), x.FORBIDDEN_PROPERTY_NAMES = /* @__PURE__ */ new Set([
706
+ "constructor",
707
+ "__proto__",
708
+ "prototype"
709
+ ]), x.OBJECT_PROPERTY_MODIFIERS = /* @__PURE__ */ new Set([
710
+ "get",
711
+ "set",
712
+ "async"
713
+ ]), x.DISALLOWED_KEYWORDS = /* @__PURE__ */ new Set([
714
+ "await",
715
+ "break",
716
+ "case",
717
+ "catch",
718
+ "class",
719
+ "const",
720
+ "continue",
721
+ "debugger",
722
+ "default",
723
+ "delete",
724
+ "do",
725
+ "else",
726
+ "export",
727
+ "finally",
728
+ "for",
729
+ "function",
730
+ "if",
731
+ "import",
732
+ "in",
733
+ "instanceof",
734
+ "let",
735
+ "new",
736
+ "return",
737
+ "switch",
738
+ "this",
739
+ "throw",
740
+ "try",
741
+ "typeof",
742
+ "var",
743
+ "void",
744
+ "while",
745
+ "with",
746
+ "yield"
747
+ ]), x.EXPRESSION_CACHE = /* @__PURE__ */ new Map();
748
+ let U = x;
749
+ class ot {
750
+ constructor() {
751
+ this.MAX_BUDGET = 8, this.queue = [], this.processing = !1;
752
+ }
753
+ /**
754
+ * 処理をキューに追加します
755
+ *
756
+ * @param task 実行する処理
757
+ * @param prepend trueの場合はキューの先頭に追加、falseの場合は末尾に追加
758
+ * @returns 処理完了Promise
589
759
  */
590
- static findFragmentsByKey(t, e) {
591
- return v.findFragmentByKeyParts(t, e.split("."));
760
+ enqueue(t, e = !1) {
761
+ let r, s;
762
+ const i = new Promise((a, o) => {
763
+ r = a, s = o;
764
+ }), n = {
765
+ task: t,
766
+ timestamp: performance.now(),
767
+ promise: i,
768
+ resolve: r,
769
+ reject: s
770
+ };
771
+ return e ? this.queue.unshift(n) : this.queue.push(n), this.scheduleProcessing(), i;
592
772
  }
593
773
  /**
594
- * 指定されたキーに一致するフラグメントを検索します。
595
- * data-form-list属性で指定された場合はdata-row属性を持つ子要素の位置と添字が一致するものを対象とします。
774
+ * キューを処理します。
596
775
  *
597
- * @param fragment 対象フラグメント
598
- * @param parts キーのパーツ
599
- * @returns 一致するフラグメントの配列
776
+ * @returns 処理完了Promise
600
777
  */
601
- static findFragmentByKeyParts(t, e) {
602
- const r = [], s = e[0];
603
- if (e.length == 1 && t.getAttribute("name") === s && r.push(t), t.hasAttribute(`${c.prefix}form-object`))
604
- e.length > 1 && t.getAttribute(`${c.prefix}form-object`) === s && t.getChildElementFragments().forEach((n) => {
605
- r.push(...v.findFragmentByKeyParts(n, e.slice(1)));
606
- });
607
- else if (t.hasAttribute(`${c.prefix}form-list`)) {
608
- if (e.length > 1) {
609
- const i = t.getAttribute(`${c.prefix}form-list`), n = s.lastIndexOf("["), a = s.lastIndexOf("]");
610
- if (n !== -1 && a !== -1 && n < a) {
611
- const o = s.substring(0, n);
612
- if (i === o) {
613
- const f = s.substring(n + 1, a), p = Number(f);
614
- if (isNaN(p))
615
- m.error("Haori", `Invalid index: ${s}`);
616
- else {
617
- const g = t.getChildElementFragments().filter((y) => y.hasAttribute(`${c.prefix}row`));
618
- p < g.length && r.push(
619
- ...v.findFragmentByKeyParts(g[p], e.slice(1))
620
- );
621
- }
778
+ async processQueue() {
779
+ if (!(this.processing || this.queue.length === 0)) {
780
+ this.processing = !0;
781
+ try {
782
+ const t = performance.now();
783
+ for (; this.queue.length > 0; ) {
784
+ const e = this.queue.shift();
785
+ if (!e)
786
+ return;
787
+ try {
788
+ const r = await e.task();
789
+ e.resolve(r);
790
+ } catch (r) {
791
+ e.reject(r), m.error("[Haori]", `Task ${e.timestamp} failed:`, r);
622
792
  }
793
+ if (performance.now() - t > this.MAX_BUDGET)
794
+ break;
623
795
  }
796
+ } catch (t) {
797
+ m.error("[Haori]", "Error processing queue:", t);
798
+ } finally {
799
+ this.processing = !1, this.queue.length > 0 && this.scheduleProcessing();
624
800
  }
625
- } else
626
- t.getChildElementFragments().forEach((i) => {
627
- r.push(...v.findFragmentByKeyParts(i, e));
628
- });
629
- return r;
801
+ }
630
802
  }
631
803
  /**
632
- * 対象のフラグメントがフォームフラグメントであればそれを返し、
633
- * そうでなければ先祖要素をたどってフォームフラグメントを探します。
804
+ * 処理をスケジュールします。
805
+ */
806
+ scheduleProcessing() {
807
+ this.processing || (typeof requestAnimationFrame < "u" ? requestAnimationFrame(() => {
808
+ this.processQueue();
809
+ }) : setTimeout(() => {
810
+ this.processQueue();
811
+ }, 16));
812
+ }
813
+ /**
814
+ * キューが空になるまで待機します。
634
815
  *
635
- * @param fragment
816
+ * @returns キューが空になったら解決されるPromise
636
817
  */
637
- static getFormFragment(t) {
638
- if (t.getTarget() instanceof HTMLFormElement)
639
- return t;
640
- const r = t.getParent();
641
- return r ? this.getFormFragment(r) : null;
818
+ async wait() {
819
+ if (this.queue.length === 0 && !this.processing)
820
+ return;
821
+ const t = this.queue.map((e) => e.promise);
822
+ t.length > 0 && await Promise.allSettled(t);
642
823
  }
643
824
  }
644
- const x = class x {
825
+ const rt = class rt {
645
826
  /**
646
- * 明示バインド内に持ち込まれてはならない危険値を返します。
827
+ * タスクをキューに追加します。
647
828
  *
648
- * @returns 危険値の配列
829
+ * @param task 実行する処理
830
+ * @param prepend trueの場合はキューの先頭に追加、falseの場合は末尾に追加
831
+ * @returns 処理完了Promise
649
832
  */
650
- static getForbiddenBindingValues() {
651
- const t = globalThis, e = [
652
- t,
653
- t.window,
654
- t.document,
655
- t.navigator,
656
- t.history,
657
- t.localStorage,
658
- t.sessionStorage,
659
- t.fetch,
660
- t.Function,
661
- t.setTimeout,
662
- t.setInterval,
663
- t.requestAnimationFrame,
664
- t.alert,
665
- t.confirm,
666
- t.prompt
667
- ];
668
- return t.window?.location && e.push(t.window.location), e.filter((r) => r != null);
833
+ static enqueue(t, e = !1) {
834
+ return this.ASYNC_QUEUE.enqueue(t, e);
669
835
  }
670
836
  /**
671
- * 現在のバインド識別子に含まれない禁止グローバルを遮断するコードを生成します。
837
+ * 全てのキュー処理が完了するまで待機します。
838
+ */
839
+ static wait() {
840
+ return this.ASYNC_QUEUE.wait();
841
+ }
842
+ };
843
+ rt.ASYNC_QUEUE = new ot();
844
+ let N = rt;
845
+ class X {
846
+ /**
847
+ * 実行モードを取得します。
672
848
  *
673
- * @param bindKeys 現在の式で利用するバインド識別子一覧
674
- * @returns 評価前に挿入する初期化コード
849
+ * @return 実行モード。
675
850
  */
676
- static buildAssignments(t) {
677
- const e = new Set(t);
678
- return this.FORBIDDEN_NAMES.filter((r) => !e.has(r)).map((r) => `const ${r} = undefined`).join(`;
679
- `);
851
+ static get runtime() {
852
+ return u.runtime;
680
853
  }
681
854
  /**
682
- * 式を評価します。
855
+ * 実行モードを設定します。
683
856
  *
684
- * @param expression 評価する式文字列
685
- * @param bindedValue バインドされた値のオブジェクト
857
+ * @param runtime 設定する実行モード。
858
+ * @return 戻り値はありません。
686
859
  */
687
- static evaluate(t, e = {}) {
688
- return this.evaluateDetailed(t, e).value;
860
+ static setRuntime(t) {
861
+ u.setRuntime(t);
689
862
  }
690
863
  /**
691
- * 式を評価し、未解決参照の有無を含む詳細結果を返します。
864
+ * 通知ダイアログを表示します。
692
865
  *
693
- * @param expression 評価する式文字列
694
- * @param bindedValues バインドされた値のオブジェクト
695
- * @returns 評価結果と未解決参照の有無
866
+ * @param message 表示メッセージ
867
+ * @returns 通知が閉じられると解決されるPromise
696
868
  */
697
- static evaluateDetailed(t, e = {}) {
698
- if (t.trim() === "")
699
- return m.warn("[Haori]", t, "Expression is empty"), { value: null, unresolvedReference: !1 };
700
- if (this.containsDangerousPatterns(t))
701
- return m.warn("[Haori]", t, "Expression contains dangerous patterns"), { value: null, unresolvedReference: !1 };
702
- if (this.containsForbiddenKeys(e))
703
- return m.warn("[Haori]", e, "Binded values contain forbidden keys"), { value: null, unresolvedReference: !1 };
704
- if (this.containsForbiddenBindingValues(e))
705
- return m.warn(
706
- "[Haori]",
707
- e,
708
- "Binded values contain forbidden values"
709
- ), { value: null, unresolvedReference: !1 };
710
- const r = Object.keys(e).filter((n) => !this.FORBIDDEN_BINDING_NAMES.has(n)).sort(), s = `${t}:${r.join(",")}`;
711
- let i = this.EXPRESSION_CACHE.get(s);
712
- if (!i) {
713
- const n = this.buildAssignments(r), a = n ? `"use strict";
714
- ${n};
715
- return (${t});` : `"use strict";
716
- return (${t});`;
869
+ static dialog(t) {
870
+ return N.enqueue(() => {
871
+ window.alert(t);
872
+ }, !0);
873
+ }
874
+ /**
875
+ * 通知トーストを表示します。
876
+ *
877
+ * @param message 表示メッセージ
878
+ * @param level メッセージのレベル(省略時は 'info')
879
+ * @return 通知が表示されると解決されるPromise
880
+ */
881
+ static async toast(t, e = "info") {
882
+ const r = document.createElement("div");
883
+ r.className = `haori-toast haori-toast-${e}`, r.textContent = t, r.setAttribute("popover", "manual"), r.setAttribute("role", "status"), r.setAttribute("aria-live", e === "error" ? "assertive" : "polite"), document.body.appendChild(r), r.showPopover(), setTimeout(() => {
717
884
  try {
718
- i = new Function(...r, a), this.EXPRESSION_CACHE.set(s, i);
719
- } catch (o) {
720
- return m.error(
721
- "[Haori]",
722
- "Failed to compile expression:",
723
- t,
724
- o
725
- ), { value: null, unresolvedReference: !1 };
885
+ r.hidePopover();
886
+ } finally {
887
+ r.remove();
726
888
  }
727
- }
728
- try {
729
- const n = [], a = this.wrapBoundValues(e);
730
- return r.forEach((o) => {
731
- n.push(a[o]);
732
- }), {
733
- value: this.withBlockedPropertyAccess(() => i(...n)),
734
- unresolvedReference: !1
735
- };
736
- } catch (n) {
737
- return m.error("[Haori]", "Expression evaluation error:", t, n), n instanceof ReferenceError ? { value: void 0, unresolvedReference: !0 } : { value: null, unresolvedReference: !1 };
738
- }
889
+ }, 3e3);
739
890
  }
740
891
  /**
741
- * 式にevalや危険な構文が含まれているかチェックします。
892
+ * 確認ダイアログを表示します。
742
893
  *
743
- * @param expression チェック対象の式文字列
744
- * @return 危険なパターンが含まれている場合はtrue
894
+ * @param message 確認メッセージ
895
+ * @returns ユーザーがOKをクリックした場合はtrue、キャンセルした場合はfalseが解決されるPromise
745
896
  */
746
- static containsDangerousPatterns(t) {
747
- return this.hasAllowedSyntax(t) ? [
748
- /\beval\s*\(/,
749
- // eval(...)
750
- /\barguments\s*\[/,
751
- // arguments[...]
752
- /\barguments\s*\./
753
- // arguments.xxx
754
- ].some((r) => r.test(t)) : !0;
897
+ static confirm(t) {
898
+ return N.enqueue(() => window.confirm(t), !0);
755
899
  }
756
900
  /**
757
- * 許可する式構文かどうかを検証します。
901
+ * ダイアログを開きます。
758
902
  *
759
- * @param expression 検証対象の式
760
- * @returns 許可する構文であればtrue
903
+ * @param element 開くダイアログのHTML要素
761
904
  */
762
- static hasAllowedSyntax(t) {
763
- const e = this.tokenizeExpression(t);
764
- if (e === null || e.length === 0)
765
- return !1;
766
- const r = [];
767
- let s = null;
768
- for (let i = 0; i < e.length; i++) {
769
- const n = e[i], a = e[i + 1] || null, o = r[r.length - 1] || null, f = e[i - 2] || null, p = e[i - 3] || null;
770
- if (this.startsObjectKey(
771
- o,
772
- s,
773
- f,
774
- p
775
- ) && (n.value === "[" || n.type === "identifier" && this.FORBIDDEN_PROPERTY_NAMES.has(n.value) || n.type === "string" && this.FORBIDDEN_PROPERTY_NAMES.has(
776
- this.decodeStringLiteral(n.value)
777
- )) || n.type === "identifier" && (this.DISALLOWED_KEYWORDS.has(n.value) || this.STRICT_FORBIDDEN_NAMES.includes(n.value) || (s?.value === "." || s?.value === "?.") && this.FORBIDDEN_PROPERTY_NAMES.has(n.value)) || o === "member" && n.value !== "]" && n.type === "string" && this.FORBIDDEN_PROPERTY_NAMES.has(
778
- this.decodeStringLiteral(n.value)
779
- ) || n.value === "." && a?.type !== "identifier" || n.value === "?." && a?.type !== "identifier" && a?.value !== "[" && a?.value !== "(")
780
- return !1;
781
- switch (n.value) {
782
- case "(":
783
- r.push("paren");
784
- break;
785
- case ")": {
786
- if (r.pop() !== "paren")
787
- return !1;
788
- break;
789
- }
790
- case "[": {
791
- const g = this.startsMemberAccess(s) ? "member" : "array";
792
- r.push(g);
793
- break;
794
- }
795
- case "{":
796
- r.push("object");
797
- break;
798
- case "]": {
799
- if (r.pop() === void 0)
800
- return !1;
801
- break;
802
- }
803
- case "}": {
804
- if (r.pop() !== "object")
805
- return !1;
806
- break;
807
- }
808
- }
809
- s = n;
810
- }
811
- return r.length === 0;
905
+ static openDialog(t) {
906
+ return N.enqueue(() => {
907
+ t instanceof HTMLDialogElement ? t.showModal() : m.error("[Haori]", "Element is not a dialog: ", t);
908
+ }, !0);
812
909
  }
813
910
  /**
814
- * 式をトークン列に分解します。
911
+ * ダイアログを閉じます。
815
912
  *
816
- * @param expression 評価前に検証する式
817
- * @returns 分解結果。未対応構文を含む場合はnull
913
+ * @param element 閉じるダイアログのHTML要素
818
914
  */
819
- static tokenizeExpression(t) {
820
- const e = [], r = [
821
- "===",
822
- "!==",
823
- "...",
824
- "?.",
825
- "&&",
826
- "||",
827
- ">=",
828
- "<=",
829
- "==",
830
- "!=",
831
- "=>"
832
- ], s = /* @__PURE__ */ new Set([
833
- "(",
834
- ")",
835
- "{",
836
- "}",
837
- "[",
838
- "]",
839
- ".",
840
- ",",
841
- "?",
842
- ":",
843
- "+",
844
- "-",
845
- "*",
846
- "/",
847
- "%",
848
- "!",
849
- ">",
850
- "<"
851
- ]);
852
- let i = 0;
853
- for (; i < t.length; ) {
854
- const n = t[i];
855
- if (/\s/.test(n)) {
856
- i += 1;
857
- continue;
858
- }
859
- if (n === "/" && (t[i + 1] === "/" || t[i + 1] === "*"))
860
- return null;
861
- if (n === '"' || n === "'") {
862
- const o = this.readStringToken(t, i);
863
- if (o === null)
864
- return null;
865
- e.push(o.token), i = o.nextIndex;
866
- continue;
867
- }
868
- const a = r.find(
869
- (o) => t.startsWith(o, i)
870
- );
871
- if (a) {
872
- e.push({ type: "operator", value: a, position: i }), i += a.length;
873
- continue;
874
- }
875
- if (/[0-9]/.test(n)) {
876
- const o = this.readNumberToken(t, i);
877
- e.push(o.token), i = o.nextIndex;
878
- continue;
879
- }
880
- if (/[A-Za-z_$]/.test(n)) {
881
- const o = this.readIdentifierToken(t, i);
882
- e.push(o.token), i = o.nextIndex;
883
- continue;
884
- }
885
- if (s.has(n)) {
886
- e.push({ type: "operator", value: n, position: i }), i += 1;
887
- continue;
888
- }
889
- return null;
890
- }
891
- return e;
915
+ static closeDialog(t) {
916
+ return N.enqueue(() => {
917
+ t instanceof HTMLDialogElement ? t.close() : m.error("[Haori]", "Element is not a dialog: ", t);
918
+ }, !0);
892
919
  }
893
920
  /**
894
- * 文字列リテラルを読み取ります。
921
+ * エラーメッセージを追加します。
895
922
  *
896
- * @param expression 式全体
897
- * @param start 開始位置
898
- * @returns トークンと次の位置
923
+ * @param target メッセージを表示する要素
924
+ * @param message エラーメッセージ
899
925
  */
900
- static readStringToken(t, e) {
901
- const r = t[e];
902
- let s = e + 1;
903
- for (; s < t.length; ) {
904
- const i = t[s];
905
- if (i === "\\") {
906
- s += 2;
907
- continue;
926
+ static addErrorMessage(t, e) {
927
+ return X.addMessage(t, e, "error");
928
+ }
929
+ /**
930
+ * メッセージをレベル付きで追加します。
931
+ *
932
+ * @param target メッセージを表示する要素
933
+ * @param message メッセージ
934
+ * @param level メッセージのレベル(省略可能)
935
+ */
936
+ static addMessage(t, e, r) {
937
+ return N.enqueue(() => {
938
+ const s = t instanceof HTMLFormElement ? t : t.parentElement ?? t;
939
+ s.setAttribute("data-message", e), r !== void 0 ? s.setAttribute("data-message-level", r) : s.removeAttribute("data-message-level");
940
+ }, !0);
941
+ }
942
+ /**
943
+ * 対象のエレメントおよびその子要素のメッセージをクリアします。
944
+ *
945
+ * @param parent メッセージをクリアする親要素
946
+ */
947
+ static clearMessages(t) {
948
+ return N.enqueue(() => {
949
+ t.removeAttribute("data-message"), t.removeAttribute("data-message-level"), t.querySelectorAll("[data-message]").forEach((e) => {
950
+ e.removeAttribute("data-message"), e.removeAttribute("data-message-level");
951
+ });
952
+ }, !0);
953
+ }
954
+ }
955
+ const lt = ["addErrorMessage", "clearMessages"];
956
+ function it() {
957
+ const t = globalThis.window?.Haori;
958
+ return lt.every(
959
+ (r) => typeof t?.[r] == "function"
960
+ ) ? t : X;
961
+ }
962
+ class y {
963
+ /**
964
+ * フォーム内にある入力エレメントの値をオブジェクトとして取得します。
965
+ * data-form-object属性があると、そのエレメント内の値はオブジェクトとして処理されます。
966
+ * 入力エレメントにdata-form-list属性があると、そのエレメントの値はリストとして処理されます。
967
+ * 入力エレメント以外にdata-form-list属性があると、そのエレメントの値はオブジェクトのリストとして処理されます。
968
+ *
969
+ * @param form フォームのElementFragment
970
+ */
971
+ static getValues(t) {
972
+ const e = {};
973
+ return y.getPartValues(t, e);
974
+ }
975
+ /**
976
+ * フォーム内の各入力エレメントから値を取得し、オブジェクトとして返します。
977
+ * 入力エレメントのname属性、data-form-object属性、data-form-list属性に基づいて値を整理します。
978
+ *
979
+ * @param fragment 対象のElementFragment
980
+ * @param values オブジェクトに追加する値のオブジェクト
981
+ * @returns values と同じオブジェクト
982
+ */
983
+ static getPartValues(t, e) {
984
+ const r = t.getAttribute("name"), s = t.getAttribute(`${u.prefix}form-object`), i = t.getAttribute(`${u.prefix}form-list`);
985
+ if (r) {
986
+ i ? Array.isArray(e[String(r)]) ? e[String(r)].push(t.getValue()) : e[String(r)] = [t.getValue()] : e[String(r)] = t.getValue(), s && m.warn(
987
+ "Haori",
988
+ `Element cannot have both ${u.prefix}form-object and name attributes.`
989
+ );
990
+ for (const n of t.getChildElementFragments())
991
+ y.getPartValues(n, e);
992
+ } else if (s) {
993
+ const n = {};
994
+ for (const a of t.getChildElementFragments())
995
+ y.getPartValues(a, n);
996
+ Object.keys(n).length > 0 && (e[String(s)] = n), i && m.warn(
997
+ "Haori",
998
+ `Element cannot have both ${u.prefix}form-list and ${u.prefix}form-object attributes.`
999
+ );
1000
+ } else if (i) {
1001
+ const n = [];
1002
+ for (const a of t.getChildElementFragments()) {
1003
+ const o = {};
1004
+ y.getPartValues(a, o), Object.keys(o).length > 0 && n.push(o);
908
1005
  }
909
- if (i === r)
910
- return {
911
- token: {
912
- type: "string",
913
- value: t.slice(e, s + 1),
914
- position: e
915
- },
916
- nextIndex: s + 1
917
- };
918
- s += 1;
919
- }
920
- return null;
1006
+ n.length > 0 && (e[String(i)] = n);
1007
+ } else
1008
+ for (const n of t.getChildElementFragments())
1009
+ y.getPartValues(n, e);
1010
+ return e;
921
1011
  }
922
1012
  /**
923
- * 数値リテラルを読み取ります。
1013
+ * フォーム内にある入力エレメントに値を設定します。
1014
+ * フォームのdata-bind属性に値が反映されます。
924
1015
  *
925
- * @param expression 式全体
926
- * @param start 開始位置
927
- * @returns トークンと次の位置
1016
+ * @param form フォームのElementFragment
1017
+ * @param values フォームに設定する値のオブジェクト
1018
+ * @param force data-form-detach属性があるエレメントにも値を反映するかどうか
1019
+ * @returns Promise(DOMの更新が完了したら解決される)
928
1020
  */
929
- static readNumberToken(t, e) {
930
- let r = e;
931
- for (; r < t.length && /[0-9_]/.test(t[r]); )
932
- r += 1;
933
- if (t[r] === ".")
934
- for (r += 1; r < t.length && /[0-9_]/.test(t[r]); )
935
- r += 1;
936
- return {
937
- token: {
938
- type: "number",
939
- value: t.slice(e, r),
940
- position: e
941
- },
942
- nextIndex: r
943
- };
1021
+ static setValues(t, e, r = !1) {
1022
+ return y.setPartValues(t, e, null, r, !0);
944
1023
  }
945
1024
  /**
946
- * 識別子を読み取ります。
1025
+ * フォーム内にある入力エレメントに値をイベントなしで設定します。
1026
+ * フォーム bindingData からの内部同期に利用します。
947
1027
  *
948
- * @param expression 式全体
949
- * @param start 開始位置
950
- * @returns トークンと次の位置
1028
+ * @param form フォームのElementFragment
1029
+ * @param values フォームに設定する値のオブジェクト
1030
+ * @param force data-form-detach属性があるエレメントにも値を反映するかどうか
1031
+ * @returns Promise(DOMの更新が完了したら解決される)
951
1032
  */
952
- static readIdentifierToken(t, e) {
953
- let r = e;
954
- for (; r < t.length && /[A-Za-z0-9_$]/.test(t[r]); )
955
- r += 1;
956
- return {
957
- token: {
958
- type: "identifier",
959
- value: t.slice(e, r),
960
- position: e
961
- },
962
- nextIndex: r
963
- };
1033
+ static syncValues(t, e, r = !1) {
1034
+ return y.setPartValues(t, e, null, r, !1);
964
1035
  }
965
1036
  /**
966
- * 角括弧がメンバーアクセスかどうかを判定します。
1037
+ * 単一フラグメントへ値を設定します。
967
1038
  *
968
- * @param previous 直前のトークン
969
- * @returns メンバーアクセスであればtrue
1039
+ * @param fragment 対象フラグメント
1040
+ * @param value 設定する値
1041
+ * @param emitEvents input/change イベントを発火するかどうか
1042
+ * @returns Promise(DOMの更新が完了したら解決される)
970
1043
  */
971
- static startsMemberAccess(t) {
972
- return t === null ? !1 : t.type === "identifier" || t.type === "number" ? !0 : t.value === ")" || t.value === "]" || t.value === "?.";
1044
+ static applyFragmentValue(t, e, r) {
1045
+ return r ? t.setValue(e) : t.syncBindingValue(e);
973
1046
  }
974
1047
  /**
975
- * object literal 内で次のトークンがキー位置かどうかを判定します。
1048
+ * フラグメント内にある各入力エレメントに値を設定します。
976
1049
  *
977
- * @param activeGroup 現在のグループ種別
978
- * @param previous 直前のトークン
979
- * @returns object literal のキー位置であれば true
1050
+ * @param fragment 対象フラグメント
1051
+ * @param values フラグメントに設定する値のオブジェクト
1052
+ * @param index 配列の場合のインデックス
1053
+ * @param force data-form-detach属性があるエレメントにも値を反映するかどうか
1054
+ * @returns Promise(DOMの更新が完了したら解決される)
980
1055
  */
981
- static startsObjectKey(t, e, r, s) {
982
- return t !== "object" ? !1 : e?.value === "{" || e?.value === "," || e?.type === "identifier" && this.OBJECT_PROPERTY_MODIFIERS.has(e.value) && (r?.value === "{" || r?.value === ",") ? !0 : e?.value !== "*" ? !1 : r?.value === "{" || r?.value === "," ? !0 : r?.type === "identifier" && r.value === "async" && (s?.value === "{" || s?.value === ",");
1056
+ static setPartValues(t, e, r = null, s = !1, i = !0) {
1057
+ const n = [], a = t.getAttribute("name"), o = t.getAttribute(`${u.prefix}form-object`), d = t.getAttribute(`${u.prefix}form-list`), p = t.getAttribute(`${u.prefix}form-detach`);
1058
+ if (a) {
1059
+ if (!p || s) {
1060
+ const g = e[String(a)];
1061
+ d && Array.isArray(g) && r !== null ? n.push(
1062
+ y.applyFragmentValue(t, g[r] ?? null, i)
1063
+ ) : typeof g > "u" || (typeof g == "string" || typeof g == "number" || typeof g == "boolean" || g === null ? n.push(y.applyFragmentValue(t, g, i)) : n.push(
1064
+ y.applyFragmentValue(t, String(g), i)
1065
+ ));
1066
+ }
1067
+ } else if (o) {
1068
+ const g = e[String(o)];
1069
+ if (g && typeof g == "object")
1070
+ for (const v of t.getChildElementFragments())
1071
+ n.push(
1072
+ y.setPartValues(
1073
+ v,
1074
+ g,
1075
+ null,
1076
+ s,
1077
+ i
1078
+ )
1079
+ );
1080
+ } else if (d) {
1081
+ const g = e[String(d)];
1082
+ if (Array.isArray(g)) {
1083
+ const v = t.getChildElementFragments();
1084
+ for (let b = 0; b < v.length; b++) {
1085
+ const l = v[b];
1086
+ g.length > b ? n.push(
1087
+ y.setPartValues(
1088
+ l,
1089
+ g[b],
1090
+ b,
1091
+ s,
1092
+ i
1093
+ )
1094
+ ) : n.push(y.setPartValues(l, {}, b, s, i));
1095
+ }
1096
+ }
1097
+ } else
1098
+ for (const g of t.getChildElementFragments())
1099
+ n.push(
1100
+ y.setPartValues(g, e, null, s, i)
1101
+ );
1102
+ return Promise.all(n).then(() => {
1103
+ });
983
1104
  }
984
1105
  /**
985
- * 文字列リテラルをプレーン文字列へ変換します。
1106
+ * 対象フラグメントとその子孫要素の値を初期化します。
1107
+ * 値の初期化とメッセージのクリアを行います。
986
1108
  *
987
- * @param literal 文字列リテラル
988
- * @returns デコード後の文字列
1109
+ * @param fragment 対象フラグメント
1110
+ * @returns すべての初期化処理が完了するPromise
989
1111
  */
990
- static decodeStringLiteral(t) {
991
- return t.slice(1, -1).replace(
992
- /\\u\{([0-9a-fA-F]+)\}/g,
993
- (e, r) => String.fromCodePoint(parseInt(r, 16))
994
- ).replace(
995
- /\\u([0-9a-fA-F]{4})/g,
996
- (e, r) => String.fromCharCode(parseInt(r, 16))
997
- ).replace(
998
- /\\x([0-9a-fA-F]{2})/g,
999
- (e, r) => String.fromCharCode(parseInt(r, 16))
1000
- ).replace(/\\(["'\\bfnrtv0])/g, (e, r) => {
1001
- switch (r) {
1002
- case "b":
1003
- return "\b";
1004
- case "f":
1005
- return "\f";
1006
- case "n":
1007
- return `
1008
- `;
1009
- case "r":
1010
- return "\r";
1011
- case "t":
1012
- return " ";
1013
- case "v":
1014
- return "\v";
1015
- case "0":
1016
- return "\0";
1017
- default:
1018
- return r;
1112
+ static async reset(t) {
1113
+ y.clearValues(t), await Promise.all([
1114
+ y.clearMessages(t),
1115
+ y.clearEachClones(t)
1116
+ ]), await N.enqueue(() => {
1117
+ const e = t.getTarget();
1118
+ if (e instanceof HTMLFormElement)
1119
+ e.reset();
1120
+ else {
1121
+ const r = e.parentElement;
1122
+ if (r) {
1123
+ const s = e.nextElementSibling, i = document.createElement("form");
1124
+ i.appendChild(e), i.reset(), r.insertBefore(e, s);
1125
+ }
1019
1126
  }
1127
+ }), await D.evaluateAll(t);
1128
+ }
1129
+ /**
1130
+ * data-each によって生成された複製(テンプレート以外)を削除します。
1131
+ * 既存のテンプレートは保持し、その後の再評価で必要に応じて再生成されます。
1132
+ * 対象エレメント自体がdata-eachを持つ場合はその子の複製を削除しますが、
1133
+ * 対象エレメント自体は削除しません。
1134
+ */
1135
+ static clearEachClones(t) {
1136
+ const e = [], r = (i) => {
1137
+ if (i.hasAttribute(`${u.prefix}each`))
1138
+ for (const n of i.getChildElementFragments()) {
1139
+ const a = n.hasAttribute(`${u.prefix}each-before`), o = n.hasAttribute(`${u.prefix}each-after`);
1140
+ !a && !o && e.push(n.remove());
1141
+ }
1142
+ }, s = (i) => {
1143
+ r(i);
1144
+ for (const n of i.getChildElementFragments())
1145
+ s(n);
1146
+ };
1147
+ r(t);
1148
+ for (const i of t.getChildElementFragments())
1149
+ s(i);
1150
+ return Promise.all(e).then(() => {
1020
1151
  });
1021
1152
  }
1022
1153
  /**
1023
- * バインド値を安全なProxyでラップします。
1154
+ * 再帰的に値を初期化します。
1024
1155
  *
1025
- * @param bindedValues バインド値
1026
- * @returns ラップ済みのバインド値
1156
+ * @param fragment 対象フラグメント
1027
1157
  */
1028
- static wrapBoundValues(t) {
1029
- const e = /* @__PURE__ */ new WeakMap(), r = {};
1030
- return Object.entries(t).forEach(([s, i]) => {
1031
- r[s] = this.wrapBoundValue(i, e);
1032
- }), r;
1158
+ static clearValues(t) {
1159
+ t.clearValue();
1160
+ for (const e of t.getChildElementFragments())
1161
+ y.clearValues(e);
1033
1162
  }
1034
1163
  /**
1035
- * 危険なプロパティアクセスを防ぐために値を再帰的にラップします。
1164
+ * フラグメントとその子要素のメッセージをクリアします。
1036
1165
  *
1037
- * @param value ラップ対象の値
1038
- * @param cache 既存Proxyのキャッシュ
1039
- * @returns ラップ済みの値
1166
+ * @param fragment 対象フラグメント
1167
+ * @returns Promise(メッセージのクリアが完了したら解決される)
1040
1168
  */
1041
- static wrapBoundValue(t, e) {
1042
- if (!this.shouldWrapValue(t))
1043
- return t;
1044
- const r = t, s = e.get(r);
1045
- if (s !== void 0)
1046
- return s;
1047
- const i = new Proxy(r, {
1048
- get: (n, a, o) => {
1049
- if (typeof a == "string" && this.FORBIDDEN_PROPERTY_NAMES.has(a))
1050
- return;
1051
- const f = Reflect.get(n, a, o);
1052
- return typeof a == "symbol" ? f : this.wrapBoundValue(
1053
- f,
1054
- e
1055
- );
1056
- },
1057
- has: (n, a) => typeof a == "string" && this.FORBIDDEN_PROPERTY_NAMES.has(a) ? !1 : Reflect.has(n, a),
1058
- getOwnPropertyDescriptor: (n, a) => {
1059
- if (!(typeof a == "string" && this.FORBIDDEN_PROPERTY_NAMES.has(a)))
1060
- return Reflect.getOwnPropertyDescriptor(n, a);
1061
- },
1062
- apply: (n, a, o) => {
1063
- const f = Reflect.apply(
1064
- n,
1065
- a,
1066
- o
1067
- );
1068
- return this.isIteratorLike(f) ? f : this.wrapBoundValue(f, e);
1069
- },
1070
- construct: (n, a, o) => this.wrapBoundValue(
1071
- Reflect.construct(
1072
- n,
1073
- a,
1074
- o
1075
- ),
1076
- e
1077
- )
1078
- });
1079
- return e.set(r, i), i;
1169
+ static clearMessages(t) {
1170
+ return it().clearMessages(
1171
+ t.getTarget()
1172
+ );
1080
1173
  }
1081
1174
  /**
1082
- * Proxy ラップ対象の値かどうかを判定します。
1175
+ * キーに一致するフラグメントにエラーメッセージを追加します。
1176
+ * キーに一致するフラグメントが見つからない場合は、指定されたフラグメントにメッセージを追加します。
1083
1177
  *
1084
- * @param value 判定対象
1085
- * @returns ラップ対象であればtrue
1178
+ * @param fragment 対象フラグメント
1179
+ * @param key キー(ドット区切りの文字列)
1180
+ * @param message 追加するエラーメッセージ
1181
+ * @return Promise(メッセージの追加が完了したら解決される)
1086
1182
  */
1087
- static shouldWrapValue(t) {
1088
- if (typeof t == "function")
1089
- return !0;
1090
- if (t === null || typeof t != "object")
1091
- return !1;
1092
- if (Array.isArray(t))
1093
- return !0;
1094
- const e = Object.getPrototypeOf(t);
1095
- return e === Object.prototype || e === null;
1183
+ static addErrorMessage(t, e, r) {
1184
+ return y.addMessage(t, e, r, "error");
1096
1185
  }
1097
1186
  /**
1098
- * 評価中のみ prototype 系プロパティへの生アクセスを抑止します。
1187
+ * キーに一致するフラグメントにレベル付きメッセージを追加します。
1188
+ * キーに一致するフラグメントが見つからない場合は、指定されたフラグメントにメッセージを追加します。
1099
1189
  *
1100
- * @param callback 実行する処理
1101
- * @returns 処理結果
1190
+ * @param fragment 対象フラグメント
1191
+ * @param key キー(ドット区切りの文字列)
1192
+ * @param message 追加するメッセージ
1193
+ * @param level メッセージのレベル(省略可能)
1194
+ * @return Promise(メッセージの追加が完了したら解決される)
1102
1195
  */
1103
- static withBlockedPropertyAccess(t) {
1104
- const r = [
1105
- { target: Object.prototype, property: "constructor" },
1106
- { target: Function.prototype, property: "constructor" },
1107
- { target: Object.prototype, property: "__proto__" }
1108
- ].map((s) => ({
1109
- ...s,
1110
- descriptor: Object.getOwnPropertyDescriptor(s.target, s.property)
1111
- })).filter((s) => s.descriptor?.configurable === !0);
1112
- r.forEach(({ target: s, property: i }) => {
1113
- Object.defineProperty(s, i, {
1114
- configurable: !0,
1115
- enumerable: !1,
1116
- get: () => {
1117
- },
1118
- set: () => {
1119
- }
1120
- });
1196
+ static addMessage(t, e, r, s) {
1197
+ const i = [], n = it(), a = n.addMessage, o = (p) => typeof a == "function" ? a.call(n, p, r, s) : n.addErrorMessage(p, r), d = y.findFragmentsByKey(t, e);
1198
+ return d.forEach((p) => {
1199
+ i.push(o(p.getTarget()));
1200
+ }), d.length === 0 && i.push(o(t.getTarget())), Promise.all(i).then(() => {
1121
1201
  });
1122
- try {
1123
- return t();
1124
- } finally {
1125
- r.forEach(({ target: s, property: i, descriptor: n }) => {
1126
- n !== void 0 && Object.defineProperty(s, i, n);
1127
- });
1128
- }
1129
1202
  }
1130
1203
  /**
1131
- * イテレータ互換オブジェクトかどうかを判定します。
1204
+ * 指定されたキーに一致するフラグメントを検索します。
1132
1205
  *
1133
- * @param value 判定対象
1134
- * @returns イテレータ互換であればtrue
1206
+ * @param fragment 対象フラグメント
1207
+ * @param key キー(ドット区切りの文字列)
1208
+ * @returns 一致するフラグメントの配列
1135
1209
  */
1136
- static isIteratorLike(t) {
1137
- return t === null || typeof t != "object" ? !1 : typeof t.next == "function";
1210
+ static findFragmentsByKey(t, e) {
1211
+ return y.findFragmentByKeyParts(t, e.split("."));
1138
1212
  }
1139
1213
  /**
1140
- * トップレベルのバインド識別子に拒否対象名が含まれていないかを判定します。
1141
- * ネストしたオブジェクトのプロパティ名は識別子として評価されないため、ここでは拒否しません。
1214
+ * 指定されたキーに一致するフラグメントを検索します。
1215
+ * data-form-list属性で指定された場合はdata-row属性を持つ子要素の位置と添字が一致するものを対象とします。
1142
1216
  *
1143
- * @param obj チェック対象のオブジェクト
1144
- * @return 禁止識別子が含まれていればtrue
1217
+ * @param fragment 対象フラグメント
1218
+ * @param parts キーのパーツ
1219
+ * @returns 一致するフラグメントの配列
1145
1220
  */
1146
- static containsForbiddenKeys(t) {
1147
- if (!t || typeof t != "object")
1148
- return !1;
1149
- for (const e of Object.keys(t))
1150
- if (this.FORBIDDEN_BINDING_NAMES.has(e))
1151
- return !0;
1152
- return !1;
1221
+ static findFragmentByKeyParts(t, e) {
1222
+ const r = [], s = e[0];
1223
+ if (e.length == 1 && t.getAttribute("name") === s && r.push(t), t.hasAttribute(`${u.prefix}form-object`))
1224
+ e.length > 1 && t.getAttribute(`${u.prefix}form-object`) === s && t.getChildElementFragments().forEach((n) => {
1225
+ r.push(...y.findFragmentByKeyParts(n, e.slice(1)));
1226
+ });
1227
+ else if (t.hasAttribute(`${u.prefix}form-list`)) {
1228
+ if (e.length > 1) {
1229
+ const i = t.getAttribute(`${u.prefix}form-list`), n = s.lastIndexOf("["), a = s.lastIndexOf("]");
1230
+ if (n !== -1 && a !== -1 && n < a) {
1231
+ const o = s.substring(0, n);
1232
+ if (i === o) {
1233
+ const d = s.substring(n + 1, a), p = Number(d);
1234
+ if (isNaN(p))
1235
+ m.error("Haori", `Invalid index: ${s}`);
1236
+ else {
1237
+ const g = t.getChildElementFragments().filter((v) => v.hasAttribute(`${u.prefix}row`));
1238
+ p < g.length && r.push(
1239
+ ...y.findFragmentByKeyParts(g[p], e.slice(1))
1240
+ );
1241
+ }
1242
+ }
1243
+ }
1244
+ }
1245
+ } else
1246
+ t.getChildElementFragments().forEach((i) => {
1247
+ r.push(...y.findFragmentByKeyParts(i, e));
1248
+ });
1249
+ return r;
1153
1250
  }
1154
1251
  /**
1155
- * バインド値に危険なホストオブジェクトやグローバル関数が含まれていないかを再帰的に判定します。
1252
+ * 対象のフラグメントがフォームフラグメントであればそれを返し、
1253
+ * そうでなければ先祖要素をたどってフォームフラグメントを探します。
1156
1254
  *
1157
- * @param obj チェック対象の値
1158
- * @param seen 循環参照検出用の訪問済み集合
1159
- * @return 危険値が含まれていればtrue
1255
+ * @param fragment
1160
1256
  */
1161
- static containsForbiddenBindingValues(t, e = /* @__PURE__ */ new WeakSet()) {
1162
- if (!t || typeof t != "object" || e.has(t))
1163
- return !1;
1164
- if (e.add(t), this.getForbiddenBindingValues().some((r) => r === t))
1165
- return !0;
1166
- for (const r of Object.values(t)) {
1167
- if (typeof r == "function") {
1168
- if (this.getForbiddenBindingValues().some(
1169
- (s) => s === r
1170
- ))
1171
- return !0;
1172
- continue;
1173
- }
1174
- if (this.containsForbiddenBindingValues(r, e))
1175
- return !0;
1176
- }
1177
- return !1;
1257
+ static getFormFragment(t) {
1258
+ if (t.getTarget() instanceof HTMLFormElement)
1259
+ return t;
1260
+ const r = t.getParent();
1261
+ return r ? this.getFormFragment(r) : null;
1178
1262
  }
1179
- };
1180
- x.FORBIDDEN_NAMES = [
1181
- // グローバルオブジェクト
1182
- "window",
1183
- "self",
1184
- "globalThis",
1185
- "frames",
1186
- "parent",
1187
- "top",
1188
- // 危険な関数/オブジェクト
1189
- "Function",
1190
- "setTimeout",
1191
- "setInterval",
1192
- "requestAnimationFrame",
1193
- "alert",
1194
- "confirm",
1195
- "prompt",
1196
- "fetch",
1197
- "XMLHttpRequest",
1198
- "Reflect",
1199
- // 脱出経路・プロトタイプ
1200
- "constructor",
1201
- "__proto__",
1202
- "prototype",
1203
- "Object",
1204
- // その他
1205
- "document",
1206
- "location",
1207
- "navigator",
1208
- "localStorage",
1209
- "sessionStorage",
1210
- "IndexedDB",
1211
- "history"
1212
- ], x.STRICT_FORBIDDEN_NAMES = ["eval", "arguments"], x.REBINDABLE_FORBIDDEN_NAMES = /* @__PURE__ */ new Set(["location"]), x.FORBIDDEN_BINDING_NAMES = /* @__PURE__ */ new Set([
1213
- ...x.FORBIDDEN_NAMES.filter(
1214
- (t) => !x.REBINDABLE_FORBIDDEN_NAMES.has(t)
1215
- ),
1216
- "constructor",
1217
- "__proto__",
1218
- "prototype",
1219
- ...x.STRICT_FORBIDDEN_NAMES
1220
- ]), x.FORBIDDEN_PROPERTY_NAMES = /* @__PURE__ */ new Set([
1221
- "constructor",
1222
- "__proto__",
1223
- "prototype"
1224
- ]), x.OBJECT_PROPERTY_MODIFIERS = /* @__PURE__ */ new Set([
1225
- "get",
1226
- "set",
1227
- "async"
1228
- ]), x.DISALLOWED_KEYWORDS = /* @__PURE__ */ new Set([
1229
- "await",
1230
- "break",
1231
- "case",
1232
- "catch",
1233
- "class",
1234
- "const",
1235
- "continue",
1236
- "debugger",
1237
- "default",
1238
- "delete",
1239
- "do",
1240
- "else",
1241
- "export",
1242
- "finally",
1243
- "for",
1244
- "function",
1245
- "if",
1246
- "import",
1247
- "in",
1248
- "instanceof",
1249
- "let",
1250
- "new",
1251
- "return",
1252
- "switch",
1253
- "this",
1254
- "throw",
1255
- "try",
1256
- "typeof",
1257
- "var",
1258
- "void",
1259
- "while",
1260
- "with",
1261
- "yield"
1262
- ]), x.EXPRESSION_CACHE = /* @__PURE__ */ new Map();
1263
- let V = x;
1264
- const L = class L {
1263
+ }
1264
+ const $ = class $ {
1265
1265
  /**
1266
1266
  * フラグメントのコンストラクタ。
1267
1267
  *
1268
1268
  * @param target 対象ノード
1269
1269
  */
1270
1270
  constructor(t) {
1271
- this.parent = null, this.mounted = !1, this.skipMutationNodes = !1, this.target = t, L.FRAGMENT_CACHE.set(t, this);
1271
+ this.parent = null, this.mounted = !1, this.skipMutationNodes = !1, this.target = t, $.FRAGMENT_CACHE.set(t, this);
1272
1272
  }
1273
1273
  static get(t) {
1274
1274
  if (t == null)
1275
1275
  return null;
1276
- if (L.FRAGMENT_CACHE.has(t))
1277
- return L.FRAGMENT_CACHE.get(t);
1276
+ if ($.FRAGMENT_CACHE.has(t))
1277
+ return $.FRAGMENT_CACHE.get(t);
1278
1278
  let e;
1279
1279
  switch (t.nodeType) {
1280
1280
  case Node.ELEMENT_NODE:
1281
- e = new D(t);
1281
+ e = new P(t);
1282
1282
  break;
1283
1283
  case Node.TEXT_NODE:
1284
- e = new I(t);
1284
+ e = new O(t);
1285
1285
  break;
1286
1286
  case Node.COMMENT_NODE:
1287
- e = new tt(t);
1287
+ e = new et(t);
1288
1288
  break;
1289
1289
  default:
1290
1290
  return m.warn("[Haori]", "Unsupported node type:", t.nodeType), null;
@@ -1365,7 +1365,7 @@ const L = class L {
1365
1365
  * @return 除去のPromise
1366
1366
  */
1367
1367
  remove(t = !0) {
1368
- return this.parent && this.parent.removeChild(this), L.FRAGMENT_CACHE.delete(this.target), t ? this.unmount() : Promise.resolve();
1368
+ return this.parent && this.parent.removeChild(this), $.FRAGMENT_CACHE.delete(this.target), t ? this.unmount() : Promise.resolve();
1369
1369
  }
1370
1370
  /**
1371
1371
  * 対象ノードを取得します。
@@ -1392,9 +1392,9 @@ const L = class L {
1392
1392
  this.parent = t;
1393
1393
  }
1394
1394
  };
1395
- L.FRAGMENT_CACHE = /* @__PURE__ */ new WeakMap();
1396
- let R = L;
1397
- const C = class C extends R {
1395
+ $.FRAGMENT_CACHE = /* @__PURE__ */ new WeakMap();
1396
+ let R = $;
1397
+ const I = class I extends R {
1398
1398
  /**
1399
1399
  * エレメントフラグメントのコンストラクタ。
1400
1400
  * アトリビュートや子フラグメントの作成も行います。
@@ -1417,10 +1417,10 @@ const C = class C extends R {
1417
1417
  "month",
1418
1418
  "time",
1419
1419
  "week"
1420
- ], this.children = [], this.attributeMap = /* @__PURE__ */ new Map(), this.bindingData = null, this.bindingDataCache = null, this.visible = !0, this.display = null, this.displayPriority = null, this.template = null, this.listKey = null, this.value = null, this.skipMutationAttributes = !1, this.skipChangeValue = !1, this.syncValue(), t.getAttributeNames().forEach((e) => {
1420
+ ], this.children = [], this.attributeMap = /* @__PURE__ */ new Map(), this.bindingData = null, this.derivedBindingData = null, this.bindingDataCache = null, this.descendantBindingDataCache = null, this.visible = !0, this.display = null, this.displayPriority = null, this.template = null, this.listKey = null, this.value = null, this.skipMutationAttributes = !1, this.skipChangeValue = !1, this.syncValue(), t.getAttributeNames().forEach((e) => {
1421
1421
  const r = t.getAttribute(e);
1422
1422
  if (r !== null && !this.attributeMap.has(e)) {
1423
- const s = new q(e, r);
1423
+ const s = new K(e, r);
1424
1424
  this.attributeMap.set(e, s);
1425
1425
  }
1426
1426
  }), t.childNodes.forEach((e) => {
@@ -1443,7 +1443,7 @@ const C = class C extends R {
1443
1443
  */
1444
1444
  getChildElementFragments() {
1445
1445
  return this.children.filter(
1446
- (t) => t instanceof C
1446
+ (t) => t instanceof I
1447
1447
  );
1448
1448
  }
1449
1449
  /**
@@ -1475,7 +1475,7 @@ const C = class C extends R {
1475
1475
  * @returns クローンされたフラグメント
1476
1476
  */
1477
1477
  clone() {
1478
- const t = new C(
1478
+ const t = new I(
1479
1479
  this.target.cloneNode(!1)
1480
1480
  );
1481
1481
  return this.attributeMap.forEach((e, r) => {
@@ -1483,14 +1483,14 @@ const C = class C extends R {
1483
1483
  }), this.children.forEach((e) => {
1484
1484
  const r = e.clone();
1485
1485
  t.getTarget().appendChild(r.getTarget()), t.pushChild(r);
1486
- }), t.mounted = !1, t.bindingData = this.bindingData, t.clearBindingDataCache(), t.visible = !0, t.display = this.display, t.displayPriority = this.displayPriority, t.template = this.template, t.normalizeClonedVisibilityState(), t;
1486
+ }), t.mounted = !1, t.bindingData = this.bindingData, t.derivedBindingData = this.derivedBindingData, t.clearBindingDataCache(), t.visible = !0, t.display = this.display, t.displayPriority = this.displayPriority, t.template = this.template, t.normalizeClonedVisibilityState(), t;
1487
1487
  }
1488
1488
  /**
1489
1489
  * clone 時に runtime の hidden 状態だけを落とします。
1490
1490
  */
1491
1491
  normalizeClonedVisibilityState() {
1492
- (this.visible === !1 || this.getTarget().style.display === "none" || this.getTarget().hasAttribute(`${c.prefix}if-false`)) && (this.visible = !0, this.display = null, this.displayPriority = null, this.getTarget().style.removeProperty("display"), this.getTarget().removeAttribute(`${c.prefix}if-false`)), this.children.forEach((t) => {
1493
- t instanceof C && t.normalizeClonedVisibilityState();
1492
+ (this.visible === !1 || this.getTarget().style.display === "none" || this.getTarget().hasAttribute(`${u.prefix}if-false`)) && (this.visible = !0, this.display = null, this.displayPriority = null, this.getTarget().style.removeProperty("display"), this.getTarget().removeAttribute(`${u.prefix}if-false`)), this.children.forEach((t) => {
1493
+ t instanceof I && t.normalizeClonedVisibilityState();
1494
1494
  });
1495
1495
  }
1496
1496
  /**
@@ -1503,7 +1503,7 @@ const C = class C extends R {
1503
1503
  const e = [];
1504
1504
  return this.children.forEach((r) => {
1505
1505
  e.push(r.remove(!1));
1506
- }), this.children.length = 0, this.attributeMap.clear(), this.bindingData = null, this.bindingDataCache = null, this.template && (e.push(this.template.remove(!1)), this.template = null), e.push(super.remove(t)), Promise.all(e).then(() => {
1506
+ }), this.children.length = 0, this.attributeMap.clear(), this.bindingData = null, this.bindingDataCache = null, this.derivedBindingData = null, this.descendantBindingDataCache = null, this.template && (e.push(this.template.remove(!1)), this.template = null), e.push(super.remove(t)), Promise.all(e).then(() => {
1507
1507
  });
1508
1508
  }
1509
1509
  /**
@@ -1520,7 +1520,18 @@ const C = class C extends R {
1520
1520
  * @returns バインドデータのオブジェクト
1521
1521
  */
1522
1522
  getBindingData() {
1523
- return this.bindingDataCache ? this.bindingDataCache : (this.bindingDataCache = {}, this.parent && Object.assign(this.bindingDataCache, this.parent.getBindingData()), this.bindingData && Object.assign(this.bindingDataCache, this.bindingData), this.bindingDataCache);
1523
+ return this.bindingDataCache ? this.bindingDataCache : (this.bindingDataCache = {}, this.parent && Object.assign(
1524
+ this.bindingDataCache,
1525
+ this.parent.getDescendantBindingData()
1526
+ ), this.bindingData && Object.assign(this.bindingDataCache, this.bindingData), this.bindingDataCache);
1527
+ }
1528
+ /**
1529
+ * 子孫要素向けのバインドデータを取得します。
1530
+ *
1531
+ * @returns 子孫要素向けのバインドデータ
1532
+ */
1533
+ getDescendantBindingData() {
1534
+ return this.descendantBindingDataCache ? this.descendantBindingDataCache : (this.descendantBindingDataCache = { ...this.getBindingData() }, this.derivedBindingData && Object.assign(this.descendantBindingDataCache, this.derivedBindingData), this.descendantBindingDataCache);
1524
1535
  }
1525
1536
  /**
1526
1537
  * 生のバインドデータを取得します。
@@ -1538,6 +1549,14 @@ const C = class C extends R {
1538
1549
  setBindingData(t) {
1539
1550
  this.bindingData = t, this.clearBindingDataCache();
1540
1551
  }
1552
+ /**
1553
+ * 子孫要素向けの派生バインドデータを設定します。
1554
+ *
1555
+ * @param data 派生バインドデータ。解除する場合は null
1556
+ */
1557
+ setDerivedBindingData(t) {
1558
+ this.derivedBindingData = t, this.clearBindingDataCache();
1559
+ }
1541
1560
  /**
1542
1561
  * 親フラグメントを設定します。バインドデータキャッシュをクリアします。
1543
1562
  *
@@ -1550,8 +1569,8 @@ const C = class C extends R {
1550
1569
  * バインドデータのキャッシュをクリアします。
1551
1570
  */
1552
1571
  clearBindingDataCache() {
1553
- this.bindingDataCache = null, this.children.forEach((t) => {
1554
- t instanceof C && t.clearBindingDataCache();
1572
+ this.bindingDataCache = null, this.descendantBindingDataCache = null, this.children.forEach((t) => {
1573
+ t instanceof I && t.clearBindingDataCache();
1555
1574
  });
1556
1575
  }
1557
1576
  /**
@@ -1732,7 +1751,7 @@ const C = class C extends R {
1732
1751
  return Promise.resolve();
1733
1752
  if (r === null)
1734
1753
  return t === e ? this.removeAttribute(t) : this.removeAliasedAttribute(t, e);
1735
- const n = new q(t, r);
1754
+ const n = new K(t, r);
1736
1755
  if (i) {
1737
1756
  const A = this.attributeMap.get(t);
1738
1757
  if (A && (A.isEvaluate || A.isForceEvaluation()) && !n.isEvaluate && !n.isForceEvaluation())
@@ -1742,12 +1761,12 @@ const C = class C extends R {
1742
1761
  });
1743
1762
  }
1744
1763
  this.attributeMap.set(t, n), this.skipMutationAttributes = !0;
1745
- const a = this.getTarget(), o = n.evaluateDetailed(this.getBindingData()), f = n.isEvaluate || n.isRawEvaluate, p = t === e && C.BOOLEAN_ATTRIBUTES.has(e.toLowerCase()), g = n.isSingleExpression(), y = H.joinEvaluateResults(o.results), b = o.results.length === 1 ? o.results[0] : y, l = !n.isForceEvaluation() && (e !== t || p || g ? o.hasUnresolvedReference || b === null || b === void 0 || b === !1 : f && y === ""), h = n.isForceEvaluation() ? r : g ? b : y;
1764
+ const a = this.getTarget(), o = n.evaluateDetailed(this.getBindingData()), d = n.isEvaluate || n.isRawEvaluate, p = t === e && I.BOOLEAN_ATTRIBUTES.has(e.toLowerCase()), g = n.isSingleExpression(), v = B.joinEvaluateResults(o.results), b = o.results.length === 1 ? o.results[0] : v, l = !n.isForceEvaluation() && (e !== t || p || g ? o.hasUnresolvedReference || b === null || b === void 0 || b === !1 : d && v === ""), f = n.isForceEvaluation() ? r : g ? b : v;
1746
1765
  return N.enqueue(() => {
1747
- if (a.getAttribute(t) !== r && a.setAttribute(t, r), l || h === null || h === !1)
1766
+ if (a.getAttribute(t) !== r && a.setAttribute(t, r), l || f === null || f === !1)
1748
1767
  a.removeAttribute(e);
1749
1768
  else {
1750
- const A = String(h);
1769
+ const A = String(f);
1751
1770
  a.getAttribute(e) !== A && a.setAttribute(e, A), s && n.isEvaluate && e === "value" && (a instanceof HTMLInputElement && this.INPUT_EVENT_TYPES.includes(a.type) || a instanceof HTMLTextAreaElement || a instanceof HTMLSelectElement) && (this.value = A, a.value !== A && (a.value = A));
1752
1771
  }
1753
1772
  }).finally(() => {
@@ -1798,7 +1817,7 @@ const C = class C extends R {
1798
1817
  value: r.results[0],
1799
1818
  hasUnresolvedReference: r.hasUnresolvedReference
1800
1819
  } : {
1801
- value: H.joinEvaluateResults(r.results),
1820
+ value: B.joinEvaluateResults(r.results),
1802
1821
  hasUnresolvedReference: r.hasUnresolvedReference
1803
1822
  };
1804
1823
  }
@@ -1875,14 +1894,14 @@ const C = class C extends R {
1875
1894
  const n = t.getParent() === this;
1876
1895
  let a = -1, o = -1;
1877
1896
  n && (a = this.children.indexOf(t), e !== null && (o = this.children.indexOf(e)));
1878
- const f = t.getParent();
1879
- f !== null && f.removeChild(t);
1897
+ const d = t.getParent();
1898
+ d !== null && d.removeChild(t);
1880
1899
  let p = r === void 0 ? e?.getTarget() || null : r;
1881
1900
  if (e === null)
1882
1901
  this.children.push(t);
1883
1902
  else {
1884
- let y;
1885
- if (n ? a !== -1 && a < o ? y = o - 1 : y = o : y = this.children.indexOf(e), y === -1) {
1903
+ let v;
1904
+ if (n ? a !== -1 && a < o ? v = o - 1 : v = o : v = this.children.indexOf(e), v === -1) {
1886
1905
  const b = this.resolveInsertionPointFromDom(
1887
1906
  e,
1888
1907
  !1
@@ -1893,7 +1912,7 @@ const C = class C extends R {
1893
1912
  e
1894
1913
  ), this.children.push(t)) : (this.children.splice(b.index, 0, t), p = b.referenceNode);
1895
1914
  } else
1896
- this.children.splice(y, 0, t);
1915
+ this.children.splice(v, 0, t);
1897
1916
  }
1898
1917
  t.setParent(this), t.setMounted(this.mounted);
1899
1918
  const g = this.skipMutationNodes;
@@ -1975,7 +1994,7 @@ const C = class C extends R {
1975
1994
  return Promise.resolve();
1976
1995
  this.visible = !1;
1977
1996
  const t = this.getTarget();
1978
- return this.display = t.style.getPropertyValue("display"), this.displayPriority = t.style.getPropertyPriority("display"), t.style.setProperty("display", "none", "important"), t.setAttribute(`${c.prefix}if-false`, ""), Promise.resolve();
1997
+ return this.display = t.style.getPropertyValue("display"), this.displayPriority = t.style.getPropertyPriority("display"), t.style.setProperty("display", "none", "important"), t.setAttribute(`${u.prefix}if-false`, ""), Promise.resolve();
1979
1998
  }
1980
1999
  /**
1981
2000
  * エレメントを表示します。
@@ -1990,7 +2009,7 @@ const C = class C extends R {
1990
2009
  "display",
1991
2010
  this.display,
1992
2011
  this.displayPriority ?? ""
1993
- ), this.display = null, this.displayPriority = null, t.removeAttribute(`${c.prefix}if-false`), this.visible = !0, Promise.resolve();
2012
+ ), this.display = null, this.displayPriority = null, t.removeAttribute(`${u.prefix}if-false`), this.visible = !0, Promise.resolve();
1994
2013
  }
1995
2014
  /**
1996
2015
  * 指定した属性名を持つ最も近い親要素を返します。
@@ -2006,7 +2025,7 @@ const C = class C extends R {
2006
2025
  return e === null ? null : e.closestByAttribute(t);
2007
2026
  }
2008
2027
  };
2009
- C.BOOLEAN_ATTRIBUTES = /* @__PURE__ */ new Set([
2028
+ I.BOOLEAN_ATTRIBUTES = /* @__PURE__ */ new Set([
2010
2029
  "allowfullscreen",
2011
2030
  "async",
2012
2031
  "autofocus",
@@ -2031,8 +2050,8 @@ C.BOOLEAN_ATTRIBUTES = /* @__PURE__ */ new Set([
2031
2050
  "reversed",
2032
2051
  "selected"
2033
2052
  ]);
2034
- let D = C;
2035
- class I extends R {
2053
+ let P = I;
2054
+ class O extends R {
2036
2055
  /**
2037
2056
  * テキストフラグメントのコンストラクタ。
2038
2057
  * 対象テキストノードの内容を初期化します。
@@ -2040,7 +2059,7 @@ class I extends R {
2040
2059
  * @param target 対象テキストノード
2041
2060
  */
2042
2061
  constructor(t) {
2043
- super(t), this.skipMutation = !1, this.text = t.textContent || "", this.contents = new H(this.text);
2062
+ super(t), this.skipMutation = !1, this.text = t.textContent || "", this.contents = new B(this.text);
2044
2063
  }
2045
2064
  /**
2046
2065
  * フラグメントをクローンします。
@@ -2048,7 +2067,7 @@ class I extends R {
2048
2067
  * @returns クローンされたフラグメント
2049
2068
  */
2050
2069
  clone() {
2051
- const t = new I(this.target.cloneNode(!0));
2070
+ const t = new O(this.target.cloneNode(!0));
2052
2071
  return t.mounted = !1, t.text = this.text, t.contents = this.contents, t;
2053
2072
  }
2054
2073
  /**
@@ -2066,7 +2085,7 @@ class I extends R {
2066
2085
  * @returns 更新のPromise
2067
2086
  */
2068
2087
  setContent(t) {
2069
- return this.skipMutation || this.text === t ? Promise.resolve() : (this.text = t, this.contents = new H(t), this.evaluate());
2088
+ return this.skipMutation || this.text === t ? Promise.resolve() : (this.text = t, this.contents = new B(t), this.evaluate());
2070
2089
  }
2071
2090
  /**
2072
2091
  * フラグメントを評価します。
@@ -2079,7 +2098,7 @@ class I extends R {
2079
2098
  ) : N.enqueue(() => {
2080
2099
  this.skipMutation = !0, this.contents.isRawEvaluate ? this.parent.getTarget().innerHTML = this.contents.evaluate(
2081
2100
  this.parent.getBindingData()
2082
- )[0] : this.contents.isEvaluate ? this.target.textContent = H.joinEvaluateResults(
2101
+ )[0] : this.contents.isEvaluate ? this.target.textContent = B.joinEvaluateResults(
2083
2102
  this.contents.evaluate(this.parent.getBindingData())
2084
2103
  ) : this.target.textContent = this.text;
2085
2104
  }).finally(() => {
@@ -2087,7 +2106,7 @@ class I extends R {
2087
2106
  });
2088
2107
  }
2089
2108
  }
2090
- class tt extends R {
2109
+ class et extends R {
2091
2110
  /**
2092
2111
  * コメントフラグメントのコンストラクタ。
2093
2112
  * 対象コメントノードの内容を初期化します。
@@ -2103,7 +2122,7 @@ class tt extends R {
2103
2122
  * @returns クローンされたフラグメント
2104
2123
  */
2105
2124
  clone() {
2106
- const t = new tt(this.target.cloneNode(!0));
2125
+ const t = new et(this.target.cloneNode(!0));
2107
2126
  return t.mounted = !1, t.text = this.text, t;
2108
2127
  }
2109
2128
  /**
@@ -2128,7 +2147,7 @@ class tt extends R {
2128
2147
  }));
2129
2148
  }
2130
2149
  }
2131
- const G = class G {
2150
+ const W = class W {
2132
2151
  /**
2133
2152
  * コンストラクタ。
2134
2153
  *
@@ -2136,7 +2155,7 @@ const G = class G {
2136
2155
  */
2137
2156
  constructor(t) {
2138
2157
  this.contents = [], this.isEvaluate = !1, this.isRawEvaluate = !1, this.value = t;
2139
- const e = [...t.matchAll(G.PLACEHOLDER_REGEX)];
2158
+ const e = [...t.matchAll(W.PLACEHOLDER_REGEX)];
2140
2159
  let r = 0, s = !1, i = !1;
2141
2160
  for (const n of e) {
2142
2161
  n.index > r && this.contents.push({
@@ -2218,7 +2237,7 @@ const G = class G {
2218
2237
  return this.contents.forEach((s) => {
2219
2238
  try {
2220
2239
  if (s.type === 1 || s.type === 2) {
2221
- const i = V.evaluateDetailed(s.text, t);
2240
+ const i = U.evaluateDetailed(s.text, t);
2222
2241
  r = r || i.unresolvedReference, e.push(i.value);
2223
2242
  } else
2224
2243
  e.push(s.text);
@@ -2232,9 +2251,9 @@ const G = class G {
2232
2251
  }), { results: e, hasUnresolvedReference: r };
2233
2252
  }
2234
2253
  };
2235
- G.PLACEHOLDER_REGEX = /\{\{\{([\s\S]+?)\}\}\}|\{\{([\s\S]+?)\}\}/g;
2236
- let H = G;
2237
- const W = class W extends H {
2254
+ W.PLACEHOLDER_REGEX = /\{\{\{([\s\S]+?)\}\}\}|\{\{([\s\S]+?)\}\}/g;
2255
+ let B = W;
2256
+ const J = class J extends B {
2238
2257
  /**
2239
2258
  * コンストラクタ。
2240
2259
  *
@@ -2242,7 +2261,7 @@ const W = class W extends H {
2242
2261
  * @param text 属性値
2243
2262
  */
2244
2263
  constructor(t, e) {
2245
- super(e), this.forceEvaluation = W.FORCE_EVALUATION_ATTRIBUTES.includes(t);
2264
+ super(e), this.forceEvaluation = J.FORCE_EVALUATION_ATTRIBUTES.includes(t);
2246
2265
  }
2247
2266
  /**
2248
2267
  * 強制評価フラグを取得します。
@@ -2278,7 +2297,7 @@ const W = class W extends H {
2278
2297
  return this.contents.forEach((s) => {
2279
2298
  try {
2280
2299
  if (this.forceEvaluation && s.type === 0 || s.type === 1 || s.type === 2) {
2281
- const i = V.evaluateDetailed(s.text, t);
2300
+ const i = U.evaluateDetailed(s.text, t);
2282
2301
  r = r || i.unresolvedReference, e.push(i.value);
2283
2302
  } else
2284
2303
  e.push(s.text);
@@ -2299,13 +2318,15 @@ const W = class W extends H {
2299
2318
  }) : { results: e, hasUnresolvedReference: r };
2300
2319
  }
2301
2320
  };
2302
- W.FORCE_EVALUATION_ATTRIBUTES = [
2321
+ J.FORCE_EVALUATION_ATTRIBUTES = [
2303
2322
  "data-if",
2304
2323
  "hor-if",
2305
2324
  "data-each",
2306
- "hor-each"
2325
+ "hor-each",
2326
+ "data-derive",
2327
+ "hor-derive"
2307
2328
  ];
2308
- let q = W;
2329
+ let K = J;
2309
2330
  class S {
2310
2331
  /**
2311
2332
  * カスタムイベントを発火します。
@@ -2387,9 +2408,9 @@ class S {
2387
2408
  */
2388
2409
  static bindChange(t, e, r, s = "other") {
2389
2410
  const i = [], n = new Set(Object.keys(e || {})), a = new Set(Object.keys(r)), o = /* @__PURE__ */ new Set([...n, ...a]);
2390
- for (const f of o) {
2391
- const p = e?.[f], g = r[f];
2392
- p !== g && i.push(f);
2411
+ for (const d of o) {
2412
+ const p = e?.[d], g = r[d];
2413
+ p !== g && i.push(d);
2393
2414
  }
2394
2415
  S.dispatch(t, "bindchange", {
2395
2416
  previous: e || {},
@@ -2514,35 +2535,35 @@ class S {
2514
2535
  });
2515
2536
  }
2516
2537
  }
2517
- const lt = [
2538
+ const ut = [
2518
2539
  "addErrorMessage",
2519
2540
  "closeDialog",
2520
2541
  "confirm",
2521
2542
  "dialog",
2522
2543
  "openDialog",
2523
2544
  "toast"
2524
- ], ut = "__haoriHistoryState__", z = "data-haori-click-lock";
2525
- function Q() {
2545
+ ], ct = "__haoriHistoryState__", Q = "data-haori-click-lock";
2546
+ function Z() {
2526
2547
  const t = globalThis.window?.Haori;
2527
- return lt.every(
2548
+ return ut.every(
2528
2549
  (r) => typeof t?.[r] == "function"
2529
- ) ? t : Y;
2550
+ ) ? t : X;
2530
2551
  }
2531
- const ct = /* @__PURE__ */ new Set(["GET", "HEAD", "OPTIONS"]);
2532
- function ht(E) {
2533
- return ct.has(E.toUpperCase());
2552
+ const ht = /* @__PURE__ */ new Set(["GET", "HEAD", "OPTIONS"]);
2553
+ function ft(E) {
2554
+ return ht.has(E.toUpperCase());
2534
2555
  }
2535
- function ft(E, t) {
2556
+ function dt(E, t) {
2536
2557
  for (const [e, r] of Object.entries(t))
2537
2558
  r !== void 0 && (r === null ? E.append(e, "") : Array.isArray(r) ? r.forEach((s) => {
2538
2559
  E.append(e, String(s));
2539
2560
  }) : typeof r == "object" || typeof r == "function" ? E.append(e, JSON.stringify(r)) : E.append(e, String(r)));
2540
2561
  }
2541
- function dt(E, t) {
2562
+ function pt(E, t) {
2542
2563
  const e = new URL(E, window.location.href), r = new URLSearchParams(e.search);
2543
- return ft(r, t), e.search = r.toString(), e.toString();
2564
+ return dt(r, t), e.search = r.toString(), e.toString();
2544
2565
  }
2545
- function pt(E) {
2566
+ function gt(E) {
2546
2567
  return E == null ? null : typeof E == "string" ? E : E instanceof URLSearchParams ? E.toString() : E instanceof FormData ? Array.from(E.entries()).map(([t, e]) => e instanceof File ? [
2547
2568
  t,
2548
2569
  {
@@ -2553,7 +2574,7 @@ function pt(E) {
2553
2574
  }
2554
2575
  ] : [t, String(e)]) : String(E);
2555
2576
  }
2556
- function gt(E, t) {
2577
+ function mt(E, t) {
2557
2578
  const e = new Headers(
2558
2579
  t.headers || void 0
2559
2580
  ), r = Array.from(e.entries()).sort(
@@ -2563,10 +2584,10 @@ function gt(E, t) {
2563
2584
  url: E,
2564
2585
  method: String(t.method || "GET").toUpperCase(),
2565
2586
  headers: r,
2566
- body: pt(t.body || null)
2587
+ body: gt(t.body || null)
2567
2588
  });
2568
2589
  }
2569
- const u = class u {
2590
+ const c = class c {
2570
2591
  /**
2571
2592
  * イベント属性名を正しく生成します。
2572
2593
  * 例: ("click", "fetch") => "data-click-fetch"
@@ -2575,7 +2596,7 @@ const u = class u {
2575
2596
  * 非イベント変種が "data-fetch-xxx" として存在するものについては、event が null の場合にそちらを返します。
2576
2597
  */
2577
2598
  static attrName(t, e, r = !1) {
2578
- return t ? `${c.prefix}${t}-${e}` : r ? `${c.prefix}fetch-${e}` : `${c.prefix}${e}`;
2599
+ return t ? `${u.prefix}${t}-${e}` : r ? `${u.prefix}fetch-${e}` : `${u.prefix}${e}`;
2579
2600
  }
2580
2601
  /**
2581
2602
  * data 属性のテンプレート式評価結果を URLSearchParams 向けに組み立てます。
@@ -2585,7 +2606,7 @@ const u = class u {
2585
2606
  * @returns パラメータ形式として扱える文字列
2586
2607
  */
2587
2608
  static resolveDataParamString(t, e) {
2588
- return u.resolveDataParamStringDetailed(t, e).value;
2609
+ return c.resolveDataParamStringDetailed(t, e).value;
2589
2610
  }
2590
2611
  /**
2591
2612
  * data 属性のテンプレート式評価結果を URLSearchParams 向けに組み立てます。
@@ -2597,9 +2618,9 @@ const u = class u {
2597
2618
  static resolveDataParamStringDetailed(t, e) {
2598
2619
  let r = !1;
2599
2620
  return { value: t.replace(
2600
- u.DATA_PLACEHOLDER_REGEX,
2621
+ c.DATA_PLACEHOLDER_REGEX,
2601
2622
  (i, n, a) => {
2602
- const o = V.evaluateDetailed(
2623
+ const o = U.evaluateDetailed(
2603
2624
  n ?? a ?? "",
2604
2625
  e
2605
2626
  );
@@ -2654,7 +2675,7 @@ const u = class u {
2654
2675
  static stringifyJsonTemplateStringContent(t) {
2655
2676
  if (t == null || Number.isNaN(t))
2656
2677
  return "";
2657
- const e = typeof t == "object" ? u.stringifyJsonTemplateValue(t) : String(t);
2678
+ const e = typeof t == "object" ? c.stringifyJsonTemplateValue(t) : String(t);
2658
2679
  return JSON.stringify(e).slice(1, -1);
2659
2680
  }
2660
2681
  /**
@@ -2665,7 +2686,7 @@ const u = class u {
2665
2686
  * @returns JSON として解釈可能な文字列
2666
2687
  */
2667
2688
  static resolveDataJsonString(t, e) {
2668
- return u.resolveDataJsonStringDetailed(t, e).value;
2689
+ return c.resolveDataJsonStringDetailed(t, e).value;
2669
2690
  }
2670
2691
  /**
2671
2692
  * JSON 形式 data 属性内のテンプレート式を安全に解決します。
@@ -2677,13 +2698,13 @@ const u = class u {
2677
2698
  static resolveDataJsonStringDetailed(t, e) {
2678
2699
  let r = !1;
2679
2700
  return { value: t.replace(
2680
- u.DATA_PLACEHOLDER_REGEX,
2701
+ c.DATA_PLACEHOLDER_REGEX,
2681
2702
  (i, n, a, o) => {
2682
- const f = V.evaluateDetailed(
2703
+ const d = U.evaluateDetailed(
2683
2704
  n ?? a ?? "",
2684
2705
  e
2685
2706
  );
2686
- return r = r || f.unresolvedReference, u.isJsonStringContext(t, o) ? u.stringifyJsonTemplateStringContent(f.value) : u.stringifyJsonTemplateValue(f.value);
2707
+ return r = r || d.unresolvedReference, c.isJsonStringContext(t, o) ? c.stringifyJsonTemplateStringContent(d.value) : c.stringifyJsonTemplateValue(d.value);
2687
2708
  }
2688
2709
  ), hasUnresolvedReference: r };
2689
2710
  }
@@ -2695,7 +2716,7 @@ const u = class u {
2695
2716
  * @returns 送信データ
2696
2717
  */
2697
2718
  static resolveDataAttribute(t, e) {
2698
- return u.resolveDataAttributeDetailed(t, e).value;
2719
+ return c.resolveDataAttributeDetailed(t, e).value;
2699
2720
  }
2700
2721
  /**
2701
2722
  * data 属性を評価済みの値として取得し、未解決参照の有無を返します。
@@ -2714,27 +2735,27 @@ const u = class u {
2714
2735
  if (typeof i != "string" || r === null)
2715
2736
  return { value: null, hasUnresolvedReference: n };
2716
2737
  const a = r.trim();
2717
- if (u.SINGLE_PLACEHOLDER_REGEX.test(a))
2738
+ if (c.SINGLE_PLACEHOLDER_REGEX.test(a))
2718
2739
  return {
2719
- value: P.parseDataBind(i),
2740
+ value: D.parseDataBind(i),
2720
2741
  hasUnresolvedReference: n
2721
2742
  };
2722
2743
  if (a.startsWith("{") || a.startsWith("[")) {
2723
- const f = u.resolveDataJsonStringDetailed(
2744
+ const d = c.resolveDataJsonStringDetailed(
2724
2745
  r,
2725
2746
  t.getBindingData()
2726
2747
  );
2727
2748
  return {
2728
- value: P.parseDataBind(f.value),
2729
- hasUnresolvedReference: n || f.hasUnresolvedReference
2749
+ value: D.parseDataBind(d.value),
2750
+ hasUnresolvedReference: n || d.hasUnresolvedReference
2730
2751
  };
2731
2752
  }
2732
- const o = u.resolveDataParamStringDetailed(
2753
+ const o = c.resolveDataParamStringDetailed(
2733
2754
  r,
2734
2755
  t.getBindingData()
2735
2756
  );
2736
2757
  return {
2737
- value: P.parseDataBind(o.value),
2758
+ value: D.parseDataBind(o.value),
2738
2759
  hasUnresolvedReference: n || o.hasUnresolvedReference
2739
2760
  };
2740
2761
  }
@@ -2750,27 +2771,27 @@ const u = class u {
2750
2771
  targetFragment: t
2751
2772
  };
2752
2773
  if (e) {
2753
- if (t.hasAttribute(u.attrName(e, "validate")) && (r.valid = !0), t.hasAttribute(u.attrName(e, "confirm")) && (r.confirmMessage = t.getAttribute(
2754
- u.attrName(e, "confirm")
2774
+ if (t.hasAttribute(c.attrName(e, "validate")) && (r.valid = !0), t.hasAttribute(c.attrName(e, "confirm")) && (r.confirmMessage = t.getAttribute(
2775
+ c.attrName(e, "confirm")
2755
2776
  ).replace(/\\n/g, `
2756
- `)), t.hasAttribute(u.attrName(e, "data")) && (r.dataAttrName = u.attrName(e, "data")), t.hasAttribute(u.attrName(e, "form"))) {
2777
+ `)), t.hasAttribute(c.attrName(e, "data")) && (r.dataAttrName = c.attrName(e, "data")), t.hasAttribute(c.attrName(e, "form"))) {
2757
2778
  const l = t.getRawAttribute(
2758
- u.attrName(e, "form")
2779
+ c.attrName(e, "form")
2759
2780
  );
2760
2781
  if (l) {
2761
- const h = document.body.querySelector(l);
2762
- h !== null ? r.formFragment = v.getFormFragment(
2763
- R.get(h)
2782
+ const f = document.body.querySelector(l);
2783
+ f !== null ? r.formFragment = y.getFormFragment(
2784
+ R.get(f)
2764
2785
  ) : m.error(
2765
2786
  "Haori",
2766
- `Form element not found: ${l} (${u.attrName(e, "form")})`
2787
+ `Form element not found: ${l} (${c.attrName(e, "form")})`
2767
2788
  );
2768
2789
  } else
2769
- r.formFragment = v.getFormFragment(t);
2770
- } else e === "change" && (r.formFragment = v.getFormFragment(t));
2771
- if (t.hasAttribute(`${c.prefix}${e}-before-run`)) {
2790
+ r.formFragment = y.getFormFragment(t);
2791
+ } else e === "change" && (r.formFragment = y.getFormFragment(t));
2792
+ if (t.hasAttribute(`${u.prefix}${e}-before-run`)) {
2772
2793
  const l = t.getRawAttribute(
2773
- `${c.prefix}${e}-before-run`
2794
+ `${u.prefix}${e}-before-run`
2774
2795
  );
2775
2796
  try {
2776
2797
  r.beforeCallback = new Function(
@@ -2781,79 +2802,79 @@ const u = class u {
2781
2802
  ${l}
2782
2803
  `
2783
2804
  );
2784
- } catch (h) {
2785
- m.error("Haori", `Invalid before script: ${h}`);
2805
+ } catch (f) {
2806
+ m.error("Haori", `Invalid before script: ${f}`);
2786
2807
  }
2787
2808
  }
2788
2809
  }
2789
- const s = u.attrName(e, "fetch"), i = t.hasAttribute(s);
2810
+ const s = c.attrName(e, "fetch"), i = t.hasAttribute(s);
2790
2811
  if (i) {
2791
2812
  const l = t.getAttributeEvaluation(s);
2792
2813
  l && (r.fetchHasUnresolvedReference = l.hasUnresolvedReference, r.fetchUrl = l.hasUnresolvedReference ? null : l.value);
2793
2814
  }
2794
2815
  const n = {};
2795
2816
  if (e) {
2796
- const l = u.attrName(e, "fetch-method");
2817
+ const l = c.attrName(e, "fetch-method");
2797
2818
  if (t.hasAttribute(l)) {
2798
- const h = t.getAttributeEvaluation(
2819
+ const f = t.getAttributeEvaluation(
2799
2820
  l
2800
2821
  );
2801
- h?.hasUnresolvedReference ? r.fetchHasUnresolvedReference = !0 : n.method = h?.value;
2822
+ f?.hasUnresolvedReference ? r.fetchHasUnresolvedReference = !0 : n.method = f?.value;
2802
2823
  }
2803
2824
  } else {
2804
- const l = u.attrName(null, "method", !0);
2825
+ const l = c.attrName(null, "method", !0);
2805
2826
  if (t.hasAttribute(l)) {
2806
- const h = t.getAttributeEvaluation(
2827
+ const f = t.getAttributeEvaluation(
2807
2828
  l
2808
2829
  );
2809
- h?.hasUnresolvedReference ? r.fetchHasUnresolvedReference = !0 : n.method = h?.value;
2830
+ f?.hasUnresolvedReference ? r.fetchHasUnresolvedReference = !0 : n.method = f?.value;
2810
2831
  }
2811
2832
  }
2812
2833
  if (e) {
2813
- const l = u.attrName(e, "fetch-headers");
2834
+ const l = c.attrName(e, "fetch-headers");
2814
2835
  if (t.hasAttribute(l)) {
2815
- const h = t.getRawAttribute(
2836
+ const f = t.getRawAttribute(
2816
2837
  l
2817
2838
  );
2818
2839
  try {
2819
- n.headers = P.parseDataBind(h);
2840
+ n.headers = D.parseDataBind(f);
2820
2841
  } catch (A) {
2821
2842
  m.error("Haori", `Invalid fetch headers: ${A}`);
2822
2843
  }
2823
2844
  }
2824
2845
  } else {
2825
- const l = u.attrName(
2846
+ const l = c.attrName(
2826
2847
  null,
2827
2848
  "headers",
2828
2849
  !0
2829
2850
  );
2830
2851
  if (t.hasAttribute(l)) {
2831
- const h = t.getRawAttribute(
2852
+ const f = t.getRawAttribute(
2832
2853
  l
2833
2854
  );
2834
2855
  try {
2835
- n.headers = P.parseDataBind(h);
2856
+ n.headers = D.parseDataBind(f);
2836
2857
  } catch (A) {
2837
2858
  m.error("Haori", `Invalid fetch headers: ${A}`);
2838
2859
  }
2839
2860
  }
2840
2861
  }
2841
2862
  if (e) {
2842
- const l = u.attrName(
2863
+ const l = c.attrName(
2843
2864
  e,
2844
2865
  "fetch-content-type"
2845
2866
  );
2846
2867
  if (t.hasAttribute(l)) {
2847
- const h = t.getAttributeEvaluation(
2868
+ const f = t.getAttributeEvaluation(
2848
2869
  l
2849
2870
  );
2850
- h?.hasUnresolvedReference && (r.fetchHasUnresolvedReference = !0), n.headers = {
2871
+ f?.hasUnresolvedReference && (r.fetchHasUnresolvedReference = !0), n.headers = {
2851
2872
  ...n.headers,
2852
- "Content-Type": h?.value
2873
+ "Content-Type": f?.value
2853
2874
  };
2854
2875
  } else if (n.method && n.method !== "GET" && n.method !== "HEAD" && n.method !== "OPTIONS") {
2855
- let h = !1;
2856
- n.headers && typeof n.headers == "object" && (h = "Content-Type" in n.headers), h || (n.headers = {
2876
+ let f = !1;
2877
+ n.headers && typeof n.headers == "object" && (f = "Content-Type" in n.headers), f || (n.headers = {
2857
2878
  ...n.headers,
2858
2879
  "Content-Type": "application/json"
2859
2880
  });
@@ -2862,22 +2883,22 @@ ${l}
2862
2883
  "Content-Type": "application/x-www-form-urlencoded"
2863
2884
  });
2864
2885
  } else {
2865
- const l = u.attrName(
2886
+ const l = c.attrName(
2866
2887
  null,
2867
2888
  "content-type",
2868
2889
  !0
2869
2890
  );
2870
2891
  if (t.hasAttribute(l)) {
2871
- const h = t.getAttributeEvaluation(
2892
+ const f = t.getAttributeEvaluation(
2872
2893
  l
2873
2894
  );
2874
- h?.hasUnresolvedReference && (r.fetchHasUnresolvedReference = !0), n.headers = {
2895
+ f?.hasUnresolvedReference && (r.fetchHasUnresolvedReference = !0), n.headers = {
2875
2896
  ...n.headers,
2876
- "Content-Type": h?.value
2897
+ "Content-Type": f?.value
2877
2898
  };
2878
2899
  } else if (n.method && n.method !== "GET" && n.method !== "HEAD" && n.method !== "OPTIONS") {
2879
- let h = !1;
2880
- n.headers && typeof n.headers == "object" && (h = "Content-Type" in n.headers), h || (n.headers = {
2900
+ let f = !1;
2901
+ n.headers && typeof n.headers == "object" && (f = "Content-Type" in n.headers), f || (n.headers = {
2881
2902
  ...n.headers,
2882
2903
  "Content-Type": "application/json"
2883
2904
  });
@@ -2887,12 +2908,12 @@ ${l}
2887
2908
  });
2888
2909
  }
2889
2910
  Object.keys(n).length > 0 && (r.fetchOptions = n);
2890
- const a = e ? u.attrName(e, "bind") : u.attrName(null, "bind", !0);
2911
+ const a = e ? c.attrName(e, "bind") : c.attrName(null, "bind", !0);
2891
2912
  if (t.hasAttribute(a)) {
2892
2913
  const l = t.getRawAttribute(a);
2893
2914
  if (l) {
2894
- const h = document.body.querySelectorAll(l);
2895
- h.length > 0 ? (r.bindFragments = [], h.forEach((A) => {
2915
+ const f = document.body.querySelectorAll(l);
2916
+ f.length > 0 ? (r.bindFragments = [], f.forEach((A) => {
2896
2917
  const F = R.get(A);
2897
2918
  F && r.bindFragments.push(F);
2898
2919
  })) : m.error(
@@ -2901,105 +2922,105 @@ ${l}
2901
2922
  );
2902
2923
  }
2903
2924
  }
2904
- const o = u.attrName(e, "bind-arg"), f = u.attrName(
2925
+ const o = c.attrName(e, "bind-arg"), d = c.attrName(
2905
2926
  null,
2906
2927
  "arg",
2907
2928
  !0
2908
- ), p = u.attrName(
2929
+ ), p = c.attrName(
2909
2930
  null,
2910
2931
  "bind-arg",
2911
2932
  !0
2912
2933
  );
2913
- e ? t.hasAttribute(o) && (r.bindArg = t.getRawAttribute(o)) : t.hasAttribute(f) ? r.bindArg = t.getRawAttribute(
2914
- f
2934
+ e ? t.hasAttribute(o) && (r.bindArg = t.getRawAttribute(o)) : t.hasAttribute(d) ? r.bindArg = t.getRawAttribute(
2935
+ d
2915
2936
  ) : t.hasAttribute(p) && (r.bindArg = t.getRawAttribute(p));
2916
- const g = e ? u.attrName(e, "bind-params") : u.attrName(null, "bind-params", !0);
2937
+ const g = e ? c.attrName(e, "bind-params") : c.attrName(null, "bind-params", !0);
2917
2938
  if (t.hasAttribute(g)) {
2918
2939
  const l = t.getRawAttribute(g);
2919
- r.bindParams = l.split("&").map((h) => h.trim());
2940
+ r.bindParams = l.split("&").map((f) => f.trim());
2920
2941
  }
2921
- const y = e ? u.attrName(e, "bind-append") : u.attrName(null, "bind-append", !0);
2922
- if (t.hasAttribute(y)) {
2923
- const l = t.getRawAttribute(y);
2924
- r.bindAppendParams = l.split("&").map((h) => h.trim()).filter(Boolean);
2942
+ const v = e ? c.attrName(e, "bind-append") : c.attrName(null, "bind-append", !0);
2943
+ if (t.hasAttribute(v)) {
2944
+ const l = t.getRawAttribute(v);
2945
+ r.bindAppendParams = l.split("&").map((f) => f.trim()).filter(Boolean);
2925
2946
  }
2926
- const b = e ? u.attrName(e, "copy-params") : null;
2947
+ const b = e ? c.attrName(e, "copy-params") : null;
2927
2948
  if (b && t.hasAttribute(b)) {
2928
2949
  const l = t.getRawAttribute(
2929
2950
  b
2930
2951
  );
2931
- r.copyParams = l.split("&").map((h) => h.trim()).filter(Boolean);
2952
+ r.copyParams = l.split("&").map((f) => f.trim()).filter(Boolean);
2932
2953
  }
2933
2954
  if (e) {
2934
- if (t.hasAttribute(u.attrName(e, "adjust"))) {
2935
- const h = t.getRawAttribute(
2936
- u.attrName(e, "adjust")
2955
+ if (t.hasAttribute(c.attrName(e, "adjust"))) {
2956
+ const f = t.getRawAttribute(
2957
+ c.attrName(e, "adjust")
2937
2958
  );
2938
- if (h) {
2939
- const A = document.body.querySelectorAll(h);
2959
+ if (f) {
2960
+ const A = document.body.querySelectorAll(f);
2940
2961
  A.length > 0 ? (r.adjustFragments = [], A.forEach((F) => {
2941
2962
  const w = R.get(F);
2942
2963
  w && r.adjustFragments.push(w);
2943
2964
  })) : m.error(
2944
2965
  "Haori",
2945
- `Adjust element not found: ${h} (${u.attrName(e, "adjust")})`
2966
+ `Adjust element not found: ${f} (${c.attrName(e, "adjust")})`
2946
2967
  );
2947
2968
  }
2948
- if (t.hasAttribute(u.attrName(e, "adjust-value"))) {
2969
+ if (t.hasAttribute(c.attrName(e, "adjust-value"))) {
2949
2970
  const A = t.getRawAttribute(
2950
- u.attrName(e, "adjust-value")
2971
+ c.attrName(e, "adjust-value")
2951
2972
  ), F = Number(A);
2952
2973
  isNaN(F) || (r.adjustValue = F);
2953
2974
  }
2954
2975
  }
2955
- if (t.hasAttribute(u.attrName(e, "row-add")) && (r.rowAdd = !0), t.hasAttribute(u.attrName(e, "row-remove")) && (r.rowRemove = !0), t.hasAttribute(u.attrName(e, "row-prev")) && (r.rowMovePrev = !0), t.hasAttribute(u.attrName(e, "row-next")) && (r.rowMoveNext = !0), t.hasAttribute(`${c.prefix}${e}-after-run`)) {
2956
- const h = t.getRawAttribute(
2957
- `${c.prefix}${e}-after-run`
2976
+ if (t.hasAttribute(c.attrName(e, "row-add")) && (r.rowAdd = !0), t.hasAttribute(c.attrName(e, "row-remove")) && (r.rowRemove = !0), t.hasAttribute(c.attrName(e, "row-prev")) && (r.rowMovePrev = !0), t.hasAttribute(c.attrName(e, "row-next")) && (r.rowMoveNext = !0), t.hasAttribute(`${u.prefix}${e}-after-run`)) {
2977
+ const f = t.getRawAttribute(
2978
+ `${u.prefix}${e}-after-run`
2958
2979
  );
2959
2980
  try {
2960
2981
  r.afterCallback = new Function(
2961
2982
  "response",
2962
2983
  `
2963
2984
  "use strict";
2964
- ${h}
2985
+ ${f}
2965
2986
  `
2966
2987
  );
2967
2988
  } catch (A) {
2968
2989
  m.error("Haori", `Invalid after script: ${A}`);
2969
2990
  }
2970
2991
  }
2971
- if (t.hasAttribute(u.attrName(e, "dialog")) && (r.dialogMessage = t.getAttribute(
2972
- u.attrName(e, "dialog")
2992
+ if (t.hasAttribute(c.attrName(e, "dialog")) && (r.dialogMessage = t.getAttribute(
2993
+ c.attrName(e, "dialog")
2973
2994
  ).replace(/\\n/g, `
2974
- `)), t.hasAttribute(u.attrName(e, "toast"))) {
2995
+ `)), t.hasAttribute(c.attrName(e, "toast"))) {
2975
2996
  r.toastMessage = t.getAttribute(
2976
- u.attrName(e, "toast")
2997
+ c.attrName(e, "toast")
2977
2998
  );
2978
- const h = t.getRawAttribute(
2979
- u.attrName(e, "toast-level")
2980
- ), F = ["info", "warning", "error", "success"].includes(h);
2981
- r.toastLevel = F ? h : null;
2999
+ const f = t.getRawAttribute(
3000
+ c.attrName(e, "toast-level")
3001
+ ), F = ["info", "warning", "error", "success"].includes(f);
3002
+ r.toastLevel = F ? f : null;
2982
3003
  }
2983
- if (t.hasAttribute(u.attrName(e, "redirect")) && (r.redirectUrl = t.getAttribute(
2984
- u.attrName(e, "redirect")
2985
- )), t.hasAttribute(u.attrName(e, "scroll-error")) && (r.scrollOnError = !0), t.hasAttribute(u.attrName(e, "scroll")) && (r.scrollTarget = t.getAttribute(
2986
- u.attrName(e, "scroll")
2987
- )), t.hasAttribute(u.attrName(e, "history")) && (r.historyUrl = t.getAttribute(
2988
- u.attrName(e, "history")
2989
- )), t.hasAttribute(u.attrName(e, "history-data")) && (r.historyDataAttrName = u.attrName(e, "history-data")), t.hasAttribute(u.attrName(e, "history-form"))) {
2990
- const h = t.getRawAttribute(
2991
- u.attrName(e, "history-form")
3004
+ if (t.hasAttribute(c.attrName(e, "redirect")) && (r.redirectUrl = t.getAttribute(
3005
+ c.attrName(e, "redirect")
3006
+ )), t.hasAttribute(c.attrName(e, "scroll-error")) && (r.scrollOnError = !0), t.hasAttribute(c.attrName(e, "scroll")) && (r.scrollTarget = t.getAttribute(
3007
+ c.attrName(e, "scroll")
3008
+ )), t.hasAttribute(c.attrName(e, "history")) && (r.historyUrl = t.getAttribute(
3009
+ c.attrName(e, "history")
3010
+ )), t.hasAttribute(c.attrName(e, "history-data")) && (r.historyDataAttrName = c.attrName(e, "history-data")), t.hasAttribute(c.attrName(e, "history-form"))) {
3011
+ const f = t.getRawAttribute(
3012
+ c.attrName(e, "history-form")
2992
3013
  );
2993
- if (h) {
2994
- const A = document.body.querySelector(h);
2995
- A !== null ? r.historyFormFragment = v.getFormFragment(
3014
+ if (f) {
3015
+ const A = document.body.querySelector(f);
3016
+ A !== null ? r.historyFormFragment = y.getFormFragment(
2996
3017
  R.get(A)
2997
3018
  ) : m.error(
2998
3019
  "Haori",
2999
- `Form element not found: ${h} (${u.attrName(e, "history-form")})`
3020
+ `Form element not found: ${f} (${c.attrName(e, "history-form")})`
3000
3021
  );
3001
3022
  } else
3002
- r.historyFormFragment = v.getFormFragment(t);
3023
+ r.historyFormFragment = y.getFormFragment(t);
3003
3024
  }
3004
3025
  [
3005
3026
  "reset-before",
@@ -3009,16 +3030,16 @@ ${h}
3009
3030
  "copy",
3010
3031
  "open",
3011
3032
  "close"
3012
- ].forEach((h) => {
3013
- const A = u.attrName(e, h);
3033
+ ].forEach((f) => {
3034
+ const A = c.attrName(e, f);
3014
3035
  if (!t.hasAttribute(A))
3015
3036
  return;
3016
3037
  const F = t.getRawAttribute(A), w = [];
3017
- if (F ? (document.body.querySelectorAll(F).forEach((X) => {
3018
- const rt = R.get(X);
3019
- rt && w.push(rt);
3038
+ if (F ? (document.body.querySelectorAll(F).forEach((z) => {
3039
+ const q = R.get(z);
3040
+ q && w.push(q);
3020
3041
  }), w.length === 0 && m.error("Haori", `Element not found: ${F} (${A})`)) : w.push(t), w.length > 0)
3021
- switch (h) {
3042
+ switch (f) {
3022
3043
  case "reset-before":
3023
3044
  r.resetBeforeFragments = w;
3024
3045
  break;
@@ -3043,20 +3064,20 @@ ${h}
3043
3064
  }
3044
3065
  });
3045
3066
  }
3046
- if (!e && (t.hasAttribute(u.attrName(null, "data", !0)) && (r.dataAttrName = u.attrName(null, "data", !0)), t.hasAttribute(u.attrName(null, "form", !0)))) {
3067
+ if (!e && (t.hasAttribute(c.attrName(null, "data", !0)) && (r.dataAttrName = c.attrName(null, "data", !0)), t.hasAttribute(c.attrName(null, "form", !0)))) {
3047
3068
  const l = t.getRawAttribute(
3048
- u.attrName(null, "form", !0)
3069
+ c.attrName(null, "form", !0)
3049
3070
  );
3050
3071
  if (l) {
3051
- const h = document.body.querySelector(l);
3052
- h !== null ? r.formFragment = v.getFormFragment(
3053
- R.get(h)
3072
+ const f = document.body.querySelector(l);
3073
+ f !== null ? r.formFragment = y.getFormFragment(
3074
+ R.get(f)
3054
3075
  ) : m.error(
3055
3076
  "Haori",
3056
- `Form element not found: ${l} (${u.attrName(null, "fetch-form", !0)})`
3077
+ `Form element not found: ${l} (${c.attrName(null, "fetch-form", !0)})`
3057
3078
  );
3058
3079
  } else
3059
- r.formFragment = v.getFormFragment(t);
3080
+ r.formFragment = y.getFormFragment(t);
3060
3081
  }
3061
3082
  return i && (!r.bindFragments || r.bindFragments.length === 0) && (r.bindFragments = [t]), r;
3062
3083
  }
@@ -3079,7 +3100,7 @@ ${h}
3079
3100
  * @param arg2 イベント名
3080
3101
  */
3081
3102
  constructor(t, e = null) {
3082
- u.isElementFragment(t) ? (this.options = u.buildOptions(t, e), this.eventType = e) : (this.options = t, this.eventType = null);
3103
+ c.isElementFragment(t) ? (this.options = c.buildOptions(t, e), this.eventType = e) : (this.options = t, this.eventType = null);
3083
3104
  }
3084
3105
  /**
3085
3106
  * 非イベント data-fetch の自動再評価用シグネチャを解決します。
@@ -3088,7 +3109,7 @@ ${h}
3088
3109
  * @returns フェッチシグネチャと未解決参照の有無
3089
3110
  */
3090
3111
  static resolveAutoFetchSignature(t) {
3091
- return new u(t, null).resolveFetchSignature();
3112
+ return new c(t, null).resolveFetchSignature();
3092
3113
  }
3093
3114
  /**
3094
3115
  * 一連の処理を実行します。オプションが空の場合は即座にresolveされます。
@@ -3121,7 +3142,7 @@ ${h}
3121
3142
  return !1;
3122
3143
  this.options.resetBeforeFragments && this.options.resetBeforeFragments.length > 0 && (await Promise.all(
3123
3144
  this.options.resetBeforeFragments.map(
3124
- (p) => v.reset(p)
3145
+ (p) => y.reset(p)
3125
3146
  )
3126
3147
  ), this.captureHistorySnapshots());
3127
3148
  const r = this.prepareFetchRequest(), s = r.payload;
@@ -3139,20 +3160,20 @@ ${h}
3139
3160
  }
3140
3161
  const a = Object.keys(s).length > 0;
3141
3162
  if (i) {
3142
- const p = { ...n || {} }, g = r.requestedMethod, y = r.effectiveMethod, b = r.transportMode === "query-get", l = r.queryString;
3163
+ const p = { ...n || {} }, g = r.requestedMethod, v = r.effectiveMethod, b = r.transportMode === "query-get", l = r.queryString;
3143
3164
  if (b && m.info("Haori demo fetch normalization", {
3144
- runtime: c.runtime,
3165
+ runtime: u.runtime,
3145
3166
  requestedMethod: g,
3146
- effectiveMethod: y,
3167
+ effectiveMethod: v,
3147
3168
  transportMode: "query-get",
3148
3169
  url: i,
3149
3170
  payload: a ? s : void 0,
3150
3171
  queryString: l
3151
3172
  }), this.options.targetFragment && i) {
3152
- const h = performance.now(), A = {
3153
- runtime: c.runtime,
3173
+ const f = performance.now(), A = {
3174
+ runtime: u.runtime,
3154
3175
  requestedMethod: g,
3155
- effectiveMethod: y,
3176
+ effectiveMethod: v,
3156
3177
  transportMode: b ? "query-get" : "http",
3157
3178
  ...b ? { queryString: l } : {}
3158
3179
  };
@@ -3165,7 +3186,7 @@ ${h}
3165
3186
  ), fetch(i, p).then((F) => this.handleFetchResult(
3166
3187
  F,
3167
3188
  i || void 0,
3168
- h
3189
+ f
3169
3190
  )).catch((F) => {
3170
3191
  throw i && S.fetchError(
3171
3192
  this.options.targetFragment.getTarget(),
@@ -3174,21 +3195,21 @@ ${h}
3174
3195
  ), F;
3175
3196
  });
3176
3197
  }
3177
- return fetch(i, p).then((h) => this.handleFetchResult(h, i || void 0));
3198
+ return fetch(i, p).then((f) => this.handleFetchResult(f, i || void 0));
3178
3199
  }
3179
3200
  if ((!this.options.bindFragments || this.options.bindFragments.length === 0) && this.options.formFragment && a) {
3180
- const p = this.options.formFragment, g = p.getTarget(), y = /* @__PURE__ */ new Set();
3181
- t && t.appliedDisabledAttribute && this.options.targetFragment && y.add(this.options.targetFragment), g.setAttribute(
3182
- `${c.prefix}bind`,
3201
+ const p = this.options.formFragment, g = p.getTarget(), v = /* @__PURE__ */ new Set();
3202
+ t && t.appliedDisabledAttribute && this.options.targetFragment && v.add(this.options.targetFragment), g.setAttribute(
3203
+ `${u.prefix}bind`,
3183
3204
  JSON.stringify(s)
3184
3205
  );
3185
3206
  const b = p.getBindingData();
3186
- Object.assign(b, s), await P.setBindingData(g, b, y);
3207
+ Object.assign(b, s), await D.setBindingData(g, b, v);
3187
3208
  }
3188
- const o = a ? s : {}, f = new Response(JSON.stringify(o), {
3209
+ const o = a ? s : {}, d = new Response(JSON.stringify(o), {
3189
3210
  headers: { "Content-Type": "application/json" }
3190
3211
  });
3191
- return this.handleFetchResult(f);
3212
+ return this.handleFetchResult(d);
3192
3213
  } finally {
3193
3214
  this.releaseExecutionLock(t);
3194
3215
  }
@@ -3202,7 +3223,7 @@ ${h}
3202
3223
  if (this.eventType !== "click" || !this.options.targetFragment)
3203
3224
  return null;
3204
3225
  const e = this.options.targetFragment.getTarget();
3205
- return u.RUNNING_CLICK_TARGETS.has(e) || e.matches(":disabled") || e.hasAttribute("disabled") || e.hasAttribute(z) ? !1 : (u.RUNNING_CLICK_TARGETS.add(e), e.setAttribute(z, ""), e.setAttribute("disabled", ""), {
3226
+ return c.RUNNING_CLICK_TARGETS.has(e) || e.matches(":disabled") || e.hasAttribute("disabled") || e.hasAttribute(Q) ? !1 : (c.RUNNING_CLICK_TARGETS.add(e), e.setAttribute(Q, ""), e.setAttribute("disabled", ""), {
3206
3227
  target: e,
3207
3228
  appliedDisabledAttribute: !0
3208
3229
  });
@@ -3214,13 +3235,13 @@ ${h}
3214
3235
  * @returns 戻り値はありません。
3215
3236
  */
3216
3237
  releaseExecutionLock(t) {
3217
- t && (u.RUNNING_CLICK_TARGETS.delete(t.target), t.appliedDisabledAttribute && (t.target.removeAttribute("disabled"), t.target.removeAttribute(z)));
3238
+ t && (c.RUNNING_CLICK_TARGETS.delete(t.target), t.appliedDisabledAttribute && (t.target.removeAttribute("disabled"), t.target.removeAttribute(Q)));
3218
3239
  }
3219
3240
  /**
3220
3241
  * フェッチ後の処理を実行します。
3221
3242
  */
3222
3243
  async handleFetchResult(t, e, r) {
3223
- const s = Q();
3244
+ const s = Z();
3224
3245
  if (!t.ok)
3225
3246
  return this.options.targetFragment && e && S.fetchError(
3226
3247
  this.options.targetFragment.getTarget(),
@@ -3244,11 +3265,11 @@ ${h}
3244
3265
  }
3245
3266
  const i = [];
3246
3267
  i.push(this.bindResult(t)), i.push(this.adjust()), i.push(this.addRow()), i.push(this.removeRow()), i.push(this.movePrevRow()), i.push(this.moveNextRow()), await Promise.all(i), this.options.resetFragments && this.options.resetFragments.length > 0 && await Promise.all(
3247
- this.options.resetFragments.map((a) => v.reset(a))
3268
+ this.options.resetFragments.map((a) => y.reset(a))
3248
3269
  ), await this.copy();
3249
3270
  const n = [];
3250
3271
  return this.options.refetchFragments && this.options.refetchFragments.length > 0 && this.options.refetchFragments.forEach((a) => {
3251
- n.push(new u(a, null).run());
3272
+ n.push(new c(a, null).run());
3252
3273
  }), this.options.clickFragments && this.options.clickFragments.length > 0 && this.options.clickFragments.forEach((a) => {
3253
3274
  const o = a.getTarget();
3254
3275
  typeof o.click == "function" ? o.click() : o.dispatchEvent(
@@ -3278,19 +3299,19 @@ ${h}
3278
3299
  try {
3279
3300
  const n = t ? this.options.historyUrl : window.location.pathname, a = new URL(n, window.location.href);
3280
3301
  if (a.origin !== window.location.origin) {
3281
- const f = "history.pushState: cross-origin URL is not allowed: " + a.toString();
3302
+ const d = "history.pushState: cross-origin URL is not allowed: " + a.toString();
3282
3303
  m.error(
3283
3304
  "Haori",
3284
- f
3305
+ d
3285
3306
  );
3286
3307
  return;
3287
3308
  }
3288
- const o = (f) => {
3289
- for (const [p, g] of Object.entries(f))
3290
- g != null && (Array.isArray(g) ? g.forEach((y) => a.searchParams.append(p, String(y))) : typeof g == "object" ? a.searchParams.set(p, JSON.stringify(g)) : a.searchParams.set(p, String(g)));
3309
+ const o = (d) => {
3310
+ for (const [p, g] of Object.entries(d))
3311
+ g != null && (Array.isArray(g) ? g.forEach((v) => a.searchParams.append(p, String(v))) : typeof g == "object" ? a.searchParams.set(p, JSON.stringify(g)) : a.searchParams.set(p, String(g)));
3291
3312
  };
3292
3313
  s && o(e), i && o(r), history.pushState(
3293
- { [ut]: !0 },
3314
+ { [ct]: !0 },
3294
3315
  "",
3295
3316
  a.toString()
3296
3317
  );
@@ -3303,10 +3324,10 @@ ${h}
3303
3324
  */
3304
3325
  async handleFetchError(t) {
3305
3326
  let e = null;
3306
- this.options.formFragment ? e = this.options.formFragment : this.options.targetFragment && (e = v.getFormFragment(this.options.targetFragment) || this.options.targetFragment);
3327
+ this.options.formFragment ? e = this.options.formFragment : this.options.targetFragment && (e = y.getFormFragment(this.options.targetFragment) || this.options.targetFragment);
3307
3328
  const r = async (n) => {
3308
3329
  const a = e ? e.getTarget() : document.body;
3309
- await Q().addErrorMessage(a, n);
3330
+ await Z().addErrorMessage(a, n);
3310
3331
  }, s = () => {
3311
3332
  if (!this.options.scrollOnError)
3312
3333
  return;
@@ -3321,18 +3342,18 @@ ${h}
3321
3342
  for (const o of n.messages)
3322
3343
  typeof o == "string" && a.push({ message: o });
3323
3344
  if (n.errors && typeof n.errors == "object")
3324
- for (const [o, f] of Object.entries(n.errors))
3325
- Array.isArray(f) ? a.push({ key: o, message: f.join(`
3326
- `) }) : typeof f == "string" ? a.push({ key: o, message: f }) : f != null && a.push({ key: o, message: String(f) });
3345
+ for (const [o, d] of Object.entries(n.errors))
3346
+ Array.isArray(d) ? a.push({ key: o, message: d.join(`
3347
+ `) }) : typeof d == "string" ? a.push({ key: o, message: d }) : d != null && a.push({ key: o, message: String(d) });
3327
3348
  if (a.length === 0)
3328
- for (const [o, f] of Object.entries(n))
3329
- o === "message" || o === "messages" || o === "errors" || (Array.isArray(f) ? a.push({ key: o, message: f.join(`
3330
- `) }) : typeof f == "string" && a.push({ key: o, message: f }));
3349
+ for (const [o, d] of Object.entries(n))
3350
+ o === "message" || o === "messages" || o === "errors" || (Array.isArray(d) ? a.push({ key: o, message: d.join(`
3351
+ `) }) : typeof d == "string" && a.push({ key: o, message: d }));
3331
3352
  }
3332
3353
  if (a.length === 0)
3333
3354
  return await r(`${t.status} ${t.statusText}`), s(), !1;
3334
3355
  for (const o of a)
3335
- o.key && e ? await v.addErrorMessage(e, o.key, o.message) : await r(o.message);
3356
+ o.key && e ? await y.addErrorMessage(e, o.key, o.message) : await r(o.message);
3336
3357
  return s(), !1;
3337
3358
  } catch {
3338
3359
  }
@@ -3391,7 +3412,7 @@ ${h}
3391
3412
  */
3392
3413
  confirm() {
3393
3414
  const t = this.options.confirmMessage;
3394
- return t == null ? Promise.resolve(!0) : Q().confirm(t);
3415
+ return t == null ? Promise.resolve(!0) : Z().confirm(t);
3395
3416
  }
3396
3417
  /**
3397
3418
  * 結果データを対象のフラグメントにバインドします。
@@ -3411,15 +3432,15 @@ ${h}
3411
3432
  this.options.bindFragments.forEach((i) => {
3412
3433
  const n = i.getBindingData(), a = this.options.bindArg;
3413
3434
  if (r && typeof r == "object" && !Array.isArray(r)) {
3414
- const o = n[a], f = o && typeof o == "object" && !Array.isArray(o) ? o : {};
3435
+ const o = n[a], d = o && typeof o == "object" && !Array.isArray(o) ? o : {};
3415
3436
  n[a] = this.mergeAppendBindingData(
3416
3437
  i,
3417
3438
  r,
3418
- f
3439
+ d
3419
3440
  );
3420
3441
  } else
3421
3442
  n[a] = r;
3422
- s.push(P.setBindingData(i.getTarget(), n));
3443
+ s.push(D.setBindingData(i.getTarget(), n));
3423
3444
  });
3424
3445
  else {
3425
3446
  if (typeof r == "string")
@@ -3432,7 +3453,7 @@ ${h}
3432
3453
  r
3433
3454
  );
3434
3455
  s.push(
3435
- P.setBindingData(
3456
+ D.setBindingData(
3436
3457
  i.getTarget(),
3437
3458
  n
3438
3459
  )
@@ -3467,7 +3488,7 @@ ${h}
3467
3488
  ...s.getBindingData(),
3468
3489
  ...e
3469
3490
  };
3470
- return P.setBindingData(s.getTarget(), i);
3491
+ return D.setBindingData(s.getTarget(), i);
3471
3492
  });
3472
3493
  return Promise.all(r).then(() => {
3473
3494
  });
@@ -3476,7 +3497,7 @@ ${h}
3476
3497
  * copy のコピー元データを取得します。
3477
3498
  */
3478
3499
  resolveCopySourceData() {
3479
- return this.options.formFragment ? v.getValues(this.options.formFragment) : this.options.targetFragment ? { ...this.options.targetFragment.getBindingData() } : {};
3500
+ return this.options.formFragment ? y.getValues(this.options.formFragment) : this.options.targetFragment ? { ...this.options.targetFragment.getBindingData() } : {};
3480
3501
  }
3481
3502
  /**
3482
3503
  * data 属性とフォーム値を統合した送信データを作成します。
@@ -3494,8 +3515,8 @@ ${h}
3494
3515
  buildPayloadResolution() {
3495
3516
  const t = {};
3496
3517
  let e = !1;
3497
- if (this.options.formFragment && Object.assign(t, v.getValues(this.options.formFragment)), this.options.data && typeof this.options.data == "object" && Object.assign(t, this.options.data), this.options.targetFragment && this.options.dataAttrName) {
3498
- const r = u.resolveDataAttributeDetailed(
3518
+ if (this.options.formFragment && Object.assign(t, y.getValues(this.options.formFragment)), this.options.data && typeof this.options.data == "object" && Object.assign(t, this.options.data), this.options.targetFragment && this.options.dataAttrName) {
3519
+ const r = c.resolveDataAttributeDetailed(
3499
3520
  this.options.targetFragment,
3500
3521
  this.options.dataAttrName
3501
3522
  );
@@ -3536,22 +3557,22 @@ ${h}
3536
3557
  let s = this.options.fetchUrl;
3537
3558
  const i = { ...this.options.fetchOptions || {} }, n = new Headers(
3538
3559
  i.headers || void 0
3539
- ), a = (i.method || "GET").toUpperCase(), o = c.runtime === "demo" && !ht(a), f = o ? "GET" : a;
3540
- if (i.method = f, f === "GET" || f === "HEAD" || f === "OPTIONS")
3541
- Object.keys(e).length > 0 && (s = dt(s, e));
3560
+ ), a = (i.method || "GET").toUpperCase(), o = u.runtime === "demo" && !ft(a), d = o ? "GET" : a;
3561
+ if (i.method = d, d === "GET" || d === "HEAD" || d === "OPTIONS")
3562
+ Object.keys(e).length > 0 && (s = pt(s, e));
3542
3563
  else if (Object.keys(e).length > 0) {
3543
3564
  const g = n.get("Content-Type") || "";
3544
3565
  if (/multipart\/form-data/i.test(g)) {
3545
3566
  n.delete("Content-Type");
3546
- const y = new FormData();
3567
+ const v = new FormData();
3547
3568
  for (const [b, l] of Object.entries(e))
3548
- l == null ? y.append(b, "") : l instanceof Blob ? y.append(b, l) : Array.isArray(l) ? l.forEach((h) => y.append(b, String(h))) : typeof l == "object" ? y.append(b, JSON.stringify(l)) : y.append(b, String(l));
3549
- i.body = y;
3569
+ l == null ? v.append(b, "") : l instanceof Blob ? v.append(b, l) : Array.isArray(l) ? l.forEach((f) => v.append(b, String(f))) : typeof l == "object" ? v.append(b, JSON.stringify(l)) : v.append(b, String(l));
3570
+ i.body = v;
3550
3571
  } else if (/application\/x-www-form-urlencoded/i.test(g)) {
3551
- const y = new URLSearchParams();
3572
+ const v = new URLSearchParams();
3552
3573
  for (const [b, l] of Object.entries(e))
3553
- l !== void 0 && (l === null ? y.append(b, "") : Array.isArray(l) ? l.forEach((h) => y.append(b, String(h))) : typeof l == "object" ? y.append(b, JSON.stringify(l)) : y.append(b, String(l)));
3554
- i.body = y;
3574
+ l !== void 0 && (l === null ? v.append(b, "") : Array.isArray(l) ? l.forEach((f) => v.append(b, String(f))) : typeof l == "object" ? v.append(b, JSON.stringify(l)) : v.append(b, String(l)));
3575
+ i.body = v;
3555
3576
  } else
3556
3577
  n.set("Content-Type", "application/json"), i.body = JSON.stringify(e);
3557
3578
  }
@@ -3563,20 +3584,20 @@ ${h}
3563
3584
  payload: e,
3564
3585
  hasUnresolvedReference: !1,
3565
3586
  requestedMethod: a,
3566
- effectiveMethod: f,
3587
+ effectiveMethod: d,
3567
3588
  queryString: p,
3568
3589
  transportMode: o ? "query-get" : "http",
3569
- signature: gt(s, i)
3590
+ signature: mt(s, i)
3570
3591
  };
3571
3592
  }
3572
3593
  /**
3573
3594
  * reset-before 後の history 用スナップショットを保存します。
3574
3595
  */
3575
3596
  captureHistorySnapshots() {
3576
- this.options.targetFragment && this.options.historyDataAttrName ? this.historyDataSnapshot = u.resolveDataAttribute(
3597
+ this.options.targetFragment && this.options.historyDataAttrName ? this.historyDataSnapshot = c.resolveDataAttribute(
3577
3598
  this.options.targetFragment,
3578
3599
  this.options.historyDataAttrName
3579
- ) : this.historyDataSnapshot = void 0, this.historyFormSnapshot = this.options.historyFormFragment ? v.getValues(this.options.historyFormFragment) : void 0;
3600
+ ) : this.historyDataSnapshot = void 0, this.historyFormSnapshot = this.options.historyFormFragment ? y.getValues(this.options.historyFormFragment) : void 0;
3580
3601
  }
3581
3602
  /**
3582
3603
  * history-data の評価値を取得します。
@@ -3584,7 +3605,7 @@ ${h}
3584
3605
  * @returns history-data の評価値。
3585
3606
  */
3586
3607
  resolveHistoryDataValues() {
3587
- return this.historyDataSnapshot !== void 0 ? this.historyDataSnapshot : this.options.targetFragment && this.options.historyDataAttrName ? u.resolveDataAttribute(
3608
+ return this.historyDataSnapshot !== void 0 ? this.historyDataSnapshot : this.options.targetFragment && this.options.historyDataAttrName ? c.resolveDataAttribute(
3588
3609
  this.options.targetFragment,
3589
3610
  this.options.historyDataAttrName
3590
3611
  ) : this.options.historyData;
@@ -3598,7 +3619,7 @@ ${h}
3598
3619
  if (this.historyFormSnapshot !== void 0)
3599
3620
  return this.historyFormSnapshot;
3600
3621
  if (this.options.historyFormFragment)
3601
- return v.getValues(this.options.historyFormFragment);
3622
+ return y.getValues(this.options.historyFormFragment);
3602
3623
  }
3603
3624
  /**
3604
3625
  * copy-params が指定されている場合は include / exclude を考慮して抽出します。
@@ -3648,7 +3669,7 @@ ${h}
3648
3669
  if (!this.options.targetFragment)
3649
3670
  return m.error("Haori", "Target fragment is not specified for row operation."), null;
3650
3671
  const t = this.options.targetFragment.closestByAttribute(
3651
- `${c.prefix}row`
3672
+ `${u.prefix}row`
3652
3673
  );
3653
3674
  return t || (m.error("Haori", "Row fragment not found."), null);
3654
3675
  }
@@ -3666,7 +3687,7 @@ ${h}
3666
3687
  const e = [], r = t.clone();
3667
3688
  return e.push(
3668
3689
  t.getParent().insertAfter(r, t)
3669
- ), e.push(P.evaluateAll(r)), e.push(v.reset(r)), Promise.all(e).then(() => {
3690
+ ), e.push(D.evaluateAll(r)), e.push(y.reset(r)), Promise.all(e).then(() => {
3670
3691
  });
3671
3692
  }
3672
3693
  /**
@@ -3681,7 +3702,7 @@ ${h}
3681
3702
  if (!t)
3682
3703
  return Promise.reject(new Error("Row fragment not found."));
3683
3704
  const e = t.getParent();
3684
- return e && e.getChildElementFragments().filter((s) => !s.hasAttribute(`${c.prefix}each-before`) && !s.hasAttribute(`${c.prefix}each-after`)).length <= 1 ? Promise.resolve() : t.remove();
3705
+ return e && e.getChildElementFragments().filter((s) => !s.hasAttribute(`${u.prefix}each-before`) && !s.hasAttribute(`${u.prefix}each-after`)).length <= 1 ? Promise.resolve() : t.remove();
3685
3706
  }
3686
3707
  /**
3687
3708
  * 前の行へ移動します。
@@ -3718,9 +3739,9 @@ ${h}
3718
3739
  return r ? r.insertAfter(t, e) : Promise.resolve();
3719
3740
  }
3720
3741
  };
3721
- u.DATA_PLACEHOLDER_REGEX = /\{\{\{([\s\S]+?)\}\}\}|\{\{([\s\S]+?)\}\}/g, u.SINGLE_PLACEHOLDER_REGEX = /^(\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\})$/, u.RUNNING_CLICK_TARGETS = /* @__PURE__ */ new WeakSet();
3722
- let $ = u;
3723
- class mt {
3742
+ c.DATA_PLACEHOLDER_REGEX = /\{\{\{([\s\S]+?)\}\}\}|\{\{([\s\S]+?)\}\}/g, c.SINGLE_PLACEHOLDER_REGEX = /^(\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\})$/, c.RUNNING_CLICK_TARGETS = /* @__PURE__ */ new WeakSet();
3743
+ let j = c;
3744
+ class bt {
3724
3745
  /**
3725
3746
  * URLのクエリパラメータを取得します。
3726
3747
  *
@@ -3733,7 +3754,7 @@ class mt {
3733
3754
  }), t;
3734
3755
  }
3735
3756
  }
3736
- class bt {
3757
+ class vt {
3737
3758
  /**
3738
3759
  * 指定URLから HTML を取得し、body 内の HTML 文字列を返します。
3739
3760
  *
@@ -3771,7 +3792,7 @@ class bt {
3771
3792
  }
3772
3793
  }
3773
3794
  }
3774
- const d = class d {
3795
+ const h = class h {
3775
3796
  /**
3776
3797
  * 遅延属性かどうか(完全名で判定)を判定します。
3777
3798
  *
@@ -3779,8 +3800,8 @@ const d = class d {
3779
3800
  * @returns 遅延属性かどうか
3780
3801
  */
3781
3802
  static isDeferredAttributeName(t) {
3782
- return d.DEFERRED_ATTRIBUTE_SUFFIXES.some(
3783
- (e) => t === `${c.prefix}${e}`
3803
+ return h.DEFERRED_ATTRIBUTE_SUFFIXES.some(
3804
+ (e) => t === `${u.prefix}${e}`
3784
3805
  );
3785
3806
  }
3786
3807
  /**
@@ -3790,8 +3811,8 @@ const d = class d {
3790
3811
  * @returns 除外対象かどうか
3791
3812
  */
3792
3813
  static isEvaluateAllExcludedAttributeName(t) {
3793
- return d.EVALUATE_ALL_EXCLUDED_ATTRIBUTE_SUFFIXES.some(
3794
- (e) => t === `${c.prefix}${e}`
3814
+ return h.EVALUATE_ALL_EXCLUDED_ATTRIBUTE_SUFFIXES.some(
3815
+ (e) => t === `${u.prefix}${e}`
3795
3816
  );
3796
3817
  }
3797
3818
  /**
@@ -3802,7 +3823,7 @@ const d = class d {
3802
3823
  * @returns 再評価する場合は true
3803
3824
  */
3804
3825
  static shouldReevaluateAttribute(t, e) {
3805
- return e !== null && !d.isEvaluateAllExcludedAttributeName(t) && d.ATTRIBUTE_PLACEHOLDER_REGEX.test(e);
3826
+ return e !== null && !h.isEvaluateAllExcludedAttributeName(t) && h.ATTRIBUTE_PLACEHOLDER_REGEX.test(e);
3806
3827
  }
3807
3828
  /**
3808
3829
  * data-attr-* 形式の属性名から実際に更新する属性名を取得します。
@@ -3811,7 +3832,7 @@ const d = class d {
3811
3832
  * @returns 実際の属性名。data-attr-* でない場合は null
3812
3833
  */
3813
3834
  static getAliasedAttributeName(t) {
3814
- const e = `${c.prefix}${d.ATTRIBUTE_ALIAS_SUFFIX}`;
3835
+ const e = `${u.prefix}${h.ATTRIBUTE_ALIAS_SUFFIX}`;
3815
3836
  return !t.startsWith(e) || t.length <= e.length ? null : t.slice(e.length);
3816
3837
  }
3817
3838
  /**
@@ -3823,8 +3844,8 @@ const d = class d {
3823
3844
  */
3824
3845
  static isAliasedAttributeReflection(t, e) {
3825
3846
  const r = R.get(t);
3826
- return r instanceof D ? r.hasAttribute(
3827
- `${c.prefix}${d.ATTRIBUTE_ALIAS_SUFFIX}${e}`
3847
+ return r instanceof P ? r.hasAttribute(
3848
+ `${u.prefix}${h.ATTRIBUTE_ALIAS_SUFFIX}${e}`
3828
3849
  ) : !1;
3829
3850
  }
3830
3851
  /**
@@ -3838,13 +3859,26 @@ const d = class d {
3838
3859
  let e = Promise.resolve();
3839
3860
  for (const r of t.getAttributeNames()) {
3840
3861
  const s = t.getRawAttribute(r);
3841
- d.shouldReevaluateAttribute(r, s) && (e = e.then(
3842
- () => d.setAttribute(t.getTarget(), r, s)
3862
+ h.shouldReevaluateAttribute(r, s) && (e = e.then(
3863
+ () => h.setAttribute(t.getTarget(), r, s)
3843
3864
  ));
3844
3865
  }
3845
3866
  return e.then(() => {
3846
3867
  });
3847
3868
  }
3869
+ /**
3870
+ * 指定フラグメントの直下の子孫評価を再実行します。
3871
+ *
3872
+ * @param fragment 対象フラグメント
3873
+ * @returns 再評価完了の Promise
3874
+ */
3875
+ static reevaluateChildren(t) {
3876
+ const e = [];
3877
+ return t.getChildren().forEach((r) => {
3878
+ r instanceof P ? e.push(h.evaluateAll(r)) : r instanceof O && e.push(h.evaluateText(r));
3879
+ }), Promise.all(e).then(() => {
3880
+ });
3881
+ }
3848
3882
  /**
3849
3883
  * data-fetch の再評価状態を取得します。
3850
3884
  *
@@ -3852,7 +3886,7 @@ const d = class d {
3852
3886
  * @returns 再評価状態
3853
3887
  */
3854
3888
  static getReactiveFetchState(t) {
3855
- const e = d.REACTIVE_FETCH_STATES.get(t);
3889
+ const e = h.REACTIVE_FETCH_STATES.get(t);
3856
3890
  if (e)
3857
3891
  return e;
3858
3892
  const r = {
@@ -3860,7 +3894,7 @@ const d = class d {
3860
3894
  running: !1,
3861
3895
  rerunRequested: !1
3862
3896
  };
3863
- return d.REACTIVE_FETCH_STATES.set(t, r), r;
3897
+ return h.REACTIVE_FETCH_STATES.set(t, r), r;
3864
3898
  }
3865
3899
  /**
3866
3900
  * data-import の再評価状態を取得します。
@@ -3869,7 +3903,7 @@ const d = class d {
3869
3903
  * @returns 再評価状態
3870
3904
  */
3871
3905
  static getReactiveImportState(t) {
3872
- const e = d.REACTIVE_IMPORT_STATES.get(t);
3906
+ const e = h.REACTIVE_IMPORT_STATES.get(t);
3873
3907
  if (e)
3874
3908
  return e;
3875
3909
  const r = {
@@ -3877,7 +3911,7 @@ const d = class d {
3877
3911
  running: !1,
3878
3912
  rerunRequested: !1
3879
3913
  };
3880
- return d.REACTIVE_IMPORT_STATES.set(t, r), r;
3914
+ return h.REACTIVE_IMPORT_STATES.set(t, r), r;
3881
3915
  }
3882
3916
  /**
3883
3917
  * bind 更新時に data-fetch / data-import を専用ルートで再評価します。
@@ -3890,9 +3924,9 @@ const d = class d {
3890
3924
  if (e.has(t))
3891
3925
  return Promise.resolve();
3892
3926
  const r = [];
3893
- return t.hasAttribute(`${c.prefix}fetch`) && r.push(d.executeManagedFetch(t)), t.hasAttribute(`${c.prefix}import`) && r.push(d.executeManagedImport(t)), t.getChildren().forEach((s) => {
3894
- s instanceof D && r.push(
3895
- d.reevaluateReactiveSpecialAttributes(s, e)
3927
+ return t.hasAttribute(`${u.prefix}fetch`) && r.push(h.executeManagedFetch(t)), t.hasAttribute(`${u.prefix}import`) && r.push(h.executeManagedImport(t)), t.getChildren().forEach((s) => {
3928
+ s instanceof P && r.push(
3929
+ h.reevaluateReactiveSpecialAttributes(s, e)
3896
3930
  );
3897
3931
  }), Promise.all(r).then(() => {
3898
3932
  });
@@ -3904,11 +3938,11 @@ const d = class d {
3904
3938
  * @returns 実行完了の Promise
3905
3939
  */
3906
3940
  static executeManagedFetch(t) {
3907
- const e = t.getTarget(), r = d.getReactiveFetchState(e), s = $.resolveAutoFetchSignature(t);
3908
- return r.running ? ((s.hasUnresolvedReference || s.signature !== r.lastSignature) && (r.rerunRequested = !0), Promise.resolve()) : s.hasUnresolvedReference || s.signature === null ? (r.lastSignature = null, Promise.resolve()) : r.lastSignature === s.signature ? Promise.resolve() : (r.lastSignature = s.signature, r.running = !0, new $(t, null).runWithResult().then(() => {
3941
+ const e = t.getTarget(), r = h.getReactiveFetchState(e), s = j.resolveAutoFetchSignature(t);
3942
+ return r.running ? ((s.hasUnresolvedReference || s.signature !== r.lastSignature) && (r.rerunRequested = !0), Promise.resolve()) : s.hasUnresolvedReference || s.signature === null ? (r.lastSignature = null, Promise.resolve()) : r.lastSignature === s.signature ? Promise.resolve() : (r.lastSignature = s.signature, r.running = !0, new j(t, null).runWithResult().then(() => {
3909
3943
  }).finally(() => {
3910
3944
  if (r.running = !1, r.rerunRequested)
3911
- return r.rerunRequested = !1, d.executeManagedFetch(t);
3945
+ return r.rerunRequested = !1, h.executeManagedFetch(t);
3912
3946
  }));
3913
3947
  }
3914
3948
  /**
@@ -3918,8 +3952,8 @@ const d = class d {
3918
3952
  * @returns 実行完了の Promise
3919
3953
  */
3920
3954
  static executeManagedImport(t) {
3921
- const e = t.getTarget(), r = d.getReactiveImportState(e), s = t.getAttributeEvaluation(
3922
- `${c.prefix}import`
3955
+ const e = t.getTarget(), r = h.getReactiveImportState(e), s = t.getAttributeEvaluation(
3956
+ `${u.prefix}import`
3923
3957
  ), i = s && !s.hasUnresolvedReference && typeof s.value == "string" && s.value !== "" ? s.value : null;
3924
3958
  if (r.running)
3925
3959
  return i !== r.lastUrl && (r.rerunRequested = !0), Promise.resolve();
@@ -3929,25 +3963,25 @@ const d = class d {
3929
3963
  return Promise.resolve();
3930
3964
  r.lastUrl = i, r.running = !0;
3931
3965
  const n = performance.now();
3932
- return e.setAttribute(`${c.prefix}importing`, ""), S.importStart(e, i), bt.load(i).then((a) => {
3966
+ return e.setAttribute(`${u.prefix}importing`, ""), S.importStart(e, i), vt.load(i).then((a) => {
3933
3967
  const o = new TextEncoder().encode(a).length;
3934
3968
  return N.enqueue(() => {
3935
3969
  e.innerHTML = a;
3936
3970
  }).then(() => {
3937
- if (e.removeAttribute(`${c.prefix}importing`), S.importEnd(e, i, o, n), !document.body.hasAttribute("data-haori-ready")) {
3938
- const f = [];
3971
+ if (e.removeAttribute(`${u.prefix}importing`), S.importEnd(e, i, o, n), !document.body.hasAttribute("data-haori-ready")) {
3972
+ const d = [];
3939
3973
  return e.childNodes.forEach((p) => {
3940
3974
  const g = R.get(p);
3941
- g instanceof D ? f.push(d.scan(g.getTarget())) : g instanceof I && f.push(d.evaluateText(g));
3942
- }), Promise.all(f).then(() => {
3975
+ g instanceof P ? d.push(h.scan(g.getTarget())) : g instanceof O && d.push(h.evaluateText(g));
3976
+ }), Promise.all(d).then(() => {
3943
3977
  });
3944
3978
  }
3945
3979
  });
3946
3980
  }).catch((a) => {
3947
- e.removeAttribute(`${c.prefix}importing`), S.importError(e, i, a), m.error("[Haori]", "Failed to import HTML:", i, a);
3981
+ e.removeAttribute(`${u.prefix}importing`), S.importError(e, i, a), m.error("[Haori]", "Failed to import HTML:", i, a);
3948
3982
  }).finally(() => {
3949
3983
  if (r.running = !1, r.rerunRequested)
3950
- return r.rerunRequested = !1, d.executeManagedImport(t);
3984
+ return r.rerunRequested = !1, h.executeManagedImport(t);
3951
3985
  });
3952
3986
  }
3953
3987
  /**
@@ -3963,10 +3997,10 @@ const d = class d {
3963
3997
  t.parentNode && (R.get(t.parentNode)?.isMounted() || document.body.contains(t) ? e.setMounted(!0) : e.setMounted(!1));
3964
3998
  let r = Promise.resolve();
3965
3999
  const s = /* @__PURE__ */ new Set();
3966
- for (const i of d.PRIORITY_ATTRIBUTE_SUFFIXES) {
3967
- const n = c.prefix + i;
4000
+ for (const i of h.PRIORITY_ATTRIBUTE_SUFFIXES) {
4001
+ const n = u.prefix + i;
3968
4002
  e.hasAttribute(n) && (r = r.then(
3969
- () => d.setAttribute(
4003
+ () => h.setAttribute(
3970
4004
  e.getTarget(),
3971
4005
  n,
3972
4006
  e.getRawAttribute(n)
@@ -3974,17 +4008,17 @@ const d = class d {
3974
4008
  ), s.add(n));
3975
4009
  }
3976
4010
  for (const i of e.getAttributeNames()) {
3977
- if (s.has(i) || d.isDeferredAttributeName(i))
4011
+ if (s.has(i) || h.isDeferredAttributeName(i))
3978
4012
  continue;
3979
4013
  const n = e.getRawAttribute(i);
3980
4014
  n !== null && (r = r.then(
3981
- () => d.setAttribute(e.getTarget(), i, n)
4015
+ () => h.setAttribute(e.getTarget(), i, n)
3982
4016
  ));
3983
4017
  }
3984
- for (const i of d.DEFERRED_ATTRIBUTE_SUFFIXES) {
3985
- const n = c.prefix + i;
4018
+ for (const i of h.DEFERRED_ATTRIBUTE_SUFFIXES) {
4019
+ const n = u.prefix + i;
3986
4020
  e.hasAttribute(n) && (r = r.then(
3987
- () => d.setAttribute(
4021
+ () => h.setAttribute(
3988
4022
  e.getTarget(),
3989
4023
  n,
3990
4024
  e.getRawAttribute(n)
@@ -3992,10 +4026,13 @@ const d = class d {
3992
4026
  ), s.add(n));
3993
4027
  }
3994
4028
  return r.then(() => {
3995
- const i = [];
3996
- return e.getChildren().forEach((n) => {
3997
- n instanceof D ? i.push(d.scan(n.getTarget())) : n instanceof I && i.push(d.evaluateText(n));
3998
- }), Promise.all(i).then(() => {
4029
+ const i = e.getAttribute(`${u.prefix}if`);
4030
+ if (e.hasAttribute(`${u.prefix}if`) && (i === !1 || i === void 0 || i === null || Number.isNaN(i)))
4031
+ return;
4032
+ const n = [];
4033
+ return e.getChildren().forEach((a) => {
4034
+ a instanceof P ? n.push(h.scan(a.getTarget())) : a instanceof O && n.push(h.evaluateText(a));
4035
+ }), Promise.all(n).then(() => {
3999
4036
  });
4000
4037
  }).then(() => {
4001
4038
  });
@@ -4010,7 +4047,7 @@ const d = class d {
4010
4047
  * @returns Promise (DOM操作が完了したときに解決される)
4011
4048
  */
4012
4049
  static setAttribute(t, e, r, s = !1) {
4013
- const i = R.get(t), n = d.getAliasedAttributeName(e);
4050
+ const i = R.get(t), n = h.getAliasedAttributeName(e);
4014
4051
  if (n !== null)
4015
4052
  return r === null ? i.removeAliasedAttribute(e, n) : i.setAliasedAttribute(
4016
4053
  e,
@@ -4020,34 +4057,55 @@ const d = class d {
4020
4057
  );
4021
4058
  const a = [];
4022
4059
  switch (e) {
4023
- case `${c.prefix}bind`: {
4024
- r === null ? (i.clearBindingDataCache(), i.setBindingData({})) : i.setBindingData(d.parseDataBind(r));
4060
+ case `${u.prefix}bind`: {
4061
+ r === null ? (i.clearBindingDataCache(), i.setBindingData({})) : i.setBindingData(h.parseDataBind(r));
4025
4062
  break;
4026
4063
  }
4027
- case `${c.prefix}if`:
4028
- a.push(d.evaluateIf(i));
4064
+ case `${u.prefix}derive`:
4065
+ a.push(
4066
+ h.evaluateDerive(
4067
+ i,
4068
+ r,
4069
+ i.getRawAttribute(`${u.prefix}derive-name`)
4070
+ )
4071
+ );
4072
+ break;
4073
+ case `${u.prefix}derive-name`:
4074
+ a.push(
4075
+ h.evaluateDerive(
4076
+ i,
4077
+ i.getRawAttribute(`${u.prefix}derive`),
4078
+ r
4079
+ )
4080
+ );
4029
4081
  break;
4030
- case `${c.prefix}each`:
4031
- a.push(d.evaluateEach(i));
4082
+ case `${u.prefix}if`:
4083
+ a.push(h.evaluateIf(i));
4032
4084
  break;
4033
- case `${c.prefix}fetch`:
4034
- a.push(d.executeManagedFetch(i));
4085
+ case `${u.prefix}each`:
4086
+ a.push(h.evaluateEach(i));
4035
4087
  break;
4036
- case `${c.prefix}import`:
4037
- typeof r == "string" && a.push(d.executeManagedImport(i));
4088
+ case `${u.prefix}fetch`:
4089
+ a.push(h.executeManagedFetch(i));
4038
4090
  break;
4039
- case `${c.prefix}url-param`: {
4040
- const o = i.getAttribute(`${c.prefix}url-arg`), f = mt.readParams();
4091
+ case `${u.prefix}import`:
4092
+ typeof r == "string" && a.push(h.executeManagedImport(i));
4093
+ break;
4094
+ case `${u.prefix}url-param`: {
4095
+ const o = i.getAttribute(`${u.prefix}url-arg`), d = bt.readParams();
4041
4096
  if (o === null)
4042
- a.push(d.setBindingData(t, f));
4097
+ a.push(h.setBindingData(t, d));
4043
4098
  else {
4044
4099
  const p = i.getRawBindingData() || {};
4045
- p[String(o)] = f, a.push(d.setBindingData(t, p));
4100
+ p[String(o)] = d, a.push(h.setBindingData(t, p));
4046
4101
  }
4047
4102
  break;
4048
4103
  }
4049
4104
  }
4050
4105
  return r === null ? a.push(i.removeAttribute(e)) : a.push(i.setAttribute(e, r, s)), Promise.all(a).then(() => {
4106
+ if (e === `${u.prefix}derive` || e === `${u.prefix}derive-name`)
4107
+ return h.reevaluateChildren(i);
4108
+ }).then(() => {
4051
4109
  });
4052
4110
  }
4053
4111
  /**
@@ -4062,15 +4120,15 @@ const d = class d {
4062
4120
  const s = R.get(t), i = s.getRawBindingData();
4063
4121
  s.setBindingData(e);
4064
4122
  let n = s.setAttribute(
4065
- `${c.prefix}bind`,
4123
+ `${u.prefix}bind`,
4066
4124
  JSON.stringify(e)
4067
4125
  );
4068
4126
  if (t.tagName === "FORM") {
4069
- const a = s.getAttribute(`${c.prefix}form-arg`), o = a && e[String(a)] && typeof e[String(a)] == "object" && !Array.isArray(e[String(a)]) ? e[String(a)] : a ? {} : e;
4070
- n = n.then(() => v.syncValues(s, o));
4127
+ const a = s.getAttribute(`${u.prefix}form-arg`), o = a && e[String(a)] && typeof e[String(a)] == "object" && !Array.isArray(e[String(a)]) ? e[String(a)] : a ? {} : e;
4128
+ n = n.then(() => y.syncValues(s, o));
4071
4129
  }
4072
- return n = n.then(() => d.evaluateAll(s, r)), n = n.then(
4073
- () => d.reevaluateReactiveSpecialAttributes(s, r)
4130
+ return n = n.then(() => h.evaluateAll(s, r)), n = n.then(
4131
+ () => h.reevaluateReactiveSpecialAttributes(s, r)
4074
4132
  ), S.bindChange(t, i, e, "manual"), n.then(() => {
4075
4133
  });
4076
4134
  }
@@ -4105,7 +4163,7 @@ const d = class d {
4105
4163
  if (r.isSkipMutationNodes())
4106
4164
  return;
4107
4165
  const s = R.get(e.nextSibling), i = R.get(e);
4108
- i && (r.insertBefore(i, s), i instanceof D ? d.scan(i.getTarget()) : i instanceof I && d.evaluateText(i));
4166
+ i && (r.insertBefore(i, s), i instanceof P ? h.scan(i.getTarget()) : i instanceof O && h.evaluateText(i));
4109
4167
  }
4110
4168
  /**
4111
4169
  * ノードを親要素から削除します。
@@ -4145,11 +4203,11 @@ const d = class d {
4145
4203
  return Promise.resolve();
4146
4204
  const s = [];
4147
4205
  s.push(r.setValue(e));
4148
- const i = d.getFormFragment(r);
4206
+ const i = h.getFormFragment(r);
4149
4207
  if (i) {
4150
- const n = v.getValues(i), a = i.getAttribute(`${c.prefix}form-arg`);
4208
+ const n = y.getValues(i), a = i.getAttribute(`${u.prefix}form-arg`);
4151
4209
  let o;
4152
- a ? (o = i.getRawBindingData(), o || (o = {}), o[String(a)] = n) : o = n, s.push(d.setBindingData(i.getTarget(), o));
4210
+ a ? (o = i.getRawBindingData(), o || (o = {}), o[String(a)] = n) : o = n, s.push(h.setBindingData(i.getTarget(), o));
4153
4211
  }
4154
4212
  return Promise.all(s).then(() => {
4155
4213
  });
@@ -4164,7 +4222,7 @@ const d = class d {
4164
4222
  if (t.getTarget() instanceof HTMLFormElement)
4165
4223
  return t;
4166
4224
  const e = t.getParent();
4167
- return e ? d.getFormFragment(e) : null;
4225
+ return e ? h.getFormFragment(e) : null;
4168
4226
  }
4169
4227
  /**
4170
4228
  * フラグメントとその子要素を評価します。
@@ -4175,11 +4233,42 @@ const d = class d {
4175
4233
  static evaluateAll(t, e = /* @__PURE__ */ new Set()) {
4176
4234
  if (e.has(t))
4177
4235
  return Promise.resolve();
4178
- const r = [];
4179
- return r.push(d.reevaluateInterpolatedAttributes(t)), t.hasAttribute(`${c.prefix}if`) && r.push(d.evaluateIf(t)), t.hasAttribute(`${c.prefix}each`) ? Promise.all(r).then(() => d.evaluateEach(t)) : (t.getChildren().forEach((s) => {
4180
- s instanceof D ? r.push(d.evaluateAll(s, e)) : s instanceof I && r.push(d.evaluateText(s));
4181
- }), Promise.all(r).then(() => {
4182
- }));
4236
+ let r = h.reevaluateInterpolatedAttributes(t);
4237
+ const s = t.hasAttribute(`${u.prefix}derive`), i = t.hasAttribute(`${u.prefix}if`), n = t.hasAttribute(`${u.prefix}each`);
4238
+ if (s && (r = r.then(() => h.evaluateDerive(t))), i && (r = r.then(() => h.evaluateIf(t))), n)
4239
+ return r.then(() => h.evaluateEach(t));
4240
+ if (i)
4241
+ return r.then(() => {
4242
+ });
4243
+ const a = [];
4244
+ return t.getChildren().forEach((o) => {
4245
+ o instanceof P ? a.push(h.evaluateAll(o, e)) : o instanceof O && a.push(h.evaluateText(o));
4246
+ }), r.then(() => Promise.all(a)).then(() => {
4247
+ });
4248
+ }
4249
+ /**
4250
+ * data-derive / data-derive-name を評価し、子孫要素向けの派生値を更新します。
4251
+ *
4252
+ * @param fragment 対象フラグメント
4253
+ * @param deriveExpression 上書きする導出式
4254
+ * @param deriveName 上書きする導出名
4255
+ * @returns Promise (評価完了時に解決)
4256
+ */
4257
+ static evaluateDerive(t, e = t.getRawAttribute(
4258
+ `${u.prefix}derive`
4259
+ ), r = t.getRawAttribute(
4260
+ `${u.prefix}derive-name`
4261
+ )) {
4262
+ const s = typeof r == "string" ? r.trim() : "";
4263
+ if (!e || s === "")
4264
+ return t.setDerivedBindingData(null), Promise.resolve();
4265
+ const i = U.evaluateDetailed(
4266
+ e,
4267
+ t.getBindingData()
4268
+ );
4269
+ return i.unresolvedReference ? (t.setDerivedBindingData(null), Promise.resolve()) : (t.setDerivedBindingData({
4270
+ [s]: i.value
4271
+ }), Promise.resolve());
4183
4272
  }
4184
4273
  /**
4185
4274
  * テキストフラグメントを評価します。
@@ -4198,7 +4287,7 @@ const d = class d {
4198
4287
  * @return Promise (DOM操作が完了したときに解決される)
4199
4288
  */
4200
4289
  static evaluateIf(t) {
4201
- const e = [], r = t.getAttribute(`${c.prefix}if`);
4290
+ const e = [], r = t.getAttribute(`${u.prefix}if`);
4202
4291
  if (r === !1 || r === void 0 || r === null || Number.isNaN(r))
4203
4292
  e.push(
4204
4293
  t.hide().then(() => {
@@ -4208,7 +4297,9 @@ const d = class d {
4208
4297
  else {
4209
4298
  const s = [];
4210
4299
  t.getChildren().forEach((i) => {
4211
- i instanceof D ? s.push(d.evaluateAll(i)) : i instanceof I && s.push(d.evaluateText(i));
4300
+ i instanceof P ? s.push(
4301
+ i.isMounted() ? h.evaluateAll(i) : h.scan(i.getTarget())
4302
+ ) : i instanceof O && s.push(h.evaluateText(i));
4212
4303
  }), e.push(
4213
4304
  t.show().then(() => {
4214
4305
  S.show(t.getTarget());
@@ -4228,15 +4319,15 @@ const d = class d {
4228
4319
  static evaluateEach(t) {
4229
4320
  if (!t.isVisible() || !t.isMounted())
4230
4321
  return Promise.resolve();
4231
- const e = d.resolveEachItems(t);
4322
+ const e = h.resolveEachItems(t);
4232
4323
  if (e === null)
4233
4324
  return Promise.reject(new Error("Invalid each attribute."));
4234
4325
  let r = t.getTemplate();
4235
4326
  if (r === null) {
4236
4327
  let s = !1;
4237
4328
  return t.getChildren().forEach((i) => {
4238
- if (!s && i instanceof D) {
4239
- if (i.hasAttribute(`${c.prefix}each-before`) || i.hasAttribute(`${c.prefix}each-after`))
4329
+ if (!s && i instanceof P) {
4330
+ if (i.hasAttribute(`${u.prefix}each-before`) || i.hasAttribute(`${u.prefix}each-after`))
4240
4331
  return;
4241
4332
  r = i.clone(), t.setTemplate(r), s = !0, t.removeChild(i);
4242
4333
  const n = i.getTarget();
@@ -4253,7 +4344,7 @@ const d = class d {
4253
4344
  * @returns 配列。無効な場合は null
4254
4345
  */
4255
4346
  static resolveEachItems(t) {
4256
- const e = t.getAttributeEvaluation(`${c.prefix}each`), r = e?.value;
4347
+ const e = t.getAttributeEvaluation(`${u.prefix}each`), r = e?.value;
4257
4348
  return e?.hasUnresolvedReference || r === !1 || r === null || r === void 0 ? [] : Array.isArray(r) ? r : (m.error("[Haori]", "Invalid each attribute:", r), null);
4258
4349
  }
4259
4350
  /**
@@ -4266,65 +4357,68 @@ const d = class d {
4266
4357
  const r = t.getTemplate();
4267
4358
  if (r === null)
4268
4359
  return m.error("[Haori]", "Template is not set for each element."), Promise.resolve();
4269
- let s = t.getAttribute(`${c.prefix}each-index`);
4360
+ let s = t.getAttribute(`${u.prefix}each-index`);
4270
4361
  s && (s = String(s));
4271
- const i = t.getAttribute(`${c.prefix}each-key`), n = t.getAttribute(`${c.prefix}each-arg`), a = /* @__PURE__ */ new Map(), o = [];
4272
- e.forEach((l, h) => {
4273
- const A = d.createListKey(
4362
+ const i = t.getAttribute(`${u.prefix}each-key`), n = t.getAttribute(`${u.prefix}each-arg`), a = /* @__PURE__ */ new Map(), o = [];
4363
+ e.forEach((l, f) => {
4364
+ const A = h.createListKey(
4274
4365
  l,
4275
4366
  i ? String(i) : null,
4276
- h
4367
+ f
4277
4368
  );
4278
- o.push(A), a.set(A, { item: l, itemIndex: h });
4369
+ o.push(A), a.set(A, { item: l, itemIndex: f });
4279
4370
  });
4280
- const f = [];
4281
- let p = t.getChildren().filter((l) => l instanceof D).filter(
4282
- (l) => !l.hasAttribute(`${c.prefix}each-before`) && !l.hasAttribute(`${c.prefix}each-after`)
4371
+ const d = [];
4372
+ let p = t.getChildren().filter((l) => l instanceof P).filter(
4373
+ (l) => !l.hasAttribute(`${u.prefix}each-before`) && !l.hasAttribute(`${u.prefix}each-after`)
4283
4374
  );
4284
- p = p.filter((l) => o.indexOf(String(l.getListKey())) === -1 ? (f.push(l.remove()), !1) : !0);
4285
- const g = p.map((l) => l.getListKey()), y = t.getChildren().filter((l) => l instanceof D).filter((l) => l.hasAttribute(`${c.prefix}each-before`)).length;
4375
+ p = p.filter((l) => o.indexOf(String(l.getListKey())) === -1 ? (d.push(l.remove()), !1) : !0);
4376
+ const g = p.map((l) => l.getListKey()), v = t.getChildren().filter((l) => l instanceof P).filter((l) => l.hasAttribute(`${u.prefix}each-before`)).length;
4286
4377
  let b = Promise.resolve();
4287
- return o.forEach((l, h) => {
4378
+ return o.forEach((l, f) => {
4288
4379
  const A = g.indexOf(l), { item: F, itemIndex: w } = a.get(l);
4289
- let O;
4380
+ let C;
4290
4381
  if (A !== -1)
4291
- O = p[A], b = b.then(
4292
- () => d.updateRowFragment(
4293
- O,
4382
+ C = p[A], b = b.then(
4383
+ () => h.updateRowFragment(
4384
+ C,
4294
4385
  F,
4295
4386
  s,
4296
4387
  w,
4297
4388
  n ? String(n) : null,
4298
4389
  l
4299
- ).then(() => d.evaluateAll(O)).then(() => d.scheduleEvaluateAll(O))
4390
+ ).then(() => h.evaluateAll(C)).then(() => h.scheduleEvaluateAll(C))
4300
4391
  );
4301
4392
  else {
4302
- O = r.clone();
4303
- const X = y + h;
4393
+ C = r.clone();
4394
+ const z = v + f;
4304
4395
  b = b.then(
4305
- () => d.updateRowFragment(
4306
- O,
4396
+ () => h.updateRowFragment(
4397
+ C,
4307
4398
  F,
4308
4399
  s,
4309
4400
  w,
4310
4401
  n ? String(n) : null,
4311
4402
  l
4312
- ).then(
4313
- () => t.insertBefore(
4314
- O,
4315
- t.getChildren()[X] || null
4316
- ).then(() => d.evaluateAll(O)).then(() => d.scheduleEvaluateAll(O))
4317
- )
4403
+ ).then(() => {
4404
+ const q = t.getChildren().filter(
4405
+ (nt) => nt instanceof P
4406
+ )[z] || null;
4407
+ return t.insertBefore(
4408
+ C,
4409
+ q
4410
+ ).then(() => h.evaluateAll(C)).then(() => h.scheduleEvaluateAll(C));
4411
+ })
4318
4412
  );
4319
4413
  }
4320
- }), Promise.all(f).then(() => b).then(() => {
4414
+ }), Promise.all(d).then(() => b).then(() => {
4321
4415
  const l = o.filter(
4322
4416
  (w) => w !== null
4323
- ), h = g.filter(
4417
+ ), f = g.filter(
4324
4418
  (w) => w !== null
4325
4419
  ), A = l.filter(
4326
- (w) => !h.includes(w)
4327
- ), F = h.filter(
4420
+ (w) => !f.includes(w)
4421
+ ), F = f.filter(
4328
4422
  (w) => !l.includes(w)
4329
4423
  );
4330
4424
  S.eachUpdate(
@@ -4379,9 +4473,9 @@ const d = class d {
4379
4473
  else
4380
4474
  return m.error(
4381
4475
  "[Haori]",
4382
- `Primitive value requires '${c.prefix}each-arg' attribute: ${e}`
4476
+ `Primitive value requires '${u.prefix}each-arg' attribute: ${e}`
4383
4477
  ), Promise.resolve();
4384
- return t.setListKey(n), t.setBindingData(a), t.setAttribute(`${c.prefix}row`, n);
4478
+ return t.setListKey(n), t.setBindingData(a), t.setAttribute(`${u.prefix}row`, n);
4385
4479
  }
4386
4480
  /**
4387
4481
  * フラグメントの再評価を次のイベントループで実行します。
@@ -4390,25 +4484,29 @@ const d = class d {
4390
4484
  */
4391
4485
  static scheduleEvaluateAll(t) {
4392
4486
  setTimeout(() => {
4393
- d.evaluateAll(t);
4487
+ h.evaluateAll(t);
4394
4488
  }, 100);
4395
4489
  }
4396
4490
  };
4397
- d.ATTRIBUTE_ALIAS_SUFFIX = "attr-", d.PRIORITY_ATTRIBUTE_SUFFIXES = [
4491
+ h.ATTRIBUTE_ALIAS_SUFFIX = "attr-", h.PRIORITY_ATTRIBUTE_SUFFIXES = [
4398
4492
  "bind",
4399
4493
  "url-param",
4494
+ "derive-name",
4495
+ "derive",
4400
4496
  "if",
4401
4497
  "each"
4402
- ], d.DEFERRED_ATTRIBUTE_SUFFIXES = ["fetch"], d.EVALUATE_ALL_EXCLUDED_ATTRIBUTE_SUFFIXES = [
4498
+ ], h.DEFERRED_ATTRIBUTE_SUFFIXES = ["fetch"], h.EVALUATE_ALL_EXCLUDED_ATTRIBUTE_SUFFIXES = [
4403
4499
  "bind",
4500
+ "derive",
4501
+ "derive-name",
4404
4502
  "if",
4405
4503
  "each",
4406
4504
  "fetch",
4407
4505
  "import",
4408
4506
  "url-param"
4409
- ], d.ATTRIBUTE_PLACEHOLDER_REGEX = /\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/, d.REACTIVE_FETCH_STATES = /* @__PURE__ */ new WeakMap(), d.REACTIVE_IMPORT_STATES = /* @__PURE__ */ new WeakMap();
4410
- let P = d;
4411
- const J = class J {
4507
+ ], h.ATTRIBUTE_PLACEHOLDER_REGEX = /\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/, h.REACTIVE_FETCH_STATES = /* @__PURE__ */ new WeakMap(), h.REACTIVE_IMPORT_STATES = /* @__PURE__ */ new WeakMap();
4508
+ let D = h;
4509
+ const Y = class Y {
4412
4510
  /**
4413
4511
  * コンストラクタ。
4414
4512
  *
@@ -4417,10 +4515,10 @@ const J = class J {
4417
4515
  constructor(t = document) {
4418
4516
  this.onClick = (e) => this.delegate(e, "click"), this.onChange = (e) => this.delegate(e, "change"), this.onLoadCapture = (e) => this.delegate(e, "load"), this.onWindowLoad = () => {
4419
4517
  const e = document.documentElement, r = R.get(e);
4420
- r && new $(r, "load").run();
4518
+ r && new j(r, "load").run();
4421
4519
  }, this.onPopstate = (e) => {
4422
4520
  const r = e.state;
4423
- !r || r[J.HISTORY_STATE_KEY] !== !0 || location.reload();
4521
+ !r || r[Y.HISTORY_STATE_KEY] !== !0 || location.reload();
4424
4522
  }, this.root = t;
4425
4523
  }
4426
4524
  /**
@@ -4447,7 +4545,7 @@ const J = class J {
4447
4545
  if (!r)
4448
4546
  return;
4449
4547
  const s = R.get(r);
4450
- s && (e === "change" && s instanceof D && s.syncValue(), new $(s, e).run().catch((i) => {
4548
+ s && (e === "change" && s instanceof P && s.syncValue(), new j(s, e).run().catch((i) => {
4451
4549
  m.error("[Haori]", "Procedure execution error:", i);
4452
4550
  }));
4453
4551
  }
@@ -4487,8 +4585,8 @@ const J = class J {
4487
4585
  return null;
4488
4586
  }
4489
4587
  };
4490
- J.HISTORY_STATE_KEY = "__haoriHistoryState__";
4491
- let _ = J;
4588
+ Y.HISTORY_STATE_KEY = "__haoriHistoryState__";
4589
+ let tt = Y;
4492
4590
  const T = class T {
4493
4591
  /**
4494
4592
  * ノードが現在の Window に属する HTMLElement かどうかを判定します。
@@ -4515,7 +4613,7 @@ const T = class T {
4515
4613
  }
4516
4614
  if (typeof IntersectionObserver > "u")
4517
4615
  return;
4518
- const s = T.resolveRoot(r), i = T.resolveRootMargin(r), n = T.resolveThreshold(r), a = r.hasAttribute(`${c.prefix}intersect-once`);
4616
+ const s = T.resolveRoot(r), i = T.resolveRootMargin(r), n = T.resolveThreshold(r), a = r.hasAttribute(`${u.prefix}intersect-once`);
4519
4617
  if (e && e.observer.root === s && e.observer.rootMargin === i && T.sameThreshold(
4520
4618
  e.observer.thresholds,
4521
4619
  n
@@ -4525,20 +4623,20 @@ const T = class T {
4525
4623
  }
4526
4624
  e && (e.observer.disconnect(), T.registrations.delete(t));
4527
4625
  const o = new IntersectionObserver(
4528
- (f) => {
4626
+ (d) => {
4529
4627
  const p = T.registrations.get(t);
4530
- p && f.forEach((g) => {
4531
- !g.isIntersecting || p.running || T.isDisabled(p.fragment) || (p.running = !0, new $(p.fragment, "intersect").runWithResult().then((y) => {
4532
- y && p.once && (p.observer.disconnect(), T.registrations.delete(t));
4533
- }).catch((y) => {
4628
+ p && d.forEach((g) => {
4629
+ !g.isIntersecting || p.running || T.isDisabled(p.fragment) || (p.running = !0, new j(p.fragment, "intersect").runWithResult().then((v) => {
4630
+ v && p.once && (p.observer.disconnect(), T.registrations.delete(t));
4631
+ }).catch((v) => {
4534
4632
  m.error(
4535
4633
  "[Haori]",
4536
4634
  "Intersect procedure execution error:",
4537
- y
4635
+ v
4538
4636
  );
4539
4637
  }).finally(() => {
4540
- const y = T.registrations.get(t);
4541
- y && (y.running = !1);
4638
+ const v = T.registrations.get(t);
4639
+ v && (v.running = !1);
4542
4640
  }));
4543
4641
  });
4544
4642
  },
@@ -4572,14 +4670,14 @@ const T = class T {
4572
4670
  }
4573
4671
  static shouldObserve(t) {
4574
4672
  return t.getAttributeNames().some((e) => {
4575
- if (!e.startsWith(`${c.prefix}intersect-`))
4673
+ if (!e.startsWith(`${u.prefix}intersect-`))
4576
4674
  return !1;
4577
- const r = e.slice(`${c.prefix}intersect-`.length);
4675
+ const r = e.slice(`${u.prefix}intersect-`.length);
4578
4676
  return !T.CONFIG_KEYS.has(r);
4579
4677
  });
4580
4678
  }
4581
4679
  static resolveRoot(t) {
4582
- const e = `${c.prefix}intersect-root`;
4680
+ const e = `${u.prefix}intersect-root`;
4583
4681
  if (!t.hasAttribute(e))
4584
4682
  return null;
4585
4683
  const r = t.getAttribute(e);
@@ -4589,15 +4687,15 @@ const T = class T {
4589
4687
  return T.isHtmlElement(s) ? s : (m.error("[Haori]", `Intersect root element not found: ${r}`), null);
4590
4688
  }
4591
4689
  static resolveRootMargin(t) {
4592
- const e = `${c.prefix}intersect-root-margin`, r = t.getAttribute(e);
4690
+ const e = `${u.prefix}intersect-root-margin`, r = t.getAttribute(e);
4593
4691
  return r === null || r === !1 || r === "" ? "0px" : String(r);
4594
4692
  }
4595
4693
  static resolveThreshold(t) {
4596
- const e = `${c.prefix}intersect-threshold`, r = t.getAttribute(e), s = typeof r == "number" ? r : Number.parseFloat(String(r ?? 0));
4694
+ const e = `${u.prefix}intersect-threshold`, r = t.getAttribute(e), s = typeof r == "number" ? r : Number.parseFloat(String(r ?? 0));
4597
4695
  return Number.isNaN(s) ? 0 : Math.min(1, Math.max(0, s));
4598
4696
  }
4599
4697
  static isDisabled(t) {
4600
- const e = `${c.prefix}intersect-disabled`, r = t.getAttribute(e);
4698
+ const e = `${u.prefix}intersect-disabled`, r = t.getAttribute(e);
4601
4699
  if (r === null || r === !1)
4602
4700
  return !1;
4603
4701
  if (typeof r == "boolean")
@@ -4616,7 +4714,7 @@ T.CONFIG_KEYS = /* @__PURE__ */ new Set([
4616
4714
  "disabled",
4617
4715
  "once"
4618
4716
  ]), T.registrations = /* @__PURE__ */ new Map();
4619
- let j = T;
4717
+ let V = T;
4620
4718
  const M = class M {
4621
4719
  /**
4622
4720
  * 既存の MutationObserver をすべて停止します。
@@ -4635,10 +4733,10 @@ const M = class M {
4635
4733
  return;
4636
4734
  M._initialized = !0, M.disconnectMutationObservers();
4637
4735
  const t = await Promise.allSettled([
4638
- P.scan(document.head),
4639
- P.scan(document.body)
4736
+ D.scan(document.head),
4737
+ D.scan(document.body)
4640
4738
  ]), [e, r] = t;
4641
- e.status !== "fulfilled" && m.error("[Haori]", "Failed to build head fragment:", e.reason), r.status !== "fulfilled" && m.error("[Haori]", "Failed to build body fragment:", r.reason), await N.wait(), document.body.setAttribute("data-haori-ready", ""), M.observe(document.head), M.observe(document.body), new _().start(), j.syncTree(document.body);
4739
+ e.status !== "fulfilled" && m.error("[Haori]", "Failed to build head fragment:", e.reason), r.status !== "fulfilled" && m.error("[Haori]", "Failed to build body fragment:", r.reason), await N.wait(), document.body.setAttribute("data-haori-ready", ""), M.observe(document.head), M.observe(document.body), new tt().start(), V.syncTree(document.body);
4642
4740
  }
4643
4741
  /**
4644
4742
  * 指定された要素を監視します。
@@ -4658,17 +4756,17 @@ const M = class M {
4658
4756
  s.attributeName
4659
4757
  );
4660
4758
  const i = s.target;
4661
- if (s.attributeName && i.hasAttribute("data-haori-click-lock") && (s.attributeName === "disabled" || s.attributeName === "data-haori-click-lock") || s.attributeName && P.isAliasedAttributeReflection(
4759
+ if (s.attributeName && i.hasAttribute("data-haori-click-lock") && (s.attributeName === "disabled" || s.attributeName === "data-haori-click-lock") || s.attributeName && D.isAliasedAttributeReflection(
4662
4760
  i,
4663
4761
  s.attributeName
4664
4762
  ))
4665
4763
  break;
4666
- P.setAttribute(
4764
+ D.setAttribute(
4667
4765
  i,
4668
4766
  s.attributeName,
4669
4767
  i.getAttribute(s.attributeName),
4670
4768
  !0
4671
- ), j.syncElement(i);
4769
+ ), V.syncElement(i);
4672
4770
  break;
4673
4771
  }
4674
4772
  case "childList": {
@@ -4678,9 +4776,9 @@ const M = class M {
4678
4776
  Array.from(s.removedNodes).map((i) => i.nodeName),
4679
4777
  Array.from(s.addedNodes).map((i) => i.nodeName)
4680
4778
  ), Array.from(s.removedNodes).forEach((i) => {
4681
- j.cleanupTree(i), P.removeNode(i);
4779
+ V.cleanupTree(i), D.removeNode(i);
4682
4780
  }), Array.from(s.addedNodes).forEach((i) => {
4683
- i.parentElement instanceof Element && (P.addNode(i.parentElement, i), j.syncTree(i));
4781
+ i.parentElement instanceof Element && (D.addNode(i.parentElement, i), V.syncTree(i));
4684
4782
  });
4685
4783
  break;
4686
4784
  }
@@ -4690,7 +4788,7 @@ const M = class M {
4690
4788
  "Character data changed:",
4691
4789
  s.target,
4692
4790
  s.target.textContent
4693
- ), s.target instanceof Text || s.target instanceof Comment ? P.changeText(s.target, s.target.textContent) : m.warn(
4791
+ ), s.target instanceof Text || s.target instanceof Comment ? D.changeText(s.target, s.target.textContent) : m.warn(
4694
4792
  "[Haori]",
4695
4793
  "Unsupported character data type:",
4696
4794
  s.target
@@ -4714,18 +4812,18 @@ const M = class M {
4714
4812
  }
4715
4813
  };
4716
4814
  M._initialized = !1, M._mutationObservers = [];
4717
- let K = M;
4718
- document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", K.init) : K.init();
4815
+ let G = M;
4816
+ document.readyState === "loading" ? document.addEventListener("DOMContentLoaded", G.init) : G.init();
4719
4817
  const yt = "0.4.13";
4720
4818
  export {
4721
- P as Core,
4722
- c as Env,
4723
- v as Form,
4819
+ D as Core,
4820
+ u as Env,
4821
+ y as Form,
4724
4822
  R as Fragment,
4725
- Y as Haori,
4823
+ X as Haori,
4726
4824
  m as Log,
4727
4825
  N as Queue,
4728
- Y as default,
4826
+ X as default,
4729
4827
  yt as version
4730
4828
  };
4731
4829
  //# sourceMappingURL=haori.es.js.map