arelle-release 2.17.1__py3-none-any.whl → 2.37.71__py3-none-any.whl

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 (893) hide show
  1. arelle/Aspect.py +6 -3
  2. arelle/BetaFeatures.py +3 -0
  3. arelle/Cntlr.py +117 -413
  4. arelle/CntlrCmdLine.py +364 -227
  5. arelle/CntlrQuickBooks.py +4 -2
  6. arelle/CntlrWebMain.py +179 -119
  7. arelle/CntlrWinMain.py +342 -124
  8. arelle/DialogAbout.py +1 -1
  9. arelle/DialogArcroleGroup.py +1 -1
  10. arelle/DialogFind.py +1 -1
  11. arelle/DialogFormulaParameters.py +2 -2
  12. arelle/DialogLanguage.py +45 -36
  13. arelle/DialogNewFactItem.py +1 -1
  14. arelle/DialogOpenArchive.py +30 -34
  15. arelle/DialogPackageManager.py +11 -8
  16. arelle/DialogPluginManager.py +43 -89
  17. arelle/DialogRssWatch.py +2 -2
  18. arelle/DialogURL.py +1 -1
  19. arelle/DialogUserPassword.py +1 -1
  20. arelle/DisclosureSystem.py +69 -1
  21. arelle/ErrorManager.py +321 -0
  22. arelle/FileSource.py +201 -99
  23. arelle/FunctionFn.py +44 -5
  24. arelle/FunctionIxt.py +16 -13
  25. arelle/FunctionUtil.py +1 -1
  26. arelle/FunctionXfi.py +68 -24
  27. arelle/FunctionXs.py +1 -1
  28. arelle/HtmlUtil.py +5 -4
  29. arelle/LeiUtil.py +63 -43
  30. arelle/LinkbaseType.py +94 -0
  31. arelle/LocalViewer.py +8 -2
  32. arelle/Locale.py +239 -79
  33. arelle/ModelDocument.py +180 -48
  34. arelle/ModelDtsObject.py +32 -27
  35. arelle/ModelFormulaObject.py +14 -6
  36. arelle/ModelInstanceObject.py +43 -14
  37. arelle/ModelManager.py +6 -1
  38. arelle/ModelObject.py +12 -8
  39. arelle/ModelObjectFactory.py +18 -2
  40. arelle/ModelRelationshipSet.py +46 -3
  41. arelle/ModelRenderingObject.py +899 -951
  42. arelle/ModelRssItem.py +2 -4
  43. arelle/ModelTestcaseObject.py +41 -4
  44. arelle/ModelValue.py +42 -14
  45. arelle/ModelVersReport.py +1 -1
  46. arelle/ModelXbrl.py +133 -273
  47. arelle/PackageManager.py +202 -176
  48. arelle/PluginManager.py +551 -239
  49. arelle/PluginUtils.py +54 -0
  50. arelle/PrototypeInstanceObject.py +53 -12
  51. arelle/PythonUtil.py +166 -25
  52. arelle/RuntimeOptions.py +32 -18
  53. arelle/SocketUtils.py +3 -0
  54. arelle/SystemInfo.py +1 -1
  55. arelle/TkTableWrapper.py +33 -5
  56. arelle/UITkTable.py +27 -21
  57. arelle/Updater.py +7 -3
  58. arelle/UrlUtil.py +6 -2
  59. arelle/Validate.py +596 -402
  60. arelle/ValidateDuplicateFacts.py +584 -0
  61. arelle/ValidateFileSource.py +38 -0
  62. arelle/ValidateFilingText.py +46 -29
  63. arelle/ValidateInfoset.py +104 -32
  64. arelle/ValidateUtr.py +31 -4
  65. arelle/ValidateXbrl.py +144 -120
  66. arelle/ValidateXbrlCalcs.py +51 -66
  67. arelle/ValidateXbrlDTS.py +98 -29
  68. arelle/Version.py +2 -7
  69. arelle/ViewFile.py +2 -0
  70. arelle/ViewFileDTS.py +7 -2
  71. arelle/ViewFileFactList.py +1 -1
  72. arelle/ViewFileFactTable.py +4 -4
  73. arelle/ViewFileRelationshipSet.py +36 -19
  74. arelle/ViewFileRenderedGrid.py +164 -753
  75. arelle/ViewFileRenderedLayout.py +174 -0
  76. arelle/ViewFileRenderedStructure.py +108 -0
  77. arelle/ViewWinDTS.py +4 -1
  78. arelle/ViewWinFactList.py +1 -1
  79. arelle/ViewWinFactTable.py +1 -1
  80. arelle/ViewWinRelationshipSet.py +14 -8
  81. arelle/ViewWinRenderedGrid.py +397 -287
  82. arelle/ViewWinRssFeed.py +4 -0
  83. arelle/ViewWinTree.py +15 -9
  84. arelle/ViewWinXml.py +1 -1
  85. arelle/WebCache.py +510 -272
  86. arelle/XbrlConst.py +202 -196
  87. arelle/XbrlUtil.py +2 -1
  88. arelle/XhtmlValidate.py +9 -23
  89. arelle/XmlUtil.py +24 -19
  90. arelle/XmlValidate.py +95 -67
  91. arelle/XmlValidateParticles.py +4 -4
  92. arelle/_version.py +33 -3
  93. arelle/api/Session.py +183 -0
  94. arelle/config/creationSoftwareNames.json +24 -10
  95. arelle/config/disclosuresystems.xml +1 -1
  96. arelle/config/disclosuresystems.xsd +3 -0
  97. arelle/config/sbr-text-formatting.xsd +737 -0
  98. arelle/conformance/CSVTestcaseLoader.py +102 -0
  99. arelle/formula/FactAspectsCache.py +10 -4
  100. arelle/formula/ValidateFormula.py +82 -194
  101. arelle/formula/XPathContext.py +42 -28
  102. arelle/formula/XPathParser.py +15 -9
  103. arelle/locale/ar_EG/LC_MESSAGES/ar_EG.po +3 -4
  104. arelle/locale/messages.pot +1 -2
  105. arelle/locale/ru/LC_MESSAGES/ru.po +2 -2
  106. arelle/logging/formatters/LogFormatter.py +47 -0
  107. arelle/logging/handlers/LogHandlerWithXml.py +94 -0
  108. arelle/logging/handlers/LogToBufferHandler.py +20 -0
  109. arelle/logging/handlers/LogToPrintHandler.py +41 -0
  110. arelle/logging/handlers/LogToXmlHandler.py +244 -0
  111. arelle/logging/handlers/StructuredMessageLogHandler.py +74 -0
  112. arelle/model/CommentBase.py +3 -0
  113. arelle/model/ElementBase.py +3 -0
  114. arelle/model/PIBase.py +3 -0
  115. arelle/model/__init__.py +3 -0
  116. arelle/oim/Load.py +2869 -0
  117. arelle/oim/Validate.py +155 -0
  118. arelle/oim/xml/Save.py +21 -0
  119. arelle/packages/PackageConst.py +7 -0
  120. arelle/packages/PackageType.py +13 -0
  121. arelle/packages/PackageUtils.py +22 -0
  122. arelle/packages/PackageValidation.py +200 -0
  123. arelle/packages/report/DetectReportPackage.py +13 -0
  124. arelle/packages/report/ReportPackage.py +265 -0
  125. arelle/packages/report/ReportPackageConst.py +79 -0
  126. arelle/packages/report/ReportPackageValidator.py +207 -0
  127. arelle/plugin/EdgarRendererAllReports.py +12 -12
  128. arelle/plugin/OimTaxonomy/ModelValueMore.py +15 -0
  129. arelle/plugin/OimTaxonomy/ValidateDTS.py +484 -0
  130. arelle/plugin/OimTaxonomy/ViewXbrlTxmyObj.py +239 -0
  131. arelle/plugin/OimTaxonomy/XbrlAbstract.py +16 -0
  132. arelle/plugin/OimTaxonomy/XbrlConcept.py +68 -0
  133. arelle/plugin/OimTaxonomy/XbrlConst.py +261 -0
  134. arelle/plugin/OimTaxonomy/XbrlCube.py +91 -0
  135. arelle/plugin/OimTaxonomy/XbrlDimension.py +38 -0
  136. arelle/plugin/OimTaxonomy/XbrlDts.py +152 -0
  137. arelle/plugin/OimTaxonomy/XbrlEntity.py +16 -0
  138. arelle/plugin/OimTaxonomy/XbrlGroup.py +22 -0
  139. arelle/plugin/OimTaxonomy/XbrlImportedTaxonomy.py +22 -0
  140. arelle/plugin/OimTaxonomy/XbrlLabel.py +31 -0
  141. arelle/plugin/OimTaxonomy/XbrlNetwork.py +100 -0
  142. arelle/plugin/OimTaxonomy/XbrlProperty.py +28 -0
  143. arelle/plugin/OimTaxonomy/XbrlReference.py +33 -0
  144. arelle/plugin/OimTaxonomy/XbrlReport.py +24 -0
  145. arelle/plugin/OimTaxonomy/XbrlTableTemplate.py +35 -0
  146. arelle/plugin/OimTaxonomy/XbrlTaxonomy.py +93 -0
  147. arelle/plugin/OimTaxonomy/XbrlTaxonomyObject.py +154 -0
  148. arelle/plugin/OimTaxonomy/XbrlTransform.py +17 -0
  149. arelle/plugin/OimTaxonomy/XbrlTypes.py +23 -0
  150. arelle/plugin/OimTaxonomy/XbrlUnit.py +17 -0
  151. arelle/plugin/OimTaxonomy/__init__.py +1037 -0
  152. arelle/plugin/OimTaxonomy/resources/iso4217.json +4479 -0
  153. arelle/plugin/OimTaxonomy/resources/oim-taxonomy-schema.json +935 -0
  154. arelle/plugin/OimTaxonomy/resources/ref.json +333 -0
  155. arelle/plugin/OimTaxonomy/resources/transform-types.json +2481 -0
  156. arelle/plugin/OimTaxonomy/resources/types.json +727 -0
  157. arelle/plugin/OimTaxonomy/resources/utr.json +3046 -0
  158. arelle/plugin/OimTaxonomy/resources/xbrlSpec.json +1082 -0
  159. arelle/plugin/formulaLoader.py +3 -3
  160. arelle/plugin/formulaSaver.py +4 -4
  161. arelle/plugin/inlineXbrlDocumentSet.py +331 -102
  162. arelle/plugin/internet/proxyNTLM/HTTPNtlmAuthHandler.py +1 -1
  163. arelle/plugin/loadFromExcel.py +13 -10
  164. arelle/plugin/loadFromOIM.py +16 -3096
  165. arelle/plugin/logging/saveMessages.py +1 -1
  166. arelle/plugin/saveHtmlEBAtables.py +293 -213
  167. arelle/plugin/saveLoadableOIM.py +652 -361
  168. arelle/plugin/saveOIMTaxonomy.py +311 -0
  169. arelle/plugin/streamingExtensions.py +1 -1
  170. arelle/plugin/systemInfo.py +46 -0
  171. arelle/plugin/transforms/tester.py +4 -4
  172. arelle/plugin/validate/CIPC/Const.py +18 -0
  173. arelle/plugin/validate/CIPC/__init__.py +34 -13
  174. arelle/plugin/validate/DBA/DisclosureSystems.py +12 -0
  175. arelle/plugin/validate/DBA/PluginValidationDataExtension.py +165 -0
  176. arelle/plugin/validate/DBA/ValidationPluginExtension.py +545 -0
  177. arelle/plugin/validate/DBA/__init__.py +49 -0
  178. arelle/plugin/validate/DBA/resources/config.xml +21 -0
  179. arelle/plugin/validate/DBA/rules/__init__.py +323 -0
  180. arelle/plugin/validate/DBA/rules/fr.py +1377 -0
  181. arelle/plugin/validate/DBA/rules/tc.py +45 -0
  182. arelle/plugin/validate/DBA/rules/th.py +172 -0
  183. arelle/plugin/validate/DBA/rules/tm.py +351 -0
  184. arelle/plugin/validate/DBA/rules/tr.py +373 -0
  185. arelle/plugin/validate/EBA/__init__.py +11 -12
  186. arelle/plugin/validate/EDINET/Constants.py +208 -0
  187. arelle/plugin/validate/EDINET/ContextRequirement.py +58 -0
  188. arelle/plugin/validate/EDINET/ControllerPluginData.py +298 -0
  189. arelle/plugin/validate/EDINET/CoverItemRequirements.py +42 -0
  190. arelle/plugin/validate/EDINET/DeiRequirements.py +118 -0
  191. arelle/plugin/validate/EDINET/DisclosureSystems.py +1 -0
  192. arelle/plugin/validate/EDINET/FilingFormat.py +275 -0
  193. arelle/plugin/validate/EDINET/FormType.py +134 -0
  194. arelle/plugin/validate/EDINET/ManifestInstance.py +236 -0
  195. arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +640 -0
  196. arelle/plugin/validate/EDINET/ReportFolderType.py +162 -0
  197. arelle/plugin/validate/EDINET/Statement.py +139 -0
  198. arelle/plugin/validate/EDINET/TableOfContentsBuilder.py +493 -0
  199. arelle/plugin/validate/EDINET/UploadContents.py +48 -0
  200. arelle/plugin/validate/EDINET/ValidationPluginExtension.py +64 -0
  201. arelle/plugin/validate/EDINET/__init__.py +109 -0
  202. arelle/plugin/validate/EDINET/resources/config.xml +22 -0
  203. arelle/plugin/validate/EDINET/resources/cover-item-requirements.json +793 -0
  204. arelle/plugin/validate/EDINET/resources/dei-requirements.csv +27 -0
  205. arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml +62 -0
  206. arelle/plugin/validate/EDINET/rules/contexts.py +547 -0
  207. arelle/plugin/validate/EDINET/rules/edinet.py +1991 -0
  208. arelle/plugin/validate/EDINET/rules/frta.py +301 -0
  209. arelle/plugin/validate/EDINET/rules/gfm.py +2394 -0
  210. arelle/plugin/validate/EDINET/rules/manifests.py +88 -0
  211. arelle/plugin/validate/EDINET/rules/upload.py +1370 -0
  212. arelle/plugin/validate/ESEF/Const.py +16 -75
  213. arelle/plugin/validate/ESEF/Dimensions.py +2 -2
  214. arelle/plugin/validate/ESEF/ESEF_2021/DTS.py +6 -1
  215. arelle/plugin/validate/ESEF/ESEF_2021/Image.py +7 -4
  216. arelle/plugin/validate/ESEF/ESEF_2021/ValidateXbrlFinally.py +80 -57
  217. arelle/plugin/validate/ESEF/ESEF_Current/DTS.py +60 -22
  218. arelle/plugin/validate/ESEF/ESEF_Current/ValidateXbrlFinally.py +272 -133
  219. arelle/plugin/validate/ESEF/Util.py +5 -19
  220. arelle/plugin/validate/ESEF/__init__.py +61 -46
  221. arelle/plugin/validate/ESEF/resources/authority-validations.json +120 -10
  222. arelle/plugin/validate/ESEF/resources/config.xml +44 -3
  223. arelle/plugin/validate/FERC/__init__.py +31 -18
  224. arelle/plugin/validate/FERC/config.xml +18 -18
  225. arelle/plugin/validate/NL/DisclosureSystems.py +19 -3
  226. arelle/plugin/validate/NL/PluginValidationDataExtension.py +710 -7
  227. arelle/plugin/validate/NL/ValidationPluginExtension.py +117 -12
  228. arelle/plugin/validate/NL/__init__.py +21 -10
  229. arelle/plugin/validate/NL/resources/config.xml +27 -6
  230. arelle/plugin/validate/NL/rules/br_kvk.py +81 -21
  231. arelle/plugin/validate/NL/rules/fg_nl.py +292 -0
  232. arelle/plugin/validate/NL/rules/fr_kvk.py +60 -7
  233. arelle/plugin/validate/NL/rules/fr_nl.py +705 -24
  234. arelle/plugin/validate/NL/rules/nl_kvk.py +2182 -0
  235. arelle/plugin/validate/ROS/DisclosureSystems.py +1 -0
  236. arelle/plugin/validate/ROS/PluginValidationDataExtension.py +109 -0
  237. arelle/plugin/validate/ROS/ValidationPluginExtension.py +27 -0
  238. arelle/plugin/validate/ROS/__init__.py +28 -341
  239. arelle/plugin/validate/ROS/resources/config.xml +20 -0
  240. arelle/plugin/validate/ROS/rules/__init__.py +56 -0
  241. arelle/plugin/validate/ROS/rules/ros.py +393 -0
  242. arelle/plugin/validate/UK/ValidateUK.py +1372 -0
  243. arelle/plugin/validate/{HMRC → UK}/__init__.py +195 -189
  244. arelle/plugin/validate/{HMRC → UK}/config.xml +1 -1
  245. arelle/plugin/xbrlDB/SqlDb.py +1 -1
  246. arelle/plugin/xbrlDB/XbrlOpenSqlDB.py +5 -5
  247. arelle/plugin/xbrlDB/XbrlPublicPostgresDB.py +1 -1
  248. arelle/plugin/xbrlDB/XbrlSemanticJsonDB.py +1 -1
  249. arelle/plugin/xbrlDB/XbrlSemanticRdfDB.py +1 -1
  250. arelle/plugin/xbrlDB/__init__.py +4 -1
  251. arelle/{RenderingEvaluator.py → rendering/RenderingEvaluator.py} +120 -99
  252. arelle/rendering/RenderingLayout.py +476 -0
  253. arelle/rendering/RenderingResolution.py +814 -0
  254. arelle/resources/cache/http/www.eurofiling.info/eu/fr/xbrl/ext/filing-indicators.xsd +20 -0
  255. arelle/resources/cache/http/www.w3.org/2001/03/xml.xsd +117 -0
  256. arelle/resources/cache/http/www.w3.org/2001/XMLSchema.xsd +2534 -0
  257. arelle/resources/cache/http/www.w3.org/2001/xml.xsd +287 -0
  258. arelle/resources/cache/http/www.xbrl.org/2003/xbrl-instance-2003-12-31.xsd +779 -0
  259. arelle/resources/cache/http/www.xbrl.org/2003/xbrl-linkbase-2003-12-31.xsd +486 -0
  260. arelle/resources/cache/http/www.xbrl.org/2003/xl-2003-12-31.xsd +251 -0
  261. arelle/resources/cache/http/www.xbrl.org/2003/xlink-2003-12-31.xsd +121 -0
  262. arelle/resources/cache/http/www.xbrl.org/2004/ref-2004-08-10.xsd +129 -0
  263. arelle/resources/cache/http/www.xbrl.org/2005/xbrldt-2005.xsd +53 -0
  264. arelle/resources/cache/http/www.xbrl.org/2006/ref-2006-02-27.xsd +120 -0
  265. arelle/resources/cache/http/www.xbrl.org/2006/xbrldi-2006.xsd +41 -0
  266. arelle/resources/cache/http/www.xbrl.org/2008/boolean-filter.xsd +51 -0
  267. arelle/resources/cache/http/www.xbrl.org/2008/concept-filter.xsd +127 -0
  268. arelle/resources/cache/http/www.xbrl.org/2008/conformance.xsd +116 -0
  269. arelle/resources/cache/http/www.xbrl.org/2008/conformanceFunction.xsd +51 -0
  270. arelle/resources/cache/http/www.xbrl.org/2008/consistency-assertion.xsd +66 -0
  271. arelle/resources/cache/http/www.xbrl.org/2008/dimension-filter.xsd +86 -0
  272. arelle/resources/cache/http/www.xbrl.org/2008/entity-filter.xsd +92 -0
  273. arelle/resources/cache/http/www.xbrl.org/2008/existence-assertion.xsd +44 -0
  274. arelle/resources/cache/http/www.xbrl.org/2008/formula.xsd +261 -0
  275. arelle/resources/cache/http/www.xbrl.org/2008/function.xsd +90 -0
  276. arelle/resources/cache/http/www.xbrl.org/2008/general-filter.xsd +38 -0
  277. arelle/resources/cache/http/www.xbrl.org/2008/generic-label.xsd +80 -0
  278. arelle/resources/cache/http/www.xbrl.org/2008/generic-link.xsd +81 -0
  279. arelle/resources/cache/http/www.xbrl.org/2008/generic-reference.xsd +63 -0
  280. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xbrl-instance-2003-12-31-ixmod.xsd +788 -0
  281. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xbrl-linkbase-2003-12-31-ixmod.xsd +488 -0
  282. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xl-2003-12-31.xsd +248 -0
  283. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xbrl/xlink-2003-12-31.xsd +117 -0
  284. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xframes-1.xsd +166 -0
  285. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-applet-1.xsd +66 -0
  286. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-attribs-1.xsd +72 -0
  287. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-base-1.xsd +36 -0
  288. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic-form-1.xsd +195 -0
  289. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic-table-1.xsd +169 -0
  290. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10-model-1.xsd +376 -0
  291. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10-module-redefines-1.xsd +61 -0
  292. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10-modules-1.xsd +259 -0
  293. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-basic10.xsd +98 -0
  294. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-bdo-1.xsd +78 -0
  295. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-blkphras-1.xsd +161 -0
  296. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-blkpres-1.xsd +37 -0
  297. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-blkstruct-1.xsd +49 -0
  298. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-charent-1.xsd +38 -0
  299. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-copyright-1.xsd +29 -0
  300. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-csismap-1.xsd +96 -0
  301. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-datatypes-1.xsd +128 -0
  302. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-edit-1.xsd +39 -0
  303. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-events-1.xsd +130 -0
  304. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-form-1.xsd +326 -0
  305. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-frames-1.xsd +113 -0
  306. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-framework-1.xsd +66 -0
  307. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-hypertext-1.xsd +47 -0
  308. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-iframe-1.xsd +68 -0
  309. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-image-1.xsd +45 -0
  310. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlphras-1.xsd +163 -0
  311. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlpres-1.xsd +39 -0
  312. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlstruct-1.xsd +50 -0
  313. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-inlstyle-1.xsd +27 -0
  314. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-legacy-1.xsd +97 -0
  315. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-link-1.xsd +45 -0
  316. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-list-1.xsd +99 -0
  317. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-meta-1.xsd +42 -0
  318. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-misc-1.xsd +441 -0
  319. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-nameident-1.xsd +63 -0
  320. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-notations-1.xsd +69 -0
  321. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-object-1.xsd +76 -0
  322. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-param-1.xsd +51 -0
  323. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-pres-1.xsd +51 -0
  324. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-ruby-1.xsd +171 -0
  325. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-ruby-basic-1.xsd +89 -0
  326. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-script-1.xsd +70 -0
  327. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-ssismap-1.xsd +43 -0
  328. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-struct-1.xsd +112 -0
  329. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-style-1.xsd +52 -0
  330. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-table-1.xsd +272 -0
  331. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-target-1.xsd +53 -0
  332. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml-text-1.xsd +67 -0
  333. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11-model-1.xsd +677 -0
  334. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11-module-redefines-1.xsd +335 -0
  335. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11-modules-1.xsd +528 -0
  336. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml11.xsd +104 -0
  337. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xhtml2.xsd +21 -0
  338. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-1.xsd +73 -0
  339. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-2.xsd +74 -0
  340. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-attribs-1.xsd +73 -0
  341. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-attribs-2.xsd +75 -0
  342. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-copyright-1.xsd +34 -0
  343. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-events-copyright-2.xsd +34 -0
  344. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml/xml-handlers-2.xsd +98 -0
  345. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0-definitions.xsd +225 -0
  346. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0-model.xsd +681 -0
  347. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0-modules.xsd +535 -0
  348. arelle/resources/cache/http/www.xbrl.org/2008/inlinexbrl/xhtml-inlinexbrl-1_0.xsd +40 -0
  349. arelle/resources/cache/http/www.xbrl.org/2008/match-filter.xsd +94 -0
  350. arelle/resources/cache/http/www.xbrl.org/2008/period-filter.xsd +86 -0
  351. arelle/resources/cache/http/www.xbrl.org/2008/registry.xsd +145 -0
  352. arelle/resources/cache/http/www.xbrl.org/2008/relative-filter.xsd +38 -0
  353. arelle/resources/cache/http/www.xbrl.org/2008/segment-scenario-filter.xsd +41 -0
  354. arelle/resources/cache/http/www.xbrl.org/2008/tuple-filter.xsd +83 -0
  355. arelle/resources/cache/http/www.xbrl.org/2008/unit-filter.xsd +58 -0
  356. arelle/resources/cache/http/www.xbrl.org/2008/validation.xsd +78 -0
  357. arelle/resources/cache/http/www.xbrl.org/2008/value-assertion.xsd +43 -0
  358. arelle/resources/cache/http/www.xbrl.org/2008/value-filter.xsd +43 -0
  359. arelle/resources/cache/http/www.xbrl.org/2008/variable.xsd +240 -0
  360. arelle/resources/cache/http/www.xbrl.org/2010/aspect-cover-filter.xsd +67 -0
  361. arelle/resources/cache/http/www.xbrl.org/2010/concept-relation-filter.xsd +108 -0
  362. arelle/resources/cache/http/www.xbrl.org/2010/custom-function-implementation.xsd +71 -0
  363. arelle/resources/cache/http/www.xbrl.org/2010/generic-message.xsd +68 -0
  364. arelle/resources/cache/http/www.xbrl.org/2010/validation-message.xsd +50 -0
  365. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xbrl-instance-2003-12-31-ixmod.xsd +788 -0
  366. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xbrl-linkbase-2003-12-31-ixmod.xsd +488 -0
  367. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xl-2003-12-31.xsd +248 -0
  368. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xbrl/xlink-2003-12-31.xsd +117 -0
  369. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xframes-1.xsd +166 -0
  370. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-applet-1.xsd +66 -0
  371. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-attribs-1.xsd +72 -0
  372. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-base-1.xsd +36 -0
  373. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic-form-1.xsd +195 -0
  374. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic-table-1.xsd +169 -0
  375. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10-model-1.xsd +376 -0
  376. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10-module-redefines-1.xsd +61 -0
  377. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10-modules-1.xsd +259 -0
  378. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-basic10.xsd +98 -0
  379. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-bdo-1.xsd +78 -0
  380. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-blkphras-1.xsd +161 -0
  381. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-blkpres-1.xsd +37 -0
  382. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-blkstruct-1.xsd +49 -0
  383. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-charent-1.xsd +38 -0
  384. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-copyright-1.xsd +29 -0
  385. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-csismap-1.xsd +96 -0
  386. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-datatypes-1.xsd +128 -0
  387. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-edit-1.xsd +39 -0
  388. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-events-1.xsd +130 -0
  389. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-form-1.xsd +326 -0
  390. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-frames-1.xsd +113 -0
  391. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-framework-1.xsd +66 -0
  392. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-hypertext-1.xsd +47 -0
  393. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-iframe-1.xsd +68 -0
  394. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-image-1.xsd +45 -0
  395. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlphras-1.xsd +163 -0
  396. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlpres-1.xsd +39 -0
  397. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlstruct-1.xsd +50 -0
  398. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-inlstyle-1.xsd +27 -0
  399. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-legacy-1.xsd +97 -0
  400. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-link-1.xsd +45 -0
  401. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-list-1.xsd +99 -0
  402. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-meta-1.xsd +42 -0
  403. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-misc-1.xsd +441 -0
  404. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-nameident-1.xsd +63 -0
  405. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-notations-1.xsd +69 -0
  406. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-object-1.xsd +76 -0
  407. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-param-1.xsd +51 -0
  408. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-pres-1.xsd +51 -0
  409. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-ruby-1.xsd +171 -0
  410. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-ruby-basic-1.xsd +89 -0
  411. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-script-1.xsd +70 -0
  412. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-ssismap-1.xsd +43 -0
  413. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-struct-1.xsd +112 -0
  414. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-style-1.xsd +52 -0
  415. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-table-1.xsd +272 -0
  416. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-target-1.xsd +53 -0
  417. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml-text-1.xsd +67 -0
  418. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11-model-1.xsd +677 -0
  419. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11-module-redefines-1.xsd +335 -0
  420. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11-modules-1.xsd +528 -0
  421. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml11.xsd +104 -0
  422. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xhtml2.xsd +21 -0
  423. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-1.xsd +73 -0
  424. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-2.xsd +74 -0
  425. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-attribs-1.xsd +73 -0
  426. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-attribs-2.xsd +75 -0
  427. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-copyright-1.xsd +34 -0
  428. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-events-copyright-2.xsd +34 -0
  429. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml/xml-handlers-2.xsd +98 -0
  430. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1-definitions.xsd +252 -0
  431. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1-model.xsd +681 -0
  432. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1-modules.xsd +535 -0
  433. arelle/resources/cache/http/www.xbrl.org/2013/inlineXBRL/xhtml-inlinexbrl-1_1.xsd +40 -0
  434. arelle/resources/cache/http/www.xbrl.org/2013/match-filter.xsd +94 -0
  435. arelle/resources/cache/http/www.xbrl.org/2013/preferred-label.xsd +12 -0
  436. arelle/resources/cache/http/www.xbrl.org/2013/versioning-base.xsd +142 -0
  437. arelle/resources/cache/http/www.xbrl.org/2013/versioning-concept-details.xsd +143 -0
  438. arelle/resources/cache/http/www.xbrl.org/2013/versioning-concept-use.xsd +64 -0
  439. arelle/resources/cache/http/www.xbrl.org/2013/versioning-dimensions.xsd +162 -0
  440. arelle/resources/cache/http/www.xbrl.org/2014/extensible-enumerations.xsd +27 -0
  441. arelle/resources/cache/http/www.xbrl.org/2014/table.xsd +356 -0
  442. arelle/resources/cache/http/www.xbrl.org/2014/tablemodel.xsd +156 -0
  443. arelle/resources/cache/http/www.xbrl.org/2016/assertion-severity.xsd +29 -0
  444. arelle/resources/cache/http/www.xbrl.org/2016/severities.xml +21 -0
  445. arelle/resources/cache/http/www.xbrl.org/2016/taxonomy-package-catalog.xsd +38 -0
  446. arelle/resources/cache/http/www.xbrl.org/2016/taxonomy-package.xsd +154 -0
  447. arelle/resources/cache/http/www.xbrl.org/2022/assertion-severity.xsd +43 -0
  448. arelle/resources/cache/http/www.xbrl.org/2022/severities.xml +21 -0
  449. arelle/resources/cache/http/www.xbrl.org/dtr/type/nonNumeric-2009-12-16.xsd +76 -0
  450. arelle/resources/cache/http/www.xbrl.org/dtr/type/numeric-2009-12-16.xsd +78 -0
  451. arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/accounting-arcrole-2023-01-04.xsd +39 -0
  452. arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/deprecated-2009-12-16.xsd +29 -0
  453. arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/esma-arcrole-2018-11-21.xsd +14 -0
  454. arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/factExplanatory-2009-12-16.xsd +13 -0
  455. arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/jpfr-arcrole-2007-11-07.xsd +27 -0
  456. arelle/resources/cache/http/www.xbrl.org/lrr/arcrole/parent-child-2013-09-19.xsd +12 -0
  457. arelle/resources/cache/http/www.xbrl.org/lrr/role/deprecated-2009-12-16.xsd +17 -0
  458. arelle/resources/cache/http/www.xbrl.org/lrr/role/jpfr-role-2007-11-07.xsd +47 -0
  459. arelle/resources/cache/http/www.xbrl.org/lrr/role/negated-2008-03-31.xsd +30 -0
  460. arelle/resources/cache/http/www.xbrl.org/lrr/role/negated-2009-12-16.xsd +33 -0
  461. arelle/resources/cache/http/www.xbrl.org/lrr/role/negative-2009-12-16.xsd +25 -0
  462. arelle/resources/cache/http/www.xbrl.org/lrr/role/net-2009-12-16.xsd +13 -0
  463. arelle/resources/cache/http/www.xbrl.org/lrr/role/positive-2009-12-16.xsd +25 -0
  464. arelle/resources/cache/http/www.xbrl.org/lrr/role/property-2022-09-28.xsd +15 -0
  465. arelle/resources/cache/http/www.xbrl.org/lrr/role/reference-2009-12-16.xsd +21 -0
  466. arelle/resources/cache/http/www.xbrl.org/lrr/role/restated-2006-02-21.xsd +19 -0
  467. arelle/resources/cache/http/www.xbrl.org/utr/2012-01-30/utr.xml +4543 -0
  468. arelle/resources/cache/http/www.xbrl.org/utr/2012-10-31/utr.xml +4510 -0
  469. arelle/resources/cache/http/www.xbrl.org/utr/2012-11-30/utr.xml +4567 -0
  470. arelle/resources/cache/http/www.xbrl.org/utr/2013-02-28/utr.xml +5180 -0
  471. arelle/resources/cache/http/www.xbrl.org/utr/2013-05-17/utr.xml +5349 -0
  472. arelle/resources/cache/http/www.xbrl.org/utr/2016-08-10/utr.xml +5363 -0
  473. arelle/resources/cache/http/www.xbrl.org/utr/2017-07-12/utr.xml +6164 -0
  474. arelle/resources/cache/http/www.xbrl.org/utr/2021-02-16/utr.xml +6370 -0
  475. arelle/resources/cache/http/www.xbrl.org/utr/2021-12-08/utr.xml +6493 -0
  476. arelle/resources/cache/http/www.xbrl.org/utr/2022-02-16/utr.xml +6551 -0
  477. arelle/resources/cache/http/www.xbrl.org/utr/2022-07-20/utr.xml +6638 -0
  478. arelle/resources/cache/http/www.xbrl.org/utr/2023-12-20/utr.xml +6680 -0
  479. arelle/resources/cache/http/www.xbrl.org/utr/2024-01-31/utr.xml +6680 -0
  480. arelle/resources/cache/http/www.xbrl.org/utr/2024-10-22/utr.xml +6693 -0
  481. arelle/resources/cache/http/www.xbrl.org/utr/utr.xml +6693 -0
  482. arelle/resources/cache/https/www.xbrl.org/2005/conformance.xsd +87 -0
  483. arelle/resources/cache/https/www.xbrl.org/2020/extensible-enumerations-2.0.xsd +51 -0
  484. arelle/resources/cache/https/www.xbrl.org/2023/calculation-1.1.xsd +27 -0
  485. arelle/resources/cache/https/www.xbrl.org/dtr/type/2020-01-21/types.xsd +812 -0
  486. arelle/resources/cache/https/www.xbrl.org/dtr/type/2022-03-31/types.xsd +847 -0
  487. arelle/resources/cache/https/www.xbrl.org/dtr/type/2024-01-31/types.xsd +897 -0
  488. arelle/resources/cache/https/www.xbrl.org/taxonomy/int/filing-indicators/REC/2021-02-03/filing-indicators-def.xml +68 -0
  489. arelle/resources/cache/https/www.xbrl.org/taxonomy/int/filing-indicators/REC/2021-02-03/filing-indicators-label.xml +84 -0
  490. arelle/resources/cache/https/www.xbrl.org/taxonomy/int/filing-indicators/REC/2021-02-03/filing-indicators.xsd +67 -0
  491. arelle/resources/libs/Tktable2.11/linux-x86_64/README.txt +149 -0
  492. arelle/resources/libs/Tktable2.11/linux-x86_64/html/tkTable.html +2039 -0
  493. arelle/resources/libs/Tktable2.11/linux-x86_64/libTktable2.11.so +0 -0
  494. arelle/resources/libs/Tktable2.11/linux-x86_64/license.txt +51 -0
  495. arelle/resources/libs/Tktable2.11/linux-x86_64/pkgIndex.tcl +3 -0
  496. arelle/resources/libs/Tktable2.11/linux-x86_64/tkTable.tcl +825 -0
  497. arelle/resources/libs/Tktable2.11/linux-x86_64/tktable.py +674 -0
  498. arelle/resources/libs/Tktable2.11/macos-arm64/README.txt +149 -0
  499. arelle/resources/libs/Tktable2.11/macos-arm64/html/tkTable.html +2039 -0
  500. arelle/resources/libs/Tktable2.11/macos-arm64/libTktable2.11.dylib +0 -0
  501. arelle/resources/libs/Tktable2.11/macos-arm64/license.txt +51 -0
  502. arelle/resources/libs/Tktable2.11/macos-arm64/pkgIndex.tcl +2 -0
  503. arelle/resources/libs/Tktable2.11/macos-arm64/tkTable.tcl +825 -0
  504. arelle/resources/libs/Tktable2.11/macos-arm64/tktable.py +674 -0
  505. arelle/resources/libs/Tktable2.11/macos-x86_64/README.txt +149 -0
  506. arelle/resources/libs/Tktable2.11/macos-x86_64/html/tkTable.html +2039 -0
  507. arelle/resources/libs/Tktable2.11/macos-x86_64/libTktable2.11.dylib +0 -0
  508. arelle/resources/libs/Tktable2.11/macos-x86_64/license.txt +51 -0
  509. arelle/resources/libs/Tktable2.11/macos-x86_64/pkgIndex.tcl +2 -0
  510. arelle/resources/libs/Tktable2.11/macos-x86_64/tkTable.tcl +825 -0
  511. arelle/resources/libs/Tktable2.11/macos-x86_64/tktable.py +674 -0
  512. arelle/resources/libs/Tktable2.11/win-x86_64/Tktable.dll +0 -0
  513. arelle/resources/libs/Tktable2.11/win-x86_64/pkgIndex.tcl +2 -0
  514. arelle/resources/libs/Tktable2.11/win-x86_64/tkTable.tcl +825 -0
  515. arelle/typing.py +9 -4
  516. arelle/utils/Contexts.py +38 -0
  517. arelle/utils/EntryPointDetection.py +139 -0
  518. arelle/utils/Equivalence.py +22 -0
  519. arelle/utils/{validate/PluginValidationData.py → PluginData.py} +5 -2
  520. arelle/utils/PluginHooks.py +256 -5
  521. arelle/utils/Units.py +36 -0
  522. arelle/utils/validate/Decorator.py +5 -3
  523. arelle/utils/validate/DetectScriptsInXhtml.py +99 -0
  524. arelle/utils/validate/ESEFImage.py +283 -0
  525. arelle/utils/validate/Validation.py +9 -1
  526. arelle/utils/validate/ValidationPlugin.py +74 -11
  527. arelle/utils/validate/ValidationUtil.py +55 -0
  528. arelle/webserver/bottle.py +5 -4424
  529. {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/METADATA +51 -42
  530. arelle_release-2.37.71.dist-info/RECORD +697 -0
  531. {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/WHEEL +1 -1
  532. {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info/licenses}/LICENSE.md +1 -4
  533. {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/top_level.txt +0 -1
  534. arelle/DialogOpenTaxonomyPackage.py +0 -1
  535. arelle/RenderingResolver.py +0 -624
  536. arelle/examples/.pydevproject +0 -5
  537. arelle/examples/CustomLogger.py +0 -43
  538. arelle/examples/LoadEFMvalidate.py +0 -32
  539. arelle/examples/LoadSavePreLbCsv.py +0 -26
  540. arelle/examples/LoadValidate.cs +0 -31
  541. arelle/examples/LoadValidate.py +0 -36
  542. arelle/examples/LoadValidateCmdLine.java +0 -69
  543. arelle/examples/LoadValidatePostedZip.java +0 -57
  544. arelle/examples/LoadValidateWebService.java +0 -34
  545. arelle/examples/SaveTableToExelle.py +0 -140
  546. arelle/examples/TR3toTR4.py +0 -88
  547. arelle/examples/plugin/bigInstance.py +0 -394
  548. arelle/examples/plugin/cmdWebServerExtension.py +0 -42
  549. arelle/examples/plugin/crashTest.py +0 -38
  550. arelle/examples/plugin/formulaSuiteConverter.py +0 -212
  551. arelle/examples/plugin/functionsCustom.py +0 -59
  552. arelle/examples/plugin/hello_dolly.py +0 -64
  553. arelle/examples/plugin/hello_i18n.pot +0 -26
  554. arelle/examples/plugin/hello_i18n.py +0 -32
  555. arelle/examples/plugin/importTestChild1.py +0 -21
  556. arelle/examples/plugin/importTestChild2.py +0 -22
  557. arelle/examples/plugin/importTestGrandchild1.py +0 -21
  558. arelle/examples/plugin/importTestGrandchild2.py +0 -21
  559. arelle/examples/plugin/importTestImported1.py +0 -23
  560. arelle/examples/plugin/importTestImported11.py +0 -22
  561. arelle/examples/plugin/importTestParent.py +0 -48
  562. arelle/examples/plugin/locale/fr/LC_MESSAGES/hello_i18n.po +0 -25
  563. arelle/examples/plugin/packagedImportTest/__init__.py +0 -47
  564. arelle/examples/plugin/packagedImportTest/importTestChild1.py +0 -21
  565. arelle/examples/plugin/packagedImportTest/importTestChild2.py +0 -22
  566. arelle/examples/plugin/packagedImportTest/importTestGrandchild1.py +0 -21
  567. arelle/examples/plugin/packagedImportTest/importTestGrandchild2.py +0 -21
  568. arelle/examples/plugin/packagedImportTest/importTestImported1.py +0 -24
  569. arelle/examples/plugin/packagedImportTest/importTestImported11.py +0 -21
  570. arelle/examples/plugin/packagedImportTest/subdir/importTestImported111.py +0 -21
  571. arelle/examples/plugin/packagedImportTest/subdir/subsubdir/importTestImported1111.py +0 -21
  572. arelle/examples/plugin/sakaCalendar.py +0 -215
  573. arelle/examples/plugin/saveInstanceInfoset.py +0 -121
  574. arelle/examples/plugin/streamingExtensions.py +0 -335
  575. arelle/examples/plugin/testcaseCalc11ValidateSetup.py +0 -32
  576. arelle/examples/plugin/testcaseIxExpectedHtmlFixup.py +0 -45
  577. arelle/examples/plugin/updateTableLB.py +0 -242
  578. arelle/examples/plugin/validate/XYZ/DisclosureSystems.py +0 -2
  579. arelle/examples/plugin/validate/XYZ/PluginValidationDataExtension.py +0 -10
  580. arelle/examples/plugin/validate/XYZ/ValidationPluginExtension.py +0 -49
  581. arelle/examples/plugin/validate/XYZ/__init__.py +0 -75
  582. arelle/examples/plugin/validate/XYZ/resources/config.xml +0 -16
  583. arelle/examples/plugin/validate/XYZ/rules/rules01.py +0 -109
  584. arelle/examples/plugin/validate/XYZ/rules/rules02.py +0 -58
  585. arelle/examples/plugin/validateSchemaLxml.py +0 -156
  586. arelle/examples/plugin/validateTableInfoset.py +0 -52
  587. arelle/examples/us-gaap-dei-docType-extraction-frm.xml +0 -90
  588. arelle/examples/us-gaap-dei-ratio-cash-frm.xml +0 -150
  589. arelle/plugin/functionsXmlCreation.py +0 -106
  590. arelle/plugin/instanceInfo.py +0 -306
  591. arelle/plugin/loadFromOIM-2018.py +0 -1282
  592. arelle/plugin/objectmaker.py +0 -285
  593. arelle/plugin/sphinx/FormulaGenerator.py +0 -823
  594. arelle/plugin/sphinx/SphinxContext.py +0 -404
  595. arelle/plugin/sphinx/SphinxEvaluator.py +0 -783
  596. arelle/plugin/sphinx/SphinxMethods.py +0 -1287
  597. arelle/plugin/sphinx/SphinxParser.py +0 -1093
  598. arelle/plugin/sphinx/SphinxValidator.py +0 -163
  599. arelle/plugin/sphinx/US-GAAP Ratios Example.xsr +0 -52
  600. arelle/plugin/sphinx/__init__.py +0 -285
  601. arelle/plugin/transforms/SEC/__init__.py +0 -308
  602. arelle/plugin/transforms/SEC/conf/README.md +0 -39
  603. arelle/plugin/transforms/SEC/conf/extractTestcase.sh +0 -2
  604. arelle/plugin/transforms/SEC/conf/extractTestcase.xsl +0 -109
  605. arelle/plugin/transforms/SEC/conf/runIxtSecTests.sh +0 -16
  606. arelle/plugin/transforms/SEC/conf/saxon9.jar +0 -0
  607. arelle/plugin/transforms/SEC/conf/testcase.xml +0 -7117
  608. arelle/plugin/transforms/SEC/conf/tests.xml +0 -848
  609. arelle/plugin/transforms/SEC/text2num.py +0 -110
  610. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-boolballotbox.xml +0 -66
  611. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-countrynameen.xml +0 -65
  612. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-datequarterend.xml +0 -66
  613. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durday.xml +0 -61
  614. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durhour.xml +0 -69
  615. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durmonth.xml +0 -71
  616. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durweek.xml +0 -70
  617. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-durwordsen.xml +0 -56
  618. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-duryear.xml +0 -64
  619. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-edgarprovcountryen.xml +0 -65
  620. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-entityfilercategoryen.xml +0 -63
  621. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-exchnameen.xml +0 -86
  622. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-numwordsen.xml +0 -55
  623. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-stateprovnameen.xml +0 -64
  624. arelle/plugin/transforms/SEC/transformationRegistry/registry/ixt-sec-yesnoballotbox.xml +0 -66
  625. arelle/plugin/transforms/SEC/transformationRegistry/registry/transform-registry.xml +0 -314
  626. arelle/plugin/transforms/SEC/transformationRegistry/schema/inlinexbrl-sec-transformation.xsd +0 -418
  627. arelle/plugin/validate/EFM/Consts.py +0 -362
  628. arelle/plugin/validate/EFM/DTS.py +0 -569
  629. arelle/plugin/validate/EFM/Dimensions.py +0 -264
  630. arelle/plugin/validate/EFM/Document.py +0 -206
  631. arelle/plugin/validate/EFM/Filing.py +0 -4383
  632. arelle/plugin/validate/EFM/IsolateSeparateIXDSes.py +0 -19
  633. arelle/plugin/validate/EFM/MessageNumericId.py +0 -142
  634. arelle/plugin/validate/EFM/PreCalAlignment.py +0 -324
  635. arelle/plugin/validate/EFM/Util.py +0 -688
  636. arelle/plugin/validate/EFM/__init__.py +0 -843
  637. arelle/plugin/validate/EFM/config.xml +0 -333
  638. arelle/plugin/validate/EFM/resources/README.md +0 -57
  639. arelle/plugin/validate/EFM/resources/axiswarnings.json +0 -27
  640. arelle/plugin/validate/EFM/resources/cef-deprecated-concepts.json +0 -8
  641. arelle/plugin/validate/EFM/resources/country-deprecated-concepts.json +0 -19
  642. arelle/plugin/validate/EFM/resources/currency-deprecated-concepts.json +0 -7
  643. arelle/plugin/validate/EFM/resources/dei-deprecated-concepts.json +0 -8
  644. arelle/plugin/validate/EFM/resources/dei-validations.json +0 -2884
  645. arelle/plugin/validate/EFM/resources/dqc-us-rules.json +0 -1389
  646. arelle/plugin/validate/EFM/resources/ecd-deprecated-concepts.json +0 -1
  647. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-16-4.xml +0 -115
  648. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-0-4.xml +0 -300
  649. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-1.xml +0 -304
  650. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-2.xml +0 -290
  651. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-17-3-1.xml +0 -294
  652. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-18.1.xml +0 -549
  653. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-18.2.xml +0 -506
  654. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-18.3.xml +0 -496
  655. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-19-1.xml +0 -662
  656. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-19-2.xml +0 -3761
  657. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-19-3.xml +0 -3577
  658. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-20-1.xml +0 -4020
  659. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-20-2.xml +0 -3320
  660. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-20-3.xml +0 -2998
  661. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2012.xml +0 -957
  662. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2013.xml +0 -982
  663. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2014.xml +0 -1001
  664. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2015.xml +0 -1076
  665. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-2016.xml +0 -120
  666. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-1.xml +0 -3329
  667. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-2.xml +0 -1230
  668. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-3.xml +0 -1113
  669. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-21-4.xml +0 -1321
  670. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-1-preview.xml +0 -1721
  671. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-1.xml +0 -1841
  672. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-2-2.xml +0 -1450
  673. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-2.xml +0 -1429
  674. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-22-4.xml +0 -1527
  675. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-1-1.xml +0 -2049
  676. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-1.xml +0 -2065
  677. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-2.xml +0 -1674
  678. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-23-3.xml +0 -1715
  679. arelle/plugin/validate/EFM/resources/edgartaxonomies/edgartaxonomies-all-years.xml +0 -10671
  680. arelle/plugin/validate/EFM/resources/edgartaxonomies/erxl.xsd +0 -69
  681. arelle/plugin/validate/EFM/resources/edgartaxonomies/extendedtaxonomies-all-years.xml +0 -18
  682. arelle/plugin/validate/EFM/resources/edgartaxonomies/ifrs-taxonomies.xml +0 -3126
  683. arelle/plugin/validate/EFM/resources/edgartaxonomies/ifrstaxonomies-all-years.xml +0 -22
  684. arelle/plugin/validate/EFM/resources/ex26-validations.json +0 -255
  685. arelle/plugin/validate/EFM/resources/exch-deprecated-concepts.json +0 -163
  686. arelle/plugin/validate/EFM/resources/ifrs-full-deprecated-concepts.json +0 -204
  687. arelle/plugin/validate/EFM/resources/invest-deprecated-concepts.json +0 -99
  688. arelle/plugin/validate/EFM/resources/ixbrl-transform-registries.json +0 -16
  689. arelle/plugin/validate/EFM/resources/naics-deprecated-concepts.json +0 -295
  690. arelle/plugin/validate/EFM/resources/oef-deprecated-concepts.json +0 -59
  691. arelle/plugin/validate/EFM/resources/other-standard-taxonomies.json +0 -12
  692. arelle/plugin/validate/EFM/resources/rr-deprecated-concepts.json +0 -14
  693. arelle/plugin/validate/EFM/resources/rxp-deprecated-concepts.json +0 -1
  694. arelle/plugin/validate/EFM/resources/shr-deprecated-concepts.json +0 -1
  695. arelle/plugin/validate/EFM/resources/sic-deprecated-concepts.json +0 -1
  696. arelle/plugin/validate/EFM/resources/signwarnings.json +0 -112
  697. arelle/plugin/validate/EFM/resources/srt-deprecated-concepts.json +0 -1
  698. arelle/plugin/validate/EFM/resources/stpr-deprecated-concepts.json +0 -1
  699. arelle/plugin/validate/EFM/resources/taxonomy-compatibility.json +0 -79
  700. arelle/plugin/validate/EFM/resources/us-gaap-deprecated-concepts.json +0 -2886
  701. arelle/plugin/validate/EFM/resources/us-gaap-rels-2020.json +0 -29068
  702. arelle/plugin/validate/EFM/resources/us-gaap-rels-2021.json +0 -29598
  703. arelle/plugin/validate/EFM/resources/us-gaap-rels-2022.json +0 -29141
  704. arelle/plugin/validate/EFM/resources/us-gaap-rels-2023.json +0 -29400
  705. arelle/plugin/validate/EFM/resources/vip-deprecated-concepts.json +0 -1
  706. arelle/plugin/validate/EFM/tools/CheckTxmyRefs.py +0 -180
  707. arelle/plugin/validate/EFM-htm/Const.py +0 -205
  708. arelle/plugin/validate/EFM-htm/__init__.py +0 -217
  709. arelle/plugin/validate/EFM-htm/config.xml +0 -17
  710. arelle/plugin/validate/EFM-htm/resources/efm-htm.dtd +0 -664
  711. arelle/plugin/validate/ESEF/ESEF_Current/Image.py +0 -199
  712. arelle/plugin/validate/ESEF_2022/__init__.py +0 -47
  713. arelle/plugin/validate/GFM/__init__.py +0 -59
  714. arelle/plugin/validate/GFM/config.xml +0 -82
  715. arelle/plugin/validate/SBRnl/CustomLoader.py +0 -19
  716. arelle/plugin/validate/SBRnl/DTS.py +0 -305
  717. arelle/plugin/validate/SBRnl/Dimensions.py +0 -357
  718. arelle/plugin/validate/SBRnl/Document.py +0 -799
  719. arelle/plugin/validate/SBRnl/Filing.py +0 -467
  720. arelle/plugin/validate/SBRnl/__init__.py +0 -75
  721. arelle/plugin/validate/SBRnl/config.xml +0 -26
  722. arelle/plugin/validate/SBRnl/sbr-nl-taxonomies.xml +0 -754
  723. arelle/plugin/validate/USBestPractices.py +0 -570
  724. arelle/plugin/validate/USCorpAction.py +0 -557
  725. arelle/plugin/validate/USSecTagging.py +0 -337
  726. arelle/plugin/validate/XDC/__init__.py +0 -77
  727. arelle/plugin/validate/XDC/config.xml +0 -20
  728. arelle/plugin/validate/XFsyntax/__init__.py +0 -64
  729. arelle/plugin/validate/XFsyntax/xf.py +0 -2227
  730. arelle/plugin/validate/__init__.py +0 -20
  731. arelle/plugin/validate/calc2.py +0 -536
  732. arelle/plugin/validateSBRnl.py +0 -530
  733. arelle/scripts-macOS/startWebServer.command +0 -3
  734. arelle/scripts-unix/startWebServer.sh +0 -1
  735. arelle/scripts-windows/startWebServer.bat +0 -5
  736. arelle_release-2.17.1.dist-info/RECORD +0 -676
  737. tests/__init__.py +0 -0
  738. tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/ArelleGUITest.csproj +0 -30
  739. tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/Tests.cs +0 -381
  740. tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest/Usings.cs +0 -1
  741. tests/integration_tests/ui_tests/ArelleGUITest/ArelleGUITest.sln +0 -31
  742. tests/integration_tests/ui_tests/resources/workiva.zip +0 -0
  743. tests/integration_tests/validation/README.md +0 -50
  744. tests/integration_tests/validation/conformance_suite_config.py +0 -59
  745. tests/integration_tests/validation/conformance_suite_configs.py +0 -63
  746. tests/integration_tests/validation/conformance_suite_configurations/efm_current.py +0 -261
  747. tests/integration_tests/validation/conformance_suite_configurations/esef_ixbrl_2021.py +0 -85
  748. tests/integration_tests/validation/conformance_suite_configurations/esef_ixbrl_2022.py +0 -90
  749. tests/integration_tests/validation/conformance_suite_configurations/esef_xhtml_2021.py +0 -15
  750. tests/integration_tests/validation/conformance_suite_configurations/esef_xhtml_2022.py +0 -15
  751. tests/integration_tests/validation/conformance_suite_configurations/nl_nt16.py +0 -13
  752. tests/integration_tests/validation/conformance_suite_configurations/nl_nt17.py +0 -13
  753. tests/integration_tests/validation/conformance_suite_configurations/nl_nt18.py +0 -13
  754. tests/integration_tests/validation/conformance_suite_configurations/xbrl_2_1.py +0 -34
  755. tests/integration_tests/validation/conformance_suite_configurations/xbrl_calculations_1_1.py +0 -40
  756. tests/integration_tests/validation/conformance_suite_configurations/xbrl_dimensions_1_0.py +0 -28
  757. tests/integration_tests/validation/conformance_suite_configurations/xbrl_extensible_enumerations_1_0.py +0 -10
  758. tests/integration_tests/validation/conformance_suite_configurations/xbrl_extensible_enumerations_2_0.py +0 -10
  759. tests/integration_tests/validation/conformance_suite_configurations/xbrl_formula_1_0.py +0 -9
  760. tests/integration_tests/validation/conformance_suite_configurations/xbrl_formula_1_0_assertion_severity_2_0.py +0 -9
  761. tests/integration_tests/validation/conformance_suite_configurations/xbrl_formula_1_0_function_registry.py +0 -14
  762. tests/integration_tests/validation/conformance_suite_configurations/xbrl_ixbrl_1_1.py +0 -22
  763. tests/integration_tests/validation/conformance_suite_configurations/xbrl_link_role_registry_1_0.py +0 -11
  764. tests/integration_tests/validation/conformance_suite_configurations/xbrl_oim_1_0.py +0 -19
  765. tests/integration_tests/validation/conformance_suite_configurations/xbrl_table_linkbase_1_0.py +0 -296
  766. tests/integration_tests/validation/conformance_suite_configurations/xbrl_taxonomy_packages_1_0.py +0 -13
  767. tests/integration_tests/validation/conformance_suite_configurations/xbrl_transformation_registry_3.py +0 -13
  768. tests/integration_tests/validation/conformance_suite_configurations/xbrl_transformation_registry_4.py +0 -13
  769. tests/integration_tests/validation/conformance_suite_configurations/xbrl_transformation_registry_5.py +0 -13
  770. tests/integration_tests/validation/conformance_suite_configurations/xbrl_utr_malformed_1_0.py +0 -31
  771. tests/integration_tests/validation/conformance_suite_configurations/xbrl_utr_registry_1_0.py +0 -22
  772. tests/integration_tests/validation/conformance_suite_configurations/xbrl_utr_structure_1_0.py +0 -18
  773. tests/integration_tests/validation/conftest.py +0 -24
  774. tests/integration_tests/validation/discover_tests.py +0 -22
  775. tests/integration_tests/validation/download_conformance_suites.py +0 -47
  776. tests/integration_tests/validation/run_conformance_suites.py +0 -175
  777. tests/integration_tests/validation/test_conformance_suites.py +0 -14
  778. tests/integration_tests/validation/validation_util.py +0 -271
  779. tests/resources/conformance_suites/nl_nt16/br_kvk/2-04-invalid-period.xbrl +0 -63
  780. tests/resources/conformance_suites/nl_nt16/br_kvk/2-04-testcase.xml +0 -22
  781. tests/resources/conformance_suites/nl_nt16/br_kvk/3-01-missing.xbrl +0 -53
  782. tests/resources/conformance_suites/nl_nt16/br_kvk/3-01-multiple.xbrl +0 -60
  783. tests/resources/conformance_suites/nl_nt16/br_kvk/3-01-testcase.xml +0 -33
  784. tests/resources/conformance_suites/nl_nt16/br_kvk/4-07-invalid.xbrl +0 -57
  785. tests/resources/conformance_suites/nl_nt16/br_kvk/4-07-testcase.xml +0 -22
  786. tests/resources/conformance_suites/nl_nt16/br_kvk/4-10-invalid.xbrl +0 -58
  787. tests/resources/conformance_suites/nl_nt16/br_kvk/4-10-testcase.xml +0 -22
  788. tests/resources/conformance_suites/nl_nt16/br_kvk/4-12-invalid.xbrl +0 -63
  789. tests/resources/conformance_suites/nl_nt16/br_kvk/4-12-testcase.xml +0 -22
  790. tests/resources/conformance_suites/nl_nt16/br_kvk/4-16-missing.xbrl +0 -61
  791. tests/resources/conformance_suites/nl_nt16/br_kvk/4-16-testcase.xml +0 -22
  792. tests/resources/conformance_suites/nl_nt16/br_kvk/4-20-invalid-date.xbrl +0 -89
  793. tests/resources/conformance_suites/nl_nt16/br_kvk/4-20-testcase.xml +0 -22
  794. tests/resources/conformance_suites/nl_nt16/fr_kvk/1-01-invalid-file-extension.xml +0 -56
  795. tests/resources/conformance_suites/nl_nt16/fr_kvk/1-01-testcase.xml +0 -22
  796. tests/resources/conformance_suites/nl_nt16/fr_kvk/2-01-invalid-lang.xbrl +0 -56
  797. tests/resources/conformance_suites/nl_nt16/fr_kvk/2-01-missing-lang.xbrl +0 -55
  798. tests/resources/conformance_suites/nl_nt16/fr_kvk/2-01-testcase.xml +0 -33
  799. tests/resources/conformance_suites/nl_nt16/fr_kvk/2-03-entrypoint.xsd +0 -6
  800. tests/resources/conformance_suites/nl_nt16/fr_kvk/2-03-invalid-entrypoint.xbrl +0 -63
  801. tests/resources/conformance_suites/nl_nt16/fr_kvk/2-03-testcase.xml +0 -22
  802. tests/resources/conformance_suites/nl_nt16/fr_kvk/5-01-invalid-decimals.xbrl +0 -49
  803. tests/resources/conformance_suites/nl_nt16/fr_kvk/5-01-testcase.xml +0 -22
  804. tests/resources/conformance_suites/nl_nt16/fr_kvk/5-02-invalid-decimals.xbrl +0 -49
  805. tests/resources/conformance_suites/nl_nt16/fr_kvk/5-02-testcase.xml +0 -22
  806. tests/resources/conformance_suites/nl_nt16/fr_nl/1-01-invalid-file.xbrl +0 -2
  807. tests/resources/conformance_suites/nl_nt16/fr_nl/1-01-invalid-zip.zip +0 -0
  808. tests/resources/conformance_suites/nl_nt16/fr_nl/1-01-testcase.xml +0 -33
  809. tests/resources/conformance_suites/nl_nt16/fr_nl/1-03-invalid-doctype.xbrl +0 -4
  810. tests/resources/conformance_suites/nl_nt16/fr_nl/1-03-testcase.xml +0 -22
  811. tests/resources/conformance_suites/nl_nt16/fr_nl/1-05-invalid-encoding.xbrl +0 -0
  812. tests/resources/conformance_suites/nl_nt16/fr_nl/1-05-testcase.xml +0 -22
  813. tests/resources/conformance_suites/nl_nt16/fr_nl/1-06-testcase.xml +0 -22
  814. tests/resources/conformance_suites/nl_nt16/fr_nl/1-06.invalid.xbrl +0 -2
  815. tests/resources/conformance_suites/nl_nt16/fr_nl/2-06-invalid-file.xbrl +0 -8
  816. tests/resources/conformance_suites/nl_nt16/fr_nl/2-06-invalid-zip.zip +0 -0
  817. tests/resources/conformance_suites/nl_nt16/fr_nl/2-06-testcase.xml +0 -33
  818. tests/resources/conformance_suites/nl_nt16/index.xml +0 -20
  819. tests/resources/conformance_suites/nl_nt17/br_kvk/2-04-invalid-period.xbrl +0 -63
  820. tests/resources/conformance_suites/nl_nt17/br_kvk/2-04-testcase.xml +0 -22
  821. tests/resources/conformance_suites/nl_nt17/br_kvk/3-01-missing.xbrl +0 -53
  822. tests/resources/conformance_suites/nl_nt17/br_kvk/3-01-multiple.xbrl +0 -60
  823. tests/resources/conformance_suites/nl_nt17/br_kvk/3-01-testcase.xml +0 -33
  824. tests/resources/conformance_suites/nl_nt17/br_kvk/4-07-invalid.xbrl +0 -57
  825. tests/resources/conformance_suites/nl_nt17/br_kvk/4-07-testcase.xml +0 -22
  826. tests/resources/conformance_suites/nl_nt17/br_kvk/4-10-invalid.xbrl +0 -58
  827. tests/resources/conformance_suites/nl_nt17/br_kvk/4-10-testcase.xml +0 -22
  828. tests/resources/conformance_suites/nl_nt17/br_kvk/4-12-invalid.xbrl +0 -63
  829. tests/resources/conformance_suites/nl_nt17/br_kvk/4-12-testcase.xml +0 -22
  830. tests/resources/conformance_suites/nl_nt17/br_kvk/4-16-missing.xbrl +0 -61
  831. tests/resources/conformance_suites/nl_nt17/br_kvk/4-16-testcase.xml +0 -22
  832. tests/resources/conformance_suites/nl_nt17/br_kvk/4-20-invalid-date.xbrl +0 -89
  833. tests/resources/conformance_suites/nl_nt17/br_kvk/4-20-testcase.xml +0 -22
  834. tests/resources/conformance_suites/nl_nt17/fr_kvk/1-01-invalid-file-extension.xml +0 -56
  835. tests/resources/conformance_suites/nl_nt17/fr_kvk/1-01-testcase.xml +0 -22
  836. tests/resources/conformance_suites/nl_nt17/fr_kvk/2-01-invalid-lang.xbrl +0 -56
  837. tests/resources/conformance_suites/nl_nt17/fr_kvk/2-01-missing-lang.xbrl +0 -55
  838. tests/resources/conformance_suites/nl_nt17/fr_kvk/2-01-testcase.xml +0 -33
  839. tests/resources/conformance_suites/nl_nt17/fr_kvk/2-03-entrypoint.xsd +0 -6
  840. tests/resources/conformance_suites/nl_nt17/fr_kvk/2-03-invalid-entrypoint.xbrl +0 -63
  841. tests/resources/conformance_suites/nl_nt17/fr_kvk/2-03-testcase.xml +0 -22
  842. tests/resources/conformance_suites/nl_nt17/fr_kvk/5-01-invalid-decimals.xbrl +0 -49
  843. tests/resources/conformance_suites/nl_nt17/fr_kvk/5-01-testcase.xml +0 -22
  844. tests/resources/conformance_suites/nl_nt17/fr_kvk/5-02-invalid-decimals.xbrl +0 -49
  845. tests/resources/conformance_suites/nl_nt17/fr_kvk/5-02-testcase.xml +0 -22
  846. tests/resources/conformance_suites/nl_nt17/fr_nl/1-01-invalid-file.xbrl +0 -2
  847. tests/resources/conformance_suites/nl_nt17/fr_nl/1-01-invalid-zip.zip +0 -0
  848. tests/resources/conformance_suites/nl_nt17/fr_nl/1-01-testcase.xml +0 -33
  849. tests/resources/conformance_suites/nl_nt17/fr_nl/1-03-invalid-doctype.xbrl +0 -4
  850. tests/resources/conformance_suites/nl_nt17/fr_nl/1-03-testcase.xml +0 -22
  851. tests/resources/conformance_suites/nl_nt17/fr_nl/1-05-invalid-encoding.xbrl +0 -0
  852. tests/resources/conformance_suites/nl_nt17/fr_nl/1-05-testcases.xml +0 -22
  853. tests/resources/conformance_suites/nl_nt17/fr_nl/1-06-testcase.xml +0 -22
  854. tests/resources/conformance_suites/nl_nt17/fr_nl/1-06.invalid.xbrl +0 -2
  855. tests/resources/conformance_suites/nl_nt17/fr_nl/2-06-invalid-file.xbrl +0 -8
  856. tests/resources/conformance_suites/nl_nt17/fr_nl/2-06-invalid-zip.zip +0 -0
  857. tests/resources/conformance_suites/nl_nt17/fr_nl/2-06-testcase.xml +0 -33
  858. tests/resources/conformance_suites/nl_nt17/index.xml +0 -20
  859. tests/resources/conformance_suites/nl_nt18/fr_nl/1-03-invalid-doctype.xbrl +0 -4
  860. tests/resources/conformance_suites/nl_nt18/fr_nl/1-03-testcase.xml +0 -22
  861. tests/resources/conformance_suites/nl_nt18/fr_nl/1-05-invalid-encoding.xbrl +0 -0
  862. tests/resources/conformance_suites/nl_nt18/fr_nl/1-05-testcases.xml +0 -22
  863. tests/resources/conformance_suites/nl_nt18/fr_nl/1-06-testcase.xml +0 -22
  864. tests/resources/conformance_suites/nl_nt18/fr_nl/1-06.invalid.xbrl +0 -2
  865. tests/resources/conformance_suites/nl_nt18/fr_nl/1.01-invalid-file.xbrl +0 -2
  866. tests/resources/conformance_suites/nl_nt18/fr_nl/1.01-invalid-zip.zip +0 -0
  867. tests/resources/conformance_suites/nl_nt18/fr_nl/1.01-testcase.xml +0 -33
  868. tests/resources/conformance_suites/nl_nt18/fr_nl/2-06-invalid-file.xbrl +0 -8
  869. tests/resources/conformance_suites/nl_nt18/fr_nl/2-06-invalid-zip.zip +0 -0
  870. tests/resources/conformance_suites/nl_nt18/fr_nl/2-06-testcase.xml +0 -33
  871. tests/resources/conformance_suites/nl_nt18/index.xml +0 -8
  872. tests/unit_tests/arelle/conftest.py +0 -16
  873. tests/unit_tests/arelle/formula/test_fact_aspects_cache.py +0 -170
  874. tests/unit_tests/arelle/plugin/test_loadfromoim.py +0 -40
  875. tests/unit_tests/arelle/plugin/test_plugin_imports.py +0 -27
  876. tests/unit_tests/arelle/test_betafeatures.py +0 -81
  877. tests/unit_tests/arelle/test_cntlr.py +0 -28
  878. tests/unit_tests/arelle/test_import.py +0 -40
  879. tests/unit_tests/arelle/test_locale.py +0 -73
  880. tests/unit_tests/arelle/test_modelmanager.py +0 -15
  881. tests/unit_tests/arelle/test_packagemanager.py +0 -65
  882. tests/unit_tests/arelle/test_pluginmanager.py +0 -176
  883. tests/unit_tests/arelle/test_qname.py +0 -140
  884. tests/unit_tests/arelle/test_runtimeoptions.py +0 -56
  885. tests/unit_tests/arelle/test_system_info.py +0 -26
  886. tests/unit_tests/arelle/test_updater.py +0 -507
  887. tests/unit_tests/arelle/test_urlutil.py +0 -49
  888. tests/unit_tests/arelle/test_version.py +0 -46
  889. tests/unit_tests/arelle/utils/validate/test_decorator.py +0 -59
  890. /arelle/{examples/plugin/validate/XYZ → plugin/validate/EDINET}/rules/__init__.py +0 -0
  891. /arelle/plugin/validate/{HMRC → UK}/consistencyChecksByName.json +0 -0
  892. /arelle/plugin/validate/{HMRC → UK}/hmrc-taxonomies.xml +0 -0
  893. {arelle_release-2.17.1.dist-info → arelle_release-2.37.71.dist-info}/entry_points.txt +0 -0
@@ -0,0 +1,1377 @@
1
+ """
2
+ See COPYRIGHT.md for copyright information.
3
+ """
4
+ from __future__ import annotations
5
+
6
+ import datetime
7
+ import decimal
8
+ from collections.abc import Iterable
9
+ from typing import Any, cast
10
+
11
+ from arelle import ModelDocument
12
+ from arelle.XbrlConst import xhtml
13
+ from arelle.typing import TypeGetText
14
+ from arelle.ValidateXbrl import ValidateXbrl
15
+ from arelle.utils.PluginHooks import ValidationHook
16
+ from arelle.utils.validate.Decorator import validation
17
+ from arelle.utils.validate.Validation import Validation
18
+ from arelle.XmlValidateConst import VALID
19
+ from . import errorOnDateFactComparison, getFactsWithDimension, getFactsGroupedByContextId, getFactsWithoutDimension, groupFactsByContextHash, \
20
+ minimumRequiredFactsFound, consolidatedDimensionExists
21
+ from ..PluginValidationDataExtension import PluginValidationDataExtension
22
+ from ..ValidationPluginExtension import DANISH_CURRENCY_ID, ROUNDING_MARGIN, PERSONNEL_EXPENSE_THRESHOLD, REQUIRED_DISCLOSURE_OF_EQUITY_FACTS, REQUIRED_STATEMENT_OF_CHANGES_IN_EQUITY_FACTS
23
+ from ..DisclosureSystems import MULTI_TARGET_DISCLOSURE_SYSTEMS, STAND_ALONE_DISCLOSURE_SYSTEMS
24
+
25
+ _: TypeGetText
26
+
27
+ @validation(
28
+ hook=ValidationHook.XBRL_FINALLY,
29
+ )
30
+ def rule_fr1(
31
+ pluginData: PluginValidationDataExtension,
32
+ val: ValidateXbrl,
33
+ *args: Any,
34
+ **kwargs: Any,
35
+ ) -> Iterable[Validation]:
36
+ """
37
+ DBA.FR1: First and last name of the conductor for the general meeting or person who takes the conductor's place is missing
38
+ Companies that hold a general meeting and therefore provide a general meeting date
39
+ (gsd:DateOfGeneralMeeting) must also provide the name of the director
40
+ (gsd:NameAndSurnameOfChairmanOfGeneralMeeting).
41
+ """
42
+ meetingFacts = val.modelXbrl.factsByQname.get(pluginData.dateOfGeneralMeetingQn, set())
43
+ if len(meetingFacts) > 0:
44
+ chairmanFacts = val.modelXbrl.factsByQname.get(pluginData.nameAndSurnameOfChairmanOfGeneralMeetingQn, set())
45
+ if len(chairmanFacts) == 0:
46
+ yield Validation.error(
47
+ codes="DBA.FR1",
48
+ msg=_("First and last name of the conductor for the general meeting or person who takes the conductor's place is missing"),
49
+ modelObject=[val.modelXbrl.modelDocument]
50
+ )
51
+
52
+
53
+ @validation(
54
+ hook=ValidationHook.XBRL_FINALLY,
55
+ )
56
+ def rule_fr7(
57
+ pluginData: PluginValidationDataExtension,
58
+ val: ValidateXbrl,
59
+ *args: Any,
60
+ **kwargs: Any,
61
+ ) -> Iterable[Validation]:
62
+ """
63
+ DBA.FR7: Date of approval of the annual report (gsd:DateOfApprovalOfAnnualReport)
64
+ must be after the end date of the Accounting Period (gsd:ReportingPeriodEndDate
65
+ with default TypeOfReportingPeriodDimension).
66
+ """
67
+ return errorOnDateFactComparison(
68
+ val.modelXbrl,
69
+ fact1Qn=pluginData.reportingPeriodEndDateQn,
70
+ fact2Qn=pluginData.dateOfApprovalOfAnnualReportQn,
71
+ dimensionQn=pluginData.typeOfReportingPeriodDimensionQn,
72
+ code='DBA.FR7',
73
+ message=_("Date of approval of the annual report='%(fact2)s' "
74
+ "must be after the end date of the accounting period='%(fact1)s'"),
75
+ assertion=lambda endDate, approvalDate: endDate < approvalDate,
76
+ )
77
+
78
+
79
+ @validation(
80
+ hook=ValidationHook.XBRL_FINALLY,
81
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
82
+ )
83
+ def rule_fr20(
84
+ pluginData: PluginValidationDataExtension,
85
+ val: ValidateXbrl,
86
+ *args: Any,
87
+ **kwargs: Any,
88
+ ) -> Iterable[Validation]:
89
+ """
90
+ DBA.FR20: The annual report is missing a management endorsement. An annual report must always contain a management
91
+ endorsement if the company has more than one management member or if the company prepares an annual report according
92
+ to accounting class D.
93
+ """
94
+ modelXbrl = val.modelXbrl
95
+ for concept_qn in pluginData.managementEndorsementQns:
96
+ facts = modelXbrl.factsByQname.get(concept_qn, set())
97
+ for fact in facts:
98
+ if fact.xValid >= VALID and not fact.isNil:
99
+ return
100
+ yield Validation.error(
101
+ codes="DBA.FR20",
102
+ msg=_("The annual report does not contain a management endorsement. Please tag one of the following elements: {}").format(
103
+ [qn.localName for qn in pluginData.managementEndorsementQns]
104
+ ),
105
+ modelObject=val.modelXbrl.modelDocument
106
+ )
107
+
108
+
109
+ @validation(
110
+ hook=ValidationHook.XBRL_FINALLY,
111
+ )
112
+ def rule_fr24(
113
+ pluginData: PluginValidationDataExtension,
114
+ val: ValidateXbrl,
115
+ *args: Any,
116
+ **kwargs: Any,
117
+ ) -> Iterable[Validation]:
118
+ """
119
+ DBA.FR24: When cmn:TypeOfAuditorAssistance is "Revisionspåtegning" or "Auditor's report on audited financial statements"
120
+ then arr:DescriptionOfQualificationsOfAuditedFinancialStatements must not contain the following text:
121
+ - 'har ikke givet anledning til forbehold'
122
+ - 'has not given rise to reservations'
123
+ """
124
+ modelXbrl = val.modelXbrl
125
+ type_of_auditors_assistance_facts = modelXbrl.factsByQname.get(pluginData.typeOfAuditorAssistanceQn, set())
126
+ for auditor_fact in type_of_auditors_assistance_facts:
127
+ if (auditor_fact.xValid >= VALID and
128
+ (auditor_fact.xValue == pluginData.auditedFinancialStatementsDanish or
129
+ auditor_fact.xValue == pluginData.auditedFinancialStatementsEnglish)):
130
+ description_facts = modelXbrl.factsByQname.get(pluginData.descriptionOfQualificationsOfAuditedFinancialStatementsQn, set())
131
+ for description_fact in description_facts:
132
+ if description_fact.xValid >= VALID:
133
+ for text in pluginData.hasNotGivenRiseToReservationsText:
134
+ if text in str(description_fact.xValue):
135
+ yield Validation.error(
136
+ codes="DBA.FR24",
137
+ msg=_("The value of DescriptionOfQualificationsOfAuditedFinancialStatements must not "
138
+ "contain the text: \'{}\', when TypeOfAuditorAssistance is set to \'Revisionspåtegning\' "
139
+ "or \'Auditor's report on audited financial statements\'").format(text),
140
+ modelObject=description_fact
141
+ )
142
+
143
+
144
+ @validation(
145
+ hook=ValidationHook.XBRL_FINALLY,
146
+ )
147
+ def rule_fr25(
148
+ pluginData: PluginValidationDataExtension,
149
+ val: ValidateXbrl,
150
+ *args: Any,
151
+ **kwargs: Any,
152
+ ) -> Iterable[Validation]:
153
+ """
154
+ DBA.FR25: When cmn:TypeOfAuditorAssistance is "Erklæring om udvidet gennemgang" or "Auditor's report on extended review"
155
+ then arr:DescriptionOfQualificationsOfFinancialStatementsExtendedReview must not contain the following text:
156
+ - 'har ikke givet anledning til forbehold'
157
+ - 'has not given rise to reservations'
158
+ """
159
+ modelXbrl = val.modelXbrl
160
+ type_of_auditors_assistance_facts = modelXbrl.factsByQname.get(pluginData.typeOfAuditorAssistanceQn, set())
161
+ for auditor_fact in type_of_auditors_assistance_facts:
162
+ if (auditor_fact.xValid >= VALID and
163
+ (auditor_fact.xValue == pluginData.auditedExtendedReviewDanish or
164
+ auditor_fact.xValue == pluginData.auditedExtendedReviewEnglish)):
165
+ description_facts = modelXbrl.factsByQname.get(pluginData.descriptionOfQualificationsOfFinancialStatementsExtendedReviewQn, set())
166
+ for description_fact in description_facts:
167
+ if description_fact.xValid >= VALID:
168
+ for text in pluginData.hasNotGivenRiseToReservationsText:
169
+ if text in str(description_fact.xValue):
170
+ yield Validation.error(
171
+ codes="DBA.FR25",
172
+ msg=_("The value of DescriptionOfQualificationsOfFinancialStatementsExtendedReview must not "
173
+ "contain the text: \'{}\', when TypeOfAuditorAssistance is set to \'Erklæring om udvidet "
174
+ "gennemgang\' or \'Auditor's report on extended review\'").format(text),
175
+ modelObject=description_fact
176
+ )
177
+
178
+
179
+
180
+ @validation(
181
+ hook=ValidationHook.XBRL_FINALLY,
182
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
183
+ )
184
+ def rule_fr33(
185
+ pluginData: PluginValidationDataExtension,
186
+ val: ValidateXbrl,
187
+ *args: Any,
188
+ **kwargs: Any,
189
+ ) -> Iterable[Validation]:
190
+ """
191
+ DBA.FR33: For groups in accounting classes C and D, either Statement of changes in equity [hierarchy:fsa:StatementOfChangesInEquity] must have a minimum of three fields filled in from
192
+ [hierarchy:fsa:StatementOfChangesInEquity] or two fields in
193
+ Information on equity [hierarchy:fsa:DisclosureOfEquity].
194
+ """
195
+ reportingClass = False
196
+ classOfReportingEntityFacts = val.modelXbrl.factsByQname.get(pluginData.classOfReportingEntityQn, set())
197
+ for fact in classOfReportingEntityFacts:
198
+ if fact is not None and fact.xValid >= VALID:
199
+ if fact.xValue in pluginData.cClassOfReportingEntityEnums or fact.xValue in pluginData.dClassOfReportingEntityEnums:
200
+ reportingClass = True
201
+ break
202
+ if not reportingClass:
203
+ reportingClass = any(
204
+ fact and fact.xValid >= VALID
205
+ for fact in val.modelXbrl.factsByQname.get(pluginData.selectedElementsFromReportingClassCQn, set())
206
+ )
207
+ if not reportingClass:
208
+ reportingClass = any(
209
+ fact and fact.xValid >= VALID
210
+ for fact in val.modelXbrl.factsByQname.get(pluginData.selectedElementsFromReportingClassDQn, set())
211
+ )
212
+ if reportingClass:
213
+ if not minimumRequiredFactsFound(val.modelXbrl, pluginData.disclosureOfEquityQns, REQUIRED_DISCLOSURE_OF_EQUITY_FACTS):
214
+ if not minimumRequiredFactsFound(val.modelXbrl, pluginData.statementOfChangesInEquityQns, REQUIRED_STATEMENT_OF_CHANGES_IN_EQUITY_FACTS):
215
+ yield Validation.error(
216
+ codes="DBA.FR33",
217
+ msg=_("For groups in accounting classes C and D, either Statement of Changes in Equity '[hierarchy:fsa:StatementOfChangesInEquity]' must have a minimum of three fields filled in "
218
+ "Or two fields in Information on Equity [hierarchy:fsa:DisclosureOfEquity] ."),
219
+ modelObject=val.modelXbrl.modelDocument
220
+ )
221
+
222
+
223
+ @validation(
224
+ hook=ValidationHook.XBRL_FINALLY,
225
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
226
+ )
227
+ def rule_fr34(
228
+ pluginData: PluginValidationDataExtension,
229
+ val: ValidateXbrl,
230
+ *args: Any,
231
+ **kwargs: Any,
232
+ ) -> Iterable[Validation]:
233
+ """
234
+ DBA.FR34: If Equity does not equal 0 more fields are required. At least one field must be filled in on the balance sheet in addition to equity:
235
+ Assets, NoncurrentAssets, CurrentAssets, LongtermLiabilitiesOtherThanProvisions, ShorttermLiabilitiesOtherThanProvisions, LiabilitiesOtherThanProvisions, LiabilitiesAndEquity
236
+ """
237
+ equityFacts = val.modelXbrl.factsByQname.get(pluginData.equityQn, set())
238
+ nonZeroEquityFacts = []
239
+ for fact in equityFacts:
240
+ if fact.xValid >= VALID:
241
+ if fact.xValue != 0:
242
+ nonZeroEquityFacts.append(fact)
243
+ if nonZeroEquityFacts:
244
+ otherRequiredFactsQnames = [
245
+ pluginData.assetsQn, pluginData.noncurrentAssetsQn, pluginData.longtermLiabilitiesOtherThanProvisionsQn,
246
+ pluginData.shorttermLiabilitiesOtherThanProvisionsQn, pluginData.liabilitiesOtherThanProvisionsQn, pluginData.liabilitiesAndEquityQn
247
+ ]
248
+ hasEquityRequiredFacts = any(val.modelXbrl.factsByQname.get(factQname, set()) for factQname in otherRequiredFactsQnames)
249
+ if not hasEquityRequiredFacts:
250
+ yield Validation.error(
251
+ codes="DBA.FR34",
252
+ msg=_("If Equity is filled in and is not zero, at least one other field must also be filled in: "
253
+ "Assets, NoncurrentAssets, CurrentAssets, LongtermLiabilitiesOtherThanProvisions, ShorttermLiabilitiesOtherThanProvisions, "
254
+ "LiabilitiesOtherThanProvisions, LiabilitiesAndEquity."),
255
+ modelObject=nonZeroEquityFacts
256
+ )
257
+
258
+
259
+ @validation(
260
+ hook=ValidationHook.XBRL_FINALLY,
261
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
262
+ )
263
+ def rule_fr35(
264
+ pluginData: PluginValidationDataExtension,
265
+ val: ValidateXbrl,
266
+ *args: Any,
267
+ **kwargs: Any,
268
+ ) -> Iterable[Validation]:
269
+ """
270
+ DBA.FR35: The annual report does not contain a section on applied accounting practices. The annual report must
271
+ contain a section on the accounting practices used.
272
+ """
273
+ modelXbrl = val.modelXbrl
274
+ noDimensionFacts = set()
275
+ consolidatedDimensionFacts = set()
276
+ checkConsolidated = consolidatedDimensionExists(modelXbrl, pluginData.consolidatedSoloDimensionQn)
277
+ for concept_qn in pluginData.accountingPolicyConceptQns:
278
+ facts = modelXbrl.factsByQname.get(concept_qn, set())
279
+ for fact in facts:
280
+ if fact.xValid >= VALID and not fact.isNil:
281
+ if not fact.context.scenDimValues:
282
+ noDimensionFacts.add(fact)
283
+ if pluginData.consolidatedSoloDimensionQn in [dim.qname for dim in fact.context.scenDimValues.keys()]:
284
+ consolidatedDimensionFacts.add(fact)
285
+ if not checkConsolidated and len(noDimensionFacts) == 0:
286
+ yield Validation.error(
287
+ codes="DBA.FR35.noDimension",
288
+ msg=_("The annual report does not contain information on applied accounting practices. Please tag one of the following elements without a dimension: {}").format(
289
+ [qn.localName for qn in pluginData.accountingPolicyConceptQns]
290
+ ),
291
+ modelObject=val.modelXbrl.modelDocument
292
+ )
293
+ if checkConsolidated and len(consolidatedDimensionFacts) == 0:
294
+ yield Validation.error(
295
+ codes="DBA.FR35.consolidatedSoloDimension",
296
+ msg=_("The annual report does not contain information on applied accounting practices. Please tag one of the following elements with the ConsolidatedSoloDimension: {}").format(
297
+ [qn.localName for qn in pluginData.accountingPolicyConceptQns]
298
+ ),
299
+ modelObject=val.modelXbrl.modelDocument
300
+ )
301
+
302
+
303
+ @validation(
304
+ hook=ValidationHook.XBRL_FINALLY,
305
+ )
306
+ def rule_fr36(
307
+ pluginData: PluginValidationDataExtension,
308
+ val: ValidateXbrl,
309
+ *args: Any,
310
+ **kwargs: Any,
311
+ ) -> Iterable[Validation]:
312
+ """
313
+ DBA.FR36: arr:DescriptionsOfQualificationsOfReviewedFinancialStatements must not contain the following text:
314
+ - 'har ikke givet anledning til forbehold'
315
+ - 'has not given rise to reservations'
316
+ """
317
+ modelXbrl = val.modelXbrl
318
+ description_facts = modelXbrl.factsByQname.get(pluginData.descriptionsOfQualificationsOfReviewedFinancialStatementsQn, set())
319
+ for description_fact in description_facts:
320
+ if description_fact.xValid >= VALID:
321
+ for text in pluginData.hasNotGivenRiseToReservationsText:
322
+ if text in str(description_fact.xValue):
323
+ yield Validation.error(
324
+ codes="DBA.FR36",
325
+ msg=_("The value of DescriptionsOfQualificationsOfReviewedFinancialStatements must not contain the text: \'{}\'".format(text)),
326
+ modelObject=description_fact
327
+ )
328
+
329
+
330
+ @validation(
331
+ hook=ValidationHook.XBRL_FINALLY,
332
+ )
333
+ def rule_fr37(
334
+ pluginData: PluginValidationDataExtension,
335
+ val: ValidateXbrl,
336
+ *args: Any,
337
+ **kwargs: Any,
338
+ ) -> Iterable[Validation]:
339
+ """
340
+ DBA.FR37: arr:DescriptionOfQualificationsOfAssuranceEngagementPerformed must not contain the following text:
341
+ - 'har ikke givet anledning til forbehold'
342
+ - 'has not given rise to reservations'
343
+ """
344
+ modelXbrl = val.modelXbrl
345
+ description_facts = modelXbrl.factsByQname.get(pluginData.descriptionOfQualificationsOfAssuranceEngagementPerformedQn, set())
346
+ for description_fact in description_facts:
347
+ if description_fact.xValid >= VALID:
348
+ for text in pluginData.hasNotGivenRiseToReservationsText:
349
+ if text in str(description_fact.xValue):
350
+ yield Validation.error(
351
+ codes="DBA.FR37",
352
+ msg=_("The value of DescriptionOfQualificationsOfAssuranceEngagementPerformed must not contain the text: \'{}\'".format(text)),
353
+ modelObject=description_fact
354
+ )
355
+
356
+
357
+ @validation(
358
+ hook=ValidationHook.XBRL_FINALLY,
359
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
360
+ )
361
+ def rule_fr41(
362
+ pluginData: PluginValidationDataExtension,
363
+ val: ValidateXbrl,
364
+ *args: Any,
365
+ **kwargs: Any,
366
+ ) -> Iterable[Validation]:
367
+ """
368
+ DBA.FR41: Failure to fill in 'Tax on profit for the year' or 'Tax on ordinary profit'
369
+
370
+ If the result for the year is positive(fsa:ProfitLoss) (defined as greater than DKK 1000),
371
+ either Tax on the year's result (fsa:TaxExpense) or Tax on ordinary result
372
+ (fsa:TaxExpenseOnOrdinaryActivities) must be filled in.
373
+
374
+ The control does not look at I/S (partnership), K/S (limited partnership) and P/S
375
+ (partner company, like an LLC). (based on what legal form the identification number is
376
+ registered as in the business register).
377
+
378
+ Implementation: For each reporting period context that has a fsa:ProfitLoss fact above
379
+ the threshold, check if there is either a non-nil fsa:TaxExpense or fsa:TaxExpenseOnOrdinaryActivities
380
+ fact in the same context. If not, trigger an error.
381
+ """
382
+
383
+ # TODO: There appears to be criteria that exempt some filings from this rule.
384
+ # The criteria is based on the legal form of the company, which may or may not be
385
+ # something we can determine from the identification number and/or other instance data.
386
+ # Once we determine if/how that criteria can be implemented, we can add it here.
387
+
388
+ modelXbrl = val.modelXbrl
389
+ contextIds = {c.id for c in pluginData.getCurrentAndPreviousReportingPeriodContexts(modelXbrl)}
390
+ contextMap = {k: v for k, v in pluginData.contextFactMap(modelXbrl).items() if k in contextIds}
391
+ for contextId, factMap in contextMap.items():
392
+ profitLossFact = factMap.get(pluginData.profitLossQn)
393
+ if profitLossFact is None:
394
+ continue
395
+
396
+ if profitLossFact.xValid >= VALID and cast(decimal.Decimal, profitLossFact.xValue) <= pluginData.positiveProfitThreshold:
397
+ continue
398
+ taxExpenseFact = factMap.get(pluginData.taxExpenseQn)
399
+ if taxExpenseFact is not None and not taxExpenseFact.isNil:
400
+ continue
401
+ taxExpenseOnOrdinaryActivitiesFact = factMap.get(pluginData.taxExpenseOnOrdinaryActivitiesQn)
402
+ if taxExpenseOnOrdinaryActivitiesFact is not None and not taxExpenseOnOrdinaryActivitiesFact.isNil:
403
+ continue
404
+ yield Validation.warning(
405
+ codes='DBA.FR41',
406
+ msg=_("The annual report does not contain information on tax "
407
+ "on the year's profit. If the profit for the year in the income "
408
+ "statement is positive, either 'Tax on profit for the year' or "
409
+ "'Tax on ordinary profit' must be filled in."),
410
+ modelObject=profitLossFact,
411
+ )
412
+
413
+
414
+ @validation(
415
+ hook=ValidationHook.XBRL_FINALLY,
416
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
417
+ )
418
+ def rule_fr48(
419
+ pluginData: PluginValidationDataExtension,
420
+ val: ValidateXbrl,
421
+ *args: Any,
422
+ **kwargs: Any,
423
+ ) -> Iterable[Validation]:
424
+ """
425
+ DBA.FR48: Annual reports with a start date of 1/1 2016 or later may not use the fields:
426
+ 'Extraordinary result before tax',
427
+ 'Extraordinary income',
428
+ 'Extraordinary costs',
429
+ as §30 of the Annual Accounts Act is repealed."
430
+ """
431
+ disallowedFactQnames = [pluginData.extraordinaryCostsQn, pluginData.extraordinaryIncomeQn, pluginData.extraordinaryResultBeforeTaxQn]
432
+ foundFacts = []
433
+ for factQname in disallowedFactQnames:
434
+ facts = val.modelXbrl.factsByQname.get(factQname, set())
435
+ if len(facts) > 0:
436
+ foundFacts.append(facts)
437
+ if len(foundFacts) > 0:
438
+ yield Validation.warning(
439
+ codes="DBA.FR48",
440
+ msg=_("Annual reports with a start date of 1/1 2016 or later must not use the fields: "
441
+ "'Extraordinary profit before tax', 'Extraordinary income', 'Extraordinary costs'."),
442
+ modelObject=foundFacts
443
+ )
444
+
445
+
446
+ @validation(
447
+ hook=ValidationHook.XBRL_FINALLY,
448
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
449
+ )
450
+ def rule_fr52(
451
+ pluginData: PluginValidationDataExtension,
452
+ val: ValidateXbrl,
453
+ *args: Any,
454
+ **kwargs: Any,
455
+ ) -> Iterable[Validation]:
456
+ """
457
+ DBA.FR52: Any usage of fsa:ProposedExtraordinaryDividendRecognisedInLiabilities is prohibited.
458
+ """
459
+ modelXbrl = val.modelXbrl
460
+ facts = modelXbrl.factsByQname.get(pluginData.proposedExtraordinaryDividendRecognisedInLiabilitiesQn, set())
461
+ if len(facts) > 0:
462
+ yield Validation.warning(
463
+ codes='DBA.FR52',
464
+ msg=_("The concept ProposedExtraordinaryDividendRecognisedInLiabilities should not be used"),
465
+ modelObject=facts
466
+ )
467
+
468
+
469
+ @validation(
470
+ hook=ValidationHook.XBRL_FINALLY,
471
+ )
472
+ def rule_fr53(
473
+ pluginData: PluginValidationDataExtension,
474
+ val: ValidateXbrl,
475
+ *args: Any,
476
+ **kwargs: Any,
477
+ ) -> Iterable[Validation]:
478
+ """
479
+ DBA.FR53: Information is missing on the audit company's CVR no. and the audit firm's name.
480
+
481
+ The audit firm's CVR number and name of audit firm should be provided when (fsa:TypeOfAuditorAssistance) is
482
+ tagged with one of the following values:
483
+ - (Revisionspåtegning) / (Auditor's report on audited financial statements)
484
+ - (Erklæring om udvidet gennemgang) / (Auditor's report on extended review)
485
+ - (Den uafhængige revisors erklæringer (review)) / (The independent auditor's reports (Review))
486
+ - (Andre erklæringer med sikkerhed) / (The independent auditor's reports (Other assurance Reports))
487
+ """
488
+ modelXbrl = val.modelXbrl
489
+ facts = modelXbrl.factsByQname.get(pluginData.typeOfAuditorAssistanceQn, set())
490
+ for fact in facts:
491
+ if fact.xValid >= VALID:
492
+ if fact.xValue in [
493
+ pluginData.auditedFinancialStatementsDanish,
494
+ pluginData.auditedFinancialStatementsEnglish,
495
+ pluginData.auditedExtendedReviewDanish,
496
+ pluginData.auditedExtendedReviewEnglish,
497
+ pluginData.independentAuditorsReportDanish,
498
+ pluginData.independentAuditorsReportEnglish,
499
+ pluginData.auditedAssuranceReportsDanish,
500
+ pluginData.auditedAssuranceReportsEnglish
501
+ ]:
502
+ missing_concepts = []
503
+ cvr_facts = modelXbrl.factsByQname.get(pluginData.identificationNumberCvrOfAuditFirmQn, set())
504
+ auditor_name_facts = modelXbrl.factsByQname.get(pluginData.nameOfAuditFirmQn, set())
505
+ if len(cvr_facts) == 0:
506
+ missing_concepts.append(pluginData.identificationNumberCvrOfAuditFirmQn.localName)
507
+ if len(auditor_name_facts) == 0:
508
+ missing_concepts.append(pluginData.nameOfAuditFirmQn.localName)
509
+ if len(missing_concepts) > 0:
510
+ yield Validation.warning(
511
+ codes='DBA.FR53',
512
+ msg=_("The following concepts should be tagged: {} when {} is tagged with the value of {}").format(
513
+ ",".join(missing_concepts),
514
+ pluginData.typeOfAuditorAssistanceQn.localName,
515
+ fact.xValue
516
+ ),
517
+ modelObject=fact
518
+ )
519
+
520
+
521
+ @validation(
522
+ hook=ValidationHook.XBRL_FINALLY,
523
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
524
+ )
525
+ def rule_fr56(
526
+ pluginData: PluginValidationDataExtension,
527
+ val: ValidateXbrl,
528
+ *args: Any,
529
+ **kwargs: Any,
530
+ ) -> Iterable[Validation]:
531
+ """
532
+ DBA.FR56: Missing allocation of profit. The annual report must contain a
533
+ distribution of results.
534
+
535
+ Annual reports, etc. with a start date of 1/1 2016 or later must have a profit
536
+ allocation, if the profit (fsa:ProfitLoss) for the year is greater than 1000 or
537
+ less than -1000, cf. the Annual Accounts Act §§ 31 and 95 a.
538
+ """
539
+ modelXbrl = val.modelXbrl
540
+ contextIds = {c.id for c in pluginData.getCurrentAndPreviousReportingPeriodContexts(modelXbrl)}
541
+ profitLossFactsMap = getFactsGroupedByContextId(modelXbrl, pluginData.profitLossQn)
542
+ distributionFactsMap = getFactsGroupedByContextId(
543
+ modelXbrl,
544
+ *pluginData.distributionOfResultsQns,
545
+ )
546
+ for contextId, profitLossFacts in profitLossFactsMap.items():
547
+ if contextId not in contextIds:
548
+ continue
549
+ profitLossFact = None
550
+ for fact in profitLossFacts:
551
+ if fact.xValid >= VALID:
552
+ profitLossValue = cast(decimal.Decimal, fact.xValue)
553
+ if not (-pluginData.positiveProfitThreshold <= profitLossValue <= pluginData.positiveProfitThreshold):
554
+ profitLossFact = fact
555
+ break
556
+ if profitLossFact is None:
557
+ continue
558
+ distributionFacts = distributionFactsMap.get(contextId, [])
559
+ valid = False
560
+ for distributionsResultDistributionFact in distributionFacts:
561
+ if not distributionsResultDistributionFact.isNil:
562
+ valid = True
563
+ break
564
+ if not valid:
565
+ yield Validation.warning(
566
+ codes='DBA.FR56',
567
+ msg=_("The annual report does not contain a profit distribution. "
568
+ "The annual report must contain a profit and loss statement with a "
569
+ "distribution of profits."),
570
+ modelObject=profitLossFact
571
+ )
572
+
573
+
574
+ @validation(
575
+ hook=ValidationHook.XBRL_FINALLY,
576
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
577
+ )
578
+ def rule_fr57(
579
+ pluginData: PluginValidationDataExtension,
580
+ val: ValidateXbrl,
581
+ *args: Any,
582
+ **kwargs: Any,
583
+ ) -> Iterable[Validation]:
584
+ """
585
+ DBA.FR57.MarkingOfPeriod(Error):
586
+ Previous accounting period is marked(fsa:PrecedingReportingPeriodStartDate), even though it is the first accounting period.
587
+ The company has marked the previous accounting period, even though it is the first accounting period. If the previous accounting period is marked,
588
+ the control expects comparative figures.
589
+
590
+ DBA.FR57.ProfitLoss(Error):
591
+ The profit for the year (fsa:ProfitLoss) in the income statement must be filled in
592
+
593
+ DBA.FR57.Equity(Error):
594
+ The equity (fsa:Equity) in the balance sheet must be filled in
595
+
596
+ DBA.FR57.Assets(Error):
597
+ Assets (fsa:Assets) must be stated and must not be negative
598
+
599
+ DBA.FR57.LiabilitiesAndEquity(Error):
600
+ Liabilities (fsa:LiabilitiesAndEquity) must be stated and must not be negative
601
+
602
+ DBA.FR57.Equality(Error):
603
+ Assets (fsa:Assets) must equal Liabilities (fsa:LiabilitiesAndEquity)
604
+ """
605
+ currentStartDateFacts = getFactsWithDimension(val, pluginData.reportingPeriodStartDateQn, pluginData.consolidatedSoloDimensionQn, [pluginData.consolidatedMemberQn, pluginData.soloMemberQn])
606
+ currentEndDateFacts = getFactsWithDimension(val, pluginData.reportingPeriodEndDateQn, pluginData.consolidatedSoloDimensionQn, [pluginData.consolidatedMemberQn, pluginData.soloMemberQn])
607
+ currentGroupedFacts = groupFactsByContextHash(currentStartDateFacts.union(currentEndDateFacts))
608
+ precedingEndDateFacts = getFactsWithDimension(val, pluginData.precedingReportingPeriodEndDateQn, pluginData.consolidatedSoloDimensionQn, [pluginData.consolidatedMemberQn, pluginData.soloMemberQn])
609
+ precedingStartDateFacts = getFactsWithDimension(val, pluginData.precedingReportingPeriodStartDateQn, pluginData.consolidatedSoloDimensionQn, [pluginData.consolidatedMemberQn, pluginData.soloMemberQn])
610
+ precedingGroupedFacts = groupFactsByContextHash(precedingEndDateFacts.union(precedingStartDateFacts))
611
+ currentEndDateFact = None
612
+ currentStartDateFact = None
613
+ precedingStartDateFact = None
614
+ precedingEndDateFact = None
615
+ foundCurrentAssets = None
616
+ foundCurrentLiabilitiesAndEquity = None
617
+ foundPreviousAssets = None
618
+ foundPreviousLiabilitiesAndEquity = None
619
+ assetErrors = []
620
+ equityErrors = []
621
+ equalityErrorPairs = []
622
+ profitLossErrors = []
623
+ liabilitiesAndEquityErrors = []
624
+ negativeAssetFacts = []
625
+ negativeLiabilitiesAndEquityFacts = []
626
+ currentPeriodFound = any(len(facts) == 2 for facts in currentGroupedFacts.values())
627
+ precedingPeriodFound = any(len(facts) == 2 for facts in precedingGroupedFacts.values())
628
+ if precedingPeriodFound and not currentPeriodFound:
629
+ yield Validation.error(
630
+ codes="DBA.FR57.MarkingOfPeriod",
631
+ msg=_("The company has marked the previous accounting period, even though it is the first accounting period."),
632
+ )
633
+ elif currentPeriodFound:
634
+ assetsFacts = getFactsWithoutDimension(val, pluginData.assetsQn)
635
+ equityFacts = getFactsWithoutDimension(val, pluginData.equityQn)
636
+ profitLossFacts = getFactsWithoutDimension(val, pluginData.profitLossQn)
637
+ liabilitiesAndEquityFacts = getFactsWithoutDimension(val, pluginData.liabilitiesAndEquityQn)
638
+ for facts in currentGroupedFacts.values():
639
+ if len(facts) == 2:
640
+ for fact in facts:
641
+ if fact.qname == pluginData.reportingPeriodStartDateQn:
642
+ currentStartDateFact = fact
643
+ elif fact.qname == pluginData.reportingPeriodEndDateQn:
644
+ currentEndDateFact = fact
645
+ if currentEndDateFact is not None and currentStartDateFact is not None:
646
+ for asset in assetsFacts:
647
+ if asset.context.endDatetime - datetime.timedelta(days=1) == currentEndDateFact.xValue:
648
+ foundCurrentAssets = asset
649
+ if cast(int, asset.xValue) < 0:
650
+ negativeAssetFacts.append(asset)
651
+ for liabilitiesAndEquity in liabilitiesAndEquityFacts:
652
+ if liabilitiesAndEquity.context.endDatetime - datetime.timedelta(days=1) == currentEndDateFact.xValue:
653
+ foundCurrentLiabilitiesAndEquity = liabilitiesAndEquity
654
+ if cast(int, liabilitiesAndEquity.xValue) < 0:
655
+ negativeLiabilitiesAndEquityFacts.append(liabilitiesAndEquity)
656
+ foundCurrentEquity = any(
657
+ equity.context.endDatetime - datetime.timedelta(days=1) == currentEndDateFact.xValue
658
+ for equity in equityFacts
659
+ )
660
+ foundCurrentProfitLoss = any(
661
+ profitLoss.context.startDatetime == currentStartDateFact.xValue and
662
+ profitLoss.context.endDatetime - datetime.timedelta(days=1) == currentEndDateFact.xValue
663
+ for profitLoss in profitLossFacts
664
+ )
665
+ if foundCurrentAssets is not None and foundCurrentLiabilitiesAndEquity is not None:
666
+ if foundCurrentAssets.xValue != foundCurrentLiabilitiesAndEquity.xValue:
667
+ equalityErrorPairs.append((foundCurrentAssets, foundCurrentLiabilitiesAndEquity))
668
+ if foundCurrentAssets is None:
669
+ assetErrors.append(currentEndDateFact.xValue)
670
+ if foundCurrentEquity is False:
671
+ equityErrors.append(currentEndDateFact.xValue)
672
+ if foundCurrentLiabilitiesAndEquity is None:
673
+ liabilitiesAndEquityErrors.append(currentEndDateFact.xValue)
674
+ if foundCurrentProfitLoss is False:
675
+ profitLossErrors.append([currentStartDateFact.xValue, currentEndDateFact.xValue])
676
+ if precedingPeriodFound:
677
+ for context, facts in precedingGroupedFacts.items():
678
+ if len(facts) == 2:
679
+ for fact in facts:
680
+ if fact.qname == pluginData.precedingReportingPeriodStartDateQn:
681
+ precedingStartDateFact = fact
682
+ elif fact.qname == pluginData.precedingReportingPeriodEndDateQn:
683
+ precedingEndDateFact = fact
684
+ if precedingStartDateFact is not None and precedingEndDateFact is not None:
685
+ for asset in assetsFacts:
686
+ if asset.context.endDatetime - datetime.timedelta(days=1) == precedingEndDateFact.xValue:
687
+ foundPreviousAssets = asset
688
+ if cast(int, asset.xValue) < 0:
689
+ negativeAssetFacts.append(asset)
690
+ for liabilitiesAndEquity in liabilitiesAndEquityFacts:
691
+ if liabilitiesAndEquity.context.endDatetime - datetime.timedelta(days=1) == precedingEndDateFact.xValue:
692
+ foundPreviousLiabilitiesAndEquity = liabilitiesAndEquity
693
+ if cast(int, liabilitiesAndEquity.xValue) < 0:
694
+ negativeLiabilitiesAndEquityFacts.append(liabilitiesAndEquity)
695
+ foundPreviousEquity = any(
696
+ equity.context.endDatetime - datetime.timedelta(days=1) == precedingEndDateFact.xValue
697
+ for equity in equityFacts
698
+ )
699
+ foundPreviousProfitLoss = any(
700
+ profitLoss.context.startDatetime == precedingStartDateFact.xValue and
701
+ profitLoss.context.endDatetime - datetime.timedelta(days=1) == precedingEndDateFact.xValue
702
+ for profitLoss in profitLossFacts
703
+ )
704
+ if foundPreviousAssets is None:
705
+ assetErrors.append(precedingEndDateFact.xValue)
706
+ if foundPreviousEquity is False:
707
+ equityErrors.append(precedingEndDateFact.xValue)
708
+ if foundPreviousLiabilitiesAndEquity is None:
709
+ liabilitiesAndEquityErrors.append(precedingEndDateFact.xValue)
710
+ if foundPreviousProfitLoss is False:
711
+ profitLossErrors.append([precedingStartDateFact.xValue, precedingEndDateFact.xValue])
712
+ if not len(assetErrors) == 0:
713
+ yield Validation.error(
714
+ codes="DBA.FR57.Assets",
715
+ msg=_("Assets (fsa:Assets) must be stated and must not be negative. "
716
+ "There is a problem with the reporting period ending: %(periods)s"),
717
+ periods = ", ".join([cast(datetime.datetime, dt).strftime("%Y-%m-%d") for dt in assetErrors])
718
+ )
719
+ if not len(negativeAssetFacts) == 0:
720
+ for fact in negativeAssetFacts:
721
+ yield Validation.error(
722
+ codes="DBA.FR57.NegativeAssets",
723
+ msg=_("Assets (fsa:Assets) must not be negative. "
724
+ "Assets was tagged with the value: %(factValue)s"),
725
+ factValue = fact.effectiveValue,
726
+ modelObject=fact
727
+ )
728
+ if not len(equalityErrorPairs) == 0:
729
+ for pair in equalityErrorPairs:
730
+ yield Validation.error(
731
+ codes="DBA.FR57.Equality",
732
+ msg=_("The total of Assets (fsa:Assets) must be equal to the total of Liabilities and Equity (fsa:LiabilitiesAndEquity). "
733
+ "Assets: %(Assets)s Liabilities and Equity: %(LiabilitiesAndEquity)s"),
734
+ Assets=pair[0].effectiveValue,
735
+ LiabilitiesAndEquity=pair[1].effectiveValue,
736
+ modelObject=pair
737
+ )
738
+ if not len(equityErrors) == 0:
739
+ yield Validation.error(
740
+ codes="DBA.FR57.Equity",
741
+ msg=_("The equity (fsa:Equity) in the balance sheet must be filled in. There is a problem with the reporting period ending: %(periods)s"),
742
+ periods = ", ".join([cast(datetime.datetime, dt).strftime("%Y-%m-%d") for dt in equityErrors])
743
+ )
744
+ if not len(negativeLiabilitiesAndEquityFacts) == 0:
745
+ for fact in negativeLiabilitiesAndEquityFacts:
746
+ yield Validation.error(
747
+ codes="DBA.FR57.NegativeLiabilitiesAndEquity",
748
+ msg=_("Liabilities and Equity (fsa:LiabilitiesAndEquity) must not be negative. "
749
+ "Liabilities and Equity was tagged with the value: %(factValue)s"),
750
+ factValue = fact.effectiveValue,
751
+ modelObject=fact
752
+ )
753
+ if not len(liabilitiesAndEquityErrors) == 0:
754
+ yield Validation.error(
755
+ codes="DBA.FR57.LiabilitiesAndEquity",
756
+ msg=_("Liabilities and equity (fsa:LiabilitiesAndEquity) in the balance sheet must be filled in. "
757
+ "There is a problem with the reporting period ending: %(periods)s"),
758
+ periods = ", ".join([cast(datetime.datetime, dt).strftime("%Y-%m-%d") for dt in liabilitiesAndEquityErrors])
759
+ )
760
+ if not len(profitLossErrors) == 0:
761
+ for profitLossError in profitLossErrors:
762
+ yield Validation.error(
763
+ codes="DBA.FR57.ProfitLoss",
764
+ msg=_("The profit for the year (fsa:ProfitLoss) in the income statement must be filled in. "
765
+ "There is a problem with the reporting periods starting %(start)s and ending: %(end)s"),
766
+ start = profitLossError[0],
767
+ end = profitLossError[1]
768
+ )
769
+
770
+
771
+ @validation(
772
+ hook=ValidationHook.XBRL_FINALLY,
773
+ )
774
+ def rule_fr58(
775
+ pluginData: PluginValidationDataExtension,
776
+ val: ValidateXbrl,
777
+ *args: Any,
778
+ **kwargs: Any,
779
+ ) -> Iterable[Validation]:
780
+ """
781
+ DBA.FR58: If arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportAudit is tagged then one of the following concepts MUST also be tagged:
782
+ arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCriminalCodeAndFiscalTaxAndSubsidyLegislationAudit
783
+ arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCompaniesActOrEquivalentLegislationThatTheCompanyIsSubjectToAudit
784
+ arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyLegislationOnFinancialReportingIncludingAccountingAndStorageOfAccountingRecordsAudit
785
+ arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyOtherMattersAudit
786
+
787
+ """
788
+ modelXbrl = val.modelXbrl
789
+ indicatorFacts = modelXbrl.factsByQname.get(pluginData.reportingResponsibilitiesOnApprovedAuditorsReportAuditQn, set())
790
+ if len(indicatorFacts) > 0:
791
+ for qname in pluginData.declarationObligationQns:
792
+ facts = modelXbrl.factsByQname.get(qname, set())
793
+ if len(facts) > 0:
794
+ return
795
+ yield Validation.warning(
796
+ codes='DBA.FR58',
797
+ msg=_("When the field 'Declaration obligations according to the declaration order ' (ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportAudit) is completed, "
798
+ "one or more of the sub-items below must be indicated: "
799
+ "Declaration obligations according to the declaration order, including especially the Criminal Code as well as tax, levy and subsidy legislation (audit) (ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCriminalCodeAndFiscalTaxAndSubsidyLegislationAudit)"
800
+ "Declaration obligations according to the declaration order, including especially the company law or similar legislation laid down for the company (audit) (ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCompaniesActOrEquivalentLegislationThatTheCompanyIsSubjectToAudit)"
801
+ "Declaration obligations according to the declaration order, including especially the legislation on financial reporting, including on bookkeeping and storage of accounting material (audit) (ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyLegislationOnFinancialReportingIncludingAccountingAndStorageOfAccountingRecordsAudit)"
802
+ "Declaration obligations according to the declaration order, including other matters in particular (revision (ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyOtherMattersAudit)"),
803
+ )
804
+
805
+
806
+ @validation(
807
+ hook=ValidationHook.XBRL_FINALLY,
808
+ )
809
+ def rule_fr59(
810
+ pluginData: PluginValidationDataExtension,
811
+ val: ValidateXbrl,
812
+ *args: Any,
813
+ **kwargs: Any,
814
+ ) -> Iterable[Validation]:
815
+ """
816
+ DBA.FR59: When the annual report contains an audit report, which is when TypeOfAuditorAssistance = Revisionspåtegning / Auditor's report on audited financial statements, then the concept
817
+ arr:DescriptionOfQualificationsOfAuditedFinancialStatements must be filled in.
818
+ """
819
+ modelXbrl = val.modelXbrl
820
+ noDimensionDescriptionFacts = []
821
+ consolidatedDescriptionFacts = []
822
+ descriptionFacts = modelXbrl.factsByQname.get(pluginData.descriptionOfQualificationsOfAuditedFinancialStatementsQn, set())
823
+ for dFact in descriptionFacts:
824
+ if not dFact.context.scenDimValues:
825
+ noDimensionDescriptionFacts.append(dFact)
826
+ if pluginData.consolidatedSoloDimensionQn in [dim.qname for dim in dFact.context.scenDimValues.keys()]:
827
+ consolidatedDescriptionFacts.append(dFact)
828
+ checkConsolidated = consolidatedDimensionExists(modelXbrl, pluginData.consolidatedSoloDimensionQn)
829
+ noDimensionIndicatorFacts = []
830
+ consolidatedIndicatorFacts = []
831
+ auditorFacts = modelXbrl.factsByQname.get(pluginData.typeOfAuditorAssistanceQn, set())
832
+ for aFact in auditorFacts:
833
+ if aFact.xValid >= VALID and aFact.xValue in [pluginData.auditedFinancialStatementsDanish, pluginData.auditedFinancialStatementsEnglish]:
834
+ if not aFact.context.scenDimValues:
835
+ noDimensionIndicatorFacts.append(aFact)
836
+ if pluginData.consolidatedSoloDimensionQn in [dim.qname for dim in aFact.context.scenDimValues.keys()]:
837
+ consolidatedIndicatorFacts.append(aFact)
838
+ if not checkConsolidated and len(noDimensionIndicatorFacts) > 0 and len(noDimensionDescriptionFacts) == 0:
839
+ yield Validation.error(
840
+ codes='DBA.FR59.noDimension',
841
+ msg=_("DescriptionOfQualificationsOfAuditedFinancialStatement must be tagged without dimensions when {} is tagged with the value of {}").format(
842
+ pluginData.typeOfAuditorAssistanceQn.localName,
843
+ noDimensionIndicatorFacts[0].xValue),
844
+ modelObject=noDimensionIndicatorFacts[0])
845
+ if checkConsolidated and len(consolidatedIndicatorFacts) > 0 and len(consolidatedDescriptionFacts) == 0:
846
+ yield Validation.error(
847
+ codes='DBA.FR59.consolidatedSoloDimension',
848
+ msg=_("DescriptionOfQualificationsOfAuditedFinancialStatement must be tagged with ConsolidatedSoloDimension when {} is tagged with the value of {}").format(
849
+ pluginData.typeOfAuditorAssistanceQn.localName,
850
+ consolidatedIndicatorFacts[0].xValue),
851
+ modelObject=consolidatedIndicatorFacts[0])
852
+
853
+
854
+ @validation(
855
+ hook=ValidationHook.XBRL_FINALLY,
856
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
857
+ )
858
+ def rule_fr63(
859
+ pluginData: PluginValidationDataExtension,
860
+ val: ValidateXbrl,
861
+ *args: Any,
862
+ **kwargs: Any,
863
+ ) -> Iterable[Validation]:
864
+ """
865
+ DBA.FR63: Items in the balance sheet must be less than or equal to the balance sheet total. Assets must be
866
+ less than or equal to the balance sheet total. Applies to both the year's figures and comparative figures.
867
+ """
868
+ modelXbrl = val.modelXbrl
869
+ asset_facts = modelXbrl.factsByQname.get(pluginData.assetsQn, set())
870
+ for asset_fact in asset_facts:
871
+ if asset_fact.xValid >= VALID and isinstance(asset_fact.xValue, decimal.Decimal):
872
+ concepts_in_error = []
873
+ facts_in_error = []
874
+ for balance_sheet_qn in pluginData.balanceSheetQnLessThanOrEqualToAssets:
875
+ balance_sheet_qn_facts = modelXbrl.factsByQname.get(balance_sheet_qn, set())
876
+ for balance_sheet_qn_fact in balance_sheet_qn_facts:
877
+ if (balance_sheet_qn_fact.xValid >= VALID and
878
+ isinstance(balance_sheet_qn_fact.xValue, decimal.Decimal) and
879
+ asset_fact.contextID == balance_sheet_qn_fact.contextID and
880
+ asset_fact.xValue < balance_sheet_qn_fact.xValue):
881
+ concepts_in_error.append(balance_sheet_qn.localName)
882
+ facts_in_error.append(balance_sheet_qn_fact)
883
+ if len(facts_in_error) > 0:
884
+ yield Validation.error(
885
+ codes='DBA.FR63',
886
+ msg=_("The annual report contains items in the balance sheet (year's figures or comparison "
887
+ "figures) which are greater than the balance sheet total(Assets). The following "
888
+ "fields do not comply: {}").format(concepts_in_error),
889
+ modelObject=facts_in_error
890
+ )
891
+
892
+
893
+ @validation(
894
+ hook=ValidationHook.XBRL_FINALLY,
895
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
896
+ )
897
+ def rule_fr71(
898
+ pluginData: PluginValidationDataExtension,
899
+ val: ValidateXbrl,
900
+ *args: Any,
901
+ **kwargs: Any,
902
+ ) -> Iterable[Validation]:
903
+ """
904
+ DBA.FR71: The accounts must not contain negative personnel costs
905
+
906
+ Costs must be reported as positive numbers in the XBRL file. It indicates that there is an error in the setup of the XBRL file.
907
+ The following elements are checked:
908
+ • Personnel costs (fsa:EmployeeBenefitsExpense),
909
+ • Salaries (fsa:WagesAndSalaries)
910
+ • Pensions (fsa:PostemploymentBenefitExpense)
911
+ • Other personnel costs (fsa:OtherEmployeeExpense)
912
+
913
+ Both on the year's figures and comparative figures."
914
+ """
915
+ modelXbrl = val.modelXbrl
916
+ facts_in_error = []
917
+ for cost_qn in [
918
+ pluginData.employeeBenefitsExpenseQn,
919
+ pluginData.wagesAndSalariesQn,
920
+ pluginData.postemploymentBenefitExpenseQn,
921
+ pluginData.otherEmployeeExpenseQn
922
+ ]:
923
+ facts = modelXbrl.factsByQname.get(cost_qn, set())
924
+ for fact in facts:
925
+ if fact.xValid >= VALID and isinstance(fact.xValue, decimal.Decimal) and fact.xValue < 0:
926
+ facts_in_error.append(fact)
927
+ if len(facts_in_error) > 0:
928
+ yield Validation.warning(
929
+ codes="DBA.FR71",
930
+ msg=_("Costs must be reported as positive numbers in the XBRL file"),
931
+ modelObject=facts_in_error
932
+ )
933
+
934
+
935
+ @validation(
936
+ hook=ValidationHook.XBRL_FINALLY,
937
+ )
938
+ def rule_fr72(
939
+ pluginData: PluginValidationDataExtension,
940
+ val: ValidateXbrl,
941
+ *args: Any,
942
+ **kwargs: Any,
943
+ ) -> Iterable[Validation]:
944
+ """
945
+ DBA.FR72: If the value of arr:TypeOfBasisForModifiedOpinionOnFinancialStatementsReview is set to one of the following:
946
+ Grundlag for konklusion med forbehold // Basis for Qualified Opinion
947
+ Grundlag for afkræftende konklusion // Basis for Adverse Opinion
948
+ Grundlag for manglende konklusion // Basis for Disclaimer of Opinion
949
+ then arr:DescriptionsOfQualificationsOfReviewedFinancialStatements must be tagged.
950
+ """
951
+ modelXbrl = val.modelXbrl
952
+ review_facts = modelXbrl.factsByQname.get(pluginData.typeOfBasisForModifiedOpinionOnFinancialStatementsReviewQn, set())
953
+ for review_fact in review_facts:
954
+ if review_fact.xValid >= VALID and review_fact.xValue in [
955
+ pluginData.basisForAdverseOpinionDanish,
956
+ pluginData.basisForAdverseOpinionEnglish,
957
+ pluginData.basisForDisclaimerOpinionDanish,
958
+ pluginData.basisForDisclaimerOpinionEnglish,
959
+ pluginData.basisForQualifiedOpinionDanish,
960
+ pluginData.basisForQualifiedOpinionEnglish,
961
+ ]:
962
+ description_facts = modelXbrl.factsByQname.get(pluginData.descriptionsOfQualificationsOfReviewedFinancialStatementsQn, set())
963
+ if len(description_facts) == 0:
964
+ yield Validation.warning(
965
+ codes='DBA.FR72',
966
+ msg=_("DescriptionsOfQualificationsOfReviewedFinancialStatements must be tagged when {} is tagged with the value of {}").format(
967
+ pluginData.typeOfBasisForModifiedOpinionOnFinancialStatementsReviewQn.localName,
968
+ review_fact.xValue
969
+ ),
970
+ modelObject=review_fact
971
+ )
972
+
973
+
974
+ @validation(
975
+ hook=ValidationHook.XBRL_FINALLY,
976
+ )
977
+ def rule_fr73(
978
+ pluginData: PluginValidationDataExtension,
979
+ val: ValidateXbrl,
980
+ *args: Any,
981
+ **kwargs: Any,
982
+ ) -> Iterable[Validation]:
983
+ """
984
+ DBA.FR73: If arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsExtendedReview is tagged then one of the following concepts MUST also be tagged:
985
+ arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCriminalCodeAndFiscalTaxAndSubsidyLegislationExtendedReview
986
+ arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCompaniesActOrEquivalentLegislationThatTheCompanyIsSubjectToExtendedReview
987
+ arr:ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyLegislationOnFinancialReportingInApplication
988
+ """
989
+ modelXbrl = val.modelXbrl
990
+ indicatorFacts = modelXbrl.factsByQname.get(pluginData.reportingResponsibilitiesOnApprovedAuditorsReportsExtendedReviewQn, set())
991
+ if len(indicatorFacts) > 0:
992
+ for qname in pluginData.reportingObligationQns:
993
+ facts = modelXbrl.factsByQname.get(qname, set())
994
+ if len(facts) > 0:
995
+ return
996
+ yield Validation.warning(
997
+ codes='DBA.FR73',
998
+ msg=_("When the field ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsExtendedReview is completed "
999
+ "one or more of the sub-items below must be indicated: "
1000
+ "ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCriminalCodeAndFiscalTaxAndSubsidyLegislationExtendedReview "
1001
+ "ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyTheCompaniesActOrEquivalentLegislationThatTheCompanyIsSubjectToExtendedReview "
1002
+ "ReportingResponsibilitiesAccordingToTheDanishExecutiveOrderOnApprovedAuditorsReportsEspeciallyLegislationOnFinancialReportingInApplication."),
1003
+ )
1004
+
1005
+
1006
+
1007
+ @validation(
1008
+ hook=ValidationHook.XBRL_FINALLY,
1009
+ )
1010
+ def rule_fr74(
1011
+ pluginData: PluginValidationDataExtension,
1012
+ val: ValidateXbrl,
1013
+ *args: Any,
1014
+ **kwargs: Any,
1015
+ ) -> Iterable[Validation]:
1016
+ """
1017
+ DBA.FR74a:Provisions [hierarchy:fsa:Provisions] and underlying fields must each be less than or equal to the balance sheet total (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity).
1018
+ DBA.FR74b: Liabilities (fsa:LiabilitiesOtherThanProvisions) must be less than or equal to total assets (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity).
1019
+ """
1020
+ groupedFacts = getFactsGroupedByContextId(val.modelXbrl, pluginData.equityQn, pluginData.liabilitiesAndEquityQn, pluginData.provisionsQn, pluginData.liabilitiesOtherThanProvisionsQn)
1021
+ for contextID, facts in groupedFacts.items():
1022
+ equityFact = None
1023
+ liabilityFact = None
1024
+ liabilityOtherFact = None
1025
+ provisionFact = None
1026
+ for fact in facts:
1027
+ if fact.qname == pluginData.equityQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
1028
+ equityFact = fact
1029
+ elif fact.qname == pluginData.liabilitiesQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
1030
+ liabilityFact = fact
1031
+ elif fact.qname == pluginData.provisionsQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
1032
+ provisionFact = fact
1033
+ elif fact.qname == pluginData.liabilitiesOtherThanProvisionsQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
1034
+ liabilityOtherFact = fact
1035
+ if equityFact is not None and liabilityFact is not None and provisionFact is not None and equityFact.xValid >= VALID and liabilityFact.xValid >= VALID and provisionFact.xValid >= VALID:
1036
+ if not cast(decimal.Decimal, liabilityFact.xValue) - cast(decimal.Decimal, equityFact.xValue) >= cast(decimal.Decimal, provisionFact.xValue) - ROUNDING_MARGIN:
1037
+ yield Validation.error(
1038
+ codes="DBA.FR74a",
1039
+ msg=_("Provisions (fsa:Provisions) must be less than or equal to the balance sheet total (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity). "
1040
+ "LiabilitiesAndEquity: %(liabilities)s, Equity: %(equity)s, Provisions: %(provisions)s"),
1041
+ equity=equityFact.effectiveValue,
1042
+ liabilities=liabilityFact.effectiveValue,
1043
+ provisions=provisionFact.effectiveValue,
1044
+ modelObject=[equityFact, liabilityFact, provisionFact]
1045
+ )
1046
+ if equityFact is not None and liabilityOtherFact is not None and liabilityFact is not None and equityFact.xValid >= VALID and liabilityFact.xValid >= VALID and liabilityOtherFact.xValid >= VALID:
1047
+ if not cast(decimal.Decimal, liabilityFact.xValue) - cast(decimal.Decimal, equityFact.xValue) >= cast(decimal.Decimal, liabilityOtherFact.xValue) - ROUNDING_MARGIN:
1048
+ yield Validation.error(
1049
+ codes="DBA.FR74b",
1050
+ msg=_("Liabilities (fsa:LiabilitiesOtherThanProvisions) must be less than or equal to total assets (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity). "
1051
+ "LiabilitiesAndEquity: %(liabilities)s, Equity: %(equity)s, LiabilitiesOtherThanProvisions: %(liabilityOther)s"),
1052
+ equity=equityFact.effectiveValue,
1053
+ liabilityOther=liabilityOtherFact.effectiveValue,
1054
+ liabilities=liabilityFact.effectiveValue,
1055
+ modelObject=[equityFact, liabilityFact, liabilityOtherFact]
1056
+ )
1057
+
1058
+
1059
+ @validation(
1060
+ hook=ValidationHook.XBRL_FINALLY,
1061
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
1062
+ )
1063
+ def rule_fr75(
1064
+ pluginData: PluginValidationDataExtension,
1065
+ val: ValidateXbrl,
1066
+ *args: Any,
1067
+ **kwargs: Any,
1068
+ ) -> Iterable[Validation]:
1069
+ """
1070
+ DBA.FR75: The company must provide information on the number of employees. The rule is activated if personnel costs (fsa:EmployeeBenefitsExpense) or salaries (fsa:WagesAndSalaries) are greater
1071
+ than DKK 200,000, and no number of employees (fsa:AverageNumberOfEmployees) has been specified.
1072
+ """
1073
+ groupedFacts = getFactsGroupedByContextId(val.modelXbrl, pluginData.employeeBenefitsExpenseQn, pluginData.wagesAndSalariesQn, pluginData.averageNumberOfEmployeesQn)
1074
+ for contextID, facts in groupedFacts.items():
1075
+ benefitsFact = None
1076
+ wagesFact = None
1077
+ employeesFact = None
1078
+ for fact in facts:
1079
+ if fact.qname == pluginData.employeeBenefitsExpenseQn and fact.unit.id.upper() == DANISH_CURRENCY_ID and fact.xValid >= VALID and cast(decimal.Decimal, fact.xValue) >= PERSONNEL_EXPENSE_THRESHOLD:
1080
+ benefitsFact = fact
1081
+ elif fact.qname == pluginData.wagesAndSalariesQn and fact.unit.id.upper() == DANISH_CURRENCY_ID and fact.xValid >= VALID and cast(decimal.Decimal, fact.xValue) >= PERSONNEL_EXPENSE_THRESHOLD:
1082
+ wagesFact = fact
1083
+ elif fact.qname == pluginData.averageNumberOfEmployeesQn and fact.xValid >= VALID and cast(decimal.Decimal, fact.xValue) > 0:
1084
+ employeesFact = fact
1085
+ if (benefitsFact is not None or wagesFact is not None) and employeesFact is None:
1086
+ yield Validation.error(
1087
+ codes="DBA.FR75",
1088
+ msg=_("The company must provide information on the number of employees. The rule is activated if personnel costs (fsa:EmployeeBenefitsExpense) "
1089
+ "or salaries (fsa:WagesAndSalaries) are greater than DKK 200,000, and no number of employees (fsa:AverageNumberOfEmployees) has been specified."),
1090
+ modelObject=[benefitsFact, wagesFact]
1091
+ )
1092
+
1093
+
1094
+ @validation(
1095
+ hook=ValidationHook.XBRL_FINALLY,
1096
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
1097
+ )
1098
+ def rule_fr77(
1099
+ pluginData: PluginValidationDataExtension,
1100
+ val: ValidateXbrl,
1101
+ *args: Any,
1102
+ **kwargs: Any,
1103
+ ) -> Iterable[Validation]:
1104
+ """
1105
+ DBA.FR77b: Long-term liabilities (fsa:LongtermLiabilitiesOtherThanProvisions) must be less than or equal to the balance sheet total (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity).
1106
+ DBA.FR77b: Short-term liabilities (fsa:ShorttermLiabilitiesOtherThanProvisions) must be less than or equal to the balance sheet total (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity).
1107
+ """
1108
+ groupedFacts = getFactsGroupedByContextId(val.modelXbrl, pluginData.equityQn, pluginData.liabilitiesAndEquityQn, pluginData.longtermLiabilitiesOtherThanProvisionsQn, pluginData.shorttermLiabilitiesOtherThanProvisionsQn)
1109
+ for contextID, facts in groupedFacts.items():
1110
+ equityFact = None
1111
+ liabilityFact = None
1112
+ longLiabilityFact = None
1113
+ shortLiabilityFact = None
1114
+ for fact in facts:
1115
+ if fact.qname == pluginData.equityQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
1116
+ equityFact = fact
1117
+ elif fact.qname == pluginData.liabilitiesQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
1118
+ liabilityFact = fact
1119
+ elif fact.qname == pluginData.longtermLiabilitiesOtherThanProvisionsQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
1120
+ longLiabilityFact = fact
1121
+ elif fact.qname == pluginData.shorttermLiabilitiesOtherThanProvisionsQn and fact.unit.id.upper() == DANISH_CURRENCY_ID:
1122
+ shortLiabilityFact = fact
1123
+ if equityFact is not None and liabilityFact is not None and longLiabilityFact is not None and equityFact.xValid >= VALID and liabilityFact.xValid >= VALID and longLiabilityFact.xValid >= VALID:
1124
+ if not cast(decimal.Decimal, liabilityFact.xValue) - cast(decimal.Decimal, equityFact.xValue) >= cast(decimal.Decimal, longLiabilityFact.xValue) - ROUNDING_MARGIN:
1125
+ yield Validation.error(
1126
+ codes="DBA.FR77a",
1127
+ msg=_("Long-term liabilities (fsa:LongtermLiabilitiesOtherThanProvisions) must be less than or equal to the balance sheet total (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity). "
1128
+ "LiabilitiesAndEquity: %(liabilities)s, Equity: %(equity)s, LongtermLiabilitiesOtherThanProvisions: %(longLiabilities)s"),
1129
+ equity=equityFact.effectiveValue,
1130
+ liabilities=liabilityFact.effectiveValue,
1131
+ longLiabilities=longLiabilityFact.effectiveValue,
1132
+ modelObject=[equityFact, liabilityFact, longLiabilityFact]
1133
+ )
1134
+ if equityFact is not None and liabilityFact is not None and shortLiabilityFact is not None and equityFact.xValid >= VALID and liabilityFact.xValid >= VALID and shortLiabilityFact.xValid >= VALID:
1135
+ if not cast(decimal.Decimal, liabilityFact.xValue) - cast(decimal.Decimal, equityFact.xValue) >= cast(decimal.Decimal, shortLiabilityFact.xValue) - ROUNDING_MARGIN:
1136
+ yield Validation.error(
1137
+ codes="DBA.FR77b",
1138
+ msg=_("Short-term liabilities (fsa:ShorttermLiabilitiesOtherThanProvisions) must be less than or equal to the balance sheet total (fsa:LiabilitiesAndEquity) minus equity (fsa:Equity). "
1139
+ "LiabilitiesAndEquity: %(liabilities)s, Equity: %(equity)s, ShorttermLiabilitiesOtherThanProvisions: %(shortLiabilities)s"),
1140
+ equity=equityFact.effectiveValue,
1141
+ liabilities=liabilityFact.effectiveValue,
1142
+ shortLiabilities=shortLiabilityFact.effectiveValue,
1143
+ modelObject=[equityFact, liabilityFact, shortLiabilityFact]
1144
+ )
1145
+
1146
+
1147
+ @validation(
1148
+ hook=ValidationHook.XBRL_FINALLY,
1149
+ )
1150
+ def rule_fr81(
1151
+ pluginData: PluginValidationDataExtension,
1152
+ val: ValidateXbrl,
1153
+ *args: Any,
1154
+ **kwargs: Any,
1155
+ ) -> Iterable[Validation]:
1156
+ """
1157
+ DBA.FR81: The language used must be stated. There must be at least one fact with either the Danish
1158
+ (`da`) or English (`en`) `lang` attribute in the digital file (the XBRL file or the IXBRL file).
1159
+
1160
+ Implementation: Check all facts for at least one `lang` attribute that must be either `da` or `en`.
1161
+ """
1162
+ has_valid_lang = any(fact.xmlLang in {'da', 'en'} for fact in val.modelXbrl.facts)
1163
+ if not has_valid_lang:
1164
+ yield Validation.error(
1165
+ codes="DBA.FR81",
1166
+ msg=_("The digital annual report does not contain a technical indication of the language used. There "
1167
+ "must be at least one fact, with either the Danish ('da') or English ('en') language attribute."),
1168
+ modelObject=[val.modelXbrl.modelDocument]
1169
+ )
1170
+
1171
+
1172
+ @validation(
1173
+ hook=ValidationHook.XBRL_FINALLY,
1174
+ disclosureSystems=MULTI_TARGET_DISCLOSURE_SYSTEMS,
1175
+ )
1176
+ def rule_fr82(
1177
+ pluginData: PluginValidationDataExtension,
1178
+ val: ValidateXbrl,
1179
+ *args: Any,
1180
+ **kwargs: Any,
1181
+ ) -> Iterable[Validation]:
1182
+ """
1183
+ DBA.FR82: This control blocks reporting in XBRL and thus only allows reporting with inlineXBRL for DK ESEF.
1184
+ """
1185
+ if (val.modelXbrl.modelDocument is not None and
1186
+ val.modelXbrl.modelDocument.type not in [ModelDocument.Type.INLINEXBRL, ModelDocument.Type.INLINEXBRLDOCUMENTSET]):
1187
+ yield Validation.error(
1188
+ codes="DBA.FR82",
1189
+ msg=_("The digital annual report must be reported in inlineXBRL for DK ESEF."),
1190
+ modelObject=[val.modelXbrl.modelDocument]
1191
+ )
1192
+
1193
+
1194
+ @validation(
1195
+ hook=ValidationHook.XBRL_FINALLY,
1196
+ disclosureSystems=STAND_ALONE_DISCLOSURE_SYSTEMS,
1197
+ )
1198
+ def rule_fr83(
1199
+ pluginData: PluginValidationDataExtension,
1200
+ val: ValidateXbrl,
1201
+ *args: Any,
1202
+ **kwargs: Any,
1203
+ ) -> Iterable[Validation]:
1204
+ """
1205
+ DBA.FR83: This control blocks reporting in XBRL and thus only allows reporting with inlineXBRL for DK GAAP.
1206
+ """
1207
+ if (val.modelXbrl.modelDocument is not None and
1208
+ val.modelXbrl.modelDocument.type not in [ModelDocument.Type.INLINEXBRL, ModelDocument.Type.INLINEXBRLDOCUMENTSET]):
1209
+ yield Validation.error(
1210
+ codes="DBA.FR83",
1211
+ msg=_("The digital annual report must be reported in inlineXBRL for DK GAAP."),
1212
+ modelObject=[val.modelXbrl.modelDocument]
1213
+ )
1214
+
1215
+
1216
+ @validation(
1217
+ hook=ValidationHook.XBRL_FINALLY,
1218
+ )
1219
+ def rule_fr87(
1220
+ pluginData: PluginValidationDataExtension,
1221
+ val: ValidateXbrl,
1222
+ *args: Any,
1223
+ **kwargs: Any,
1224
+ ) -> Iterable[Validation]:
1225
+ """
1226
+ DBA.FR87: InlineXBRL must not link to external CSS. The IXBRL file must have all CSS inline.
1227
+ """
1228
+ modelXbrl = val.modelXbrl
1229
+ _xhtmlNs = "{{{}}}".format(xhtml)
1230
+ _xhtmlNsLen = len(_xhtmlNs)
1231
+ if hasattr(modelXbrl, "ixdsHtmlElements"):
1232
+ for ixdsHtmlRootElt in modelXbrl.ixdsHtmlElements: # ix root elements for all ix docs in IXDS
1233
+ ixNStag = ixdsHtmlRootElt.modelDocument.ixNStag
1234
+ ixTags = set(ixNStag + ln for ln in ("nonNumeric", "nonFraction", "references", "relationship"))
1235
+ ixTargets = set()
1236
+ for ixdsHtmlRootElt in modelXbrl.ixdsHtmlElements:
1237
+ for elt in ixdsHtmlRootElt.iter():
1238
+ eltTag = elt.tag
1239
+ if eltTag in ixTags:
1240
+ ixTargets.add( elt.get("target") )
1241
+ else:
1242
+ if eltTag.startswith(_xhtmlNs):
1243
+ eltTag = eltTag[_xhtmlNsLen:]
1244
+ if eltTag == "link" and elt.get("type") == "text/css":
1245
+ yield Validation.error(
1246
+ codes='DBA.FR87',
1247
+ msg=_("CSS must be embedded in the inline XBRL document. The document contains a link to an external CSS file."),
1248
+ modelObject=elt,
1249
+ )
1250
+
1251
+
1252
+ @validation(
1253
+ hook=ValidationHook.XBRL_FINALLY,
1254
+ )
1255
+ def rule_fr89(
1256
+ pluginData: PluginValidationDataExtension,
1257
+ val: ValidateXbrl,
1258
+ *args: Any,
1259
+ **kwargs: Any,
1260
+ ) -> Iterable[Validation]:
1261
+ """
1262
+ DBA.FR89: If ClassOfReportingEntity is one of the following values:
1263
+
1264
+ Regnskabsklasse C, mellemstor virksomhed // Reporting class C, medium-size enterprise
1265
+ Regnskabsklasse C, stor virksomhed // Reporting class C, large enterprise
1266
+ Regnskabsklasse D // Reporting class D
1267
+ Then TypeOfAuditorAssistance should be: Revisionspåtegning // Auditor's report on audited financial statements
1268
+ """
1269
+ if pluginData.isAnnualReport(val.modelXbrl):
1270
+ auditorFacts = val.modelXbrl.factsByQname.get(pluginData.typeOfAuditorAssistanceQn, set())
1271
+ for auditorFact in auditorFacts:
1272
+ if auditorFact.xValid >= VALID and auditorFact.xValue in [
1273
+ pluginData.auditedFinancialStatementsDanish,
1274
+ pluginData.auditedFinancialStatementsEnglish
1275
+ ]:
1276
+ return
1277
+ classFacts = []
1278
+ facts = val.modelXbrl.factsByQname.get(pluginData.classOfReportingEntityQn, set())
1279
+ for fact in facts:
1280
+ if fact.xValid >= VALID and fact.xValue in [
1281
+ pluginData.reportingClassCLargeDanish,
1282
+ pluginData.reportingClassCLargeEnglish,
1283
+ pluginData.reportingClassCMediumDanish,
1284
+ pluginData.reportingClassCMediumEnglish,
1285
+ pluginData.reportingClassDDanish,
1286
+ pluginData.reportingClassDEnglish
1287
+ ]:
1288
+ classFacts.append(fact)
1289
+ if len(classFacts) > 0:
1290
+ yield Validation.error(
1291
+ codes='DBA.FR89',
1292
+ msg=_("TypeOfAuditorAssistance should be {} or {} when {} is tagged with the value of {}.").format(
1293
+ pluginData.auditedFinancialStatementsDanish,
1294
+ pluginData.auditedFinancialStatementsEnglish,
1295
+ pluginData.classOfReportingEntityQn.localName,
1296
+ classFacts[0].xValue
1297
+ ),
1298
+ modelObject=classFacts[0]
1299
+ )
1300
+
1301
+
1302
+ @validation(
1303
+ hook=ValidationHook.XBRL_FINALLY,
1304
+ )
1305
+ def rule_fr91(
1306
+ pluginData: PluginValidationDataExtension,
1307
+ val: ValidateXbrl,
1308
+ *args: Any,
1309
+ **kwargs: Any,
1310
+ ) -> Iterable[Validation]:
1311
+ """
1312
+ DBA.FR91: If the annual report contains information about both the general meeting date
1313
+ (gsd:DateOfGeneralMeeting) and the annual accounts meeting date (gsd:DateOfApprovalOfAnnualReport), the values must be the same.
1314
+ """
1315
+ if pluginData.isAnnualReport(val.modelXbrl):
1316
+ approvalOfReportFact = None
1317
+ generalMeetingFact = None
1318
+ approvalFacts = (val.modelXbrl.factsByQname.get(pluginData.dateOfApprovalOfAnnualReportQn, set()))
1319
+ if len(approvalFacts) > 0:
1320
+ approvalOfReportFact = next(iter(approvalFacts), None)
1321
+ meetingFacts = val.modelXbrl.factsByQname.get(pluginData.dateOfGeneralMeetingQn, set())
1322
+ if len(meetingFacts) > 0:
1323
+ generalMeetingFact = next(iter(meetingFacts), None)
1324
+ if generalMeetingFact is not None and generalMeetingFact.xValid >= VALID and approvalOfReportFact is not None and approvalOfReportFact.xValid >= VALID and generalMeetingFact.xValue != approvalOfReportFact.xValue:
1325
+ yield Validation.error(
1326
+ codes='DBA.FR91',
1327
+ msg=_("The annual report contains information about both the general meeting date (gsd:DateOfGeneralMeeting) and the annual accounts meeting date (gsd:DateOfApprovalOfAnnualReport), the values must be the same."),
1328
+ modelObject=[generalMeetingFact, approvalOfReportFact]
1329
+ )
1330
+
1331
+
1332
+ @validation(
1333
+ hook=ValidationHook.XBRL_FINALLY,
1334
+ )
1335
+ def rule_fr92(
1336
+ pluginData: PluginValidationDataExtension,
1337
+ val: ValidateXbrl,
1338
+ *args: Any,
1339
+ **kwargs: Any,
1340
+ ) -> Iterable[Validation]:
1341
+ """
1342
+ DBA.FR92: Information is missing on the auditor's signature date.
1343
+
1344
+ The auditor's signature date must be provided when (fsa:TypeOfAuditorAssistance) is
1345
+ tagged with one of the following values:
1346
+ - (Revisionspåtegning) / (Auditor's report on audited financial statements)
1347
+ - (Erklæring om udvidet gennemgang) / (Auditor's report on extended review)
1348
+ - (Den uafhængige revisors erklæringer (review)) / (The independent auditor's reports (Review))
1349
+ - (Andre erklæringer med sikkerhed) / (The independent auditor's reports (Other assurance Reports))
1350
+ - (Andre erklæringer uden sikkerhed) / (Auditor's reports (Other non-assurance reports))
1351
+ """
1352
+ modelXbrl = val.modelXbrl
1353
+ facts = modelXbrl.factsByQname.get(pluginData.typeOfAuditorAssistanceQn, set())
1354
+ for fact in facts:
1355
+ if fact.xValid >= VALID:
1356
+ if fact.xValue in [
1357
+ pluginData.auditedFinancialStatementsDanish,
1358
+ pluginData.auditedFinancialStatementsEnglish,
1359
+ pluginData.auditedExtendedReviewDanish,
1360
+ pluginData.auditedExtendedReviewEnglish,
1361
+ pluginData.independentAuditorsReportDanish,
1362
+ pluginData.independentAuditorsReportEnglish,
1363
+ pluginData.auditedAssuranceReportsDanish,
1364
+ pluginData.auditedAssuranceReportsEnglish,
1365
+ pluginData.auditedNonAssuranceReportsDanish,
1366
+ pluginData.auditedNonAssuranceReportsEnglish,
1367
+ ]:
1368
+ signature_facts = modelXbrl.factsByQname.get(pluginData.signatureOfAuditorsDateQn, set())
1369
+ if len(signature_facts) == 0:
1370
+ yield Validation.error(
1371
+ codes='DBA.FR92',
1372
+ msg=_("SignatureOfAuditorsDate must be tagged when {} is tagged with the value of {}").format(
1373
+ pluginData.typeOfAuditorAssistanceQn.localName,
1374
+ fact.xValue
1375
+ ),
1376
+ modelObject=fact
1377
+ )