@jjlmoya/utils-diy 1.11.0 → 1.12.0

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 (273) hide show
  1. package/package.json +1 -1
  2. package/src/category/index.ts +2 -1
  3. package/src/entries.ts +3 -1
  4. package/src/index.ts +2 -0
  5. package/src/pages/[locale]/[slug].astro +28 -12
  6. package/src/tests/locale_completeness.test.ts +7 -9
  7. package/src/tests/shared-test-helpers.ts +56 -0
  8. package/src/tests/tool_exports.test.ts +34 -0
  9. package/src/tests/tool_validation.test.ts +2 -2
  10. package/src/tool/balusterCalculator/bibliography.astro +2 -10
  11. package/src/tool/balusterCalculator/bibliography.ts +16 -0
  12. package/src/tool/balusterCalculator/i18n/de.ts +2 -15
  13. package/src/tool/balusterCalculator/i18n/en.ts +2 -15
  14. package/src/tool/balusterCalculator/i18n/es.ts +2 -15
  15. package/src/tool/balusterCalculator/i18n/fr.ts +2 -15
  16. package/src/tool/balusterCalculator/i18n/id.ts +2 -15
  17. package/src/tool/balusterCalculator/i18n/it.ts +2 -15
  18. package/src/tool/balusterCalculator/i18n/ja.ts +2 -15
  19. package/src/tool/balusterCalculator/i18n/ko.ts +2 -15
  20. package/src/tool/balusterCalculator/i18n/nl.ts +2 -15
  21. package/src/tool/balusterCalculator/i18n/pl.ts +2 -15
  22. package/src/tool/balusterCalculator/i18n/pt.ts +2 -15
  23. package/src/tool/balusterCalculator/i18n/ru.ts +2 -15
  24. package/src/tool/balusterCalculator/i18n/sv.ts +2 -15
  25. package/src/tool/balusterCalculator/i18n/tr.ts +2 -15
  26. package/src/tool/balusterCalculator/i18n/zh.ts +2 -15
  27. package/src/tool/balusterCalculator/seo.astro +1 -1
  28. package/src/tool/clayCalculator/bibliography.astro +2 -10
  29. package/src/tool/clayCalculator/bibliography.ts +12 -0
  30. package/src/tool/clayCalculator/i18n/de.ts +2 -11
  31. package/src/tool/clayCalculator/i18n/en.ts +2 -11
  32. package/src/tool/clayCalculator/i18n/es.ts +2 -11
  33. package/src/tool/clayCalculator/i18n/fr.ts +2 -11
  34. package/src/tool/clayCalculator/i18n/id.ts +2 -11
  35. package/src/tool/clayCalculator/i18n/it.ts +2 -11
  36. package/src/tool/clayCalculator/i18n/ja.ts +2 -11
  37. package/src/tool/clayCalculator/i18n/ko.ts +2 -11
  38. package/src/tool/clayCalculator/i18n/nl.ts +2 -11
  39. package/src/tool/clayCalculator/i18n/pl.ts +2 -11
  40. package/src/tool/clayCalculator/i18n/pt.ts +2 -11
  41. package/src/tool/clayCalculator/i18n/ru.ts +2 -11
  42. package/src/tool/clayCalculator/i18n/sv.ts +2 -11
  43. package/src/tool/clayCalculator/i18n/tr.ts +2 -11
  44. package/src/tool/clayCalculator/i18n/zh.ts +2 -11
  45. package/src/tool/clayCalculator/seo.astro +1 -1
  46. package/src/tool/concreteCalculator/bibliography.astro +2 -9
  47. package/src/tool/concreteCalculator/bibliography.ts +7 -0
  48. package/src/tool/concreteCalculator/i18n/de.ts +2 -15
  49. package/src/tool/concreteCalculator/i18n/en.ts +2 -15
  50. package/src/tool/concreteCalculator/i18n/es.ts +2 -15
  51. package/src/tool/concreteCalculator/i18n/fr.ts +2 -15
  52. package/src/tool/concreteCalculator/i18n/id.ts +2 -15
  53. package/src/tool/concreteCalculator/i18n/it.ts +2 -15
  54. package/src/tool/concreteCalculator/i18n/ja.ts +2 -15
  55. package/src/tool/concreteCalculator/i18n/ko.ts +2 -15
  56. package/src/tool/concreteCalculator/i18n/nl.ts +2 -15
  57. package/src/tool/concreteCalculator/i18n/pl.ts +2 -15
  58. package/src/tool/concreteCalculator/i18n/pt.ts +2 -15
  59. package/src/tool/concreteCalculator/i18n/ru.ts +2 -15
  60. package/src/tool/concreteCalculator/i18n/sv.ts +2 -15
  61. package/src/tool/concreteCalculator/i18n/tr.ts +2 -15
  62. package/src/tool/concreteCalculator/i18n/zh.ts +2 -15
  63. package/src/tool/concreteCalculator/seo.astro +2 -1
  64. package/src/tool/cutOptimizer/bibliography.astro +2 -9
  65. package/src/tool/cutOptimizer/bibliography.ts +12 -0
  66. package/src/tool/cutOptimizer/i18n/de.ts +2 -11
  67. package/src/tool/cutOptimizer/i18n/en.ts +2 -11
  68. package/src/tool/cutOptimizer/i18n/es.ts +2 -11
  69. package/src/tool/cutOptimizer/i18n/fr.ts +2 -11
  70. package/src/tool/cutOptimizer/i18n/id.ts +2 -11
  71. package/src/tool/cutOptimizer/i18n/it.ts +2 -11
  72. package/src/tool/cutOptimizer/i18n/ja.ts +2 -11
  73. package/src/tool/cutOptimizer/i18n/ko.ts +2 -11
  74. package/src/tool/cutOptimizer/i18n/nl.ts +2 -11
  75. package/src/tool/cutOptimizer/i18n/pl.ts +2 -11
  76. package/src/tool/cutOptimizer/i18n/pt.ts +2 -11
  77. package/src/tool/cutOptimizer/i18n/ru.ts +2 -11
  78. package/src/tool/cutOptimizer/i18n/sv.ts +2 -11
  79. package/src/tool/cutOptimizer/i18n/tr.ts +2 -11
  80. package/src/tool/cutOptimizer/i18n/zh.ts +2 -11
  81. package/src/tool/cutOptimizer/seo.astro +2 -1
  82. package/src/tool/drillCalculator/bibliography.astro +2 -9
  83. package/src/tool/drillCalculator/bibliography.ts +12 -0
  84. package/src/tool/drillCalculator/i18n/de.ts +2 -5
  85. package/src/tool/drillCalculator/i18n/en.ts +2 -5
  86. package/src/tool/drillCalculator/i18n/es.ts +2 -5
  87. package/src/tool/drillCalculator/i18n/fr.ts +2 -5
  88. package/src/tool/drillCalculator/i18n/id.ts +2 -5
  89. package/src/tool/drillCalculator/i18n/it.ts +2 -5
  90. package/src/tool/drillCalculator/i18n/ja.ts +2 -5
  91. package/src/tool/drillCalculator/i18n/ko.ts +2 -5
  92. package/src/tool/drillCalculator/i18n/nl.ts +2 -5
  93. package/src/tool/drillCalculator/i18n/pl.ts +2 -5
  94. package/src/tool/drillCalculator/i18n/pt.ts +2 -5
  95. package/src/tool/drillCalculator/i18n/ru.ts +2 -5
  96. package/src/tool/drillCalculator/i18n/sv.ts +2 -5
  97. package/src/tool/drillCalculator/i18n/tr.ts +2 -5
  98. package/src/tool/drillCalculator/i18n/zh.ts +2 -5
  99. package/src/tool/drillCalculator/seo.astro +2 -1
  100. package/src/tool/drillSharpener/bibliography.astro +2 -9
  101. package/src/tool/drillSharpener/bibliography.ts +16 -0
  102. package/src/tool/drillSharpener/i18n/de.ts +2 -5
  103. package/src/tool/drillSharpener/i18n/en.ts +2 -6
  104. package/src/tool/drillSharpener/i18n/es.ts +2 -6
  105. package/src/tool/drillSharpener/i18n/fr.ts +2 -6
  106. package/src/tool/drillSharpener/i18n/id.ts +2 -5
  107. package/src/tool/drillSharpener/i18n/it.ts +2 -5
  108. package/src/tool/drillSharpener/i18n/ja.ts +2 -5
  109. package/src/tool/drillSharpener/i18n/ko.ts +2 -5
  110. package/src/tool/drillSharpener/i18n/nl.ts +2 -5
  111. package/src/tool/drillSharpener/i18n/pl.ts +2 -5
  112. package/src/tool/drillSharpener/i18n/pt.ts +2 -5
  113. package/src/tool/drillSharpener/i18n/ru.ts +2 -5
  114. package/src/tool/drillSharpener/i18n/sv.ts +2 -5
  115. package/src/tool/drillSharpener/i18n/tr.ts +2 -5
  116. package/src/tool/drillSharpener/i18n/zh.ts +2 -5
  117. package/src/tool/drillSharpener/seo.astro +2 -1
  118. package/src/tool/epoxyCalculator/bibliography.astro +2 -10
  119. package/src/tool/epoxyCalculator/bibliography.ts +20 -0
  120. package/src/tool/epoxyCalculator/i18n/de.ts +2 -5
  121. package/src/tool/epoxyCalculator/i18n/en.ts +2 -19
  122. package/src/tool/epoxyCalculator/i18n/es.ts +2 -19
  123. package/src/tool/epoxyCalculator/i18n/fr.ts +2 -19
  124. package/src/tool/epoxyCalculator/i18n/id.ts +2 -5
  125. package/src/tool/epoxyCalculator/i18n/it.ts +2 -5
  126. package/src/tool/epoxyCalculator/i18n/ja.ts +2 -5
  127. package/src/tool/epoxyCalculator/i18n/ko.ts +2 -5
  128. package/src/tool/epoxyCalculator/i18n/nl.ts +2 -5
  129. package/src/tool/epoxyCalculator/i18n/pl.ts +2 -5
  130. package/src/tool/epoxyCalculator/i18n/pt.ts +2 -5
  131. package/src/tool/epoxyCalculator/i18n/ru.ts +2 -5
  132. package/src/tool/epoxyCalculator/i18n/sv.ts +2 -5
  133. package/src/tool/epoxyCalculator/i18n/tr.ts +2 -5
  134. package/src/tool/epoxyCalculator/i18n/zh.ts +2 -5
  135. package/src/tool/epoxyCalculator/seo.astro +1 -1
  136. package/src/tool/furnitureFit/bibliography.astro +2 -9
  137. package/src/tool/furnitureFit/bibliography.ts +12 -0
  138. package/src/tool/furnitureFit/i18n/de.ts +2 -5
  139. package/src/tool/furnitureFit/i18n/en.ts +2 -5
  140. package/src/tool/furnitureFit/i18n/es.ts +2 -5
  141. package/src/tool/furnitureFit/i18n/fr.ts +2 -5
  142. package/src/tool/furnitureFit/i18n/id.ts +2 -5
  143. package/src/tool/furnitureFit/i18n/it.ts +2 -5
  144. package/src/tool/furnitureFit/i18n/ja.ts +2 -5
  145. package/src/tool/furnitureFit/i18n/ko.ts +2 -5
  146. package/src/tool/furnitureFit/i18n/nl.ts +2 -5
  147. package/src/tool/furnitureFit/i18n/pl.ts +2 -5
  148. package/src/tool/furnitureFit/i18n/pt.ts +2 -5
  149. package/src/tool/furnitureFit/i18n/ru.ts +2 -5
  150. package/src/tool/furnitureFit/i18n/sv.ts +2 -5
  151. package/src/tool/furnitureFit/i18n/tr.ts +2 -5
  152. package/src/tool/furnitureFit/i18n/zh.ts +2 -5
  153. package/src/tool/furnitureFit/seo.astro +2 -1
  154. package/src/tool/mortarCalculator/bibliography.astro +2 -9
  155. package/src/tool/mortarCalculator/bibliography.ts +20 -0
  156. package/src/tool/mortarCalculator/i18n/de.ts +2 -5
  157. package/src/tool/mortarCalculator/i18n/en.ts +2 -19
  158. package/src/tool/mortarCalculator/i18n/es.ts +2 -19
  159. package/src/tool/mortarCalculator/i18n/fr.ts +2 -19
  160. package/src/tool/mortarCalculator/i18n/id.ts +2 -5
  161. package/src/tool/mortarCalculator/i18n/it.ts +2 -5
  162. package/src/tool/mortarCalculator/i18n/ja.ts +2 -5
  163. package/src/tool/mortarCalculator/i18n/ko.ts +2 -5
  164. package/src/tool/mortarCalculator/i18n/nl.ts +2 -5
  165. package/src/tool/mortarCalculator/i18n/pl.ts +2 -5
  166. package/src/tool/mortarCalculator/i18n/pt.ts +2 -5
  167. package/src/tool/mortarCalculator/i18n/ru.ts +2 -5
  168. package/src/tool/mortarCalculator/i18n/sv.ts +2 -5
  169. package/src/tool/mortarCalculator/i18n/tr.ts +2 -5
  170. package/src/tool/mortarCalculator/i18n/zh.ts +2 -5
  171. package/src/tool/mortarCalculator/seo.astro +2 -1
  172. package/src/tool/passepartoutCalculator/bibliography.astro +2 -9
  173. package/src/tool/passepartoutCalculator/bibliography.ts +16 -0
  174. package/src/tool/passepartoutCalculator/i18n/de.ts +2 -6
  175. package/src/tool/passepartoutCalculator/i18n/en.ts +2 -15
  176. package/src/tool/passepartoutCalculator/i18n/es.ts +2 -15
  177. package/src/tool/passepartoutCalculator/i18n/fr.ts +2 -15
  178. package/src/tool/passepartoutCalculator/i18n/id.ts +2 -6
  179. package/src/tool/passepartoutCalculator/i18n/it.ts +2 -6
  180. package/src/tool/passepartoutCalculator/i18n/ja.ts +2 -6
  181. package/src/tool/passepartoutCalculator/i18n/ko.ts +2 -6
  182. package/src/tool/passepartoutCalculator/i18n/nl.ts +2 -6
  183. package/src/tool/passepartoutCalculator/i18n/pl.ts +2 -6
  184. package/src/tool/passepartoutCalculator/i18n/pt.ts +2 -6
  185. package/src/tool/passepartoutCalculator/i18n/ru.ts +2 -6
  186. package/src/tool/passepartoutCalculator/i18n/sv.ts +2 -6
  187. package/src/tool/passepartoutCalculator/i18n/tr.ts +2 -6
  188. package/src/tool/passepartoutCalculator/i18n/zh.ts +2 -6
  189. package/src/tool/passepartoutCalculator/seo.astro +2 -1
  190. package/src/tool/stairCalculator/bibliography.astro +2 -9
  191. package/src/tool/stairCalculator/bibliography.ts +16 -0
  192. package/src/tool/stairCalculator/i18n/de.ts +2 -5
  193. package/src/tool/stairCalculator/i18n/en.ts +2 -6
  194. package/src/tool/stairCalculator/i18n/es.ts +2 -6
  195. package/src/tool/stairCalculator/i18n/fr.ts +2 -6
  196. package/src/tool/stairCalculator/i18n/id.ts +2 -5
  197. package/src/tool/stairCalculator/i18n/it.ts +2 -5
  198. package/src/tool/stairCalculator/i18n/ja.ts +2 -5
  199. package/src/tool/stairCalculator/i18n/ko.ts +2 -5
  200. package/src/tool/stairCalculator/i18n/nl.ts +2 -5
  201. package/src/tool/stairCalculator/i18n/pl.ts +2 -5
  202. package/src/tool/stairCalculator/i18n/pt.ts +2 -5
  203. package/src/tool/stairCalculator/i18n/ru.ts +2 -5
  204. package/src/tool/stairCalculator/i18n/sv.ts +2 -5
  205. package/src/tool/stairCalculator/i18n/tr.ts +2 -5
  206. package/src/tool/stairCalculator/i18n/zh.ts +2 -5
  207. package/src/tool/stairCalculator/seo.astro +2 -1
  208. package/src/tool/thermalExpansionCalculator/bibliography.astro +2 -9
  209. package/src/tool/thermalExpansionCalculator/bibliography.ts +16 -0
  210. package/src/tool/thermalExpansionCalculator/i18n/de.ts +2 -6
  211. package/src/tool/thermalExpansionCalculator/i18n/en.ts +2 -6
  212. package/src/tool/thermalExpansionCalculator/i18n/es.ts +2 -6
  213. package/src/tool/thermalExpansionCalculator/i18n/fr.ts +2 -6
  214. package/src/tool/thermalExpansionCalculator/i18n/id.ts +2 -6
  215. package/src/tool/thermalExpansionCalculator/i18n/it.ts +2 -6
  216. package/src/tool/thermalExpansionCalculator/i18n/ja.ts +2 -6
  217. package/src/tool/thermalExpansionCalculator/i18n/ko.ts +2 -6
  218. package/src/tool/thermalExpansionCalculator/i18n/nl.ts +2 -6
  219. package/src/tool/thermalExpansionCalculator/i18n/pl.ts +2 -6
  220. package/src/tool/thermalExpansionCalculator/i18n/pt.ts +2 -6
  221. package/src/tool/thermalExpansionCalculator/i18n/ru.ts +2 -6
  222. package/src/tool/thermalExpansionCalculator/i18n/sv.ts +2 -6
  223. package/src/tool/thermalExpansionCalculator/i18n/tr.ts +2 -6
  224. package/src/tool/thermalExpansionCalculator/i18n/zh.ts +2 -6
  225. package/src/tool/thermalExpansionCalculator/seo.astro +2 -1
  226. package/src/tool/voltageDropCalculator/bibliography.astro +2 -9
  227. package/src/tool/voltageDropCalculator/bibliography.ts +16 -0
  228. package/src/tool/voltageDropCalculator/i18n/de.ts +2 -5
  229. package/src/tool/voltageDropCalculator/i18n/en.ts +2 -6
  230. package/src/tool/voltageDropCalculator/i18n/es.ts +2 -6
  231. package/src/tool/voltageDropCalculator/i18n/fr.ts +2 -6
  232. package/src/tool/voltageDropCalculator/i18n/id.ts +2 -5
  233. package/src/tool/voltageDropCalculator/i18n/it.ts +2 -5
  234. package/src/tool/voltageDropCalculator/i18n/ja.ts +2 -5
  235. package/src/tool/voltageDropCalculator/i18n/ko.ts +2 -5
  236. package/src/tool/voltageDropCalculator/i18n/nl.ts +2 -5
  237. package/src/tool/voltageDropCalculator/i18n/pl.ts +2 -5
  238. package/src/tool/voltageDropCalculator/i18n/pt.ts +2 -5
  239. package/src/tool/voltageDropCalculator/i18n/ru.ts +2 -5
  240. package/src/tool/voltageDropCalculator/i18n/sv.ts +2 -5
  241. package/src/tool/voltageDropCalculator/i18n/tr.ts +2 -5
  242. package/src/tool/voltageDropCalculator/i18n/zh.ts +2 -5
  243. package/src/tool/voltageDropCalculator/seo.astro +2 -1
  244. package/src/tool/workshopFractionConverter/bibliography.astro +6 -0
  245. package/src/tool/workshopFractionConverter/bibliography.ts +12 -0
  246. package/src/tool/workshopFractionConverter/client.ts +183 -0
  247. package/src/tool/workshopFractionConverter/component.astro +226 -0
  248. package/src/tool/workshopFractionConverter/converter.ts +110 -0
  249. package/src/tool/workshopFractionConverter/engine.ts +223 -0
  250. package/src/tool/workshopFractionConverter/entry.ts +24 -0
  251. package/src/tool/workshopFractionConverter/i18n/de.ts +141 -0
  252. package/src/tool/workshopFractionConverter/i18n/en.ts +141 -0
  253. package/src/tool/workshopFractionConverter/i18n/es.ts +141 -0
  254. package/src/tool/workshopFractionConverter/i18n/fr.ts +141 -0
  255. package/src/tool/workshopFractionConverter/i18n/id.ts +141 -0
  256. package/src/tool/workshopFractionConverter/i18n/it.ts +141 -0
  257. package/src/tool/workshopFractionConverter/i18n/ja.ts +141 -0
  258. package/src/tool/workshopFractionConverter/i18n/ko.ts +141 -0
  259. package/src/tool/workshopFractionConverter/i18n/nl.ts +141 -0
  260. package/src/tool/workshopFractionConverter/i18n/pl.ts +141 -0
  261. package/src/tool/workshopFractionConverter/i18n/pt.ts +141 -0
  262. package/src/tool/workshopFractionConverter/i18n/ru.ts +141 -0
  263. package/src/tool/workshopFractionConverter/i18n/sv.ts +141 -0
  264. package/src/tool/workshopFractionConverter/i18n/tr.ts +141 -0
  265. package/src/tool/workshopFractionConverter/i18n/zh.ts +141 -0
  266. package/src/tool/workshopFractionConverter/index.ts +11 -0
  267. package/src/tool/workshopFractionConverter/seo.astro +15 -0
  268. package/src/tool/workshopFractionConverter/types-client.ts +89 -0
  269. package/src/tool/workshopFractionConverter/ui-updater.ts +94 -0
  270. package/src/tool/workshopFractionConverter/ui.ts +38 -0
  271. package/src/tool/workshopFractionConverter/workshop-fraction-converter.css +563 -0
  272. package/src/tools.ts +2 -1
  273. package/src/types.ts +1 -1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jjlmoya/utils-diy",
