From dbcc1ff637c7fd29d11a401722a841adbf36582b Mon Sep 17 00:00:00 2001 From: dmitrievanthony Date: Tue, 17 Dec 2019 10:59:26 +0300 Subject: [PATCH 1/4] Use Gradle multiplatform plugin instead of Maven. --- .gitignore | 3 + .mvn/maven.config | 1 - .mvn/wrapper/maven-wrapper.jar | Bin 49519 -> 0 bytes .mvn/wrapper/maven-wrapper.properties | 1 - .../kotlinx-html/README.md => README-JS.md | 0 README.md | 5 +- assembly/pom.xml | 81 -- assembly/src/main/assembly/js.xml | 22 - assembly/src/main/assembly/jvm.xml | 20 - assembly/src/main/assembly/webjar.xml | 34 - build.gradle.kts | 385 ++++++++ buildSrc/build.gradle.kts | 13 + .../kotlinx/html/generate}/attributes.kt | 0 .../kotlin/kotlinx/html/generate}/codegen.kt | 1 - .../kotlin/kotlinx/html/generate}/enums.kt | 2 - .../kotlinx/html/generate}/humanizer.kt | 4 +- .../kotlin/kotlinx/html/generate}/kdoc.kt | 17 +- .../kotlin/kotlinx/html/generate}/main.kt | 25 +- .../kotlin/kotlinx/html/generate}/model.kt | 2 - .../html/generate}/parent-ifaces-gen.kt | 1 - .../kotlinx/html/generate/resource-loader.kt | 8 + .../kotlin/kotlinx/html/generate}/rules.kt | 642 ++++++------- .../kotlinx/html/generate}/tag-builders.kt | 0 .../kotlinx/html/generate}/tag-unions.kt | 2 - .../kotlin/kotlinx/html/generate}/tagsgen.kt | 856 +++++++++--------- .../kotlinx/html/generate}/xsdparser.kt | 13 +- .../main/kotlin/kotlinx/html/js/package.kt | 35 + .../src/main/resources/entities.txt | 0 .../src/main/resources/html5table.xml | 0 .../src/main/resources/html_5.xsd | 0 .../src/main/resources/htmltable.xml | 0 .../src/main/resources/i18Languages.xsd | 0 generate/pom.xml | 79 -- gradle.properties | 2 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 55616 bytes gradle/wrapper/gradle-wrapper.properties | 5 + gradlew | 188 ++++ gradlew.bat | 100 ++ js/npm.templates/kotlinx-html/package.json | 23 - js/pom.xml | 232 ----- jvm/pom.xml | 147 --- jvm/src/test/kotlin/compatibility.kt | 16 - mvnw | 234 ----- mvnw.cmd | 145 --- npm_publish.xml | 147 --- pom.xml | 304 ------- scripts/activate-profile.kts | 53 -- settings.gradle.kts | 1 + shared/pom.xml | 78 -- .../main => src/commonMain}/kotlin/Event.kt | 0 .../src/main => src/commonMain}/kotlin/api.kt | 0 .../commonMain}/kotlin/attributes.kt | 0 .../commonMain}/kotlin/compatibility.kt | 0 .../commonMain}/kotlin/delayed-consumer.kt | 0 .../commonMain}/kotlin/delegating-map.kt | 0 .../commonMain}/kotlin/exception-consumer.kt | 0 .../commonMain}/kotlin/filter-consumer.kt | 0 .../commonMain}/kotlin/finalize-consumer.kt | 0 .../kotlin/generated/gen-attr-traits.kt | 0 .../kotlin/generated/gen-attributes.kt | 0 .../kotlin/generated/gen-consumer-tags.kt | 0 .../kotlin/generated/gen-entities.kt | 0 .../commonMain}/kotlin/generated/gen-enums.kt | 0 .../kotlin/generated/gen-parent-traits.kt | 0 .../kotlin/generated/gen-tag-groups.kt | 0 .../kotlin/generated/gen-tag-unions.kt | 0 .../kotlin/generated/gen-tags-a.kt | 0 .../kotlin/generated/gen-tags-b.kt | 0 .../kotlin/generated/gen-tags-c.kt | 0 .../kotlin/generated/gen-tags-d.kt | 0 .../kotlin/generated/gen-tags-e.kt | 0 .../kotlin/generated/gen-tags-f.kt | 0 .../kotlin/generated/gen-tags-h.kt | 0 .../kotlin/generated/gen-tags-i.kt | 0 .../kotlin/generated/gen-tags-k.kt | 0 .../kotlin/generated/gen-tags-l.kt | 0 .../kotlin/generated/gen-tags-m.kt | 0 .../kotlin/generated/gen-tags-n.kt | 0 .../kotlin/generated/gen-tags-o.kt | 0 .../kotlin/generated/gen-tags-p.kt | 0 .../kotlin/generated/gen-tags-q.kt | 0 .../kotlin/generated/gen-tags-r.kt | 0 .../kotlin/generated/gen-tags-s.kt | 0 .../kotlin/generated/gen-tags-t.kt | 0 .../kotlin/generated/gen-tags-u.kt | 0 .../kotlin/generated/gen-tags-v.kt | 0 .../main => src/commonMain}/kotlin/htmltag.kt | 0 .../commonMain}/kotlin/measure-consumer.kt | 0 .../main => src/commonMain}/kotlin/stream.kt | 0 .../commonMain}/kotlin/trace-consumer.kt | 0 .../main => src/commonMain}/kotlin/util.kt | 0 .../jsMain}/kotlin/compatibility-js.kt | 0 {js/src/main => src/jsMain}/kotlin/dom-js.kt | 0 .../kotlin/generated/gen-consumer-tags-js.kt | 0 .../kotlin/generated/gen-event-attrs-js.kt | 0 .../main => src/jsMain}/kotlin/injector.kt | 0 .../main => src/jsMain}/kotlin/trace-js.kt | 0 .../jsMain}/kotlin/utilsImpl-js.kt | 0 .../test => src/jsTest}/karma/karma.conf.js | 5 - .../test => src/jsTest}/karma/package.json | 0 .../test => src/jsTest}/kotlin/exceptions.kt | 0 .../test => src/jsTest}/kotlin/injector.kt | 0 {js/src/test => src/jsTest}/kotlin/trees.kt | 0 {js/src/test => src/jsTest}/kotlin/unsafe.kt | 0 .../main => src/jvmMain}/kotlin/dom-jvm.kt | 0 .../main => src/jvmMain}/kotlin/trace-jvm.kt | 0 .../jvmMain}/kotlin/utilsImpl-jvm.kt | 0 src/jvmTest/kotlin/compatibility.kt | 36 + .../test => src/jvmTest}/kotlin/custom-tag.kt | 0 .../test => src/jvmTest}/kotlin/dom-trees.kt | 461 +++++----- .../test => src/jvmTest}/kotlin/exceptions.kt | 0 .../test => src/jvmTest}/kotlin/html5-tags.kt | 3 +- {jvm/src/test => src/jvmTest}/kotlin/huge.kt | 8 +- .../test => src/jvmTest}/kotlin/streaming.kt | 21 +- .../src/test => src/jvmTest}/kotlin/unsafe.kt | 0 .../jvmTest}/resources/declarations.json | 0 116 files changed, 1813 insertions(+), 2648 deletions(-) delete mode 100644 .mvn/maven.config delete mode 100644 .mvn/wrapper/maven-wrapper.jar delete mode 100644 .mvn/wrapper/maven-wrapper.properties rename js/npm.templates/kotlinx-html/README.md => README-JS.md (100%) delete mode 100644 assembly/pom.xml delete mode 100644 assembly/src/main/assembly/js.xml delete mode 100644 assembly/src/main/assembly/jvm.xml delete mode 100644 assembly/src/main/assembly/webjar.xml create mode 100644 build.gradle.kts create mode 100644 buildSrc/build.gradle.kts rename {generate/src/main/kotlin => buildSrc/src/main/kotlin/kotlinx/html/generate}/attributes.kt (100%) rename {generate/src/main/kotlin => buildSrc/src/main/kotlin/kotlinx/html/generate}/codegen.kt (99%) rename {generate/src/main/kotlin => buildSrc/src/main/kotlin/kotlinx/html/generate}/enums.kt (97%) rename {generate/src/main/kotlin => buildSrc/src/main/kotlin/kotlinx/html/generate}/humanizer.kt (98%) rename {generate/src/main/kotlin => buildSrc/src/main/kotlin/kotlinx/html/generate}/kdoc.kt (74%) rename {generate/src/main/kotlin => buildSrc/src/main/kotlin/kotlinx/html/generate}/main.kt (94%) rename {generate/src/main/kotlin => buildSrc/src/main/kotlin/kotlinx/html/generate}/model.kt (97%) rename {generate/src/main/kotlin => buildSrc/src/main/kotlin/kotlinx/html/generate}/parent-ifaces-gen.kt (98%) create mode 100644 buildSrc/src/main/kotlin/kotlinx/html/generate/resource-loader.kt rename {generate/src/main/kotlin => buildSrc/src/main/kotlin/kotlinx/html/generate}/rules.kt (95%) rename {generate/src/main/kotlin => buildSrc/src/main/kotlin/kotlinx/html/generate}/tag-builders.kt (100%) rename {generate/src/main/kotlin => buildSrc/src/main/kotlin/kotlinx/html/generate}/tag-unions.kt (97%) rename {generate/src/main/kotlin => buildSrc/src/main/kotlin/kotlinx/html/generate}/tagsgen.kt (96%) rename {generate/src/main/kotlin => buildSrc/src/main/kotlin/kotlinx/html/generate}/xsdparser.kt (96%) create mode 100644 buildSrc/src/main/kotlin/kotlinx/html/js/package.kt rename {generate => buildSrc}/src/main/resources/entities.txt (100%) rename {generate => buildSrc}/src/main/resources/html5table.xml (100%) rename {generate => buildSrc}/src/main/resources/html_5.xsd (100%) rename {generate => buildSrc}/src/main/resources/htmltable.xml (100%) rename {generate => buildSrc}/src/main/resources/i18Languages.xsd (100%) delete mode 100644 generate/pom.xml create mode 100644 gradle.properties create mode 100644 gradle/wrapper/gradle-wrapper.jar create mode 100644 gradle/wrapper/gradle-wrapper.properties create mode 100755 gradlew create mode 100644 gradlew.bat delete mode 100644 js/npm.templates/kotlinx-html/package.json delete mode 100644 js/pom.xml delete mode 100644 jvm/pom.xml delete mode 100644 jvm/src/test/kotlin/compatibility.kt delete mode 100755 mvnw delete mode 100644 mvnw.cmd delete mode 100644 npm_publish.xml delete mode 100644 pom.xml delete mode 100644 scripts/activate-profile.kts create mode 100644 settings.gradle.kts delete mode 100644 shared/pom.xml rename {shared/src/main => src/commonMain}/kotlin/Event.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/api.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/attributes.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/compatibility.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/delayed-consumer.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/delegating-map.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/exception-consumer.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/filter-consumer.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/finalize-consumer.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-attr-traits.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-attributes.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-consumer-tags.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-entities.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-enums.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-parent-traits.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tag-groups.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tag-unions.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-a.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-b.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-c.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-d.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-e.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-f.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-h.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-i.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-k.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-l.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-m.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-n.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-o.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-p.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-q.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-r.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-s.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-t.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-u.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/generated/gen-tags-v.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/htmltag.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/measure-consumer.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/stream.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/trace-consumer.kt (100%) rename {shared/src/main => src/commonMain}/kotlin/util.kt (100%) rename {js/src/main => src/jsMain}/kotlin/compatibility-js.kt (100%) rename {js/src/main => src/jsMain}/kotlin/dom-js.kt (100%) rename {js/src/main => src/jsMain}/kotlin/generated/gen-consumer-tags-js.kt (100%) rename {js/src/main => src/jsMain}/kotlin/generated/gen-event-attrs-js.kt (100%) rename {js/src/main => src/jsMain}/kotlin/injector.kt (100%) rename {js/src/main => src/jsMain}/kotlin/trace-js.kt (100%) rename {js/src/main => src/jsMain}/kotlin/utilsImpl-js.kt (100%) rename {js/src/test => src/jsTest}/karma/karma.conf.js (87%) rename {js/src/test => src/jsTest}/karma/package.json (100%) rename {js/src/test => src/jsTest}/kotlin/exceptions.kt (100%) rename {js/src/test => src/jsTest}/kotlin/injector.kt (100%) rename {js/src/test => src/jsTest}/kotlin/trees.kt (100%) rename {js/src/test => src/jsTest}/kotlin/unsafe.kt (100%) rename {jvm/src/main => src/jvmMain}/kotlin/dom-jvm.kt (100%) rename {jvm/src/main => src/jvmMain}/kotlin/trace-jvm.kt (100%) rename {jvm/src/main => src/jvmMain}/kotlin/utilsImpl-jvm.kt (100%) create mode 100644 src/jvmTest/kotlin/compatibility.kt rename {jvm/src/test => src/jvmTest}/kotlin/custom-tag.kt (100%) rename {jvm/src/test => src/jvmTest}/kotlin/dom-trees.kt (95%) rename {jvm/src/test => src/jvmTest}/kotlin/exceptions.kt (100%) rename {jvm/src/test => src/jvmTest}/kotlin/html5-tags.kt (96%) rename {jvm/src/test => src/jvmTest}/kotlin/huge.kt (96%) rename {jvm/src/test => src/jvmTest}/kotlin/streaming.kt (95%) rename {jvm/src/test => src/jvmTest}/kotlin/unsafe.kt (100%) rename {jvm/src/test => src/jvmTest}/resources/declarations.json (100%) diff --git a/.gitignore b/.gitignore index e46776d6..bd14b5fb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ .idea *.iml target +build +.gradle *~ *.versionsBackup **/karma/node_modules @@ -8,3 +10,4 @@ target **/karma/etc js/src/test/karma/package-lock.json + diff --git a/.mvn/maven.config b/.mvn/maven.config deleted file mode 100644 index 854796cd..00000000 --- a/.mvn/maven.config +++ /dev/null @@ -1 +0,0 @@ ---no-snapshot-updates diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index c6feb8bb6f76f2553e266ff8bf8867105154237e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49519 zcmb@tV|1n6wzeBvGe*U>ZQHh;%-Bg)Y}={WHY%yuwkkF%MnzxVwRUS~wY|@J_gP;% z^VfXZ{5793?z><89(^dufT2xlYVOQnYG>@?lA@vQF|UF0&X7tk8BUf?wq2J& zZe&>>paKUg4@;fwk0yeUPvM$yk)=f>TSFFB^a8f|_@mbE#MaBnd5qf6;hXq}c%IeK zn7gB0Kldbedq-vl@2wxJi{$%lufroKUjQLSFmt|<;M8~<5otM5ur#Dgc@ivmwRiYZW(Oco7kb8DWmo|a{coqYMU2raB9r6e9viK6MI3c&%jp05-Tf*O#6@8Ra=egYy01 z-V!G;_omANEvU-8!*>*)lWka9M<+IkNsrsenbXOfLc6qrYe`;lpst;vfs*70$z9UM zq%L>pFCOr$X*|9&3L2h;?VA9-IU*iR6FiGlJ=b~DzE5s^thxXUs4%~*zD#K&k>wZAU8 zpaa!M+Z-zjkfGK15N!&o<3=cgbZV7%ex@j^)Q9V`q^i;Fsbkbe6eHJ;dx{QbdCCs1 zdxq^WxoPsr`eiK3D0Ep}k$ank-0G&+lY!ZHDZBYEx%% z2FyE?Lb0cflLB)kDIj;G=m`^UO<4h(RWdF-DT>p{1J5J90!K!AgC0)?jxPbm$KUjg zJED+#7xQmAmr`(S%BQTV-c97As~r3zD$E;3S)@}p5udA@m6pLgRL5h-;m>LvCq?&Q zokC7Vnk-zBEaa;=Y;6(LJHS>mOJV&%0YfRdUOqbKZy~b z(905jIW0Pg;y`Yv2t+RnDvL4yGEUX*tK)JT6TWn4ik~L)fX#tAV!d8)+A)qWtSjcr z7s|f%f;*%XW!jiRvv9ayj@f&dc|1tKDc{O3BWcLGsn-OYyXRLXEOEwP4k?c`nIut0 z?4S;eO@EoynmkxHq>QpDL1q^wOQxrl))2qya?dk05^5hK? z{P6;WKHUaHw9B0dd&|xw&CYN2fVrn};Gq<=Z^QZk3e~HzzY~JrnPCs0XwMp#B<9Gm zw0?7h#4EY%O-ub6mi&O2vcpIkuM?st;RtEpKSz^Xr#3WHhpsZd!gh|_jGQ`KA30T- zKlz9vgB;pY^}Uh??nQKSzk>2&J+Qi*r3DeX4^$%2ag9^x_YckA-f9p_;8ulh(8j9~ zes{O#{v!m%n^el(VryTF-C%xfJJ$rZj)|Y|8o&))q9CEwg2;Wz&xzyHD=@T_B%b}C z=8G^*4*J4#jUJn{7-3^U(_uUp6E8+GDt#le)nya-Q4kL5ZGiFxT4bF+mX`whcif*? z>CL&Ryn3HHT^^QmWYr<}Q1_Jj7fOh}cS8r+^R#at-CnNl3!1_$96&7nR}gh}))7a0J&z-_eI))+{RCt)r8|7|sV9o01^9nv?aePxMqwPP!x|sNmnn&6{K$K*mVX9lxSAmcqAV1(hKA-=coeTb*otxTOGYXsh zW$31^q7L@<#y~SUYoNKP1JK?4|FQNQb$i8mCG@WhX9i_^;@M2f#!nq7_K*M!4lGz1 z5tfADkO7BZDLgVQ?k7C)f;$eqjHI&zgxhf}x$8^ZEwFfm-qY=+M+fbS)9r8fFE5H9 zv{WPU35cR8%z;(W%5<>y+E&v84J4^Y##N!$B++RI`CZ1i3IW9Nau=*pSxW&^Ov-F> zex=&9XYLVcm1Y?am>2VC`%gMev9$#~; zYwxYvMfeKFsd!OBB@eOb2QNHFcsfKm;&z{OVEUiYmQ}~L@>$Ms@|Ptf3jQO-=Q;1+ zFCw+p+Z3lK_FmIAYnk2V;o915cDM}%Ht5RH%w}P>Yg9{h1mZ}~R6tUII4X7i4-2i% z2Uiw3_uHR!d~5(s;p6btI@-xhAkRg9K|n#}PNT9Dw9P>z$3>30lP1(=mcQ|tpyv3@ ze1qU!69OAx4s7$8r7Y-#5I`m!BXq`f!6C(BtUlG-oq+liqMCS_D@0nSFc%y+N6_Zh zi%L3LhF3zZP{d1)L&SXxPD(fp@T@J;jZeNaf$zl>vAh7=tI z2;wS^QyRdZm~)Ur&!af;8eB8*7(F96K^=WbC$)#TWvB~Awo5AtPf8Il4snD}Xsqd< z>cH+gcg72nTg5tl>oFbwdT{BDyy1=f=4~h~L$)UX;FXa;NdSlyF{(YLrx&VDp`pQI zh3pQtC=d8i1V6yUmFon*LQsNYWen?eO-gSZ4cvYcdEd0klSxcBYw+|5AyCv6TT96h z{7Yh9`h}biU?3oBFn=d8>Hn`1Q*w6rgeX^QbC-WFwjY}Int0;qUny4WMjIee@#0%l z>YAWLVCNo1lp$>9L$Tx`t!dp?>5Pfbhc*!*wzfWkj_x`Q?`3Jc@9r8uq~dgb+lgeh zlA`eUal3e2ZnWQSSYB>qy#85^>j7!=uO-hG5*erp22NaC81#Ytioc>r?D9$b_JiC+ zSp)8KR$%}FjFNRkeE#c5vKbXNJDBoO< z)73Jt7Y|3v45efud1xkg2GO3OwYfsuBV`f6S_D>Aoh2%=`1Y$bHP>0kBvTSowX57H z&1nbbx=IT>X^ScKYL&&{LNq~^UNgR|at`D;SxTYpLvnj_F*bGgNV2tEl1k$ccA&NW zmX(LV*>Op)BOgoric(98mIU)$eUa&jM5bKlnOrHm$p^v@u;W0J)!@XWg+#X=9En(-tiw!l?65rD=zzl(+%<)bI{ZN;SRco{jO;>7 zlSY|TIxuN|d#YHx^^~>iYj2V>cC>wQwWzGVI!6#epjJ6tl_`7tDY17WMKMB@s*Jr& zXOs*@>EwQ6s>M13eZEBJ#q0|;8jao{wK4keesH9?$OSk~_3#*x`8fAzQa7fprQ6(Z zi$}B%m81y*S)RxaX;wW!5{{EDw8)IE3XDRO1Y^%TMr}c|Y>WBAKT=b*K&uMT(?JSl zO>gVtl_bKQ$??TeWr7wYO+Vbl?CTQj?JrW&td`|#@;R2Gca9jq^p`{@)KY97o3}Af zfTh{pUUWD;P7sq=I!lA6;*hq0Nq`F56T)x$K?BMOk}tptYw(%$?*otp2N6IF3#GgqM46Cda!qzvGZcMgcGV`bY5ZIfOB6^;US#WgRai zq#vS8ZqPY953|eFw<-p2Cakx|z#_{4pG}mk{EANI{PnK*CUslvS8whko=OTe13|It z>{O2p=mmanR2-n>LQHaMo}noWCmjFO@7^z~`Y{V>O`@rT{yBS=VXsb}*Pi_zDqM3? zjCZqWR}fEzAkms+Hiq8~qRAFvo}dVW{1gcZ?v&PdX?UG*yS}zT9g7nZ!F1WRH}sHA zJ4~B2Br~8?uhbaX!3g+7=3fVM)q^wEzv**rk5e34==NRCV z3G$G5B!DICFslm)c){oesa_0muLxGoq`xYVNURl*NhE#v2>y9vDz&vJwrB`Q>DhN# zY2GnY!Y^8E%PU0}haXL$8a5QN1-&7NWuC~{62j| z2ozmFyx8GpOzj?&KK1JF28;E8H_p4N^LMm9K0y}!lCxcK79eFGTtGm?7jy?t94Q@X zli|our1#|>f*68fyA0bSn=YisYSl8HB(dFN4Y$qb7p4DR0YQt=^eEMnJkgiM48$>QV6x5*^a|D|t zMPDk}u<^YEYrt|H&hy)DRk%rDIb{LTo;h7=fp^J9Lr&`{9`8_pS*tQ_$KXB$2#5{h z-&yPbN-zInq{7aYZuaItS8-2Mb4OQe2jD*&)0~898E|HlAq`o!M&It@vvnj z_y@))>~_oR%S8OfmFTGYIat^#8_YKMqWLac<^}RZFDcJqvSJa>&6HaLS7p-$)QyL= zHrO|t75`d41Bp37RZtKR%g^%o@9C5Ce=CjuvVQ-KI#Uw2WWa>cho;jztUt~Le*_pT zkfA2iif9QFp;vhd)|A?tdAQ?9o~?EqgL;=)eKFQ{E^u?OIP}fl^5A;$^ZVutCIqj5 z&*i+G?!Px|5~~6zTYf>~uw*kM`5p&Hju&#w!7^An3*mQwTK22wC7p^OsvMjWf`$MY zLX|ZFV#+>Uq2!QyRD9cgbI9nswteMAMWtK(_=d%r?TLrx?_rkjbjI(rbK#T9Gn}J| z5ajow3ZErpw+%}YfVL-q^{r~##xJ^_ux2yO1!LJZXg)>F70STV=&Ruwp&XP^_?$h0 zn>$a?!>N+Kt$UXzg`e+szB}*uw)Z$uL6?>*!0IrE)SgV~#a?Qgg7HuTsu3ncrcs|l z=sQSMtr}S!sQ4SriKg=M`1Y|bC`XJ+J(YT)op!Q);kj0_e)YNVNw8SI|1f%9%X?i5>$lLE(Wfc$wY?(O985d5e*)UPtF!7gG3(Kd z-^=-%-wWCEK`r4oFh^{|;Ci%W^P>K%9dBNDqi%c$Q{iY#(zbwN7~pQI=SHd%WuV7Z zO?0P;Zc6yeN;)IbJIP0=>W)EgE!76jM^?IyQ*D(T})1NGmP z~YAb6T^#R6;)Ls;cV~LWk z33lcLpbSjxStw9Z>Nv&+rPOXxCGB=?ttZs?{OF7;GYlV&w7-82POb$XrogqFpLA2`j&MLZXr=IG>PAFSb2np~x;E_kV{ zsDwbK$?iYRn7$;mHYZhQn6P2#_hXAHd?;q~!Zy}%;@%wT3u|Sa-!WxxOE_fwyFv*Db@>X;Rl+fK1oP?55*dN0#2%SuikZ)y7Kx>`8*9d?}5 zKvXF7J5&Ey6{A8qUFxrFOh<$xdSWV^dw7z|`7RVZJhAwO72V zRrM_3*wI`^ycl7~>6KaCYBr#WGR>}B)Q(V%&$MhVrU>u~ql zjGeZF&>=_ld$oY!V}5}Gb> z*iP38KOav9RHY)0uITwgz99w- zJX-0BGCdY*$c7pi@>@-`2>#>}c(DHaI62ntpKz z`c01Z#u7WuMZ71!jl7hv5|o61+uv5nG?*dffEL~328P5HlKh2&RQ;9X@f>c1x<>v= zZWNSz3Ii~oyAsKCmbd}|$2%ZN&3gc9>(NV=Z4Fnz2F@)PPbx1wwVMsUn=-G=cqE3# zjY{G4OI~2o$|*iuswTg1=hcZK$C=0^rOt-aOwXuxU=*uT?yF00)6sE}ZAZyy*$ZTH zk!P*xILX#5RygHy{k?2((&pRQv9_Ew+wZ>KPho_o1-{~I*s1h8 zBse@ONdkk-8EG?r5qof}lwTxdmmEN|%qw(STW|PFsw1LD!h_Vjo;C4?@h|da4Y;*; zvApQ=T&=jWU39Uz=_yN@Bn0{{)yn8RZ2&X!<*KBv-7tcWdkF1Ij8D0mU zwbcs}0vDaLGd@xx%S_QZ1H)GTt`~>+#z}HXJTl9S!sd9seVJc|_wUMSdD$>k`K_RG zlq(fsnR@KM^;C}}&vG2t+}_nGPuI5ovg$6TYeMPIREGxP@2r~RKd@>gV`mq0XENsh z%IRZ-ZNP+4#J`o-yRpP;w@;CrSr3wiix3e9Qc|s(WapRq950P->g|JYC$A)$YrGeH zz5dKlAHAPJ>%?llqqB&#+#VU3sp=9>Xms1J;tSYN>LMwNtU68yr!})K4X>%^IrIDp z>SHy&6fJHybwS^BW>okFeaQp6wxaVP`hy;ZX#e+=w3c?PGD&_LmeqL8oZ*YaM1+#S z5WNAKo4+99JW(+qcMjh;+c%R#R?t;(aQ`2`C=bo((ERzgAwKKazXy*0wHN;v;P|f> zBW&?`h#_I^?Bc5GX7XP@|MOiw%&-#?EQ|w+FdCl_&qPN&s$|Z17UCF9oXS#N z)px6>zm&}0osTnCGI;AXsj`q=LpIsW4x}q~70uey5N_NpdJ*Gv^@$g@f2{EB>LP7Y zE5P`jZh1vHNgk7LfMT({jLCjRZa4ubW;UA#%<@Zj?efrPdm{W3J5UEFgm`YkVqz;AMFetZuM5uQpvORb1GDX`WZGwTrF z46+&sAri5QXCfGYpdgonWR5`>ZEa;?jrKvfNvXF<&l)1uU-3q#4X16R2~?P0yg3H` zfw82QWZo^cac+%(g^_6`+2>~Fvy{pOCGnj86+=-!N`GPWAjus1ejhn6f4|mDkU6EE z&u~;xfdRMkj=h;4d~~+4(>L8weT3cz9e@E11EH!tX<IC!@kS+dsIQA`HQ2vdoS zzSD0U?mb1M0@qXu{yhZk2Y6}2B-AvvYg|tRr6z*_*2l*VLiR6G;M{O^Znq~LI%=I_ zCEU{htx&Bo+69G`p|A@R>KlY1*;;!{aWq?Pc0Cu!mT-0S`!>3<@s%Ri;utYNQ+CXDj+LC5<*$4*$-mogGg^S~3JRv{ry zPJzKJg!XKb>P}yJVc^1V@T&MV{z;@DLhvV{dG?RogCcPkROivliSr58>5Zw&&A2?n z9`JOLU;eQGaOr6GB(u{t3!+$NaLge$x#M&*sg!J;m~rRc)Ij5|?KX_4WiM-eE%t8e zqUM7eZ~ZonavR;K4g2t$4Fj=UVyEHM7LPb%8#0?Ks{~?!qhx9)2^>rg8{0npLtFKR zJB)19TFiD^T7IUXA8wt!@n5gj&@OK~EO}MR6^qd?^-?%-0~b2K9RWh+_mSEQQWsLCFOt#JlAQMgNxvv-m z;sF*r;WZ*Wi@I|6pMN+|_rLYKlWwvpKZY9rA;fo8l8hFQGI?4#kt1-r4UL;nPF@{~ z2T~a@2>yD|GuU55boxoIIe_BFo2Vq&rs&2itv|B>OC*bIeOqMBRw~y5KRMwiVHc)` zIBdliiY?Ai7*+k#NZf3MW5!hya~RZ6r7k)b?HF0e(n`ZX=iCpT7St`FDwL@SGgKlq zNnnU*3IcnYDzJg{7V$cb`xeb4(s(({&%f69XMTw-JQErS%?X_}?&y&tvHw@>1v{#R z4J@(=el^kRI+jGa;4)l#v%-jM^$~0ulxh6-{w*4Lsa>Tuc z>ElR3uM~GUChI)c{TW${73A3$vs<&iH;e?4HjW2MvSz9tp9@69+`_@x{Qte^eFo5IlAi&zw$=t6u8K%8JtjRI88PFNM7R>DaCO3rgngmk zI-RMOyt@kr-gVra=tl^@J#tI7M$dird(?aU!`&1xcm~2;dHN(RCxh4H((f|orQ!BS zu;(3Vn+^doXaqlhnjBJj-)w?5{;EEZTMx+?G>Rp4U^g<_yw_blAkdbj=5YrNhZB9@ zNmW=-!yFx5?5aF^+6*1XI|s3lIn_eyh`uv%?liNzSC#z&z^R(mqEYL@TdWzgkf>g1 zedzs*={eJavn{8vF%4nf@et<@wkOPR>NiVuYtESbFXQ;sDz_;|ITVeoW|me5>jN5P z5--{13JT{3ktkAf9M;Jty)yectg#{+9sK{C;2CvPU81tB3{8S5>hK{EXdVe?fR?sd8m`V zPM*$)g$HKp0~9Xf6#z!YJ&g!%VkCMxkt>ofE!62?#-&%|95^)JJ9 zk;GlJdoH0HwtDF(_aTv}mt$?EyRyE6@pm5DG~Gj-2%3HcZT13e)$)z99bdK_WCx|Q zQNza(R)Z>ZKTn8oIdcw%c^pFaMpFZ4HOds!BODgSBWJJYW3I_WJvoEm4xsfs%#LZ6 zdPCk{5XJ>2f7Hj-i*9lTW6BKCIuy)3L!b3(uPoSgW1WA+OEYYBRgSsJq7wjHh%c8ymMs3FU%~cprqL*084p*^T3{J%Gwq`jB30n(&y6- zII8-_r-s5&CVtsoNZ9%On?7yn;oZG03-$wx^uRk9>b*ufh15|HHk|%=MA^ioyb9CYU$7y$4R|M5HvpiCTxKSU`LUg$+ zB3IBl&{qO}agqF~BFM6&11wMeR-#Rkuh_(^j+P4{;X_w|siva$5P`dykyhfAUD%e8 z+{G0|7(Q`_U91sMKFO^rHoCWfXi0$^ev)-187G}klYv@+Rf%uZ&T4-Uhh=)pcU6O1 znXc^c5)!$X+39|4`yNHuCj0wkm+K1VN0G3_EL?-ZH$p5Y*v6ec4MV zS~1~}ZUhl&i^4`Fa|zyH4I%rXp;D6{&@*^TPEX2;4aI$}H@*ROEyFfe^RZI%;T>X> z>WVSUmx@2gGBxkV&nfyPK=JI$HxRKUv(-*xA_C;lDxT|PgX*&YYdkrd5-*3E1OSXBs>35DLsHHp%zm+n0N(Yu{lMo>_t&d1Xy zfCxl=(CNNx>ze+7w)60mp>(M``Qn$aUrVb$cJAb6=Do7VgW`Qn2;v5{9tB)jP$_mB zn{Hb_sMs4yxK|!`PI7+zO68}{Iv)dpu!+ZZl)xuoVU(oFsm<3gT{j2c*ORl|Lt+?dR^M?0 znW6rNA)cR*ci;z?BaG(f(XynY_y+kTjj~T$9{N{>ITQ4-DmZ6{cOkoea9*LpYL{Apo0hSpLqJu z9`tjP&ei;%pn9QY>-$9=<73M#X;qGb+%Bt0x>=u`eDtthI+LWB9CdAO=ulZo9&Ohs2X8GW>b7#&U|py28KTvPBl#Nqv^{AgkVXrOyS z@%3)}$I&mJOYWoG$BBb)Kb~0ptDmBxHNH^i6B8FA7NR2HfTnjP?eDnoY4NS_aYg4P zGGPw11sAf^^fTkY#j@T#6Ll*^GVaPo-1;aS6_a}{r{tWZilzse2m zc?LS=B|EWxCD|!O%|%t3C@Rd7=rKJRsteAWRoDu|*Kx-QwYZQeYpGrZ_1J%mFM;*S*u=0 z%1OC9>kmCGqBBu#-1jVPRVW*BTv%3uPI8fO?JOZD#P_W^V+K7&KVB>hzZ@PdY*%Ezo;}|5Mk`Mo2m*_K%no*jDJGp(s9j;&U`Z>z zO#SEe)k!p$VE-j2xDoX$!;Up5%8x$c`GH$l+gTA*YQaE0jwCOA<*__2NkV){z_u2=4NQ zSk$(oj$%ygio?3V8T3IyGMYvPs`t{im2IoHs7or+>>MYvG%Q?PwOLqe%73uGh6Wn; zo>e7qI$9?%cVVkvQLOLKcU5n*`~qn8pzkdu=Z4#2VnhUy>S*;kT=NqA!dQtnE?wVg zOKobxJ|QCjk`!(2*~5NQx{{=Lr=)ndyn{V|&PxUa=xQXVU?#M24F8H%C*uvs(#Va0 zSkp}0EFYq0#9xp&$O?gIInc#^^_6Ol88W%)S5A@HeE0(SR&!Yl>u=*5JEoUViDR@2 zJBjTsp=Y44W`Nb2+*CcZCkwP(QChX1s)b09DEIZCKt1$q2~;&DJ9!{bQ1Y6&T_9u1 zZM8^im8Wf#FUO6tZqc7#`z0cN_JA>#U_b7he%?cCnlV2&47y5Fc)Z7bp5xGe1zNq9 zl1VaV-tsm3fY=oIX^SPl!P;9$o?**0brq#ShM~3CXhh^SK0oOKB9O>;q3G@ z&4&h$mLSgohc^5IC|H>IGfZvVQFUT>T$|U7{znY`56<5d)07oiv*2R0+-BGPPkWJ! zIOzKF+<5o2YLWP|SGCx8w@<>u6K1o`++xJ+6kaJrt<&0Haq zyUccgxI$sR07Vo9-pF);heBva;?&NcAzC*gSSG9B3c?A;IH9J zl$j%F4*8;F0;H2Cjo*kWz4{kSh?nX}23&&KL+U(#nOAuR`wn@uwUNkWEgb*ZShKPy z`aXTJT4f*Um4`iv2KOfzf-~`#pOfH8>is*xnLBDTyx2Xuc8Y2Od6z((P2AZK@b_96 z#0V6jdw>sEDJ#uNGV|EshD1g&bYZCzCZTZ)286HLHc8Eyy_HPi;d#%;Wx}d6tUUxq z_VB$+898z_{9-A<*v6VI7?(dC04o!8$>DQ$OdbrA_@<6auiBNp{Dw$Hs@@gcybIQT zAU7Pc5YEX&&9IZ~iDo&V`&8K$-4o$)g?wF8xdv1I8-n}1bc7tviIBqt z#iIl1Hn;W?>2&#bU#VZ1wxq(7z=Q15#0yoz)#|r`KSPKI-{aN%l61^?B4RMDt?Vk` z)G#K6vUN?C!t{Q<@O4$0(qI>$U@@TI2FVF;AhSSb5}LtXx&=k&8%MWM3wv;Xq0p~W z#ZX;QFv5G9-i6=+d;R7Dwi)ciIZ1_V!aw;K^etau+g0fOA2HXpV#LQZGzf?h#@}(o z|3w!sZ|&mp$;tmDiO=zef5C|Alz+@@4u5#yZ7yNpP=&`432%a{K#{;nsS!jwk-$Qs zZRty}+N`Y~)c8|$&ra{bOQWM2K7qa}4Y{ndK%dKp&{ zFCvX{PAy_C{xzS_-`0>JlPP7&5!5 zBQ$NQz^z#2y-VeIxnfY|RzU`w+1t6vwQ|wM)LlpuaUzYehGII;>2DYyR|~wC@l97s zgX=f*1qtfDyco%BHmN+o<2qoi`D67R+RM$$NN5-moE4kx3MCFfuip*45nComOZKQf z3!(8tkSdhY5+A%@Y=eVEZkXU3S6B2V-R$ZuRIXWhsrJg3g)p4vXY@RV60bKuG zT6T!enE<;(A{*HPQhae*(@_!maV~AWD4EOwq10tkCXq+HPoe_Pu?d4Kg=2ypcs?&f zLa>mEmPF4ucJ%i~fEsNIa{QmQU27%Abh|w(`q)s~He5$5WYQ_wNJX6Qop<=7;I1jd zNZak`}0lVm+^O!i;|Lwo}ofXuJ)*UtH4xaPm*R7?YS*<&D__=@Kki>{f_Z-XqM;Tj195+~@d;rx zh5pj8oMuupWa#E(%85**I~1Zat-Sa^_R11-CiKdd`8m(DGuzOm9lX$Dd!DX!_Al}d zS!-|}dWG80S;`jSKDH%Uv;-OJNeBI0Bp$z->{_>1KU%h&Af7nns(L=xRN1 zLvOP=*UWIr)_5G2+fCsUV7mV|D>-~_VnvZ3_>=9 z_bL6`eK%W*9eJ34&Puz^@^ZIyoF@%DTun#OOEdUEn8>N9q(}?5*?`o?!_<(i%yc`k zf!xXD6SQscHgPgiHt>x6{n{+}%azrfV4VHi#umyi0;11c816`E??2`$;Rc`)qA2H( z5L|{o=ut7Te=^~@cR0_#cah0?w0Me$&>}ga8xxy=?DDl#}S~Y z4o2n`%IyGjQEP%8qS|v(kFK&RCJbF1gsRVJ>ceSjU`LuYJu%C>SRV#l`)ShD&KKzv ztD<9l0lcW0UQ8xjv|1NXRrCZhZh3JFX_BNT@V|u9$o~8M=cjOX|5iBS|9PAGPvQLc z6sA~BTM(~!c&V=5<}ZIx}O7A;|&bd7vR_y)t+ z?Vm7kb^gJ88g;!fRfMTSvKaPozQz4WcYD8l#0WxQ${P%0A$pwhjXzyA0ZzErH{1@M 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 diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index a3f9f187..00000000 --- a/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1 +0,0 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.6.0/apache-maven-3.6.0-bin.zip diff --git a/js/npm.templates/kotlinx-html/README.md b/README-JS.md similarity index 100% rename from js/npm.templates/kotlinx-html/README.md rename to README-JS.md diff --git a/README.md b/README.md index 76131b6b..7b2163c5 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ [![Official JetBrains Project](https://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) -[![Download](https://api.bintray.com/packages/kotlin/kotlinx.html/kotlinx.html/images/download.svg)](https://bintray.com/kotlin/kotlinx.html/kotlinx.html/_latestVersion) [![npm](https://img.shields.io/npm/v/kotlinx-html.svg)](https://www.npmjs.com/package/kotlinx-html) [![TeamCity (simple build status)](https://img.shields.io/teamcity/http/teamcity.jetbrains.com/s/KotlinTools_KotlinxHtml_Build.svg)](https://teamcity.jetbrains.com/viewType.html?buildTypeId=KotlinTools_KotlinxHtml_Build&branch_Kotlin_KotlinX=%3Cdefault%3E&tab=buildTypeStatusDiv&guest=1) [ ![Kotlin](https://img.shields.io/badge/Kotlin-1.2.71-orange.svg) ](https://kotlinlang.org/) [![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-green.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0) +[![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-green.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0) +[![Kotlin](https://img.shields.io/badge/Kotlin-1.2.71-orange.svg) ](https://kotlinlang.org/)[![Download](https://api.bintray.com/packages/kotlin/kotlinx.html/kotlinx.html/images/download.svg)](https://bintray.com/kotlin/kotlinx.html/kotlinx.html/_latestVersion) +[![npm](https://img.shields.io/npm/v/kotlinx-html.svg)](https://www.npmjs.com/package/kotlinx-html) +[![TeamCity (simple build status)](https://teamcity.jetbrains.com/app/rest/builds/aggregated/strob:\(branch:\(buildType:\(id:KotlinTools_KotlinxHtml_BuildGradleMasterBranch\),policy:active_history_and_active_vcs_branches\),locator:\(buildType:\(id:KotlinTools_KotlinxHtml_BuildGradleMasterBranch\)\)\)/statusIcon.svg)](https://teamcity.jetbrains.com/viewType.html?buildTypeId=KotlinTools_KotlinxHtml_BuildGradleMasterBranch&branch_Kotlin_KotlinX=%3Cdefault%3E&tab=buildTypeStatusDiv&guest=1) # kotlinx.html diff --git a/assembly/pom.xml b/assembly/pom.xml deleted file mode 100644 index b25df02c..00000000 --- a/assembly/pom.xml +++ /dev/null @@ -1,81 +0,0 @@ - - - - kotlinx-html - org.jetbrains.kotlinx - 0.6.13-SNAPSHOT - - 4.0.0 - - kotlinx-html-assembly - - - - org.jetbrains.kotlinx - kotlinx-html-jvm - ${project.version} - - - org.jetbrains.kotlinx - kotlinx-html-js - ${project.version} - - - - - - - maven-assembly-plugin - 2.6 - - - jvm-and-webjar - package - - single - - - - src/main/assembly/jvm.xml - src/main/assembly/webjar.xml - - - - - js-only - package - - single - - - src/main/assembly/js.xml - - - true - - - kotlinx-html-js-assembly - - - - - - - kotlinx-html-${project.version} - - - - maven-jar-plugin - - - default-jar - - - true - - - - - - - diff --git a/assembly/src/main/assembly/js.xml b/assembly/src/main/assembly/js.xml deleted file mode 100644 index 3573de4f..00000000 --- a/assembly/src/main/assembly/js.xml +++ /dev/null @@ -1,22 +0,0 @@ - - js - - jar - - false - - - - false - / - 777 - true - - - org.jetbrains.kotlinx:kotlinx-html-js:jar - - - - \ No newline at end of file diff --git a/assembly/src/main/assembly/jvm.xml b/assembly/src/main/assembly/jvm.xml deleted file mode 100644 index b99641fa..00000000 --- a/assembly/src/main/assembly/jvm.xml +++ /dev/null @@ -1,20 +0,0 @@ - - jvm - - zip - - false - - - - false - / - 777 - - org.jetbrains.kotlinx:kotlinx-html-jvm - - - - \ No newline at end of file diff --git a/assembly/src/main/assembly/webjar.xml b/assembly/src/main/assembly/webjar.xml deleted file mode 100644 index 9c81d516..00000000 --- a/assembly/src/main/assembly/webjar.xml +++ /dev/null @@ -1,34 +0,0 @@ - - webjar - - jar - - false - - - - false - META-INF/resources/webjars/kotlinx-html/${project.version} - 777 - - org.jetbrains.kotlinx:kotlinx-html-js - - true - - true - unix - false - - **/*.meta.js - **/META-INF/** - **/kotlinx/** - **/kotlinx-html-js/** - **/*.kotlin_file_table - **/*.js.map - - - - - \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..b8d51dfa --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,385 @@ +import kotlinx.html.js.* +import org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsSetupTask +import org.apache.tools.ant.taskdefs.condition.Os + +/** + * This build script supports following parameters: + * -Prelease - activates "release" profile (uploading to Bintray "kotlin/kotlinx.html" without publication and + * publication to npmjs "kotlinx-html"). + * -Pbranch-build - activates "branch-build" profile (publication to Bintray "kotlin/kotlin-dev" and to npmjs + * "@kotlinx-branch-build/kotlinx-html"). + * -Pmaster-build - activates "master-build" profile (publication to OSS Sonatype snapshot repository and to npmjs + * "@kotlinx-master-build/kotlinx-html"). + * -PversionTag - works together with "branch-build" profile and overrides "-SNAPSHOT" suffix of the version. + */ +plugins { + kotlin("multiplatform") version "1.3.61" + id("maven-publish") +} + +group = "org.jetbrains.kotlinx" +version = "0.6.13-SNAPSHOT" + +/** + * If "release" profile is used the "-SNAPSHOT" suffix of the version is removed. + */ +if (hasProperty("release")) { + val versionString = version as String + if (versionString.endsWith("-SNAPSHOT")) { + version = versionString.replace("-SNAPSHOT", "") + } +} + +/** + * Handler of "versionTag" property. + * Required to support Bintray and NPM repositories that doesn't support "-SNAPSHOT" versions. To build and publish + * artifacts with specific version run "./gradlew -PversionTag=my-tag" and the final version will be "0.6.13-my-tag". + */ +if (hasProperty("versionTag")) { + val versionString = version as String + val versionTag = properties["versionTag"] + if (versionString.endsWith("-SNAPSHOT")) { + version = versionString.replace("-SNAPSHOT", "-$versionTag") + logger.lifecycle("Project will be built with version '$version'.") + } else { + error("Could not apply 'versionTag' together with non-snapshot version.") + } +} + +publishing { + publications { + repositories { + when { + hasProperty("release") -> { + maven { + url = uri("https://api.bintray.com/maven/kotlin/kotlinx.html/kotlinx.html;publish=0") + credentials { + username = System.getenv("BINTRAY_USERNAME") + password = System.getenv("BINTRAY_PASSWORD") + } + } + } + hasProperty("branch-build") -> { + require(!(version as String).endsWith("-SNAPSHOT")) { + "Profile 'branch-build' assumes non-snapshot version. Use -PversionTag to fix the build." + } + + maven { + url = uri("https://api.bintray.com/maven/kotlin/kotlin-dev/kotlinx.html/;publish=1") + credentials { + username = System.getenv("BINTRAY_USERNAME") + password = System.getenv("BINTRAY_PASSWORD") + } + } + } + hasProperty("master-build") -> { + require((version as String).endsWith("-SNAPSHOT")) { + "Profile 'master-build' assumes snapshot version. Change the version or use another profile." + } + + maven { + url = uri("https://oss.sonatype.org/content/repositories/snapshots") + credentials { + username = System.getenv("SONATYPE_USERNAME") + password = System.getenv("SONATYPE_PASSWORD") + } + } + } + } + } + + create("kotlinx-html-assembly") { + artifactId = "kotlinx-html-assembly" + jar("jsWebJar") { + archiveBaseName by "${project.name}-assembly" + archiveClassifier by "webjar" + from("$buildDir/js/packages/${project.name}/kotlin/kotlinx-html.js") + into("META-INF/resources/webjars/${project.name}/${project.version}/") + rename("kotlinx-html.js", "kotlinx-html-js.js") + } + } + } +} + +repositories { + jcenter() + mavenCentral() + + when { + /** Allow all profiles but release to use development and SNAPSHOT dependencies. */ + !hasProperty("release") -> { + maven { url = uri("https://dl.bintray.com/kotlin/kotlin-dev") } + maven { + url = uri("https://oss.sonatype.org/content/repositories/snapshots") + mavenContent { + snapshotsOnly() + } + } + } + } +} + +kotlin { + jvm { + compilations["main"].kotlinOptions.apply { + freeCompilerArgs += "-Xdump-declarations-to=${buildDir}/declarations.json" + } + + mavenPublication { + groupId = group as String + pom.config { name by "${project.name}-jvm" } + + javadocJar("jvmJavadocJar") + jar("jvmTestSourcesJar") { + archiveClassifier by "test-sources" + with(sourceSets["jvmTest"]) { + from(kotlin, resources) + } + } + } + } + + js { + browser { + testTask { + useKarma { + useChromeHeadless() + useConfigDirectory("${project.projectDir}/src/jsTest/karma") + } + } + } + + compilations["main"].packageJson { + main = "kotlin/kotlinx-html-js.js" + name = "kotlinx-html-js" + } + + compilations["main"].kotlinOptions.apply { + outputFile = "$buildDir/js/packages/${project.name}/kotlin/${project.name}-js.js" + moduleKind = "umd" + sourceMap = true + sourceMapEmbedSources = "always" + } + + compilations["test"].kotlinOptions.apply { + moduleKind = "umd" + metaInfo = true + sourceMap = true + } + + mavenPublication { + groupId = group as String + pom.config { name by "${project.name}-js" } + + javadocJar("jsJavadocJar") + jar("jsTestSourcesJar") { + archiveClassifier by "test-sources" + with(sourceSets["jsTest"]) { + from(kotlin, resources) + } + } + } + } + + metadata { + mavenPublication { + groupId = group as String + artifactId = "${project.name}-common" + pom.config { name by "${project.name}-common" } + + javadocJar("commonJavadocJar") + jar("commonTestSourcesJar") { + archiveClassifier by "test-sources" + } + } + } +} + +kotlin { + sourceSets { + commonMain { + dependencies { + implementation(kotlin("stdlib-common")) + } + } + + val jsMain by getting { + dependencies { + implementation(kotlin("stdlib-js")) + } + } + + val jsTest by getting { + dependencies { + implementation(kotlin("test-js")) + api(npm("puppeteer", "*")) + } + } + + val jvmMain by getting { + dependencies { + implementation(kotlin("stdlib-jdk8")) + } + } + + val jvmTest by getting { + dependencies { + implementation(kotlin("test-junit")) + /* Jackson is required to parse declarations.json. */ + implementation("com.fasterxml.jackson.core:jackson-core:2.10.1") + implementation("com.fasterxml.jackson.core:jackson-databind:2.10.1") + } + } + } +} + +tasks.withType { + manifest { + attributes += sortedMapOf( + "Built-By" to System.getProperty("user.name"), + "Build-Jdk" to System.getProperty("java.version"), + "Implementation-Vendor" to "JetBrains s.r.o.", + "Implementation-Version" to archiveVersion.get(), + "Created-By" to org.gradle.util.GradleVersion.current() + ) + } +} + +tasks.register("generate") { + group = "source-generation" + description = "Generate tag-handling code using tags description." + + doLast { + kotlinx.html.generate.generate( + "kotlinx.html", + "src/commonMain/kotlin/generated", + "src/jsMain/kotlin/generated" + ) + } +} + +tasks.register("jsPackagePrepare") { + dependsOn("jsMainClasses") + tasks["assemble"].dependsOn(this) + + group = "build" + description = "Assembles NPM package (result is placed into 'build/tmp/jsPackage')." + + val baseTargetDir = "$buildDir/tmp/jsPackage" + + from("README-JS.md") + from("$buildDir/js/packages/${project.name}/kotlin") + into(baseTargetDir) + + rename("README-JS.md", "README.md") + + doLast { + var npmVersion = version as String + if (npmVersion.endsWith("-SNAPSHOT")) { + npmVersion = npmVersion.replace("-SNAPSHOT", "-${System.currentTimeMillis()}") + } + + val organization = when { + project.hasProperty("branch-build") -> "kotlinx-branch-build" + project.hasProperty("master-build") -> "kotlinx-master-build" + else -> null + } + + File(baseTargetDir, "package.json").writeText(packageJson(npmVersion, organization)) + file("$baseTargetDir/kotlinx-html-js").renameTo(File("$buildDir/js-module/kotlinx-html-js")) + } +} + +tasks.register("publishNpm") { + dependsOn("jsPackagePrepare") + dependsOn("kotlinNodeJsSetup") + + group = "publishing" + description = "Publishes ${project.name} NPM module to 'registry.npmjs.org'." + + val kotlinNodeJsSetupTask = tasks["kotlinNodeJsSetup"] as NodeJsSetupTask + + // For some unknown reason, the node distributive's structure is different on Windows and UNIX. + val node = if (Os.isFamily(Os.FAMILY_WINDOWS)) { + kotlinNodeJsSetupTask.destination + .resolve("node.exe") + } else { + kotlinNodeJsSetupTask.destination + .resolve("bin") + .resolve("node") + } + + val npm = if (Os.isFamily(Os.FAMILY_WINDOWS)) { + kotlinNodeJsSetupTask.destination + .resolve("node_modules") + .resolve("npm") + .resolve("bin") + .resolve("npm-cli.js") + } else { + kotlinNodeJsSetupTask.destination + .resolve("lib") + .resolve("node_modules") + .resolve("npm") + .resolve("bin") + .resolve("npm-cli.js") + } + + commandLine( + node, + npm, + "publish", + "$buildDir/tmp/jsPackage", + "--//registry.npmjs.org/:_authToken=${System.getenv("NPMJS_AUTH")}", + "--access=public" + ) +} + +typealias MavenPomFile = org.gradle.api.publish.maven.MavenPom + +fun MavenPomFile.config(config: MavenPomFile.() -> Unit = {}) { + config() + + url by "https://github.com/Kotlin/kotlinx.html" + + licenses { + license { + name by "The Apache License, Version 2.0" + url by "https://www.apache.org/licenses/LICENSE-2.0.txt" + } + } + + scm { + connection by "scm:git:git@github.com:Kotlin/kotlinx.html.git" + url by "https://github.com/Kotlin/kotlinx.html" + tag by "HEAD" + } + + developers { + developer { + name by "Sergey Mashkov" + organization by "JetBrains s.r.o." + roles to "developer" + } + + developer { + name by "Anton Dmitriev" + organization by "JetBrains s.r.o." + roles to "developer" + } + } +} + +tasks.withType { + enabled = false +} + +fun MavenPublication.jar(taskName: String, config: Action) = artifact(tasks.create(taskName, Jar::class, config)) + +fun MavenPublication.javadocJar(taskName: String, config: Jar.() -> Unit = {}) = jar(taskName) { + archiveClassifier by "javadoc" + config() +} + +infix fun Property.by(value: T) { + set(value) +} diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 00000000..60a2d25e --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,13 @@ +plugins { + kotlin("jvm") version "1.3.61" +} + +repositories { + jcenter() + mavenCentral() +} + +dependencies { + implementation(kotlin("stdlib-jdk8")) + implementation("com.sun.xsom:xsom:20140925") +} \ No newline at end of file diff --git a/generate/src/main/kotlin/attributes.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/attributes.kt similarity index 100% rename from generate/src/main/kotlin/attributes.kt rename to buildSrc/src/main/kotlin/kotlinx/html/generate/attributes.kt diff --git a/generate/src/main/kotlin/codegen.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/codegen.kt similarity index 99% rename from generate/src/main/kotlin/codegen.kt rename to buildSrc/src/main/kotlin/kotlinx/html/generate/codegen.kt index b18ff41f..28a81942 100644 --- a/generate/src/main/kotlin/codegen.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/codegen.kt @@ -1,6 +1,5 @@ package kotlinx.html.generate -import kotlinx.html.generate.humanize.humanize import java.util.ArrayList interface Const diff --git a/generate/src/main/kotlin/enums.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/enums.kt similarity index 97% rename from generate/src/main/kotlin/enums.kt rename to buildSrc/src/main/kotlin/kotlinx/html/generate/enums.kt index e31f3335..f81e0d6f 100644 --- a/generate/src/main/kotlin/enums.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/enums.kt @@ -1,7 +1,5 @@ package kotlinx.html.generate -import kotlinx.html.generate.humanize.humanize - val reservedNames = setOf("class", "val", "var", "object", "true", "false", "as", "is", "for") fun String.replaceIfReserved() = if (this in reservedNames) "html" + this.capitalize() else this diff --git a/generate/src/main/kotlin/humanizer.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/humanizer.kt similarity index 98% rename from generate/src/main/kotlin/humanizer.kt rename to buildSrc/src/main/kotlin/kotlinx/html/generate/humanizer.kt index f6c20a68..3c709217 100644 --- a/generate/src/main/kotlin/humanizer.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/humanizer.kt @@ -1,6 +1,4 @@ -package kotlinx.html.generate.humanize - -import kotlinx.html.generate.* +package kotlinx.html.generate fun String.humanize() : String { if (this.isEmpty()) { diff --git a/generate/src/main/kotlin/kdoc.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/kdoc.kt similarity index 74% rename from generate/src/main/kotlin/kdoc.kt rename to buildSrc/src/main/kotlin/kotlinx/html/generate/kdoc.kt index 5049bb0f..2904abf8 100644 --- a/generate/src/main/kotlin/kdoc.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/kdoc.kt @@ -1,11 +1,12 @@ -import kotlinx.html.generate.TagInfo +package kotlinx.html.generate + import org.w3c.dom.Node import org.w3c.dom.NodeList -import java.io.File +import java.net.URL import javax.xml.parsers.DocumentBuilderFactory -private val HTML_TABLE_PATH = "generate/src/main/resources/htmltable.xml" -private val HTML5_TABLE_PATH = "generate/src/main/resources/html5table.xml" +private val HTML_TABLE_URL = "htmltable.xml".asResourceUrl() +private val HTML5_TABLE_URL = "html5table.xml".asResourceUrl() object KdocRepository { lateinit var tags: Map @@ -18,14 +19,14 @@ fun fillKdocRepositoryExtension() { val TagInfo.kdoc: KDocInfo? get() = KdocRepository.tags[this.name.toLowerCase()] private fun parseDocInfos(): Map { - val html = parseDocInfo(HTML_TABLE_PATH) - val html5 = parseDocInfo(HTML5_TABLE_PATH) + val html = parseDocInfo(HTML_TABLE_URL) + val html5 = parseDocInfo(HTML5_TABLE_URL) return (html + html5).map { it.name to it }.toMap() } -private fun parseDocInfo(xmlPath: String): List { - val xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(File(xmlPath)) +private fun parseDocInfo(xmlPath: URL): List { + val xml = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlPath.openStream()) xml.documentElement.normalize() return xml.getElementsByTagName("tag").asList().map { node -> diff --git a/generate/src/main/kotlin/main.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt similarity index 94% rename from generate/src/main/kotlin/main.kt rename to buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt index 4ab6a516..01a7844d 100644 --- a/generate/src/main/kotlin/main.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt @@ -1,16 +1,13 @@ package kotlinx.html.generate -import fillKdocRepositoryExtension -import java.io.* +import java.io.File +import java.io.FileOutputStream +import java.io.InputStreamReader - -fun main(args: Array) { +fun generate(packg: String, todir: String, jsdir: String) { fillRepository() fillKdocRepositoryExtension() - val packg = "kotlinx.html" - val todir = "shared/src/main/kotlin/generated" - val jsdir = "js/src/main/kotlin/generated" File(todir).mkdirs() File(jsdir).mkdirs() @@ -267,13 +264,15 @@ fun main(args: Array) { append("enum ") clazz(Clazz(name = "Entities")) { - File("generate/src/main/resources/entities.txt").readLines().filter { it.isNotEmpty() }.forEachIndexed { idx, ent -> - if (idx > 0) { - append(",") + InputStreamReader("entities.txt".asResourceUrl().openStream()).useLines { lines -> + lines.filter { it.isNotEmpty() }.forEachIndexed { idx, ent -> + if (idx > 0) { + append(",") + } + indent() + append(ent) + emptyLine() } - indent() - append(ent) - emptyLine() } append(";") diff --git a/generate/src/main/kotlin/model.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/model.kt similarity index 97% rename from generate/src/main/kotlin/model.kt rename to buildSrc/src/main/kotlin/kotlinx/html/generate/model.kt index e4893968..e64f43ab 100644 --- a/generate/src/main/kotlin/model.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/model.kt @@ -1,9 +1,7 @@ package kotlinx.html.generate -import kotlinx.html.generate.humanize.* import java.util.* import kotlin.collections.HashMap -import kotlin.comparisons.thenComparator object Repository { val tags = TreeMap() diff --git a/generate/src/main/kotlin/parent-ifaces-gen.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/parent-ifaces-gen.kt similarity index 98% rename from generate/src/main/kotlin/parent-ifaces-gen.kt rename to buildSrc/src/main/kotlin/kotlinx/html/generate/parent-ifaces-gen.kt index 63e1b4d8..be361d11 100644 --- a/generate/src/main/kotlin/parent-ifaces-gen.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/parent-ifaces-gen.kt @@ -1,6 +1,5 @@ package kotlinx.html.generate -import kotlinx.html.generate.humanize.* import java.io.* import java.util.* diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/resource-loader.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/resource-loader.kt new file mode 100644 index 00000000..df408632 --- /dev/null +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/resource-loader.kt @@ -0,0 +1,8 @@ +package kotlinx.html.generate + +import java.net.URL + +private class ResourceLoader + +internal fun String.asResourceUrl(): URL = ResourceLoader::class.java.classLoader.getResource(this) + ?: throw IllegalArgumentException("Resource $this not found in classpath.") \ No newline at end of file diff --git a/generate/src/main/kotlin/rules.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/rules.kt similarity index 95% rename from generate/src/main/kotlin/rules.kt rename to buildSrc/src/main/kotlin/kotlinx/html/generate/rules.kt index 777f1f4d..b101d9cd 100644 --- a/generate/src/main/kotlin/rules.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/rules.kt @@ -1,322 +1,322 @@ -package kotlinx.html.generate - -import java.util.regex.Pattern - -val globalSuggestedAttributes = listOf( - "a" to "href", - "a" to "target", - "img" to "src", - "script" to "type", - "script" to "src", - "div" to "class", - "span" to "class", - "meta" to "name", - "meta" to "content", - "meta" to "charset", - "i" to "class", - "input" to "type", - "input" to "name", - "button" to "name", - "link" to "rel", - "link" to "href", - "link" to "type", - "style" to "type", - "head" to "-class", - "html" to "-class", - "link" to "-class", - "script" to "-class", - "style" to "-class", - "meta" to "-class", - "title" to "-class" -).groupBy { it.first }.mapValues { it.value.map { it.second } } - -val tagNamespaces = mapOf( - "svg" to "http://www.w3.org/2000/svg" -) - -val tagsWithCustomizableNamespace = setOf("html") - -val renames = mapOf( - "CommonAttributeGroupFacadePhrasingContent" to "HtmlInlineTag", - "CommonAttributeGroupFacadeFlowContent" to "HtmlBlockTag", - "CommonAttributeGroupFacadeMetaDataContent" to "HtmlHeadTag", - "CommonAttributeGroupFacadeFlowPhrasingContent" to "HtmlBlockInlineTag" -) - -val tagIgnoreList = setOf( - "menu", "menuitem" -) - -fun Iterable.filterIgnored() = filter { it.name.toLowerCase() !in tagIgnoreList } - -val globalSuggestedAttributeNames = setOf("class") - -val specialTypes = listOf( - "*.class" to AttributeType.STRING_SET -).groupBy { it.first }.mapValues { it.value.single().second } - -fun specialTypeFor(tagName: String, attributeName: String): AttributeType? = - specialTypes[tagName + "." + attributeName] ?: specialTypes["*." + attributeName] - -val wellKnownWords = listOf("span", "class", "enabled?", "edit(able)?", - "^on", "encoded?", "form", "type", - "run", "href", "drag(gable)?", - "over", "mouse", - "start(ed)?", "legend", "end(ed)?", "stop", "key", "load(ed)?", "check(ed)?", - "time", "ready", "content", "changed?", - "click", "play(ing)?", "context", - "rows?", "cols?", "group(ed)?", "auto", - "list", "field", "data", "block", "scripts?", - "item", "area", "length", "colors?", "suspend", "focus", "touch" -).map { it.toRegex(RegexOption.IGNORE_CASE) } - -val excludeAttributes = listOf("^item$").map { Pattern.compile(it, Pattern.CASE_INSENSITIVE) } -fun isAttributeExcluded(name: String) = excludeAttributes.any { it.matcher(name).find() } - -val excludedEnums = listOf("Lang$").map { it.toRegex(RegexOption.IGNORE_CASE) } -fun isEnumExcluded(name: String) = excludedEnums.any { it.containsMatchIn(name) } - -val contentlessTags = setOf("html", "head", "script", "style") - -val deprecated = listOf(".*FormMethod#(put|patch|delete)" to "method is not allowed in browsers") - .map { it.first.toRegex(RegexOption.IGNORE_CASE) to it.second } - -fun findEnumDeprecation(attribute: AttributeInfo, value: AttributeEnumValue): String? { - return deprecated.firstOrNull { p -> p.first.matches("""${attribute.enumTypeName}#${value.realName}""") }?.second -} - -val knownTagClasses = """ -HTMLElement -HTMLUnknownElement -HTMLHtmlElement -HTMLHeadElement -HTMLTitleElement -HTMLBaseElement -HTMLLinkElement -HTMLMetaElement -HTMLStyleElement -HTMLBodyElement -HTMLHeadingElement -HTMLParagraphElement -HTMLHRElement -HTMLPreElement -HTMLQuoteElement -HTMLOListElement -HTMLUListElement -HTMLLIElement -HTMLDListElement -HTMLDivElement -HTMLAnchorElement -HTMLDataElement -HTMLTimeElement -HTMLSpanElement -HTMLBRElement -HTMLModElement -HTMLIFrameElement -HTMLEmbedElement -HTMLObjectElement -HTMLParamElement -HTMLVideoElement -HTMLAudioElement -HTMLSourceElement -HTMLTrackElement -HTMLMediaElement -HTMLMapElement -HTMLAreaElement -HTMLTableElement -HTMLTableCaptionElement -HTMLTableColElement -HTMLTableSectionElement -HTMLTableRowElement -HTMLTableDataCellElement -HTMLTableHeaderCellElement -HTMLTableCellElement -HTMLFormElement -HTMLLabelElement -HTMLInputElement -HTMLButtonElement -HTMLSelectElement -HTMLDataListElement -HTMLOptGroupElement -HTMLOptionElement -HTMLTextAreaElement -HTMLKeygenElement -HTMLOutputElement -HTMLProgressElement -HTMLMeterElement -HTMLFieldSetElement -HTMLLegendElement -HTMLDetailsElement -HTMLMenuElement -HTMLMenuItemElement -HTMLDialogElement -HTMLScriptElement -HTMLTemplateElement -HTMLCanvasElement -HTMLAppletElement -HTMLMarqueeElement -HTMLFrameSetElement -HTMLFrameElement -HTMLAnchorElement -HTMLAreaElement -HTMLBodyElement -HTMLBRElement -HTMLTableCaptionElement -HTMLTableColElement -HTMLDirectoryElement -HTMLDivElement -HTMLDListElement -HTMLEmbedElement -HTMLFontElement -HTMLHeadingElement -HTMLHRElement -HTMLHtmlElement -HTMLIFrameElement -HTMLImageElement -HTMLInputElement -HTMLLegendElement -HTMLLIElement -HTMLLinkElement -HTMLMenuElement -HTMLMetaElement -HTMLObjectElement -HTMLOListElement -HTMLParagraphElement -HTMLParamElement -HTMLPreElement -HTMLScriptElement -HTMLTableElement -HTMLTableSectionElement -HTMLTableCellElement -HTMLTableDataCellElement -HTMLTableRowElement -HTMLUListElement -HTMLElement -HTMLUnknownElement -HTMLHtmlElement -HTMLHeadElement -HTMLTitleElement -HTMLBaseElement -HTMLLinkElement -HTMLMetaElement -HTMLStyleElement -HTMLBodyElement -HTMLHeadingElement -HTMLParagraphElement -HTMLHRElement -HTMLPreElement -HTMLQuoteElement -HTMLOListElement -HTMLUListElement -HTMLLIElement -HTMLDListElement -HTMLDivElement -HTMLAnchorElement -HTMLDataElement -HTMLTimeElement -HTMLSpanElement -HTMLBRElement -HTMLModElement -HTMLPictureElement -HTMLSourceElement -HTMLImageElement -HTMLIFrameElement -HTMLEmbedElement -HTMLObjectElement -HTMLParamElement -HTMLVideoElement -HTMLAudioElement -HTMLSourceElement -HTMLTrackElement -HTMLMediaElement -HTMLMapElement -HTMLAreaElement -HTMLTableElement -HTMLTableCaptionElement -HTMLTableColElement -HTMLTableSectionElement -HTMLTableRowElement -HTMLTableDataCellElement -HTMLTableHeaderCellElement -HTMLTableCellElement -HTMLFormElement -HTMLLabelElement -HTMLInputElement -HTMLButtonElement -HTMLSelectElement -HTMLDataListElement -HTMLOptGroupElement -HTMLOptionElement -HTMLTextAreaElement -HTMLKeygenElement -HTMLOutputElement -HTMLProgressElement -HTMLMeterElement -HTMLFieldSetElement -HTMLLegendElement -HTMLDetailsElement -HTMLMenuElement -HTMLMenuItemElement -HTMLDialogElement -HTMLScriptElement -HTMLTemplateElement -HTMLCanvasElement -HTMLAppletElement -HTMLMarqueeElement -HTMLFrameSetElement -HTMLFrameElement -HTMLAnchorElement -HTMLAreaElement -HTMLBodyElement -HTMLBRElement -HTMLTableCaptionElement -HTMLTableColElement -HTMLDirectoryElement -HTMLDivElement -HTMLDListElement -HTMLEmbedElement -HTMLFontElement -HTMLHeadingElement -HTMLHRElement -HTMLHtmlElement -HTMLIFrameElement -HTMLImageElement -HTMLInputElement -HTMLLegendElement -HTMLLIElement -HTMLLinkElement -HTMLMenuElement -HTMLMetaElement -HTMLObjectElement -HTMLOListElement -HTMLParagraphElement -HTMLParamElement -HTMLPreElement -HTMLScriptElement -HTMLTableElement -HTMLTableSectionElement -HTMLTableCellElement -HTMLTableDataCellElement -HTMLTableRowElement -HTMLUListElement -""".split("\\s+".toRegex()).toSet() - -val tagReplacements = listOf( - "img" to "image", - "h\\d" to "heading", - "p" to "paragraph", - "a" to "anchor", - "blockquote" to "quote", - "td" to "TableCell", - "tr" to "TableRow", - "th" to "TableCell", - "col" to "TableCol", - "colGroup" to "TableCol", - "thead" to "TableSection", - "tbody" to "TableSection", - "tfoot" to "TableSection" -) - -val attributeReplacements = listOf( - "class" to "classes" +package kotlinx.html.generate + +import java.util.regex.Pattern + +val globalSuggestedAttributes = listOf( + "a" to "href", + "a" to "target", + "img" to "src", + "script" to "type", + "script" to "src", + "div" to "class", + "span" to "class", + "meta" to "name", + "meta" to "content", + "meta" to "charset", + "i" to "class", + "input" to "type", + "input" to "name", + "button" to "name", + "link" to "rel", + "link" to "href", + "link" to "type", + "style" to "type", + "head" to "-class", + "html" to "-class", + "link" to "-class", + "script" to "-class", + "style" to "-class", + "meta" to "-class", + "title" to "-class" +).groupBy { it.first }.mapValues { it.value.map { it.second } } + +val tagNamespaces = mapOf( + "svg" to "http://www.w3.org/2000/svg" +) + +val tagsWithCustomizableNamespace = setOf("html") + +val renames = mapOf( + "CommonAttributeGroupFacadePhrasingContent" to "HtmlInlineTag", + "CommonAttributeGroupFacadeFlowContent" to "HtmlBlockTag", + "CommonAttributeGroupFacadeMetaDataContent" to "HtmlHeadTag", + "CommonAttributeGroupFacadeFlowPhrasingContent" to "HtmlBlockInlineTag" +) + +val tagIgnoreList = setOf( + "menu", "menuitem" +) + +fun Iterable.filterIgnored() = filter { it.name.toLowerCase() !in tagIgnoreList } + +val globalSuggestedAttributeNames = setOf("class") + +val specialTypes = listOf( + "*.class" to AttributeType.STRING_SET +).groupBy { it.first }.mapValues { it.value.single().second } + +fun specialTypeFor(tagName: String, attributeName: String): AttributeType? = + specialTypes[tagName + "." + attributeName] ?: specialTypes["*." + attributeName] + +val wellKnownWords = listOf("span", "class", "enabled?", "edit(able)?", + "^on", "encoded?", "form", "type", + "run", "href", "drag(gable)?", + "over", "mouse", + "start(ed)?", "legend", "end(ed)?", "stop", "key", "load(ed)?", "check(ed)?", + "time", "ready", "content", "changed?", + "click", "play(ing)?", "context", + "rows?", "cols?", "group(ed)?", "auto", + "list", "field", "data", "block", "scripts?", + "item", "area", "length", "colors?", "suspend", "focus", "touch" +).map { it.toRegex(RegexOption.IGNORE_CASE) } + +val excludeAttributes = listOf("^item$").map { Pattern.compile(it, Pattern.CASE_INSENSITIVE) } +fun isAttributeExcluded(name: String) = excludeAttributes.any { it.matcher(name).find() } + +val excludedEnums = listOf("Lang$").map { it.toRegex(RegexOption.IGNORE_CASE) } +fun isEnumExcluded(name: String) = excludedEnums.any { it.containsMatchIn(name) } + +val contentlessTags = setOf("html", "head", "script", "style") + +val deprecated = listOf(".*FormMethod#(put|patch|delete)" to "method is not allowed in browsers") + .map { it.first.toRegex(RegexOption.IGNORE_CASE) to it.second } + +fun findEnumDeprecation(attribute: AttributeInfo, value: AttributeEnumValue): String? { + return deprecated.firstOrNull { p -> p.first.matches("""${attribute.enumTypeName}#${value.realName}""") }?.second +} + +val knownTagClasses = """ +HTMLElement +HTMLUnknownElement +HTMLHtmlElement +HTMLHeadElement +HTMLTitleElement +HTMLBaseElement +HTMLLinkElement +HTMLMetaElement +HTMLStyleElement +HTMLBodyElement +HTMLHeadingElement +HTMLParagraphElement +HTMLHRElement +HTMLPreElement +HTMLQuoteElement +HTMLOListElement +HTMLUListElement +HTMLLIElement +HTMLDListElement +HTMLDivElement +HTMLAnchorElement +HTMLDataElement +HTMLTimeElement +HTMLSpanElement +HTMLBRElement +HTMLModElement +HTMLIFrameElement +HTMLEmbedElement +HTMLObjectElement +HTMLParamElement +HTMLVideoElement +HTMLAudioElement +HTMLSourceElement +HTMLTrackElement +HTMLMediaElement +HTMLMapElement +HTMLAreaElement +HTMLTableElement +HTMLTableCaptionElement +HTMLTableColElement +HTMLTableSectionElement +HTMLTableRowElement +HTMLTableDataCellElement +HTMLTableHeaderCellElement +HTMLTableCellElement +HTMLFormElement +HTMLLabelElement +HTMLInputElement +HTMLButtonElement +HTMLSelectElement +HTMLDataListElement +HTMLOptGroupElement +HTMLOptionElement +HTMLTextAreaElement +HTMLKeygenElement +HTMLOutputElement +HTMLProgressElement +HTMLMeterElement +HTMLFieldSetElement +HTMLLegendElement +HTMLDetailsElement +HTMLMenuElement +HTMLMenuItemElement +HTMLDialogElement +HTMLScriptElement +HTMLTemplateElement +HTMLCanvasElement +HTMLAppletElement +HTMLMarqueeElement +HTMLFrameSetElement +HTMLFrameElement +HTMLAnchorElement +HTMLAreaElement +HTMLBodyElement +HTMLBRElement +HTMLTableCaptionElement +HTMLTableColElement +HTMLDirectoryElement +HTMLDivElement +HTMLDListElement +HTMLEmbedElement +HTMLFontElement +HTMLHeadingElement +HTMLHRElement +HTMLHtmlElement +HTMLIFrameElement +HTMLImageElement +HTMLInputElement +HTMLLegendElement +HTMLLIElement +HTMLLinkElement +HTMLMenuElement +HTMLMetaElement +HTMLObjectElement +HTMLOListElement +HTMLParagraphElement +HTMLParamElement +HTMLPreElement +HTMLScriptElement +HTMLTableElement +HTMLTableSectionElement +HTMLTableCellElement +HTMLTableDataCellElement +HTMLTableRowElement +HTMLUListElement +HTMLElement +HTMLUnknownElement +HTMLHtmlElement +HTMLHeadElement +HTMLTitleElement +HTMLBaseElement +HTMLLinkElement +HTMLMetaElement +HTMLStyleElement +HTMLBodyElement +HTMLHeadingElement +HTMLParagraphElement +HTMLHRElement +HTMLPreElement +HTMLQuoteElement +HTMLOListElement +HTMLUListElement +HTMLLIElement +HTMLDListElement +HTMLDivElement +HTMLAnchorElement +HTMLDataElement +HTMLTimeElement +HTMLSpanElement +HTMLBRElement +HTMLModElement +HTMLPictureElement +HTMLSourceElement +HTMLImageElement +HTMLIFrameElement +HTMLEmbedElement +HTMLObjectElement +HTMLParamElement +HTMLVideoElement +HTMLAudioElement +HTMLSourceElement +HTMLTrackElement +HTMLMediaElement +HTMLMapElement +HTMLAreaElement +HTMLTableElement +HTMLTableCaptionElement +HTMLTableColElement +HTMLTableSectionElement +HTMLTableRowElement +HTMLTableDataCellElement +HTMLTableHeaderCellElement +HTMLTableCellElement +HTMLFormElement +HTMLLabelElement +HTMLInputElement +HTMLButtonElement +HTMLSelectElement +HTMLDataListElement +HTMLOptGroupElement +HTMLOptionElement +HTMLTextAreaElement +HTMLKeygenElement +HTMLOutputElement +HTMLProgressElement +HTMLMeterElement +HTMLFieldSetElement +HTMLLegendElement +HTMLDetailsElement +HTMLMenuElement +HTMLMenuItemElement +HTMLDialogElement +HTMLScriptElement +HTMLTemplateElement +HTMLCanvasElement +HTMLAppletElement +HTMLMarqueeElement +HTMLFrameSetElement +HTMLFrameElement +HTMLAnchorElement +HTMLAreaElement +HTMLBodyElement +HTMLBRElement +HTMLTableCaptionElement +HTMLTableColElement +HTMLDirectoryElement +HTMLDivElement +HTMLDListElement +HTMLEmbedElement +HTMLFontElement +HTMLHeadingElement +HTMLHRElement +HTMLHtmlElement +HTMLIFrameElement +HTMLImageElement +HTMLInputElement +HTMLLegendElement +HTMLLIElement +HTMLLinkElement +HTMLMenuElement +HTMLMetaElement +HTMLObjectElement +HTMLOListElement +HTMLParagraphElement +HTMLParamElement +HTMLPreElement +HTMLScriptElement +HTMLTableElement +HTMLTableSectionElement +HTMLTableCellElement +HTMLTableDataCellElement +HTMLTableRowElement +HTMLUListElement +""".split("\\s+".toRegex()).toSet() + +val tagReplacements = listOf( + "img" to "image", + "h\\d" to "heading", + "p" to "paragraph", + "a" to "anchor", + "blockquote" to "quote", + "td" to "TableCell", + "tr" to "TableRow", + "th" to "TableCell", + "col" to "TableCol", + "colGroup" to "TableCol", + "thead" to "TableSection", + "tbody" to "TableSection", + "tfoot" to "TableSection" +) + +val attributeReplacements = listOf( + "class" to "classes" ).map { Pair(it.first.toRegex(), it.second) } \ No newline at end of file diff --git a/generate/src/main/kotlin/tag-builders.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/tag-builders.kt similarity index 100% rename from generate/src/main/kotlin/tag-builders.kt rename to buildSrc/src/main/kotlin/kotlinx/html/generate/tag-builders.kt diff --git a/generate/src/main/kotlin/tag-unions.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/tag-unions.kt similarity index 97% rename from generate/src/main/kotlin/tag-unions.kt rename to buildSrc/src/main/kotlin/kotlinx/html/generate/tag-unions.kt index 479d977d..9dc29273 100644 --- a/generate/src/main/kotlin/tag-unions.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/tag-unions.kt @@ -1,7 +1,5 @@ package kotlinx.html.generate -import kotlinx.html.generate.humanize.* - fun tagUnions() { val groupings = Repository.groupsByTags.filter { it.value.size > 1 } val groups = groupings.values.map { it.map { it.name }.toHashSet() }.distinct().sortedByDescending { it.size } diff --git a/generate/src/main/kotlin/tagsgen.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/tagsgen.kt similarity index 96% rename from generate/src/main/kotlin/tagsgen.kt rename to buildSrc/src/main/kotlin/kotlinx/html/generate/tagsgen.kt index 86e3b5c0..2654a937 100644 --- a/generate/src/main/kotlin/tagsgen.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/tagsgen.kt @@ -1,429 +1,427 @@ -package kotlinx.html.generate - -import kdoc -import kotlinx.html.generate.humanize.* -import java.util.* - -fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { - val parentAttributeIfaces = tag.attributeGroups.map {it.name.capitalize() + "Facade"} - val parentElementIfaces = tag.tagGroupNames.map { it.humanize().capitalize() } - val allParentIfaces = parentAttributeIfaces + parentElementIfaces - val betterParentIfaces = humanizeJoin(allParentIfaces) - - val namespace = tagNamespaces[tag.name.toLowerCase()] - val customizableNamespace = tag.name.toLowerCase() in tagsWithCustomizableNamespace - - val parameters = mutableListOf( - Var("initialAttributes", "Map", false, false, true), - Var("consumer", "TagConsumer<*>", false, true) - ) - val superConstructorArguments = mutableListOf( - tag.name.quote(), - "consumer", - "initialAttributes", - namespace?.quote().toString(), - (tag.name in inlineTags).toString(), - (tag.name in emptyTags).toString() - ) - - if (customizableNamespace) { - parameters.add(Var("namespace", "String?", false, false, true, namespace?.quote() ?: "null")) - superConstructorArguments[3] = "namespace" - } - - appendln("@Suppress(\"unused\")") - clazz(Clazz( - name = tag.className, - variables = parameters, - parents = listOf( - buildString { - functionCall("HTMLTag", superConstructorArguments) - } - ) + when { - allParentIfaces.isNotEmpty() -> listOf(betterParentIfaces).map { renames[it] ?: it } - else -> emptyList() - }, - isOpen = true - )) { - val lowerCasedNames = tag.attributes.map {it.name.toLowerCase()}.toSet() - val attributes = tag.attributes.filter {it.name !in excludeAttributes} - - attributes.filter {!isAttributeExcluded(it.name) }.forEach { attribute -> - if (attribute.name[0].isLowerCase() || attribute.name.toLowerCase() !in lowerCasedNames) { - attributeProperty(attribute) - } - } - - fun contentlessTagDeprecation() { - indent() - appendln("@Deprecated(\"This tag most likely doesn't support text content or requires unsafe content (try unsafe {}\")") - } - - if (tag.name.toLowerCase() in contentlessTags) { - contentlessTagDeprecation() - - indent() - function("unaryPlus", modifiers = listOf("override", "operator"), receiver = "Entities") - block { - indent(2) - append("@Suppress(\"DEPRECATION\") ") - functionCall("entity", listOf("this")) - appendln() - indent() - } - - appendln() - contentlessTagDeprecation() - - indent() - function("unaryPlus", modifiers = listOf("override", "operator"), receiver = "String") - block { - indent(2) - append("@Suppress(\"DEPRECATION\") ") - functionCall("text", listOf("this")) - appendln() - indent() - } - - appendln() - contentlessTagDeprecation() - - indent() - function("text", arguments = listOf(Var("s", "String")), modifiers = listOf("override")) - block { - indent(2) - receiverDot("super") - functionCall("text", listOf("s")) - appendln() - indent() - } - - appendln() - contentlessTagDeprecation() - - indent() - function("text", arguments = listOf(Var("n", "Number")), modifiers = listOf("override")) - block { - indent(2) - receiverDot("super") - functionCall("text", listOf("n")) - appendln() - indent() - } - - appendln() - contentlessTagDeprecation() - - indent() - function("entity", arguments = listOf(Var("e", "Entities")), modifiers = listOf("override")) - block { - indent(2) - receiverDot("super") - functionCall("entity", listOf("e")) - appendln() - indent() - } - } - - emptyLine() - } - - tag.directChildren.map {Repository.tags[it]}.filterNotNull().filterIgnored().forEach { children -> - htmlTagBuilders(tag.className, children) - } - - if (parentElementIfaces.size > 1) { - val commons = tag.tagGroupNames.map {Repository.tagGroups[it]?.tags?.toSet()}.filterNotNull().reduce { a, b -> a.intersect(b) } - if (commons.isNotEmpty()) { - parentElementIfaces.forEach { group -> - variable(Var(name = "as" + group, type = group), receiver = tag.className) - appendln() - getter() - defineIs("this") - emptyLine() - } - } - } - - emptyLine() -} - -internal fun Appendable.tagAttributeVar(attribute: AttributeInfo, receiver: String?, indent: Int = 1): AttributeRequest { - val options = LinkedList>() - - if (attribute.type == AttributeType.ENUM) { - options.add(ReferenceConst(attribute.enumTypeName.decapitalize() + "Values")) - } else if (attribute.type == AttributeType.BOOLEAN && attribute.trueFalse.isNotEmpty()) { - options.addAll(attribute.trueFalse.map(::StringConst)) - } - - val attributeRequest = AttributeRequest(attribute.type, if (attribute.type == AttributeType.ENUM) attribute.enumTypeName else "", options) - Repository.attributeDelegateRequests.add(attributeRequest) - - indent(indent) - variable(Var(attribute.fieldName, attribute.typeName, true), receiver = receiver ?: "") - return attributeRequest -} - -fun probeType(htmlClassName : String) : Boolean = htmlClassName in knownTagClasses - -private fun tagCandidates(tag : TagInfo) = (listOf(tag.memberName) + tagReplacements.map { tag.memberName.replace(it.first.toRegex(), it.second) }).flatMap { listOf(it.capitalize(), it.toUpperCase()) }.distinct() - -fun getTagResultClass(tag: TagInfo) = - tagCandidates(tag) - .map { "HTML${it}Element" } - .firstOrNull { probeType(it) } ?: "HTMLElement" - -fun contentArgumentValue(tag : TagInfo, blockOrContent : Boolean) = when { - tag.name.toLowerCase() in emptyTags -> "block" - blockOrContent -> "block" - else -> "{+content}" -} - -fun Appendable.consumerBuilderJS(tag : TagInfo, blockOrContent : Boolean) { - val resultType = getTagResultClass(tag) - - val constructorArgs = mutableListOf( - buildSuggestedAttributesArgument(tag), - "this" - ) - - if (tag.name.toLowerCase() in tagsWithCustomizableNamespace) { - constructorArgs.add("namespace") - } - - tagKdoc(tag) - htmlDslMarker() - append("public ") - function(tag.memberName, tagBuilderFunctionArguments(tag, blockOrContent), resultType, receiver = "TagConsumer") - defineIs(buildString { - functionCall(tag.className, constructorArgs) - append(".") - functionCall("visitAndFinalize", listOf( - "this", - contentArgumentValue(tag, blockOrContent) - )) - - if (resultType != "HTMLElement") { - append(" as ") - append(resultType) - } - }) -} - -fun Appendable.consumerBuilderShared(tag : TagInfo, blockOrContent : Boolean) { - val constructorArgs = mutableListOf( - buildSuggestedAttributesArgument(tag), - "this" - ) - - if (tag.name.toLowerCase() in tagsWithCustomizableNamespace) { - constructorArgs.add("namespace") - } - - tagKdoc(tag) - htmlDslMarker() - function(tag.memberName, tagBuilderFunctionArguments(tag, blockOrContent), "T", listOf("T", "C : TagConsumer"), "C") - defineIs(buildString { - functionCall(tag.className, constructorArgs) - append(".") - functionCall("visitAndFinalize", listOf( - "this", - contentArgumentValue(tag, blockOrContent) - )) - }) -} - -fun Appendable.htmlTagBuilderMethod(receiver : String, tag : TagInfo, blockOrContent : Boolean) { - val arguments = tagBuilderFunctionArguments(tag, blockOrContent) - - val constructorArgs = mutableListOf( - buildSuggestedAttributesArgument(tag), - "consumer" - ) - - if (tag.name.toLowerCase() in tagsWithCustomizableNamespace) { - constructorArgs.add("namespace") - } - - tagKdoc(tag) - htmlDslMarker() - function(tag.memberName, arguments, "Unit", receiver = receiver) - defineIs(buildString { - functionCall(tag.className, constructorArgs) - append(".") - functionCall("visit", listOf(contentArgumentValue(tag, blockOrContent))) - }) -} - -fun Appendable.htmlTagEnumBuilderMethod(receiver : String, tag : TagInfo, blockOrContent : Boolean, enumAttribute : AttributeInfo, indent : Int) { - require(enumAttribute.enumValues.isNotEmpty()) - - val arguments = tagBuilderFunctionArguments(tag, blockOrContent).filter {it.name != enumAttribute.fieldName} - - enumAttribute.enumValues.forEach { enumValue -> - val deprecation = findEnumDeprecation(enumAttribute, enumValue) - - val constructorArgs = mutableListOf( - buildSuggestedAttributesArgument(tag, mapOf(enumAttribute.fieldName to enumAttribute.typeName + "." + enumValue.fieldName + ".realValue")), - "consumer" - ) - if (tag.name.toLowerCase() in tagsWithCustomizableNamespace) { - constructorArgs.add("namespace") - } - - if (deprecation != null) { - indent(indent) - suppress("DEPRECATION") - } - - indent(indent) - htmlDslMarker() - function(enumValue.fieldName + tag.memberName.capitalize(), arguments, "Unit", receiver = receiver) - defineIs(buildString { - functionCall(tag.className, constructorArgs) - append(".") - functionCall("visit", listOf(contentArgumentValue(tag, blockOrContent))) - }) - } -} - -fun Appendable.indent(stops : Int = 1) { - for (i in 0 until stops) { - append(" ") - } -} - -private fun buildSuggestedAttributesArgument(tag: TagInfo, predefinedValues : Map = emptyMap()) : String = - tag.mergeAttributes().filter {it.name in tag.suggestedAttributes}.map { attribute -> - val name = attribute.fieldName - - val encoded = if (name in predefinedValues) predefinedValues[name] else when (attribute.type) { - AttributeType.STRING -> name - AttributeType.BOOLEAN -> "$name?.booleanEncode()" - AttributeType.ENUM -> "$name?.enumEncode()" - AttributeType.TICKER -> "$name?.tickerEncode(${attribute.name.quote()})" - AttributeType.STRING_SET -> name - } - - "${attribute.name.quote()}, $encoded" - }.let { attributeArgs -> - when (attributeArgs.size) { - 0 -> "emptyMap" - else -> attributeArgs.joinToString(",", "attributesMapOf(", ")") - } - } - -private fun tagBuilderFunctionArguments(tag: TagInfo, blockOrContent : Boolean) : ArrayList { - val arguments = ArrayList() - val customizableNamespace = tag.name.toLowerCase() in tagsWithCustomizableNamespace - val defaultNamespace: String = tagNamespaces[tag.name.toLowerCase()]?.quote().toString() - - tag.mergeAttributes().filter {it.name in tag.suggestedAttributes}.forEach { attribute -> - val type = when (attribute.type) { - AttributeType.STRING_SET -> "String" - else -> attribute.typeName - } - arguments.add(Var(attribute.fieldName, type + "?", defaultValue = "null")) - } - - fun addNamespaceParameter() { - if (customizableNamespace) { - arguments.add(Var("namespace", "String?", false, false, true, defaultNamespace)) - } - } - - fun addBlockParameter() { - arguments.add(Var("block", "${tag.className}.() -> Unit", defaultValue = "{}")) - } - - fun addContentParameter() { - arguments.add(Var("content", "String", defaultValue = "\"\"")) - } - - when { - tag.name.toLowerCase() in emptyTags || blockOrContent -> { - addNamespaceParameter() - addBlockParameter() - } - else -> { - addContentParameter() - addNamespaceParameter() - } - } - - return arguments -} - -private fun Appendable.htmlDslMarker() { - appendln("@HtmlTagMarker") -} - -private fun Appendable.tagKdoc(tag: TagInfo) { - val kdoc = tag.kdoc ?: return - appendln("/**") - appendln(" * ${kdoc.description}") - appendln(" */") -} - -private val inlineTags = """a -abbr -acronym -area -b -base -basefont -bdi -bdo -bgsound -big -br -button -cite -code -command -data -datalist -device -dfn -em -embed -font -i -iframe -img -input -kbd -keygen -label -legend -map -mark -menuitem -meter -object -optgroup -option -output -param -progress -q -rp -rt -ruby -samp -select -small -source -span -strong -sub -summary -sup -textarea -time -track -tt -u -var -wbr""".lines().toSet() +package kotlinx.html.generate + +import java.util.* + +fun Appendable.tagClass(tag : TagInfo, excludeAttributes : Set) { + val parentAttributeIfaces = tag.attributeGroups.map {it.name.capitalize() + "Facade"} + val parentElementIfaces = tag.tagGroupNames.map { it.humanize().capitalize() } + val allParentIfaces = parentAttributeIfaces + parentElementIfaces + val betterParentIfaces = humanizeJoin(allParentIfaces) + + val namespace = tagNamespaces[tag.name.toLowerCase()] + val customizableNamespace = tag.name.toLowerCase() in tagsWithCustomizableNamespace + + val parameters = mutableListOf( + Var("initialAttributes", "Map", false, false, true), + Var("consumer", "TagConsumer<*>", false, true) + ) + val superConstructorArguments = mutableListOf( + tag.name.quote(), + "consumer", + "initialAttributes", + namespace?.quote().toString(), + (tag.name in inlineTags).toString(), + (tag.name in emptyTags).toString() + ) + + if (customizableNamespace) { + parameters.add(Var("namespace", "String?", false, false, true, namespace?.quote() ?: "null")) + superConstructorArguments[3] = "namespace" + } + + appendln("@Suppress(\"unused\")") + clazz(Clazz( + name = tag.className, + variables = parameters, + parents = listOf( + buildString { + functionCall("HTMLTag", superConstructorArguments) + } + ) + when { + allParentIfaces.isNotEmpty() -> listOf(betterParentIfaces).map { renames[it] ?: it } + else -> emptyList() + }, + isOpen = true + )) { + val lowerCasedNames = tag.attributes.map {it.name.toLowerCase()}.toSet() + val attributes = tag.attributes.filter {it.name !in excludeAttributes} + + attributes.filter {!isAttributeExcluded(it.name) }.forEach { attribute -> + if (attribute.name[0].isLowerCase() || attribute.name.toLowerCase() !in lowerCasedNames) { + attributeProperty(attribute) + } + } + + fun contentlessTagDeprecation() { + indent() + appendln("@Deprecated(\"This tag most likely doesn't support text content or requires unsafe content (try unsafe {}\")") + } + + if (tag.name.toLowerCase() in contentlessTags) { + contentlessTagDeprecation() + + indent() + function("unaryPlus", modifiers = listOf("override", "operator"), receiver = "Entities") + block { + indent(2) + append("@Suppress(\"DEPRECATION\") ") + functionCall("entity", listOf("this")) + appendln() + indent() + } + + appendln() + contentlessTagDeprecation() + + indent() + function("unaryPlus", modifiers = listOf("override", "operator"), receiver = "String") + block { + indent(2) + append("@Suppress(\"DEPRECATION\") ") + functionCall("text", listOf("this")) + appendln() + indent() + } + + appendln() + contentlessTagDeprecation() + + indent() + function("text", arguments = listOf(Var("s", "String")), modifiers = listOf("override")) + block { + indent(2) + receiverDot("super") + functionCall("text", listOf("s")) + appendln() + indent() + } + + appendln() + contentlessTagDeprecation() + + indent() + function("text", arguments = listOf(Var("n", "Number")), modifiers = listOf("override")) + block { + indent(2) + receiverDot("super") + functionCall("text", listOf("n")) + appendln() + indent() + } + + appendln() + contentlessTagDeprecation() + + indent() + function("entity", arguments = listOf(Var("e", "Entities")), modifiers = listOf("override")) + block { + indent(2) + receiverDot("super") + functionCall("entity", listOf("e")) + appendln() + indent() + } + } + + emptyLine() + } + + tag.directChildren.map {Repository.tags[it]}.filterNotNull().filterIgnored().forEach { children -> + htmlTagBuilders(tag.className, children) + } + + if (parentElementIfaces.size > 1) { + val commons = tag.tagGroupNames.map {Repository.tagGroups[it]?.tags?.toSet()}.filterNotNull().reduce { a, b -> a.intersect(b) } + if (commons.isNotEmpty()) { + parentElementIfaces.forEach { group -> + variable(Var(name = "as" + group, type = group), receiver = tag.className) + appendln() + getter() + defineIs("this") + emptyLine() + } + } + } + + emptyLine() +} + +internal fun Appendable.tagAttributeVar(attribute: AttributeInfo, receiver: String?, indent: Int = 1): AttributeRequest { + val options = LinkedList>() + + if (attribute.type == AttributeType.ENUM) { + options.add(ReferenceConst(attribute.enumTypeName.decapitalize() + "Values")) + } else if (attribute.type == AttributeType.BOOLEAN && attribute.trueFalse.isNotEmpty()) { + options.addAll(attribute.trueFalse.map(::StringConst)) + } + + val attributeRequest = AttributeRequest(attribute.type, if (attribute.type == AttributeType.ENUM) attribute.enumTypeName else "", options) + Repository.attributeDelegateRequests.add(attributeRequest) + + indent(indent) + variable(Var(attribute.fieldName, attribute.typeName, true), receiver = receiver ?: "") + return attributeRequest +} + +fun probeType(htmlClassName : String) : Boolean = htmlClassName in knownTagClasses + +private fun tagCandidates(tag : TagInfo) = (listOf(tag.memberName) + tagReplacements.map { tag.memberName.replace(it.first.toRegex(), it.second) }).flatMap { listOf(it.capitalize(), it.toUpperCase()) }.distinct() + +fun getTagResultClass(tag: TagInfo) = + tagCandidates(tag) + .map { "HTML${it}Element" } + .firstOrNull { probeType(it) } ?: "HTMLElement" + +fun contentArgumentValue(tag : TagInfo, blockOrContent : Boolean) = when { + tag.name.toLowerCase() in emptyTags -> "block" + blockOrContent -> "block" + else -> "{+content}" +} + +fun Appendable.consumerBuilderJS(tag : TagInfo, blockOrContent : Boolean) { + val resultType = getTagResultClass(tag) + + val constructorArgs = mutableListOf( + buildSuggestedAttributesArgument(tag), + "this" + ) + + if (tag.name.toLowerCase() in tagsWithCustomizableNamespace) { + constructorArgs.add("namespace") + } + + tagKdoc(tag) + htmlDslMarker() + append("public ") + function(tag.memberName, tagBuilderFunctionArguments(tag, blockOrContent), resultType, receiver = "TagConsumer") + defineIs(buildString { + functionCall(tag.className, constructorArgs) + append(".") + functionCall("visitAndFinalize", listOf( + "this", + contentArgumentValue(tag, blockOrContent) + )) + + if (resultType != "HTMLElement") { + append(" as ") + append(resultType) + } + }) +} + +fun Appendable.consumerBuilderShared(tag : TagInfo, blockOrContent : Boolean) { + val constructorArgs = mutableListOf( + buildSuggestedAttributesArgument(tag), + "this" + ) + + if (tag.name.toLowerCase() in tagsWithCustomizableNamespace) { + constructorArgs.add("namespace") + } + + tagKdoc(tag) + htmlDslMarker() + function(tag.memberName, tagBuilderFunctionArguments(tag, blockOrContent), "T", listOf("T", "C : TagConsumer"), "C") + defineIs(buildString { + functionCall(tag.className, constructorArgs) + append(".") + functionCall("visitAndFinalize", listOf( + "this", + contentArgumentValue(tag, blockOrContent) + )) + }) +} + +fun Appendable.htmlTagBuilderMethod(receiver : String, tag : TagInfo, blockOrContent : Boolean) { + val arguments = tagBuilderFunctionArguments(tag, blockOrContent) + + val constructorArgs = mutableListOf( + buildSuggestedAttributesArgument(tag), + "consumer" + ) + + if (tag.name.toLowerCase() in tagsWithCustomizableNamespace) { + constructorArgs.add("namespace") + } + + tagKdoc(tag) + htmlDslMarker() + function(tag.memberName, arguments, "Unit", receiver = receiver) + defineIs(buildString { + functionCall(tag.className, constructorArgs) + append(".") + functionCall("visit", listOf(contentArgumentValue(tag, blockOrContent))) + }) +} + +fun Appendable.htmlTagEnumBuilderMethod(receiver : String, tag : TagInfo, blockOrContent : Boolean, enumAttribute : AttributeInfo, indent : Int) { + require(enumAttribute.enumValues.isNotEmpty()) + + val arguments = tagBuilderFunctionArguments(tag, blockOrContent).filter {it.name != enumAttribute.fieldName} + + enumAttribute.enumValues.forEach { enumValue -> + val deprecation = findEnumDeprecation(enumAttribute, enumValue) + + val constructorArgs = mutableListOf( + buildSuggestedAttributesArgument(tag, mapOf(enumAttribute.fieldName to enumAttribute.typeName + "." + enumValue.fieldName + ".realValue")), + "consumer" + ) + if (tag.name.toLowerCase() in tagsWithCustomizableNamespace) { + constructorArgs.add("namespace") + } + + if (deprecation != null) { + indent(indent) + suppress("DEPRECATION") + } + + indent(indent) + htmlDslMarker() + function(enumValue.fieldName + tag.memberName.capitalize(), arguments, "Unit", receiver = receiver) + defineIs(buildString { + functionCall(tag.className, constructorArgs) + append(".") + functionCall("visit", listOf(contentArgumentValue(tag, blockOrContent))) + }) + } +} + +fun Appendable.indent(stops : Int = 1) { + for (i in 0 until stops) { + append(" ") + } +} + +private fun buildSuggestedAttributesArgument(tag: TagInfo, predefinedValues : Map = emptyMap()) : String = + tag.mergeAttributes().filter {it.name in tag.suggestedAttributes}.map { attribute -> + val name = attribute.fieldName + + val encoded = if (name in predefinedValues) predefinedValues[name] else when (attribute.type) { + AttributeType.STRING -> name + AttributeType.BOOLEAN -> "$name?.booleanEncode()" + AttributeType.ENUM -> "$name?.enumEncode()" + AttributeType.TICKER -> "$name?.tickerEncode(${attribute.name.quote()})" + AttributeType.STRING_SET -> name + } + + "${attribute.name.quote()}, $encoded" + }.let { attributeArgs -> + when (attributeArgs.size) { + 0 -> "emptyMap" + else -> attributeArgs.joinToString(",", "attributesMapOf(", ")") + } + } + +private fun tagBuilderFunctionArguments(tag: TagInfo, blockOrContent : Boolean) : ArrayList { + val arguments = ArrayList() + val customizableNamespace = tag.name.toLowerCase() in tagsWithCustomizableNamespace + val defaultNamespace: String = tagNamespaces[tag.name.toLowerCase()]?.quote().toString() + + tag.mergeAttributes().filter {it.name in tag.suggestedAttributes}.forEach { attribute -> + val type = when (attribute.type) { + AttributeType.STRING_SET -> "String" + else -> attribute.typeName + } + arguments.add(Var(attribute.fieldName, type + "?", defaultValue = "null")) + } + + fun addNamespaceParameter() { + if (customizableNamespace) { + arguments.add(Var("namespace", "String?", false, false, true, defaultNamespace)) + } + } + + fun addBlockParameter() { + arguments.add(Var("block", "${tag.className}.() -> Unit", defaultValue = "{}")) + } + + fun addContentParameter() { + arguments.add(Var("content", "String", defaultValue = "\"\"")) + } + + when { + tag.name.toLowerCase() in emptyTags || blockOrContent -> { + addNamespaceParameter() + addBlockParameter() + } + else -> { + addContentParameter() + addNamespaceParameter() + } + } + + return arguments +} + +private fun Appendable.htmlDslMarker() { + appendln("@HtmlTagMarker") +} + +private fun Appendable.tagKdoc(tag: TagInfo) { + val kdoc = tag.kdoc ?: return + appendln("/**") + appendln(" * ${kdoc.description}") + appendln(" */") +} + +private val inlineTags = """a +abbr +acronym +area +b +base +basefont +bdi +bdo +bgsound +big +br +button +cite +code +command +data +datalist +device +dfn +em +embed +font +i +iframe +img +input +kbd +keygen +label +legend +map +mark +menuitem +meter +object +optgroup +option +output +param +progress +q +rp +rt +ruby +samp +select +small +source +span +strong +sub +summary +sup +textarea +time +track +tt +u +var +wbr""".lines().toSet() diff --git a/generate/src/main/kotlin/xsdparser.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/xsdparser.kt similarity index 96% rename from generate/src/main/kotlin/xsdparser.kt rename to buildSrc/src/main/kotlin/kotlinx/html/generate/xsdparser.kt index 45174786..3bb67a97 100644 --- a/generate/src/main/kotlin/xsdparser.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/xsdparser.kt @@ -1,13 +1,14 @@ package kotlinx.html.generate -import com.sun.xml.xsom.* -import com.sun.xml.xsom.parser.* -import kotlinx.html.generate.humanize.* +import com.sun.xml.xsom.XSAttGroupDecl +import com.sun.xml.xsom.XSAttributeDecl +import com.sun.xml.xsom.XSTerm +import com.sun.xml.xsom.parser.XSOMParser import java.util.* -import javax.xml.parsers.* +import javax.xml.parsers.SAXParserFactory -val SCHEME_URL = "generate/src/main/resources/html_5.xsd" -val HTML_NAMESPACE = "html-5" +val SCHEME_URL = "html_5.xsd".asResourceUrl() +const val HTML_NAMESPACE = "html-5" private fun flattenTerm(term: XSTerm, result: MutableCollection, visitedModelNames: MutableSet) { if (term.isElementDecl) { diff --git a/buildSrc/src/main/kotlin/kotlinx/html/js/package.kt b/buildSrc/src/main/kotlin/kotlinx/html/js/package.kt new file mode 100644 index 00000000..b6618981 --- /dev/null +++ b/buildSrc/src/main/kotlin/kotlinx/html/js/package.kt @@ -0,0 +1,35 @@ +package kotlinx.html.js + +import org.gradle.api.Project + +private const val GITHUB_ORGANIZATION = "Kotlin" +private const val GITHUB_REPOSITORY = "kotlin.html" + +private const val GIT_URL = "git+https://github.com/$GITHUB_ORGANIZATION/$GITHUB_REPOSITORY.git" +private const val GITHUB_BUGS_URL = "https://github.com/$GITHUB_ORGANIZATION/$GITHUB_REPOSITORY/issues" +private const val GITHUB_WIKI_URL = "https://github.com/$GITHUB_ORGANIZATION/$GITHUB_REPOSITORY/wiki" + +fun Project.packageJson(version: String, organization: String? = null): String = """{ + "name": "${organization?.let { "@$it/" } ?: ""}${project.name}", + "version": "$version", + "description": "Library for building HTML in Kotlin", + "main": "${project.name}-js.js", + "repository": { + "type": "git", + "url": "$GIT_URL" + }, + "keywords": [ + "Kotlin", + "Language", + "HTML", + "JavaScript", + "JetBrains" + ], + "author": "JetBrains", + "license": "Apache-2.0", + "bugs": { + "url": "$GITHUB_BUGS_URL" + }, + "homepage": "$GITHUB_WIKI_URL" +} +""" \ No newline at end of file diff --git a/generate/src/main/resources/entities.txt b/buildSrc/src/main/resources/entities.txt similarity index 100% rename from generate/src/main/resources/entities.txt rename to buildSrc/src/main/resources/entities.txt diff --git a/generate/src/main/resources/html5table.xml b/buildSrc/src/main/resources/html5table.xml similarity index 100% rename from generate/src/main/resources/html5table.xml rename to buildSrc/src/main/resources/html5table.xml diff --git a/generate/src/main/resources/html_5.xsd b/buildSrc/src/main/resources/html_5.xsd similarity index 100% rename from generate/src/main/resources/html_5.xsd rename to buildSrc/src/main/resources/html_5.xsd diff --git a/generate/src/main/resources/htmltable.xml b/buildSrc/src/main/resources/htmltable.xml similarity index 100% rename from generate/src/main/resources/htmltable.xml rename to buildSrc/src/main/resources/htmltable.xml diff --git a/generate/src/main/resources/i18Languages.xsd b/buildSrc/src/main/resources/i18Languages.xsd similarity index 100% rename from generate/src/main/resources/i18Languages.xsd rename to buildSrc/src/main/resources/i18Languages.xsd diff --git a/generate/pom.xml b/generate/pom.xml deleted file mode 100644 index 05a7ea58..00000000 --- a/generate/pom.xml +++ /dev/null @@ -1,79 +0,0 @@ - - - - kotlinx-html - org.jetbrains.kotlinx - 0.6.13-SNAPSHOT - - 4.0.0 - - generate - - - - org.jetbrains.kotlin - kotlin-stdlib - - - com.sun.xsom - xsom - 20140925 - - - - - - - kotlin-maven-plugin - org.jetbrains.kotlin - - - - compile - compile - - compile - - - - - test-compile - test-compile - - test-compile - - - - - activate-profile - none - - script - - - - ../scripts/activate-profile.kts - - - - - - - - maven-deploy-plugin - 2.8.2 - - - none - - - - true - - - - - diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..eb12f73a --- /dev/null +++ b/gradle.properties @@ -0,0 +1,2 @@ +# The following property is required to mitigate issue https://github.com/gradle/gradle/issues/11412. +systemProp.org.gradle.internal.publish.checksums.insecure=true \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..5c2d1cf016b3885f6930543d57b744ea8c220a1a GIT binary patch literal 55616 zcmafaW0WS*vSoFbZJS-TZP!<}ZQEV8ZQHihW!tvx>6!c9%-lQoy;&DmfdT@8fB*sl68LLCKtKQ283+jS?^Q-bNq|NIAW8=eB==8_)^)r*{C^$z z{u;{v?IMYnO`JhmPq7|LA_@Iz75S9h~8`iX>QrjrmMeu{>hn4U;+$dor zz+`T8Q0f}p^Ao)LsYq74!W*)&dTnv}E8;7H*Zetclpo2zf_f>9>HT8;`O^F8;M%l@ z57Z8dk34kG-~Wg7n48qF2xwPp;SOUpd1}9Moir5$VSyf4gF)Mp-?`wO3;2x9gYj59oFwG>?Leva43@e(z{mjm0b*@OAYLC`O9q|s+FQLOE z!+*Y;%_0(6Sr<(cxE0c=lS&-FGBFGWd_R<5$vwHRJG=tB&Mi8@hq_U7@IMyVyKkOo6wgR(<% zQw1O!nnQl3T9QJ)Vh=(`cZM{nsEKChjbJhx@UQH+G>6p z;beBQ1L!3Zl>^&*?cSZjy$B3(1=Zyn~>@`!j%5v7IBRt6X`O)yDpVLS^9EqmHxBcisVG$TRwiip#ViN|4( zYn!Av841_Z@Ys=T7w#>RT&iXvNgDq3*d?$N(SznG^wR`x{%w<6^qj&|g})La;iD?`M=p>99p><39r9+e z`dNhQ&tol5)P#;x8{tT47i*blMHaDKqJs8!Pi*F{#)9%USFxTVMfMOy{mp2ZrLR40 z2a9?TJgFyqgx~|j0eA6SegKVk@|Pd|_6P$HvwTrLTK)Re`~%kg8o9`EAE1oAiY5Jgo=H}0*D?tSCn^=SIN~fvv453Ia(<1|s07aTVVtsRxY6+tT3589iQdi^ zC92D$ewm9O6FA*u*{Fe_=b`%q`pmFvAz@hfF@OC_${IPmD#QMpPNo0mE9U=Ch;k0L zZteokPG-h7PUeRCPPYG%H!WswC?cp7M|w42pbtwj!m_&4%hB6MdLQe&}@5-h~! zkOt;w0BbDc0H!RBw;1UeVckHpJ@^|j%FBZlC} zsm?nFOT$`F_i#1_gh4|n$rDe>0md6HvA=B%hlX*3Z%y@a&W>Rq`Fe(8smIgxTGb#8 zZ`->%h!?QCk>v*~{!qp=w?a*};Y**1uH`)OX`Gi+L%-d6{rV?@}MU#qfCU(!hLz;kWH=0A%W7E^pA zD;A%Jg5SsRe!O*0TyYkAHe&O9z*Ij-YA$%-rR?sc`xz_v{>x%xY39!8g#!Z0#03H( z{O=drKfb0cbx1F*5%q81xvTDy#rfUGw(fesh1!xiS2XT;7_wBi(Rh4i(!rR^9=C+- z+**b9;icxfq@<7}Y!PW-0rTW+A^$o*#ZKenSkxLB$Qi$%gJSL>x!jc86`GmGGhai9 zOHq~hxh}KqQHJeN$2U{M>qd*t8_e&lyCs69{bm1?KGTYoj=c0`rTg>pS6G&J4&)xp zLEGIHSTEjC0-s-@+e6o&w=h1sEWWvJUvezID1&exb$)ahF9`(6`?3KLyVL$|c)CjS zx(bsy87~n8TQNOKle(BM^>1I!2-CZ^{x6zdA}qeDBIdrfd-(n@Vjl^9zO1(%2pP9@ zKBc~ozr$+4ZfjmzEIzoth(k?pbI87=d5OfjVZ`Bn)J|urr8yJq`ol^>_VAl^P)>2r)s+*3z5d<3rP+-fniCkjmk=2hTYRa@t zCQcSxF&w%mHmA?!vaXnj7ZA$)te}ds+n8$2lH{NeD4mwk$>xZCBFhRy$8PE>q$wS`}8pI%45Y;Mg;HH+}Dp=PL)m77nKF68FggQ-l3iXlVZuM2BDrR8AQbK;bn1%jzahl0; zqz0(mNe;f~h8(fPzPKKf2qRsG8`+Ca)>|<&lw>KEqM&Lpnvig>69%YQpK6fx=8YFj zHKrfzy>(7h2OhUVasdwKY`praH?>qU0326-kiSyOU_Qh>ytIs^htlBA62xU6xg?*l z)&REdn*f9U3?u4$j-@ndD#D3l!viAUtw}i5*Vgd0Y6`^hHF5R=No7j8G-*$NWl%?t z`7Nilf_Yre@Oe}QT3z+jOUVgYtT_Ym3PS5(D>kDLLas8~F+5kW%~ZYppSrf1C$gL* zCVy}fWpZ3s%2rPL-E63^tA|8OdqKsZ4TH5fny47ENs1#^C`_NLg~H^uf3&bAj#fGV zDe&#Ot%_Vhj$}yBrC3J1Xqj>Y%&k{B?lhxKrtYy;^E9DkyNHk5#6`4cuP&V7S8ce9 zTUF5PQIRO7TT4P2a*4;M&hk;Q7&{(83hJe5BSm=9qt~;U)NTf=4uKUcnxC`;iPJeI zW#~w?HIOM+0j3ptB0{UU{^6_#B*Q2gs;1x^YFey(%DJHNWz@e_NEL?$fv?CDxG`jk zH|52WFdVsZR;n!Up;K;4E$|w4h>ZIN+@Z}EwFXI{w_`?5x+SJFY_e4J@|f8U08%dd z#Qsa9JLdO$jv)?4F@&z_^{Q($tG`?|9bzt8ZfH9P`epY`soPYqi1`oC3x&|@m{hc6 zs0R!t$g>sR@#SPfNV6Pf`a^E?q3QIaY30IO%yKjx#Njj@gro1YH2Q(0+7D7mM~c>C zk&_?9Ye>B%*MA+77$Pa!?G~5tm`=p{NaZsUsOgm6Yzclr_P^2)r(7r%n(0?4B#$e7 z!fP;+l)$)0kPbMk#WOjm07+e?{E)(v)2|Ijo{o1+Z8#8ET#=kcT*OwM#K68fSNo%< zvZFdHrOrr;>`zq!_welWh!X}=oN5+V01WJn7=;z5uo6l_$7wSNkXuh=8Y>`TjDbO< z!yF}c42&QWYXl}XaRr0uL?BNPXlGw=QpDUMo`v8pXzzG(=!G;t+mfCsg8 zJb9v&a)E!zg8|%9#U?SJqW!|oBHMsOu}U2Uwq8}RnWeUBJ>FtHKAhP~;&T4mn(9pB zu9jPnnnH0`8ywm-4OWV91y1GY$!qiQCOB04DzfDDFlNy}S{$Vg9o^AY!XHMueN<{y zYPo$cJZ6f7``tmlR5h8WUGm;G*i}ff!h`}L#ypFyV7iuca!J+C-4m@7*Pmj9>m+jh zlpWbud)8j9zvQ`8-oQF#u=4!uK4kMFh>qS_pZciyq3NC(dQ{577lr-!+HD*QO_zB9 z_Rv<#qB{AAEF8Gbr7xQly%nMA%oR`a-i7nJw95F3iH&IX5hhy3CCV5y>mK4)&5aC*12 zI`{(g%MHq<(ocY5+@OK-Qn-$%!Nl%AGCgHl>e8ogTgepIKOf3)WoaOkuRJQt%MN8W z=N-kW+FLw=1^}yN@*-_c>;0N{-B!aXy#O}`%_~Nk?{e|O=JmU8@+92Q-Y6h)>@omP=9i~ zi`krLQK^!=@2BH?-R83DyFkejZkhHJqV%^} zUa&K22zwz7b*@CQV6BQ9X*RB177VCVa{Z!Lf?*c~PwS~V3K{id1TB^WZh=aMqiws5)qWylK#^SG9!tqg3-)p_o(ABJsC!0;0v36;0tC= z!zMQ_@se(*`KkTxJ~$nIx$7ez&_2EI+{4=uI~dwKD$deb5?mwLJ~ema_0Z z6A8Q$1~=tY&l5_EBZ?nAvn$3hIExWo_ZH2R)tYPjxTH5mAw#3n-*sOMVjpUrdnj1DBm4G!J+Ke}a|oQN9f?!p-TcYej+(6FNh_A? zJ3C%AOjc<8%9SPJ)U(md`W5_pzYpLEMwK<_jgeg-VXSX1Nk1oX-{yHz z-;CW!^2ds%PH{L{#12WonyeK5A=`O@s0Uc%s!@22etgSZW!K<%0(FHC+5(BxsXW@e zAvMWiO~XSkmcz%-@s{|F76uFaBJ8L5H>nq6QM-8FsX08ug_=E)r#DC>d_!6Nr+rXe zzUt30Du_d0oSfX~u>qOVR*BmrPBwL@WhF^5+dHjWRB;kB$`m8|46efLBXLkiF|*W= zg|Hd(W}ZnlJLotYZCYKoL7YsQdLXZ!F`rLqLf8n$OZOyAzK`uKcbC-n0qoH!5-rh&k-`VADETKHxrhK<5C zhF0BB4azs%j~_q_HA#fYPO0r;YTlaa-eb)Le+!IeP>4S{b8&STp|Y0if*`-A&DQ$^ z-%=i73HvEMf_V6zSEF?G>G-Eqn+|k`0=q?(^|ZcqWsuLlMF2!E*8dDAx%)}y=lyMa z$Nn0_f8YN8g<4D>8IL3)GPf#dJYU@|NZqIX$;Lco?Qj=?W6J;D@pa`T=Yh z-ybpFyFr*3^gRt!9NnbSJWs2R-S?Y4+s~J8vfrPd_&_*)HBQ{&rW(2X>P-_CZU8Y9 z-32><7|wL*K+3{ZXE5}nn~t@NNT#Bc0F6kKI4pVwLrpU@C#T-&f{Vm}0h1N3#89@d zgcx3QyS;Pb?V*XAq;3(W&rjLBazm69XX;%^n6r}0!CR2zTU1!x#TypCr`yrII%wk8 z+g)fyQ!&xIX(*>?T}HYL^>wGC2E}euj{DD_RYKK@w=yF+44367X17)GP8DCmBK!xS zE{WRfQ(WB-v>DAr!{F2-cQKHIjIUnLk^D}7XcTI#HyjSiEX)BO^GBI9NjxojYfQza zWsX@GkLc7EqtP8(UM^cq5zP~{?j~*2T^Bb={@PV)DTkrP<9&hxDwN2@hEq~8(ZiF! z3FuQH_iHyQ_s-#EmAC5~K$j_$cw{+!T>dm#8`t%CYA+->rWp09jvXY`AJQ-l%C{SJ z1c~@<5*7$`1%b}n7ivSo(1(j8k+*Gek(m^rQ!+LPvb=xA@co<|(XDK+(tb46xJ4) zcw7w<0p3=Idb_FjQ@ttoyDmF?cT4JRGrX5xl&|ViA@Lg!vRR}p#$A?0=Qe+1)Mizl zn;!zhm`B&9t0GA67GF09t_ceE(bGdJ0mbXYrUoV2iuc3c69e;!%)xNOGG*?x*@5k( zh)snvm0s&gRq^{yyeE)>hk~w8)nTN`8HJRtY0~1f`f9ue%RV4~V(K*B;jFfJY4dBb z*BGFK`9M-tpWzayiD>p_`U(29f$R|V-qEB;+_4T939BPb=XRw~8n2cGiRi`o$2qm~ zN&5N7JU{L*QGM@lO8VI)fUA0D7bPrhV(GjJ$+@=dcE5vAVyCy6r&R#4D=GyoEVOnu z8``8q`PN-pEy>xiA_@+EN?EJpY<#}BhrsUJC0afQFx7-pBeLXR9Mr+#w@!wSNR7vxHy@r`!9MFecB4O zh9jye3iSzL0@t3)OZ=OxFjjyK#KSF|zz@K}-+HaY6gW+O{T6%Zky@gD$6SW)Jq;V0 zt&LAG*YFO^+=ULohZZW*=3>7YgND-!$2}2)Mt~c>JO3j6QiPC-*ayH2xBF)2m7+}# z`@m#q{J9r~Dr^eBgrF(l^#sOjlVNFgDs5NR*Xp;V*wr~HqBx7?qBUZ8w)%vIbhhe) zt4(#1S~c$Cq7b_A%wpuah1Qn(X9#obljoY)VUoK%OiQZ#Fa|@ZvGD0_oxR=vz{>U* znC(W7HaUDTc5F!T77GswL-jj7e0#83DH2+lS-T@_^SaWfROz9btt*5zDGck${}*njAwf}3hLqKGLTeV&5(8FC+IP>s;p{L@a~RyCu)MIa zs~vA?_JQ1^2Xc&^cjDq02tT_Z0gkElR0Aa$v@VHi+5*)1(@&}gEXxP5Xon?lxE@is z9sxd|h#w2&P5uHJxWgmtVZJv5w>cl2ALzri;r57qg){6`urTu(2}EI?D?##g=!Sbh z*L*>c9xN1a3CH$u7C~u_!g81`W|xp=54oZl9CM)&V9~ATCC-Q!yfKD@vp#2EKh0(S zgt~aJ^oq-TM0IBol!w1S2j7tJ8H7;SR7yn4-H}iz&U^*zW95HrHiT!H&E|rSlnCYr z7Y1|V7xebn=TFbkH;>WIH6H>8;0?HS#b6lCke9rSsH%3AM1#2U-^*NVhXEIDSFtE^ z=jOo1>j!c__Bub(R*dHyGa)@3h?!ls1&M)d2{?W5#1|M@6|ENYYa`X=2EA_oJUw=I zjQ)K6;C!@>^i7vdf`pBOjH>Ts$97}B=lkb07<&;&?f#cy3I0p5{1=?O*#8m$C_5TE zh}&8lOWWF7I@|pRC$G2;Sm#IJfhKW@^jk=jfM1MdJP(v2fIrYTc{;e5;5gsp`}X8-!{9{S1{h+)<@?+D13s^B zq9(1Pu(Dfl#&z|~qJGuGSWDT&u{sq|huEsbJhiqMUae}K*g+R(vG7P$p6g}w*eYWn zQ7luPl1@{vX?PMK%-IBt+N7TMn~GB z!Ldy^(2Mp{fw_0;<$dgHAv1gZgyJAx%}dA?jR=NPW1K`FkoY zNDgag#YWI6-a2#&_E9NMIE~gQ+*)i<>0c)dSRUMHpg!+AL;a;^u|M1jp#0b<+#14z z+#LuQ1jCyV_GNj#lHWG3e9P@H34~n0VgP#(SBX=v|RSuOiY>L87 z#KA{JDDj2EOBX^{`a;xQxHtY1?q5^B5?up1akjEPhi1-KUsK|J9XEBAbt%^F`t0I- zjRYYKI4OB7Zq3FqJFBZwbI=RuT~J|4tA8x)(v2yB^^+TYYJS>Et`_&yge##PuQ%0I z^|X!Vtof}`UuIxPjoH8kofw4u1pT5h`Ip}d8;l>WcG^qTe>@x63s#zoJiGmDM@_h= zo;8IZR`@AJRLnBNtatipUvL^(1P_a;q8P%&voqy#R!0(bNBTlV&*W9QU?kRV1B*~I zWvI?SNo2cB<7bgVY{F_CF$7z!02Qxfw-Ew#p!8PC#! z1sRfOl`d-Y@&=)l(Sl4CS=>fVvor5lYm61C!!iF3NMocKQHUYr0%QM}a4v2>rzPfM zUO}YRDb7-NEqW+p_;e0{Zi%0C$&B3CKx6|4BW`@`AwsxE?Vu}@Jm<3%T5O&05z+Yq zkK!QF(vlN}Rm}m_J+*W4`8i~R&`P0&5!;^@S#>7qkfb9wxFv@(wN@$k%2*sEwen$a zQnWymf+#Uyv)0lQVd?L1gpS}jMQZ(NHHCKRyu zjK|Zai0|N_)5iv)67(zDBCK4Ktm#ygP|0(m5tU`*AzR&{TSeSY8W=v5^=Ic`ahxM-LBWO+uoL~wxZmgcSJMUF9q%<%>jsvh9Dnp^_e>J_V=ySx4p?SF0Y zg4ZpZt@!h>WR76~P3_YchYOak7oOzR|`t+h!BbN}?zd zq+vMTt0!duALNWDwWVIA$O=%{lWJEj;5(QD()huhFL5=6x_=1h|5ESMW&S|*oxgF# z-0GRIb ziolwI13hJ-Rl(4Rj@*^=&Zz3vD$RX8bFWvBM{niz(%?z0gWNh_vUvpBDoa>-N=P4c zbw-XEJ@txIbc<`wC883;&yE4ayVh>+N($SJ01m}fumz!#!aOg*;y4Hl{V{b;&ux3& zBEmSq2jQ7#IbVm3TPBw?2vVN z0wzj|Y6EBS(V%Pb+@OPkMvEKHW~%DZk#u|A18pZMmCrjWh%7J4Ph>vG61 zRBgJ6w^8dNRg2*=K$Wvh$t>$Q^SMaIX*UpBG)0bqcvY%*by=$EfZAy{ZOA#^tB(D( zh}T(SZgdTj?bG9u+G{Avs5Yr1x=f3k7%K|eJp^>BHK#~dsG<&+=`mM@>kQ-cAJ2k) zT+Ht5liXdc^(aMi9su~{pJUhe)!^U&qn%mV6PS%lye+Iw5F@Xv8E zdR4#?iz+R4--iiHDQmQWfNre=iofAbF~1oGTa1Ce?hId~W^kPuN(5vhNx++ZLkn?l zUA7L~{0x|qA%%%P=8+-Ck{&2$UHn#OQncFS@uUVuE39c9o~#hl)v#!$X(X*4ban2c z{buYr9!`H2;6n73n^W3Vg(!gdBV7$e#v3qubWALaUEAf@`ava{UTx%2~VVQbEE(*Q8_ zv#me9i+0=QnY)$IT+@3vP1l9Wrne+MlZNGO6|zUVG+v&lm7Xw3P*+gS6e#6mVx~(w zyuaXogGTw4!!&P3oZ1|4oc_sGEa&m3Jsqy^lzUdJ^y8RlvUjDmbC^NZ0AmO-c*&m( zSI%4P9f|s!B#073b>Eet`T@J;3qY!NrABuUaED6M^=s-Q^2oZS`jVzuA z>g&g$!Tc>`u-Q9PmKu0SLu-X(tZeZ<%7F+$j3qOOftaoXO5=4!+P!%Cx0rNU+@E~{ zxCclYb~G(Ci%o{}4PC(Bu>TyX9slm5A^2Yi$$kCq-M#Jl)a2W9L-bq5%@Pw^ zh*iuuAz`x6N_rJ1LZ7J^MU9~}RYh+EVIVP+-62u+7IC%1p@;xmmQ`dGCx$QpnIUtK z0`++;Ddz7{_R^~KDh%_yo8WM$IQhcNOALCIGC$3_PtUs?Y44@Osw;OZ()Lk=(H&Vc zXjkHt+^1@M|J%Q&?4>;%T-i%#h|Tb1u;pO5rKst8(Cv2!3U{TRXdm&>fWTJG)n*q&wQPjRzg%pS1RO9}U0*C6fhUi&f#qoV`1{U<&mWKS<$oVFW>{&*$6)r6Rx)F4W zdUL8Mm_qNk6ycFVkI5F?V+cYFUch$92|8O^-Z1JC94GU+Nuk zA#n3Z1q4<6zRiv%W5`NGk*Ym{#0E~IA6*)H-=RmfWIY%mEC0? zSih7uchi`9-WkF2@z1ev6J_N~u;d$QfSNLMgPVpHZoh9oH-8D*;EhoCr~*kJ<|-VD z_jklPveOxWZq40E!SV@0XXy+~Vfn!7nZ1GXsn~U$>#u0d*f?RL9!NMlz^qxYmz|xt zz6A&MUAV#eD%^GcP#@5}QH5e7AV`}(N2#(3xpc!7dDmgu7C3TpgX5Z|$%Vu8=&SQI zdxUk*XS-#C^-cM*O>k}WD5K81e2ayyRA)R&5>KT1QL!T!%@}fw{>BsF+-pzu>;7{g z^CCSWfH;YtJGT@+An0Ded#zM9>UEFOdR_Xq zS~!5R*{p1Whq62ynHo|n$4p7&d|bal{iGsxAY?opi3R${)Zt*8YyOU!$TWMYXF?|i zPXYr}wJp#EH;keSG5WYJ*(~oiu#GDR>C4%-HpIWr7v`W`lzQN-lb?*vpoit z8FqJ)`LC4w8fO8Fu}AYV`awF2NLMS4$f+?=KisU4P6@#+_t)5WDz@f*qE|NG0*hwO z&gv^k^kC6Fg;5>Gr`Q46C{6>3F(p0QukG6NM07rxa&?)_C*eyU(jtli>9Zh#eUb(y zt9NbC-bp0>^m?i`?$aJUyBmF`N0zQ% zvF_;vLVI{tq%Ji%u*8s2p4iBirv*uD(?t~PEz$CfxVa=@R z^HQu6-+I9w>a35kX!P)TfnJDD!)j8!%38(vWNe9vK0{k*`FS$ABZ`rdwfQe@IGDki zssfXnsa6teKXCZUTd^qhhhUZ}>GG_>F0~LG7*<*x;8e39nb-0Bka(l)%+QZ_IVy3q zcmm2uKO0p)9|HGxk*e_$mX2?->&-MXe`=Fz3FRTFfM!$_y}G?{F9jmNgD+L%R`jM1 zIP-kb=3Hlsb35Q&qo(%Ja(LwQj>~!GI|Hgq65J9^A!ibChYB3kxLn@&=#pr}BwON0Q=e5;#sF8GGGuzx6O}z%u3l?jlKF&8Y#lUA)Cs6ZiW8DgOk|q z=YBPAMsO7AoAhWgnSKae2I7%7*Xk>#AyLX-InyBO?OD_^2^nI4#;G|tBvg3C0ldO0 z*`$g(q^es4VqXH2t~0-u^m5cfK8eECh3Rb2h1kW%%^8A!+ya3OHLw$8kHorx4(vJO zAlVu$nC>D{7i?7xDg3116Y2e+)Zb4FPAdZaX}qA!WW{$d?u+sK(iIKqOE-YM zH7y^hkny24==(1;qEacfFU{W{xSXhffC&DJV&oqw`u~WAl@=HIel>KC-mLs2ggFld zsSm-03=Jd^XNDA4i$vKqJ|e|TBc19bglw{)QL${Q(xlN?E;lPumO~;4w_McND6d+R zsc2p*&uRWd`wTDszTcWKiii1mNBrF7n&LQp$2Z<}zkv=8k2s6-^+#siy_K1`5R+n( z++5VOU^LDo(kt3ok?@$3drI`<%+SWcF*`CUWqAJxl3PAq!X|q{al;8%HfgxxM#2Vb zeBS756iU|BzB>bN2NP=AX&!{uZXS;|F`LLd9F^97UTMnNks_t7EPnjZF`2ocD2*u+ z?oKP{xXrD*AKGYGkZtlnvCuazg6g16ZAF{Nu%w+LCZ+v_*`0R$NK)tOh_c#cze;o$ z)kY(eZ5Viv<5zl1XfL(#GO|2FlXL#w3T?hpj3BZ&OAl^L!7@ zy;+iJWYQYP?$(`li_!|bfn!h~k#=v-#XXyjTLd+_txOqZZETqSEp>m+O0ji7MxZ*W zSdq+yqEmafrsLErZG8&;kH2kbCwluSa<@1yU3^Q#5HmW(hYVR0E6!4ZvH;Cr<$`qf zSvqRc`Pq_9b+xrtN3qLmds9;d7HdtlR!2NV$rZPCh6>(7f7M}>C^LeM_5^b$B~mn| z#)?`E=zeo9(9?{O_ko>51~h|c?8{F=2=_-o(-eRc z9p)o51krhCmff^U2oUi#$AG2p-*wSq8DZ(i!Jmu1wzD*)#%J&r)yZTq`3e|v4>EI- z=c|^$Qhv}lEyG@!{G~@}Wbx~vxTxwKoe9zn%5_Z^H$F1?JG_Kadc(G8#|@yaf2-4< zM1bdQF$b5R!W1f`j(S>Id;CHMzfpyjYEC_95VQ*$U3y5piVy=9Rdwg7g&)%#6;U%b2W}_VVdh}qPnM4FY9zFP(5eR zWuCEFox6e;COjs$1RV}IbpE0EV;}5IP}Oq|zcb*77PEDIZU{;@_;8*22{~JRvG~1t zc+ln^I+)Q*+Ha>(@=ra&L&a-kD;l$WEN;YL0q^GE8+})U_A_StHjX_gO{)N>tx4&F zRK?99!6JqktfeS-IsD@74yuq*aFJoV{5&K(W`6Oa2Qy0O5JG>O`zZ-p7vBGh!MxS;}}h6(96Wp`dci3DY?|B@1p8fVsDf$|0S zfE{WL5g3<9&{~yygYyR?jK!>;eZ2L#tpL2)H#89*b zycE?VViXbH7M}m33{#tI69PUPD=r)EVPTBku={Qh{ zKi*pht1jJ+yRhVE)1=Y()iS9j`FesMo$bjLSqPMF-i<42Hxl6%y7{#vw5YT(C}x0? z$rJU7fFmoiR&%b|Y*pG?7O&+Jb#Z%S8&%o~fc?S9c`Dwdnc4BJC7njo7?3bp#Yonz zPC>y`DVK~nzN^n}jB5RhE4N>LzhCZD#WQseohYXvqp5^%Ns!q^B z&8zQN(jgPS(2ty~g2t9!x9;Dao~lYVujG-QEq{vZp<1Nlp;oj#kFVsBnJssU^p-4% zKF_A?5sRmA>d*~^og-I95z$>T*K*33TGBPzs{OMoV2i+(P6K|95UwSj$Zn<@Rt(g%|iY z$SkSjYVJ)I<@S(kMQ6md{HxAa8S`^lXGV?ktLX!ngTVI~%WW+p#A#XTWaFWeBAl%U z&rVhve#Yse*h4BC4nrq7A1n>Rlf^ErbOceJC`o#fyCu@H;y)`E#a#)w)3eg^{Hw&E7);N5*6V+z%olvLj zp^aJ4`h*4L4ij)K+uYvdpil(Z{EO@u{BcMI&}5{ephilI%zCkBhBMCvOQT#zp|!18 zuNl=idd81|{FpGkt%ty=$fnZnWXxem!t4x{ zat@68CPmac(xYaOIeF}@O1j8O?2jbR!KkMSuix;L8x?m01}|bS2=&gsjg^t2O|+0{ zlzfu5r5_l4)py8uPb5~NHPG>!lYVynw;;T-gk1Pl6PQ39Mwgd2O+iHDB397H)2grN zHwbd>8i%GY>Pfy7;y5X7AN>qGLZVH>N_ZuJZ-`z9UA> zfyb$nbmPqxyF2F;UW}7`Cu>SS%0W6h^Wq5e{PWAjxlh=#Fq+6SiPa-L*551SZKX&w zc9TkPv4eao?kqomkZ#X%tA{`UIvf|_=Y7p~mHZKqO>i_;q4PrwVtUDTk?M7NCssa?Y4uxYrsXj!+k@`Cxl;&{NLs*6!R<6k9$Bq z%grLhxJ#G_j~ytJpiND8neLfvD0+xu>wa$-%5v;4;RYYM66PUab)c9ruUm%d{^s{# zTBBY??@^foRv9H}iEf{w_J%rV<%T1wv^`)Jm#snLTIifjgRkX``x2wV(D6(=VTLL4 zI-o}&5WuwBl~(XSLIn5~{cGWorl#z+=(vXuBXC#lp}SdW=_)~8Z(Vv!#3h2@pdA3d z{cIPYK@Ojc9(ph=H3T7;aY>(S3~iuIn05Puh^32WObj%hVN(Y{Ty?n?Cm#!kGNZFa zW6Ybz!tq|@erhtMo4xAus|H8V_c+XfE5mu|lYe|{$V3mKnb1~fqoFim;&_ZHN_=?t zysQwC4qO}rTi}k8_f=R&i27RdBB)@bTeV9Wcd}Rysvod}7I%ujwYbTI*cN7Kbp_hO z=eU521!#cx$0O@k9b$;pnCTRtLIzv){nVW6Ux1<0@te6`S5%Ew3{Z^9=lbL5$NFvd4eUtK?%zgmB;_I&p`)YtpN`2Im(?jPN<(7Ua_ZWJRF(CChv`(gHfWodK%+joy>8Vaa;H1w zIJ?!kA|x7V;4U1BNr(UrhfvjPii7YENLIm`LtnL9Sx z5E9TYaILoB2nSwDe|BVmrpLT43*dJ8;T@1l zJE)4LEzIE{IN}+Nvpo3=ZtV!U#D;rB@9OXYw^4QH+(52&pQEcZq&~u9bTg63ikW9! z=!_RjN2xO=F+bk>fSPhsjQA;)%M1My#34T`I7tUf>Q_L>DRa=>Eo(sapm>}}LUsN% zVw!C~a)xcca`G#g*Xqo>_uCJTz>LoWGSKOwp-tv`yvfqw{17t`9Z}U4o+q2JGP^&9 z(m}|d13XhYSnEm$_8vH-Lq$A^>oWUz1)bnv|AVn_0FwM$vYu&8+qUg$+qP}nwrykD zwmIF?wr$()X@33oz1@B9zi+?Th^nZnsES)rb@O*K^JL~ZH|pRRk$i0+ohh?Il)y&~ zQaq{}9YxPt5~_2|+r#{k#~SUhO6yFq)uBGtYMMg4h1qddg!`TGHocYROyNFJtYjNe z3oezNpq6%TP5V1g(?^5DMeKV|i6vdBq)aGJ)BRv;K(EL0_q7$h@s?BV$)w31*c(jd z{@hDGl3QdXxS=#?0y3KmPd4JL(q(>0ikTk6nt98ptq$6_M|qrPi)N>HY>wKFbnCKY z%0`~`9p)MDESQJ#A`_>@iL7qOCmCJ(p^>f+zqaMuDRk!z01Nd2A_W^D%~M73jTqC* zKu8u$$r({vP~TE8rPk?8RSjlRvG*BLF}ye~Su%s~rivmjg2F z24dhh6-1EQF(c>Z1E8DWY)Jw#9U#wR<@6J)3hjA&2qN$X%piJ4s={|>d-|Gzl~RNu z##iR(m;9TN3|zh+>HgTI&82iR>$YVoOq$a(2%l*2mNP(AsV=lR^>=tIP-R9Tw!BYnZROx`PN*JiNH>8bG}&@h0_v$yOTk#@1;Mh;-={ZU7e@JE(~@@y0AuETvsqQV@7hbKe2wiWk@QvV=Kz`%@$rN z_0Hadkl?7oEdp5eaaMqBm;#Xj^`fxNO^GQ9S3|Fb#%{lN;1b`~yxLGEcy8~!cz{!! z=7tS!I)Qq%w(t9sTSMWNhoV#f=l5+a{a=}--?S!rA0w}QF!_Eq>V4NbmYKV&^OndM z4WiLbqeC5+P@g_!_rs01AY6HwF7)$~%Ok^(NPD9I@fn5I?f$(rcOQjP+z?_|V0DiN zb}l0fy*el9E3Q7fVRKw$EIlb&T0fG~fDJZL7Qn8*a5{)vUblM)*)NTLf1ll$ zpQ^(0pkSTol`|t~`Y4wzl;%NRn>689mpQrW=SJ*rB;7}w zVHB?&sVa2%-q@ANA~v)FXb`?Nz8M1rHKiZB4xC9<{Q3T!XaS#fEk=sXI4IFMnlRqG+yaFw< zF{}7tcMjV04!-_FFD8(FtuOZx+|CjF@-xl6-{qSFF!r7L3yD()=*Ss6fT?lDhy(h$ zt#%F575$U(3-e2LsJd>ksuUZZ%=c}2dWvu8f!V%>z3gajZ!Dlk zm=0|(wKY`c?r$|pX6XVo6padb9{EH}px)jIsdHoqG^(XH(7}r^bRa8BC(%M+wtcB? z6G2%tui|Tx6C3*#RFgNZi9emm*v~txI}~xV4C`Ns)qEoczZ>j*r zqQCa5k90Gntl?EX!{iWh=1t$~jVoXjs&*jKu0Ay`^k)hC^v_y0xU~brMZ6PPcmt5$ z@_h`f#qnI$6BD(`#IR0PrITIV^~O{uo=)+Bi$oHA$G* zH0a^PRoeYD3jU_k%!rTFh)v#@cq`P3_y=6D(M~GBud;4 zCk$LuxPgJ5=8OEDlnU!R^4QDM4jGni}~C zy;t2E%Qy;A^bz_5HSb5pq{x{g59U!ReE?6ULOw58DJcJy;H?g*ofr(X7+8wF;*3{rx>j&27Syl6A~{|w{pHb zeFgu0E>OC81~6a9(2F13r7NZDGdQxR8T68&t`-BK zE>ZV0*0Ba9HkF_(AwfAds-r=|dA&p`G&B_zn5f9Zfrz9n#Rvso`x%u~SwE4SzYj!G zVQ0@jrLwbYP=awX$21Aq!I%M{x?|C`narFWhp4n;=>Sj!0_J!k7|A0;N4!+z%Oqlk z1>l=MHhw3bi1vT}1!}zR=6JOIYSm==qEN#7_fVsht?7SFCj=*2+Ro}B4}HR=D%%)F z?eHy=I#Qx(vvx)@Fc3?MT_@D))w@oOCRR5zRw7614#?(-nC?RH`r(bb{Zzn+VV0bm zJ93!(bfrDH;^p=IZkCH73f*GR8nDKoBo|!}($3^s*hV$c45Zu>6QCV(JhBW=3(Tpf z=4PT6@|s1Uz+U=zJXil3K(N6;ePhAJhCIo`%XDJYW@x#7Za);~`ANTvi$N4(Fy!K- z?CQ3KeEK64F0@ykv$-0oWCWhYI-5ZC1pDqui@B|+LVJmU`WJ=&C|{I_))TlREOc4* zSd%N=pJ_5$G5d^3XK+yj2UZasg2) zXMLtMp<5XWWfh-o@ywb*nCnGdK{&S{YI54Wh2|h}yZ})+NCM;~i9H@1GMCgYf`d5n zwOR(*EEkE4-V#R2+Rc>@cAEho+GAS2L!tzisLl${42Y=A7v}h;#@71_Gh2MV=hPr0_a% z0!={Fcv5^GwuEU^5rD|sP;+y<%5o9;#m>ssbtVR2g<420(I-@fSqfBVMv z?`>61-^q;M(b3r2z{=QxSjyH=-%99fpvb}8z}d;%_8$$J$qJg1Sp3KzlO_!nCn|g8 zzg8skdHNsfgkf8A7PWs;YBz_S$S%!hWQ@G>guCgS--P!!Ui9#%GQ#Jh?s!U-4)7ozR?i>JXHU$| zg0^vuti{!=N|kWorZNFX`dJgdphgic#(8sOBHQdBkY}Qzp3V%T{DFb{nGPgS;QwnH9B9;-Xhy{? z(QVwtzkn9I)vHEmjY!T3ifk1l5B?%%TgP#;CqG-?16lTz;S_mHOzu#MY0w}XuF{lk z*dt`2?&plYn(B>FFXo+fd&CS3q^hquSLVEn6TMAZ6e*WC{Q2e&U7l|)*W;^4l~|Q= zt+yFlLVqPz!I40}NHv zE2t1meCuGH%<`5iJ(~8ji#VD{?uhP%F(TnG#uRZW-V}1=N%ev&+Gd4v!0(f`2Ar-Y z)GO6eYj7S{T_vxV?5^%l6TF{ygS_9e2DXT>9caP~xq*~oE<5KkngGtsv)sdCC zaQH#kSL%c*gLj6tV)zE6SGq|0iX*DPV|I`byc9kn_tNQkPU%y<`rj zMC}lD<93=Oj+D6Y2GNMZb|m$^)RVdi`&0*}mxNy0BW#0iq!GGN2BGx5I0LS>I|4op z(6^xWULBr=QRpbxIJDK~?h;K#>LwQI4N<8V?%3>9I5l+e*yG zFOZTIM0c3(q?y9f7qDHKX|%zsUF%2zN9jDa7%AK*qrI5@z~IruFP+IJy7!s~TE%V3 z_PSSxXlr!FU|Za>G_JL>DD3KVZ7u&}6VWbwWmSg?5;MabycEB)JT(eK8wg`^wvw!Q zH5h24_E$2cuib&9>Ue&@%Cly}6YZN-oO_ei5#33VvqV%L*~ZehqMe;)m;$9)$HBsM zfJ96Hk8GJyWwQ0$iiGjwhxGgQX$sN8ij%XJzW`pxqgwW=79hgMOMnC|0Q@ed%Y~=_ z?OnjUB|5rS+R$Q-p)vvM(eFS+Qr{_w$?#Y;0Iknw3u(+wA=2?gPyl~NyYa3me{-Su zhH#8;01jEm%r#5g5oy-f&F>VA5TE_9=a0aO4!|gJpu470WIrfGo~v}HkF91m6qEG2 zK4j=7C?wWUMG$kYbIp^+@)<#ArZ$3k^EQxraLk0qav9TynuE7T79%MsBxl3|nRn?L zD&8kt6*RJB6*a7=5c57wp!pg)p6O?WHQarI{o9@3a32zQ3FH8cK@P!DZ?CPN_LtmC6U4F zlv8T2?sau&+(i@EL6+tvP^&=|aq3@QgL4 zOu6S3wSWeYtgCnKqg*H4ifIQlR4hd^n{F+3>h3;u_q~qw-Sh;4dYtp^VYymX12$`? z;V2_NiRt82RC=yC+aG?=t&a81!gso$hQUb)LM2D4Z{)S zI1S9f020mSm(Dn$&Rlj0UX}H@ zv={G+fFC>Sad0~8yB%62V(NB4Z|b%6%Co8j!>D(VyAvjFBP%gB+`b*&KnJ zU8s}&F+?iFKE(AT913mq;57|)q?ZrA&8YD3Hw*$yhkm;p5G6PNiO3VdFlnH-&U#JH zEX+y>hB(4$R<6k|pt0?$?8l@zeWk&1Y5tlbgs3540F>A@@rfvY;KdnVncEh@N6Mfi zY)8tFRY~Z?Qw!{@{sE~vQy)0&fKsJpj?yR`Yj+H5SDO1PBId3~d!yjh>FcI#Ug|^M z7-%>aeyQhL8Zmj1!O0D7A2pZE-$>+-6m<#`QX8(n)Fg>}l404xFmPR~at%$(h$hYD zoTzbxo`O{S{E}s8Mv6WviXMP}(YPZoL11xfd>bggPx;#&pFd;*#Yx%TtN1cp)MuHf z+Z*5CG_AFPwk624V9@&aL0;=@Ql=2h6aJoqWx|hPQQzdF{e7|fe(m){0==hk_!$ou zI|p_?kzdO9&d^GBS1u+$>JE-6Ov*o{mu@MF-?$r9V>i%;>>Fo~U`ac2hD*X}-gx*v z1&;@ey`rA0qNcD9-5;3_K&jg|qvn@m^+t?8(GTF0l#|({Zwp^5Ywik@bW9mN+5`MU zJ#_Ju|jtsq{tv)xA zY$5SnHgHj}c%qlQG72VS_(OSv;H~1GLUAegygT3T-J{<#h}))pk$FjfRQ+Kr%`2ZiI)@$96Nivh82#K@t>ze^H?R8wHii6Pxy z0o#T(lh=V>ZD6EXf0U}sG~nQ1dFI`bx;vivBkYSVkxXn?yx1aGxbUiNBawMGad;6? zm{zp?xqAoogt=I2H0g@826=7z^DmTTLB11byYvAO;ir|O0xmNN3Ec0w%yHO({-%q(go%?_X{LP?=E1uXoQgrEGOfL1?~ zI%uPHC23dn-RC@UPs;mxq6cFr{UrgG@e3ONEL^SoxFm%kE^LBhe_D6+Ia+u0J=)BC zf8FB!0J$dYg33jb2SxfmkB|8qeN&De!%r5|@H@GiqReK(YEpnXC;-v~*o<#JmYuze zW}p-K=9?0=*fZyYTE7A}?QR6}m_vMPK!r~y*6%My)d;x4R?-=~MMLC_02KejX9q6= z4sUB4AD0+H4ulSYz4;6mL8uaD07eXFvpy*i5X@dmx--+9`ur@rcJ5<L#s%nq3MRi4Dpr;#28}dl36M{MkVs4+Fm3Pjo5qSV)h}i(2^$Ty|<7N z>*LiBzFKH30D!$@n^3B@HYI_V1?yM(G$2Ml{oZ}?frfPU+{i|dHQOP^M0N2#NN_$+ zs*E=MXUOd=$Z2F4jSA^XIW=?KN=w6{_vJ4f(ZYhLxvFtPozPJv9k%7+z!Zj+_0|HC zMU0(8`8c`Sa=%e$|Mu2+CT22Ifbac@7Vn*he`|6Bl81j`44IRcTu8aw_Y%;I$Hnyd zdWz~I!tkWuGZx4Yjof(?jM;exFlUsrj5qO=@2F;56&^gM9D^ZUQ!6TMMUw19zslEu zwB^^D&nG96Y+Qwbvgk?Zmkn9%d{+V;DGKmBE(yBWX6H#wbaAm&O1U^ zS4YS7j2!1LDC6|>cfdQa`}_^satOz6vc$BfFIG07LoU^IhVMS_u+N=|QCJao0{F>p z-^UkM)ODJW9#9*o;?LPCRV1y~k9B`&U)jbTdvuxG&2%!n_Z&udT=0mb@e;tZ$_l3bj6d0K2;Ya!&)q`A${SmdG_*4WfjubB)Mn+vaLV+)L5$yD zYSTGxpVok&fJDG9iS8#oMN{vQneO|W{Y_xL2Hhb%YhQJgq7j~X7?bcA|B||C?R=Eo z!z;=sSeKiw4mM$Qm>|aIP3nw36Tbh6Eml?hL#&PlR5xf9^vQGN6J8op1dpLfwFg}p zlqYx$610Zf?=vCbB_^~~(e4IMic7C}X(L6~AjDp^;|=d$`=!gd%iwCi5E9<6Y~z0! zX8p$qprEadiMgq>gZ_V~n$d~YUqqqsL#BE6t9ufXIUrs@DCTfGg^-Yh5Ms(wD1xAf zTX8g52V!jr9TlWLl+whcUDv?Rc~JmYs3haeG*UnV;4bI=;__i?OSk)bF3=c9;qTdP zeW1exJwD+;Q3yAw9j_42Zj9nuvs%qGF=6I@($2Ue(a9QGRMZTd4ZAlxbT5W~7(alP1u<^YY!c3B7QV z@jm$vn34XnA6Gh1I)NBgTmgmR=O1PKp#dT*mYDPRZ=}~X3B8}H*e_;;BHlr$FO}Eq zJ9oWk0y#h;N1~ho724x~d)A4Z-{V%F6#e5?Z^(`GGC}sYp5%DKnnB+i-NWxwL-CuF+^JWNl`t@VbXZ{K3#aIX+h9-{T*+t(b0BM&MymW9AA*{p^&-9 zWpWQ?*z(Yw!y%AoeoYS|E!(3IlLksr@?Z9Hqlig?Q4|cGe;0rg#FC}tXTmTNfpE}; z$sfUYEG@hLHUb$(K{A{R%~%6MQN|Bu949`f#H6YC*E(p3lBBKcx z-~Bsd6^QsKzB0)$FteBf*b3i7CN4hccSa-&lfQz4qHm>eC|_X!_E#?=`M(bZ{$cvU zZpMbr|4omp`s9mrgz@>4=Fk3~8Y7q$G{T@?oE0<(I91_t+U}xYlT{c&6}zPAE8ikT z3DP!l#>}i!A(eGT+@;fWdK#(~CTkwjs?*i4SJVBuNB2$6!bCRmcm6AnpHHvnN8G<| zuh4YCYC%5}Zo;BO1>L0hQ8p>}tRVx~O89!${_NXhT!HUoGj0}bLvL2)qRNt|g*q~B z7U&U7E+8Ixy1U`QT^&W@ZSRN|`_Ko$-Mk^^c%`YzhF(KY9l5))1jSyz$&>mWJHZzHt0Jje%BQFxEV}C00{|qo5_Hz7c!FlJ|T(JD^0*yjkDm zL}4S%JU(mBV|3G2jVWU>DX413;d+h0C3{g3v|U8cUj`tZL37Sf@1d*jpwt4^B)`bK zZdlwnPB6jfc7rIKsldW81$C$a9BukX%=V}yPnaBz|i6(h>S)+Bn44@i8RtBZf0XetH&kAb?iAL zD%Ge{>Jo3sy2hgrD?15PM}X_)(6$LV`&t*D`IP)m}bzM)+x-xRJ zavhA)>hu2cD;LUTvN38FEtB94ee|~lIvk~3MBPzmTsN|7V}Kzi!h&za#NyY zX^0BnB+lfBuW!oR#8G&S#Er2bCVtA@5FI`Q+a-e?G)LhzW_chWN-ZQmjtR

eWu-UOPu^G}|k=o=;ffg>8|Z*qev7qS&oqA7%Z{4Ezb!t$f3& z^NuT8CSNp`VHScyikB1YO{BgaBVJR&>dNIEEBwYkfOkWN;(I8CJ|vIfD}STN z{097)R9iC@6($s$#dsb*4BXBx7 zb{6S2O}QUk>upEfij9C2tjqWy7%%V@Xfpe)vo6}PG+hmuY1Tc}peynUJLLmm)8pshG zb}HWl^|sOPtYk)CD-7{L+l(=F zOp}fX8)|n{JDa&9uI!*@jh^^9qP&SbZ(xxDhR)y|bjnn|K3MeR3gl6xcvh9uqzb#K zYkVjnK$;lUky~??mcqN-)d5~mk{wXhrf^<)!Jjqc zG~hX0P_@KvOKwV=X9H&KR3GnP3U)DfqafBt$e10}iuVRFBXx@uBQ)sn0J%%c<;R+! zQz;ETTVa+ma>+VF%U43w?_F6s0=x@N2(oisjA7LUOM<$|6iE|$WcO67W|KY8JUV_# zg7P9K3Yo-c*;EmbsqT!M4(WT`%9uk+s9Em-yB0bE{B%F4X<8fT!%4??vezaJ(wJhj zfOb%wKfkY3RU}7^FRq`UEbB-#A-%7)NJQwQd1As=!$u#~2vQ*CE~qp`u=_kL<`{OL zk>753UqJVx1-4~+d@(pnX-i zV4&=eRWbJ)9YEGMV53poXpv$vd@^yd05z$$@i5J7%>gYKBx?mR2qGv&BPn!tE-_aW zg*C!Z&!B zH>3J16dTJC(@M0*kIc}Jn}jf=f*agba|!HVm|^@+7A?V>Woo!$SJko*Jv1mu>;d}z z^vF{3u5Mvo_94`4kq2&R2`32oyoWc2lJco3`Ls0Ew4E7*AdiMbn^LCV%7%mU)hr4S3UVJjDLUoIKRQ)gm?^{1Z}OYzd$1?a~tEY ztjXmIM*2_qC|OC{7V%430T?RsY?ZLN$w!bkDOQ0}wiq69){Kdu3SqW?NMC))S}zq^ zu)w!>E1!;OrXO!RmT?m&PA;YKUjJy5-Seu=@o;m4*Vp$0OipBl4~Ub)1xBdWkZ47=UkJd$`Z}O8ZbpGN$i_WtY^00`S8=EHG#Ff{&MU1L(^wYjTchB zMTK%1LZ(eLLP($0UR2JVLaL|C2~IFbWirNjp|^=Fl48~Sp9zNOCZ@t&;;^avfN(NpNfq}~VYA{q%yjHo4D>JB>XEv(~Z!`1~SoY=9v zTq;hrjObE_h)cmHXLJ>LC_&XQ2BgGfV}e#v}ZF}iF97bG`Nog&O+SA`2zsn%bbB309}I$ zYi;vW$k@fC^muYBL?XB#CBuhC&^H)F4E&vw(5Q^PF{7~}(b&lF4^%DQzL0(BVk?lM zTHXTo4?Ps|dRICEiux#y77_RF8?5!1D-*h5UY&gRY`WO|V`xxB{f{DHzBwvt1W==r zdfAUyd({^*>Y7lObr;_fO zxDDw7X^dO`n!PLqHZ`by0h#BJ-@bAFPs{yJQ~Ylj^M5zWsxO_WFHG}8hH>OK{Q)9` zSRP94d{AM(q-2x0yhK@aNMv!qGA5@~2tB;X?l{Pf?DM5Y*QK`{mGA? zjx;gwnR~#Nep12dFk<^@-U{`&`P1Z}Z3T2~m8^J&7y}GaMElsTXg|GqfF3>E#HG=j zMt;6hfbfjHSQ&pN9(AT8q$FLKXo`N(WNHDY!K6;JrHZCO&ISBdX`g8sXvIf?|8 zX$-W^ut!FhBxY|+R49o44IgWHt}$1BuE|6|kvn1OR#zhyrw}4H*~cpmFk%K(CTGYc zNkJ8L$eS;UYDa=ZHWZy`rO`!w0oIcgZnK&xC|93#nHvfb^n1xgxf{$LB`H1ao+OGb zKG_}>N-RHSqL(RBdlc7J-Z$Gaay`wEGJ_u-lo88{`aQ*+T~+x(H5j?Q{uRA~>2R+} zB+{wM2m?$->unwg8-GaFrG%ZmoHEceOj{W21)Mi2lAfT)EQuNVo+Do%nHPuq7Ttt7 z%^6J5Yo64dH671tOUrA7I2hL@HKZq;S#Ejxt;*m-l*pPj?=i`=E~FAXAb#QH+a}-% z#3u^pFlg%p{hGiIp>05T$RiE*V7bPXtkz(G<+^E}Risi6F!R~Mbf(Qz*<@2&F#vDr zaL#!8!&ughWxjA(o9xtK{BzzYwm_z2t*c>2jI)c0-xo8ahnEqZ&K;8uF*!Hg0?Gd* z=eJK`FkAr>7$_i$;kq3Ks5NNJkNBnw|1f-&Ys56c9Y@tdM3VTTuXOCbWqye9va6+ZSeF0eh} zYb^ct&4lQTfNZ3M3(9?{;s><(zq%hza7zcxlZ+`F8J*>%4wq8s$cC6Z=F@ zhbvdv;n$%vEI$B~B)Q&LkTse!8Vt};7Szv2@YB!_Ztp@JA>rc(#R1`EZcIdE+JiI% zC2!hgYt+~@%xU?;ir+g92W`*j z3`@S;I6@2rO28zqj&SWO^CvA5MeNEhBF+8-U0O0Q1Co=I^WvPl%#}UFDMBVl z5iXV@d|`QTa$>iw;m$^}6JeuW zjr;{)S2TfK0Q%xgHvONSJb#NA|LOmg{U=k;R?&1tQbylMEY4<1*9mJh&(qo`G#9{X zYRs)#*PtEHnO;PV0G~6G`ca%tpKgb6<@)xc^SQY58lTo*S$*sv5w7bG+8YLKYU`8{ zNBVlvgaDu7icvyf;N&%42z2L4(rR<*Jd48X8Jnw zN>!R$%MZ@~Xu9jH?$2Se&I|ZcW>!26BJP?H7og0hT(S`nXh6{sR36O^7%v=31T+eL z)~BeC)15v>1m#(LN>OEwYFG?TE0_z)MrT%3SkMBBjvCd6!uD+03Jz#!s#Y~b1jf>S z&Rz5&8rbLj5!Y;(Hx|UY(2aw~W(8!3q3D}LRE%XX(@h5TnP@PhDoLVQx;6|r^+Bvs zaR55cR%Db9hZ<<|I%dDkone+8Sq7dqPOMnGoHk~-R*#a8w$c)`>4U`k+o?2|E>Sd4 zZ0ZVT{95pY$qKJ54K}3JB!(WcES>F+x56oJBRg))tMJ^#Qc(2rVcd5add=Us6vpBNkIg9b#ulk%!XBU zV^fH1uY(rGIAiFew|z#MM!qsVv%ZNb#why9%9In4Kj-hDYtMdirWLFzn~de!nnH(V zv0>I3;X#N)bo1$dFzqo(tzmvqNUKraAz~?)OSv42MeM!OYu;2VKn2-s7#fucX`|l~ zplxtG1Pgk#(;V=`P_PZ`MV{Bt4$a7;aLvG@KQo%E=;7ZO&Ws-r@XL+AhnPn>PAKc7 zQ_iQ4mXa-a4)QS>cJzt_j;AjuVCp8g^|dIV=DI0>v-f_|w5YWAX61lNBjZEZax3aV znher(j)f+a9_s8n#|u=kj0(unR1P-*L7`{F28xv054|#DMh}q=@rs@-fbyf(2+52L zN>hn3v!I~%jfOV=j(@xLOsl$Jv-+yR5{3pX)$rIdDarl7(C3)})P`QoHN|y<<2n;` zJ0UrF=Zv}d=F(Uj}~Yv9(@1pqUSRa5_bB*AvQ|Z-6YZ*N%p(U z<;Bpqr9iEBe^LFF!t{1UnRtaH-9=@p35fMQJ~1^&)(2D|^&z?m z855r&diVS6}jmt2)A7LZDiv;&Ys6@W5P{JHY!!n7W zvj3(2{1R9Y=TJ|{^2DK&be*ZaMiRHw>WVI^701fC) zAp1?8?oiU%Faj?Qhou6S^d11_7@tEK-XQ~%q!!7hha-Im^>NcRF7OH7s{IO7arZQ{ zE8n?2><7*!*lH}~usWPWZ}2&M+)VQo7C!AWJSQc>8g_r-P`N&uybK5)p$5_o;+58Q z-Ux2l<3i|hxqqur*qAfHq=)?GDchq}ShV#m6&w|mi~ar~`EO_S=fb~<}66U>5i7$H#m~wR;L~4yHL2R&;L*u7-SPdHxLS&Iy76q$2j#Pe)$WulRiCICG*t+ zeehM8`!{**KRL{Q{8WCEFLXu3+`-XF(b?c1Z~wg?c0lD!21y?NLq?O$STk3NzmrHM zsCgQS5I+nxDH0iyU;KKjzS24GJmG?{D`08|N-v+Egy92lBku)fnAM<}tELA_U`)xKYb=pq|hejMCT1-rg0Edt6(*E9l9WCKI1a=@c99swp2t6Tx zFHy`8Hb#iXS(8c>F~({`NV@F4w0lu5X;MH6I$&|h*qfx{~DJ*h5e|61t1QP}tZEIcjC%!Fa)omJTfpX%aI+OD*Y(l|xc0$1Zip;4rx; zV=qI!5tSuXG7h?jLR)pBEx!B15HCoVycD&Z2dlqN*MFQDb!|yi0j~JciNC!>){~ zQQgmZvc}0l$XB0VIWdg&ShDTbTkArryp3x)T8%ulR;Z?6APx{JZyUm=LC-ACkFm`6 z(x7zm5ULIU-xGi*V6x|eF~CN`PUM%`!4S;Uv_J>b#&OT9IT=jx5#nydC4=0htcDme zDUH*Hk-`Jsa>&Z<7zJ{K4AZE1BVW%zk&MZ^lHyj8mWmk|Pq8WwHROz0Kwj-AFqvR)H2gDN*6dzVk>R3@_CV zw3Z@6s^73xW)XY->AFwUlk^4Q=hXE;ckW=|RcZFchyOM0vqBW{2l*QR#v^SZNnT6j zZv|?ZO1-C_wLWVuYORQryj29JA; zS4BsxfVl@X!W{!2GkG9fL4}58Srv{$-GYngg>JuHz!7ZPQbfIQr4@6ZC4T$`;Vr@t zD#-uJ8A!kSM*gA&^6yWi|F}&59^*Rx{qn3z{(JYxrzg!X2b#uGd>&O0e=0k_2*N?3 zYXV{v={ONL{rW~z_FtFj7kSSJZ?s);LL@W&aND7blR8rlvkAb48RwJZlOHA~t~RfC zOD%ZcOzhYEV&s9%qns0&ste5U!^MFWYn`Od()5RwIz6%@Ek+Pn`s79unJY-$7n-Uf z&eUYvtd)f7h7zG_hDiFC!psCg#q&0c=GHKOik~$$>$Fw*k z;G)HS$IR)Cu72HH|JjeeauX;U6IgZ_IfxFCE_bGPAU25$!j8Etsl0Rk@R`$jXuHo8 z3Hhj-rTR$Gq(x)4Tu6;6rHQhoCvL4Q+h0Y+@Zdt=KTb0~wj7-(Z9G%J+aQu05@k6JHeCC|YRFWGdDCV}ja;-yl^9<`>f=AwOqML1a~* z9@cQYb?!+Fmkf}9VQrL8$uyq8k(r8)#;##xG9lJ-B)Fg@15&To(@xgk9SP*bkHlxiy8I*wJQylh(+9X~H-Is!g&C!q*eIYuhl&fS&|w)dAzXBdGJ&Mp$+8D| zZaD<+RtjI90QT{R0YLk6_dm=GfCg>7;$ zlyLsNYf@MfLH<}ott5)t2CXiQos zFLt^`%ygB2Vy^I$W3J_Rt4olRn~Gh}AW(`F@LsUN{d$sR%bU&3;rsD=2KCL+4c`zv zlI%D>9-)U&R3;>d1Vdd5b{DeR!HXDm44Vq*u?`wziLLsFUEp4El;*S0;I~D#TgG0s zBXYZS{o|Hy0A?LVNS)V4c_CFwyYj-E#)4SQq9yaf`Y2Yhk7yHSdos~|fImZG5_3~~o<@jTOH@Mc7`*xn-aO5F zyFT-|LBsm(NbWkL^oB-Nd31djBaYebhIGXhsJyn~`SQ6_4>{fqIjRp#Vb|~+Qi}Mdz!Zsw= zz?5L%F{c{;Cv3Q8ab>dsHp)z`DEKHf%e9sT(aE6$az?A}3P`Lm(~W$8Jr=;d8#?dm_cmv>2673NqAOenze z=&QW`?TQAu5~LzFLJvaJ zaBU3mQFtl5z?4XQDBWNPaH4y)McRpX#$(3o5Nx@hVoOYOL&-P+gqS1cQ~J;~1roGH zVzi46?FaI@w-MJ0Y7BuAg*3;D%?<_OGsB3)c|^s3A{UoAOLP8scn`!5?MFa|^cTvq z#%bYG3m3UO9(sH@LyK9-LSnlVcm#5^NRs9BXFtRN9kBY2mPO|@b7K#IH{B{=0W06) zl|s#cIYcreZ5p3j>@Ly@35wr-q8z5f9=R42IsII=->1stLo@Q%VooDvg@*K(H@*5g zUPS&cM~k4oqp`S+qp^*nxzm^0mg3h8ppEHQ@cXyQ=YKV-6)FB*$KCa{POe2^EHr{J zOxcVd)s3Mzs8m`iV?MSp=qV59blW9$+$P+2;PZDRUD~sr*CQUr&EDiCSfH@wuHez+ z`d5p(r;I7D@8>nbZ&DVhT6qe+accH;<}q$8Nzz|d1twqW?UV%FMP4Y@NQ`3(+5*i8 zP9*yIMP7frrneG3M9 zf>GsjA!O#Bifr5np-H~9lR(>#9vhE6W-r`EjjeQ_wdWp+rt{{L5t5t(Ho|4O24@}4 z_^=_CkbI`3;~sXTnnsv=^b3J}`;IYyvb1gM>#J9{$l#Zd*W!;meMn&yXO7x`Epx_Y zm-1wlu~@Ii_7D}>%tzlXW;zQT=uQXSG@t$<#6-W*^vy7Vr2TCpnix@7!_|aNXEnN<-m?Oq;DpN*x6f>w za1Wa5entFEDtA0SD%iZv#3{wl-S`0{{i3a9cmgNW`!TH{J*~{@|5f%CKy@uk*8~af zt_d34U4y&3y9IZ5cXxLQ?(XjH5?q3Z0KxK~y!-CUyWG6{<)5lkhbox0HnV&7^zNBn zjc|?X!Y=63(Vg>#&Wx%=LUr5{i@~OdzT#?P8xu#P*I_?Jl7xM4dq)4vi}3Wj_c=XI zSbc)@Q2Et4=(nBDU{aD(F&*%Ix!53_^0`+nOFk)}*34#b0Egffld|t_RV91}S0m)0 zap{cQDWzW$geKzYMcDZDAw480!1e1!1Onpv9fK9Ov~sfi!~OeXb(FW)wKx335nNY! za6*~K{k~=pw`~3z!Uq%?MMzSl#s%rZM{gzB7nB*A83XIGyNbi|H8X>a5i?}Rs+z^; z2iXrmK4|eDOu@{MdS+?@(!-Ar4P4?H_yjTEMqm7`rbV4P275(-#TW##v#Dt14Yn9UB-Sg3`WmL0+H~N;iC`Mg%pBl?1AAOfZ&e; z*G=dR>=h_Mz@i;lrGpIOQwezI=S=R8#);d*;G8I(39ZZGIpWU)y?qew(t!j23B9fD z?Uo?-Gx3}6r8u1fUy!u)7LthD2(}boE#uhO&mKBau8W8`XV7vO>zb^ZVWiH-DOjl2 zf~^o1CYVU8eBdmpAB=T%i(=y}!@3N%G-*{BT_|f=egqtucEtjRJJhSf)tiBhpPDpgzOpG12UgvOFnab&16Zn^2ZHjs)pbd&W1jpx%%EXmE^ zdn#R73^BHp3w%&v!0~azw(Fg*TT*~5#dJw%-UdxX&^^(~V&C4hBpc+bPcLRZizWlc zjR;$4X3Sw*Rp4-o+a4$cUmrz05RucTNoXRINYG*DPpzM&;d1GNHFiyl(_x#wspacQ zL)wVFXz2Rh0k5i>?Ao5zEVzT)R(4Pjmjv5pzPrav{T(bgr|CM4jH1wDp6z*_jnN{V ziN56m1T)PBp1%`OCFYcJJ+T09`=&=Y$Z#!0l0J2sIuGQtAr>dLfq5S;{XGJzNk@a^ zk^eHlC4Gch`t+ue3RviiOlhz81CD9z~d|n5;A>AGtkZMUQ#f>5M14f2d}2 z8<*LNZvYVob!p9lbmb!0jt)xn6O&JS)`}7v}j+csS3e;&Awj zoNyjnqLzC(QQ;!jvEYUTy73t_%16p)qMb?ihbU{y$i?=a7@JJoXS!#CE#y}PGMK~3 zeeqqmo7G-W_S97s2eed^erB2qeh4P25)RO1>MH7ai5cZJTEevogLNii=oKG)0(&f` z&hh8cO{of0;6KiNWZ6q$cO(1)9r{`}Q&%p*O0W7N--sw3Us;)EJgB)6iSOg(9p_mc zRw{M^qf|?rs2wGPtjVKTOMAfQ+ZNNkb$Ok0;Pe=dNc7__TPCzw^H$5J0l4D z%p(_0w(oLmn0)YDwrcFsc*8q)J@ORBRoZ54GkJpxSvnagp|8H5sxB|ZKirp%_mQt_ z81+*Y8{0Oy!r8Gmih48VuRPwoO$dDW@h53$C)duL4_(osryhwZSj%~KsZ?2n?b`Z* z#C8aMdZxYmCWSM{mFNw1ov*W}Dl=%GQpp90qgZ{(T}GOS8#>sbiEU;zYvA?=wbD5g+ahbd1#s`=| zV6&f#ofJC261~Ua6>0M$w?V1j##jh-lBJ2vQ%&z`7pO%frhLP-1l)wMs=3Q&?oth1 zefkPr@3Z(&OL@~|<0X-)?!AdK)ShtFJ;84G2(izo3cCuKc{>`+aDoziL z6gLTL(=RYeD7x^FYA%sPXswOKhVa4i(S4>h&mLvS##6-H?w8q!B<8Alk>nQEwUG)SFXK zETfcTwi=R3!ck|hSM`|-^N3NWLav&UTO{a9=&Tuz-Kq963;XaRFq#-1R18fi^Gb-; zVO>Q{Oe<^b0WA!hkBi9iJp3`kGwacXX2CVQ0xQn@Y2OhrM%e4)Ea7Y*Df$dY2BpbL zv$kX}*#`R1uNA(7lk_FAk~{~9Z*Si5xd(WKQdD&I?8Y^cK|9H&huMU1I(251D7(LL z+){kRc=ALmD;#SH#YJ+|7EJL6e~w!D7_IrK5Q=1DCulUcN(3j`+D_a|GP}?KYx}V+ zx_vLTYCLb0C?h;e<{K0`)-|-qfM16y{mnfX(GGs2H-;-lRMXyb@kiY^D;i1haxoEk zsQ7C_o2wv?;3KS_0w^G5#Qgf*>u)3bT<3kGQL-z#YiN9QH7<(oDdNlSdeHD zQJN-U*_wJM_cU}1YOH=m>DW~{%MAPxL;gLdU6S5xLb$gJt#4c2KYaEaL8ORWf=^(l z-2`8^J;&YG@vb9em%s~QpU)gG@24BQD69;*y&-#0NBkxumqg#YYomd2tyo0NGCr8N z5<5-E%utH?Ixt!(Y4x>zIz4R^9SABVMpLl(>oXnBNWs8w&xygh_e4*I$y_cVm?W-^ ze!9mPy^vTLRclXRGf$>g%Y{(#Bbm2xxr_Mrsvd7ci|X|`qGe5=54Zt2Tb)N zlykxE&re1ny+O7g#`6e_zyjVjRi5!DeTvSJ9^BJqQ*ovJ%?dkaQl!8r{F`@KuDEJB3#ho5 zmT$A&L=?}gF+!YACb=%Y@}8{SnhaGCHRmmuAh{LxAn0sg#R6P_^cJ-9)+-{YU@<^- zlYnH&^;mLVYE+tyjFj4gaAPCD4CnwP75BBXA`O*H(ULnYD!7K14C!kGL_&hak)udZ zkQN8)EAh&9I|TY~F{Z6mBv7sz3?<^o(#(NXGL898S3yZPTaT|CzZpZ~pK~*9Zcf2F zgwuG)jy^OTZD`|wf&bEdq4Vt$ir-+qM7BosXvu`>W1;iFN7yTvcpN_#at)Q4n+(Jh zYX1A-24l9H5jgY?wdEbW{(6U1=Kc?Utren80bP`K?J0+v@{-RDA7Y8yJYafdI<7-I z_XA!xeh#R4N7>rJ_?(VECa6iWhMJ$qdK0Ms27xG&$gLAy(|SO7_M|AH`fIY)1FGDp zlsLwIDshDU;*n`dF@8vV;B4~jRFpiHrJhQ6TcEm%OjWTi+KmE7+X{19 z>e!sg0--lE2(S0tK}zD&ov-{6bMUc%dNFIn{2^vjXWlt>+uxw#d)T6HNk6MjsfN~4 zDlq#Jjp_!wn}$wfs!f8NX3Rk#9)Q6-jD;D9D=1{$`3?o~caZjXU*U32^JkJ$ZzJ_% zQWNfcImxb!AV1DRBq`-qTV@g1#BT>TlvktYOBviCY!13Bv?_hGYDK}MINVi;pg)V- z($Bx1Tj`c?1I3pYg+i_cvFtcQ$SV9%%9QBPg&8R~Ig$eL+xKZY!C=;M1|r)$&9J2x z;l^a*Ph+isNl*%y1T4SviuK1Nco_spQ25v5-}7u?T9zHB5~{-+W*y3p{yjn{1obqf zYL`J^Uz8zZZN8c4Dxy~)k3Ws)E5eYi+V2C!+7Sm0uu{xq)S8o{9uszFTnE>lPhY=5 zdke-B8_*KwWOd%tQs_zf0x9+YixHp+Qi_V$aYVc$P-1mg?2|_{BUr$6WtLdIX2FaF zGmPRTrdIz)DNE)j*_>b9E}sp*(1-16}u za`dgT`KtA3;+e~9{KV48RT=CGPaVt;>-35}%nlFUMK0y7nOjoYds7&Ft~#>0$^ciZ zM}!J5Mz{&|&lyG^bnmh?YtR z*Z5EfDxkrI{QS#Iq752aiA~V)DRlC*2jlA|nCU!@CJwxO#<=j6ssn;muv zhBT9~35VtwsoSLf*(7vl&{u7d_K_CSBMbzr zzyjt&V5O#8VswCRK3AvVbS7U5(KvTPyUc0BhQ}wy0z3LjcdqH8`6F3!`)b3(mOSxL z>i4f8xor(#V+&#ph~ycJMcj#qeehjxt=~Na>dx#Tcq6Xi4?BnDeu5WBBxt603*BY& zZ#;o1kv?qpZjwK-E{8r4v1@g*lwb|8w@oR3BTDcbiGKs)a>Fpxfzh&b ziQANuJ_tNHdx;a*JeCo^RkGC$(TXS;jnxk=dx++D8|dmPP<0@ z$wh#ZYI%Rx$NKe-)BlJzB*bot0ras3I%`#HTMDthGtM_G6u-(tSroGp1Lz+W1Y`$@ zP`9NK^|IHbBrJ#AL3!X*g3{arc@)nuqa{=*2y+DvSwE=f*{>z1HX(>V zNE$>bbc}_yAu4OVn;8LG^naq5HZY zh{Hec==MD+kJhy6t=Nro&+V)RqORK&ssAxioc7-L#UQuPi#3V2pzfh6Ar400@iuV5 z@r>+{-yOZ%XQhsSfw%;|a4}XHaloW#uGluLKux0II9S1W4w=X9J=(k&8KU()m}b{H zFtoD$u5JlGfpX^&SXHlp$J~wk|DL^YVNh2w(oZ~1*W156YRmenU;g=mI zw({B(QVo2JpJ?pJqu9vijk$Cn+%PSw&b4c@uU6vw)DjGm2WJKt!X}uZ43XYlDIz%& z=~RlgZpU-tu_rD`5!t?289PTyQ zZgAEp=zMK>RW9^~gyc*x%vG;l+c-V?}Bm;^{RpgbEnt_B!FqvnvSy)T=R zGa!5GACDk{9801o@j>L8IbKp#!*Td5@vgFKI4w!5?R{>@^hd8ax{l=vQnd2RDHopo zwA+qb2cu4Rx9^Bu1WNYT`a(g}=&&vT`&Sqn-irxzX_j1=tIE#li`Hn=ht4KQXp zzZj`JO+wojs0dRA#(bXBOFn**o+7rPY{bM9m<+UBF{orv$#yF8)AiOWfuas5Fo`CJ zqa;jAZU^!bh8sjE7fsoPn%Tw11+vufr;NMm3*zC=;jB{R49e~BDeMR+H6MGzDlcA^ zKg>JEL~6_6iaR4i`tSfUhkgPaLXZ<@L7poRF?dw_DzodYG{Gp7#24<}=18PBT}aY` z{)rrt`g}930jr3^RBQNA$j!vzTh#Mo1VL`QCA&US?;<2`P+xy8b9D_Hz>FGHC2r$m zW>S9ywTSdQI5hh%7^e`#r#2906T?))i59O(V^Rpxw42rCAu-+I3y#Pg6cm#&AX%dy ze=hv0cUMxxxh1NQEIYXR{IBM&Bk8FK3NZI3z+M>r@A$ocd*e%x-?W;M0pv50p+MVt zugo<@_ij*6RZ;IPtT_sOf2Zv}-3R_1=sW37GgaF9Ti(>V z1L4ju8RzM%&(B}JpnHSVSs2LH#_&@`4Kg1)>*)^i`9-^JiPE@=4l$+?NbAP?44hX&XAZy&?}1;=8c(e0#-3bltVWg6h=k!(mCx=6DqOJ-I!-(g;*f~DDe={{JGtH7=UY|0F zNk(YyXsGi;g%hB8x)QLpp;;`~4rx>zr3?A|W$>xj>^D~%CyzRctVqtiIz7O3pc@r@JdGJiH@%XR_9vaYoV?J3K1cT%g1xOYqhXfSa`fg=bCLy% zWG74UTdouXiH$?H()lyx6QXt}AS)cOa~3IdBxddcQp;(H-O}btpXR-iwZ5E)di9Jf zfToEu%bOR11xf=Knw7JovRJJ#xZDgAvhBDF<8mDu+Q|!}Z?m_=Oy%Ur4p<71cD@0OGZW+{-1QT?U%_PJJ8T!0d2*a9I2;%|A z9LrfBU!r9qh4=3Mm3nR_~X-EyNc<;?m`?dKUNetCnS)}_-%QcWuOpw zAdZF`4c_24z&m{H9-LIL`=Hrx%{IjrNZ~U<7k6p{_wRkR84g>`eUBOQd3x5 zT^kISYq)gGw?IB8(lu1=$#Vl?iZdrx$H0%NxW)?MO$MhRHn8$F^&mzfMCu>|`{)FL z`ZgOt`z%W~^&kzMAuWy9=q~$ldBftH0}T#(K5e8;j~!x$JjyspJ1IISI?ON5OIPB$ z-5_|YUMb+QUsiv3R%Ys4tVYW+x$}dg;hw%EdoH%SXMp`)v?cxR4wic{X9pVBH>=`#`Kcj!}x4 zV!`6tj|*q?jZdG(CSevn(}4Ogij5 z-kp;sZs}7oNu0x+NHs~(aWaKGV@l~TBkmW&mPj==N!f|1e1SndS6(rPxsn7dz$q_{ zL0jSrihO)1t?gh8N zosMjR3n#YC()CVKv zos2TbnL&)lHEIiYdz|%6N^vAUvTs6?s|~kwI4uXjc9fim`KCqW3D838Xu{48p$2?I zOeEqQe1}JUZECrZSO_m=2<$^rB#B6?nrFXFpi8jw)NmoKV^*Utg6i8aEW|^QNJuW& z4cbXpHSp4|7~TW(%JP%q9W2~@&@5Y5%cXL#fMhV59AGj<3$Hhtfa>24DLk{7GZUtr z5ql**-e58|mbz%5Kk~|f!;g+Ze^b);F+5~^jdoq#m+s?Y*+=d5ruym%-Tnn8htCV; zDyyUrWydgDNM&bI{yp<_wd-q&?Ig+BN-^JjWo6Zu3%Eov^Ja>%eKqrk&7kUqeM8PL zs5D}lTe_Yx;e=K`TDya!-u%y$)r*Cr4bSfN*eZk$XT(Lv2Y}qj&_UaiTevxs_=HXjnOuBpmT> zBg|ty8?|1rD1~Ev^6=C$L9%+RkmBSQxlnj3j$XN?%QBstXdx+Vl!N$f2Ey`i3p@!f zzqhI3jC(TZUx|sP%yValu^nzEV96o%*CljO>I_YKa8wMfc3$_L()k4PB6kglP@IT#wBd*3RITYADL}g+hlzLYxFmCt=_XWS}=jg8`RgJefB57z(2n&&q>m ze&F(YMmoRZW7sQ;cZgd(!A9>7mQ2d#!-?$%G8IQ0`p1|*L&P$GnU0i0^(S;Rua4v8 z_7Qhmv#@+kjS-M|($c*ZOo?V2PgT;GKJyP1REABlZhPyf!kR(0UA7Bww~R<7_u6#t z{XNbiKT&tjne(&=UDZ+gNxf&@9EV|fblS^gxNhI-DH;|`1!YNlMcC{d7I{u_E~cJOalFEzDY|I?S3kHtbrN&}R3k zK(Ph_Ty}*L3Et6$cUW`0}**BY@44KtwEy(jW@pAt`>g> z&8>-TmJiDwc;H%Ae%k6$ndZlfKruu1GocgZrLN=sYI52}_I%d)~ z6z40!%W4I6ch$CE2m>Dl3iwWIbcm27QNY#J!}3hqc&~(F8K{^gIT6E&L!APVaQhj^ zjTJEO&?**pivl^xqfD(rpLu;`Tm1MV+Wtd4u>X6u5V{Yp%)xH$k410o{pGoKdtY0t@GgqFN zO=!hTcYoa^dEPKvPX4ukgUTmR#q840gRMMi%{3kvh9gt(wK;Fniqu9A%BMsq?U&B5DFXC8t8FBN1&UIwS#=S zF(6^Eyn8T}p)4)yRvs2rCXZ{L?N6{hgE_dkH_HA#L3a0$@UMoBw6RE9h|k_rx~%rB zUqeEPL|!Pbp|up2Q=8AcUxflck(fPNJYP1OM_4I(bc24a**Qnd-@;Bkb^2z8Xv?;3yZp*| zoy9KhLo=;8n0rPdQ}yAoS8eb zAtG5QYB|~z@Z(Fxdu`LmoO>f&(JzsO|v0V?1HYsfMvF!3| zka=}6U13(l@$9&=1!CLTCMS~L01CMs@Abl4^Q^YgVgizWaJa%{7t)2sVcZg0mh7>d z(tN=$5$r?s={yA@IX~2ot9`ZGjUgVlul$IU4N}{ zIFBzY3O0;g$BZ#X|VjuTPKyw*|IJ+&pQ` z(NpzU`o=D86kZ3E5#!3Ry$#0AW!6wZe)_xZ8EPidvJ0f+MQJZ6|ZJ$CEV6;Yt{OJnL`dewc1k>AGbkK9Gf5BbB-fg? zgC4#CPYX+9%LLHg@=c;_Vai_~#ksI~)5|9k(W()g6ylc(wP2uSeJ$QLATtq%e#zpT zp^6Y)bV+e_pqIE7#-hURQhfQvIZpMUzD8&-t$esrKJ}4`ZhT|woYi>rP~y~LRf`*2!6 z6prDzJ~1VOlYhYAuBHcu9m>k_F>;N3rpLg>pr;{EDkeQPHfPv~woj$?UTF=txmaZy z?RrVthxVcqUM;X*(=UNg4(L|0d250Xk)6GF&DKD@r6{aZo;(}dnO5@CP7pMmdsI)- zeYH*@#+|)L8x7)@GNBu0Npyyh6r z^~!3$x&w8N)T;|LVgnwx1jHmZn{b2V zO|8s#F0NZhvux?0W9NH5;qZ?P_JtPW86)4J>AS{0F1S0d}=L2`{F z_y;o;17%{j4I)znptnB z%No1W>o}H2%?~CFo~0j?pzWk?dV4ayb!s{#>Yj`ZJ!H)xn}*Z_gFHy~JDis)?9-P=z4iOQg{26~n?dTms7)+F}? zcXvnHHnnbNTzc!$t+V}=<2L<7l(84v1I3b;-)F*Q?cwLNlgg{zi#iS)*rQ5AFWe&~ zWHPPGy{8wEC9JSL?qNVY76=es`bA{vUr~L7f9G@mP}2MNF0Qhv6Sgs`r_k!qRbSXK zv16Qqq`rFM9!4zCrCeiVS~P2e{Pw^A8I?p?NSVR{XfwlQo*wj|Ctqz4X-j+dU7eGkC(2y`(P?FM?P4gKki3Msw#fM6paBq#VNc>T2@``L{DlnnA-_*i10Kre&@-H!Z7gzn9pRF61?^^ z8dJ5kEeVKb%Bly}6NLV}<0(*eZM$QTLcH#+@iWS^>$Of_@Mu1JwM!>&3evymgY6>C_)sK+n|A5G6(3RJz0k>(z2uLdzXeTw)e4*g!h} zn*UvIx-Ozx<3rCF#C`khSv`Y-b&R4gX>d5osr$6jlq^8vi!M$QGx05pJZoY#RGr*J zsJmOhfodAzYQxv-MoU?m_|h^aEwgEHt5h_HMkHwtE+OA03(7{hm1V?AlYAS7G$u5n zO+6?51qo@aQK5#l6pM`kD5OmI28g!J2Z{5kNlSuKl=Yj3QZ|bvVHU}FlM+{QV=<=) z+b|%Q!R)FE z@ycDMSKV2?*XfcAc5@IOrSI&3&aR$|oAD8WNA6O;p~q-J@ll{x`jP<*eEpIYOYnT zer_t=dYw6a0avjQtKN&#n&(KJ5Kr$RXPOp1@Fq#0Of zTXQkq4qQxKWR>x#d{Hyh?6Y)U07;Q$?BTl7mx2bSPY_juXub1 z%-$)NKXzE<%}q>RX25*oeMVjiz&r_z;BrQV-(u>!U>C*OisXNU*UftsrH6vAhTEm@ zoKA`?fZL1sdd!+G@*NNvZa>}37u^x8^T>VH0_6Bx{3@x5NAg&55{2jUE-w3zCJNJi z^IlU=+DJz-9K&4c@7iKj(zlj@%V}27?vYmxo*;!jZVXJMeDg;5T!4Y1rxNV-e$WAu zkk6^Xao8HC=w2hpLvM(!xwo|~$eG6jJj39zyQHf)E+NPJlfspUhzRv&_qr8+Z1`DA zz`EV=A)d=;2&J;eypNx~q&Ir_7e_^xXg(L9>k=X4pxZ3y#-ch$^TN}i>X&uwF%75c(9cjO6`E5 z16vbMYb!lEIM?jxn)^+Ld8*hmEXR4a8TSfqwBg1(@^8$p&#@?iyGd}uhWTVS`Mlpa zGc+kV)K7DJwd46aco@=?iASsx?sDjbHoDVU9=+^tk46|Fxxey1u)_}c1j z^(`5~PU%og1LdSBE5x4N&5&%Nh$sy0oANXwUcGa>@CCMqP`4W$ZPSaykK|giiuMIw zu#j)&VRKWP55I(5K1^cog|iXgaK1Z%wm%T;;M3X`-`TTWaI}NtIZj;CS)S%S(h}qq zRFQ#{m4Qk$7;1i*0PC^|X1@a1pcMq1aiRSCHq+mnfj^FS{oxWs0McCN-lK4>SDp#` z7=Duh)kXC;lr1g3dqogzBBDg6>et<<>m>KO^|bI5X{+eMd^-$2xfoP*&e$vdQc7J% zmFO~OHf7aqlIvg%P`Gu|3n;lKjtRd@;;x#$>_xU(HpZos7?ShZlQSU)bY?qyQM3cHh5twS6^bF8NBKDnJgXHa)? zBYv=GjsZuYC2QFS+jc#uCsaEPEzLSJCL=}SIk9!*2Eo(V*SAUqKw#?um$mUIbqQQb zF1Nn(y?7;gP#@ws$W76>TuGcG=U_f6q2uJq?j#mv7g;llvqu{Yk~Mo>id)jMD7;T> zSB$1!g)QpIf*f}IgmV;!B+3u(ifW%xrD=`RKt*PDC?M5KI)DO`VXw(7X-OMLd3iVU z0CihUN(eNrY;m?vwK{55MU`p1;JDF=6ITN$+!q8W#`iIsN8;W7H?`htf%RS9Lh+KQ z_p_4?qO4#*`t+8l-N|kAKDcOt zoHsqz_oO&n?@4^Mr*4YrkDX44BeS*0zaA1j@*c}{$;jUxRXx1rq7z^*NX6d`DcQ}L z6*cN7e%`2#_J4z8=^GM6>%*i>>X^_0u9qn%0JTUo)c0zIz|7a`%_UnB)-I1cc+ z0}jAK0}jBl|6-2VT759oxBnf%-;7vs>7Mr}0h3^$0`5FAy}2h{ps5%RJA|^~6uCqg zxBMK5bQVD{Aduh1lu4)`Up*&( zCJQ>nafDb#MuhSZ5>YmD@|TcrNv~Q%!tca;tyy8Iy2vu2CeA+AsV^q*Wohg%69XYq zP0ppEDEYJ9>Se&X(v=U#ibxg()m=83pLc*|otbG;`CYZ z*YgsakGO$E$E_$|3bns7`m9ARe%myU3$DE;RoQ<6hR8e;%`pxO1{GXb$cCZl9lVnJ$(c` z``G?|PhXaz`>)rb7jm2#v7=(W?@ zjUhrNndRFMQ}%^^(-nmD&J>}9w@)>l;mhRr@$}|4ueOd?U9ZfO-oi%^n4{#V`i}#f zqh<@f^%~(MnS?Z0xsQI|Fghrby<&{FA+e4a>c(yxFL!Pi#?DW!!YI{OmR{xEC7T7k zS_g*9VWI}d0IvIXx*d5<7$5Vs=2^=ews4qZGmAVyC^9e;wxJ%BmB(F5*&!yyABCtLVGL@`qW>X9K zpv=W~+EszGef=am3LG+#yIq5oLXMnZ_dxSLQ_&bwjC^0e8qN@v!p?7mg02H<9`uaJ zy0GKA&YQV2CxynI3T&J*m!rf4@J*eo235*!cB1zEMQZ%h5>GBF;8r37K0h?@|E*0A zIHUg0y7zm(rFKvJS48W7RJwl!i~<6X2Zw+Fbm9ekev0M;#MS=Y5P(kq^(#q11zsvq zDIppe@xOMnsOIK+5BTFB=cWLalK#{3eE>&7fd11>l2=MpNKjsZT2kmG!jCQh`~Fu0 z9P0ab`$3!r`1yz8>_7DYsO|h$kIsMh__s*^KXv?Z1O8|~sEz?Y{+GDzze^GPjk$E$ zXbA-1gd77#=tn)YKU=;JE?}De0)WrT%H9s3`fn|%YibEdyZov3|MJ>QWS>290eCZj z58i<*>dC9=kz?s$sP_9kK1p>nV3qvbleExyq56|o+oQsb{ZVmuu1n~JG z0sUvo_i4fSM>xRs8rvG$*+~GZof}&ISxn(2JU*K{L<3+b{bBw{68H&Uiup@;fWWl5 zgB?IWMab0LkXK(Hz#yq>scZbd2%=B?DO~^q9tarlzZysN+g}n0+v);JhbjUT8AYrt z3?;0r%p9zLJv1r$%q&HKF@;3~0wVwO!U5m;J`Mm|`Nc^80sZd+Wj}21*SPoF82hCF zoK?Vw;4ioafdAkZxT1er-LLVi-*0`@2Ur&*!b?0U>R;no+S%)xoBuBxRw$?weN-u~tKE}8xb@7Gs%(aC;e1-LIlSfXDK(faFW)mnHdrLc3`F z6ZBsT^u0uVS&il=>YVX^*5`k!P4g1)2LQmz{?&dgf`7JrA4ZeE0sikL`k!Eb6r=g0 z{aCy_0I>fxSAXQYz3lw5G|ivg^L@(x-uch!AphH+d;E4`175`R0#b^)Zp>EM1Ks=zx6_261>!7 z{7F#a{Tl@Tpw9S`>7_i|PbScS-(dPJv9_0-FBP_aa@Gg^2IoKNZM~#=sW$SH3MJ|{ zsQy8F43lX7hYx<{v^Q9`2QsMzeen3cGpiTgzVp- z`aj3&Wv0(he1qKI!2jpGpO-i0Wpcz%vdn`2o9x&3;^nsZPt3c \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >/dev/null +APP_HOME="`pwd -P`" +cd "$SAVED" >/dev/null + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn () { + echo "$*" +} + +die () { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +nonstop=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; + NONSTOP* ) + nonstop=true + ;; +esac + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin or MSYS, switch paths to Windows format before running java +if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + JAVACMD=`cygpath --unix "$JAVACMD"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Escape application args +save () { + for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done + echo " " +} +APP_ARGS=$(save "$@") + +# Collect all arguments for the java command, following the shell quoting and substitution rules +eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" + +# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong +if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then + cd "$(dirname "$0")" +fi + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..9618d8d9 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,100 @@ +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/js/npm.templates/kotlinx-html/package.json b/js/npm.templates/kotlinx-html/package.json deleted file mode 100644 index 0756a2e8..00000000 --- a/js/npm.templates/kotlinx-html/package.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "name": "kotlinx-html", - "version": "1.0.0", - "description": "Library for building HTML in Kotlin", - "main": "kotlinx-html-js.js", - "repository": { - "type": "git", - "url": "git+https://github.com/Kotlin/kotlinx.html.git" - }, - "keywords": [ - "Kotlin", - "Language", - "HTML", - "JavaScript", - "JetBrains" - ], - "author": "JetBrains", - "license": "Apache-2.0", - "bugs": { - "url": "https://github.com/Kotlin/kotlinx.html/issues" - }, - "homepage": "https://github.com/kotlin/kotlinx.html/wiki" -} diff --git a/js/pom.xml b/js/pom.xml deleted file mode 100644 index 928aa539..00000000 --- a/js/pom.xml +++ /dev/null @@ -1,232 +0,0 @@ - - - - kotlinx-html - org.jetbrains.kotlinx - 0.6.13-SNAPSHOT - - 4.0.0 - - org.jetbrains.kotlinx - kotlinx-html-js - 0.6.13-SNAPSHOT - - kotlinx.html JS - kotlinx.html JS implementation - - - - The Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0.txt - - - - - - Sergey Mashkov - JetBrains s.r.o. - - developer - - - - - https://github.com/Kotlin/kotlinx.html - - scm:git:git@github.com:Kotlin/kotlinx.html.git - https://github.com/Kotlin/kotlinx.html - HEAD - - - - - org.jetbrains.kotlin - kotlin-stdlib-js - - - org.jetbrains.kotlinx - kotlinx-html-common - ${project.version} - - - test - org.jetbrains.kotlin - kotlin-test-js - ${kotlin.version} - true - - - - - - - kotlin-maven-plugin - org.jetbrains.kotlin - ${kotlin.version} - - - - compile - compile - - js - - - umd - true - always - ./ - ${project.build.outputDirectory}/${project.artifactId}.js - true - - - - compile-js-tests - test-compile - - test-js - - - ${project.basedir}/target/test-js/${project.artifactId}-tests.js - true - true - umd - true - - - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.0.0 - - - add-source - prepare-package - - add-source - - - - ../shared/src/main/kotlin - - - - - - - org.apache.maven.plugins - maven-jar-plugin - 2.6 - - true - ${project.build.outputDirectory} - - **/*.js - **/*.js.map - **/*.kjsm - **/*.kotlin_classes - **/*.kotlin_string_table - **/*.kotlin_file_table - - - - - ${user.name} - - JetBrains s.r.o. - ${project.version} - - - - - - org.apache.maven.plugins - maven-source-plugin - - - attach-sources - - jar - - - - - - org.jetbrains.dokka - dokka-maven-plugin - - - maven-dependency-plugin - 2.10 - - - - unpack-dependencies - - test-compile - - test - kotlinx-html-common - jar - ${project.basedir}/target/test-js - *.js - *.meta.js - - - - - - com.github.eirslett - frontend-maven-plugin - 1.6 - - - - install node and npm - generate-test-resources - - install-node-and-npm - - - ${maven.test.skip} - - - - - npm install - generate-test-resources - - npm - - - - install - ${maven.test.skip} - - - - - javascript tests - - karma - - - ${project.basedir}/src/test/karma/karma.conf.js - ${maven.test.skip} - ${maven.test.skip} - - - - - - v8.9.4 - 5.6.0 - - ${project.basedir}/src/test/karma - - - - - diff --git a/jvm/pom.xml b/jvm/pom.xml deleted file mode 100644 index 2cb1180b..00000000 --- a/jvm/pom.xml +++ /dev/null @@ -1,147 +0,0 @@ - - - - kotlinx-html - org.jetbrains.kotlinx - 0.6.13-SNAPSHOT - - 4.0.0 - - org.jetbrains.kotlinx - kotlinx-html-jvm - 0.6.13-SNAPSHOT - - kotlinx.html JVM - kotlinx.html JVM implementation - - - - The Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0.txt - - - - - - Sergey Mashkov - JetBrains s.r.o. - - developer - - - - - https://github.com/Kotlin/kotlinx.html - - scm:git:git@github.com:Kotlin/kotlinx.html.git - https://github.com/Kotlin/kotlinx.html - HEAD - - - - - junit - junit - test - - - org.jetbrains.kotlin - kotlin-stdlib - - - org.jetbrains.kotlin - kotlin-test-junit - test - - - org.jetbrains.kotlinx - kotlinx-html-common - ${project.version} - true - - - org.jetbrains.kotlin - kotlin-stdlib-common - - - - - - - - - kotlin-maven-plugin - org.jetbrains.kotlin - - - - compile - compile - - compile - - - - -Xdump-declarations-to=${build.directory}/declarations.json - - - - - - test-compile - test-compile - - test-compile - - - - - - true - - - - org.codehaus.mojo - build-helper-maven-plugin - 3.0.0 - - - add-source - prepare-package - - add-source - - - - ../shared/src/main/kotlin - - - - - - - - org.apache.maven.plugins - maven-source-plugin - 2.4 - - - - attach-sources - prepare-package - - jar-no-fork - test-jar-no-fork - - - - - - - org.jetbrains.dokka - dokka-maven-plugin - - - - - diff --git a/jvm/src/test/kotlin/compatibility.kt b/jvm/src/test/kotlin/compatibility.kt deleted file mode 100644 index e785b3aa..00000000 --- a/jvm/src/test/kotlin/compatibility.kt +++ /dev/null @@ -1,16 +0,0 @@ -package kotlinx.html.tests - -import java.io.* -import kotlin.test.* - -class CompatibilityTest { - // NOTE: this test shouldn't be started from IDEA because incremental compiler will only dump - // changed declarations - @Test - fun binaryCompatibilityTest() { - val expected = this::class.java.classLoader.getResourceAsStream("declarations.json")!!.reader().readText() - val actual = File("target/declarations.json").readText() - - assertEquals(expected, actual) - } -} diff --git a/mvnw b/mvnw deleted file mode 100755 index fc7efd17..00000000 --- a/mvnw +++ /dev/null @@ -1,234 +0,0 @@ -#!/bin/sh -# ---------------------------------------------------------------------------- -# Licensed to the Apache Software Foundation (ASF) under one -# or more contributor license agreements. See the NOTICE file -# distributed with this work for additional information -# regarding copyright ownership. The ASF licenses this file -# to you under the Apache License, Version 2.0 (the -# "License"); you may not use this file except in compliance -# with the License. You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, -# software distributed under the License is distributed on an -# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -# KIND, either express or implied. See the License for the -# specific language governing permissions and limitations -# under the License. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# M2_HOME - location of maven2's installed home dir -# MAVEN_OPTS - parameters passed to the Java VM when running Maven -# e.g. to debug Maven itself, use -# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -# MAVEN_SKIP_RC - flag to disable loading of mavenrc files -# ---------------------------------------------------------------------------- - -if [ -z "$MAVEN_SKIP_RC" ] ; then - - if [ -f /etc/mavenrc ] ; then - . /etc/mavenrc - fi - - if [ -f "$HOME/.mavenrc" ] ; then - . "$HOME/.mavenrc" - fi - -fi - -# OS specific support. $var _must_ be set to either true or false. -cygwin=false; -darwin=false; -mingw=false -case "`uname`" in - CYGWIN*) cygwin=true ;; - MINGW*) mingw=true;; - Darwin*) darwin=true - # - # Look for the Apple JDKs first to preserve the existing behaviour, and then look - # for the new JDKs provided by Oracle. - # - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then - # - # Oracle JDKs - # - export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then - # - # Apple JDKs - # - export JAVA_HOME=`/usr/libexec/java_home` - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=`java-config --jre-home` - fi -fi - -if [ -z "$M2_HOME" ] ; then - ## resolve links - $0 may be a link to maven's home - PRG="$0" - - # need this for relative symlinks - while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG="`dirname "$PRG"`/$link" - fi - done - - saveddir=`pwd` - - M2_HOME=`dirname "$PRG"`/.. - - # make it fully qualified - M2_HOME=`cd "$M2_HOME" && pwd` - - cd "$saveddir" - # echo Using m2 at $M2_HOME -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --unix "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --unix "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --unix "$CLASSPATH"` -fi - -# For Migwn, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$M2_HOME" ] && - M2_HOME="`(cd "$M2_HOME"; pwd)`" - [ -n "$JAVA_HOME" ] && - JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? -fi - -if [ -z "$JAVA_HOME" ]; then - javaExecutable="`which javac`" - if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then - # readlink(1) is not available as standard on Solaris 10. - readLink=`which readlink` - if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then - if $darwin ; then - javaHome="`dirname \"$javaExecutable\"`" - javaExecutable="`cd \"$javaHome\" && pwd -P`/javac" - else - javaExecutable="`readlink -f \"$javaExecutable\"`" - fi - javaHome="`dirname \"$javaExecutable\"`" - javaHome=`expr "$javaHome" : '\(.*\)/bin'` - JAVA_HOME="$javaHome" - export JAVA_HOME - fi - fi -fi - -if [ -z "$JAVACMD" ] ; then - if [ -n "$JAVA_HOME" ] ; then - if [ -x "$JAVA_HOME/jre/sh/java" ] ; then - # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" - else - JAVACMD="$JAVA_HOME/bin/java" - fi - else - JAVACMD="`which java`" - fi -fi - -if [ ! -x "$JAVACMD" ] ; then - echo "Error: JAVA_HOME is not defined correctly." >&2 - echo " We cannot execute $JAVACMD" >&2 - exit 1 -fi - -if [ -z "$JAVA_HOME" ] ; then - echo "Warning: JAVA_HOME environment variable is not set." -fi - -CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` -fi - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - local basedir=$(pwd) - local wdir=$(pwd) - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - wdir=$(cd "$wdir/.."; pwd) - done - echo "${basedir}" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - echo "$(tr -s '\n' ' ' < "$1")" - fi -} - -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# Provide a "standardized" way to retrieve the CLI args that will -# work with both Windows and non-Windows executions. -MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" -export MAVEN_CMD_LINE_ARGS - -WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -exec "$JAVACMD" \ - $MAVEN_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CMD_LINE_ARGS - diff --git a/mvnw.cmd b/mvnw.cmd deleted file mode 100644 index 00104808..00000000 --- a/mvnw.cmd +++ /dev/null @@ -1,145 +0,0 @@ -@REM ---------------------------------------------------------------------------- -@REM Licensed to the Apache Software Foundation (ASF) under one -@REM or more contributor license agreements. See the NOTICE file -@REM distributed with this work for additional information -@REM regarding copyright ownership. The ASF licenses this file -@REM to you under the Apache License, Version 2.0 (the -@REM "License"); you may not use this file except in compliance -@REM with the License. You may obtain a copy of the License at -@REM -@REM http://www.apache.org/licenses/LICENSE-2.0 -@REM -@REM Unless required by applicable law or agreed to in writing, -@REM software distributed under the License is distributed on an -@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -@REM KIND, either express or implied. See the License for the -@REM specific language governing permissions and limitations -@REM under the License. -@REM ---------------------------------------------------------------------------- - -@REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@REM M2_HOME - location of maven2's installed home dir -@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending -@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven -@REM e.g. to debug Maven itself, use -@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files -@REM ---------------------------------------------------------------------------- - -@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' -@echo off -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' -@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% - -@REM set %HOME% to equivalent of $HOME -if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%") - -@REM Execute a user defined script before this one -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre -@REM check for pre script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat" -if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd" -:skipRcPre - -@setlocal - -set ERROR_CODE=0 - -@REM To isolate internal variables from possible post scripts, we use another setlocal -@setlocal - -@REM ==== START VALIDATION ==== -if not "%JAVA_HOME%" == "" goto OkJHome - -echo. -echo Error: JAVA_HOME not found in your environment. >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -:OkJHome -if exist "%JAVA_HOME%\bin\java.exe" goto init - -echo. -echo Error: JAVA_HOME is set to an invalid directory. >&2 -echo JAVA_HOME = "%JAVA_HOME%" >&2 -echo Please set the JAVA_HOME variable in your environment to match the >&2 -echo location of your Java installation. >&2 -echo. -goto error - -@REM ==== END VALIDATION ==== - -:init - -set MAVEN_CMD_LINE_ARGS=%MAVEN_CONFIG% %* - -@REM Find the project base dir, i.e. the directory that contains the folder ".mvn". -@REM Fallback to current working directory if not found. - -set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR% -IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir - -set EXEC_DIR=%CD% -set WDIR=%EXEC_DIR% -:findBaseDir -IF EXIST "%WDIR%"\.mvn goto baseDirFound -cd .. -IF "%WDIR%"=="%CD%" goto baseDirNotFound -set WDIR=%CD% -goto findBaseDir - -:baseDirFound -set MAVEN_PROJECTBASEDIR=%WDIR% -cd "%EXEC_DIR%" -goto endDetectBaseDir - -:baseDirNotFound -set MAVEN_PROJECTBASEDIR=%EXEC_DIR% -cd "%EXEC_DIR%" - -:endDetectBaseDir - -IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig - -@setlocal EnableExtensions EnableDelayedExpansion -for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a -@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS% - -:endReadAdditionalConfig - -SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" - -set WRAPPER_JAR=""%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"" -set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain - -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% -if ERRORLEVEL 1 goto error -goto end - -:error -set ERROR_CODE=1 - -:end -@endlocal & set ERROR_CODE=%ERROR_CODE% - -if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost -@REM check for post script, once with legacy .bat ending and once with .cmd ending -if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat" -if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd" -:skipRcPost - -@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on' -if "%MAVEN_BATCH_PAUSE%" == "on" pause - -if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% - -exit /B %ERROR_CODE% diff --git a/npm_publish.xml b/npm_publish.xml deleted file mode 100644 index 7d7e6600..00000000 --- a/npm_publish.xml +++ /dev/null @@ -1,147 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/pom.xml b/pom.xml deleted file mode 100644 index 4ecdeaf0..00000000 --- a/pom.xml +++ /dev/null @@ -1,304 +0,0 @@ - - - 4.0.0 - - org.jetbrains.kotlinx - kotlinx-html - pom - 0.6.13-SNAPSHOT - - kotlinx.html root module - A root module for all kotlinx.html components - - - - The Apache License, Version 2.0 - https://www.apache.org/licenses/LICENSE-2.0.txt - - - - - shared - jvm - js - generate - assembly - - - https://github.com/Kotlin/kotlinx.html - - scm:git:git@github.com:Kotlin/kotlinx.html.git - https://github.com/Kotlin/kotlinx.html - HEAD - - - - - Sergey Mashkov - JetBrains s.r.o. - - developer - - - - - - UTF-8 - - - - - - org.jetbrains.kotlin - kotlin-stdlib - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-stdlib-common - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-stdlib-js - ${kotlin.version} - - - org.jetbrains.kotlin - kotlin-test-junit - ${kotlin.version} - - - junit - junit - 4.12 - test - - - - - - ${project.basedir}/src/main/kotlin - ${project.basedir}/src/test/kotlin - - - - org.apache.maven.plugins - maven-source-plugin - 3.0.1 - - - - attach-sources - prepare-package - - jar-no-fork - test-jar-no-fork - - - true - - - - - - maven-release-plugin - 2.5.3 - - - true - - - - org.apache.maven.plugins - maven-jar-plugin - 3.0.2 - - - empty-javadoc-jar - prepare-package - - jar - - - javadoc - ${build.dir}/empty - true - - - - - - maven-surefire-plugin - 2.18.1 - - 2C - true - - - - com.devexperts.bintray - bintray-maven-plugin - 1.3 - - - bintray-deploy - - publish - - - bintray - ${bintray.url} - - - - - - - - - - org.jetbrains.kotlin - kotlin-maven-plugin - ${kotlin.version} - - - - org.jetbrains.dokka - dokka-maven-plugin - 0.9.1 - - - pre-site - - dokka - - - - - - - -

