intelligent-system-design-language 0.3.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/.claude/agents/langium-language-designer.md +38 -0
  2. package/.claude/agents/typescript-vscode-expert.md +29 -0
  3. package/.claude/agents/ui-ux-designer.md +36 -0
  4. package/.claude/settings.local.json +33 -0
  5. package/.idea/inspectionProfiles/Project_Default.xml +7 -0
  6. package/.idea/isdl.iml +14 -0
  7. package/.idea/modules.xml +9 -0
  8. package/.idea/vcs.xml +7 -0
  9. package/.idea/watcherTasks.xml +4 -0
  10. package/.vscodeignore +18 -0
  11. package/LICENSE +674 -0
  12. package/README.md +86 -0
  13. package/bin/cli.js +4 -0
  14. package/bin/lsp.js +8 -0
  15. package/isdl.png +0 -0
  16. package/out/_backgrounds.scss +91 -0
  17. package/out/_handlebars.scss +505 -0
  18. package/out/_isdlStyles.scss +1357 -0
  19. package/out/_vuetifyOverrides.scss +425 -0
  20. package/out/_vuetifyStyles.scss +31957 -0
  21. package/out/cli/cli-util.js +39 -0
  22. package/out/cli/cli-util.js.map +1 -0
  23. package/out/cli/components/_backgrounds.scss +91 -0
  24. package/out/cli/components/_handlebars.scss +505 -0
  25. package/out/cli/components/_isdlStyles.scss +1357 -0
  26. package/out/cli/components/_vuetifyOverrides.scss +425 -0
  27. package/out/cli/components/_vuetifyStyles.scss +31957 -0
  28. package/out/cli/components/active-effect-sheet-generator.js +643 -0
  29. package/out/cli/components/active-effect-sheet-generator.js.map +1 -0
  30. package/out/cli/components/base-actor-sheet-generator.js +125 -0
  31. package/out/cli/components/base-actor-sheet-generator.js.map +1 -0
  32. package/out/cli/components/base-sheet-generator.js +525 -0
  33. package/out/cli/components/base-sheet-generator.js.map +1 -0
  34. package/out/cli/components/chat-card-generator.js +683 -0
  35. package/out/cli/components/chat-card-generator.js.map +1 -0
  36. package/out/cli/components/css-generator.js +58 -0
  37. package/out/cli/components/css-generator.js.map +1 -0
  38. package/out/cli/components/damage-roll-generator.js +173 -0
  39. package/out/cli/components/damage-roll-generator.js.map +1 -0
  40. package/out/cli/components/datamodel-generator.js +672 -0
  41. package/out/cli/components/datamodel-generator.js.map +1 -0
  42. package/out/cli/components/derived-data-generator.js +1340 -0
  43. package/out/cli/components/derived-data-generator.js.map +1 -0
  44. package/out/cli/components/hotbar-drop-hook-generator.js +95 -0
  45. package/out/cli/components/hotbar-drop-hook-generator.js.map +1 -0
  46. package/out/cli/components/init-hook-generator.js +597 -0
  47. package/out/cli/components/init-hook-generator.js.map +1 -0
  48. package/out/cli/components/keywords-generator.js +220 -0
  49. package/out/cli/components/keywords-generator.js.map +1 -0
  50. package/out/cli/components/language-generator.js +110 -0
  51. package/out/cli/components/language-generator.js.map +1 -0
  52. package/out/cli/components/measured-template-preview.js +234 -0
  53. package/out/cli/components/measured-template-preview.js.map +1 -0
  54. package/out/cli/components/method-generator.js +1812 -0
  55. package/out/cli/components/method-generator.js.map +1 -0
  56. package/out/cli/components/ready-hook-generator.js +448 -0
  57. package/out/cli/components/ready-hook-generator.js.map +1 -0
  58. package/out/cli/components/token-generator.js +138 -0
  59. package/out/cli/components/token-generator.js.map +1 -0
  60. package/out/cli/components/utils.js +176 -0
  61. package/out/cli/components/utils.js.map +1 -0
  62. package/out/cli/components/vue/base-components/vue-attribute.js +148 -0
  63. package/out/cli/components/vue/base-components/vue-attribute.js.map +1 -0
  64. package/out/cli/components/vue/base-components/vue-boolean.js +77 -0
  65. package/out/cli/components/vue/base-components/vue-boolean.js.map +1 -0
  66. package/out/cli/components/vue/base-components/vue-calculator.js +106 -0
  67. package/out/cli/components/vue/base-components/vue-calculator.js.map +1 -0
  68. package/out/cli/components/vue/base-components/vue-damage-application.js +369 -0
  69. package/out/cli/components/vue/base-components/vue-damage-application.js.map +1 -0
  70. package/out/cli/components/vue/base-components/vue-damage-bonuses.js +225 -0
  71. package/out/cli/components/vue/base-components/vue-damage-bonuses.js.map +1 -0
  72. package/out/cli/components/vue/base-components/vue-damage-resistances.js +256 -0
  73. package/out/cli/components/vue/base-components/vue-damage-resistances.js.map +1 -0
  74. package/out/cli/components/vue/base-components/vue-damage-track.js +134 -0
  75. package/out/cli/components/vue/base-components/vue-damage-track.js.map +1 -0
  76. package/out/cli/components/vue/base-components/vue-date-time.js +55 -0
  77. package/out/cli/components/vue/base-components/vue-date-time.js.map +1 -0
  78. package/out/cli/components/vue/base-components/vue-dice.js +111 -0
  79. package/out/cli/components/vue/base-components/vue-dice.js.map +1 -0
  80. package/out/cli/components/vue/base-components/vue-die.js +86 -0
  81. package/out/cli/components/vue/base-components/vue-die.js.map +1 -0
  82. package/out/cli/components/vue/base-components/vue-document-choice.js +172 -0
  83. package/out/cli/components/vue/base-components/vue-document-choice.js.map +1 -0
  84. package/out/cli/components/vue/base-components/vue-document-choices.js +203 -0
  85. package/out/cli/components/vue/base-components/vue-document-choices.js.map +1 -0
  86. package/out/cli/components/vue/base-components/vue-document-link.js +73 -0
  87. package/out/cli/components/vue/base-components/vue-document-link.js.map +1 -0
  88. package/out/cli/components/vue/base-components/vue-extended-choice.js +101 -0
  89. package/out/cli/components/vue/base-components/vue-extended-choice.js.map +1 -0
  90. package/out/cli/components/vue/base-components/vue-inventory.js +532 -0
  91. package/out/cli/components/vue/base-components/vue-inventory.js.map +1 -0
  92. package/out/cli/components/vue/base-components/vue-macro-choice.js +150 -0
  93. package/out/cli/components/vue/base-components/vue-macro-choice.js.map +1 -0
  94. package/out/cli/components/vue/base-components/vue-measured-template.js +543 -0
  95. package/out/cli/components/vue/base-components/vue-measured-template.js.map +1 -0
  96. package/out/cli/components/vue/base-components/vue-money.js +496 -0
  97. package/out/cli/components/vue/base-components/vue-money.js.map +1 -0
  98. package/out/cli/components/vue/base-components/vue-number.js +184 -0
  99. package/out/cli/components/vue/base-components/vue-number.js.map +1 -0
  100. package/out/cli/components/vue/base-components/vue-paperdoll.js +56 -0
  101. package/out/cli/components/vue/base-components/vue-paperdoll.js.map +1 -0
  102. package/out/cli/components/vue/base-components/vue-parent-property-reference.js +89 -0
  103. package/out/cli/components/vue/base-components/vue-parent-property-reference.js.map +1 -0
  104. package/out/cli/components/vue/base-components/vue-prosemirror.js +31 -0
  105. package/out/cli/components/vue/base-components/vue-prosemirror.js.map +1 -0
  106. package/out/cli/components/vue/base-components/vue-resource.js +149 -0
  107. package/out/cli/components/vue/base-components/vue-resource.js.map +1 -0
  108. package/out/cli/components/vue/base-components/vue-roll-visualizer.js +121 -0
  109. package/out/cli/components/vue/base-components/vue-roll-visualizer.js.map +1 -0
  110. package/out/cli/components/vue/base-components/vue-self-property-reference.js +75 -0
  111. package/out/cli/components/vue/base-components/vue-self-property-reference.js.map +1 -0
  112. package/out/cli/components/vue/base-components/vue-string-choice.js +111 -0
  113. package/out/cli/components/vue/base-components/vue-string-choice.js.map +1 -0
  114. package/out/cli/components/vue/base-components/vue-string-choices.js +216 -0
  115. package/out/cli/components/vue/base-components/vue-string-choices.js.map +1 -0
  116. package/out/cli/components/vue/base-components/vue-string.js +73 -0
  117. package/out/cli/components/vue/base-components/vue-string.js.map +1 -0
  118. package/out/cli/components/vue/base-components/vue-text-field.js +66 -0
  119. package/out/cli/components/vue/base-components/vue-text-field.js.map +1 -0
  120. package/out/cli/components/vue/base-components/vue-tracker.js +444 -0
  121. package/out/cli/components/vue/base-components/vue-tracker.js.map +1 -0
  122. package/out/cli/components/vue/vue-action-component-generator.js +88 -0
  123. package/out/cli/components/vue/vue-action-component-generator.js.map +1 -0
  124. package/out/cli/components/vue/vue-active-effect-sheet-generator.js +1016 -0
  125. package/out/cli/components/vue/vue-active-effect-sheet-generator.js.map +1 -0
  126. package/out/cli/components/vue/vue-base-components-generator.js +59 -0
  127. package/out/cli/components/vue/vue-base-components-generator.js.map +1 -0
  128. package/out/cli/components/vue/vue-datatable-component-generator.js +307 -0
  129. package/out/cli/components/vue/vue-datatable-component-generator.js.map +1 -0
  130. package/out/cli/components/vue/vue-datatable-sheet-class-generator.js +342 -0
  131. package/out/cli/components/vue/vue-datatable-sheet-class-generator.js.map +1 -0
  132. package/out/cli/components/vue/vue-datatable2-component-generator.js +939 -0
  133. package/out/cli/components/vue/vue-datatable2-component-generator.js.map +1 -0
  134. package/out/cli/components/vue/vue-document-creation-app.js +140 -0
  135. package/out/cli/components/vue/vue-document-creation-app.js.map +1 -0
  136. package/out/cli/components/vue/vue-document-creation-sheet.js +105 -0
  137. package/out/cli/components/vue/vue-document-creation-sheet.js.map +1 -0
  138. package/out/cli/components/vue/vue-generator.js +240 -0
  139. package/out/cli/components/vue/vue-generator.js.map +1 -0
  140. package/out/cli/components/vue/vue-mixin.js +338 -0
  141. package/out/cli/components/vue/vue-mixin.js.map +1 -0
  142. package/out/cli/components/vue/vue-pinned-datatable-component-generator.js +306 -0
  143. package/out/cli/components/vue/vue-pinned-datatable-component-generator.js.map +1 -0
  144. package/out/cli/components/vue/vue-prompt-generator.js +201 -0
  145. package/out/cli/components/vue/vue-prompt-generator.js.map +1 -0
  146. package/out/cli/components/vue/vue-prompt-sheet-class-generator.js +252 -0
  147. package/out/cli/components/vue/vue-prompt-sheet-class-generator.js.map +1 -0
  148. package/out/cli/components/vue/vue-sheet-application-generator.js +2008 -0
  149. package/out/cli/components/vue/vue-sheet-application-generator.js.map +1 -0
  150. package/out/cli/components/vue/vue-sheet-class-generator.js +484 -0
  151. package/out/cli/components/vue/vue-sheet-class-generator.js.map +1 -0
  152. package/out/cli/generator.js +659 -0
  153. package/out/cli/generator.js.map +1 -0
  154. package/out/cli/main.js +43 -0
  155. package/out/cli/main.js.map +1 -0
  156. package/out/datatables.min.css +54 -0
  157. package/out/datatables.min.js +178 -0
  158. package/out/extension/github/githubAuthProvider.js +345 -0
  159. package/out/extension/github/githubAuthProvider.js.map +1 -0
  160. package/out/extension/github/githubConfig.js +132 -0
  161. package/out/extension/github/githubConfig.js.map +1 -0
  162. package/out/extension/github/githubGistActions.js +251 -0
  163. package/out/extension/github/githubGistActions.js.map +1 -0
  164. package/out/extension/github/githubGistManager.js +255 -0
  165. package/out/extension/github/githubGistManager.js.map +1 -0
  166. package/out/extension/github/githubManager.js +1735 -0
  167. package/out/extension/github/githubManager.js.map +1 -0
  168. package/out/extension/github/githubQuickActions.js +659 -0
  169. package/out/extension/github/githubQuickActions.js.map +1 -0
  170. package/out/extension/github/githubTreeProvider.js +181 -0
  171. package/out/extension/github/githubTreeProvider.js.map +1 -0
  172. package/out/extension/github/system-workflow.yml +48 -0
  173. package/out/extension/main.cjs +70315 -0
  174. package/out/extension/main.cjs.map +7 -0
  175. package/out/extension/main.js +237 -0
  176. package/out/extension/main.js.map +1 -0
  177. package/out/extension/package.json +426 -0
  178. package/out/isdl.png +0 -0
  179. package/out/language/generated/ast.js +2992 -0
  180. package/out/language/generated/ast.js.map +1 -0
  181. package/out/language/generated/grammar.js +13970 -0
  182. package/out/language/generated/grammar.js.map +1 -0
  183. package/out/language/generated/module.js +20 -0
  184. package/out/language/generated/module.js.map +1 -0
  185. package/out/language/intelligent-system-design-language-formatter.js +85 -0
  186. package/out/language/intelligent-system-design-language-formatter.js.map +1 -0
  187. package/out/language/intelligent-system-design-language-module.js +69 -0
  188. package/out/language/intelligent-system-design-language-module.js.map +1 -0
  189. package/out/language/intelligent-system-design-language-quickfixes.js +37 -0
  190. package/out/language/intelligent-system-design-language-quickfixes.js.map +1 -0
  191. package/out/language/intelligent-system-design-language-validator.js +515 -0
  192. package/out/language/intelligent-system-design-language-validator.js.map +1 -0
  193. package/out/language/isdl-hover-provider.js +77 -0
  194. package/out/language/isdl-hover-provider.js.map +1 -0
  195. package/out/language/isdl-scope-provider.js +149 -0
  196. package/out/language/isdl-scope-provider.js.map +1 -0
  197. package/out/language/main.cjs +47655 -0
  198. package/out/language/main.cjs.map +7 -0
  199. package/out/language/main.js +11 -0
  200. package/out/language/main.js.map +1 -0
  201. package/out/missing-character.png +0 -0
  202. package/out/package.json +426 -0
  203. package/out/paperdoll_default.png +0 -0
  204. package/out/progressbar.min.js +7 -0
  205. package/out/styles.scss +722 -0
  206. package/out/test/formatting/formatter.test.js +46 -0
  207. package/out/test/formatting/formatter.test.js.map +1 -0
  208. package/out/vuetify.esm.js +30279 -0
  209. package/package.json +426 -0