3
- "version": "1.11.0",
3
+ "version": "1.12.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -12,10 +12,11 @@ import { thermalExpansionCalculator } from '../tool/thermalExpansionCalculator/i
12
12
  import { drillCalculator } from '../tool/drillCalculator/index';
13
13
  import { stairCalculator } from '../tool/stairCalculator/index';
14
14
  import { drillSharpener } from '../tool/drillSharpener/index';
15
+ import { workshopFractionConverter } from '../tool/workshopFractionConverter/index';
15
16
 
16
17
  export const diyCategory: DiyCategoryEntry = {
17
18
  icon: 'mdi:hand',
18
- tools: [clayCalculator, epoxyCalculator, balusterCalculator, mortarCalculator, passepartoutCalculator, concreteCalculator, cutOptimizer, voltageDropCalculator, furnitureFit, thermalExpansionCalculator, drillCalculator, stairCalculator, drillSharpener],
19
+ tools: [clayCalculator, epoxyCalculator, balusterCalculator, mortarCalculator, passepartoutCalculator, concreteCalculator, cutOptimizer, voltageDropCalculator, furnitureFit, thermalExpansionCalculator, drillCalculator, stairCalculator, drillSharpener, workshopFractionConverter],
19
20
  i18n: {
20
21
  de: () => import('./i18n/de').then((m) => m.content),
21
22
  en: () => import('./i18n/en').then((m) => m.content),
package/src/entries.ts CHANGED
@@ -14,6 +14,7 @@ export { passepartoutCalculator } from './tool/passepartoutCalculator/entry';
14
14
  export { stairCalculator } from './tool/stairCalculator/entry';
15
15
  export { thermalExpansionCalculator } from './tool/thermalExpansionCalculator/entry';
16
16
  export { voltageDropCalculator } from './tool/voltageDropCalculator/entry';
17
+ export { workshopFractionConverter } from './tool/workshopFractionConverter/entry';
17
18
  export { diyCategory } from './category';
18
19
  import { balusterCalculator } from './tool/balusterCalculator/entry';
19
20
  import { clayCalculator } from './tool/clayCalculator/entry';
@@ -28,4 +29,5 @@ import { passepartoutCalculator } from './tool/passepartoutCalculator/entry';
28
29
  import { stairCalculator } from './tool/stairCalculator/entry';
29
30
  import { thermalExpansionCalculator } from './tool/thermalExpansionCalculator/entry';
30
31
  import { voltageDropCalculator } from './tool/voltageDropCalculator/entry';
31
- export const ALL_ENTRIES = [balusterCalculator, clayCalculator, concreteCalculator, cutOptimizer, drillCalculator, drillSharpener, epoxyCalculator, furnitureFit, mortarCalculator, passepartoutCalculator, stairCalculator, thermalExpansionCalculator, voltageDropCalculator];
32
+ import { workshopFractionConverter } from './tool/workshopFractionConverter/entry';
33
+ export const ALL_ENTRIES = [balusterCalculator, clayCalculator, concreteCalculator, cutOptimizer, drillCalculator, drillSharpener, epoxyCalculator, furnitureFit, mortarCalculator, passepartoutCalculator, stairCalculator, thermalExpansionCalculator, voltageDropCalculator, workshopFractionConverter];
package/src/index.ts CHANGED
@@ -42,3 +42,5 @@ export { DRILL_CALCULATOR_TOOL } from './tool/drillCalculator/index';
42
42
  export { STAIR_CALCULATOR_TOOL } from './tool/stairCalculator/index';
43
43
 
44
44
  export { DRILL_SHARPENER_TOOL } from './tool/drillSharpener/index';
45
+
46
+ export { WORKSHOP_FRACTION_CONVERTER_TOOL } from './tool/workshopFractionConverter/index';
@@ -34,18 +34,28 @@ export async function getStaticPaths() {
34
34
  ]),
35
35
  ) as Partial<Record<KnownLocale, string>>;