${project.basedir}/src/main/kotlin - https://github.com/Kotlin/kotlinx.html/ - - - - - - - - - - - jcenter - JCenter - https://jcenter.bintray.com/ - - - - - - bintray - ${bintray.url} - - - - - - kotlin-latest - - true - - - 1.3.40 - https://api.bintray.com/maven/kotlin/kotlinx.html/kotlinx.html - - - - kotlin-snapshot - - false - - - 1.2-SNAPSHOT - https://api.bintray.com/maven/kotlin/kotlin-dev/kotlinx.html - - - - - sonatype.oss.snapshots - Sonatype OSS Snapshot Repository - https://oss.sonatype.org/content/repositories/snapshots - - false - - - true - - - - - - - sonatype.oss.snapshots - Sonatype OSS Snapshot Repository - https://oss.sonatype.org/content/repositories/snapshots - - false - - - true - - - - - - kotlin-dev - - false - - - 1.3.40 - https://api.bintray.com/maven/kotlin/kotlin-dev/kotlinx.html - - - - - - false - - bintray-kotlin-kotlin-dev - bintray - https://dl.bintray.com/kotlin/kotlin-dev - - - - false - - bintray-kotlin-kotlin-eap - bintray - https://dl.bintray.com/kotlin/kotlin-eap-1.1 - - - - - - false - - bintray-kotlin-plugin-kotlin-dev - bintray-plugins - https://dl.bintray.com/kotlin/kotlin-dev - - - - false - - bintray-kotlin-plugin-kotlin-eap - bintray-plugins - https://dl.bintray.com/kotlin/kotlin-eap-1.1 - - - - - diff --git a/scripts/activate-profile.kts b/scripts/activate-profile.kts deleted file mode 100644 index 420033ba..00000000 --- a/scripts/activate-profile.kts +++ /dev/null @@ -1,53 +0,0 @@ -import java.io.* -import kotlin.system.* - -// activate profiles from -DactivateProfile -val profileToActivate = System.getProperty("activateProfile") -if (profileToActivate == null) { - System.err.println("No property activateProfile specified, -DactivateProfile=someProfile") - exitProcess(1) -} - -val file = File("../pom.xml") -val pom = file.readText() - -val profilesReg = ".*?()".toRegex(RegexOption.DOT_MATCHES_ALL) -val profileId = "(.*?)".toRegex(RegexOption.DOT_MATCHES_ALL) -val activeByDefault = "(.*?)".toRegex(RegexOption.DOT_MATCHES_ALL) - -val profiles = profilesReg.findAll(pom).toList() - -if (profiles.isEmpty()) { - System.err.println("No profiles were found in ${file.absolutePath}") - exitProcess(1) -} - -val result = buildString { - append(pom, 0, profiles.first().range.start) - - profiles.forEachIndexed { index, profileMatch -> - val id = profileId.find(profileMatch.value)?.groupValues?.get(1) - val activated = activeByDefault.find(profileMatch.value) - val activatedValue = activated?.groups?.get(1)?.range - - if (id != null && activatedValue != null) { - val newValue = if (id == profileToActivate) "true" else "false" - - append(profileMatch.value, 0, activatedValue.start) - append(newValue) - append(profileMatch.value, activatedValue.endInclusive + 1, profileMatch.value.length) - } else { - append(profileMatch.value) - } - - if (index != profiles.lastIndex) { - append(pom, profileMatch.range.endInclusive + 1, profiles[index + 1].range.start) - } - } - - append(pom, profiles.last().range.endInclusive + 1, pom.length) -} - -file.writeText(result) - - diff --git a/settings.gradle.kts b/settings.gradle.kts new file mode 100644 index 00000000..52648267 --- /dev/null +++ b/settings.gradle.kts @@ -0,0 +1 @@ +rootProject.name = "kotlinx-html" \ No newline at end of file diff --git a/shared/pom.xml b/shared/pom.xml deleted file mode 100644 index 70da85b1..00000000 --- a/shared/pom.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - kotlinx-html - org.jetbrains.kotlinx - 0.6.13-SNAPSHOT - - 4.0.0 - - kotlinx-html-common - - - - org.jetbrains.kotlin - kotlin-stdlib-common - ${kotlin.version} - - - - - - - maven-resources-plugin - 3.0.2 - - - org.jetbrains.kotlin - kotlin-maven-plugin - - - - metadata - - metadata - - - - - - org.jetbrains.dokka - dokka-maven-plugin - - - org.apache.maven.plugins - maven-jar-plugin - 2.6 - - true - - - - ${user.name} - - JetBrains s.r.o. - ${project.version} - - - - - - default-jar - none - - - pack-meta - package - - jar - - - ${project.build.outputDirectory} - - - - - - - diff --git a/shared/src/main/kotlin/Event.kt b/src/commonMain/kotlin/Event.kt similarity index 100% rename from shared/src/main/kotlin/Event.kt rename to src/commonMain/kotlin/Event.kt diff --git a/shared/src/main/kotlin/api.kt b/src/commonMain/kotlin/api.kt similarity index 100% rename from shared/src/main/kotlin/api.kt rename to src/commonMain/kotlin/api.kt diff --git a/shared/src/main/kotlin/attributes.kt b/src/commonMain/kotlin/attributes.kt similarity index 100% rename from shared/src/main/kotlin/attributes.kt rename to src/commonMain/kotlin/attributes.kt diff --git a/shared/src/main/kotlin/compatibility.kt b/src/commonMain/kotlin/compatibility.kt similarity index 100% rename from shared/src/main/kotlin/compatibility.kt rename to src/commonMain/kotlin/compatibility.kt diff --git a/shared/src/main/kotlin/delayed-consumer.kt b/src/commonMain/kotlin/delayed-consumer.kt similarity index 100% rename from shared/src/main/kotlin/delayed-consumer.kt rename to src/commonMain/kotlin/delayed-consumer.kt diff --git a/shared/src/main/kotlin/delegating-map.kt b/src/commonMain/kotlin/delegating-map.kt similarity index 100% rename from shared/src/main/kotlin/delegating-map.kt rename to src/commonMain/kotlin/delegating-map.kt diff --git a/shared/src/main/kotlin/exception-consumer.kt b/src/commonMain/kotlin/exception-consumer.kt similarity index 100% rename from shared/src/main/kotlin/exception-consumer.kt rename to src/commonMain/kotlin/exception-consumer.kt diff --git a/shared/src/main/kotlin/filter-consumer.kt b/src/commonMain/kotlin/filter-consumer.kt similarity index 100% rename from shared/src/main/kotlin/filter-consumer.kt rename to src/commonMain/kotlin/filter-consumer.kt diff --git a/shared/src/main/kotlin/finalize-consumer.kt b/src/commonMain/kotlin/finalize-consumer.kt similarity index 100% rename from shared/src/main/kotlin/finalize-consumer.kt rename to src/commonMain/kotlin/finalize-consumer.kt diff --git a/shared/src/main/kotlin/generated/gen-attr-traits.kt b/src/commonMain/kotlin/generated/gen-attr-traits.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-attr-traits.kt rename to src/commonMain/kotlin/generated/gen-attr-traits.kt diff --git a/shared/src/main/kotlin/generated/gen-attributes.kt b/src/commonMain/kotlin/generated/gen-attributes.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-attributes.kt rename to src/commonMain/kotlin/generated/gen-attributes.kt diff --git a/shared/src/main/kotlin/generated/gen-consumer-tags.kt b/src/commonMain/kotlin/generated/gen-consumer-tags.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-consumer-tags.kt rename to src/commonMain/kotlin/generated/gen-consumer-tags.kt diff --git a/shared/src/main/kotlin/generated/gen-entities.kt b/src/commonMain/kotlin/generated/gen-entities.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-entities.kt rename to src/commonMain/kotlin/generated/gen-entities.kt diff --git a/shared/src/main/kotlin/generated/gen-enums.kt b/src/commonMain/kotlin/generated/gen-enums.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-enums.kt rename to src/commonMain/kotlin/generated/gen-enums.kt diff --git a/shared/src/main/kotlin/generated/gen-parent-traits.kt b/src/commonMain/kotlin/generated/gen-parent-traits.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-parent-traits.kt rename to src/commonMain/kotlin/generated/gen-parent-traits.kt diff --git a/shared/src/main/kotlin/generated/gen-tag-groups.kt b/src/commonMain/kotlin/generated/gen-tag-groups.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tag-groups.kt rename to src/commonMain/kotlin/generated/gen-tag-groups.kt diff --git a/shared/src/main/kotlin/generated/gen-tag-unions.kt b/src/commonMain/kotlin/generated/gen-tag-unions.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tag-unions.kt rename to src/commonMain/kotlin/generated/gen-tag-unions.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-a.kt b/src/commonMain/kotlin/generated/gen-tags-a.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-a.kt rename to src/commonMain/kotlin/generated/gen-tags-a.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-b.kt b/src/commonMain/kotlin/generated/gen-tags-b.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-b.kt rename to src/commonMain/kotlin/generated/gen-tags-b.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-c.kt b/src/commonMain/kotlin/generated/gen-tags-c.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-c.kt rename to src/commonMain/kotlin/generated/gen-tags-c.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-d.kt b/src/commonMain/kotlin/generated/gen-tags-d.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-d.kt rename to src/commonMain/kotlin/generated/gen-tags-d.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-e.kt b/src/commonMain/kotlin/generated/gen-tags-e.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-e.kt rename to src/commonMain/kotlin/generated/gen-tags-e.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-f.kt b/src/commonMain/kotlin/generated/gen-tags-f.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-f.kt rename to src/commonMain/kotlin/generated/gen-tags-f.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-h.kt b/src/commonMain/kotlin/generated/gen-tags-h.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-h.kt rename to src/commonMain/kotlin/generated/gen-tags-h.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-i.kt b/src/commonMain/kotlin/generated/gen-tags-i.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-i.kt rename to src/commonMain/kotlin/generated/gen-tags-i.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-k.kt b/src/commonMain/kotlin/generated/gen-tags-k.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-k.kt rename to src/commonMain/kotlin/generated/gen-tags-k.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-l.kt b/src/commonMain/kotlin/generated/gen-tags-l.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-l.kt rename to src/commonMain/kotlin/generated/gen-tags-l.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-m.kt b/src/commonMain/kotlin/generated/gen-tags-m.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-m.kt rename to src/commonMain/kotlin/generated/gen-tags-m.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-n.kt b/src/commonMain/kotlin/generated/gen-tags-n.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-n.kt rename to src/commonMain/kotlin/generated/gen-tags-n.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-o.kt b/src/commonMain/kotlin/generated/gen-tags-o.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-o.kt rename to src/commonMain/kotlin/generated/gen-tags-o.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-p.kt b/src/commonMain/kotlin/generated/gen-tags-p.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-p.kt rename to src/commonMain/kotlin/generated/gen-tags-p.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-q.kt b/src/commonMain/kotlin/generated/gen-tags-q.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-q.kt rename to src/commonMain/kotlin/generated/gen-tags-q.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-r.kt b/src/commonMain/kotlin/generated/gen-tags-r.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-r.kt rename to src/commonMain/kotlin/generated/gen-tags-r.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-s.kt b/src/commonMain/kotlin/generated/gen-tags-s.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-s.kt rename to src/commonMain/kotlin/generated/gen-tags-s.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-t.kt b/src/commonMain/kotlin/generated/gen-tags-t.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-t.kt rename to src/commonMain/kotlin/generated/gen-tags-t.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-u.kt b/src/commonMain/kotlin/generated/gen-tags-u.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-u.kt rename to src/commonMain/kotlin/generated/gen-tags-u.kt diff --git a/shared/src/main/kotlin/generated/gen-tags-v.kt b/src/commonMain/kotlin/generated/gen-tags-v.kt similarity index 100% rename from shared/src/main/kotlin/generated/gen-tags-v.kt rename to src/commonMain/kotlin/generated/gen-tags-v.kt diff --git a/shared/src/main/kotlin/htmltag.kt b/src/commonMain/kotlin/htmltag.kt similarity index 100% rename from shared/src/main/kotlin/htmltag.kt rename to src/commonMain/kotlin/htmltag.kt diff --git a/shared/src/main/kotlin/measure-consumer.kt b/src/commonMain/kotlin/measure-consumer.kt similarity index 100% rename from shared/src/main/kotlin/measure-consumer.kt rename to src/commonMain/kotlin/measure-consumer.kt diff --git a/shared/src/main/kotlin/stream.kt b/src/commonMain/kotlin/stream.kt similarity index 100% rename from shared/src/main/kotlin/stream.kt rename to src/commonMain/kotlin/stream.kt diff --git a/shared/src/main/kotlin/trace-consumer.kt b/src/commonMain/kotlin/trace-consumer.kt similarity index 100% rename from shared/src/main/kotlin/trace-consumer.kt rename to src/commonMain/kotlin/trace-consumer.kt diff --git a/shared/src/main/kotlin/util.kt b/src/commonMain/kotlin/util.kt similarity index 100% rename from shared/src/main/kotlin/util.kt rename to src/commonMain/kotlin/util.kt diff --git a/js/src/main/kotlin/compatibility-js.kt b/src/jsMain/kotlin/compatibility-js.kt similarity index 100% rename from js/src/main/kotlin/compatibility-js.kt rename to src/jsMain/kotlin/compatibility-js.kt diff --git a/js/src/main/kotlin/dom-js.kt b/src/jsMain/kotlin/dom-js.kt similarity index 100% rename from js/src/main/kotlin/dom-js.kt rename to src/jsMain/kotlin/dom-js.kt diff --git a/js/src/main/kotlin/generated/gen-consumer-tags-js.kt b/src/jsMain/kotlin/generated/gen-consumer-tags-js.kt similarity index 100% rename from js/src/main/kotlin/generated/gen-consumer-tags-js.kt rename to src/jsMain/kotlin/generated/gen-consumer-tags-js.kt diff --git a/js/src/main/kotlin/generated/gen-event-attrs-js.kt b/src/jsMain/kotlin/generated/gen-event-attrs-js.kt similarity index 100% rename from js/src/main/kotlin/generated/gen-event-attrs-js.kt rename to src/jsMain/kotlin/generated/gen-event-attrs-js.kt diff --git a/js/src/main/kotlin/injector.kt b/src/jsMain/kotlin/injector.kt similarity index 100% rename from js/src/main/kotlin/injector.kt rename to src/jsMain/kotlin/injector.kt diff --git a/js/src/main/kotlin/trace-js.kt b/src/jsMain/kotlin/trace-js.kt similarity index 100% rename from js/src/main/kotlin/trace-js.kt rename to src/jsMain/kotlin/trace-js.kt diff --git a/js/src/main/kotlin/utilsImpl-js.kt b/src/jsMain/kotlin/utilsImpl-js.kt similarity index 100% rename from js/src/main/kotlin/utilsImpl-js.kt rename to src/jsMain/kotlin/utilsImpl-js.kt diff --git a/js/src/test/karma/karma.conf.js b/src/jsTest/karma/karma.conf.js similarity index 87% rename from js/src/test/karma/karma.conf.js rename to src/jsTest/karma/karma.conf.js index 2ba29746..fd0dced7 100644 --- a/js/src/test/karma/karma.conf.js +++ b/src/jsTest/karma/karma.conf.js @@ -20,11 +20,6 @@ module.exports = function (config) { config.set({ frameworks: ['qunit'], reporters: ['progress', 'junit'], - files: [ - '../../../target/test-js/kotlin.js', - '../../../target/classes/kotlinx-html-js.js', - '../../../target/test-js/*.js' - ], exclude: [], port: 9876, runnerPort: 9100, diff --git a/js/src/test/karma/package.json b/src/jsTest/karma/package.json similarity index 100% rename from js/src/test/karma/package.json rename to src/jsTest/karma/package.json diff --git a/js/src/test/kotlin/exceptions.kt b/src/jsTest/kotlin/exceptions.kt similarity index 100% rename from js/src/test/kotlin/exceptions.kt rename to src/jsTest/kotlin/exceptions.kt diff --git a/js/src/test/kotlin/injector.kt b/src/jsTest/kotlin/injector.kt similarity index 100% rename from js/src/test/kotlin/injector.kt rename to src/jsTest/kotlin/injector.kt diff --git a/js/src/test/kotlin/trees.kt b/src/jsTest/kotlin/trees.kt similarity index 100% rename from js/src/test/kotlin/trees.kt rename to src/jsTest/kotlin/trees.kt diff --git a/js/src/test/kotlin/unsafe.kt b/src/jsTest/kotlin/unsafe.kt similarity index 100% rename from js/src/test/kotlin/unsafe.kt rename to src/jsTest/kotlin/unsafe.kt diff --git a/jvm/src/main/kotlin/dom-jvm.kt b/src/jvmMain/kotlin/dom-jvm.kt similarity index 100% rename from jvm/src/main/kotlin/dom-jvm.kt rename to src/jvmMain/kotlin/dom-jvm.kt diff --git a/jvm/src/main/kotlin/trace-jvm.kt b/src/jvmMain/kotlin/trace-jvm.kt similarity index 100% rename from jvm/src/main/kotlin/trace-jvm.kt rename to src/jvmMain/kotlin/trace-jvm.kt diff --git a/jvm/src/main/kotlin/utilsImpl-jvm.kt b/src/jvmMain/kotlin/utilsImpl-jvm.kt similarity index 100% rename from jvm/src/main/kotlin/utilsImpl-jvm.kt rename to src/jvmMain/kotlin/utilsImpl-jvm.kt diff --git a/src/jvmTest/kotlin/compatibility.kt b/src/jvmTest/kotlin/compatibility.kt new file mode 100644 index 00000000..3d041c1a --- /dev/null +++ b/src/jvmTest/kotlin/compatibility.kt @@ -0,0 +1,36 @@ +package kotlinx.html.tests + +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.node.ArrayNode +import com.fasterxml.jackson.databind.node.TextNode +import java.io.File +import java.io.InputStreamReader +import kotlin.test.Test +import kotlin.test.assertEquals + +class CompatibilityTest { + // NOTE: this test shouldn't be started from IDEA because incremental compiler will only dump + // changed declarations + @Test + fun binaryCompatibilityTest() { + val objectMapper = ObjectMapper() + + val expectedJson = objectMapper.readTree(loadResource("declarations.json")) + val actualJson = objectMapper.readTree(File("build/declarations.json").readText()) + + val expected = objectMapper.sortByClass(expectedJson) + val actual = objectMapper.sortByClass(actualJson) + + if (expected != actual) { + // Show text diff. + assertEquals(expected.toPrettyString(), actual.toPrettyString()) + } + } + + private fun loadResource(path: String): InputStreamReader + = this::class.java.classLoader.getResourceAsStream(path)!!.reader() + + private fun ObjectMapper.sortByClass(node: JsonNode): JsonNode + = createArrayNode().addAll((node as ArrayNode).sortedBy { (it["class"] as TextNode).textValue() }) +} diff --git a/jvm/src/test/kotlin/custom-tag.kt b/src/jvmTest/kotlin/custom-tag.kt similarity index 100% rename from jvm/src/test/kotlin/custom-tag.kt rename to src/jvmTest/kotlin/custom-tag.kt diff --git a/jvm/src/test/kotlin/dom-trees.kt b/src/jvmTest/kotlin/dom-trees.kt similarity index 95% rename from jvm/src/test/kotlin/dom-trees.kt rename to src/jvmTest/kotlin/dom-trees.kt index a8cb0841..40e62a2c 100644 --- a/jvm/src/test/kotlin/dom-trees.kt +++ b/src/jvmTest/kotlin/dom-trees.kt @@ -1,230 +1,233 @@ -package kotlinx.html.tests - -import kotlinx.html.* -import kotlinx.html.consumers.filter -import kotlinx.html.dom.* -import kotlinx.html.dom.createHTMLDocument -import kotlin.test.assertEquals -import org.junit.Test as test - -class TestDOMTrees { - @test fun `able to create simple tree`() { - val tree = createHTMLDocument().div { - id = "test-node" - +"content" - } - - assertEquals("div", tree.getElementById("test-node")?.tagName?.toLowerCase()) - } - - @test fun `able to create complex tree and render it with pretty print`() { - val tree = createHTMLDocument().html { - body { - h1 { - +"header" - } - div { - +"content" - span { - +"yo" - } - } - } - } - - assertEquals("\n

