aiden-shared-calculations-unified 1.0.81 → 1.0.82

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.
@@ -0,0 +1,372 @@
1
+ /**
2
+ * @fileoverview Calculation (Pass 1 - Meta) for historical price metrics.
3
+ *
4
+ * This metric answers: "What is the Volatility, Sharpe Ratio, and Max Drawdown
5
+ * for all instruments over 7, 30, 90, and 365-day periods?"
6
+ *
7
+ * It also aggregates these metrics as an average for each sector.
8
+ */
9
+
10
+ const RANGES = [7, 30, 90, 365];
11
+ const TRADING_DAYS_PER_YEAR = 252;
12
+ const MAX_LOOKBACK_DAYS = 5; // For finding a non-holiday/weekend price
13
+
14
+ class CorePriceMetrics {
15
+
16
+ // #region --- Static Metadata & Schema ---
17
+
18
+ /**
19
+ * Statically defines all metadata for the manifest builder.
20
+ */
21
+ static getMetadata() {
22
+ return {
23
+ type: 'meta',
24
+ rootDataDependencies: [], // Relies on price data, not root data
25
+ isHistorical: true, // Needs up to 365d of price history
26
+ userType: 'n/a',
27
+ category: 'core_metrics' // Fits with other price/metric calcs
28
+ };
29
+ }
30
+
31
+ /**
32
+ * This is a Pass 1 calculation and has no dependencies on other calculations.
33
+ */
34
+ static getDependencies() {
35
+ return [];
36
+ }
37
+
38
+ /**
39
+ * Defines the output schema for this calculation.
40
+ */
41
+ static getSchema() {
42
+ // This is the sub-schema for a single instrument's metrics
43
+ const instrumentMetricsSchema = {
44
+ "type": "object",
45
+ "properties": {
46
+ "stdev_7d": { "type": ["number", "null"], "description": "7-day standard deviation of daily returns" },
47
+ "volatility_annualized_7d": { "type": ["number", "null"], "description": "7-day annualized volatility" },
48
+ "sharpe_ratio_7d": { "type": ["number", "null"], "description": "7-day annualized Sharpe ratio (rf=0)" },
49
+ "max_drawdown_7d": { "type": ["number", "null"], "description": "7-day max peak-to-trough drawdown" },
50
+
51
+ "stdev_30d": { "type": ["number", "null"], "description": "30-day standard deviation of daily returns" },
52
+ "volatility_annualized_30d": { "type": ["number", "null"], "description": "30-day annualized volatility" },
53
+ "sharpe_ratio_30d": { "type": ["number", "null"], "description": "30-day annualized Sharpe ratio (rf=0)" },
54
+ "max_drawdown_30d": { "type": ["number", "null"], "description": "30-day max peak-to-trough drawdown" },
55
+
56
+ "stdev_90d": { "type": ["number", "null"], "description": "90-day standard deviation of daily returns" },
57
+ "volatility_annualized_90d": { "type": ["number", "null"], "description": "90-day annualized volatility" },
58
+ "sharpe_ratio_90d": { "type": ["number", "null"], "description": "90-day annualized Sharpe ratio (rf=0)" },
59
+ "max_drawdown_90d": { "type": ["number", "null"], "description": "90-day max peak-to-trough drawdown" },
60
+
61
+ "stdev_365d": { "type": ["number", "null"], "description": "365-day standard deviation of daily returns" },
62
+ "volatility_annualized_365d": { "type": ["number", "null"], "description": "365-day annualized volatility" },
63
+ "sharpe_ratio_365d": { "type": ["number", "null"], "description": "365-day annualized Sharpe ratio (rf=0)" },
64
+ "max_drawdown_365d": { "type": ["number", "null"], "description": "365-day max peak-to-trough drawdown" }
65
+ },
66
+ "additionalProperties": false
67
+ };
68
+
69
+ // This is the sub-schema for a single sector's *averages*
70
+ const sectorMetricsSchema = {
71
+ "type": "object",
72
+ "properties": {
73
+ "average_stdev_7d": { "type": ["number", "null"], "description": "Average 7-day standard deviation for the sector" },
74
+ "average_volatility_annualized_7d": { "type": ["number", "null"], "description": "Average 7-day annualized volatility for the sector" },
75
+ "average_sharpe_ratio_7d": { "type": ["number", "null"], "description": "Average 7-day annualized Sharpe ratio for the sector" },
76
+ "average_max_drawdown_7d": { "type": ["number", "null"], "description": "Average 7-day max drawdown for the sector" },
77
+
78
+ "average_stdev_30d": { "type": ["number", "null"], "description": "Average 30-day standard deviation for the sector" },
79
+ "average_volatility_annualized_30d": { "type": ["number", "null"], "description": "Average 30-day annualized volatility for the sector" },
80
+ "average_sharpe_ratio_30d": { "type": ["number", "null"], "description": "Average 30-day annualized Sharpe ratio for the sector" },
81
+ "average_max_drawdown_30d": { "type": ["number", "null"], "description": "Average 30-day max drawdown for the sector" },
82
+
83
+ "average_stdev_90d": { "type": ["number", "null"], "description": "Average 90-day standard deviation for the sector" },
84
+ "average_volatility_annualized_90d": { "type": ["number", "null"], "description": "Average 90-day annualized volatility for the sector" },
85
+ "average_sharpe_ratio_90d": { "type": ["number", "null"], "description": "Average 90-day annualized Sharpe ratio for the sector" },
86
+ "average_max_drawdown_90d": { "type": ["number", "null"], "description": "Average 90-day max drawdown for the sector" },
87
+
88
+ "average_stdev_365d": { "type": ["number", "null"], "description": "Average 365-day standard deviation for the sector" },
89
+ "average_volatility_annualized_365d": { "type": ["number", "null"], "description": "Average 365-day annualized volatility for the sector" },
90
+ "average_sharpe_ratio_365d": { "type": ["number", "null"], "description": "Average 365-day annualized Sharpe ratio for the sector" },
91
+ "average_max_drawdown_365d": { "type": ["number", "null"], "description": "Average 365-day max drawdown for the sector" }
92
+ },
93
+ "additionalProperties": false
94
+ };
95
+
96
+ // This is the final, top-level schema
97
+ return {
98
+ "type": "object",
99
+ "description": "Calculates risk/return metrics (StdDev, Sharpe, Vol, Drawdown) for instruments and sectors.",
100
+ "properties": {
101
+ "by_instrument": {
102
+ "type": "object",
103
+ "description": "Metrics per instrument, keyed by Ticker.",
104
+ "patternProperties": { "^[A-Z\\.]+$": instrumentMetricsSchema }, // Match tickers like 'NVDA' or 'BRK.B'
105
+ "additionalProperties": instrumentMetricsSchema
106
+ },
107
+ "by_sector": {
108
+ "type": "object",
109
+ "description": "Average metrics per sector, keyed by Sector Name.",
110
+ "patternProperties": { "^[a-zA-Z0-9_ ]+$": sectorMetricsSchema }, // Match sector names
111
+ "additionalProperties": sectorMetricsSchema
112
+ }
113
+ },
114
+ "required": ["by_instrument", "by_sector"]
115
+ };
116
+ }
117
+
118
+ // #endregion --- Static Metadata & Schema ---
119
+
120
+
121
+ // #region --- Main Process ---
122
+
123
+ /**
124
+ * This is a 'meta' calculation. It runs once.
125
+ * @param {string} dateStr - The date string 'YYYY-MM-DD'.
126
+ * @param {object} dependencies - The shared dependencies (e.g., logger, calculationUtils).
127
+ * @param {object} config - The computation system configuration.
128
+ * @returns {Promise<object>} The calculation result.
129
+ */
130
+ async process(dateStr, dependencies, config) {
131
+ const { logger, calculationUtils } = dependencies;
132
+
133
+ const priceMap = await calculationUtils.loadAllPriceData();
134
+ const mappings = await calculationUtils.loadInstrumentMappings();
135
+
136
+ if (!priceMap || !mappings || !mappings.instrumentToTicker || !mappings.instrumentToSector) {
137
+ logger.log('ERROR', '[core-price-metrics] Failed to load priceMap or mappings.');
138
+ return { by_instrument: {}, by_sector: {} };
139
+ }
140
+
141
+ const { instrumentToTicker, instrumentToSector } = mappings;
142
+ const by_instrument = {};
143
+
144
+ // 1. Calculate Per-Instrument Metrics
145
+ for (const instrumentId in priceMap) {
146
+ const ticker = instrumentToTicker[instrumentId];
147
+ if (!ticker) continue;
148
+
149
+ const priceHistoryObj = priceMap[instrumentId];
150
+ const instrumentMetrics = {};
151
+
152
+ // Null-out all metrics by default to ensure consistent schema
153
+ for (const range of RANGES) {
154
+ instrumentMetrics[`stdev_${range}d`] = null;
155
+ instrumentMetrics[`volatility_annualized_${range}d`] = null;
156
+ instrumentMetrics[`sharpe_ratio_${range}d`] = null;
157
+ instrumentMetrics[`max_drawdown_${range}d`] = null;
158
+ }
159
+
160
+ for (const range of RANGES) {
161
+ // Get the price slice for the range (e.g., last 30 days)
162
+ // We need range + 1 prices to calculate `range` number of returns
163
+ const priceArray = this._getHistoricalPriceArray(priceHistoryObj, dateStr, range + 1);
164
+
165
+ if (priceArray.length < 2) {
166
+ continue; // Not enough data for this range
167
+ }
168
+
169
+ // Calculate drawdown on prices
170
+ instrumentMetrics[`max_drawdown_${range}d`] = this._calculateMaxDrawdown(priceArray);
171
+
172
+ // Calculate returns and return-based metrics
173
+ const dailyReturns = this._calculateDailyReturns(priceArray);
174
+ if (dailyReturns.length < 2) {
175
+ continue; // Not enough returns to calculate stddev
176
+ }
177
+
178
+ const meanReturn = this._calculateMean(dailyReturns);
179
+ const stdDev = this._calculateStdDev(dailyReturns, meanReturn);
180
+
181
+ instrumentMetrics[`stdev_${range}d`] = stdDev;
182
+
183
+ if (stdDev > 0) {
184
+ instrumentMetrics[`sharpe_ratio_${range}d`] = (meanReturn / stdDev) * Math.sqrt(TRADING_DAYS_PER_YEAR);
185
+ instrumentMetrics[`volatility_annualized_${range}d`] = stdDev * Math.sqrt(TRADING_DAYS_PER_YEAR);
186
+ } else {
187
+ instrumentMetrics[`sharpe_ratio_${range}d`] = 0;
188
+ instrumentMetrics[`volatility_annualized_${range}d`] = 0;
189
+ }
190
+ }
191
+
192
+ by_instrument[ticker] = instrumentMetrics;
193
+ }
194
+
195
+ // 2. Calculate Sector Aggregates
196
+ const by_sector = this._aggregateMetricsBySector(by_instrument, instrumentToTicker, instrumentToSector);
197
+
198
+ return {
199
+ by_instrument,
200
+ by_sector,
201
+ };
202
+ }
203
+
204
+ // #endregion --- Main Process ---
205
+
206
+
207
+ // #region --- Aggregation Helpers ---
208
+
209
+ _aggregateMetricsBySector(by_instrument, instrumentToTicker, instrumentToSector) {
210
+ const sectorAggregates = {}; // { [sector]: { metrics: { [metricName]: sum }, counts: { [metricName]: count } } }
211
+ const tickerToInstrument = Object.fromEntries(Object.entries(instrumentToTicker).map(([id, ticker]) => [ticker, id]));
212
+
213
+ for (const ticker in by_instrument) {
214
+ const instrumentId = tickerToInstrument[ticker];
215
+ const sector = instrumentToSector[instrumentId] || "Unknown";
216
+ const metrics = by_instrument[ticker];
217
+
218
+ if (!sectorAggregates[sector]) {
219
+ sectorAggregates[sector] = { metrics: {}, counts: {} };
220
+ }
221
+
222
+ for (const metricName in metrics) {
223
+ const value = metrics[metricName];
224
+ // Check for valid, non-null, finite numbers
225
+ if (value !== null && typeof value === 'number' && isFinite(value)) {
226
+ if (!sectorAggregates[sector].metrics[metricName]) {
227
+ sectorAggregates[sector].metrics[metricName] = 0;
228
+ sectorAggregates[sector].counts[metricName] = 0;
229
+ }
230
+ sectorAggregates[sector].metrics[metricName] += value;
231
+ sectorAggregates[sector].counts[metricName]++;
232
+ }
233
+ }
234
+ }
235
+
236
+ // Finalize averages
237
+ const by_sector = {};
238
+ for (const sector in sectorAggregates) {
239
+ by_sector[sector] = {};
240
+ const agg = sectorAggregates[sector];
241
+
242
+ // Get all unique metric names from this sector's aggregation
243
+ const allMetricNames = Object.keys(agg.metrics);
244
+
245
+ for (const metricName of allMetricNames) {
246
+ const count = agg.counts[metricName];
247
+ if (count > 0) {
248
+ by_sector[sector][`average_${metricName}`] = agg.metrics[metricName] / count;
249
+ } else {
250
+ by_sector[sector][`average_${metricName}`] = null; // Ensure null if no valid data
251
+ }
252
+ }
253
+ }
254
+ return by_sector;
255
+ }
256
+
257
+ // #endregion --- Aggregation Helpers ---
258
+
259
+
260
+ // #region --- Math & Price Helpers ---
261
+
262
+ /**
263
+ * Re-implementation of the logic from price_data_provider.js's private helper.
264
+ * Finds the most recent available price on or before a given date.
265
+ */
266
+ _findPriceOnOrBefore(priceHistory, dateStr) {
267
+ if (!priceHistory) return null;
268
+
269
+ let checkDate = new Date(dateStr + 'T00:00:00Z');
270
+
271
+ for (let i = 0; i < MAX_LOOKBACK_DAYS; i++) {
272
+ const checkDateStr = checkDate.toISOString().slice(0, 10);
273
+ const price = priceHistory[checkDateStr];
274
+
275
+ if (price !== undefined && price !== null && price > 0) {
276
+ return price; // Found it
277
+ }
278
+ // If not found, look back one more day
279
+ checkDate.setUTCDate(checkDate.getUTCDate() - 1);
280
+ }
281
+ return null;
282
+ }
283
+
284
+ /**
285
+ * Gets a gap-filled array of prices for a historical range.
286
+ * @param {object} priceHistoryObj - The map of { "YYYY-MM-DD": price }
287
+ * @param {string} endDateStr - The end date of the period (e.g., today).
288
+ * @param {number} numDays - The number of calendar days to fetch prices for.
289
+ * @returns {number[]} A sorted array of prices, oldest to newest.
290
+ */
291
+ _getHistoricalPriceArray(priceHistoryObj, endDateStr, numDays) {
292
+ const prices = [];
293
+ let currentDate = new Date(endDateStr + 'T00:00:00Z');
294
+ let lastPrice = null;
295
+
296
+ for (let i = 0; i < numDays; i++) {
297
+ const targetDateStr = currentDate.toISOString().slice(0, 10);
298
+ let price = this._findPriceOnOrBefore(priceHistoryObj, targetDateStr);
299
+
300
+ // If price is null (e.g., new instrument), try to use the last known price
301
+ if (price === null) {
302
+ price = lastPrice;
303
+ } else {
304
+ lastPrice = price; // Update last known price
305
+ }
306
+
307
+ if (price !== null) {
308
+ prices.push(price);
309
+ }
310
+
311
+ // Go back one calendar day for the next data point
312
+ currentDate.setUTCDate(currentDate.getUTCDate() - 1);
313
+ }
314
+
315
+ // We built the array from newest to oldest, so reverse it.
316
+ // And filter out any initial nulls if lastPrice was null at the start
317
+ return prices.reverse().filter(p => p !== null);
318
+ }
319
+
320
+
321
+ _calculateMean(arr) {
322
+ if (!arr || arr.length === 0) return 0;
323
+ const sum = arr.reduce((acc, val) => acc + val, 0);
324
+ return sum / arr.length;
325
+ }
326
+
327
+ _calculateStdDev(arr, mean) {
328
+ if (!arr || arr.length < 2) return 0;
329
+ const avg = mean === undefined ? this._calculateMean(arr) : mean;
330
+ // Use N-1 for sample standard deviation
331
+ const variance = arr.reduce((acc, val) => acc + (val - avg) ** 2, 0) / (arr.length - 1);
332
+ return Math.sqrt(variance);
333
+ }
334
+
335
+ _calculateDailyReturns(prices) {
336
+ const returns = [];
337
+ for (let i = 1; i < prices.length; i++) {
338
+ const prevPrice = prices[i - 1];
339
+ const currPrice = prices[i];
340
+ if (prevPrice !== 0 && prevPrice !== null && currPrice !== null) {
341
+ returns.push((currPrice - prevPrice) / prevPrice);
342
+ } else {
343
+ returns.push(0);
344
+ }
345
+ }
346
+ return returns;
347
+ }
348
+
349
+ _calculateMaxDrawdown(prices) {
350
+ if (!prices || prices.length < 2) return 0;
351
+ let maxDrawdown = 0;
352
+ let peak = -Infinity;
353
+
354
+ for (const price of prices) {
355
+ if (price > peak) {
356
+ peak = price;
357
+ }
358
+ if (peak > 0) { // Only calculate drawdown if peak is positive
359
+ const drawdown = (price - peak) / peak;
360
+ if (drawdown < maxDrawdown) {
361
+ maxDrawdown = drawdown;
362
+ }
363
+ }
364
+ }
365
+ // Ensure result is a finite number, default to 0
366
+ return isFinite(maxDrawdown) ? maxDrawdown : 0;
367
+ }
368
+
369
+ // #endregion --- Math & Price Helpers ---
370
+ }
371
+
372
+ module.exports = CorePriceMetrics;
@@ -0,0 +1,123 @@
1
+ # node-graphviz
2
+
3
+ A JS + WASM module for compiling graphs written in DOT to images, using GraphViz in Node.js.
4
+
5
+ No annoying native build system or native dependencies that need to be compiled.
6
+
7
+ ## Installation
8
+
9
+ ```
10
+ npm install node-graphviz --save
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ See [The DOT Language](https://graphviz.gitlab.io/_pages/doc/info/lang.html) for more information about DOT, and [GraphViz Pocket Reference](https://graphs.grevian.org/example) for some examples.
16
+
17
+ ```js
18
+ const fs = require('fs');
19
+ const { graphviz } = require('node-graphviz');
20
+
21
+ // Define a graph using DOT notation
22
+ const graph = `
23
+ digraph {
24
+ a -> b;
25
+ b -> c;
26
+ c -> d;
27
+ d -> a;
28
+ }
29
+ `;
30
+
31
+ // Compile the graph to SVG using the `circo` layout algorithm
32
+ graphviz.circo(graph, 'svg').then((svg) => {
33
+ // Write the SVG to file
34
+ fs.writeFileSync('graph.svg', svg);
35
+ });
36
+ ```
37
+
38
+ Running the above produces the following SVG:
39
+
40
+ ![SVG Image showing compiled graph](./tests/output.svg)
41
+
42
+ ## API
43
+
44
+ The module exports the following API:
45
+
46
+ ```ts
47
+ declare type Format = 'svg' | 'dot' | 'json' | 'dot_json' | 'xdot_json';
48
+
49
+ declare type Engine = 'circo' | 'dot' | 'fdp' | 'neato' | 'osage' | 'patchwork' | 'twopi';
50
+
51
+ export declare const graphviz = {
52
+ layout(dotSource: string, outputFormat?: Format, layoutEngine?: Engine): Promise<string>;
53
+ circo(dotSource: string, outputFormat?: Format): Promise<string>;
54
+ dot(dotSource: string, outputFormat?: Format): Promise<string>;
55
+ fdp(dotSource: string, outputFormat?: Format): Promise<string>;
56
+ neato(dotSource: string, outputFormat?: Format): Promise<string>;
57
+ osage(dotSource: string, outputFormat?: Format): Promise<string>;
58
+ patchwork(dotSource: string, outputFormat?: Format): Promise<string>;
59
+ twopi(dotSource: string, outputFormat?: Format): Promise<string>;
60
+ };
61
+ ```
62
+
63
+ ### graphviz.layout(_dotSource_[, _outputFormat_][, _layoutengine_])
64
+
65
+ Performs layout for the supplied `dotSource`.
66
+
67
+ Where:
68
+
69
+ - `outputFormat` is one of the following (see [Output Formats](https://graphviz.gitlab.io/_pages/doc/info/output.html) for details):
70
+ - `dot`
71
+ - `dot_json`
72
+ - `json`
73
+ - `svg` (default)
74
+ - `xdot_json`
75
+ - `layoutEngine` is one of the following (see [Layout documentation](https://www.graphviz.org/documentation/) for details):
76
+ - `circo`
77
+ - `dot` (default)
78
+ - `fdp`
79
+ - `neato`
80
+ - `osage`
81
+ - `patchwork`
82
+ - `twopi`
83
+
84
+ ### graphviz.circo(_dotSource_[, _outputFormat_])
85
+
86
+ Convenience function that performs **circo** layout, is equivalent to `layout(dotSource, outputFormat, 'circo')`.
87
+
88
+ ### graphviz.dot(_dotSource_[, _outputFormat_])
89
+
90
+ Convenience function that performs **dot** layout, is equivalent to `layout(dotSource, outputFormat, 'dot')`.
91
+
92
+ ### graphviz.fdp(_dotSource_[, _outputFormat_])
93
+
94
+ Convenience function that performs **circo** layout, is equivalent to `layout(dotSource, outputFormat, 'fdp')`.
95
+
96
+ ### graphviz.neato(_dotSource_[, _outputFormat_])
97
+
98
+ Convenience function that performs **neato** layout, is equivalent to `layout(dotSource, outputFormat, 'neato')`.
99
+
100
+ ### graphviz.osage(_dotSource_[, _outputFormat_])
101
+
102
+ Convenience function that performs **osage** layout, is equivalent to `layout(dotSource, outputFormat, 'osage')`.
103
+
104
+ ### graphviz.patchwork(_dotSource_[, _outputFormat_])
105
+
106
+ Convenience function that performs **patchwork** layout, is equivalent to `layout(dotSource, outputFormat, 'patchwork')`.
107
+
108
+ ### graphviz.twopi(_dotSource_[, _outputFormat_])
109
+
110
+ Convenience function that performs **twopi** layout, is equivalent to `layout(dotSource, outputFormat, 'twopi')`.
111
+
112
+ ## Credits
113
+
114
+ This module is based on [hpcc-systems/hpcc-js-wasm](https://github.com/hpcc-systems/hpcc-js-wasm), which is designed for use in a browser, not Node.js. The following changes were made to support Node and simplify the module to include only GraphViz:
115
+
116
+ - Rewrote WASM binary location and fetching to read from the filesystem
117
+ - Added the compiled [WASM binary](https://unpkg.com/browse/@hpcc-js/wasm@0.3.14/dist/) to the source
118
+ - Reduced the JS code by half to include only GraphViz, removed Expat and other unrelated code
119
+ - Removed build system and TypeScript, in favor of a single source file (based on the compiled dist file from [hpcc-systems/hpcc-js-wasm](https://github.com/hpcc-systems/hpcc-js-wasm))
120
+
121
+ ## Licence
122
+
123
+ [MIT](LICENSE)
@@ -0,0 +1,33 @@
1
+ declare type Format = "svg" | "dot" | "json" | "dot_json" | "xdot_json";
2
+
3
+ declare type Engine = "circo" | "dot" | "fdp" | "neato" | "osage" | "patchwork" | "twopi";
4
+
5
+ interface Image {
6
+ path: string;
7
+ width: string;
8
+ height: string;
9
+ }
10
+
11
+ interface File {
12
+ path: string;
13
+ data: string;
14
+ }
15
+
16
+ interface Ext {
17
+ images?: Image[];
18
+ files?: File[];
19
+ }
20
+
21
+ export declare const graphviz: {
22
+ layout(dotSource: string, outputFormat?: Format, layoutEngine?: Engine, ext?: Ext | undefined): Promise<string>;
23
+ circo(dotSource: string, outputFormat?: Format, ext?: Ext | undefined): Promise<string>;
24
+ dot(dotSource: string, outputFormat?: Format, ext?: Ext | undefined): Promise<string>;
25
+ fdp(dotSource: string, outputFormat?: Format, ext?: Ext | undefined): Promise<string>;
26
+ neato(dotSource: string, outputFormat?: Format, ext?: Ext | undefined): Promise<string>;
27
+ osage(dotSource: string, outputFormat?: Format, ext?: Ext | undefined): Promise<string>;
28
+ patchwork(dotSource: string, outputFormat?: Format, ext?: Ext | undefined): Promise<string>;
29
+ twopi(dotSource: string, outputFormat?: Format, ext?: Ext | undefined): Promise<string>;
30
+ };
31
+
32
+ export {};
33
+