From bc49286f91a2fc621aafe43784515d6e38fe4648 Mon Sep 17 00:00:00 2001 From: LeRatierBretonnier Date: Mon, 27 Apr 2026 21:30:33 +0200 Subject: [PATCH] Correction compendiums --- css/cde-theme.css | 355 +++++++++++++++++++++ css/cde-theme.less | 393 ++++++++++++++++++++++++ dist/system.js | 246 ++++++++++++++- dist/system.js.map | 6 +- lang/fr-cde.json | 22 ++ packs/cde-armors/000004.log | 0 packs/cde-armors/000007.log | Bin 0 -> 3153 bytes packs/cde-armors/CURRENT | 2 +- packs/cde-armors/LOG | 8 +- packs/cde-armors/LOG.old | 5 + packs/cde-armors/MANIFEST-000002 | Bin 134 -> 0 bytes packs/cde-armors/MANIFEST-000006 | Bin 0 -> 119 bytes packs/cde-ingredients/000004.log | 0 packs/cde-ingredients/000007.log | Bin 0 -> 32147 bytes packs/cde-ingredients/CURRENT | 2 +- packs/cde-ingredients/LOG | 8 +- packs/cde-ingredients/LOG.old | 5 + packs/cde-ingredients/MANIFEST-000002 | Bin 134 -> 0 bytes packs/cde-ingredients/MANIFEST-000006 | Bin 0 -> 119 bytes packs/cde-items/000004.log | 0 packs/cde-items/000007.log | Bin 0 -> 567 bytes packs/cde-items/CURRENT | 2 +- packs/cde-items/LOG | 8 +- packs/cde-items/LOG.old | 5 + packs/cde-items/MANIFEST-000002 | Bin 134 -> 0 bytes packs/cde-items/MANIFEST-000006 | Bin 0 -> 119 bytes packs/cde-kungfus/000004.log | 0 packs/cde-kungfus/000007.log | Bin 0 -> 56491 bytes packs/cde-kungfus/CURRENT | 2 +- packs/cde-kungfus/LOG | 8 +- packs/cde-kungfus/LOG.old | 5 + packs/cde-kungfus/MANIFEST-000002 | Bin 135 -> 0 bytes packs/cde-kungfus/MANIFEST-000006 | Bin 0 -> 120 bytes packs/cde-npcs/000004.log | 0 packs/cde-npcs/000007.log | Bin 0 -> 115533 bytes packs/cde-npcs/CURRENT | 2 +- packs/cde-npcs/LOG | 8 +- packs/cde-npcs/LOG.old | 5 + packs/cde-npcs/MANIFEST-000002 | Bin 137 -> 0 bytes packs/cde-npcs/MANIFEST-000006 | Bin 0 -> 122 bytes packs/cde-sanhei/000004.log | 0 packs/cde-sanhei/000007.log | Bin 0 -> 8978 bytes packs/cde-sanhei/CURRENT | 2 +- packs/cde-sanhei/LOG | 8 +- packs/cde-sanhei/LOG.old | 5 + packs/cde-sanhei/MANIFEST-000002 | Bin 134 -> 0 bytes packs/cde-sanhei/MANIFEST-000006 | Bin 0 -> 119 bytes packs/cde-spells/000004.log | 0 packs/cde-spells/000007.log | Bin 0 -> 220483 bytes packs/cde-spells/CURRENT | 2 +- packs/cde-spells/LOG | 8 +- packs/cde-spells/LOG.old | 5 + packs/cde-spells/MANIFEST-000002 | Bin 135 -> 0 bytes packs/cde-spells/MANIFEST-000006 | Bin 0 -> 120 bytes packs/cde-supernaturals/000004.log | 0 packs/cde-supernaturals/000007.log | Bin 0 -> 17681 bytes packs/cde-supernaturals/CURRENT | 2 +- packs/cde-supernaturals/LOG | 8 +- packs/cde-supernaturals/LOG.old | 5 + packs/cde-supernaturals/MANIFEST-000002 | Bin 134 -> 0 bytes packs/cde-supernaturals/MANIFEST-000006 | Bin 0 -> 119 bytes packs/cde-weapons/000004.log | 0 packs/cde-weapons/000007.log | Bin 0 -> 11893 bytes packs/cde-weapons/CURRENT | 2 +- packs/cde-weapons/LOG | 8 +- packs/cde-weapons/LOG.old | 5 + packs/cde-weapons/MANIFEST-000002 | Bin 134 -> 0 bytes packs/cde-weapons/MANIFEST-000006 | Bin 0 -> 119 bytes src/config/constants.js | 1 + src/documents/combat.js | 87 ++++++ src/system.js | 43 ++- src/ui/apps/index.js | 1 + src/ui/apps/wheel-app.js | 204 ++++++++++++ src/ui/helpers.js | 25 ++ system.json | 52 +++- templates/apps/cde-wheel-app.html | 148 +++++++++ 76 files changed, 1645 insertions(+), 73 deletions(-) delete mode 100644 packs/cde-armors/000004.log create mode 100644 packs/cde-armors/000007.log create mode 100644 packs/cde-armors/LOG.old delete mode 100644 packs/cde-armors/MANIFEST-000002 create mode 100644 packs/cde-armors/MANIFEST-000006 delete mode 100644 packs/cde-ingredients/000004.log create mode 100644 packs/cde-ingredients/000007.log create mode 100644 packs/cde-ingredients/LOG.old delete mode 100644 packs/cde-ingredients/MANIFEST-000002 create mode 100644 packs/cde-ingredients/MANIFEST-000006 delete mode 100644 packs/cde-items/000004.log create mode 100644 packs/cde-items/000007.log create mode 100644 packs/cde-items/LOG.old delete mode 100644 packs/cde-items/MANIFEST-000002 create mode 100644 packs/cde-items/MANIFEST-000006 delete mode 100644 packs/cde-kungfus/000004.log create mode 100644 packs/cde-kungfus/000007.log create mode 100644 packs/cde-kungfus/LOG.old delete mode 100644 packs/cde-kungfus/MANIFEST-000002 create mode 100644 packs/cde-kungfus/MANIFEST-000006 delete mode 100644 packs/cde-npcs/000004.log create mode 100644 packs/cde-npcs/000007.log create mode 100644 packs/cde-npcs/LOG.old delete mode 100644 packs/cde-npcs/MANIFEST-000002 create mode 100644 packs/cde-npcs/MANIFEST-000006 delete mode 100644 packs/cde-sanhei/000004.log create mode 100644 packs/cde-sanhei/000007.log create mode 100644 packs/cde-sanhei/LOG.old delete mode 100644 packs/cde-sanhei/MANIFEST-000002 create mode 100644 packs/cde-sanhei/MANIFEST-000006 delete mode 100644 packs/cde-spells/000004.log create mode 100644 packs/cde-spells/000007.log create mode 100644 packs/cde-spells/LOG.old delete mode 100644 packs/cde-spells/MANIFEST-000002 create mode 100644 packs/cde-spells/MANIFEST-000006 delete mode 100644 packs/cde-supernaturals/000004.log create mode 100644 packs/cde-supernaturals/000007.log create mode 100644 packs/cde-supernaturals/LOG.old delete mode 100644 packs/cde-supernaturals/MANIFEST-000002 create mode 100644 packs/cde-supernaturals/MANIFEST-000006 delete mode 100644 packs/cde-weapons/000004.log create mode 100644 packs/cde-weapons/000007.log create mode 100644 packs/cde-weapons/LOG.old delete mode 100644 packs/cde-weapons/MANIFEST-000002 create mode 100644 packs/cde-weapons/MANIFEST-000006 create mode 100644 src/documents/combat.js create mode 100644 src/ui/apps/wheel-app.js create mode 100644 templates/apps/cde-wheel-app.html diff --git a/css/cde-theme.css b/css/cde-theme.css index e7f26a7..8a01cb0 100644 --- a/css/cde-theme.css +++ b/css/cde-theme.css @@ -3833,3 +3833,358 @@ ol.item-list li.item .item-controls a.item-control:hover { color: #ff3d5a; text-shadow: 0 0 5px rgba(255, 61, 90, 0.4); } +/* ============================================================ + ROUE D'INITIATIVE — CDEWheelApp + ============================================================ */ +.cde-wheel-app { + color: #e2e8f4; + background: #080c14; + font-family: "Averia", "Averia Regular", sans-serif; +} +.cde-wheel-app .window-content { + padding: 0; + overflow: hidden; +} +/* Two-column layout: SVG wheel left, panel right */ +.cde-wheel-layout { + display: flex; + height: 100%; + min-height: 520px; +} +/* ---- Left: SVG wheel ---- */ +.cde-wheel-svg-container { + flex: 0 0 480px; + width: 480px; + padding: 12px 12px 6px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background: #0d1520; + border-right: 1px solid #1a2436; +} +.cde-wheel-svg-container svg { + flex: 1 1 auto; + width: 100%; + max-width: 456px; + max-height: 456px; + overflow: visible; +} +.cde-wheel-svg-container .cde-wheel-legend { + display: flex; + align-items: center; + gap: 8px; + padding: 4px 0 2px; + font-size: 11px; + color: rgba(255, 255, 255, 0.55); + flex-shrink: 0; +} +.cde-wheel-svg-container .cde-wheel-legend-dot { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 50%; + flex-shrink: 0; +} +.cde-wheel-svg-container .cde-wheel-segment { + stroke: #080c14; + stroke-width: 1.5; + transition: opacity 0.2s; +} +.cde-wheel-svg-container .cde-wheel-cran-label { + font-family: "Averia Regular", sans-serif; + font-size: 12px; + fill: rgba(255, 255, 255, 0.55); + text-anchor: middle; + dominant-baseline: central; + pointer-events: none; + user-select: none; +} +.cde-wheel-svg-container .cde-wheel-fighter-circle { + stroke-width: 2; + cursor: pointer; + transition: r 0.2s, stroke-width 0.2s; +} +.cde-wheel-svg-container .cde-wheel-fighter-circle:hover { + stroke-width: 3; +} +.cde-wheel-svg-container .cde-wheel-fighter-circle.is-active { + r: 18; + stroke-width: 3; + filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.7)); +} +.cde-wheel-svg-container .cde-wheel-fighter-circle.is-turn { + stroke-dasharray: 3 2; + animation: cde-spin 4s linear infinite; +} +.cde-wheel-svg-container .cde-wheel-fighter-initial { + font-size: 13px; + font-weight: 700; + fill: #fff; + text-anchor: middle; + dominant-baseline: central; + pointer-events: none; +} +/* ---- Right: panel ---- */ +.cde-wheel-panel { + flex: 1 1 auto; + display: flex; + flex-direction: column; + overflow: hidden; + padding: 0; + min-width: 0; +} +.cde-wheel-section-title { + padding: 7px 12px 6px; + border-bottom: 1px solid #1a2436; + background: #0d1520; + font-size: 10px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.12em; + color: #7d94b8; + border-left: 3px solid #4a9eff; + flex-shrink: 0; +} +.cde-wheel-section-title em { + font-style: normal; + color: #e2e8f4; + text-transform: none; + letter-spacing: 0; + font-size: 11px; +} +/* Combatant list */ +.cde-wheel-combatants { + flex: 0 0 auto; + max-height: 130px; + overflow-y: auto; + border-bottom: 1px solid #1a2436; +} +.cde-wheel-combatant { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 12px 6px 9px; + cursor: pointer; + border-bottom: 1px solid rgba(26, 36, 54, 0.5); + border-left: 3px solid transparent; + transition: background 0.15s, border-color 0.15s; +} +.cde-wheel-combatant:last-child { + border-bottom: none; +} +.cde-wheel-combatant:hover { + background: #101622; +} +.cde-wheel-combatant.cde-wheel-combatant--selected { + background: rgba(74, 158, 255, 0.1); + border-left-color: #4a9eff; +} +.cde-wheel-combatant.cde-wheel-combatant--selected .cde-wheel-combatant-name { + color: #e2e8f4; + font-weight: 600; +} +.cde-wheel-combatant.cde-wheel-combatant--active .cde-wheel-active-marker { + color: #f0c040; + filter: drop-shadow(0 0 3px #f0c040); +} +.cde-wheel-combatant-img { + width: 30px; + height: 30px; + border-radius: 50%; + object-fit: cover; + border: 1.5px solid #263853; + flex-shrink: 0; +} +.cde-wheel-combatant-name { + flex: 1 1 auto; + font-size: 13px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + color: #7d94b8; +} +.cde-wheel-combatant-cran { + font-size: 11px; + font-weight: 700; + font-variant-numeric: tabular-nums; + flex-shrink: 0; + min-width: 22px; + text-align: center; + padding: 2px 6px; + border-radius: 12px; + line-height: 1.3; +} +.cde-wheel-active-marker { + font-size: 10px; + color: #7d94b8; + flex-shrink: 0; +} +/* Action area */ +.cde-wheel-actions { + flex: 1 1 auto; + display: flex; + flex-direction: column; + overflow-y: auto; + padding: 8px 10px 10px; + gap: 6px; +} +.cde-wheel-actions.cde-wheel-actions--hint { + justify-content: center; + align-items: center; +} +.cde-wheel-hint { + color: #7d94b8; + font-size: 12px; + text-align: center; + font-style: italic; + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; +} +.cde-wheel-hint i { + font-size: 22px; + opacity: 0.4; +} +.cde-wheel-action-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 5px; +} +.cde-wheel-action-btn { + display: flex; + align-items: center; + justify-content: space-between; + gap: 4px; + background: #101622; + border: 1px solid #263853; + border-radius: 5px; + color: #7d94b8; + font-size: 11px; + padding: 5px 7px; + cursor: pointer; + text-align: left; + transition: background 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s; + font-family: inherit; +} +.cde-wheel-action-btn:hover { + color: #e2e8f4; + background: #1a2436; + border-color: #263853; +} +.cde-wheel-action-btn .cde-wheel-action-name { + flex: 1 1 auto; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.cde-wheel-action-btn .cde-wheel-action-cost { + flex-shrink: 0; + font-weight: 700; + font-size: 10px; + padding: 1px 5px; + border-radius: 10px; + background: #263853; + color: #7d94b8; + line-height: 1.4; +} +.cde-wheel-action-btn[data-cost="1"]:hover { + box-shadow: 0 0 6px rgba(74, 158, 255, 0.22); +} +.cde-wheel-action-btn[data-cost="1"] .cde-wheel-action-cost { + background: #1a3d6a; + color: #6aadff; +} +.cde-wheel-action-btn[data-cost="2"]:hover { + box-shadow: 0 0 6px rgba(212, 160, 80, 0.25); +} +.cde-wheel-action-btn[data-cost="2"] .cde-wheel-action-cost { + background: #4a3200; + color: #d4a050; +} +.cde-wheel-action-btn[data-cost="3"]:hover { + box-shadow: 0 0 6px rgba(224, 96, 48, 0.28); +} +.cde-wheel-action-btn[data-cost="3"] .cde-wheel-action-cost { + background: #4a1800; + color: #e07840; +} +.cde-wheel-action-btn[data-cost="6"] { + border-color: rgba(204, 32, 64, 0.4); +} +.cde-wheel-action-btn[data-cost="6"]:hover { + box-shadow: 0 0 6px rgba(204, 32, 64, 0.35); +} +.cde-wheel-action-btn[data-cost="6"] .cde-wheel-action-cost { + background: #4a0814; + color: #e03050; +} +/* Special action buttons */ +.cde-wheel-special-actions { + display: flex; + gap: 6px; + margin-top: 2px; +} +.cde-wheel-btn-roll, +.cde-wheel-btn-surprise { + flex: 1 1 0; + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + border-radius: 5px; + font-size: 11px; + font-weight: 600; + padding: 7px 8px; + cursor: pointer; + font-family: inherit; + transition: background 0.15s, box-shadow 0.15s; + border: 1px solid; +} +.cde-wheel-btn-roll { + background: rgba(192, 138, 0, 0.14); + border-color: rgba(192, 138, 0, 0.5); + color: #e0b030; +} +.cde-wheel-btn-roll:hover { + background: rgba(192, 138, 0, 0.26); + box-shadow: 0 0 8px rgba(192, 138, 0, 0.4); +} +.cde-wheel-btn-surprise { + background: rgba(255, 61, 90, 0.12); + border-color: rgba(255, 61, 90, 0.45); + color: #ff3d5a; +} +.cde-wheel-btn-surprise:hover { + background: rgba(255, 61, 90, 0.24); + box-shadow: 0 0 8px rgba(255, 61, 90, 0.35); +} +/* No-combat empty state */ +.cde-wheel-no-combat { + flex: 1 1 auto; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + color: #7d94b8; + gap: 8px; + padding: 20px; + text-align: center; + font-size: 12px; +} +.cde-wheel-no-combat i { + font-size: 28px; + opacity: 0.4; +} +/* Spin animation for active-turn token */ +@keyframes cde-spin { + from { + transform-origin: var(--fx) var(--fy); + transform: rotate(0deg); + } + to { + transform-origin: var(--fx) var(--fy); + transform: rotate(360deg); + } +} diff --git a/css/cde-theme.less b/css/cde-theme.less index f3f2603..1f29abf 100644 --- a/css/cde-theme.less +++ b/css/cde-theme.less @@ -3951,3 +3951,396 @@ ol.item-list { text-shadow: 0 0 5px fade(@cde-kungfu, 40%); } } + + +/* ============================================================ + ROUE D'INITIATIVE — CDEWheelApp + ============================================================ */ + +// Wu Xing segment colours (match JS constants) +@wu-metal: #b8c4cc; +@wu-water: #3a7bd5; +@wu-earth: #c8a84b; +@wu-fire: #d94f3d; +@wu-wood: #4a9b5a; +@wu-reference: #2c1f6b; + +.cde-wheel-app { + color: @cde-text; + background: @cde-bg; + font-family: "Averia", "Averia Regular", sans-serif; + + .window-content { + padding: 0; + overflow: hidden; + } +} + +/* Two-column layout: SVG wheel left, panel right */ +.cde-wheel-layout { + display: flex; + height: 100%; + min-height: 520px; +} + +/* ---- Left: SVG wheel ---- */ +.cde-wheel-svg-container { + flex: 0 0 480px; + width: 480px; + padding: 12px 12px 6px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background: @cde-surface2; + border-right: 1px solid @cde-border; + + svg { + flex: 1 1 auto; + width: 100%; + max-width: 456px; + max-height: 456px; + overflow: visible; + } + + .cde-wheel-legend { + display: flex; + align-items: center; + gap: 8px; + padding: 4px 0 2px; + font-size: 11px; + color: rgba(255,255,255,0.55); + flex-shrink: 0; + } + + .cde-wheel-legend-dot { + display: inline-block; + width: 10px; + height: 10px; + border-radius: 50%; + flex-shrink: 0; + } + + .cde-wheel-segment { + stroke: @cde-bg; + stroke-width: 1.5; + transition: opacity 0.2s; + } + + .cde-wheel-cran-label { + font-family: "Averia Regular", sans-serif; + font-size: 12px; + fill: rgba(255,255,255,0.55); + text-anchor: middle; + dominant-baseline: central; + pointer-events: none; + user-select: none; + } + + // Combatant token circle on the wheel + .cde-wheel-fighter-circle { + stroke-width: 2; + cursor: pointer; + transition: r 0.2s, stroke-width 0.2s; + + &:hover { + stroke-width: 3; + } + + &.is-active { + r: 18; + stroke-width: 3; + filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.7)); + } + + &.is-turn { + stroke-dasharray: 3 2; + animation: cde-spin 4s linear infinite; + } + } + + .cde-wheel-fighter-initial { + font-size: 13px; + font-weight: 700; + fill: #fff; + text-anchor: middle; + dominant-baseline: central; + pointer-events: none; + } +} + +/* ---- Right: panel ---- */ +.cde-wheel-panel { + flex: 1 1 auto; + display: flex; + flex-direction: column; + overflow: hidden; + padding: 0; + min-width: 0; +} + +.cde-wheel-section-title { + padding: 7px 12px 6px; + border-bottom: 1px solid @cde-border; + background: @cde-surface2; + font-size: 10px; + font-weight: 700; + text-transform: uppercase; + letter-spacing: 0.12em; + color: @cde-muted; + border-left: 3px solid @cde-spell; + flex-shrink: 0; + + em { + font-style: normal; + color: @cde-text; + text-transform: none; + letter-spacing: 0; + font-size: 11px; + } +} + +/* Combatant list */ +.cde-wheel-combatants { + flex: 0 0 auto; + max-height: 130px; + overflow-y: auto; + border-bottom: 1px solid @cde-border; +} + +.cde-wheel-combatant { + display: flex; + align-items: center; + gap: 8px; + padding: 6px 12px 6px 9px; + cursor: pointer; + border-bottom: 1px solid fade(@cde-border, 50%); + border-left: 3px solid transparent; + transition: background 0.15s, border-color 0.15s; + + &:last-child { border-bottom: none; } + + &:hover { + background: @cde-surface; + } + + &.cde-wheel-combatant--selected { + background: fade(@cde-spell, 10%); + border-left-color: @cde-spell; + + .cde-wheel-combatant-name { + color: @cde-text; + font-weight: 600; + } + } + + &.cde-wheel-combatant--active { + .cde-wheel-active-marker { + color: #f0c040; + filter: drop-shadow(0 0 3px #f0c040); + } + } +} + +.cde-wheel-combatant-img { + width: 30px; + height: 30px; + border-radius: 50%; + object-fit: cover; + border: 1.5px solid @cde-border-hi; + flex-shrink: 0; +} + +.cde-wheel-combatant-name { + flex: 1 1 auto; + font-size: 13px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + color: @cde-muted; +} + +.cde-wheel-combatant-cran { + font-size: 11px; + font-weight: 700; + font-variant-numeric: tabular-nums; + flex-shrink: 0; + min-width: 22px; + text-align: center; + padding: 2px 6px; + border-radius: 12px; + line-height: 1.3; +} + +.cde-wheel-active-marker { + font-size: 10px; + color: @cde-muted; + flex-shrink: 0; +} + +/* Action area */ +.cde-wheel-actions { + flex: 1 1 auto; + display: flex; + flex-direction: column; + overflow-y: auto; + padding: 8px 10px 10px; + gap: 6px; + + &.cde-wheel-actions--hint { + justify-content: center; + align-items: center; + } +} + +.cde-wheel-hint { + color: @cde-muted; + font-size: 12px; + text-align: center; + font-style: italic; + display: flex; + flex-direction: column; + align-items: center; + gap: 8px; + + i { + font-size: 22px; + opacity: 0.4; + } +} + +.cde-wheel-action-grid { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 5px; +} + +.cde-wheel-action-btn { + display: flex; + align-items: center; + justify-content: space-between; + gap: 4px; + background: @cde-surface; + border: 1px solid @cde-border-hi; + border-radius: @cde-radius-sm; + color: @cde-muted; + font-size: 11px; + padding: 5px 7px; + cursor: pointer; + text-align: left; + transition: background 0.15s, border-color 0.15s, color 0.15s, box-shadow 0.15s; + font-family: inherit; + + &:hover { + color: @cde-text; + background: @cde-border; + border-color: @cde-border-hi; + } + + .cde-wheel-action-name { + flex: 1 1 auto; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .cde-wheel-action-cost { + flex-shrink: 0; + font-weight: 700; + font-size: 10px; + padding: 1px 5px; + border-radius: 10px; + background: @cde-border-hi; + color: @cde-muted; + line-height: 1.4; + } + + &[data-cost="1"] { + &:hover { box-shadow: 0 0 6px fade(@cde-spell, 22%); } + .cde-wheel-action-cost { background: #1a3d6a; color: #6aadff; } + } + &[data-cost="2"] { + &:hover { box-shadow: 0 0 6px fade(#d4a050, 25%); } + .cde-wheel-action-cost { background: #4a3200; color: #d4a050; } + } + &[data-cost="3"] { + &:hover { box-shadow: 0 0 6px fade(#e06030, 28%); } + .cde-wheel-action-cost { background: #4a1800; color: #e07840; } + } + &[data-cost="6"] { + border-color: fade(#cc2040, 40%); + &:hover { box-shadow: 0 0 6px fade(#cc2040, 35%); } + .cde-wheel-action-cost { background: #4a0814; color: #e03050; } + } +} + +/* Special action buttons */ +.cde-wheel-special-actions { + display: flex; + gap: 6px; + margin-top: 2px; +} + +.cde-wheel-btn-roll, +.cde-wheel-btn-surprise { + flex: 1 1 0; + display: flex; + align-items: center; + justify-content: center; + gap: 6px; + border-radius: @cde-radius-sm; + font-size: 11px; + font-weight: 600; + padding: 7px 8px; + cursor: pointer; + font-family: inherit; + transition: background 0.15s, box-shadow 0.15s; + border: 1px solid; +} + +.cde-wheel-btn-roll { + background: fade(#c08a00, 14%); + border-color: fade(#c08a00, 50%); + color: #e0b030; + + &:hover { + background: fade(#c08a00, 26%); + box-shadow: 0 0 8px fade(#c08a00, 40%); + } +} + +.cde-wheel-btn-surprise { + background: fade(@cde-kungfu, 12%); + border-color: fade(@cde-kungfu, 45%); + color: @cde-kungfu; + + &:hover { + background: fade(@cde-kungfu, 24%); + box-shadow: 0 0 8px fade(@cde-kungfu, 35%); + } +} + +/* No-combat empty state */ +.cde-wheel-no-combat { + flex: 1 1 auto; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + color: @cde-muted; + gap: 8px; + padding: 20px; + text-align: center; + font-size: 12px; + + i { + font-size: 28px; + opacity: 0.4; + } +} + +/* Spin animation for active-turn token */ +@keyframes cde-spin { + from { transform-origin: var(--fx) var(--fy); transform: rotate(0deg); } + to { transform-origin: var(--fx) var(--fy); transform: rotate(360deg); } +} diff --git a/dist/system.js b/dist/system.js index 7c808e8..23c70ee 100644 --- a/dist/system.js +++ b/dist/system.js @@ -130,7 +130,8 @@ var TEMPLATE_PARTIALS = [ "systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-kungfus.html", "systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-items.html", "systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-loksyu-app.html", - "systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-tinji-app.html" + "systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-tinji-app.html", + "systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-wheel-app.html" ]; // src/config/settings.js @@ -807,6 +808,20 @@ function registerHandlebarsHelpers() { }; return game.i18n.localize(keys[activation] ?? "CDE.Activation"); }); + Handlebars.registerHelper("cranPosition", function(cran, cx, cy, r) { + const angleDeg = 90 + cran * 15; + const angleRad = angleDeg * Math.PI / 180; + const x = Math.round(cx + r * Math.cos(angleRad)); + const y = Math.round(cy - r * Math.sin(angleRad)); + return { x, y }; + }); + Handlebars.registerHelper("fighterX", function(cx, index, total) { + const offset = total > 1 ? (index - (total - 1) / 2) * 34 : 0; + return Math.round(cx - 15 + offset); + }); + Handlebars.registerHelper("fighterY", function(cy, index, total) { + return Math.round(cy - 50); + }); } // src/ui/templates.js @@ -2209,6 +2224,205 @@ var CDETinjiApp = class _CDETinjiApp extends foundry.applications.api.Handlebars } }; +// src/documents/combat.js +var CDECombat = class extends Combat { + /** + * Override rollInitiative to open the PC or NPC initiative dialog + * for each selected combatant, then sync the result to the Combatant document. + */ + async rollInitiative(ids, options = {}) { + const combatantIds = typeof ids === "string" ? [ids] : ids; + for (const id of combatantIds) { + const combatant = this.combatants.get(id); + if (!combatant) continue; + const actor = combatant.actor; + if (!actor) continue; + if (actor.type === ACTOR_TYPES.character) { + await rollInitiativePC(actor); + } else { + await rollInitiativeNPC(actor); + } + } + return this; + } + /** + * Sort combatants: highest initiative first (furthest counter-clockwise = acts first). + * Ties: PCs before NPCs; among PCs, by name; among NPCs, by name. + * Calls super.setupTurns() first to ensure this.current is properly initialized. + */ + setupTurns() { + super.setupTurns(); + this.turns = this.turns.slice().sort((a, b) => { + const ia = a.initiative ?? 0; + const ib = b.initiative ?? 0; + if (ia !== ib) return ib - ia; + const aIsPC = a.actor?.type === ACTOR_TYPES.character ? 1 : 0; + const bIsPC = b.actor?.type === ACTOR_TYPES.character ? 1 : 0; + if (aIsPC !== bIsPC) return bIsPC - aIsPC; + return (a.name ?? "").localeCompare(b.name ?? ""); + }); + return this.turns; + } +}; +async function advanceCombatantPosition(combatant, cranCost) { + const current = combatant.initiative ?? combatant.actor?.system?.initiative ?? 1; + const newValue = (current - cranCost - 1 + 48) % 24 + 1; + await combatant.update({ initiative: newValue }); +} + +// src/ui/apps/wheel-app.js +var WHEEL_TEMPLATE = "systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-wheel-app.html"; +var ACTION_COSTS = [ + { key: "draw", label: "CDE.ActionCostDraw", cost: 1 }, + { key: "changestyle", label: "CDE.ActionCostChangeStyle", cost: 1 }, + { key: "defense", label: "CDE.ActionCostDefense", cost: 1 }, + { key: "aim", label: "CDE.ActionCostAim", cost: 2 }, + { key: "help", label: "CDE.ActionCostHelp", cost: 2 }, + { key: "defally", label: "CDE.ActionCostDefendAlly", cost: 2 }, + { key: "move", label: "CDE.ActionCostMove", cost: 2 }, + { key: "attack", label: "CDE.ActionCostAttack", cost: 3 }, + { key: "delay", label: "CDE.ActionCostDelay", cost: 6 } +]; +var WHEEL_SEGMENTS = [ + { label: "M\xE9tal", color: "#b8c4cc", textColor: "#1a1a1a", crans: [1, 2, 3, 4] }, + { label: "Eau", color: "#3a7bd5", textColor: "#ffffff", crans: [5, 6, 7, 8] }, + { label: "Terre", color: "#c8a84b", textColor: "#1a1a1a", crans: [9, 10, 11, 12] }, + { label: "Feu", color: "#d94f3d", textColor: "#ffffff", crans: [13, 14, 15, 16] }, + { label: "Bois", color: "#4a9b5a", textColor: "#ffffff", crans: [17, 18, 19, 20] }, + { label: "Rep\xE8re", color: "#1a1a2e", textColor: "#aaaaaa", crans: [21, 22, 23, 24] } +]; +function segmentForCran(cran) { + return WHEEL_SEGMENTS.find((s) => s.crans.includes(cran)) ?? WHEEL_SEGMENTS[0]; +} +var CDEWheelApp = class _CDEWheelApp extends foundry.applications.api.ApplicationV2 { + static DEFAULT_OPTIONS = { + id: "cde-wheel-app", + classes: ["cde-wheel-app"], + tag: "div", + window: { + title: "CDE.InitiativeWheel", + icon: "fas fa-circle-notch", + resizable: true + }, + position: { width: 820, height: 620 }, + actions: { + advanceCran: _CDEWheelApp.#advanceCran, + setSurprised: _CDEWheelApp.#setSurprised, + rollInitiative: _CDEWheelApp.#rollInitiative + } + }; + /** @type {CDEWheelApp|null} */ + static #instance = null; + /** Open (or bring to front) the singleton instance. */ + static open() { + if (!_CDEWheelApp.#instance || _CDEWheelApp.#instance.rendered === false) { + _CDEWheelApp.#instance = new _CDEWheelApp(); + _CDEWheelApp.#instance.render(true); + } else { + _CDEWheelApp.#instance.bringToFront(); + } + return _CDEWheelApp.#instance; + } + /** Currently selected combatant id (for action panel). */ + #selectedId = null; + async _prepareContext(options) { + const combat = game.combat; + const combatants = combat ? [...combat.combatants.values()] : []; + const sorted = [...combatants].sort((a, b) => (b.initiative ?? 0) - (a.initiative ?? 0)); + const cranData = this.#buildCranData(combatants); + const selected = this.#selectedId ? combatants.find((c) => c.id === this.#selectedId) : null; + const actionCosts = ACTION_COSTS.map((a) => ({ + ...a, + label: game.i18n.localize(a.label) + })); + return { + hasCombat: !!combat, + combatants: sorted.map((c) => ({ + id: c.id, + name: c.name, + img: c.token?.texture?.src ?? c.actor?.img ?? "icons/svg/mystery-man.svg", + initiative: c.initiative ?? "\u2014", + segment: segmentForCran(c.initiative ?? 1), + isActive: combat?.current?.combatantId === c.id, + isSelected: c.id === this.#selectedId, + hasInitiative: c.initiative != null + })), + cranData, + selected, + selectedName: selected?.name ?? null, + actionCosts + }; + } + async _renderHTML(context, options) { + return foundry.applications.handlebars.renderTemplate(WHEEL_TEMPLATE, context); + } + _replaceHTML(result, content, options) { + content.innerHTML = result; + this.#bindEvents(content); + } + /** Build per-cran data for the SVG wheel. */ + #buildCranData(combatants) { + const data = []; + for (let cran = 1; cran <= 24; cran++) { + const segment = segmentForCran(cran); + const fighters = combatants.filter((c) => Math.round(c.initiative) === cran); + data.push({ cran, segment, fighters }); + } + return data; + } + /** Bind click events for combatant selection. */ + #bindEvents(content) { + content.querySelectorAll("[data-select-combatant]").forEach((el) => { + el.addEventListener("click", () => { + this.#selectedId = el.dataset.selectCombatant; + this.render(); + }); + }); + } + /** Action: advance selected combatant by given cran cost. */ + static async #advanceCran(event, element) { + const app = _CDEWheelApp.#instance; + if (!app?.#selectedId) return; + const cost = parseInt(element.dataset.cost, 10); + if (!cost || isNaN(cost)) return; + const combatant = game.combat?.combatants.get(app.#selectedId); + if (!combatant) return; + await advanceCombatantPosition(combatant, cost); + } + /** Action: set selected combatant to surprised (position 1 = reference). */ + static async #setSurprised(event, element) { + const app = _CDEWheelApp.#instance; + if (!app?.#selectedId) return; + const combatant = game.combat?.combatants.get(app.#selectedId); + if (!combatant) return; + await combatant.update({ initiative: 1 }); + } + /** Action: open the initiative dialog for the selected combatant. */ + static async #rollInitiative(event, element) { + const app = _CDEWheelApp.#instance; + if (!app?.#selectedId) return; + const combatant = game.combat?.combatants.get(app.#selectedId); + if (!combatant) return; + await game.combat.rollInitiative([app.#selectedId]); + } + /** Re-render when combat state changes. */ + static registerHooks() { + const refresh = () => { + if (_CDEWheelApp.#instance?.rendered) _CDEWheelApp.#instance.render(); + }; + Hooks.on("updateCombat", refresh); + Hooks.on("updateCombatant", refresh); + Hooks.on("createCombatant", refresh); + Hooks.on("deleteCombatant", refresh); + Hooks.on("updateActor", (_actor, diff) => { + if (foundry.utils.hasProperty(diff, "system.initiative")) refresh(); + }); + Hooks.on("deleteCombat", () => { + if (_CDEWheelApp.#instance?.rendered) _CDEWheelApp.#instance.render(); + }); + } +}; + // src/ui/roll-actions.js var RESULT_TEMPLATE3 = "systems/fvtt-chroniques-de-l-etrange/templates/form/cde-dice-result.html"; function injectRollActions(message, html) { @@ -2362,7 +2576,8 @@ Hooks.once("init", async () => { console.info(`CHRONIQUESDELETRANGE | Initializing ${SYSTEM_ID}`); registerSettings(); game.system.CONST = { MAGICS, SUBTYPES }; - game.cde = { CDELoksyuApp, CDETinjiApp }; + game.cde = { CDELoksyuApp, CDETinjiApp, CDEWheelApp }; + CONFIG.Combat.documentClass = CDECombat; CONFIG.Actor.dataModels = { [ACTOR_TYPES.character]: CharacterDataModel, [ACTOR_TYPES.npc]: NpcDataModel @@ -2440,6 +2655,7 @@ Hooks.once("init", async () => { }); Hooks.once("ready", async () => { await migrateIfNeeded(); + CDEWheelApp.registerHooks(); }); Hooks.on("renderChatLog", (_app, html) => { const el = html instanceof HTMLElement ? html : html[0] ?? html; @@ -2454,10 +2670,14 @@ Hooks.on("renderChatLog", (_app, html) => { + `; wrapper.addEventListener("click", (ev) => { if (ev.target.closest(".cde-chat-btn--loksyu")) CDELoksyuApp.open(); if (ev.target.closest(".cde-chat-btn--tinji")) CDETinjiApp.open(); + if (ev.target.closest(".cde-chat-btn--wheel")) CDEWheelApp.open(); }); const anchor = el.querySelector(".chat-form") ?? el.querySelector(".chat-message-form") ?? el.querySelector("form"); if (anchor) anchor.parentElement.insertBefore(wrapper, anchor); @@ -2472,6 +2692,28 @@ Hooks.on("updateSetting", (setting) => { refreshAllRollActions(); } }); +Hooks.on("updateActor", (actor, diff) => { + if (!foundry.utils.hasProperty(diff, "system.initiative")) return; + if (!game.combat) return; + const initiative = actor.system.initiative; + const combatant = game.combat.combatants.find((c) => c.actor?.id === actor.id); + if (combatant && combatant.initiative !== initiative) { + combatant.update({ initiative }).catch(() => { + }); + } +}); +Hooks.on("updateCombatant", (combatant, diff) => { + if (!("initiative" in diff)) return; + const initiative = combatant.initiative; + if (initiative == null) return; + setTimeout(() => { + const actor = combatant.actor; + if (actor && actor.system?.initiative !== initiative) { + actor.update({ "system.initiative": initiative }).catch(() => { + }); + } + }, 0); +}); /** * Chroniques de l'Étrange — Système FoundryVTT * diff --git a/dist/system.js.map b/dist/system.js.map index 366fc95..fdef890 100644 --- a/dist/system.js.map +++ b/dist/system.js.map @@ -1,7 +1,7 @@ { "version": 3, - "sources": ["../src/config/constants.js", "../src/config/settings.js", "../src/config/localize.js", "../src/config/runtime.js", "../src/data/actors/character.js", "../src/data/actors/npc.js", "../src/data/items/item.js", "../src/data/items/kungfu.js", "../src/data/items/spell.js", "../src/data/items/supernatural.js", "../src/data/items/weapon.js", "../src/data/items/armor.js", "../src/data/items/sanhei.js", "../src/data/items/ingredient.js", "../src/documents/chat-message.js", "../src/documents/actor.js", "../src/documents/item.js", "../src/ui/dice.js", "../src/ui/helpers.js", "../src/ui/templates.js", "../src/ui/initiative.js", "../src/ui/apps/singletons.js", "../src/ui/rolling.js", "../src/ui/sheets/actors/base.js", "../src/ui/sheets/actors/character.js", "../src/ui/sheets/actors/npc.js", "../src/ui/sheets/items/base.js", "../src/ui/sheets/items/item.js", "../src/ui/sheets/items/kungfu.js", "../src/ui/sheets/items/spell.js", "../src/ui/sheets/items/supernatural.js", "../src/ui/sheets/items/weapon.js", "../src/ui/sheets/items/armor.js", "../src/ui/sheets/items/sanhei.js", "../src/ui/sheets/items/ingredient.js", "../src/ui/apps/loksyu-app.js", "../src/ui/apps/tinji-app.js", "../src/ui/roll-actions.js", "../src/system.js"], - "sourcesContent": ["/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport const SYSTEM_ID = \"fvtt-chroniques-de-l-etrange\"\n\nexport const ACTOR_TYPES = {\n character: \"character\",\n npc: \"npc\",\n}\n\nexport const ITEM_TYPES = {\n item: \"item\",\n kungfu: \"kungfu\",\n spell: \"spell\",\n supernatural: \"supernatural\",\n weapon: \"weapon\",\n armor: \"armor\",\n sanhei: \"sanhei\",\n ingredient: \"ingredient\",\n}\n\nexport const SUBTYPES = {\n weapon: { id: \"weapon\", label: \"CDE.Weapon\" },\n armor: { id: \"armor\", label: \"CDE.Armor\" },\n sanhei: { id: \"sanhei\", label: \"CDE.Sanhei\" },\n other: { id: \"other\", label: \"CDE.Other\" },\n}\n\nexport const MAGICS = {\n internalcinnabar: {\n id: \"internalcinnabar\",\n background: \"linear-grey\",\n label: \"CDE.InternalCinnabar\",\n aspectlabel: \"CDE.Metal\",\n speciality: {\n essence: { label: \"CDE.Essence\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n mind: { label: \"CDE.Mind\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n purification: { label: \"CDE.Purification\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n manipulation: { label: \"CDE.Manipulation\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n aura: { label: \"CDE.Aura\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n alchemy: {\n id: \"alchemy\",\n background: \"linear-blue\",\n label: \"CDE.Alchemy\",\n aspectlabel: \"CDE.Water\",\n speciality: {\n acupuncture: { label: \"CDE.Acupuncture\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n elixirs: { label: \"CDE.Elixirs\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n poisons: { label: \"CDE.Poisons\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n arsenal: { label: \"CDE.Arsenal\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n potions: { label: \"CDE.Potions\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n masteryoftheway: {\n id: \"masteryoftheway\",\n background: \"linear-brown\",\n label: \"CDE.MasteryOfTheWay\",\n aspectlabel: \"CDE.Earth\",\n speciality: {\n curse: { label: \"CDE.Curse\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n transfiguration: { label: \"CDE.Transfiguration\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n necromancy: { label: \"CDE.Necromancy\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n climatecontrol: { label: \"CDE.ClimateControl\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n goldenmagic: { label: \"CDE.GoldenMagic\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n exorcism: {\n id: \"exorcism\",\n background: \"linear-red\",\n label: \"CDE.Exorcism\",\n aspectlabel: \"CDE.Fire\",\n speciality: {\n invocation: { label: \"CDE.Invocation\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n tracking: { label: \"CDE.Tracking\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n protection: { label: \"CDE.Protection\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n punishment: { label: \"CDE.Punishment\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n domination: { label: \"CDE.Domination\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n geomancy: {\n id: \"geomancy\",\n background: \"linear-green\",\n label: \"CDE.Geomancy\",\n aspectlabel: \"CDE.Wood\",\n speciality: {\n neutralization: { label: \"CDE.Neutralization\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n divination: { label: \"CDE.Divination\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n earthlyprayer: { label: \"CDE.EarthlyPrayer\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n heavenlyprayer: { label: \"CDE.HeavenlyPrayer\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n fungseoi: { label: \"CDE.Fungseoi\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n}\n\n/** Map aspect name \u2192 i18n label key */\nexport const ASPECT_LABELS = {\n metal: \"CDE.Metal\",\n water: \"CDE.Water\",\n earth: \"CDE.Earth\",\n fire: \"CDE.Fire\",\n wood: \"CDE.Wood\",\n}\n\n/** Map aspect name \u2192 image path */\nexport const ASPECT_ICONS = {\n metal: \"systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\",\n water: \"systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n earth: \"systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n fire: \"systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n wood: \"systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n}\n\n/** Map aspect name \u2192 die face pair [yin, yang] (face=10 stored as 0) */\nexport const ASPECT_FACES = {\n metal: [3, 8],\n water: [1, 6],\n earth: [0, 5], // 0 = face \"10\"\n fire: [2, 7],\n wood: [4, 9],\n}\n\n/** Ordered aspect names by index (metal=0, water=1, earth=2, fire=3, wood=4) */\nexport const ASPECT_NAMES = [\"metal\", \"water\", \"earth\", \"fire\", \"wood\"]\n\n/**\n * Wu Xing generating/overcoming cycle.\n * For each active aspect, the five result categories in order:\n * [successes, auspicious, noxious, loksyu, tinji]\n */\nexport const WU_XING_CYCLE = {\n wood: [\"wood\", \"fire\", \"water\", \"earth\", \"metal\"],\n fire: [\"fire\", \"earth\", \"wood\", \"metal\", \"water\"],\n earth: [\"earth\", \"metal\", \"fire\", \"water\", \"wood\"],\n metal: [\"metal\", \"water\", \"earth\", \"wood\", \"fire\"],\n water: [\"water\", \"wood\", \"metal\", \"fire\", \"earth\"],\n}\n\nexport const TEMPLATE_PARTIALS = [\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-skills.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-magics.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-nghang.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-treasures.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-items.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-kungfus.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-spells.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-supernaturals.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-spells.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-kungfus.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-items.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-loksyu-app.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-tinji-app.html\",\n]\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { SYSTEM_ID } from \"./constants.js\"\n\n/**\n * Register all world/client settings for the system.\n * Called during the \"init\" hook before sheets and data-models are set up.\n */\nexport function registerSettings() {\n game.settings.register(SYSTEM_ID, \"loksyuData\", {\n scope: \"world\",\n config: false,\n type: Object,\n default: {\n wood: { yin: 0, yang: 0 },\n fire: { yin: 0, yang: 0 },\n earth: { yin: 0, yang: 0 },\n metal: { yin: 0, yang: 0 },\n water: { yin: 0, yang: 0 },\n },\n })\n\n game.settings.register(SYSTEM_ID, \"tinjiData\", {\n scope: \"world\",\n config: false,\n type: Number,\n default: 0,\n })\n}\n\n/**\n * Run any pending data migrations on the \"ready\" hook.\n * Reserved for future schema migrations.\n */\nexport async function migrateIfNeeded() {\n // No migrations required yet.\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { MAGICS, SUBTYPES } from \"./constants.js\"\n\nexport function preLocalizeConfig() {\n const localizeConfigObject = (obj, keys) => {\n for (const o of Object.values(obj)) {\n for (const key of keys) {\n o[key] = game.i18n.localize(o[key])\n }\n }\n }\n\n localizeConfigObject(SUBTYPES, [\"label\"])\n Object.values(MAGICS).forEach((magic) => {\n magic.label = game.i18n.localize(magic.label)\n magic.aspectlabel = game.i18n.localize(magic.aspectlabel)\n Object.values(magic.speciality).forEach((spec) => {\n spec.label = game.i18n.localize(spec.label)\n spec.labelelement = game.i18n.localize(spec.labelelement)\n })\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport function configureRuntime() {\n CONFIG.Actor.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/actor-banner.webp\"\n CONFIG.Adventure.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/adventure-banner.webp\"\n CONFIG.Cards.compendiumBanner = \"ui/banners/cards-banner.webp\"\n CONFIG.Item.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/item-banner.webp\"\n CONFIG.JournalEntry.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/journalentry-banner.webp\"\n CONFIG.Macro.compendiumBanner = \"ui/banners/macro-banner.webp\"\n CONFIG.Playlist.compendiumBanner = \"ui/banners/playlist-banner.webp\"\n CONFIG.RollTable.compendiumBanner = \"ui/banners/rolltable-banner.webp\"\n CONFIG.Scene.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/scene-banner.webp\"\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class CharacterDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const numberField = (initial = 0, extra = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...extra })\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const boolField = (initial = false) => new fields.BooleanField({ required: true, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n const aspectField = (label, chinese) =>\n new fields.SchemaField({\n chinese: stringField(chinese),\n label: stringField(label),\n value: numberField(15, { min: 0 }),\n })\n\n const skillField = (label) =>\n new fields.SchemaField({\n label: stringField(label),\n specialities: stringField(\"\"),\n value: numberField(0, { min: 0 }),\n })\n\n const resourceField = (label) =>\n new fields.SchemaField({\n label: stringField(label),\n specialities: stringField(\"\"),\n value: numberField(0, { min: 0 }),\n debt: boolField(false),\n })\n\n const componentField = () =>\n new fields.SchemaField({\n value: stringField(\"\"),\n })\n\n const magicSpecialityField = () =>\n new fields.SchemaField({\n check: boolField(false),\n })\n\n const magicField = () =>\n new fields.SchemaField({\n visible: boolField(true),\n value: numberField(0, { min: 0 }),\n speciality: new fields.SchemaField({\n essence: magicSpecialityField(),\n mind: magicSpecialityField(),\n purification: magicSpecialityField(),\n manipulation: magicSpecialityField(),\n aura: magicSpecialityField(),\n acupuncture: magicSpecialityField(),\n elixirs: magicSpecialityField(),\n poisons: magicSpecialityField(),\n arsenal: magicSpecialityField(),\n potions: magicSpecialityField(),\n curse: magicSpecialityField(),\n transfiguration: magicSpecialityField(),\n necromancy: magicSpecialityField(),\n climatecontrol: magicSpecialityField(),\n goldenmagic: magicSpecialityField(),\n invocation: magicSpecialityField(),\n tracking: magicSpecialityField(),\n protection: magicSpecialityField(),\n punishment: magicSpecialityField(),\n domination: magicSpecialityField(),\n neutralization: magicSpecialityField(),\n divination: magicSpecialityField(),\n earthlyprayer: magicSpecialityField(),\n heavenlyprayer: magicSpecialityField(),\n fungseoi: magicSpecialityField(),\n }),\n })\n\n const treasureBranch = () =>\n new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n max: numberField(0, { min: 0 }),\n min: numberField(0, { min: 0 }),\n })\n\n const treasureLevel = () =>\n new fields.SchemaField({\n san: treasureBranch(),\n zing: treasureBranch(),\n })\n\n const schema = {\n concept: stringField(\"\"),\n guardian: numberField(0, { min: 0, max: 5 }),\n initiative: numberField(1, { min: 0 }),\n anti_initiative: numberField(24, { min: 0 }),\n description: htmlField(\"\"),\n prefs: new fields.SchemaField({\n typeofthrow: new fields.SchemaField({\n check: boolField(true),\n choice: stringField(\"0\"),\n }),\n }),\n prompt: new fields.SchemaField({\n typeofthrow: new fields.SchemaField({\n check: boolField(true),\n choice: stringField(\"0\"),\n }),\n configure: new fields.SchemaField({\n numberofdice: numberField(0),\n aspect: numberField(0),\n bonus: numberField(0),\n bonusauspiciousdice: numberField(0),\n typeofthrow: numberField(0),\n aspectskill: numberField(0),\n bonusmalusskill: numberField(0),\n aspectspeciality: numberField(0),\n rolldifficulty: numberField(0),\n bonusmalusspeciality: numberField(0),\n }),\n }),\n aspect: new fields.SchemaField({\n fire: aspectField(\"CDE.Fire\", \"\u328B\"),\n earth: aspectField(\"CDE.Earth\", \"\u328F\"),\n metal: aspectField(\"CDE.Metal\", \"\u328E\"),\n water: aspectField(\"CDE.Water\", \"\u328C\"),\n wood: aspectField(\"CDE.Wood\", \"\u328D\"),\n }),\n skills: new fields.SchemaField({\n art: skillField(\"CDE.Art\"),\n investigation: skillField(\"CDE.Investigation\"),\n erudition: skillField(\"CDE.Erudition\"),\n knavery: skillField(\"CDE.Knavery\"),\n wordliness: skillField(\"CDE.Wordliness\"),\n prowess: skillField(\"CDE.Prowess\"),\n sciences: skillField(\"CDE.Sciences\"),\n technologies: skillField(\"CDE.Technologies\"),\n kungfu: skillField(\"CDE.KungFu\"),\n rangedcombat: skillField(\"CDE.RangedCombat\"),\n }),\n resources: new fields.SchemaField({\n supply: resourceField(\"CDE.Supply\"),\n inquiry: resourceField(\"CDE.Inquiry\"),\n influence: resourceField(\"CDE.Influence\"),\n }),\n component: new fields.SchemaField({\n one: componentField(),\n two: componentField(),\n three: componentField(),\n four: componentField(),\n five: componentField(),\n six: componentField(),\n seven: componentField(),\n eight: componentField(),\n nine: componentField(),\n zero: componentField(),\n }),\n magics: new fields.SchemaField({\n internalcinnabar: magicField(),\n alchemy: magicField(),\n masteryoftheway: magicField(),\n exorcism: magicField(),\n geomancy: magicField(),\n }),\n threetreasures: new fields.SchemaField({\n heiyang: new fields.SchemaField({ value: numberField(0, { min: 0 }), max: numberField(0, { min: 0 }) }),\n heiyin: new fields.SchemaField({ value: numberField(0, { min: 0 }), max: numberField(0, { min: 0 }) }),\n dicelevel: new fields.SchemaField({\n level0d: treasureLevel(),\n level1d: treasureLevel(),\n level2d: treasureLevel(),\n }),\n }),\n experience: new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n max: numberField(0, { min: 0 }),\n min: numberField(0, { min: 0 }),\n }),\n }\n\n return schema\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class NpcDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const numberField = (initial = 0, extra = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...extra })\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const boolField = (initial = false) => new fields.BooleanField({ required: true, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n const aptitudeField = () =>\n new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n speciality: stringField(\"\"),\n })\n\n const trackedField = () =>\n new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n calcul: numberField(0, { min: 0 }),\n note: stringField(\"\"),\n })\n\n return {\n type: stringField(\"\"),\n threat: numberField(0, { min: 0, max: 4 }), // profane(0) | apprentice(1) | initiate(2) | accomplished(3) | renowned(4)\n nuisance: numberField(0, { min: 0, max: 5 }), // figurant(0) | minion(1) | adversary(2) | ally(3) | boss(4) | divinity(5)\n initiative: numberField(1, { min: 0 }),\n anti_initiative: numberField(24, { min: 0 }),\n aptitudes: new fields.SchemaField({\n physical: aptitudeField(),\n martial: aptitudeField(),\n mental: aptitudeField(),\n social: aptitudeField(),\n spiritual: aptitudeField(),\n }),\n vitality: trackedField(),\n hei: trackedField(),\n description: htmlField(\"\"),\n prefs: new fields.SchemaField({\n typeofthrow: new fields.SchemaField({\n check: boolField(false),\n choice: stringField(\"0\"),\n }),\n }),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class EquipmentDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const numberField = (initial = 0, extra = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...extra })\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n quantity: numberField(1, { min: 0 }),\n weight: numberField(0, { min: 0 }),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class KungfuDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const boolField = (initial = false) => new fields.BooleanField({ required: true, initial })\n\n const techniqueField = () =>\n new fields.SchemaField({\n check: boolField(false),\n name: stringField(\"\"),\n activation: stringField(\"action-attack\"), // action-attack | action-defense | action-aid | action-attack-defense | reaction | dice | damage-inflicted | damage-received\n technique: htmlField(\"\"),\n })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n orientation: stringField(\"yin\"), // yin | yang | yinyang\n aspect: stringField(\"metal\"), // metal | eau | terre | feu | bois\n skill: stringField(\"kungfu\"), // kungfu | rangedcombat\n speciality: stringField(\"\"),\n style: stringField(\"\"),\n techniques: new fields.SchemaField({\n technique1: techniqueField(),\n technique2: techniqueField(),\n technique3: techniqueField(),\n }),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class SpellDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n specialityname: stringField(\"\"),\n associatedelement: stringField(\"metal\"), // metal | eau | terre | feu | bois\n hei: stringField(\"\"),\n realizationtimeritual: stringField(\"\"),\n realizationtimeaccelerated: stringField(\"\"),\n flashback: stringField(\"\"),\n components: htmlField(\"\"),\n effects: htmlField(\"\"),\n examples: htmlField(\"\"),\n notes: htmlField(\"\"),\n discipline: stringField(\"internalcinnabar\"),\n heiType: stringField(\"yin\"),\n heiCost: new fields.NumberField({ required: true, nullable: false, integer: true, min: 0, initial: 1 }),\n difficulty: new fields.NumberField({ required: true, nullable: false, integer: true, min: 0, initial: 1 }),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class SupernaturalDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n notes: htmlField(\"\"),\n heiType: stringField(\"yin\"),\n heiCost: new fields.NumberField({ required: true, nullable: false, integer: true, min: 0, initial: 0 }),\n trigger: stringField(\"\"),\n effects: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class WeaponDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n weaponType: stringField(\"melee\"),\n material: stringField(\"\"),\n damageAspect: stringField(\"metal\"),\n damageBase: intField(1),\n range: stringField(\"contact\"), // contact | courte | mediane | longue | extreme\n obtainLevel: intField(0, { min: 0, max: 5 }),\n obtainDifficulty: intField(0, { min: 0, max: 3 }),\n quantity: intField(1),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class ArmorDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n protectionValue: intField(0),\n domain: stringField(\"\"),\n obtainLevel: intField(0, { min: 0, max: 5 }),\n obtainDifficulty: intField(0, { min: 0, max: 3 }),\n quantity: intField(1),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class SanheiDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n const propertySchema = () => new fields.SchemaField({\n name: stringField(\"\"),\n heiCost: intField(0),\n heiType: stringField(\"yin\"),\n description: htmlField(\"\"),\n })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n heiType: stringField(\"yin\"),\n properties: new fields.SchemaField({\n prop1: propertySchema(),\n prop2: propertySchema(),\n prop3: propertySchema(),\n }),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class IngredientDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n school: stringField(\"all\"),\n obtainLevel: intField(0, { min: 0, max: 5 }),\n obtainDifficulty: intField(0, { min: 0, max: 3 }),\n quantity: intField(1),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport class CDEMessage extends ChatMessage {\n async renderHTML({ canDelete, canClose = false, ...rest } = {}) {\n const html = await super.renderHTML({ canDelete, canClose, ...rest })\n this.#enrichChatCard(html)\n return html\n }\n\n getAssociatedActor() {\n if (this.speaker.scene && this.speaker.token) {\n const scene = game.scenes.get(this.speaker.scene)\n const token = scene?.tokens.get(this.speaker.token)\n if (token) return token.actor\n }\n return game.actors.get(this.speaker.actor)\n }\n\n #enrichChatCard(html) {\n const actor = this.getAssociatedActor()\n\n let img\n let nameText\n if (this.isContentVisible) {\n img = actor?.img ?? this.author.avatar\n nameText = this.alias\n } else {\n img = this.author.avatar\n nameText = this.author.name\n }\n\n const avatar = document.createElement(\"a\")\n avatar.classList.add(\"avatar\")\n if (actor) avatar.dataset.uuid = actor.uuid\n const avatarImg = document.createElement(\"img\")\n Object.assign(avatarImg, { src: img, alt: nameText })\n avatar.append(avatarImg)\n\n const name = document.createElement(\"span\")\n name.classList.add(\"name-stacked\")\n const title = document.createElement(\"span\")\n title.classList.add(\"title\")\n title.append(nameText)\n name.append(title)\n\n const sender = html.querySelector(\".message-sender\")\n sender?.replaceChildren(avatar, name)\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { ACTOR_TYPES } from \"../config/constants.js\"\n\nexport class CDEActor extends Actor {\n getRollData() {\n const data = this.toObject(false).system\n return data\n }\n\n prepareBaseData() {\n super.prepareBaseData()\n\n if (this.type === ACTOR_TYPES.character) {\n this.system.anti_initiative = 25 - (this.system.initiative ?? 0)\n }\n\n if (this.type === ACTOR_TYPES.npc) {\n this.system.vitality.calcul = (this.system.aptitudes.physical.value ?? 0) * 4\n this.system.hei.calcul = (this.system.aptitudes.spiritual.value ?? 0) * 4\n this.system.anti_initiative = 25 - (this.system.initiative ?? 0)\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/** Default icons per item type. */\nconst DEFAULT_ICONS = {\n kungfu: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-kungfu.svg\",\n spell: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-spell.svg\",\n supernatural: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-supernatural.svg\",\n weapon: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-weapon.svg\",\n armor: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-armor.svg\",\n sanhei: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-sanhei.svg\",\n ingredient: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-ingredient.svg\",\n item: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-item.svg\",\n};\n\nexport class CDEItem extends Item {\n\n /** @override */\n async _preCreate(data, options, userId) {\n await super._preCreate(data, options, userId);\n const defaultIcon = DEFAULT_ICONS[this.type];\n if (defaultIcon && (!data.img || data.img === Item.DEFAULT_ICON)) {\n this.updateSource({ img: defaultIcon });\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nconst DIGIT_LABELS = [\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-1.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-2.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-3.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-4.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-5.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-6.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-7.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-8.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-9.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-10.webp\",\n]\n\nconst CLASSIC_LABELS = [\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-1.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-2.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-3.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-4.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-5.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-6.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-7.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-8.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-9.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-10.webp\",\n]\n\nexport function registerDice() {\n Hooks.once(\"diceSoNiceReady\", (dice3d) => {\n dice3d.addColorset(\n {\n name: \"cde\",\n description: \"CdE\",\n foreground: \"#000000\",\n background: \"#ffffff\",\n edge: \"#ffffff\",\n font: \"DeliusUnicase\",\n texture: \"ice\",\n material: \"plastic\",\n },\n \"preferred\",\n )\n\n dice3d.addSystem({ id: \"fvtt-chroniques-de-l-etrangedigit\", name: \"Chroniques de l'\u00E9trange digits\" }, \"preferred\")\n dice3d.addDicePreset({ type: \"d10\", labels: DIGIT_LABELS, system: \"fvtt-chroniques-de-l-etrangedigit\" })\n\n dice3d.addSystem({ id: \"fvtt-chroniques-de-l-etrange\", name: \"Chroniques de l'\u00E9trange\" }, \"preferred\")\n dice3d.addDicePreset({ type: \"d10\", labels: CLASSIC_LABELS, system: \"fvtt-chroniques-de-l-etrange\" })\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { MAGICS } from \"../config/constants.js\"\n\nexport function registerHandlebarsHelpers() {\n const { Handlebars } = globalThis\n if (!Handlebars) return\n\n Handlebars.registerHelper(\"select\", function (selected, options) {\n const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected))\n const rgx = new RegExp(` value=[\"']${escapedValue}[\"']`)\n const html = options.fn(this)\n return html.replace(rgx, \"$& selected\")\n })\n\n Handlebars.registerHelper(\"getMagicBackground\", function (magic) {\n return game.i18n.localize(MAGICS[magic]?.background ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicLabel\", function (magic) {\n return game.i18n.localize(MAGICS[magic]?.label ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicAspectLabel\", function (magic) {\n return game.i18n.localize(MAGICS[magic]?.aspectlabel ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityLabel\", function (magic, speciality) {\n return game.i18n.localize(MAGICS[magic]?.speciality?.[speciality]?.label ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityClassIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.classicon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.icon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityElementIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.elementicon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityLabelIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.labelicon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityLabelElement\", function (magic, speciality) {\n return game.i18n.localize(MAGICS[magic]?.speciality?.[speciality]?.labelelement ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicAspectIcon\", function (magic) {\n const icons = {\n internalcinnabar: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\",\n alchemy: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n masteryoftheway: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n exorcism: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n geomancy: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n }\n return icons[magic] ?? \"\"\n })\n\n Handlebars.registerHelper(\"getElementIcon\", function (aspect) {\n const icons = {\n metal: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\",\n water: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n earth: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n fire: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n wood: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n // legacy French keys\n eau: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n terre: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n feu: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n bois: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n }\n return icons[aspect] ?? \"\"\n })\n\n Handlebars.registerHelper(\"getOrientationIcon\", function (orientation) {\n const icons = {\n yin: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\",\n yang: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\",\n yinyang: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\",\n }\n return icons[orientation] ?? \"\"\n })\n\n Handlebars.registerHelper(\"getOrientationLabel\", function (orientation) {\n const keys = {\n yin: \"CDE.OrientationYin\",\n yang: \"CDE.OrientationYang\",\n yinyang: \"CDE.OrientationYinYang\",\n }\n return game.i18n.localize(keys[orientation] ?? \"CDE.Orientation\")\n })\n\n Handlebars.registerHelper(\"getActivationLabel\", function (activation) {\n const keys = {\n \"action-attack\": \"CDE.ActivationAttack\",\n \"action-defense\": \"CDE.ActivationDefense\",\n \"action-aid\": \"CDE.ActivationAid\",\n \"action-attack-defense\": \"CDE.ActivationAttackOrDefense\",\n reaction: \"CDE.ActivationReaction\",\n dice: \"CDE.ActivationDice\",\n \"damage-inflicted\": \"CDE.ActivationDamageInflicted\",\n \"damage-received\": \"CDE.ActivationDamageReceived\",\n }\n return game.i18n.localize(keys[activation] ?? \"CDE.Activation\")\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { TEMPLATE_PARTIALS } from \"../config/constants.js\"\n\nexport async function preloadPartials() {\n return foundry.applications.handlebars.loadTemplates(TEMPLATE_PARTIALS)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Initiative determination system for Chroniques de l'\u00C9trange.\n *\n * PJ formula: Initiative = Prouesse + Premi\u00E8re action (comp\u00E9tence/ressource/magie)\n * PNJ formula: Initiative = Aptitude physique + Premi\u00E8re action (aptitude)\n *\n * Range 1-24 ; anti-initiative = 25 \u2212 initiative.\n * Combat order is ascending (low initiative acts first).\n */\n\nconst PC_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-initiative-prompt.html\"\nconst NPC_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-initiative-prompt-npc.html\"\nconst RESULT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-initiative-result.html\"\n\n/** Skills, resources and magics available as \"premi\u00E8re action\" for a PC. */\nfunction buildPCOptions(sys) {\n const sk = sys.skills ?? {}\n const rs = sys.resources ?? {}\n const mg = sys.magics ?? {}\n return [\n { key: \"art\", label: game.i18n.localize(\"CDE.Art\"), value: sk.art?.value ?? 0 },\n { key: \"investigation\", label: game.i18n.localize(\"CDE.Investigation\"), value: sk.investigation?.value ?? 0 },\n { key: \"erudition\", label: game.i18n.localize(\"CDE.Erudition\"), value: sk.erudition?.value ?? 0 },\n { key: \"knavery\", label: game.i18n.localize(\"CDE.Knavery\"), value: sk.knavery?.value ?? 0 },\n { key: \"wordliness\", label: game.i18n.localize(\"CDE.Wordliness\"), value: sk.wordliness?.value ?? 0 },\n { key: \"prowess\", label: game.i18n.localize(\"CDE.Prowess\"), value: sk.prowess?.value ?? 0 },\n { key: \"sciences\", label: game.i18n.localize(\"CDE.Sciences\"), value: sk.sciences?.value ?? 0 },\n { key: \"technologies\", label: game.i18n.localize(\"CDE.Technologies\"), value: sk.technologies?.value ?? 0 },\n { key: \"kungfu\", label: game.i18n.localize(\"CDE.KungFu\"), value: sk.kungfu?.value ?? 0 },\n { key: \"rangedcombat\", label: game.i18n.localize(\"CDE.RangedCombat\"), value: sk.rangedcombat?.value ?? 0 },\n { key: \"supply\", label: game.i18n.localize(\"CDE.Supply\"), value: rs.supply?.value ?? 0 },\n { key: \"inquiry\", label: game.i18n.localize(\"CDE.Inquiry\"), value: rs.inquiry?.value ?? 0 },\n { key: \"influence\", label: game.i18n.localize(\"CDE.Influence\"), value: rs.influence?.value ?? 0 },\n { key: \"internalcinnabar\", label: game.i18n.localize(\"CDE.InternalCinnabar\"), value: mg.internalcinnabar?.value ?? 0 },\n { key: \"alchemy\", label: game.i18n.localize(\"CDE.Alchemy\"), value: mg.alchemy?.value ?? 0 },\n { key: \"masteryoftheway\", label: game.i18n.localize(\"CDE.MasteryOfTheWay\"), value: mg.masteryoftheway?.value ?? 0 },\n { key: \"exorcism\", label: game.i18n.localize(\"CDE.Exorcism\"), value: mg.exorcism?.value ?? 0 },\n { key: \"geomancy\", label: game.i18n.localize(\"CDE.Geomancy\"), value: mg.geomancy?.value ?? 0 },\n ]\n}\n\n/** Aptitudes available as \"premi\u00E8re action\" for an NPC. */\nfunction buildNPCOptions(sys) {\n const ap = sys.aptitudes ?? {}\n return [\n { key: \"physical\", label: game.i18n.localize(\"CDE.Physical\"), value: ap.physical?.value ?? 0 },\n { key: \"martial\", label: game.i18n.localize(\"CDE.Martial\"), value: ap.martial?.value ?? 0 },\n { key: \"mental\", label: game.i18n.localize(\"CDE.Mental\"), value: ap.mental?.value ?? 0 },\n { key: \"social\", label: game.i18n.localize(\"CDE.Social\"), value: ap.social?.value ?? 0 },\n { key: \"spiritual\", label: game.i18n.localize(\"CDE.Spiritual\"), value: ap.spiritual?.value ?? 0 },\n ]\n}\n\n/** Parse the dialog element and extract firstaction + modifier. */\nfunction readInitFields(dialog) {\n const root = dialog.element ?? dialog\n const selectedKey = root.querySelector(\"select[name='firstaction']\")?.value ?? \"\"\n const modifier = parseInt(root.querySelector(\"input[name='modifier']\")?.value ?? \"0\", 10) || 0\n return { selectedKey, modifier }\n}\n\n/** Post a styled initiative chat message. */\nasync function sendInitChatMessage({ actor, baseName, baseValue, actionName, actionValue, modifier, initiative, antiInitiative }) {\n const html = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE, {\n actorName: actor.name,\n actorImg: actor.img,\n baseName,\n baseValue,\n actionName,\n actionValue,\n modifier,\n hasModifier: modifier !== 0,\n initiative,\n antiInitiative,\n })\n await ChatMessage.create({\n user: game.user.id,\n speaker: ChatMessage.getSpeaker({ actor }),\n content: html,\n })\n}\n\n/**\n * Open the PC initiative dialog, compute initiative (Prouesse + Premi\u00E8re action + modificateur)\n * and update the actor, then post a chat card.\n */\nexport async function rollInitiativePC(actor) {\n const sys = actor.system\n const prowess = sys.skills?.prowess?.value ?? 0\n const options = buildPCOptions(sys)\n const baseName = game.i18n.localize(\"CDE.Prowess\")\n\n const content = await foundry.applications.handlebars.renderTemplate(PC_PROMPT_TEMPLATE, {\n prowessValue: prowess,\n options,\n modifier: 0,\n })\n\n const result = await foundry.applications.api.DialogV2.prompt({\n window: { title: game.i18n.localize(\"CDE.InitiativeRoll\") },\n content,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (_ev, _btn, dialog) => readInitFields(dialog),\n },\n })\n if (!result) return\n\n const { selectedKey, modifier } = result\n const selected = options.find((o) => o.key === selectedKey) ?? options[0]\n const rawValue = prowess + selected.value + modifier\n const initiative = Math.max(1, Math.min(24, rawValue))\n const antiInit = 25 - initiative\n\n await actor.update({ \"system.initiative\": initiative })\n await sendInitChatMessage({\n actor,\n baseName,\n baseValue: prowess,\n actionName: selected.label,\n actionValue: selected.value,\n modifier,\n initiative,\n antiInitiative: antiInit,\n })\n}\n\n/**\n * Open the NPC initiative dialog, compute initiative (Aptitude physique + Premi\u00E8re action + modificateur)\n * and update the actor, then post a chat card.\n */\nexport async function rollInitiativeNPC(actor) {\n const sys = actor.system\n const physical = sys.aptitudes?.physical?.value ?? 0\n const options = buildNPCOptions(sys)\n const baseName = game.i18n.localize(\"CDE.Physical\")\n\n const content = await foundry.applications.handlebars.renderTemplate(NPC_PROMPT_TEMPLATE, {\n physicalValue: physical,\n options,\n modifier: 0,\n })\n\n const result = await foundry.applications.api.DialogV2.prompt({\n window: { title: game.i18n.localize(\"CDE.InitiativeRoll\") },\n content,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (_ev, _btn, dialog) => readInitFields(dialog),\n },\n })\n if (!result) return\n\n const { selectedKey, modifier } = result\n const selected = options.find((o) => o.key === selectedKey) ?? options[0]\n const rawValue = physical + selected.value + modifier\n const initiative = Math.max(1, Math.min(24, rawValue))\n const antiInit = 25 - initiative\n\n await actor.update({ \"system.initiative\": initiative })\n await sendInitChatMessage({\n actor,\n baseName,\n baseValue: physical,\n actionName: selected.label,\n actionValue: selected.value,\n modifier,\n initiative,\n antiInitiative: antiInit,\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Loksyu / TinJi settings-based helpers.\n *\n * Data is stored as world settings instead of singleton Actor documents.\n */\n\nimport { SYSTEM_ID, WU_XING_CYCLE, ASPECT_FACES } from \"../../config/constants.js\"\n\n/** Read the current loksyu data object from world settings */\nexport function getLoksyuData() {\n return game.settings.get(SYSTEM_ID, \"loksyuData\") ?? {\n wood: {yin:0,yang:0}, fire: {yin:0,yang:0}, earth: {yin:0,yang:0}, metal: {yin:0,yang:0}, water: {yin:0,yang:0},\n }\n}\n\n/** Write the loksyu data object to world settings */\nexport async function setLoksyuData(data) {\n await game.settings.set(SYSTEM_ID, \"loksyuData\", data)\n Hooks.callAll(\"cde:loksyuUpdated\", data)\n}\n\n/** Read current TinJi value from world settings */\nexport function getTinjiValue() {\n return game.settings.get(SYSTEM_ID, \"tinjiData\") ?? 0\n}\n\n/** Write TinJi value to world settings */\nexport async function setTinjiValue(value) {\n await game.settings.set(SYSTEM_ID, \"tinjiData\", Math.max(0, value))\n Hooks.callAll(\"cde:tinjiUpdated\", Math.max(0, value))\n}\n\n/**\n * After a WuXing roll, add the loksyu faces (yin + yang) of the relevant\n * aspect to the loksyu settings data.\n *\n * @param {string} activeAspect - e.g. \"fire\"\n * @param {Object} faces - Die face counts { 0: n, 1: n, \u2026, 9: n }\n */\nexport async function updateLoksyuFromRoll(activeAspect, faces) {\n const cycle = WU_XING_CYCLE[activeAspect]\n if (!cycle) return\n\n const lokAspect = cycle[3]\n const [yinFace, yangFace] = ASPECT_FACES[lokAspect] ?? []\n if (yinFace === undefined) return\n\n const yinCount = faces[yinFace] ?? 0\n const yangCount = faces[yangFace] ?? 0\n if (yinCount === 0 && yangCount === 0) return\n\n const data = getLoksyuData()\n const current = data[lokAspect] ?? { yin: 0, yang: 0 }\n data[lokAspect] = {\n yin: (current.yin ?? 0) + yinCount,\n yang: (current.yang ?? 0) + yangCount,\n }\n await setLoksyuData(data)\n}\n\n/**\n * After a WuXing roll, add tinji faces to the TinJi settings.\n *\n * @param {number} count - Number of tinji faces rolled\n */\nexport async function updateTinjiFromRoll(count) {\n if (!count || count <= 0) return\n const current = getTinjiValue()\n await setTinjiValue(current + count)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Wu Xing rolling system for Chroniques de l'\u00C9trange.\n *\n * The Wu Xing cycle maps each aspect (by index 0-4) to die face groups:\n * - metal=0 : faces 3,8\n * - water=1 : faces 1,6\n * - earth=2 : faces 0/10,5\n * - fire=3 : faces 2,7\n * - wood=4 : faces 4,9\n *\n * For a given active aspect the five result categories are:\n * successes / auspicious / noxious / loksyu (yin face, yang face) / tinji\n * Each category is associated with one of the five aspects in Wu Xing cycle order.\n */\n\nimport { MAGICS, ASPECT_LABELS, ASPECT_ICONS, ASPECT_FACES, ASPECT_NAMES, WU_XING_CYCLE } from \"../config/constants.js\"\nimport { updateLoksyuFromRoll, updateTinjiFromRoll } from \"./apps/singletons.js\"\n\nconst RESULT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-dice-result.html\"\nconst SKILL_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-skill-dice-prompt.html\"\nconst SKILL_SPECIAL_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-skill-special-dice-prompt.html\"\nconst MAGIC_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-magic-dice-prompt.html\"\nconst WEAPON_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-weapon-dice-prompt.html\"\n\n/** Maps i18n element label \u2192 aspect name (for speciality default aspect lookup) */\nconst LABELELEMENT_TO_ASPECT = {\n \"CDE.Metal\": \"metal\",\n \"CDE.Water\": \"water\",\n \"CDE.Earth\": \"earth\",\n \"CDE.Fire\": \"fire\",\n \"CDE.Wood\": \"wood\",\n}\n\n/** Maps weapon range string \u2192 dice malus applied to the attack pool */\nconst RANGE_MALUS = {\n contact: 0,\n courte: 0,\n mediane: -1,\n longue: -2,\n extreme: -3,\n}\n\n/** Maps weapon type string \u2192 default skill key */\nconst WEAPON_TYPE_SKILL = {\n melee: \"kungfu\",\n thrown: \"rangedcombat\",\n ranged: \"rangedcombat\",\n firearm: \"rangedcombat\",\n}\n\n/** Maps weapon damageAspect name \u2192 ASPECT_NAMES index */\nconst WEAPON_ASPECT_INDEX = { metal: 0, eau: 1, water: 1, terre: 2, earth: 2, feu: 3, fire: 3, bois: 4, wood: 4 }\n\n/** Count how many times each die face appeared in the roll results */\nfunction countFaces(rollResults) {\n const counts = { 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 0:0 }\n for (const die of rollResults) {\n const face = die.result === 10 ? 0 : die.result\n counts[face]++\n }\n return counts\n}\n\n/**\n * Compute Wu Xing result categories from face counts and active aspect.\n * Returns { successesdice, auspiciousdice, noxiousdice, loksyudice, tinjidice, loksyurepartition }\n */\nfunction computeWuXingResults(faces, aspectName, bonusAuspicious = 0) {\n const cycle = WU_XING_CYCLE[aspectName]\n if (!cycle) return null\n\n const [succAspect, ausAspect, noxAspect, lokAspect, tinAspect] = cycle\n const [succYin, succYang] = ASPECT_FACES[succAspect]\n const [ausYin, ausYang] = ASPECT_FACES[ausAspect]\n const [noxYin, noxYang] = ASPECT_FACES[noxAspect]\n const [lokYin, lokYang] = ASPECT_FACES[lokAspect]\n const [tinYin, tinYang] = ASPECT_FACES[tinAspect]\n\n const yin = game.i18n.localize(\"CDE.Yin\")\n const yang = game.i18n.localize(\"CDE.Yang\")\n\n return {\n successesdice: faces[succYin] + faces[succYang],\n auspiciousdice: faces[ausYin] + faces[ausYang] + bonusAuspicious,\n noxiousdice: faces[noxYin] + faces[noxYang],\n loksyudice: faces[lokYin] + faces[lokYang],\n loksyurepartition: `[${yin}(${faces[lokYin]}) ${yang}(${faces[lokYang]})]`,\n tinjidice: faces[tinYin] + faces[tinYang],\n }\n}\n\n/** Read a named field from a dialog DOM element */\nfunction readField(dlg, name) {\n const el = dlg.querySelector(`[name=\"${name}\"]`)\n if (!el) return null\n return el.type === \"checkbox\" ? el.checked : el.value\n}\n\n/**\n * Open a DialogV2.prompt with the given template + data and return the resolved form values.\n * The callback receives the DialogV2 application instance; fields are read from its .element.\n * @returns {Promise|null>}\n */\nasync function showRollPrompt({ title, template, data, fields }) {\n const content = await foundry.applications.handlebars.renderTemplate(template, data)\n return foundry.applications.api.DialogV2.prompt({\n window: { title },\n content,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (event, button, dialog) => {\n // In AppV2, dialog is the application instance; .element is the root HTMLElement\n const root = dialog.element ?? dialog\n const result = {}\n for (const field of fields) {\n result[field] = readField(root, field)\n }\n return result\n },\n },\n })\n}\n\n/**\n * Open the skill roll prompt and return the user-confirmed parameters.\n * @param {object} params - Initial values\n * @returns {Promise}\n */\nasync function showSkillPrompt(params) {\n return showRollPrompt({\n title: params.title,\n template: params.isSpecial ? SKILL_SPECIAL_PROMPT_TEMPLATE : SKILL_PROMPT_TEMPLATE,\n data: {\n numberofdice: params.numberofdice,\n aspect: Number(params.aspect ?? 0),\n bonusmalus: params.bonusmalus ?? 0,\n woundmalus: params.woundmalus ?? 0,\n bonusauspiciousdice: params.bonusauspiciousdice ?? 0,\n typeofthrow: Number(params.typeofthrow ?? 0),\n },\n fields: [\"aspect\", \"bonusmalus\", \"woundmalus\", \"bonusauspiciousdice\", \"typeofthrow\"],\n })\n}\n\n/**\n * Open the magic roll prompt and return the user-confirmed parameters.\n */\nasync function showMagicPrompt(params) {\n return showRollPrompt({\n title: params.title,\n template: MAGIC_PROMPT_TEMPLATE,\n data: {\n numberofdice: params.numberofdice ?? 0,\n aspectskill: Number(params.aspectskill ?? 0),\n bonusmalusskill: params.bonusmalusskill ?? 0,\n bonusauspiciousdice: params.bonusauspiciousdice ?? 0,\n aspectspeciality: Number(params.aspectspeciality ?? 0),\n rolldifficulty: params.rolldifficulty ?? 1,\n bonusmalusspeciality: params.bonusmalusspeciality ?? 0,\n heispend: params.heispend ?? 0,\n typeofthrow: Number(params.typeofthrow ?? 0),\n },\n fields: [\"aspectskill\", \"bonusmalusskill\", \"bonusauspiciousdice\",\n \"aspectspeciality\", \"rolldifficulty\", \"bonusmalusspeciality\",\n \"heispend\", \"typeofthrow\"],\n })\n}\n\n/**\n * Open the weapon attack roll prompt and return user-confirmed parameters.\n */\nasync function showWeaponPrompt(params) {\n return showRollPrompt({\n title: params.title,\n template: WEAPON_PROMPT_TEMPLATE,\n data: {\n numberofdice: params.numberofdice ?? 0,\n weaponName: params.weaponName ?? \"\",\n weaponTypeLabel: params.weaponTypeLabel ?? \"CDE.Weapon\",\n weaponAspectIcon: params.weaponAspectIcon ?? \"\",\n weaponAspectLabel: params.weaponAspectLabel ?? \"\",\n damageBase: params.damageBase ?? 1,\n weaponskill: params.weaponskill ?? \"kungfu\",\n aspect: Number(params.aspect ?? 0),\n effectiverange: params.effectiverange ?? \"contact\",\n bonusmalus: params.bonusmalus ?? 0,\n woundmalus: params.woundmalus ?? 0,\n bonusauspiciousdice: params.bonusauspiciousdice ?? 0,\n typeofthrow: Number(params.typeofthrow ?? 0),\n },\n fields: [\"weaponskill\", \"aspect\", \"effectiverange\", \"bonusmalus\", \"woundmalus\",\n \"bonusauspiciousdice\", \"typeofthrow\"],\n })\n}\n\n/**\n * Build and send a single enriched ChatMessage containing both the roll\n * (for Dice So Nice) and the Wu Xing result card.\n */\nasync function sendResultMessage(actor, resultData, roll, rollMode) {\n const html = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE, resultData)\n return ChatMessage.create({\n user: game.user.id,\n speaker: ChatMessage.getSpeaker({ actor }),\n content: html,\n rolls: [roll],\n rollMode,\n flags: {\n \"fvtt-chroniques-de-l-etrange\": { rollResult: { ...resultData } },\n },\n })\n}\n\nconst ROLL_MODES = [\"roll\", \"gmroll\", \"blindroll\", \"selfroll\"]\n\n/**\n * Main entry point: roll dice for a given actor.\n *\n * @param {Actor} actor\n * @param {string} rollKey - e.g. \"prowess-skill\", \"fire-aspect\", \"alchemy-magic-elixirs\"\n */\nexport async function rollForActor(actor, rollKey) {\n const parts = rollKey.split(\"-\")\n const skillLibel = parts[0]\n const typeLibel = parts[1]\n const specialLibel = parts[2] ?? null\n\n const sys = actor.system\n const typeOfThrow = Number(sys.prefs?.typeofthrow?.choice ?? 0)\n\n let numberofdice = 0\n let title = \"\"\n let isSpecial = false\n let isMagic = false\n let isMagicSpecial = false\n let kfDefaultAspect = -1 // set in \"itemkungfu\" case, used when computing defaultAspect\n\n // ---- Determine dice count + title ----\n const MAGIC_I18N_KEYS = {\n internalcinnabar: \"CDE.InternalCinnabar\",\n alchemy: \"CDE.Alchemy\",\n masteryoftheway: \"CDE.MasteryOfTheWay\",\n exorcism: \"CDE.Exorcism\",\n geomancy: \"CDE.Geomancy\",\n }\n\n switch (typeLibel) {\n case \"aspect\":\n numberofdice = sys.aspect[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.aspect[skillLibel]?.label ?? \"CDE.Roll\")\n break\n case \"aptitude\":\n // NPC aptitude roll \u2014 flat pool with WuXing prompt\n numberofdice = sys.aptitudes?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(`CDE.${skillLibel.charAt(0).toUpperCase() + skillLibel.slice(1)}`)\n break\n case \"skill\":\n numberofdice = sys.skills?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.skills?.[skillLibel]?.label ?? \"CDE.Roll\")\n break\n case \"special\":\n numberofdice = sys.skills?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.skills?.[skillLibel]?.label ?? \"CDE.Roll\")\n title += ` [${game.i18n.localize(\"CDE.Speciality\")}]`\n isSpecial = true\n if (!sys.skills?.[skillLibel]?.specialities) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error2\"))\n return\n }\n break\n case \"resource\":\n numberofdice = sys.resources?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.resources?.[skillLibel]?.label ?? \"CDE.Roll\")\n break\n case \"field\":\n numberofdice = sys.resources?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.resources?.[skillLibel]?.label ?? \"CDE.Roll\")\n title += ` [${game.i18n.localize(\"CDE.Field\")}]`\n isSpecial = true\n if (!sys.resources?.[skillLibel]?.specialities) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error4\"))\n return\n }\n break\n case \"magic\":\n numberofdice = sys.magics?.[skillLibel]?.value ?? 0\n isMagic = true\n title = game.i18n.localize(MAGIC_I18N_KEYS[skillLibel] ?? \"CDE.Magics\")\n break\n case \"magicspecial\":\n numberofdice = sys.magics?.[skillLibel]?.value ?? 0\n isMagicSpecial = true\n isMagic = true\n if (!sys.magics?.[skillLibel]?.speciality?.[specialLibel]?.check) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error6\"))\n return\n }\n title = `${game.i18n.localize(MAGIC_I18N_KEYS[skillLibel] ?? \"CDE.Magics\")} [${game.i18n.localize(MAGICS?.[skillLibel]?.speciality?.[specialLibel]?.label ?? \"\")}]`\n break\n case \"itemkungfu\": {\n // skillLibel = item._id \u2014 look up the kungfu item to find which skill + aspect to use\n const kfItem = actor.items.get(skillLibel)\n if (!kfItem) { ui.notifications.warn(game.i18n.localize(\"CDE.Error0\")); return }\n const kfSkill = kfItem.system.skill ?? \"kungfu\"\n numberofdice = sys.skills?.[kfSkill]?.value ?? 0\n title = `${kfItem.name} [${game.i18n.localize(sys.skills?.[kfSkill]?.label ?? \"CDE.KungFu\")}]`\n kfDefaultAspect = ASPECT_NAMES.indexOf(kfItem.system.aspect ?? \"metal\")\n if (kfDefaultAspect < 0) kfDefaultAspect = 0\n break\n }\n case \"itemweapon\": {\n // skillLibel = item._id \u2014 look up the weapon item to find type + aspect + damage\n const wpItem = actor.items.get(skillLibel)\n if (!wpItem) { ui.notifications.warn(game.i18n.localize(\"CDE.Error0\")); return }\n\n const wpType = wpItem.system.weaponType ?? \"melee\"\n const wpSkill = WEAPON_TYPE_SKILL[wpType] ?? \"kungfu\"\n numberofdice = sys.skills?.[wpSkill]?.value ?? 0\n\n const wpAspectRaw = wpItem.system.damageAspect ?? \"metal\"\n const wpAspectIdx = WEAPON_ASPECT_INDEX[wpAspectRaw] ?? 0\n const wpRange = wpItem.system.range ?? \"contact\"\n\n const WEAPON_TYPE_LABELS = {\n melee: \"CDE.WeaponMelee\",\n thrown: \"CDE.WeaponThrown\",\n ranged: \"CDE.WeaponRanged\",\n firearm: \"CDE.WeaponFirearm\",\n }\n\n // Show weapon-specific prompt\n const wParams = await showWeaponPrompt({\n title: `${wpItem.name} [${game.i18n.localize(sys.skills?.[wpSkill]?.label ?? \"CDE.WeaponRoll\")}]`,\n numberofdice,\n weaponName: wpItem.name,\n weaponTypeLabel: WEAPON_TYPE_LABELS[wpType] ?? \"CDE.Weapon\",\n weaponAspectIcon: ASPECT_ICONS[ASPECT_NAMES[wpAspectIdx]] ?? \"\",\n weaponAspectLabel: game.i18n.localize(ASPECT_LABELS[ASPECT_NAMES[wpAspectIdx]] ?? \"\"),\n damageBase: wpItem.system.damageBase ?? 1,\n weaponskill: wpSkill,\n aspect: wpAspectIdx,\n effectiverange: wpRange,\n bonusmalus: 0,\n woundmalus: 0,\n bonusauspiciousdice: 0,\n typeofthrow: typeOfThrow,\n })\n\n if (!wParams) return // cancelled\n\n // Resolve final pool from weapon prompt values\n const wpChosenSkill = wParams.weaponskill ?? wpSkill\n const wpSkillDice = sys.skills?.[wpChosenSkill]?.value ?? 0\n const wpAspFinal = Number(wParams.aspect ?? wpAspectIdx)\n const wpAspectDice = sys.aspect[ASPECT_NAMES[wpAspFinal]]?.value ?? 0\n const wpRangeMalus = RANGE_MALUS[wParams.effectiverange ?? \"contact\"] ?? 0\n const wpBonusMalus = Number(wParams.bonusmalus ?? 0)\n const wpWoundMalus = Number(wParams.woundmalus ?? 0)\n const wpBonusAusp = Number(wParams.bonusauspiciousdice ?? 0)\n const wpThrowMode = Number(wParams.typeofthrow ?? 0)\n const wpDamageBase = wpItem.system.damageBase ?? 1\n\n const wpTotalDice = wpSkillDice + wpAspectDice + wpRangeMalus + wpBonusMalus - wpWoundMalus\n if (wpTotalDice <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error0\"))\n return\n }\n\n const wpRoll = new Roll(`${wpTotalDice}d10`)\n await wpRoll.evaluate()\n\n const wpAspectName = ASPECT_NAMES[wpAspFinal] ?? \"metal\"\n const wpFaces = countFaces(wpRoll.dice[0]?.results ?? [])\n const wpResults = computeWuXingResults(wpFaces, wpAspectName, wpBonusAusp)\n if (!wpResults) return\n\n const wpModParts = []\n if (wpRangeMalus !== 0) wpModParts.push(`${wpRangeMalus} ${game.i18n.localize(\"CDE.RangePenalty\")}`)\n if (wpBonusMalus !== 0) wpModParts.push(`${wpBonusMalus > 0 ? \"+\" : \"\"}${wpBonusMalus} ${game.i18n.localize(\"CDE.BonusMalus\")}`)\n if (wpWoundMalus !== 0) wpModParts.push(`-${wpWoundMalus} ${game.i18n.localize(\"CDE.WoundMalus\")}`)\n if (wpBonusAusp !== 0) wpModParts.push(`+${wpBonusAusp} ${game.i18n.localize(\"CDE.BonusAuspiciousDice\")}`)\n\n const wpMsg = await sendResultMessage(actor, {\n rollLabel: `${wpItem.name}`,\n aspectName: wpAspectName,\n aspectLabel: game.i18n.localize(ASPECT_LABELS[wpAspectName] ?? \"\"),\n aspectIcon: ASPECT_ICONS[wpAspectName] ?? \"\",\n totalDice: wpTotalDice,\n modifiersText: wpModParts.length ? wpModParts.join(\" \u00B7 \") : \"\",\n spellPower: null,\n rollDifficulty: null,\n actorName: actor.name ?? \"\",\n actorImg: actor.img ?? \"\",\n // weapon-specific\n weaponName: wpItem.name,\n damageBase: wpDamageBase,\n totalDamage: wpResults.successesdice * wpDamageBase,\n ...wpResults,\n aspect: wpAspectName,\n d1: wpFaces[1], d2: wpFaces[2], d3: wpFaces[3], d4: wpFaces[4], d5: wpFaces[5],\n d6: wpFaces[6], d7: wpFaces[7], d8: wpFaces[8], d9: wpFaces[9], d0: wpFaces[0],\n }, wpRoll, ROLL_MODES[wpThrowMode] ?? \"roll\")\n\n if (game.modules.get(\"dice-so-nice\")?.active && wpMsg?.id) {\n await game.dice3d.waitFor3DAnimationByMessageID(wpMsg.id)\n }\n // Auto-update Loksyu/TinJi singletons from weapon roll faces\n if ((wpResults.loksyudice ?? 0) > 0) await updateLoksyuFromRoll(wpAspectName, wpFaces)\n if ((wpResults.tinjidice ?? 0) > 0) await updateTinjiFromRoll(wpResults.tinjidice)\n return\n }\n default:\n ui.notifications.warn(`Unknown roll type: ${typeLibel}`)\n return\n }\n\n // For magic rolls the prompt allows adding HEI dice, so don't block early.\n // For itemkungfu, allow 0 base dice (user can add bonus dice in the prompt).\n if (numberofdice <= 0 && typeLibel !== \"aspect\" && typeLibel !== \"itemkungfu\" && !isMagic) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error0\"))\n return\n }\n\n // ---- Pre-compute default aspect for magic based on skill ----\n const MAGIC_ASPECTS = {\n internalcinnabar: 0, // metal\n alchemy: 1, // water\n masteryoftheway: 2, // earth\n exorcism: 3, // fire\n geomancy: 4, // wood\n }\n\n let defaultAspect = typeLibel === \"aspect\"\n ? [\"metal\",\"water\",\"earth\",\"fire\",\"wood\"].indexOf(skillLibel)\n : 0\n if (isMagic && MAGIC_ASPECTS[skillLibel] !== undefined) {\n defaultAspect = MAGIC_ASPECTS[skillLibel]\n }\n if (kfDefaultAspect >= 0) {\n defaultAspect = kfDefaultAspect\n }\n\n let defaultSpecialAspect = 0\n if (isMagicSpecial && specialLibel) {\n // Look up the speciality's element from the MAGICS config constant\n const specialCfg = MAGICS?.[skillLibel]?.speciality?.[specialLibel]\n const aspectName = LABELELEMENT_TO_ASPECT[specialCfg?.labelelement]\n if (aspectName) {\n defaultSpecialAspect = ASPECT_NAMES.indexOf(aspectName)\n }\n }\n\n // ---- Show roll prompt ----\n let params\n\n if (isMagic) {\n params = await showMagicPrompt({\n title,\n numberofdice,\n aspectskill: defaultAspect,\n bonusmalusskill: 0,\n bonusauspiciousdice: 0,\n aspectspeciality: defaultSpecialAspect,\n rolldifficulty: 1,\n bonusmalusspeciality: 0,\n heispend: 0,\n typeofthrow: typeOfThrow,\n })\n } else {\n params = await showSkillPrompt({\n title,\n numberofdice,\n aspect: defaultAspect,\n bonusmalus: 0,\n woundmalus: 0,\n bonusauspiciousdice: 0,\n typeofthrow: typeOfThrow,\n isSpecial,\n })\n }\n\n if (!params) return // cancelled\n\n // ---- Compute total dice and roll ----\n let aspectIndex, bonusMalus, bonusAuspicious, throwMode\n let spellAspectIndex = null // magic only: aspect of the speciality for Wu Xing\n let rollDifficulty = 1 // magic only: multiplier applied to successes\n\n if (isMagic) {\n const skillAspectIndex = Number(params.aspectskill ?? 0)\n spellAspectIndex = Number(params.aspectspeciality ?? skillAspectIndex)\n aspectIndex = skillAspectIndex // used only for skill dice pool\n bonusMalus = Number(params.bonusmalusskill ?? 0)\n bonusAuspicious = Number(params.bonusauspiciousdice ?? 0)\n rollDifficulty = Math.max(1, Number(params.rolldifficulty ?? 1))\n throwMode = Number(params.typeofthrow ?? 0)\n // magic: magic skill + aspect + bonuses + 1 (speciality base) + HEI spent\n const aspectDice = sys.aspect?.[ASPECT_NAMES[aspectIndex]]?.value ?? 0\n const bonusSpec = Number(params.bonusmalusspeciality ?? 0)\n const heiDice = Number(params.heispend ?? 0)\n numberofdice = numberofdice + aspectDice + bonusMalus + 1 + bonusSpec + heiDice\n } else {\n aspectIndex = Number(params.aspect ?? 0)\n bonusMalus = Number(params.bonusmalus ?? 0)\n const woundMalus = Number(params.woundmalus ?? 0)\n bonusAuspicious = Number(params.bonusauspiciousdice ?? 0)\n throwMode = Number(params.typeofthrow ?? 0)\n\n const aspectDice = (typeLibel !== \"aspect\")\n ? (sys.aspect?.[ASPECT_NAMES[aspectIndex]]?.value ?? 0)\n : 0\n\n numberofdice = numberofdice + aspectDice + bonusMalus - woundMalus\n if (isSpecial) numberofdice += 1 // +1d for speciality\n }\n\n if (numberofdice <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error0\"))\n return\n }\n\n // ---- Roll ----\n const roll = new Roll(`${numberofdice}d10`)\n await roll.evaluate()\n\n const rollModeKey = ROLL_MODES[throwMode] ?? \"roll\"\n\n // ---- Compute Wu Xing results ----\n // For magic rolls, the spell's aspect (aspectspeciality) governs the Wu Xing\n // cycle (which faces count as successes/auspicious/etc.), not the skill aspect.\n const wuXingAspectName = spellAspectIndex !== null\n ? ASPECT_NAMES[spellAspectIndex]\n : ASPECT_NAMES[aspectIndex]\n const allResults = roll.dice[0]?.results ?? []\n const faces = countFaces(allResults)\n const results = computeWuXingResults(faces, wuXingAspectName, bonusAuspicious)\n if (!results) return\n\n // For magic, successesdice \u00D7 rollDifficulty = spell power\n const spellPower = isMagic ? results.successesdice * rollDifficulty : null\n\n // ---- Build modifier summary text ----\n const modParts = []\n if (isMagic) {\n const bm = Number(params.bonusmalusskill ?? 0)\n const bs = Number(params.bonusmalusspeciality ?? 0)\n const hs = Number(params.heispend ?? 0)\n const ba = Number(params.bonusauspiciousdice ?? 0)\n if (bm !== 0) modParts.push(`${bm > 0 ? \"+\" : \"\"}${bm} ${game.i18n.localize(\"CDE.BonusMalus\")}`)\n if (bs !== 0) modParts.push(`${bs > 0 ? \"+\" : \"\"}${bs} ${game.i18n.localize(\"CDE.SpellBonus\")}`)\n if (ba !== 0) modParts.push(`+${ba} ${game.i18n.localize(\"CDE.BonusAuspiciousDice\")}`)\n if (hs !== 0) modParts.push(`${hs} ${game.i18n.localize(\"CDE.HeiSpend\")}`)\n if (rollDifficulty !== 1) modParts.push(`\u00D7${rollDifficulty} ${game.i18n.localize(\"CDE.RollDifficulty\")}`)\n } else {\n const bm = Number(params.bonusmalus ?? 0)\n const wm = Number(params.woundmalus ?? 0)\n const ba = Number(params.bonusauspiciousdice ?? 0)\n if (bm !== 0) modParts.push(`${bm > 0 ? \"+\" : \"\"}${bm} ${game.i18n.localize(\"CDE.BonusMalus\")}`)\n if (wm !== 0) modParts.push(`-${wm} ${game.i18n.localize(\"CDE.WoundMalus\")}`)\n if (ba !== 0) modParts.push(`+${ba} ${game.i18n.localize(\"CDE.BonusAuspiciousDice\")}`)\n }\n\n // ---- Send single enriched ChatMessage (roll + result card) ----\n const msg = await sendResultMessage(actor, {\n // Roll identity\n rollLabel: title,\n aspectName: wuXingAspectName,\n aspectLabel: game.i18n.localize(ASPECT_LABELS[wuXingAspectName] ?? \"\"),\n aspectIcon: ASPECT_ICONS[wuXingAspectName] ?? \"\",\n totalDice: numberofdice,\n modifiersText: modParts.length ? modParts.join(\" \u00B7 \") : \"\",\n // Spell power (magic only)\n spellPower,\n rollDifficulty: isMagic ? rollDifficulty : null,\n // Actor info\n actorName: actor.name ?? \"\",\n actorImg: actor.img ?? \"\",\n // Wu Xing results\n aspect: wuXingAspectName,\n ...results,\n // Die face counts\n d1: faces[1], d2: faces[2], d3: faces[3], d4: faces[4], d5: faces[5],\n d6: faces[6], d7: faces[7], d8: faces[8], d9: faces[9], d0: faces[0],\n }, roll, rollModeKey)\n\n // ---- Wait for Dice So Nice animation ----\n if (game.modules.get(\"dice-so-nice\")?.active && msg?.id) {\n await game.dice3d.waitFor3DAnimationByMessageID(msg.id)\n }\n\n // ---- Auto-update Loksyu / TinJi singletons ----\n if ((results.loksyudice ?? 0) > 0) await updateLoksyuFromRoll(wuXingAspectName, faces)\n if ((results.tinjidice ?? 0) > 0) await updateTinjiFromRoll(results.tinjidice)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nconst { HandlebarsApplicationMixin } = foundry.applications.api\n\nexport class CDEBaseActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {\n static DEFAULT_OPTIONS = {\n classes: [\"fvtt-chroniques-de-l-etrange\", \"actor\"],\n position: { width: 920, height: 800 },\n window: { resizable: true },\n form: { submitOnChange: true },\n dragDrop: [{ dragSelector: \".item, [data-drag='true']\", dropSelector: null }],\n actions: {\n create: CDEBaseActorSheet.#onItemCreate,\n edit: CDEBaseActorSheet.#onItemEdit,\n delete: CDEBaseActorSheet.#onItemDelete,\n editImage: CDEBaseActorSheet.#onEditImage,\n },\n }\n\n tabGroups = { primary: \"description\" }\n\n get title() {\n return this.document.name\n }\n\n async _prepareContext() {\n const descriptionHTML = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description ?? \"\", { async: true })\n const cssClass = this.options.classes?.join(\" \") ?? \"\"\n return {\n actor: this.document,\n system: this.document.system,\n systemData: this.document.system,\n systemFields: this.document.system.schema.fields,\n items: this.document.items.contents,\n descriptionHTML,\n editable: this.isEditable,\n cssClass,\n }\n }\n\n // Restore the active tab after every render (including re-renders from submitOnChange).\n // AppV2 does NOT preserve tab state natively \u2014 we must re-apply it from this.tabGroups,\n // which is dynamically updated by changeTab() when the user clicks a tab.\n _onRender(context, options) {\n super._onRender?.(context, options)\n for (const [group, tab] of Object.entries(this.tabGroups)) {\n this.changeTab(tab, group, { force: true })\n }\n }\n\n static async #onItemCreate(event, target) {\n const type = target.dataset.type ?? \"item\"\n const cls = getDocumentClass(\"Item\")\n const labels = {\n item: \"CDE.ItemNew\",\n weapon: \"CDE.WeaponNew\",\n armor: \"CDE.ArmorNew\",\n sanhei: \"CDE.SanheiNew\",\n ingredient: \"CDE.IngredientNew\",\n kungfu: \"CDE.KFNew\",\n spell: \"CDE.SpellNew\",\n supernatural: \"CDE.SupernaturalNew\",\n }\n const name = game.i18n.localize(labels[type] ?? \"CDE.ItemNew\")\n const systemData = {}\n if (type === \"spell\" && target.dataset.discipline) {\n systemData.discipline = target.dataset.discipline\n }\n return cls.create({ name, type, system: systemData }, { parent: this.document })\n }\n\n static #onItemEdit(event, target) {\n const itemId = target.dataset.itemId ?? target.closest(\"[data-item-id]\")?.dataset.itemId\n const item = this.document.items.get(itemId)\n if (item) item.sheet.render(true)\n }\n\n static #onItemDelete(event, target) {\n const itemId = target.dataset.itemId ?? target.closest(\"[data-item-id]\")?.dataset.itemId\n const item = this.document.items.get(itemId)\n if (item) item.delete()\n }\n\n static async #onEditImage(event, target) {\n const attr = target.dataset.edit\n const current = foundry.utils.getProperty(this.document, attr)\n const { img } = this.document.constructor.getDefaultArtwork?.(this.document.toObject()) ?? {}\n const fp = new FilePicker({\n current,\n type: \"image\",\n redirectToRoot: img ? [img] : [],\n callback: (path) => this.document.update({ [attr]: path }),\n top: this.position.top + 40,\n left: this.position.left + 10,\n })\n return fp.browse()\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { MAGICS, SUBTYPES } from \"../../../config/constants.js\"\nimport { rollInitiativePC } from \"../../initiative.js\"\nimport { rollForActor } from \"../../rolling.js\"\nimport { CDEBaseActorSheet } from \"./base.js\"\n\nexport class CDECharacterSheet extends CDEBaseActorSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"character\"],\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/actor/cde-character-sheet.html\" },\n }\n\n tabGroups = { primary: \"description\" }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n context.equipments = context.items.filter((item) => item.type === \"item\")\n context.weapons = context.items.filter((item) => item.type === \"weapon\")\n context.armors = context.items.filter((item) => item.type === \"armor\")\n context.sanheis = context.items.filter((item) => item.type === \"sanhei\")\n context.ingredients = context.items.filter((item) => item.type === \"ingredient\")\n context.spells = context.items.filter((item) => item.type === \"spell\")\n context.kungfus = context.items.filter((item) => item.type === \"kungfu\")\n context.CDE = { MAGICS, SUBTYPES }\n\n // Group spells by discipline key (matches MAGICS keys)\n const spellsByDiscipline = {}\n for (const spell of context.spells) {\n const disc = spell.system?.discipline ?? \"internalcinnabar\"\n if (!spellsByDiscipline[disc]) spellsByDiscipline[disc] = []\n spellsByDiscipline[disc].push(spell)\n }\n\n // Build magicsDisplay: only include the 5 relevant specialities per magic type + grimoire\n const systemMagics = context.systemData.magics ?? {}\n context.magicsDisplay = Object.fromEntries(\n Object.entries(MAGICS).map(([magicKey, magicDef]) => {\n const magicData = systemMagics[magicKey] ?? {}\n return [\n magicKey,\n {\n value: magicData.value ?? 0,\n visible: magicData.visible ?? false,\n speciality: Object.fromEntries(\n Object.keys(magicDef.speciality).map((specKey) => [\n specKey,\n { check: magicData.speciality?.[specKey]?.check ?? false },\n ])\n ),\n grimoire: spellsByDiscipline[magicKey] ?? [],\n },\n ]\n })\n )\n\n return context\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindInitiativeControls()\n this.#bindPrefs()\n this.#bindRollButtons()\n this.#bindComponentRandomize()\n this.#bindDiagramZoom()\n }\n\n #bindInitiativeControls() {\n const buttons = this.element?.querySelectorAll(\".click-initiative\")\n if (!buttons?.length) return\n buttons.forEach((button) => {\n button.addEventListener(\"click\", async () => {\n const action = button.dataset.libelId\n let initiative = this.document.system.initiative ?? 1\n if (action === \"plus\") {\n initiative = initiative >= 24 ? 1 : initiative + 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"minus\") {\n initiative = initiative <= 1 ? 24 : initiative - 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"create\") {\n await rollInitiativePC(this.document)\n }\n })\n })\n }\n\n #bindPrefs() {\n const button = this.element?.querySelector(\".click-prefs\")\n if (!button) return\n button.addEventListener(\"click\", async () => {\n const current = this.document.system.prefs?.typeofthrow ?? { choice: \"0\", check: true }\n const html = `\n
\n
\n \n \n
\n
\n \n \n
\n
`\n const prefs = await foundry.applications.api.DialogV2.prompt({\n window: { title: game.i18n.localize(\"CDE.Preferences\") },\n content: html,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (_ev, _btn, dialog) => {\n const root = dialog.element ?? dialog\n const choice = root.querySelector(\"select[name='choice']\")?.value ?? \"0\"\n const check = root.querySelector(\"input[name='check']\")?.checked ?? false\n return { choice, check }\n },\n },\n })\n if (prefs) {\n await this.document.update({\n \"system.prefs.typeofthrow.choice\": String(prefs.choice),\n \"system.prefs.typeofthrow.check\": !!prefs.check,\n })\n }\n })\n }\n\n #bindRollButtons() {\n const cells = this.element?.querySelectorAll(\"td.click[data-libel-id], td.click2[data-libel-id], .cde-roll-trigger[data-libel-id]\")\n if (!cells?.length) return\n cells.forEach((cell) => {\n cell.addEventListener(\"click\", (event) => {\n event.preventDefault()\n const rollKey = cell.dataset.libelId\n if (rollKey) rollForActor(this.document, rollKey)\n })\n })\n }\n\n #bindDiagramZoom() {\n const img = this.element?.querySelector(\"[data-action='zoom-diagram']\")\n if (!img) return\n img.addEventListener(\"click\", () => {\n new ImagePopout(img.src, {\n title: game.i18n.localize(\"CDE.NghangDiagramTitle\"),\n shareable: false,\n }).render(true)\n })\n }\n\n #bindComponentRandomize() {\n const btn = this.element?.querySelector(\"[data-action='randomize-component']\")\n if (!btn) return\n btn.addEventListener(\"click\", async () => {\n const roll = new Roll(\"1d10\")\n await roll.evaluate()\n const face = roll.total === 10 ? 0 : roll.total\n const COMPONENT_KEYS = { 1:\"one\", 2:\"two\", 3:\"three\", 4:\"four\", 5:\"five\",\n 6:\"six\", 7:\"seven\", 8:\"eight\", 9:\"nine\", 0:\"zero\" }\n const componentKey = COMPONENT_KEYS[face]\n const componentValue = this.document.system.component?.[componentKey]?.value ?? \"\"\n const label = componentValue\n ? `${componentValue}`\n : `${game.i18n.localize(\"CDE.Component\")}${face}`\n const content = `\n
\n ${game.i18n.localize(\"CDE.ChanceThrowResult\")}\n ${label}\n
`\n await ChatMessage.create({\n user: game.user.id,\n speaker: ChatMessage.getSpeaker({ actor: this.document }),\n content,\n rolls: [roll],\n rollMode: game.settings.get(\"core\", \"rollMode\") ?? \"roll\",\n })\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { rollInitiativeNPC } from \"../../initiative.js\"\nimport { rollForActor } from \"../../rolling.js\"\nimport { CDEBaseActorSheet } from \"./base.js\"\n\nexport class CDENpcSheet extends CDEBaseActorSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"npc\"],\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/actor/cde-npc-sheet.html\" },\n }\n\n tabGroups = { primary: \"description\" }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n context.supernaturals = context.items.filter((item) => item.type === \"supernatural\")\n context.spells = context.items.filter((item) => item.type === \"spell\")\n context.kungfus = context.items.filter((item) => item.type === \"kungfu\")\n context.weapons = context.items.filter((item) => item.type === \"weapon\")\n context.armors = context.items.filter((item) => item.type === \"armor\")\n context.equipments = context.items.filter((item) => item.type === \"item\")\n return context\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindInitiativeControls()\n this.#bindRollButtons()\n }\n\n #bindRollButtons() {\n const cells = this.element?.querySelectorAll(\".cde-roll-trigger[data-libel-id]\")\n if (!cells?.length) return\n cells.forEach((cell) => {\n cell.addEventListener(\"click\", (event) => {\n event.preventDefault()\n const rollKey = cell.dataset.libelId\n if (rollKey) rollForActor(this.document, rollKey)\n })\n })\n }\n\n #bindInitiativeControls() {\n const buttons = this.element?.querySelectorAll(\".click-initiative-npc\")\n if (!buttons?.length) return\n buttons.forEach((button) => {\n button.addEventListener(\"click\", async () => {\n const action = button.dataset.libelId\n let initiative = this.document.system.initiative ?? 1\n if (action === \"plus\") {\n initiative = initiative >= 24 ? 1 : initiative + 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"minus\") {\n initiative = initiative <= 1 ? 24 : initiative - 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"create\") {\n await rollInitiativeNPC(this.document)\n }\n })\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nconst { HandlebarsApplicationMixin } = foundry.applications.api\n\nexport class CDEBaseItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {\n static DEFAULT_OPTIONS = {\n classes: [\"fvtt-chroniques-de-l-etrange\", \"item\"],\n position: { width: 520, height: \"auto\" },\n window: { resizable: true },\n form: { submitOnChange: true },\n actions: {\n editImage: CDEBaseItemSheet.#onEditImage,\n },\n }\n\n tabGroups = { primary: \"details\" }\n\n get title() {\n return this.document.name\n }\n\n async _prepareContext() {\n const cssClass = this.options.classes?.join(\" \") ?? \"\"\n const enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description ?? \"\", { async: true })\n const enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes ?? \"\", { async: true })\n return {\n item: this.document,\n system: this.document.system,\n systemData: this.document.system,\n systemFields: this.document.system.schema.fields,\n editable: this.isEditable,\n cssClass,\n enrichedDescription,\n enrichedNotes,\n descriptionHTML: enrichedDescription,\n notesHTML: enrichedNotes,\n }\n }\n\n // Restore the active tab after every render (including re-renders from submitOnChange).\n _onRender(context, options) {\n super._onRender?.(context, options)\n for (const [group, tab] of Object.entries(this.tabGroups)) {\n this.changeTab(tab, group, { force: true })\n }\n }\n\n static async #onEditImage(event, target) {\n const attr = target.dataset.edit\n const current = foundry.utils.getProperty(this.document, attr)\n const { img } = this.document.constructor.getDefaultArtwork?.(this.document.toObject()) ?? {}\n const fp = new FilePicker({\n current,\n type: \"image\",\n redirectToRoot: img ? [img] : [],\n callback: (path) => this.document.update({ [attr]: path }),\n top: this.position.top + 40,\n left: this.position.left + 10,\n })\n return fp.browse()\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEItemSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"equipment\"],\n position: { width: 560, height: 460 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-item-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEKungfuSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"kungfu\"],\n position: { width: 720, height: 680 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-kungfu-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const techniques = this.document.system.techniques ?? {}\n const enrich = (value) => foundry.applications.ux.TextEditor.implementation.enrichHTML(value ?? \"\", { async: true })\n context.descriptionTechnique1HTML = await enrich(techniques.technique1?.technique)\n context.descriptionTechnique2HTML = await enrich(techniques.technique2?.technique)\n context.descriptionTechnique3HTML = await enrich(techniques.technique3?.technique)\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDESpellSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"spell\"],\n position: { width: 660, height: 680 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-spell-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? \"\", { async: true })\n context.spellDescriptionHTML = await enrich(this.document.system.description)\n context.componentsDescriptionHTML = await enrich(this.document.system.components)\n context.effectsDescriptionHTML = await enrich(this.document.system.effects)\n context.examplesDescriptionHTML = await enrich(this.document.system.examples)\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDESupernaturalSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"supernatural\"],\n position: { width: 560, height: 520 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-supernatural-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? \"\", { async: true })\n context.effectsHTML = await enrich(this.document.system.effects)\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEWeaponSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"weapon\"],\n position: { width: 580, height: 520 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-weapon-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEArmorSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"armor\"],\n position: { width: 520, height: 460 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-armor-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDESanheiSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"sanhei\"],\n position: { width: 580, height: 620 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-sanhei-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? \"\", { async: true })\n const props = this.document.system.properties\n context.prop1DescriptionHTML = await enrich(props.prop1.description)\n context.prop2DescriptionHTML = await enrich(props.prop2.description)\n context.prop3DescriptionHTML = await enrich(props.prop3.description)\n context.propFields = this.document.system.schema.fields.properties.fields\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEIngredientSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"ingredient\"],\n position: { width: 520, height: 460 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-ingredient-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { getLoksyuData, setLoksyuData } from \"./singletons.js\"\nimport { SYSTEM_ID } from \"../../config/constants.js\"\n\nexport class CDELoksyuApp extends foundry.applications.api.HandlebarsApplicationMixin(\n foundry.applications.api.ApplicationV2\n) {\n static DEFAULT_OPTIONS = {\n id: \"cde-loksyu-app\",\n tag: \"div\",\n window: {\n title: \"CDE.Loksyu\",\n icon: \"fas fa-yin-yang\",\n resizable: false,\n },\n classes: [\"cde-app\", \"cde-loksyu-standalone\"],\n position: { width: 520, height: \"auto\" },\n actions: {\n resetElement: CDELoksyuApp.#onResetElement,\n resetAll: CDELoksyuApp.#onResetAll,\n zoomVisual: CDELoksyuApp.#onZoomVisual,\n },\n }\n\n static PARTS = {\n main: {\n template: `systems/${SYSTEM_ID}/templates/apps/cde-loksyu-app.html`,\n },\n }\n\n /** @type {Function|null} bound hook handler */\n _updateHook = null\n\n /** Singleton accessor \u2014 open or bring to front */\n static open() {\n const existing = Array.from(foundry.applications.instances.values()).find(\n (app) => app instanceof CDELoksyuApp\n )\n if (existing) { existing.bringToFront(); return existing }\n const app = new CDELoksyuApp()\n app.render(true)\n return app\n }\n\n async _prepareContext() {\n const sys = getLoksyuData()\n const ELEMENTS = [\n { key: \"wood\", nameKey: \"CDE.Wood\", qualKey: \"CDE.WoodQualities\", img: `systems/${SYSTEM_ID}/images/cde_bois.webp` },\n { key: \"fire\", nameKey: \"CDE.Fire\", qualKey: \"CDE.FireQualities\", img: `systems/${SYSTEM_ID}/images/cde_feu.webp` },\n { key: \"earth\", nameKey: \"CDE.Earth\", qualKey: \"CDE.EarthQualities\", img: `systems/${SYSTEM_ID}/images/cde_terre.webp` },\n { key: \"metal\", nameKey: \"CDE.Metal\", qualKey: \"CDE.MetalQualities\", img: `systems/${SYSTEM_ID}/images/cde_metal.webp` },\n { key: \"water\", nameKey: \"CDE.Water\", qualKey: \"CDE.WaterQualities\", img: `systems/${SYSTEM_ID}/images/cde_eau.webp` },\n ]\n\n return {\n canEdit: game.user.isGM,\n elements: ELEMENTS.map((el) => ({\n ...el,\n yang: sys[el.key]?.yang ?? 0,\n yin: sys[el.key]?.yin ?? 0,\n })),\n }\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindInputs()\n\n this._updateHook = Hooks.on(\"cde:loksyuUpdated\", () => this.render())\n }\n\n _onClose(options) {\n if (this._updateHook !== null) {\n Hooks.off(\"cde:loksyuUpdated\", this._updateHook)\n this._updateHook = null\n }\n super._onClose(options)\n }\n\n #bindInputs() {\n const inputs = this.element?.querySelectorAll(\"input[data-field]\")\n if (!inputs?.length) return\n inputs.forEach((input) => {\n input.addEventListener(\"change\", async (ev) => {\n const field = ev.currentTarget.dataset.field\n const val = parseInt(ev.currentTarget.value, 10)\n if (!field || isNaN(val)) return\n // field is like \"wood.yin\" or \"fire.yang\"\n const [aspect, dim] = field.split(\".\")\n if (!aspect || !dim) return\n const data = getLoksyuData()\n if (!data[aspect]) data[aspect] = { yin: 0, yang: 0 }\n data[aspect][dim] = Math.max(0, val)\n await setLoksyuData(data)\n })\n })\n }\n\n static async #onResetElement(event, target) {\n const key = target.dataset.element\n if (!key) return\n const data = getLoksyuData()\n data[key] = { yin: 0, yang: 0 }\n await setLoksyuData(data)\n }\n\n static async #onResetAll(_event, _target) {\n const KEYS = [\"wood\", \"fire\", \"earth\", \"metal\", \"water\"]\n const data = getLoksyuData()\n for (const k of KEYS) data[k] = { yin: 0, yang: 0 }\n await setLoksyuData(data)\n }\n\n static #onZoomVisual(_event, target) {\n new ImagePopout(target.src, {\n title: game.i18n.localize(\"CDE.LoksyuDiagramTitle\"),\n shareable: false,\n }).render(true)\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { getTinjiValue, setTinjiValue } from \"./singletons.js\"\nimport { SYSTEM_ID } from \"../../config/constants.js\"\n\nexport class CDETinjiApp extends foundry.applications.api.HandlebarsApplicationMixin(\n foundry.applications.api.ApplicationV2\n) {\n static DEFAULT_OPTIONS = {\n id: \"cde-tinji-app\",\n tag: \"div\",\n window: {\n title: \"CDE.TinJi2\",\n icon: \"fas fa-star\",\n resizable: false,\n },\n classes: [\"cde-app\", \"cde-tinji-standalone\"],\n position: { width: 380, height: \"auto\" },\n actions: {\n increment: CDETinjiApp.#onIncrement,\n decrement: CDETinjiApp.#onDecrement,\n reset: CDETinjiApp.#onReset,\n spend: CDETinjiApp.#onSpend,\n },\n }\n\n static PARTS = {\n main: {\n template: `systems/${SYSTEM_ID}/templates/apps/cde-tinji-app.html`,\n },\n }\n\n /** @type {Function|null} */\n _updateHook = null\n\n static open() {\n const existing = Array.from(foundry.applications.instances.values()).find(\n (app) => app instanceof CDETinjiApp\n )\n if (existing) { existing.bringToFront(); return existing }\n const app = new CDETinjiApp()\n app.render(true)\n return app\n }\n\n async _prepareContext() {\n return {\n canEdit: game.user.isGM,\n value: getTinjiValue(),\n }\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindDirectInput()\n this._updateHook = Hooks.on(\"cde:tinjiUpdated\", () => this.render())\n }\n\n _onClose(options) {\n if (this._updateHook !== null) {\n Hooks.off(\"cde:tinjiUpdated\", this._updateHook)\n this._updateHook = null\n }\n super._onClose(options)\n }\n\n #bindDirectInput() {\n const input = this.element?.querySelector(\"input.cde-tinji-direct\")\n if (!input) return\n input.addEventListener(\"change\", async (ev) => {\n const val = parseInt(ev.currentTarget.value, 10)\n if (!isNaN(val)) await setTinjiValue(val)\n })\n }\n\n static async #onIncrement() {\n await setTinjiValue(getTinjiValue() + 1)\n }\n\n static async #onDecrement() {\n const current = getTinjiValue()\n if (current <= 0) return\n await setTinjiValue(current - 1)\n }\n\n static async #onReset() {\n await setTinjiValue(0)\n }\n\n static async #onSpend() {\n const current = getTinjiValue()\n if (current <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.TinjiEmpty\"))\n return\n }\n await setTinjiValue(current - 1)\n ChatMessage.create({\n user: game.user.id,\n content: `
\n \n ${game.i18n.localize(\"CDE.TinJi2\")}\n ${game.i18n.format(\"CDE.TinjiSpent\", { name: game.user.name })}\n (${current - 1} ${game.i18n.localize(\"CDE.TinjiRemaining\")})\n
`,\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Post-roll interactive action buttons injected into dice result chat messages.\n * Allows players to pull dice from the Loksyu (as Successes or d\u00E9s-fastes)\n * and allows the GM to spend Tin Ji to intervene.\n *\n * After a draw, the originating roll result message is updated in-place\n * with the new counts, without creating noise.\n */\n\nimport { getLoksyuData, setLoksyuData, getTinjiValue, setTinjiValue } from \"./apps/singletons.js\"\nimport { SYSTEM_ID, WU_XING_CYCLE, ASPECT_LABELS, ASPECT_ICONS } from \"../config/constants.js\"\n\nconst RESULT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-dice-result.html\"\n\n/**\n * Inject or refresh post-roll action buttons in the given chat message HTML element.\n * Called from renderChatMessageHTML hook.\n * @param {ChatMessage} message\n * @param {HTMLElement} html - the chat message HTML element (li.chat-message)\n */\nexport function injectRollActions(message, html) {\n const rollCard = html.querySelector(\".cde-roll-result\")\n if (!rollCard) return\n const aspect = rollCard.dataset.aspect\n if (!aspect || !WU_XING_CYCLE[aspect]) return\n refreshRollActions(rollCard, aspect, message)\n}\n\n/**\n * Re-render the action buttons section based on current Loksyu / TinJi state.\n */\nfunction refreshRollActions(rollCard, aspect, message) {\n rollCard.querySelector(\".cde-roll-actions\")?.remove()\n\n const cycle = WU_XING_CYCLE[aspect]\n const fasteAspect = cycle[1]\n\n const loksyu = getLoksyuData()\n const tinji = getTinjiValue()\n\n const successAvail = (loksyu[aspect]?.yin ?? 0) + (loksyu[aspect]?.yang ?? 0)\n const fasteAvail = (loksyu[fasteAspect]?.yin ?? 0) + (loksyu[fasteAspect]?.yang ?? 0)\n const isGM = game.user.isGM\n\n const hasSomething = successAvail > 0 || fasteAvail > 0 || (isGM && tinji > 0)\n if (!hasSomething) return\n\n const aspLabel = game.i18n.localize(ASPECT_LABELS[aspect])\n const fasteLabel = game.i18n.localize(ASPECT_LABELS[fasteAspect])\n\n let btns = \"\"\n\n if (successAvail > 0) {\n btns += ``\n }\n\n if (fasteAvail > 0) {\n btns += ``\n }\n\n if (isGM && tinji > 0) {\n btns += ``\n }\n\n const wrapper = document.createElement(\"div\")\n wrapper.className = \"cde-roll-actions\"\n wrapper.innerHTML = `\n
\n \n ${game.i18n.localize(\"CDE.PostRollActions\")}\n
\n
${btns}
\n `\n rollCard.appendChild(wrapper)\n\n wrapper.addEventListener(\"click\", async ev => {\n const btn = ev.target.closest(\"[data-action]\")\n if (!btn || btn.disabled) return\n const action = btn.dataset.action\n if (action === \"loksyu-success\") {\n await _drawFromLoksyu(message, aspect, \"success\", aspLabel)\n } else if (action === \"loksyu-faste\") {\n await _drawFromLoksyu(message, fasteAspect, \"faste\", fasteLabel)\n } else if (action === \"tinji\") {\n await _spendTinjiPostRoll()\n }\n // Buttons will be re-injected automatically via renderChatMessageHTML\n // after message.update(). For tinji (no message update), refresh manually.\n if (action === \"tinji\") refreshRollActions(rollCard, aspect, message)\n })\n}\n\n/**\n * Pull one die from a given Loksyu aspect slot, update Loksyu settings,\n * and update the originating roll-result message in-place.\n *\n * @param {ChatMessage} message - the roll result chat message to update\n * @param {string} aspect - which Loksyu aspect slot to draw from\n * @param {\"success\"|\"faste\"} type\n * @param {string} aspectLabel - localised aspect name for the notification\n */\nasync function _drawFromLoksyu(message, aspect, type, aspectLabel) {\n const data = getLoksyuData()\n const entry = data[aspect] ?? { yin: 0, yang: 0 }\n const total = entry.yin + entry.yang\n if (total <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.LoksyuEmpty\"))\n return\n }\n\n // Remove 1 die (prefer yang first)\n if (entry.yang > 0) entry.yang--\n else entry.yin--\n data[aspect] = entry\n await setLoksyuData(data)\n\n // Update the roll-result message in-place if it has stored flags\n const flags = message?.flags?.[SYSTEM_ID]\n if (flags?.rollResult && message.isOwner) {\n const updated = foundry.utils.deepClone(flags.rollResult)\n if (type === \"success\") {\n updated.successesdice = (updated.successesdice ?? 0) + 1\n updated.loksyuBonusSuc = (updated.loksyuBonusSuc ?? 0) + 1\n // Recalculate weapon damage if applicable\n if (updated.damageBase) updated.totalDamage = updated.successesdice * updated.damageBase\n } else {\n updated.auspiciousdice = (updated.auspiciousdice ?? 0) + 1\n updated.loksyuBonusFaste = (updated.loksyuBonusFaste ?? 0) + 1\n }\n const newHtml = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE, updated)\n await message.update({\n content: newHtml,\n [`flags.${SYSTEM_ID}.rollResult`]: updated,\n })\n // renderChatMessageHTML hook fires automatically \u2192 buttons re-injected\n }\n\n const remain = entry.yin + entry.yang\n const typeLabel = type === \"success\"\n ? game.i18n.localize(\"CDE.Successes\")\n : game.i18n.localize(\"CDE.AuspiciousDie\")\n\n ChatMessage.create({\n user: game.user.id,\n content: `
\n
\n \"${aspectLabel}\"/\n ${game.user.name}\n ${game.i18n.localize(\"CDE.LoksyuDrawsA\")}\n ${typeLabel}\n ${game.i18n.localize(\"CDE.LoksyuFromAspect\")} ${aspectLabel}\n
\n
\n \n ${game.i18n.localize(\"CDE.Loksyu\")} ${aspectLabel} : \n ${remain} ${game.i18n.localize(\"CDE.LoksyuRemaining\")}\n
\n
`,\n })\n}\n\n/**\n * Spend 1 Tin Ji point (GM only) and post a notification.\n */\nasync function _spendTinjiPostRoll() {\n if (!game.user.isGM) return\n const current = getTinjiValue()\n if (current <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.TinjiEmpty\"))\n return\n }\n await setTinjiValue(current - 1)\n ChatMessage.create({\n user: game.user.id,\n content: `
\n \u5929\n \n ${game.user.name} ${game.i18n.localize(\"CDE.TinjiSpent\").replace(\"{name}\", game.user.name)}\n \n (${current - 1} ${game.i18n.localize(\"CDE.TinjiRemaining\")})\n
`,\n })\n}\n\n/**\n * Refresh all visible roll-result buttons when Loksyu or TinJi settings change.\n * Wired up via Hooks.on(\"updateSetting\", ...) in system.js.\n */\nexport function refreshAllRollActions() {\n document.querySelectorAll(\".chat-message .cde-roll-result[data-aspect]\").forEach(card => {\n const aspect = card.dataset.aspect\n if (!aspect || !WU_XING_CYCLE[aspect]) return\n // Find the ChatMessage document from the ancestor element's data-message-id\n const msgEl = card.closest(\"[data-message-id]\")\n const msgId = msgEl?.dataset?.messageId\n const message = msgId ? game.messages.get(msgId) : null\n refreshRollActions(card, aspect, message)\n })\n}\n\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { ACTOR_TYPES, ITEM_TYPES, MAGICS, SUBTYPES, SYSTEM_ID } from \"./config/constants.js\"\nimport { registerSettings, migrateIfNeeded } from \"./config/settings.js\"\nimport { preLocalizeConfig } from \"./config/localize.js\"\nimport { configureRuntime } from \"./config/runtime.js\"\nimport { CharacterDataModel, NpcDataModel } from \"./data/actors/index.js\"\nimport { EquipmentDataModel, KungfuDataModel, SpellDataModel, SupernaturalDataModel, WeaponDataModel, ArmorDataModel, SanheiDataModel, IngredientDataModel } from \"./data/items/index.js\"\nimport { CDEMessage } from \"./documents/chat-message.js\"\nimport { CDEActor } from \"./documents/actor.js\"\nimport { CDEItem } from \"./documents/item.js\"\nimport { registerDice } from \"./ui/dice.js\"\nimport { registerHandlebarsHelpers } from \"./ui/helpers.js\"\nimport { preloadPartials } from \"./ui/templates.js\"\nimport { CDECharacterSheet, CDENpcSheet } from \"./ui/sheets/actors/index.js\"\nimport { CDEItemSheet, CDEKungfuSheet, CDESpellSheet, CDESupernaturalSheet, CDEWeaponSheet, CDEArmorSheet, CDESanheiSheet, CDEIngredientSheet } from \"./ui/sheets/items/index.js\"\nimport { CDELoksyuApp } from \"./ui/apps/loksyu-app.js\"\nimport { CDETinjiApp } from \"./ui/apps/tinji-app.js\"\nimport { injectRollActions, refreshAllRollActions } from \"./ui/roll-actions.js\"\n\nHooks.once(\"i18nInit\", preLocalizeConfig)\n\nHooks.once(\"init\", async () => {\n console.info(`CHRONIQUESDELETRANGE | Initializing ${SYSTEM_ID}`)\n\n registerSettings()\n\n game.system.CONST = { MAGICS, SUBTYPES }\n\n // Expose standalone apps globally for macros\n game.cde = { CDELoksyuApp, CDETinjiApp }\n\n CONFIG.Actor.dataModels = {\n [ACTOR_TYPES.character]: CharacterDataModel,\n [ACTOR_TYPES.npc]: NpcDataModel,\n }\n CONFIG.Item.dataModels = {\n [ITEM_TYPES.item]: EquipmentDataModel,\n [ITEM_TYPES.kungfu]: KungfuDataModel,\n [ITEM_TYPES.spell]: SpellDataModel,\n [ITEM_TYPES.supernatural]: SupernaturalDataModel,\n [ITEM_TYPES.weapon]: WeaponDataModel,\n [ITEM_TYPES.armor]: ArmorDataModel,\n [ITEM_TYPES.sanhei]: SanheiDataModel,\n [ITEM_TYPES.ingredient]: IngredientDataModel,\n }\n\n CONFIG.Actor.documentClass = CDEActor\n CONFIG.Item.documentClass = CDEItem\n CONFIG.ChatMessage.documentClass = CDEMessage\n\n configureRuntime()\n\n foundry.applications.apps.DocumentSheetConfig.unregisterSheet(Actor, \"core\", foundry.appv1.sheets.ActorSheet)\n foundry.applications.apps.DocumentSheetConfig.unregisterSheet(Item, \"core\", foundry.appv1.sheets.ItemSheet)\n\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Actor, SYSTEM_ID, CDECharacterSheet, {\n types: [ACTOR_TYPES.character],\n makeDefault: true,\n label: \"CDE Character Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Actor, SYSTEM_ID, CDENpcSheet, {\n types: [ACTOR_TYPES.npc],\n makeDefault: true,\n label: \"CDE NPC Sheet (V2)\",\n })\n\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEItemSheet, {\n types: [ITEM_TYPES.item],\n makeDefault: true,\n label: \"CDE Item Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEKungfuSheet, {\n types: [ITEM_TYPES.kungfu],\n makeDefault: true,\n label: \"CDE KungFu Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDESpellSheet, {\n types: [ITEM_TYPES.spell],\n makeDefault: true,\n label: \"CDE Spell Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDESupernaturalSheet, {\n types: [ITEM_TYPES.supernatural],\n makeDefault: true,\n label: \"CDE Supernatural Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEWeaponSheet, {\n types: [ITEM_TYPES.weapon],\n makeDefault: true,\n label: \"CDE Weapon Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEArmorSheet, {\n types: [ITEM_TYPES.armor],\n makeDefault: true,\n label: \"CDE Armor Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDESanheiSheet, {\n types: [ITEM_TYPES.sanhei],\n makeDefault: true,\n label: \"CDE Sanhei Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEIngredientSheet, {\n types: [ITEM_TYPES.ingredient],\n makeDefault: true,\n label: \"CDE Ingredient Sheet (V2)\",\n })\n\n await preloadPartials()\n registerHandlebarsHelpers()\n registerDice()\n\n console.info(`CHRONIQUESDELETRANGE | Initialized`)\n})\n\nHooks.once(\"ready\", async () => {\n await migrateIfNeeded()\n})\n\n/** Add Loksyu + Tin Ji quick-access buttons to the chat panel (FoundryVTT v13) */\nHooks.on(\"renderChatLog\", (_app, html) => {\n const el = html instanceof HTMLElement ? html : (html[0] ?? html)\n if (!el?.querySelector) return\n\n // Avoid double-injection on re-renders\n if (el.querySelector(\".cde-chat-app-buttons\")) return\n\n const wrapper = document.createElement(\"div\")\n wrapper.classList.add(\"cde-chat-app-buttons\")\n wrapper.innerHTML = `\n \n \n `\n\n // Use event delegation to avoid being swallowed by Foundry's own handlers\n wrapper.addEventListener(\"click\", (ev) => {\n if (ev.target.closest(\".cde-chat-btn--loksyu\")) CDELoksyuApp.open()\n if (ev.target.closest(\".cde-chat-btn--tinji\")) CDETinjiApp.open()\n })\n\n // Insert before the chat form \u2014 works on v12 and v13\n const anchor = el.querySelector(\".chat-form\")\n ?? el.querySelector(\".chat-message-form\")\n ?? el.querySelector(\"form\")\n if (anchor) anchor.parentElement.insertBefore(wrapper, anchor)\n else el.appendChild(wrapper)\n})\n\n/** Inject Loksyu / TinJi action buttons into roll-result chat messages */\nHooks.on(\"renderChatMessageHTML\", (message, html) => {\n injectRollActions(message, html)\n})\n\n/** Refresh all visible roll-result buttons whenever Loksyu or TinJi settings change */\nHooks.on(\"updateSetting\", setting => {\n if (!setting.key) return\n if (setting.key.includes(\"loksyuData\") || setting.key.includes(\"tinjiData\")) {\n refreshAllRollActions()\n }\n})\n"], - "mappings": "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", + "sources": ["../src/config/constants.js", "../src/config/settings.js", "../src/config/localize.js", "../src/config/runtime.js", "../src/data/actors/character.js", "../src/data/actors/npc.js", "../src/data/items/item.js", "../src/data/items/kungfu.js", "../src/data/items/spell.js", "../src/data/items/supernatural.js", "../src/data/items/weapon.js", "../src/data/items/armor.js", "../src/data/items/sanhei.js", "../src/data/items/ingredient.js", "../src/documents/chat-message.js", "../src/documents/actor.js", "../src/documents/item.js", "../src/ui/dice.js", "../src/ui/helpers.js", "../src/ui/templates.js", "../src/ui/initiative.js", "../src/ui/apps/singletons.js", "../src/ui/rolling.js", "../src/ui/sheets/actors/base.js", "../src/ui/sheets/actors/character.js", "../src/ui/sheets/actors/npc.js", "../src/ui/sheets/items/base.js", "../src/ui/sheets/items/item.js", "../src/ui/sheets/items/kungfu.js", "../src/ui/sheets/items/spell.js", "../src/ui/sheets/items/supernatural.js", "../src/ui/sheets/items/weapon.js", "../src/ui/sheets/items/armor.js", "../src/ui/sheets/items/sanhei.js", "../src/ui/sheets/items/ingredient.js", "../src/ui/apps/loksyu-app.js", "../src/ui/apps/tinji-app.js", "../src/documents/combat.js", "../src/ui/apps/wheel-app.js", "../src/ui/roll-actions.js", "../src/system.js"], + "sourcesContent": ["/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport const SYSTEM_ID = \"fvtt-chroniques-de-l-etrange\"\n\nexport const ACTOR_TYPES = {\n character: \"character\",\n npc: \"npc\",\n}\n\nexport const ITEM_TYPES = {\n item: \"item\",\n kungfu: \"kungfu\",\n spell: \"spell\",\n supernatural: \"supernatural\",\n weapon: \"weapon\",\n armor: \"armor\",\n sanhei: \"sanhei\",\n ingredient: \"ingredient\",\n}\n\nexport const SUBTYPES = {\n weapon: { id: \"weapon\", label: \"CDE.Weapon\" },\n armor: { id: \"armor\", label: \"CDE.Armor\" },\n sanhei: { id: \"sanhei\", label: \"CDE.Sanhei\" },\n other: { id: \"other\", label: \"CDE.Other\" },\n}\n\nexport const MAGICS = {\n internalcinnabar: {\n id: \"internalcinnabar\",\n background: \"linear-grey\",\n label: \"CDE.InternalCinnabar\",\n aspectlabel: \"CDE.Metal\",\n speciality: {\n essence: { label: \"CDE.Essence\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n mind: { label: \"CDE.Mind\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n purification: { label: \"CDE.Purification\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n manipulation: { label: \"CDE.Manipulation\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n aura: { label: \"CDE.Aura\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n alchemy: {\n id: \"alchemy\",\n background: \"linear-blue\",\n label: \"CDE.Alchemy\",\n aspectlabel: \"CDE.Water\",\n speciality: {\n acupuncture: { label: \"CDE.Acupuncture\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n elixirs: { label: \"CDE.Elixirs\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n poisons: { label: \"CDE.Poisons\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n arsenal: { label: \"CDE.Arsenal\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n potions: { label: \"CDE.Potions\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n masteryoftheway: {\n id: \"masteryoftheway\",\n background: \"linear-brown\",\n label: \"CDE.MasteryOfTheWay\",\n aspectlabel: \"CDE.Earth\",\n speciality: {\n curse: { label: \"CDE.Curse\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n transfiguration: { label: \"CDE.Transfiguration\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n necromancy: { label: \"CDE.Necromancy\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n climatecontrol: { label: \"CDE.ClimateControl\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n goldenmagic: { label: \"CDE.GoldenMagic\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n exorcism: {\n id: \"exorcism\",\n background: \"linear-red\",\n label: \"CDE.Exorcism\",\n aspectlabel: \"CDE.Fire\",\n speciality: {\n invocation: { label: \"CDE.Invocation\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n tracking: { label: \"CDE.Tracking\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n protection: { label: \"CDE.Protection\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n punishment: { label: \"CDE.Punishment\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n domination: { label: \"CDE.Domination\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n geomancy: {\n id: \"geomancy\",\n background: \"linear-green\",\n label: \"CDE.Geomancy\",\n aspectlabel: \"CDE.Wood\",\n speciality: {\n neutralization: { label: \"CDE.Neutralization\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\", labelicon: \"Yin\", labelelement: \"CDE.Metal\" },\n divination: { label: \"CDE.Divination\", classicon: \"icon-yin\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\", labelicon: \"Yin\", labelelement: \"CDE.Water\" },\n earthlyprayer: { label: \"CDE.EarthlyPrayer\", classicon: \"icon-yinyang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\", labelicon: \"Yin/Yang\", labelelement: \"CDE.Earth\" },\n heavenlyprayer: { label: \"CDE.HeavenlyPrayer\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\", labelicon: \"Yang\", labelelement: \"CDE.Fire\" },\n fungseoi: { label: \"CDE.Fungseoi\", classicon: \"icon-yang\", icon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\", elementicon: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\", labelicon: \"Yang\", labelelement: \"CDE.Wood\" },\n },\n },\n}\n\n/** Map aspect name \u2192 i18n label key */\nexport const ASPECT_LABELS = {\n metal: \"CDE.Metal\",\n water: \"CDE.Water\",\n earth: \"CDE.Earth\",\n fire: \"CDE.Fire\",\n wood: \"CDE.Wood\",\n}\n\n/** Map aspect name \u2192 image path */\nexport const ASPECT_ICONS = {\n metal: \"systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\",\n water: \"systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n earth: \"systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n fire: \"systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n wood: \"systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n}\n\n/** Map aspect name \u2192 die face pair [yin, yang] (face=10 stored as 0) */\nexport const ASPECT_FACES = {\n metal: [3, 8],\n water: [1, 6],\n earth: [0, 5], // 0 = face \"10\"\n fire: [2, 7],\n wood: [4, 9],\n}\n\n/** Ordered aspect names by index (metal=0, water=1, earth=2, fire=3, wood=4) */\nexport const ASPECT_NAMES = [\"metal\", \"water\", \"earth\", \"fire\", \"wood\"]\n\n/**\n * Wu Xing generating/overcoming cycle.\n * For each active aspect, the five result categories in order:\n * [successes, auspicious, noxious, loksyu, tinji]\n */\nexport const WU_XING_CYCLE = {\n wood: [\"wood\", \"fire\", \"water\", \"earth\", \"metal\"],\n fire: [\"fire\", \"earth\", \"wood\", \"metal\", \"water\"],\n earth: [\"earth\", \"metal\", \"fire\", \"water\", \"wood\"],\n metal: [\"metal\", \"water\", \"earth\", \"wood\", \"fire\"],\n water: [\"water\", \"wood\", \"metal\", \"fire\", \"earth\"],\n}\n\nexport const TEMPLATE_PARTIALS = [\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-skills.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-magics.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-nghang.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-treasures.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-items.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-kungfus.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-character-spells.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-supernaturals.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-spells.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-kungfus.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/actor/parts/cde-npc-items.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-loksyu-app.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-tinji-app.html\",\n \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-wheel-app.html\",\n]\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { SYSTEM_ID } from \"./constants.js\"\n\n/**\n * Register all world/client settings for the system.\n * Called during the \"init\" hook before sheets and data-models are set up.\n */\nexport function registerSettings() {\n game.settings.register(SYSTEM_ID, \"loksyuData\", {\n scope: \"world\",\n config: false,\n type: Object,\n default: {\n wood: { yin: 0, yang: 0 },\n fire: { yin: 0, yang: 0 },\n earth: { yin: 0, yang: 0 },\n metal: { yin: 0, yang: 0 },\n water: { yin: 0, yang: 0 },\n },\n })\n\n game.settings.register(SYSTEM_ID, \"tinjiData\", {\n scope: \"world\",\n config: false,\n type: Number,\n default: 0,\n })\n}\n\n/**\n * Run any pending data migrations on the \"ready\" hook.\n * Reserved for future schema migrations.\n */\nexport async function migrateIfNeeded() {\n // No migrations required yet.\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { MAGICS, SUBTYPES } from \"./constants.js\"\n\nexport function preLocalizeConfig() {\n const localizeConfigObject = (obj, keys) => {\n for (const o of Object.values(obj)) {\n for (const key of keys) {\n o[key] = game.i18n.localize(o[key])\n }\n }\n }\n\n localizeConfigObject(SUBTYPES, [\"label\"])\n Object.values(MAGICS).forEach((magic) => {\n magic.label = game.i18n.localize(magic.label)\n magic.aspectlabel = game.i18n.localize(magic.aspectlabel)\n Object.values(magic.speciality).forEach((spec) => {\n spec.label = game.i18n.localize(spec.label)\n spec.labelelement = game.i18n.localize(spec.labelelement)\n })\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport function configureRuntime() {\n CONFIG.Actor.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/actor-banner.webp\"\n CONFIG.Adventure.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/adventure-banner.webp\"\n CONFIG.Cards.compendiumBanner = \"ui/banners/cards-banner.webp\"\n CONFIG.Item.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/item-banner.webp\"\n CONFIG.JournalEntry.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/journalentry-banner.webp\"\n CONFIG.Macro.compendiumBanner = \"ui/banners/macro-banner.webp\"\n CONFIG.Playlist.compendiumBanner = \"ui/banners/playlist-banner.webp\"\n CONFIG.RollTable.compendiumBanner = \"ui/banners/rolltable-banner.webp\"\n CONFIG.Scene.compendiumBanner = \"/systems/fvtt-chroniques-de-l-etrange/images/banners/scene-banner.webp\"\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class CharacterDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const numberField = (initial = 0, extra = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...extra })\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const boolField = (initial = false) => new fields.BooleanField({ required: true, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n const aspectField = (label, chinese) =>\n new fields.SchemaField({\n chinese: stringField(chinese),\n label: stringField(label),\n value: numberField(15, { min: 0 }),\n })\n\n const skillField = (label) =>\n new fields.SchemaField({\n label: stringField(label),\n specialities: stringField(\"\"),\n value: numberField(0, { min: 0 }),\n })\n\n const resourceField = (label) =>\n new fields.SchemaField({\n label: stringField(label),\n specialities: stringField(\"\"),\n value: numberField(0, { min: 0 }),\n debt: boolField(false),\n })\n\n const componentField = () =>\n new fields.SchemaField({\n value: stringField(\"\"),\n })\n\n const magicSpecialityField = () =>\n new fields.SchemaField({\n check: boolField(false),\n })\n\n const magicField = () =>\n new fields.SchemaField({\n visible: boolField(true),\n value: numberField(0, { min: 0 }),\n speciality: new fields.SchemaField({\n essence: magicSpecialityField(),\n mind: magicSpecialityField(),\n purification: magicSpecialityField(),\n manipulation: magicSpecialityField(),\n aura: magicSpecialityField(),\n acupuncture: magicSpecialityField(),\n elixirs: magicSpecialityField(),\n poisons: magicSpecialityField(),\n arsenal: magicSpecialityField(),\n potions: magicSpecialityField(),\n curse: magicSpecialityField(),\n transfiguration: magicSpecialityField(),\n necromancy: magicSpecialityField(),\n climatecontrol: magicSpecialityField(),\n goldenmagic: magicSpecialityField(),\n invocation: magicSpecialityField(),\n tracking: magicSpecialityField(),\n protection: magicSpecialityField(),\n punishment: magicSpecialityField(),\n domination: magicSpecialityField(),\n neutralization: magicSpecialityField(),\n divination: magicSpecialityField(),\n earthlyprayer: magicSpecialityField(),\n heavenlyprayer: magicSpecialityField(),\n fungseoi: magicSpecialityField(),\n }),\n })\n\n const treasureBranch = () =>\n new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n max: numberField(0, { min: 0 }),\n min: numberField(0, { min: 0 }),\n })\n\n const treasureLevel = () =>\n new fields.SchemaField({\n san: treasureBranch(),\n zing: treasureBranch(),\n })\n\n const schema = {\n concept: stringField(\"\"),\n guardian: numberField(0, { min: 0, max: 5 }),\n initiative: numberField(1, { min: 0 }),\n anti_initiative: numberField(24, { min: 0 }),\n description: htmlField(\"\"),\n prefs: new fields.SchemaField({\n typeofthrow: new fields.SchemaField({\n check: boolField(true),\n choice: stringField(\"0\"),\n }),\n }),\n prompt: new fields.SchemaField({\n typeofthrow: new fields.SchemaField({\n check: boolField(true),\n choice: stringField(\"0\"),\n }),\n configure: new fields.SchemaField({\n numberofdice: numberField(0),\n aspect: numberField(0),\n bonus: numberField(0),\n bonusauspiciousdice: numberField(0),\n typeofthrow: numberField(0),\n aspectskill: numberField(0),\n bonusmalusskill: numberField(0),\n aspectspeciality: numberField(0),\n rolldifficulty: numberField(0),\n bonusmalusspeciality: numberField(0),\n }),\n }),\n aspect: new fields.SchemaField({\n fire: aspectField(\"CDE.Fire\", \"\u328B\"),\n earth: aspectField(\"CDE.Earth\", \"\u328F\"),\n metal: aspectField(\"CDE.Metal\", \"\u328E\"),\n water: aspectField(\"CDE.Water\", \"\u328C\"),\n wood: aspectField(\"CDE.Wood\", \"\u328D\"),\n }),\n skills: new fields.SchemaField({\n art: skillField(\"CDE.Art\"),\n investigation: skillField(\"CDE.Investigation\"),\n erudition: skillField(\"CDE.Erudition\"),\n knavery: skillField(\"CDE.Knavery\"),\n wordliness: skillField(\"CDE.Wordliness\"),\n prowess: skillField(\"CDE.Prowess\"),\n sciences: skillField(\"CDE.Sciences\"),\n technologies: skillField(\"CDE.Technologies\"),\n kungfu: skillField(\"CDE.KungFu\"),\n rangedcombat: skillField(\"CDE.RangedCombat\"),\n }),\n resources: new fields.SchemaField({\n supply: resourceField(\"CDE.Supply\"),\n inquiry: resourceField(\"CDE.Inquiry\"),\n influence: resourceField(\"CDE.Influence\"),\n }),\n component: new fields.SchemaField({\n one: componentField(),\n two: componentField(),\n three: componentField(),\n four: componentField(),\n five: componentField(),\n six: componentField(),\n seven: componentField(),\n eight: componentField(),\n nine: componentField(),\n zero: componentField(),\n }),\n magics: new fields.SchemaField({\n internalcinnabar: magicField(),\n alchemy: magicField(),\n masteryoftheway: magicField(),\n exorcism: magicField(),\n geomancy: magicField(),\n }),\n threetreasures: new fields.SchemaField({\n heiyang: new fields.SchemaField({ value: numberField(0, { min: 0 }), max: numberField(0, { min: 0 }) }),\n heiyin: new fields.SchemaField({ value: numberField(0, { min: 0 }), max: numberField(0, { min: 0 }) }),\n dicelevel: new fields.SchemaField({\n level0d: treasureLevel(),\n level1d: treasureLevel(),\n level2d: treasureLevel(),\n }),\n }),\n experience: new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n max: numberField(0, { min: 0 }),\n min: numberField(0, { min: 0 }),\n }),\n }\n\n return schema\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class NpcDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const numberField = (initial = 0, extra = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...extra })\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const boolField = (initial = false) => new fields.BooleanField({ required: true, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n const aptitudeField = () =>\n new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n speciality: stringField(\"\"),\n })\n\n const trackedField = () =>\n new fields.SchemaField({\n value: numberField(0, { min: 0 }),\n calcul: numberField(0, { min: 0 }),\n note: stringField(\"\"),\n })\n\n return {\n type: stringField(\"\"),\n threat: numberField(0, { min: 0, max: 4 }), // profane(0) | apprentice(1) | initiate(2) | accomplished(3) | renowned(4)\n nuisance: numberField(0, { min: 0, max: 5 }), // figurant(0) | minion(1) | adversary(2) | ally(3) | boss(4) | divinity(5)\n initiative: numberField(1, { min: 0 }),\n anti_initiative: numberField(24, { min: 0 }),\n aptitudes: new fields.SchemaField({\n physical: aptitudeField(),\n martial: aptitudeField(),\n mental: aptitudeField(),\n social: aptitudeField(),\n spiritual: aptitudeField(),\n }),\n vitality: trackedField(),\n hei: trackedField(),\n description: htmlField(\"\"),\n prefs: new fields.SchemaField({\n typeofthrow: new fields.SchemaField({\n check: boolField(false),\n choice: stringField(\"0\"),\n }),\n }),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class EquipmentDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const numberField = (initial = 0, extra = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...extra })\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n quantity: numberField(1, { min: 0 }),\n weight: numberField(0, { min: 0 }),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class KungfuDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const boolField = (initial = false) => new fields.BooleanField({ required: true, initial })\n\n const techniqueField = () =>\n new fields.SchemaField({\n check: boolField(false),\n name: stringField(\"\"),\n activation: stringField(\"action-attack\"), // action-attack | action-defense | action-aid | action-attack-defense | reaction | dice | damage-inflicted | damage-received\n technique: htmlField(\"\"),\n })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n orientation: stringField(\"yin\"), // yin | yang | yinyang\n aspect: stringField(\"metal\"), // metal | eau | terre | feu | bois\n skill: stringField(\"kungfu\"), // kungfu | rangedcombat\n speciality: stringField(\"\"),\n style: stringField(\"\"),\n techniques: new fields.SchemaField({\n technique1: techniqueField(),\n technique2: techniqueField(),\n technique3: techniqueField(),\n }),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class SpellDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n specialityname: stringField(\"\"),\n associatedelement: stringField(\"metal\"), // metal | eau | terre | feu | bois\n hei: stringField(\"\"),\n realizationtimeritual: stringField(\"\"),\n realizationtimeaccelerated: stringField(\"\"),\n flashback: stringField(\"\"),\n components: htmlField(\"\"),\n effects: htmlField(\"\"),\n examples: htmlField(\"\"),\n notes: htmlField(\"\"),\n discipline: stringField(\"internalcinnabar\"),\n heiType: stringField(\"yin\"),\n heiCost: new fields.NumberField({ required: true, nullable: false, integer: true, min: 0, initial: 1 }),\n difficulty: new fields.NumberField({ required: true, nullable: false, integer: true, min: 0, initial: 1 }),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class SupernaturalDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n notes: htmlField(\"\"),\n heiType: stringField(\"yin\"),\n heiCost: new fields.NumberField({ required: true, nullable: false, integer: true, min: 0, initial: 0 }),\n trigger: stringField(\"\"),\n effects: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class WeaponDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n weaponType: stringField(\"melee\"),\n material: stringField(\"\"),\n damageAspect: stringField(\"metal\"),\n damageBase: intField(1),\n range: stringField(\"contact\"), // contact | courte | mediane | longue | extreme\n obtainLevel: intField(0, { min: 0, max: 5 }),\n obtainDifficulty: intField(0, { min: 0, max: 3 }),\n quantity: intField(1),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class ArmorDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n protectionValue: intField(0),\n domain: stringField(\"\"),\n obtainLevel: intField(0, { min: 0, max: 5 }),\n obtainDifficulty: intField(0, { min: 0, max: 3 }),\n quantity: intField(1),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class SanheiDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n const propertySchema = () => new fields.SchemaField({\n name: stringField(\"\"),\n heiCost: intField(0),\n heiType: stringField(\"yin\"),\n description: htmlField(\"\"),\n })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n heiType: stringField(\"yin\"),\n properties: new fields.SchemaField({\n prop1: propertySchema(),\n prop2: propertySchema(),\n prop3: propertySchema(),\n }),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport default class IngredientDataModel extends foundry.abstract.TypeDataModel {\n static defineSchema() {\n const { fields } = foundry.data\n const stringField = (initial = \"\") => new fields.StringField({ required: true, nullable: false, initial })\n const htmlField = (initial = \"\") => new fields.HTMLField({ required: true, nullable: false, initial, textSearch: true })\n const intField = (initial = 0, opts = {}) => new fields.NumberField({ required: true, nullable: false, integer: true, initial, ...opts })\n\n return {\n reference: stringField(\"\"),\n description: htmlField(\"\"),\n school: stringField(\"all\"),\n obtainLevel: intField(0, { min: 0, max: 5 }),\n obtainDifficulty: intField(0, { min: 0, max: 3 }),\n quantity: intField(1),\n notes: htmlField(\"\"),\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nexport class CDEMessage extends ChatMessage {\n async renderHTML({ canDelete, canClose = false, ...rest } = {}) {\n const html = await super.renderHTML({ canDelete, canClose, ...rest })\n this.#enrichChatCard(html)\n return html\n }\n\n getAssociatedActor() {\n if (this.speaker.scene && this.speaker.token) {\n const scene = game.scenes.get(this.speaker.scene)\n const token = scene?.tokens.get(this.speaker.token)\n if (token) return token.actor\n }\n return game.actors.get(this.speaker.actor)\n }\n\n #enrichChatCard(html) {\n const actor = this.getAssociatedActor()\n\n let img\n let nameText\n if (this.isContentVisible) {\n img = actor?.img ?? this.author.avatar\n nameText = this.alias\n } else {\n img = this.author.avatar\n nameText = this.author.name\n }\n\n const avatar = document.createElement(\"a\")\n avatar.classList.add(\"avatar\")\n if (actor) avatar.dataset.uuid = actor.uuid\n const avatarImg = document.createElement(\"img\")\n Object.assign(avatarImg, { src: img, alt: nameText })\n avatar.append(avatarImg)\n\n const name = document.createElement(\"span\")\n name.classList.add(\"name-stacked\")\n const title = document.createElement(\"span\")\n title.classList.add(\"title\")\n title.append(nameText)\n name.append(title)\n\n const sender = html.querySelector(\".message-sender\")\n sender?.replaceChildren(avatar, name)\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { ACTOR_TYPES } from \"../config/constants.js\"\n\nexport class CDEActor extends Actor {\n getRollData() {\n const data = this.toObject(false).system\n return data\n }\n\n prepareBaseData() {\n super.prepareBaseData()\n\n if (this.type === ACTOR_TYPES.character) {\n this.system.anti_initiative = 25 - (this.system.initiative ?? 0)\n }\n\n if (this.type === ACTOR_TYPES.npc) {\n this.system.vitality.calcul = (this.system.aptitudes.physical.value ?? 0) * 4\n this.system.hei.calcul = (this.system.aptitudes.spiritual.value ?? 0) * 4\n this.system.anti_initiative = 25 - (this.system.initiative ?? 0)\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/** Default icons per item type. */\nconst DEFAULT_ICONS = {\n kungfu: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-kungfu.svg\",\n spell: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-spell.svg\",\n supernatural: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-supernatural.svg\",\n weapon: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-weapon.svg\",\n armor: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-armor.svg\",\n sanhei: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-sanhei.svg\",\n ingredient: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-ingredient.svg\",\n item: \"systems/fvtt-chroniques-de-l-etrange/images/icons/icon-item.svg\",\n};\n\nexport class CDEItem extends Item {\n\n /** @override */\n async _preCreate(data, options, userId) {\n await super._preCreate(data, options, userId);\n const defaultIcon = DEFAULT_ICONS[this.type];\n if (defaultIcon && (!data.img || data.img === Item.DEFAULT_ICON)) {\n this.updateSource({ img: defaultIcon });\n }\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nconst DIGIT_LABELS = [\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-1.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-2.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-3.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-4.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-5.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-6.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-7.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-8.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-9.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/digit/d10-10.webp\",\n]\n\nconst CLASSIC_LABELS = [\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-1.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-2.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-3.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-4.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-5.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-6.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-7.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-8.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-9.webp\",\n \"systems/fvtt-chroniques-de-l-etrange/images/dice-so-nice/d10-10.webp\",\n]\n\nexport function registerDice() {\n Hooks.once(\"diceSoNiceReady\", (dice3d) => {\n dice3d.addColorset(\n {\n name: \"cde\",\n description: \"CdE\",\n foreground: \"#000000\",\n background: \"#ffffff\",\n edge: \"#ffffff\",\n font: \"DeliusUnicase\",\n texture: \"ice\",\n material: \"plastic\",\n },\n \"preferred\",\n )\n\n dice3d.addSystem({ id: \"fvtt-chroniques-de-l-etrangedigit\", name: \"Chroniques de l'\u00E9trange digits\" }, \"preferred\")\n dice3d.addDicePreset({ type: \"d10\", labels: DIGIT_LABELS, system: \"fvtt-chroniques-de-l-etrangedigit\" })\n\n dice3d.addSystem({ id: \"fvtt-chroniques-de-l-etrange\", name: \"Chroniques de l'\u00E9trange\" }, \"preferred\")\n dice3d.addDicePreset({ type: \"d10\", labels: CLASSIC_LABELS, system: \"fvtt-chroniques-de-l-etrange\" })\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { MAGICS } from \"../config/constants.js\"\n\nexport function registerHandlebarsHelpers() {\n const { Handlebars } = globalThis\n if (!Handlebars) return\n\n Handlebars.registerHelper(\"select\", function (selected, options) {\n const escapedValue = RegExp.escape(Handlebars.escapeExpression(selected))\n const rgx = new RegExp(` value=[\"']${escapedValue}[\"']`)\n const html = options.fn(this)\n return html.replace(rgx, \"$& selected\")\n })\n\n Handlebars.registerHelper(\"getMagicBackground\", function (magic) {\n return game.i18n.localize(MAGICS[magic]?.background ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicLabel\", function (magic) {\n return game.i18n.localize(MAGICS[magic]?.label ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicAspectLabel\", function (magic) {\n return game.i18n.localize(MAGICS[magic]?.aspectlabel ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityLabel\", function (magic, speciality) {\n return game.i18n.localize(MAGICS[magic]?.speciality?.[speciality]?.label ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityClassIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.classicon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.icon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityElementIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.elementicon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityLabelIcon\", function (magic, speciality) {\n return MAGICS[magic]?.speciality?.[speciality]?.labelicon ?? \"\"\n })\n\n Handlebars.registerHelper(\"getMagicSpecialityLabelElement\", function (magic, speciality) {\n return game.i18n.localize(MAGICS[magic]?.speciality?.[speciality]?.labelelement ?? \"\")\n })\n\n Handlebars.registerHelper(\"getMagicAspectIcon\", function (magic) {\n const icons = {\n internalcinnabar: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\",\n alchemy: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n masteryoftheway: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n exorcism: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n geomancy: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n }\n return icons[magic] ?? \"\"\n })\n\n Handlebars.registerHelper(\"getElementIcon\", function (aspect) {\n const icons = {\n metal: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_metal.webp\",\n water: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n earth: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n fire: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n wood: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n // legacy French keys\n eau: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_eau.webp\",\n terre: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_terre.webp\",\n feu: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_feu.webp\",\n bois: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_bois.webp\",\n }\n return icons[aspect] ?? \"\"\n })\n\n Handlebars.registerHelper(\"getOrientationIcon\", function (orientation) {\n const icons = {\n yin: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yin.webp\",\n yang: \"/systems/fvtt-chroniques-de-l-etrange/images/cde_yang.webp\",\n yinyang: \"/systems/fvtt-chroniques-de-l-etrange/images/yin_yang.webp\",\n }\n return icons[orientation] ?? \"\"\n })\n\n Handlebars.registerHelper(\"getOrientationLabel\", function (orientation) {\n const keys = {\n yin: \"CDE.OrientationYin\",\n yang: \"CDE.OrientationYang\",\n yinyang: \"CDE.OrientationYinYang\",\n }\n return game.i18n.localize(keys[orientation] ?? \"CDE.Orientation\")\n })\n\n Handlebars.registerHelper(\"getActivationLabel\", function (activation) {\n const keys = {\n \"action-attack\": \"CDE.ActivationAttack\",\n \"action-defense\": \"CDE.ActivationDefense\",\n \"action-aid\": \"CDE.ActivationAid\",\n \"action-attack-defense\": \"CDE.ActivationAttackOrDefense\",\n reaction: \"CDE.ActivationReaction\",\n dice: \"CDE.ActivationDice\",\n \"damage-inflicted\": \"CDE.ActivationDamageInflicted\",\n \"damage-received\": \"CDE.ActivationDamageReceived\",\n }\n return game.i18n.localize(keys[activation] ?? \"CDE.Activation\")\n })\n\n /**\n * Compute the SVG x,y coordinates for a cran on the initiative wheel.\n * Cran 1\u201324 are arranged counter-clockwise from the bottom (reference at 6 o'clock).\n * angle = 90\u00B0 + cran * 15\u00B0 (counter-clockwise = positive in standard math, negative in SVG).\n * In SVG coords: x = cx + r*cos(a), y = cy - r*sin(a) [y-axis is flipped in SVG].\n */\n Handlebars.registerHelper(\"cranPosition\", function (cran, cx, cy, r) {\n const angleDeg = 90 + cran * 15 // counter-clockwise from bottom\n const angleRad = (angleDeg * Math.PI) / 180\n const x = Math.round(cx + r * Math.cos(angleRad))\n const y = Math.round(cy - r * Math.sin(angleRad))\n return { x, y }\n })\n\n /** X offset for overlapping fighters on the same cran. Centres a 30px image on the cran cx. */\n Handlebars.registerHelper(\"fighterX\", function (cx, index, total) {\n const offset = total > 1 ? (index - (total - 1) / 2) * 34 : 0\n return Math.round(cx - 15 + offset)\n })\n\n /** Y offset for fighters \u2014 positions image just above the cran circle. */\n Handlebars.registerHelper(\"fighterY\", function (cy, index, total) {\n return Math.round(cy - 50)\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { TEMPLATE_PARTIALS } from \"../config/constants.js\"\n\nexport async function preloadPartials() {\n return foundry.applications.handlebars.loadTemplates(TEMPLATE_PARTIALS)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Initiative determination system for Chroniques de l'\u00C9trange.\n *\n * PJ formula: Initiative = Prouesse + Premi\u00E8re action (comp\u00E9tence/ressource/magie)\n * PNJ formula: Initiative = Aptitude physique + Premi\u00E8re action (aptitude)\n *\n * Range 1-24 ; anti-initiative = 25 \u2212 initiative.\n * Combat order is ascending (low initiative acts first).\n */\n\nconst PC_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-initiative-prompt.html\"\nconst NPC_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-initiative-prompt-npc.html\"\nconst RESULT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-initiative-result.html\"\n\n/** Skills, resources and magics available as \"premi\u00E8re action\" for a PC. */\nfunction buildPCOptions(sys) {\n const sk = sys.skills ?? {}\n const rs = sys.resources ?? {}\n const mg = sys.magics ?? {}\n return [\n { key: \"art\", label: game.i18n.localize(\"CDE.Art\"), value: sk.art?.value ?? 0 },\n { key: \"investigation\", label: game.i18n.localize(\"CDE.Investigation\"), value: sk.investigation?.value ?? 0 },\n { key: \"erudition\", label: game.i18n.localize(\"CDE.Erudition\"), value: sk.erudition?.value ?? 0 },\n { key: \"knavery\", label: game.i18n.localize(\"CDE.Knavery\"), value: sk.knavery?.value ?? 0 },\n { key: \"wordliness\", label: game.i18n.localize(\"CDE.Wordliness\"), value: sk.wordliness?.value ?? 0 },\n { key: \"prowess\", label: game.i18n.localize(\"CDE.Prowess\"), value: sk.prowess?.value ?? 0 },\n { key: \"sciences\", label: game.i18n.localize(\"CDE.Sciences\"), value: sk.sciences?.value ?? 0 },\n { key: \"technologies\", label: game.i18n.localize(\"CDE.Technologies\"), value: sk.technologies?.value ?? 0 },\n { key: \"kungfu\", label: game.i18n.localize(\"CDE.KungFu\"), value: sk.kungfu?.value ?? 0 },\n { key: \"rangedcombat\", label: game.i18n.localize(\"CDE.RangedCombat\"), value: sk.rangedcombat?.value ?? 0 },\n { key: \"supply\", label: game.i18n.localize(\"CDE.Supply\"), value: rs.supply?.value ?? 0 },\n { key: \"inquiry\", label: game.i18n.localize(\"CDE.Inquiry\"), value: rs.inquiry?.value ?? 0 },\n { key: \"influence\", label: game.i18n.localize(\"CDE.Influence\"), value: rs.influence?.value ?? 0 },\n { key: \"internalcinnabar\", label: game.i18n.localize(\"CDE.InternalCinnabar\"), value: mg.internalcinnabar?.value ?? 0 },\n { key: \"alchemy\", label: game.i18n.localize(\"CDE.Alchemy\"), value: mg.alchemy?.value ?? 0 },\n { key: \"masteryoftheway\", label: game.i18n.localize(\"CDE.MasteryOfTheWay\"), value: mg.masteryoftheway?.value ?? 0 },\n { key: \"exorcism\", label: game.i18n.localize(\"CDE.Exorcism\"), value: mg.exorcism?.value ?? 0 },\n { key: \"geomancy\", label: game.i18n.localize(\"CDE.Geomancy\"), value: mg.geomancy?.value ?? 0 },\n ]\n}\n\n/** Aptitudes available as \"premi\u00E8re action\" for an NPC. */\nfunction buildNPCOptions(sys) {\n const ap = sys.aptitudes ?? {}\n return [\n { key: \"physical\", label: game.i18n.localize(\"CDE.Physical\"), value: ap.physical?.value ?? 0 },\n { key: \"martial\", label: game.i18n.localize(\"CDE.Martial\"), value: ap.martial?.value ?? 0 },\n { key: \"mental\", label: game.i18n.localize(\"CDE.Mental\"), value: ap.mental?.value ?? 0 },\n { key: \"social\", label: game.i18n.localize(\"CDE.Social\"), value: ap.social?.value ?? 0 },\n { key: \"spiritual\", label: game.i18n.localize(\"CDE.Spiritual\"), value: ap.spiritual?.value ?? 0 },\n ]\n}\n\n/** Parse the dialog element and extract firstaction + modifier. */\nfunction readInitFields(dialog) {\n const root = dialog.element ?? dialog\n const selectedKey = root.querySelector(\"select[name='firstaction']\")?.value ?? \"\"\n const modifier = parseInt(root.querySelector(\"input[name='modifier']\")?.value ?? \"0\", 10) || 0\n return { selectedKey, modifier }\n}\n\n/** Post a styled initiative chat message. */\nasync function sendInitChatMessage({ actor, baseName, baseValue, actionName, actionValue, modifier, initiative, antiInitiative }) {\n const html = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE, {\n actorName: actor.name,\n actorImg: actor.img,\n baseName,\n baseValue,\n actionName,\n actionValue,\n modifier,\n hasModifier: modifier !== 0,\n initiative,\n antiInitiative,\n })\n await ChatMessage.create({\n user: game.user.id,\n speaker: ChatMessage.getSpeaker({ actor }),\n content: html,\n })\n}\n\n/**\n * Open the PC initiative dialog, compute initiative (Prouesse + Premi\u00E8re action + modificateur)\n * and update the actor, then post a chat card.\n */\nexport async function rollInitiativePC(actor) {\n const sys = actor.system\n const prowess = sys.skills?.prowess?.value ?? 0\n const options = buildPCOptions(sys)\n const baseName = game.i18n.localize(\"CDE.Prowess\")\n\n const content = await foundry.applications.handlebars.renderTemplate(PC_PROMPT_TEMPLATE, {\n prowessValue: prowess,\n options,\n modifier: 0,\n })\n\n const result = await foundry.applications.api.DialogV2.prompt({\n window: { title: game.i18n.localize(\"CDE.InitiativeRoll\") },\n content,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (_ev, _btn, dialog) => readInitFields(dialog),\n },\n })\n if (!result) return\n\n const { selectedKey, modifier } = result\n const selected = options.find((o) => o.key === selectedKey) ?? options[0]\n const rawValue = prowess + selected.value + modifier\n const initiative = Math.max(1, Math.min(24, rawValue))\n const antiInit = 25 - initiative\n\n await actor.update({ \"system.initiative\": initiative })\n await sendInitChatMessage({\n actor,\n baseName,\n baseValue: prowess,\n actionName: selected.label,\n actionValue: selected.value,\n modifier,\n initiative,\n antiInitiative: antiInit,\n })\n}\n\n/**\n * Open the NPC initiative dialog, compute initiative (Aptitude physique + Premi\u00E8re action + modificateur)\n * and update the actor, then post a chat card.\n */\nexport async function rollInitiativeNPC(actor) {\n const sys = actor.system\n const physical = sys.aptitudes?.physical?.value ?? 0\n const options = buildNPCOptions(sys)\n const baseName = game.i18n.localize(\"CDE.Physical\")\n\n const content = await foundry.applications.handlebars.renderTemplate(NPC_PROMPT_TEMPLATE, {\n physicalValue: physical,\n options,\n modifier: 0,\n })\n\n const result = await foundry.applications.api.DialogV2.prompt({\n window: { title: game.i18n.localize(\"CDE.InitiativeRoll\") },\n content,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (_ev, _btn, dialog) => readInitFields(dialog),\n },\n })\n if (!result) return\n\n const { selectedKey, modifier } = result\n const selected = options.find((o) => o.key === selectedKey) ?? options[0]\n const rawValue = physical + selected.value + modifier\n const initiative = Math.max(1, Math.min(24, rawValue))\n const antiInit = 25 - initiative\n\n await actor.update({ \"system.initiative\": initiative })\n await sendInitChatMessage({\n actor,\n baseName,\n baseValue: physical,\n actionName: selected.label,\n actionValue: selected.value,\n modifier,\n initiative,\n antiInitiative: antiInit,\n })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Loksyu / TinJi settings-based helpers.\n *\n * Data is stored as world settings instead of singleton Actor documents.\n */\n\nimport { SYSTEM_ID, WU_XING_CYCLE, ASPECT_FACES } from \"../../config/constants.js\"\n\n/** Read the current loksyu data object from world settings */\nexport function getLoksyuData() {\n return game.settings.get(SYSTEM_ID, \"loksyuData\") ?? {\n wood: {yin:0,yang:0}, fire: {yin:0,yang:0}, earth: {yin:0,yang:0}, metal: {yin:0,yang:0}, water: {yin:0,yang:0},\n }\n}\n\n/** Write the loksyu data object to world settings */\nexport async function setLoksyuData(data) {\n await game.settings.set(SYSTEM_ID, \"loksyuData\", data)\n Hooks.callAll(\"cde:loksyuUpdated\", data)\n}\n\n/** Read current TinJi value from world settings */\nexport function getTinjiValue() {\n return game.settings.get(SYSTEM_ID, \"tinjiData\") ?? 0\n}\n\n/** Write TinJi value to world settings */\nexport async function setTinjiValue(value) {\n await game.settings.set(SYSTEM_ID, \"tinjiData\", Math.max(0, value))\n Hooks.callAll(\"cde:tinjiUpdated\", Math.max(0, value))\n}\n\n/**\n * After a WuXing roll, add the loksyu faces (yin + yang) of the relevant\n * aspect to the loksyu settings data.\n *\n * @param {string} activeAspect - e.g. \"fire\"\n * @param {Object} faces - Die face counts { 0: n, 1: n, \u2026, 9: n }\n */\nexport async function updateLoksyuFromRoll(activeAspect, faces) {\n const cycle = WU_XING_CYCLE[activeAspect]\n if (!cycle) return\n\n const lokAspect = cycle[3]\n const [yinFace, yangFace] = ASPECT_FACES[lokAspect] ?? []\n if (yinFace === undefined) return\n\n const yinCount = faces[yinFace] ?? 0\n const yangCount = faces[yangFace] ?? 0\n if (yinCount === 0 && yangCount === 0) return\n\n const data = getLoksyuData()\n const current = data[lokAspect] ?? { yin: 0, yang: 0 }\n data[lokAspect] = {\n yin: (current.yin ?? 0) + yinCount,\n yang: (current.yang ?? 0) + yangCount,\n }\n await setLoksyuData(data)\n}\n\n/**\n * After a WuXing roll, add tinji faces to the TinJi settings.\n *\n * @param {number} count - Number of tinji faces rolled\n */\nexport async function updateTinjiFromRoll(count) {\n if (!count || count <= 0) return\n const current = getTinjiValue()\n await setTinjiValue(current + count)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Wu Xing rolling system for Chroniques de l'\u00C9trange.\n *\n * The Wu Xing cycle maps each aspect (by index 0-4) to die face groups:\n * - metal=0 : faces 3,8\n * - water=1 : faces 1,6\n * - earth=2 : faces 0/10,5\n * - fire=3 : faces 2,7\n * - wood=4 : faces 4,9\n *\n * For a given active aspect the five result categories are:\n * successes / auspicious / noxious / loksyu (yin face, yang face) / tinji\n * Each category is associated with one of the five aspects in Wu Xing cycle order.\n */\n\nimport { MAGICS, ASPECT_LABELS, ASPECT_ICONS, ASPECT_FACES, ASPECT_NAMES, WU_XING_CYCLE } from \"../config/constants.js\"\nimport { updateLoksyuFromRoll, updateTinjiFromRoll } from \"./apps/singletons.js\"\n\nconst RESULT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-dice-result.html\"\nconst SKILL_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-skill-dice-prompt.html\"\nconst SKILL_SPECIAL_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-skill-special-dice-prompt.html\"\nconst MAGIC_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-magic-dice-prompt.html\"\nconst WEAPON_PROMPT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-weapon-dice-prompt.html\"\n\n/** Maps i18n element label \u2192 aspect name (for speciality default aspect lookup) */\nconst LABELELEMENT_TO_ASPECT = {\n \"CDE.Metal\": \"metal\",\n \"CDE.Water\": \"water\",\n \"CDE.Earth\": \"earth\",\n \"CDE.Fire\": \"fire\",\n \"CDE.Wood\": \"wood\",\n}\n\n/** Maps weapon range string \u2192 dice malus applied to the attack pool */\nconst RANGE_MALUS = {\n contact: 0,\n courte: 0,\n mediane: -1,\n longue: -2,\n extreme: -3,\n}\n\n/** Maps weapon type string \u2192 default skill key */\nconst WEAPON_TYPE_SKILL = {\n melee: \"kungfu\",\n thrown: \"rangedcombat\",\n ranged: \"rangedcombat\",\n firearm: \"rangedcombat\",\n}\n\n/** Maps weapon damageAspect name \u2192 ASPECT_NAMES index */\nconst WEAPON_ASPECT_INDEX = { metal: 0, eau: 1, water: 1, terre: 2, earth: 2, feu: 3, fire: 3, bois: 4, wood: 4 }\n\n/** Count how many times each die face appeared in the roll results */\nfunction countFaces(rollResults) {\n const counts = { 1:0, 2:0, 3:0, 4:0, 5:0, 6:0, 7:0, 8:0, 9:0, 0:0 }\n for (const die of rollResults) {\n const face = die.result === 10 ? 0 : die.result\n counts[face]++\n }\n return counts\n}\n\n/**\n * Compute Wu Xing result categories from face counts and active aspect.\n * Returns { successesdice, auspiciousdice, noxiousdice, loksyudice, tinjidice, loksyurepartition }\n */\nfunction computeWuXingResults(faces, aspectName, bonusAuspicious = 0) {\n const cycle = WU_XING_CYCLE[aspectName]\n if (!cycle) return null\n\n const [succAspect, ausAspect, noxAspect, lokAspect, tinAspect] = cycle\n const [succYin, succYang] = ASPECT_FACES[succAspect]\n const [ausYin, ausYang] = ASPECT_FACES[ausAspect]\n const [noxYin, noxYang] = ASPECT_FACES[noxAspect]\n const [lokYin, lokYang] = ASPECT_FACES[lokAspect]\n const [tinYin, tinYang] = ASPECT_FACES[tinAspect]\n\n const yin = game.i18n.localize(\"CDE.Yin\")\n const yang = game.i18n.localize(\"CDE.Yang\")\n\n return {\n successesdice: faces[succYin] + faces[succYang],\n auspiciousdice: faces[ausYin] + faces[ausYang] + bonusAuspicious,\n noxiousdice: faces[noxYin] + faces[noxYang],\n loksyudice: faces[lokYin] + faces[lokYang],\n loksyurepartition: `[${yin}(${faces[lokYin]}) ${yang}(${faces[lokYang]})]`,\n tinjidice: faces[tinYin] + faces[tinYang],\n }\n}\n\n/** Read a named field from a dialog DOM element */\nfunction readField(dlg, name) {\n const el = dlg.querySelector(`[name=\"${name}\"]`)\n if (!el) return null\n return el.type === \"checkbox\" ? el.checked : el.value\n}\n\n/**\n * Open a DialogV2.prompt with the given template + data and return the resolved form values.\n * The callback receives the DialogV2 application instance; fields are read from its .element.\n * @returns {Promise|null>}\n */\nasync function showRollPrompt({ title, template, data, fields }) {\n const content = await foundry.applications.handlebars.renderTemplate(template, data)\n return foundry.applications.api.DialogV2.prompt({\n window: { title },\n content,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (event, button, dialog) => {\n // In AppV2, dialog is the application instance; .element is the root HTMLElement\n const root = dialog.element ?? dialog\n const result = {}\n for (const field of fields) {\n result[field] = readField(root, field)\n }\n return result\n },\n },\n })\n}\n\n/**\n * Open the skill roll prompt and return the user-confirmed parameters.\n * @param {object} params - Initial values\n * @returns {Promise}\n */\nasync function showSkillPrompt(params) {\n return showRollPrompt({\n title: params.title,\n template: params.isSpecial ? SKILL_SPECIAL_PROMPT_TEMPLATE : SKILL_PROMPT_TEMPLATE,\n data: {\n numberofdice: params.numberofdice,\n aspect: Number(params.aspect ?? 0),\n bonusmalus: params.bonusmalus ?? 0,\n woundmalus: params.woundmalus ?? 0,\n bonusauspiciousdice: params.bonusauspiciousdice ?? 0,\n typeofthrow: Number(params.typeofthrow ?? 0),\n },\n fields: [\"aspect\", \"bonusmalus\", \"woundmalus\", \"bonusauspiciousdice\", \"typeofthrow\"],\n })\n}\n\n/**\n * Open the magic roll prompt and return the user-confirmed parameters.\n */\nasync function showMagicPrompt(params) {\n return showRollPrompt({\n title: params.title,\n template: MAGIC_PROMPT_TEMPLATE,\n data: {\n numberofdice: params.numberofdice ?? 0,\n aspectskill: Number(params.aspectskill ?? 0),\n bonusmalusskill: params.bonusmalusskill ?? 0,\n bonusauspiciousdice: params.bonusauspiciousdice ?? 0,\n aspectspeciality: Number(params.aspectspeciality ?? 0),\n rolldifficulty: params.rolldifficulty ?? 1,\n bonusmalusspeciality: params.bonusmalusspeciality ?? 0,\n heispend: params.heispend ?? 0,\n typeofthrow: Number(params.typeofthrow ?? 0),\n },\n fields: [\"aspectskill\", \"bonusmalusskill\", \"bonusauspiciousdice\",\n \"aspectspeciality\", \"rolldifficulty\", \"bonusmalusspeciality\",\n \"heispend\", \"typeofthrow\"],\n })\n}\n\n/**\n * Open the weapon attack roll prompt and return user-confirmed parameters.\n */\nasync function showWeaponPrompt(params) {\n return showRollPrompt({\n title: params.title,\n template: WEAPON_PROMPT_TEMPLATE,\n data: {\n numberofdice: params.numberofdice ?? 0,\n weaponName: params.weaponName ?? \"\",\n weaponTypeLabel: params.weaponTypeLabel ?? \"CDE.Weapon\",\n weaponAspectIcon: params.weaponAspectIcon ?? \"\",\n weaponAspectLabel: params.weaponAspectLabel ?? \"\",\n damageBase: params.damageBase ?? 1,\n weaponskill: params.weaponskill ?? \"kungfu\",\n aspect: Number(params.aspect ?? 0),\n effectiverange: params.effectiverange ?? \"contact\",\n bonusmalus: params.bonusmalus ?? 0,\n woundmalus: params.woundmalus ?? 0,\n bonusauspiciousdice: params.bonusauspiciousdice ?? 0,\n typeofthrow: Number(params.typeofthrow ?? 0),\n },\n fields: [\"weaponskill\", \"aspect\", \"effectiverange\", \"bonusmalus\", \"woundmalus\",\n \"bonusauspiciousdice\", \"typeofthrow\"],\n })\n}\n\n/**\n * Build and send a single enriched ChatMessage containing both the roll\n * (for Dice So Nice) and the Wu Xing result card.\n */\nasync function sendResultMessage(actor, resultData, roll, rollMode) {\n const html = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE, resultData)\n return ChatMessage.create({\n user: game.user.id,\n speaker: ChatMessage.getSpeaker({ actor }),\n content: html,\n rolls: [roll],\n rollMode,\n flags: {\n \"fvtt-chroniques-de-l-etrange\": { rollResult: { ...resultData } },\n },\n })\n}\n\nconst ROLL_MODES = [\"roll\", \"gmroll\", \"blindroll\", \"selfroll\"]\n\n/**\n * Main entry point: roll dice for a given actor.\n *\n * @param {Actor} actor\n * @param {string} rollKey - e.g. \"prowess-skill\", \"fire-aspect\", \"alchemy-magic-elixirs\"\n */\nexport async function rollForActor(actor, rollKey) {\n const parts = rollKey.split(\"-\")\n const skillLibel = parts[0]\n const typeLibel = parts[1]\n const specialLibel = parts[2] ?? null\n\n const sys = actor.system\n const typeOfThrow = Number(sys.prefs?.typeofthrow?.choice ?? 0)\n\n let numberofdice = 0\n let title = \"\"\n let isSpecial = false\n let isMagic = false\n let isMagicSpecial = false\n let kfDefaultAspect = -1 // set in \"itemkungfu\" case, used when computing defaultAspect\n\n // ---- Determine dice count + title ----\n const MAGIC_I18N_KEYS = {\n internalcinnabar: \"CDE.InternalCinnabar\",\n alchemy: \"CDE.Alchemy\",\n masteryoftheway: \"CDE.MasteryOfTheWay\",\n exorcism: \"CDE.Exorcism\",\n geomancy: \"CDE.Geomancy\",\n }\n\n switch (typeLibel) {\n case \"aspect\":\n numberofdice = sys.aspect[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.aspect[skillLibel]?.label ?? \"CDE.Roll\")\n break\n case \"aptitude\":\n // NPC aptitude roll \u2014 flat pool with WuXing prompt\n numberofdice = sys.aptitudes?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(`CDE.${skillLibel.charAt(0).toUpperCase() + skillLibel.slice(1)}`)\n break\n case \"skill\":\n numberofdice = sys.skills?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.skills?.[skillLibel]?.label ?? \"CDE.Roll\")\n break\n case \"special\":\n numberofdice = sys.skills?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.skills?.[skillLibel]?.label ?? \"CDE.Roll\")\n title += ` [${game.i18n.localize(\"CDE.Speciality\")}]`\n isSpecial = true\n if (!sys.skills?.[skillLibel]?.specialities) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error2\"))\n return\n }\n break\n case \"resource\":\n numberofdice = sys.resources?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.resources?.[skillLibel]?.label ?? \"CDE.Roll\")\n break\n case \"field\":\n numberofdice = sys.resources?.[skillLibel]?.value ?? 0\n title = game.i18n.localize(sys.resources?.[skillLibel]?.label ?? \"CDE.Roll\")\n title += ` [${game.i18n.localize(\"CDE.Field\")}]`\n isSpecial = true\n if (!sys.resources?.[skillLibel]?.specialities) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error4\"))\n return\n }\n break\n case \"magic\":\n numberofdice = sys.magics?.[skillLibel]?.value ?? 0\n isMagic = true\n title = game.i18n.localize(MAGIC_I18N_KEYS[skillLibel] ?? \"CDE.Magics\")\n break\n case \"magicspecial\":\n numberofdice = sys.magics?.[skillLibel]?.value ?? 0\n isMagicSpecial = true\n isMagic = true\n if (!sys.magics?.[skillLibel]?.speciality?.[specialLibel]?.check) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error6\"))\n return\n }\n title = `${game.i18n.localize(MAGIC_I18N_KEYS[skillLibel] ?? \"CDE.Magics\")} [${game.i18n.localize(MAGICS?.[skillLibel]?.speciality?.[specialLibel]?.label ?? \"\")}]`\n break\n case \"itemkungfu\": {\n // skillLibel = item._id \u2014 look up the kungfu item to find which skill + aspect to use\n const kfItem = actor.items.get(skillLibel)\n if (!kfItem) { ui.notifications.warn(game.i18n.localize(\"CDE.Error0\")); return }\n const kfSkill = kfItem.system.skill ?? \"kungfu\"\n numberofdice = sys.skills?.[kfSkill]?.value ?? 0\n title = `${kfItem.name} [${game.i18n.localize(sys.skills?.[kfSkill]?.label ?? \"CDE.KungFu\")}]`\n kfDefaultAspect = ASPECT_NAMES.indexOf(kfItem.system.aspect ?? \"metal\")\n if (kfDefaultAspect < 0) kfDefaultAspect = 0\n break\n }\n case \"itemweapon\": {\n // skillLibel = item._id \u2014 look up the weapon item to find type + aspect + damage\n const wpItem = actor.items.get(skillLibel)\n if (!wpItem) { ui.notifications.warn(game.i18n.localize(\"CDE.Error0\")); return }\n\n const wpType = wpItem.system.weaponType ?? \"melee\"\n const wpSkill = WEAPON_TYPE_SKILL[wpType] ?? \"kungfu\"\n numberofdice = sys.skills?.[wpSkill]?.value ?? 0\n\n const wpAspectRaw = wpItem.system.damageAspect ?? \"metal\"\n const wpAspectIdx = WEAPON_ASPECT_INDEX[wpAspectRaw] ?? 0\n const wpRange = wpItem.system.range ?? \"contact\"\n\n const WEAPON_TYPE_LABELS = {\n melee: \"CDE.WeaponMelee\",\n thrown: \"CDE.WeaponThrown\",\n ranged: \"CDE.WeaponRanged\",\n firearm: \"CDE.WeaponFirearm\",\n }\n\n // Show weapon-specific prompt\n const wParams = await showWeaponPrompt({\n title: `${wpItem.name} [${game.i18n.localize(sys.skills?.[wpSkill]?.label ?? \"CDE.WeaponRoll\")}]`,\n numberofdice,\n weaponName: wpItem.name,\n weaponTypeLabel: WEAPON_TYPE_LABELS[wpType] ?? \"CDE.Weapon\",\n weaponAspectIcon: ASPECT_ICONS[ASPECT_NAMES[wpAspectIdx]] ?? \"\",\n weaponAspectLabel: game.i18n.localize(ASPECT_LABELS[ASPECT_NAMES[wpAspectIdx]] ?? \"\"),\n damageBase: wpItem.system.damageBase ?? 1,\n weaponskill: wpSkill,\n aspect: wpAspectIdx,\n effectiverange: wpRange,\n bonusmalus: 0,\n woundmalus: 0,\n bonusauspiciousdice: 0,\n typeofthrow: typeOfThrow,\n })\n\n if (!wParams) return // cancelled\n\n // Resolve final pool from weapon prompt values\n const wpChosenSkill = wParams.weaponskill ?? wpSkill\n const wpSkillDice = sys.skills?.[wpChosenSkill]?.value ?? 0\n const wpAspFinal = Number(wParams.aspect ?? wpAspectIdx)\n const wpAspectDice = sys.aspect[ASPECT_NAMES[wpAspFinal]]?.value ?? 0\n const wpRangeMalus = RANGE_MALUS[wParams.effectiverange ?? \"contact\"] ?? 0\n const wpBonusMalus = Number(wParams.bonusmalus ?? 0)\n const wpWoundMalus = Number(wParams.woundmalus ?? 0)\n const wpBonusAusp = Number(wParams.bonusauspiciousdice ?? 0)\n const wpThrowMode = Number(wParams.typeofthrow ?? 0)\n const wpDamageBase = wpItem.system.damageBase ?? 1\n\n const wpTotalDice = wpSkillDice + wpAspectDice + wpRangeMalus + wpBonusMalus - wpWoundMalus\n if (wpTotalDice <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error0\"))\n return\n }\n\n const wpRoll = new Roll(`${wpTotalDice}d10`)\n await wpRoll.evaluate()\n\n const wpAspectName = ASPECT_NAMES[wpAspFinal] ?? \"metal\"\n const wpFaces = countFaces(wpRoll.dice[0]?.results ?? [])\n const wpResults = computeWuXingResults(wpFaces, wpAspectName, wpBonusAusp)\n if (!wpResults) return\n\n const wpModParts = []\n if (wpRangeMalus !== 0) wpModParts.push(`${wpRangeMalus} ${game.i18n.localize(\"CDE.RangePenalty\")}`)\n if (wpBonusMalus !== 0) wpModParts.push(`${wpBonusMalus > 0 ? \"+\" : \"\"}${wpBonusMalus} ${game.i18n.localize(\"CDE.BonusMalus\")}`)\n if (wpWoundMalus !== 0) wpModParts.push(`-${wpWoundMalus} ${game.i18n.localize(\"CDE.WoundMalus\")}`)\n if (wpBonusAusp !== 0) wpModParts.push(`+${wpBonusAusp} ${game.i18n.localize(\"CDE.BonusAuspiciousDice\")}`)\n\n const wpMsg = await sendResultMessage(actor, {\n rollLabel: `${wpItem.name}`,\n aspectName: wpAspectName,\n aspectLabel: game.i18n.localize(ASPECT_LABELS[wpAspectName] ?? \"\"),\n aspectIcon: ASPECT_ICONS[wpAspectName] ?? \"\",\n totalDice: wpTotalDice,\n modifiersText: wpModParts.length ? wpModParts.join(\" \u00B7 \") : \"\",\n spellPower: null,\n rollDifficulty: null,\n actorName: actor.name ?? \"\",\n actorImg: actor.img ?? \"\",\n // weapon-specific\n weaponName: wpItem.name,\n damageBase: wpDamageBase,\n totalDamage: wpResults.successesdice * wpDamageBase,\n ...wpResults,\n aspect: wpAspectName,\n d1: wpFaces[1], d2: wpFaces[2], d3: wpFaces[3], d4: wpFaces[4], d5: wpFaces[5],\n d6: wpFaces[6], d7: wpFaces[7], d8: wpFaces[8], d9: wpFaces[9], d0: wpFaces[0],\n }, wpRoll, ROLL_MODES[wpThrowMode] ?? \"roll\")\n\n if (game.modules.get(\"dice-so-nice\")?.active && wpMsg?.id) {\n await game.dice3d.waitFor3DAnimationByMessageID(wpMsg.id)\n }\n // Auto-update Loksyu/TinJi singletons from weapon roll faces\n if ((wpResults.loksyudice ?? 0) > 0) await updateLoksyuFromRoll(wpAspectName, wpFaces)\n if ((wpResults.tinjidice ?? 0) > 0) await updateTinjiFromRoll(wpResults.tinjidice)\n return\n }\n default:\n ui.notifications.warn(`Unknown roll type: ${typeLibel}`)\n return\n }\n\n // For magic rolls the prompt allows adding HEI dice, so don't block early.\n // For itemkungfu, allow 0 base dice (user can add bonus dice in the prompt).\n if (numberofdice <= 0 && typeLibel !== \"aspect\" && typeLibel !== \"itemkungfu\" && !isMagic) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error0\"))\n return\n }\n\n // ---- Pre-compute default aspect for magic based on skill ----\n const MAGIC_ASPECTS = {\n internalcinnabar: 0, // metal\n alchemy: 1, // water\n masteryoftheway: 2, // earth\n exorcism: 3, // fire\n geomancy: 4, // wood\n }\n\n let defaultAspect = typeLibel === \"aspect\"\n ? [\"metal\",\"water\",\"earth\",\"fire\",\"wood\"].indexOf(skillLibel)\n : 0\n if (isMagic && MAGIC_ASPECTS[skillLibel] !== undefined) {\n defaultAspect = MAGIC_ASPECTS[skillLibel]\n }\n if (kfDefaultAspect >= 0) {\n defaultAspect = kfDefaultAspect\n }\n\n let defaultSpecialAspect = 0\n if (isMagicSpecial && specialLibel) {\n // Look up the speciality's element from the MAGICS config constant\n const specialCfg = MAGICS?.[skillLibel]?.speciality?.[specialLibel]\n const aspectName = LABELELEMENT_TO_ASPECT[specialCfg?.labelelement]\n if (aspectName) {\n defaultSpecialAspect = ASPECT_NAMES.indexOf(aspectName)\n }\n }\n\n // ---- Show roll prompt ----\n let params\n\n if (isMagic) {\n params = await showMagicPrompt({\n title,\n numberofdice,\n aspectskill: defaultAspect,\n bonusmalusskill: 0,\n bonusauspiciousdice: 0,\n aspectspeciality: defaultSpecialAspect,\n rolldifficulty: 1,\n bonusmalusspeciality: 0,\n heispend: 0,\n typeofthrow: typeOfThrow,\n })\n } else {\n params = await showSkillPrompt({\n title,\n numberofdice,\n aspect: defaultAspect,\n bonusmalus: 0,\n woundmalus: 0,\n bonusauspiciousdice: 0,\n typeofthrow: typeOfThrow,\n isSpecial,\n })\n }\n\n if (!params) return // cancelled\n\n // ---- Compute total dice and roll ----\n let aspectIndex, bonusMalus, bonusAuspicious, throwMode\n let spellAspectIndex = null // magic only: aspect of the speciality for Wu Xing\n let rollDifficulty = 1 // magic only: multiplier applied to successes\n\n if (isMagic) {\n const skillAspectIndex = Number(params.aspectskill ?? 0)\n spellAspectIndex = Number(params.aspectspeciality ?? skillAspectIndex)\n aspectIndex = skillAspectIndex // used only for skill dice pool\n bonusMalus = Number(params.bonusmalusskill ?? 0)\n bonusAuspicious = Number(params.bonusauspiciousdice ?? 0)\n rollDifficulty = Math.max(1, Number(params.rolldifficulty ?? 1))\n throwMode = Number(params.typeofthrow ?? 0)\n // magic: magic skill + aspect + bonuses + 1 (speciality base) + HEI spent\n const aspectDice = sys.aspect?.[ASPECT_NAMES[aspectIndex]]?.value ?? 0\n const bonusSpec = Number(params.bonusmalusspeciality ?? 0)\n const heiDice = Number(params.heispend ?? 0)\n numberofdice = numberofdice + aspectDice + bonusMalus + 1 + bonusSpec + heiDice\n } else {\n aspectIndex = Number(params.aspect ?? 0)\n bonusMalus = Number(params.bonusmalus ?? 0)\n const woundMalus = Number(params.woundmalus ?? 0)\n bonusAuspicious = Number(params.bonusauspiciousdice ?? 0)\n throwMode = Number(params.typeofthrow ?? 0)\n\n const aspectDice = (typeLibel !== \"aspect\")\n ? (sys.aspect?.[ASPECT_NAMES[aspectIndex]]?.value ?? 0)\n : 0\n\n numberofdice = numberofdice + aspectDice + bonusMalus - woundMalus\n if (isSpecial) numberofdice += 1 // +1d for speciality\n }\n\n if (numberofdice <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.Error0\"))\n return\n }\n\n // ---- Roll ----\n const roll = new Roll(`${numberofdice}d10`)\n await roll.evaluate()\n\n const rollModeKey = ROLL_MODES[throwMode] ?? \"roll\"\n\n // ---- Compute Wu Xing results ----\n // For magic rolls, the spell's aspect (aspectspeciality) governs the Wu Xing\n // cycle (which faces count as successes/auspicious/etc.), not the skill aspect.\n const wuXingAspectName = spellAspectIndex !== null\n ? ASPECT_NAMES[spellAspectIndex]\n : ASPECT_NAMES[aspectIndex]\n const allResults = roll.dice[0]?.results ?? []\n const faces = countFaces(allResults)\n const results = computeWuXingResults(faces, wuXingAspectName, bonusAuspicious)\n if (!results) return\n\n // For magic, successesdice \u00D7 rollDifficulty = spell power\n const spellPower = isMagic ? results.successesdice * rollDifficulty : null\n\n // ---- Build modifier summary text ----\n const modParts = []\n if (isMagic) {\n const bm = Number(params.bonusmalusskill ?? 0)\n const bs = Number(params.bonusmalusspeciality ?? 0)\n const hs = Number(params.heispend ?? 0)\n const ba = Number(params.bonusauspiciousdice ?? 0)\n if (bm !== 0) modParts.push(`${bm > 0 ? \"+\" : \"\"}${bm} ${game.i18n.localize(\"CDE.BonusMalus\")}`)\n if (bs !== 0) modParts.push(`${bs > 0 ? \"+\" : \"\"}${bs} ${game.i18n.localize(\"CDE.SpellBonus\")}`)\n if (ba !== 0) modParts.push(`+${ba} ${game.i18n.localize(\"CDE.BonusAuspiciousDice\")}`)\n if (hs !== 0) modParts.push(`${hs} ${game.i18n.localize(\"CDE.HeiSpend\")}`)\n if (rollDifficulty !== 1) modParts.push(`\u00D7${rollDifficulty} ${game.i18n.localize(\"CDE.RollDifficulty\")}`)\n } else {\n const bm = Number(params.bonusmalus ?? 0)\n const wm = Number(params.woundmalus ?? 0)\n const ba = Number(params.bonusauspiciousdice ?? 0)\n if (bm !== 0) modParts.push(`${bm > 0 ? \"+\" : \"\"}${bm} ${game.i18n.localize(\"CDE.BonusMalus\")}`)\n if (wm !== 0) modParts.push(`-${wm} ${game.i18n.localize(\"CDE.WoundMalus\")}`)\n if (ba !== 0) modParts.push(`+${ba} ${game.i18n.localize(\"CDE.BonusAuspiciousDice\")}`)\n }\n\n // ---- Send single enriched ChatMessage (roll + result card) ----\n const msg = await sendResultMessage(actor, {\n // Roll identity\n rollLabel: title,\n aspectName: wuXingAspectName,\n aspectLabel: game.i18n.localize(ASPECT_LABELS[wuXingAspectName] ?? \"\"),\n aspectIcon: ASPECT_ICONS[wuXingAspectName] ?? \"\",\n totalDice: numberofdice,\n modifiersText: modParts.length ? modParts.join(\" \u00B7 \") : \"\",\n // Spell power (magic only)\n spellPower,\n rollDifficulty: isMagic ? rollDifficulty : null,\n // Actor info\n actorName: actor.name ?? \"\",\n actorImg: actor.img ?? \"\",\n // Wu Xing results\n aspect: wuXingAspectName,\n ...results,\n // Die face counts\n d1: faces[1], d2: faces[2], d3: faces[3], d4: faces[4], d5: faces[5],\n d6: faces[6], d7: faces[7], d8: faces[8], d9: faces[9], d0: faces[0],\n }, roll, rollModeKey)\n\n // ---- Wait for Dice So Nice animation ----\n if (game.modules.get(\"dice-so-nice\")?.active && msg?.id) {\n await game.dice3d.waitFor3DAnimationByMessageID(msg.id)\n }\n\n // ---- Auto-update Loksyu / TinJi singletons ----\n if ((results.loksyudice ?? 0) > 0) await updateLoksyuFromRoll(wuXingAspectName, faces)\n if ((results.tinjidice ?? 0) > 0) await updateTinjiFromRoll(results.tinjidice)\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nconst { HandlebarsApplicationMixin } = foundry.applications.api\n\nexport class CDEBaseActorSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ActorSheetV2) {\n static DEFAULT_OPTIONS = {\n classes: [\"fvtt-chroniques-de-l-etrange\", \"actor\"],\n position: { width: 920, height: 800 },\n window: { resizable: true },\n form: { submitOnChange: true },\n dragDrop: [{ dragSelector: \".item, [data-drag='true']\", dropSelector: null }],\n actions: {\n create: CDEBaseActorSheet.#onItemCreate,\n edit: CDEBaseActorSheet.#onItemEdit,\n delete: CDEBaseActorSheet.#onItemDelete,\n editImage: CDEBaseActorSheet.#onEditImage,\n },\n }\n\n tabGroups = { primary: \"description\" }\n\n get title() {\n return this.document.name\n }\n\n async _prepareContext() {\n const descriptionHTML = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description ?? \"\", { async: true })\n const cssClass = this.options.classes?.join(\" \") ?? \"\"\n return {\n actor: this.document,\n system: this.document.system,\n systemData: this.document.system,\n systemFields: this.document.system.schema.fields,\n items: this.document.items.contents,\n descriptionHTML,\n editable: this.isEditable,\n cssClass,\n }\n }\n\n // Restore the active tab after every render (including re-renders from submitOnChange).\n // AppV2 does NOT preserve tab state natively \u2014 we must re-apply it from this.tabGroups,\n // which is dynamically updated by changeTab() when the user clicks a tab.\n _onRender(context, options) {\n super._onRender?.(context, options)\n for (const [group, tab] of Object.entries(this.tabGroups)) {\n this.changeTab(tab, group, { force: true })\n }\n }\n\n static async #onItemCreate(event, target) {\n const type = target.dataset.type ?? \"item\"\n const cls = getDocumentClass(\"Item\")\n const labels = {\n item: \"CDE.ItemNew\",\n weapon: \"CDE.WeaponNew\",\n armor: \"CDE.ArmorNew\",\n sanhei: \"CDE.SanheiNew\",\n ingredient: \"CDE.IngredientNew\",\n kungfu: \"CDE.KFNew\",\n spell: \"CDE.SpellNew\",\n supernatural: \"CDE.SupernaturalNew\",\n }\n const name = game.i18n.localize(labels[type] ?? \"CDE.ItemNew\")\n const systemData = {}\n if (type === \"spell\" && target.dataset.discipline) {\n systemData.discipline = target.dataset.discipline\n }\n return cls.create({ name, type, system: systemData }, { parent: this.document })\n }\n\n static #onItemEdit(event, target) {\n const itemId = target.dataset.itemId ?? target.closest(\"[data-item-id]\")?.dataset.itemId\n const item = this.document.items.get(itemId)\n if (item) item.sheet.render(true)\n }\n\n static #onItemDelete(event, target) {\n const itemId = target.dataset.itemId ?? target.closest(\"[data-item-id]\")?.dataset.itemId\n const item = this.document.items.get(itemId)\n if (item) item.delete()\n }\n\n static async #onEditImage(event, target) {\n const attr = target.dataset.edit\n const current = foundry.utils.getProperty(this.document, attr)\n const { img } = this.document.constructor.getDefaultArtwork?.(this.document.toObject()) ?? {}\n const fp = new FilePicker({\n current,\n type: \"image\",\n redirectToRoot: img ? [img] : [],\n callback: (path) => this.document.update({ [attr]: path }),\n top: this.position.top + 40,\n left: this.position.left + 10,\n })\n return fp.browse()\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { MAGICS, SUBTYPES } from \"../../../config/constants.js\"\nimport { rollInitiativePC } from \"../../initiative.js\"\nimport { rollForActor } from \"../../rolling.js\"\nimport { CDEBaseActorSheet } from \"./base.js\"\n\nexport class CDECharacterSheet extends CDEBaseActorSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"character\"],\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/actor/cde-character-sheet.html\" },\n }\n\n tabGroups = { primary: \"description\" }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n context.equipments = context.items.filter((item) => item.type === \"item\")\n context.weapons = context.items.filter((item) => item.type === \"weapon\")\n context.armors = context.items.filter((item) => item.type === \"armor\")\n context.sanheis = context.items.filter((item) => item.type === \"sanhei\")\n context.ingredients = context.items.filter((item) => item.type === \"ingredient\")\n context.spells = context.items.filter((item) => item.type === \"spell\")\n context.kungfus = context.items.filter((item) => item.type === \"kungfu\")\n context.CDE = { MAGICS, SUBTYPES }\n\n // Group spells by discipline key (matches MAGICS keys)\n const spellsByDiscipline = {}\n for (const spell of context.spells) {\n const disc = spell.system?.discipline ?? \"internalcinnabar\"\n if (!spellsByDiscipline[disc]) spellsByDiscipline[disc] = []\n spellsByDiscipline[disc].push(spell)\n }\n\n // Build magicsDisplay: only include the 5 relevant specialities per magic type + grimoire\n const systemMagics = context.systemData.magics ?? {}\n context.magicsDisplay = Object.fromEntries(\n Object.entries(MAGICS).map(([magicKey, magicDef]) => {\n const magicData = systemMagics[magicKey] ?? {}\n return [\n magicKey,\n {\n value: magicData.value ?? 0,\n visible: magicData.visible ?? false,\n speciality: Object.fromEntries(\n Object.keys(magicDef.speciality).map((specKey) => [\n specKey,\n { check: magicData.speciality?.[specKey]?.check ?? false },\n ])\n ),\n grimoire: spellsByDiscipline[magicKey] ?? [],\n },\n ]\n })\n )\n\n return context\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindInitiativeControls()\n this.#bindPrefs()\n this.#bindRollButtons()\n this.#bindComponentRandomize()\n this.#bindDiagramZoom()\n }\n\n #bindInitiativeControls() {\n const buttons = this.element?.querySelectorAll(\".click-initiative\")\n if (!buttons?.length) return\n buttons.forEach((button) => {\n button.addEventListener(\"click\", async () => {\n const action = button.dataset.libelId\n let initiative = this.document.system.initiative ?? 1\n if (action === \"plus\") {\n initiative = initiative >= 24 ? 1 : initiative + 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"minus\") {\n initiative = initiative <= 1 ? 24 : initiative - 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"create\") {\n await rollInitiativePC(this.document)\n }\n })\n })\n }\n\n #bindPrefs() {\n const button = this.element?.querySelector(\".click-prefs\")\n if (!button) return\n button.addEventListener(\"click\", async () => {\n const current = this.document.system.prefs?.typeofthrow ?? { choice: \"0\", check: true }\n const html = `\n
\n
\n \n \n
\n
\n \n \n
\n
`\n const prefs = await foundry.applications.api.DialogV2.prompt({\n window: { title: game.i18n.localize(\"CDE.Preferences\") },\n content: html,\n rejectClose: false,\n ok: {\n label: game.i18n.localize(\"CDE.Validate\"),\n callback: (_ev, _btn, dialog) => {\n const root = dialog.element ?? dialog\n const choice = root.querySelector(\"select[name='choice']\")?.value ?? \"0\"\n const check = root.querySelector(\"input[name='check']\")?.checked ?? false\n return { choice, check }\n },\n },\n })\n if (prefs) {\n await this.document.update({\n \"system.prefs.typeofthrow.choice\": String(prefs.choice),\n \"system.prefs.typeofthrow.check\": !!prefs.check,\n })\n }\n })\n }\n\n #bindRollButtons() {\n const cells = this.element?.querySelectorAll(\"td.click[data-libel-id], td.click2[data-libel-id], .cde-roll-trigger[data-libel-id]\")\n if (!cells?.length) return\n cells.forEach((cell) => {\n cell.addEventListener(\"click\", (event) => {\n event.preventDefault()\n const rollKey = cell.dataset.libelId\n if (rollKey) rollForActor(this.document, rollKey)\n })\n })\n }\n\n #bindDiagramZoom() {\n const img = this.element?.querySelector(\"[data-action='zoom-diagram']\")\n if (!img) return\n img.addEventListener(\"click\", () => {\n new ImagePopout(img.src, {\n title: game.i18n.localize(\"CDE.NghangDiagramTitle\"),\n shareable: false,\n }).render(true)\n })\n }\n\n #bindComponentRandomize() {\n const btn = this.element?.querySelector(\"[data-action='randomize-component']\")\n if (!btn) return\n btn.addEventListener(\"click\", async () => {\n const roll = new Roll(\"1d10\")\n await roll.evaluate()\n const face = roll.total === 10 ? 0 : roll.total\n const COMPONENT_KEYS = { 1:\"one\", 2:\"two\", 3:\"three\", 4:\"four\", 5:\"five\",\n 6:\"six\", 7:\"seven\", 8:\"eight\", 9:\"nine\", 0:\"zero\" }\n const componentKey = COMPONENT_KEYS[face]\n const componentValue = this.document.system.component?.[componentKey]?.value ?? \"\"\n const label = componentValue\n ? `${componentValue}`\n : `${game.i18n.localize(\"CDE.Component\")}${face}`\n const content = `\n
\n ${game.i18n.localize(\"CDE.ChanceThrowResult\")}\n ${label}\n
`\n await ChatMessage.create({\n user: game.user.id,\n speaker: ChatMessage.getSpeaker({ actor: this.document }),\n content,\n rolls: [roll],\n rollMode: game.settings.get(\"core\", \"rollMode\") ?? \"roll\",\n })\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { rollInitiativeNPC } from \"../../initiative.js\"\nimport { rollForActor } from \"../../rolling.js\"\nimport { CDEBaseActorSheet } from \"./base.js\"\n\nexport class CDENpcSheet extends CDEBaseActorSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"npc\"],\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/actor/cde-npc-sheet.html\" },\n }\n\n tabGroups = { primary: \"description\" }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n context.supernaturals = context.items.filter((item) => item.type === \"supernatural\")\n context.spells = context.items.filter((item) => item.type === \"spell\")\n context.kungfus = context.items.filter((item) => item.type === \"kungfu\")\n context.weapons = context.items.filter((item) => item.type === \"weapon\")\n context.armors = context.items.filter((item) => item.type === \"armor\")\n context.equipments = context.items.filter((item) => item.type === \"item\")\n return context\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindInitiativeControls()\n this.#bindRollButtons()\n }\n\n #bindRollButtons() {\n const cells = this.element?.querySelectorAll(\".cde-roll-trigger[data-libel-id]\")\n if (!cells?.length) return\n cells.forEach((cell) => {\n cell.addEventListener(\"click\", (event) => {\n event.preventDefault()\n const rollKey = cell.dataset.libelId\n if (rollKey) rollForActor(this.document, rollKey)\n })\n })\n }\n\n #bindInitiativeControls() {\n const buttons = this.element?.querySelectorAll(\".click-initiative-npc\")\n if (!buttons?.length) return\n buttons.forEach((button) => {\n button.addEventListener(\"click\", async () => {\n const action = button.dataset.libelId\n let initiative = this.document.system.initiative ?? 1\n if (action === \"plus\") {\n initiative = initiative >= 24 ? 1 : initiative + 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"minus\") {\n initiative = initiative <= 1 ? 24 : initiative - 1\n await this.document.update({ \"system.initiative\": initiative })\n return\n }\n if (action === \"create\") {\n await rollInitiativeNPC(this.document)\n }\n })\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nconst { HandlebarsApplicationMixin } = foundry.applications.api\n\nexport class CDEBaseItemSheet extends HandlebarsApplicationMixin(foundry.applications.sheets.ItemSheetV2) {\n static DEFAULT_OPTIONS = {\n classes: [\"fvtt-chroniques-de-l-etrange\", \"item\"],\n position: { width: 520, height: \"auto\" },\n window: { resizable: true },\n form: { submitOnChange: true },\n actions: {\n editImage: CDEBaseItemSheet.#onEditImage,\n },\n }\n\n tabGroups = { primary: \"details\" }\n\n get title() {\n return this.document.name\n }\n\n async _prepareContext() {\n const cssClass = this.options.classes?.join(\" \") ?? \"\"\n const enrichedDescription = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.description ?? \"\", { async: true })\n const enrichedNotes = await foundry.applications.ux.TextEditor.implementation.enrichHTML(this.document.system.notes ?? \"\", { async: true })\n return {\n item: this.document,\n system: this.document.system,\n systemData: this.document.system,\n systemFields: this.document.system.schema.fields,\n editable: this.isEditable,\n cssClass,\n enrichedDescription,\n enrichedNotes,\n descriptionHTML: enrichedDescription,\n notesHTML: enrichedNotes,\n }\n }\n\n // Restore the active tab after every render (including re-renders from submitOnChange).\n _onRender(context, options) {\n super._onRender?.(context, options)\n for (const [group, tab] of Object.entries(this.tabGroups)) {\n this.changeTab(tab, group, { force: true })\n }\n }\n\n static async #onEditImage(event, target) {\n const attr = target.dataset.edit\n const current = foundry.utils.getProperty(this.document, attr)\n const { img } = this.document.constructor.getDefaultArtwork?.(this.document.toObject()) ?? {}\n const fp = new FilePicker({\n current,\n type: \"image\",\n redirectToRoot: img ? [img] : [],\n callback: (path) => this.document.update({ [attr]: path }),\n top: this.position.top + 40,\n left: this.position.left + 10,\n })\n return fp.browse()\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEItemSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"equipment\"],\n position: { width: 560, height: 460 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-item-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEKungfuSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"kungfu\"],\n position: { width: 720, height: 680 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-kungfu-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const techniques = this.document.system.techniques ?? {}\n const enrich = (value) => foundry.applications.ux.TextEditor.implementation.enrichHTML(value ?? \"\", { async: true })\n context.descriptionTechnique1HTML = await enrich(techniques.technique1?.technique)\n context.descriptionTechnique2HTML = await enrich(techniques.technique2?.technique)\n context.descriptionTechnique3HTML = await enrich(techniques.technique3?.technique)\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDESpellSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"spell\"],\n position: { width: 660, height: 680 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-spell-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? \"\", { async: true })\n context.spellDescriptionHTML = await enrich(this.document.system.description)\n context.componentsDescriptionHTML = await enrich(this.document.system.components)\n context.effectsDescriptionHTML = await enrich(this.document.system.effects)\n context.examplesDescriptionHTML = await enrich(this.document.system.examples)\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDESupernaturalSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"supernatural\"],\n position: { width: 560, height: 520 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-supernatural-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? \"\", { async: true })\n context.effectsHTML = await enrich(this.document.system.effects)\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEWeaponSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"weapon\"],\n position: { width: 580, height: 520 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-weapon-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEArmorSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"armor\"],\n position: { width: 520, height: 460 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-armor-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDESanheiSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"sanhei\"],\n position: { width: 580, height: 620 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-sanhei-sheet.html\" },\n }\n\n async _prepareContext() {\n const context = await super._prepareContext()\n const enrich = (content) => foundry.applications.ux.TextEditor.implementation.enrichHTML(content ?? \"\", { async: true })\n const props = this.document.system.properties\n context.prop1DescriptionHTML = await enrich(props.prop1.description)\n context.prop2DescriptionHTML = await enrich(props.prop2.description)\n context.prop3DescriptionHTML = await enrich(props.prop3.description)\n context.propFields = this.document.system.schema.fields.properties.fields\n return context\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { CDEBaseItemSheet } from \"./base.js\"\n\nexport class CDEIngredientSheet extends CDEBaseItemSheet {\n static DEFAULT_OPTIONS = {\n classes: [\"ingredient\"],\n position: { width: 520, height: 460 },\n }\n\n static PARTS = {\n main: { template: \"systems/fvtt-chroniques-de-l-etrange/templates/item/cde-ingredient-sheet.html\" },\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { getLoksyuData, setLoksyuData } from \"./singletons.js\"\nimport { SYSTEM_ID } from \"../../config/constants.js\"\n\nexport class CDELoksyuApp extends foundry.applications.api.HandlebarsApplicationMixin(\n foundry.applications.api.ApplicationV2\n) {\n static DEFAULT_OPTIONS = {\n id: \"cde-loksyu-app\",\n tag: \"div\",\n window: {\n title: \"CDE.Loksyu\",\n icon: \"fas fa-yin-yang\",\n resizable: false,\n },\n classes: [\"cde-app\", \"cde-loksyu-standalone\"],\n position: { width: 520, height: \"auto\" },\n actions: {\n resetElement: CDELoksyuApp.#onResetElement,\n resetAll: CDELoksyuApp.#onResetAll,\n zoomVisual: CDELoksyuApp.#onZoomVisual,\n },\n }\n\n static PARTS = {\n main: {\n template: `systems/${SYSTEM_ID}/templates/apps/cde-loksyu-app.html`,\n },\n }\n\n /** @type {Function|null} bound hook handler */\n _updateHook = null\n\n /** Singleton accessor \u2014 open or bring to front */\n static open() {\n const existing = Array.from(foundry.applications.instances.values()).find(\n (app) => app instanceof CDELoksyuApp\n )\n if (existing) { existing.bringToFront(); return existing }\n const app = new CDELoksyuApp()\n app.render(true)\n return app\n }\n\n async _prepareContext() {\n const sys = getLoksyuData()\n const ELEMENTS = [\n { key: \"wood\", nameKey: \"CDE.Wood\", qualKey: \"CDE.WoodQualities\", img: `systems/${SYSTEM_ID}/images/cde_bois.webp` },\n { key: \"fire\", nameKey: \"CDE.Fire\", qualKey: \"CDE.FireQualities\", img: `systems/${SYSTEM_ID}/images/cde_feu.webp` },\n { key: \"earth\", nameKey: \"CDE.Earth\", qualKey: \"CDE.EarthQualities\", img: `systems/${SYSTEM_ID}/images/cde_terre.webp` },\n { key: \"metal\", nameKey: \"CDE.Metal\", qualKey: \"CDE.MetalQualities\", img: `systems/${SYSTEM_ID}/images/cde_metal.webp` },\n { key: \"water\", nameKey: \"CDE.Water\", qualKey: \"CDE.WaterQualities\", img: `systems/${SYSTEM_ID}/images/cde_eau.webp` },\n ]\n\n return {\n canEdit: game.user.isGM,\n elements: ELEMENTS.map((el) => ({\n ...el,\n yang: sys[el.key]?.yang ?? 0,\n yin: sys[el.key]?.yin ?? 0,\n })),\n }\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindInputs()\n\n this._updateHook = Hooks.on(\"cde:loksyuUpdated\", () => this.render())\n }\n\n _onClose(options) {\n if (this._updateHook !== null) {\n Hooks.off(\"cde:loksyuUpdated\", this._updateHook)\n this._updateHook = null\n }\n super._onClose(options)\n }\n\n #bindInputs() {\n const inputs = this.element?.querySelectorAll(\"input[data-field]\")\n if (!inputs?.length) return\n inputs.forEach((input) => {\n input.addEventListener(\"change\", async (ev) => {\n const field = ev.currentTarget.dataset.field\n const val = parseInt(ev.currentTarget.value, 10)\n if (!field || isNaN(val)) return\n // field is like \"wood.yin\" or \"fire.yang\"\n const [aspect, dim] = field.split(\".\")\n if (!aspect || !dim) return\n const data = getLoksyuData()\n if (!data[aspect]) data[aspect] = { yin: 0, yang: 0 }\n data[aspect][dim] = Math.max(0, val)\n await setLoksyuData(data)\n })\n })\n }\n\n static async #onResetElement(event, target) {\n const key = target.dataset.element\n if (!key) return\n const data = getLoksyuData()\n data[key] = { yin: 0, yang: 0 }\n await setLoksyuData(data)\n }\n\n static async #onResetAll(_event, _target) {\n const KEYS = [\"wood\", \"fire\", \"earth\", \"metal\", \"water\"]\n const data = getLoksyuData()\n for (const k of KEYS) data[k] = { yin: 0, yang: 0 }\n await setLoksyuData(data)\n }\n\n static #onZoomVisual(_event, target) {\n new ImagePopout(target.src, {\n title: game.i18n.localize(\"CDE.LoksyuDiagramTitle\"),\n shareable: false,\n }).render(true)\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { getTinjiValue, setTinjiValue } from \"./singletons.js\"\nimport { SYSTEM_ID } from \"../../config/constants.js\"\n\nexport class CDETinjiApp extends foundry.applications.api.HandlebarsApplicationMixin(\n foundry.applications.api.ApplicationV2\n) {\n static DEFAULT_OPTIONS = {\n id: \"cde-tinji-app\",\n tag: \"div\",\n window: {\n title: \"CDE.TinJi2\",\n icon: \"fas fa-star\",\n resizable: false,\n },\n classes: [\"cde-app\", \"cde-tinji-standalone\"],\n position: { width: 380, height: \"auto\" },\n actions: {\n increment: CDETinjiApp.#onIncrement,\n decrement: CDETinjiApp.#onDecrement,\n reset: CDETinjiApp.#onReset,\n spend: CDETinjiApp.#onSpend,\n },\n }\n\n static PARTS = {\n main: {\n template: `systems/${SYSTEM_ID}/templates/apps/cde-tinji-app.html`,\n },\n }\n\n /** @type {Function|null} */\n _updateHook = null\n\n static open() {\n const existing = Array.from(foundry.applications.instances.values()).find(\n (app) => app instanceof CDETinjiApp\n )\n if (existing) { existing.bringToFront(); return existing }\n const app = new CDETinjiApp()\n app.render(true)\n return app\n }\n\n async _prepareContext() {\n return {\n canEdit: game.user.isGM,\n value: getTinjiValue(),\n }\n }\n\n _onRender(context, options) {\n super._onRender(context, options)\n this.#bindDirectInput()\n this._updateHook = Hooks.on(\"cde:tinjiUpdated\", () => this.render())\n }\n\n _onClose(options) {\n if (this._updateHook !== null) {\n Hooks.off(\"cde:tinjiUpdated\", this._updateHook)\n this._updateHook = null\n }\n super._onClose(options)\n }\n\n #bindDirectInput() {\n const input = this.element?.querySelector(\"input.cde-tinji-direct\")\n if (!input) return\n input.addEventListener(\"change\", async (ev) => {\n const val = parseInt(ev.currentTarget.value, 10)\n if (!isNaN(val)) await setTinjiValue(val)\n })\n }\n\n static async #onIncrement() {\n await setTinjiValue(getTinjiValue() + 1)\n }\n\n static async #onDecrement() {\n const current = getTinjiValue()\n if (current <= 0) return\n await setTinjiValue(current - 1)\n }\n\n static async #onReset() {\n await setTinjiValue(0)\n }\n\n static async #onSpend() {\n const current = getTinjiValue()\n if (current <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.TinjiEmpty\"))\n return\n }\n await setTinjiValue(current - 1)\n ChatMessage.create({\n user: game.user.id,\n content: `
\n \n ${game.i18n.localize(\"CDE.TinJi2\")}\n ${game.i18n.format(\"CDE.TinjiSpent\", { name: game.user.name })}\n (${current - 1} ${game.i18n.localize(\"CDE.TinjiRemaining\")})\n
`,\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { rollInitiativePC, rollInitiativeNPC } from \"../ui/initiative.js\"\nimport { ACTOR_TYPES } from \"../config/constants.js\"\n\n/**\n * Custom Combat document for Chroniques de l'\u00C9trange.\n *\n * The initiative wheel has 24 crans (positions). The character with the\n * highest initiative acts first (furthest counter-clockwise from reference).\n * After each action, their position advances clockwise by the action's cran cost\n * (initiative decreases, wrapping from 1 \u2192 24).\n *\n * Sort order: descending by initiative (highest acts first).\n */\nexport class CDECombat extends Combat {\n\n /**\n * Override rollInitiative to open the PC or NPC initiative dialog\n * for each selected combatant, then sync the result to the Combatant document.\n */\n async rollInitiative(ids, options = {}) {\n const combatantIds = typeof ids === \"string\" ? [ids] : ids\n for (const id of combatantIds) {\n const combatant = this.combatants.get(id)\n if (!combatant) continue\n const actor = combatant.actor\n if (!actor) continue\n\n if (actor.type === ACTOR_TYPES.character) {\n await rollInitiativePC(actor)\n } else {\n await rollInitiativeNPC(actor)\n }\n // combatant.initiative is synced by the updateActor hook in system.js\n // (triggered by actor.update inside rollInitiativePC/NPC)\n }\n return this\n }\n\n /**\n * Sort combatants: highest initiative first (furthest counter-clockwise = acts first).\n * Ties: PCs before NPCs; among PCs, by name; among NPCs, by name.\n * Calls super.setupTurns() first to ensure this.current is properly initialized.\n */\n setupTurns() {\n super.setupTurns()\n this.turns = this.turns.slice().sort((a, b) => {\n const ia = a.initiative ?? 0\n const ib = b.initiative ?? 0\n if (ia !== ib) return ib - ia // descending \u2014 highest acts first\n\n // Tie-break: PCs before NPCs\n const aIsPC = a.actor?.type === ACTOR_TYPES.character ? 1 : 0\n const bIsPC = b.actor?.type === ACTOR_TYPES.character ? 1 : 0\n if (aIsPC !== bIsPC) return bIsPC - aIsPC\n\n return (a.name ?? \"\").localeCompare(b.name ?? \"\")\n })\n return this.turns\n }\n}\n\n/**\n * Advance a combatant's wheel position by the given action cran cost.\n * Position wraps: after reaching 1, it continues from 24.\n *\n * @param {Combatant} combatant\n * @param {number} cranCost\n */\nexport async function advanceCombatantPosition(combatant, cranCost) {\n const current = combatant.initiative ?? combatant.actor?.system?.initiative ?? 1\n const newValue = ((current - cranCost - 1 + 48) % 24) + 1\n // Update combatant only; the updateCombatant hook in system.js syncs actor.initiative.\n await combatant.update({ initiative: newValue })\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { advanceCombatantPosition } from \"../../documents/combat.js\"\n\nconst WHEEL_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-wheel-app.html\"\n\n/**\n * Action costs for common combat actions (in crans).\n * Listed in order from cheapest to most expensive.\n */\nexport const ACTION_COSTS = [\n { key: \"draw\", label: \"CDE.ActionCostDraw\", cost: 1 },\n { key: \"changestyle\", label: \"CDE.ActionCostChangeStyle\", cost: 1 },\n { key: \"defense\", label: \"CDE.ActionCostDefense\", cost: 1 },\n { key: \"aim\", label: \"CDE.ActionCostAim\", cost: 2 },\n { key: \"help\", label: \"CDE.ActionCostHelp\", cost: 2 },\n { key: \"defally\", label: \"CDE.ActionCostDefendAlly\", cost: 2 },\n { key: \"move\", label: \"CDE.ActionCostMove\", cost: 2 },\n { key: \"attack\", label: \"CDE.ActionCostAttack\", cost: 3 },\n { key: \"delay\", label: \"CDE.ActionCostDelay\", cost: 6 },\n]\n\n/**\n * Wu Xing color segments for the 24-cran wheel.\n * 6 colors \u00D7 4 crans = 24. Each colour covers crans [start..start+3].\n * An effect lasting 6 crans returns to the same colour.\n */\nconst WHEEL_SEGMENTS = [\n { label: \"M\u00E9tal\", color: \"#b8c4cc\", textColor: \"#1a1a1a\", crans: [1, 2, 3, 4] },\n { label: \"Eau\", color: \"#3a7bd5\", textColor: \"#ffffff\", crans: [5, 6, 7, 8] },\n { label: \"Terre\", color: \"#c8a84b\", textColor: \"#1a1a1a\", crans: [9, 10, 11, 12] },\n { label: \"Feu\", color: \"#d94f3d\", textColor: \"#ffffff\", crans: [13, 14, 15, 16] },\n { label: \"Bois\", color: \"#4a9b5a\", textColor: \"#ffffff\", crans: [17, 18, 19, 20] },\n { label: \"Rep\u00E8re\", color: \"#1a1a2e\", textColor: \"#aaaaaa\", crans: [21, 22, 23, 24] },\n]\n\n/** Return the segment data for a given cran (1\u201324). */\nfunction segmentForCran(cran) {\n return WHEEL_SEGMENTS.find(s => s.crans.includes(cran)) ?? WHEEL_SEGMENTS[0]\n}\n\n/**\n * Roue d'Initiative \u2014 visual initiative wheel for CDE combat.\n *\n * Shows all combatants in the current combat scene on a 24-cran wheel.\n * Provides action-cost buttons to advance a combatant's position.\n *\n * Singleton: open via CDEWheelApp.open().\n */\nexport class CDEWheelApp extends foundry.applications.api.ApplicationV2 {\n static DEFAULT_OPTIONS = {\n id: \"cde-wheel-app\",\n classes: [\"cde-wheel-app\"],\n tag: \"div\",\n window: {\n title: \"CDE.InitiativeWheel\",\n icon: \"fas fa-circle-notch\",\n resizable: true,\n },\n position: { width: 820, height: 620 },\n actions: {\n advanceCran: CDEWheelApp.#advanceCran,\n setSurprised: CDEWheelApp.#setSurprised,\n rollInitiative: CDEWheelApp.#rollInitiative,\n },\n }\n\n /** @type {CDEWheelApp|null} */\n static #instance = null\n\n /** Open (or bring to front) the singleton instance. */\n static open() {\n if (!CDEWheelApp.#instance || CDEWheelApp.#instance.rendered === false) {\n CDEWheelApp.#instance = new CDEWheelApp()\n CDEWheelApp.#instance.render(true)\n } else {\n CDEWheelApp.#instance.bringToFront()\n }\n return CDEWheelApp.#instance\n }\n\n /** Currently selected combatant id (for action panel). */\n #selectedId = null\n\n async _prepareContext(options) {\n const combat = game.combat\n const combatants = combat ? [...combat.combatants.values()] : []\n const sorted = [...combatants].sort((a, b) => (b.initiative ?? 0) - (a.initiative ?? 0))\n const cranData = this.#buildCranData(combatants)\n const selected = this.#selectedId\n ? combatants.find(c => c.id === this.#selectedId)\n : null\n const actionCosts = ACTION_COSTS.map(a => ({\n ...a,\n label: game.i18n.localize(a.label),\n }))\n\n return {\n hasCombat: !!combat,\n combatants: sorted.map(c => ({\n id: c.id,\n name: c.name,\n img: c.token?.texture?.src ?? c.actor?.img ?? \"icons/svg/mystery-man.svg\",\n initiative: c.initiative ?? \"\u2014\",\n segment: segmentForCran(c.initiative ?? 1),\n isActive: combat?.current?.combatantId === c.id,\n isSelected: c.id === this.#selectedId,\n hasInitiative: c.initiative != null,\n })),\n cranData,\n selected,\n selectedName: selected?.name ?? null,\n actionCosts,\n }\n }\n\n async _renderHTML(context, options) {\n return foundry.applications.handlebars.renderTemplate(WHEEL_TEMPLATE, context)\n }\n\n _replaceHTML(result, content, options) {\n content.innerHTML = result\n this.#bindEvents(content)\n }\n\n /** Build per-cran data for the SVG wheel. */\n #buildCranData(combatants) {\n const data = []\n for (let cran = 1; cran <= 24; cran++) {\n const segment = segmentForCran(cran)\n const fighters = combatants.filter(c => Math.round(c.initiative) === cran)\n data.push({ cran, segment, fighters })\n }\n return data\n }\n\n /** Bind click events for combatant selection. */\n #bindEvents(content) {\n content.querySelectorAll(\"[data-select-combatant]\").forEach(el => {\n el.addEventListener(\"click\", () => {\n this.#selectedId = el.dataset.selectCombatant\n this.render()\n })\n })\n }\n\n /** Action: advance selected combatant by given cran cost. */\n static async #advanceCran(event, element) {\n const app = CDEWheelApp.#instance\n if (!app?.#selectedId) return\n const cost = parseInt(element.dataset.cost, 10)\n if (!cost || isNaN(cost)) return\n const combatant = game.combat?.combatants.get(app.#selectedId)\n if (!combatant) return\n await advanceCombatantPosition(combatant, cost)\n }\n\n /** Action: set selected combatant to surprised (position 1 = reference). */\n static async #setSurprised(event, element) {\n const app = CDEWheelApp.#instance\n if (!app?.#selectedId) return\n const combatant = game.combat?.combatants.get(app.#selectedId)\n if (!combatant) return\n // Update combatant only \u2014 updateCombatant hook in system.js syncs actor\n await combatant.update({ initiative: 1 })\n }\n\n /** Action: open the initiative dialog for the selected combatant. */\n static async #rollInitiative(event, element) {\n const app = CDEWheelApp.#instance\n if (!app?.#selectedId) return\n const combatant = game.combat?.combatants.get(app.#selectedId)\n if (!combatant) return\n await game.combat.rollInitiative([app.#selectedId])\n }\n\n /** Re-render when combat state changes. */\n static registerHooks() {\n const refresh = () => {\n if (CDEWheelApp.#instance?.rendered) CDEWheelApp.#instance.render()\n }\n Hooks.on(\"updateCombat\", refresh)\n Hooks.on(\"updateCombatant\", refresh)\n Hooks.on(\"createCombatant\", refresh)\n Hooks.on(\"deleteCombatant\", refresh)\n Hooks.on(\"updateActor\", (_actor, diff) => {\n if (foundry.utils.hasProperty(diff, \"system.initiative\")) refresh()\n })\n Hooks.on(\"deleteCombat\", () => {\n if (CDEWheelApp.#instance?.rendered) CDEWheelApp.#instance.render()\n })\n }\n}\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\n/**\n * Post-roll interactive action buttons injected into dice result chat messages.\n * Allows players to pull dice from the Loksyu (as Successes or d\u00E9s-fastes)\n * and allows the GM to spend Tin Ji to intervene.\n *\n * After a draw, the originating roll result message is updated in-place\n * with the new counts, without creating noise.\n */\n\nimport { getLoksyuData, setLoksyuData, getTinjiValue, setTinjiValue } from \"./apps/singletons.js\"\nimport { SYSTEM_ID, WU_XING_CYCLE, ASPECT_LABELS, ASPECT_ICONS } from \"../config/constants.js\"\n\nconst RESULT_TEMPLATE = \"systems/fvtt-chroniques-de-l-etrange/templates/form/cde-dice-result.html\"\n\n/**\n * Inject or refresh post-roll action buttons in the given chat message HTML element.\n * Called from renderChatMessageHTML hook.\n * @param {ChatMessage} message\n * @param {HTMLElement} html - the chat message HTML element (li.chat-message)\n */\nexport function injectRollActions(message, html) {\n const rollCard = html.querySelector(\".cde-roll-result\")\n if (!rollCard) return\n const aspect = rollCard.dataset.aspect\n if (!aspect || !WU_XING_CYCLE[aspect]) return\n refreshRollActions(rollCard, aspect, message)\n}\n\n/**\n * Re-render the action buttons section based on current Loksyu / TinJi state.\n */\nfunction refreshRollActions(rollCard, aspect, message) {\n rollCard.querySelector(\".cde-roll-actions\")?.remove()\n\n const cycle = WU_XING_CYCLE[aspect]\n const fasteAspect = cycle[1]\n\n const loksyu = getLoksyuData()\n const tinji = getTinjiValue()\n\n const successAvail = (loksyu[aspect]?.yin ?? 0) + (loksyu[aspect]?.yang ?? 0)\n const fasteAvail = (loksyu[fasteAspect]?.yin ?? 0) + (loksyu[fasteAspect]?.yang ?? 0)\n const isGM = game.user.isGM\n\n const hasSomething = successAvail > 0 || fasteAvail > 0 || (isGM && tinji > 0)\n if (!hasSomething) return\n\n const aspLabel = game.i18n.localize(ASPECT_LABELS[aspect])\n const fasteLabel = game.i18n.localize(ASPECT_LABELS[fasteAspect])\n\n let btns = \"\"\n\n if (successAvail > 0) {\n btns += ``\n }\n\n if (fasteAvail > 0) {\n btns += ``\n }\n\n if (isGM && tinji > 0) {\n btns += ``\n }\n\n const wrapper = document.createElement(\"div\")\n wrapper.className = \"cde-roll-actions\"\n wrapper.innerHTML = `\n
\n \n ${game.i18n.localize(\"CDE.PostRollActions\")}\n
\n
${btns}
\n `\n rollCard.appendChild(wrapper)\n\n wrapper.addEventListener(\"click\", async ev => {\n const btn = ev.target.closest(\"[data-action]\")\n if (!btn || btn.disabled) return\n const action = btn.dataset.action\n if (action === \"loksyu-success\") {\n await _drawFromLoksyu(message, aspect, \"success\", aspLabel)\n } else if (action === \"loksyu-faste\") {\n await _drawFromLoksyu(message, fasteAspect, \"faste\", fasteLabel)\n } else if (action === \"tinji\") {\n await _spendTinjiPostRoll()\n }\n // Buttons will be re-injected automatically via renderChatMessageHTML\n // after message.update(). For tinji (no message update), refresh manually.\n if (action === \"tinji\") refreshRollActions(rollCard, aspect, message)\n })\n}\n\n/**\n * Pull one die from a given Loksyu aspect slot, update Loksyu settings,\n * and update the originating roll-result message in-place.\n *\n * @param {ChatMessage} message - the roll result chat message to update\n * @param {string} aspect - which Loksyu aspect slot to draw from\n * @param {\"success\"|\"faste\"} type\n * @param {string} aspectLabel - localised aspect name for the notification\n */\nasync function _drawFromLoksyu(message, aspect, type, aspectLabel) {\n const data = getLoksyuData()\n const entry = data[aspect] ?? { yin: 0, yang: 0 }\n const total = entry.yin + entry.yang\n if (total <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.LoksyuEmpty\"))\n return\n }\n\n // Remove 1 die (prefer yang first)\n if (entry.yang > 0) entry.yang--\n else entry.yin--\n data[aspect] = entry\n await setLoksyuData(data)\n\n // Update the roll-result message in-place if it has stored flags\n const flags = message?.flags?.[SYSTEM_ID]\n if (flags?.rollResult && message.isOwner) {\n const updated = foundry.utils.deepClone(flags.rollResult)\n if (type === \"success\") {\n updated.successesdice = (updated.successesdice ?? 0) + 1\n updated.loksyuBonusSuc = (updated.loksyuBonusSuc ?? 0) + 1\n // Recalculate weapon damage if applicable\n if (updated.damageBase) updated.totalDamage = updated.successesdice * updated.damageBase\n } else {\n updated.auspiciousdice = (updated.auspiciousdice ?? 0) + 1\n updated.loksyuBonusFaste = (updated.loksyuBonusFaste ?? 0) + 1\n }\n const newHtml = await foundry.applications.handlebars.renderTemplate(RESULT_TEMPLATE, updated)\n await message.update({\n content: newHtml,\n [`flags.${SYSTEM_ID}.rollResult`]: updated,\n })\n // renderChatMessageHTML hook fires automatically \u2192 buttons re-injected\n }\n\n const remain = entry.yin + entry.yang\n const typeLabel = type === \"success\"\n ? game.i18n.localize(\"CDE.Successes\")\n : game.i18n.localize(\"CDE.AuspiciousDie\")\n\n ChatMessage.create({\n user: game.user.id,\n content: `
\n
\n \"${aspectLabel}\"/\n ${game.user.name}\n ${game.i18n.localize(\"CDE.LoksyuDrawsA\")}\n ${typeLabel}\n ${game.i18n.localize(\"CDE.LoksyuFromAspect\")} ${aspectLabel}\n
\n
\n \n ${game.i18n.localize(\"CDE.Loksyu\")} ${aspectLabel} : \n ${remain} ${game.i18n.localize(\"CDE.LoksyuRemaining\")}\n
\n
`,\n })\n}\n\n/**\n * Spend 1 Tin Ji point (GM only) and post a notification.\n */\nasync function _spendTinjiPostRoll() {\n if (!game.user.isGM) return\n const current = getTinjiValue()\n if (current <= 0) {\n ui.notifications.warn(game.i18n.localize(\"CDE.TinjiEmpty\"))\n return\n }\n await setTinjiValue(current - 1)\n ChatMessage.create({\n user: game.user.id,\n content: `
\n \u5929\n \n ${game.user.name} ${game.i18n.localize(\"CDE.TinjiSpent\").replace(\"{name}\", game.user.name)}\n \n (${current - 1} ${game.i18n.localize(\"CDE.TinjiRemaining\")})\n
`,\n })\n}\n\n/**\n * Refresh all visible roll-result buttons when Loksyu or TinJi settings change.\n * Wired up via Hooks.on(\"updateSetting\", ...) in system.js.\n */\nexport function refreshAllRollActions() {\n document.querySelectorAll(\".chat-message .cde-roll-result[data-aspect]\").forEach(card => {\n const aspect = card.dataset.aspect\n if (!aspect || !WU_XING_CYCLE[aspect]) return\n // Find the ChatMessage document from the ancestor element's data-message-id\n const msgEl = card.closest(\"[data-message-id]\")\n const msgId = msgEl?.dataset?.messageId\n const message = msgId ? game.messages.get(msgId) : null\n refreshRollActions(card, aspect, message)\n })\n}\n\n", "/**\n * Chroniques de l'\u00C9trange \u2014 Syst\u00E8me FoundryVTT\n *\n * Chroniques de l'\u00C9trange est un jeu de r\u00F4le \u00E9dit\u00E9 par Antre-Monde \u00C9ditions.\n * Ce syst\u00E8me FoundryVTT est une impl\u00E9mentation ind\u00E9pendante et n'est pas\n * affili\u00E9 \u00E0 Antre-Monde \u00C9ditions,\n * mais a \u00E9t\u00E9 r\u00E9alis\u00E9 avec l'autorisation d'Antre-Monde \u00C9ditions.\n *\n * @author LeRatierBretonnien\n * @copyright 2024\u20132026 LeRatierBretonnien\n * @license CC BY-NC-SA 4.0 \u2013 https://creativecommons.org/licenses/by-nc-sa/4.0/\n */\n\nimport { ACTOR_TYPES, ITEM_TYPES, MAGICS, SUBTYPES, SYSTEM_ID } from \"./config/constants.js\"\nimport { registerSettings, migrateIfNeeded } from \"./config/settings.js\"\nimport { preLocalizeConfig } from \"./config/localize.js\"\nimport { configureRuntime } from \"./config/runtime.js\"\nimport { CharacterDataModel, NpcDataModel } from \"./data/actors/index.js\"\nimport { EquipmentDataModel, KungfuDataModel, SpellDataModel, SupernaturalDataModel, WeaponDataModel, ArmorDataModel, SanheiDataModel, IngredientDataModel } from \"./data/items/index.js\"\nimport { CDEMessage } from \"./documents/chat-message.js\"\nimport { CDEActor } from \"./documents/actor.js\"\nimport { CDEItem } from \"./documents/item.js\"\nimport { registerDice } from \"./ui/dice.js\"\nimport { registerHandlebarsHelpers } from \"./ui/helpers.js\"\nimport { preloadPartials } from \"./ui/templates.js\"\nimport { CDECharacterSheet, CDENpcSheet } from \"./ui/sheets/actors/index.js\"\nimport { CDEItemSheet, CDEKungfuSheet, CDESpellSheet, CDESupernaturalSheet, CDEWeaponSheet, CDEArmorSheet, CDESanheiSheet, CDEIngredientSheet } from \"./ui/sheets/items/index.js\"\nimport { CDELoksyuApp } from \"./ui/apps/loksyu-app.js\"\nimport { CDETinjiApp } from \"./ui/apps/tinji-app.js\"\nimport { CDEWheelApp } from \"./ui/apps/wheel-app.js\"\nimport { injectRollActions, refreshAllRollActions } from \"./ui/roll-actions.js\"\nimport { CDECombat } from \"./documents/combat.js\"\n\nHooks.once(\"i18nInit\", preLocalizeConfig)\n\nHooks.once(\"init\", async () => {\n console.info(`CHRONIQUESDELETRANGE | Initializing ${SYSTEM_ID}`)\n\n registerSettings()\n\n game.system.CONST = { MAGICS, SUBTYPES }\n\n // Expose standalone apps globally for macros\n game.cde = { CDELoksyuApp, CDETinjiApp, CDEWheelApp }\n\n CONFIG.Combat.documentClass = CDECombat\n\n CONFIG.Actor.dataModels = {\n [ACTOR_TYPES.character]: CharacterDataModel,\n [ACTOR_TYPES.npc]: NpcDataModel,\n }\n CONFIG.Item.dataModels = {\n [ITEM_TYPES.item]: EquipmentDataModel,\n [ITEM_TYPES.kungfu]: KungfuDataModel,\n [ITEM_TYPES.spell]: SpellDataModel,\n [ITEM_TYPES.supernatural]: SupernaturalDataModel,\n [ITEM_TYPES.weapon]: WeaponDataModel,\n [ITEM_TYPES.armor]: ArmorDataModel,\n [ITEM_TYPES.sanhei]: SanheiDataModel,\n [ITEM_TYPES.ingredient]: IngredientDataModel,\n }\n\n CONFIG.Actor.documentClass = CDEActor\n CONFIG.Item.documentClass = CDEItem\n CONFIG.ChatMessage.documentClass = CDEMessage\n\n configureRuntime()\n\n foundry.applications.apps.DocumentSheetConfig.unregisterSheet(Actor, \"core\", foundry.appv1.sheets.ActorSheet)\n foundry.applications.apps.DocumentSheetConfig.unregisterSheet(Item, \"core\", foundry.appv1.sheets.ItemSheet)\n\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Actor, SYSTEM_ID, CDECharacterSheet, {\n types: [ACTOR_TYPES.character],\n makeDefault: true,\n label: \"CDE Character Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Actor, SYSTEM_ID, CDENpcSheet, {\n types: [ACTOR_TYPES.npc],\n makeDefault: true,\n label: \"CDE NPC Sheet (V2)\",\n })\n\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEItemSheet, {\n types: [ITEM_TYPES.item],\n makeDefault: true,\n label: \"CDE Item Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEKungfuSheet, {\n types: [ITEM_TYPES.kungfu],\n makeDefault: true,\n label: \"CDE KungFu Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDESpellSheet, {\n types: [ITEM_TYPES.spell],\n makeDefault: true,\n label: \"CDE Spell Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDESupernaturalSheet, {\n types: [ITEM_TYPES.supernatural],\n makeDefault: true,\n label: \"CDE Supernatural Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEWeaponSheet, {\n types: [ITEM_TYPES.weapon],\n makeDefault: true,\n label: \"CDE Weapon Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEArmorSheet, {\n types: [ITEM_TYPES.armor],\n makeDefault: true,\n label: \"CDE Armor Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDESanheiSheet, {\n types: [ITEM_TYPES.sanhei],\n makeDefault: true,\n label: \"CDE Sanhei Sheet (V2)\",\n })\n foundry.applications.apps.DocumentSheetConfig.registerSheet(Item, SYSTEM_ID, CDEIngredientSheet, {\n types: [ITEM_TYPES.ingredient],\n makeDefault: true,\n label: \"CDE Ingredient Sheet (V2)\",\n })\n\n await preloadPartials()\n registerHandlebarsHelpers()\n registerDice()\n\n console.info(`CHRONIQUESDELETRANGE | Initialized`)\n})\n\nHooks.once(\"ready\", async () => {\n await migrateIfNeeded()\n CDEWheelApp.registerHooks()\n})\n\n/** Add Loksyu + Tin Ji quick-access buttons to the chat panel (FoundryVTT v13) */\nHooks.on(\"renderChatLog\", (_app, html) => {\n const el = html instanceof HTMLElement ? html : (html[0] ?? html)\n if (!el?.querySelector) return\n\n // Avoid double-injection on re-renders\n if (el.querySelector(\".cde-chat-app-buttons\")) return\n\n const wrapper = document.createElement(\"div\")\n wrapper.classList.add(\"cde-chat-app-buttons\")\n wrapper.innerHTML = `\n \n \n \n `\n\n // Use event delegation to avoid being swallowed by Foundry's own handlers\n wrapper.addEventListener(\"click\", (ev) => {\n if (ev.target.closest(\".cde-chat-btn--loksyu\")) CDELoksyuApp.open()\n if (ev.target.closest(\".cde-chat-btn--tinji\")) CDETinjiApp.open()\n if (ev.target.closest(\".cde-chat-btn--wheel\")) CDEWheelApp.open()\n })\n\n // Insert before the chat form \u2014 works on v12 and v13\n const anchor = el.querySelector(\".chat-form\")\n ?? el.querySelector(\".chat-message-form\")\n ?? el.querySelector(\"form\")\n if (anchor) anchor.parentElement.insertBefore(wrapper, anchor)\n else el.appendChild(wrapper)\n})\n\n/** Inject Loksyu / TinJi action buttons into roll-result chat messages */\nHooks.on(\"renderChatMessageHTML\", (message, html) => {\n injectRollActions(message, html)\n})\n\n/** Refresh all visible roll-result buttons whenever Loksyu or TinJi settings change */\nHooks.on(\"updateSetting\", setting => {\n if (!setting.key) return\n if (setting.key.includes(\"loksyuData\") || setting.key.includes(\"tinjiData\")) {\n refreshAllRollActions()\n }\n})\n\n/**\n * When an actor's initiative changes (via +/- buttons on the sheet),\n * sync the corresponding combatant in the active combat.\n */\nHooks.on(\"updateActor\", (actor, diff) => {\n if (!foundry.utils.hasProperty(diff, \"system.initiative\")) return\n if (!game.combat) return\n const initiative = actor.system.initiative\n const combatant = game.combat.combatants.find(c => c.actor?.id === actor.id)\n if (combatant && combatant.initiative !== initiative) {\n combatant.update({ initiative }).catch(() => {})\n }\n})\n\n/**\n * When a combatant's initiative changes (via wheel action buttons),\n * sync the actor's system.initiative to match.\n * Uses setTimeout to defer until after Foundry's update chain resolves,\n * avoiding concurrent #recordPreviousState errors on the combat document.\n */\nHooks.on(\"updateCombatant\", (combatant, diff) => {\n if (!(\"initiative\" in diff)) return\n const initiative = combatant.initiative\n if (initiative == null) return\n setTimeout(() => {\n const actor = combatant.actor\n if (actor && actor.system?.initiative !== initiative) {\n actor.update({ \"system.initiative\": initiative }).catch(() => {})\n }\n }, 0)\n})\n"], + "mappings": "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", "names": ["RESULT_TEMPLATE", "HandlebarsApplicationMixin", "app", "app", "RESULT_TEMPLATE"] } diff --git a/lang/fr-cde.json b/lang/fr-cde.json index c667c24..d179341 100644 --- a/lang/fr-cde.json +++ b/lang/fr-cde.json @@ -131,6 +131,28 @@ "CDE.InitiativeNPCSpeciality": "Première action (Aptitude) que vous escomptez effectuer", "CDE.InitiativeRoll": "Jet d'initiative", "CDE.InitiativeSpeciality": "Première action (Compétence) que vous escomptez effectuer", + "CDE.InitiativeWheel": "Roue d'Initiative", + "CDE.InitiativeWheelOpen": "Ouvrir la Roue d'Initiative", + "CDE.InitiativeWheelHint": "Roue d'initiative – Les Chroniques de l'Étrange", + "CDE.ActionCostAttack": "Attaque", + "CDE.ActionCostDefense": "Défense", + "CDE.ActionCostDefendAlly": "Défendre un allié", + "CDE.ActionCostMove": "Déplacement", + "CDE.ActionCostHelp": "Aide", + "CDE.ActionCostAim": "Viser", + "CDE.ActionCostChangeStyle": "Changer d'art", + "CDE.ActionCostDraw": "Dégainer", + "CDE.ActionCostDelay": "Retarder (événement)", + "CDE.ActionCostAdvance": "Avancer de {n} crans", + "CDE.ActiveCombatant": "Combat en cours — ce personnage agit maintenant", + "CDE.AdvanceCombatant": "Avancer sur la roue", + "CDE.Combatants": "Combattants", + "CDE.NoCombatActive": "Aucun combat en cours", + "CDE.SelectCombatantHint": "Cliquez sur un combattant pour sélectionner ses actions", + "CDE.SurprisedAction": "Pris par surprise", + "CDE.SurprisedHint": "Place le personnage sur le cran de référence (position 1)", + "CDE.WheelCran": "Cran", + "CDE.WheelReference": "Repère", "CDE.Inquiry": "Renseignement", "CDE.InternalCinnabar": "Cinabre Interne", "CDE.Investigation": "Enquête", diff --git a/packs/cde-armors/000004.log b/packs/cde-armors/000004.log deleted file mode 100644 index e69de29..0000000 diff --git a/packs/cde-armors/000007.log b/packs/cde-armors/000007.log new file mode 100644 index 0000000000000000000000000000000000000000..819af2b59d954e00bdaca94411b9041daddab345 GIT binary patch literal 3153 zcmeH}OKTiQ5XWPPZ@K4^Lwhc{>_Z#H3R#Rnl7;bOgJKIwBpA~>Q!}d2k5PBecx55T zcgQ)Aqt{kzu>k+X)6EAripx~faTNmEdtwJgZ@ zIkl$!?#_(#d|kj$Ya$t*CXRA)WYV||1~T%g<1(-{=(thdoI85NK3Es`5vkRsYMuoW z@U&Di?kzH!JKYm|u6gE#la4x~Xr`u_I;lvL32}k0d^4q<*fFp(hOe-rC1XJ|_1GkK z^ltRan{cLdHc%RU*_Wzq* zw>Zx^tyDNkhJ#LWTwyz&Hw-rO@fOZH3FSF#qV?mWPLf-dkxPcAQVLgRT}Xy&u=vD~ z^G969Ys@H@FpB}K&Xp{%_7r~~<3!QU>HNy?#IShZ!z~|YAI95P7_9f!dTSU+t)rFh z_3MM!?MMd7_BcjX>!h|B=e*jdqz|Kc{}#^Q&Wx`~CgVy!w3Ult(Dr9lsW^q*)oz-U zIREQ?XJ<Nv_(j(IBX%L+V8DITPGC)*I$|V^sG5-u1JBM`WZfVO;PX?po$@LdYGA@pslW`ld5=4nS z+8s+k;6-2T6Hm(kV}<-@_am%NDt-rw+DM$J8M5Zb>r{CUrQD)j-0cAC>pat znP5>tAWop|2%P@|2l3|GY6;#Nu1O-jFHV3mXcAoWT({*>Jr8#Pfnx3Jn!l A=Kufz literal 0 HcmV?d00001 diff --git a/packs/cde-armors/CURRENT b/packs/cde-armors/CURRENT index 1a84852..f7753e2 100644 --- a/packs/cde-armors/CURRENT +++ b/packs/cde-armors/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000006 diff --git a/packs/cde-armors/LOG b/packs/cde-armors/LOG index 4719a47..ab97ea8 100644 --- a/packs/cde-armors/LOG +++ b/packs/cde-armors/LOG @@ -1,5 +1,3 @@ -2026/04/27-17:47:13.055628 7f2779bff6c0 Delete type=3 #1 -2026/04/27-17:47:13.058468 7f272b7fe6c0 Level-0 table #5: started -2026/04/27-17:47:13.061813 7f272b7fe6c0 Level-0 table #5: 1330 bytes OK -2026/04/27-17:47:13.067956 7f272b7fe6c0 Delete type=0 #3 -2026/04/27-17:47:13.068111 7f272b7fe6c0 Manual compaction at level-0 from '!items!3aig6MWvZCRoWXPW' @ 72057594037927935 : 1 .. '!items!cXaQG1TBE0jzrbNt' @ 0 : 0; will stop at (end) +2026/04/27-20:01:11.390845 7fed927fc6c0 Recovering log #4 +2026/04/27-20:01:11.400505 7fed927fc6c0 Delete type=3 #2 +2026/04/27-20:01:11.400599 7fed927fc6c0 Delete type=0 #4 diff --git a/packs/cde-armors/LOG.old b/packs/cde-armors/LOG.old new file mode 100644 index 0000000..4719a47 --- /dev/null +++ b/packs/cde-armors/LOG.old @@ -0,0 +1,5 @@ +2026/04/27-17:47:13.055628 7f2779bff6c0 Delete type=3 #1 +2026/04/27-17:47:13.058468 7f272b7fe6c0 Level-0 table #5: started +2026/04/27-17:47:13.061813 7f272b7fe6c0 Level-0 table #5: 1330 bytes OK +2026/04/27-17:47:13.067956 7f272b7fe6c0 Delete type=0 #3 +2026/04/27-17:47:13.068111 7f272b7fe6c0 Manual compaction at level-0 from '!items!3aig6MWvZCRoWXPW' @ 72057594037927935 : 1 .. '!items!cXaQG1TBE0jzrbNt' @ 0 : 0; will stop at (end) diff --git a/packs/cde-armors/MANIFEST-000002 b/packs/cde-armors/MANIFEST-000002 deleted file mode 100644 index 310d6529fc48b4419d3bd5e349e6984bb25187b0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmWIhx#Ncn10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAe$kRS-TOEg7@3$k8JJmE z7^a1ve&Y+|vH-bkEG+Cyted#x6*EgxbBh&?6EoAze8bD4oP+YiBLc!185zI;CZ8OU W80c;o;^b(Z6pl< diff --git a/packs/cde-armors/MANIFEST-000006 b/packs/cde-armors/MANIFEST-000006 new file mode 100644 index 0000000000000000000000000000000000000000..e6e2d8fe74d19d6f8265bed7f8e9a4a834cf9398 GIT binary patch literal 119 zcmZP-dU`35fss)vC$%g!CnZVGsj?)sJhM2}IX|}`u_&=5zlfcQbrYAoVrEHdZn2_q zVrIITZ+Kahb5MSGL_jzrBLf(~2WYHGO=?q JFmtf5004-cACCY4 literal 0 HcmV?d00001 diff --git a/packs/cde-ingredients/000004.log b/packs/cde-ingredients/000004.log deleted file mode 100644 index e69de29..0000000 diff --git a/packs/cde-ingredients/000007.log b/packs/cde-ingredients/000007.log new file mode 100644 index 0000000000000000000000000000000000000000..ba697d79d56c00eb7f074e4dd82fab2b85a1debf GIT binary patch literal 32147 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 lK^RioRITodow6 diff --git a/packs/cde-ingredients/MANIFEST-000006 b/packs/cde-ingredients/MANIFEST-000006 new file mode 100644 index 0000000000000000000000000000000000000000..3792c69ee84bba88984ce04e3d6fd77474c3a7db GIT binary patch literal 119 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 XR*;*RT%I59>TVGk;vC2*15p3~@@^#L diff --git a/packs/cde-npcs/MANIFEST-000006 b/packs/cde-npcs/MANIFEST-000006 new file mode 100644 index 0000000000000000000000000000000000000000..b4ae1d248eac2d95a2487c25b447eeae3b62a199 GIT binary patch literal 122 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 literal 0 HcmV?d00001 diff --git a/packs/cde-sanhei/CURRENT b/packs/cde-sanhei/CURRENT index 1a84852..f7753e2 100644 --- a/packs/cde-sanhei/CURRENT +++ b/packs/cde-sanhei/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000006 diff --git a/packs/cde-sanhei/LOG b/packs/cde-sanhei/LOG index 6b5d8d2..a758d72 100644 --- a/packs/cde-sanhei/LOG +++ b/packs/cde-sanhei/LOG @@ -1,5 +1,3 @@ -2026/04/27-17:47:13.202702 7f27793fe6c0 Delete type=3 #1 -2026/04/27-17:47:13.203697 7f272b7fe6c0 Level-0 table #5: started -2026/04/27-17:47:13.207185 7f272b7fe6c0 Level-0 table #5: 4830 bytes OK -2026/04/27-17:47:13.213948 7f272b7fe6c0 Delete type=0 #3 -2026/04/27-17:47:13.214169 7f272b7fe6c0 Manual compaction at level-0 from '!items!DC2kimCi9sWxqhXG' @ 72057594037927935 : 1 .. '!items!qzfAEhmvVxEMzm0k' @ 0 : 0; will stop at (end) +2026/04/27-20:01:11.404989 7fed937fe6c0 Recovering log #4 +2026/04/27-20:01:11.415714 7fed937fe6c0 Delete type=3 #2 +2026/04/27-20:01:11.415769 7fed937fe6c0 Delete type=0 #4 diff --git a/packs/cde-sanhei/LOG.old b/packs/cde-sanhei/LOG.old new file mode 100644 index 0000000..6b5d8d2 --- /dev/null +++ b/packs/cde-sanhei/LOG.old @@ -0,0 +1,5 @@ +2026/04/27-17:47:13.202702 7f27793fe6c0 Delete type=3 #1 +2026/04/27-17:47:13.203697 7f272b7fe6c0 Level-0 table #5: started +2026/04/27-17:47:13.207185 7f272b7fe6c0 Level-0 table #5: 4830 bytes OK +2026/04/27-17:47:13.213948 7f272b7fe6c0 Delete type=0 #3 +2026/04/27-17:47:13.214169 7f272b7fe6c0 Manual compaction at level-0 from '!items!DC2kimCi9sWxqhXG' @ 72057594037927935 : 1 .. '!items!qzfAEhmvVxEMzm0k' @ 0 : 0; will stop at (end) diff --git a/packs/cde-sanhei/MANIFEST-000002 b/packs/cde-sanhei/MANIFEST-000002 deleted file mode 100644 index f18fe734b9424be0dc5fe0c6c579d902e1fa2d21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 134 zcmWIhx#Ncn10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAe$kRS-TOEg7@3$k8JJmE z7`A$@wetmXS%6$N7FKp9)_bb*ikT&;xy6bu&PLgpxz3rE#o-l&84>P`%nV=vlP|1F Wb9BwfEeoq~^{vV^$Yx}O$O8bD>?CCX diff --git a/packs/cde-sanhei/MANIFEST-000006 b/packs/cde-sanhei/MANIFEST-000006 new file mode 100644 index 0000000000000000000000000000000000000000..ad4c48d5a2980c9cabbee102c3c3983cd16a5658 GIT binary patch literal 119 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�nn@*-taxQMt&Im` z_GZcF?OWGDp)DL!(pZ8yoegw%dWsh=L95;SsoatzlTMOz)Sw!ZrBiTKQ)k0?iw&(1 zRQTZ9WOG(`lg!{~;?sz?#R>{pIuBe*#2I*~<_P=O<(kHlw3ti>4X8AwXs=QXy;fI% zM>siP@qxo;0w%`po?cx&2`Uft)k91N%~XlyJfvNQ9~|R#C(*-=TH{3zv!Oz9yqrT1 zCPS(Le`C@iP%-ftvXeIj8_>E6J3M^gzIE&O;Mf+X@I0zH+MBFmwevj*%~e>89k$&Y zn@m@@7e`peLKh)nLw3q3<_;B+D!0TnF+g%pv+fGkdMCtJ33xrK)7u;E)J!%j2R#UI zIx|xde#JoFQ)PI`oY!&`dtC9_%<(K}<1c^A1wcjL1k*+f4txsb&0sUvNgi8rtvT#h zI1X&HqJn$9yqF-S7Bddgi1NwaW>zu$aaj^)hAYzee&?++QCD5)+6}E&F(CtL z-Xm6GSlsIZyl%zNH5sPt?i7+><3ez2J3#HFS6%{ExOyBU337?Dd%qK}31bLK9;&*ss#?D%%{b57$_~u!VjF za1U{tqBz$?*v3kb`0L;7?g6v4S>%Tf)`FATYfh8~d&X;#M%lnfJ<_!@C5}- z8kMHM(o$8S)i)!(Jn14}i*#dJ?O~~5=0M&k9qJf8`#U=NO^#1FclGgIs)2&(5t0U8 znQUBa)|;kOUGJ=vCvhi$<`wYD-RB%pGgqRP0s^MMqgcqiBx zw3dC3ceo`}<;3+u;NT)Bh}Tj~4;e0r)agE9+2gVEpSANp+LPRE@C8HLT7$@821^kg zA)Q`o_a3PxJgEWOn->2SmR7;W;T(hyqScBiqsrk99R^4UOO&U1CLp4=+%$Enav9A? z`zVisYtxGr8{i!U6)$GMHITyM-jsz22odq3X2b1jAPi!aj;4g#VnjA6us#@^c=tZj zEH-&}kz)moPyyOIk(%I|_va+LgvN*iDl;6##e&EBm`<5Fj`z&r5>?EC1R*N=fk%iH zrBm8~?qF;nkWIA?@8g`_2AmpyRcX2uy*jDDc8`8JTj2u!*sh_w-I-_VUUB>&kos-W zjbL;@gJjUVqH(L3*=Q`Er_kq)ZLkaD!#7_9=mL_!M!uXMoE=SmFutnE{Eaj7O4UW| zL|1abeEW%c*P|~T)Iy^(n-p5HVz^ql9v(o{v@h>;us}7rTBaVZxOq@05oi#Ls+i0X zTraU}smbdokBP2&T$^9plGir?QZTImn&F}h^Dq1k*726?yET9Xonv+a!SsZVODrx@ zd(yz{&)2_fpKQNbd}N;0sNR+@xpBGB*o3$PErL}W-wp?^W(IbRsH+*RzPYfEOI)bv~zVN_kptGSX-?VQ&tmr17J|4(x_Jo+_hLXfd?+YYdWG0!9t*#|Q z@PovYM5>yN2p=k`?s3N}vK4wjQkb8S6UdhL1!8Ya?`_b%Sj`~XI^7|SM7Ev=R0F28 zU1$4sBeIXJfoa~;L&81|Q|T$GX$tRHNO?LXV2eK$!AQJ%@M?MZ+pF2(>jy|vfs@wx zqrH4K1&ps5l*12<-sRdwdkZV@eOsM{=N2_Oi}LyQAxwxAsPV&1b17?vTh@?9t!6?i zC?WzY;lnV5CZSmuZfag4&qmiO(-iYn;cVIIayCgQosQ0y?R**EvY|LCZAx?yRj5+d z%Nbcwt?J~zR8A2-76g@lQRW<}x{!iBz=sAz7S0R3$P;;~A|zKlV*V9IaGiVCg$084 z!z>ouvYZ!2F=h&>3o!})xF9qLeU$V(pZ9F^4BbL;q#d#jL0bU=-~w}U zl&Y#-$z(=mf!uk{eSs16!eo=p<5s(t(5EkQU?9hLI2Y!Nb#REld90GLu|DD>O^x(! zf_Ruo;83=Zs;<6PMe8HA^d3Y$&`_l8Z(a^6dh3c|l{uwAjFgDbZLsP%uTEeAZXqjx zIP`6blhu-2-H_~#6z8WTEz-420d%RPpGcIY)j_Jt))Hx(!_0Sc^>FMEO@xlPtJr`l z2V8yUeg`6F0O09Azz0 zAHqLLL4BY7#vQb-DWUBbn!;!`Ju29;XcF@goEy@?xN-zZ_qXmwSltlrf*7ZO1^aP8 zYFj2ja*oKx)COv)%wROs92JX>0JR4vl)}}5;)k)Xmtum4F>0*$a2I@KP--nI1|S2B z61kHo9@3TIx9IOJNBKtl2@VEn4wtY>qN>=LbO$;2$)*UNb+!qqjLeB|M@rOKES)#$%(_DV@?hl-GoKA)EH4s)Tnjf63zZ6M8|QP4BK#E&7e%PSW@ zp*z=3DZ!}r*Rk!(9!ex8ZO2VwVS70SXJvvQ3MVuGQa@Cm=dR3(L#;%>e;Y2m+b4e& zL1|^d#H+OM%T-|XishlgVq=y@@;ao0z0NF}U;XG`lP6~xZ%U86tRkSonDgi7rkOcs zPZtJ2Gz1&fo)`!jqq#h#7#D9#M-(!xVm;Rq$gf(F$#*g_ERBaUmRUZLy}DicbYd<1 zANZ|B6>lPaTug_{Hv5V*DcUaY(TfIto#v9Y0jy^~MB(MlXB_V%b^w4PK*^-4jMc@q zClCxTq5OJLn;BncUDS!p6c(@cVLF&NclcIT4BvI7@;JdI$@x zqTVqpZRW_N(-kx8p2>7!s1TUKS0x^u#T4ol2^}?&1pxd(b2>w->J3Z&P86x+fH*#%N}x1>>RgplawYB}(KyMZWs)+IH8`v`xg;i=Mj6xJ zk-iJg;Sg8C4eD}y+j7q?d=yvE`5Me0Y3YbYF0n&c^HobNbOox`!!~jGZ19v$hbhq5 zZ}U)uq~ij_5%1uyVS4~mb*zLk3&cK#GWieg0~LWYLJ0rNe=R1UkX+IOgJ+fyA^2vc zn0!?LrA~)Sk!*EUs9h(RvZC<70<62r5RHd#n^IW?vOYvv1iPfrz+QbB2J=m|}@v-yOi6P#0Ey$a(X!b28c7YQxJD%CjfbDZN9 z2!bpY!`H1WzLqy|-{+^(i_0m7r)DtSvIAiN*MaHT6pz@EnE>G5$7kBTJ?SsHy1 z^NPN1u0g35yr?=x-mC88gcLmMVH#gxxQ$u%+h7G|-Q)1l(>{{vVUKBiAVX)~tb;ox zK0SaeeGqKkl$X-wv|?BkZ1}=Z%c=;rbCygU1AuK@%UOzIJ5Sy5jh>Mil7X$ilq+L| zA-HlmC~^y~d~T~v2t|PQKHT!sfw3CSioVOae1FhNZ1FP8&*!W^z zX3#IId6Rq_?0z@QeVaZYCi2YyvkPorWq~``h-Xs<)C8|!-|8UxPH*;?`H6i>@|A$6 zf|xkmNcgRk6f&{fjw5L zhqck#7bShF=4DbiMOioAky2O|HMmnqWGC$7L(+D!){2pr2>=N=v>8HR5iE;M%`b8K zkw$>1@+;xG97ccw+khz)7cMPF-#Z=GD_;|~8rM4>FS8VKgAFtUQZlp@9J9q5B6i(1 z0h4t zjY;cW6MD+gqQU+Q?NV>8==2lU-^X0TZ$>%XK%BMai|?j-zhc;AQ$tb(!=Iy4J|6fp>H+c z9OYNl_$4B7rx9`Ux(gW_-jnhP%0h1KSA(&R5zwq|2{v|Rvrt=X{9xD?E{vJ=B87oi zl%#h=d8{!MZ`GBNXXslc?4Xl%nMNR$H8?lqeT>AB@yD<#e##fCv1vqBW5T&&{6~k7 z?5xuF%zPr>D6JpM25_bT4SruHkNa5wK2k~(ydjv#zl|ui&fRT75(yS(K_%k*Ql%1O z&@|MKJC!YLvo*-(^Zy@t@6x2%b)9F1Lp|%Bd)P@#R0snQK!B74DdYeOMG#;CL<2?2 zl)~Z8%F4=0FfYZt6so9Dh@+0+SUqsh+#JXR9br%0Bh6gl-_Uao+<%~Z;6Zov^So>C zea`v5FK-|q&|-u{RA!!i&c3YcyDl3uax>dF$4%ncLAs`c~-rW~sopnzuw|9Qj08)Dlnju7vWce`J75XVMRuD5IK!k})gmr6se> z^{&YFilkyfIHndj#(amL@J7la4Px3bN9!hdulR%?+Kj@MCbJEb8-wjK2-ZE;33Gy!QpY9z{?Go4wJ6plq1gMWNFxN;Nzx z1VZyw#hsXHb==0BMx97%Y;Qyj;VO;^Gm}&vp@9JzZiJE>&t45jLQQ+eyEKU1?~R^c z|MnlhC?H#!N_s&5BByZ|{`vp#f4~1<|K|7Tx5%_YG#|Zx!(ii~#wClH&n{DOJ-0xSy z2gpzIg+kiHc4}YR1bR)D62Rs31#etXI?HM)nBq?maJI>u6!(#7UB+;rjat;Yz7Mm7O)y`F)JKKfb4{b9+_~pUQV6d zU;lk~I{{_@S9qAz0KXK)4rs(IVuny5L%tcgff)?FnK@9A(+VU*?S_Z*^0%zH4k|&? zlW!YHgl|h9Cf+919zOpCHwk1VGDop0|A_6Zeb_TxMk)Z0rP>gjNVr(vJgY!i)Hzk^5>No$4&&EEr^al>4n6I2DL4R14y|Y2OP+q zvU_Hb`PD@fY)&%cXi%k5MBkd-t#54ofRu6O---1on{fVsevoQ=d5R0`E5)*AicI0{ zt*-?F*#RWQCpnAe7p|3a<>dKW!aM=iyk7FcxKiGca z3i_1b`VyH=Y2A)#TD(b4ztC7OjQlmm~pu(V%XWkdsnaiXEzdJUDz|xFi;6=M zQl^wNrgfqUW}UNHHiwWSGzhnDKcY&&eQP}^zy#CU!LK9&F}gcQs2F;hY`lHyERhfq zX?`4YO--ReuSVKEtKlt#;o!1Zl_D_4Q z+Uj52)9SbXA^MB^SLw;*3G(}|zf=vbNJn1OOVw2XQ9~uLTkp}NENYGv=FUiifLhi5 zX`%p+q>O=qXbJ>dOYzAKR`8ojjkvwK(T=6?oP^kFan)>lY{(O{)hB_#3|joE+7|LH zIuIfwKvndE`MYveGlrM7W=1r};0H{+vzM7j7Z3DdLs^Gu>Q^u&$sXa-2Z;R4(9qoZ z6Pp~7y0oksPL7@1@XxpI!qoryZ_ghno#TMzI}KZ)SKHyNwBH+skdZc?YnLyP(!N7~ zLbL?o`Q4OnMQgX`UgQIJPBV4(Bui_TlI$~Sf^20ZPY znz#ob8<}tyv8$%y=zG1e@I-16A_eEEclbsvxswQGiO+xD&E{M8v5Q{BKoN|}j&37y zu(LEuO4fLHVlAiSnaww!(IUgso_QTHXQLE3n)9RPHB5OIHGNgIhZqYICD|l@eUCFw z8j5dD@XN*M;FLk8RBx2bx>)4sBRtVytys<9sg?CZ=+MiV2WL&@$d7_%(>NSrXz?RX z7>@+oa~t*M5l3IE+KH?&5$bjz5yg6o`m`>cDTQxso0wQDlLu_c*1xiKuV>m$*;%57 zZ7ZQh(-Ac#I}hOjz#^?ih#ZmX?h;>eu&vuvN4q8kV!)!;ICBJ69V{G&r+T_i18LnX zQO#aWKUlcBMe|<#C(JW>9Xka9K!OSBRVPF#n)Gv{V@=PvEomwMxlg7`_&kd=58;W zQJw7n^rbBX`9mJWfP*a$c8;eCsfWsjt2WknhMlih z*EP-Bl)dE0=GutIe>TvdE7Lh!otpA%A**%!QCNtMcKSuT8nJ@P({erL>g}UC_C(E|R4-0u z!48>j%{p`nx=Km|;T2UoQP0NRzjuQ6-MZ)dFu=Gi{*;#^3RmL&ZZ_kIS8F@G%+trYHEi-r3FuAI=^LtFi z4L7H(f_a77@%Zz<2c*qSo4`c#S7#Woh2c2&Z@Pgsntw9Cd{quCBUalW^#jYG^%G-m zw<`wKGRH&eC0%#+S-|NjZokd~1Xr_BDB{duwpPuWDEI64?_*5r~0^I#<$ZPiQY}# zCn2&7ud8}$bv)WsTG)&3@M=GzN~ZV+thq;v#r+@Ka;u_?oyaV$9kuTYJ`{X_Jgm5M z5rC4qhfzD)gb6=vkpD4idkZl4aw@-=9cU3~e=U2w(3Ox^N40Nl(!7_G;ER$A^sDI6!oGL4d*Qx2s{4BQGaEGgXq2|74t;S};Mfw;jTS*O<*_Hal73)*;YKaN zvSCP;T1*7+YK}miel5<&yXaEzEacV({q)iB-=^v_Sa_a~8hM%Ij?88AfNXIjG{P3? zOjbchCM}0jI@4S`F?^7Vq}}tGCi`E^7~ih9v@ZW&^5hZ`#5r!xwoi8@4i)gV)}2Zn ze!N4h0mkDj{Ttg?{Rl5*wN2;kS1vm8)x6@Y-T~~z%+gprt?6_|ifgh%zS*=??Vm5e zctX}pJDJHWOTxW{wrj?ffj&Liias>}0~q?B4XwB`Y-V4o6@`PNQ<904Ol(@-x_*jW$#s1g3+#?i@-vw3m~k~ zv{H0hHo~S_iR`A7v4>nI?E_jnH%}a+&(s?KmU)u5mC z#~3#G5dKa?qvj`nKuR1LcGeFnYb7z7W*N3<(R&|qkJCpVKmR%Z*&25|y>;)s?|PgF34o_CjsPAz1dcJ5h&eJE z9ZP;Ce;_Sy|I`d$t6lg5VHLE!tn3dgDwx*{t4w88-s9{Fb0r>5BgN7Cgz0c85e5oJ zdD1+!g!_FTUZMk;aRRgnN6i*Q@#GOcpx@TYt}tW8QPZ2CtkK*_;pEkX&5LtQ`VYs| zYn7a{<5NoRQm3l1+Yq(j7?Lp;|`pfoA~ziD$J04jjPOj=Xc7q|8Ze|YWHw0bu;`44gUgL(9<61jO6rk|t^ z>;VKoX4RbVVPYdl4!}&P3GKkwjE6P)vhW26zq01J0$4 z)9OCvTD%aG3`Xg4RLYxQJC`7w=9{tSOa@MKr0=!0;UB?3{vH zL^e(_4|avEBE<%9r=^rIe=eC5NpMz`_rP2XvP7P)xIGc4ye3yPWF4MiRg2~*dR7SQ zcXubx%1-78y-H4LHiaU3W6i&y{Ro>sK@-ihueKY#sE;zrTXu<9*t5Fi?vChc}UxtkV@ zc2g+zu7TPe`7I#kM0N}bc38DEq^yvxI8TnBp<&S5J6tx>-cjjN9PDIZYEdke z2RqV<7%WStgNw~+7-7N+FFTnU9K%FLMQ2I0RsLLeqR0mwMu;F{lCp2*-i)e1gKcG1 zjdauSw8FtSnSnmFh|WJNd(7vmf9X{DUfZI~hJ`Ctk(s+sNOS*VD7#C;YE)Fl2~xo; z&7S|qLnhIrC9gn-miE*xi`aWyIJ3EIaX8UK%cYvoW^*}$B^+!iN&ZW&oL;Cahj|=i z{%AyhG;S!t15;=#1xv?Stl@n!>_LtUK#OU1)twnNLzKnYXw0kUv2CCq%0DzMrT`~u zjCZuFn)s9gdYprHjSQ;Q6SSLIv4vdl<8F+t>b6~I;P99%gTS}!LT0K=ojxeh8nLbX z_}m_XZ6^UD8qu(wb}Oimh^n?UV)Ut5Rmh{#cwQNeTHxq|4>}<-|4c=Wc&|h|Hiq|> zwcQEYo-^beLM{Y|`NuXYi2thhT$KA{T9CG2bB@qCNkQp%0 z++s|${v|CYenrTDzH5QPnSc{VZRsvCt^Z z?^La9-0|MADUGnvljpx=mO&s{9?`&sBraGLFe*MQ^_Ft==NjDhzB>f(qYsW?qqvKn07sSG=i}j z=F$H%cK|M|%e1r;Qt(^XlV30LI{0094#{|YPWX5PRBtciuWMu*j6X48c%*6>NR!35 z9Qb#S$9&)3U$Q^91yR$a6n^)kPx#;pts!(8BTesMuXi_wU@r{&6`s%=qLwG4u!hr@ zAXKrbO02gPl{2ElnD0FJ*CZ*KA8FQM-|mLZrx*Y!Zm$g(ExN-jzA6uiAcEIBklz)` z{6*USrMg&tg}?NbsCG#9y$yRFR4*p&d`vu`d9y~^J4dZuQybCGL-i>w8MwOy2gXs3gu4-vr6(k;QZgHk)Km6tQ}$*};58EyI-}<^4x( z%`D=L^Hm1Nx|vnkOrWH*;J9_}rqY&?7u(fDLAPB|puX%lbx=9uW&kJ<`40lQlGlkb znr;gX3GLwgl}`gH2#;uyExBS5S-LwpFb$`X5OQsK_X-y8YX|!yGAUYLV)ls{;+C{4 zBZ3BXLXvl;vbXYV^kAVRntrA`7&G5{{;NW+t1coMymuF!==gN&nUyU^X$r=uxOAnj zLh@~D&-mp1=Hxw~>r>pkTTw!zp#cYQyH{PeVVEVoF#sD7gN&<<8bO!u1puVVLQR6Z zwPC7HxNp1-MuPzMy0t8foGZZC=lEyMQiz$iGIBOsTr!D|$V zn*9s^Io|@zn`V}nqngLeS*tVPp>06(%V%joBoL7d9o-dzyJap< z`;#A;0u-vWq-NBm~w?sdHYO6Y`T(RI54!C_6wpYVaoQ)$uTY|32LI% zEk&?vdc{IS+u^Flc$U3_vn98(rqhPWohD;Y3xI0<_0Rs!-=iyU<=lTXBn!X$`W<|{myJ3Y)ae(q77P>?&XUzG zP`+_5Wma3{UVC8eAgSPNR5sgD#w<* z{8g*Pq_}>`3Xxp@pjlU{!kIO4O(htN8&n5TbTjq0b^C^jFF4{RmA7_-&SU~2s5fB^ zz;?OseV`2*;qoxg^SgV`9)lde@ND0DAAY{g72z+u`Pxe_RF_4tZvf}~c)GKXZF%I= z*FYU;pxs&(^WGI`VhKBZS@#!DiQrpT;0{<|yTns^ zUieUsUs6^$Fachv7{g^r;gt`b)bL6NZ|}NG6Yer)toMV70f|ObSejRy+ZsGlG=xa zg}@E57V!^}gYn3QKh_NS_H>-VX61^JLh}w-IAdj%Zps>`QWaQy<_-tJ1XaNnu9WYp z`WI*6&Hb->y(5q%+z_~>-9riqb@#A$-U`y`>2<$(i*$W9hPTe$l9?;K(SJ|l2PSK! z3NTixMsX>!1y~h+00B4Q3MKe{37E}%8g03uY^g{3Espt$P$Eey;II95t}2nq1{ z-p|3$^F(Z!(%GO5~pCI!~w3jnbjdzC6e|| z#eGX}6J;wO4Bsh!DfMy(d~2Su*c_>>Nvcg(D$~DMIi$O|S2(zMQNYHArha2nl2k7o z@*}HFP2~=pCpM2<447a6-8o>w>^y_(MTr~-wL&|s^$r_=-(0yROmcLToh8#bMj(9C zx;Ldm`8>nF`O?-Kv~M_HNo?!srE8d2i><>uh%H@i{uK#9?4`ps+QPnm5h-?WO#^1X z+HuY-{z_*p&d{R`s~U>%omGc<;q|t=cKr-t>NSvNUm5Qgq|!OpRfIH$Mp=9?l8Re3 zu#bIlD$KnfW6S0*0c^0Vh51HM&A_#bXK0hs^BT-Ug3f^z-1;_C;}?$L67j+qOc0g@e+|YR&Nz$h8aF zr{r1~9$>>q&o2LH__W>ADqwxR8gs+4|e1P%rcqfjRWfmgN?6h<2Pkq z4E|dCuw#1hZ{-zvO*qoG>PtxVr+vq!gwu~hfR%tha9{Qw+j50Ef=Oj=tnrJA(yOGX z4Ndwt*y?e))P~4M5mFZGh#9l35VFM3%U*IN+(L9hWCX218)eAELJeg}Sx>eJbP`s< zAjy=@w?tNa+b{r%kNO;v?ly2Lc`{LQtGTLHzBrRWNhZeZtn!_w9CgMXDk!-*JaCPdEd#ez9$flmxLsG!-47`R=m zFDf-cg)N4xB4j`og|-CFc1OC&BK7HJ6fo*!P0M(c&+Aqhdl z9<$%P2I|2N$X&s?YtNHVz<~)ARTgyOkQv{4lNqa_j*xwUUXe)+9goROiA{lZh`Ukk3Y`{( zjHp0mVtJb?G8u5vwD(_m9|o}k^r?wS%Ks@!6LDK&#kQpQiv5SA1|k)r3Z zj|9={YmM*uV?3}hzB7t5CB(?-^2Zqb)AfA_F7*lLo@_1$3}4R`Og7M5biM_1OZJjjVg3>?23ISH&3%$@k=th-og#phqOo=ey7vTSq^n(v^awE zY`fclsI5B5CuTW!UtoUMrbVwSk4lQ6wC(~+a5q+%`yk^fpX&2nG`Q_4Za9tZGv;5hitK(6w zek-_s-K55WmcwW&P4S8BUHtA5_&oN2Vj{ag?mbO4VoNe-X|KM>p<~FWToW9K$YBvs;%FaWkhD6zs4O)rqxBT;>Kcf@+b*3D}7Jg>j9`N3ZnVX z^2OjLEuK@*yd6xa;b&K~h1i5MxB{Cc-qpr;Wp-M3yx$U~nQgSRMK%~lj)fsNh^80U z+~lf$Zbd;@=2$t`VZIGk&JPako(Al+*KAC}5_TBA^;&09F~RCx5>clOaitmTS_Vqh zZqoe{&EVQ*ie$Dv;nrnf=fHgwc$yC(ZC?jp*f&RP2>zRfUXre@oJc%|_&m;3U% zlerG%PDSsbFeqg7?`iPDXd1AIa{bH(;)PV-6!=Q-W$ z+3RzfbfhfX$+9oxBAWF16_b5ZDyp$rnQZ#~erXq~Zs34VS`amkDw>znIsSQG{Z}GX zxWn?+YqO>s*{D@3qgwF=AHC4TaNu1|gcI}1Y;?thIYW@g&_tb=Z=mV7PFnVg-;U6z zbtKP!MRFdLuCN%U9&*ix%XGpt2N90lsT=r)ikjlSVU@%;+}(P^5qkO;7}k&jf-Z0) zl%}NY115*xNi?k;W4#D5Adv{j)Z?~62iocm%(t-FQF6zjbxT1-@_rydJ4S7`mR$PzNc=Y@xm(?P! z4cay(GnGcp$t5P7RN~oB)$AcgVn>{yUsx8je?$tVK@K0fT^RsCsFnQzXAC@Z4!*$p z)hY_sBPhOOgHN)G57dFlFawq>A0~LnKwSL>S^hXxTJw*%Zw@KKn#duB$OM5}lSuyD zn;-(NM=!nATH5#Kt}9HfzEu)H#3l@==KNZ$7CE;fckap$0p;qVD>k-#2={fMKabmn zl*1Nyk^`~1EE9ys?sJK;$*wK@4H)Jc=*zB1e(be41Pjv|wz5cc|8d*!SE}ij(*kTH zjBtc}6A~quZhcuADzwYu$@#*_fByNWP<_hp36483_}wl38aDKb>Jniv@%9O*G(XAz z#u7}j@XwWc?BLue&sZt(xz__3p*OM#u7Uh8XF_q9@+VvAN2>C54k^cU%RMK;hE#PU z`A=P3kA$hbZYOx|OUr}JJGP!sXYcT&IU_6}1#Q&`y$E#zbBWk{n`IgHYL~uv2lp@dZ?EL&$O}JC++0~S z(2!6U)0k;w{@G95U6;@Y4|L*{wfT2-LaKW`ZM>Faf)Oi&NtCFpSg1nw@$@FOjKUlt zD?g-waYQb)j4hFna&Z&%z?mXnBDGSt;TZWh+~kD(q2^K({+yXCEK?MCo19}WvLrpM zj{I)0?LHn|1#jNV%Oe4K{5o5CNh)}e@XKjrWMQVwzwIc0oY^22GUBUq)5V>W-@l@U zUeoSIb8y@xOy`~>Q|gYOvngNj+AI>XnI%y5bZ>uu0rz-pYpjz`U&=jOsDR{{K%3-C zATevYb#=YBy?V6)|947(6LuO@M?|&E64jeeV>Di9>djIm=KHbxluI|bv8P37<+&)! z^swYR+M@6p+A#N)&A%`)2)cfmvekjN+NM*bOhreSw}Kh9lWVuLpz2UUfq5zQIL3?f zobHeZ-yeCy=b=b8ggL)MwFP$5Q{3^#sDqzZw;OkhKfVj5Ql828F}3HBzb=aJ#iLO$ zB27h$No7U)&OENUiB?H=mrB)s3cOFDnzP|t`EiXh)`Tj{@cAxPyTGl=&O}a@@e&`t zNyxIrX#j4){7JxJ$nCGPy{I2> z+Z$Na)TrUq0qd561VJLDVx_~VqqB+d;tZRZ-lwChLov$-$e4LbfWLSrEK$T%Eq2nH zKEr!kFFe__&1x7hTZZ<&yc?X;>fMSDn^gfhjR-sZXf<;43P*mch@&=w3XOvUe%wFY^QW}^IsJo&PtML>-g!hD8g=C<;hmQcUZ$AX zl%+qYwoZSrk4JNw|9v?xdFAwpMH=-ATMeD;((pikmKXB}@=eI~eykzRFaGqgcgD@< z6hBq++cEFL4DT{C!jJsEhvZ2nMSfa{j$)qK=bBK*-o_N8)T&TvP6IVoJ{YoY3eIZx zvS*-N0Yg=SZ1WtOWFG9_N14X$OX~n#$0T9l&bC5-p^ok=>8`z3Y$KOfN1i!i;_guv zc&5M1awuB0XPdU1Z-&*FD*v$kRjy{hc;eT>9j%~wfMM0;O$ASMi?^{%tUs=0Vb*Io z$?=zbP37;Hs>iM2=ibBwOJ|!{X)K}IFiaDYwNH4r`%uAS8ZN-iC?h_Fsu#(Dsa-zv ze*SNDaqBw>mG~4ee1xAG3>{y;Ywp&Y$R5F`>ZFjv~ za!{FAOcXWHjKD0n{4QrP=z+Ddk2DLZ{MTN?P}7Xp!XZN6b^QzXkRZWJL8i~6p%5vs zh^gE}PAbrZCL&aoh@V+g>3OGmbA=XbovAoCe-V2@+n6m(Vox`qV9xYS(jRGk zXUH62crV+esAc4f(QOKEZgW$bJzJg~SyQot^w?A@=4CnjiBw$#%6g3$Cs2RAR*@KO zLLirC#}CgQ?S8g>*+n9+6^6^ZFD(?a=mQMI!an>4o}TxmIX>U#Hwrqk&d9J)BDT_= z502B1<@DJB{fU9r{@vF1A02|Q6|_Me$SCzfx>R!|oa2MzvvbV$@hdKNfHXPWcpMO< zsorX2ObCw6e9m>OWWx<0@HyrV0Bc%L+quyuRDoNQv$1{|h!WonBI6U3!}O;{UDvSu zr-H6&CTxn9+fMDs<3H-X`}>K z+B*gh?b%V7yvToT$i!&++1Vs&?qe|-AvyzaW7nT-@#4jK}q z4A)B89lI$IGkU(%qVTAbu97O#Sb9!jhe|~%>G;>Op&Qn@Rww;dz@VGi2<)V!q{bM$ zsmIE$ntF>xK@v?S4H?B>5Vd~gU{|V`1YbLZ_}h>+LMrmF(M1es&IM!lUvt!`06UGU z_V}q{c}VbFKL%dFKU;iB1)iY!^Up!%w8;5e6g!&Fwx&_cTi=Bvoz(aE?;_pv zEEbXvl#MLGbx*KMXb)s1f*W;Qce>Iqk8+~CLTkw;vf1JJbRy%;2Xsz#0%DIKmkp%= zJ_tVHr_?eVa1gK_&E zu1$45BAgW(NxH15;T*w>Rcg7_WCtLD*9kCHl&TZ*V=T#`9b$41*mW}8ab}+I} zuHD5uW05jPk-sH93j4xbt|GHI4lS1GCgHDC#h|vScW~3A`QUgj9u7PBgxf}wn229K z%f)6Fkxcl+P^)i79yC|Ehd{WR18KYeFtp%`rZ%;6`ybJIzglCL094Nz&@||V1fPPQ zvH52q&LO~6j{l$;^mhrNP4d`_Nh%1LR3V#79z$Io!bE@Rj;t(4y3fbT&%NU#?1X}l zC)-sI zdbiplMNx9s8+2beyItVvg!!%1y8$%n0JII%*qC-tDPc9RhnKB$6#r(g8=z#SI6mWI zv!PU&qxRGRY-_)qA zUyb+PJokmi7}E+;Z518ibO%f-jV(XosY<|E&wXio(AlDRdEl=Qqotj54VeZEtBC1* zz-p0X`@)3)Z<`aJ>Y8+u#n*NgH0LDRE;kH~qUIC>8&zd1dQ8>tP6-E7t_COEx1^{g zSPel2#HnLy^J4^zdghf%&S3(>_cS4Q6jZmSS#cV%s~d3J>0X_N8x!kT;6qPa(cWxh zG4I%=ybRdibv7`0QB z=0_Uk)*hh3D_C5%b8MJ&vH4U~otRfy$4g{-%OlNrN;Dmsen z-7t)(4a6Qbf5%R1tvlU-$SWG`hVZ&3FOk+R2&*VPcQK5H_F_}m`Pd}QENEW71Kgal z60Unyn4{!frcdlD=dH+UM5f&{CR#>J9+^+>5;%V-*QN2%H1D;Hk2|BK<}JFcCOCK3 zMUG$l7U(y<9}wIfG*<>4oCD&Z+*{YUqBAl{S*Obyp(jnuT=dRwU0Dk=1?a45oZg)p zZzRZ=BZ7aX?6B{A0bYCfmI33W4`99@fIyADfX=pIWEllv*`Y$fiB5X<>EshmogX0# z05blV-$-R>bnzx~30&6V`s$#Rg>H6>GITka#RdxOvF9G;Vg{8 zGmjVczi~V5#x*n>%t7(F@P8Ws1!DO*KgBGm7S6?w19o6}4x50p=IvAkCu?uFinJ!v z+`7F_vK9Q{C;~2MCyim=S~|xxrFaPd9_gT~71EBd2^2c&`pfw#h6-X;o@T%9vf&E5 z5?T{^;aTz-&^k6NK0dm!Z&iZ;)7z0l;r)mhzN61=(;WN%BpizEt2nabdcD6x;5}`v zj%?h==m+iwv76D0WI-xT6KbxV`J@4=kI&kyF=L+OgC!qNb|0{n$)edNF3by}1=+@< z(}$o-`3t*QEh_Vq1|HN=M)wSDh}(3&|8k(^+P0odhp!43wwGG0+?9LiNnJuf>*bvm z%wFqqui-D+%XaZSHtIeJ%bMVEz5D) zlQ@HEd_!eAv6coS@{jE1f`#V(bFuHcoi|&=2y$#KS4#&$ez`HGOCdkii}(E!Jfl&7 zXjEF2S)+zGg@awq&FBgO$91-=cxwE|D13Q_4L%{$nb&m`jkuJ9sB$%`gkY$UiCG*G zEDDQC=6rBYj|{V<+cm?p+jg6qDn%{7Zn~^)JbbMN>6z(7=BhR9)~(86M~6fh=jKO; zq!$8nI69W~oZ+ow9`eQ}6D@64{vv;*UxG*V%GTTZT+VeIX9l%Rj({Xe6S@VrYps!1 zG(ib^ztwN+35PU$MyZt@*?zG77;%a|tbk8?A8^r0nldQ%6>ujpjG(u}mid^+&rqR; zZ2-UbGrzVAIiw~()M(KL$be{mOR*oQz!mZywi{-9OyIp{4zBlIqD7SN^m!V1&B&+2}#0lLMe5lC@+fc?K8#6 zO**oRfTTHa_81*dk*qOGT3HNAD~H#wOs6#CK6%ysH=$pOji$=4+U?;CY%C)4aeo$s zP;A2FW(uuEsGec<5KZ)Z(E0hphpZLqbhFudy!A|_F0F%GO3F3@?)YLd33&LWOfFUFNIo~M)3^3tdD3e;$q zNDfd%6h_Jy-5?Yp?-fx;Hl6I>KTmjQZVyDC`e-C;CqFVfpaB#?t%;u=li`CNBpD2qmId+uk#P1{} zS61GngBlQRqQ0ZL_Tkxu>XCvr>K+G8R%9ew%X*$p)G5tuF^7beV`-170j%_Q1ks43 zfcSKg@gLH2X{bY2E-_7YBeq zcRHxLt7%BdcRxAatw7F)d&ls0HXH^>fi!#s(-qs+H5h0SUS>((DSpWguwC4T+&EBa z>G9TFMKgg7FU(*^VBediMZNL6nilo=dnf1L|HBWr-~Wpr{qVETKE3nn-JTY;`WN@K zwGKz~g7)x>uRkLSeuTVIAE1JV(vYyR9klG$@yFN?l`8U>+nD47BXvm1as*Y{Xx0eP zun$Rh$CUdZ+~EyOFbZ3c1{fX)6mL}GD@q3*@Rd{yD+%G5+>d`MHfe#}e zKcSfw|ASJRx89O7Cbmeh604txR4l5FX|l`)B;Dh$_`nolW)EHhnRWx%ir2Pu5vC_S zs!DNYdMD?H&VkrYNv!xuZ9lYBQYa)#mb=XbmN;XaNK;x+stecU3G z#1IJ*?)y|!2UFl5z3J86m`-#8gGg$Ayi#>?cKo#BX_MC<@=6sAlVY0qhJdF$KhsZf zEX>%8hYvxdF30oMZRfZ4!gXsg&<=4f)CbL`-U<$j(GvscVY-X#L#ua4&Pa9=Uy^&C zVE<~P^++!d!Ww*{;2!2)`q#UV_L6<*CgrwM%o;s1upe&MJu#iO%vFA&ozLM#32?J( z3c5Uka^a*o(72i@Yp8F+VK`^PYOZbn=+oMcS*g^ofA)76R(ujR*6mQsQ52LEVlH?j z!pLd)8HhB_E?SCju|Y3C|2HrDqP)632cDr2z|2nU9$pHt@6wetFBVwn?v;Ty`Q~22 z%8o&=Mm&=jkZas91eHoIzHJ$Rg?UPR@pMKFpLbCTSFkjrh>UvnEJ>{UXNHY{i=km+i-cJ}wq zpZ_~^#ULS4Q)1we9g5*a$97d1tGlJ+ro~Jn#CPXixAMC|xZW&S& zjShFu+O$J*s*TkIz4e!_PN%x}A&goG`|=sp)0a<5>WtUr{*z=+Wc)&P|-g4j*x8RTpTPV;@IwHd;O=sj|AJ8CpfyWL-z@^`vPJpw!1Qw zIMx74zPTUzaD$QEXR`@GDYW}glvqNu0(#UNPgHpyk9c5=?I;#XqQg~^8t(<+h^}pU z0Y0yXwNH!iq<+Fzwshu0<(<6cMGfgG*gT=zh?ST(JG(F%dsqf#Gt^>xMCvCis;gFS zW>mmc^Bq>-UW*)hV#CorK3TA=zMDphx=Cf)b2-I=X3fGob6xbFkIHtRm{;n&VTR0* zYq>*ASuWScB@1}eBjPh_3f`Q$Oh%^GW@Akkq`hb@$_x0dMh&z!6o^V#Ezaz=!cT18_bujHG&Fp|1CO8kPz7Yck3wMriKIR zfGjkWj}PK^-s&k!=DjSKQ=){|HfYExoU%C4P;oJ6C*|vMXU}}r+IfN*e)cjBrWjrI zhtb#b?RxN;IT{Lq`;sn1lti=YXU2TF$_^TuJMs%s+NnRl`GP6l)SS5d% z$jIXhsi8(}YOWd_ZAz&64&jpc*nsk09Gfx>l|4JM>~&>JU_?B$sd_VsgNYp58`LZ=fa&Xo#uDI~{WqV(O~l znv|sS@e|QM*Px_^KX?6e6(#XT-#*hn*P^7miP;di!al-z*hoNMx#2J~6C#V&M3G_# z8&DijaY`yd1qUHZq*00*phaX-GA9DXBsP&6%8P`S+rPYF6oOUH28ikx`XeDaUy51tegeUo5%6iGBJn3W>$uP6m+-uZY<4LS0?$AUml$b-(<3ZU@~aN|wd5X)nA-;v!ESN^kY7%4gRico z&#NXsJ&~aXHyKRG!k}}}q?8~~>R~0Li7*#>^bVSw`b!jDF9}Z+%TWy+`!bZ@EbQGu zwg#|>&fVt{%v)T*S!hD@-^^is{!7Y;{59y4Giudsm!0S^yM6x4KTwWs){GY>=NgbI zc33(Wm%uS~#!j!nF{{Un!BuBWfcB@|bM%HM$5gOq3QVHhh56I?QGqO3c z+e7i!NL|y4dboW*em1eWNpV$*8&Zh4f;%fmB9~w(L(bYIy^L)sKztT9#h9&Zq(N~D zXuJV@O@6d7*8=!fe80^Ux9ZCdT*3ajRr=+^6Qdx{se1orQL%`|oZH02QPQ|<>M$JL z&;4THz8xp<;Xbl^cdLex5p@6u@>^Rw!hE5i`8hp1r%PzL=Cy&G=l$`%1l(~+(U+Rz zP6^SDlLTp8pKjkhA=Ohb9GYR9y;@gIHz(T`dS>C{K^+%We0Y77C+@2q14Aa=Cq@+!Md>Mbl3ld$SA_N8CIK#ZmJK)+Aobom5QB z(wP@sjmQk`35+mp>=^=N&}`5m!zr`sJNPbg{N+4C^xiy;k-m8M?RT8;+d4oA+kH=S z`qmCv&aZ6!ix&y=C4;|ft2nB;Fc{?w*Y(B>yh2N}B}dLWVKSGd>Q-xjJ*nQRa!#1* zmO|T@;B-AE$hTiF9w&a3B1dG`%*0p;9`TT-e}B`~x7yfEFz&nT1%(Di`_A{0aIieU zq3uezM1-!~rPi=10-vqZl-9v8Y$Op^Z(=$tw<}4sf;Mc6b9(k-QrZF2O(YIl*ip5+ zBP9Ia+!nLTEhUdQOxx;?a%sp{e~q~)U%R$$(^k7ri``D!AwkO8?0)Yl@}I1wv@>yt zZgVf-?I$Oza7Bbiv{`AlJRFV7=bw`ae}aY`(IuL5*EKU=*2!(~ggUvx_S*-~3 z=Jvs$*GX$JRk^p>cfYaK=DT!TRhzDKSb0Q>Hl5EpE7bOp-b127^`Hxe;en|E`|TzZ zkebgF`C}Aewz8rXo=1<5#tnJAI)MaAT^epfEKJhH0XGsb`NC!ylf*NKxSw#_&x}=o??jz@!JSmFMmP!3IMbS|}X;o`##Z=3qZP?STXX+SyNDN;7ILl#I z-SDz|`*EAzCxJKjlsiA1L7<6TfomxPPpQlJPfF!C(0)_6emyO?Rv@4x)FzZNY4@+u z`zJHauv`uoS%1NGQ_EPX48W!g7I?GH#B+i^blKyPv8P&`y&)QOGj5?mFP6F?P4x+N zRjtAgx|!r1Ka@9>vmx8b_iKSXF|Q*jZB}A&63H=@DH)PFZ65Na4!FoN?I_qK{JDs8 zESS?5Z{W{0?T;pR&a-ymcbVF{ZI`Wa-&*EmB{n;jU!Ive$lq98EBUOF;|FX>-Ecg+ z$)ly)rVbt!Yx1`h#s_zc0pTxFo_`l|PMW+Q1MwhX2J=2S!MZld5afxTn$8=mLajw| zF%1IAVC3o8HfDjxVArHaGHH0mQwuxl&egKExWYHViedE~ae=|XVe*srwtos{c(PBn zausGd=I%PnY6hnx*JN)c}VRRqhwEj{}E7NYHJRYj1b%$9{q+4$zxfy6J2?96-IGth`+xq=qxfaz zFK%fSzq~g}{`uY4U;h%EVpb0s1pjoq!`iHED$w&_k!wB+Mk@X{JKHVSt|#TNW8n_g5An&+Yq5$4JqWXI*@psh0hhP9xc(2WW~ z>zKRzmN)>1v&k~l`ECKCq=nd*WN9zIh30gwbV*W(1ACA(>oM^Qo{NodBz8>3o=q#f4VE zrx4mTt3BsDe7#c7lqAP|)`7md&Qp_y&bp~uo-mTe4zT#sEMfeYNGCn+su_ z`A#eqB=V+O7}Dpr5BS@o>Uz9?RR6wL?cAUBpRd*Pxb;#v#CX+Oq{;%TfHj% zwB6`vJ-g*0XHz104<3#Z7yODR;Rd+-2oDy70Ny~iRMAtt*mjqC)xrl>pj1h+hNec- z0hfg(nygjhuP~Z17WqBK&hEkb$2V5SOif?d23iO0Kdgc4jg-N$gcg~n-7qlPs->aL z5&$d@Xp^YT#Ptq8cqYX=R1G}deyoye%k3J&_TMMxN0^w%j2Mr$1Q@L* z`~Hn8nCKGTX2F~9s@6&<7yfNoGi^fUt7y-o^JBo2^_DepQb9?m*o)$;J_LLp&30fX zvo@zdW`LP}uG6$2o^oZ1t~mfVqJHr`8$2;mo>W4 zy=c>HZ+5bYL-#6|(l~0F>+WyaCS6o}9l=q1c^BIk?nc>rx;|~hW&1H{vc4--?!X~8 zd<6$xn41`6(C(>MnJ6ONf!SgyoJTaFU;$W99C@n#(0v+2I4XcDJP2!KQ%>*B#(BZe_4h>W;y!OCg?<89k{q&l0LHH7V=bIruy^LU0*V%pPT zrzsd`hmSm{^5%50aZI&6FwxgtPPRtiAHMpRCO`@GvCZ?~u_WsN{}i{Ge=k#m|D_^2 zsHTPKExMIY#Dq2gXTUvQG7k7gz z(#ZaR%6K_eKD1CYFRqb}O(WyLGruE_W_D{DHLR>^2Hi*%#!P!-$JmK;~5-xG}lsGDQ>U7az3Rv4dNCBkh zdEo>*QaAFs7AW<{C)%e{TE7agg`~Kfp1h*4WwP{|yep&AuSB5sE(lnx|9X44 zH^JqN^$61@?1`Srm~}aDLjsKjyh(ET`f6-5BhV!xJFG~}wOKi4yWr$5V&datqwl;y z1u#fzc^6VdRV6CE;b8%zW z%c#+VSad^=(u8K{jKsBCQp~*lJI4OXnRKLcXCc$>G(L~+X>oE zRgC5N&sJ;!1eJ)GoosEGr6C|6!$UFiT2ZVl{W)sNOq&XqnSWGrNykwM3(@63FTb|W zX>n?=LpaMS*p;pBEA@H4K5~vBy%m=Qn!aYhvuO##i=)l%Z=f5NJ+MSbmK}d)Iv|Hp zyR*Wxlaq>|*Nj3H;JvCGBE9TgtL^;<)ia@8OzznXj(`QKP%=KHMqOie7}&M05Z8j? zoml620Wd#L=pskiqK6Tz3lPddQwI*`($X2Q8EJvkI*RsL`Si8<)Q4y1*_m{ccK!~T z&bZp8PWeykMONpqk`zz4h+AKL=KcL2heO{w(M_+x*k`$(UGEOK?Z_x^)>sW1*v7Kr z>7tk~R%6cCW}IouY~o!l@-)vH65V{FK;|WXSw_P@Bc(zUzd3z=Xwt{u?xN%p6WpVe{7Od?7VTvpR(JKg8@73gMp_FnSj>mRHWBgGmHx-8@=G)a&2=!!(zO zL(g5U#J5XSyarf&5~LEoT%ogEm*ZU0fvNiGvPq2#PUzPu^3?8<0X4C!?{%FD*Rz34 z6kV%+1;^sk-F%!y(>kv6{_qp`$@W)(2N*~8P?R8eO*2K~G-1_4txlGhq^0G-| zeb_ABt$Dtc_uNdhi6)xa{>@ddugkw=cTIW|JE1nP8E8(ad4B4Im}bn1eA$A_fLn6g zEEx;&CgLYUi`_b7$Ik7z3+INOB-IK<4oE-t%DGqD~5-RvM#imeb}r5ztAnbnHaptD)4cRzf7FVw8xM(j<}(X zn2!KKZ88(f!BzTPLWRW1<7wh*ymPX>r`+Zs95iA|nbzg>CziPEPTD9@>C`_@yc!}} zh^7y!$ejXlKcaZza#HV1nY)m0Y!FU9zUC|>zw81NE*mvvHxaL(xtuO`T~-66z$UGo z5>zou+Zv7Om><{GvzR_z-#$Itc%_>}*Xji`I?ESUI5T~HcW2AiOkNWR+!}98+XCkC z8GhG7W+Y_WFkRNLw?C?xP!}Kz=?-;82vb#kdWEWu(@?(BKHFchCI6O&=6P+qK3I|v zdDtMy76@E9CQJ0!z3sNX@8nDVW_7!h3exu5{y9GCUUnYzDF42<%h6|qQ6>}`ff)}{i$cM4u;&$4$nQx8g0!+yWF8Zy5q(y)w{8P zt&hm|ie_(pY?cmJme$>Pp0}IURXf`(FSeG=duXDn3ZvS-^0!6?v+MS1dn%DEP!kmH z*7qdX;WsQ53dU5=Rm18I_LZZkc#Dw90KA)!Zhg&Tj_Xp+qvC-bzsrErU#Zw`A6Pgqo1|4YO?-Yrwl>n$E`geAG0m30 zb9|1_f7vE@kV(1m72wO4FBkozSM{}Rk4fmS8l+v!VST)@#DU&Bkm{gZjsExx7l16) z`y^gotV;Qn6_t1=_cnV|_QDaery)m~*zG8qF=ASZ3FvY?ul5x7b+83LCU)zsMS zDX|TjTBoDqI`cbL-4NFU!;&aiJYDYC*^22@bn)vK-*ux&O{*UW?kVi#eGa z636JDuW#WZm_ZL^Yj#wk=_K})Muh0aB3cmYXne8(nLi@3O*fO$aCw~72ecx0{fqC^7C z=oL?$GtJYiC_6zcY%D>y$7-M;>`E$Ur!hB$pA{cd!jCnWq@JJmdsX`wiMlELkV#9* zUnjMqurdM5wMoizk(mOd3JyDcvAAl#;>1E%^bwv3wZdIfq8Oi@ga%~MDV|;SIg$*c z*@SeUUHj;ArKdVWIyQHl8zk{Z%LFbsgS-)cW5Yp|RDKyuDB2 zQef@uW5Q!zwl#y?@$cD1t@m;>man^;{?JXx;hsrQww>Ddt_|a7EQDMjCQ>Rj3t-k$ ze#QP#vJ7+@E=j> zT%Mr2F%qQNr;IcVc?hn^VPhh?>U0`Q#)viRgvr?bY6_l4+=wAEmq;#P32xgAitQ9p zw~`S?D+1~Fk@a8XyYz+EElVDI3?DSohCAZsYj#`!6!UjrRt{X-Hiur7yYL^~VZ2-c z?AMvs?mBR2LTK+P$R3Mw$J-3jva%Tks1Yr+1Y-}C@JNLLm+aY=WPpYz@ zP1z{H_-wYu!#Fa;gu{#U+9TOt!WS(PWA5}_fNL(vi^#ak^hQvn@Qdv-n@8$BZ^mM< zbAK1zv>;|1*(%;%Ox%$G?-;??;8Xxi_{TQQ$_u?!db&VlZEoU;{r3!Mz_D@ZVaY!J zT{&M={{##zv8w>3ePRFDHtwA&Y_YMol)dgm%M~)VdE)9@Rui*t6+s6)XdW=%#@@x> zj>)XD4?R^v7Ppy!ERgP%;XHR(rX2ft42D$q;|;hjgqgnV?G8Ho^~ptK6=DH2fjra6 z1TAk=aPZos-dol1J+7hiw5 zL20Q7&&?Mb#@0OnL&4D1c*wN`*d*W|@&;t2Hicfjor%l)NSlCViRB|h$YqEId(h(h zrM(guh*bdj86@DzAR_HY-iKzF^B>ziT@0-$bX-He5eKmscEKeBxeF$(UXO)UqU4j@ zH$%J@jq6Ln#W8jdw+YY|CqCFsMP_ zfym(?To0V*@q>Nt^<+}QI|}Rb6C5i!)~8@HQ#08^+D{|i>+**7VwH5us6d?Xs{4K? z2JTE6a%~qWcaV%-s%byEfA*|VlNcAQ%%8sMRB5%E4T0Ihqiu?R`Q&d)%Jfqy*pyM~$42{`L*Y(c=o_#rymKGawIq{Ux`Tmj*}+W)ts2bimLrbr3xJwE^AMKxi@vd0~jw_kD*O6UfD(#_HEU`#a(d*ymHO zkG9d{12PEnC?P0Kib$!MF7L#4yB9d$iO&_wv9bBC( zvb_Zba`3^lXo<^FhB_lCoJIuq(%kY&e6$9)Ym~b6U3c76i%Z>y@}jjgyBE|K^54Jy zzyFv2`ZvF4`czM$;;CB7#@zRAqA?>sU+%xgXZJ^7%T~OkAQ&t0VRsl3N4IPzh`+KZ zwHzt}9pJ;kr%ap1aweP=FC|&hed-s@xuFX}=ap~(i{Zdn+Kt+X)i;kVzzT550sk3F zw@{EgSv$##glK19mJMg=XOI8vs`P64P=&dKIVAqR1_0CYoJ|CTuA??&Bw5p7z)HMi=mx-gije0O($xkU<&RfyX!jSYny znf*~x9I}?eZ6g&G21S-xOIBKF!0P-rfW6mW57Pmr2t+lsYsnIzgg|&LF(dLav&Zhn zUd5(QE>Lz^FS0JfZU%Vc^{y2Zhs8S3gL-baptcRrm=-TA)~`xylPiPUn*X%VW3zk< zV)K5$1O}8ut@}=uHST@l6SHm(3a7XYysLs5VZBRPqQmHoBLnKK&Oeh26iB=No3Su4Jub}k>@=!2G+bs~AoTZEP z3Mx@R$X@KstG;VBm_p!?sLnK{Gt{YF#^K2z`c{6)*T%cr^Ag%D&EDfLlSaE=4Sczc zxN>)Q_D__Y$;GZ6dZ$<0AVar>vxPuJYR+~6Pdti;_@~v}!u}Zif^TrG;W1WW9y|=b zR~72(wwP-yw-CX&z4H^Q7<7WPs&ie+JZb`e^_0 z3vd3_3lDa=eD2`vg*RXQ>y&lwQHA$c{PSN~)91gb>^#~1Apit6ySx0g=_n^>^WXjTU;mST`VH&G>K>ql)pBtZ@hehZXa)okG|jE-E%*9hz3 z0emqxJ!c4Bjln65;^J>EP+;zDP!9uqYZZQzbbHwN|kRwG) zr-dT$j|kFm82C1a!s}b^801~{H$>jwC&rDK;pLBT61bl7m8}NLcQJk+8<20AvY%|s z%GnS~)IL8Y<1gs^WQ9j$rBi%9J^+5v<=NKBe_fPfiwOb2U13WEKKaVTiSF~C5^K)4 zyfDp(D4Rq|TNf1<=_9y8lec6ZN&phxH*iU_*WE8d@bDGhHR*@QY2a@_;78obP&jh- z$L)UrCn^Lxi$ zzS|o-PX1}=r!(RXYIKStxi_>UV^++%%K+k&24ZOY!?gh@wTDfLs+A}1YW*i9dlV;` z>Vke}=(Ww5V1EgscoQgST_JyZRP7TmAnJ$SKVkghS`8HTc8|&E+qvu((br$SZU+Sd zqQ>~tSDXaXns-j%CJcU~n!BiT!W`Nosfr6^e;iu^(_es%aDLN@xehV zkg2v#;IrAaklnxBfa=94#C{AfL*!Wleq*TxsKMMVJX~m-sm_hahQZwo`a3=cjE0P9 zD7%jOVHT0@2O%8*bVHr1kt1$?AUsElEar*mJlw`8J=sT{RQS6Yh_?z1JU*FS8_MCR z$p++iCqNVE%)sJ$m`_Gm#e=~xjO zVSDH+wp)3vJn1M#V_>Zl`A>hHSyaTB$8UMWSWvKVdw*d?ThrB$9Xy(eZF8%>>|%Jy z%l#?HZLC^xwz}T_Xd~LT>aMP!0i+cotgYFnFIjfC2x`G0a*$tD!ctXj%qQcqapEy; zDp9rtyQxva8gdv_B3&ETUm{4A5?UV|VuO)AZ|97*k4KK5C>99` zVIxh*bm!B%^9g@pFs^B=B>AH8`Vu@m>6!nIleuydoEmn!q{+A{9AN?DnvJ^9Ry{w< z;GLx96qGB!*{$H@kN)%Do$Ms?d+TZN~vExJHt7V9d#>tWECF}HL z8kc=k{THD>r~`wfIzR@-TE}6sr+6w2iV;qMmV8AL5;&u3W30WVzHYiM+6>n`iyam! zlNS&|vLorax+TUNBPS_zYvvActF+lb_Tt7q;zIctnwB zgAt5Y*QZlK3lE%BqVY;_;5P>I&9Ln;6AqqzjL%O_R+fxUQ&sT@QEtHG@9df3sSPA(=jM%YJ_P3wht_nQX)AqV(Jq5bY!H% zbxG6#t5jMnzKKLDqdp2@C29HE^aUBMx$Fj5G&4KsLIJJRGaV%fMQ?6 z-Ghq=)e&WYUR#zrYSKH9Rshn^JB#?hkPd$H;^){GanBBLs~ z-gseF5{+I7_E6pHO^rqaFlN=w%&e}U`E`K|bzDjIi>_Hn?0hNCav-J~%4C$-bhqp^ z=ssIv?bgjKg&PRvtOrZsA517WpCmMIC02Z8GIe8O4(W^#)&VJNs9hm9?1$I@8V}i? zo7oQzxhc(Kn=Pv0LN{^lXLnLG`p)|`U@s-{?yp-w;)rXI_*|wtWRqB5l6Zj-lUR4u zb1Sa;A|vR`F(e7McSPy#kXRW8$7IncMROf{dqk+YTx@4E z_p)d1;oRZw{y<$c)dpSfUOLXUV(yNr+97>YWU7`V1}A4rh8|9+K6cQxYLORoCU&0K zMbD$+-|1?+dcZwxz^~lkIxHXORa44|HfA#zv+it&j-2U4iJZeAFkTnBvZR;QX5BApZC@5jcx&jHx~^aH9-F}O>QKL3xS2d8^iaXYLZorsvTiHZ4=@0w=% zJ^#me`(0qFn%eD0C~i@#{)_+evtLmxDF=+n?Uz{LhfjP77c@r6FMcb+HfBS0Z z!n%M%&YpE~-zIrP%f3L^$5{HtMQQiT!r(GnS0#HK>)ei)oQw--3uzx<_xvS39jJ%d z9Bi4O0*LYl?_1;UzL!kINo|8t#F`WmEG;wN56<@S8&2sW`U|o)_;2c1QHUNpN6^OA z^o0UL)}Z4caPJVML`}x^1ja5824U2anD6@z2{P#IT69B!5B66dERM2_W ziQuC?wo!enyz>pc|Bo+hX^$uS0UGpgM8OtR8cd5^w3k2J&E4sh z9T}1_I+@}?Hqc!ra`5~Ydwte?S0{?BdMK0aPK6QsM$J2pd*-qfWhr&b5q%t3ZO6YkM~>YyZqTtlD# zd%;ECp$Ul)gbvQE<(Z-ZHsIj;9@{|fM=QcBHkpV?`n}`N4vwpvM_=~#1L7>F27gk1 zrJjnnZJS_i5TECb{+gIiU(RVds3`-qM}O+S4|*CZlLiLYL!3 zPObQ2Um-#6V|fbb1Yh#1HiB0Xo7GFr(Vp-jKPZbK!dS6sE7b<7$cU_#<8$8GKS4;} z>L$fl!bG#(iQq^--=rW5D{Gd~?a~}H7Xy{|iHHW_h@f-;k!fAtP`_~+03II3H0`NI zuFHd?XNQkTkLouGAcCObHh>SY6X`~{OE>vvZZqc}u^gdzO4T5EdM)zTKl@)5%JhQb zI$Ki%`aApg{bMUK1L^wU{Wk8cRs-DapL%X6Wa{& zjA4uRDOE$HEovjlDk_u^^NIRZhR-=7Q>Kc-+8gy+S4qq?H-u#~TisBiK10g#FbM2_ z;0j|>K@{1kNO+2crMyyZT<3~qF&+O4p zEVZI1?H$NESVW0AyKb0$*wC5hjrg~N{Tm%G(0}q`m&Hu3_NolyQ|P%T ze<0$26=nYDoKG?bQYe!B(7wo&2tSyJ={dR_O{e5!3^X971BoIcs1xk~PLo*Kd(a|| zkx6Wwnm8#~L$SeqHv55g**b~8_3QCTBxXyyfuwLXu{>y>)v3FOBBLEWBx#mhJQDaY z=QIu=Z^tX1}g@OS4sXA3(IYa&7dj z))WP#tTl9%_&N~F2G!OQ!?~TVe}gFC2%;o0EBNQIJ+s!F1HJqqaQUx&3MEl0ptFoUUr9|c9KsLkX1-btVUjWJsW#s7#~p^<*7yWD)}_^v3ScG z?90jmKYZV4Fg0bhXq-gSEX$D4bmT;^lSp$Tbu+)6ifZK(jQWI$Yw(l!1*~F{HJ*P- z`(zX}CdGC*L)M&aBW+4Hn@5XwC-oi1eJU<%{}sM&{eE*Dm~Wfq)CDNX6fVR{MVZ1a z`sjVNlaegt(gwj@iSkKgSQB>{=nLzH$e2ulKi}weK+jHr3TkMj1jNwjsLRyp>!D zn8zZDhj|-ANs|SSj}D*gC?ALRG}fTek~*eS1gMy{u~f~;E|po;2>@UnVu?G(v(DHY zswcZ0GnvUM3y&#CsKU1`mNVJZ?NqvSCtVj^6LZ4C1!YoYR?nG!&IA&6+Y}WJhcly3 zvVPMpg%z%HrD}P|#+o}PxM0k1VrDS1q?0|IOqYHT8>8sKc-K%H z(z|?Ly`W=~Vz5)NhtK2SxRbnc84xI|Pgtfvj4-ftxluZTr!T+;9#4YTcSU zlWB_4Nm}(m?0=J4RRmJxls=fW-|FC^e4DJ4HY`#AAwap1)EZML*(61bAHM%<%3jmI z+%@(L@P2SzaP$Bzn_>#|6OjvXAEID1FyjCD1N7s*whyr_Y&>~UwRwclOj(b8h)+(SbVCIx-DN!5N8_%0}or3itXht78@iCFyQBqCO0ILxb5V&9-iKk@5MYZgMeymV#kG`#{F7!=PrLE*@XBUV zVY^d}pj(mh=k-R;U#q>1^9-@LD_Rnk7d$8cZU^rAjdrR6ch{jI1;B3#qZE;0D$C;zFSdM^&as4E*2Ss+uZ#WS|}p=0Uo!AWdE6$fMRl~RIFv{3zVhl zpXI0#6Y1}cCmWltDo)X4sTIt-m8!37eb_DrQ(5+6#mnmtmAR@-g<@@;JN`^8B9gDy zP~;5!4cMb{$8=HPMrth)@p-hIniP_#t&#w*g&Pqg^kF-XNEj$`tszSt@1WRC1sI6G zlU>HP3Jm;kPQ~WV^}Ak(aifbYW3ybZJ4?T!fv>GJa4`k~K?BEnpJl(cy`g-VHL&3m zCq6IBxcWlNOS`ieS^R`skf?h>U0+eA@dvYJ3Zq`5ZHnD3?BIp3dERXsWe=Q@78efDU7!`DV*ms3fZ9!DYj zf^Cb3{X7;W|I2&mKa8z3(qwvec=oHp6ewOE^}_~}Gz;*E2tq^{PpgF<6hEWxBfu&~ z{FI(76Zd47f-1kvRxcIPXSMS2MQQULujZlZK8)#r-G&#eUB(2l37{LLFuYj5(42E! z8sfYfw%@m0Av;ueYhq+-Yhe*!w6?OdY1iGo+ITS)K38HLNpdp39ZTtRBJ%6=Rabq* zlB&xDJ(%z;odOU+TM6>}RV33YA>L(ycg#H4d{JoGMml>fJm`v*g0cAcEh-_%Mmlb| zKbb3RTN>?x?k_=~PacQFm>4^ZF<8RRZ{Y{1s3vuEfKX)%-V;(xbfLHCisu)onVsVV z#Jls>#_1gWG&61%;JDb%mP(%EI(>F{pE~yJ76&maMHi}Kj^#o7d2HQ=e(*7DKiuVg zg6+FG>+k{)1_f3SN6gri^I2<)=%g-GTA$s6wU$GE4-hwsgzu=t!%U>H?ih4}E1!RE zo0QjSexQBHe56I2&6n`?H{YQE{L#zzX}-jhh+lsP5CXq3N5s^d>jdz@G3dja22)Y= zW{kxlK^{(BvOd^uFWOZSpFYEdx}PrZ-+y#S$YCLz{o=KIXW?4!@%2wj60xI9l;y}& zA)_{j-&8n5y1I1A&3UgZSYa-P*#ymZ;dEKkUZG71@ZgZ3{e~~la+2wdsRCdkEpcQp zyUsOt&Lct<2V0~26}u8H+jslWP)!^U9Uh2>bl^oCfw4)f8(}SAs0cRwqK|WUOn&iv9Zu^@WW~?>Sfd~ zBEZQ^X>lNMi0TsE9qw9lV&a?yI&Zg@pK#X|o{8^4zzWHMA+e_;e1hJqX5LZ7nrKwl zmB(co5hT+&Efi)M3mY&L``Fs6&S2XT2iC+P46&e=X<2Ml=7*9f4={q#=zJMFY&2HV zkwP){Of_qc=auB1%~JwSc`78>T)*ZLPCd<5-wL*cGZ{Z_wi->%MPA`eE3ztr(F7|y zu(>FUq=D9D&XP9F08K@-McRmtsPcEo0=m_6C{@~^*sw+hFZyTX)!k+ zo>?xlNSr*m$j>Ay&%?2Hv~#<$<8v!QyMIN#k=RAv4O9y-tN$p-UVAX!pAq+ zw~u%6B*BGCdM)D?Ww~uFHgU;T^PY8U#LxLRg9VZ8!u0B9Vprw~=}qE$Mk)@#-f+v; z-aIYv(py#D;z~@@FtHH%R5rfQtK}V`<=^-{0O>9;7{IV5Nco|`XoRcx*sJo}3wTRB z1v3n5^f1A(rl9!L=cEtsAA=~6wv+caQ4e5AO6`k7!_dHe@9brZW{^*HkEoB|DunXH zgeSlHCRYLV;?pD>m`!=j&Ea);C4^@y2?U#|bs8rO;UPfr@_*Xyz{T19Q4|cxR=AK! z2n(8HM9|LgHWXg4VH95$*}GAf$oINYxQ7qu z_KLGJ&beO_CE1Nq?pIvqhp)W-imo4Rrnx_9)--ACFB=*>I|P_x5Jnxa$ifN;eL$wv zvSh;;LqrVGRJG@23~_jz1ZmjNxiT3^dc;)~Jj-?$60o=ZQ&Oa#8h@7n@>LVz#-!Ne zv*-U25}#DeY-MsaZX~E&MoN@DMsJ=Qs*D%uVM<3}4V(2*L_x{Xo=QMI)9BN)GI-=f zn1so!bE53s%yfB{=r!t|$TSbd*fGTxH3F$~3cj9BQkZ_eykuF)!F4NcnC0wI(|Pq~ z0BJFGzHE8FoN8uRwJ^Yo-?xFet9NVeCR~vQ?{s`?%~jc$4)<+6O3IQul;=l0f_?Xn z4SZb)!OSwDv1O7-cN;3}3-8NBs!!%GFC3n;g5KG)G8hwTb#Ax}$`}E&YNjJ?kS#$* z7n&=fjge{Evb-FoM`wvXB!`^SsMNz_G9lWaQ~4cYyjn9kh&Q_ca!5Z9SG+rJ#gII} zx@L_VPhBpv#CMzvr{dg!Y9hI3C(k@!NVh&D?m-yw553yP#Vy+?5WmbEwC+y)LU_y7vs6oI5aB!78S9pHML@vDwIe(Snz;2Qe9_2Bm>;G5}w ziBZStcI5@Gojm@nKgX?}?t=gq9-&60I4EY6>wv2Zn4K$-%kF>RZ7st1`wh6VCwhx7 zqA0&^2z!K%*zesbs@LEUF>K~NkL~^b=E&ZZG=4RB&7R!-{bBzMgl<4naIHG8b&HG1 zehs)9>bU}`j+J2GB<)qK3E2o!Q|>h|YLq-4Nb6)>(Dc^zaOs4Lt^lRkh}#S2rVOSO zKs3u3(=R6Y6vbrPmtoQM_?1AkNh^gy|2}R)BTbKX!l0MObT7qq_pqlp;8UT*8Svb0 zdy56m`!M_#w=IZUWffQ5w1Cl!J0wu>`jT$VYEVg&{UYaO zd4)jv_{?1+ZTR@rC`q$bAZq2Z1E0hc#dE;qH(xk8Lk3?XWX86+qXqUlf_L@44zn%k zDAilYtb_gD0ky?!mNTvV!PuYGD&`^eDP9~$n_xT@!385%jpK zn)C(9tN@$tUu&SW0?oO$Yr-xc&jav-LYAHU=fIJ#Uin)2sm!vf={7CcQCJ@I9U|wl z(k!uadRKGUu*j9OS}quuq_;2e;5jTjkVr6vk1a{t)x%9RK6)JS*d?u{}Nv!C=DCXX;TxqZI^;LbSVV>YsX25QcQ=9tUi)2z2F^eI zliMo` zM8R@}FX+>7bPH$G&cVnuP7rfI>7Op@N?Ypv^g6#iqg1Kh6Ty(4i^U35@U z;XANAvzcOy6+lKRUK-k`1Sqh0YV*WrogqD%G`FTE*y7i*evEkYL?Y+a-n37#=l_{6 z27nr~FhN0^TU3wTzSlVbj4NQ(X>)ihj{}&Cdz!`!p3R>Na3sGJ6G6L#nXnG)WSmgh z=y`j-)dP?z4l9=-mqgbag}Mo4v(pAJ8XC$M4<8qxQBBu_nd6Y296zb7bLoUU1fa*t z*D}rH%#3o4LXM<$oQN^MR^t=%735d!n0p;Oq4_gA+ukn@{%KhXuS<0^ze%ozd9#%9 z7_B2DM?$j5C-pxyErFaWGdD}&_$Y*#(-_r+quEx@YqBvK5qvVQOwrLb!HQjV!Hez0 zR;z%|WCi8!g>g+4nD-APSCaC3&5&fWk<(-s{)YVqCuE^e99PMauO#32h8R}GEwB$> z*%5W#xsMLOxtb4@qR%;36B9Ox3rK6@EQW7IdVFcT+zeifddrsRgwtxec_5S&SBBTO zeB>Oi;V1g&@X}AW*%aUoQXxEYdLjM2Aa^X_=?!2Q6U%aVRa=R;;HdU!5kP-ksLt)R z=_>h*0`XNovz9_n%j?r!MCT^tip|(Q;BN!F+Is!fKi;AU2;^`7CtHM=wjSZH?D4Ce zt(5a-jkx&ie2x1;I2RdOqYn-UKq{v#bk(iFDccI^eqF12Zz56hz;; zNcoZ5vut}pZC5cuPXoQ#N=AxkR}h4dy->9`w6l3mxsuaqOq(&~ilUR|_o{9M{xU_^ zmE1)T4Loc;bUDxe5O|4li(qNG(xbj&7&)5>&9m7vIh^2`maWC7_=CzJRSi|Oq;DnJ zC5i6-f#ZJ2X^B+ievDb;v!1!uv(@6XDrv@|rc|}{1tWg3u2~ntFOB=qecnJbt8((= z3n|SEqgvd3!)<~xvxeuaizf;*^AW^Yg$bH8UQKl^otO|D%1KhE&?|{RWV>3k%_kzw zW_Lrl=`%1fQ9g$Dqz8>Ef`0c8z=`;L#aZnymH8t48|otrS<01^>8_PJkU7e@sEJ)8 zlo4;7rS&mM4k*5QkEC!mmU)=fNqq}!L zp+C+(9k$&7(xXvj3bx&+-1>&hsO~}Y!y1>1b`S;Kzaf93SmA?`4qN~EZ!rcINQID+ zF=aY0MCr5Cu>*FWQ2bS<*!<(r0c1t5ugEL@(yT7zmlyb%Bx6g0ea?XHcwjZcQ&_kK ziSZ4d--#&IhC@hpBAI1wHsa=$9hY0p=F3~_m6t#sNbmKY%VjGCv5qCU!U&;C<+6fQ z>YiG4rgd}ASFG0z?0&Y11Yg_*r2ec!sHd*inw^zjX6pL6v^+S#)ukEs>i zaIpLzlukbZx@tSu0_Cq?J-d6+_6TN*>q@jgiv5rt^o(4v{W zDO3J>X=lFU4TxJj^LK$&!bG;T=#(#TjU-PX{~SrBsF_h{JT2u{39j75Ytl)C*+i)v zN$aP^{=Z6@a7c+^p$&2r{U8suGGwpT;6~G3IsvIq9yeyG1E@5gSG+F%=(M^9#+!@| zw~*>?fJ+H@+}Y@Bd>Us4vqQYRN)lzc>XM zunkbcbVpv9+t+=~M*GupW7H4l61EzTl8;0lBwJw#Q`>yJsHAbUdwbf#vSDyn&1-n2 z2=Uz$APL&aAStkkLM6Dy2|B;h?^*2fc~YMqQa3VP^Mhkjk-9Z#f+xR((#UT@zRZlq z=@!`XQ{{0;1=7<(#5h1s!SxI!(a|d_LtRhkrNOD`fbwh4-eLo(0MX^1N6zqPu42Wy zxKAn@`q^dmltt27a9xSiL;A@R*?MRYOfS~seDM|hz?&r#e5oGSl%mz6GS_#%Dw=v- z=c~R1>U(j{!I$BFtuN@y_Qj5mfAaiK|K)!NF~CTOq~=_X^?gNd*|abyMwDn2Ik#Hc zE4-}HVzhG)LQ9UXPNeIDTL%&z8Ml62OEQmGOorCOJQvV#ZciD!NR4{Y3y@W?X{>y7Le@b~>|?{iM3 zQl(6wx`|*?mC8JqeOY^5|FxDEZ*0(cu?%yt9C}jB+8mRmmG36pIs-3{?HAl^<9Qjx zxO$MTn|XO&v-Fma!IlYF5QFZ?W+#d7*0$I@1#24%aA^^~FC);0z92g={nkN5Ega0biK?^C8uW%u4MML)CGYuFc~47mfsGG_SJyeb{AROoq{A*aKbR2L zjW%M&(6d;QsMnR{8_mQ_@daCozN5joHZvBzVRL&ikDs^!dKZe3Q?Htgne^sXV_wjb z5pOjdy;${cL)+2IH#8r;v}w`by9Md9L$VwDTfAdimy7qTJ7@Ty2+LJvW238O(0cW7 zQa5nCc>T3=cC+ur%RPac+mzn%!pzEy{uay9YgUX)zv}j-pI?B9>0`IHGQH`KYH0ex z?QKo(`gZ1K-nXg6>BUqFjZN2_g0~r+-onPlF|du@>3x3`)6*B-VttNc469;W9L^iB z-dTJ}UeLwk`PrR!{^`!aA!hLL<(+rl_&P@I(FNb~@gGQ|y7V(0)6Wk-VSNe4)nZ_u0O9D@H6O#$cNC<#{9r-8*!=L|=TG~U zgqSR7Fuywa81L@G;Ry#<>F|DexcoKwX*d?A-+le{pZ)nuz%foPUV3tJ_~HHE{Oah* z(>K0+dv@=We|evt+y$A*w*zCYgBF<47{yHfea`IkwHg ziw}6K1UxNv{W!_K!%IhtoLKR3;!QIrgzK!P-Zhu@W_fp`M!8|qoi!D=$+%0DYbo9C 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 literal 0 HcmV?d00001 diff --git a/packs/cde-spells/CURRENT b/packs/cde-spells/CURRENT index 1a84852..f7753e2 100644 --- a/packs/cde-spells/CURRENT +++ b/packs/cde-spells/CURRENT @@ -1 +1 @@ -MANIFEST-000002 +MANIFEST-000006 diff --git a/packs/cde-spells/LOG b/packs/cde-spells/LOG index 751e0ca..2e07d15 100644 --- a/packs/cde-spells/LOG +++ b/packs/cde-spells/LOG @@ -1,5 +1,3 @@ -2026/04/27-17:47:13.236474 7f2778bfd6c0 Delete type=3 #1 -2026/04/27-17:47:13.238827 7f272b7fe6c0 Level-0 table #5: started -2026/04/27-17:47:13.244095 7f272b7fe6c0 Level-0 table #5: 120353 bytes OK -2026/04/27-17:47:13.250468 7f272b7fe6c0 Delete type=0 #3 -2026/04/27-17:47:13.250702 7f272b7fe6c0 Manual compaction at level-0 from '!items!2f51pcvFkcZjaxDk' @ 72057594037927935 : 1 .. '!items!yVN7PZw35iIaBl0H' @ 0 : 0; will stop at (end) +2026/04/27-20:01:11.343717 7fed927fc6c0 Recovering log #4 +2026/04/27-20:01:11.353301 7fed927fc6c0 Delete type=3 #2 +2026/04/27-20:01:11.353373 7fed927fc6c0 Delete type=0 #4 diff --git a/packs/cde-spells/LOG.old b/packs/cde-spells/LOG.old new file mode 100644 index 0000000..751e0ca --- /dev/null +++ b/packs/cde-spells/LOG.old @@ -0,0 +1,5 @@ +2026/04/27-17:47:13.236474 7f2778bfd6c0 Delete type=3 #1 +2026/04/27-17:47:13.238827 7f272b7fe6c0 Level-0 table #5: started +2026/04/27-17:47:13.244095 7f272b7fe6c0 Level-0 table #5: 120353 bytes OK +2026/04/27-17:47:13.250468 7f272b7fe6c0 Delete type=0 #3 +2026/04/27-17:47:13.250702 7f272b7fe6c0 Manual compaction at level-0 from '!items!2f51pcvFkcZjaxDk' @ 72057594037927935 : 1 .. '!items!yVN7PZw35iIaBl0H' @ 0 : 0; will stop at (end) diff --git a/packs/cde-spells/MANIFEST-000002 b/packs/cde-spells/MANIFEST-000002 deleted file mode 100644 index 721ffe0a90789105fdbb05e4126a43e4f99eb2c1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 135 zcmWIhx#Ncn10$nUPHI_dPD+xVQ)NkNd1i5{bAE0?Vo_pAe$kRS-TOEg7@3$k8JJmE z7$Pi#zWM>VEI=+BizGV}>%ukc@`{-yskz09Mro#o1<7S@*~w8^i4`u{jC>4W0F$o_ X^D_^KDmOOG^h|WhG4NoNfXD*?vt1+n diff --git a/packs/cde-spells/MANIFEST-000006 b/packs/cde-spells/MANIFEST-000006 new file mode 100644 index 0000000000000000000000000000000000000000..4a3ed8a2a19c486679e8b8d4cf0ddd7a7e25897e GIT binary patch literal 120 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 W@^&wD39E2SD>5`O2xsJn$O8a<3L`=Q diff --git a/packs/cde-supernaturals/MANIFEST-000006 b/packs/cde-supernaturals/MANIFEST-000006 new file mode 100644 index 0000000000000000000000000000000000000000..3a55a6e4c161f52450606c395e585ec62996ac17 GIT binary patch literal 119 zcmXTxkiC+~z{n_-lUkOVlai$8R9TW*o>`pgoS$2eSd>_jU&PMDy3Sc%F|#B!w^-3J zz|YdKAkfFa&nYdc*xj6wi2)2?@)Z?P-tL7iVHJ*PMTRB@;f(wc`SvE?^BfF}OzfNt I%p5EN0Ei18e*gdg literal 0 HcmV?d00001 diff --git a/packs/cde-weapons/000004.log b/packs/cde-weapons/000004.log deleted file mode 100644 index e69de29..0000000 diff --git a/packs/cde-weapons/000007.log b/packs/cde-weapons/000007.log new file mode 100644 index 0000000000000000000000000000000000000000..8f142c76661585328a028e8e83cd7f2126b64f49 GIT binary patch literal 11893 zcmeHNzi%7K70wk&n{;XC*hq(vlt{|9BpeRV4@;Ir$vjK8EC<11xI0UZG&{SVACzdr zzyVh!2=XTchZM>2iu7sH@IOeGBF+5)>Cy)IW_C$RG$s2kbi#rvDDFJ&>>KiZ^S$rA zF?|28vi#A{ew6+F6#qW@`N!O_SbtpIJ8O2g8ar$C{p9?WKL5v$Ul+dMVPU;6ZYdNC zlEw^{{;$)1kC7#EOq+^f+;mene#vN>NL=%{g-hMl?h#8-$Cy&kR*B>QKBSi}^QfqM`PA=824so{9wdg0UbvpReu zB9Sf2iiFERSVPV^m1MEs^X`T!!ID2Il8`23Q9IXhaX}50lrTf6HHv8>FpnmQ;!GMU zm@a?1lzxT>W^SEiD~*|8Zs9RCOmQl5pQu~RhE7>vFcLFN;9T{?n^eQ~O0nSA4Kr43 zC_Y#$BuzuPtg{ZoMAgCdHjg46SYf(;@TH~FaCd<@WMY_h4}DWCuqeXwaP`Yy6$?=! zLZ%Aq(h7lZFHvx088co=rgWR9?wbr*L@_N4xH}TGg?nG)?HAfmH_z+*Ticq{ zbsqP-cxuQc0{@U|Z5;v*DdHGWjStNN2sRWz-~ua=A;N``G!fkn!Wi$%WDDOPAQTdW zH9_cl&vg-RwZ;fA(8^Z$Uj%(K;Tm7Y_ltQ%bcTU>%x75mFfqUSAl_#kYxkshcyw_b z{c9NWE5G< zFZA~A(dI}Lj9W&)*rqB(LbS;dHBK6|t>PEVsexHYj2bFAN0yAO9sJPmwUDqP)0aWN z2O{_yZ;=FXStfg#a0sy&Bt}iQ812~aoZ6U6T*OjqX8hZS||445~uomJtv(RDjUmP)#cO z-zgTz;X|33xRy4O+vaTT2YxADX> zla&Cvs~Q zL*Mk6VAnv`jn*EHZ1`q3PEp{<$Bn8LAOz{*MSBP(qaFTyrFQ_hi8y($y45=v=KCD$ zm;+_nKxsb=`2C$1C$)xNv+_v%X$X{Y%Lpiqf%IKW8BW;va}X-gNcRPIhlFN?dWLRl z7V{ELD^B|9KOeS?E*0W0JR!2SrRAqVb-$7pFgM)FlG4n$o`$UHsas1!=P z_yF4egEsi01knL&;R5!0*BQjLzo<;6nrU>!C+qf!IoiAjGHnFOaQpD^;&ZkopH?3? zs_MI;AQ`ue5HwWCsq4`pgoS$2eSd>_jU&PMD+O8z8m|2pVTdZj0 z8JSe+9N=c@ { + const ia = a.initiative ?? 0 + const ib = b.initiative ?? 0 + if (ia !== ib) return ib - ia // descending — highest acts first + + // Tie-break: PCs before NPCs + const aIsPC = a.actor?.type === ACTOR_TYPES.character ? 1 : 0 + const bIsPC = b.actor?.type === ACTOR_TYPES.character ? 1 : 0 + if (aIsPC !== bIsPC) return bIsPC - aIsPC + + return (a.name ?? "").localeCompare(b.name ?? "") + }) + return this.turns + } +} + +/** + * Advance a combatant's wheel position by the given action cran cost. + * Position wraps: after reaching 1, it continues from 24. + * + * @param {Combatant} combatant + * @param {number} cranCost + */ +export async function advanceCombatantPosition(combatant, cranCost) { + const current = combatant.initiative ?? combatant.actor?.system?.initiative ?? 1 + const newValue = ((current - cranCost - 1 + 48) % 24) + 1 + // Update combatant only; the updateCombatant hook in system.js syncs actor.initiative. + await combatant.update({ initiative: newValue }) +} diff --git a/src/system.js b/src/system.js index 06e6650..d06d7f0 100644 --- a/src/system.js +++ b/src/system.js @@ -27,7 +27,9 @@ import { CDECharacterSheet, CDENpcSheet } from "./ui/sheets/actors/index.js" import { CDEItemSheet, CDEKungfuSheet, CDESpellSheet, CDESupernaturalSheet, CDEWeaponSheet, CDEArmorSheet, CDESanheiSheet, CDEIngredientSheet } from "./ui/sheets/items/index.js" import { CDELoksyuApp } from "./ui/apps/loksyu-app.js" import { CDETinjiApp } from "./ui/apps/tinji-app.js" +import { CDEWheelApp } from "./ui/apps/wheel-app.js" import { injectRollActions, refreshAllRollActions } from "./ui/roll-actions.js" +import { CDECombat } from "./documents/combat.js" Hooks.once("i18nInit", preLocalizeConfig) @@ -39,7 +41,9 @@ Hooks.once("init", async () => { game.system.CONST = { MAGICS, SUBTYPES } // Expose standalone apps globally for macros - game.cde = { CDELoksyuApp, CDETinjiApp } + game.cde = { CDELoksyuApp, CDETinjiApp, CDEWheelApp } + + CONFIG.Combat.documentClass = CDECombat CONFIG.Actor.dataModels = { [ACTOR_TYPES.character]: CharacterDataModel, @@ -126,6 +130,7 @@ Hooks.once("init", async () => { Hooks.once("ready", async () => { await migrateIfNeeded() + CDEWheelApp.registerHooks() }) /** Add Loksyu + Tin Ji quick-access buttons to the chat panel (FoundryVTT v13) */ @@ -145,12 +150,16 @@ Hooks.on("renderChatLog", (_app, html) => { + ` // Use event delegation to avoid being swallowed by Foundry's own handlers wrapper.addEventListener("click", (ev) => { if (ev.target.closest(".cde-chat-btn--loksyu")) CDELoksyuApp.open() if (ev.target.closest(".cde-chat-btn--tinji")) CDETinjiApp.open() + if (ev.target.closest(".cde-chat-btn--wheel")) CDEWheelApp.open() }) // Insert before the chat form — works on v12 and v13 @@ -173,3 +182,35 @@ Hooks.on("updateSetting", setting => { refreshAllRollActions() } }) + +/** + * When an actor's initiative changes (via +/- buttons on the sheet), + * sync the corresponding combatant in the active combat. + */ +Hooks.on("updateActor", (actor, diff) => { + if (!foundry.utils.hasProperty(diff, "system.initiative")) return + if (!game.combat) return + const initiative = actor.system.initiative + const combatant = game.combat.combatants.find(c => c.actor?.id === actor.id) + if (combatant && combatant.initiative !== initiative) { + combatant.update({ initiative }).catch(() => {}) + } +}) + +/** + * When a combatant's initiative changes (via wheel action buttons), + * sync the actor's system.initiative to match. + * Uses setTimeout to defer until after Foundry's update chain resolves, + * avoiding concurrent #recordPreviousState errors on the combat document. + */ +Hooks.on("updateCombatant", (combatant, diff) => { + if (!("initiative" in diff)) return + const initiative = combatant.initiative + if (initiative == null) return + setTimeout(() => { + const actor = combatant.actor + if (actor && actor.system?.initiative !== initiative) { + actor.update({ "system.initiative": initiative }).catch(() => {}) + } + }, 0) +}) diff --git a/src/ui/apps/index.js b/src/ui/apps/index.js index a8d0f02..50d270f 100644 --- a/src/ui/apps/index.js +++ b/src/ui/apps/index.js @@ -14,3 +14,4 @@ export { CDELoksyuApp } from "./loksyu-app.js" export { CDETinjiApp } from "./tinji-app.js" export { updateLoksyuFromRoll, updateTinjiFromRoll } from "./singletons.js" +export { CDEWheelApp } from "./wheel-app.js" diff --git a/src/ui/apps/wheel-app.js b/src/ui/apps/wheel-app.js new file mode 100644 index 0000000..24135e5 --- /dev/null +++ b/src/ui/apps/wheel-app.js @@ -0,0 +1,204 @@ +/** + * Chroniques de l'Étrange — Système FoundryVTT + * + * Chroniques de l'Étrange est un jeu de rôle édité par Antre-Monde Éditions. + * Ce système FoundryVTT est une implémentation indépendante et n'est pas + * affilié à Antre-Monde Éditions, + * mais a été réalisé avec l'autorisation d'Antre-Monde Éditions. + * + * @author LeRatierBretonnien + * @copyright 2024–2026 LeRatierBretonnien + * @license CC BY-NC-SA 4.0 – https://creativecommons.org/licenses/by-nc-sa/4.0/ + */ + +import { advanceCombatantPosition } from "../../documents/combat.js" + +const WHEEL_TEMPLATE = "systems/fvtt-chroniques-de-l-etrange/templates/apps/cde-wheel-app.html" + +/** + * Action costs for common combat actions (in crans). + * Listed in order from cheapest to most expensive. + */ +export const ACTION_COSTS = [ + { key: "draw", label: "CDE.ActionCostDraw", cost: 1 }, + { key: "changestyle", label: "CDE.ActionCostChangeStyle", cost: 1 }, + { key: "defense", label: "CDE.ActionCostDefense", cost: 1 }, + { key: "aim", label: "CDE.ActionCostAim", cost: 2 }, + { key: "help", label: "CDE.ActionCostHelp", cost: 2 }, + { key: "defally", label: "CDE.ActionCostDefendAlly", cost: 2 }, + { key: "move", label: "CDE.ActionCostMove", cost: 2 }, + { key: "attack", label: "CDE.ActionCostAttack", cost: 3 }, + { key: "delay", label: "CDE.ActionCostDelay", cost: 6 }, +] + +/** + * Wu Xing color segments for the 24-cran wheel. + * 6 colors × 4 crans = 24. Each colour covers crans [start..start+3]. + * An effect lasting 6 crans returns to the same colour. + */ +const WHEEL_SEGMENTS = [ + { label: "Métal", color: "#b8c4cc", textColor: "#1a1a1a", crans: [1, 2, 3, 4] }, + { label: "Eau", color: "#3a7bd5", textColor: "#ffffff", crans: [5, 6, 7, 8] }, + { label: "Terre", color: "#c8a84b", textColor: "#1a1a1a", crans: [9, 10, 11, 12] }, + { label: "Feu", color: "#d94f3d", textColor: "#ffffff", crans: [13, 14, 15, 16] }, + { label: "Bois", color: "#4a9b5a", textColor: "#ffffff", crans: [17, 18, 19, 20] }, + { label: "Repère", color: "#1a1a2e", textColor: "#aaaaaa", crans: [21, 22, 23, 24] }, +] + +/** Return the segment data for a given cran (1–24). */ +function segmentForCran(cran) { + return WHEEL_SEGMENTS.find(s => s.crans.includes(cran)) ?? WHEEL_SEGMENTS[0] +} + +/** + * Roue d'Initiative — visual initiative wheel for CDE combat. + * + * Shows all combatants in the current combat scene on a 24-cran wheel. + * Provides action-cost buttons to advance a combatant's position. + * + * Singleton: open via CDEWheelApp.open(). + */ +export class CDEWheelApp extends foundry.applications.api.ApplicationV2 { + static DEFAULT_OPTIONS = { + id: "cde-wheel-app", + classes: ["cde-wheel-app"], + tag: "div", + window: { + title: "CDE.InitiativeWheel", + icon: "fas fa-circle-notch", + resizable: true, + }, + position: { width: 820, height: 620 }, + actions: { + advanceCran: CDEWheelApp.#advanceCran, + setSurprised: CDEWheelApp.#setSurprised, + rollInitiative: CDEWheelApp.#rollInitiative, + }, + } + + /** @type {CDEWheelApp|null} */ + static #instance = null + + /** Open (or bring to front) the singleton instance. */ + static open() { + if (!CDEWheelApp.#instance || CDEWheelApp.#instance.rendered === false) { + CDEWheelApp.#instance = new CDEWheelApp() + CDEWheelApp.#instance.render(true) + } else { + CDEWheelApp.#instance.bringToFront() + } + return CDEWheelApp.#instance + } + + /** Currently selected combatant id (for action panel). */ + #selectedId = null + + async _prepareContext(options) { + const combat = game.combat + const combatants = combat ? [...combat.combatants.values()] : [] + const sorted = [...combatants].sort((a, b) => (b.initiative ?? 0) - (a.initiative ?? 0)) + const cranData = this.#buildCranData(combatants) + const selected = this.#selectedId + ? combatants.find(c => c.id === this.#selectedId) + : null + const actionCosts = ACTION_COSTS.map(a => ({ + ...a, + label: game.i18n.localize(a.label), + })) + + return { + hasCombat: !!combat, + combatants: sorted.map(c => ({ + id: c.id, + name: c.name, + img: c.token?.texture?.src ?? c.actor?.img ?? "icons/svg/mystery-man.svg", + initiative: c.initiative ?? "—", + segment: segmentForCran(c.initiative ?? 1), + isActive: combat?.current?.combatantId === c.id, + isSelected: c.id === this.#selectedId, + hasInitiative: c.initiative != null, + })), + cranData, + selected, + selectedName: selected?.name ?? null, + actionCosts, + } + } + + async _renderHTML(context, options) { + return foundry.applications.handlebars.renderTemplate(WHEEL_TEMPLATE, context) + } + + _replaceHTML(result, content, options) { + content.innerHTML = result + this.#bindEvents(content) + } + + /** Build per-cran data for the SVG wheel. */ + #buildCranData(combatants) { + const data = [] + for (let cran = 1; cran <= 24; cran++) { + const segment = segmentForCran(cran) + const fighters = combatants.filter(c => Math.round(c.initiative) === cran) + data.push({ cran, segment, fighters }) + } + return data + } + + /** Bind click events for combatant selection. */ + #bindEvents(content) { + content.querySelectorAll("[data-select-combatant]").forEach(el => { + el.addEventListener("click", () => { + this.#selectedId = el.dataset.selectCombatant + this.render() + }) + }) + } + + /** Action: advance selected combatant by given cran cost. */ + static async #advanceCran(event, element) { + const app = CDEWheelApp.#instance + if (!app?.#selectedId) return + const cost = parseInt(element.dataset.cost, 10) + if (!cost || isNaN(cost)) return + const combatant = game.combat?.combatants.get(app.#selectedId) + if (!combatant) return + await advanceCombatantPosition(combatant, cost) + } + + /** Action: set selected combatant to surprised (position 1 = reference). */ + static async #setSurprised(event, element) { + const app = CDEWheelApp.#instance + if (!app?.#selectedId) return + const combatant = game.combat?.combatants.get(app.#selectedId) + if (!combatant) return + // Update combatant only — updateCombatant hook in system.js syncs actor + await combatant.update({ initiative: 1 }) + } + + /** Action: open the initiative dialog for the selected combatant. */ + static async #rollInitiative(event, element) { + const app = CDEWheelApp.#instance + if (!app?.#selectedId) return + const combatant = game.combat?.combatants.get(app.#selectedId) + if (!combatant) return + await game.combat.rollInitiative([app.#selectedId]) + } + + /** Re-render when combat state changes. */ + static registerHooks() { + const refresh = () => { + if (CDEWheelApp.#instance?.rendered) CDEWheelApp.#instance.render() + } + Hooks.on("updateCombat", refresh) + Hooks.on("updateCombatant", refresh) + Hooks.on("createCombatant", refresh) + Hooks.on("deleteCombatant", refresh) + Hooks.on("updateActor", (_actor, diff) => { + if (foundry.utils.hasProperty(diff, "system.initiative")) refresh() + }) + Hooks.on("deleteCombat", () => { + if (CDEWheelApp.#instance?.rendered) CDEWheelApp.#instance.render() + }) + } +} diff --git a/src/ui/helpers.js b/src/ui/helpers.js index 7e23697..c2c9e13 100644 --- a/src/ui/helpers.js +++ b/src/ui/helpers.js @@ -118,4 +118,29 @@ export function registerHandlebarsHelpers() { } return game.i18n.localize(keys[activation] ?? "CDE.Activation") }) + + /** + * Compute the SVG x,y coordinates for a cran on the initiative wheel. + * Cran 1–24 are arranged counter-clockwise from the bottom (reference at 6 o'clock). + * angle = 90° + cran * 15° (counter-clockwise = positive in standard math, negative in SVG). + * In SVG coords: x = cx + r*cos(a), y = cy - r*sin(a) [y-axis is flipped in SVG]. + */ + Handlebars.registerHelper("cranPosition", function (cran, cx, cy, r) { + const angleDeg = 90 + cran * 15 // counter-clockwise from bottom + const angleRad = (angleDeg * Math.PI) / 180 + const x = Math.round(cx + r * Math.cos(angleRad)) + const y = Math.round(cy - r * Math.sin(angleRad)) + return { x, y } + }) + + /** X offset for overlapping fighters on the same cran. Centres a 30px image on the cran cx. */ + Handlebars.registerHelper("fighterX", function (cx, index, total) { + const offset = total > 1 ? (index - (total - 1) / 2) * 34 : 0 + return Math.round(cx - 15 + offset) + }) + + /** Y offset for fighters — positions image just above the cran circle. */ + Handlebars.registerHelper("fighterY", function (cy, index, total) { + return Math.round(cy - 50) + }) } diff --git a/system.json b/system.json index 9bcedbb..dd62d87 100644 --- a/system.json +++ b/system.json @@ -25,7 +25,10 @@ "path": "packs/cde-kungfus", "system": "fvtt-chroniques-de-l-etrange", "flags": {}, - "ownership": { "PLAYER": "OBSERVER", "ASSISTANT": "OWNER" } + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } }, { "name": "cde-spells", @@ -34,7 +37,10 @@ "path": "packs/cde-spells", "system": "fvtt-chroniques-de-l-etrange", "flags": {}, - "ownership": { "PLAYER": "OBSERVER", "ASSISTANT": "OWNER" } + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } }, { "name": "cde-supernaturals", @@ -43,7 +49,10 @@ "path": "packs/cde-supernaturals", "system": "fvtt-chroniques-de-l-etrange", "flags": {}, - "ownership": { "PLAYER": "OBSERVER", "ASSISTANT": "OWNER" } + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } }, { "name": "cde-weapons", @@ -52,7 +61,10 @@ "path": "packs/cde-weapons", "system": "fvtt-chroniques-de-l-etrange", "flags": {}, - "ownership": { "PLAYER": "OBSERVER", "ASSISTANT": "OWNER" } + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } }, { "name": "cde-armors", @@ -61,7 +73,10 @@ "path": "packs/cde-armors", "system": "fvtt-chroniques-de-l-etrange", "flags": {}, - "ownership": { "PLAYER": "OBSERVER", "ASSISTANT": "OWNER" } + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } }, { "name": "cde-sanhei", @@ -70,7 +85,10 @@ "path": "packs/cde-sanhei", "system": "fvtt-chroniques-de-l-etrange", "flags": {}, - "ownership": { "PLAYER": "OBSERVER", "ASSISTANT": "OWNER" } + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } }, { "name": "cde-ingredients", @@ -79,7 +97,10 @@ "path": "packs/cde-ingredients", "system": "fvtt-chroniques-de-l-etrange", "flags": {}, - "ownership": { "PLAYER": "OBSERVER", "ASSISTANT": "OWNER" } + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } }, { "name": "cde-items", @@ -88,7 +109,10 @@ "path": "packs/cde-items", "system": "fvtt-chroniques-de-l-etrange", "flags": {}, - "ownership": { "PLAYER": "OBSERVER", "ASSISTANT": "OWNER" } + "ownership": { + "PLAYER": "OBSERVER", + "ASSISTANT": "OWNER" + } }, { "name": "cde-npcs", @@ -97,7 +121,10 @@ "path": "packs/cde-npcs", "system": "fvtt-chroniques-de-l-etrange", "flags": {}, - "ownership": { "PLAYER": "NONE", "ASSISTANT": "OWNER" } + "ownership": { + "PLAYER": "NONE", + "ASSISTANT": "OWNER" + } } ], "languages": [ @@ -185,16 +212,15 @@ "minimum": "13", "verified": "13" }, - "relationships": { - }, + "relationships": {}, "background": "/systems/fvtt-chroniques-de-l-etrange/images/background/accueil.webp", "grid": { "distance": 5, "units": "m" }, - "initiative": "@anti_initiative", + "initiative": "@initiative", "primaryTokenAttribute": "threetreasures.heiyang", "secondaryTokenAttribute": "threetreasures.heiyin", "manifest": "https://www.uberwald.me/gitea/uberwald/fvtt-chroniques-de-l-etrange/raw/branch/main/system.json", "download": "https://www.uberwald.me/gitea/uberwald/fvtt-chroniques-de-l-etrange/raw/branch/main/13.0.0.zip" -} +} \ No newline at end of file diff --git a/templates/apps/cde-wheel-app.html b/templates/apps/cde-wheel-app.html new file mode 100644 index 0000000..79ab516 --- /dev/null +++ b/templates/apps/cde-wheel-app.html @@ -0,0 +1,148 @@ +{{! Roue d'Initiative — Chroniques de l'Étrange }} +
+ + {{! ── SVG Wheel ── }} +
+ {{#if hasCombat}} + + + {{! Background circle }} + + + {{! Cran slots — 24 positions, arranged counter-clockwise from bottom }} + {{#each cranData}} + {{#with (cranPosition cran 200 200 158)}} + + + {{../cran}} + + {{! Combatant avatar(s) on this cran — placed above the cran circle }} + {{#each ../fighters}} + + {{/each}} + + {{/with}} + {{/each}} + + {{! Centre: system name }} + CHRONIQUES + DE L'ÉTRANGE + + {{! Reference marker at bottom (cran 0 / position between 24 and 1) }} + + + {{ localize "CDE.WheelReference" }} + + + + {{! Wu Xing colour legend — HTML strip below SVG }} +
+ Métal + Eau + Terre + Feu + Bois +
+ {{else}} +
+ +

{{ localize "CDE.NoCombatActive" }}

+
+ {{/if}} +
+ + {{! ── Right panel: combatant list + actions ── }} +
+ + {{! Combatant list }} +
+
{{ localize "CDE.Combatants" }}
+ {{#if hasCombat}} + {{#each combatants}} +
+ {{name}} + {{name}} + + {{initiative}} + + {{#if isActive}}{{/if}} +
+ {{/each}} + {{else}} +

{{ localize "CDE.NoCombatActive" }}

+ {{/if}} +
+ + {{! Action cost panel — only shown when a combatant is selected }} + {{#if selected}} +
+
+ {{ localize "CDE.AdvanceCombatant" }} — {{selectedName}} +
+ +
+ {{#each actionCosts}} + + {{/each}} +
+ +
+ + +
+
+ {{else}} +
+

+ + {{ localize "CDE.SelectCombatantHint" }} +

+
+ {{/if}} + +
{{! end panel }} +
{{! end layout }}