arelle-release 2.37.54__py3-none-any.whl → 2.37.56__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.
Potentially problematic release.
This version of arelle-release might be problematic. Click here for more details.
- arelle/CntlrCmdLine.py +5 -4
- arelle/Validate.py +2 -2
- arelle/_version.py +2 -2
- arelle/plugin/validate/EDINET/Constants.py +21 -0
- arelle/plugin/validate/EDINET/ControllerPluginData.py +32 -16
- arelle/plugin/validate/EDINET/PluginValidationDataExtension.py +19 -1
- arelle/plugin/validate/EDINET/UploadContents.py +18 -2
- arelle/plugin/validate/EDINET/ValidationPluginExtension.py +1 -0
- arelle/plugin/validate/EDINET/rules/gfm.py +60 -0
- arelle/plugin/validate/EDINET/rules/upload.py +139 -25
- arelle/plugin/validate/ROS/rules/ros.py +2 -2
- {arelle_release-2.37.54.dist-info → arelle_release-2.37.56.dist-info}/METADATA +1 -1
- {arelle_release-2.37.54.dist-info → arelle_release-2.37.56.dist-info}/RECORD +17 -17
- {arelle_release-2.37.54.dist-info → arelle_release-2.37.56.dist-info}/WHEEL +0 -0
- {arelle_release-2.37.54.dist-info → arelle_release-2.37.56.dist-info}/entry_points.txt +0 -0
- {arelle_release-2.37.54.dist-info → arelle_release-2.37.56.dist-info}/licenses/LICENSE.md +0 -0
- {arelle_release-2.37.54.dist-info → arelle_release-2.37.56.dist-info}/top_level.txt +0 -0
arelle/CntlrCmdLine.py
CHANGED
|
@@ -1171,10 +1171,6 @@ class CntlrCmdLine(Cntlr.Cntlr):
|
|
|
1171
1171
|
for pluginXbrlMethod in PluginManager.pluginClassMethods("CntlrCmdLine.Xbrl.Run"):
|
|
1172
1172
|
pluginXbrlMethod(self, options, modelXbrl, _entrypoint, sourceZipStream=sourceZipStream, responseZipStream=responseZipStream)
|
|
1173
1173
|
|
|
1174
|
-
if options.validate:
|
|
1175
|
-
for pluginXbrlMethod in PluginManager.pluginClassMethods("Validate.Complete"):
|
|
1176
|
-
pluginXbrlMethod(self, filesource)
|
|
1177
|
-
|
|
1178
1174
|
except OSError as err:
|
|
1179
1175
|
self.addToLog(_("[IOError] Failed to save output:\n {0}").format(err),
|
|
1180
1176
|
messageCode="IOError",
|
|
@@ -1222,6 +1218,11 @@ class CntlrCmdLine(Cntlr.Cntlr):
|
|
|
1222
1218
|
self.modelManager.close(modelDiffReport)
|
|
1223
1219
|
elif modelXbrl:
|
|
1224
1220
|
self.modelManager.close(modelXbrl)
|
|
1221
|
+
|
|
1222
|
+
if options.validate:
|
|
1223
|
+
for pluginXbrlMethod in PluginManager.pluginClassMethods("Validate.Complete"):
|
|
1224
|
+
pluginXbrlMethod(self, filesource)
|
|
1225
|
+
|
|
1225
1226
|
if filesource is not None and not options.keepOpen:
|
|
1226
1227
|
# Archive filesource potentially used by multiple reports may still be open.
|
|
1227
1228
|
filesource.close()
|
arelle/Validate.py
CHANGED
|
@@ -488,13 +488,13 @@ class Validate:
|
|
|
488
488
|
self.instValidator.validate(model, parameters)
|
|
489
489
|
for pluginXbrlMethod in pluginClassMethods("TestcaseVariation.Xbrl.Validated"):
|
|
490
490
|
pluginXbrlMethod(self.modelXbrl, model)
|
|
491
|
-
for pluginXbrlMethod in pluginClassMethods("Validate.Complete"):
|
|
492
|
-
pluginXbrlMethod(self.modelXbrl.modelManager.cntlr, filesource)
|
|
493
491
|
except Exception as err:
|
|
494
492
|
model.error("exception:" + type(err).__name__,
|
|
495
493
|
_("Testcase variation validation exception: %(error)s, instance: %(instance)s"),
|
|
496
494
|
modelXbrl=model, instance=model.modelDocument.basename, error=err, exc_info=(type(err) is not AssertionError))
|
|
497
495
|
model.hasFormulae = _hasFormulae
|
|
496
|
+
for pluginXbrlMethod in pluginClassMethods("Validate.Complete"):
|
|
497
|
+
pluginXbrlMethod(self.modelXbrl.modelManager.cntlr, filesource)
|
|
498
498
|
errors = [error for model in loadedModels for error in model.errors]
|
|
499
499
|
for err in preLoadingErrors:
|
|
500
500
|
if err not in errors:
|
arelle/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '2.37.
|
|
32
|
-
__version_tuple__ = version_tuple = (2, 37,
|
|
31
|
+
__version__ = version = '2.37.56'
|
|
32
|
+
__version_tuple__ = version_tuple = (2, 37, 56)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -40,6 +40,27 @@ xhtmlDtdExtension = "xhtml1-strict-ix.dtd"
|
|
|
40
40
|
|
|
41
41
|
COVER_PAGE_FILENAME_PREFIX = "0000000_header_"
|
|
42
42
|
|
|
43
|
+
PROHIBITED_HTML_ATTRIBUTES = frozenset({
|
|
44
|
+
'onblur',
|
|
45
|
+
'onchange',
|
|
46
|
+
'onclick',
|
|
47
|
+
'ondblclick',
|
|
48
|
+
'onfocus',
|
|
49
|
+
'onkeydown',
|
|
50
|
+
'onkeypress',
|
|
51
|
+
'onkeyup',
|
|
52
|
+
'onload',
|
|
53
|
+
'onmousedown',
|
|
54
|
+
'onmousemove',
|
|
55
|
+
'onmouseout',
|
|
56
|
+
'onmouseover',
|
|
57
|
+
'onmouseup',
|
|
58
|
+
'onreset',
|
|
59
|
+
'onselect',
|
|
60
|
+
'onsubmit',
|
|
61
|
+
'onunload',
|
|
62
|
+
})
|
|
63
|
+
|
|
43
64
|
PROHIBITED_HTML_TAGS = frozenset({
|
|
44
65
|
'applet',
|
|
45
66
|
'embed',
|
|
@@ -27,12 +27,14 @@ _: TypeGetText
|
|
|
27
27
|
@dataclass
|
|
28
28
|
class ControllerPluginData(PluginData):
|
|
29
29
|
_manifestInstancesById: dict[str, ManifestInstance]
|
|
30
|
+
_uploadContents: UploadContents | None
|
|
30
31
|
_usedFilepaths: set[Path]
|
|
31
32
|
|
|
32
33
|
def __init__(self, name: str):
|
|
33
34
|
super().__init__(name)
|
|
34
35
|
self._manifestInstancesById = {}
|
|
35
36
|
self._usedFilepaths = set()
|
|
37
|
+
self._uploadContents = None
|
|
36
38
|
|
|
37
39
|
def __hash__(self) -> int:
|
|
38
40
|
return id(self)
|
|
@@ -49,18 +51,21 @@ class ControllerPluginData(PluginData):
|
|
|
49
51
|
"""
|
|
50
52
|
return list(self._manifestInstancesById.values())
|
|
51
53
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
def getUploadContents(self) -> UploadContents | None:
|
|
55
|
+
return self._uploadContents
|
|
56
|
+
|
|
57
|
+
def setUploadContents(self, fileSource: FileSource) -> UploadContents:
|
|
55
58
|
reports = defaultdict(list)
|
|
56
59
|
uploadPaths = {}
|
|
57
|
-
for path in
|
|
60
|
+
for path, zipPath in self.getUploadFilepaths(fileSource).items():
|
|
58
61
|
if len(path.parts) == 0:
|
|
59
62
|
continue
|
|
63
|
+
assert isinstance(fileSource.basefile, str)
|
|
64
|
+
fullPath = Path(fileSource.basefile) / path
|
|
60
65
|
parents = list(reversed([p.name for p in path.parents if len(p.name) > 0]))
|
|
61
66
|
reportFolderType = None
|
|
62
67
|
isCorrection = True
|
|
63
|
-
isDirectory =
|
|
68
|
+
isDirectory = zipPath.is_dir()
|
|
64
69
|
isInSubdirectory = False
|
|
65
70
|
reportPath = None
|
|
66
71
|
if len(parents) > 0:
|
|
@@ -79,32 +84,43 @@ class ControllerPluginData(PluginData):
|
|
|
79
84
|
if not isCorrection:
|
|
80
85
|
reports[reportFolderType].append(path)
|
|
81
86
|
uploadPaths[path] = UploadPathInfo(
|
|
87
|
+
fullPath=fullPath,
|
|
82
88
|
isAttachment=reportFolderType is not None and reportFolderType.isAttachment,
|
|
83
89
|
isCorrection=isCorrection,
|
|
84
90
|
isCoverPage=not isDirectory and path.stem.startswith(Constants.COVER_PAGE_FILENAME_PREFIX),
|
|
85
|
-
isDirectory=
|
|
91
|
+
isDirectory=isDirectory,
|
|
86
92
|
isRoot=len(path.parts) == 1,
|
|
87
93
|
isSubdirectory=isInSubdirectory or (isDirectory and reportFolderType is not None),
|
|
88
94
|
path=path,
|
|
89
95
|
reportFolderType=reportFolderType,
|
|
90
96
|
reportPath=reportPath,
|
|
91
97
|
)
|
|
92
|
-
|
|
98
|
+
self._uploadContents = UploadContents(
|
|
93
99
|
reports={k: frozenset(v) for k, v in reports.items() if len(v) > 0},
|
|
94
|
-
uploadPaths=uploadPaths
|
|
100
|
+
uploadPaths=list(uploadPaths.values())
|
|
95
101
|
)
|
|
102
|
+
return self._uploadContents
|
|
96
103
|
|
|
97
104
|
@lru_cache(1)
|
|
98
|
-
def getUploadFilepaths(self, fileSource: FileSource) ->
|
|
105
|
+
def getUploadFilepaths(self, fileSource: FileSource) -> dict[Path, zipfile.Path]:
|
|
99
106
|
if not self.isUpload(fileSource):
|
|
100
|
-
return
|
|
101
|
-
paths =
|
|
107
|
+
return {}
|
|
108
|
+
paths = {}
|
|
102
109
|
assert isinstance(fileSource.fs, zipfile.ZipFile)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
paths
|
|
107
|
-
|
|
110
|
+
# First, fill in paths from zip file list
|
|
111
|
+
for file in fileSource.fs.filelist:
|
|
112
|
+
zipPath = zipfile.Path(fileSource.fs, file.filename)
|
|
113
|
+
paths[Path(file.filename)] = zipPath
|
|
114
|
+
# Then, fill in any parent directories that weren't in file list
|
|
115
|
+
for path in list(paths):
|
|
116
|
+
for parent in path.parents:
|
|
117
|
+
if parent in paths:
|
|
118
|
+
continue
|
|
119
|
+
paths[parent] = zipfile.Path(fileSource.fs, parent.as_posix() + '/')
|
|
120
|
+
return {
|
|
121
|
+
path: paths[path]
|
|
122
|
+
for path in sorted(paths)
|
|
123
|
+
}
|
|
108
124
|
|
|
109
125
|
@lru_cache(1)
|
|
110
126
|
def getUploadFileSizes(self, fileSource: FileSource) -> dict[Path, int]:
|
|
@@ -31,10 +31,11 @@ from arelle.XhtmlValidate import htmlEltUriAttrs
|
|
|
31
31
|
from arelle.XmlValidate import VALID
|
|
32
32
|
from arelle.typing import TypeGetText
|
|
33
33
|
from arelle.utils.PluginData import PluginData
|
|
34
|
-
from .Constants import CORPORATE_FORMS, FormType, xhtmlDtdExtension, PROHIBITED_HTML_TAGS
|
|
34
|
+
from .Constants import CORPORATE_FORMS, FormType, xhtmlDtdExtension, PROHIBITED_HTML_TAGS, PROHIBITED_HTML_ATTRIBUTES
|
|
35
35
|
from .ControllerPluginData import ControllerPluginData
|
|
36
36
|
from .ManifestInstance import ManifestInstance
|
|
37
37
|
from .Statement import Statement, STATEMENTS, BalanceSheet, StatementInstance, StatementType
|
|
38
|
+
from .UploadContents import UploadContents
|
|
38
39
|
|
|
39
40
|
_: TypeGetText
|
|
40
41
|
|
|
@@ -301,6 +302,19 @@ class PluginValidationDataExtension(PluginData):
|
|
|
301
302
|
controllerPluginData = ControllerPluginData.get(modelXbrl.modelManager.cntlr, self.name)
|
|
302
303
|
return controllerPluginData.matchManifestInstance(modelXbrl.ixdsDocUrls)
|
|
303
304
|
|
|
305
|
+
@lru_cache(1)
|
|
306
|
+
def getProhibitedAttributeElements(self, modelDocument: ModelDocument) -> list[tuple[ModelObject, str]]:
|
|
307
|
+
results: list[tuple[ModelObject, str]] = []
|
|
308
|
+
if modelDocument.type not in (ModelDocumentType.INLINEXBRL, ModelDocumentType.HTML):
|
|
309
|
+
return results
|
|
310
|
+
for elt in modelDocument.xmlRootElement.iter():
|
|
311
|
+
if not isinstance(elt, ModelObject):
|
|
312
|
+
continue
|
|
313
|
+
for attributeName in elt.attrib:
|
|
314
|
+
if attributeName in PROHIBITED_HTML_ATTRIBUTES:
|
|
315
|
+
results.append((elt, str(attributeName)))
|
|
316
|
+
return results
|
|
317
|
+
|
|
304
318
|
@lru_cache(1)
|
|
305
319
|
def getProhibitedTagElements(self, modelDocument: ModelDocument) -> list[ModelObject]:
|
|
306
320
|
elts: list[ModelObject] = []
|
|
@@ -314,6 +328,10 @@ class PluginValidationDataExtension(PluginData):
|
|
|
314
328
|
elts.append(elt)
|
|
315
329
|
return elts
|
|
316
330
|
|
|
331
|
+
def getUploadContents(self, modelXbrl: ModelXbrl) -> UploadContents | None:
|
|
332
|
+
controllerPluginData = ControllerPluginData.get(modelXbrl.modelManager.cntlr, self.name)
|
|
333
|
+
return controllerPluginData.getUploadContents()
|
|
334
|
+
|
|
317
335
|
@lru_cache(1)
|
|
318
336
|
def getUriAttributeValues(self, modelDocument: ModelDocument) -> list[tuple[ModelObject, str, str]]:
|
|
319
337
|
results: list[tuple[ModelObject, str, str]] = []
|
|
@@ -4,6 +4,7 @@ See COPYRIGHT.md for copyright information.
|
|
|
4
4
|
from __future__ import annotations
|
|
5
5
|
|
|
6
6
|
from dataclasses import dataclass
|
|
7
|
+
from functools import cached_property
|
|
7
8
|
from pathlib import Path
|
|
8
9
|
|
|
9
10
|
from .ReportFolderType import ReportFolderType
|
|
@@ -12,15 +13,30 @@ from .ReportFolderType import ReportFolderType
|
|
|
12
13
|
@dataclass(frozen=True)
|
|
13
14
|
class UploadContents:
|
|
14
15
|
reports: dict[ReportFolderType, frozenset[Path]]
|
|
15
|
-
uploadPaths:
|
|
16
|
+
uploadPaths: list[UploadPathInfo]
|
|
16
17
|
|
|
17
18
|
@property
|
|
18
19
|
def sortedPaths(self) -> list[Path]:
|
|
19
|
-
return sorted(self.uploadPaths
|
|
20
|
+
return sorted(uploadPath.path for uploadPath in self.uploadPaths)
|
|
21
|
+
|
|
22
|
+
@cached_property
|
|
23
|
+
def uploadPathsByFullPath(self) -> dict[Path, UploadPathInfo]:
|
|
24
|
+
return {
|
|
25
|
+
uploadPath.fullPath: uploadPath
|
|
26
|
+
for uploadPath in self.uploadPaths
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
@cached_property
|
|
30
|
+
def uploadPathsByPath(self) -> dict[Path, UploadPathInfo]:
|
|
31
|
+
return {
|
|
32
|
+
uploadPath.path: uploadPath
|
|
33
|
+
for uploadPath in self.uploadPaths
|
|
34
|
+
}
|
|
20
35
|
|
|
21
36
|
|
|
22
37
|
@dataclass(frozen=True)
|
|
23
38
|
class UploadPathInfo:
|
|
39
|
+
fullPath: Path
|
|
24
40
|
isAttachment: bool
|
|
25
41
|
isCorrection: bool
|
|
26
42
|
isCoverPage: bool
|
|
@@ -37,6 +37,7 @@ class ValidationPluginExtension(ValidationPlugin):
|
|
|
37
37
|
}, level=logging.INFO
|
|
38
38
|
)
|
|
39
39
|
pluginData = ControllerPluginData.get(filesource.cntlr, self.name)
|
|
40
|
+
pluginData.setUploadContents(filesource)
|
|
40
41
|
entrypointFiles = []
|
|
41
42
|
for instance in instances:
|
|
42
43
|
pluginData.addManifestInstance(instance)
|
|
@@ -641,3 +641,63 @@ def rule_gfm_1_3_1(
|
|
|
641
641
|
msg=_("The submitter-specific taxonomy contains include elements."),
|
|
642
642
|
modelObject=warnings
|
|
643
643
|
)
|
|
644
|
+
|
|
645
|
+
|
|
646
|
+
@validation(
|
|
647
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
648
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
649
|
+
)
|
|
650
|
+
def rule_gfm_1_3_8(
|
|
651
|
+
pluginData: PluginValidationDataExtension,
|
|
652
|
+
val: ValidateXbrl,
|
|
653
|
+
*args: Any,
|
|
654
|
+
**kwargs: Any,
|
|
655
|
+
) -> Iterable[Validation]:
|
|
656
|
+
"""
|
|
657
|
+
EDINET.EC5700W: [GFM 1.3.8] TThe submitter-specific taxonomy has an embedded linkbase.
|
|
658
|
+
"""
|
|
659
|
+
embeddedElements = []
|
|
660
|
+
for modelDocument in val.modelXbrl.urlDocs.values():
|
|
661
|
+
if pluginData.isStandardTaxonomyUrl(modelDocument.uri, val.modelXbrl):
|
|
662
|
+
continue
|
|
663
|
+
rootElt = modelDocument.xmlRootElement
|
|
664
|
+
for elt in rootElt.iterdescendants(XbrlConst.qnLinkLinkbaseRef.clarkNotation):
|
|
665
|
+
if elt.attrib.get(XbrlConst.qnXlinkType.clarkNotation) in ('extended', 'arc', 'resource', 'locator'):
|
|
666
|
+
embeddedElements.append(elt)
|
|
667
|
+
if len(embeddedElements) > 0:
|
|
668
|
+
yield Validation.warning(
|
|
669
|
+
codes='EDINET.EC5700W.GFM.1.3.8',
|
|
670
|
+
msg=_("The submitter-specific taxonomy has an embedded linkbase."),
|
|
671
|
+
modelObject=embeddedElements
|
|
672
|
+
)
|
|
673
|
+
|
|
674
|
+
|
|
675
|
+
@validation(
|
|
676
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
677
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
678
|
+
)
|
|
679
|
+
def rule_gfm_1_5_6(
|
|
680
|
+
pluginData: PluginValidationDataExtension,
|
|
681
|
+
val: ValidateXbrl,
|
|
682
|
+
*args: Any,
|
|
683
|
+
**kwargs: Any,
|
|
684
|
+
) -> Iterable[Validation]:
|
|
685
|
+
"""
|
|
686
|
+
EDINET.EC5700W: [GFM 1.5.6] The length of a label must be less than 511 characters unless it its role is documentation.
|
|
687
|
+
"""
|
|
688
|
+
labelRelationshipSet = val.modelXbrl.relationshipSet(XbrlConst.conceptLabel)
|
|
689
|
+
if labelRelationshipSet is None:
|
|
690
|
+
return
|
|
691
|
+
for concept in val.modelXbrl.qnameConcepts.values():
|
|
692
|
+
labelRels = labelRelationshipSet.fromModelObject(concept)
|
|
693
|
+
for rel in labelRels:
|
|
694
|
+
label = rel.toModelObject
|
|
695
|
+
if label.role != XbrlConst.documentationLabel and label.viewText() is not None and len(label.viewText()) > 511:
|
|
696
|
+
yield Validation.warning(
|
|
697
|
+
codes='EDINET.EC5700W.GFM.1.5.6',
|
|
698
|
+
msg=_("The concept of '%(concept)s' has a label classified as '%(role)s' that is longer than 511 characters: %(label)s"),
|
|
699
|
+
concept=concept.qname,
|
|
700
|
+
role=label.role,
|
|
701
|
+
label=label.viewText(),
|
|
702
|
+
modelObject=label
|
|
703
|
+
)
|
|
@@ -122,8 +122,10 @@ def rule_EC0100E(
|
|
|
122
122
|
For this implementation, we will allow all directories that may be valid for at least one submission type.
|
|
123
123
|
This allows for a false-negative outcome when a non-correction submission has a correction-only root directory.
|
|
124
124
|
"""
|
|
125
|
-
uploadContents = pluginData.getUploadContents(
|
|
126
|
-
|
|
125
|
+
uploadContents = pluginData.getUploadContents()
|
|
126
|
+
if uploadContents is None:
|
|
127
|
+
return
|
|
128
|
+
for path, pathInfo in uploadContents.uploadPathsByPath.items():
|
|
127
129
|
if pathInfo.isRoot and path.name not in ALLOWED_ROOT_FOLDERS:
|
|
128
130
|
yield Validation.error(
|
|
129
131
|
codes='EDINET.EC0100E',
|
|
@@ -153,8 +155,8 @@ def rule_EC0124E_EC0187E(
|
|
|
153
155
|
"""
|
|
154
156
|
uploadFilepaths = pluginData.getUploadFilepaths(fileSource)
|
|
155
157
|
emptyDirectories = []
|
|
156
|
-
for path in uploadFilepaths:
|
|
157
|
-
if
|
|
158
|
+
for path, zipPath in uploadFilepaths.items():
|
|
159
|
+
if not zipPath.is_dir():
|
|
158
160
|
continue
|
|
159
161
|
if not any(path in p.parents for p in uploadFilepaths):
|
|
160
162
|
emptyDirectories.append(path)
|
|
@@ -227,8 +229,10 @@ def rule_EC0130E(
|
|
|
227
229
|
"""
|
|
228
230
|
EDINET.EC0130E: File extensions must match the file extensions allowed in Figure 2-1-3 and Figure 2-1-5.
|
|
229
231
|
"""
|
|
230
|
-
uploadContents = pluginData.getUploadContents(
|
|
231
|
-
|
|
232
|
+
uploadContents = pluginData.getUploadContents()
|
|
233
|
+
if uploadContents is None:
|
|
234
|
+
return
|
|
235
|
+
for path, pathInfo in uploadContents.uploadPathsByPath.items():
|
|
232
236
|
if pathInfo.reportFolderType is None or pathInfo.isDirectory:
|
|
233
237
|
continue
|
|
234
238
|
validExtensions = pathInfo.reportFolderType.getValidExtensions(pathInfo.isCorrection, pathInfo.isSubdirectory)
|
|
@@ -265,7 +269,9 @@ def rule_EC0132E(
|
|
|
265
269
|
"""
|
|
266
270
|
EDINET.EC0132E: Store the manifest file directly under the relevant folder.
|
|
267
271
|
"""
|
|
268
|
-
uploadContents = pluginData.getUploadContents(
|
|
272
|
+
uploadContents = pluginData.getUploadContents()
|
|
273
|
+
if uploadContents is None:
|
|
274
|
+
return
|
|
269
275
|
for reportFolderType, paths in uploadContents.reports.items():
|
|
270
276
|
if reportFolderType.isAttachment:
|
|
271
277
|
continue
|
|
@@ -353,8 +359,10 @@ def rule_EC0192E(
|
|
|
353
359
|
PublicDoc cover file. Please delete the cover file from PrivateDoc and upload
|
|
354
360
|
it again.
|
|
355
361
|
"""
|
|
356
|
-
uploadContents = pluginData.getUploadContents(
|
|
357
|
-
|
|
362
|
+
uploadContents = pluginData.getUploadContents()
|
|
363
|
+
if uploadContents is None:
|
|
364
|
+
return
|
|
365
|
+
for path, pathInfo in uploadContents.uploadPathsByPath.items():
|
|
358
366
|
if not pathInfo.isCoverPage:
|
|
359
367
|
continue
|
|
360
368
|
# Only applies to PrivateDoc correction reports
|
|
@@ -383,8 +391,8 @@ def rule_EC0198E(
|
|
|
383
391
|
"""
|
|
384
392
|
fileCounts: dict[Path, int] = defaultdict(int)
|
|
385
393
|
uploadFilepaths = pluginData.getUploadFilepaths(fileSource)
|
|
386
|
-
for path in uploadFilepaths:
|
|
387
|
-
if
|
|
394
|
+
for path, zipPath in uploadFilepaths.items():
|
|
395
|
+
if zipPath.is_dir():
|
|
388
396
|
continue
|
|
389
397
|
for directory in FILE_COUNT_LIMITS.keys():
|
|
390
398
|
if directory in path.parents:
|
|
@@ -421,10 +429,12 @@ def rule_EC0233E(
|
|
|
421
429
|
NOTE: This includes files in subdirectories. For example, PublicDoc/00000000_images/image.png
|
|
422
430
|
comes before PublicDoc/0000000_header_*.htm
|
|
423
431
|
"""
|
|
424
|
-
uploadContents = pluginData.getUploadContents(
|
|
432
|
+
uploadContents = pluginData.getUploadContents()
|
|
433
|
+
if uploadContents is None:
|
|
434
|
+
return
|
|
425
435
|
directories = defaultdict(list)
|
|
426
436
|
for path in uploadContents.sortedPaths:
|
|
427
|
-
pathInfo = uploadContents.
|
|
437
|
+
pathInfo = uploadContents.uploadPathsByPath[path]
|
|
428
438
|
if pathInfo.isDirectory:
|
|
429
439
|
continue
|
|
430
440
|
if pathInfo.reportFolderType in (ReportFolderType.PRIVATE_DOC, ReportFolderType.PUBLIC_DOC):
|
|
@@ -462,8 +472,10 @@ def rule_EC0234E(
|
|
|
462
472
|
"""
|
|
463
473
|
EDINET.EC0234E: A cover file exists in an unsupported subdirectory.
|
|
464
474
|
"""
|
|
465
|
-
uploadContents = pluginData.getUploadContents(
|
|
466
|
-
|
|
475
|
+
uploadContents = pluginData.getUploadContents()
|
|
476
|
+
if uploadContents is None:
|
|
477
|
+
return
|
|
478
|
+
for path, pathInfo in uploadContents.uploadPathsByPath.items():
|
|
467
479
|
if pathInfo.isDirectory:
|
|
468
480
|
continue
|
|
469
481
|
if pathInfo.reportFolderType not in (ReportFolderType.PRIVATE_DOC, ReportFolderType.PUBLIC_DOC):
|
|
@@ -549,14 +561,16 @@ def rule_EC0349E(
|
|
|
549
561
|
EDINET.EC0349E: An unexpected directory or file exists in the XBRL directory.
|
|
550
562
|
Only PublicDoc, PrivateDoc, or AuditDoc directories may exist beneath the XBRL directory.
|
|
551
563
|
"""
|
|
552
|
-
|
|
564
|
+
uploadContents = pluginData.getUploadContents()
|
|
565
|
+
if uploadContents is None:
|
|
566
|
+
return
|
|
553
567
|
xbrlDirectoryPath = Path('XBRL')
|
|
554
568
|
allowedPaths = {p.xbrlDirectory for p in (
|
|
555
569
|
ReportFolderType.AUDIT_DOC,
|
|
556
570
|
ReportFolderType.PRIVATE_DOC,
|
|
557
571
|
ReportFolderType.PUBLIC_DOC,
|
|
558
572
|
)}
|
|
559
|
-
for path, pathInfo in
|
|
573
|
+
for path, pathInfo in uploadContents.uploadPathsByPath.items():
|
|
560
574
|
if path.parent != xbrlDirectoryPath:
|
|
561
575
|
continue
|
|
562
576
|
if path not in allowedPaths:
|
|
@@ -583,8 +597,10 @@ def rule_EC0352E(
|
|
|
583
597
|
"""
|
|
584
598
|
EDINET.EC0352E: An XBRL file with an invalid name exists.
|
|
585
599
|
"""
|
|
586
|
-
|
|
587
|
-
|
|
600
|
+
uploadContents = pluginData.getUploadContents()
|
|
601
|
+
if uploadContents is None:
|
|
602
|
+
return
|
|
603
|
+
for path, pathInfo in uploadContents.uploadPathsByPath.items():
|
|
588
604
|
if (
|
|
589
605
|
pathInfo.isDirectory or
|
|
590
606
|
pathInfo.isCorrection or
|
|
@@ -603,6 +619,43 @@ def rule_EC0352E(
|
|
|
603
619
|
)
|
|
604
620
|
|
|
605
621
|
|
|
622
|
+
@validation(
|
|
623
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
624
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
625
|
+
)
|
|
626
|
+
def rules_cover_page(
|
|
627
|
+
pluginData: PluginValidationDataExtension,
|
|
628
|
+
val: ValidateXbrl,
|
|
629
|
+
*args: Any,
|
|
630
|
+
**kwargs: Any,
|
|
631
|
+
) -> Iterable[Validation]:
|
|
632
|
+
"""
|
|
633
|
+
EDINET.EC1000E: Cover page must contain "【表紙】".
|
|
634
|
+
"""
|
|
635
|
+
uploadContents = pluginData.getUploadContents(val.modelXbrl)
|
|
636
|
+
if uploadContents is None:
|
|
637
|
+
return
|
|
638
|
+
for url, doc in val.modelXbrl.urlDocs.items():
|
|
639
|
+
path = Path(url)
|
|
640
|
+
pathInfo = uploadContents.uploadPathsByFullPath.get(path)
|
|
641
|
+
if pathInfo is None or not pathInfo.isCoverPage:
|
|
642
|
+
continue
|
|
643
|
+
rootElt = doc.xmlRootElement
|
|
644
|
+
coverPageTextFound = False
|
|
645
|
+
for elt in rootElt.iterdescendants():
|
|
646
|
+
if not coverPageTextFound and elt.text and '【表紙】' in elt.text:
|
|
647
|
+
coverPageTextFound = True
|
|
648
|
+
# TODO: Other checks related to the cover page will be implemented here.
|
|
649
|
+
if not coverPageTextFound:
|
|
650
|
+
yield Validation.error(
|
|
651
|
+
codes='EDINET.EC1000E',
|
|
652
|
+
msg=_("There is no '【表紙】' on the cover page. "
|
|
653
|
+
"File name: '%(file)s'. "
|
|
654
|
+
"Please add '【表紙】' to the relevant file."),
|
|
655
|
+
file=doc.basename,
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
|
|
606
659
|
@validation(
|
|
607
660
|
hook=ValidationHook.XBRL_FINALLY,
|
|
608
661
|
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
@@ -644,8 +697,13 @@ def rule_uri_references(
|
|
|
644
697
|
"""
|
|
645
698
|
EDINET.EC1007E: The URI in the HTML specifies a URL or absolute path.
|
|
646
699
|
EDINET.EC1013E: The URI in the HTML specifies a path not under a subdirectory.
|
|
647
|
-
EDINET.EC1014E: The URI in the HTML specifies a path to a
|
|
700
|
+
EDINET.EC1014E: The URI in the HTML specifies a path to a directory.
|
|
701
|
+
EDINET.EC1021E: The URI in the HTML specifies a path to a file that doesn't exist.
|
|
702
|
+
EDINET.EC1023E: The URI in the HTML specifies a path to a PDF file.
|
|
648
703
|
"""
|
|
704
|
+
uploadContents = pluginData.getUploadContents(val.modelXbrl)
|
|
705
|
+
if uploadContents is None:
|
|
706
|
+
return
|
|
649
707
|
for uriReference in pluginData.uriReferences:
|
|
650
708
|
if UrlUtil.isAbsolute(uriReference.attributeValue):
|
|
651
709
|
yield Validation.error(
|
|
@@ -671,10 +729,11 @@ def rule_uri_references(
|
|
|
671
729
|
)
|
|
672
730
|
continue
|
|
673
731
|
fullPath = Path(uriReference.document.uri).parent / path
|
|
674
|
-
|
|
732
|
+
pathInfo = uploadContents.uploadPathsByFullPath.get(fullPath)
|
|
733
|
+
if pathInfo is not None and pathInfo.isDirectory:
|
|
675
734
|
yield Validation.error(
|
|
676
735
|
codes='EDINET.EC1014E',
|
|
677
|
-
msg=_("The URI in the HTML specifies a path to a
|
|
736
|
+
msg=_("The URI in the HTML specifies a path to a directory. "
|
|
678
737
|
"File name: '%(file)s' (line %(line)s). "
|
|
679
738
|
"Please update the URI to reference a file."),
|
|
680
739
|
file=uriReference.document.basename,
|
|
@@ -682,6 +741,29 @@ def rule_uri_references(
|
|
|
682
741
|
modelObject=uriReference.element,
|
|
683
742
|
)
|
|
684
743
|
continue
|
|
744
|
+
if path.suffix.lower() == '.pdf':
|
|
745
|
+
yield Validation.error(
|
|
746
|
+
codes='EDINET.EC1023E',
|
|
747
|
+
msg=_("The URI in the HTML specifies a path to a PDF file. "
|
|
748
|
+
"File name: '%(file)s' (line %(line)s). "
|
|
749
|
+
"Please remove the link from the relevant file."),
|
|
750
|
+
file=uriReference.document.basename,
|
|
751
|
+
line=uriReference.element.sourceline,
|
|
752
|
+
modelObject=uriReference.element,
|
|
753
|
+
)
|
|
754
|
+
continue
|
|
755
|
+
if not val.modelXbrl.fileSource.exists(str(fullPath)):
|
|
756
|
+
yield Validation.error(
|
|
757
|
+
codes='EDINET.EC1021E',
|
|
758
|
+
msg=_("The linked file ('%(path)s') does not exist. "
|
|
759
|
+
"File name: '%(file)s' (line %(line)s). "
|
|
760
|
+
"Please update the URI to reference a file."),
|
|
761
|
+
path=str(path),
|
|
762
|
+
file=uriReference.document.basename,
|
|
763
|
+
line=uriReference.element.sourceline,
|
|
764
|
+
modelObject=uriReference.element,
|
|
765
|
+
)
|
|
766
|
+
continue
|
|
685
767
|
|
|
686
768
|
|
|
687
769
|
@validation(
|
|
@@ -727,10 +809,12 @@ def rule_EC1017E(
|
|
|
727
809
|
"""
|
|
728
810
|
EDINET.EC1017E: There is an unused file.
|
|
729
811
|
"""
|
|
730
|
-
uploadContents = pluginData.getUploadContents(
|
|
812
|
+
uploadContents = pluginData.getUploadContents()
|
|
813
|
+
if uploadContents is None:
|
|
814
|
+
return
|
|
731
815
|
existingSubdirectoryFilepaths = {
|
|
732
816
|
path
|
|
733
|
-
for path, pathInfo in uploadContents.
|
|
817
|
+
for path, pathInfo in uploadContents.uploadPathsByPath.items()
|
|
734
818
|
if pathInfo.isSubdirectory and not pathInfo.isDirectory
|
|
735
819
|
}
|
|
736
820
|
usedFilepaths = pluginData.getUsedFilepaths()
|
|
@@ -790,6 +874,33 @@ def rule_EC1020E(
|
|
|
790
874
|
)
|
|
791
875
|
|
|
792
876
|
|
|
877
|
+
@validation(
|
|
878
|
+
hook=ValidationHook.XBRL_FINALLY,
|
|
879
|
+
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
880
|
+
)
|
|
881
|
+
def rule_EC1031E(
|
|
882
|
+
pluginData: PluginValidationDataExtension,
|
|
883
|
+
val: ValidateXbrl,
|
|
884
|
+
*args: Any,
|
|
885
|
+
**kwargs: Any,
|
|
886
|
+
) -> Iterable[Validation]:
|
|
887
|
+
"""
|
|
888
|
+
EDINET.EC1031E: Prohibited attribute is used in HTML.
|
|
889
|
+
"""
|
|
890
|
+
for doc in val.modelXbrl.urlDocs.values():
|
|
891
|
+
for elt, attributeName in pluginData.getProhibitedAttributeElements(doc):
|
|
892
|
+
yield Validation.error(
|
|
893
|
+
codes='EDINET.EC1031E',
|
|
894
|
+
msg=_("Prohibited attribute '%(attributeName)s' is used in HTML. "
|
|
895
|
+
"File name: %(file)s (line %(line)s). "
|
|
896
|
+
"Please correct the tag attributes of the relevant file."),
|
|
897
|
+
attributeName=attributeName,
|
|
898
|
+
file=doc.basename,
|
|
899
|
+
line=elt.sourceline,
|
|
900
|
+
modelObject=elt,
|
|
901
|
+
)
|
|
902
|
+
|
|
903
|
+
|
|
793
904
|
@validation(
|
|
794
905
|
hook=ValidationHook.FILESOURCE,
|
|
795
906
|
disclosureSystems=[DISCLOSURE_SYSTEM_EDINET],
|
|
@@ -811,7 +922,10 @@ def rule_filenames(
|
|
|
811
922
|
than those allowed (alphanumeric characters, '-' and '_').
|
|
812
923
|
Note: Applies ONLY to files directly beneath non-correction report folders.
|
|
813
924
|
"""
|
|
814
|
-
|
|
925
|
+
uploadContents = pluginData.getUploadContents()
|
|
926
|
+
if uploadContents is None:
|
|
927
|
+
return
|
|
928
|
+
for path, pathInfo in uploadContents.uploadPathsByPath.items():
|
|
815
929
|
isReportFile = (
|
|
816
930
|
not pathInfo.isAttachment and
|
|
817
931
|
not pathInfo.isCorrection and
|
|
@@ -302,14 +302,14 @@ def rule_ros19(
|
|
|
302
302
|
equity_facts = val.modelXbrl.factsByLocalName.get(EQUITY, set())
|
|
303
303
|
largest_equity_fact = None
|
|
304
304
|
for e_fact in equity_facts:
|
|
305
|
-
if e_fact.xValid >= VALID:
|
|
305
|
+
if e_fact.xValid >= VALID and e_fact.xValue is not None:
|
|
306
306
|
if largest_equity_fact is None or abs(convertToDecimal(e_fact.xValue)) > abs(convertToDecimal(largest_equity_fact.xValue)):
|
|
307
307
|
largest_equity_fact = e_fact
|
|
308
308
|
|
|
309
309
|
turnover_facts = val.modelXbrl.factsByLocalName.get(TURNOVER_REVENUE, set())
|
|
310
310
|
largest_turnover_fact = None
|
|
311
311
|
for t_fact in turnover_facts:
|
|
312
|
-
if t_fact.xValid >= VALID:
|
|
312
|
+
if t_fact.xValid >= VALID and t_fact.xValue is not None:
|
|
313
313
|
if largest_turnover_fact is None or convertToDecimal(t_fact.xValue) > convertToDecimal(largest_turnover_fact.xValue):
|
|
314
314
|
largest_turnover_fact = t_fact
|
|
315
315
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
arelle/Aspect.py,sha256=Pn9I91D1os1RTVj6htuxTfRzVMhmVDtrbKvV_zy9xMI,5470
|
|
2
2
|
arelle/BetaFeatures.py,sha256=T_tPac-FiozHyYLCemt0RoHJ1JahUE71L-0tHmIRKpE,858
|
|
3
3
|
arelle/Cntlr.py,sha256=nwE_qIQMTa5R3sr_dLP6s3srLhiEA5zDOqfas2pDxoA,31691
|
|
4
|
-
arelle/CntlrCmdLine.py,sha256=
|
|
4
|
+
arelle/CntlrCmdLine.py,sha256=D5Xs847rIAMsI_fmJC27GSB0jIMGjE3VejpKvMTqncU,88717
|
|
5
5
|
arelle/CntlrComServer.py,sha256=h1KPf31uMbErpxTZn_iklDqUMGFgQnjZkFkFjd8gtLQ,1888
|
|
6
6
|
arelle/CntlrProfiler.py,sha256=2VQJudiUhxryVypxjODx2ccP1-n60icTiWs5lSEokhQ,972
|
|
7
7
|
arelle/CntlrQuickBooks.py,sha256=BMqd5nkNQOZyNFPefkTeWUUDCYNS6BQavaG8k1Lepu4,31543
|
|
@@ -67,7 +67,7 @@ arelle/UITkTable.py,sha256=N83cXi5c0lLZLsDbwSKcPrlYoUoGsNavGN5YRx6d9XY,39810
|
|
|
67
67
|
arelle/UiUtil.py,sha256=3G0xPclZI8xW_XQDbiFrmylB7Nd5muqi5n2x2oMkMZU,34218
|
|
68
68
|
arelle/Updater.py,sha256=IZ8cq44Rq88WbQcB1VOpMA6bxdfZxfYQ8rgu9Ehpbes,7448
|
|
69
69
|
arelle/UrlUtil.py,sha256=HrxZSG59EUMGMMGmWPuZkPi5-0BGqY3jAMkp7V4IdZo,32400
|
|
70
|
-
arelle/Validate.py,sha256=
|
|
70
|
+
arelle/Validate.py,sha256=cX1OA3JPiwmjNmxfecZc24GBW1qXdjcEEynJ9F1K7Zg,58764
|
|
71
71
|
arelle/ValidateDuplicateFacts.py,sha256=L556J1Dhz4ZmsMlRNoDCMpFgDQYiryd9vuBYDvE0Aq8,21769
|
|
72
72
|
arelle/ValidateFilingText.py,sha256=xnXc0xgdNiHQk0eyP7VSSpvw7qr-pRFRwqqoUb569is,54051
|
|
73
73
|
arelle/ValidateInfoset.py,sha256=Rz_XBi5Ha43KpxXYhjLolURcWVx5qmqyjLxw48Yt9Dg,20396
|
|
@@ -125,7 +125,7 @@ arelle/XmlValidateConst.py,sha256=U_wN0Q-nWKwf6dKJtcu_83FXPn9c6P8JjzGA5b0w7P0,33
|
|
|
125
125
|
arelle/XmlValidateParticles.py,sha256=Mn6vhFl0ZKC_vag1mBwn1rH_x2jmlusJYqOOuxFPO2k,9231
|
|
126
126
|
arelle/XmlValidateSchema.py,sha256=6frtZOc1Yrx_5yYF6V6oHbScnglWrVbWr6xW4EHtLQI,7428
|
|
127
127
|
arelle/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
128
|
-
arelle/_version.py,sha256=
|
|
128
|
+
arelle/_version.py,sha256=fDTO72M4k2Bg8Q2mmpC5_JjetoiOyfrQn3nJSak1r6w,708
|
|
129
129
|
arelle/typing.py,sha256=PRe-Fxwr2SBqYYUVPCJ3E7ddDX0_oOISNdT5Q97EbRM,1246
|
|
130
130
|
arelle/api/Session.py,sha256=kgSxS7VckA1sQ7xp0pJiK7IK-vRxAdAZKUo8gEx27s8,7549
|
|
131
131
|
arelle/config/creationSoftwareNames.json,sha256=5MK7XUjfDJ9OpRCCHXeOErJ1SlTBZji4WEcEOdOacx0,3128
|
|
@@ -312,15 +312,15 @@ arelle/plugin/validate/DBA/rules/tm.py,sha256=ui9oKBqlAForwkQ9kk9KBiUogTJE5pv1Rb
|
|
|
312
312
|
arelle/plugin/validate/DBA/rules/tr.py,sha256=4TootFjl0HXsKZk1XNBCyj-vnjRs4lg35hfiz_b_4wU,14684
|
|
313
313
|
arelle/plugin/validate/EBA/__init__.py,sha256=x3zXNcdSDJ3kHfL7kMs0Ve0Vs9oWbzNFVf1TK4Avmy8,45924
|
|
314
314
|
arelle/plugin/validate/EBA/config.xml,sha256=37wMVUAObK-XEqakqD8zPNog20emYt4a_yfL1AKubF8,2022
|
|
315
|
-
arelle/plugin/validate/EDINET/Constants.py,sha256=
|
|
316
|
-
arelle/plugin/validate/EDINET/ControllerPluginData.py,sha256=
|
|
315
|
+
arelle/plugin/validate/EDINET/Constants.py,sha256=IkJ1R0ZQAs9kUXY8eB7e8azYlC4m500VILrQhniB5Q4,1949
|
|
316
|
+
arelle/plugin/validate/EDINET/ControllerPluginData.py,sha256=zsBOWkSatXza0v_ZB-jIdFLSIj9Btzd50GdNIgVw6Fo,8027
|
|
317
317
|
arelle/plugin/validate/EDINET/DisclosureSystems.py,sha256=3rKG42Eg-17Xx_KXU_V5yHW6I3LTwQunvf4a44C9k_4,36
|
|
318
318
|
arelle/plugin/validate/EDINET/ManifestInstance.py,sha256=o6BGlaQHSsn6D0VKH4zn59UscKnjTKlo99kSGfGdYlU,6910
|
|
319
|
-
arelle/plugin/validate/EDINET/PluginValidationDataExtension.py,sha256=
|
|
319
|
+
arelle/plugin/validate/EDINET/PluginValidationDataExtension.py,sha256=CVTtWTYrvC_oeK9iWHLt5l9dN3KmzgLAEZmGdlPqv3g,16362
|
|
320
320
|
arelle/plugin/validate/EDINET/ReportFolderType.py,sha256=Q-9a-5tJfhK-cjY8WUB2AT1NI-Nn9cFtARVOIJoLRGU,2979
|
|
321
321
|
arelle/plugin/validate/EDINET/Statement.py,sha256=0Mw5IB7LMtvUZ-2xKZfxmq67xF_dCgJo3eNLweLFRHU,9350
|
|
322
|
-
arelle/plugin/validate/EDINET/UploadContents.py,sha256=
|
|
323
|
-
arelle/plugin/validate/EDINET/ValidationPluginExtension.py,sha256=
|
|
322
|
+
arelle/plugin/validate/EDINET/UploadContents.py,sha256=o29mDoX48M3S2jQqrJO4ZaulltAPt4vD-qdsWTMCUPc,1196
|
|
323
|
+
arelle/plugin/validate/EDINET/ValidationPluginExtension.py,sha256=8LNqvXzNaWP54dShEjet5ely4BnM8ByCSyimKpUx3_s,2577
|
|
324
324
|
arelle/plugin/validate/EDINET/__init__.py,sha256=ECWgqzwHA7MZ3g7SeoFI7ttR9Wq_lywV-TlqeUW_juY,3186
|
|
325
325
|
arelle/plugin/validate/EDINET/resources/config.xml,sha256=7uT4GcRgk5veMLpFhPPQJxbGKiQvM52P8EMrjn0qd0g,646
|
|
326
326
|
arelle/plugin/validate/EDINET/resources/edinet-taxonomies.xml,sha256=997I3RGTLg5OY3vn5hQxVFAAxOmDSOYpuyQe6VnWSY0,16285
|
|
@@ -328,9 +328,9 @@ arelle/plugin/validate/EDINET/rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQ
|
|
|
328
328
|
arelle/plugin/validate/EDINET/rules/contexts.py,sha256=KPoyWfRaURvxoGVcWP64mTMTAKPMSmQSX06RClCLddw,7590
|
|
329
329
|
arelle/plugin/validate/EDINET/rules/edinet.py,sha256=VYrDZaKbsQuQEvOY5F0Pv4Jzk9YZ4iETOkAFOggrhEY,12632
|
|
330
330
|
arelle/plugin/validate/EDINET/rules/frta.py,sha256=N0YglHYZuLD2IuwE26viR2ViwUYjneBuMFU9vlrS0aQ,7616
|
|
331
|
-
arelle/plugin/validate/EDINET/rules/gfm.py,sha256=
|
|
331
|
+
arelle/plugin/validate/EDINET/rules/gfm.py,sha256=1SBUQG2M4VOhxp4e2ALnm_Uq8p3g-S0WbKkRCEH-ttw,26769
|
|
332
332
|
arelle/plugin/validate/EDINET/rules/manifests.py,sha256=MoT9R_a4BzuYdQVbF7RC5wz134Ve68svSdJ3NlpO_AU,4026
|
|
333
|
-
arelle/plugin/validate/EDINET/rules/upload.py,sha256=
|
|
333
|
+
arelle/plugin/validate/EDINET/rules/upload.py,sha256=opGEEFf80RLKk_Z43gkUYHJLBvq_Hd-BMzMMg2Vhnns,40064
|
|
334
334
|
arelle/plugin/validate/ESEF/Const.py,sha256=JujF_XV-_TNsxjGbF-8SQS4OOZIcJ8zhCMnr-C1O5Ho,22660
|
|
335
335
|
arelle/plugin/validate/ESEF/Dimensions.py,sha256=MOJM7vwNPEmV5cu-ZzPrhx3347ZvxgD6643OB2HRnIk,10597
|
|
336
336
|
arelle/plugin/validate/ESEF/Util.py,sha256=QH3btcGqBpr42M7WSKZLSdNXygZaZLfEiEjlxoG21jE,7950
|
|
@@ -365,7 +365,7 @@ arelle/plugin/validate/ROS/__init__.py,sha256=KuWg1MHVzA2S6eaHFptvP3Vu_5gQWf3OUY
|
|
|
365
365
|
arelle/plugin/validate/ROS/config.xml,sha256=ZCpCFgr1ZAjoUuhb1eRpDnmKrae-sXA9yl6SOWnrfm8,654
|
|
366
366
|
arelle/plugin/validate/ROS/resources/config.xml,sha256=HXWume5HlrAqOx5AtiWWqgADbRatA8YSfm_JvZGwdgQ,657
|
|
367
367
|
arelle/plugin/validate/ROS/rules/__init__.py,sha256=wW7BUAIb7sRkOxC1Amc_ZKrz03FM-Qh1TyZe6wxYaAU,1567
|
|
368
|
-
arelle/plugin/validate/ROS/rules/ros.py,sha256=
|
|
368
|
+
arelle/plugin/validate/ROS/rules/ros.py,sha256=yGvvJZJwENgFLpA5r464eez1aHf3pKZm0HyzaWiQn6E,19930
|
|
369
369
|
arelle/plugin/validate/UK/ValidateUK.py,sha256=h7-tnCubHme8Meaif-o55TV2rCfMWuikfpZCcK6NNDs,56447
|
|
370
370
|
arelle/plugin/validate/UK/__init__.py,sha256=GT67T_7qpOASzdmgRXFPmLxfPg3Gjubli7luQDK3zck,27462
|
|
371
371
|
arelle/plugin/validate/UK/config.xml,sha256=mUFhWDfBzGTn7v0ZSmf4HaweQTMJh_4ZcJmD9mzCHrA,1547
|
|
@@ -680,9 +680,9 @@ arelle/utils/validate/ValidationUtil.py,sha256=9vmSvShn-EdQy56dfesyV8JjSRVPj7txr
|
|
|
680
680
|
arelle/utils/validate/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
681
681
|
arelle/webserver/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
682
682
|
arelle/webserver/bottle.py,sha256=P-JECd9MCTNcxCnKoDUvGcoi03ezYVOgoWgv2_uH-6M,362
|
|
683
|
-
arelle_release-2.37.
|
|
684
|
-
arelle_release-2.37.
|
|
685
|
-
arelle_release-2.37.
|
|
686
|
-
arelle_release-2.37.
|
|
687
|
-
arelle_release-2.37.
|
|
688
|
-
arelle_release-2.37.
|
|
683
|
+
arelle_release-2.37.56.dist-info/licenses/LICENSE.md,sha256=Q0tn6q0VUbr-NM8916513NCIG8MNzo24Ev-sxMUBRZc,3959
|
|
684
|
+
arelle_release-2.37.56.dist-info/METADATA,sha256=Wtmg0dACPtcIDHq93LetjVlxqOerxZ1VGQdsa1ZgUds,9327
|
|
685
|
+
arelle_release-2.37.56.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
686
|
+
arelle_release-2.37.56.dist-info/entry_points.txt,sha256=Uj5niwfwVsx3vaQ3fYj8hrZ1xpfCJyTUA09tYKWbzpo,111
|
|
687
|
+
arelle_release-2.37.56.dist-info/top_level.txt,sha256=fwU7SYawL4_r-sUMRg7r1nYVGjFMSDvRWx8VGAXEw7w,7
|
|
688
|
+
arelle_release-2.37.56.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|