riksdagsmonitor 0.8.12 → 0.8.15

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 (779) hide show
  1. package/dist/lib/cia/dashboard-init.d.ts +26 -0
  2. package/dist/lib/cia/dashboard-init.d.ts.map +1 -0
  3. package/dist/lib/cia/dashboard-init.js +108 -0
  4. package/dist/lib/cia/dashboard-init.js.map +1 -0
  5. package/dist/lib/cia/data-loader.d.ts +408 -0
  6. package/dist/lib/cia/data-loader.d.ts.map +1 -0
  7. package/dist/lib/cia/data-loader.js +867 -0
  8. package/dist/lib/cia/data-loader.js.map +1 -0
  9. package/dist/lib/cia/election-predictions.d.ts +78 -0
  10. package/dist/lib/cia/election-predictions.d.ts.map +1 -0
  11. package/dist/lib/cia/election-predictions.js +259 -0
  12. package/dist/lib/cia/election-predictions.js.map +1 -0
  13. package/dist/lib/cia/i18n-translations.d.ts +111 -0
  14. package/dist/lib/cia/i18n-translations.d.ts.map +1 -0
  15. package/dist/lib/cia/i18n-translations.js +619 -0
  16. package/dist/lib/cia/i18n-translations.js.map +1 -0
  17. package/dist/lib/cia/visualizations.d.ts +64 -0
  18. package/dist/lib/cia/visualizations.d.ts.map +1 -0
  19. package/dist/lib/cia/visualizations.js +662 -0
  20. package/dist/lib/cia/visualizations.js.map +1 -0
  21. package/dist/lib/dashboards/anomaly-detection.d.ts +44 -0
  22. package/dist/lib/dashboards/anomaly-detection.d.ts.map +1 -0
  23. package/dist/lib/dashboards/anomaly-detection.js +1017 -0
  24. package/dist/lib/dashboards/anomaly-detection.js.map +1 -0
  25. package/dist/lib/dashboards/coalition-dashboard.d.ts +36 -0
  26. package/dist/lib/dashboards/coalition-dashboard.d.ts.map +1 -0
  27. package/dist/lib/dashboards/coalition-dashboard.js +629 -0
  28. package/dist/lib/dashboards/coalition-dashboard.js.map +1 -0
  29. package/dist/lib/dashboards/coalition-loader.d.ts +43 -0
  30. package/dist/lib/dashboards/coalition-loader.d.ts.map +1 -0
  31. package/dist/lib/dashboards/coalition-loader.js +665 -0
  32. package/dist/lib/dashboards/coalition-loader.js.map +1 -0
  33. package/dist/lib/dashboards/committees-dashboard.d.ts +23 -0
  34. package/dist/lib/dashboards/committees-dashboard.d.ts.map +1 -0
  35. package/dist/lib/dashboards/committees-dashboard.js +886 -0
  36. package/dist/lib/dashboards/committees-dashboard.js.map +1 -0
  37. package/dist/lib/dashboards/election-cycle.d.ts +62 -0
  38. package/dist/lib/dashboards/election-cycle.d.ts.map +1 -0
  39. package/dist/lib/dashboards/election-cycle.js +484 -0
  40. package/dist/lib/dashboards/election-cycle.js.map +1 -0
  41. package/dist/lib/dashboards/ministry-dashboard.d.ts +46 -0
  42. package/dist/lib/dashboards/ministry-dashboard.d.ts.map +1 -0
  43. package/dist/lib/dashboards/ministry-dashboard.js +1114 -0
  44. package/dist/lib/dashboards/ministry-dashboard.js.map +1 -0
  45. package/dist/lib/dashboards/party-dashboard.d.ts +56 -0
  46. package/dist/lib/dashboards/party-dashboard.d.ts.map +1 -0
  47. package/dist/lib/dashboards/party-dashboard.js +981 -0
  48. package/dist/lib/dashboards/party-dashboard.js.map +1 -0
  49. package/dist/lib/dashboards/politician-dashboard.d.ts +41 -0
  50. package/dist/lib/dashboards/politician-dashboard.d.ts.map +1 -0
  51. package/dist/lib/dashboards/politician-dashboard.js +611 -0
  52. package/dist/lib/dashboards/politician-dashboard.js.map +1 -0
  53. package/dist/lib/dashboards/pre-election.d.ts +64 -0
  54. package/dist/lib/dashboards/pre-election.d.ts.map +1 -0
  55. package/dist/lib/dashboards/pre-election.js +604 -0
  56. package/dist/lib/dashboards/pre-election.js.map +1 -0
  57. package/dist/lib/dashboards/risk-dashboard.d.ts +37 -0
  58. package/dist/lib/dashboards/risk-dashboard.d.ts.map +1 -0
  59. package/dist/lib/dashboards/risk-dashboard.js +863 -0
  60. package/dist/lib/dashboards/risk-dashboard.js.map +1 -0
  61. package/dist/lib/dashboards/seasonal-patterns.d.ts +24 -0
  62. package/dist/lib/dashboards/seasonal-patterns.d.ts.map +1 -0
  63. package/dist/lib/dashboards/seasonal-patterns.js +535 -0
  64. package/dist/lib/dashboards/seasonal-patterns.js.map +1 -0
  65. package/dist/lib/dashboards/stats-loader.d.ts +35 -0
  66. package/dist/lib/dashboards/stats-loader.d.ts.map +1 -0
  67. package/dist/lib/dashboards/stats-loader.js +145 -0
  68. package/dist/lib/dashboards/stats-loader.js.map +1 -0
  69. package/dist/lib/shared/chart-factory.d.ts.map +1 -0
  70. package/dist/lib/shared/chart-factory.js.map +1 -0
  71. package/dist/lib/shared/data-loader.d.ts.map +1 -0
  72. package/dist/lib/shared/data-loader.js.map +1 -0
  73. package/dist/lib/shared/dom-utils.d.ts.map +1 -0
  74. package/dist/lib/shared/dom-utils.js.map +1 -0
  75. package/dist/lib/shared/error-boundary.d.ts.map +1 -0
  76. package/dist/lib/shared/error-boundary.js.map +1 -0
  77. package/dist/lib/shared/fallback-ui.d.ts.map +1 -0
  78. package/dist/lib/shared/fallback-ui.js.map +1 -0
  79. package/dist/lib/shared/index.d.ts.map +1 -0
  80. package/dist/lib/shared/index.js.map +1 -0
  81. package/dist/lib/shared/logger.d.ts.map +1 -0
  82. package/dist/lib/shared/logger.js.map +1 -0
  83. package/dist/lib/shared/register-globals.d.ts +14 -0
  84. package/dist/lib/shared/register-globals.d.ts.map +1 -0
  85. package/dist/lib/shared/register-globals.js +21 -0
  86. package/dist/lib/shared/register-globals.js.map +1 -0
  87. package/dist/lib/shared/theme.d.ts.map +1 -0
  88. package/dist/lib/shared/theme.js.map +1 -0
  89. package/dist/lib/shared/types.d.ts.map +1 -0
  90. package/dist/lib/shared/types.js.map +1 -0
  91. package/dist/lib/ui/back-to-top.d.ts +13 -0
  92. package/dist/lib/ui/back-to-top.d.ts.map +1 -0
  93. package/dist/lib/ui/back-to-top.js +48 -0
  94. package/dist/lib/ui/back-to-top.js.map +1 -0
  95. package/dist/scripts/ai-analysis/coalition-detector.d.ts +28 -0
  96. package/dist/scripts/ai-analysis/coalition-detector.d.ts.map +1 -0
  97. package/dist/scripts/ai-analysis/coalition-detector.js +242 -0
  98. package/dist/scripts/ai-analysis/coalition-detector.js.map +1 -0
  99. package/dist/scripts/ai-analysis/dashboard-analyzer.d.ts +73 -0
  100. package/dist/scripts/ai-analysis/dashboard-analyzer.d.ts.map +1 -0
  101. package/dist/scripts/ai-analysis/dashboard-analyzer.js +511 -0
  102. package/dist/scripts/ai-analysis/dashboard-analyzer.js.map +1 -0
  103. package/dist/scripts/ai-analysis/document-analyzer.d.ts +196 -0
  104. package/dist/scripts/ai-analysis/document-analyzer.d.ts.map +1 -0
  105. package/dist/scripts/ai-analysis/document-analyzer.js +1001 -0
  106. package/dist/scripts/ai-analysis/document-analyzer.js.map +1 -0
  107. package/dist/scripts/ai-analysis/domains/index.d.ts +15 -0
  108. package/dist/scripts/ai-analysis/domains/index.d.ts.map +1 -0
  109. package/dist/scripts/ai-analysis/domains/index.js +494 -0
  110. package/dist/scripts/ai-analysis/domains/index.js.map +1 -0
  111. package/dist/scripts/ai-analysis/helpers.d.ts +43 -0
  112. package/dist/scripts/ai-analysis/helpers.d.ts.map +1 -0
  113. package/dist/scripts/ai-analysis/helpers.js +79 -0
  114. package/dist/scripts/ai-analysis/helpers.js.map +1 -0
  115. package/dist/scripts/ai-analysis/index.d.ts +15 -0
  116. package/dist/scripts/ai-analysis/index.d.ts.map +1 -0
  117. package/dist/scripts/ai-analysis/index.js +14 -0
  118. package/dist/scripts/ai-analysis/index.js.map +1 -0
  119. package/dist/scripts/ai-analysis/pipeline.d.ts +41 -0
  120. package/dist/scripts/ai-analysis/pipeline.d.ts.map +1 -0
  121. package/dist/scripts/ai-analysis/pipeline.js +208 -0
  122. package/dist/scripts/ai-analysis/pipeline.js.map +1 -0
  123. package/dist/scripts/ai-analysis/political-significance.d.ts +63 -0
  124. package/dist/scripts/ai-analysis/political-significance.d.ts.map +1 -0
  125. package/dist/scripts/ai-analysis/political-significance.js +227 -0
  126. package/dist/scripts/ai-analysis/political-significance.js.map +1 -0
  127. package/dist/scripts/ai-analysis/quality-assessor.d.ts +104 -0
  128. package/dist/scripts/ai-analysis/quality-assessor.d.ts.map +1 -0
  129. package/dist/scripts/ai-analysis/quality-assessor.js +554 -0
  130. package/dist/scripts/ai-analysis/quality-assessor.js.map +1 -0
  131. package/dist/scripts/ai-analysis/swot/index.d.ts +56 -0
  132. package/dist/scripts/ai-analysis/swot/index.d.ts.map +1 -0
  133. package/dist/scripts/ai-analysis/swot/index.js +360 -0
  134. package/dist/scripts/ai-analysis/swot/index.js.map +1 -0
  135. package/dist/scripts/ai-analysis/swot/placeholders.d.ts +30 -0
  136. package/dist/scripts/ai-analysis/swot/placeholders.d.ts.map +1 -0
  137. package/dist/scripts/ai-analysis/swot/placeholders.js +381 -0
  138. package/dist/scripts/ai-analysis/swot/placeholders.js.map +1 -0
  139. package/dist/scripts/ai-analysis/types.d.ts +333 -0
  140. package/dist/scripts/ai-analysis/types.d.ts.map +1 -0
  141. package/dist/scripts/ai-analysis/types.js +19 -0
  142. package/dist/scripts/ai-analysis/types.js.map +1 -0
  143. package/dist/scripts/ai-analysis/visualisation/index.d.ts +15 -0
  144. package/dist/scripts/ai-analysis/visualisation/index.d.ts.map +1 -0
  145. package/dist/scripts/ai-analysis/visualisation/index.js +179 -0
  146. package/dist/scripts/ai-analysis/visualisation/index.js.map +1 -0
  147. package/dist/scripts/analysis-framework/cross-reference.d.ts +35 -0
  148. package/dist/scripts/analysis-framework/cross-reference.d.ts.map +1 -0
  149. package/dist/scripts/analysis-framework/cross-reference.js +290 -0
  150. package/dist/scripts/analysis-framework/cross-reference.js.map +1 -0
  151. package/dist/scripts/analysis-framework/index.d.ts +79 -0
  152. package/dist/scripts/analysis-framework/index.d.ts.map +1 -0
  153. package/dist/scripts/analysis-framework/index.js +133 -0
  154. package/dist/scripts/analysis-framework/index.js.map +1 -0
  155. package/dist/scripts/analysis-framework/lenses/citizen.d.ts +29 -0
  156. package/dist/scripts/analysis-framework/lenses/citizen.d.ts.map +1 -0
  157. package/dist/scripts/analysis-framework/lenses/citizen.js +220 -0
  158. package/dist/scripts/analysis-framework/lenses/citizen.js.map +1 -0
  159. package/dist/scripts/analysis-framework/lenses/economic.d.ts +29 -0
  160. package/dist/scripts/analysis-framework/lenses/economic.d.ts.map +1 -0
  161. package/dist/scripts/analysis-framework/lenses/economic.js +227 -0
  162. package/dist/scripts/analysis-framework/lenses/economic.js.map +1 -0
  163. package/dist/scripts/analysis-framework/lenses/government.d.ts +32 -0
  164. package/dist/scripts/analysis-framework/lenses/government.d.ts.map +1 -0
  165. package/dist/scripts/analysis-framework/lenses/government.js +265 -0
  166. package/dist/scripts/analysis-framework/lenses/government.js.map +1 -0
  167. package/dist/scripts/analysis-framework/lenses/international.d.ts +29 -0
  168. package/dist/scripts/analysis-framework/lenses/international.d.ts.map +1 -0
  169. package/dist/scripts/analysis-framework/lenses/international.js +248 -0
  170. package/dist/scripts/analysis-framework/lenses/international.js.map +1 -0
  171. package/dist/scripts/analysis-framework/lenses/media.d.ts +29 -0
  172. package/dist/scripts/analysis-framework/lenses/media.d.ts.map +1 -0
  173. package/dist/scripts/analysis-framework/lenses/media.js +211 -0
  174. package/dist/scripts/analysis-framework/lenses/media.js.map +1 -0
  175. package/dist/scripts/analysis-framework/lenses/opposition.d.ts +29 -0
  176. package/dist/scripts/analysis-framework/lenses/opposition.d.ts.map +1 -0
  177. package/dist/scripts/analysis-framework/lenses/opposition.js +234 -0
  178. package/dist/scripts/analysis-framework/lenses/opposition.js.map +1 -0
  179. package/dist/scripts/analysis-framework/methodology-types.d.ts +309 -0
  180. package/dist/scripts/analysis-framework/methodology-types.d.ts.map +1 -0
  181. package/dist/scripts/analysis-framework/methodology-types.js +38 -0
  182. package/dist/scripts/analysis-framework/methodology-types.js.map +1 -0
  183. package/dist/scripts/analysis-framework/political-classification.d.ts +58 -0
  184. package/dist/scripts/analysis-framework/political-classification.d.ts.map +1 -0
  185. package/dist/scripts/analysis-framework/political-classification.js +414 -0
  186. package/dist/scripts/analysis-framework/political-classification.js.map +1 -0
  187. package/dist/scripts/analysis-framework/political-risk-assessment.d.ts +74 -0
  188. package/dist/scripts/analysis-framework/political-risk-assessment.d.ts.map +1 -0
  189. package/dist/scripts/analysis-framework/political-risk-assessment.js +656 -0
  190. package/dist/scripts/analysis-framework/political-risk-assessment.js.map +1 -0
  191. package/dist/scripts/analysis-framework/political-threat-analysis.d.ts +65 -0
  192. package/dist/scripts/analysis-framework/political-threat-analysis.d.ts.map +1 -0
  193. package/dist/scripts/analysis-framework/political-threat-analysis.js +553 -0
  194. package/dist/scripts/analysis-framework/political-threat-analysis.js.map +1 -0
  195. package/dist/scripts/analysis-framework/significance-scorer.d.ts +62 -0
  196. package/dist/scripts/analysis-framework/significance-scorer.d.ts.map +1 -0
  197. package/dist/scripts/analysis-framework/significance-scorer.js +196 -0
  198. package/dist/scripts/analysis-framework/significance-scorer.js.map +1 -0
  199. package/dist/scripts/analysis-framework/types.d.ts +138 -0
  200. package/dist/scripts/analysis-framework/types.d.ts.map +1 -0
  201. package/dist/scripts/analysis-framework/types.js +12 -0
  202. package/dist/scripts/analysis-framework/types.js.map +1 -0
  203. package/dist/scripts/analysis-reader.d.ts +240 -0
  204. package/dist/scripts/analysis-reader.d.ts.map +1 -0
  205. package/dist/scripts/analysis-reader.js +495 -0
  206. package/dist/scripts/analysis-reader.js.map +1 -0
  207. package/dist/scripts/article-quality-enhancer.d.ts +148 -0
  208. package/dist/scripts/article-quality-enhancer.d.ts.map +1 -0
  209. package/dist/scripts/article-quality-enhancer.js +430 -0
  210. package/dist/scripts/article-quality-enhancer.js.map +1 -0
  211. package/dist/scripts/article-template/constants.d.ts +104 -0
  212. package/dist/scripts/article-template/constants.d.ts.map +1 -0
  213. package/dist/scripts/article-template/constants.js +225 -0
  214. package/dist/scripts/article-template/constants.js.map +1 -0
  215. package/dist/scripts/article-template/helpers.d.ts +83 -0
  216. package/dist/scripts/article-template/helpers.d.ts.map +1 -0
  217. package/dist/scripts/article-template/helpers.js +236 -0
  218. package/dist/scripts/article-template/helpers.js.map +1 -0
  219. package/dist/scripts/article-template/index.d.ts +39 -0
  220. package/dist/scripts/article-template/index.d.ts.map +1 -0
  221. package/dist/scripts/article-template/index.js +37 -0
  222. package/dist/scripts/article-template/index.js.map +1 -0
  223. package/dist/scripts/article-template/registry.d.ts +64 -0
  224. package/dist/scripts/article-template/registry.d.ts.map +1 -0
  225. package/dist/scripts/article-template/registry.js +405 -0
  226. package/dist/scripts/article-template/registry.js.map +1 -0
  227. package/dist/scripts/article-template/template.d.ts +18 -0
  228. package/dist/scripts/article-template/template.d.ts.map +1 -0
  229. package/dist/scripts/article-template/template.js +359 -0
  230. package/dist/scripts/article-template/template.js.map +1 -0
  231. package/dist/scripts/article-template/types.d.ts +90 -0
  232. package/dist/scripts/article-template/types.d.ts.map +1 -0
  233. package/dist/scripts/article-template/types.js +96 -0
  234. package/dist/scripts/article-template/types.js.map +1 -0
  235. package/dist/scripts/article-template.d.ts +18 -0
  236. package/dist/scripts/article-template.d.ts.map +1 -0
  237. package/dist/scripts/article-template.js +18 -0
  238. package/dist/scripts/article-template.js.map +1 -0
  239. package/dist/scripts/catalog-downloaded-data.d.ts +66 -0
  240. package/dist/scripts/catalog-downloaded-data.d.ts.map +1 -0
  241. package/dist/scripts/catalog-downloaded-data.js +239 -0
  242. package/dist/scripts/catalog-downloaded-data.js.map +1 -0
  243. package/dist/scripts/check-cia-schema-updates.d.ts +186 -0
  244. package/dist/scripts/check-cia-schema-updates.d.ts.map +1 -0
  245. package/dist/scripts/check-cia-schema-updates.js +363 -0
  246. package/dist/scripts/check-cia-schema-updates.js.map +1 -0
  247. package/dist/scripts/data-transformers/calendar.d.ts +16 -0
  248. package/dist/scripts/data-transformers/calendar.d.ts.map +1 -0
  249. package/dist/scripts/data-transformers/calendar.js +137 -0
  250. package/dist/scripts/data-transformers/calendar.js.map +1 -0
  251. package/dist/scripts/data-transformers/constants/committee-names.d.ts +15 -0
  252. package/dist/scripts/data-transformers/constants/committee-names.d.ts.map +1 -0
  253. package/dist/scripts/data-transformers/constants/committee-names.js +30 -0
  254. package/dist/scripts/data-transformers/constants/committee-names.js.map +1 -0
  255. package/dist/scripts/data-transformers/constants/content-labels-part1.d.ts +11 -0
  256. package/dist/scripts/data-transformers/constants/content-labels-part1.d.ts.map +1 -0
  257. package/dist/scripts/data-transformers/constants/content-labels-part1.js +900 -0
  258. package/dist/scripts/data-transformers/constants/content-labels-part1.js.map +1 -0
  259. package/dist/scripts/data-transformers/constants/content-labels-part2.d.ts +11 -0
  260. package/dist/scripts/data-transformers/constants/content-labels-part2.d.ts.map +1 -0
  261. package/dist/scripts/data-transformers/constants/content-labels-part2.js +900 -0
  262. package/dist/scripts/data-transformers/constants/content-labels-part2.js.map +1 -0
  263. package/dist/scripts/data-transformers/constants/content-labels.d.ts +13 -0
  264. package/dist/scripts/data-transformers/constants/content-labels.d.ts.map +1 -0
  265. package/dist/scripts/data-transformers/constants/content-labels.js +18 -0
  266. package/dist/scripts/data-transformers/constants/content-labels.js.map +1 -0
  267. package/dist/scripts/data-transformers/constants/index.d.ts +15 -0
  268. package/dist/scripts/data-transformers/constants/index.d.ts.map +1 -0
  269. package/dist/scripts/data-transformers/constants/index.js +15 -0
  270. package/dist/scripts/data-transformers/constants/index.js.map +1 -0
  271. package/dist/scripts/data-transformers/constants/locale-map.d.ts +13 -0
  272. package/dist/scripts/data-transformers/constants/locale-map.d.ts.map +1 -0
  273. package/dist/scripts/data-transformers/constants/locale-map.js +17 -0
  274. package/dist/scripts/data-transformers/constants/locale-map.js.map +1 -0
  275. package/dist/scripts/data-transformers/constants.d.ts +14 -0
  276. package/dist/scripts/data-transformers/constants.d.ts.map +1 -0
  277. package/dist/scripts/data-transformers/constants.js +14 -0
  278. package/dist/scripts/data-transformers/constants.js.map +1 -0
  279. package/dist/scripts/data-transformers/content-generators/ai-mindmap-analyzer.d.ts +64 -0
  280. package/dist/scripts/data-transformers/content-generators/ai-mindmap-analyzer.d.ts.map +1 -0
  281. package/dist/scripts/data-transformers/content-generators/ai-mindmap-analyzer.js +805 -0
  282. package/dist/scripts/data-transformers/content-generators/ai-mindmap-analyzer.js.map +1 -0
  283. package/dist/scripts/data-transformers/content-generators/ai-swot-analyzer.d.ts +89 -0
  284. package/dist/scripts/data-transformers/content-generators/ai-swot-analyzer.d.ts.map +1 -0
  285. package/dist/scripts/data-transformers/content-generators/ai-swot-analyzer.js +667 -0
  286. package/dist/scripts/data-transformers/content-generators/ai-swot-analyzer.js.map +1 -0
  287. package/dist/scripts/data-transformers/content-generators/cia-overview-section.d.ts +50 -0
  288. package/dist/scripts/data-transformers/content-generators/cia-overview-section.d.ts.map +1 -0
  289. package/dist/scripts/data-transformers/content-generators/cia-overview-section.js +310 -0
  290. package/dist/scripts/data-transformers/content-generators/cia-overview-section.js.map +1 -0
  291. package/dist/scripts/data-transformers/content-generators/committee.d.ts +12 -0
  292. package/dist/scripts/data-transformers/content-generators/committee.d.ts.map +1 -0
  293. package/dist/scripts/data-transformers/content-generators/committee.js +247 -0
  294. package/dist/scripts/data-transformers/content-generators/committee.js.map +1 -0
  295. package/dist/scripts/data-transformers/content-generators/dashboard-section.d.ts +124 -0
  296. package/dist/scripts/data-transformers/content-generators/dashboard-section.d.ts.map +1 -0
  297. package/dist/scripts/data-transformers/content-generators/dashboard-section.js +564 -0
  298. package/dist/scripts/data-transformers/content-generators/dashboard-section.js.map +1 -0
  299. package/dist/scripts/data-transformers/content-generators/economic-dashboard-section.d.ts +82 -0
  300. package/dist/scripts/data-transformers/content-generators/economic-dashboard-section.d.ts.map +1 -0
  301. package/dist/scripts/data-transformers/content-generators/economic-dashboard-section.js +321 -0
  302. package/dist/scripts/data-transformers/content-generators/economic-dashboard-section.js.map +1 -0
  303. package/dist/scripts/data-transformers/content-generators/generic.d.ts +12 -0
  304. package/dist/scripts/data-transformers/content-generators/generic.d.ts.map +1 -0
  305. package/dist/scripts/data-transformers/content-generators/generic.js +295 -0
  306. package/dist/scripts/data-transformers/content-generators/generic.js.map +1 -0
  307. package/dist/scripts/data-transformers/content-generators/index.d.ts +56 -0
  308. package/dist/scripts/data-transformers/content-generators/index.d.ts.map +1 -0
  309. package/dist/scripts/data-transformers/content-generators/index.js +45 -0
  310. package/dist/scripts/data-transformers/content-generators/index.js.map +1 -0
  311. package/dist/scripts/data-transformers/content-generators/interpellations.d.ts +12 -0
  312. package/dist/scripts/data-transformers/content-generators/interpellations.d.ts.map +1 -0
  313. package/dist/scripts/data-transformers/content-generators/interpellations.js +124 -0
  314. package/dist/scripts/data-transformers/content-generators/interpellations.js.map +1 -0
  315. package/dist/scripts/data-transformers/content-generators/mindmap-section.d.ts +137 -0
  316. package/dist/scripts/data-transformers/content-generators/mindmap-section.d.ts.map +1 -0
  317. package/dist/scripts/data-transformers/content-generators/mindmap-section.js +286 -0
  318. package/dist/scripts/data-transformers/content-generators/mindmap-section.js.map +1 -0
  319. package/dist/scripts/data-transformers/content-generators/month-ahead.d.ts +17 -0
  320. package/dist/scripts/data-transformers/content-generators/month-ahead.d.ts.map +1 -0
  321. package/dist/scripts/data-transformers/content-generators/month-ahead.js +212 -0
  322. package/dist/scripts/data-transformers/content-generators/month-ahead.js.map +1 -0
  323. package/dist/scripts/data-transformers/content-generators/monthly-review.d.ts +17 -0
  324. package/dist/scripts/data-transformers/content-generators/monthly-review.d.ts.map +1 -0
  325. package/dist/scripts/data-transformers/content-generators/monthly-review.js +173 -0
  326. package/dist/scripts/data-transformers/content-generators/monthly-review.js.map +1 -0
  327. package/dist/scripts/data-transformers/content-generators/motions.d.ts +12 -0
  328. package/dist/scripts/data-transformers/content-generators/motions.d.ts.map +1 -0
  329. package/dist/scripts/data-transformers/content-generators/motions.js +158 -0
  330. package/dist/scripts/data-transformers/content-generators/motions.js.map +1 -0
  331. package/dist/scripts/data-transformers/content-generators/newsworthiness.d.ts +52 -0
  332. package/dist/scripts/data-transformers/content-generators/newsworthiness.d.ts.map +1 -0
  333. package/dist/scripts/data-transformers/content-generators/newsworthiness.js +244 -0
  334. package/dist/scripts/data-transformers/content-generators/newsworthiness.js.map +1 -0
  335. package/dist/scripts/data-transformers/content-generators/propositions.d.ts +12 -0
  336. package/dist/scripts/data-transformers/content-generators/propositions.d.ts.map +1 -0
  337. package/dist/scripts/data-transformers/content-generators/propositions.js +263 -0
  338. package/dist/scripts/data-transformers/content-generators/propositions.js.map +1 -0
  339. package/dist/scripts/data-transformers/content-generators/sankey-section.d.ts +92 -0
  340. package/dist/scripts/data-transformers/content-generators/sankey-section.d.ts.map +1 -0
  341. package/dist/scripts/data-transformers/content-generators/sankey-section.js +257 -0
  342. package/dist/scripts/data-transformers/content-generators/sankey-section.js.map +1 -0
  343. package/dist/scripts/data-transformers/content-generators/shared.d.ts +81 -0
  344. package/dist/scripts/data-transformers/content-generators/shared.d.ts.map +1 -0
  345. package/dist/scripts/data-transformers/content-generators/shared.js +913 -0
  346. package/dist/scripts/data-transformers/content-generators/shared.js.map +1 -0
  347. package/dist/scripts/data-transformers/content-generators/stakeholder-swot-section.d.ts +83 -0
  348. package/dist/scripts/data-transformers/content-generators/stakeholder-swot-section.d.ts.map +1 -0
  349. package/dist/scripts/data-transformers/content-generators/stakeholder-swot-section.js +219 -0
  350. package/dist/scripts/data-transformers/content-generators/stakeholder-swot-section.js.map +1 -0
  351. package/dist/scripts/data-transformers/content-generators/swot-section.d.ts +50 -0
  352. package/dist/scripts/data-transformers/content-generators/swot-section.d.ts.map +1 -0
  353. package/dist/scripts/data-transformers/content-generators/swot-section.js +177 -0
  354. package/dist/scripts/data-transformers/content-generators/swot-section.js.map +1 -0
  355. package/dist/scripts/data-transformers/content-generators/week-ahead.d.ts +12 -0
  356. package/dist/scripts/data-transformers/content-generators/week-ahead.d.ts.map +1 -0
  357. package/dist/scripts/data-transformers/content-generators/week-ahead.js +332 -0
  358. package/dist/scripts/data-transformers/content-generators/week-ahead.js.map +1 -0
  359. package/dist/scripts/data-transformers/content-generators.d.ts +15 -0
  360. package/dist/scripts/data-transformers/content-generators.d.ts.map +1 -0
  361. package/dist/scripts/data-transformers/content-generators.js +14 -0
  362. package/dist/scripts/data-transformers/content-generators.js.map +1 -0
  363. package/dist/scripts/data-transformers/document-analysis.d.ts +58 -0
  364. package/dist/scripts/data-transformers/document-analysis.d.ts.map +1 -0
  365. package/dist/scripts/data-transformers/document-analysis.js +396 -0
  366. package/dist/scripts/data-transformers/document-analysis.js.map +1 -0
  367. package/dist/scripts/data-transformers/helpers.d.ts +144 -0
  368. package/dist/scripts/data-transformers/helpers.d.ts.map +1 -0
  369. package/dist/scripts/data-transformers/helpers.js +408 -0
  370. package/dist/scripts/data-transformers/helpers.js.map +1 -0
  371. package/dist/scripts/data-transformers/index.d.ts +45 -0
  372. package/dist/scripts/data-transformers/index.d.ts.map +1 -0
  373. package/dist/scripts/data-transformers/index.js +66 -0
  374. package/dist/scripts/data-transformers/index.js.map +1 -0
  375. package/dist/scripts/data-transformers/metadata.d.ts +42 -0
  376. package/dist/scripts/data-transformers/metadata.d.ts.map +1 -0
  377. package/dist/scripts/data-transformers/metadata.js +385 -0
  378. package/dist/scripts/data-transformers/metadata.js.map +1 -0
  379. package/dist/scripts/data-transformers/policy-analysis.d.ts +105 -0
  380. package/dist/scripts/data-transformers/policy-analysis.d.ts.map +1 -0
  381. package/dist/scripts/data-transformers/policy-analysis.js +686 -0
  382. package/dist/scripts/data-transformers/policy-analysis.js.map +1 -0
  383. package/dist/scripts/data-transformers/risk-analysis.d.ts +104 -0
  384. package/dist/scripts/data-transformers/risk-analysis.d.ts.map +1 -0
  385. package/dist/scripts/data-transformers/risk-analysis.js +279 -0
  386. package/dist/scripts/data-transformers/risk-analysis.js.map +1 -0
  387. package/dist/scripts/data-transformers/types.d.ts +260 -0
  388. package/dist/scripts/data-transformers/types.d.ts.map +1 -0
  389. package/dist/scripts/data-transformers/types.js +11 -0
  390. package/dist/scripts/data-transformers/types.js.map +1 -0
  391. package/dist/scripts/data-transformers.d.ts +23 -0
  392. package/dist/scripts/data-transformers.d.ts.map +1 -0
  393. package/dist/scripts/data-transformers.js +35 -0
  394. package/dist/scripts/data-transformers.js.map +1 -0
  395. package/dist/scripts/deep-inspection/index.d.ts +55 -0
  396. package/dist/scripts/deep-inspection/index.d.ts.map +1 -0
  397. package/dist/scripts/deep-inspection/index.js +66 -0
  398. package/dist/scripts/deep-inspection/index.js.map +1 -0
  399. package/dist/scripts/detect-swedish-leakage.d.ts +69 -0
  400. package/dist/scripts/detect-swedish-leakage.d.ts.map +1 -0
  401. package/dist/scripts/detect-swedish-leakage.js +417 -0
  402. package/dist/scripts/detect-swedish-leakage.js.map +1 -0
  403. package/dist/scripts/editorial-framework.d.ts +121 -0
  404. package/dist/scripts/editorial-framework.d.ts.map +1 -0
  405. package/dist/scripts/editorial-framework.js +364 -0
  406. package/dist/scripts/editorial-framework.js.map +1 -0
  407. package/dist/scripts/editorial-pillars.d.ts +43 -0
  408. package/dist/scripts/editorial-pillars.d.ts.map +1 -0
  409. package/dist/scripts/editorial-pillars.js +215 -0
  410. package/dist/scripts/editorial-pillars.js.map +1 -0
  411. package/dist/scripts/extract-news-metadata.d.ts +12 -0
  412. package/dist/scripts/extract-news-metadata.d.ts.map +1 -0
  413. package/dist/scripts/extract-news-metadata.js +107 -0
  414. package/dist/scripts/extract-news-metadata.js.map +1 -0
  415. package/dist/scripts/extract-vocabulary.d.ts +15 -0
  416. package/dist/scripts/extract-vocabulary.d.ts.map +1 -0
  417. package/dist/scripts/extract-vocabulary.js +255 -0
  418. package/dist/scripts/extract-vocabulary.js.map +1 -0
  419. package/dist/scripts/fix-article-navigation.d.ts +37 -0
  420. package/dist/scripts/fix-article-navigation.d.ts.map +1 -0
  421. package/dist/scripts/fix-article-navigation.js +198 -0
  422. package/dist/scripts/fix-article-navigation.js.map +1 -0
  423. package/dist/scripts/fix-keywords-localization.d.ts +18 -0
  424. package/dist/scripts/fix-keywords-localization.d.ts.map +1 -0
  425. package/dist/scripts/fix-keywords-localization.js +270 -0
  426. package/dist/scripts/fix-keywords-localization.js.map +1 -0
  427. package/dist/scripts/fix-old-articles-branding.d.ts +17 -0
  428. package/dist/scripts/fix-old-articles-branding.d.ts.map +1 -0
  429. package/dist/scripts/fix-old-articles-branding.js +229 -0
  430. package/dist/scripts/fix-old-articles-branding.js.map +1 -0
  431. package/dist/scripts/generate-news-backport.d.ts +16 -0
  432. package/dist/scripts/generate-news-backport.d.ts.map +1 -0
  433. package/dist/scripts/generate-news-backport.js +379 -0
  434. package/dist/scripts/generate-news-backport.js.map +1 -0
  435. package/dist/scripts/generate-news-enhanced/ai-analysis-pipeline.d.ts +124 -0
  436. package/dist/scripts/generate-news-enhanced/ai-analysis-pipeline.d.ts.map +1 -0
  437. package/dist/scripts/generate-news-enhanced/ai-analysis-pipeline.js +529 -0
  438. package/dist/scripts/generate-news-enhanced/ai-analysis-pipeline.js.map +1 -0
  439. package/dist/scripts/generate-news-enhanced/analysis-cache.d.ts +59 -0
  440. package/dist/scripts/generate-news-enhanced/analysis-cache.d.ts.map +1 -0
  441. package/dist/scripts/generate-news-enhanced/analysis-cache.js +116 -0
  442. package/dist/scripts/generate-news-enhanced/analysis-cache.js.map +1 -0
  443. package/dist/scripts/generate-news-enhanced/analysis-labels.d.ts +58 -0
  444. package/dist/scripts/generate-news-enhanced/analysis-labels.d.ts.map +1 -0
  445. package/dist/scripts/generate-news-enhanced/analysis-labels.js +144 -0
  446. package/dist/scripts/generate-news-enhanced/analysis-labels.js.map +1 -0
  447. package/dist/scripts/generate-news-enhanced/config.d.ts +57 -0
  448. package/dist/scripts/generate-news-enhanced/config.d.ts.map +1 -0
  449. package/dist/scripts/generate-news-enhanced/config.js +286 -0
  450. package/dist/scripts/generate-news-enhanced/config.js.map +1 -0
  451. package/dist/scripts/generate-news-enhanced/generators.d.ts +119 -0
  452. package/dist/scripts/generate-news-enhanced/generators.d.ts.map +1 -0
  453. package/dist/scripts/generate-news-enhanced/generators.js +2108 -0
  454. package/dist/scripts/generate-news-enhanced/generators.js.map +1 -0
  455. package/dist/scripts/generate-news-enhanced/helpers.d.ts +123 -0
  456. package/dist/scripts/generate-news-enhanced/helpers.d.ts.map +1 -0
  457. package/dist/scripts/generate-news-enhanced/helpers.js +438 -0
  458. package/dist/scripts/generate-news-enhanced/helpers.js.map +1 -0
  459. package/dist/scripts/generate-news-enhanced/index.d.ts +19 -0
  460. package/dist/scripts/generate-news-enhanced/index.d.ts.map +1 -0
  461. package/dist/scripts/generate-news-enhanced/index.js +221 -0
  462. package/dist/scripts/generate-news-enhanced/index.js.map +1 -0
  463. package/dist/scripts/generate-news-enhanced/swot-analyzer.d.ts +35 -0
  464. package/dist/scripts/generate-news-enhanced/swot-analyzer.d.ts.map +1 -0
  465. package/dist/scripts/generate-news-enhanced/swot-analyzer.js +1179 -0
  466. package/dist/scripts/generate-news-enhanced/swot-analyzer.js.map +1 -0
  467. package/dist/scripts/generate-news-enhanced/types.d.ts +34 -0
  468. package/dist/scripts/generate-news-enhanced/types.d.ts.map +1 -0
  469. package/dist/scripts/generate-news-enhanced/types.js +9 -0
  470. package/dist/scripts/generate-news-enhanced/types.js.map +1 -0
  471. package/dist/scripts/generate-news-enhanced.d.ts +25 -0
  472. package/dist/scripts/generate-news-enhanced.d.ts.map +1 -0
  473. package/dist/scripts/generate-news-enhanced.js +37 -0
  474. package/dist/scripts/generate-news-enhanced.js.map +1 -0
  475. package/dist/scripts/generate-news-indexes/constants.d.ts +20 -0
  476. package/dist/scripts/generate-news-indexes/constants.d.ts.map +1 -0
  477. package/dist/scripts/generate-news-indexes/constants.js +308 -0
  478. package/dist/scripts/generate-news-indexes/constants.js.map +1 -0
  479. package/dist/scripts/generate-news-indexes/helpers.d.ts +73 -0
  480. package/dist/scripts/generate-news-indexes/helpers.d.ts.map +1 -0
  481. package/dist/scripts/generate-news-indexes/helpers.js +352 -0
  482. package/dist/scripts/generate-news-indexes/helpers.js.map +1 -0
  483. package/dist/scripts/generate-news-indexes/index.d.ts +20 -0
  484. package/dist/scripts/generate-news-indexes/index.d.ts.map +1 -0
  485. package/dist/scripts/generate-news-indexes/index.js +75 -0
  486. package/dist/scripts/generate-news-indexes/index.js.map +1 -0
  487. package/dist/scripts/generate-news-indexes/template.d.ts +25 -0
  488. package/dist/scripts/generate-news-indexes/template.d.ts.map +1 -0
  489. package/dist/scripts/generate-news-indexes/template.js +644 -0
  490. package/dist/scripts/generate-news-indexes/template.js.map +1 -0
  491. package/dist/scripts/generate-news-indexes/types.d.ts +96 -0
  492. package/dist/scripts/generate-news-indexes/types.d.ts.map +1 -0
  493. package/dist/scripts/generate-news-indexes/types.js +9 -0
  494. package/dist/scripts/generate-news-indexes/types.js.map +1 -0
  495. package/dist/scripts/generate-news-indexes.d.ts +20 -0
  496. package/dist/scripts/generate-news-indexes.d.ts.map +1 -0
  497. package/dist/scripts/generate-news-indexes.js +19 -0
  498. package/dist/scripts/generate-news-indexes.js.map +1 -0
  499. package/dist/scripts/generate-rss.d.ts +48 -0
  500. package/dist/scripts/generate-rss.d.ts.map +1 -0
  501. package/dist/scripts/generate-rss.js +299 -0
  502. package/dist/scripts/generate-rss.js.map +1 -0
  503. package/dist/scripts/generate-sitemap-html.d.ts +79 -0
  504. package/dist/scripts/generate-sitemap-html.d.ts.map +1 -0
  505. package/dist/scripts/generate-sitemap-html.js +878 -0
  506. package/dist/scripts/generate-sitemap-html.js.map +1 -0
  507. package/dist/scripts/generate-sitemap.d.ts +23 -0
  508. package/dist/scripts/generate-sitemap.d.ts.map +1 -0
  509. package/dist/scripts/generate-sitemap.js +476 -0
  510. package/dist/scripts/generate-sitemap.js.map +1 -0
  511. package/dist/scripts/generate-types-from-cia-schemas.d.ts +176 -0
  512. package/dist/scripts/generate-types-from-cia-schemas.d.ts.map +1 -0
  513. package/dist/scripts/generate-types-from-cia-schemas.js +318 -0
  514. package/dist/scripts/generate-types-from-cia-schemas.js.map +1 -0
  515. package/dist/scripts/government-role-validator.d.ts +65 -0
  516. package/dist/scripts/government-role-validator.d.ts.map +1 -0
  517. package/dist/scripts/government-role-validator.js +217 -0
  518. package/dist/scripts/government-role-validator.js.map +1 -0
  519. package/dist/scripts/html-utils.d.ts +17 -0
  520. package/dist/scripts/html-utils.d.ts.map +1 -0
  521. package/dist/scripts/html-utils.js +29 -0
  522. package/dist/scripts/html-utils.js.map +1 -0
  523. package/dist/scripts/load-cia-stats.d.ts +89 -0
  524. package/dist/scripts/load-cia-stats.d.ts.map +1 -0
  525. package/dist/scripts/load-cia-stats.js +400 -0
  526. package/dist/scripts/load-cia-stats.js.map +1 -0
  527. package/dist/scripts/mcp-client/client.d.ts +73 -0
  528. package/dist/scripts/mcp-client/client.d.ts.map +1 -0
  529. package/dist/scripts/mcp-client/client.js +526 -0
  530. package/dist/scripts/mcp-client/client.js.map +1 -0
  531. package/dist/scripts/mcp-client/document-types.d.ts +23 -0
  532. package/dist/scripts/mcp-client/document-types.d.ts.map +1 -0
  533. package/dist/scripts/mcp-client/document-types.js +62 -0
  534. package/dist/scripts/mcp-client/document-types.js.map +1 -0
  535. package/dist/scripts/mcp-client/index.d.ts +34 -0
  536. package/dist/scripts/mcp-client/index.d.ts.map +1 -0
  537. package/dist/scripts/mcp-client/index.js +67 -0
  538. package/dist/scripts/mcp-client/index.js.map +1 -0
  539. package/dist/scripts/mcp-client/transport.d.ts +32 -0
  540. package/dist/scripts/mcp-client/transport.d.ts.map +1 -0
  541. package/dist/scripts/mcp-client/transport.js +102 -0
  542. package/dist/scripts/mcp-client/transport.js.map +1 -0
  543. package/dist/scripts/mcp-client.d.ts +18 -0
  544. package/dist/scripts/mcp-client.d.ts.map +1 -0
  545. package/dist/scripts/mcp-client.js +18 -0
  546. package/dist/scripts/mcp-client.js.map +1 -0
  547. package/dist/scripts/mcp-query-cli.d.ts +25 -0
  548. package/dist/scripts/mcp-query-cli.d.ts.map +1 -0
  549. package/dist/scripts/mcp-query-cli.js +66 -0
  550. package/dist/scripts/mcp-query-cli.js.map +1 -0
  551. package/dist/scripts/news-types/breaking-news.d.ts +178 -0
  552. package/dist/scripts/news-types/breaking-news.d.ts.map +1 -0
  553. package/dist/scripts/news-types/breaking-news.js +428 -0
  554. package/dist/scripts/news-types/breaking-news.js.map +1 -0
  555. package/dist/scripts/news-types/committee-reports.d.ts +212 -0
  556. package/dist/scripts/news-types/committee-reports.d.ts.map +1 -0
  557. package/dist/scripts/news-types/committee-reports.js +404 -0
  558. package/dist/scripts/news-types/committee-reports.js.map +1 -0
  559. package/dist/scripts/news-types/month-ahead.d.ts +71 -0
  560. package/dist/scripts/news-types/month-ahead.d.ts.map +1 -0
  561. package/dist/scripts/news-types/month-ahead.js +392 -0
  562. package/dist/scripts/news-types/month-ahead.js.map +1 -0
  563. package/dist/scripts/news-types/monthly-review.d.ts +61 -0
  564. package/dist/scripts/news-types/monthly-review.d.ts.map +1 -0
  565. package/dist/scripts/news-types/monthly-review.js +417 -0
  566. package/dist/scripts/news-types/monthly-review.js.map +1 -0
  567. package/dist/scripts/news-types/motions.d.ts +214 -0
  568. package/dist/scripts/news-types/motions.d.ts.map +1 -0
  569. package/dist/scripts/news-types/motions.js +447 -0
  570. package/dist/scripts/news-types/motions.js.map +1 -0
  571. package/dist/scripts/news-types/propositions.d.ts +204 -0
  572. package/dist/scripts/news-types/propositions.d.ts.map +1 -0
  573. package/dist/scripts/news-types/propositions.js +401 -0
  574. package/dist/scripts/news-types/propositions.js.map +1 -0
  575. package/dist/scripts/news-types/week-ahead.d.ts +231 -0
  576. package/dist/scripts/news-types/week-ahead.d.ts.map +1 -0
  577. package/dist/scripts/news-types/week-ahead.js +441 -0
  578. package/dist/scripts/news-types/week-ahead.js.map +1 -0
  579. package/dist/scripts/news-types/weekly-review/analysis.d.ts +47 -0
  580. package/dist/scripts/news-types/weekly-review/analysis.d.ts.map +1 -0
  581. package/dist/scripts/news-types/weekly-review/analysis.js +276 -0
  582. package/dist/scripts/news-types/weekly-review/analysis.js.map +1 -0
  583. package/dist/scripts/news-types/weekly-review/data-loader.d.ts +51 -0
  584. package/dist/scripts/news-types/weekly-review/data-loader.d.ts.map +1 -0
  585. package/dist/scripts/news-types/weekly-review/data-loader.js +298 -0
  586. package/dist/scripts/news-types/weekly-review/data-loader.js.map +1 -0
  587. package/dist/scripts/news-types/weekly-review/generator.d.ts +18 -0
  588. package/dist/scripts/news-types/weekly-review/generator.d.ts.map +1 -0
  589. package/dist/scripts/news-types/weekly-review/generator.js +284 -0
  590. package/dist/scripts/news-types/weekly-review/generator.js.map +1 -0
  591. package/dist/scripts/news-types/weekly-review/index.d.ts +20 -0
  592. package/dist/scripts/news-types/weekly-review/index.d.ts.map +1 -0
  593. package/dist/scripts/news-types/weekly-review/index.js +23 -0
  594. package/dist/scripts/news-types/weekly-review/index.js.map +1 -0
  595. package/dist/scripts/news-types/weekly-review/types.d.ts +72 -0
  596. package/dist/scripts/news-types/weekly-review/types.d.ts.map +1 -0
  597. package/dist/scripts/news-types/weekly-review/types.js +20 -0
  598. package/dist/scripts/news-types/weekly-review/types.js.map +1 -0
  599. package/dist/scripts/news-types/weekly-review/validation.d.ts +10 -0
  600. package/dist/scripts/news-types/weekly-review/validation.d.ts.map +1 -0
  601. package/dist/scripts/news-types/weekly-review/validation.js +95 -0
  602. package/dist/scripts/news-types/weekly-review/validation.js.map +1 -0
  603. package/dist/scripts/news-types/weekly-review.d.ts +15 -0
  604. package/dist/scripts/news-types/weekly-review.d.ts.map +1 -0
  605. package/dist/scripts/news-types/weekly-review.js +14 -0
  606. package/dist/scripts/news-types/weekly-review.js.map +1 -0
  607. package/dist/scripts/party-variants.d.ts +23 -0
  608. package/dist/scripts/party-variants.d.ts.map +1 -0
  609. package/dist/scripts/party-variants.js +50 -0
  610. package/dist/scripts/party-variants.js.map +1 -0
  611. package/dist/scripts/pipeline/index.d.ts +19 -0
  612. package/dist/scripts/pipeline/index.d.ts.map +1 -0
  613. package/dist/scripts/pipeline/index.js +17 -0
  614. package/dist/scripts/pipeline/index.js.map +1 -0
  615. package/dist/scripts/pipeline/orchestrator.d.ts +56 -0
  616. package/dist/scripts/pipeline/orchestrator.d.ts.map +1 -0
  617. package/dist/scripts/pipeline/orchestrator.js +147 -0
  618. package/dist/scripts/pipeline/orchestrator.js.map +1 -0
  619. package/dist/scripts/pipeline/types.d.ts +117 -0
  620. package/dist/scripts/pipeline/types.d.ts.map +1 -0
  621. package/dist/scripts/pipeline/types.js +13 -0
  622. package/dist/scripts/pipeline/types.js.map +1 -0
  623. package/dist/scripts/pipeline/validation.d.ts +66 -0
  624. package/dist/scripts/pipeline/validation.d.ts.map +1 -0
  625. package/dist/scripts/pipeline/validation.js +129 -0
  626. package/dist/scripts/pipeline/validation.js.map +1 -0
  627. package/dist/scripts/populate-analysis-data.d.ts +41 -0
  628. package/dist/scripts/populate-analysis-data.d.ts.map +1 -0
  629. package/dist/scripts/populate-analysis-data.js +255 -0
  630. package/dist/scripts/populate-analysis-data.js.map +1 -0
  631. package/dist/scripts/pre-article-analysis/data-downloader.d.ts +80 -0
  632. package/dist/scripts/pre-article-analysis/data-downloader.d.ts.map +1 -0
  633. package/dist/scripts/pre-article-analysis/data-downloader.js +230 -0
  634. package/dist/scripts/pre-article-analysis/data-downloader.js.map +1 -0
  635. package/dist/scripts/pre-article-analysis/data-persistence.d.ts +141 -0
  636. package/dist/scripts/pre-article-analysis/data-persistence.d.ts.map +1 -0
  637. package/dist/scripts/pre-article-analysis/data-persistence.js +345 -0
  638. package/dist/scripts/pre-article-analysis/data-persistence.js.map +1 -0
  639. package/dist/scripts/pre-article-analysis/markdown-serializer.d.ts +95 -0
  640. package/dist/scripts/pre-article-analysis/markdown-serializer.d.ts.map +1 -0
  641. package/dist/scripts/pre-article-analysis/markdown-serializer.js +648 -0
  642. package/dist/scripts/pre-article-analysis/markdown-serializer.js.map +1 -0
  643. package/dist/scripts/pre-article-analysis/pdf-converter.d.ts +58 -0
  644. package/dist/scripts/pre-article-analysis/pdf-converter.d.ts.map +1 -0
  645. package/dist/scripts/pre-article-analysis/pdf-converter.js +142 -0
  646. package/dist/scripts/pre-article-analysis/pdf-converter.js.map +1 -0
  647. package/dist/scripts/pre-article-analysis.d.ts +41 -0
  648. package/dist/scripts/pre-article-analysis.d.ts.map +1 -0
  649. package/dist/scripts/pre-article-analysis.js +578 -0
  650. package/dist/scripts/pre-article-analysis.js.map +1 -0
  651. package/dist/scripts/scb-client.d.ts +104 -0
  652. package/dist/scripts/scb-client.d.ts.map +1 -0
  653. package/dist/scripts/scb-client.js +286 -0
  654. package/dist/scripts/scb-client.js.map +1 -0
  655. package/dist/scripts/scb-context.d.ts +88 -0
  656. package/dist/scripts/scb-context.d.ts.map +1 -0
  657. package/dist/scripts/scb-context.js +307 -0
  658. package/dist/scripts/scb-context.js.map +1 -0
  659. package/dist/scripts/shared/version.d.ts +9 -0
  660. package/dist/scripts/shared/version.d.ts.map +1 -0
  661. package/dist/scripts/shared/version.js +28 -0
  662. package/dist/scripts/shared/version.js.map +1 -0
  663. package/dist/scripts/statistical-claims-detector.d.ts +119 -0
  664. package/dist/scripts/statistical-claims-detector.d.ts.map +1 -0
  665. package/dist/scripts/statistical-claims-detector.js +391 -0
  666. package/dist/scripts/statistical-claims-detector.js.map +1 -0
  667. package/dist/scripts/sync-cia-schemas.d.ts +52 -0
  668. package/dist/scripts/sync-cia-schemas.d.ts.map +1 -0
  669. package/dist/scripts/sync-cia-schemas.js +195 -0
  670. package/dist/scripts/sync-cia-schemas.js.map +1 -0
  671. package/dist/scripts/translation-dictionary.d.ts +45 -0
  672. package/dist/scripts/translation-dictionary.d.ts.map +1 -0
  673. package/dist/scripts/translation-dictionary.js +3642 -0
  674. package/dist/scripts/translation-dictionary.js.map +1 -0
  675. package/dist/scripts/types/article.d.ts +362 -0
  676. package/dist/scripts/types/article.d.ts.map +1 -0
  677. package/dist/scripts/types/article.js +6 -0
  678. package/dist/scripts/types/article.js.map +1 -0
  679. package/dist/scripts/types/content.d.ts +167 -0
  680. package/dist/scripts/types/content.d.ts.map +1 -0
  681. package/dist/scripts/types/content.js +6 -0
  682. package/dist/scripts/types/content.js.map +1 -0
  683. package/dist/scripts/types/editorial.d.ts +17 -0
  684. package/dist/scripts/types/editorial.d.ts.map +1 -0
  685. package/dist/scripts/types/editorial.js +6 -0
  686. package/dist/scripts/types/editorial.js.map +1 -0
  687. package/dist/scripts/types/language.d.ts +7 -0
  688. package/dist/scripts/types/language.d.ts.map +1 -0
  689. package/dist/scripts/types/language.js +6 -0
  690. package/dist/scripts/types/language.js.map +1 -0
  691. package/dist/scripts/types/mcp.d.ts +117 -0
  692. package/dist/scripts/types/mcp.d.ts.map +1 -0
  693. package/dist/scripts/types/mcp.js +6 -0
  694. package/dist/scripts/types/mcp.js.map +1 -0
  695. package/dist/scripts/types/party.d.ts +9 -0
  696. package/dist/scripts/types/party.d.ts.map +1 -0
  697. package/dist/scripts/types/party.js +6 -0
  698. package/dist/scripts/types/party.js.map +1 -0
  699. package/dist/scripts/types/validation.d.ts +136 -0
  700. package/dist/scripts/types/validation.d.ts.map +1 -0
  701. package/dist/scripts/types/validation.js +6 -0
  702. package/dist/scripts/types/validation.js.map +1 -0
  703. package/dist/scripts/types/workflow.d.ts +78 -0
  704. package/dist/scripts/types/workflow.d.ts.map +1 -0
  705. package/dist/scripts/types/workflow.js +6 -0
  706. package/dist/scripts/types/workflow.js.map +1 -0
  707. package/dist/scripts/update-stats-from-cia.d.ts +44 -0
  708. package/dist/scripts/update-stats-from-cia.d.ts.map +1 -0
  709. package/dist/scripts/update-stats-from-cia.js +310 -0
  710. package/dist/scripts/update-stats-from-cia.js.map +1 -0
  711. package/dist/scripts/validate-against-cia-schemas.d.ts +126 -0
  712. package/dist/scripts/validate-against-cia-schemas.d.ts.map +1 -0
  713. package/dist/scripts/validate-against-cia-schemas.js +299 -0
  714. package/dist/scripts/validate-against-cia-schemas.js.map +1 -0
  715. package/dist/scripts/validate-cross-references.d.ts +49 -0
  716. package/dist/scripts/validate-cross-references.d.ts.map +1 -0
  717. package/dist/scripts/validate-cross-references.js +183 -0
  718. package/dist/scripts/validate-cross-references.js.map +1 -0
  719. package/dist/scripts/validate-file-ownership.d.ts +68 -0
  720. package/dist/scripts/validate-file-ownership.d.ts.map +1 -0
  721. package/dist/scripts/validate-file-ownership.js +135 -0
  722. package/dist/scripts/validate-file-ownership.js.map +1 -0
  723. package/dist/scripts/validate-news-translations.d.ts +27 -0
  724. package/dist/scripts/validate-news-translations.d.ts.map +1 -0
  725. package/dist/scripts/validate-news-translations.js +258 -0
  726. package/dist/scripts/validate-news-translations.js.map +1 -0
  727. package/dist/scripts/validate-translations.d.ts +162 -0
  728. package/dist/scripts/validate-translations.d.ts.map +1 -0
  729. package/dist/scripts/validate-translations.js +378 -0
  730. package/dist/scripts/validate-translations.js.map +1 -0
  731. package/dist/scripts/workflow-state-coordinator.d.ts +354 -0
  732. package/dist/scripts/workflow-state-coordinator.d.ts.map +1 -0
  733. package/dist/scripts/workflow-state-coordinator.js +876 -0
  734. package/dist/scripts/workflow-state-coordinator.js.map +1 -0
  735. package/dist/scripts/world-bank-client.d.ts +122 -0
  736. package/dist/scripts/world-bank-client.d.ts.map +1 -0
  737. package/dist/scripts/world-bank-client.js +192 -0
  738. package/dist/scripts/world-bank-client.js.map +1 -0
  739. package/dist/scripts/world-bank-context.d.ts +88 -0
  740. package/dist/scripts/world-bank-context.d.ts.map +1 -0
  741. package/dist/scripts/world-bank-context.js +331 -0
  742. package/dist/scripts/world-bank-context.js.map +1 -0
  743. package/package.json +32 -7
  744. package/dist/lib/chart-factory.d.ts.map +0 -1
  745. package/dist/lib/chart-factory.js.map +0 -1
  746. package/dist/lib/data-loader.d.ts.map +0 -1
  747. package/dist/lib/data-loader.js.map +0 -1
  748. package/dist/lib/dom-utils.d.ts.map +0 -1
  749. package/dist/lib/dom-utils.js.map +0 -1
  750. package/dist/lib/error-boundary.d.ts.map +0 -1
  751. package/dist/lib/error-boundary.js.map +0 -1
  752. package/dist/lib/fallback-ui.d.ts.map +0 -1
  753. package/dist/lib/fallback-ui.js.map +0 -1
  754. package/dist/lib/index.d.ts.map +0 -1
  755. package/dist/lib/index.js.map +0 -1
  756. package/dist/lib/logger.d.ts.map +0 -1
  757. package/dist/lib/logger.js.map +0 -1
  758. package/dist/lib/theme.d.ts.map +0 -1
  759. package/dist/lib/theme.js.map +0 -1
  760. package/dist/lib/types.d.ts.map +0 -1
  761. package/dist/lib/types.js.map +0 -1
  762. /package/dist/lib/{chart-factory.d.ts → shared/chart-factory.d.ts} +0 -0
  763. /package/dist/lib/{chart-factory.js → shared/chart-factory.js} +0 -0
  764. /package/dist/lib/{data-loader.d.ts → shared/data-loader.d.ts} +0 -0
  765. /package/dist/lib/{data-loader.js → shared/data-loader.js} +0 -0
  766. /package/dist/lib/{dom-utils.d.ts → shared/dom-utils.d.ts} +0 -0
  767. /package/dist/lib/{dom-utils.js → shared/dom-utils.js} +0 -0
  768. /package/dist/lib/{error-boundary.d.ts → shared/error-boundary.d.ts} +0 -0
  769. /package/dist/lib/{error-boundary.js → shared/error-boundary.js} +0 -0
  770. /package/dist/lib/{fallback-ui.d.ts → shared/fallback-ui.d.ts} +0 -0
  771. /package/dist/lib/{fallback-ui.js → shared/fallback-ui.js} +0 -0
  772. /package/dist/lib/{index.d.ts → shared/index.d.ts} +0 -0
  773. /package/dist/lib/{index.js → shared/index.js} +0 -0
  774. /package/dist/lib/{logger.d.ts → shared/logger.d.ts} +0 -0
  775. /package/dist/lib/{logger.js → shared/logger.js} +0 -0
  776. /package/dist/lib/{theme.d.ts → shared/theme.d.ts} +0 -0
  777. /package/dist/lib/{theme.js → shared/theme.js} +0 -0
  778. /package/dist/lib/{types.d.ts → shared/types.d.ts} +0 -0
  779. /package/dist/lib/{types.js → shared/types.js} +0 -0