36
36
 
37
+ const firstLoader = entry.i18n.en ?? Object.values(entry.i18n)[0];
38
+ const englishSlug = firstLoader ? (await firstLoader()).slug : entry.id;
39
+
37
40
  for (const { locale, content } of localeContents) {
38
- const allToolsNav = await Promise.all(
39
- ALL_TOOLS.map(async ({ entry: navEntry }) => ({
40
- id: navEntry.id,
41
- title: (await navEntry.i18n[locale]!()).title,
42
- href: `/${locale}/${(await navEntry.i18n[locale]!()).slug}`,
43
- isActive: navEntry.id === entry.id,
44
- })),
45
- );
41
+ const allToolsNav = (
42
+ await Promise.all(
43
+ ALL_TOOLS.map(async ({ entry: navEntry }) => {
44
+ const loader = navEntry.i18n[locale] ?? navEntry.i18n.en;
45
+ if (!loader) return null;
46
+ const navContent = await loader();
47
+ return {
48
+ id: navEntry.id,
49
+ title: navContent.title,
50
+ href: `/${locale}/${navContent.slug}`,
51
+ isActive: navEntry.id === entry.id,
52
+ };
53
+ }),
54
+ )
55
+ ).filter(Boolean) as NavItem[];
46
56
  paths.push({
47
57
  params: { locale, slug: content.slug },
48
- props: { Component, locale, content, localeUrls, allToolsNav },
58
+ props: { Component, locale, content, localeUrls, allToolsNav, englishSlug },
49
59
  });
50
60
  }
