@trebco/treb 23.6.5 → 25.0.0-rc2
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.
- package/.eslintignore +8 -0
- package/.eslintrc.js +164 -0
- package/README-shadow-DOM.md +88 -0
- package/README.md +37 -130
- package/api-config.json +29 -0
- package/api-generator/api-generator-types.ts +82 -0
- package/api-generator/api-generator.ts +1172 -0
- package/api-generator/package.json +3 -0
- package/build/treb-spreadsheet.mjs +14 -0
- package/{treb.d.ts → build/treb.d.ts} +323 -271
- package/esbuild-custom-element.mjs +336 -0
- package/esbuild.js +305 -0
- package/package.json +49 -14
- package/treb-base-types/package.json +5 -0
- package/treb-base-types/src/api_types.ts +36 -0
- package/treb-base-types/src/area.ts +583 -0
- package/treb-base-types/src/basic_types.ts +45 -0
- package/treb-base-types/src/cell.ts +612 -0
- package/treb-base-types/src/cells.ts +1066 -0
- package/treb-base-types/src/color.ts +124 -0
- package/treb-base-types/src/import.ts +71 -0
- package/treb-base-types/src/index-standalone.ts +29 -0
- package/treb-base-types/src/index.ts +42 -0
- package/treb-base-types/src/layout.ts +47 -0
- package/treb-base-types/src/localization.ts +187 -0
- package/treb-base-types/src/rectangle.ts +145 -0
- package/treb-base-types/src/render_text.ts +72 -0
- package/treb-base-types/src/style.ts +545 -0
- package/treb-base-types/src/table.ts +109 -0
- package/treb-base-types/src/text_part.ts +54 -0
- package/treb-base-types/src/theme.ts +608 -0
- package/treb-base-types/src/union.ts +152 -0
- package/treb-base-types/src/value-type.ts +164 -0
- package/treb-base-types/style/resizable.css +59 -0
- package/treb-calculator/modern.tsconfig.json +11 -0
- package/treb-calculator/package.json +5 -0
- package/treb-calculator/src/calculator.ts +2546 -0
- package/treb-calculator/src/complex-math.ts +558 -0
- package/treb-calculator/src/dag/array-vertex.ts +198 -0
- package/treb-calculator/src/dag/graph.ts +951 -0
- package/treb-calculator/src/dag/leaf_vertex.ts +118 -0
- package/treb-calculator/src/dag/spreadsheet_vertex.ts +327 -0
- package/treb-calculator/src/dag/spreadsheet_vertex_base.ts +44 -0
- package/treb-calculator/src/dag/vertex.ts +352 -0
- package/treb-calculator/src/descriptors.ts +162 -0
- package/treb-calculator/src/expression-calculator.ts +1069 -0
- package/treb-calculator/src/function-error.ts +103 -0
- package/treb-calculator/src/function-library.ts +103 -0
- package/treb-calculator/src/functions/base-functions.ts +1214 -0
- package/treb-calculator/src/functions/checkbox.ts +164 -0
- package/treb-calculator/src/functions/complex-functions.ts +253 -0
- package/treb-calculator/src/functions/finance-functions.ts +399 -0
- package/treb-calculator/src/functions/information-functions.ts +102 -0
- package/treb-calculator/src/functions/matrix-functions.ts +182 -0
- package/treb-calculator/src/functions/sparkline.ts +335 -0
- package/treb-calculator/src/functions/statistics-functions.ts +350 -0
- package/treb-calculator/src/functions/text-functions.ts +298 -0
- package/treb-calculator/src/index.ts +27 -0
- package/treb-calculator/src/notifier-types.ts +59 -0
- package/treb-calculator/src/primitives.ts +428 -0
- package/treb-calculator/src/utilities.ts +305 -0
- package/treb-charts/package.json +5 -0
- package/treb-charts/src/chart-functions.ts +156 -0
- package/treb-charts/src/chart-types.ts +230 -0
- package/treb-charts/src/chart.ts +1288 -0
- package/treb-charts/src/index.ts +24 -0
- package/treb-charts/src/main.ts +37 -0
- package/treb-charts/src/rectangle.ts +52 -0
- package/treb-charts/src/renderer.ts +1841 -0
- package/treb-charts/src/util.ts +122 -0
- package/treb-charts/style/charts.scss +221 -0
- package/treb-charts/style/old-charts.scss +250 -0
- package/treb-embed/markup/layout.html +137 -0
- package/treb-embed/markup/toolbar.html +175 -0
- package/treb-embed/modern.tsconfig.json +25 -0
- package/treb-embed/src/custom-element/content-types.d.ts +18 -0
- package/treb-embed/src/custom-element/global.d.ts +11 -0
- package/treb-embed/src/custom-element/spreadsheet-constructor.ts +1228 -0
- package/treb-embed/src/custom-element/treb-global.ts +44 -0
- package/treb-embed/src/custom-element/treb-spreadsheet-element.ts +52 -0
- package/treb-embed/src/embedded-spreadsheet.ts +5358 -0
- package/treb-embed/src/index.ts +16 -0
- package/treb-embed/src/language-model.ts +41 -0
- package/treb-embed/src/options.ts +298 -0
- package/treb-embed/src/progress-dialog.ts +228 -0
- package/treb-embed/src/selection-state.ts +16 -0
- package/treb-embed/src/spinner.ts +42 -0
- package/treb-embed/src/toolbar-message.ts +96 -0
- package/treb-embed/src/types.ts +167 -0
- package/treb-embed/style/autocomplete.scss +103 -0
- package/treb-embed/style/dark-theme.scss +114 -0
- package/treb-embed/style/defaults.scss +36 -0
- package/treb-embed/style/dialog.scss +181 -0
- package/treb-embed/style/dropdown-select.scss +101 -0
- package/treb-embed/style/formula-bar.scss +193 -0
- package/treb-embed/style/grid.scss +374 -0
- package/treb-embed/style/layout.scss +424 -0
- package/treb-embed/style/mouse-mask.scss +67 -0
- package/treb-embed/style/note.scss +92 -0
- package/treb-embed/style/overlay-editor.scss +102 -0
- package/treb-embed/style/spinner.scss +92 -0
- package/treb-embed/style/tab-bar.scss +228 -0
- package/treb-embed/style/table.scss +80 -0
- package/treb-embed/style/theme-defaults.scss +444 -0
- package/treb-embed/style/toolbar.scss +416 -0
- package/treb-embed/style/tooltip.scss +68 -0
- package/treb-embed/style/treb-icons.scss +130 -0
- package/treb-embed/style/treb-spreadsheet-element.scss +20 -0
- package/treb-embed/style/z-index.scss +43 -0
- package/treb-export/docs/charts.md +68 -0
- package/treb-export/modern.tsconfig.json +19 -0
- package/treb-export/package.json +4 -0
- package/treb-export/src/address-type.ts +77 -0
- package/treb-export/src/base-template.ts +22 -0
- package/treb-export/src/column-width.ts +85 -0
- package/treb-export/src/drawing2/chart-template-components2.ts +389 -0
- package/treb-export/src/drawing2/chart2.ts +282 -0
- package/treb-export/src/drawing2/column-chart-template2.ts +521 -0
- package/treb-export/src/drawing2/donut-chart-template2.ts +296 -0
- package/treb-export/src/drawing2/drawing2.ts +355 -0
- package/treb-export/src/drawing2/embedded-image.ts +71 -0
- package/treb-export/src/drawing2/scatter-chart-template2.ts +555 -0
- package/treb-export/src/export-worker/export-worker.ts +99 -0
- package/treb-export/src/export-worker/index-modern.ts +22 -0
- package/treb-export/src/export2.ts +2204 -0
- package/treb-export/src/import2.ts +882 -0
- package/treb-export/src/relationship.ts +36 -0
- package/treb-export/src/shared-strings2.ts +128 -0
- package/treb-export/src/template-2.ts +22 -0
- package/treb-export/src/unescape_xml.ts +47 -0
- package/treb-export/src/workbook-sheet2.ts +182 -0
- package/treb-export/src/workbook-style2.ts +1285 -0
- package/treb-export/src/workbook-theme2.ts +88 -0
- package/treb-export/src/workbook2.ts +491 -0
- package/treb-export/src/xml-utils.ts +201 -0
- package/treb-export/template/base/[Content_Types].xml +2 -0
- package/treb-export/template/base/_rels/.rels +2 -0
- package/treb-export/template/base/docProps/app.xml +2 -0
- package/treb-export/template/base/docProps/core.xml +12 -0
- package/treb-export/template/base/xl/_rels/workbook.xml.rels +2 -0
- package/treb-export/template/base/xl/sharedStrings.xml +2 -0
- package/treb-export/template/base/xl/styles.xml +2 -0
- package/treb-export/template/base/xl/theme/theme1.xml +2 -0
- package/treb-export/template/base/xl/workbook.xml +2 -0
- package/treb-export/template/base/xl/worksheets/sheet1.xml +2 -0
- package/treb-export/template/base.xlsx +0 -0
- package/treb-format/package.json +8 -0
- package/treb-format/src/format.test.ts +213 -0
- package/treb-format/src/format.ts +942 -0
- package/treb-format/src/format_cache.ts +199 -0
- package/treb-format/src/format_parser.ts +723 -0
- package/treb-format/src/index.ts +25 -0
- package/treb-format/src/number_format_section.ts +100 -0
- package/treb-format/src/value_parser.ts +337 -0
- package/treb-grid/package.json +5 -0
- package/treb-grid/src/editors/autocomplete.ts +394 -0
- package/treb-grid/src/editors/autocomplete_matcher.ts +260 -0
- package/treb-grid/src/editors/formula_bar.ts +473 -0
- package/treb-grid/src/editors/formula_editor_base.ts +910 -0
- package/treb-grid/src/editors/overlay_editor.ts +511 -0
- package/treb-grid/src/index.ts +37 -0
- package/treb-grid/src/layout/base_layout.ts +2618 -0
- package/treb-grid/src/layout/grid_layout.ts +299 -0
- package/treb-grid/src/layout/rectangle_cache.ts +86 -0
- package/treb-grid/src/render/selection-renderer.ts +414 -0
- package/treb-grid/src/render/svg_header_overlay.ts +93 -0
- package/treb-grid/src/render/svg_selection_block.ts +187 -0
- package/treb-grid/src/render/tile_renderer.ts +2122 -0
- package/treb-grid/src/types/annotation.ts +216 -0
- package/treb-grid/src/types/border_constants.ts +34 -0
- package/treb-grid/src/types/clipboard_data.ts +31 -0
- package/treb-grid/src/types/data_model.ts +334 -0
- package/treb-grid/src/types/drag_mask.ts +81 -0
- package/treb-grid/src/types/grid.ts +7743 -0
- package/treb-grid/src/types/grid_base.ts +3644 -0
- package/treb-grid/src/types/grid_command.ts +470 -0
- package/treb-grid/src/types/grid_events.ts +124 -0
- package/treb-grid/src/types/grid_options.ts +97 -0
- package/treb-grid/src/types/grid_selection.ts +60 -0
- package/treb-grid/src/types/named_range.ts +369 -0
- package/treb-grid/src/types/scale-control.ts +202 -0
- package/treb-grid/src/types/serialize_options.ts +72 -0
- package/treb-grid/src/types/set_range_options.ts +52 -0
- package/treb-grid/src/types/sheet.ts +3099 -0
- package/treb-grid/src/types/sheet_types.ts +95 -0
- package/treb-grid/src/types/tab_bar.ts +464 -0
- package/treb-grid/src/types/tile.ts +59 -0
- package/treb-grid/src/types/update_flags.ts +75 -0
- package/treb-grid/src/util/dom_utilities.ts +44 -0
- package/treb-grid/src/util/fontmetrics2.ts +179 -0
- package/treb-grid/src/util/ua.ts +104 -0
- package/treb-logo.svg +18 -0
- package/treb-parser/package.json +5 -0
- package/treb-parser/src/csv-parser.ts +122 -0
- package/treb-parser/src/index.ts +25 -0
- package/treb-parser/src/md-parser.ts +526 -0
- package/treb-parser/src/parser-types.ts +397 -0
- package/treb-parser/src/parser.test.ts +298 -0
- package/treb-parser/src/parser.ts +2673 -0
- package/treb-utils/package.json +5 -0
- package/treb-utils/src/dispatch.ts +57 -0
- package/treb-utils/src/event_source.ts +147 -0
- package/treb-utils/src/ievent_source.ts +33 -0
- package/treb-utils/src/index.ts +31 -0
- package/treb-utils/src/measurement.ts +174 -0
- package/treb-utils/src/resizable.ts +160 -0
- package/treb-utils/src/scale.ts +137 -0
- package/treb-utils/src/serialize_html.ts +124 -0
- package/treb-utils/src/template.ts +70 -0
- package/treb-utils/src/validate_uri.ts +61 -0
- package/tsconfig.json +10 -0
- package/tsproject.json +30 -0
- package/util/license-plugin-esbuild.js +86 -0
- package/util/list-css-vars.sh +46 -0
- package/README-esm.md +0 -37
- package/treb-bundle.css +0 -2
- package/treb-bundle.mjs +0 -15
|
@@ -0,0 +1,352 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of TREB.
|
|
3
|
+
*
|
|
4
|
+
* TREB is free software: you can redistribute it and/or modify it under the
|
|
5
|
+
* terms of the GNU General Public License as published by the Free Software
|
|
6
|
+
* Foundation, either version 3 of the License, or (at your option) any
|
|
7
|
+
* later version.
|
|
8
|
+
*
|
|
9
|
+
* TREB is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
10
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
11
|
+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
12
|
+
* details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU General Public License along
|
|
15
|
+
* with TREB. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*
|
|
17
|
+
* Copyright 2022-2023 trebco, llc.
|
|
18
|
+
* info@treb.app
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* colors for the CLRS color algorithm.
|
|
24
|
+
*
|
|
25
|
+
* these colors are useful because gray is "in between" white and black, but
|
|
26
|
+
* (outside of the general move away from using white/black as identifiers) it
|
|
27
|
+
* might be easier to conceptualize with descriptive labels like "untested"
|
|
28
|
+
* (white), "being tested", (gray) and "testing complete" (black).
|
|
29
|
+
*/
|
|
30
|
+
export enum Color {
|
|
31
|
+
white, gray, black
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export class Vertex {
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* vertex and its subclasses have a type parameter for type
|
|
38
|
+
* guards/reflection; each instance has a type that is set
|
|
39
|
+
* to the static class type.
|
|
40
|
+
*/
|
|
41
|
+
public static type = 'vertex';
|
|
42
|
+
|
|
43
|
+
// --- members ---
|
|
44
|
+
|
|
45
|
+
public type = Vertex.type; // for type guard
|
|
46
|
+
|
|
47
|
+
public color = Color.white; // for loop check
|
|
48
|
+
|
|
49
|
+
/** dependencies */
|
|
50
|
+
// public edges_in: Vertex[] = [];
|
|
51
|
+
public edges_in: Set<Vertex> = new Set();
|
|
52
|
+
|
|
53
|
+
/** dependents */
|
|
54
|
+
// public edges_out: Vertex[] = [];
|
|
55
|
+
public edges_out: Set<Vertex> = new Set();
|
|
56
|
+
|
|
57
|
+
// --- accessors ---
|
|
58
|
+
|
|
59
|
+
get has_inbound_edges(): boolean { return this.edges_in.size > 0; }
|
|
60
|
+
|
|
61
|
+
get has_outbound_edges(): boolean { return this.edges_out.size > 0; }
|
|
62
|
+
|
|
63
|
+
// --- cleanup operations ---
|
|
64
|
+
|
|
65
|
+
/** reset this node */
|
|
66
|
+
public Reset(): void {
|
|
67
|
+
|
|
68
|
+
for (const edge of this.edges_out) {
|
|
69
|
+
edge.RemoveDependency(this);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
for (const edge of this.edges_in) {
|
|
73
|
+
edge.RemoveDependent(this);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
//this.edges_out = [];
|
|
77
|
+
this.edges_out.clear();
|
|
78
|
+
//this.edges_in = [];
|
|
79
|
+
this.edges_in.clear();
|
|
80
|
+
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** removes all inbound edges (dependencies) */
|
|
84
|
+
public ClearDependencies(): void {
|
|
85
|
+
for (const edge of this.edges_in) {
|
|
86
|
+
edge.RemoveDependent(this);
|
|
87
|
+
|
|
88
|
+
// testing inline...
|
|
89
|
+
// edge.edges_out = edge.edges_out.filter(check => check !== this);
|
|
90
|
+
|
|
91
|
+
}
|
|
92
|
+
// this.edges_in = [];
|
|
93
|
+
this.edges_in.clear();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// --- basic node operations ---
|
|
97
|
+
|
|
98
|
+
/** add a dependent. doesn't add if already in the list */
|
|
99
|
+
public AddDependent(edge: Vertex): void {
|
|
100
|
+
if (edge === this) return; // circular
|
|
101
|
+
|
|
102
|
+
if (this.edges_out.has(edge)) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/*
|
|
107
|
+
for (const check of this.edges_out) {
|
|
108
|
+
if (check === edge) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
*/
|
|
113
|
+
|
|
114
|
+
//this.edges_out.push(edge);
|
|
115
|
+
this.edges_out.add(edge);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** remove a dependent */
|
|
119
|
+
public RemoveDependent(edge: Vertex): void {
|
|
120
|
+
|
|
121
|
+
// this.edges_out = this.edges_out.filter((check) => check !== edge);
|
|
122
|
+
|
|
123
|
+
// updated for performance.
|
|
124
|
+
|
|
125
|
+
// this seems to be faster than any other method of removing an item.
|
|
126
|
+
// (also tried: temp loop and copy non-matching).
|
|
127
|
+
|
|
128
|
+
// this does assume that edges can't be in the list twice, but that
|
|
129
|
+
// should already be true (it would cause all sorts of other problems).
|
|
130
|
+
|
|
131
|
+
// actually does this just win because we break the loop earlier?
|
|
132
|
+
// (presumably in 50% of cases)? even if so, if the splice is not
|
|
133
|
+
// more expensive this is a win.
|
|
134
|
+
|
|
135
|
+
// splice should be expensive, though... weird. because what splice
|
|
136
|
+
// does (AIUI) is reassign array indexes above the delete index.
|
|
137
|
+
// it would be better if we could get rid of indexes altogether, perhaps
|
|
138
|
+
// using a set?
|
|
139
|
+
|
|
140
|
+
// note: tried to improve on splice with some direct methods, nothing
|
|
141
|
+
// seemed to work any better (not worse, either, but if there's no
|
|
142
|
+
// improvement we should use the native method).
|
|
143
|
+
|
|
144
|
+
/*
|
|
145
|
+
for (let i = 0; i < this.edges_out.length; i++) {
|
|
146
|
+
if (this.edges_out[i] === edge) {
|
|
147
|
+
this.edges_out.splice(i, 1);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
*/
|
|
152
|
+
this.edges_out.delete(edge);
|
|
153
|
+
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/** add a dependency. doesn't add if already in the list */
|
|
157
|
+
public AddDependency(edge: Vertex): void {
|
|
158
|
+
if (edge === this) return; // circular
|
|
159
|
+
|
|
160
|
+
/*
|
|
161
|
+
for (const check of this.edges_in) {
|
|
162
|
+
if (check === edge) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
*/
|
|
167
|
+
if (this.edges_in.has(edge)){
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
//this.edges_in.push(edge);
|
|
172
|
+
this.edges_in.add(edge);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/** remove a dependency */
|
|
176
|
+
public RemoveDependency(edge: Vertex): void {
|
|
177
|
+
// this.edges_in = this.edges_in.filter((check) => check !== edge);
|
|
178
|
+
this.edges_in.delete(edge);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* this is a composite operation, because the operations are always called
|
|
183
|
+
* in pairs. this means create a pair of links such that _edge_ depends on
|
|
184
|
+
* _this_.
|
|
185
|
+
*/
|
|
186
|
+
public LinkTo(edge: Vertex): void {
|
|
187
|
+
this.AddDependent(edge);
|
|
188
|
+
edge.AddDependency(this);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* this is an alteranate formulation that may make more intuitive sense.
|
|
193
|
+
* it creates a pair of forward/backward links, such that _this_ depends
|
|
194
|
+
* on _edge_.
|
|
195
|
+
*/
|
|
196
|
+
public DependsOn(edge: Vertex): void {
|
|
197
|
+
this.AddDependency(edge);
|
|
198
|
+
edge.AddDependent(this);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* this is called during calculation (if necessary). on a hit (loop), we
|
|
203
|
+
* reset the color of this, the test node, to white. there are two reasons
|
|
204
|
+
* for this:
|
|
205
|
+
*
|
|
206
|
+
* one, we want subsequent tests to also find the hit. in some cases we may
|
|
207
|
+
* not be marking the node as a loop (if it precedes the backref in the graph),
|
|
208
|
+
* so we want subsequent nodes to also hit the loop. [Q: this makes no sense,
|
|
209
|
+
* because this would still hit if the node were marked grey, assuming you
|
|
210
|
+
* test for that].
|
|
211
|
+
*
|
|
212
|
+
* two, if you fix the loop, on a subsequent call we want to force a re-check,
|
|
213
|
+
* which we can do if the vertex is marked white. [Q: could also be done on
|
|
214
|
+
* gray?]
|
|
215
|
+
*
|
|
216
|
+
* [A: logically you are correct, but this works, and matching grey does not].
|
|
217
|
+
*/
|
|
218
|
+
public LoopCheck(): boolean {
|
|
219
|
+
|
|
220
|
+
|
|
221
|
+
const stack: Vertex[] = [this];
|
|
222
|
+
|
|
223
|
+
while (stack.length) {
|
|
224
|
+
|
|
225
|
+
// note peek: we leave it on the stack
|
|
226
|
+
const v = stack[stack.length - 1];
|
|
227
|
+
|
|
228
|
+
// state flag: unset if we have edges we need to check
|
|
229
|
+
let complete = true;
|
|
230
|
+
|
|
231
|
+
// skip this vertex if it's clean
|
|
232
|
+
if (v.color !== Color.black) {
|
|
233
|
+
|
|
234
|
+
v.color = Color.gray; // set here, not top of function
|
|
235
|
+
|
|
236
|
+
for (const edge of v.edges_out) {
|
|
237
|
+
|
|
238
|
+
if (edge.color === Color.gray) {
|
|
239
|
+
this.color = Color.white; // note: this, not v
|
|
240
|
+
return true; // found a loop
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// if (edge.color === Color.white && edge.edges_out.length) {
|
|
244
|
+
if (edge.color === Color.white && edge.edges_out.size) {
|
|
245
|
+
stack.push(edge);
|
|
246
|
+
complete = false;
|
|
247
|
+
|
|
248
|
+
// the only thing this break does is add loops. we can
|
|
249
|
+
// safely add all (white) edges as long as we don't color
|
|
250
|
+
// them here -- that was the issue in the last version.
|
|
251
|
+
|
|
252
|
+
// break; // ?
|
|
253
|
+
|
|
254
|
+
// if you really want fidelity with the recursive version
|
|
255
|
+
// you could reverse the order, but the order is arbitrary
|
|
256
|
+
// anyway so it makes no difference.
|
|
257
|
+
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (complete) {
|
|
265
|
+
v.color = Color.black;
|
|
266
|
+
stack.pop();
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
|
|
272
|
+
/*
|
|
273
|
+
this.color = Color.gray;
|
|
274
|
+
|
|
275
|
+
// switch to stack algorithm. see the method in Graph for details.
|
|
276
|
+
|
|
277
|
+
// NOTE: this is bugged. need to rewrite. it's generating false positives
|
|
278
|
+
// where the recursive version still works.
|
|
279
|
+
|
|
280
|
+
const stack: Vertex[] = [this];
|
|
281
|
+
|
|
282
|
+
while (stack.length) {
|
|
283
|
+
|
|
284
|
+
const v = stack[stack.length - 1];
|
|
285
|
+
let completed = true;
|
|
286
|
+
|
|
287
|
+
if (v.color !== Color.black) {
|
|
288
|
+
|
|
289
|
+
for (const edge of v.edges_out) {
|
|
290
|
+
|
|
291
|
+
if (edge.color === Color.gray) {
|
|
292
|
+
|
|
293
|
+
// this is different than the graph algo, here we reset the
|
|
294
|
+
// color when we hit a loop.
|
|
295
|
+
|
|
296
|
+
this.color = Color.white; // someone else can test
|
|
297
|
+
return true; // loop
|
|
298
|
+
|
|
299
|
+
}
|
|
300
|
+
else if (edge.color === Color.white) {
|
|
301
|
+
edge.color = Color.gray;
|
|
302
|
+
stack.push(edge);
|
|
303
|
+
completed = false;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
if (completed) {
|
|
311
|
+
stack.pop();
|
|
312
|
+
v.color = Color.black;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
}
|
|
316
|
+
*/
|
|
317
|
+
|
|
318
|
+
/*
|
|
319
|
+
// the old recursive version
|
|
320
|
+
|
|
321
|
+
for (const edge of this.edges_out) {
|
|
322
|
+
if (edge.color === Color.gray || (edge.color === Color.white && edge.LoopCheck())) {
|
|
323
|
+
this.color = Color.white; // someone else can test
|
|
324
|
+
return true; // loop
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
*/
|
|
328
|
+
|
|
329
|
+
this.color = Color.black;
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/*
|
|
334
|
+
public LoopCheck2(compare: Vertex = this): boolean {
|
|
335
|
+
this.color = Color.gray;
|
|
336
|
+
|
|
337
|
+
for (const edge of this.edges_out) {
|
|
338
|
+
if (edge.color === Color.gray || (edge.color === Color.white && edge.LoopCheck2(compare))) {
|
|
339
|
+
this.color = Color.white; // someone else can test
|
|
340
|
+
return edge === compare; // loop
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
this.color = Color.black;
|
|
345
|
+
return false;
|
|
346
|
+
|
|
347
|
+
}
|
|
348
|
+
*/
|
|
349
|
+
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* This file is part of TREB.
|
|
3
|
+
*
|
|
4
|
+
* TREB is free software: you can redistribute it and/or modify it under the
|
|
5
|
+
* terms of the GNU General Public License as published by the Free Software
|
|
6
|
+
* Foundation, either version 3 of the License, or (at your option) any
|
|
7
|
+
* later version.
|
|
8
|
+
*
|
|
9
|
+
* TREB is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
10
|
+
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
11
|
+
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
12
|
+
* details.
|
|
13
|
+
*
|
|
14
|
+
* You should have received a copy of the GNU General Public License along
|
|
15
|
+
* with TREB. If not, see <https://www.gnu.org/licenses/>.
|
|
16
|
+
*
|
|
17
|
+
* Copyright 2022-2023 trebco, llc.
|
|
18
|
+
* info@treb.app
|
|
19
|
+
*
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { RenderFunction, ClickFunction, UnionValue } from 'treb-base-types';
|
|
23
|
+
|
|
24
|
+
// FIXME: at least some of this could move to base types
|
|
25
|
+
|
|
26
|
+
export enum ReturnType {
|
|
27
|
+
value, reference
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* descriptor for an individual argument
|
|
32
|
+
*/
|
|
33
|
+
export interface ArgumentDescriptor {
|
|
34
|
+
|
|
35
|
+
name?: string;
|
|
36
|
+
description?: string;
|
|
37
|
+
default?: any;
|
|
38
|
+
|
|
39
|
+
// moved from function arrays:
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* allows error values to propagate. otherwise, a function will
|
|
43
|
+
* return an #ARG error if any arguments contain errors. used for
|
|
44
|
+
* IsError and IfError, atm.
|
|
45
|
+
*
|
|
46
|
+
* UPDATE: also used in IF.
|
|
47
|
+
*/
|
|
48
|
+
allow_error?: boolean;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* this argument (reference) should be treated as an address, not resolved.
|
|
52
|
+
* it's used for identifying multivariate groups.
|
|
53
|
+
*
|
|
54
|
+
* UPDATE: this is used in reference + lookup functions (Offset, specifically)
|
|
55
|
+
* so don't move to MC lib.
|
|
56
|
+
*/
|
|
57
|
+
address?: boolean;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* require the argument to be a union
|
|
61
|
+
*/
|
|
62
|
+
boxed?: boolean;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* similar to collector, this flag will return metadata about the cell
|
|
66
|
+
*
|
|
67
|
+
* supported in annotations only, not spreadsheet cells (atm)
|
|
68
|
+
*
|
|
69
|
+
* returns cell data type defined in chart (FIXME: move)
|
|
70
|
+
*/
|
|
71
|
+
metadata?: boolean;
|
|
72
|
+
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* merging the old function descriptor and decorated function types, since
|
|
77
|
+
* there's a good deal of overlap and we spend a lot of effort keeping them
|
|
78
|
+
* in sync.
|
|
79
|
+
*
|
|
80
|
+
* this is a wrapper object that contains the function and (mostly optional)
|
|
81
|
+
* metadata.
|
|
82
|
+
*/
|
|
83
|
+
export interface CompositeFunctionDescriptor {
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* description for the function wizard
|
|
87
|
+
*/
|
|
88
|
+
description?: string;
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* list of arguments, for the function wizard and tooltip
|
|
92
|
+
*/
|
|
93
|
+
arguments?: ArgumentDescriptor[];
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* volatile: value changes on every recalc, even if dependencies
|
|
97
|
+
* don't change
|
|
98
|
+
*/
|
|
99
|
+
volatile?: boolean;
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* FIXME: we need to unify type with what's in the cell class
|
|
103
|
+
*/
|
|
104
|
+
render?: RenderFunction; // (options: any) => boolean;
|
|
105
|
+
|
|
106
|
+
click?: ClickFunction; // (options: any) => {value?: any };
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* the actual function. if this is an object member and needs access
|
|
110
|
+
* to the containing instance, make sure to bind it to that instance.
|
|
111
|
+
*/
|
|
112
|
+
fn: (...args: any[]) => UnionValue; // UnionOrArray; // |UnitAddress|UnitRange;
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* for the future. some functions should not be available in
|
|
116
|
+
* spreadsheet cells (charts, basically)
|
|
117
|
+
*/
|
|
118
|
+
visibility?: string;
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* for the future
|
|
122
|
+
*/
|
|
123
|
+
category?: string[];
|
|
124
|
+
|
|
125
|
+
/*
|
|
126
|
+
* if we want to collapse imports (convert functions -> literal calculated
|
|
127
|
+
* values) this flag indicates which functions should be converted. we could
|
|
128
|
+
* theoretically use the category flag but that could be fuzzy, so we will
|
|
129
|
+
* have an explicit flag. applies only to the MC functions atm.
|
|
130
|
+
*/
|
|
131
|
+
extension?: boolean;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* there is some set of functions that need an "_xlfn." prefix on export.
|
|
135
|
+
* I'm not sure why or where the list comes from, but we want to flag
|
|
136
|
+
* those functions so we can export them properly.
|
|
137
|
+
*/
|
|
138
|
+
xlfn?: boolean;
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* support returning references
|
|
142
|
+
*/
|
|
143
|
+
return_type?: ReturnType;
|
|
144
|
+
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface FunctionMap {
|
|
148
|
+
[index: string]: CompositeFunctionDescriptor;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* the stored value also includes a canonical name. this used to be separate
|
|
153
|
+
* from the registered name (because those were functions, and had to adhere
|
|
154
|
+
* to language rules) but now we use arbitrary tokens, so we can consolidate.
|
|
155
|
+
*/
|
|
156
|
+
export interface ExtendedFunctionDescriptor extends CompositeFunctionDescriptor {
|
|
157
|
+
canonical_name: string;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
export interface ExtendedFunctionMap {
|
|
161
|
+
[index: string]: ExtendedFunctionDescriptor;
|
|
162
|
+
}
|