@sqg/sqg 0.19.1 → 0.20.0
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 +1 -0
- package/dist/index.mjs +188 -25
- package/dist/sqg.mjs +195 -26
- package/dist/templates/java-duckdb-arrow.hbs +3 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -120,6 +120,7 @@ console.log(user?.name);
|
|
|
120
120
|
| `-- QUERY name` | SELECT query returning rows |
|
|
121
121
|
| `-- QUERY name :one` | Query returning single row or undefined |
|
|
122
122
|
| `-- QUERY name :pluck` | Return single (first) column value |
|
|
123
|
+
| `-- QUERY name :result=Foo` | Name the row type (Java). Add it to ONE query and every same-shape query shares it. Full-table `SELECT *` reuses the `TABLE` row type without annotation. |
|
|
123
124
|
| `-- EXEC name` | INSERT/UPDATE/DELETE (no result rows) |
|
|
124
125
|
| `-- TESTDATA name` | Test data, runs after migrations |
|
|
125
126
|
| `@set var = value` | Define parameter with sample value |
|
package/dist/index.mjs
CHANGED
|
@@ -3,7 +3,7 @@ import consola, { LogLevels } from "consola";
|
|
|
3
3
|
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
4
|
import { LRParser } from "@lezer/lr";
|
|
5
5
|
import { homedir } from "node:os";
|
|
6
|
-
import { basename, dirname, extname, join, resolve } from "node:path";
|
|
6
|
+
import { basename, dirname, extname, join, relative, resolve } from "node:path";
|
|
7
7
|
import { camelCase, pascalCase, snakeCase } from "es-toolkit/string";
|
|
8
8
|
import Handlebars from "handlebars";
|
|
9
9
|
import YAML from "yaml";
|
|
@@ -237,11 +237,18 @@ SQL Annotation Syntax:
|
|
|
237
237
|
\${varName} Reference a variable in SQL
|
|
238
238
|
|
|
239
239
|
Modifiers:
|
|
240
|
-
:one
|
|
241
|
-
:pluck
|
|
242
|
-
:all
|
|
243
|
-
:batch
|
|
244
|
-
:appender
|
|
240
|
+
:one Return single row (or null) instead of array
|
|
241
|
+
:pluck Return single column value (requires exactly 1 column)
|
|
242
|
+
:all Return all rows (default)
|
|
243
|
+
:batch Generate a JDBC batch method for an EXEC (Java only)
|
|
244
|
+
:appender Generate bulk insert appender for TABLE annotation
|
|
245
|
+
:result=Name Name (and share) the row type (Java only). Annotate ONE query
|
|
246
|
+
with :result=Name — every other query in the same file with the
|
|
247
|
+
same column shape automatically gets the same name; you do NOT
|
|
248
|
+
need to repeat the modifier on each query.
|
|
249
|
+
Without :result=, each query keeps its own per-query row type.
|
|
250
|
+
Exception: SELECT * matching a -- TABLE schema (same columns,
|
|
251
|
+
same order) auto-uses the table's row type with no annotation.
|
|
245
252
|
|
|
246
253
|
Example:
|
|
247
254
|
-- MIGRATE 1
|
|
@@ -405,7 +412,7 @@ const parser = LRParser.deserialize({
|
|
|
405
412
|
maxTerm: 34,
|
|
406
413
|
skippedNodes: [0],
|
|
407
414
|
repeatNodeCount: 6,
|
|
408
|
-
tokenData: "$KR~RqOX#YXY'wYZ(iZ]#Y]^$W^p#Ypq'wqr#Yrs(}st#Ytu6^uw#Ywx9[xz#Yz{%_{}#Y}!OKi!O!P#Y!P!Q#2P!Q![$A]![!]$Bu!]!_#Y!_!`$Eu!`!b#Y!b!c$Fu!c!}$A]!}#R#Y#R#S$A]#S#T#Y#T#o$A]#o;'S#Y;'S;=`'q<%lO#YU#_]_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YS$ZTOz$Wz{$j{;'S$W;'S;=`%X<%lO$WS$mVOz$Wz{$j{!P$W!P!Q%S!Q;'S$W;'S;=`%X<%lO$WS%XOnSS%[P;=`<%l$WU%d__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!P#Y!P!Q&c!Q;'S#Y;'S;=`'q<%lO#YU&jVnS_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ'UV_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ'nP;=`<%l'PU'tP;=`<%l#Y~'|Xj~OX$WXY'wYp$Wpq'wqz$Wz{$j{;'S$W;'S;=`%X<%lO$W~(nTk~Oz$Wz{$j{;'S$W;'S;=`%X<%lO$WU)Sb_QOX(}XY*[YZ$WZ](}]^*[^p(}pq*[qr(}rs.yst(}tu*[uz(}z{/y{#O(}#O#P5V#P;'S(};'S;=`6W<%lO(}U*_ZOY*[YZ$WZr*[rs+Qsz*[z{+f{#O*[#O#P.Z#P;'S*[;'S;=`.s<%lO*[U+VT]QOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU+i]OY*[YZ$WZr*[rs+Qsz*[z{+f{!P*[!P!Q,b!Q#O*[#O#P.Z#P;'S*[;'S;=`.s<%lO*[U,gWnSOY-PZr-Prs-ls#O-P#O#P-q#P;'S-P;'S;=`.T<%lO-PQ-SWOY-PZr-Prs-ls#O-P#O#P-q#P;'S-P;'S;=`.T<%lO-PQ-qO]QQ-tTOY-PYZ-PZ;'S-P;'S;=`.T<%lO-PQ.WP;=`<%l-PU.^VOY*[YZ*[Zz*[z{+f{;'S*[;'S;=`.s<%lO*[U.vP;=`<%l*[U/Q]]Q_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YU0Od_QOX(}XY*[YZ$WZ](}]^*[^p(}pq*[qr(}rs.yst(}tu*[uz(}z{/y{!P(}!P!Q1^!Q#O(}#O#P5V#P;'S(};'S;=`6W<%lO(}U1e_nS_QOX2dXY-PZ]2d]^-P^p2dpq-Pqr2drs3hst2dtu-Pu#O2d#O#P4U#P;'S2d;'S;=`5P<%lO2dQ2i__QOX2dXY-PZ]2d]^-P^p2dpq-Pqr2drs3hst2dtu-Pu#O2d#O#P4U#P;'S2d;'S;=`5P<%lO2dQ3oV]Q_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ4Z[_QOX2dXY-PYZ-PZ]2d]^-P^p2dpq-Pqt2dtu-Pu;'S2d;'S;=`5P<%lO2dQ5SP;=`<%l2dU5[^_QOX(}XY*[YZ*[Z](}]^*[^p(}pq*[qt(}tu*[uz(}z{/y{;'S(};'S;=`6W<%lO(}U6ZP;=`<%l(}U6cV_QOz$Wz{$j{#o$W#o#p6x#p;'S$W;'S;=`%X<%lO$WU6{]Oz$Wz{$j{!Q$W!Q![7t![!c$W!c!}7t!}#R$W#R#S7t#S#T$W#T#o7t#o;'S$W;'S;=`%X<%lO$WU7w_Oz$Wz{$j{!Q$W!Q![7t![!c$W!c!}7t!}#R$W#R#S7t#S#T$W#T#o7t#o#q$W#q#r8v#r;'S$W;'S;=`%X<%lO$WU8{TaQOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU9ab_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[U:lZOY:iYZ$WZw:iwx;_xz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU;dT^QOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU;v]OY:iYZ$WZw:iwx;_xz:iz{;s{!P:i!P!Q<o!Q#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU<tWnSOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q=aWOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q>OO^QQ>RXOY=^YZ=^Zw=^wx>nx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q>sW^QOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q?`P;=`<%l=^U?fZOY:iYZ:iZw:iwx@Xxz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU@^Z^QOY:iYZ$WZw:iwx;_xz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iUASP;=`<%l:iUA^]^Q_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YUB[d_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{!P9[!P!QCj!Q#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UCq_nS_QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQDu__QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQE{V^Q_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQFg`_QOXDpXY=^YZ=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxGix#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQGp_^Q_QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQHrP;=`<%lDpUHzb_QOX9[XY:iYZ:iZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxJSxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UJZb^Q_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UKfP;=`<%l9[VKn__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{}#Y}!OLm!O;'S#Y;'S;=`'q<%lO#YVLthQR_QOXN`XY!&|YZ$WZ]N`]^! c^pN`pq!&|qtN`tu! cuzN`z{!#q{!dN`!d!e!=`!e!gN`!g!h!Ft!h!oN`!o!p!Ja!p!sN`!s!t#!`!t!vN`!v!w#'U!w;'SN`;'S;=`!&v<%lON`VNg^QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{;'SN`;'S;=`!&v<%lON`V! hVQROY! cYZ$WZz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!!SXQROY! cYZ$WZz! cz{! }{!P! c!P!Q!!o!Q;'S! c;'S;=`!#k<%lO! cV!!vSnSQROY!#SZ;'S!#S;'S;=`!#e<%lO!#SR!#XSQROY!#SZ;'S!#S;'S;=`!#e<%lO!#SR!#hP;=`<%l!#SV!#nP;=`<%l! cV!#x`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!PN`!P!Q!$z!Q;'SN`;'S;=`!&v<%lON`V!%TZnSQR_QOX!%vXY!#SZ]!%v]^!#S^p!%vpq!#Sqt!%vtu!#Su;'S!%v;'S;=`!&p<%lO!%vR!%}ZQR_QOX!%vXY!#SZ]!%v]^!#S^p!%vpq!#Sqt!%vtu!#Su;'S!%v;'S;=`!&p<%lO!%vR!&sP;=`<%l!%vV!&yP;=`<%lN`V!'RdQROX! cXY!&|YZ$WZp! cpq!&|qz! cz{! }{!d! c!d!e!(a!e!g! c!g!h!.l!h!o! c!o!p!0p!p!s! c!s!t!4W!t!v! c!v!w!6|!w;'S! c;'S;=`!#k<%lO! cV!(fXQROY! cYZ$WZz! cz{! }{!c! c!c!d!)R!d;'S! c;'S;=`!#k<%lO! cV!)WXQROY! cYZ$WZz! cz{! }{!u! c!u!v!)s!v;'S! c;'S;=`!#k<%lO! cV!)xXQROY! cYZ$WZz! cz{! }{!g! c!g!h!*e!h;'S! c;'S;=`!#k<%lO! cV!*jXQROY! cYZ$WZz! cz{! }{!n! c!n!o!+V!o;'S! c;'S;=`!#k<%lO! cV!+[XQROY! cYZ$WZz! cz{! }{!k! c!k!l!+w!l;'S! c;'S;=`!#k<%lO! cV!+|XQROY! cYZ$WZz! cz{! }{!p! c!p!q!,i!q;'S! c;'S;=`!#k<%lO! cV!,nXQROY! cYZ$WZz! cz{! }{!g! c!g!h!-Z!h;'S! c;'S;=`!#k<%lO! cV!-`YQROX! cXY!.OYZ$WZp! cpq!.Oqz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!.VVYRQROY! cYZ$WZz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!.qXQROY! cYZ$WZz! cz{! }{!z! c!z!{!/^!{;'S! c;'S;=`!#k<%lO! cV!/cXQROY! cYZ$WZz! cz{! }{!g! c!g!h!0O!h;'S! c;'S;=`!#k<%lO! cV!0TXQROY! cYZ$WZz! cz{! }{!e! c!e!f!-Z!f;'S! c;'S;=`!#k<%lO! cV!0uXQROY! cYZ$WZz! cz{! }{!k! c!k!l!1b!l;'S! c;'S;=`!#k<%lO! cV!1gXQROY! cYZ$WZz! cz{! }{!i! c!i!j!2S!j;'S! c;'S;=`!#k<%lO! cV!2XXQROY! cYZ$WZz! cz{! }{!t! c!t!u!2t!u;'S! c;'S;=`!#k<%lO! cV!2yXQROY! cYZ$WZz! cz{! }{!c! c!c!d!3f!d;'S! c;'S;=`!#k<%lO! cV!3kXQROY! cYZ$WZz! cz{! }{!v! c!v!w!,i!w;'S! c;'S;=`!#k<%lO! cV!4]XQROY! cYZ$WZz! cz{! }{!w! c!w!x!4x!x;'S! c;'S;=`!#k<%lO! cV!4}XQROY! cYZ$WZz! cz{! }{!g! c!g!h!5j!h;'S! c;'S;=`!#k<%lO! cV!5oXQROY! cYZ$WZz! cz{! }{!t! c!t!u!6[!u;'S! c;'S;=`!#k<%lO! cV!6aXQROY! cYZ$WZz! cz{! }{!{! c!{!|!-Z!|;'S! c;'S;=`!#k<%lO! cV!7RZQROY! cYZ$WZz! cz{! }{!c! c!c!d!7t!d!g! c!g!h!9W!h;'S! c;'S;=`!#k<%lO! cV!7yXQROY! cYZ$WZz! cz{! }{!d! c!d!e!8f!e;'S! c;'S;=`!#k<%lO! cV!8kXQROY! cYZ$WZz! cz{! }{!n! c!n!o!,i!o;'S! c;'S;=`!#k<%lO! cV!9]XQROY! cYZ$WZz! cz{! }{!u! c!u!v!9x!v;'S! c;'S;=`!#k<%lO! cV!9}XQROY! cYZ$WZz! cz{! }{!v! c!v!w!:j!w;'S! c;'S;=`!#k<%lO! cV!:oXQROY! cYZ$WZz! cz{! }{!f! c!f!g!;[!g;'S! c;'S;=`!#k<%lO! cV!;aXQROY! cYZ$WZz! cz{! }{!c! c!c!d!;|!d;'S! c;'S;=`!#k<%lO! cV!<RXQROY! cYZ$WZz! cz{! }{!v! c!v!w!<n!w;'S! c;'S;=`!#k<%lO! cV!<sXQROY! cYZ$WZz! cz{! }{!c! c!c!d!-Z!d;'S! c;'S;=`!#k<%lO! cV!=g`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d!>i!d;'SN`;'S;=`!&v<%lON`V!>p`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!uN`!u!v!?r!v;'SN`;'S;=`!&v<%lON`V!?y`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!@{!h;'SN`;'S;=`!&v<%lON`V!AS`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!nN`!n!o!BU!o;'SN`;'S;=`!&v<%lON`V!B]`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!kN`!k!l!C_!l;'SN`;'S;=`!&v<%lON`V!Cf`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!pN`!p!q!Dh!q;'SN`;'S;=`!&v<%lON`V!Do`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!Eq!h;'SN`;'S;=`!&v<%lON`V!Ex^QR_QOXN`XY!.OYZ$WZ]N`]^! c^pN`pq!.OqtN`tu! cuzN`z{!#q{;'SN`;'S;=`!&v<%lON`V!F{`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!zN`!z!{!G}!{;'SN`;'S;=`!&v<%lON`V!HU`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!IW!h;'SN`;'S;=`!&v<%lON`V!I_`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!eN`!e!f!Eq!f;'SN`;'S;=`!&v<%lON`V!Jh`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!kN`!k!l!Kj!l;'SN`;'S;=`!&v<%lON`V!Kq`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!iN`!i!j!Ls!j;'SN`;'S;=`!&v<%lON`V!Lz`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!tN`!t!u!M|!u;'SN`;'S;=`!&v<%lON`V!NT`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d# V!d;'SN`;'S;=`!&v<%lON`V# ^`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w!Dh!w;'SN`;'S;=`!&v<%lON`V#!g`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!wN`!w!x##i!x;'SN`;'S;=`!&v<%lON`V##p`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h#$r!h;'SN`;'S;=`!&v<%lON`V#$y`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!tN`!t!u#%{!u;'SN`;'S;=`!&v<%lON`V#&S`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!{N`!{!|!Eq!|;'SN`;'S;=`!&v<%lON`V#']bQR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d#(e!d!gN`!g!h#*w!h;'SN`;'S;=`!&v<%lON`V#(l`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!dN`!d!e#)n!e;'SN`;'S;=`!&v<%lON`V#)u`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!nN`!n!o!Dh!o;'SN`;'S;=`!&v<%lON`V#+O`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!uN`!u!v#,Q!v;'SN`;'S;=`!&v<%lON`V#,X`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w#-Z!w;'SN`;'S;=`!&v<%lON`V#-b`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!fN`!f!g#.d!g;'SN`;'S;=`!&v<%lON`V#.k`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d#/m!d;'SN`;'S;=`!&v<%lON`V#/t`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w#0v!w;'SN`;'S;=`!&v<%lON`V#0}`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d!Eq!d;'SN`;'S;=`!&v<%lON`V#2U]_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{#2}{;'S#Y;'S;=`'q<%lO#YV#3Sj_QOX#4tXY#8uYZ#8uZ]#4t]^#5r^p#4tpq#8uqt#4ttu#5ruz#4tz{#6{{!P#4t!P!Q#Js!Q!d#4t!d!e$ p!e!g#4t!g!h$*_!h!o#4t!o!p$-k!p!s#4t!s!t$3P!t!v#4t!v!w$7a!w;'S#4t;'S;=`#8o<%lO#4tV#4y]_QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{;'S#4t;'S;=`#8o<%lO#4tV#5uTOz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#6XVOz#5rz{#6U{!P#5r!P!Q#6n!Q;'S#5r;'S;=`#6u<%lO#5rV#6uORRnSV#6xP;=`<%l#5rV#7Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!P#4t!P!Q#8P!Q;'S#4t;'S;=`#8o<%lO#4tV#8YVRRnS_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PV#8rP;=`<%l#4tV#8xdOX#5rXY#8uYZ#8uZp#5rpq#8uqz#5rz{#6U{!d#5r!d!e#:W!e!g#5r!g!h#?o!h!o#5r!o!p#AZ!p!s#5r!s!t#Cw!t!v#5r!v!w#E{!w;'S#5r;'S;=`#6u<%lO#5rV#:ZVOz#5rz{#6U{!c#5r!c!d#:p!d;'S#5r;'S;=`#6u<%lO#5rV#:sVOz#5rz{#6U{!u#5r!u!v#;Y!v;'S#5r;'S;=`#6u<%lO#5rV#;]VOz#5rz{#6U{!g#5r!g!h#;r!h;'S#5r;'S;=`#6u<%lO#5rV#;uVOz#5rz{#6U{!n#5r!n!o#<[!o;'S#5r;'S;=`#6u<%lO#5rV#<_VOz#5rz{#6U{!k#5r!k!l#<t!l;'S#5r;'S;=`#6u<%lO#5rV#<wVOz#5rz{#6U{!p#5r!p!q#=^!q;'S#5r;'S;=`#6u<%lO#5rV#=aVOz#5rz{#6U{!g#5r!g!h#=v!h;'S#5r;'S;=`#6u<%lO#5rV#=yYOX#5rXY#>iYZ#?ZZp#5rpq#>iqz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#>nXUROX#5rXY#>iYp#5rpq#>iqz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#?`TUROz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#?rVOz#5rz{#6U{!z#5r!z!{#@X!{;'S#5r;'S;=`#6u<%lO#5rV#@[VOz#5rz{#6U{!g#5r!g!h#@q!h;'S#5r;'S;=`#6u<%lO#5rV#@tVOz#5rz{#6U{!e#5r!e!f#=v!f;'S#5r;'S;=`#6u<%lO#5rV#A^VOz#5rz{#6U{!k#5r!k!l#As!l;'S#5r;'S;=`#6u<%lO#5rV#AvVOz#5rz{#6U{!i#5r!i!j#B]!j;'S#5r;'S;=`#6u<%lO#5rV#B`VOz#5rz{#6U{!t#5r!t!u#Bu!u;'S#5r;'S;=`#6u<%lO#5rV#BxVOz#5rz{#6U{!c#5r!c!d#C_!d;'S#5r;'S;=`#6u<%lO#5rV#CbVOz#5rz{#6U{!v#5r!v!w#=^!w;'S#5r;'S;=`#6u<%lO#5rV#CzVOz#5rz{#6U{!w#5r!w!x#Da!x;'S#5r;'S;=`#6u<%lO#5rV#DdVOz#5rz{#6U{!g#5r!g!h#Dy!h;'S#5r;'S;=`#6u<%lO#5rV#D|VOz#5rz{#6U{!t#5r!t!u#Ec!u;'S#5r;'S;=`#6u<%lO#5rV#EfVOz#5rz{#6U{!{#5r!{!|#=v!|;'S#5r;'S;=`#6u<%lO#5rV#FOXOz#5rz{#6U{!c#5r!c!d#Fk!d!g#5r!g!h#Gm!h;'S#5r;'S;=`#6u<%lO#5rV#FnVOz#5rz{#6U{!d#5r!d!e#GT!e;'S#5r;'S;=`#6u<%lO#5rV#GWVOz#5rz{#6U{!n#5r!n!o#=^!o;'S#5r;'S;=`#6u<%lO#5rV#GpVOz#5rz{#6U{!u#5r!u!v#HV!v;'S#5r;'S;=`#6u<%lO#5rV#HYVOz#5rz{#6U{!v#5r!v!w#Ho!w;'S#5r;'S;=`#6u<%lO#5rV#HrVOz#5rz{#6U{!f#5r!f!g#IX!g;'S#5r;'S;=`#6u<%lO#5rV#I[VOz#5rz{#6U{!c#5r!c!d#Iq!d;'S#5r;'S;=`#6u<%lO#5rV#ItVOz#5rz{#6U{!v#5r!v!w#JZ!w;'S#5r;'S;=`#6u<%lO#5rV#J^VOz#5rz{#6U{!c#5r!c!d#=v!d;'S#5r;'S;=`#6u<%lO#5rV#Jz]nS_QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{;'S#Ks;'S;=`$ j<%lO#KsR#Kx]_QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{;'S#Ks;'S;=`$ j<%lO#KsR#LtTOz#Lqz{#MT{;'S#Lq;'S;=`#Mr<%lO#LqR#MWVOz#Lqz{#MT{!P#Lq!P!Q#Mm!Q;'S#Lq;'S;=`#Mr<%lO#LqR#MrORRR#MuP;=`<%l#LqR#M}__QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{!P#Ks!P!Q#N|!Q;'S#Ks;'S;=`$ j<%lO#KsR$ TVRR_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PR$ mP;=`<%l#KsV$ u__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$!t!d;'S#4t;'S;=`#8o<%lO#4tV$!y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!u#4t!u!v$#x!v;'S#4t;'S;=`#8o<%lO#4tV$#}__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$$|!h;'S#4t;'S;=`#8o<%lO#4tV$%R__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!n#4t!n!o$&Q!o;'S#4t;'S;=`#8o<%lO#4tV$&V__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!k#4t!k!l$'U!l;'S#4t;'S;=`#8o<%lO#4tV$'Z__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!p#4t!p!q$(Y!q;'S#4t;'S;=`#8o<%lO#4tV$(___QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$)^!h;'S#4t;'S;=`#8o<%lO#4tV$)c^_QOX#4tXY#>iYZ#?ZZ]#4t]^#5r^p#4tpq#>iqt#4ttu#5ruz#4tz{#6{{;'S#4t;'S;=`#8o<%lO#4tV$*d__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!z#4t!z!{$+c!{;'S#4t;'S;=`#8o<%lO#4tV$+h__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$,g!h;'S#4t;'S;=`#8o<%lO#4tV$,l__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!e#4t!e!f$)^!f;'S#4t;'S;=`#8o<%lO#4tV$-p__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!k#4t!k!l$.o!l;'S#4t;'S;=`#8o<%lO#4tV$.t__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!i#4t!i!j$/s!j;'S#4t;'S;=`#8o<%lO#4tV$/x__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!t#4t!t!u$0w!u;'S#4t;'S;=`#8o<%lO#4tV$0|__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$1{!d;'S#4t;'S;=`#8o<%lO#4tV$2Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$(Y!w;'S#4t;'S;=`#8o<%lO#4tV$3U__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!w#4t!w!x$4T!x;'S#4t;'S;=`#8o<%lO#4tV$4Y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$5X!h;'S#4t;'S;=`#8o<%lO#4tV$5^__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!t#4t!t!u$6]!u;'S#4t;'S;=`#8o<%lO#4tV$6b__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!{#4t!{!|$)^!|;'S#4t;'S;=`#8o<%lO#4tV$7fa_QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$8k!d!g#4t!g!h$:s!h;'S#4t;'S;=`#8o<%lO#4tV$8p__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!d#4t!d!e$9o!e;'S#4t;'S;=`#8o<%lO#4tV$9t__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!n#4t!n!o$(Y!o;'S#4t;'S;=`#8o<%lO#4tV$:x__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!u#4t!u!v$;w!v;'S#4t;'S;=`#8o<%lO#4tV$;|__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$<{!w;'S#4t;'S;=`#8o<%lO#4tV$=Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!f#4t!f!g$>P!g;'S#4t;'S;=`#8o<%lO#4tV$>U__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$?T!d;'S#4t;'S;=`#8o<%lO#4tV$?Y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$@X!w;'S#4t;'S;=`#8o<%lO#4tV$@^__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$)^!d;'S#4t;'S;=`#8o<%lO#4tV$AdeVP_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$A]![!c#Y!c!}$A]!}#R#Y#R#S$A]#S#T#Y#T#o$A]#o;'S#Y;'S;=`'q<%lO#Y~$Bze_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$D]![!c#Y!c!}$D]!}#R#Y#R#S$D]#S#T#Y#T#o$D]#o;'S#Y;'S;=`'q<%lO#Y~$DdeW~_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$D]![!c#Y!c!}$D]!}#R#Y#R#S$D]#S#T#Y#T#o$D]#o;'S#Y;'S;=`'q<%lO#YV$E|]qP_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YU$Fz__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#g#Y#g#h$Gy#h;'S#Y;'S;=`'q<%lO#YU$HO__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#X#Y#X#Y$H}#Y;'S#Y;'S;=`'q<%lO#YU$IS__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#h#Y#h#i$JR#i;'S#Y;'S;=`'q<%lO#YU$JY]pQ_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#Y",
|
|
415
|
+
tokenData: "$NX~RqOX#YXY'wYZ(iZ]#Y]^$W^p#Ypq'wqr#Yrs(}st#Ytu6^uw#Ywx9[xz#Yz{%_{}#Y}!OKi!O!P#Y!P!Q#2P!Q![$A]![!]$Bu!]!_#Y!_!`$H{!`!b#Y!b!c$I{!c!}$A]!}#R#Y#R#S$A]#S#T#Y#T#o$A]#o;'S#Y;'S;=`'q<%lO#YU#_]_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YS$ZTOz$Wz{$j{;'S$W;'S;=`%X<%lO$WS$mVOz$Wz{$j{!P$W!P!Q%S!Q;'S$W;'S;=`%X<%lO$WS%XOnSS%[P;=`<%l$WU%d__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!P#Y!P!Q&c!Q;'S#Y;'S;=`'q<%lO#YU&jVnS_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ'UV_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ'nP;=`<%l'PU'tP;=`<%l#Y~'|Xj~OX$WXY'wYp$Wpq'wqz$Wz{$j{;'S$W;'S;=`%X<%lO$W~(nTk~Oz$Wz{$j{;'S$W;'S;=`%X<%lO$WU)Sb_QOX(}XY*[YZ$WZ](}]^*[^p(}pq*[qr(}rs.yst(}tu*[uz(}z{/y{#O(}#O#P5V#P;'S(};'S;=`6W<%lO(}U*_ZOY*[YZ$WZr*[rs+Qsz*[z{+f{#O*[#O#P.Z#P;'S*[;'S;=`.s<%lO*[U+VT]QOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU+i]OY*[YZ$WZr*[rs+Qsz*[z{+f{!P*[!P!Q,b!Q#O*[#O#P.Z#P;'S*[;'S;=`.s<%lO*[U,gWnSOY-PZr-Prs-ls#O-P#O#P-q#P;'S-P;'S;=`.T<%lO-PQ-SWOY-PZr-Prs-ls#O-P#O#P-q#P;'S-P;'S;=`.T<%lO-PQ-qO]QQ-tTOY-PYZ-PZ;'S-P;'S;=`.T<%lO-PQ.WP;=`<%l-PU.^VOY*[YZ*[Zz*[z{+f{;'S*[;'S;=`.s<%lO*[U.vP;=`<%l*[U/Q]]Q_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YU0Od_QOX(}XY*[YZ$WZ](}]^*[^p(}pq*[qr(}rs.yst(}tu*[uz(}z{/y{!P(}!P!Q1^!Q#O(}#O#P5V#P;'S(};'S;=`6W<%lO(}U1e_nS_QOX2dXY-PZ]2d]^-P^p2dpq-Pqr2drs3hst2dtu-Pu#O2d#O#P4U#P;'S2d;'S;=`5P<%lO2dQ2i__QOX2dXY-PZ]2d]^-P^p2dpq-Pqr2drs3hst2dtu-Pu#O2d#O#P4U#P;'S2d;'S;=`5P<%lO2dQ3oV]Q_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ4Z[_QOX2dXY-PYZ-PZ]2d]^-P^p2dpq-Pqt2dtu-Pu;'S2d;'S;=`5P<%lO2dQ5SP;=`<%l2dU5[^_QOX(}XY*[YZ*[Z](}]^*[^p(}pq*[qt(}tu*[uz(}z{/y{;'S(};'S;=`6W<%lO(}U6ZP;=`<%l(}U6cV_QOz$Wz{$j{#o$W#o#p6x#p;'S$W;'S;=`%X<%lO$WU6{]Oz$Wz{$j{!Q$W!Q![7t![!c$W!c!}7t!}#R$W#R#S7t#S#T$W#T#o7t#o;'S$W;'S;=`%X<%lO$WU7w_Oz$Wz{$j{!Q$W!Q![7t![!c$W!c!}7t!}#R$W#R#S7t#S#T$W#T#o7t#o#q$W#q#r8v#r;'S$W;'S;=`%X<%lO$WU8{TaQOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU9ab_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[U:lZOY:iYZ$WZw:iwx;_xz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU;dT^QOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU;v]OY:iYZ$WZw:iwx;_xz:iz{;s{!P:i!P!Q<o!Q#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU<tWnSOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q=aWOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q>OO^QQ>RXOY=^YZ=^Zw=^wx>nx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q>sW^QOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q?`P;=`<%l=^U?fZOY:iYZ:iZw:iwx@Xxz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU@^Z^QOY:iYZ$WZw:iwx;_xz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iUASP;=`<%l:iUA^]^Q_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YUB[d_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{!P9[!P!QCj!Q#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UCq_nS_QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQDu__QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQE{V^Q_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQFg`_QOXDpXY=^YZ=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxGix#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQGp_^Q_QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQHrP;=`<%lDpUHzb_QOX9[XY:iYZ:iZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxJSxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UJZb^Q_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UKfP;=`<%l9[VKn__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{}#Y}!OLm!O;'S#Y;'S;=`'q<%lO#YVLthQR_QOXN`XY!&|YZ$WZ]N`]^! c^pN`pq!&|qtN`tu! cuzN`z{!#q{!dN`!d!e!=`!e!gN`!g!h!Ft!h!oN`!o!p!Ja!p!sN`!s!t#!`!t!vN`!v!w#'U!w;'SN`;'S;=`!&v<%lON`VNg^QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{;'SN`;'S;=`!&v<%lON`V! hVQROY! cYZ$WZz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!!SXQROY! cYZ$WZz! cz{! }{!P! c!P!Q!!o!Q;'S! c;'S;=`!#k<%lO! cV!!vSnSQROY!#SZ;'S!#S;'S;=`!#e<%lO!#SR!#XSQROY!#SZ;'S!#S;'S;=`!#e<%lO!#SR!#hP;=`<%l!#SV!#nP;=`<%l! cV!#x`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!PN`!P!Q!$z!Q;'SN`;'S;=`!&v<%lON`V!%TZnSQR_QOX!%vXY!#SZ]!%v]^!#S^p!%vpq!#Sqt!%vtu!#Su;'S!%v;'S;=`!&p<%lO!%vR!%}ZQR_QOX!%vXY!#SZ]!%v]^!#S^p!%vpq!#Sqt!%vtu!#Su;'S!%v;'S;=`!&p<%lO!%vR!&sP;=`<%l!%vV!&yP;=`<%lN`V!'RdQROX! cXY!&|YZ$WZp! cpq!&|qz! cz{! }{!d! c!d!e!(a!e!g! c!g!h!.l!h!o! c!o!p!0p!p!s! c!s!t!4W!t!v! c!v!w!6|!w;'S! c;'S;=`!#k<%lO! cV!(fXQROY! cYZ$WZz! cz{! }{!c! c!c!d!)R!d;'S! c;'S;=`!#k<%lO! cV!)WXQROY! cYZ$WZz! cz{! }{!u! c!u!v!)s!v;'S! c;'S;=`!#k<%lO! cV!)xXQROY! cYZ$WZz! cz{! }{!g! c!g!h!*e!h;'S! c;'S;=`!#k<%lO! cV!*jXQROY! cYZ$WZz! cz{! }{!n! c!n!o!+V!o;'S! c;'S;=`!#k<%lO! cV!+[XQROY! cYZ$WZz! cz{! }{!k! c!k!l!+w!l;'S! c;'S;=`!#k<%lO! cV!+|XQROY! cYZ$WZz! cz{! }{!p! c!p!q!,i!q;'S! c;'S;=`!#k<%lO! cV!,nXQROY! cYZ$WZz! cz{! }{!g! c!g!h!-Z!h;'S! c;'S;=`!#k<%lO! cV!-`YQROX! cXY!.OYZ$WZp! cpq!.Oqz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!.VVYRQROY! cYZ$WZz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!.qXQROY! cYZ$WZz! cz{! }{!z! c!z!{!/^!{;'S! c;'S;=`!#k<%lO! cV!/cXQROY! cYZ$WZz! cz{! }{!g! c!g!h!0O!h;'S! c;'S;=`!#k<%lO! cV!0TXQROY! cYZ$WZz! cz{! }{!e! c!e!f!-Z!f;'S! c;'S;=`!#k<%lO! cV!0uXQROY! cYZ$WZz! cz{! }{!k! c!k!l!1b!l;'S! c;'S;=`!#k<%lO! cV!1gXQROY! cYZ$WZz! cz{! }{!i! c!i!j!2S!j;'S! c;'S;=`!#k<%lO! cV!2XXQROY! cYZ$WZz! cz{! }{!t! c!t!u!2t!u;'S! c;'S;=`!#k<%lO! cV!2yXQROY! cYZ$WZz! cz{! }{!c! c!c!d!3f!d;'S! c;'S;=`!#k<%lO! cV!3kXQROY! cYZ$WZz! cz{! }{!v! c!v!w!,i!w;'S! c;'S;=`!#k<%lO! cV!4]XQROY! cYZ$WZz! cz{! }{!w! c!w!x!4x!x;'S! c;'S;=`!#k<%lO! cV!4}XQROY! cYZ$WZz! cz{! }{!g! c!g!h!5j!h;'S! c;'S;=`!#k<%lO! cV!5oXQROY! cYZ$WZz! cz{! }{!t! c!t!u!6[!u;'S! c;'S;=`!#k<%lO! cV!6aXQROY! cYZ$WZz! cz{! }{!{! c!{!|!-Z!|;'S! c;'S;=`!#k<%lO! cV!7RZQROY! cYZ$WZz! cz{! }{!c! c!c!d!7t!d!g! c!g!h!9W!h;'S! c;'S;=`!#k<%lO! cV!7yXQROY! cYZ$WZz! cz{! }{!d! c!d!e!8f!e;'S! c;'S;=`!#k<%lO! cV!8kXQROY! cYZ$WZz! cz{! }{!n! c!n!o!,i!o;'S! c;'S;=`!#k<%lO! cV!9]XQROY! cYZ$WZz! cz{! }{!u! c!u!v!9x!v;'S! c;'S;=`!#k<%lO! cV!9}XQROY! cYZ$WZz! cz{! }{!v! c!v!w!:j!w;'S! c;'S;=`!#k<%lO! cV!:oXQROY! cYZ$WZz! cz{! }{!f! c!f!g!;[!g;'S! c;'S;=`!#k<%lO! cV!;aXQROY! cYZ$WZz! cz{! }{!c! c!c!d!;|!d;'S! c;'S;=`!#k<%lO! cV!<RXQROY! cYZ$WZz! cz{! }{!v! c!v!w!<n!w;'S! c;'S;=`!#k<%lO! cV!<sXQROY! cYZ$WZz! cz{! }{!c! c!c!d!-Z!d;'S! c;'S;=`!#k<%lO! cV!=g`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d!>i!d;'SN`;'S;=`!&v<%lON`V!>p`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!uN`!u!v!?r!v;'SN`;'S;=`!&v<%lON`V!?y`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!@{!h;'SN`;'S;=`!&v<%lON`V!AS`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!nN`!n!o!BU!o;'SN`;'S;=`!&v<%lON`V!B]`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!kN`!k!l!C_!l;'SN`;'S;=`!&v<%lON`V!Cf`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!pN`!p!q!Dh!q;'SN`;'S;=`!&v<%lON`V!Do`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!Eq!h;'SN`;'S;=`!&v<%lON`V!Ex^QR_QOXN`XY!.OYZ$WZ]N`]^! c^pN`pq!.OqtN`tu! cuzN`z{!#q{;'SN`;'S;=`!&v<%lON`V!F{`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!zN`!z!{!G}!{;'SN`;'S;=`!&v<%lON`V!HU`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!IW!h;'SN`;'S;=`!&v<%lON`V!I_`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!eN`!e!f!Eq!f;'SN`;'S;=`!&v<%lON`V!Jh`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!kN`!k!l!Kj!l;'SN`;'S;=`!&v<%lON`V!Kq`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!iN`!i!j!Ls!j;'SN`;'S;=`!&v<%lON`V!Lz`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!tN`!t!u!M|!u;'SN`;'S;=`!&v<%lON`V!NT`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d# V!d;'SN`;'S;=`!&v<%lON`V# ^`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w!Dh!w;'SN`;'S;=`!&v<%lON`V#!g`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!wN`!w!x##i!x;'SN`;'S;=`!&v<%lON`V##p`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h#$r!h;'SN`;'S;=`!&v<%lON`V#$y`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!tN`!t!u#%{!u;'SN`;'S;=`!&v<%lON`V#&S`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!{N`!{!|!Eq!|;'SN`;'S;=`!&v<%lON`V#']bQR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d#(e!d!gN`!g!h#*w!h;'SN`;'S;=`!&v<%lON`V#(l`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!dN`!d!e#)n!e;'SN`;'S;=`!&v<%lON`V#)u`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!nN`!n!o!Dh!o;'SN`;'S;=`!&v<%lON`V#+O`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!uN`!u!v#,Q!v;'SN`;'S;=`!&v<%lON`V#,X`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w#-Z!w;'SN`;'S;=`!&v<%lON`V#-b`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!fN`!f!g#.d!g;'SN`;'S;=`!&v<%lON`V#.k`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d#/m!d;'SN`;'S;=`!&v<%lON`V#/t`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w#0v!w;'SN`;'S;=`!&v<%lON`V#0}`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d!Eq!d;'SN`;'S;=`!&v<%lON`V#2U]_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{#2}{;'S#Y;'S;=`'q<%lO#YV#3Sj_QOX#4tXY#8uYZ#8uZ]#4t]^#5r^p#4tpq#8uqt#4ttu#5ruz#4tz{#6{{!P#4t!P!Q#Js!Q!d#4t!d!e$ p!e!g#4t!g!h$*_!h!o#4t!o!p$-k!p!s#4t!s!t$3P!t!v#4t!v!w$7a!w;'S#4t;'S;=`#8o<%lO#4tV#4y]_QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{;'S#4t;'S;=`#8o<%lO#4tV#5uTOz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#6XVOz#5rz{#6U{!P#5r!P!Q#6n!Q;'S#5r;'S;=`#6u<%lO#5rV#6uORRnSV#6xP;=`<%l#5rV#7Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!P#4t!P!Q#8P!Q;'S#4t;'S;=`#8o<%lO#4tV#8YVRRnS_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PV#8rP;=`<%l#4tV#8xdOX#5rXY#8uYZ#8uZp#5rpq#8uqz#5rz{#6U{!d#5r!d!e#:W!e!g#5r!g!h#?o!h!o#5r!o!p#AZ!p!s#5r!s!t#Cw!t!v#5r!v!w#E{!w;'S#5r;'S;=`#6u<%lO#5rV#:ZVOz#5rz{#6U{!c#5r!c!d#:p!d;'S#5r;'S;=`#6u<%lO#5rV#:sVOz#5rz{#6U{!u#5r!u!v#;Y!v;'S#5r;'S;=`#6u<%lO#5rV#;]VOz#5rz{#6U{!g#5r!g!h#;r!h;'S#5r;'S;=`#6u<%lO#5rV#;uVOz#5rz{#6U{!n#5r!n!o#<[!o;'S#5r;'S;=`#6u<%lO#5rV#<_VOz#5rz{#6U{!k#5r!k!l#<t!l;'S#5r;'S;=`#6u<%lO#5rV#<wVOz#5rz{#6U{!p#5r!p!q#=^!q;'S#5r;'S;=`#6u<%lO#5rV#=aVOz#5rz{#6U{!g#5r!g!h#=v!h;'S#5r;'S;=`#6u<%lO#5rV#=yYOX#5rXY#>iYZ#?ZZp#5rpq#>iqz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#>nXUROX#5rXY#>iYp#5rpq#>iqz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#?`TUROz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#?rVOz#5rz{#6U{!z#5r!z!{#@X!{;'S#5r;'S;=`#6u<%lO#5rV#@[VOz#5rz{#6U{!g#5r!g!h#@q!h;'S#5r;'S;=`#6u<%lO#5rV#@tVOz#5rz{#6U{!e#5r!e!f#=v!f;'S#5r;'S;=`#6u<%lO#5rV#A^VOz#5rz{#6U{!k#5r!k!l#As!l;'S#5r;'S;=`#6u<%lO#5rV#AvVOz#5rz{#6U{!i#5r!i!j#B]!j;'S#5r;'S;=`#6u<%lO#5rV#B`VOz#5rz{#6U{!t#5r!t!u#Bu!u;'S#5r;'S;=`#6u<%lO#5rV#BxVOz#5rz{#6U{!c#5r!c!d#C_!d;'S#5r;'S;=`#6u<%lO#5rV#CbVOz#5rz{#6U{!v#5r!v!w#=^!w;'S#5r;'S;=`#6u<%lO#5rV#CzVOz#5rz{#6U{!w#5r!w!x#Da!x;'S#5r;'S;=`#6u<%lO#5rV#DdVOz#5rz{#6U{!g#5r!g!h#Dy!h;'S#5r;'S;=`#6u<%lO#5rV#D|VOz#5rz{#6U{!t#5r!t!u#Ec!u;'S#5r;'S;=`#6u<%lO#5rV#EfVOz#5rz{#6U{!{#5r!{!|#=v!|;'S#5r;'S;=`#6u<%lO#5rV#FOXOz#5rz{#6U{!c#5r!c!d#Fk!d!g#5r!g!h#Gm!h;'S#5r;'S;=`#6u<%lO#5rV#FnVOz#5rz{#6U{!d#5r!d!e#GT!e;'S#5r;'S;=`#6u<%lO#5rV#GWVOz#5rz{#6U{!n#5r!n!o#=^!o;'S#5r;'S;=`#6u<%lO#5rV#GpVOz#5rz{#6U{!u#5r!u!v#HV!v;'S#5r;'S;=`#6u<%lO#5rV#HYVOz#5rz{#6U{!v#5r!v!w#Ho!w;'S#5r;'S;=`#6u<%lO#5rV#HrVOz#5rz{#6U{!f#5r!f!g#IX!g;'S#5r;'S;=`#6u<%lO#5rV#I[VOz#5rz{#6U{!c#5r!c!d#Iq!d;'S#5r;'S;=`#6u<%lO#5rV#ItVOz#5rz{#6U{!v#5r!v!w#JZ!w;'S#5r;'S;=`#6u<%lO#5rV#J^VOz#5rz{#6U{!c#5r!c!d#=v!d;'S#5r;'S;=`#6u<%lO#5rV#Jz]nS_QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{;'S#Ks;'S;=`$ j<%lO#KsR#Kx]_QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{;'S#Ks;'S;=`$ j<%lO#KsR#LtTOz#Lqz{#MT{;'S#Lq;'S;=`#Mr<%lO#LqR#MWVOz#Lqz{#MT{!P#Lq!P!Q#Mm!Q;'S#Lq;'S;=`#Mr<%lO#LqR#MrORRR#MuP;=`<%l#LqR#M}__QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{!P#Ks!P!Q#N|!Q;'S#Ks;'S;=`$ j<%lO#KsR$ TVRR_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PR$ mP;=`<%l#KsV$ u__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$!t!d;'S#4t;'S;=`#8o<%lO#4tV$!y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!u#4t!u!v$#x!v;'S#4t;'S;=`#8o<%lO#4tV$#}__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$$|!h;'S#4t;'S;=`#8o<%lO#4tV$%R__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!n#4t!n!o$&Q!o;'S#4t;'S;=`#8o<%lO#4tV$&V__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!k#4t!k!l$'U!l;'S#4t;'S;=`#8o<%lO#4tV$'Z__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!p#4t!p!q$(Y!q;'S#4t;'S;=`#8o<%lO#4tV$(___QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$)^!h;'S#4t;'S;=`#8o<%lO#4tV$)c^_QOX#4tXY#>iYZ#?ZZ]#4t]^#5r^p#4tpq#>iqt#4ttu#5ruz#4tz{#6{{;'S#4t;'S;=`#8o<%lO#4tV$*d__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!z#4t!z!{$+c!{;'S#4t;'S;=`#8o<%lO#4tV$+h__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$,g!h;'S#4t;'S;=`#8o<%lO#4tV$,l__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!e#4t!e!f$)^!f;'S#4t;'S;=`#8o<%lO#4tV$-p__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!k#4t!k!l$.o!l;'S#4t;'S;=`#8o<%lO#4tV$.t__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!i#4t!i!j$/s!j;'S#4t;'S;=`#8o<%lO#4tV$/x__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!t#4t!t!u$0w!u;'S#4t;'S;=`#8o<%lO#4tV$0|__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$1{!d;'S#4t;'S;=`#8o<%lO#4tV$2Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$(Y!w;'S#4t;'S;=`#8o<%lO#4tV$3U__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!w#4t!w!x$4T!x;'S#4t;'S;=`#8o<%lO#4tV$4Y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$5X!h;'S#4t;'S;=`#8o<%lO#4tV$5^__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!t#4t!t!u$6]!u;'S#4t;'S;=`#8o<%lO#4tV$6b__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!{#4t!{!|$)^!|;'S#4t;'S;=`#8o<%lO#4tV$7fa_QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$8k!d!g#4t!g!h$:s!h;'S#4t;'S;=`#8o<%lO#4tV$8p__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!d#4t!d!e$9o!e;'S#4t;'S;=`#8o<%lO#4tV$9t__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!n#4t!n!o$(Y!o;'S#4t;'S;=`#8o<%lO#4tV$:x__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!u#4t!u!v$;w!v;'S#4t;'S;=`#8o<%lO#4tV$;|__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$<{!w;'S#4t;'S;=`#8o<%lO#4tV$=Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!f#4t!f!g$>P!g;'S#4t;'S;=`#8o<%lO#4tV$>U__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$?T!d;'S#4t;'S;=`#8o<%lO#4tV$?Y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$@X!w;'S#4t;'S;=`#8o<%lO#4tV$@^__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$)^!d;'S#4t;'S;=`#8o<%lO#4tV$AdeVP_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$A]![!c#Y!c!}$A]!}#R#Y#R#S$A]#S#T#Y#T#o$A]#o;'S#Y;'S;=`'q<%lO#Y~$Bze_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$D]![!c#Y!c!}$D]!}#R#Y#R#S$D]#S#T#Y#T#o$D]#o;'S#Y;'S;=`'q<%lO#Y~$DdgW~_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$D]![!_#Y!_!`$E{!`!c#Y!c!}$D]!}#R#Y#R#S$D]#S#T#Y#T#o$D]#o;'S#Y;'S;=`'q<%lO#Y~$FQe_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$Gc![!c#Y!c!}$Gc!}#R#Y#R#S$Gc#S#T#Y#T#o$Gc#o;'S#Y;'S;=`'q<%lO#Y~$GjeW~_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$Gc![!c#Y!c!}$Gc!}#R#Y#R#S$Gc#S#T#Y#T#o$Gc#o;'S#Y;'S;=`'q<%lO#YV$IS]qP_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YU$JQ__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#g#Y#g#h$KP#h;'S#Y;'S;=`'q<%lO#YU$KU__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#X#Y#X#Y$LT#Y;'S#Y;'S;=`'q<%lO#YU$LY__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#h#Y#h#i$MX#i;'S#Y;'S;=`'q<%lO#YU$M`]pQ_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#Y",
|
|
409
416
|
tokenizers: [
|
|
410
417
|
0,
|
|
411
418
|
1,
|
|
@@ -459,13 +466,13 @@ var TypeMapper = class {
|
|
|
459
466
|
* @param path - Optional prefix path for nested type references
|
|
460
467
|
* @returns Generated type declaration code, or empty string for primitive types
|
|
461
468
|
*/
|
|
462
|
-
getDeclarations(column, path = "") {
|
|
463
|
-
if (column.type instanceof StructType) return this.generateStructDeclaration(column, path);
|
|
469
|
+
getDeclarations(column, path = "", nameOverride) {
|
|
470
|
+
if (column.type instanceof StructType) return this.generateStructDeclaration(column, path, nameOverride);
|
|
464
471
|
if (column.type instanceof ListType) return this.getDeclarations({
|
|
465
472
|
name: column.name,
|
|
466
473
|
type: column.type.baseType,
|
|
467
474
|
nullable: true
|
|
468
|
-
}, path);
|
|
475
|
+
}, path, nameOverride);
|
|
469
476
|
return "";
|
|
470
477
|
}
|
|
471
478
|
};
|
|
@@ -622,9 +629,9 @@ var JavaTypeMapper = class JavaTypeMapper extends TypeMapper {
|
|
|
622
629
|
formatStructTypeName(fieldName) {
|
|
623
630
|
return `${pascalCase(fieldName)}Result`;
|
|
624
631
|
}
|
|
625
|
-
generateStructDeclaration(column, path = "") {
|
|
632
|
+
generateStructDeclaration(column, path = "", nameOverride) {
|
|
626
633
|
if (!(column.type instanceof StructType)) throw new Error(`Expected StructType ${column}`);
|
|
627
|
-
const structName = this.formatStructTypeName(column.name);
|
|
634
|
+
const structName = nameOverride ?? this.formatStructTypeName(column.name);
|
|
628
635
|
const newPath = `${path}${structName}.`;
|
|
629
636
|
const children = column.type.fields.map((field) => {
|
|
630
637
|
return this.getDeclarations({
|
|
@@ -818,7 +825,7 @@ var TypeScriptTypeMapper = class extends TypeMapper {
|
|
|
818
825
|
formatMapTypeName(fieldName) {
|
|
819
826
|
return "Map";
|
|
820
827
|
}
|
|
821
|
-
generateStructDeclaration(column) {
|
|
828
|
+
generateStructDeclaration(column, _path, _nameOverride) {
|
|
822
829
|
if (!(column.type instanceof StructType)) throw new Error("Expected StructType");
|
|
823
830
|
return `interface ${this.formatStructTypeName(column.name)} {\n entries: {\n${column.type.fields.map((field) => {
|
|
824
831
|
const fieldType = this.getTypeName({
|
|
@@ -953,7 +960,7 @@ var PythonTypeMapper = class PythonTypeMapper extends TypeMapper {
|
|
|
953
960
|
formatMapTypeName(_fieldName) {
|
|
954
961
|
return "dict";
|
|
955
962
|
}
|
|
956
|
-
generateStructDeclaration(column, path = "") {
|
|
963
|
+
generateStructDeclaration(column, path = "", _nameOverride) {
|
|
957
964
|
if (!(column.type instanceof StructType)) throw new Error(`Expected StructType ${column}`);
|
|
958
965
|
const structName = this.formatStructTypeName(column.name);
|
|
959
966
|
const newPath = `${path}${structName}.`;
|
|
@@ -1024,7 +1031,7 @@ var BaseGenerator = class {
|
|
|
1024
1031
|
...query.columns[0],
|
|
1025
1032
|
name: query.id
|
|
1026
1033
|
});
|
|
1027
|
-
return this.getClassName(`${query.id}_Result`);
|
|
1034
|
+
return this.getClassName(query.resultTypeName ?? `${query.id}_Result`);
|
|
1028
1035
|
}
|
|
1029
1036
|
getStatement(q) {
|
|
1030
1037
|
return q.queryAnonymous;
|
|
@@ -1034,6 +1041,8 @@ var BaseGenerator = class {
|
|
|
1034
1041
|
//#region src/generators/java-generator.ts
|
|
1035
1042
|
var JavaGenerator = class extends BaseGenerator {
|
|
1036
1043
|
engine;
|
|
1044
|
+
/** Query ids that should emit their row-type record declaration (set per render). */
|
|
1045
|
+
declareTypeOwners = /* @__PURE__ */ new Set();
|
|
1037
1046
|
constructor(template, engine = "duckdb") {
|
|
1038
1047
|
super(template, new JavaTypeMapper());
|
|
1039
1048
|
this.template = template;
|
|
@@ -1084,7 +1093,21 @@ var JavaGenerator = class extends BaseGenerator {
|
|
|
1084
1093
|
if (readExpr !== null) return readExpr;
|
|
1085
1094
|
return this.typeMapper.parseValue(column, `rs.getObject(${idx})`, path);
|
|
1086
1095
|
}
|
|
1087
|
-
async beforeGenerate(_projectDir, _gen,
|
|
1096
|
+
async beforeGenerate(_projectDir, _gen, queries, tables) {
|
|
1097
|
+
this.declareTypeOwners = /* @__PURE__ */ new Set();
|
|
1098
|
+
const seenRowTypes = /* @__PURE__ */ new Set();
|
|
1099
|
+
const tableRowTypes = new Set(this.supportsAppenders(this.engine) ? tables.filter((t) => t.hasAppender).map((t) => this.getClassName(`${t.id}_row`)) : []);
|
|
1100
|
+
for (const q of queries) {
|
|
1101
|
+
if (q.skipGenerateFunction) continue;
|
|
1102
|
+
if (!q.isQuery || q.isPluck) continue;
|
|
1103
|
+
if (q.columns.length === 0) continue;
|
|
1104
|
+
const rowTypeName = this.rowType(q);
|
|
1105
|
+
if (tableRowTypes.has(rowTypeName)) continue;
|
|
1106
|
+
if (seenRowTypes.has(rowTypeName)) continue;
|
|
1107
|
+
seenRowTypes.add(rowTypeName);
|
|
1108
|
+
this.declareTypeOwners.add(q.id);
|
|
1109
|
+
}
|
|
1110
|
+
Handlebars.registerHelper("shouldDeclareType", (queryHelper) => this.declareTypeOwners.has(queryHelper.id));
|
|
1088
1111
|
Handlebars.registerHelper("isDuckDB", () => this.engine === "duckdb");
|
|
1089
1112
|
Handlebars.registerHelper("isPostgres", () => this.engine === "postgres");
|
|
1090
1113
|
Handlebars.registerHelper("pgBulkType", (column) => {
|
|
@@ -1107,7 +1130,9 @@ var JavaGenerator = class extends BaseGenerator {
|
|
|
1107
1130
|
...query.columns[0],
|
|
1108
1131
|
name: query.id
|
|
1109
1132
|
}, " ");
|
|
1110
|
-
|
|
1133
|
+
if (!this.declareTypeOwners.has(query.id)) return "";
|
|
1134
|
+
const structName = this.rowType(query);
|
|
1135
|
+
return queryHelper.typeMapper.getDeclarations(query.allColumns, "", structName);
|
|
1111
1136
|
});
|
|
1112
1137
|
Handlebars.registerHelper("appenderType", (column) => {
|
|
1113
1138
|
return this.typeMapper.getUnboxedTypeName(column);
|
|
@@ -1331,13 +1356,25 @@ var JavaDuckDBArrowGenerator = class extends BaseGenerator {
|
|
|
1331
1356
|
async beforeGenerate(projectDir, gen, queries, tables) {
|
|
1332
1357
|
const q = queries.filter((q) => q.isQuery && q.isOne || q.isMigrate);
|
|
1333
1358
|
const name = `${gen.name}-jdbc`;
|
|
1334
|
-
writeGeneratedFile(projectDir, {
|
|
1359
|
+
await writeGeneratedFile(projectDir, {
|
|
1335
1360
|
name,
|
|
1336
1361
|
generator: "java/duckdb/jdbc",
|
|
1337
1362
|
output: gen.output,
|
|
1338
1363
|
config: gen.config,
|
|
1339
1364
|
projectName: gen.projectName
|
|
1340
1365
|
}, this.javaGenerator, name, q, tables, "duckdb");
|
|
1366
|
+
const owners = /* @__PURE__ */ new Set();
|
|
1367
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1368
|
+
for (const q of queries) {
|
|
1369
|
+
if (q.skipGenerateFunction) continue;
|
|
1370
|
+
if (!q.isQuery || q.isOne) continue;
|
|
1371
|
+
if (q.columns.length === 0) continue;
|
|
1372
|
+
const rowTypeName = this.rowType(q);
|
|
1373
|
+
if (seen.has(rowTypeName)) continue;
|
|
1374
|
+
seen.add(rowTypeName);
|
|
1375
|
+
owners.add(q.id);
|
|
1376
|
+
}
|
|
1377
|
+
Handlebars.registerHelper("shouldDeclareType", (queryHelper) => owners.has(queryHelper.id));
|
|
1341
1378
|
}
|
|
1342
1379
|
isCompatibleWith(engine) {
|
|
1343
1380
|
return engine === "duckdb";
|
|
@@ -1399,7 +1436,7 @@ var JavaDuckDBArrowGenerator = class extends BaseGenerator {
|
|
|
1399
1436
|
}
|
|
1400
1437
|
rowType(query) {
|
|
1401
1438
|
if (query.isOne) return this.javaGenerator.rowType(query);
|
|
1402
|
-
return this.getClassName(`${query.id}_Result`);
|
|
1439
|
+
return this.getClassName(query.resultTypeName ?? `${query.id}_Result`);
|
|
1403
1440
|
}
|
|
1404
1441
|
};
|
|
1405
1442
|
//#endregion
|
|
@@ -2151,6 +2188,106 @@ function getOutputPath(projectDir, sqlFileName, gen, generator) {
|
|
|
2151
2188
|
mkdirSync(dirname(outputPath), { recursive: true });
|
|
2152
2189
|
return outputPath;
|
|
2153
2190
|
}
|
|
2191
|
+
function assignResultTypeNames(queries, tables, projectDir = process.cwd()) {
|
|
2192
|
+
const hints = [];
|
|
2193
|
+
const tablesByName = /* @__PURE__ */ new Map();
|
|
2194
|
+
for (const t of tables) tablesByName.set(t.tableName, t);
|
|
2195
|
+
const groups = /* @__PURE__ */ new Map();
|
|
2196
|
+
const eligible = queries.filter((q) => q.isQuery && !q.isPluck && !q.skipGenerateFunction && q.columns.length > 0);
|
|
2197
|
+
for (const q of eligible) {
|
|
2198
|
+
const cols = effectiveColumns(q);
|
|
2199
|
+
const key = JSON.stringify(cols.map((c) => ({
|
|
2200
|
+
n: c.name,
|
|
2201
|
+
t: c.type.toString(),
|
|
2202
|
+
nu: c.nullable,
|
|
2203
|
+
s: c.sourceTable ?? null
|
|
2204
|
+
})));
|
|
2205
|
+
let g = groups.get(key);
|
|
2206
|
+
if (!g) {
|
|
2207
|
+
g = { queries: [] };
|
|
2208
|
+
groups.set(key, g);
|
|
2209
|
+
}
|
|
2210
|
+
g.queries.push(q);
|
|
2211
|
+
}
|
|
2212
|
+
const recordShape = (cols) => JSON.stringify(cols.map((c) => ({
|
|
2213
|
+
n: c.name,
|
|
2214
|
+
t: c.type.toString(),
|
|
2215
|
+
nu: c.nullable
|
|
2216
|
+
})));
|
|
2217
|
+
const claims = /* @__PURE__ */ new Map();
|
|
2218
|
+
for (const t of tables) {
|
|
2219
|
+
if (!t.hasAppender) continue;
|
|
2220
|
+
const cols = t.columns.filter((c) => !c.generated);
|
|
2221
|
+
claims.set(pascalCase(`${t.id}_row`), {
|
|
2222
|
+
shape: recordShape(cols),
|
|
2223
|
+
offenderId: t.id,
|
|
2224
|
+
source: `TABLE ${t.tableName}`
|
|
2225
|
+
});
|
|
2226
|
+
}
|
|
2227
|
+
const claim = (name, shape, representative, source) => {
|
|
2228
|
+
const canonical = pascalCase(name);
|
|
2229
|
+
const existing = claims.get(canonical);
|
|
2230
|
+
if (existing && existing.shape !== shape) throw SqgError.inQuery(`Result type '${name}' would be emitted with two incompatible shapes: ${source} ('${representative.id}') vs ${existing.source} ('${existing.offenderId}')`, "VALIDATION_ERROR", representative.id, representative.filename, { suggestion: "Use a different `:result=` name for one of the queries, or change the queries so their result columns match" });
|
|
2231
|
+
if (!existing) claims.set(canonical, {
|
|
2232
|
+
shape,
|
|
2233
|
+
offenderId: representative.id,
|
|
2234
|
+
source
|
|
2235
|
+
});
|
|
2236
|
+
};
|
|
2237
|
+
for (const group of groups.values()) {
|
|
2238
|
+
const overrides = group.queries.map((q) => q.resultTypeOverride).filter((v) => !!v);
|
|
2239
|
+
const uniqueOverrides = new Set(overrides);
|
|
2240
|
+
if (uniqueOverrides.size > 1) {
|
|
2241
|
+
const offenders = group.queries.filter((q) => q.resultTypeOverride);
|
|
2242
|
+
throw SqgError.inQuery(`Conflicting ':result=' names for queries with identical result shapes: ${offenders.map((q) => `'${q.id}' uses '${q.resultTypeOverride}'`).join(", ")}`, "VALIDATION_ERROR", offenders[0].id, offenders[0].filename, { suggestion: "Pick a single name for this row type or change the queries so their shapes differ" });
|
|
2243
|
+
}
|
|
2244
|
+
const shape = recordShape(effectiveColumns(group.queries[0]));
|
|
2245
|
+
if (uniqueOverrides.size === 1) {
|
|
2246
|
+
const resolved = [...uniqueOverrides][0];
|
|
2247
|
+
claim(resolved, shape, group.queries.find((q) => q.resultTypeOverride === resolved), `:result=${resolved}`);
|
|
2248
|
+
for (const q of group.queries) q.resultTypeName = resolved;
|
|
2249
|
+
continue;
|
|
2250
|
+
}
|
|
2251
|
+
const fullMatch = tryFullTableMatch(group.queries[0], tablesByName);
|
|
2252
|
+
if (fullMatch) {
|
|
2253
|
+
claim(fullMatch, shape, group.queries[0], `full-table match`);
|
|
2254
|
+
for (const q of group.queries) q.resultTypeName = fullMatch;
|
|
2255
|
+
continue;
|
|
2256
|
+
}
|
|
2257
|
+
if (group.queries.length >= 2) {
|
|
2258
|
+
const list = group.queries.map((q) => `'${q.id}' (${displayPath(q.filename, projectDir)}:${q.line})`).join(", ");
|
|
2259
|
+
hints.push({
|
|
2260
|
+
queryIds: group.queries.map((q) => q.id),
|
|
2261
|
+
message: `${group.queries.length} queries return the same row shape: ${list}. Add \`:result=Name\` to any one of them to share a single row type.`
|
|
2262
|
+
});
|
|
2263
|
+
}
|
|
2264
|
+
}
|
|
2265
|
+
return hints;
|
|
2266
|
+
}
|
|
2267
|
+
/** Show paths relative to the project root when it's inside the tree; otherwise fall back to absolute. */
|
|
2268
|
+
function displayPath(fullPath, projectDir) {
|
|
2269
|
+
const rel = relative(projectDir, fullPath);
|
|
2270
|
+
return rel && !rel.startsWith("..") ? rel : fullPath;
|
|
2271
|
+
}
|
|
2272
|
+
/** Resolve config-overridden column info, mirroring what validateQueries does for allColumns. */
|
|
2273
|
+
function effectiveColumns(query) {
|
|
2274
|
+
return query.columns.map((col) => query.config?.getColumnInfo(col.name) ?? col);
|
|
2275
|
+
}
|
|
2276
|
+
function tryFullTableMatch(query, tablesByName) {
|
|
2277
|
+
const cols = effectiveColumns(query);
|
|
2278
|
+
const firstSource = cols[0]?.sourceTable;
|
|
2279
|
+
if (!firstSource) return void 0;
|
|
2280
|
+
if (!cols.every((c) => c.sourceTable === firstSource)) return void 0;
|
|
2281
|
+
const table = tablesByName.get(firstSource);
|
|
2282
|
+
if (!table) return void 0;
|
|
2283
|
+
if (table.columns.some((c) => c.generated)) return void 0;
|
|
2284
|
+
if (table.columns.length !== cols.length) return void 0;
|
|
2285
|
+
for (let i = 0; i < cols.length; i++) {
|
|
2286
|
+
if (cols[i].name !== table.columns[i].name) return void 0;
|
|
2287
|
+
if (cols[i].type.toString() !== table.columns[i].type.toString()) return void 0;
|
|
2288
|
+
}
|
|
2289
|
+
return `${table.id}_row`;
|
|
2290
|
+
}
|
|
2154
2291
|
function validateQueries(queries) {
|
|
2155
2292
|
for (const query of queries) {
|
|
2156
2293
|
if (query.isQuery && query.isPluck && query.columns.length !== 1) throw SqgError.inQuery(`':pluck' modifier requires exactly 1 column, but query has ${query.columns.length} columns`, "VALIDATION_ERROR", query.id, query.filename, { suggestion: query.columns.length === 0 ? "Ensure the query returns at least one column" : `Remove ':pluck' or select only one column. Current columns: ${query.columns.map((c) => c.name).join(", ")}` });
|
|
@@ -2308,6 +2445,9 @@ async function processProjectFromConfig(project, projectDir, writeToStdout = fal
|
|
|
2308
2445
|
if (tables.length > 0) await dbEngine.introspectTables(tables, reporter);
|
|
2309
2446
|
ui?.succeedPhase(`Introspected ${executableQueries.length} queries`);
|
|
2310
2447
|
validateQueries(queries);
|
|
2448
|
+
const hints = assignResultTypeNames(queries, tables, projectDir);
|
|
2449
|
+
for (const hint of hints) if (ui) ui.hint(hint.message);
|
|
2450
|
+
else consola.info(hint.message);
|
|
2311
2451
|
await dbEngine.close();
|
|
2312
2452
|
} catch (e) {
|
|
2313
2453
|
ui?.failPhase(`Failed to process ${sqlFile}`);
|
|
@@ -2395,6 +2535,10 @@ var SQLQuery = class {
|
|
|
2395
2535
|
allColumns;
|
|
2396
2536
|
/** Database-reported parameter types (variable name → SQL type), set by database adapters */
|
|
2397
2537
|
parameterTypes;
|
|
2538
|
+
/** Explicit row-type name from `:result=Name` modifier, when present. */
|
|
2539
|
+
resultTypeOverride;
|
|
2540
|
+
/** Final row-type identifier assigned by assignResultTypeNames (after introspection). */
|
|
2541
|
+
resultTypeName;
|
|
2398
2542
|
constructor(filename, id, rawQuery, queryAnonymous, queryNamed, queryPositional, type, isOne, isPluck, isBatch, variables, config, line) {
|
|
2399
2543
|
this.filename = filename;
|
|
2400
2544
|
this.id = id;
|
|
@@ -2508,6 +2652,7 @@ function parseSQLQueries(filePath, extraVariables) {
|
|
|
2508
2652
|
const isOne = modifiers.includes(":one");
|
|
2509
2653
|
const isPluck = modifiers.includes(":pluck");
|
|
2510
2654
|
const isBatch = modifiers.includes(":batch");
|
|
2655
|
+
const resultTypeOverride = modifiers.find((m) => m.startsWith(":result="))?.slice(8);
|
|
2511
2656
|
let configStr = getStr("Config", true);
|
|
2512
2657
|
if (configStr?.endsWith("*/")) configStr = configStr.slice(0, -2);
|
|
2513
2658
|
let config = null;
|
|
@@ -2662,6 +2807,7 @@ function parseSQLQueries(filePath, extraVariables) {
|
|
|
2662
2807
|
config
|
|
2663
2808
|
});
|
|
2664
2809
|
const query = new SQLQuery(filePath, name, sqlContentStr, sql.toSqlWithAnonymousPlaceholders(), sql.toSqlWithNamedPlaceholders(), sql.toSqlWithPositionalPlaceholders(), queryType, isOne, isPluck, isBatch, variables, config, annotationLine);
|
|
2810
|
+
query.resultTypeOverride = resultTypeOverride;
|
|
2665
2811
|
checkDuplicate(queryType, name);
|
|
2666
2812
|
queries.push(query);
|
|
2667
2813
|
consola.debug(`Added query: ${name} (${queryType})`);
|
|
@@ -2946,6 +3092,7 @@ const postgres = new class {
|
|
|
2946
3092
|
mode;
|
|
2947
3093
|
dynamicTypeCache = /* @__PURE__ */ new Map();
|
|
2948
3094
|
enumTypeCache = /* @__PURE__ */ new Map();
|
|
3095
|
+
tableOidCache = /* @__PURE__ */ new Map();
|
|
2949
3096
|
async startContainer(reporter) {
|
|
2950
3097
|
reporter?.onContainerStarting?.();
|
|
2951
3098
|
const container = await new PostgreSqlContainer("postgres:16-alpine").withDatabase("sqg-db").withUsername("sqg").withPassword("secret").start();
|
|
@@ -2996,10 +3143,17 @@ const postgres = new class {
|
|
|
2996
3143
|
if (enumType) return enumType;
|
|
2997
3144
|
return this.getTypeName(dataTypeID);
|
|
2998
3145
|
}
|
|
3146
|
+
async resolveTableOids(db, oids) {
|
|
3147
|
+
const missing = oids.filter((oid) => !this.tableOidCache.has(oid));
|
|
3148
|
+
if (missing.length === 0) return;
|
|
3149
|
+
const res = await db.query("SELECT oid::int AS oid, relname FROM pg_class WHERE oid = ANY($1)", [missing]);
|
|
3150
|
+
for (const row of res.rows) this.tableOidCache.set(Number(row.oid), row.relname);
|
|
3151
|
+
}
|
|
2999
3152
|
async initializeDatabase(queries, reporter) {
|
|
3000
3153
|
const externalUrl = process.env.SQG_POSTGRES_URL;
|
|
3001
3154
|
this.dynamicTypeCache = /* @__PURE__ */ new Map();
|
|
3002
3155
|
this.enumTypeCache = /* @__PURE__ */ new Map();
|
|
3156
|
+
this.tableOidCache = /* @__PURE__ */ new Map();
|
|
3003
3157
|
if (externalUrl) this.mode = new ExternalDbMode(externalUrl);
|
|
3004
3158
|
else {
|
|
3005
3159
|
const { connectionUri, container } = await this.startContainer(reporter);
|
|
@@ -3065,11 +3219,18 @@ const postgres = new class {
|
|
|
3065
3219
|
});
|
|
3066
3220
|
consola.debug("Columns:", columnNames);
|
|
3067
3221
|
consola.debug("Types:", columnTypes.map((t) => t.toString()));
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3222
|
+
const tableOids = Array.from(new Set(result.fields.map((f) => f.tableID).filter((oid) => oid && oid > 0)));
|
|
3223
|
+
await this.resolveTableOids(db, tableOids);
|
|
3224
|
+
query.columns = columnNames.map((name, index) => {
|
|
3225
|
+
const field = result.fields[index];
|
|
3226
|
+
const sourceTable = field.tableID && field.tableID > 0 ? this.tableOidCache.get(field.tableID) : void 0;
|
|
3227
|
+
return {
|
|
3228
|
+
name,
|
|
3229
|
+
type: columnTypes[index],
|
|
3230
|
+
nullable: true,
|
|
3231
|
+
sourceTable
|
|
3232
|
+
};
|
|
3233
|
+
});
|
|
3073
3234
|
}
|
|
3074
3235
|
if (query.isQuery) {
|
|
3075
3236
|
if (query.isOne) return result.rows[0] || null;
|
|
@@ -3107,6 +3268,7 @@ const postgres = new class {
|
|
|
3107
3268
|
await this.mode.close(this.db);
|
|
3108
3269
|
this.dynamicTypeCache = /* @__PURE__ */ new Map();
|
|
3109
3270
|
this.enumTypeCache = /* @__PURE__ */ new Map();
|
|
3271
|
+
this.tableOidCache = /* @__PURE__ */ new Map();
|
|
3110
3272
|
}
|
|
3111
3273
|
}();
|
|
3112
3274
|
//#endregion
|
|
@@ -3217,7 +3379,8 @@ const sqlite = new class {
|
|
|
3217
3379
|
return {
|
|
3218
3380
|
name: col.name,
|
|
3219
3381
|
type: col.type || probed.type || "unknown",
|
|
3220
|
-
nullable: col.table ? colInfo?.pk === 0 && colInfo?.notnull === 0 : probed.nullable
|
|
3382
|
+
nullable: col.table ? colInfo?.pk === 0 && colInfo?.notnull === 0 : probed.nullable,
|
|
3383
|
+
sourceTable: col.table ?? void 0
|
|
3221
3384
|
};
|
|
3222
3385
|
});
|
|
3223
3386
|
}
|
package/dist/sqg.mjs
CHANGED
|
@@ -229,11 +229,18 @@ SQL Annotation Syntax:
|
|
|
229
229
|
\${varName} Reference a variable in SQL
|
|
230
230
|
|
|
231
231
|
Modifiers:
|
|
232
|
-
:one
|
|
233
|
-
:pluck
|
|
234
|
-
:all
|
|
235
|
-
:batch
|
|
236
|
-
:appender
|
|
232
|
+
:one Return single row (or null) instead of array
|
|
233
|
+
:pluck Return single column value (requires exactly 1 column)
|
|
234
|
+
:all Return all rows (default)
|
|
235
|
+
:batch Generate a JDBC batch method for an EXEC (Java only)
|
|
236
|
+
:appender Generate bulk insert appender for TABLE annotation
|
|
237
|
+
:result=Name Name (and share) the row type (Java only). Annotate ONE query
|
|
238
|
+
with :result=Name — every other query in the same file with the
|
|
239
|
+
same column shape automatically gets the same name; you do NOT
|
|
240
|
+
need to repeat the modifier on each query.
|
|
241
|
+
Without :result=, each query keeps its own per-query row type.
|
|
242
|
+
Exception: SELECT * matching a -- TABLE schema (same columns,
|
|
243
|
+
same order) auto-uses the table's row type with no annotation.
|
|
237
244
|
|
|
238
245
|
Example:
|
|
239
246
|
-- MIGRATE 1
|
|
@@ -724,7 +731,7 @@ const parser = LRParser.deserialize({
|
|
|
724
731
|
maxTerm: 34,
|
|
725
732
|
skippedNodes: [0],
|
|
726
733
|
repeatNodeCount: 6,
|
|
727
|
-
tokenData: "$KR~RqOX#YXY'wYZ(iZ]#Y]^$W^p#Ypq'wqr#Yrs(}st#Ytu6^uw#Ywx9[xz#Yz{%_{}#Y}!OKi!O!P#Y!P!Q#2P!Q![$A]![!]$Bu!]!_#Y!_!`$Eu!`!b#Y!b!c$Fu!c!}$A]!}#R#Y#R#S$A]#S#T#Y#T#o$A]#o;'S#Y;'S;=`'q<%lO#YU#_]_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YS$ZTOz$Wz{$j{;'S$W;'S;=`%X<%lO$WS$mVOz$Wz{$j{!P$W!P!Q%S!Q;'S$W;'S;=`%X<%lO$WS%XOnSS%[P;=`<%l$WU%d__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!P#Y!P!Q&c!Q;'S#Y;'S;=`'q<%lO#YU&jVnS_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ'UV_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ'nP;=`<%l'PU'tP;=`<%l#Y~'|Xj~OX$WXY'wYp$Wpq'wqz$Wz{$j{;'S$W;'S;=`%X<%lO$W~(nTk~Oz$Wz{$j{;'S$W;'S;=`%X<%lO$WU)Sb_QOX(}XY*[YZ$WZ](}]^*[^p(}pq*[qr(}rs.yst(}tu*[uz(}z{/y{#O(}#O#P5V#P;'S(};'S;=`6W<%lO(}U*_ZOY*[YZ$WZr*[rs+Qsz*[z{+f{#O*[#O#P.Z#P;'S*[;'S;=`.s<%lO*[U+VT]QOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU+i]OY*[YZ$WZr*[rs+Qsz*[z{+f{!P*[!P!Q,b!Q#O*[#O#P.Z#P;'S*[;'S;=`.s<%lO*[U,gWnSOY-PZr-Prs-ls#O-P#O#P-q#P;'S-P;'S;=`.T<%lO-PQ-SWOY-PZr-Prs-ls#O-P#O#P-q#P;'S-P;'S;=`.T<%lO-PQ-qO]QQ-tTOY-PYZ-PZ;'S-P;'S;=`.T<%lO-PQ.WP;=`<%l-PU.^VOY*[YZ*[Zz*[z{+f{;'S*[;'S;=`.s<%lO*[U.vP;=`<%l*[U/Q]]Q_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YU0Od_QOX(}XY*[YZ$WZ](}]^*[^p(}pq*[qr(}rs.yst(}tu*[uz(}z{/y{!P(}!P!Q1^!Q#O(}#O#P5V#P;'S(};'S;=`6W<%lO(}U1e_nS_QOX2dXY-PZ]2d]^-P^p2dpq-Pqr2drs3hst2dtu-Pu#O2d#O#P4U#P;'S2d;'S;=`5P<%lO2dQ2i__QOX2dXY-PZ]2d]^-P^p2dpq-Pqr2drs3hst2dtu-Pu#O2d#O#P4U#P;'S2d;'S;=`5P<%lO2dQ3oV]Q_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ4Z[_QOX2dXY-PYZ-PZ]2d]^-P^p2dpq-Pqt2dtu-Pu;'S2d;'S;=`5P<%lO2dQ5SP;=`<%l2dU5[^_QOX(}XY*[YZ*[Z](}]^*[^p(}pq*[qt(}tu*[uz(}z{/y{;'S(};'S;=`6W<%lO(}U6ZP;=`<%l(}U6cV_QOz$Wz{$j{#o$W#o#p6x#p;'S$W;'S;=`%X<%lO$WU6{]Oz$Wz{$j{!Q$W!Q![7t![!c$W!c!}7t!}#R$W#R#S7t#S#T$W#T#o7t#o;'S$W;'S;=`%X<%lO$WU7w_Oz$Wz{$j{!Q$W!Q![7t![!c$W!c!}7t!}#R$W#R#S7t#S#T$W#T#o7t#o#q$W#q#r8v#r;'S$W;'S;=`%X<%lO$WU8{TaQOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU9ab_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[U:lZOY:iYZ$WZw:iwx;_xz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU;dT^QOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU;v]OY:iYZ$WZw:iwx;_xz:iz{;s{!P:i!P!Q<o!Q#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU<tWnSOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q=aWOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q>OO^QQ>RXOY=^YZ=^Zw=^wx>nx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q>sW^QOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q?`P;=`<%l=^U?fZOY:iYZ:iZw:iwx@Xxz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU@^Z^QOY:iYZ$WZw:iwx;_xz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iUASP;=`<%l:iUA^]^Q_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YUB[d_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{!P9[!P!QCj!Q#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UCq_nS_QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQDu__QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQE{V^Q_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQFg`_QOXDpXY=^YZ=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxGix#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQGp_^Q_QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQHrP;=`<%lDpUHzb_QOX9[XY:iYZ:iZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxJSxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UJZb^Q_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UKfP;=`<%l9[VKn__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{}#Y}!OLm!O;'S#Y;'S;=`'q<%lO#YVLthQR_QOXN`XY!&|YZ$WZ]N`]^! c^pN`pq!&|qtN`tu! cuzN`z{!#q{!dN`!d!e!=`!e!gN`!g!h!Ft!h!oN`!o!p!Ja!p!sN`!s!t#!`!t!vN`!v!w#'U!w;'SN`;'S;=`!&v<%lON`VNg^QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{;'SN`;'S;=`!&v<%lON`V! hVQROY! cYZ$WZz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!!SXQROY! cYZ$WZz! cz{! }{!P! c!P!Q!!o!Q;'S! c;'S;=`!#k<%lO! cV!!vSnSQROY!#SZ;'S!#S;'S;=`!#e<%lO!#SR!#XSQROY!#SZ;'S!#S;'S;=`!#e<%lO!#SR!#hP;=`<%l!#SV!#nP;=`<%l! cV!#x`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!PN`!P!Q!$z!Q;'SN`;'S;=`!&v<%lON`V!%TZnSQR_QOX!%vXY!#SZ]!%v]^!#S^p!%vpq!#Sqt!%vtu!#Su;'S!%v;'S;=`!&p<%lO!%vR!%}ZQR_QOX!%vXY!#SZ]!%v]^!#S^p!%vpq!#Sqt!%vtu!#Su;'S!%v;'S;=`!&p<%lO!%vR!&sP;=`<%l!%vV!&yP;=`<%lN`V!'RdQROX! cXY!&|YZ$WZp! cpq!&|qz! cz{! }{!d! c!d!e!(a!e!g! c!g!h!.l!h!o! c!o!p!0p!p!s! c!s!t!4W!t!v! c!v!w!6|!w;'S! c;'S;=`!#k<%lO! cV!(fXQROY! cYZ$WZz! cz{! }{!c! c!c!d!)R!d;'S! c;'S;=`!#k<%lO! cV!)WXQROY! cYZ$WZz! cz{! }{!u! c!u!v!)s!v;'S! c;'S;=`!#k<%lO! cV!)xXQROY! cYZ$WZz! cz{! }{!g! c!g!h!*e!h;'S! c;'S;=`!#k<%lO! cV!*jXQROY! cYZ$WZz! cz{! }{!n! c!n!o!+V!o;'S! c;'S;=`!#k<%lO! cV!+[XQROY! cYZ$WZz! cz{! }{!k! c!k!l!+w!l;'S! c;'S;=`!#k<%lO! cV!+|XQROY! cYZ$WZz! cz{! }{!p! c!p!q!,i!q;'S! c;'S;=`!#k<%lO! cV!,nXQROY! cYZ$WZz! cz{! }{!g! c!g!h!-Z!h;'S! c;'S;=`!#k<%lO! cV!-`YQROX! cXY!.OYZ$WZp! cpq!.Oqz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!.VVYRQROY! cYZ$WZz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!.qXQROY! cYZ$WZz! cz{! }{!z! c!z!{!/^!{;'S! c;'S;=`!#k<%lO! cV!/cXQROY! cYZ$WZz! cz{! }{!g! c!g!h!0O!h;'S! c;'S;=`!#k<%lO! cV!0TXQROY! cYZ$WZz! cz{! }{!e! c!e!f!-Z!f;'S! c;'S;=`!#k<%lO! cV!0uXQROY! cYZ$WZz! cz{! }{!k! c!k!l!1b!l;'S! c;'S;=`!#k<%lO! cV!1gXQROY! cYZ$WZz! cz{! }{!i! c!i!j!2S!j;'S! c;'S;=`!#k<%lO! cV!2XXQROY! cYZ$WZz! cz{! }{!t! c!t!u!2t!u;'S! c;'S;=`!#k<%lO! cV!2yXQROY! cYZ$WZz! cz{! }{!c! c!c!d!3f!d;'S! c;'S;=`!#k<%lO! cV!3kXQROY! cYZ$WZz! cz{! }{!v! c!v!w!,i!w;'S! c;'S;=`!#k<%lO! cV!4]XQROY! cYZ$WZz! cz{! }{!w! c!w!x!4x!x;'S! c;'S;=`!#k<%lO! cV!4}XQROY! cYZ$WZz! cz{! }{!g! c!g!h!5j!h;'S! c;'S;=`!#k<%lO! cV!5oXQROY! cYZ$WZz! cz{! }{!t! c!t!u!6[!u;'S! c;'S;=`!#k<%lO! cV!6aXQROY! cYZ$WZz! cz{! }{!{! c!{!|!-Z!|;'S! c;'S;=`!#k<%lO! cV!7RZQROY! cYZ$WZz! cz{! }{!c! c!c!d!7t!d!g! c!g!h!9W!h;'S! c;'S;=`!#k<%lO! cV!7yXQROY! cYZ$WZz! cz{! }{!d! c!d!e!8f!e;'S! c;'S;=`!#k<%lO! cV!8kXQROY! cYZ$WZz! cz{! }{!n! c!n!o!,i!o;'S! c;'S;=`!#k<%lO! cV!9]XQROY! cYZ$WZz! cz{! }{!u! c!u!v!9x!v;'S! c;'S;=`!#k<%lO! cV!9}XQROY! cYZ$WZz! cz{! }{!v! c!v!w!:j!w;'S! c;'S;=`!#k<%lO! cV!:oXQROY! cYZ$WZz! cz{! }{!f! c!f!g!;[!g;'S! c;'S;=`!#k<%lO! cV!;aXQROY! cYZ$WZz! cz{! }{!c! c!c!d!;|!d;'S! c;'S;=`!#k<%lO! cV!<RXQROY! cYZ$WZz! cz{! }{!v! c!v!w!<n!w;'S! c;'S;=`!#k<%lO! cV!<sXQROY! cYZ$WZz! cz{! }{!c! c!c!d!-Z!d;'S! c;'S;=`!#k<%lO! cV!=g`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d!>i!d;'SN`;'S;=`!&v<%lON`V!>p`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!uN`!u!v!?r!v;'SN`;'S;=`!&v<%lON`V!?y`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!@{!h;'SN`;'S;=`!&v<%lON`V!AS`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!nN`!n!o!BU!o;'SN`;'S;=`!&v<%lON`V!B]`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!kN`!k!l!C_!l;'SN`;'S;=`!&v<%lON`V!Cf`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!pN`!p!q!Dh!q;'SN`;'S;=`!&v<%lON`V!Do`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!Eq!h;'SN`;'S;=`!&v<%lON`V!Ex^QR_QOXN`XY!.OYZ$WZ]N`]^! c^pN`pq!.OqtN`tu! cuzN`z{!#q{;'SN`;'S;=`!&v<%lON`V!F{`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!zN`!z!{!G}!{;'SN`;'S;=`!&v<%lON`V!HU`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!IW!h;'SN`;'S;=`!&v<%lON`V!I_`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!eN`!e!f!Eq!f;'SN`;'S;=`!&v<%lON`V!Jh`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!kN`!k!l!Kj!l;'SN`;'S;=`!&v<%lON`V!Kq`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!iN`!i!j!Ls!j;'SN`;'S;=`!&v<%lON`V!Lz`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!tN`!t!u!M|!u;'SN`;'S;=`!&v<%lON`V!NT`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d# V!d;'SN`;'S;=`!&v<%lON`V# ^`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w!Dh!w;'SN`;'S;=`!&v<%lON`V#!g`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!wN`!w!x##i!x;'SN`;'S;=`!&v<%lON`V##p`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h#$r!h;'SN`;'S;=`!&v<%lON`V#$y`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!tN`!t!u#%{!u;'SN`;'S;=`!&v<%lON`V#&S`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!{N`!{!|!Eq!|;'SN`;'S;=`!&v<%lON`V#']bQR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d#(e!d!gN`!g!h#*w!h;'SN`;'S;=`!&v<%lON`V#(l`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!dN`!d!e#)n!e;'SN`;'S;=`!&v<%lON`V#)u`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!nN`!n!o!Dh!o;'SN`;'S;=`!&v<%lON`V#+O`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!uN`!u!v#,Q!v;'SN`;'S;=`!&v<%lON`V#,X`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w#-Z!w;'SN`;'S;=`!&v<%lON`V#-b`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!fN`!f!g#.d!g;'SN`;'S;=`!&v<%lON`V#.k`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d#/m!d;'SN`;'S;=`!&v<%lON`V#/t`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w#0v!w;'SN`;'S;=`!&v<%lON`V#0}`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d!Eq!d;'SN`;'S;=`!&v<%lON`V#2U]_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{#2}{;'S#Y;'S;=`'q<%lO#YV#3Sj_QOX#4tXY#8uYZ#8uZ]#4t]^#5r^p#4tpq#8uqt#4ttu#5ruz#4tz{#6{{!P#4t!P!Q#Js!Q!d#4t!d!e$ p!e!g#4t!g!h$*_!h!o#4t!o!p$-k!p!s#4t!s!t$3P!t!v#4t!v!w$7a!w;'S#4t;'S;=`#8o<%lO#4tV#4y]_QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{;'S#4t;'S;=`#8o<%lO#4tV#5uTOz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#6XVOz#5rz{#6U{!P#5r!P!Q#6n!Q;'S#5r;'S;=`#6u<%lO#5rV#6uORRnSV#6xP;=`<%l#5rV#7Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!P#4t!P!Q#8P!Q;'S#4t;'S;=`#8o<%lO#4tV#8YVRRnS_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PV#8rP;=`<%l#4tV#8xdOX#5rXY#8uYZ#8uZp#5rpq#8uqz#5rz{#6U{!d#5r!d!e#:W!e!g#5r!g!h#?o!h!o#5r!o!p#AZ!p!s#5r!s!t#Cw!t!v#5r!v!w#E{!w;'S#5r;'S;=`#6u<%lO#5rV#:ZVOz#5rz{#6U{!c#5r!c!d#:p!d;'S#5r;'S;=`#6u<%lO#5rV#:sVOz#5rz{#6U{!u#5r!u!v#;Y!v;'S#5r;'S;=`#6u<%lO#5rV#;]VOz#5rz{#6U{!g#5r!g!h#;r!h;'S#5r;'S;=`#6u<%lO#5rV#;uVOz#5rz{#6U{!n#5r!n!o#<[!o;'S#5r;'S;=`#6u<%lO#5rV#<_VOz#5rz{#6U{!k#5r!k!l#<t!l;'S#5r;'S;=`#6u<%lO#5rV#<wVOz#5rz{#6U{!p#5r!p!q#=^!q;'S#5r;'S;=`#6u<%lO#5rV#=aVOz#5rz{#6U{!g#5r!g!h#=v!h;'S#5r;'S;=`#6u<%lO#5rV#=yYOX#5rXY#>iYZ#?ZZp#5rpq#>iqz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#>nXUROX#5rXY#>iYp#5rpq#>iqz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#?`TUROz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#?rVOz#5rz{#6U{!z#5r!z!{#@X!{;'S#5r;'S;=`#6u<%lO#5rV#@[VOz#5rz{#6U{!g#5r!g!h#@q!h;'S#5r;'S;=`#6u<%lO#5rV#@tVOz#5rz{#6U{!e#5r!e!f#=v!f;'S#5r;'S;=`#6u<%lO#5rV#A^VOz#5rz{#6U{!k#5r!k!l#As!l;'S#5r;'S;=`#6u<%lO#5rV#AvVOz#5rz{#6U{!i#5r!i!j#B]!j;'S#5r;'S;=`#6u<%lO#5rV#B`VOz#5rz{#6U{!t#5r!t!u#Bu!u;'S#5r;'S;=`#6u<%lO#5rV#BxVOz#5rz{#6U{!c#5r!c!d#C_!d;'S#5r;'S;=`#6u<%lO#5rV#CbVOz#5rz{#6U{!v#5r!v!w#=^!w;'S#5r;'S;=`#6u<%lO#5rV#CzVOz#5rz{#6U{!w#5r!w!x#Da!x;'S#5r;'S;=`#6u<%lO#5rV#DdVOz#5rz{#6U{!g#5r!g!h#Dy!h;'S#5r;'S;=`#6u<%lO#5rV#D|VOz#5rz{#6U{!t#5r!t!u#Ec!u;'S#5r;'S;=`#6u<%lO#5rV#EfVOz#5rz{#6U{!{#5r!{!|#=v!|;'S#5r;'S;=`#6u<%lO#5rV#FOXOz#5rz{#6U{!c#5r!c!d#Fk!d!g#5r!g!h#Gm!h;'S#5r;'S;=`#6u<%lO#5rV#FnVOz#5rz{#6U{!d#5r!d!e#GT!e;'S#5r;'S;=`#6u<%lO#5rV#GWVOz#5rz{#6U{!n#5r!n!o#=^!o;'S#5r;'S;=`#6u<%lO#5rV#GpVOz#5rz{#6U{!u#5r!u!v#HV!v;'S#5r;'S;=`#6u<%lO#5rV#HYVOz#5rz{#6U{!v#5r!v!w#Ho!w;'S#5r;'S;=`#6u<%lO#5rV#HrVOz#5rz{#6U{!f#5r!f!g#IX!g;'S#5r;'S;=`#6u<%lO#5rV#I[VOz#5rz{#6U{!c#5r!c!d#Iq!d;'S#5r;'S;=`#6u<%lO#5rV#ItVOz#5rz{#6U{!v#5r!v!w#JZ!w;'S#5r;'S;=`#6u<%lO#5rV#J^VOz#5rz{#6U{!c#5r!c!d#=v!d;'S#5r;'S;=`#6u<%lO#5rV#Jz]nS_QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{;'S#Ks;'S;=`$ j<%lO#KsR#Kx]_QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{;'S#Ks;'S;=`$ j<%lO#KsR#LtTOz#Lqz{#MT{;'S#Lq;'S;=`#Mr<%lO#LqR#MWVOz#Lqz{#MT{!P#Lq!P!Q#Mm!Q;'S#Lq;'S;=`#Mr<%lO#LqR#MrORRR#MuP;=`<%l#LqR#M}__QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{!P#Ks!P!Q#N|!Q;'S#Ks;'S;=`$ j<%lO#KsR$ TVRR_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PR$ mP;=`<%l#KsV$ u__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$!t!d;'S#4t;'S;=`#8o<%lO#4tV$!y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!u#4t!u!v$#x!v;'S#4t;'S;=`#8o<%lO#4tV$#}__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$$|!h;'S#4t;'S;=`#8o<%lO#4tV$%R__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!n#4t!n!o$&Q!o;'S#4t;'S;=`#8o<%lO#4tV$&V__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!k#4t!k!l$'U!l;'S#4t;'S;=`#8o<%lO#4tV$'Z__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!p#4t!p!q$(Y!q;'S#4t;'S;=`#8o<%lO#4tV$(___QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$)^!h;'S#4t;'S;=`#8o<%lO#4tV$)c^_QOX#4tXY#>iYZ#?ZZ]#4t]^#5r^p#4tpq#>iqt#4ttu#5ruz#4tz{#6{{;'S#4t;'S;=`#8o<%lO#4tV$*d__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!z#4t!z!{$+c!{;'S#4t;'S;=`#8o<%lO#4tV$+h__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$,g!h;'S#4t;'S;=`#8o<%lO#4tV$,l__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!e#4t!e!f$)^!f;'S#4t;'S;=`#8o<%lO#4tV$-p__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!k#4t!k!l$.o!l;'S#4t;'S;=`#8o<%lO#4tV$.t__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!i#4t!i!j$/s!j;'S#4t;'S;=`#8o<%lO#4tV$/x__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!t#4t!t!u$0w!u;'S#4t;'S;=`#8o<%lO#4tV$0|__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$1{!d;'S#4t;'S;=`#8o<%lO#4tV$2Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$(Y!w;'S#4t;'S;=`#8o<%lO#4tV$3U__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!w#4t!w!x$4T!x;'S#4t;'S;=`#8o<%lO#4tV$4Y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$5X!h;'S#4t;'S;=`#8o<%lO#4tV$5^__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!t#4t!t!u$6]!u;'S#4t;'S;=`#8o<%lO#4tV$6b__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!{#4t!{!|$)^!|;'S#4t;'S;=`#8o<%lO#4tV$7fa_QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$8k!d!g#4t!g!h$:s!h;'S#4t;'S;=`#8o<%lO#4tV$8p__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!d#4t!d!e$9o!e;'S#4t;'S;=`#8o<%lO#4tV$9t__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!n#4t!n!o$(Y!o;'S#4t;'S;=`#8o<%lO#4tV$:x__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!u#4t!u!v$;w!v;'S#4t;'S;=`#8o<%lO#4tV$;|__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$<{!w;'S#4t;'S;=`#8o<%lO#4tV$=Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!f#4t!f!g$>P!g;'S#4t;'S;=`#8o<%lO#4tV$>U__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$?T!d;'S#4t;'S;=`#8o<%lO#4tV$?Y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$@X!w;'S#4t;'S;=`#8o<%lO#4tV$@^__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$)^!d;'S#4t;'S;=`#8o<%lO#4tV$AdeVP_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$A]![!c#Y!c!}$A]!}#R#Y#R#S$A]#S#T#Y#T#o$A]#o;'S#Y;'S;=`'q<%lO#Y~$Bze_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$D]![!c#Y!c!}$D]!}#R#Y#R#S$D]#S#T#Y#T#o$D]#o;'S#Y;'S;=`'q<%lO#Y~$DdeW~_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$D]![!c#Y!c!}$D]!}#R#Y#R#S$D]#S#T#Y#T#o$D]#o;'S#Y;'S;=`'q<%lO#YV$E|]qP_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YU$Fz__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#g#Y#g#h$Gy#h;'S#Y;'S;=`'q<%lO#YU$HO__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#X#Y#X#Y$H}#Y;'S#Y;'S;=`'q<%lO#YU$IS__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#h#Y#h#i$JR#i;'S#Y;'S;=`'q<%lO#YU$JY]pQ_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#Y",
|
|
734
|
+
tokenData: "$NX~RqOX#YXY'wYZ(iZ]#Y]^$W^p#Ypq'wqr#Yrs(}st#Ytu6^uw#Ywx9[xz#Yz{%_{}#Y}!OKi!O!P#Y!P!Q#2P!Q![$A]![!]$Bu!]!_#Y!_!`$H{!`!b#Y!b!c$I{!c!}$A]!}#R#Y#R#S$A]#S#T#Y#T#o$A]#o;'S#Y;'S;=`'q<%lO#YU#_]_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YS$ZTOz$Wz{$j{;'S$W;'S;=`%X<%lO$WS$mVOz$Wz{$j{!P$W!P!Q%S!Q;'S$W;'S;=`%X<%lO$WS%XOnSS%[P;=`<%l$WU%d__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!P#Y!P!Q&c!Q;'S#Y;'S;=`'q<%lO#YU&jVnS_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ'UV_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ'nP;=`<%l'PU'tP;=`<%l#Y~'|Xj~OX$WXY'wYp$Wpq'wqz$Wz{$j{;'S$W;'S;=`%X<%lO$W~(nTk~Oz$Wz{$j{;'S$W;'S;=`%X<%lO$WU)Sb_QOX(}XY*[YZ$WZ](}]^*[^p(}pq*[qr(}rs.yst(}tu*[uz(}z{/y{#O(}#O#P5V#P;'S(};'S;=`6W<%lO(}U*_ZOY*[YZ$WZr*[rs+Qsz*[z{+f{#O*[#O#P.Z#P;'S*[;'S;=`.s<%lO*[U+VT]QOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU+i]OY*[YZ$WZr*[rs+Qsz*[z{+f{!P*[!P!Q,b!Q#O*[#O#P.Z#P;'S*[;'S;=`.s<%lO*[U,gWnSOY-PZr-Prs-ls#O-P#O#P-q#P;'S-P;'S;=`.T<%lO-PQ-SWOY-PZr-Prs-ls#O-P#O#P-q#P;'S-P;'S;=`.T<%lO-PQ-qO]QQ-tTOY-PYZ-PZ;'S-P;'S;=`.T<%lO-PQ.WP;=`<%l-PU.^VOY*[YZ*[Zz*[z{+f{;'S*[;'S;=`.s<%lO*[U.vP;=`<%l*[U/Q]]Q_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YU0Od_QOX(}XY*[YZ$WZ](}]^*[^p(}pq*[qr(}rs.yst(}tu*[uz(}z{/y{!P(}!P!Q1^!Q#O(}#O#P5V#P;'S(};'S;=`6W<%lO(}U1e_nS_QOX2dXY-PZ]2d]^-P^p2dpq-Pqr2drs3hst2dtu-Pu#O2d#O#P4U#P;'S2d;'S;=`5P<%lO2dQ2i__QOX2dXY-PZ]2d]^-P^p2dpq-Pqr2drs3hst2dtu-Pu#O2d#O#P4U#P;'S2d;'S;=`5P<%lO2dQ3oV]Q_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQ4Z[_QOX2dXY-PYZ-PZ]2d]^-P^p2dpq-Pqt2dtu-Pu;'S2d;'S;=`5P<%lO2dQ5SP;=`<%l2dU5[^_QOX(}XY*[YZ*[Z](}]^*[^p(}pq*[qt(}tu*[uz(}z{/y{;'S(};'S;=`6W<%lO(}U6ZP;=`<%l(}U6cV_QOz$Wz{$j{#o$W#o#p6x#p;'S$W;'S;=`%X<%lO$WU6{]Oz$Wz{$j{!Q$W!Q![7t![!c$W!c!}7t!}#R$W#R#S7t#S#T$W#T#o7t#o;'S$W;'S;=`%X<%lO$WU7w_Oz$Wz{$j{!Q$W!Q![7t![!c$W!c!}7t!}#R$W#R#S7t#S#T$W#T#o7t#o#q$W#q#r8v#r;'S$W;'S;=`%X<%lO$WU8{TaQOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU9ab_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[U:lZOY:iYZ$WZw:iwx;_xz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU;dT^QOz$Wz{$j{;'S$W;'S;=`%X<%lO$WU;v]OY:iYZ$WZw:iwx;_xz:iz{;s{!P:i!P!Q<o!Q#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU<tWnSOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q=aWOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q>OO^QQ>RXOY=^YZ=^Zw=^wx>nx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q>sW^QOY=^Zw=^wx=yx#O=^#O#P>O#P;'S=^;'S;=`?]<%lO=^Q?`P;=`<%l=^U?fZOY:iYZ:iZw:iwx@Xxz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iU@^Z^QOY:iYZ$WZw:iwx;_xz:iz{;s{#O:i#O#P?c#P;'S:i;'S;=`AP<%lO:iUASP;=`<%l:iUA^]^Q_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YUB[d_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{!P9[!P!QCj!Q#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UCq_nS_QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQDu__QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQE{V^Q_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PQFg`_QOXDpXY=^YZ=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxGix#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQGp_^Q_QOXDpXY=^Z]Dp]^=^^pDppq=^qtDptu=^uwDpwxEtx#ODp#O#PFb#P;'SDp;'S;=`Ho<%lODpQHrP;=`<%lDpUHzb_QOX9[XY:iYZ:iZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxJSxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UJZb^Q_QOX9[XY:iYZ$WZ]9[]^:i^p9[pq:iqt9[tu:iuw9[wxAVxz9[z{BV{#O9[#O#PHu#P;'S9[;'S;=`Kc<%lO9[UKfP;=`<%l9[VKn__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{}#Y}!OLm!O;'S#Y;'S;=`'q<%lO#YVLthQR_QOXN`XY!&|YZ$WZ]N`]^! c^pN`pq!&|qtN`tu! cuzN`z{!#q{!dN`!d!e!=`!e!gN`!g!h!Ft!h!oN`!o!p!Ja!p!sN`!s!t#!`!t!vN`!v!w#'U!w;'SN`;'S;=`!&v<%lON`VNg^QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{;'SN`;'S;=`!&v<%lON`V! hVQROY! cYZ$WZz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!!SXQROY! cYZ$WZz! cz{! }{!P! c!P!Q!!o!Q;'S! c;'S;=`!#k<%lO! cV!!vSnSQROY!#SZ;'S!#S;'S;=`!#e<%lO!#SR!#XSQROY!#SZ;'S!#S;'S;=`!#e<%lO!#SR!#hP;=`<%l!#SV!#nP;=`<%l! cV!#x`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!PN`!P!Q!$z!Q;'SN`;'S;=`!&v<%lON`V!%TZnSQR_QOX!%vXY!#SZ]!%v]^!#S^p!%vpq!#Sqt!%vtu!#Su;'S!%v;'S;=`!&p<%lO!%vR!%}ZQR_QOX!%vXY!#SZ]!%v]^!#S^p!%vpq!#Sqt!%vtu!#Su;'S!%v;'S;=`!&p<%lO!%vR!&sP;=`<%l!%vV!&yP;=`<%lN`V!'RdQROX! cXY!&|YZ$WZp! cpq!&|qz! cz{! }{!d! c!d!e!(a!e!g! c!g!h!.l!h!o! c!o!p!0p!p!s! c!s!t!4W!t!v! c!v!w!6|!w;'S! c;'S;=`!#k<%lO! cV!(fXQROY! cYZ$WZz! cz{! }{!c! c!c!d!)R!d;'S! c;'S;=`!#k<%lO! cV!)WXQROY! cYZ$WZz! cz{! }{!u! c!u!v!)s!v;'S! c;'S;=`!#k<%lO! cV!)xXQROY! cYZ$WZz! cz{! }{!g! c!g!h!*e!h;'S! c;'S;=`!#k<%lO! cV!*jXQROY! cYZ$WZz! cz{! }{!n! c!n!o!+V!o;'S! c;'S;=`!#k<%lO! cV!+[XQROY! cYZ$WZz! cz{! }{!k! c!k!l!+w!l;'S! c;'S;=`!#k<%lO! cV!+|XQROY! cYZ$WZz! cz{! }{!p! c!p!q!,i!q;'S! c;'S;=`!#k<%lO! cV!,nXQROY! cYZ$WZz! cz{! }{!g! c!g!h!-Z!h;'S! c;'S;=`!#k<%lO! cV!-`YQROX! cXY!.OYZ$WZp! cpq!.Oqz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!.VVYRQROY! cYZ$WZz! cz{! }{;'S! c;'S;=`!#k<%lO! cV!.qXQROY! cYZ$WZz! cz{! }{!z! c!z!{!/^!{;'S! c;'S;=`!#k<%lO! cV!/cXQROY! cYZ$WZz! cz{! }{!g! c!g!h!0O!h;'S! c;'S;=`!#k<%lO! cV!0TXQROY! cYZ$WZz! cz{! }{!e! c!e!f!-Z!f;'S! c;'S;=`!#k<%lO! cV!0uXQROY! cYZ$WZz! cz{! }{!k! c!k!l!1b!l;'S! c;'S;=`!#k<%lO! cV!1gXQROY! cYZ$WZz! cz{! }{!i! c!i!j!2S!j;'S! c;'S;=`!#k<%lO! cV!2XXQROY! cYZ$WZz! cz{! }{!t! c!t!u!2t!u;'S! c;'S;=`!#k<%lO! cV!2yXQROY! cYZ$WZz! cz{! }{!c! c!c!d!3f!d;'S! c;'S;=`!#k<%lO! cV!3kXQROY! cYZ$WZz! cz{! }{!v! c!v!w!,i!w;'S! c;'S;=`!#k<%lO! cV!4]XQROY! cYZ$WZz! cz{! }{!w! c!w!x!4x!x;'S! c;'S;=`!#k<%lO! cV!4}XQROY! cYZ$WZz! cz{! }{!g! c!g!h!5j!h;'S! c;'S;=`!#k<%lO! cV!5oXQROY! cYZ$WZz! cz{! }{!t! c!t!u!6[!u;'S! c;'S;=`!#k<%lO! cV!6aXQROY! cYZ$WZz! cz{! }{!{! c!{!|!-Z!|;'S! c;'S;=`!#k<%lO! cV!7RZQROY! cYZ$WZz! cz{! }{!c! c!c!d!7t!d!g! c!g!h!9W!h;'S! c;'S;=`!#k<%lO! cV!7yXQROY! cYZ$WZz! cz{! }{!d! c!d!e!8f!e;'S! c;'S;=`!#k<%lO! cV!8kXQROY! cYZ$WZz! cz{! }{!n! c!n!o!,i!o;'S! c;'S;=`!#k<%lO! cV!9]XQROY! cYZ$WZz! cz{! }{!u! c!u!v!9x!v;'S! c;'S;=`!#k<%lO! cV!9}XQROY! cYZ$WZz! cz{! }{!v! c!v!w!:j!w;'S! c;'S;=`!#k<%lO! cV!:oXQROY! cYZ$WZz! cz{! }{!f! c!f!g!;[!g;'S! c;'S;=`!#k<%lO! cV!;aXQROY! cYZ$WZz! cz{! }{!c! c!c!d!;|!d;'S! c;'S;=`!#k<%lO! cV!<RXQROY! cYZ$WZz! cz{! }{!v! c!v!w!<n!w;'S! c;'S;=`!#k<%lO! cV!<sXQROY! cYZ$WZz! cz{! }{!c! c!c!d!-Z!d;'S! c;'S;=`!#k<%lO! cV!=g`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d!>i!d;'SN`;'S;=`!&v<%lON`V!>p`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!uN`!u!v!?r!v;'SN`;'S;=`!&v<%lON`V!?y`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!@{!h;'SN`;'S;=`!&v<%lON`V!AS`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!nN`!n!o!BU!o;'SN`;'S;=`!&v<%lON`V!B]`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!kN`!k!l!C_!l;'SN`;'S;=`!&v<%lON`V!Cf`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!pN`!p!q!Dh!q;'SN`;'S;=`!&v<%lON`V!Do`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!Eq!h;'SN`;'S;=`!&v<%lON`V!Ex^QR_QOXN`XY!.OYZ$WZ]N`]^! c^pN`pq!.OqtN`tu! cuzN`z{!#q{;'SN`;'S;=`!&v<%lON`V!F{`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!zN`!z!{!G}!{;'SN`;'S;=`!&v<%lON`V!HU`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h!IW!h;'SN`;'S;=`!&v<%lON`V!I_`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!eN`!e!f!Eq!f;'SN`;'S;=`!&v<%lON`V!Jh`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!kN`!k!l!Kj!l;'SN`;'S;=`!&v<%lON`V!Kq`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!iN`!i!j!Ls!j;'SN`;'S;=`!&v<%lON`V!Lz`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!tN`!t!u!M|!u;'SN`;'S;=`!&v<%lON`V!NT`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d# V!d;'SN`;'S;=`!&v<%lON`V# ^`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w!Dh!w;'SN`;'S;=`!&v<%lON`V#!g`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!wN`!w!x##i!x;'SN`;'S;=`!&v<%lON`V##p`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!gN`!g!h#$r!h;'SN`;'S;=`!&v<%lON`V#$y`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!tN`!t!u#%{!u;'SN`;'S;=`!&v<%lON`V#&S`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!{N`!{!|!Eq!|;'SN`;'S;=`!&v<%lON`V#']bQR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d#(e!d!gN`!g!h#*w!h;'SN`;'S;=`!&v<%lON`V#(l`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!dN`!d!e#)n!e;'SN`;'S;=`!&v<%lON`V#)u`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!nN`!n!o!Dh!o;'SN`;'S;=`!&v<%lON`V#+O`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!uN`!u!v#,Q!v;'SN`;'S;=`!&v<%lON`V#,X`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w#-Z!w;'SN`;'S;=`!&v<%lON`V#-b`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!fN`!f!g#.d!g;'SN`;'S;=`!&v<%lON`V#.k`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d#/m!d;'SN`;'S;=`!&v<%lON`V#/t`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!vN`!v!w#0v!w;'SN`;'S;=`!&v<%lON`V#0}`QR_QOXN`XY! cYZ$WZ]N`]^! c^pN`pq! cqtN`tu! cuzN`z{!#q{!cN`!c!d!Eq!d;'SN`;'S;=`!&v<%lON`V#2U]_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{#2}{;'S#Y;'S;=`'q<%lO#YV#3Sj_QOX#4tXY#8uYZ#8uZ]#4t]^#5r^p#4tpq#8uqt#4ttu#5ruz#4tz{#6{{!P#4t!P!Q#Js!Q!d#4t!d!e$ p!e!g#4t!g!h$*_!h!o#4t!o!p$-k!p!s#4t!s!t$3P!t!v#4t!v!w$7a!w;'S#4t;'S;=`#8o<%lO#4tV#4y]_QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{;'S#4t;'S;=`#8o<%lO#4tV#5uTOz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#6XVOz#5rz{#6U{!P#5r!P!Q#6n!Q;'S#5r;'S;=`#6u<%lO#5rV#6uORRnSV#6xP;=`<%l#5rV#7Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!P#4t!P!Q#8P!Q;'S#4t;'S;=`#8o<%lO#4tV#8YVRRnS_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PV#8rP;=`<%l#4tV#8xdOX#5rXY#8uYZ#8uZp#5rpq#8uqz#5rz{#6U{!d#5r!d!e#:W!e!g#5r!g!h#?o!h!o#5r!o!p#AZ!p!s#5r!s!t#Cw!t!v#5r!v!w#E{!w;'S#5r;'S;=`#6u<%lO#5rV#:ZVOz#5rz{#6U{!c#5r!c!d#:p!d;'S#5r;'S;=`#6u<%lO#5rV#:sVOz#5rz{#6U{!u#5r!u!v#;Y!v;'S#5r;'S;=`#6u<%lO#5rV#;]VOz#5rz{#6U{!g#5r!g!h#;r!h;'S#5r;'S;=`#6u<%lO#5rV#;uVOz#5rz{#6U{!n#5r!n!o#<[!o;'S#5r;'S;=`#6u<%lO#5rV#<_VOz#5rz{#6U{!k#5r!k!l#<t!l;'S#5r;'S;=`#6u<%lO#5rV#<wVOz#5rz{#6U{!p#5r!p!q#=^!q;'S#5r;'S;=`#6u<%lO#5rV#=aVOz#5rz{#6U{!g#5r!g!h#=v!h;'S#5r;'S;=`#6u<%lO#5rV#=yYOX#5rXY#>iYZ#?ZZp#5rpq#>iqz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#>nXUROX#5rXY#>iYp#5rpq#>iqz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#?`TUROz#5rz{#6U{;'S#5r;'S;=`#6u<%lO#5rV#?rVOz#5rz{#6U{!z#5r!z!{#@X!{;'S#5r;'S;=`#6u<%lO#5rV#@[VOz#5rz{#6U{!g#5r!g!h#@q!h;'S#5r;'S;=`#6u<%lO#5rV#@tVOz#5rz{#6U{!e#5r!e!f#=v!f;'S#5r;'S;=`#6u<%lO#5rV#A^VOz#5rz{#6U{!k#5r!k!l#As!l;'S#5r;'S;=`#6u<%lO#5rV#AvVOz#5rz{#6U{!i#5r!i!j#B]!j;'S#5r;'S;=`#6u<%lO#5rV#B`VOz#5rz{#6U{!t#5r!t!u#Bu!u;'S#5r;'S;=`#6u<%lO#5rV#BxVOz#5rz{#6U{!c#5r!c!d#C_!d;'S#5r;'S;=`#6u<%lO#5rV#CbVOz#5rz{#6U{!v#5r!v!w#=^!w;'S#5r;'S;=`#6u<%lO#5rV#CzVOz#5rz{#6U{!w#5r!w!x#Da!x;'S#5r;'S;=`#6u<%lO#5rV#DdVOz#5rz{#6U{!g#5r!g!h#Dy!h;'S#5r;'S;=`#6u<%lO#5rV#D|VOz#5rz{#6U{!t#5r!t!u#Ec!u;'S#5r;'S;=`#6u<%lO#5rV#EfVOz#5rz{#6U{!{#5r!{!|#=v!|;'S#5r;'S;=`#6u<%lO#5rV#FOXOz#5rz{#6U{!c#5r!c!d#Fk!d!g#5r!g!h#Gm!h;'S#5r;'S;=`#6u<%lO#5rV#FnVOz#5rz{#6U{!d#5r!d!e#GT!e;'S#5r;'S;=`#6u<%lO#5rV#GWVOz#5rz{#6U{!n#5r!n!o#=^!o;'S#5r;'S;=`#6u<%lO#5rV#GpVOz#5rz{#6U{!u#5r!u!v#HV!v;'S#5r;'S;=`#6u<%lO#5rV#HYVOz#5rz{#6U{!v#5r!v!w#Ho!w;'S#5r;'S;=`#6u<%lO#5rV#HrVOz#5rz{#6U{!f#5r!f!g#IX!g;'S#5r;'S;=`#6u<%lO#5rV#I[VOz#5rz{#6U{!c#5r!c!d#Iq!d;'S#5r;'S;=`#6u<%lO#5rV#ItVOz#5rz{#6U{!v#5r!v!w#JZ!w;'S#5r;'S;=`#6u<%lO#5rV#J^VOz#5rz{#6U{!c#5r!c!d#=v!d;'S#5r;'S;=`#6u<%lO#5rV#Jz]nS_QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{;'S#Ks;'S;=`$ j<%lO#KsR#Kx]_QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{;'S#Ks;'S;=`$ j<%lO#KsR#LtTOz#Lqz{#MT{;'S#Lq;'S;=`#Mr<%lO#LqR#MWVOz#Lqz{#MT{!P#Lq!P!Q#Mm!Q;'S#Lq;'S;=`#Mr<%lO#LqR#MrORRR#MuP;=`<%l#LqR#M}__QOX#KsXZ#LqZ]#Ks]^#Lq^p#Kspq#Lqqt#Kstu#Lquz#Ksz{#Mx{!P#Ks!P!Q#N|!Q;'S#Ks;'S;=`$ j<%lO#KsR$ TVRR_QOX'PZ]'P^p'Pqt'Pu;'S'P;'S;=`'k<%lO'PR$ mP;=`<%l#KsV$ u__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$!t!d;'S#4t;'S;=`#8o<%lO#4tV$!y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!u#4t!u!v$#x!v;'S#4t;'S;=`#8o<%lO#4tV$#}__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$$|!h;'S#4t;'S;=`#8o<%lO#4tV$%R__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!n#4t!n!o$&Q!o;'S#4t;'S;=`#8o<%lO#4tV$&V__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!k#4t!k!l$'U!l;'S#4t;'S;=`#8o<%lO#4tV$'Z__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!p#4t!p!q$(Y!q;'S#4t;'S;=`#8o<%lO#4tV$(___QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$)^!h;'S#4t;'S;=`#8o<%lO#4tV$)c^_QOX#4tXY#>iYZ#?ZZ]#4t]^#5r^p#4tpq#>iqt#4ttu#5ruz#4tz{#6{{;'S#4t;'S;=`#8o<%lO#4tV$*d__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!z#4t!z!{$+c!{;'S#4t;'S;=`#8o<%lO#4tV$+h__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$,g!h;'S#4t;'S;=`#8o<%lO#4tV$,l__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!e#4t!e!f$)^!f;'S#4t;'S;=`#8o<%lO#4tV$-p__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!k#4t!k!l$.o!l;'S#4t;'S;=`#8o<%lO#4tV$.t__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!i#4t!i!j$/s!j;'S#4t;'S;=`#8o<%lO#4tV$/x__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!t#4t!t!u$0w!u;'S#4t;'S;=`#8o<%lO#4tV$0|__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$1{!d;'S#4t;'S;=`#8o<%lO#4tV$2Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$(Y!w;'S#4t;'S;=`#8o<%lO#4tV$3U__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!w#4t!w!x$4T!x;'S#4t;'S;=`#8o<%lO#4tV$4Y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!g#4t!g!h$5X!h;'S#4t;'S;=`#8o<%lO#4tV$5^__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!t#4t!t!u$6]!u;'S#4t;'S;=`#8o<%lO#4tV$6b__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!{#4t!{!|$)^!|;'S#4t;'S;=`#8o<%lO#4tV$7fa_QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$8k!d!g#4t!g!h$:s!h;'S#4t;'S;=`#8o<%lO#4tV$8p__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!d#4t!d!e$9o!e;'S#4t;'S;=`#8o<%lO#4tV$9t__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!n#4t!n!o$(Y!o;'S#4t;'S;=`#8o<%lO#4tV$:x__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!u#4t!u!v$;w!v;'S#4t;'S;=`#8o<%lO#4tV$;|__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$<{!w;'S#4t;'S;=`#8o<%lO#4tV$=Q__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!f#4t!f!g$>P!g;'S#4t;'S;=`#8o<%lO#4tV$>U__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$?T!d;'S#4t;'S;=`#8o<%lO#4tV$?Y__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!v#4t!v!w$@X!w;'S#4t;'S;=`#8o<%lO#4tV$@^__QOX#4tXZ#5rZ]#4t]^#5r^p#4tpq#5rqt#4ttu#5ruz#4tz{#6{{!c#4t!c!d$)^!d;'S#4t;'S;=`#8o<%lO#4tV$AdeVP_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$A]![!c#Y!c!}$A]!}#R#Y#R#S$A]#S#T#Y#T#o$A]#o;'S#Y;'S;=`'q<%lO#Y~$Bze_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$D]![!c#Y!c!}$D]!}#R#Y#R#S$D]#S#T#Y#T#o$D]#o;'S#Y;'S;=`'q<%lO#Y~$DdgW~_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$D]![!_#Y!_!`$E{!`!c#Y!c!}$D]!}#R#Y#R#S$D]#S#T#Y#T#o$D]#o;'S#Y;'S;=`'q<%lO#Y~$FQe_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$Gc![!c#Y!c!}$Gc!}#R#Y#R#S$Gc#S#T#Y#T#o$Gc#o;'S#Y;'S;=`'q<%lO#Y~$GjeW~_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{!Q#Y!Q![$Gc![!c#Y!c!}$Gc!}#R#Y#R#S$Gc#S#T#Y#T#o$Gc#o;'S#Y;'S;=`'q<%lO#YV$IS]qP_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#YU$JQ__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#g#Y#g#h$KP#h;'S#Y;'S;=`'q<%lO#YU$KU__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#X#Y#X#Y$LT#Y;'S#Y;'S;=`'q<%lO#YU$LY__QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{#h#Y#h#i$MX#i;'S#Y;'S;=`'q<%lO#YU$M`]pQ_QOX#YXZ$WZ]#Y]^$W^p#Ypq$Wqt#Ytu$Wuz#Yz{%_{;'S#Y;'S;=`'q<%lO#Y",
|
|
728
735
|
tokenizers: [
|
|
729
736
|
0,
|
|
730
737
|
1,
|
|
@@ -774,6 +781,10 @@ var SQLQuery = class {
|
|
|
774
781
|
allColumns;
|
|
775
782
|
/** Database-reported parameter types (variable name → SQL type), set by database adapters */
|
|
776
783
|
parameterTypes;
|
|
784
|
+
/** Explicit row-type name from `:result=Name` modifier, when present. */
|
|
785
|
+
resultTypeOverride;
|
|
786
|
+
/** Final row-type identifier assigned by assignResultTypeNames (after introspection). */
|
|
787
|
+
resultTypeName;
|
|
777
788
|
constructor(filename, id, rawQuery, queryAnonymous, queryNamed, queryPositional, type, isOne, isPluck, isBatch, variables, config, line) {
|
|
778
789
|
this.filename = filename;
|
|
779
790
|
this.id = id;
|
|
@@ -887,6 +898,7 @@ function parseSQLQueries(filePath, extraVariables) {
|
|
|
887
898
|
const isOne = modifiers.includes(":one");
|
|
888
899
|
const isPluck = modifiers.includes(":pluck");
|
|
889
900
|
const isBatch = modifiers.includes(":batch");
|
|
901
|
+
const resultTypeOverride = modifiers.find((m) => m.startsWith(":result="))?.slice(8);
|
|
890
902
|
let configStr = getStr("Config", true);
|
|
891
903
|
if (configStr?.endsWith("*/")) configStr = configStr.slice(0, -2);
|
|
892
904
|
let config = null;
|
|
@@ -1041,6 +1053,7 @@ function parseSQLQueries(filePath, extraVariables) {
|
|
|
1041
1053
|
config
|
|
1042
1054
|
});
|
|
1043
1055
|
const query = new SQLQuery(filePath, name, sqlContentStr, sql.toSqlWithAnonymousPlaceholders(), sql.toSqlWithNamedPlaceholders(), sql.toSqlWithPositionalPlaceholders(), queryType, isOne, isPluck, isBatch, variables, config, annotationLine);
|
|
1056
|
+
query.resultTypeOverride = resultTypeOverride;
|
|
1044
1057
|
checkDuplicate(queryType, name);
|
|
1045
1058
|
queries.push(query);
|
|
1046
1059
|
consola.debug(`Added query: ${name} (${queryType})`);
|
|
@@ -1325,6 +1338,7 @@ const postgres = new class {
|
|
|
1325
1338
|
mode;
|
|
1326
1339
|
dynamicTypeCache = /* @__PURE__ */ new Map();
|
|
1327
1340
|
enumTypeCache = /* @__PURE__ */ new Map();
|
|
1341
|
+
tableOidCache = /* @__PURE__ */ new Map();
|
|
1328
1342
|
async startContainer(reporter) {
|
|
1329
1343
|
reporter?.onContainerStarting?.();
|
|
1330
1344
|
const container = await new PostgreSqlContainer("postgres:16-alpine").withDatabase("sqg-db").withUsername("sqg").withPassword("secret").start();
|
|
@@ -1375,10 +1389,17 @@ const postgres = new class {
|
|
|
1375
1389
|
if (enumType) return enumType;
|
|
1376
1390
|
return this.getTypeName(dataTypeID);
|
|
1377
1391
|
}
|
|
1392
|
+
async resolveTableOids(db, oids) {
|
|
1393
|
+
const missing = oids.filter((oid) => !this.tableOidCache.has(oid));
|
|
1394
|
+
if (missing.length === 0) return;
|
|
1395
|
+
const res = await db.query("SELECT oid::int AS oid, relname FROM pg_class WHERE oid = ANY($1)", [missing]);
|
|
1396
|
+
for (const row of res.rows) this.tableOidCache.set(Number(row.oid), row.relname);
|
|
1397
|
+
}
|
|
1378
1398
|
async initializeDatabase(queries, reporter) {
|
|
1379
1399
|
const externalUrl = process.env.SQG_POSTGRES_URL;
|
|
1380
1400
|
this.dynamicTypeCache = /* @__PURE__ */ new Map();
|
|
1381
1401
|
this.enumTypeCache = /* @__PURE__ */ new Map();
|
|
1402
|
+
this.tableOidCache = /* @__PURE__ */ new Map();
|
|
1382
1403
|
if (externalUrl) this.mode = new ExternalDbMode(externalUrl);
|
|
1383
1404
|
else {
|
|
1384
1405
|
const { connectionUri, container } = await this.startContainer(reporter);
|
|
@@ -1444,11 +1465,18 @@ const postgres = new class {
|
|
|
1444
1465
|
});
|
|
1445
1466
|
consola.debug("Columns:", columnNames);
|
|
1446
1467
|
consola.debug("Types:", columnTypes.map((t) => t.toString()));
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1468
|
+
const tableOids = Array.from(new Set(result.fields.map((f) => f.tableID).filter((oid) => oid && oid > 0)));
|
|
1469
|
+
await this.resolveTableOids(db, tableOids);
|
|
1470
|
+
query.columns = columnNames.map((name, index) => {
|
|
1471
|
+
const field = result.fields[index];
|
|
1472
|
+
const sourceTable = field.tableID && field.tableID > 0 ? this.tableOidCache.get(field.tableID) : void 0;
|
|
1473
|
+
return {
|
|
1474
|
+
name,
|
|
1475
|
+
type: columnTypes[index],
|
|
1476
|
+
nullable: true,
|
|
1477
|
+
sourceTable
|
|
1478
|
+
};
|
|
1479
|
+
});
|
|
1452
1480
|
}
|
|
1453
1481
|
if (query.isQuery) {
|
|
1454
1482
|
if (query.isOne) return result.rows[0] || null;
|
|
@@ -1486,6 +1514,7 @@ const postgres = new class {
|
|
|
1486
1514
|
await this.mode.close(this.db);
|
|
1487
1515
|
this.dynamicTypeCache = /* @__PURE__ */ new Map();
|
|
1488
1516
|
this.enumTypeCache = /* @__PURE__ */ new Map();
|
|
1517
|
+
this.tableOidCache = /* @__PURE__ */ new Map();
|
|
1489
1518
|
}
|
|
1490
1519
|
}();
|
|
1491
1520
|
//#endregion
|
|
@@ -1596,7 +1625,8 @@ const sqlite = new class {
|
|
|
1596
1625
|
return {
|
|
1597
1626
|
name: col.name,
|
|
1598
1627
|
type: col.type || probed.type || "unknown",
|
|
1599
|
-
nullable: col.table ? colInfo?.pk === 0 && colInfo?.notnull === 0 : probed.nullable
|
|
1628
|
+
nullable: col.table ? colInfo?.pk === 0 && colInfo?.notnull === 0 : probed.nullable,
|
|
1629
|
+
sourceTable: col.table ?? void 0
|
|
1600
1630
|
};
|
|
1601
1631
|
});
|
|
1602
1632
|
}
|
|
@@ -1666,13 +1696,13 @@ var TypeMapper = class {
|
|
|
1666
1696
|
* @param path - Optional prefix path for nested type references
|
|
1667
1697
|
* @returns Generated type declaration code, or empty string for primitive types
|
|
1668
1698
|
*/
|
|
1669
|
-
getDeclarations(column, path = "") {
|
|
1670
|
-
if (column.type instanceof StructType) return this.generateStructDeclaration(column, path);
|
|
1699
|
+
getDeclarations(column, path = "", nameOverride) {
|
|
1700
|
+
if (column.type instanceof StructType) return this.generateStructDeclaration(column, path, nameOverride);
|
|
1671
1701
|
if (column.type instanceof ListType) return this.getDeclarations({
|
|
1672
1702
|
name: column.name,
|
|
1673
1703
|
type: column.type.baseType,
|
|
1674
1704
|
nullable: true
|
|
1675
|
-
}, path);
|
|
1705
|
+
}, path, nameOverride);
|
|
1676
1706
|
return "";
|
|
1677
1707
|
}
|
|
1678
1708
|
};
|
|
@@ -1829,9 +1859,9 @@ var JavaTypeMapper = class JavaTypeMapper extends TypeMapper {
|
|
|
1829
1859
|
formatStructTypeName(fieldName) {
|
|
1830
1860
|
return `${pascalCase(fieldName)}Result`;
|
|
1831
1861
|
}
|
|
1832
|
-
generateStructDeclaration(column, path = "") {
|
|
1862
|
+
generateStructDeclaration(column, path = "", nameOverride) {
|
|
1833
1863
|
if (!(column.type instanceof StructType)) throw new Error(`Expected StructType ${column}`);
|
|
1834
|
-
const structName = this.formatStructTypeName(column.name);
|
|
1864
|
+
const structName = nameOverride ?? this.formatStructTypeName(column.name);
|
|
1835
1865
|
const newPath = `${path}${structName}.`;
|
|
1836
1866
|
const children = column.type.fields.map((field) => {
|
|
1837
1867
|
return this.getDeclarations({
|
|
@@ -2025,7 +2055,7 @@ var TypeScriptTypeMapper = class extends TypeMapper {
|
|
|
2025
2055
|
formatMapTypeName(fieldName) {
|
|
2026
2056
|
return "Map";
|
|
2027
2057
|
}
|
|
2028
|
-
generateStructDeclaration(column) {
|
|
2058
|
+
generateStructDeclaration(column, _path, _nameOverride) {
|
|
2029
2059
|
if (!(column.type instanceof StructType)) throw new Error("Expected StructType");
|
|
2030
2060
|
return `interface ${this.formatStructTypeName(column.name)} {\n entries: {\n${column.type.fields.map((field) => {
|
|
2031
2061
|
const fieldType = this.getTypeName({
|
|
@@ -2160,7 +2190,7 @@ var PythonTypeMapper = class PythonTypeMapper extends TypeMapper {
|
|
|
2160
2190
|
formatMapTypeName(_fieldName) {
|
|
2161
2191
|
return "dict";
|
|
2162
2192
|
}
|
|
2163
|
-
generateStructDeclaration(column, path = "") {
|
|
2193
|
+
generateStructDeclaration(column, path = "", _nameOverride) {
|
|
2164
2194
|
if (!(column.type instanceof StructType)) throw new Error(`Expected StructType ${column}`);
|
|
2165
2195
|
const structName = this.formatStructTypeName(column.name);
|
|
2166
2196
|
const newPath = `${path}${structName}.`;
|
|
@@ -2231,7 +2261,7 @@ var BaseGenerator = class {
|
|
|
2231
2261
|
...query.columns[0],
|
|
2232
2262
|
name: query.id
|
|
2233
2263
|
});
|
|
2234
|
-
return this.getClassName(`${query.id}_Result`);
|
|
2264
|
+
return this.getClassName(query.resultTypeName ?? `${query.id}_Result`);
|
|
2235
2265
|
}
|
|
2236
2266
|
getStatement(q) {
|
|
2237
2267
|
return q.queryAnonymous;
|
|
@@ -2241,6 +2271,8 @@ var BaseGenerator = class {
|
|
|
2241
2271
|
//#region src/generators/java-generator.ts
|
|
2242
2272
|
var JavaGenerator = class extends BaseGenerator {
|
|
2243
2273
|
engine;
|
|
2274
|
+
/** Query ids that should emit their row-type record declaration (set per render). */
|
|
2275
|
+
declareTypeOwners = /* @__PURE__ */ new Set();
|
|
2244
2276
|
constructor(template, engine = "duckdb") {
|
|
2245
2277
|
super(template, new JavaTypeMapper());
|
|
2246
2278
|
this.template = template;
|
|
@@ -2291,7 +2323,21 @@ var JavaGenerator = class extends BaseGenerator {
|
|
|
2291
2323
|
if (readExpr !== null) return readExpr;
|
|
2292
2324
|
return this.typeMapper.parseValue(column, `rs.getObject(${idx})`, path);
|
|
2293
2325
|
}
|
|
2294
|
-
async beforeGenerate(_projectDir, _gen,
|
|
2326
|
+
async beforeGenerate(_projectDir, _gen, queries, tables) {
|
|
2327
|
+
this.declareTypeOwners = /* @__PURE__ */ new Set();
|
|
2328
|
+
const seenRowTypes = /* @__PURE__ */ new Set();
|
|
2329
|
+
const tableRowTypes = new Set(this.supportsAppenders(this.engine) ? tables.filter((t) => t.hasAppender).map((t) => this.getClassName(`${t.id}_row`)) : []);
|
|
2330
|
+
for (const q of queries) {
|
|
2331
|
+
if (q.skipGenerateFunction) continue;
|
|
2332
|
+
if (!q.isQuery || q.isPluck) continue;
|
|
2333
|
+
if (q.columns.length === 0) continue;
|
|
2334
|
+
const rowTypeName = this.rowType(q);
|
|
2335
|
+
if (tableRowTypes.has(rowTypeName)) continue;
|
|
2336
|
+
if (seenRowTypes.has(rowTypeName)) continue;
|
|
2337
|
+
seenRowTypes.add(rowTypeName);
|
|
2338
|
+
this.declareTypeOwners.add(q.id);
|
|
2339
|
+
}
|
|
2340
|
+
Handlebars.registerHelper("shouldDeclareType", (queryHelper) => this.declareTypeOwners.has(queryHelper.id));
|
|
2295
2341
|
Handlebars.registerHelper("isDuckDB", () => this.engine === "duckdb");
|
|
2296
2342
|
Handlebars.registerHelper("isPostgres", () => this.engine === "postgres");
|
|
2297
2343
|
Handlebars.registerHelper("pgBulkType", (column) => {
|
|
@@ -2314,7 +2360,9 @@ var JavaGenerator = class extends BaseGenerator {
|
|
|
2314
2360
|
...query.columns[0],
|
|
2315
2361
|
name: query.id
|
|
2316
2362
|
}, " ");
|
|
2317
|
-
|
|
2363
|
+
if (!this.declareTypeOwners.has(query.id)) return "";
|
|
2364
|
+
const structName = this.rowType(query);
|
|
2365
|
+
return queryHelper.typeMapper.getDeclarations(query.allColumns, "", structName);
|
|
2318
2366
|
});
|
|
2319
2367
|
Handlebars.registerHelper("appenderType", (column) => {
|
|
2320
2368
|
return this.typeMapper.getUnboxedTypeName(column);
|
|
@@ -2538,13 +2586,25 @@ var JavaDuckDBArrowGenerator = class extends BaseGenerator {
|
|
|
2538
2586
|
async beforeGenerate(projectDir, gen, queries, tables) {
|
|
2539
2587
|
const q = queries.filter((q) => q.isQuery && q.isOne || q.isMigrate);
|
|
2540
2588
|
const name = `${gen.name}-jdbc`;
|
|
2541
|
-
writeGeneratedFile(projectDir, {
|
|
2589
|
+
await writeGeneratedFile(projectDir, {
|
|
2542
2590
|
name,
|
|
2543
2591
|
generator: "java/duckdb/jdbc",
|
|
2544
2592
|
output: gen.output,
|
|
2545
2593
|
config: gen.config,
|
|
2546
2594
|
projectName: gen.projectName
|
|
2547
2595
|
}, this.javaGenerator, name, q, tables, "duckdb");
|
|
2596
|
+
const owners = /* @__PURE__ */ new Set();
|
|
2597
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2598
|
+
for (const q of queries) {
|
|
2599
|
+
if (q.skipGenerateFunction) continue;
|
|
2600
|
+
if (!q.isQuery || q.isOne) continue;
|
|
2601
|
+
if (q.columns.length === 0) continue;
|
|
2602
|
+
const rowTypeName = this.rowType(q);
|
|
2603
|
+
if (seen.has(rowTypeName)) continue;
|
|
2604
|
+
seen.add(rowTypeName);
|
|
2605
|
+
owners.add(q.id);
|
|
2606
|
+
}
|
|
2607
|
+
Handlebars.registerHelper("shouldDeclareType", (queryHelper) => owners.has(queryHelper.id));
|
|
2548
2608
|
}
|
|
2549
2609
|
isCompatibleWith(engine) {
|
|
2550
2610
|
return engine === "duckdb";
|
|
@@ -2606,7 +2666,7 @@ var JavaDuckDBArrowGenerator = class extends BaseGenerator {
|
|
|
2606
2666
|
}
|
|
2607
2667
|
rowType(query) {
|
|
2608
2668
|
if (query.isOne) return this.javaGenerator.rowType(query);
|
|
2609
|
-
return this.getClassName(`${query.id}_Result`);
|
|
2669
|
+
return this.getClassName(query.resultTypeName ?? `${query.id}_Result`);
|
|
2610
2670
|
}
|
|
2611
2671
|
};
|
|
2612
2672
|
//#endregion
|
|
@@ -3358,6 +3418,106 @@ function getOutputPath(projectDir, sqlFileName, gen, generator) {
|
|
|
3358
3418
|
mkdirSync(dirname(outputPath), { recursive: true });
|
|
3359
3419
|
return outputPath;
|
|
3360
3420
|
}
|
|
3421
|
+
function assignResultTypeNames(queries, tables, projectDir = process.cwd()) {
|
|
3422
|
+
const hints = [];
|
|
3423
|
+
const tablesByName = /* @__PURE__ */ new Map();
|
|
3424
|
+
for (const t of tables) tablesByName.set(t.tableName, t);
|
|
3425
|
+
const groups = /* @__PURE__ */ new Map();
|
|
3426
|
+
const eligible = queries.filter((q) => q.isQuery && !q.isPluck && !q.skipGenerateFunction && q.columns.length > 0);
|
|
3427
|
+
for (const q of eligible) {
|
|
3428
|
+
const cols = effectiveColumns(q);
|
|
3429
|
+
const key = JSON.stringify(cols.map((c) => ({
|
|
3430
|
+
n: c.name,
|
|
3431
|
+
t: c.type.toString(),
|
|
3432
|
+
nu: c.nullable,
|
|
3433
|
+
s: c.sourceTable ?? null
|
|
3434
|
+
})));
|
|
3435
|
+
let g = groups.get(key);
|
|
3436
|
+
if (!g) {
|
|
3437
|
+
g = { queries: [] };
|
|
3438
|
+
groups.set(key, g);
|
|
3439
|
+
}
|
|
3440
|
+
g.queries.push(q);
|
|
3441
|
+
}
|
|
3442
|
+
const recordShape = (cols) => JSON.stringify(cols.map((c) => ({
|
|
3443
|
+
n: c.name,
|
|
3444
|
+
t: c.type.toString(),
|
|
3445
|
+
nu: c.nullable
|
|
3446
|
+
})));
|
|
3447
|
+
const claims = /* @__PURE__ */ new Map();
|
|
3448
|
+
for (const t of tables) {
|
|
3449
|
+
if (!t.hasAppender) continue;
|
|
3450
|
+
const cols = t.columns.filter((c) => !c.generated);
|
|
3451
|
+
claims.set(pascalCase(`${t.id}_row`), {
|
|
3452
|
+
shape: recordShape(cols),
|
|
3453
|
+
offenderId: t.id,
|
|
3454
|
+
source: `TABLE ${t.tableName}`
|
|
3455
|
+
});
|
|
3456
|
+
}
|
|
3457
|
+
const claim = (name, shape, representative, source) => {
|
|
3458
|
+
const canonical = pascalCase(name);
|
|
3459
|
+
const existing = claims.get(canonical);
|
|
3460
|
+
if (existing && existing.shape !== shape) throw SqgError.inQuery(`Result type '${name}' would be emitted with two incompatible shapes: ${source} ('${representative.id}') vs ${existing.source} ('${existing.offenderId}')`, "VALIDATION_ERROR", representative.id, representative.filename, { suggestion: "Use a different `:result=` name for one of the queries, or change the queries so their result columns match" });
|
|
3461
|
+
if (!existing) claims.set(canonical, {
|
|
3462
|
+
shape,
|
|
3463
|
+
offenderId: representative.id,
|
|
3464
|
+
source
|
|
3465
|
+
});
|
|
3466
|
+
};
|
|
3467
|
+
for (const group of groups.values()) {
|
|
3468
|
+
const overrides = group.queries.map((q) => q.resultTypeOverride).filter((v) => !!v);
|
|
3469
|
+
const uniqueOverrides = new Set(overrides);
|
|
3470
|
+
if (uniqueOverrides.size > 1) {
|
|
3471
|
+
const offenders = group.queries.filter((q) => q.resultTypeOverride);
|
|
3472
|
+
throw SqgError.inQuery(`Conflicting ':result=' names for queries with identical result shapes: ${offenders.map((q) => `'${q.id}' uses '${q.resultTypeOverride}'`).join(", ")}`, "VALIDATION_ERROR", offenders[0].id, offenders[0].filename, { suggestion: "Pick a single name for this row type or change the queries so their shapes differ" });
|
|
3473
|
+
}
|
|
3474
|
+
const shape = recordShape(effectiveColumns(group.queries[0]));
|
|
3475
|
+
if (uniqueOverrides.size === 1) {
|
|
3476
|
+
const resolved = [...uniqueOverrides][0];
|
|
3477
|
+
claim(resolved, shape, group.queries.find((q) => q.resultTypeOverride === resolved), `:result=${resolved}`);
|
|
3478
|
+
for (const q of group.queries) q.resultTypeName = resolved;
|
|
3479
|
+
continue;
|
|
3480
|
+
}
|
|
3481
|
+
const fullMatch = tryFullTableMatch(group.queries[0], tablesByName);
|
|
3482
|
+
if (fullMatch) {
|
|
3483
|
+
claim(fullMatch, shape, group.queries[0], `full-table match`);
|
|
3484
|
+
for (const q of group.queries) q.resultTypeName = fullMatch;
|
|
3485
|
+
continue;
|
|
3486
|
+
}
|
|
3487
|
+
if (group.queries.length >= 2) {
|
|
3488
|
+
const list = group.queries.map((q) => `'${q.id}' (${displayPath(q.filename, projectDir)}:${q.line})`).join(", ");
|
|
3489
|
+
hints.push({
|
|
3490
|
+
queryIds: group.queries.map((q) => q.id),
|
|
3491
|
+
message: `${group.queries.length} queries return the same row shape: ${list}. Add \`:result=Name\` to any one of them to share a single row type.`
|
|
3492
|
+
});
|
|
3493
|
+
}
|
|
3494
|
+
}
|
|
3495
|
+
return hints;
|
|
3496
|
+
}
|
|
3497
|
+
/** Show paths relative to the project root when it's inside the tree; otherwise fall back to absolute. */
|
|
3498
|
+
function displayPath(fullPath, projectDir) {
|
|
3499
|
+
const rel = relative(projectDir, fullPath);
|
|
3500
|
+
return rel && !rel.startsWith("..") ? rel : fullPath;
|
|
3501
|
+
}
|
|
3502
|
+
/** Resolve config-overridden column info, mirroring what validateQueries does for allColumns. */
|
|
3503
|
+
function effectiveColumns(query) {
|
|
3504
|
+
return query.columns.map((col) => query.config?.getColumnInfo(col.name) ?? col);
|
|
3505
|
+
}
|
|
3506
|
+
function tryFullTableMatch(query, tablesByName) {
|
|
3507
|
+
const cols = effectiveColumns(query);
|
|
3508
|
+
const firstSource = cols[0]?.sourceTable;
|
|
3509
|
+
if (!firstSource) return void 0;
|
|
3510
|
+
if (!cols.every((c) => c.sourceTable === firstSource)) return void 0;
|
|
3511
|
+
const table = tablesByName.get(firstSource);
|
|
3512
|
+
if (!table) return void 0;
|
|
3513
|
+
if (table.columns.some((c) => c.generated)) return void 0;
|
|
3514
|
+
if (table.columns.length !== cols.length) return void 0;
|
|
3515
|
+
for (let i = 0; i < cols.length; i++) {
|
|
3516
|
+
if (cols[i].name !== table.columns[i].name) return void 0;
|
|
3517
|
+
if (cols[i].type.toString() !== table.columns[i].type.toString()) return void 0;
|
|
3518
|
+
}
|
|
3519
|
+
return `${table.id}_row`;
|
|
3520
|
+
}
|
|
3361
3521
|
function validateQueries(queries) {
|
|
3362
3522
|
for (const query of queries) {
|
|
3363
3523
|
if (query.isQuery && query.isPluck && query.columns.length !== 1) throw SqgError.inQuery(`':pluck' modifier requires exactly 1 column, but query has ${query.columns.length} columns`, "VALIDATION_ERROR", query.id, query.filename, { suggestion: query.columns.length === 0 ? "Ensure the query returns at least one column" : `Remove ':pluck' or select only one column. Current columns: ${query.columns.map((c) => c.name).join(", ")}` });
|
|
@@ -3515,6 +3675,9 @@ async function processProjectFromConfig(project, projectDir, writeToStdout = fal
|
|
|
3515
3675
|
if (tables.length > 0) await dbEngine.introspectTables(tables, reporter);
|
|
3516
3676
|
ui?.succeedPhase(`Introspected ${executableQueries.length} queries`);
|
|
3517
3677
|
validateQueries(queries);
|
|
3678
|
+
const hints = assignResultTypeNames(queries, tables, projectDir);
|
|
3679
|
+
for (const hint of hints) if (ui) ui.hint(hint.message);
|
|
3680
|
+
else consola.info(hint.message);
|
|
3518
3681
|
await dbEngine.close();
|
|
3519
3682
|
} catch (e) {
|
|
3520
3683
|
ui?.failPhase(`Failed to process ${sqlFile}`);
|
|
@@ -3565,7 +3728,7 @@ async function processProject(projectPath, ui) {
|
|
|
3565
3728
|
//#region src/mcp-server.ts
|
|
3566
3729
|
const server = new Server({
|
|
3567
3730
|
name: "sqg-mcp",
|
|
3568
|
-
version: process.env.npm_package_version ?? "0.
|
|
3731
|
+
version: process.env.npm_package_version ?? "0.20.0"
|
|
3569
3732
|
}, { capabilities: {
|
|
3570
3733
|
tools: {},
|
|
3571
3734
|
resources: {}
|
|
@@ -3987,6 +4150,12 @@ var UI = class {
|
|
|
3987
4150
|
this.log("");
|
|
3988
4151
|
this.log(` ${pc.green("done")} ${pc.dim(`in ${formatMs(totalMs)}`)}`);
|
|
3989
4152
|
}
|
|
4153
|
+
/** Display an info-level hint (e.g. "these queries could share a row type") */
|
|
4154
|
+
hint(message) {
|
|
4155
|
+
if (this.silent) return;
|
|
4156
|
+
this.stopSpinner();
|
|
4157
|
+
this.log(` ${pc.cyan(pc.bold("hint"))} ${message}`);
|
|
4158
|
+
}
|
|
3990
4159
|
/** Display a formatted error */
|
|
3991
4160
|
error(err) {
|
|
3992
4161
|
if (this.silent) return;
|
|
@@ -4030,7 +4199,7 @@ function formatMs(ms) {
|
|
|
4030
4199
|
}
|
|
4031
4200
|
//#endregion
|
|
4032
4201
|
//#region src/sqg.ts
|
|
4033
|
-
const version = process.env.npm_package_version ?? "0.
|
|
4202
|
+
const version = process.env.npm_package_version ?? "0.20.0";
|
|
4034
4203
|
updateNotifier({ pkg: {
|
|
4035
4204
|
name: "@sqg/sqg",
|
|
4036
4205
|
version
|
|
@@ -75,6 +75,7 @@ public class {{className}} {
|
|
|
75
75
|
|
|
76
76
|
{{#*inline "columnTypesRecord"}}
|
|
77
77
|
{{#if isQuery}}
|
|
78
|
+
{{#if (shouldDeclareType this)}}
|
|
78
79
|
{{#if isOne}}
|
|
79
80
|
public record {{rowType}}({{#each columns}}{{type}} {{name}}{{#unless @last}}, {{/unless}}{{/each}}) {}
|
|
80
81
|
{{else}}
|
|
@@ -83,7 +84,7 @@ public record {{rowType}}(PreparedStatement statement, RootAllocator allocator,
|
|
|
83
84
|
public boolean loadNextBatch() throws IOException {
|
|
84
85
|
return reader.loadNextBatch();
|
|
85
86
|
}
|
|
86
|
-
|
|
87
|
+
|
|
87
88
|
public int getRowCount() throws IOException {
|
|
88
89
|
return reader.getVectorSchemaRoot().getRowCount();
|
|
89
90
|
}
|
|
@@ -96,6 +97,7 @@ public record {{rowType}}(PreparedStatement statement, RootAllocator allocator,
|
|
|
96
97
|
}
|
|
97
98
|
{{/if}}
|
|
98
99
|
{{/if}}
|
|
100
|
+
{{/if}}
|
|
99
101
|
{{/inline}}
|
|
100
102
|
|
|
101
103
|
{{#*inline "returnType"}}
|