51
61
  }
@@ -66,11 +76,16 @@ interface Props {
66
76
  content: ToolLocaleContent;
67
77
  localeUrls: Partial<Record<KnownLocale, string>>;
68
78
  allToolsNav: NavItem[];
79
+ englishSlug: string;
69
80
  }
70
81
 
71
- const { Component, locale, content, localeUrls, allToolsNav } = Astro.props;
82
+ const { Component, locale, content, localeUrls, allToolsNav, englishSlug } = Astro.props;
83
+
84
+ const cssFiles = import.meta.glob("../../tool/*/*.css", { query: "?raw", import: "default" });
85
+ const cssKey = Object.keys(cssFiles).find((k) => k.endsWith(`/${englishSlug}.css`));
86
+ const toolCss = cssKey ? await cssFiles[cssKey]() as string : "";
72
87
 
73
- const seoContent: UtilitySEOContent = { locale, sections: content.seo };
88
+ const seoContent: UtilitySEOContent = { locale, sections: content.seo ?? [] };
74
89
 
75
90
  const words = content.title.split(" ");
76
91
  const titleHighlight = words[0] || "";
@@ -89,8 +104,9 @@ const titleBase = words.slice(1).join(" ") || "";
89
104
  tools={allToolsNav}
90
105
  />
91
106
  <Fragment slot="head">
