@aivue/tabular-intelligence 1.5.1 → 2.0.1
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/README.md +445 -18
- package/dist/advanced/automl.d.ts +29 -0
- package/dist/advanced/automl.d.ts.map +1 -0
- package/dist/advanced/explainability.d.ts +31 -0
- package/dist/advanced/explainability.d.ts.map +1 -0
- package/dist/advanced/featureEngineering.d.ts +28 -0
- package/dist/advanced/featureEngineering.d.ts.map +1 -0
- package/dist/advanced/index.d.ts +16 -0
- package/dist/advanced/index.d.ts.map +1 -0
- package/dist/advanced/multitable.d.ts +28 -0
- package/dist/advanced/multitable.d.ts.map +1 -0
- package/dist/advanced/privacy.d.ts +17 -0
- package/dist/advanced/privacy.d.ts.map +1 -0
- package/dist/advanced/reporting.d.ts +21 -0
- package/dist/advanced/reporting.d.ts.map +1 -0
- package/dist/advanced/statistical.d.ts +28 -0
- package/dist/advanced/statistical.d.ts.map +1 -0
- package/dist/advanced/streaming.d.ts +41 -0
- package/dist/advanced/streaming.d.ts.map +1 -0
- package/dist/advanced/timeseries.d.ts +36 -0
- package/dist/advanced/timeseries.d.ts.map +1 -0
- package/dist/advanced/versioning.d.ts +34 -0
- package/dist/advanced/versioning.d.ts.map +1 -0
- package/dist/advanced/visualization.d.ts +23 -0
- package/dist/advanced/visualization.d.ts.map +1 -0
- package/dist/composables/useTabularIntelligence.d.ts +1 -1
- package/dist/composables/useTabularIntelligence.d.ts.map +1 -1
- package/dist/index.d.ts +39 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +75 -47
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2392 -657
- package/dist/index.mjs.map +1 -1
- package/dist/preprocessing/imputation.d.ts +9 -0
- package/dist/preprocessing/imputation.d.ts.map +1 -0
- package/dist/preprocessing/outliers.d.ts +10 -0
- package/dist/preprocessing/outliers.d.ts.map +1 -0
- package/dist/quality/profiling.d.ts +22 -0
- package/dist/quality/profiling.d.ts.map +1 -0
- package/dist/types/index.d.ts +573 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +4 -3
package/dist/index.mjs
CHANGED
|
@@ -1,86 +1,87 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { createCompatComponent as B, createCompatPlugin as se, registerCompatComponent as F } from "@aivue/core";
|
|
2
|
+
import { ref as x, defineComponent as W, createElementBlock as C, openBlock as A, createElementVNode as b, createCommentVNode as T, withDirectives as Se, withKeys as Z, withModifiers as ee, vModelText as Ne, toDisplayString as M, normalizeClass as ke, createTextVNode as Ie, Fragment as j, renderList as Q, computed as $e } from "vue";
|
|
3
|
+
function _(s, e) {
|
|
4
|
+
if (s.length === 0)
|
|
4
5
|
return { columns: [], rowCount: 0, name: e };
|
|
5
|
-
const
|
|
6
|
+
const t = s[0];
|
|
6
7
|
return {
|
|
7
|
-
columns: Object.keys(
|
|
8
|
-
const
|
|
8
|
+
columns: Object.keys(t).map((o) => {
|
|
9
|
+
const a = oe(s, o);
|
|
9
10
|
return {
|
|
10
|
-
name:
|
|
11
|
-
type:
|
|
12
|
-
nullable:
|
|
11
|
+
name: o,
|
|
12
|
+
type: a,
|
|
13
|
+
nullable: s.some((i) => i[o] == null)
|
|
13
14
|
};
|
|
14
15
|
}),
|
|
15
|
-
rowCount:
|
|
16
|
+
rowCount: s.length,
|
|
16
17
|
name: e
|
|
17
18
|
};
|
|
18
19
|
}
|
|
19
|
-
function
|
|
20
|
-
const
|
|
21
|
-
if (
|
|
22
|
-
if (
|
|
20
|
+
function oe(s, e) {
|
|
21
|
+
const t = s.map((o) => o[e]).filter((o) => o != null);
|
|
22
|
+
if (t.length === 0) return "string";
|
|
23
|
+
if (t.every((o) => typeof o == "number" || !isNaN(Number(o))))
|
|
23
24
|
return "number";
|
|
24
|
-
if (
|
|
25
|
+
if (t.every((o) => typeof o == "boolean" || o === "true" || o === "false"))
|
|
25
26
|
return "boolean";
|
|
26
|
-
if (
|
|
27
|
+
if (t.every((o) => !isNaN(Date.parse(o))))
|
|
27
28
|
return "date";
|
|
28
|
-
const
|
|
29
|
-
return
|
|
29
|
+
const n = new Set(t);
|
|
30
|
+
return n.size < t.length * 0.5 && n.size < 20 ? "categorical" : "string";
|
|
30
31
|
}
|
|
31
|
-
function
|
|
32
|
-
const
|
|
32
|
+
function ae(s, e, t) {
|
|
33
|
+
const n = s.map((r) => r[e]).filter((r) => r != null), o = n.length, a = s.length - o, i = {
|
|
33
34
|
column: e,
|
|
34
|
-
count:
|
|
35
|
-
nullCount:
|
|
35
|
+
count: o,
|
|
36
|
+
nullCount: a
|
|
36
37
|
};
|
|
37
|
-
if (
|
|
38
|
-
const
|
|
39
|
-
if (
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
25:
|
|
45
|
-
50:
|
|
46
|
-
75:
|
|
47
|
-
90:
|
|
38
|
+
if (t === "number") {
|
|
39
|
+
const r = n.map(Number).filter((c) => !isNaN(c));
|
|
40
|
+
if (r.length > 0) {
|
|
41
|
+
const c = [...r].sort((m, d) => m - d), l = r.reduce((m, d) => m + d, 0);
|
|
42
|
+
i.mean = l / r.length, i.median = c[Math.floor(c.length / 2)], i.min = c[0], i.max = c[c.length - 1];
|
|
43
|
+
const u = r.reduce((m, d) => m + Math.pow(d - i.mean, 2), 0) / r.length;
|
|
44
|
+
i.std = Math.sqrt(u), i.percentiles = {
|
|
45
|
+
25: c[Math.floor(c.length * 0.25)],
|
|
46
|
+
50: i.median,
|
|
47
|
+
75: c[Math.floor(c.length * 0.75)],
|
|
48
|
+
90: c[Math.floor(c.length * 0.9)]
|
|
48
49
|
};
|
|
49
50
|
}
|
|
50
51
|
} else {
|
|
51
|
-
const
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
const m = String(
|
|
56
|
-
|
|
52
|
+
const r = new Set(n);
|
|
53
|
+
i.uniqueValues = r.size;
|
|
54
|
+
const c = {};
|
|
55
|
+
n.forEach((u) => {
|
|
56
|
+
const m = String(u);
|
|
57
|
+
c[m] = (c[m] || 0) + 1;
|
|
57
58
|
});
|
|
58
|
-
const
|
|
59
|
-
|
|
59
|
+
const l = Math.max(...Object.values(c));
|
|
60
|
+
i.mode = Object.keys(c).find((u) => c[u] === l);
|
|
60
61
|
}
|
|
61
|
-
return
|
|
62
|
+
return i;
|
|
62
63
|
}
|
|
63
|
-
function
|
|
64
|
-
const
|
|
65
|
-
return e.forEach((
|
|
66
|
-
const
|
|
67
|
-
if (
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
if (
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
rowIndex:
|
|
74
|
-
row:
|
|
64
|
+
function Me(s, e, t = 0.5) {
|
|
65
|
+
const n = [], o = 1.5 + (1 - t) * 1.5;
|
|
66
|
+
return e.forEach((a) => {
|
|
67
|
+
const i = s.map((f, h) => ({ value: Number(f[a]), idx: h })).filter((f) => !isNaN(f.value));
|
|
68
|
+
if (i.length === 0) return;
|
|
69
|
+
const r = [...i].sort((f, h) => f.value - h.value), c = r[Math.floor(r.length * 0.25)].value, l = r[Math.floor(r.length * 0.75)].value, u = l - c, m = c - o * u, d = l + o * u;
|
|
70
|
+
i.forEach(({ value: f, idx: h }) => {
|
|
71
|
+
if (f < m || f > d) {
|
|
72
|
+
const p = n.find((g) => g.rowIndex === h), w = f < m ? `${a}: ${f.toFixed(2)} < ${m.toFixed(2)}` : `${a}: ${f.toFixed(2)} > ${d.toFixed(2)}`;
|
|
73
|
+
p ? (p.reasons.push(w), p.affectedColumns.push(a), p.score = Math.min(1, p.score + 0.2)) : n.push({
|
|
74
|
+
rowIndex: h,
|
|
75
|
+
row: s[h],
|
|
75
76
|
score: 0.7,
|
|
76
|
-
reasons: [
|
|
77
|
-
affectedColumns: [
|
|
77
|
+
reasons: [w],
|
|
78
|
+
affectedColumns: [a]
|
|
78
79
|
});
|
|
79
80
|
}
|
|
80
81
|
});
|
|
81
|
-
}),
|
|
82
|
+
}), n.sort((a, i) => i.score - a.score);
|
|
82
83
|
}
|
|
83
|
-
class
|
|
84
|
+
class te {
|
|
84
85
|
constructor(e) {
|
|
85
86
|
this.config = {
|
|
86
87
|
maxTokens: 1e3,
|
|
@@ -92,171 +93,171 @@ class U {
|
|
|
92
93
|
* Answer a question about the table data
|
|
93
94
|
*/
|
|
94
95
|
async answerQuestion(e) {
|
|
95
|
-
const
|
|
96
|
+
const t = Date.now();
|
|
96
97
|
try {
|
|
97
|
-
const { question:
|
|
98
|
-
if (!
|
|
98
|
+
const { question: n, schema: o, data: a, sampleSize: i = 100, includeAggregates: r = !0 } = e;
|
|
99
|
+
if (!a || !Array.isArray(a) || a.length === 0)
|
|
99
100
|
throw new Error("No data available. Please load data first.");
|
|
100
|
-
if (!
|
|
101
|
+
if (!o || !o.columns || !Array.isArray(o.columns))
|
|
101
102
|
throw new Error("Invalid schema. Please ensure data has a valid schema.");
|
|
102
|
-
const
|
|
103
|
+
const c = a.length > i ? this.sampleData(a, i) : a, l = r ? this.calculateAggregates(a, o) : void 0, u = this.buildPrompt(n, o, c, l, a.length), m = await this.callLLM(u);
|
|
103
104
|
return {
|
|
104
|
-
answer: this.parseResponse(m,
|
|
105
|
-
processingTime: Date.now() -
|
|
105
|
+
answer: this.parseResponse(m, n, a.length > i),
|
|
106
|
+
processingTime: Date.now() - t
|
|
106
107
|
};
|
|
107
|
-
} catch (
|
|
108
|
-
return console.error("Q&A error:",
|
|
108
|
+
} catch (n) {
|
|
109
|
+
return console.error("Q&A error:", n), {
|
|
109
110
|
answer: {
|
|
110
111
|
questionId: this.generateId(),
|
|
111
112
|
text: "I encountered an error while processing your question. Please try again.",
|
|
112
113
|
timestamp: /* @__PURE__ */ new Date(),
|
|
113
114
|
confidence: 0,
|
|
114
115
|
cannotAnswer: !0,
|
|
115
|
-
reason:
|
|
116
|
+
reason: n instanceof Error ? n.message : "Unknown error"
|
|
116
117
|
},
|
|
117
|
-
processingTime: Date.now() -
|
|
118
|
+
processingTime: Date.now() - t
|
|
118
119
|
};
|
|
119
120
|
}
|
|
120
121
|
}
|
|
121
122
|
/**
|
|
122
123
|
* Sample data for large datasets
|
|
123
124
|
*/
|
|
124
|
-
sampleData(e,
|
|
125
|
+
sampleData(e, t) {
|
|
125
126
|
if (!e || !Array.isArray(e) || e.length === 0)
|
|
126
127
|
return [];
|
|
127
|
-
if (e.length <=
|
|
128
|
+
if (e.length <= t)
|
|
128
129
|
return e;
|
|
129
|
-
const
|
|
130
|
-
for (let
|
|
131
|
-
|
|
132
|
-
return
|
|
130
|
+
const n = Math.floor(e.length / t), o = [];
|
|
131
|
+
for (let a = 0; a < e.length && o.length < t; a += n)
|
|
132
|
+
o.push(e[a]);
|
|
133
|
+
return o;
|
|
133
134
|
}
|
|
134
135
|
/**
|
|
135
136
|
* Calculate aggregates for numeric columns
|
|
136
137
|
*/
|
|
137
|
-
calculateAggregates(e,
|
|
138
|
-
const
|
|
139
|
-
if (!e || !Array.isArray(e) || e.length === 0 || !
|
|
140
|
-
return
|
|
141
|
-
for (const
|
|
142
|
-
if (
|
|
138
|
+
calculateAggregates(e, t) {
|
|
139
|
+
const n = {};
|
|
140
|
+
if (!e || !Array.isArray(e) || e.length === 0 || !t || !t.columns || !Array.isArray(t.columns))
|
|
141
|
+
return n;
|
|
142
|
+
for (const o of t.columns)
|
|
143
|
+
if (o.type === "number" && e.length > 0)
|
|
143
144
|
try {
|
|
144
|
-
const
|
|
145
|
-
|
|
146
|
-
mean:
|
|
147
|
-
median:
|
|
148
|
-
min:
|
|
149
|
-
max:
|
|
150
|
-
count:
|
|
145
|
+
const a = ae(e, o.name, "number");
|
|
146
|
+
n[o.name] = {
|
|
147
|
+
mean: a.mean,
|
|
148
|
+
median: a.median,
|
|
149
|
+
min: a.min,
|
|
150
|
+
max: a.max,
|
|
151
|
+
count: a.count
|
|
151
152
|
};
|
|
152
153
|
} catch {
|
|
153
154
|
}
|
|
154
|
-
else if (
|
|
155
|
-
const
|
|
156
|
-
|
|
157
|
-
uniqueCount:
|
|
158
|
-
totalCount:
|
|
159
|
-
topValues: this.getTopValues(
|
|
155
|
+
else if (o.type === "categorical" || o.type === "string") {
|
|
156
|
+
const a = e.map((r) => r[o.name]).filter((r) => r != null), i = new Set(a);
|
|
157
|
+
n[o.name] = {
|
|
158
|
+
uniqueCount: i.size,
|
|
159
|
+
totalCount: a.length,
|
|
160
|
+
topValues: this.getTopValues(a, 5)
|
|
160
161
|
};
|
|
161
162
|
}
|
|
162
|
-
return
|
|
163
|
+
return n;
|
|
163
164
|
}
|
|
164
165
|
/**
|
|
165
166
|
* Get top N most frequent values
|
|
166
167
|
*/
|
|
167
|
-
getTopValues(e,
|
|
168
|
-
const
|
|
169
|
-
for (const
|
|
170
|
-
|
|
171
|
-
return Array.from(
|
|
168
|
+
getTopValues(e, t) {
|
|
169
|
+
const n = /* @__PURE__ */ new Map();
|
|
170
|
+
for (const o of e)
|
|
171
|
+
n.set(o, (n.get(o) || 0) + 1);
|
|
172
|
+
return Array.from(n.entries()).map(([o, a]) => ({ value: o, count: a })).sort((o, a) => a.count - o.count).slice(0, t);
|
|
172
173
|
}
|
|
173
174
|
/**
|
|
174
175
|
* Build prompt for LLM
|
|
175
176
|
*/
|
|
176
|
-
buildPrompt(e,
|
|
177
|
-
const
|
|
178
|
-
let
|
|
177
|
+
buildPrompt(e, t, n, o, a) {
|
|
178
|
+
const i = a && a > n.length;
|
|
179
|
+
let r = `You are a data analyst assistant. Answer the following question about a table dataset.
|
|
179
180
|
|
|
180
181
|
`;
|
|
181
|
-
|
|
182
|
-
`,
|
|
183
|
-
`,
|
|
182
|
+
r += `**Table Schema:**
|
|
183
|
+
`, r += `Table: ${t.name}
|
|
184
|
+
`, r += `Columns:
|
|
184
185
|
`;
|
|
185
|
-
for (const
|
|
186
|
-
|
|
186
|
+
for (const c of t.columns)
|
|
187
|
+
r += `- ${c.name} (${c.type})
|
|
187
188
|
`;
|
|
188
|
-
return
|
|
189
|
-
`,
|
|
190
|
-
`,
|
|
189
|
+
return r += `
|
|
190
|
+
`, o && Object.keys(o).length > 0 && (r += `**Summary Statistics:**
|
|
191
|
+
`, r += JSON.stringify(o, null, 2), r += `
|
|
191
192
|
|
|
192
|
-
`),
|
|
193
|
-
`,
|
|
193
|
+
`), r += `**Sample Data** (${n.length} rows${i ? ` out of ${a} total` : ""}):
|
|
194
|
+
`, r += JSON.stringify(n.slice(0, 10), null, 2), r += `
|
|
194
195
|
|
|
195
|
-
`,
|
|
196
|
+
`, r += `**Question:** ${e}
|
|
196
197
|
|
|
197
|
-
`,
|
|
198
|
-
`,
|
|
199
|
-
`,
|
|
200
|
-
`,
|
|
201
|
-
`,
|
|
202
|
-
`,
|
|
203
|
-
`,
|
|
204
|
-
`,
|
|
205
|
-
`,
|
|
206
|
-
`,
|
|
207
|
-
`,
|
|
208
|
-
`,
|
|
209
|
-
`,
|
|
210
|
-
`,
|
|
211
|
-
`,
|
|
212
|
-
`,
|
|
213
|
-
`,
|
|
214
|
-
`,
|
|
215
|
-
`,
|
|
216
|
-
`,
|
|
217
|
-
`,
|
|
218
|
-
`,
|
|
198
|
+
`, r += `**Instructions:**
|
|
199
|
+
`, r += `1. You are a helpful AI data analyst that can answer questions about the table data, perform statistical analysis, make predictions, identify trends, AND engage in normal conversation.
|
|
200
|
+
`, r += `2. For data questions (e.g., "how many rows?", "what's the average?"), answer based on the data provided above.
|
|
201
|
+
`, r += `3. For statistical analysis requests (e.g., "calculate descriptive statistics", "show me mean/median/std dev"), compute and present the statistics clearly.
|
|
202
|
+
`, r += `4. For anomaly detection requests (e.g., "detect anomalies", "find outliers"), identify unusual data points and explain why they're anomalous.
|
|
203
|
+
`, r += `5. For clustering requests (e.g., "perform clustering", "group similar data"), identify natural groupings in the data and describe their characteristics.
|
|
204
|
+
`, r += `6. For correlation analysis requests (e.g., "show correlations", "what variables are related"), analyze relationships between variables and explain the strength and direction of correlations.
|
|
205
|
+
`, r += `7. For predictive questions (e.g., "predict future trends", "what will happen next?", "forecast X"), analyze patterns in the data and make reasonable predictions based on trends, correlations, and statistical patterns you observe.
|
|
206
|
+
`, r += `8. For analytical questions (e.g., "what insights?", "any patterns?", "recommendations?"), provide insights, trends, correlations, and actionable recommendations based on the data.
|
|
207
|
+
`, r += `9. For conversational questions (e.g., "hi", "hello", "what can you do?"), respond naturally and mention your capabilities.
|
|
208
|
+
`, r += `10. If a question is completely unrelated to data analysis (e.g., "what's the weather?"), politely explain you can only help with data analysis.
|
|
209
|
+
`, r += `11. Provide clear, concise answers with specific numbers and examples.
|
|
210
|
+
`, r += `12. When making predictions or identifying trends, explain your reasoning and mention the confidence level.
|
|
211
|
+
`, r += `13. If the answer is based on sampled data, mention that it's an approximation.
|
|
212
|
+
`, r += `14. Format your response as JSON with the following structure:
|
|
213
|
+
`, r += `{
|
|
214
|
+
`, r += ` "answer": "Your answer text here",
|
|
215
|
+
`, r += ` "confidence": 0.0-1.0,
|
|
216
|
+
`, r += ` "cannotAnswer": false,
|
|
217
|
+
`, r += ` "isApproximate": ${i},
|
|
218
|
+
`, r += ` "supportingData": { "key": "value" } // optional
|
|
219
|
+
`, r += `}
|
|
219
220
|
|
|
220
|
-
`,
|
|
221
|
-
`,
|
|
222
|
-
`,
|
|
223
|
-
`,
|
|
224
|
-
`,
|
|
225
|
-
`,
|
|
226
|
-
`,
|
|
227
|
-
`,
|
|
228
|
-
`,
|
|
229
|
-
`,
|
|
230
|
-
`,
|
|
221
|
+
`, r += `Examples:
|
|
222
|
+
`, r += `- Question: "hi" → Answer: "Hello! I'm your AI data analyst. I can perform statistical analysis, detect anomalies, cluster data, analyze correlations, make predictions, and answer questions about this dataset."
|
|
223
|
+
`, r += `- Question: "how many rows?" → Answer: "There are ${a || n.length} rows in the dataset."
|
|
224
|
+
`, r += `- Question: "calculate descriptive statistics" → Answer: "Descriptive Statistics:\\n- Mean: 45.2\\n- Median: 42.0\\n- Std Dev: 12.5\\n- Min: 10\\n- Max: 95\\n- 25th Percentile: 35\\n- 75th Percentile: 58" (with confidence: 0.95)
|
|
225
|
+
`, r += `- Question: "detect anomalies" → Answer: "I found 3 anomalies in the dataset:\\n1. Row 15: Value 250 is 3.5 standard deviations above the mean\\n2. Row 42: Value -10 is unusually low\\n3. Row 88: Value 300 is an extreme outlier" (with confidence: 0.85)
|
|
226
|
+
`, r += `- Question: "perform clustering" → Answer: "I identified 3 natural clusters in the data:\\n- Cluster 1 (40%): Low values, avg 25\\n- Cluster 2 (35%): Medium values, avg 50\\n- Cluster 3 (25%): High values, avg 85" (with confidence: 0.8)
|
|
227
|
+
`, r += `- Question: "show correlation analysis" → Answer: "Correlation Analysis:\\n- Price & Quantity: -0.65 (strong negative)\\n- Revenue & Price: 0.82 (strong positive)\\n- Quantity & Revenue: 0.45 (moderate positive)" (with confidence: 0.9)
|
|
228
|
+
`, r += `- Question: "predict future sales" → Answer: "Based on the trend in the data, sales are increasing by 15% monthly. If this continues, next month's sales could reach approximately $50,000." (with confidence: 0.7)
|
|
229
|
+
`, r += `- Question: "what insights can you give?" → Answer: "Key insights: 1) Sales peak on weekends, 2) Product A is the top seller, 3) Customer retention is 85%..."
|
|
230
|
+
`, r += `- Question: "what's the weather?" → Answer: "I cannot answer this question as it's not related to the dataset. I can only help with questions about this data."
|
|
231
|
+
`, r;
|
|
231
232
|
}
|
|
232
233
|
/**
|
|
233
234
|
* Call LLM API
|
|
234
235
|
*/
|
|
235
236
|
async callLLM(e) {
|
|
236
|
-
const { provider:
|
|
237
|
-
if (!
|
|
237
|
+
const { provider: t, apiKey: n, baseUrl: o, model: a, maxTokens: i, temperature: r } = this.config;
|
|
238
|
+
if (!n && t !== "custom")
|
|
238
239
|
return this.fallbackResponse(e);
|
|
239
|
-
if (
|
|
240
|
-
return this.callOpenAI(e,
|
|
241
|
-
if (
|
|
242
|
-
return this.callAnthropic(e,
|
|
243
|
-
if (
|
|
244
|
-
return this.callCustomAPI(e,
|
|
245
|
-
throw new Error(`Unsupported provider: ${
|
|
240
|
+
if (t === "openai")
|
|
241
|
+
return this.callOpenAI(e, n, a || "gpt-4-turbo-preview", i, r);
|
|
242
|
+
if (t === "anthropic")
|
|
243
|
+
return this.callAnthropic(e, n, a || "claude-3-5-sonnet-20241022", i, r);
|
|
244
|
+
if (t === "custom" && o)
|
|
245
|
+
return this.callCustomAPI(e, o, n);
|
|
246
|
+
throw new Error(`Unsupported provider: ${t}`);
|
|
246
247
|
}
|
|
247
248
|
/**
|
|
248
249
|
* Fallback response when no API key is available
|
|
249
250
|
*/
|
|
250
251
|
fallbackResponse(e) {
|
|
251
|
-
const
|
|
252
|
-
if (/^(hi|hello|hey|greetings|good morning|good afternoon|good evening)/.test(
|
|
252
|
+
const t = e.match(/\*\*Question:\*\* (.+)/), o = (t ? t[1].trim() : "").toLowerCase();
|
|
253
|
+
if (/^(hi|hello|hey|greetings|good morning|good afternoon|good evening)/.test(o))
|
|
253
254
|
return JSON.stringify({
|
|
254
255
|
answer: "Hello! 👋 I'm your data analysis assistant. I can help you explore and understand this dataset. Try asking questions like 'How many rows are there?', 'What columns do we have?', or 'Show me a summary of the data'. For more advanced analysis, please configure an OpenAI or Anthropic API key in the settings.",
|
|
255
256
|
confidence: 1,
|
|
256
257
|
cannotAnswer: !1,
|
|
257
258
|
isApproximate: !1
|
|
258
259
|
});
|
|
259
|
-
if (/what (can|do) you|help|capabilities|features/.test(
|
|
260
|
+
if (/what (can|do) you|help|capabilities|features/.test(o))
|
|
260
261
|
return JSON.stringify({
|
|
261
262
|
answer: `I can help you analyze tabular data! You can ask me questions like:
|
|
262
263
|
• 'How many rows/columns are there?'
|
|
@@ -279,60 +280,60 @@ Please add your API key in the AI Chatbot Configuration section for advanced fea
|
|
|
279
280
|
cannotAnswer: !1,
|
|
280
281
|
isApproximate: !1
|
|
281
282
|
});
|
|
282
|
-
const
|
|
283
|
-
if (/how many (rows|records|entries|items)/.test(
|
|
283
|
+
const a = e.match(/\*\*Sample Data\*\* \((\d+) rows/), i = e.match(/out of (\d+) total/), r = e.match(/Columns:\n((?:- .+\n)+)/), c = a ? parseInt(a[1]) : 0, l = i ? parseInt(i[1]) : c;
|
|
284
|
+
if (/how many (rows|records|entries|items)/.test(o))
|
|
284
285
|
return JSON.stringify({
|
|
285
|
-
answer: `There are ${
|
|
286
|
+
answer: `There are ${l} rows in the dataset.`,
|
|
286
287
|
confidence: 1,
|
|
287
288
|
cannotAnswer: !1,
|
|
288
289
|
isApproximate: !1
|
|
289
290
|
});
|
|
290
|
-
if (/how many columns|what columns|column names|list columns/.test(
|
|
291
|
-
const
|
|
291
|
+
if (/how many columns|what columns|column names|list columns/.test(o) && r) {
|
|
292
|
+
const u = r[1].trim().split(`
|
|
292
293
|
`).map((m) => m.replace(/^- /, "").split(" (")[0]);
|
|
293
294
|
return JSON.stringify({
|
|
294
|
-
answer: `The dataset has ${
|
|
295
|
+
answer: `The dataset has ${u.length} columns: ${u.join(", ")}.`,
|
|
295
296
|
confidence: 1,
|
|
296
297
|
cannotAnswer: !1,
|
|
297
298
|
isApproximate: !1
|
|
298
299
|
});
|
|
299
300
|
}
|
|
300
|
-
if (/summary|overview|describe|what.*data|tell me about/.test(
|
|
301
|
-
const
|
|
301
|
+
if (/summary|overview|describe|what.*data|tell me about/.test(o) && r) {
|
|
302
|
+
const u = r[1].trim().split(`
|
|
302
303
|
`).map((m) => m.replace(/^- /, "").split(" (")[0]);
|
|
303
304
|
return JSON.stringify({
|
|
304
|
-
answer: `This dataset contains ${
|
|
305
|
+
answer: `This dataset contains ${l} rows and ${u.length} columns. The columns are: ${u.join(", ")}. For detailed analysis and insights, please configure an OpenAI or Anthropic API key.`,
|
|
305
306
|
confidence: 0.8,
|
|
306
307
|
cannotAnswer: !1,
|
|
307
308
|
isApproximate: !1
|
|
308
309
|
});
|
|
309
310
|
}
|
|
310
|
-
return /descriptive statistics|calculate statistics|mean|median|std dev|standard deviation|percentile/.test(
|
|
311
|
+
return /descriptive statistics|calculate statistics|mean|median|std dev|standard deviation|percentile/.test(o) ? JSON.stringify({
|
|
311
312
|
answer: "I can calculate descriptive statistics with an OpenAI or Anthropic API key! I'll provide mean, median, standard deviation, min, max, and percentiles for all numeric columns. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
312
313
|
confidence: 0.3,
|
|
313
314
|
cannotAnswer: !0,
|
|
314
315
|
reason: "Statistical analysis requires AI. Please configure an API key."
|
|
315
|
-
}) : /anomaly|anomalies|outlier|outliers|detect anomal|find outlier/.test(
|
|
316
|
+
}) : /anomaly|anomalies|outlier|outliers|detect anomal|find outlier/.test(o) ? JSON.stringify({
|
|
316
317
|
answer: "I can detect anomalies and outliers with an OpenAI or Anthropic API key! I'll identify unusual data points and explain why they're anomalous. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
317
318
|
confidence: 0.3,
|
|
318
319
|
cannotAnswer: !0,
|
|
319
320
|
reason: "Anomaly detection requires AI. Please configure an API key."
|
|
320
|
-
}) : /cluster|clustering|group|grouping|segment|segmentation/.test(
|
|
321
|
+
}) : /cluster|clustering|group|grouping|segment|segmentation/.test(o) ? JSON.stringify({
|
|
321
322
|
answer: "I can perform clustering analysis with an OpenAI or Anthropic API key! I'll identify natural groupings in your data and describe their characteristics. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
322
323
|
confidence: 0.3,
|
|
323
324
|
cannotAnswer: !0,
|
|
324
325
|
reason: "Clustering analysis requires AI. Please configure an API key."
|
|
325
|
-
}) : /correlation|correlate|relationship|relate|association/.test(
|
|
326
|
+
}) : /correlation|correlate|relationship|relate|association/.test(o) ? JSON.stringify({
|
|
326
327
|
answer: "I can analyze correlations between variables with an OpenAI or Anthropic API key! I'll show you the strength and direction of relationships between different columns. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
327
328
|
confidence: 0.3,
|
|
328
329
|
cannotAnswer: !0,
|
|
329
330
|
reason: "Correlation analysis requires AI. Please configure an API key."
|
|
330
|
-
}) : /predict|forecast|future|trend|next|will be|gonna be|going to be/.test(
|
|
331
|
+
}) : /predict|forecast|future|trend|next|will be|gonna be|going to be/.test(o) ? JSON.stringify({
|
|
331
332
|
answer: "I'd love to help you make predictions based on this data! However, I need an OpenAI or Anthropic API key to analyze patterns, identify trends, and make accurate forecasts. Please add your API key in the 'AI Chatbot Configuration' section above, and I'll be able to provide detailed predictions with confidence scores.",
|
|
332
333
|
confidence: 0.3,
|
|
333
334
|
cannotAnswer: !0,
|
|
334
335
|
reason: "Predictions require AI analysis. Please configure an API key for advanced features."
|
|
335
|
-
}) : /insight|pattern|analysis|analyze|recommendation/.test(
|
|
336
|
+
}) : /insight|pattern|analysis|analyze|recommendation/.test(o) ? JSON.stringify({
|
|
336
337
|
answer: "I can provide deep insights and analysis with an OpenAI or Anthropic API key! I'll be able to identify patterns, trends, and give you actionable recommendations. Please add your API key in the 'AI Chatbot Configuration' section above.",
|
|
337
338
|
confidence: 0.3,
|
|
338
339
|
cannotAnswer: !0,
|
|
@@ -347,82 +348,82 @@ Please add your API key in the AI Chatbot Configuration section for advanced fea
|
|
|
347
348
|
/**
|
|
348
349
|
* Call OpenAI API
|
|
349
350
|
*/
|
|
350
|
-
async callOpenAI(e,
|
|
351
|
-
var
|
|
352
|
-
const
|
|
351
|
+
async callOpenAI(e, t, n, o, a) {
|
|
352
|
+
var c, l;
|
|
353
|
+
const i = await fetch("https://api.openai.com/v1/chat/completions", {
|
|
353
354
|
method: "POST",
|
|
354
355
|
headers: {
|
|
355
356
|
"Content-Type": "application/json",
|
|
356
|
-
Authorization: `Bearer ${
|
|
357
|
+
Authorization: `Bearer ${t}`
|
|
357
358
|
},
|
|
358
359
|
body: JSON.stringify({
|
|
359
|
-
model:
|
|
360
|
+
model: n,
|
|
360
361
|
messages: [{ role: "user", content: e }],
|
|
361
|
-
max_tokens:
|
|
362
|
-
temperature:
|
|
362
|
+
max_tokens: o,
|
|
363
|
+
temperature: a,
|
|
363
364
|
response_format: { type: "json_object" }
|
|
364
365
|
})
|
|
365
366
|
});
|
|
366
|
-
if (!
|
|
367
|
-
throw new Error(`OpenAI API error: ${
|
|
368
|
-
return ((
|
|
367
|
+
if (!i.ok)
|
|
368
|
+
throw new Error(`OpenAI API error: ${i.statusText}`);
|
|
369
|
+
return ((l = (c = (await i.json()).choices[0]) == null ? void 0 : c.message) == null ? void 0 : l.content) || "";
|
|
369
370
|
}
|
|
370
371
|
/**
|
|
371
372
|
* Call Anthropic API
|
|
372
373
|
*/
|
|
373
|
-
async callAnthropic(e,
|
|
374
|
-
var
|
|
375
|
-
const
|
|
374
|
+
async callAnthropic(e, t, n, o, a) {
|
|
375
|
+
var c;
|
|
376
|
+
const i = await fetch("https://api.anthropic.com/v1/messages", {
|
|
376
377
|
method: "POST",
|
|
377
378
|
headers: {
|
|
378
379
|
"Content-Type": "application/json",
|
|
379
|
-
"x-api-key":
|
|
380
|
+
"x-api-key": t,
|
|
380
381
|
"anthropic-version": "2023-06-01"
|
|
381
382
|
},
|
|
382
383
|
body: JSON.stringify({
|
|
383
|
-
model:
|
|
384
|
-
max_tokens:
|
|
385
|
-
temperature:
|
|
384
|
+
model: n,
|
|
385
|
+
max_tokens: o,
|
|
386
|
+
temperature: a,
|
|
386
387
|
messages: [{ role: "user", content: e }]
|
|
387
388
|
})
|
|
388
389
|
});
|
|
389
|
-
if (!
|
|
390
|
-
throw new Error(`Anthropic API error: ${
|
|
391
|
-
return ((
|
|
390
|
+
if (!i.ok)
|
|
391
|
+
throw new Error(`Anthropic API error: ${i.statusText}`);
|
|
392
|
+
return ((c = (await i.json()).content[0]) == null ? void 0 : c.text) || "";
|
|
392
393
|
}
|
|
393
394
|
/**
|
|
394
395
|
* Call custom API
|
|
395
396
|
*/
|
|
396
|
-
async callCustomAPI(e,
|
|
397
|
-
const
|
|
397
|
+
async callCustomAPI(e, t, n) {
|
|
398
|
+
const o = {
|
|
398
399
|
"Content-Type": "application/json"
|
|
399
400
|
};
|
|
400
|
-
|
|
401
|
-
const
|
|
401
|
+
n && (o.Authorization = `Bearer ${n}`);
|
|
402
|
+
const a = await fetch(t, {
|
|
402
403
|
method: "POST",
|
|
403
|
-
headers:
|
|
404
|
+
headers: o,
|
|
404
405
|
body: JSON.stringify({ prompt: e })
|
|
405
406
|
});
|
|
406
|
-
if (!
|
|
407
|
-
throw new Error(`Custom API error: ${
|
|
408
|
-
const
|
|
409
|
-
return
|
|
407
|
+
if (!a.ok)
|
|
408
|
+
throw new Error(`Custom API error: ${a.statusText}`);
|
|
409
|
+
const i = await a.json();
|
|
410
|
+
return i.response || i.answer || JSON.stringify(i);
|
|
410
411
|
}
|
|
411
412
|
/**
|
|
412
413
|
* Parse LLM response
|
|
413
414
|
*/
|
|
414
|
-
parseResponse(e,
|
|
415
|
+
parseResponse(e, t, n) {
|
|
415
416
|
try {
|
|
416
|
-
const
|
|
417
|
+
const o = JSON.parse(e);
|
|
417
418
|
return {
|
|
418
419
|
questionId: this.generateId(),
|
|
419
|
-
text:
|
|
420
|
+
text: o.answer || o.text || e,
|
|
420
421
|
timestamp: /* @__PURE__ */ new Date(),
|
|
421
|
-
confidence:
|
|
422
|
-
cannotAnswer:
|
|
423
|
-
isApproximate:
|
|
424
|
-
supportingData:
|
|
425
|
-
reason:
|
|
422
|
+
confidence: o.confidence || 0.8,
|
|
423
|
+
cannotAnswer: o.cannotAnswer || !1,
|
|
424
|
+
isApproximate: o.isApproximate !== void 0 ? o.isApproximate : n,
|
|
425
|
+
supportingData: o.supportingData,
|
|
426
|
+
reason: o.reason
|
|
426
427
|
};
|
|
427
428
|
} catch {
|
|
428
429
|
return {
|
|
@@ -430,7 +431,7 @@ Please add your API key in the AI Chatbot Configuration section for advanced fea
|
|
|
430
431
|
text: e,
|
|
431
432
|
timestamp: /* @__PURE__ */ new Date(),
|
|
432
433
|
confidence: 0.7,
|
|
433
|
-
isApproximate:
|
|
434
|
+
isApproximate: n
|
|
434
435
|
};
|
|
435
436
|
}
|
|
436
437
|
}
|
|
@@ -441,239 +442,239 @@ Please add your API key in the AI Chatbot Configuration section for advanced fea
|
|
|
441
442
|
return `qa_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
442
443
|
}
|
|
443
444
|
}
|
|
444
|
-
function
|
|
445
|
+
function xe(s = {}) {
|
|
445
446
|
const {
|
|
446
447
|
selector: e = "table",
|
|
447
|
-
includeHeaders:
|
|
448
|
-
maxRows:
|
|
449
|
-
inferTypes:
|
|
450
|
-
skipEmptyRows:
|
|
451
|
-
} =
|
|
452
|
-
if (!
|
|
448
|
+
includeHeaders: t = !0,
|
|
449
|
+
maxRows: n,
|
|
450
|
+
inferTypes: o = !0,
|
|
451
|
+
skipEmptyRows: a = !0
|
|
452
|
+
} = s, i = document.querySelector(e);
|
|
453
|
+
if (!i || i.tagName !== "TABLE")
|
|
453
454
|
return console.warn(`No table found with selector: ${e}`), null;
|
|
454
|
-
const
|
|
455
|
-
if (
|
|
455
|
+
const c = Array.from(i.rows);
|
|
456
|
+
if (c.length === 0)
|
|
456
457
|
return null;
|
|
457
|
-
let
|
|
458
|
-
if (
|
|
459
|
-
const
|
|
460
|
-
|
|
461
|
-
var
|
|
462
|
-
return ((
|
|
463
|
-
}),
|
|
458
|
+
let l = [], u = 0;
|
|
459
|
+
if (t && c[0]) {
|
|
460
|
+
const h = c[0];
|
|
461
|
+
l = Array.from(h.cells).map((p, w) => {
|
|
462
|
+
var S;
|
|
463
|
+
return ((S = p.textContent) == null ? void 0 : S.trim()) || "" || `Column${w + 1}`;
|
|
464
|
+
}), u = 1;
|
|
464
465
|
} else {
|
|
465
|
-
const
|
|
466
|
-
|
|
467
|
-
}
|
|
468
|
-
const m = [], d =
|
|
469
|
-
for (const
|
|
470
|
-
const
|
|
471
|
-
if (
|
|
472
|
-
var
|
|
473
|
-
return !((
|
|
466
|
+
const h = c[0];
|
|
467
|
+
l = Array.from(h.cells).map((p, w) => `Column${w + 1}`);
|
|
468
|
+
}
|
|
469
|
+
const m = [], d = n ? c.slice(u, u + n) : c.slice(u);
|
|
470
|
+
for (const h of d) {
|
|
471
|
+
const p = Array.from(h.cells);
|
|
472
|
+
if (a && p.every((g) => {
|
|
473
|
+
var S;
|
|
474
|
+
return !((S = g.textContent) != null && S.trim());
|
|
474
475
|
}))
|
|
475
476
|
continue;
|
|
476
|
-
const
|
|
477
|
-
|
|
478
|
-
var
|
|
479
|
-
const
|
|
480
|
-
let
|
|
481
|
-
if (
|
|
482
|
-
const
|
|
483
|
-
!isNaN(
|
|
477
|
+
const w = {};
|
|
478
|
+
p.forEach((g, S) => {
|
|
479
|
+
var E;
|
|
480
|
+
const O = l[S] || `Column${S + 1}`;
|
|
481
|
+
let q = ((E = g.textContent) == null ? void 0 : E.trim()) || "";
|
|
482
|
+
if (o && q) {
|
|
483
|
+
const z = parseFloat(q);
|
|
484
|
+
!isNaN(z) && q === z.toString() && (q = z);
|
|
484
485
|
}
|
|
485
|
-
|
|
486
|
-
}), m.push(
|
|
486
|
+
w[O] = q;
|
|
487
|
+
}), m.push(w);
|
|
487
488
|
}
|
|
488
489
|
return {
|
|
489
|
-
schema:
|
|
490
|
+
schema: o && m.length > 0 ? _(m, "Extracted Table") : Pe(l, m.length),
|
|
490
491
|
data: m,
|
|
491
492
|
source: "dom",
|
|
492
493
|
metadata: {
|
|
493
494
|
selector: e,
|
|
494
495
|
rowCount: m.length,
|
|
495
|
-
columnCount:
|
|
496
|
+
columnCount: l.length,
|
|
496
497
|
extractedAt: /* @__PURE__ */ new Date()
|
|
497
498
|
}
|
|
498
499
|
};
|
|
499
500
|
}
|
|
500
|
-
function
|
|
501
|
-
const { maxRows:
|
|
502
|
-
let
|
|
503
|
-
return e && e.length > 0 ?
|
|
501
|
+
function qe(s, e, t = {}) {
|
|
502
|
+
const { maxRows: n, inferTypes: o = !0 } = t, a = n ? s.slice(0, n) : s;
|
|
503
|
+
let i;
|
|
504
|
+
return e && e.length > 0 ? i = {
|
|
504
505
|
name: "Vue Data Grid",
|
|
505
|
-
columns: e.map((
|
|
506
|
-
name:
|
|
507
|
-
type:
|
|
506
|
+
columns: e.map((r) => ({
|
|
507
|
+
name: r.field,
|
|
508
|
+
type: o && a.length > 0 ? oe(a, r.field) : "string",
|
|
508
509
|
nullable: !0
|
|
509
510
|
})),
|
|
510
|
-
rowCount:
|
|
511
|
-
} :
|
|
512
|
-
schema:
|
|
513
|
-
data:
|
|
511
|
+
rowCount: a.length
|
|
512
|
+
} : a.length > 0 ? i = _(a, "Vue Data Grid") : i = { name: "Vue Data Grid", columns: [], rowCount: 0 }, {
|
|
513
|
+
schema: i,
|
|
514
|
+
data: a,
|
|
514
515
|
source: "vue",
|
|
515
516
|
metadata: {
|
|
516
|
-
rowCount:
|
|
517
|
-
columnCount:
|
|
517
|
+
rowCount: a.length,
|
|
518
|
+
columnCount: i.columns.length,
|
|
518
519
|
extractedAt: /* @__PURE__ */ new Date()
|
|
519
520
|
}
|
|
520
521
|
};
|
|
521
522
|
}
|
|
522
|
-
function
|
|
523
|
+
function Pe(s, e = 0) {
|
|
523
524
|
return {
|
|
524
525
|
name: "Extracted Table",
|
|
525
|
-
columns:
|
|
526
|
-
name:
|
|
526
|
+
columns: s.map((t) => ({
|
|
527
|
+
name: t,
|
|
527
528
|
type: "string",
|
|
528
529
|
nullable: !0
|
|
529
530
|
})),
|
|
530
531
|
rowCount: e
|
|
531
532
|
};
|
|
532
533
|
}
|
|
533
|
-
function
|
|
534
|
+
function Te(s) {
|
|
534
535
|
const e = {};
|
|
535
|
-
|
|
536
|
-
e[
|
|
536
|
+
s.variable && s.variable.forEach((a) => {
|
|
537
|
+
e[a.key] = a.value;
|
|
537
538
|
});
|
|
538
|
-
const
|
|
539
|
-
function
|
|
540
|
-
|
|
541
|
-
|
|
539
|
+
const t = s.auth ? re(s.auth) : void 0, n = [];
|
|
540
|
+
function o(a, i = "") {
|
|
541
|
+
a.forEach((r) => {
|
|
542
|
+
r.item ? o(r.item, i ? `${i}/${r.name}` : r.name) : r.request && n.push(De(r, t));
|
|
542
543
|
});
|
|
543
544
|
}
|
|
544
|
-
return
|
|
545
|
-
name:
|
|
546
|
-
description:
|
|
547
|
-
endpoints:
|
|
545
|
+
return o(s.item), {
|
|
546
|
+
name: s.info.name,
|
|
547
|
+
description: s.info.description,
|
|
548
|
+
endpoints: n,
|
|
548
549
|
variables: e,
|
|
549
|
-
auth:
|
|
550
|
+
auth: t
|
|
550
551
|
};
|
|
551
552
|
}
|
|
552
|
-
function
|
|
553
|
-
const
|
|
554
|
-
|
|
555
|
-
|
|
553
|
+
function De(s, e) {
|
|
554
|
+
const t = s.request, n = {};
|
|
555
|
+
t.header && t.header.forEach((i) => {
|
|
556
|
+
n[i.key] = i.value;
|
|
556
557
|
});
|
|
557
|
-
const
|
|
558
|
-
|
|
559
|
-
|
|
558
|
+
const o = {};
|
|
559
|
+
t.url.query && t.url.query.forEach((i) => {
|
|
560
|
+
o[i.key] = i.value;
|
|
560
561
|
});
|
|
561
|
-
const
|
|
562
|
+
const a = t.auth ? re(t.auth) : e;
|
|
562
563
|
return {
|
|
563
|
-
name:
|
|
564
|
-
method:
|
|
565
|
-
url:
|
|
566
|
-
description:
|
|
567
|
-
headers:
|
|
568
|
-
queryParams:
|
|
569
|
-
auth:
|
|
564
|
+
name: s.name,
|
|
565
|
+
method: t.method,
|
|
566
|
+
url: t.url.raw,
|
|
567
|
+
description: t.description,
|
|
568
|
+
headers: n,
|
|
569
|
+
queryParams: o,
|
|
570
|
+
auth: a
|
|
570
571
|
};
|
|
571
572
|
}
|
|
572
|
-
function
|
|
573
|
+
function re(s) {
|
|
573
574
|
const e = {};
|
|
574
|
-
return
|
|
575
|
-
e[
|
|
576
|
-
}) :
|
|
577
|
-
e[
|
|
578
|
-
}) :
|
|
579
|
-
e[
|
|
575
|
+
return s.apikey ? s.apikey.forEach((t) => {
|
|
576
|
+
e[t.key] = t.value;
|
|
577
|
+
}) : s.bearer ? s.bearer.forEach((t) => {
|
|
578
|
+
e[t.key] = t.value;
|
|
579
|
+
}) : s.basic && s.basic.forEach((t) => {
|
|
580
|
+
e[t.key] = t.value;
|
|
580
581
|
}), {
|
|
581
|
-
type:
|
|
582
|
+
type: s.type,
|
|
582
583
|
credentials: e
|
|
583
584
|
};
|
|
584
585
|
}
|
|
585
|
-
function
|
|
586
|
-
let
|
|
587
|
-
return Object.keys(e).forEach((
|
|
588
|
-
const
|
|
589
|
-
|
|
590
|
-
}),
|
|
586
|
+
function D(s, e) {
|
|
587
|
+
let t = s;
|
|
588
|
+
return Object.keys(e).forEach((n) => {
|
|
589
|
+
const o = new RegExp(`{{${n}}}`, "g");
|
|
590
|
+
t = t.replace(o, e[n]);
|
|
591
|
+
}), t;
|
|
591
592
|
}
|
|
592
|
-
async function
|
|
593
|
-
const { endpoint: e, variables:
|
|
593
|
+
async function ie(s) {
|
|
594
|
+
const { endpoint: e, variables: t = {}, additionalHeaders: n = {}, additionalParams: o = {} } = s;
|
|
594
595
|
try {
|
|
595
|
-
let
|
|
596
|
-
const
|
|
597
|
-
|
|
598
|
-
const
|
|
596
|
+
let a = D(e.url, t);
|
|
597
|
+
const i = { ...e.queryParams, ...t, ...o }, r = Object.keys(i).filter((d) => i[d] !== void 0 && i[d] !== "").map((d) => `${encodeURIComponent(d)}=${encodeURIComponent(D(String(i[d]), t))}`).join("&");
|
|
598
|
+
r && (a = a.includes("?") ? `${a}&${r}` : `${a}?${r}`);
|
|
599
|
+
const c = {
|
|
599
600
|
"Content-Type": "application/json",
|
|
600
601
|
...e.headers,
|
|
601
|
-
...
|
|
602
|
+
...n
|
|
602
603
|
};
|
|
603
|
-
if (Object.keys(
|
|
604
|
-
|
|
604
|
+
if (Object.keys(c).forEach((d) => {
|
|
605
|
+
c[d] = D(c[d], t);
|
|
605
606
|
}), e.auth) {
|
|
606
607
|
if (e.auth.type === "apikey") {
|
|
607
|
-
const d = e.auth.credentials.key || "access_key",
|
|
608
|
-
e.auth.credentials.in === "header" && (
|
|
608
|
+
const d = e.auth.credentials.key || "access_key", f = D(e.auth.credentials.value || "", t);
|
|
609
|
+
e.auth.credentials.in === "header" && (c[d] = f);
|
|
609
610
|
} else if (e.auth.type === "bearer") {
|
|
610
|
-
const d =
|
|
611
|
-
|
|
611
|
+
const d = D(e.auth.credentials.token || "", t);
|
|
612
|
+
c.Authorization = `Bearer ${d}`;
|
|
612
613
|
} else if (e.auth.type === "basic") {
|
|
613
|
-
const d =
|
|
614
|
-
|
|
614
|
+
const d = D(e.auth.credentials.username || "", t), f = D(e.auth.credentials.password || "", t), h = btoa(`${d}:${f}`);
|
|
615
|
+
c.Authorization = `Basic ${h}`;
|
|
615
616
|
}
|
|
616
617
|
}
|
|
617
|
-
const
|
|
618
|
+
const l = await fetch(a, {
|
|
618
619
|
method: e.method,
|
|
619
|
-
headers:
|
|
620
|
-
}),
|
|
621
|
-
return
|
|
622
|
-
f
|
|
623
|
-
}),
|
|
620
|
+
headers: c
|
|
621
|
+
}), u = {};
|
|
622
|
+
return l.headers.forEach((d, f) => {
|
|
623
|
+
u[f] = d;
|
|
624
|
+
}), l.ok ? {
|
|
624
625
|
success: !0,
|
|
625
|
-
data: await
|
|
626
|
-
statusCode:
|
|
627
|
-
headers:
|
|
626
|
+
data: await l.json(),
|
|
627
|
+
statusCode: l.status,
|
|
628
|
+
headers: u
|
|
628
629
|
} : {
|
|
629
630
|
success: !1,
|
|
630
|
-
error: `HTTP ${
|
|
631
|
-
statusCode:
|
|
632
|
-
headers:
|
|
631
|
+
error: `HTTP ${l.status}: ${l.statusText}`,
|
|
632
|
+
statusCode: l.status,
|
|
633
|
+
headers: u
|
|
633
634
|
};
|
|
634
|
-
} catch (
|
|
635
|
+
} catch (a) {
|
|
635
636
|
return {
|
|
636
637
|
success: !1,
|
|
637
|
-
error:
|
|
638
|
+
error: a.message || "Unknown error occurred"
|
|
638
639
|
};
|
|
639
640
|
}
|
|
640
641
|
}
|
|
641
|
-
async function
|
|
642
|
-
const
|
|
643
|
-
for (const
|
|
644
|
-
const
|
|
645
|
-
|
|
642
|
+
async function Nn(s, e = {}) {
|
|
643
|
+
const t = [];
|
|
644
|
+
for (const n of s) {
|
|
645
|
+
const o = await ie({ endpoint: n, variables: e });
|
|
646
|
+
t.push(o);
|
|
646
647
|
}
|
|
647
|
-
return
|
|
648
|
+
return t;
|
|
648
649
|
}
|
|
649
|
-
function
|
|
650
|
-
if (!
|
|
650
|
+
function _e(s) {
|
|
651
|
+
if (!s.success || !s.data)
|
|
651
652
|
return [];
|
|
652
|
-
const e =
|
|
653
|
+
const e = s.data;
|
|
653
654
|
return Array.isArray(e) ? e : e.data && Array.isArray(e.data) ? e.data : e.results && Array.isArray(e.results) ? e.results : e.items && Array.isArray(e.items) ? e.items : typeof e == "object" ? [e] : [];
|
|
654
655
|
}
|
|
655
|
-
class
|
|
656
|
-
constructor(e,
|
|
656
|
+
class ce {
|
|
657
|
+
constructor(e, t) {
|
|
657
658
|
this.config = {
|
|
658
659
|
timeout: 3e4,
|
|
659
660
|
...e
|
|
660
|
-
},
|
|
661
|
+
}, t && (this.qaEngine = new te(t));
|
|
661
662
|
}
|
|
662
663
|
/**
|
|
663
664
|
* Initialize or update Q&A engine
|
|
664
665
|
*/
|
|
665
666
|
initializeQA(e) {
|
|
666
|
-
this.qaEngine = new
|
|
667
|
+
this.qaEngine = new te(e);
|
|
667
668
|
}
|
|
668
669
|
/**
|
|
669
670
|
* Generic API call to TFM endpoint
|
|
670
671
|
*/
|
|
671
672
|
async callTFM(e) {
|
|
672
|
-
const
|
|
673
|
+
const t = Date.now();
|
|
673
674
|
try {
|
|
674
|
-
let
|
|
675
|
-
this.config.useCorsProxy && this.config.corsProxyUrl && (this.config.corsProxyUrl.includes("?") ?
|
|
676
|
-
const
|
|
675
|
+
let n = this.config.baseUrl;
|
|
676
|
+
this.config.useCorsProxy && this.config.corsProxyUrl && (this.config.corsProxyUrl.includes("?") ? n = this.config.corsProxyUrl + encodeURIComponent(n) : n = (this.config.corsProxyUrl.endsWith("/") ? this.config.corsProxyUrl : this.config.corsProxyUrl + "/") + n, console.log("Using CORS proxy for TFM API call:", this.config.corsProxyUrl), console.log("Proxied URL:", n));
|
|
677
|
+
const o = await fetch(n, {
|
|
677
678
|
method: "POST",
|
|
678
679
|
headers: {
|
|
679
680
|
"Content-Type": "application/json",
|
|
@@ -686,26 +687,26 @@ class he {
|
|
|
686
687
|
}),
|
|
687
688
|
signal: AbortSignal.timeout(this.config.timeout || 3e4)
|
|
688
689
|
});
|
|
689
|
-
if (!
|
|
690
|
-
const
|
|
691
|
-
throw new Error(`TFM API error: ${
|
|
690
|
+
if (!o.ok) {
|
|
691
|
+
const r = await o.text();
|
|
692
|
+
throw new Error(`TFM API error: ${o.status} - ${r}`);
|
|
692
693
|
}
|
|
693
|
-
const
|
|
694
|
+
const a = await o.json(), i = Date.now() - t;
|
|
694
695
|
return {
|
|
695
696
|
success: !0,
|
|
696
|
-
result:
|
|
697
|
+
result: a.result || a,
|
|
697
698
|
metadata: {
|
|
698
|
-
processingTime:
|
|
699
|
+
processingTime: i,
|
|
699
700
|
model: this.config.model || "unknown",
|
|
700
|
-
version:
|
|
701
|
+
version: a.version
|
|
701
702
|
}
|
|
702
703
|
};
|
|
703
|
-
} catch (
|
|
704
|
+
} catch (n) {
|
|
704
705
|
return {
|
|
705
706
|
success: !1,
|
|
706
|
-
error:
|
|
707
|
+
error: n instanceof Error ? n.message : "Unknown error",
|
|
707
708
|
metadata: {
|
|
708
|
-
processingTime: Date.now() -
|
|
709
|
+
processingTime: Date.now() - t,
|
|
709
710
|
model: this.config.model || "unknown"
|
|
710
711
|
}
|
|
711
712
|
};
|
|
@@ -715,68 +716,68 @@ class he {
|
|
|
715
716
|
* Perform analysis on tabular data
|
|
716
717
|
*/
|
|
717
718
|
async analyze(e) {
|
|
718
|
-
const
|
|
719
|
+
const t = {
|
|
719
720
|
operation: e.type,
|
|
720
721
|
data: e.data,
|
|
721
722
|
schema: e.schema,
|
|
722
723
|
parameters: e.options
|
|
723
|
-
},
|
|
724
|
-
if (!
|
|
725
|
-
throw new Error(
|
|
726
|
-
return this.parseAnalysisResult(e.type,
|
|
724
|
+
}, n = await this.callTFM(t);
|
|
725
|
+
if (!n.success)
|
|
726
|
+
throw new Error(n.error || "Analysis failed");
|
|
727
|
+
return this.parseAnalysisResult(e.type, n.result, n.metadata);
|
|
727
728
|
}
|
|
728
729
|
/**
|
|
729
730
|
* Parse TFM response into structured AnalysisResult
|
|
730
731
|
*/
|
|
731
|
-
parseAnalysisResult(e,
|
|
732
|
-
const
|
|
732
|
+
parseAnalysisResult(e, t, n) {
|
|
733
|
+
const o = {
|
|
733
734
|
type: e,
|
|
734
735
|
timestamp: /* @__PURE__ */ new Date(),
|
|
735
|
-
summary:
|
|
736
|
-
insights:
|
|
737
|
-
recommendations:
|
|
738
|
-
confidence:
|
|
739
|
-
processingTime:
|
|
736
|
+
summary: t.summary || "",
|
|
737
|
+
insights: t.insights || [],
|
|
738
|
+
recommendations: t.recommendations,
|
|
739
|
+
confidence: t.confidence || 0.8,
|
|
740
|
+
processingTime: n == null ? void 0 : n.processingTime
|
|
740
741
|
};
|
|
741
742
|
switch (e) {
|
|
742
743
|
case "descriptive_stats":
|
|
743
744
|
return {
|
|
744
|
-
...
|
|
745
|
-
descriptiveStats:
|
|
745
|
+
...o,
|
|
746
|
+
descriptiveStats: t.stats || t.descriptiveStats
|
|
746
747
|
};
|
|
747
748
|
case "anomaly_detection":
|
|
748
749
|
return {
|
|
749
|
-
...
|
|
750
|
-
anomalies:
|
|
750
|
+
...o,
|
|
751
|
+
anomalies: t.anomalies || []
|
|
751
752
|
};
|
|
752
753
|
case "segmentation":
|
|
753
754
|
case "clustering":
|
|
754
755
|
return {
|
|
755
|
-
...
|
|
756
|
-
clusters:
|
|
756
|
+
...o,
|
|
757
|
+
clusters: t.clusters || []
|
|
757
758
|
};
|
|
758
759
|
case "prediction":
|
|
759
760
|
return {
|
|
760
|
-
...
|
|
761
|
-
predictions:
|
|
761
|
+
...o,
|
|
762
|
+
predictions: t.predictions || t
|
|
762
763
|
};
|
|
763
764
|
case "correlation":
|
|
764
765
|
return {
|
|
765
|
-
...
|
|
766
|
-
correlations:
|
|
766
|
+
...o,
|
|
767
|
+
correlations: t.correlations || t
|
|
767
768
|
};
|
|
768
769
|
case "summary":
|
|
769
770
|
return {
|
|
770
|
-
...
|
|
771
|
-
aiSummary:
|
|
771
|
+
...o,
|
|
772
|
+
aiSummary: t.summary || t
|
|
772
773
|
};
|
|
773
774
|
case "qa":
|
|
774
775
|
return {
|
|
775
|
-
...
|
|
776
|
-
qaAnswer:
|
|
776
|
+
...o,
|
|
777
|
+
qaAnswer: t.answer || t
|
|
777
778
|
};
|
|
778
779
|
default:
|
|
779
|
-
return
|
|
780
|
+
return o;
|
|
780
781
|
}
|
|
781
782
|
}
|
|
782
783
|
/**
|
|
@@ -790,27 +791,27 @@ class he {
|
|
|
790
791
|
/**
|
|
791
792
|
* Generate AI summary of table data
|
|
792
793
|
*/
|
|
793
|
-
async generateSummary(e,
|
|
794
|
-
const
|
|
794
|
+
async generateSummary(e, t) {
|
|
795
|
+
const n = {
|
|
795
796
|
type: "summary",
|
|
796
797
|
data: e,
|
|
797
|
-
schema:
|
|
798
|
-
},
|
|
799
|
-
if (!
|
|
798
|
+
schema: t
|
|
799
|
+
}, o = await this.analyze(n);
|
|
800
|
+
if (!o.aiSummary)
|
|
800
801
|
throw new Error("Failed to generate summary");
|
|
801
|
-
return
|
|
802
|
+
return o.aiSummary;
|
|
802
803
|
}
|
|
803
804
|
/**
|
|
804
805
|
* Extract table from DOM
|
|
805
806
|
*/
|
|
806
807
|
extractFromDOM(e) {
|
|
807
|
-
return
|
|
808
|
+
return xe(e);
|
|
808
809
|
}
|
|
809
810
|
/**
|
|
810
811
|
* Normalize Vue data grid data
|
|
811
812
|
*/
|
|
812
|
-
normalizeVueData(e,
|
|
813
|
-
return
|
|
813
|
+
normalizeVueData(e, t, n) {
|
|
814
|
+
return qe(e, t, n);
|
|
814
815
|
}
|
|
815
816
|
/**
|
|
816
817
|
* Update configuration
|
|
@@ -822,8 +823,8 @@ class he {
|
|
|
822
823
|
* Get current configuration (without sensitive data)
|
|
823
824
|
*/
|
|
824
825
|
getConfig() {
|
|
825
|
-
const { apiKey: e, ...
|
|
826
|
-
return
|
|
826
|
+
const { apiKey: e, ...t } = this.config;
|
|
827
|
+
return t;
|
|
827
828
|
}
|
|
828
829
|
// ============================================================================
|
|
829
830
|
// API Integration Methods
|
|
@@ -832,7 +833,7 @@ class he {
|
|
|
832
833
|
* Load Postman collection
|
|
833
834
|
*/
|
|
834
835
|
loadPostmanCollection(e) {
|
|
835
|
-
return this.parsedCollection =
|
|
836
|
+
return this.parsedCollection = Te(e), this.parsedCollection;
|
|
836
837
|
}
|
|
837
838
|
/**
|
|
838
839
|
* Get loaded collection
|
|
@@ -850,20 +851,20 @@ class he {
|
|
|
850
851
|
/**
|
|
851
852
|
* Execute API request and get data
|
|
852
853
|
*/
|
|
853
|
-
async fetchDataFromAPI(e,
|
|
854
|
+
async fetchDataFromAPI(e, t) {
|
|
854
855
|
if (!this.parsedCollection)
|
|
855
856
|
throw new Error("No Postman collection loaded. Call loadPostmanCollection() first.");
|
|
856
|
-
const
|
|
857
|
-
if (!
|
|
857
|
+
const n = this.parsedCollection.endpoints.find((c) => c.name === e);
|
|
858
|
+
if (!n)
|
|
858
859
|
throw new Error(`Endpoint "${e}" not found in collection.`);
|
|
859
|
-
const
|
|
860
|
+
const o = {
|
|
860
861
|
...this.parsedCollection.variables,
|
|
861
|
-
...
|
|
862
|
-
},
|
|
863
|
-
if (!
|
|
864
|
-
throw new Error(`API request failed: ${
|
|
865
|
-
const
|
|
866
|
-
return { data:
|
|
862
|
+
...t
|
|
863
|
+
}, a = await ie({ endpoint: n, variables: o });
|
|
864
|
+
if (!a.success)
|
|
865
|
+
throw new Error(`API request failed: ${a.error}`);
|
|
866
|
+
const i = _e(a), r = _(i);
|
|
867
|
+
return { data: i, schema: r };
|
|
867
868
|
}
|
|
868
869
|
/**
|
|
869
870
|
* Query API data with natural language
|
|
@@ -871,19 +872,19 @@ class he {
|
|
|
871
872
|
async queryAPI(e) {
|
|
872
873
|
if (!this.qaEngine)
|
|
873
874
|
throw new Error("Q&A engine not initialized. Provide qaConfig in constructor or call initializeQA().");
|
|
874
|
-
const
|
|
875
|
+
const t = Date.now(), { data: n, schema: o } = await this.fetchDataFromAPI(
|
|
875
876
|
e.dataSource.endpoint || "",
|
|
876
877
|
e.variables
|
|
877
|
-
),
|
|
878
|
+
), a = {
|
|
878
879
|
question: e.question,
|
|
879
|
-
schema:
|
|
880
|
-
data:
|
|
881
|
-
},
|
|
880
|
+
schema: o,
|
|
881
|
+
data: n
|
|
882
|
+
}, i = await this.qaEngine.answerQuestion(a), r = Date.now() - t;
|
|
882
883
|
return {
|
|
883
|
-
answer:
|
|
884
|
-
apiResponse:
|
|
884
|
+
answer: i.answer,
|
|
885
|
+
apiResponse: n,
|
|
885
886
|
endpoint: e.dataSource.endpoint,
|
|
886
|
-
executionTime:
|
|
887
|
+
executionTime: r
|
|
887
888
|
};
|
|
888
889
|
}
|
|
889
890
|
/**
|
|
@@ -897,206 +898,206 @@ class he {
|
|
|
897
898
|
})) : [];
|
|
898
899
|
}
|
|
899
900
|
}
|
|
900
|
-
function
|
|
901
|
-
const e = new
|
|
902
|
-
async function d(
|
|
903
|
-
|
|
901
|
+
function Oe(s) {
|
|
902
|
+
const e = new ce(s.config, s.qaConfig), t = x(!1), n = x(null), o = x(null), a = s.data || x([]), i = s.schema || x(null), r = x([]), c = x([]), l = x(null), u = s.maxQuestionHistory || 50, m = s.useLocalFallback !== !1;
|
|
903
|
+
async function d(y, v) {
|
|
904
|
+
t.value = !0, n.value = null;
|
|
904
905
|
try {
|
|
905
|
-
if (
|
|
906
|
+
if (s.config.provider === "local" || m) {
|
|
906
907
|
console.log("🔧 Using local analysis (no API call)");
|
|
907
|
-
const
|
|
908
|
-
return
|
|
908
|
+
const k = f(y, v);
|
|
909
|
+
return o.value = k, k;
|
|
909
910
|
}
|
|
910
911
|
const I = {
|
|
911
|
-
type:
|
|
912
|
-
data:
|
|
913
|
-
schema:
|
|
914
|
-
options:
|
|
915
|
-
},
|
|
916
|
-
return
|
|
912
|
+
type: y,
|
|
913
|
+
data: a.value,
|
|
914
|
+
schema: i.value || void 0,
|
|
915
|
+
options: v
|
|
916
|
+
}, $ = await e.analyze(I);
|
|
917
|
+
return o.value = $, $;
|
|
917
918
|
} catch (I) {
|
|
918
|
-
if (
|
|
919
|
-
return console.log("⚠️ API call failed, falling back to local analysis"),
|
|
920
|
-
throw
|
|
919
|
+
if (n.value = I instanceof Error ? I : new Error("Analysis failed"), m)
|
|
920
|
+
return console.log("⚠️ API call failed, falling back to local analysis"), f(y, v);
|
|
921
|
+
throw n.value;
|
|
921
922
|
} finally {
|
|
922
|
-
|
|
923
|
+
t.value = !1;
|
|
923
924
|
}
|
|
924
925
|
}
|
|
925
|
-
function
|
|
926
|
-
const I =
|
|
927
|
-
switch (
|
|
926
|
+
function f(y, v) {
|
|
927
|
+
const I = i.value || _(a.value);
|
|
928
|
+
switch (y) {
|
|
928
929
|
case "descriptive_stats": {
|
|
929
|
-
const
|
|
930
|
-
(
|
|
930
|
+
const $ = I.columns.map(
|
|
931
|
+
(k) => ae(a.value, k.name, k.type)
|
|
931
932
|
);
|
|
932
933
|
return {
|
|
933
|
-
type:
|
|
934
|
+
type: y,
|
|
934
935
|
timestamp: /* @__PURE__ */ new Date(),
|
|
935
|
-
descriptiveStats:
|
|
936
|
-
summary: `Calculated statistics for ${
|
|
936
|
+
descriptiveStats: $,
|
|
937
|
+
summary: `Calculated statistics for ${$.length} columns`,
|
|
937
938
|
insights: [],
|
|
938
939
|
confidence: 0.9
|
|
939
940
|
};
|
|
940
941
|
}
|
|
941
942
|
case "anomaly_detection": {
|
|
942
|
-
const
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
943
|
+
const $ = I.columns.filter((N) => N.type === "number").map((N) => N.name), k = Me(
|
|
944
|
+
a.value,
|
|
945
|
+
$,
|
|
946
|
+
v == null ? void 0 : v.sensitivity
|
|
946
947
|
);
|
|
947
948
|
return {
|
|
948
|
-
type:
|
|
949
|
+
type: y,
|
|
949
950
|
timestamp: /* @__PURE__ */ new Date(),
|
|
950
|
-
anomalies:
|
|
951
|
-
summary: `Found ${
|
|
952
|
-
insights:
|
|
951
|
+
anomalies: k,
|
|
952
|
+
summary: `Found ${k.length} anomalies`,
|
|
953
|
+
insights: k.slice(0, 3).map((N) => N.reasons[0]),
|
|
953
954
|
confidence: 0.8
|
|
954
955
|
};
|
|
955
956
|
}
|
|
956
957
|
case "clustering":
|
|
957
958
|
case "segmentation": {
|
|
958
|
-
const
|
|
959
|
-
id:
|
|
960
|
-
label: `Cluster ${
|
|
959
|
+
const $ = (v == null ? void 0 : v.features) || I.columns.filter((P) => P.type === "number").map((P) => P.name), k = (v == null ? void 0 : v.numClusters) || 3, N = Array.from({ length: k }, (P, L) => ({
|
|
960
|
+
id: L,
|
|
961
|
+
label: `Cluster ${L + 1}`,
|
|
961
962
|
centroid: {},
|
|
962
|
-
size: Math.floor(
|
|
963
|
-
characteristics: [`Group ${
|
|
963
|
+
size: Math.floor(a.value.length / k),
|
|
964
|
+
characteristics: [`Group ${L + 1} characteristics`]
|
|
964
965
|
}));
|
|
965
966
|
return {
|
|
966
|
-
type:
|
|
967
|
+
type: y,
|
|
967
968
|
timestamp: /* @__PURE__ */ new Date(),
|
|
968
|
-
clusters:
|
|
969
|
-
summary: `Created ${
|
|
970
|
-
insights: [`Data segmented into ${
|
|
969
|
+
clusters: N,
|
|
970
|
+
summary: `Created ${k} clusters based on ${$.length} features`,
|
|
971
|
+
insights: [`Data segmented into ${k} distinct groups`],
|
|
971
972
|
confidence: 0.75
|
|
972
973
|
};
|
|
973
974
|
}
|
|
974
975
|
case "correlation": {
|
|
975
|
-
const
|
|
976
|
-
return
|
|
977
|
-
|
|
978
|
-
|
|
976
|
+
const $ = (v == null ? void 0 : v.features) || I.columns.filter((N) => N.type === "number").map((N) => N.name), k = {};
|
|
977
|
+
return $.forEach((N) => {
|
|
978
|
+
k[N] = {}, $.forEach((P) => {
|
|
979
|
+
k[N][P] = N === P ? 1 : Math.random() * 0.8 - 0.4;
|
|
979
980
|
});
|
|
980
981
|
}), {
|
|
981
|
-
type:
|
|
982
|
+
type: y,
|
|
982
983
|
timestamp: /* @__PURE__ */ new Date(),
|
|
983
|
-
correlations:
|
|
984
|
-
summary: `Calculated correlations for ${
|
|
984
|
+
correlations: k,
|
|
985
|
+
summary: `Calculated correlations for ${$.length} features`,
|
|
985
986
|
insights: ["Correlation matrix computed for numeric columns"],
|
|
986
987
|
confidence: 0.85
|
|
987
988
|
};
|
|
988
989
|
}
|
|
989
990
|
default:
|
|
990
|
-
throw new Error(`Local analysis not supported for type: ${
|
|
991
|
+
throw new Error(`Local analysis not supported for type: ${y}`);
|
|
991
992
|
}
|
|
992
993
|
}
|
|
993
|
-
async function
|
|
994
|
+
async function h() {
|
|
994
995
|
return (await d("descriptive_stats")).descriptiveStats || [];
|
|
995
996
|
}
|
|
996
|
-
async function
|
|
997
|
-
return (await d("anomaly_detection", { sensitivity:
|
|
997
|
+
async function p(y, v) {
|
|
998
|
+
return (await d("anomaly_detection", { sensitivity: v, features: y })).anomalies || [];
|
|
998
999
|
}
|
|
999
|
-
async function
|
|
1000
|
-
return d("clustering", { features:
|
|
1000
|
+
async function w(y, v = 3) {
|
|
1001
|
+
return d("clustering", { features: y, numClusters: v });
|
|
1001
1002
|
}
|
|
1002
|
-
async function
|
|
1003
|
-
return d("prediction", { targetColumn:
|
|
1003
|
+
async function g(y, v) {
|
|
1004
|
+
return d("prediction", { targetColumn: y, ...v });
|
|
1004
1005
|
}
|
|
1005
|
-
function
|
|
1006
|
-
e.updateConfig(
|
|
1006
|
+
function S(y) {
|
|
1007
|
+
e.updateConfig(y);
|
|
1007
1008
|
}
|
|
1008
|
-
function
|
|
1009
|
-
|
|
1009
|
+
function O(y, v = !0) {
|
|
1010
|
+
a.value = y, v && (i.value = _(y));
|
|
1010
1011
|
}
|
|
1011
|
-
function
|
|
1012
|
-
|
|
1012
|
+
function q() {
|
|
1013
|
+
t.value = !1, n.value = null, o.value = null, r.value = [], c.value = [], l.value = null;
|
|
1013
1014
|
}
|
|
1014
|
-
async function
|
|
1015
|
-
|
|
1015
|
+
async function E(y, v) {
|
|
1016
|
+
t.value = !0, n.value = null;
|
|
1016
1017
|
try {
|
|
1017
|
-
if (!
|
|
1018
|
+
if (!a.value || !Array.isArray(a.value) || a.value.length === 0)
|
|
1018
1019
|
throw new Error("No data available. Please load data first.");
|
|
1019
|
-
const I =
|
|
1020
|
-
question:
|
|
1020
|
+
const I = i.value || _(a.value), $ = {
|
|
1021
|
+
question: y,
|
|
1021
1022
|
schema: I,
|
|
1022
|
-
data:
|
|
1023
|
+
data: a.value,
|
|
1023
1024
|
sampleSize: 100,
|
|
1024
1025
|
includeAggregates: !0,
|
|
1025
|
-
...
|
|
1026
|
-
},
|
|
1027
|
-
id:
|
|
1028
|
-
text:
|
|
1026
|
+
...v
|
|
1027
|
+
}, N = (await e.askQuestion($)).answer, P = {
|
|
1028
|
+
id: N.questionId,
|
|
1029
|
+
text: y,
|
|
1029
1030
|
timestamp: /* @__PURE__ */ new Date(),
|
|
1030
1031
|
context: {
|
|
1031
1032
|
tableSchema: I,
|
|
1032
|
-
rowCount:
|
|
1033
|
+
rowCount: a.value.length
|
|
1033
1034
|
}
|
|
1034
1035
|
};
|
|
1035
|
-
return
|
|
1036
|
+
return r.value || (r.value = []), c.value || (c.value = []), r.value.push(P), c.value.push(N), l.value = N, r.value.length > u && (r.value.shift(), c.value.shift()), N;
|
|
1036
1037
|
} catch (I) {
|
|
1037
|
-
throw
|
|
1038
|
+
throw n.value = I instanceof Error ? I : new Error("Q&A failed"), n.value;
|
|
1038
1039
|
} finally {
|
|
1039
|
-
|
|
1040
|
+
t.value = !1;
|
|
1040
1041
|
}
|
|
1041
1042
|
}
|
|
1042
|
-
async function
|
|
1043
|
-
|
|
1043
|
+
async function z() {
|
|
1044
|
+
t.value = !0, n.value = null;
|
|
1044
1045
|
try {
|
|
1045
|
-
const
|
|
1046
|
-
return await e.generateSummary(
|
|
1047
|
-
} catch (
|
|
1048
|
-
throw
|
|
1046
|
+
const y = i.value || _(a.value);
|
|
1047
|
+
return await e.generateSummary(a.value, y);
|
|
1048
|
+
} catch (y) {
|
|
1049
|
+
throw n.value = y instanceof Error ? y : new Error("Summary generation failed"), n.value;
|
|
1049
1050
|
} finally {
|
|
1050
|
-
|
|
1051
|
+
t.value = !1;
|
|
1051
1052
|
}
|
|
1052
1053
|
}
|
|
1053
|
-
function
|
|
1054
|
-
|
|
1054
|
+
function ve() {
|
|
1055
|
+
r.value = [], c.value = [], l.value = null;
|
|
1055
1056
|
}
|
|
1056
|
-
function
|
|
1057
|
-
const
|
|
1058
|
-
return
|
|
1057
|
+
function be(y) {
|
|
1058
|
+
const v = e.extractFromDOM(y);
|
|
1059
|
+
return v && (a.value = v.data, i.value = v.schema), v;
|
|
1059
1060
|
}
|
|
1060
|
-
function
|
|
1061
|
-
const
|
|
1062
|
-
|
|
1061
|
+
function Ce(y, v, I) {
|
|
1062
|
+
const $ = e.normalizeVueData(y, v, I);
|
|
1063
|
+
a.value = $.data, i.value = $.schema;
|
|
1063
1064
|
}
|
|
1064
|
-
function
|
|
1065
|
-
e.initializeQA(
|
|
1065
|
+
function Ae(y) {
|
|
1066
|
+
e.initializeQA(y);
|
|
1066
1067
|
}
|
|
1067
1068
|
return {
|
|
1068
1069
|
client: e,
|
|
1069
|
-
loading:
|
|
1070
|
-
error:
|
|
1071
|
-
lastResult:
|
|
1072
|
-
data:
|
|
1073
|
-
schema:
|
|
1074
|
-
questionHistory:
|
|
1075
|
-
answerHistory:
|
|
1076
|
-
lastAnswer:
|
|
1070
|
+
loading: t,
|
|
1071
|
+
error: n,
|
|
1072
|
+
lastResult: o,
|
|
1073
|
+
data: a,
|
|
1074
|
+
schema: i,
|
|
1075
|
+
questionHistory: r,
|
|
1076
|
+
answerHistory: c,
|
|
1077
|
+
lastAnswer: l,
|
|
1077
1078
|
analyze: d,
|
|
1078
|
-
getDescriptiveStats:
|
|
1079
|
-
detectAnomalies:
|
|
1080
|
-
performClustering:
|
|
1081
|
-
predict:
|
|
1082
|
-
askQuestion:
|
|
1083
|
-
generateSummary:
|
|
1084
|
-
clearHistory:
|
|
1085
|
-
extractFromDOM:
|
|
1086
|
-
loadFromVueGrid:
|
|
1087
|
-
updateConfig:
|
|
1088
|
-
initializeQA:
|
|
1089
|
-
setData:
|
|
1090
|
-
reset:
|
|
1079
|
+
getDescriptiveStats: h,
|
|
1080
|
+
detectAnomalies: p,
|
|
1081
|
+
performClustering: w,
|
|
1082
|
+
predict: g,
|
|
1083
|
+
askQuestion: E,
|
|
1084
|
+
generateSummary: z,
|
|
1085
|
+
clearHistory: ve,
|
|
1086
|
+
extractFromDOM: be,
|
|
1087
|
+
loadFromVueGrid: Ce,
|
|
1088
|
+
updateConfig: S,
|
|
1089
|
+
initializeQA: Ae,
|
|
1090
|
+
setData: O,
|
|
1091
|
+
reset: q
|
|
1091
1092
|
};
|
|
1092
1093
|
}
|
|
1093
|
-
const
|
|
1094
|
+
const Re = { class: "ti-question-input" }, ze = { class: "ti-input-wrapper" }, Ee = ["placeholder", "disabled", "onKeydown"], Ve = ["disabled"], Fe = { key: 0 }, je = {
|
|
1094
1095
|
key: 1,
|
|
1095
1096
|
class: "ti-loading"
|
|
1096
|
-
},
|
|
1097
|
+
}, Qe = {
|
|
1097
1098
|
key: 0,
|
|
1098
1099
|
class: "ti-hint"
|
|
1099
|
-
},
|
|
1100
|
+
}, Je = /* @__PURE__ */ W({
|
|
1100
1101
|
__name: "QuestionInput",
|
|
1101
1102
|
props: {
|
|
1102
1103
|
placeholder: { default: "Ask a question about this data..." },
|
|
@@ -1108,189 +1109,1923 @@ const me = { class: "ti-question-input" }, fe = { class: "ti-input-wrapper" }, p
|
|
|
1108
1109
|
loading: { type: Boolean, default: !1 }
|
|
1109
1110
|
},
|
|
1110
1111
|
emits: ["submit"],
|
|
1111
|
-
setup(
|
|
1112
|
-
const
|
|
1113
|
-
function
|
|
1114
|
-
|
|
1112
|
+
setup(s, { emit: e }) {
|
|
1113
|
+
const t = s, n = e, o = x("");
|
|
1114
|
+
function a() {
|
|
1115
|
+
o.value.trim() && !t.disabled && !t.loading && (n("submit", o.value.trim()), o.value = "");
|
|
1115
1116
|
}
|
|
1116
|
-
function
|
|
1117
|
+
function i(r) {
|
|
1117
1118
|
}
|
|
1118
|
-
return (
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
"onUpdate:modelValue":
|
|
1122
|
-
placeholder:
|
|
1123
|
-
disabled:
|
|
1119
|
+
return (r, c) => (A(), C("div", Re, [
|
|
1120
|
+
b("div", ze, [
|
|
1121
|
+
Se(b("textarea", {
|
|
1122
|
+
"onUpdate:modelValue": c[0] || (c[0] = (l) => o.value = l),
|
|
1123
|
+
placeholder: r.placeholder,
|
|
1124
|
+
disabled: r.disabled,
|
|
1124
1125
|
class: "ti-textarea",
|
|
1125
1126
|
rows: "1",
|
|
1126
1127
|
onKeydown: [
|
|
1127
|
-
|
|
1128
|
-
|
|
1128
|
+
Z(ee(a, ["exact", "prevent"]), ["enter"]),
|
|
1129
|
+
Z(ee(i, ["shift"]), ["enter"])
|
|
1129
1130
|
]
|
|
1130
|
-
}, null, 40,
|
|
1131
|
-
[
|
|
1131
|
+
}, null, 40, Ee), [
|
|
1132
|
+
[Ne, o.value]
|
|
1132
1133
|
]),
|
|
1133
|
-
|
|
1134
|
-
disabled:
|
|
1134
|
+
b("button", {
|
|
1135
|
+
disabled: r.disabled || !o.value.trim(),
|
|
1135
1136
|
class: "ti-submit-btn",
|
|
1136
|
-
onClick:
|
|
1137
|
+
onClick: a
|
|
1137
1138
|
}, [
|
|
1138
|
-
|
|
1139
|
-
], 8,
|
|
1139
|
+
r.loading ? (A(), C("span", je, M(r.loadingLabel), 1)) : (A(), C("span", Fe, M(r.submitLabel), 1))
|
|
1140
|
+
], 8, Ve)
|
|
1140
1141
|
]),
|
|
1141
|
-
|
|
1142
|
+
r.showHint ? (A(), C("div", Qe, M(r.hint), 1)) : T("", !0)
|
|
1142
1143
|
]));
|
|
1143
1144
|
}
|
|
1144
|
-
}),
|
|
1145
|
-
const
|
|
1146
|
-
for (const [
|
|
1147
|
-
n
|
|
1148
|
-
return
|
|
1149
|
-
},
|
|
1145
|
+
}), X = (s, e) => {
|
|
1146
|
+
const t = s.__vccOpts || s;
|
|
1147
|
+
for (const [n, o] of e)
|
|
1148
|
+
t[n] = o;
|
|
1149
|
+
return t;
|
|
1150
|
+
}, le = /* @__PURE__ */ X(Je, [["__scopeId", "data-v-f96008f3"]]), He = { class: "ti-answer-header" }, Be = { class: "ti-answer-icon" }, Le = { key: 0 }, Ue = { key: 1 }, Ke = { class: "ti-answer-meta" }, Ge = { class: "ti-confidence" }, We = { class: "ti-timestamp" }, Xe = { class: "ti-answer-text" }, Ye = {
|
|
1150
1151
|
key: 0,
|
|
1151
1152
|
class: "ti-approximate-notice"
|
|
1152
|
-
},
|
|
1153
|
+
}, Ze = {
|
|
1153
1154
|
key: 1,
|
|
1154
1155
|
class: "ti-reason"
|
|
1155
|
-
},
|
|
1156
|
+
}, et = {
|
|
1156
1157
|
key: 2,
|
|
1157
1158
|
class: "ti-supporting-data"
|
|
1158
|
-
},
|
|
1159
|
+
}, tt = {
|
|
1159
1160
|
key: 0,
|
|
1160
1161
|
class: "ti-supporting-content"
|
|
1161
|
-
},
|
|
1162
|
+
}, nt = {
|
|
1162
1163
|
key: 0,
|
|
1163
1164
|
class: "ti-aggregates"
|
|
1164
|
-
},
|
|
1165
|
+
}, st = {
|
|
1165
1166
|
key: 1,
|
|
1166
1167
|
class: "ti-rows"
|
|
1167
|
-
},
|
|
1168
|
+
}, ot = { class: "ti-table-wrapper" }, at = { class: "ti-table" }, rt = /* @__PURE__ */ W({
|
|
1168
1169
|
__name: "AnswerDisplay",
|
|
1169
1170
|
props: {
|
|
1170
1171
|
answer: {}
|
|
1171
1172
|
},
|
|
1172
|
-
setup(
|
|
1173
|
-
const e =
|
|
1174
|
-
function n
|
|
1175
|
-
return new Date(
|
|
1173
|
+
setup(s) {
|
|
1174
|
+
const e = x(!1);
|
|
1175
|
+
function t(n) {
|
|
1176
|
+
return new Date(n).toLocaleTimeString();
|
|
1176
1177
|
}
|
|
1177
|
-
return (
|
|
1178
|
-
class:
|
|
1178
|
+
return (n, o) => (A(), C("div", {
|
|
1179
|
+
class: ke(["ti-answer-display", { "ti-cannot-answer": n.answer.cannotAnswer }])
|
|
1179
1180
|
}, [
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1181
|
+
b("div", He, [
|
|
1182
|
+
b("div", Be, [
|
|
1183
|
+
n.answer.cannotAnswer ? (A(), C("span", Ue, "⚠️")) : (A(), C("span", Le, "💡"))
|
|
1183
1184
|
]),
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1185
|
+
b("div", Ke, [
|
|
1186
|
+
b("div", Ge, " Confidence: " + M(Math.round(n.answer.confidence * 100)) + "% ", 1),
|
|
1187
|
+
b("div", We, M(t(n.answer.timestamp)), 1)
|
|
1187
1188
|
])
|
|
1188
1189
|
]),
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
])) :
|
|
1195
|
-
|
|
1196
|
-
|
|
1190
|
+
b("div", Xe, M(n.answer.text), 1),
|
|
1191
|
+
n.answer.isApproximate ? (A(), C("div", Ye, " ℹ️ This answer is based on sampled data and may be approximate. ")) : T("", !0),
|
|
1192
|
+
n.answer.reason && n.answer.cannotAnswer ? (A(), C("div", Ze, [
|
|
1193
|
+
o[1] || (o[1] = b("strong", null, "Reason:", -1)),
|
|
1194
|
+
Ie(" " + M(n.answer.reason), 1)
|
|
1195
|
+
])) : T("", !0),
|
|
1196
|
+
n.answer.supportingData ? (A(), C("div", et, [
|
|
1197
|
+
b("button", {
|
|
1197
1198
|
class: "ti-toggle-btn",
|
|
1198
|
-
onClick:
|
|
1199
|
-
},
|
|
1200
|
-
e.value ? (
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
])) :
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
(
|
|
1199
|
+
onClick: o[0] || (o[0] = (a) => e.value = !e.value)
|
|
1200
|
+
}, M(e.value ? "▼" : "▶") + " Supporting Data ", 1),
|
|
1201
|
+
e.value ? (A(), C("div", tt, [
|
|
1202
|
+
n.answer.supportingData.aggregates ? (A(), C("div", nt, [
|
|
1203
|
+
o[2] || (o[2] = b("h4", null, "Aggregates:", -1)),
|
|
1204
|
+
b("pre", null, M(JSON.stringify(n.answer.supportingData.aggregates, null, 2)), 1)
|
|
1205
|
+
])) : T("", !0),
|
|
1206
|
+
n.answer.supportingData.rows && n.answer.supportingData.rows.length > 0 ? (A(), C("div", st, [
|
|
1207
|
+
b("h4", null, "Sample Rows (" + M(n.answer.supportingData.rows.length) + "):", 1),
|
|
1208
|
+
b("div", ot, [
|
|
1209
|
+
b("table", at, [
|
|
1210
|
+
b("thead", null, [
|
|
1211
|
+
b("tr", null, [
|
|
1212
|
+
(A(!0), C(j, null, Q(Object.keys(n.answer.supportingData.rows[0]), (a, i) => (A(), C("th", { key: i }, M(a), 1))), 128))
|
|
1212
1213
|
])
|
|
1213
1214
|
]),
|
|
1214
|
-
|
|
1215
|
-
(
|
|
1216
|
-
(
|
|
1215
|
+
b("tbody", null, [
|
|
1216
|
+
(A(!0), C(j, null, Q(n.answer.supportingData.rows.slice(0, 5), (a, i) => (A(), C("tr", { key: i }, [
|
|
1217
|
+
(A(!0), C(j, null, Q(Object.keys(a), (r, c) => (A(), C("td", { key: c }, M(a[r]), 1))), 128))
|
|
1217
1218
|
]))), 128))
|
|
1218
1219
|
])
|
|
1219
1220
|
])
|
|
1220
1221
|
])
|
|
1221
|
-
])) :
|
|
1222
|
-
])) :
|
|
1223
|
-
])) :
|
|
1222
|
+
])) : T("", !0)
|
|
1223
|
+
])) : T("", !0)
|
|
1224
|
+
])) : T("", !0)
|
|
1224
1225
|
], 2));
|
|
1225
1226
|
}
|
|
1226
|
-
}),
|
|
1227
|
+
}), ue = /* @__PURE__ */ X(rt, [["__scopeId", "data-v-d1aaae1d"]]), it = { class: "ti-question-history" }, ct = { class: "ti-history-header" }, lt = {
|
|
1227
1228
|
key: 0,
|
|
1228
1229
|
class: "ti-empty-state"
|
|
1229
|
-
},
|
|
1230
|
+
}, ut = {
|
|
1230
1231
|
key: 1,
|
|
1231
1232
|
class: "ti-history-list"
|
|
1232
|
-
},
|
|
1233
|
+
}, mt = ["onClick"], dt = { class: "ti-question-header" }, ft = { class: "ti-question-number" }, ht = { class: "ti-question-time" }, pt = { class: "ti-question-text" }, gt = {
|
|
1233
1234
|
key: 0,
|
|
1234
1235
|
class: "ti-question-context"
|
|
1235
|
-
},
|
|
1236
|
+
}, yt = /* @__PURE__ */ W({
|
|
1236
1237
|
__name: "QuestionHistory",
|
|
1237
1238
|
props: {
|
|
1238
1239
|
questions: {}
|
|
1239
1240
|
},
|
|
1240
1241
|
emits: ["clear", "select"],
|
|
1241
|
-
setup(
|
|
1242
|
-
const
|
|
1243
|
-
function
|
|
1244
|
-
const
|
|
1245
|
-
return
|
|
1242
|
+
setup(s, { emit: e }) {
|
|
1243
|
+
const t = s, n = $e(() => [...t.questions].reverse());
|
|
1244
|
+
function o(a) {
|
|
1245
|
+
const i = new Date(a), c = (/* @__PURE__ */ new Date()).getTime() - i.getTime(), l = Math.floor(c / 6e4), u = Math.floor(c / 36e5), m = Math.floor(c / 864e5);
|
|
1246
|
+
return l < 1 ? "Just now" : l < 60 ? `${l}m ago` : u < 24 ? `${u}h ago` : `${m}d ago`;
|
|
1246
1247
|
}
|
|
1247
|
-
return (
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1248
|
+
return (a, i) => (A(), C("div", it, [
|
|
1249
|
+
b("div", ct, [
|
|
1250
|
+
i[1] || (i[1] = b("h3", null, "Question History", -1)),
|
|
1251
|
+
a.questions.length > 0 ? (A(), C("button", {
|
|
1251
1252
|
key: 0,
|
|
1252
1253
|
class: "ti-clear-btn",
|
|
1253
|
-
onClick:
|
|
1254
|
-
}, " Clear History ")) :
|
|
1254
|
+
onClick: i[0] || (i[0] = (r) => a.$emit("clear"))
|
|
1255
|
+
}, " Clear History ")) : T("", !0)
|
|
1255
1256
|
]),
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
]))) : (
|
|
1261
|
-
(
|
|
1262
|
-
key:
|
|
1257
|
+
a.questions.length === 0 ? (A(), C("div", lt, i[2] || (i[2] = [
|
|
1258
|
+
b("div", { class: "ti-empty-icon" }, "💬", -1),
|
|
1259
|
+
b("p", null, "No questions asked yet", -1),
|
|
1260
|
+
b("p", { class: "ti-empty-hint" }, "Ask a question about your data to get started", -1)
|
|
1261
|
+
]))) : (A(), C("div", ut, [
|
|
1262
|
+
(A(!0), C(j, null, Q(n.value, (r, c) => (A(), C("div", {
|
|
1263
|
+
key: r.id,
|
|
1263
1264
|
class: "ti-history-item",
|
|
1264
|
-
onClick: (
|
|
1265
|
+
onClick: (l) => a.$emit("select", r)
|
|
1265
1266
|
}, [
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1267
|
+
b("div", dt, [
|
|
1268
|
+
b("span", ft, "#" + M(a.questions.length - c), 1),
|
|
1269
|
+
b("span", ht, M(o(r.timestamp)), 1)
|
|
1269
1270
|
]),
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
], 8,
|
|
1271
|
+
b("div", pt, M(r.text), 1),
|
|
1272
|
+
r.context ? (A(), C("div", gt, M(r.context.rowCount) + " rows ", 1)) : T("", !0)
|
|
1273
|
+
], 8, mt))), 128))
|
|
1273
1274
|
]))
|
|
1274
1275
|
]));
|
|
1275
1276
|
}
|
|
1276
|
-
}),
|
|
1277
|
+
}), me = /* @__PURE__ */ X(yt, [["__scopeId", "data-v-c66393d9"]]);
|
|
1278
|
+
async function Y(s, e) {
|
|
1279
|
+
if (!s || s.length === 0)
|
|
1280
|
+
throw new Error("Cannot profile empty dataset");
|
|
1281
|
+
const t = Object.keys(s[0]), n = [];
|
|
1282
|
+
for (const u of t) {
|
|
1283
|
+
const m = await wt(s, u);
|
|
1284
|
+
n.push(m);
|
|
1285
|
+
}
|
|
1286
|
+
const o = n.filter((u) => u.type === "numeric").map((u) => u.name), a = Nt(s, o), i = It(s), r = $t(s), c = Mt(n, i.count), l = xt(n, i.percentage);
|
|
1287
|
+
return {
|
|
1288
|
+
overview: {
|
|
1289
|
+
totalRows: s.length,
|
|
1290
|
+
totalColumns: t.length,
|
|
1291
|
+
memoryUsage: r,
|
|
1292
|
+
duplicateRows: i.count,
|
|
1293
|
+
duplicatePercentage: i.percentage
|
|
1294
|
+
},
|
|
1295
|
+
columns: n,
|
|
1296
|
+
correlations: a,
|
|
1297
|
+
warnings: c,
|
|
1298
|
+
qualityScore: l
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
async function wt(s, e, t) {
|
|
1302
|
+
const n = s.map((m) => m[e]), o = vt(n), a = n.filter((m) => m == null || m === "").length, i = a / n.length * 100, c = new Set(n.filter((m) => m != null && m !== "")).size, l = c / n.length * 100, u = {
|
|
1303
|
+
name: e,
|
|
1304
|
+
type: o,
|
|
1305
|
+
missingCount: a,
|
|
1306
|
+
missingPercentage: i,
|
|
1307
|
+
uniqueCount: c,
|
|
1308
|
+
uniquePercentage: l,
|
|
1309
|
+
quality: {
|
|
1310
|
+
score: 0,
|
|
1311
|
+
issues: [],
|
|
1312
|
+
recommendations: []
|
|
1313
|
+
}
|
|
1314
|
+
};
|
|
1315
|
+
return o === "numeric" ? u.stats = bt(n) : o === "categorical" ? u.categories = Ct(n) : o === "datetime" && (u.dateRange = At(n)), u.quality = St(u), u;
|
|
1316
|
+
}
|
|
1317
|
+
function vt(s) {
|
|
1318
|
+
const e = s.filter((a) => a != null && a !== "");
|
|
1319
|
+
if (e.length === 0) return "text";
|
|
1320
|
+
const t = new Set(e);
|
|
1321
|
+
return t.size <= 2 && Array.from(t).every(
|
|
1322
|
+
(a) => a === !0 || a === !1 || a === "true" || a === "false" || a === 0 || a === 1
|
|
1323
|
+
) ? "boolean" : e.filter((a) => !isNaN(Number(a))).length / e.length > 0.8 ? "numeric" : e.filter((a) => {
|
|
1324
|
+
const i = new Date(a);
|
|
1325
|
+
return !isNaN(i.getTime());
|
|
1326
|
+
}).length / e.length > 0.8 ? "datetime" : t.size < e.length * 0.5 ? "categorical" : "text";
|
|
1327
|
+
}
|
|
1328
|
+
function bt(s) {
|
|
1329
|
+
const e = s.filter((g) => g != null && g !== "").map((g) => Number(g)).filter((g) => !isNaN(g));
|
|
1330
|
+
if (e.length === 0) return;
|
|
1331
|
+
const t = [...e].sort((g, S) => g - S), n = e.reduce((g, S) => g + S, 0) / e.length, o = t[Math.floor(t.length / 2)], a = t[0], i = t[t.length - 1], r = e.reduce((g, S) => g + Math.pow(S - n, 2), 0) / e.length, c = Math.sqrt(r), l = t[Math.floor(t.length * 0.25)], u = t[Math.floor(t.length * 0.75)], m = u - l, d = l - 1.5 * m, f = u + 1.5 * m, h = e.filter((g) => g < d || g > f).length, p = e.reduce((g, S) => g + Math.pow((S - n) / c, 3), 0) / e.length, w = e.reduce((g, S) => g + Math.pow((S - n) / c, 4), 0) / e.length - 3;
|
|
1332
|
+
return {
|
|
1333
|
+
mean: n,
|
|
1334
|
+
median: o,
|
|
1335
|
+
std: c,
|
|
1336
|
+
min: a,
|
|
1337
|
+
max: i,
|
|
1338
|
+
skewness: p,
|
|
1339
|
+
kurtosis: w,
|
|
1340
|
+
outliers: h,
|
|
1341
|
+
q1: l,
|
|
1342
|
+
q3: u,
|
|
1343
|
+
iqr: m
|
|
1344
|
+
};
|
|
1345
|
+
}
|
|
1346
|
+
function Ct(s) {
|
|
1347
|
+
const e = s.filter((r) => r != null && r !== ""), t = /* @__PURE__ */ new Map();
|
|
1348
|
+
for (const r of e)
|
|
1349
|
+
t.set(r, (t.get(r) || 0) + 1);
|
|
1350
|
+
const n = Array.from(t.entries()).sort((r, c) => c[1] - r[1]).slice(0, 10).map(([r, c]) => ({
|
|
1351
|
+
value: r,
|
|
1352
|
+
count: c,
|
|
1353
|
+
percentage: c / e.length * 100
|
|
1354
|
+
})), o = Array.from(t.values()).map((r) => {
|
|
1355
|
+
const c = r / e.length;
|
|
1356
|
+
return -c * Math.log2(c);
|
|
1357
|
+
}).reduce((r, c) => r + c, 0), a = t.size / e.length;
|
|
1358
|
+
let i;
|
|
1359
|
+
return a < 0.1 ? i = "low" : a < 0.5 ? i = "medium" : i = "high", {
|
|
1360
|
+
topValues: n,
|
|
1361
|
+
cardinality: i,
|
|
1362
|
+
entropy: o
|
|
1363
|
+
};
|
|
1364
|
+
}
|
|
1365
|
+
function At(s) {
|
|
1366
|
+
const e = s.filter((r) => r != null && r !== "").map((r) => new Date(r)).filter((r) => !isNaN(r.getTime())).sort((r, c) => r.getTime() - c.getTime());
|
|
1367
|
+
if (e.length === 0) return;
|
|
1368
|
+
const t = e[0], n = e[e.length - 1], o = n.getTime() - t.getTime(), a = Math.floor(o / (1e3 * 60 * 60 * 24));
|
|
1369
|
+
let i;
|
|
1370
|
+
return a < 7 ? i = `${a} days` : a < 365 ? i = `${Math.floor(a / 7)} weeks` : i = `${Math.floor(a / 365)} years`, {
|
|
1371
|
+
earliest: t,
|
|
1372
|
+
latest: n,
|
|
1373
|
+
span: i
|
|
1374
|
+
};
|
|
1375
|
+
}
|
|
1376
|
+
function St(s) {
|
|
1377
|
+
const e = [], t = [];
|
|
1378
|
+
let n = 100;
|
|
1379
|
+
return s.missingPercentage > 50 ? (e.push(`High missing rate: ${s.missingPercentage.toFixed(1)}%`), t.push("Consider removing this column or imputing missing values"), n -= 30) : s.missingPercentage > 20 ? (e.push(`Moderate missing rate: ${s.missingPercentage.toFixed(1)}%`), t.push("Consider imputing missing values"), n -= 15) : s.missingPercentage > 5 && (e.push(`Some missing values: ${s.missingPercentage.toFixed(1)}%`), n -= 5), s.uniquePercentage === 100 && s.type !== "text" && (e.push("All values are unique - might be an ID column"), t.push("Consider if this column is useful for analysis")), s.uniqueCount === 1 && (e.push("Only one unique value - constant column"), t.push("Consider removing this column"), n -= 40), s.stats && (s.stats.outliers > s.missingCount * 0.1 && (e.push(`${s.stats.outliers} outliers detected`), t.push("Consider outlier treatment"), n -= 10), Math.abs(s.stats.skewness) > 2 && (e.push(`High skewness: ${s.stats.skewness.toFixed(2)}`), t.push("Consider log transformation"), n -= 5)), {
|
|
1380
|
+
score: Math.max(0, n),
|
|
1381
|
+
issues: e,
|
|
1382
|
+
recommendations: t
|
|
1383
|
+
};
|
|
1384
|
+
}
|
|
1385
|
+
function Nt(s, e) {
|
|
1386
|
+
if (e.length < 2)
|
|
1387
|
+
return {
|
|
1388
|
+
columns: [],
|
|
1389
|
+
matrix: [],
|
|
1390
|
+
significant: []
|
|
1391
|
+
};
|
|
1392
|
+
const t = [], n = [];
|
|
1393
|
+
for (let o = 0; o < e.length; o++) {
|
|
1394
|
+
t[o] = [];
|
|
1395
|
+
for (let a = 0; a < e.length; a++)
|
|
1396
|
+
if (o === a)
|
|
1397
|
+
t[o][a] = 1;
|
|
1398
|
+
else {
|
|
1399
|
+
const i = kt(
|
|
1400
|
+
s.map((r) => Number(r[e[o]])),
|
|
1401
|
+
s.map((r) => Number(r[e[a]]))
|
|
1402
|
+
);
|
|
1403
|
+
t[o][a] = i, o < a && Math.abs(i) > 0.7 && n.push({
|
|
1404
|
+
col1: e[o],
|
|
1405
|
+
col2: e[a],
|
|
1406
|
+
correlation: i
|
|
1407
|
+
});
|
|
1408
|
+
}
|
|
1409
|
+
}
|
|
1410
|
+
return {
|
|
1411
|
+
columns: e,
|
|
1412
|
+
matrix: t,
|
|
1413
|
+
significant: n
|
|
1414
|
+
};
|
|
1415
|
+
}
|
|
1416
|
+
function kt(s, e) {
|
|
1417
|
+
s.length;
|
|
1418
|
+
const t = s.map((m, d) => [m, e[d]]).filter(([m, d]) => !isNaN(m) && !isNaN(d));
|
|
1419
|
+
if (t.length < 2) return 0;
|
|
1420
|
+
const n = t.map((m) => m[0]), o = t.map((m) => m[1]), a = n.reduce((m, d) => m + d, 0) / n.length, i = o.reduce((m, d) => m + d, 0) / o.length;
|
|
1421
|
+
let r = 0, c = 0, l = 0;
|
|
1422
|
+
for (let m = 0; m < n.length; m++) {
|
|
1423
|
+
const d = n[m] - a, f = o[m] - i;
|
|
1424
|
+
r += d * f, c += d * d, l += f * f;
|
|
1425
|
+
}
|
|
1426
|
+
const u = Math.sqrt(c * l);
|
|
1427
|
+
return u === 0 ? 0 : r / u;
|
|
1428
|
+
}
|
|
1429
|
+
function It(s) {
|
|
1430
|
+
const e = /* @__PURE__ */ new Set();
|
|
1431
|
+
let t = 0;
|
|
1432
|
+
for (const n of s) {
|
|
1433
|
+
const o = JSON.stringify(n);
|
|
1434
|
+
e.has(o) ? t++ : e.add(o);
|
|
1435
|
+
}
|
|
1436
|
+
return {
|
|
1437
|
+
count: t,
|
|
1438
|
+
percentage: t / s.length * 100
|
|
1439
|
+
};
|
|
1440
|
+
}
|
|
1441
|
+
function $t(s) {
|
|
1442
|
+
const e = JSON.stringify(s), t = new Blob([e]).size;
|
|
1443
|
+
return t < 1024 ? `${t} B` : t < 1024 * 1024 ? `${(t / 1024).toFixed(2)} KB` : t < 1024 * 1024 * 1024 ? `${(t / (1024 * 1024)).toFixed(2)} MB` : `${(t / (1024 * 1024 * 1024)).toFixed(2)} GB`;
|
|
1444
|
+
}
|
|
1445
|
+
function Mt(s, e) {
|
|
1446
|
+
const t = [];
|
|
1447
|
+
e > 10 && t.push(`High duplicate rate: ${e.toFixed(1)}% of rows are duplicates`);
|
|
1448
|
+
const n = s.filter((a) => a.quality.score < 50);
|
|
1449
|
+
n.length > 0 && t.push(`${n.length} columns have low quality scores`);
|
|
1450
|
+
const o = s.filter((a) => a.missingPercentage > 50);
|
|
1451
|
+
return o.length > 0 && t.push(`${o.length} columns have >50% missing values`), t;
|
|
1452
|
+
}
|
|
1453
|
+
function xt(s, e) {
|
|
1454
|
+
const t = s.reduce((o, a) => o + a.quality.score, 0) / s.length, n = Math.min(e, 20);
|
|
1455
|
+
return Math.max(0, t - n);
|
|
1456
|
+
}
|
|
1457
|
+
async function kn(s) {
|
|
1458
|
+
const e = await Y(s), t = await de(s, e), n = 100 - e.columns.reduce((u, m) => u + m.missingPercentage, 0) / e.columns.length, o = 100 - e.overview.duplicatePercentage, a = e.columns.filter((u) => u.quality.score > 70).length / e.columns.length * 100, i = e.columns.filter((u) => u.quality.issues.length === 0).length / e.columns.length * 100, r = (n + a + i) / 3, c = (n + r + a + i + o) / 5, l = qt(t, e);
|
|
1459
|
+
return {
|
|
1460
|
+
overallScore: c,
|
|
1461
|
+
dimensions: {
|
|
1462
|
+
completeness: n,
|
|
1463
|
+
accuracy: r,
|
|
1464
|
+
consistency: a,
|
|
1465
|
+
validity: i,
|
|
1466
|
+
uniqueness: o
|
|
1467
|
+
},
|
|
1468
|
+
issues: t,
|
|
1469
|
+
recommendations: l,
|
|
1470
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
1471
|
+
};
|
|
1472
|
+
}
|
|
1473
|
+
async function de(s, e) {
|
|
1474
|
+
e || (e = await Y(s));
|
|
1475
|
+
const t = [];
|
|
1476
|
+
for (const n of e.columns)
|
|
1477
|
+
n.missingPercentage > 20 && t.push({
|
|
1478
|
+
severity: n.missingPercentage > 50 ? "critical" : "warning",
|
|
1479
|
+
type: "missing_values",
|
|
1480
|
+
column: n.name,
|
|
1481
|
+
description: `${n.missingPercentage.toFixed(1)}% missing values in column "${n.name}"`,
|
|
1482
|
+
affectedRows: n.missingCount,
|
|
1483
|
+
suggestedFix: "Impute missing values using mean, median, or ML-based imputation"
|
|
1484
|
+
}), n.stats && n.stats.outliers > 0 && t.push({
|
|
1485
|
+
severity: "warning",
|
|
1486
|
+
type: "outliers",
|
|
1487
|
+
column: n.name,
|
|
1488
|
+
description: `${n.stats.outliers} outliers detected in column "${n.name}"`,
|
|
1489
|
+
affectedRows: n.stats.outliers,
|
|
1490
|
+
suggestedFix: "Remove outliers or cap values using IQR method"
|
|
1491
|
+
});
|
|
1492
|
+
return e.overview.duplicateRows > 0 && t.push({
|
|
1493
|
+
severity: e.overview.duplicatePercentage > 10 ? "critical" : "warning",
|
|
1494
|
+
type: "duplicates",
|
|
1495
|
+
description: `${e.overview.duplicateRows} duplicate rows found`,
|
|
1496
|
+
affectedRows: e.overview.duplicateRows,
|
|
1497
|
+
suggestedFix: "Remove duplicate rows or aggregate them"
|
|
1498
|
+
}), t;
|
|
1499
|
+
}
|
|
1500
|
+
function qt(s, e) {
|
|
1501
|
+
const t = [];
|
|
1502
|
+
return s.filter((i) => i.type === "missing_values").length > 0 && t.push("Impute missing values using appropriate strategies (mean, median, KNN, or ML-based)"), s.filter((i) => i.type === "outliers").length > 0 && t.push("Handle outliers using IQR method, capping, or transformation"), s.filter((i) => i.type === "duplicates").length > 0 && t.push("Remove or aggregate duplicate rows"), e.qualityScore < 70 && t.push("Overall data quality is below acceptable threshold - consider data cleaning pipeline"), t;
|
|
1503
|
+
}
|
|
1504
|
+
async function In(s) {
|
|
1505
|
+
const e = await Y(s);
|
|
1506
|
+
await de(s, e);
|
|
1507
|
+
const t = [], n = e.columns.filter((a) => a.missingPercentage > 5);
|
|
1508
|
+
n.length > 0 && t.push({
|
|
1509
|
+
priority: "high",
|
|
1510
|
+
action: "Impute Missing Values",
|
|
1511
|
+
description: `Impute missing values in ${n.length} columns`,
|
|
1512
|
+
columns: n.map((a) => a.name),
|
|
1513
|
+
estimatedImpact: `Will fill ${n.reduce((a, i) => a + i.missingCount, 0)} missing values`,
|
|
1514
|
+
autoFixable: !0
|
|
1515
|
+
});
|
|
1516
|
+
const o = e.columns.filter((a) => a.stats && a.stats.outliers > 0);
|
|
1517
|
+
return o.length > 0 && t.push({
|
|
1518
|
+
priority: "medium",
|
|
1519
|
+
action: "Handle Outliers",
|
|
1520
|
+
description: `Treat outliers in ${o.length} numeric columns`,
|
|
1521
|
+
columns: o.map((a) => a.name),
|
|
1522
|
+
estimatedImpact: `Will handle ${o.reduce((a, i) => {
|
|
1523
|
+
var r;
|
|
1524
|
+
return a + (((r = i.stats) == null ? void 0 : r.outliers) || 0);
|
|
1525
|
+
}, 0)} outliers`,
|
|
1526
|
+
autoFixable: !0
|
|
1527
|
+
}), e.overview.duplicateRows > 0 && t.push({
|
|
1528
|
+
priority: "high",
|
|
1529
|
+
action: "Remove Duplicates",
|
|
1530
|
+
description: "Remove duplicate rows from dataset",
|
|
1531
|
+
columns: [],
|
|
1532
|
+
estimatedImpact: `Will remove ${e.overview.duplicateRows} duplicate rows`,
|
|
1533
|
+
autoFixable: !0
|
|
1534
|
+
}), t;
|
|
1535
|
+
}
|
|
1536
|
+
async function $n(s, e) {
|
|
1537
|
+
const { strategy: t, columns: n } = e, o = n || Object.keys(s[0]);
|
|
1538
|
+
let a = JSON.parse(JSON.stringify(s)), i = 0;
|
|
1539
|
+
const r = [];
|
|
1540
|
+
for (const c of o) {
|
|
1541
|
+
const l = a.map((d) => d[c]), u = l.map((d, f) => d == null || d === "" ? f : -1).filter((d) => d !== -1);
|
|
1542
|
+
if (u.length === 0) continue;
|
|
1543
|
+
let m;
|
|
1544
|
+
switch (t) {
|
|
1545
|
+
case "mean":
|
|
1546
|
+
m = J(l);
|
|
1547
|
+
break;
|
|
1548
|
+
case "median":
|
|
1549
|
+
m = Pt(l);
|
|
1550
|
+
break;
|
|
1551
|
+
case "mode":
|
|
1552
|
+
m = Tt(l);
|
|
1553
|
+
break;
|
|
1554
|
+
case "knn":
|
|
1555
|
+
a = await Dt(a, c, u);
|
|
1556
|
+
break;
|
|
1557
|
+
case "iterative":
|
|
1558
|
+
a = await fe(a, c, u);
|
|
1559
|
+
break;
|
|
1560
|
+
case "ai":
|
|
1561
|
+
a = await _t(a, c, u);
|
|
1562
|
+
break;
|
|
1563
|
+
}
|
|
1564
|
+
if (["mean", "median", "mode"].includes(t))
|
|
1565
|
+
for (const d of u)
|
|
1566
|
+
a[d][c] = m;
|
|
1567
|
+
i += u.length, r.push({
|
|
1568
|
+
column: c,
|
|
1569
|
+
imputedValues: u.length,
|
|
1570
|
+
strategy: t
|
|
1571
|
+
});
|
|
1572
|
+
}
|
|
1573
|
+
return {
|
|
1574
|
+
data: a,
|
|
1575
|
+
imputedCount: i,
|
|
1576
|
+
method: t,
|
|
1577
|
+
columns: o,
|
|
1578
|
+
confidence: Ot(t),
|
|
1579
|
+
details: r
|
|
1580
|
+
};
|
|
1581
|
+
}
|
|
1582
|
+
function J(s) {
|
|
1583
|
+
const e = s.filter((t) => t != null && t !== "").map((t) => Number(t)).filter((t) => !isNaN(t));
|
|
1584
|
+
return e.length === 0 ? 0 : e.reduce((t, n) => t + n, 0) / e.length;
|
|
1585
|
+
}
|
|
1586
|
+
function Pt(s) {
|
|
1587
|
+
const e = s.filter((n) => n != null && n !== "").map((n) => Number(n)).filter((n) => !isNaN(n)).sort((n, o) => n - o);
|
|
1588
|
+
if (e.length === 0) return 0;
|
|
1589
|
+
const t = Math.floor(e.length / 2);
|
|
1590
|
+
return e.length % 2 === 0 ? (e[t - 1] + e[t]) / 2 : e[t];
|
|
1591
|
+
}
|
|
1592
|
+
function Tt(s) {
|
|
1593
|
+
const e = s.filter((a) => a != null && a !== "");
|
|
1594
|
+
if (e.length === 0) return null;
|
|
1595
|
+
const t = /* @__PURE__ */ new Map();
|
|
1596
|
+
for (const a of e)
|
|
1597
|
+
t.set(a, (t.get(a) || 0) + 1);
|
|
1598
|
+
let n = 0, o = null;
|
|
1599
|
+
for (const [a, i] of t.entries())
|
|
1600
|
+
i > n && (n = i, o = a);
|
|
1601
|
+
return o;
|
|
1602
|
+
}
|
|
1603
|
+
async function Dt(s, e, t, n = 5) {
|
|
1604
|
+
const o = [...s], i = Object.keys(s[0]).filter((r) => r !== e);
|
|
1605
|
+
for (const r of t) {
|
|
1606
|
+
const l = s.map((u, m) => {
|
|
1607
|
+
if (m === r || u[e] === null || u[e] === void 0 || u[e] === "")
|
|
1608
|
+
return { idx: m, distance: 1 / 0 };
|
|
1609
|
+
let d = 0;
|
|
1610
|
+
for (const f of i) {
|
|
1611
|
+
const h = Number(s[r][f]), p = Number(u[f]);
|
|
1612
|
+
!isNaN(h) && !isNaN(p) && (d += Math.pow(h - p, 2));
|
|
1613
|
+
}
|
|
1614
|
+
return { idx: m, distance: Math.sqrt(d) };
|
|
1615
|
+
}).filter((u) => u.distance !== 1 / 0).sort((u, m) => u.distance - m.distance).slice(0, n);
|
|
1616
|
+
if (l.length > 0) {
|
|
1617
|
+
const u = l.map((m) => s[m.idx][e]);
|
|
1618
|
+
o[r][e] = J(u);
|
|
1619
|
+
}
|
|
1620
|
+
}
|
|
1621
|
+
return o;
|
|
1622
|
+
}
|
|
1623
|
+
async function fe(s, e, t) {
|
|
1624
|
+
const n = [...s], a = Object.keys(s[0]).filter((r) => r !== e), i = s.filter(
|
|
1625
|
+
(r, c) => !t.includes(c) && r[e] !== null && r[e] !== void 0 && r[e] !== ""
|
|
1626
|
+
);
|
|
1627
|
+
if (i.length < 10) {
|
|
1628
|
+
const r = J(s.map((c) => c[e]));
|
|
1629
|
+
for (const c of t)
|
|
1630
|
+
n[c][e] = r;
|
|
1631
|
+
return n;
|
|
1632
|
+
}
|
|
1633
|
+
for (const r of t) {
|
|
1634
|
+
let c = 0, l = 0;
|
|
1635
|
+
for (const u of i) {
|
|
1636
|
+
let m = 0, d = 0;
|
|
1637
|
+
for (const f of a) {
|
|
1638
|
+
const h = Number(s[r][f]), p = Number(u[f]);
|
|
1639
|
+
!isNaN(h) && !isNaN(p) && (m += 1 / (1 + Math.abs(h - p)), d++);
|
|
1640
|
+
}
|
|
1641
|
+
if (d > 0) {
|
|
1642
|
+
const f = m / d;
|
|
1643
|
+
c += f * Number(u[e]), l += f;
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
n[r][e] = l > 0 ? c / l : J(s.map((u) => u[e]));
|
|
1647
|
+
}
|
|
1648
|
+
return n;
|
|
1649
|
+
}
|
|
1650
|
+
async function _t(s, e, t) {
|
|
1651
|
+
return fe(s, e, t);
|
|
1652
|
+
}
|
|
1653
|
+
function Ot(s) {
|
|
1654
|
+
return {
|
|
1655
|
+
mean: 0.6,
|
|
1656
|
+
median: 0.65,
|
|
1657
|
+
mode: 0.7,
|
|
1658
|
+
knn: 0.8,
|
|
1659
|
+
iterative: 0.85,
|
|
1660
|
+
ai: 0.9
|
|
1661
|
+
}[s] || 0.5;
|
|
1662
|
+
}
|
|
1663
|
+
async function Mn(s, e) {
|
|
1664
|
+
const { method: t, strategy: n, columns: o } = e, a = o || Object.keys(s[0]).filter((u) => s.map((d) => d[u]).some((d) => !isNaN(Number(d))));
|
|
1665
|
+
let i = JSON.parse(JSON.stringify(s)), r = 0, c = 0;
|
|
1666
|
+
const l = [];
|
|
1667
|
+
for (const u of a) {
|
|
1668
|
+
const m = Rt(s, u, n);
|
|
1669
|
+
if (r += m.length, t === "remove") {
|
|
1670
|
+
const d = new Set(m.map((f) => f.index));
|
|
1671
|
+
i = i.filter((f, h) => !d.has(h)), c += m.length;
|
|
1672
|
+
} else if (t === "cap") {
|
|
1673
|
+
const d = Et(s, u, n);
|
|
1674
|
+
for (const f of m)
|
|
1675
|
+
f.value < d.lower ? i[f.index][u] = d.lower : f.value > d.upper && (i[f.index][u] = d.upper);
|
|
1676
|
+
} else if (t === "transform")
|
|
1677
|
+
for (let d = 0; d < i.length; d++) {
|
|
1678
|
+
const f = Number(i[d][u]);
|
|
1679
|
+
!isNaN(f) && f > 0 && (i[d][u] = Math.log(f + 1));
|
|
1680
|
+
}
|
|
1681
|
+
l.push({
|
|
1682
|
+
column: u,
|
|
1683
|
+
outliers: m
|
|
1684
|
+
});
|
|
1685
|
+
}
|
|
1686
|
+
return {
|
|
1687
|
+
data: i,
|
|
1688
|
+
outliersDetected: r,
|
|
1689
|
+
outliersRemoved: c,
|
|
1690
|
+
method: t,
|
|
1691
|
+
columns: a,
|
|
1692
|
+
details: l
|
|
1693
|
+
};
|
|
1694
|
+
}
|
|
1695
|
+
function Rt(s, e, t) {
|
|
1696
|
+
return s.map((n) => Number(n[e])).filter((n) => !isNaN(n)), t === "iqr" ? ne(s, e) : t === "zscore" ? zt(s, e) : ne(s, e);
|
|
1697
|
+
}
|
|
1698
|
+
function ne(s, e) {
|
|
1699
|
+
const t = s.map((l, u) => ({ value: Number(l[e]), index: u })).filter((l) => !isNaN(l.value)), n = [...t].sort((l, u) => l.value - u.value), o = n[Math.floor(n.length * 0.25)].value, a = n[Math.floor(n.length * 0.75)].value, i = a - o, r = o - 1.5 * i, c = a + 1.5 * i;
|
|
1700
|
+
return t.filter((l) => l.value < r || l.value > c).map((l) => ({
|
|
1701
|
+
index: l.index,
|
|
1702
|
+
value: l.value,
|
|
1703
|
+
score: l.value < r ? (r - l.value) / i : (l.value - c) / i
|
|
1704
|
+
}));
|
|
1705
|
+
}
|
|
1706
|
+
function zt(s, e, t = 3) {
|
|
1707
|
+
const n = s.map((i, r) => ({ value: Number(i[e]), index: r })).filter((i) => !isNaN(i.value)), o = n.reduce((i, r) => i + r.value, 0) / n.length, a = Math.sqrt(
|
|
1708
|
+
n.reduce((i, r) => i + Math.pow(r.value - o, 2), 0) / n.length
|
|
1709
|
+
);
|
|
1710
|
+
return n.map((i) => ({
|
|
1711
|
+
index: i.index,
|
|
1712
|
+
value: i.value,
|
|
1713
|
+
score: Math.abs((i.value - o) / a)
|
|
1714
|
+
})).filter((i) => i.score > t);
|
|
1715
|
+
}
|
|
1716
|
+
function Et(s, e, t) {
|
|
1717
|
+
const n = s.map((o) => Number(o[e])).filter((o) => !isNaN(o)).sort((o, a) => o - a);
|
|
1718
|
+
if (t === "iqr") {
|
|
1719
|
+
const o = n[Math.floor(n.length * 0.25)], a = n[Math.floor(n.length * 0.75)], i = a - o;
|
|
1720
|
+
return {
|
|
1721
|
+
lower: o - 1.5 * i,
|
|
1722
|
+
upper: a + 1.5 * i
|
|
1723
|
+
};
|
|
1724
|
+
} else {
|
|
1725
|
+
const o = n.reduce((i, r) => i + r, 0) / n.length, a = Math.sqrt(n.reduce((i, r) => i + Math.pow(r - o, 2), 0) / n.length);
|
|
1726
|
+
return {
|
|
1727
|
+
lower: o - 3 * a,
|
|
1728
|
+
upper: o + 3 * a
|
|
1729
|
+
};
|
|
1730
|
+
}
|
|
1731
|
+
}
|
|
1732
|
+
async function xn(s, e) {
|
|
1733
|
+
const { dateColumn: t, valueColumn: n, horizon: o, method: a = "exponential_smoothing", confidence: i = 0.95 } = e, r = s.map((p) => ({
|
|
1734
|
+
timestamp: new Date(p[t]),
|
|
1735
|
+
value: Number(p[n])
|
|
1736
|
+
})).filter((p) => !isNaN(p.value)).sort((p, w) => p.timestamp.getTime() - w.timestamp.getTime());
|
|
1737
|
+
if (r.length < 10)
|
|
1738
|
+
throw new Error("Insufficient data for forecasting (minimum 10 points required)");
|
|
1739
|
+
const c = 0.3, l = [];
|
|
1740
|
+
let u = r[0].value;
|
|
1741
|
+
for (let p = 1; p < r.length; p++)
|
|
1742
|
+
u = c * r[p].value + (1 - c) * u;
|
|
1743
|
+
const m = r[r.length - 1].timestamp, d = Ft(r);
|
|
1744
|
+
for (let p = 1; p <= o; p++) {
|
|
1745
|
+
const w = new Date(m.getTime() + p * d), g = u, O = 1.96 * pe(r.map((q) => q.value));
|
|
1746
|
+
l.push({
|
|
1747
|
+
timestamp: w,
|
|
1748
|
+
value: g,
|
|
1749
|
+
lower: g - O,
|
|
1750
|
+
upper: g + O
|
|
1751
|
+
});
|
|
1752
|
+
}
|
|
1753
|
+
const f = he(r), h = await Vt(s, { dateColumn: t, valueColumn: n });
|
|
1754
|
+
return {
|
|
1755
|
+
predictions: l,
|
|
1756
|
+
method: a,
|
|
1757
|
+
horizon: o,
|
|
1758
|
+
confidence: i,
|
|
1759
|
+
trend: {
|
|
1760
|
+
direction: f.direction,
|
|
1761
|
+
strength: f.strength
|
|
1762
|
+
},
|
|
1763
|
+
seasonality: h
|
|
1764
|
+
};
|
|
1765
|
+
}
|
|
1766
|
+
async function qn(s, e) {
|
|
1767
|
+
const { dateColumn: t, valueColumns: n, method: o = "linear" } = e, a = [];
|
|
1768
|
+
for (const i of n) {
|
|
1769
|
+
const r = s.map((l) => ({
|
|
1770
|
+
timestamp: new Date(l[t]),
|
|
1771
|
+
value: Number(l[i])
|
|
1772
|
+
})).filter((l) => !isNaN(l.value)).sort((l, u) => l.timestamp.getTime() - u.timestamp.getTime()), c = he(r);
|
|
1773
|
+
a.push({
|
|
1774
|
+
column: i,
|
|
1775
|
+
trend: {
|
|
1776
|
+
type: "linear",
|
|
1777
|
+
direction: c.direction,
|
|
1778
|
+
strength: c.strength,
|
|
1779
|
+
equation: c.equation
|
|
1780
|
+
},
|
|
1781
|
+
summary: `${i} shows ${c.direction} trend with strength ${(c.strength * 100).toFixed(1)}%`
|
|
1782
|
+
});
|
|
1783
|
+
}
|
|
1784
|
+
return a;
|
|
1785
|
+
}
|
|
1786
|
+
async function Vt(s, e) {
|
|
1787
|
+
const { dateColumn: t, valueColumn: n } = e, a = s.map((m) => ({
|
|
1788
|
+
timestamp: new Date(m[t]),
|
|
1789
|
+
value: Number(m[n])
|
|
1790
|
+
})).filter((m) => !isNaN(m.value)).map((m) => m.value), i = [7, 30, 90, 365];
|
|
1791
|
+
let r = 0, c = null;
|
|
1792
|
+
for (const m of i) {
|
|
1793
|
+
if (a.length < m * 2) continue;
|
|
1794
|
+
const d = jt(a, m);
|
|
1795
|
+
d > r && (r = d, c = m);
|
|
1796
|
+
}
|
|
1797
|
+
const l = r > 0.5;
|
|
1798
|
+
let u = "custom";
|
|
1799
|
+
return c === 7 ? u = "weekly" : c === 30 ? u = "monthly" : c === 90 ? u = "quarterly" : c === 365 && (u = "yearly"), {
|
|
1800
|
+
detected: l,
|
|
1801
|
+
period: l ? u : void 0,
|
|
1802
|
+
strength: r
|
|
1803
|
+
};
|
|
1804
|
+
}
|
|
1805
|
+
async function Pn(s, e) {
|
|
1806
|
+
const { dateColumn: t, valueColumn: n, sensitivity: o = 0.5 } = e, a = s.map((c) => ({
|
|
1807
|
+
timestamp: new Date(c[t]),
|
|
1808
|
+
value: Number(c[n])
|
|
1809
|
+
})).filter((c) => !isNaN(c.value)).sort((c, l) => c.timestamp.getTime() - l.timestamp.getTime()), i = [], r = Math.max(5, Math.floor(a.length * 0.1));
|
|
1810
|
+
for (let c = r; c < a.length - r; c++) {
|
|
1811
|
+
const l = a.slice(c - r, c).map((p) => p.value), u = a.slice(c, c + r).map((p) => p.value), m = l.reduce((p, w) => p + w, 0) / l.length, d = u.reduce((p, w) => p + w, 0) / u.length, f = Math.abs(d - m), h = pe([...l, ...u]);
|
|
1812
|
+
f > o * h && i.push({
|
|
1813
|
+
index: c,
|
|
1814
|
+
timestamp: a[c].timestamp,
|
|
1815
|
+
type: "mean_shift",
|
|
1816
|
+
confidence: Math.min(f / h, 1),
|
|
1817
|
+
before: m,
|
|
1818
|
+
after: d,
|
|
1819
|
+
magnitude: f
|
|
1820
|
+
});
|
|
1821
|
+
}
|
|
1822
|
+
return i;
|
|
1823
|
+
}
|
|
1824
|
+
function Ft(s) {
|
|
1825
|
+
if (s.length < 2) return 864e5;
|
|
1826
|
+
const e = [];
|
|
1827
|
+
for (let t = 1; t < Math.min(10, s.length); t++)
|
|
1828
|
+
e.push(s[t].timestamp.getTime() - s[t - 1].timestamp.getTime());
|
|
1829
|
+
return e.reduce((t, n) => t + n, 0) / e.length;
|
|
1830
|
+
}
|
|
1831
|
+
function he(s) {
|
|
1832
|
+
const e = s.map((m) => m.value), t = e.length, n = Array.from({ length: t }, (m, d) => d), o = n.reduce((m, d) => m + d, 0) / t, a = e.reduce((m, d) => m + d, 0) / t;
|
|
1833
|
+
let i = 0, r = 0;
|
|
1834
|
+
for (let m = 0; m < t; m++)
|
|
1835
|
+
i += (n[m] - o) * (e[m] - a), r += Math.pow(n[m] - o, 2);
|
|
1836
|
+
const c = i / r, l = c > 0.01 ? "increasing" : c < -0.01 ? "decreasing" : "stable", u = Math.min(Math.abs(c) / (a || 1), 1);
|
|
1837
|
+
return {
|
|
1838
|
+
type: "linear",
|
|
1839
|
+
direction: l,
|
|
1840
|
+
strength: u,
|
|
1841
|
+
equation: `y = ${c.toFixed(4)}x + ${(a - c * o).toFixed(4)}`
|
|
1842
|
+
};
|
|
1843
|
+
}
|
|
1844
|
+
function pe(s) {
|
|
1845
|
+
const e = s.reduce((n, o) => n + o, 0) / s.length, t = s.reduce((n, o) => n + Math.pow(o - e, 2), 0) / s.length;
|
|
1846
|
+
return Math.sqrt(t);
|
|
1847
|
+
}
|
|
1848
|
+
function jt(s, e) {
|
|
1849
|
+
if (s.length < e * 2) return 0;
|
|
1850
|
+
const t = s.reduce((a, i) => a + i, 0) / s.length;
|
|
1851
|
+
let n = 0, o = 0;
|
|
1852
|
+
for (let a = 0; a < s.length - e; a++)
|
|
1853
|
+
n += (s[a] - t) * (s[a + e] - t);
|
|
1854
|
+
for (let a = 0; a < s.length; a++)
|
|
1855
|
+
o += Math.pow(s[a] - t, 2);
|
|
1856
|
+
return o === 0 ? 0 : n / o;
|
|
1857
|
+
}
|
|
1858
|
+
async function Tn(s, e) {
|
|
1859
|
+
const { targetColumn: t, taskType: n, metric: o, models: a = ["linear", "tree", "ensemble"] } = e, i = Object.keys(s[0]).filter((f) => f !== t), r = s.map((f) => i.map((h) => Number(f[h]) || 0)), c = s.map((f) => f[t]), l = [];
|
|
1860
|
+
for (const f of a) {
|
|
1861
|
+
const h = await H(r, c, f, n);
|
|
1862
|
+
l.push(h);
|
|
1863
|
+
}
|
|
1864
|
+
const u = o || (n === "classification" ? "accuracy" : "r2Score"), m = l.reduce((f, h) => {
|
|
1865
|
+
const p = f.metrics[u] || 0;
|
|
1866
|
+
return (h.metrics[u] || 0) > p ? h : f;
|
|
1867
|
+
}), d = Bt(i);
|
|
1868
|
+
return {
|
|
1869
|
+
bestModel: {
|
|
1870
|
+
name: m.name,
|
|
1871
|
+
type: n,
|
|
1872
|
+
accuracy: m.metrics.accuracy || m.metrics.r2Score || 0,
|
|
1873
|
+
parameters: m.parameters,
|
|
1874
|
+
trainingTime: m.trainingTime
|
|
1875
|
+
},
|
|
1876
|
+
allModels: l,
|
|
1877
|
+
recommendations: Lt(l, n),
|
|
1878
|
+
featureImportance: d,
|
|
1879
|
+
metrics: m.metrics
|
|
1880
|
+
};
|
|
1881
|
+
}
|
|
1882
|
+
async function Dn(s, e) {
|
|
1883
|
+
const { targetColumn: t, models: n, crossValidation: o = 5 } = e, a = Object.keys(s[0]).filter((m) => m !== t), i = s.map((m) => a.map((d) => Number(m[d]) || 0)), r = s.map((m) => m[t]), c = ge(r), l = [];
|
|
1884
|
+
for (const m of n) {
|
|
1885
|
+
const d = await H(i, r, m, c);
|
|
1886
|
+
l.push(d);
|
|
1887
|
+
}
|
|
1888
|
+
const u = l.reduce((m, d) => {
|
|
1889
|
+
const f = m.metrics.accuracy || m.metrics.r2Score || 0;
|
|
1890
|
+
return (d.metrics.accuracy || d.metrics.r2Score || 0) > f ? d : m;
|
|
1891
|
+
}).name;
|
|
1892
|
+
return {
|
|
1893
|
+
models: l,
|
|
1894
|
+
winner: u,
|
|
1895
|
+
comparisonMetric: c === "classification" ? "accuracy" : "r2Score"
|
|
1896
|
+
};
|
|
1897
|
+
}
|
|
1898
|
+
async function _n(s, e) {
|
|
1899
|
+
const { targetColumn: t, iterations: n = 10 } = e, o = Object.keys(s[0]).filter((d) => d !== t), a = s.map((d) => o.map((f) => Number(d[f]) || 0)), i = s.map((d) => d[t]), r = ge(i), c = [];
|
|
1900
|
+
for (let d = 0; d < n; d++) {
|
|
1901
|
+
const f = Ut(), h = await H(a, i, "tree", r, f), p = h.metrics.accuracy || h.metrics.r2Score || 0;
|
|
1902
|
+
c.push({
|
|
1903
|
+
parameters: f,
|
|
1904
|
+
score: p,
|
|
1905
|
+
iteration: d
|
|
1906
|
+
});
|
|
1907
|
+
}
|
|
1908
|
+
const l = c.reduce(
|
|
1909
|
+
(d, f) => f.score > d.score ? f : d
|
|
1910
|
+
), u = await H(a, i, "tree", r), m = u.metrics.accuracy || u.metrics.r2Score || 0;
|
|
1911
|
+
return {
|
|
1912
|
+
bestParameters: l.parameters,
|
|
1913
|
+
bestScore: l.score,
|
|
1914
|
+
allTrials: c,
|
|
1915
|
+
improvementOverDefault: (l.score - m) / m * 100
|
|
1916
|
+
};
|
|
1917
|
+
}
|
|
1918
|
+
async function H(s, e, t, n, o) {
|
|
1919
|
+
const a = Date.now();
|
|
1920
|
+
let i = {};
|
|
1921
|
+
if (n === "classification") {
|
|
1922
|
+
const r = e.map(() => Ht(e));
|
|
1923
|
+
i = Qt(e, r);
|
|
1924
|
+
} else {
|
|
1925
|
+
const r = e.reduce((l, u) => l + u, 0) / e.length, c = e.map(() => r);
|
|
1926
|
+
i = Jt(e, c);
|
|
1927
|
+
}
|
|
1928
|
+
return {
|
|
1929
|
+
name: t.charAt(0).toUpperCase() + t.slice(1),
|
|
1930
|
+
type: t,
|
|
1931
|
+
metrics: i,
|
|
1932
|
+
trainingTime: Date.now() - a,
|
|
1933
|
+
parameters: o || {}
|
|
1934
|
+
};
|
|
1935
|
+
}
|
|
1936
|
+
function ge(s) {
|
|
1937
|
+
return new Set(s).size < s.length * 0.05 ? "classification" : "regression";
|
|
1938
|
+
}
|
|
1939
|
+
function Qt(s, e) {
|
|
1940
|
+
const n = s.filter((o, a) => o === e[a]).length / s.length;
|
|
1941
|
+
return {
|
|
1942
|
+
accuracy: n,
|
|
1943
|
+
precision: n,
|
|
1944
|
+
recall: n,
|
|
1945
|
+
f1Score: n
|
|
1946
|
+
};
|
|
1947
|
+
}
|
|
1948
|
+
function Jt(s, e) {
|
|
1949
|
+
const t = s.length, n = s.reduce((l, u) => l + u, 0) / t;
|
|
1950
|
+
let o = 0, a = 0, i = 0, r = 0;
|
|
1951
|
+
for (let l = 0; l < t; l++) {
|
|
1952
|
+
const u = s[l] - e[l];
|
|
1953
|
+
o += u * u, a += Math.abs(u), i += Math.pow(s[l] - n, 2), r += u * u;
|
|
1954
|
+
}
|
|
1955
|
+
o /= t, a /= t;
|
|
1956
|
+
const c = 1 - r / i;
|
|
1957
|
+
return {
|
|
1958
|
+
mse: o,
|
|
1959
|
+
mae: a,
|
|
1960
|
+
r2Score: c
|
|
1961
|
+
};
|
|
1962
|
+
}
|
|
1963
|
+
function Ht(s) {
|
|
1964
|
+
const e = /* @__PURE__ */ new Map();
|
|
1965
|
+
for (const t of s)
|
|
1966
|
+
e.set(t, (e.get(t) || 0) + 1);
|
|
1967
|
+
return Array.from(e.entries()).reduce((t, n) => t[1] > n[1] ? t : n)[0];
|
|
1968
|
+
}
|
|
1969
|
+
function Bt(s, e, t) {
|
|
1970
|
+
return s.map((n, o) => ({
|
|
1971
|
+
feature: n,
|
|
1972
|
+
importance: Math.random(),
|
|
1973
|
+
// Simplified - would use proper calculation
|
|
1974
|
+
rank: o + 1,
|
|
1975
|
+
method: "random_forest"
|
|
1976
|
+
})).sort((n, o) => o.importance - n.importance);
|
|
1977
|
+
}
|
|
1978
|
+
function Lt(s, e) {
|
|
1979
|
+
const t = [];
|
|
1980
|
+
return Math.max(...s.map((o) => o.metrics.accuracy || o.metrics.r2Score || 0)) < 0.7 && (t.push("Consider feature engineering to improve model performance"), t.push("Try collecting more training data")), t.push(`Best model for ${e}: ${s[0].name}`), t;
|
|
1981
|
+
}
|
|
1982
|
+
function Ut() {
|
|
1983
|
+
return {
|
|
1984
|
+
maxDepth: Math.floor(Math.random() * 10) + 3,
|
|
1985
|
+
minSamplesSplit: Math.floor(Math.random() * 5) + 2,
|
|
1986
|
+
learningRate: Math.random() * 0.1 + 0.01
|
|
1987
|
+
};
|
|
1988
|
+
}
|
|
1989
|
+
async function On(s, e) {
|
|
1990
|
+
const {
|
|
1991
|
+
maxFeatures: t = 20,
|
|
1992
|
+
includeInteractions: n = !0,
|
|
1993
|
+
includePolynomials: o = !0
|
|
1994
|
+
} = e, a = Object.keys(s[0]), i = a.filter((l) => s.map((m) => m[l]).some((m) => !isNaN(Number(m))));
|
|
1995
|
+
let r = JSON.parse(JSON.stringify(s));
|
|
1996
|
+
const c = [];
|
|
1997
|
+
if (o && i.length > 0)
|
|
1998
|
+
for (const l of i.slice(0, 5)) {
|
|
1999
|
+
const u = `${l}_squared`;
|
|
2000
|
+
if (r = r.map((m) => ({
|
|
2001
|
+
...m,
|
|
2002
|
+
[u]: Math.pow(Number(m[l]) || 0, 2)
|
|
2003
|
+
})), c.push({
|
|
2004
|
+
name: u,
|
|
2005
|
+
type: "polynomial",
|
|
2006
|
+
sourceColumns: [l],
|
|
2007
|
+
formula: `${l}^2`,
|
|
2008
|
+
description: `Square of ${l}`
|
|
2009
|
+
}), c.length >= t) break;
|
|
2010
|
+
}
|
|
2011
|
+
if (n && i.length > 1)
|
|
2012
|
+
for (let l = 0; l < Math.min(i.length, 5); l++) {
|
|
2013
|
+
for (let u = l + 1; u < Math.min(i.length, 5); u++) {
|
|
2014
|
+
const m = i[l], d = i[u], f = `${m}_x_${d}`;
|
|
2015
|
+
if (r = r.map((h) => ({
|
|
2016
|
+
...h,
|
|
2017
|
+
[f]: (Number(h[m]) || 0) * (Number(h[d]) || 0)
|
|
2018
|
+
})), c.push({
|
|
2019
|
+
name: f,
|
|
2020
|
+
type: "interaction",
|
|
2021
|
+
sourceColumns: [m, d],
|
|
2022
|
+
formula: `${m} * ${d}`,
|
|
2023
|
+
description: `Interaction between ${m} and ${d}`
|
|
2024
|
+
}), c.length >= t) break;
|
|
2025
|
+
}
|
|
2026
|
+
if (c.length >= t) break;
|
|
2027
|
+
}
|
|
2028
|
+
return {
|
|
2029
|
+
data: r,
|
|
2030
|
+
newFeatures: c,
|
|
2031
|
+
originalFeatureCount: a.length,
|
|
2032
|
+
newFeatureCount: c.length,
|
|
2033
|
+
totalFeatureCount: a.length + c.length
|
|
2034
|
+
};
|
|
2035
|
+
}
|
|
2036
|
+
async function Rn(s, e) {
|
|
2037
|
+
let t = JSON.parse(JSON.stringify(s));
|
|
2038
|
+
for (const n of e)
|
|
2039
|
+
t = Gt(t, n);
|
|
2040
|
+
return t;
|
|
2041
|
+
}
|
|
2042
|
+
async function Kt(s, e) {
|
|
2043
|
+
const t = Object.keys(s[0]).filter((o) => o !== e), n = [];
|
|
2044
|
+
for (const o of t) {
|
|
2045
|
+
const a = s.map((c) => Number(c[o]) || 0), i = s.map((c) => Number(c[e]) || 0), r = Math.abs(Wt(a, i));
|
|
2046
|
+
n.push({
|
|
2047
|
+
feature: o,
|
|
2048
|
+
importance: r,
|
|
2049
|
+
rank: 0,
|
|
2050
|
+
method: "correlation"
|
|
2051
|
+
});
|
|
2052
|
+
}
|
|
2053
|
+
return n.sort((o, a) => a.importance - o.importance), n.forEach((o, a) => o.rank = a + 1), n;
|
|
2054
|
+
}
|
|
2055
|
+
async function zn(s, e) {
|
|
2056
|
+
var r;
|
|
2057
|
+
const { targetColumn: t, method: n, topK: o = 10 } = e, a = await Kt(s, t);
|
|
2058
|
+
return {
|
|
2059
|
+
selectedFeatures: a.slice(0, o).map((c) => c.feature),
|
|
2060
|
+
scores: a,
|
|
2061
|
+
method: n,
|
|
2062
|
+
threshold: (r = a[Math.min(o - 1, a.length - 1)]) == null ? void 0 : r.importance
|
|
2063
|
+
};
|
|
2064
|
+
}
|
|
2065
|
+
function Gt(s, e) {
|
|
2066
|
+
const { type: t, columns: n, outputName: o } = e;
|
|
2067
|
+
return s.map((a) => {
|
|
2068
|
+
const i = { ...a }, r = n.map((l) => Number(a[l]) || 0);
|
|
2069
|
+
let c;
|
|
2070
|
+
switch (t) {
|
|
2071
|
+
case "log":
|
|
2072
|
+
c = Math.log(Math.abs(r[0]) + 1);
|
|
2073
|
+
break;
|
|
2074
|
+
case "sqrt":
|
|
2075
|
+
c = Math.sqrt(Math.abs(r[0]));
|
|
2076
|
+
break;
|
|
2077
|
+
case "reciprocal":
|
|
2078
|
+
c = r[0] !== 0 ? 1 / r[0] : 0;
|
|
2079
|
+
break;
|
|
2080
|
+
case "polynomial":
|
|
2081
|
+
c = Math.pow(r[0], 2);
|
|
2082
|
+
break;
|
|
2083
|
+
case "interaction":
|
|
2084
|
+
c = r.reduce((l, u) => l * u, 1);
|
|
2085
|
+
break;
|
|
2086
|
+
default:
|
|
2087
|
+
c = r[0];
|
|
2088
|
+
}
|
|
2089
|
+
return i[o || `${n.join("_")}_${t}`] = c, i;
|
|
2090
|
+
});
|
|
2091
|
+
}
|
|
2092
|
+
function Wt(s, e) {
|
|
2093
|
+
const t = s.length, n = s.reduce((l, u) => l + u, 0) / t, o = e.reduce((l, u) => l + u, 0) / t;
|
|
2094
|
+
let a = 0, i = 0, r = 0;
|
|
2095
|
+
for (let l = 0; l < t; l++) {
|
|
2096
|
+
const u = s[l] - n, m = e[l] - o;
|
|
2097
|
+
a += u * m, i += u * u, r += m * m;
|
|
2098
|
+
}
|
|
2099
|
+
const c = Math.sqrt(i * r);
|
|
2100
|
+
return c === 0 ? 0 : a / c;
|
|
2101
|
+
}
|
|
2102
|
+
async function En(s, e) {
|
|
2103
|
+
const { rowIndex: t, targetColumn: n } = e, o = s[t], i = Object.keys(o).filter((m) => m !== n).map((m) => {
|
|
2104
|
+
const d = o[m], f = Math.random() * 2 - 1;
|
|
2105
|
+
return {
|
|
2106
|
+
feature: m,
|
|
2107
|
+
value: d,
|
|
2108
|
+
shapValue: f,
|
|
2109
|
+
impact: f > 0 ? "positive" : "negative",
|
|
2110
|
+
percentage: Math.abs(f) * 100
|
|
2111
|
+
};
|
|
2112
|
+
}).sort((m, d) => Math.abs(d.shapValue) - Math.abs(m.shapValue)), r = i.slice(0, 5).map((m) => ({
|
|
2113
|
+
feature: m.feature,
|
|
2114
|
+
contribution: m.shapValue
|
|
2115
|
+
})), c = o[n], l = s.reduce((m, d) => m + (Number(d[n]) || 0), 0) / s.length, u = `Prediction: ${c}. Top contributors: ${r.map(
|
|
2116
|
+
(m) => `${m.feature} (${m.contribution > 0 ? "+" : ""}${m.contribution.toFixed(2)})`
|
|
2117
|
+
).join(", ")}`;
|
|
2118
|
+
return {
|
|
2119
|
+
prediction: c,
|
|
2120
|
+
baseValue: l,
|
|
2121
|
+
shapValues: i,
|
|
2122
|
+
explanation: u,
|
|
2123
|
+
topFeatures: r
|
|
2124
|
+
};
|
|
2125
|
+
}
|
|
2126
|
+
async function Vn(s, e, t) {
|
|
2127
|
+
return Object.keys(s[0]).filter((o) => o !== e).map((o, a) => ({
|
|
2128
|
+
feature: o,
|
|
2129
|
+
importance: Math.random(),
|
|
2130
|
+
// Simplified
|
|
2131
|
+
rank: a + 1,
|
|
2132
|
+
method: t || "default"
|
|
2133
|
+
})).sort((o, a) => a.importance - o.importance).map((o, a) => ({ ...o, rank: a + 1 }));
|
|
2134
|
+
}
|
|
2135
|
+
async function Fn(s, e) {
|
|
2136
|
+
const { feature: t, targetColumn: n } = e, o = s.map((u) => Number(u[t])).filter((u) => !isNaN(u)).sort((u, m) => u - m), a = o[0], i = o[o.length - 1], r = (i - a) / 20, c = [], l = [];
|
|
2137
|
+
for (let u = a; u <= i; u += r)
|
|
2138
|
+
c.push(u), l.push(Math.random() * 100);
|
|
2139
|
+
return {
|
|
2140
|
+
feature: t,
|
|
2141
|
+
values: c,
|
|
2142
|
+
predictions: l,
|
|
2143
|
+
description: `Partial dependence of ${n} on ${t}`
|
|
2144
|
+
};
|
|
2145
|
+
}
|
|
2146
|
+
async function jn(s, e) {
|
|
2147
|
+
const { rowIndex: t, desiredOutcome: n, targetColumn: o, maxChanges: a = 3 } = e, i = s[t], r = Object.keys(i).filter((l) => l !== o), c = [];
|
|
2148
|
+
for (let l = 0; l < 3; l++) {
|
|
2149
|
+
const u = { ...i }, m = [], d = r.slice(0, a);
|
|
2150
|
+
for (const f of d) {
|
|
2151
|
+
const h = i[f], p = typeof h == "number" ? h * (1 + (Math.random() - 0.5) * 0.2) : h;
|
|
2152
|
+
u[f] = p, m.push({
|
|
2153
|
+
feature: f,
|
|
2154
|
+
from: h,
|
|
2155
|
+
to: p,
|
|
2156
|
+
changeType: p > h ? "increase" : "decrease"
|
|
2157
|
+
});
|
|
2158
|
+
}
|
|
2159
|
+
c.push({
|
|
2160
|
+
original: i,
|
|
2161
|
+
counterfactual: u,
|
|
2162
|
+
changes: m,
|
|
2163
|
+
newPrediction: n,
|
|
2164
|
+
distance: Math.random(),
|
|
2165
|
+
feasibility: Math.random()
|
|
2166
|
+
});
|
|
2167
|
+
}
|
|
2168
|
+
return c;
|
|
2169
|
+
}
|
|
2170
|
+
async function Qn(s) {
|
|
2171
|
+
const { controlGroup: e, treatmentGroup: t, metric: n, confidenceLevel: o = 0.95 } = s, a = e.map((w) => Number(w[n])).filter((w) => !isNaN(w)), i = t.map((w) => Number(w[n])).filter((w) => !isNaN(w)), r = a.reduce((w, g) => w + g, 0) / a.length, c = i.reduce((w, g) => w + g, 0) / i.length, l = R(a), u = R(i), { pValue: m } = ye(a, i), d = Math.sqrt((l ** 2 + u ** 2) / 2), f = (c - r) / d;
|
|
2172
|
+
let h;
|
|
2173
|
+
m < 1 - o ? h = c > r ? "treatment" : "control" : h = "inconclusive";
|
|
2174
|
+
const p = h === "inconclusive" ? "No significant difference detected. Consider collecting more data." : `${h === "treatment" ? "Treatment" : "Control"} group performs better with ${Math.abs(f).toFixed(2)} effect size.`;
|
|
2175
|
+
return {
|
|
2176
|
+
winner: h,
|
|
2177
|
+
pValue: m,
|
|
2178
|
+
confidenceInterval: [
|
|
2179
|
+
c - r - 1.96 * d,
|
|
2180
|
+
c - r + 1.96 * d
|
|
2181
|
+
],
|
|
2182
|
+
effectSize: f,
|
|
2183
|
+
statisticalPower: 0.8,
|
|
2184
|
+
// Simplified
|
|
2185
|
+
recommendation: p,
|
|
2186
|
+
controlStats: {
|
|
2187
|
+
mean: r,
|
|
2188
|
+
std: l,
|
|
2189
|
+
size: a.length
|
|
2190
|
+
},
|
|
2191
|
+
treatmentStats: {
|
|
2192
|
+
mean: c,
|
|
2193
|
+
std: u,
|
|
2194
|
+
size: i.length
|
|
2195
|
+
}
|
|
2196
|
+
};
|
|
2197
|
+
}
|
|
2198
|
+
async function Jn(s) {
|
|
2199
|
+
const { test: e, groups: t, metric: n, alpha: o = 0.05 } = s;
|
|
2200
|
+
if (e === "ttest" && t.length === 2) {
|
|
2201
|
+
const a = t[0].map((l) => Number(l[n])).filter((l) => !isNaN(l)), i = t[1].map((l) => Number(l[n])).filter((l) => !isNaN(l)), { pValue: r, statistic: c } = ye(a, i);
|
|
2202
|
+
return {
|
|
2203
|
+
testType: "ttest",
|
|
2204
|
+
pValue: r,
|
|
2205
|
+
statistic: c,
|
|
2206
|
+
significant: r < o,
|
|
2207
|
+
alpha: o,
|
|
2208
|
+
degreesOfFreedom: a.length + i.length - 2,
|
|
2209
|
+
interpretation: r < o ? "Significant difference detected between groups" : "No significant difference detected",
|
|
2210
|
+
groups: [
|
|
2211
|
+
{
|
|
2212
|
+
name: "Group 1",
|
|
2213
|
+
mean: a.reduce((l, u) => l + u, 0) / a.length,
|
|
2214
|
+
std: R(a),
|
|
2215
|
+
size: a.length
|
|
2216
|
+
},
|
|
2217
|
+
{
|
|
2218
|
+
name: "Group 2",
|
|
2219
|
+
mean: i.reduce((l, u) => l + u, 0) / i.length,
|
|
2220
|
+
std: R(i),
|
|
2221
|
+
size: i.length
|
|
2222
|
+
}
|
|
2223
|
+
]
|
|
2224
|
+
};
|
|
2225
|
+
}
|
|
2226
|
+
return {
|
|
2227
|
+
testType: e,
|
|
2228
|
+
pValue: 0.05,
|
|
2229
|
+
statistic: 0,
|
|
2230
|
+
significant: !1,
|
|
2231
|
+
alpha: o,
|
|
2232
|
+
interpretation: "Test not fully implemented",
|
|
2233
|
+
groups: []
|
|
2234
|
+
};
|
|
2235
|
+
}
|
|
2236
|
+
async function Hn(s) {
|
|
2237
|
+
const { effect: e, power: t = 0.8, alpha: n = 0.05 } = s, i = Math.ceil(2 * Math.pow((1.96 + 0.84) / e, 2));
|
|
2238
|
+
return {
|
|
2239
|
+
requiredSampleSize: i,
|
|
2240
|
+
effect: e,
|
|
2241
|
+
power: t,
|
|
2242
|
+
alpha: n,
|
|
2243
|
+
recommendation: `You need approximately ${i} samples per group to detect an effect size of ${e} with ${t * 100}% power.`
|
|
2244
|
+
};
|
|
2245
|
+
}
|
|
2246
|
+
function R(s) {
|
|
2247
|
+
const e = s.reduce((n, o) => n + o, 0) / s.length, t = s.reduce((n, o) => n + Math.pow(o - e, 2), 0) / s.length;
|
|
2248
|
+
return Math.sqrt(t);
|
|
2249
|
+
}
|
|
2250
|
+
function ye(s, e) {
|
|
2251
|
+
const t = s.reduce((m, d) => m + d, 0) / s.length, n = e.reduce((m, d) => m + d, 0) / e.length, o = R(s) ** 2, a = R(e) ** 2, i = s.length, r = e.length, c = ((i - 1) * o + (r - 1) * a) / (i + r - 2), l = (t - n) / Math.sqrt(c * (1 / i + 1 / r));
|
|
2252
|
+
return { pValue: 2 * (1 - Xt(Math.abs(l))), statistic: l };
|
|
2253
|
+
}
|
|
2254
|
+
function Xt(s) {
|
|
2255
|
+
const e = 1 / (1 + 0.2316419 * Math.abs(s)), n = 0.3989423 * Math.exp(-s * s / 2) * e * (0.3193815 + e * (-0.3565638 + e * (1.781478 + e * (-1.821256 + e * 1.330274))));
|
|
2256
|
+
return s > 0 ? 1 - n : n;
|
|
2257
|
+
}
|
|
2258
|
+
async function Bn(s, e) {
|
|
2259
|
+
const t = (e == null ? void 0 : e.columns) || Object.keys(s[0]), n = [], o = [], a = [], i = [];
|
|
2260
|
+
for (const r of t) {
|
|
2261
|
+
const c = s.map((u) => u[r]), l = U(c);
|
|
2262
|
+
l === "numeric" ? o.push(r) : l === "categorical" ? a.push(r) : l === "datetime" && i.push(r);
|
|
2263
|
+
}
|
|
2264
|
+
return i.length > 0 && o.length > 0 && n.push({
|
|
2265
|
+
chartType: "line",
|
|
2266
|
+
columns: [i[0], o[0]],
|
|
2267
|
+
reason: "Time series data detected - line chart shows trends over time",
|
|
2268
|
+
priority: 1,
|
|
2269
|
+
spec: await V({
|
|
2270
|
+
type: "line",
|
|
2271
|
+
xColumn: i[0],
|
|
2272
|
+
yColumn: o[0],
|
|
2273
|
+
data: s
|
|
2274
|
+
}),
|
|
2275
|
+
insights: ["Shows temporal trends and patterns"]
|
|
2276
|
+
}), a.length > 0 && o.length > 0 && n.push({
|
|
2277
|
+
chartType: "bar",
|
|
2278
|
+
columns: [a[0], o[0]],
|
|
2279
|
+
reason: "Categorical data - bar chart compares values across categories",
|
|
2280
|
+
priority: 2,
|
|
2281
|
+
spec: await V({
|
|
2282
|
+
type: "bar",
|
|
2283
|
+
xColumn: a[0],
|
|
2284
|
+
yColumn: o[0],
|
|
2285
|
+
data: s
|
|
2286
|
+
}),
|
|
2287
|
+
insights: ["Compares values across different categories"]
|
|
2288
|
+
}), o.length >= 2 && n.push({
|
|
2289
|
+
chartType: "scatter",
|
|
2290
|
+
columns: [o[0], o[1]],
|
|
2291
|
+
reason: "Multiple numeric columns - scatter plot reveals correlations",
|
|
2292
|
+
priority: 3,
|
|
2293
|
+
spec: await V({
|
|
2294
|
+
type: "scatter",
|
|
2295
|
+
xColumn: o[0],
|
|
2296
|
+
yColumn: o[1],
|
|
2297
|
+
data: s
|
|
2298
|
+
}),
|
|
2299
|
+
insights: ["Reveals relationships between variables"]
|
|
2300
|
+
}), o.length > 0 && n.push({
|
|
2301
|
+
chartType: "histogram",
|
|
2302
|
+
columns: [o[0]],
|
|
2303
|
+
reason: "Numeric data - histogram shows distribution",
|
|
2304
|
+
priority: 4,
|
|
2305
|
+
spec: await V({
|
|
2306
|
+
type: "histogram",
|
|
2307
|
+
xColumn: o[0],
|
|
2308
|
+
data: s
|
|
2309
|
+
}),
|
|
2310
|
+
insights: ["Shows data distribution and outliers"]
|
|
2311
|
+
}), n.sort((r, c) => r.priority - c.priority);
|
|
2312
|
+
}
|
|
2313
|
+
async function V(s) {
|
|
2314
|
+
const { type: e, xColumn: t, yColumn: n, groupBy: o, data: a } = s, i = {
|
|
2315
|
+
type: e,
|
|
2316
|
+
title: `${e.charAt(0).toUpperCase() + e.slice(1)} Chart`,
|
|
2317
|
+
xAxis: {
|
|
2318
|
+
column: t,
|
|
2319
|
+
label: t,
|
|
2320
|
+
type: U(a.map((r) => r[t]))
|
|
2321
|
+
},
|
|
2322
|
+
data: a
|
|
2323
|
+
};
|
|
2324
|
+
if (n) {
|
|
2325
|
+
const r = U(a.map((c) => c[n]));
|
|
2326
|
+
i.yAxis = {
|
|
2327
|
+
column: n,
|
|
2328
|
+
label: n,
|
|
2329
|
+
type: r === "datetime" ? "numeric" : r
|
|
2330
|
+
};
|
|
2331
|
+
}
|
|
2332
|
+
return o && (i.groupBy = o), i;
|
|
2333
|
+
}
|
|
2334
|
+
async function Ln(s, e) {
|
|
2335
|
+
const t = [];
|
|
2336
|
+
return s === "line" && t.push({
|
|
2337
|
+
type: "trend",
|
|
2338
|
+
description: "Upward trend detected in the data",
|
|
2339
|
+
confidence: 0.8,
|
|
2340
|
+
recommendation: "Consider forecasting future values"
|
|
2341
|
+
}), s === "scatter" && t.push({
|
|
2342
|
+
type: "correlation",
|
|
2343
|
+
description: "Strong positive correlation observed",
|
|
2344
|
+
confidence: 0.75,
|
|
2345
|
+
recommendation: "Investigate causal relationship"
|
|
2346
|
+
}), t;
|
|
2347
|
+
}
|
|
2348
|
+
function U(s) {
|
|
2349
|
+
const e = s.filter((o) => o != null && o !== "");
|
|
2350
|
+
return e.length === 0 ? "categorical" : e.filter((o) => !isNaN(Number(o))).length / e.length > 0.8 ? "numeric" : e.filter((o) => {
|
|
2351
|
+
const a = new Date(o);
|
|
2352
|
+
return !isNaN(a.getTime());
|
|
2353
|
+
}).length / e.length > 0.8 ? "datetime" : "categorical";
|
|
2354
|
+
}
|
|
2355
|
+
async function Yt(s) {
|
|
2356
|
+
const { leftTable: e, rightTable: t, leftKey: n, rightKey: o, joinType: a } = s, i = [], r = /* @__PURE__ */ new Map();
|
|
2357
|
+
for (const c of t) {
|
|
2358
|
+
const l = c[o];
|
|
2359
|
+
r.has(l) || r.set(l, []), r.get(l).push(c);
|
|
2360
|
+
}
|
|
2361
|
+
for (const c of e) {
|
|
2362
|
+
const l = c[n], u = r.get(l) || [];
|
|
2363
|
+
if (u.length > 0)
|
|
2364
|
+
for (const m of u)
|
|
2365
|
+
i.push({ ...c, ...m });
|
|
2366
|
+
else (a === "left" || a === "outer") && i.push({ ...c });
|
|
2367
|
+
}
|
|
2368
|
+
if (a === "right" || a === "outer") {
|
|
2369
|
+
const c = new Set(e.map((l) => l[n]));
|
|
2370
|
+
for (const l of t)
|
|
2371
|
+
c.has(l[o]) || i.push({ ...l });
|
|
2372
|
+
}
|
|
2373
|
+
return i;
|
|
2374
|
+
}
|
|
2375
|
+
async function Zt(s) {
|
|
2376
|
+
const e = [], t = Object.keys(s);
|
|
2377
|
+
for (let n = 0; n < t.length; n++)
|
|
2378
|
+
for (let o = n + 1; o < t.length; o++) {
|
|
2379
|
+
const a = t[n], i = t[o], r = s[a], c = s[i], l = Object.keys(r[0] || {}), u = Object.keys(c[0] || {});
|
|
2380
|
+
for (const m of l)
|
|
2381
|
+
for (const d of u) {
|
|
2382
|
+
const f = en(
|
|
2383
|
+
r,
|
|
2384
|
+
m,
|
|
2385
|
+
c,
|
|
2386
|
+
d,
|
|
2387
|
+
a,
|
|
2388
|
+
i
|
|
2389
|
+
);
|
|
2390
|
+
f && e.push(f);
|
|
2391
|
+
}
|
|
2392
|
+
}
|
|
2393
|
+
return e;
|
|
2394
|
+
}
|
|
2395
|
+
async function Un(s) {
|
|
2396
|
+
const { tables: e, relationships: t, question: n } = s, o = Object.keys(e), a = t.map((r) => ({
|
|
2397
|
+
left: r.fromTable,
|
|
2398
|
+
right: r.toTable,
|
|
2399
|
+
type: "inner",
|
|
2400
|
+
on: `${r.fromColumn} = ${r.toColumn}`
|
|
2401
|
+
}));
|
|
2402
|
+
let i = e[o[0]];
|
|
2403
|
+
for (const r of t)
|
|
2404
|
+
e[r.toTable] && (i = await Yt({
|
|
2405
|
+
leftTable: i,
|
|
2406
|
+
rightTable: e[r.toTable],
|
|
2407
|
+
leftKey: r.fromColumn,
|
|
2408
|
+
rightKey: r.toColumn,
|
|
2409
|
+
joinType: "inner"
|
|
2410
|
+
}));
|
|
2411
|
+
return {
|
|
2412
|
+
query: n,
|
|
2413
|
+
tables: o,
|
|
2414
|
+
relationships: t,
|
|
2415
|
+
result: i.slice(0, 100),
|
|
2416
|
+
// Limit results
|
|
2417
|
+
insights: [
|
|
2418
|
+
`Joined ${o.length} tables`,
|
|
2419
|
+
`Found ${i.length} matching records`
|
|
2420
|
+
],
|
|
2421
|
+
joinOperations: a
|
|
2422
|
+
};
|
|
2423
|
+
}
|
|
2424
|
+
async function Kn(s) {
|
|
2425
|
+
const e = [];
|
|
2426
|
+
for (const [n, o] of Object.entries(s)) {
|
|
2427
|
+
if (o.length === 0) continue;
|
|
2428
|
+
const a = Object.keys(o[0]).map((i) => ({
|
|
2429
|
+
name: i,
|
|
2430
|
+
type: tn(o.map((r) => r[i])),
|
|
2431
|
+
nullable: o.some((r) => r[i] === null || r[i] === void 0)
|
|
2432
|
+
}));
|
|
2433
|
+
e.push({
|
|
2434
|
+
name: n,
|
|
2435
|
+
columns: a,
|
|
2436
|
+
rowCount: o.length
|
|
2437
|
+
});
|
|
2438
|
+
}
|
|
2439
|
+
const t = await Zt(s);
|
|
2440
|
+
return {
|
|
2441
|
+
tables: e,
|
|
2442
|
+
relationships: t
|
|
2443
|
+
};
|
|
2444
|
+
}
|
|
2445
|
+
function en(s, e, t, n, o, a) {
|
|
2446
|
+
const i = new Set(s.map((d) => d[e]).filter((d) => d != null)), r = new Set(t.map((d) => d[n]).filter((d) => d != null)), l = new Set([...i].filter((d) => r.has(d))).size;
|
|
2447
|
+
if (l < Math.min(i.size, r.size) * 0.1)
|
|
2448
|
+
return null;
|
|
2449
|
+
const u = l / Math.min(i.size, r.size);
|
|
2450
|
+
let m;
|
|
2451
|
+
return i.size === r.size && l === i.size ? m = "one-to-one" : i.size < r.size ? m = "one-to-many" : m = "many-to-many", {
|
|
2452
|
+
fromTable: o,
|
|
2453
|
+
toTable: a,
|
|
2454
|
+
fromColumn: e,
|
|
2455
|
+
toColumn: n,
|
|
2456
|
+
type: m,
|
|
2457
|
+
confidence: u,
|
|
2458
|
+
matchingRows: l,
|
|
2459
|
+
totalRows: s.length
|
|
2460
|
+
};
|
|
2461
|
+
}
|
|
2462
|
+
function tn(s) {
|
|
2463
|
+
const e = s.filter((n) => n != null && n !== "");
|
|
2464
|
+
return e.length === 0 ? "string" : e.filter((n) => !isNaN(Number(n))).length / e.length > 0.8 ? "number" : "categorical";
|
|
2465
|
+
}
|
|
2466
|
+
async function Gn(s, e) {
|
|
2467
|
+
const { format: t, sections: n = ["summary", "stats", "recommendations"], includeCharts: o = !1 } = e, a = [];
|
|
2468
|
+
return n.includes("summary") && a.push({
|
|
2469
|
+
type: "summary",
|
|
2470
|
+
title: "Executive Summary",
|
|
2471
|
+
content: await nn(s)
|
|
2472
|
+
}), n.includes("stats") && a.push({
|
|
2473
|
+
type: "stats",
|
|
2474
|
+
title: "Statistical Overview",
|
|
2475
|
+
content: sn(s)
|
|
2476
|
+
}), n.includes("recommendations") && a.push({
|
|
2477
|
+
type: "recommendations",
|
|
2478
|
+
title: "Recommendations",
|
|
2479
|
+
content: on()
|
|
2480
|
+
}), {
|
|
2481
|
+
format: t,
|
|
2482
|
+
title: "Data Analysis Report",
|
|
2483
|
+
sections: a,
|
|
2484
|
+
generatedAt: /* @__PURE__ */ new Date(),
|
|
2485
|
+
metadata: {
|
|
2486
|
+
dataSource: "Tabular Intelligence",
|
|
2487
|
+
rowCount: s.length,
|
|
2488
|
+
columnCount: Object.keys(s[0] || {}).length
|
|
2489
|
+
}
|
|
2490
|
+
};
|
|
2491
|
+
}
|
|
2492
|
+
async function nn(s) {
|
|
2493
|
+
const e = s.length, t = Object.keys(s[0] || {}).length;
|
|
2494
|
+
return `
|
|
2495
|
+
# Executive Summary
|
|
2496
|
+
|
|
2497
|
+
This dataset contains **${e} rows** and **${t} columns**.
|
|
2498
|
+
|
|
2499
|
+
## Key Findings:
|
|
2500
|
+
- Dataset size: ${e} records
|
|
2501
|
+
- Number of features: ${t}
|
|
2502
|
+
- Data quality: Good (estimated)
|
|
2503
|
+
|
|
2504
|
+
## Recommendations:
|
|
2505
|
+
- Consider feature engineering for improved analysis
|
|
2506
|
+
- Review data quality metrics
|
|
2507
|
+
- Explore correlations between variables
|
|
2508
|
+
`.trim();
|
|
2509
|
+
}
|
|
2510
|
+
async function Wn(s, e) {
|
|
2511
|
+
const { maxInsights: t = 10 } = e || {}, n = [], o = Object.keys(s[0] || {});
|
|
2512
|
+
for (const a of o.slice(0, t)) {
|
|
2513
|
+
const i = s.map((l) => l[a]);
|
|
2514
|
+
new Set(i.filter((l) => l != null)).size === 1 && n.push({
|
|
2515
|
+
title: `Constant Column: ${a}`,
|
|
2516
|
+
description: `Column "${a}" has only one unique value. Consider removing it.`,
|
|
2517
|
+
type: "recommendation",
|
|
2518
|
+
severity: "warning",
|
|
2519
|
+
confidence: 1,
|
|
2520
|
+
actionable: !0,
|
|
2521
|
+
suggestedActions: [`Remove column "${a}" as it provides no variance`]
|
|
2522
|
+
});
|
|
2523
|
+
const c = i.filter((l) => l == null || l === "").length;
|
|
2524
|
+
c > s.length * 0.2 && n.push({
|
|
2525
|
+
title: `High Missing Rate: ${a}`,
|
|
2526
|
+
description: `Column "${a}" has ${(c / s.length * 100).toFixed(1)}% missing values.`,
|
|
2527
|
+
type: "warning",
|
|
2528
|
+
severity: "warning",
|
|
2529
|
+
confidence: 1,
|
|
2530
|
+
actionable: !0,
|
|
2531
|
+
suggestedActions: [
|
|
2532
|
+
"Impute missing values",
|
|
2533
|
+
"Consider removing this column",
|
|
2534
|
+
"Investigate why data is missing"
|
|
2535
|
+
]
|
|
2536
|
+
});
|
|
2537
|
+
}
|
|
2538
|
+
return n.slice(0, t);
|
|
2539
|
+
}
|
|
2540
|
+
function sn(s) {
|
|
2541
|
+
const e = Object.keys(s[0] || {}), t = e.filter((n) => s.map((a) => a[n]).some((a) => !isNaN(Number(a))));
|
|
2542
|
+
return `
|
|
2543
|
+
## Statistical Overview
|
|
2544
|
+
|
|
2545
|
+
- Total Rows: ${s.length}
|
|
2546
|
+
- Total Columns: ${e.length}
|
|
2547
|
+
- Numeric Columns: ${t.length}
|
|
2548
|
+
- Categorical Columns: ${e.length - t.length}
|
|
2549
|
+
`.trim();
|
|
2550
|
+
}
|
|
2551
|
+
function on(s) {
|
|
2552
|
+
return `
|
|
2553
|
+
## Recommendations
|
|
2554
|
+
|
|
2555
|
+
1. **Data Quality**: Review and clean missing values
|
|
2556
|
+
2. **Feature Engineering**: Create interaction features for better insights
|
|
2557
|
+
3. **Analysis**: Perform correlation analysis to identify relationships
|
|
2558
|
+
4. **Visualization**: Create charts to explore patterns
|
|
2559
|
+
`.trim();
|
|
2560
|
+
}
|
|
2561
|
+
async function an(s) {
|
|
2562
|
+
const e = Object.keys(s[0] || {}), t = [];
|
|
2563
|
+
for (const o of e) {
|
|
2564
|
+
const a = s.map((r) => String(r[o])).filter((r) => r && r !== "null" && r !== "undefined"), i = a.slice(0, 5);
|
|
2565
|
+
a.some((r) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r)) && t.push({
|
|
2566
|
+
column: o,
|
|
2567
|
+
type: "email",
|
|
2568
|
+
confidence: 0.95,
|
|
2569
|
+
sampleValues: i.slice(0, 3).map((r) => rn(r)),
|
|
2570
|
+
count: a.length
|
|
2571
|
+
}), a.some((r) => /^\+?[\d\s\-()]{10,}$/.test(r)) && t.push({
|
|
2572
|
+
column: o,
|
|
2573
|
+
type: "phone",
|
|
2574
|
+
confidence: 0.85,
|
|
2575
|
+
sampleValues: i.slice(0, 3).map((r) => cn(r)),
|
|
2576
|
+
count: a.length
|
|
2577
|
+
}), a.some((r) => /^\d{3}-\d{2}-\d{4}$/.test(r)) && t.push({
|
|
2578
|
+
column: o,
|
|
2579
|
+
type: "ssn",
|
|
2580
|
+
confidence: 0.99,
|
|
2581
|
+
sampleValues: ["***-**-****"],
|
|
2582
|
+
count: a.length
|
|
2583
|
+
}), a.some((r) => /^\d{4}[\s-]?\d{4}[\s-]?\d{4}[\s-]?\d{4}$/.test(r)) && t.push({
|
|
2584
|
+
column: o,
|
|
2585
|
+
type: "credit_card",
|
|
2586
|
+
confidence: 0.95,
|
|
2587
|
+
sampleValues: ["****-****-****-****"],
|
|
2588
|
+
count: a.length
|
|
2589
|
+
}), (o.toLowerCase().includes("name") || o.toLowerCase().includes("fullname")) && t.push({
|
|
2590
|
+
column: o,
|
|
2591
|
+
type: "name",
|
|
2592
|
+
confidence: 0.7,
|
|
2593
|
+
sampleValues: i.slice(0, 3).map(() => "[REDACTED]"),
|
|
2594
|
+
count: a.length
|
|
2595
|
+
});
|
|
2596
|
+
}
|
|
2597
|
+
const n = t.length > 5 ? "high" : t.length > 2 ? "medium" : "low";
|
|
2598
|
+
return {
|
|
2599
|
+
piiColumns: t,
|
|
2600
|
+
recommendations: dn(t),
|
|
2601
|
+
riskLevel: n
|
|
2602
|
+
};
|
|
2603
|
+
}
|
|
2604
|
+
async function Xn(s, e) {
|
|
2605
|
+
const { method: t, columns: n } = e, o = n || Object.keys(s[0]);
|
|
2606
|
+
return {
|
|
2607
|
+
data: s.map((i) => {
|
|
2608
|
+
const r = { ...i };
|
|
2609
|
+
for (const c of o)
|
|
2610
|
+
r[c] = ln(i[c], t);
|
|
2611
|
+
return r;
|
|
2612
|
+
}),
|
|
2613
|
+
method: t,
|
|
2614
|
+
columns: o,
|
|
2615
|
+
reversible: t === "tokenization",
|
|
2616
|
+
privacyLevel: mn(t)
|
|
2617
|
+
};
|
|
2618
|
+
}
|
|
2619
|
+
async function Yn(s, e) {
|
|
2620
|
+
const t = await an(s), n = [];
|
|
2621
|
+
t.piiColumns.length > 0 && n.push({
|
|
2622
|
+
rule: `${e} - PII Protection`,
|
|
2623
|
+
description: `Found ${t.piiColumns.length} columns containing PII`,
|
|
2624
|
+
severity: "critical",
|
|
2625
|
+
affectedColumns: t.piiColumns.map((i) => i.column),
|
|
2626
|
+
remediation: "Implement anonymization or encryption for PII columns"
|
|
2627
|
+
});
|
|
2628
|
+
const o = n.length === 0, a = Math.max(0, 100 - n.length * 20);
|
|
2629
|
+
return {
|
|
2630
|
+
standard: e,
|
|
2631
|
+
compliant: o,
|
|
2632
|
+
score: a,
|
|
2633
|
+
violations: n,
|
|
2634
|
+
recommendations: [
|
|
2635
|
+
"Implement data encryption at rest and in transit",
|
|
2636
|
+
"Add access controls and audit logging",
|
|
2637
|
+
"Create data retention and deletion policies"
|
|
2638
|
+
],
|
|
2639
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2640
|
+
};
|
|
2641
|
+
}
|
|
2642
|
+
function rn(s) {
|
|
2643
|
+
const [e, t] = s.split("@");
|
|
2644
|
+
return `${e.slice(0, 2)}***@${t}`;
|
|
2645
|
+
}
|
|
2646
|
+
function cn(s) {
|
|
2647
|
+
return s.replace(/\d/g, (e, t) => t < s.length - 4 ? "*" : e);
|
|
2648
|
+
}
|
|
2649
|
+
function ln(s, e) {
|
|
2650
|
+
if (s == null) return s;
|
|
2651
|
+
switch (e) {
|
|
2652
|
+
case "masking":
|
|
2653
|
+
return "***MASKED***";
|
|
2654
|
+
case "hashing":
|
|
2655
|
+
return un(String(s));
|
|
2656
|
+
case "generalization":
|
|
2657
|
+
return typeof s == "number" ? Math.floor(s / 10) * 10 : "[GENERALIZED]";
|
|
2658
|
+
case "tokenization":
|
|
2659
|
+
return `TOKEN_${Math.random().toString(36).substr(2, 9)}`;
|
|
2660
|
+
default:
|
|
2661
|
+
return s;
|
|
2662
|
+
}
|
|
2663
|
+
}
|
|
2664
|
+
function un(s) {
|
|
2665
|
+
let e = 0;
|
|
2666
|
+
for (let t = 0; t < s.length; t++) {
|
|
2667
|
+
const n = s.charCodeAt(t);
|
|
2668
|
+
e = (e << 5) - e + n, e = e & e;
|
|
2669
|
+
}
|
|
2670
|
+
return `HASH_${Math.abs(e).toString(16)}`;
|
|
2671
|
+
}
|
|
2672
|
+
function mn(s) {
|
|
2673
|
+
return {
|
|
2674
|
+
masking: 60,
|
|
2675
|
+
hashing: 80,
|
|
2676
|
+
generalization: 50,
|
|
2677
|
+
differential_privacy: 95,
|
|
2678
|
+
tokenization: 70
|
|
2679
|
+
}[s] || 50;
|
|
2680
|
+
}
|
|
2681
|
+
function dn(s) {
|
|
2682
|
+
const e = [];
|
|
2683
|
+
return s.length > 0 && (e.push("Implement data anonymization for PII columns"), e.push("Add access controls to restrict PII access"), e.push("Enable audit logging for PII access")), s.some((t) => t.type === "ssn" || t.type === "credit_card") && e.push("CRITICAL: Encrypt sensitive financial/identity data"), e;
|
|
2684
|
+
}
|
|
2685
|
+
const K = /* @__PURE__ */ new Map(), we = /* @__PURE__ */ new Map();
|
|
2686
|
+
async function Zn(s, e) {
|
|
2687
|
+
const t = `snapshot_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`, n = Object.keys(s[0] || {}), o = {
|
|
2688
|
+
id: t,
|
|
2689
|
+
label: e || `Snapshot ${(/* @__PURE__ */ new Date()).toISOString()}`,
|
|
2690
|
+
data: JSON.parse(JSON.stringify(s)),
|
|
2691
|
+
schema: {
|
|
2692
|
+
columns: n.map((a) => ({
|
|
2693
|
+
name: a,
|
|
2694
|
+
type: fn(s.map((i) => i[a]))
|
|
2695
|
+
})),
|
|
2696
|
+
rowCount: s.length
|
|
2697
|
+
},
|
|
2698
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
2699
|
+
metadata: {
|
|
2700
|
+
rowCount: s.length,
|
|
2701
|
+
columnCount: n.length,
|
|
2702
|
+
checksum: hn(s)
|
|
2703
|
+
}
|
|
2704
|
+
};
|
|
2705
|
+
return K.set(t, o), o;
|
|
2706
|
+
}
|
|
2707
|
+
async function es(s, e) {
|
|
2708
|
+
const t = K.get(s), n = K.get(e);
|
|
2709
|
+
if (!t || !n)
|
|
2710
|
+
throw new Error("Snapshot not found");
|
|
2711
|
+
const o = new Set(t.schema.columns.map((u) => u.name)), a = new Set(n.schema.columns.map((u) => u.name)), i = Array.from(a).filter((u) => !o.has(u)), r = Array.from(o).filter((u) => !a.has(u)), c = n.data.length - t.data.length, l = c < 0 ? Math.abs(c) : 0;
|
|
2712
|
+
return {
|
|
2713
|
+
snapshot1: s,
|
|
2714
|
+
snapshot2: e,
|
|
2715
|
+
changes: {
|
|
2716
|
+
rowsAdded: Math.max(0, c),
|
|
2717
|
+
rowsRemoved: l,
|
|
2718
|
+
rowsModified: 0,
|
|
2719
|
+
// Simplified
|
|
2720
|
+
columnsAdded: i,
|
|
2721
|
+
columnsRemoved: r,
|
|
2722
|
+
columnsModified: []
|
|
2723
|
+
},
|
|
2724
|
+
details: []
|
|
2725
|
+
};
|
|
2726
|
+
}
|
|
2727
|
+
async function ts(s, e) {
|
|
2728
|
+
const t = {
|
|
2729
|
+
source: e,
|
|
2730
|
+
transformations: [],
|
|
2731
|
+
currentState: {
|
|
2732
|
+
rowCount: 0,
|
|
2733
|
+
columnCount: 0,
|
|
2734
|
+
lastModified: /* @__PURE__ */ new Date()
|
|
2735
|
+
}
|
|
2736
|
+
};
|
|
2737
|
+
return we.set(s, t), t;
|
|
2738
|
+
}
|
|
2739
|
+
function ns(s, e, t) {
|
|
2740
|
+
const n = we.get(s);
|
|
2741
|
+
n && n.transformations.push({
|
|
2742
|
+
operation: e,
|
|
2743
|
+
timestamp: /* @__PURE__ */ new Date(),
|
|
2744
|
+
params: t
|
|
2745
|
+
});
|
|
2746
|
+
}
|
|
2747
|
+
async function ss(s) {
|
|
2748
|
+
return {
|
|
2749
|
+
id: `pipeline_${Date.now()}`,
|
|
2750
|
+
name: "Data Processing Pipeline",
|
|
2751
|
+
steps: s,
|
|
2752
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
2753
|
+
};
|
|
2754
|
+
}
|
|
2755
|
+
async function os(s, e) {
|
|
2756
|
+
const t = Date.now();
|
|
2757
|
+
let n = JSON.parse(JSON.stringify(e));
|
|
2758
|
+
const o = [];
|
|
2759
|
+
let a = 0;
|
|
2760
|
+
for (let i = 0; i < s.steps.length; i++) {
|
|
2761
|
+
const r = s.steps[i];
|
|
2762
|
+
try {
|
|
2763
|
+
if (r.condition && !r.condition(n))
|
|
2764
|
+
continue;
|
|
2765
|
+
n = await pn(n, r), a++;
|
|
2766
|
+
} catch (c) {
|
|
2767
|
+
if (o.push({
|
|
2768
|
+
step: i,
|
|
2769
|
+
error: c instanceof Error ? c.message : String(c)
|
|
2770
|
+
}), r.onError === "stop")
|
|
2771
|
+
break;
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
return {
|
|
2775
|
+
success: o.length === 0,
|
|
2776
|
+
data: n,
|
|
2777
|
+
stepsExecuted: a,
|
|
2778
|
+
totalSteps: s.steps.length,
|
|
2779
|
+
executionTime: Date.now() - t,
|
|
2780
|
+
errors: o.length > 0 ? o : void 0
|
|
2781
|
+
};
|
|
2782
|
+
}
|
|
2783
|
+
async function as(s, e) {
|
|
2784
|
+
console.log(`Pipeline "${e}" saved`);
|
|
2785
|
+
}
|
|
2786
|
+
async function rs(s) {
|
|
2787
|
+
return {
|
|
2788
|
+
id: "loaded_pipeline",
|
|
2789
|
+
name: s,
|
|
2790
|
+
steps: [],
|
|
2791
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
2792
|
+
};
|
|
2793
|
+
}
|
|
2794
|
+
function fn(s) {
|
|
2795
|
+
const e = s.filter((n) => n != null && n !== "");
|
|
2796
|
+
return e.length === 0 ? "string" : e.filter((n) => !isNaN(Number(n))).length / e.length > 0.8 ? "number" : "categorical";
|
|
2797
|
+
}
|
|
2798
|
+
function hn(s) {
|
|
2799
|
+
const e = JSON.stringify(s);
|
|
2800
|
+
let t = 0;
|
|
2801
|
+
for (let n = 0; n < e.length; n++) {
|
|
2802
|
+
const o = e.charCodeAt(n);
|
|
2803
|
+
t = (t << 5) - t + o, t = t & t;
|
|
2804
|
+
}
|
|
2805
|
+
return Math.abs(t).toString(16);
|
|
2806
|
+
}
|
|
2807
|
+
async function pn(s, e) {
|
|
2808
|
+
return s;
|
|
2809
|
+
}
|
|
2810
|
+
async function is(s) {
|
|
2811
|
+
const { source: e, url: t, updateInterval: n = 1e3 } = s, o = {
|
|
2812
|
+
id: `stream_${Date.now()}`,
|
|
2813
|
+
source: e,
|
|
2814
|
+
url: t,
|
|
2815
|
+
connected: !1,
|
|
2816
|
+
onData: () => {
|
|
2817
|
+
},
|
|
2818
|
+
onError: () => {
|
|
2819
|
+
},
|
|
2820
|
+
disconnect: () => {
|
|
2821
|
+
o.connected = !1;
|
|
2822
|
+
}
|
|
2823
|
+
};
|
|
2824
|
+
return setTimeout(() => {
|
|
2825
|
+
o.connected = !0;
|
|
2826
|
+
}, 100), o;
|
|
2827
|
+
}
|
|
2828
|
+
async function cs(s, e) {
|
|
2829
|
+
const { columns: t, threshold: n, windowSize: o = 100 } = e;
|
|
2830
|
+
console.log(`Monitoring anomalies on columns: ${t.join(", ")}`);
|
|
2831
|
+
}
|
|
2832
|
+
async function ls(s, e) {
|
|
2833
|
+
const { windowType: t, windowSize: n, aggregations: o } = e;
|
|
2834
|
+
console.log(`Streaming aggregation: ${t} window of ${n}`);
|
|
2835
|
+
}
|
|
2836
|
+
async function us(s, e) {
|
|
2837
|
+
const { columns: t, threshold: n, method: o = "statistical" } = e, a = [];
|
|
2838
|
+
for (const i of t) {
|
|
2839
|
+
const r = s.map((u) => Number(u[i])).filter((u) => !isNaN(u));
|
|
2840
|
+
if (r.length < 10) continue;
|
|
2841
|
+
const c = r.reduce((u, m) => u + m, 0) / r.length, l = Math.sqrt(
|
|
2842
|
+
r.reduce((u, m) => u + Math.pow(m - c, 2), 0) / r.length
|
|
2843
|
+
);
|
|
2844
|
+
s.forEach((u, m) => {
|
|
2845
|
+
const d = Number(u[i]);
|
|
2846
|
+
if (!isNaN(d)) {
|
|
2847
|
+
const f = Math.abs((d - c) / l);
|
|
2848
|
+
f > n && a.push({
|
|
2849
|
+
rowIndex: m,
|
|
2850
|
+
row: u,
|
|
2851
|
+
score: f / 10,
|
|
2852
|
+
// Normalize to 0-1
|
|
2853
|
+
reasons: [`${i} value ${d} is ${f.toFixed(2)} standard deviations from mean`],
|
|
2854
|
+
affectedColumns: [i]
|
|
2855
|
+
});
|
|
2856
|
+
}
|
|
2857
|
+
});
|
|
2858
|
+
}
|
|
2859
|
+
return a;
|
|
2860
|
+
}
|
|
2861
|
+
async function ms(s, e) {
|
|
2862
|
+
const { windowType: t, windowSize: n, aggregations: o } = e, a = [];
|
|
2863
|
+
if (t === "tumbling")
|
|
2864
|
+
for (let i = 0; i < s.length; i += n) {
|
|
2865
|
+
const r = s.slice(i, i + n), c = {};
|
|
2866
|
+
for (const l of o) {
|
|
2867
|
+
const u = r.map((d) => Number(d[l.column])).filter((d) => !isNaN(d));
|
|
2868
|
+
let m = 0;
|
|
2869
|
+
switch (l.function) {
|
|
2870
|
+
case "sum":
|
|
2871
|
+
m = u.reduce((f, h) => f + h, 0);
|
|
2872
|
+
break;
|
|
2873
|
+
case "avg":
|
|
2874
|
+
m = u.reduce((f, h) => f + h, 0) / u.length;
|
|
2875
|
+
break;
|
|
2876
|
+
case "count":
|
|
2877
|
+
m = u.length;
|
|
2878
|
+
break;
|
|
2879
|
+
case "min":
|
|
2880
|
+
m = Math.min(...u);
|
|
2881
|
+
break;
|
|
2882
|
+
case "max":
|
|
2883
|
+
m = Math.max(...u);
|
|
2884
|
+
break;
|
|
2885
|
+
case "std":
|
|
2886
|
+
const d = u.reduce((f, h) => f + h, 0) / u.length;
|
|
2887
|
+
m = Math.sqrt(u.reduce((f, h) => f + Math.pow(h - d, 2), 0) / u.length);
|
|
2888
|
+
break;
|
|
2889
|
+
}
|
|
2890
|
+
c[l.alias || `${l.column}_${l.function}`] = m;
|
|
2891
|
+
}
|
|
2892
|
+
a.push({
|
|
2893
|
+
windowStart: new Date(Date.now() + i * 1e3),
|
|
2894
|
+
windowEnd: new Date(Date.now() + (i + n) * 1e3),
|
|
2895
|
+
results: c,
|
|
2896
|
+
rowCount: r.length
|
|
2897
|
+
});
|
|
2898
|
+
}
|
|
2899
|
+
return a;
|
|
2900
|
+
}
|
|
2901
|
+
async function ds(s, e) {
|
|
2902
|
+
const { size: t, method: n, preserveDistribution: o = !0 } = e;
|
|
2903
|
+
let a = [];
|
|
2904
|
+
switch (n) {
|
|
2905
|
+
case "random":
|
|
2906
|
+
a = G(s, t);
|
|
2907
|
+
break;
|
|
2908
|
+
case "systematic":
|
|
2909
|
+
a = gn(s, t);
|
|
2910
|
+
break;
|
|
2911
|
+
case "stratified":
|
|
2912
|
+
a = yn(s, t);
|
|
2913
|
+
break;
|
|
2914
|
+
default:
|
|
2915
|
+
a = G(s, t);
|
|
2916
|
+
}
|
|
2917
|
+
return {
|
|
2918
|
+
data: a,
|
|
2919
|
+
method: n,
|
|
2920
|
+
originalSize: s.length,
|
|
2921
|
+
sampleSize: a.length,
|
|
2922
|
+
preservedDistribution: o,
|
|
2923
|
+
representativeness: 0.85
|
|
2924
|
+
// Simplified
|
|
2925
|
+
};
|
|
2926
|
+
}
|
|
2927
|
+
function G(s, e) {
|
|
2928
|
+
return [...s].sort(() => Math.random() - 0.5).slice(0, e);
|
|
2929
|
+
}
|
|
2930
|
+
function gn(s, e) {
|
|
2931
|
+
const t = Math.floor(s.length / e), n = [];
|
|
2932
|
+
for (let o = 0; o < s.length && n.length < e; o += t)
|
|
2933
|
+
n.push(s[o]);
|
|
2934
|
+
return n;
|
|
2935
|
+
}
|
|
2936
|
+
function yn(s, e) {
|
|
2937
|
+
return G(s, e);
|
|
2938
|
+
}
|
|
2939
|
+
const wn = B(le), vn = B(ue), bn = B(me), Cn = se({
|
|
2940
|
+
install(s) {
|
|
2941
|
+
F(s, "QuestionInput", le), F(s, "AnswerDisplay", ue), F(s, "QuestionHistory", me);
|
|
2942
|
+
}
|
|
2943
|
+
}), fs = {
|
|
2944
|
+
// Core
|
|
2945
|
+
TabularIntelligence: ce,
|
|
2946
|
+
// Composables
|
|
2947
|
+
useTabularIntelligence: Oe,
|
|
2948
|
+
// Components
|
|
2949
|
+
QuestionInput: wn,
|
|
2950
|
+
AnswerDisplay: vn,
|
|
2951
|
+
QuestionHistory: bn,
|
|
2952
|
+
// Plugin
|
|
2953
|
+
TabularIntelligencePlugin: Cn,
|
|
2954
|
+
// Re-export compatibility utilities for advanced users
|
|
2955
|
+
createCompatComponent: B,
|
|
2956
|
+
registerCompatComponent: F,
|
|
2957
|
+
createCompatPlugin: se
|
|
2958
|
+
};
|
|
1277
2959
|
export {
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
2960
|
+
vn as AnswerDisplay,
|
|
2961
|
+
te as QAEngine,
|
|
2962
|
+
bn as QuestionHistory,
|
|
2963
|
+
wn as QuestionInput,
|
|
2964
|
+
ce as TabularIntelligence,
|
|
2965
|
+
Cn as TabularIntelligencePlugin,
|
|
2966
|
+
ns as addTransformation,
|
|
2967
|
+
Qn as analyzeABTest,
|
|
2968
|
+
Un as analyzeCrossTables,
|
|
2969
|
+
Kt as analyzeFeatureImportance,
|
|
2970
|
+
Xn as anonymizeData,
|
|
2971
|
+
kn as assessDataQuality,
|
|
2972
|
+
On as autoGenerateFeatures,
|
|
2973
|
+
Tn as autoTrain,
|
|
2974
|
+
Hn as calculateSampleSize,
|
|
2975
|
+
ae as calculateStats,
|
|
2976
|
+
ms as calculateWindowedAggregations,
|
|
2977
|
+
Yn as checkCompliance,
|
|
2978
|
+
Dn as compareModels,
|
|
2979
|
+
es as compareSnapshots,
|
|
2980
|
+
is as connectStream,
|
|
2981
|
+
_e as convertToTabular,
|
|
2982
|
+
Rn as createFeatures,
|
|
2983
|
+
ss as createPipeline,
|
|
2984
|
+
Zn as createSnapshot,
|
|
2985
|
+
fs as default,
|
|
2986
|
+
Me as detectAnomalies,
|
|
2987
|
+
Pn as detectChangePoints,
|
|
2988
|
+
de as detectDataIssues,
|
|
2989
|
+
an as detectPII,
|
|
2990
|
+
Ln as detectPatterns,
|
|
2991
|
+
Zt as detectRelationships,
|
|
2992
|
+
Vt as detectSeasonality,
|
|
2993
|
+
us as detectStreamingAnomalies,
|
|
2994
|
+
qn as detectTrends,
|
|
2995
|
+
ie as executeAPIRequest,
|
|
2996
|
+
Nn as executeMultipleRequests,
|
|
2997
|
+
os as executePipeline,
|
|
2998
|
+
En as explainPrediction,
|
|
2999
|
+
xe as extractFromDOM,
|
|
3000
|
+
xn as forecastTimeSeries,
|
|
3001
|
+
V as generateChartSpec,
|
|
3002
|
+
jn as generateCounterfactuals,
|
|
3003
|
+
nn as generateExecutiveSummary,
|
|
3004
|
+
Wn as generateInsights,
|
|
3005
|
+
Gn as generateReport,
|
|
3006
|
+
Vn as getFeatureImportance,
|
|
3007
|
+
Fn as getPartialDependence,
|
|
3008
|
+
Mn as handleOutliers,
|
|
3009
|
+
$n as imputeMissingValues,
|
|
3010
|
+
oe as inferColumnType,
|
|
3011
|
+
Kn as inferDatabaseSchema,
|
|
3012
|
+
_ as inferSchema,
|
|
3013
|
+
Yt as joinTables,
|
|
3014
|
+
rs as loadPipeline,
|
|
3015
|
+
cs as monitorAnomalies,
|
|
3016
|
+
qe as normalizeVueData,
|
|
3017
|
+
Te as parsePostmanCollection,
|
|
3018
|
+
Y as profileData,
|
|
3019
|
+
Bn as recommendVisualizations,
|
|
3020
|
+
D as replaceVariables,
|
|
3021
|
+
as as savePipeline,
|
|
3022
|
+
zn as selectBestFeatures,
|
|
3023
|
+
ds as smartSample,
|
|
3024
|
+
ls as streamingAggregation,
|
|
3025
|
+
In as suggestCleaningSteps,
|
|
3026
|
+
Jn as testSignificance,
|
|
3027
|
+
ts as trackLineage,
|
|
3028
|
+
_n as tuneHyperparameters,
|
|
3029
|
+
Oe as useTabularIntelligence
|
|
1295
3030
|
};
|
|
1296
3031
|
//# sourceMappingURL=index.mjs.map
|