header

contentyo
", tree.serialize(false)) - assertEquals(""" - - - -

header

-
contentyo -
- - """.trimIndent(), tree.serialize(true).trim().replace("\r\n", "\n")) - } - - @test fun `vals create and append support`() { - val document = createHTMLDocument().html { - body { - div { - id = "content" - } - } - } - - val contentNode = document.getElementById("content")!! - contentNode.append.p { - +"p1" - } - - val p2 = document.create.p { - +"p2" - } - contentNode.appendChild(p2) - - assertEquals(""" - - -
-

p1

-

p2

-
- - - """.trim().replace("\r\n", "\n"), document.serialize(true).trim().replace("\r\n", "\n")) - } - - @test fun `append function support`() { - val document = createHTMLDocument().html { - body { - div { - id = "content" - } - } - } - - val contentNode = document.getElementById("content")!! - - val nodes = contentNode.append { - p { - +"p1" - } - p { - +"p2" - p { - +"p3" - } - } - } - - assertEquals(2, nodes.size) - - assertEquals(""" - - -
-

p1

-

p2

p3

-

-
- - - """.trim().replace("\r\n", "\n"), document.serialize(true).trim().replace("\r\n", "\n")) - } - - @test fun `should compile wiki example`() { - println(document { - append.filter { if (it.tagName == "div") SKIP else PASS }.html { - body { - div { - a { +"link1" } - } - a { +"link2" } - } - } - }.serialize()) - } - - @test fun `svg should have namespace`() { - val d = document { - append.html { - body { - svg { - } - } - } - } - - assertEquals("\n", - d.serialize(false).trim().replace("\r\n", "\n")) - } - - @test fun `generalize tests`() { - fun T.genericFlow() where T : HtmlBlockTag { - classes += "aha" - +"content" - +Entities.nbsp - div { - } - } - - fun T.genericPhrasing() where T : HtmlInlineTag { - classes += "aha" - +"content" - +Entities.nbsp - span { } - } - - fun T.genericMetaData() where T : HtmlHeadTag { - classes += "aha" - +"content" - +Entities.nbsp - meta("a") - script(ScriptType.textJavaScript) { } - } - - document { - append.html { - head { - genericMetaData() - } - body { - div { - genericFlow() - p { - genericPhrasing() - } - } - } - } - } - } - - @test fun `script content`() { - val document = document { - append.html { - head { - script(ScriptType.textJavaScript) { - unsafe { - raw("fun f() { return 1; }") - } - } - } - } - } - - - assertEquals("\n" + - "", - document.serialize(false).trim().replace("\r\n", "\n")) - } - - @test fun testPrepend() { - val document = createHTMLDocument().html { - body { - a { text("aaa") } - } - } - - document.getElementsByTagName("body").item(0).prepend { - p { - text("OK") - } - } - - assertEquals("\n" + - "

OK

aaa", - document.serialize(false).trim().replace("\r\n", "\n")) - } - - @test fun testComment() { - val document = createHTMLDocument().html { - comment("commented") - } - - assertEquals("\n" + - "", - document.serialize(false).trim().replace("\r\n", "\n")) - } +package kotlinx.html.tests + +import kotlinx.html.* +import kotlinx.html.consumers.filter +import kotlinx.html.dom.* +import kotlinx.html.dom.createHTMLDocument +import kotlin.test.assertEquals +import org.junit.Test as test + +class TestDOMTrees { + @test fun `able to create simple tree`() { + val tree = createHTMLDocument().div { + id = "test-node" + +"content" + } + + assertEquals("div", tree.getElementById("test-node")?.tagName?.toLowerCase()) + } + + @test fun `able to create complex tree and render it with pretty print`() { + val tree = createHTMLDocument().html { + body { + h1 { + +"header" + } + div { + +"content" + span { + +"yo" + } + } + } + } + + assertEquals("\n

header

contentyo
", tree.serialize(false)) + assertEquals(""" + + + +

