@graphenedata/cli 0.0.10 → 0.0.11
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/cli.ts +6 -1
- package/dist/cli/cli.js +121 -118
- package/dist/docs/agent-instructions.md +18 -0
- package/dist/docs/graphene.md +310 -182
- package/dist/ui/app.css +8 -10
- package/dist/ui/internal/NavSidebar.svelte +24 -8
- package/dist/ui/internal/NavSidebarHMR.svelte +8 -0
- package/dist/ui/internal/queryEngine.ts +1 -1
- package/dist/ui/web.js +1 -1
- package/package.json +1 -1
package/dist/cli/cli.js
CHANGED
|
@@ -58,12 +58,12 @@ function walkExpression(root, fn, parent = null) {
|
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
async function pollFor(fn, timeoutMs,
|
|
61
|
+
async function pollFor(fn, timeoutMs, interval2) {
|
|
62
62
|
let end = Date.now() + timeoutMs;
|
|
63
63
|
while (Date.now() < end) {
|
|
64
64
|
let res = fn();
|
|
65
65
|
if (res) return res;
|
|
66
|
-
await new Promise((r) => setTimeout(r,
|
|
66
|
+
await new Promise((r) => setTimeout(r, interval2));
|
|
67
67
|
}
|
|
68
68
|
return null;
|
|
69
69
|
}
|
|
@@ -240,7 +240,11 @@ var init_functionDefs = __esm({
|
|
|
240
240
|
}
|
|
241
241
|
});
|
|
242
242
|
BIGQUERY_DIALECT_FUNCTIONS = {
|
|
243
|
-
"
|
|
243
|
+
"countif": {
|
|
244
|
+
takes: { "value": "boolean" },
|
|
245
|
+
returns: { measure: "number" },
|
|
246
|
+
impl: { function: "COUNTIF" }
|
|
247
|
+
},
|
|
244
248
|
"if": { ...DUCKDB_DIALECT_FUNCTIONS["if"] },
|
|
245
249
|
"safe_divide": {
|
|
246
250
|
takes: { "numerator": "number", "denominator": "number" },
|
|
@@ -478,29 +482,6 @@ function parseTemporalLiteral(value, expected) {
|
|
|
478
482
|
}
|
|
479
483
|
return null;
|
|
480
484
|
}
|
|
481
|
-
function parseTemporal(node) {
|
|
482
|
-
if (node.node !== "stringLiteral") return null;
|
|
483
|
-
let rawValue = typeof node.literal === "string" ? node.literal.trim() : "";
|
|
484
|
-
if (!rawValue) return null;
|
|
485
|
-
let parsedDate = parseTemporalLiteral(rawValue, "date");
|
|
486
|
-
if (parsedDate) {
|
|
487
|
-
let typeDef = { type: parsedDate.type, timeframe: parsedDate.timeframe };
|
|
488
|
-
Object.assign(node, { node: "timeLiteral", literal: parsedDate.literal, type: parsedDate.type, typeDef });
|
|
489
|
-
return parsedDate.timeframe;
|
|
490
|
-
}
|
|
491
|
-
let parsedTimestamp = parseTemporalLiteral(rawValue, "timestamp");
|
|
492
|
-
if (parsedTimestamp) {
|
|
493
|
-
let typeDef = { type: parsedTimestamp.type, timeframe: parsedTimestamp.timeframe };
|
|
494
|
-
Object.assign(node, { node: "timeLiteral", literal: parsedTimestamp.literal, type: parsedTimestamp.type, typeDef });
|
|
495
|
-
return parsedTimestamp.timeframe;
|
|
496
|
-
}
|
|
497
|
-
let interval = parseIntervalLiteral(rawValue);
|
|
498
|
-
if (interval) {
|
|
499
|
-
Object.assign(node, { node: "numberLiteral", literal: interval.quantity.toString(), type: "interval", intervalUnit: interval.unit });
|
|
500
|
-
return interval.unit;
|
|
501
|
-
}
|
|
502
|
-
return null;
|
|
503
|
-
}
|
|
504
485
|
function parseIntervalLiteral(value) {
|
|
505
486
|
let raw = (value ?? "").trim().toLowerCase().replace(/\s+/g, " ");
|
|
506
487
|
if (!raw) return null;
|
|
@@ -512,6 +493,9 @@ function parseIntervalLiteral(value) {
|
|
|
512
493
|
if (!unit) return null;
|
|
513
494
|
return { quantity, unit };
|
|
514
495
|
}
|
|
496
|
+
function parseIntervalUnit(value) {
|
|
497
|
+
return INTERVAL_UNITS[value.toLowerCase()] || null;
|
|
498
|
+
}
|
|
515
499
|
function buildResult(year, month, day, hour, minute, second, timeframe, expected) {
|
|
516
500
|
if (expected === "date") {
|
|
517
501
|
return { literal: `${pad(year)}-${pad(month)}-${pad(day)}`, timeframe, type: "date" };
|
|
@@ -528,8 +512,8 @@ function inRange(value, min, max) {
|
|
|
528
512
|
function isValidDate(year, month, day) {
|
|
529
513
|
if (!inRange(month, 1, 12)) return false;
|
|
530
514
|
if (!inRange(day, 1, 31)) return false;
|
|
531
|
-
let
|
|
532
|
-
return
|
|
515
|
+
let date2 = new Date(Date.UTC(year, month - 1, day));
|
|
516
|
+
return date2.getUTCFullYear() === year && date2.getUTCMonth() === month - 1 && date2.getUTCDate() === day;
|
|
533
517
|
}
|
|
534
518
|
function pad(value) {
|
|
535
519
|
return value.toString().padStart(2, "0");
|
|
@@ -717,9 +701,11 @@ function findTables(fi) {
|
|
|
717
701
|
let nodes = tn.getChildren("TableStatement").concat(tn.getChildren("ViewStatement"));
|
|
718
702
|
for (let syntaxNode of nodes) {
|
|
719
703
|
let name = txt(syntaxNode.getChild("Ref"));
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
704
|
+
let existing = Object.values(FILE_MAP).find((f) => {
|
|
705
|
+
if (f.path.endsWith(".md") && f.path != fi.path) return;
|
|
706
|
+
return f.tables.find((t) => t.name == name);
|
|
707
|
+
});
|
|
708
|
+
if (existing) diag(syntaxNode.getChild("Ref"), `Table "${name}" is already defined`);
|
|
723
709
|
let table2 = makeTable(name, syntaxNode.getChild("QueryStatement") ? "query_source" : "table");
|
|
724
710
|
table2.metadata = extractLeadingMetadata(syntaxNode);
|
|
725
711
|
syntaxNode.getChildren("ColumnDef").forEach((cn) => addColumnField(table2, cn));
|
|
@@ -957,6 +943,31 @@ function analyzeExpression(expr, scope) {
|
|
|
957
943
|
if (!type) return diag(expr.getChild("CastType"), `Unsupported cast type: ${targetTypeStr}`, errExpr2);
|
|
958
944
|
return { node: "cast", safe: false, e, dstSQLType: targetTypeStr.toUpperCase(), type, isAgg: e.isAgg };
|
|
959
945
|
}
|
|
946
|
+
case "IntervalExpression": {
|
|
947
|
+
let stringNode = expr.getChild("String");
|
|
948
|
+
if (stringNode) {
|
|
949
|
+
let parsed = parseIntervalLiteral(txt(stringNode).slice(1, -1));
|
|
950
|
+
if (!parsed) return diag(stringNode, "Could not parse interval literal", errExpr2);
|
|
951
|
+
return { node: "numberLiteral", literal: parsed.quantity.toString(), type: "interval", intervalUnit: parsed.unit, isAgg: false };
|
|
952
|
+
} else {
|
|
953
|
+
let numNode = expr.getChild("Number");
|
|
954
|
+
let unitNode = expr.getChild("IntervalUnit");
|
|
955
|
+
let quantity = Number(txt(numNode));
|
|
956
|
+
let unitStr = txt(unitNode).toLowerCase();
|
|
957
|
+
let unit = parseIntervalUnit(unitStr);
|
|
958
|
+
if (!unit) return diag(unitNode, `Invalid interval unit: "${unitStr}"`, errExpr2);
|
|
959
|
+
return { node: "numberLiteral", literal: quantity.toString(), type: "interval", intervalUnit: unit, isAgg: false };
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
case "DateExpression":
|
|
963
|
+
case "TimestampExpression": {
|
|
964
|
+
let expectedType = expr.name === "DateExpression" ? "date" : "timestamp";
|
|
965
|
+
let stringNode = expr.getChild("String");
|
|
966
|
+
let parsed = parseTemporalLiteral(txt(stringNode).slice(1, -1), expectedType);
|
|
967
|
+
if (!parsed) return diag(stringNode, `Could not parse ${expectedType}`, errExpr2);
|
|
968
|
+
let typeDef = { type: parsed.type, timeframe: parsed.timeframe };
|
|
969
|
+
return { node: "timeLiteral", literal: parsed.literal, type: parsed.type, typeDef, isAgg: false };
|
|
970
|
+
}
|
|
960
971
|
case "FunctionCall":
|
|
961
972
|
return analyzeFunctionCall(expr, scope);
|
|
962
973
|
case "Parenthetical":
|
|
@@ -1049,29 +1060,23 @@ function analyzeExpression(expr, scope) {
|
|
|
1049
1060
|
}
|
|
1050
1061
|
function analyzeTimeExpression(op, left2, right2, node) {
|
|
1051
1062
|
if (left2.type !== "date" && left2.type !== "timestamp") return diag(node, "Expected left side to be a date or timestamp", errExpr2);
|
|
1052
|
-
let units = left2.type === "timestamp" ? "second" : "day";
|
|
1053
|
-
if (right2.node == "stringLiteral") {
|
|
1054
|
-
units = parseTemporal(right2);
|
|
1055
|
-
if (right2.node == "stringLiteral") {
|
|
1056
|
-
return diag(node, "Could not parse interval", errExpr2);
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
1063
|
if (right2.type == "date" || right2.type == "timestamp") {
|
|
1060
1064
|
if (op !== "-") return diag(node, "Only subtraction between dates is supported", errExpr2);
|
|
1061
1065
|
if (right2.type !== left2.type) return diag(node, `Expected right side to be a ${left2.type}`, errExpr2);
|
|
1066
|
+
let units = left2.type === "timestamp" ? "second" : "day";
|
|
1062
1067
|
return { node: "timeDiff", kids: { left: left2, right: right2 }, units, type: "interval", isAgg: false };
|
|
1063
1068
|
}
|
|
1064
1069
|
if (right2.type == "interval") {
|
|
1065
1070
|
let typeDef = { type: left2.type };
|
|
1071
|
+
let units = right2.intervalUnit;
|
|
1072
|
+
if (!units) return diag(node, "Interval must have a unit", errExpr2);
|
|
1066
1073
|
return { node: "delta", kids: { base: left2, delta: right2 }, op, units, type: left2.type, typeDef, isAgg: false };
|
|
1067
1074
|
}
|
|
1068
|
-
return diag(node, "Expected right side to be a date or interval", errExpr2);
|
|
1075
|
+
return diag(node, "Expected right side to be a date, timestamp, or interval", errExpr2);
|
|
1069
1076
|
}
|
|
1070
1077
|
function ensureSameType(left2, leftNode, right2, rightNode) {
|
|
1071
1078
|
if (left2.type === "error" || right2.type === "error") return;
|
|
1072
1079
|
if (left2.node === "parameter" || right2.node === "parameter") return;
|
|
1073
|
-
if (isTemporalType(left2.type)) checkTypes(right2, [left2.type], rightNode);
|
|
1074
|
-
if (isTemporalType(right2.type)) checkTypes(left2, [right2.type], leftNode);
|
|
1075
1080
|
if (left2.type !== right2.type) diag(rightNode, `Expected ${left2.type}, got ${right2.type}`);
|
|
1076
1081
|
}
|
|
1077
1082
|
function checkTypes(expr, expected, node) {
|
|
@@ -1079,17 +1084,7 @@ function checkTypes(expr, expected, node) {
|
|
|
1079
1084
|
if (expr.node === "parameter") return;
|
|
1080
1085
|
if (expected.includes(expr.type)) return;
|
|
1081
1086
|
if (expected.includes("generic")) return;
|
|
1082
|
-
|
|
1083
|
-
if (expr.node == "stringLiteral" && dt) {
|
|
1084
|
-
let parsed = parseTemporalLiteral(expr.literal, dt);
|
|
1085
|
-
if (!parsed) return diag(node, `Could not parse ${dt} literal: "${expr.literal}"`, void 0);
|
|
1086
|
-
let typeDef = { type: parsed.type, timeframe: parsed.timeframe };
|
|
1087
|
-
Object.assign(expr, { node: "timeLiteral", literal: parsed?.literal, type: parsed?.type, typeDef });
|
|
1088
|
-
} else if (expr.node == "stringLiteral" && expected.includes("interval")) {
|
|
1089
|
-
let parsed = parseIntervalLiteral(expr.literal);
|
|
1090
|
-
if (!parsed) return diag(node, `Could not parse interval literal: "${expr.literal}"`, void 0);
|
|
1091
|
-
return Object.assign(expr, { node: "numberLiteral", literal: parsed.quantity.toString(), type: "interval", intervalUnit: parsed.unit });
|
|
1092
|
-
} else diag(node, `Expected types: ${expected.join(", ")}`);
|
|
1087
|
+
diag(node, `Expected types: ${expected.join(", ")}`);
|
|
1093
1088
|
}
|
|
1094
1089
|
function lookupField(expr, scope) {
|
|
1095
1090
|
let pathNodes = expr.getChildren("Identifier");
|
|
@@ -1247,40 +1242,43 @@ var init_analyze = __esm({
|
|
|
1247
1242
|
});
|
|
1248
1243
|
|
|
1249
1244
|
// ../lang/parser.terms.js
|
|
1250
|
-
var table, primary_key, join, as, on, or, and, like, not, _in, from, inner, left, right, full, cross, select, where, group, by, order, asc, desc, limit, offset, is, _null, exists, _true, _false;
|
|
1245
|
+
var table, date, timestamp, interval, primary_key, join, as, on, or, and, like, not, _in, from, inner, left, right, full, cross, select, where, group, by, order, asc, desc, limit, offset, is, _null, exists, _true, _false;
|
|
1251
1246
|
var init_parser_terms = __esm({
|
|
1252
1247
|
"../lang/parser.terms.js"() {
|
|
1253
1248
|
"use strict";
|
|
1254
1249
|
table = 5;
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1250
|
+
date = 10;
|
|
1251
|
+
timestamp = 12;
|
|
1252
|
+
interval = 14;
|
|
1253
|
+
primary_key = 17;
|
|
1254
|
+
join = 21;
|
|
1255
|
+
as = 27;
|
|
1256
|
+
on = 30;
|
|
1257
|
+
or = 39;
|
|
1258
|
+
and = 43;
|
|
1259
|
+
like = 52;
|
|
1260
|
+
not = 54;
|
|
1261
|
+
_in = 64;
|
|
1262
|
+
from = 69;
|
|
1263
|
+
inner = 75;
|
|
1264
|
+
left = 77;
|
|
1265
|
+
right = 79;
|
|
1266
|
+
full = 81;
|
|
1267
|
+
cross = 83;
|
|
1268
|
+
select = 86;
|
|
1269
|
+
where = 93;
|
|
1270
|
+
group = 96;
|
|
1271
|
+
by = 98;
|
|
1272
|
+
order = 104;
|
|
1273
|
+
asc = 108;
|
|
1274
|
+
desc = 110;
|
|
1275
|
+
limit = 113;
|
|
1276
|
+
offset = 115;
|
|
1277
|
+
is = 118;
|
|
1278
|
+
_null = 120;
|
|
1279
|
+
exists = 138;
|
|
1280
|
+
_true = 142;
|
|
1281
|
+
_false = 144;
|
|
1284
1282
|
}
|
|
1285
1283
|
});
|
|
1286
1284
|
|
|
@@ -1324,7 +1322,10 @@ var init_tokens = __esm({
|
|
|
1324
1322
|
offset,
|
|
1325
1323
|
table,
|
|
1326
1324
|
exists,
|
|
1327
|
-
primary_key
|
|
1325
|
+
primary_key,
|
|
1326
|
+
interval,
|
|
1327
|
+
date,
|
|
1328
|
+
timestamp
|
|
1328
1329
|
};
|
|
1329
1330
|
}
|
|
1330
1331
|
});
|
|
@@ -1336,24 +1337,24 @@ var init_parser = __esm({
|
|
|
1336
1337
|
"../lang/parser.js"() {
|
|
1337
1338
|
"use strict";
|
|
1338
1339
|
init_tokens();
|
|
1339
|
-
spec_Identifier = { __proto__: null, table: 10, primary_key:
|
|
1340
|
+
spec_Identifier = { __proto__: null, table: 10, date: 20, timestamp: 24, interval: 28, primary_key: 34, join: 42, one: 46, many: 50, as: 54, on: 60, or: 78, and: 86, like: 104, not: 108, in: 128, from: 138, inner: 150, left: 154, right: 158, full: 162, cross: 166, select: 172, distinct: 176, where: 186, group: 192, by: 196, having: 202, order: 208, asc: 216, desc: 220, limit: 226, offset: 230, is: 236, null: 240, case: 250, when: 256, then: 260, else: 266, end: 270, exists: 276, true: 284, false: 288, count: 298, extract: 304, cast: 312, extend: 338 };
|
|
1340
1341
|
parser = LRParser.deserialize({
|
|
1341
1342
|
version: 14,
|
|
1342
|
-
states: "
|
|
1343
|
-
stateData: "
|
|
1344
|
-
goto: "
|
|
1345
|
-
nodeNames: "\u26A0 Program TableStatement Kw Identifier table Ref ColumnDef DataType PrimaryKey Kw primary_key JoinDef JoinType Kw join Kw one Kw many Kw as Alias Kw on BinaryExpression = ComputedDef TypeCastExpression :: CastType BinaryExpression Kw or TypeCastExpression BinaryExpression Kw and ComparisonOp != <> < > <= >= Kw like Kw not AddOp + - MulOp * / % InExpression Kw in InValueList QueryStatement FromClause Kw from TableName Subquery SubqueryExpression JoinClause Kw inner Kw left Kw right Kw full Kw cross SelectClause Kw select Kw distinct SelectItem Wildcard WhereClause Kw where GroupByClause Kw group Kw by HavingClause Kw having OrderByClause Kw order OrderItem Number Kw asc Kw desc LimitClause Kw limit Kw offset NullTestExpression Kw is Kw null UnaryExpression UnaryOperator CaseExpression Kw case WhenClause Kw when Kw then ElseClause Kw else Kw end ExistsExpression Kw exists String Boolean Kw true Kw false Null FunctionCall Count Kw count ExtractExpression Kw extract ExtractUnit CastExpression Kw cast Param Parenthetical InExpression NullTestExpression : ViewStatement ExtendStatement Kw extend",
|
|
1346
|
-
maxTerm:
|
|
1343
|
+
states: "JfQYQPOOOOQO'#C_'#C_OOQO'#Dr'#DrOwQPO'#DqOOQO'#ET'#ETO#aQPO'#ESOOQO'#E['#E[OOQO'#E_'#E_O#hQPO'#E^OOQO'#Ed'#EdOOQO'#Eg'#EgO#hQPO'#EfOOQO'#Ep'#EpO#mQPO'#EoOOQO'#GQ'#GQO$ZQPO'#DpO$hQPO'#C^OOQO'#Fz'#FzO$hQPO'#FyO$mQPO'#F|QYQPOOQ%bQPO'#F|O%gQPO'#EZO%gQPO'#EcO)^QPO'#CbO)hQPO'#CbO)mQPO'#DtO#rQPO'#DvO*zQPO'#DuOOQO'#Gb'#GbO,mQPO,5:]O-aQPO'#CbO.sQPO'#CbOOQO'#Ce'#CeOOQO'#Cg'#CgOOQO'#Ci'#CiO0]QPO'#EXOOQO'#Dc'#DcO1VQPO'#DvOOQO'#EV'#EVOOQO'#EY'#EYOOQO'#EX'#EXO1pQPO,5:nO!PQPO,5:nOOQO'#Ew'#EwOOQO'#Ez'#EzOOQO'#E|'#E|O2eQPO'#E{OOQO'#FZ'#FZO2lQPO'#FYOOQO'#F_'#F_OOQO'#Fa'#FaOOQO'#F^'#F^OOQO'#Fc'#FcOOQO'#Gf'#GfOOQO'#Ff'#FfO2qQPO'#FeOOQO'#Ge'#GeOOQO'#Fi'#FiOOQO'#Fm'#FmO2vQPO'#FoO3OQPO'#FqO3TQPO'#FrOOQO'#Gd'#GdOOQO'#Gg'#GgOOQO'#G`'#G`O%gQPO'#EyO3YQPO'#FhO3_QPO'#FlOOQO'#Ea'#EaO!PQPO,5:xO3dQPO,5;QO3lQPO,5;ZOOQO-E:O-E:OO4aQPO,58xO4iQPO,5<eOOQO,5<h,5<hOOQO-E9z-E9zO4nQPO,5:uO5bQPO,5:}OOQO,5<i,5<iO6UQPO,58|OOQO-E9{-E9{OOQO'#Cv'#CvOOQO'#Cx'#CxOOQO,5:`,5:`O:PQPO,5:`O:UQPO,5:bOOQO,5:a,5:aO:PQPO,5:aOOQO'#Cp'#CpOOQO'#Dx'#DxOOQO'#Dz'#DzOOQO'#D|'#D|OOQO'#EO'#EOOOQO'#EQ'#EQOwQPO'#DwO:ZQPO'#DwOOQO'#GR'#GRO:`QPO1G/wO;SQPO,5<OOOQO,5:t,5:tOOQO'#DS'#DSO;ZQPO,59pOOQO'#DW'#DWOOQO'#Da'#DaOOQO'#DY'#DYO;iQPO,5:WOOQO'#De'#DeOOQO'#Dh'#DhOOQO'#Dm'#DmO;qQPO,5:WOOQO'#Eu'#EuO;vQPO,5;`O%gQPO,59qO%gQPO,59qO%gQPO,59qO%gQPO,59qO%gQPO,59qOOQO,5:s,5:sO:PQPO,5:sO<OQPO,5<`O<VQPO1G0YO<yQPO1G0YO<yQPO1G0YO=nQPO,5;gOOQO'#FP'#FPOOQO'#GU'#GUO=uQPO,5;gO%gQPO'#FOO#rQPO,5;tO>QQPO,5<POOQO,5<Z,5<ZO>_QPO,5<ZOOQO,5<],5<]OOQO,5<^,5<^O>dQPO,5;eOBUQPO,5<SO%gQPO,5<WOB^QPO1G0dOCRQPO'#EiOC|QPO1G0lOOQO'#Er'#ErODqQPO1G0uODvQPO1G.dOFTQPO1G2OOFYQPO1G2PPGgQPO'#F}OOQO1G/z1G/zOOQO1G/|1G/|OOQO1G/{1G/{OGlQPO,5:cOwQPO,5:cOOQO-E:P-E:POHsQPO1G1jOOQO1G1j1G1jOOQO'#DQ'#DQOOQO1G/[1G/[OOQO,59t,59tOH}QPO1G/rO1VQPO1G/rOOQO1G0z1G0zO;yQPO1G0zOLqQPO1G/]OLxQPO1G/]O!!kQPO1G/]O!!uQPO1G/]O!#PQPO1G/]OOQO1G0_1G0_OOQO1G1z1G1zOOQO,5<n,5<nO!&qQPO7+%tOOQO-E:Q-E:QO!'eQPO7+%tO=uQPO1G1ROOQO-E:S-E:SOOQO'#FU'#FUOOQO'#FW'#FWOOQO1G1R1G1RO={QPO1G1RO%gQPO'#FTO!(YQPO,5;jO!(aQPO1G1`O!(fQPO1G1kOOQO1G1k1G1kO!(mQPO1G1kO%gQPO1G1kOOQO'#Fp'#FpOOQO1G1u1G1uOOQO'#Fk'#FkO!(rQPO1G1nO.{QPO1G1rO!(wQPO7+&OO!)kQPO7+&OOOQO'#Ek'#EkOOQO'#Em'#EmOOQO,5;T,5;TO!+QQPO7+&WO!+[QPO7+&WOOQO7+&a7+&aO!,|QPO'#CbO!-^QPO'#CoO$hQPO'#CnO!.pQPO'#C}OOQO'#G_'#G_OOQO'#G^'#G^O!.zQPO'#GOO!0_QPO7+$OO!0fQPO'#C}O#rQPO7+'jO!+cQPO'#CbOOQO'#Gi'#GiO!0kQPO'#GVO!2OQPO7+'kOOQO'#Cy'#CyO%gQPO1G/}O!2VQPO1G/}O!3^QPO7+'UO!3fQPO7+'UOOQO7+'U7+'UO1VQPO7+%^O!3mQPO'#DoO!3wQPO7+%^OOQO7+&f7+&fP!PQPO'#GSO!3|QPO<<I`OOQO7+&m7+&mO={QPO7+&mO!4pQPO,5;oOOQO'#FR'#FRO%gQPO1G1UOOQO7+&z7+&zOOQO7+'V7+'VO!4wQPO7+'VO%gQPO7+'YO;ZQPO7+'^O!5OQPO<<IjOOQO,5<o,5<oO!5rQPO<<IrOOQO-E:R-E:ROOQO'#Cd'#CdO!6jQPO,58}OOQO'#Cr'#CrOOQO'#Ct'#CtOOQO,59Z,59ZO!8QQPO,59YO;ZQPO,59jO;iQPO,5<aO!8YQPO,5<aO;vQPO,5<bO%gQPO,59mO%gQPO,59mO%gQPO,59mO%gQPO,59mO%gQPO,59mO:PQPO,59iOOQO,5<j,5<jOOQO-E9|-E9|OOQO<<Gj<<GjO%gQPO,59iO!8_QPO<<KUOOQO,5<q,5<qOOQO-E:T-E:TOOQO<<KV<<KVO!8dQPO7+%iO%gQPO7+%iOOQO-E9}-E9}O!9jQPO<<JpOOQO<<Jp<<JpO!9qQPO,5<kO!9{QPO<<HxO!:QQPO,5:ZO!:YQPO,5:ZOOQO<<Hx<<HxOOQO<<JX<<JXO!:aQPO7+&pOOQO<<Jq<<JqO!:nQPO<<JtO!:uQPO<<JxP3dQPO'#GTOOQO'#Cl'#ClOOQO'#Ck'#CkOOQO1G.i1G.iO$hQPO1G.tO:PQPO1G.tOOQO1G/U1G/UO!:zQPO1G1{O1VQPO1G1{OOQO1G1|1G1|O;yQPO1G1|O!<^QPO1G/XO!<eQPO1G/XO!=vQPO1G/XO!>QQPO1G/XO!>[QPO1G/XOOQO1G/T1G/TO!?lQPO1G/TOOQOAN@pAN@pO!@xQPO<<ITP%gQPO'#GPOOQOAN@[AN@[OOQOAN>dAN>dO!BOQPO1G/uOOQOAN@`AN@`OOQOAN@dAN@dO!BVQPO'#C{OOQO7+$`7+$`O!8TQPO7+$`O1VQPO7+'gO!B[QPO7+'gOOQO7+'h7+'hO$hQPO,59gO$hQPO<<GzO!BaQPO<<KROOQO<<KR<<KROOQO1G/R1G/ROOQOAN=fAN=fOOQOAN@mAN@m",
|
|
1344
|
+
stateData: "!Bm~O$|OS$}OS~OTPO!gQO!xSO#PUO#SVO#XXO#[YO#e[O$oaO~OShO%PkO~OSoOYqO[rO^sO!WuO!Y}O!Z}O!]xO#^!WO#l|O#q!OO$O!QO$P!WO$S!SO$U!TO$Z!XO$^![O$b!]O$g!aO%PvO~O!zwO~P!PO#U!gO~O#^!jO~O!gQO!xSO#PUO#SVO#XXO#[YO#e[O~O$z!dX%[!dX%V!dX~P#rOShO~O%[!nOT$pX!g$pX!x$pX#P$pX#S$pX#X$pX#[$pX#e$pX$o$pX$z$pX~O%[!nO~OSoOYqO[rO^sO!WuO!Y}O!Z}O#^!WO#l|O#q!OO$O!QO$P!WO$S!SO$U!TO$Z!XO$^![O$b!]O$g!aO%PvO~O%O!rOSUXeUXkUX!gUX!mUX!oUX!qUX!sUX!uUX!xUX#PUX#SUX#XUX#[UX#eUX$zUX%[UX%VUXpUXYUX[UX^UX!WUX!YUX!ZUX#^UX#lUX#qUX$OUX$PUX$SUX$UUX$ZUX$^UX$bUX$gUX%TUX~O%PUXnUX~P&tOS!sO~OS!vOk!uOe!hX!g!hX!m!hX!o!hX!q!hX!s!hX!u!hX!x!hX#P!hX#S!hX#X!hX#[!hX#e!hX$z!hX%[!hX%V!hXn!hX~OS!vOk!uOe!iX!g!iX!m!iX!o!iX!q!iX!s!iX!u!iX!x!iX#P!iX#S!iX#X!iX#[!iX#e!iX$z!iX%[!iX%V!iXn!iX~Oe!|O!m!}O!o#OO!q#PO!s#QO!u#RO~O!g!ea!x!ea#P!ea#S!ea#X!ea#[!ea#e!ea$z!ea%[!ea%V!ea~P,XO%P#WOsUXwUX{UX}UX!OUX!PUX!QUX!RUX!SUX!UUX!]UX!^UX!_UX!bUX#jUX#tUX#vUX#{UX#yUX~P&tOS!sO!]#XO~Ok!uOp#^Os#ZOw#YO{#[O}#^O!O#^O!P#^O!Q#^O!R#^O!S#^O!U#]O!WuO!Y#`O!Z#`O!]#aO!^#aO!_#aO!b#bO#j#dO~OS!vO!g!{X!x!{X#P!{X#S!{X#X!{X#[!{X#e!{X$z!{X%T!{X%[!{X%V!{X~P.{O!gQO!xSO#PUO#SVO#XXO#[YO#e[O~P%gO%T#nO!g!va!x!va#P!va#S!va#X!va#[!va#e!va$z!va%[!va%V!va~O#t#rO~P%gO%P#vO~O%P#wO~O#^#yO$P#xO~O$P#zO~O$P#{O~O%P#}O~O%P$OO~OS$QO#^$QO~O#g$SO!g#ca!x#ca#P#ca#S#ca#X#ca#[#ca#e#ca$z#ca%[#ca%V#ca~Ok!uO%P$UO~O%P$WO~O!g!}a!x!}a#P!}a#S!}a#X!}a#[!}a#e!}a$z!}a%[!}a%V!}a~P/OO!g#Va!x#Va#P#Va#S#Va#X#Va#[#Va#e#Va$z#Va%[#Va%V#Va~P/OO%O!rOSUaeUakUa!gUa!mUa!oUa!qUa!sUa!uUa!xUa#PUa#SUa#XUa#[Ua#eUa$zUa%[UapUasUawUa{Ua}Ua!OUa!PUa!QUa!RUa!SUa!UUa!WUa!YUa!ZUa!]Ua!^Ua!_Ua!bUa#jUa%TUa%PUa%VUa#tUanUa#vUa#{Ua#yUaYUa[Ua^Ua#^Ua#lUa#qUa$OUa$PUa$SUa$UUa$ZUa$^Ua$bUa$gUa~OS!vO~O%V$ZO~Oe!|O~O!g!ei!x!ei#P!ei#S!ei#X!ei#[!ei#e!ei$z!ei%[!ei%V!ei~P,XO%V$aO~P%gOS$bOYqO[rO^sO~O!U#]O!b#bO~O%P$fO~O!WuO#l|O~O%V$oO~P/OO!g!vi!x!vi#P!vi#S!vi#X!vi#[!vi#e!vi$z!vi%[!vi%V!vi~P!PO%T$qO!g!vi!x!vi#P!vi#S!vi#X!vi#[!vi#e!vi$z!vi%[!vi%V!vi~O#t#rO~P/OO#t#rO#y$vO#{$wO~O!]%PO!zwO%V%OO~P%gOS%RO~Os#ZOS#mak#map#maw#ma{#ma}#ma!O#ma!P#ma!Q#ma!R#ma!S#ma!U#ma!W#ma!Y#ma!Z#ma!]#ma!^#ma!_#ma!b#ma!g#ma!x#ma#P#ma#S#ma#X#ma#[#ma#e#ma#j#ma$z#ma%T#ma%[#ma%V#ma#t#ma#v#ma#{#mae#ma!m#ma!o#ma!q#ma!s#ma!u#ma#y#maY#ma[#ma^#ma#^#ma#l#ma#q#ma$O#ma$P#ma$S#ma$U#ma$Z#ma$^#ma$b#ma$g#ma~OS%TO$P%TO~O%T%WO!g#Qi!x#Qi#P#Qi#S#Qi#X#Qi#[#Qi#e#Qi$z#Qi%[#Qi%V#Qi~O#`%YO#b%ZO!g#]X!x#]X#P#]X#S#]X#X#]X#[#]X#e#]X$z#]X%T#]X%[#]X%V#]X~O%T%]O!g#Yi!x#Yi#P#Yi#S#Yi#X#Yi#[#Yi#e#Yi$z#Yi%[#Yi%V#Yi~O#^%_O~OS%`OYqO[rO^sOe!|O!WuO!Y}O!Z}O#^!WO#l|O#q!OO$O!QO$P!WO$S!SO$U!TO$Z!XO$^![O$b!]O$g!aO~O%P%iO~OS%jOYqO[rO^sOe!|O!WuO!Y}O!Z}O#^!WO#l|O#q!OO$O!QO$P!WO$S!SO$U!TO$Z!XO$^![O$b!]O$g!aO~O%O!rO~On%nOe!ka!g!ka!m!ka!o!ka!q!ka!s!ka!u!ka!x!ka#P!ka#S!ka#X!ka#[!ka#e!ka$z!ka%[!ka%V!ka~O%T%rO%V%sO~P/OO%P%tO~Op#^Os#ZO}#^O!O#^O!P#^O!Q#^O!R#^O!S#^O!U#]O!WuO!Y#`O!Z#`O!]#aO!^#aO!_#aO!b#bO#j#dOSyikyiwyi!gyi!xyi#Pyi#Syi#Xyi#[yi#eyi$zyi%Tyi%[yi%Vyi#tyi#vyi#{yieyi!myi!oyi!qyi!syi!uyi#yyiYyi[yi^yi#^yi#lyi#qyi$Oyi$Pyi$Syi$Uyi$Zyi$^yi$byi$gyi~O{#[O~PISO{yi~PISOs#ZO!]#aO!^#aO!_#aOSyikyipyiwyi{yi}yi!Oyi!Pyi!Qyi!Ryi!Syi!Uyi!Wyi!byi!gyi!xyi#Pyi#Syi#Xyi#[yi#eyi#jyi$zyi%Tyi%[yi%Vyi#tyi#vyi#{yieyi!myi!oyi!qyi!syi!uyi#yyiYyi[yi^yi#^yi#lyi#qyi$Oyi$Pyi$Syi$Uyi$Zyi$^yi$byi$gyi~O!Y#`O!Z#`O~PMPO!Yyi!Zyi~PMPOs#ZOSyikyipyiwyi{yi}yi!Oyi!Pyi!Qyi!Ryi!Syi!Uyi!Wyi!Yyi!Zyi!]yi!^yi!_yi!byi!gyi!xyi#Pyi#Syi#Xyi#[yi#eyi#jyi$zyi%Tyi%[yi%Vyi#tyi#vyi#{yieyi!myi!oyi!qyi!syi!uyi#yyiYyi[yi^yi#^yi#lyi#qyi$Oyi$Pyi$Syi$Uyi$Zyi$^yi$byi$gyi~O!g!vq!x!vq#P!vq#S!vq#X!vq#[!vq#e!vq$z!vq%[!vq%V!vq~P!PO%T%yO!g!vq!x!vq#P!vq#S!vq#X!vq#[!vq#e!vq$z!vq%[!vq%V!vq~O#v%}O~P/OO%V&PO~O%V&QO~P/OO%V&QO~O!gQO~O!g#Qq!x#Qq#P#Qq#S#Qq#X#Qq#[#Qq#e#Qq$z#Qq%[#Qq%V#Qq~P!PO%T&UO!g#Qq!x#Qq#P#Qq#S#Qq#X#Qq#[#Qq#e#Qq$z#Qq%[#Qq%V#Qq~O!g#Yq!x#Yq#P#Yq#S#Yq#X#Yq#[#Yq#e#Yq$z#Yq%[#Yq%V#Yq~OS$QO#^$QO~P!*`O%T&WO~P!*`O%O!rO%P#WOkUXpUXsUXwUX{UX}UX!OUX!PUX!QUX!RUX!SUX!UUX!WUX!YUX!ZUX!]UX!^UX!_UX!bUX#jUX$klX~OS&YOYqO[rO^sO~P!+cOg&[Oi&]O~Op#^Ow#YO{#[O}#^O!O#^O!P#^O!Q#^O!R#^O!S#^O!U#]O!WuO!Y#`O!Z#`O!]#aO!^#aO!_#aO!b#bO#j#dO~Ok!uOs&`O~P!-fO%T&jOS$rXY$rX[$rX^$rXe$rX!W$rX!Y$rX!Z$rX#^$rX#l$rX#q$rX$O$rX$P$rX$S$rX$U$rX$Z$rX$^$rX$b$rX$g$rX%V$rX~O%V&lO~PDvO$k&mO~O%T&oOS$yXY$yX[$yX^$yXe$yX!W$yX!Y$yX!Z$yX#^$yX#l$yX#q$yX$O$yX$P$yX$S$yX$U$yX$Z$yX$^$yX$b$yX$g$yX%V$yX~O%V&qO~PFYOn%nOe!ki!g!ki!m!ki!o!ki!q!ki!s!ki!u!ki!x!ki#P!ki#S!ki#X!ki#[!ki#e!ki$z!ki%[!ki%V!ki~O%T&uO%V&vO~O%V&vO~P%gO%T&zO%V!cX~P/OO%V&{O~O!g!vy!x!vy#P!vy#S!vy#X!vy#[!vy#e!vy$z!vy%[!vy%V!vy~P!PO#{#wa~P/OO%V'OO~P/OO!g#Qy!x#Qy#P#Qy#S#Qy#X#Qy#[#Qy#e#Qy$z#Qy%[#Qy%V#Qy~P!POS$QO#^$QO!g#Yy!x#Yy#P#Yy#S#Yy#X#Yy#[#Yy#e#Yy$z#Yy%[#Yy%V#Yy~Oa'SOSVaYVa[Va^VaeVa!WVa!YVa!ZVa#^Va#lVa#qVa$OVa$PVa$SVa$UVa$ZVa$^Va$bVa$gVa%TVa%VVa~Ok!uOn%nO~O%P'ZO~O%V'eO~Oe!kq!g!kq!m!kq!o!kq!q!kq!s!kq!u!kq!x!kq#P!kq#S!kq#X!kq#[!kq#e!kq$z!kq%[!kq%V!kq~P/OO%V'hO~P%gO%T$sa%V$sa~P/OO%V'iO~O%T'jO%V!ca~O%V!ca~P%gO#t#rq#y#rq#{#rq~P/OO%V'kO~P/OO%V'lO~O%P'pO~Op#^Os#ZO}#^O!O#^O!P#^O!Q#^O!R#^O!S#^O!U#]O!WuO!Y#`O!Z#`O!]#aO!^#aO!_#aO!b#bO#j#dOkuiwui~O{#[O~P!;PO{ui~P!;POs#ZO!]#aO!^#aO!_#aOkuipuiwui{ui}ui!Oui!Pui!Qui!Rui!Sui!Uui!Wui!bui#jui~O!Y#`O!Z#`O~P!<lO!Yui!Zui~P!<lOs#ZOkuipuiwui{ui}ui!Oui!Pui!Qui!Rui!Sui!Uui!Wui!Yui!Zui!]ui!^ui!_ui!bui#jui~OSqiYqi[qi^qieqi#^qi#lqi#qqi$Oqi$Pqi$Sqi$Uqi$Zqi$^qi$bqi$gqi%Tqi%Vqi~P/OOe!ky!g!ky!m!ky!o!ky!q!ky!s!ky!u!ky!x!ky#P!ky#S!ky#X!ky#[!ky#e!ky$z!ky%[!ky%V!ky~P/OO%V!ci~P%gOp'sO~O%V'vO~O%V'yO~O$}!Zs$k!]!^~",
|
|
1345
|
+
goto: "! V%^PP%_%cPP%g'Q'U'XP(eP)qP*}+QP+T+]+cP+pP+pP+sP,Y,xP-UP+T-[P-b-[-kP.S.S/SP/mPPPPPP0YP0wP2nPP3]PPP.S3|P4o4{5g5tP6U6U6Z7`7dP7dP7dP7dP7dP5g7hP7uP7{8^5g8iP5g8vP9TP5g9ZP5g9hP9uP9}P9}P5g:QP:_P.S:bP:}P<_=c<_>gP?k?qP?wP?z@QP@UP<_@`PPAdBhPBhPAdClClDpP<_EtPFx<_F{P<_HP<_<_P6`-[-[P%_%_HSPHWH^IqIwJRJbJhJvJ|KWPPPPPPK^KbKhPMrPM{<_Cl.SP! RTcOdT`OdUjR#S$^#S!ZTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'pQ!l`Q!mbQ&_%bS'm'V'tR'w'sT%e$U%gR&Z%`#S!_Tfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'pU$b#Z&T&`R&Y%`#S!`Tfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'pU$b#Z&T&`R&Y%`#S!^Tfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'pU$b#Z&T&`R&Y%`R'U&ZR'T&ZS%e$U%gT%k$W%mX%b$U$W%g%mS#Sn#VQ$^#TX%a$U$W%g%mR&^%aQ!xjQ!{lQ#ltQ$V!lQ&T%VQ&i%cR'W&_Q!wjQ!zlQ#ktQ$Y!xQ$[!{Q$n#lW%h$U$W%g%mQ'c&iR'o'WQ%o$]Q&s%pQ'V&_R't'oQ'n'VR'x'tX%d$U$W%g%mQ$c#ZQ'Q&TR'X&`t#ft!p!q#m#q$`${$}%V%u%|&R&r&w&}'P'd'fR&d%c!{!cTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$f$q$z%Q%W%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'px#gt!p!q#m#q$`$i${$}%V%u%|&R&r&w&}'P'^'d'fR&e%c|#ht!p!q#m#q$`$i$j${$}%V%u%|&R&r&w&}'P'^'_'d'fR&f%c!O#^t!p!q#m#q$`$i$j${$}%V%c%u%|&R&r&w&}'P'^'_'d'fT$d#_&a#S}Tfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'p|#_t!p!q#m#q$`$i$j${$}%V%u%|&R&r&w&}'P'^'_'d'fQ$h#eQ&a%cR']&c!Q#it!p!q#m#q$`$i$j$k${$}%V%u%|&R&r&w&}'P'^'_'`'d'fR&g%c!U#jt!p!q#m#q$`$i$j$k$l${$}%V%u%|&R&r&w&}'P'^'_'`'a'd'fR&h%c|#ct!p!q#m#q$`$i$j${$}%V%u%|&R&r&w&}'P'^'_'d'fQ$e#_Q&b%cR'Y&aQ%v$fQ&x%tQ'q'ZR'u'pSeOdS!ykvQ$|#vQ%v$fQ&n%iQ&x%tQ'q'ZR'u'pg^O_dkv#v$f%i%t'Z'pfRO_dkv#v$f%i%t'Z'pR&S%UVmR#S$^UlR#S$^!{!bTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$f$q$z%Q%W%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'pT#Un#VT#Tn#VgTO_dkv#v$f%i%t'Z'pQ{TR%Q#wQzTQ#p{Q$P!h]$p#n$q%W%x%y&UcyT{!h#n$q%W%x%y&UgfO_dkv#v$f%i%t'Z'pgWO_dkv#v$f%i%t'Z'pQ!hWR!iZggO_dkv#v$f%i%t'Z'pgZO_dkv#v$f%i%t'Z'pQ$R!iV&V%]&W'RR%[$Qg]O_dkv#v$f%i%t'Z'pR$T!j|#et!p!q#m#q$`$i$j${$}%V%u%|&R&r&w&}'P'^'_'d'fR&c%c#S!VTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'pQ$g#eQ%w$hQ'[&cR'r']#T!aTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'p#T!dTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'p#T!PTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'pX#s!P#q#t$tX#u!P#q#t$tR&O${Q$y#tR%{$tT$z#t$tQ$x#tS%z$t$yR&|%{#T!RTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'p#T!WTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'p#T!UTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'p#T!ZTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'p#T!YTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'p#T!eTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'pR%U#}#T!fTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$U$W$f$q$z%Q%W%g%m%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'pR%S#yTbOdQdOR!od#SiR`bfgv!P!d#S#W#f#g#h#i#j#u#w$O$U$W$^$f$z%Q%b%g%m%o%r%t&O&S&d&e&f&g&h&m&s&u&z'V'Z'g'j'p's'tbpT{!h#n$q%W%x%y&UT!tipQ%g$UR&k%gQ%q$`S&t%q&yR&y%ud_Odkv#v$f%i%t'Z'pR!k_Q#VnR$_#VQ#ozU$r#o$s%XQ$s#pR%X$PQ%^$RR&X%^Q#t!PQ$t#qT$u#t$tQ%m$WR&p%mT%f$U%gX%c$U$W%g%mbtT{!h#n$q%W%x%y&UQ!pfQ!qgQ#mvQ#q!PQ#|!dQ$`#WQ$i#fQ$j#gQ$k#hQ$l#iQ$m#jQ${#uQ$}#wQ%V$OW%u$f%t'Z'pQ%|$zQ&R%QQ&r%oY&w%r&u&z'g'jQ&}&OQ'P&SQ'^&dQ'_&eQ'`&fQ'a&gQ'b&hQ'd&mR'f&sQnRQ$]#SR%p$^!z!cTfgv{!P!d!h#W#f#g#h#i#j#n#u#w$O$f$q$z%Q%W%o%r%t%x%y&O&S&U&d&e&f&g&h&m&s&u&z'Z'g'j'pX%d$U$W%g%mT%l$W%m",
|
|
1346
|
+
nodeNames: "\u26A0 Program TableStatement Kw Identifier table Ref ColumnDef DataType Kw date Kw timestamp Kw interval PrimaryKey Kw primary_key JoinDef JoinType Kw join Kw one Kw many Kw as Alias Kw on BinaryExpression = ComputedDef TypeCastExpression :: CastType BinaryExpression Kw or TypeCastExpression BinaryExpression Kw and ComparisonOp != <> < > <= >= Kw like Kw not AddOp + - MulOp * / % InExpression Kw in InValueList QueryStatement FromClause Kw from TableName Subquery SubqueryExpression JoinClause Kw inner Kw left Kw right Kw full Kw cross SelectClause Kw select Kw distinct SelectItem Wildcard WhereClause Kw where GroupByClause Kw group Kw by HavingClause Kw having OrderByClause Kw order OrderItem Number Kw asc Kw desc LimitClause Kw limit Kw offset NullTestExpression Kw is Kw null UnaryExpression UnaryOperator CaseExpression Kw case WhenClause Kw when Kw then ElseClause Kw else Kw end ExistsExpression Kw exists String Boolean Kw true Kw false Null FunctionCall Count Kw count ExtractExpression Kw extract ExtractUnit CastExpression Kw cast IntervalExpression IntervalUnit DateExpression TimestampExpression Param Parenthetical InExpression NullTestExpression : ViewStatement ExtendStatement Kw extend",
|
|
1347
|
+
maxTerm: 197,
|
|
1347
1348
|
nodeProps: [
|
|
1348
|
-
["group", -
|
|
1349
|
+
["group", -16, 6, 106, 121, 123, 136, 139, 140, 145, 146, 147, 150, 154, 157, 159, 160, 161, "Expression Expression", -11, 31, 34, 37, 40, 41, 62, 72, 116, 162, 163, 164, "Expression", -2, 70, 71, "TablePrimary"]
|
|
1349
1350
|
],
|
|
1350
1351
|
skippedNodes: [0],
|
|
1351
1352
|
repeatNodeCount: 10,
|
|
1352
|
-
tokenData: "*w~RoX^#Spq#Sqr#wrs$Stu$quv%cwx%hxy&Qyz&Vz{&[{|&a|}&f}!O&k!O!P'[!P!Q'a!Q![(p![!])Z!]!^)h!^!_)m!_!`*S!`!a*X!c!}*f#T#o*f#y#z#S$f$g#S#BY#BZ#S$IS$I_#S$I|$JO#S$JT$JU#S$KV$KW#S&FU&FV#S~#XY
|
|
1353
|
+
tokenData: "*w~RoX^#Spq#Sqr#wrs$Stu$quv%cwx%hxy&Qyz&Vz{&[{|&a|}&f}!O&k!O!P'[!P!Q'a!Q![(p![!])Z!]!^)h!^!_)m!_!`*S!`!a*X!c!}*f#T#o*f#y#z#S$f$g#S#BY#BZ#S$IS$I_#S$I|$JO#S$JT$JU#S$KV$KW#S&FU&FV#S~#XY$|~X^#Spq#S#y#z#S$f$g#S#BY#BZ#S$IS$I_#S$I|$JO#S$JT$JU#S$KV$KW#S&FU&FV#S~#zP!_!`#}~$SO}~~$VTOr$Srs$fs;'S$S;'S;=`$k<%lO$S~$kO$P~~$nP;=`<%l$S~$tS!Q![%Q!c!}%Q#R#S%Q#T#o%Q~%VS$g~!Q![%Q!c!}%Q#R#S%Q#T#o%Q~%hO!_~~%kTOw%hwx$fx;'S%h;'S;=`%z<%lO%h~%}P;=`<%l%h~&VO%P~~&[O%V~~&aO!]~~&fO!Y~~&kO%T~~&pP!Z~}!O&s~&xS$}~OY&sZ;'S&s;'S;=`'U<%lO&s~'XP;=`<%l&s~'aO%O~~'fP!^~z{'i~'lTOz'iz{'{{;'S'i;'S;=`(j<%lO'i~(OVOz'iz{'{{!P'i!P!Q(e!Q;'S'i;'S;=`(j<%lO'i~(jO$}~~(mP;=`<%l'i~(uQ#^~!O!P({!Q![(p~)OP!Q![)R~)WP#^~!Q![)R~)`P$k~![!])c~)hOs~~)mO%[~~)rQ!P~!_!`)x!`!a)}~)}O!R~~*SO!O~~*XOp~~*^P!Q~!_!`*a~*fO!S~~*kSS~!Q![*f!c!}*f#R#S*f#T#o*f",
|
|
1353
1354
|
tokenizers: [0],
|
|
1354
1355
|
topRules: { "Program": [0, 1] },
|
|
1355
1356
|
specialized: [{ term: 4, get: (value, stack) => specializeIdentifier(value, stack) << 1, external: specializeIdentifier }, { term: 4, get: (value) => spec_Identifier[value] || -1 }],
|
|
1356
|
-
tokenPrec:
|
|
1357
|
+
tokenPrec: 3656
|
|
1357
1358
|
});
|
|
1358
1359
|
}
|
|
1359
1360
|
});
|
|
@@ -2206,8 +2207,8 @@ __export(bigQuery_exports, {
|
|
|
2206
2207
|
});
|
|
2207
2208
|
import { BigQuery, BigQueryDate, BigQueryTimestamp } from "@google-cloud/bigquery";
|
|
2208
2209
|
import { readFileSync as readFileSync3 } from "fs";
|
|
2209
|
-
function
|
|
2210
|
-
|
|
2210
|
+
function validateBigQueryIdent(ident) {
|
|
2211
|
+
if (!/^[\w.-]+$/.test(ident)) throw new Error(`Invalid BigQuery identifier: ${ident}`);
|
|
2211
2212
|
}
|
|
2212
2213
|
var BigQueryConnection;
|
|
2213
2214
|
var init_bigQuery = __esm({
|
|
@@ -2234,8 +2235,8 @@ var init_bigQuery = __esm({
|
|
|
2234
2235
|
this.client = new BigQuery({ ...options, userAgent: "Graphene" });
|
|
2235
2236
|
this.defaultNamespace = config.namespace;
|
|
2236
2237
|
}
|
|
2237
|
-
async runQuery(sql) {
|
|
2238
|
-
let [job] = await this.client.createQueryJob({ query: sql, useLegacySql: false });
|
|
2238
|
+
async runQuery(sql, params) {
|
|
2239
|
+
let [job] = await this.client.createQueryJob({ query: sql, useLegacySql: false, params });
|
|
2239
2240
|
let [rows] = await job.getQueryResults({ maxResults: 1e4 });
|
|
2240
2241
|
let metadata = job.metadata || (await job.getMetadata())[0];
|
|
2241
2242
|
let totalRows = Number(metadata?.statistics?.query?.totalRows ?? rows.length);
|
|
@@ -2253,6 +2254,7 @@ var init_bigQuery = __esm({
|
|
|
2253
2254
|
}
|
|
2254
2255
|
async listTables(dataset) {
|
|
2255
2256
|
if (!dataset) throw new Error("BigQuery requires a dataset");
|
|
2257
|
+
validateBigQueryIdent(dataset);
|
|
2256
2258
|
let res = await this.runQuery(`select table_schema as table_schema, table_name as table_name
|
|
2257
2259
|
from \`${dataset}.INFORMATION_SCHEMA.TABLES\`
|
|
2258
2260
|
where table_type in ('BASE TABLE', 'VIEW') order by table_name`);
|
|
@@ -2262,13 +2264,14 @@ var init_bigQuery = __esm({
|
|
|
2262
2264
|
let parts = target.split(".");
|
|
2263
2265
|
let table2 = parts.pop() || "";
|
|
2264
2266
|
let dataset = parts.join(".");
|
|
2267
|
+
validateBigQueryIdent(dataset);
|
|
2265
2268
|
let sql = `
|
|
2266
2269
|
select column_name as column_name, data_type as data_type, ordinal_position as ordinal_position
|
|
2267
2270
|
from \`${dataset}.INFORMATION_SCHEMA.COLUMNS\`
|
|
2268
|
-
where lower(table_name) = lower(
|
|
2271
|
+
where lower(table_name) = lower(@table)
|
|
2269
2272
|
order by ordinal_position
|
|
2270
2273
|
`.trim();
|
|
2271
|
-
let res = await this.runQuery(sql);
|
|
2274
|
+
let res = await this.runQuery(sql, { table: table2 });
|
|
2272
2275
|
return res.rows.map((row) => {
|
|
2273
2276
|
return { name: String(row["column_name"]), dataType: String(row["data_type"]) };
|
|
2274
2277
|
});
|
|
@@ -2285,9 +2288,6 @@ __export(duckdb_exports, {
|
|
|
2285
2288
|
import { promises as fs5 } from "fs";
|
|
2286
2289
|
import path6 from "path";
|
|
2287
2290
|
import { DuckDBTimestampValue, DuckDBInstance, DuckDBDateValue } from "@duckdb/node-api";
|
|
2288
|
-
function sqlStringLiteral2(value) {
|
|
2289
|
-
return `'${value.replace(/'/g, "''")}'`;
|
|
2290
|
-
}
|
|
2291
2291
|
var DuckDBConnection;
|
|
2292
2292
|
var init_duckdb = __esm({
|
|
2293
2293
|
"connections/duckdb.ts"() {
|
|
@@ -2315,9 +2315,9 @@ var init_duckdb = __esm({
|
|
|
2315
2315
|
await this.connection.run(`attach '${escapedPath}' as graphene_cli (READ_ONLY);`);
|
|
2316
2316
|
await this.connection.run("use graphene_cli;");
|
|
2317
2317
|
}
|
|
2318
|
-
async runQuery(sql) {
|
|
2318
|
+
async runQuery(sql, params) {
|
|
2319
2319
|
await this.ready;
|
|
2320
|
-
let reader = await this.connection.runAndReadAll(sql);
|
|
2320
|
+
let reader = params ? await this.connection.runAndReadAll(sql, params) : await this.connection.runAndReadAll(sql);
|
|
2321
2321
|
let rows = reader.getRowObjects().map((record) => {
|
|
2322
2322
|
let out = {};
|
|
2323
2323
|
for (let [k, v] of Object.entries(record)) {
|
|
@@ -2349,14 +2349,15 @@ var init_duckdb = __esm({
|
|
|
2349
2349
|
let parts = target.split(".");
|
|
2350
2350
|
let table2 = parts.pop() || "";
|
|
2351
2351
|
let schema = parts[0];
|
|
2352
|
-
let schemaFilter = schema ?
|
|
2352
|
+
let schemaFilter = schema ? "lower(table_schema) = lower($2)" : "table_schema not in ('information_schema', 'pg_catalog')";
|
|
2353
2353
|
let sql = `
|
|
2354
2354
|
select column_name as column_name, data_type as data_type, ordinal_position as ordinal_position
|
|
2355
2355
|
from information_schema.columns
|
|
2356
|
-
where lower(table_name) = lower($
|
|
2356
|
+
where lower(table_name) = lower($1) and ${schemaFilter}
|
|
2357
2357
|
order by ordinal_position
|
|
2358
2358
|
`.trim();
|
|
2359
|
-
let
|
|
2359
|
+
let params = schema ? [table2, schema] : [table2];
|
|
2360
|
+
let res = await this.runQuery(sql, params);
|
|
2360
2361
|
return res.rows.map((row) => {
|
|
2361
2362
|
return { name: String(row["column_name"]), dataType: String(row["data_type"]) };
|
|
2362
2363
|
});
|
|
@@ -2376,9 +2377,6 @@ function snowflakeIdent(value) {
|
|
|
2376
2377
|
if (!value) throw new Error("Snowflake identifiers cannot be empty");
|
|
2377
2378
|
return `"${value.replace(/"/g, '""')}"`;
|
|
2378
2379
|
}
|
|
2379
|
-
function sqlStringLiteral3(value) {
|
|
2380
|
-
return `'${value.replace(/'/g, "''")}'`;
|
|
2381
|
-
}
|
|
2382
2380
|
var SnowflakeConnection;
|
|
2383
2381
|
var init_snowflake2 = __esm({
|
|
2384
2382
|
"connections/snowflake.ts"() {
|
|
@@ -2412,12 +2410,13 @@ var init_snowflake2 = __esm({
|
|
|
2412
2410
|
this.connection.connect((err, conn) => err ? reject(err) : resolve(conn));
|
|
2413
2411
|
});
|
|
2414
2412
|
}
|
|
2415
|
-
async runQuery(sql) {
|
|
2413
|
+
async runQuery(sql, params) {
|
|
2416
2414
|
await this.ready;
|
|
2417
2415
|
return await new Promise((resolve, reject) => {
|
|
2418
2416
|
let rows = [];
|
|
2419
2417
|
this.connection.execute({
|
|
2420
2418
|
sqlText: sql,
|
|
2419
|
+
binds: params,
|
|
2421
2420
|
streamResult: true,
|
|
2422
2421
|
complete: (error, statement) => {
|
|
2423
2422
|
if (error) {
|
|
@@ -2450,9 +2449,9 @@ var init_snowflake2 = __esm({
|
|
|
2450
2449
|
let res = await this.runQuery(`
|
|
2451
2450
|
select table_schema as "table_schema", table_name as "table_name"
|
|
2452
2451
|
from ${snowflakeIdent(database)}.INFORMATION_SCHEMA.TABLES
|
|
2453
|
-
where table_type in ('BASE TABLE', 'VIEW') and table_schema =
|
|
2452
|
+
where table_type in ('BASE TABLE', 'VIEW') and table_schema = ?
|
|
2454
2453
|
order by table_name
|
|
2455
|
-
|
|
2454
|
+
`, [schema]);
|
|
2456
2455
|
return res.rows.map((row) => `${row["table_schema"]}.${row["table_name"]}`);
|
|
2457
2456
|
}
|
|
2458
2457
|
async describeTable(target) {
|
|
@@ -2463,9 +2462,9 @@ var init_snowflake2 = __esm({
|
|
|
2463
2462
|
let res = await this.runQuery(`
|
|
2464
2463
|
select column_name as "column_name", data_type as "data_type", ordinal_position as ordinal_position
|
|
2465
2464
|
from ${snowflakeIdent(database)}.INFORMATION_SCHEMA.COLUMNS
|
|
2466
|
-
where upper(table_schema) = upper(
|
|
2465
|
+
where upper(table_schema) = upper(?) and upper(table_name) = upper(?)
|
|
2467
2466
|
order by ordinal_position
|
|
2468
|
-
|
|
2467
|
+
`, [schema, table2]);
|
|
2469
2468
|
return res.rows.map((row) => {
|
|
2470
2469
|
return { name: String(row["column_name"]).toLowerCase(), dataType: String(row["data_type"]) };
|
|
2471
2470
|
});
|
|
@@ -2489,17 +2488,17 @@ async function getConnection() {
|
|
|
2489
2488
|
throw new Error(`Unsupported dialect: ${config.dialect}`);
|
|
2490
2489
|
}
|
|
2491
2490
|
}
|
|
2492
|
-
async function runQuery(sql) {
|
|
2491
|
+
async function runQuery(sql, params) {
|
|
2493
2492
|
if (config.host) {
|
|
2494
2493
|
let resp = await authenticatedFetch("/_api/query", {
|
|
2495
2494
|
method: "POST",
|
|
2496
2495
|
headers: { "Content-Type": "application/json" },
|
|
2497
|
-
body: JSON.stringify({ sql })
|
|
2496
|
+
body: JSON.stringify({ sql, params })
|
|
2498
2497
|
});
|
|
2499
2498
|
return await resp.json();
|
|
2500
2499
|
}
|
|
2501
2500
|
let conn = await getConnection();
|
|
2502
|
-
return await conn.runQuery(sql);
|
|
2501
|
+
return await conn.runQuery(sql, params);
|
|
2503
2502
|
}
|
|
2504
2503
|
var init_connections = __esm({
|
|
2505
2504
|
"connections/index.ts"() {
|
|
@@ -2838,10 +2837,14 @@ init_auth();
|
|
|
2838
2837
|
import { Command } from "commander";
|
|
2839
2838
|
import fs8 from "fs-extra";
|
|
2840
2839
|
import path9 from "path";
|
|
2840
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
2841
2841
|
import dotenv from "dotenv";
|
|
2842
2842
|
dotenv.config({ quiet: true });
|
|
2843
2843
|
var program = new Command();
|
|
2844
|
-
|
|
2844
|
+
var __dirname = path9.dirname(fileURLToPath3(import.meta.url));
|
|
2845
|
+
var pkgPath = fs8.existsSync(path9.join(__dirname, "package.json")) ? path9.join(__dirname, "package.json") : path9.join(__dirname, "../../package.json");
|
|
2846
|
+
var pkg = fs8.readJsonSync(pkgPath);
|
|
2847
|
+
program.name("graphene").description("Graphene CLI").version(pkg.version, "-v, --version");
|
|
2845
2848
|
program.hook("preAction", async () => {
|
|
2846
2849
|
if (process.env.CLI_DELAY) {
|
|
2847
2850
|
await new Promise((r) => setTimeout(r, 1e3));
|