From 4dd10f071ad21f9ea99246e2438c8508ca2bc20f Mon Sep 17 00:00:00 2001 From: Nuno Cruces Date: Fri, 3 Mar 2023 14:48:56 +0000 Subject: [PATCH] Towards shared modules: backup. --- api.go | 184 ++++++++++++++++-------------- backup.go | 69 +++++++++++ conn.go | 45 ++++++-- embed/sqlite3.wasm | Bin 1034013 -> 1034126 bytes sqlite3/exports.txt | 1 + tests/mptest/testdata/build.sh | 3 +- tests/mptest/testdata/mptest.wasm | 4 +- 7 files changed, 204 insertions(+), 102 deletions(-) create mode 100644 backup.go diff --git a/api.go b/api.go index 0649ecb..cfd2450 100644 --- a/api.go +++ b/api.go @@ -22,96 +22,106 @@ func (module *module) loadAPI() (err error) { return module.mem.readUint32(uint32(global.Get())) } - { - module.api = sqliteAPI{ - free: getFun("free"), - malloc: getFun("malloc"), - destructor: uint64(getVal("malloc_destructor")), - errcode: getFun("sqlite3_errcode"), - errstr: getFun("sqlite3_errstr"), - errmsg: getFun("sqlite3_errmsg"), - erroff: getFun("sqlite3_error_offset"), - open: getFun("sqlite3_open_v2"), - close: getFun("sqlite3_close"), - prepare: getFun("sqlite3_prepare_v3"), - finalize: getFun("sqlite3_finalize"), - reset: getFun("sqlite3_reset"), - step: getFun("sqlite3_step"), - exec: getFun("sqlite3_exec"), - clearBindings: getFun("sqlite3_clear_bindings"), - bindCount: getFun("sqlite3_bind_parameter_count"), - bindIndex: getFun("sqlite3_bind_parameter_index"), - bindName: getFun("sqlite3_bind_parameter_name"), - bindNull: getFun("sqlite3_bind_null"), - bindInteger: getFun("sqlite3_bind_int64"), - bindFloat: getFun("sqlite3_bind_double"), - bindText: getFun("sqlite3_bind_text64"), - bindBlob: getFun("sqlite3_bind_blob64"), - bindZeroBlob: getFun("sqlite3_bind_zeroblob64"), - columnCount: getFun("sqlite3_column_count"), - columnName: getFun("sqlite3_column_name"), - columnType: getFun("sqlite3_column_type"), - columnInteger: getFun("sqlite3_column_int64"), - columnFloat: getFun("sqlite3_column_double"), - columnText: getFun("sqlite3_column_text"), - columnBlob: getFun("sqlite3_column_blob"), - columnBytes: getFun("sqlite3_column_bytes"), - autocommit: getFun("sqlite3_get_autocommit"), - lastRowid: getFun("sqlite3_last_insert_rowid"), - changes: getFun("sqlite3_changes64"), - blobOpen: getFun("sqlite3_blob_open"), - blobClose: getFun("sqlite3_blob_close"), - blobReopen: getFun("sqlite3_blob_reopen"), - blobBytes: getFun("sqlite3_blob_bytes"), - blobRead: getFun("sqlite3_blob_read"), - blobWrite: getFun("sqlite3_blob_write"), - interrupt: getVal("sqlite3_interrupt_offset"), - } + module.api = sqliteAPI{ + free: getFun("free"), + malloc: getFun("malloc"), + destructor: uint64(getVal("malloc_destructor")), + errcode: getFun("sqlite3_errcode"), + errstr: getFun("sqlite3_errstr"), + errmsg: getFun("sqlite3_errmsg"), + erroff: getFun("sqlite3_error_offset"), + open: getFun("sqlite3_open_v2"), + close: getFun("sqlite3_close"), + closeZombie: getFun("sqlite3_close_v2"), + prepare: getFun("sqlite3_prepare_v3"), + finalize: getFun("sqlite3_finalize"), + reset: getFun("sqlite3_reset"), + step: getFun("sqlite3_step"), + exec: getFun("sqlite3_exec"), + clearBindings: getFun("sqlite3_clear_bindings"), + bindCount: getFun("sqlite3_bind_parameter_count"), + bindIndex: getFun("sqlite3_bind_parameter_index"), + bindName: getFun("sqlite3_bind_parameter_name"), + bindNull: getFun("sqlite3_bind_null"), + bindInteger: getFun("sqlite3_bind_int64"), + bindFloat: getFun("sqlite3_bind_double"), + bindText: getFun("sqlite3_bind_text64"), + bindBlob: getFun("sqlite3_bind_blob64"), + bindZeroBlob: getFun("sqlite3_bind_zeroblob64"), + columnCount: getFun("sqlite3_column_count"), + columnName: getFun("sqlite3_column_name"), + columnType: getFun("sqlite3_column_type"), + columnInteger: getFun("sqlite3_column_int64"), + columnFloat: getFun("sqlite3_column_double"), + columnText: getFun("sqlite3_column_text"), + columnBlob: getFun("sqlite3_column_blob"), + columnBytes: getFun("sqlite3_column_bytes"), + autocommit: getFun("sqlite3_get_autocommit"), + lastRowid: getFun("sqlite3_last_insert_rowid"), + changes: getFun("sqlite3_changes64"), + blobOpen: getFun("sqlite3_blob_open"), + blobClose: getFun("sqlite3_blob_close"), + blobReopen: getFun("sqlite3_blob_reopen"), + blobBytes: getFun("sqlite3_blob_bytes"), + blobRead: getFun("sqlite3_blob_read"), + blobWrite: getFun("sqlite3_blob_write"), + backupInit: getFun("sqlite3_backup_init"), + backupStep: getFun("sqlite3_backup_step"), + backupFinish: getFun("sqlite3_backup_finish"), + backupRemaining: getFun("sqlite3_backup_remaining"), + backupPageCount: getFun("sqlite3_backup_pagecount"), + interrupt: getVal("sqlite3_interrupt_offset"), } return err } type sqliteAPI struct { - free api.Function - malloc api.Function - destructor uint64 - errcode api.Function - errstr api.Function - errmsg api.Function - erroff api.Function - open api.Function - close api.Function - prepare api.Function - finalize api.Function - reset api.Function - step api.Function - exec api.Function - clearBindings api.Function - bindNull api.Function - bindCount api.Function - bindIndex api.Function - bindName api.Function - bindInteger api.Function - bindFloat api.Function - bindText api.Function - bindBlob api.Function - bindZeroBlob api.Function - columnCount api.Function - columnName api.Function - columnType api.Function - columnInteger api.Function - columnFloat api.Function - columnText api.Function - columnBlob api.Function - columnBytes api.Function - autocommit api.Function - lastRowid api.Function - changes api.Function - blobOpen api.Function - blobClose api.Function - blobReopen api.Function - blobBytes api.Function - blobRead api.Function - blobWrite api.Function - interrupt uint32 + free api.Function + malloc api.Function + destructor uint64 + errcode api.Function + errstr api.Function + errmsg api.Function + erroff api.Function + open api.Function + close api.Function + closeZombie api.Function + prepare api.Function + finalize api.Function + reset api.Function + step api.Function + exec api.Function + clearBindings api.Function + bindNull api.Function + bindCount api.Function + bindIndex api.Function + bindName api.Function + bindInteger api.Function + bindFloat api.Function + bindText api.Function + bindBlob api.Function + bindZeroBlob api.Function + columnCount api.Function + columnName api.Function + columnType api.Function + columnInteger api.Function + columnFloat api.Function + columnText api.Function + columnBlob api.Function + columnBytes api.Function + autocommit api.Function + lastRowid api.Function + changes api.Function + blobOpen api.Function + blobClose api.Function + blobReopen api.Function + blobBytes api.Function + blobRead api.Function + blobWrite api.Function + backupInit api.Function + backupStep api.Function + backupFinish api.Function + backupRemaining api.Function + backupPageCount api.Function + interrupt uint32 } diff --git a/backup.go b/backup.go new file mode 100644 index 0000000..61c7202 --- /dev/null +++ b/backup.go @@ -0,0 +1,69 @@ +package sqlite3 + +// Backup is a handle to an open BLOB. +// +// https://www.sqlite.org/c3ref/backup.html +type Backup struct { + c *Conn + handle uint32 +} + +// BackupInit initializes a backup operation to copy the content of one database into another. +// +// BackupInit calls [Conn.Open] to open the SQLite database file dstURI, +// then initializes a backup that copies the content of srcDB to the "main" database in dstURI. +// +// https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupinit +func (c *Conn) BackupInit(srcDB, dstURI string) (*Backup, error) { + return c.backupInit(srcDB, "main", 0) +} + +func (c *Conn) backupInit(srcDB, dstDB string, handle uint32) (*Backup, error) { + return nil, notImplErr +} + +// Close finishes a backup operation. +// +// It is safe to close a nil, zero or closed Backup. +// +// https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupfinish +func (b *Backup) Close() error { + if b == nil || b.handle == 0 { + return nil + } + + r := b.c.call(b.c.api.backupFinish, uint64(b.handle)) + + b.handle = 0 + return b.c.error(r[0]) +} + +// Step copies up to nPage pages between the source and destination databases. +// If nPage is negative, all remaining source pages are copied. +// +// https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupstep +func (b *Backup) Step(nPage int) (done bool, err error) { + r := b.c.call(b.c.api.backupStep, uint64(b.handle), uint64(nPage)) + if r[0] == _DONE { + return true, nil + } + return false, b.c.error(r[0]) +} + +// Remaining returns the number of pages still to be backed up +// at the conclusion of the most recent [Backup.Step]. +// +// https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupremaining +func (b *Backup) Remaining() int { + r := b.c.call(b.c.api.backupRemaining, uint64(b.handle)) + return int(r[0]) +} + +// PageCount returns the total number of pages in the source database +// at the conclusion of the most recent [Backup.Step]. +// +// https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backuppagecount +func (b *Backup) PageCount() int { + r := b.c.call(b.c.api.backupFinish, uint64(b.handle)) + return int(r[0]) +} diff --git a/conn.go b/conn.go index 80fb71a..e41c7ee 100644 --- a/conn.go +++ b/conn.go @@ -33,7 +33,7 @@ type Conn struct { // Open calls [OpenFlags] with [OPEN_READWRITE], [OPEN_CREATE] and [OPEN_URI]. func Open(filename string) (*Conn, error) { - return openFlags(filename, OPEN_READWRITE|OPEN_CREATE|OPEN_URI) + return newConn(filename, OPEN_READWRITE|OPEN_CREATE|OPEN_URI) } // OpenFlags opens an SQLite database file as specified by the filename argument. @@ -44,10 +44,10 @@ func Open(filename string) (*Conn, error) { // // https://www.sqlite.org/c3ref/open.html func OpenFlags(filename string, flags OpenFlag) (*Conn, error) { - return openFlags(filename, flags) + return newConn(filename, flags) } -func openFlags(filename string, flags OpenFlag) (conn *Conn, err error) { +func newConn(filename string, flags OpenFlag) (conn *Conn, err error) { ctx := context.Background() mod, err := instantiateModule() if err != nil { @@ -68,16 +68,24 @@ func openFlags(filename string, flags OpenFlag) (conn *Conn, err error) { mem: &mod.mem, } c.arena = c.newArena(1024) + c.handle, err = c.openDB(filename, flags) + if err != nil { + return nil, err + } + return c, nil +} +func (c *Conn) openDB(filename string, flags OpenFlag) (uint32, error) { defer c.arena.reset() connPtr := c.arena.new(ptrlen) namePtr := c.arena.string(filename) r := c.call(c.api.open, uint64(namePtr), uint64(connPtr), uint64(flags), 0) - c.handle = c.mem.readUint32(connPtr) - if err := c.error(r[0]); err != nil { - return nil, err + handle := c.mem.readUint32(connPtr) + if err := c.mod.error(r[0], handle); err != nil { + c.closeDB(handle) + return 0, err } if flags|OPEN_URI != 0 && strings.HasPrefix(filename, "file:") { @@ -90,11 +98,22 @@ func openFlags(filename string, flags OpenFlag) (conn *Conn, err error) { pragmas.WriteByte(';') } } - if err := c.Exec(pragmas.String()); err != nil { - return nil, fmt.Errorf("sqlite3: invalid _pragma: %w", err) + + pragmaPtr := c.arena.string(pragmas.String()) + r := c.call(c.api.exec, uint64(handle), uint64(pragmaPtr), 0, 0, 0) + if err := c.mod.error(r[0], handle, pragmas.String()); err != nil { + c.closeDB(handle) + return 0, fmt.Errorf("sqlite3: invalid _pragma: %w", err) } } - return c, nil + return handle, nil +} + +func (c *Conn) closeDB(handle uint32) { + r := c.call(c.api.closeZombie, uint64(c.handle)) + if err := c.mod.error(r[0], handle); err != nil { + panic(err) + } } // Close closes the database connection. @@ -312,6 +331,10 @@ func (c *Conn) Pragma(str string) []string { } func (c *Conn) error(rc uint64, sql ...string) error { + return c.mod.error(rc, c.handle, sql...) +} + +func (c *module) error(rc uint64, handle uint32, sql ...string) error { if rc == _OK { return nil } @@ -329,13 +352,13 @@ func (c *Conn) error(rc uint64, sql ...string) error { err.str = c.mem.readString(uint32(r[0]), _MAX_STRING) } - r, _ = c.api.errmsg.Call(c.ctx, uint64(c.handle)) + r, _ = c.api.errmsg.Call(c.ctx, uint64(handle)) if r != nil { err.msg = c.mem.readString(uint32(r[0]), _MAX_STRING) } if sql != nil { - r, _ = c.api.erroff.Call(c.ctx, uint64(c.handle)) + r, _ = c.api.erroff.Call(c.ctx, uint64(handle)) if r != nil && r[0] != math.MaxUint32 { err.sql = sql[0][r[0]:] } diff --git a/embed/sqlite3.wasm b/embed/sqlite3.wasm index 800b058bdd0ba9b4de2075368f07bba97922b002..fddcbceeb38edc8cfdf2242f1a80ab20d4ef19f7 100755 GIT binary patch delta 28999 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Ơ-FZBSqIydJ)zLWCF|G#1pDgiks4>xn)UFE=dJ1+*f3Fu*|L$1 zhQhV_9kFLM-TIyF((YT*mCDHsM%3qu^KRhM?^5a6fB-r$&E(dymH-K>Wy}ng`ghBDZDEg%YDk0L5(?;=71wuBmkH z0811(VAF#vv(QXoaX9n`iX6@p=$Y4R8xpuoYH|qS428WzEFquD-vlm&L`P}z*&%4f zOA0>>V}3>Z55tkZr00iOY1Us#Iv7_2FR8*2Rx5m+SOTJl=dK)vevxU2#9HS3I5q=r zz!6rVggQ6{xuh=(6PHbJ0nJ~RUk@E&MVu0QxV?t0vYhzj2#YJF&Km%h^r?01;!e=+ zJ6G7T#NeasLu~-3sF!a8YXujFkrsjKR>sa zPamIRp>>7}01R_5!iQas`lxz?D2ZHDip8y0F2#RvEd3NK9X4D{z}=tRs$gwdVYh-< zQDqg^$(K$cL+ecurx686tUP$p& zAV37oFW6kp9)SB}+ch|q`!x6(i$-(n8rxo?w`6~i&}6#^s`-W223J5IOl%Mxz7FRy zj?!*`HACq64djdWt%f(TB%)%%Eu_Lr=#N{hLMa)TJprf;Xgv`*p9`ynP5>46EBC?lx=<^M~DGUw|`cLg?8YBrCq(n`XfaWK#buIIv8*ki}Y-m8=Rw z(rfcf(_%}Z`VS5UFdaW!7sQgjU#ZPqq(Ecox4TGbdsFdyFqz)gH}@b4)N6ja&yL}K zulWN|d(|5EfHl$JAud0}l$rF&Beq$4KK?P=D!k|R$5?!hRpJSou4(^R8BbX)Ts2xx zpCe^+JQOO0l^0XqmqB#M-iHbn z7J4Agm8(1R7|k~*UqZ+^NY^!<>>HGs85~4mp|fHprP_D{oUb>C<^=`X!R{AU89VQ6 z!xqN|@fz9+YfljWP{THYgE^|7men#hM}hwab#w3vXl6UO@aCr+{5M3PQ97?xV3jl_ zp$jk%8^}blU^$)B`KJIZ%Q!L}n$LJ$G`AQpi;z}`bBADKn8DYeIc@N^IR3xq1XTU90HH!+mcpEf7xOl}fmRJHAA+)@dc$E&8AiE5>uP_*~ORWlRg|(DajEB;QJp3K)ruBOs{!By3W?eqMQCnwq%g+yq3-wP6@=+ke-cI-klKI@tzbd*(tl_(d z-YkCi_@6RpE2=I4ms`po#vkB!J)9TUwo(tIjRZF*^56uj72nwNHF*MfvFH&}NtWJj@Se>q-~ z-YLfi7Z@!xw}@MJ>+qi_61ek=0y@T*1FUCxj;gzLv^=kG$5EqbC02k8y05kT#fLm8#(4V(M6xS41xAeQ zt`P<&W)7^*FCbU!Sc4Z6xpoacK*MHvE&e6X1`P&WLM^$%@>;xb@Bx7X+3&$xypkdJ zB_*%9wp;8y9)ml3>hb}UXA`aZ07jZYSs(CkwKG=J4>|7aU(&gcAm7!N=VOlJ?iSkZ z;W(pP@74kF(BIY(JWI>8KCR2$HoRZhxjz33H@M9k@W*h^jT-Xr0kfbXFRfj-4mRWq zMWy}c&v*|sPe0?cakiM&7^~f}UNq*5QL3^QHs$w4UO25ePtvYgc|PZ%8s=7NA+~y* zR=4D9@tD|(*VKZpi=9!WFL_5R@0S91KkN6_{DgoX-v(=-{FMJ&=;$@8?zeoEnEvED z{vDdH+VUz$V1~4Xs~Sj)+w$gUUbcl@52R1qf!KkR)DEsic81cScKmJp{-PakEC9ZT zMJ_sRi&HN zdFB5P*Zx*`97k~LN1w;@g5X4_cwVmb00AxDE0$NL;kiBBHBfccGlatvTGpR_iwD!L z)75zHMiZO>dmFl|bJ!yZC660k?SbC}4dYeTKAiF~4l)9H6VfC0m;UO({7 zc5SZZ>B7_O5X!l3e2|9c4nOgAcD=t?5I1C4sQfQ{mNwlw@C$^h4X_6H;vt$_j(hT= zG%gqhPAndiavLMkhV)aT91eG z8aCXozB3B`bR=~c#s9=p!_mAPnq<|akLHPZ;$!&4ydxxnU~z*9R{#_v$Qr|kI%U7; zLne#9=3}AABWU_qJ_+aZ4}azTQ5)FuD}Rb(`o?j>fU>N*gdm24>30**KBBG@05pQ0 zPk@^rLG>nL%`vokB3}n_B~1c7+D)322GhJn4bypfR1H$nvFYB{nRMPsR8s3sLEbRT zS~7*#wjoWsJ&g~BkM2HQ1YM$x89*_CuFnAQL~1n?%_Q15ldr(LD@n8XW^nr5+1wp6 zS!^&o$Us67=7OX}dWx6-TvI4^Hm{89v$WZWfK%z%Y+j|vQ~`|JbHL^iu3KEA2Z}rR zsT4Mcf2mEQZgY@bOsC0nxTU38U(Dq;E$<95E6kysxHv$}q?mcUi8h0*dAu3YuHgCb zeiNwfeEvCT9X}uLdlKbc0B1hSs=Yw?!r63SAukX-M`E&5*a}|I(iZVBt=MeQB~tp@ zI11rx5#T8Vl0=m~z?EiwvY1B-ZcJYS7ciF|F5x{vWY?vm-Dd*nm3m7!5=OWxNR^65eICtNa(QvZ=aFq7kQ{C8+z>i9)Ab&I#(ZBz5>y= z5A9z8H`<4;t$>{_q<$;;P|)F8g+=<(tX1GyU+dW_{*~rP6N`l-8>c(5`dc*gRA5EA z*uz$U+-Cv)|oetikJHIS3}3Ht)t~821 z$%mj`cKaj}%QWhBig$r?dUy)_e@3CFLEm$#ewuH?*wfQ+*J+e;1}10G*)zNy9PNi^ z#TH)B7w7os;?D%vWo-cW`(=f4;b;omvkOytPJ!nUBVSO>^KcM<(8lu!CNHcT=XqTl z()V}&M0$$R`Iq!@RqQxJvX3$ODO9G((yE^ zcoPg-Lc?z&v06e4Z}M-%=OU)eK^|ND7Qc%dy*#&hexQBpHsD`U``hqGIM=J@_-%0K zB?aBVzF$)1I}rT>`u+|kETJxUkcy|%qdQ2&)2MnDzk;UdT|O5yY`qJ$n@sQA11VGJ z%X?7C-zfbae;*(x?g=?s>G$~_!IzE?;b+!ZgCFvSHjEyA%=@7Cizhs)&|1Y=5gt(; z!B4k4s55Ra4?N+maZoAy6vVBgubx6n)=`hA$eh;G>Zb^W8|dLvo(%rRJcHh+(aL9d zO0(X2&hy%F_;~LXk47`)72m3*t!{4wL7%CUW^{%I9@UI*@Ko7m}zw z#uN>O+y{ZiM>P%#vcxBD5S?<159HLaarp)gZXfWPmd}gh-AY?+IEmc8Ug{KN427ZG z4>B6z!#^MAGLC8`{*XJ=rS2fQi`QKWt9M>R-DESpo7;E~O4>QM@iwNCXf|70a~pU; zaVr&MMz!}9hCuiuD0@H{DmmiC+5D~p5;KbJk_>x=094*RJwL@t;tg12`3I>VGim_q zdS;A63HNhu)COH+xY5mC{*ah0cBqNi-q54_@QJtRR2LGMlZazeshZ1}iLiUpWeh~k z_xn6Xk9=xvk&J10z1)F2`Ki{OJcd&P{#SX8dV$(ut6m{PI2~$R*w_f)6B=TKi;pOM zQq(wz`(0P45u)Lmt9&tI5OVUB#f^rE;Cix)OKl@P!Otv+s$ zfbgz|8}-rB=OvBX+9~psGD@I{EM>%?*;~peh2~Bvqim5=l1Ji`Oa+sQ7&jP<@MYZTM+9u-J18}r5crGc(7 zG@zU@50l<0Z>&diy}U6D)O35>xQe;$Dj1J|_^XP@h=K9zN`mV&sgiLFyH9$@sD@l) z_B+Nae5_}7Wh0Ncm$Kf45*(+jca2rrMQctKBexA#LQAU|wa{c%1A?hkuDX!|eVtt0 zm>}q_QPXINW=KtA2o@<&%P5Vr%LlcLf6$bE&$xmy_P$XO^WS^lcstK=u?O+F3zS1~ zlZSWMyS#5yswBIM$daN*ZV#{CAs@Rapgp$K=S&{o@L?Ts>dmA>?;9WD-pu)du^9)I z10NV}8*<7!9~tFr+BGUt+o*s{tU+yvVT853wt=hYskF@lbDK);I>rU<(D(>rC7AJb zU853RiZHsW-_xNU59=BUT8N}4+#x=rC|={mfmbbkje69Ff{dUw^}&ph^rXH~4%L&A z4UC3)uL)w|{Ih{aP>%-2GjOGQL*p_Ic;7WLnn8PL@u$X5;9%L$j5tx09M>4ean0J- z7<rq-=?t7jR!a(7HVPOg33y70as97!sP%G(~>;_4Z;GE1KMh<5s_`*CbN}M2$^b` zR>n&(?X542&vRu7@FJ9zYLuo)Wm!e*z!ye$kqEN^Rs(w^@ihJ*B8 zTX5l^g|0+_E9`rt6Ph948_zLqV5CtV&5B54T;ILHVu4oMx6&u}Z)mG0(WOPhmd zm+!;*$8v&O1KS(;Jl;Vo%xjDg@6#{q0F&NL(>lT;w$tg3MqeCL+IE8dKcQ}&jAh82 z%Ee%3d+5g)>~}jYiGj=9MWQF;LZgMCN;7_ea@o?2>izgah4ar8oBx9n`-Qvl>jnB{~8>hhFQYq39y(v(EsWdso z7>?%cRO4qXF)tMgfyczI#s_E?b~T=$Krs79kT{jj{wUeq=qDqL>UEQnMOSfZ-yIHP zs)c@!R!{~N@lq6gGW1E904l*W?LY7|2dUA|Mg*GSKO1e4mE8E*_yJFCdl=V{*);ma z*kMETb@evF5!kBsMkGU+?QJYX_4b!O##e|h$NLyzA-zS~9S#m)0em7!L|gnQg?Q`g zYlslvw6F06npu6}M$%|RKZK1mt5kpZQ?bkd_!umnIM8sT06l7;@u`+arAEQx1fB~@ z0D`X%GVWvY#li5ane_1xj81{bU^0`(ADG8VIk(&@3r zJ#Ccr$FD{e4XrlbIAL>*6hs>GWqO7;WJX$<6O2)IIHT_A2ymmUnv;!>gOG`LongF% z!`S2*Mtg1I_?hrI;%AtZK2w``O?s3!MZHBUA5=gR3F)zbjg%vPN{@YHjH+Kzm8!?SL@ zc-dg>aPf1Fe0l4Q;nA-)V_?@l@iWJ;%#g&pAD({O#ms{v|2-d8CWdE?76Z>G<`^y^ zm-mgY-6}>d&&@GTedZZWvHwH!S^?RXk0qoo)1e&r>YB} zwdvGaH9ZzUztd^`0{HlJdbj}5V*J|TcG&L5{bLcNY9s$7!{e~?@8z= z);_Eo$*IXP@d8XdAIU~lKQ*OlqlB2$qdHflHc5=`66ZZe#z?bJ&*OTY4ghGC*x8$a zFQrKqbMbz0r^u8}b-f@dvHQvF?FdW_F%S{wjZ8k3bAjq&fz!GHRMjISKRjK!osp=k z*T)yYWTQW;=X(u<-kxgJa|%>Z=3Do?&IKqItuBbVpu5Cl%fv3pQQk&U02g(?yjrB< z%XkD0f9ejf!Rt-HH>6zBb@_X=Hz~E#W#2P<+E?C8Ct^VpOoil(OcKAkL` z`RCS4>~QxrCg=^mt>|8k1ry_wx}+jGQP{G!vp$$v{|g@!`Gy?Nc=G- z`q7)a5j=RTGa-fs-qZ+hT-*~qkCaA)5J2-}ZxTp+s^@#%=Scz=qMM|2e5N~J_cjHF z=eqg2BSL(w(Tkos%OS3py5W0L%J(XJREVq>bNWXW=XZvV+*^P^K8t5(XC4sd*w8-qic!Fy<6%Nj^(zhqIoNwVtRSy2K=VNBD>r zdfX~e;2O!~xR3TxKH7u=jQ;NxnkOcWVY%gIp%Y`XDO4))D=R981bNLm)Q?F{NdB|`nhPSSmQYm|`UO_qu@Ia_+d@Sy3D@l#jJ^e%%yLJe&jVR3VGi-@7YT4lOO@ul zX5KOuEK~`sUe3&xiOH#Ty4Q^XH7NjI!E`aPNn~z{p7^>mZ|Zno9T=3W{EE|nBUV2)(B~C5oo0E7d>0E$Au+}@om{XpTeh#p6%J< zY}r-D+8wlKyji62PUeydP{*5q44_lvm;~>xY~8HuZQn%#@6N_20}Jr&$p&iOAu%~# zEU}j=lbOHgzHHiB0@?oTbt9sF6i|Qo6j3?313s%3+dt^zhA-?K^66+Dzk56Eo2i`6 z5kDU3^N;$TzDW8;*y%Br!%zFfd7R0p-56;{sy929pI`+tC8blVM4;__k>$@`M*3%kvI`w75rt& zGtn$m<*yw3fssjlhHbU-CdXgNL9B4RYTi|9Gtn$k^lw(kmqiHj8X<-Ykd{%A2{@BZ zG>g^yhvm&C6HZx8zLtX;<(yUj^_;{Dvs2wSC~KlwxWG*%jwW5=Qe*rp-J;@?%t94z zt5xbEq3z}$YH>#q4wvKaYK}xAiy|kP1smRdW3X{zWOUQ!i7EH~g$LoiYm56zpgue; zyl@^V!tn@f4`|aQv#9+cD?k~O%>2!xA2FHTNlF@bjT78>jL-#L_La_ zAReExB4YGS>_XcF`e)=xGsXQ+n>4dn;TO!GkNcS|1^<#prkMqMzEbRInVQ@sDz!^8 zynJMIFD|Lc!LlEFb5pFRk`x)H`f#b{ss~Jni%CiC%cY?R#IPlB8`DGWgwS2D|^9OcuUzm=wE0(;+rW4^FlfJBKX+O z$NC{OBHb)leyG|=4)G3C=w)Uhxcwyrg>W#O{zx~A<{R+_yx{OidY*2EgpT5cbLg-* z7YO~Wmynv=eKfs0*(_XmOb*1pj8C}cu@pJkELiAQ#ei((6R5}WVl*0tRqe}2VaDTm zPRTXzlB&8%aj9-%l;F8vODE8&$)-5UHlJb^DA_bI!8?f;6})&u8Y%6X;tLStkVfOe zW{Oz?=S{$epiUS&#VlHB3NQFSroh;y{)<{6t!Z+po=p=Ilcp<@d|VZFA$-6L#k*|6 zYgC)5WCpkx=!j2iW~s@(rwDw*XnTAU=xn8g5uLgubQW8H>z%`;kMsd5XC9H;2S1mZ zO*KRDoh)%v&B7ndR}0CIE8U+koCRE-(1eiXz(NHiWGCe&HEa=W0-h?1x%BRcC>>%t zw(J~})L2j)8MlPz^sFsY6O&(MI| zA(99o_mzqR@>v;_VBacAng)$s{e~7~A3%Ro%vC##Nr*}5gwH5~f;MZo3^LgkU9Vdz z4i=5!fa2CFjm#cuj%*<@)w?bS&5{S}6+O}m-B`PLHEx0E~ zk6LFh&(l+oDS`aU>{FWC9OGXY5+aFYV(kj_Uz@hAC zh2t;?`UcAbz>ncbPP7dY+v9-#WyDcMxI){mNxdK5J(iQ8cFhpFlaId%)FAcU6ZGy( zGqmSP#mtroF*u^8icCx#_fPqB35l&2X{z0)4Nr=9q$V4H+7gO=|w^{V@Y;5SR&&$cfxjNhmt&P6tBjQC*S_=F`ha)s(C-JWe0 zZ}LnLFVqV)wV1e=$mH(NefYfI&WbfJ6uEMHYW7QoP@TP1*DGF_!sg=3q4}g z@~s1W$h=a~>WQy19!MqTn#J()tf4d-G~z|d z*>lY>x;ob^KxgKf3|F>)&oxVQ9BIgeOdk2w{ze%x@`zZZIz}rZBINfStFAGIOvPHD zN-AQk>Ktq2%w*(l`~bgF{5-SphvU>@DDL{B^LT|@)dUn8GGy|XT^LZk6DVUIN`Mm$ znZx<le57fbJ;V+keN$1SgXX;$T)FQ zo+?0{B6ZF7k<%!0J_6Zv!q_8Or%jx4et(ttC=tq!V-``++# zIfnPYL4_O;bQk->@LvXq^<_U;rcfTBsf*2!uMa8?ckkXV8hjIH%*5nF|BX)2epvaB z?%i9a!ZnFvTZg#BACD;hW}ly+A)sg+R|JlX!EJXWwA7^qew+ zpQE!&%#e`tZw#xWgb?lpaxOIs7QOg}=EC~?Ib8Ce^vP13%`Q>9rDowam!+?%ipU}q z;4k%5CniBWU6D3YRfNZSagsB2x{Lm+hK{_nY71{CJp8SIM866#K2W@Wv=px5AIajX zsfnF^^)uz0uNgUV^{T!^{JP=)%LNd5RcIA1EN)2GE9U1+n~*i#l-e%_{$0_!CDlTV zG)uxAm|F0*WU-_}-2SM}JK3E%>QY%!W&$#23UoIc>Fb2#p7gK+GP{g)KYOxrMLpF* z4_+_yx`y;nIs?IapOHRN9pJvNkZyMQ#43^^%O@%MZ(8b-lh$ zkwa8P3KA3DLj2{1eok>@t||;ns(ycGjs#D33xyt_kPE0fk#VA`JO8$!VV-&L2D~wghWI$ISzp7a| zbINgke)-eC@oFV?JVQl_oUXXYo(VYf%gQ`%FQQT>I7Q^H+8n2HRQ#pemJFZh6baND z{cz@!obrbHjodKJDYB2MDE=Qf?_-;$>-My0eIw7Ys*(O2Z8L0e`op>`b+LA8E)XW+_S(hp;D^ zgr&@;MXSuv!gHKCVi~L>Dmh+U`OKw@tIQ(R=P7pQ$Yk?hBP!^XN+>4tB>QeZNw`?}UBPBcyI8SRDq zg?_A6vJ_WMN&q5Kty6IRsnIdX>wOBOsyaS&DI1(3Ijt(D2wUCgWIrZH;v}EkE-F6h zccqIyXC~r8o$g}AP0o-GbQFJoC+}vz7=-GIDq04;{LKt$u|@3$t0=7#7Ps|Zny3<} zZP~2w>1TY>_J2(lN5dTyW0|3ib~?qOs%kb~sF5ghM#LxWQj?mbB-iQEp@TXd?EV+D zOyQ(8?V&#`vv8%oYH?-iDq8GQdltmhONhqBR}{jCH!ga=vJJ_lKi*JQ0V?4RDCuVt z*8;^V+&~|6<~Sj~wxp_64!tqp+lsgzI84LWn1$kwC>iD`tsGT7eiij3cRZ#PS2$Nu zSoI-6etcYQO$_)7q*YEh#d)%-A0M&;q?3*!!nqVK#jM^0X~Nh2jMp?z&HDCWz6 zB2QiNj1|%T;=j;{)6k!4wVd-WIYmvoY7_rzEu}{VPg2Es?=orlLr{28x!^jpc#$h= z7mcG*6nherJ<(l7aJouO*O>(?{H?TAF*YhPu3=0nxSHvUPJ-R&X@ILuZ}LAhYMoiM z^fkpP5uK2Yi1>6}^~k#iq^3<;Ho8Fvf!u!6S%9?lW&ynV{A!(9%zN7>ED`iDRV;ev zbyrhFWfbw^vlPj`GlI%erSG__V0{C!>z-O#=%%ne4Be;RSh2{1H7Z7fxq; z+$oD}TZ#Xr+JdjXohba#D}_2c7T~>y_@rK@43GZKy55Gk3TciT%-*ITJNdd(%3#yzqUy@3cZiwa_l(8rb&Eo#gJNXLP}Aw__T_EEJ~WxHMQOXpBX%&_doG?56Q304E6Gp6ANi7xK7yv2x_TA_O*5GfRuDAZKO_j6Val{GvP-u&(&U*+ zpy*a7i(1*4@+?zE35@(ZS)Ogmd~WDP(_H}O$QKv?-~RU45}LfpEYxJFSwQ_cy-HCi(M96# z#Cf|3i7mqtaFze+U2Ycj9p2?%$otpm3eq;4rSYAUWj3Q)7{A%fOKtEc>hQU;gw19t z{2{$kW0&LOj|(=NCS4Yzd+}%W@PV$sHk;*8NpWW2>Tn%Z%rMK~17Tle0M!QiPlj0v z-ybneJpE2PGR(Iq5B{DNE82IP<;V7L7Nr5`v+ptA9{ZiM zkoXgK`SB5iZCf#UAN{=*sP+@vhNnNM(l)cCdB6T9$#e4^r1{So;vAZ9~2F zFs&X6Q5G4qTfQ(N&E=#Y=`S)PuF9 z!*}X=Y|Bhq)6Wda>1UaSZ)K7v*^}b8+{{J)Y%p`#{Z^P1*5AyT$8V*X!#BsfYm3-~ z7JjSDAiBT73`+G|ZRY%7LUcm=7O@_`HUG0R#nUOpZ|(nfcTV*9t^1$u_{cbq-}-mm zEn?!Mn~BXq^9EnHS)rNi_wKoIm@{YXO=dP9Msh5^eQd1XX5R|$0)YzvZ83AdH}?-u zQi6AnttKrPU;OB${$m%6i^g$w zf}Lci*lBi#onz%tE$d0kI>@vH;o*K`M7sgBDmGQ=SYjkxE za1M43aSn41cTRWCbk26pan5tjcP?-)bS`o(cJ?v*nf=WH=0J0zImw)CPBEvN)6D7S zOmmhw+Z<<(H`C33%?aiZbErAY9Bz&<4?2%KPdZOIuNgOuTgGkUj&aYpU($GBJTx8| z=kyEuMg5X~MZc!s&~NFF^r!kW{gwV&A7l(Rh8RPQ;l{|}3v+~|PBx|(Q;liH3}db_ z&zNs4G!_|)jidT${fxd*->h%Zx9dCfo%$|)x4uW;uOHC=SST@y&b--^RD|9eig= zzMH>hZ&?@KhY#bU_`m!ryT-1wC+sG>&F->$>^^(UZZLN6Or`DJI|lXc7^LCHh95hA z{P7cjpDg$Z#7|bMV~}IPER*@U{ajo7b?M^A$J(_3n(%c%Fpb>gC~WI}jMku~^mUGk zsrCr1mf;uS7v^vO#`cZduc*!C_K)ySX;ajuhX+(Q{M-Q%Ex z2(2c@{oHofHo1=*BbaCSaRDbN%+3KyYZLD8wqp;@1^kF-w#?An--tz7F+1EYHv1o7 z)NZ{a)Co#@f)dP#2ne&$`1Otwx(2)ocENvsZW|q5@AyeerTblNK~#5x;|Fc0HF<;M zpe^fam)$>A`^Ppa*`AB;BxqTzF`FHKX+Q517`tr|6Aos`?+IDKb-H}_{O`Wzo8fd$%9orq_?B#chUBk0Pyw%!8 z1PbQal!!th0GqCHcNW0}Tf|E3Grvgg*4#F0!fwZCn|6pk-REem9i~D19C<e`;EZ{B{i99 z|LC*5*LQ=w^C)q@qa@H9pV0)RojFjAq6~$H&@pI&;x+rSuEI1@5*-1h)*B8&GvS8gqIQRR+yuF|sQE3&ThZJGbMDYL zcN|5D-*Hsb?pXN!s$F|PMISg?X%A`014lmX5zTwx_ye8A9y(T`x%|-a3C8k0a#YeD zS&bh#7HN14eBx-Kjj-B0afAxGdOmZU0YTBv9Tm`wevT#2g-ml$*~R`p(-$usk=h7K zf8p4G{^l(D*73(n&(CB1Ugwmt7h z*+%gkwEvZ34mSP!wPQ8leD=oS(Z*R5-Z)$~?ak7KtiMfLO<&qsh_;4)va?cJH|l9; z<+L}JWoJred{E3XZpHDctIb(yh-8fH}1S-J3mg1RtBH^A*z z$rcRb6}~L5Ymn#xfO?e8e^a`3-J12P5%etSm74H;g%iYR(L2qg^C9;1#ByYczdd02C6X6<}4gF?6~B z#FIw6AS>b=E2dVmeF2;TT!ZMFf~<=+jy4ozt09|z3bA^@1H_DQyWwa1Mj#F^7}N$P z*q1I9VucI!m!pU+81r}A5T-CTOYJWu;PwaDGKE>PbA;%HP;4+d*8o~jn7LiEWda*9KglD{eb&8Nks*w@;8>tQKoYT5$J zUIs$d=F(SXS?TNx<;-xm1BU01DCt^g{ZkgA@M4j}*F9(Ys&Y)jHml3CU@SgTp7qcc zQPT=651I}YAj`3|t^y0owpfw_kLV?53EdZy`jb(S1^Y&!|BBcpRH-5h$J(DOvaby( zj_?4t3BE6-sTEmEZ7Jy=v!nik{WR}mmdkqmF$>hRB^2-pE0BGeL_bgu6bf7%>SEDn zpRmi?a&lK@O@MCa${^A=OR9N*yEta8sLTpzE9i7(R|&p?HC(9+d^E7T|0yd8?&trEh31oH92SVk%mpH*&#wL4+yyoGj4cg>-SR5z zMagjzV>@O+G5w*Ks>5dc#x1iN8=|`S9l>xam8;4U{-0Omq6<~oHSD*m8k>S9u{xV? zOp{XacWV(g*EA|w1G+Mu*3^Iyr&E=hY!j`n!G5C_wV)|8tVy-l6q`1aYJLZ?&a{Sn z$8y#cFj*A~;Sjo2D(0fjbZ zZYbdAjoD*6R+VeQLZPvBny?kwl@SPAwnGcS@x_$;XEqrOUiCBE3wicy%JOQHU9&Mh~(E z{00StTbutoYpt!N;AZSEZLKx38S87))>$95U`qm=Qb^%KHrQu_b-ooFq`@a8#;`?* zI0f3U33#+Nw`CVa_l!99r?!;}#;5Vode~0cjo$o6~f>bf3U1}M6&9CvsQ>?bN_}^ zWF#vKp}hT@71IV-#r|RbHuRS6!peoJ=mi`5->B8O3rkk9;Nt*k9i(+*pIXhkA`~J7 z4DZJ7Y1(M&(SyaJx!;2=fzO}T6Y+uQXiruNuHV^<6)df6FhJN~L~12lEyxU}sD}$b z;S#=GSz{pjh3jkHiw)98OH&Gfd=Wlh^n$Z^Mv=WC#OJiLH%mnGc^|e#*>q@FyN?_bs%eK(@tBz3}z=a?Tq!w zP*9}L6*Kvlh%Byi)P5MNo%5AI0^Ap;m~c%fh~|1thla5)v~!kgIIE^<7wCr(tc-S% zdX8WpYnN!%2n6-pR_I71651PTG>TPlycJ*|=GQcM6jGBn^l%i5cd6d20_T$92B>UD z?C%`iCA!$KAhv_UF3Sp&O@^Q=D>mvzZ^yA89g=A9;HCBZcvf9Q zradK{?J0R#EUIpZ3_St?yn)-Vir**pT8cX^*A+1=qBd4uw8sC-I*XOLC$bURWtuaQ zeTC-cMCL*B{Um_BV$mdqQ@~9sHHEc6Gh_<;9L?@2@N2iI-BflTY>b-5uG&D(cQe^h zWVHomu{iB64V}eWX1^zi$l7M^Cw7qw1cErnZ20{LRBASopobJWn{CSTNX!CKBB-mA zm2g7=IPE;PzMjLlrahtW=CXVM9y6Ck<#;N|&?><+rM&H~Cvj3ThaURgVX^opF z4D6;gbslAZwhiE{M&>FAQ_1$+QxO0daQ>FyhqvwR$mRf z1H8ip#c+!aY#w&Xwvh$rkgMAuB?)i`VwT&1@h>*ASq`Z{B6X*Q`Rrlj+5|sw+Ul_h zxdlSWqRs5J_L>%KVKbnRKW}9<;GQOIMaDdk9&Tkx`3DJqCm+wUCI+R}RWJ{qP zi*`vxy0eQl10nTxv+HOo?~zZV_do`BY0Vz^sGD?W50a&u(~Iq8TK20_opcdQ+-`Sx z8`o9(d>{PnO=`K1mEpsbSxPmVu#XYkV&(nV=NYB!XFJh+eSob3mM;&mFR|v+gDgK> zRFi`&9U^{u5coZ&&ksS5ZqcGca5g>Y@*$uyg4kj9`B%54mLfbNYY2nSvy0!5x{3^P zq}*AIvK>Ii#%iKTKE@hrBWe3FNbDXxIR@PuNx6kx>M7O_mb~{AIDVUYoQ78=ns*u&ahbNCW)nk5V9niu@NMFsAa@|N z57uy*x}Cu>f~d?{i9wIEIDL#F{Ty^7NUb&pn!d0fzaI_FQ0fAhghn z61`>@*$-b!%?yR_0XtyXHDKX^ZvQsOFZ`jzQk4E}!sMW2sOI*c^NBqeegektnm`XP zB03GG;+NR(*_7ll0~WF$N&h_>a|waWZD%D49lPNz5N#T9m(Pw;A&2Aw{0 zl|`Bgr+^HM>Rm(JxJiqy!7U86BCZS1Kif*Z$!gjFc-w7OECYrOFkaqFrci>`X zQK`FZxi-YQau+!*WS8SU&M$Xq?R~J|9zDK~^yVpzdcX$56&8L7RzIQShtSlgbmJj{ zSUMGW#LDFJsi-DY6a_uajo*-aiQH@?B|KtH0w+qD@1n2~w%oM;fZd<2Ka%>D`!Pb} zO{)7Cfodc4VcI0x_JmD`qfdCsl7xr5@C<4?iLyUuk=i6H zbBWPGFQGJ7>EcUPFI-7EpiL!cm_(+mR0TYj6~Rt(4YL}(0*TPiey>5t6x#HfrJ$+& z2HHA>TD)OTVYf}+f*UuN2Jk<{23<9N7EPoLk0a@{jZXrLy4ZPct|TJh&Y($lUK(f| zu=BRC;4l4oDLl1BE{e2zfIlyUr$zp}3nWz`fUmG=bFABe{F$xbJi(wan+l*fW6GmB z_!(|@&6gTrhZlEno&>0WaljctlQ^#is8=~pF7ig`b+~^eTOSPs`nwiLZ~?Faqzetg zWyvrLl8ml8FZF$zLH7-V zhas`oofsQQMV)*hcyhwY6VQBX@^Cb9CjVBOfocV>k0z^&R|s07c7)ElMX>3iwZTEE zzKiDyUM5GNFMTwTv1f(j@0kE!p0UiOhu?p~dKqX5-{weh3n}WP3R5qp{FPU56E?k7TSI|&t za8&`pG^Zf{2y=E9lt0NHWB_<`UM{*9tslr72)~N%qYSu z0HISwcnq2vMWNkSDW)iQhpzRCG?z#oyJ)CfpzWc#W}=QK>y!KRT(r9=l(7dz6ytwD z%~luVbqmOVEpjgSMy(=_9o`78I*Qq|!e5pw&dcZY$r@^e#3wvZp_g2oR}6VKB(756 zWh4G-qlVWP=RrX9NOAs^Hq#0!!QmKZT7^pTVj8r*ekp!S+hBcBnqLmgw@DBX<}d0e zI^-Fq>*7EWfHX^UZKAI#f#S{9j7mJaru}EF`h-`t;avOnQ<&s7EABI%Upx-@f=|I{ zxi9(MEV#W0tHyt~X$P$?HE@OQJR~*{r-v*^4G&u@YxB=F?I1n*mj8_=4^ox} zVDLfe+JKKiljnP=-$D9KHUEAuH*zOY?jNMpQG9R4lQk`x_qJ=tsdQ_8O*?Moj^PC~?F4<^2EpJY^=yM+ zcY>C*;oU+`3Zg}h6AtB@nr7rubn4XM}8@{JnxHS zI56TCEL)uJ0BD`XJ8_gj&rqJud@0WL2Rie50oqw|r}9499GaQRi)-tx!>NeW+G%>+ zg>OU=Xn9xulO2;>Jt2(K^hZzZzK&-0gfgC^=RM(c&e0FOco8&z_kyE4O;#_c-)VZ@ z3z9ueReA&Jd5Y`J^AtNTF0;b3q5z?}wus-uvdWaOsO=syNQA!XBIavg*uvhBIhO70 zgE)1bn)c;+3;9+f%ZM1<2bV+$lm4!O3Z{4EDH_`sxSXac!51th`=-qyy)zR5Ss|;TH_yA-PY= z`4D4}>y+W+BXXJeA8+`ytOU+Z3)?7 zh-x`}VKvtsYv&k_yOG=U(>Oj5=l09vcn{>WZN|gTpf)fbVeu|49?ySALX$n6&(&tr z`gFbk34ObNG4_Cl|I3rb<<{!}DuyXeSNUJy6EFI4lE^cZ>N@a~(BV6T=RX zH@S7Bj4nA8?t*8JZ4;giLBh310e8EAAW}C3L(?~TFWsLGUEOPaHiKu?a_x{a1Kql? zASdkg7-Ho2Wk5PMBOKJWdUD?Gv@e( z{E%I{H@)3bS%^tm#uo%C9{Ew%c|2I&>(W>YqPc1HTFwt^A-afbI9fY5@;Do`rt%iuoCxV)Pbvy-0_ z$@MN_5A@G2Ub>jfT}0t7KmHFChy81ik~;MS%8HGD#3j)~M|Q!#UZtSj(DkddaW_AK zv)lMRydR1bMfdWCc=~fM`2Cd1??W)TM=|^OfY3WK-9quPpem-jRK3yWN+)waPY}so zm;L-&?n%;q4eXD@afE-wj4qqI_<@zF2N20n+B?AGbEwo!z*0aMik77gLStT2}-~(N9$8bB2h7wqb!#uX2I%vS9NSxK) zIM?Ekul7aznpPd=UuZq)*+VCT8gv1G5b9JG}BRmAk@#hilLCNd< z5xxalHvK;yixPa$QT`1stA04ji{|JlU_@wPfx5`Gg=g(WLyq!o;82reh%|4g>~Z9G z{bR}}EQ{ha_^|glFBCRFp#uhh0Ku@LKuIDb zDyrg2Ip_qEt}fL61R~-?ns9z;<~$$e4+Tfu2`B3ccNWPUb%alp z5f@PiSY?i%)~zepS({H^T|+Xsm5yJ7>20Iz*Wt9cQswJ7#XqDe*LmmM{iTQn0K};v z!I5HiKU^JGyaBiIkXGH`(P-Q^`Ie8m$f@$hC>*IP*@A=v2QzTAMRwMk{BOa1jG#TY zz>&UG`ZjXGht?mru_XfIggZ!T=Z?C|OBR$tIl>R8d@WTJ-GvfE+JL0{6nhCZxQmnc zYl^)KF1@e@--RvVns)6y{sZ`dCWK1eM`q&vy~}-A`Bk#+!$V!AY!7&&qLNeM6$M+w z1g%X$)cw1FNnE}gc1CRJ{gnnhfEEs;YY&jEcA*9jq5fU0fe#@7RAuHo;zw}P*X=Q| zy=-lJ%PEdPve68`b&GweRq`u;hesA<=%hc9?#+&Wq%Un4IueeE%TxAmy{^NhmA~vFSNcc%5d`YvP1_M>Mafk{t|wW&Lc|+uA_XmH@qy zw$OSNpnstO?@t4DR6mzlJ+ta4+TWyE4!tCrqYhm-XwLLyDDQ4$dgYvp1!7Y8@L4wC zh2#DLGP(XOCN||dQW-kQ^=fF`x?U84thTN@1mhYR`f@b7Q~wDt-^w^J^RFmvFt7wuz>M>z&c$ zF97*&q8|$A4KX&OfL;dF9V?(m;R%b+;dqd*kiImZ%AUbTTycpgA`Q`dH@t-I7Sanj zGip6T)T^xU!g?M%ic4>c=>;gVnBF(%5TVGSZsun2q9_8mgZ{>uAL9!#ZDDa8rFSb! z3B86L=Zw0g^#a;@YFAoMN80Hsqqh{Vuyrh}kHnj9Mmc?jZO1@5@EmV*-7BYmTjGcy zA7?(hOa3PEgDfKJwz*W^gy1D-_`5cfr@UT2r_A-~Y zz{EK;rh;Ay&9(~qpG74Ya9Naa)J381K`!$>%%L_F^(vraZbiK?=r~+aUsrgJl2Mp2 z3$PGx9tuXf{uA9ID2ti~c3ttYeirHDm`Zv+k#SejdugEgtIGP1ddAd1%$rbIuj2Ne z_(YiU^X9=265PaI0Tl_e?Nhz9A+e4Sx}v!@TVH;v$KaZurhg6vTT53yhi$K?0$=FA zYA38NU+B2ze@*6BdQ`v?Au&pw$IFuY9Is~G{7N_N(CC*DI!^6YR22{hz3*35zpq`j z{;H4mf#maVovTh!*~eW(A8reqy`Do!8= z>tOG@R++l`TokXY)AjU6B40e%Ku^@JTUEc;^J-YzyrE#l4Z7M$UxCMojrC8ofE$8N zYW}0%%BuFGfZg4?*F--m=5KF`Jy39%Oi(b{X6_! zFFO0X-T+P6X7C5S=&xo#wime~^&nc-OfRcO@{+wdoJTJz(_F73W;KV|_o6k;;rx2i z{pK()xuz1DnvqZ)Oo_zI-qwyty{8RPpnf!z{FyZ+T95Y+dMz*)dLS;kWpu{fa^V== z&=6ZHw$Za{`sqQKB5cit%&}Hm{Y>dDs>iKY5y49Sm+I;!I&taj#=AFF-unK-8v<72 zSiQ6s++B=^XHhEFTBw?MO9UX(;`CyLdS;A@-tepux~rG!s%{7`s-|9x0~2phaJ=qD z^JzR(r#E$q*E?x_=zct+KwrwA0Gj(!qXd1T*3WvJppVgT?>e|07(BpQ)J|V-*QQy? z?RC6w-Q6-f>wPplkN!hnX=gpeh8%AW^`Kw>(Wht=EG-p6)_Pj2y67RATaHI$N10qO zOum!t4h+j;|3?hYaL zps#u$%=EH)_0Vy(KbCg)gl3PWhdp7$W2sUv{bMw-z4RX-%#FSDk2Dn>K;80WgiH6f*#mo>_edKm`jv6x8AP3H$RC;)a>H`iVaE=n{`s@j*Cu z;?_2D2t4v28a+fmkEcI|>c!AZQO(|=dIFxl8m5oQK2QP(l+|gZ=QiY-*N5r-ow8qS zgv1wp-G)Q42hyS8dKymk@gww}s3<%dp})Z4{_aR&Q1`43gkXrX?cmX9pU{lam^6?| zk3paqNFB#u&!Kd6jJ^`$nv@27kTmQb3sb#Ke~i8RPZVqTJdc9oa{J z>s-42jSb0O*hIZAT>I>aB9f1yhm!z;DBomE9!}?VF}sTAI~+x^C05PZX=d94bPHBfumYJ43Il zO{D8H^!mu_KAj1#Nz`Gc{ynJJK2!e_R8*UVNHN(;nk9Vb6w>A(!J10_Z|Qlh3Ul-@ zE#DLYR-6&O!HEgS6TgVuibR|f(yVrK^+>^?L-XJ!rcu%PdMePHF<-BN=I(qb#AG_K zK>rt)m+i#or_!k3LVY-rll+VHzD?!|*fyAlG;mpLjIaT2*TLu)DXu6#M%aBlz7AxJ zY6_P6mGZljdAT^gbfve8;D5VP-o-HJS+s1i-XF+SS%RIr(SJ+8!fsZnrTR}=)--_u zJ_td7U*$z;{bK)8*12W+2|Ey7wGx(emENq>MT-EqYw7bfdIvk_xK?gR#N$s??%58nFq(4g&=+HD+YY@g5|#=(_1fUd-#hhCG^2Ow>p{`a zyPyteXYUpkm2Pd`qd(LFBwr}oF-MTKe;<4Z!fW9JpefB-aR6Qw?e&AOm@uiTC~Aaf z!L>(8KjDj0zl9kDy6q9?WGyQBu>Kq<#2rB@nMSvcAnvBong8?)2;duz>an@JrXk)U z34qfR?_4t2Mb%@-@6u@0F})uOa$(1j%cjwy<9d7ev7#p+j2Bez1WT-HA}Un?yF-3oW( ziXMRqK>aJY9DF;->Ul+Phc)!{sy+^B`iN_Ky__q>l2D-!b~oNPD9Azd1bTW634NMX z>^dg08Da`QulYXebM=NEVO!Uq{u<0;Y1B=q$SgW>6Fa3*-doTKX|{>5tyj08c5|t~ zZKV2X)a*7mF_+feMshZnPT$slu^sJ4`={Z~tHB-pK`yzCxQwm?bCQ7w8Qv^vau=&# z(}=t9ODG$tChI-0>NS0G4@`JXE$-=Ma?KQ2%Cigi7l#%dOu##y)9)eqA4|pVBl%CG zR`>PGXzD)Drvtyo51@|YDDolD98Y~7LRFX2-iP{UnBsUOglX-4r0*0g8}kG{$g);F z(QDZ->i=BthTh)K^{Cv-71KpHMb!iUy4?Y7UCT&&p*O(+sp$)#x`O(?fU2yZ`7e-p zt)#0j^lt)IiG^hP+Y3?RKekfz&r2x91RDDi){#b+U*e>hW;J=GXSd@B)b_0&jb{H_ zeUp~9bc7KA-KR9oXbYvxVl#fpr96mCh9ZhUOR|dBAk(alHUsy0tE@hDBVB`)76~xE zth7(;EQKD3!VNw$RLQ2xcZ6{JffrD`ejm5|kVIDeuX-sh!03(+ zRD?%z!;Lx1xKRnsZElQ2XLsHB2AgfxjZXF)`^9ELS2d9f)QVuPy?7tM$c2E_(q&9W z9A?>!-l!uF%VzwYW3NO_XSa;wqKivw?Za6i-E0@El?ynuNI_5Tnx1k}y#u_-C zdLc%*_()W{JjQ-p30KK$glM=c`!%1@2TA+oe8y**>!<)LFo@{X#+?_RK`Qf+(FU)8 zrhOzP@3WS;fdb+nx#LL0r<>h;L=_)_6jbk*tpb?`T zqt^wEf@s1E8AU_oqHysstDFt+kD48bYpG)tUC1b-9kWIhGJX>XJ}7Jq#v7yEiWn6H z2a6a7fk@w?Mm{b3A+fU*kEmGV^@pLfyqGZqiz15~tI*^tVGID8vq~6Ouy$xk<0%05 zErnbf5c`)F?5EwOjU!;oq%x4#2s&EEc&i<<*Q+N*vrko(?J7TxZ4X2wTc4 zE)RzIAdom#UnTqJ#uvDi`{r|FJ&riq7lzx0>@)l;qnHhctvcTrC6Tjr{sv+gXkGlq zz$JD%J&7=WLDR5`aTeNDzN)bp+~{A;C{01tj1KDeaZsG1)s1*9L?RUKsDzJuh*ySj ztE%?CPV;L(bq3On8sNqtDpAuYrro3;Y8th&Ul-VlY}_|_AkD97yaZcj*D@~RY&f{K zQ6G9mXTLT601KObXT*x)=e9a9lk3)-Iv@(8pVz|%H>pECqa%{bJN1kz*>4NTIJ>~H ziv-4oS6QmmH$K6;QGe7owrV-m>!DHptC~a-G)*$__Tjc zYQBg2TcJN1%|#OZ=T8PssrP7f6VP&xjx+&f_bvTrg9K$$ni_S{JZNgn1I&rPz+ls9 zK>b=6d4goOjE?U{tQ9Q`eAaKD)yQKE5-;#yXldL< z(sZyD>|itLt&Q$D#tdl~{J4tb(D?g3s3^$Q(p+7>)B?ED(w!@&V;fR8+h=!$;|BEDAXZitZHrMvM1n*X}Pd8E<$9*7!g){i~m zMa4F~;90Qw#NG%kFRYEdjc>JVDoY9!C-f|kDiF@s*LZ}*+55qpUZuo-#!q=}`HTYr zUB?@Cuw;4lW5b6EFZ44ee$_)FCf=6N@`U4EPdL{$$U6N#^8+Vb*F}XQLJM<<7-|!u zL%?t?Le&Ai!WnJo56n=I>2G|6Gj!nr@SWG`Xzh=@CT%E0`I@#41&?0S z^`S=bJhJj3jjoj6ZF%0%B2FQO__?N7rH3Irql&O{I6(KMbHlN^AL%2EhuYv}BMp4Q zVz5~Ku8#~}<3wqnK`Uj-mhpE1cOjFZ~FNk$7K z@pC6b7aC1Ae%3}?`29=qNsXIRj4JvV0j@gyj1!-4`*f-?4g>#9HKMTevuQ?tG(S%R z|B3!kPh-^6O4XcH%_}vQXS!VQnQDGkO{eK{`55)ITs22k=QH(`dxl(BNi{#rkPABC z$xV`2*bbav#EMPgC5VgD#lO?K0&N%3k{L$5uhlHPl_zH1lCy5D5g*|8&XPd9!*4c= z<@*O`1`;vTaJQB~LS+e6fU$;&89O&-nx`1Ac3C@04E)b7GB1;8Ozr=FPvF#bwH87b zWnl~F>f#}9;sK8jtHU|-l=<_*pO4B*Av+EorA!BLb9HT^;v0g44F0VFd`20tj zB3Hb|WFWo@NQXdM^4ZNpCrAw@c#v#wRVxQ)IYDZ zXE*>GYEiNp91t=8>3WFI54TE#En^)DSXTX&hACWevsEHukEQvmjW9#GaFo^kJ6Wp*)FS?&NYT)Q)V+arE6(FZRgDk^(3 zM&|UsvB|J*Y;ykH+!(gm<}bd}M7yxbcG5~IXkLqnWT7p9TAB!yV&r3X3o^z?8EO8*~2n_R|&pKWbeBv-ft4w$4mvU zYC>#mq}X9U%MqUt6`Abu_QbamTOD9VQc6-xoahwK2QwhmNJ*|xJ3b~Q^$^n)sJaQ! z?PEQMneV%4#Ee>z$*pV0Cwr1oj<9Sk(a|`ettTE|my;x*{l|D~OsM7ojtQNQGT)c& z_*Pbp^+YBe%e>{sV$0*q0H}|vN`|CHwC{96!v44hzO5z${z;bO-K31(Q);F{)w}O$ zri+=_^kae48Rim?jS|`?MR{sV37loVuls43g0Be@IGke+FvjDFPsNwFoM%ivM0*lb zT3_%!M78!rwY|v9R-S~!gxJnisw8x3gzpr(#9WzrfO2H)W#;>Wn#SNn^-d{bgDWh= zs|w#HC&V|7#Mk=>?1ZS2uQIa@I;%%UwXT|)5FhV}O1Z|e`MRnANbUG&Pp9iFyRWZW zOmdW(c!Rloo%QjpGL1pQO=kGIs){eExy5p1Jhx9uPDpAfzNzRobNYH~#Kfj}lJ2lz zbhL_Z5Sf(hL04>T@vA33C9;+0F4KLJ>)~5}?lJCrte(*F{yRv}D}1ZcgG?JH#3i;* z@id4`Y5kBfv8X{3zH_PNBbqtmld7m1=k*AEuLnbvnDOEkOvCmjG zDVnN68V!;>iNNqV%ki!+A`x7OuAAKI1#`aZtp^A%nfb1xs`y5tSE-C=65eZOc%PIi zzR4IB0({GyzEQ>bE<8i>J_&W@YKwQ`>Be=rX+sZmKiSjW`{-5GpL%dZ5LX4?V^yf|iTryTF z&;Tx384=a4eN2*Ppch%8#f=lh+CggEi|b%7E<)f#xMFc57;seU1_=;hgM`GPJgX!Q zIxs8)Bc%evd7e}`Ch)1>vPMi&a!RJfBLExUJx@moDJ_+=s;v{C|AMr!USgH=5}GtF zLwv#xq3Mxv<9SXAqKchvXu6mB>hMSJdjI7)yb2*4mCu+b@a*2+)cPGf zNwJZMVq_xE=I#9{CZ%;uyy(N{LF8@?JtB5Y=1N@~MRxEc3jR*R#;$(!g32$$Y0N`0+doF^p`>KnP9`{IS*nUMMh0bfQC(X)}K`X&e;ASP_eSn@5rrRdq5 zA@@cdWE9`RgS{|d11Ye8WNDFN?pE%S+Ec|7kMyE-otSvfwhTqD=4sJh0@$9hN0n4? zLM+^oF{??-grqppwKGG#8hTo_kByWuepd$mjR1Rh25MEKI*K)Wyh^P+=w7c25xm>y zWhGD+0dBun-+#{tZwI_fl}kJ510)%G$or(6!eO2%2zYhj2$%Um9ppSIo{aq9KZ+P_ z=FWMPi)7{FA2HZM;PNAcb&TRho56XH^Wco33{>iRQd%cOpP-4O%{+LEeGMj-Jf${} zFob(nb53(#tQYx4-9#DO&X6|73=TfagEBx%C$5&9qjF=+Tp{Oq&Wuq-vKqcX&BvIz zTV2eA7Ys|PFwCj3Cn@eyCQO8LR_iYFV6Q3)Od2F4$HpY5h~Y{VuW;Wt^ogO`i1nhs zQB-97RXQ`q%$MsL&z^w`oVfycowB8wxr1+HqCz@WHF}f2Ni&0U-cp>c+deiW#s~N| z#bIH|I|^tuq`jSdLk;gL+~H|_T@8?4+@l3)X0BTI-y5ux5E)$$bUgR~4x)aCh7Wm& zz}O3?p$9%AS-2Yk?GZW0ntAMxc}{YTHG>*NKjAV3l$g}%5G#m(iinBz)nKCy5s03t zM-eH+<8vPRztDx^2=Fgx$XHWcJIx$x<_mtsGiAAww^G!v>C9L-mp6(%jZ%`@N2Rn+ z@(AE>6*iez*0GCjiv3jXBAMJ(ml~^jyu$3JOBEN4Yvf6(-#!JIRn->Vbt$_{;5wz0 z@1d4EGkR;lefFfT_Jc z+NY@QQHsyi5~73&`Sg^iXu6r-K3dOBUDM4R0fO2w6q#=3Ljfx_-TVmW&VSR*5c@bi zM9!eS>1G!Dc-*py`Ju>*(my~+2<2ZdywrLL35gTb&R*^b0}%E;QL!ikze*J+DOq7& z43xpE9+TB#?^9KL6KaddsJ2sdsryx1w~uctNP%~ps!QAPPE@|9YF6+3X_Wr2nYZzD zJ(m!?R1&$?2XBVjS_at~vF(#v3!9m#%M+XsuN;`ACJCWQfk`m4$vMHyn~L`f1Z0GP zmNBgwwT(%vBWQ?>ovZuK$~7?DC?z2Yw$`X~eAGO(z}JKPsBuC{WNh+$-6;S`#gdpT z@Y;+}T#zZa6TMJjCb1G4uqc<}lI&2{C0M+e)=e;T6<_k6LJ0Kbk#(sOfTB4jJ|?;K zGI~3~%-z(|W$?%_@9LdWaQLVLZxp-SYac$#Z-9&;A;q&I6Vj3^D-}MH3fUo7ucE|> zX3&?bGcj8#a!uqrYcf$F>8>Ku-n9y_5P`~-*U<)msJvd!9H6Rs+O-E38+0yM=Y86! z_=Z$Yd~>Oa+?&XlWQL}0es4$t-lF#RPWOe{tqN6dZ|&rW*!cEw+uoC@cdSN2Z1i@; z(TL=zm>9L;j!ZpjpPhQPRDq?OuJj-@CNM zKBXCrle`G*&v;fa4gjHFustUDARNpLwq`;LBz!+sJ){skd`*(g2+=hhUFL5YgMF`sjdhdxE&FplGYQq>m66=3h=Mo|e# zo)bzyRYi*6^HeA4{$%+1Q)GPw6dg(9^ZCn6x=FtZ0U~pDxh&(1& zZE;RbQ2bW$|GeU+uqlyEUGUJp_-F>}RTRse(#6acO$0N#VK z+T*Iy>FW5xUR5=?raIoGU)PmHL}K*rV0J?ho+;(JNnul=&9@X8nX|3i@0mySPKij3 zI^Ox8&WQNvy9zEVAy&(S?tQO|lV^2x^cDJ=8vVeF*}H*O~yH@3!Rx}<__v=s9KzI?ozqBkz=}Dw75uQSMy37ISeC^82dGTMlMq&kKujH)KYK@n8fP(!9-4N+Vbp;vVd zqlq)jP<(!C^$asOb%X+pa<4C-j#O||6+kT+WynM?qZFWeN#XCU&Zxf8hRo%BJ2p;G z-DAASW|R)nyxabk81n7lJ+VyJAQJ}?$09yvdQ|Rs748)MD!^EP&@_8A3 zFm!LK(CY_H5H#VR@$ESXBFb3s)Hb*BMgOK~~b6*=9(S zRYvA~UGh{^Q3NkmD_VTKlOA!6B3Sf+L2y}Xl`8utiPCwqht{I-X-NuYUY};mSb>_k=R6_bER49@k~sECc;1Dly*- z`S$dC!|ISB1bs$rp*mFR_ESPq^x5~c8dmA^Wl85~(0rWf&eOd4W^mIB(l1p&qA#@L zqI#+l6EB`FNsFlQ!Bhs1`N|uqT_3#zEo!x@ z^Rcvk!B4MMK2aTDskh^)f}c6%d?v#|1(|Y|M#}hH(eob1UML(s;K@tcun^UlS8Bm~ zIp%96rD`oimib0u@s2%jrTeImDV6Nv6qx~f;2Ra2x;jNt1Nn}PxN3x9X9h-4u?2XB}+1^!BDlyyPb!r zO=M(O+YVQZ%$!_~@G-J}VhR%OKRhGVR_cg`64fZD3w**sUsmLCYY~+~&YUgj(qc2{ z)6q_mM^$KmGdW8B(sRRak8#SIYh{Ms+%U~4@{S6P+JRefDPyVJ5;JG6af(@}BPi}k zMvkXQ{E3%TacP$B%oG?Zz0fWhslZ<#T^E`RTX3kyS!#xUJYDfRQ#w0C zfkz;LO9EjjGrb)d`Ry$FXQ`P#Xtokc<}`N>Em&#>;Z<@>2q`ZuVV+ZDiP8u94wXu# z^VRaq+3f;yEyMA2p(6Udbas)_+7Hv&#a`Sp(%B^nD%dEZlq{Pp&CEmZz%n&W26Jzh zr8rSf+)hCkgib71Vip%nN*p3Utx)rPOQU0wR(h35)p5Mwl2>wIDmiYqE<>#43~hBVxusKG8u^@JI2 zR0w4BskCWR1}oIes&R>%KUgddh+Am6W#+BD)hV*r3K=k!^23`$Or@|HWK4+#=;X4bfP=5b=170e`#Q^?l(0c?5OAxypRPs#CRA@P*x_tT? zk<{w2(qiF$MeWrK7CG|~MW-0>)=V6EbGo(>@Zm%a^f8ZLQ&L+2zVzI20k|^=AQCOEHWhuH_9y&MBiy= zrYyZe-P%f)G69l|X`&*KJeSE+Sk)G1KL8`nOXt*Xnb)6p<`MMP_3hS3`dY9kMHFK% zP=l2?`dxHpN_}ORP${4{8NZ~cs}q&1xR{XSWzJ=9v;u!?;u`b_{*=o(9A0grT4z^lc+I|4pc4nru1lE5?iay9Jgxnhb} zW$Pmkf%kvmR4;&Fa}VIhq`b`BAvSyEbhZG)MY66`<+UQgTNzIfe(j9{oe@*;Qbkwqq%4E>FhppD?Q0MOO+1y_+{bt7#JuFtwt=o;YNBjYc!)qr*h zlw>N?Q!V*k6sv1T_fk&^sg}Lf4k|NjEN3@W{~$8KE8UVC?rj&X(snG zo!)M53fTV(lY4ta&Nsl+ePG0UQv)*w1zv+P7JG}^gXylIV2G(FW~xRHH4XLX-C~%@ z)U()NxXHb91^f}dApw4*sYfLwb{2o9E-ucKGzx#qu34*;W@Yg)CDAq7ll#pDdG)UWC$3rk({t|C-!8 zS0FUOHzW|6Naxp@xk4wIGO|au@AN@VJ(;qtGea6rF=aM|@poDCR8uCc=*yHiPcvmQ zhR)2H^7M@5Vo#Mb%%FePnYq56spO0W8Hwer3>cYH%h?&*WlARJ;7_Xsd*+%s!BMz? z(ov|>MdGjDc{&LR%rkSUKNa{v|9otKJm7=g1*R|im48O?gVBZ5V7*yL{B@1>W|)1k z8BSgMnK@|gdebCYZ)T^x_zQgYrDj1I+6VQ;=jgXDGm8wz$1TM}813n2I`9{+OcNhk z`)z}nAD>qHYlB$?pH`c)0f1N0&JAWke4WN!@wA3=ZZr$y^Qd2J1jNrbVyEPd*rd7m zhwz9GpUxITvo@M8I=d0hZ4*7-XcoYyA3`>n;o27ZViUk^rN~WYQTsNtg#4R)GcBEDs2YX-PBY(;lpHjqQ5p{*9DsaYabXfaUjq; zu^E)@ryHA5tUW+kx8PKLkcw`>(nC~di&-3B6wz@DAmIBIx8Q>HKeNE_{btaIo8qqn uY{eI~9WygtxWUmQIVFkiZ!tqd5}?cYgL)qzdcrI;-0jL`{kauv`TqbLqRs^X diff --git a/sqlite3/exports.txt b/sqlite3/exports.txt index 0a538db..96bc471 100644 --- a/sqlite3/exports.txt +++ b/sqlite3/exports.txt @@ -7,6 +7,7 @@ sqlite3_errmsg sqlite3_error_offset sqlite3_open_v2 sqlite3_close +sqlite3_close_v2 sqlite3_prepare_v3 sqlite3_finalize sqlite3_reset diff --git a/tests/mptest/testdata/build.sh b/tests/mptest/testdata/build.sh index 56e51cd..7cd5a8d 100755 --- a/tests/mptest/testdata/build.sh +++ b/tests/mptest/testdata/build.sh @@ -22,5 +22,4 @@ zig cc --target=wasm32-wasi -flto -g0 -Os \ -DSQLITE_DEFAULT_LOCKING_MODE=0 \ -DHAVE_USLEEP -DSQLITE_NO_SYNC \ -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ - -D_WASI_EMULATED_GETPID -lwasi-emulated-getpid \ - $(awk '{print "-Wl,--export="$0}' ../../../sqlite3/exports.txt) \ No newline at end of file + -D_WASI_EMULATED_GETPID -lwasi-emulated-getpid \ No newline at end of file diff --git a/tests/mptest/testdata/mptest.wasm b/tests/mptest/testdata/mptest.wasm index de8cafe..0395be1 100755 --- a/tests/mptest/testdata/mptest.wasm +++ b/tests/mptest/testdata/mptest.wasm @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:430afdac4d212a6e4b662db46c1bbb5bfb3d601770ae493beb0420a302dc3131 -size 1080243 +oid sha256:e155ad9a9723b2eb2c0d187cbd079f4111931064a62ba0cb30ff4e4242bf5efd +size 1077263