header

+
+ contentyo +
+ + """.trimIndent(), tree.serialize(true).trim().replace("\r\n", "\n")) + } + + @test fun `vals create and append support`() { + val document = createHTMLDocument().html { + body { + div { + id = "content" + } + } + } + + val contentNode = document.getElementById("content")!! + contentNode.append.p { + +"p1" + } + + val p2 = document.create.p { + +"p2" + } + contentNode.appendChild(p2) + + assertEquals(""" + + +
+

p1

+

p2

+
+ + + """.trim().replace("\r\n", "\n"), document.serialize(true).trim().replace("\r\n", "\n")) + } + + @test fun `append function support`() { + val document = createHTMLDocument().html { + body { + div { + id = "content" + } + } + } + + val contentNode = document.getElementById("content")!! + + val nodes = contentNode.append { + p { + +"p1" + } + p { + +"p2" + p { + +"p3" + } + } + } + + assertEquals(2, nodes.size) + + assertEquals(""" + + +
+

p1

+

+ p2 +

p3

+

+
+ + + """.trim().replace("\r\n", "\n"), document.serialize(true).trim().replace("\r\n", "\n")) + } + + @test fun `should compile wiki example`() { + println(document { + append.filter { if (it.tagName == "div") SKIP else PASS }.html { + body { + div { + a { +"link1" } + } + a { +"link2" } + } + } + }.serialize()) + } + + @test fun `svg should have namespace`() { + val d = document { + append.html { + body { + svg { + } + } + } + } + + assertEquals("\n", + d.serialize(false).trim().replace("\r\n", "\n")) + } + + @test fun `generalize tests`() { + fun T.genericFlow() where T : HtmlBlockTag { + classes += "aha" + +"content" + +Entities.nbsp + div { + } + } + + fun T.genericPhrasing() where T : HtmlInlineTag { + classes += "aha" + +"content" + +Entities.nbsp + span { } + } + + fun T.genericMetaData() where T : HtmlHeadTag { + classes += "aha" + +"content" + +Entities.nbsp + meta("a") + script(ScriptType.textJavaScript) { } + } + + document { + append.html { + head { + genericMetaData() + } + body { + div { + genericFlow() + p { + genericPhrasing() + } + } + } + } + } + } + + @test fun `script content`() { + val document = document { + append.html { + head { + script(ScriptType.textJavaScript) { + unsafe { + raw("fun f() { return 1; }") + } + } + } + } + } + + + assertEquals("\n" + + "", + document.serialize(false).trim().replace("\r\n", "\n")) + } + + @test fun testPrepend() { + val document = createHTMLDocument().html { + body { + a { text("aaa") } + } + } + + document.getElementsByTagName("body").item(0).prepend { + p { + text("OK") + } + } + + assertEquals("\n" + + "

OK

aaa", + document.serialize(false).trim().replace("\r\n", "\n")) + } + + @test fun testComment() { + val document = createHTMLDocument().html { + comment("commented") + } + + assertEquals("\n" + + "", + document.serialize(false).trim().replace("\r\n", "\n")) + } } \ No newline at end of file diff --git a/jvm/src/test/kotlin/exceptions.kt b/src/jvmTest/kotlin/exceptions.kt similarity index 100% rename from jvm/src/test/kotlin/exceptions.kt rename to src/jvmTest/kotlin/exceptions.kt diff --git a/jvm/src/test/kotlin/html5-tags.kt b/src/jvmTest/kotlin/html5-tags.kt similarity index 96% rename from jvm/src/test/kotlin/html5-tags.kt rename to src/jvmTest/kotlin/html5-tags.kt index 712b55fc..dee88ff6 100644 --- a/jvm/src/test/kotlin/html5-tags.kt +++ b/src/jvmTest/kotlin/html5-tags.kt @@ -54,7 +54,8 @@ class Html5TagsTest {

header

-
contentyo +
+ contentyo
""".trimIndent(), tree.serialize(true).trim().replace("\r\n", "\n")) diff --git a/jvm/src/test/kotlin/huge.kt b/src/jvmTest/kotlin/huge.kt similarity index 96% rename from jvm/src/test/kotlin/huge.kt rename to src/jvmTest/kotlin/huge.kt index 1ac950b6..f9192209 100644 --- a/jvm/src/test/kotlin/huge.kt +++ b/src/jvmTest/kotlin/huge.kt @@ -1,15 +1,15 @@ package kotlinx.html.tests import kotlinx.html.* -import kotlinx.html.stream.* -import org.junit.* -import kotlin.system.* +import kotlinx.html.stream.appendHTML +import org.junit.Test +import kotlin.system.measureTimeMillis open class HugeStreamingBenchmark { @Test fun testName() { val sb = StringBuilder(8192) - val count = 10000000 + val count = 100 val time = measureTimeMillis { for (i in 1..count) { testHuge(sb) diff --git a/jvm/src/test/kotlin/streaming.kt b/src/jvmTest/kotlin/streaming.kt similarity index 95% rename from jvm/src/test/kotlin/streaming.kt rename to src/jvmTest/kotlin/streaming.kt index 57bd1d06..44d575de 100644 --- a/jvm/src/test/kotlin/streaming.kt +++ b/src/jvmTest/kotlin/streaming.kt @@ -232,16 +232,31 @@ class TestStreaming { @test fun `test measure consumer with loop inside`() { val count = 1000 - val rs = StringBuilder(26 * (count + 1)).appendHTML(false).measureTime().div { + val builder = StringBuilder(26 * (count + 1)).appendHTML(false) + + var minStart = 0L + var maxStart = 0L + var minEnd = 0L + var maxEnd = 0L + + minStart = currentTimeMillis() + val rs = builder.measureTime().div { + maxStart = currentTimeMillis() for (i in 1..count) { div { p { +"node$i" } } } + minEnd = currentTimeMillis() } + maxEnd = currentTimeMillis() + + val maxTime = maxEnd - minStart + val minTime = minEnd - maxStart - assertTrue(rs.time > 0) - assertTrue(rs.time < count.toLong()) + val errorMessage = "Expected time should be between $minTime and $maxTime ms, but actual is ${rs.time} ms" + assertTrue(errorMessage) { rs.time >= minTime } + assertTrue(errorMessage) { rs.time <= maxTime } val expected = StringBuilder().apply { append("
") diff --git a/jvm/src/test/kotlin/unsafe.kt b/src/jvmTest/kotlin/unsafe.kt similarity index 100% rename from jvm/src/test/kotlin/unsafe.kt rename to src/jvmTest/kotlin/unsafe.kt diff --git a/jvm/src/test/resources/declarations.json b/src/jvmTest/resources/declarations.json similarity index 100% rename from jvm/src/test/resources/declarations.json rename to src/jvmTest/resources/declarations.json From 751f66d67be056afe3cfc045d76c18384fe5f251 Mon Sep 17 00:00:00 2001 From: dmitrievanthony Date: Mon, 13 Jan 2020 16:00:01 +0300 Subject: [PATCH 2/4] Use Kotlin official code style. --- .../src/main/kotlin/kotlinx/html/js/package.kt | 2 +- gradle.properties | 3 ++- src/commonMain/kotlin/delayed-consumer.kt | 7 ++----- src/commonMain/kotlin/delegating-map.kt | 3 +-- src/commonMain/kotlin/exception-consumer.kt | 3 +-- src/commonMain/kotlin/filter-consumer.kt | 7 ++----- src/commonMain/kotlin/finalize-consumer.kt | 7 ++----- src/commonMain/kotlin/measure-consumer.kt | 2 +- src/commonMain/kotlin/stream.kt | 2 +- src/jsMain/kotlin/dom-js.kt | 1 - src/jsMain/kotlin/utilsImpl-js.kt | 2 +- src/jsTest/kotlin/exceptions.kt | 14 ++++++-------- src/jsTest/kotlin/injector.kt | 3 +-- src/jsTest/kotlin/trees.kt | 1 - src/jsTest/kotlin/unsafe.kt | 1 - src/jvmMain/kotlin/dom-jvm.kt | 2 +- src/jvmTest/kotlin/compatibility.kt | 12 ++++-------- src/jvmTest/kotlin/dom-trees.kt | 5 ++--- src/jvmTest/kotlin/exceptions.kt | 7 +++---- src/jvmTest/kotlin/html5-tags.kt | 5 +---- src/jvmTest/kotlin/huge.kt | 6 +++--- 21 files changed, 35 insertions(+), 60 deletions(-) diff --git a/buildSrc/src/main/kotlin/kotlinx/html/js/package.kt b/buildSrc/src/main/kotlin/kotlinx/html/js/package.kt index b6618981..cf9f5074 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/js/package.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/js/package.kt @@ -1,6 +1,6 @@ package kotlinx.html.js -import org.gradle.api.Project +import org.gradle.api.* private const val GITHUB_ORGANIZATION = "Kotlin" private const val GITHUB_REPOSITORY = "kotlin.html" diff --git a/gradle.properties b/gradle.properties index eb12f73a..24b55e47 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1,3 @@ # The following property is required to mitigate issue https://github.com/gradle/gradle/issues/11412. -systemProp.org.gradle.internal.publish.checksums.insecure=true \ No newline at end of file +systemProp.org.gradle.internal.publish.checksums.insecure=true +kotlin.code.style=official \ No newline at end of file diff --git a/src/commonMain/kotlin/delayed-consumer.kt b/src/commonMain/kotlin/delayed-consumer.kt index 5d61971b..4a2cb971 100644 --- a/src/commonMain/kotlin/delayed-consumer.kt +++ b/src/commonMain/kotlin/delayed-consumer.kt @@ -1,10 +1,7 @@ package kotlinx.html.consumers -import kotlinx.html.Entities -import kotlinx.html.Tag -import kotlinx.html.TagConsumer -import kotlinx.html.Unsafe -import org.w3c.dom.events.Event +import kotlinx.html.* +import org.w3c.dom.events.* class DelayedConsumer(val downstream : TagConsumer) : TagConsumer { private var delayed : Tag? = null diff --git a/src/commonMain/kotlin/delegating-map.kt b/src/commonMain/kotlin/delegating-map.kt index d5d8679a..25d39f75 100644 --- a/src/commonMain/kotlin/delegating-map.kt +++ b/src/commonMain/kotlin/delegating-map.kt @@ -1,7 +1,6 @@ package kotlinx.html.impl -import kotlinx.html.Tag -import kotlinx.html.TagConsumer +import kotlinx.html.* class DelegatingMap(initialValues : Map, private val tag : Tag, private val consumer : () -> TagConsumer<*>) : MutableMap { private var backing: Map = initialValues diff --git a/src/commonMain/kotlin/exception-consumer.kt b/src/commonMain/kotlin/exception-consumer.kt index de5cd374..381ad93c 100644 --- a/src/commonMain/kotlin/exception-consumer.kt +++ b/src/commonMain/kotlin/exception-consumer.kt @@ -1,7 +1,6 @@ package kotlinx.html.consumers -import kotlinx.html.Tag -import kotlinx.html.TagConsumer +import kotlinx.html.* private class DelegatingExceptionConsumer( val underlying: TagConsumer, diff --git a/src/commonMain/kotlin/filter-consumer.kt b/src/commonMain/kotlin/filter-consumer.kt index 49110f51..2e3d95d5 100644 --- a/src/commonMain/kotlin/filter-consumer.kt +++ b/src/commonMain/kotlin/filter-consumer.kt @@ -1,10 +1,7 @@ package kotlinx.html.consumers -import kotlinx.html.Entities -import kotlinx.html.Tag -import kotlinx.html.TagConsumer -import kotlinx.html.Unsafe -import org.w3c.dom.events.Event +import kotlinx.html.* +import org.w3c.dom.events.* object PredicateResults { val PASS = PredicateResult.PASS diff --git a/src/commonMain/kotlin/finalize-consumer.kt b/src/commonMain/kotlin/finalize-consumer.kt index b0f6d332..96768b22 100644 --- a/src/commonMain/kotlin/finalize-consumer.kt +++ b/src/commonMain/kotlin/finalize-consumer.kt @@ -1,10 +1,7 @@ package kotlinx.html.consumers -import kotlinx.html.Entities -import kotlinx.html.Tag -import kotlinx.html.TagConsumer -import kotlinx.html.Unsafe -import org.w3c.dom.events.Event +import kotlinx.html.* +import org.w3c.dom.events.* class FinalizeConsumer(val downstream : TagConsumer, val block : (F, Boolean) -> T) : TagConsumer { private var level = 0 diff --git a/src/commonMain/kotlin/measure-consumer.kt b/src/commonMain/kotlin/measure-consumer.kt index c054e7c1..7307bbd4 100644 --- a/src/commonMain/kotlin/measure-consumer.kt +++ b/src/commonMain/kotlin/measure-consumer.kt @@ -1,7 +1,7 @@ package kotlinx.html.consumers import kotlinx.html.* -import org.w3c.dom.events.Event +import org.w3c.dom.events.* data class TimedResult(val result: T, val time: Long) val TimedResult.out: O diff --git a/src/commonMain/kotlin/stream.kt b/src/commonMain/kotlin/stream.kt index 4fe09996..ae8f8962 100644 --- a/src/commonMain/kotlin/stream.kt +++ b/src/commonMain/kotlin/stream.kt @@ -2,7 +2,7 @@ package kotlinx.html.stream import kotlinx.html.* import kotlinx.html.consumers.* -import org.w3c.dom.events.Event +import org.w3c.dom.events.* class HTMLStreamBuilder(val out : O, val prettyPrint : Boolean, val xhtmlCompatible: Boolean) : TagConsumer { private var level = 0 diff --git a/src/jsMain/kotlin/dom-js.kt b/src/jsMain/kotlin/dom-js.kt index ef44968b..7892cbe1 100644 --- a/src/jsMain/kotlin/dom-js.kt +++ b/src/jsMain/kotlin/dom-js.kt @@ -4,7 +4,6 @@ import kotlinx.html.* import kotlinx.html.consumers.* import org.w3c.dom.* import org.w3c.dom.events.* -import kotlin.dom.* @Suppress("NOTHING_TO_INLINE") private inline fun HTMLElement.setEvent(name: String, noinline callback : (Event) -> Unit) : Unit { diff --git a/src/jsMain/kotlin/utilsImpl-js.kt b/src/jsMain/kotlin/utilsImpl-js.kt index 3dc8bacb..c39bd7e7 100644 --- a/src/jsMain/kotlin/utilsImpl-js.kt +++ b/src/jsMain/kotlin/utilsImpl-js.kt @@ -1,5 +1,5 @@ package kotlinx.html -import kotlin.js.Date +import kotlin.js.* actual fun currentTimeMillis(): Long = Date().getTime().toLong() diff --git a/src/jsTest/kotlin/exceptions.kt b/src/jsTest/kotlin/exceptions.kt index 43f51d85..47a83545 100644 --- a/src/jsTest/kotlin/exceptions.kt +++ b/src/jsTest/kotlin/exceptions.kt @@ -1,11 +1,9 @@ -import kotlinx.html.consumers.catch -import kotlinx.html.dom.append -import kotlinx.html.h1 -import kotlinx.html.h2 -import kotlinx.html.js.div -import kotlin.test.Test -import kotlin.browser.document -import kotlin.test.assertEquals +import kotlinx.html.* +import kotlinx.html.consumers.* +import kotlinx.html.dom.* +import kotlinx.html.js.* +import kotlin.browser.* +import kotlin.test.* class TestExceptions { diff --git a/src/jsTest/kotlin/injector.kt b/src/jsTest/kotlin/injector.kt index 558980b5..64d19d14 100644 --- a/src/jsTest/kotlin/injector.kt +++ b/src/jsTest/kotlin/injector.kt @@ -4,8 +4,7 @@ import kotlinx.html.* import kotlinx.html.dom.* import kotlinx.html.injector.* import kotlinx.html.js.* -import org.w3c.dom.HTMLDivElement -import org.w3c.dom.HTMLParagraphElement +import org.w3c.dom.* import kotlin.browser.* import kotlin.properties.* import kotlin.test.* diff --git a/src/jsTest/kotlin/trees.kt b/src/jsTest/kotlin/trees.kt index 3105ce9b..8e3507e0 100644 --- a/src/jsTest/kotlin/trees.kt +++ b/src/jsTest/kotlin/trees.kt @@ -6,7 +6,6 @@ import kotlinx.html.dom.* import kotlinx.html.js.* import org.w3c.dom.* import kotlin.browser.* -import kotlin.dom.* import kotlin.test.* import kotlin.test.Test as test diff --git a/src/jsTest/kotlin/unsafe.kt b/src/jsTest/kotlin/unsafe.kt index f425ffd8..b558d32c 100644 --- a/src/jsTest/kotlin/unsafe.kt +++ b/src/jsTest/kotlin/unsafe.kt @@ -3,7 +3,6 @@ package kotlinx.html.tests.unsafes import kotlinx.html.* import kotlinx.html.dom.* import kotlinx.html.stream.* -import kotlin.test.Test import kotlin.browser.* import kotlin.test.* diff --git a/src/jvmMain/kotlin/dom-jvm.kt b/src/jvmMain/kotlin/dom-jvm.kt index 87cf0bcb..6de00345 100644 --- a/src/jvmMain/kotlin/dom-jvm.kt +++ b/src/jvmMain/kotlin/dom-jvm.kt @@ -4,7 +4,7 @@ import kotlinx.html.* import kotlinx.html.consumers.* import org.w3c.dom.* import org.w3c.dom.events.* -import org.xml.sax.InputSource +import org.xml.sax.* import java.io.* import java.util.* import javax.xml.parsers.* diff --git a/src/jvmTest/kotlin/compatibility.kt b/src/jvmTest/kotlin/compatibility.kt index 3d041c1a..510736aa 100644 --- a/src/jvmTest/kotlin/compatibility.kt +++ b/src/jvmTest/kotlin/compatibility.kt @@ -1,13 +1,9 @@ package kotlinx.html.tests -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.ObjectMapper -import com.fasterxml.jackson.databind.node.ArrayNode -import com.fasterxml.jackson.databind.node.TextNode -import java.io.File -import java.io.InputStreamReader -import kotlin.test.Test -import kotlin.test.assertEquals +import com.fasterxml.jackson.databind.* +import com.fasterxml.jackson.databind.node.* +import java.io.* +import kotlin.test.* class CompatibilityTest { // NOTE: this test shouldn't be started from IDEA because incremental compiler will only dump diff --git a/src/jvmTest/kotlin/dom-trees.kt b/src/jvmTest/kotlin/dom-trees.kt index 40e62a2c..97eb80a3 100644 --- a/src/jvmTest/kotlin/dom-trees.kt +++ b/src/jvmTest/kotlin/dom-trees.kt @@ -1,10 +1,9 @@ package kotlinx.html.tests import kotlinx.html.* -import kotlinx.html.consumers.filter +import kotlinx.html.consumers.* import kotlinx.html.dom.* -import kotlinx.html.dom.createHTMLDocument -import kotlin.test.assertEquals +import kotlin.test.* import org.junit.Test as test class TestDOMTrees { diff --git a/src/jvmTest/kotlin/exceptions.kt b/src/jvmTest/kotlin/exceptions.kt index b89046df..88c0eb71 100644 --- a/src/jvmTest/kotlin/exceptions.kt +++ b/src/jvmTest/kotlin/exceptions.kt @@ -1,9 +1,8 @@ import kotlinx.html.* -import kotlinx.html.consumers.catch -import kotlinx.html.stream.appendHTML +import kotlinx.html.consumers.* +import kotlinx.html.stream.* import org.junit.Test -import kotlin.test.assertEquals -import kotlin.test.assertTrue +import kotlin.test.* class TestExceptions { @Test fun `default exception must result in empty tag`() { diff --git a/src/jvmTest/kotlin/html5-tags.kt b/src/jvmTest/kotlin/html5-tags.kt index dee88ff6..9b84f760 100644 --- a/src/jvmTest/kotlin/html5-tags.kt +++ b/src/jvmTest/kotlin/html5-tags.kt @@ -1,11 +1,8 @@ package kotlinx.html.tests import kotlinx.html.* -import kotlinx.html.consumers.filter import kotlinx.html.dom.* -import kotlinx.html.dom.createHTMLDocument -import kotlin.test.Test -import kotlin.test.assertEquals +import kotlin.test.* import org.junit.Test as test class Html5TagsTest { diff --git a/src/jvmTest/kotlin/huge.kt b/src/jvmTest/kotlin/huge.kt index f9192209..56bd3554 100644 --- a/src/jvmTest/kotlin/huge.kt +++ b/src/jvmTest/kotlin/huge.kt @@ -1,9 +1,9 @@ package kotlinx.html.tests import kotlinx.html.* -import kotlinx.html.stream.appendHTML -import org.junit.Test -import kotlin.system.measureTimeMillis +import kotlinx.html.stream.* +import org.junit.* +import kotlin.system.* open class HugeStreamingBenchmark { @Test From d415d2025460b58a18aace801262046d7f02ba56 Mon Sep 17 00:00:00 2001 From: dmitrievanthony Date: Mon, 13 Jan 2020 16:18:33 +0300 Subject: [PATCH 3/4] Use Gradle 5.6.4. --- gradle/wrapper/gradle-wrapper.jar | Bin 55616 -> 58702 bytes gradle/wrapper/gradle-wrapper.properties | 2 +- gradlew | 29 ++++++++++------------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 5c2d1cf016b3885f6930543d57b744ea8c220a1a..cc4fdc293d0e50b0ad9b65c16e7ddd1db2f6025b 100644 GIT binary patch delta 16535 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 Date: Mon, 13 Jan 2020 16:30:39 +0300 Subject: [PATCH 4/4] Fix Kotlin code style. --- buildSrc/src/main/kotlin/kotlinx/html/generate/codegen.kt | 2 +- buildSrc/src/main/kotlin/kotlinx/html/generate/kdoc.kt | 7 +++---- buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt | 4 +--- .../main/kotlin/kotlinx/html/generate/resource-loader.kt | 2 +- buildSrc/src/main/kotlin/kotlinx/html/generate/rules.kt | 2 +- .../src/main/kotlin/kotlinx/html/generate/xsdparser.kt | 8 +++----- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/codegen.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/codegen.kt index 28a81942..b05c0eb5 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/codegen.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/codegen.kt @@ -1,6 +1,6 @@ package kotlinx.html.generate -import java.util.ArrayList +import java.util.* interface Const data class StringConst(val value : String) : Const diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/kdoc.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/kdoc.kt index 2904abf8..3f69c4a6 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/kdoc.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/kdoc.kt @@ -1,9 +1,8 @@ package kotlinx.html.generate -import org.w3c.dom.Node -import org.w3c.dom.NodeList -import java.net.URL -import javax.xml.parsers.DocumentBuilderFactory +import org.w3c.dom.* +import java.net.* +import javax.xml.parsers.* private val HTML_TABLE_URL = "htmltable.xml".asResourceUrl() private val HTML5_TABLE_URL = "html5table.xml".asResourceUrl() diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt index 01a7844d..ef23d2a3 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/main.kt @@ -1,8 +1,6 @@ package kotlinx.html.generate -import java.io.File -import java.io.FileOutputStream -import java.io.InputStreamReader +import java.io.* fun generate(packg: String, todir: String, jsdir: String) { fillRepository() diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/resource-loader.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/resource-loader.kt index df408632..5efaa9b4 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/resource-loader.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/resource-loader.kt @@ -1,6 +1,6 @@ package kotlinx.html.generate -import java.net.URL +import java.net.* private class ResourceLoader diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/rules.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/rules.kt index b101d9cd..f7b227e0 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/rules.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/rules.kt @@ -1,6 +1,6 @@ package kotlinx.html.generate -import java.util.regex.Pattern +import java.util.regex.* val globalSuggestedAttributes = listOf( "a" to "href", diff --git a/buildSrc/src/main/kotlin/kotlinx/html/generate/xsdparser.kt b/buildSrc/src/main/kotlin/kotlinx/html/generate/xsdparser.kt index 3bb67a97..0f3e1fb3 100644 --- a/buildSrc/src/main/kotlin/kotlinx/html/generate/xsdparser.kt +++ b/buildSrc/src/main/kotlin/kotlinx/html/generate/xsdparser.kt @@ -1,11 +1,9 @@ package kotlinx.html.generate -import com.sun.xml.xsom.XSAttGroupDecl -import com.sun.xml.xsom.XSAttributeDecl -import com.sun.xml.xsom.XSTerm -import com.sun.xml.xsom.parser.XSOMParser +import com.sun.xml.xsom.* +import com.sun.xml.xsom.parser.* import java.util.* -import javax.xml.parsers.SAXParserFactory +import javax.xml.parsers.* val SCHEME_URL = "html_5.xsd".asResourceUrl() const val HTML_NAMESPACE = "html-5"