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,659 @@
1
+ import { isActor, isItem, isHtmlExp, isConfigExpression, } from "../language/generated/ast.js";
2
+ import { expandToNode, toString } from 'langium/generate';
3
+ import * as fs from 'node:fs';
4
+ import * as path from 'node:path';
5
+ import { extractDestinationAndName } from './cli-util.js';
6
+ import { generateCustomCss, generateSystemCss } from './components/css-generator.js';
7
+ import { generateLanguageJson } from './components/language-generator.js';
8
+ import { generateExtendedDocumentClasses } from './components/derived-data-generator.js';
9
+ import { generateDocumentDataModel, generateUuidDocumentField, generateUuidDocumentArrayField } from './components/datamodel-generator.js';
10
+ import { fileURLToPath } from 'url';
11
+ import { generateActiveEffectHandlebars, generateBaseActiveEffectBaseSheet as generateActiveEffectBaseSheet } from './components/active-effect-sheet-generator.js';
12
+ import { generateChatCardClass, generateStandardChatCardTemplate } from './components/chat-card-generator.js';
13
+ import { generateBaseDocumentSheet } from './components/base-sheet-generator.js';
14
+ import { generateBaseActorSheet } from './components/base-actor-sheet-generator.js';
15
+ import { getAllOfType } from './components/utils.js';
16
+ import { generateCanvasToken, generateTokenDocument } from './components/token-generator.js';
17
+ import { generateVue, runViteBuild } from './components/vue/vue-generator.js';
18
+ import { generateInitHookMjs } from "./components/init-hook-generator.js";
19
+ import { generateReadyHookMjs } from "./components/ready-hook-generator.js";
20
+ import { generateHotbarDropHookMjs } from "./components/hotbar-drop-hook-generator.js";
21
+ import { generateMeasuredTemplatePreview } from "./components/measured-template-preview.js";
22
+ import { generateDamageRoll } from "./components/damage-roll-generator.js";
23
+ export async function generateJavaScript(entry, filePath, destination) {
24
+ const config = entry.config;
25
+ const data = extractDestinationAndName(filePath, destination);
26
+ const id = config.body.find(x => isConfigExpression(x) && x.type == "id").value;
27
+ data.destination = path.join(data.destination, id);
28
+ console.log("Writing to " + data.destination);
29
+ if (!fs.existsSync(path.join(data.destination, "system"))) {
30
+ fs.mkdirSync(path.join(data.destination, "system"), { recursive: true });
31
+ }
32
+ // Libraries
33
+ copyDataTableFiles(data.destination);
34
+ copyProgressBarJs(data.destination);
35
+ // Images
36
+ copyImage("isdl.png", data.destination);
37
+ copyImage("paperdoll_default.png", data.destination);
38
+ copyImage("missing-character.png", data.destination);
39
+ // Generic shared components
40
+ generateSystemCss(entry, id, data.destination);
41
+ generateCustomCss(entry, id, data.destination);
42
+ generateUuidDocumentField(data.destination);
43
+ generateUuidDocumentArrayField(data.destination);
44
+ generateActiveEffectBaseSheet(entry, id, data.destination);
45
+ generateActiveEffectHandlebars(id, entry, data.destination);
46
+ generateSystemJson(entry, id, data.destination);
47
+ generateLanguageJson(entry, id, data.destination);
48
+ generateTemplateJson(entry, id, data.destination);
49
+ generateBaseDocumentSheet(entry, id, data.destination);
50
+ generateBaseActorSheet(entry, id, data.destination);
51
+ generateExtendedDocumentClasses(entry, id, data.destination);
52
+ generateMeasuredTemplatePreview(data.destination);
53
+ generateEntryMjs(entry, id, data.destination);
54
+ generateCustomEntryMjs(entry, id, data.destination);
55
+ generateInitHookMjs(entry, id, data.destination);
56
+ generateReadyHookMjs(entry, id, data.destination);
57
+ generateHotbarDropHookMjs(entry, id, data.destination);
58
+ generateHotReloadHookMjs(entry, id, data.destination);
59
+ generateChatCardClass(entry, data.destination);
60
+ generateStandardChatCardTemplate(data.destination);
61
+ generateRenderChatLogHookMjs(entry, id, data.destination);
62
+ generateRenderSettingsHookMjs(entry, id, data.destination);
63
+ generateExtendedRoll(entry, id, data.destination);
64
+ generateDamageRoll(entry, id, data.destination);
65
+ generateContextMenu2(entry, id, data.destination);
66
+ generateDocumentCreateHbs(entry, id, data.destination);
67
+ generateCombatant(entry, id, data.destination);
68
+ generateCanvasToken(entry, id, data.destination);
69
+ generateTokenDocument(entry, id, data.destination);
70
+ generateVue(entry, id, data.destination);
71
+ // Documents
72
+ entry.documents.forEach(x => {
73
+ generateDocumentDataModel(entry, x, data.destination);
74
+ });
75
+ console.log("Running Vite build");
76
+ await runViteBuild(data.destination);
77
+ console.log("Vite build complete");
78
+ return data.destination;
79
+ }
80
+ function copyDataTableFiles(destination) {
81
+ const __filename = fileURLToPath(import.meta.url);
82
+ const __dirname = path.dirname(__filename);
83
+ // Make the scripts and css directories
84
+ const cssDir = path.join(destination, "css");
85
+ const jsDir = path.join(destination, "scripts");
86
+ if (!fs.existsSync(cssDir)) {
87
+ fs.mkdirSync(cssDir, { recursive: true });
88
+ }
89
+ if (!fs.existsSync(jsDir)) {
90
+ fs.mkdirSync(jsDir, { recursive: true });
91
+ }
92
+ // Copy the files
93
+ const cssFilePath = path.join(destination, "css", "datatables.min.css");
94
+ const jsFilePath = path.join(destination, "scripts", "datatables.min.js");
95
+ fs.copyFileSync(path.join(__dirname, "../datatables.min.css"), cssFilePath);
96
+ fs.copyFileSync(path.join(__dirname, "../datatables.min.js"), jsFilePath);
97
+ }
98
+ function copyProgressBarJs(destination) {
99
+ const __filename = fileURLToPath(import.meta.url);
100
+ const __dirname = path.dirname(__filename);
101
+ // Make the scripts and css directories
102
+ const jsDir = path.join(destination, "scripts");
103
+ if (!fs.existsSync(jsDir)) {
104
+ fs.mkdirSync(jsDir, { recursive: true });
105
+ }
106
+ // Copy the files
107
+ const jsFilePath = path.join(destination, "scripts", "progressbar.min.js");
108
+ fs.copyFileSync(path.join(__dirname, "../progressbar.min.js"), jsFilePath);
109
+ }
110
+ function copyImage(source, destination) {
111
+ const __filename = fileURLToPath(import.meta.url);
112
+ const __dirname = path.dirname(__filename);
113
+ const imgDir = path.join(destination, "img");
114
+ if (!fs.existsSync(imgDir)) {
115
+ fs.mkdirSync(imgDir, { recursive: true });
116
+ }
117
+ // Copy the files
118
+ const imgFilePath = path.join(imgDir, source);
119
+ fs.copyFileSync(path.join(__dirname, "../" + source), imgFilePath);
120
+ }
121
+ function getExtensionVersion() {
122
+ const __filename = fileURLToPath(import.meta.url);
123
+ const __dirname = path.dirname(__filename);
124
+ var packageJsonPath = path.join(__dirname, "../extension/package.json");
125
+ console.log(packageJsonPath);
126
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
127
+ return packageJson.version;
128
+ }
129
+ function generateSystemJson(entry, id, destination) {
130
+ var _a, _b, _c;
131
+ const generatedFilePath = path.join(destination, `system.json`);
132
+ // Get the version of the extension
133
+ const extensionVersion = getExtensionVersion();
134
+ const fileNode = expandToNode `
135
+ {
136
+ "id": "${id}",
137
+ "title": "${(_a = entry.config.body.find(x => isConfigExpression(x) && x.type == "label")) === null || _a === void 0 ? void 0 : _a.value}",
138
+ "description": "${(_b = entry.config.body.find(x => isConfigExpression(x) && x.type == "description")) === null || _b === void 0 ? void 0 : _b.value}",
139
+ "version": "This is auto replaced",
140
+ "compatibility": {
141
+ "minimum": 12,
142
+ "verified": 14
143
+ },
144
+ "authors": [
145
+ {
146
+ "name": "${(_c = entry.config.body.find(x => isConfigExpression(x) && x.type == "author")) === null || _c === void 0 ? void 0 : _c.value}"
147
+ }
148
+ ],
149
+ "scripts": [
150
+ "scripts/datatables.min.js"
151
+ ],
152
+ "esmodules": [
153
+ "system/${id}-main.mjs",
154
+ "system/${id}-custom.mjs"
155
+ ],
156
+ "styles": [
157
+ "css/datatables.min.css",
158
+ "css/materialdesignicons.min.css",
159
+ "css/${id}.css",
160
+ "css/${id}-custom.css"
161
+ ],
162
+ "license": "LICENSE",
163
+ "readme": "README.md",
164
+ "socket": true,
165
+ "languages": [
166
+ {
167
+ "lang": "en",
168
+ "name": "English",
169
+ "path": "lang/en.json"
170
+ }
171
+ ],
172
+ "flags": {
173
+ "hotReload": {
174
+ "extensions": ["css", "hbs", "json", "mjs"],
175
+ "paths": ["css", "system", "lang", "system", "system.json"]
176
+ },
177
+ "isdl-version": "${extensionVersion}"
178
+ },
179
+ "media": [
180
+ {
181
+ "type": "setup",
182
+ "url": "systems/${id}/img/isdl.png",
183
+ "thumbnail": "systems/${id}/img/isdl.png"
184
+ }
185
+ ],
186
+ "relationships": {
187
+ "recommends": [
188
+ {
189
+ "id": "intelligent-filepicker",
190
+ "type": "module",
191
+ "manifest": "https://github.com/cswendrowski/intelligent-filepicker/releases/latest/download/module.json",
192
+ "reason": "Makes it much faster to pick out Icons for your Documents"
193
+ },
194
+ {
195
+ "id": "ric",
196
+ "type": "module",
197
+ "manifest": "https://github.com/GamerFlix/ric/releases/latest/download/module.json",
198
+ "reason": "Adds an UI for managing invalid Documents, such as when fields change to become required but were not filled in"
199
+ }
200
+ ]
201
+ },
202
+ "url": "This is auto replaced",
203
+ "manifest": "This is auto replaced",
204
+ "download": "This is auto replaced"
205
+ }
206
+ `.appendNewLineIfNotEmpty();
207
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
208
+ }
209
+ function generateTemplateJson(entry, id, destination) {
210
+ const generatedFilePath = path.join(destination, `template.json`);
211
+ function getHtmlFields(documents) {
212
+ const extra = documents.flatMap(doc => getAllOfType(doc.body, isHtmlExp).map(p => p.name.toLowerCase()));
213
+ return ['description', ...extra];
214
+ }
215
+ const actorDocs = entry.documents.filter(d => isActor(d));
216
+ const itemDocs = entry.documents.filter(d => isItem(d));
217
+ const template = {
218
+ Actor: Object.assign({ types: actorDocs.map(d => d.name.toLowerCase()), htmlFields: getHtmlFields(actorDocs) }, Object.fromEntries(actorDocs.map(d => [d.name.toLowerCase(), {}]))),
219
+ Item: Object.assign({ types: itemDocs.map(d => d.name.toLowerCase()), htmlFields: getHtmlFields(itemDocs) }, Object.fromEntries(itemDocs.map(d => [d.name.toLowerCase(), {}])))
220
+ };
221
+ fs.writeFileSync(generatedFilePath, JSON.stringify(template, null, 4));
222
+ }
223
+ function generateEntryMjs(entry, id, destination) {
224
+ const generatedFilePath = path.join(destination, "system", `${id}-main.mjs`);
225
+ const fileNode = expandToNode `
226
+ import {init} from "./hooks/init.mjs";
227
+ import {ready} from "./hooks/ready.mjs";
228
+ import {renderChatLog} from "./hooks/render-chat-log.mjs";
229
+ import {renderSettings} from "./hooks/render-settings.mjs";
230
+ import {hotReload} from "./hooks/hot-reload.mjs";
231
+ import {hotbarDrop} from "./hooks/hotbar-drop.mjs";
232
+
233
+ Hooks.once("init", init);
234
+ Hooks.once("ready", ready);
235
+ Hooks.on("devModeReady", ({registerPackageDebugFlag}) => registerPackageDebugFlag("${id}"));
236
+ Hooks.on("renderChatMessage", renderChatLog);
237
+ Hooks.on("renderSettings", renderSettings);
238
+ Hooks.on("hotReload", hotReload);
239
+ Hooks.on("hotbarDrop", hotbarDrop);
240
+ `.appendNewLineIfNotEmpty();
241
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
242
+ }
243
+ function generateCustomEntryMjs(entry, id, destination) {
244
+ const generatedFilePath = path.join(destination, "system", `${id}-custom.mjs`);
245
+ // If the file already exists, don't overwrite it
246
+ if (fs.existsSync(generatedFilePath)) {
247
+ return;
248
+ }
249
+ const fileNode = expandToNode `
250
+ // Write your custom code and hooks here. This file will not be overwritten by the generator.
251
+
252
+ Hooks.once("init", () => {});
253
+ `.appendNewLineIfNotEmpty();
254
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
255
+ }
256
+ function generateHotReloadHookMjs(entry, id, destination) {
257
+ const generatedFileDir = path.join(destination, "system", "hooks");
258
+ const generatedFilePath = path.join(generatedFileDir, `hot-reload.mjs`);
259
+ if (!fs.existsSync(generatedFileDir)) {
260
+ fs.mkdirSync(generatedFileDir, { recursive: true });
261
+ }
262
+ const fileNode = expandToNode `
263
+ export function hotReload(context) {
264
+ const reloadFileTypes = ["mjs", "json"];
265
+ if (!reloadFileTypes.includes(context.extension)) return;
266
+
267
+ if (context.extension === "json") {
268
+ if (!context.path.endsWith("system.json")) return;
269
+ ui.notifications.warn("The system configuration has been updated. Please reload your world to apply changes.", { permanent: true });
270
+ }
271
+
272
+ ui.notifications.info("Reloading page to apply script changes", { permanent: true });
273
+
274
+ const lastState = {
275
+ openWindows: []
276
+ };
277
+ for (const window of Object.values(ui.windows)) {
278
+ if (!window.object) continue;
279
+ const uuid = window.object.uuid;
280
+ lastState.openWindows.push({
281
+ uuid: uuid,
282
+ position: window.position
283
+ });
284
+ }
285
+ game.settings.set("${id}", "hotReloadLastState", lastState).then(() =>
286
+ {
287
+ // Reload the page
288
+ window.location.reload(true);
289
+ });
290
+ }
291
+ `.appendNewLineIfNotEmpty();
292
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
293
+ }
294
+ function generateRenderChatLogHookMjs(entry, id, destination) {
295
+ const generatedFileDir = path.join(destination, "system", "hooks");
296
+ const generatedFilePath = path.join(generatedFileDir, `render-chat-log.mjs`);
297
+ if (!fs.existsSync(generatedFileDir)) {
298
+ fs.mkdirSync(generatedFileDir, { recursive: true });
299
+ }
300
+ const fileNode = expandToNode `
301
+ import ${entry.config.name}ChatCard from "../documents/chat-card.mjs";
302
+
303
+ export function renderChatLog(app, html, data) {
304
+ ${entry.config.name}ChatCard.activateListeners(html);
305
+ }
306
+ `.appendNewLineIfNotEmpty();
307
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
308
+ }
309
+ function generateRenderSettingsHookMjs(entry, id, destination) {
310
+ const generatedFileDir = path.join(destination, "system", "hooks");
311
+ const generatedFilePath = path.join(generatedFileDir, `render-settings.mjs`);
312
+ if (!fs.existsSync(generatedFileDir)) {
313
+ fs.mkdirSync(generatedFileDir, { recursive: true });
314
+ }
315
+ const fileNode = expandToNode `
316
+ // Adds an "ISDL" version row to the Foundry Settings sidebar, next to the
317
+ // system info, showing which version of ISDL generated this system.
318
+ export function renderSettings(app, html) {
319
+ const root = html instanceof HTMLElement ? html : html?.[0];
320
+ if (!root) return;
321
+
322
+ const info = root.querySelector("section.info");
323
+ if (!info || info.querySelector(".isdl-version")) return;
324
+
325
+ const version = game.system.flags?.["isdl-version"] ?? "unknown";
326
+
327
+ const row = document.createElement("div");
328
+ row.classList.add("isdl-version");
329
+ const label = document.createElement("span");
330
+ label.classList.add("label");
331
+ label.textContent = "ISDL";
332
+ const value = document.createElement("span");
333
+ value.classList.add("value");
334
+ value.textContent = version;
335
+ row.append(label, value);
336
+
337
+ // Place it right after the system row when present, else append.
338
+ const systemRow = info.querySelector(".system");
339
+ if (systemRow) systemRow.after(row);
340
+ else info.appendChild(row);
341
+ }
342
+ `.appendNewLineIfNotEmpty();
343
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
344
+ }
345
+ function generateExtendedRoll(entry, id, destination) {
346
+ const generatedFileDir = path.join(destination, "system", "rolls");
347
+ const generatedFilePath = path.join(generatedFileDir, `roll.mjs`);
348
+ if (!fs.existsSync(generatedFileDir)) {
349
+ fs.mkdirSync(generatedFileDir, { recursive: true });
350
+ }
351
+ const fileNode = expandToNode `
352
+ export default class ${entry.config.name}Roll extends Roll {
353
+ async getTooltip() {
354
+ const parts = [];
355
+
356
+ for ( const term of this.terms ) {
357
+ if ( foundry.utils.isSubclass(term.constructor, foundry.dice.terms.DiceTerm) ) {
358
+ parts.push(term.getTooltipData());
359
+ }
360
+ else if ( foundry.utils.isSubclass(term.constructor, foundry.dice.terms.NumericTerm) ) {
361
+ parts.push({
362
+ formula: term.flavor,
363
+ total: term.total,
364
+ faces: null,
365
+ flavor: "",
366
+ rolls: []
367
+ });
368
+ }
369
+ }
370
+
371
+ return renderTemplate(this.constructor.TOOLTIP_TEMPLATE, { parts });
372
+ }
373
+
374
+ /* -------------------------------------------- */
375
+
376
+ get cleanFormula() {
377
+ // Replace flavor terms such as 5[STR] with just the flavor text
378
+ let cleanFormula = this._formula;
379
+ for ( const term of this.terms ) {
380
+ if ( term.formula && term.flavor ) {
381
+ cleanFormula = cleanFormula.replace(term.formula, term.flavor);
382
+ }
383
+ }
384
+
385
+ // If there are still parts of the formula such as 5[STR] then replace them with just the flavor text
386
+ const rgx = new RegExp(/(\\d+)\\[(.*?)\\]/g);
387
+ cleanFormula = cleanFormula.replace(rgx, "$2");
388
+
389
+ return cleanFormula;
390
+ }
391
+ }
392
+ `.appendNewLineIfNotEmpty();
393
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
394
+ }
395
+ function generateContextMenu2(entry, id, destination) {
396
+ const generatedFilePath = path.join(destination, "system", "contextMenu2.js");
397
+ const fileNode = expandToNode `
398
+ export class ContextMenu2 {
399
+ constructor(element, selector, menuItems, {eventName="contextmenu"}={}) {
400
+
401
+ /**
402
+ * The target HTMLElement being selected
403
+ * @type {HTMLElement}
404
+ */
405
+ this.element = element;
406
+
407
+ /**
408
+ * The target CSS selector which activates the menu
409
+ * @type {String}
410
+ */
411
+ this.selector = selector || element.attr("id");
412
+
413
+ /**
414
+ * An interaction event name which activates the menu
415
+ * @type {String}
416
+ */
417
+ this.eventName = eventName;
418
+
419
+ /**
420
+ * The array of menu items being rendered
421
+ * @type {Array}
422
+ */
423
+ this.menuItems = menuItems;
424
+
425
+ /**
426
+ * Track which direction the menu is expanded in
427
+ * @type {Boolean}
428
+ */
429
+ this._expandUp = false;
430
+
431
+ // Bind to the current element
432
+ this.bind();
433
+ }
434
+
435
+ /* -------------------------------------------- */
436
+
437
+ /**
438
+ * A convenience accessor to the context menu HTML object
439
+ * @return {*|jQuery.fn.init|jQuery|HTMLElement}
440
+ */
441
+ get menu() {
442
+ return $("#context-menu2");
443
+ }
444
+
445
+ /* -------------------------------------------- */
446
+
447
+ /**
448
+ * Attach a ContextMenu instance to an HTML selector
449
+ */
450
+ bind() {
451
+ this.element.on(this.eventName, this.selector, event => {
452
+ event.preventDefault();
453
+ event.stopPropagation();
454
+ let parent = $(event.currentTarget),
455
+ menu = this.menu;
456
+
457
+ if (this.selector == ".message") return;
458
+
459
+ // Remove existing context UI
460
+ $('.context').removeClass("context");
461
+
462
+ // Close the current context
463
+ if ( $.contains(parent[0], menu[0]) ) this.close();
464
+
465
+ // If the new target element is different
466
+ else {
467
+ this.render(parent);
468
+ ui.context = this;
469
+ }
470
+ })
471
+ }
472
+
473
+ /* -------------------------------------------- */
474
+
475
+ /**
476
+ * Animate closing the menu by sliding up and removing from the DOM
477
+ */
478
+ async close() {
479
+ let menu = this.menu;
480
+ await this._animateClose(menu);
481
+ menu.remove();
482
+ $('.context').removeClass("context");
483
+ delete ui.context;
484
+ }
485
+
486
+ /* -------------------------------------------- */
487
+
488
+ async _animateOpen(menu) {
489
+ menu.hide();
490
+ return new Promise(resolve => menu.slideDown(200, resolve));
491
+ }
492
+
493
+ /* -------------------------------------------- */
494
+
495
+ async _animateClose(menu) {
496
+ return new Promise(resolve => menu.slideUp(200, resolve));
497
+ }
498
+
499
+ /* -------------------------------------------- */
500
+
501
+ /**
502
+ * Render the Context Menu by iterating over the menuItems it contains
503
+ * Check the visibility of each menu item, and only render ones which are allowed by the item's logical condition
504
+ * Attach a click handler to each item which is rendered
505
+ * @param target
506
+ */
507
+ render(target) {
508
+ let html = $("#context-menu2").length ? $("#context-menu2") : $('<nav id="context-menu2" data-mod="1"></nav>');
509
+ let ol = $('<ol class="context-items"></ol>');
510
+ html.append($(\`<h2>\${game.i18n.localize('CONTEXT.ApplyChanges')}</h2>\`));
511
+ html.append(ol);
512
+
513
+ // Determine if user-selected targets are allowed.
514
+ const allowTargeting = game.settings.get('${id}', 'allowTargetDamageApplication');
515
+ let targetType = game.settings.get('${id}', 'userTargetDamageApplicationType');
516
+ if (!allowTargeting && targetType !== 'selected') {
517
+ game.settings.set('${id}', 'userTargetDamageApplicationType', 'selected');
518
+ targetType = 'selected';
519
+ }
520
+
521
+ // Add default target type.
522
+ html[0].dataset.target = targetType;
523
+
524
+ // Build menu items
525
+ for (let item of this.menuItems) {
526
+
527
+ // Determine menu item visibility (display unless false)
528
+ let display = true;
529
+ if ( item.condition !== undefined ) {
530
+ display = ( item.condition instanceof Function ) ? item.condition(target) : item.condition;
531
+ }
532
+ if ( !display ) continue;
533
+
534
+ // Construct and add the menu item
535
+ let name = game.i18n.localize(item.name);
536
+ let li = $(\`<li class="context-item \${item?.id ?? ''}">\${item.icon}\${name}</li>\`);
537
+ // If this is the target buttons option, set one of them to active.
538
+ if (name.includes('data-target="targeted"')) {
539
+ const button = li.find(\`[data-target="\${targetType}"]\`);
540
+ button.addClass('active');
541
+ }
542
+ li.children("i").addClass("fa-fw");
543
+ li.click(e => {
544
+ e.preventDefault();
545
+ e.stopPropagation();
546
+ item.callback(target, e);
547
+ // If this was a target button, prevent closing the context menu.
548
+ if (!item?.preventClose) {
549
+ this.close();
550
+ }
551
+ });
552
+ ol.append(li);
553
+ }
554
+
555
+ // Bail out if there are no children
556
+ if ( ol.children().length === 0 ) return;
557
+
558
+ // Append to target
559
+ this._setPosition(html, target);
560
+
561
+ // Deactivate global tooltip
562
+ game.tooltip.deactivate();
563
+
564
+ // Animate open the menu
565
+ return this._animateOpen(html);
566
+ }
567
+
568
+ /* -------------------------------------------- */
569
+
570
+ /**
571
+ * Set the position of the context menu, taking into consideration whether the menu should expand upward or downward
572
+ * @private
573
+ */
574
+ _setPosition(html, target) {
575
+ const targetRect = target[0].getBoundingClientRect();
576
+ const parentRect = target[0].parentElement.getBoundingClientRect();
577
+
578
+ // Append to target and get the context bounds
579
+ target.css('position', 'relative');
580
+ html.css("visibility", "hidden");
581
+ target.append(html);
582
+ const contextRect = html[0].getBoundingClientRect();
583
+
584
+ // Determine whether to expand down or expand up
585
+ const bottomHalf = targetRect.bottom > (window.innerHeight / 2);
586
+ this._expandUp = bottomHalf && ((parentRect.bottom - targetRect.bottom) < contextRect.height);
587
+
588
+ // Shift left if needed to avoid overflowing
589
+ const horizontalOverflow = parentRect.right - contextRect.right;
590
+ if (horizontalOverflow < 0) {
591
+ html.css("left", Math.floor(horizontalOverflow));
592
+ }
593
+
594
+ // Display the menu
595
+ html.addClass(this._expandUp ? "expand-up" : "expand-down");
596
+ html.css("visibility", "");
597
+ target.addClass("context");
598
+ }
599
+
600
+ /* -------------------------------------------- */
601
+
602
+ static eventListeners() {
603
+ document.addEventListener("click", ev => {
604
+ if ( ui.context ) ui.context.close();
605
+ });
606
+ };
607
+ }
608
+ `.appendNewLineIfNotEmpty();
609
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
610
+ }
611
+ function generateDocumentCreateHbs(entry, id, destination) {
612
+ const generatedFileDir = path.join(destination, "system", "templates");
613
+ const generatedFilePath = path.join(generatedFileDir, `document-create.hbs`);
614
+ if (!fs.existsSync(generatedFileDir)) {
615
+ fs.mkdirSync(generatedFileDir, { recursive: true });
616
+ }
617
+ const fileNode = expandToNode `
618
+ <form id="document-create" autocomplete="off">
619
+ <header>
620
+ <input type="text" class="document-name uninput" name="name" value="{{ name }}" autofocus
621
+ placeholder="{{ localize 'Name' }}">
622
+ {{#if hasFolders}}
623
+ <select class="unselect" name="folder" form="document-create">
624
+ {{ selectOptions folders selected=folder labelAttr="name" valueAttr="id"
625
+ blank=(localize "DOCUMENT.Folder") }}
626
+ </select>
627
+ {{/if}}
628
+ </header>
629
+ <ol class="unlist card">
630
+ {{#each types}}
631
+ <li data-tooltip="{{ description }}">
632
+ <label>
633
+ <img src="{{ icon }}" alt="{{ label }}">
634
+ <span>{{ label }}</span>
635
+ <input type="radio" name="type" value="{{ type }}" required {{#if selected}}checked{{/if}}>
636
+ </label>
637
+ </li>
638
+ {{/each}}
639
+ </ol>
640
+ </form>
641
+ `.appendNewLineIfNotEmpty();
642
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
643
+ }
644
+ function generateCombatant(entry, id, destination) {
645
+ const generatedFileDir = path.join(destination, "system", "documents");
646
+ const generatedFilePath = path.join(generatedFileDir, `combatant.mjs`);
647
+ if (!fs.existsSync(generatedFileDir)) {
648
+ fs.mkdirSync(generatedFileDir, { recursive: true });
649
+ }
650
+ const fileNode = expandToNode `
651
+ export default class ${entry.config.name}Combatant extends Combatant {
652
+ _getInitiativeFormula() {
653
+ return String(CONFIG.Combat.initiative.formula || game.system.initiative || this.actor.getInitiativeFormula());
654
+ }
655
+ }
656
+ `.appendNewLineIfNotEmpty();
657
+ fs.writeFileSync(generatedFilePath, toString(fileNode));
658
+ }
659
+ //# sourceMappingURL=generator.js.map