107
+ {toolCss ? <Fragment set:html={`<style is:inline>${toolCss}</style>`} /> : null}
92
108
  {
93
- content.schemas.map((schema: unknown) => (
109
+ ( content.schemas ?? []).map((schema: unknown) => (
94
110
  <script
95
111
  is:inline
96
112
  type="application/ld+json"
@@ -19,24 +19,22 @@ describe('Locale Completeness Validation', () => {
19
19
  }
20
20
  });
21
21
 
22
- it('bibliographyTitle should be defined when bibliography items exist', async () => {
22
+ it('bibliography should be available (from independent file)', async () => {
23
23
  const loader = tool.entry.i18n[locale as keyof typeof tool.entry.i18n];
24
24
  const content = (await loader?.()) as ToolLocaleContent;
25
25
 
26
- if (content.bibliography.length > 0) {
27
- expect(
28
- content.bibliographyTitle,
29
- `Tool "${tool.entry.id}" locale "${locale}" has ${content.bibliography.length} bibliography items but is missing bibliographyTitle`,
30
- ).toBeTruthy();
31
- }
26
+ expect(
27
+ content.bibliography,
28
+ `Tool "${tool.entry.id}" locale "${locale}" should have bibliography available`,
29
+ ).toBeDefined();
32
30
  });
33
31
  });
34
32
  });
35
33
  });
36
34
  });
37
35
 
38
- it('all 13 tools registered', () => {
39
- expect(ALL_TOOLS.length).toBe(13);
36
+ it('all 14 tools registered', () => {
37
+ expect(ALL_TOOLS.length).toBe(14);
40
38
  });
41
39
  });
42
40
 
