ixbrl-viewer 1.4.1__py3-none-any.whl → 1.4.86__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.
- iXBRLViewerPlugin/__init__.py +231 -127
- iXBRLViewerPlugin/_version.py +33 -3
- iXBRLViewerPlugin/constants.py +96 -2
- iXBRLViewerPlugin/featureConfig.py +8 -1
- iXBRLViewerPlugin/iXBRLViewer.py +356 -214
- iXBRLViewerPlugin/plugin.py +12 -0
- iXBRLViewerPlugin/ui.py +81 -50
- iXBRLViewerPlugin/viewer/dist/ixbrlviewer.js +1 -1
- iXBRLViewerPlugin/viewer/dist/ixbrlviewer.js.LICENSE.txt +12 -5
- iXBRLViewerPlugin/viewer/i18next-parser.config.js +1 -1
- iXBRLViewerPlugin/viewer/src/data/utr.json +1244 -0
- iXBRLViewerPlugin/viewer/src/html/fact-details.html +69 -38
- iXBRLViewerPlugin/viewer/src/html/footer-logo.html +4 -0
- iXBRLViewerPlugin/viewer/src/html/footnote-details.html +2 -2
- iXBRLViewerPlugin/viewer/src/html/inspector.html +352 -197
- iXBRLViewerPlugin/viewer/src/i18n/cy/balancetypes.json +1 -0
- iXBRLViewerPlugin/viewer/src/i18n/cy/currencies.json +13 -0
- iXBRLViewerPlugin/viewer/src/i18n/cy/datatypes.json +9 -0
- iXBRLViewerPlugin/viewer/src/i18n/cy/labelroles.json +24 -0
- iXBRLViewerPlugin/viewer/src/i18n/cy/referenceparts.json +10 -0
- iXBRLViewerPlugin/viewer/src/i18n/cy/scale.json +16 -0
- iXBRLViewerPlugin/viewer/src/i18n/cy/tooltips.json +17 -0
- iXBRLViewerPlugin/viewer/src/i18n/cy/translation.json +179 -0
- iXBRLViewerPlugin/viewer/src/i18n/da/balancetypes.json +4 -0
- iXBRLViewerPlugin/viewer/src/i18n/da/currencies.json +13 -0
- iXBRLViewerPlugin/viewer/src/i18n/da/datatypes.json +9 -0
- iXBRLViewerPlugin/viewer/src/i18n/da/labelroles.json +24 -0
- iXBRLViewerPlugin/viewer/src/i18n/da/referenceparts.json +10 -0
- iXBRLViewerPlugin/viewer/src/i18n/da/scale.json +15 -0
- iXBRLViewerPlugin/viewer/src/i18n/da/tooltips.json +17 -0
- iXBRLViewerPlugin/viewer/src/i18n/da/translation.json +179 -0
- iXBRLViewerPlugin/viewer/src/i18n/de/balancetypes.json +4 -0
- iXBRLViewerPlugin/viewer/src/i18n/de/currencies.json +13 -0
- iXBRLViewerPlugin/viewer/src/i18n/de/datatypes.json +9 -0
- iXBRLViewerPlugin/viewer/src/i18n/de/labelroles.json +24 -0
- iXBRLViewerPlugin/viewer/src/i18n/de/referenceparts.json +10 -0
- iXBRLViewerPlugin/viewer/src/i18n/de/scale.json +15 -0
- iXBRLViewerPlugin/viewer/src/i18n/de/tooltips.json +17 -0
- iXBRLViewerPlugin/viewer/src/i18n/de/translation.json +179 -0
- iXBRLViewerPlugin/viewer/src/i18n/en/balancetypes.json +4 -0
- iXBRLViewerPlugin/viewer/src/i18n/en/datatypes.json +10 -0
- iXBRLViewerPlugin/viewer/src/i18n/en/labelroles.json +4 -0
- iXBRLViewerPlugin/viewer/src/i18n/en/scale.json +16 -0
- iXBRLViewerPlugin/viewer/src/i18n/en/tooltips.json +17 -0
- iXBRLViewerPlugin/viewer/src/i18n/en/translation.json +73 -23
- iXBRLViewerPlugin/viewer/src/i18n/es/balancetypes.json +4 -0
- iXBRLViewerPlugin/viewer/src/i18n/es/datatypes.json +10 -0
- iXBRLViewerPlugin/viewer/src/i18n/es/labelroles.json +24 -0
- iXBRLViewerPlugin/viewer/src/i18n/es/scale.json +16 -0
- iXBRLViewerPlugin/viewer/src/i18n/es/tooltips.json +17 -0
- iXBRLViewerPlugin/viewer/src/i18n/es/translation.json +87 -37
- iXBRLViewerPlugin/viewer/src/i18n/fr/balancetypes.json +4 -0
- iXBRLViewerPlugin/viewer/src/i18n/fr/currencies.json +13 -0
- iXBRLViewerPlugin/viewer/src/i18n/fr/datatypes.json +9 -0
- iXBRLViewerPlugin/viewer/src/i18n/fr/labelroles.json +24 -0
- iXBRLViewerPlugin/viewer/src/i18n/fr/referenceparts.json +10 -0
- iXBRLViewerPlugin/viewer/src/i18n/fr/scale.json +15 -0
- iXBRLViewerPlugin/viewer/src/i18n/fr/tooltips.json +17 -0
- iXBRLViewerPlugin/viewer/src/i18n/fr/translation.json +179 -0
- iXBRLViewerPlugin/viewer/src/i18n/nl/balancetypes.json +4 -0
- iXBRLViewerPlugin/viewer/src/i18n/nl/currencies.json +13 -0
- iXBRLViewerPlugin/viewer/src/i18n/nl/datatypes.json +9 -0
- iXBRLViewerPlugin/viewer/src/i18n/nl/labelroles.json +24 -0
- iXBRLViewerPlugin/viewer/src/i18n/nl/referenceparts.json +10 -0
- iXBRLViewerPlugin/viewer/src/i18n/nl/scale.json +15 -0
- iXBRLViewerPlugin/viewer/src/i18n/nl/tooltips.json +17 -0
- iXBRLViewerPlugin/viewer/src/i18n/nl/translation.json +179 -0
- iXBRLViewerPlugin/viewer/src/i18n/uk/balancetypes.json +4 -0
- iXBRLViewerPlugin/viewer/src/i18n/uk/currencies.json +13 -0
- iXBRLViewerPlugin/viewer/src/i18n/uk/datatypes.json +9 -0
- iXBRLViewerPlugin/viewer/src/i18n/uk/labelroles.json +24 -0
- iXBRLViewerPlugin/viewer/src/i18n/uk/referenceparts.json +10 -0
- iXBRLViewerPlugin/viewer/src/i18n/uk/scale.json +15 -0
- iXBRLViewerPlugin/viewer/src/i18n/uk/tooltips.json +17 -0
- iXBRLViewerPlugin/viewer/src/i18n/uk/translation.json +179 -0
- iXBRLViewerPlugin/viewer/src/icons/calculator.svg +13 -0
- iXBRLViewerPlugin/viewer/src/icons/circle-cross.svg +11 -0
- iXBRLViewerPlugin/viewer/src/icons/circle-tick.svg +11 -0
- iXBRLViewerPlugin/viewer/src/icons/dark-mode.svg +4 -0
- iXBRLViewerPlugin/viewer/src/icons/dimension.svg +1 -5
- iXBRLViewerPlugin/viewer/src/icons/member.svg +2 -5
- iXBRLViewerPlugin/viewer/src/icons/multi-tag.svg +10 -0
- iXBRLViewerPlugin/viewer/src/img/arelle-dark.svg +179 -0
- iXBRLViewerPlugin/viewer/src/img/inline-viewer-dark.svg +59 -0
- iXBRLViewerPlugin/viewer/src/js/accordian.js +5 -4
- iXBRLViewerPlugin/viewer/src/js/aspect.js +29 -10
- iXBRLViewerPlugin/viewer/src/js/aspect.test.js +40 -31
- iXBRLViewerPlugin/viewer/src/js/balance.js +14 -0
- iXBRLViewerPlugin/viewer/src/js/calculation.js +213 -0
- iXBRLViewerPlugin/viewer/src/js/calculation.test.js +306 -0
- iXBRLViewerPlugin/viewer/src/js/calculationInspector.js +187 -0
- iXBRLViewerPlugin/viewer/src/js/chart.js +26 -24
- iXBRLViewerPlugin/viewer/src/js/chart.test.js +10 -9
- iXBRLViewerPlugin/viewer/src/js/concept.js +37 -4
- iXBRLViewerPlugin/viewer/src/js/concept.test.js +30 -6
- iXBRLViewerPlugin/viewer/src/js/datatype.js +20 -0
- iXBRLViewerPlugin/viewer/src/js/datatype.test.js +62 -0
- iXBRLViewerPlugin/viewer/src/js/dialog.js +6 -4
- iXBRLViewerPlugin/viewer/src/js/docOrderIndex.js +7 -7
- iXBRLViewerPlugin/viewer/src/js/fact.js +156 -59
- iXBRLViewerPlugin/viewer/src/js/fact.test.js +160 -29
- iXBRLViewerPlugin/viewer/src/js/factset.js +64 -15
- iXBRLViewerPlugin/viewer/src/js/factset.test.js +102 -31
- iXBRLViewerPlugin/viewer/src/js/footnote.js +8 -2
- iXBRLViewerPlugin/viewer/src/js/index.js +11 -3
- iXBRLViewerPlugin/viewer/src/js/inspector.js +747 -221
- iXBRLViewerPlugin/viewer/src/js/inspector.test.js +143 -25
- iXBRLViewerPlugin/viewer/src/js/interval.js +70 -0
- iXBRLViewerPlugin/viewer/src/js/interval.test.js +153 -0
- iXBRLViewerPlugin/viewer/src/js/ixbrlviewer.js +391 -262
- iXBRLViewerPlugin/viewer/src/js/ixbrlviewer.test.js +134 -20
- iXBRLViewerPlugin/viewer/src/js/ixnode.js +1 -1
- iXBRLViewerPlugin/viewer/src/js/menu.js +25 -7
- iXBRLViewerPlugin/viewer/src/js/number-matcher.js +7 -3
- iXBRLViewerPlugin/viewer/src/js/number-matcher.test.js +4 -0
- iXBRLViewerPlugin/viewer/src/js/outline.js +34 -13
- iXBRLViewerPlugin/viewer/src/js/outline.test.js +97 -91
- iXBRLViewerPlugin/viewer/src/js/period.js +0 -1
- iXBRLViewerPlugin/viewer/src/js/report.js +260 -351
- iXBRLViewerPlugin/viewer/src/js/report.test.js +95 -27
- iXBRLViewerPlugin/viewer/src/js/reportset.js +264 -0
- iXBRLViewerPlugin/viewer/src/js/reportset.test.js +357 -0
- iXBRLViewerPlugin/viewer/src/js/search.js +72 -38
- iXBRLViewerPlugin/viewer/src/js/search.test.js +184 -84
- iXBRLViewerPlugin/viewer/src/js/summary.js +34 -8
- iXBRLViewerPlugin/viewer/src/js/summary.test.js +69 -25
- iXBRLViewerPlugin/viewer/src/js/tableExport.js +9 -9
- iXBRLViewerPlugin/viewer/src/js/taxonomynamer.js +34 -0
- iXBRLViewerPlugin/viewer/src/js/taxonomynamer.test.js +32 -0
- iXBRLViewerPlugin/viewer/src/js/test-utils.js +46 -0
- iXBRLViewerPlugin/viewer/src/js/theme.js +50 -0
- iXBRLViewerPlugin/viewer/src/js/unit.js +90 -32
- iXBRLViewerPlugin/viewer/src/js/unit.test.js +62 -25
- iXBRLViewerPlugin/viewer/src/js/util.js +94 -0
- iXBRLViewerPlugin/viewer/src/js/util.test.js +33 -1
- iXBRLViewerPlugin/viewer/src/js/utr.js +27 -0
- iXBRLViewerPlugin/viewer/src/js/viewer.js +205 -181
- iXBRLViewerPlugin/viewer/src/js/viewerOptions.js +0 -2
- iXBRLViewerPlugin/viewer/src/less/accordian.less +10 -6
- iXBRLViewerPlugin/viewer/src/less/block-list.less +16 -5
- iXBRLViewerPlugin/viewer/src/less/calculation-inspector.less +83 -0
- iXBRLViewerPlugin/viewer/src/less/chart.less +8 -5
- iXBRLViewerPlugin/viewer/src/less/colours-dark-mode.less +40 -0
- iXBRLViewerPlugin/viewer/src/less/colours.less +32 -20
- iXBRLViewerPlugin/viewer/src/less/common.less +3 -3
- iXBRLViewerPlugin/viewer/src/less/components.less +6 -4
- iXBRLViewerPlugin/viewer/src/less/core.less +2 -0
- iXBRLViewerPlugin/viewer/src/less/dialog.less +21 -14
- iXBRLViewerPlugin/viewer/src/less/form-controls.less +33 -11
- iXBRLViewerPlugin/viewer/src/less/inspector.less +1045 -726
- iXBRLViewerPlugin/viewer/src/less/loader.less +2 -2
- iXBRLViewerPlugin/viewer/src/less/menu.less +33 -15
- iXBRLViewerPlugin/viewer/src/less/summary.less +16 -6
- iXBRLViewerPlugin/viewer/src/less/tabs.less +9 -9
- iXBRLViewerPlugin/viewer/src/less/text-block-viewer.less +2 -0
- iXBRLViewerPlugin/viewer/src/less/text-mixins.less +2 -1
- iXBRLViewerPlugin/viewer/src/less/validation-report.less +2 -3
- iXBRLViewerPlugin/viewer/src/less/viewer.less +105 -74
- iXBRLViewerPlugin/viewer/webpack.common.js +19 -9
- iXBRLViewerPlugin/xhtmlserialize.py +59 -45
- {ixbrl_viewer-1.4.1.dist-info → ixbrl_viewer-1.4.86.dist-info}/METADATA +181 -50
- ixbrl_viewer-1.4.86.dist-info/RECORD +217 -0
- {ixbrl_viewer-1.4.1.dist-info → ixbrl_viewer-1.4.86.dist-info}/WHEEL +1 -1
- ixbrl_viewer-1.4.1.dist-info/LICENSE → ixbrl_viewer-1.4.86.dist-info/licenses/LICENSE.md +8 -14
- {ixbrl_viewer-1.4.1.dist-info → ixbrl_viewer-1.4.86.dist-info}/top_level.txt +0 -1
- iXBRLViewerPlugin/viewer/src/js/calculations.js +0 -111
- iXBRLViewerPlugin/viewer/src/js/interact.min.js +0 -6
- ixbrl_viewer-1.4.1.dist-info/RECORD +0 -155
- tests/__init__.py +0 -0
- tests/puppeteer/framework/core_elements.js +0 -117
- tests/puppeteer/framework/page_objects/doc_frame.js +0 -105
- tests/puppeteer/framework/page_objects/fact_details_panel.js +0 -80
- tests/puppeteer/framework/page_objects/search_panel.js +0 -76
- tests/puppeteer/framework/page_objects/toolbar.js +0 -18
- tests/puppeteer/framework/utils.js +0 -3
- tests/puppeteer/framework/viewer_page.js +0 -103
- tests/puppeteer/puppeteer_test_run_via_intellij.jpg +0 -0
- tests/puppeteer/test_filings/filing_documents_smoke_test.zip +0 -0
- tests/puppeteer/test_filings/highlights.zip +0 -0
- tests/puppeteer/tests/fact_properties.test.js +0 -78
- tests/puppeteer/tests/highlight.test.js +0 -186
- tests/puppeteer/tests/search.test.js +0 -86
- tests/puppeteer/tools/generate.sh +0 -15
- tests/unit_tests/__init__.py +0 -0
- tests/unit_tests/iXBRLViewerPlugin/__init__.py +0 -0
- tests/unit_tests/iXBRLViewerPlugin/mock_arelle.py +0 -39
- tests/unit_tests/iXBRLViewerPlugin/test_iXBRLViewer.py +0 -641
- tests/unit_tests/iXBRLViewerPlugin/test_xhtmlserialize.py +0 -310
- {ixbrl_viewer-1.4.1.dist-info → ixbrl_viewer-1.4.86.dist-info}/entry_points.txt +0 -0
- {ixbrl_viewer-1.4.1.dist-info → ixbrl_viewer-1.4.86.dist-info/licenses}/NOTICE +0 -0
|
@@ -1,419 +1,328 @@
|
|
|
1
1
|
// See COPYRIGHT.md for copyright information
|
|
2
2
|
|
|
3
|
-
import { Fact } from "./fact.js"
|
|
4
|
-
import { Footnote } from "./footnote.js"
|
|
5
|
-
import { QName } from "./qname.js"
|
|
6
3
|
import { Concept } from "./concept.js";
|
|
7
|
-
import {
|
|
8
|
-
import { ViewerOptions } from "./viewerOptions.js";
|
|
9
|
-
import { setDefault, titleCase } from "./util.js";
|
|
10
|
-
import $ from 'jquery'
|
|
4
|
+
import { setDefault } from "./util.js";
|
|
11
5
|
import i18next from "i18next";
|
|
12
6
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
// A map of IDs to Fact and Footnote objects
|
|
16
|
-
this._items = {};
|
|
17
|
-
this._ixNodeMap = {};
|
|
18
|
-
this._viewerOptions = new ViewerOptions();
|
|
19
|
-
this._reverseRelationshipCache = {};
|
|
20
|
-
}
|
|
7
|
+
// Class to represent the XBRL data from a single target document in a single
|
|
8
|
+
// Inline XBRL Document or Document Set.
|
|
21
9
|
|
|
22
|
-
|
|
23
|
-
* Set additional information about facts obtained from parsing the iXBRL.
|
|
24
|
-
*/
|
|
25
|
-
iXBRLReport.prototype.setIXNodeMap = function(ixData) {
|
|
26
|
-
this._ixNodeMap = ixData;
|
|
27
|
-
this._initialize();
|
|
28
|
-
}
|
|
10
|
+
export class XBRLReport {
|
|
29
11
|
|
|
30
|
-
|
|
12
|
+
constructor(reportSet, reportData) {
|
|
13
|
+
this.reportSet = reportSet;
|
|
14
|
+
this._reportData = reportData;
|
|
15
|
+
// A map of IDs to Fact and Footnote objects
|
|
16
|
+
this._reverseRelationshipCache = {};
|
|
17
|
+
}
|
|
31
18
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
19
|
+
availableLanguages() {
|
|
20
|
+
if (!this._availableLanguages) {
|
|
21
|
+
this._availableLanguages = new Set()
|
|
22
|
+
for (const c of Object.values(this._reportData.concepts)) {
|
|
23
|
+
for (const ll of Object.values(c.labels)) {
|
|
24
|
+
for (const lang of Object.keys(ll)) {
|
|
25
|
+
this._availableLanguages.add(lang);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return this._availableLanguages;
|
|
31
|
+
}
|
|
36
32
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
this._items[id] = new Fact(this, id);
|
|
33
|
+
facts() {
|
|
34
|
+
return this.reportSet.factsForReport(this);
|
|
40
35
|
}
|
|
41
36
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
//
|
|
45
|
-
// Associate source facts with target footnote/facts to allow two way
|
|
46
|
-
// navigation.
|
|
47
|
-
for (const id in this.data.facts) {
|
|
48
|
-
const f = this._items[id];
|
|
49
|
-
const fns = this.data.facts[id].fn || [];
|
|
50
|
-
fns.forEach((fnid) => {
|
|
51
|
-
var fn = this._items[fnid];
|
|
52
|
-
if (fn === undefined) {
|
|
53
|
-
fn = new Footnote(this, fnid, "Footnote " + (fnorder.indexOf(fnid) + 1));
|
|
54
|
-
this._items[fnid] = fn;
|
|
55
|
-
}
|
|
56
|
-
// Associate fact with footnote
|
|
57
|
-
fn.addLinkedFact(f);
|
|
58
|
-
});
|
|
37
|
+
targetDocument() {
|
|
38
|
+
return this._reportData.target ?? null;
|
|
59
39
|
}
|
|
60
|
-
}
|
|
61
40
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}));
|
|
70
|
-
} else {
|
|
71
|
-
this._calculationContributors = new Set();
|
|
41
|
+
getChildRelationships(conceptName, arcrole) {
|
|
42
|
+
const rels = {}
|
|
43
|
+
const elrs = this._reportData.rels[arcrole] || {};
|
|
44
|
+
for (const elr in elrs) {
|
|
45
|
+
if (conceptName in elrs[elr]) {
|
|
46
|
+
rels[elr] = elrs[elr][conceptName];
|
|
47
|
+
}
|
|
72
48
|
}
|
|
49
|
+
return rels;
|
|
73
50
|
}
|
|
74
|
-
return this._calculationContributors.has(c);
|
|
75
|
-
}
|
|
76
51
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
52
|
+
/*
|
|
53
|
+
* Build and cache an inverse map of relationships for a given arcrole for
|
|
54
|
+
* efficient lookup of parents concept from a child.
|
|
55
|
+
*
|
|
56
|
+
* Map is arcrole => elr => target => [ rel, ... ]
|
|
57
|
+
*
|
|
58
|
+
* "rel" is modified to have a "src" property with the source concept.
|
|
59
|
+
*/
|
|
60
|
+
_reverseRelationships(arcrole) {
|
|
61
|
+
if (!(arcrole in this._reverseRelationshipCache)) {
|
|
62
|
+
const rrc = {};
|
|
63
|
+
const elrs = this._reportData.rels[arcrole] || {};
|
|
64
|
+
for (const [elr, relSet] of Object.entries(elrs)) {
|
|
65
|
+
for (const [src, rels] of Object.entries(relSet)) {
|
|
66
|
+
for (const r of rels) {
|
|
67
|
+
r.src = src;
|
|
68
|
+
setDefault(setDefault(rrc, elr, {}), r.t, []).push(r);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
this._reverseRelationshipCache[arcrole] = rrc;
|
|
85
73
|
}
|
|
74
|
+
return this._reverseRelationshipCache[arcrole];
|
|
86
75
|
}
|
|
87
|
-
return this._calculationSummations.has(c);
|
|
88
|
-
}
|
|
89
76
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
return "<no label>";
|
|
97
|
-
}
|
|
98
|
-
const labels = concept.labels[rolePrefix]
|
|
99
|
-
if (labels === undefined || Object.keys(labels).length == 0) {
|
|
100
|
-
return undefined;
|
|
101
|
-
}
|
|
102
|
-
else {
|
|
103
|
-
var label;
|
|
104
|
-
if (lang && labels[lang]) {
|
|
105
|
-
label = labels[lang];
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
// Fall back on English, then any label deterministically.
|
|
109
|
-
label = labels["en"] || labels["en-us"] || labels[Object.keys(labels).sort()[0]];
|
|
110
|
-
}
|
|
111
|
-
if (label === undefined) {
|
|
112
|
-
return undefined;
|
|
113
|
-
}
|
|
114
|
-
var s = '';
|
|
115
|
-
if (showPrefix && this._viewerOptions.showPrefixes) {
|
|
116
|
-
s = "(" + this.qname(c).prefix + ") ";
|
|
77
|
+
getParentRelationships(conceptName, arcrole) {
|
|
78
|
+
const rels = {}
|
|
79
|
+
for (const [elr, relSet] of Object.entries(this._reverseRelationships(arcrole))) {
|
|
80
|
+
if (conceptName in relSet) {
|
|
81
|
+
rels[elr] = relSet[conceptName];
|
|
82
|
+
}
|
|
117
83
|
}
|
|
118
|
-
|
|
119
|
-
return s;
|
|
84
|
+
return rels;
|
|
120
85
|
}
|
|
121
|
-
}
|
|
122
86
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
return c;
|
|
87
|
+
getParentRelationshipsInGroup(conceptName, arcrole, elr) {
|
|
88
|
+
const relSet = this._reverseRelationships(arcrole)[elr] || {};
|
|
89
|
+
return relSet[conceptName] || [];
|
|
127
90
|
}
|
|
128
|
-
return label;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
iXBRLReport.prototype.availableLanguages = function() {
|
|
132
|
-
if (!this._availableLanguages) {
|
|
133
|
-
var map = {};
|
|
134
|
-
$.each(this.data.concepts, function (k,v) {
|
|
135
|
-
$.each(v.labels, function (rolePrefx, ll) {
|
|
136
|
-
$.each(ll, function (lang, v) {
|
|
137
|
-
map[lang] = 1;
|
|
138
|
-
});
|
|
139
|
-
});
|
|
140
|
-
});
|
|
141
|
-
this._availableLanguages = Object.keys(map);
|
|
142
91
|
|
|
92
|
+
dimensionDefault(dimensionName) {
|
|
93
|
+
// ELR is irrelevant for dimension-default relationships, so check all of
|
|
94
|
+
// them, and return the first (illegal for there to be more than one
|
|
95
|
+
for (const rel of Object.values(this._reportData.rels["d-d"] || {})) {
|
|
96
|
+
if (dimensionName in rel) {
|
|
97
|
+
return rel[dimensionName][0].t;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return undefined;
|
|
143
101
|
}
|
|
144
|
-
return this._availableLanguages;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
iXBRLReport.prototype.languageNames = function() {
|
|
148
|
-
return this.data.languages;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
iXBRLReport.prototype.getItemById = function(id) {
|
|
152
|
-
return this._items[id];
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
iXBRLReport.prototype.getIXNodeForItemId = function(id) {
|
|
156
|
-
return this._ixNodeMap[id] || {};
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
iXBRLReport.prototype.facts = function() {
|
|
160
|
-
return Object.keys(this.data.facts).map(id => this.getItemById(id));
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
iXBRLReport.prototype.filingDocuments = function() {
|
|
164
|
-
return this.data.filingDocuments;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
iXBRLReport.prototype.prefixMap = function() {
|
|
168
|
-
return this.data.prefixes;
|
|
169
|
-
}
|
|
170
102
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
this._usedPrefixes = new Set(Object.values(this._items)
|
|
174
|
-
.filter(f => f instanceof Fact)
|
|
175
|
-
.map(f => f.getConceptPrefix()));
|
|
103
|
+
relationshipGroups(arcrole) {
|
|
104
|
+
return Object.keys(this._reportData.rels[arcrole] || {});
|
|
176
105
|
}
|
|
177
|
-
return this._usedPrefixes;
|
|
178
|
-
}
|
|
179
106
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
.map(f => f.unit()?.value())
|
|
189
|
-
.filter(f => f)
|
|
190
|
-
.sort());
|
|
107
|
+
relationshipGroupRoots(arcrole, elr) {
|
|
108
|
+
const roots = [];
|
|
109
|
+
for (const conceptName in this._reportData.rels[arcrole][elr]) {
|
|
110
|
+
if (!(elr in this.getParentRelationships(conceptName, arcrole))) {
|
|
111
|
+
roots.push(conceptName);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return roots;
|
|
191
115
|
}
|
|
192
|
-
return this._usedUnits;
|
|
193
|
-
}
|
|
194
116
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
117
|
+
getAlignedFacts(f, coveredAspects) {
|
|
118
|
+
// XXX should filter to current report facts?
|
|
119
|
+
const all = this.reportSet.facts();
|
|
120
|
+
const aligned = [];
|
|
121
|
+
if (!coveredAspects) {
|
|
122
|
+
coveredAspects = {};
|
|
123
|
+
}
|
|
124
|
+
for (const ff of all) {
|
|
125
|
+
if (ff.isAligned(f, coveredAspects)) {
|
|
126
|
+
aligned.push(ff);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
return aligned;
|
|
206
130
|
}
|
|
207
|
-
return this._unitsMap[unitKey];
|
|
208
|
-
}
|
|
209
131
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
if (scale !== null && scale !== undefined) {
|
|
218
|
-
if (!(scale in usedScalesMap)) {
|
|
219
|
-
usedScalesMap[scale] = new Set();
|
|
220
|
-
}
|
|
221
|
-
const labels = usedScalesMap[scale];
|
|
222
|
-
const label = titleCase(fact.getScaleLabel(scale));
|
|
223
|
-
if (label && !labels.has(label)) {
|
|
224
|
-
labels.add(label);
|
|
132
|
+
deduplicate(facts) {
|
|
133
|
+
const ff = [];
|
|
134
|
+
for (const f of facts) {
|
|
135
|
+
let dupe = false;
|
|
136
|
+
for (const other of ff) {
|
|
137
|
+
if (other.isAligned(f,{})) {
|
|
138
|
+
dupe = true;
|
|
225
139
|
}
|
|
226
140
|
}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
iXBRLReport.prototype.roleMap = function() {
|
|
232
|
-
return this.data.roles;
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
iXBRLReport.prototype.qname = function(v) {
|
|
236
|
-
return new QName(this.prefixMap(), v);
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
iXBRLReport.prototype.getChildRelationships = function(conceptName, arcrole) {
|
|
240
|
-
var rels = {}
|
|
241
|
-
const elrs = this.data.rels[arcrole] || {};
|
|
242
|
-
for (const elr in elrs) {
|
|
243
|
-
if (conceptName in elrs[elr]) {
|
|
244
|
-
rels[elr] = elrs[elr][conceptName];
|
|
141
|
+
if (!dupe) {
|
|
142
|
+
ff.push(f);
|
|
143
|
+
}
|
|
245
144
|
}
|
|
145
|
+
return ff;
|
|
246
146
|
}
|
|
247
|
-
return rels;
|
|
248
|
-
}
|
|
249
147
|
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
148
|
+
getConcept(name) {
|
|
149
|
+
return new Concept(this, name);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
getRoleLabel(rolePrefix) {
|
|
153
|
+
/* This is currently hard-coded to "en" as the generator does not yet
|
|
154
|
+
* support generic labels, and instead provides the (non-localisable) role
|
|
155
|
+
* definition as a single "en" label.
|
|
156
|
+
*
|
|
157
|
+
* Returns the ELR URI if there is no label
|
|
158
|
+
*/
|
|
159
|
+
const labels = this._reportData.roleDefs[rolePrefix];
|
|
160
|
+
if (labels !== undefined) {
|
|
161
|
+
const label = labels["en"];
|
|
162
|
+
// Earlier versions of the generator added a "null" label if no labels
|
|
163
|
+
// were available.
|
|
164
|
+
if (label !== undefined && label !== null) {
|
|
165
|
+
return label;
|
|
268
166
|
}
|
|
269
167
|
}
|
|
270
|
-
|
|
168
|
+
return undefined;
|
|
271
169
|
}
|
|
272
|
-
return this._reverseRelationshipCache[arcrole];
|
|
273
|
-
}
|
|
274
170
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
for (const [elr, relSet] of Object.entries(this._reverseRelationships(arcrole))) {
|
|
278
|
-
if (conceptName in relSet) {
|
|
279
|
-
rels[elr] = relSet[conceptName];
|
|
280
|
-
}
|
|
171
|
+
getRoleLabelOrURI(rolePrefix) {
|
|
172
|
+
return this.getRoleLabel(rolePrefix) ?? this.reportSet.roleMap()[rolePrefix];
|
|
281
173
|
}
|
|
282
|
-
return rels;
|
|
283
|
-
}
|
|
284
174
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
}
|
|
175
|
+
getLabelRoleLabel(rolePrefix) {
|
|
176
|
+
const roleURI = this.reportSet.roleMap()[rolePrefix];
|
|
177
|
+
if (roleURI === undefined) {
|
|
178
|
+
return undefined;
|
|
179
|
+
}
|
|
290
180
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
181
|
+
// Built-in label roles don't have a definition in the taxonomy. Do an
|
|
182
|
+
// i18n look-up on the last part of the URI. For "en" the camel-case
|
|
183
|
+
// splitter will do what we want for everything except standard label
|
|
184
|
+
// and documentation label
|
|
185
|
+
const suffix = roleURI.split("/").pop();
|
|
186
|
+
if (roleURI.startsWith("http://www.xbrl.org/2003/role/") && i18next.exists(`labelRoles:${suffix}`)) {
|
|
187
|
+
return i18next.t(`labelRoles:${suffix}`);
|
|
297
188
|
}
|
|
298
|
-
}
|
|
299
|
-
return undefined;
|
|
300
|
-
}
|
|
301
189
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
190
|
+
// Attempt to get a label from the role definition
|
|
191
|
+
const label = this.getRoleLabel(rolePrefix);
|
|
192
|
+
if (label !== undefined) {
|
|
193
|
+
return label;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Fall back on de-camel-casing the last part of the URI
|
|
197
|
+
return suffix
|
|
198
|
+
.replaceAll(/([A-Z][a-z]+)/g, ' $1')
|
|
199
|
+
.trim()
|
|
200
|
+
.replace(/^./, s => s.toUpperCase());
|
|
201
|
+
}
|
|
305
202
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
if (!(elr in this.getParentRelationships(conceptName, arcrole))) {
|
|
310
|
-
roots.push(conceptName);
|
|
203
|
+
localDocuments() {
|
|
204
|
+
if (this._reportData.localDocs === undefined) {
|
|
205
|
+
return {}
|
|
311
206
|
}
|
|
207
|
+
return this._reportData.localDocs;
|
|
312
208
|
}
|
|
313
|
-
return roots;
|
|
314
|
-
}
|
|
315
209
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
var aligned = [];
|
|
319
|
-
if (!coveredAspects) {
|
|
320
|
-
coveredAspects = {};
|
|
210
|
+
qname(v) {
|
|
211
|
+
return this.reportSet.qname(v);
|
|
321
212
|
}
|
|
322
|
-
$.each(all, function (i, ff) {
|
|
323
|
-
if (ff.isAligned(f, coveredAspects)) {
|
|
324
|
-
aligned.push(ff);
|
|
325
|
-
}
|
|
326
|
-
});
|
|
327
|
-
return aligned;
|
|
328
|
-
}
|
|
329
213
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
dupe = true;
|
|
214
|
+
getScaleLabel(scale, unit) {
|
|
215
|
+
let label = i18next.t(`scale:${scale}`, {defaultValue:"noName"});
|
|
216
|
+
if (unit && unit.isMonetary() && scale === -2) {
|
|
217
|
+
let measure = unit.value() ?? '';
|
|
218
|
+
if (measure) {
|
|
219
|
+
measure = this.qname(measure).localname;
|
|
337
220
|
}
|
|
338
|
-
|
|
339
|
-
if (!dupe){
|
|
340
|
-
ff.push(f);
|
|
221
|
+
label = i18next.t(`currencies:cents${measure}`, {defaultValue: label});
|
|
341
222
|
}
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
this._viewerOptions = vo;
|
|
348
|
-
}
|
|
223
|
+
if (label === "noName") {
|
|
224
|
+
return null;
|
|
225
|
+
}
|
|
226
|
+
return label;
|
|
227
|
+
}
|
|
349
228
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
counts[f.conceptQName().prefix] = counts[f.conceptQName().prefix] || 0;
|
|
354
|
-
counts[f.conceptQName().prefix]++;
|
|
355
|
-
});
|
|
356
|
-
var prefixes = Object.keys(counts);
|
|
357
|
-
prefixes.sort(function (a, b) { return counts[b] - counts[a] });
|
|
358
|
-
return prefixes;
|
|
359
|
-
}
|
|
229
|
+
concepts() {
|
|
230
|
+
return this._reportData.concepts;
|
|
231
|
+
}
|
|
360
232
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}
|
|
233
|
+
getLabel(c, rolePrefix, showPrefix) {
|
|
234
|
+
return this.getLabelAndLang(c, rolePrefix, showPrefix).label;
|
|
235
|
+
}
|
|
364
236
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
237
|
+
getLabelAndLang(c, rolePrefix, showPrefix) {
|
|
238
|
+
rolePrefix = rolePrefix || 'std';
|
|
239
|
+
const lang = this.reportSet.viewerOptions.language;
|
|
240
|
+
const concept = this._reportData.concepts[c];
|
|
241
|
+
if (concept === undefined) {
|
|
242
|
+
console.log("Attempt to get label for undefined concept: " + c);
|
|
243
|
+
return { label: "<no label>" };
|
|
244
|
+
}
|
|
245
|
+
const labels = concept.labels[rolePrefix]
|
|
246
|
+
if (labels === undefined || Object.keys(labels).length == 0) {
|
|
247
|
+
return { label: undefined };
|
|
248
|
+
}
|
|
249
|
+
else {
|
|
250
|
+
let label;
|
|
251
|
+
let actualLang;
|
|
252
|
+
if (lang && labels[lang]) {
|
|
253
|
+
label = labels[lang];
|
|
254
|
+
actualLang = lang;
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
// Fall back on English, then any label deterministically.
|
|
258
|
+
for (const l of ["en", "en-us", Object.keys(labels).sort()[0]]) {
|
|
259
|
+
if (labels[l] !== undefined) {
|
|
260
|
+
label = labels[l];
|
|
261
|
+
actualLang = l;
|
|
262
|
+
break;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (label === undefined) {
|
|
267
|
+
return {label: undefined};
|
|
268
|
+
}
|
|
269
|
+
let s = '';
|
|
270
|
+
if (showPrefix && this.reportSet.viewerOptions.showPrefixes) {
|
|
271
|
+
s = "(" + this.reportSet.taxonomyNamer.fromQName(this.qname(c)).prefix + ") ";
|
|
272
|
+
}
|
|
273
|
+
s += label;
|
|
274
|
+
return { label: s, lang: actualLang };
|
|
379
275
|
}
|
|
380
276
|
}
|
|
381
|
-
return this.roleMap()[rolePrefix];
|
|
382
|
-
}
|
|
383
277
|
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
278
|
+
getLabelOrName(c, rolePrefix, showPrefix) {
|
|
279
|
+
const label = this.getLabel(c, rolePrefix, showPrefix);
|
|
280
|
+
if (label === undefined) {
|
|
281
|
+
return c;
|
|
282
|
+
}
|
|
283
|
+
return label;
|
|
387
284
|
}
|
|
388
|
-
return this.data.localDocs;
|
|
389
|
-
}
|
|
390
285
|
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
286
|
+
getLabelOrNameAndLang(c, rolePrefix, showPrefix) {
|
|
287
|
+
const labelLang = this.getLabelAndLang(c, rolePrefix, showPrefix);
|
|
288
|
+
if (labelLang.label === undefined) {
|
|
289
|
+
return { label: c };
|
|
290
|
+
}
|
|
291
|
+
return labelLang;
|
|
394
292
|
}
|
|
395
|
-
return this.data.docSetFiles;
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
iXBRLReport.prototype.isDocumentSet = function() {
|
|
399
|
-
return this.documentSetFiles().length > 1;
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
iXBRLReport.prototype.usesAnchoring = function() {
|
|
403
|
-
return this.data.rels["w-n"] !== undefined;
|
|
404
|
-
}
|
|
405
293
|
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
294
|
+
isCalculationContributor(c) {
|
|
295
|
+
if (this._calculationContributors === undefined) {
|
|
296
|
+
if (this._reportData.rels?.calc) {
|
|
297
|
+
this._calculationContributors = new Set(Object.values(this._reportData.rels.calc).flatMap(calculations => {
|
|
298
|
+
return Object.values(calculations).flatMap(contributors => {
|
|
299
|
+
return contributors.map(c => c.t);
|
|
300
|
+
});
|
|
301
|
+
}));
|
|
302
|
+
} else {
|
|
303
|
+
this._calculationContributors = new Set();
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
return this._calculationContributors.has(c);
|
|
307
|
+
}
|
|
409
308
|
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
309
|
+
isCalculationSummation(c) {
|
|
310
|
+
if (this._calculationSummations === undefined) {
|
|
311
|
+
if (this._reportData.rels?.calc) {
|
|
312
|
+
this._calculationSummations = new Set(Object.values(this._reportData.rels.calc).flatMap(calculations => {
|
|
313
|
+
return Object.keys(calculations);
|
|
314
|
+
}));
|
|
315
|
+
} else {
|
|
316
|
+
this._calculationSummations = new Set();
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
return this._calculationSummations.has(c);
|
|
414
320
|
}
|
|
415
|
-
|
|
416
|
-
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* @return {Array[String]} Software credit text labels provided with this report for display purposes.
|
|
324
|
+
*/
|
|
325
|
+
softwareCredits() {
|
|
326
|
+
return this._reportData.softwareCredits ?? [];
|
|
417
327
|
}
|
|
418
|
-
return label;
|
|
419
328
|
}
|