@@ -0,0 +1,2008 @@
1
+ import * as path from 'node:path';
2
+ import * as fs from 'node:fs';
3
+ import { expandToNode, joinToNode, toString } from 'langium/generate';
4
+ import { isAccess, isAction, isActor, isAttributeExp, isAttributeParamMod, isAttributeRollParam, isAttributeStyleParam, isBackgroundParam, isBooleanExp, isBooleanParamValue, isChoiceCustomProperty, isChoiceStringValue, isColorParam, isColumn, isDateExp, isDateTimeExp, isDiceField, isDiceFields, isDieChoicesParam, isDieNoneParam, isDieField, isDocumentChoiceExp, isDocumentChoicesExp, isEntry, isHtmlExp, isIconParam, isImageParam, isLabelParam, isMacroField, isMeasuredTemplateField, isDamageBonusesField, isDamageResistancesField, isPinnedField, isMoneyField, isDamageTrackExp, isDamageTrackTypesParam, isMethodBlock, isNumberExp, isNumberParamMax, isNumberParamMin, isNumberParamValue, isNumberParamCalculator, isPage, isPaperDollExp, isParentPropertyRefChoiceParam, isParentPropertyRefExp, isSelfPropertyRefExp, isProperty, isResourceExp, isRow, isSection, isSegmentsParameter, isSingleDocumentExp, isSizeParam, isStatusProperty, isStringChoiceField, isDamageTypeChoiceField, isStringChoicesField, isStringExp, isStringExtendedChoice, isStringParamChoices, isStringParamValue, isTableField, isTimeExp, isTrackerExp, isTrackerStyleParameter, isVisibilityParam, isInventoryField, isInventorySlotsParam, isInventoryRowsParam, isInventoryColumnsParam, isInventorySlotSizeParam, isInventoryQuantityParam, isInventoryMoneyParam, isInventorySumParam, isInventorySumMaxParam, isInventorySortParam, isInventoryEmptySlotsParam, isInventorySummaryParam, isWhereParam, isGlobalParam } from "../../../language/generated/ast.js";
5
+ import { getAllOfType, getDocument, getSystemPath, globalGetAllOfType, toMachineIdentifier } from '../utils.js';
6
+ import { AstUtils } from 'langium';
7
+ import { generateActionComponent } from './vue-action-component-generator.js';
8
+ import { generatePinnedVuetifyDatatableComponent } from './vue-pinned-datatable-component-generator.js';
9
+ // import {generateDocumentChoiceComponent} from './vue-document-choice-component-generator.js';
10
+ import { generateDocumentChoicesComponent } from './base-components/vue-document-choices.js';
11
+ import { translateBodyExpressionToJavascript, translateExpression } from '../method-generator.js';
12
+ import { humanize } from "inflection";
13
+ import { generateVuetifyDatatableComponent } from "./vue-datatable2-component-generator.js";
14
+ import { generateDocumentChoiceComponent } from "./base-components/vue-document-choice.js";
15
+ export function generateDocumentVueComponent(entry, id, document, destination) {
16
+ const type = isActor(document) ? 'actor' : 'item';
17
+ const generatedFileDir = path.join(destination, "system", "templates", "vue", type, document.name.toLowerCase());
18
+ const generatedFilePath = path.join(generatedFileDir, `${document.name.toLowerCase()}App.vue`);
19
+ if (!fs.existsSync(generatedFileDir)) {
20
+ fs.mkdirSync(generatedFileDir, { recursive: true });
21
+ }
22
+ const fileNode = expandToNode `
23
+ ${generateVueComponentScript(entry, id, document, destination)}
24
+ ${generateVueComponentTemplate(entry, id, document)}
25
+ `.appendNewLineIfNotEmpty();
26
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
27
+ }
28
+ function generateVueComponentScript(entry, id, document, destination) {
29
+ const pages = getAllOfType(document.body, isPage);
30
+ const actions = getAllOfType(document.body, isAction, false);
31
+ const paperDoll = getAllOfType(document.body, isPaperDollExp);
32
+ const documentChoices = getAllOfType(document.body, isDocumentChoiceExp);
33
+ const documentChoicesPlural = getAllOfType(document.body, isDocumentChoicesExp);
34
+ const firstPagePinned = document.body.filter(isPinnedField);
35
+ function getPageBackground(page) {
36
+ var _a, _b, _c;
37
+ const background = (_c = (_b = (_a = page.params) === null || _a === void 0 ? void 0 : _a.find(x => isBackgroundParam(x))) === null || _b === void 0 ? void 0 : _b.background) !== null && _c !== void 0 ? _c : 'topography';
38
+ return `'${page.name.toLowerCase()}': '${background}'`;
39
+ }
40
+ //let tables = getAllOfType<TableField>(document.body, isTableField, true);
41
+ let allTables = getAllOfType(document.body, isTableField, false);
42
+ function importDataTable2(table) {
43
+ const page = AstUtils.getContainerOfType(table, isPage);
44
+ const pageName = page ? page.name : document.name;
45
+ generateVuetifyDatatableComponent(id, document, pageName, table, destination);
46
+ return expandToNode `
47
+ import ${document.name}${pageName}${table.name}VuetifyDatatable from './components/datatables/${document.name.toLowerCase()}${pageName}${table.name}VuetifyDatatable.vue';
48
+ `;
49
+ }
50
+ function importEffectsDataTable() {
51
+ generateEffectsVuetifyDatatableComponent(id, document, destination);
52
+ return expandToNode `
53
+ import ${document.name}EffectsVuetifyDatatable from './components/datatables/${document.name.toLowerCase()}EffectsVuetifyDatatable.vue';
54
+ `;
55
+ }
56
+ function importPinnedDataTable(pinnedField) {
57
+ generatePinnedVuetifyDatatableComponent(id, document, pinnedField, destination, entry);
58
+ const page = AstUtils.getContainerOfType(pinnedField, isPage);
59
+ const pageName = page ? page.name : document.name;
60
+ return expandToNode `
61
+ import ${document.name}${pageName}${pinnedField.name}VuetifyDatatable from './components/datatables/${document.name.toLowerCase()}${pageName}${pinnedField.name}VuetifyDatatable.vue';
62
+ `;
63
+ }
64
+ function generateEffectsVuetifyDatatableComponent(id, document, destination) {
65
+ const type = isActor(document) ? 'actor' : 'item';
66
+ const generatedFileDir = path.join(destination, "system", "templates", "vue", type, document.name.toLowerCase(), "components", "datatables");
67
+ const generatedFilePath = path.join(generatedFileDir, `${document.name.toLowerCase()}EffectsVuetifyDatatable.vue`);
68
+ if (!fs.existsSync(generatedFileDir)) {
69
+ fs.mkdirSync(generatedFileDir, { recursive: true });
70
+ }
71
+ const fileNode = expandToNode `
72
+ <script setup>
73
+ import { ref, computed, inject, onMounted } from "vue";
74
+
75
+ const props = defineProps({
76
+ context: Object,
77
+ primaryColor: String,
78
+ secondaryColor: String,
79
+ tertiaryColor: String
80
+ });
81
+
82
+ const document = inject('rawDocument');
83
+ const search = ref('');
84
+ const loading = ref(false);
85
+
86
+ const data = ref([]);
87
+
88
+ function updateEffects() {
89
+ data.value = Array.from(document.allApplicableEffects());
90
+ }
91
+
92
+ updateEffects();
93
+
94
+ Hooks.on("createActiveEffect", updateEffects);
95
+ Hooks.on("updateActiveEffect", updateEffects);
96
+ Hooks.on("deleteActiveEffect", updateEffects);
97
+
98
+ const headers = [
99
+ {
100
+ title: game.i18n.localize("Image"),
101
+ key: 'img',
102
+ sortable: false,
103
+ width: '50px',
104
+ maxWidth: '50px'
105
+ },
106
+ {
107
+ title: game.i18n.localize("Name"),
108
+ key: 'name',
109
+ sortable: true,
110
+ minWidth: '120px'
111
+ },
112
+ {
113
+ title: game.i18n.localize("Source"),
114
+ key: 'source',
115
+ sortable: true,
116
+ minWidth: '120px'
117
+ },
118
+ {
119
+ title: game.i18n.localize("Duration"),
120
+ key: 'duration',
121
+ sortable: true,
122
+ minWidth: '100px'
123
+ },
124
+ {
125
+ title: game.i18n.localize("Actions"),
126
+ key: 'actions',
127
+ sortable: false,
128
+ width: '150px',
129
+ align: 'center'
130
+ }
131
+ ];
132
+
133
+ const editItem = (item) => {
134
+ const foundryItem = document.effects.get(item._id);
135
+ foundryItem.sheet.render(true);
136
+ };
137
+
138
+ const toggleEffect = async (item) => {
139
+ const update = {
140
+ _id: item._id,
141
+ disabled: !item.disabled
142
+ };
143
+ item.disabled = !item.disabled;
144
+ document.updateEmbeddedDocuments("ActiveEffect", [update]);
145
+ };
146
+
147
+ const deleteEffect = async (item) => {
148
+ const shouldDelete = await Dialog.confirm({
149
+ title: "Delete Confirmation",
150
+ content: \`<p>Are you sure you would like to delete the "\${item.name}" Effect?</p>\`,
151
+ defaultYes: false
152
+ });
153
+ if (shouldDelete) {
154
+ await document.deleteEmbeddedDocuments("ActiveEffect", [item.id]);
155
+ // Don't call updateEffects() here as the Hooks will handle it
156
+ };
157
+ };
158
+
159
+ const addNewEffect = async () => {
160
+ loading.value = true;
161
+ try {
162
+ const effects = await ActiveEffect.createDocuments([{
163
+ name: "New Effect",
164
+ icon: "icons/svg/aura.svg"
165
+ }], {parent: document});
166
+
167
+ if (effects && effects[0]) {
168
+ effects[0].sheet.render(true);
169
+ updateEffects();
170
+ }
171
+ } catch (error) {
172
+ console.error("Error creating effect:", error);
173
+ ui.notifications.error("Failed to create new effect");
174
+ } finally {
175
+ loading.value = false;
176
+ }
177
+ };
178
+
179
+ const formatDuration = (effect) => {
180
+ if (!effect.duration) return "Permanent";
181
+ if (effect.duration.type === "none") return "Permanent";
182
+ if (effect.duration.type === "turns") {
183
+ return \`\${effect.duration.remaining} turns\`;
184
+ }
185
+ if (effect.duration.type === "seconds") {
186
+ return \`\${effect.duration.remaining} seconds\`;
187
+ }
188
+ return "Temporary";
189
+ };
190
+ </script>
191
+
192
+ <template>
193
+ <v-card flat class="isdl-datatable">
194
+ <v-card-title class="d-flex align-center pe-1" style="height: 40px;">
195
+ <v-icon icon="fa-solid fa-sparkles" size="small" />
196
+ &nbsp; {{ game.i18n.localize("Effects") }}
197
+ <v-spacer></v-spacer>
198
+ <v-text-field
199
+ v-model="search"
200
+ density="compact"
201
+ label="Search"
202
+ prepend-inner-icon="fa-solid fa-magnify"
203
+ variant="outlined"
204
+ flat
205
+ hide-details
206
+ single-line
207
+ clearable
208
+ style="margin: 0; margin-right: 8px;"
209
+ ></v-text-field>
210
+ <v-btn
211
+ :color="primaryColor || 'primary'"
212
+ prepend-icon="fa-solid fa-plus"
213
+ rounded="0"
214
+ size="small"
215
+ :loading="loading"
216
+ @click="addNewEffect"
217
+ style="max-width: 80px; height: 38px;"
218
+ >
219
+ {{ game.i18n.localize("Add") }}
220
+ </v-btn>
221
+ </v-card-title>
222
+ <v-divider></v-divider>
223
+
224
+ <v-data-table
225
+ v-model:search="search"
226
+ :headers="headers"
227
+ :items="data"
228
+ :search="search"
229
+ hover
230
+ density="compact"
231
+ hide-default-footer
232
+ style="background: none;"
233
+ class="custom-datatable"
234
+ >
235
+ <!-- Image slot -->
236
+ <template v-slot:item.img="{ item }">
237
+ <v-avatar size="40" rounded="0">
238
+ <v-img :src="item.img ?? item.icon" :alt="item.name" cover></v-img>
239
+ </v-avatar>
240
+ </template>
241
+
242
+ <!-- Name slot -->
243
+ <template v-slot:item.name="{ item }">
244
+ <div class="d-flex align-center">
245
+ <div class="font-weight-medium text-truncate" style="min-width: 120px; max-width: 200px;">{{ item.name }}</div>
246
+ </div>
247
+ </template>
248
+
249
+ <!-- Source slot -->
250
+ <template v-slot:item.source="{ item }">
251
+ <v-chip
252
+ label
253
+ size="x-small"
254
+ variant="elevated"
255
+ class="text-caption text-truncate"
256
+ style="max-width: 150px;"
257
+ :data-tooltip="item.flags?.['${id}']?.source || 'Unknown'">
258
+ {{ item.flags?.['${id}']?.source || 'Unknown' }}
259
+ </v-chip>
260
+ </template>
261
+
262
+ <!-- Duration slot -->
263
+ <template v-slot:item.duration="{ item }">
264
+ <v-chip
265
+ label
266
+ size="x-small"
267
+ variant="elevated"
268
+ class="text-caption"
269
+ :color="item.duration?.type === 'none' ? 'primary' : 'secondary'"
270
+ >
271
+ {{ formatDuration(item) }}
272
+ </v-chip>
273
+ </template>
274
+
275
+ <!-- Actions slot -->
276
+ <template v-slot:item.actions="{ item }">
277
+ <div class="d-flex align-center justify-center ga-1">
278
+ <v-tooltip :text="item.disabled ? 'Enable' : 'Disable'">
279
+ <template v-slot:activator="{ props }">
280
+ <v-btn
281
+ v-bind="props"
282
+ :icon="item.disabled ? 'fa-solid fa-pause' : 'fa-solid fa-play'"
283
+ size="x-small"
284
+ variant="text"
285
+ :color="item.disabled ? 'warning' : 'success'"
286
+ @click="toggleEffect(item)"
287
+ ></v-btn>
288
+ </template>
289
+ </v-tooltip>
290
+ <v-tooltip text="Edit">
291
+ <template v-slot:activator="{ props }">
292
+ <v-btn
293
+ v-bind="props"
294
+ icon="fa-solid fa-edit"
295
+ size="x-small"
296
+ variant="text"
297
+ @click="editItem(item)"
298
+ ></v-btn>
299
+ </template>
300
+ </v-tooltip>
301
+ <v-tooltip text="Delete">
302
+ <template v-slot:activator="{ props }">
303
+ <v-btn
304
+ v-bind="props"
305
+ icon="fa-solid fa-trash"
306
+ size="x-small"
307
+ variant="text"
308
+ color="error"
309
+ @click="deleteEffect(item)"
310
+ ></v-btn>
311
+ </template>
312
+ </v-tooltip>
313
+ </div>
314
+ </template>
315
+
316
+ <!-- No data slot -->
317
+ <template v-slot:no-data>
318
+ <div class="text-center pa-4">
319
+ <v-icon size="48" color="grey-lighten-1">fa-solid fa-magic</v-icon>
320
+ <div class="text-h6 mt-2">No effects found</div>
321
+ <div class="text-body-2 text-medium-emphasis">
322
+ Add your first effect to get started
323
+ </div>
324
+ </div>
325
+ </template>
326
+ </v-data-table>
327
+ </v-card>
328
+ </template>
329
+ `;
330
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
331
+ }
332
+ function importPageOfPinnedDataTable(page) {
333
+ const pinned = getAllOfType(page.body, isPinnedField, true);
334
+ return expandToNode `
335
+ ${joinToNode(pinned, pinnedField => importPinnedDataTable(pinnedField), { appendNewLineIfNotEmpty: true })}
336
+ `;
337
+ }
338
+ function importActionComponent(action) {
339
+ generateActionComponent(entry, id, document, action, destination);
340
+ const componentName = `${document.name.toLowerCase()}${action.name}Action`;
341
+ return expandToNode `
342
+ import ${componentName} from './components/actions/${componentName}.vue';
343
+ `;
344
+ }
345
+ function importDocumentChoiceComponent(documentChoice) {
346
+ generateDocumentChoiceComponent(entry, id, document, documentChoice, destination);
347
+ const componentName = `${document.name.toLowerCase()}${documentChoice.name}DocumentChoice`;
348
+ return expandToNode `
349
+ import ${componentName} from './components/document-choices/${componentName}.vue';
350
+ `;
351
+ }
352
+ function importDocumentChoicesComponent(documentChoices) {
353
+ generateDocumentChoicesComponent(entry, id, document, documentChoices, destination);
354
+ const componentName = `${document.name.toLowerCase()}${documentChoices.name}DocumentChoices`;
355
+ return expandToNode `
356
+ import ${componentName} from './components/document-choices/${componentName}.vue';
357
+ `;
358
+ }
359
+ function paperDollSlots(element) {
360
+ var _a, _b, _c;
361
+ let slots = [];
362
+ for (const property of element.elements) {
363
+ slots.push({
364
+ name: property.name,
365
+ systemPath: `system.${element.name.toLowerCase()}.${property.name.toLowerCase()}`,
366
+ type: (_a = property.document.ref) === null || _a === void 0 ? void 0 : _a.name.toLowerCase(),
367
+ left: (_b = property.left) !== null && _b !== void 0 ? _b : "0px",
368
+ top: (_c = property.top) !== null && _c !== void 0 ? _c : "0px",
369
+ });
370
+ }
371
+ return expandToNode `
372
+ const ${element.name.toLowerCase()}Slots = [
373
+ ${joinToNode(slots, slot => expandToNode `
374
+ {
375
+ name: '${slot.name}',
376
+ systemPath: '${slot.systemPath}',
377
+ type: '${slot.type}',
378
+ left: '${slot.left}',
379
+ top: '${slot.top}'
380
+ }`, { separator: ',', appendNewLineIfNotEmpty: true })}
381
+ ];
382
+ `;
383
+ }
384
+ const properties = getAllOfType(document.body, isProperty, false);
385
+ function isComputedField(element) {
386
+ if (isStringExp(element)) {
387
+ return element.params.find(isStringParamValue) !== undefined;
388
+ }
389
+ if (isBooleanExp(element)) {
390
+ return element.params.find(isBooleanParamValue) !== undefined;
391
+ }
392
+ if (isNumberExp(element) || isAttributeExp(element) || isResourceExp(element) || isTrackerExp(element) || isMoneyField(element)) {
393
+ const numberParams = element.params;
394
+ return numberParams.find(isNumberParamValue) !== undefined;
395
+ }
396
+ return false;
397
+ }
398
+ function generateVisibilityState(element) {
399
+ var _a;
400
+ if (isProperty(element) || isAction(element)) {
401
+ const standardParams = element.params;
402
+ const visibilityParam = standardParams.find(function (p) {
403
+ return isVisibilityParam(p);
404
+ });
405
+ // If there's only a modifier and no visibility param, return the modifier
406
+ if (element.modifier != undefined && !visibilityParam) {
407
+ return expandToNode `
408
+ '${element.name.toLowerCase()}': computed(() => {
409
+ return '${element.modifier}';
410
+ })
411
+ `;
412
+ }
413
+ if (visibilityParam) {
414
+ if (isMethodBlock(visibilityParam.visibility)) {
415
+ // If the visibility is a method block, we need to return a function that returns the visibility
416
+ return expandToNode `
417
+ '${element.name.toLowerCase()}': computed(() => {
418
+ let editMode = editModeRef.value;
419
+ let combatant = currentCombatant.value; // This will kick the recalc when changed
420
+ let update = {};
421
+ let embeddedUpdate = {};
422
+ let parentUpdate = {};
423
+ let parentEmbeddedUpdate = {};
424
+ let targetUpdate = {};
425
+ let targetEmbeddedUpdate = {};
426
+ let selfDeleted = false;
427
+ let rerender = false;
428
+ const context = {
429
+ object: document,
430
+ target: game.user.getTargetOrNothing()
431
+ };
432
+ // If this is an item, attach the parent
433
+ if (document.documentName === "Item" && document.parent) {
434
+ context.actor = document.parent;
435
+ }
436
+ else {
437
+ context.actor = document;
438
+ }
439
+ const visibility = (system) => {
440
+ ${translateBodyExpressionToJavascript(entry, id, visibilityParam.visibility.body, false, element)}
441
+ };
442
+ const returnedVisibility = visibility(props.context.system);
443
+ console.log("Returned visibility for ${element.name}: " + returnedVisibility);
444
+
445
+ return returnedVisibility ?? "${(_a = element.modifier) !== null && _a !== void 0 ? _a : 'default'}";
446
+ })
447
+ `;
448
+ }
449
+ return expandToNode `
450
+ '${element.name.toLowerCase()}': computed(() => {
451
+ return '${visibilityParam.visibility}';
452
+ })
453
+ `;
454
+ }
455
+ }
456
+ return expandToNode `
457
+ '${element.name.toLowerCase()}': computed(() => {
458
+ return 'default';
459
+ })
460
+ `;
461
+ }
462
+ const attributes = getAllOfType(document.body, isAttributeExp, false);
463
+ function generateAttributeRollMethod(attribute) {
464
+ const rollParam = attribute.params.find(isAttributeRollParam);
465
+ if (rollParam) {
466
+ return expandToNode `
467
+ const on${toMachineIdentifier(attribute.name)}AttributeRoll = async () => {
468
+ const context = {
469
+ object: document
470
+ };
471
+ const roll = ${translateExpression(entry, id, rollParam.roll, false, attribute)};
472
+ // Create the chat message
473
+ const ${attribute.name}Description = context.object.description ?? context.object.system.description;
474
+ const ${attribute.name}Context = {
475
+ cssClass: "${id} ${toMachineIdentifier(attribute.name)}",
476
+ document: context.object,
477
+ description: ${attribute.name}Description,
478
+ hasDescription: ${attribute.name}Description!= "",
479
+ parts: [
480
+ {
481
+ label: "${humanize(attribute.name)} Attribute Roll",
482
+ value: roll,
483
+ isRoll: true,
484
+ wide: true,
485
+ tooltip: await roll.getTooltip()
486
+ }
487
+ ],
488
+ tags: []
489
+ };
490
+ const ${attribute.name}Content = await renderTemplate("systems/${id}/system/templates/chat/standard-card.hbs", ${attribute.name}Context);
491
+ await ChatMessage.create({
492
+ user: game.user._id,
493
+ speaker: ChatMessage.getSpeaker(),
494
+ content: ${attribute.name}Content,
495
+ flavor: "",
496
+ type: ${attribute.name}Context.parts.find(x => x.isRoll) ? null : CONST.CHAT_MESSAGE_STYLES.IC,
497
+ rolls: Array.from(${attribute.name}Context.parts.filter(x => x.isRoll).map(x => x.value)),
498
+ });
499
+ };
500
+ `;
501
+ }
502
+ return expandToNode ``;
503
+ }
504
+ return expandToNode `
505
+ <script setup>
506
+ import { ref, watch, inject, computed, watchEffect } from "vue";
507
+ ${joinToNode(allTables, table => importDataTable2(table), { appendNewLineIfNotEmpty: true })}
508
+ ${joinToNode(pages, importPageOfPinnedDataTable, { appendNewLineIfNotEmpty: true })}
509
+ ${joinToNode(actions, importActionComponent, { appendNewLineIfNotEmpty: true })}
510
+ ${joinToNode(documentChoices, importDocumentChoiceComponent, { appendNewLineIfNotEmpty: true })}
511
+ ${joinToNode(documentChoicesPlural, importDocumentChoicesComponent, { appendNewLineIfNotEmpty: true })}
512
+ ${importEffectsDataTable()}
513
+ ${joinToNode(firstPagePinned, (pinned) => importPinnedDataTable(pinned), { appendNewLineIfNotEmpty: true })}
514
+ import ${entry.config.name}Roll from "../../../../rolls/roll.mjs";
515
+
516
+ const document = inject('rawDocument');
517
+ const props = defineProps(['context']);
518
+
519
+ // Colors
520
+ let storedColors = game.settings.get('${id}', 'documentColorThemes');
521
+ const primaryColor = ref(storedColors[document.uuid]?.primary ?? '#1565c0');
522
+ const secondaryColor = ref(storedColors[document.uuid]?.secondary ?? '#4db6ac');
523
+ const tertiaryColor = ref(storedColors[document.uuid]?.tertiary ?? '#ffb74d');
524
+
525
+ const setupColors = () => {
526
+ const colors = {
527
+ primary: primaryColor.value,
528
+ secondary: secondaryColor.value,
529
+ tertiary: tertiaryColor.value
530
+ };
531
+ game.settings.set('${id}', 'documentColorThemes', { ...storedColors, [document.uuid]: colors });
532
+ };
533
+ const resetColors = () => {
534
+ primaryColor.value = '#1565c0';
535
+ secondaryColor.value = '#4db6ac';
536
+ teritaryColor.value = '#ffb74d';
537
+ setupColors();
538
+ };
539
+
540
+ watch(primaryColor, () => {
541
+ setupColors();
542
+ });
543
+ watch(secondaryColor, () => {
544
+ setupColors();
545
+ });
546
+ watch(tertiaryColor, () => {
547
+ setupColors();
548
+ });
549
+
550
+ // Pages and Tabs
551
+ const lastStates = game.settings.get('${id}', 'documentLastState');
552
+ const lastState = lastStates[document.uuid] ?? {
553
+ page: '${document.name.toLowerCase()}',
554
+ tab: 'description'
555
+ };
556
+
557
+ const drawer = ref(false);
558
+ const page = ref(lastState.page);
559
+ const tab = ref(lastState.tab);
560
+ const pageDefaultTabs = {
561
+ '${document.name.toLowerCase()}': 'description'
562
+ };
563
+
564
+ const updateLastState = () => {
565
+ const lastStates = game.settings.get('${id}', 'documentLastState');
566
+ lastStates[document.uuid] = { page: page.value, tab: tab.value };
567
+ game.settings.set('${id}', 'documentLastState', lastStates);
568
+ };
569
+
570
+ // When the page changes, reset the tab to the first tab on that page
571
+ watch(page, () => {
572
+ tab.value = pageDefaultTabs[page.value.toLowerCase()];
573
+ document.sheet.dragDrop.forEach((d) => d.bind(document.sheet.element));
574
+ // Dismiss the drawer when the page changes
575
+ drawer.value = false;
576
+ updateLastState();
577
+ });
578
+
579
+ watch(tab, () => {
580
+ try {
581
+ if (document.sheet?.element) {
582
+ document.sheet.dragDrop.forEach((d) => d.bind(document.sheet.element));
583
+ }
584
+ }
585
+ catch {}
586
+ updateLastState();
587
+ });
588
+
589
+ const pageBackgrounds = {
590
+ '${document.name.toLowerCase()}': 'topography',
591
+ ${joinToNode(pages, getPageBackground, { separator: ',', appendNewLineIfNotEmpty: true })}
592
+ };
593
+
594
+ const pageBackground = computed(() => {
595
+ if (editModeRef.value) {
596
+ return 'edit-mode';
597
+ }
598
+ if (props.context.system.dead) {
599
+ return 'dead';
600
+ }
601
+ return pageBackgrounds[page.value];
602
+ });
603
+
604
+ // Edit Mode
605
+ const editModeRef = ref(document.getFlag('${id}', 'edit-mode') ?? true);
606
+ const hovered = ref(false);
607
+
608
+ const toggleEditMode = () => {
609
+ editModeRef.value = !editModeRef.value;
610
+ document.setFlag('${id}', 'edit-mode', editModeRef.value);
611
+ };
612
+
613
+ function spawnDatatableWindow(e, pageName, tabName) {
614
+ if (event.button === 1) {
615
+ event.preventDefault();
616
+ event.stopPropagation();
617
+ const tableName = \`${isActor(document) ? 'actor' : 'item'}${document.name}\${pageName}\${tabName}\`;
618
+ const systemName = "system." + tabName.toLowerCase();
619
+ const sheet = new game.system.datatableApp(document, tableName, systemName, tabName);
620
+ sheet.render(true);
621
+ }
622
+ }
623
+
624
+ // Effects
625
+ const effects = ref([]);
626
+
627
+ function updateEffects() {
628
+ effects.value = Array.from(document.allApplicableEffects());
629
+ }
630
+
631
+ updateEffects();
632
+
633
+ Hooks.on("createActiveEffect", updateEffects);
634
+ Hooks.on("updateActiveEffect", updateEffects);
635
+ Hooks.on("deleteActiveEffect", updateEffects);
636
+
637
+ // Combat
638
+ const currentCombatant = ref(game.combat?.combatant);
639
+ Hooks.on("combatTurnChange", () => {
640
+ currentCombatant.value = game.combat?.combatant;
641
+ });
642
+
643
+ // Paper Doll Slots
644
+ ${joinToNode(paperDoll, paperDollSlots, { appendNewLineIfNotEmpty: true })}
645
+
646
+ // Visibility states
647
+ const visibilityStates = {
648
+ ${joinToNode(properties, generateVisibilityState, { separator: ',', appendNewLineIfNotEmpty: true })},
649
+ ${joinToNode(actions, generateVisibilityState, { separator: ',', appendNewLineIfNotEmpty: true })}
650
+ };
651
+
652
+ // Computed fields mapping
653
+ const computedFields = {
654
+ ${joinToNode(properties, prop => expandToNode `'${prop.name.toLowerCase()}': ${isComputedField(prop)}`, { separator: ',', appendNewLineIfNotEmpty: true })},
655
+ ${joinToNode(actions, action => expandToNode `'${action.name.toLowerCase()}': ${isComputedField(action)}`, { separator: ',', appendNewLineIfNotEmpty: true })}
656
+ };
657
+
658
+
659
+ const isHidden = (type) => {
660
+ const visibility = visibilityStates[type].value;
661
+ if (visibility === "hidden") {
662
+ return true;
663
+ }
664
+ if (visibility === "gmOnly") {
665
+ return !game.user.isGM;
666
+ }
667
+ if (visibility === "secret") {
668
+ const isGm = game.user.isGM;
669
+ const isOwner = document.getUserLevel(game.user) === CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER;
670
+ return !isGm && !isOwner;
671
+ }
672
+ if (visibility === "edit") {
673
+ return !editModeRef.value;
674
+ }
675
+ if (visibility === "play") {
676
+ return editModeRef.value;
677
+ }
678
+
679
+ // Default to visible
680
+ return false;
681
+ };
682
+
683
+ const isDisabled = (type) => {
684
+ // Computed fields are always disabled
685
+ if (computedFields[type]) {
686
+ //console.log(type + " is computed and disabled");
687
+ return true;
688
+ }
689
+
690
+ const visibility = visibilityStates[type].value;
691
+ const disabledStates = ["readonly", "locked"];
692
+ if (disabledStates.includes(visibility)) {
693
+ //console.log(type + " is readonly / locked and disabled");
694
+ return true;
695
+ }
696
+ if (visibility === "gmEdit") {
697
+ const isGm = game.user.isGM;
698
+ const isEditMode = editModeRef.value;
699
+ return !isGm && !isEditMode;
700
+ }
701
+
702
+ if (visibility === "unlocked") {
703
+ //console.log(type + " is unlocked and enabled");
704
+ return false;
705
+ }
706
+
707
+ // Default to enabled while in editMode
708
+ return !editModeRef.value;
709
+ };
710
+
711
+ const getLabel = (label, icon) => {
712
+ const localized = game.i18n.localize(label);
713
+ if (icon) {
714
+ return \`<i class="\${icon}"></i> \${localized}\`;
715
+ }
716
+ return localized;
717
+ };
718
+
719
+ // Attribute roll methods
720
+ ${joinToNode(attributes, generateAttributeRollMethod, { appendNewLineIfNotEmpty: true })}
721
+ </script>
722
+ <style>
723
+ </style>
724
+ `;
725
+ }
726
+ function generateVueComponentTemplate(entry, id, document) {
727
+ const pages = getAllOfType(document.body, isPage);
728
+ const firstPageTables = document.body.filter(isTableField); // We explicitly only want top-level tables
729
+ const firstPagePinned = document.body.filter(isPinnedField); // We explicitly only want top-level pinned fields
730
+ const firstPageInventories = document.body.filter(isInventoryField); // We explicitly only want top-level inventories
731
+ return expandToNode `
732
+ <template>
733
+ <v-app>
734
+ <!-- App Bar -->
735
+ <v-app-bar :color="editModeRef ? 'amber-accent-3' : primaryColor" density="comfortable">
736
+ <v-app-bar-nav-icon @click="drawer = !drawer"></v-app-bar-nav-icon>
737
+ <v-app-bar-title v-if="!editModeRef">{{ context.document.name }}</v-app-bar-title>
738
+ <v-text-field name="name" v-model="context.document.name" variant="outlined" class="document-name" v-if="editModeRef" density="compact"></v-text-field>
739
+ <v-alert :text="game.i18n.localize('EditModeWarning')" type="warning" density="compact" class="ga-2 ma-1" color="amber-accent-3" v-if="editModeRef"></v-alert>
740
+ <template v-slot:append>
741
+ <v-btn
742
+ :icon="hovered ? (editModeRef ? 'fa-solid fa-dice-d20' : 'fa-solid fa-pen-to-square') : (editModeRef ? 'fa-solid fa-pen-to-square' : 'fa-solid fa-dice-d20')"
743
+ @click="toggleEditMode"
744
+ @mouseover="hovered = true"
745
+ @mouseleave="hovered = false"
746
+ :data-tooltip="editModeRef ? 'Swap to Play mode' : 'Swap to Edit mode'"
747
+ ></v-btn>
748
+ </template>
749
+ </v-app-bar>
750
+
751
+ <!-- Navigation Drawer -->
752
+ <v-navigation-drawer v-model="drawer" temporary style="background-color: #dddddd">
753
+ <v-img :src="context.document.img" style="background-color: lightgray" data-edit='img' data-action='onEditImage'>
754
+ <template #error>
755
+ <v-img src="/systems/${id}/img/missing-character.png" data-edit='img' data-action='onEditImage'></v-img>
756
+ </template>
757
+ </v-img>
758
+ <v-tabs v-model="page" direction="vertical">
759
+ <v-tab value="${document.name.toLowerCase()}" prepend-icon="fa-solid fa-circle-user">${document.name}</v-tab>
760
+ ${joinToNode(pages, generateNavListItem, { appendNewLineIfNotEmpty: true })}
761
+ </v-tabs>
762
+ <template v-slot:append>
763
+ <div class="pa-2">
764
+ <v-btn block @click="setupColors" :color="secondaryColor" prepend-icon="fa-solid fa-palette">
765
+ Setup Colors
766
+
767
+ <v-dialog activator="parent" max-width="1000">
768
+ <template v-slot:default="{ isActive }">
769
+ <v-card
770
+ title="Setup Colors"
771
+ >
772
+ <v-card-text>
773
+ <div class="d-flex flex-row">
774
+ <div class="d-flex flex-column">
775
+ <v-label>Primary Color</v-label>
776
+ <v-color-picker hide-inputs hide-sliders hide-canvas show-swatches v-model="primaryColor" swatches-max-height="500px"></v-color-picker>
777
+ </div>
778
+ <v-spacer></v-spacer>
779
+ <div class="d-flex flex-column">
780
+ <v-label>Secondary Color</v-label>
781
+ <v-color-picker hide-inputs hide-sliders hide-canvas show-swatches v-model="secondaryColor" swatches-max-height="500px"></v-color-picker>
782
+ </div>
783
+ <v-spacer></v-spacer>
784
+ <div class="d-flex flex-column">
785
+ <v-label>Tertiary Color</v-label>
786
+ <v-color-picker hide-inputs hide-sliders hide-canvas show-swatches v-model="tertiaryColor" swatches-max-height="500px"></v-color-picker>
787
+ </div>
788
+ </div>
789
+ <h3>Preview</h3>
790
+ <div class="d-flex flex-row"style="overflow-x: scroll; padding-left: 0.5rem; padding-right: 0.5rem;">
791
+ <div
792
+ v-for="i in 10"
793
+ :key="i"
794
+ :style="{
795
+ flex: 1,
796
+ minWidth: '5px',
797
+ flexShrink: 0,
798
+ height: '30px',
799
+ backgroundColor: i <= 4 ? primaryColor : (i <= 6 ? tertiaryColor : 'transparent'),
800
+ border: i <= value ? 'none' : '2px solid ' + secondaryColor,
801
+ transform: 'skewX(-20deg)',
802
+ borderRadius: '2px'
803
+ }"
804
+ />
805
+ </div>
806
+ </v-card-text>
807
+ <v-card-actions>
808
+ <v-btn
809
+ variant="tonal"
810
+ prepend-icon="fa-solid fa-sync"
811
+ text="Reset"
812
+ :color="secondaryColor"
813
+ @click="resetColors"
814
+ ></v-btn>
815
+ </v-card-actions>
816
+ </v-card>
817
+ </template>
818
+ </v-dialog>
819
+ </v-btn>
820
+ </div>
821
+ </template>
822
+ </v-navigation-drawer>
823
+
824
+ <!-- Main Content -->
825
+ <v-main class="d-flex">
826
+ <v-container :key="editModeRef" :class="pageBackground" fluid>
827
+ <v-tabs-window v-model="page">
828
+ <v-tabs-window-item value="${document.name.toLowerCase()}" data-tab="${document.name.toLowerCase()}">
829
+ <v-row dense>
830
+ ${joinToNode(document.body, element => generateElement(element, true), { appendNewLineIfNotEmpty: true })}
831
+ </v-row>
832
+ <v-divider class="mt-4 mb-2"></v-divider>
833
+ <v-tabs v-model="tab" grow always-center>
834
+ <v-tab value="description" prepend-icon="fa-solid fa-book">Description</v-tab>
835
+ ${joinToNode(firstPageTables, table => generateSubTab(table), { appendNewLineIfNotEmpty: true })}
836
+ ${joinToNode(firstPagePinned, (pinned) => generatePinnedTab(pinned), { appendNewLineIfNotEmpty: true })}
837
+ ${joinToNode(firstPageInventories, inventory => generateSubTab(inventory), { appendNewLineIfNotEmpty: true })}
838
+ <v-tab value="effects" prepend-icon="fa-solid fa-sparkles" @mousedown="spawnDatatableWindow($event, '${document.name}', 'effects')">Effects</v-tab>
839
+ </v-tabs>
840
+ <v-tabs-window v-model="tab" class="tabs-window">
841
+ <v-tabs-window-item value="description" data-tab="description" class="tabs-container">
842
+ <i-prosemirror :field="context.editors['system.description']" :disabled="!editModeRef"></i-prosemirror>
843
+ </v-tabs-window-item>
844
+ ${joinToNode(firstPageTables, table => generateVuetifyDatatable(document.name, table), { appendNewLineIfNotEmpty: true })}
845
+ ${joinToNode(firstPagePinned, (pinned) => generatePinnedTabWindow(pinned), { appendNewLineIfNotEmpty: true })}
846
+ ${joinToNode(firstPageInventories, inventory => generateInventoryTabWindow(document.name, inventory), { appendNewLineIfNotEmpty: true })}
847
+ <v-tabs-window-item value="effects" data-tab="effects" class="tabs-container">
848
+ <${document.name}EffectsVuetifyDatatable
849
+ :context="context"
850
+ :primaryColor="primaryColor"
851
+ :secondaryColor="secondaryColor"
852
+ :tertiaryColor="tertiaryColor"
853
+ />
854
+ </v-tabs-window-item>
855
+ </v-tabs-window>
856
+ </v-tabs-window-item>
857
+ ${joinToNode(pages, generatePageBody, { appendNewLineIfNotEmpty: true })}
858
+ </v-tabs-window>
859
+ </v-container>
860
+ </v-main>
861
+ </v-app>
862
+ </template>
863
+ `;
864
+ function generateSubTab(tab) {
865
+ var _a, _b;
866
+ const params = tab.params;
867
+ const iconParam = params.find((p) => isIconParam(p));
868
+ const icon = (_a = iconParam === null || iconParam === void 0 ? void 0 : iconParam.value) !== null && _a !== void 0 ? _a : "fa-solid fa-table";
869
+ const page = AstUtils.getContainerOfType(tab, isPage);
870
+ const pageName = page ? page.name : document.name;
871
+ // Check for label parameter
872
+ const labelParam = params.find((p) => isLabelParam(p));
873
+ const label = (_b = labelParam === null || labelParam === void 0 ? void 0 : labelParam.value) !== null && _b !== void 0 ? _b : `${document.name}.${tab.name}`;
874
+ return expandToNode `
875
+ <v-tab value="${tab.name.toLowerCase()}" prepend-icon="${icon}" @mousedown="spawnDatatableWindow($event, '${pageName}', '${tab.name}')">{{ game.i18n.localize('${label}') }}</v-tab>
876
+ `;
877
+ }
878
+ function generateNavListItem(page) {
879
+ var _a, _b;
880
+ const pageIconParam = (_a = page.params) === null || _a === void 0 ? void 0 : _a.find(p => isIconParam(p));
881
+ const icon = (_b = pageIconParam === null || pageIconParam === void 0 ? void 0 : pageIconParam.value) !== null && _b !== void 0 ? _b : "fa-solid fa-page";
882
+ return expandToNode `
883
+ <v-tab value="${page.name.toLowerCase()}" prepend-icon="${icon}">{{ game.i18n.localize('${page.name}') }}</v-tab>
884
+ `;
885
+ }
886
+ function generatePageBody(page) {
887
+ const tables = page.body.filter(isTableField); // We explictly only want top-level tables
888
+ const pinned = page.body.filter(isPinnedField); // We explictly only want top-level pinned fields
889
+ const inventories = page.body.filter(isInventoryField); // We explictly only want top-level inventories
890
+ return expandToNode `
891
+ <v-tabs-window-item value="${page.name.toLowerCase()}" data-tab="${page.name.toLowerCase()}">
892
+ <v-row dense>
893
+ ${joinToNode(page.body, element => generateElement(element, true), { appendNewLineIfNotEmpty: true })}
894
+ </v-row>
895
+ <v-divider class="mt-4 mb-2"></v-divider>
896
+ <v-tabs v-model="tab" grow always-center>
897
+ ${joinToNode(tables, table => generateSubTab(table), { appendNewLineIfNotEmpty: true })}
898
+ ${joinToNode(pinned, pinnedField => generatePinnedTab(pinnedField), { appendNewLineIfNotEmpty: true })}
899
+ ${joinToNode(inventories, inventory => generateSubTab(inventory), { appendNewLineIfNotEmpty: true })}
900
+ </v-tabs>
901
+ <v-tabs-window v-model="tab" class="tabs-window">
902
+ ${joinToNode(tables, table => generateVuetifyDatatable(page.name, table), { appendNewLineIfNotEmpty: true })}
903
+ ${joinToNode(pinned, pinnedField => generatePinnedTabWindow(pinnedField), { appendNewLineIfNotEmpty: true })}
904
+ ${joinToNode(inventories, inventory => generateInventoryTabWindow(page.name, inventory), { appendNewLineIfNotEmpty: true })}
905
+ </v-tabs-window>
906
+ </v-tabs-window-item>
907
+ `;
908
+ }
909
+ function generateVuetifyDatatable(pageName, element) {
910
+ const systemPath = getSystemPath(element, [], undefined, false);
911
+ let componentName = `${document.name}${pageName}${element.name}VuetifyDatatable`;
912
+ return expandToNode `
913
+ <v-tabs-window-item value="${element.name.toLowerCase()}" data-tab="${element.name.toLowerCase()}" data-type="table" class="tabs-container">
914
+ <${componentName} systemPath="${systemPath}" :context="context" :primaryColor="primaryColor" :secondaryColor="secondaryColor" :teritaryColor="teritaryColor"></${componentName}>
915
+ </v-tabs-window-item>
916
+ `.appendNewLine();
917
+ }
918
+ function generateInventoryTabWindow(pageName, element) {
919
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
920
+ const systemPath = getSystemPath(element, [], undefined, false);
921
+ const iconParam = element.params.find(p => isIconParam(p));
922
+ const labelParam = element.params.find(p => isLabelParam(p));
923
+ const slotsParam = element.params.find(isInventorySlotsParam);
924
+ const rowsParam = element.params.find(isInventoryRowsParam);
925
+ const slotSizeParam = element.params.find(isInventorySlotSizeParam);
926
+ const quantityParam = element.params.find(isInventoryQuantityParam);
927
+ const moneyParam = element.params.find(isInventoryMoneyParam);
928
+ const sumParam = element.params.find(isInventorySumParam);
929
+ const sumMaxParam = element.params.find(isInventorySumMaxParam);
930
+ const sortParam = element.params.find(isInventorySortParam);
931
+ const whereParam = element.params.find(isWhereParam);
932
+ const globalParam = element.params.find(isGlobalParam);
933
+ const emptySlotsParam = element.params.find(isInventoryEmptySlotsParam);
934
+ const summaryParam = element.params.find(isInventorySummaryParam);
935
+ const label = labelParam ? labelParam.value : `${document.name}.${element.name}`;
936
+ const icon = iconParam === null || iconParam === void 0 ? void 0 : iconParam.value;
937
+ const slots = (_a = slotsParam === null || slotsParam === void 0 ? void 0 : slotsParam.value) !== null && _a !== void 0 ? _a : 20;
938
+ const rows = rowsParam === null || rowsParam === void 0 ? void 0 : rowsParam.value;
939
+ const slotSize = slotSizeParam ? parseInt(slotSizeParam.value.replace('px', '')) : 60;
940
+ const documentType = (_b = element.document.ref) === null || _b === void 0 ? void 0 : _b.name.toLowerCase();
941
+ const quantityField = (_c = quantityParam === null || quantityParam === void 0 ? void 0 : quantityParam.field.ref) === null || _c === void 0 ? void 0 : _c.name.toLowerCase();
942
+ const moneyField = (_d = moneyParam === null || moneyParam === void 0 ? void 0 : moneyParam.field.ref) === null || _d === void 0 ? void 0 : _d.name.toLowerCase();
943
+ const moneyFieldLabel = moneyField ? `${document.name}.${(_f = (_e = moneyParam === null || moneyParam === void 0 ? void 0 : moneyParam.field) === null || _e === void 0 ? void 0 : _e.ref) === null || _f === void 0 ? void 0 : _f.name}` : undefined;
944
+ const moneyFieldIcon = moneyField ? (_j = (_h = (_g = moneyParam === null || moneyParam === void 0 ? void 0 : moneyParam.field) === null || _g === void 0 ? void 0 : _g.ref) === null || _h === void 0 ? void 0 : _h.params.find(isIconParam)) === null || _j === void 0 ? void 0 : _j.value : undefined;
945
+ const sortProperty = (_k = sortParam === null || sortParam === void 0 ? void 0 : sortParam.property.ref) === null || _k === void 0 ? void 0 : _k.name;
946
+ const sortOrder = (_l = sortParam === null || sortParam === void 0 ? void 0 : sortParam.order) !== null && _l !== void 0 ? _l : 'asc';
947
+ const globalAllowed = (_m = globalParam === null || globalParam === void 0 ? void 0 : globalParam.value) !== null && _m !== void 0 ? _m : false;
948
+ const emptySlots = (_o = emptySlotsParam === null || emptySlotsParam === void 0 ? void 0 : emptySlotsParam.value) !== null && _o !== void 0 ? _o : 'show';
949
+ const summary = (_p = summaryParam === null || summaryParam === void 0 ? void 0 : summaryParam.value) !== null && _p !== void 0 ? _p : 'full';
950
+ // Handle sum properties (can be single or array)
951
+ let sumProperties = [];
952
+ if (sumParam) {
953
+ if (sumParam.properties.property) {
954
+ sumProperties = [((_q = sumParam.properties.property.ref) === null || _q === void 0 ? void 0 : _q.name) || ''];
955
+ }
956
+ else if (sumParam.properties.properties) {
957
+ sumProperties = sumParam.properties.properties
958
+ .map(p => { var _a; return ((_a = p.ref) === null || _a === void 0 ? void 0 : _a.name) || ''; })
959
+ .filter(n => n !== '');
960
+ }
961
+ }
962
+ // Handle sumMax (can be int, expression, or array of ints/expressions)
963
+ let sumMax = undefined;
964
+ if (sumMaxParam) {
965
+ if (sumMaxParam.value !== undefined) {
966
+ // It's a single INT
967
+ sumMax = String(sumMaxParam.value);
968
+ }
969
+ else if (sumMaxParam.expression) {
970
+ // It's a single expression (like self.CarryCapacity), translate it
971
+ const sumMaxNode = translateExpression(entry, id, sumMaxParam.expression);
972
+ if (sumMaxNode) {
973
+ // Prefix with context. so it evaluates correctly in Vue template
974
+ sumMax = `context.${toString(sumMaxNode)}`;
975
+ }
976
+ }
977
+ else if ((_r = sumMaxParam.values) === null || _r === void 0 ? void 0 : _r.values) {
978
+ // It's an array of ints/expressions
979
+ const maxValues = sumMaxParam.values.values.map((val) => {
980
+ if (typeof val === 'number') {
981
+ return String(val);
982
+ }
983
+ else {
984
+ // It's an expression, translate it
985
+ const valNode = translateExpression(entry, id, val);
986
+ if (valNode) {
987
+ return `context.${toString(valNode)}`;
988
+ }
989
+ return '0';
990
+ }
991
+ });
992
+ sumMax = `[${maxValues.join(', ')}]`;
993
+ }
994
+ }
995
+ // Handle where expression
996
+ let whereExpression = undefined;
997
+ if (whereParam) {
998
+ const whereNode = translateExpression(entry, id, whereParam.value);
999
+ whereExpression = whereNode ? toString(whereNode) : undefined;
1000
+ }
1001
+ return expandToNode `
1002
+ <v-tabs-window-item value="${element.name.toLowerCase()}" data-tab="${element.name.toLowerCase()}" data-type="inventory" class="tabs-container">
1003
+ <i-inventory
1004
+ label="${label}"
1005
+ systemPath="${systemPath}"
1006
+ :context="context"
1007
+ :editMode="editModeRef"
1008
+ ${icon ? `icon="${icon}"` : ''}
1009
+ ${slots ? `:maxSlots="${slots}"` : ''}
1010
+ ${rows ? `:rows="${rows}"` : ''}
1011
+ :slotSize="${slotSize}"
1012
+ documentType="${documentType}"
1013
+ ${whereExpression ? `whereExpression="${whereExpression}"` : ''}
1014
+ ${globalAllowed ? ':globalAllowed="true"' : ''}
1015
+ ${quantityField ? `quantityField="${quantityField}"` : ''}
1016
+ ${moneyField ? `moneyField="${moneyField}"` : ''}
1017
+ ${moneyFieldLabel ? `moneyFieldLabel="${moneyFieldLabel}"` : ''}
1018
+ ${moneyFieldIcon ? `moneyFieldIcon="${moneyFieldIcon}"` : ''}
1019
+ ${sumProperties.length > 0 ? `:sumProperties='${JSON.stringify(sumProperties)}'` : ''}
1020
+ ${sumMax ? `:sumMax="${sumMax}"` : ''}
1021
+ ${sortProperty ? `sortProperty="${sortProperty}"` : ''}
1022
+ sortOrder="${sortOrder}"
1023
+ emptySlots="${emptySlots}"
1024
+ summary="${summary}"
1025
+ :primaryColor="primaryColor"
1026
+ :secondaryColor="secondaryColor"
1027
+ :teritaryColor="teritaryColor"
1028
+ />
1029
+ </v-tabs-window-item>
1030
+ `.appendNewLine();
1031
+ }
1032
+ function generatePinnedTab(element) {
1033
+ var _a, _b;
1034
+ const iconParam = element.params.find(p => isIconParam(p));
1035
+ const labelParam = element.params.find(p => isLabelParam(p));
1036
+ const icon = (_a = iconParam === null || iconParam === void 0 ? void 0 : iconParam.value) !== null && _a !== void 0 ? _a : "fa-solid fa-thumbtack";
1037
+ const label = (_b = labelParam === null || labelParam === void 0 ? void 0 : labelParam.value) !== null && _b !== void 0 ? _b : `${document.name}.${element.name}`;
1038
+ return expandToNode `
1039
+ <v-tab value="${element.name.toLowerCase()}" prepend-icon="${icon}" @mousedown="spawnDatatableWindow($event, '${document.name}', '${element.name}')">{{ game.i18n.localize("${label}") }}</v-tab>
1040
+ `.appendNewLine();
1041
+ }
1042
+ function generatePinnedTabWindow(element) {
1043
+ const page = AstUtils.getContainerOfType(element, isPage);
1044
+ const pageName = page ? page.name : document.name;
1045
+ let componentName = `${document.name}${pageName}${element.name}VuetifyDatatable`;
1046
+ return expandToNode `
1047
+ <v-tabs-window-item value="${element.name.toLowerCase()}" data-tab="${element.name.toLowerCase()}" data-type="pinned" class="tabs-container">
1048
+ <${componentName}
1049
+ :context="context"
1050
+ :primaryColor="primaryColor"
1051
+ :secondaryColor="secondaryColor"
1052
+ :tertiaryColor="tertiaryColor"
1053
+ />
1054
+ </v-tabs-window-item>
1055
+ `.appendNewLine();
1056
+ }
1057
+ function generateElement(element, isTopLevel = false) {
1058
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7;
1059
+ if (isSection(element)) {
1060
+ return expandToNode `
1061
+ <v-col class="section">
1062
+ <v-card variant="outlined" elevation="4">
1063
+ <v-card-title>{{ game.i18n.localize('${document.name}.${element.name}') }}</v-card-title>
1064
+
1065
+ <v-card-text>
1066
+ <v-row dense>
1067
+ ${joinToNode(element.body, element => generateElement(element), { appendNewLineIfNotEmpty: true })}
1068
+ </v-row>
1069
+ </v-card-text>
1070
+ </v-card>
1071
+ </v-col>
1072
+ `;
1073
+ }
1074
+ if (isRow(element)) {
1075
+ return expandToNode `
1076
+ <v-row dense>
1077
+ ${joinToNode(element.body, element => generateElement(element), { appendNewLineIfNotEmpty: true })}
1078
+ </v-row>
1079
+ `;
1080
+ }
1081
+ if (isColumn(element)) {
1082
+ return expandToNode `
1083
+ <v-col>
1084
+ ${joinToNode(element.body, element => generateElement(element), { appendNewLineIfNotEmpty: true })}
1085
+ </v-col>
1086
+ `;
1087
+ }
1088
+ // We don't render these elements as part of this function
1089
+ if (isPage(element) || isAccess(element) || isStatusProperty(element)) {
1090
+ return expandToNode ``;
1091
+ }
1092
+ if (isAction(element)) {
1093
+ const componentName = `${document.name.toLowerCase()}${element.name}Action`;
1094
+ const colorParam = element.params.find(x => isColorParam(x));
1095
+ const primaryColor = colorParam ? `'${colorParam.value}'` : "primaryColor";
1096
+ return expandToNode `
1097
+ <${componentName}
1098
+ :context="context"
1099
+ :color="${primaryColor}"
1100
+ :editMode="editModeRef"
1101
+ :visibility="visibilityStates['${element.name.toLowerCase()}'].value">
1102
+ </${componentName}>
1103
+ `;
1104
+ }
1105
+ if (!isProperty(element))
1106
+ return expandToNode ``;
1107
+ if (isProperty(element)) {
1108
+ if (element.modifier == "hidden")
1109
+ return expandToNode ``;
1110
+ if (element.name == "RollVisualizer") {
1111
+ return expandToNode `
1112
+ <i-roll-visualizer :context="context"></i-roll-visualizer>
1113
+ `;
1114
+ }
1115
+ const standardParams = element.params;
1116
+ const iconParam = standardParams.find(p => isIconParam(p));
1117
+ const colorParam = standardParams.find(p => isColorParam(p));
1118
+ const label = `${document.name}.${element.name}`;
1119
+ const standardParamsFragment = colorParam ? `:disabled="isDisabled('${element.name.toLowerCase()}')" v-if="!isHidden('${element.name.toLowerCase()}')" color="${colorParam.value}"` : `:disabled="isDisabled('${element.name.toLowerCase()}')" v-if="!isHidden('${element.name.toLowerCase()}')"`;
1120
+ const systemPath = getSystemPath(element, [], undefined, false);
1121
+ const entry = AstUtils.getContainerOfType(element, isEntry);
1122
+ if (isParentPropertyRefExp(element)) {
1123
+ const choicesParam = element.params.find(p => isParentPropertyRefChoiceParam(p));
1124
+ let allChoices = [];
1125
+ switch (element.propertyType) {
1126
+ case "attribute":
1127
+ allChoices = globalGetAllOfType(entry, isAttributeExp);
1128
+ break;
1129
+ case "resource":
1130
+ allChoices = globalGetAllOfType(entry, isResourceExp);
1131
+ break;
1132
+ case "number":
1133
+ allChoices = globalGetAllOfType(entry, isNumberExp);
1134
+ break;
1135
+ case "boolean":
1136
+ allChoices = globalGetAllOfType(entry, isBooleanExp);
1137
+ break;
1138
+ case "date":
1139
+ allChoices = globalGetAllOfType(entry, isDateExp);
1140
+ break;
1141
+ case "time":
1142
+ allChoices = globalGetAllOfType(entry, isTimeExp);
1143
+ break;
1144
+ case "datetime":
1145
+ allChoices = globalGetAllOfType(entry, isDateTimeExp);
1146
+ break;
1147
+ case "die":
1148
+ allChoices = globalGetAllOfType(entry, isDieField);
1149
+ break;
1150
+ case "dice":
1151
+ allChoices = globalGetAllOfType(entry, isDiceField);
1152
+ break;
1153
+ case "string":
1154
+ allChoices = globalGetAllOfType(entry, isStringExp);
1155
+ break;
1156
+ case "tracker":
1157
+ allChoices = globalGetAllOfType(entry, isTrackerExp);
1158
+ break;
1159
+ case "choice":
1160
+ allChoices = globalGetAllOfType(entry, isDocumentChoiceExp);
1161
+ break;
1162
+ case "paperdoll":
1163
+ allChoices = globalGetAllOfType(entry, isPaperDollExp);
1164
+ break;
1165
+ case "html":
1166
+ allChoices = globalGetAllOfType(entry, isHtmlExp);
1167
+ break;
1168
+ //default: console.error("Unsupported parent property type: " + element.propertyType); break;
1169
+ }
1170
+ let refChoices = allChoices.map(x => {
1171
+ let parentDocument = getDocument(x);
1172
+ if (choicesParam && choicesParam.choices.length > 0) {
1173
+ if (!choicesParam.choices.find(y => {
1174
+ var _a, _b;
1175
+ const documentNameMatches = ((_a = y.document.ref) === null || _a === void 0 ? void 0 : _a.name.toLowerCase()) == (parentDocument === null || parentDocument === void 0 ? void 0 : parentDocument.name.toLowerCase());
1176
+ if (y.property != undefined) {
1177
+ const propertyNameMatches = ((_b = y.property.ref) === null || _b === void 0 ? void 0 : _b.name.toLowerCase()) == x.name.toLowerCase();
1178
+ return documentNameMatches && propertyNameMatches;
1179
+ }
1180
+ // Just check document name
1181
+ return documentNameMatches;
1182
+ })) {
1183
+ return undefined;
1184
+ }
1185
+ }
1186
+ return {
1187
+ path: `system.${x.name.toLowerCase()}`,
1188
+ parent: parentDocument === null || parentDocument === void 0 ? void 0 : parentDocument.name,
1189
+ name: x.name
1190
+ };
1191
+ });
1192
+ refChoices = refChoices.filter(x => x != undefined);
1193
+ const choices = refChoices.map(c => `{ label: '${c === null || c === void 0 ? void 0 : c.parent} - ${c === null || c === void 0 ? void 0 : c.name}', value: '${c === null || c === void 0 ? void 0 : c.path}' }`).join(", ");
1194
+ return expandToNode `
1195
+ <i-parent-property-reference
1196
+ :context="context"
1197
+ label="${label}"
1198
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1199
+ systemPath="${systemPath}"
1200
+ :refChoices="[${choices}]"
1201
+ ${standardParamsFragment}>
1202
+ </i-parent-property-reference>
1203
+ `;
1204
+ }
1205
+ if (isSelfPropertyRefExp(element)) {
1206
+ const choicesParam = element.params.find(p => p.$type === 'SelfPropertyRefChoiceParam');
1207
+ let allChoices = [];
1208
+ // Get the current document
1209
+ const currentDocument = getDocument(element);
1210
+ if (!currentDocument) {
1211
+ return expandToNode `
1212
+ <div class="error">Self property reference error: Cannot find current document</div>
1213
+ `;
1214
+ }
1215
+ switch (element.propertyType) {
1216
+ case "attribute":
1217
+ allChoices = getAllOfType(currentDocument.body, isAttributeExp);
1218
+ break;
1219
+ case "resource":
1220
+ allChoices = getAllOfType(currentDocument.body, isResourceExp);
1221
+ break;
1222
+ case "number":
1223
+ allChoices = getAllOfType(currentDocument.body, isNumberExp);
1224
+ break;
1225
+ case "boolean":
1226
+ allChoices = getAllOfType(currentDocument.body, isBooleanExp);
1227
+ break;
1228
+ case "date":
1229
+ allChoices = getAllOfType(currentDocument.body, isDateExp);
1230
+ break;
1231
+ case "time":
1232
+ allChoices = getAllOfType(currentDocument.body, isTimeExp);
1233
+ break;
1234
+ case "datetime":
1235
+ allChoices = getAllOfType(currentDocument.body, isDateTimeExp);
1236
+ break;
1237
+ case "die":
1238
+ allChoices = getAllOfType(currentDocument.body, isDieField);
1239
+ break;
1240
+ case "dice":
1241
+ allChoices = getAllOfType(currentDocument.body, isDiceField);
1242
+ break;
1243
+ case "string":
1244
+ allChoices = getAllOfType(currentDocument.body, isStringExp);
1245
+ break;
1246
+ case "tracker":
1247
+ allChoices = getAllOfType(currentDocument.body, isTrackerExp);
1248
+ break;
1249
+ case "choice":
1250
+ allChoices = getAllOfType(currentDocument.body, isDocumentChoiceExp);
1251
+ break;
1252
+ case "paperdoll":
1253
+ allChoices = getAllOfType(currentDocument.body, isPaperDollExp);
1254
+ break;
1255
+ case "html":
1256
+ allChoices = getAllOfType(currentDocument.body, isHtmlExp);
1257
+ break;
1258
+ }
1259
+ let refChoices = allChoices.filter(x => x !== element).map(x => {
1260
+ return {
1261
+ path: `system.${x.name.toLowerCase()}`,
1262
+ name: x.name
1263
+ };
1264
+ });
1265
+ // Filter based on choices parameter if provided
1266
+ if (choicesParam && ((_a = choicesParam.choices) === null || _a === void 0 ? void 0 : _a.length) > 0) {
1267
+ const allowedProperties = choicesParam.choices.map((c) => { var _a; return (_a = c.property.ref) === null || _a === void 0 ? void 0 : _a.name.toLowerCase(); });
1268
+ refChoices = refChoices.filter(x => allowedProperties.includes(x.name.toLowerCase()));
1269
+ }
1270
+ const choices = refChoices.map(c => `{ title: '${c.name}', value: '${c.path}' }`).join(", ");
1271
+ return expandToNode `
1272
+ <i-self-property-reference
1273
+ :context="context"
1274
+ label="${label}"
1275
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1276
+ systemPath="${systemPath}"
1277
+ propertyType="${element.propertyType}"
1278
+ :choices="[${choices}]"
1279
+ ${standardParamsFragment}>
1280
+ </i-self-property-reference>
1281
+ `;
1282
+ }
1283
+ if (isStringExp(element)) {
1284
+ const valueParam = element.params.find(p => isStringParamValue(p));
1285
+ if (valueParam !== undefined) {
1286
+ return expandToNode `
1287
+ <i-string
1288
+ :context="context"
1289
+ label="${label}"
1290
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1291
+ systemPath="${systemPath}"
1292
+ ${standardParamsFragment}>
1293
+ </i-string>
1294
+ `;
1295
+ }
1296
+ return expandToNode `
1297
+ <i-text-field
1298
+ label="${label}"
1299
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1300
+ systemPath="${systemPath}"
1301
+ ${standardParamsFragment}
1302
+ :context="context"
1303
+ :editMode="editModeRef"
1304
+ :primaryColor="primaryColor"
1305
+ :secondaryColor="secondaryColor">
1306
+ </i-text-field>
1307
+ `;
1308
+ }
1309
+ if (isStringChoiceField(element)) {
1310
+ const choicesParam = element.params.find(p => isStringParamChoices(p));
1311
+ if (!choicesParam) {
1312
+ console.warn(`StringChoiceField ${element.name} does not have a choices parameter.`);
1313
+ return expandToNode ``;
1314
+ }
1315
+ if (((_b = choicesParam === null || choicesParam === void 0 ? void 0 : choicesParam.choices) === null || _b === void 0 ? void 0 : _b.length) === 0)
1316
+ return expandToNode ``;
1317
+ function choiceValue(choice) {
1318
+ if (!isStringExtendedChoice(choice.value)) {
1319
+ return toMachineIdentifier(choice.value);
1320
+ }
1321
+ let value = choice.value.properties.find(isChoiceStringValue);
1322
+ if (value) {
1323
+ return toMachineIdentifier(value.value);
1324
+ }
1325
+ let label = choice.value.properties.find(isLabelParam);
1326
+ if (label) {
1327
+ return toMachineIdentifier(label.value);
1328
+ }
1329
+ return "unknown";
1330
+ }
1331
+ function choiceData(choice) {
1332
+ var _a, _b, _c, _d;
1333
+ let choiceField = element;
1334
+ if (!isStringExtendedChoice(choice.value)) {
1335
+ return expandToNode `{ label: game.i18n.localize('${document.name}.${choiceField.name}.${choiceValue(choice)}'), value: '${choiceValue(choice)}', icon: '', color: '' }`;
1336
+ }
1337
+ let icon = choice.value.properties.find(isIconParam);
1338
+ let color = choice.value.properties.find(isColorParam);
1339
+ if (isStringExtendedChoice(choice.value)) {
1340
+ let customProperties = choice.value.properties.filter(isChoiceCustomProperty);
1341
+ if (customProperties.length > 0) {
1342
+ return expandToNode `{ label: game.i18n.localize('${document.name}.${choiceField.name}.${choiceValue(choice)}'), value: '${choiceValue(choice)}', icon: '${(_a = icon === null || icon === void 0 ? void 0 : icon.value) !== null && _a !== void 0 ? _a : ""}', color: '${(_b = color === null || color === void 0 ? void 0 : color.value) !== null && _b !== void 0 ? _b : ""}', customKeys: [${joinToNode(customProperties, custom => `{ key: '${custom.key}', label: '${humanize(custom.key)}', value: ${custom.value} }`, { separator: ',' })}] }`;
1343
+ }
1344
+ }
1345
+ return expandToNode `{ label: game.i18n.localize('${document.name}.${choiceField.name}.${choiceValue(choice)}'), value: '${choiceValue(choice)}', icon: '${(_c = icon === null || icon === void 0 ? void 0 : icon.value) !== null && _c !== void 0 ? _c : ""}', color: '${(_d = color === null || color === void 0 ? void 0 : color.value) !== null && _d !== void 0 ? _d : ""}' }`;
1346
+ }
1347
+ return expandToNode `
1348
+ <i-string-choice
1349
+ :context="context"
1350
+ label="${label}.label"
1351
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1352
+ systemPath="${systemPath}"
1353
+ :items="[${joinToNode(choicesParam.choices, choiceData, { separator: ',', appendNewLineIfNotEmpty: true })}]"
1354
+ :isExtended="true"
1355
+ :primaryColor="primaryColor"
1356
+ :secondaryColor="secondaryColor"
1357
+ ${standardParamsFragment}>
1358
+ </i-string-choice>
1359
+ `;
1360
+ }
1361
+ if (isDamageTypeChoiceField(element)) {
1362
+ const choicesParam = element.params.find(p => isStringParamChoices(p));
1363
+ if (!choicesParam) {
1364
+ console.warn(`DamageTypeChoiceField ${element.name} does not have a choices parameter.`);
1365
+ return expandToNode ``;
1366
+ }
1367
+ if (((_c = choicesParam === null || choicesParam === void 0 ? void 0 : choicesParam.choices) === null || _c === void 0 ? void 0 : _c.length) === 0)
1368
+ return expandToNode ``;
1369
+ function choiceValue(choice) {
1370
+ if (!isStringExtendedChoice(choice.value)) {
1371
+ return toMachineIdentifier(choice.value);
1372
+ }
1373
+ let value = choice.value.properties.find(isChoiceStringValue);
1374
+ if (value) {
1375
+ return toMachineIdentifier(value.value);
1376
+ }
1377
+ let label = choice.value.properties.find(isLabelParam);
1378
+ if (label) {
1379
+ return toMachineIdentifier(label.value);
1380
+ }
1381
+ return "unknown";
1382
+ }
1383
+ function choiceData(choice) {
1384
+ var _a, _b, _c, _d;
1385
+ let choiceField = element;
1386
+ if (!isStringExtendedChoice(choice.value)) {
1387
+ return expandToNode `{ label: game.i18n.localize('${document.name}.${choiceField.name}.${choiceValue(choice)}'), value: '${choiceValue(choice)}', icon: '', color: '' }`;
1388
+ }
1389
+ let icon = choice.value.properties.find(isIconParam);
1390
+ let color = choice.value.properties.find(isColorParam);
1391
+ function asStringOrVal(value) {
1392
+ // If string, return as "value", else just value
1393
+ if (typeof value === 'string')
1394
+ return `'${value}'`;
1395
+ return `${value}`;
1396
+ }
1397
+ if (isStringExtendedChoice(choice.value)) {
1398
+ let customProperties = choice.value.properties.filter(isChoiceCustomProperty);
1399
+ if (customProperties.length > 0) {
1400
+ return expandToNode `{ label: game.i18n.localize('${document.name}.${choiceField.name}.${choiceValue(choice)}'), value: '${choiceValue(choice)}', icon: '${(_a = icon === null || icon === void 0 ? void 0 : icon.value) !== null && _a !== void 0 ? _a : ""}', color: '${(_b = color === null || color === void 0 ? void 0 : color.value) !== null && _b !== void 0 ? _b : ""}', customKeys: [${joinToNode(customProperties, custom => `{ key: '${custom.key}', label: '${humanize(custom.key)}', value: ${asStringOrVal(custom.value)} }`, { separator: ',' })}] }`;
1401
+ }
1402
+ }
1403
+ return expandToNode `{ label: game.i18n.localize('${document.name}.${choiceField.name}.${choiceValue(choice)}'), value: '${choiceValue(choice)}', icon: '${(_c = icon === null || icon === void 0 ? void 0 : icon.value) !== null && _c !== void 0 ? _c : ""}', color: '${(_d = color === null || color === void 0 ? void 0 : color.value) !== null && _d !== void 0 ? _d : ""}' }`;
1404
+ }
1405
+ return expandToNode `
1406
+ <i-string-choice
1407
+ :context="context"
1408
+ label="${label}.label"
1409
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1410
+ systemPath="${systemPath}"
1411
+ :items="[${joinToNode(choicesParam.choices, choiceData, { separator: ',', appendNewLineIfNotEmpty: true })}]"
1412
+ :isExtended="true"
1413
+ :primaryColor="primaryColor"
1414
+ :secondaryColor="secondaryColor"
1415
+ ${standardParamsFragment}>
1416
+ </i-string-choice>
1417
+ `;
1418
+ }
1419
+ if (isStringChoicesField(element)) {
1420
+ const choicesParam = element.params.find(p => p.$type === 'StringChoicesParamChoices');
1421
+ if (!choicesParam) {
1422
+ console.warn(`StringChoicesField ${element.name} does not have a choices parameter.`);
1423
+ return expandToNode ``;
1424
+ }
1425
+ if (((_d = choicesParam === null || choicesParam === void 0 ? void 0 : choicesParam.choices) === null || _d === void 0 ? void 0 : _d.length) === 0)
1426
+ return expandToNode ``;
1427
+ function choiceValue(choice) {
1428
+ if (!isStringExtendedChoice(choice.value)) {
1429
+ return toMachineIdentifier(choice.value);
1430
+ }
1431
+ let value = choice.value.properties.find(isChoiceStringValue);
1432
+ if (value) {
1433
+ return toMachineIdentifier(value.value);
1434
+ }
1435
+ let label = choice.value.properties.find(isLabelParam);
1436
+ if (label) {
1437
+ return toMachineIdentifier(label.value);
1438
+ }
1439
+ return "unknown";
1440
+ }
1441
+ function choiceData(choice) {
1442
+ var _a, _b, _c, _d;
1443
+ let choiceField = element;
1444
+ if (!isStringExtendedChoice(choice.value)) {
1445
+ return expandToNode `{ label: game.i18n.localize('${document.name}.${choiceField.name}.${choiceValue(choice)}'), value: '${choiceValue(choice)}', icon: '', color: '' }`;
1446
+ }
1447
+ let icon = choice.value.properties.find(isIconParam);
1448
+ let color = choice.value.properties.find(isColorParam);
1449
+ if (isStringExtendedChoice(choice.value)) {
1450
+ let customProperties = choice.value.properties.filter(isChoiceCustomProperty);
1451
+ if (customProperties.length > 0) {
1452
+ return expandToNode `{ label: game.i18n.localize('${document.name}.${choiceField.name}.${choiceValue(choice)}'), value: '${choiceValue(choice)}', icon: '${(_a = icon === null || icon === void 0 ? void 0 : icon.value) !== null && _a !== void 0 ? _a : ""}', color: '${(_b = color === null || color === void 0 ? void 0 : color.value) !== null && _b !== void 0 ? _b : ""}', customKeys: [${joinToNode(customProperties, custom => `{ key: '${custom.key}', label: '${humanize(custom.key)}', value: ${custom.value} }`, { separator: ',' })}] }`;
1453
+ }
1454
+ }
1455
+ return expandToNode `{ label: game.i18n.localize('${document.name}.${choiceField.name}.${choiceValue(choice)}'), value: '${choiceValue(choice)}', icon: '${(_c = icon === null || icon === void 0 ? void 0 : icon.value) !== null && _c !== void 0 ? _c : ""}', color: '${(_d = color === null || color === void 0 ? void 0 : color.value) !== null && _d !== void 0 ? _d : ""}' }`;
1456
+ }
1457
+ // Get maxSelections parameter
1458
+ const maxParam = element.params.find(p => p.$type === 'StringChoicesParamMax');
1459
+ const maxSelections = maxParam ? maxParam.value : undefined;
1460
+ return expandToNode `
1461
+ <i-string-choices
1462
+ :context="context"
1463
+ label="${label}.label"
1464
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1465
+ systemPath="${systemPath}"
1466
+ :items="[${joinToNode(choicesParam.choices, choiceData, { separator: ',', appendNewLineIfNotEmpty: true })}]"
1467
+ :isExtended="true"
1468
+ ${maxSelections ? `:maxSelections="${maxSelections}"` : ''}
1469
+ :primaryColor="primaryColor"
1470
+ :secondaryColor="secondaryColor"
1471
+ ${standardParamsFragment}>
1472
+ </i-string-choices>
1473
+ `;
1474
+ }
1475
+ if (isDocumentChoiceExp(element)) {
1476
+ const componentName = `${document.name.toLowerCase()}${element.name}DocumentChoice`;
1477
+ return expandToNode `
1478
+ <${componentName}
1479
+ label="${label}"
1480
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1481
+ :context="context"
1482
+ :editMode="editModeRef"
1483
+ ${standardParamsFragment}
1484
+ :primaryColor="primaryColor"
1485
+ :secondaryColor="secondaryColor">
1486
+ </${componentName}>
1487
+ `;
1488
+ }
1489
+ if (isDocumentChoicesExp(element)) {
1490
+ const componentName = `${document.name.toLowerCase()}${element.name}DocumentChoices`;
1491
+ return expandToNode `
1492
+ <${componentName}
1493
+ label="${label}"
1494
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1495
+ :context="context"
1496
+ :editMode="editModeRef"
1497
+ ${standardParamsFragment}
1498
+ :primaryColor="primaryColor"
1499
+ :secondaryColor="secondaryColor">
1500
+ </${componentName}>
1501
+ `;
1502
+ }
1503
+ if (isMacroField(element)) {
1504
+ return expandToNode `
1505
+ <i-macro
1506
+ label="${label}"
1507
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1508
+ systemPath="${systemPath}"
1509
+ ${standardParamsFragment}
1510
+ :context="context"
1511
+ :editMode="editModeRef"
1512
+ :primaryColor="primaryColor"
1513
+ :secondaryColor="secondaryColor">
1514
+ </i-macro>
1515
+ `;
1516
+ }
1517
+ if (isHtmlExp(element)) {
1518
+ return expandToNode `
1519
+ <i-prosemirror
1520
+ label="${label}"
1521
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1522
+ :field="context.editors['${systemPath}']"
1523
+ ${standardParamsFragment}>
1524
+ </i-prosemirror>
1525
+ `;
1526
+ }
1527
+ if (isMeasuredTemplateField(element)) {
1528
+ return expandToNode `
1529
+ <i-measured-template
1530
+ :context="context"
1531
+ label="${label}"
1532
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1533
+ systemPath="${systemPath}"
1534
+ :primaryColor="primaryColor"
1535
+ :secondaryColor="secondaryColor"
1536
+ ${standardParamsFragment}>
1537
+ </i-measured-template>
1538
+ `;
1539
+ }
1540
+ if (isDamageBonusesField(element)) {
1541
+ return expandToNode `
1542
+ <i-bonuses
1543
+ :context="context"
1544
+ label="${label}"
1545
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1546
+ systemPath="${systemPath}"
1547
+ ${standardParamsFragment}>
1548
+ </i-bonuses>
1549
+ `;
1550
+ }
1551
+ if (isDamageResistancesField(element)) {
1552
+ return expandToNode `
1553
+ <i-resistances
1554
+ :context="context"
1555
+ label="${label}"
1556
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1557
+ systemPath="${systemPath}"
1558
+ ${standardParamsFragment}>
1559
+ </i-resistances>
1560
+ `;
1561
+ }
1562
+ if (isPinnedField(element)) {
1563
+ if (isTopLevel)
1564
+ return expandToNode ``;
1565
+ const page = AstUtils.getContainerOfType(element, isPage);
1566
+ const pageName = (_e = page === null || page === void 0 ? void 0 : page.name) !== null && _e !== void 0 ? _e : document.name;
1567
+ const systemPath = getSystemPath(element, [], undefined, false);
1568
+ let componentName = `${document.name}${pageName}${element.name}VuetifyDatatable`;
1569
+ // Wrap in a drop zone so drag-drop works for pinned tables inside a
1570
+ // row/column (same reason as regular tables above).
1571
+ return expandToNode `
1572
+ <div class="datatable-drop-zone">
1573
+ <${componentName}
1574
+ :context="context"
1575
+ label="${label}"
1576
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1577
+ systemPath="${systemPath}"
1578
+ :primaryColor="primaryColor" :secondaryColor="secondaryColor" :teritaryColor="teritaryColor">
1579
+ </${componentName}>
1580
+ </div>
1581
+ `;
1582
+ }
1583
+ if (isBooleanExp(element)) {
1584
+ return expandToNode `
1585
+ <i-boolean
1586
+ :context="context"
1587
+ label="${label}"
1588
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1589
+ systemPath="${systemPath}"
1590
+ ${standardParamsFragment}>
1591
+ </i-boolean>
1592
+ `;
1593
+ }
1594
+ if (isNumberExp(element)) {
1595
+ const valueParam = element.params.find(x => isNumberParamValue(x));
1596
+ const maxParam = element.params.find(x => isNumberParamMax(x));
1597
+ const calculatorParam = element.params.find(x => isNumberParamCalculator(x));
1598
+ // Determine if max value is a number (not a MethodBlock)
1599
+ let maxValue = undefined;
1600
+ if (maxParam && typeof maxParam.value === 'number') {
1601
+ maxValue = maxParam.value;
1602
+ }
1603
+ return expandToNode `
1604
+ <i-number
1605
+ :context="context"
1606
+ label="${label}"
1607
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1608
+ systemPath="${systemPath}"
1609
+ :hasValueParam="${valueParam != undefined}"
1610
+ :editMode="editModeRef"
1611
+ :primaryColor="primaryColor"
1612
+ :secondaryColor="secondaryColor"
1613
+ ${maxValue !== undefined ? `:max="${maxValue}"` : ''}
1614
+ ${calculatorParam !== undefined ? `:calculator="${calculatorParam.value}"` : ''}
1615
+ ${standardParamsFragment}>
1616
+ </i-number>
1617
+ `;
1618
+ }
1619
+ if (isMoneyField(element)) {
1620
+ const formatParam = element.params.find(p => p.$type === 'MoneyFormatParam');
1621
+ const precisionParam = element.params.find(p => p.$type === 'MoneyPrecisionParam');
1622
+ const displayParam = element.params.find(p => p.$type === 'MoneyDisplayParam');
1623
+ const valueParam = element.params.find(x => isNumberParamValue(x));
1624
+ const format = (formatParam === null || formatParam === void 0 ? void 0 : formatParam.value) || 'auto';
1625
+ const precision = (precisionParam === null || precisionParam === void 0 ? void 0 : precisionParam.value) || 1;
1626
+ const display = (displayParam === null || displayParam === void 0 ? void 0 : displayParam.value) || 'breakdown';
1627
+ // Generate denominations array from AST
1628
+ let denominationsArray = '[]';
1629
+ if (element.denominations && element.denominations.length > 0) {
1630
+ const denominations = element.denominations.map(denom => {
1631
+ const valueParam = denom.params.find((p) => p.$type === 'MoneyDenominationValueParam');
1632
+ const denomIconParam = denom.params.find((p) => p.$type === 'IconParam');
1633
+ const denomColorParam = denom.params.find((p) => p.$type === 'ColorParam');
1634
+ return `{ name: '${denom.name}', value: ${(valueParam === null || valueParam === void 0 ? void 0 : valueParam.value) || 1}, icon: '${(denomIconParam === null || denomIconParam === void 0 ? void 0 : denomIconParam.value) || ''}', color: '${(denomColorParam === null || denomColorParam === void 0 ? void 0 : denomColorParam.value) || ''}' }`;
1635
+ }).join(', ');
1636
+ denominationsArray = `[${denominations}]`;
1637
+ }
1638
+ return expandToNode `
1639
+ <i-money
1640
+ :context="context"
1641
+ label="${label}"
1642
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1643
+ systemPath="${systemPath}"
1644
+ format="${format}"
1645
+ :precision="${precision}"
1646
+ display="${display}"
1647
+ :denominations="${denominationsArray}"
1648
+ :hasValueParam="${valueParam != undefined}"
1649
+ :editMode="editModeRef"
1650
+ :primaryColor="primaryColor"
1651
+ :secondaryColor="secondaryColor"
1652
+ ${standardParamsFragment}>
1653
+ </i-money>
1654
+ `;
1655
+ }
1656
+ if (isAttributeExp(element)) {
1657
+ const minParam = element.params.find(x => isNumberParamMin(x));
1658
+ const min = (_f = minParam === null || minParam === void 0 ? void 0 : minParam.value) !== null && _f !== void 0 ? _f : 0;
1659
+ const hasMod = element.params.find(x => isAttributeParamMod(x)) != undefined;
1660
+ const modSystemPath = getSystemPath(element, ["mod"], undefined, false);
1661
+ const valueSystemPath = getSystemPath(element, ["value"], undefined, false);
1662
+ const styleParam = element.params.find(x => isAttributeStyleParam(x));
1663
+ const style = (_g = styleParam === null || styleParam === void 0 ? void 0 : styleParam.style) !== null && _g !== void 0 ? _g : "box";
1664
+ const rollParam = element.params.find(x => isAttributeRollParam(x));
1665
+ return expandToNode `
1666
+ <i-attribute
1667
+ label="${label}"
1668
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1669
+ attributeStyle="${style}"
1670
+ :editMode="editModeRef"
1671
+ :hasMod="${hasMod}"
1672
+ :mod="context.${modSystemPath}"
1673
+ systemPath="${valueSystemPath}"
1674
+ :context="context"
1675
+ :min="${min}"
1676
+ ${standardParamsFragment}
1677
+ :primaryColor="primaryColor"
1678
+ :secondaryColor="secondaryColor"
1679
+ :roll="${rollParam ? expandToNode `on${element.name}AttributeRoll` : expandToNode `undefined`}"
1680
+ :hasRoll="${rollParam != undefined}"
1681
+ >
1682
+ </i-attribute>
1683
+ `;
1684
+ }
1685
+ // if () {
1686
+ // return expandToNode`
1687
+ // <i-resource
1688
+ // label="${label}"
1689
+ // icon="${iconParam?.value}"
1690
+ // systemPath="system.${element.name.toLowerCase()}"
1691
+ // :context="context"
1692
+ // ${standardParamsFragment}
1693
+ // :primaryColor="primaryColor"
1694
+ // :secondaryColor="secondaryColor">
1695
+ // </i-resource>
1696
+ // `;
1697
+ // }
1698
+ if (isDamageTrackExp(element)) {
1699
+ const typesParam = element.params.find(x => isDamageTrackTypesParam(x));
1700
+ const types = (_h = typesParam === null || typesParam === void 0 ? void 0 : typesParam.types) !== null && _h !== void 0 ? _h : [];
1701
+ const maxParam = element.params.find(x => isNumberParamMax(x));
1702
+ const max = (_j = maxParam === null || maxParam === void 0 ? void 0 : maxParam.value) !== null && _j !== void 0 ? _j : 5;
1703
+ const colorParam = element.params.find(x => isColorParam(x));
1704
+ const primaryColor = colorParam ? `'${colorParam.value}'` : "primaryColor";
1705
+ return expandToNode `
1706
+ <i-damage-track
1707
+ label="${label}"
1708
+ systemPath="system.${element.name.toLowerCase()}"
1709
+ :context="context"
1710
+ :editMode="editModeRef"
1711
+ :primaryColor="${primaryColor}"
1712
+ :secondaryColor="secondaryColor"
1713
+ :types="[${types.map(t => `'${t}'`).join(', ')}]"
1714
+ :max="${max}"
1715
+ ></i-damage-track>
1716
+ `;
1717
+ }
1718
+ if (isTrackerExp(element) || isResourceExp(element)) {
1719
+ const styleParam = element.params.find(x => isTrackerStyleParameter(x));
1720
+ const style = (_k = styleParam === null || styleParam === void 0 ? void 0 : styleParam.style) !== null && _k !== void 0 ? _k : "bar";
1721
+ const iconParam = element.params.find(x => isIconParam(x));
1722
+ const icon = (_l = iconParam === null || iconParam === void 0 ? void 0 : iconParam.value) !== null && _l !== void 0 ? _l : undefined;
1723
+ const minParam = element.params.find(x => isNumberParamMin(x));
1724
+ const disableMin = (minParam === null || minParam === void 0 ? void 0 : minParam.value) != undefined;
1725
+ let hideMin = false;
1726
+ const valueParam = element.params.find(x => isNumberParamValue(x));
1727
+ const disableValue = (valueParam === null || valueParam === void 0 ? void 0 : valueParam.value) != undefined;
1728
+ const maxParam = element.params.find(x => isNumberParamMax(x));
1729
+ const disableMax = (maxParam === null || maxParam === void 0 ? void 0 : maxParam.value) != undefined;
1730
+ const colorParam = element.params.find(x => isColorParam(x));
1731
+ const primaryColor = colorParam ? `'${colorParam.value}'` : "primaryColor";
1732
+ const segmentParm = element.params.find(x => isSegmentsParameter(x));
1733
+ const segments = (_m = segmentParm === null || segmentParm === void 0 ? void 0 : segmentParm.segments) !== null && _m !== void 0 ? _m : 1;
1734
+ let isHealth = false;
1735
+ let isWounds = false;
1736
+ if (isResourceExp(element)) {
1737
+ hideMin = true;
1738
+ isHealth = element.tag == "health";
1739
+ isWounds = element.tag == "wounds";
1740
+ }
1741
+ return expandToNode `
1742
+ <i-tracker
1743
+ label="${label}"
1744
+ systemPath="system.${element.name.toLowerCase()}" :context="context"
1745
+ :visibility="visibilityStates['${element.name.toLowerCase()}'].value"
1746
+ :editMode="editModeRef"
1747
+ :primaryColor="${primaryColor}" :secondaryColor="secondaryColor" :tertiaryColor="tertiaryColor"
1748
+ trackerStyle="${style}"
1749
+ icon="${icon}"
1750
+ :hideMin="${hideMin}"
1751
+ :disableMin="${disableMin}"
1752
+ :disableValue="${disableValue}"
1753
+ :disableMax="${disableMax}"
1754
+ :segments="${segments}"
1755
+ :isHealth="${isHealth}"
1756
+ :isWounds="${isWounds}"
1757
+ ></i-tracker>
1758
+ `;
1759
+ }
1760
+ if (isSingleDocumentExp(element)) {
1761
+ return expandToNode `
1762
+ <i-document-link
1763
+ label="${label}"
1764
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1765
+ systemPath="system.${element.name.toLowerCase()}"
1766
+ documentName="${(_o = element.document.ref) === null || _o === void 0 ? void 0 : _o.name.toLowerCase()}"
1767
+ :context="context"
1768
+ ${standardParamsFragment}
1769
+ :secondaryColor="secondaryColor">
1770
+ </i-document-link>
1771
+ `;
1772
+ }
1773
+ if (isDateExp(element)) {
1774
+ return expandToNode `
1775
+ <i-datetime
1776
+ type="date"
1777
+ label="${label}"
1778
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1779
+ systemPath="system.${element.name.toLowerCase()}"
1780
+ :context="context"
1781
+ ${standardParamsFragment}
1782
+ :primaryColor="primaryColor" :secondaryColor="secondaryColor">
1783
+ </i-datetime>
1784
+ `;
1785
+ }
1786
+ if (isTimeExp(element)) {
1787
+ return expandToNode `
1788
+ <i-datetime
1789
+ type="time"
1790
+ label="${label}"
1791
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1792
+ systemPath="system.${element.name.toLowerCase()}"
1793
+ :context="context"
1794
+ ${standardParamsFragment}
1795
+ :primaryColor="primaryColor" :secondaryColor="secondaryColor">
1796
+ </i-datetime>
1797
+ `;
1798
+ }
1799
+ if (isDateTimeExp(element)) {
1800
+ return expandToNode `
1801
+ <i-datetime
1802
+ type="datetime-local"
1803
+ label="${label}"
1804
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1805
+ systemPath="system.${element.name.toLowerCase()}"
1806
+ :context="context"
1807
+ ${standardParamsFragment}
1808
+ :primaryColor="primaryColor" :secondaryColor="secondaryColor">
1809
+ </i-datetime>
1810
+ `;
1811
+ }
1812
+ if (isPaperDollExp(element)) {
1813
+ let sizeParam = element.params.find(x => isSizeParam(x));
1814
+ let size = (_p = sizeParam === null || sizeParam === void 0 ? void 0 : sizeParam.value) !== null && _p !== void 0 ? _p : "40px";
1815
+ let imageParam = element.params.find(x => isImageParam(x));
1816
+ let image = (_q = imageParam === null || imageParam === void 0 ? void 0 : imageParam.value) !== null && _q !== void 0 ? _q : `systems/${id}/img/paperdoll_default.png`;
1817
+ return expandToNode `
1818
+ <i-paperdoll
1819
+ label="${label}"
1820
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1821
+ systemPath="system.${element.name.toLowerCase()}"
1822
+ :context="context"
1823
+ ${standardParamsFragment}
1824
+ image="${image}"
1825
+ size="${size}"
1826
+ :slots="${element.name.toLowerCase()}Slots">
1827
+ </i-paperdoll>
1828
+ `;
1829
+ }
1830
+ if (isDiceFields(element)) {
1831
+ let choicesParam = element.params.find(x => isDieChoicesParam(x));
1832
+ let choices = choicesParam ? `[${choicesParam.choices.join(", ")}]` : "[ 'd4', 'd6', 'd8', 'd10', 'd12', 'd20' ]";
1833
+ let noneParam = element.params.find(x => isDieNoneParam(x));
1834
+ let noneAttr = (noneParam === null || noneParam === void 0 ? void 0 : noneParam.value) ? `:none="true"` : '';
1835
+ if (isDieField(element)) {
1836
+ return expandToNode `
1837
+ <i-die
1838
+ :context="context"
1839
+ label="${label}"
1840
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1841
+ systemPath="${systemPath}"
1842
+ :choices="${choices}"
1843
+ ${noneAttr}
1844
+ ${standardParamsFragment}>
1845
+ </i-die>
1846
+ `;
1847
+ }
1848
+ if (isDiceField(element)) {
1849
+ return expandToNode `
1850
+ <i-dice
1851
+ label="${label}"
1852
+ icon="${iconParam === null || iconParam === void 0 ? void 0 : iconParam.value}"
1853
+ systemPath="system.${element.name.toLowerCase()}"
1854
+ :context="context"
1855
+ :editMode="editModeRef"
1856
+ :disabled="isDisabled('${element.name.toLowerCase()}')"
1857
+ v-if="!isHidden('${element.name.toLowerCase()}')"
1858
+ :choices="${choices}"
1859
+ :primaryColor="primaryColor"
1860
+ :secondaryColor="secondaryColor"
1861
+ />
1862
+ `;
1863
+ }
1864
+ }
1865
+ if (isTableField(element)) {
1866
+ if (isTopLevel)
1867
+ return expandToNode ``;
1868
+ const page = AstUtils.getContainerOfType(element, isPage);
1869
+ const pageName = (_r = page === null || page === void 0 ? void 0 : page.name) !== null && _r !== void 0 ? _r : document.name;
1870
+ const systemPath = getSystemPath(element, [], undefined, false);
1871
+ let componentName = `${document.name}${pageName}${element.name}VuetifyDatatable`;
1872
+ // Wrap in a drop zone so drag-drop works for tables inside a row/column.
1873
+ // Tables rendered as their own tab are wrapped in .tabs-container (the
1874
+ // sheet's drop target); layout-rendered tables aren't, so without this
1875
+ // wrapper they have no drop target. The wrapper only exists in the layout
1876
+ // case (never nested inside a .tabs-container), so no double drop binding.
1877
+ return expandToNode `
1878
+ <div class="datatable-drop-zone">
1879
+ <${componentName} systemPath="${systemPath}" :context="context" :primaryColor="primaryColor" :secondaryColor="secondaryColor" :teritaryColor="teritaryColor"></${componentName}>
1880
+ </div>
1881
+ `.appendNewLine();
1882
+ }
1883
+ if (isInventoryField(element)) {
1884
+ if (isTopLevel)
1885
+ return expandToNode ``;
1886
+ const systemPath = getSystemPath(element, [], undefined, false);
1887
+ const iconParam = element.params.find(p => isIconParam(p));
1888
+ const labelParam = element.params.find(p => isLabelParam(p));
1889
+ const slotsParam = element.params.find(isInventorySlotsParam);
1890
+ const rowsParam = element.params.find(isInventoryRowsParam);
1891
+ const columnsParam = element.params.find(isInventoryColumnsParam);
1892
+ const slotSizeParam = element.params.find(isInventorySlotSizeParam);
1893
+ const quantityParam = element.params.find(isInventoryQuantityParam);
1894
+ const moneyParam = element.params.find(isInventoryMoneyParam);
1895
+ const sumParam = element.params.find(isInventorySumParam);
1896
+ const sumMaxParam = element.params.find(isInventorySumMaxParam);
1897
+ const sortParam = element.params.find(isInventorySortParam);
1898
+ const whereParam = element.params.find(isWhereParam);
1899
+ const globalParam = element.params.find(isGlobalParam);
1900
+ const emptySlotsParam = element.params.find(isInventoryEmptySlotsParam);
1901
+ const summaryParam = element.params.find(isInventorySummaryParam);
1902
+ const label = labelParam ? labelParam.value : `${document.name}.${element.name}`;
1903
+ const icon = iconParam === null || iconParam === void 0 ? void 0 : iconParam.value;
1904
+ const slots = (_s = slotsParam === null || slotsParam === void 0 ? void 0 : slotsParam.value) !== null && _s !== void 0 ? _s : 20;
1905
+ const rows = rowsParam === null || rowsParam === void 0 ? void 0 : rowsParam.value;
1906
+ const columns = columnsParam === null || columnsParam === void 0 ? void 0 : columnsParam.value;
1907
+ const slotSize = slotSizeParam ? parseInt(slotSizeParam.value.replace('px', '')) : 60;
1908
+ const documentType = (_t = element.document.ref) === null || _t === void 0 ? void 0 : _t.name.toLowerCase();
1909
+ const quantityField = (_u = quantityParam === null || quantityParam === void 0 ? void 0 : quantityParam.field.ref) === null || _u === void 0 ? void 0 : _u.name.toLowerCase();
1910
+ const moneyField = (_v = moneyParam === null || moneyParam === void 0 ? void 0 : moneyParam.field.ref) === null || _v === void 0 ? void 0 : _v.name.toLowerCase();
1911
+ const moneyFieldLabel = moneyField ? `${document.name}.${(_x = (_w = moneyParam === null || moneyParam === void 0 ? void 0 : moneyParam.field) === null || _w === void 0 ? void 0 : _w.ref) === null || _x === void 0 ? void 0 : _x.name}` : undefined;
1912
+ const moneyFieldIcon = moneyField ? (_0 = (_z = (_y = moneyParam === null || moneyParam === void 0 ? void 0 : moneyParam.field) === null || _y === void 0 ? void 0 : _y.ref) === null || _z === void 0 ? void 0 : _z.params.find(isIconParam)) === null || _0 === void 0 ? void 0 : _0.value : undefined;
1913
+ const sortProperty = (_1 = sortParam === null || sortParam === void 0 ? void 0 : sortParam.property.ref) === null || _1 === void 0 ? void 0 : _1.name;
1914
+ const sortOrder = (_2 = sortParam === null || sortParam === void 0 ? void 0 : sortParam.order) !== null && _2 !== void 0 ? _2 : 'asc';
1915
+ const globalAllowed = (_3 = globalParam === null || globalParam === void 0 ? void 0 : globalParam.value) !== null && _3 !== void 0 ? _3 : false;
1916
+ const emptySlots = (_4 = emptySlotsParam === null || emptySlotsParam === void 0 ? void 0 : emptySlotsParam.value) !== null && _4 !== void 0 ? _4 : 'show';
1917
+ const summary = (_5 = summaryParam === null || summaryParam === void 0 ? void 0 : summaryParam.value) !== null && _5 !== void 0 ? _5 : 'full';
1918
+ // Handle sum properties (can be single or array)
1919
+ let sumProperties = [];
1920
+ if (sumParam) {
1921
+ if (sumParam.properties.property) {
1922
+ sumProperties = [((_6 = sumParam.properties.property.ref) === null || _6 === void 0 ? void 0 : _6.name) || ''];
1923
+ }
1924
+ else if (sumParam.properties.properties) {
1925
+ sumProperties = sumParam.properties.properties
1926
+ .map(p => { var _a; return ((_a = p.ref) === null || _a === void 0 ? void 0 : _a.name) || ''; })
1927
+ .filter(n => n !== '');
1928
+ }
1929
+ }
1930
+ // Handle sumMax (can be int, expression, or array of ints/expressions)
1931
+ let sumMax = undefined;
1932
+ if (sumMaxParam) {
1933
+ if (sumMaxParam.value !== undefined) {
1934
+ // It's a single INT
1935
+ sumMax = String(sumMaxParam.value);
1936
+ }
1937
+ else if (sumMaxParam.expression) {
1938
+ // It's a single expression (like self.CarryCapacity), translate it
1939
+ const sumMaxNode = translateExpression(entry, id, sumMaxParam.expression);
1940
+ if (sumMaxNode) {
1941
+ // Prefix with context. so it evaluates correctly in Vue template
1942
+ sumMax = `context.${toString(sumMaxNode)}`;
1943
+ }
1944
+ }
1945
+ else if ((_7 = sumMaxParam.values) === null || _7 === void 0 ? void 0 : _7.values) {
1946
+ // It's an array of ints/expressions
1947
+ const maxValues = sumMaxParam.values.values.map((val) => {
1948
+ if (typeof val === 'number') {
1949
+ return String(val);
1950
+ }
1951
+ else {
1952
+ // It's an expression, translate it
1953
+ const valNode = translateExpression(entry, id, val);
1954
+ if (valNode) {
1955
+ return `context.${toString(valNode)}`;
1956
+ }
1957
+ return '0';
1958
+ }
1959
+ });
1960
+ sumMax = `[${maxValues.join(', ')}]`;
1961
+ }
1962
+ }
1963
+ // Handle where expression
1964
+ let whereExpression = undefined;
1965
+ if (whereParam) {
1966
+ const whereNode = translateExpression(entry, id, whereParam.value);
1967
+ whereExpression = whereNode ? toString(whereNode) : undefined;
1968
+ }
1969
+ return expandToNode `
1970
+ <i-inventory
1971
+ label="${label}"
1972
+ systemPath="${systemPath}"
1973
+ :context="context"
1974
+ :editMode="editModeRef"
1975
+ ${icon ? `icon="${icon}"` : ''}
1976
+ ${slots ? `:maxSlots="${slots}"` : ''}
1977
+ ${rows ? `:rows="${rows}"` : ''}
1978
+ ${columns ? `:columns="${columns}"` : ''}
1979
+ :slotSize="${slotSize}"
1980
+ documentType="${documentType}"
1981
+ ${whereExpression ? `whereExpression="${whereExpression}"` : ''}
1982
+ ${globalAllowed ? ':globalAllowed="true"' : ''}
1983
+ ${quantityField ? `quantityField="${quantityField}"` : ''}
1984
+ ${moneyField ? `moneyField="${moneyField}"` : ''}
1985
+ ${moneyFieldLabel ? `moneyFieldLabel="${moneyFieldLabel}"` : ''}
1986
+ ${moneyFieldIcon ? `moneyFieldIcon="${moneyFieldIcon}"` : ''}
1987
+ ${sumProperties.length > 0 ? `:sumProperties='${JSON.stringify(sumProperties)}'` : ''}
1988
+ ${sumMax ? `:sumMax="${sumMax}"` : ''}
1989
+ ${sortProperty ? `sortProperty="${sortProperty}"` : ''}
1990
+ sortOrder="${sortOrder}"
1991
+ emptySlots="${emptySlots}"
1992
+ summary="${summary}"
1993
+ :primaryColor="primaryColor"
1994
+ :secondaryColor="secondaryColor"
1995
+ :teritaryColor="teritaryColor"
1996
+ />
1997
+ `.appendNewLine();
1998
+ }
1999
+ return expandToNode `
2000
+ <v-alert text="Unknown Property ${element.name}" type="warning" density="compact" class="ga-2 ma-1" variant="outlined"></v-alert>
2001
+ `;
2002
+ }
2003
+ return expandToNode `
2004
+ <v-alert text="Unknown Element" type="warning" density="compact" class="ga-2 ma-1" variant="outlined"></v-alert>
2005
+ `;
2006
+ }
2007
+ }
2008
+ //# sourceMappingURL=vue-sheet-application-generator.js.map