+
<#if headline != "">
-
${headline}
+

+
+
+ ${headline}
+
#if>
<#if preheadline != "">
-
+
<#if preheadlineLink != "">
${preheadline}
@@ -66,7 +70,7 @@ limitations under the License.
#if>
<#if subheadline != "">
- ${subheadline}
+
${subheadline}
#if>
<#nested>
diff --git a/engine/src/main/resources/template/macros/scenario.ftl b/engine/src/main/resources/template/macros/scenario.ftl
index 64659d31..0a6e9e00 100644
--- a/engine/src/main/resources/template/macros/scenario.ftl
+++ b/engine/src/main/resources/template/macros/scenario.ftl
@@ -110,9 +110,9 @@ limitations under the License.
#if>
- <#if element.firstExceptionClass != "">
+ <#if element.firstExceptionSummary != "">
${element.firstExceptionClass}
+ style="word-break: break-word">${element.firstExceptionSummary}
#if>
<#if element.isMultiRunParent()>
@@ -123,12 +123,13 @@ limitations under the License.
Previous run from
- ${childElement.startDateString}, ${childElement.startTimeString}
+ ${childElement.startDateString}
+ , ${childElement.startTimeString}
<@common.status status=childElement.status.statusString/>
- <#if childElement.firstExceptionClass != "">
+ <#if childElement.firstExceptionSummary != "">
${childElement.firstExceptionClass}
+ style="word-break: break-word">${childElement.firstExceptionSummary}
#if>
#list>
@@ -163,6 +164,7 @@ limitations under the License.
<#list step.embeddings as attachment>
<#assign attachmentID = attachment.hashCode()?string["0"]>
+ <#assign isTextAttachment = attachment.mimeType == "TXT" || attachment.mimeType == "XML" || attachment.mimeType == "JSON" || attachment.mimeType == "APPLICATION_XML">
Toggle |
@@ -171,6 +173,11 @@ limitations under the License.
<#else>
${attachment.mimeType} attachment
#if>
+ <#if isTextAttachment>
+
+ #if>
- <#elseif attachment.mimeType == "TXT" || attachment.mimeType == "XML" || attachment.mimeType == "JSON" || attachment.mimeType == "APPLICATION_XML">
+ <#elseif isTextAttachment>
${attachment.decodedData}
<#elseif attachment.mimeType == "MP4">
<#if attachment.externalContent>
@@ -209,7 +216,10 @@ limitations under the License.
<#macro errorMessage step>
<#if step.result.hasErrorMessage()>
-
+
+
${step.result.returnErrorMessageWithClickableLinks()}
@@ -228,6 +238,9 @@ limitations under the License.
+
${step.output?join("
")}
diff --git a/engine/src/main/resources/template/scenario-detail.ftl b/engine/src/main/resources/template/scenario-detail.ftl
index d1861e45..93643d15 100644
--- a/engine/src/main/resources/template/scenario-detail.ftl
+++ b/engine/src/main/resources/template/scenario-detail.ftl
@@ -242,6 +242,9 @@ preheadlineLink="pages/feature-scenarios/feature_${element.featureIndex?c}.html"
<#if (step.docString.value)?? >
+
${step.docString.returnWithClickableLinks()}
@@ -340,6 +343,9 @@ preheadlineLink="pages/feature-scenarios/feature_${element.featureIndex?c}.html"
<#if (step.docString.value)?? >
+
${step.docString.returnWithClickableLinks()}
diff --git a/engine/src/main/resources/template/scenario-summary.ftl b/engine/src/main/resources/template/scenario-summary.ftl
index 59cf4456..6d9eec52 100644
--- a/engine/src/main/resources/template/scenario-summary.ftl
+++ b/engine/src/main/resources/template/scenario-summary.ftl
@@ -22,10 +22,19 @@ limitations under the License.
<#if (tagFilter??)>
<#assign base = "./../..">
- <#assign headline = "Scenarios tagged with '${tagFilter.name}'">
+ <#assign headline = "Scenarios tagged with">
<#assign pageName = "Tagged Scenarios">
<#assign highlight = "tag_summary">
- <#assign subheadline = "">
+ <#assign subheadline = "${tagFilter.name}">
+ <#assign subsubheadline = "">
+ <#assign preheadline = "">
+ <#assign preheadlineLink = "">
+<#elseif (exceptionFilter??)>
+ <#assign base = "./../..">
+ <#assign headline = "Scenarios with Exception">
+ <#assign pageName = "Scenarios with Exception">
+ <#assign highlight = "exception_summary">
+ <#assign subheadline = "${exceptionFilter}">
<#assign subsubheadline = "">
<#assign preheadline = "">
<#assign preheadlineLink = "">
@@ -40,10 +49,10 @@ limitations under the License.
<#assign preheadlineLink="pages/feature-scenarios/feature_${featureFilter.index?c}.html">
<#elseif (stepFilter??)>
<#assign base = "./../..">
- <#assign headline = "Scenarios using Step '${stepFilter.returnNameWithArgumentPlaceholders()}'">
+ <#assign headline = "Scenarios using Step">
<#assign pageName = "Scenarios with Step">
<#assign highlight = "step_summary">
- <#assign subheadline = "">
+ <#assign subheadline = "${stepFilter.returnNameWithArgumentPlaceholders()}">
<#assign subsubheadline = "">
<#assign preheadline = "">
<#assign preheadlineLink = "">
diff --git a/engine/src/main/resources/template/snippets/js.ftl b/engine/src/main/resources/template/snippets/js.ftl
index 35ca10e6..ff4998e2 100644
--- a/engine/src/main/resources/template/snippets/js.ftl
+++ b/engine/src/main/resources/template/snippets/js.ftl
@@ -150,4 +150,15 @@ limitations under the License.
}
}, 500);
}
+
+ function copyText(elementId) {
+ let text = document.getElementById(elementId).innerText;
+ if (text.startsWith("Copy to clipboard")) {
+ text = text.substring(18);
+ }
+ navigator.clipboard.writeText(text)
+ .catch((error) => {
+ console.error('Failed to copy text from ' + elementId + ':', error);
+ });
+ }
\ No newline at end of file
diff --git a/engine/src/main/resources/template/tree-view.ftl b/engine/src/main/resources/template/tree-view.ftl
index 0e78e4b8..db7b29a0 100644
--- a/engine/src/main/resources/template/tree-view.ftl
+++ b/engine/src/main/resources/template/tree-view.ftl
@@ -30,31 +30,48 @@ preheadlineLink="">
<@page.card width="12" title="${numberOfFeatures} ${common.pluralizeFn('Feature', numberOfFeatures)} with ${numberOfScenarios} ${common.pluralizeFn('Scenario', numberOfScenarios)}" subtitle="" classes="">
-
- <#list elements as feature, scenarios>
- <#assign tooltipText = "">
- <#if feature.description?has_content>
- <#assign tooltipText = "${feature.description} | ">
- #if>
- <#assign tooltipText = "${tooltipText}${feature.uri}">
- -
-
- ${feature.name?html}
-
-
-
- <#list scenarios as scenario>
- <#if ((!scenario.isMultiRunParent() && !scenario.isMultiRunChild()) || scenario.isMultiRunParent()) >
- - ${scenario.name?html}
-
- #if>
+ <#macro renderTree node>
+ <#if node.children?has_content>
+
+ <#list node.children?values as child>
+ -
+ <#if child.features??>
+ <#list child.features as feature, scenarios>
+ <#assign tooltipText = "${feature.uri}">
+ <#if feature.description?has_content>
+ <#assign tooltipText = "${tooltipText} | ${feature.description}">
+ #if>
+
+
+ ${feature.name?html}
+
+
+ <#if scenarios??>
+
+ <#list scenarios as scenario>
+ <#if ((!scenario.isMultiRunParent() && !scenario.isMultiRunChild()) || scenario.isMultiRunParent()) >
+ -
+ ${scenario.name?html}
+
+ #if>
+ #list>
+
+ #if>
+
+ #list>
+ <#else>
+ ${child.name}/
+ #if>
+ <@renderTree node=child/>
+
#list>
-
- #list>
-
+ #if>
+ #macro>
+
+ <@renderTree node=rootTreeNode/>
+
@page.card>
@page.page>
diff --git a/engine/src/test/java/com/trivago/cluecumber/engine/rendering/ReportGeneratorTest.java b/engine/src/test/java/com/trivago/cluecumber/engine/rendering/ReportGeneratorTest.java
index d51419dd..6f932a07 100644
--- a/engine/src/test/java/com/trivago/cluecumber/engine/rendering/ReportGeneratorTest.java
+++ b/engine/src/test/java/com/trivago/cluecumber/engine/rendering/ReportGeneratorTest.java
@@ -92,7 +92,7 @@ public void fileOperationsTest() throws CluecumberException {
reportGenerator.generateReport(allScenariosPageCollection);
- verify(fileSystemManager, times(9)).createDirectory(anyString());
- verify(fileSystemManager, times(18)).copyResourceFromJar(anyString(), anyString());
+ verify(fileSystemManager, times(10)).createDirectory(anyString());
+ verify(fileSystemManager, times(19)).copyResourceFromJar(anyString(), anyString());
}
}
diff --git a/engine/src/test/java/com/trivago/cluecumber/engine/rendering/pages/pojos/pagecollections/PojoTest.java b/engine/src/test/java/com/trivago/cluecumber/engine/rendering/pages/pojos/pagecollections/PojoTest.java
index b57c00b0..0d28b7ab 100644
--- a/engine/src/test/java/com/trivago/cluecumber/engine/rendering/pages/pojos/pagecollections/PojoTest.java
+++ b/engine/src/test/java/com/trivago/cluecumber/engine/rendering/pages/pojos/pagecollections/PojoTest.java
@@ -15,7 +15,7 @@
import java.util.List;
public class PojoTest {
- private static final int EXPECTED_CLASS_COUNT = 12;
+ private static final int EXPECTED_CLASS_COUNT = 13;
private static final String POJO_PACKAGE = "com.trivago.cluecumber.engine.rendering.pages.pojos.pagecollections";
@BeforeAll
diff --git a/engine/src/test/java/com/trivago/cluecumber/engine/rendering/pages/visitors/VisitorDirectoryTest.java b/engine/src/test/java/com/trivago/cluecumber/engine/rendering/pages/visitors/VisitorDirectoryTest.java
index 624de2e7..da99d210 100644
--- a/engine/src/test/java/com/trivago/cluecumber/engine/rendering/pages/visitors/VisitorDirectoryTest.java
+++ b/engine/src/test/java/com/trivago/cluecumber/engine/rendering/pages/visitors/VisitorDirectoryTest.java
@@ -14,17 +14,19 @@ public void setUp() {
ScenarioVisitor scenarioVisitor = mock(ScenarioVisitor.class);
FeatureVisitor featureVisitor = mock(FeatureVisitor.class);
TagVisitor tagVisitor = mock(TagVisitor.class);
+ ExceptionVisitor exceptionVisitor = mock(ExceptionVisitor.class);
StepVisitor stepVisitor = mock(StepVisitor.class);
visitorDirectory = new VisitorDirectory(
scenarioVisitor,
featureVisitor,
tagVisitor,
+ exceptionVisitor,
stepVisitor
);
}
@Test
public void getVisitorDirectoryTest() {
- assertEquals(visitorDirectory.getVisitors().size(), 4);
+ assertEquals(visitorDirectory.getVisitors().size(), 5);
}
}
diff --git a/examples/core-example/pom.xml b/examples/core-example/pom.xml
index 210eb1df..00cf9b9d 100644
--- a/examples/core-example/pom.xml
+++ b/examples/core-example/pom.xml
@@ -6,7 +6,7 @@
blog.softwaretester
core-example
-
3.10.0
+
3.11.0
jar
diff --git a/examples/maven-example/README.md b/examples/maven-example/README.md
index 208d6c48..5abe7f19 100644
--- a/examples/maven-example/README.md
+++ b/examples/maven-example/README.md
@@ -4,8 +4,8 @@
- [Cluecumber Maven Example](#cluecumber-maven-example)
- - [Configuration options](#configuration-options)
- - [Run the project](#run-the-project)
+ - [Configuration options](#configuration-options)
+ - [Run the project](#run-the-project)
@@ -24,8 +24,10 @@ You can add different options as explained in the [Cluecumber Maven Readme](../.
To run the project you need to have at least Java 11 and Maven 3.3.9 installed on your system.
-Just run the Maven command ```mvn clean verify``` to see the report generation of Cluecumber in action.
+Just run the Maven command `mvn clean verify` to see the report generation of Cluecumber in action.
+This can also be run via `make test` from Cluecumber's root directory.
-The example Cucumber JSON files are located in the project's `json` directory. These are based on the https://github.com/aslakhellesoy/cucumber-json-formatter project.
+The example Cucumber JSON files are located in the project's `json` directory. These are based on
+the https://github.com/aslakhellesoy/cucumber-json-formatter project.
The report is generated inside the `target/cluecumber-report` directory.
diff --git a/examples/maven-example/custom/logo.png b/examples/maven-example/custom/logo.png
new file mode 100644
index 0000000000000000000000000000000000000000..30003fdadfd82eb0108519c0634bc85913ac6ca3
GIT binary patch
literal 200345
zcmbSzQ+yq7)b7rXokorAG)@}ZHX7TuZL_g$+fLfpc4Id7N%}wEx%@89)t-5O`{k^)
zo@ZeuOio4=9tH~r006*?iwP+J0HA>Y0LT^;@T0|kff*VAAOMI9@hiDzoOXJ&&Z7m(V5oM&c)-Zi%j0Kvi3HQ
z%Fg@NqqXCE9Q@m33uPz#`_&88+oTjsm>_{%ISN#mAXq=`L*U2nzuPL!a15INd!tGJ
z|8cDeaw+gN=ik76SReg0K}LdT`Tm=U1(iYlbHlRN6EkW3Sf7_$bZ?H`z
zNS?@fBue|&boj5uwv<9%Q$hIOQnx)72TcE)L15co{(rfyVO0>pLHk^Q?c3)tM@Y=M
zP=IM$1VqI#Cp<;&anp>{omMyiW$>=vm?Fps@*1J_yM!xI6au_&k|BT
zBo3TRtPRNp>zjs&c{tjpnrpX(X+Qs4IT7xnY*;tPmX
zDEqE@J!(R}uQk^Qo;Vu4PwSb?&YPrTbUy1e|LgTTl}H5kAe)bZ*q3_*pNrzYcB{`&DJn2muY2Ok^7QuQxr)3Gz-LUgfE}MqRE~JA{A5|B46Oq
zW{ef5(~oC&vE3>{uEp?V+H$=Gs9NdhiZo%xF^j2HDW6c+fB5%ABR>y*0mqQ9RcyuN
zg8u{n7}6Ah>*Q30sou6z)N60bD8JKWE%Cm^yu*m=wm;LJ$2jXSssAT7w(JUhH$nBp
zBNea1)l9G4$I6t{ZxtM?u0ruQk0SlC4;T}ZB%5q?S=mg&my5>s$LJ7($FrN%picow
z{coVproZJw0%uk74z$~wc*5_O4#ads-TYSJaOcv
zC|Z|?L{g`e|7~1VM#2m^K{DD1rB>ip
za@n9JX?*J9wcuyJ@?jGAuMi&i0HBu5O#Kn4`{gU5eLQznW8JxlN+gqVUgz5QkRTg_b$*lj1!*hTu>uUvi@ia
zHXCoaq5e&8AHuF#e_>nB!i`QsBc~ub*I3zVefajP3A;Yon-;X>KfR=!I7Aa6`!+E$
zC@Bi(6us3GZ*PxDwMl;`ri{Mg0*@?>y9=64zqo+;v|!1x<%7Jb#6?ge?^-R90Y;}H5>R1KN%+wq;|ofFIjJQ9K|57Rzh1vC
zQK&?ZojUp!cJBHIRTV0Q_x1^kBOjxp#^;S@Chf`W2Os|Wj>)nmL5vx2B~`xa;kr38
zWsT9~@g?HlxqsN^8yEvR{<tTjmoFFq
zfuB|dqDm@3?o<~0L*bsde4OtLC#p4*
z@SFr5EnT0hqsU+vj?{)imcaDEuP)BM@*ZxkCmH~_big`z^u^AcT?R+cF6WY2?TzWz_Tr!869(k?3{9L7XTvhwa8u2e
zF9O>g3S+Qyd_7>%%upbz$_V<4)_9r9>A=!;OP*Ecm0Q(K&-v4~{@Zz9%^-`a{%M%>
z5Zi*GVAm2L@?hJ2u86#&!j?LKUKnl8#ww@JH$2BT@K;N2QLd+PxhSiPEJIsWzp!(H
z{oU&p`^dfGKTtCf_>%t>D+0+y76
z4IlwS1Iz*Zpyvd7!KBKVO&|OQe$xyZMXjVmcQ8$*rzDhpXIIklILYO#Dz*09cWU;U
z&aGbQ*`C(rTMZ(KgUML|04}ysNw#`^qK1bD|4_o6GKR;Vs-QUG@R7m8!@IPjs^9qf
zY43<~LZ>6JQy=smpPXP1Z$^Ig7ws6;47Leo)V5}g7ClE@|
zSZbEp6pQqt<(H!%(yyuMp??#_c&>(7R)D&YR!3pG7;oIRC8ts;H$U5N*7A9lR$X@=
zUzp~+?6a^{+Wu~*sMA_>A-alHo{F^Ks$+rc0DP#3D`vD?5!GK|(Qg?`(tCS@Q$&0j
zqv$gGd^{5wL?U!xvcv5juQkbL3>?yoEZaro8ct+tk%Q^{-~g$TDBpruGWv(q(44Y%
z19jbJdCxls*TZvio||QIUMI`vZN)QaMD<@kgY*1`YAh-e&x|9%M0l!dAU<*L|GD!TrBELn&SNwuCJ@>7he!aDGR+o;NO)
z?O)}Ui@A5L5;y*8aU=UsiA0or`vk>VnJ@XWtknBBypjv;>dQaH<-A)~U0)kE4@?{2
zpEGGB!#CX<8eq&<3&^3rEOUKho6|CQhF*IoU+sR66XkV$Pso-d-J()NLKEV+Dwv)z
z95bN;qj9c7B`R3EfTcB1?zA_)S5h@*@H%og`o(5RLm7;p-bbQc3l31OK?B$t%gHsE
zV{=@U)i<#a;+7SDQ?!sbooJ=&{xh#*dqX-o1dFiy(=``&D#Ws=hb)csWNJDm*jI?2pY!-VUtDKDG`4S0#%ld&$OCB7C;^!K
zK$KKMw{Im(ZBbhYAp5-op&MPEQ<8WQdmLKy)DO_Cnt3#7;-d}mH)14G))8{SHiQ83
zt|t>BXgP(|>RO?C{LC)9h&4r@4CQ${+`!Ch4uE+lfxQ>&V#
zoT`2pRDR&_@!%y*N{hsOzUX{~x^imm;S{5CEOUB-Mba!l
zswCpPV20w@O=sDl6cO*iCmP?!+{Mjv`CNomfmLH2y?nkE3HX&Ee4rs47zPW5
ziY3A;%zy<+GDuWYEfXIEx5FY_GMlECm9Jg->*3sRKE@%$*_)ciaL+_-1Unj8#u(kB
zc7{TZLRVY3B*)E!KFzN$n58y@Fx1mzQO9f7!Mf$Oyy{J|d22bG7%&B}(orby?CV8Q
zZlmUyp3&O2Qmb@odNAjv+I`mgWK?~R9|k?*XZ>7FLRYS0d#pu6h@nQp!Vw9s-yh`M
z;Ua)C_$iQ&73K|<=Ph?%_ISx$X~72WNI|T@&1;!jVvuHiKcu5ovV>Ql9Eob(_VH^?ts&Q4cq$n{
zNTA4jy39(NKdG!Y8fk7>A-!#|QG@kmP^0_YNTYfK#_q*xN*Cw?Wfkyi3uHpRG4wu1
z%WiVG*}er-^_)vTw(N$$BYN?tn9rxFK=?4^$?&_O4zlRlo8%Omnb6{4!R%~k=sO22
z&a#93$Eix!Z(!uMlh4@?ue|PCF8EsBL*rD{N%3S!03x!IAZ;8l1c<3b1hPQrhVCc&
zejd`n0m1J@^DO6Un^hN7q@g1+(jp9LEYq&iE@@It3H&<7xPZS4acbIRb`k_p;u6IY
z;AnwGhG`>NK*{_5^svw-&4nmh0$-aZ;k{r%(e5+Yw-tx0K1^#cFzHiz34YM@(mEiL
zNdgu#?1JftW)L~$IE$>b3(Ald2Ex<{dwOJp4k-I@X5pt#Y3n98aA+i0RZgO_xayft
zY!AXwTWdP~^}3)5=r55bmf}Vs<7Ma*?&ES_8?$zOsYTD->fyO4gIvjHY@ILx*BCyn
zoCDBSp1OTwjtbaF7!JiyzGxsIIF(v%=;_Ksb~$SJLx9@dd^^e?%A><%`HLS`_STk-
z4Kvg~&ORwFfEw=FKe(r}I8-2TA)Eqd-1E<%K(x=M0N-%s<92#=+aH!@@81r#!w^~E
z0Gbvkj*K$>d4=@~NmD=-X27H#XcXKPw-XU!MjNx1SvS)^A2jxZiP;lj2F{-Qr?PXX
ziI5G8@R&CItuyORp;@Xpy%a(8tA(AtUxo@AUTFr9&
z3f0u0ko>C`{&&T$Fyb)oBSFs6s|~5B18dO51I~X82~GNgM&Qp*vz9v_>kqZUr0tUd
z7r_3sj}tSL`T9dJ$?3v(=o#BC1`?;sZclDp_t>o8j$D}i85jo-90P>9CWRXVtL4%t
zW+`07|CS@R4@<_Zx5W)f?I!-^DF@?=6K`#4Pb+z9-=L!Kh
z1?pieqpL%Ln*6+R&<=Zt6$fj!Z~eR
zuYO;u>p~y~I)WpVa2@X07db-4oQNe!G)+YjoUqD9FW2imF%_{G+5kSeQf{o`z+vI<
z%SN6#=)U=rUAs&~m>xf{FcrBkUHoTLc%n`u&fFc4J}(ycuQ!6jysDEO?&Nu<1VoM^
zfPF9t-w7}=@ndKxN`a$*HGd2wJlGRj{j9-da9w=u;VpW-8WG5|o{r*g9)*jqzXYeK
z7YE+&mUG(v3Z*VxtPQ_H?prLz5%6+F)!=8aqY?3H-RlwfGsl^@*y~lmSAs~fYy3j+
z4f~0g8lLO
z!sqfHf5lr3)mO>sa>ZER_%b>=5SWH)a(Syyui3BrQ03)bP4nb9y)urrLV?9IW9hb>
zY7^0EXh7mk&@y9rYan~spcGeO*4IHZ{0iG=sUQyTB17ZOtIPra%TG8XliA!D22cnf
zqX!39N^=J+4K|(nvXN+P-ej*t|C%2!Wr
zHbwBd+tlT!;_y8i@agciD0~<}PX`gQ!{Y$5CR4l;1S+evZc4;ol7EM|#`xh)XAwdG
zIlT$pPY;tF?@SjE`?j2D2S~!$MPK7BeI4%wN4Tox>s}!kZFSZ4lLWS>G*2zrNB6MF
zf)Ag9cwl&~2jhy@OvvEp)yf$bak8;<#oFx0QSVXi+f)Y*hh8HiHyneQzwoJjMg0~e
zp4LoXHcuu=xcZA_g{Rzm1KZkX_Fx;0z!s(iFnDF`=ETAjq{5djv0E1(g|j6Se0~yR
ztnc2K#6>Rr(#_R8rC^n=WRZ2NiIAulylDi2S$QM5V5O(_(DFQ!{QIQeU#4g39^qS=v
z&4BHVv@~;EWthJq^bt0$qsqS`s-D0oy2ir{Fm`uFVbNB%fnqK?~g-vw|
z=C8U6rB`MpkuTvGP=O`fy8g}!KtpQDby7dluH(bgBa{!zHx3&!gdDRjid!5xc_s%r>e|ZuigesbS;=XR
zQe3T2QR=kIIG)FD1=V0ZV@ktiaWAe7phYuA{ep6}5(Y+v
z4OOeLRo=mp25n*{y+^zy6b27A1$EiAhPui15f4Yw0=}B&idb7(kTH|aNNc?5Nxj;MCO6}>+}tVN^v0?^PU
zZ71NN`WmXFU3?&2h<%VfirIXSQqA51PR3@Z(uLDL_(M5>Yixdw+gngALhKN`R|@9Wqq&%>pUIbf_KL0TC|=C~s)Zi3)j%GaiO
zUfXT(JFQ1xYu%S(%Gq>=rPQ1*5_@Z^rQ;l0N2YG3Kjcy=?
zZ=$^N)9~v%j#3A4RZM!w1DzOW1-8XnjFb~yi$?e!h{cBL1!SGX
zpzW2*9K9qHl2WxgEn2*vNT%iRlB{dIC1R-hycsJF!x-C9
zGS}0UE4!sB>!}E9)2*KJ)QD^1siZk92RqMZlJ4qM#ESOR4gUtrCu(a@l=$P;uN08_
z9_YOH*|;t=d*NwA0EYdrE(4*z)4({3gRcKo_)|C$5)99iDWe#3E?#XvIePR7{I<0U
z1BXWrBGtnI(vXQWnZ+%R#r(sx>e?yWjPQ)0p~l#iLX*^RKi}!!4)J|1MJXrR&sJ>u
z__5HwK+7L5q0K_q8Qx~50TnFW8#VC|uq9xaBZli%$vH*spDD=l1Qehs#-yM)rWE9|
zQ01Wrf)_yegw4RIDsm(PP#p3k5sS448neo@BL9x
z9D<#ra052R1~MICSRw8(eI#x48Nttk^aJCRLS5j+tW2V4L6|pu)+=pX=i?T&B20EE
zd-@UhvDLuW0cj*6EbW7e_giFpauipR
z@M8{^C?Tp8tt?VPu<;0mz370
z72baq`7L!&!qTqv=C#%J?iyB>C<5InCf;JJx?IAN1d=GSx;{8$c``rg^LoPirlE^c
z4Cpgf>$B^crzJoVlMRtTcBGC&UL{|LsvQstUXBhGR97MB
z7e)oPQ_v~45E9&Y)iy@{-|d>*Sq!{jiU)g0_oXMd_*vJ{2aG~qtnSE;nTU{ZzA?I2
z0RY$i2(C@rEoAhL^QmKkJ!T&>gmRsj=;X!}&Up84Hj1SssNpTPinV_s6zV7*L`NA~hXbHe2GkJ85
zIFkkISZZiCT_&Z*ph)>|EULUffa+vbyY+5p*=iZ0jg=*c>(KUUQ&~BhHA;wurP9*M
z0Qxo+MGgNcl(}wmZ@e0iEsXr@5}~D^Q3Po(WQ@;_Qu|q@*WWo5L|&)v;;9~yFCK|c
zu8>raq8G_3lm%633ny?)amM2EZ7T3c4DN+xpp3BsT1(`!23Y1i+r?BdrF-vw+(sf?_*>t!W)=M`9_}SFjo)uLa!UDGL
zJzeXo6ZpMm@`=r?=MJ4fpMwZhV3$6%RP*NtWE(r;&FvMo{$-)kT6ii|MSTvtlOM6n
zkzR9KAMKZo65LORaDs=T@84~?*YVoVep#;NC1cBGw~&*pM7<)UpqtX2ffgbqyM+VU
z*Sr%TD7SdESSR?OS^&y^Zzu!Bm{KeezZAJB-=P`?wZQ=~0nsa8Q^j0!!bAv}adqS!
z03d3&!!E-h`qAkcJKB2v2Cdn%pA11OCY|*v^7bBz4~tOS=y$$~au0EvuXQyO&DE45
zn;meN_ipZ)$LX|dIGWe7ZW%39Tryr_EQ5AXa~$T9CL<*cLpaFSm1=;3Ksd<|$0=#_
zaYIWc8}tVlZ`9vO;C(7enhOY^e_c3jIm|Gn89LD27wiY@fb($>Wx66!kA=1S_(@EM
z9&ED#_Gm^h9uV;Grtbynj7!hqkEdnjUX)n+YEa+3^KJU^lZhjLsI32NA@VO^4e>Jy
z3Z?I%*tD+|fZng%7v7b*+wL#!MdwAcudc^LS<_!8C}9G64u`P@2|8Q_IXp3E4SV(k
z^Vlj~t(C_vp>SGIZx^0>_;O@U2y<251TeOb}PS6t4NeGCnC-tcVSGA%Tr4
zq937LD}NLj(xeTuzbPJB+pZ}`i9kWaM9D;=nsZ(gsI#0NS8bMNdW>Idzb7NU!#A*?
zn@y+zuJu#{UiD8;HSa8kQ5$)$^`r*rKB@li_|L$+_>p+^lfvTYku|YNgGVkW;Ie(m
z+BFFU$`%80clY9DV3VWi^+%~t2Rm;*F-DuBK&}M&REmyPUhGj`Me9AfR{LQS_@vBo
zG54|Y{+Rw1u#YdaFCDX#O1rbk++42Yi?3gjqPtB)l=1H)U{AC|($+$M^SXEcSG@JM
zv*r0rQ9Eq8+-drjRjM)(v-!G8H4yqRtayYSJ&0NBHz}x`z+|@V!rJP5Lndq|I|E_>
zn;#Z$SEN?+k1FC11e)p1FP31b5XOpj42U~-^MC(}7lI
zcj^X>7n-t&t~ZU3O+rN#rI{DW#!5S9g)@gXI$Tma3rW=xk*-N`Bl(Y;z^P>Q_)jTg
zNUx?TgYv1DVReF(dkJ-uHd_QeJ_c@(xPL_-b29B9qnN=AZnRc?}B0&Vj`^wKxOT}jSTdU9VP)zWT
zGSD~o3-CslNMZ(|lE}&?_xf`cGl8gISy_<{sl3_~66yF1H+#;$wAXS&f&^Ll=3FyU
zz}D@Lud+8f-&f9Gv{U&UZ#c4GXqSG1PcpP{WET0Ir;)KeGgDhUHRZB(W+CdDSVY~F
zz$PyU99tmdRqy+50`DBoDv05}`CK3ynwgoCqCDxCGjv=mPUnSp3aV{3KTiVBvRG
zJ<08(WP5yO2Z0%poo!4{Y7;$MYO^$PALjn=CrZFdOX|Ync#P+xRrPDxBP&c*`0YAG
zs1_o~KH4DxmNXB_wb0p|Y3yMv@DfjE$KUX=M&PyWTdJ1i0kQ_8Y=aKeI~McM3FRC`
zn6xkMselVYMEN`6
zvbp7IN;{=zmg8|4%{ku!sd@hSg<&5cLkKl}=BX~cw?gPa?4r@$
z6^XVDZiQnzYyLcm@4fmQ^QuQ$k({Ii5cWL8Dur=!lpl+%KffpbQ~$V-KXRmG8VOOH
z<2mDD_tz;OTw@Z$el9_OC6qEJh5c4iwr+!akM$>`#d*tl#6`>g@AEa!qc3aIi@yQ7
zE@sg%eBZa=h%SE`M3kP7+)#?eq|
zt+$VU5y0{UDZCJ0X%;~ZnYopN%1bGb>-;d;E2E`
zrz=@41Bbc20nf9l}~R%j;pf>}`Y`BxTXRt)(qTQn{E^
zEDrmT9|pwiqTKK1cfaQPygr=w1DsUCT+O9Ln-Zy(svPCw&E(<>kP-6lO69Kl#>fZ=
z>delj?}5;hsGRjlsEBEl?8NgIeb^Ptjjando!2&<03QZ2qRJZI>~dJ+%Pm?0YMJC!
zoxa0Y*G2by=G3JhxI^!NqWfFCZ+_YjyTeNk^cEW|*?0w_d
z1Q5Qg0)gC-h+EA*=aWA1y5P6A*zMQO2}#uiL|FnsB6irpW0G>?cie1xg7MPr#^XtoqWOUbY;bPam2p1xJjnvMJ
zAH)TqM#0Z9QyrvFqX7+4CjEAS*f0tsv+0_HzxD4v&JyXF^ZC4G)kYMYep`Yvp)J09
zVp9(hT0e*e;1Y@F=1uX!dz1VA1&7f?tElUugL6^x{C>syQKV&LiKI}$ZKS%3hJzRz
zOQy{)y3?4Q~Nv0>!2;Gu`T^Nun^$;j4l<*W@t^v1r{diwKwDR`{+Ad!3^|(7&
z^paA`Y5vi0fN4TfR-8el1z%|g7Ly${FiywR;Qxt`1~#2|_EJ2H*UCj1@5AH4EjfGXa{0SPW(=P|5A
z%PZ9(MjcR-Dr#(Zb_lKJtpI&xx2t@fr|3Ly;t-!`h-(OwXkOPAgVhO$5JoNGVFc?~
zJ*Dsxwa^cZ6Owbk@nQVI1zzjHWVaME<+nEdz3tP0JwR&0u5}I(#4{J5qC2twwUXzIq@6X?OEeXIZf$nJ*!po
zNg5JO#AiWhrpRb`K&cwk-a^)OUOHo5)2%epETDfCC1^=#QErd^nhVs=OS`Sob(u&k
zpwd>VBiEZV2Lni}GvEFq7=x3`3+}m4i5jn9hem3)=Gkq}dVg)+`dyO`=n#NrlOPSK
zmvoG{PG@N=7hkUDG*sw&vHPa-S!$u#^kL-@mYF!R$w4j}Hh+zp*3H^-R<81CY}0n#
zCttim8&DVRP$SyqK`cb&mmvXz;ADRe8B4y;K-RrHo$A~_;ziP8O7UH&`%^_T1Cl1b
z{#Il-x2X*6diYWOvQO-DMz!Xzl>>s4Ll2I&13+}*n-b#@FIpqUgPyHQy0f})isFWw
z%g&Ae;kL9<_{&nMAl6Zb$@rDQ9~0+gn(8TkElhM93E+w2^FV$7@@i0=1&~kGM?X)7
z>R{(DC$yy#^Lw74j;`l)8jNWbyWY8v(SG6+UzP|6lYl8fo#M>T|I$Rw>0IYLzsU29
z-F181tPkQYW_1a}WPSKROxO*{?)K!LH13WbcJ(jcI{Fdmbt6(ud`#1R8WqDO@Nf$m
z^>)6T>(gO!LCRQjJ=G%jetXS+#GRs=h}5pk!`RAT&joGEl{iG(7h<=&3BO3-;-`e`
zl)&T&aEB2#+nFzS!3%Gdm}RDC;H@s(KR#Z$czMBhi|!yv{4QnDmA~Y82~@Jptu|RC
zX2$IDLcWu#tz;s;H{VhgFfmGL;WSd+rcL*gLgdQv9(Pf9;cMP-??$RkH|FROwfgm4
z+7HV)9dyg!;j)_hhK}cLBxG*u#q$SEjoDs>zT|-}O>VS=LE0`_Y-|v9gSpZ$Xn^zF
zEWtU$p(9@n>{+vuBonjweEdHDV|=>y+qmeaXM>yf(qkaA>LV6QE@PM7*pqJLxj@_V
z)%U$C_Z-*U&sbWJZBW?sHS(!OzW(22E4(tWSYSIf4j0KJ9G{qatDhpZMk}bqC>O^$m^>(4Zpsy>t1((~LF{j{L({qNPbA|5s1v%Vd~oJu+G)Qg(FqX~
zT&IUR_YN(zJ$^TD_#WtS!oaH_g`mfx(=O%ZQYnVDPVjF$FH|I^FtTlr_-1A47EZSc
zfJ@8pw(zGY>1jo^UBtm)
z_jUbG9b|_$l<)Z*M<~_CQG5b**1c|7Z$}SL6(G-WEzekg{zZX=TKhhPD7XHB>_n8<
zn&XTCnMhICNEh~tE-2!*0k7TU{qg8emi;EZMt0r+Ut@C^Cw_l$uj$F=S!r7QMG|O6
z)O<5fNhvEtWO_xLW84f(5C;y8Z!Un5HODX${I=a&I@jN@m&h4Xqmu_}?o=fRa>`-(
z=50r;gl>QCEl2e7Wi(u-##);>Hk{ETZ_HF8J@pbP9E`q#_HIoeuu2g
zxF8jjJ;(!Y=S%^jn8RL14H|nZu6AK(M7XOIa!TMhv@8@GIXT==bpqpC8hP|xT88!I
z`(YQEN=q4z&A6gtl<@4_GVbWwO~NUsMkpkzoGvuQmLCmL%*!guh5Mw}d-HjXJ@#+&
z-b!?pQu#SQ8ceb12S*BkXnH@?gWmJ^pAkP?GarEmESFHzMZiVCjB_l*WGimbQc*el83Rj?kX69M`
zM^+WS{&+Ka;AQMQzMHS9F>iE%R&z}2NvTRA@`$;xWF!hb%3=JDc(GmCWE5VTDUW
zr1LQv5x5(u_9VuoD`pJn*B1MzpI}4g(1Mxu3YSt1bK#Xo7hb?IO%~{BIm2NaNJN7a
zHB?g&XyS}C-v0LY>UM8u22SzZg~o4NWvPHJBXH8AEq5*KiL8B>q;G^iMWSKM@1{#g
zWDUhoa74_v1R8pr%_`h}MclQ@xNp%K-4{mltU*%B`+k@WeQeq>rzoVA7uVbO^{w`v
zs7Oq*x0{aT@qB20pYLfTlYM|Y@zYnm$O)HP)xE4kF+Zas`6*j(=r4!H*O0D@blx|(
zZ56Ajyld7?;lHR#dK3)=Ji=^tkur;Qxwt521F^JvFv4S0CnBtk9Q}LLli=P-F7%ym>j8eg;
z9HEUWz`$M1%JEetvsnz9HhpXL
zof+8Q&CN#xoq}o+P#Z^7EH>G&$NP@l*Y1EWC$^=gyxI`fihop^@#AnL?PY7Q^QXHt
z9HJ8F3JyI-EW1z8dGC7=-wzahG$mOy78sctlAh>U+6w~jQbSUt**9gMDN<*Uz%tDP
z870!TR^6?@a+qwqwNLswSXlg08(8N=H|&R3Z3bX#0G_Cz-|^uiA<&@WQDbE`N6V-X
zHOwV8wY9q5tjC_&w{U`7ip||OxrC0=Mjx>$=FmiCgug0Am`X^Ll@pydFVIl>T07_gPb8~@|G+Ym{
zYAdjWXrY;V6gC2Zw?{sdyvS?F)$ru;6+M6JE3bK#^@mP2V_46QoC=;c9JfH9GlH)ma
z8g2DDS5i>Jek$^jH3WWjE&sM8#Zwf-*cIpg?H9Sv{_ZfZWtCq}71d^59}WpLIm2aE
zmo!qAQZ0|n=4SKsixw3?uebXv6db(xg{cF>Rn&FFT_B&f+xlYn(MU`$r>h$1SdR6f
zL2w!qwoZ0c+Ga4D^jY{&G-e3|zW4KY*AEhiN~<4^!Oc13E?IzRRRu?1=a9M+>);2o
z0$zq0t$hEM59za$5VKjCmvSa~#g{N{Xmi(tS#%797K#vnRcec=nFZ!qJ?XLSTe7en0DMn&4J67ES4+Z`+R`kFj-!y!>sJlVL
zBcYk!;Sv?}u@l%_w;38MrG%8ehUN|4Q?JDP!D!IacyfLt>25gi$4LD=0Xc1p;&3&7{Y4
zfj_KSx~wz|PMUPQ&lX>AEqs6owyqt^tzFAPMmq}U%P*j0&t-)6G!wlpV>xfst4+KH
zVKW~ERDFfQABrRk!#j*Glo8;d?1&dy%ENN^p3iUGf{*`Ta^Lw{KTZtB>O?C!QNgGp
z0IAg5r@-jJ#KdW5uUqdwKwXH52Tm}aXbW+m(PY|?d8VSG=+^MBhVbO~!DeUzpf`#c
zJP{Jg?gtw44@c^tWhI~^CZA|K{P7oT>RD}ZD;z16nrCWUF3KJ4x_ez5waDnf8IZA#
zwRBCF-t#VJ4@bY}%VybDGY}=dsA1blPM*I_!^zo#TKwv&^U*s|N$kE7U+t*_W5U@i
zfWGuHrK*_>XT@?9dZ_}??1KO-b^l7@1Ny5d3zwB$;A36C&UGj2`vt*NA689pxk75Y
z{z1~QwZ^`cbCBA!v00+7PnzM@2W$&$&wQj!ne=foWvd;C*pp8XLiHykGpJB{*5{w!
zde?ayF54Y^QqYXY$8gGrdMTwy?iMA#!r}7N%Xm>9uSQJY+(rKwqcq-;?&x!K^+hw`
zToPHQTJyPHyYLu&xph!kf-wI!zqlh%hWj*T^y~eciutB_$m{kg)#-1r?(yH`>_W~L
zzBHRMQjg~I9lJpY;UlRo<-(J6J++86%#4OTHOuF{MwhZ1dUdWh$(Z+-?6r41D)xE_
zi|d?}&=&eBJmfaJNE=4TuO~c>b)NA2omc`r8$YO(^xFTlu70cdGUCE>@T^mN3&DJu
zH33GbjX#m&G5V~giusau>K}2S^6y22&)lb_81gqo!`)E*=3hwnqj}esm)lS8&&x5d
zC6LrANiGU*59%FMxJZyfA--m;M=rdEJa5NEQid&``qH9asR69{RsTmMYOrstzoc2q
z<-mpK-ovI3m(a;*E(ECFCWJ*vm)UjhXkEq0L~T!{vWq}%`6~>W-HMQ%L)ZNkG>h=P
ziOs{SzB)_Wp)$8?Qpo+gQO_Y!{%x>n8|$crrJvvfGtb+s&l551vU3KVljy$E7l0Ed
zF;~uGf%Gz1#-VY8>>s@g^>TtDf*?65&&Wl^pCM^YT3Ble(cL?3i`{>ox}gE#|EHOGfjU4*nA!QR!c=!l1b9q46_Cw_g1
zA-8LA2l;;4g}=;zs4HmPwzp<(5S1gu50z+k`l1#&r0SHV$xON_o*KaS#iERq;LLIu
zU4h+z+Vr^lt&rD^ybH${H$)pA&;%z#IW&Q#FmXE5SojVJ2nfhaZ%4~_
z%
z)m}-%drP`L*A}w=ha(fd9~s}!jjI#YN_qnh;l77qSR4>=4NuEAe4qVue4VYi3U(>-
z`lj#0Wu-Z8j#=XN_IWk&{E5GN=~q2dszr`6@9QcGwU?sVX8#zUICpQgCHwql>N-h%
z;KG4~?)EePso5a6LJPUaAA%V^9?RM2TzHFa+3SNW^P;0!&ftEVM#W{;6JNf+4V`=5NF
z-?XcXblZ*8zPY?AP}q2HAa+|`JDKXi&j*6-i@UU)c4+y;G@dm`xZiUUQXWOz6@7}n
z9{3000@=M;vpbV8o9;AfKYYQV_bhPVzes4e836L8a^R9PA!zO
zUEfXyZwm&E0-Ez{fkm@!*)*dS(=kjK{C?f#t#h(Jq82`oHaFZk8V11sHB(s{7~|&a
zngkH80vb{w-rqyiUymxORV-gOVE!q{fas)So2^LgOv$b|Iv?u6pEqPRwi<=VGext8
zWQ5!YtZcHs{qDXk)u}@X7OXgto)$S8@CbJ07B+Z?+w=SDw}w4%Vh~4wq@f3g+|q5{9zrxQQSV1;82^3DG-&M*=D+gi!f_)Sk;z35>Mjz<
zi&w5bHn*UmY(2bunERcW&8x6?vqdpm#r+R4UmSuFn|?gUqU58bJTf*3x1(o~|C&jj
zM1*REZ8e^sN|RBIvjqkX;Iq)$DV$sa8aVuVfaUu?K^T^gmN*QKB$iOA)d3W;RB4h!Bep_V@`5U=FDjPb(|!sbKiF2W1H|x5os`*mer)*wTOA%WHThDzbJiV
zYQm*I-0(Kv3vmL^`f#Io+-Q}~5r(O-bVa`!0aE
z4jG}g&HhqZSg(#zUArc;q~FWPLFaYTa)f>;0bFxh_0tL_k2lV}JezL*e{i@}hn{}`
zArNR&AYzJEP0%VF
z;q#w&=ll1|Qt~&Pt)XoTDHoxP8kVwr7$GS|T7^_?N@r;Zq+%%P^pGoej;re;E3CM(
zB$Q3>+10N7vPJOR4!LwXRKhr`MK|V>N#-9E^<;>Ywkt(lUN9YJx|u
zq*O2hdWnY2-!MRgra&yY?b_pn3(w2S?2Wf?K^k@2=#1BmgEDzn$`$M4?HDdgv3;AT
zPf!CRlu5vuc65Q3CWbomw8H9_Qx-bc{&Ga0YeFv2_8y3uP_hJyJm84a0UKUgS%T+O
z${I5nXN(rKAphMcOBYeF7ip+JQ<=eLV~$0Aud3kPLm~TG$Sb8gf0_<&sC*yPqLvW^
zz-4>$J>vc4-i6DkYq#u&u+_Nv{{eYGhQF&Ibgbf&7KS&akDrkLK3z>h_OZ~>R8r#7
zIKDo`>%AHU%jVdo+j`SYKlakC*F@vC0bQC{Vb!NZpK)x`sB0zZmGE#C3j0z19TYAh
zbpKrnBf%E`7v7SCLB(kgzyO0czSs@tC{{JM;bBz4}>{Ev`E8vQu;Jpk>Mr8U($fvd+6)XS1
z$PS73kMIVZ1Ww^g@n5|4OMdFeHMfB9wlt8&RvRzAg(r>Csm$DNc4w6MTOj?T6F!+J
zq7ZRVX)xQ?O64%F^4s>$?*EC;+5Hfp1}cal*!I(=$Xg>maRZlgO%sW(|Ye=#CN^;$6tb10azZ#Yy*v;?t-4Vm$@=1pH(}1+ou3*
z6r