@@ -0,0 +1,56 @@
1
+ import type { ToolDefinition } from '../types';
2
+
3
+ export interface ToolExportValidationResult {
4
+ passed: boolean;
5
+ failures: string[];
6
+ }
7
+
8
+ function validateComponentType(
9
+ toolId: string,
10
+ componentName: string,
11
+ component: unknown,
12
+ failures: string[],
13
+ ): void {
14
+ if (typeof component !== 'function') {
15
+ failures.push(`${toolId}: ${componentName} is not a function (${typeof component})`);
16
+ }
17
+ }
18
+
19
+ async function validateComponentExecution(
20
+ toolId: string,
21
+ componentName: string,
22
+ fn: () => Promise<unknown>,
23
+ failures: string[],
24
+ ): Promise<void> {
25
+ try {
26
+ const result = await fn();
27
+ if (!result || typeof result !== 'object') {
28
+ failures.push(`${toolId}: ${componentName} import returned invalid result`);
29
+ }
30
+ } catch (error) {
31
+ failures.push(`${toolId}: ${componentName} execution error - ${error instanceof Error ? error.message : 'unknown'}`);
32
+ }
33
+ }
34
+
35
+ export async function validateToolExports(tools: ToolDefinition[]): Promise<ToolExportValidationResult> {
36
+ const failures: string[] = [];
37
+
38
+ for (const tool of tools) {
39
+ validateComponentType(tool.entry.id, 'Component', tool.Component, failures);
40
+ validateComponentType(tool.entry.id, 'SEOComponent', tool.SEOComponent, failures);
41
+ validateComponentType(tool.entry.id, 'BibliographyComponent', tool.BibliographyComponent, failures);
42
+
43
+ const componentFn = tool.Component as () => Promise<unknown>;
44
+ const seoFn = tool.SEOComponent as () => Promise<unknown>;
45
+ const bibFn = tool.BibliographyComponent as () => Promise<unknown>;
46
+
47
+ await validateComponentExecution(tool.entry.id, 'Component', componentFn, failures);
48
+ await validateComponentExecution(tool.entry.id, 'SEOComponent', seoFn, failures);
49
+ await validateComponentExecution(tool.entry.id, 'BibliographyComponent', bibFn, failures);
50
+ }
51
+
52
+ return {
53
+ passed: failures.length === 0,
54
+ failures,
55
+ };
56
+ }
@@ -0,0 +1,34 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { ALL_TOOLS } from '../tools';
3
+ import { validateToolExports } from './shared-test-helpers';
4
+
5
+ describe('Tool Exports Pattern Validation', () => {
6
+ describe('Component Exports Format', () => {
7
+ ALL_TOOLS.forEach((tool) => {
8
+ it(`${tool.entry.id}: Component should be a lazy-loaded function`, () => {
9
+ expect(typeof tool.Component).toBe('function');
10
+ expect(tool.Component).toBeInstanceOf(Function);
11
+ });
12
+
13
+ it(`${tool.entry.id}: SEOComponent should be a lazy-loaded function`, () => {
14
+ expect(typeof tool.SEOComponent).toBe('function');
15
+ expect(tool.SEOComponent).toBeInstanceOf(Function);
16
+ });
17
+
18
+ it(`${tool.entry.id}: BibliographyComponent should be a lazy-loaded function`, () => {
19
+ expect(typeof tool.BibliographyComponent).toBe('function');
20
+ expect(tool.BibliographyComponent).toBeInstanceOf(Function);
21
+ });
22
+ });
23
+ });
24
+
25
+ describe('Dynamic Import Validation', () => {
26
+ it('all tools must have functional dynamic imports', async () => {
27
+ const result = await validateToolExports(ALL_TOOLS);
28
+ if (!result.passed) {
29
+ throw new Error(`Tool export validation failed:\n${result.failures.join('\n')}`);
30
+ }
31
+ expect(result.passed).toBe(true);
32
+ });
33
+ });
34
+ });
@@ -4,8 +4,8 @@ import { diyCategory } from '../data';
4
4
 
