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,138 @@
1
+ import { expandToNode, toString } from 'langium/generate';
2
+ import * as fs from 'node:fs';
3
+ import * as path from 'node:path';
4
+ export function generateCanvasToken(entry, id, destination) {
5
+ const generatedFileDir = path.join(destination, "system", "canvas");
6
+ const generatedFilePath = path.join(generatedFileDir, `token.mjs`);
7
+ if (!fs.existsSync(generatedFileDir)) {
8
+ fs.mkdirSync(generatedFileDir, { recursive: true });
9
+ }
10
+ const fileNode = expandToNode `
11
+ export default class ${entry.config.name}Token extends Token {
12
+ /** @inheritDoc */
13
+ _drawBar(number, bar, data) {
14
+ const resource = foundry.utils.getProperty(this.document.actor.system, data.attribute);
15
+
16
+ if (resource.temp <= 0) {
17
+ return super._drawBar(number, bar, data);
18
+ }
19
+
20
+ const displayMax = resource.max;
21
+
22
+ const tempPct = Math.clamp(resource.temp, 0, displayMax) / displayMax;
23
+ const colorPct = Math.clamp(resource.value, 0, displayMax) / displayMax;
24
+
25
+ // Determine the container size (logic borrowed from core)
26
+ const w = this.w;
27
+ let h = Math.max((canvas.dimensions.size / 12), 8);
28
+ if (this.document.height >= 2) h *= 1.6;
29
+ const bs = Math.clamp(h / 8, 1, 2);
30
+ const bs1 = bs + 1;
31
+
32
+ // Determine the color to use
33
+ const blk = 0x000000;
34
+ let color;
35
+ if ( number === 0 ) color = Color.fromRGB([(1-(colorPct/2)), colorPct, 0]);
36
+ else color = Color.fromRGB([(0.5 * colorPct), (0.7 * colorPct), 0.5 + (colorPct / 2)]);
37
+
38
+ // Overall bar container
39
+ bar.clear();
40
+ bar.beginFill(blk, 0.5).lineStyle(bs, blk, 1.0).drawRoundedRect(0, 0, w, h, 3);
41
+
42
+ // Health bar
43
+ bar.beginFill(color, 1.0).lineStyle(bs, blk, 1.0).drawRoundedRect(0, 0, colorPct*w, h, 2);
44
+
45
+ function getBlendedContrast(color, blendFactor = 0.3) {
46
+ // Convert color to hex string
47
+ let hex = color.toString(16).padStart(6, "0");
48
+
49
+ // Extract RGB components
50
+ let r = parseInt(hex.substring(0, 2), 16);
51
+ let g = parseInt(hex.substring(2, 4), 16);
52
+ let b = parseInt(hex.substring(4, 6), 16);
53
+
54
+ // Calculate luminance
55
+ let luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
56
+
57
+ // Determine base contrast color (black or white)
58
+ let baseContrast = luminance > 0.5 ? 0x000000 : 0xFFFFFF;
59
+
60
+ // Extract RGB from base contrast
61
+ let bcR = (baseContrast >> 16) & 0xFF;
62
+ let bcG = (baseContrast >> 8) & 0xFF;
63
+ let bcB = baseContrast & 0xFF;
64
+
65
+ // Blend original color with contrast color
66
+ let blendedR = Math.round(r * (1 - blendFactor) + bcR * blendFactor);
67
+ let blendedG = Math.round(g * (1 - blendFactor) + bcG * blendFactor);
68
+ let blendedB = Math.round(b * (1 - blendFactor) + bcB * blendFactor);
69
+
70
+ // Return new blended color
71
+ return (blendedR << 16) | (blendedG << 8) | blendedB;
72
+ }
73
+
74
+ // Calculate a temporary color that is a lighter shade than color
75
+ const tempColor = number === 0 ? 0x33AAFF : getBlendedContrast(color);
76
+
77
+ // Temporary health bar
78
+
79
+ const blur = new PIXI.filters.BlurFilter();
80
+ blur.blur = 1; // Adjust for stronger glow
81
+
82
+ const colorMatrix = new PIXI.filters.ColorMatrixFilter();
83
+ colorMatrix.brightness(1.2); // Increase brightness
84
+
85
+ const tempBar = new PIXI.Graphics();
86
+ tempBar.filters = [blur, colorMatrix];
87
+ tempBar.beginFill(tempColor, 1.0).lineStyle(0).drawRoundedRect(bs1, bs1, (tempPct*w)-(2*bs1), h-(2*bs1), 1)
88
+
89
+ bar.addChild(tempBar);
90
+
91
+ // Animation - Flashing (Opacity Pulse)
92
+ canvas.app.ticker.add((delta) => {
93
+ tempBar.alpha = 0.7 + 0.3 * Math.sin(performance.now() / 1000);
94
+ });
95
+
96
+ // Set position
97
+ let posY = number === 0 ? this.h - h : 0;
98
+ bar.position.set(0, posY);
99
+ }
100
+
101
+ /* -------------------------------------------- */
102
+
103
+ static onTargetToken(user, token, targeted) {
104
+ if ( !targeted ) return;
105
+ if ( !token.hasDynamicRing ) return;
106
+ const color = Color.from(user.color);
107
+ token.ring.flashColor(color, { duration: 500, easing: token.ring.constructor.easeTwoPeaks });
108
+ }
109
+ }
110
+ `.appendNewLineIfNotEmpty();
111
+ fs.writeFileSync(generatedFilePath, toString(fileNode), 'utf-8');
112
+ }
113
+ export function generateTokenDocument(entry, id, destination) {
114
+ const generatedFileDir = path.join(destination, "system", "documents");
115
+ const generatedFilePath = path.join(generatedFileDir, `token.mjs`);
116
+ if (!fs.existsSync(generatedFileDir)) {
117
+ fs.mkdirSync(generatedFileDir, { recursive: true });
118
+ }
119
+ const fileNode = expandToNode `
120
+ export default class ${entry.config.name}TokenDocument extends TokenDocument {
121
+ /** @inheritDoc */
122
+ getBarAttribute(barName, options={}) {
123
+ const data = super.getBarAttribute(barName, options);
124
+ if ( data === null ) return;
125
+ const resource = foundry.utils.getProperty(this.actor.system, data.attribute);
126
+ data.value += resource.temp;
127
+ return data;
128
+ }
129
+
130
+ _onUpdateBaseActor(update={}, options={}) {
131
+ if (foundry.utils.isEmpty(update)) return;
132
+ if (!this.isEditable) return;
133
+ super._onUpdateBaseActor(update, options);
134
+ }
135
+ }`.appendNewLineIfNotEmpty();
136
+ fs.writeFileSync(generatedFilePath, toString(fileNode), 'utf-8');
137
+ }
138
+ //# sourceMappingURL=token-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-generator.js","sourceRoot":"","sources":["../../../src/cli/components/token-generator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAGlC,MAAM,UAAU,mBAAmB,CAAC,KAAY,EAAE,EAAU,EAAE,WAAmB;IAC7E,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;IACpE,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IAEnE,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;2BACN,KAAK,CAAC,MAAM,CAAC,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAmGvC,CAAC,uBAAuB,EAAE,CAAC;IAE5B,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,KAAY,EAAE,EAAU,EAAE,WAAmB;IAC/E,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;IACvE,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;IAEnE,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;2BACN,KAAK,CAAC,MAAM,CAAC,IAAI;;;;;;;;;;;;;;;MAetC,CAAC,uBAAuB,EAAE,CAAC;IAE7B,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;AACrE,CAAC"}
@@ -0,0 +1,176 @@
1
+ import { AstUtils } from 'langium';
2
+ import { isDamageTypeChoiceField, } from '../../language/generated/ast.js';
3
+ import { isResourceExp, isAttributeExp, isPage, isInitiativeProperty, isDocument, isIfStatement, isParentTypeCheckExpression, isTrackerExp, isParentAccess, isTargetTypeCheckExpression, isLayout, isStringChoiceField, isTargetAccess, isDocumentChoiceExp, isDiceField, } from "../../language/generated/ast.js";
4
+ export function toMachineIdentifier(s) {
5
+ return s.replace(/[^a-zA-Z0-9]/g, '');
6
+ }
7
+ function getPropertyAccessorSuffix(property) {
8
+ if (isResourceExp(property) || isTrackerExp(property) || isStringChoiceField(property) || isDiceField(property) || isDamageTypeChoiceField(property)) {
9
+ return '.value';
10
+ }
11
+ else if (isAttributeExp(property)) {
12
+ return '.mod';
13
+ }
14
+ // For numbers and other types (string, boolean, etc.), no additional accessor needed
15
+ return '';
16
+ }
17
+ function appendPropertyAccessor(systemPath, document, propertyName, safeAccess = true) {
18
+ if (!document || !document.body) {
19
+ return systemPath;
20
+ }
21
+ const allProperties = getAllOfType(document.body, (p) => true);
22
+ const targetProperty = allProperties.find(prop => 'name' in prop && prop.name && prop.name.toLowerCase() === propertyName.toLowerCase());
23
+ if (targetProperty) {
24
+ const suffix = getPropertyAccessorSuffix(targetProperty);
25
+ if (suffix) {
26
+ const accessor = safeAccess ? '?' : '';
27
+ return `${systemPath}${accessor}${suffix}`;
28
+ }
29
+ }
30
+ return systemPath;
31
+ }
32
+ export function getSystemPath(reference, subProperties = [], generatingProperty = undefined, safeAccess = true) {
33
+ // Not all references are to the baseline - resources and attributes have sub-paths
34
+ if (reference == undefined) {
35
+ return "";
36
+ }
37
+ if (isInitiativeProperty(reference)) {
38
+ return "initiative";
39
+ }
40
+ // If the property is "name", that is at the base of the object, not system
41
+ if (reference.name.toLowerCase() === "name") {
42
+ return reference.name.toLowerCase();
43
+ }
44
+ let basePath = "system.";
45
+ // If we are accessing a sub-property of a resource or attribute, we need to use the appropriate sub-path
46
+ if (subProperties.length > 0) {
47
+ let systemPath = `${basePath}${reference.name.toLowerCase()}`;
48
+ // For dice fields with number/die subproperties, we access them directly on the dice object
49
+ // No need to add .value for these specific subproperties
50
+ if (subProperties.length > 0) {
51
+ if (isDocumentChoiceExp(reference) ||
52
+ isParentAccess(generatingProperty) || isTargetAccess(generatingProperty)) {
53
+ if (safeAccess) {
54
+ systemPath = `${systemPath}?.system`;
55
+ }
56
+ else {
57
+ systemPath = `${systemPath}.system`;
58
+ }
59
+ }
60
+ }
61
+ // Process all sub-properties except the last one
62
+ for (let i = 0; i < subProperties.length - 1; i++) {
63
+ const subProperty = subProperties[i];
64
+ if (safeAccess) {
65
+ systemPath = `${systemPath}?.${subProperty.toLowerCase()}`;
66
+ }
67
+ else {
68
+ systemPath = `${systemPath}.${subProperty.toLowerCase()}`;
69
+ }
70
+ }
71
+ // Handle the final sub-property - need to determine if it should have .value/.mod appended
72
+ if (subProperties.length > 0) {
73
+ const finalProperty = subProperties[subProperties.length - 1];
74
+ const finalPropertyLower = finalProperty.toLowerCase();
75
+ if (safeAccess) {
76
+ systemPath = `${systemPath}?.${finalPropertyLower}`;
77
+ }
78
+ else {
79
+ systemPath = `${systemPath}.${finalPropertyLower}`;
80
+ }
81
+ // For document choice accesses, we need special handling
82
+ if (isDocumentChoiceExp(reference)) {
83
+ const referencedDocument = reference.document.ref;
84
+ if (referencedDocument) {
85
+ // For string choice fields, check if we're accessing a metadata property
86
+ if (isStringChoiceField(reference)) {
87
+ // Metadata properties are accessed directly (e.g., system.training.bonus)
88
+ // Choice value itself would be accessed as system.training.value
89
+ // Since we have subproperties, this must be a metadata access - don't append .value
90
+ }
91
+ else {
92
+ // For non-choice fields, use normal property accessor logic
93
+ systemPath = appendPropertyAccessor(systemPath, referencedDocument, finalProperty, safeAccess);
94
+ }
95
+ }
96
+ }
97
+ // For parent/target accesses, use document-based property type detection
98
+ else if (isParentAccess(generatingProperty) || isTargetAccess(generatingProperty)) {
99
+ const referencedDocument = isParentAccess(generatingProperty)
100
+ ? getParentDocument(generatingProperty)
101
+ : getTargetDocument(generatingProperty);
102
+ if (referencedDocument) {
103
+ systemPath = appendPropertyAccessor(systemPath, referencedDocument, finalProperty, safeAccess);
104
+ }
105
+ }
106
+ }
107
+ return systemPath;
108
+ }
109
+ const suffix = getPropertyAccessorSuffix(reference);
110
+ return `${basePath}${reference.name.toLowerCase()}${suffix}`;
111
+ }
112
+ export function getAllOfType(body, comparisonFunc, samePageOnly = false) {
113
+ if (!body)
114
+ return [];
115
+ let result = [];
116
+ const matchingResults = body.filter(x => comparisonFunc(x)).map(x => x);
117
+ result.push(...matchingResults);
118
+ if (!samePageOnly) {
119
+ for (let page of body.filter(x => isPage(x)).map(x => x)) {
120
+ if (page.body) {
121
+ result.push(...getAllOfType(page.body, comparisonFunc, samePageOnly));
122
+ }
123
+ }
124
+ }
125
+ for (let layout of body.filter(x => isLayout(x) && !isPage(x)).map(x => x)) {
126
+ if (layout.body) {
127
+ result.push(...getAllOfType(layout.body, comparisonFunc, samePageOnly));
128
+ }
129
+ }
130
+ for (let document of body.filter(x => isDocument(x)).map(x => x)) {
131
+ if (document.body) {
132
+ result.push(...getAllOfType(document.body, comparisonFunc, samePageOnly));
133
+ }
134
+ }
135
+ return result;
136
+ }
137
+ export function globalGetAllOfType(entry, comparisonFunc) {
138
+ let result = [];
139
+ for (let document of entry.documents) {
140
+ result.push(...getAllOfType(document.body, comparisonFunc, false));
141
+ }
142
+ return result;
143
+ }
144
+ export function getParentDocument(parentAccess) {
145
+ const ifStatement = AstUtils.getContainerOfType(parentAccess.$container, (n) => {
146
+ const isIf = isIfStatement(n);
147
+ if (!isIf)
148
+ return false;
149
+ return isParentTypeCheckExpression(n.expression);
150
+ });
151
+ const parentTypeCheck = ifStatement.expression;
152
+ if (parentTypeCheck == undefined) {
153
+ console.error("Parent type check not found");
154
+ return undefined;
155
+ }
156
+ return parentTypeCheck.document.ref;
157
+ }
158
+ export function getTargetDocument(targetAccess) {
159
+ const ifStatement = AstUtils.getContainerOfType(targetAccess.$container, (n) => {
160
+ const isIf = isIfStatement(n);
161
+ if (!isIf)
162
+ return false;
163
+ return isTargetTypeCheckExpression(n.expression);
164
+ });
165
+ const targetTypeCheck = ifStatement.expression;
166
+ if (targetTypeCheck == undefined) {
167
+ console.error("Target type check not found");
168
+ return undefined;
169
+ }
170
+ return targetTypeCheck.document.ref;
171
+ }
172
+ export function getDocument(property) {
173
+ const document = AstUtils.getContainerOfType(property.$container, isDocument);
174
+ return document;
175
+ }
176
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/cli/components/utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,148 @@
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 generateAttributeComponent(destination) {
5
+ const generatedFileDir = path.join(destination, "system", "templates", "vue", "components");
6
+ const generatedFilePath = path.join(generatedFileDir, `attribute.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 } from "vue";
13
+
14
+ const props = defineProps({
15
+ label: String,
16
+ icon: String,
17
+ hasMod: Boolean,
18
+ mod: Number,
19
+ systemPath: String,
20
+ context: Object,
21
+ min: Number,
22
+ disabled: Boolean,
23
+ primaryColor: String,
24
+ secondaryColor: String,
25
+ editMode: Boolean,
26
+ attributeStyle: String, // plain or box
27
+ roll: Function,
28
+ hasRoll: Boolean
29
+ });
30
+
31
+ const document = inject("rawDocument");
32
+
33
+ const value = computed({
34
+ get: () => foundry.utils.getProperty(props.context, props.systemPath),
35
+ set: (newValue) => foundry.utils.setProperty(props.context, props.systemPath, newValue)
36
+ });
37
+
38
+ // Vuetify's up/down stepper buttons update the model without firing a
39
+ // native change event, so Foundry's submitOnChange form handler never
40
+ // persists them. When the value changes while focus is NOT on a text
41
+ // input (i.e. a stepper click, not typing), persist directly. Typing
42
+ // still persists via the input's native change on blur/enter.
43
+ // ('document' is the injected Foundry document; DOM access uses window.)
44
+ const persistOnStep = (path, newValue) => {
45
+ if (document && window.document.activeElement?.tagName !== 'INPUT') {
46
+ document.update({ [path]: newValue });
47
+ }
48
+ };
49
+
50
+ const getStyle = computed(() => {
51
+ const p = props.primaryColor || "#92aed9";
52
+
53
+ // Get either black or white text color based on the primary color brightness
54
+ const brightness = (parseInt(p.slice(1, 3), 16) * 299 + parseInt(p.slice(3, 5), 16) * 587 + parseInt(p.slice(5, 7), 16) * 114) / 1000;
55
+ let textColor = "#ffffff"; // Default to white text
56
+ if (brightness > 128) {
57
+ textColor = "#000000"; // Use black text for brighter colors
58
+ }
59
+
60
+ return {
61
+ backgroundColor: p,
62
+ color: textColor,
63
+ borderColor: p
64
+ };
65
+ });
66
+
67
+ const getLabel = computed(() => {
68
+ const localized = game.i18n.localize(props.label);
69
+ if (props.icon) {
70
+ return \`<i class="fa-solid \${props.icon}"></i> \${localized}\`;
71
+ }
72
+ return localized;
73
+ });
74
+
75
+ const isHovering = ref(false);
76
+
77
+ const handleRoll = () => {
78
+ if (props.roll) {
79
+ props.roll();
80
+ }
81
+ };
82
+ </script>
83
+
84
+ <template>
85
+ <div class="dice-container"
86
+ @mouseenter="isHovering = true"
87
+ @mouseleave="isHovering = false"
88
+ >
89
+ <div v-if="attributeStyle == 'plain'">
90
+ <v-number-input v-if="attributeStyle == 'plain' && editMode" :model-value="value" @update:model-value="(v) => { value = v; persistOnStep(systemPath, v); }" :name="systemPath" :min="props.min" :disabled="disabled" type="number" variant="outlined" density="compact" :hide-details="true" data-tooltip="Value">
91
+ <template #label>
92
+ <span v-html="getLabel" />
93
+ </template>
94
+ </v-number-input>
95
+ <v-number-input v-if="attributeStyle == 'plain' && !editMode" :model-value="mod" :name="systemPath" :disabled="true" type="number" controlVariant="hidden" variant="outlined" density="compact" :hide-details="true" data-tooltip="Mod">
96
+ <template #label>
97
+ <span v-html="getLabel" />
98
+ </template>
99
+ </v-number-input>
100
+ <!-- Overlay with dice icon - appears on hover when roll function is available -->
101
+ <div
102
+ v-if="hasRoll && isHovering && !editMode"
103
+ class="dice-overlay plain"
104
+ @click="handleRoll"
105
+ >
106
+ <v-btn
107
+ icon
108
+ size="x-small"
109
+ :color="primaryColor"
110
+ class="dice-roll-btn"
111
+ variant="elevated"
112
+ elevation="4"
113
+ >
114
+ <v-icon size="small">fa-solid fa-dice</v-icon>
115
+ </v-btn>
116
+ </div>
117
+ </div>
118
+ <v-container
119
+ :class="['isdl-property', 'attributeExp', { 'no-mod': !hasMod }]"
120
+ v-if="attributeStyle == 'box'"
121
+
122
+ >
123
+ <v-label :style="getStyle"><v-icon v-if="icon" size="x-small" :icon="icon" style="padding-right: 0.5rem;"></v-icon>{{ game.i18n.localize(label) }}</v-label>
124
+ <div class="mod" v-if="hasMod">{{ mod }}</div>
125
+ <v-number-input :model-value="value" @update:model-value="(v) => { value = v; persistOnStep(systemPath, v); }" inset :min="props.min" :disabled="disabled" :name="systemPath" :controlVariant="disabled ? 'hidden' : 'split'" :step="1" type="number" variant="outlined" density="compact" :hide-details="true" :tile="true"></v-number-input>
126
+ <!-- Overlay with dice icon - appears on hover when roll function is available -->
127
+ <div
128
+ v-if="hasRoll && isHovering && !editMode"
129
+ class="dice-overlay"
130
+ @click="handleRoll"
131
+ >
132
+ <v-btn
133
+ icon
134
+ :color="primaryColor"
135
+ class="dice-roll-btn"
136
+ variant="elevated"
137
+ elevation="4"
138
+ >
139
+ <v-icon>fa-solid fa-dice</v-icon>
140
+ </v-btn>
141
+ </div>
142
+ </v-container>
143
+ </div>
144
+ </template>
145
+ `;
146
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
147
+ }
148
+ //# sourceMappingURL=vue-attribute.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue-attribute.js","sourceRoot":"","sources":["../../../../../src/cli/components/vue/base-components/vue-attribute.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,0BAA0B,CAAC,WAAmB;IAClE,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,eAAe,CAAC,CAAC;IAEvE,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAuI5B,CAAC;IAEF,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC5D,CAAC"}
@@ -0,0 +1,77 @@
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 generateBooleanComponent(destination, entry) {
5
+ const generatedFileDir = path.join(destination, "system", "templates", "vue", "components");
6
+ const generatedFilePath = path.join(generatedFileDir, `boolean.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 } from "vue";
13
+
14
+ const props = defineProps({
15
+ label: String,
16
+ systemPath: String,
17
+ context: Object,
18
+ visibility: String,
19
+ editMode: Boolean,
20
+ icon: String,
21
+ color: String,
22
+ disabled: Boolean
23
+ });
24
+
25
+ const document = inject("rawDocument");
26
+
27
+ const value = computed({
28
+ get: () => foundry.utils.getProperty(props.context, props.systemPath),
29
+ set: (newValue) => foundry.utils.setProperty(props.context, props.systemPath, newValue)
30
+ });
31
+
32
+ const isHidden = computed(() => {
33
+ if (props.visibility === "hidden") {
34
+ return true;
35
+ }
36
+ if (props.visibility === "gm" && !game.user.isGM) {
37
+ return true;
38
+ }
39
+ return false;
40
+ });
41
+
42
+ const isDisabled = computed(() => {
43
+ return props.disabled ||
44
+ props.visibility === "locked" ||
45
+ props.visibility === "readonly" ||
46
+ (props.visibility === "gmOnly" && !game.user.isGM);
47
+ });
48
+
49
+ const checkboxColor = computed(() => {
50
+ return props.color || 'primary';
51
+ });
52
+ </script>
53
+
54
+ <template>
55
+ <div v-if="!isHidden" class="isdl-boolean single-wide">
56
+ <v-checkbox
57
+ v-model="value"
58
+ :name="props.systemPath"
59
+ :disabled="isDisabled"
60
+ :color="checkboxColor"
61
+ density="compact"
62
+ class="single-wide"
63
+ variant="outlined"
64
+ >
65
+ <template #label>
66
+ <span class="field-label">
67
+ <v-icon v-if="props.icon" :icon="props.icon" size="small" class="me-1"></v-icon>
68
+ {{ game.i18n.localize(props.label) }}
69
+ </span>
70
+ </template>
71
+ </v-checkbox>
72
+ </div>
73
+ </template>
74
+ `.appendNewLine();
75
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
76
+ }
77
+ //# sourceMappingURL=vue-boolean.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vue-boolean.js","sourceRoot":"","sources":["../../../../../src/cli/components/vue/base-components/vue-boolean.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;AAGxD,MAAM,CAAC,OAAO,UAAU,wBAAwB,CAAC,WAAmB,EAAE,KAAa;IAC/E,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;KAgE5B,CAAC,aAAa,EAAE,CAAC;IAElB,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AAC5D,CAAC"}