@@ -0,0 +1,913 @@
1
+ /**
2
+ * @module data-transformers/content-generators/shared
3
+ * @description Shared internal helpers and templates used by all content generators.
4
+ * Contains TITLE_SUFFIX_TEMPLATES, keyword extraction, event/document matching helpers,
5
+ * and the deep analysis section generator (5W framework).
6
+ *
7
+ * @author Hack23 AB
8
+ * @license Apache-2.0
9
+ */
10
+ import { escapeHtml } from '../../html-utils.js';
11
+ import { L, normalizePartyKey } from '../helpers.js';
12
+ import { detectPolicyDomains } from '../policy-analysis.js';
13
+ import { analyzeDocuments as analyzeDocumentsBatch, } from '../../ai-analysis/document-analyzer.js';
14
+ import { analyzeDocuments as analyzeDocumentsPerspectives, } from '../../analysis-framework/index.js';
15
+ export const DOC_TYPE_DISPLAY = {
16
+ prop: {
17
+ singular: {
18
+ en: 'Proposition', sv: 'Proposition', da: 'Proposition', no: 'Proposisjon',
19
+ fi: 'Hallituksen esitys', de: 'Regierungsvorlage', fr: 'Projet de loi', es: 'Proposición',
20
+ nl: 'Wetsvoorstel', ar: 'مقترح قانون', he: 'הצעת חוק', ja: '法案', ko: '정부 제출 법안', zh: '政府法案',
21
+ },
22
+ plural: {
23
+ en: 'Propositions', sv: 'Propositioner', da: 'Propositioner', no: 'Proposisjoner',
24
+ fi: 'Hallituksen esitykset', de: 'Regierungsvorlagen', fr: 'Projets de loi', es: 'Proposiciones',
25
+ nl: 'Wetsvoorstellen', ar: 'مقترحات قوانين', he: 'הצעות חוק', ja: '法案', ko: '정부 제출 법안', zh: '政府法案',
26
+ },
27
+ },
28
+ bet: {
29
+ singular: {
30
+ en: 'Committee Report', sv: 'Betänkande', da: 'Udvalgsbetænkning', no: 'Komitéinnstilling',
31
+ fi: 'Valiokunnan mietintö', de: 'Ausschussbericht', fr: 'Rapport de commission', es: 'Informe de comisión',
32
+ nl: 'Commissieverslag', ar: 'تقرير لجنة', he: 'דוח ועדה', ja: '委員会報告書', ko: '위원회 보고서', zh: '委员会报告',
33
+ },
34
+ plural: {
35
+ en: 'Committee Reports', sv: 'Betänkanden', da: 'Udvalgsbetænkninger', no: 'Komitéinnstillinger',
36
+ fi: 'Valiokunnan mietinnöt', de: 'Ausschussberichte', fr: 'Rapports de commission', es: 'Informes de comisión',
37
+ nl: 'Commissieverslagen', ar: 'تقارير لجان', he: 'דוחות ועדה', ja: '委員会報告書', ko: '위원회 보고서', zh: '委员会报告',
38
+ },
39
+ },
40
+ mot: {
41
+ singular: {
42
+ en: 'Motion', sv: 'Motion', da: 'Forslag', no: 'Forslag',
43
+ fi: 'Aloite', de: 'Antrag', fr: 'Motion', es: 'Moción',
44
+ nl: 'Motie', ar: 'مقترح', he: 'הצעה', ja: '動議', ko: '동의안', zh: '动议',
45
+ },
46
+ plural: {
47
+ en: 'Motions', sv: 'Motioner', da: 'Forslag', no: 'Forslag',
48
+ fi: 'Aloitteet', de: 'Anträge', fr: 'Motions', es: 'Mociones',
49
+ nl: 'Moties', ar: 'مقترحات', he: 'הצעות', ja: '動議', ko: '동의안', zh: '动议',
50
+ },
51
+ },
52
+ skr: {
53
+ singular: {
54
+ en: 'Government Communication', sv: 'Skrivelse', da: 'Regeringsskrivelse', no: 'Regjeringsskriv',
55
+ fi: 'Valtioneuvoston kirjelmä', de: 'Regierungsschreiben', fr: 'Communication du gouvernement', es: 'Comunicación del gobierno',
56
+ nl: 'Regeringsmededeling', ar: 'مذكرة حكومية', he: 'מכתב ממשלתי', ja: '政府通信文書', ko: '정부 통신문', zh: '政府公文',
57
+ },
58
+ plural: {
59
+ en: 'Government Communications', sv: 'Skrivelser', da: 'Regeringsskrivelser', no: 'Regjeringsskriv',
60
+ fi: 'Valtioneuvoston kirjelmät', de: 'Regierungsschreiben', fr: 'Communications du gouvernement', es: 'Comunicaciones del gobierno',
61
+ nl: 'Regeringsmededelingen', ar: 'مذكرات حكومية', he: 'מכתבים ממשלתיים', ja: '政府通信文書', ko: '정부 통신문', zh: '政府公文',
62
+ },
63
+ },
64
+ sfs: {
65
+ singular: {
66
+ en: 'Law/Statute', sv: 'Lag/förordning', da: 'Lov/forordning', no: 'Lov/forordning',
67
+ fi: 'Laki/asetus', de: 'Gesetz/Verordnung', fr: 'Loi/Règlement', es: 'Ley/Reglamento',
68
+ nl: 'Wet/Verordening', ar: 'قانون / لائحة', he: 'חוק/תקנה', ja: '法律/条例', ko: '법률/법규', zh: '法律/法规',
69
+ },
70
+ plural: {
71
+ en: 'Laws/Statutes', sv: 'Lagar/förordningar', da: 'Love/forordninger', no: 'Lover/forordninger',
72
+ fi: 'Lait/asetukset', de: 'Gesetze/Verordnungen', fr: 'Lois/Règlements', es: 'Leyes/Reglamentos',
73
+ nl: 'Wetten/Verordeningen', ar: 'قوانين / لوائح', he: 'חוקים/תקנות', ja: '法律/条例', ko: '법률/법규', zh: '法律/法规',
74
+ },
75
+ },
76
+ fpm: {
77
+ singular: {
78
+ en: 'EU Position Paper', sv: 'Faktapromemoria', da: 'EU-faktanota', no: 'EU-faktanotat',
79
+ fi: 'EU-tietomuistio', de: 'EU-Positionspapier', fr: 'Note de position UE', es: 'Documento de posición de la UE',
80
+ nl: 'EU-positiepaper', ar: 'ورقة موقف للاتحاد الأوروبي', he: 'מסמך עמדה של האיחוד האירופי', ja: 'EUポジションペーパー', ko: 'EU 입장 문서', zh: '欧盟立场文件',
81
+ },
82
+ plural: {
83
+ en: 'EU Position Papers', sv: 'Faktapromemorior', da: 'EU-faktanotaer', no: 'EU-faktanotater',
84
+ fi: 'EU-tietomuistiot', de: 'EU-Positionspapiere', fr: 'Notes de position UE', es: 'Documentos de posición de la UE',
85
+ nl: 'EU-positiepapers', ar: 'أوراق موقف للاتحاد الأوروبي', he: 'מסמכי עמדה של האיחוד האירופי', ja: 'EUポジションペーパー', ko: 'EU 입장 문서', zh: '欧盟立场文件',
86
+ },
87
+ },
88
+ pressm: {
89
+ singular: {
90
+ en: 'Press Release', sv: 'Pressmeddelande', da: 'Pressemeddelelse', no: 'Pressemelding',
91
+ fi: 'Lehdistötiedote', de: 'Pressemitteilung', fr: 'Communiqué de presse', es: 'Comunicado de prensa',
92
+ nl: 'Persbericht', ar: 'بيان صحفي', he: 'הודעה לעיתונות', ja: 'プレスリリース', ko: '보도자료', zh: '新闻稿',
93
+ },
94
+ plural: {
95
+ en: 'Press Releases', sv: 'Pressmeddelanden', da: 'Pressemeddelelser', no: 'Pressemeldinger',
96
+ fi: 'Lehdistötiedotteet', de: 'Pressemitteilungen', fr: 'Communiqués de presse', es: 'Comunicados de prensa',
97
+ nl: 'Persberichten', ar: 'بيانات صحفية', he: 'הודעות לעיתונות', ja: 'プレスリリース', ko: '보도자료', zh: '新闻稿',
98
+ },
99
+ },
100
+ ext: {
101
+ singular: {
102
+ en: 'External Reference', sv: 'Extern referens', da: 'Ekstern reference', no: 'Ekstern referanse',
103
+ fi: 'Ulkoinen viite', de: 'Externe Referenz', fr: 'Référence externe', es: 'Referencia externa',
104
+ nl: 'Externe referentie', ar: 'مرجع خارجي', he: 'הפניה חיצונית', ja: '外部参照', ko: '외부 참조', zh: '外部参考',
105
+ },
106
+ plural: {
107
+ en: 'External References', sv: 'Externa referenser', da: 'Eksterne referencer', no: 'Eksterne referanser',
108
+ fi: 'Ulkoiset viitteet', de: 'Externe Referenzen', fr: 'Références externes', es: 'Referencias externas',
109
+ nl: 'Externe referenties', ar: 'مراجع خارجية', he: 'הפניות חיצוניות', ja: '外部参照', ko: '외부 참조', zh: '外部参考',
110
+ },
111
+ },
112
+ other: {
113
+ singular: {
114
+ en: 'Other Document', sv: 'Övrigt dokument', da: 'Andet dokument', no: 'Annet dokument',
115
+ fi: 'Muu asiakirja', de: 'Sonstiges Dokument', fr: 'Autre document', es: 'Otro documento',
116
+ nl: 'Overig document', ar: 'مستند آخر', he: 'מסמך אחר', ja: 'その他の文書', ko: '기타 문서', zh: '其他文件',
117
+ },
118
+ plural: {
119
+ en: 'Other Documents', sv: 'Övriga dokument', da: 'Andre dokumenter', no: 'Andre dokumenter',
120
+ fi: 'Muut asiakirjat', de: 'Sonstige Dokumente', fr: 'Autres documents', es: 'Otros documentos',
121
+ nl: 'Overige documenten', ar: 'مستندات أخرى', he: 'מסמכים אחרים', ja: 'その他の文書', ko: '기타 문서', zh: '其他文件',
122
+ },
123
+ },
124
+ };
125
+ export function localizeDocType(code, lang, count) {
126
+ const entry = DOC_TYPE_DISPLAY[code];
127
+ if (!entry)
128
+ return code;
129
+ const usePlural = count !== 1;
130
+ const primary = usePlural ? entry.plural : entry.singular;
131
+ const fallback = usePlural ? entry.singular : entry.plural;
132
+ return primary[lang] ?? primary.en ?? fallback[lang] ?? fallback.en ?? code;
133
+ }
134
+ /** Per-language title-suffix templates for inverted-pyramid lede construction. */
135
+ export const TITLE_SUFFIX_TEMPLATES = {
136
+ sv: t => ` — inklusive "${t}"`,
137
+ da: t => ` — herunder "${t}"`,
138
+ no: t => ` — inkludert "${t}"`,
139
+ fi: t => ` — mukaan lukien "${t}"`,
140
+ de: t => ` — darunter "${t}"`,
141
+ fr: t => ` — notamment "${t}"`,
142
+ es: t => ` — incluyendo "${t}"`,
143
+ nl: t => ` — inclusief "${t}"`,
144
+ ar: t => ` — بما فيها "${t}"`,
145
+ he: t => ` — כולל "${t}"`,
146
+ ja: t => `、「${t}」を含む`,
147
+ ko: t => `, "${t}" 포함`,
148
+ zh: t => `,包括"${t}"`,
149
+ };
150
+ /** Extract meaningful keywords from text for cross-reference matching (min 2 chars, captures EU, KU, etc.; splits on whitespace, hyphens, and commas) */
151
+ function extractKeywords(text) {
152
+ return text.toLowerCase().split(/[\s,–-]+/u).filter(w => w.length >= 2);
153
+ }
154
+ /** Find documents related to a calendar event by organ match or keyword overlap (max 3) */
155
+ export function findRelatedDocuments(event, documents) {
156
+ const eventOrgan = event.organ ?? '';
157
+ const keywords = extractKeywords(event.rubrik ?? event.titel ?? event.title ?? '');
158
+ return documents.filter(doc => {
159
+ const docOrgan = doc.organ ?? doc.committee ?? '';
160
+ if (eventOrgan && docOrgan && eventOrgan.toLowerCase() === docOrgan.toLowerCase())
161
+ return true;
162
+ const docText = (doc.titel ?? doc.title ?? '').toLowerCase();
163
+ return keywords.some(kw => docText.includes(kw));
164
+ }).slice(0, 3);
165
+ }
166
+ /** Find written questions related to a calendar event by keyword overlap (max 3) */
167
+ export function findRelatedQuestions(event, questions) {
168
+ const keywords = extractKeywords(event.rubrik ?? event.titel ?? event.title ?? '');
169
+ return questions.filter(q => {
170
+ const qText = (q.titel ?? q.title ?? '').toLowerCase();
171
+ return keywords.some(kw => qText.includes(kw));
172
+ }).slice(0, 3);
173
+ }
174
+ /** Extract targeted minister name from interpellation summary "till MINISTER" header line.
175
+ * Strips trailing topic clauses ("om X", "angående Y", etc.) and punctuation. */
176
+ export function extractMinister(summary) {
177
+ // Use non-newline whitespace ([^\S\n]+) so we don't cross into the next line
178
+ const m = summary.match(/\btill[^\S\n]+([^\n]+)/i);
179
+ if (!m)
180
+ return '';
181
+ const raw = m[1].trim();
182
+ if (!raw)
183
+ return '';
184
+ // Remove common trailing topic clauses and punctuation
185
+ const lowerRaw = raw.toLowerCase();
186
+ const stopPhrases = [' om ', ' angående ', ' rörande ', ' beträffande '];
187
+ let end = raw.length;
188
+ for (const phrase of stopPhrases) {
189
+ const idx = lowerRaw.indexOf(phrase);
190
+ if (idx !== -1 && idx < end)
191
+ end = idx;
192
+ }
193
+ // Cut at terminating punctuation if it comes earlier
194
+ const punctIdx = raw.search(/[?:;.,]/);
195
+ if (punctIdx !== -1 && punctIdx < end)
196
+ end = punctIdx;
197
+ return raw.slice(0, end).trim();
198
+ }
199
+ /**
200
+ * Run the document analysis framework over a set of documents and return
201
+ * both the per-document analysis map and the multi-perspective batch result.
202
+ *
203
+ * Content generators should call this once per article and pass the results
204
+ * into `generateDeepAnalysisSection()` via the `frameworkAnalysis` and
205
+ * `perspectiveAnalysis` options.
206
+ *
207
+ * Results are cached internally by the framework, so repeated calls with
208
+ * the same documents are cheap.
209
+ */
210
+ export function analyzeDocumentsForContent(docs, lang, cia) {
211
+ const frameworkAnalysis = analyzeDocumentsBatch(docs, lang, cia);
212
+ const perspectiveAnalysis = analyzeDocumentsPerspectives(docs, cia, lang);
213
+ return { frameworkAnalysis, perspectiveAnalysis };
214
+ }
215
+ /**
216
+ * Extract unique party names from a set of documents for "Who" analysis.
217
+ */
218
+ function extractKeyActors(docs) {
219
+ const parties = new Map();
220
+ const authorSet = new Set();
221
+ for (const doc of docs) {
222
+ const party = normalizePartyKey(doc.parti);
223
+ if (party && party !== 'other') {
224
+ parties.set(party, (parties.get(party) ?? 0) + 1);
225
+ }
226
+ const author = doc.intressent_namn || doc.author || '';
227
+ if (author && author !== 'Unknown' && author.length > 1) {
228
+ authorSet.add(author);
229
+ }
230
+ }
231
+ return { parties, authors: Array.from(authorSet).slice(0, 8) };
232
+ }
233
+ /**
234
+ * Aggregate policy domains across all documents for "What" analysis.
235
+ */
236
+ function aggregateDomains(docs, lang) {
237
+ const domainCounts = new Map();
238
+ for (const doc of docs) {
239
+ for (const domain of detectPolicyDomains(doc, lang)) {
240
+ domainCounts.set(domain, (domainCounts.get(domain) ?? 0) + 1);
241
+ }
242
+ }
243
+ return domainCounts;
244
+ }
245
+ /**
246
+ * Determine winners and losers based on document patterns and CIA context.
247
+ */
248
+ function analyseWinnersLosers(docs, cia, lang) {
249
+ const parts = [];
250
+ // Count government vs opposition documents
251
+ const govDocs = docs.filter(d => d.doktyp === 'prop' || d.doktyp === 'bet' || d.doktyp === 'skr');
252
+ const oppDocs = docs.filter(d => d.doktyp === 'mot');
253
+ if (govDocs.length > 0 && oppDocs.length > 0) {
254
+ const ratio = govDocs.length / Math.max(1, oppDocs.length);
255
+ if (ratio > 2) {
256
+ parts.push(govAdvantageText(lang, govDocs.length, oppDocs.length));
257
+ }
258
+ else if (ratio < 0.5) {
259
+ parts.push(oppPressureText(lang, oppDocs.length));
260
+ }
261
+ else {
262
+ parts.push(balancedText(lang));
263
+ }
264
+ }
265
+ if (cia) {
266
+ const margin = cia.coalitionStability?.majorityMargin ?? 0;
267
+ const stability = cia.coalitionStability?.stabilityScore ?? 100;
268
+ if (margin <= 3 && stability < 60) {
269
+ parts.push(coalitionRiskText(lang, margin));
270
+ }
271
+ }
272
+ return parts.join(' ') || neutralText(lang);
273
+ }
274
+ function govAdvantageText(lang, gov, opp) {
275
+ const templates = {
276
+ en: `The governing coalition holds the initiative with ${gov} legislative items versus ${opp} opposition motions, suggesting strong agenda control.`,
277
+ sv: `Regeringskoalitionen håller initiativet med ${gov} lagstiftningsärenden mot ${opp} oppositionsyrkanden, vilket tyder på stark agendakontroll.`,
278
+ da: `Regeringskoalitionen har initiativet med ${gov} lovgivningspunkter mod ${opp} oppositionsforslag.`,
279
+ no: `Regjeringskoalisjonen holder initiativet med ${gov} lovforslag mot ${opp} opposisjonsforslag.`,
280
+ fi: `Hallituskoalitio pitää aloitteen ${gov} lainsäädäntöasialla vastaan ${opp} opposition aloitetta.`,
281
+ de: `Die Regierungskoalition hält die Initiative mit ${gov} Gesetzgebungspunkten gegenüber ${opp} Oppositionsanträgen.`,
282
+ fr: `La coalition gouvernementale tient l'initiative avec ${gov} points législatifs contre ${opp} motions de l'opposition.`,
283
+ es: `La coalición gobernante mantiene la iniciativa con ${gov} puntos legislativos frente a ${opp} mociones de la oposición.`,
284
+ nl: `De regeringscoalitie houdt het initiatief met ${gov} wetgevingspunten versus ${opp} oppositiemoties.`,
285
+ ar: `يحتفظ الائتلاف الحاكم بالمبادرة بـ${gov} بنداً تشريعياً مقابل ${opp} اقتراحات معارضة.`,
286
+ he: `הקואליציה שומרת על היוזמה עם ${gov} סעיפי חקיקה מול ${opp} הצעות אופוזיציה.`,
287
+ ja: `与党連合は${gov}の立法項目で主導権を握り、野党の${opp}動議に対して優位に立っています。`,
288
+ ko: `여당 연합은 ${gov}건의 입법 항목으로 주도권을 유지하며, 야당의 ${opp}건 동의에 대해 우위를 보이고 있습니다.`,
289
+ zh: `执政联盟以${gov}项立法议题保持主动权,对比反对党的${opp}项动议。`,
290
+ };
291
+ return templates[lang] ?? templates.en;
292
+ }
293
+ function oppPressureText(lang, opp) {
294
+ const templates = {
295
+ en: `The opposition is applying significant pressure with ${opp} motions, signalling broad dissatisfaction with government policy.`,
296
+ sv: `Oppositionen utövar betydande tryck med ${opp} motioner, vilket signalerar brett missnöje med regeringens politik.`,
297
+ };
298
+ return templates[lang] ?? templates.en;
299
+ }
300
+ function balancedText(lang) {
301
+ const templates = {
302
+ en: 'The balance between government and opposition activity suggests a competitive legislative environment where neither side dominates.',
303
+ sv: 'Balansen mellan regerings- och oppositionsaktivitet tyder på en konkurrensutsatt lagstiftningsmiljö.',
304
+ };
305
+ return templates[lang] ?? templates.en;
306
+ }
307
+ function coalitionRiskText(lang, margin) {
308
+ const templates = {
309
+ en: `With a majority margin of only ${margin} seats, the coalition faces elevated risk of legislative defeats on contested measures.`,
310
+ sv: `Med en majoritetsmarginal på bara ${margin} mandat löper koalitionen förhöjd risk för nederlag vid omstridda omröstningar.`,
311
+ };
312
+ return templates[lang] ?? templates.en;
313
+ }
314
+ function neutralText(lang) {
315
+ const templates = {
316
+ en: 'The political landscape remains fluid, with both government and opposition positioning for advantage.',
317
+ sv: 'Det politiska landskapet förblir rörligt, med både regering och opposition som positionerar sig.',
318
+ };
319
+ return templates[lang] ?? templates.en;
320
+ }
321
+ /**
322
+ * Generate a comprehensive Deep Analysis section following the 5W framework
323
+ * (Who, What, When, Why, Winners/Losers) plus impact, consequences, and critical
324
+ * assessment subsections. This section is designed for highly analytical readers
325
+ * who seek multi-perspective intelligence on parliamentary developments.
326
+ *
327
+ * @returns HTML string for the deep analysis section, or empty string if insufficient data
328
+ */
329
+ export function generateDeepAnalysisSection(opts) {
330
+ const { documents, lang, cia, articleType, whyContext, frameworkAnalysis, perspectiveAnalysis } = opts;
331
+ // Deep analysis requires at least 2 documents for cross-document insights
332
+ // in standard article types. For deep-inspection articles, allow single-
333
+ // document analysis since the whole article is dedicated to in-depth review.
334
+ const minDocs = articleType === 'deep-inspection' ? 1 : 2;
335
+ if (!documents || documents.length < minDocs)
336
+ return '';
337
+ const lbl = (key) => {
338
+ const val = L(lang, key);
339
+ return typeof val === 'string' ? val : key;
340
+ };
341
+ const parts = [];
342
+ parts.push(`\n <section class="deep-analysis" aria-label="${escapeHtml(lbl('deepAnalysis'))}">`);
343
+ parts.push(` <h2>${escapeHtml(lbl('deepAnalysis'))}</h2>`);
344
+ // ── WHO: Key Actors ────────────────────────────────────────────────────────
345
+ const { parties, authors } = extractKeyActors(documents);
346
+ if (parties.size > 0 || authors.length > 0) {
347
+ parts.push(` <h3>${escapeHtml(lbl('deepAnalysisWho'))}</h3>`);
348
+ if (parties.size > 0) {
349
+ const sortedParties = [...parties.entries()].sort((a, b) => b[1] - a[1]);
350
+ const partyList = sortedParties
351
+ .map(([p, count]) => `<strong>${escapeHtml(p)}</strong> (${count})`)
352
+ .join(', ');
353
+ parts.push(` <p>${partyList}</p>`);
354
+ }
355
+ if (authors.length > 0) {
356
+ parts.push(` <p>${authors.map(a => escapeHtml(a)).join(', ')}</p>`);
357
+ }
358
+ }
359
+ // ── WHAT: What Happened ────────────────────────────────────────────────────
360
+ const domains = aggregateDomains(documents, lang);
361
+ if (domains.size > 0) {
362
+ parts.push(` <h3>${escapeHtml(lbl('deepAnalysisWhat'))}</h3>`);
363
+ const sortedDomains = [...domains.entries()].sort((a, b) => b[1] - a[1]);
364
+ const domainItems = sortedDomains.slice(0, 6)
365
+ .map(([d, c]) => `${escapeHtml(d)} (${c})`)
366
+ .join(', ');
367
+ const docTypes = new Map();
368
+ for (const doc of documents) {
369
+ const t = doc.doktyp || doc.documentType || 'other';
370
+ docTypes.set(t, (docTypes.get(t) ?? 0) + 1);
371
+ }
372
+ const typeList = [...docTypes.entries()]
373
+ .sort((a, b) => b[1] - a[1])
374
+ .map(([t, c]) => `${escapeHtml(localizeDocType(t, lang, c))}: ${c}`)
375
+ .join(', ');
376
+ parts.push(` <p>${domainItems}</p>`);
377
+ parts.push(` <p><em>${typeList}</em></p>`);
378
+ }
379
+ // ── WHEN: Timeline & Context ───────────────────────────────────────────────
380
+ parts.push(` <h3>${escapeHtml(lbl('deepAnalysisWhen'))}</h3>`);
381
+ const timelineContext = generateTimelineContext(documents, lang, articleType);
382
+ parts.push(` <p>${timelineContext}</p>`);
383
+ // ── WHY: Why This Matters ──────────────────────────────────────────────────
384
+ parts.push(` <h3>${escapeHtml(lbl('deepAnalysisWhy'))}</h3>`);
385
+ const whyText = generateWhyAnalysis(documents, lang, cia, whyContext);
386
+ parts.push(` <p>${whyText}</p>`);
387
+ // ── WINNERS & LOSERS ───────────────────────────────────────────────────────
388
+ parts.push(` <h3>${escapeHtml(lbl('deepAnalysisWinners'))}</h3>`);
389
+ const winnersText = analyseWinnersLosers(documents, cia, lang);
390
+ parts.push(` <p>${winnersText}</p>`);
391
+ // ── POLITICAL IMPACT ───────────────────────────────────────────────────────
392
+ parts.push(` <h3>${escapeHtml(lbl('deepAnalysisImpact'))}</h3>`);
393
+ const impactText = generateImpactAnalysis(documents, lang, cia);
394
+ parts.push(` <p>${impactText}</p>`);
395
+ // ── ACTIONS & CONSEQUENCES ─────────────────────────────────────────────────
396
+ parts.push(` <h3>${escapeHtml(lbl('deepAnalysisConsequences'))}</h3>`);
397
+ const consequencesText = generateConsequencesAnalysis(documents, lang, articleType);
398
+ parts.push(` <p>${consequencesText}</p>`);
399
+ // ── CRITICAL ASSESSMENT ────────────────────────────────────────────────────
400
+ parts.push(` <h3>${escapeHtml(lbl('deepAnalysisCritical'))}</h3>`);
401
+ const criticalText = generateCriticalAssessment(documents, lang, cia);
402
+ parts.push(` <p>${criticalText}</p>`);
403
+ // ── MULTIPLE PERSPECTIVES ──────────────────────────────────────────────────
404
+ if (parties.size >= 2) {
405
+ parts.push(` <h3>${escapeHtml(lbl('deepAnalysisPerspectives'))}</h3>`);
406
+ const perspectivesText = generatePerspectivesAnalysis(documents, lang, parties);
407
+ parts.push(` <p>${perspectivesText}</p>`);
408
+ }
409
+ // ── FRAMEWORK ANALYSIS SECTIONS ────────────────────────────────────────────
410
+ // When the document analysis framework has been run, inject its richer
411
+ // PESTLE, stakeholder impact, risk, and implementation assessment data.
412
+ if (frameworkAnalysis && frameworkAnalysis.size > 0) {
413
+ const analyses = [...frameworkAnalysis.values()];
414
+ // PESTLE Analysis — aggregate across all analysed documents
415
+ parts.push(` <h3>${escapeHtml(lbl('deepAnalysisPestle'))}</h3>`);
416
+ parts.push(renderAggregatedPestle(analyses, lang));
417
+ // Stakeholder Impact — summarise stakeholder impacts from the framework
418
+ parts.push(` <h3>${escapeHtml(lbl('deepAnalysisStakeholderImpact'))}</h3>`);
419
+ parts.push(renderStakeholderImpactSummary(analyses, lang));
420
+ // Risk Assessment — aggregate risk factors across documents
421
+ const allRisks = analyses.flatMap(a => a.riskAssessment);
422
+ if (allRisks.length > 0) {
423
+ parts.push(` <h3>${escapeHtml(lbl('deepAnalysisRisk'))}</h3>`);
424
+ parts.push(renderRiskAssessment(allRisks, lang));
425
+ }
426
+ // Implementation Assessment — summarise implementation feasibility
427
+ parts.push(` <h3>${escapeHtml(lbl('deepAnalysisImplementation'))}</h3>`);
428
+ parts.push(renderImplementationAssessment(analyses, lang));
429
+ }
430
+ // ── MULTI-PERSPECTIVE INSIGHTS (6 lenses) ────────────────────────────────
431
+ // When the analysis-framework has been run, inject key insights from the
432
+ // government, opposition, citizen, economic, international, and media lenses.
433
+ if (perspectiveAnalysis && perspectiveAnalysis.results.length > 0) {
434
+ const allInsights = perspectiveAnalysis.results.flatMap(r => r.keyInsights);
435
+ if (allInsights.length > 0) {
436
+ const uniqueInsights = [...new Set(allInsights)].slice(0, MAX_PERSPECTIVE_INSIGHTS);
437
+ parts.push(` <div class="perspective-insights">`);
438
+ const insightItems = uniqueInsights.map(i => ` <li>${escapeHtml(i)}</li>`).join('\n');
439
+ parts.push(` <ul>\n${insightItems}\n </ul>`);
440
+ parts.push(` </div>`);
441
+ }
442
+ }
443
+ parts.push(' </section>\n');
444
+ return parts.join('\n');
445
+ }
446
+ // ---------------------------------------------------------------------------
447
+ // Deep Analysis subsection generators
448
+ // ---------------------------------------------------------------------------
449
+ function generateTimelineContext(docs, lang, articleType) {
450
+ const count = docs.length;
451
+ const committees = new Set(docs.map(d => d.organ || d.committee || '').filter(Boolean));
452
+ const prospective = articleType.includes('ahead');
453
+ const retrospective = articleType.includes('review');
454
+ const templates = {
455
+ en: {
456
+ prospective: `${count} items are scheduled across ${committees.size} committee${committees.size !== 1 ? 's' : ''}, creating a dense legislative calendar that demands close monitoring. Each item moves through committee review and chamber debate — timing and sequencing will determine which issues reach a vote.`,
457
+ retrospective: `Over the review period, ${count} parliamentary actions were recorded across ${committees.size} committee${committees.size !== 1 ? 's' : ''}. The volume and distribution of activity reveals the government's priorities and the opposition's strategic responses.`,
458
+ default: `${count} parliamentary items across ${committees.size} active committee${committees.size !== 1 ? 's' : ''} define the current legislative landscape. The pace of activity signals the political urgency driving these proceedings.`,
459
+ },
460
+ sv: {
461
+ prospective: `${count} ärenden är planerade i ${committees.size} utskott, vilket skapar en tät lagstiftningskalender som kräver noggrann bevakning.`,
462
+ retrospective: `Under granskningsperioden registrerades ${count} parlamentariska åtgärder i ${committees.size} utskott. Volymen och fördelningen avslöjar regeringens prioriteringar.`,
463
+ default: `${count} riksdagsärenden i ${committees.size} aktiva utskott definierar det aktuella lagstiftningslandskapet.`,
464
+ },
465
+ };
466
+ const langTemplates = templates[lang] ?? templates.en;
467
+ const key = prospective ? 'prospective' : retrospective ? 'retrospective' : 'default';
468
+ return langTemplates[key] ?? langTemplates.default;
469
+ }
470
+ function generateWhyAnalysis(docs, lang, cia, extraContext) {
471
+ const parts = [];
472
+ // Domain breadth signals policy ambition
473
+ const domains = aggregateDomains(docs, lang);
474
+ const domainCount = domains.size;
475
+ if (domainCount >= 4) {
476
+ parts.push(broadAgendaText(lang, domainCount));
477
+ }
478
+ else if (domainCount >= 2) {
479
+ parts.push(focusedAgendaText(lang, domainCount));
480
+ }
481
+ // Coalition stability context
482
+ if (cia) {
483
+ const stability = cia.coalitionStability?.stabilityScore ?? 100;
484
+ if (stability < 50) {
485
+ parts.push(instabilityText(lang));
486
+ }
487
+ }
488
+ if (extraContext) {
489
+ parts.push(escapeHtml(extraContext));
490
+ }
491
+ if (parts.length === 0) {
492
+ parts.push(defaultWhyText(lang));
493
+ }
494
+ return parts.join(' ');
495
+ }
496
+ function broadAgendaText(lang, n) {
497
+ const templates = {
498
+ en: `With ${n} policy domains in play, this represents a broad legislative push that will shape multiple aspects of Swedish society. The breadth of activity makes this a critical period for understanding the government's strategic direction.`,
499
+ sv: `Med ${n} politikområden i spel representerar detta en bred lagstiftningssatsning som kommer att forma flera aspekter av det svenska samhället.`,
500
+ };
501
+ return templates[lang] ?? templates.en;
502
+ }
503
+ function focusedAgendaText(lang, n) {
504
+ const templates = {
505
+ en: `Activity concentrated in ${n} policy domains suggests targeted legislative priorities rather than broad reform, making each initiative particularly consequential.`,
506
+ sv: `Aktivitet koncentrerad till ${n} politikområden tyder på riktade lagstiftningsprioriteringar snarare än bred reform.`,
507
+ };
508
+ return templates[lang] ?? templates.en;
509
+ }
510
+ function instabilityText(lang) {
511
+ const templates = {
512
+ en: 'The current coalition instability adds significant uncertainty to all legislative proceedings. Any controversial measure could become a confidence test.',
513
+ sv: 'Den nuvarande koalitionsinstabiliteten tillför betydande osäkerhet till alla lagstiftningsförfaranden.',
514
+ };
515
+ return templates[lang] ?? templates.en;
516
+ }
517
+ function defaultWhyText(lang) {
518
+ const templates = {
519
+ en: 'These parliamentary developments carry significance for Swedish governance, reflecting ongoing policy debates and power dynamics within the Riksdag.',
520
+ sv: 'Dessa riksdagshändelser har betydelse för svensk styrning och speglar pågående politiska debatter och maktdynamik.',
521
+ };
522
+ return templates[lang] ?? templates.en;
523
+ }
524
+ function generateImpactAnalysis(docs, lang, cia) {
525
+ const parts = [];
526
+ const propCount = docs.filter(d => d.doktyp === 'prop').length;
527
+ const motCount = docs.filter(d => d.doktyp === 'mot').length;
528
+ const betCount = docs.filter(d => d.doktyp === 'bet').length;
529
+ if (propCount > 0) {
530
+ parts.push(propImpactText(lang, propCount));
531
+ }
532
+ if (betCount > 0) {
533
+ parts.push(betImpactText(lang, betCount));
534
+ }
535
+ if (motCount > 0) {
536
+ parts.push(motImpactText(lang, motCount));
537
+ }
538
+ if (cia) {
539
+ const margin = cia.coalitionStability?.majorityMargin ?? 0;
540
+ if (margin <= 5) {
541
+ parts.push(thinMajorityImpactText(lang, margin));
542
+ }
543
+ }
544
+ return parts.join(' ') || genericImpactText(lang);
545
+ }
546
+ function propImpactText(lang, n) {
547
+ const t = {
548
+ en: `${n} government proposition${n !== 1 ? 's' : ''} will, if adopted, directly alter Swedish law and policy, affecting citizens, businesses, and institutions.`,
549
+ sv: `${n} regeringsproposition${n !== 1 ? 'er' : ''} kommer, om de antas, att direkt ändra svensk lag och politik.`,
550
+ };
551
+ return t[lang] ?? t.en;
552
+ }
553
+ function betImpactText(lang, n) {
554
+ const t = {
555
+ en: `${n} committee report${n !== 1 ? 's' : ''} represent${n === 1 ? 's' : ''} the culmination of legislative review, with recommendations that guide chamber votes.`,
556
+ sv: `${n} betänkande${n !== 1 ? 'n' : ''} representerar kulmen av lagstiftningsöversynen.`,
557
+ };
558
+ return t[lang] ?? t.en;
559
+ }
560
+ function motImpactText(lang, n) {
561
+ const t = {
562
+ en: `${n} opposition motion${n !== 1 ? 's' : ''} challenge${n === 1 ? 's' : ''} the government's position, even though most motions are historically rejected; they signal future electoral battlegrounds.`,
563
+ sv: `${n} oppositionsmotion${n !== 1 ? 'er' : ''} utmanar regeringens position och signalerar framtida valfrågor.`,
564
+ };
565
+ return t[lang] ?? t.en;
566
+ }
567
+ function thinMajorityImpactText(lang, margin) {
568
+ const t = {
569
+ en: `The thin majority margin of ${margin} seat${margin !== 1 ? 's' : ''} means any defection could defeat government measures, amplifying the political stakes.`,
570
+ sv: `Den tunna majoritetsmarginal på ${margin} mandat innebär att varje avhopp kan fälla regeringens förslag.`,
571
+ };
572
+ return t[lang] ?? t.en;
573
+ }
574
+ function genericImpactText(lang) {
575
+ const t = {
576
+ en: 'The legislative activity reflects the ongoing interplay between governing ambition and opposition scrutiny that characterises Swedish parliamentary democracy.',
577
+ sv: 'Lagstiftningsaktiviteten speglar det pågående samspelet mellan regeringsambitioner och oppositionens granskning.',
578
+ };
579
+ return t[lang] ?? t.en;
580
+ }
581
+ function generateConsequencesAnalysis(docs, lang, _articleType) {
582
+ const propCount = docs.filter(d => d.doktyp === 'prop').length;
583
+ const motCount = docs.filter(d => d.doktyp === 'mot').length;
584
+ const parts = [];
585
+ if (propCount > 0) {
586
+ parts.push(propConsequencesText(lang, propCount));
587
+ }
588
+ if (motCount > 0) {
589
+ parts.push(motConsequencesText(lang, motCount));
590
+ }
591
+ if (parts.length === 0) {
592
+ parts.push(genericConsequencesText(lang));
593
+ }
594
+ return parts.join(' ');
595
+ }
596
+ function propConsequencesText(lang, n) {
597
+ const t = {
598
+ en: `If adopted, these ${n} proposition${n !== 1 ? 's' : ''} will trigger implementation across government agencies, requiring regulatory changes, budget allocations, and administrative adaptation. Failure to pass would signal coalition weakness and embolden the opposition.`,
599
+ sv: `Om de antas kommer dessa ${n} proposition${n !== 1 ? 'er' : ''} att utlösa implementering i myndigheter, kräva regeländringar och budgetanpassningar.`,
600
+ };
601
+ return t[lang] ?? t.en;
602
+ }
603
+ function motConsequencesText(lang, n) {
604
+ const t = {
605
+ en: `The ${n} opposition motion${n !== 1 ? 's' : ''}, while likely to be rejected, establish the policy alternatives that opposition parties will champion in the next election cycle. Rejection does not diminish their strategic value as campaign ammunition.`,
606
+ sv: `De ${n} oppositionsmotion${n !== 1 ? 'erna' : 'en'}, även om de troligen avslås, etablerar policyalternativ för nästa valcykel.`,
607
+ };
608
+ return t[lang] ?? t.en;
609
+ }
610
+ function genericConsequencesText(lang) {
611
+ const t = {
612
+ en: 'The outcomes of these proceedings will cascade through committee deliberations, chamber votes, and ultimately into policy implementation — or be shelved, affecting political credibility and future legislative strategy.',
613
+ sv: 'Resultaten av dessa ärenden kommer att kaskadgenomslag genom utskottsbehandling, kammarröstning och slutligen policyimplementering.',
614
+ };
615
+ return t[lang] ?? t.en;
616
+ }
617
+ function generateCriticalAssessment(docs, lang, cia) {
618
+ const parts = [];
619
+ // Check for single-party dominance in motions (potential echo chamber)
620
+ const motionParties = new Map();
621
+ docs.filter(d => d.doktyp === 'mot').forEach(d => {
622
+ const p = normalizePartyKey(d.parti);
623
+ if (p && p !== 'other')
624
+ motionParties.set(p, (motionParties.get(p) ?? 0) + 1);
625
+ });
626
+ const totalMotions = [...motionParties.values()].reduce((a, b) => a + b, 0);
627
+ if (motionParties.size === 1 && totalMotions > 3) {
628
+ parts.push(singlePartyDominanceText(lang));
629
+ }
630
+ // Check for lack of debate data (information gap)
631
+ const withSpeeches = docs.filter(d => d.speeches && d.speeches.length > 0).length;
632
+ if (withSpeeches === 0 && docs.length > 3) {
633
+ parts.push(noDebateDataText(lang));
634
+ }
635
+ // Thin majority risk assessment
636
+ if (cia) {
637
+ const stability = cia.coalitionStability?.stabilityScore ?? 100;
638
+ if (stability < 40) {
639
+ parts.push(criticalStabilityText(lang));
640
+ }
641
+ }
642
+ if (parts.length === 0) {
643
+ parts.push(defaultCriticalText(lang));
644
+ }
645
+ return parts.join(' ');
646
+ }
647
+ function singlePartyDominanceText(lang) {
648
+ const t = {
649
+ en: 'Opposition activity is dominated by a single party, which may indicate either strategic focus or a failure of other parties to engage. Watch for whether this concentration reflects genuine policy leadership or internal opposition dysfunction.',
650
+ sv: 'Oppositionsaktiviteten domineras av ett enda parti, vilket kan tyda på antingen strategiskt fokus eller andra partiers misslyckande att engagera sig.',
651
+ };
652
+ return t[lang] ?? t.en;
653
+ }
654
+ function noDebateDataText(lang) {
655
+ const t = {
656
+ en: 'No chamber debate data is available for these items, limiting our ability to assess the depth of parliamentary deliberation. This information gap should be monitored — the quality of democracy depends on substantive debate, not just procedural passage.',
657
+ sv: 'Inga debattdata från kammaren finns tillgängliga, vilket begränsar vår förmåga att bedöma parlamentariskt deliberationsdjup.',
658
+ };
659
+ return t[lang] ?? t.en;
660
+ }
661
+ function criticalStabilityText(lang) {
662
+ const t = {
663
+ en: 'Coalition stability has deteriorated to critical levels. The risk of a government crisis is non-trivial, and any procedural surprise could trigger a confidence vote. All legislative analysis must be read through this lens of instability.',
664
+ sv: 'Koalitionsstabiliteten har försämrats till kritiska nivåer. Risken för en regeringskris är icke-trivial.',
665
+ };
666
+ return t[lang] ?? t.en;
667
+ }
668
+ function defaultCriticalText(lang) {
669
+ const t = {
670
+ en: 'Standard parliamentary procedures are being followed, but vigilance is warranted. The gap between legislative intent and implementation often reveals the true political winners and losers. Monitor committee amendments and chamber debate quality for the full picture.',
671
+ sv: 'Standardiserade parlamentariska förfaranden följs, men vaksamhet är motiverad. Klyftan mellan lagstiftningsavsikt och implementering avslöjar ofta de verkliga vinnarna och förlorarna.',
672
+ };
673
+ return t[lang] ?? t.en;
674
+ }
675
+ function generatePerspectivesAnalysis(docs, lang, parties) {
676
+ const sortedParties = [...parties.entries()].sort((a, b) => b[1] - a[1]).slice(0, 4);
677
+ const partyAnalyses = [];
678
+ for (const [party, count] of sortedParties) {
679
+ const partyDocs = docs.filter(d => normalizePartyKey(d.parti) === party);
680
+ const partyDomains = aggregateDomains(partyDocs, lang);
681
+ const topDomains = [...partyDomains.entries()]
682
+ .sort((a, b) => b[1] - a[1])
683
+ .slice(0, 2)
684
+ .map(([d]) => d);
685
+ if (topDomains.length > 0) {
686
+ partyAnalyses.push(`<strong>${escapeHtml(party)}</strong> (${count}): ${topDomains.map(d => escapeHtml(d)).join(', ')}`);
687
+ }
688
+ else {
689
+ partyAnalyses.push(`<strong>${escapeHtml(party)}</strong> (${count})`);
690
+ }
691
+ }
692
+ if (partyAnalyses.length === 0)
693
+ return '';
694
+ return partyAnalyses.join(' · ');
695
+ }
696
+ // ---------------------------------------------------------------------------
697
+ // Framework analysis section renderers
698
+ // ---------------------------------------------------------------------------
699
+ /** Max items per PESTLE dimension in aggregated display */
700
+ const MAX_PESTLE_ITEMS = 4;
701
+ /** Max stakeholder impacts shown in the summary list */
702
+ const MAX_STAKEHOLDER_IMPACTS = 7;
703
+ /** Max risk items shown in the risk assessment summary */
704
+ const MAX_RISK_ITEMS = 5;
705
+ /** Max perspective insights shown from 6-lens analysis */
706
+ const MAX_PERSPECTIVE_INSIGHTS = 5;
707
+ /** Max implementation obstacles listed */
708
+ const MAX_IMPLEMENTATION_OBSTACLES = 4;
709
+ /** Max agencies displayed in implementation assessment */
710
+ const MAX_AGENCIES_DISPLAYED = 5;
711
+ const PESTLE_LABELS = {
712
+ en: { political: 'Political', economic: 'Economic', social: 'Social', technological: 'Technological', legal: 'Legal', environmental: 'Environmental' },
713
+ sv: { political: 'Politisk', economic: 'Ekonomisk', social: 'Social', technological: 'Teknologisk', legal: 'Juridisk', environmental: 'Miljö' },
714
+ da: { political: 'Politisk', economic: 'Økonomisk', social: 'Social', technological: 'Teknologisk', legal: 'Juridisk', environmental: 'Miljø' },
715
+ no: { political: 'Politisk', economic: 'Økonomisk', social: 'Sosial', technological: 'Teknologisk', legal: 'Juridisk', environmental: 'Miljø' },
716
+ fi: { political: 'Poliittinen', economic: 'Taloudellinen', social: 'Sosiaalinen', technological: 'Teknologinen', legal: 'Oikeudellinen', environmental: 'Ympäristö' },
717
+ de: { political: 'Politisch', economic: 'Wirtschaftlich', social: 'Sozial', technological: 'Technologisch', legal: 'Rechtlich', environmental: 'Umwelt' },
718
+ fr: { political: 'Politique', economic: 'Économique', social: 'Social', technological: 'Technologique', legal: 'Juridique', environmental: 'Environnemental' },
719
+ es: { political: 'Político', economic: 'Económico', social: 'Social', technological: 'Tecnológico', legal: 'Jurídico', environmental: 'Ambiental' },
720
+ nl: { political: 'Politiek', economic: 'Economisch', social: 'Sociaal', technological: 'Technologisch', legal: 'Juridisch', environmental: 'Milieu' },
721
+ ar: { political: 'سياسي', economic: 'اقتصادي', social: 'اجتماعي', technological: 'تقني', legal: 'قانوني', environmental: 'بيئي' },
722
+ he: { political: 'פוליטי', economic: 'כלכלי', social: 'חברתי', technological: 'טכנולוגי', legal: 'משפטי', environmental: 'סביבתי' },
723
+ ja: { political: '政治', economic: '経済', social: '社会', technological: '技術', legal: '法的', environmental: '環境' },
724
+ ko: { political: '정치', economic: '경제', social: '사회', technological: '기술', legal: '법률', environmental: '환경' },
725
+ zh: { political: '政治', economic: '经济', social: '社会', technological: '技术', legal: '法律', environmental: '环境' },
726
+ };
727
+ const RISK_TYPE_LABELS = {
728
+ en: { political: 'Political', implementation: 'Implementation', 'public-acceptance': 'Public acceptance', legal: 'Legal', financial: 'Financial' },
729
+ sv: { political: 'Politisk', implementation: 'Genomförande', 'public-acceptance': 'Offentlig acceptans', legal: 'Juridisk', financial: 'Finansiell' },
730
+ da: { political: 'Politisk', implementation: 'Implementering', 'public-acceptance': 'Offentlig accept', legal: 'Juridisk', financial: 'Finansiel' },
731
+ no: { political: 'Politisk', implementation: 'Implementering', 'public-acceptance': 'Offentlig aksept', legal: 'Juridisk', financial: 'Finansiell' },
732
+ fi: { political: 'Poliittinen', implementation: 'Toteutus', 'public-acceptance': 'Julkinen hyväksyntä', legal: 'Oikeudellinen', financial: 'Taloudellinen' },
733
+ de: { political: 'Politisch', implementation: 'Umsetzung', 'public-acceptance': 'Öffentliche Akzeptanz', legal: 'Rechtlich', financial: 'Finanziell' },
734
+ fr: { political: 'Politique', implementation: 'Mise en œuvre', 'public-acceptance': 'Acceptation publique', legal: 'Juridique', financial: 'Financier' },
735
+ es: { political: 'Político', implementation: 'Implementación', 'public-acceptance': 'Aceptación pública', legal: 'Jurídico', financial: 'Financiero' },
736
+ nl: { political: 'Politiek', implementation: 'Implementatie', 'public-acceptance': 'Publieke acceptatie', legal: 'Juridisch', financial: 'Financieel' },
737
+ ar: { political: 'سياسي', implementation: 'تنفيذي', 'public-acceptance': 'القبول العام', legal: 'قانوني', financial: 'مالي' },
738
+ he: { political: 'פוליטי', implementation: 'יישום', 'public-acceptance': 'קבלה ציבורית', legal: 'משפטי', financial: 'פיננסי' },
739
+ ja: { political: '政治', implementation: '実装', 'public-acceptance': '世論受容', legal: '法的', financial: '財政' },
740
+ ko: { political: '정치', implementation: '이행', 'public-acceptance': '대중 수용성', legal: '법률', financial: '재정' },
741
+ zh: { political: '政治', implementation: '实施', 'public-acceptance': '公众接受度', legal: '法律', financial: '财政' },
742
+ };
743
+ const LEVEL_LABELS = {
744
+ en: { high: 'High', medium: 'Medium', low: 'Low' },
745
+ sv: { high: 'Hög', medium: 'Medel', low: 'Låg' },
746
+ da: { high: 'Høj', medium: 'Mellem', low: 'Lav' },
747
+ no: { high: 'Høy', medium: 'Middels', low: 'Lav' },
748
+ fi: { high: 'Korkea', medium: 'Keskitaso', low: 'Matala' },
749
+ de: { high: 'Hoch', medium: 'Mittel', low: 'Niedrig' },
750
+ fr: { high: 'Élevé', medium: 'Moyen', low: 'Faible' },
751
+ es: { high: 'Alto', medium: 'Medio', low: 'Bajo' },
752
+ nl: { high: 'Hoog', medium: 'Middel', low: 'Laag' },
753
+ ar: { high: 'مرتفع', medium: 'متوسط', low: 'منخفض' },
754
+ he: { high: 'גבוה', medium: 'בינוני', low: 'נמוך' },
755
+ ja: { high: '高', medium: '中', low: '低' },
756
+ ko: { high: '높음', medium: '보통', low: '낮음' },
757
+ zh: { high: '高', medium: '中', low: '低' },
758
+ };
759
+ const IMPLEMENTATION_LABELS = {
760
+ en: { feasibility: 'Feasibility', obstacles: 'Key obstacles', agencies: 'Agencies involved', noStakeholderData: 'No stakeholder impact data available.', noImplementationData: 'No implementation data available.', burden: 'Burden' },
761
+ sv: { feasibility: 'Genomförbarhet', obstacles: 'Viktiga hinder', agencies: 'Berörda myndigheter', noStakeholderData: 'Ingen data om intressentpåverkan tillgänglig.', noImplementationData: 'Ingen implementeringsdata tillgänglig.', burden: 'Belastning' },
762
+ da: { feasibility: 'Gennemførlighed', obstacles: 'Vigtige hindringer', agencies: 'Involverede myndigheder', noStakeholderData: 'Ingen data om interessentpåvirkning tilgængelig.', noImplementationData: 'Ingen implementeringsdata tilgængelig.', burden: 'Byrde' },
763
+ no: { feasibility: 'Gjennomførbarhet', obstacles: 'Viktige hindringer', agencies: 'Involverte etater', noStakeholderData: 'Ingen data om interessentpåvirkning tilgjengelig.', noImplementationData: 'Ingen implementeringsdata tilgjengelig.', burden: 'Belastning' },
764
+ fi: { feasibility: 'Toteutettavuus', obstacles: 'Keskeiset esteet', agencies: 'Mukana olevat viranomaiset', noStakeholderData: 'Sidosryhmävaikutustietoa ei saatavilla.', noImplementationData: 'Toteutustietoa ei saatavilla.', burden: 'Rasite' },
765
+ de: { feasibility: 'Umsetzbarkeit', obstacles: 'Wesentliche Hindernisse', agencies: 'Beteiligte Behörden', noStakeholderData: 'Keine Daten zu Stakeholder-Auswirkungen verfügbar.', noImplementationData: 'Keine Umsetzungsdaten verfügbar.', burden: 'Belastung' },
766
+ fr: { feasibility: 'Faisabilité', obstacles: 'Obstacles clés', agencies: 'Agences impliquées', noStakeholderData: 'Aucune donnée d’impact des parties prenantes disponible.', noImplementationData: 'Aucune donnée de mise en œuvre disponible.', burden: 'Charge' },
767
+ es: { feasibility: 'Viabilidad', obstacles: 'Obstáculos clave', agencies: 'Organismos implicados', noStakeholderData: 'No hay datos de impacto en partes interesadas.', noImplementationData: 'No hay datos de implementación disponibles.', burden: 'Carga' },
768
+ nl: { feasibility: 'Haalbaarheid', obstacles: 'Belangrijkste obstakels', agencies: 'Betrokken instanties', noStakeholderData: 'Geen gegevens over impact op belanghebbenden beschikbaar.', noImplementationData: 'Geen implementatiegegevens beschikbaar.', burden: 'Last' },
769
+ ar: { feasibility: 'قابلية التنفيذ', obstacles: 'العقبات الرئيسية', agencies: 'الجهات المعنية', noStakeholderData: 'لا تتوفر بيانات تأثير أصحاب المصلحة.', noImplementationData: 'لا تتوفر بيانات تنفيذ.', burden: 'العبء' },
770
+ he: { feasibility: 'ישימות', obstacles: 'חסמים מרכזיים', agencies: 'גורמים מעורבים', noStakeholderData: 'אין נתוני השפעה על בעלי עניין.', noImplementationData: 'אין נתוני יישום.', burden: 'נטל' },
771
+ ja: { feasibility: '実現可能性', obstacles: '主な障害', agencies: '関係機関', noStakeholderData: 'ステークホルダー影響データはありません。', noImplementationData: '実施データはありません。', burden: '負担' },
772
+ ko: { feasibility: '실행 가능성', obstacles: '주요 장애 요인', agencies: '관여 기관', noStakeholderData: '이해관계자 영향 데이터가 없습니다.', noImplementationData: '이행 데이터가 없습니다.', burden: '부담' },
773
+ zh: { feasibility: '可实施性', obstacles: '关键障碍', agencies: '涉及机构', noStakeholderData: '暂无利益相关方影响数据。', noImplementationData: '暂无实施数据。', burden: '负担' },
774
+ };
775
+ function localizeLevel(level, lang) {
776
+ return LEVEL_LABELS[lang]?.[level] ?? LEVEL_LABELS.en[level];
777
+ }
778
+ function localizeRiskType(type, lang) {
779
+ return RISK_TYPE_LABELS[lang]?.[type] ?? RISK_TYPE_LABELS.en[type];
780
+ }
781
+ function localizedImplementationLabels(lang) {
782
+ return IMPLEMENTATION_LABELS[lang] ?? IMPLEMENTATION_LABELS.en;
783
+ }
784
+ /**
785
+ * Aggregate PESTLE dimensions across multiple document analyses into a
786
+ * deduplicated list per dimension and render as an HTML description list.
787
+ */
788
+ function renderAggregatedPestle(analyses, lang) {
789
+ const merged = {
790
+ political: [], economic: [], social: [],
791
+ technological: [], legal: [], environmental: [],
792
+ };
793
+ for (const a of analyses) {
794
+ const p = a.pestleDimensions;
795
+ merged.political.push(...p.political);
796
+ merged.economic.push(...p.economic);
797
+ merged.social.push(...p.social);
798
+ merged.technological.push(...p.technological);
799
+ merged.legal.push(...p.legal);
800
+ merged.environmental.push(...p.environmental);
801
+ }
802
+ // Deduplicate per dimension
803
+ const dedup = (arr) => [...new Set(arr)].slice(0, MAX_PESTLE_ITEMS);
804
+ const labels = PESTLE_LABELS[lang] ?? PESTLE_LABELS.en;
805
+ const dims = [
806
+ [labels.political, dedup(merged.political)],
807
+ [labels.economic, dedup(merged.economic)],
808
+ [labels.social, dedup(merged.social)],
809
+ [labels.technological, dedup(merged.technological)],
810
+ [labels.legal, dedup(merged.legal)],
811
+ [labels.environmental, dedup(merged.environmental)],
812
+ ];
813
+ const items = dims
814
+ .filter(([, items]) => items.length > 0)
815
+ .map(([label, items]) => ` <dt><strong>${escapeHtml(label)}</strong></dt>\n <dd>${items.map(i => escapeHtml(i)).join(' ')}</dd>`)
816
+ .join('\n');
817
+ return ` <dl class="pestle-analysis">\n${items}\n </dl>`;
818
+ }
819
+ /**
820
+ * Render a summary of stakeholder impacts across all analysed documents.
821
+ * Shows up to 7 stakeholder groups with impact direction, confidence, and burden.
822
+ */
823
+ function renderStakeholderImpactSummary(analyses, lang) {
824
+ const labels = localizedImplementationLabels(lang);
825
+ // Collect all stakeholder impacts, deduplicated by stakeholder name
826
+ const impactMap = new Map();
827
+ for (const a of analyses) {
828
+ for (const impact of a.stakeholderImpacts) {
829
+ // Keep the higher-magnitude impact per stakeholder
830
+ const existing = impactMap.get(impact.stakeholder);
831
+ if (!existing || magnitudeRank(impact.directImpact.magnitude) > magnitudeRank(existing.directImpact.magnitude)) {
832
+ impactMap.set(impact.stakeholder, impact);
833
+ }
834
+ }
835
+ }
836
+ const impacts = [...impactMap.values()].slice(0, MAX_STAKEHOLDER_IMPACTS);
837
+ if (impacts.length === 0)
838
+ return ` <p>${escapeHtml(labels.noStakeholderData)}</p>`;
839
+ const rows = impacts.map(i => {
840
+ const directionIcon = i.directImpact.direction === 'positive' ? '↑'
841
+ : i.directImpact.direction === 'negative' ? '↓'
842
+ : i.directImpact.direction === 'mixed' ? '↕'
843
+ : '→';
844
+ const burdenText = localizeLevel(i.implementationBurden, lang);
845
+ return ` <li><strong>${escapeHtml(i.displayName)}</strong>: ${directionIcon} ${escapeHtml(i.directImpact.summary)} (${escapeHtml(i.confidence)}; ${escapeHtml(labels.burden)}: ${escapeHtml(burdenText)})</li>`;
846
+ });
847
+ return ` <ul class="stakeholder-impact-list">\n${rows.join('\n')}\n </ul>`;
848
+ }
849
+ /**
850
+ * Render a risk assessment summary. Groups risks by type and keeps the
851
+ * highest-severity risk per type.
852
+ */
853
+ function renderRiskAssessment(risks, lang) {
854
+ // Deduplicate by type, preferring higher severity
855
+ const byType = new Map();
856
+ for (const r of risks) {
857
+ const key = r.type;
858
+ const existing = byType.get(key);
859
+ if (!existing || severityRank(r.severity) > severityRank(existing.severity)) {
860
+ byType.set(key, r);
861
+ }
862
+ }
863
+ const top = [...byType.values()].slice(0, MAX_RISK_ITEMS);
864
+ const rows = top.map(r => {
865
+ const icon = r.severity === 'high' ? '🔴' : r.severity === 'medium' ? '🟡' : '🟢';
866
+ return ` <li>${icon} <strong>${escapeHtml(localizeRiskType(r.type, lang))}</strong> (${escapeHtml(localizeLevel(r.severity, lang))}): ${escapeHtml(r.description)}</li>`;
867
+ });
868
+ return ` <ul class="risk-assessment-list">\n${rows.join('\n')}\n </ul>`;
869
+ }
870
+ function severityRank(s) {
871
+ return s === 'high' ? 3 : s === 'medium' ? 2 : 1;
872
+ }
873
+ function magnitudeRank(magnitude) {
874
+ return magnitude === 'significant' ? 3 : magnitude === 'moderate' ? 2 : 1;
875
+ }
876
+ /**
877
+ * Render implementation assessment summary from framework analyses.
878
+ */
879
+ function renderImplementationAssessment(analyses, lang) {
880
+ const labels = localizedImplementationLabels(lang);
881
+ const assessments = analyses.map(a => a.implementationAssessment);
882
+ if (assessments.length === 0)
883
+ return ` <p>${escapeHtml(labels.noImplementationData)}</p>`;
884
+ // Aggregate obstacles and agencies across all documents
885
+ const allObstacles = new Set();
886
+ const allAgencies = new Set();
887
+ let highestFeasibility = 'high';
888
+ let selectedAssessment = assessments[0];
889
+ for (const ia of assessments) {
890
+ ia.keyObstacles.forEach(o => allObstacles.add(o));
891
+ ia.agenciesInvolved.forEach(a => allAgencies.add(a));
892
+ if (feasibilityRank(ia.feasibility) < feasibilityRank(highestFeasibility)) {
893
+ highestFeasibility = ia.feasibility;
894
+ selectedAssessment = ia;
895
+ }
896
+ }
897
+ const parts = [];
898
+ const fIcon = highestFeasibility === 'high' ? '🟢' : highestFeasibility === 'medium' ? '🟡' : '🔴';
899
+ const timeline = selectedAssessment.estimatedTimeline;
900
+ parts.push(` <p>${fIcon} <strong>${escapeHtml(labels.feasibility)}:</strong> ${escapeHtml(localizeLevel(highestFeasibility, lang))}. ${escapeHtml(timeline)}</p>`);
901
+ if (allObstacles.size > 0) {
902
+ const obstacleList = [...allObstacles].slice(0, MAX_IMPLEMENTATION_OBSTACLES).map(o => `<li>${escapeHtml(o)}</li>`).join('');
903
+ parts.push(` <p><strong>${escapeHtml(labels.obstacles)}:</strong></p>\n <ul>${obstacleList}</ul>`);
904
+ }
905
+ if (allAgencies.size > 0) {
906
+ parts.push(` <p><strong>${escapeHtml(labels.agencies)}:</strong> ${[...allAgencies].slice(0, MAX_AGENCIES_DISPLAYED).map(a => escapeHtml(a)).join(', ')}</p>`);
907
+ }
908
+ return parts.join('\n');
909
+ }
910
+ function feasibilityRank(f) {
911
+ return f === 'high' ? 3 : f === 'medium' ? 2 : 1;
912
+ }
913
+ //# sourceMappingURL=shared.js.map