5
5
  describe('Tool Validation Suite', () => {
6
6
  describe('Library Registration', () => {
7
- it('should have 13 tools in ALL_TOOLS', () => {
8
- expect(ALL_TOOLS.length).toBe(13);
7
+ it('should have 14 tools in ALL_TOOLS', () => {
8
+ expect(ALL_TOOLS.length).toBe(14);
9
9
  });
10
10
 
11
11
  it('diyCategory should be defined', () => {
@@ -1,14 +1,6 @@
1
1
  ---
2
2
  import { Bibliography as SharedBibliography } from '@jjlmoya/utils-shared';
3
- import { balusterCalculator } from './index';
4
- import type { KnownLocale } from '../../types';
5
-
6
- interface Props {
7
- locale?: KnownLocale;
8
- }
9
-
10
- const { locale = 'es' } = Astro.props;
11
- const content = await balusterCalculator.i18n[locale]?.();
3
+ import { bibliography } from './bibliography';
12
4
  ---
13
5
 
14
- {content && <SharedBibliography links={content.bibliography} />}
6
+ <SharedBibliography links={bibliography} />
@@ -0,0 +1,16 @@
1
+ import type { BibliographyEntry } from '../../types';
2
+
3
+ export const bibliography: BibliographyEntry[] = [
4
+ {
5
+ name: 'IRC - International Residential Code (USA)',
6
+ url: 'https://codes.iccsafe.org/content/IRC2021',
7
+ },
8
+ {
9
+ name: 'IBC - International Building Code',
10
+ url: 'https://codes.iccsafe.org/content/IBC2021',
11
+ },
12
+ {
13
+ name: 'CTE - Código Técnico de la Edificación (Spain)',
14
+ url: 'https://www.codigotecnico.org/',
15
+ },
16
+ ];
@@ -1,6 +1,7 @@
1
1
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
2
  import type { ToolLocaleContent } from '../../../types';
3
3
  import type { BalusterCalculatorUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
4
5
 
5
6
  const slug = 'baluster-rechner';
6
7
  const title = 'Baluster Rechner: Exakter Abstand für Geländer';
@@ -89,21 +90,7 @@ export const content: ToolLocaleContent<BalusterCalculatorUI> = {
89
90
  description,
90
91
  faqTitle: 'Häufig gestellte Fragen',
91
92
  faq: faqData,
92
- bibliographyTitle: 'Technische Referenzen',
93
- bibliography: [
94
- {
95
- name: 'DIN 18065 - Treppenmaße und Geländer (Deutschland)',
96
- url: 'https://www.beuth.de/de/norm/din-18065/324683526',
97
- },
98
- {
99
- name: 'IRC - International Residential Code (USA)',
100
- url: 'https://codes.iccsafe.org/content/IRC2021',
101
- },
102
- {
103
- name: 'IBC - International Building Code',
104
- url: 'https://codes.iccsafe.org/content/IBC2021',
105
- },
106
- ],
93
+ bibliography,
107
94
  howTo: howToData,
108
95
  schemas: [faqSchema, howToSchema, appSchema],
109
96
  seo: [
@@ -1,6 +1,7 @@
1
1
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
2
  import type { ToolLocaleContent } from '../../../types';
3
3
  import type { BalusterCalculatorUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
4
5
 
5
6
  const slug = 'baluster-calculator';
6
7
  const title = 'Baluster Calculator: Exact Railing Spacing';
@@ -89,21 +90,7 @@ export const content: ToolLocaleContent<BalusterCalculatorUI> = {
89
90
  description,
90
91
  faqTitle: 'Frequently Asked Questions',
91
92
  faq: faqData,
92
- bibliographyTitle: 'Technical References',
93
- bibliography: [
94
- {
95
- name: 'IRC - International Residential Code (USA)',
96
- url: 'https://codes.iccsafe.org/content/IRC2021',
97
- },
98
- {
99
- name: 'IBC - International Building Code',
100
- url: 'https://codes.iccsafe.org/content/IBC2021',
101
- },
102
- {
103
- name: 'CTE - Código Técnico de la Edificación (Spain)',
104
- url: 'https://www.codigotecnico.org/',
105
- },
106
- ],
93
+ bibliography,
107
94
  howTo: howToData,
108
95
  schemas: [faqSchema, howToSchema, appSchema],
109
96
  seo: [
@@ -1,6 +1,7 @@
1
1
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
2
  import type { ToolLocaleContent } from '../../../types';
3
3
  import type { BalusterCalculatorUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
4
5
 
5
6
  const slug = 'calculadora-balustres';
6
7
  const title = 'Calculadora de Balustres: Espaciado Exacto para Barandillas';
@@ -89,21 +90,7 @@ export const content: ToolLocaleContent<BalusterCalculatorUI> = {
89
90
  description,
90
91
  faqTitle: 'Preguntas Frecuentes',
91
92
  faq: faqData,
92
- bibliographyTitle: 'Referencias Técnicas',
93
- bibliography: [
94
- {
95
- name: 'CTE - Código Técnico de la Edificación (España)',
96
- url: 'https://www.codigotecnico.org/',
97
- },
98
- {
99
- name: 'IRC - International Residential Code (EE.UU.)',
100
- url: 'https://codes.iccsafe.org/content/IRC2021',
101
- },
102
- {
103
- name: 'IBC - International Building Code',
104
- url: 'https://codes.iccsafe.org/content/IBC2021',
105
- },
106
- ],
93
+ bibliography,
107
94
  howTo: howToData,
108
95
  schemas: [faqSchema, howToSchema, appSchema],
109
96
  seo: [
@@ -1,6 +1,7 @@
1
1
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
2
  import type { ToolLocaleContent } from '../../../types';
3
3
  import type { BalusterCalculatorUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
4
5
 
5
6
  const slug = 'calculateur-balustres';
6
7
  const title = 'Calculateur de Balustres: Espacement Exact pour Rampes';
@@ -89,21 +90,7 @@ export const content: ToolLocaleContent<BalusterCalculatorUI> = {
89
90
  description,
90
91
  faqTitle: 'Questions Fréquentes',
91
92
  faq: faqData,
92
- bibliographyTitle: 'Références Techniques',
93
- bibliography: [
94
- {
95
- name: 'IBC - International Building Code',
96
- url: 'https://codes.iccsafe.org/content/IBC2021',
97
- },
98
- {
99
- name: 'IRC - International Residential Code (États-Unis)',
100
- url: 'https://codes.iccsafe.org/content/IRC2021',
101
- },
102
- {
103
- name: 'CTE - Código Técnico de la Edificación (Espagne)',
104
- url: 'https://www.codigotecnico.org/',
105
- },
106
- ],
93
+ bibliography,
107
94
  howTo: howToData,
108
95
  schemas: [faqSchema, howToSchema, appSchema],
109
96
  seo: [
@@ -1,6 +1,7 @@
1
1
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
2
  import type { ToolLocaleContent } from '../../../types';
3
3
  import type { BalusterCalculatorUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
4
5
 
5
6
  const slug = 'kalkulator-baluster';
6
7
  const title = 'Kalkulator Baluster: Jarak Tepat untuk Pagar';
@@ -89,21 +90,7 @@ export const content: ToolLocaleContent<BalusterCalculatorUI> = {
89
90
  description,
90
91
  faqTitle: 'Pertanyaan Umum',
91
92
  faq: faqData,
92
- bibliographyTitle: 'Referensi Teknis',
93
- bibliography: [
94
- {
95
- name: 'Standar Keamanan Pagar Internasional',
96
- url: 'https://www.iccsafe.org/',
97
- },
98
- {
99
- name: 'IRC - International Residential Code (AS)',
100
- url: 'https://codes.iccsafe.org/content/IRC2021',
101
- },
102
- {
103
- name: 'IBC - International Building Code',
104
- url: 'https://codes.iccsafe.org/content/IBC2021',
105
- },
106
- ],
93
+ bibliography,
107
94
  howTo: howToData,
108
95
  schemas: [faqSchema, howToSchema, appSchema],
109
96
  seo: [
@@ -1,6 +1,7 @@
1
1
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
2
  import type { ToolLocaleContent } from '../../../types';
3
3
  import type { BalusterCalculatorUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
4
5
 
5
6
  const slug = 'calcolatrice-balaustre';
6
7
  const title = 'Calcolatrice per Balaustre: Spaziatura Esatta per Ringhiere';
@@ -89,21 +90,7 @@ export const content: ToolLocaleContent<BalusterCalculatorUI> = {
89
90
  description,
90
91
  faqTitle: 'Domande Frequenti',
91
92
  faq: faqData,
92
- bibliographyTitle: 'Riferimenti Tecnici',
93
- bibliography: [
94
- {
95
- name: 'Normativa Italiana sulle Ringhiere e Parapetti',
96
- url: 'https://www.lavoripubblici.it/',
97
- },
98
- {
99
- name: 'IRC - International Residential Code (USA)',
100
- url: 'https://codes.iccsafe.org/content/IRC2021',
101
- },
102
- {
103
- name: 'IBC - International Building Code',
104
- url: 'https://codes.iccsafe.org/content/IBC2021',
105
- },
106
- ],
93
+ bibliography,
107
94
  howTo: howToData,
108
95
  schemas: [faqSchema, howToSchema, appSchema],
109
96
  seo: [
@@ -1,6 +1,7 @@
1
1
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
2
  import type { ToolLocaleContent } from '../../../types';
3
3
  import type { BalusterCalculatorUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
4
5
 
5
6
  const slug = 'baluster-calculator';
6
7
  const title = 'バラスター計算機:手すりの正確な間隔計算';
@@ -89,21 +90,7 @@ export const content: ToolLocaleContent<BalusterCalculatorUI> = {
89
90
  description,
90
91
  faqTitle: 'よくある質問',
91
92
  faq: faqData,
92
- bibliographyTitle: '技術リファレンス',
93
- bibliography: [
94
- {
95
- name: '建築基準法(日本)',
96
- url: 'https://www.mlit.go.jp/',
97
- },
98
- {
99
- name: 'IRC - 国際住宅基準(米国)',
100
- url: 'https://codes.iccsafe.org/content/IRC2021',
101
- },
102
- {
103
- name: 'IBC - 国際建築基準',
104
- url: 'https://codes.iccsafe.org/content/IBC2021',
105
- },
106
- ],
93
+ bibliography,
107
94
  howTo: howToData,
108
95
  schemas: [faqSchema, howToSchema, appSchema],
109
96
  seo: [
@@ -1,6 +1,7 @@
1
1
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
2
  import type { ToolLocaleContent } from '../../../types';
3
3
  import type { BalusterCalculatorUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
4
5
 
5
6
  const slug = 'baluster-calculator';
6
7
  const title = '발러스터 계산기: 난간의 정확한 간격 계산';
@@ -89,21 +90,7 @@ export const content: ToolLocaleContent<BalusterCalculatorUI> = {
89
90
  description,
90
91
  faqTitle: '자주 묻는 질문',
91
92
  faq: faqData,
92
- bibliographyTitle: '기술 참고 문헌',
93
- bibliography: [
94
- {
95
- name: '건축물의 피난·방화구조 등의 기준에 관한 규칙 (한국)',
96
- url: 'https://www.law.go.kr/',
97
- },
98
- {
99
- name: 'IRC - 국제 주택 기준 (미국)',
100
- url: 'https://codes.iccsafe.org/content/IRC2021',
101
- },
102
- {
103
- name: 'IBC - 국제 건축 기준',
104
- url: 'https://codes.iccsafe.org/content/IBC2021',
105
- },
106
- ],
93
+ bibliography,
107
94
  howTo: howToData,
108
95
  schemas: [faqSchema, howToSchema, appSchema],
109
96
  seo: [
@@ -1,6 +1,7 @@
1
1
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
2
  import type { ToolLocaleContent } from '../../../types';
3
3
  import type { BalusterCalculatorUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
4
5
 
5
6
  const slug = 'baluster-rekenmachine';
6
7
  const title = 'Baluster Calculator: Exacte Afstand voor Leuningen';
@@ -89,21 +90,7 @@ export const content: ToolLocaleContent<BalusterCalculatorUI> = {
89
90
  description,
90
91
  faqTitle: 'Veelgestelde Vragen',
91
92
  faq: faqData,
92
- bibliographyTitle: 'Technische Verwijzingen',
93
- bibliography: [
94
- {
95
- name: 'Bouwbesluit (Nederland)',
96
- url: 'https://www.bouwbesluitonline.nl/',
97
- },
98
- {
99
- name: 'IRC - International Residential Code (VS)',
100
- url: 'https://codes.iccsafe.org/content/IRC2021',
101
- },
102
- {
103
- name: 'IBC - International Building Code',
104
- url: 'https://codes.iccsafe.org/content/IBC2021',
105
- },
106
- ],
93
+ bibliography,
107
94
  howTo: howToData,
108
95
  schemas: [faqSchema, howToSchema, appSchema],
109
96
  seo: [
@@ -1,6 +1,7 @@
1
1
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
2
  import type { ToolLocaleContent } from '../../../types';
3
3
  import type { BalusterCalculatorUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
4
5
 
5
6
  const slug = 'kalkulator-tralek';
6
7
  const title = 'Kalkulator Tralek: Dokładne Rozmieszczenie dla Barierek';
@@ -89,21 +90,7 @@ export const content: ToolLocaleContent<BalusterCalculatorUI> = {
89
90
  description,
90
91
  faqTitle: 'Często Zadawane Pytania',
91
92
  faq: faqData,
92
- bibliographyTitle: 'Referencje Techniczne',
93
- bibliography: [
94
- {
95
- name: 'Prawo Budowlane (Polska)',
96
- url: 'https://isap.sejm.gov.pl/',
97
- },
98
- {
99
- name: 'IRC - International Residential Code (USA)',
100
- url: 'https://codes.iccsafe.org/content/IRC2021',
101
- },
102
- {
103
- name: 'IBC - International Building Code',
104
- url: 'https://codes.iccsafe.org/content/IBC2021',
105
- },
106
- ],
93
+ bibliography,
107
94
  howTo: howToData,
108
95
  schemas: [faqSchema, howToSchema, appSchema],
109
96
  seo: [
@@ -1,6 +1,7 @@
1
1
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
2
  import type { ToolLocaleContent } from '../../../types';
3
3
  import type { BalusterCalculatorUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
4
5
 
5
6
  const slug = 'calculadora-balaustres';
6
7
  const title = 'Calculadora de Balaústres: Espaçamento Exato para Guardas';
@@ -89,21 +90,7 @@ export const content: ToolLocaleContent<BalusterCalculatorUI> = {
89
90
  description,
90
91
  faqTitle: 'Perguntas Frequentes',
91
92
  faq: faqData,
92
- bibliographyTitle: 'Referências Técnicas',
93
- bibliography: [
94
- {
95
- name: 'RGEU - Regulamento Geral das Edificações Urbanas (Portugal)',
96
- url: 'https://DiariodaRepublica.pt/',
97
- },
98
- {
99
- name: 'IRC - International Residential Code (EUA)',
100
- url: 'https://codes.iccsafe.org/content/IRC2021',
101
- },
102
- {
103
- name: 'IBC - International Building Code',
104
- url: 'https://codes.iccsafe.org/content/IBC2021',
105
- },
106
- ],
93
+ bibliography,
107
94
  howTo: howToData,
108
95
  schemas: [faqSchema, howToSchema, appSchema],
109
96
  seo: [
@@ -1,6 +1,7 @@
1
1
  import type { WithContext, FAQPage, HowToThing, SoftwareApplication } from 'schema-dts';
2
2
  import type { ToolLocaleContent } from '../../../types';
3
3
  import type { BalusterCalculatorUI } from '../ui';
4
+ import { bibliography } from '../bibliography';
4
5
 
5
6
  const slug = 'kalkulyator-balyasin';
6
7
  const title = 'Калькулятор балясин: Точный расчет расстояния для ограждений';
@@ -89,21 +90,7 @@ export const content: ToolLocaleContent<BalusterCalculatorUI> = {
89
90
  description,
90
91
  faqTitle: 'Часто задаваемые вопросы',
91
92
  faq: faqData,
92
- bibliographyTitle: 'Технические справочники',
93
- bibliography: [
94
- {
95
- name: 'ГОСТ 25772-2021 Ограждения лестниц, балконов и крыш стальные',
96
- url: 'https://docs.cntd.ru/',
97
- },
98
- {
99
- name: 'IRC - International Residential Code (США)',
100
- url: 'https://codes.iccsafe.org/content/IRC2021',
101
- },
102
- {
103
- name: 'IBC - International Building Code',
104
- url: 'https://codes.iccsafe.org/content/IBC2021',
105
- },
106
- ],
93
+ bibliography,
107
94
  howTo: howToData,
108
95
  schemas: [faqSchema, howToSchema, appSchema],
109
96
  seo: [