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,444 @@
1
+ import * as path from 'node:path';
2
+ import * as fs from 'node:fs';
3
+ import { expandToNode, toString } from 'langium/generate';
4
+ export default function generateTrackerComponent(destination) {
5
+ const generatedFileDir = path.join(destination, "system", "templates", "vue", "components");
6
+ const generatedFilePath = path.join(generatedFileDir, `tracker.vue`);
7
+ if (!fs.existsSync(generatedFileDir)) {
8
+ fs.mkdirSync(generatedFileDir, { recursive: true });
9
+ }
10
+ const fileNode = expandToNode `
11
+ <script setup>
12
+ import { ref, computed, inject, watchEffect } from "vue";
13
+
14
+ const props = defineProps({
15
+ label: String,
16
+ systemPath: String,
17
+ context: Object,
18
+ visibility: String,
19
+ editMode: Boolean,
20
+ primaryColor: String,
21
+ secondaryColor: String,
22
+ tertiaryColor: String,
23
+ trackerStyle: String,
24
+ icon: String,
25
+ hideMin: Boolean,
26
+ disableMin: Boolean,
27
+ disableValue: Boolean,
28
+ disableMax: Boolean,
29
+ segments: Number,
30
+ isHealth: Boolean,
31
+ isWounds: Boolean
32
+ });
33
+
34
+ const document = inject("rawDocument");
35
+
36
+ // Vuetify's up/down stepper buttons update the model without firing a
37
+ // native change event, so Foundry's submitOnChange form handler never
38
+ // persists them. When the value changes while focus is NOT on a text
39
+ // input (i.e. a stepper click, not typing), persist directly. Typing
40
+ // still persists via the input's native change on blur/enter.
41
+ // ('document' is the injected Foundry document; DOM access uses window.)
42
+ const persistOnStep = (path, newValue) => {
43
+ if (document && window.document.activeElement?.tagName !== 'INPUT') {
44
+ document.update({ [path]: newValue });
45
+ }
46
+ };
47
+
48
+ const isHidden = computed(() => {
49
+ if (props.visibility === "hidden") {
50
+ return true;
51
+ }
52
+ if (props.visibility === "gmOnly") {
53
+ return !game.user.isGM;
54
+ }
55
+ if (props.visibility === "secret") {
56
+ const isGm = game.user.isGM;
57
+ const isOwner = document.getUserLevel(game.user) === CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER;
58
+ return !isGm && !isOwner;
59
+ }
60
+ if (props.visibility === "edit") {
61
+ return !props.editMode;
62
+ }
63
+ if (props.visibility === "play") {
64
+ return props.editMode;
65
+ }
66
+
67
+ // Default to visible
68
+ return false;
69
+ });
70
+
71
+ const isDisabled = (type) => {
72
+ const disabledStates = ["readonly", "locked"];
73
+ if (disabledStates.includes(props.visibility)) {
74
+ return true;
75
+ }
76
+ if (props.visibility === "gmEdit") {
77
+ const isGm = game.user.isGM;
78
+ const isEditMode = props.editMode;
79
+ return !isGm && !isEditMode;
80
+ }
81
+
82
+ if (props.visibility === "unlocked") {
83
+ return false;
84
+ }
85
+
86
+ // Default to enabled while in editMode
87
+ if (type == "value") return false;
88
+ return !props.editMode;
89
+ };
90
+
91
+ const min = computed({
92
+ get: () => foundry.utils.getProperty(props.context, props.systemPath + ".min") ?? 0,
93
+ set: (newValue) => foundry.utils.setProperty(props.context, props.systemPath + ".min", newValue)
94
+ });
95
+
96
+ const value = computed({
97
+ get: () => foundry.utils.getProperty(props.context, props.systemPath + ".value"),
98
+ set: (newValue) => foundry.utils.setProperty(props.context, props.systemPath + ".value", newValue)
99
+ });
100
+
101
+ const temp = computed({
102
+ get: () => foundry.utils.getProperty(props.context, props.systemPath + ".temp") ?? 0,
103
+ set: (newValue) => foundry.utils.setProperty(props.context, props.systemPath + ".temp", newValue)
104
+ });
105
+
106
+ const max = computed({
107
+ get: () => foundry.utils.getProperty(props.context, props.systemPath + ".max") ?? 10000,
108
+ set: (newValue) => foundry.utils.setProperty(props.context, props.systemPath + ".max", newValue)
109
+ });
110
+
111
+ const barMax = computed(() => {
112
+ const totalValue = Math.floor(value.value + (temp.value ?? 0));
113
+ const floorMax = Math.floor(max.value);
114
+ if (totalValue > floorMax) return totalValue;
115
+ return floorMax;
116
+ });
117
+
118
+ const circleValue = computed(() => {
119
+ // We need to calculate the percentage of the value in relation to the min to max range
120
+ const percentage = (value.value - min.value) / (max.value - min.value);
121
+ return Math.round(percentage * 100);
122
+ });
123
+
124
+ const refill = () => value.value = max.value;
125
+ const empty = () => value.value = 0;
126
+
127
+ const filledIcon = computed(() => {
128
+ if (!props.icon) return "fa-solid fa-star";
129
+ return "fa-solid " + props.icon;
130
+ });
131
+ const emptyIcon = computed(() => {
132
+ if (!props.icon) return "fa-regular fa-star";
133
+ return "fa-regular " + props.icon;
134
+ });
135
+
136
+ const mainColor = computed(() => {
137
+ // If this is health, use a scale of red (0) to green (max). Wounds should be reverse. Otherwise, use primary.
138
+
139
+ if (props.isHealth) {
140
+ const pct = (value.value - (min.value ?? 0)) / ((max.value ?? 0) - (min.value ?? 0));
141
+ // Use the number === 0 logic for health
142
+ const red = Math.round(255 * (1 - (pct / 2)));
143
+ const green = Math.round(255 * pct);
144
+ const blue = 0;
145
+ return \`rgb(\${red}, \${green}, \${blue})\`;
146
+ }
147
+ if (props.isWounds) {
148
+ const pct = (value.value - (min.value ?? 0)) / ((max.value ?? 0) - (min.value ?? 0));
149
+ // Use the else logic for wounds
150
+ const red = Math.round(255 * (0.5 * pct));
151
+ const green = Math.round(255 * (0.7 * pct));
152
+ const blue = Math.round(255 * (0.5 + (pct / 2)));
153
+ return \`rgb(\${red}, \${green}, \${blue})\`;
154
+ }
155
+ return props.primaryColor;
156
+ });
157
+
158
+ const expanded = ref(false);
159
+
160
+ const expandIcon = computed(() => {
161
+ return expanded.value ? "fa-solid fa-caret-up" : "fa-solid fa-caret-down";
162
+ });
163
+
164
+ const displayText = computed(() => {
165
+ if (temp.value > 0) {
166
+ return value.value + " / " + max.value + " (+" + temp.value + ")";
167
+ }
168
+ return value.value + " / " + max.value;
169
+ });
170
+
171
+ const circularText = computed(() => {
172
+ return value.value + " / " + max.value;
173
+ });
174
+
175
+ const add = () => {
176
+ if (props.disableValue || isDisabled('value')) return;
177
+ if (value.value < max.value) {
178
+ value.value++;
179
+ }
180
+ }
181
+
182
+ const remove = () => {
183
+ if (props.disableValue || isDisabled('value')) return;
184
+ if (value.value > min.value) {
185
+ value.value--;
186
+ }
187
+ }
188
+
189
+ const getSegmentFill = (segmentIndex) => {
190
+ const filled = value.value;
191
+ const tempFilled = filled + (temp?.value ?? 0);
192
+ const segmentStart = (segmentIndex - 1) * props.segments;
193
+ const segmentEnd = segmentIndex * props.segments;
194
+
195
+ const primaryFill = Math.min(Math.max(filled - segmentStart, 0), props.segments);
196
+ const tempFill = Math.min(Math.max(tempFilled - segmentStart, 0), props.segments);
197
+
198
+ const primaryPct = (primaryFill / props.segments) * 100;
199
+ const tempPct = (tempFill / props.segments) * 100;
200
+
201
+ const fill = \`linear-gradient(
202
+ to right,
203
+ \${mainColor.value} 0%,
204
+ \${mainColor.value} \${primaryPct}%,
205
+ \${props.tertiaryColor} \${primaryPct}%,
206
+ \${props.tertiaryColor} \${tempPct}%,
207
+ transparent \${tempPct}%
208
+ )\`;
209
+
210
+ const segmentLines = \`repeating-linear-gradient(
211
+ to right,
212
+ \${props.secondaryColor} 0,
213
+ \${props.secondaryColor} 1px,
214
+ transparent 1px,
215
+ transparent calc(100% / \${props.segments})
216
+ )\`;
217
+
218
+ return \`\${segmentLines}, \${fill}\`;
219
+ };
220
+
221
+ const size = 100;
222
+ const radius = size / 2 - 2;
223
+
224
+ function describeSlice(index, total, r, center) {
225
+ const anglePer = (2 * Math.PI) / total;
226
+ const startAngle = anglePer * index - Math.PI / 2;
227
+ const endAngle = startAngle + anglePer;
228
+
229
+ const x1 = center + r * Math.cos(startAngle);
230
+ const y1 = center + r * Math.sin(startAngle);
231
+ const x2 = center + r * Math.cos(endAngle);
232
+ const y2 = center + r * Math.sin(endAngle);
233
+
234
+ const largeArcFlag = anglePer > Math.PI ? 1 : 0;
235
+
236
+ return \`
237
+ M \${center} \${center}
238
+ L \${x1} \${y1}
239
+ A \${r} \${r} 0 \${largeArcFlag} 1 \${x2} \${y2}
240
+ Z
241
+ \`;
242
+ }
243
+
244
+ const getLabel = computed(() => {
245
+ const localized = game.i18n.localize(props.label);
246
+ if (props.icon) {
247
+ return \`<i class="fa-solid \${props.icon}"></i> \${localized}\`;
248
+ }
249
+ return localized;
250
+ });
251
+ </script>
252
+
253
+ <template>
254
+ <v-input v-model="value" :class="[trackerStyle, 'isdl-tracker']" v-if="!isHidden">
255
+ <template #default>
256
+ <v-field
257
+ class="v-field--active"
258
+ density="compact"
259
+ variant="outlined"
260
+ >
261
+ <template #label>
262
+ <span v-html="getLabel" />
263
+ </template>
264
+ <template #append-inner>
265
+ <v-icon
266
+ :icon="expandIcon"
267
+ @click.stop="expanded = !expanded"
268
+ class="v-select__menu-icon"
269
+ />
270
+ </template>
271
+ <div class="tracker-content flexcol">
272
+ <div class="d-flex tracker-inner-content">
273
+ <v-progress-linear
274
+ v-if="trackerStyle == 'bar'"
275
+ :height="18"
276
+ :color="mainColor"
277
+ bg-color="#92aed9"
278
+ rounded
279
+ :model-value="value"
280
+ min="0"
281
+ :data-tooltip="displayText"
282
+ :max="barMax"
283
+ :buffer-value="value + temp"
284
+ buffer-opacity="1"
285
+ :buffer-color="tertiaryColor"
286
+ >
287
+ <template v-slot:default>
288
+ {{ displayText }}
289
+ </template>
290
+ </v-progress-linear>
291
+
292
+ <v-progress-circular
293
+ v-if="trackerStyle == 'dial'"
294
+ :model-value="circleValue"
295
+ :rotate="360"
296
+ :size="100"
297
+ :width="15"
298
+ :data-tooltip="displayText"
299
+ :color="mainColor">
300
+
301
+ <template v-slot:default> {{ circularText }} </template>
302
+ </v-progress-circular>
303
+
304
+ <div v-if="trackerStyle == 'icons'" class="d-flex flex-row" @click.stop="add" @contextmenu.prevent.stop="remove" style="overflow-x: auto; overflow-y: hidden;">
305
+ <v-icon v-if="value > 0" v-for="i in Math.floor(value)" :key="i" :icon="filledIcon" :color="mainColor" style="margin-right: 0.25rem; width: 25px;" :data-tooltip="displayText" />
306
+ <v-icon v-if="temp > 0" v-for="i in Math.floor(temp)" :key="i + value" :icon="filledIcon" :color="tertiaryColor" style="margin-right: 0.25rem; width: 25px;" :data-tooltip="displayText" />
307
+ <v-icon v-if="Math.floor(max - value - temp) > 0" v-for="i in Math.floor(max - value - temp)" :key="i + temp + value" :icon="emptyIcon" :color="secondaryColor" style="margin-right: 0.25rem; width: 25px;" :data-tooltip="displayText" />
308
+ </div>
309
+
310
+ <div v-if="trackerStyle == 'slashes'" class="d-flex flex-row" @click.stop="add" @contextmenu.prevent.stop="remove" style="overflow-x: scroll; padding-left: 0.5rem; padding-right: 0.5rem;">
311
+ <div
312
+ v-for="i in barMax"
313
+ :data-tooltip="displayText"
314
+ :key="i"
315
+ :style="{
316
+ flex: 1,
317
+ minWidth: '5px',
318
+ flexShrink: 0,
319
+ height: '30px',
320
+ backgroundColor: i <= value ? mainColor : (i <= value + temp ? tertiaryColor : 'transparent'),
321
+ border: i <= value ? 'none' : '2px solid ' + secondaryColor,
322
+ transform: 'skewX(-20deg)',
323
+ borderRadius: '2px',
324
+ marginRight: '0.25rem'
325
+ }"
326
+ />
327
+ </div>
328
+
329
+ <div v-if="trackerStyle == 'segmented'" class="d-flex flex-row" @click.stop="add" @contextmenu.prevent.stop="remove">
330
+ <div
331
+ v-for="i in Math.ceil(barMax / segments)"
332
+ :key="i"
333
+ :data-tooltip="displayText"
334
+ :style="{
335
+ flex: 1,
336
+ minWidth: '15px',
337
+ flexShrink: 0,
338
+ height: '30px',
339
+ border: '2px solid ' + secondaryColor,
340
+ borderRadius: '2px',
341
+ marginRight: '0.25rem',
342
+ background: getSegmentFill(i)
343
+ }"
344
+ />
345
+ </div>
346
+
347
+ <svg
348
+ v-if="trackerStyle === 'clock'"
349
+ :width="size"
350
+ :height="size"
351
+ :viewBox="\`0 0 \${size} \${size}\`"
352
+ @click.stop="add"
353
+ @contextmenu.prevent.stop="remove"
354
+ :data-tooltip="displayText"
355
+ style="width: auto;"
356
+ >
357
+ <g v-for="i in barMax" :key="i">
358
+ <path
359
+ :d="describeSlice(i - 1, barMax, radius, size / 2)"
360
+ :fill="i <= value ? mainColor : (i <= value + temp ? tertiaryColor: 'transparent')"
361
+ :stroke="secondaryColor"
362
+ stroke-width="2"
363
+ />
364
+ </g>
365
+ </svg>
366
+
367
+ <v-number-input v-if="trackerStyle == 'plain'" :model-value="value" @update:model-value="(v) => { value = v; persistOnStep(systemPath + '.value', v); }" :name="systemPath" :min="min" :max="max" :disabled="disabled" type="number" variant="outlined" density="compact" hide-details="true"></v-number-input>
368
+ </div>
369
+ <v-expand-transition>
370
+ <div v-show="expanded" style="margin-top: 1rem;">
371
+ <div class="d-flex flex-row">
372
+ <v-number-input
373
+ :model-value="value"
374
+ @update:model-value="(v) => { value = v; persistOnStep(systemPath + '.value', v); }"
375
+ :name="systemPath + '.value'"
376
+ label="Value"
377
+ controlVariant="stacked"
378
+ density="compact"
379
+ variant="outlined"
380
+ class="flex-grow-1 slim-number"
381
+ style="min-width: 70px;"
382
+ :hide-details="true"
383
+ :tile="true"
384
+ :disabled="isDisabled('value') || disableValue"
385
+ />
386
+ <v-number-input
387
+ :model-value="temp"
388
+ @update:model-value="(v) => { temp = v; persistOnStep(systemPath + '.temp', v); }"
389
+ :name="systemPath + '.temp'"
390
+ label="Temp"
391
+ controlVariant="stacked"
392
+ density="compact"
393
+ variant="outlined"
394
+ class="flex-grow-1"
395
+ style="min-width: 70px; margin-right: 0.5rem;"
396
+ :hide-details="true"
397
+ :tile="true"
398
+ :disabled="isDisabled('value') || disableValue"
399
+ />
400
+ <v-btn size="small" icon="fa-solid fa-battery-empty" @click="empty" :disabled="isDisabled('value') || disableValue" data-tooltip="Empty" :color="secondaryColor" />
401
+ </div>
402
+ <div class="d-flex flex-row" style="margin-top: 1rem;">
403
+ <v-number-input
404
+ :model-value="min"
405
+ @update:model-value="(v) => { min = v; persistOnStep(systemPath + '.min', v); }"
406
+ :name="systemPath + '.min'"
407
+ label="Min"
408
+ controlVariant="stacked"
409
+ density="compact"
410
+ variant="outlined"
411
+ class="flex-grow-1 slim-number"
412
+ style="min-width: 70px;"
413
+ :hide-details="true"
414
+ :tile="true"
415
+ :disabled="isDisabled('min') || disableMin"
416
+ v-if="!hideMin"
417
+ />
418
+ <v-number-input
419
+ :model-value="max"
420
+ @update:model-value="(v) => { max = v; persistOnStep(systemPath + '.max', v); }"
421
+ :name="systemPath + '.max'"
422
+ label="Max"
423
+ controlVariant="stacked"
424
+ density="compact"
425
+ variant="outlined"
426
+ class="flex-grow-1"
427
+ style="min-width: 70px; margin-right: 0.5rem;"
428
+ :hide-details="true"
429
+ :tile="true"
430
+ :disabled="isDisabled('max') || disableMax"
431
+ />
432
+ <v-btn size="small" icon="fa-solid fa-battery-full" @click="refill" :disabled="isDisabled('value') || disableValue" data-tooltip="Refill" :color="secondaryColor" />
433
+ </div>
434
+ </div>
435
+ </v-expand-transition>
436
+ </div>
437
+ </v-field>
438
+ </template>
439
+ </v-input>
440
+ </template>
441
+ `;
442
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
443
+ }
444
+ //# sourceMappingURL=vue-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue-tracker.js","sourceRoot":"","sources":["../../../../../src/cli/components/vue/base-components/vue-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAC,YAAY,EAAE,QAAQ,EAAC,MAAM,kBAAkB,CAAC;AAExD,MAAM,CAAC,OAAO,UAAU,wBAAwB,CAAC,WAAmB;IAChE,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,YAAY,CAAC,CAAC;IAC5F,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,aAAa,CAAC,CAAC;IAErE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE;QAClC,EAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAC,SAAS,EAAE,IAAI,EAAC,CAAC,CAAC;KACrD;IAED,MAAM,QAAQ,GAAG,YAAY,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KA+a5B,CAAC;IACF,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,88 @@
1
+ import * as path from 'node:path';
2
+ import * as fs from 'node:fs';
3
+ import { expandToNode, toString } from 'langium/generate';
4
+ import { isActor, isIconParam, isPrompt, isVariableExpression } from "../../../language/generated/ast.js";
5
+ import { generatePromptApp } from './vue-prompt-generator.js';
6
+ import { generatePromptSheetClass } from './vue-prompt-sheet-class-generator.js';
7
+ export function generateActionComponent(entry, id, document, action, destination) {
8
+ const type = isActor(document) ? 'actor' : 'item';
9
+ const generatedFileDir = path.join(destination, "system", "templates", "vue", type, document.name.toLowerCase(), "components", "actions");
10
+ const generatedFilePath = path.join(generatedFileDir, `${document.name.toLowerCase()}${action.name}Action.vue`);
11
+ const iconParam = action.params.find(x => isIconParam(x));
12
+ const variables = action.method.body.filter(x => isVariableExpression(x));
13
+ const prompts = variables.filter(x => isPrompt(x.value)).map(x => x.value);
14
+ for (const prompt of prompts) {
15
+ generatePromptSheetClass(action.name, entry, id, document, prompt, destination);
16
+ generatePromptApp(action.name, entry, id, document, prompt, destination);
17
+ }
18
+ if (!fs.existsSync(generatedFileDir)) {
19
+ fs.mkdirSync(generatedFileDir, { recursive: true });
20
+ }
21
+ const fileNode = expandToNode `
22
+ <script setup>
23
+ import { inject, computed } from "vue";
24
+
25
+ const props = defineProps({
26
+ context: Object,
27
+ color: String,
28
+ editMode: Boolean,
29
+ visibility: String
30
+ });
31
+
32
+ const document = inject('rawDocument');
33
+
34
+ const onClick = async (e) => {
35
+ document.sheet._on${action.name}Action(e, props.context);
36
+ };
37
+
38
+ const disabled = computed(() => {
39
+ //console.log("Action ${action.name} disabled computed triggered", props.visibility, props.editMode);
40
+ const disabledStates = ["readonly", "locked"];
41
+ if (disabledStates.includes(props.visibility)) {
42
+ return true;
43
+ }
44
+ if (props.visibility === "gmEdit") {
45
+ const isGm = game.user.isGM;
46
+ const isEditMode = props.editMode;
47
+ return !isGm && !isEditMode;
48
+ }
49
+
50
+ if (props.visibility === "unlocked") {
51
+ return false;
52
+ }
53
+
54
+ // Default to disabled while in editMode
55
+ return props.editMode;
56
+ });
57
+
58
+ const hidden = computed(() => {
59
+ //console.log("Action ${action.name} hidden computed triggered", props.visibility, props.editMode);
60
+ if (props.visibility === "hidden") {
61
+ return true;
62
+ }
63
+ if (props.visibility === "gmOnly") {
64
+ return !game.user.isGM;
65
+ }
66
+ if (props.visibility === "secret") {
67
+ const isGm = game.user.isGM;
68
+ const isOwner = document.getUserLevel(game.user) === CONST.DOCUMENT_OWNERSHIP_LEVELS.OWNER;
69
+ return !isGm && !isOwner;
70
+ }
71
+ if (props.visibility === "edit") {
72
+ return !props.editMode;
73
+ }
74
+ if (props.visibility === "play") {
75
+ return props.editMode;
76
+ }
77
+
78
+ // Default to visible
79
+ return false;
80
+ });
81
+ </script>
82
+ <template>
83
+ <v-btn :color="color" class="action-btn" @click="onClick" v-if="!hidden" :disabled="disabled" ${iconParam ? `prepend-icon="${iconParam.value}"` : ''} :data-tooltip="game.i18n.localize('${document.name}.${action.name}')">{{game.i18n.localize('${document.name}.${action.name}')}}</v-btn>
84
+ </template>
85
+ `;
86
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
87
+ }
88
+ //# sourceMappingURL=vue-action-component-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue-action-component-generator.js","sourceRoot":"","sources":["../../../../src/cli/components/vue/vue-action-component-generator.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAsC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,oBAAoB,EAA8B,MAAM,oCAAoC,CAAC;AAC1K,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AAEjF,MAAM,UAAU,uBAAuB,CAAC,KAAY,EAAE,EAAU,EAAE,QAAkB,EAAE,MAAc,EAAE,WAAmB;IACrH,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;IAClD,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,YAAY,EAAE,SAAS,CAAC,CAAC;IAC1I,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,MAAM,CAAC,IAAI,YAAY,CAAC,CAAC;IAChH,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,CAA0B,CAAC;IAEnF,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAyB,CAAC;IAClG,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAa,CAAC;IACvF,KAAM,MAAM,MAAM,IAAI,OAAO,EAAG;QAC5B,wBAAwB,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;QAChF,iBAAiB,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC;KAC5E;IAED,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE;QAClC,EAAE,CAAC,SAAS,CAAC,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;KACvD;IAED,MAAM,QAAQ,GAAG,YAAY,CAAA;;;;;;;;;;;;;;gCAcD,MAAM,CAAC,IAAI;;;;oCAIP,MAAM,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;oCAoBX,MAAM,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;wGAwByD,SAAS,CAAC,CAAC,CAAC,iBAAiB,SAAS,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,uCAAuC,QAAQ,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,6BAA6B,QAAQ,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI;;KAEnR,CAAC;IAEF,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC5D,CAAC"}