JDWP-based on-device debugging for ParparVM iOS and Android, plus standard JUnit 5 @Test methods against the JavaSE simulator with annotations for the visual configuration.'
+---
+
+
+
+Two things this post. Both are about how you iterate on a Codename One app rather than what the app itself does, and both are the kind of change that you only notice the impact of after a week of working with them in place. The first is the one I have personally been wanting for the longest: on-device debugging that actually treats Java as Java. The second is JUnit 5 as a first-class test framework against the simulator.
+
+## On-device debugging that treats Java as Java
+
+Codename One has always supported on-device debugging in the strict technical sense. You could attach Xcode to a `.ipa`, you could attach Android Studio to a running APK, you could read the native call stack, you could step through Objective-C or the C ParparVM emits. What you could not do is set a breakpoint in `MyForm.java`, hit it on a real iPhone, and inspect a Java field on a Java object as a Java object. The bridge between "this is the Java code I wrote" and "this is what is actually running on the silicon" got chopped in two by the translation step, and the only way back across the gap was to read C and translate it in your head.
+
+[PR #4999](https://github.com/codenameone/CodenameOne/pull/4999) (iOS) and [PR #5012](https://github.com/codenameone/CodenameOne/pull/5012) (Android) close the gap. As of this week you can attach `jdb`, IntelliJ IDEA, VS Code, Eclipse, or NetBeans (anything that speaks JDWP) to a Codename One app running on:
+
+- a real iPhone connected over USB,
+- a real iPhone over Wi-Fi after pairing,
+- the iOS Simulator,
+- a real Android phone over USB,
+- a real Android phone over wireless `adb`,
+- the Android emulator.
+
+You then set a breakpoint in your Java source, hit it, see the locals as Java values, walk the stack as Java frames, inspect instance fields as Java fields, and invoke methods on live Java objects. The same workflow you have on the simulator, on the device, with nothing in the middle pretending to be something else.
+
+If you would rather just *try* it, the developer guide has the step-by-step under [On-Device-Debugging.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/On-Device-Debugging.asciidoc) for iOS and [On-Device-Debugging-Android.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/On-Device-Debugging-Android.asciidoc) for Android. The rest of this section is how it is wired.
+
+### iOS, in three pieces
+
+The iOS half is structural because ParparVM translates Java bytecode to C and the operating system has no idea any of it ever was Java. The PR adds three independent pieces that together carry Java semantics across the gap:
+
+1. **Translator instrumentation.** When you set `cn1.onDeviceDebug=true` the ParparVM translator emits side-tables next to every method (locals address arrays, variable names, line tables, per-class field offset tables, per-method invoke thunks) plus a `cn1-symbols.txt` sidecar that names every class, method, line, local, and field. Release builds are unaffected; the whole thing is gated by a `CN1_ON_DEVICE_DEBUG` preprocessor define so when the hint is off there is no extra code in the binary.
+2. **Device runtime.** A new `cn1_debugger.{h,m}` is compiled into debug builds. It dials out to a desktop proxy over TCP and services a wire protocol from a listener thread. The fast path through the `__CN1_DEBUG_INFO` hook when nothing is attached is a single load and predicted-not-taken branch (`__builtin_expect(cn1DebuggerActive, 0)`), so the cost of having the instrumentation present is in the noise. When something *is* attached, suspend / resume yields the GC bit so paused threads do not block collection; `dup2`-based capture forwards `stdout` and `stderr` into the IDE console; method invocation is queued on the suspended Java thread so it runs in a valid `tsd` context, and the underlying call is wrapped in `setjmp` so an uncaught throw round-trips back as a typed exception instead of `longjmp`-ing past `suspendCurrent`.
+3. **Desktop proxy.** `maven/cn1-debug-proxy/` is a minimum-viable JDWP server that translates between our custom wire protocol and standard JDWP. It is the piece that lets *any* JDWP-speaking IDE attach: from the IDE's point of view it is just talking to a JVM. Coverage includes the parts you actually use day to day: `VirtualMachine.*`, `ReferenceType.*`, `ClassType.InvokeMethod`, `Method.LineTable` / `VariableTable`, `ObjectReference.GetValues` / `InvokeMethod`, `ArrayReference.Length` / `GetValues`, `StringReference.Value`, `ThreadReference.*`, `StackFrame.*`, the full `EventRequest` parser with all twelve JDWP modifier kinds, and the `Event.Composite` events that come back.
+
+The generated archetype includes two IntelliJ run configurations in an *On-Device Debug* folder: *CN1 iOS On-Device Debug* (Maven), which builds the debug `.ipa` with the right hints, installs it, and starts the proxy; and *CN1 Attach iOS* (Remote JVM Debug, `localhost:5005`), which is the second click that hooks IntelliJ to the proxy. Two clicks. Same flow for VS Code and Eclipse using their respective remote-JVM-debug profiles pointed at `localhost:5005`.
+
+### Android, in much less code
+
+Dalvik and ART already speak JDWP, which is the reason the Android PR is much smaller. No proxy and no instrumentation; just orchestration:
+
+- A new build hint `android.onDeviceDebug=true` flips the manifest to `debuggable="true"` and disables R8 / Proguard for the debug build. Release builds are unaffected.
+- A new `cn1:android-on-device-debugging` Mojo locates `adb`, optionally `adb connect`s a wireless device, installs the APK, sets the debug-app for wait-for-attach, launches the Activity, forwards JDWP onto `localhost:5005`, and streams `logcat --pid=
Date: Fri, 29 May 2026 14:29:41 +0300
Subject: [PATCH 3/6] Developer-workflow post: full rewrite per review
- New opening that does not start with the "Two things this post"
fragment.
- Supported targets clarified: iOS = simulator or real iPhone over
Wi-Fi from a Mac (the "USB pairing" language is gone). Android =
USB, wireless adb, or the emulator (all three).
- New paragraph spelling out that iOS still needs a Mac in the
pipeline because the bits come from Xcode (locally or via the
build server).
- Dev-guide references go to the HTML version on the website
(/developer-guide/#_on_device_debugging_ios etc.), not to the
asciidoc source.
- Step-by-step IntelliJ tutorial for iOS: enable the four build
hints (using the in-settings names, no codename1.arg. prefix),
recommend leaving the block-on-load option on so the
on-device-debug variant is visible, run the proxy, attach the
debugger, launch the app.
- Same shape Android tutorial.
- Device-console behaviour and its caveat called out explicitly.
- Capability note up front: Android can step through native C/C++
via Android Studio's LLDB alongside the JDWP attach; iOS cannot.
- "The thing that surprised us" section removed.
- "Why the two changes pair" section removed.
- JUnit section rewritten: explicit that it is standard JUnit 5
(not a fork), com.codename1.testing.junit holds annotations +
CodenameOneExtension, AbstractTest stays for on-device tests.
- Tutorial: file location, minimal example, plain-validator
variant, visual-config variant, @SimulatorProperty variant.
- Testcontainers / WireMock no longer in the example list.
- Hero image lands at /blog/developer-workflow-debug-and-junit.jpg.
- IntelliJ debugger screenshot lands at
/blog/developer-workflow-debug-and-junit/intellij-debugger-on-device.png.
- "Back to the weekly index" link to the intro post in the wrap-up.
---
.../developer-workflow-debug-and-junit.md | 266 ++++++++++++++----
.../developer-workflow-debug-and-junit.jpg | Bin 0 -> 54882 bytes
.../intellij-debugger-on-device.png | Bin 0 -> 806452 bytes
3 files changed, 217 insertions(+), 49 deletions(-)
create mode 100644 docs/website/static/blog/developer-workflow-debug-and-junit.jpg
create mode 100644 docs/website/static/blog/developer-workflow-debug-and-junit/intellij-debugger-on-device.png
diff --git a/docs/website/content/blog/developer-workflow-debug-and-junit.md b/docs/website/content/blog/developer-workflow-debug-and-junit.md
index 93ba0ab856..e2a03b4556 100644
--- a/docs/website/content/blog/developer-workflow-debug-and-junit.md
+++ b/docs/website/content/blog/developer-workflow-debug-and-junit.md
@@ -1,107 +1,275 @@
---
-title: Developer Workflow: On-Device Debugging And JUnit 5
+title: On-Device Debugging And JUnit 5
slug: developer-workflow-debug-and-junit
url: /blog/developer-workflow-debug-and-junit/
date: '2026-05-30'
author: Shai Almog
-description: JDWP-based on-device debugging for ParparVM iOS apps and Android apps, so jdb / IntelliJ / VS Code / Eclipse / NetBeans attach straight to the device or simulator. Plus standard JUnit 5 @Test methods against the JavaSE simulator, with annotations for the visual configuration (@Theme, @DarkMode, @LargerText, @Orientation, @RTL).
-feed_html: '
JDWP-based on-device debugging for ParparVM iOS and Android, plus standard JUnit 5 @Test methods against the JavaSE simulator with annotations for the visual configuration.'
+description: A walk-through of the new JDWP-based on-device debugging pipeline for ParparVM iOS apps and Android apps, with a step-by-step IntelliJ tutorial for each. Plus a short tutorial on the new standard JUnit 5 integration against the JavaSE simulator, with annotations for the visual configuration.
+feed_html: '
A walk-through of the new JDWP-based on-device debugging pipeline for ParparVM iOS apps and Android apps, with a step-by-step IntelliJ tutorial for each, and a short tutorial on the new standard JUnit 5 integration against the JavaSE simulator.'
---
-
+
-Two things this post. Both are about how you iterate on a Codename One app rather than what the app itself does, and both are the kind of change you only notice the impact of after a week of working with them in place. The first is one we have wanted for a long time: on-device debugging that actually treats Java as Java. The second is JUnit 5 as a first-class test framework against the simulator.
+This is the first follow-up to [Friday's release post](/blog/metal-default-new-build-cloud-and-a-new-format/) and it covers the two changes from this release that affect how you iterate on a Codename One app rather than what the app itself does. On-device debugging that treats Java as Java on a real iPhone or a real Android device, and standard JUnit 5 against the JavaSE simulator. The first is the one we have been wanting for a long time, and is the one that takes the most explaining, so most of the post is about it.
## On-device debugging that treats Java as Java
-Codename One has always supported on-device debugging in the strict technical sense. You could attach Xcode to a `.ipa`, you could attach Android Studio to a running APK, you could read the native call stack, you could step through Objective-C or the C ParparVM emits. What you could not do is set a breakpoint in `MyForm.java`, hit it on a real iPhone, and inspect a Java field on a Java object as a Java object. The bridge between "this is the Java code you wrote" and "this is what is actually running on the silicon" got chopped in two by the translation step, and the only way back across the gap was to read C and translate it in your head.
+Codename One has always supported on-device debugging in the strict technical sense. You could attach Xcode to a `.ipa`, you could attach Android Studio to a running APK, you could read the native call stack, you could step through Objective-C or the C that ParparVM emits. What you could not do was set a breakpoint in `MyForm.java`, hit it on a real iPhone, and inspect a Java field on a Java object as a Java object. You also could not debug an iOS app without a Mac in the loop somewhere, because the only debugger that understood the binary was Xcode. The translation step between the Java you wrote and the C that ParparVM produces left no way back across the gap on the device.
-[PR #4999](https://github.com/codenameone/CodenameOne/pull/4999) (iOS) and [PR #5012](https://github.com/codenameone/CodenameOne/pull/5012) (Android) close the gap. As of this week you can attach `jdb`, IntelliJ IDEA, VS Code, Eclipse, or NetBeans (anything that speaks JDWP) to a Codename One app running on:
+[PR #4999](https://github.com/codenameone/CodenameOne/pull/4999) (iOS) and [PR #5012](https://github.com/codenameone/CodenameOne/pull/5012) (Android) close that gap. As of this week any JDWP-speaking debugger (IntelliJ IDEA, `jdb`, VS Code's Java Debugger, Eclipse, NetBeans) can attach to a Codename One app and treat the running process as a JVM.
-- a real iPhone connected over USB,
-- a real iPhone over Wi-Fi after pairing,
-- the iOS Simulator,
+Supported targets:
+
+**iOS**
+
+- the iOS Simulator under Xcode (any host),
+- a real iPhone reached over Wi-Fi from a Mac on the same network.
+
+iOS still needs a Mac somewhere in the pipeline because the actual `.ipa` is built by Xcode (locally or via the build server). The Mac is where the bits come from. Once they are on the device, the IDE attaches over Wi-Fi from any machine that can reach the device's IP.
+
+**Android**
+
+- the Android emulator,
- a real Android phone over USB,
-- a real Android phone over wireless `adb`,
-- the Android emulator.
+- a real Android phone over wireless `adb`.
+
+Android does not need a Mac because Dalvik / ART already speak JDWP natively. The `adb` tool does the rest.
+
+### What it looks like
+
+A breakpoint inside an iOS app, hit on the iOS Simulator next to IntelliJ IDEA:
+
+
+
+The same Debug tool window you use for any other Java project. Frames panel on the left has the full Java call stack. The Variables panel shows `this` and the locals as Java values, with the same drill-down you would get on a regular JVM. The simulator on the right is the real iOS app, paused at the breakpoint, waiting for the next step.
+
+### How the pieces fit together
+
+On iOS the dataflow is:
+
+```
+ IntelliJ <--JDWP--> CN1 Debug Proxy <--CN1 wire protocol--> iOS app
+ (any host) (your laptop) (Wi-Fi or
+ iOS Simulator)
+```
+
+The CN1 Debug Proxy is a small Java process you run on your laptop. It binds two TCP ports: one for the iOS app to dial into, one that speaks standard JDWP for the IDE. The IDE thinks it is attached to a normal remote JVM. The iOS app thinks it is talking to a debug proxy. The proxy translates between the two and walks the ParparVM struct layout so Java fields, Java method calls, and Java values round-trip cleanly in both directions.
+
+On Android the proxy is unnecessary. Dalvik / ART implement JDWP themselves, so IntelliJ attaches directly to the device through `adb`'s JDWP forwarder:
+
+```
+ IntelliJ <--JDWP via adb forward--> Android device / emulator
+```
+
+The Maven plugin's new `cn1:android-on-device-debugging` goal does the `adb` orchestration and the port forwarding for you.
+
+There is one capability difference worth knowing up front: on Android the same `adb`-attached session can drop into native C / C++ via Android Studio's LLDB alongside the JDWP attach, so if you have native code in a cn1lib you can step through that too. On iOS the JDWP attach is Java-only; if you also want to step through native Objective-C, you need Xcode in parallel.
+
+### Tutorial: IntelliJ + iOS
+
+The Codename One archetype now generates two run configurations under an *On-Device Debug* folder in the IntelliJ run-config dropdown: **CN1 Debug Proxy** and **CN1 Attach iOS**. The tutorial below assumes a project generated from the [Initializr](/initializr/) recently enough to have those. If you have an older project, the [iOS on-device debugging chapter](https://www.codenameone.com/developer-guide/#_on_device_debugging_ios) of the developer guide has the run-configuration XML to drop into `.idea/runConfigurations/`.
+
+**1. Enable the build hints.**
+
+Open `common/codenameone_settings.properties` and uncomment the four lines the archetype generated:
+
+```
+ios.onDeviceDebug=true
+ios.onDeviceDebug.proxyHost=127.0.0.1
+ios.onDeviceDebug.proxyPort=55333
+ios.onDeviceDebug.waitForAttach=true
+```
+
+`ios.onDeviceDebug=true` flips the iOS build into the instrumented variant. The other three configure the proxy connection.
+
+The fourth hint, `ios.onDeviceDebug.waitForAttach=true`, is the **block-on-load** option, and we recommend leaving it on. With it enabled, the iOS app shows a "Waiting for debugger" overlay at launch and does not progress past `Display.init` until the proxy issues its first resume. The recommendation is mostly about making the on-device-debug variant visible. If somebody on the team launches the app on a device and it sits on "Waiting for debugger" they immediately know what kind of build they have, instead of being confused by an app that does nothing.
+
+For a physical iPhone the `proxyHost` value should be the laptop's LAN IP (run `ifconfig | grep "inet "` to find it) rather than `127.0.0.1`. The iOS Simulator can always use `127.0.0.1`.
+
+**2. Build the iOS app.**
+
+Either path works:
+
+- Local Xcode build (`mvn cn1:buildIosXcodeProject`) and then run from Xcode. This is the fastest iteration loop.
+- Cloud build for a real device (`mvn cn1:buildIosOnDeviceDebug`) and install the resulting `.ipa`.
+
+Both produce an iOS binary instrumented for on-device debugging because the build hint is set.
+
+**3. Start the proxy.**
+
+In IntelliJ, pick **CN1 Debug Proxy** from the run-config dropdown and click the green ▶ Run button (not the bug icon; Debug on this config would attach IntelliJ to the proxy itself, which is not what you want). The Run tool window shows:
+
+```
+On-device-debug proxy starting:
+ symbols : .../cn1-symbols.txt
+ device : listening on tcp://0.0.0.0:55333
+ jdwp : listening on tcp://0.0.0.0:8000
+[device] listening on port 55333 for ParparVM app to dial in
+[jdwp] listening on port 8000 for debugger (jdb) to attach
+```
+
+When the `[jdwp]` line appears, the proxy is ready.
+
+**4. Attach the debugger.**
+
+Switch the run-config dropdown to **CN1 Attach iOS** and click the 🐞 Debug button. IntelliJ connects to `localhost:8000` and opens its standard Debug tool window. You can now set breakpoints anywhere in your Java code or in the framework.
+
+**5. Launch the app.**
+
+Launch the iOS app under the iOS Simulator (from Xcode) or on the tethered device. With `waitForAttach=true` it pauses at the "Waiting for debugger" overlay until the proxy issues its first resume. Hit Resume on the IntelliJ Debug toolbar; the app proceeds, your breakpoints fire as the app exercises them.
+
+**The proxy's Run window is also your device console.** Anything the app writes to `System.out`, `Log.p`, `printf`, or `NSLog` from native code is forwarded to the proxy and printed in the **CN1 Debug Proxy** Run window with a `[device]` prefix. This is genuinely useful and is one fewer thing you need Xcode for. The caveat is that the forwarding starts when the proxy connection is established, so output written during the very first millisecond of process launch (before `Display.init`) is not always captured. If you need every byte from `t=0`, attach Xcode's console for that specific run.
-You then set a breakpoint in your Java source, hit it, see the locals as Java values, walk the stack as Java frames, inspect instance fields as Java fields, and invoke methods on live Java objects. The same workflow you have on the simulator, on the device, with nothing in the middle pretending to be something else.
+### Tutorial: IntelliJ + Android
-If you would rather just *try* it, the developer guide has the step-by-step under [On-Device-Debugging.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/On-Device-Debugging.asciidoc) for iOS and [On-Device-Debugging-Android.asciidoc](https://github.com/codenameone/CodenameOne/blob/master/docs/developer-guide/On-Device-Debugging-Android.asciidoc) for Android. The rest of this section is how it is wired.
+Android is simpler because the proxy is not needed. The archetype generates two run configurations under the same *On-Device Debug* folder: **CN1 Android On-Device Debug** (Maven, builds and installs the APK and forwards JDWP) and **CN1 Attach Android** (Remote JVM Debug at `localhost:5005`).
-### iOS, in three pieces
+**1. Enable the build hint.**
-The iOS half is structural because ParparVM translates Java bytecode to C and the operating system has no idea any of it ever was Java. The PR adds three independent pieces that together carry Java semantics across the gap:
+In `common/codenameone_settings.properties`:
-1. **Translator instrumentation.** When you set `cn1.onDeviceDebug=true` the ParparVM translator emits side-tables next to every method (locals address arrays, variable names, line tables, per-class field offset tables, per-method invoke thunks) plus a `cn1-symbols.txt` sidecar that names every class, method, line, local, and field. Release builds are unaffected; the whole thing is gated by a `CN1_ON_DEVICE_DEBUG` preprocessor define so when the hint is off there is no extra code in the binary.
-2. **Device runtime.** A new `cn1_debugger.{h,m}` is compiled into debug builds. It dials out to a desktop proxy over TCP and services a wire protocol from a listener thread. The fast path through the `__CN1_DEBUG_INFO` hook when nothing is attached is a single load and predicted-not-taken branch (`__builtin_expect(cn1DebuggerActive, 0)`), so the cost of having the instrumentation present is in the noise. When something *is* attached, suspend / resume yields the GC bit so paused threads do not block collection; `dup2`-based capture forwards `stdout` and `stderr` into the IDE console; method invocation is queued on the suspended Java thread so it runs in a valid `tsd` context, and the underlying call is wrapped in `setjmp` so an uncaught throw round-trips back as a typed exception instead of `longjmp`-ing past `suspendCurrent`.
-3. **Desktop proxy.** `maven/cn1-debug-proxy/` is a minimum-viable JDWP server that translates between our custom wire protocol and standard JDWP. It is the piece that lets *any* JDWP-speaking IDE attach: from the IDE's point of view it is just talking to a JVM. Coverage includes the parts you actually use day to day: `VirtualMachine.*`, `ReferenceType.*`, `ClassType.InvokeMethod`, `Method.LineTable` / `VariableTable`, `ObjectReference.GetValues` / `InvokeMethod`, `ArrayReference.Length` / `GetValues`, `StringReference.Value`, `ThreadReference.*`, `StackFrame.*`, the full `EventRequest` parser with all twelve JDWP modifier kinds, and the `Event.Composite` events that come back.
+```
+android.onDeviceDebug=true
+```
+
+This single hint flips the manifest to `debuggable="true"` and turns R8 / Proguard off for this build. Release builds without the hint are unaffected.
-The generated archetype includes two IntelliJ run configurations in an *On-Device Debug* folder: *CN1 iOS On-Device Debug* (Maven), which builds the debug `.ipa` with the right hints, installs it, and starts the proxy; and *CN1 Attach iOS* (Remote JVM Debug, `localhost:5005`), which is the second click that hooks IntelliJ to the proxy. Two clicks. Same flow for VS Code and Eclipse using their respective remote-JVM-debug profiles pointed at `localhost:5005`.
+**2. Run CN1 Android On-Device Debug.**
-### Android, in much less code
+Picks up the hint, builds the APK, installs it on the connected device or emulator, sets the debug-app for wait-for-attach, launches the Activity, forwards JDWP to `localhost:5005`, and streams `logcat --pid=k~^=H@e#! Y4)+gdv}}A7_cCk!ot|4Q_p}|AJ{7drNSTF<
zfBXKtAbO5-hxD|Qy(*hLYUgygnwcF{@P2%JWDRcusF(X~h5H!0pB_F^F(_tlnbVdd
z6ML{~x4riX48yGX<&mHWEqb`-($2mY8XX_EFJTpw%QMbQb8a`DvNuv(QM&3u&+6~_
z9pSalg>*%Q3Qzep9^sce00W|cFaO!);IkubH#@w}w7uV!y~o2A%jCC3AJ72)GOI%>`6vnBn`sx2lD>Vw_R
zjd=JbY{S2f%-Dq1IQAwca9WH}esPOkqDz2#;MdZFO`m#2)D@}a=@a;4C#`?pTX|!i
z?47DT8_l#>(-F^m!>uy?e&?nxlV0XNmCc{XCR%T|()S))=b}# tM#9I8@
zAFEDve4NURtDt2mWVA)Z|1w%m{R>OU%0yO>Ju(9EL*?c2nhB$5{Kh8gJAS45TT+&+
z3iiD)!RiZ6l69 2>$yk@#g1JcSU#mklLBvKPG~gU
z$N54C5Q1S$n2TPRPHC8<8f~8-9z}LW#a-oj7c_HD?fLD;c+=Eg9+}tN4$lMxpb4bH
z-|OstI-TR1;MN+BcxrmH99}nN=kB1kWhXWQ^l~@7OnRr!(0fCX)Yx1~v)>h^1$YCT
z1Wh5bTA$Px8xDO{B?)~524sJ>H$fU|3=3E=>UdT77!hqEcOpnJ4kc2P=|$b8#@M$J
zd=9(ZnHE@L!DFWq(nm85-qWs_)KP)DM4##RkdGucOr~X(SU*PeJcIWHRmVPiS-4!b
z;u||w7vsiWx_d`zT`}}<(eM Ya%QS6;KU+d{Ze> 8O_>zcRs1^jc@yr?&V?OL;`+x5M!NY#YAn6_Qag_uuQOmCeI?Ctd9vI5sQo
z>Azw8&wf}$|6PpqtZKPF???0pmWN;c|9gGX6AARF5AdBW00?~apAW($)>QiMb9gKK
zpR>^Q|BvI-bXZ*Li^><_guwgo^Fb0k|C}N;~FUAO4YAn}ChV=5VJ|-AMF|qsBI*>j1
zH49>Zz~@%b=r(DZ@?O*(*kyTEwRtb_Hd=3^ep(B8xL0juVBqAU4+&{5ukaQ}SMRR9
z{AAdokJDUigVfl
ptrGWhC(IfemD2)8q4Haw{&$
zT=5AAI7g0uH=2GW{8ABNydmxK%5rO0
-&n)N
z7t)6lNO11C{ov4>GXXcM=yQ`zH9RdKB?d*SVB>RyzM9_C1a_|wa9*tpA2P@$UVoF+
za~=C!ER2y-_rvCyoOs5H9$D1McyJiSJqzS_(XttzkQ1;?Nd(G8rbxd#*!WQX7t#fN
z>U|gtU|26W=i-igLF5qRqhVz4=wX;uI`?e-pyE4K;Ec{9y21e2;P5XFA;8b$sCdFZ
z5!8A?3*eLe;#f@gon^*y;4vemo`=<+uV4~?tVn=-qA=ieedsyb@WD(Pw1<4Q3;)ap
zX=uFTJz*I9WPk>}&rGa8DPwz42KWI4hfjQyuy_I?pni}v7H^uYx1K+*RpsiL^T(_U
zZ^~xA@ybWjF58i