From fd4f35e8791ff6681a790efc2b6c4cd3d7094663 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Sat, 22 Feb 2025 00:50:19 +0200 Subject: [PATCH] feat(import/single): support UTF-16 LE with BOM for HTML --- package-lock.json | 30 ++++++-- package.json | 10 +-- .../samples/IREN Reports Q2 FY25 Results.htm | Bin 0 -> 693586 bytes src/services/import/single.spec.ts | 71 ++++++++++-------- src/services/import/single.ts | 19 ++++- 5 files changed, 85 insertions(+), 45 deletions(-) create mode 100644 src/services/import/samples/IREN Reports Q2 FY25 Results.htm diff --git a/package-lock.json b/package-lock.json index 894c82f64..8eb6db485 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,6 +31,7 @@ "better-sqlite3": "11.8.1", "bootstrap": "5.3.3", "boxicons": "2.1.4", + "chardet": "2.0.0", "cheerio": "1.0.0", "chokidar": "4.0.3", "cls-hooked": "4.2.2", @@ -97,6 +98,7 @@ "source-map-support": "0.5.21", "split.js": "1.6.5", "stream-throttle": "0.1.3", + "strip-bom": "5.0.0", "striptags": "3.2.0", "swagger-ui-express": "5.0.1", "tmp": "0.2.3", @@ -6175,6 +6177,12 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/chardet": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.0.0.tgz", + "integrity": "sha512-xVgPpulCooDjY6zH4m9YW3jbkaBe3FKIAvF5sj5t7aBNsVl2ljIE+xwJ4iNgiDZHFQvNIpjdKdVOQvvk5ZfxbQ==", + "license": "MIT" + }, "node_modules/check-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", @@ -11889,6 +11897,16 @@ "node": ">=4" } }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -15917,13 +15935,15 @@ } }, "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-5.0.0.tgz", + "integrity": "sha512-p+byADHF7SzEcVnLvc/r3uognM1hUhObuHXxJcgLCfD194XAkaLbjq3Wzb0N5G2tgIjH0dgT708Z51QxMeu60A==", "license": "MIT", "engines": { - "node": ">=4" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/strip-eof": { diff --git a/package.json b/package.json index e14d45979..401f3d5ad 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "server:start-test": "npm run server:switch && rimraf ./data-test && cross-env TRILIUM_DATA_DIR=./data-test TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev TRILIUM_PORT=9999 nodemon src/main.ts", "server:qstart": "npm run server:switch && npm run server:start", "server:switch": "rimraf ./node_modules/better-sqlite3 && npm install", - "electron:start": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev electron ./electron-main.ts --inspect=5858 .", "electron:start-no-dir": "cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_ENV=dev electron --inspect=5858 .", "electron:start-nix": "electron-rebuild --version 33.3.1 && cross-env NODE_OPTIONS=\"--import tsx\" TRILIUM_DATA_DIR=./data TRILIUM_SYNC_SERVER_HOST=http://tsyncserver:4000 TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./electron-main.ts --inspect=5858 .\"", @@ -37,30 +36,23 @@ "electron:start-prod-nix-no-dir": "electron-rebuild --version 33.3.1 && npm run build:prepare-dist && cross-env TRILIUM_ENV=dev nix-shell -p electron_33 --run \"electron ./dist/electron-main.js --inspect=5858 .\"", "electron:qstart": "npm run electron:switch && npm run electron:start", "electron:switch": "electron-rebuild", - "electron-forge:start": "npm run build:prepare-dist && electron-forge start", "electron-forge:make": "npm run build:prepare-dist && electron-forge make", "electron-forge:package": "npm run build:prepare-dist && electron-forge package", - "docs:build-backend": "rimraf ./docs/backend_api && typedoc ./docs/backend_api src/becca/entities/*.ts src/services/backend_script_api.ts src/services/sql.ts", "docs:build-frontend": "rimraf ./docs/frontend_api && jsdoc -c jsdoc-conf.json -d ./docs/frontend_api src/public/app/entities/*.js src/public/app/services/frontend_script_api.js src/public/app/widgets/basic_widget.js src/public/app/widgets/note_context_aware_widget.js src/public/app/widgets/right_panel_widget.js", "docs:build": "npm run docs:build-backend && npm run docs:build-frontend", - "build:webpack": "tsx node_modules/webpack/bin/webpack.js -c webpack.config.ts", "build:prepare-dist": "npm run build:webpack && rimraf ./dist && tsc && tsx ./bin/copy-dist.ts", - "test": "cross-env TRILIUM_DATA_DIR=./integration-tests/db TRILIUM_INTEGRATION_TEST=memory vitest", "test:coverage": "cross-env TRILIUM_DATA_DIR=./integration-tests/db vitest --coverage", "test:playwright": "playwright test", - "test:integration-edit-db": "cross-env TRILIUM_INTEGRATION_TEST=edit TRILIUM_PORT=8081 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts", "test:integration-mem-db": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts", "test:integration-mem-db-dev": "cross-env TRILIUM_INTEGRATION_TEST=memory TRILIUM_PORT=8082 TRILIUM_ENV=dev TRILIUM_DATA_DIR=./integration-tests/db nodemon src/main.ts", - "dev:watch-dist": "tsx ./bin/watch-dist.ts", "dev:prettier-check": "prettier . --check", "dev:prettier-fix": "prettier . --write", - "chore:update-build-info": "tsx bin/update-build-info.ts", "chore:ci-update-nightly-version": "tsx ./bin/update-nightly-version.ts", "chore:generate-document": "cross-env nodemon ./bin/generate_document.ts 1000", @@ -89,6 +81,7 @@ "better-sqlite3": "11.8.1", "bootstrap": "5.3.3", "boxicons": "2.1.4", + "chardet": "2.0.0", "cheerio": "1.0.0", "chokidar": "4.0.3", "cls-hooked": "4.2.2", @@ -155,6 +148,7 @@ "source-map-support": "0.5.21", "split.js": "1.6.5", "stream-throttle": "0.1.3", + "strip-bom": "5.0.0", "striptags": "3.2.0", "swagger-ui-express": "5.0.1", "tmp": "0.2.3", diff --git a/src/services/import/samples/IREN Reports Q2 FY25 Results.htm b/src/services/import/samples/IREN Reports Q2 FY25 Results.htm new file mode 100644 index 0000000000000000000000000000000000000000..361ceb340c4e2520d6d5be64b239de901ad29ef0 GIT binary patch literal 693586 zcmeHw+j1O7nqEct!r_UTH?SjmD6hD?G0g)=kRm{8mePnTc_nI=rZ_L& z7Kg>G_{qH<6=%g(@ni9*xK{j7oEAs;@2q%*>-O;d4&Kl4dVo((i(~wETZd|O-%?SRR#YS-pKX>tr+j!4!-!`rvcOxG2UBRCl_`QR_g!VP=e^ETc-)F@a z#pl=)+uOSs<67~l+Y{~!cYP0gxqI>1LyWnH`Ro7-Y?L`Z`Bz}Tfy0H*F~Sk9*mHm9 z80S4^zlZC&@8KK5$*X?C-;Q6OmD~|LCPd;*cdJHJ`E}<(!a)j#%*Q4V1 z4%c26U*X#Nh~K%{?_w2xhj*{=WZp%X{EVBQ`M2(xJv?~_S91O8Prg=sQ^WLGVdKrP zXPX_6e~afHU}p{h&sgIex~F{)cuz5hL#)ped~%5Q^Wtl~JHvdq%WvHG`wm~fayap{ z_zQ<|&v5ODoAWuY_MiPdzVYv#6#sRIt8M~NKk4Esx}PoDM^D;(qQtRUXbKmi_S{r3T1IcoVip8Li7`x;k}lX)zd6%PQ%r{IxZ z9(rhI`2QGt`7JQQWKosdJjYWg6-eu^F;~0O?tKg_IK)%lfuB7s{uYqg6@+rw(|M=C zxp+0}T;m*jOPRixnf}7Kfdcv2Tg)WTU>#mc8m`}I@f=*|PpY?YRZfXS8 zZ@$12cku1uApZw^Pwep6 zvsXL@wGlpQuIDA(psrfK`#G*9BwvA!|IzW^uW;v&m(TnZpY!?DQ)~^p?}_LA6(Blt zbJ=qm#7}tEE;O>Trqnb}+I{g@|pPv_hz-(;&7hN4gQN8jp zR^_~@I81AX_x$rxcdU{ zU%I)*G-dZa#|rc67g&|Q#hs*1($(jVVuW!&Mu&&HM0Zy=Ii&3 zuzrCnZQZ_gD|v(!@|M%zVP$Atduh=$Q-k=4gW|+-l2Zr$saspxO`K8lj(qF59IxkI z?3H%#Iqvb=>z9BjzT4;`1?Om2Z8_OM+NF&a<74?-a(2Q>EsH(^a#-4mpX1$IU>2dI z^~u%b)2`LlllSqu@39kHv+9$mckg2q;&1oe&$0V2YtQ%?I{IB$KHK0F&CfV<^Cd<< z!ARt>RXDtVqWNxGK4)0--#J*Td(IgiUf`3r7^}~w72kB%>7cua75l}1X_x~g2X~7Y z>gnYNK;1m{JGTxe5k^+wzKvD&K8Pmhxtr(Ca(!D{O=|Kl!N1zaCxx8?pUL^__mh+C zg6IE;Yhw6`>17P{_-pvTSmWYVU0OG_@v;?}YGqJo``S@~--AG{XILGNIbQ?Msa26P z^Lx?^{Uq10pQgK9yS(}jSc5lM9q#vcPRbrZx>CQ{t=(ht#E(OZhQ7Wp-QB$ZsCI|J zL^)6D^V(Y*EL>%87kdfD>mK08d-ABAHqV{>h5K7tHag=6={vuWp!5Pn86QtI=_92)%G5$Yj|(7r}wjr=i|f1_38tg zdHcMqq2FrNA>3Gb2=A;sgm+gSLV8bEn^MSSazNO|X#=-0&O8I}Ud+$KJ9#7f8dvJA%B;qfhO08Gai!#{%xYZexhk_7SE{bctj3kLt1_!`rEs^TUEXFadunG< z++y9VU&gx_ac8apBLFk^m${egHWNnZ{VaTx+k5Rfr*)i-`P&&kTeqDsoLWcN%ibW{ z10VAka~GO9FZGM*EQRzq)GNfKLgZ`AdFSBGjAi;flNop#vu~N7@fr~~#`VwEj+z)T zWwsgf7JU{iv+j2#BLyMm&>srjxRCTW>mvXR^+8 z63=9v=_H=XxOCFw6Ta=bZuH5)ec>!L>Zt1`AwG8=PS#qo_I=%;e-5}=vCG(#_cV_= zgJ#^AGFnj1EAo{*)^lQZS-1Ea{s2Y_-oQ3xjSFjQ#+-Ey4eK+&y^Gqf8LAuCGg4Te z!ForegN?_EE#ee8g0GiaugvoHnXI>FQr(yJwrK0KS!WHUKAUm1lpH+y8|Pm>gKY6} zjxX^)W1eG2Ynr7hYe4#FT)qyRTmjvNOpc_^Yo0_SLTIHV5DRYyEWICfWT2 zn8Y4;>~!!IB%iOD{tz@PYKhHrTSs~L6xxZ;m^1#go|a1!4z8bnv1u0T=QC-VMVSYz zBb{{5X&v{8*;wqKvA%ZWmls`x*jbXC>-)8{-RX0%eu(TuGVP3-w8aex^ZOA)(hdYduiQ=ip?t`_`A<=_909VSQ)dBU02_eLgDn zsr8)=`*^+wmtvNuKQUsx;v9iCsD)Y&P2a_jl)^JG)^$eoj#`i2^__)vjAf@y&%M^K z?jc|qyLbC;ufEP}-S#EcQC?s+>p73+Iw9Y0_0OPt_FrDdydk=&4-0)9|E5ad$WG|nq{eDCpWD-{fBw1H|2+UtT)Yvd8{|Jhk1M`bUtqX&>WHc zW_~qp$Iz>r$GAO0bI)U)J(gv>3iDWR`4Q%^-tr^NW4+}^n8$j{k1&t*mLFjr>n%UR zJl0!&+`;*VGna$F9*m4YuD>s$c~0vsSDNRv-ZI8&FL~0(iOWOu=Zdad47{wzd;y={ z9&*(g>px$+XnuJn%uQlHVD>I#EQvW|tbAPO-LcwJ?$Nq?T;jQ`H+S<{$Lqc$Hj58q zFV;`CeCGHQE6vEOrl|yJsvEL1tI9oK%AC}ESnJF=U$}0nJb5|yEXu3u>wMTFoZWQ~ zT~_vK#+~ll>wuYy%=%#u>Q|7VIjY$1UG%^zuN$qE*H|;w$Uk@WYP;E>@oUxwjoDFS zVpS83-n*zgY=dJ88f}Jyd^JADoc%kvAB<^L_h)RG*bEbWJbhpqSHd;JM1Rd9m<)6B ztPs5}Y0%_Y8~RQbL1WmQXKm;KNrNWG+VFI&G-$@vaGJ3AegiLN@0C+m32zuYHSfFc zGMVBvq3umg=@b^8&vwcy7w$Lk<2p?FR;bRE>(CfgO}$_JB>1dg#UphhdK~gle40$Z z3dqP|VoWCvneJmdcomSx?HG!*uvX5>sEqp2Q-m=d540QS6o^-G1qtRXke0_A>tAMYM)|(%`G(Gq#;Hqmfb-gdvjIRR9x>i$% zGVtr%`rv(cLQBk#>+oHr?&bSBRi&G0g^Tw$hs|2Y!m`%dwzD}Pt7BdnvbH_V0on5U zbPgz&*Qawpxr{!Y1HNUnmmKgdqrK#SZyD_+2YkzDFVn*}Onb=zS6yz@6X!6IJfb72{qepbu29F2yNO+4#@$Iw3i(4 zEu+2UfNvS?B?o-VXfM;lH%xoU0oU@{OAaXOGNi5@1P&A1ZaLtqOOiT#ZQ9H9@GYmk zkaMo4_L2j#I_9NlFF7Eq<6K|uB?pwtYcDyVBn=MLUUI<4G1B0x`>t}pw~Y3Z1HNUn zmmKgdqrFTI-!SbZ2VBc*FFByB%aFQu(5AiQfUhn|>hQH`FVn+!JD~=oxy~Z)j56gJ ztxfqb8yD4 zmskhj`J=}dXKC|vGIleXeucfP@2+--1o{u|V~@$AI!@Q&E<2Uq*FTRZ~9JlXjN z2YYpX2kwL~_MCc+Yj)fj%kMMH(aYnh=9s?2FN$xA&!PE!iPhP0y&-aR4!PSyUi^?|#IBjtyCY#xERxmN9C|9hV!T#&<*ENIiMTPqo#*$93GVe&MA0Q z4!Eb_QPaacHjkR#-*C5~7gw`YTF*Ji0o`yOl>@rrJZgIA#^F&p;GBX-<$!w%9yLAO zWAmsSKK|i)R1WBd^Qauq4d+qQLpKhO$^qvTJSqp=Q}C$i;U1euO`pHCj2@K(y5T%3 z2Xw=E)b!Ae!=rM*IR%f(0rwOVjZ>PTXp?=-`b z!#1yTnPym~*TI{3N;5219p!I^swvtwH7;#7WQa9G*A!Em8oEUqOEZ))SGbCpU)`!| zhP3Yap`=+I&T$oMm(EM_LpO}OTm_u%8cQ=KHu0USfV*8|X@!du$#xy}zN!JKZb=>b71E=!WyC9MBEtQPV>=4v)$K z=M+3D2i#NesOjMzn@8n{`3={jazHnnN9BNSIFFhhx^Z|^4mhXaQ90nAf=5jc_t-ot zN6c?HkIDhva2}Ndy5T%(dg#XCQ90n8f=A_mdkP*kF5KOnKxXJ@lG^2@+4sioeLNSM z-A;~1jiTj%{(12h9ZF6CKf9H@N2eC{{W-*Jj?kfI%$Q(~*?ft)oS{?AIbL6{9rVOR z_FOsxCLQ9G`8{-wnH3)ne$hWs#j1yhI=?Hn&@*EPyXGnBIo`c@U6Ia;Po2k`SN#M` zJ;eVHi(eOibXV@;dHcn`6m$I8b!V6N+9$tu-+S7JNV6iDE?dJo42_C5O8m~u0MYN_{>+hYy0A!6TCmd z^Um;;IXWTova22>Jw@|@y2ftjGTll?$&mZ9T7Jk{cg4c1D|J|+XkRAFC@USBj zF^I2W#`PUyz79uT{M$bF>i%rhRyTEjcCdEm*!T9a#@ijvcEjxsJ11=dGdCTE+A7TP z?QMK|AHSctedO!1`*IDPMu?Fw9j@-+dEYpkc>`W(0Hv3cEN=yc>7fydQxay$yiyRIfdC@YBFloDJ)<5J_`H#2|VTu^owc9$hNAu(QL zlKn%K_ z=co8RbzJzc_zj*z&eZlD<^PY3-?m)H9cxChLHv-@Ag+v+wwZ?mecHZ0qHw%9j?!b(;CCw zLBpf2_HTf33;VQzwYlZ^hm8`hi*?6qMc^~nub(&}()E&5a%$^PJUl1Nz#D!RztLS)KHV&;mV#?Z0=q&x`^8 zOf`>T74npf@w>qbAGpON2w2<8INN885>N$);=f0i9G2lm&g#k_^)TP$DS&$mhne}yb4(s&B(8vksb zQ`w*DXW~8Nv9~#RgBVe%dV_3EP5ZU@&Vc8!f5k`K3AvBn#;4b$`SIz$e}yN+GwCx< zbYD;IDoHFVkJbRD!N(R1%(DzK1zn%;I8B z*X>Kaqka$b2zhp!kAyM5!t{nV&bP5N=WFv>*E!!9dWEg1&3!dEC9{gFkTuap;CGBU z595?gcZyRkipBP)^_cI?L3PdX*}%`^JF2))=4-?DYS9zBp%bU{+$gM6e@=O4X-?S| z5&1cBO4h|!ak-0A)}!Ud{Y}o6b05k)wti-D%iUru8!StKZqip{f?OxZi&O5Ac{-<*VIP9p6#i?=tUd+YfQS z+}y7kLko807W^Bm&7;5RRi{0@xip__i_iX?_#~_Tt8^niY5vMK4wRBD9P_5K0-_i|GHHxF7oo*j}3!BJL;dSGDA&C4PiB z%7e?_D$N85ROXnLZ?Gti!rTqUT3AoSiZ6R|(AT^4L)LbA+VvGYjL97$IvT3G+P<~= zuBPwPqSN&|4SxU49F|RpM=y#mGZLxFEp|?@m5X(j_Q*hrE@pDQT?;E`U;Ano;uR}k zc9ECEh~Oc90!}r3WB644E)AEecL|d`7fy-LFXqpyfJr`YjhSi8Z8-!+F;c{C8Ud#k zUt`$SepMQtwckG!sI5ZlUB~%7;lru zU?$u??onlIKX2QV{MFO;uH*TyFS%`?i1zP|8k(<2qlD&rMFpx4&sQJrwO8sFrY#5T zf9v#)^5=&2@i%GM9^WG@zX~ib_XWh75I>z>2P)fkAHl-<4Bb@NG3d#q zuimhk7M<5Kc#r>&e`DNUbX6JC+pbH;`?e>D3Pc5cyMd%r0c}QhzvF9+`PFaA*k1lF z9mC6a39E(GQ(`qO0@fE*`8j)sl)s6wI(*j$tHWKw>i$?wJNeXQsk54n{!w=NtgdAF zs$j9xN@OISU1mQ*FVtI?zw885?cTt8z+L=szg{o2vBOniEN}C(&lm5nz8bti^BJ0Z z6TE!ur+t}Uw4X22(^@RE?qVnH*Qypwb7PGQb1+y(Ne|5~7uRQ2!#BD9?Bf!&ldAzq1J&$~s;9odHHx zUNf2&G){IhuFjqs>}$;4I?Hp`flFJDc;6Lu51Qw9ZasI=UzYtPjLJg~&j2O6@ol=% zeOGPP7!sBML5OfMyTQKq+Oui8&7X&7_*e~V;(WC!E1Jt%%GM1DDk+`%<_i*@j|eC#;NXApCE+5qc`@8R7hs*BmN(QwG_ zXHVfi&l3GurC)g{|U$|DVOz z(I3UV^}204_LQFMn}`|Fb83dQVF%SG-JUhjG;@wCQ}6?p><)xNKj6+`HuK zzqCt-;O=!vJe92LOH16PX6e(8NgpOH)%y~*uRv~EVrSs0CjIl|c=uPBmVEzaalAuV z6sybed{+kT(jjcV)!wC_k6fZ%7WN|eNZ4mEWc7wDU9TC^4(@+f`RvD=&g%8Cp!oF1 zKf+GkhaK`7Rw{i!-X^7=<`&M6v};2o$$w&Ai|4q@KQ+Z~;cYxhTl4=t#jNc_BIbwr z(-Om6z3dC4(_;|2BZfO@M};TVt*P_U{F!mho}(}EBwFb72-uk^_4DoGJAEuM?aml# z`VGeFb!vWt@(A=eF+SqG4e`lHeieDeqWJSBcI7TSKlDMFhc0|pwZZ*(J6OHgBiF3G zcz+mqak*pdu;@YEKT0i)^R8B|bz8{n;z&E3G+_P`o~RmD)+nI)WL2KHN;+$!q6dzK z9$uc%O3a?&oYrG_gnVx(dK_afHTx|7i0{2u>k+Cnc?Eq=*YFMf`t-8hWqU zHQHzPfA2me)Vp|Md3N51J;S^RIje9UwR)+`_i?w%_k4pp<1^)|^C)u$e{z+tLE-tR zWh!p>nbxn2y@d2jbI+>R8HX(6#TZ8@e%uE2@6IIGedWTPI+q?-tJfo!`6Neu9~@L+jQ;7;TljT%J2j zXPu_6NaZ~L#|r&;y0;bgR387g+I#X9y5^EY5LZ41{xN27fPMNK_m`6UhTDO+_?Ft( zHujEk;>2N^=Xmx$o;N?`Q~CQ4*NaY>>9-Da%1EoHw?({Uz37xYW8G=>JM7CYc7_>& z)I;7Q`;XN11fNjC{(#R;orb`ZK$)q;p5%=0&EONE{l=49e~)ulMZ+JutbO6Q^m6pu zmtLxxR?sEdv<+f!xN3ZjLwNq7@ zgujP0nn7Ou(}h&x_h&Anh90e{sFhl|>8u|^e!j$5Cr*=%_19QqHH$P}TkqkRI}1H@ zNT6@(1fGv=jKgz~Pr=pvc|%*clGYu)DMuBXw_7JJTXXH)waPaiWBdbWO}1NUroHiA zZ<}+T?cG?2W!;{uZOpSR|Jp{ZW?oYx{`TK_{}w%RN6xY^TcSE^d&+9SJu7}Wo53;) zI8~=!o5>H4CyEoriQ?Ep+dPC#c^8YbPH1byvHN!2Atjz;kSGG~E3}7tyVA2OtFip$ z_D}IR)@d>qmt6~n?w)*=@>QnV;i5QE+%mF4@i@if+GT#Xw^=f->C6PvW1BQ;QJg4F z6qnP>E{YSyiQ+_Y{=~RNvRM&uMZi-nZ^I+`DwnZ8MRB4yQCv>hEQ%AwiQ+_Y`7I*l zoG9l+IVZ|FQO=3)Z=vYG9=erZU(m@iC1*$xa7DnE@jxg#py)t;U08XQ*57eaug=x- zvC4BI&xt%I@|@(C7V@0Pb0W`)JSXy;$a7LYTdrLa$#cS!Mf>nfWil(1xx4O26t|Of z?nO#(C{dg!P88=?pk7Hmh3`ugCyEoriQ?wy+7M1kpMuknpAF+SipQ1h7TIyK;}~=3 zuEZ6^ZU0P9BvW)i(SbgmuHl?Q5pYGo6#-WSyxj}ht)~pL3MAts<0Ru00apZE5pYGo zuV40Tr7n_k4tVrfw06$0;7Cc%0&K`Sml!;}nm}Bbz1TB;zFGB;zFGj*4TPET;&#BH)UED*`@d zMW$rLbKv2Vl?m2i{u&NHE&U$ zb%g#c%bZZ62)H8Pih$?ThDC9rI8mG^F24^#d6mkm%oEj+jFXI$jFXI$j8k4^S5B$o zaf-*~=M&2EQkIvpyp-jY#~zZ5lZ=y$%V`gZ;zV(xI8mIkyta@dkW$;J=zyXFd9-0g z2NWGpbRef}7R8C;L~)|H{1%b4N@B{XLR#l5vu8l5vu8)(J;v>$LaOmakI2$~>Gx5pYGo6#-WSJikRG z87CPh8JE){62*z)L~)`xMZnuFZ$$?b9muZ>D>|U)fT9CAC9^0_6eo%k#pSVwq*Y3* zlvbJ3%Pxu&#fjoXaq4rTJ}2dKxY~Kb<3iDaJle2wPLy+^oRgfgSrjLV6UB+*+O?k- z#R1OE+rz1)ZD;8XJ8e`sC(b#HJ;~-C)!)(9`)!`=!!e; zjQe>Ztun2Xv~o_AbE2G+oRV1-CyEoriQ@9uL&`Z(&PjeWzTSSs^l5vu8IV~bloG4BdCyG7R8C;L~)|HJob>ZN@aZr<0RuG<0RuG<0RuG<5o*HE3Z;{mCCEkDVs%cqBv2UC@#N6q`XSyRpyB!O2$dX zNybUWNye#{S63Fdq63N!f$c))4jkj$g`MK4xQ5jjmdz{Ai99FroXB$`&xuJ@b%<^6Q=^;{<(%Z< z6v{bK&WUnPa(aA3aiTa;oG328pIus|v`T4}IeieKI8mG^P88Rb&8z5uq63N!&my0uTs9s{Cq+Ya7Dls0apY(k3A$ACmAOhm(v~+#fjoXaiTayz;%9{&X2RM zBjg9C#UB2i6<+s0##v&+tN@OKeJ9} z4$}9Ifb&kl;x!?ube(sQJg4F6eo&nw>PHpL8x}1+q*2SQd;GB zUO!QsC@xQSnzTx3mC`DuRZ6Q=wT`NFju82Y<5KN(krLgZe{~AWU|3{JTBWo~X_dn= z-b8Vhm8S@}&qkbruPYuGyhx%rQCzHxiQ*2B1MM^FrdSJ6oG4Bdr`iE!GB;;%57*9A zJD}Quc2Ck&aeMVSF?qhIs%#2PYB;A*JWlaA#p4u@%P%by9Z+;Y(E&vVx}w0+Dy3Db zdtOdHA&L{liQ+_Yd9*Y6D&?!pZ+%L}NybUWNybUWSv=wmI!f)Llhl^$Yv;Y<6JtP?? z87CQ+(;gDViQ+_YqBxx&r}N{=XOy(_gp^)T7S||U)Kz?0V(E&vV6dlMZnMHA;I8mG^ zE{{DVtx{U0w91@bc2S%tP827K>&~@M1Y8ktMZj}%3Q?RWP827K%dej)0V? zoMfD2oMfD2oX#ES%D0iPQohRkd_oa$MZgsSR|GtdJtP??87CQ+(;gDViQ+_YqBups zw~90$grWnA4&>2>6&+A?K+%DmvRM=-iW9|&;__QW(ki7@N~_H2XBWkZ;zV(xxURel zMZgsSR|GsKpAf}~;zV(xxIEgKBH)UE=lAzW#!1FW#!1FW#_6Pw?%W&sD&?!p!zmO2 zR|H%Ua7DoLTSSs^l5vu8IV~bloG4BdCyG-9Tqk{;7w?P1Vy}2qTrb*nzsE&4$NW|C zi^6<5)T2-F)Scq2@N{;JDjQLpC{7e7io3o-d_wU!#p4u@%PE;faiTa;oG31j2SQn1 z%JOQrYhM%x&_(xPrOt|{czuW0XT>o-+kw4$t=KMhaRvGHAwD73O6wIN87CPh87CPh z8D}2BH{heY;ILcZqlfspUVI8(`^(v^_!vC(rQ@;N_~c=6)4eDE{S^NhADQ8uJSXy; zjOkgX$9kB2msTmQQd(usY$;KkC{7e7itEmqmsY7vW@R$xd2h@WHSLFRZ6Q=mY1@;l;vfXqq4l(>l@{(l&>-mr;z7Fo)dXai>H<*UrkClmo!1Y8ktMZoje zLy~claguR4?IBT|C{7e7ic&m-O1Y8ktMZk0N2~nIVP827K%cGqs0a2K**LQe*RvhEA9oVbaitS<- zSCC&H;uCVMv|bUCaguS8aguS8apnNtcS^WX_e9{rB&w4mJ-E@;zV(xxbB>JX_d-k zRwi>!P9cgD#fjoXaryN#Wiof?<(UVL_&HWio;)Y=RaQN;#EIBPI|b$q^VcaJXMXfW zKJ_W~YdEKnRw=DgTBWo~X_d-3>8hJhbU@L8{Cq-MrL;1i%1kFiW9|&;<`NK@>R-LDPLtyJ|T(|#fjoX zae1^eMZgsS&+qS%jFXI$jFXI$j8g=>yE0e4O8F}Da0*4h6#-WSToLg67LjC}WSnGN zPK!tsCyEoriQ*IiZ_hnfbU@L8{JOBB1BwnPI*?N`i{eCaqBv1p9(zbyrL;ToLd*9v{g#$vDY4$vDY4^zRLW3LJ@F9z!d>k1U!#DBpD|eCmEO19umcg;zV(xI7Ps>iZmaDq63N!@jGDy3CQtIX+V7sZLk1Ux675XFh& zL~)|HJldHe;EI6f_xDJ~NybUWNybUW>7MfYH( z&WfjaeTUa)#W6nHfxUXI*e-T)1^M+MJ|Wji>lGmxCmAOhCmAOhXCA>f;G?_Xuv_4x zhxoZ(d7(Df*&}^%R;f&8WisdF6rwm$oG4BdmtQ|qCUbXQo_XMipJV0Z$#WuK zWz|DVoQQq2Q()dOf1ToS=0{)TQ=ekLhI0yOmC`DuRZ6RrR;iqmuDS_D2NWI1&nKi+ zN~=_sm$JN+0h(vLsI8mG^ zuFFF%U!{DN@>S;K6QVd#oG4Bdmq$BO1Y8mD{Qe%vILSE4ILSE4I7Ps_D|6+ml&>-m zr%(i35pYGo6#>t05lO~L#!1HIw1`A;qBv2UC{7XZ_S|zt2NWI1uL~uV@sW&^jFXI$jFXI0Pv)+C8~G~btIW?Q6aiNRToG_Z!1LHcl5vu8l5sihAyJ$t zP827KQv`ggNb^A`I-ux49&K3B0YwKC9mpx0MRB4yQJg3)zeOaiQd*_7%A9_7QJg4F z6eo)7%DYemToG_Zz;p5mQJg4F6eo(yqn#-Nt_XO3e~)CGWSnH2WSnH2PWtH1y^*g{ zzREnDLJ@F9z!d>k1U$b*BpD|eCmEO1A`-=k;zV(xI7Ps9(#Lu6zBnxQibuuuqFwiU zTy%5HUlqS7%%?*=`V>#yDb5N{XUC|r5ygq(L~)|H>np@36pvFpPVu;$l35fdiW9|& z;_`SPl;x!?uXelkMR5RKbPrbQtaysocX)kP9OJVc*sIry?P3>KkY69-6LPJzUJ;UU zl5vu8l5vu8<`H}YKDrAIy9GXah@b1lr{J}}oXv`l!Bby49=nZC9u_yHe%d5S^C7 zll&HuWSnH2WL!>*NE9cE6UB+*x;*6aRmxW>Uu8}{A&L{liQ+_Yd9*V{z!d?{@9&X} zlZ=y$lZ=y$Qv|%bGFQGz`6}~p3Pr#b0apZE5%ByLkz|}?oMc>1i%1kFiW9|&;uHaI z&plUkK+%Exy0D@HiVi3`kW(^?;zV(xI8j_4dq`TPv`T4}Ilb(nI8mG^P88RjYoQ3Z zBH)UE=j0TkI8mG^P8644KT`x;5%4@7AIUh$ILSE4ILSEmWbVqhk*`v|%KUsn5pYGo z6#-WSJdZsj87CPh8JE)@62*z)L~)`xMZmX;G#`Yb1Bwph(S{WrP;@}ift<2g6eo%k z#fjqbTSU?-rBzC+%;{$r#fjoXaiX}cybDFZ6#-WSJSU$J#fjoXaiX|9+Lt|08~G~btIWeG6aiNRToG_Z!1G%~l5vu8l5sgLB2k0$d^*&lPw~{9;;is=c8n?;QJg4F6eo(i zzCwIL@i@if6pza(nMHA;I8mG^E{_L7SzgNWYPV}&6bH~n_h6;Yil=yehu3GtF+SUY zy?U+KE_QJR`Sl?_A=gUl6(JcX87CPh87CQM9>F)@qr2d+Ti~OI__b#WtO9| zyxQv<<*SshG7qPa=R}?pc~0ax$!`%!#!1FW#^tn#L~)`xQJg5Q%R??-rF@n0Rp#Uq zqBv2UC{7fYM>|slToLg6{vOFV$vDY4$vDY4MZmi&bLFd)uQCs(Py}2Na7Dls0ncv{ zNybUWNyg>0h(vLsI8mG^P7(0-+;c?-6dlN~3oAOH=zyXFIVH0wP827K6UF7Rhon_X ztCUum)5|W36UB+*L~-4@7K(r?08@aB zQ~vVAGIpi?5qE{p>Ytq8bhB6P9LY2E$$eCOgTKc(b@CWpnR(vi;e_X%S#~1nA*Ba2 z=W(r=>U7NZh;8aAZwB8^@#f;R&TGYQu%7Hmd{)fyyN7um6#F>Av+vxOn>Qh|5u3Up z{lEXazB;_l<|}tk=1#}`t`}+MSB0sBa#+u7Vd{b7%I%z`OzWwfbvf>`h_keFRblFT zNY_2c+-c6w98P08?=(K;_2+=8|9&+*0`!et{i z>22-YHC1Qju1ui?OuOU4RpIJ*G%8%3!(weZ34K}HN__R$c~RC0R~Ksn+|k&+H2IWA zBHC#E@U;$gyH$KuoRu&Rvx)O*0ff9Y$D^bu^C?SXtncv?M8aBQn;_3%{Ef8FZVB>hiZgl%yYMACl`t3=Ixj`-s-B9g=M zk;$>7rS25WXHPo;Pg-hM#A*uK6rP^Atd4$oD(Nrj-phjxAzEjF?-HW%BqcW70o%Wdg*d^yJ}~cTW43k1gxj*C5A z?&@v8#WBCfh^K(;2aLUowfv}fQar%#9sJ%xN^h<5-nt68>cpM=Vm_prXs z0qGonxdw;0_ZZ`CUBG!8@O)C-E!D!rbDaaeL)^OsIJh#ime=d}<_%!suD!wa@tVxs zT0L^}*oD_N?1}CUiThQot5Sno^^=1 z(L)hmdHn**W`KrJ?cz1;Uv*wTy7e(!J;#`=<%<0t;qL10$7|iS#@iQrHfzM1IYvDw z{_PSUe#E;|hdXr)n*+*YcRg`~afo^G6V_^T0aiBML%*iKCtfvQ;nqdRw!(or7uUcA ztl7uFYmo!Cac0tXQD|5#yj~!>8U+}IuIC6QV$Q{!0+~&GExPGs=2Wk&kMF`t5 z{Vry|Sx{=7V1=fUNKLp-sFuffa(G|ma{{cVJn%XNciZ#7cxP8t9&t7JV{$3pufCWc zq%ySvY9XIHSwIS)tf&0=3OGK8j!<1655rYrbBwuMm3TE+H~kY}FH7I6#9~621CtkX zv5khETy<e3y&}dKV$FpIF+Tx+fk$gFkb+X;seIU43On zxQ|q6R!n|9sZMQ#EYMa}FOF$3TvyeA<5e8fvayx3*C1V%qrzsJZH|3kR{L&V<7IU6 znbYz5Nj_VzRj|mKS7df!)3wnUXJ8UCg56w~Ei;7r%?2CkcLt zb{Rw{`BT+7o4m?x(y5EP`VrOv^9gA>_Va3^fLPP7;`;64KDdM zKA_mc&kla>UB&_1R>gl#oBk9Lvpvj*I>Vowh0opo9{-hhzluFgd;0)8YyR2AtNss| z-yV2$H+P%?GFEw?0rU4RSDF;XSm1lC(hryc<1s#p=DX`vqu4hwPtK+s8!o>$9OpHm zgW}?~BmKwS6;rNfJg-Yr;dA(GMh3gD^;eoSPQAVxiZlrNjP9>pJaYG_sUvocws@qJ zQFx7)0L`nu2!i&}yGCw%YV#8pJ&oTr!QV7O)6@Iw6}QplEM6;<;wgIU6!Ev%x7swq z7@oCdd}!76GM!^_j*9UjuCMWiF5Tfp>B_QSG|oj?CQn5%KkmlQJLYFvaC3~C`eBUm zUK(C47T5KZSkqOkuW2_op#9eO(pzp*=6Ez&(A~LK#xV`wmdgqm9_?%P7<&tn@wdg1 za;|u=*{WK5nXAvCT`~%(n4!;`tgcn?AXRs@t;Ww;gadKIDsIU@w^YobV;m&&V?Yh1Mx4SVf%b?J)`t`?0EqMUTr z&K3Rcaqp(o|GIF8P!NVx4R1WD;OEcLQ#|>xjnV9{|Fg^ZqD8q6Z>aZZn>Vwa-+4IV z=NpEMSuJ1IltQN*Pamu_VTFXvi`q``A9ulS(3VH=kqp*~SWlj|k-S`Q%fs`lcmSGt z4NNJIKu<^)WM$g-{tk=((7*l@p5TA}ggv7_pRp;c+A;j7zn+0&UbRFYUO60Kwk&l~ z_H^j|2Fa8{maib@Pr+Fdk0rC2J#X+{Ab|)>!cZ<1EcM1 zgz_%bEth(4!(b_GBYqI-g0=w94_KjN#BRe*Z6RX9Z1fZCPwWw_?*w^iJ+n95&q}04 zK90NizFXhu!m@G(=C#sZ{mwo6r1)ot340jpE%tK{kw)81AJ@5wUG;IjMfRdmSt?KH zg1Wn=+S6VPT{%)yeqWwJTGXb=v)#1AP2TS2>-tKvx(B@Nxl>7}u02ZiG;B8dcH-Hr zww6X%0}ogQYsgm5=q@F1YB6U_(S=sSBiDtOT$?E}L^eu##|)B+`68Ar5+d61H`V&1 zR8N}iuf3*akZfY+i!(@4Xpv(M(K}fQ%~~9u4p5e(x1Bcd7m$~Rt&GK=Lt@+Yl-;ZX zJ%mP_Y(?U<_6!@k(C8b*`cIzbE-S(V|ZKp>u zYlT|k{6h9yt@#!{xq)@`SReK?tkw7Kz9YA@ud$n~**0CB9OkRyS@8wVi%eO?XLuH? ze@_7ovpW7Bcr-&U-9I^en&C;*IDY`d{GO7yEa&Zg8g7t&ZB{9;4acAEJ!DTEuD(C{ zF$Ef&_AC?{D#(xCY-B!&Y~GT21vHX1G{WO`%86 z+xmM*+ogBt5fWnK-T0lNW5oH)T@b87#`EtW!I||tD;`6~I>g!3<4axb9doFwr+uej zT)PhMJ!9to`WVlD=``bQrz6|vRed?lFD8m>Kbvj&T{G*5x$MWzH~b#d#~J{$gZA(# zIcKv)#4CeEbVKxtb)rRUeuk>8Z`roNevNJYR6Bn8oe!K<^y>Teti!JT9=PStNn!ki z9o-nKWM$Rt0_(oVJJPbRPT^JL_l!ESgC658Z}H1W9DQ!fR~T8v&<#BQ4BnT!@M~}- zsWZ-9WakK@Fjg00evC}`3dWm&h*z`X?6-KrBh036Jn&;Yi*-%gcn*7aG3NIGzx1B& zivCh{E^Bu3A1CTe7f7j(Q_pUq#U!ybycWv#s#PL%Wr*1ISLp+}Q>#^JS~0WUrpPYrl0Qa?T{*$`&6p@w`xEEXde+RvRmg1LKWp*{D4(GcY*W+T$*WymZ`;h`e z>~{<+8Fp*~TAoGwQg$pnqrMx=Dx)Rt^1VV~NvT!By5CQ#H3wk~Ft|6~SdV>^)cAbn~mI67J?x z>z}7(GA54fgq-EBTBGhY>dq=%oSB+}Z9^!OCkWW=S6u^5vE$0I%#dqdjkNh*{9BN9 z?EOrNpH;d?^~-oCt=cMhdh$MDPqOj*YbY4 zsUR(C7xWohQ|c=8)GU8KG9ixry=5(-{N83o&8?rNkdhzbcVo&vGELn>Os14yz4zxT zy*ZoNw1j3pKAuicJq4h=&h}pNyr~Min|By52vVx8^InzP56i3QukEgrER8M8Snt`2 z{554y&T8abKY%1#?8ix=L(=0zm&;m}O033V=QVn-OoCeRd0r)0 z0-pLGI&Gs%i?71d?ukgT_`4~~I1^uu$}EDl1&D9q^N=sjo{5L>RUX62+P<(&<}TVr zO^1E=>|ShaQuDYkZ8=n-%{V>vtP* zx*Lf1y#*$gb&vARc62WT)0<`3aCNwvyI|!L2I+(IqqX$>T|sM???sKA)!hoZ$N1; zh0DU_R$Ts~)+N0kx7-JoGUCjb9qr67z=v65YFNzd;qs?GzvN4IE&H{z|A{OqX&G(2 z_7AYOpX0Y5R3W+2~93KA>)2Revwhs#)vH_5$!L zVBViNPPHhXHfdmuBPjGyyr@`@BL#VP{YGUP{|pM01#4Lo6*__m8#KEN8WW0`6i;uEikhpK7t zo?ai-w!Eossdx2J@OvLj6r7zCQ&wDgZ9cL`-p|MxPoM7Q`4*v596XNcs@I%&Y&M2!BO}`dIHV!=Pgk_ll8COV*TDd@f|F+RNqOu zy`j8$(p2BP`THM`F3@ylP|Ugg3Yo4(8_1ssbA}9?Z-BqYh(IzvLl46tEUj>5IoEcX zld!sJY5jBD%WGBd(o7E3y$by?`NPSHE9btIbK+J<4@f!9Hia6c2Ta*ulid^zN<({W;YqYa(-BLu<1xpPxf6vXcqVIHr&G6j~-TAy|#w&Cj_; zL6%DDPGNzYwH{|!hkBsqiUh0k>8?yjIj^7_6Nc!h>m=FJD#v_Bp4Xrv-z#Vr(W{Tp z{rCZX@8Fj+j`xw>mRV_P{h4jws;?>gXf}K}9b-A__FUCG2x%wMR`qiGKL@Ai);k9ha>~rG!aa4PU8o4Z6-AcF(*U ze*)bw63&xvULu-9+GBKQ6V%53Rrld7;R!aph9~0O#w+_`J-`p^0Qb<5Ace1SuKjg^ ztKn^gwVxN$X2-Z<3Xh9%%4%Aw+{*r^AG6LA=gy<_Z`c7}$Hm;W(6z@d z=si^jPN$h8lV}V3%_`G2IO_Mjzq}{Sp7ju|4tFCw>%ieWoU6~}2xm8^OXVYc+B)$P z!rPyp*erdn0=f4&{K(Z4cv84ckjK?idaHaWO_C5Y<4tX^T_=3eHcE+3`my}q)#49? zX8k?;t^k@eG^oG`dKd1w|O_$LpQl z*3=wYMjr{_pC4kg%UMo*v7z zbbBp@>-2|eQO3Y9j9*1wM*Ot(pMswmRZhdxQnGyrLHyHfKZR;|W+9kO)_iT&>hc_|+Jewx=Xd)DKL|J!V@Uaf804PV`!Uf#|vk2)4_ zUXGFpk?~;Plg`d4k29}hoLQWiu{=a^1$cYJsXvEa9ya5=fvVg6j&^Oldg)%o<)Ixv z_EE-Rd;btP#CVWpS+SDDK4aG!&j08l+IS5Z7j~2pNS47na^%+;>p(*-dxYy@uv2#E3wZ>SN zSQ0Ml^}7wJv77~NYqvVu7$I6cjf_yOvQ|d;Oxs!y&5RJ|(at#1YI93M=<`$Zb4**E zRrEv>Hv38UN^XqA6K!S2s3saicKDT8P2Nb@()nXOSGr!4GTw^yx01U#>3GnwU;ZaJ z%X+N-8b&XRUsssN-+Sr}_2Cr#>FSEZeLi%?14eExIA^xJSn9Sat(aR0MyyI{BP z`(joKHjIgV-rv%OS*g7V`ktq2tJC#5MK`K(yb}hw?e8M)>(94)cBxs_4V!%b#O@bJUGnH90xyn0p`kpYpT|j`cY@rhf}vj6KtRB&F{O z@MFT)7xNZji}<&3ocMJd{+-&-Egrl5Kk@DMwejDGZXZR1F?)r_;mk~LshwHHPIn8!G) zW}XAZpz9dE`Z1TQjJFuqOv%t`%BY?$f;djRXB_(K(@*cN%ak*p$ynpZ94O{9Jk6QC z`PhM-xlLn6xl*j}MSdaUOu3^WeJwZk_VDrXkP8yD?~pq^)_zik9AVdZhBi-c`w4&J zSo9XYXGd0^^VW3r3=!<$iyaFt+pieI*q4OouXRD>JCKg&_pR~(|9s;2Ll@_IjkPI5 zTCWhG-|+Tmo>Cvfy;l4Q`^EE7`ST}0!ah(NsLQ)H+DK>c@4j-m>u<2~=kUOiwr}F+ zEj}lu(*sNlWvtSl5O%};{}$Ky{)W4l`=;x3$gYR4uu`7@Qm)7?+`-<6`}nv{!am-ycj-Oc!~gmHD|~+o zam5>eoTto>xiaU7$MV#PN8ohj-LH3|-v)#{Uy&zY@JzHVTyJsr@vxL9V;o?P+^H>$ z!=B2=pypUlBp%+ts@%u#3Gjz}W(TkHj_a1IDlO|nmV3}#8+RA9)SVeP7N041h`v_B zz27+)PKtlNQ|FiWT3-YPg*w4t$za++#-`i|FE{*9S8`rC0exdFz^<_$LfA66i*LyYQjQz95 znC;jz9cz~3%y7)v@mapN_j2CMF;-~#)fsDLmYvOVGZ|wR%gkUn^vgod`-fuV&>0V# z?J_eR0%?CJheFsFx_*!ifr|I^!HPaJNQb^Jjh{Z+X_rZurr&ev1wRJmWkYFzYVw$o}vCc5q0t`0IO_%>zT zTY9V@#ZL22OZ6A`;Sy!POz<1V9?rS*lbpb3!gCp!P0DJx;E82@KtB&>l{a;rh?J)9 zrue|Cby#h=v8-wKmZ@2wDf<-L$|1Kgbh9b@f{o_J^H&h!kKxCA>AWu6@V}I8>GFG< zRX@8rRZf!Aq{>RW(ztf_Uh~PRIz}qQsnGV9?DRROP;MWp?MpvhxSKA=A0)|f$zbpA zqxLb)DeuNRVoV6}uP%<-g%K$}<}MkWf-CDLgSXxJ+98U-?nImTVRd5)m3z+Ud+w&h z^5gyO>WI+=T`D)6o_})%x;XumJo$FgZmk1P-hh1RT1ii3CShe4{akr+8m@>ZlfSbg z9pl5S&W`nZ@#OBf&k#L%V|1R}oC)_1GW-C0yNB3*buVej)=zdVp962XEnON^s!qLu ze1jDJ?Jb@eG)mg69zPjz_jx7VJ0clir&pHG4ob-`FZWtE52n`Dy0{nN2%Y9)E?Ljsy9OS{96R5MHI|lfb``I(j)7(0W7DZ#sW4vMS%WFu zgX`FYNpolw2Sxo%-R5iS{ie(3H>KXg%(}Ey_4PPBSEbt*pN7@z!%?_n{XFix!)(QX z@6(>2+Qn{f;qrC~pJPA7i`CG53?i#^Y|?>ZO{YtrsmBDmEsJ!1M|eZG zM0;`!b$WatMeg^5ZBbTxf4s}VLHfrR~? z$XB!Uhp+x@W_K{x!}u?`#Szw;J-bfvjXz=b9HX)l=@7OA@sCxFJlTVh&Nr@Frt3NW zd9;0eRg`~L{~36G`U5IXj#|bID{1dS)nH6Jshly@;w#h8KGy0O>%*!egJWFFsyy2C znpOXuYNCemc%$*DsWh#A8jEJuBgdVMG0V z=dzwNL(Q}0lg=UysQk@vOyFvy^xQ6MlI2KSRhzWF0A7divAI+~tH;gq-||SDW9T7U z9oP8dxcQ?Gp{Wer)i=-ssd3ZuS*?dZaNiwaXIT}0+hGwSnY3u;u4?$mX_9-mg8Yc} z@wA+Lr7Ta0;??ZL{#!iZ5wQ6l^x{6X^B?0`Z?W^+c+M`Ka2I*YJNO|itb@OgpKuN9 z)_v9deO$ALA6~mm?*MXTYVUiP7gy*{7dg~Nn3J!TwyfOhP6rIz#ob&Tt_wABYS87p z?V&ptM)(0whr)9)%PD&U{4CS7%Hv{b;o|j2J64&zoh&i!$gY`Jz2zDRsEPi|L zcr|-Ua4*>9o?}vu?&3dsQ%-?5bKou`YRh(SAdDU>Uqs__-92PHAFNzY z$Apl*QbHd9pJ8s8?f=_xe65_1UVa~6yG+e@pM1wM54QKI8Hjd${Oa#EYkH^^K}_h* zm5fKW|4izSpJ_T&`pPQmlM!zFSbjCBFRQ4$DvRFRiha0N(Ke(*laFbb{2e#aSKb-f zV6wpsA7q2g&~JPXy3!22$Ni}oN6=!uj{S47!KlaH#wzT=_PPx&wg)>*HrRUFV4r+& zHrPAhBWr1Wws<}p?7L`O*y zho&ziygqfeQz1@;wtp@jPb5t7b@0hk)naxV8XK#vtpCSnE>oE{)K~b7^|L9INLiO7W3*g-msZ{A;}g_~%T-G}ao+b(3l*%}+^_k=L+z2jSa!u8^PTX=U` z{Ehp|4y{(v$SS|)Zz#2WRn+j)JYzl))-&`Oqy)E&f@Sex@tzPv7`b0%yqMy2lvHib z^Rx8Yu2ij#n8~N6XFU4ryKSRX2>Q!n*53v$8DcrZvwuu-PEq&P#YNIJ&^xXQ(yAR7 z$Iynz=@faHx4yhvLX@?^PVYs=zGYsxdk{po;24p^9=HC|6#kIFwfcZJJ4EQL87oa{w^S958n;Q z@eRCVmk3{}%+pcW6M%bh4?D<=dR})I|J}#k_ppb5M*VWi+4Hf4i+8$8A&bwHk9D=? zv*7(s`7_|VsGicldPaP>pWU8J|BWlbJr-s}sv_=3-(t+P+{`k+V0y)VAOypCZ}(n2KXKXmpn`*~2qD9a_^E1zBk`p`UY zVo#7G$h-KvShJ}2*!R*T=B2Sb485JUAYC6o?gs6s3{z9D{koUWxO~vZ+xu6>P}!aF zjDjw<7^{YLM(j^{<9h(xy?aKf@qWeYW4dIO%IyCx9byg*tjUwcvCSI13M`IsgLZGc z3Qd~RRbnq8%z?p+H9}?(#N3E*(Yj~+x4wqH=W3u;dYNb|5v!VPYew%+-A>qb9($Xv z?PrG@uBX`EO)_H(P`97Y)WtjM*k+bi=(hB^vjs^N-XD5;>4|PTv9hn^@O$NVYqe;P zkOetWJ)t6|%y1pO*?mrK86r)Zc5b|m=8SvzPIBy3Oiw($33E`uvieCg+~)gl9<_d& z3r}V-ttG`0Y~l^8!XKJfB;^c+KD?u^^lV$PRi)CaqSUtC3sNyinRbnESqa(>#c~_@`X|VB=273r-&^oIKX9ICzTZS|A**!Vg{`#X zdcN-A9Y5u{i0nnQ56}BzoLmhpeDT_(auV)TAF11<&s1aXbw3h){JvxK%=!BlzwbVk zDm})Qa-Pvp?cVbM|CejHx_pW-t{$%DcP?x%!D&| zjhQ@hvhN5ygn8@Lxm(Vu&tkAMo=D$zM}Le9YZqrD4yzp50|u9~dHZpy>U^832Lcu@ zTRSjTElGLLjeb+J61%ewt92#iTq#l>4lsj676eM zX2sXQOIF|z^LD`tX2oOR>LFgkc&vzF4UMn0VBHF@WM*2N1vx!#j8$3EcLlq5F|I_J z0!#YB>?LhmwbIyCDPlS+yHG2JFl>tM~5+|tC=hBVJh}~49Uda z^(V;xAxBs)N4g9F->*L=g-oZkx=iL>v4-Szgn@l&Kh^*P?u0xPN!gH*OltoYxjLsE zk-#c;Qk(bHm_E~%dfqO6ysV_uq$a!7ASt;&+UH;m<6~+J-&*XvBlqD zZ&`6PE55;=^Mpj6wmB=FyM5(3Gw1G_=g`}Dw&NaNSylYJ_zths!}wFxpiG+@pW3B2 z)oHiwlT^tkX-E5%=kG4tgjw;zICZ z1TCkoA@}Jb(AReB3vstCS@j51J53BZJGO;3K;S=r5+S_;OOxlms$S#^uB>ZM|)`5HM~kp12#IK!)1LbQ6=#fE>6oYu>XN%qyLdkp(XkG{~Q zNt^MdM_)MmN}DmHN7+YHesBAcUejKtJie!X&{Wx6y{_qh-aF(Ba(`c6o6g^5aooNU ziD!Qf{e!&{9)Y`+v8kT_<+OJ>j@JOn`hdN!^2)wkqR*Oj z>pGsoVxL4=qba|)84S~IR#$c})7zy?FHP^4k@Ac4)u)l{>+2;8cN*vGzw1LZ=P+(xi2Z28pyjyP-4d3td0RhCtN^qI78bLc;4)cRLm0G-&%knlf_tsHr1%jkb8Clu>xiqE%l6 zLHp=kBey-Z`H733#_yWoZyKTg^tLBAJ+=D8_-Rc~qLi;b$$xeN>9bg4^}eQ*8WsAi z7&E8Wo*unp$Q7PO@z&)5g?gfGe7Xle7Ej#>^)J)_Lp4j?R~^eplg#7!p#6v;2e6zO zQ-5ET*#-}NN$du5;AX~7r*GV)I^kbHj`WqDZqy7(i$-^afE z8hXJGcpkOBQ{2sp4Bq$Ib&ErLG2((+!FceMPu?ctX5F0}1k_t_LxOz^uxj84Od zcz1oSXQ&yq-DP~I`YCy>jn=0MJBO!bk>|uAe*E#v8W zF_dv$KTpT8U#`^)XmG67Dd)1Wn;FlI`$MX=m}dZ1Jf&DOskZdS=1I`fm*L zUBGO=et+Z0r_ZD$bV0xMJLDlQW7F9A!1TEI3b)@vo8>u-_kc}|@Nc?z?2z~h*Dw=+ zxp|E6KfwR{_`T&YBjopb{>Ag@d3q0@@CknSf4HVC2RK~u3Q+KrAf5|!7k_#B4WHI` zZ>m+z)jb*q`^$T?c-PstoYh3st*Om@h2PhhBXcep$s-p3*4crvW^VKFSW>RrOnG0; zIUgH;n)8SA;1V+|UXFxY^wQe8m-n;}T{o`<`K-^>4f{NEIz69FyWht3o?@Q!n6k6w zYliGHH55|WOURG6c+b-*X%92+iBTWlTi^`e60hF^PF{6{Ut;Y|Ttn-4AHRG(!d1*F z&a?B&aFKC#`UEu0d}-#&$NBTL$9%6@=9e|CQS+WR^Z(HC;eTVKuG+;}!K=#Ei>!F8 z)-U?29)sT#18J#IZ=hrx+FihVwc=AE{b#}YXL=LVe2lexe__Gdm8=|ki(U41#Qz6Q7yknQ literal 0 HcmV?d00001 diff --git a/src/services/import/single.spec.ts b/src/services/import/single.spec.ts index 716eb7b91..e650c8e98 100644 --- a/src/services/import/single.spec.ts +++ b/src/services/import/single.spec.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from "vitest"; +import { beforeAll, describe, expect, it } from "vitest"; import fs from "fs"; import path from "path"; import { fileURLToPath } from "url"; @@ -12,38 +12,47 @@ import { initializeTranslations } from "../i18n.js"; import single from "./single.js"; const scriptDir = dirname(fileURLToPath(import.meta.url)); -describe("processNoteContent", () => { - it("treats single MDX as Markdown", async () => { - const mdxSample = fs.readFileSync(path.join(scriptDir, "samples", "Text Note.mdx")); - const taskContext = TaskContext.getInstance("import-mdx", "import", { - textImportedAsText: true - }); +async function testImport(fileName: string, mimetype: string): Promise { + const mdxSample = fs.readFileSync(path.join(scriptDir, "samples", fileName)); + const taskContext = TaskContext.getInstance("import-mdx", "import", { + textImportedAsText: true + }); - await new Promise((resolve, reject) => { - cls.init(async () => { - initializeTranslations(); - sql_init.initializeDb(); - await sql_init.dbReady; + return new Promise((resolve, reject) => { + cls.init(async () => { + const rootNote = becca.getNote("root"); + if (!rootNote) { + reject("Missing root note."); + } - const rootNote = becca.getNote("root"); - if (!rootNote) { - reject("Missing root note."); - } - - const importedNote = single.importSingleFile(taskContext, { - originalname: "Text Note.mdx", - mimetype: "text/mdx", - buffer: mdxSample - }, rootNote as BNote); - try { - expect(importedNote.mime).toBe("text/html"); - expect(importedNote.type).toBe("text"); - expect(importedNote.title).toBe("Text Note"); - } catch (e) { - reject(e); - } - resolve(); - }); + const importedNote = single.importSingleFile(taskContext, { + originalname: fileName, + mimetype, + buffer: mdxSample + }, rootNote as BNote); + resolve(importedNote); }); }); +} + +describe("processNoteContent", () => { + beforeAll(async () => { + initializeTranslations(); + sql_init.initializeDb(); + await sql_init.dbReady; + }); + + it("treats single MDX as Markdown", async () => { + const importedNote = await testImport("Text Note.mdx", "text/mdx"); + expect(importedNote.mime).toBe("text/html"); + expect(importedNote.type).toBe("text"); + expect(importedNote.title).toBe("Text Note"); + }); + + it("supports HTML note with UTF-16 (w/ BOM) from Microsoft Outlook", async () => { + const importedNote = await testImport("IREN Reports Q2 FY25 Results.htm", "text/html"); + expect(importedNote.mime).toBe("text/html"); + expect(importedNote.title).toBe("IREN Reports Q2 FY25 Results"); + expect(importedNote.getContent().toString().substring(0, 5)).toEqual("s into