From 2a5c89b94340cc53de7ca9c13575145eb770f112 Mon Sep 17 00:00:00 2001 From: Philipp Wagner Date: Thu, 8 Oct 2026 23:22:11 +0200 Subject: [PATCH] Next major release/version1.50 (#89) * Make DBController work on one database file per instance The controller was a static singleton: an eagerly created static instance opened the root database during class initialization, and both the connection and the path were static fields. A second operator profile in the same process was therefore impossible, and ChatController's own "new DBController()" never opened anything - it silently adopted the eagerly opened root connection. - drop the eager static instance in favour of a lazily created default instance - turn connection and path into instance state - add a constructor taking a database file name relative to the application directory plus a flag whether a missing file is seeded from the bundled template - create additional profile databases empty instead of seeding them: the bundled template carries 3452 foreign callsigns and user_version 0, which would show a new operator foreign data and trigger the full callsign normalization rebuild. The schema is created by the existing table setup. - remember the shutdown hook so closeDBConnection can deregister it; otherwise every profile switch would leave another hook holding a dead connection All SQL statements keep referencing the plain field and are unchanged. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Allow preferences and chat controller to be bound to a file set ChatPreferences gains a constructor taking a preferences file name relative to the application directory, so "profiles/OP2/preferences.xml" is as valid as the historic flat "preferences.xml". A missing file is still seeded from the bundled template, which gives an additional operator the same clean defaults a first installation gets. ChatController gains a constructor that passes both relative file names and the seed flag through to ChatPreferences and DBController. The existing constructors delegate to the historic file names, so nothing changes yet. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Introduce the operator profile model and its registry Adds the descriptor, the path derivation and the registry persistence for operator profiles. Nothing calls them yet, so behaviour is unchanged. The descriptor stores only a shared/own flag, never a path. All file names are derived in OperatorProfilePaths, so a stored path can never drift apart from the flag that produced it. A profile identifier is a stable, file system safe slug assigned once, so renaming a profile never moves a directory. The registry is created lazily. An installation that only has the historic flat layout gets no registry file and no profiles directory; the root profile is synthesised in memory instead. That keeps a single operator installation byte for byte the one it was before, and it keeps a downgrade to an older release a no-op. A missing, unreadable or malformed registry is logged and treated like an installation without additional profiles, never as an error. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Select the operator profile at startup Resolves the active operator profile before the chat controller is built and passes its two file names on, so preferences, layout and worked data follow the profile. The resolution is deliberately quiet for existing installations. With no registry or exactly one profile nothing is asked and nothing is written, so a single operator start is unchanged. Only from two profiles on does a small picker appear with the last used profile preselected, where Enter or a double click starts immediately. A "--profile" argument, or the equivalent system property, skips the picker; an unknown name warns and falls back to the normal selection instead of refusing to start. The startup decision itself lives in OperatorProfileBootstrap and contains no user interface code, so it is covered by headless tests. The window title gains the profile name only when a second profile exists. Command line parsing happens in init() and is kept in a process wide holder, because JavaFX only knows the parameters of the instance it launched itself. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Release the background resources a discarded runtime owns Several resources outlived a disconnect on purpose, which was harmless while a process ran exactly one session for its whole life. They are now released when the controller itself is closed: - the ON4KST connection supervisor thread, which stopByUser did not touch - the sked reminder scheduler, which had no shutdown at all - the reachability executor, whose shutdown method existed but was never called - the PSTRotator retry scheduler and its pending retry - the map tile proxy, whose stop method existed but was never called, leaving a server socket and a twelve thread pool behind - the station map bridge listeners and its coalescing animation, which would otherwise keep firing into a dead user interface These are real leaks today; they only become visible when a second runtime is built in the same process. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Switch the operator profile while the application is running Splits the teardown out of stop() into a reusable, idempotent shutdownRuntime() and adds File - Switch operator profile..., which tears the current runtime down and builds a fresh one for the selected profile. The new runtime is a new application instance rather than a second start() on the existing one. Many controls are instance fields created once, so reusing the instance would re-parent mounted nodes and register every listener twice. A fresh instance is safe because the class keeps no mutable static state. Closing every window during a switch would end the process under the JavaFX default, so the application takes over the exit decision: implicit exit is turned off, the main window gets an explicit close handler, and every exit path runs through the launcher. That also fixes losing the window layout on exit after a switch, because JavaFX only calls stop() on the instance it launched. The two view timers are now cancelled null-safe; stop() used to dereference them unguarded, which would fail if shutdown happened before they were created. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Manage operator profiles from the settings window Adds a "Profiles" tab, appended last so no established tab position shifts, offering create, duplicate, rename, delete, a switch between shared and own worked stations, and activation of another profile. Duplicating copies the whole configuration except callsign and password. The antenna, locator, layout and integration settings are exactly the work nobody wants to enter twice, while the credentials belong to one operator only. The root profile can neither be deleted nor moved off the common station database, because its files are the installation itself. The login callsign and its raw form now default to empty instead of a real callsign. The XML reader treats an empty element as "not set" and falls back to the field default, so without this change a profile created without credentials would come up carrying the callsign compiled into the defaults - and an operator could transmit under someone else's call. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Document operator profiles Adds a manual section in both languages covering where profile files live, the choice between shared and own worked stations, managing profiles, the startup selection and the --profile argument, switching while running, and the fact that passwords stay in clear text so profiles are not an access boundary. Records the architecture in PROJECT_CONTEXT: lazy registry, derived paths, why an additional profile database is created empty, why the login callsign default is empty, and the constraints of rebuilding the runtime for a switch. Adds a v1.50 changelog entry in both languages including the upgrade notes: no file is moved, and going back to an older release stays possible. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Make the terrain profile cache multi operator safe The cache stored a single owner identity in a meta table and dropped the whole TerrainProfileCache table whenever the configured callsign or locator differed from it. With several operator profiles that turns the cache into a permanent miss: every switch between two operators with different locators would discard every computed profile. Entries are separated by owner identity through the primary key already, so the wipe is replaced by an owner table that simply records which identities are in use. A different owner now misses the cache instead of clearing everybody's. The cache also moves out of the worked station database into its own global terrainprofilecache.db. Terrain profiles are pure geometry derived from two locators and a sample count; at a multi operator station both operators share one location, so a per profile copy would only double the traffic against the terrain service. No migration is needed, the new file refills itself, and the old tables stay readable for older releases. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Fail cleanly when the registry path has no directory SpotBugs flagged a null passed to Files.createTempFile: the null check guarded only createDirectories, while the temporary file creation would still have dereferenced it. The path is resolved absolute so this is practically unreachable, but bailing out with a log line is cheaper than the latent NPE. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01Hpa6bjie5qkeNG62y6FmXm * Code Version 1.50 * Add the in-app update concept for 1.50 Captures the agreed design so it can be handed over later: extended update feed with per-artifact metadata, a build-time package-type marker, a testable check service replacing the blocking call in the ChatController constructor, a non-modal hint suppressed while connected to ON4KST, verified downloads and platform-specific execution. Concept only, nothing implemented yet. Line anchors were verified against this branch. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_01HT8R7zTMoQnmJj6dGbaqqf * Use one base font size and a per-profile startup design JavaFX picks a 13px default font on macOS and Linux but 12px on Windows, so labels in fixed-size controls were cut off outside Windows. Both stylesheets now set 12px on the root. Each operator profile now chooses light or dark mode for startup on the GUI settings tab. The Windows menu entries remain a quick switch for the running session. All windows, including the update window and the top candidates list, follow the design, and the main window no longer starts light while the station map starts dark. Co-Authored-By: Claude Opus 5.5 * Show a drag-to-install layout in the macOS DMG The DMG window now has a background with an arrow from the app to the Applications folder, in the KST4Contest colours. Finder applies the layout through AppleScript; if that fails, e.g. on a headless runner, the script warns and builds the plain DMG as before. Co-Authored-By: Claude Opus 5.5 * Use the macOS system menu bar in all windows On macOS the main menus move into the system menu bar and are shared with the secondary windows, so they stay available whichever window has the focus. The connection state indicator becomes a read-only LINK menu there instead of the status bar button. Other platforms are unchanged. Co-Authored-By: Claude Opus 5.5 * List direct commits on main in the release notes GitHub's generated release notes only cover merged pull requests, so commits pushed straight to main were missing. The release job now builds the notes itself: "What's Changed" holds "Commits on main" (first-parent, without bot and squash-merge commits) and GitHub's PR list as "Merged PRs". Co-Authored-By: Claude Opus 5.5 * Build with Gradle in two modules, and free core of JavaFX Etappen 1 and 2 of the Compose migration (43 commits). The Maven build, the single source tree and the JPMS module-info went together. core now holds the domain and app-desktop the user interface, both built by Gradle, packaged through jpackage from Gradle, with SpotBugs and PMD wired in. JavaFX moves to the classpath, which is why the launcher is Main and not the Application subclass. The PR check, the nightly artifacts, the release and the AUR packages all build from Gradle; the macOS DMG points at its output. Verified on Linux, macOS and Windows. core then loses JavaFX entirely. It observes through kst4contest.observe -- ObservableValue, ObservableRoster, and UiDispatcher as the one boundary a worker thread crosses to touch the interface. The controller collections become rosters and the visible station list a pure derivation rather than a FilteredList/SortedList chain, which is also what fixed two focus defects only a load test had exposed: the keyboard focus stays where the operator put it, and the send field keeps it after a row click. The rule that outlives this commit: ObservableRoster is the store and the list a view is bound to is a mirror of it, never the other way round. * Draw the whole interface in Compose Etappen 3 to 6a of the migration (129 commits). Every window the operator sees is Compose; the JavaFX ones still exist beside them so the two could be compared against a live session, which is the only way the differences came to light. The toolchain first, then the settings window with its eleven tabs and 72 real preferences; then the multi-column table as a component, and with it the rules it needs -- stable row identity, a selection that survives a refresh, column order the operator can drag, and a repaint when the rows change rather than when the list instance does. Then the update and monitor windows, and the main window: 22 station columns, the filter bar, the selected-station panel, the message tabs, the priority bar, the sked controls, the status indicators and the timeline, assembled behind a splitter because Compose has none. The map stops being a WebView. A Compose canvas projects WebMercator tiles itself, with the clustering in core and an asynchronous fetcher in place of the local tile proxy; derive() becomes a pure Kotlin reimplementation instead of a reflection call into com.sun.javafx. Most of the volume here is parity the operator would notice rather than new behaviour: desktop density instead of Material's phone minimums, colours taken from the JavaFX stylesheets instead of Material's palette, row dividers, band columns, grid-square labels and their colours, the home marker and antenna beam, pinch-to-zoom under Wayland, and layouts that survive a window narrower than the chart they stack. Two lessons are worth more than the diff. A control bound to a value Compose cannot observe writes through and never redraws -- that one shipped repeatedly with a green build, because no test drew anything. And a layout that clips instead of wrapping is worse than one that is merely too narrow: half a word is the worst available outcome. * Remove JavaFX The second half of Etappe 6 (61 commits). grep -rl "javafx\." over both main source trees is empty, nothing imports javafx, neither classpath resolves it, and org.openjfx is out of the build and the version catalog. The finding that shaped the work: the JavaFX main window was built on every start and never shown -- primaryStage's setScene and show were both commented out. Most of those 11,655 lines were dead weight rather than a port. But not all of them, and that is the trap this commit is really about: dead-looking methods still fed live Compose sinks. They were cut at their seams instead of deleted, and a sweep script that follows calls was written to find them, because reading the code does not reveal them. In order: the colour derivation frozen as checked-in test data, so the pin survives JavaFX being removed instead of silently comparing against itself; the live feeds lifted out of the never-shown window and given names and tests; the dead scaffolding deleted in slices; then the lifecycle. UiDispatcher now delivers to the AWT event dispatch thread, the ten Alerts are modal Compose dialogs, HostServices gives way to java.awt.Desktop with the mailto/http split JavaFX did not need, and extends Application, start(Stage), stop and launch are gone -- main builds the runtime and a shutdown hook replaces stop(). An independent review found two deadlocks in that move, both the same failure class, both invisible to the build: a blocking wait on the event thread for work that can only advance on the event thread. The profile picker waited on a latch and froze the client for good; ComposeWindowHost.close waited on Thread.join and returned with the window still marked open, which made a profile switch raise the dead runtime's window and leave the rebuilt profile without its Connect button. A third came out of fixing them: a ComposeDialog built off the event thread cannot create its GL context and never paints. Three defects only a GUI run showed, never the build: an NPE on a deleted field, a Compose menu still hanging on deleted MenuItems, and a category bookkeeping field that looked dead but is read by the outgoing-message category resolution -- deleting it would have sent messages in the wrong category. The binding docs and the manual no longer describe a JavaFX client. * Draw the menu bar in Compose, and give the drawing layer a net What the removal left open (4 commits). Compose's MenuBar is a javax.swing.JMenuBar set on the window, so Swing draws it and no theme reaches it; with no look-and-feel configured that meant the default Metal menu above a themed window. The bar is drawn in the window now, except on macOS, where the system bar is where that platform expects it. Two renderers read one description -- mainMenuModel is a plain function of the state, which also gives the menus their first tests. Closing the main window quits the application again, and the window writes its size back to the profile; both had quietly stopped working when the last JavaFX stage went. Then Etappe 7. Four faults shipped in the settings-window branch alongside a green suite of 382 tests, because not one of those tests drew anything: a control that never redrew, a tab strip that clipped mid-word, a form taller than its window with no way down, and colours that came from Material rather than the stylesheet. One regression test per class, and the spec's acceptance criterion is met rather than assumed -- each fault was put back deliberately and the matching test watched to fail. The CI had never run the suite at all; it does now, headless. What that took was not Xvfb: skiko's native library links against libGL and only has to be loadable, since the drawing tests render in software. Without the package the whole Compose half of the suite dies with a message that reads like a missing display. Found by running the job under act rather than on GitHub. The six tests that open a real window skip headless by their own guard. The summary step counts from the result XML and fails on failures there, because this project's rule is never to infer a green suite from an exit code. * Make the colours adjustable per operator profile Six colour roles per design, per profile: surface, window surface, field interior, text, accent and separator line. A change applies at once in every open window and survives a restart once the settings are saved, like any other preference. Three sources, later wins role by role: the shipped stylesheet from the classpath, then the profile's own stylesheet file if there is one, then the overrides stored in the profile's preferences. resolvePalette is a pure function and reports where every role's colour came from, which the tab shows per field -- with two sources able to decide one colour, that is the only thing keeping "why is this colour what it is" answerable, and the spec calls it mandatory rather than decorative. Four things this had to get right, each learned the hard way and each pinned: A role is a selector and a property, not a property alone. Three of the six are stated outside .root -- text on .label, the separator on .separator *.line -- and -fx-background-color alone appears a dozen times in the evening sheet. Measured: the shipped daylight sheet states no colour at all, the evening sheet states five and implies the sixth. Kst4ContestTheme reads the palette from the store's state and not from remember. That read is what makes a change repaint every open window; remember(darkMode) held the palette until somebody toggled day/evening, so a change reached nothing. A derived colour follows its source's value, never its provenance. The root profile's own stylesheet is the one copyResourceIfRequired writes at every startup -- the shipped sheet itself -- so layer 2 declares the accent on every existing installation with nobody having chosen anything. Keying textAccent on "does this come from a file" repainted the evening accent from green to blue on upgrade and made "reset to shipped" disagree with "discard my changes". The contrast guard measures where colours are actually drawn, read off Theme.kt's Material mapping rather than off the role names: background and surface are both the window surface, and primary is textAccent, not accent. It reports a pair only when it is both under WCAG AA and worse than the shipped sheet -- the shipped sheets have three pairs under 4.5 themselves, so an absolute floor would warn on an untouched client and teach the operator to ignore warnings. The way back out of an unreadable palette is deliberately overbuilt, because it is the one failure that locks itself in. "Reset to the shipped colours" takes the shipped palette as a required parameter and reads no composition local, so there is no path by which it could be drawn in the colours it exists to undo; it looks out of place under a customised palette, and that is what makes it findable. Ctrl+Z, Ctrl+D and Ctrl+R reach the three ways back even with the caret in a colour field. A mistyped colour is refused and the field snaps back. The profile's stylesheet is the hand-editing route the copy under ~/.praktiKST has been promising since it was first written and never read. It is read now. A button writes the shipped template as a starting point and never replaces a file that is already there. An unreadable, truncated or non-CSS file does not prevent startup -- the role falls back to the shipped design. A sheet stating -fx-base and no -fx-background states the derived window surface too, the way JavaFX does, or the most natural hand edit would leave every window the shipped light grey. 101 new tests. All of it runs headless. * Document the adjustable colours, and record the design and the plan Both manuals get the Colours tab in full: the six roles, that a change applies at once but survives a restart only after Save settings, the three ways back with their keyboard shortcuts, what each provenance label means, and the readability notice that warns without refusing. Two things an operator would otherwise have to discover. The reset button is always drawn in the shipped colours and works when nothing else can be read -- the risk section of the design says plainly that a keyboard path only helps whoever knows it, so the manual is where this has to be written down. And the root profile already has both stylesheet files, because KST4Contest has been writing them at startup for years, so most of its roles report "from file" rather than "shipped" with identical values. PROJECT_CONTEXT.md records the decisions that outlive this stage: the three sources and their precedence, that a role is a selector and a property, that the theme must read the store's state rather than remember, where the contrast pairs come from, why the root profile's file layer always exists, and why the lifeline refuses the active palette. Also corrects its claim that CSS stays global -- a profile now owns its stylesheets. The design document and the implementation plan are kept as they were written, including the plan's own corrections where measuring the code contradicted it. * Speak the operator's language The interface is German or English, chosen per operator profile on the GUI tab, in force at once in every open window, and remembered across restarts. 376 texts in both languages. The texts are ordinary .properties files that nobody has to compile: a contributor copies the English one, translates the values, and opens a pull request. A third module -- build tooling that never ships -- turns them into Kotlin before anything compiles, which is what makes a mistyped key and a wrong argument count compile errors rather than things an operator discovers. It lives in the main build rather than buildSrc because buildSrc's tests do not run on `./gradlew build`, measured, and a generator whose tests never run is the exact failure it exists to prevent. Incompleteness is allowed and incorrectness is not. A missing key warns and falls back to English, so a partial contributed language can be submitted at all; an orphan key, a placeholder the translation drops, a duplicate key or an unreadable file fail the build with the generator's own message naming the file. The argument count always comes from the English base. German is held complete by a test because it ships; a contributed language is not. What is deliberately not translated is the harder half. Protocol frames and chat commands would break the connection or go unread; the beacon texts, auto answers, snippets and shortcuts go to other radio amateurs and sit in every operator's stored profile; the 273 println calls in core are diagnostics, and a German stack trace is worse for whoever reads the bug report; and QRA, QRG, QTF, LOS, Fresnel and wkd read the same in either language. Three tests guard the boundary by measuring behaviour rather than text: the protocol frames built under three locales, every preference default compared by reflection, and no translation value being a protocol command. The reflective one is the only one that covers what nobody thought of. One insight turned up three times. Anything built outside a composition freezes the language it was built in: the window title, the settings tab strip and every column header are all constructed once at startup -- the columns from Java -- so each now holds a function read when it is drawn. That also fixed something older and unrelated to language: the main window's title was a fixed "KST4Contest (Compose)" for the whole session, where the JavaFX window had carried the live connection line. It carries it again. A column's id is never translated. It is what the remembered widths and order are keyed on. * Document the two languages, and how to contribute a third Both manuals get the language picker in full: where it sits, that it applies per profile and takes effect at once in every open window, and -- at more length -- what is deliberately left alone and why. An operator who sees an English beacon text in a German client should be able to read that it is meant that way. The contribution route is written down in both, because plain text files are only useful if somebody knows they are there: copy, translate, submit; a partial file is welcome; the build reports mistakes by file name and writes a worksheet of what is still missing. PROJECT_CONTEXT records the decisions that outlive this stage -- the four kinds of text and the rule that the addressee decides, that core produces no display text, that incompleteness is allowed and incorrectness is not, that anything built outside a composition needs its text read inside one, and that a column id is never translated. CLAUDE.md said two modules; there are three, and the third never ships. It also states the German orthography now, which this session got wrong across a spec and two plans: ss after a short vowel, so muss and dass. * Remove the implementation plans now that every stage is executed Thirteen plans, all of them step-by-step instructions for work that is committed. A plan left behind reads to the next person like an open intention, and these describe a build that no longer exists -- the first still explains how to introduce Gradle. The specifications stay. They say why the architecture is what it is, which the code cannot, and three of them are still argued from. The live-findings note stays too: CLAUDE.md sends people to it, and its hardest lesson -- that a blocking wait on the AWT event thread deadlocks the interface while the build stays green -- is written down nowhere else. Its sweep script stays as well. The note argues explicitly that the script belongs beside the finding so the next reader can measure rather than believe, and removing it would contradict the reasoning it illustrates. Two references in the note and one in the JavaFX-removal spec pointed at plans and now say where the reasoning went instead. * Point the JavaFX-removal spec at where its plan's reasoning went * Remove the stray release-metadata patch from the working tree A 416-line patch file that was applied long ago and has sat in the repository root since. It predates this branch and stays in the shared history, where rewriting it would mean rewriting commits that are already on main and on origin. * Check the translation files in CI and say what they hold classes already runs the generator, so an orphan key, a dropped placeholder or a duplicate fails the compile job with the generator's own message naming the file -- verified by breaking strings_de.properties on purpose. A step summary counts each language against the base, so the author of a translation PR sees what they covered without reading the build log. Co-Authored-By: Claude Opus 5 (1M context) * Refuse a translation key that would not form a Kotlin name The generator escaped every translation value but emitted the key verbatim as the member identifier, and identifierFor strips only . _ - -- so a key carrying a space, a brace, a quote or a newline from a \uXXXX escape broke out of val : String get() = lookup(...) into an init block or property initializer that runs when Strings is instantiated. Translation files are the contribution surface that arrives by pull request, so this was a path from a merged .properties change to code in every client. The generated identifier is now held to letters-then-letters-and-digits before any source is written, alongside the existing orphan and collision refusals. Proven by replaying a file-writing payload against the built generator: it now throws and writes nothing. Co-Authored-By: Claude Opus 5 (1M context) * Port the rebased diagnostics and session logging onto the modules origin/main landed replayable session logging (MessageHistoryRecorder), file logging (ApplicationFileLogging) and a user-list refresh split on the old flat layout. The rebase carried the new files, but three things needed the new architecture: - ChatController.fireUserListUpdate() used javafx Platform; core is toolkit-free now, so it dispatches through uiDispatcher like every other fire method. - Two new tests were left in the old src/test/java; moved into core. - ScoreServiceRefreshTest mocked javafx Platform statically; it now injects the DirectUiDispatcher the no-arg constructor installs. The Leaflet map performance work was dropped with the HTML map it optimised. classes testClasses and test are green: 1069 tests, 0 failures, 3 skipped. Co-Authored-By: Claude Opus 5 (1M context) * Give the debug-to-file recording a home in the Compose settings origin/main added a checkbox to the old JavaFX settings that recorded the whole ON4KST session to file; the Compose redraw dropped the old settings UI, so the toggle had no control left even though the preference and its wiring survived the rebase. It returns to the message-handling tab: the state writes the preference and asks the application, through a new SettingsHost callback, to open or close the error-log handler and the history recorder in the order the old checkbox kept. The explanatory line and its German translation say that passwords are redacted. Co-Authored-By: Claude Opus 5 (1M context) * Fix Codex review findings on PR 89: station row key, map selection, sort after filter - Station row key now includes the chat category, so the same callsign in two categories no longer collides. - Map marker click and Reset view go through the central station selection. - Sorting now operates on the filtered rows, so filters stay effective. Co-Authored-By: Claude Opus 5.5 * Keep the map drawing test off the network and the user's tile cache The test assumed no tile ever arrives, but it used the default TileFetcher, which reads the real disk cache and the OSM tile server. On CI a tile now and then landed before the frame was rendered and covered the background the 'unreachable tile source' test asserts on. An empty temporary cache and a source that always fails make the assumption hold by construction. Co-Authored-By: Claude Opus 5.5 --------- Co-authored-by: Claude Opus 5 --- .github/workflows/aur-nightly-git.yml | 4 +- .github/workflows/aur-publish.yml | 6 +- .github/workflows/docs-pdf.yml | 2 +- .github/workflows/nightly-artifacts.yml | 199 +- .github/workflows/pr-compile-check.yml | 163 +- .github/workflows/tagged-release.yml | 260 +- .../workflows/test-publish-version-xml.yml | 170 + .gitignore | 12 + .mvn/wrapper/maven-wrapper.jar | Bin 62547 -> 0 bytes .mvn/wrapper/maven-wrapper.properties | 18 - ...ument-v1.43-and-fix-release-metadata.patch | 416 - AGENTS.md | 37 +- CLAUDE.md | 51 + README.md | 12 +- app-desktop/build.gradle.kts | 157 + .../src/main/i18n/strings_de.properties | 380 + .../src/main/i18n/strings_en.properties | 389 + .../kst4contest/controller/AppRunner.java | 0 ...atPreferencesStationMapVisibilityTest.java | 0 .../test/FrequencyTextParserTest.java | 0 .../kst4contest/test/PatternMatcherTest.java | 42 +- .../test/Utils4KSTFrequencyTest.java | 6 +- .../view/ApplicationRuntimeLauncher.java | 101 + .../kst4contest/view/AwtUiDispatcher.java | 41 + .../kst4contest/view/CoalescingTrigger.java | 38 + .../kst4contest/view/CommandLineOptions.java | 133 + .../view/ComposeChatInputActions.java | 100 + .../kst4contest/view/ComposeMenuActions.java | 115 + .../kst4contest/view/ExternalDocuments.java | 75 + .../main/java/kst4contest/view/GuiUtils.java | 65 +- .../view/Kst4ContestApplication.java | 4268 +++++ .../java/kst4contest/view/LayoutAutosave.java | 72 + .../src}/main/java/kst4contest/view/Main.java | 0 .../view/OperatorProfileBootstrap.java | 107 + .../view/OperatorProfileChoiceRequester.java | 26 + .../view/PrivateMessageRowStyleResolver.java | 0 .../kst4contest/view/RosterListBinding.java | 162 + .../java/kst4contest/view/ScreenBounds.java | 60 + .../kst4contest/view/TableLayoutManager.java | 45 + .../view/TruncatedTextTooltipSupport.java | 0 .../main/kotlin/kst4contest/view/BuildInfo.kt | 18 + .../kst4contest/view/compose/AirplaneCell.kt | 61 + .../kst4contest/view/compose/ChatInputRow.kt | 308 + .../view/compose/ChatInputState.kt | 199 + .../kst4contest/view/compose/ComposeAlert.kt | 436 + .../view/compose/ComposeWindowHost.kt | 350 + .../kst4contest/view/compose/ConnectionBar.kt | 114 + .../kst4contest/view/compose/ContrastRule.kt | 96 + .../kst4contest/view/compose/DataTable.kt | 381 + .../view/compose/DataTableState.kt | 406 + .../kst4contest/view/compose/DataTableView.kt | 440 + .../kst4contest/view/compose/Density.kt | 68 + .../view/compose/DirectedMessageColumns.kt | 88 + .../view/compose/DirectedMessageRowStyle.kt | 68 + .../kst4contest/view/compose/FormControls.kt | 564 + .../view/compose/JavaFxStylesheet.kt | 447 + .../kst4contest/view/compose/MainMenuBar.kt | 223 + .../kst4contest/view/compose/MainMenuModel.kt | 136 + .../view/compose/MainMenuRowState.kt | 48 + .../kst4contest/view/compose/MainMenuState.kt | 71 + .../kst4contest/view/compose/MainWindow.kt | 285 + .../view/compose/MainWindowFrame.kt | 93 + .../view/compose/MainWindowHost.kt | 153 + .../view/compose/MainWindowState.kt | 164 + .../view/compose/MessageFormats.kt | 52 + .../kst4contest/view/compose/MessageTabs.kt | 96 + .../view/compose/MonitorColumns.kt | 72 + .../kst4contest/view/compose/MonitorWindow.kt | 107 + .../kst4contest/view/compose/ObservedValue.kt | 37 + .../compose/OperatorProfilePickerWindow.kt | 222 + .../view/compose/PaletteResolution.kt | 88 + .../kst4contest/view/compose/PaletteStore.kt | 211 + .../view/compose/PaletteStoreFactory.kt | 95 + .../view/compose/PublicMessageColumns.kt | 50 + .../compose/SelectedStationMessageColumns.kt | 60 + .../view/compose/SelectedStationPanel.kt | 257 + .../view/compose/SelectedStationState.kt | 183 + .../kst4contest/view/compose/SettingsTabs.kt | 332 + .../view/compose/SettingsWindow.kt | 328 + .../view/compose/SnippetContextMenu.kt | 30 + .../kst4contest/view/compose/SplitterPane.kt | 136 + .../kst4contest/view/compose/SplitterState.kt | 109 + .../view/compose/StationColumns.kt | 154 + .../view/compose/StationFilterBar.kt | 282 + .../view/compose/StationFilterState.kt | 161 + .../view/compose/StationRowStyle.kt | 42 + .../kst4contest/view/compose/StatusBar.kt | 242 + .../view/compose/StatusIndicatorState.kt | 225 + .../kotlin/kst4contest/view/compose/Theme.kt | 169 + .../kst4contest/view/compose/TimelineState.kt | 212 + .../kst4contest/view/compose/TimelineView.kt | 311 + .../compose/TopPriorityCandidatesWindow.kt | 173 + .../view/compose/TopPriorityState.kt | 44 + .../kst4contest/view/compose/UpdateWindow.kt | 168 + .../view/compose/UpdateWindowState.kt | 96 + .../view/compose/WindowShortcuts.kt | 70 + .../view/compose/map/ComposeStationMap.kt | 916 ++ .../view/compose/map/MapOverlayControls.kt | 120 + .../view/compose/map/PathAnalysisDetails.kt | 151 + .../view/compose/map/PathProfileChart.kt | 585 + .../view/compose/map/StationMapWindow.kt | 399 + .../view/compose/map/TileBitmapCache.kt | 54 + .../view/compose/tabs/AirscoutTab.kt | 92 + .../view/compose/tabs/AirscoutTabState.kt | 111 + .../view/compose/tabs/BeaconTab.kt | 58 + .../view/compose/tabs/BeaconTabState.kt | 104 + .../view/compose/tabs/ColourShortcuts.kt | 83 + .../view/compose/tabs/ColoursTab.kt | 266 + .../view/compose/tabs/ColoursTabState.kt | 171 + .../compose/tabs/ExternalInterfaceFields.kt | 156 + .../view/compose/tabs/GuiOptionsTab.kt | 80 + .../view/compose/tabs/GuiOptionsTabState.kt | 57 + .../view/compose/tabs/LogSynchTab.kt | 100 + .../view/compose/tabs/LogSynchTabState.kt | 127 + .../view/compose/tabs/MessageHandlingTab.kt | 46 + .../compose/tabs/MessageHandlingTabState.kt | 51 + .../view/compose/tabs/NotificationTab.kt | 151 + .../view/compose/tabs/NotificationTabState.kt | 214 + .../view/compose/tabs/ProfilesTab.kt | 380 + .../view/compose/tabs/ProfilesTabState.kt | 246 + .../view/compose/tabs/ShortcutsTab.kt | 48 + .../view/compose/tabs/ShortcutsTabState.kt | 51 + .../view/compose/tabs/StationTab.kt | 106 + .../view/compose/tabs/StationTabState.kt | 213 + .../view/compose/tabs/StylesheetExport.kt | 59 + .../view/compose/tabs/TrxSynchTab.kt | 70 + .../view/compose/tabs/TrxSynchTabState.kt | 78 + .../view/compose/tabs/WorkedDatabaseTab.kt | 150 + .../compose/tabs/WorkedDatabaseTabState.kt | 96 + .../view/feed/ConnectionStateFeed.kt | 32 + .../view/feed/SelectedStationMessagesFeed.kt | 27 + .../kst4contest/view/feed/TimelineFeed.kt | 50 + .../kst4contest/view/i18n/LanguageStore.kt | 128 + .../view/i18n/LanguageStoreFactory.kt | 37 + .../kst4contest/view/i18n/LocaleChoice.kt | 33 + .../main/resources/KST4ContestDefaultDay.css | 5 + .../resources/KST4ContestDefaultEvening.css | 2 + .../test/MessageVariableResolverTest.java | 14 +- .../PrivateMessageRowStyleResolverTest.java | 0 .../kst4contest/view/AwtUiDispatcherTest.java | 90 + .../view/CoalescingTriggerTest.java | 101 + .../view/CommandLineOptionsTest.java | 46 + .../view/ComposeMainWindowOptionTest.java | 52 + .../view/ExternalDocumentsTest.java | 44 + .../kst4contest/view/LayoutAutosaveTest.java | 83 + .../MacOsConnectionStateMenuTitleTest.java | 34 + .../view/OperatorProfileBootstrapTest.java | 161 + .../view/RosterListBindingTest.java | 153 + .../kst4contest/view/ScreenBoundsTest.java | 51 + .../view/TableLayoutManagerTest.java | 0 .../view/TruncatedTextTableCellTest.java | 0 .../TerrainProfileCacheRepositoryTest.java | 111 + .../kotlin/kst4contest/view/BuildInfoTest.kt | 24 + .../view/StartupStylesheetCopyTest.kt | 56 + .../view/compose/AirplaneCellTest.kt | 107 + .../view/compose/ChatInputStateTest.kt | 435 + .../view/compose/ComposeAlertTest.kt | 152 + .../compose/ComposeWindowHostCloseTest.kt | 146 + .../compose/ComposeWindowHostRaiseTest.kt | 80 + .../view/compose/ContrastRuleTest.kt | 172 + .../view/compose/DataTableStateTest.kt | 559 + .../compose/DirectedMessageColumnsTest.kt | 123 + .../compose/DirectedMessageRowStyleTest.kt | 75 + .../compose/DrawingLayerRegressionTest.kt | 207 + .../view/compose/EditableListStateTest.kt | 220 + .../view/compose/JavaFxStylesheetTest.kt | 340 + .../view/compose/MainMenuModelTest.kt | 184 + .../view/compose/MainMenuRowStateTest.kt | 83 + .../view/compose/MainMenuStateTest.kt | 113 + .../view/compose/MainWindowFrameTest.kt | 158 + .../view/compose/MainWindowStateTest.kt | 173 + .../view/compose/MonitorColumnsTest.kt | 133 + .../view/compose/ObservedValueTest.kt | 93 + .../compose/OperatorProfilePickerStateTest.kt | 69 + .../OperatorProfilePickerWindowTest.kt | 88 + .../view/compose/PaletteResolutionTest.kt | 169 + .../view/compose/PaletteStoreFactoryTest.kt | 109 + .../view/compose/PaletteStoreTest.kt | 278 + .../view/compose/PublicMessageColumnsTest.kt | 70 + .../view/compose/SelectedStationStateTest.kt | 226 + .../view/compose/SettingsFieldCoverageTest.kt | 44 + .../SettingsForeignWriteCoverageTest.kt | 50 + .../view/compose/SplitterStateTest.kt | 225 + .../view/compose/StationColumnsTest.kt | 136 + .../view/compose/StationFilterStateTest.kt | 157 + .../view/compose/StatusIndicatorStateTest.kt | 414 + .../compose/StylesheetDeclaredRolesTest.kt | 163 + .../compose/ThemeReadsPaletteStoreTest.kt | 83 + .../compose/TimelineCandidateFieldsTest.kt | 51 + .../view/compose/TimelineStateTest.kt | 316 + .../TopPriorityCandidatesWindowTest.kt | 140 + .../view/compose/TopPriorityStateTest.kt | 122 + .../view/compose/TypographyScalingTest.kt | 31 + .../view/compose/UpdateWindowStateTest.kt | 123 + .../view/compose/WindowShortcutsTest.kt | 45 + .../map/ComposeStationMapDrawingTest.kt | 278 + .../map/ComposeStationMapLayoutTest.kt | 80 + .../map/PathAnalysisDetailsLayoutTest.kt | 65 + .../map/PathAnalysisDetailsWidthTest.kt | 83 + .../compose/map/PathProfileChartLayoutTest.kt | 46 + .../compose/map/StationMapBodyLayoutTest.kt | 119 + .../view/compose/map/TileBitmapCacheTest.kt | 82 + .../view/compose/map/TileKeyTest.kt | 64 + .../view/compose/tabs/AirscoutTabStateTest.kt | 132 + .../view/compose/tabs/BeaconTabStateTest.kt | 138 + .../view/compose/tabs/ColourShortcutsTest.kt | 80 + .../view/compose/tabs/ColoursTabStateTest.kt | 219 + .../compose/tabs/GuiOptionsTabStateTest.kt | 84 + .../view/compose/tabs/LifelineColoursTest.kt | 76 + .../view/compose/tabs/LogSynchTabStateTest.kt | 156 + .../tabs/MessageHandlingTabStateTest.kt | 65 + .../compose/tabs/NotificationTabStateTest.kt | 272 + .../view/compose/tabs/ProfilesTabStateTest.kt | 168 + .../compose/tabs/ShortcutsTabStateTest.kt | 117 + .../view/compose/tabs/StationTabStateTest.kt | 98 + .../view/compose/tabs/StylesheetExportTest.kt | 124 + .../view/compose/tabs/TrxSynchTabStateTest.kt | 120 + .../tabs/WorkedDatabaseTabStateTest.kt | 80 + .../view/feed/ConnectionStateFeedTest.kt | 76 + .../view/feed/FeedIsTheOnlyWriterTest.kt | 192 + .../feed/FeedLifetimeIsTiedToTheWindowTest.kt | 81 + .../feed/SelectedStationMessagesFeedTest.kt | 76 + .../kst4contest/view/feed/TimelineFeedTest.kt | 88 + .../view/i18n/LanguageStoreTest.kt | 140 + .../kst4contest/view/i18n/LocaleChoiceTest.kt | 54 + .../i18n/StringsReachTheCompositionTest.kt | 75 + .../view/i18n/TranslationBoundaryTest.kt | 122 + .../resources/javafx-derive-reference.txt | 223 + .../src/test/resources/settings-fields.txt | 72 + .../resources/settings-foreign-writes.txt | 5 + build.gradle.kts | 48 + core/build.gradle.kts | 21 + .../kst4contest/ApplicationConstants.java | 4 +- .../controller/ActiveOperatorProfile.java | 48 + ...outPeriodicalAPReflectionInquirerTask.java | 0 .../kst4contest/controller/BeaconTask.java | 0 .../controller/ChatController.java | 567 +- .../controller/ChatMemberListView.java | 77 + .../kst4contest/controller/DBController.java | 184 +- .../controller/DXClusterController.java | 2 +- .../controller/DXClusterSpotFormatter.java | 0 .../DXClusterThreadPooledServer.java | 10 +- .../controller/ExternalLoggedQso.java | 0 .../controller/InputReaderThread.java | 0 .../kst4contest/controller/LoggedQsoBand.java | 0 .../MessageBusManagementThread.java | 22 +- ...sManagementThreadFrequencyContextTest.java | 0 .../controller/MessageHistoryRecorder.java | 0 .../controller/MessageVariableResolver.java | 6 +- .../controller/On4KstConnectionManager.java | 14 + .../controller/On4KstConnectionState.java | 0 .../controller/On4KstProtocol.java | 0 .../controller/On4KstProtocolTest.java | 0 .../controller/On4KstSocketThreadTest.java | 0 .../OperatorProfileManagementService.java | 312 + .../controller/OperatorProfilePaths.java | 228 + .../controller/OperatorProfileStore.java | 386 + .../controller/PstRotatorClient.java | 0 .../controller/ReachabilityService.java | 13 +- .../kst4contest/controller/ReadThread.java | 0 .../controller/ReadUDPByWintestThread.java | 3 +- .../ReadUDPByWintestThreadTest.java | 0 .../ReadUDPbyAirScoutMessageThread.java | 5 +- .../controller/ReadUDPbyUCXMessageThread.java | 5 +- .../kst4contest/controller/RegexTester.java | 0 .../kst4contest/controller/ScoreService.java | 53 +- .../controller/ScoreboardUpdateTask.java | 0 .../controller/SkedReminderService.java | 19 +- .../kst4contest/controller/StartChat.java | 2 - .../controller/StationMetricsService.java | 0 .../controller/StatusUpdateListener.java | 0 .../controller/ThreadStatusCallback.java | 0 .../controller/UCXLogFileToHashsetParser.java | 0 .../kst4contest/controller/UpdateChecker.java | 0 .../controller/UserActualizationTask.java | 0 .../kst4contest/controller/Utils4KST.java | 6 +- .../controller/WinTestIhaveInventory.java | 0 .../controller/WinTestLogSegment.java | 0 .../controller/WinTestLogSyncService.java | 0 .../controller/WinTestMessage.java | 0 .../WinTestNetworkAddressResolver.java | 0 .../kst4contest/controller/WinTestPacket.java | 0 .../controller/WinTestSkedSender.java | 0 .../controller/WorkedGrossFieldCache.java | 0 .../kst4contest/controller/WriteThread.java | 0 .../interfaces/PstRotatorEventListener.java | 0 .../keepAliveMessageSenderTask.java | 0 .../java/kst4contest/locatorUtils/Angle.java | 0 .../locatorUtils/DirectionUtils.java | 0 .../kst4contest/locatorUtils/Latitude.java | 0 .../kst4contest/locatorUtils/Location.java | 0 .../kst4contest/locatorUtils/Longitude.java | 0 .../locatorUtils/TestLocatorUtils.java | 0 .../logic/BandOpportunityResolver.java | 0 .../logic/FrequencyTextParser.java | 0 .../kst4contest/logic/PriorityCalculator.java | 2 +- .../logic/PropagationFrequencyResolver.java | 0 .../kst4contest/logic/SignalDetector.java | 0 .../main/java/kst4contest/model/AirPlane.java | 0 .../model/AirPlaneReflectionInfo.java | 8 +- .../main/java/kst4contest/model/Band.java | 0 .../java/kst4contest/model/ChatCategory.java | 0 .../java/kst4contest/model/ChatMember.java | 21 +- .../ChatMemberDirectionOpportunityTest.java | 0 .../java/kst4contest/model/ChatMessage.java | 0 .../kst4contest/model/ChatPreferences.java | 251 +- .../kst4contest/model/ClusterMessage.java | 0 .../java/kst4contest/model/ContestSked.java | 0 .../kst4contest/model/OperatorProfile.java | 133 + .../model/OperatorProfileSelection.java | 70 + .../kst4contest/model/PaletteOverrides.java | 120 + .../java/kst4contest/model/PaletteRole.java | 97 + .../kst4contest/model/ThreadStateMessage.java | 0 .../kst4contest/model/UpdateInformation.java | 0 .../observe/DirectUiDispatcher.java | 22 + .../kst4contest/observe/MutableValue.java | 11 + .../kst4contest/observe/ObservableRoster.java | 33 + .../kst4contest/observe/ObservableValue.java | 22 + .../kst4contest/observe/SimpleRoster.java | 119 + .../java/kst4contest/observe/SimpleValue.java | 57 + .../kst4contest/observe/UiDispatcher.java | 18 + .../service/path/FresnelMathUtils.java | 0 .../java/kst4contest/test/MockKstServer.java | 0 .../utils/ApplicationFileLogging.java | 0 .../utils/ApplicationFileUtils.java | 0 .../java/kst4contest/utils/PlatformUtils.java | 29 + .../kst4contest/utils/PlayAudioUtils.java | 0 .../java/kst4contest/utils/VersionUtils.java | 0 .../map/ChainedTerrainProfileProvider.java | 0 ...CopernicusGlo30TerrainProfileProvider.java | 0 .../java/kst4contest/view/map/DemDataset.java | 0 .../map/FallbackTerrainProfileProvider.java | 0 .../map/GeometryOnlyPathAnalysisService.java | 0 .../view/map/MaidenheadGridRenderPlanner.java | 0 .../view/map/MaidenheadGridUtils.java | 0 .../view/map/MapCallsignRawSnapshot.java | 0 .../map/MapCallsignRawSnapshotBuilder.java | 10 +- .../view/map/MapMarkerCluster.java | 53 + .../view/map/MapMarkerClusterTooltip.java | 51 + .../kst4contest/view/map/MapViewport.java | 230 + .../view/map/NoOpTerrainProfileProvider.java | 0 .../view/map/OfflineDemImportService.java | 0 .../view/map/OfflineDemManager.java | 0 .../map/OfflineDemTerrainProfileProvider.java | 0 .../map/OpenMeteoTerrainProfileProvider.java | 0 .../view/map/PathAnalysisRequest.java | 0 .../view/map/PathAnalysisResult.java | 0 .../view/map/PathAnalysisService.java | 0 .../view/map/PathGeometryUtils.java | 0 .../view/map/PathHorizonSummary.java | 0 .../view/map/PathLinkBudgetSettings.java | 0 .../view/map/PathLinkBudgetSummary.java | 0 .../view/map/PathObstructionSummary.java | 0 .../view/map/PathProfilePoint.java | 0 .../view/map/PathPropagationAssessment.java | 0 .../view/map/StationMapClusterer.java | 160 + .../view/map/StationMapStatusText.java | 99 + .../map/SyntheticTerrainProfileProvider.java | 0 .../kst4contest/view/map/TerrainCatalog.java | 0 .../view/map/TerrainCatalogClient.java | 0 .../view/map/TerrainCatalogPackageEntry.java | 0 .../view/map/TerrainCoverageResolver.java | 0 .../view/map/TerrainPackageDownloader.java | 0 .../view/map/TerrainPackageInstaller.java | 0 .../view/map/TerrainPackageManifest.java | 0 .../view/map/TerrainPackageService.java | 0 .../map/TerrainProfileCacheRepository.java | 107 +- .../view/map/TerrainProfileData.java | 0 .../view/map/TerrainProfileProvider.java | 0 .../view/map/TerrainProfileRequest.java | 0 .../view/map/TerrainTileMetadata.java | 0 .../kst4contest/view/map/TileFetcher.java | 311 + .../view/map/WebMercatorProjection.java | 33 + .../java/kst4contest/view/map/mapTest.java | 0 {src => core/src}/main/resources/LTTR0.mp3 | Bin {src => core/src}/main/resources/LTTR1.mp3 | Bin {src => core/src}/main/resources/LTTR2.mp3 | Bin {src => core/src}/main/resources/LTTR3.mp3 | Bin {src => core/src}/main/resources/LTTR4.mp3 | Bin {src => core/src}/main/resources/LTTR5.mp3 | Bin {src => core/src}/main/resources/LTTR6.mp3 | Bin {src => core/src}/main/resources/LTTR7.mp3 | Bin {src => core/src}/main/resources/LTTR8.mp3 | Bin {src => core/src}/main/resources/LTTR9.mp3 | Bin {src => core/src}/main/resources/LTTRA.mp3 | Bin {src => core/src}/main/resources/LTTRB.mp3 | Bin {src => core/src}/main/resources/LTTRC.mp3 | Bin {src => core/src}/main/resources/LTTRD.mp3 | Bin {src => core/src}/main/resources/LTTRE.mp3 | Bin {src => core/src}/main/resources/LTTRF.mp3 | Bin {src => core/src}/main/resources/LTTRG.mp3 | Bin {src => core/src}/main/resources/LTTRH.mp3 | Bin {src => core/src}/main/resources/LTTRI.mp3 | Bin {src => core/src}/main/resources/LTTRJ.mp3 | Bin {src => core/src}/main/resources/LTTRK.mp3 | Bin {src => core/src}/main/resources/LTTRL.mp3 | Bin {src => core/src}/main/resources/LTTRM.mp3 | Bin .../src}/main/resources/LTTRMINUS.mp3 | Bin {src => core/src}/main/resources/LTTRN.mp3 | Bin {src => core/src}/main/resources/LTTRO.mp3 | Bin {src => core/src}/main/resources/LTTRP.mp3 | Bin .../src}/main/resources/LTTRPOINT.mp3 | Bin {src => core/src}/main/resources/LTTRQ.mp3 | Bin .../src}/main/resources/LTTRQUESTMARK.mp3 | Bin {src => core/src}/main/resources/LTTRR.mp3 | Bin {src => core/src}/main/resources/LTTRS.mp3 | Bin .../src}/main/resources/LTTRSPACE.mp3 | Bin .../src}/main/resources/LTTRSTROKE.mp3 | Bin {src => core/src}/main/resources/LTTRT.mp3 | Bin {src => core/src}/main/resources/LTTRU.mp3 | Bin {src => core/src}/main/resources/LTTRV.mp3 | Bin {src => core/src}/main/resources/LTTRW.mp3 | Bin {src => core/src}/main/resources/LTTRX.mp3 | Bin {src => core/src}/main/resources/LTTRY.mp3 | Bin {src => core/src}/main/resources/LTTRZ.mp3 | Bin .../src}/main/resources/NOISECQWINDOW.mp3 | Bin .../src}/main/resources/NOISEERROR.mp3 | Bin .../src}/main/resources/NOISENOTIFY.mp3 | Bin .../src}/main/resources/NOISEPMWINDOW.mp3 | Bin .../src}/main/resources/NOISESTARTUP.mp3 | Bin {src => core/src}/main/resources/VOICE0.mp3 | Bin {src => core/src}/main/resources/VOICE1.mp3 | Bin {src => core/src}/main/resources/VOICE2.mp3 | Bin {src => core/src}/main/resources/VOICE3.mp3 | Bin {src => core/src}/main/resources/VOICE4.mp3 | Bin {src => core/src}/main/resources/VOICE5.mp3 | Bin {src => core/src}/main/resources/VOICE6.mp3 | Bin {src => core/src}/main/resources/VOICE7.mp3 | Bin {src => core/src}/main/resources/VOICE73.mp3 | Bin {src => core/src}/main/resources/VOICE8.mp3 | Bin {src => core/src}/main/resources/VOICE9.mp3 | Bin {src => core/src}/main/resources/VOICEA.mp3 | Bin {src => core/src}/main/resources/VOICEB.mp3 | Bin .../src}/main/resources/VOICEBELL.mp3 | Bin {src => core/src}/main/resources/VOICEC.mp3 | Bin {src => core/src}/main/resources/VOICED.mp3 | Bin {src => core/src}/main/resources/VOICEE.mp3 | Bin {src => core/src}/main/resources/VOICEF.mp3 | Bin {src => core/src}/main/resources/VOICEG.mp3 | Bin {src => core/src}/main/resources/VOICEH.mp3 | Bin .../src}/main/resources/VOICEHELLO.mp3 | Bin {src => core/src}/main/resources/VOICEI.mp3 | Bin {src => core/src}/main/resources/VOICEJ.mp3 | Bin {src => core/src}/main/resources/VOICEK.mp3 | Bin {src => core/src}/main/resources/VOICEL.mp3 | Bin {src => core/src}/main/resources/VOICEM.mp3 | Bin .../src}/main/resources/VOICEMEEPMEEP.mp3 | Bin {src => core/src}/main/resources/VOICEN.mp3 | Bin {src => core/src}/main/resources/VOICEO.mp3 | Bin {src => core/src}/main/resources/VOICEP.mp3 | Bin {src => core/src}/main/resources/VOICEQ.mp3 | Bin {src => core/src}/main/resources/VOICER.mp3 | Bin {src => core/src}/main/resources/VOICES.mp3 | Bin .../src}/main/resources/VOICESTROKE.mp3 | Bin .../main/resources/VOICESTROKEPORTABLE.mp3 | Bin {src => core/src}/main/resources/VOICET.mp3 | Bin {src => core/src}/main/resources/VOICEU.mp3 | Bin {src => core/src}/main/resources/VOICEV.mp3 | Bin {src => core/src}/main/resources/VOICEW.mp3 | Bin {src => core/src}/main/resources/VOICEX.mp3 | Bin {src => core/src}/main/resources/VOICEY.mp3 | Bin .../src}/main/resources/VOICEYOUGOTMAIL.mp3 | Bin {src => core/src}/main/resources/VOICEZ.mp3 | Bin .../main/resources/icons/kst4contest.icns | Bin .../src}/main/resources/icons/kst4contest.ico | Bin .../src}/main/resources/icons/kst4contest.png | Bin {src => core/src}/main/resources/praktiKST.db | Bin .../main/resources/praktiKSTpreferences.old | 0 .../main/resources/praktiKSTpreferences.xml | 0 {src => core/src}/main/resources/sk.mp3 | Bin {src => core/src}/main/resources/tick.mp3 | Bin .../ChatControllerInitialWorkedStateTest.java | 0 .../ChatControllerSimpleLogTest.java | 0 .../controller/ChatMemberListViewTest.java | 164 + .../DBControllerProfileDatabaseTest.java | 127 + .../DXClusterSpotFormatterTest.java | 0 .../controller/ExternalLoggedQsoTest.java | 0 .../ExternalLoggerListenerValidationTest.java | 0 ...sManagementThreadDxClusterCommentTest.java | 4 +- ...ssageBusManagementThreadFrequencyTest.java | 0 .../MessageBusRawRxLoggingTest.java | 0 .../MessageHistoryRecorderTest.java | 0 .../controller/On4KstConnectionProbeTest.java | 0 .../On4KstHistoryIntegrationTest.java | 0 .../controller/On4KstIdlePracticeTest.java | 0 .../On4KstProbeVariantPracticeTest.java | 0 .../controller/On4KstProtocolLocaleTest.java | 84 + .../OperatorProfileManagementServiceTest.java | 177 + .../controller/OperatorProfilePathsTest.java | 109 + .../controller/OperatorProfileStoreTest.java | 117 + .../controller/ScoreServiceRefreshTest.java | 24 +- .../controller/UserActualizationTaskTest.java | 0 .../controller/WinTestIhaveInventoryTest.java | 0 .../controller/WinTestLogSyncServiceTest.java | 0 .../WinTestNetworkAddressResolverTest.java | 0 .../controller/WinTestPacketTest.java | 0 .../DirectionUtilsConsoleOutputTest.java | 0 .../model/ChatMemberFrequencyTest.java | 34 + .../model/ChatPreferencesLanguageTest.java | 33 + .../model/ChatPreferencesLocaleTest.java | 91 + .../model/ChatPreferencesObservableTest.java | 39 + .../model/ChatPreferencesPaletteTest.java | 46 + .../model/PaletteOverridesTest.java | 101 + .../kst4contest/model/PaletteRoleTest.java | 87 + .../observe/DirectUiDispatcherTest.java | 32 + .../kst4contest/observe/SimpleRosterTest.java | 168 + .../kst4contest/observe/SimpleValueTest.java | 86 + .../test/BandOpportunityResolverTest.java | 0 .../test/ChatPreferencesDebugModeTest.java | 0 .../ChatPreferencesLayoutPersistenceTest.java | 0 ...atPreferencesStationMapClusteringTest.java | 0 .../FrequencyTextParserRegressionTest.java | 0 .../MapCallsignRawSnapshotBuilderTest.java | 39 + .../kst4contest/test/PlatformUtilsTest.java | 24 + .../PropagationFrequencyResolverTest.java | 0 .../test/TestApplicationFileUtils.java | 0 .../kst4contest/test/TestChatPreferences.java | 0 .../kst4contest/test/TestDBController.java | 0 .../kst4contest/test/TestLocatorUtils.java | 0 .../test/TestReadUDPASListenerThread.java | 0 .../test/TestReadUDPUCXListenerThread.java | 0 .../test/TestUCXLogFileToHashsetParser.java | 0 .../test/UDPAirScoutSendMessages.java | 0 .../kst4contest/test/testTimeGeneration.java | 0 .../utils/ApplicationFileLoggingTest.java | 0 .../view/map/MapMarkerClusterTooltipTest.java | 80 + .../kst4contest/view/map/MapViewportTest.java | 206 + .../view/map/StationMapClustererTest.java | 206 + .../view/map/StationMapStatusTextTest.java | 150 + .../kst4contest/view/map/TileFetcherTest.java | 279 + docs/CONCEPT_IN_APP_UPDATE.md | 306 + docs/PROJECT_CONTEXT.md | 127 +- .../notes/2026-10-01-javafx-lebendbefund.md | 670 + .../superpowers/notes/javafx-compose-sweep.py | 128 + .../2026-09-25-compose-migration-design.md | 490 + .../2026-10-01-javafx-entfernen-design.md | 286 + .../2026-10-04-farben-anpassbar-design.md | 240 + .../2026-10-04-mehrsprachigkeit-design.md | 301 + github_docs/de-Benutzeroberflaeche.md | 5 +- github_docs/de-Changelog.md | 41 + github_docs/de-Funktionen.md | 152 +- github_docs/de-Konfiguration.md | 59 +- github_docs/en-Changelog.md | 41 + github_docs/en-Configuration.md | 59 +- github_docs/en-Features.md | 149 +- github_docs/en-User-Interface.md | 5 +- gradle.properties | 8 + gradle/libs.versions.toml | 29 + gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 47505 bytes gradle/wrapper/gradle-wrapper.properties | 9 + gradlew | 248 + gradlew.bat | 82 + i18n-generator/build.gradle.kts | 17 + .../kotlin/kst4contest/i18n/GeneratorMain.kt | 184 + .../kotlin/kst4contest/i18n/StringsSource.kt | 121 + .../kst4contest/i18n/TranslationFiles.kt | 95 + .../kst4contest/i18n/TranslationRules.kt | 82 + .../kotlin/kst4contest/i18n/GenerationTest.kt | 197 + .../kst4contest/i18n/StringsSourceTest.kt | 126 + .../kst4contest/i18n/TranslationFilesTest.kt | 105 + .../kst4contest/i18n/TranslationRulesTest.kt | 134 + jstack_dump.txt | 198 + mvnw | 308 - mvnw.cmd | 205 - packaging/AddModules.java | 128 - packaging/aur/kst4contest-git/PKGBUILD | 27 +- packaging/aur/kst4contest/PKGBUILD | 38 +- packaging/icons/generate-icons.sh | 90 + packaging/macos/build-signed-dmg.sh | 142 +- packaging/macos/dmg/background.tiff | Bin 0 -> 761748 bytes packaging/macos/dmg/render-background.swift | 131 + pom.xml | 510 - scratch/AAA01.png | Bin 0 -> 621654 bytes scratch/AAA02.png | Bin 0 -> 853603 bytes scratch/AAA03.png | Bin 0 -> 819084 bytes scratch/AAA04.png | Bin 0 -> 631922 bytes scratch/FilterBarRewrite.kt | 207 + scratch/UpdateFilterBar.py | 182 + settings.gradle.kts | 13 + .../utils/BoundedDequeObservableList.java | 168 - .../utils/TestAudioPlayerUtils.java | 19 - .../view/Kst4ContestApplication.java | 13205 ---------------- .../java/kst4contest/view/LayoutAutosave.java | 50 - .../view/MessageTextTableCell.java | 327 - .../kst4contest/view/TableLayoutManager.java | 280 - .../java/kst4contest/view/TimelineView.java | 376 - .../view/TruncatedTextTableCell.java | 109 - .../view/map/MapHtmlResources.java | 1295 -- .../view/map/PathProfileChart.java | 1162 -- .../view/map/StationMapBridge.java | 481 - .../map/StationMapPerformanceSupport.java | 96 - .../kst4contest/view/map/StationMapView.java | 1822 --- .../kst4contest/view/map/TileProxyServer.java | 159 - src/main/java/module-info.java | 24 - src/main/resources/leaflet-1.9.4.css | 661 - src/main/resources/leaflet-1.9.4.js | 6 - src/main/resources/web/leaflet/leaflet.css | 663 - src/main/resources/web/leaflet/leaflet.js | 6 - .../test/MapHtmlResourcesContractTest.java | 110 - .../map/StationMapPerformanceSupportTest.java | 122 - 600 files changed, 46019 insertions(+), 23704 deletions(-) create mode 100644 .github/workflows/test-publish-version-xml.yml delete mode 100644 .mvn/wrapper/maven-wrapper.jar delete mode 100644 .mvn/wrapper/maven-wrapper.properties delete mode 100644 0001-Document-v1.43-and-fix-release-metadata.patch create mode 100644 CLAUDE.md create mode 100644 app-desktop/build.gradle.kts create mode 100644 app-desktop/src/main/i18n/strings_de.properties create mode 100644 app-desktop/src/main/i18n/strings_en.properties rename {src => app-desktop/src}/main/java/kst4contest/controller/AppRunner.java (100%) rename {src => app-desktop/src}/main/java/kst4contest/test/ChatPreferencesStationMapVisibilityTest.java (100%) rename {src => app-desktop/src}/main/java/kst4contest/test/FrequencyTextParserTest.java (100%) rename {src => app-desktop/src}/main/java/kst4contest/test/PatternMatcherTest.java (84%) rename {src => app-desktop/src}/main/java/kst4contest/test/Utils4KSTFrequencyTest.java (92%) create mode 100644 app-desktop/src/main/java/kst4contest/view/ApplicationRuntimeLauncher.java create mode 100644 app-desktop/src/main/java/kst4contest/view/AwtUiDispatcher.java create mode 100644 app-desktop/src/main/java/kst4contest/view/CoalescingTrigger.java create mode 100644 app-desktop/src/main/java/kst4contest/view/CommandLineOptions.java create mode 100644 app-desktop/src/main/java/kst4contest/view/ComposeChatInputActions.java create mode 100644 app-desktop/src/main/java/kst4contest/view/ComposeMenuActions.java create mode 100644 app-desktop/src/main/java/kst4contest/view/ExternalDocuments.java rename {src => app-desktop/src}/main/java/kst4contest/view/GuiUtils.java (53%) create mode 100644 app-desktop/src/main/java/kst4contest/view/Kst4ContestApplication.java create mode 100644 app-desktop/src/main/java/kst4contest/view/LayoutAutosave.java rename {src => app-desktop/src}/main/java/kst4contest/view/Main.java (100%) create mode 100644 app-desktop/src/main/java/kst4contest/view/OperatorProfileBootstrap.java create mode 100644 app-desktop/src/main/java/kst4contest/view/OperatorProfileChoiceRequester.java rename {src => app-desktop/src}/main/java/kst4contest/view/PrivateMessageRowStyleResolver.java (100%) create mode 100644 app-desktop/src/main/java/kst4contest/view/RosterListBinding.java create mode 100644 app-desktop/src/main/java/kst4contest/view/ScreenBounds.java create mode 100644 app-desktop/src/main/java/kst4contest/view/TableLayoutManager.java rename {src => app-desktop/src}/main/java/kst4contest/view/TruncatedTextTooltipSupport.java (100%) create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/BuildInfo.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/AirplaneCell.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/ChatInputRow.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/ChatInputState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/ComposeAlert.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/ComposeWindowHost.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/ConnectionBar.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/ContrastRule.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/DataTable.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/DataTableState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/DataTableView.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/Density.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/DirectedMessageColumns.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/DirectedMessageRowStyle.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/FormControls.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/JavaFxStylesheet.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuBar.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuModel.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuRowState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindow.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindowFrame.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindowHost.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindowState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/MessageFormats.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/MessageTabs.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/MonitorColumns.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/MonitorWindow.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/ObservedValue.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/OperatorProfilePickerWindow.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/PaletteResolution.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/PaletteStore.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/PaletteStoreFactory.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/PublicMessageColumns.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/SelectedStationMessageColumns.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/SelectedStationPanel.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/SelectedStationState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/SettingsTabs.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/SettingsWindow.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/SnippetContextMenu.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/SplitterPane.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/SplitterState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/StationColumns.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/StationFilterBar.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/StationFilterState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/StationRowStyle.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/StatusBar.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/StatusIndicatorState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/Theme.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/TimelineState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/TimelineView.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/TopPriorityCandidatesWindow.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/TopPriorityState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/UpdateWindow.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/UpdateWindowState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/WindowShortcuts.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/map/ComposeStationMap.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/map/MapOverlayControls.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/map/PathAnalysisDetails.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/map/PathProfileChart.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/map/StationMapWindow.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/map/TileBitmapCache.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/AirscoutTab.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/AirscoutTabState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/BeaconTab.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/BeaconTabState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ColourShortcuts.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ColoursTab.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ColoursTabState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ExternalInterfaceFields.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/GuiOptionsTab.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/GuiOptionsTabState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/LogSynchTab.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/LogSynchTabState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTab.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTabState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/NotificationTab.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/NotificationTabState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ProfilesTab.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ProfilesTabState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ShortcutsTab.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ShortcutsTabState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/StationTab.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/StationTabState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/StylesheetExport.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/TrxSynchTab.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/TrxSynchTabState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/WorkedDatabaseTab.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/WorkedDatabaseTabState.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/feed/ConnectionStateFeed.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/feed/SelectedStationMessagesFeed.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/feed/TimelineFeed.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/i18n/LanguageStore.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/i18n/LanguageStoreFactory.kt create mode 100644 app-desktop/src/main/kotlin/kst4contest/view/i18n/LocaleChoice.kt rename {src => app-desktop/src}/main/resources/KST4ContestDefaultDay.css (97%) rename {src => app-desktop/src}/main/resources/KST4ContestDefaultEvening.css (98%) rename {src/main => app-desktop/src/test}/java/kst4contest/test/MessageVariableResolverTest.java (90%) rename {src => app-desktop/src}/test/java/kst4contest/test/PrivateMessageRowStyleResolverTest.java (100%) create mode 100644 app-desktop/src/test/java/kst4contest/view/AwtUiDispatcherTest.java create mode 100644 app-desktop/src/test/java/kst4contest/view/CoalescingTriggerTest.java create mode 100644 app-desktop/src/test/java/kst4contest/view/CommandLineOptionsTest.java create mode 100644 app-desktop/src/test/java/kst4contest/view/ComposeMainWindowOptionTest.java create mode 100644 app-desktop/src/test/java/kst4contest/view/ExternalDocumentsTest.java create mode 100644 app-desktop/src/test/java/kst4contest/view/LayoutAutosaveTest.java create mode 100644 app-desktop/src/test/java/kst4contest/view/MacOsConnectionStateMenuTitleTest.java create mode 100644 app-desktop/src/test/java/kst4contest/view/OperatorProfileBootstrapTest.java create mode 100644 app-desktop/src/test/java/kst4contest/view/RosterListBindingTest.java create mode 100644 app-desktop/src/test/java/kst4contest/view/ScreenBoundsTest.java rename {src => app-desktop/src}/test/java/kst4contest/view/TableLayoutManagerTest.java (100%) rename {src => app-desktop/src}/test/java/kst4contest/view/TruncatedTextTableCellTest.java (100%) create mode 100644 app-desktop/src/test/java/kst4contest/view/map/TerrainProfileCacheRepositoryTest.java create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/BuildInfoTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/StartupStylesheetCopyTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/AirplaneCellTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/ChatInputStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/ComposeAlertTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/ComposeWindowHostCloseTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/ComposeWindowHostRaiseTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/ContrastRuleTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/DataTableStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/DirectedMessageColumnsTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/DirectedMessageRowStyleTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/DrawingLayerRegressionTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/EditableListStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/JavaFxStylesheetTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/MainMenuModelTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/MainMenuRowStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/MainMenuStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/MainWindowFrameTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/MainWindowStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/MonitorColumnsTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/ObservedValueTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/OperatorProfilePickerStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/OperatorProfilePickerWindowTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/PaletteResolutionTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/PaletteStoreFactoryTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/PaletteStoreTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/PublicMessageColumnsTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/SelectedStationStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/SettingsFieldCoverageTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/SettingsForeignWriteCoverageTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/SplitterStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/StationColumnsTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/StationFilterStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/StatusIndicatorStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/StylesheetDeclaredRolesTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/ThemeReadsPaletteStoreTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/TimelineCandidateFieldsTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/TimelineStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/TopPriorityCandidatesWindowTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/TopPriorityStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/TypographyScalingTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/UpdateWindowStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/WindowShortcutsTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/map/ComposeStationMapDrawingTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/map/ComposeStationMapLayoutTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/map/PathAnalysisDetailsLayoutTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/map/PathAnalysisDetailsWidthTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/map/PathProfileChartLayoutTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/map/StationMapBodyLayoutTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/map/TileBitmapCacheTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/map/TileKeyTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/AirscoutTabStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/BeaconTabStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ColourShortcutsTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ColoursTabStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/GuiOptionsTabStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/LifelineColoursTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/LogSynchTabStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/MessageHandlingTabStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/NotificationTabStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ProfilesTabStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ShortcutsTabStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/StationTabStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/StylesheetExportTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/TrxSynchTabStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/WorkedDatabaseTabStateTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/feed/ConnectionStateFeedTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/feed/FeedIsTheOnlyWriterTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/feed/FeedLifetimeIsTiedToTheWindowTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/feed/SelectedStationMessagesFeedTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/feed/TimelineFeedTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/i18n/LanguageStoreTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/i18n/LocaleChoiceTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/i18n/StringsReachTheCompositionTest.kt create mode 100644 app-desktop/src/test/kotlin/kst4contest/view/i18n/TranslationBoundaryTest.kt create mode 100644 app-desktop/src/test/resources/javafx-derive-reference.txt create mode 100644 app-desktop/src/test/resources/settings-fields.txt create mode 100644 app-desktop/src/test/resources/settings-foreign-writes.txt create mode 100644 build.gradle.kts create mode 100644 core/build.gradle.kts rename {src => core/src}/main/java/kst4contest/ApplicationConstants.java (99%) create mode 100644 core/src/main/java/kst4contest/controller/ActiveOperatorProfile.java rename {src => core/src}/main/java/kst4contest/controller/AirScoutPeriodicalAPReflectionInquirerTask.java (100%) rename {src => core/src}/main/java/kst4contest/controller/BeaconTask.java (100%) rename {src => core/src}/main/java/kst4contest/controller/ChatController.java (88%) create mode 100644 core/src/main/java/kst4contest/controller/ChatMemberListView.java rename {src => core/src}/main/java/kst4contest/controller/DBController.java (90%) rename {src => core/src}/main/java/kst4contest/controller/DXClusterController.java (98%) rename {src => core/src}/main/java/kst4contest/controller/DXClusterSpotFormatter.java (100%) rename {src => core/src}/main/java/kst4contest/controller/DXClusterThreadPooledServer.java (96%) rename {src => core/src}/main/java/kst4contest/controller/ExternalLoggedQso.java (100%) rename {src => core/src}/main/java/kst4contest/controller/InputReaderThread.java (100%) rename {src => core/src}/main/java/kst4contest/controller/LoggedQsoBand.java (100%) rename {src => core/src}/main/java/kst4contest/controller/MessageBusManagementThread.java (99%) rename {src => core/src}/main/java/kst4contest/controller/MessageBusManagementThreadFrequencyContextTest.java (100%) rename {src => core/src}/main/java/kst4contest/controller/MessageHistoryRecorder.java (100%) rename {src => core/src}/main/java/kst4contest/controller/MessageVariableResolver.java (97%) rename {src => core/src}/main/java/kst4contest/controller/On4KstConnectionManager.java (98%) rename {src => core/src}/main/java/kst4contest/controller/On4KstConnectionState.java (100%) rename {src => core/src}/main/java/kst4contest/controller/On4KstProtocol.java (100%) rename {src => core/src}/main/java/kst4contest/controller/On4KstProtocolTest.java (100%) rename {src => core/src}/main/java/kst4contest/controller/On4KstSocketThreadTest.java (100%) create mode 100644 core/src/main/java/kst4contest/controller/OperatorProfileManagementService.java create mode 100644 core/src/main/java/kst4contest/controller/OperatorProfilePaths.java create mode 100644 core/src/main/java/kst4contest/controller/OperatorProfileStore.java rename {src => core/src}/main/java/kst4contest/controller/PstRotatorClient.java (100%) rename {src => core/src}/main/java/kst4contest/controller/ReachabilityService.java (98%) rename {src => core/src}/main/java/kst4contest/controller/ReadThread.java (100%) rename {src => core/src}/main/java/kst4contest/controller/ReadUDPByWintestThread.java (99%) rename {src => core/src}/main/java/kst4contest/controller/ReadUDPByWintestThreadTest.java (100%) rename {src => core/src}/main/java/kst4contest/controller/ReadUDPbyAirScoutMessageThread.java (98%) rename {src => core/src}/main/java/kst4contest/controller/ReadUDPbyUCXMessageThread.java (99%) rename {src => core/src}/main/java/kst4contest/controller/RegexTester.java (100%) rename {src => core/src}/main/java/kst4contest/controller/ScoreService.java (88%) rename {src => core/src}/main/java/kst4contest/controller/ScoreboardUpdateTask.java (100%) rename {src => core/src}/main/java/kst4contest/controller/SkedReminderService.java (88%) rename {src => core/src}/main/java/kst4contest/controller/StartChat.java (84%) rename {src => core/src}/main/java/kst4contest/controller/StationMetricsService.java (100%) rename {src => core/src}/main/java/kst4contest/controller/StatusUpdateListener.java (100%) rename {src => core/src}/main/java/kst4contest/controller/ThreadStatusCallback.java (100%) rename {src => core/src}/main/java/kst4contest/controller/UCXLogFileToHashsetParser.java (100%) rename {src => core/src}/main/java/kst4contest/controller/UpdateChecker.java (100%) rename {src => core/src}/main/java/kst4contest/controller/UserActualizationTask.java (100%) rename {src => core/src}/main/java/kst4contest/controller/Utils4KST.java (98%) rename {src => core/src}/main/java/kst4contest/controller/WinTestIhaveInventory.java (100%) rename {src => core/src}/main/java/kst4contest/controller/WinTestLogSegment.java (100%) rename {src => core/src}/main/java/kst4contest/controller/WinTestLogSyncService.java (100%) rename {src => core/src}/main/java/kst4contest/controller/WinTestMessage.java (100%) rename {src => core/src}/main/java/kst4contest/controller/WinTestNetworkAddressResolver.java (100%) rename {src => core/src}/main/java/kst4contest/controller/WinTestPacket.java (100%) rename {src => core/src}/main/java/kst4contest/controller/WinTestSkedSender.java (100%) rename {src => core/src}/main/java/kst4contest/controller/WorkedGrossFieldCache.java (100%) rename {src => core/src}/main/java/kst4contest/controller/WriteThread.java (100%) rename {src => core/src}/main/java/kst4contest/controller/interfaces/PstRotatorEventListener.java (100%) rename {src => core/src}/main/java/kst4contest/controller/keepAliveMessageSenderTask.java (100%) rename {src => core/src}/main/java/kst4contest/locatorUtils/Angle.java (100%) rename {src => core/src}/main/java/kst4contest/locatorUtils/DirectionUtils.java (100%) rename {src => core/src}/main/java/kst4contest/locatorUtils/Latitude.java (100%) rename {src => core/src}/main/java/kst4contest/locatorUtils/Location.java (100%) rename {src => core/src}/main/java/kst4contest/locatorUtils/Longitude.java (100%) rename {src => core/src}/main/java/kst4contest/locatorUtils/TestLocatorUtils.java (100%) rename {src => core/src}/main/java/kst4contest/logic/BandOpportunityResolver.java (100%) rename {src => core/src}/main/java/kst4contest/logic/FrequencyTextParser.java (100%) rename {src => core/src}/main/java/kst4contest/logic/PriorityCalculator.java (99%) rename {src => core/src}/main/java/kst4contest/logic/PropagationFrequencyResolver.java (100%) rename {src => core/src}/main/java/kst4contest/logic/SignalDetector.java (100%) rename {src => core/src}/main/java/kst4contest/model/AirPlane.java (100%) rename {src => core/src}/main/java/kst4contest/model/AirPlaneReflectionInfo.java (83%) rename {src => core/src}/main/java/kst4contest/model/Band.java (100%) rename {src => core/src}/main/java/kst4contest/model/ChatCategory.java (100%) rename {src => core/src}/main/java/kst4contest/model/ChatMember.java (96%) rename {src => core/src}/main/java/kst4contest/model/ChatMemberDirectionOpportunityTest.java (100%) rename {src => core/src}/main/java/kst4contest/model/ChatMessage.java (100%) rename {src => core/src}/main/java/kst4contest/model/ChatPreferences.java (93%) rename {src => core/src}/main/java/kst4contest/model/ClusterMessage.java (100%) rename {src => core/src}/main/java/kst4contest/model/ContestSked.java (100%) create mode 100644 core/src/main/java/kst4contest/model/OperatorProfile.java create mode 100644 core/src/main/java/kst4contest/model/OperatorProfileSelection.java create mode 100644 core/src/main/java/kst4contest/model/PaletteOverrides.java create mode 100644 core/src/main/java/kst4contest/model/PaletteRole.java rename {src => core/src}/main/java/kst4contest/model/ThreadStateMessage.java (100%) rename {src => core/src}/main/java/kst4contest/model/UpdateInformation.java (100%) create mode 100644 core/src/main/java/kst4contest/observe/DirectUiDispatcher.java create mode 100644 core/src/main/java/kst4contest/observe/MutableValue.java create mode 100644 core/src/main/java/kst4contest/observe/ObservableRoster.java create mode 100644 core/src/main/java/kst4contest/observe/ObservableValue.java create mode 100644 core/src/main/java/kst4contest/observe/SimpleRoster.java create mode 100644 core/src/main/java/kst4contest/observe/SimpleValue.java create mode 100644 core/src/main/java/kst4contest/observe/UiDispatcher.java rename {src => core/src}/main/java/kst4contest/service/path/FresnelMathUtils.java (100%) rename {src => core/src}/main/java/kst4contest/test/MockKstServer.java (100%) rename {src => core/src}/main/java/kst4contest/utils/ApplicationFileLogging.java (100%) rename {src => core/src}/main/java/kst4contest/utils/ApplicationFileUtils.java (100%) create mode 100644 core/src/main/java/kst4contest/utils/PlatformUtils.java rename {src => core/src}/main/java/kst4contest/utils/PlayAudioUtils.java (100%) rename {src => core/src}/main/java/kst4contest/utils/VersionUtils.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/ChainedTerrainProfileProvider.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/CopernicusGlo30TerrainProfileProvider.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/DemDataset.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/FallbackTerrainProfileProvider.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/GeometryOnlyPathAnalysisService.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/MaidenheadGridRenderPlanner.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/MaidenheadGridUtils.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/MapCallsignRawSnapshot.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/MapCallsignRawSnapshotBuilder.java (96%) create mode 100644 core/src/main/java/kst4contest/view/map/MapMarkerCluster.java create mode 100644 core/src/main/java/kst4contest/view/map/MapMarkerClusterTooltip.java create mode 100644 core/src/main/java/kst4contest/view/map/MapViewport.java rename {src => core/src}/main/java/kst4contest/view/map/NoOpTerrainProfileProvider.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/OfflineDemImportService.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/OfflineDemManager.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/OfflineDemTerrainProfileProvider.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/OpenMeteoTerrainProfileProvider.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/PathAnalysisRequest.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/PathAnalysisResult.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/PathAnalysisService.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/PathGeometryUtils.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/PathHorizonSummary.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/PathLinkBudgetSettings.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/PathLinkBudgetSummary.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/PathObstructionSummary.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/PathProfilePoint.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/PathPropagationAssessment.java (100%) create mode 100644 core/src/main/java/kst4contest/view/map/StationMapClusterer.java create mode 100644 core/src/main/java/kst4contest/view/map/StationMapStatusText.java rename {src => core/src}/main/java/kst4contest/view/map/SyntheticTerrainProfileProvider.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/TerrainCatalog.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/TerrainCatalogClient.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/TerrainCatalogPackageEntry.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/TerrainCoverageResolver.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/TerrainPackageDownloader.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/TerrainPackageInstaller.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/TerrainPackageManifest.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/TerrainPackageService.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/TerrainProfileCacheRepository.java (78%) rename {src => core/src}/main/java/kst4contest/view/map/TerrainProfileData.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/TerrainProfileProvider.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/TerrainProfileRequest.java (100%) rename {src => core/src}/main/java/kst4contest/view/map/TerrainTileMetadata.java (100%) create mode 100644 core/src/main/java/kst4contest/view/map/TileFetcher.java create mode 100644 core/src/main/java/kst4contest/view/map/WebMercatorProjection.java rename {src => core/src}/main/java/kst4contest/view/map/mapTest.java (100%) rename {src => core/src}/main/resources/LTTR0.mp3 (100%) rename {src => core/src}/main/resources/LTTR1.mp3 (100%) rename {src => core/src}/main/resources/LTTR2.mp3 (100%) rename {src => core/src}/main/resources/LTTR3.mp3 (100%) rename {src => core/src}/main/resources/LTTR4.mp3 (100%) rename {src => core/src}/main/resources/LTTR5.mp3 (100%) rename {src => core/src}/main/resources/LTTR6.mp3 (100%) rename {src => core/src}/main/resources/LTTR7.mp3 (100%) rename {src => core/src}/main/resources/LTTR8.mp3 (100%) rename {src => core/src}/main/resources/LTTR9.mp3 (100%) rename {src => core/src}/main/resources/LTTRA.mp3 (100%) rename {src => core/src}/main/resources/LTTRB.mp3 (100%) rename {src => core/src}/main/resources/LTTRC.mp3 (100%) rename {src => core/src}/main/resources/LTTRD.mp3 (100%) rename {src => core/src}/main/resources/LTTRE.mp3 (100%) rename {src => core/src}/main/resources/LTTRF.mp3 (100%) rename {src => core/src}/main/resources/LTTRG.mp3 (100%) rename {src => core/src}/main/resources/LTTRH.mp3 (100%) rename {src => core/src}/main/resources/LTTRI.mp3 (100%) rename {src => core/src}/main/resources/LTTRJ.mp3 (100%) rename {src => core/src}/main/resources/LTTRK.mp3 (100%) rename {src => core/src}/main/resources/LTTRL.mp3 (100%) rename {src => core/src}/main/resources/LTTRM.mp3 (100%) rename {src => core/src}/main/resources/LTTRMINUS.mp3 (100%) rename {src => core/src}/main/resources/LTTRN.mp3 (100%) rename {src => core/src}/main/resources/LTTRO.mp3 (100%) rename {src => core/src}/main/resources/LTTRP.mp3 (100%) rename {src => core/src}/main/resources/LTTRPOINT.mp3 (100%) rename {src => core/src}/main/resources/LTTRQ.mp3 (100%) rename {src => core/src}/main/resources/LTTRQUESTMARK.mp3 (100%) rename {src => core/src}/main/resources/LTTRR.mp3 (100%) rename {src => core/src}/main/resources/LTTRS.mp3 (100%) rename {src => core/src}/main/resources/LTTRSPACE.mp3 (100%) rename {src => core/src}/main/resources/LTTRSTROKE.mp3 (100%) rename {src => core/src}/main/resources/LTTRT.mp3 (100%) rename {src => core/src}/main/resources/LTTRU.mp3 (100%) rename {src => core/src}/main/resources/LTTRV.mp3 (100%) rename {src => core/src}/main/resources/LTTRW.mp3 (100%) rename {src => core/src}/main/resources/LTTRX.mp3 (100%) rename {src => core/src}/main/resources/LTTRY.mp3 (100%) rename {src => core/src}/main/resources/LTTRZ.mp3 (100%) rename {src => core/src}/main/resources/NOISECQWINDOW.mp3 (100%) rename {src => core/src}/main/resources/NOISEERROR.mp3 (100%) rename {src => core/src}/main/resources/NOISENOTIFY.mp3 (100%) rename {src => core/src}/main/resources/NOISEPMWINDOW.mp3 (100%) rename {src => core/src}/main/resources/NOISESTARTUP.mp3 (100%) rename {src => core/src}/main/resources/VOICE0.mp3 (100%) rename {src => core/src}/main/resources/VOICE1.mp3 (100%) rename {src => core/src}/main/resources/VOICE2.mp3 (100%) rename {src => core/src}/main/resources/VOICE3.mp3 (100%) rename {src => core/src}/main/resources/VOICE4.mp3 (100%) rename {src => core/src}/main/resources/VOICE5.mp3 (100%) rename {src => core/src}/main/resources/VOICE6.mp3 (100%) rename {src => core/src}/main/resources/VOICE7.mp3 (100%) rename {src => core/src}/main/resources/VOICE73.mp3 (100%) rename {src => core/src}/main/resources/VOICE8.mp3 (100%) rename {src => core/src}/main/resources/VOICE9.mp3 (100%) rename {src => core/src}/main/resources/VOICEA.mp3 (100%) rename {src => core/src}/main/resources/VOICEB.mp3 (100%) rename {src => core/src}/main/resources/VOICEBELL.mp3 (100%) rename {src => core/src}/main/resources/VOICEC.mp3 (100%) rename {src => core/src}/main/resources/VOICED.mp3 (100%) rename {src => core/src}/main/resources/VOICEE.mp3 (100%) rename {src => core/src}/main/resources/VOICEF.mp3 (100%) rename {src => core/src}/main/resources/VOICEG.mp3 (100%) rename {src => core/src}/main/resources/VOICEH.mp3 (100%) rename {src => core/src}/main/resources/VOICEHELLO.mp3 (100%) rename {src => core/src}/main/resources/VOICEI.mp3 (100%) rename {src => core/src}/main/resources/VOICEJ.mp3 (100%) rename {src => core/src}/main/resources/VOICEK.mp3 (100%) rename {src => core/src}/main/resources/VOICEL.mp3 (100%) rename {src => core/src}/main/resources/VOICEM.mp3 (100%) rename {src => core/src}/main/resources/VOICEMEEPMEEP.mp3 (100%) rename {src => core/src}/main/resources/VOICEN.mp3 (100%) rename {src => core/src}/main/resources/VOICEO.mp3 (100%) rename {src => core/src}/main/resources/VOICEP.mp3 (100%) rename {src => core/src}/main/resources/VOICEQ.mp3 (100%) rename {src => core/src}/main/resources/VOICER.mp3 (100%) rename {src => core/src}/main/resources/VOICES.mp3 (100%) rename {src => core/src}/main/resources/VOICESTROKE.mp3 (100%) rename {src => core/src}/main/resources/VOICESTROKEPORTABLE.mp3 (100%) rename {src => core/src}/main/resources/VOICET.mp3 (100%) rename {src => core/src}/main/resources/VOICEU.mp3 (100%) rename {src => core/src}/main/resources/VOICEV.mp3 (100%) rename {src => core/src}/main/resources/VOICEW.mp3 (100%) rename {src => core/src}/main/resources/VOICEX.mp3 (100%) rename {src => core/src}/main/resources/VOICEY.mp3 (100%) rename {src => core/src}/main/resources/VOICEYOUGOTMAIL.mp3 (100%) rename {src => core/src}/main/resources/VOICEZ.mp3 (100%) rename {src => core/src}/main/resources/icons/kst4contest.icns (100%) rename {src => core/src}/main/resources/icons/kst4contest.ico (100%) rename {src => core/src}/main/resources/icons/kst4contest.png (100%) rename {src => core/src}/main/resources/praktiKST.db (100%) rename {src => core/src}/main/resources/praktiKSTpreferences.old (100%) rename {src => core/src}/main/resources/praktiKSTpreferences.xml (100%) rename {src => core/src}/main/resources/sk.mp3 (100%) rename {src => core/src}/main/resources/tick.mp3 (100%) rename {src => core/src}/test/java/kst4contest/controller/ChatControllerInitialWorkedStateTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/ChatControllerSimpleLogTest.java (100%) create mode 100644 core/src/test/java/kst4contest/controller/ChatMemberListViewTest.java create mode 100644 core/src/test/java/kst4contest/controller/DBControllerProfileDatabaseTest.java rename {src => core/src}/test/java/kst4contest/controller/DXClusterSpotFormatterTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/ExternalLoggedQsoTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/ExternalLoggerListenerValidationTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/MessageBusManagementThreadDxClusterCommentTest.java (94%) rename {src => core/src}/test/java/kst4contest/controller/MessageBusManagementThreadFrequencyTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/MessageBusRawRxLoggingTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/MessageHistoryRecorderTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/On4KstConnectionProbeTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/On4KstHistoryIntegrationTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/On4KstIdlePracticeTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/On4KstProbeVariantPracticeTest.java (100%) create mode 100644 core/src/test/java/kst4contest/controller/On4KstProtocolLocaleTest.java create mode 100644 core/src/test/java/kst4contest/controller/OperatorProfileManagementServiceTest.java create mode 100644 core/src/test/java/kst4contest/controller/OperatorProfilePathsTest.java create mode 100644 core/src/test/java/kst4contest/controller/OperatorProfileStoreTest.java rename {src => core/src}/test/java/kst4contest/controller/ScoreServiceRefreshTest.java (78%) rename {src => core/src}/test/java/kst4contest/controller/UserActualizationTaskTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/WinTestIhaveInventoryTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/WinTestLogSyncServiceTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/WinTestNetworkAddressResolverTest.java (100%) rename {src => core/src}/test/java/kst4contest/controller/WinTestPacketTest.java (100%) rename {src => core/src}/test/java/kst4contest/locatorUtils/DirectionUtilsConsoleOutputTest.java (100%) create mode 100644 core/src/test/java/kst4contest/model/ChatMemberFrequencyTest.java create mode 100644 core/src/test/java/kst4contest/model/ChatPreferencesLanguageTest.java create mode 100644 core/src/test/java/kst4contest/model/ChatPreferencesLocaleTest.java create mode 100644 core/src/test/java/kst4contest/model/ChatPreferencesObservableTest.java create mode 100644 core/src/test/java/kst4contest/model/ChatPreferencesPaletteTest.java create mode 100644 core/src/test/java/kst4contest/model/PaletteOverridesTest.java create mode 100644 core/src/test/java/kst4contest/model/PaletteRoleTest.java create mode 100644 core/src/test/java/kst4contest/observe/DirectUiDispatcherTest.java create mode 100644 core/src/test/java/kst4contest/observe/SimpleRosterTest.java create mode 100644 core/src/test/java/kst4contest/observe/SimpleValueTest.java rename {src => core/src}/test/java/kst4contest/test/BandOpportunityResolverTest.java (100%) rename {src => core/src}/test/java/kst4contest/test/ChatPreferencesDebugModeTest.java (100%) rename {src => core/src}/test/java/kst4contest/test/ChatPreferencesLayoutPersistenceTest.java (100%) rename {src => core/src}/test/java/kst4contest/test/ChatPreferencesStationMapClusteringTest.java (100%) rename {src => core/src}/test/java/kst4contest/test/FrequencyTextParserRegressionTest.java (100%) rename {src => core/src}/test/java/kst4contest/test/MapCallsignRawSnapshotBuilderTest.java (73%) create mode 100644 core/src/test/java/kst4contest/test/PlatformUtilsTest.java rename {src => core/src}/test/java/kst4contest/test/PropagationFrequencyResolverTest.java (100%) rename {src => core/src}/test/java/kst4contest/test/TestApplicationFileUtils.java (100%) rename {src => core/src}/test/java/kst4contest/test/TestChatPreferences.java (100%) rename {src => core/src}/test/java/kst4contest/test/TestDBController.java (100%) rename {src => core/src}/test/java/kst4contest/test/TestLocatorUtils.java (100%) rename {src => core/src}/test/java/kst4contest/test/TestReadUDPASListenerThread.java (100%) rename {src => core/src}/test/java/kst4contest/test/TestReadUDPUCXListenerThread.java (100%) rename {src => core/src}/test/java/kst4contest/test/TestUCXLogFileToHashsetParser.java (100%) rename {src => core/src}/test/java/kst4contest/test/UDPAirScoutSendMessages.java (100%) rename {src => core/src}/test/java/kst4contest/test/testTimeGeneration.java (100%) rename {src => core/src}/test/java/kst4contest/utils/ApplicationFileLoggingTest.java (100%) create mode 100644 core/src/test/java/kst4contest/view/map/MapMarkerClusterTooltipTest.java create mode 100644 core/src/test/java/kst4contest/view/map/MapViewportTest.java create mode 100644 core/src/test/java/kst4contest/view/map/StationMapClustererTest.java create mode 100644 core/src/test/java/kst4contest/view/map/StationMapStatusTextTest.java create mode 100644 core/src/test/java/kst4contest/view/map/TileFetcherTest.java create mode 100644 docs/CONCEPT_IN_APP_UPDATE.md create mode 100644 docs/superpowers/notes/2026-10-01-javafx-lebendbefund.md create mode 100644 docs/superpowers/notes/javafx-compose-sweep.py create mode 100644 docs/superpowers/specs/2026-09-25-compose-migration-design.md create mode 100644 docs/superpowers/specs/2026-10-01-javafx-entfernen-design.md create mode 100644 docs/superpowers/specs/2026-10-04-farben-anpassbar-design.md create mode 100644 docs/superpowers/specs/2026-10-04-mehrsprachigkeit-design.md create mode 100644 gradle.properties create mode 100644 gradle/libs.versions.toml 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 create mode 100644 i18n-generator/build.gradle.kts create mode 100644 i18n-generator/src/main/kotlin/kst4contest/i18n/GeneratorMain.kt create mode 100644 i18n-generator/src/main/kotlin/kst4contest/i18n/StringsSource.kt create mode 100644 i18n-generator/src/main/kotlin/kst4contest/i18n/TranslationFiles.kt create mode 100644 i18n-generator/src/main/kotlin/kst4contest/i18n/TranslationRules.kt create mode 100644 i18n-generator/src/test/kotlin/kst4contest/i18n/GenerationTest.kt create mode 100644 i18n-generator/src/test/kotlin/kst4contest/i18n/StringsSourceTest.kt create mode 100644 i18n-generator/src/test/kotlin/kst4contest/i18n/TranslationFilesTest.kt create mode 100644 i18n-generator/src/test/kotlin/kst4contest/i18n/TranslationRulesTest.kt create mode 100644 jstack_dump.txt delete mode 100755 mvnw delete mode 100644 mvnw.cmd delete mode 100644 packaging/AddModules.java create mode 100755 packaging/icons/generate-icons.sh create mode 100644 packaging/macos/dmg/background.tiff create mode 100644 packaging/macos/dmg/render-background.swift delete mode 100644 pom.xml create mode 100644 scratch/AAA01.png create mode 100644 scratch/AAA02.png create mode 100644 scratch/AAA03.png create mode 100644 scratch/AAA04.png create mode 100644 scratch/FilterBarRewrite.kt create mode 100644 scratch/UpdateFilterBar.py create mode 100644 settings.gradle.kts delete mode 100644 src/main/java/kst4contest/utils/BoundedDequeObservableList.java delete mode 100644 src/main/java/kst4contest/utils/TestAudioPlayerUtils.java delete mode 100644 src/main/java/kst4contest/view/Kst4ContestApplication.java delete mode 100644 src/main/java/kst4contest/view/LayoutAutosave.java delete mode 100644 src/main/java/kst4contest/view/MessageTextTableCell.java delete mode 100644 src/main/java/kst4contest/view/TableLayoutManager.java delete mode 100644 src/main/java/kst4contest/view/TimelineView.java delete mode 100644 src/main/java/kst4contest/view/TruncatedTextTableCell.java delete mode 100644 src/main/java/kst4contest/view/map/MapHtmlResources.java delete mode 100644 src/main/java/kst4contest/view/map/PathProfileChart.java delete mode 100644 src/main/java/kst4contest/view/map/StationMapBridge.java delete mode 100644 src/main/java/kst4contest/view/map/StationMapPerformanceSupport.java delete mode 100644 src/main/java/kst4contest/view/map/StationMapView.java delete mode 100644 src/main/java/kst4contest/view/map/TileProxyServer.java delete mode 100644 src/main/java/module-info.java delete mode 100644 src/main/resources/leaflet-1.9.4.css delete mode 100644 src/main/resources/leaflet-1.9.4.js delete mode 100644 src/main/resources/web/leaflet/leaflet.css delete mode 100644 src/main/resources/web/leaflet/leaflet.js delete mode 100644 src/test/java/kst4contest/test/MapHtmlResourcesContractTest.java delete mode 100644 src/test/java/kst4contest/view/map/StationMapPerformanceSupportTest.java diff --git a/.github/workflows/aur-nightly-git.yml b/.github/workflows/aur-nightly-git.yml index a27628f3..92d0947a 100644 --- a/.github/workflows/aur-nightly-git.yml +++ b/.github/workflows/aur-nightly-git.yml @@ -41,8 +41,8 @@ jobs: - name: Compute pkgver id: ver run: | - BASE=$(grep -m1 '' pom.xml \ - | sed 's/.*\(.*\)<\/version>.*/\1/' \ + BASE=$(grep -m1 '^version=' gradle.properties \ + | cut -d= -f2 \ | sed 's/[-.]nightly//') GIT_PKGVER="${BASE}.r$(git rev-list --count HEAD).g$(git rev-parse --short HEAD)" diff --git a/.github/workflows/aur-publish.yml b/.github/workflows/aur-publish.yml index e26aac00..fbea1440 100644 --- a/.github/workflows/aur-publish.yml +++ b/.github/workflows/aur-publish.yml @@ -107,9 +107,9 @@ jobs: sed -i "s/^pkgrel=.*/pkgrel=1/" packaging/aur/kst4contest-bin/PKGBUILD sed -i "s/^pkgrel=.*/pkgrel=1/" packaging/aur/kst4contest/PKGBUILD - # kst4contest-git: Basis aus pom.xml, Suffix aus git - BASE_VER=$(grep -m1 '' pom.xml \ - | sed 's/.*\(.*\)<\/version>.*/\1/' | sed 's/[-.]nightly//') + # kst4contest-git: Basis aus gradle.properties, Suffix aus git + BASE_VER=$(grep -m1 '^version=' gradle.properties \ + | cut -d= -f2 | sed 's/[-.]nightly//') GIT_PKGVER="${BASE_VER}.r$(git rev-list --count HEAD).g$(git rev-parse --short HEAD)" sed -i "s/^pkgver=.*/pkgver=${GIT_PKGVER}/" packaging/aur/kst4contest-git/PKGBUILD diff --git a/.github/workflows/docs-pdf.yml b/.github/workflows/docs-pdf.yml index aae3a02c..36ec1144 100644 --- a/.github/workflows/docs-pdf.yml +++ b/.github/workflows/docs-pdf.yml @@ -32,7 +32,7 @@ jobs: if [[ "${{ github.ref }}" == refs/tags/* ]]; then VERSION="${{ github.ref_name }}" else - VERSION="$(grep -m1 '' pom.xml | sed 's/.*\(.*\)<\/version>.*/\1/')-${GITHUB_SHA::7}" + VERSION="$(grep -m1 '^version=' gradle.properties | cut -d= -f2)-${GITHUB_SHA::7}" fi echo "DOC_VERSION=$VERSION" >> "$GITHUB_ENV" diff --git a/.github/workflows/nightly-artifacts.yml b/.github/workflows/nightly-artifacts.yml index 73fc3b06..a1b9ea74 100644 --- a/.github/workflows/nightly-artifacts.yml +++ b/.github/workflows/nightly-artifacts.yml @@ -5,12 +5,15 @@ on: branches: - main paths: - - "src/**" - "packaging/icons/**" - "packaging/macos/**" - - "pom.xml" - - "mvnw" - - "mvnw.cmd" + - "core/**" + - "app-desktop/**" + - "*.gradle.kts" + - "gradle.properties" + - "gradle/**" + - "gradlew" + - "gradlew.bat" - ".github/workflows/nightly-artifacts.yml" workflow_dispatch: @@ -33,8 +36,7 @@ jobs: - name: Resolve nightly version info shell: pwsh run: | - $xml = [xml](Get-Content pom.xml) - $version = $xml.project.version + $version = (Select-String -Path gradle.properties -Pattern '^version=').Line.Split('=')[1] $shortSha = "${{ github.sha }}".Substring(0, 7) Add-Content -Path $env:GITHUB_ENV -Value "VERSION=$version" Add-Content -Path $env:GITHUB_ENV -Value "SHORT_SHA=$shortSha" @@ -50,40 +52,23 @@ jobs: shell: pwsh run: choco install wixtoolset --no-progress -y - - name: Build JAR and copy runtime dependencies - shell: pwsh - run: | - .\mvnw.cmd -B -DskipTests package dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/dist-libs - $jar = Get-ChildItem -Path target -Filter 'praktiKST-*.jar' | Sort-Object LastWriteTime -Descending | Select-Object -First 1 - if (-not $jar) { - throw "No project JAR produced" - } - Copy-Item $jar.FullName target/dist-libs/app.jar - - - name: Build app-image with jpackage + - name: Build app-image shell: pwsh run: | + .\gradlew.bat -S :app-desktop:createDistributable New-Item -ItemType Directory -Force -Path dist | Out-Null - $addModules = & java packaging/AddModules.java - if ($LASTEXITCODE -ne 0) { throw "Failed to resolve --add-modules from module-info.java" } - jpackage ` - --type app-image ` - --name praktiKST ` - --icon packaging/icons/kst4contest.ico ` - --input target/dist-libs ` - --main-jar app.jar ` - --main-class kst4contest.view.Kst4ContestApplication ` - --module-path target/dist-libs ` - --add-modules $addModules ` - --dest dist + # The next step reads dist/KST4Contest, so the Compose output goes + # there. The module list now lives in app-desktop/build.gradle.kts. + if (Test-Path dist/KST4Contest) { Remove-Item -Recurse -Force dist/KST4Contest } + Copy-Item -Recurse app-desktop/build/compose/binaries/main/app/KST4Contest dist/KST4Contest - name: Create Windows ZIP shell: pwsh run: | - if (-not (Test-Path dist/praktiKST)) { - throw "No Windows app-image produced by jpackage" + if (-not (Test-Path dist/KST4Contest)) { + throw "No Windows app-image produced by createDistributable" } - Compress-Archive -Path dist/praktiKST -DestinationPath "dist/$env:ASSET_BASENAME-windows-x64.zip" -Force + Compress-Archive -Path dist/KST4Contest -DestinationPath "dist/$env:ASSET_BASENAME-windows-x64.zip" -Force - name: Upload Windows artifact uses: actions/upload-artifact@v4.3.4 @@ -102,7 +87,7 @@ jobs: - name: Resolve nightly version info run: | - VERSION=$(grep -m1 '' pom.xml | sed 's/.*\(.*\)<\/version>.*/\1/') + VERSION=$(grep -m1 '^version=' gradle.properties | cut -d= -f2) SHORT_SHA="${GITHUB_SHA::7}" echo "ASSET_BASENAME=KST4Contest-${VERSION}-${SHORT_SHA}" >> "$GITHUB_ENV" @@ -112,31 +97,21 @@ jobs: distribution: temurin java-version: "21" - - name: Ensure mvnw is executable - run: chmod +x mvnw + - name: Ensure gradlew is executable + run: chmod +x gradlew - - name: Build JAR and copy runtime dependencies - run: | - ./mvnw -B -DskipTests package dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/dist-libs - cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar - - - name: Build app-image with jpackage + - name: Build app-image run: | + ./gradlew -S :app-desktop:createDistributable mkdir -p dist - ADD_MODULES="$(java packaging/AddModules.java)" - jpackage \ - --type app-image \ - --name KST4Contest \ - --icon packaging/icons/kst4contest.png \ - --input target/dist-libs \ - --main-jar app.jar \ - --main-class kst4contest.view.Kst4ContestApplication \ - --module-path target/dist-libs \ - --add-modules "$ADD_MODULES" \ - --dest dist + # The following steps read dist/KST4Contest, so the Compose output goes + # there. The module list now lives in app-desktop/build.gradle.kts. + rm -rf dist/KST4Contest + cp -a app-desktop/build/compose/binaries/main/app/KST4Contest dist/ - name: Create AppDir metadata run: | + mkdir -p target rm -rf target/KST4Contest.AppDir cp -a dist/KST4Contest target/KST4Contest.AppDir @@ -163,6 +138,7 @@ jobs: - name: Build AppImage run: | + mkdir -p target wget -q -O target/appimagetool.AppImage https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage chmod +x target/appimagetool.AppImage APPIMAGE_EXTRACT_AND_RUN=1 ARCH=x86_64 target/appimagetool.AppImage target/KST4Contest.AppDir "dist/${ASSET_BASENAME}-linux-x86_64.AppImage" @@ -184,7 +160,7 @@ jobs: - name: Resolve nightly version info run: | - VERSION=$(grep -m1 '' pom.xml | sed 's/.*\(.*\)<\/version>.*/\1/') + VERSION=$(grep -m1 '^version=' gradle.properties | cut -d= -f2) SHORT_SHA="${GITHUB_SHA::7}" echo "ASSET_BASENAME=KST4Contest-${VERSION}-${SHORT_SHA}" >> "$GITHUB_ENV" @@ -199,32 +175,16 @@ jobs: sudo apt-get update -qq sudo apt-get install -y --no-install-recommends fakeroot - - name: Ensure mvnw is executable - run: chmod +x mvnw - - - name: Build JAR and copy runtime dependencies - run: | - ./mvnw -B -DskipTests package dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/dist-libs - cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar + - name: Ensure gradlew is executable + run: chmod +x gradlew - name: Build Debian package run: | + ./gradlew -S :app-desktop:packageDeb mkdir -p dist - ADD_MODULES="$(java packaging/AddModules.java)" - jpackage \ - --type deb \ - --name KST4Contest \ - --icon packaging/icons/kst4contest.png \ - --input target/dist-libs \ - --main-jar app.jar \ - --main-class kst4contest.view.Kst4ContestApplication \ - --module-path target/dist-libs \ - --add-modules "$ADD_MODULES" \ - --linux-package-deps "libgstreamer1.0-0,libgstreamer-plugins-base1.0-0,gstreamer1.0-plugins-good" \ - --dest dist - DEB="$(ls dist/*.deb | head -n 1)" + DEB="$(ls app-desktop/build/compose/binaries/main/deb/*.deb | head -n 1)" if [ -z "$DEB" ]; then - echo "No DEB produced by jpackage" && exit 1 + echo "No DEB produced by packageDeb" && exit 1 fi mv "$DEB" "dist/${ASSET_BASENAME}-debian-amd64.deb" @@ -245,7 +205,7 @@ jobs: - name: Resolve nightly version info run: | - VERSION=$(grep -m1 '' pom.xml | sed 's/.*\(.*\)<\/version>.*/\1/') + VERSION=$(grep -m1 '^version=' gradle.properties | cut -d= -f2) SHORT_SHA="${GITHUB_SHA::7}" echo "ASSET_BASENAME=KST4Contest-${VERSION}-${SHORT_SHA}" >> "$GITHUB_ENV" @@ -260,32 +220,16 @@ jobs: sudo apt-get update -qq sudo apt-get install -y --no-install-recommends rpm - - name: Ensure mvnw is executable - run: chmod +x mvnw - - - name: Build JAR and copy runtime dependencies - run: | - ./mvnw -B -DskipTests package dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/dist-libs - cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar + - name: Ensure gradlew is executable + run: chmod +x gradlew - name: Build Fedora package run: | + ./gradlew -S :app-desktop:packageRpm mkdir -p dist - ADD_MODULES="$(java packaging/AddModules.java)" - jpackage \ - --type rpm \ - --name KST4Contest \ - --icon packaging/icons/kst4contest.png \ - --input target/dist-libs \ - --main-jar app.jar \ - --main-class kst4contest.view.Kst4ContestApplication \ - --module-path target/dist-libs \ - --add-modules "$ADD_MODULES" \ - --linux-package-deps "gstreamer1,gstreamer1-plugins-base,gstreamer1-plugins-good" \ - --dest dist - RPM="$(ls dist/*.rpm | head -n 1)" + RPM="$(ls app-desktop/build/compose/binaries/main/rpm/*.rpm | head -n 1)" if [ -z "$RPM" ]; then - echo "No RPM produced by jpackage" && exit 1 + echo "No RPM produced by packageRpm" && exit 1 fi mv "$RPM" "dist/${ASSET_BASENAME}-fedora-x86_64.rpm" @@ -306,7 +250,7 @@ jobs: - name: Resolve nightly version info run: | - VERSION=$(grep -m1 '' pom.xml | sed 's/.*\(.*\)<\/version>.*/\1/') + VERSION=$(grep -m1 '^version=' gradle.properties | cut -d= -f2) SHORT_SHA="${GITHUB_SHA::7}" echo "VERSION=$VERSION" >> "$GITHUB_ENV" echo "SHORT_SHA=$SHORT_SHA" >> "$GITHUB_ENV" @@ -323,31 +267,21 @@ jobs: sudo apt-get update -qq sudo apt-get install -y --no-install-recommends zstd - - name: Ensure mvnw is executable - run: chmod +x mvnw + - name: Ensure gradlew is executable + run: chmod +x gradlew - - name: Build JAR and copy runtime dependencies - run: | - ./mvnw -B -DskipTests package dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/dist-libs - cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar - - - name: Build app-image with jpackage + - name: Build app-image run: | + ./gradlew -S :app-desktop:createDistributable mkdir -p dist - ADD_MODULES="$(java packaging/AddModules.java)" - jpackage \ - --type app-image \ - --name KST4Contest \ - --icon packaging/icons/kst4contest.png \ - --input target/dist-libs \ - --main-jar app.jar \ - --main-class kst4contest.view.Kst4ContestApplication \ - --module-path target/dist-libs \ - --add-modules "$ADD_MODULES" \ - --dest dist + # The following steps read dist/KST4Contest, so the Compose output goes + # there. The module list now lives in app-desktop/build.gradle.kts. + rm -rf dist/KST4Contest + cp -a app-desktop/build/compose/binaries/main/app/KST4Contest dist/ - name: Build Arch Linux package artifact run: | + mkdir -p target ARCH=$(uname -m) PKGVER=$(printf '%s' "${VERSION}-${SHORT_SHA}" | sed 's/[^[:alnum:].+_]/_/g') PKGROOT="target/archpkg" @@ -427,7 +361,7 @@ jobs: - name: Resolve nightly version info run: | - VERSION=$(grep -m1 '' pom.xml | sed 's/.*\(.*\)<\/version>.*/\1/') + VERSION=$(grep -m1 '^version=' gradle.properties | cut -d= -f2) SHORT_SHA="${GITHUB_SHA::7}" echo "VERSION=$VERSION" >> "$GITHUB_ENV" echo "SHORT_SHA=$SHORT_SHA" >> "$GITHUB_ENV" @@ -439,8 +373,8 @@ jobs: distribution: temurin java-version: "21" - - name: Ensure mvnw is executable - run: chmod +x mvnw + - name: Ensure gradlew is executable + run: chmod +x gradlew - name: Install Flatpak tooling run: | @@ -449,25 +383,17 @@ jobs: flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo flatpak --user install -y flathub org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 - - name: Build app-image with jpackage + - name: Build app-image run: | - ./mvnw -B -DskipTests package dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/dist-libs - cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar + ./gradlew -S :app-desktop:createDistributable mkdir -p target/flatpak-src - ADD_MODULES="$(java packaging/AddModules.java)" - jpackage \ - --type app-image \ - --name KST4Contest \ - --icon packaging/icons/kst4contest.png \ - --input target/dist-libs \ - --main-jar app.jar \ - --main-class kst4contest.view.Kst4ContestApplication \ - --module-path target/dist-libs \ - --add-modules "$ADD_MODULES" \ - --dest target/flatpak-src + # The manifest's source is flatpak-src/KST4Contest. + rm -rf target/flatpak-src/KST4Contest + cp -a app-desktop/build/compose/binaries/main/app/KST4Contest target/flatpak-src/ - name: Create Flatpak manifest run: | + mkdir -p target mkdir -p dist cat > target/de.x08.KST4Contest.yml << 'EOF' app-id: de.x08.KST4Contest @@ -515,6 +441,7 @@ jobs: - name: Build Flatpak repo (nightly) run: | + mkdir -p target flatpak-builder --force-clean target/flatpak-build target/de.x08.KST4Contest.yml flatpak build-export --gpg-sign="$FLATPAK_GPG_KEY_ID" target/flatpak-repo target/flatpak-build nightly flatpak build-update-repo --gpg-sign="$FLATPAK_GPG_KEY_ID" target/flatpak-repo @@ -622,7 +549,7 @@ jobs: - name: Resolve nightly version info run: | - VERSION=$(grep -m1 '' pom.xml | sed 's/.*\(.*\)<\/version>.*/\1/') + VERSION=$(grep -m1 '^version=' gradle.properties | cut -d= -f2) SHORT_SHA="${GITHUB_SHA::7}" ARCH=$(uname -m) echo "VERSION=$VERSION" >> "$GITHUB_ENV" @@ -636,8 +563,8 @@ jobs: distribution: temurin java-version: "21" - - name: Ensure mvnw is executable - run: chmod +x mvnw + - name: Ensure gradlew is executable + run: chmod +x gradlew - name: Import signing certificate env: diff --git a/.github/workflows/pr-compile-check.yml b/.github/workflows/pr-compile-check.yml index fd3228d2..b323ddbd 100644 --- a/.github/workflows/pr-compile-check.yml +++ b/.github/workflows/pr-compile-check.yml @@ -24,11 +24,162 @@ jobs: distribution: temurin java-version: "21" - - name: Ensure mvnw is executable - run: chmod +x mvnw - - - name: Verify packaging module list matches module-info.java - run: java packaging/AddModules.java --verify-pom + - name: Ensure gradlew is executable + run: chmod +x gradlew + # classes + testClasses rather than compileJava + compileTestJava. The old pair did + # cover Kotlin -- checked with a deliberately broken Kotlin test file, and also in + # --dry-run: the Kotlin plugin makes compileTestJava depend on compileTestKotlin, + # because Java has to see the Kotlin output. But that is the plugin's wiring and not + # this job's statement of intent, and it covered no resources. These two aggregates + # say "compile everything in all three modules" and do not depend on knowing that. + # + # They also run the translation generator, which app-desktop's compileKotlin depends + # on. That is why a pull request contributing a language needs no workflow of its own: + # an orphan key, a dropped placeholder or a duplicate fails here, with the generator's + # own message naming the file. - name: Compile - run: ./mvnw -B -DskipTests compile + run: ./gradlew -S classes testClasses + + # What a translation PR is actually about, put where its author will look. The counts + # come from the files rather than from Gradle's output, so an up-to-date task cannot + # make the table disappear. + - name: Summarise the interface texts + if: always() + run: | + set -euo pipefail + shopt -s nullglob + + base="app-desktop/src/main/i18n/strings_en.properties" + if [ ! -f "$base" ]; then + echo "no base translation file at $base" >&2 + exit 1 + fi + + count_keys() { grep -cE '^[^#!][^=]*=' "$1" || true; } + + total=$(count_keys "$base") + + { + echo "### Interface texts" + echo "" + echo "| language | translated | of | missing |" + echo "|---|---|---|---|" + } >> "$GITHUB_STEP_SUMMARY" + + for file in app-desktop/src/main/i18n/strings_*.properties; do + lang=$(basename "$file" .properties); lang=${lang#strings_} + have=$(count_keys "$file") + missing=$(( total - have )) + [ "$missing" -lt 0 ] && missing=0 + echo "| \`$lang\` | $have | $total | $missing |" >> "$GITHUB_STEP_SUMMARY" + done + + { + echo "" + echo "A language may be incomplete: a key it leaves out falls back to English," + echo "which is what lets a translation be contributed a piece at a time. German is" + echo "held complete by a test, because it ships." + } >> "$GITHUB_STEP_SUMMARY" + + worksheets=(app-desktop/build/generated/i18n/todo/*.todo.properties) + if [ ${#worksheets[@]} -gt 0 ]; then + { + echo "" + echo "The build wrote a worksheet of what is still missing for:" + echo "" + } >> "$GITHUB_STEP_SUMMARY" + for w in "${worksheets[@]}"; do + echo "- \`$(basename "$w")\`" >> "$GITHUB_STEP_SUMMARY" + done + fi + + test: + name: Test (Java 21, headless) + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4.1.7 + + - name: Set up Java 21 + uses: actions/setup-java@v4.1.0 + with: + distribution: temurin + java-version: "21" + + - name: Ensure gradlew is executable + run: chmod +x gradlew + + # Skiko's native library links against libGL, so it has to be loadable even though + # nothing here renders through it: the drawing tests use Skia's software backend and + # runComposeUiTest never opens a window. Without this the whole Compose half of the + # suite dies with "libskiko-linux-x64.so: libGL.so.1: cannot open shared object + # file" -- which reads like a missing display and is not one. Found by running this + # job under act, where the container has no libGL; GitHub's own runner image happens + # to ship it, so the step is what makes the job reproducible off GitHub. + - name: Install the OpenGL client library skiko links against + run: | + sudo apt-get update + sudo apt-get install -y --no-install-recommends libgl1 + + # No Xvfb, deliberately. Everything that pins behaviour runs without a display: + # runComposeUiTest reaches the semantics tree headless (measured before this job was + # written), and the ImageComposeScene drawing tests render in software. The handful + # of tests that open a real window guard themselves with assumeFalse(isHeadless) and + # skip here; the summary below prints the skip count, so that is visible rather than + # assumed. + # + # Software GL under Xvfb was considered and rejected: a missing Skia GL context is + # the hardest failure in this codebase to read, and importing that class of flake + # into CI would cost more than the few window tests are worth here. + + # All three modules. The translation generator is a Gradle module and not buildSrc + # precisely so that its 42 tests run here: buildSrc tests do not run on `./gradlew + # build` -- measured, not assumed. The summary below globs */build/test-results, so + # the module was counted the moment it existed. + - name: Test + run: ./gradlew -S test + + - name: Summarise the test results + if: always() + run: | + set -euo pipefail + shopt -s nullglob + files=(*/build/test-results/test/TEST-*.xml) + if [ ${#files[@]} -eq 0 ]; then + echo "No test result XML was produced -- the test task did not run." >&2 + exit 1 + fi + # Counted from the XML and not from Gradle's console output: this project's own + # rule is never to infer "all tests passed" from an exit code. + summary=$(grep -h "> "$GITHUB_STEP_SUMMARY" + if [ "$failures" != "0" ] || [ "$errors" != "0" ]; then + echo "The result XML reports failures or errors." >&2 + exit 1 + fi + + - name: Keep the test reports on a failure + if: failure() + uses: actions/upload-artifact@v4 + with: + name: test-results + path: | + */build/test-results/test/ + */build/reports/tests/test/ + if-no-files-found: ignore + retention-days: 7 diff --git a/.github/workflows/tagged-release.yml b/.github/workflows/tagged-release.yml index 50b84de7..e70de310 100644 --- a/.github/workflows/tagged-release.yml +++ b/.github/workflows/tagged-release.yml @@ -34,40 +34,23 @@ jobs: shell: pwsh run: choco install wixtoolset --no-progress -y - - name: Build JAR and copy runtime dependencies - shell: pwsh - run: | - .\mvnw.cmd -B -DskipTests package dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/dist-libs - $jar = Get-ChildItem -Path target -Filter 'praktiKST-*.jar' | Sort-Object LastWriteTime -Descending | Select-Object -First 1 - if (-not $jar) { - throw "No project JAR produced" - } - Copy-Item $jar.FullName target/dist-libs/app.jar - - - name: Build app-image with jpackage + - name: Build app-image shell: pwsh run: | + .\gradlew.bat -S :app-desktop:createDistributable New-Item -ItemType Directory -Force -Path dist | Out-Null - $addModules = & java packaging/AddModules.java - if ($LASTEXITCODE -ne 0) { throw "Failed to resolve --add-modules from module-info.java" } - jpackage ` - --type app-image ` - --name praktiKST ` - --icon packaging/icons/kst4contest.ico ` - --input target/dist-libs ` - --main-jar app.jar ` - --main-class kst4contest.view.Kst4ContestApplication ` - --module-path target/dist-libs ` - --add-modules $addModules ` - --dest dist + # The next step reads dist/KST4Contest, so the Compose output goes + # there. The module list now lives in app-desktop/build.gradle.kts. + if (Test-Path dist/KST4Contest) { Remove-Item -Recurse -Force dist/KST4Contest } + Copy-Item -Recurse app-desktop/build/compose/binaries/main/app/KST4Contest dist/KST4Contest - name: Create Windows ZIP shell: pwsh run: | - if (-not (Test-Path dist/praktiKST)) { - throw "No Windows app-image produced by jpackage" + if (-not (Test-Path dist/KST4Contest)) { + throw "No Windows app-image produced by createDistributable" } - Compress-Archive -Path dist/praktiKST -DestinationPath dist/praktiKST-${{ github.ref_name }}-windows-x64.zip -Force + Compress-Archive -Path dist/KST4Contest -DestinationPath dist/praktiKST-${{ github.ref_name }}-windows-x64.zip -Force - name: Upload Windows artifact uses: actions/upload-artifact@v4.3.4 @@ -89,31 +72,21 @@ jobs: distribution: temurin java-version: "21" - - name: Ensure mvnw is executable - run: chmod +x mvnw + - name: Ensure gradlew is executable + run: chmod +x gradlew - - name: Build JAR and copy runtime dependencies - run: | - ./mvnw -B -DskipTests package dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/dist-libs - cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar - - - name: Build app-image with jpackage + - name: Build app-image run: | + ./gradlew -S :app-desktop:createDistributable mkdir -p dist - ADD_MODULES="$(java packaging/AddModules.java)" - jpackage \ - --type app-image \ - --name KST4Contest \ - --icon packaging/icons/kst4contest.png \ - --input target/dist-libs \ - --main-jar app.jar \ - --main-class kst4contest.view.Kst4ContestApplication \ - --module-path target/dist-libs \ - --add-modules "$ADD_MODULES" \ - --dest dist + # The following steps read dist/KST4Contest, so the Compose output goes + # there. The module list now lives in app-desktop/build.gradle.kts. + rm -rf dist/KST4Contest + cp -a app-desktop/build/compose/binaries/main/app/KST4Contest dist/ - name: Create AppDir metadata run: | + mkdir -p target rm -rf target/KST4Contest.AppDir cp -a dist/KST4Contest target/KST4Contest.AppDir @@ -140,6 +113,7 @@ jobs: - name: Build AppImage run: | + mkdir -p target wget -q -O target/appimagetool.AppImage https://github.com/AppImage/appimagetool/releases/download/continuous/appimagetool-x86_64.AppImage chmod +x target/appimagetool.AppImage APPIMAGE_EXTRACT_AND_RUN=1 ARCH=x86_64 target/appimagetool.AppImage target/KST4Contest.AppDir dist/KST4Contest-${{ github.ref_name }}-linux-x86_64.AppImage @@ -169,32 +143,16 @@ jobs: sudo apt-get update -qq sudo apt-get install -y --no-install-recommends fakeroot - - name: Ensure mvnw is executable - run: chmod +x mvnw - - - name: Build JAR and copy runtime dependencies - run: | - ./mvnw -B -DskipTests package dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/dist-libs - cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar + - name: Ensure gradlew is executable + run: chmod +x gradlew - name: Build Debian package run: | + ./gradlew -S :app-desktop:packageDeb mkdir -p dist - ADD_MODULES="$(java packaging/AddModules.java)" - jpackage \ - --type deb \ - --name KST4Contest \ - --icon packaging/icons/kst4contest.png \ - --input target/dist-libs \ - --main-jar app.jar \ - --main-class kst4contest.view.Kst4ContestApplication \ - --module-path target/dist-libs \ - --add-modules "$ADD_MODULES" \ - --linux-package-deps "libgstreamer1.0-0,libgstreamer-plugins-base1.0-0,gstreamer1.0-plugins-good" \ - --dest dist - DEB="$(ls dist/*.deb | head -n 1)" + DEB="$(ls app-desktop/build/compose/binaries/main/deb/*.deb | head -n 1)" if [ -z "$DEB" ]; then - echo "No DEB produced by jpackage" && exit 1 + echo "No DEB produced by packageDeb" && exit 1 fi mv "$DEB" "dist/KST4Contest-${{ github.ref_name }}-debian-amd64.deb" @@ -223,32 +181,16 @@ jobs: sudo apt-get update -qq sudo apt-get install -y --no-install-recommends rpm - - name: Ensure mvnw is executable - run: chmod +x mvnw - - - name: Build JAR and copy runtime dependencies - run: | - ./mvnw -B -DskipTests package dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/dist-libs - cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar + - name: Ensure gradlew is executable + run: chmod +x gradlew - name: Build Fedora package run: | + ./gradlew -S :app-desktop:packageRpm mkdir -p dist - ADD_MODULES="$(java packaging/AddModules.java)" - jpackage \ - --type rpm \ - --name KST4Contest \ - --icon packaging/icons/kst4contest.png \ - --input target/dist-libs \ - --main-jar app.jar \ - --main-class kst4contest.view.Kst4ContestApplication \ - --module-path target/dist-libs \ - --add-modules "$ADD_MODULES" \ - --linux-package-deps "gstreamer1,gstreamer1-plugins-base,gstreamer1-plugins-good" \ - --dest dist - RPM="$(ls dist/*.rpm | head -n 1)" + RPM="$(ls app-desktop/build/compose/binaries/main/rpm/*.rpm | head -n 1)" if [ -z "$RPM" ]; then - echo "No RPM produced by jpackage" && exit 1 + echo "No RPM produced by packageRpm" && exit 1 fi mv "$RPM" "dist/KST4Contest-${{ github.ref_name }}-fedora-x86_64.rpm" @@ -277,31 +219,21 @@ jobs: sudo apt-get update -qq sudo apt-get install -y --no-install-recommends zstd - - name: Ensure mvnw is executable - run: chmod +x mvnw + - name: Ensure gradlew is executable + run: chmod +x gradlew - - name: Build JAR and copy runtime dependencies - run: | - ./mvnw -B -DskipTests package dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/dist-libs - cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar - - - name: Build app-image with jpackage + - name: Build app-image run: | + ./gradlew -S :app-desktop:createDistributable mkdir -p dist - ADD_MODULES="$(java packaging/AddModules.java)" - jpackage \ - --type app-image \ - --name KST4Contest \ - --icon packaging/icons/kst4contest.png \ - --input target/dist-libs \ - --main-jar app.jar \ - --main-class kst4contest.view.Kst4ContestApplication \ - --module-path target/dist-libs \ - --add-modules "$ADD_MODULES" \ - --dest dist + # The following steps read dist/KST4Contest, so the Compose output goes + # there. The module list now lives in app-desktop/build.gradle.kts. + rm -rf dist/KST4Contest + cp -a app-desktop/build/compose/binaries/main/app/KST4Contest dist/ - name: Build Arch Linux package artifact run: | + mkdir -p target ARCH=$(uname -m) PKGVER=$(printf '%s' "${{ github.ref_name }}" | sed 's/[^[:alnum:].+_]/_/g') PKGROOT="target/archpkg" @@ -384,8 +316,8 @@ jobs: distribution: temurin java-version: "21" - - name: Ensure mvnw is executable - run: chmod +x mvnw + - name: Ensure gradlew is executable + run: chmod +x gradlew - name: Install Flatpak tooling run: | @@ -394,25 +326,17 @@ jobs: flatpak remote-add --user --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo flatpak --user install -y flathub org.freedesktop.Platform//24.08 org.freedesktop.Sdk//24.08 - - name: Build app-image with jpackage + - name: Build app-image run: | - ./mvnw -B -DskipTests package dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/dist-libs - cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar + ./gradlew -S :app-desktop:createDistributable mkdir -p target/flatpak-src - ADD_MODULES="$(java packaging/AddModules.java)" - jpackage \ - --type app-image \ - --name KST4Contest \ - --icon packaging/icons/kst4contest.png \ - --input target/dist-libs \ - --main-jar app.jar \ - --main-class kst4contest.view.Kst4ContestApplication \ - --module-path target/dist-libs \ - --add-modules "$ADD_MODULES" \ - --dest target/flatpak-src + # The manifest's source is flatpak-src/KST4Contest. + rm -rf target/flatpak-src/KST4Contest + cp -a app-desktop/build/compose/binaries/main/app/KST4Contest target/flatpak-src/ - name: Create Flatpak manifest run: | + mkdir -p target mkdir -p dist cat > target/de.x08.KST4Contest.yml << 'EOF' app-id: de.x08.KST4Contest @@ -470,6 +394,7 @@ jobs: - name: Build Flatpak repo run: | + mkdir -p target flatpak-builder --force-clean target/flatpak-build target/de.x08.KST4Contest.yml flatpak build-export --gpg-sign="$FLATPAK_GPG_KEY_ID" target/flatpak-repo target/flatpak-build "$OSTREE_BRANCH" flatpak build-update-repo --gpg-sign="$FLATPAK_GPG_KEY_ID" target/flatpak-repo @@ -520,8 +445,8 @@ jobs: distribution: temurin java-version: "21" - - name: Ensure mvnw is executable - run: chmod +x mvnw + - name: Ensure gradlew is executable + run: chmod +x gradlew - name: Import signing certificate env: @@ -718,6 +643,90 @@ jobs: steps: - name: Checkout release source uses: actions/checkout@v4.1.7 + with: + # Full history and tags, needed to list the commits since the previous release. + fetch-depth: 0 + + # GitHub's generated release notes list merged pull requests only. Commits + # pushed directly to main are added here as their own section: + # ## What's Changed + # ### Commits on main (first-parent commits, no merges, no bots) + # ### Merged PRs (GitHub's generated PR list) + # The body also feeds the in-app update feed (website/src/_data/versionInfo.js, + # cleanReleaseBody), which drops headings and keeps the "* ..." lines. + - name: Build release notes + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG: ${{ github.ref_name }} + run: | + set -euo pipefail + + # Stable releases compare against the previous stable release, betas + # against the previous tag of any kind. + if [[ "$TAG" == beta-* ]]; then + PREVIOUS_TAG="$(git describe --tags --abbrev=0 "${TAG}^" 2>/dev/null || true)" + else + PREVIOUS_TAG="$(git describe --tags --abbrev=0 --exclude 'beta-*' "${TAG}^" 2>/dev/null || true)" + fi + echo "Previous tag: ${PREVIOUS_TAG:-}" + + RANGE="$TAG" + [ -n "$PREVIOUS_TAG" ] && RANGE="${PREVIOUS_TAG}..${TAG}" + + # --first-parent keeps the commits made directly on main; commits inside + # pull requests are covered by the PR list. Squash-merged PRs end in + # "(#123)" and are listed by GitHub as well. + git log --first-parent --no-merges --format='%an%x09%s' "$RANGE" \ + | awk -F '\t' '$1 != "github-actions[bot]" { print $2 }' \ + | grep -Ev '\(#[0-9]+\)$' \ + | sed 's/^/* /' > direct-commits.md || true + + # Let GitHub generate the PR part for the same range. + if [ -n "$PREVIOUS_TAG" ]; then + gh api "repos/${GITHUB_REPOSITORY}/releases/generate-notes" \ + -f tag_name="$TAG" -f previous_tag_name="$PREVIOUS_TAG" --jq .body > generated-notes.md + else + gh api "repos/${GITHUB_REPOSITORY}/releases/generate-notes" \ + -f tag_name="$TAG" --jq .body > generated-notes.md + fi + + python3 - <<'PY' + import re + + commits = open("direct-commits.md", encoding="utf-8").read().strip() + generated = open("generated-notes.md", encoding="utf-8").read() + + # GitHub's body: "## What's Changed" with the PR list, optionally + # "## New Contributors", and a closing "**Full Changelog**" line. + prs, rest = [], [] + section = None + for line in generated.splitlines(): + if re.match(r"^##\s+What's Changed", line): + section = "prs" + continue + if line.startswith("## ") or line.startswith("**Full Changelog**"): + section = "rest" + if section == "prs": + if line.strip(): + prs.append(line) + elif line.strip() or rest: + rest.append(line) + + parts = [] + if commits or prs: + parts.append("## What's Changed") + if commits: + parts.append("### Commits on main\n" + commits) + if prs: + parts.append("### Merged PRs\n" + "\n".join(prs)) + if rest: + parts.append("\n".join(rest).strip()) + + with open("release-notes.md", "w", encoding="utf-8") as out: + out.write("\n\n".join(parts) + "\n") + PY + + cat release-notes.md - name: Download Windows artifact uses: actions/download-artifact@v4.1.3 @@ -778,7 +787,8 @@ jobs: allowUpdates: false replacesArtifacts: false makeLatest: ${{ !startsWith(github.ref_name, 'beta-') }} - generateReleaseNotes: true + bodyFile: release-notes.md + generateReleaseNotes: false artifacts: >- release-assets/windows/praktiKST-${{ github.ref_name }}-windows-x64.zip, release-assets/linux/KST4Contest-${{ github.ref_name }}-linux-x86_64.AppImage, diff --git a/.github/workflows/test-publish-version-xml.yml b/.github/workflows/test-publish-version-xml.yml new file mode 100644 index 00000000..3a4dd6e5 --- /dev/null +++ b/.github/workflows/test-publish-version-xml.yml @@ -0,0 +1,170 @@ +name: TEST publish-version-xml (local only) + +on: + workflow_dispatch: + +jobs: + publish-version-xml: + name: Publish Version Info XML via WebDAV + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v4.1.7 + + - name: Generate kst4ContestVersionInfo.xml from GitHub releases + history + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + python3 << 'PYEOF' + import subprocess, json + from xml.etree.ElementTree import Element, SubElement, ElementTree, parse, indent + + def safe_version(tag): + cleaned = tag.lstrip('v') + try: + float(cleaned) + except ValueError: + pass + return cleaned + + import os, urllib.request + + REPO = 'praktimarc/kst4contest' + token = os.environ['GH_TOKEN'] + + def gh_get(path): + url = f'https://api.github.com/repos/{REPO}{path}' + req = urllib.request.Request(url, headers={ + 'Authorization': f'Bearer {token}', + 'Accept': 'application/vnd.github+json', + 'X-GitHub-Api-Version': '2022-11-28', + }) + with urllib.request.urlopen(req) as resp: + return json.loads(resp.read()) + + def get_issues_for_release(since, until): + """Return closed issues in (since, until] categorised by label.""" + LABEL_MAP = {'enhancement': 'added', 'bug': 'fixed'} + buckets = {'added': [], 'fixed': []} + page = 1 + while True: + items = gh_get(f'/issues?state=closed&per_page=100&page={page}') + if not items: + break + for issue in items: + if 'pull_request' in issue: + continue + closed = issue.get('closed_at') or '' + if not (since < closed <= until): + continue + labels = [l['name'] for l in issue['labels']] + bucket = next((LABEL_MAP[l] for l in labels if l in LABEL_MAP), None) + if bucket: + buckets[bucket].append(f'- {issue["title"]}') + if len(items) < 100: + break + page += 1 + return {k: '\n'.join(v) for k, v in buckets.items()} + + def clean_body(body): + """Strip GitHub markdown noise, keep plain text.""" + import re + lines = [] + for line in (body or '').splitlines(): + if re.match(r'^#{1,3}\s', line): + continue + if line.strip().startswith('**Full Changelog**'): + continue + line = re.sub(r'\s+by @\S+ in https://\S+', '', line) + line = re.sub(r'^\* ', '- ', line) + if line.strip(): + lines.append(line) + return re.sub(r'\n{3,}', '\n\n', '\n'.join(lines)).strip() + + # --- Fetch all releases --- + raw = gh_get('/releases?per_page=100') + gh_releases = [ + { + 'tagName': r['tag_name'], + 'publishedAt': r['published_at'] or '', + 'name': r['name'] or r['tag_name'], + 'body': r['body'] or '', + 'isPrerelease': r['prerelease'], + } + for r in raw + ] + + # --- Simulate a stable 1.41 release for testing --- + gh_releases.insert(0, { + 'tagName': '1.41', + 'publishedAt': '2026-06-30T10:00:00Z', + 'name': 'Release 1.41', + 'body': 'Release 1.41', + 'isPrerelease': False, + }) + + gh_releases.sort(key=lambda r: r['publishedAt'], reverse=True) + + stable_releases = [r for r in gh_releases if not r['isPrerelease']] + stable = stable_releases[0] if stable_releases else None + + gh_versions = {safe_version(r['tagName']) for r in stable_releases} + + history_tree = parse('.github/version-history.xml') + history_entries = history_tree.getroot().findall('changeLog') + + root = Element('praktiKST') + + lv = SubElement(root, 'latestVersion') + latest_tag = stable['tagName'] if stable else 'unknown' + SubElement(lv, 'versionNumber').text = safe_version(latest_tag) + SubElement(lv, 'adminMessage').text = '' + latest_issues = get_issues_for_release('1970-01-01T00:00:00Z', stable['publishedAt']) if stable else {} + SubElement(lv, 'majorChanges').text = latest_issues.get('added', '')[:300] + win_filename = f'praktiKST-{latest_tag}-windows-x64.zip' + SubElement(lv, 'latestVersionPathOnWebserver').text = ( + f'https://github.com/{REPO}/releases/download/{latest_tag}/{win_filename}' + ) + + nuf = SubElement(root, 'needUpdateSinceLastVersion') + SubElement(nuf, 'filename').text = win_filename + + # Build changelog for each stable release using closed issues in its window + for i, rel in enumerate(stable_releases): + until = rel['publishedAt'] + since = stable_releases[i + 1]['publishedAt'] if i + 1 < len(stable_releases) else '1970-01-01T00:00:00Z' + s = get_issues_for_release(since, until) + cl = SubElement(root, 'changeLog') + SubElement(cl, 'changedVersionNumber').text = safe_version(rel['tagName']) + SubElement(cl, 'date').text = until[:10] + SubElement(cl, 'description').text = rel['name'] + SubElement(cl, 'added').text = s['added'] + SubElement(cl, 'changed').text = clean_body(rel['body']) + SubElement(cl, 'fixed').text = s['fixed'] + SubElement(cl, 'removed').text = '' + + for entry in history_entries: + ver_node = entry.find('changedVersionNumber') + if ver_node is not None and ver_node.text and ver_node.text.strip() in gh_versions: + continue + root.append(entry) + + indent(root, space=' ') + tree = ElementTree(root) + with open('kst4ContestVersionInfo.xml', 'w', encoding='utf-8') as f: + f.write('\n') + tree.write(f, encoding='unicode', xml_declaration=False) + + print('Generated kst4ContestVersionInfo.xml') + PYEOF + + - name: Show generated XML (first 40 lines) + run: head -40 kst4ContestVersionInfo.xml + + - name: Upload to WebDAV + run: | + curl --fail --silent --show-error \ + --user "${{ secrets.WEBDAV_USER }}:${{ secrets.WEBDAV_PASSWORD }}" \ + --upload-file kst4ContestVersionInfo.xml \ + "${{ secrets.WEBDAV_URL }}/kst4ContestVersionInfo.xml" diff --git a/.gitignore b/.gitignore index e9632171..6e89ba3a 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,15 @@ website/_site/ # Apple notarization private keys - never commit these *.p8 + +# Gradle +.gradle/ +build/ +core/build/ +app-desktop/build/ + +# Agent scratch area - screenshots, notes, throwaway scripts +scratch/ + +# Kotlin incremental build data +.kotlin/ diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar deleted file mode 100644 index cb28b0e37c7d206feb564310fdeec0927af4123a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 62547 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 A?*IS* diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties deleted file mode 100644 index 3c6fda8c..00000000 --- a/.mvn/wrapper/maven-wrapper.properties +++ /dev/null @@ -1,18 +0,0 @@ -# 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. -distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.2/apache-maven-3.9.2-bin.zip -wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar diff --git a/0001-Document-v1.43-and-fix-release-metadata.patch b/0001-Document-v1.43-and-fix-release-metadata.patch deleted file mode 100644 index dd44886f..00000000 --- a/0001-Document-v1.43-and-fix-release-metadata.patch +++ /dev/null @@ -1,416 +0,0 @@ -From afb77c6a8674ff5571a9c57cbe7108b9a5189407 Mon Sep 17 00:00:00 2001 -From: Codex -Date: Fri, 4 Sep 2026 00:17:15 +0300 -Subject: [PATCH] Document v1.43 and fix release metadata - ---- - .github/workflows/tagged-release.yml | 84 +++++++++---------- - docs/PROJECT_CONTEXT.md | 4 + - github_docs/de-Changelog.md | 80 +++++++++++++++--- - github_docs/en-Changelog.md | 80 +++++++++++++++--- - .../kst4contest/ApplicationConstants.java | 2 +- - website/src/news/2026-09-03-version-1-43.md | 29 +++++++ - 6 files changed, 212 insertions(+), 67 deletions(-) - create mode 100644 website/src/news/2026-09-03-version-1-43.md - -diff --git a/.github/workflows/tagged-release.yml b/.github/workflows/tagged-release.yml -index d9133550..be7bf536 100644 ---- a/.github/workflows/tagged-release.yml -+++ b/.github/workflows/tagged-release.yml -@@ -786,45 +786,45 @@ jobs: - release-assets/macos/KST4Contest-${{ github.ref_name }}-macos-*.dmg, - release-assets/docs/KST4Contest-${{ github.ref_name }}-manual-en.pdf, - release-assets/docs/KST4Contest-${{ github.ref_name }}-manual-de.pdf -- -- # The update feed is generated only after GitHub has published the -- # release. Otherwise the Releases API cannot return the release notes -- # belonging to the tag which triggered this workflow. -- - name: Set up Node.js for website build -- uses: actions/setup-node@v4 -- with: -- node-version: "24" -- cache: npm -- cache-dependency-path: website/package-lock.json -- -- - name: Build and validate website after release publication -- working-directory: website -- run: | -- npm ci -- npm test -- npm run build -- env: -- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -- -- - name: Verify Stable release in update feed -- if: ${{ !startsWith(github.ref_name, 'beta-') }} -- working-directory: website -- run: npm run validate:version-info -- env: -- EXPECTED_STABLE_VERSION: ${{ github.ref_name }} -- -- - name: Attach verified version info to tagged release -- run: >- -- gh release upload "${GITHUB_REF_NAME}" -- website/_site/kst4ContestVersionInfo.xml -- --clobber -- env: -- GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} -- -- - name: Upload verified website artifact -- uses: actions/upload-artifact@v4.3.4 -- with: -- name: kst4contest-website-${{ github.ref_name }} -- path: website/_site/ -- if-no-files-found: error -- retention-days: 14 -\ No newline at end of file -+ -+ # The update feed is generated only after GitHub has published the -+ # release. Otherwise the Releases API cannot return the release notes -+ # belonging to the tag which triggered this workflow. -+ - name: Set up Node.js for website build -+ uses: actions/setup-node@v4 -+ with: -+ node-version: "24" -+ cache: npm -+ cache-dependency-path: website/package-lock.json -+ -+ - name: Build and validate website after release publication -+ working-directory: website -+ run: | -+ npm ci -+ npm test -+ npm run build -+ env: -+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} -+ -+ - name: Verify Stable release in update feed -+ if: ${{ !startsWith(github.ref_name, 'beta-') }} -+ working-directory: website -+ run: npm run validate:version-info -+ env: -+ EXPECTED_STABLE_VERSION: ${{ github.ref_name }} -+ -+ - name: Attach verified version info to tagged release -+ run: >- -+ gh release upload "${GITHUB_REF_NAME}" -+ website/_site/kst4ContestVersionInfo.xml -+ --clobber -+ env: -+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} -+ -+ - name: Upload verified website artifact -+ uses: actions/upload-artifact@v4.3.4 -+ with: -+ name: kst4contest-website-${{ github.ref_name }} -+ path: website/_site/ -+ if-no-files-found: error -+ retention-days: 14 -diff --git a/docs/PROJECT_CONTEXT.md b/docs/PROJECT_CONTEXT.md -index b0ca4b63..c4d70f1f 100644 ---- a/docs/PROJECT_CONTEXT.md -+++ b/docs/PROJECT_CONTEXT.md -@@ -162,6 +162,10 @@ The repository contains the KST4Contest website under `website/`, published sepa - - Current website/deployment scripts and update-feed behaviour must be inspected before changes; do not rely on historical assumptions. - -+- `APPLICATION_CURRENT_VERSION` is the user-visible semantic version and must use the dotted `major.minor.patch` form. `APPLICATION_CURRENTVERSIONNUMBER` is retained only for older feeds and encodes patch releases by appending the patch digit, for example `1.43.1` as `1.431`. -+- The tagged-release workflow creates the GitHub Release before building the website update feed. This ordering is required because `versionInfo.js` reads the published release body through the GitHub Releases API. -+- After publication, the workflow tests and builds the website, validates the expected Stable version, attaches `kst4ContestVersionInfo.xml` to the release and uploads the complete website build as a workflow artifact. -+ - ## Important Decisions and Workarounds - - - Preserve full callsign/category identity while applying base-call normalisation only to specifically defined features. -diff --git a/github_docs/de-Changelog.md b/github_docs/de-Changelog.md -index 2022f904..622bb446 100644 ---- a/github_docs/de-Changelog.md -+++ b/github_docs/de-Changelog.md -@@ -8,6 +8,72 @@ Die veröffentlichten Stable-Versionen und ihre Programmpakete stehen unter [Git - - --- - -+## v1.43.1 (2026-09-03) -+ -+**Korrigierte Versionsmetadaten** -+ -+v1.43.1 enthält dieselben funktionalen Änderungen wie v1.43.0. Korrigiert wurden die Anwendungs- und Build-Metadaten für Anzeige, ON4KST-Kennung und Update-Vergleich. Ein Teil der Metadaten des ersten v1.43.0-Pakets wies den Build noch als Version 1.42 aus. -+ -+### Behoben -+ -+- **Einheitliche semantische Version:** Die sichtbare Anwendungsversion verwendet jetzt vollständig `1.43.1`. Der kompakte Wert `1.431` bleibt ausschließlich im veralteten numerischen Feld für die Kompatibilität mit älteren Update-Feeds erhalten. -+ -+- **Update-Feed im Tagged-Release-Workflow:** Website-Build, Prüfung des Versionsfeeds und Upload der Artefakte laufen jetzt tatsächlich nach der Veröffentlichung des GitHub Releases. Diese Schritte waren zuvor versehentlich in die Artefaktliste der Release-Action eingerückt und wurden deshalb übersprungen. -+ -+Wer v1.43.0 installiert hat, sollte v1.43.1 verwenden. Die Funktionen bleiben unverändert; korrigiert werden nur die Versionsmetadaten und der Release-Workflow. -+ -+Die korrigierte Version ist als [Release v1.43.1](https://github.com/praktimarc/kst4contest/releases/tag/v1.43.1) verfügbar. -+ -+--- -+ -+## v1.43.0 (2026-09-03) -+ -+**Zuverlässigere Log-Synchronisation, gespeicherte Tabellenlayouts und bessere DX-Cluster-Kompatibilität** -+ -+v1.43 konzentriert sich auf die zuverlässige Verarbeitung externer Logdaten und den stabilen Betrieb während längerer Conteste. Hinzu kommen praktische Einstellmöglichkeiten für Tabellenlayouts und die Stationsgruppierung auf der Karte. -+ -+### Neu -+ -+- **Optionale Kartencluster:** **Group nearby stations** schaltet die räumliche Gruppierung bei niedrigen Zoomstufen unmittelbar ein oder aus. Die gespeicherte Auswahl verändert weder Kartenausschnitt noch Stationsauswahl; die Zusammenfassung aktiver Varianten desselben Basisrufzeichens bleibt davon unabhängig. Damit ist [Issue #79](https://github.com/praktimarc/kst4contest/issues/79) umgesetzt. -+ -+- **Tabellenlayout automatisch gesichert:** Tabellen erhalten beim ersten brauchbaren Inhalt sinnvolle Breiten. Manuell geänderte Spaltenbreiten, Fenstergrößen und relevante Divider werden nach kurzer Verzögerung in `preferences.xml` geschrieben. Haupt- und Monitorfenster behalten getrennte Layouts für DXCluster und QSO of the other. -+ -+- **Tooltips für gekürzte Tabellenwerte:** Normale Tabellenzellen zeigen ihren vollständigen Inhalt, wenn die sichtbare Spalte zu schmal ist. Funktionale Tooltips und anklickbare Links bleiben davon unberührt. -+ -+- **Hinweis bei neu angelegtem Simplelogfile:** Fehlt die ausgewählte Datei, legt KST4Contest sie an und zeigt einen Hinweis mit Dateipfad, konkretem Testablauf und Link zum passenden Abschnitt des Handbuchs. -+ -+### Geändert -+ -+- **Robuste Simplelogfile-Auswertung:** Die ausgewählte Datei wird einmal pro Minute ausgewertet und nach jedem Durchlauf geschlossen, damit das Logprogramm sie ersetzen oder rotieren kann. Erkannte Rufzeichen setzen den globalen Worked-Status für alle aktiven Suffixvarianten des Basisrufzeichens. Bei deaktivierter Funktion findet kein Dateizugriff statt; Lese- oder Erstellungsfehler beenden die periodische Aufgabe nicht mehr. -+ -+- **Einheitliche Bandwerte externer Logger:** UCXLog-kompatible Pakete und Win-Test-Ereignisse verwenden eine gemeinsame Bandnormalisierung. Numerische Werte, Meter- und Zentimeterangaben sowie die vorhandenen Win-Test-IDs setzen damit dieselben Worked-Markierungen und Worked-Großfelder. Insbesondere `2320`, `5760` und `10368` werden zuverlässig verarbeitet; bei fehlendem oder unbekanntem Band wird nur der globale Worked-Status gesetzt. -+ -+- **Kompakte vollständige Frequenzen erkannt:** Vollständige Frequenzangaben ohne Dezimaltrenner werden auf allen unterstützten Bändern akzeptiert; die letzten drei Ziffern bilden den kHz-Anteil. Nackte dreistellige Zahlen benötigen weiterhin einen erkennbaren Frequenzkontext, damit Signalrapporte und andere Zahlen nicht als QRG behandelt werden. -+ -+- **DXSpider-kompatibles Spotformat:** Lokale DX-Cluster-Spots verwenden eine feste 75-Zeichen-Nutzzeile mit dem DX-Rufzeichen ab Spalte 27, einem 30 Zeichen breiten Kommentarfeld und der UTC-Zeit ab Spalte 71. Das Format bleibt bis 24 GHz stabil. Überlange DX-Rufzeichen werden verworfen und protokolliert, statt unbemerkt abgeschnitten zu werden. Damit ist [Issue #86](https://github.com/praktimarc/kst4contest/issues/86) behoben. -+ -+- **Aktive ON4KST-Verbindungsprüfung:** Ein ruhiger Chatserver wird mit einer expliziten, sitzungsweiten Abfrage geprüft, bevor die Verbindung als unterbrochen gilt. Heartbeat und Prüftelegramme behalten das erforderliche CR/LF-Framing. -+ -+- **Zuverlässige Altersmarkierung privater Nachrichten:** Eingehende Privatnachrichten verwenden bis zu fünf Minuten lang die definierten grünen Altersstufen. Eigene Nachrichten behalten ihre separate Darstellung; leere oder wiederverwendete Tabellenzeilen kehren zum normalen Design zurück und behalten keine veraltete Hervorhebung. -+ -+### Behoben -+ -+- **Worked-Status nach dem Login:** Persistierte SQLite-Informationen werden vor der Veröffentlichung jeder initialen ON4KST-Benutzerliste geladen und angewendet. Erneute Verbindungen, beide Kategorien und alle aktiven Varianten eines Basisrufzeichens starten dadurch mit dem richtigen Status. Damit ist [Issue #85](https://github.com/praktimarc/kst4contest/issues/85) behoben. -+ -+- **Fehlerhafte Trennung bei ruhigem Server:** Eine gültige ON4KST-Verbindung wird nicht mehr beendet, nur weil der Server gerade keine Aktivitätszeilen überträgt. -+ -+### Dokumentation und Auslieferung -+ -+- Das deutsche und englische Handbuch wurden mit der Implementierung abgeglichen und überarbeitet. Ein neues Kapitel zum Contest-Workflow verbindet die einzelnen Funktionen zu einem praktischen Betriebsablauf; außerdem wurden die Abschnitte zu Dual Chat, Privatnachrichten, QRG-Synchronisation, Simplelogfile-Auswertung und Konfiguration präzisiert. -+ -+- Die Website beschreibt Band- und Richtungsgelegenheiten, Stationskarte, QRG-Verarbeitung, Filter, globale Nachrichtenansichten, Privatnachrichten und Log-Synchronisation jetzt ausführlicher. -+ -+- Die AUR-Paketdefinitionen wurden auf v1.43.0 aktualisiert. -+ -+Die vollständige Funktionalität von v1.43.0 steht im [Release v1.43.0](https://github.com/praktimarc/kst4contest/releases/tag/v1.43.0) bereit. Wegen der inkonsistenten eingebetteten Versionsmetadaten ist v1.43.1 der empfohlene Paketstand. -+ -+--- -+ - ## v1.42.0 (2026-08-22) - - **Gemeinsamer Bandkontext, sitzungsbasierte ON4KST-Verbindung und signierte macOS-Pakete** -@@ -38,21 +104,17 @@ v1.42 führt mehrere bisher getrennte Auswertungen zusammen. Bandinformationen, - - - **Filter zurücksetzen:** Ein eigener Reset-Button entfernt die aktiven Filterprädikate der Benutzerliste zuverlässig. - --- **Optionale Kartencluster:** **Group nearby stations** schaltet die räumliche Gruppierung bei niedrigen Zoomstufen unmittelbar ein oder aus. Die automatisch gespeicherte Auswahl verändert weder Kartenausschnitt noch Stationsauswahl; die Zusammenfassung aktiver Varianten desselben Basisrufzeichens bleibt davon unabhängig. Damit ist [Issue #79](https://github.com/praktimarc/kst4contest/issues/79) umgesetzt. -+- **Kartencluster:** Räumlich dicht beieinanderliegende Stationen werden bei niedrigen Zoomstufen zusammengefasst. Die ausgewählte Station und relevante Richtungsgelegenheiten bleiben einzeln sichtbar. - - - **Ausblendbare Streckenanalyse:** Geländeprofil und Analysebereich der Stationskarte können vollständig ausgeblendet werden. Die Auswahl wird gespeichert und beim nächsten Programmstart wiederhergestellt. - - ### Geändert - --- **Tabellenlayout automatisch gesichert:** Tabellen werden beim ersten brauchbaren Inhalt sinnvoll dimensioniert. Manuell geänderte Spaltenbreiten, Fenstergrößen und relevante Divider werden verzögert in `preferences.xml` gespeichert; Haupt- und Monitorfenster behalten für DXCluster und QSO of the other getrennte Layouts. Gekürzte normale Zellwerte zeigen ihren Volltext im Tooltip, ohne funktionale Tooltips oder anklickbare Links zu verdrängen. -- --- **DX-Cluster-Zeilenformat vereinheitlicht:** Lokale Spots verwenden jetzt eine feste, DXSpider-kompatible 75-Zeichen-Nutzzeile mit dem DX-Rufzeichen ab Spalte 27, einem 30 Zeichen breiten Kommentarfeld und der UTC-Zeit ab Spalte 71. Das Format bleibt auch bei Mikrowellenfrequenzen bis 24 GHz stabil. Überlange DX-Rufzeichen werden verworfen und protokolliert, statt still abgeschnitten zu werden; AirScout- und Testkommentare sind entsprechend kompakter. -- - - **Sessionbezogene ON4KST-Verbindungssteuerung:** Socket, Reader, Writer, Messagebus und Warteschlangen gehören jetzt zu einer eindeutig identifizierten Verbindungssession. Veraltete Threads einer abgelösten Verbindung können dadurch keine Daten mehr verarbeiten oder die neue Verbindung schließen. `ONLINE` wird erst nach bestätigtem Login und vollständig empfangenen Benutzerlisten gemeldet. Verbindungsaufbau, Login und Synchronisation besitzen feste Zeitlimits; Heartbeats, ausbleibende Eingangsdaten, EOF sowie Lese- und Schreibfehler werden überwacht und lösen bei Bedarf einen kontrollierten Neuaufbau mit Backoff aus. - - - **ON4KST-Protokollbefehle abgesichert:** Ausgehende Befehle werden zentral aufgebaut und auf gültige Kategorien, Locatoren und unerlaubte Frame-Trennzeichen geprüft. Da ON4KST pro TCP-Session nur einen Locator verwaltet, wird für beide Chat-Kategorien der Hauptlocator verwendet und eine abweichende zweite Konfiguration protokolliert, statt widersprüchliche Befehle an den Server zu senden. - --- **QRG-Erkennung präzisiert:** Vollständige Frequenzangaben werden auch ohne Dezimaltrenner erkannt; die letzten drei Ziffern bilden dabei den kHz-Anteil. Relative Frequenzen bleiben unverändert, und nackte dreistellige Zahlen gelten weiterhin nur bei erkennbarem Frequenzkontext als QRG. Signalrapporte, Bandangaben und andere Zahlen erzeugen dadurch seltener falsche Frequenzen. -+- **QRG-Erkennung präzisiert:** Vollständige und relative Frequenzangaben werden weiterhin erkannt. Nackte dreistellige Zahlen gelten nur noch bei erkennbarem Frequenzkontext als QRG. Signalrapporte, Bandangaben und andere Zahlen erzeugen dadurch seltener falsche Frequenzen. - - - **Stationsbezogener Frequenzkontext:** Bei relativen QRGs verwendet KST4Contest zuerst einen höchstens 30 Minuten alten Bandkontext derselben Station. Erst wenn dieser fehlt, wird das global konfigurierte Fallback-Band verwendet. - -@@ -86,10 +148,6 @@ v1.42 führt mehrere bisher getrennte Auswertungen zusammen. Bandinformationen, - - - **DXLog-Gesamtlog übernommen:** Der UCXLog-kompatible UDP-Listener verarbeitet neben `contactinfo` auch `contactreplace`. Dadurch kann ein von DXLog.net als vollständiges Log ausgesendeter Datenbestand eingelesen werden. - --- **Logger-Bandwerte vereinheitlicht:** Numerische sowie Meter- und Zentimeterangaben aus UCXLog-kompatiblen QSO-Paketen und die Band-IDs von Win-Test werden einmal normalisiert und danach einheitlich für Worked-Markierungen und Worked-Großfelder verwendet. Dadurch setzen insbesondere `2320`, `5760` und `10368` zuverlässig ihre vorhandenen Bandmarkierungen. Bei einem fehlenden oder unbekannten Band bleibt es beim globalen Worked-Status. -- --- **Simplelogfile-Verhalten präzisiert:** Die ausgewählte Textdatei wird einmal pro Minute mit einem festen Rufzeichenmuster ausgewertet. Treffer setzen den globalen Worked-Status aller aktiven Varianten des Basisrufzeichens, werden aber nicht in SQLite persistiert. Eine fehlende Datei wird angelegt; Lese- und Erstellungsfehler beenden die periodische Auswertung nicht. Ein Datenbank-Reset verändert die Datei nicht, sodass enthaltene Rufzeichen bei der nächsten Auswertung erneut als gearbeitet markiert werden. -- - - **Automatische QRG-Übernahme abgesichert:** `MYQRG` wird nur von einer aktivierten Schnittstelle aktualisiert, die tatsächlich gültige `RadioInfo`- beziehungsweise Win-Test-`STATUS`-Pakete liefert. Eine aktivierte, aber nicht liefernde Quelle ersetzt die notwendige Funktionsprüfung oder manuelle QRG-Pflege nicht. - - - **Versionserkennung verbessert:** Versionsnummern werden semantisch verglichen, damit beispielsweise Patch-Versionen und Nightly-Stände nicht mehr durch eine einfache Fließkommazahl falsch eingeordnet werden. -@@ -98,8 +156,6 @@ v1.42 führt mehrere bisher getrennte Auswertungen zusammen. Bandinformationen, - - - **Zuverlässige Benutzerliste beim Login:** Ungültige oder unvollständige `UA0`-Teilnehmerdatensätze werden einzeln verworfen und protokolliert, ohne die Verarbeitung der alphabetisch folgenden Teilnehmer abzubrechen. Die gültigen Einträge werden zunächst pro Kategorie gesammelt und erst mit dem ersten zugehörigen `UE`-Abschlussframe vollständig veröffentlicht. - --- **Persistierter Worked-Status beim Listenaufbau:** Beim Abschluss jeder initialen ON4KST-Benutzerliste wird der SQLite-Zustand einmal geladen und vor der Veröffentlichung auf die neuen Chatmember angewendet. Das gilt für beide Kategorien, erneute Verbindungen und alle aktiven Varianten eines Basisrufzeichens. -- - - **Benutzerliste verschwindet nach dem Login:** ON4KST kann nach Namens-, Status- oder anderen Live-Änderungen weitere `UE`-Frames für dieselbe Kategorie senden. Wiederholte Abschlussframes werden jetzt erkannt und ignoriert, damit eine bereits gefüllte Benutzerliste nicht durch eine leere Momentaufnahme ersetzt wird. - - - **Fehlgeschlagener Erstaufbau und Verbindungsverlust:** Wenn beim Programmstart keine Verbindung zum Server hergestellt werden kann, läuft KST4Contest nicht mehr in eine Endlos- oder Busy-Wait-Schleife. Die Oberfläche bleibt bedienbar und weitere Versuche erfolgen mit begrenztem Backoff. Auch ein vom Server geschlossener oder über längere Zeit stummer Socket wird zuverlässig erkannt. -diff --git a/github_docs/en-Changelog.md b/github_docs/en-Changelog.md -index 1635ce44..af1cb47b 100644 ---- a/github_docs/en-Changelog.md -+++ b/github_docs/en-Changelog.md -@@ -8,6 +8,72 @@ Published Stable versions and their application packages are available under [Gi - - --- - -+## v1.43.1 (2026-09-03) -+ -+**Corrected version metadata** -+ -+v1.43.1 contains the same functional changes as v1.43.0. It corrects the application and build metadata used for display, ON4KST identification and update comparison. Some metadata in the first v1.43.0 package set still identified the build as version 1.42. -+ -+### Fixed -+ -+- **Consistent semantic version:** The user-visible application version now uses the complete `1.43.1` form. The compact value `1.431` remains only in the deprecated numeric field required for compatibility with older update feeds. -+ -+- **Tagged-release update feed:** The website build, version-feed validation and artifact upload now run as actual workflow steps after the GitHub Release has been published. They were previously indented into the release action's artifact list and therefore skipped. -+ -+Users of v1.43.0 should install v1.43.1. The functionality is unchanged; the update only corrects the version metadata and release workflow. -+ -+The corrected version is available as [Release v1.43.1](https://github.com/praktimarc/kst4contest/releases/tag/v1.43.1). -+ -+--- -+ -+## v1.43.0 (2026-09-03) -+ -+**More reliable log synchronisation, persistent layouts and better DX Cluster compatibility** -+ -+v1.43 concentrates on reliability around external log data and long-running contest operation. It also adds practical control over table layouts and station grouping on the map. -+ -+### Added -+ -+- **Optional map clustering:** **Group nearby stations** immediately enables or disables spatial grouping at lower zoom levels. The stored setting changes neither the viewport nor the selected station; aggregation of active variants sharing one base callsign remains independent. This implements [Issue #79](https://github.com/praktimarc/kst4contest/issues/79). -+ -+- **Automatic table-layout persistence:** Tables receive useful widths when their first meaningful contents arrive. Manually changed column widths, window sizes and relevant dividers are written to `preferences.xml` after a short delay. The main and monitor windows keep separate DXCluster and QSO-of-the-other layouts. -+ -+- **Tooltips for truncated table values:** Normal table cells expose their complete text when the visible column is too narrow, without replacing functional tooltips or clickable links. -+ -+- **Simplelogfile creation notice:** When the selected file does not exist, KST4Contest creates it and displays a notice with the file path, a concrete test procedure and a link to the relevant manual section. -+ -+### Changed -+ -+- **Robust Simplelogfile evaluation:** The selected file is evaluated once per minute and closed after every pass so that the logging application can replace or rotate it. Detected callsigns apply the global Worked state to every active suffix variant of the base callsign. Disabling the function prevents any file access, while read or creation errors no longer terminate the periodic task. -+ -+- **Consistent external logger bands:** UCXLog-compatible packets and Win-Test events use one shared band normalisation. Numeric values, metre and centimetre designators and the existing Win-Test IDs now set the same Worked flags and worked grid squares. Values including `2320`, `5760` and `10368` are handled reliably; a missing or unknown band sets only the global Worked state. -+ -+- **Compact full-frequency recognition:** Complete frequencies without a decimal separator are accepted across the supported bands, with the final three digits interpreted as the kHz part. Bare three-digit numbers still require recognisable frequency context so that signal reports and unrelated numbers are not treated as QRGs. -+ -+- **DXSpider-compatible spot format:** Local DX Cluster spots use a fixed 75-character payload line with the DX callsign in column 27, a 30-character comment field and UTC time in column 71. The format remains stable up to 24 GHz. Overlong DX callsigns are rejected and logged instead of being silently truncated. This resolves [Issue #86](https://github.com/praktimarc/kst4contest/issues/86). -+ -+- **Active ON4KST connection probe:** A quiet chat server is checked with an explicit session-wide probe before the connection is treated as dead. Heartbeats and probe frames retain the required CR/LF framing. -+ -+- **Reliable private-message age highlighting:** Incoming private messages use the defined green age levels for up to five minutes. Locally sent messages retain their separate style, and empty or reused table rows return to the normal design instead of keeping an obsolete highlight. -+ -+### Fixed -+ -+- **Worked state after login:** Persisted SQLite Worked information is loaded and applied before each initial ON4KST user list is published. Reconnects, both categories and all active variants of a base callsign therefore start with the correct state. This resolves [Issue #85](https://github.com/praktimarc/kst4contest/issues/85). -+ -+- **False disconnect during quiet periods:** A valid ON4KST connection is no longer closed merely because the server currently has no activity lines to send. -+ -+### Documentation and packaging -+ -+- The German and English manuals were revised against the implementation. A new contest-workflow chapter connects the individual functions into a practical operating sequence, while the sections on dual chat, private-message handling, QRG synchronisation, Simplelogfile evaluation and configuration were clarified. -+ -+- The website feature pages now describe band and direction opportunities, the station map, QRG handling, filters, global message views, private-message handling and logger synchronisation in more detail. -+ -+- The AUR package definitions were updated for v1.43.0. -+ -+The complete v1.43.0 functionality is available in [Release v1.43.0](https://github.com/praktimarc/kst4contest/releases/tag/v1.43.0). Because its embedded version metadata is inconsistent, v1.43.1 is the recommended package set. -+ -+--- -+ - ## v1.42.0 (2026-08-22) - - **Shared band context, session-based ON4KST connection and signed macOS packages** -@@ -38,21 +104,17 @@ v1.42 brings several previously separate calculations together. Band information - - - **Filter reset:** A dedicated reset button reliably removes the active user-list filter predicates. - --- **Optional map clustering:** **Group nearby stations** immediately enables or disables spatial grouping at lower zoom levels. The automatically stored setting changes neither the viewport nor the selected station; aggregation of active variants sharing one base callsign remains independent. This implements [Issue #79](https://github.com/praktimarc/kst4contest/issues/79). -+- **Map clustering:** Stations close to each other are grouped at lower zoom levels. The selected station and relevant direction opportunities remain individually visible. - - - **Hideable path analysis:** The terrain profile and analysis section of the station map can be hidden completely. The selected state is stored and restored at the next application start. - - ### Changed - --- **Automatic table-layout persistence:** Tables receive useful widths when their first meaningful contents arrive. Manually changed column widths, window sizes and relevant dividers are written to `preferences.xml` after a short delay; the main and monitor windows keep separate DXCluster and QSO-of-the-other layouts. Truncated normal cell values expose their full text in a tooltip without replacing functional tooltips or clickable links. -- --- **Unified DX Cluster line format:** Local spots now use a fixed, DXSpider-compatible 75-character payload line with the DX callsign in column 27, a 30-character comment field and UTC time in column 71. The layout remains stable for microwave frequencies up to 24 GHz. Overlong DX callsigns are rejected and logged instead of being silently truncated; AirScout and test comments are correspondingly more compact. -- - - **Session-based ON4KST connection lifecycle:** Each socket, reader, writer, message bus and queue now belongs to an explicitly identified connection session. Delayed threads from an obsolete connection can therefore no longer process data or close its replacement. `ONLINE` is reported only after the login has been accepted and all requested user lists have been received. Connection setup, login and synchronisation use bounded timeouts, while heartbeats, missing inbound traffic, EOF and read or write failures trigger controlled reconnect attempts with backoff where appropriate. - - - **Validated ON4KST protocol commands:** Outgoing frames are built centrally and checked for valid categories, locators and prohibited frame delimiters. Because ON4KST maintains one locator per TCP session, the main locator is used for both chat categories and a conflicting secondary configuration is logged instead of sending contradictory commands to the server. - --- **More precise QRG recognition:** Complete frequencies are also recognised without a decimal separator, with the final three digits interpreted as the kHz part. Relative frequencies remain unchanged, and bare three-digit numbers still require recognisable frequency context. Signal reports, band designators and unrelated numbers therefore produce fewer false frequencies. -+- **More precise QRG recognition:** Complete and relative frequency references continue to be recognised. Bare three-digit numbers are treated as QRGs only when a frequency context is available. Signal reports, band designators and unrelated numbers therefore produce fewer false frequencies. - - - **Station-specific frequency context:** For relative QRGs, KST4Contest first uses a band context for the same station which is no more than 30 minutes old. The globally configured fallback band is used only when this context is unavailable. - -@@ -86,10 +148,6 @@ v1.42 brings several previously separate calculations together. Band information - - - **DXLog full-log import:** In addition to `contactinfo`, the UCXLog-compatible UDP listener processes `contactreplace`. This allows a complete log broadcast by DXLog.net to be imported. - --- **Consistent logger band values:** Numeric, metre and centimetre values from UCXLog-compatible QSO packets and Win-Test band IDs are normalised once and then used consistently for Worked marks and worked grid squares. In particular, `2320`, `5760` and `10368` now reliably set their existing band marks. A missing or unknown band continues to set only the global Worked status. -- --- **Defined Simplelogfile behaviour:** The selected text file is evaluated once per minute using a fixed callsign pattern. Matches set the global Worked status for all active variants of the base callsign but are not persisted in SQLite. A missing file is created, and read or creation errors do not terminate the periodic task. A database reset does not change the file, so callsigns contained in it are marked as worked again during the next evaluation. -- - - **Guarded automatic QRG updates:** `MYQRG` is updated only by an enabled interface which actually supplies valid `RadioInfo` or Win-Test `STATUS` packets. An enabled source which provides no data does not remove the need for a functional check or manual QRG maintenance. - - - **Improved version comparison:** Versions are compared semantically so that patch releases and Nightly versions are not misclassified by conversion to a floating-point number. -@@ -98,8 +156,6 @@ v1.42 brings several previously separate calculations together. Band information - - - **Reliable initial user list:** Invalid or incomplete `UA0` member records are rejected and logged individually without preventing alphabetically following members from being processed. Valid entries are staged per category and published as one complete snapshot when the first corresponding `UE` end marker is received. - --- **Persisted Worked state during initial-list setup:** At the end of each initial ON4KST user list, the SQLite state is loaded once and applied to the new chat members before publication. This covers both categories, reconnects and every active variant of a base callsign. -- - - **User list disappearing after login:** ON4KST may send additional `UE` frames for the same category after name, state or other live updates. Repeated end markers are now detected and ignored so that an already populated user list cannot be replaced by an empty snapshot. - - - **Failed initial connection and lost sockets:** An unavailable server during startup no longer sends KST4Contest into an endless or busy-wait loop. The user interface remains responsive and further attempts use bounded reconnect backoff. Sockets closed by the server, or connections without inbound traffic for an excessive period, are also detected reliably. -diff --git a/src/main/java/kst4contest/ApplicationConstants.java b/src/main/java/kst4contest/ApplicationConstants.java -index 6da42ff4..71f64575 100644 ---- a/src/main/java/kst4contest/ApplicationConstants.java -+++ b/src/main/java/kst4contest/ApplicationConstants.java -@@ -20,7 +20,7 @@ public class ApplicationConstants { - /** - * Version shown to the user and used for semantic version comparison. - */ -- public static final String APPLICATION_CURRENT_VERSION = "1.431"; -+ public static final String APPLICATION_CURRENT_VERSION = "1.43.1"; - - /** - * Legacy numeric representation used only while older update feeds and -diff --git a/website/src/news/2026-09-03-version-1-43.md b/website/src/news/2026-09-03-version-1-43.md -new file mode 100644 -index 00000000..30754c3d ---- /dev/null -+++ b/website/src/news/2026-09-03-version-1-43.md -@@ -0,0 +1,29 @@ -+--- -+title: Version 1.43.1 released -+summary: Reliable log synchronisation, persistent layouts and better DX Cluster compatibility -+date: 2026-09-03 -+--- -+ -+## Version 1.43.1 -+ -+Version 1.43 focuses on the parts of KST4Contest that have to keep working during a long contest: ON4KST connection monitoring, log synchronisation, Worked information and the data sent to external logging software. -+ -+The first v1.43.0 packages already contained all functional changes described below, but some embedded version metadata still identified the build as version 1.42. v1.43.1 corrects this. If you already downloaded v1.43.0, use v1.43.1 instead. -+ -+### What changed -+ -+- **More reliable log synchronisation:** The Simplelogfile parser now closes the selected file after every pass, handles suffix variants by their base callsign and reports when a missing file has been created. UCXLog-compatible packets and Win-Test events share the same band normalisation, including the existing microwave bands. -+- **Correct Worked state after login:** Persisted Worked information is applied before the initial ON4KST user list becomes visible. Reconnects and both chat categories therefore start with the correct state. -+- **No false disconnect on a quiet server:** KST4Contest actively checks a quiet ON4KST session before treating it as dead. A period without new activity lines no longer causes an unnecessary reconnect. -+- **DX Cluster compatibility:** Local spots now use a fixed, DXSpider-compatible 75-character line format that is also accepted reliably by DXLog. Frequencies up to 24 GHz keep the required column positions. -+- **Layouts that stay where you put them:** Table column widths, window sizes and relevant dividers are saved automatically. Truncated table values expose their full text in a tooltip. -+- **Controllable map grouping:** **Group nearby stations** switches map clustering on or off without changing the current viewport or selected station. -+- **Smaller corrections:** Complete QRGs without a decimal separator are recognised across the supported bands, and private-message age highlighting no longer remains attached to reused table rows. -+ -+The complete technical list is available in the [changelog](/manual/en/changelog/) and the [GitHub release notes](https://github.com/praktimarc/kst4contest/releases/tag/v1.43.1). -+ -+### Getting it -+ -+Packages for Windows, Linux and macOS are available on the [download page](/download/) and in the [GitHub release](https://github.com/praktimarc/kst4contest/releases/tag/v1.43.1). The AUR packages are updated through their normal release workflow. -+ -+The German and English manuals have also been revised. The new contest-workflow chapter connects the individual functions into a practical operating sequence instead of describing them only in isolation. 73 --- -2.51.1 - diff --git a/AGENTS.md b/AGENTS.md index 54da6081..098ff61b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -4,18 +4,18 @@ These project instructions extend Marc's global Codex working agreements. ## Project identity -KST4Contest is a Java/JavaFX desktop client for ON4KST chat with contest-oriented workflows and integrations including logging software, AirScout, rotor control, DXCluster and local persistence. +KST4Contest is a Java/Kotlin desktop client for ON4KST chat, with a Compose Multiplatform user interface with contest-oriented workflows and integrations including logging software, AirScout, rotor control, DXCluster and local persistence. Primary repository areas: -- `src/main/java/kst4contest/` -- `src/test/` where present; +- `core/src/main/java/kst4contest/` and `core/src/test/` +- `app-desktop/src/main/java/kst4contest/` and `app-desktop/src/test/` - `github_docs/` - `website/` - `docs/` - `packaging/` - `.github/` -- `pom.xml` +- `build.gradle.kts`, `settings.gradle.kts`, `gradle.properties`, `gradle/` Inspect the current tree before assuming an exact class/path still exists. @@ -43,13 +43,13 @@ If an answer is uncertain, do not interpolate it. Check current code/tests/docs/ - Commit messages are concise English when a commit is explicitly requested. - User-facing DE/EN documentation follows `$praktimarc-writing-style`. -## Java and JavaFX architecture +## Java and user-interface architecture - Preserve or improve separation between network/parsing/service/controller/UI responsibilities. -- Do not solve architecture problems by letting worker/model code directly manipulate JavaFX UI collections. -- Active chat-member domain state is conceptually thread-safe state; JavaFX `ObservableList` data is a UI projection, not the canonical worker-thread store. -- `MessageBusManagementThread` must not directly read or mutate the JavaFX `ObservableList` used by the UI. -- Route UI-visible mutations through the controller and the JavaFX Application Thread (`Platform.runLater` or the project's equivalent helper). +- Do not solve architecture problems by letting worker/model code directly manipulate user-interface collections. +- Active chat-member domain state is conceptually thread-safe state and lives in an `ObservableRoster` in `core`; the `ObservableList` a `TableView` is bound to is a mirror of it, not the store. +- `MessageBusManagementThread` must not directly read or mutate the row lists the user interface draws from; it works on snapshots. +- Route UI-visible mutations through the controller and the `UiDispatcher` (`AwtUiDispatcher` hands them to the AWT event dispatch thread, where Compose draws). Do not reach for a toolkit thread call such as `Platform.runLater` or `EventQueue.invokeLater` in `core`; it has no toolkit dependency. - Prefer explicit DTOs over records when introducing transport/parser DTOs in this codebase unless the approved concept says otherwise. - Handle incomplete external/historical data defensively. - `qrb`, QTF and related external values can be absent. `null` means unavailable, not zero. @@ -96,9 +96,10 @@ Never change CR/LF, XML framing, callsign normalization, frequency formatting or - If no send category is selected, preserve the established Main-category fallback unless explicitly changed. - Null/unknown data must render as unavailable/empty according to current UI conventions, not as fake zero values. -## WebView / map compatibility +## Map -- The Leaflet WebView workaround that disables problematic CSS 3D transforms before Leaflet loads is a known Java 21 stability measure. Do not remove or reorder it without reproducing and understanding the original rendering/flicker problem. +- The station map is a Compose canvas. It fetches its tiles directly; the former JavaFX WebView, the bundled Leaflet resources, the CSS-3D-transform workaround and the `TileProxyServer` that worked around the WebView's TLS behaviour in AppImage and Flatpak packaging are all gone. +- Map reset clears the selected target without changing the zoom. Offline DEM, terrain packages and the profile cache must keep working unchanged. ## Autoanswer / beacon safety @@ -111,22 +112,22 @@ Never change CR/LF, XML framing, callsign normalization, frequency formatting or ## Build and verification -Use the Maven wrapper. +Use the Gradle wrapper. Windows: ```text -.\mvnw.cmd ... +.\gradlew.bat ... ``` -Read the current `pom.xml` before relying on version numbers. +Read the current `gradle.properties` and `gradle/libs.versions.toml` before relying on version numbers. -At the package creation snapshot the project uses Java 21 / JavaFX 21.x and JUnit 5/Mockito, with PMD and SpotBugs integrated. +At this context snapshot the project uses Java 21, Kotlin 2.2 and Compose Multiplatform 1.8.x, with JUnit 5/Mockito, PMD and SpotBugs integrated. JavaFX is gone; there is no `org.openjfx` dependency left. -Important: Maven/Surefire configuration has historically allowed test failures to be ignored, and static-analysis findings may not fail the build. Therefore: +Important: the build configuration has historically allowed test failures to be ignored, and static-analysis findings do not fail the build. Therefore: -- inspect the Maven test summary; -- inspect Surefire results when needed; +- inspect the Gradle test summary; +- inspect the test-results XML under `*/build/test-results/` when needed; - do not infer "all tests passed" from exit code 0; - report PMD/SpotBugs findings that are visible in the relevant build. diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 00000000..bea000b7 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,51 @@ +# CLAUDE.md + +Diese Datei gilt für Claude Code in diesem Repository. + +## Projektregeln + +Die fachlichen und stilistischen Regeln stehen in **[AGENTS.md](AGENTS.md)** und +**[docs/PROJECT_CONTEXT.md](docs/PROJECT_CONTEXT.md)**. Beide sind verbindlich und +werden hier nicht wiederholt. Besonders wichtig: Kommunikation auf Deutsch, +Quelltextkommentare und Javadoc auf Englisch, und das Konzept-vor-Umsetzung-Vorgehen +aus dem Abschnitt „Mandatory interaction rule" in `AGENTS.md`. + +## Subagenten + +Subagenten (Agent-Tool) dürfen ohne Rückfrage genutzt werden, wenn eine Aufgabe +davon profitiert — insbesondere für Abschlussprüfungen ganzer Zweige und für +umfangreiche Umbauten, bei denen ein frischer Blick pro Teilaufgabe etwas wert ist. + +Nicht sinnvoll bei kleinen, aufeinander aufbauenden Schritten: dort liest jeder +neue Subagent die Codebasis von null und kostet mehr, als er beiträgt. + +## Build + +Gradle, nicht Maven. `./gradlew clean build`, Java 21. Das Projekt besteht aus +drei Modulen: `core` (Fachlichkeit), `app-desktop` (Oberfläche) und +`i18n-generator` (reines Bauwerkzeug, das aus den Übersetzungsdateien Kotlin +erzeugt und **nicht ausgeliefert** wird). Paketnamen sind über `core` und +`app-desktop` hinweg dieselben. + +## Sprache + +Kommunikation auf Deutsch, in **neuer Rechtschreibung** — `muss` und `dass`, +nicht `muß` und `daß`. Quelltextkommentare und Javadoc bleiben ausschließlich Englisch. + +Oberflächentexte stehen seit Etappe 9 in `app-desktop/src/main/i18n/strings_.properties` +und nicht mehr im Quelltext. Wer dort etwas ändert: der Erzeuger prüft beim Bau, und die +Regel, was übersetzt wird, steht in `docs/PROJECT_CONTEXT.md` unter „Important Decisions". + +## Laufende Arbeit + +Spezifikationen liegen unter `docs/superpowers/specs/` und bleiben: sie sagen, **warum** die +Architektur so ist, und das steht nirgends sonst. Umsetzungspläne werden nach der Ausführung +entfernt — sie sind Arbeitsanweisungen für erledigte Arbeit, und ein liegengebliebener Plan +liest sich für den Nächsten wie eine offene Absicht. Was aus ihnen zu behalten war, steht in +den Commit-Nachrichten und in `docs/PROJECT_CONTEXT.md`. Die Ablösung von JavaFX durch Compose Multiplatform ist +**abgeschlossen**: unter `src/main` steht kein `javafx.` mehr, und `org.openjfx` ist +aus `app-desktop/build.gradle.kts` und `gradle/libs.versions.toml` entfernt. Die +Begründungen und die harten Lehren stehen in +`docs/superpowers/notes/2026-10-01-javafx-lebendbefund.md`; die wichtigste: ein +blockierendes Warten auf dem AWT-Ereignisfaden verklemmt die Oberfläche, und der grüne +Build sagt über Fadenzugehörigkeit nichts. diff --git a/README.md b/README.md index 62812d86..69267a46 100644 --- a/README.md +++ b/README.md @@ -57,26 +57,24 @@ Changes to operating behaviour should be documented together with their purpose ## Building from source -Building KST4Contest requires JDK 21. The Maven Wrapper included in the repository should be used, so a separate Maven installation is not required. +Building KST4Contest requires JDK 21. The Gradle Wrapper included in the repository should be used, so a separate Gradle installation is not required. Linux and macOS: ```bash -./mvnw clean test -./mvnw -B -DskipTests compile +./gradlew clean build ``` Windows: ```powershell -mvnw.cmd clean test -mvnw.cmd -B -DskipTests compile +.\gradlew.bat clean build ``` ## Repository structure -- `src/main/java/` – application source code -- `src/test/` – automated tests +- `core/` – domain, controller and network code, free of user-interface technology +- `app-desktop/` – the Compose Multiplatform user interface and the packaging tasks - `github_docs/` – German and English manual sources - `website/` – project website sources - `packaging/` – platform-specific packaging files diff --git a/app-desktop/build.gradle.kts b/app-desktop/build.gradle.kts new file mode 100644 index 00000000..348ca0cf --- /dev/null +++ b/app-desktop/build.gradle.kts @@ -0,0 +1,157 @@ +plugins { + java + alias(libs.plugins.kotlinJvm) + alias(libs.plugins.composeCompiler) + alias(libs.plugins.composeMultiplatform) +} + +kotlin { + jvmToolchain(21) +} + +dependencies { + // Mirrors the compile-scope entries in pom.xml: a few test classes still live under + // src/main/java and need JUnit and Mockito on the main compile classpath. + implementation(libs.junit.jupiter.api) + implementation(libs.mockito.core.compile) + implementation(libs.jetbrains.annotations) + implementation(project(":core")) + implementation(compose.desktop.currentOs) + implementation(compose.material3) + implementation(libs.sqlite.jdbc) + implementation(libs.jlayer) + /* + * The Compose UI test harness, used through runComposeUiTest { } from ordinary Jupiter + * tests. Deliberately NOT ui-test-junit4: that one brings the vintage engine, and two + * engines on one classpath is how half a suite silently stops being run. Checked after + * adding this: the only engine resolved is junit-jupiter-engine. JUnit 4 classes are on + * the test classpath, but they were before this too — something else pulls them + * transitively — and with no vintage engine nothing executes them. + * + * The accessor is marked experimental by the Compose Gradle plugin, so the opt-in sits + * here — one place, for one dependency. What it buys is the only mechanism that can + * answer "did the value reach the screen": the state-level tests and the two settings + * coverage nets check that a setter is called, which is a different question. + */ + @OptIn(org.jetbrains.compose.ExperimentalComposeLibrary::class) + testImplementation(compose.uiTest) + testImplementation(libs.junit.jupiter) + testImplementation(libs.mockito.core) + testImplementation(libs.mockito.junit.jupiter) + // Gradle 9 no longer adds the launcher implicitly. + testRuntimeOnly(libs.junit.platform.launcher) +} + +/* + * The translation files are turned into Kotlin before anything compiles, by the + * :i18n-generator module. Two consequences worth naming: + * + * - A broken translation fails `./gradlew classes`, which is what the PR workflow already + * runs -- so a contributor's mistake is reported in their pull request without a new + * workflow existing for it. + * - The generator is reached through its own configuration, not through `implementation`, so + * it stays out of the application's runtime classpath and out of the jar. + */ +val i18nGenerator: Configuration by configurations.creating + +dependencies { + i18nGenerator(project(":i18n-generator")) +} + +val generatedI18nDirectory = layout.buildDirectory.dir("generated/i18n") + +val generateStrings by tasks.registering(JavaExec::class) { + description = "Generates Strings.kt from app-desktop/src/main/i18n" + group = "build" + + classpath = i18nGenerator + mainClass.set("kst4contest.i18n.GeneratorMain") + + val input = layout.projectDirectory.dir("src/main/i18n") + inputs.dir(input) + outputs.dir(generatedI18nDirectory) + + argumentProviders.add(CommandLineArgumentProvider { + listOf(input.asFile.absolutePath, generatedI18nDirectory.get().asFile.absolutePath) + }) +} + +kotlin.sourceSets["main"].kotlin.srcDir(generatedI18nDirectory) + +tasks.named("compileKotlin") { dependsOn(generateStrings) } + +compose.desktop { + application { + // Main forwards to Kst4ContestApplication.main. It was a workaround for + // launching a JavaFX Application subclass from the classpath; it stays because + // the packaged launchers and the AUR/Flatpak wrappers name this class. + mainClass = "kst4contest.view.Main" + + nativeDistributions { + /* + * Only the formats the building machine can actually produce. Compose rejects a + * foreign one while CONFIGURING the project, not while packaging it, so a list + * naming all five made every Gradle task fail on macOS and Windows — including + * `run` and `test`, which package nothing. The build was Linux-only without + * anyone having decided that. + */ + val host = org.gradle.internal.os.OperatingSystem.current() + targetFormats( + *when { + host.isMacOsX -> arrayOf( + org.jetbrains.compose.desktop.application.dsl.TargetFormat.Dmg, + ) + host.isWindows -> arrayOf( + org.jetbrains.compose.desktop.application.dsl.TargetFormat.Msi, + ) + else -> arrayOf( + org.jetbrains.compose.desktop.application.dsl.TargetFormat.AppImage, + org.jetbrains.compose.desktop.application.dsl.TargetFormat.Deb, + org.jetbrains.compose.desktop.application.dsl.TargetFormat.Rpm, + ) + } + ) + /* + * jlink must come from JDK 21, not from whatever the Gradle JVM is. + * jdk.jsobject was removed after 21, and this machine has 26 on PATH; + * Etappe 1 hit the same wall with jpackage. + */ + javaHome = javaToolchains.launcherFor { + languageVersion.set(JavaLanguageVersion.of(21)) + }.get().metadata.installationPath.asFile.absolutePath + + /* + * KST4Contest and not praktiKST: this one name drives the app-image + * directory, the launcher, the .app bundle, the bundled icon file + * and -- lowercased -- the deb/rpm package name. Every packaging + * consumer already uses KST4Contest there (AppRun, the Arch and + * Flatpak wrappers, the AUR PKGBUILDs, build-signed-dmg.sh), and the + * shipped deb/rpm must keep the package identity "kst4contest" so an + * installed copy still upgrades. + */ + packageName = "KST4Contest" + packageVersion = providers.gradleProperty("composePackageVersion").get() + + /* + * Kept from the former module-info.java. jdk.jsobject went with the map + * bridge: it carried netscape.javascript, and nothing imports that any + * more. jdk.unsupported stays — its justification used to be the JavaFX + * Marlin renderer, but sun.misc.Unsafe is reached by other dependencies + * too, and dropping it is a separate decision from removing JavaFX. + */ + modules( + "java.desktop", "java.net.http", "java.sql", + "jdk.crypto.ec", "jdk.net", + "jdk.xml.dom", "jdk.unsupported", + ) + + linux { iconFile.set(rootProject.file("packaging/icons/kst4contest.png")) } + windows { iconFile.set(rootProject.file("packaging/icons/kst4contest.ico")) } + macOS { + iconFile.set(rootProject.file("packaging/icons/kst4contest.icns")) + // Must stay de.x08.KST4Contest: build-signed-dmg.sh signs against it. + bundleID = "de.x08.KST4Contest" + } + } + } +} diff --git a/app-desktop/src/main/i18n/strings_de.properties b/app-desktop/src/main/i18n/strings_de.properties new file mode 100644 index 00000000..c994505a --- /dev/null +++ b/app-desktop/src/main/i18n/strings_de.properties @@ -0,0 +1,380 @@ +# German. Held complete by a test, because this is a shipped language. +airscout.applyHint=Serverkennung, Clientkennung und Frequenzmodus wirken sofort. Nach einer Änderung des UDP-Ports neu verbinden. +airscout.automaticFrequency=AirScout-Frequenz je Station automatisch wählen +airscout.automaticHint=Die automatische Wahl nimmt zuerst die aktuelle QRG der Station, dann Hinweise aus Stationsname und Chat-Kategorie. Nur abschalten, um für jede Station einen festen Protokollwert zu erzwingen. +airscout.clientIdentifier=KST4Contest-Clientkennung [KST]: +airscout.enabled=AirScout-UDP-Anbindung aktivieren (AirScout 0.9.9.5 oder neuer) +airscout.forcedBand=Fester AirScout-Bandwert [1440000 = 144 MHz]: +airscout.frequencySection=Abgefragte Frequenz +airscout.serverIdentifier=AirScout-Serverkennung [AS]: +airscout.udpPort=AirScout-UDP-Port [9872] — nach Änderung neu verbinden: +airscout.udpSection=AirScout-UDP-Kommunikation +alert.ok=OK +beacon.enabled=Die Bake in dieser Kategorie senden +beacon.intervalMinutes=Abstand in ganzen Minuten +beacon.intervalSection=Gemeinsamer Abstand +beacon.message=Bakentext +beacon.sectionFor=CQ-Bake für {0} +connection.connect=Verbinden +connection.connectTo=Mit {0} verbinden +connection.disconnect=Trennen +connection.disconnectAndCloseChat=Trennen & Chat schließen +dialog.cancel=Abbrechen +dialog.ok=OK +gui.bandColumnHints=Hinweise in den Bandspalten +gui.language=Sprache +gui.language.system=Systemsprache +gui.startupDesign=Design beim Start +gui.startupFilters=Beim Start aktive Nachrichtenfilter +logSynch.fileChooserTitle=Nur-Lese-Loginterpreter-Datei wählen +logSynch.fileEnabled=Gearbeitete Rufzeichen regelmäßig aus einer Logdatei lesen (ohne Bandangabe) +logSynch.fileLabel=Zu überwachende Logdatei: +logSynch.fileSection=Dateiabfrage für gearbeitete Rufzeichen +logSynch.networkEnabled=QSO-Nachrichten von N1MM+, QARTEST, UCXLog und DXLog.net verarbeiten +logSynch.networkSection=Netzbasierter QSO-Abgleich (N1MM/QARTEST/UCXLog/DXLog) +logSynch.sharedPort=Gemeinsamer UDP-Port für QSO- und TRX-Nachrichten [Vorgabe 12060]: +logSynch.winTestBroadcast=UDP-Broadcast-Adresse für Win-Test (Vorgabe = Broadcast der Internetschnittstelle) +logSynch.winTestEnabled=Win-Test-UDP-Lognachrichten aus dem Netz empfangen +logSynch.winTestHint=Die Broadcast-Adresse wird einmal ermittelt, solange sie noch {0} ist. Eine Portänderung wirkt auf den laufenden Empfänger, sobald das Feld den Fokus verliert. +logSynch.winTestPort=UDP-Port für den Win-Test-Empfänger (Vorgabe ist 9871) +logSynch.winTestSection=Win-Test-Netzwerkempfänger +logSynch.winTestStationName=KST-Stationsname im Win-Test-Netz (Quelle der SKED-Pakete) +menu.about=Über... +menu.contactAuthor=Den Autor per Standard-Mailprogramm anschreiben +menu.disconnect=Trennen +menu.donateOv3t=OV3Ts Flugzeug-Datendienst unterstützen +menu.donatePayPal=Entwicklung von kst4Contest per PayPal unterstützen +menu.exitAndDisconnect=Beenden + trennen +menu.file=Datei +menu.hideMonitor=Cluster- / Fremd-QSOs ausblenden +menu.hideOptions=Optionen ausblenden +menu.homepage=DARC-X08-Homepage besuchen +menu.info=Info +menu.newsgroup=kst4Contest-Newsgroup beitreten +menu.options=Optionen +menu.setQrgAsNameInChat=QRG als Namen im Chat setzen (Hauptkategorie) +menu.showMeAsActive=Mich als AKTIV im Chat zeigen! +menu.showMeAsAway=Mich als ABWESEND vom Chat zeigen! +menu.showMonitor=Cluster- / Fremd-QSOs anzeigen +menu.showOptions=Optionen anzeigen +menu.switchOperatorProfile=Operatorprofil wechseln... +menu.toggleStationMap=Stationskarte ein-/ausblenden +menu.useDarkDesign=Abenddesign verwenden +menu.useDefaultDesign=Tagdesign verwenden +menu.windows=Fenster +messageHandling.autoAnswerEnabled=Privatnachrichten automatisch beantworten +messageHandling.autoAnswerSection=Automatische Antwort auf Privatnachrichten +messageHandling.autoAnswerText=Antworttext +messageHandling.qrgAnswerEnabled=Eine QRG-Anfrage mit der aktuellen Frequenz beantworten +messageHandling.qrgAnswerSection=Automatische Antwort auf eine QRG-Anfrage +messageHandling.debugToFileEnabled=Die vollständige Sitzung in eine Datei aufzeichnen +messageHandling.debugToFileHint=Zeichnet den kompletten ON4KST-Sende- und Empfangsverkehr in Messagehistory.raw auf und schreibt zusätzliche Diagnosedetails in kst4contest-errors.log. Anmeldepasswörter werden geschwärzt. Warnungen und Fehler werden immer protokolliert. +messageHandling.diagnosticsSection=Diagnose +notification.addCallsignToList=Ein Rufzeichen zur Überwachungsliste hinzufügen +notification.addMonitored=Überwachtes Rufzeichen hinzufügen +notification.bandUpgradeHint=Auf einen möglichen Bandwechsel hinweisen, wenn ein QSO geloggt wird +notification.bandUpgradePriority=Die Priorität einer Station mit möglichem Bandwechsel anheben +notification.bandUpgradeSection=Hinweise auf Bandwechsel +notification.callsign=Rufzeichen +notification.clusterEnabled=Den DX-Cluster-Server betreiben +notification.clusterPort=TCP-Port +notification.clusterSection=Lokaler DX-Cluster-Server +notification.cwCallsign=Das Rufzeichen bei einer empfangenen Privatnachricht in CW geben +notification.fallbackBand=Ersatzband für ein Spot ohne Bandangabe +notification.monitoringSection=QSO-Überwachung +notification.sendTestSpot=Ein Testspot senden +notification.simpleSounds=Einfache Töne abspielen +notification.soundsSection=Töne +notification.speakCallsign=Das Rufzeichen bei einer empfangenen Privatnachricht ansagen +notification.spotterCallsign=Spotter-Rufzeichen +settings.applyAndClose=Übernehmen/Schließen +settings.save=Einstellungen speichern +shortcuts.addButton=Kurztaste hinzufügen +shortcuts.addSnippet=Neuen Textbaustein hinzufügen +shortcuts.buttonsSection=Kurztastenknöpfe über dem Nachrichtenfeld +shortcuts.snippetsSection=Textbausteine (die ersten 10 über Strg+1 bis Strg+0) +station.bandsSection=Aktive Bänder +station.beamWidth=Öffnungswinkel der Antenne, Grad +station.callsign=Rufzeichen +station.chatSection=Chat-Kategorie +station.defaultsSection=Vorgaben +station.demDirectory=DEM-Stammverzeichnis +station.locator=Locator +station.mainCategory=Hauptkategorie +station.maxQrb=Maximaler QRB +station.nameMain=Name, Hauptkategorie +station.nameSecond=Name, zweite Kategorie +station.ownAntennaGain=Eigener Antennengewinn, dBi +station.ownAntennaHeight=Eigene Antennenhöhe, Meter +station.ownSection=Eigene Station +station.ownTxPower=Eigene Sendeleistung, Watt +station.password=Passwort +station.pathSection=Vorgaben für die Streckenanalyse +station.qtf=QTF +station.rotatorEnabled=Rotorabgleich aktiv +station.rotatorHost=Rotor-Host +station.rotatorPort=Rotor-Port +station.rotatorSection=PSTRotator +station.secondCategory=Zweite Kategorie +station.secondChatEnabled=2. Chat: in einer zweiten Kategorie anmelden +station.serverHost=Servername +station.serverPort=Serverport +station.serverSection=ON4KST-Server +station.targetAntennaGain=Antennengewinn der Gegenstation, dBi +station.targetTxPower=Sendeleistung der Gegenstation, Watt +trxSynch.hint=Eine aktivierte Quelle erzeugt von sich aus keine Frequenz. Die eigene QRG wird erst aktualisiert, wenn tatsächlich gültige RadioInfo- oder Win-Test-STATUS-Daten eintreffen; bis dahin bleibt sie so, wie sie von Hand eingetragen wurde. +trxSynch.hintSection=Was eine aktivierte Quelle bewirkt +trxSynch.ucxEnabled=MYQRG aus RadioInfo-Nachrichten auf dem gemeinsamen Log-Sync-Port aktualisieren +trxSynch.ucxSection=UCXLog-TRX-Infos empfangen +trxSynch.winTestEnabled=Win-Test-STATUS-QRG-Abgleich (aktualisiert die eigene QRG aus der Win-Test-Transceiverfrequenz) +trxSynch.winTestPassFrequency=Durchgangsfrequenz aus Win-Test-STATUS verwenden (statt der eigenen QRG) +trxSynch.winTestSection=Win-Test-TRX-Abgleich +trxSynch.winTestStationFilter=Win-Test-Stationsnamenfilter (z. B. STN1, leer = alle annehmen) +worked.empty=Die Datenbank enthält keine Rufzeichen. +worked.expiryHint=Worked-, NOT-QRV- und Feldangaben verfallen nach drei Tagen von selbst. Ein Zurücksetzen vor jedem Contest ist normalerweise nicht nötig. +worked.lastResetAffected=Das letzte Zurücksetzen betraf {0} Zeilen. +worked.refresh=Datenbank neu einlesen +worked.reset=Worked-, NOT-QRV- und Feldangaben zurücksetzen... +worked.resetConfirm=Daten zurücksetzen +worked.resetDialogBody=Alle Worked-, NOT-QRV- und Feldangaben zurücksetzen?\n\nDas löscht jede contestbezogene Markierung in der internen Datenbank. Vor jedem Contest ist das normalerweise nicht nötig, weil diese Angaben nach drei Tagen verfallen. +worked.resetDialogTitle=Contestdaten zurücksetzen +worked.resetFailed=Die Contestdaten konnten nicht zurückgesetzt werden. Die interne Datenbank ist möglicherweise nicht erreichbar oder inkonsistent. Es wurde kein erfolgreiches Zurücksetzen bestätigt. +worked.section=Datenbank gearbeiteter Stationen +tab.station=Station +tab.logSynch=Log-Abgleich +tab.trxSynch=TRX-Abgleich +tab.airscout=Airscout +tab.notification=Hinweise +tab.shortcuts=Kurztasten +tab.beacon=Bake +tab.messageHandling=Nachrichten +tab.workedDatabase=Worked-Datenbank +tab.gui=GUI +tab.profiles=Profile +tab.colours=Farben +settings.categoryMainFallback=Haupt-Chat-Kategorie +settings.categorySecondFallback=Zweite Chat-Kategorie +settings.spotNeedsConnection=Zuerst KST4Contest verbinden und den lokalen DX-Cluster-Server einschalten. +settings.spotNoClient=Es ist kein DX-Cluster-Client mit KST4Contest verbunden. +settings.spotNotDelivered=Das Testspot konnte nicht zugestellt werden. +settings.writeFailed=Die Konfigurationsdatei konnte nicht geschrieben werden. Die Einstellungen bleiben für diese Sitzung aktiv. +settings.writtenTo=Die Einstellungen sind als Vorgabe in der XML-Konfigurationsdatei gespeichert:\n{0} +profiles.active=Aktives Profil: +profiles.settingsFile=Einstellungsdatei: +profiles.workedStations=Gearbeitete Stationen: +profiles.new=Neues Profil... +profiles.duplicate=Duplizieren... +profiles.rename=Umbenennen... +profiles.delete=Löschen... +profiles.changeWorked=Gearbeitete Stationen ändern... +profiles.switchTo=Zum gewählten Profil wechseln... +profiles.explanation=Jedes Profil hat eigene Einstellungen und ein eigenes Fensterlayout. Ein Profil kann entweder die gemeinsamen gearbeiteten Stationen der Station mitbenutzen — was eine Mehrmann-Station will — oder eigene führen. Beim Duplizieren wird alles übernommen außer Rufzeichen und Passwort, und gearbeitete Stationen nie. +profiles.dialogTitle=Operatorprofile +profiles.none=Kein Operatorprofil eingerichtet. +profiles.columnProfile=Profil +profiles.columnWorked=Gearbeitete Stationen +profiles.columnLastUsed=Zuletzt benutzt +profiles.inUse= (in Benutzung) +profiles.newTitle=Neues Operatorprofil +profiles.newBody=Name und gearbeitete Stationen des neuen Profils +profiles.nameLabel=Profilname, zum Beispiel DN9APW +profiles.create=Profil anlegen +profiles.duplicateTitle=Operatorprofil duplizieren +profiles.duplicateBody=Name des neuen Profils +profiles.duplicateHint=Alles wird übernommen außer Rufzeichen und Passwort. Gearbeitete Stationen werden nie kopiert. +profiles.renameTitle=Operatorprofil umbenennen +profiles.renameBody=Neuer Name des Profils +profiles.renameHint=Dateien und Ordner des Profils werden nicht angefasst. +profiles.deleteTitle=Operatorprofil löschen +profiles.deleteBody=Das Profil "{0}" löschen? +profiles.deleteConfirm=Profil löschen +profiles.workedTitle=Gearbeitete Stationen +profiles.workedBody=Gearbeitete Stationen von "{0}" +profiles.workedHint=Das Umschalten verschiebt keine Daten. Bereits unter der anderen Einstellung gesammelte gearbeitete Stationen bleiben, wo sie sind. +colours.section=Farben dieses Entwurfs +colours.roleWithSource={0} ({1}) +colours.readabilitySection=Lesbarkeit +colours.warning={0} liest sich jetzt mit {1} zu 1, wo dieser Entwurf {2} zu 1 ausliefert. +colours.warningKept=Die Farben werden trotzdem behalten — eine harte Kombination kann gewollt sein. +colours.keepingSection=Diese Farben behalten +colours.keepingHint=Eine Farbe gilt sofort und überall. Den Neustart überlebt sie erst, wenn „Einstellungen speichern" gedrückt wurde. +colours.waysBackSection=Wege zurück +colours.backToPrevious=Zurück zum Stand von vorher ({0}) +colours.discardChanges=Meine Änderungen verwerfen ({0}) +colours.resetToShipped=Auf Auslieferung zurücksetzen ({0}) +colours.fileSection=Die Stilvorlage von Hand bearbeiten +colours.fileReads=Dieser Entwurf liest {0}. Eine oben gesetzte Farbe überstimmt für diese Rolle, was die Datei sagt. +colours.fileAbsent=Dieser Entwurf hat keine eigene Stilvorlage. Eine kann als Ausgangspunkt nach {0} geschrieben werden. +colours.exportButton=Die Stilvorlage dieses Entwurfs in mein Profil schreiben +colours.exportWritten=Nach {0} geschrieben. Bearbeiten und neu starten, um das Ergebnis zu sehen. +colours.exportAlreadyThere={0} ist schon vorhanden und wurde nicht angefasst. +colours.exportFailed=Die Stilvorlage konnte nicht geschrieben werden: {0} +colours.sourceShipped=Auslieferung +colours.sourceFile=Datei +colours.sourceChanged=geändert +colours.roleSurface=Fläche (Menüzeile, ausgewählte Zeilen) +colours.roleWindowSurface=Fensterfläche (die Fenster selbst) +colours.roleFieldInterior=Feldinneres (Felder, Listen, Knöpfe) +colours.roleText=Text +colours.roleAccent=Akzent +colours.roleSeparator=Trennlinie +colours.notAColour='{0}' ist keine Farbe. Sechs Hexadezimalziffern mit führendem Rautezeichen, zum Beispiel #3C7A4B. {1} bleibt unverändert. +column.callsign=Rufzeichen +column.name=Name +column.message=Nachricht +column.time=Zeit +column.lastQrgRx=Letzte QRG RX +column.lastQrgTx=Letzte QRG TX +filter.find=Suchen... +filter.reset=Filter zurücksetzen +filter.showOnlyQrb=Nur QRB [km] <= +filter.showOnlyQtf=Nur QTF: +filter.hideWorked=Gearbeitete ausblenden: +filter.inactiveStations=Inaktive Stationen +filter.onlyNewGrids=Nur neue Felder +filter.gridColour=Feldfarbe +filter.newBands=Neue Bänder +filter.tropo=Tropo >=0dB +selected.none=Keine Station gewählt. +selected.priority=Priorität: +selected.more=mehr +selected.showMessages=Nachrichten zeigen +selected.createSked=Sked anlegen +selected.sked=Sked +selected.skedInMinutes=Sked in (Min.) +selected.skedFail=Sked fehlgeschlagen +selected.remindPmIn=Erinnerungs-PM in +selected.reminderOffsets=Erinnerungsabstände +selected.resetFail=Zurücksetzen fehlgeschlagen +selected.tagNotQrv=Als NOT QRV markieren +selected.band=Band +selected.mode=Mode +selected.lookUpAndShow=Nachschlagen und zeigen +selected.lookupQrz=Auf qrz.com nachschlagen +selected.lookupQrzcq=Auf qrzcq.com nachschlagen +selected.showPathInAs=Strecke in AS zeigen +selected.lastActivity=Letzte Aktivität: {0} (vor {1} Min.) +candidates.title=Stationen mit höchster Priorität +candidates.none=Noch keine Kandidaten. +candidates.doubleClick=Doppelklick auf einen Kandidaten wählt ihn aus. +update.title=Aktualisierungsinformationen +update.available=Aktualisierung verfügbar! +update.installedVersion=Installierte Version: +update.latestVersion=Neueste stabile Version: +update.mainChanges=Wesentliche Änderungen: +update.additionalInformation=Weitere Informationen: +update.download=Herunterladen: +update.openReleasePage=Release-Seite öffnen +update.changeLog=Änderungsprotokoll +update.knownBugs=Bekannte Fehler +update.versions=Versionen +map.title=Stationskarte +map.tab=Karte +map.resetView=Ansicht zurücksetzen +map.groupNearby=Nahe Stationen gruppieren +map.triggerClusterSpot=Cluster-Spot auslösen +map.showPathAnalysis=Streckenanalyse zeigen +map.hidePathAnalysis=Streckenanalyse ausblenden +map.pathAnalysisHidden=Die Streckenanalyse ist ausgeblendet. +map.tilesUnavailable=Kartenkacheln nicht verfügbar — die Netzverbindung prüfen. +path.title=Strecken- und Geländeanalyse +path.selectStation=Eine Station wählen, um Strecken- und Geländeanalyse vorzubereiten. +path.fromLocator=Vom Locator: +path.toLocator=Zum Locator: +path.endpoints=Endpunkte: +path.distanceQtf=Entfernung/QTF: +path.frequency=Frequenz: +path.status=Status: +path.source=Quelle: +path.los=LOS: +path.fresnel=Fresnel: +path.obstruction=Hindernis: +path.radioHorizon=Funkhorizont: +path.terrainHorizon=Geländehorizont: +path.refraction=Refraktion: +path.mechanisms=Mechanismen: +path.assessment=Bewertung: +path.linkBudget=Streckenbilanz: +path.rxPower=Empfangsleistung: +path.cwHint=CW-Hinweis: +chart.noSamples=Keine Profilpunkte verfügbar. +chart.distanceAxis=Entfernung [km] +chart.heightAxis=Höhe [m] +chart.legend=Legende: +chart.terrain=Gelände +chart.los=LOS +chart.fresnel=Fresnel +chart.critical=Kritisch +chart.diffraction=Beugung +chart.home=Eigene +chart.radioHorizonShort=Funkhor. +chart.terrainHorizonShort=Geländehor. +chart.homeRadioHorizon=Eigener Funkhorizont +chart.homeTerrainHorizon=Eigener Geländehorizont +chart.dxRadioHorizon=Funkhorizont der Gegenstation +chart.dxTerrainHorizon=Geländehorizont der Gegenstation +chart.frequency=f = {0} MHz +chart.criticalFresnel=Kritischer Punkt: Fresnel-Eingriff {0} m bei {1} km +chart.criticalLos=Kritischer Punkt: LOS-Freiraum {0} m bei {1} km +chart.diffractionCandidate=Beugungskandidat {0} km, KE ≈ {1} dB +title.connectionLost=VERBINDUNG VERLOREN – neuer Versuch eingeplant +title.connecting=Verbindung zu ON4KST wird aufgebaut… +title.authenticating=Verbunden – Anmeldung bei ON4KST läuft… +title.synchronizing=Verbunden – ON4KST-Chatdaten werden abgeglichen… +title.disconnected=NICHT VERBUNDEN! +status.noConnection=Keine ON4KST-Verbindung +status.linkTooltip=ON4KST-Verbindung: {0}\n{1} +status.linkConnected=🟢 LINK: Verbunden +status.linkConnecting=🟡 LINK: Verbindet… +status.linkDisconnecting=🟡 LINK: Trennt… +status.linkReconnecting=🔴 LINK: Verbindet neu… +status.linkDisconnected=🔴 LINK: Nicht verbunden +picker.title=Operatorprofil wählen +picker.moreThanOne=Es ist mehr als ein Operatorprofil eingerichtet. +picker.start=Starten +picker.quit=Beenden +dialog.yes=Ja +dialog.switchProfile=Profil wechseln +alert.profileTitle=Operatorprofil +alert.profileNotFound=Das angeforderte Operatorprofil wurde nicht gefunden. +alert.profilesTitle=Operatorprofile +alert.onlyOneProfile=Es ist nur ein Operatorprofil eingerichtet. +alert.onlyOneProfileBody=Weitere Profile werden im Einstellungsfenster im Reiter „Profile" angelegt. Jedes Profil behält eigene Einstellungen und ein eigenes Layout und kann die Worked-Datenbank der Station entweder mitbenutzen oder eine eigene führen. +alert.switchProfileTitle=Operatorprofil wechseln +alert.switchProfileQuestion=Zu „{0}" wechseln? +alert.switchProfileBody=Die ON4KST-Verbindung wird geschlossen und alle Fenster werden mit den Einstellungen und dem Layout des gewählten Profils neu aufgebaut.\n\nNicht gespeicherte Einstellungen des aktuellen Profils gehen verloren. Fenstergrößen sowie Teiler- und Spaltenbreiten werden automatisch gesichert. +alert.quitTitle=Anwendung beenden +alert.quitQuestion=Soll die Verbindung zum Chat getrennt werden? +alert.simpleLogTitle=Simplelogfile angelegt +alert.simpleLogHeader=Das gewählte Simplelogfile gab es nicht und wurde angelegt +alert.simpleLogBody=Datei: {0}\n\nPrüfe zuerst, ob du die Simplelogfile-Anbindung überhaupt brauchst. Bietet dein Logprogramm eine unterstützte Netzschnittstelle, nutze diese für Band- und Locatorangaben.\n\nWenn du Simplelogfile benutzt, stelle dein Logprogramm so ein, dass es sein laufendes Log in diese Datei schreibt. Logge dann ein Test-QSO und prüfe, ob das Rufzeichen in KST4Contest binnen einer Minute als gearbeitet markiert wird.\n\nPrüfe vor jedem Contest, dass das Logprogramm das aktuelle Contestlog in genau diese Datei schreibt. KST4Contest setzt aus Simplelogfile stammende Worked-Markierungen zum Contestbeginn nicht von selbst zurück. +alert.simpleLogLink=Das Simplelogfile-Handbuch öffnen +tooltip.bandsNone=Bänder: - +tooltip.bandsPrefix=Bänder: +tooltip.bandStatusLegend=Bandstatus:\nX = auf diesem Band gearbeitet\nB+ = Band verfügbar, auf diesem Band noch nicht gearbeitet (Rufzeichen auf einem anderen Band bereits gearbeitet)\na = Band verfügbar, Rufzeichen auf keinem Band gearbeitet (in den GUI-Einstellungen abschaltbar; fällt dann auf B+ zurück)\no = Großfeld auf diesem Band bereits gearbeitet, von einer beliebigen Station (in den GUI-Einstellungen abschaltbar)\n(leer) = keine Angaben zu diesem Band\no kann mit den übrigen zusammentreffen, zum Beispiel „ao" oder „B+o" +tooltip.bandStatusThisStation=\n\nDiese Station ({0}):\nStatus: {1} +tooltip.workedStatusLegend=Worked-Status:\nleer = Rufzeichen nicht gearbeitet, Feld nicht gearbeitet\nx = Rufzeichen gearbeitet\no = Feld gearbeitet\nxo = Rufzeichen und Feld gearbeitet +tooltip.workedStatusThisStation=\n\nDiese Station:\nRufzeichen gearbeitet: {0}\nFeld gearbeitet: {1} ({2}) +tooltip.yes=ja +tooltip.no=nein +tooltip.unknownGrid=unbekanntes Feld +tooltip.grid=Feld {0} +messages.public=Öffentliche Nachrichten +messages.dxCluster=DXCluster-Nachrichten +messages.qsoOfTheOther=QSO der Gegenstation +chat.ownQrgTooltip=Die eigene Frequenz in der Hauptkategorie +chat.secondQrgTooltip=Die Frequenz für die zweite Chat-Kategorie von Hand eintragen +chat.qtfTooltip=Die eigene Antennenrichtung (QTF); wird vom Rotor übernommen, wenn einer abgeglichen wird +list.moveDown=Auswahl nach unten +list.moveUp=Auswahl nach oben +list.clearToRemove=Den Text eines Eintrags leeren, um ihn zu entfernen. +column.lastKnownQrg=Letzte bekannte QRG +alert.cannotConnectTitle=Verbinden nicht möglich +alert.credentialsMissing=Anmeldedaten fehlen +alert.credentialsMissingBody=Bitte zuerst Rufzeichen und Passwort in den Einstellungen eintragen. +alert.connectionFailedTitle=Verbindung fehlgeschlagen +alert.connectionFailedBody=Verbinden nicht möglich: {0} +contrast.textOnWindowSurface=Text auf der Fensterfläche +contrast.textInsideField=Text im Feld +contrast.accentOnWindowSurface=Akzent auf der Fensterfläche +contrast.textOnMenuStrip=Text auf der Menüzeile diff --git a/app-desktop/src/main/i18n/strings_en.properties b/app-desktop/src/main/i18n/strings_en.properties new file mode 100644 index 00000000..79d6016e --- /dev/null +++ b/app-desktop/src/main/i18n/strings_en.properties @@ -0,0 +1,389 @@ +# The base language. Every key and every argument count comes from this file. +# +# To contribute a language: copy this file to strings_.properties and translate the +# values to the right of the equals sign. An untranslated key falls back to English, so a +# partial file is welcome. `./gradlew :app-desktop:classes` builds and reports any mistake, +# and writes a worksheet of what is still missing to +# app-desktop/build/generated/i18n/todo/. +# +# Nothing that goes to the ON4KST server or to other radio amateurs belongs in this file -- +# none of it is here, and three tests keep it that way. +airscout.applyHint=Server identifier, client identifier and frequency mode are applied immediately. Reconnect after changing the UDP port. +airscout.automaticFrequency=Select AirScout frequency automatically per station +airscout.automaticHint=Automatic selection uses the station's current QRG first, then station-name and chat-category evidence. Disable it only to force one protocol value for every station. +airscout.clientIdentifier=KST4Contest client identifier [KST]: +airscout.enabled=Enable AirScout UDP integration (AirScout 0.9.9.5 or newer) +airscout.forcedBand=Forced AirScout band value [1440000 = 144 MHz]: +airscout.frequencySection=Queried frequency +airscout.serverIdentifier=AirScout server identifier [AS]: +airscout.udpPort=AirScout UDP port [9872] — reconnect after changing: +airscout.udpSection=AirScout UDP communication +alert.ok=OK +beacon.enabled=Send the beacon in this category +beacon.intervalMinutes=Interval in whole minutes +beacon.intervalSection=Shared interval +beacon.message=Beacon message +beacon.sectionFor=CQ beacon for {0} +connection.connect=Connect +connection.connectTo=Connect to {0} +connection.disconnect=Disconnect +connection.disconnectAndCloseChat=Disconnect & close Chat +dialog.cancel=Cancel +dialog.ok=OK +gui.bandColumnHints=Hints in the band columns +gui.language=Language +gui.language.system=System language +gui.startupDesign=Startup design +gui.startupFilters=Message filters active at startup +logSynch.fileChooserTitle=Choose Readonly-Loginterpreter-File +logSynch.fileEnabled=Read worked callsigns periodically from a log file (without band information) +logSynch.fileLabel=Log file to be monitored: +logSynch.fileSection=File polling for worked callsigns +logSynch.networkEnabled=Process QSO messages from N1MM+, QARTEST, UCXLog and DXLog.net +logSynch.networkSection=Network-based QSO synchronization (N1MM/QARTEST/UCXLog/DXLog) +logSynch.sharedPort=Shared UDP port for QSO and TRX messages [default 12060]: +logSynch.winTestBroadcast=UDP broadcast address for Win-Test (default = internet interface broadcast) +logSynch.winTestEnabled=Receive Win-Test network based UDP log messages +logSynch.winTestHint=The broadcast address is detected once while it is still {0}. A port change takes effect on the running listener when the field loses focus. +logSynch.winTestPort=UDP-Port for Win-Test listener (default is 9871) +logSynch.winTestSection=Win-Test Network-Listener +logSynch.winTestStationName=KST station name in Win-Test network (src of SKED packets) +menu.about=About... +menu.contactAuthor=Contact the author using default mail app +menu.disconnect=Disconnect +menu.donateOv3t=Donate for OV3T´s plane feed service +menu.donatePayPal=Donate for kst4Contest development via PayPal +menu.exitAndDisconnect=Exit + disconnect +menu.file=File +menu.hideMonitor=Hide cluster / stranger QSOs +menu.hideOptions=hide options +menu.homepage=Visit DARC X08-Homepage +menu.info=Info +menu.newsgroup=Join kst4Contest newsgroup +menu.options=Options +menu.setQrgAsNameInChat=Set QRG as name in Chat (main category) +menu.showMeAsActive=Show me as ACTIVE in chat! +menu.showMeAsAway=Show me as AWAY FROM chat! +menu.showMonitor=Show cluster / stranger QSOs +menu.showOptions=Show options +menu.switchOperatorProfile=Switch operator profile... +menu.toggleStationMap=Show / hide station map +menu.useDarkDesign=Use dark mode design +menu.useDefaultDesign=Use default mode design +menu.windows=Windows +messageHandling.autoAnswerEnabled=Answer private messages automatically +messageHandling.autoAnswerSection=Automatic answer to private messages +messageHandling.autoAnswerText=Answer text +messageHandling.qrgAnswerEnabled=Answer a QRG request with the current frequency +messageHandling.qrgAnswerSection=Automatic answer to a QRG request +messageHandling.debugToFileEnabled=Record the whole session to file +messageHandling.debugToFileHint=Records complete ON4KST RX/TX session traffic in Messagehistory.raw and adds diagnostic details to kst4contest-errors.log. Login passwords are redacted. Warnings and errors are always logged. +messageHandling.diagnosticsSection=Diagnostics +notification.addCallsignToList=Add a callsign to the monitoring list +notification.addMonitored=Add monitored callsign +notification.bandUpgradeHint=Hint at a band upgrade when a QSO is logged +notification.bandUpgradePriority=Raise the priority of a station worth upgrading +notification.bandUpgradeSection=Band upgrade hints +notification.callsign=Callsign +notification.clusterEnabled=Run the DX Cluster server +notification.clusterPort=TCP port +notification.clusterSection=Local DX Cluster server +notification.cwCallsign=Play the callsign in CW on a received private message +notification.fallbackBand=Fallback band for a spot without band information +notification.monitoringSection=QSO monitoring +notification.sendTestSpot=Send a test spot +notification.simpleSounds=Play simple sounds +notification.soundsSection=Sounds +notification.speakCallsign=Speak the callsign on a received private message +notification.spotterCallsign=Spotter callsign +settings.applyAndClose=Apply/Close prefs +settings.save=Save settings +shortcuts.addButton=Add shortcut +shortcuts.addSnippet=Add new snippet +shortcuts.buttonsSection=Shortcut buttons above the message field +shortcuts.snippetsSection=Text snippets (the first 10 use Ctrl+1 through Ctrl+0) +station.bandsSection=Active bands +station.beamWidth=Antenna beam width, degrees +station.callsign=Callsign +station.chatSection=Chat category +station.defaultsSection=Defaults +station.demDirectory=DEM root directory +station.locator=Locator +station.mainCategory=Main category +station.maxQrb=Maximum QRB +station.nameMain=Name, main category +station.nameSecond=Name, second category +station.ownAntennaGain=Own antenna gain, dBi +station.ownAntennaHeight=Own antenna height, metres +station.ownSection=Own station +station.ownTxPower=Own TX power, watts +station.password=Password +station.pathSection=Path analysis defaults +station.qtf=QTF +station.rotatorEnabled=Rotator sync enabled +station.rotatorHost=Rotator host +station.rotatorPort=Rotator port +station.rotatorSection=PSTRotator +station.secondCategory=Second category +station.secondChatEnabled=2nd chat: log in to a second category +station.serverHost=Server host name +station.serverPort=Server port +station.serverSection=ON4KST server +station.targetAntennaGain=Target antenna gain, dBi +station.targetTxPower=Target TX power, watts +trxSynch.hint=An enabled source does not produce a frequency by itself. The own QRG is only updated once valid RadioInfo or Win-Test STATUS data actually arrives; until then it stays as entered by hand. +trxSynch.hintSection=What an enabled source does +trxSynch.ucxEnabled=Update MYQRG from RadioInfo messages received on the shared log-sync port +trxSynch.ucxSection=Receive UCXLog TRX info +trxSynch.winTestEnabled=Win-Test STATUS QRG Sync (updates own QRG from Win-Test transceiver frequency) +trxSynch.winTestPassFrequency=Use pass frequency from Win-Test STATUS (instead of own QRG) +trxSynch.winTestSection=Win-Test TRX sync +trxSynch.winTestStationFilter=Win-Test station name filter (e.g. STN1, empty = accept all) +worked.empty=The worked database holds no callsigns. +worked.expiryHint=Worked, NOT-QRV and grid data expire after three days on their own. A reset before every contest is normally not required. +worked.lastResetAffected=Last reset affected {0} rows. +worked.refresh=Refresh worked database +worked.reset=Reset worked, NOT-QRV and grid data... +worked.resetConfirm=Reset data +worked.resetDialogBody=Reset all worked, NOT-QRV and grid data?\n\nThis clears every contest-related flag in the internal database. A reset before every contest is normally not required because these data expire after three days. +worked.resetDialogTitle=Reset contest data +worked.resetFailed=The contest data could not be reset. The internal database may be unavailable or inconsistent. No successful reset was confirmed. +worked.section=Worked station database +tab.station=Station +tab.logSynch=Log synch +tab.trxSynch=TRX synch +tab.airscout=Airscout +tab.notification=Notification +tab.shortcuts=Shortcuts +tab.beacon=Beacon +tab.messageHandling=Messagehandling +tab.workedDatabase=Workedstn database +tab.gui=GUI +tab.profiles=Profiles +tab.colours=Colours +settings.categoryMainFallback=Main chat category +settings.categorySecondFallback=Second chat category +settings.spotNeedsConnection=Connect KST4Contest and enable the local DX Cluster server first. +settings.spotNoClient=No DX Cluster client is connected to KST4Contest. +settings.spotNotDelivered=The test spot could not be delivered. +settings.writeFailed=The configuration file could not be written. The settings stay active for this session. +settings.writtenTo=Settings are stored as default to the xml config file:\n{0} +profiles.active=Active profile: +profiles.settingsFile=Settings file: +profiles.workedStations=Worked stations: +profiles.new=New profile... +profiles.duplicate=Duplicate... +profiles.rename=Rename... +profiles.delete=Delete... +profiles.changeWorked=Change worked stations... +profiles.switchTo=Switch to selected profile... +profiles.explanation=Each profile has its own settings and window layout. A profile can either share the common station worked stations, which is what a multi operator station wants, or keep its own. Duplicating a profile copies everything except callsign and password, and never copies worked stations. +profiles.dialogTitle=Operator profiles +profiles.none=No operator profile configured. +profiles.columnProfile=Profile +profiles.columnWorked=Worked stations +profiles.columnLastUsed=Last used +profiles.inUse= (in use) +profiles.newTitle=New operator profile +profiles.newBody=Name and worked stations of the new profile +profiles.nameLabel=Profile name, for example DN9APW +profiles.create=Create profile +profiles.duplicateTitle=Duplicate operator profile +profiles.duplicateBody=Name of the new profile +profiles.duplicateHint=Everything is copied except callsign and password. Worked stations are never copied. +profiles.renameTitle=Rename operator profile +profiles.renameBody=New name of the profile +profiles.renameHint=Files and folders of the profile are not touched. +profiles.deleteTitle=Delete operator profile +profiles.deleteBody=Delete the profile "{0}"? +profiles.deleteConfirm=Delete profile +profiles.workedTitle=Worked stations +profiles.workedBody=Worked stations of "{0}" +profiles.workedHint=Switching does not move any data. Worked stations already collected under the other setting stay where they are. +colours.section=Colours of this design +colours.roleWithSource={0} ({1}) +colours.readabilitySection=Readability +colours.warning={0} now reads at {1} to 1, where this design ships {2} to 1. +colours.warningKept=The colours are kept either way — a hard combination can be deliberate. +colours.keepingSection=Keeping these colours +colours.keepingHint=A colour applies at once, everywhere. It survives a restart only once Save settings has been pressed. +colours.waysBackSection=Ways back +colours.backToPrevious=Back to how it was ({0}) +colours.discardChanges=Discard my changes ({0}) +colours.resetToShipped=Reset to the shipped colours ({0}) +colours.fileSection=Editing the stylesheet by hand +colours.fileReads=This design reads {0}. A colour set above overrides what the file says for that role. +colours.fileAbsent=This design has no stylesheet of its own. One can be written to {0} as a starting point. +colours.exportButton=Write this design's stylesheet into my profile +colours.exportWritten=Written to {0}. Edit it and restart to see the result. +colours.exportAlreadyThere={0} is already there and was left untouched. +colours.exportFailed=Could not write the stylesheet: {0} +colours.sourceShipped=shipped +colours.sourceFile=from file +colours.sourceChanged=changed +colours.roleSurface=Surface (menu strip, selected rows) +colours.roleWindowSurface=Window surface (the windows themselves) +colours.roleFieldInterior=Field interior (fields, lists, buttons) +colours.roleText=Text +colours.roleAccent=Accent +colours.roleSeparator=Separator line +colours.notAColour='{0}' is not a colour. Six hexadecimal digits with a leading hash, for example #3C7A4B. {1} is unchanged. +column.callsign=Callsign +column.name=Name +column.message=Message +column.time=Time +column.lastQrgRx=Last QRG RX +column.lastQrgTx=Last QRG TX +filter.find=Find... +filter.reset=Reset filters +filter.showOnlyQrb=Show only QRB [km] <= +filter.showOnlyQtf=Show only QTF: +filter.hideWorked=Hide worked: +filter.inactiveStations=Inactive stations +filter.onlyNewGrids=Only new grids +filter.gridColour=Grid color +filter.newBands=New bands +filter.tropo=Tropo >=0dB +selected.none=No station selected. +selected.priority=Priority: +selected.more=more +selected.showMessages=Show messages +selected.createSked=Create sked +selected.sked=Sked +selected.skedInMinutes=Sked in (min) +selected.skedFail=Sked fail +selected.remindPmIn=Remind-PM in +selected.reminderOffsets=Reminder offsets +selected.resetFail=Reset fail +selected.tagNotQrv=Tag not QRV +selected.band=Band +selected.mode=Mode +selected.lookUpAndShow=Look up and show +selected.lookupQrz=Lookup on qrz.com +selected.lookupQrzcq=Lookup on qrzcq.com +selected.showPathInAs=Show path in AS +selected.lastActivity=Last activity: {0} ({1} min ago) +candidates.title=Top priority candidates +candidates.none=No candidates yet. +candidates.doubleClick=Double-click a candidate to select it. +update.title=Update information +update.available=Update available! +update.installedVersion=Installed version: +update.latestVersion=Latest stable version: +update.mainChanges=Main changes: +update.additionalInformation=Additional information: +update.download=Download: +update.openReleasePage=Open release page +update.changeLog=ChangeLog +update.knownBugs=Known bugs +update.versions=Versions +map.title=Station Map +map.tab=Map +map.resetView=Reset view +map.groupNearby=Group nearby stations +map.triggerClusterSpot=Trigger cluster spot +map.showPathAnalysis=Show path analysis +map.hidePathAnalysis=Hide path analysis +map.pathAnalysisHidden=Path analysis is hidden. +map.tilesUnavailable=Map tiles unavailable — check the network connection. +path.title=Path / terrain analysis +path.selectStation=Select a station to prepare path and terrain analysis. +path.fromLocator=From locator: +path.toLocator=To locator: +path.endpoints=Endpoints: +path.distanceQtf=Distance/QTF: +path.frequency=Frequency: +path.status=Status: +path.source=Source: +path.los=LOS: +path.fresnel=Fresnel: +path.obstruction=Obstruction: +path.radioHorizon=Radio horizon: +path.terrainHorizon=Terrain horizon: +path.refraction=Refraction: +path.mechanisms=Mechanisms: +path.assessment=Assessment: +path.linkBudget=Link budget: +path.rxPower=RX power: +path.cwHint=CW hint: +chart.noSamples=No profile samples available. +chart.distanceAxis=Distance [km] +chart.heightAxis=Height [m] +chart.legend=Legend: +chart.terrain=Terrain +chart.los=LOS +chart.fresnel=Fresnel +chart.critical=Critical +chart.diffraction=Diffraction +chart.home=Home +chart.radioHorizonShort=Radio hor. +chart.terrainHorizonShort=Terr. hor. +chart.homeRadioHorizon=Home radio horizon +chart.homeTerrainHorizon=Home terrain horizon +chart.dxRadioHorizon=DX radio horizon +chart.dxTerrainHorizon=DX terrain horizon +chart.frequency=f = {0} MHz +chart.criticalFresnel=Critical point: Fresnel intrusion {0} m @ {1} km +chart.criticalLos=Critical point: LOS clearance {0} m @ {1} km +chart.diffractionCandidate=Diffraction candidate {0} km, KE ≈ {1} dB +title.connectionLost=CONNECTION LOST – reconnect scheduled +title.connecting=Connecting to ON4KST… +title.authenticating=Connected – authenticating with ON4KST… +title.synchronizing=Connected – synchronizing ON4KST chat data… +title.disconnected=DISCONNECTED! +status.noConnection=No ON4KST connection +status.linkTooltip=ON4KST link: {0}\n{1} +status.linkConnected=🟢 LINK: Connected +status.linkConnecting=🟡 LINK: Connecting… +status.linkDisconnecting=🟡 LINK: Disconnecting… +status.linkReconnecting=🔴 LINK: Reconnecting… +status.linkDisconnected=🔴 LINK: Disconnected +picker.title=Select operator profile +picker.moreThanOne=More than one operator profile is configured. +picker.start=Start +picker.quit=Quit +dialog.yes=Yes +dialog.switchProfile=Switch profile +alert.profileTitle=Operator profile +alert.profileNotFound=The requested operator profile was not found. +alert.profilesTitle=Operator profiles +alert.onlyOneProfile=Only one operator profile is configured. +alert.onlyOneProfileBody=Additional profiles are created in the settings window on the "Profiles" tab. Each profile keeps its own settings and layout, and can either share the station worked database or use its own. +alert.switchProfileTitle=Switch operator profile +alert.switchProfileQuestion=Switch to "{0}"? +alert.switchProfileBody=The ON4KST connection is closed and all windows are rebuilt with the settings and layout of the selected profile.\n\nUnsaved settings of the current profile are lost. Window sizes, divider and column widths are saved automatically. +alert.quitTitle=Quit application +alert.quitQuestion=Do you want to disconnect from the Chat? +alert.simpleLogTitle=Simplelogfile created +alert.simpleLogHeader=The selected Simplelogfile did not exist and has been created +alert.simpleLogBody=File: {0}\n\nFirst check whether you need the Simplelogfile integration. If your logging application provides a supported network interface, use that interface for band and locator information.\n\nIf you use Simplelogfile, configure your logging application to write its live log to this file. Then log a test QSO and verify that the callsign is marked as worked in KST4Contest within one minute.\n\nBefore each contest, verify that the logging application writes the current contest log to this exact file. KST4Contest does not reset Simplelogfile-derived Worked marks automatically when a new contest starts. +alert.simpleLogLink=Open the Simplelogfile manual +tooltip.bandsNone=Bands: - +tooltip.bandsPrefix=Bands: +tooltip.bandStatusLegend=Band status:\nX = worked on this band\nB+ = band available, not worked on this band yet (call already worked on another band)\na = band available, call not worked on any band yet (can be turned off in GUI settings; falls back to B+)\no = grid square already worked on this band, by any station (can be turned off in GUI settings)\n(empty) = no information for this band\no can combine with the others, e.g. "ao" or "B+o" +tooltip.bandStatusThisStation=\n\nThis station ({0}):\nStatus: {1} +tooltip.workedStatusLegend=Worked status:\nempty = call not worked, grid not worked\nx = call worked\no = grid worked\nxo = call and grid worked +tooltip.workedStatusThisStation=\n\nThis station:\nCall worked: {0}\nGrid worked: {1} ({2}) +tooltip.yes=yes +tooltip.no=no +tooltip.unknownGrid=unknown grid +tooltip.grid=grid {0} +messages.public=Public messages +messages.dxCluster=DXCluster messages +messages.qsoOfTheOther=QSO of the other +chat.ownQrgTooltip=Your own frequency in the main category +chat.secondQrgTooltip=Enter the frequency for the second chat category by hand +chat.qtfTooltip=Your antenna heading (QTF); read from the rotator when one is synced +list.moveDown=Move selected down +list.moveUp=Move selected up +list.clearToRemove=Clear the text of an entry to remove it. +column.lastKnownQrg=Last known QRG +alert.cannotConnectTitle=Cannot connect +alert.credentialsMissing=Login credentials missing +alert.credentialsMissingBody=Please configure your callsign and password in Settings first. +alert.connectionFailedTitle=Connection failed +alert.connectionFailedBody=Could not connect: {0} +contrast.textOnWindowSurface=Text on the window surface +contrast.textInsideField=Text inside a field +contrast.accentOnWindowSurface=Accent on the window surface +contrast.textOnMenuStrip=Text on the menu strip diff --git a/src/main/java/kst4contest/controller/AppRunner.java b/app-desktop/src/main/java/kst4contest/controller/AppRunner.java similarity index 100% rename from src/main/java/kst4contest/controller/AppRunner.java rename to app-desktop/src/main/java/kst4contest/controller/AppRunner.java diff --git a/src/main/java/kst4contest/test/ChatPreferencesStationMapVisibilityTest.java b/app-desktop/src/main/java/kst4contest/test/ChatPreferencesStationMapVisibilityTest.java similarity index 100% rename from src/main/java/kst4contest/test/ChatPreferencesStationMapVisibilityTest.java rename to app-desktop/src/main/java/kst4contest/test/ChatPreferencesStationMapVisibilityTest.java diff --git a/src/main/java/kst4contest/test/FrequencyTextParserTest.java b/app-desktop/src/main/java/kst4contest/test/FrequencyTextParserTest.java similarity index 100% rename from src/main/java/kst4contest/test/FrequencyTextParserTest.java rename to app-desktop/src/main/java/kst4contest/test/FrequencyTextParserTest.java diff --git a/src/main/java/kst4contest/test/PatternMatcherTest.java b/app-desktop/src/main/java/kst4contest/test/PatternMatcherTest.java similarity index 84% rename from src/main/java/kst4contest/test/PatternMatcherTest.java rename to app-desktop/src/main/java/kst4contest/test/PatternMatcherTest.java index da8ce0cc..3511295b 100644 --- a/src/main/java/kst4contest/test/PatternMatcherTest.java +++ b/app-desktop/src/main/java/kst4contest/test/PatternMatcherTest.java @@ -1,6 +1,6 @@ package kst4contest.test; -import javafx.beans.property.SimpleStringProperty; +import kst4contest.observe.SimpleValue; import kst4contest.controller.Utils4KST; import java.util.regex.Matcher; @@ -107,25 +107,25 @@ public class PatternMatcherTest { int i = 0; - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.775", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.300.2", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144,300.2", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144300.2", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144300,2", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.300", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.300.20", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("300", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString(".300", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString(".300.2", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString(".300.20", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300.2", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300.20", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300,2", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300,20", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300,2", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300.2", new SimpleStringProperty("144"))); - System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("q305", new SimpleStringProperty("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.775", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.300.2", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144,300.2", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144300.2", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144300,2", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.300", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("144.300.20", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("300", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString(".300", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString(".300.2", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString(".300.20", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300.2", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300.20", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300,2", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300,20", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296.300,2", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("1296,300.2", new SimpleValue<>("144"))); + System.out.println(i++ + ": " + Utils4KST.normalizeFrequencyString("q305", new SimpleValue<>("144"))); } } diff --git a/src/main/java/kst4contest/test/Utils4KSTFrequencyTest.java b/app-desktop/src/main/java/kst4contest/test/Utils4KSTFrequencyTest.java similarity index 92% rename from src/main/java/kst4contest/test/Utils4KSTFrequencyTest.java rename to app-desktop/src/main/java/kst4contest/test/Utils4KSTFrequencyTest.java index f42ff657..3029f6c1 100644 --- a/src/main/java/kst4contest/test/Utils4KSTFrequencyTest.java +++ b/app-desktop/src/main/java/kst4contest/test/Utils4KSTFrequencyTest.java @@ -1,6 +1,6 @@ package kst4contest.test; -import javafx.beans.property.SimpleStringProperty; +import kst4contest.observe.SimpleValue; import kst4contest.controller.Utils4KST; import org.junit.jupiter.api.Test; @@ -51,9 +51,9 @@ class Utils4KSTFrequencyTest { } private String convert(String frequency, String fallbackPrefix) { - SimpleStringProperty fallback = fallbackPrefix == null + SimpleValue fallback = fallbackPrefix == null ? null - : new SimpleStringProperty(fallbackPrefix); + : new SimpleValue<>(fallbackPrefix); return Utils4KST.normalizeFrequencyString( frequency, diff --git a/app-desktop/src/main/java/kst4contest/view/ApplicationRuntimeLauncher.java b/app-desktop/src/main/java/kst4contest/view/ApplicationRuntimeLauncher.java new file mode 100644 index 00000000..1522473c --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/ApplicationRuntimeLauncher.java @@ -0,0 +1,101 @@ +package kst4contest.view; + +import kst4contest.controller.ActiveOperatorProfile; +import kst4contest.controller.OperatorProfilePaths; +import kst4contest.controller.OperatorProfileStore; +import kst4contest.model.OperatorProfile; + +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Owns the lifecycle of the running application. + * + *

Switching the operator profile tears the current runtime down completely and builds + * a fresh one in the same process. Rebinding the existing windows is not an option: the + * user interface is built from the chat controller outwards, with several hundred + * references to the active preferences, and many controls are instance fields created + * once. A new {@link Kst4ContestApplication} instance gets fresh controls, which is safe + * here because the class keeps no mutable static state.

+ */ +public final class ApplicationRuntimeLauncher { + + private static final Logger LOGGER = Logger.getLogger(ApplicationRuntimeLauncher.class.getName()); + + private static Kst4ContestApplication currentRuntime; + + private ApplicationRuntimeLauncher() { + // Utility class. + } + + /** + * Registers the runtime that is currently live. + * + * @param runtime the running application instance + */ + public static void setCurrent(final Kst4ContestApplication runtime) { + currentRuntime = runtime; + } + + /** + * Returns the runtime that is currently live. + * + * @return the running application instance, or null before the first startup + */ + public static Kst4ContestApplication getCurrent() { + return currentRuntime; + } + + /** + * Shuts the application down. + * + *

Releases the live runtime's resources explicitly: after a profile switch that is + * no longer the instance the process started with.

+ */ + public static void exitApplication() { + + if (currentRuntime != null) { + currentRuntime.shutdownRuntime(); + } + + System.exit(0); + } + + /** + * Replaces the running runtime with one bound to another operator profile. + * + * @param targetProfile profile to activate + * @return true if the new runtime was built + */ + public static boolean switchProfile(final OperatorProfile targetProfile) { + + if (targetProfile == null) { + return false; + } + + new OperatorProfileStore().recordLastUsed(targetProfile.getProfileId()); + + if (currentRuntime != null) { + currentRuntime.shutdownRuntime(); + } + + ActiveOperatorProfile.set(OperatorProfilePaths.resolve(targetProfile)); + + Kst4ContestApplication nextRuntime = new Kst4ContestApplication(); + + try { + nextRuntime.startRuntime(); + } catch (Exception e) { + // The previous runtime is already gone, so there is nothing left to return to. + LOGGER.log(Level.SEVERE, "Could not start the selected operator profile", e); + Kst4ContestApplication.alertWindowEvent( + "The operator profile could not be started: " + e.getMessage() + + "\n\nKST4Contest has to be closed."); + System.exit(1); + return false; + } + + setCurrent(nextRuntime); + return true; + } +} diff --git a/app-desktop/src/main/java/kst4contest/view/AwtUiDispatcher.java b/app-desktop/src/main/java/kst4contest/view/AwtUiDispatcher.java new file mode 100644 index 00000000..11f33378 --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/AwtUiDispatcher.java @@ -0,0 +1,41 @@ +package kst4contest.view; + +import kst4contest.observe.UiDispatcher; + +import java.awt.EventQueue; + +/** + * The {@link UiDispatcher} backed by the AWT event dispatch thread. + * + *

That is the thread Compose Desktop composes on, so this is where user-interface + * state belongs. The contract is the one {@code JavaFxUiDispatcher} had, down to the + * inline execution: a task handed over from the user-interface thread runs before + * {@link #runOnUi(Runnable)} returns rather than queueing behind work that is already + * pending. Several callers in {@code ChatController} ask {@link #isUiThread()} first and + * rely on exactly that.

+ */ +public class AwtUiDispatcher implements UiDispatcher { + + @Override + public void runOnUi(Runnable task) { + if (EventQueue.isDispatchThread()) { + runGuarded(task); + } else { + EventQueue.invokeLater(() -> runGuarded(task)); + } + } + + @Override + public boolean isUiThread() { + return EventQueue.isDispatchThread(); + } + + private static void runGuarded(Runnable task) { + try { + task.run(); + } catch (RuntimeException e) { + // Must not tear down the AWT event dispatch thread. + System.err.println("[observe] UI task failed: " + e); + } + } +} diff --git a/app-desktop/src/main/java/kst4contest/view/CoalescingTrigger.java b/app-desktop/src/main/java/kst4contest/view/CoalescingTrigger.java new file mode 100644 index 00000000..6730eaa4 --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/CoalescingTrigger.java @@ -0,0 +1,38 @@ +package kst4contest.view; + +import javax.swing.Timer; +import java.util.Objects; + +/** + * Collapses a burst of requests into one run, a fixed delay after the last of them. + * + *

Replaces the JavaFX pause transition the station list used. A + * {@code javax.swing.Timer} fires on the AWT event thread, which is where the user + * interface lives, and {@code restart()} means exactly what that class's + * {@code playFromStart()} meant. The old one needed a running JavaFX toolkit, which the + * application no longer starts.

+ */ +public final class CoalescingTrigger { + + private final Timer timer; + + /** + * @param delayMs how long to wait after the last request + * @param action runs on the user-interface thread once the delay elapses + */ + public CoalescingTrigger(final int delayMs, final Runnable action) { + Objects.requireNonNull(action, "action"); + this.timer = new Timer(delayMs, event -> action.run()); + this.timer.setRepeats(false); + } + + /** Requests a run, restarting the delay. */ + public void trigger() { + timer.restart(); + } + + /** Drops a pending run. Idempotent, and the trigger stays usable afterwards. */ + public void cancel() { + timer.stop(); + } +} diff --git a/app-desktop/src/main/java/kst4contest/view/CommandLineOptions.java b/app-desktop/src/main/java/kst4contest/view/CommandLineOptions.java new file mode 100644 index 00000000..0843817f --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/CommandLineOptions.java @@ -0,0 +1,133 @@ +package kst4contest.view; + +import java.util.List; + +/** + * Command line options of the application. + * + *

The parsed value is additionally kept in a process wide holder. JavaFX only knows + * the parameters of the {@code Application} instance it launched itself, so an instance + * created during a profile switch would see no parameters at all. Parsing once at + * startup and remembering the result avoids that entirely.

+ */ +public class CommandLineOptions { + + /** + * Command line switch selecting the operator profile to start with. + */ + public static final String PROFILE_ARGUMENT = "--profile"; + + /** + * System property used as an alternative to the command line switch. + */ + public static final String PROFILE_SYSTEM_PROPERTY = "kst4contest.profile"; + + /** + * Opens the Compose main window beside the JavaFX one. + * + *

Off unless asked for. The two are meant to run side by side while the operator + * compares them against a live session; until that comparison is done, an ordinary start + * must behave exactly as it did.

+ */ + public static final String COMPOSE_MAIN_WINDOW_ARGUMENT = "--compose-main-window"; + + private static volatile CommandLineOptions rememberedOptions = new CommandLineOptions(null); + + private final String requestedProfileName; + + private final boolean composeMainWindowRequested; + + public CommandLineOptions(final String requestedProfileName) { + this(requestedProfileName, false); + } + + public CommandLineOptions( + final String requestedProfileName, + final boolean composeMainWindowRequested) { + this.composeMainWindowRequested = composeMainWindowRequested; + this.requestedProfileName = requestedProfileName; + } + + /** + * Parses the raw application arguments. + * + *

Unknown arguments are ignored on purpose. A typo in a command line must never + * keep an operator out of the application shortly before a contest.

+ * + * @param rawArguments raw arguments, may be null + * @return the parsed options + */ + public static CommandLineOptions parse(final List rawArguments) { + + String requestedProfileName = null; + boolean composeMainWindow = false; + + if (rawArguments != null) { + for (int argumentIndex = 0; argumentIndex < rawArguments.size(); argumentIndex++) { + String currentArgument = rawArguments.get(argumentIndex); + + if (currentArgument == null) { + continue; + } + + if (COMPOSE_MAIN_WINDOW_ARGUMENT.equals(currentArgument)) { + composeMainWindow = true; + } else if (currentArgument.startsWith(PROFILE_ARGUMENT + "=")) { + requestedProfileName = currentArgument.substring(PROFILE_ARGUMENT.length() + 1); + } else if (PROFILE_ARGUMENT.equals(currentArgument) + && argumentIndex + 1 < rawArguments.size()) { + requestedProfileName = rawArguments.get(argumentIndex + 1); + argumentIndex++; + } + } + } + + if (requestedProfileName == null || requestedProfileName.isBlank()) { + requestedProfileName = System.getProperty(PROFILE_SYSTEM_PROPERTY); + } + + if (requestedProfileName != null && requestedProfileName.isBlank()) { + requestedProfileName = null; + } + + return new CommandLineOptions( + requestedProfileName == null ? null : requestedProfileName.trim(), + composeMainWindow); + } + + /** + * Stores the parsed options for the lifetime of the process. + * + * @param options options to remember + */ + public static void remember(final CommandLineOptions options) { + rememberedOptions = options == null ? new CommandLineOptions(null) : options; + } + + /** + * Returns the options parsed at application startup. + * + * @return the remembered options, never null + */ + public static CommandLineOptions remembered() { + return rememberedOptions; + } + + /** + * Returns the operator profile requested on the command line. + * + * @return the requested profile name, or null when none was given + */ + /** + * Whether the Compose main window should be opened beside the JavaFX one. + * + * @return {@code true} only when --compose-main-window was passed + */ + public boolean isComposeMainWindowRequested() { + return composeMainWindowRequested; + } + + public String getRequestedProfileName() { + return requestedProfileName; + } +} diff --git a/app-desktop/src/main/java/kst4contest/view/ComposeChatInputActions.java b/app-desktop/src/main/java/kst4contest/view/ComposeChatInputActions.java new file mode 100644 index 00000000..cbbe6286 --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/ComposeChatInputActions.java @@ -0,0 +1,100 @@ +package kst4contest.view; + +import kst4contest.model.ChatCategory; +import kst4contest.model.ChatMember; +import kst4contest.model.ChatMessage; +import kst4contest.view.compose.ChatInputActions; + +/** + * What the Compose send line needs from the runtime. + * + *

Every method forwards to the same code the JavaFX send button runs, so that while the two + * windows sit side by side a message sent from either takes exactly one path. The order the + * steps are called in lives in {@code ChatInputState}, where it is tested against the + * original; this class only answers questions.

+ */ +public final class ComposeChatInputActions implements ChatInputActions { + + private final Kst4ContestApplication application; + + public ComposeChatInputActions(final Kst4ContestApplication application) { + this.application = application; + } + + @Override + public ChatMember panelSelection() { + return application.selectedCallSignInfoStageChatMember; + } + + @Override + public ChatMember tableSelection() { + /* + * The JavaFX station table is gone. Kept rather than dropped from the interface + * because ChatInputState's three-step lookup is the documented selection order, and + * a Compose station selection may fill this in again. + */ + return null; + } + + @Override + public ChatMember scoreSelection() { + if (application.chatcontroller == null + || application.chatcontroller.getScoreService() == null) { + return null; + } + return application.chatcontroller.getScoreService().getSelectedChatMember(); + } + + @Override + public String resolveVariables(final String template, final ChatMember member) { + if (application.messageVariableResolver == null) { + return template; + } + return application.messageVariableResolver.resolveForSelectedStation(template, member); + } + + @Override + public boolean isAddressedToOwnCallsign(final String text) { + return application.isMessageAddressedToOwnCallsignFromCompose(text); + } + + @Override + public ChatCategory resolveCategory(final String text, final ChatMember member) { + return application.resolveOutgoingChatCategoryFromCompose(text, member); + } + + @Override + public ChatCategory mainCategory() { + return application.chatcontroller.getChatCategoryMain(); + } + + @Override + public void recordOutboundCq(final String text) { + application.chatcontroller.getStationMetricsService() + .tryRecordOutboundCq(text, System.currentTimeMillis()); + } + + @Override + public void requestRecompute(final String reason) { + if (application.chatcontroller.getScoreService() != null) { + application.chatcontroller.getScoreService().requestRecompute(reason); + } + } + + @Override + public void queue(final ChatMessage message) { + application.chatcontroller.getMessageTXBus().add(message); + } + + @Override + public String ownQrgMain() { + String value = application.chatcontroller.getChatPreferences().getMYQRGFirstCat().get(); + return value == null ? "" : value; + } + + @Override + public String ownQrgSecond() { + String value = application.chatcontroller.getChatPreferences().getMYQRGSecondCat().get(); + return value == null ? "" : value; + } +} diff --git a/app-desktop/src/main/java/kst4contest/view/ComposeMenuActions.java b/app-desktop/src/main/java/kst4contest/view/ComposeMenuActions.java new file mode 100644 index 00000000..505fc3f5 --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/ComposeMenuActions.java @@ -0,0 +1,115 @@ +package kst4contest.view; + +import kst4contest.view.compose.MainMenuActions; + +/** + * The Compose menu bar's actions, delegated to methods on {@link Kst4ContestApplication}. + * + *

These used to fire the {@code MenuItem}s of the old JavaFX menu bar, + * which ran side by side with the Compose bar so the two could be compared. The JavaFX bar is + * gone (part 3), so the handlers now live in {@code menuAction…} methods of the application and + * this class calls those directly. It stays a thin bridge: no behaviour of its own, one call per + * menu entry.

+ */ +public final class ComposeMenuActions implements MainMenuActions { + + private final Kst4ContestApplication application; + + public ComposeMenuActions(final Kst4ContestApplication application) { + this.application = application; + } + + @Override + public void connect() { + application.runOnUi(application::menuActionConnect); + } + + @Override + public void disconnect() { + application.runOnUi(application::menuActionDisconnect); + } + + @Override + public void switchOperatorProfile() { + application.runOnUi(application::showOperatorProfileSwitchDialogFromCompose); + } + + @Override + public void exitApplication() { + application.runOnUi(application::menuActionExit); + } + + @Override + public void setQrgAsNameInChat() { + application.runOnUi(application::menuActionSetQrgAsNameInChat); + } + + @Override + public void toggleAwayState() { + application.runOnUi(application::menuActionToggleAwayState); + } + + @Override + public void toggleSettingsWindow() { + application.runOnUi(application::menuActionToggleSettingsWindow); + } + + @Override + public void toggleMonitorWindow() { + application.runOnUi(application::menuActionToggleMonitorWindow); + } + + @Override + public void toggleStationMap() { + application.runOnUi(application::menuActionToggleStationMap); + } + + @Override + public void useDarkDesign() { + application.runOnUi(application::menuActionUseDarkDesign); + } + + @Override + public void useDefaultDesign() { + application.runOnUi(application::menuActionUseDefaultDesign); + } + + @Override + public void openDonationPage() { + application.runOnUi(application::menuActionOpenDonationPage); + } + + @Override + public void openHomepage() { + application.runOnUi(application::menuActionOpenHomepage); + } + + @Override + public void openNewsgroup() { + application.runOnUi(application::menuActionOpenNewsgroup); + } + + @Override + public void openChangelog() { + /* + * The JavaFX item and its handler were both commented out, so there is nothing to do. + * The method stays because the interface is shared and an empty body is honest about + * there being no such feature. + */ + } + + @Override + public void openOv3tDonationPage() { + application.runOnUi(application::menuActionOpenOv3tDonationPage); + } + + @Override + public void contactAuthor() { + application.runOnUi(application::menuActionContactAuthor); + } + + @Override + public void showAbout() { + application.runOnUi(application::menuActionShowAbout); + } +} diff --git a/app-desktop/src/main/java/kst4contest/view/ExternalDocuments.java b/app-desktop/src/main/java/kst4contest/view/ExternalDocuments.java new file mode 100644 index 00000000..a5130422 --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/ExternalDocuments.java @@ -0,0 +1,75 @@ +package kst4contest.view; + +import java.awt.Desktop; +import java.net.URI; +import java.util.Locale; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Opens an address in whatever the desktop uses for it. + * + *

Replaces {@code Application.getHostServices().showDocument(...)}, which went away + * with {@code extends Application}. JavaFX treated web and mail addresses alike; AWT does + * not, so the scheme is decided here: {@code Desktop.mail} for mail, {@code Desktop.browse} + * for everything else. A {@code browse("mailto:...")} silently opens nothing on Linux.

+ */ +public final class ExternalDocuments { + + private static final Logger LOGGER = Logger.getLogger(ExternalDocuments.class.getName()); + + private static final String MAIL_SCHEME = "mailto:"; + + private ExternalDocuments() { + // Utility class. + } + + /** + * Whether the address names a mail recipient rather than a document. + * + * @param address the address to classify, may be null + * @return true when the address carries the mailto scheme + */ + public static boolean isMailAddress(final String address) { + + if (address == null) { + return false; + } + + return address.trim().toLowerCase(Locale.ROOT).startsWith(MAIL_SCHEME); + } + + /** + * Opens the address, or logs why it could not be opened. + * + *

A failure here is never worth terminating anything: the operator asked for a web + * page, not for a state change.

+ * + * @param address an http/https address or a mailto address, may be null + */ + public static void open(final String address) { + + if (address == null || address.isBlank()) { + return; + } + + try { + URI target = URI.create(address.trim()); + + if (!Desktop.isDesktopSupported()) { + LOGGER.log(Level.WARNING, "No desktop integration available for {0}", address); + return; + } + + Desktop desktop = Desktop.getDesktop(); + + if (isMailAddress(address)) { + desktop.mail(target); + } else { + desktop.browse(target); + } + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Could not open " + address, e); + } + } +} diff --git a/src/main/java/kst4contest/view/GuiUtils.java b/app-desktop/src/main/java/kst4contest/view/GuiUtils.java similarity index 53% rename from src/main/java/kst4contest/view/GuiUtils.java rename to app-desktop/src/main/java/kst4contest/view/GuiUtils.java index 0905068b..5d68e2a7 100644 --- a/src/main/java/kst4contest/view/GuiUtils.java +++ b/app-desktop/src/main/java/kst4contest/view/GuiUtils.java @@ -4,62 +4,15 @@ import kst4contest.controller.ChatController; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javafx.scene.image.Image; -import javafx.stage.Stage; - -import java.net.URL; +import java.awt.EventQueue; public class GuiUtils { - private static final String APPLICATION_ICON_RESOURCE = "/icons/kst4contest.png"; - - private static Image applicationIcon; - - /** - * Applies the common KST4Contest application icon to a JavaFX stage. - * - *

The icon is loaded only once and reused for all application windows. - * A missing icon resource must never prevent a window from opening.

- * - * @param stage stage that should receive the application icon + /* + * The application icon used to live here as a JavaFX image applied to a Stage. There is + * no Stage left: every window is a Compose window and loads the same resource itself in + * ComposeWindowHost.applicationIcon(). */ - public static void applyApplicationIcon(Stage stage) { - - if (stage == null) { - return; - } - - Image icon = getApplicationIcon(); - - if (icon != null && !stage.getIcons().contains(icon)) { - stage.getIcons().add(icon); - } - } - - /** - * Loads and caches the common KST4Contest application icon. - * - * @return application icon or null if the resource is unavailable - */ - private static Image getApplicationIcon() { - - if (applicationIcon != null) { - return applicationIcon; - } - - URL iconUrl = GuiUtils.class.getResource(APPLICATION_ICON_RESOURCE); - - if (iconUrl == null) { - System.err.println( - "Application icon resource not found: " - + APPLICATION_ICON_RESOURCE - ); - return null; - } - - applicationIcon = new Image(iconUrl.toExternalForm()); - return applicationIcon; - } private static final String PTRN_CALLSIGNSYNTAX = "^(?:[A-Z]{1,2}[0-9]|[0-9][A-Z])[0-9A-Z]{1,3}$"; /** @@ -77,7 +30,7 @@ public class GuiUtils { * @param maybeCallSignValue * @return true if yes */ - static boolean isCallSignSyntax(String maybeCallSignValue) { + public static boolean isCallSignSyntax(String maybeCallSignValue) { Pattern pattern = Pattern.compile(PTRN_CALLSIGNSYNTAX, Pattern.CASE_INSENSITIVE); Matcher matcher = pattern.matcher(maybeCallSignValue); @@ -96,10 +49,10 @@ public class GuiUtils { public static void triggerGUIFilteredChatMemberListChange(ChatController chatController) { - if (javafx.application.Platform.isFxApplicationThread()) { + if (EventQueue.isDispatchThread()) { triggerUpdate(chatController); - } else{ - javafx.application.Platform.runLater(() -> triggerUpdate(chatController)); + } else { + EventQueue.invokeLater(() -> triggerUpdate(chatController)); } } diff --git a/app-desktop/src/main/java/kst4contest/view/Kst4ContestApplication.java b/app-desktop/src/main/java/kst4contest/view/Kst4ContestApplication.java new file mode 100644 index 00000000..8039929f --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/Kst4ContestApplication.java @@ -0,0 +1,4268 @@ +package kst4contest.view; +import kst4contest.view.compose.SettingsHost; +import kst4contest.view.compose.SettingsNotices; +import kst4contest.view.compose.SettingsTabsKt; +import kst4contest.view.compose.UpdateWindow; +import kst4contest.view.compose.UpdateWindowState; +import kst4contest.view.compose.ColumnWidthStore; +import kst4contest.view.compose.DataTableState; +import kst4contest.view.compose.MonitorColumns; +import kst4contest.view.compose.MonitorWindow; +import kst4contest.view.compose.RowKeys; +import kst4contest.view.compose.BlinkingNotice; +import kst4contest.view.compose.ThreadStatusButtons; +import kst4contest.view.compose.StationColumns; +import kst4contest.view.compose.StationFilterState; +import kst4contest.view.compose.DirectedMessageColumns; +import kst4contest.view.compose.PublicMessageColumns; +import kst4contest.view.compose.SelectedMessageFilter; +import kst4contest.view.compose.SelectedStationMessageColumns; +import kst4contest.view.compose.SelectedStationState; +import kst4contest.view.compose.TopPriorityCandidatesWindow; +import kst4contest.view.compose.TopPriorityState; +import kst4contest.view.compose.TimelineState; +import kst4contest.view.compose.ChatInputState; +import kst4contest.view.compose.MainMenuState; +import kst4contest.view.compose.MainWindowState; +import kst4contest.view.compose.MainWindowSurroundings; +import kst4contest.view.compose.MainWindowHost; +import kst4contest.view.compose.MainWindowFrame; +import kst4contest.view.compose.MainWindowSize; +import kst4contest.view.compose.SplitterState; +import kst4contest.view.compose.SettingsWindow; +import kst4contest.controller.ScoreService; +import kst4contest.view.compose.SettingsWindow; +import kst4contest.controller.On4KstConnectionState; + +import java.io.File; +import java.io.IOException; +import java.net.URISyntaxException; +import java.nio.file.Path; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.function.Consumer; +import java.util.function.Predicate; + +import kst4contest.model.ContestSked; // The new model + +import kst4contest.ApplicationConstants; +import kst4contest.view.compose.OperatorProfilePickerWindow; +import kst4contest.observe.MutableValue; +import kst4contest.observe.ObservableRoster; +import kst4contest.observe.SimpleValue; +import kst4contest.observe.UiDispatcher; + +import java.awt.EventQueue; +import kst4contest.view.compose.ComposeAlert; +import kst4contest.view.compose.TimelineCandidate; +import kst4contest.view.compose.ConfirmKind; +import kst4contest.controller.ChatController; +import kst4contest.controller.MessageVariableResolver; +import kst4contest.controller.StatusUpdateListener; +import kst4contest.controller.Utils4KST; +import kst4contest.locatorUtils.DirectionUtils; +import kst4contest.model.*; + + +import kst4contest.logic.BandOpportunityResolver; +import kst4contest.utils.ApplicationFileLogging; +import kst4contest.utils.ApplicationFileUtils; +import kst4contest.utils.PlatformUtils; +import kst4contest.controller.ActiveOperatorProfile; +import kst4contest.controller.OperatorProfileStore; +import kst4contest.controller.OperatorProfileManagementService; +import kst4contest.controller.OperatorProfilePaths; +import kst4contest.model.OperatorProfile; +import kst4contest.model.OperatorProfileSelection; +import kst4contest.view.map.OfflineDemImportService; +import kst4contest.controller.WorkedGrossFieldCache; + + +public class Kst4ContestApplication implements StatusUpdateListener, SettingsHost { + +// private static final Kst4ContestApplication dbcontroller = new DBController(); + // Null means Auto: use the lowest session band, or category fallback. + + // Enables optional color highlighting of the QRA/grid cell. +// The status text itself remains visible independently of this flag. + + private static final Logger LOGGER = Logger.getLogger( + Kst4ContestApplication.class.getName()); + private static ApplicationFileLogging fileLogging; + private static final String SIMPLE_LOG_MANUAL_URL = + "https://kst4contest.hamradioonline.de/manual/en/log-sync/" + + "#method-1-universal-file-based-callsign-interpreter-simplelogfile"; + + private boolean gridSquareHighlightEnabled = false; + + + /** + * True for a very short moment when the operator explicitly interacts with the + * ChatMember table by mouse or keyboard. + * + * This flag is the distinction between: + * - real operator selection: may overwrite the send field with "/cq CALL " + * - artificial refresh/selection event: must not overwrite operator text + */ + + + private CoalescingTrigger userListRefreshCoalescer; + private String pendingUserListUpdateReason = ""; + + /** + * Remembers the last combined ChatMember table predicate that was applied. + * + * This avoids repeatedly assigning the same predicate to the FilteredList during + * periodic refreshes. Reassigning the predicate without a real filter change can + * invalidate the TableView and trigger artificial selection events. + */ + private Predicate lastAppliedChatMemberFilterPredicate = null; + + + private Band selectedReachabilityBandOverride = null; + + private kst4contest.view.feed.TimelineFeed timelineFeed; + private kst4contest.view.feed.SelectedStationMessagesFeed selectedStationMessagesFeed; + private kst4contest.view.feed.ConnectionStateFeed connectionStateFeed; + private LayoutAutosave layoutAutosave; + + private On4KstConnectionState lastDisplayedConnectionState; + private String lastDisplayedConnectionDetail = ""; + + + /** The delay the former JavaFX pause transition used, so the feel does not change. */ + private static final int USER_LIST_REFRESH_DELAY_MS = 300; + + // Timeline: show at most N priority markers per minute bucket (minute 0/1 often has many planes) + private static final int TIMELINE_PRIORITY_MARKERS_PER_MINUTE = 2; + + // Timeline: show 2 more in other directions + private static final int TIMELINE_BEAM_MARKERS_PER_MINUTE = 2; + + + // Keep in sync with TimelineView PREVIEW_TIME_MS (currently 30 minutes = 30L * 60L * 1000L) + private static final long TIMELINE_PREVIEW_TIME_MS = 30L * 60L * 1000L; + + /** + * Reused show-all predicate for the station table. + * + * Using the same instance avoids unnecessary FilteredList invalidations when no + * station filters are active. Such invalidations can make the TableView selection + * model fire again although the operator did not select another station. + */ + private static final Predicate SHOW_ALL_CHAT_MEMBER_PREDICATE = chatMember -> true; + + //recoloring of the chatmembers list is turned on and off here + private static final boolean ENABLE_PRIORITY_SCORE_ROW_COLORING = false; + + + + + /* + * Derived and never spelled out: this is the file the root profile's own stylesheet layer + * reads, under the name OperatorProfilePaths.paletteRelativeFileName builds from the same + * constant. Two independent literals of this value would have to stay equal for that to + * work, and a rename on one side would restore the "written but never read" defect + * silently, with a green build. + */ + public static final String STYLE_DEFAULTCSSDAY_FILE = ApplicationConstants.STYLECSSFILE_DEFAULT_DAYLIGHT; + public static final String STYLE_DEFAULTCSSDAY_RESOURCE = "/" + ApplicationConstants.STYLECSSFILE_DEFAULT_DAYLIGHT; + + public static final String STYLE_DEFAULTCSSEVENING_FILE = ApplicationConstants.STYLECSSFILE_DEFAULT_EVENING; + public static final String STYLE_DEFAULTCSSEVENING_RESOURCE = "/" + ApplicationConstants.STYLECSSFILE_DEFAULT_EVENING; + + /** Hands worker-thread results over to the AWT event thread, where Compose draws. */ + private final UiDispatcher uiDispatcher = new AwtUiDispatcher(); + + /** + * Runs work on the user-interface thread. Package-private so the Compose bridge classes + * can hand their work to the same dispatcher rather than bringing a second one. + */ + void runOnUi(final Runnable work) { + uiDispatcher.runOnUi(work); + } + + /** + * The profile switch, reachable from the Compose menu. + * + *

A thin forwarder rather than a promotion of the private method: the switch is about + * to change its nature in task 14, and a second public entry point would be a second + * thing to change then.

+ */ + void showOperatorProfileSwitchDialogFromCompose() { + showOperatorProfileSwitchDialog(); + } + + /** Forwarders so the Compose send line runs the very same checks the send button does. */ + boolean isMessageAddressedToOwnCallsignFromCompose(final String messageText) { + return isMessageAddressedToOwnCallsign(messageText); + } + + ChatCategory resolveOutgoingChatCategoryFromCompose( + final String outgoingText, + final ChatMember selectedMember) { + return resolveOutgoingChatCategory(outgoingText, selectedMember); + } + + /** + * Follows the own QRG in the text field. Replaces the former + * {@code textProperty().bind(...)}: a MutableValue is not a JavaFX + * property, so the field is updated through a listener instead. Attaching + * twice is harmless; detaching releases the listener. + */ + + + + /** Live mirrors of core rosters, handed to TableViews. Released on shutdown. */ + private final java.util.List> rosterBindings = new java.util.ArrayList<>(); + + private java.util.List mirrorOf(ObservableRoster roster) { + RosterListBinding binding = RosterListBinding.mirror(roster, uiDispatcher); + rosterBindings.add(binding); + return binding.list(); + } + + /** + * Registers a mirror whose content is computed rather than copied. Used for the + * station list and the message tabs, which used to be FilteredList/SortedList + * views on a core collection. + */ + private RosterListBinding derivedBinding( + java.util.function.Supplier> derivation, + ObservableRoster... sources) { + RosterListBinding binding = RosterListBinding.derived(uiDispatcher, derivation, sources); + rosterBindings.add(binding); + return binding; + } + + /** The visible station list, replacing the former SortedList on the TableView. */ + private RosterListBinding chatMemberListBinding; + + /** + * The message view of the selected-station info window. Its filter is switched + * by the radio buttons of that window, so the binding has to be refreshed + * explicitly. The other message views keep the filter they were given in the + * controller and follow their source rosters on their own. + */ + private RosterListBinding selectedCallSignInfoMessageBinding; + + /** + * Sets the message filter of the selected-station info window and shows the + * result immediately, the way {@code FilteredList.setPredicate} did. + */ + private void applySelectedCallSignInfoFilter(Predicate filter) { + chatcontroller.setSelectedCallSignInfoFilter(filter); + if (selectedCallSignInfoMessageBinding != null) { + selectedCallSignInfoMessageBinding.refresh(); + uiDispatcher.runOnUi(() -> { + if (selectedStationMessagesFeed != null) { + selectedStationMessagesFeed.push(selectedCallSignInfoMessageBinding.list()); + } + }); + } + } + + /** Follows the PSTRotator QTF in the text field; replaces a JavaFX string binding. */ + + + + + + ChatController chatcontroller; + public ChatController getChatController() { return chatcontroller; } + MessageVariableResolver messageVariableResolver; + + + // the text later + + Timer timer_buildWindowTitle; + Timer timer_updatePrivatemessageTable; // same here + + + private void ensureStationMapSupportInitialized() { + // Nothing to initialize for Compose map here + } + + private void toggleStationMapWindow() { + if (composeMainWindowState != null) { + kst4contest.view.compose.map.StationMapWindow.INSTANCE.toggle(composeMainWindowState, paletteStore, languageStore); + } + } + + private void showSelectedCallsignOnMap() { + if (composeMainWindowState != null) { + if (!kst4contest.view.compose.map.StationMapWindow.INSTANCE.isShowing()) { + kst4contest.view.compose.map.StationMapWindow.INSTANCE.toggle(composeMainWindowState, paletteStore, languageStore); + } + } + } + + private void refreshStationMapIfVisible() { + // Compose map state is reactive to main window state + } + + /** + * Resolves a reasonable initial directory for the DEM tile file chooser. + * + *

Preference order: + *

    + *
  1. configured DEM root directory if it already exists
  2. + *
  3. its parent directory if that exists
  4. + *
  5. user home directory
  6. + *
+ * + * @param configuredDemRootDirectory current DEM root directory text + * @return usable initial directory or null + */ + private File resolveInitialDirectoryForDemImport(String configuredDemRootDirectory) { + if (configuredDemRootDirectory != null && !configuredDemRootDirectory.isBlank()) { + File configuredDirectory = new File(configuredDemRootDirectory.trim()); + + if (configuredDirectory.isDirectory()) { + return configuredDirectory; + } + + File parentDirectory = configuredDirectory.getParentFile(); + if (parentDirectory != null && parentDirectory.isDirectory()) { + return parentDirectory; + } + } + + File userHomeDirectory = new File(System.getProperty("user.home")); + return userHomeDirectory.isDirectory() ? userHomeDirectory : null; + } + + /** + * helper DTO for planes and arriving time in minutes. Maybe + */ + private static final class NextApInfo { + final AirPlane plane; + final int arrivingMinutes; + + private NextApInfo(AirPlane plane, int arrivingMinutes) { + this.plane = plane; + this.arrivingMinutes = arrivingMinutes; + } + } + + /** + * Helper DTO for timeline building + */ + private static final class TimelineCandidateTmp { + final kst4contest.controller.ScoreService.TopCandidate top; + final ChatMember representativeMember; + final NextApInfo nextAp; + + TimelineCandidateTmp(kst4contest.controller.ScoreService.TopCandidate top, ChatMember representativeMember, NextApInfo nextAp) { + this.top = top; + this.representativeMember = representativeMember; + this.nextAp = nextAp; + } + } + + + + /** + * Gets thread notifications and makes new statusbuttons at the top + * + * @param sourceName + */ + private void updateStatusButton(String sourceName, ThreadStateMessage threadStateMessage) { + if (composeMainWindowState != null) { + composeMainWindowState.getThreadButtons().update(sourceName, threadStateMessage); + } + } + + /** + * Helps the view to format the RX Bands for a callsign, using the chatmembers frequencies detected MAP + * @param callSignRaw + * @param maxAgeMs + * @return + */ + private String formatDetectedRxBandsForCallsignRaw(String callSignRaw, long maxAgeMs) { + + if (callSignRaw == null) return kst4contest.view.i18n.CurrentStrings.get().getTooltipBandsNone(); + + List variants = chatcontroller.findActiveChatMembersByRawCall(callSignRaw); + BandOpportunityResolver.Resolution bandResolution = + BandOpportunityResolver.resolve(variants, System.currentTimeMillis(), maxAgeMs); + EnumSet availableBands = bandResolution.getAvailableBands(); + + if (availableBands.isEmpty()) { + return kst4contest.view.i18n.CurrentStrings.get().getTooltipBandsNone(); + } + + Map newestPerBand = + new EnumMap<>(Band.class); + + for (ChatMember member : variants) { + if (member == null || member.getKnownActiveBands() == null) continue; + + for (Map.Entry entry + : member.getKnownActiveBands().entrySet()) { + + Band band = entry.getKey(); + ChatMember.ActiveFrequencyInfo info = entry.getValue(); + if (band == null || info == null || !availableBands.contains(band)) continue; + + long ageMs = System.currentTimeMillis() - info.timestampEpoch; + if (ageMs < 0L || (maxAgeMs > 0 && ageMs > maxAgeMs)) continue; + + ChatMember.ActiveFrequencyInfo existing = newestPerBand.get(band); + if (existing == null || info.timestampEpoch > existing.timestampEpoch) { + newestPerBand.put(band, info); + } + } + } + + StringBuilder result = new StringBuilder(kst4contest.view.i18n.CurrentStrings.get().getTooltipBandsPrefix() + " ").append( + availableBands.stream() + .sorted() + .map(this::bandToHumanLabel) + .collect(java.util.stream.Collectors.joining(", ")) + ); + + if (newestPerBand.isEmpty()) { + return result.toString(); + } + + result.append(" | QRGs: "); + boolean first = true; + + for (Band band : Band.values()) { + ChatMember.ActiveFrequencyInfo info = newestPerBand.get(band); + if (info == null) continue; + + if (!first) result.append(" | "); + first = false; + + long ageMinutes = (System.currentTimeMillis() - info.timestampEpoch) / 60_000L; + result.append(bandToHumanLabel(band)) + .append(" ") + .append(String.format(Locale.US, "%.3f", info.frequency)) + .append(" MHz (") + .append(ageMinutes) + .append(" min ago)"); + } + + return result.toString(); + } + + /** + * Checks whether a station has known activity on the given band and that band is + * one of my own currently enabled bands, i.e. a new-band opportunity worth flagging + * with a star in that band's table cell. + * + * @param chatMember station row + * @param band band to check + * @return true if the band cell should show a star + */ + private boolean isBandOfferForMainView(ChatMember chatMember, Band band) { + if (chatMember == null || band == null || chatcontroller == null) { + return false; + } + + List variants = + chatcontroller.findActiveChatMembersByRawCall(chatMember.getCallSignRaw()); + if (variants.isEmpty()) { + variants = List.of(chatMember); + } + + BandOpportunityResolver.Resolution resolution = + BandOpportunityResolver.resolve(variants, System.currentTimeMillis()); + EnumSet enabledBands = + BandOpportunityResolver.getEnabledStationBands(chatcontroller.getChatPreferences()); + + return resolution.getUnworkedEnabledBands(enabledBands).contains(band); + } + + /** + * Checks whether the station's four-character grid square has already been worked + * specifically on the given band, regardless of which call was worked there. Mirrors + * the "o" semantics of the wkdAny column, just scoped to one band instead of any band. + * Can be turned off via + * {@link ChatPreferences#isGuiOptions_showGrossFieldWorkedHintInBandColumns()}. + * + * @param chatMember station row + * @param band band to check + * @return true if the cell should show the "o" worked-grid-square hint + */ + private boolean isGrossFieldWorkedForBand(ChatMember chatMember, Band band) { + if (chatMember == null || band == null || chatcontroller == null) { + return false; + } + + if (!chatcontroller.getChatPreferences().isGuiOptions_showGrossFieldWorkedHintInBandColumns()) { + return false; + } + + String qra = chatMember.getQra(); + if (qra == null || qra.isBlank()) { + return false; + } + + return chatcontroller.getWorkedGrossFieldCache().isGrossFieldWorked(band, qra); + } + + /** + * Resolves the compact per-band status shown in the 144/432/23/13/9/6/3 table + * columns. + * + *

{@code X}/{@code a}/{@code B+}/(empty) describe the band-opportunity part: + * {@code X} if worked on this exact band, otherwise {@code a}/{@code B+} if the band + * is offered, enabled and unworked ({@code a} when the call has not been worked on + * any band yet, {@code B+} when it has), otherwise empty.

+ * + *

{@code o} is an independent overlay, appended to whichever of the above applies, + * exactly like the {@code x}/{@code o}/{@code xo} combination in the wkdAny column: + * it marks that this band's grid square has already been worked, by any station. + * So e.g. {@code "a"}, {@code "ao"}, {@code "B+"}, {@code "B+o"} or just {@code "o"} + * can all appear.

+ * + * @param chatMember station row + * @param band band this column represents + * @param workedThisBand true if the per-band worked flag for this exact band is set + * @return compact status text for the cell + */ + private String formatBandCellStatus(ChatMember chatMember, Band band, boolean workedThisBand) { + String opportunity; + + boolean showFreshCallHint = chatcontroller != null + && chatcontroller.getChatPreferences().isGuiOptions_showFreshCallHintInBandColumns(); + + if (workedThisBand) { + opportunity = "X"; + } else if (isBandOfferForMainView(chatMember, band)) { + opportunity = showFreshCallHint && chatMember != null && !chatMember.isWorked() ? "a" : "B+"; + } else { + opportunity = ""; + } + + return isGrossFieldWorkedForBand(chatMember, band) ? opportunity + "o" : opportunity; + } + + /** + * Builds the tooltip shown on a band-status cell: a fixed legend plus this row's + * resolved status for the given band. + */ + private String buildBandCellStatusTooltipText(ChatMember chatMember, Band band, String status) { + StringBuilder tooltip = new StringBuilder(kst4contest.view.i18n.CurrentStrings.get().getTooltipBandStatusLegend()); + + if (chatMember != null && band != null) { + tooltip.append(kst4contest.view.i18n.CurrentStrings.get().tooltipBandStatusThisStation( + bandToHumanLabel(band), + status == null || status.isBlank() ? "-" : status)); + } + + return tooltip.toString(); + } + + + private String bandToHumanLabel(kst4contest.model.Band b) { + // Human-friendly labels for VHF/UHF/microwave contesting + return switch (b) { + case B_50 -> "6m"; + case B_70 -> "4m"; + case B_144 -> "2m"; + case B_432 -> "70cm"; + case B_1296 -> "23cm"; + case B_2320 -> "13cm"; + case B_3400 -> "9cm"; + case B_5760 -> "6cm"; + case B_10G -> "3cm"; + case B_24G -> "24G"; + }; + } + + /** + * Chooses a useful initial band for a new sked. + * + *

Recent frequency evidence has priority over station-name information. + * Manual NOT-QRV exclusions are respected. The operator can still select + * another locally enabled band from the dropdown.

+ */ + private Band resolveDefaultSkedBand(ChatMember selectedMember, + EnumSet enabledBands) { + + if (selectedMember == null || enabledBands == null || enabledBands.isEmpty()) { + return null; + } + + List variants = + chatcontroller.findActiveChatMembersByRawCall( + selectedMember.getCallSignRaw() + ); + + if (variants.isEmpty()) { + variants = List.of(selectedMember); + } + + BandOpportunityResolver.Resolution resolution = + BandOpportunityResolver.resolve( + variants, + System.currentTimeMillis() + ); + + EnumSet availableBands = resolution.getAvailableBands(); + availableBands.retainAll(enabledBands); + + Band newestFrequencyBand = null; + long newestTimestamp = Long.MIN_VALUE; + long now = System.currentTimeMillis(); + + for (ChatMember member : variants) { + if (member == null || member.getKnownActiveBands() == null) { + continue; + } + + for (Map.Entry entry + : member.getKnownActiveBands().entrySet()) { + + Band band = entry.getKey(); + ChatMember.ActiveFrequencyInfo info = entry.getValue(); + + if (band == null + || info == null + || !availableBands.contains(band) + || !band.isPlausible(info.frequency)) { + continue; + } + + long ageMs = now - info.timestampEpoch; + if (ageMs < 0L + || ageMs > BandOpportunityResolver.RECENT_DYNAMIC_EVIDENCE_MAX_AGE_MS) { + continue; + } + + if (info.timestampEpoch > newestTimestamp) { + newestTimestamp = info.timestampEpoch; + newestFrequencyBand = band; + } + } + } + + if (newestFrequencyBand != null) { + return newestFrequencyBand; + } + + if (!availableBands.isEmpty()) { + return availableBands.iterator().next(); + } + + return enabledBands.iterator().next(); + } + + + /** + * This method generates a BoderPane which shows some additional information about a callsign which had been + * selected either:
+ * - at the userlist
+ * - at the CQ message list (senders callsign)
+ * - at the PM message list (senders callsign)

+ * Method gets its information source out of the original chatmember object of the userlist, not a copy + * + * @param selectedCallSignInfoStageChatMember + * @return + */ + + + /** + * Applies the currently selected station filters to the ChatMember FilteredList. + * + * This replaces the old predicate-property binding / forced refresh mechanics. + * The important point is that the TableView should only be invalidated when the + * effective filter really changed. Otherwise JavaFX may emit selection events + * during normal periodic updates although the operator did not click another + * station. + * + *

Regardless of whether the invalidation below was really necessary, + * re-evaluating the FilteredList predicate can make the TableView emit a + * selection-changed event for the still-selected station (e.g. because the + * FilteredList/SortedList rebuild produces a new ChatMember instance for the + * same callsign). This happens synchronously for every caller of this method, + * including the callsign search field's textProperty listener on every single + * keystroke. Without a guard, that spurious event reaches the table-selection + * listener and re-prepares/re-focuses the send text field, yanking keyboard + * focus away from wherever the operator currently is. Guard it the same way + * focusChatMemberAndPrepareCq guards its own programmatic selection.

+ */ + private void applyChatMemberFilterPredicates() { + if (chatcontroller == null + || chatMemberListBinding == null + || chatcontroller.getLst_chatMemberListFilterPredicates() == null) { + return; + } + + Predicate combinedPredicate; + + if (chatcontroller.getLst_chatMemberListFilterPredicates().snapshot().isEmpty()) { + combinedPredicate = SHOW_ALL_CHAT_MEMBER_PREDICATE; + } else { + combinedPredicate = chatcontroller.getLst_chatMemberListFilterPredicates() + .snapshot() + .stream() + .reduce(SHOW_ALL_CHAT_MEMBER_PREDICATE, Predicate::and); + } + + /* + * Do not reset the same show-all predicate over and over again. + * + * The periodic priority/user-list refresh calls this method regularly. If the + * visible station list is rebuilt without real filter changes, the TableView + * selection model may emit another selection event and the send-text field can + * be prepared again. + */ + if (combinedPredicate == lastAppliedChatMemberFilterPredicate) { + return; + } + + lastAppliedChatMemberFilterPredicate = combinedPredicate; + + /* + * The refresh used to be wrapped in programmaticChatMemberSelectionChange so the + * TableView's selection listener would not prepare the send text a second time. + * There is no such listener any more: the Compose station table reports a click + * directly through onStationSelected, and a mirror refresh emits nothing. + */ + chatMemberListBinding.refresh(); + } + + + /** + * Helper method for furtherinfoPane + * @param s + * @return + */ + private static List parseMinuteOffsets(String s) { + if (s == null || s.isBlank()) return List.of(); + String[] parts = s.split("\\+"); + List out = new ArrayList<>(); + for (String p : parts) { + try { + out.add(Integer.parseInt(p.trim())); + } catch (Exception ignore) {} + } + return out; + } + + + + private ChatMember resolveChatMemberForCallRawAndCategory(String callRaw, ChatCategory preferredCategory) { + + if (callRaw == null) return null; + + // 1) Prefer exact (callRaw + category) + // One snapshot for both passes: the roster is consistent inside it. + List currentMembers = chatcontroller.getLst_chatMemberList().snapshot(); + + for (ChatMember m : currentMembers) { + if (m == null) continue; + if (m.getCallSignRaw() == null) continue; + if (!m.getCallSignRaw().equalsIgnoreCase(callRaw)) continue; + + if (preferredCategory != null && preferredCategory.equals(m.getChatCategory())) { + return m; + } + } + + // 2) Fallback: any variant with same callsignRaw + for (ChatMember m : currentMembers) { + if (m == null) continue; + if (m.getCallSignRaw() == null) continue; + if (m.getCallSignRaw().equalsIgnoreCase(callRaw)) return m; + } + + return null; + } + + /** + * Focuses a ChatMember and prepares the send field. + * + * This overload is used by explicit operator actions such as timeline clicks or + * context actions. In those cases it is acceptable to overwrite the previous + * automatic /cq template, because the operator intentionally chose a station. + */ + private void focusChatMemberAndPrepareCq(ChatMember member) { + focusChatMemberAndPrepareCq(member, true); + } + + /** + * Focuses a ChatMember and optionally prepares the /cq command. + * + * The method selects the member in the table if possible, but guards that + * programmatic selection with programmaticChatMemberSelectionChange. This prevents + * the table selection listener from running the same logic a second time. + * + * @param member ChatMember that should become the active station + * @param forcePrepareCq true if /cq should be prepared even if the logical + * selection did not change + */ + private void focusChatMemberAndPrepareCq(ChatMember member, boolean forcePrepareCq) { + if (member == null) { + return; + } + + /* + * This used to select and scroll to the row in the JavaFX station table first, for + * visual feedback. The Compose table scrolls itself when its selection changes, and + * the JavaFX one never had rows. + */ + handleChatMemberSelectionChanged(member, forcePrepareCq); + } + + /** + * Central handler for a selected ChatMember. + * + * Selection changes can be emitted by JavaFX even when the user did not click a + * new station, for example after FilteredList/SortedList invalidations during + * periodic score updates. + * + * Therefore the send text is only auto-prepared when: + * - the logical station really changed, or + * - the caller explicitly forces preparation. + * + * Even then, the send field is protected by prepareCqTextForSelectedChatMember() + * so manually typed operator text is not destroyed. + */ + private void handleChatMemberSelectionChanged(ChatMember selectedMember, boolean forcePrepareCq) { + if (selectedMember == null) { + return; + } + + /* + * Whether the info pane already shows this station. Compared against the + * member the pane was last built for, not against the selection model's + * previous value: a station entering or leaving the chat replaces the whole + * table mirror, which makes the model emit [null, sameMember]. Its previous + * value is then null and looks like a change, while the operator never left + * the station. + * + * Rebuilding the pane on such an event resets the message filter radio + * buttons to their configured defaults, which takes the operator's view away + * while they are still reading it. On a busy server that happens every few + * seconds. + */ + boolean infoPaneAlreadyShowsMember = + isSameLogicalChatMember(selectedCallSignInfoStageChatMember, selectedMember); + + selectedCallSignInfoStageChatMember = selectedMember; + + if (chatcontroller != null && chatcontroller.getScoreService() != null) { + chatcontroller.getScoreService().setSelectedChatMember(selectedMember); + } + + if (!infoPaneAlreadyShowsMember) { + /* + * Rebind the Compose "messages of the selected station" table to the newly + * selected member. This used to be a side effect of building the JavaFX + * info pane (generateFurtherInfoAbtSelectedCallsignBP, now deleted): that + * pane was never shown, but the binding it created feeds the Compose table. + * Only that live binding remains here. + */ + try { + rebuildSelectedCallSignInfoMessageBinding(); + } catch (Exception exception) { + System.out.println("KST4CApp: ERROR, selected member disappeared: " + exception.getMessage()); + } + } + + /* + * prepareCqTextForSelectedChatMember() ends in requestFocus() on the send + * field. It must therefore only run when the station really changed, or when + * the operator selected a row themselves: the [null, sameMember] burst a + * mirror replacement produces would otherwise pull the keyboard focus away + * from whatever field the operator is typing in, every time a station enters + * or leaves the chat. + */ + if (forcePrepareCq || !infoPaneAlreadyShowsMember) { + prepareCqTextForSelectedChatMember(selectedMember, forcePrepareCq); + } + } + + /** + * Prepares the send field with "/cq CALL " for the selected ChatMember. + * + * The ChatMember's category is stored together with the prepared text. This is + * required because a later table refresh may change the selected row while the + * operator is still editing the message. The send handler can then still send the + * message in the category of the callsign shown in the text field. + */ + private void prepareCqTextForSelectedChatMember(ChatMember member, boolean forceOverwrite) { + if (member == null) { + return; + } + + rememberAutoPreparedCqTarget(member.getCallSign(), member.getChatCategory()); + } + + /** + * Convenience overload when only a callsign is known. + * + * No category is attached in this case. The send handler will later try to + * resolve the category from the visible /cq callsign and the active user list. + */ + private void rememberAutoPreparedCqTarget(String callSign) { + rememberAutoPreparedCqTarget(callSign, null); + } + + /** + * Prepares "/cq CALL " in the send field without destroying operator input. + * + * The field may only be overwritten when: + * - forceOverwrite is true, + * - the field is empty, or + * - the field still contains the previous automatically generated /cq template. + * + * If the operator already changed the text, this method leaves the field exactly + * as it is. + */ + private void rememberAutoPreparedCqTarget(String callSign, ChatCategory preparedCategory) { + if (callSign == null || callSign.isBlank()) { + return; + } + + /* + * Remember which station the /cq text was prepared for, and in which category. + * resolveOutgoingChatCategory reads this: it connects the visible /cq command to + * the right chat category even when a refresh or a filter changes the selected row + * while the operator is still typing. The Compose chat input owns the text and its + * own overwrite guard, but it keeps no category, so this bookkeeping has no Compose + * counterpart and stays here. + * + * Recorded unconditionally. If the Compose input declined to overwrite operator + * text, the recorded callsign simply will not match the /cq target extracted from + * the visible text, and resolveOutgoingChatCategory falls through to its remaining + * sources — which is what it did before this was recorded at all. + */ + lastAutoPreparedCqTargetCallsign = normalizeCallsignForCategoryResolution(callSign); + lastAutoPreparedCqTargetCategory = normalizeToActiveChatCategory(preparedCategory); + } + + /** + * Compares two ChatMember objects by their active chat identity. + * + *

JavaFX may replace item instances during list refreshes, so object + * identity alone is not sufficient. The complete callsign and the chat + * category identify one active ON4KST login.

+ * + *

The raw/base callsign must not be used here. Otherwise callsigns such as + * {@code 9A0BB-2} and {@code 9A0BB-70} would still be treated as the same + * selection inside one chat category.

+ */ + private boolean isSameLogicalChatMember(ChatMember a, ChatMember b) { + + if (a == b) { + return true; + } + + if (a == null || b == null) { + return false; + } + + String aCallSign = a.getCallSign(); + String bCallSign = b.getCallSign(); + + if (aCallSign == null + || bCallSign == null + || !aCallSign.equalsIgnoreCase(bCallSign)) { + return false; + } + + ChatCategory aCategory = a.getChatCategory(); + ChatCategory bCategory = b.getChatCategory(); + + if (aCategory == bCategory) { + return true; + } + + if (aCategory == null || bCategory == null) { + return false; + } + + return aCategory.getCategoryNumber() + == bCategory.getCategoryNumber(); + } + + /** + * Resolves the chat category for an outgoing message. + * + * Important: if the send field contains an explicit "/cq CALL ...", the target + * callsign in the text is authoritative. This prevents a later table refresh or + * selection event from sending an already typed message in the category of a + * different selected ChatMember. + */ + private ChatCategory resolveOutgoingChatCategory(String outgoingText, ChatMember selectedMember) { + ChatCategory mainCategory = chatcontroller != null ? chatcontroller.getChatCategoryMain() : null; + ChatCategory selectedMemberCategory = getActiveChatCategoryForMember(selectedMember); + String cqTargetCallsign = extractCqTargetCallsign(outgoingText); + + if (cqTargetCallsign != null) { + String normalizedTarget = normalizeCallsignForCategoryResolution(cqTargetCallsign); + + /* + * If this text was auto-prepared from a concrete ChatMember, keep that + * category attached to the text even if the table selection changes later. + */ + if (normalizedTarget.equals(lastAutoPreparedCqTargetCallsign) + && lastAutoPreparedCqTargetCategory != null) { + return lastAutoPreparedCqTargetCategory; + } + + /* + * If the currently selected member is the same station as the /cq target, + * its category is safe to use. + */ + if (selectedMember != null + && selectedMemberCategory != null + && chatMemberMatchesCallsign(selectedMember, normalizedTarget)) { + return selectedMemberCategory; + } + + /* + * Otherwise resolve the /cq target from the user list. This also protects + * manually typed /cq texts when a different station is selected. + */ + ChatCategory uniqueCategoryForTarget = findUniqueActiveCategoryForCallsign(normalizedTarget); + if (uniqueCategoryForTarget != null) { + return uniqueCategoryForTarget; + } + + System.out.println("KST4CApp: WARNING, could not resolve chat category for explicit /cq target " + + cqTargetCallsign + "; using main chat category as safe fallback."); + return mainCategory; + } + + if (selectedMemberCategory != null) { + return selectedMemberCategory; + } + + return mainCategory; + } + + /** + * Returns an active ChatCategory object for the member category. + * + * This avoids sending with stale category instances and maps the member category + * to the controller's current main/second category objects. + */ + private ChatCategory getActiveChatCategoryForMember(ChatMember member) { + if (member == null) { + return null; + } + return normalizeToActiveChatCategory(member.getChatCategory()); + } + + /** + * Maps any category object to the currently active main/second chat category. + * + * This is safer than directly reusing a category object from a ChatMember, because + * the controller owns the actual active category instances used for sending. + */ + private ChatCategory normalizeToActiveChatCategory(ChatCategory category) { + if (category == null || chatcontroller == null) { + return null; + } + + String categoryNumber = category.getCategoryNumber() + ""; + + if (chatcontroller.getChatCategoryMain() != null + && categoryNumber.equals(chatcontroller.getChatCategoryMain().getCategoryNumber() + "")) { + return chatcontroller.getChatCategoryMain(); + } + + if (chatcontroller.getChatCategorySecondChat() != null + && categoryNumber.equals(chatcontroller.getChatCategorySecondChat().getCategoryNumber() + "")) { + return chatcontroller.getChatCategorySecondChat(); + } + + return null; + } + + /** + * Extracts the target callsign from a directed ON4KST command such as: + * + * /cq DL1ABC hello + * + * Returns null for normal/general messages that do not start with "/cq ". + */ + private String extractCqTargetCallsign(String outgoingText) { + if (outgoingText == null) { + return null; + } + + String trimmedText = outgoingText.trim(); + if (trimmedText.length() < 5 || !trimmedText.toLowerCase(Locale.ROOT).startsWith("/cq ")) { + return null; + } + + String afterCommand = trimmedText.substring(4).trim(); + if (afterCommand.isBlank()) { + return null; + } + + String[] parts = afterCommand.split("\\s+", 2); + return parts.length > 0 && !parts[0].isBlank() ? parts[0].trim() : null; + } + + /** + * Searches the active user list for one unique category for a callsign. + * + * If the same callsign is present in both active chat channels, the result is not + * unique and null is returned. In that case the send handler falls back to the + * main category and logs a warning. + */ + private ChatCategory findUniqueActiveCategoryForCallsign(String normalizedCallsign) { + if (normalizedCallsign == null || normalizedCallsign.isBlank() + || chatcontroller == null || chatcontroller.getLst_chatMemberList() == null) { + return null; + } + + ChatCategory foundCategory = null; + + for (ChatMember chatMember : chatcontroller.getLst_chatMemberList().snapshot()) { + if (chatMember == null || !chatMemberMatchesCallsign(chatMember, normalizedCallsign)) { + continue; + } + + ChatCategory activeCategory = getActiveChatCategoryForMember(chatMember); + if (activeCategory == null) { + continue; + } + + if (foundCategory == null) { + foundCategory = activeCategory; + } else if (foundCategory.getCategoryNumber() != activeCategory.getCategoryNumber()) { + // Same callsign is present in multiple active chat channels; not unique. + return null; + } + } + + return foundCategory; + } + + /** + * Checks whether a ChatMember represents the given normalized callsign. + * + * Both getCallSign() and getCallSignRaw() are checked because different parts of + * the program use either the decorated/display callsign or the raw callsign. + */ + private boolean chatMemberMatchesCallsign(ChatMember chatMember, String normalizedCallsign) { + if (chatMember == null || normalizedCallsign == null || normalizedCallsign.isBlank()) { + return false; + } + + String callSign = normalizeCallsignForCategoryResolution(chatMember.getCallSign()); + String callSignRaw = normalizeCallsignForCategoryResolution(chatMember.getCallSignRaw()); + + return normalizedCallsign.equals(callSign) || normalizedCallsign.equals(callSignRaw); + } + + /** + * Normalizes callsigns for safe comparisons. + */ + private String normalizeCallsignForCategoryResolution(String callsign) { + return callsign == null ? "" : callsign.trim().toUpperCase(Locale.ROOT); + } + +// private void focusChatMemberAndPrepareCq(ChatMember member) { +// if (member == null) return; +// +// // Try selecting in table if it is visible (nice UX), but do not depend on it +// try { +// if (tbl_chatMember != null && tbl_chatMember.getItems() != null && tbl_chatMember.getItems().contains(member)) { +// tbl_chatMember.getSelectionModel().select(member); +// tbl_chatMember.scrollTo(member); +// } +// } catch (Exception ignored) { +// // ignore: table not ready or filtered +// } +// +// // Force selection effects regardless of filters/selection state +// selectedCallSignInfoStageChatMember = member; +// chatcontroller.getScoreService().setSelectedChatMember(member); +// +// selectedCallSignFurtherInfoPane.getChildren().setAll(generateFurtherInfoAbtSelectedCallsignBP(member)); +// +// txt_chatMessageUserInput.clear(); +// txt_chatMessageUserInput.setText("/cq " + member.getCallSign() + " "); +// txt_chatMessageUserInput.requestFocus(); +// txt_chatMessageUserInput.selectEnd(); +// } + + + + /** + * Creates the mirror that feeds the Compose "messages of the selected station" table. + * + * Lifted out of initFurtherInfoAbtCallsignMSGTable, which built the never-shown + * JavaFX table around it. The feed it drives does not depend on that table existing, + * so the binding must not either - otherwise deleting the table would silently empty + * the Compose table with a green build and no compile error, the exact failure class + * part 1 was written to prevent. + * + * Called once per selected-station info build, replacing the previous mirror rather + * than leaving it listening on the message roster - the same lifecycle the binding + * had while it lived inside the table builder. + */ + private void rebuildSelectedCallSignInfoMessageBinding() { + if (selectedCallSignInfoMessageBinding != null) { + selectedCallSignInfoMessageBinding.dispose(); + rosterBindings.remove(selectedCallSignInfoMessageBinding); + } + selectedCallSignInfoMessageBinding = derivedBinding( + chatcontroller::selectedCallSignInfoMessages, + chatcontroller.getLst_globalChatMessageList()); + selectedCallSignInfoMessageBinding.onChanged(rows -> { + if (selectedStationMessagesFeed != null) { + selectedStationMessagesFeed.push(rows); + } + }); + } + + /** + * Builds the lower global-message area. + * + * This TabPane is intentionally independent from the selected ChatMember. + * It contains global message streams only: + * - public/CQ messages + * - DXCluster messages + * - messages between other stations ("QSO of the other") + * + * The already initialized public-message table is passed in so its existing + * context menu and selection handling remain unchanged. + * + * DXCluster and QSO-of-the-other get their own TableViews on the same backing + * lists. This is important because the existing separate "Cluster & QSO of the other" + * window can keep using its own TableViews at the same time. + */ + + /** + * initializes the tableview in which the cq- and beacon-texts are shown + * + * @return + */ + + + + + + +// private BorderPane initTopPriorityListPane(TableView tbl_chatMember, TextField txt_chatMessageUserInput) { +// +// BorderPane pane = new BorderPane(); +// pane.setStyle("-fx-padding: 3;"); +// +// Label header = new Label("Top priority candidates"); +// header.getStyleClass().add("label"); +// +// ListView listView = new ListView<>(); +// listView.setItems(mirrorOf(chatcontroller.getScoreService().topCandidates())); +// +// listView.setCellFactory(lv -> new ListCell<>() { +// @Override +// protected void updateItem(kst4contest.controller.ScoreService.TopCandidate item, boolean empty) { +// super.updateItem(item, empty); +// if (empty || item == null) { +// setText(null); +// return; +// } +// // Keep it compact; score is mainly evaluated in FurtherInfo +// setText(item.getDisplayCallSign() + " | score " + String.format(java.util.Locale.US, "%.0f", item.getScore())); +// } +// }); +// +// listView.setOnMouseClicked(evt -> { +// if (evt.getClickCount() < 1) return; +// kst4contest.controller.ScoreService.TopCandidate c = listView.getSelectionModel().getSelectedItem(); +// if (c == null) return; +// +// ChatMember resolved = resolveChatMemberForTopCandidate(c); +// if (resolved == null) return; +// +// // Try to select in table (reuses existing selection logic) +// if (tbl_chatMember.getItems().contains(resolved)) { +// tbl_chatMember.getSelectionModel().select(resolved); +// tbl_chatMember.scrollTo(resolved); +// } else { +// // Fallback: if filtered out, still show FurtherInfo + prepare /cq +// selectedCallSignInfoStageChatMember = resolved; +// chatcontroller.getScoreService().setSelectedChatMember(selectedCallSignInfoStageChatMember); +// +// selectedCallSignFurtherInfoPane.getChildren().setAll(generateFurtherInfoAbtSelectedCallsignBP(resolved)); +// txt_chatMessageUserInput.clear(); +// txt_chatMessageUserInput.setText("/cq " + resolved.getCallSign() + " "); +// txt_chatMessageUserInput.requestFocus(); +// txt_chatMessageUserInput.selectEnd(); +// +// // Keep ScoreService selection in sync +// chatcontroller.getScoreService().setSelectedChatMember(resolved); +// } +// }); +// +// pane.setTop(header); +// pane.setCenter(listView); +// return pane; +// } + + /** + * Builds the compact priority candidate area for the right side of the main UI. + * + * The former implementation showed the complete priority list permanently. + * That used a lot of vertical space although normally only the first one or two + * candidates are relevant during live operation. + * + * New behaviour: + * - show only Top 1 and Top 2 directly in the main window + * - click Top 1/Top 2 to select that candidate immediately + * - use "more" to open the full priority list in a separate window + */ + + + + /** + * Resolves and selects a priority candidate. + * + *

The common selection helper is used deliberately. It updates Further Info, + * prepares the directed message and selects the corresponding table row when + * the row is currently visible. A candidate hidden by an active table filter + * remains usable without changing or resetting that filter.

+ */ + private void selectTopCandidate(kst4contest.controller.ScoreService.TopCandidate candidate) { + if (candidate == null) { + return; + } + + ChatMember resolved = resolveChatMemberForTopCandidate(candidate); + + if (resolved == null) { + return; + } + + /* + * This is an explicit operator action and therefore follows the same path + * as a timeline click. The exact callsign and category stored in the + * TopCandidate remain authoritative. + * + * focusChatMemberAndPrepareCq() also handles candidates which are currently + * hidden by a FilteredList. In that case the table row cannot be selected, + * but Further Info, ScoreService selection and the prepared /cq message are + * still updated. + */ + focusChatMemberAndPrepareCq(resolved); + } + + /** + * Opens the complete priority candidate list in a separate window. + * + * This keeps the main UI compact while still making the full list available when + * the operator wants to inspect more than the first two candidates. + * + * The window is Compose. Its JavaFX predecessor was the only Stage this class + * constructed, and it carried the themed-scene registration and the shared system + * menu bar with it; both lose their only live caller here. + */ + private void showTopPriorityCandidatesWindow() { + TopPriorityCandidatesWindow.show( + () -> chatcontroller.getScoreService().topCandidates().snapshot(), + candidate -> uiDispatcher.runOnUi(() -> selectTopCandidate(candidate)), + chatcontroller.getChatPreferences().isGUI_darkModeActive(), + SETTINGS_WINDOW_FONT_SIZE_SP, + paletteStore, + languageStore + ); + } + + + private ChatMember resolveChatMemberForTopCandidate( + kst4contest.controller.ScoreService.TopCandidate c + ) { + + if (c == null + || c.getDisplayCallSign() == null + || c.getPreferredChatCategory() == null) { + return null; + } + + /* + * Resolve the concrete active login by full callsign and category. Falling + * back to callSignRaw could select a different suffix in the same category. + */ + return chatcontroller.findActiveChatMember( + c.getDisplayCallSign(), + c.getPreferredChatCategory() + ); + } + + + /** + * Pushes the current skeds and priority candidates into the Compose timeline strip + * above the send field. Driven by the sked list, the score-service pulse, the QTF + * change and an initial run; it reads the antenna azimuth fresh from preferences. + */ + private void updateTimelineVisuals() { + if (chatcontroller == null) return; + + if (!uiDispatcher.isUiThread()) { + uiDispatcher.runOnUi(this::updateTimelineVisuals); + return; + } + + List skedsSnapshot = new ArrayList<>(chatcontroller.getActiveSkeds().snapshot()); + List candidates = buildTimelinePriorityCandidateEvents(); + + if (composeMainWindowState != null) { + if (timelineFeed != null) { + timelineFeed.push( + skedsSnapshot, + candidates, + chatcontroller.getChatPreferences().getActualQTF().get(), + chatcontroller.getChatPreferences().getStn_antennaBeamWidthDeg() + ); + } + } + } + + /** + * Build candidate markers for the timeline: + * - Use ScoreService TopCandidates (already sorted) + * - Resolve representative ChatMember (preferred category if possible) + * - Use "next airplane arriving minute" as time basis + * - Bucket by minute, keep top 1-2 per minute (config above) + */ + private List buildTimelinePriorityCandidateEvents() { + + if (chatcontroller.getScoreService() == null) return Collections.emptyList(); + + long now = System.currentTimeMillis(); + + // Snapshot to avoid concurrent modifications (TopCandidates list is FX observable) + List topSnapshot = + new ArrayList<>(chatcontroller.getScoreService().topCandidates().snapshot()); + + Map> byMinute = new HashMap<>(); + + for (kst4contest.controller.ScoreService.TopCandidate c : topSnapshot) { + + ChatMember representative = resolveChatMemberForTopCandidate(c); + if (representative == null) continue; + + AirPlaneReflectionInfo apInfo = representative.getAirPlaneReflectInfo(); + + // choose airplane by (highest potential) then (shortest time) within preview window + int maxMinutes = (int) (TIMELINE_PREVIEW_TIME_MS / 60_000L); + NextApInfo selectedAp = findBestAirplane(apInfo, maxMinutes); + if (selectedAp == null) continue; + + long timeUntilMs = selectedAp.arrivingMinutes * 60_000L; + if (timeUntilMs < 0 || timeUntilMs > TIMELINE_PREVIEW_TIME_MS) continue; + + int minuteBucket = selectedAp.arrivingMinutes; + + byMinute.computeIfAbsent(minuteBucket, k -> new ArrayList<>()) + .add(new TimelineCandidateTmp(c, representative, selectedAp)); + } + + List out = new ArrayList<>(); + + for (Map.Entry> e : byMinute.entrySet()) { + + int minuteBucket = e.getKey(); + List bucket = e.getValue(); + + // Highest score first + bucket.sort((a, b) -> Double.compare(b.top.getScore(), a.top.getScore())); + + + // 1) Pick top-N in beam -> lanes 0..1 + List inBeam = new ArrayList<>(); + for (TimelineCandidateTmp tmp : bucket) { + if (chatcontroller.isChatMemberInMyBeam(tmp.representativeMember)) { + inBeam.add(tmp); + } + } + + // Avoid duplicates between beam and global selection + Set used = new HashSet<>(); + + int beamTake = Math.min(TIMELINE_BEAM_MARKERS_PER_MINUTE, inBeam.size()); + for (int lane = 0; lane < beamTake; lane++) { + + TimelineCandidateTmp tmp = inBeam.get(lane); + used.add(tmp.top.getCallSignRaw()); + + double az = (tmp.representativeMember.getQTFdirection() != null) ? tmp.representativeMember.getQTFdirection() : 0.0; + long timeUntilMs = minuteBucket * 60_000L; + + String tooltip = buildTimelineCandidateTooltip(tmp, minuteBucket); + int potential = (tmp.nextAp != null && tmp.nextAp.plane != null) ? tmp.nextAp.plane.getPotential() : 0; + + out.add(new TimelineCandidate( + tmp.top.getCallSignRaw(), + tmp.top.getDisplayCallSign(), + tmp.top.getPreferredChatCategory(), + timeUntilMs, + minuteBucket, + lane, // lanes 0..1 = in-beam + az, + tmp.top.getScore(), + potential, + tooltip + )); + } + + // 2) Pick top-N global distinct -> lanes 2..3 + int globalAdded = 0; + for (TimelineCandidateTmp tmp : bucket) { + + if (globalAdded >= TIMELINE_PRIORITY_MARKERS_PER_MINUTE) break; + if (used.contains(tmp.top.getCallSignRaw())) continue; + + double az = (tmp.representativeMember.getQTFdirection() != null) ? tmp.representativeMember.getQTFdirection() : 0.0; + long timeUntilMs = minuteBucket * 60_000L; + + String tooltip = buildTimelineCandidateTooltip(tmp, minuteBucket); + int potential = (tmp.nextAp != null && tmp.nextAp.plane != null) ? tmp.nextAp.plane.getPotential() : 0; + + int laneIndex = TIMELINE_BEAM_MARKERS_PER_MINUTE + globalAdded; // lanes 2..3 + + out.add(new TimelineCandidate( + tmp.top.getCallSignRaw(), + tmp.top.getDisplayCallSign(), + tmp.top.getPreferredChatCategory(), + timeUntilMs, + minuteBucket, + laneIndex, + az, + tmp.top.getScore(), + potential, + tooltip + )); + + globalAdded++; + } + } + + out.sort(Comparator + .comparingInt(TimelineCandidate::getMinuteBucket) + .thenComparingInt(TimelineCandidate::getLaneIndex)); + + return out; + } + + private String buildTimelineCandidateTooltip(TimelineCandidateTmp tmp, int minuteBucket) { + AirPlane p = tmp.nextAp.plane; + + String planeStr = "-"; + if (p != null) { + planeStr = p.getApCallSign() + + " | " + p.getPotencialDescriptionAsWord() + + " | pot " + p.getPotential() + + " | dist " + p.getDistanceKm() + " km"; + } + + NextApInfo earliest = findEarliestAirplane( + tmp.representativeMember.getAirPlaneReflectInfo(), + (int) (TIMELINE_PREVIEW_TIME_MS / 60_000L) + ); + + String earliestStr = ""; + if (earliest != null && earliest.plane != null) { + // only show if it differs from the selected/best plane minute + if (earliest.arrivingMinutes != minuteBucket) { + earliestStr = "\nearliest AP: +" + earliest.arrivingMinutes + + " min (pot " + earliest.plane.getPotential() + "%)"; + } + } + + return tmp.top.getDisplayCallSign() + + "\nscore: " + String.format(Locale.US, "%.0f", tmp.top.getScore()) + + "\nbest AP: +" + minuteBucket + " min" + + "\nplane: " + planeStr + + earliestStr; + } + + /** + * Select the airplane that should drive timeline/sked decisions. + * + * Rule: prefer highest potential; if tied, prefer shortest arriving time. + * Only considers planes within [0..maxMinutes] to avoid dropping stations completely. + */ + private NextApInfo findBestAirplane(AirPlaneReflectionInfo apInfo, int maxMinutes) { + if (apInfo == null) return null; + if (apInfo.getRisingAirplanes() == null) return null; + + AirPlane best = null; + int bestMin = Integer.MAX_VALUE; + int bestPot = Integer.MIN_VALUE; + + for (AirPlane p : apInfo.getRisingAirplanes()) { + if (p == null) continue; + + int m = p.getArrivingDurationMinutes(); + if (m < 0 || m > maxMinutes) continue; + + int pot = p.getPotential(); + + // primary: potential DESC, secondary: time ASC + if (best == null || pot > bestPot || (pot == bestPot && m < bestMin)) { + best = p; + bestPot = pot; + bestMin = m; + } + } + + if (best == null) return null; + return new NextApInfo(best, bestMin); + } + + /** + * Select the earliest airplane (used for additional tooltip info). + * Rule: prefer shortest arriving time; if tied, prefer higher potential. + */ + private NextApInfo findEarliestAirplane(AirPlaneReflectionInfo apInfo, int maxMinutes) { + if (apInfo == null) return null; + if (apInfo.getRisingAirplanes() == null) return null; + + AirPlane best = null; + int bestMin = Integer.MAX_VALUE; + + for (AirPlane p : apInfo.getRisingAirplanes()) { + if (p == null) continue; + + int m = p.getArrivingDurationMinutes(); + if (m < 0 || m > maxMinutes) continue; + + if (m < bestMin) { + bestMin = m; + best = p; + } else if (m == bestMin && best != null && p.getPotential() > best.getPotential()) { + best = p; + } + } + + if (best == null || bestMin == Integer.MAX_VALUE) return null; + return new NextApInfo(best, bestMin); + } + + + + + + + + + + + + /** + * Switches every Compose window to the dark or light design for the running session. + * The per-profile startup design is not changed here. + */ + private void applyTheme(boolean darkMode) { + LOGGER.info("Switching GUI design to " + (darkMode ? "dark" : "light") + " mode"); + + chatcontroller.getChatPreferences().setGUI_darkModeActive(darkMode); + + MainWindowHost.applyDarkMode(darkMode); + SettingsWindow.applyDarkMode(darkMode); + UpdateWindow.applyDarkMode(darkMode); + MonitorWindow.applyDarkMode(darkMode); + kst4contest.view.compose.map.StationMapWindow.applyDarkMode(darkMode); + TopPriorityCandidatesWindow.applyDarkMode(darkMode); + } + + /** + * Title of the macOS connection state menu, e.g. "🟢 LINK: Connected". + */ + static String macOsConnectionStateMenuTitle(On4KstConnectionState state) { + On4KstConnectionState effectiveState = state == null + ? On4KstConnectionState.DISCONNECTED : state; + return switch (effectiveState) { + case ONLINE -> "🟢 LINK: Connected"; + case CONNECTING, WAITING_FOR_LOGIN_PROMPT, AUTHENTICATING, + SYNCING_MAIN_CHAT, SYNCING_SECOND_CHAT -> "🟡 LINK: Connecting…"; + case STOPPING -> "🟡 LINK: Disconnecting…"; + case RECONNECT_WAIT -> "🔴 LINK: Reconnecting…"; + case DISCONNECTED -> "🔴 LINK: Disconnected"; + }; + } + + + /***************************************************** + * Sked warning Initializing and functional section + ****************************************************/ + + private void updateConnectionStateIndicator( + On4KstConnectionState state, + String detail + ) { + if (!uiDispatcher.isUiThread()) { + LOGGER.warning( + "Connection indicator update arrived outside the JavaFX thread; " + + "rescheduling it safely"); + uiDispatcher.runOnUi(() -> updateConnectionStateIndicator(state, detail)); + return; + } + + On4KstConnectionState effectiveState = state == null + ? On4KstConnectionState.DISCONNECTED : state; + String stateDetail = detail == null || detail.isBlank() + ? effectiveState.name() : detail; + + /* + * One write, not two. This method used to push the same pair into the Compose + * surroundings twice - once here and once again below the tooltip update - which + * is invisible until one of the two starts carrying stale values. + */ + if (connectionStateFeed != null) { + connectionStateFeed.push(state, detail); + } + + logConnectionIndicatorTransition(effectiveState, stateDetail); + } + + private void logConnectionIndicatorTransition( + On4KstConnectionState newState, + String newDetail + ) { + boolean stateChanged = newState != lastDisplayedConnectionState; + boolean detailChanged = !Objects.equals( + newDetail, lastDisplayedConnectionDetail); + if (!stateChanged && !detailChanged) { + return; + } + + On4KstConnectionState previousState = lastDisplayedConnectionState; + Level logLevel = switch (newState) { + case DISCONNECTED, RECONNECT_WAIT -> Level.WARNING; + default -> Level.INFO; + }; + + LOGGER.log(logLevel, + "ON4KST connection indicator: {0} -> {1}; detail: {2}", + new Object[] { + previousState == null ? "UNINITIALIZED" : previousState, + newState, + newDetail + }); + + lastDisplayedConnectionState = newState; + lastDisplayedConnectionDetail = newDetail; + } + + + /** + * Shows the sked warning in the Compose main window's notice strip. + * + * The JavaFX blinking button this used to drive belonged to the window that is never + * shown; it is gone. The Compose notice carries its own show/hide timing, so the + * blink timeline went with the button rather than being reimplemented here. + */ + private void showBlinkingSkedWarnIndicator(String text) { + if (composeMainWindowState != null) { + uiDispatcher.runOnUi(() -> composeMainWindowState.getSkedNotice().show(text, text)); + } + } + + + /***************************************************** + * Band-Upgrade warning (after log entry) section + ****************************************************/ + + private void maybeShowBandUpgradeIndicator(String key, ThreadStateMessage msg) { + if (msg == null) return; + + String nick = msg.getThreadNickName() == null ? "" : msg.getThreadNickName().toLowerCase(Locale.ROOT); + String k = key == null ? "" : key.toLowerCase(Locale.ROOT); + + boolean isBandUpgrade = k.contains("bandupgrade") || nick.contains("bandupgrade"); + if (!isBandUpgrade) return; + + String buttonText = msg.getRunningInformationTextDescription(); + if (buttonText == null || buttonText.isBlank()) buttonText = "BAND+"; + + String tooltip = msg.getRunningInformation(); + if (tooltip == null || tooltip.isBlank()) tooltip = buttonText; + + final String finalButtonText = buttonText; + final String finalTooltip = tooltip; + + uiDispatcher.runOnUi(() -> showBlinkingBandUpgradeIndicator(finalButtonText, finalTooltip)); + } + + /** + * Shows the band-upgrade hint in the Compose main window's notice strip. + * + * As with the sked warning, the JavaFX blinking button belonged to the never-shown + * window and is gone; the Compose notice owns its own timing. + */ + private void showBlinkingBandUpgradeIndicator(String buttonText, String tooltipText) { + if (composeMainWindowState != null) { + uiDispatcher.runOnUi(() -> composeMainWindowState.getBandUpgradeNotice().show(buttonText, tooltipText)); + } + } + +/** + * End Band-Upgrade section + */ + + + /** + * End Sked warning section + */ + + + + /** + * Stores the last automatically prepared text in the send input field. + * + * This is used to distinguish between: + * - text that KST4Contest created automatically, e.g. "/cq DL1ABC " + * - text that the operator has already edited manually + * + * Only automatically prepared text may be overwritten by a later automatic + * preparation. Manually typed text must never be destroyed by a table refresh. + */ + + /** + * Callsign behind the last automatically prepared /cq command. + * + * This is important for category resolution while sending. If the visible text is + * "/cq DL1ABC ..." and a later table refresh changes the selected ChatMember, the + * outgoing message must still be sent in the category that belonged to DL1ABC. + */ + private String lastAutoPreparedCqTargetCallsign = ""; + + /** + * Chat category that belonged to the last automatically prepared /cq target. + * + * The send handler uses this as the strongest category hint when the current + * input still targets the same callsign. + */ + private ChatCategory lastAutoPreparedCqTargetCategory = null; + + /** + * Guard flag for programmatic table selections. + * + * Some UI actions intentionally select a row in the ChatMember table for visual + * feedback. Those programmatic selections must not run the normal user-selection + * handler again, otherwise /cq preparation can happen twice or at the wrong time. + */ + + + + + /** + * True once this runtime released its resources. Shutdown must stay idempotent + * because it is reached both through the JavaFX stop() callback and explicitly. + */ + /** + * Guards the teardown against running twice. + * + *

Atomic because two threads can reach it since the shutdown hook replaced + * {@code Application.stop()}: the user-interface thread through + * {@code ApplicationRuntimeLauncher.exitApplication}, and the hook's own thread on a + * SIGTERM. A plain field let both pass the check, which means a double disconnect, a + * double preferences flush, and {@code rosterBindings.forEach(dispose)} racing + * {@code rosterBindings.clear()}. {@code compareAndSet} is what makes the javadoc + * below true rather than nearly true.

+ */ + private final java.util.concurrent.atomic.AtomicBoolean runtimeShutdownDone = + new java.util.concurrent.atomic.AtomicBoolean(); + +// Stage stage_selectedCallSignInfoStage; + ChatMember selectedCallSignInfoStageChatMember; + + + + + + + + /** + * Resolves the operator profile this runtime works with. + * + *

Only executed on the very first launch. A profile switch sets the profile before + * building the new runtime, so the resolution is skipped there.

+ * + *

An installation with no or exactly one profile is resolved without asking + * anything, which keeps the single operator startup exactly as it was.

+ * + * @return true if the application may continue starting up + */ + private boolean resolveOperatorProfileIfRequired() { + + if (ActiveOperatorProfile.isInitialized()) { + return true; + } + + OperatorProfileBootstrap bootstrap = new OperatorProfileBootstrap(); + OperatorProfileSelection resolvedProfile = bootstrap.resolveAtStartup( + new OperatorProfileStore(), + CommandLineOptions.remembered(), + OperatorProfilePickerWindow::showAndSelect); + + if (bootstrap.getStartupWarning() != null) { + ComposeAlert.acknowledge( + kst4contest.view.i18n.CurrentStrings.get().getAlertProfileTitle(), + kst4contest.view.i18n.CurrentStrings.get().getAlertProfileNotFound(), + bootstrap.getStartupWarning()); + } + + if (resolvedProfile == null) { + System.exit(0); + return false; + } + + ActiveOperatorProfile.set(resolvedProfile); + return true; + } + + /** + * Returns the window title suffix naming the active operator profile. + * + *

Empty for the historic single profile installation, so nothing changes visually + * for operators who never create a second profile.

+ * + * @return the suffix to append to a window title, never null + */ + private String buildOperatorProfileTitleSuffix() { + + OperatorProfileSelection activeProfile = ActiveOperatorProfile.get(); + + if (activeProfile == null || activeProfile.getProfile().isRootProfile()) { + return ""; + } + + return " - " + activeProfile.getProfile().getDisplayName(); + } + + /** + * Lets the operator pick another profile and rebuilds the runtime for it. + * + *

Offers to create a second profile when only one exists, because the menu entry + * is the discoverable place to find the feature at all.

+ */ + private void showOperatorProfileSwitchDialog() { + + OperatorProfileStore profileStore = new OperatorProfileStore(); + List selectableProfiles = profileStore.loadProfiles(); + + if (selectableProfiles.size() < 2) { + ComposeAlert.acknowledge( + kst4contest.view.i18n.CurrentStrings.get().getAlertProfilesTitle(), + kst4contest.view.i18n.CurrentStrings.get().getAlertOnlyOneProfile(), + kst4contest.view.i18n.CurrentStrings.get().getAlertOnlyOneProfileBody(), + chatcontroller.getChatPreferences().isGUI_darkModeActive()); + return; + } + + OperatorProfileSelection activeProfile = ActiveOperatorProfile.get(); + String activeProfileId = activeProfile == null ? null : activeProfile.getProfile().getProfileId(); + + Optional chosenProfile = + OperatorProfilePickerWindow.showAndSelect(selectableProfiles, activeProfileId); + + if (chosenProfile.isEmpty()) { + return; + } + + if (chosenProfile.get().getProfileId().equalsIgnoreCase(activeProfileId)) { + return; + } + + requestOperatorProfileSwitch(chosenProfile.get()); + } + + /** + * Confirms and performs a switch to another operator profile. + * + *

Shared by the File menu and the profile settings tab, so both ask the same + * question before giving up the running session.

+ * + * @param targetProfile profile to activate + */ + private void requestOperatorProfileSwitch(OperatorProfile targetProfile) { + + if (targetProfile == null || !confirmOperatorProfileSwitch(targetProfile)) { + return; + } + + ApplicationRuntimeLauncher.switchProfile(targetProfile); + } + + /** + * Asks whether the running session may be given up for a profile switch. + * + * @param targetProfile profile the operator selected + * @return true if the switch may proceed + */ + private boolean confirmOperatorProfileSwitch(OperatorProfile targetProfile) { + + return ComposeAlert.confirm( + kst4contest.view.i18n.CurrentStrings.get().getAlertSwitchProfileTitle(), + kst4contest.view.i18n.CurrentStrings.get().alertSwitchProfileQuestion(targetProfile.getDisplayName()), + kst4contest.view.i18n.CurrentStrings.get().getAlertSwitchProfileBody(), + kst4contest.view.i18n.CurrentStrings.get().getDialogSwitchProfile(), + kst4contest.view.i18n.CurrentStrings.get().getDialogCancel(), + chatcontroller.getChatPreferences().isGUI_darkModeActive()); + } + + /** + * Releases every resource this runtime owns, without terminating the process. + * + *

Separated from {@link #stop()} so the same teardown can be reused when the + * operator switches to another profile and a fresh runtime is built afterwards. + * The method is idempotent and tolerates a runtime that never connected, because a + * switch may happen before the first login.

+ */ + public void shutdownRuntime() { + + if (!runtimeShutdownDone.compareAndSet(false, true)) { + return; + } + + LOGGER.info("Application is shutting down and closing all resources"); + + if (layoutAutosave != null) { + // Flush before cancelling, otherwise a pending debounced write would either + // be lost or land after a profile switch. + layoutAutosave.flushPending(); + layoutAutosave.cancelPending(); + } + + cancelViewTimer(timer_buildWindowTitle); + timer_buildWindowTitle = null; + +// timer_chatMemberTableSortTimer.purge(); +// timer_chatMemberTableSortTimer.cancel(); + + cancelViewTimer(timer_updatePrivatemessageTable); + timer_updatePrivatemessageTable = null; + + if (userListRefreshCoalescer != null) { + userListRefreshCoalescer.cancel(); + userListRefreshCoalescer = null; + } + + + + /* + * Every mirror holds a listener inside a core roster. Without releasing them + * a discarded runtime stays reachable across an operator profile switch. + */ + rosterBindings.forEach(RosterListBinding::dispose); + rosterBindings.clear(); + chatMemberListBinding = null; + selectedCallSignInfoMessageBinding = null; + + kst4contest.view.compose.map.StationMapWindow.INSTANCE.hide(); + TopPriorityCandidatesWindow.hide(); + + closeOwnedStages(); + + try { + if (chatcontroller != null) { + chatcontroller.disconnect(ApplicationConstants.DISCSTRING_DISCONNECT_AND_CLOSE); + } + } catch (Exception e) { + LOGGER.log(Level.WARNING, "Exception during disconnect", e); + } + chatcontroller.getMessageHistoryRecorder().close(); + closeFileLogging(); + } + + /** + * Cancels a timer created during user interface construction. + * + * @param timerToCancel timer to cancel, may be null when startup did not get that far + */ + private static void cancelViewTimer(Timer timerToCancel) { + + if (timerToCancel == null) { + return; + } + + timerToCancel.purge(); + timerToCancel.cancel(); + } + + + /** + * Closes every window this runtime opened, so no stale window survives a profile + * switch. The map window is closed by its own dispose method. + */ + private void closeOwnedStages() { + + /* + * The settings window is a Compose window, not a Stage, so it has to be closed + * by name. It carries the Connect button, so a copy left over from the previous + * profile would block the new one from opening its own. + */ + SettingsWindow.close(); + UpdateWindow.close(); + MonitorWindow.close(); + releaseMonitorListeners(); + // Etappe 5c: Compose Fenster bleibt beim Profilwechsel offen + // MainWindowHost.close(); + releaseComposeMainWindow(); + + } + + private void requestLayoutSave() { + if (layoutAutosave != null) { + layoutAutosave.requestSave(); + } + } + + + + /** + * Builds the running application: profile, chat controller, listeners and windows. + * + *

Toolkit-free on purpose. An operator profile switch calls this on a fresh + * instance, and it must not need a JavaFX stage to do so.

+ * + * @throws InterruptedException when startup is interrupted while waiting + * @throws IOException when a profile or resource file cannot be read + * @throws URISyntaxException when a configured address cannot be parsed + */ + public void startRuntime() throws InterruptedException, IOException, URISyntaxException { + + if (!resolveOperatorProfileIfRequired()) { + return; + } + + ApplicationRuntimeLauncher.setCurrent(this); + + ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, STYLE_DEFAULTCSSDAY_RESOURCE, STYLE_DEFAULTCSSDAY_FILE); + ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, STYLE_DEFAULTCSSEVENING_RESOURCE, STYLE_DEFAULTCSSEVENING_FILE); + ChatMember ownChatMemberObject = new ChatMember(); + OperatorProfileSelection activeOperatorProfile = ActiveOperatorProfile.get(); + + // instantiate the Chatcontroller with the user object and the files of the active profile + chatcontroller = new ChatController( + ownChatMemberObject, + this, + activeOperatorProfile.getPreferencesRelativeFileName(), + activeOperatorProfile.getWorkedDatabaseRelativeFileName(), + activeOperatorProfile.isSeedWorkedDatabaseFromResource(), + uiDispatcher); + setDebugFileLoggingEnabled(chatcontroller.getChatPreferences() + .isMessageHandling_debugModeToFileEnabled()); + layoutAutosave = new LayoutAutosave( + chatcontroller.getChatPreferences()::writeLayoutPreferencesToXmlFile, uiDispatcher); + // Every profile starts with its own configured design; the menu quick switch only lasts for the session. + chatcontroller.getChatPreferences().setGUI_darkModeActive( + chatcontroller.getChatPreferences().isGUI_darkModeActiveByDefault()); + /* + * The palette, before any window is built: every Compose window reads it, and a window + * built without it would draw the shipped colours until it was rebuilt. + */ + paletteStore = kst4contest.view.compose.PaletteStoreFactory.create( + chatcontroller.getChatPreferences(), activeOperatorProfile.getProfile()); + + languageStore = kst4contest.view.i18n.LanguageStoreFactory.create( + chatcontroller.getChatPreferences(), java.util.Locale.getDefault()); + messageVariableResolver = new MessageVariableResolver(chatcontroller.getChatPreferences()); + chatcontroller.setStatusListener(this); //callback interface for updating Thread events in visual + + // 1. Timeline an die Sked-Liste binden + chatcontroller.getActiveSkeds().addListener(skeds -> updateTimelineVisuals()); + + // 1. bind table to the sked list + chatcontroller.getScoreService().uiPulse().addListener(newVal -> { + updateTimelineVisuals(); + }); + + // Update the Compose timeline when the rotor direction changes. The azimuth is + // read fresh from preferences inside updateTimelineVisuals, so no setter is kept. + chatcontroller.getChatPreferences().getActualQTF().addListener(newV -> updateTimelineVisuals()); + + /* + * Sked reminder: feeds the Compose notice strip. Lives here, after the dead + * scene construction, because that is the only part of start() still standing; + * it used to sit inside the never-shown JavaFX build next to the sked-warning + * button that part 3 removed. + */ + chatcontroller.lastUiReminderEvent().addListener( + reminderEvent -> { + if (reminderEvent == null) { + return; + } + + String text = "REMINDER: " + + reminderEvent.getCallSignRaw() + + " T-" + + reminderEvent.getMinutesBefore() + + "m"; + + uiDispatcher.runOnUi( + () -> showBlinkingSkedWarnIndicator(text) + ); + } + ); + + /** + * Window selected callsign information + * Works with a ChatMember variable, initialized by a selected-listener of the Chatmemberlist + */ + + + + /** + * end Window selected callsign information + */ + + /** + * Window Cluster & qso of the other + * + * Compose now; see openMonitorWindow and kst4contest.view.compose.MonitorWindow. + */ + openMonitorWindow(); + + /* + * The Compose main window, beside this one, only on --compose-main-window. It is here + * rather than earlier because it reads the tables and the preferences this method has + * just finished building. + */ + openComposeMainWindowIfRequested(); + + /** + * Window updates + * + * Compose now; see openUpdateWindowIfAvailable and + * kst4contest.view.compose.UpdateWindow. + */ + openUpdateWindowIfAvailable(); + + /***************************************************************************** + * + * Settings window + * + * Compose now; see openSettingsWindow and kst4contest.view.compose. It is opened + * here because it carries the Connect button and is therefore the way into the + * chat, which is what the JavaFX window was shown for at startup too. + * + ****************************************************************************/ + openSettingsWindow(); + + + + //initialize the timeline + uiDispatcher.runOnUi(this::updateTimelineVisuals); + + /* + * Replaces Application.stop(), which only JavaFX ever called. This covers a SIGTERM + * and a closing terminal; the ordinary exit still goes through + * ApplicationRuntimeLauncher.exitApplication(), and shutdownRuntime is idempotent. + */ + Runtime.getRuntime().addShutdownHook( + new Thread(this::shutdownRuntime, "kst4contest-shutdown")); + } + + /** + * This is a helping class for providing information for the TimeLineView to give full information about the + * Chatmember objects on which the Sked object is referring to. + * @param sked + * @return + */ + private String buildSkedHoverInfo(ContestSked sked) { + if (sked == null || sked.getTargetCallsign() == null) return ""; + + String callRaw = sked.getTargetCallsign().trim().toUpperCase(); + + ChatMember member = null; + for (ChatMember cm : chatcontroller.getLst_chatMemberList().snapshot()) { + if (cm == null || cm.getCallSignRaw() == null) continue; + if (callRaw.equals(cm.getCallSignRaw().trim().toUpperCase())) { + member = cm; + break; + } + } + if (member == null) return ""; + + AirPlaneReflectionInfo ap = member.getAirPlaneReflectInfo(); + if (ap == null) return ""; + + StringBuilder sb = new StringBuilder(); + sb.append("AP reachable: ").append(ap.getAirPlanesReachableCntr()); + + if (ap.getRisingAirplanes() != null && !ap.getRisingAirplanes().isEmpty()) { + AirPlane a0 = ap.getRisingAirplanes().get(0); + sb.append("\nNext: ") + .append(a0.getArrivingDurationMinutes()) + .append(" min (") + .append(a0.getPotential()) + .append("%)"); + + if (ap.getRisingAirplanes().size() > 1) { + AirPlane a1 = ap.getRisingAirplanes().get(1); + sb.append(" / ") + .append(a1.getArrivingDurationMinutes()) + .append(" min (") + .append(a1.getPotential()) + .append("%)"); + } + } + return sb.toString(); + } + + + /** + * Formats the global worked/grid status for the worked-any column. + * + *

Status characters follow the user feedback: + *

    + *
  • empty = call not worked, grid not worked
  • + *
  • x = call worked
  • + *
  • o = grid worked, call not worked
  • + *
  • xo = call and grid worked
  • + *
+ * + *

The call status is based on {@link ChatMember#isWorked()}, i.e. worked-any. + * The grid status is based on the four-character grid square worked on any band.

+ * + * @param member station row + * @return compact status text + */ + private String formatWorkedAnyGridStatus(ChatMember member) { + if (member == null) { + return ""; + } + + boolean callWorked = member.isWorked(); + boolean gridWorked = chatcontroller != null && chatcontroller.isGridSquareWorkedAny(member); + + if (callWorked && gridWorked) { + return "xo"; + } + + if (callWorked) { + return "x"; + } + + if (gridWorked) { + return "o"; + } + + return ""; + } + + /** + * Builds a tooltip for the worked-any/grid-status cell. + * + * @param member station row + * @return tooltip text + */ + private String buildWorkedAnyGridStatusTooltip(ChatMember member) { + if (member == null) { + return "empty = call not worked, grid not worked\n" + + "x = call worked\n" + + "o = grid worked\n" + + "xo = call and grid worked"; + } + + String grossField = WorkedGrossFieldCache.extractGrossField(member.getQra()); + String gridText = grossField == null + ? kst4contest.view.i18n.CurrentStrings.get().getTooltipUnknownGrid() + : kst4contest.view.i18n.CurrentStrings.get().tooltipGrid(grossField); + + return kst4contest.view.i18n.CurrentStrings.get().getTooltipWorkedStatusLegend() + + kst4contest.view.i18n.CurrentStrings.get().tooltipWorkedStatusThisStation( + member.isWorked() ? kst4contest.view.i18n.CurrentStrings.get().getTooltipYes() : kst4contest.view.i18n.CurrentStrings.get().getTooltipNo(), + chatcontroller != null && chatcontroller.isGridSquareWorkedAny(member) + ? kst4contest.view.i18n.CurrentStrings.get().getTooltipYes() : kst4contest.view.i18n.CurrentStrings.get().getTooltipNo(), + gridText); + } + +// /** +// * +// * resets the style of the not selected direction buttons +// * +// * REPLACED BY CSS USAGE +// * @deprecated +// * @param exceptThisButton +// * @return +// */ +// public boolean uiHelper_recolorQtfDirectionButtonsExceptThisOne(Button exceptThisButton) { +// +//// Button[] qtfButtons = new Button[8]; +// +// for (int i = 0; i < btnQtfButtonsAvl.length; i++) { +// +//// if (!btnQtfButtonsAvl[i].equals(exceptThisButton)) { +//// btnQtfButtonsAvl[i].setStyle(""); +//// } else { +//// btnQtfButtonsAvl[i].setStyle("-fx-background-color:\n" + +//// " linear-gradient(#f0ff35, #a9ff00),\n" + +//// " radial-gradient(center 50% -40%, radius 200%, #b8ee36 45%, #80c800 50%);\n" + +//// " -fx-background-radius: 6, 5;\n" + +//// " -fx-background-insets: 0, 1;\n" + +//// " -fx-effect: dropshadow( three-pass-box , rgba(0,0,0,0.4) , 5, 0.0 , 0 , 1 );\n" + +//// " -fx-text-fill: #395306;"); //Todo fancy button style +//// } +// +// } +// +// return true; +// +// } + + + /** + * Asks whether the chat connection may be given up, and quits when it may. + * + *

Blocking on purpose: the answer decides whether the application exits. The + * former {@code WindowEvent} parameter is gone with the JavaFX stage; both callers + * passed null and the body never read it.

+ */ + private void closeWindowEvent() { + System.out.println("Window close request ..."); + + /* + * ConfirmKind.YES and not the default: the JavaFX dialog used ButtonType.YES here, + * and JavaFX ordered YES ahead of CANCEL on Linux and Windows but behind it on + * macOS. The profile-switch confirmation used OK_DONE and orders the other way on + * Linux, so the two genuinely differ. + */ + boolean quit = ComposeAlert.confirm( + kst4contest.view.i18n.CurrentStrings.get().getAlertQuitTitle(), + null, + kst4contest.view.i18n.CurrentStrings.get().getAlertQuitQuestion(), + kst4contest.view.i18n.CurrentStrings.get().getDialogYes(), + kst4contest.view.i18n.CurrentStrings.get().getDialogCancel(), + chatcontroller.getChatPreferences().isGUI_darkModeActive(), + ConfirmKind.YES); + + if (quit) { + System.out.println("closewindowevent: exiting the application"); + + // Routed through the launcher so the runtime that is actually live + // releases its resources. After a profile switch that is no longer the + // instance JavaFX would call stop() on. + ApplicationRuntimeLauncher.exitApplication(); + } + } + + /** + * Informs a user about a warning, shows given String in simple alertwindow + * + */ + public static void alertWindowEvent(String warning) { + System.out.println("Alert due to ... " + warning); + + /* + * Static, and also called from ApplicationRuntimeLauncher after the runtime is + * already gone, so there are no preferences left to read a design from. + */ + ComposeAlert.show("WARNING", null, warning); + } + +// public void updateStatusButtons() { +// //TODO: Hier muss noch was hin +//// get +// } + + + public static void main(String[] args) { + setupFileLogging(); + + CommandLineOptions.remember(CommandLineOptions.parse( + args == null ? null : java.util.List.of(args))); + + try { + new Kst4ContestApplication().startRuntime(); + } catch (Exception startupProblem) { + LOGGER.log(java.util.logging.Level.SEVERE, "Could not start KST4Contest", startupProblem); + ComposeAlert.acknowledge( + "KST4Contest", + "KST4Contest could not be started.", + String.valueOf(startupProblem.getMessage())); + System.exit(1); + } + } + + + private static void setupFileLogging() { + if (fileLogging != null) { + return; + } + try { + Path logFile = Path.of(ApplicationFileUtils.getFilePath( + ApplicationConstants.APPLICATION_NAME, + "kst4contest-errors.log")); + // Start conservatively until the persisted preference has been loaded. + fileLogging = new ApplicationFileLogging(logFile, false); + } catch (IOException e) { + System.err.println("Could not set up file logging: " + e.getMessage()); + } + } + + private static void setDebugFileLoggingEnabled(boolean enabled) { + if (fileLogging != null) { + fileLogging.setDebugEnabled(enabled); + } + } + + private static void closeFileLogging() { + if (fileLogging != null) { + fileLogging.close(); + fileLogging = null; + } + } + + @Override + public void onThreadStatusChanged( + String key, + ThreadStateMessage threadStateMessage + ) { + if (threadStateMessage == null) { + LOGGER.log(Level.WARNING, + "Ignoring empty thread-status update from source {0}", + key == null ? "UNKNOWN" : key); + return; + } + if (key == null || key.isBlank()) { + LOGGER.log(Level.WARNING, + "Ignoring thread-status update without a source key. Detail: {0}", + threadStateMessage.getRunningInformation()); + return; + } + + if ("ON4KST".equalsIgnoreCase(key)) { + String detail = threadStateMessage.getRunningInformation(); + uiDispatcher.runOnUi(() -> updateConnectionStateIndicator( + chatcontroller.getOn4KstConnectionState(), detail)); + return; + } + + uiDispatcher.runOnUi(() -> updateStatusButton(key, threadStateMessage)); + maybeShowBandUpgradeIndicator(key, threadStateMessage); + } + + + public void onConnectionStateChanged( + On4KstConnectionState state, + String detail + ) { + On4KstConnectionState effectiveState = state; + if (effectiveState == null) { + LOGGER.log(Level.WARNING, + "Received ON4KST connection callback without a state; " + + "treating it as disconnected. Detail: {0}", + detail); + effectiveState = On4KstConnectionState.DISCONNECTED; + } + + On4KstConnectionState stateToDisplay = effectiveState; + uiDispatcher.runOnUi(() -> updateConnectionStateIndicator(stateToDisplay, detail)); + } + + @Override + public void onSimpleLogFileCreated(Path filePath) { + ComposeAlert.showWithLink( + kst4contest.view.i18n.CurrentStrings.get().getAlertSimpleLogTitle(), + kst4contest.view.i18n.CurrentStrings.get().getAlertSimpleLogHeader(), + kst4contest.view.i18n.CurrentStrings.get().alertSimpleLogBody(filePath), + kst4contest.view.i18n.CurrentStrings.get().getAlertSimpleLogLink(), + SIMPLE_LOG_MANUAL_URL, + chatcontroller.getChatPreferences().isGUI_darkModeActive()); + } + + + /** + * Forces the station FilteredList to evaluate all active predicates again. + * + *

Several filters depend on mutable ChatMember fields, for example worked + * flags, AirScout windows or calculated Tropo values. Updating such fields does + * not necessarily create a JavaFX list-change event. Therefore we explicitly + * re-apply the combined predicate instead of adding/removing a dummy predicate. + * The dummy-predicate trick can corrupt SortedList mapping in JavaFX.

+ * + *

applyChatMemberFilterPredicates() itself guards against the resulting + * spurious TableView selection events, so no extra guard is needed here.

+ */ + private void forceChatMemberFilterRefresh() { + updateComposeFilters(); + applyChatMemberFilterPredicates(); + } + + private void updateComposeFilters() { + if (composeMainWindowState == null) return; + kst4contest.view.compose.StationFilterState state = composeMainWindowState.getStationFilter(); + + String text = state.getSearchText().trim(); + boolean hasText = !text.isEmpty(); + + java.util.function.Predicate unifiedPredicate = member -> { + if (hasText) { + String cs = member.getCallSign(); + if (cs == null || !cs.toUpperCase(java.util.Locale.ROOT).contains(text.toUpperCase(java.util.Locale.ROOT))) { + return false; + } + } + + if (state.isOn(kst4contest.view.compose.StationFilter.ONLY_NEW_GRIDS) && !chatcontroller.isNewGridSquare(member)) return false; + if (state.isOn(kst4contest.view.compose.StationFilter.TROPO_REACHABLE) && !isReachableViaTropoFilterMatch(member)) return false; + if (state.isOn(kst4contest.view.compose.StationFilter.NEW_BANDS) && !isNewBandOpportunity(member)) return false; + if (state.isOn(kst4contest.view.compose.StationFilter.AIRSCOUT_NEXT_5_MIN) && !hasAsWindowInNextMinutes(member, 5)) return false; + + if (state.isOn(kst4contest.view.compose.StationFilter.MAX_QRB)) { + Double qrb = member.getQrb(); + if (qrb == null || qrb > state.getMaxQrbKm()) return false; + } + + if (state.isOn(kst4contest.view.compose.StationFilter.QTF)) { + Double qtf = member.getQTFdirection(); + if (qtf == null || !kst4contest.locatorUtils.DirectionUtils.isAngleInRange(qtf, state.getQtfDegrees(), chatcontroller.getChatPreferences().getStn_antennaBeamWidthDeg())) return false; + } + + if (state.isOn(kst4contest.view.compose.StationFilter.HIDE_INACTIVE)) { + long inactiveMinutes = kst4contest.controller.Utils4KST.time_getSecondsBetweenEpochAndNow(member.getActivityTimeLastInEpoch() + "") / 60; + if (inactiveMinutes > 20L) return false; + } + + if (state.isOn(kst4contest.view.compose.StationFilter.HIDE_WORKED_ANY) && member.isWorked()) return false; + + if (state.isOn(kst4contest.view.compose.StationFilter.HIDE_WORKED_50) && (member.isWorked50() || !member.isQrv50())) return false; + if (state.isOn(kst4contest.view.compose.StationFilter.HIDE_WORKED_70) && (member.isWorked70() || !member.isQrv70())) return false; + if (state.isOn(kst4contest.view.compose.StationFilter.HIDE_WORKED_144) && (member.isWorked144() || !member.isQrv144())) return false; + if (state.isOn(kst4contest.view.compose.StationFilter.HIDE_WORKED_432) && (member.isWorked432() || !member.isQrv432())) return false; + if (state.isOn(kst4contest.view.compose.StationFilter.HIDE_WORKED_23) && (member.isWorked1240() || !member.isQrv1240())) return false; + if (state.isOn(kst4contest.view.compose.StationFilter.HIDE_WORKED_13) && (member.isWorked2300() || !member.isQrv2300())) return false; + if (state.isOn(kst4contest.view.compose.StationFilter.HIDE_WORKED_9) && (member.isWorked3400() || !member.isQrv3400())) return false; + if (state.isOn(kst4contest.view.compose.StationFilter.HIDE_WORKED_6) && (member.isWorked5600() || !member.isQrv5600())) return false; + if (state.isOn(kst4contest.view.compose.StationFilter.HIDE_WORKED_3) && (member.isWorked10G() || !member.isQrv10G())) return false; + + return true; + }; + + composeMainWindowState.getStations().setRowFilter(unifiedPredicate::test); + + chatcontroller.clearChatMemberListFilterPredicates(); + chatcontroller.addChatMemberListFilterPredicate(unifiedPredicate); + } + + @Override + public void onUserListUpdated() { + scheduleUserListRefresh(null); + } + + @Override + public void onUserListUpdated(final String reason) { + scheduleUserListRefresh(reason); + } + + private void scheduleUserListRefresh(final String diagnosticReason) { + uiDispatcher.runOnUi(() -> { + if (diagnosticReason != null && !diagnosticReason.isBlank()) { + pendingUserListUpdateReason = diagnosticReason; + } + + if (userListRefreshCoalescer == null) { + userListRefreshCoalescer = new CoalescingTrigger( + USER_LIST_REFRESH_DELAY_MS, + () -> { + final String completedDiagnosticReason = pendingUserListUpdateReason; + pendingUserListUpdateReason = ""; + + forceChatMemberFilterRefresh(); + + if (composeMainWindowState != null) { + composeMainWindowState.getStations().forceRedraw(); + } + + refreshStationMapIfVisible(); + + if (!completedDiagnosticReason.isEmpty()) { + System.out.println("KST4Capp, UI Update Trigger: " + + completedDiagnosticReason); + } + }); + } + + userListRefreshCoalescer.trigger(); + }); + } + + +// public class MaidenheadLocatorMapPane extends Pane { +// +// private static final double MAP_WIDTH = 800; +// private static final double MAP_HEIGHT = 600; +// private static final double CIRCLE_RADIUS = 5; +// private static final double TEXT_OFFSET_X = 10; +// private static final double TEXT_OFFSET_Y = -10; +// +// public MaidenheadLocatorMapPane() { +// setPrefSize(MAP_WIDTH, MAP_HEIGHT); +// } +// +// public void addLocator(String locator, Color color) { +// double[] coords = locatorToCoordinates(locator); +// Circle circle = new Circle(coords[0], coords[1], CIRCLE_RADIUS, color); +// Text text = new Text(coords[0] + TEXT_OFFSET_X, coords[1] + TEXT_OFFSET_Y, locator); +// getChildren().addAll(circle, text); +// } +// +// public void connectLocators(String locator1, String locator2) { +// double[] coords1 = locatorToCoordinates(locator1); +// double[] coords2 = locatorToCoordinates(locator2); +// Line line = new Line(coords1[0], coords1[1], coords2[0], coords2[1]); +// getChildren().add(line); +// +// // Calculate distance between locators +// double distance = calculateDistance(coords1, coords2); +// +// // Calculate direction in degrees from locator1 to locator2 +// double direction = calculateDirection(coords1, coords2); +// +// // Format distance to display only two decimal places +// DecimalFormat df = new DecimalFormat("#.##"); +// +// // Create text for displaying distance and direction +// Text distanceText = new Text((coords1[0] + coords2[0]) / 2, (coords1[1] + coords2[1]) / 2, "Distance: " + df.format(distance) + " km"); +// Text directionText = new Text((coords1[0] + coords2[0]) / 2, (coords1[1] + coords2[1]) / 2 + 20, "Direction: " + df.format(direction) + "°"); +// getChildren().addAll(distanceText, directionText); +// } +// +// // Helper method to convert Maidenhead locator string to coordinates +// private double[] locatorToCoordinates(String locator) { +// double lon = (locator.charAt(0) - 'A') * 20 - 180; +// double lat = (locator.charAt(1) - 'A') * 10 - 90; +// lon += (locator.charAt(2) - '0') * 2; +// lat += (locator.charAt(3) - '0'); +// lon += (locator.charAt(4) - 'A') * 5.0 / 60; +// lat += (locator.charAt(5) - 'A') * 2.5 / 60; +// +// // Convert coordinates to map coordinates +// double x = (lon + 180) / 360 * MAP_WIDTH; +// double y = MAP_HEIGHT - (lat + 90) / 180 * MAP_HEIGHT; +// return new double[]{x, y}; +// } +// +// // Helper method to calculate distance between two coordinates (in km) +// private double calculateDistance(double[] coords1, double[] coords2) { +// double lon1 = Math.toRadians(coords1[0]); +// double lat1 = Math.toRadians(coords1[1]); +// double lon2 = Math.toRadians(coords2[0]); +// double lat2 = Math.toRadians(coords2[1]); +// +// double dlon = lon2 - lon1; +// double dlat = lat2 - lat1; +// +// double a = Math.pow(Math.sin(dlat / 2), 2) + Math.cos(lat1) * Math.cos(lat2) * Math.pow(Math.sin(dlon / 2), 2); +// double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); +// +// // Earth radius in km +// double radius = 6371; +// +// return radius * c; +// } +// +// // Helper method to calculate direction in degrees from coords1 to coords2 +// private double calculateDirection(double[] coords1, double[] coords2) { +// double lon1 = Math.toRadians(coords1[0]); +// double lat1 = Math.toRadians(coords1[1]); +// double lon2 = Math.toRadians(coords2[0]); +// double lat2 = Math.toRadians(coords2[1]); +// +// double dLon = lon2 - lon1; +// +// double y = Math.sin(dLon) * Math.cos(lat2); +// double x = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(dLon); +// +// double direction = Math.atan2(y, x); +// direction = Math.toDegrees(direction); +// direction = (direction + 360) % 360; +// +// return direction; +// } +// } + + + /** + * Returns the best currently selected ChatMember for actions that depend on a + * selected station. + * + *

The normal source is selectedCallSignInfoStageChatMember. As a fallback, + * the current table selection and the ScoreService selection are checked. If + * nothing is selected yet, null is returned. This is valid and must be handled + * by the caller.

+ * + * @return selected ChatMember or null if no station is selected + */ + private ChatMember getEffectiveSelectedChatMember() { + if (selectedCallSignInfoStageChatMember != null) { + return selectedCallSignInfoStageChatMember; + } + + /* + * The JavaFX station table used to sit between these two. It never received rows + * after the window was disconnected, so this branch could not fire. + */ + if (chatcontroller != null + && chatcontroller.getScoreService() != null + && chatcontroller.getScoreService().getSelectedChatMember() != null) { + return chatcontroller.getScoreService().getSelectedChatMember(); + } + + return null; + } + + + + + /** + * Checks whether an outgoing private message targets the local callsign. + * + * @param messageText outgoing message text + * @return {@code true} if the /cq target is the local station + */ + private boolean isMessageAddressedToOwnCallsign(String messageText) { + String targetCallsign = extractCqTargetCallsign(messageText); + + if (targetCallsign == null + || chatcontroller == null + || chatcontroller.getChatPreferences() == null) { + return false; + } + + String ownCallsign = chatcontroller.getChatPreferences().getStn_loginCallSign(); + return ownCallsign != null && targetCallsign.equalsIgnoreCase(ownCallsign.trim()); + } + + + + /** + * Resolves the chat category for an outgoing operator message. + * + *

If a station is selected, the message is sent in the category of that + * station. If no station is selected yet, the message is sent in the main chat + * category. This prevents NullPointerExceptions when the operator writes to the + * chat immediately after joining.

+ * + * @param selectedMember selected station, may be null + * @return category for the outgoing message, normally main or second category + */ + private ChatCategory resolveOutgoingChatCategory(ChatMember selectedMember) { + ChatCategory mainCategory = chatcontroller.getChatCategoryMain(); + ChatCategory secondCategory = chatcontroller.getChatCategorySecondChat(); + + if (selectedMember == null || selectedMember.getChatCategory() == null) { + return mainCategory; + } + + String categoryNumber = selectedMember.getChatCategory().getCategoryNumber() + ""; + + if (mainCategory != null + && categoryNumber.equals(mainCategory.getCategoryNumber() + "")) { + return mainCategory; + } + + if (secondCategory != null + && categoryNumber.equals(secondCategory.getCategoryNumber() + "")) { + return secondCategory; + } + + return mainCategory; + } + + + /** + * helper method, in cases of QRG ending qith 0 as double values, it will fill the ending 0 to the qrg string + * @param raw + * @return + */ + private static String formatQrgForUi(String raw) { + + if (raw == null) return ""; + String s = raw.trim(); + if (s.isEmpty()) return ""; + + // Einheitlich Punkt als Dezimaltrenner + s = s.replace(',', '.'); + + // Wenn es nicht numerisch ist: einfach anzeigen wie es ist + try { + Double.parseDouble(s); + } catch (NumberFormatException e) { + return s; + } + + int dot = s.indexOf('.'); + if (dot < 0) { + // keine Nachkommastellen -> .000 ergänzen + return s + ".000"; + } + + String dec = s.substring(dot + 1); + if (dec.length() >= 3) { + // schon >= 3 Nachkommastellen -> unverändert lassen + return s; + } + + StringBuilder sb = new StringBuilder(s); + while (dec.length() < 3) { + sb.append('0'); + dec += "0"; + } + return sb.toString(); + } + + + + + /************************************************************************************* + * Settings window (Compose) + * + * The window, its eleven tabs and the rules of every field live in Kotlin under + * kst4contest.view.compose. What stays here is the work only this class can do: + * rebuilding JavaFX controls, and starting or dropping the ON4KST session. + ************************************************************************************/ + + /** + * There is no configurable base font size; the JavaFX settings window used the + * platform default. This is the same value the operator profile picker uses, so both + * Compose windows read like the JavaFX ones next to them. + */ + private static final float SETTINGS_WINDOW_FONT_SIZE_SP = 12f; + + private final SettingsNotices settingsNotices = new SettingsNotices(); + + /** + * The monitor window's roster subscriptions. Held so shutdownRuntime can release + * them: a discarded runtime that still feeds a closed window keeps itself alive. + */ + private java.util.function.Consumer> monitorClusterListener; + + private java.util.function.Consumer> monitorChatListener; + + /** Releases the monitor window's roster subscriptions. */ + private void releaseMonitorListeners() { + + if (monitorClusterListener != null) { + chatcontroller.getLst_clusterMemberList().removeListener(monitorClusterListener); + monitorClusterListener = null; + } + + if (monitorChatListener != null) { + chatcontroller.getLst_globalChatMessageList().removeListener(monitorChatListener); + monitorChatListener = null; + } + } + + /***************************************************** + * The Compose main window, opened beside the JavaFX one + ****************************************************/ + + /** Held so the feeds can be released; a discarded runtime that still feeds a window lives on. */ + private MainWindowState composeMainWindowState; + + /** + * The palette of the active profile, handed to every Compose window. + * + * Built once per runtime start, which is also once per profile: a profile switch tears + * the runtime down and starts it again on a fresh application object, so there is no + * separate rebuild to do here. + */ + private kst4contest.view.compose.PaletteStore paletteStore; + + /** + * The interface language of the active profile, handed to every Compose window. + * + * Built once per runtime start, which is also once per profile: a profile switch tears the + * runtime down and starts it again on a fresh application object. + */ + private kst4contest.view.i18n.LanguageStore languageStore; + private java.util.function.Consumer> composeMemberListener; + private java.util.function.Consumer> composeChatListener; + private java.util.function.Consumer> composeClusterListener; + + /** + * Opens the Compose main window beside the JavaFX one. + * + *

Only on --compose-main-window, and never a second time. The two run side by side so + * the operator can compare them against a live session, which is the only way the + * differences of the last three Etappen came to light.

+ */ + private void openComposeMainWindowIfRequested() { + + // Etappe 5c: Compose Hauptfenster wird immer gestartet + // if (!CommandLineOptions.remembered().isComposeMainWindowRequested()) { + // return; + // } + + // if (MainWindowHost.isOpen()) { + // return; + // } + + ColumnWidthStore widths = new ColumnWidthStore() { + @Override + public Double width(String tableId, String columnId) { + java.util.OptionalDouble stored = + chatcontroller.getChatPreferences().getTableColumnWidth(tableId, columnId); + return stored.isPresent() ? stored.getAsDouble() : null; + } + + @Override + public void setWidth(String tableId, String columnId, double width) { + chatcontroller.getChatPreferences().setTableColumnWidth(tableId, columnId, width); + } + + @Override + public void requestSave() { + requestLayoutSave(); + } + }; + + /* + * Own table ids, deliberately. The Compose window's columns are the operator's to + * arrange separately while both windows are on screen; sharing the ids would let a + * drag in one silently rearrange the other. + */ + DataTableState stations = new DataTableState<>( + StationColumns.INSTANCE.all( + member -> { + Band band = resolveReachabilityBandForUi(member); + chatcontroller.getReachabilityService() + .ensureTropoMarginCalculated(member, band); + return member.formatTropoSsbMarginForBand(band); + }, + member -> parseTableDouble(formatPriorityScore(member)), + (member, band, worked) -> formatBandCellStatus(member, band, worked), + BandOpportunityResolver.getEnabledStationBands(chatcontroller.getChatPreferences())), + RowKeys.INSTANCE.byValue(member -> member.getCallSign() + "|" + + (member.getChatCategory() == null ? "" : member.getChatCategory().getCategoryNumber())), + "compose-stations", + widths); + + DataTableState directed = new DataTableState<>( + DirectedMessageColumns.INSTANCE.all( + () -> chatcontroller.getChatPreferences().getStn_loginCallSign(), + chatcontroller::formatChatMessageTextForDisplay), + RowKeys.INSTANCE.byReference(), + "compose-directed-messages", + widths); + + DataTableState publicMessages = new DataTableState<>( + PublicMessageColumns.INSTANCE.all(), + RowKeys.INSTANCE.byReference(), + "compose-public-messages", + widths); + + DataTableState cluster = new DataTableState<>( + MonitorColumns.INSTANCE.dxCluster(), + RowKeys.INSTANCE.byReference(), + "compose-dx-cluster", + widths); + + DataTableState qsoOfTheOther = new DataTableState<>( + MonitorColumns.INSTANCE.qsoOfTheOther(), + RowKeys.INSTANCE.byReference(), + "compose-qso-other", + widths); + + DataTableState selectedStationMessages = new DataTableState<>( + SelectedStationMessageColumns.INSTANCE.all(), + RowKeys.INSTANCE.byReference(), + "compose-selected-station-messages", + widths); + + MainMenuState menu = new MainMenuState(); + MainWindowSurroundings surroundings = new MainWindowSurroundings(menu); + + SelectedStationState selectedStation = new SelectedStationState( + member -> { + chatcontroller.propagateNotQrvStateToActiveMembers(member); + return kotlin.Unit.INSTANCE; + }, + this::createSkedFromCompose, + member -> kotlin.Unit.INSTANCE, + member -> kotlin.Unit.INSTANCE, + filter -> { + if (filter == null) { + return kotlin.Unit.INSTANCE; + } + Predicate predicate; + switch (filter) { + case PM_TO_ME: + predicate = chatMessage -> { + try { + if (chatMessage.getReceiver().getCallSign().equals("ALL") && !(chatMessage.getMessageText().toLowerCase().contains(chatcontroller.getChatPreferences().getStn_loginCallSign().toLowerCase()))) { + return false; + } + return ((chatMessage.getReceiver().getCallSign().equals(chatcontroller.getChatPreferences().getStn_loginCallSign())) || (chatMessage.getSender().getCallSign().equals(chatcontroller.getChatPreferences().getStn_loginCallSign()))) && + ((chatMessage.getReceiver().getCallSign().equals(selectedCallSignInfoStageChatMember.getCallSign())) || (chatMessage.getSender().getCallSign().equals(selectedCallSignInfoStageChatMember.getCallSign()))); + } catch (Exception e) { return false; } + }; + break; + case PM_TO_OTHER: + predicate = chatMessage -> { + try { + return (chatMessage.getSender().getCallSign().equals(selectedCallSignInfoStageChatMember.getCallSign()) && !chatMessage.getReceiver().getCallSign().equals("ALL") && !chatMessage.getReceiver().getCallSign().equals(chatcontroller.getChatPreferences().getStn_loginCallSign())) || + (chatMessage.getReceiver().getCallSign().equals(selectedCallSignInfoStageChatMember.getCallSign()) && !chatMessage.getReceiver().getCallSign().equals("ALL") && !chatMessage.getReceiver().getCallSign().equals(chatcontroller.getChatPreferences().getStn_loginCallSign())); + } catch (Exception e) { return false; } + }; + break; + case PUBLIC: + predicate = chatMessage -> { + try { + return chatMessage.getSender().getCallSign().equals(selectedCallSignInfoStageChatMember.getCallSign()) && chatMessage.getReceiver().getCallSign().equals("ALL"); + } catch (Exception e) { return false; } + }; + break; + case NOTHING: + default: + predicate = chatMessage -> { + try { + return chatMessage.getSender().getCallSign().equals(selectedCallSignInfoStageChatMember.getCallSign()) || chatMessage.getReceiver().getCallSign().equals(selectedCallSignInfoStageChatMember.getCallSign()); + } catch (Exception e) { return false; } + }; + break; + } + applySelectedCallSignInfoFilter(predicate); + return kotlin.Unit.INSTANCE; + }, + member -> { + if (member == null || member.getCallSignRaw() == null) { + return ""; + } + return formatDetectedRxBandsForCallsignRaw(member.getCallSignRaw(), 30L * 60L * 1000L); + }, + member -> { + if (member == null) return null; + java.util.EnumSet enabledBands = kst4contest.logic.BandOpportunityResolver.getEnabledStationBands(chatcontroller.getChatPreferences()); + return resolveDefaultSkedBand(member, enabledBands); + }); + + if (chatcontroller.getChatPreferences().isGuiOptions_defaultFilterPmToMe()) { + selectedStation.setMessageFilter(SelectedMessageFilter.PM_TO_ME); + } else if (chatcontroller.getChatPreferences().isGuiOptions_defaultFilterPmToOther()) { + selectedStation.setMessageFilter(SelectedMessageFilter.PM_TO_OTHER); + } else { + selectedStation.setMessageFilter(SelectedMessageFilter.NOTHING); + } + + TopPriorityState topPriority = new TopPriorityState( + this::composeTopStations, + member -> selectStationInCompose(selectedStation, stations, member)); + + ChatInputState chatInput = new ChatInputState(new ComposeChatInputActions(this)); + + composeMainWindowState = new MainWindowState( + BandOpportunityResolver.getEnabledStationBands(chatcontroller.getChatPreferences()), + chatcontroller.getChatPreferences(), + stations, + new StationFilterState(), + directed, + publicMessages, + cluster, + qsoOfTheOther, + selectedStationMessages, + selectedStation, + topPriority, + new TimelineState(), + chatInput, + menu, + surroundings, + new BlinkingNotice(), + new BlinkingNotice(), + new ThreadStatusButtons(), + new SplitterState( + 2, + chatcontroller.getChatPreferences().getGUImainWindowLeftSplitPane_dividerposition(), + SplitterState.DEFAULT_MIN_PANE_PX, + positions -> { + chatcontroller.getChatPreferences() + .setGUImainWindowLeftSplitPane_dividerposition(positions); + requestLayoutSave(); + return kotlin.Unit.INSTANCE; + }), + new SplitterState( + MainWindowState.MESSAGE_PANE_COUNT, + chatcontroller.getChatPreferences().getGUImessageSectionSplitpane_dividerposition(), + SplitterState.DEFAULT_MIN_PANE_PX, + positions -> { + chatcontroller.getChatPreferences() + .setGUImessageSectionSplitpane_dividerposition(positions); + requestLayoutSave(); + return kotlin.Unit.INSTANCE; + }), + new SplitterState( + MainWindowState.RIGHT_PANE_COUNT, + chatcontroller.getChatPreferences().getGUImainWindowRightSplitPane_dividerposition(), + SplitterState.DEFAULT_MIN_PANE_PX, + positions -> { + chatcontroller.getChatPreferences() + .setGUImainWindowRightSplitPane_dividerposition(positions); + requestLayoutSave(); + return kotlin.Unit.INSTANCE; + })); + + /* + * The feed, not the window construction, owns the timeline's data from here. + * Created beside the state it fills so its lifetime is that state's lifetime + * and not that of a JavaFX node nobody shows. + */ + timelineFeed = new kst4contest.view.feed.TimelineFeed( + composeMainWindowState.getTimeline(), uiDispatcher); + selectedStationMessagesFeed = new kst4contest.view.feed.SelectedStationMessagesFeed( + composeMainWindowState.getSelectedStationMessages(), uiDispatcher); + connectionStateFeed = new kst4contest.view.feed.ConnectionStateFeed( + composeMainWindowState.getSurroundings(), uiDispatcher); + + menu.setConnectLabel(buildComposeConnectLabel()); + + /* + * Subscribed first and seeded afterwards, so a message arriving in between is not + * missed — the order RosterListBinding uses for the same reason. + */ + composeMemberListener = rows -> uiDispatcher.runOnUi(() -> stations.replaceRows(rows)); + chatcontroller.getLst_chatMemberList().addListener(composeMemberListener); + + composeMainWindowState.setStationSelector(member -> { + selectStationInCompose(selectedStation, stations, member); + return kotlin.Unit.INSTANCE; + }); + + composeChatListener = rows -> uiDispatcher.runOnUi(() -> { + directed.replaceRows(chatcontroller.toMeMessages()); + publicMessages.replaceRows(rows); + qsoOfTheOther.replaceRows(chatcontroller.toOtherMessages()); + }); + chatcontroller.getLst_globalChatMessageList().addListener(composeChatListener); + + composeClusterListener = rows -> uiDispatcher.runOnUi(() -> cluster.replaceRows(rows)); + chatcontroller.getLst_clusterMemberList().addListener(composeClusterListener); + + if (chatcontroller.getScoreService() != null) { + chatcontroller.getScoreService().topCandidates().addListener(candidates -> uiDispatcher.runOnUi(() -> topPriority.refresh())); + } + uiDispatcher.runOnUi(() -> topPriority.refresh()); + + stations.replaceRows(chatcontroller.getLst_chatMemberList().snapshot()); + directed.replaceRows(chatcontroller.toMeMessages()); + publicMessages.replaceRows(chatcontroller.getLst_globalChatMessageList().snapshot()); + cluster.replaceRows(chatcontroller.getLst_clusterMemberList().snapshot()); + qsoOfTheOther.replaceRows(chatcontroller.toOtherMessages()); + /* + * The only push that does not check the feed for null, and deliberately so: the + * feed is assigned earlier in this same method, so a guard here could never fire + * and would read as a seam that does not exist. The other four sites are called + * from listeners that can run before this method does, which is why they check. + * If this block is ever moved above the assignment, the guard belongs back. + */ + if (selectedCallSignInfoMessageBinding != null) { + selectedStationMessagesFeed.push(selectedCallSignInfoMessageBinding.list()); + } + + double[] storedSize = chatcontroller.getChatPreferences().getGUIscn_ChatwindowMainSceneSizeHW(); + MainWindowSize size = MainWindowFrame.INSTANCE.startupSize( + storedSize, ScreenBounds.availableHeight(), ScreenBounds.availableWidth()); + + MainWindowHost.show( + composeMainWindowState, + new ComposeMenuActions(this), + buildOperatorProfileTitleSuffixForCompose(), + chatcontroller.getChatPreferences().isGUI_darkModeActive(), + SETTINGS_WINDOW_FONT_SIZE_SP, + paletteStore, + languageStore, + (float) size.getWidthDp(), + (float) size.getHeightDp(), + (width, height) -> { + /* + * Written to the profile now. It was deliberately dropped while the + * JavaFX window still existed, because two windows writing one size + * would have left the operator's arrangement to whichever was resized + * last. There is only this window left, so the size it is given back on + * the next start is the size the operator chose. + * + * Height first, then width: that is the order ChatPreferences stores + * and getScreenAwareMainSceneSize read. + */ + chatcontroller.getChatPreferences().setGUIscn_ChatwindowMainSceneSizeHW( + new double[] { height, width }); + requestLayoutSave(); + return kotlin.Unit.INSTANCE; + }, + /* + * Closing the main window quits the application, asking first — the same + * question the File menu's Exit asks. Without this the window would merely + * disappear and leave the client running with the chat connected. + */ + () -> { + closeWindowEvent(); + return kotlin.Unit.INSTANCE; + }, + () -> composeSkedBands(selectedStation.getSelected()), + address -> runOnUi(() -> ExternalDocuments.open(address)), + () -> { + runOnUi(() -> showSelectedCallsignOnMap()); + return kotlin.Unit.INSTANCE; + }, + () -> { + if (selectedCallSignInfoStageChatMember != null) { + chatcontroller.airScout_SendAsShowPathPacket(selectedCallSignInfoStageChatMember); + } + return kotlin.Unit.INSTANCE; + }, + member -> selectStationInCompose(selectedStation, stations, member), + message -> onDirectedMessageClickedInCompose(selectedStation, stations, composeMainWindowState.getChatInput(), message), + this::isOwnChatMessage, + this::chatMessageAgeSeconds, + () -> { + runOnUi(() -> { + updateComposeFilters(); + }); + return kotlin.Unit.INSTANCE; + }, + () -> { + runOnUi(() -> showTopPriorityCandidatesWindow()); + return kotlin.Unit.INSTANCE; + }, + candidate -> { + if (candidate == null) return kotlin.Unit.INSTANCE; + ChatMember resolved = resolveChatMemberForCallRawAndCategory( + candidate.getCallSignRaw(), candidate.getPreferredChatCategory()); + if (resolved != null) { + selectStationInCompose(selectedStation, stations, resolved); + composeMainWindowState.getChatInput().prepareCq(resolved.getCallSign(), false); + + // Sync with JavaFX state just in case + prepareCqTextForSelectedChatMember(resolved, false); + focusChatMemberAndPrepareCq(resolved, false); + } + return kotlin.Unit.INSTANCE; + }); + + updateComposeSurroundings(); + } + + /** + * Arranges a sked from the Compose panel, exactly as the JavaFX sked button does. + * + * @return whether it was arranged; a station without a bearing still gets one, at 0°, as + * the original did + */ + private boolean createSkedFromCompose( + final ChatMember selectedMember, + final int minutes, + final Band band, + final String mode) { + + if (selectedMember == null || band == null) { + return false; + } + + long skedTime = System.currentTimeMillis() + minutes * 60_000L; + double azimuth = + selectedMember.getQTFdirection() != null ? selectedMember.getQTFdirection() : 0.0; + + ContestSked sked = new ContestSked( + selectedMember.getCallSignRaw(), + selectedMember.getCallSign(), + selectedMember.getChatCategory(), + azimuth, + skedTime, + band); + + chatcontroller.addSked(sked); + chatcontroller.getScoreService().requestRecompute("sked-created"); + + // Arm PM reminders, exactly as the JavaFX Create sked handler does + if (composeMainWindowState != null) { + SelectedStationState ssState = composeMainWindowState.getSelectedStation(); + if (ssState.getRemindPm()) { + List offsets = parseMinuteOffsets(ssState.getReminderOffsets()); + chatcontroller.getSkedReminderService().armReminders( + sked.getTargetChatCallsign(), + sked.getTargetChatCategory(), + skedTime, + offsets + ); + } + } + + return true; + } + + /** The Connect item's label, built exactly as initMenuBar builds it. */ + private String buildComposeConnectLabel() { + /* + * Through the volatile bridge rather than a composition local: this runs on whatever + * thread rebuilt the menu state, not inside a composition. The menu picks the new + * label up the next time the state is rebuilt. + */ + kst4contest.view.i18n.Strings strings = kst4contest.view.i18n.CurrentStrings.get(); + + ChatCategory mainCat = chatcontroller.getChatPreferences().getLoginChatCategoryMain(); + if (mainCat == null) { + return strings.getConnectionConnect(); + } + + String label = strings.connectionConnectTo( + mainCat.getChatCategoryName(mainCat.getCategoryNumber())); + if (chatcontroller.getChatPreferences().isLoginToSecondChatEnabled()) { + ChatCategory secondCat = chatcontroller.getChatPreferences().getLoginChatCategorySecond(); + if (secondCat != null) { + label += " & " + secondCat.getChatCategoryName(secondCat.getCategoryNumber()); + } + } + return label; + } + + /** The profile name for the title, or null for the root profile. */ + private String buildOperatorProfileTitleSuffixForCompose() { + OperatorProfileSelection activeProfile = ActiveOperatorProfile.get(); + if (activeProfile == null || activeProfile.getProfile().isRootProfile()) { + return null; + } + return activeProfile.getProfile().getDisplayName(); + } + + /** The bands a sked can be arranged on for this station: enabled here, available there. */ + private java.util.List composeSkedBands(ChatMember selectedMember) { + if (selectedMember == null) { + return java.util.List.of(); + } + + java.util.List variants = + chatcontroller.findActiveChatMembersByRawCall(selectedMember.getCallSignRaw()); + if (variants.isEmpty()) { + variants = java.util.List.of(selectedMember); + } + + BandOpportunityResolver.Resolution resolution = + BandOpportunityResolver.resolve(variants, System.currentTimeMillis()); + EnumSet enabledBands = + BandOpportunityResolver.getEnabledStationBands(chatcontroller.getChatPreferences()); + + EnumSet available = EnumSet.copyOf(resolution.getAvailableBands()); + available.retainAll(enabledBands); + return new ArrayList<>(available); + } + + /** The score service's ranking, as the Compose priority bar wants it. */ + private java.util.List> composeTopStations() { + java.util.List> out = new ArrayList<>(); + + if (chatcontroller.getScoreService() == null) { + return out; + } + + for (ScoreService.TopCandidate candidate + : chatcontroller.getScoreService().topCandidates().snapshot()) { + + /* + * A candidate names a callsign, not a station. The first active variant is the one + * the JavaFX buttons resolved to as well; a callsign with no variant left the chat + * between the ranking and this draw. + */ + java.util.List variants = + chatcontroller.findActiveChatMembersByRawCall(candidate.getCallSignRaw()); + if (!variants.isEmpty()) { + out.add(new kotlin.Pair<>(variants.get(0), candidate.getScore())); + } + } + return out; + } + + /** + * Selects a station in the Compose window: the panel, the table and the score service, the + * three places the JavaFX selection listener kept in step. + */ + private kotlin.Unit selectStationInCompose( + SelectedStationState panel, + DataTableState table, + ChatMember member) { + + panel.select(member); + table.select(member); + + selectedCallSignInfoStageChatMember = member; + if (selectedCallSignInfoMessageBinding != null) { + selectedCallSignInfoMessageBinding.refresh(); + uiDispatcher.runOnUi(() -> { + if (selectedStationMessagesFeed != null) { + selectedStationMessagesFeed.push(selectedCallSignInfoMessageBinding.list()); + } + }); + } + + if (member != null && chatcontroller.getScoreService() != null) { + chatcontroller.getScoreService().setSelectedChatMember(member); + + if (composeMainWindowState != null && composeMainWindowState.getChatInput() != null) { + composeMainWindowState.getChatInput().prepareCq(member.getCallSign(), false); + } + + runOnUi(() -> focusChatMemberAndPrepareCq(member, false)); + } + return kotlin.Unit.INSTANCE; + } + + private kotlin.Unit onDirectedMessageClickedInCompose( + SelectedStationState panel, + DataTableState stationsTable, + ChatInputState chatInput, + ChatMessage message) { + + if (message == null || message.getSender() == null) { + return kotlin.Unit.INSTANCE; + } + + if (message.getSender().getCallSign().equals(chatcontroller.getChatPreferences().getStn_loginCallSign())) { + String receiverCallsign = message.getMessageText().substring(2, message.getMessageText().indexOf(")")); + chatInput.prepareCq(receiverCallsign, false); + rememberAutoPreparedCqTarget(receiverCallsign, message.getChatCategory()); + } else { + selectStationInCompose(panel, stationsTable, message.getSender()); + + chatInput.prepareCq(message.getSender().getCallSign(), false); + prepareCqTextForSelectedChatMember(message.getSender(), false); + focusChatMemberAndPrepareCq(message.getSender(), false); + } + + return kotlin.Unit.INSTANCE; + } + + /** Whether a message came from this station; decides its row colour. */ + private boolean isOwnChatMessage(ChatMessage message) { + if (message == null || message.getSender() == null) { + return false; + } + + String ownCall = chatcontroller.getChatPreferences().getStn_loginCallSign(); + return ownCall != null && ownCall.equals(message.getSender().getCallSign()); + } + + /** How long ago a message arrived, for the fading highlight. */ + private long chatMessageAgeSeconds(ChatMessage message) { + if (message == null) { + return Long.MAX_VALUE; + } + + try { + long generated = Long.parseLong(message.getMessageGeneratedTime()); + return (System.currentTimeMillis() / 1000L) - generated; + } catch (RuntimeException notATimestamp) { + return Long.MAX_VALUE; + } + } + + /** Pushes the link state and the window flags into the Compose window. */ + private void updateComposeSurroundings() { + if (composeMainWindowState == null) { + return; + } + + MainWindowSurroundings surroundings = composeMainWindowState.getSurroundings(); + /* + * Through the feed, and with the detail. This used to set the state alone, which + * left the badge standing beside the default "No ON4KST connection" until the + * next indicator update corrected it. A null detail makes the feed substitute + * the state's own name, which is what the JavaFX indicator always did. + */ + if (connectionStateFeed != null) { + connectionStateFeed.push(chatcontroller.getOn4KstConnectionState(), null); + } + surroundings.setSettingsWindowOpen(SettingsWindow.isOpen()); + surroundings.setMonitorWindowOpen(MonitorWindow.isOpen()); + composeMainWindowState.getMenu().setAwayFromChat( + chatcontroller.getChatPreferences().isStn_loginAFKState()); + } + + /** Releases the Compose window's feeds; a discarded runtime that still feeds one lives on. */ + private void releaseComposeMainWindow() { + if (composeMemberListener != null) { + chatcontroller.getLst_chatMemberList().removeListener(composeMemberListener); + composeMemberListener = null; + } + if (composeChatListener != null) { + chatcontroller.getLst_globalChatMessageList().removeListener(composeChatListener); + composeChatListener = null; + } + if (composeClusterListener != null) { + chatcontroller.getLst_clusterMemberList().removeListener(composeClusterListener); + composeClusterListener = null; + } + if (composeMainWindowState != null) { + composeMainWindowState.release(); + composeMainWindowState = null; + } + } + + /** + * Opens the cluster and QSO monitor. + * + * Both tables follow their roster: the listener replaces the rows, and + * DataTableState keeps the selection on the row the operator picked rather than on + * the position it happened to occupy. The two subscriptions are held in fields and + * released by releaseMonitorListeners, because a discarded runtime that still feeds + * a closed window keeps itself alive. + */ + private void openMonitorWindow() { + + /* + * Guarded before anything is built. Without this a second click registers two + * more roster listeners and then hands them to a window that refuses to open, + * so every inbound message would re-run toOtherMessages once more over up to + * thirty thousand stored messages — work whose result is thrown away, on the + * thread that draws. + */ + if (MonitorWindow.isOpen()) { + return; + } + + ColumnWidthStore widths = new ColumnWidthStore() { + @Override + public Double width(String tableId, String columnId) { + java.util.OptionalDouble stored = + chatcontroller.getChatPreferences().getTableColumnWidth(tableId, columnId); + return stored.isPresent() ? stored.getAsDouble() : null; + } + + @Override + public void setWidth(String tableId, String columnId, double width) { + chatcontroller.getChatPreferences().setTableColumnWidth(tableId, columnId, width); + } + + @Override + public void requestSave() { + requestLayoutSave(); + } + }; + + DataTableState clusterTable = new DataTableState<>( + MonitorColumns.INSTANCE.dxCluster(), + RowKeys.INSTANCE.byReference(), + "dx-cluster-monitor", + widths); + + DataTableState qsoTable = new DataTableState<>( + MonitorColumns.INSTANCE.qsoOfTheOther(), + RowKeys.INSTANCE.byReference(), + "qso-other-monitor", + widths); + + /* + * Subscribed first and seeded afterwards, so a message arriving in between is + * not missed — the order RosterListBinding uses for the same reason. + */ + monitorClusterListener = rows -> uiDispatcher.runOnUi(() -> clusterTable.replaceRows(rows)); + chatcontroller.getLst_clusterMemberList().addListener(monitorClusterListener); + + /* + * The QSO table shows a filtered view, so the whole filter is re-run rather + * than the delivered list being used: toOtherMessages is what decides which + * messages belong to other operators. + */ + monitorChatListener = + rows -> uiDispatcher.runOnUi(() -> qsoTable.replaceRows(chatcontroller.toOtherMessages())); + chatcontroller.getLst_globalChatMessageList().addListener(monitorChatListener); + + clusterTable.replaceRows(chatcontroller.getLst_clusterMemberList().snapshot()); + qsoTable.replaceRows(chatcontroller.toOtherMessages()); + + MonitorWindow.show( + clusterTable, + qsoTable, + chatcontroller.getChatPreferences().isGUI_darkModeActive(), + SETTINGS_WINDOW_FONT_SIZE_SP, + paletteStore, + languageStore, + (float) chatcontroller.getChatPreferences().getGUIclusterAndQSOMonStage_SceneSizeHW()[0], + (float) chatcontroller.getChatPreferences().getGUIclusterAndQSOMonStage_SceneSizeHW()[1], + (width, height) -> { + chatcontroller.getChatPreferences().getGUIclusterAndQSOMonStage_SceneSizeHW()[0] = width; + chatcontroller.getChatPreferences().getGUIclusterAndQSOMonStage_SceneSizeHW()[1] = height; + requestLayoutSave(); + return kotlin.Unit.INSTANCE; + }); + } + + /** + * Opens the update window when the server carries a newer release. + * + * The decision itself lives in UpdateWindowState and is covered by tests; what + * stays here is reaching the system browser, which is the host application's + * business. + */ + private void openUpdateWindowIfAvailable() { + + try { + UpdateWindowState updateState = new UpdateWindowState( + chatcontroller.getUpdateInformation(), + ApplicationConstants.APPLICATION_CURRENT_VERSION, + ApplicationConstants.APPLICATION_CURRENTVERSIONNUMBER); + + if (!updateState.getUpdateAvailable()) { + return; + } + + UpdateWindow.show( + updateState, + chatcontroller.getChatPreferences().isGUI_darkModeActive(), + SETTINGS_WINDOW_FONT_SIZE_SP, + paletteStore, + languageStore, + (float) chatcontroller.getChatPreferences().getGUIstage_updateStage_SceneSizeHW()[0], + (float) chatcontroller.getChatPreferences().getGUIstage_updateStage_SceneSizeHW()[1], + address -> ExternalDocuments.open(address), + (width, height) -> { + chatcontroller.getChatPreferences().getGUIstage_updateStage_SceneSizeHW()[0] = width; + chatcontroller.getChatPreferences().getGUIstage_updateStage_SceneSizeHW()[1] = height; + requestLayoutSave(); + return kotlin.Unit.INSTANCE; + }); + } catch (Exception updateProblem) { + // The client must start even when the update service is unreachable. + System.out.println("[KST4ContestApp, ERROR]: Problem on Updateservice! " + + updateProblem.getMessage()); + updateProblem.printStackTrace(); + } + } + + /** + * Opens the settings window, or does nothing when it is already open. + * + *

This window carries the Connect button and is therefore the way into the chat, + * which is why it is opened once at startup as the JavaFX window was.

+ */ + private void openSettingsWindow() { + + SettingsWindow.show( + SettingsTabsKt.buildSettingsTabs(chatcontroller, this, settingsNotices, paletteStore, languageStore), + settingsNotices, + chatcontroller.getChatPreferences().isGUI_darkModeActive(), + SETTINGS_WINDOW_FONT_SIZE_SP, + paletteStore, + languageStore, + (float) chatcontroller.getChatPreferences().getGUIsettingsStageSceneSizeHW()[0], + (float) chatcontroller.getChatPreferences().getGUIsettingsStageSceneSizeHW()[1], + (width, height) -> { + chatcontroller.getChatPreferences().getGUIsettingsStageSceneSizeHW()[0] = width; + chatcontroller.getChatPreferences().getGUIsettingsStageSceneSizeHW()[1] = height; + requestLayoutSave(); + return kotlin.Unit.INSTANCE; + }, + SettingsTabsKt.settingsButtons(chatcontroller, this, settingsNotices)); + } + + /* + * The Compose main menu's actions, lifted out of the JavaFX menu-item handlers that + * initMenuBar used to carry. ComposeMenuActions calls these directly now; the enabled + * state of the entries lives in MainMenuState, so these methods carry only behaviour, + * not the former setDisable() bookkeeping of the deleted MenuItems. + */ + + /** File -> Connect, using the stored login credentials. */ + void menuActionConnect() { + String call = chatcontroller.getChatPreferences().getStn_loginCallSign(); + String pass = chatcontroller.getChatPreferences().getStn_loginPassword(); + + boolean darkMode = chatcontroller.getChatPreferences().isGUI_darkModeActive(); + + if (call == null || call.isBlank() || pass == null || pass.isBlank()) { + ComposeAlert.show( + kst4contest.view.i18n.CurrentStrings.get().getAlertCannotConnectTitle(), + kst4contest.view.i18n.CurrentStrings.get().getAlertCredentialsMissing(), + kst4contest.view.i18n.CurrentStrings.get().getAlertCredentialsMissingBody(), + darkMode); + return; + } + + try { + chatcontroller.execute(); + } catch (InterruptedException | IOException e) { + LOGGER.log(java.util.logging.Level.SEVERE, "Exception", e); + ComposeAlert.show( + kst4contest.view.i18n.CurrentStrings.get().getAlertConnectionFailedTitle(), + null, + kst4contest.view.i18n.CurrentStrings.get().alertConnectionFailedBody(String.valueOf(e.getMessage())), + darkMode); + } + } + + /** File -> Disconnect (keeps the session, unlike exit). */ + void menuActionDisconnect() { + chatcontroller.disconnect(ApplicationConstants.DISCSTRING_DISCONNECTONLY); + } + + /** File -> Exit + disconnect. */ + void menuActionExit() { + closeWindowEvent(); + } + + /** Options -> Set QRG as name in Chat (main category). */ + void menuActionSetQrgAsNameInChat() { + ChatMessage sendMe = new ChatMessage(); + sendMe.setMessageDirectedToServer(false); + sendMe.setMessageText("/SETNAME " + chatcontroller.getChatPreferences().getMYQRGFirstCat().get()); + chatcontroller.getMessageTXBus().add(sendMe); + } + + /** Options -> toggle AFK state; sends /AWAY or /BACK accordingly. */ + void menuActionToggleAwayState() { + ChatMessage sendMe = new ChatMessage(); + sendMe.setMessageDirectedToServer(false); + + if (chatcontroller.getChatPreferences().isStn_loginAFKState()) { + chatcontroller.getChatPreferences().setStn_loginAFKState(false); + sendMe.setMessageText("/BACK"); + } else { + chatcontroller.getChatPreferences().setStn_loginAFKState(true); + sendMe.setMessageText("/AWAY"); + } + + chatcontroller.getMessageTXBus().add(sendMe); + } + + /** Options/Windows -> open or close the settings window. */ + void menuActionToggleSettingsWindow() { + if (SettingsWindow.isOpen()) { + SettingsWindow.close(); + } else { + openSettingsWindow(); + } + } + + /** Windows -> open or close the cluster / stranger-QSO monitor window. */ + void menuActionToggleMonitorWindow() { + if (MonitorWindow.isOpen()) { + MonitorWindow.close(); + releaseMonitorListeners(); + } else { + openMonitorWindow(); + } + } + + /** Windows -> show or hide the station map. */ + void menuActionToggleStationMap() { + toggleStationMapWindow(); + } + + /** Windows -> dark design, for this session only. */ + void menuActionUseDarkDesign() { + applyTheme(true); + } + + /** Windows -> default (light) design, for this session only. */ + void menuActionUseDefaultDesign() { + applyTheme(false); + } + + /** Info -> donate via Ko-fi. */ + void menuActionOpenDonationPage() { + ExternalDocuments.open("https://ko-fi.com/praktimarc"); + } + + /** Info -> DARC X08 homepage. */ + void menuActionOpenHomepage() { + ExternalDocuments.open("http://www.x08.de"); + } + + /** Info -> kst4Contest newsgroup. */ + void menuActionOpenNewsgroup() { + ExternalDocuments.open("https://groups.google.com/g/kst4contest/about"); + } + + /** Info -> donate for OV3T's aeroplane feed service. */ + void menuActionOpenOv3tDonationPage() { + ExternalDocuments.open("https://www.paypal.me/ov3t"); + } + + /** Info -> contact the author by mail. */ + void menuActionContactAuthor() { + ExternalDocuments.open("mailto:praktimarc+kst4contest@gmail.com"); + } + + /** Info -> About dialog. */ + void menuActionShowAbout() { + ComposeAlert.show( + "About kst4contest", + "kst4Contest " + ApplicationConstants.APPLICATION_CURRENT_VERSION + + ": ON4KST Chatclient by DO5AMF and DN9APW", + chatcontroller.getChatPreferences().getProgramVersion(), + chatcontroller.getChatPreferences().isGUI_darkModeActive()); + } + + @Override + public void refreshShortcutButtonsFromSettings() { + /* + * Points at the Compose shortcut row, which is the only one left. Until now this + * rebuilt the JavaFX button row into flwPane_textSnippets, a pane that has been null + * since the window was disconnected — so an edited shortcut did not reach the + * operator until the window was rebuilt. MainWindowState.RosterMirror says as much + * about its own refresh hook; this is the caller it was waiting for. + */ + uiDispatcher.runOnUi(() -> { + if (composeMainWindowState != null) { + composeMainWindowState.getShortcuts().refresh(); + } + }); + } + + /** + * No-op since the JavaFX snippet context menus were removed with the never-shown + * table. The Compose settings still call this through the shared interface; there is + * no JavaFX menu left to rebuild, and the Compose message panes do not expose the + * snippet context menu that this used to refresh. + */ + @Override + public void refreshTextSnippetContextMenusFromSettings() { + /* + * The JavaFX context menu this used to rebuild is gone, but the Compose snippet + * mirror still needs catching up after an edit — the same hook the shortcut row + * was missing. + */ + uiDispatcher.runOnUi(() -> { + if (composeMainWindowState != null) { + composeMainWindowState.getSnippets().refresh(); + } + }); + } + + @Override + public String detectWintestBroadcastAddress() { + + try { + return detectPreferredWintestBroadcastAddress(); + } catch (Exception detectionProblem) { + System.out.println("[Main.java, Warning]: Could not auto-detect broadcast: " + + detectionProblem.getMessage()); + return null; + } + } + + /** + * No-op since the JavaFX own-QRG text field was removed with the never-shown window. + * + *

The Compose chat input owns that value on both sides: it writes it through + * {@code prefs.getMYQRGFirstCat().set(...)} and the MYQRG button reads it back through + * {@code ChatInputState.appendOwnQrg}. There is no second field left to keep in step. + * The Compose settings still call this through the shared interface, and an empty body + * is honest about there being nothing to do.

+ */ + @Override + public void applyOwnQrgFollower(boolean enabled) { + // intentionally empty: no JavaFX text field left to follow + } + + @Override + public void applyDebugModeToFile(boolean enabled) { + /* + * The preference itself is written by the settings tab. What only the application + * can do is open and close the error-log file handler and the recorder, in the + * order the JavaFX checkbox kept: on the way up the log opens before the recorder + * starts, on the way down the recorder stops before the log closes. + */ + if (enabled) { + setDebugFileLoggingEnabled(true); + chatcontroller.setMessageHistoryRecordingEnabled(true); + } else { + chatcontroller.setMessageHistoryRecordingEnabled(false); + setDebugFileLoggingEnabled(false); + } + } + + /** + * The worked-stations rows are a snapshot the tab takes from the roster itself, so + * there is nothing for this class to redraw. The JavaFX table needed an explicit + * refresh because a TableView does not notice that the objects inside it changed. + */ + @Override + public void refreshWorkedStationsView() { + // nothing to do: the Compose tab re-reads the roster + } + + @Override + public void switchToOperatorProfile(OperatorProfile profile) { + uiDispatcher.runOnUi(() -> requestOperatorProfileSwitch(profile)); + } + + /** + * Starts the ON4KST session. The credentials are already in the preferences: every + * field of the Station tab writes through as it is edited, so there is nothing to + * collect here first. + */ + @Override + public String connectFromSettings() { + + try { + chatcontroller.execute(); + return null; + } catch (InterruptedException interrupted) { + Thread.currentThread().interrupt(); + return "The connection was interrupted: " + interrupted.getMessage(); + } catch (IOException connectionProblem) { + return "The ON4KST server could not be reached: " + connectionProblem.getMessage(); + } + } + + @Override + public void disconnectOnlyFromSettings() { + chatcontroller.disconnect(ApplicationConstants.DISCSTRING_DISCONNECTONLY); + } + + @Override + public void disconnectAndCloseChatFromSettings() { + uiDispatcher.runOnUi(this::closeWindowEvent); + } + + @Override + public String savePreferencesFromSettings() { + + if (!chatcontroller.getChatPreferences().writePreferencesToXmlFile()) { + return null; + } + + if (layoutAutosave != null) { + layoutAutosave.cancelPending(); + } + + return chatcontroller.getChatPreferences().getStoreAndRestorePreferencesFileName(); + } + + private String detectPreferredWintestBroadcastAddress() { + String internetRouteBroadcast = detectInternetRouteBroadcastAddress(); + if (internetRouteBroadcast != null && !internetRouteBroadcast.isBlank()) { + return internetRouteBroadcast; + } + return detectFirstUsableBroadcastAddress(); + } + + private String detectInternetRouteBroadcastAddress() { + java.net.DatagramSocket routeProbe = null; + try { + routeProbe = new java.net.DatagramSocket(); + routeProbe.connect(java.net.InetAddress.getByName("8.8.8.8"), 53); + + java.net.InetAddress localAddress = routeProbe.getLocalAddress(); + if (localAddress == null || localAddress.isAnyLocalAddress() || localAddress.isLoopbackAddress()) { + return null; + } + + java.net.NetworkInterface networkInterface = java.net.NetworkInterface.getByInetAddress(localAddress); + if (networkInterface == null || !networkInterface.isUp()) { + return null; + } + + for (java.net.InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) { + if (!(interfaceAddress.getAddress() instanceof java.net.Inet4Address)) { + continue; + } + if (!localAddress.equals(interfaceAddress.getAddress())) { + continue; + } + if (interfaceAddress.getBroadcast() != null) { + return interfaceAddress.getBroadcast().getHostAddress(); + } + } + + for (java.net.InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) { + if (interfaceAddress.getBroadcast() != null && interfaceAddress.getAddress() instanceof java.net.Inet4Address) { + return interfaceAddress.getBroadcast().getHostAddress(); + } + } + } catch (Exception ignored) { + // Fallback to generic detection if internet-route probing fails + } finally { + if (routeProbe != null && !routeProbe.isClosed()) { + routeProbe.close(); + } + } + return null; + } + + private String detectFirstUsableBroadcastAddress() { + try { + for (java.net.NetworkInterface networkInterface : java.util.Collections.list(java.net.NetworkInterface.getNetworkInterfaces())) { + if (!networkInterface.isUp() || networkInterface.isLoopback() || networkInterface.isVirtual() || networkInterface.isPointToPoint()) { + continue; + } + for (java.net.InterfaceAddress interfaceAddress : networkInterface.getInterfaceAddresses()) { + if (interfaceAddress.getBroadcast() != null && interfaceAddress.getAddress() instanceof java.net.Inet4Address) { + return interfaceAddress.getBroadcast().getHostAddress(); + } + } + } + } catch (Exception ignored) { + // Keep configured value if no interface can be detected + } + return null; + } + + + /** + * Checks whether a value can safely be used as an AirScout routing + * identifier. + * + * Spaces are allowed because AirScout encloses the identifier in quotation + * marks. Quotation marks and line breaks would break the protocol message. + * + * @param identifier entered server or client identifier + * @return true if the identifier can be used + */ + private boolean isValidAirScoutIdentifier(String identifier) { + if (identifier == null) { + return false; + } + + String normalizedIdentifier = identifier.trim(); + + return !normalizedIdentifier.isEmpty() + && !normalizedIdentifier.contains("\"") + && !normalizedIdentifier.contains("\r") + && !normalizedIdentifier.contains("\n"); + } + + + + /** + * Resolves the currently selected UI reachability band. Null override means Auto. + * + * @param member station row + * @return manually selected band or automatic band + */ + private Band resolveReachabilityBandForUi(ChatMember member) { + if (selectedReachabilityBandOverride != null) { + return selectedReachabilityBandOverride; + } + return chatcontroller.getReachabilityService().resolveAutoBand(member); + } + + /** + * Parses the reachability ComboBox selection. + * + * @param selectedLabel selected UI text + * @return selected band, or null for Auto + */ + private Band parseReachabilityBandSelection(String selectedLabel) { + if (selectedLabel == null || selectedLabel.isBlank() || "Auto".equalsIgnoreCase(selectedLabel)) { + return null; + } + + for (Band band : Band.values()) { + if (selectedLabel.equalsIgnoreCase(band.getDisplayLabel())) { + return band; + } + } + return null; + } + + /** + * Formats the projected priority score for the station table. + * + * @param member station row + * @return score text + */ + private String formatPriorityScore(ChatMember member) { + if (member == null || !Double.isFinite(member.getCurrentPriorityScore())) { + return "-"; + } + return String.format(Locale.US, "%.0f", member.getCurrentPriorityScore()); + } + + /** + * Parses a numeric table value for custom score sorting. + * + * @param value table text + * @return parsed value or negative infinity for missing values + */ + private double parseTableDouble(String value) { + if (value == null || value.isBlank() || value.equals("-") || value.startsWith("- @")) { + return Double.NEGATIVE_INFINITY; + } + + String normalized = value.replace(",", ".").replace("+", "").trim(); + int firstSpace = normalized.indexOf(' '); + if (firstSpace > 0) { + normalized = normalized.substring(0, firstSpace); + } + + try { + return Double.parseDouble(normalized); + } catch (NumberFormatException ignored) { + return Double.NEGATIVE_INFINITY; + } + } + + /** + * Predicate helper for the tropo filter. Pending or failed calculations remain + * visible as requested; only finite negative margins are hidden. + * + * @param member station row + * @return true if station should remain visible under the tropo filter + */ + private boolean isReachableViaTropoFilterMatch(ChatMember member) { + if (member == null || chatcontroller.getReachabilityService() == null) { + return true; + } + + Band selectedBand = resolveReachabilityBandForUi(member); + chatcontroller.getReachabilityService().ensureTropoMarginCalculated(member, selectedBand); + + OptionalDouble marginDb = member.getTropoSsbMarginDb(selectedBand); + if (marginDb.isEmpty() || !Double.isFinite(marginDb.getAsDouble())) { + return true; + } + + return marginDb.getAsDouble() >= 0.0; + } + + + /** + * Returns true when a station has any AirScout window now or within maxMinutes. + * + * @param member station row + * @param maxMinutes look-ahead window + * @return true if any AS window is available + */ + private boolean hasAsWindowInNextMinutes(ChatMember member, int maxMinutes) { + if (member == null || member.getAirPlaneReflectInfo() == null + || member.getAirPlaneReflectInfo().getRisingAirplanes() == null) { + return false; + } + + return member.getAirPlaneReflectInfo().getRisingAirplanes().stream() + .filter(Objects::nonNull) + .anyMatch(airPlane -> airPlane.getArrivingDurationMinutes() >= 0 + && airPlane.getArrivingDurationMinutes() <= maxMinutes); + } + + /** + * Returns true when the station is known to be QRV on at least one enabled own band + * that has not been worked yet. + * + * @param member station row + * @return true if there is a new-band opportunity + */ + private boolean isNewBandOpportunity(ChatMember member) { + if (member == null || chatcontroller == null) { + return false; + } + + List variants = + chatcontroller.findActiveChatMembersByRawCall(member.getCallSignRaw()); + if (variants.isEmpty()) { + variants = List.of(member); + } + + BandOpportunityResolver.Resolution resolution = + BandOpportunityResolver.resolve(variants, System.currentTimeMillis()); + EnumSet enabledBands = + BandOpportunityResolver.getEnabledStationBands(chatcontroller.getChatPreferences()); + + return !resolution.getUnworkedEnabledBands(enabledBands).isEmpty(); + } + +} + + + + diff --git a/app-desktop/src/main/java/kst4contest/view/LayoutAutosave.java b/app-desktop/src/main/java/kst4contest/view/LayoutAutosave.java new file mode 100644 index 00000000..35088929 --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/LayoutAutosave.java @@ -0,0 +1,72 @@ +package kst4contest.view; + +import kst4contest.observe.UiDispatcher; + +import javax.swing.Timer; +import java.util.Objects; + +/** + * Coalesces layout changes into selective preferences writes. + * + *

Dragging a column divider produces a stream of change events; writing the + * preferences file on each would make the drag stutter. The write is therefore delayed + * and restarted on every request, so a burst ends in exactly one write.

+ * + *

The class knows nothing about where the layout goes: it takes the write action, not + * the preferences. That is what lets the debounce be tested without touching the + * operator's profile on disk.

+ */ +public final class LayoutAutosave { + + private static final int SAVE_DELAY_MS = 750; + + private final Runnable writeLayout; + private final UiDispatcher uiDispatcher; + private final Timer saveDelay; + private boolean pending; + + /** + * @param writeLayout persists the layout; called on the user-interface thread + * @param uiDispatcher confines the pending state to one thread + */ + public LayoutAutosave(final Runnable writeLayout, final UiDispatcher uiDispatcher) { + this.writeLayout = Objects.requireNonNull(writeLayout, "writeLayout"); + this.uiDispatcher = Objects.requireNonNull(uiDispatcher, "uiDispatcher"); + /* + * A javax.swing.Timer and not the former JavaFX PauseTransition: it fires on the + * AWT event thread, which is where the user interface lives now, and restart() + * has the same meaning playFromStart() had. A PauseTransition would need the + * JavaFX toolkit to be running, which it no longer is. + */ + this.saveDelay = new Timer(SAVE_DELAY_MS, event -> flushPending()); + this.saveDelay.setRepeats(false); + } + + /** Asks for a save, restarting the delay. Safe to call from any thread. */ + public void requestSave() { + if (!uiDispatcher.isUiThread()) { + uiDispatcher.runOnUi(this::requestSave); + return; + } + + pending = true; + saveDelay.restart(); + } + + /** Writes a pending layout now. Does nothing when nothing is pending. */ + public void flushPending() { + if (!pending) { + return; + } + + saveDelay.stop(); + pending = false; + writeLayout.run(); + } + + /** Drops a pending layout without writing it. */ + public void cancelPending() { + saveDelay.stop(); + pending = false; + } +} diff --git a/src/main/java/kst4contest/view/Main.java b/app-desktop/src/main/java/kst4contest/view/Main.java similarity index 100% rename from src/main/java/kst4contest/view/Main.java rename to app-desktop/src/main/java/kst4contest/view/Main.java diff --git a/app-desktop/src/main/java/kst4contest/view/OperatorProfileBootstrap.java b/app-desktop/src/main/java/kst4contest/view/OperatorProfileBootstrap.java new file mode 100644 index 00000000..22e022bb --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/OperatorProfileBootstrap.java @@ -0,0 +1,107 @@ +package kst4contest.view; + +import kst4contest.controller.OperatorProfilePaths; +import kst4contest.controller.OperatorProfileStore; +import kst4contest.model.OperatorProfile; +import kst4contest.model.OperatorProfileSelection; + +import java.util.List; +import java.util.Optional; + +/** + * Decides which operator profile the application starts with. + * + *

The class contains no user interface code so the decision can be tested headless. + * Asking the operator is delegated to an {@link OperatorProfileChoiceRequester}, and a + * problem worth telling the operator about is reported through + * {@link #getStartupWarning()} instead of being shown here.

+ * + *

The most important property of this logic is what it does not do: an + * installation with no or exactly one profile is resolved without asking anything and + * without touching a single file, so a single operator start stays exactly as fast and + * as quiet as it was before profiles existed.

+ */ +public class OperatorProfileBootstrap { + + private String startupWarning; + + /** + * Resolves the operator profile to start with. + * + * @param store registry to read the profiles from + * @param commandLineOptions parsed command line options + * @param choiceRequester requester used when the operator has to choose + * @return the resolved selection, or null when the operator chose to quit + */ + public OperatorProfileSelection resolveAtStartup(final OperatorProfileStore store, + final CommandLineOptions commandLineOptions, + final OperatorProfileChoiceRequester choiceRequester) { + + startupWarning = null; + + List availableProfiles = store.loadProfiles(); + String requestedProfileName = commandLineOptions == null + ? null + : commandLineOptions.getRequestedProfileName(); + + if (requestedProfileName != null) { + OperatorProfile requestedProfile = findProfile(availableProfiles, requestedProfileName); + + if (requestedProfile != null) { + return OperatorProfilePaths.resolve(requestedProfile); + } + + startupWarning = "The operator profile \"" + requestedProfileName + + "\" is unknown. KST4Contest continues with the normal profile selection."; + } + + if (availableProfiles.isEmpty()) { + // No registry at all: the historic flat installation is the only profile. + return OperatorProfilePaths.resolve(store.buildImplicitRootProfile()); + } + + if (availableProfiles.size() == 1) { + return OperatorProfilePaths.resolve(availableProfiles.get(0)); + } + + String preselectedProfileId = store.loadLastUsedProfileId().orElse(null); + Optional chosenProfile = + choiceRequester.requestProfileChoice(availableProfiles, preselectedProfileId); + + return chosenProfile.map(OperatorProfilePaths::resolve).orElse(null); + } + + /** + * Returns a message that should be shown to the operator after startup. + * + * @return the warning text, or null when startup was unremarkable + */ + public String getStartupWarning() { + return startupWarning; + } + + /** + * Finds a profile by identifier or display name, ignoring case. + * + * @param availableProfiles profiles to search + * @param requestedName identifier or display name entered by the operator + * @return the matching profile, or null + */ + private static OperatorProfile findProfile(final List availableProfiles, + final String requestedName) { + + for (OperatorProfile currentProfile : availableProfiles) { + if (requestedName.equalsIgnoreCase(currentProfile.getProfileId())) { + return currentProfile; + } + } + + for (OperatorProfile currentProfile : availableProfiles) { + if (requestedName.equalsIgnoreCase(currentProfile.getDisplayName())) { + return currentProfile; + } + } + + return null; + } +} diff --git a/app-desktop/src/main/java/kst4contest/view/OperatorProfileChoiceRequester.java b/app-desktop/src/main/java/kst4contest/view/OperatorProfileChoiceRequester.java new file mode 100644 index 00000000..1f026cca --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/OperatorProfileChoiceRequester.java @@ -0,0 +1,26 @@ +package kst4contest.view; + +import kst4contest.model.OperatorProfile; + +import java.util.List; +import java.util.Optional; + +/** + * Asks the operator which profile to start with. + * + *

The startup logic depends on this interface rather than on a dialog, so the + * decision which profile to use can be tested without a JavaFX runtime.

+ */ +@FunctionalInterface +public interface OperatorProfileChoiceRequester { + + /** + * Requests a profile choice. + * + * @param selectableProfiles profiles to choose from, never empty + * @param preselectedProfileId identifier to preselect, may be null + * @return the chosen profile, or empty when the operator wants to quit + */ + Optional requestProfileChoice(List selectableProfiles, + String preselectedProfileId); +} diff --git a/src/main/java/kst4contest/view/PrivateMessageRowStyleResolver.java b/app-desktop/src/main/java/kst4contest/view/PrivateMessageRowStyleResolver.java similarity index 100% rename from src/main/java/kst4contest/view/PrivateMessageRowStyleResolver.java rename to app-desktop/src/main/java/kst4contest/view/PrivateMessageRowStyleResolver.java diff --git a/app-desktop/src/main/java/kst4contest/view/RosterListBinding.java b/app-desktop/src/main/java/kst4contest/view/RosterListBinding.java new file mode 100644 index 00000000..0bc79ca2 --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/RosterListBinding.java @@ -0,0 +1,162 @@ +package kst4contest.view; + +import kst4contest.observe.ObservableRoster; +import kst4contest.observe.UiDispatcher; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Supplier; + +/** + * Mirrors an {@link ObservableRoster} into a plain list the user interface can read. + * + *

The mirror instance never changes: callers hold on to the list they were handed, so + * {@link #list()} returns the same unmodifiable view every time. {@link #dispose()} + * unregisters the listener, which is what keeps a discarded runtime from being held alive + * across a profile switch.

+ * + *

Besides the plain one-to-one mirror there is a derived form: a supplier computes the + * visible content (filtered, ordered) and one or more rosters act as the change sources. + * That is what replaced the former {@code FilteredList}/{@code SortedList} chains, which + * recomputed themselves whenever their source list changed.

+ * + *

Named a binding and not a mirror on purpose: {@code kst4contest.view.compose.RosterMirror} + * already exists and mirrors a {@code SimpleRoster} into Compose state. Two classes of the same + * name doing the same job in sibling packages is a reader's trap.

+ * + *

This was an {@code ObservableList} while a {@code TableView} was bound to it. The + * Compose panes take a snapshot instead — {@code SelectedStationMessagesFeed.push} copies + * what it is given — so the only thing the observable collection still provided was the + * change notification, which is now {@link #onChanged(Consumer)}.

+ */ +public final class RosterListBinding { + + private final List mirror = new ArrayList<>(); + + /** + * Handed out by {@link #list()}. A field and not a fresh wrapper per call, so the + * instance a caller kept stays the instance it keeps seeing. + */ + private final List readOnlyView = Collections.unmodifiableList(mirror); + + private final List>> changeListeners = new ArrayList<>(); + private final List unsubscribes = new ArrayList<>(); + private final Supplier> derivation; + private final UiDispatcher dispatcher; + private volatile boolean disposed; + + private RosterListBinding(Supplier> derivation, UiDispatcher dispatcher) { + this.derivation = derivation; + this.dispatcher = dispatcher; + } + + /** Mirrors the roster one to one. */ + public static RosterListBinding mirror(ObservableRoster source, UiDispatcher dispatcher) { + RosterListBinding binding = new RosterListBinding<>(source::snapshot, dispatcher); + binding.subscribe(source); + binding.applyNow(); + return binding; + } + + /** + * Mirrors whatever {@code derivation} computes and recomputes it whenever one of the + * given rosters changes. + * + * @param dispatcher hands the mirror update to the user-interface thread + * @param derivation computes the visible content; called on the UI thread + * @param sources rosters whose changes trigger a recomputation + */ + public static RosterListBinding derived(UiDispatcher dispatcher, + Supplier> derivation, + ObservableRoster... sources) { + RosterListBinding binding = new RosterListBinding<>(derivation, dispatcher); + for (ObservableRoster source : sources) { + binding.subscribe(source); + } + binding.applyNow(); + return binding; + } + + /** + * Registers a listener for real content changes. + * + *

Replaces the {@code ListChangeListener} a {@code TableView} used to attach. It is + * called on the user-interface thread, with an immutable snapshot, and only when the + * content actually changed — see {@link #applyNow()}.

+ */ + public void onChanged(Consumer> listener) { + changeListeners.add(Objects.requireNonNull(listener, "listener")); + } + + /** + * Recomputes the mirror. Needed when something other than a source roster changed the + * result, for example a newly set filter predicate. + */ + public void refresh() { + if (disposed) { + return; + } + dispatcher.runOnUi(this::applyNow); + } + + /** The list to read. Always the same instance, and not modifiable by the caller. */ + public List list() { + return readOnlyView; + } + + /** Unregisters from every source and empties the mirror. Idempotent. */ + public void dispose() { + if (disposed) { + return; + } + disposed = true; + for (Runnable unsubscribe : unsubscribes) { + unsubscribe.run(); + } + unsubscribes.clear(); + changeListeners.clear(); + mirror.clear(); + } + + private void subscribe(ObservableRoster source) { + Consumer> listener = snapshot -> refresh(); + source.addListener(listener); + unsubscribes.add(() -> source.removeListener(listener)); + } + + private void applyNow() { + if (disposed) { + return; + } + List computed = derivation.get(); + /* + * An unchanged result must not notify. The selected-station message pane replaces + * its rows on every notification, and the periodic station-list refresh would + * otherwise fight the operator for the selected row on every tick. + * + * This comparison also breaks a cycle: a consumer that reacts by asking for a + * refresh would land here again, and notifying unconditionally would ask it to + * react again. Once the content is equal the chain stops. + * + * It rests on element identity. ChatMember declares equals(ChatMember) — an + * overload, not an override of equals(Object) — so List.equals falls back to + * reference comparison. Turning that overload into a real override would make two + * different rows with the same callsign compare equal here, and a genuine change + * could be dropped. See ChatMember. + */ + if (mirror.equals(computed)) { + return; + } + + mirror.clear(); + mirror.addAll(computed); + + List snapshot = List.copyOf(mirror); + for (Consumer> listener : changeListeners) { + listener.accept(snapshot); + } + } +} diff --git a/app-desktop/src/main/java/kst4contest/view/ScreenBounds.java b/app-desktop/src/main/java/kst4contest/view/ScreenBounds.java new file mode 100644 index 00000000..a4303fed --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/ScreenBounds.java @@ -0,0 +1,60 @@ +package kst4contest.view; + +import java.awt.GraphicsEnvironment; +import java.awt.Rectangle; + +/** + * The screen area a window may actually use. + * + *

Replaces the former JavaFX screen lookup, which asked the primary screen for its + * visual bounds. {@code GraphicsEnvironment.getMaximumWindowBounds()} is the AWT + * equivalent: it excludes task bars and docks, which is exactly why the old code used the + * visual bounds rather than the raw bounds.

+ */ +public final class ScreenBounds { + + /** Used when there is no display at all, so a window still gets a usable size. */ + public static final double FALLBACK_WIDTH = 1234.0; + + /** Used when there is no display at all, so a window still gets a usable size. */ + public static final double FALLBACK_HEIGHT = 768.0; + + private ScreenBounds() { + // Utility class. + } + + /** + * The usable width of the primary screen. + * + * @return the width in pixels, or {@link #FALLBACK_WIDTH} without a display + */ + public static double availableWidth() { + return widthOf(maximumWindowBounds()); + } + + /** + * The usable height of the primary screen. + * + * @return the height in pixels, or {@link #FALLBACK_HEIGHT} without a display + */ + public static double availableHeight() { + return heightOf(maximumWindowBounds()); + } + + static double widthOf(final Rectangle bounds) { + return bounds == null || bounds.width <= 0 ? FALLBACK_WIDTH : bounds.width; + } + + static double heightOf(final Rectangle bounds) { + return bounds == null || bounds.height <= 0 ? FALLBACK_HEIGHT : bounds.height; + } + + private static Rectangle maximumWindowBounds() { + + if (GraphicsEnvironment.isHeadless()) { + return null; + } + + return GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds(); + } +} diff --git a/app-desktop/src/main/java/kst4contest/view/TableLayoutManager.java b/app-desktop/src/main/java/kst4contest/view/TableLayoutManager.java new file mode 100644 index 00000000..b6f56a49 --- /dev/null +++ b/app-desktop/src/main/java/kst4contest/view/TableLayoutManager.java @@ -0,0 +1,45 @@ +package kst4contest.view; + +/** + * The column-width rule the station and monitor tables are sized by. + * + *

What is left of the class that applied persisted leaf-column widths to a + * {@code TableView} and performed one content-based initial sizing pass. The tables are + * Compose now: {@code DataTableState} applies the stored widths and + * {@code ColumnWidthStore} persists them, so the installation, the resize detection and + * the measuring all went with the JavaFX table.

+ * + *

The sizing rule itself did not. It survives because it is the one piece that decides + * what the operator sees on a first run, and because several Compose column definitions + * still name this class as the place their column ids were registered — a reader who + * follows that reference should find the rule, not a gap.

+ */ +public final class TableLayoutManager { + + /** Room for the cell's left and right padding, on top of the measured text. */ + private static final double CELL_HORIZONTAL_PADDING = 16.0; + + private TableLayoutManager() { + } + + private static double clamp(double value, double minimum, double maximum) { + return Math.max(minimum, Math.min(value, maximum)); + } + + /** + * Calculates a compact content width. Package-private for focused sizing tests. + * + * @param measuredWidth width the content needs without padding + * @param minimum narrowest acceptable column width + * @param maximum widest width an initial sizing pass may choose + * @return the width to use, padding included and clamped into range + */ + @SuppressWarnings("PMD.CommentDefaultAccessModifier") + static double calculateInitialContentWidth( + final double measuredWidth, + final double minimum, + final double maximum + ) { + return clamp(measuredWidth + CELL_HORIZONTAL_PADDING, minimum, maximum); + } +} diff --git a/src/main/java/kst4contest/view/TruncatedTextTooltipSupport.java b/app-desktop/src/main/java/kst4contest/view/TruncatedTextTooltipSupport.java similarity index 100% rename from src/main/java/kst4contest/view/TruncatedTextTooltipSupport.java rename to app-desktop/src/main/java/kst4contest/view/TruncatedTextTooltipSupport.java diff --git a/app-desktop/src/main/kotlin/kst4contest/view/BuildInfo.kt b/app-desktop/src/main/kotlin/kst4contest/view/BuildInfo.kt new file mode 100644 index 00000000..0c332f56 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/BuildInfo.kt @@ -0,0 +1,18 @@ +package kst4contest.view + +/** + * Build identity shown in window titles and in the about text. + * + * Reads the version the Gradle build stamped into the jar manifest and falls + * back to a marker that is obviously not a release, so an unstamped build can + * never be mistaken for one. + */ +object BuildInfo { + + const val UNKNOWN_VERSION: String = "dev-unstamped" + + val version: String + get() = BuildInfo::class.java.`package`?.implementationVersion ?: UNKNOWN_VERSION + + fun windowTitle(base: String): String = "$base $version" +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/AirplaneCell.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/AirplaneCell.kt new file mode 100644 index 00000000..b27e981d --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/AirplaneCell.kt @@ -0,0 +1,61 @@ +package kst4contest.view.compose + +import androidx.compose.ui.graphics.Color +import kst4contest.model.AirPlaneReflectionInfo + +/** + * The aircraft-reflection cell, shared by the station list and the directed messages. + * + * Both JavaFX tables built this text by hand and identically, which is why it lives in + * one place now: minutes until the aeroplane is in the path, and how promising that path + * is, for at most the first two. + */ +object AirplaneCell { + + /** How many fit in the column before it stops being readable. */ + private const val SHOWN_AIRPLANES = 2 + + fun format(info: AirPlaneReflectionInfo?): String { + // Nothing computed for this station yet. Both JavaFX cells ended up blank here, by + // different routes: the directed-message one catches the NullPointerException, the + // station-list one has no guard at all and lets it escape the value factory. + val planes = info?.risingAirplanes ?: return if (info == null) "" else NOTHING_COMING + + if (planes.isEmpty()) return NOTHING_COMING + + return planes.take(SHOWN_AIRPLANES).joinToString(" / ") { plane -> + "${plane.arrivingDurationMinutes} (${plane.potential}%)" + } + } + + /** + * Not an empty cell: the operator has to tell "no aeroplane is coming" apart from + * "nothing has been computed for this station yet". + */ + private const val NOTHING_COMING = "nil" + + /** `.table-cell-100PercentAP`, identical in both stylesheets: a certain path. */ + val PURPLE_100 = Color(0xFFF98AFF) + + /** `.table-cell-75PercentAP`: a good one. */ + val RED_75 = Color(0xFFFA6666) + + /** `.table-cell-50PercentAP`: a fair one. */ + val ORANGE_50 = Color(0xFFFA9F66) + + /** + * The colour of the cell, which is what an aircraft-scatter chance is spotted by — the + * numbers are read afterwards. + * + * Pinned as found: the JavaFX cell factories matched the RENDERED STRING, so only + * exactly 100, 75 and 50 are coloured and 85% gets nothing. Colouring by threshold + * instead would light up cells the operator has never seen lit, which changes what the + * column means at a glance. + */ + fun accentFor(renderedValue: String): CellAccent? = when { + renderedValue.contains("100%") -> CellAccent(foreground = PURPLE_100) + renderedValue.contains("75%") -> CellAccent(foreground = RED_75) + renderedValue.contains("50%") -> CellAccent(foreground = ORANGE_50) + else -> null + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/ChatInputRow.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/ChatInputRow.kt new file mode 100644 index 00000000..0dbea70f --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/ChatInputRow.kt @@ -0,0 +1,308 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.TooltipArea +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.widthIn +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.material3.LocalTextStyle +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.KeyEventType +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.onPreviewKeyEvent +import androidx.compose.ui.input.key.type +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.luminance +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.unit.dp +import kst4contest.model.ChatPreferences + +/** + * The line the operator types into, and the shortcut buttons above it. + * + * This is the busiest strip of the window: everything that leaves this station passes + * through it. Two details matter more here than anywhere else — the field keeps the + * focus, and the caret stays at the end. A button that swallows the focus mid sentence + * costs a QSO. + */ +@OptIn(ExperimentalLayoutApi::class) +@Composable +fun ShortcutButtonRow( + shortcuts: List, + state: ChatInputState, + modifier: Modifier = Modifier, +) { + FlowRow( + modifier = modifier.fillMaxWidth().padding(horizontal = 2.dp, vertical = 0.dp), + horizontalArrangement = Arrangement.spacedBy(0.dp), + verticalArrangement = Arrangement.spacedBy(0.dp), + ) { + shortcuts.forEach { shortcut -> + when (shortcut) { + // The two frequency buttons take their text straight from the field beside + // them rather than through the variable resolver, which is why they are + // not ordinary shortcuts. + MYQRG_SHORTCUT -> ShortcutButton(shortcut, accented = true) { + state.appendOwnQrg(mainCategory = true) + } + + SECOND_QRG_SHORTCUT -> ShortcutButton(shortcut, accented = true) { + state.appendOwnQrg(mainCategory = false) + } + + else -> ShortcutButton( + label = shortcut, + accented = shortcut == SET_NAME_MYQRG_SHORTCUT, + ) { + state.appendShortcut(shortcut) + } + } + } + } +} + +/** The two names the shortcut roster gives special meaning to. */ +const val MYQRG_SHORTCUT = "MYQRG" +const val SECOND_QRG_SHORTCUT = "SECONDQRG" + +/** Accented like the two frequency buttons, but an ordinary appending shortcut otherwise. */ +const val SET_NAME_MYQRG_SHORTCUT = "/SETNAME MYQRG" + +/** + * A shortcut button. + * + * Three shortcuts wear `.buttonMyQrg1` in both stylesheets — the two frequency buttons and + * "/SETNAME MYQRG" — the same green-to-lightgreen gradient the palette already reads as the + * accent, so they are told apart by colour rather than by position. Everything else is an + * ordinary button. + */ +@Composable +private fun ShortcutButton(label: String, accented: Boolean, onClick: () -> Unit) { + if (!accented) { + Form.button(text = label, onClick = onClick) + return + } + + val palette = LocalJavaFxPalette.current + Box( + modifier = Modifier + .heightIn(min = Density.BUTTON_MIN_HEIGHT) + .background( + brush = if (palette.windowBackground.luminance() < 0.5f) { + androidx.compose.ui.graphics.Brush.linearGradient( + colors = listOf(Color(0xFF008000), Color(0xFF90EE90)) + ) + } else { + androidx.compose.ui.graphics.Brush.linearGradient( + colors = listOf(Color(0xFF00FFFF), Color(0xFFFF99FF)) + ) + }, + shape = Density.BUTTON_SHAPE + ) + .clickable { onClick() } + .padding(Density.BUTTON_CONTENT_PADDING), + contentAlignment = Alignment.Center, + ) { + Text( + text = label, + color = MYQRG_LABEL_COLOR, + style = MaterialTheme.typography.labelLarge, + maxLines = 1, + ) + } +} + +/** `-fx-text-fill: #395306` from `.buttonMyQrg1`; a dark olive that reads on the green. */ +private val MYQRG_LABEL_COLOR = Color(0xFF395306) + +/** + * The send row: the message field, TX, clear, and the three small fields the operator + * keeps their own frequencies and antenna heading in. + */ +@OptIn(ExperimentalFoundationApi::class) +@Composable +fun ChatInputRow( + state: ChatInputState, + prefs: ChatPreferences, + /** + * The three fields' live values. Mirrors and not preference reads: the rotator and the + * frequency follower move these while the operator is looking at them, and a plain read + * would draw the value once and then never again. + */ + ownQrgMain: ObservedValue, + ownQrgSecond: ObservedValue, + antennaQtf: ObservedValue, + modifier: Modifier = Modifier, +) { + val focusRequester = remember { FocusRequester() } + + // Every insertion bumps focusRequests; this is requestFocus() + selectEnd(). + LaunchedEffect(state.focusRequests) { + if (state.focusRequests > 0) { + runCatching { focusRequester.requestFocus() } + } + } + + Row( + modifier = modifier.fillMaxWidth().padding(horizontal = 2.dp, vertical = 2.dp), + horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP), + verticalAlignment = Alignment.CenterVertically, + ) { + MessageField( + state = state, + focusRequester = focusRequester, + modifier = Modifier.weight(1f), + ) + + Form.button(text = "TX", onClick = { state.send() }) + Form.button(text = "clear", onClick = { state.clear() }) + + VerticalRule() + + // Commit on focus loss, as in JavaFX: typing a frequency should not write the + // profile on every keystroke. + InlineCommittedField( + stored = ownQrgMain.value.orEmpty(), + onCommit = { prefs.getMYQRGFirstCat().set(it) }, + tooltip = kst4contest.view.i18n.CurrentStrings.get().chatOwnQrgTooltip, + ) + InlineCommittedField( + stored = ownQrgSecond.value.orEmpty(), + onCommit = { prefs.getMYQRGSecondCat().set(it) }, + tooltip = kst4contest.view.i18n.CurrentStrings.get().chatSecondQrgTooltip, + ) + InlineCommittedField( + stored = antennaQtf.value?.toString().orEmpty(), + onCommit = { text -> text.toDoubleOrNull()?.let { prefs.getActualQTF().set(it) } }, + tooltip = kst4contest.view.i18n.CurrentStrings.get().chatQtfTooltip, + ) + } +} + +/** + * One of the three narrow fields beside the send controls. + * + * Written back when the focus leaves, not on every keystroke — the JavaFX fields hung + * their write on focusedProperty for the same reason: a half-typed frequency is not a + * frequency, and the profile is a file. + */ +@OptIn(ExperimentalFoundationApi::class) +@Composable +private fun InlineCommittedField( + stored: String, + onCommit: (String) -> Unit, + tooltip: String, +) { + var draft by remember(stored) { mutableStateOf(stored) } + + TooltipArea(tooltip = { TooltipChip(tooltip) }) { + CompactTextField( + value = draft, + onValueChange = { draft = it }, + modifier = Modifier + .width(QRG_FIELD_WIDTH) + .onFocusChanged { focus -> + if (!focus.isFocused && draft != stored) onCommit(draft) + }, + ) + } +} + +@Composable +private fun TooltipChip(text: String) { + Surface( + color = MaterialTheme.colorScheme.surfaceVariant, + contentColor = MaterialTheme.colorScheme.onSurfaceVariant, + shape = Density.BUTTON_SHAPE, + tonalElevation = 4.dp, + ) { + Text( + text = text, + modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), + style = MaterialTheme.typography.bodySmall, + ) + } +} + +private val QRG_FIELD_WIDTH = 70.dp + +/** + * The message field. + * + * Enter sends and is consumed, so the newline never reaches the text. Escape clears — + * both were on the scene in JavaFX, which means they worked wherever the focus was; here + * they are on the field, and the window handles them for the rest of the surface. + */ +@Composable +private fun MessageField( + state: ChatInputState, + focusRequester: FocusRequester, + modifier: Modifier = Modifier, +) { + val scheme = MaterialTheme.colorScheme + + Box( + modifier = modifier + .heightIn(min = Density.FIELD_MIN_HEIGHT) + .border(1.5.dp, scheme.primary, Density.BUTTON_SHAPE) + .background(scheme.surface, Density.BUTTON_SHAPE) + .padding(horizontal = 6.dp, vertical = 4.dp), + contentAlignment = Alignment.CenterStart, + ) { + BasicTextField( + value = state.value, + onValueChange = { state.value = it }, + modifier = Modifier + .fillMaxWidth() + .focusRequester(focusRequester) + .onPreviewKeyEvent { event -> + if (event.type != KeyEventType.KeyDown) return@onPreviewKeyEvent false + when (event.key) { + Key.Enter, Key.NumPadEnter -> { state.send(); true } + Key.Escape -> { state.clear(); true } + else -> false + } + }, + singleLine = true, + textStyle = LocalTextStyle.current.copy(color = scheme.onSurface), + cursorBrush = SolidColor(scheme.primary), + ) + } +} + +/** The vertical separator that sets the frequency fields apart from the send controls. */ +@Composable +private fun VerticalRule() { + Box( + Modifier + .width(Density.HAIRLINE) + .height(Density.FIELD_MIN_HEIGHT) + .background(MaterialTheme.colorScheme.outline), + ) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/ChatInputState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/ChatInputState.kt new file mode 100644 index 00000000..2fb7874c --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/ChatInputState.kt @@ -0,0 +1,199 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.text.TextRange +import androidx.compose.ui.text.input.TextFieldValue +import kst4contest.model.ChatCategory +import kst4contest.model.ChatMember +import kst4contest.model.ChatMessage + +/** + * Everything the send line needs from the rest of the application. + * + * An interface rather than a handful of lambdas because there are twelve of them and + * they belong together; the implementation is the runtime, the test implements it with + * recording doubles. + */ +interface ChatInputActions { + + /** The station shown in the info panel, set by clicking one. */ + fun panelSelection(): ChatMember? + + fun tableSelection(): ChatMember? + + fun scoreSelection(): ChatMember? + + /** Replaces %variables% in a template; may legitimately return blank. */ + fun resolveVariables(template: String, member: ChatMember?): String? + + /** Whether an outgoing private message targets the local station. */ + fun isAddressedToOwnCallsign(text: String): Boolean + + /** Which chat the message belongs in; the /cq target in the text outranks the selection. */ + fun resolveCategory(text: String, member: ChatMember?): ChatCategory? + + fun mainCategory(): ChatCategory? + + fun recordOutboundCq(text: String) + + fun requestRecompute(reason: String) + + /** Hands the message to the TX queue; the existing mechanism sends it. */ + fun queue(message: ChatMessage) + + fun ownQrgMain(): String + + fun ownQrgSecond(): String +} + +/** + * The line the operator types into, and the buttons around it. + * + * Three things go into this field, and they behave differently on purpose. A shortcut + * button APPENDS, so several can be strung together into one message. A snippet + * REPLACES, because it builds a whole directed message and a half-typed remainder would + * only corrupt it. Typing is typing. + */ +class ChatInputState(private val actions: ChatInputActions) { + + /** Text and caret together, because every insertion also moves the caret. */ + var value: TextFieldValue by mutableStateOf(TextFieldValue("")) + + /** + * Bumped whenever the field should take the focus back. The Compose counterpart of + * requestFocus() + selectEnd(): the operator is mid sentence, and a field that lost + * the focus to a button turns the next keystroke into nothing. + */ + var focusRequests: Int by mutableStateOf(0) + private set + + /** + * Resolves, checks and queues the message, then empties the field. + * + * The order is the original's, including one inconsistency that is kept because + * changing it would change what gets transmitted: the score service's selection is + * consulted only after the variables have been resolved, so a station only it knows + * about reaches the category decision but not the resolver. + */ + fun send() { + var member = actions.panelSelection() ?: actions.tableSelection() + + val resolved = actions.resolveVariables(value.text, member) + + // A variable may legitimately resolve to an empty string; then there is nothing + // to send, and the field is emptied anyway so the operator sees it was consumed. + if (resolved.isNullOrBlank()) { + clear() + return + } + + if (actions.isAddressedToOwnCallsign(resolved)) { + clear() + return + } + + if (member == null) member = actions.scoreSelection() + + val category = actions.resolveCategory(resolved, member) ?: actions.mainCategory() + + val message = ChatMessage() + message.chatCategory = category + message.messageText = resolved + message.isMessageDirectedToServer = false + + // A /cq starts the reply clock the no-reply tracking runs on. + actions.recordOutboundCq(resolved) + actions.requestRecompute("outbound-tx") + + actions.queue(message) + clear() + } + + fun clear() { + value = TextFieldValue("") + } + + /** + * Appends a shortcut's resolved text. A template that resolves to nothing leaves the + * field — and the focus — alone. + */ + fun appendShortcut(template: String) { + val resolved = actions.resolveVariables("$template ", effectiveStation()) + if (resolved.isNullOrBlank()) return + appendAndFocus(resolved) + } + + /** + * Appends a snippet chosen from a right-click menu, resolved, with no trailing space + * and no /cq prefix. + * + * The same roster reaches the field three ways and all three differ: Ctrl+1..Ctrl+0 + * replaces the field with a whole directed message, a right-click appends just the + * snippet, and a shortcut button appends its own roster's entry followed by a space. + * Collapsing any two of them would change what goes out over the air. + */ + fun appendSnippet(snippet: String) { + val resolved = actions.resolveVariables(snippet, effectiveStation()) + if (resolved.isNullOrBlank()) return + appendAndFocus(resolved) + } + + /** + * Appends the operator's own frequency for one of the two chats. These two buttons + * take the value straight from its field rather than through the resolver, which is + * why they are not ordinary shortcuts. + */ + fun appendOwnQrg(mainCategory: Boolean) { + val qrg = if (mainCategory) actions.ownQrgMain() else actions.ownQrgSecond() + appendAndFocus("$qrg ") + } + + /** + * Replaces the field with "/cq CALL ", resolved. + * + * Without a selected station there is nobody to direct it at, so nothing happens — + * silently, as before, because this runs from Ctrl+1..Ctrl+0 while the operator is + * typing and a dialog would be worse than nothing. + */ + fun insertSnippet(snippets: List, index: Int) { + val station = effectiveStation() ?: return + val callSign = station.callSign ?: return + if (index < 0 || index >= snippets.size) return + + val resolved = actions.resolveVariables("/cq $callSign ${snippets[index]}", station) + if (resolved.isNullOrBlank()) return + + setAndFocus(resolved) + } + + private var lastAutoPreparedSendText: String = "" + + /** + * Replaces the field with "/cq CALL ", if the field is empty or contains a previous auto-generated CQ. + */ + fun prepareCq(callSign: String, forceOverwrite: Boolean = false) { + if (callSign.isBlank()) return + val preparedText = "/cq ${callSign.trim()} " + + val canOverwrite = value.text.isEmpty() || value.text == lastAutoPreparedSendText + if (!forceOverwrite && !canOverwrite) { + return + } + + lastAutoPreparedSendText = preparedText + setAndFocus(preparedText) + } + + /** The three-step lookup the shortcuts and snippets use. */ + private fun effectiveStation(): ChatMember? = + actions.panelSelection() ?: actions.tableSelection() ?: actions.scoreSelection() + + private fun appendAndFocus(text: String) = setAndFocus(value.text + text) + + private fun setAndFocus(text: String) { + value = TextFieldValue(text = text, selection = TextRange(text.length)) + focusRequests++ + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/ComposeAlert.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/ComposeAlert.kt new file mode 100644 index 00000000..6a75325b --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/ComposeAlert.kt @@ -0,0 +1,436 @@ +package kst4contest.view.compose + +import kst4contest.view.i18n.CurrentStrings +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.ExperimentalComposeUiApi +import androidx.compose.ui.awt.ComposeDialog +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.KeyEventType +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.type +import androidx.compose.ui.unit.dp +import java.awt.Dialog +import java.awt.Dimension +import java.awt.EventQueue +import java.util.concurrent.atomic.AtomicBoolean +import javax.swing.WindowConstants +import kst4contest.view.ExternalDocuments + +/** One button of an alert, and whether pressing it means "go ahead". */ +internal data class AlertButton(val text: String, val confirming: Boolean) + +/** + * Which JavaFX button type the confirming button stood for. + * + * Not a detail: JavaFX ordered `YES` and `OK_DONE` differently, and the two dialogs this + * class replaces used one each. Flattening them put the button that gives up a running + * contest session where the cancel button used to be. + */ +enum class ConfirmKind(internal val code: Char) { YES('Y'), OK_DONE('O') } + +/* + * The JavaFX ButtonBar orders, read off JavaFX 21.0.5 on a real machine rather than from + * memory. Each letter is a ButtonData type code; only three matter here: Y = YES, + * C = CANCEL_CLOSE, O = OK_DONE. Keeping the whole strings rather than a hand-made table + * means the rule below is the same rule JavaFX applied, and can be checked against it. + */ +internal const val BUTTON_ORDER_LINUX = "L_HE+UNYACBXIO_R" +internal const val BUTTON_ORDER_MAC_OS = "L_HE+U+FBIX_NCYOA_R" +internal const val BUTTON_ORDER_WINDOWS = "L_E+U+FBXI_YNOCAH_R" + +private const val CANCEL_CODE = 'C' + +/** The order string for an operating system name, as JavaFX chose one. */ +internal fun buttonOrderFor(osName: String): String = when { + osName.startsWith("mac", ignoreCase = true) -> BUTTON_ORDER_MAC_OS + osName.startsWith("darwin", ignoreCase = true) -> BUTTON_ORDER_MAC_OS + osName.startsWith("windows", ignoreCase = true) -> BUTTON_ORDER_WINDOWS + else -> BUTTON_ORDER_LINUX +} + +/** + * The button row of an alert, in the order JavaFX would have shown it. + * + * The operator reaches for a position, not a word. Both confirmations this class shows + * give something up — the running ON4KST session, or the whole client — so a row in the + * wrong order is a wrong action, not a cosmetic complaint. + */ +internal fun alertButtons( + confirmText: String, + cancelText: String?, + confirmKind: ConfirmKind, + buttonOrder: String, +): List { + + val confirm = AlertButton(confirmText, confirming = true) + + if (cancelText == null) { + return listOf(confirm) + } + + val cancel = AlertButton(cancelText, confirming = false) + + return if (buttonOrder.indexOf(confirmKind.code) < buttonOrder.indexOf(CANCEL_CODE)) { + listOf(confirm, cancel) + } else { + listOf(cancel, confirm) + } +} + +/** + * The button Enter presses: always the confirming one, as the JavaFX Alert's default + * button was. + */ +internal fun buttonForEnter(buttons: List): AlertButton? = + buttons.firstOrNull { it.confirming } + +/** + * The button ESC presses. + * + * The cancelling one when there is one. On an acknowledgement there is not, and dismissing + * an acknowledgement is acknowledging it — which is what ESC did to a JavaFX Alert holding + * a lone OK button. + */ +internal fun buttonForEscape(buttons: List): AlertButton? = + buttons.firstOrNull { !it.confirming } ?: buttons.firstOrNull() + +/** + * Builds and shows a modal dialog on the AWT event thread, blocking the caller. + * + * Both halves matter and neither is optional. + * + * A `ComposeDialog` is a heavyweight Swing component wrapping a Skia layer, so it has to + * be created and realised on the event thread. Doing it on another thread is not merely + * against the Swing rule: skiko then tries to create its OpenGL context off that thread + * and fails outright — `Failed to create Skia OpenGL context! Can't wrap nullptr`, + * followed by `RenderException: Cannot init graphic context`. The dialog appears as an + * empty frame that never paints, and because nothing can be clicked, a modal wait on it + * never ends. That was reproducible three runs out of three from `main`. + * + * `invokeAndWait` is what keeps the blocking contract while moving the work: it returns + * only once [open] returns, and [open] returns only once the modal dialog closes. So the + * caller still blocks exactly as `Stage.showAndWait()` made it block, and it also gives + * the happens-before edge that makes the answer written on the event thread visible here. + */ +internal fun openOnEventThread(open: () -> Unit) { + if (EventQueue.isDispatchThread()) { + open() + } else { + EventQueue.invokeAndWait(open) + } +} + +/** + * What closing the window without pressing a button means. + * + * The JavaFX Alert returned an empty Optional and every caller read that as "do not + * proceed"; `closeWindowEvent` would otherwise quit the client when the operator + * dismisses the question rather than answering it. + */ +internal fun dismissalConfirms(): Boolean = false + +/** + * The replacement for the JavaFX `Alert`. + * + * A modal [ComposeDialog] rather than a Compose `application { }` window on its own + * thread: a modal AWT dialog runs a nested event pump, so it blocks its caller *and* + * keeps drawing. Measured before this was written — from the event thread and from a + * worker thread alike, the call blocks for the dialog's lifetime and the content + * composes. The thread-plus-latch pattern [OperatorProfilePickerWindow] uses cannot do + * that: once the dispatcher hands menu actions to the event thread, blocking it with a + * latch would deadlock against the window trying to draw on that very thread. + */ +object ComposeAlert { + + /** The font size the JavaFX dialogs had; the settings windows use the same value. */ + private const val DIALOG_FONT_SIZE_SP = 12f + + private val DIALOG_SIZE = Dimension(520, 260) + + /** Shows the alert and returns at once. For notices nothing waits on. */ + @JvmStatic + @JvmOverloads + fun show(title: String, header: String?, body: String, darkMode: Boolean = false) { + EventQueue.invokeLater { + open( + title = title, + header = header, + body = body, + confirmText = CurrentStrings.get().alertOk, + cancelText = null, + confirmKind = ConfirmKind.OK_DONE, + darkMode = darkMode, + modal = false, + ) + } + } + + /** Shows the alert and blocks until the operator acknowledges it. */ + @JvmStatic + @JvmOverloads + fun acknowledge(title: String, header: String?, body: String, darkMode: Boolean = false) { + open( + title = title, + header = header, + body = body, + confirmText = CurrentStrings.get().alertOk, + cancelText = null, + confirmKind = ConfirmKind.OK_DONE, + darkMode = darkMode, + modal = true, + ) + } + + /** + * Asks a yes/no question and blocks until it is answered. + * + * @return true only when the operator pressed the confirming button; dismissing the + * window counts as a no, the way an empty Optional did. + */ + @JvmStatic + @JvmOverloads + fun confirm( + title: String, + header: String?, + body: String, + confirmText: String, + cancelText: String, + darkMode: Boolean = false, + /** + * Which JavaFX button type the confirming button stood for. It decides the button + * order per platform, so it is the caller's to state rather than a default to + * forget: the quit dialog used YES, the profile switch used OK_DONE, and on Linux + * those two order the row differently. + */ + confirmKind: ConfirmKind = ConfirmKind.OK_DONE, + ): Boolean = open( + title = title, + header = header, + body = body, + confirmText = confirmText, + cancelText = cancelText, + confirmKind = confirmKind, + darkMode = darkMode, + modal = true, + ) + + /** + * Shows a notice with one clickable line below the text, and returns at once. + * + * Only `onSimpleLogFileCreated` needs this; the JavaFX version put a Hyperlink into + * the dialog pane. Kept as its own entry point rather than a nullable parameter on + * [show], so the ordinary notice stays a three-argument call. + */ + /* + * The key-handling overload of ComposeDialog.setContent is marked experimental. Opted + * into the way the rest of this package already opts into Compose's experimental + * surface; if it changes, the compiler says so and the fallback is an AWT key listener. + */ + @OptIn(ExperimentalComposeUiApi::class) + @JvmStatic + @JvmOverloads + fun showWithLink( + title: String, + header: String?, + body: String, + linkText: String, + linkTarget: String, + darkMode: Boolean = false, + ) { + EventQueue.invokeLater { + val dialog = ComposeDialog(owner = null, modalityType = Dialog.ModalityType.MODELESS) + dialog.title = title + dialog.size = DIALOG_SIZE + dialog.setLocationRelativeTo(null) + /* Disposed and not hidden, for the reason spelled out in open(). */ + dialog.defaultCloseOperation = WindowConstants.DISPOSE_ON_CLOSE + dialog.isAlwaysOnTop = true + dialog.setContent( + onKeyEvent = { event -> + if (event.type == KeyEventType.KeyDown + && (event.key == Key.Enter || event.key == Key.NumPadEnter + || event.key == Key.Escape)) { + dialog.dispose() + true + } else { + false + } + }, + ) { + Kst4ContestTheme(darkMode = darkMode, baseFontSizeSp = DIALOG_FONT_SIZE_SP) { + AlertContent( + header = header, + body = body, + buttons = alertButtons("OK", null, ConfirmKind.OK_DONE, BUTTON_ORDER_LINUX), + onPressed = { dialog.dispose() }, + link = linkText to linkTarget, + ) + } + } + dialog.isVisible = true + } + } + + @OptIn(ExperimentalComposeUiApi::class) + private fun open( + title: String, + header: String?, + body: String, + confirmText: String, + cancelText: String?, + confirmKind: ConfirmKind, + darkMode: Boolean, + modal: Boolean, + ): Boolean { + /* + * Atomic rather than a captured var. Every confirm() caller happens to press and + * read on the same thread today, so a plain var would work by an unwritten AWT + * detail; this makes it correct on purpose, and the cost is nothing. + */ + val answer = AtomicBoolean(dismissalConfirms()) + + if (!EventQueue.isDispatchThread() && modal) { + /* + * A modal alert asked for from a non-event thread — startup warnings and the + * failure notice in main do this. The dialog must still be built on the event + * thread, so the whole open is handed over and this call blocks until it + * returns, which is the behaviour the caller expects. + */ + openOnEventThread { + answer.set(open(title, header, body, confirmText, cancelText, confirmKind, darkMode, true)) + } + return answer.get() + } + + val dialog = ComposeDialog( + owner = null, + modalityType = + if (modal) Dialog.ModalityType.APPLICATION_MODAL else Dialog.ModalityType.MODELESS, + ) + dialog.title = title + dialog.size = DIALOG_SIZE + dialog.setLocationRelativeTo(null) + /* + * Disposed, not hidden. The JDialog default is HIDE_ON_CLOSE, which would leave the + * window and its Skia layer alive behind the operator's back — one per dismissal, + * and a reconnect storm shows this dialog repeatedly. + */ + dialog.defaultCloseOperation = WindowConstants.DISPOSE_ON_CLOSE + /* + * Above everything else on purpose. These dialogs are asked for from Compose + * windows, which are not their owner; without this the question opens behind the + * window that asked it and the operator sees nothing happen at all. The JavaFX + * profile-switch confirmation needed the same and said so. + */ + dialog.isAlwaysOnTop = true + + val buttons = alertButtons( + confirmText, + cancelText, + confirmKind, + buttonOrderFor(System.getProperty("os.name") ?: ""), + ) + + val press: (AlertButton) -> Unit = { pressed -> + answer.set(pressed.confirming) + dialog.dispose() + } + + dialog.setContent( + /* + * Enter and ESC, which the JavaFX Alert bound for free. Without them the quit + * question ignored both keys, and a dialog one cannot dismiss from the keyboard + * is an obstacle in a contest. + */ + onKeyEvent = { event -> + if (event.type != KeyEventType.KeyDown) { + false + } else { + when (event.key) { + Key.Enter, Key.NumPadEnter -> { + buttonForEnter(buttons)?.let(press) + true + } + Key.Escape -> { + buttonForEscape(buttons)?.let(press) + true + } + else -> false + } + } + }, + ) { + Kst4ContestTheme(darkMode = darkMode, baseFontSizeSp = DIALOG_FONT_SIZE_SP) { + AlertContent( + header = header, + body = body, + buttons = buttons, + onPressed = press, + ) + } + } + + dialog.isVisible = true + return answer.get() + } +} + +@Composable +private fun AlertContent( + header: String?, + body: String, + buttons: List, + onPressed: (AlertButton) -> Unit, + link: Pair? = null, +) { + Surface(modifier = Modifier.fillMaxSize()) { + Column( + modifier = Modifier.padding(15.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + if (header != null) { + Text(header, style = MaterialTheme.typography.titleMedium) + } + + Column( + modifier = Modifier + .weight(1f) + .fillMaxWidth() + .verticalScroll(rememberScrollState()), + ) { + /* Scrolls rather than clips: onSimpleLogFileCreated shows five paragraphs. */ + Text(body, style = MaterialTheme.typography.bodyMedium) + + if (link != null) { + Text( + link.first, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.primary, + modifier = Modifier + .padding(top = 8.dp) + .clickable { ExternalDocuments.open(link.second) }, + ) + } + } + + Row(horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP)) { + buttons.forEach { button -> + Form.button(button.text) { onPressed(button) } + } + } + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/ComposeWindowHost.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/ComposeWindowHost.kt new file mode 100644 index 00000000..9e24f88a --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/ComposeWindowHost.kt @@ -0,0 +1,350 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.DisposableEffect +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.snapshotFlow +import androidx.compose.ui.unit.isSpecified +import androidx.compose.runtime.remember +import androidx.compose.ui.graphics.painter.BitmapPainter +import androidx.compose.ui.graphics.painter.Painter +import androidx.compose.ui.res.loadImageBitmap +import androidx.compose.runtime.mutableStateOf +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.FrameWindowScope +import androidx.compose.ui.window.Window +import androidx.compose.ui.window.application +import androidx.compose.ui.window.rememberWindowState +import androidx.compose.ui.awt.ComposeWindow +import java.awt.EventQueue +import java.awt.Frame +import java.awt.Toolkit +import java.util.concurrent.atomic.AtomicBoolean + +/** + * A Compose window that lives beside the JavaFX application. + * + * Every such window needs the same four things, and getting any of them wrong has + * already cost a defect: + * + * - **It must not end the process.** `application` defaults to calling `exitProcess` + * when its last window closes, which would quit the client when the operator closes + * a settings window. + * - **It must open at most once, and pressing the opener again must raise it.** Two + * windows writing the same preferences would work against each other, so a second + * press cannot build a second window — but it must not do nothing either. The JavaFX + * originals built a fresh Stage per press and were raised as a side effect of that; + * refusing silently leaves the operator pressing a button that appears dead while the + * window sits behind the main one. + * - **It must be closable from outside.** A profile switch tears every window down and + * rebuilds it. `closeOwnedStages` walks JavaFX Stages and cannot reach a Compose + * window; when the settings window survived a switch, its "already open" flag stayed + * set and the rebuilt profile silently got no window at all — and that window carries + * the Connect button. + * - **It must follow a design switch.** The operator can change the design from the + * main window's menu while this window is open. + * + * @param threadName names the thread in a stack dump, which is where one looks when a + * window will not close + */ +class ComposeWindowHost(private val threadName: String) { + + private val open = AtomicBoolean(false) + private val darkModeState = mutableStateOf(false) + private val visible = mutableStateOf(true) + + @Volatile + private var windowThread: Thread? = null + + /** The AWT frame behind the Compose window, held only so a second press can raise it. */ + @Volatile + private var frame: ComposeWindow? = null + + /** Whether the window is currently open, so a caller can tell without opening one. */ + val isOpen: Boolean + get() = open.get() + + /** Follows a design switch made in the main window. */ + fun applyDarkMode(darkMode: Boolean) { + darkModeState.value = darkMode + } + + /** + * Closes the window and waits for it to be gone. + * + * The wait is not politeness: a profile switch opens the replacement window + * immediately afterwards, and it must not be refused by the old one still closing. + * + * How it waits depends on the calling thread, and the distinction is not cosmetic. + * This window's `application { }` advances only as continuations that skiko's + * SwingDispatcher posts to the AWT event thread — unconditionally, with no + * `isDispatchNeeded` shortcut. So on that thread a plain `join` can never be + * satisfied: nothing drains the queue the teardown is sitting in. Every Windows-menu + * toggle and the whole of `shutdownRuntime` call this from there, and before the fix + * the interface froze for the timeout and then returned with [isOpen] still true — + * which made a profile switch raise the dead runtime's window and leave the rebuilt + * profile with no settings window, the one carrying the Connect button. + * + * A secondary loop is the way out: it blocks this caller while continuing to dispatch + * events, which is the same mechanism a modal dialog uses. + */ + fun close() { + if (!open.get()) { + return + } + + visible.value = false + val thread = windowThread ?: return + + if (!EventQueue.isDispatchThread()) { + thread.join(CLOSE_TIMEOUT_MS) + return + } + + val loop = Toolkit.getDefaultToolkit().systemEventQueue.createSecondaryLoop() + Thread({ + thread.join(CLOSE_TIMEOUT_MS) + /* + * Posted rather than called directly, and that is what closes the documented + * race in SecondaryLoop: an exit() that lands before enter() has begun returns + * false and leaves enter() blocked forever. Posting it means the running loop + * itself dispatches the exit, so it cannot arrive too early. The join's + * timeout also bounds the whole wait, so a window that refuses to close costs + * the timeout rather than the session. + */ + EventQueue.invokeLater { loop.exit() } + }, "$threadName-close").start() + + loop.enter() + } + + /** + * Raises the open window to the front, de-iconified if the operator had minimised it. + * + * Hops to the AWT event queue because the caller is the JavaFX thread. Both decisions + * live beside this method as plain functions — [raiseSteps] for what to do and + * [deiconifiedState] for what to write — so the only thing left here that no headless + * test can observe is the single call to `toFront`. + */ + private fun raise() { + val frame = this.frame ?: return + + EventQueue.invokeLater { + raiseSteps(frame.isDisplayable, frame.extendedState and Frame.ICONIFIED != 0) + .forEach { step -> + when (step) { + RaiseStep.DEICONIFY -> + frame.extendedState = deiconifiedState(frame.extendedState) + RaiseStep.TO_FRONT -> frame.toFront() + } + } + } + } + + /** + * Opens the window, or raises it when it is already open. + * + * @param content receives the action that closes the window; only the window itself + * can end its own Compose application + * @param onResized called with the new size whenever the operator resizes the + * window. The JavaFX scenes had width and height listeners writing the + * stored size, and the spec's acceptance criterion for this stage names + * window sizes explicitly. + */ + fun show( + /** + * Read during composition, so a window whose title says what the chat is doing keeps + * saying it. A captured string would freeze at whatever was true when the window + * opened -- which for the main window is "disconnected", for the whole session. + */ + title: () -> String, + darkMode: Boolean, + baseFontSizeSp: Float, + widthDp: Float, + heightDp: Float, + onResized: ((Float, Float) -> Unit)? = null, + /** + * Raised above the other windows. The update window needs it: it opens during + * startup, and behind the main window it goes unnoticed, which is the one thing + * it exists not to do. + */ + alwaysOnTop: Boolean = false, + /** + * The palette of the active profile. Null draws the shipped palette, which is right + * for a window that opens before a profile exists. + */ + paletteStore: PaletteStore? = null, + /** + * The interface language of the active profile. Null draws the base language, which + * is right for a window that opens before a profile exists. + */ + languageStore: kst4contest.view.i18n.LanguageStore? = null, + /** + * What a close request from outside should do — the title bar's X, and a tiling + * window manager's close, which is the same WM_DELETE_WINDOW either way. + * + * Null means close this window and leave the process alone, which is right for the + * settings, monitor and update windows. The MAIN window must pass one: closing it + * has to run the application's quit flow. Without it Compose's default merely ends + * this window's `application { }`, and the client lives on with the chat connected + * and no window to see it in — a tiling window manager shows that plainly, because + * the window disappears while the launching Gradle task keeps running. + */ + onCloseRequest: (() -> Unit)? = null, + /** + * The window's content. A FrameWindowScope receiver, because that is the only scope + * a MenuBar can be declared in — without it no window but the main one could ever + * carry the shared menu bar. + */ + content: @Composable FrameWindowScope.(close: () -> Unit) -> Unit, + ) { + darkModeState.value = darkMode + + if (!open.compareAndSet(false, true)) { + raise() + return + } + + visible.value = true + + val thread = Thread({ + try { + application(exitProcessOnExit = false) { + if (!visible.value) { + /* Nothing rendered means no window, and the application ends. */ + return@application + } + + val windowState = rememberWindowState( + width = widthDp.dp, + height = heightDp.dp, + ) + + /* + * Written back on every change. The JavaFX scenes did this through + * width and height listeners, and the size matters here beyond + * comfort: these tables are wider than the default window, so an + * operator who widens it once must not have to do it again. + */ + if (onResized != null) { + LaunchedEffect(windowState) { + snapshotFlow { windowState.size }.collect { size -> + if (size.width.isSpecified && size.height.isSpecified) { + onResized(size.width.value, size.height.value) + } + } + } + } + + Window( + onCloseRequest = { onCloseRequest?.invoke() ?: exitApplication() }, + state = windowState, + title = title(), + alwaysOnTop = alwaysOnTop, + icon = applicationIcon(), + ) { + /* + * The frame is the only handle that can raise this window later, + * and it must go when the window does: a stale frame would make a + * second press raise a window that is no longer there. + */ + DisposableEffect(window) { + frame = window + /* + * The only place the handle is dropped. Clearing it again in + * the thread's finally block looks like a belt to this brace, + * but that block runs after open.set(false) has already let + * another thread open a new window and publish its frame — so + * the late write would wipe a live handle and bring back the + * dead button this whole method exists to remove. + */ + onDispose { frame = null } + } + + CompositionLocalProvider( + LocalPaletteStore provides paletteStore, + /* + * Read inside the composition, not outside: that state read is + * what makes a language change recompose this window. Etappe 8 + * shipped the outside version for the palette. + */ + kst4contest.view.i18n.LocalStrings provides + (languageStore?.strings + ?: kst4contest.view.i18n.LocalStrings.current), + ) { + Kst4ContestTheme( + darkMode = darkModeState.value, + baseFontSizeSp = baseFontSizeSp, + ) { + content(::exitApplication) + } + } + } + } + } finally { + open.set(false) + windowThread = null + } + }, threadName) + + windowThread = thread + thread.start() + } + + private companion object { + const val CLOSE_TIMEOUT_MS = 2_000L + } +} + +/** + * The application icon, so these windows are not the only ones in the taskbar showing + * the default Java cup. Null when the resource is missing rather than failing: a window + * without an icon still works. + */ +@Composable +private fun applicationIcon(): Painter? = remember { + runCatching { + ComposeWindowHost::class.java.getResourceAsStream(APPLICATION_ICON)?.use { + BitmapPainter(loadImageBitmap(it)) + } + }.getOrNull() +} + +private const val APPLICATION_ICON = "/icons/kst4contest.png" + +/** One thing raising a window has to do. */ +internal enum class RaiseStep { DEICONIFY, TO_FRONT } + +/** + * The frame state that restores a minimised window without disturbing anything else. + * + * `extendedState` is a bit set, so this clears one bit rather than assigning a value. + * Writing `Frame.NORMAL` would be an assignment of zero: a window the operator maximised + * and then minimised holds `MAXIMIZED_BOTH or ICONIFIED` — 7 — and raising it would hand + * it back restored-down, dropping a maximisation nobody asked to drop. + */ +internal fun deiconifiedState(current: Int): Int = current and Frame.ICONIFIED.inv() + +/** + * What raising an already-open window has to do, decided without touching AWT. + * + * Split out so the rule can be tested at all: the three calls it describes need a real + * display and a real window, while the rule itself is the part that can be wrong. + * + * A minimised window has to be restored before it is raised — `toFront` on an iconified + * frame leaves it iconified on every desktop this client runs on, which would be the + * same dead button in a different disguise. A frame that is no longer displayable gets + * nothing: the window is on its way out and raising it would fight the close. + * + * There is no focus step. `toFront` is the documented way to ask for a top-level window + * to come forward, while `Component.requestFocus` on a window is a focus-cycle-root + * request that most window managers ignore — and under X11 focus-stealing prevention has + * the last word either way. It was in the first version of this list without evidence + * that it ever changed an outcome, which is not a reason to pin a third step. + */ +internal fun raiseSteps(displayable: Boolean, iconified: Boolean): List = when { + !displayable -> emptyList() + iconified -> listOf(RaiseStep.DEICONIFY, RaiseStep.TO_FRONT) + else -> listOf(RaiseStep.TO_FRONT) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/ConnectionBar.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/ConnectionBar.kt new file mode 100644 index 00000000..98578dc2 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/ConnectionBar.kt @@ -0,0 +1,114 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.Row +import androidx.compose.runtime.Composable +import kst4contest.view.i18n.LocalStrings +import kst4contest.view.i18n.Strings +import kst4contest.controller.ChatController +import kst4contest.model.ChatPreferences + +/** + * The connection state the button bar shows. Derived from the controller rather than + * held, because the session also connects and drops outside this window. + */ +enum class ConnectionState { DISCONNECTED, CONNECTED_NOT_LOGGED_IN, LOGGED_IN } + +/** + * The button bar at the bottom of the settings window. + * + * This bar is the reason the settings window exists at startup: in the JavaFX client + * it carried the Connect button, which is the one place where `ChatController.execute` + * is called and therefore the only way into the chat. Saving and closing sit next to + * it because that is where the operator has always found them. + */ +class ConnectionBarState( + private val prefs: ChatPreferences, + private val controller: ChatController, +) { + + val connectionState: ConnectionState + get() = when { + controller.isConnectedAndLoggedIn -> ConnectionState.LOGGED_IN + controller.isConnectedAndNOTLoggedIn -> ConnectionState.CONNECTED_NOT_LOGGED_IN + else -> ConnectionState.DISCONNECTED + } + + /** + * The label of the Connect button, which names the chat the station will land in — + * and both chats when the second one is enabled, so the operator sees before + * pressing it what they are logging into. + * + * Takes the texts as a parameter because this is a plain property holder and not a + * composable: it cannot read the composition local itself, and the caller can. + */ + fun connectButtonText(strings: Strings): String { + val main = prefs.getLoginChatCategoryMain() + ?: return strings.connectionConnect + + /* + * Formatted rather than concatenated: in German the chat name comes first ("Mit + * 144 MHz verbinden"), which no amount of "Connect to " + name can produce. + */ + var label = strings.connectionConnectTo(main.getChatCategoryName(main.categoryNumber)) + val second = prefs.getLoginChatCategorySecond() + + if (prefs.isLoginToSecondChatEnabled() && second != null) { + label += " & " + second.getChatCategoryName(second.categoryNumber) + } + + return label + } + + /** Only a disconnected session can connect; the JavaFX button locked itself. */ + val canConnect: Boolean + get() = connectionState != ConnectionState.LOGGED_IN + + /** Disconnecting needs a session that is actually logged in. */ + val canDisconnect: Boolean + get() = connectionState == ConnectionState.LOGGED_IN +} + +@OptIn(ExperimentalLayoutApi::class) +@Composable +fun ConnectionBar( + state: ConnectionBarState, + onConnect: () -> Unit, + onSave: () -> Unit, + onApplyAndClose: () -> Unit, + onDisconnectAndCloseChat: () -> Unit, + onDisconnectOnly: () -> Unit, +) { + /* + * Order as in the JavaFX HBox: connect, save, apply, disconnect and close, and + * disconnect only. Operators reach for these by position. + */ + /* + * A wrapping row, not a plain one. Five buttons do not fit a narrow window, and a + * plain Row does not wrap: it squeezes the last children instead. A button squeezed + * to a few pixels wraps its own label to one letter per line and grows into a tall + * coloured bar that eats the whole window height — which is exactly what happened. + */ + val strings = LocalStrings.current + + FlowRow( + horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP), + verticalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP), + ) { + Form.button( + state.connectButtonText(strings), + enabled = state.canConnect, + onClick = onConnect, + ) + Form.button(strings.settingsSave, onClick = onSave) + Form.button(strings.settingsApplyAndClose, onClick = onApplyAndClose) + Form.button(strings.connectionDisconnectAndCloseChat, onClick = onDisconnectAndCloseChat) + Form.button( + strings.connectionDisconnect, + enabled = state.canDisconnect, + onClick = onDisconnectOnly, + ) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/ContrastRule.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/ContrastRule.kt new file mode 100644 index 00000000..7e27ea84 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/ContrastRule.kt @@ -0,0 +1,96 @@ +package kst4contest.view.compose + +import androidx.compose.ui.graphics.Color +import kotlin.math.pow + +/** WCAG AA for body text. Below this a pair is reported, never refused. */ +const val CONTRAST_FLOOR = 4.5 + +/** The pairs that actually sit on top of each other, as the tab names them. */ +enum class ContrastPair { TEXT_ON_WINDOW_SURFACE, TEXT_INSIDE_FIELD, ACCENT_ON_WINDOW_SURFACE, TEXT_ON_MENU_STRIP } + +/** + * One pair that reads badly. + * + * Carries the pair itself and not its name: this is a pure function, and a translated string + * here would make every test that filters on it depend on whichever language ran last in the + * shared JVM. The tab turns it into words. + * + * @param ratio what the pair measures now + * @param shippedRatio what the same pair measures in the shipped sheet, so the tab can say + * how far the change moved it + */ +data class ContrastWarning(val what: ContrastPair, val ratio: Double, val shippedRatio: Double) + +/** + * The WCAG contrast ratio of two colours, between 1.0 and 21.0. + * + * Relative luminance and not brightness: the two are easy to confuse, and the JavaFX colour + * derivation in this same package is a standing reminder that guessing a colour formula + * produces values that look plausible and are wrong. + */ +fun contrastRatio(a: Color, b: Color): Double { + val lighter = maxOf(relativeLuminance(a), relativeLuminance(b)) + val darker = minOf(relativeLuminance(a), relativeLuminance(b)) + return (lighter + 0.05) / (darker + 0.05) +} + +private fun relativeLuminance(colour: Color): Double { + fun channel(value: Float): Double { + val v = value.toDouble() + return if (v <= 0.03928) v / 12.92 else ((v + 0.055) / 1.055).pow(2.4) + } + + return 0.2126 * channel(colour.red) + + 0.7152 * channel(colour.green) + + 0.0722 * channel(colour.blue) +} + +/** + * The pairs that actually sit on top of each other and read worse than they shipped. + * + * Two conditions, both required: under [CONTRAST_FLOOR], and worse than the same pair in the + * shipped sheet. The second is there because the shipped sheets do not meet the floor + * themselves — the evening accent measures 2.26 on its own surface — so an absolute rule + * would warn about a client nobody has touched, which is how an operator learns to ignore + * warnings. With this rule the shipped state never warns and an improvement never warns. + * + * Four pairs, and each one is read off `Theme.kt`'s Material mapping rather than off the role + * names. The names mislead: `background` and `surface` are both `windowBackground`, with + * `onBackground` and `onSurface` both `labelTextFill`, so almost every label in every window + * sits on the window surface and not on `base` — `base` reaches the screen only through the + * menu strip and the selection tint. And `primary` is `textAccent`, not `accent`, drawn as + * text and as tab underlines. Measuring `labelTextFill` against `base` alone let an operator + * black out every window and hear nothing. + * + * Four and not fifteen, deliberately: most pairs of six roles never meet on screen, and a + * warning about a pair that cannot occur costs the same attention as a real one. + */ +fun contrastWarnings(resolved: JavaFxPalette, shipped: JavaFxPalette): List { + + fun pairsOf(palette: JavaFxPalette) = listOf( + /* onBackground/onSurface on background/surface: nearly every label in every window. */ + ContrastPair.TEXT_ON_WINDOW_SURFACE to (palette.labelTextFill to palette.windowBackground), + /* onSurfaceVariant on surfaceVariant: inside a field, a list, and on every button. */ + ContrastPair.TEXT_INSIDE_FIELD to (palette.labelTextFill to palette.controlInnerBackground), + /* primary as text and as a tab underline, on the window surface. */ + ContrastPair.ACCENT_ON_WINDOW_SURFACE to (palette.textAccent to palette.windowBackground), + /* The menu strip paints base behind its titles; narrow, but it is real. */ + ContrastPair.TEXT_ON_MENU_STRIP to (palette.labelTextFill to palette.base), + ) + + val shippedRatios = pairsOf(shipped).associate { (what, colours) -> + what to contrastRatio(colours.first, colours.second) + } + + return pairsOf(resolved).mapNotNull { (what, colours) -> + val ratio = contrastRatio(colours.first, colours.second) + val shippedRatio = shippedRatios.getValue(what) + + if (ratio < CONTRAST_FLOOR && ratio < shippedRatio) { + ContrastWarning(what, ratio, shippedRatio) + } else { + null + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/DataTable.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/DataTable.kt new file mode 100644 index 00000000..9ca764dd --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/DataTable.kt @@ -0,0 +1,381 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.ui.Alignment +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.snapshots.SnapshotStateList +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.KeyEventType +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.onPreviewKeyEvent +import androidx.compose.ui.input.key.type +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import kst4contest.observe.SimpleRoster + +/** + * One row of an [EditableListState]. + * + * The key is what a LazyColumn is keyed by, and it must survive an insertion + * above the row: keying by list index makes every row below an insertion change + * identity, which moves the selection. Keying by text would collapse duplicates, + * and the shortcut and snippet lists can hold the same text twice. + */ +data class ListEntry(val key: Long, val text: String) + +/** + * What committing an edit did to the list. + * + * A commit is the counterpart of the JavaFX `setOnEditCommit` handler, which ran + * when the operator left the cell — not on every keystroke. That distinction is + * what makes a rule such as "fold a callsign to its base call" usable: applying + * it per keystroke would fight the typist. + */ +sealed interface CommitOutcome { + + /** The entry now holds this text, which a rule may have rewritten. */ + data class Stored(val text: String) : CommitOutcome + + /** The entry is gone: clearing the text was how the operator removed one. */ + data object Removed : CommitOutcome + + /** + * The edit was refused and the stored text stands. The message is the one the + * JavaFX table showed in an alert before calling `refresh()` on itself. + */ + data class Refused(val message: String) : CommitOutcome + + /** The row no longer exists: a pending edit can outlive its row. */ + data object Ignored : CommitOutcome +} + +/** + * Decides what a committed edit becomes. The default accepts the text as typed + * and treats a blank one as a removal; the monitored-callsign list replaces it + * with the normalize-and-reject-duplicates rule the JavaFX table had. + */ +fun interface EntryRule { + + /** + * @param candidate text as the operator typed it + * @param index row being committed + * @param others texts of the other rows in order, the edited row excluded, so a + * duplicate check does not compare a row against itself + */ + fun decide(candidate: String, index: Int, others: List): CommitOutcome + + companion object { + + /** Accept as typed; a blank text removes the entry. */ + val asTyped: EntryRule = EntryRule { candidate, _, _ -> + if (candidate.isBlank()) CommitOutcome.Removed else CommitOutcome.Stored(candidate) + } + } +} + +/** + * Editing state of a single-column string list, free of Compose so the rules are + * testable without a toolkit. + * + * Reproduces what the JavaFX tables in the settings window did: a new entry goes + * to the top and becomes the selection, and an entry edited to blank disappears — + * that was how the operator removed one + * (Kst4ContestApplication, ShortCol.setOnEditCommit). + */ +class EditableListState( + initial: List, + private val rule: EntryRule = EntryRule.asTyped, +) { + + private var nextKey: Long = 0 + + /* + * Compose state, so a row redraws when the selection moves off it or its text + * changes. Plain collections left the user interface guessing: select() is called + * on a focus change without any other notification, and the row that lost the + * selection kept its accent border. + */ + private val items: SnapshotStateList = + mutableStateListOf().apply { + initial.forEach { add(ListEntry(nextKey++, it)) } + } + + val entries: List + get() = items.toList() + + val texts: List + get() = items.map { it.text } + + var selectedIndex: Int? by mutableStateOf(null) + private set + + fun select(index: Int?) { + selectedIndex = index?.takeIf { it in items.indices } + } + + fun addAtTop(entry: String) { + items.add(0, ListEntry(nextKey++, entry)) + selectedIndex = 0 + } + + /** + * Appends an entry. The monitoring list grew this way: its Add button asked for + * a callsign in a dialog and called `add` on the roster, which appends. + */ + fun addAtBottom(entry: String) { + items.add(ListEntry(nextKey++, entry)) + selectedIndex = items.lastIndex + } + + /** An index outside the list is ignored: a pending edit can outlive its row. */ + fun updateAt(index: Int, text: String) { + if (index !in items.indices) { + return + } + if (text.isBlank()) { + removeAt(index) + return + } + items[index] = items[index].copy(text = text) + } + + /** + * Commits an edit through the list's [EntryRule]. This is what the user interface + * calls when the operator leaves a row or presses Enter, mirroring + * `setOnEditCommit`; [updateAt] stays the unguarded path. + */ + fun commitAt(index: Int, candidate: String): CommitOutcome { + if (index !in items.indices) { + return CommitOutcome.Ignored + } + + val others = items.filterIndexed { position, _ -> position != index }.map { it.text } + + return when (val verdict = rule.decide(candidate, index, others)) { + is CommitOutcome.Stored -> { + items[index] = items[index].copy(text = verdict.text) + verdict + } + + CommitOutcome.Removed -> { + removeAt(index) + verdict + } + + else -> verdict + } + } + + fun removeAt(index: Int) { + if (index !in items.indices) { + return + } + items.removeAt(index) + selectedIndex = selectedIndex?.let { current -> + if (current >= items.size) items.indices.lastOrNull() else current + } + } + + /** + * Moves the selected entry by [offset] positions and keeps it selected, the way + * `moveSelectedTableEntry` did. Returns false when there is no selection or the + * target position is outside the list, so the caller can skip its follow-up work. + */ + fun moveSelected(offset: Int): Boolean { + val current = selectedIndex ?: return false + val target = current + offset + + if (current !in items.indices || target !in items.indices) { + return false + } + + items.add(target, items.removeAt(current)) + selectedIndex = target + return true + } + + /** + * Fills the given roster. Deliberately setAll and not a field swap: replacing + * the roster would orphan every listener registered on it, which is the rule + * the ChatPreferences setters have followed since Etappe 2. + */ + fun commitTo(roster: SimpleRoster) { + roster.setAll(texts) + } +} + +/** + * An editable single-column list, the Compose counterpart of the three + * TableView tables in the settings window. + * + * Column widths, sorting and row styling are deliberately absent: no consumer in + * the settings window needs them. They belong with the main-window tables, where + * TableLayoutManager persists widths against stable column ids. + * + * Editing is committed when the operator leaves a row or presses Enter, not on + * every keystroke. That is what the JavaFX `TextFieldTableCell` did: the typed + * text lived in the cell editor until it was committed, which is why a rule could + * reject it and put the stored value back. + * + * @param onChanged called after every committed change — add, edit, removal, move. + * The lists write through, so this is where the roster is filled. + * @param onRefused shown to the operator when a rule refuses an edit; the JavaFX + * tables opened an alert here. + * @param onAdd replaces the default "insert the template at the top" behaviour. + * The monitoring list needs it: its Add button asked for a callsign first. + * @param listHeight the list is a bounded, scrolling area like the TableView it + * replaces. It also keeps a LazyColumn out of an unbounded parent scroll, + * which Compose rejects. + */ +@Composable +fun DataTable( + state: EditableListState, + addButtonText: String, + newEntryTemplate: String, + onChanged: () -> Unit, + modifier: Modifier = Modifier, + onRefused: (String) -> Unit = {}, + onAdd: (() -> Unit)? = null, + showMoveButtons: Boolean = false, + listHeight: Dp = 220.dp, +) { + var revision by remember { mutableStateOf(0) } + val focusOnNewRow = remember { FocusRequester() } + + fun changed() { + revision++ + onChanged() + } + + Column(modifier = modifier, verticalArrangement = Arrangement.spacedBy(6.dp)) { + @Suppress("UNUSED_EXPRESSION") revision // read so edits recompose the list + + LazyColumn( + modifier = Modifier + .fillMaxWidth() + .height(listHeight) + .padding(vertical = 4.dp), + ) { + itemsIndexed(state.entries, key = { _, entry -> entry.key }) { index, entry -> + /* + * Keyed on the revision too, so a refused edit is visibly put back: + * the stored text did not change, and without the revision the draft + * would keep the text the rule just rejected. + */ + var draft by remember(entry.key, entry.text, revision) { mutableStateOf(entry.text) } + var hadFocus by remember(entry.key) { mutableStateOf(false) } + + fun commit() { + when (val outcome = state.commitAt(index, draft)) { + is CommitOutcome.Refused -> { + changed() + onRefused(outcome.message) + } + + CommitOutcome.Ignored -> Unit + + else -> changed() + } + } + + val isSelected = state.selectedIndex == index + + /* + * The selected row is marked on the field's own outline rather than by a + * second frame around it: every row here already is a bordered text + * field, and a frame inside a frame reads as noise instead of as a + * selection. The tinted background carries it the rest of the way. + */ + CompactTextField( + value = draft, + onValueChange = { draft = it }, + borderColor = if (isSelected) MaterialTheme.colorScheme.primary else null, + borderThickness = if (isSelected) 2.dp else null, + modifier = Modifier + .fillMaxWidth() + .padding(vertical = 1.dp) + .background( + if (isSelected) { + MaterialTheme.colorScheme.secondaryContainer + } else { + Color.Transparent + } + ) + .onFocusChanged { focusState -> + if (focusState.isFocused) { + state.select(index) + } else if (hadFocus) { + commit() + } + hadFocus = focusState.isFocused + } + .onPreviewKeyEvent { event -> + if (event.type == KeyEventType.KeyDown && + (event.key == Key.Enter || event.key == Key.NumPadEnter) + ) { + commit() + true + } else { + false + } + } + .let { if (index == 0) it.focusRequester(focusOnNewRow) else it }, + ) + } + } + + Row( + horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP), + verticalAlignment = Alignment.CenterVertically, + ) { + Form.button(addButtonText) { + if (onAdd != null) { + onAdd() + revision++ + return@button + } + + state.addAtTop(newEntryTemplate) + changed() + /* + * Focus is requested explicitly. The JavaFX table opened the new row + * for editing; hoping Compose does the same would repeat the focus + * defects of Etappe 2, where two of three bugs were focus bugs. + */ + runCatching { focusOnNewRow.requestFocus() } + } + + if (showMoveButtons) { + Form.button(kst4contest.view.i18n.CurrentStrings.get().listMoveDown) { if (state.moveSelected(1)) changed() } + Form.button(kst4contest.view.i18n.CurrentStrings.get().listMoveUp) { if (state.moveSelected(-1)) changed() } + } + + Text( + kst4contest.view.i18n.CurrentStrings.get().listClearToRemove, + style = MaterialTheme.typography.bodySmall, + ) + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/DataTableState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/DataTableState.kt new file mode 100644 index 00000000..057b60ca --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/DataTableState.kt @@ -0,0 +1,406 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.graphics.Color +import java.util.IdentityHashMap + +/** + * How a cell is painted beyond its text. Both colours are optional; null keeps the + * table's own. + */ +data class CellAccent(val background: Color? = null, val foreground: Color? = null) + +/** + * One column of a data table. + * + * The shape is taken from what the station list of Etappe 5 actually does, not from + * what the two monitor tables of Etappe 4 need. Those use the simple cases only — + * cutting the interface to fit them would produce one the station list cannot use, + * which is how the single-column DataTable of Etappe 3b came about. + * + * @param id stable across releases; the stored column widths are keyed by it, so + * renaming one loses the operator's layout + * @param value what the cell shows + * @param tooltip built from the row **and** the displayed value, because the JavaFX + * cells do exactly that — the QRA column explains its grid status that way + * @param accent colouring per cell, again from row and value together + * @param comparator sorts this column; without one the displayed text decides + */ +class DataColumn( + /** + * Never translated: this is what the stored column layout is keyed on, so a language + * change must leave it alone or every operator's remembered widths and order would be + * read under names that no longer match. + */ + val id: String, + /** + * Read when the header is drawn, not stored as text. The column lists are built once at + * startup, outside any composition; a stored title would stay in the language that was + * in force then while everything around it switched. + */ + val title: () -> String, + val value: (T) -> String, + val tooltip: ((T, String) -> String)? = null, + val accent: ((T, String) -> CellAccent?)? = null, + val comparator: Comparator? = null, + val weight: Float = 1f, + /** + * Columns sharing a group are drawn under one heading, as the JavaFX table drew + * its worked columns. Without it ten columns headed "wkdany 50 70 144 432 23 13 + * 9 6 3" say nothing about what they mean. + */ + val group: String? = null, +) { + + /** For a title that genuinely never changes -- a ham abbreviation, or a test. */ + constructor( + id: String, + title: String, + value: (T) -> String, + tooltip: ((T, String) -> String)? = null, + accent: ((T, String) -> CellAccent?)? = null, + comparator: Comparator? = null, + weight: Float = 1f, + group: String? = null, + ) : this(id, { title }, value, tooltip, accent, comparator, weight, group) +} + +/** + * Gives every row a key that survives a refresh. + * + * There are two kinds of list here and they need different answers: + * + * - **Entity lists** — the station list, the worked-stations list. A row *is* a + * station, and the same station comes back updated. Its own key is the identity: + * [RowKeys.byValue] with the raw callsign. + * - **Event lists** — the DX cluster and the QSO monitor. A row is something that + * happened. Two identical messages a second apart are genuinely two messages, so a + * key built from their fields would merge them: [RowKeys.byReference]. + * + * There is deliberately no default. In Etappe 2 the visible defects came from row + * identity — a key that was the position shifted on every insert at the top, and one + * that was the text collapsed duplicates. Making the caller decide keeps that choice + * where the knowledge is. + */ +interface RowKeySource { + + fun keyOf(row: T): Any + + /** + * Lets a source that remembers keys forget the rows that have gone. + * + * Called whenever the rows are replaced. Both stores behind these tables are + * capped on purpose — ten thousand cluster messages, thirty thousand chat messages + * — so that memory cannot grow without bound. A key map holding a strong reference + * to every row it ever saw would undo that cap from the outside. + */ + fun retainOnly(rows: List) {} + + /** How many keys are being remembered. Zero for a source that remembers none. */ + fun size(): Int = 0 +} + +object RowKeys { + + /** For rows that carry their own identity; nothing is remembered. */ + fun byValue(key: (T) -> String): RowKeySource = object : RowKeySource { + override fun keyOf(row: T): Any = key(row) + } + + /** + * For append-only lists whose rows carry no identity. + * + * Keys are handed out on first sight and remembered by object reference, which + * holds because the core rosters hand back the same instances on every snapshot. + * A row that really is a new object gets a new key — which is the point. + * + * Synchronised throughout: the rows are replaced from the JavaFX thread while + * Compose draws on its own, and an IdentityHashMap torn between two threads hands + * out a duplicate key (the list then throws) or loses one (the row jumps). Both + * were seen in Etappe 2. + */ + fun byReference(): RowKeySource = object : RowKeySource { + + private val keys = IdentityHashMap() + private var next = 0L + + override fun keyOf(row: T): Any = synchronized(keys) { + keys.getOrPut(row) { next++ } + } + + override fun retainOnly(rows: List) { + synchronized(keys) { + val surviving = IdentityHashMap() + rows.forEach { surviving[it] = true } + keys.keys.retainAll { surviving.containsKey(it) } + } + } + + override fun size(): Int = synchronized(keys) { keys.size } + } +} + +/** + * Where column widths are kept between sessions. + * + * An interface rather than a direct call to ChatPreferences, so the rules can be + * tested without one. The real implementation is two lines over + * `getTableColumnWidth`/`setTableColumnWidth` plus `LayoutAutosave.requestSave`: + * that storage is toolkit-free and stays as it is, while the JavaFX glue around it + * does not come across. + */ +interface ColumnWidthStore { + + /** The stored width, or null when this column was never sized. */ + fun width(tableId: String, columnId: String): Double? + + fun setWidth(tableId: String, columnId: String, width: Double) + + /** Asks for a debounced save; widths must not be written per pixel of a drag. */ + fun requestSave() +} + +/** + * The state of a multi-column table: its rows, its sorting and its selection. + * + * Free of Compose UI so the rules can be tested, but the three mutable properties are + * Compose state: a table bound to plain properties does not repaint, and with live + * data that shows up as a stale display rather than as an unresponsive one — harder + * to notice and worse in effect. + */ +class DataTableState( + val columns: List>, + private val rowKey: RowKeySource, + /** Part of the stored layout: renaming it loses the operator's column sizing. */ + private val tableId: String = "", + private val widths: ColumnWidthStore? = null, +) { + + /** + * The order the columns are shown in, by id. + * + * Within the session only. The JavaFX TableView let the operator drag a column + * elsewhere but never stored where they put it — TableLayoutManager persists widths + * and ChatPreferences has no column order at all — and 1.50 is a functionally equal + * port, not an improvement on it. + */ + private var order: List by mutableStateOf(columns.map { it.id }) + + /** The columns in the order they are shown. */ + val orderedColumns: List> + get() = order.mapNotNull { id -> columns.firstOrNull { it.id == id } } + + /** + * Moves a column to another position. + * + * A target outside the table is clamped rather than refused: a drag that overshoots + * the last header means "put it at the end", which is what the operator did with + * the pointer. + */ + fun moveColumn(columnId: String, toIndex: Int) { + val from = order.indexOf(columnId) + + if (from < 0) { + return + } + + val target = toIndex.coerceIn(0, order.size - 1) + + if (target == from) { + return + } + + order = order.toMutableList().apply { add(target, removeAt(from)) } + } + + /** Bumped on a resize so a table reading widths repaints. */ + private var widthRevision: Int by mutableStateOf(0) + + /** + * The stored width of a column, or null when it was never sized. + * + * Null rather than a made-up number: the caller falls back to the column's own + * weight, which is where the sensible default lives. + */ + fun widthOf(columnId: String): Double? { + @Suppress("UNUSED_EXPRESSION") widthRevision + + return widths?.width(tableId, columnId) + } + + /** + * Stores a new width for a column of this table. + * + * A width of zero or less is refused. A drag past the left edge would otherwise + * store a column the operator cannot grab again, and the sizing survives restarts. + */ + fun resizeColumn(columnId: String, width: Double) { + if (width <= 0.0 || columns.none { it.id == columnId }) { + return + } + + widths?.let { store -> + store.setWidth(tableId, columnId, width) + store.requestSave() + widthRevision++ + } + } + + var rows: List by mutableStateOf(emptyList()) + private set + + var sortedColumnId: String? by mutableStateOf(null) + private set + + var sortAscending: Boolean by mutableStateOf(true) + private set + + private var selectedKey: Any? by mutableStateOf(null) + + private var sortedCache: List? = null + + private var _rowFilter by mutableStateOf<((T) -> Boolean)?>(null, androidx.compose.runtime.neverEqualPolicy()) + + /** Optional filter predicate. If set, [visibleRows] will only include matching rows. */ + var rowFilter: ((T) -> Boolean)? + get() = _rowFilter + set(value) { + _rowFilter = value + invalidateOrder() + } + + /** Incremented to force Compose to redraw visible rows when mutable backend objects change without list structural changes. */ + var contentRevision by mutableStateOf(0) + private set + + fun forceRedraw() { + contentRevision++ + } + + /** + * The rows in the order they are shown. + * + * Computed once per change and then handed back. This is read on every + * recomposition, and sorting here would mean sorting up to thirty thousand rows + * per inbound message on the thread that draws — with a column that has no + * comparator calling its value function once per comparison on top. + */ + val visibleRows: List + get() { + /* + * Read before the cache is consulted, and that order is the whole point. + * Compose repaints a composable when state it *read* changes; a cache that + * returned early stopped reading these, so the next recomposition left the + * table subscribed to nothing and later rows never reached the screen. It + * showed as a monitor window sitting empty beside a filling JavaFX tab, + * redrawing only when an unrelated click forced it. + */ + val currentRows = rows + val currentFilter = rowFilter + val currentColumn = sortedColumnId + val ascending = sortAscending + + sortedCache?.let { return it } + + val filteredRows = if (currentFilter != null) currentRows.filter(currentFilter) else currentRows + + val column = columns.firstOrNull { it.id == currentColumn } + val sorted = if (column == null) { + filteredRows + } else { + /* + * The displayed text is read once per row rather than once per + * comparison, and sortedBy is stable, so rows that compare equal keep + * the order they arrived in. Etappe 2 lost that: the JavaFX SortedList + * inserted by binary search and put ties wherever it landed, which made + * rows jump. + */ + val order = column.comparator + ?: compareBy(filteredRows.associateWith { column.value(it) }::getValue) + + if (ascending) { + filteredRows.sortedWith(order) + } else { + filteredRows.sortedWith(order.reversed()) + } + } + + sortedCache = sorted + return sorted + } + + private fun invalidateOrder() { + sortedCache = null + } + + /** The selected row, or null when nothing is selected or it has gone. */ + val selectedRow: T? + get() = selectedKey?.let { key -> rows.firstOrNull { rowKey.keyOf(it) == key } } + + /** + * Replaces the rows. + * + * The selection is kept **by key**, not by position: a station that moved because + * something above it was inserted is still the station the operator picked. When + * the selected row is gone the selection is dropped rather than sliding onto its + * neighbour, which would silently point the operator at someone else. + */ + fun replaceRows(newRows: List) { + rows = newRows + rowKey.retainOnly(newRows) + invalidateOrder() + + val key = selectedKey + if (key != null && newRows.none { rowKey.keyOf(it) == key }) { + selectedKey = null + } + } + + fun select(row: T?) { + selectedKey = row?.let(rowKey::keyOf) + } + + /** + * The key a row is drawn under. Its identity, never its position: a positional key + * reshuffles every row whenever something arrives at the top, which in a live list + * is constant. + */ + fun keyOf(row: T): Any = rowKey.keyOf(row) + + fun isSelected(row: T): Boolean = selectedKey != null && rowKey.keyOf(row) == selectedKey + + /** + * Sorts by a column, cycling ascending, descending, unsorted. + * + * The third click is not a flourish: JavaFX TableView gives that cycle for free, and + * without it an operator who sorted the message list once could never get back to + * arrival order — newest at the bottom — short of restarting. + * + * An unknown column is ignored rather than clearing the sorting: it can only come + * from a stored layout that names a column this release no longer has. + */ + fun toggleSort(columnId: String) { + if (columns.none { it.id == columnId }) { + return + } + + when { + sortedColumnId != columnId -> { + sortedColumnId = columnId + sortAscending = true + } + + sortAscending -> sortAscending = false + + // Third click: back to the order the rows arrived in. + else -> { + sortedColumnId = null + sortAscending = true + } + } + + invalidateOrder() + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/DataTableView.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/DataTableView.kt new file mode 100644 index 00000000..aa833b31 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/DataTableView.kt @@ -0,0 +1,440 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.gestures.detectHorizontalDragGestures +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.ui.unit.Dp +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.lazy.itemsIndexed +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.HorizontalScrollbar +import androidx.compose.foundation.LocalScrollbarStyle +import androidx.compose.foundation.TooltipArea +import androidx.compose.foundation.VerticalScrollbar +import androidx.compose.foundation.horizontalScroll +import androidx.compose.foundation.lazy.rememberLazyListState +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.rememberScrollbarAdapter +import androidx.compose.material3.Surface +import androidx.compose.ui.input.pointer.PointerIcon +import androidx.compose.ui.input.pointer.pointerHoverIcon +import androidx.compose.ui.text.style.TextOverflow +import java.awt.Cursor +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.snapshotFlow +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.setValue +import androidx.compose.runtime.remember +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.getValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp + +/** + * A multi-column table. + * + * The rules — row identity, selection across a refresh, stable sorting, stored widths + * — live in [DataTableState] and are tested there. What is here is only the drawing + * and the gestures, because nothing that draws is covered by a test in this release. + * + * Rows are keyed by the state's own row key, never by their position: the lists this + * table serves are live, and a positional key reshuffles every row whenever something + * arrives at the top. + * + * @param rowStyle colours a whole row, as the station list does from its priority + * score. Not used by the monitor tables, and deliberately still present: the + * interface is cut for the station list of Etappe 5. + */ +/* + * TooltipArea is experimental in Compose foundation. The opt-in is deliberate: it is + * the supported way to reach the hover text the JavaFX cells had, and losing that + * loses the only way to read a value that does not fit its column. + */ +@OptIn(ExperimentalFoundationApi::class) +@Composable +fun DataTableView( + state: DataTableState, + modifier: Modifier = Modifier, + rowStyle: ((T) -> CellAccent?)? = null, + onRowClick: ((T) -> Unit)? = null, +) { + val density = LocalDensity.current + + val horizontal = rememberScrollState() + val vertical = rememberLazyListState() + + /* + * These lists are newest-first, and a LazyColumn anchors to the item it was + * showing — so every arrival at the top pushes the view down and the operator + * drifts away from the newest line without touching anything. + * + * The rule: stay at the top while the operator is at the top, and leave them alone + * once they have scrolled down to read something. Yanking a reader back to the top + * on every inbound message would be worse than drifting. + */ + var stickToTop by remember { mutableStateOf(true) } + + LaunchedEffect(vertical) { + snapshotFlow { vertical.isScrollInProgress }.collect { scrolling -> + /* Only a scroll the operator made ends; a prepend does not scroll. */ + if (!scrolling) { + stickToTop = vertical.firstVisibleItemIndex == 0 && + vertical.firstVisibleItemScrollOffset == 0 + } + } + } + + val newestKey = state.visibleRows.firstOrNull()?.let { state.keyOf(it) } + + LaunchedEffect(newestKey) { + if (stickToTop && newestKey != null) { + vertical.scrollToItem(0) + } + } + + /* + * Both directions scroll. The columns of these two tables need about 890dp and + * 1000dp, and the stored window width starts at 700: without this the last columns + * are simply unreachable, and so are the handles that would narrow them. The JavaFX + * tables had a horizontal scrollbar. + */ + BoxWithConstraints(modifier = modifier.fillMaxSize()) { + val slack = unusedWidth(state, maxWidth) + val lastColumnId = state.orderedColumns.lastOrNull()?.id + + Column(modifier = Modifier.fillMaxSize()) { + /* + * A second header row above the first, spanning the columns that share a + * group. The station list needs it: ten columns headed "wkdany 50 70 144 432 + * 23 13 9 6 3" say nothing without the word "worked" over them. + */ + val groups = state.orderedColumns.map { it.group } + + if (groups.any { it != null }) { + Row( + modifier = Modifier + .horizontalScroll(horizontal) + .background(MaterialTheme.colorScheme.surfaceVariant) + .heightIn(min = Density.ROW_MIN_HEIGHT), + ) { + var index = 0 + + while (index < state.orderedColumns.size) { + val group = groups[index] + var span = 1 + + while (index + span < groups.size && groups[index + span] == group && group != null) { + span++ + } + + val width = (index until index + span).sumOf { position -> + val column = state.orderedColumns[position] + val stored = state.widthOf(column.id) + val own = stored ?: (DEFAULT_COLUMN_WIDTH * column.weight).value.toDouble() + own + Density.COLUMN_HANDLE_WIDTH.value + } + + Box( + modifier = Modifier.width(width.dp).padding(horizontal = 4.dp), + contentAlignment = Alignment.Center, + ) { + if (group != null) { + Text( + group, + style = MaterialTheme.typography.bodyMedium, + fontWeight = FontWeight.Bold, + maxLines = 1, + ) + } + } + + index += span + } + } + + HorizontalDivider(thickness = Density.HAIRLINE) + } + + /* + * IntrinsicSize.Min, so the fillMaxHeight of the cells and the grab handles + * resolves against the header's own content instead of against the whole + * table. Without it the header took the entire height and the handles became + * full-length bars down the window. + */ + Row( + modifier = Modifier + .horizontalScroll(horizontal) + .background(MaterialTheme.colorScheme.surfaceVariant) + .height(IntrinsicSize.Min) + .heightIn(min = Density.ROW_MIN_HEIGHT), + ) { + state.orderedColumns.forEachIndexed { index, column -> + val sorted = state.sortedColumnId == column.id + + /* + * Click to sort, drag sideways to reorder — the two gestures the JavaFX + * header had. The drag is measured in whole column steps rather than + * pixels, so a column moves once per column crossed instead of + * flickering between two places. + */ + var dragged by remember(column.id) { mutableStateOf(0f) } + + Box( + modifier = Modifier + .columnWidth(state, column, if (column.id == lastColumnId) slack else 0.dp) + .fillMaxHeight() + .clickable { state.toggleSort(column.id) } + .pointerInput(column.id, index) { + detectHorizontalDragGestures( + onDragEnd = { dragged = 0f }, + onDragCancel = { dragged = 0f }, + ) { _, dragAmount -> + dragged += dragAmount + val step = with(density) { DEFAULT_COLUMN_WIDTH.toPx() } / 2f + + if (dragged > step) { + state.moveColumn(column.id, index + 1) + dragged = 0f + } else if (dragged < -step) { + state.moveColumn(column.id, index - 1) + dragged = 0f + } + } + } + .pointerHoverIcon(PointerIcon(Cursor(Cursor.MOVE_CURSOR))) + .padding(horizontal = 4.dp, vertical = 3.dp), + contentAlignment = Alignment.CenterStart, + ) { + Text( + column.title() + if (sorted) (if (state.sortAscending) " ▲" else " ▼") else "", + style = MaterialTheme.typography.bodyMedium, + fontWeight = FontWeight.Bold, + maxLines = 1, + ) + } + + /* + * The grab handle between two headers. Two pixels wide on purpose: the + * JavaFX table put the same gesture on the column border, and operators + * resize these tables constantly during a contest. + */ + /* + * A hairline to look at, a wider area to grab. The JavaFX column border + * was a thin line; a 4dp bar in the outline colour reads as a wall + * between the columns. + */ + Box( + modifier = Modifier + .width(Density.COLUMN_HANDLE_WIDTH) + .fillMaxHeight() + .pointerHoverIcon(PointerIcon(Cursor(Cursor.E_RESIZE_CURSOR))) + .pointerInput(column.id) { + detectHorizontalDragGestures { _, dragAmount -> + /* + * The drag is in pixels, the stored width is in dp, and + * the stored value survives a restart. Mixing the two + * doubles a column on its first touch on a HiDPI screen + * and writes that into preferences.xml. + */ + val deltaDp = with(density) { dragAmount.toDp().value } + val current = state.widthOf(column.id) + ?: (DEFAULT_COLUMN_WIDTH * column.weight).value.toDouble() + + state.resizeColumn(column.id, current + deltaDp) + } + }, + contentAlignment = Alignment.Center, + ) { + Box( + modifier = Modifier + .width(Density.HAIRLINE) + .fillMaxHeight() + .background(MaterialTheme.colorScheme.outline), + ) + } + } + } + + HorizontalDivider(thickness = Density.HAIRLINE) + + Box(modifier = Modifier.weight(1f).fillMaxWidth()) { + LazyColumn( + state = vertical, + modifier = Modifier + .fillMaxSize() + .horizontalScroll(horizontal) + .padding(end = Density.SCROLLBAR_GUTTER), + ) { + itemsIndexed(state.visibleRows, key = { _, row -> state.keyOf(row) }) { index, row -> + val selected = state.isSelected(row) + val accent = rowStyle?.invoke(row) + val isEven = index % 2 == 0 + val _forceRedraw = state.contentRevision + + Column(modifier = Modifier.fillMaxWidth()) { + Row( + modifier = Modifier + .fillMaxWidth() + .height(IntrinsicSize.Min) + .background( + when { + selected -> MaterialTheme.colorScheme.secondaryContainer + accent?.background != null -> accent.background + isEven -> Color.Transparent + else -> MaterialTheme.colorScheme.surfaceVariant + } + ) + .clickable { + state.select(row) + onRowClick?.invoke(row) + } + .heightIn(min = Density.ROW_MIN_HEIGHT), + verticalAlignment = Alignment.CenterVertically, + ) { + state.orderedColumns.forEach { column -> + val value = column.value(row) + val cell = column.accent?.invoke(row, value) + + Box( + modifier = Modifier + .columnWidth(state, column, if (column.id == lastColumnId) slack else 0.dp) + .fillMaxHeight() + .background(cell?.background ?: Color.Transparent) + .padding(horizontal = 4.dp, vertical = 2.dp), + contentAlignment = Alignment.CenterStart, + ) { + TooltipArea( + tooltip = { + val hint = column.tooltip?.invoke(row, value) ?: value + + if (hint.isNotBlank()) { + Surface( + color = MaterialTheme.colorScheme.surfaceVariant, + tonalElevation = 2.dp, + ) { + Text( + hint, + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.padding(4.dp), + ) + } + } + }, + ) { + Text( + value, + style = MaterialTheme.typography.bodyMedium, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + color = cell?.foreground + ?: accent?.foreground + ?: MaterialTheme.colorScheme.onSurface, + ) + } + } + + Box( + modifier = Modifier + .width(Density.COLUMN_HANDLE_WIDTH) + .fillMaxHeight(), + contentAlignment = Alignment.Center + ) { + Box( + modifier = Modifier + .width(Density.HAIRLINE) + .fillMaxHeight() + .background(MaterialTheme.colorScheme.outlineVariant) + ) + } + } + } + + HorizontalDivider( + thickness = Density.HAIRLINE, + color = MaterialTheme.colorScheme.outline + ) + } + } + } + + VerticalScrollbar( + adapter = rememberScrollbarAdapter(vertical), + modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(), + style = LocalScrollbarStyle.current.copy( + unhoverColor = MaterialTheme.colorScheme.outline, + hoverColor = MaterialTheme.colorScheme.onSurface, + ), + ) + } + + HorizontalScrollbar( + adapter = rememberScrollbarAdapter(horizontal), + modifier = Modifier.fillMaxWidth(), + style = LocalScrollbarStyle.current.copy( + unhoverColor = MaterialTheme.colorScheme.outline, + hoverColor = MaterialTheme.colorScheme.onSurface, + ), + ) + } + } + +} + + +/** + * A stored width when the operator has sized this column, otherwise the column's own + * weight. The stored value wins because it is the operator's decision. + * + * @param extra added to the last column so the table fills the window instead of + * leaving a band of empty background to the right. The JavaFX table did the + * same through `flexibleInitialWidth`. + */ +@Composable +private fun Modifier.columnWidth( + state: DataTableState, + column: DataColumn, + extra: Dp = 0.dp, +): Modifier { + val stored = state.widthOf(column.id) + val own = if (stored != null) stored.dp else DEFAULT_COLUMN_WIDTH * column.weight + + return this.width(own + extra) +} + +/** + * How much is left over once every column has its width. Zero when the columns are + * already wider than the window, in which case the table scrolls. + */ +@Composable +private fun unusedWidth(state: DataTableState, available: Dp): Dp { + val used = state.orderedColumns.sumOf { column -> + val stored = state.widthOf(column.id) + val own = if (stored != null) stored else (DEFAULT_COLUMN_WIDTH * column.weight).value.toDouble() + own + Density.COLUMN_HANDLE_WIDTH.value + } + + return (available.value - used).coerceAtLeast(0.0).dp +} + +private val DEFAULT_COLUMN_WIDTH = 85.dp diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/Density.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/Density.kt new file mode 100644 index 00000000..a29de120 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/Density.kt @@ -0,0 +1,68 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.ui.unit.dp + +/** + * The measurements of the settings windows, in one place so the tabs cannot drift + * apart. + * + * Material 3 ships phone densities: a text field is 56dp tall, a button 40dp and + * fully rounded, a checkbox reserves a 48dp touch target. The Station tab alone has + * over thirty fields, so those defaults turn a settings window into a scrolling + * exercise and make a desktop application look like a phone. + * + * Every height here is a **minimum**, never a fixed size. The configured base font + * size scales all text through Typography.scaledTo, and a fixed height would clip a + * larger font instead of growing with it. + */ +internal object Density { + + /** Text fields, pickers and anything else on the field column. */ + val FIELD_MIN_HEIGHT = 30.dp + + /** Inside a text field. The vertical value is what buys back the 56dp. */ + val FIELD_CONTENT_PADDING = PaddingValues(horizontal = 8.dp, vertical = 2.dp) + + val BUTTON_MIN_HEIGHT = 24.dp + + val BUTTON_CONTENT_PADDING = PaddingValues(horizontal = 8.dp, vertical = 1.dp) + + /** Square-ish, not a pill: the pill shape is the strongest mobile tell. */ + val BUTTON_SHAPE = RoundedCornerShape(4.dp) + + /** One row of a list or table. */ + val ROW_MIN_HEIGHT = 26.dp + + val TAB_MIN_HEIGHT = 30.dp + + /** + * Left and right of a tab title. Material reserves 90dp minimum width per tab, + * which eleven tabs cannot live with; this is what a tab costs beyond its text. + */ + val TAB_HORIZONTAL_PADDING = 10.dp + + /** The box itself; the 48dp touch target around it is switched off separately. */ + val CHECK_SIZE = 18.dp + + /** The label column of the forms, wide enough for the longest label in use. */ + val LABEL_COLUMN_WIDTH = 260.dp + + /** Between a label and its field, and between two fields. */ + val FIELD_GAP = 3.dp + + /** Between buttons in a row. */ + val BUTTON_GAP = 6.dp + + /** Around a selected row, and the hairline between rows. */ + val SELECTION_BORDER = 1.5.dp + + /** Kept free at the right edge so the scrollbar never sits on a control. */ + val SCROLLBAR_GUTTER = 12.dp + + /** Grab area between two columns; the line drawn inside it is a hairline. */ + val COLUMN_HANDLE_WIDTH = 5.dp + + val HAIRLINE = 1.dp +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/DirectedMessageColumns.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/DirectedMessageColumns.kt new file mode 100644 index 00000000..19f2b714 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/DirectedMessageColumns.kt @@ -0,0 +1,88 @@ +package kst4contest.view.compose + +import kst4contest.model.ChatMessage + +/** + * The columns of the directed-message table: what was said to this station. + * + * Its own pane above the send line rather than one of the tabs, because an operator must + * be able to see a private call without switching away from whatever they are reading. + * + * The ids are the keys the operator's stored column widths hang on, exactly as + * TableLayoutManager registered them under "private-messages". + * + * @param ownCallSign the local station, which gets no distance to itself + * @param formatMessage the controller's display formatting for a message text + */ +object DirectedMessageColumns { + + fun all( + ownCallSign: () -> String? = { null }, + formatMessage: (ChatMessage) -> String, + ): List> = listOf( + DataColumn( + id = "time", + title = { kst4contest.view.i18n.CurrentStrings.get().columnTime }, + value = { MessageFormats.clockTime(it.messageGeneratedTime) }, + weight = 0.7f, + ), + DataColumn( + id = "callsign", + title = { kst4contest.view.i18n.CurrentStrings.get().columnCallsign }, + value = { MonitorColumns.callSignOf(it.sender) }, + ), + DataColumn(id = "name", title = { kst4contest.view.i18n.CurrentStrings.get().columnName }, value = { it.sender?.name.orEmpty() }), + DataColumn(id = "qra", title = "QRA", value = { MonitorColumns.qraOf(it.sender) }), + DataColumn( + id = "qrb", + title = "QRB", + value = { message -> qrbOf(message, ownCallSign()) }, + comparator = compareBy { it.sender?.qrb ?: 0.0 }, + weight = 0.9f, + ), + DataColumn( + id = "message", + title = { kst4contest.view.i18n.CurrentStrings.get().columnMessage }, + value = formatMessage, + weight = 3f, + ), + DataColumn( + id = "last-qrg", + title = { kst4contest.view.i18n.CurrentStrings.get().columnLastKnownQrg }, + value = { MessageFormats.paddedQrg(MonitorColumns.frequencyOf(it.sender)) }, + weight = 0.9f, + ), + DataColumn( + id = "airscout", + title = "AP [minutes / pot%]", + value = { AirplaneCell.format(it.sender?.airPlaneReflectInfo) }, + accent = { _, rendered -> AirplaneCell.accentFor(rendered) }, + weight = 1.4f, + ), + DataColumn( + id = "category", + title = "Category", + value = { message -> + message.chatCategory + ?.let { it.getChatCategoryName(it.categoryNumber) } + .orEmpty() + }, + weight = 1.2f, + ), + ) + + /** + * Distance and bearing as one cell, both cut to whole numbers to save width. + * + * The degree sign sits outside the bracket — "342 km (88)°" — which is how JavaFX + * wrote it and therefore how operators read it. + */ + private fun qrbOf(message: ChatMessage, ownCallSign: String?): String { + val sender = message.sender ?: return "" + if (sender.callSign == null || sender.callSign == ownCallSign) return "" + + val qrb = sender.qrb ?: return "" + val bearing = sender.getQTFdirection() ?: return "" + return "${qrb.toInt()} km (${bearing.toInt()})°" + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/DirectedMessageRowStyle.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/DirectedMessageRowStyle.kt new file mode 100644 index 00000000..b24cf76c --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/DirectedMessageRowStyle.kt @@ -0,0 +1,68 @@ +package kst4contest.view.compose + +import androidx.compose.ui.graphics.Color +import kst4contest.view.PrivateMessageRowStyleResolver + +/** + * The row colouring of the directed-message table. + * + * A new private message is highlighted and the highlight fades over five minutes, so a call + * that arrived while the operator was looking at the station list is still findable — being + * noticed is what that pane exists for. Own messages are blue at any age: they are context, + * not news. + * + * The steps come from [PrivateMessageRowStyleResolver], which the JavaFX row factory uses, so + * the two cannot drift apart. The colours are the stylesheets' `.messageHighlight*-column`, + * identical in both designs. + */ +object DirectedMessageRowStyle { + + /** `.messageHighlightOwn-column`. */ + val OWN = Color(0xFF00FFFF) + + /** `.messageHighlight30-column`: just arrived. */ + val FRESH = Color(0xFF33CC33) + + /** + * The fading green of `.messageHighlight30` through `.messageHighlight300`, in the order + * the resolver's age limits name them. + */ + private val FADE = listOf( + FRESH, + Color(0xFF40BF40), + Color(0xFF4DB34D), + Color(0xFF59A659), + Color(0xFF669966), + Color(0xFF738C73), + ) + + /** The resolver's style class names, in the same order as [FADE]. */ + private val FADE_CLASSES = listOf( + "messageHighlight30-column", + "messageHighlight60-column", + "messageHighlight90-column", + "messageHighlight120-column", + "messageHighlight180-column", + "messageHighlight300-column", + ) + + /** + * How a row is coloured, or null once the message is no longer news. + * + * The style class is asked of the resolver rather than recomputed here, so a change to + * the fade steps reaches both views at once. + */ + fun accentFor(ownMessage: Boolean, ageSeconds: Long): CellAccent? { + val styleClass = PrivateMessageRowStyleResolver.resolveStyleClass(ownMessage, ageSeconds) + ?: return null + + if (styleClass == PrivateMessageRowStyleResolver.OWN_STYLE_CLASS) { + return CellAccent(background = OWN, foreground = Color.Black) + } + + val index = FADE_CLASSES.indexOf(styleClass) + if (index < 0) return null + + return CellAccent(background = FADE[index], foreground = Color.White) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/FormControls.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/FormControls.kt new file mode 100644 index 00000000..11f78377 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/FormControls.kt @@ -0,0 +1,564 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.FlowRowScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.interaction.collectIsHoveredAsState +import androidx.compose.foundation.interaction.collectIsPressedAsState +import androidx.compose.ui.graphics.Brush +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.Checkbox +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.LocalMinimumInteractiveComponentSize +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.OutlinedTextFieldDefaults +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.MutableState +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.KeyEventType +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.onKeyEvent +import androidx.compose.ui.input.key.type +import androidx.compose.ui.text.input.PasswordVisualTransformation +import androidx.compose.ui.text.input.VisualTransformation +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp + +/** + * Form controls shared by the settings tabs. + * + * Numeric fields keep the operator's text while it is being typed and only hand a + * parsed value upwards when it parses. Rejecting keystrokes instead would make a + * field impossible to clear, and replacing an unparsable entry with a default would + * silently change a setting — PROJECT_CONTEXT is explicit that an absent or malformed + * value must not become a fabricated zero. + * + * Every control here is built to desktop density; see [Density] for why and for the + * measurements. + */ +object Form { + + @Composable + fun text(label: String, value: String?, enabled: Boolean = true, onChange: (String) -> Unit) { + val draft = rememberDraft(value ?: "") + + labelled(label) { + CompactTextField( + value = draft.value, + onValueChange = { typed -> + draft.value = typed + onChange(typed) + }, + enabled = enabled, + modifier = Modifier.fillMaxWidth(), + ) + } + } + + @Composable + fun password(label: String, value: String?, enabled: Boolean = true, onChange: (String) -> Unit) { + val draft = rememberDraft(value ?: "") + + labelled(label) { + CompactTextField( + value = draft.value, + onValueChange = { typed -> + draft.value = typed + onChange(typed) + }, + enabled = enabled, + visualTransformation = PasswordVisualTransformation(), + modifier = Modifier.fillMaxWidth(), + ) + } + } + + /** + * A text field that is validated when it is committed, not while it is typed. + * + * This is the Compose counterpart of the JavaFX fields which hung their rule on + * `focusedProperty` — the DX cluster port, the spotter callsign, the beacon + * templates and the beacon interval. Committing on every keystroke would refuse + * every prefix of a valid entry, so the draft lives here until the operator leaves + * the field or presses Enter. + * + * @param stored the value currently stored; the draft falls back to it when an + * entry is refused, which is what those fields did with setText + * @param commit returns null when the value was accepted, otherwise the reason + * @param onRefused shown to the operator; the JavaFX fields opened an alert + */ + @Composable + fun committed( + label: String, + stored: String, + commit: (String) -> String?, + onRefused: (String) -> Unit, + ) { + var draft by remember(stored) { mutableStateOf(stored) } + + fun commitDraft() { + val refusal = commit(draft) + if (refusal != null) { + onRefused(refusal) + draft = stored + } + } + + labelled(label) { + CompactTextField( + value = draft, + onValueChange = { draft = it }, + modifier = Modifier + .fillMaxWidth() + .onFocusChanged { focus -> if (!focus.isFocused) commitDraft() } + .onKeyEvent { event -> + if (event.type == KeyEventType.KeyUp && event.key == Key.Enter) { + commitDraft() + true + } else { + false + } + }, + ) + } + } + + /** + * Picks one item from a fixed list, the counterpart of the JavaFX ChoiceBox. + * + * A null selection is possible and shown as such: the second chat category has no + * value until the operator picks one, and inventing one would log the station into + * a chat it never chose. + */ + @Composable + fun choice( + label: String, + items: List, + selected: T?, + describe: (T) -> String, + enabled: Boolean = true, + onSelect: (T) -> Unit, + ) { + var expanded by remember { mutableStateOf(false) } + val draft = rememberDraft(selected) + + labelled(label) { + Box { + OutlinedButton( + onClick = { expanded = true }, + enabled = enabled, + shape = Density.BUTTON_SHAPE, + contentPadding = Density.FIELD_CONTENT_PADDING, + modifier = Modifier + .fillMaxWidth() + .heightIn(min = Density.FIELD_MIN_HEIGHT), + ) { + Text( + draft.value?.let(describe) ?: "not selected", + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier.fillMaxWidth(), + ) + } + DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) { + items.forEach { item -> + DropdownMenuItem( + text = { Text(describe(item), style = MaterialTheme.typography.bodyMedium) }, + onClick = { + expanded = false + draft.value = item + onSelect(item) + }, + ) + } + } + } + } + } + + @Composable + fun inlineChoice( + label: String, + items: List, + selected: T?, + describe: (T) -> String, + enabled: Boolean = true, + onSelect: (T) -> Unit, + ) { + var expanded by remember { mutableStateOf(false) } + val draft = rememberDraft(selected) + + Row(verticalAlignment = Alignment.CenterVertically) { + Text(label, style = MaterialTheme.typography.bodyMedium, modifier = Modifier.padding(end = 8.dp)) + Box { + OutlinedButton( + onClick = { expanded = true }, + enabled = enabled, + shape = Density.BUTTON_SHAPE, + contentPadding = Density.FIELD_CONTENT_PADDING, + modifier = Modifier.heightIn(min = Density.FIELD_MIN_HEIGHT), + ) { + Text( + draft.value?.let(describe) ?: "not selected", + style = MaterialTheme.typography.bodyMedium, + ) + } + DropdownMenu(expanded = expanded, onDismissRequest = { expanded = false }) { + items.forEach { item -> + DropdownMenuItem( + text = { Text(describe(item), style = MaterialTheme.typography.bodyMedium) }, + onClick = { + expanded = false + draft.value = item + onSelect(item) + }, + ) + } + } + } + } + } + + @Composable + fun check(label: String, value: Boolean, onChange: (Boolean) -> Unit) { + val draft = rememberDraft(value) + + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.heightIn(min = Density.ROW_MIN_HEIGHT), + ) { + CompactCheckbox(draft.value) { ticked -> + draft.value = ticked + onChange(ticked) + } + Text(label, modifier = Modifier.padding(start = 6.dp)) + } + } + + @Composable + fun int(label: String, value: Int, onChange: (Int) -> Unit) { + var draft by remember(value) { mutableStateOf(value.toString()) } + + labelled(label) { + CompactTextField( + value = draft, + onValueChange = { typed -> + draft = typed + typed.trim().toIntOrNull()?.let(onChange) + }, + isError = draft.trim().toIntOrNull() == null, + modifier = Modifier.fillMaxWidth(), + ) + } + } + + @Composable + fun decimal(label: String, value: Double, onChange: (Double) -> Unit) { + var draft by remember(value) { mutableStateOf(value.toString()) } + + labelled(label) { + CompactTextField( + value = draft, + onValueChange = { typed -> + draft = typed + typed.trim().replace(',', '.').toDoubleOrNull()?.let(onChange) + }, + isError = draft.trim().replace(',', '.').toDoubleOrNull() == null, + modifier = Modifier.fillMaxWidth(), + ) + } + } + + /** + * A titled section. + * + * The JavaFX window drew `generateLabeledSeparator`: a rule, the label, another + * rule. Here the label leads and one rule runs to the right edge, which sits + * better above the left-aligned label column than a centred title does. Either + * way it is a visible division, which a bare line of text was not. + */ + @Composable + fun section(title: String, content: @Composable () -> Unit) { + Column( + modifier = Modifier.fillMaxWidth().padding(top = 10.dp), + verticalArrangement = Arrangement.spacedBy(Density.FIELD_GAP), + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth().padding(bottom = 2.dp), + ) { + Text(title, style = MaterialTheme.typography.titleSmall) + HorizontalDivider(modifier = Modifier.weight(1f).padding(start = 8.dp)) + } + content() + } + } + + /** + * A section whose controls flow across the width instead of stacking. + * + * For short, like-for-like options — the nine band checkboxes, the startup filters. + * Stacked they cost nine rows of height for nine words; flowing they fill the width + * the window actually has and re-flow when it changes. + */ + @OptIn(ExperimentalLayoutApi::class) + @Composable + fun flowingSection(title: String, content: @Composable FlowRowScope.() -> Unit) { + section(title) { + FlowRow( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.spacedBy(16.dp), + content = content, + ) + } + } + + /** + * A labelled row holding a control this object does not provide, so a tab can add + * one without losing the shared label column. + */ + @Composable + fun labelledRow(label: String, field: @Composable () -> Unit) { + labelled(label, field) + } + + /** + * The button of the settings windows: square-ish corners and desktop padding. + * + * Material's own Button is a 40dp pill, which is the single strongest reason the + * window looked like a phone application. + */ + /** + * The button of the settings windows. + * + * Material's own Button is a 40dp pill; this one is square-ish and at desktop + * height. It also carries the two states the JavaFX stylesheets give every button: + * a gradient while the pointer is over it and a red border while it is held down. + */ + @Composable + fun button(text: String, enabled: Boolean = true, onClick: () -> Unit) { + val palette = LocalJavaFxPalette.current + val interactions = remember { MutableInteractionSource() } + val hovered by interactions.collectIsHoveredAsState() + val pressed by interactions.collectIsPressedAsState() + + val hoverGradient = palette.buttonHoverGradient + + CompositionLocalProvider( + LocalMinimumInteractiveComponentSize provides 0.dp + ) { + Button( + onClick = onClick, + enabled = enabled, + shape = Density.BUTTON_SHAPE, + contentPadding = Density.BUTTON_CONTENT_PADDING, + interactionSource = interactions, + border = if (pressed) { + BorderStroke(Density.SELECTION_BORDER, palette.buttonPressedBorder) + } else { + null + }, + colors = if (hovered && enabled && hoverGradient.isNotEmpty()) { + /* + * Compose paints a solid container, so the gradient is applied as the + * background below and the container itself is cleared. The text turns + * dark because the gradient the sheets use is a bright lime. + */ + ButtonDefaults.buttonColors( + containerColor = Color.Transparent, + contentColor = Color.Black, + ) + } else { + ButtonDefaults.buttonColors( + containerColor = MaterialTheme.colorScheme.surfaceVariant, + contentColor = MaterialTheme.colorScheme.onSurfaceVariant, + ) + }, + modifier = Modifier + .heightIn(min = Density.BUTTON_MIN_HEIGHT) + .then( + if (hovered && enabled && hoverGradient.size >= 2) { + Modifier.background( + brush = Brush.verticalGradient(hoverGradient), + shape = Density.BUTTON_SHAPE, + ) + } else { + Modifier + } + ), + ) { + /* + * One line, always. A label left to wrap turns a squeezed button into a tall + * bar instead of simply being too narrow, and that bar then pushes the rest + * of the window out of view. + */ + Text(text, style = MaterialTheme.typography.bodyMedium, maxLines = 1) + } + } + } + + /** + * Holds what the operator sees while they change it. + * + * The settings controls are bound to plain ChatPreferences values, and those are not + * Compose state: writing one triggers no recomposition, so a field bound straight to + * the stored value keeps painting the value from the last composition. Typing then + * writes through correctly and shows nothing, a checkbox never appears to tick, and a + * picker never appears to change — which is exactly how it behaved. + * + * Keyed on the stored value, so an external change still reaches the control, and so + * a setter that normalises its input (a trimmed space, an upper-cased callsign) puts + * the normalised value back. This is the pattern GuardedTextField already used for + * the external-interface fields. + */ + @Composable + private fun rememberDraft(stored: T): MutableState = + remember(stored) { mutableStateOf(stored) } + + @Composable + private fun labelled(label: String, field: @Composable () -> Unit) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.heightIn(min = Density.ROW_MIN_HEIGHT), + ) { + Text( + label, + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier.width(Density.LABEL_COLUMN_WIDTH), + ) + field() + } + } +} + +/** + * A text field at desktop density. + * + * Built from BasicTextField and the outlined decoration box rather than from + * OutlinedTextField, because that composable enforces a 56dp minimum height which + * cannot be passed a smaller one. The decoration box takes the content padding, and + * that is what buys the height back. + * + * The decoration box and its container are marked experimental in Material 3. The + * opt-in is deliberate and there is no alternative: it is the only supported way to + * build a text field below the enforced minimum height. Should the signature change, + * the two calls below are the whole surface to fix, and the tests around the tab states + * stay unaffected because none of them render. + * + * @param borderColor overrides the outline, so a caller can mark a selected row + * @param borderThickness overrides the outline width for the same reason + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +internal fun CompactTextField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + enabled: Boolean = true, + isError: Boolean = false, + visualTransformation: VisualTransformation = VisualTransformation.None, + borderColor: Color? = null, + borderThickness: Dp? = null, +) { + val interactionSource = remember { MutableInteractionSource() } + /* + * The container is the JavaFX -fx-control-inner-background, which both sheets set + * apart from the window background. Material leaves an outlined field transparent, + * which made every field vanish into the surface. + */ + val colors = OutlinedTextFieldDefaults.colors( + unfocusedBorderColor = borderColor ?: MaterialTheme.colorScheme.outline, + focusedBorderColor = borderColor ?: MaterialTheme.colorScheme.primary, + unfocusedContainerColor = MaterialTheme.colorScheme.surfaceVariant, + focusedContainerColor = MaterialTheme.colorScheme.surfaceVariant, + disabledContainerColor = MaterialTheme.colorScheme.surfaceVariant, + ) + + /* + * The colour has to be carried in the text style: BasicTextField has no theme of + * its own, so without this the text would stay black in the evening design. + */ + val onField = MaterialTheme.colorScheme.surfaceVariant.let { field -> + val brightness = 0.3f * field.red + 0.59f * field.green + 0.11f * field.blue + if (brightness > 0.5f) Color.Black else Color.White + } + val textColor = if (enabled) onField else onField.copy(alpha = 0.38f) + + BasicTextField( + value = value, + onValueChange = onValueChange, + enabled = enabled, + singleLine = true, + textStyle = MaterialTheme.typography.bodyMedium.copy(color = textColor), + cursorBrush = SolidColor(MaterialTheme.colorScheme.primary), + visualTransformation = visualTransformation, + interactionSource = interactionSource, + modifier = modifier.heightIn(min = Density.FIELD_MIN_HEIGHT), + ) { innerTextField -> + OutlinedTextFieldDefaults.DecorationBox( + value = value, + innerTextField = innerTextField, + enabled = enabled, + singleLine = true, + visualTransformation = visualTransformation, + interactionSource = interactionSource, + isError = isError, + colors = colors, + contentPadding = Density.FIELD_CONTENT_PADDING, + container = { + OutlinedTextFieldDefaults.Container( + enabled = enabled, + isError = isError, + interactionSource = interactionSource, + colors = colors, + shape = Density.BUTTON_SHAPE, + focusedBorderThickness = borderThickness ?: 2.dp, + unfocusedBorderThickness = borderThickness ?: 1.dp, + ) + }, + ) + } +} + +/** + * A checkbox without the 48dp touch target Material reserves around it. On a desktop + * form that target is dead space between every two rows. + */ +@Composable +internal fun CompactCheckbox(checked: Boolean, onCheckedChange: (Boolean) -> Unit) { + CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides Dp.Unspecified) { + Checkbox( + checked = checked, + onCheckedChange = onCheckedChange, + modifier = Modifier.size(Density.CHECK_SIZE), + ) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/JavaFxStylesheet.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/JavaFxStylesheet.kt new file mode 100644 index 00000000..e0fcf8b6 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/JavaFxStylesheet.kt @@ -0,0 +1,447 @@ +package kst4contest.view.compose + +import androidx.compose.ui.graphics.Color +import kst4contest.ApplicationConstants +import kst4contest.model.PaletteRole + +/** + * The colours the Compose windows take from the JavaFX stylesheets. + * + * @param fontSizePx the `-fx-font-size` of `.root`; both shipped sheets set 12px + */ +data class JavaFxPalette( + val base: Color, + /** + * What a window is actually painted with. Modena's `-fx-background` is + * `derive(-fx-base, 26.4%)`, not `-fx-base` itself: taking the base raw makes a + * Compose window visibly darker than the JavaFX one beside it. + */ + val windowBackground: Color, + val accent: Color, + /** + * The colour the operator actually reads as the accent. + * + * `-fx-accent` only drives JavaFX's own selection bar, which barely shows. What is + * seen instead is `.text-field .text`: both sheets fill the text inside every field + * — and the table column headers of the evening sheet — with a green gradient. A + * solid colour is needed here, so the gradient is collapsed to its midpoint. + */ + val textAccent: Color, + val controlInnerBackground: Color, + val labelTextFill: Color, + val separatorLine: Color, + val buttonHoverGradient: List, + val buttonPressedBorder: Color, + val fontSizePx: Float, +) + +/** + * Reads the colours of a JavaFX stylesheet. + * + * This is deliberately not a CSS engine. It looks up the handful of declarations the + * Compose windows need and understands only what those declarations actually use: + * colour literals, named colours, references to another `-fx-` value in the same + * sheet, `derive(colour, percent)` and the stops of a `linear-gradient`. + * + * **The source is the classpath resource, the same one JavaFX loads.** The copies + * under the application directory are written at startup but never read back: + * `applyThemeStylesheet` passes the bare file name to `Scene.getStylesheets()`, and + * JavaFX resolves a relative stylesheet name against the classpath. Reading the copy + * here would make the two windows disagree exactly when an operator edits it. + * + * The daylight sheet declares almost nothing and relies on JavaFX's own Modena + * defaults, so every lookup falls back to the matching Modena value. + */ +object JavaFxStylesheet { + + /* + * The classpath paths of the two shipped sheets, derived from the one place that owns + * their file names. They used to be spelled out in four places -- here, the theme, the + * store factory and the startup copy -- and two of those had to stay equal for the root + * profile's own stylesheet to be read at all: the copy is written under one name and read + * under the other. A rename on one side would silently restore the very defect this stage + * was commissioned to fix, with a green build. + */ + val DAYLIGHT_RESOURCE = "/" + ApplicationConstants.STYLECSSFILE_DEFAULT_DAYLIGHT + val EVENING_RESOURCE = "/" + ApplicationConstants.STYLECSSFILE_DEFAULT_EVENING + + /** + * The shipped palette of one design. + * + * @param darkMode true for the evening design, false for the daylight one + * @return the complete palette, Modena fallbacks included + */ + fun shipped(darkMode: Boolean): JavaFxPalette = + read(if (darkMode) EVENING_RESOURCE else DAYLIGHT_RESOURCE) + + /** Modena's own `-fx-background: derive(-fx-base, 26.4%)`. */ + private const val MODENA_BACKGROUND_DERIVE = 26.4 + + /* Modena's defaults, used wherever a sheet declares nothing. */ + private val MODENA_BASE = Color(0xFFECECEC) + private val MODENA_ACCENT = Color(0xFF0096C9) + private val MODENA_CONTROL_INNER = Color(0xFFFFFFFF) + private val MODENA_TEXT = Color(0xFF000000) + + private val NAMED_COLORS = mapOf( + "white" to Color.White, + "black" to Color.Black, + "lightgray" to Color(0xFFD3D3D3), + "lightgrey" to Color(0xFFD3D3D3), + "gray" to Color(0xFF808080), + "grey" to Color(0xFF808080), + "darkgray" to Color(0xFFA9A9A9), + "green" to Color(0xFF008000), + "lightgreen" to Color(0xFF90EE90), + "red" to Color(0xFFFF0000), + "blue" to Color(0xFF0000FF), + "yellow" to Color(0xFFFFFF00), + "orange" to Color(0xFFFFA500), + "transparent" to Color.Transparent, + ) + + /** + * @param resourcePath classpath path of the sheet, for example + * `/KST4ContestDefaultEvening.css` + */ + fun read(resourcePath: String): JavaFxPalette { + val source = JavaFxStylesheet::class.java.getResource(resourcePath)?.readText().orEmpty() + val blocks = parseBlocks(source) + val root = blocks[".root"].orEmpty() + + val base = colorOf(root["-fx-base"], root) ?: MODENA_BASE + val accent = colorOf(root["-fx-accent"], root) ?: MODENA_ACCENT + + return JavaFxPalette( + base = base, + windowBackground = colorOf(root["-fx-background"], root) + ?: derive(base, MODENA_BACKGROUND_DERIVE), + textAccent = midpointOf( + gradientStops(blocks[".text-field .text"]?.get("-fx-fill"), root) + ) ?: accent, + accent = accent, + controlInnerBackground = colorOf(root["-fx-control-inner-background"], root) + ?: MODENA_CONTROL_INNER, + labelTextFill = colorOf(blocks[".label"]?.get("-fx-text-fill"), root) ?: MODENA_TEXT, + /* Modena draws the line one fifth darker than the base. */ + separatorLine = colorOf(blocks[".separator *.line"]?.get("-fx-background-color"), root) + ?: derive(base, -20.0), + buttonHoverGradient = gradientStops( + blocks[".button:hover"]?.get("-fx-background-color"), root + ), + buttonPressedBorder = colorOf(blocks[".button:pressed"]?.get("-fx-border-color"), root) + ?: accent, + fontSizePx = root["-fx-font-size"]?.removeSuffix("px")?.trim()?.toFloatOrNull() ?: 12f, + ) + } + + /** + * The roles a stylesheet source actually names. + * + * Deliberately not [read]: that one fills a missing role from the Modena defaults, which + * is right for the shipped sheets and wrong for a layer meant to override one role at a + * time. A sheet saying only `-fx-base` must declare exactly one role. + * + * Each role is looked up at its own selector, because three of the six are stated + * outside `.root` and one of those properties -- `-fx-background-color` -- appears a + * dozen times elsewhere in the evening sheet. `.root` stays the scope in which a `-fx-` + * reference or a `derive(...)` is resolved, exactly as [read] resolves them. + * + * A value this reader does not understand -- a gradient, say -- leaves the role + * undeclared, so it falls through to the layer below rather than becoming a guess. + */ + fun declaredRoles(source: String): Map { + val blocks = parseBlocks(source) + val root = blocks[".root"].orEmpty() + + val stated = PaletteRole.values().mapNotNull { role -> + val value = blocks[role.selector()]?.get(role.cssProperty()) + ?: return@mapNotNull null + val colour = colorOf(value, root) ?: return@mapNotNull null + role to colour + }.toMap() + + /* + * A sheet that states `-fx-base` and no `-fx-background` has stated the window surface + * too, because that is what JavaFX does with it: Modena's `-fx-background` is + * `derive(-fx-base, 26.4%)`, and [read] applies the same fallback. Without this the + * most natural hand edit is nearly inert -- `-fx-base: #303030` would leave every + * window the shipped light grey, since the base itself reaches the screen only through + * the menu strip and the selection tint. + * + * Only here, in the file layer. The settings tab keeps the two roles independent, + * which is why the spec separates them at all: six fields are visible there, so an + * operator who wants both changed can say so. + * + * A consequence worth stating rather than discovering: the tab then reports the window + * surface as coming *from file* for a colour the file never spells out. That is the + * right answer. The provenance exists to answer "why is this colour what it is", not + * "which line names it", and the file's `-fx-base` is why. + */ + val base = stated[PaletteRole.SURFACE] + + if (base == null || stated.containsKey(PaletteRole.WINDOW_SURFACE)) { + return stated + } + + return stated + (PaletteRole.WINDOW_SURFACE to derive(base, MODENA_BACKGROUND_DERIVE)) + } + + /** + * The roles a stylesheet file names, or none when it cannot be read. + * + * Never throws. A client that will not start because of a broken colour file is worse + * than a client in the wrong colours, and this file is one the operator edited by hand. + */ + fun declaredRolesOfFile(file: java.io.File): Map = + runCatching { + if (!file.isFile) emptyMap() else declaredRoles(file.readText()) + }.getOrDefault(emptyMap()) + + /** + * JavaFX `derive(colour, percent)`, reimplemented. + * + * No JavaFX call and no reflection: this is the algorithm itself. The brightness it + * derives from is not the HSB value but `0.3R + 0.59G + 0.11B`, and the positive + * branch follows a staircase rather than a formula, which is why an earlier + * approximation here was measurably wrong. + * + * Correctness is not argued, it is pinned: `JavaFxStylesheetTest` checks this against + * values the real JavaFX colour-derivation routine produced, frozen into + * `javafx-derive-reference.txt` so the check survives JavaFX being removed. That + * file's header names the exact class the values came from. + * Every grey and both stylesheet bases match. One saturated blue drifts by up to + * three steps per channel. That is tolerable only because no saturated colour + * reaches here: three of the four call sites pass the window background or + * `-fx-base`, and the fourth is [parseColour]'s own `derive(...)` branch below, + * which passes whatever a sheet names — and every `derive(...)` in both shipped + * sheets derives from `-fx-base` alone. A hand-edited sheet can break that: an + * operator who sets `-fx-base` to a saturated colour sends every `derive(...)` of it + * through the inaccurate part. Revisited when the colours became operator-editable and + * deliberately left alone — a drift of three steps per channel is not perceptible in a + * colour somebody chose themselves, and what the settings tab sets does not pass + * through here at all: the resolver substitutes finished colours. + */ + fun derive(color: Color, percent: Double): Color { + val baseBrightness = 0.3 * color.red + 0.59 * color.green + 0.11 * color.blue + var calcBrightness = percent / 100.0 + + if (calcBrightness > 0) { + if (baseBrightness > 0.85) { + calcBrightness *= 1.6 + } else if (baseBrightness > 0.6) { + // no change + } else if (baseBrightness > 0.5) { + calcBrightness *= 0.9 + } else if (baseBrightness > 0.4) { + calcBrightness *= 0.8 + } else if (baseBrightness > 0.3) { + calcBrightness *= 0.7 + } else { + calcBrightness *= 0.6 + } + } else { + if (baseBrightness < 0.2) { + calcBrightness *= 0.6 + } + } + + calcBrightness = calcBrightness.coerceIn(-1.0, 1.0) + + // RGBtoHSB + val r = color.red.toDouble() + val g = color.green.toDouble() + val b = color.blue.toDouble() + val cmax = maxOf(r, g, b) + val cmin = minOf(r, g, b) + val brightness = cmax + val saturation = if (cmax != 0.0) (cmax - cmin) / cmax else 0.0 + var hue = 0.0 + + if (saturation != 0.0) { + val redc = (cmax - r) / (cmax - cmin) + val greenc = (cmax - g) / (cmax - cmin) + val bluec = (cmax - b) / (cmax - cmin) + hue = when { + r == cmax -> bluec - greenc + g == cmax -> 2.0 + redc - bluec + else -> 4.0 + greenc - redc + } + hue /= 6.0 + if (hue < 0) { + hue += 1.0 + } + } + + hue *= 360.0 + var derivedSat = saturation + var derivedBri = brightness + + if (calcBrightness > 0) { + derivedSat *= (1.0 - calcBrightness) + derivedBri += (1.0 - derivedBri) * calcBrightness + } else { + derivedBri *= (calcBrightness + 1.0) + } + + derivedSat = derivedSat.coerceIn(0.0, 1.0) + derivedBri = derivedBri.coerceIn(0.0, 1.0) + + return Color.hsv(hue.toFloat(), derivedSat.toFloat(), derivedBri.toFloat(), color.alpha) + } + + /** `selector { property: value; ... }`, comments removed. */ + private fun parseBlocks(source: String): Map> { + val withoutComments = source.replace(Regex("/\\*.*?\\*/", RegexOption.DOT_MATCHES_ALL), "") + val blocks = mutableMapOf>() + + Regex("([^{}]+)\\{([^{}]*)\\}").findAll(withoutComments).forEach { match -> + val selector = match.groupValues[1].trim().replace(Regex("\\s+"), " ") + val declarations = blocks.getOrPut(selector) { mutableMapOf() } + + splitOnTopLevel(match.groupValues[2], ';').forEach { declaration -> + val separator = declaration.indexOf(':') + if (separator > 0) { + declarations[declaration.take(separator).trim()] = + declaration.substring(separator + 1).trim() + } + } + } + + return blocks + } + + /** + * Resolves one value to a colour, or null when it is absent or is something this + * reader does not need to understand. + * + * @param variables the `.root` declarations, where `-fx-` references are looked up + */ + private fun colorOf(value: String?, variables: Map, depth: Int = 0): Color? { + val text = value?.trim()?.removeSuffix(";")?.trim() ?: return null + + /* A malformed sheet must not spin here: -fx-a: -fx-b; -fx-b: -fx-a; */ + if (depth > 8 || text.isEmpty()) { + return null + } + + NAMED_COLORS[text.lowercase()]?.let { return it } + + if (text.startsWith("#")) { + return hexColor(text) + } + + if (text.startsWith("-fx-")) { + return colorOf(variables[text], variables, depth + 1) + } + + if (text.startsWith("derive(")) { + val arguments = splitOnTopLevel(text.removePrefix("derive(").dropLast(1), ',') + if (arguments.size == 2) { + val source = colorOf(arguments[0], variables, depth + 1) ?: return null + val percent = arguments[1].removeSuffix("%").trim().toDoubleOrNull() ?: return null + return derive(source, percent) + } + return null + } + + if (text.contains("linear-gradient(")) { + return gradientStops(text, variables).firstOrNull() + } + + return null + } + + /** + * The colour stops of the first `linear-gradient` in a value. A stop may carry a + * position (`green 0%`) or a direction (`from 0% 0% to 100% 200%`); only the + * colours are wanted here. + */ + private fun gradientStops(value: String?, variables: Map): List { + val text = value?.trim() ?: return emptyList() + val start = text.indexOf("linear-gradient(") + + if (start < 0) { + return emptyList() + } + + var depth = 0 + var end = -1 + + for (index in start + "linear-gradient".length until text.length) { + when (text[index]) { + '(' -> depth++ + ')' -> { + depth-- + if (depth == 0) { + end = index + break + } + } + } + } + + if (end < 0) { + return emptyList() + } + + return splitOnTopLevel(text.substring(start + "linear-gradient(".length, end), ',') + .filterNot { it.startsWith("from ") || it.startsWith("to ") } + .mapNotNull { colorOf(it.split(Regex("\\s+")).first(), variables) } + } + + /** + * Collapses a gradient to one colour by averaging its ends. Compose paints solid + * where JavaFX paints a gradient across the glyphs, and the average is what the eye + * takes from the gradient anyway. + */ + private fun midpointOf(stops: List): Color? { + if (stops.isEmpty()) { + return null + } + + val first = stops.first() + val last = stops.last() + + return Color( + red = (first.red + last.red) / 2f, + green = (first.green + last.green) / 2f, + blue = (first.blue + last.blue) / 2f, + alpha = 1f, + ) + } + + /** Splits on a separator that is not inside brackets. */ + private fun splitOnTopLevel(text: String, separator: Char): List { + val parts = mutableListOf() + var depth = 0 + var start = 0 + + text.forEachIndexed { index, character -> + when (character) { + '(' -> depth++ + ')' -> depth-- + separator -> if (depth == 0) { + parts.add(text.substring(start, index)) + start = index + 1 + } + } + } + + parts.add(text.substring(start)) + return parts.map { it.trim() }.filter { it.isNotEmpty() } + } + + private fun hexColor(text: String): Color? { + val digits = text.removePrefix("#") + + val expanded = when (digits.length) { + 3 -> digits.toCharArray().joinToString("") { "$it$it" } + 6 -> digits + else -> return null + } + + val value = expanded.toLongOrNull(16) ?: return null + return Color(0xFF000000L or value) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuBar.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuBar.kt new file mode 100644 index 00000000..21873d53 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuBar.kt @@ -0,0 +1,223 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.hoverable +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsHoveredAsState +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.window.FrameWindowScope +import androidx.compose.ui.window.MenuBar +import kst4contest.controller.On4KstConnectionState +import kst4contest.utils.PlatformUtils +import kst4contest.view.i18n.LocalStrings + +/** + * What the menu bar does when something is picked. + * + * An interface rather than a dozen lambdas: every window is meant to carry this same bar, and a + * parameter list that long is misread sooner or later. + */ +interface MainMenuActions { + fun connect() + fun disconnect() + fun switchOperatorProfile() + fun exitApplication() + fun setQrgAsNameInChat() + fun toggleAwayState() + fun toggleSettingsWindow() + fun toggleMonitorWindow() + fun toggleStationMap() + fun useDarkDesign() + fun useDefaultDesign() + fun openDonationPage() + fun openHomepage() + fun openNewsgroup() + /** The JavaFX item and its handler are both commented out; kept so the bar can say so. */ + fun openChangelog() + + /** OV3T runs the aeroplane feed the AirScout predictions come from. */ + fun openOv3tDonationPage() + fun contactAuthor() + fun showAbout() +} + +/** + * The menu bar in the system's own bar — macOS only. + * + * Compose's `MenuBar` is a `javax.swing.JMenuBar` set on the window, so Swing draws it and + * no Compose theme reaches it. On macOS that is what one wants: the bar belongs at the top + * of the screen, drawn by the system. Everywhere else it meant an unthemed Metal menu + * sitting above a themed window, which is why [Kst4ContestMenuRow] exists. + * + * Both renderers read [mainMenuModel]. Declaring the menus twice is how one of them quietly + * loses an item the other gained. + */ +@Composable +fun FrameWindowScope.Kst4ContestMenuBar( + state: MainMenuState, + actions: MainMenuActions, + settingsWindowOpen: Boolean, + monitorWindowOpen: Boolean, + /** + * The connection state, for the read-only macOS menu. On macOS the status bar hides its + * badge because the indicator lives in the system menu bar, so without this menu a + * macOS operator would have no connection indicator at all. + */ + connectionState: On4KstConnectionState? = null, + connectionDetail: String? = null, +) { + val strings = LocalStrings.current + + MenuBar { + mainMenuModel(state, actions, settingsWindowOpen, monitorWindowOpen, strings) + .forEach { menu -> + Menu(menu.title) { + menu.entries.forEach { entry -> + when (entry) { + is MenuEntry.Item -> + Item(entry.label, enabled = entry.enabled, onClick = entry.onClick) + MenuEntry.Separator -> Separator() + } + } + } + } + + /* + * The connection indicator, for macOS only: the system menu bar is where it lives + * there, because the status bar's badge is hidden on that platform. Read-only — the + * single item is disabled, exactly as menuItemConnectionStateDetailMacOs was. + */ + if (PlatformUtils.isMacOs()) { + Menu(ConnectionIndicator.macOsMenuTitle(connectionState)) { + Item( + ConnectionIndicator.detailFor(connectionState, connectionDetail), + enabled = false, + onClick = {}, + ) + } + } + } +} + +/** + * The menu bar drawn inside the window, by Compose. + * + * Used everywhere except macOS. It exists because Compose's `MenuBar` hands the job to + * Swing, which knows nothing of the stylesheet palette: under Linux that produced the + * default cross-platform Metal menu above a themed window. This row reads the same palette + * as every other control, so a design switch reaches it. + * + * A menu title is shaped like a tab — flat, highlighted while active — so it takes the tab + * measurements rather than the button ones, and it highlights with the accent colour, which + * is what a JavaFX menu did. + * + * @param rowState which menu is down. Owned by the caller because `MainWindow` has to ask + * [MainMenuRowState.anyOpen] before letting the window-wide keys run. + */ +@Composable +fun Kst4ContestMenuRow( + state: MainMenuState, + actions: MainMenuActions, + settingsWindowOpen: Boolean, + monitorWindowOpen: Boolean, + rowState: MainMenuRowState, + modifier: Modifier = Modifier, +) { + val palette = LocalJavaFxPalette.current + val strings = LocalStrings.current + val menus = mainMenuModel(state, actions, settingsWindowOpen, monitorWindowOpen, strings) + + Row( + modifier = modifier + .fillMaxWidth() + .background(palette.base) + .heightIn(min = Density.TAB_MIN_HEIGHT), + verticalAlignment = Alignment.CenterVertically, + ) { + menus.forEach { menu -> + MenuTitle(menu = menu, rowState = rowState) + } + } +} + +@Composable +private fun MenuTitle(menu: MenuSpec, rowState: MainMenuRowState) { + val palette = LocalJavaFxPalette.current + val interactions = remember { MutableInteractionSource() } + val hovered by interactions.collectIsHoveredAsState() + val open = rowState.openMenu == menu.title + + Box { + Text( + text = menu.title, + style = MaterialTheme.typography.bodyMedium, + /* + * contrastingText and not textAccent: the accent is the background right behind + * this title, and once an operator can set the accent the two can be the same + * colour -- an invisible menu title. Black or white by brightness is readable by + * construction. + */ + color = if (open) contrastingText(palette.accent) else palette.labelTextFill, + modifier = Modifier + .background( + when { + open -> palette.accent + /* + * Hover is a hint, not a selection: the accent at full strength on + * mere pointer travel makes the bar flicker as the operator crosses + * it on the way to the chat field. + */ + hovered -> palette.accent.copy(alpha = HOVER_ALPHA) + else -> Color.Transparent + } + ) + .hoverable(interactions) + .clickable { rowState.toggle(menu.title) } + .padding( + horizontal = Density.TAB_HORIZONTAL_PADDING, + vertical = MENU_TITLE_VERTICAL_PADDING, + ), + ) + + DropdownMenu(expanded = open, onDismissRequest = rowState::close) { + menu.entries.forEach { entry -> + when (entry) { + is MenuEntry.Item -> DropdownMenuItem( + text = { + Text(entry.label, style = MaterialTheme.typography.bodyMedium) + }, + enabled = entry.enabled, + onClick = { rowState.pick(entry.onClick) }, + ) + + MenuEntry.Separator -> + HorizontalDivider( + thickness = Density.HAIRLINE, + color = palette.separatorLine, + ) + } + } + } + } +} + +/** Enough tint to show the pointer is over a title, not enough to read as a selection. */ +private const val HOVER_ALPHA = 0.35f + +private val MENU_TITLE_VERTICAL_PADDING = androidx.compose.ui.unit.Dp(4f) diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuModel.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuModel.kt new file mode 100644 index 00000000..eb1a5cd6 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuModel.kt @@ -0,0 +1,136 @@ +package kst4contest.view.compose + +import kst4contest.view.i18n.Strings +/** + * One line of a menu. + * + * Toolkit-free on purpose: the bar is drawn two different ways — Compose's `MenuBar`, + * which is a `javax.swing.JMenuBar` under the covers and only used on macOS, and the + * in-window Compose row everywhere else. Declaring the menus twice is how one renderer + * quietly loses an item that the other gained, so they both read this instead. + */ +sealed interface MenuEntry { + + /** + * @param enabled whether it can be pressed; a menu item that merely looks usable is + * worse than a disabled one, because the operator presses it mid-contest and + * either nothing happens or the wrong thing does + */ + data class Item( + val label: String, + val enabled: Boolean, + val onClick: () -> Unit, + ) : MenuEntry + + data object Separator : MenuEntry +} + +/** One menu of the bar: its title and what drops down from it. */ +data class MenuSpec(val title: String, val entries: List) + +/** + * The whole bar, as data. + * + * A plain function of the state rather than a composable, which is what finally makes the + * structure, the dynamic labels and the enabled states testable: while this lived inside + * Compose's `MenuBar` it took a running window to look at, and none of it was covered. + * + * @param settingsWindowOpen asked for at build time, not held in [MainMenuState]: a Compose + * window can be closed from its own frame without telling the menu + * @param monitorWindowOpen the same for the cluster / stranger-QSO window + */ +fun mainMenuModel( + state: MainMenuState, + actions: MainMenuActions, + settingsWindowOpen: Boolean, + monitorWindowOpen: Boolean, + /* + * Passed in rather than read from the composition, because this model is deliberately not + * a composable -- both renderers build from it and the two menu tests assert over it + * without a composition in sight. + */ + strings: Strings, +): List = listOf( + MenuSpec( + strings.menuFile, + listOf( + MenuEntry.Item(state.connectLabel, state.canConnect, actions::connect), + MenuEntry.Item(strings.menuDisconnect, state.canDisconnect, actions::disconnect), + MenuEntry.Item( + strings.menuSwitchOperatorProfile, + state.canSwitchProfile, + actions::switchOperatorProfile, + ), + MenuEntry.Item(strings.menuExitAndDisconnect, state.canExit, actions::exitApplication), + ), + ), + MenuSpec( + strings.menuOptions, + listOf( + MenuEntry.Item( + strings.menuSetQrgAsNameInChat, + state.canUseChatActions, + actions::setQrgAsNameInChat, + ), + /* + * This label is the only place the AFK state is visible anywhere in the + * application, so it follows the state rather than being flipped inside the + * click handler as JavaFX did. + */ + MenuEntry.Item( + state.awayMenuLabel(strings), + state.canUseChatActions, + actions::toggleAwayState, + ), + MenuEntry.Item( + if (settingsWindowOpen) strings.menuHideOptions else strings.menuShowOptions, + enabled = true, + actions::toggleSettingsWindow, + ), + ), + ), + MenuSpec( + strings.menuWindows, + listOf( + MenuEntry.Item( + if (monitorWindowOpen) strings.menuHideMonitor else strings.menuShowMonitor, + enabled = true, + actions::toggleMonitorWindow, + ), + MenuEntry.Item( + if (settingsWindowOpen) strings.menuHideOptions else strings.menuShowOptions, + enabled = true, + actions::toggleSettingsWindow, + ), + MenuEntry.Separator, + MenuEntry.Item(strings.menuToggleStationMap, enabled = true, actions::toggleStationMap), + MenuEntry.Separator, + MenuEntry.Item(strings.menuUseDarkDesign, enabled = true, actions::useDarkDesign), + MenuEntry.Item(strings.menuUseDefaultDesign, enabled = true, actions::useDefaultDesign), + ), + ), + MenuSpec( + strings.menuInfo, + listOf( + MenuEntry.Item( + strings.menuDonatePayPal, + enabled = true, + actions::openDonationPage, + ), + MenuEntry.Item( + strings.menuDonateOv3t, + enabled = true, + actions::openOv3tDonationPage, + ), + MenuEntry.Item(strings.menuHomepage, enabled = true, actions::openHomepage), + MenuEntry.Item(strings.menuNewsgroup, enabled = true, actions::openNewsgroup), + MenuEntry.Item( + strings.menuContactAuthor, + enabled = true, + actions::contactAuthor, + ), + MenuEntry.Separator, + MenuEntry.Item(strings.menuAbout, enabled = true, actions::showAbout), + ), + ), +) diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuRowState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuRowState.kt new file mode 100644 index 00000000..55152178 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuRowState.kt @@ -0,0 +1,48 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue + +/** + * Which menu of the in-window menu row is currently down. + * + * Compose state, because the row redraws when it changes. One menu at a time: two dropped + * at once is a thing no menu bar does. + * + * [anyOpen] is the part that is not cosmetic. `MainWindow` hangs `WindowShortcuts.handle` + * on the window's `onPreviewKeyEvent`, and a preview runs *before* its children — so + * without asking this first, pressing Escape to dismiss a menu would also clear the + * operator's half-typed message. + */ +class MainMenuRowState { + + /** The title of the open menu, or null when none is. */ + var openMenu: String? by mutableStateOf(null) + private set + + /** Whether a menu is down, and the window keys should therefore stay out of the way. */ + val anyOpen: Boolean + get() = openMenu != null + + /** Opens the named menu, or closes it when it is the one already open. */ + fun toggle(title: String) { + openMenu = if (openMenu == title) null else title + } + + /** Closes whatever is open. Idempotent; a dismissal from outside lands here too. */ + fun close() { + openMenu = null + } + + /** + * Runs a picked item's action and closes the menu it came from. + * + * Closing first would be wrong in the one case that matters: the quit item puts up a + * modal dialog, and the row must not still be drawing a dropdown underneath it. + */ + fun pick(action: () -> Unit) { + openMenu = null + action() + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuState.kt new file mode 100644 index 00000000..8b883572 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainMenuState.kt @@ -0,0 +1,71 @@ +package kst4contest.view.compose + +import kst4contest.view.i18n.Strings +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import kst4contest.controller.On4KstConnectionState + +/** + * Which menu items can be used. + * + * Compose state, not plain properties, and deliberately so: a menu item that merely + * looks usable is a worse place for a stale value than a form field. The operator + * presses it in the middle of a contest and nothing happens, or the wrong thing does. + * The JavaFX window drove the same flags from onConnectionStateChanged. + */ +class MainMenuState { + + /** Before the first callback there is no session, which reads as disconnected. */ + var connectionState: On4KstConnectionState by mutableStateOf(On4KstConnectionState.DISCONNECTED) + + private val attemptRunning: Boolean + get() = connectionState.isConnectionAttemptActive + + /** + * The Connect item's label, which names the chat the station will land in — and both when + * the second one is on, so the operator sees before pressing it what they are logging + * into. JavaFX built the same string in initMenuBar. + */ + var connectLabel: String by mutableStateOf("Connect") + + val canConnect: Boolean + get() = !attemptRunning + + /** Also while an attempt is still running: it can be given up. */ + val canDisconnect: Boolean + get() = attemptRunning + + /** + * Sending to the chat — the away state, the QRG as name — needs a session that is + * really online. Logging in is not being in the chat, and a command sent then goes + * nowhere. + */ + val canUseChatActions: Boolean + get() = connectionState.isOnline + + /** + * Whether the operator is marked away in the chat. + * + * Compose state because the away item's own label is the ONLY place this is visible — + * there is no separate indicator anywhere. JavaFX flipped the label inside the click + * handler, which left it wrong whenever the state changed from elsewhere. + */ + var awayFromChat: Boolean by mutableStateOf(false) + + /** + * What the away item says. It names the next action rather than the current state, + * which is what the JavaFX wording did. + * + * Takes the texts as a parameter: this is a plain state holder, not a composable, so the + * caller reads the composition local and hands them over. + */ + fun awayMenuLabel(strings: Strings): String = + if (awayFromChat) strings.menuShowMeAsActive else strings.menuShowMeAsAway + + /** Never blocked: switching profiles tears the session down on its own. */ + val canSwitchProfile: Boolean = true + + /** Never blocked: an operator must always be able to leave. */ + val canExit: Boolean = true +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindow.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindow.kt new file mode 100644 index 00000000..6e8566f9 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindow.kt @@ -0,0 +1,285 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Surface +import androidx.compose.runtime.Composable +import androidx.compose.runtime.remember +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.key.onPreviewKeyEvent +import androidx.compose.ui.window.FrameWindowScope +import kst4contest.model.Band +import kst4contest.model.ChatMember +import kst4contest.model.ChatMessage +import kst4contest.utils.PlatformUtils +import java.util.function.Consumer + +/** + * The main window, assembled. + * + * The JavaFX original built this in 2164 lines inside start(). What is left here is the + * arrangement — every part was built and tested on its own in 5a, 5b and tasks 10 to 13d. + * That is the point of the split: this file says how the window is put together and + * nothing else, so a change to the arrangement cannot break a table. + * + * The window is a pure function of [MainWindowState]. That is what makes the profile + * switch a state swap instead of a restart. + */ +@Composable +fun FrameWindowScope.MainWindow( + state: MainWindowState, + actions: MainMenuActions, + skedBands: List, + openInBrowser: Consumer, + onShowOnMap: () -> Unit, + onShowPathInAirScout: () -> Unit, + onStationSelected: (ChatMember) -> Unit, + /** + * A clicked private message prepares a reply to it. JavaFX resolved the receiver out of + * the message text when the sender was the local station, so replying to one's own + * message aims at whoever it was addressed to rather than at oneself. + */ + onDirectedMessageClicked: (ChatMessage) -> Unit, + /** Whether a message came from this station; decides its row colour. */ + isOwnMessage: (ChatMessage) -> Boolean, + /** How old a message is, for the fading highlight. */ + messageAgeSeconds: (ChatMessage) -> Long, + onFiltersChanged: () -> Unit, + onShowMorePriorities: () -> Unit, + onCandidateClicked: (TimelineCandidate) -> Unit, +) { + /* + * macOS gets the system menu bar at the top of the screen, which is where that platform + * expects it and which Swing draws natively. Everywhere else Compose's MenuBar meant an + * unthemed Metal menu above a themed window, so the bar is drawn in the window instead — + * see Kst4ContestMenuRow. + */ + if (PlatformUtils.isMacOs()) { + Kst4ContestMenuBar( + state = state.menu, + actions = actions, + settingsWindowOpen = state.surroundings.settingsWindowOpen, + monitorWindowOpen = state.surroundings.monitorWindowOpen, + connectionState = state.surroundings.connectionState, + connectionDetail = state.surroundings.connectionDetail, + ) + } + + val menuRow = remember { MainMenuRowState() } + + /* + * The window-wide keys, where JavaFX had them: on the scene. Enter sends and Escape + * clears wherever the focus is, and Ctrl+1..Ctrl+0 inserts a snippet — on the field alone + * they would be gone the moment the operator clicked a station or a message row, which is + * most of the time. + */ + Surface( + Modifier + .fillMaxSize() + .onPreviewKeyEvent { event -> + /* + * Not while a menu is down. This is a PREVIEW handler, so it runs before the + * dropdown sees the key — without the guard, Escape to dismiss a menu would + * first clear the operator's half-typed message. + */ + if (menuRow.anyOpen) { + false + } else { + WindowShortcuts.handle( + event = event, + send = state.chatInput::send, + clear = state.chatInput::clear, + insertSnippet = { index -> + state.chatInput.insertSnippet(state.snippets.entries, index) + }, + ) + } + }, + ) { + Column(Modifier.fillMaxSize()) { + if (!PlatformUtils.isMacOs()) { + Kst4ContestMenuRow( + state = state.menu, + actions = actions, + settingsWindowOpen = state.surroundings.settingsWindowOpen, + monitorWindowOpen = state.surroundings.monitorWindowOpen, + rowState = menuRow, + ) + + HorizontalDivider(thickness = Density.HAIRLINE) + } + + StatusBar( + connectionState = state.surroundings.connectionState, + connectionDetail = state.surroundings.connectionDetail, + skedNotice = state.skedNotice, + bandUpgradeNotice = state.bandUpgradeNotice, + threadButtons = state.threadButtons, + showConnectionBadge = !PlatformUtils.isMacOs(), + modifier = Modifier.fillMaxWidth(), + ) + + HorizontalDivider(thickness = Density.HAIRLINE) + + SplitterPane( + state = state.outerSplitter, + orientation = SplitterOrientation.HORIZONTAL, + modifier = Modifier.fillMaxSize(), + panes = listOf( + { + MessageColumn( + state = state, + onCandidateClicked = onCandidateClicked, + onDirectedMessageClicked = onDirectedMessageClicked, + isOwnMessage = isOwnMessage, + messageAgeSeconds = messageAgeSeconds, + ) + }, + { + StationColumn( + state = state, + skedBands = skedBands, + openInBrowser = openInBrowser, + onShowOnMap = onShowOnMap, + onShowPathInAirScout = onShowPathInAirScout, + onStationSelected = onStationSelected, + onFiltersChanged = onFiltersChanged, + onShowMorePriorities = onShowMorePriorities, + ) + }, + ), + ) + } + } +} + +/** + * The left column: what was said, and what this station says back. + * + * Five panes in the order the operator has looked at them for years — directed messages + * at the top, then the shortcut buttons, the timeline, the send line, and the public + * message tabs at the bottom. + */ +@Composable +private fun MessageColumn( + state: MainWindowState, + onCandidateClicked: (TimelineCandidate) -> Unit, + onDirectedMessageClicked: (ChatMessage) -> Unit, + isOwnMessage: (ChatMessage) -> Boolean, + messageAgeSeconds: (ChatMessage) -> Long, +) { + SplitterPane( + state = state.messageSplitter, + orientation = SplitterOrientation.VERTICAL, + modifier = Modifier.fillMaxSize(), + panes = listOf( + { + SnippetContextMenu(state.snippets.entries, state.chatInput) { + DataTableView( + state = state.directedMessages, + modifier = Modifier.fillMaxSize(), + rowStyle = { message -> + DirectedMessageRowStyle.accentFor( + ownMessage = isOwnMessage(message), + ageSeconds = messageAgeSeconds(message), + ) + }, + onRowClick = onDirectedMessageClicked, + ) + } + }, + { ShortcutButtonRow(state.shortcuts.entries, state.chatInput) }, + { + TimelineView( + state = state.timeline, + onCandidateClicked = onCandidateClicked, + modifier = Modifier.fillMaxWidth(), + ) + }, + { + ChatInputRow( + state = state.chatInput, + prefs = state.prefs, + ownQrgMain = state.ownQrgMain, + ownQrgSecond = state.ownQrgSecond, + antennaQtf = state.antennaQtf, + modifier = Modifier.fillMaxWidth(), + ) + }, + { + SnippetContextMenu(state.snippets.entries, state.chatInput) { + MessageTabs( + publicMessages = state.publicMessages, + clusterMessages = state.clusterMessages, + qsoOfTheOther = state.qsoOfTheOther, + modifier = Modifier.fillMaxSize(), + ) + } + }, + ), + ) +} + +/** + * The right column: who is on, who to work next, and everything about the one selected. + */ +@Composable +private fun StationColumn( + state: MainWindowState, + skedBands: List, + openInBrowser: Consumer, + onShowOnMap: () -> Unit, + onShowPathInAirScout: () -> Unit, + onStationSelected: (ChatMember) -> Unit, + onFiltersChanged: () -> Unit, + onShowMorePriorities: () -> Unit, +) { + SplitterPane( + state = state.rightSplitter, + orientation = SplitterOrientation.VERTICAL, + modifier = Modifier.fillMaxSize(), + panes = listOf( + { + Column(Modifier.fillMaxSize()) { + StationFilterBar( + filters = state.stationFilter, + activeBands = state.activeBands, + onChanged = { + onFiltersChanged() + }, + modifier = Modifier.fillMaxWidth(), + ) + HorizontalDivider(thickness = Density.HAIRLINE) + SnippetContextMenu(state.snippets.entries, state.chatInput) { + DataTableView( + state = state.stations, + modifier = Modifier.fillMaxSize(), + onRowClick = onStationSelected, + ) + } + } + }, + { + TopPriorityBar( + state = state.topPriority, + onShowMore = onShowMorePriorities, + modifier = Modifier.fillMaxWidth(), + ) + }, + { + SelectedStationPanel( + state = state.selectedStation, + messages = state.selectedStationMessages, + skedBands = skedBands, + activeBands = state.activeBands, + openInBrowser = openInBrowser, + onShowOnMap = onShowOnMap, + onShowPathInAirScout = onShowPathInAirScout, + modifier = Modifier.fillMaxSize(), + ) + }, + ), + ) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindowFrame.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindowFrame.kt new file mode 100644 index 00000000..7de35bf9 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindowFrame.kt @@ -0,0 +1,93 @@ +package kst4contest.view.compose + +import kst4contest.controller.On4KstConnectionState + +/** How big the main window opens. */ +data class MainWindowSize(val heightDp: Double, val widthDp: Double) + +/** + * The frame around the main window: the size it opens at and what its title says. + * + * Both are arithmetic and string building rather than drawing, which is why they live + * apart from the window itself and are covered by tests instead of by looking. + */ +object MainWindowFrame { + + private const val FALLBACK_HEIGHT = 768.0 + private const val FALLBACK_WIDTH = 1234.0 + + /** + * Room left for the native window decoration and the screen edge. The JavaFX scene + * size did not include the decoration, and Compose's window size does not include + * everything a tiling compositor puts around it either. + */ + private const val SCREEN_MARGIN = 40.0 + + /** + * The remembered size, never larger than the screen it is opening on. + * + * The clamp is the point: a window remembered from a larger monitor opens with its + * buttons past the edge and no way to reach them. Each dimension falls back on its + * own, because half a stored size is still half a usable one. + */ + fun startupSize(stored: DoubleArray?, screenHeight: Double, screenWidth: Double): MainWindowSize { + var height = FALLBACK_HEIGHT + var width = FALLBACK_WIDTH + + if (stored != null && stored.size >= 2) { + if (stored[0].isFinite() && stored[0] > 0) height = stored[0] + if (stored[1].isFinite() && stored[1] > 0) width = stored[1] + } + + val availableHeight = (screenHeight - SCREEN_MARGIN).coerceAtLeast(1.0) + val availableWidth = (screenWidth - SCREEN_MARGIN).coerceAtLeast(1.0) + + return MainWindowSize( + heightDp = minOf(height, availableHeight), + widthDp = minOf(width, availableWidth), + ) + } + + /** + * The window title: what the chat is doing, and which profile, when it is not the + * only one. Two profiles open side by side have to be tellable apart from the + * taskbar. + */ + fun title(chatState: String, profileName: String?): String = + if (profileName.isNullOrBlank()) chatState else "$chatState - $profileName" + + /** + * What the title says while the chat is not usable. + * + * The wording separates a scheduled reconnect from a dead session, which is the + * difference between waiting and doing something about it. + */ + /** + * What the title's first half says. + * + * The live connection detail while the chat is usable -- which is the whole status line, + * exactly what the JavaFX title carried -- and a wording about the attempt otherwise. A + * blank detail falls through to the offline wording rather than leaving the title empty. + * + * @param state the connection state, null before the first push + * @param detail the status line the controller pushes + * @return the chat half of the title + */ + fun chatState(state: On4KstConnectionState?, detail: String?): String = + if (state == On4KstConnectionState.ONLINE && !detail.isNullOrBlank()) { + detail + } else { + offlineChatState(state) + } + + fun offlineChatState(state: On4KstConnectionState?): String = + when (state ?: On4KstConnectionState.DISCONNECTED) { + On4KstConnectionState.RECONNECT_WAIT -> kst4contest.view.i18n.CurrentStrings.get().titleConnectionLost + On4KstConnectionState.CONNECTING -> kst4contest.view.i18n.CurrentStrings.get().titleConnecting + On4KstConnectionState.WAITING_FOR_LOGIN_PROMPT, + On4KstConnectionState.AUTHENTICATING -> kst4contest.view.i18n.CurrentStrings.get().titleAuthenticating + On4KstConnectionState.SYNCING_MAIN_CHAT, + On4KstConnectionState.SYNCING_SECOND_CHAT -> kst4contest.view.i18n.CurrentStrings.get().titleSynchronizing + else -> kst4contest.view.i18n.CurrentStrings.get().titleDisconnected + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindowHost.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindowHost.kt new file mode 100644 index 00000000..c4fd6e9f --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindowHost.kt @@ -0,0 +1,153 @@ +package kst4contest.view.compose + +import kst4contest.model.Band +import kst4contest.model.ChatMember +import kst4contest.model.ChatMessage +import java.util.function.Consumer +import androidx.compose.runtime.getValue +import androidx.compose.runtime.setValue + +/** + * Opens the Compose main window. + * + * Deliberately a sibling of the JavaFX window rather than its replacement for now: the two + * are meant to run side by side so the operator can compare them against a live session, + * which is the only way the differences of the last three Etappen came to light. + */ +object MainWindowHost { + + private val host = ComposeWindowHost("main-window") + + @JvmStatic + val isOpen: Boolean + get() = host.isOpen + + @JvmStatic + fun applyDarkMode(darkMode: Boolean) = host.applyDarkMode(darkMode) + + @JvmStatic + fun close() = host.close() + + /** + * @param state everything the window draws; replacing it is what a profile switch will be + * @param profileName the profile part of the title; the chat part is read from the state + */ + private var currentState by androidx.compose.runtime.mutableStateOf(null) + private var currentActions by androidx.compose.runtime.mutableStateOf(null) + private var currentSkedBands by androidx.compose.runtime.mutableStateOf<(() -> List)?>(null) + private var currentOpenInBrowser by androidx.compose.runtime.mutableStateOf?>(null) + private var currentOnShowOnMap by androidx.compose.runtime.mutableStateOf<(() -> Unit)?>(null) + private var currentOnShowPathInAirScout by androidx.compose.runtime.mutableStateOf<(() -> Unit)?>(null) + private var currentOnStationSelected by androidx.compose.runtime.mutableStateOf<((ChatMember) -> Unit)?>(null) + private var currentOnDirectedMessageClicked by androidx.compose.runtime.mutableStateOf<((ChatMessage) -> Unit)?>(null) + private var currentIsOwnMessage by androidx.compose.runtime.mutableStateOf<((ChatMessage) -> Boolean)?>(null) + private var currentMessageAgeSeconds by androidx.compose.runtime.mutableStateOf<((ChatMessage) -> Long)?>(null) + private var currentOnFiltersChanged by androidx.compose.runtime.mutableStateOf<(() -> Unit)?>(null) + private var currentOnShowMorePriorities by androidx.compose.runtime.mutableStateOf<(() -> Unit)?>(null) + private var currentOnCandidateClicked by androidx.compose.runtime.mutableStateOf<((TimelineCandidate) -> Unit)?>(null) + + @JvmStatic + fun show( + state: MainWindowState, + actions: MainMenuActions, + /** + * The profile name for the title, or null for the only profile. The rest of the + * title is what the chat is doing, and that is read from the state during + * composition -- as the JavaFX window did, where the title carried the whole + * connection line. + */ + profileName: String?, + darkMode: Boolean, + baseFontSizeSp: Float, + /** + * The palette of the active profile, handed to the theme. Null draws the shipped + * palette. + */ + paletteStore: PaletteStore? = null, + /** + * The interface language of the active profile, handed to the window. Null draws the + * base language. + */ + languageStore: kst4contest.view.i18n.LanguageStore? = null, + widthDp: Float, + heightDp: Float, + onResized: (Float, Float) -> Unit, + /** + * Runs the application's quit flow. This is the main window: its X — and a tiling + * window manager's close, the same request — has to ask whether to disconnect and + * then end the process, the way the File menu's Exit does. Closing it must not + * leave the client running with the chat connected and nothing to see it in. + */ + onCloseRequest: () -> Unit, + skedBands: () -> List, + openInBrowser: Consumer, + onShowOnMap: () -> Unit, + onShowPathInAirScout: () -> Unit, + onStationSelected: (ChatMember) -> Unit, + onDirectedMessageClicked: (ChatMessage) -> Unit, + isOwnMessage: (ChatMessage) -> Boolean, + messageAgeSeconds: (ChatMessage) -> Long, + onFiltersChanged: () -> Unit, + onShowMorePriorities: () -> Unit, + onCandidateClicked: (TimelineCandidate) -> Unit, + ) { + currentState = state + currentActions = actions + currentSkedBands = skedBands + currentOpenInBrowser = openInBrowser + currentOnShowOnMap = onShowOnMap + currentOnShowPathInAirScout = onShowPathInAirScout + currentOnStationSelected = onStationSelected + currentOnDirectedMessageClicked = onDirectedMessageClicked + currentIsOwnMessage = isOwnMessage + currentMessageAgeSeconds = messageAgeSeconds + currentOnFiltersChanged = onFiltersChanged + currentOnShowMorePriorities = onShowMorePriorities + currentOnCandidateClicked = onCandidateClicked + + host.show( + title = { + /* + * Read inside the composition, so the title follows the connection the way + * the JavaFX one did: "Connected to: 2: 144/432 MHz as DN5PW in JO50JP + * (73 users online, 73 shown), 29 messages total." A captured string would + * say "disconnected" for the life of the session. + */ + val surroundings = currentState?.surroundings + MainWindowFrame.title( + chatState = MainWindowFrame.chatState( + surroundings?.connectionState, + surroundings?.connectionDetail, + ), + profileName = profileName, + ) + }, + darkMode = darkMode, + baseFontSizeSp = baseFontSizeSp, + paletteStore = paletteStore, + languageStore = languageStore, + widthDp = widthDp, + heightDp = heightDp, + onResized = onResized, + onCloseRequest = onCloseRequest, + ) { _ -> + val s = currentState ?: return@show + val a = currentActions ?: return@show + MainWindow( + state = s, + actions = a, + skedBands = currentSkedBands?.invoke() ?: emptyList(), + openInBrowser = currentOpenInBrowser ?: Consumer { _ -> }, + onShowOnMap = currentOnShowOnMap ?: {}, + onShowPathInAirScout = currentOnShowPathInAirScout ?: {}, + onStationSelected = currentOnStationSelected ?: {}, + onDirectedMessageClicked = currentOnDirectedMessageClicked ?: {}, + isOwnMessage = currentIsOwnMessage ?: { false }, + messageAgeSeconds = currentMessageAgeSeconds ?: { 0L }, + onFiltersChanged = currentOnFiltersChanged ?: {}, + onShowMorePriorities = currentOnShowMorePriorities ?: {}, + onCandidateClicked = currentOnCandidateClicked ?: {}, + ) + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindowState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindowState.kt new file mode 100644 index 00000000..a3371881 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/MainWindowState.kt @@ -0,0 +1,164 @@ +package kst4contest.view.compose + +import kst4contest.model.ChatMessage +import kst4contest.model.ClusterMessage +import kst4contest.model.ChatMember +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import kst4contest.controller.On4KstConnectionState +import kst4contest.model.ChatPreferences +import kst4contest.observe.SimpleRoster + +/** + * Everything the main window draws, in one object. + * + * This is the shape the profile switch needs. Today a switch tears the runtime down and + * builds a new Kst4ContestApplication, because the controls are inline-created instance + * fields and there is no other way to be rid of them. Once the window is a pure function + * of this object, switching profiles is replacing it — the reason the JavaFX version had + * to restart itself is gone. + * + * Nothing here holds a window or a thread; those belong to the runtime that builds this. It + * does hold three preference listeners, which is why [release] exists and has to be called + * when the state is dropped. + */ +class MainWindowState( + val activeBands: Set, + val prefs: ChatPreferences, + + /** The station list with its filters: the operator's main working surface. */ + val stations: DataTableState, + val stationFilter: StationFilterState, + + /** Messages addressed to this station, in their own pane above the send line. */ + val directedMessages: DataTableState, + + /** The three tabs at the bottom. */ + val publicMessages: DataTableState, + val clusterMessages: DataTableState, + val qsoOfTheOther: DataTableState, + + val selectedStationMessages: DataTableState, + val selectedStation: SelectedStationState, + val topPriority: TopPriorityState, + val timeline: TimelineState, + val chatInput: ChatInputState, + val menu: MainMenuState, + + /** The link and the other windows, pushed in because none of it is Compose state at source. */ + val surroundings: MainWindowSurroundings, + + /** The status indicators along the top. */ + val skedNotice: BlinkingNotice, + val bandUpgradeNotice: BlinkingNotice, + val threadButtons: ThreadStatusButtons, + + /** The three splitters, whose positions the operator has arranged and stored. */ + val outerSplitter: SplitterState, + val messageSplitter: SplitterState, + val rightSplitter: SplitterState, +) { + + /** The shortcut buttons above the send line. */ + /** + * The one path that selects a station for the whole application (panel, table, score + * service, send line). Set by the host after construction; other windows, such as the + * map, go through it instead of touching [selectedStation] alone. Null clears. + */ + var stationSelector: ((ChatMember?) -> Unit)? = null + + val shortcuts = RosterMirror(prefs.getLst_txtShortCutBtnList()) + + /** The snippets behind Ctrl+1..Ctrl+0 and the right-click menus. */ + val snippets = RosterMirror(prefs.getLst_txtSnipList()) + + /** + * The three small fields beside the send controls. Mirrored rather than read straight + * from the preferences, because all three move without the operator touching them: the + * rotator writes the heading, and the frequency follower writes the own QRG. + */ + val ownQrgMain = ObservedValue(prefs.getMYQRGFirstCat()) + val ownQrgSecond = ObservedValue(prefs.getMYQRGSecondCat()) + val antennaQtf = ObservedValue(prefs.getActualQTF()) + + /** + * Stops following the preferences. Called when this state is dropped — a profile switch + * builds a new window over the same preferences, and a leaked follower keeps the old + * one alive and writing. + */ + fun release() { + ownQrgMain.release() + ownQrgSecond.release() + antennaQtf.release() + } + + companion object { + + /** The five panes of the message column, in the order they are stacked. */ + const val MESSAGE_PANE_COUNT = 5 + + /** Station list, top priorities, selected station. */ + const val RIGHT_PANE_COUNT = 3 + } +} + + +/** + * A roster from the preferences, mirrored into Compose state. + * + * SimpleRoster notifies its own listeners, none of which Compose can see, so a view drawn + * straight from one would render once and then go stale — the failure mode that produced + * most of this migration's invisible defects. The mirror is what the settings window's + * refresh hooks have been calling into thin air since Etappe 3b. + */ +class RosterMirror(private val roster: SimpleRoster?) { + + private val live = mutableStateListOf().apply { + addAll(roster?.snapshot().orEmpty()) + } + + /** What a view reads; a read here is a subscription. */ + val entries: List get() = live + + /** Catches the mirror up with the roster. Called after every committed edit. */ + fun refresh() { + val current = roster?.snapshot().orEmpty() + if (current == live.toList()) return + live.clear() + live.addAll(current) + } +} + + +/** + * What the window shows about its surroundings: the link, and which other windows are open. + * + * None of this is Compose state at its source — the connection state lives in the controller, + * the window flags in AtomicBooleans inside the hosts — so it is pushed in here instead of + * being read through a lambda at composition time. Read that way it would be drawn once: the + * badge frozen on whatever the link was when the window opened, and the menu's "hide options" + * saying the wrong thing for the rest of the session. + * + * @param menu kept in step with the connection state, because the badge and the menu are two + * renderings of one fact and an operator comparing them must not have to choose + */ +class MainWindowSurroundings(private val menu: MainMenuState = MainMenuState()) { + + private val liveConnectionState = + mutableStateOf(On4KstConnectionState.DISCONNECTED) + + var connectionState: On4KstConnectionState + get() = liveConnectionState.value + set(value) { + liveConnectionState.value = value + menu.connectionState = value + } + + var connectionDetail: String by mutableStateOf(kst4contest.view.i18n.CurrentStrings.get().statusNoConnection) + + var settingsWindowOpen: Boolean by mutableStateOf(false) + + var monitorWindowOpen: Boolean by mutableStateOf(false) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/MessageFormats.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/MessageFormats.kt new file mode 100644 index 00000000..3cd67b6b --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/MessageFormats.kt @@ -0,0 +1,52 @@ +package kst4contest.view.compose + +import kst4contest.controller.Utils4KST + +/** + * How the message tables show what arrives off the wire. + * + * Shared rather than repeated: the same value appears in the monitor window and in the + * tabs below the station list, and two tables of the same data disagreeing about how + * they show it is worse than either format on its own. + */ +internal object MessageFormats { + + /** + * The epoch seconds off the wire as a clock time, the way the JavaFX cells showed + * them. An unreadable value is shown as it came: an operator seeing the raw text + * learns more than one seeing an empty cell. + */ + fun clockTime(epochFromServer: String?): String { + val raw = epochFromServer?.trim().orEmpty() + + if (raw.isEmpty()) { + return "" + } + + return runCatching { Utils4KST().time_convertEpochToReadable(raw) }.getOrDefault(raw) + } + + /** + * Three decimal places, as `formatQrgForUi` pads them in the main window. The same + * column appears in both windows, and two tables of the same data must not + * disagree about how they show it. + */ + fun paddedQrg(raw: String): String { + val text = raw.trim().replace(',', '.') + + if (text.isEmpty() || text.toDoubleOrNull() == null) { + return text + } + + val dot = text.indexOf('.') + + if (dot < 0) { + return text + ".000" + } + + val decimals = text.length - dot - 1 + + return if (decimals >= 3) text else text + "0".repeat(3 - decimals) + } + +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/MessageTabs.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/MessageTabs.kt new file mode 100644 index 00000000..49f65ecf --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/MessageTabs.kt @@ -0,0 +1,96 @@ +package kst4contest.view.compose + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import kst4contest.model.ChatMessage +import kst4contest.model.ClusterMessage + +/** + * The three tabs below the station list. + * + * Two of them are the monitor window's tables under their own layout ids — the same + * columns, separate stored widths, which is what PROJECT_CONTEXT requires. Only the + * public message tab is its own. + */ +@Composable +fun MessageTabs( + publicMessages: DataTableState, + clusterMessages: DataTableState, + qsoOfTheOther: DataTableState, + modifier: Modifier = Modifier, +) { + var selected by remember { mutableStateOf(0) } + + val strings = LocalStrings.current + val titles = listOf( + strings.messagesPublic, + strings.messagesDxCluster, + strings.messagesQsoOfTheOther, + ) + + Column(modifier = modifier.fillMaxSize()) { + Row(modifier = Modifier.fillMaxWidth().background(MaterialTheme.colorScheme.surfaceVariant)) { + titles.forEachIndexed { index, title -> + val isSelected = index == selected + val underline = MaterialTheme.colorScheme.primary + + Box( + modifier = Modifier + .heightIn(min = Density.TAB_MIN_HEIGHT) + .background( + if (isSelected) MaterialTheme.colorScheme.secondaryContainer + else Color.Transparent + ) + .clickable { selected = index } + .drawBehind { + if (isSelected) { + val thickness = 2.dp.toPx() + drawRect( + color = underline, + topLeft = Offset(0f, size.height - thickness), + size = Size(size.width, thickness), + ) + } + } + .padding(horizontal = Density.TAB_HORIZONTAL_PADDING, vertical = 5.dp), + contentAlignment = Alignment.Center, + ) { + Text(title, style = MaterialTheme.typography.bodyMedium, maxLines = 1) + } + } + } + + HorizontalDivider(thickness = Density.HAIRLINE) + + Box(modifier = Modifier.fillMaxSize()) { + when (selected) { + 0 -> DataTableView(publicMessages, modifier = Modifier.fillMaxSize()) + 1 -> DataTableView(clusterMessages, modifier = Modifier.fillMaxSize()) + else -> DataTableView(qsoOfTheOther, modifier = Modifier.fillMaxSize()) + } + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/MonitorColumns.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/MonitorColumns.kt new file mode 100644 index 00000000..db53e363 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/MonitorColumns.kt @@ -0,0 +1,72 @@ +package kst4contest.view.compose + +import kst4contest.controller.Utils4KST +import kst4contest.model.ChatMember +import kst4contest.model.ChatMessage +import kst4contest.model.ClusterMessage + +/** + * The columns of the two monitor tables. + * + * The ids are not free to choose: they are part of the operator's stored layout, so + * renaming one loses their column widths without saying so. They are kept exactly as + * `TableLayoutManager.column(...)` registered them. + * + * Every value survives a half-filled message. These tables are fed straight from the + * wire, a sender or receiver can be missing, and a NullPointerException in a live + * table during a contest is the worst possible moment for one. + */ +object MonitorColumns { + + fun dxCluster(): List> = listOf( + DataColumn(id = "time", title = { kst4contest.view.i18n.CurrentStrings.get().columnTime }, value = { MessageFormats.clockTime(it.timeGenerated) }, weight = 0.7f), + DataColumn(id = "call-tx", title = "Call tx", value = { callSignOf(it.sender) }), + DataColumn(id = "locator-tx", title = "LOC tx", value = { qraOf(it.sender) }, weight = 0.7f), + DataColumn(id = "call-rx", title = "Call rx", value = { callSignOf(it.receiver) }), + DataColumn(id = "locator-rx", title = "LOC rx", value = { qraOf(it.receiver) }, weight = 0.7f), + DataColumn(id = "qrg", title = "QRG", value = { MessageFormats.paddedQrg(frequencyOf(it.receiver)) }, weight = 0.8f), + DataColumn(id = "message", title = { kst4contest.view.i18n.CurrentStrings.get().columnMessage }, value = { it.messageInhibited.orEmpty() }, weight = 2.5f), + /* "X" and not "true": the JavaFX cell printed a cross. */ + DataColumn(id = "worked", title = "wkd", value = { if (it.isReceiverWkd) "X" else "" }, weight = 0.4f), + ) + + /** + * Nine columns, not ten. The JavaFX method built a "Name" column and never added + * it to the table; porting it would put a column on screen that release 1.49 + * never showed. + */ + fun qsoOfTheOther(): List> = listOf( + DataColumn(id = "time", title = { kst4contest.view.i18n.CurrentStrings.get().columnTime }, value = { MessageFormats.clockTime(it.messageGeneratedTime) }, weight = 0.7f), + DataColumn(id = "call-tx", title = "Call TX", value = { callSignOf(it.sender) }), + DataColumn(id = "last-qrg-tx", title = { kst4contest.view.i18n.CurrentStrings.get().columnLastQrgTx }, value = { frequencyOf(it.sender) }, weight = 0.8f), + DataColumn(id = "worked-tx", title = "wkd TX?", value = { workedMark(it.sender) }, weight = 0.4f), + DataColumn(id = "call-rx", title = "Call RX", value = { callSignOf(it.receiver) }), + DataColumn(id = "last-qrg-rx", title = { kst4contest.view.i18n.CurrentStrings.get().columnLastQrgRx }, value = { frequencyOf(it.receiver) }, weight = 0.8f), + DataColumn(id = "worked-rx", title = "wkd RX?", value = { workedMark(it.receiver) }, weight = 0.4f), + DataColumn(id = "message", title = { kst4contest.view.i18n.CurrentStrings.get().columnMessage }, value = { it.messageText.orEmpty() }, weight = 2.5f), + /* + * From the sender, not from the message. Both carry a field of that name and + * they are set on different parsing paths, so they are not always the same + * value; the JavaFX cell read the sender's. + */ + DataColumn( + id = "category", + title = "Category", + value = { message -> + message.sender?.chatCategory + ?.let { it.getChatCategoryName(it.categoryNumber) } + .orEmpty() + }, + weight = 1.2f, + ), + ) + + internal fun callSignOf(member: ChatMember?): String = member?.callSign.orEmpty() + + internal fun qraOf(member: ChatMember?): String = member?.qra.orEmpty() + + internal fun frequencyOf(member: ChatMember?): String = member?.frequency?.get().orEmpty() + + private fun workedMark(member: ChatMember?): String = + if (member != null && member.isWorked) "X" else "" +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/MonitorWindow.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/MonitorWindow.kt new file mode 100644 index 00000000..a5aa51d1 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/MonitorWindow.kt @@ -0,0 +1,107 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import kst4contest.model.ChatMessage +import kst4contest.model.ClusterMessage + +/** + * The cluster and QSO monitor. + * + * Two live tables, one above the other. This is the first window in which the table + * carries data that changes while the operator watches, which is why the row identity + * rules in DataTableState matter here and not in the settings window: in Etappe 2 the + * visible defects all came from that coupling, not from the table itself. + */ +object MonitorWindow { + + private val host = ComposeWindowHost("monitor-window") + + @JvmStatic + val isOpen: Boolean + get() = host.isOpen + + @JvmStatic + fun applyDarkMode(darkMode: Boolean) = host.applyDarkMode(darkMode) + + @JvmStatic + fun close() = host.close() + + /** + * @param clusterTable fed from `getLst_clusterMemberList` + * @param qsoTable fed from `toOtherMessages` over the global chat message list + */ + @JvmStatic + fun show( + clusterTable: DataTableState, + qsoTable: DataTableState, + darkMode: Boolean, + baseFontSizeSp: Float, + /** + * The palette of the active profile, handed to the theme. Null draws the shipped + * palette. + */ + paletteStore: PaletteStore? = null, + /** + * The interface language of the active profile, handed to the window. Null draws the + * base language. + */ + languageStore: kst4contest.view.i18n.LanguageStore? = null, + widthDp: Float, + heightDp: Float, + onResized: (Float, Float) -> Unit, + ) { + host.show( + title = { "Cluster & QSO of the other" }, + darkMode = darkMode, + baseFontSizeSp = baseFontSizeSp, + paletteStore = paletteStore, + languageStore = languageStore, + widthDp = widthDp, + heightDp = heightDp, + onResized = onResized, + ) { _ -> + MonitorContent(clusterTable, qsoTable) + } + } +} + +@Composable +private fun MonitorContent( + clusterTable: DataTableState, + qsoTable: DataTableState, +) { + Surface(modifier = Modifier.fillMaxSize()) { + Column(modifier = Modifier.fillMaxSize().padding(4.dp)) { + Text("DX cluster", style = MaterialTheme.typography.titleSmall) + + /* + * Half each, fixed. The JavaFX window used a SplitPane whose divider the + * operator could drag, and that position was stored; reproducing the + * gesture belongs with the station list of Etappe 5, where a split pane is + * unavoidable. Until then an even split is honest rather than a broken + * handle. + */ + DataTableView(clusterTable, modifier = Modifier.weight(1f).fillMaxWidth()) + + HorizontalDivider(thickness = Density.HAIRLINE) + + Text( + "QSO of the other", + style = MaterialTheme.typography.titleSmall, + modifier = Modifier.padding(top = 4.dp), + ) + + DataTableView(qsoTable, modifier = Modifier.weight(1f).fillMaxWidth()) + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/ObservedValue.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/ObservedValue.kt new file mode 100644 index 00000000..8660d84b --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/ObservedValue.kt @@ -0,0 +1,37 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import kst4contest.observe.ObservableValue +import java.util.function.Consumer + +/** + * An [ObservableValue] from the domain layer, mirrored into Compose state. + * + * The domain's values notify their own listeners, none of which Compose can see, so a view + * drawn straight from one renders once and then silently goes stale. Three of them move on + * their own while the operator watches: the rotator writes the antenna heading, and the + * frequency follower writes the operator's own QRG. + * + * The JavaFX window did exactly this with attachQtfFollower() and attachOwnQrgFollower(), + * ending in a TextField; this one ends in Compose state. + * + * [release] must be called when the mirror is dropped. A profile switch builds a new window + * over the same preferences, and a leaked listener keeps the old one alive and writing. + */ +class ObservedValue(private val source: ObservableValue) { + + var value: T? by mutableStateOf(source.get()) + private set + + private val follower = Consumer { updated -> value = updated } + + init { + source.addListener(follower) + } + + fun release() { + source.removeListener(follower) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/OperatorProfilePickerWindow.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/OperatorProfilePickerWindow.kt new file mode 100644 index 00000000..90be29a2 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/OperatorProfilePickerWindow.kt @@ -0,0 +1,222 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.selection.selectable +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.compose.ui.awt.ComposeDialog +import kst4contest.model.OperatorProfile +import java.awt.Dialog +import java.awt.Dimension +import java.awt.EventQueue +import java.util.Optional +import java.util.concurrent.atomic.AtomicReference +import javax.swing.WindowConstants + +/** + * The text the JavaFX dialog showed below a profile name. Kept as a function so + * the wording and the rule behind it stay covered by a test: the root profile and + * a sharing profile both use the installation's shared worked database. + */ +internal fun workedDatabaseDescription(profile: OperatorProfile): String = + if (profile.isRootProfile || profile.isSharedWorkedDatabase) { + "shared station worked database" + } else { + "own worked database" + } + +/** + * Selection state of the operator profile picker, free of Compose so the rules + * are testable without a toolkit. + */ +class OperatorProfilePickerState( + val profiles: List, + preselectedProfileId: String?, +) { + var selected: OperatorProfile? = + profiles.firstOrNull { it.profileId == preselectedProfileId } ?: profiles.firstOrNull() + private set + + val canConfirm: Boolean + get() = selected != null + + fun select(profile: OperatorProfile) { + if (profiles.any { it.profileId == profile.profileId }) { + selected = profiles.first { it.profileId == profile.profileId } + } + } +} + +/** + * Asks the operator which profile to start with. + * + * Replaces the JavaFX dialog of the same name and keeps its contract: blocks + * until the operator decides, returns the chosen profile, or empty when they + * want to quit. Kst4ContestApplication uses this as a method reference, so the + * signature must not drift. + */ +object OperatorProfilePickerWindow { + + /** + * The font size the JavaFX dialog hardcoded. It runs before any profile is + * loaded, so there is no configured size to read; using a different one here + * would make the dialog look unlike the windows that follow it. + */ + private const val DIALOG_FONT_SIZE_SP = 12f + + private val DIALOG_SIZE = Dimension(380, 300) + + /** + * Opens the picker and blocks until the operator decides. + * + * A modal [ComposeDialog] and NOT the former dedicated thread plus `CountDownLatch`. + * That construction deadlocked once the UiDispatcher moved to the AWT event thread: + * `ComposeMenuActions.switchOperatorProfile` delivers the File menu's profile switch + * there, and skiko's SwingDispatcher posts *every* continuation of `application { }` + * — composition, the button callbacks, even the return that would release the latch — + * to that same thread, with no `isDispatchNeeded` shortcut. A latch does not pump + * events, so the window never appeared and the client froze with no timeout anywhere + * in the path. A modal AWT dialog runs a nested event pump instead: it blocks its + * caller *and* keeps drawing, which is what `Stage.showAndWait()` did. + * + * Works from any thread. The startup path calls this from `main` before any window + * exists; the File menu calls it from the event thread. Either way the dialog itself is + * built and shown ON the event thread — see [openOnEventThread]. + */ + @JvmStatic + fun showAndSelect( + selectableProfiles: List, + preselectedProfileId: String?, + ): Optional { + val state = OperatorProfilePickerState(selectableProfiles, preselectedProfileId) + val chosen = AtomicReference(null) + + openOnEventThread { openPicker(state, chosen) } + + return Optional.ofNullable(chosen.get()) + } + + private fun openPicker( + state: OperatorProfilePickerState, + chosen: AtomicReference, + ) { + val dialog = ComposeDialog(owner = null, modalityType = Dialog.ModalityType.APPLICATION_MODAL) + dialog.title = kst4contest.view.i18n.CurrentStrings.get().pickerTitle + dialog.size = DIALOG_SIZE + dialog.setLocationRelativeTo(null) + /* Disposed and not hidden: a hidden dialog keeps its window and Skia layer alive. */ + dialog.defaultCloseOperation = WindowConstants.DISPOSE_ON_CLOSE + /* + * Raised above everything else. At startup there is nothing to hide behind, but + * the File menu opens this over the main window, which is not its owner. + */ + dialog.isAlwaysOnTop = true + + dialog.setContent { + Kst4ContestTheme(darkMode = false, baseFontSizeSp = DIALOG_FONT_SIZE_SP) { + PickerContent( + state = state, + onStart = { chosen.set(state.selected); dialog.dispose() }, + /* + * Quit and the window X agree: no choice. Every caller reads an empty + * Optional as "the operator does not want to continue", which at + * startup ends the process. + */ + onQuit = { chosen.set(null); dialog.dispose() }, + ) + } + } + + dialog.isVisible = true + } +} + +@Composable +private fun PickerContent( + state: OperatorProfilePickerState, + onStart: () -> Unit, + onQuit: () -> Unit, +) { + var selectedId by mutableStateOf(state.selected?.profileId) + + Surface(modifier = Modifier.fillMaxSize()) { + Column(modifier = Modifier.padding(15.dp), verticalArrangement = Arrangement.spacedBy(8.dp)) { + Text(kst4contest.view.i18n.CurrentStrings.get().pickerMoreThanOne) + + LazyColumn(modifier = Modifier.weight(1f).fillMaxWidth()) { + items(state.profiles, key = { it.profileId }) { profile -> + val isSelected = profile.profileId == selectedId + + Column { + /* + * Marked the same way as the profiles tab: a frame in the accent + * colour over a tinted row. Colouring only the name left the + * operator guessing which profile they were about to start. + */ + Column( + modifier = Modifier + .fillMaxWidth() + .background( + if (isSelected) { + MaterialTheme.colorScheme.secondaryContainer + } else { + Color.Transparent + } + ) + .then( + if (isSelected) { + Modifier.border( + Density.SELECTION_BORDER, + MaterialTheme.colorScheme.primary, + ) + } else { + Modifier + } + ) + .selectable(selected = isSelected, onClick = { + state.select(profile) + selectedId = profile.profileId + }) + .padding(horizontal = 6.dp, vertical = 4.dp), + ) { + Text(profile.displayName) + Text( + workedDatabaseDescription(profile), + style = MaterialTheme.typography.bodySmall, + ) + } + + if (!isSelected) { + HorizontalDivider(thickness = Density.HAIRLINE) + } + } + } + } + + Row(horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP)) { + Form.button(kst4contest.view.i18n.CurrentStrings.get().pickerStart, enabled = state.canConfirm, onClick = onStart) + Form.button(kst4contest.view.i18n.CurrentStrings.get().pickerQuit, onClick = onQuit) + } + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/PaletteResolution.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/PaletteResolution.kt new file mode 100644 index 00000000..a18fc99c --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/PaletteResolution.kt @@ -0,0 +1,88 @@ +package kst4contest.view.compose + +import androidx.compose.ui.graphics.Color +import kst4contest.model.PaletteRole + +/** Which of the three layers a colour in force came from. */ +enum class PaletteSource { SHIPPED, FILE, CHANGED } + +/** One role's colour, and where it came from. */ +data class ResolvedRole(val colour: Color, val source: PaletteSource) + +/** + * The palette in force, and the provenance of every role in it. + * + * @param roles always all six, so the settings tab can show a source for each + * @param palette what the windows draw + */ +data class ResolvedPalette( + val roles: Map, + val palette: JavaFxPalette, +) + +/** + * Resolves the three layers, role by role: the later layer wins. + * + * The shipped sheet is the floor and always complete. A file and a change each carry only + * the roles they name — which is why [JavaFxStylesheet.declaredRoles] exists rather than + * `read`: a file saying only `-fx-base` must override exactly one role. + * + * Fields that are not roles — the hover gradient, the pressed border, the font size — stay + * with the shipped sheet. They are derived values rather than decisions an operator wants to + * make one by one. + * + * The exception is `textAccent`, which follows the accent role whenever that role's colour + * actually differs from the shipped one: Material's primary is mapped onto it rather than onto + * `accent`, because `-fx-accent` paints only JavaFX's selection bar while the green of + * `.text-field .text` is what an operator reads as the accent. Left on the sheet's own value, + * a chosen accent would change almost nothing visible; keyed on provenance instead of on the + * value, an accent nobody chose would repaint it. + */ +fun resolvePalette( + shipped: JavaFxPalette, + fromFile: Map, + changed: Map, +): ResolvedPalette { + + val shippedColour = mapOf( + PaletteRole.SURFACE to shipped.base, + PaletteRole.WINDOW_SURFACE to shipped.windowBackground, + PaletteRole.FIELD_INTERIOR to shipped.controlInnerBackground, + PaletteRole.TEXT to shipped.labelTextFill, + PaletteRole.ACCENT to shipped.accent, + PaletteRole.SEPARATOR to shipped.separatorLine, + ) + + val roles = PaletteRole.values().associateWith { role -> + when { + changed.containsKey(role) -> ResolvedRole(changed.getValue(role), PaletteSource.CHANGED) + fromFile.containsKey(role) -> ResolvedRole(fromFile.getValue(role), PaletteSource.FILE) + else -> ResolvedRole(shippedColour.getValue(role), PaletteSource.SHIPPED) + } + } + + fun colourOf(role: PaletteRole) = roles.getValue(role).colour + + /* + * Keyed on the value and deliberately not on the provenance. The root profile's own + * stylesheet is the one copyResourceIfRequired writes at startup -- the shipped sheet + * itself -- so on every existing installation layer 2 declares the accent without anybody + * having chosen anything. Asking "does it come from a file" repainted the evening primary + * from green to blue on upgrade, and made resetToShipped disagree with discardChanges + * about what shipped looks like. + */ + val chosenAccent = roles.getValue(PaletteRole.ACCENT).colour.takeIf { it != shipped.accent } + + return ResolvedPalette( + roles = roles, + palette = shipped.copy( + base = colourOf(PaletteRole.SURFACE), + windowBackground = colourOf(PaletteRole.WINDOW_SURFACE), + controlInnerBackground = colourOf(PaletteRole.FIELD_INTERIOR), + labelTextFill = colourOf(PaletteRole.TEXT), + accent = colourOf(PaletteRole.ACCENT), + textAccent = chosenAccent ?: shipped.textAccent, + separatorLine = colourOf(PaletteRole.SEPARATOR), + ), + ) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/PaletteStore.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/PaletteStore.kt new file mode 100644 index 00000000..9ca64b27 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/PaletteStore.kt @@ -0,0 +1,211 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.staticCompositionLocalOf +import androidx.compose.ui.graphics.Color +import kst4contest.model.PaletteOverrides +import kst4contest.model.PaletteRole + +/** + * The palette of both designs for the active profile, held as Compose state. + * + * **This is what makes a colour change reach every open window.** `Kst4ContestTheme` used to + * take its palette from `remember(darkMode)`, so a change reached nothing until somebody + * toggled day/evening. Reading [resolved] inside the theme turns every palette change into a + * recomposition of every window that draws it. + * + * Built over four lambdas rather than over `ChatPreferences` so it can be tested without a + * profile on disk: that constructor copies resources into the operator's home directory. + * + * **Where "immediately" and "survives a restart" part company:** every change writes through + * to the preferences in memory at once, which is what recolours the windows, but the XML is + * written by the existing `savePreferencesFromSettings`. That is deliberately the same + * contract every other settings tab has — the JavaFX controls wrote as they changed and + * "Save settings" only persisted — but it means a change made and never saved is gone after a + * restart. + * + * @param shippedOf layer 1: the shipped sheet for a design, always complete + * @param fileRolesOf layer 2: the roles the profile's own stylesheet names, if any + * @param storedOverridesOf layer 3 as stored, encoded by [PaletteOverrides] + * @param storeOverrides writes layer 3 back + */ +class PaletteStore( + shippedOf: (darkMode: Boolean) -> JavaFxPalette, + fileRolesOf: (darkMode: Boolean) -> Map, + storedOverridesOf: (darkMode: Boolean) -> String, + private val storeOverrides: (darkMode: Boolean, encoded: String) -> Unit, +) { + + /* + * Layers 1 and 2 are read once per design, on first use, and then held. They do not change + * while the application runs -- the shipped sheet is a classpath resource, and both manuals + * promise that edits to the profile's stylesheet take effect after a restart. Re-reading + * them inside resolved() meant two CSS parses and a disk read per recomposition of every + * window, on the UI thread, which in this codebase is never a detail. + * + * Only the overrides below stay live. The state read is the mechanism that repaints the + * windows; re-parsing immutable input was never part of it. + */ + private val shippedDaylight by lazy { shippedOf(false) } + private val shippedEvening by lazy { shippedOf(true) } + private val fileRolesDaylight by lazy { fileRolesOf(false) } + private val fileRolesEvening by lazy { fileRolesOf(true) } + + /* + * The encoded overrides per design, as state. Everything else derives from these two, so + * there is exactly one place a change has to land for the windows to follow. + */ + private val daylightOverrides = mutableStateOf(storedOverridesOf(false)) + private val eveningOverrides = mutableStateOf(storedOverridesOf(true)) + + /** What [restoreSnapshot] goes back to, or null while nothing has been remembered. */ + private var snapshot: Pair? = null + + /** + * The palette in force for a design, with every role's provenance. + * + * Reads the override state, so a composable calling this recomposes when a colour + * changes. That state read is the mechanism and must not be cached; the two immutable + * layers under it are held, which is a different thing. + */ + fun resolved(darkMode: Boolean): ResolvedPalette = resolvePalette( + shipped = shipped(darkMode), + fromFile = if (darkMode) fileRolesEvening else fileRolesDaylight, + changed = changedRoles(darkMode), + ) + + /** + * The shipped palette for a design, untouched by file or change. + * + * The lifeline reads this. A control drawn from [resolved] would disappear in exactly the + * palette it exists to undo. + * + * @param darkMode the design + * @return layer 1 + */ + fun shipped(darkMode: Boolean): JavaFxPalette = + if (darkMode) shippedEvening else shippedDaylight + + /** + * Sets one role of one design. + * + * An unusable colour is ignored rather than stored: an operator mistyping a hex value + * must not end up with a black client. The tab reports the refusal. + * + * @param darkMode the design to change + * @param role the role to set + * @param colour a six-digit hex colour; anything else is ignored + */ + fun set(darkMode: Boolean, role: PaletteRole, colour: String) { + + if (!PaletteOverrides.isValidColour(colour)) { + return + } + + val overrides = PaletteOverrides.parse(encoded(darkMode)).toMutableMap() + overrides[role] = colour + write(darkMode, PaletteOverrides.format(overrides)) + } + + /** + * Sets every role of a design to its shipped colour, as an explicit change. + * + * Not the same as [discardChanges]: it has to beat a stylesheet file too, and only an + * explicit override on all six roles does that. This is the action the stage's acceptance + * criterion names — "exactly the shipped colours", file or no file. + * + * @param darkMode the design to reset + */ + fun resetToShipped(darkMode: Boolean) { + val shipped = shipped(darkMode) + + val overrides = PaletteRole.values().associateWith { role -> + hexOf(shippedColourOf(shipped, role)) + } + + write(darkMode, PaletteOverrides.format(overrides)) + } + + /** + * Empties layer 3, so the file or the shipped sheet applies again. + * + * @param darkMode the design to clear + */ + fun discardChanges(darkMode: Boolean) { + write(darkMode, "") + } + + /** Remembers the overrides of both designs, for [restoreSnapshot]. */ + fun takeSnapshot() { + snapshot = daylightOverrides.value to eveningOverrides.value + } + + /** + * Restores the overrides remembered by [takeSnapshot], including a change that was + * already there when it was taken. Does nothing when nothing was remembered. + * + * Both designs, not only the one in force. [takeSnapshot] captures both, and an operator + * who changed a colour, switched day/evening from the main window's menu, changed another + * and then asked to go back to how it was means both -- restoring half of it would leave + * a state they never chose and cannot name. + */ + fun restoreSnapshot() { + val remembered = snapshot ?: return + write(darkMode = false, encoded = remembered.first) + write(darkMode = true, encoded = remembered.second) + } + + private fun changedRoles(darkMode: Boolean): Map = + PaletteOverrides.parse(encoded(darkMode)).mapValues { (_, hex) -> colourOf(hex) } + + private fun encoded(darkMode: Boolean): String = + if (darkMode) eveningOverrides.value else daylightOverrides.value + + private fun write(darkMode: Boolean, encoded: String) { + if (darkMode) { + eveningOverrides.value = encoded + } else { + daylightOverrides.value = encoded + } + storeOverrides(darkMode, encoded) + } + + private fun shippedColourOf(shipped: JavaFxPalette, role: PaletteRole): Color = when (role) { + PaletteRole.SURFACE -> shipped.base + PaletteRole.WINDOW_SURFACE -> shipped.windowBackground + PaletteRole.FIELD_INTERIOR -> shipped.controlInnerBackground + PaletteRole.TEXT -> shipped.labelTextFill + PaletteRole.ACCENT -> shipped.accent + PaletteRole.SEPARATOR -> shipped.separatorLine + } +} + +/** + * A six-digit hex colour as a drawable colour. + * + * Only ever called with a value [PaletteOverrides.isValidColour] has already accepted, which + * is why it does not have to answer what an unparsable value means. + */ +internal fun colourOf(hex: String): Color = + Color(("ff" + hex.trim().removePrefix("#")).toLong(16)) + +/** + * A colour as the six-digit hex form the preferences store. + * + * Alpha is dropped on purpose: the roles are opaque surfaces and text, and a stored colour + * the operator cannot type back in would be a colour they cannot edit. + */ +internal fun hexOf(colour: Color): String = "#%02X%02X%02X".format( + (colour.red * 255).toInt(), + (colour.green * 255).toInt(), + (colour.blue * 255).toInt(), +) + +/** + * The store for the windows below, or null where there is none. + * + * Null is not caution but a real case: the operator profile picker draws before a profile — + * and therefore before a store — exists, and so do the tests of individual controls. Those + * get the shipped palette. + */ +val LocalPaletteStore = staticCompositionLocalOf { null } diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/PaletteStoreFactory.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/PaletteStoreFactory.kt new file mode 100644 index 00000000..e3ab1951 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/PaletteStoreFactory.kt @@ -0,0 +1,95 @@ +package kst4contest.view.compose + +import kst4contest.ApplicationConstants +import kst4contest.controller.OperatorProfilePaths +import kst4contest.model.ChatPreferences +import kst4contest.model.OperatorProfile +import kst4contest.utils.ApplicationFileUtils +import java.io.File + +/** + * Where one profile's own stylesheets live — layer 2 of the palette, one file per design. + * + * A value rather than a path derived inside the factory, so the resolution can be tested + * without writing into the operator's home directory. + */ +data class OperatorProfilePaletteFiles(val dayFile: File, val eveningFile: File) { + + /** The file for a design. */ + fun fileFor(darkMode: Boolean): File = if (darkMode) eveningFile else dayFile + + companion object { + + /** + * The files of a profile, by the project's own path convention. + * + * @param profile the profile whose stylesheets are wanted + * @return both files, which need not exist + */ + @JvmStatic + fun of(profile: OperatorProfile): OperatorProfilePaletteFiles = + OperatorProfilePaletteFiles( + dayFile = absoluteFile(OperatorProfilePaths.paletteRelativeFileName(profile, false)), + eveningFile = absoluteFile(OperatorProfilePaths.paletteRelativeFileName(profile, true)), + ) + + private fun absoluteFile(relativeName: String): File = + File(ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, relativeName)) + } +} + +/** + * Builds the [PaletteStore] of the active profile. + * + * The store itself takes four lambdas so it can be tested without a profile on disk; this is + * where those lambdas are tied to the real preferences and the real files, and it is the only + * place that knows which preference belongs to which design. + */ +object PaletteStoreFactory { + + /** + * Creates the store for one profile. + * + * Changes write through to [prefs] immediately, which is what recolours the open windows. + * The XML is written by the existing "save settings" path, exactly like every other + * setting in this application. + * + * @param prefs the active profile's preferences + * @param files the active profile's own stylesheets, which need not exist + * @return a store for both designs + */ + @JvmStatic + fun create(prefs: ChatPreferences, files: OperatorProfilePaletteFiles): PaletteStore = + PaletteStore( + shippedOf = { darkMode -> JavaFxStylesheet.shipped(darkMode) }, + fileRolesOf = { darkMode -> + JavaFxStylesheet.declaredRolesOfFile(files.fileFor(darkMode)) + }, + storedOverridesOf = { darkMode -> + if (darkMode) { + prefs.guiOptions_paletteOverridesEvening + } else { + prefs.guiOptions_paletteOverridesDay + } + }, + storeOverrides = { darkMode, encoded -> + if (darkMode) { + prefs.guiOptions_paletteOverridesEvening = encoded + } else { + prefs.guiOptions_paletteOverridesDay = encoded + } + }, + ) + + /** + * Creates the store for the active profile, or for the root profile when no profile has + * been resolved yet. + * + * @param prefs the active profile's preferences + * @param profile the active profile + * @return a store for both designs + */ + @JvmStatic + fun create(prefs: ChatPreferences, profile: OperatorProfile): PaletteStore = + create(prefs, OperatorProfilePaletteFiles.of(profile)) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/PublicMessageColumns.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/PublicMessageColumns.kt new file mode 100644 index 00000000..67c375b8 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/PublicMessageColumns.kt @@ -0,0 +1,50 @@ +package kst4contest.view.compose + +import kst4contest.model.ChatMessage + +/** + * The columns of the public message tab. + * + * The other two tabs below the station list reuse the monitor tables under their own + * layout ids; this one is its own. Its ids are the operator's stored column widths, + * kept exactly as TableLayoutManager registered them. + */ +object PublicMessageColumns { + + fun all(): List> = listOf( + DataColumn( + id = "time", + title = { kst4contest.view.i18n.CurrentStrings.get().columnTime }, + value = { MessageFormats.clockTime(it.messageGeneratedTime) }, + weight = 0.7f, + ), + DataColumn( + id = "callsign", + title = { kst4contest.view.i18n.CurrentStrings.get().columnCallsign }, + value = { MonitorColumns.callSignOf(it.sender) }, + ), + DataColumn(id = "name", title = { kst4contest.view.i18n.CurrentStrings.get().columnName }, value = { it.sender?.name.orEmpty() }), + DataColumn( + id = "last-qrg", + title = "Last QRG", + value = { MessageFormats.paddedQrg(MonitorColumns.frequencyOf(it.sender)) }, + weight = 0.8f, + ), + DataColumn( + id = "message", + title = { kst4contest.view.i18n.CurrentStrings.get().columnMessage }, + value = { it.messageText.orEmpty() }, + weight = 3f, + ), + DataColumn( + id = "category", + title = "Category", + value = { message -> + message.sender?.chatCategory + ?.let { it.getChatCategoryName(it.categoryNumber) } + .orEmpty() + }, + weight = 1.2f, + ), + ) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/SelectedStationMessageColumns.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/SelectedStationMessageColumns.kt new file mode 100644 index 00000000..6b80f4f4 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/SelectedStationMessageColumns.kt @@ -0,0 +1,60 @@ +package kst4contest.view.compose + +import kst4contest.model.ChatMessage + +/** + * The columns of the selected station message tab. + */ +object SelectedStationMessageColumns { + + fun all(): List> = listOf( + DataColumn( + id = "time", + title = { kst4contest.view.i18n.CurrentStrings.get().columnTime }, + value = { MessageFormats.clockTime(it.messageGeneratedTime) }, + weight = 0.7f, + ), + DataColumn( + id = "call-tx", + title = "Sender", + value = { MonitorColumns.callSignOf(it.sender) }, + weight = 0.8f, + ), + DataColumn( + id = "call-rx", + title = "Receiver", + value = { MonitorColumns.callSignOf(it.receiver) }, + weight = 0.8f, + ), + DataColumn( + id = "qrg-tx", + title = { kst4contest.view.i18n.CurrentStrings.get().columnLastQrgTx }, + value = { it.sender?.frequency?.get()?.takeIf { s -> s.isNotBlank() } ?: "" }, + weight = 0.8f, + ), + DataColumn( + id = "qrg-rx", + title = { kst4contest.view.i18n.CurrentStrings.get().columnLastQrgRx }, + value = { it.receiver?.frequency?.get()?.takeIf { s -> s.isNotBlank() } ?: "" }, + weight = 0.8f, + ), + DataColumn( + id = "message", + title = { kst4contest.view.i18n.CurrentStrings.get().columnMessage }, + value = { it.messageText.orEmpty() }, + weight = 3f, + ), + DataColumn( + id = "wkd-rx", + title = "wkd RX?", + value = { if (it.receiver?.isWorked == true) "wkd" else "" }, + weight = 0.6f, + ), + DataColumn( + id = "wkd-tx", + title = "wkd TX?", + value = { if (it.sender?.isWorked == true) "wkd" else "" }, + weight = 0.6f, + ), + ) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/SelectedStationPanel.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/SelectedStationPanel.kt new file mode 100644 index 00000000..f8fc203a --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/SelectedStationPanel.kt @@ -0,0 +1,257 @@ +package kst4contest.view.compose + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.foundation.selection.selectable +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.LocalMinimumInteractiveComponentSize +import androidx.compose.material3.RadioButton +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.foundation.layout.size +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import kst4contest.model.Band +import java.util.function.Consumer + +/** + * The panel below the station list, for whichever station is selected. + * + * Its rules live in [SelectedStationState] and are tested there; what is here is the + * drawing. With nothing selected it says so rather than showing dead controls — the + * JavaFX pane disabled them, which looks the same as broken. + * + * @param openInBrowser opens a lookup address; reaching the browser is the host + * application's business + */ +@OptIn(ExperimentalLayoutApi::class) +@Composable +fun SelectedStationPanel( + state: SelectedStationState, + messages: DataTableState, + /** The bands this station is set up for; BandOpportunityResolver decides them. */ + skedBands: List, + /** My own station's enabled bands; used for the "Tag not QRV" checkboxes. */ + activeBands: Set, + openInBrowser: Consumer, + onShowOnMap: () -> Unit, + onShowPathInAirScout: () -> Unit, + modifier: Modifier = Modifier, +) { + val strings = LocalStrings.current + val member = state.selected + + Column( + modifier = modifier.fillMaxWidth().padding(4.dp), + verticalArrangement = Arrangement.spacedBy(3.dp), + ) { + if (member == null) { + Text( + strings.selectedNone, + style = MaterialTheme.typography.bodyMedium, + color = MaterialTheme.colorScheme.outline, + ) + return@Column + } + + Text( + member.callSign.orEmpty() + " " + member.qra.orEmpty(), + style = MaterialTheme.typography.titleSmall, + fontWeight = FontWeight.Bold, + ) + + FlowRow( + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(4.dp), + modifier = Modifier.padding(bottom = 8.dp) + ) { + val category = member.chatCategory?.let { it.getChatCategoryName(it.categoryNumber) } + if (category != null) { + Text(category, style = MaterialTheme.typography.bodySmall) + } + if (member.getQTFdirection() != null) { + Text("QTF: ${member.getQTFdirection()}°", style = MaterialTheme.typography.bodySmall) + } + if (member.qrb != null) { + Text("QRB: ${member.qrb} km", style = MaterialTheme.typography.bodySmall) + } + + val lastActSec = member.activityTimeLastInEpoch + if (lastActSec > 0L) { + val actStr = MessageFormats.clockTime(lastActSec.toString()) + val minAgo = kst4contest.controller.Utils4KST.time_getSecondsBetweenEpochAndNow(lastActSec.toString()) / 60 + Text(strings.selectedLastActivity(actStr, minAgo), style = MaterialTheme.typography.bodySmall) + } + + val detectedBands = state.detectedBands() + if (detectedBands.isNotBlank()) { + Text(detectedBands, style = MaterialTheme.typography.bodySmall) + } + } + + Form.section(strings.selectedShowMessages) { + FlowRow(horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP)) { + SelectedMessageFilter.entries.forEach { filter -> + RadioChoice( + label = filter.label, + selected = state.messageFilter == filter, + onSelect = { state.messageFilter = filter }, + ) + } + } + } + + DataTableView( + state = messages, + modifier = Modifier.weight(1f).fillMaxWidth(), + ) + + Form.section(strings.selectedTagNotQrv) { + FlowRow(horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP)) { + val activeNotQrvBands = NotQrvBand.entries.filter { activeBands.contains(it.band) } + + activeNotQrvBands.forEach { band -> + Form.check(band.label, state.isTaggedNotQrv(band)) { + state.tagNotQrv(band, it) + } + } + + Form.check("all", activeNotQrvBands.all { state.isTaggedNotQrv(it) }) { + state.tagNotQrvAll(it) + } + } + } + + Form.section("Sked") { + FlowRow( + horizontalArrangement = Arrangement.spacedBy(16.dp), + verticalArrangement = Arrangement.spacedBy(Density.FIELD_GAP) + ) { + Form.inlineChoice( + label = strings.selectedSkedInMinutes, + items = SelectedStationState.SKED_MINUTES, + selected = state.skedMinutes, + describe = { it.toString() }, + onSelect = { state.skedMinutes = it }, + ) + Form.inlineChoice( + label = strings.selectedBand, + items = skedBands, + selected = state.skedBand, + describe = { it.prefix + " MHz" }, + onSelect = { state.skedBand = it }, + ) + Form.inlineChoice( + label = strings.selectedMode, + items = SelectedStationState.SKED_MODES, + selected = state.skedMode, + describe = { it }, + onSelect = { state.skedMode = it }, + ) + } + + Row(horizontalArrangement = Arrangement.spacedBy(16.dp), verticalAlignment = Alignment.CenterVertically) { + Form.check(strings.selectedRemindPmIn, state.remindPm) { state.remindPm = it } + Form.inlineChoice( + label = strings.selectedReminderOffsets, + items = SelectedStationState.REMINDER_OFFSETS, + selected = state.reminderOffsets, + describe = { it }, + enabled = state.remindPm, + onSelect = { state.reminderOffsets = it }, + ) + } + + FlowRow(horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP)) { + Form.button(strings.selectedCreateSked, enabled = state.canCreateSked) { state.createSked() } + Form.button(strings.selectedSkedFail, enabled = state.canCreateSked) { state.markSkedFail() } + Form.button(strings.selectedResetFail, enabled = state.canCreateSked) { state.resetSkedFail() } + } + } + + Form.section(strings.selectedLookUpAndShow) { + FlowRow(horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP)) { + Form.button(strings.selectedShowPathInAs, onClick = onShowPathInAirScout) + Form.button("🗺 Show on map", onClick = onShowOnMap) + Form.button(strings.selectedLookupQrz, enabled = state.canLookUp) { + openInBrowser.accept(state.qrzComUrl()) + } + Form.button(strings.selectedLookupQrzcq, enabled = state.canLookUp) { + openInBrowser.accept(state.qrzCqUrl()) + } + } + } + + + } +} + +/** + * The two priority buttons beside the station list: a shortcut to the station the + * score says to work next. + */ +@Composable +fun TopPriorityBar( + state: TopPriorityState, + onShowMore: () -> Unit, + modifier: Modifier = Modifier, +) { + val strings = LocalStrings.current + + Row( + modifier = modifier.padding(2.dp), + horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP), + verticalAlignment = Alignment.CenterVertically, + ) { + Text(strings.selectedPriority, style = MaterialTheme.typography.bodySmall) + + state.entries.forEach { entry -> + Form.button(entry.label, onClick = entry.select) + } + + Form.button(strings.selectedMore, onClick = onShowMore) + } +} + + +/** + * One of a set of mutually exclusive choices. + * + * Material's RadioButton carries the same 48dp minimum that made every field too tall on + * the desktop, so the touch target is released the way the other compact controls do it. + */ +@OptIn(ExperimentalMaterial3Api::class) +@Composable +private fun RadioChoice(label: String, selected: Boolean, onSelect: () -> Unit) { + val strings = LocalStrings.current + CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides Dp.Unspecified) { + Row( + modifier = Modifier + .selectable(selected = selected, onClick = onSelect) + .padding(end = Density.BUTTON_GAP), + verticalAlignment = Alignment.CenterVertically, + ) { + RadioButton( + selected = selected, + onClick = onSelect, + modifier = Modifier.size(Density.CHECK_SIZE), + ) + Text( + text = label, + modifier = Modifier.padding(start = 4.dp), + style = MaterialTheme.typography.bodySmall, + ) + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/SelectedStationState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/SelectedStationState.kt new file mode 100644 index 00000000..eb912bdc --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/SelectedStationState.kt @@ -0,0 +1,183 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import kst4contest.model.Band +import kst4contest.model.ChatMember + +/** + * The bands a station can be tagged as not being on, under the labels the panel shows. + * + * @param read whether the station is QRV on this band + * @param write sets that flag + */ +enum class NotQrvBand( + val label: String, + val band: kst4contest.model.Band, + val read: (ChatMember) -> Boolean, + val write: (ChatMember, Boolean) -> Unit, +) { + B_50("50", kst4contest.model.Band.B_50, { it.isQrv50 }, { m, qrv -> m.isQrv50 = qrv }), + B_70("70", kst4contest.model.Band.B_70, { it.isQrv70 }, { m, qrv -> m.isQrv70 = qrv }), + B_144("144", kst4contest.model.Band.B_144, { it.isQrv144 }, { m, qrv -> m.isQrv144 = qrv }), + B_432("432", kst4contest.model.Band.B_432, { it.isQrv432 }, { m, qrv -> m.isQrv432 = qrv }), + B_23("23cm", kst4contest.model.Band.B_1296, { it.isQrv1240 }, { m, qrv -> m.isQrv1240 = qrv }), + B_13("13cm", kst4contest.model.Band.B_2320, { it.isQrv2300 }, { m, qrv -> m.isQrv2300 = qrv }), + B_9("9cm", kst4contest.model.Band.B_3400, { it.isQrv3400 }, { m, qrv -> m.isQrv3400 = qrv }), + B_6("6cm", kst4contest.model.Band.B_5760, { it.isQrv5600 }, { m, qrv -> m.isQrv5600 = qrv }), + B_3("3cm", kst4contest.model.Band.B_10G, { it.isQrv10G }, { m, qrv -> m.isQrv10G = qrv }), +} + +/** + * Which messages the panel lists for the selected station. + * + * One choice, not four switches: the JavaFX controls were a toggle group, so two can + * never be on at once. + */ +enum class SelectedMessageFilter(val label: String) { + PM_TO_ME("pm to me"), + PM_TO_OTHER("pm to other"), + PUBLIC("public msgs"), + NOTHING("nothing"), +} + +/** + * The panel below the station list, for whichever station is selected. + * + * Its "tag not qrv" marks are not display state: they are written into the station and + * propagated to the active members, so a wrong one hides that station from every list + * filtering on QRV. That is why they go through the controller rather than being kept + * here. + * + * @param propagateNotQrv hands the changed station to the controller, which is what + * `propagateNotQrvStateToActiveMembers` does + * @param createSked takes the station, the minutes, the band and the mode; returns + * whether it was accepted + */ +class SelectedStationState( + private val propagateNotQrv: (ChatMember) -> Unit, + private val createSked: (ChatMember, Int, Band?, String?) -> Boolean, + private val markSkedFail: (ChatMember) -> Unit = { }, + private val resetSkedFail: (ChatMember) -> Unit = { }, + private val onMessageFilterChange: (SelectedMessageFilter?) -> Unit = { }, + private val detectBands: (ChatMember) -> String = { "" }, + private val resolveDefaultSkedBand: (ChatMember) -> Band? = { null }, +) { + + var selected: ChatMember? by mutableStateOf(null) + private set + + /** Bumped on a tag so the panel redraws; the flags live on the station itself. */ + private var tagRevision: Int by mutableStateOf(0) + + var skedMinutes: Int by mutableStateOf(DEFAULT_SKED_MINUTES) + + var skedBand: Band? by mutableStateOf(null) + + var skedMode: String? by mutableStateOf(null) + + private var _messageFilter by mutableStateOf(null) + + /** + * Which messages the panel follows, or null until the operator picks one. + * + * JavaFX has the setSelected(true) on "pm to me" commented out, so its toggle group + * starts with nothing on. Starting on a filter would silently hide messages nobody + * asked to hide. + */ + var messageFilter: SelectedMessageFilter? + get() = _messageFilter + set(value) { + _messageFilter = value + onMessageFilterChange(value) + } + + var remindPm: Boolean by mutableStateOf(false) + + var reminderOffsets: String by mutableStateOf(REMINDER_OFFSETS.first()) + + val canCreateSked: Boolean + get() = selected != null + + val canLookUp: Boolean + get() = !selected?.callSign.isNullOrBlank() + + fun select(member: ChatMember?) { + if (selected?.callSignRaw != member?.callSignRaw) { + skedBand = member?.let { resolveDefaultSkedBand(it) } + } + selected = member + } + + fun isTaggedNotQrv(band: NotQrvBand): Boolean { + @Suppress("UNUSED_EXPRESSION") tagRevision + + val member = selected ?: return false + + return !band.read(member) + } + + /** Tagged means not QRV, so the station's QRV flag goes the other way. */ + fun tagNotQrv(band: NotQrvBand, tagged: Boolean) { + val member = selected ?: return + + band.write(member, !tagged) + tagRevision++ + propagateNotQrv(member) + } + + fun tagNotQrvAll(tagged: Boolean) { + val member = selected ?: return + + NotQrvBand.entries.forEach { it.write(member, !tagged) } + tagRevision++ + propagateNotQrv(member) + } + + /** @return whether a sked was created; false when nothing is selected. */ + fun createSked(): Boolean { + val member = selected ?: return false + + return createSked(member, skedMinutes, skedBand, skedMode) + } + + /** + * Marks the path to this station as failed. + * + * Permanent until reset, and it lowers the priority score sharply — so it is an + * answer to "I called and heard nothing", not to "not now". + */ + fun markSkedFail() { + selected?.let(markSkedFail) + } + + fun resetSkedFail() { + selected?.let(resetSkedFail) + } + + fun detectedBands(): String { + val member = selected ?: return "" + val ignored = tagRevision + return detectBands(member) + } + + + fun qrzComUrl(): String = QRZ_COM + selected?.callSign.orEmpty() + + fun qrzCqUrl(): String = QRZ_CQ + selected?.callSign.orEmpty() + + companion object { + /** The minutes the JavaFX choice offered, and the one it started on. */ + val SKED_MINUTES = listOf(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 20) + + val SKED_MODES = listOf("SSB", "CW") + + /** How long before a sked the reminders come, in minutes. */ + val REMINDER_OFFSETS = listOf("2+1", "5+2+1", "10+5+2+1") + + private const val DEFAULT_SKED_MINUTES = 5 + private const val QRZ_COM = "https://www.qrz.com/db/" + private const val QRZ_CQ = "https://www.qrzcq.com/call/" + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/SettingsTabs.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/SettingsTabs.kt new file mode 100644 index 00000000..e4cb6a10 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/SettingsTabs.kt @@ -0,0 +1,332 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import kst4contest.controller.ChatController +import kst4contest.controller.ActiveOperatorProfile +import kst4contest.controller.OperatorProfileManagementService +import kst4contest.controller.OperatorProfilePaths +import kst4contest.model.ChatMember +import kst4contest.model.OperatorProfile +import kst4contest.view.compose.OperatorProfilePaletteFiles +import kst4contest.view.compose.tabs.AirscoutTab +import kst4contest.view.compose.tabs.AirscoutTabState +import kst4contest.view.compose.tabs.BeaconTab +import kst4contest.view.compose.tabs.BeaconTabState +import kst4contest.view.compose.tabs.ColoursTab +import kst4contest.view.compose.tabs.ColoursTabState +import kst4contest.view.compose.tabs.GuiOptionsTab +import kst4contest.view.compose.tabs.GuiOptionsTabState +import kst4contest.view.compose.tabs.LogSynchTab +import kst4contest.view.compose.tabs.LogSynchTabState +import kst4contest.view.compose.tabs.MessageHandlingTab +import kst4contest.view.compose.tabs.MessageHandlingTabState +import kst4contest.view.compose.tabs.NotificationTab +import kst4contest.view.compose.tabs.NotificationTabState +import kst4contest.view.compose.tabs.ProfilesTab +import kst4contest.view.compose.tabs.ProfilesTabState +import kst4contest.view.compose.tabs.ShortcutsTab +import kst4contest.view.compose.tabs.ShortcutsTabState +import kst4contest.view.compose.tabs.StationTab +import kst4contest.view.compose.tabs.StationTabState +import kst4contest.view.compose.tabs.TrxSynchTab +import kst4contest.view.compose.tabs.TrxSynchTabState +import kst4contest.view.compose.tabs.WorkedDatabaseTab +import kst4contest.view.compose.tabs.WorkedDatabaseTabState + +/** + * The work the settings window needs from the main window. + * + * These are the callbacks whose implementation lives in the JavaFX window and cannot + * be reached from a ChatController: rebuilding controls, binding the own-QRG + * follower and refreshing a table. Everything else the tabs need comes from the + * controller, which is why it is not listed here. + */ +interface SettingsHost { + + /** + * Rebuilds the button row above the message field from the shortcut list. + * + * The suffix keeps this distinct from the window's own private method of the same + * purpose, which touches JavaFX directly; the implementation of this one has to hop + * onto the JavaFX thread first, because the settings window runs on its own. + */ + fun refreshShortcutButtonsFromSettings() + + /** Rebuilds the Ctrl+1..Ctrl+0 context menus from the snippet list. */ + fun refreshTextSnippetContextMenusFromSettings() + + /** The detected subnet broadcast address for Win-Test, or null. */ + fun detectWintestBroadcastAddress(): String? + + /** Attaches or detaches the follower that mirrors the own QRG into the station field. */ + fun applyOwnQrgFollower(enabled: Boolean) + + /** + * Turns file recording of the whole session on or off, with the history recorder. + * + * Lives here and not on the controller because enabling it opens the error-log file + * handler, which the application owns. The order — log before recorder when enabling, + * recorder before log when disabling — is the one the JavaFX checkbox kept. + */ + fun applyDebugModeToFile(enabled: Boolean) + + /** Re-reads the worked-stations table for display. */ + fun refreshWorkedStationsView() + + /** + * Switches the application to another operator profile. The tab must not do this + * itself: the switch reloads preferences and the worked database, which only the + * application can sequence. + */ + fun switchToOperatorProfile(profile: OperatorProfile) + + /** + * Starts the ON4KST session — the work of the Connect button. + * + * @return null when the session was started, otherwise the reason it was not + */ + fun connectFromSettings(): String? + + /** Drops the session and keeps the client running. */ + fun disconnectOnlyFromSettings() + + /** Drops the session and closes the client. */ + fun disconnectAndCloseChatFromSettings() + + /** + * Persists the preferences. + * + * @return the file the settings went to, or null when it could not be written + */ + fun savePreferencesFromSettings(): String? +} + +/** + * Builds the settings tabs in the order the JavaFX TabPane had them. + * + * The wiring lives here rather than in the Java window on purpose: every call that + * reaches past ChatPreferences into the running session is made in one readable + * place, and the foreign-write coverage test can see it. A tab that only wrote a + * preference and skipped its session call would look correct in the file and do + * nothing until the next restart. + */ +fun buildSettingsTabs( + controller: ChatController, + host: SettingsHost, + notices: SettingsNotices, + paletteStore: PaletteStore, + languageStore: kst4contest.view.i18n.LanguageStore, +): List { + + val prefs = controller.chatPreferences + + val stationState = StationTabState( + prefs, + applyMainCategory = { category -> controller.setChatCategoryMain(category) }, + applySecondCategory = { category -> controller.setChatCategorySecondChat(category) }, + ) + + val notificationState = NotificationTabState( + prefs, + controller.lstNotify_QSOSniffer_sniffedCallSignList, + applyDxClusterServerEnabled = { enabled -> + /* + * Starting a server that nothing can reach yet is pointless, so the JavaFX + * checkbox only touched the server while the session was logged in; the + * flag alone decides what happens at the next login. + */ + if (controller.isConnectedAndLoggedIn) { + if (enabled) controller.startDxClusterServerIfEnabled() else controller.stopDxClusterServer() + } + }, + applyDxClusterServerPort = { + if (controller.isConnectedAndLoggedIn && prefs.isNotify_dxClusterServerEnabled()) { + controller.restartDxClusterServerIfEnabled() + } + }, + broadcastTestSpot = { spot -> deliverTestSpot(controller, spot) }, + ) + + val shortcutsState = ShortcutsTabState( + prefs, + refreshShortcutButtons = host::refreshShortcutButtonsFromSettings, + refreshTextSnippetContextMenus = host::refreshTextSnippetContextMenusFromSettings, + ) + + val beaconState = BeaconTabState( + prefs, + validateBeaconTemplate = { template -> controller.validateBeaconTemplate(template) }, + restartBeaconTimer = { controller.restartBeaconTimer() }, + mainCategoryName = categoryName(controller.chatCategoryMain, kst4contest.view.i18n.CurrentStrings.get().settingsCategoryMainFallback), + secondCategoryName = categoryName(controller.chatCategorySecondChat, kst4contest.view.i18n.CurrentStrings.get().settingsCategorySecondFallback), + ) + + val logSynchState = LogSynchTabState( + prefs, + restartWintestListener = { controller.restartWintestUdpListenerIfEnabled() }, + stopWintestListener = { controller.stopWintestUdpListener() }, + detectWintestBroadcastAddress = host::detectWintestBroadcastAddress, + ) + + val workedDatabaseState = WorkedDatabaseTabState( + resetInDatabase = { controller.dbHandler.resetWorkedDataInDB() }, + refreshGuiLists = { + controller.resetWorkedAndQrvInfoInGuiLists() + controller.refreshWorkedStateAndDatabaseListFromDatabase() + }, + refreshView = host::refreshWorkedStationsView, + workedRoster = controller.lst_DBBasedWkdCallSignList, + ) + + val profilesState = ProfilesTabState( + OperatorProfileManagementService(), + activeSelection = { ActiveOperatorProfile.get() }, + requestActivation = host::switchToOperatorProfile, + ) + + val reportRefusal: (String) -> Unit = notices::problem + + /* + * The profile whose stylesheet the colours tab offers to write. Resolved here rather than + * captured, because the settings window outlives nothing but is built once per profile. + */ + fun activeProfileOrRoot(): OperatorProfile = + ActiveOperatorProfile.get()?.profile + ?: OperatorProfilePaths.buildRootProfile(prefs.stn_loginCallSign ?: "") + + /* + * Order and titles are those of the JavaFX TabPane, character for character. The + * comment there is explicit that operators navigate these tabs by muscle memory, + * so a tidier order or a shorter title would be a regression, not an improvement. + */ + return listOf( + SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabStation }) { StationTab(stationState) }, + SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabLogSynch }) { LogSynchTab(logSynchState) }, + SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabTrxSynch }) { TrxSynchTab(TrxSynchTabState(prefs, host::applyOwnQrgFollower)) }, + SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabAirscout }) { AirscoutTab(AirscoutTabState(prefs)) }, + SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabNotification }) { NotificationTab(notificationState, reportRefusal) }, + SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabShortcuts }) { ShortcutsTab(shortcutsState, reportRefusal) }, + SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabBeacon }) { BeaconTab(beaconState, reportRefusal) }, + SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabMessageHandling }) { MessageHandlingTab(MessageHandlingTabState(prefs, host::applyDebugModeToFile)) }, + /* + * Selecting this tab re-read the database in the JavaFX window; the list is a + * snapshot and would otherwise show what was true when the window opened. + */ + SettingsTab( + { kst4contest.view.i18n.CurrentStrings.get().tabWorkedDatabase }, + onSelected = { controller.refreshWorkedStateAndDatabaseListFromDatabase() }, + ) { WorkedDatabaseTab(workedDatabaseState) }, + SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabGui }) { GuiOptionsTab(GuiOptionsTabState(prefs, languageStore)) }, + /* + * Appended last on purpose so no established tab position shifts, the reason + * the JavaFX tab gave for the same placement. + */ + SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabProfiles }, onSelected = profilesState::refresh) { ProfilesTab(profilesState) }, + /* + * Appended after Profiles for the same reason Profiles was appended after GUI. The + * tab edits whichever design is in force, which is why it reads the flag through a + * lambda rather than taking its value here: the operator can switch day/evening from + * the main window's menu while this tab is open. + */ + SettingsTab({ kst4contest.view.i18n.CurrentStrings.get().tabColours }) { + /* + * Remembered rather than rebuilt: the tab recomposes on every colour change, and + * the design flag is read through a lambda precisely so the object itself does not + * have to be rebuilt to follow a day/evening switch. + */ + val coloursState = remember(paletteStore) { + ColoursTabState( + paletteStore, + { prefs.isGUI_darkModeActive }, + OperatorProfilePaletteFiles.of(activeProfileOrRoot()), + ) + } + ColoursTab(coloursState, reportRefusal, notices::info) + }, + ) +} + +/** + * Delivers the test spot and reports why it could not be delivered, in the order the + * JavaFX button checked: session first, then a connected logger, then the delivery + * itself. The messages are the ones the operator knows. + */ +private fun deliverTestSpot(controller: ChatController, spot: ChatMember): String? { + if (!controller.isConnectedAndLoggedIn || !controller.chatPreferences.isNotify_dxClusterServerEnabled()) { + return "Connect KST4Contest and enable the local DX Cluster server first." + } + + val server = controller.dxClusterServer + ?: return "Connect KST4Contest and enable the local DX Cluster server first." + + if (!server.hasConnectedClients()) { + return "No DX Cluster client is connected to KST4Contest." + } + + if (!server.broadcastSingleDXClusterEntryToLoggers(spot)) { + return "The test spot could not be delivered." + } + + return null +} + +/** The label a chat category carries in the beacon tab, or a fallback when unset. */ +private fun categoryName(category: kst4contest.model.ChatCategory?, fallback: String): String = + category?.getChatCategoryName(category.categoryNumber) ?: fallback + +/** + * The bottom button row of the settings window. + * + * Built here because it needs the controller for its state and the host for its + * actions, and because it belongs with the tabs it sits under. The `close` action comes + * from the window itself: only the window can end its own Compose application. + */ +fun settingsButtons( + controller: ChatController, + host: SettingsHost, + notices: SettingsNotices, +): @Composable (close: () -> Unit) -> Unit { + val barState = ConnectionBarState(controller.chatPreferences, controller) + + return { close -> + /* + * The bar is rebuilt after every action so its labels and enabled states follow + * the session. The JavaFX bar was told by onConnectionStateChanged instead. + */ + var revision by remember { mutableStateOf(0) } + + @Suppress("UNUSED_EXPRESSION") revision + + ConnectionBar( + state = barState, + onConnect = { + val refusal = host.connectFromSettings() + if (refusal != null) notices.problem(refusal) + revision++ + }, + onSave = { + val target = host.savePreferencesFromSettings() + if (target == null) { + notices.problem( + "The configuration file could not be written. The settings stay " + + "active for this session." + ) + } else { + notices.info( + "Settings are stored as default to the xml config file:\n" + target + ) + } + }, + onApplyAndClose = close, + onDisconnectAndCloseChat = host::disconnectAndCloseChatFromSettings, + onDisconnectOnly = { + host.disconnectOnlyFromSettings() + revision++ + }, + ) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/SettingsWindow.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/SettingsWindow.kt new file mode 100644 index 00000000..c9cf7e1d --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/SettingsWindow.kt @@ -0,0 +1,328 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.heightIn +import androidx.compose.material3.MaterialTheme +import androidx.compose.ui.graphics.Color +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.material3.HorizontalDivider +import androidx.compose.ui.Alignment +import androidx.compose.ui.draw.drawBehind +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size +import androidx.compose.foundation.LocalScrollbarStyle +import androidx.compose.foundation.VerticalScrollbar +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.rememberScrollbarAdapter +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp + +/** + * One tab of the settings window: a title and the content to show. + * + * Tabs are handed in rather than listed here so each one can be written and tested on + * its own, and so the window does not need to know what any of them contains. + */ +class SettingsTab( + /** + * Read during composition, not stored as text, so a language change retitles the strip + * of an already open window. The tabs themselves are built once, outside any + * composition; without this the titles would only follow on the next time the window + * was opened. + */ + val title: () -> String, + /** + * Called when the operator selects this tab, before its content is shown. The + * worked-stations tab used it to re-read the database, which it has to: its list is + * a snapshot taken when the window was built. + */ + val onSelected: (() -> Unit)? = null, + val content: @Composable () -> Unit, +) { + + /** For a title that genuinely never changes -- the tests, and anything not translated. */ + constructor( + title: String, + onSelected: (() -> Unit)? = null, + content: @Composable () -> Unit, + ) : this({ title }, onSelected, content) +} + +/** Something the window has to tell the operator. */ +sealed interface SettingsNotice { + + val message: String + + /** It happened; this is what the operator should know about it. */ + data class Info(override val message: String) : SettingsNotice + + /** It did not happen, and this is why. */ + data class Problem(override val message: String) : SettingsNotice +} + +/** + * Carries a notice from a tab or a button to the one dialog that shows it. + * + * The JavaFX window opened an Alert per field and per button. One reporter keeps that + * behaviour without every tab having to carry a dialog, and because the window opens + * at most once there is at most one of these in flight. + */ +class SettingsNotices { + + var current: SettingsNotice? by mutableStateOf(null) + private set + + fun info(message: String) { + current = SettingsNotice.Info(message) + } + + fun problem(message: String) { + current = SettingsNotice.Problem(message) + } + + fun dismiss() { + current = null + } +} + +/** + * The settings window. + * + * Unlike the operator profile picker this window does **not** block: the operator keeps + * working while it is open, exactly as the JavaFX window behaved. It is also opened at + * most once — a second instance would let two windows write the same preferences + * against each other. + * + * Saving does not collect values. Every control writes into ChatPreferences as it + * changes; the button bar only persists, which is what the JavaFX "Save settings" + * button did. + */ +object SettingsWindow { + + /** + * Opening, closing, the single instance and the design switch all live in + * ComposeWindowHost; this object adds only what is specific to the settings + * window. The shared part was written here first and is now on its third window, + * and its close path is exactly where the profile switch broke. + */ + private val host = ComposeWindowHost("settings-window") + + /** Whether the window is currently open, so a toggle can tell. */ + @JvmStatic + val isOpen: Boolean + get() = host.isOpen + + /** Follows a design switch made in the main window. */ + @JvmStatic + fun applyDarkMode(darkMode: Boolean) = host.applyDarkMode(darkMode) + + /** Closes the window and waits for it to be gone; see ComposeWindowHost.close. */ + @JvmStatic + fun close() = host.close() + + /** + * @param buttons the bottom button row; it receives the action that closes the + * window, because only the window itself can end its Compose application + */ + @JvmStatic + fun show( + tabs: List, + notices: SettingsNotices, + darkMode: Boolean, + baseFontSizeSp: Float, + /** + * The palette of the active profile, handed to the theme. Null draws the shipped + * palette. + */ + paletteStore: PaletteStore? = null, + /** + * The interface language of the active profile, handed to the window. Null draws the + * base language. + */ + languageStore: kst4contest.view.i18n.LanguageStore? = null, + widthDp: Float, + heightDp: Float, + onResized: (Float, Float) -> Unit, + buttons: @Composable (close: () -> Unit) -> Unit, + ) { + host.show( + title = { "Change Client Settings" }, + darkMode = darkMode, + baseFontSizeSp = baseFontSizeSp, + paletteStore = paletteStore, + languageStore = languageStore, + widthDp = widthDp, + heightDp = heightDp, + onResized = onResized, + ) { close -> + SettingsContent(tabs, notices, buttons, close) + } + } +} + +@Composable +internal fun SettingsContent( + tabs: List, + notices: SettingsNotices, + buttons: @Composable (close: () -> Unit) -> Unit, + close: () -> Unit, +) { + var selected by remember { mutableStateOf(0) } + + Surface(modifier = Modifier.fillMaxSize()) { + Column( + modifier = Modifier.padding(10.dp), + verticalArrangement = Arrangement.spacedBy(8.dp), + ) { + SettingsTabStrip( + tabs = tabs, + selectedIndex = selected, + onSelect = { index -> + selected = index + tabs[index].onSelected?.invoke() + }, + ) + + /* + * One scroll region for the whole window, with a scrollbar beside it. The + * tabs used to scroll each for themselves, and none of them could show a + * bar: a tab does not know the window it sits in, so content simply ended + * mid-form with nothing to say that more was below. + */ + val scroll = rememberScrollState() + + Box(modifier = Modifier.weight(1f).fillMaxWidth()) { + Column( + modifier = Modifier + .fillMaxSize() + .verticalScroll(scroll) + .padding(end = Density.SCROLLBAR_GUTTER), + ) { + tabs.getOrNull(selected)?.content?.invoke() + } + + VerticalScrollbar( + adapter = rememberScrollbarAdapter(scroll), + modifier = Modifier.align(Alignment.CenterEnd).fillMaxHeight(), + style = LocalScrollbarStyle.current.copy( + /* Muted on purpose: a bar in the accent colour shouts. */ + unhoverColor = MaterialTheme.colorScheme.outline, + hoverColor = MaterialTheme.colorScheme.onSurface, + ), + ) + } + + buttons(close) + } + } + + notices.current?.let { notice -> + AlertDialog( + onDismissRequest = notices::dismiss, + title = { + Text( + when (notice) { + is SettingsNotice.Info -> "Info" + is SettingsNotice.Problem -> "Settings" + } + ) + }, + text = { Text(notice.message) }, + confirmButton = { TextButton(onClick = notices::dismiss) { Text("OK") } }, + ) + } +} + +/** + * The row of tab buttons. + * + * Material's ScrollableTabRow is not usable here: it gives every tab a minimum width + * of 90dp and a height of 48dp, both private constants. Eleven tabs then need over + * 990dp before a single letter is measured, so the row overflowed and cut the last + * title in half. + * + * Here a tab is as wide as its own title plus a small padding, which is how the + * JavaFX TabPane sized them, and the row wraps to a second line when it truly does + * not fit. Wrapping rather than clipping is deliberate: half a word is the worst of + * the available outcomes, and a scrolling strip hides that tabs exist at all. + */ +@OptIn(ExperimentalLayoutApi::class) +@Composable +internal fun SettingsTabStrip( + tabs: List, + selectedIndex: Int, + onSelect: (Int) -> Unit, +) { + Column(modifier = Modifier.fillMaxWidth()) { + FlowRow(modifier = Modifier.fillMaxWidth()) { + tabs.forEachIndexed { index, tab -> + val isSelected = index == selectedIndex + + val underline = MaterialTheme.colorScheme.primary + + /* + * One box per tab, and the underline is painted inside it rather than + * stacked below it. A HorizontalDivider is fillMaxWidth by default, so + * putting one under each tab made every tab demand the full row width — + * and the row then wrapped after every single tab. + */ + Box( + modifier = Modifier + .heightIn(min = Density.TAB_MIN_HEIGHT) + .background( + if (isSelected) { + MaterialTheme.colorScheme.secondaryContainer + } else { + Color.Transparent + } + ) + .clickable { onSelect(index) } + .drawBehind { + if (isSelected) { + val thickness = 2.dp.toPx() + drawRect( + color = underline, + topLeft = Offset(0f, size.height - thickness), + size = Size(size.width, thickness), + ) + } + } + .padding(horizontal = Density.TAB_HORIZONTAL_PADDING, vertical = 6.dp), + contentAlignment = Alignment.Center, + ) { + Text( + tab.title(), + style = MaterialTheme.typography.bodyMedium, + maxLines = 1, + color = if (isSelected) { + MaterialTheme.colorScheme.onSecondaryContainer + } else { + MaterialTheme.colorScheme.onSurface + }, + ) + } + } + } + + HorizontalDivider(thickness = Density.HAIRLINE) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/SnippetContextMenu.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/SnippetContextMenu.kt new file mode 100644 index 00000000..5a6a8f23 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/SnippetContextMenu.kt @@ -0,0 +1,30 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.ContextMenuArea +import androidx.compose.foundation.ContextMenuItem +import androidx.compose.runtime.Composable + +/** + * The right-click menu of the station list and the message tables: one entry per + * configured snippet, appended to the message field when chosen. + * + * The same roster is reachable three ways and all three behave differently — see + * [ChatInputState.appendSnippet]. This is the one that appends the snippet alone. + * + * @param snippets the configured snippets, in the operator's own order + */ +@Composable +fun SnippetContextMenu( + snippets: List, + state: ChatInputState, + content: @Composable () -> Unit, +) { + ContextMenuArea( + items = { + snippets.map { snippet -> + ContextMenuItem(snippet) { state.appendSnippet(snippet) } + } + }, + content = content, + ) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/SplitterPane.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/SplitterPane.kt new file mode 100644 index 00000000..4a728496 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/SplitterPane.kt @@ -0,0 +1,136 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.background +import androidx.compose.foundation.gestures.detectDragGestures +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.input.pointer.PointerIcon +import androidx.compose.ui.input.pointer.pointerHoverIcon +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.material3.MaterialTheme +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.dp +import java.awt.Cursor + +/** Which way the panes are stacked. */ +enum class SplitterOrientation { HORIZONTAL, VERTICAL } + +/** + * A splitter with draggable dividers, because Compose Multiplatform has none. + * + * The dividers look like the column handles of the tables — a hairline to see, a wider + * area to grab — so the two things an operator can drag in this window feel the same. + * + * @param panes one composable per pane; there is one divider less than there are panes. + * Must be as many as [SplitterState.paneCount] — a mismatch lays out silently + * wrong rather than failing, which is what MainWindowSplitterDefaultsTest guards + * for the three splitters of the main window. + */ +@Composable +fun SplitterPane( + state: SplitterState, + orientation: SplitterOrientation, + panes: List<@Composable () -> Unit>, + modifier: Modifier = Modifier, +) { + BoxWithConstraints(modifier) { + val density = LocalDensity.current + val handlePx = with(density) { Density.COLUMN_HANDLE_WIDTH.toPx() } + val fullPx = with(density) { + if (orientation == SplitterOrientation.HORIZONTAL) maxWidth.toPx() else maxHeight.toPx() + } + + /* + * The handles are siblings of the panes, so what the panes share is what is left + * after them. The same span drives the drag, which keeps the divider under the + * cursor rather than drifting from it by a handle width per divider. + */ + val totalPx = SplitterState.availableFor(fullPx, handlePx, state.paneCount) + val sizes = state.paneSizes(totalPx) + + val body: @Composable () -> Unit = { + panes.forEachIndexed { index, pane -> + val sizeDp = with(density) { sizes.getOrElse(index) { 0f }.toDp() } + + Box( + if (orientation == SplitterOrientation.HORIZONTAL) { + Modifier.width(sizeDp).fillMaxHeight() + } else { + Modifier.height(sizeDp).fillMaxWidth() + }, + ) { + pane() + } + + if (index < panes.size - 1) { + SplitterHandle( + state = state, + index = index, + orientation = orientation, + totalPx = totalPx, + ) + } + } + } + + if (orientation == SplitterOrientation.HORIZONTAL) { + Row(Modifier.fillMaxWidth().fillMaxHeight()) { body() } + } else { + Column(Modifier.fillMaxWidth().fillMaxHeight()) { body() } + } + } +} + +/** + * One divider. The drag is converted to a fraction of the whole before it reaches the + * state, which is what keeps the stored value independent of the screen it was set on. + */ +@Composable +private fun SplitterHandle( + state: SplitterState, + index: Int, + orientation: SplitterOrientation, + totalPx: Float, +) { + val horizontal = orientation == SplitterOrientation.HORIZONTAL + val cursor = if (horizontal) Cursor.E_RESIZE_CURSOR else Cursor.N_RESIZE_CURSOR + + Box( + modifier = Modifier + .then( + if (horizontal) Modifier.width(Density.COLUMN_HANDLE_WIDTH).fillMaxHeight() + else Modifier.height(Density.COLUMN_HANDLE_WIDTH).fillMaxWidth(), + ) + .pointerHoverIcon(PointerIcon(Cursor(cursor))) + .pointerInput(index, totalPx) { + detectDragGestures( + onDragEnd = { state.dragFinished() }, + onDragCancel = { state.dragFinished() }, + ) { _, dragAmount -> + if (totalPx <= 0f) return@detectDragGestures + val delta = if (horizontal) dragAmount.x else dragAmount.y + val current = state.positions.getOrElse(index) { 0f } + state.drag(index, current + delta / totalPx, totalPx) + } + }, + contentAlignment = Alignment.Center, + ) { + Box( + modifier = Modifier + .then( + if (horizontal) Modifier.width(Density.HAIRLINE).fillMaxHeight() + else Modifier.height(Density.HAIRLINE).fillMaxWidth(), + ) + .background(MaterialTheme.colorScheme.outline), + ) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/SplitterState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/SplitterState.kt new file mode 100644 index 00000000..dd962c65 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/SplitterState.kt @@ -0,0 +1,109 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.mutableStateListOf + +/** + * The divider positions of one splitter, as fractions of its length. + * + * Compose Multiplatform brings no SplitPane, so this is ours. The positions are a + * setting, not decoration: an operator arranges the main window once for their screen + * and expects it back at the next contest. + * + * @param paneCount how many panes the splitter holds; there is one divider less + * @param stored the remembered positions, used only when they fit and make sense + * @param minPanePx the smallest a pane may be dragged to, so nothing vanishes by accident + * @param save called on release with the positions to remember — never during a drag, + * because the JavaFX version wrote the profile to disk on every pixel of one + */ +class SplitterState( + val paneCount: Int, + stored: DoubleArray, + private val minPanePx: Float = DEFAULT_MIN_PANE_PX, + private val save: (DoubleArray) -> Unit, +) { + + private val dividerCount = (paneCount - 1).coerceAtLeast(0) + + private val livePositions = mutableStateListOf().apply { + addAll(sanitize(stored, dividerCount)) + } + + /** What the draw reads. Compose state, so a drag reaches the screen. */ + val positions: List get() = livePositions + + private var savedPositions: List = livePositions.toList() + + /** + * Moves one divider, held off its neighbours and off the minimum pane size. + * + * @param to the wanted position as a fraction of the whole + * @param totalPx the splitter's length, needed to turn the minimum into a fraction + */ + fun drag(index: Int, to: Float, totalPx: Float) { + if (index !in 0 until dividerCount) return + + val minFraction = if (totalPx > 0f) minPanePx / totalPx else 0f + val lowerBound = (if (index == 0) 0f else livePositions[index - 1]) + minFraction + val upperBound = (if (index == dividerCount - 1) 1f else livePositions[index + 1]) - minFraction + + // A window too narrow for the minimums would give an empty range; splitting the + // remaining room is better than laying out nothing. + livePositions[index] = if (lowerBound > upperBound) { + (lowerBound + upperBound) / 2f + } else { + to.coerceIn(lowerBound, upperBound) + } + } + + /** Remembers the positions, but only if the drag actually moved something. */ + fun dragFinished() { + val current = livePositions.toList() + if (current == savedPositions) return + savedPositions = current + save(DoubleArray(current.size) { current[it].toDouble() }) + } + + /** The pane lengths for a given splitter length; they always add up to the whole. */ + fun paneSizes(totalPx: Float): List { + if (paneCount <= 1) return listOf(totalPx) + val edges = buildList { + add(0f) + livePositions.forEach { add(it * totalPx) } + add(totalPx) + } + return (0 until paneCount).map { edges[it + 1] - edges[it] } + } + + companion object { + + /** Enough to still see a table header and grab the divider again. */ + const val DEFAULT_MIN_PANE_PX = 24f + + /** + * How much length the panes may share, once the divider handles have taken theirs. + * + * The panes and the handles are laid out as siblings, so distributing the whole + * length among the panes overflows the splitter by one handle width per divider — + * 20 dp for the five-pane message column, enough to push the bottom pane off the + * edge. Never negative: a splitter smaller than its own handles hands out nothing. + */ + fun availableFor(totalPx: Float, dividerPx: Float, paneCount: Int): Float { + val dividerCount = (paneCount - 1).coerceAtLeast(0) + return (totalPx - dividerPx * dividerCount).coerceAtLeast(0f) + } + + /** + * The remembered positions are used only when there are exactly as many as there + * are dividers, each inside the pane and in ascending order. Anything else is a + * profile from an older layout, and an even split beats a window whose panes have + * no size. + */ + internal fun sanitize(stored: DoubleArray, dividerCount: Int): List { + val evenSplit = (1..dividerCount).map { it.toFloat() / (dividerCount + 1) } + if (stored.size != dividerCount) return evenSplit + if (stored.any { !it.isFinite() || it <= 0.0 || it >= 1.0 }) return evenSplit + if (stored.toList() != stored.sorted()) return evenSplit + return stored.map { it.toFloat() } + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/StationColumns.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/StationColumns.kt new file mode 100644 index 00000000..13f5ca8e --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/StationColumns.kt @@ -0,0 +1,154 @@ +package kst4contest.view.compose + +import kst4contest.model.ChatMember +import java.util.EnumSet + +/** + * The columns of the station list. + * + * The ids are not free to choose: they are the operator's stored column widths, so + * renaming one loses their layout without a word. They are kept exactly as + * `TableLayoutManager.column(...)` registered them. + * + * Every value survives a half-filled station. These rows come off the wire, a field + * can be missing, and a crash in the station list during a contest is the worst + * possible moment for one. + * + * @param tropoOf the reachability the controller computes; not carried by the row + * @param priorityScoreOf the score the row is coloured by, also computed outside + * @param formatBand formats a single band cell (worked / new / etc.) + * @param activeBands the bands the operator has enabled in settings; only these + * get a worked column. Matches the JavaFX behaviour where the column is + * only added when `isStn_bandActiveXX()` returns true. + */ +object StationColumns { + + /** The heading the ten worked columns sit under. */ + const val WORKED_GROUP = "worked" + + fun all( + tropoOf: (ChatMember) -> String, + priorityScoreOf: (ChatMember) -> Double, + formatBand: (ChatMember, kst4contest.model.Band, Boolean) -> String, + activeBands: EnumSet = EnumSet.allOf(kst4contest.model.Band::class.java), + ): List> = buildList { + add(DataColumn(id = "callsign", title = { kst4contest.view.i18n.CurrentStrings.get().columnCallsign }, value = { it.callSign.orEmpty() })) + add(DataColumn(id = "name", title = { kst4contest.view.i18n.CurrentStrings.get().columnName }, value = { it.name.orEmpty() })) + add(DataColumn(id = "qra", title = "QRA", value = { it.qra.orEmpty() }, weight = 0.8f)) + add(DataColumn( + id = "qrb", + title = "QRB", + value = { it.qrb?.toInt()?.toString().orEmpty() }, + comparator = compareBy { it.qrb ?: 0.0 }, + weight = 0.6f, + )) + add(DataColumn( + id = "qtf", + title = "QTF", + value = { it.getQTFdirection()?.let { d -> String.format("%.2f°", d) }.orEmpty() }, + comparator = compareBy { it.getQTFdirection() ?: 0.0 }, + weight = 0.7f, + )) + add(DataColumn(id = "qrg", title = "QRG", value = { it.frequency?.get().orEmpty() }, weight = 0.8f)) + add(DataColumn( + id = "airscout", + title = "AP [minutes / pot%]", + value = { AirplaneCell.format(it.airPlaneReflectInfo) }, + accent = { _, rendered -> AirplaneCell.accentFor(rendered) }, + weight = 1.4f, + )) + add(DataColumn(id = "tropo", title = "Tropo", value = tropoOf, weight = 0.7f)) + add(DataColumn( + id = "score", + title = "Score", + value = { priorityScoreOf(it).toInt().toString() }, + comparator = compareBy { priorityScoreOf(it) }, + weight = 0.6f, + )) + add(DataColumn( + id = "activity", + title = "Act", + value = { minutesSince(it.activityTimeLastInEpoch) }, + comparator = compareBy { it.activityTimeLastInEpoch }, + weight = 0.5f, + )) + + /* Individual band columns only when the operator has that band enabled. */ + if (kst4contest.model.Band.B_50 in activeBands) + add(workedColumn("band-50", "50") { formatBand(it, kst4contest.model.Band.B_50, it.isWorked50) }) + if (kst4contest.model.Band.B_70 in activeBands) + add(workedColumn("band-70", "70") { formatBand(it, kst4contest.model.Band.B_70, it.isWorked70) }) + if (kst4contest.model.Band.B_144 in activeBands) + add(workedColumn("band-144", "144") { formatBand(it, kst4contest.model.Band.B_144, it.isWorked144) }) + if (kst4contest.model.Band.B_432 in activeBands) + add(workedColumn("band-432", "432") { formatBand(it, kst4contest.model.Band.B_432, it.isWorked432) }) + if (kst4contest.model.Band.B_1296 in activeBands) + add(workedColumn("band-1296", "23") { formatBand(it, kst4contest.model.Band.B_1296, it.isWorked1240) }) + if (kst4contest.model.Band.B_2320 in activeBands) + add(workedColumn("band-2320", "13") { formatBand(it, kst4contest.model.Band.B_2320, it.isWorked2300) }) + if (kst4contest.model.Band.B_3400 in activeBands) + add(workedColumn("band-3400", "9") { formatBand(it, kst4contest.model.Band.B_3400, it.isWorked3400) }) + if (kst4contest.model.Band.B_5760 in activeBands) + add(workedColumn("band-5760", "6") { formatBand(it, kst4contest.model.Band.B_5760, it.isWorked5600) }) + if (kst4contest.model.Band.B_10G in activeBands) + add(workedColumn("band-10g", "3") { formatBand(it, kst4contest.model.Band.B_10G, it.isWorked10G) }) + + /* Worked-any is always shown, and belongs under the 'worked' group header just like in JavaFX. */ + add(workedColumn("worked-any", "wkdany", group = WORKED_GROUP, weight = 0.7f) { if (it.isWorked) "X" else "" }) + + add(DataColumn(id = "not-qrv", title = "NOT QRV @", value = { qrvBands(it, activeBands) }, weight = 1.6f)) + add(DataColumn( + id = "category", + title = "Category", + value = { member -> + member.chatCategory?.let { it.getChatCategoryName(it.categoryNumber) }.orEmpty() + }, + weight = 1.2f, + )) + } + + /** A cross or nothing, and under the shared heading. */ + private fun workedColumn( + id: String, + title: String, + group: String? = WORKED_GROUP, + weight: Float = 0.35f, + worked: (ChatMember) -> String, + ): DataColumn = DataColumn( + id = id, + title = title, + value = worked, + weight = weight, + group = group, + ) + + /** How long ago the station was last heard, in whole minutes. */ + private fun minutesSince(epochSeconds: Long): String { + if (epochSeconds <= 0L) { + return "" + } + + val seconds = (System.currentTimeMillis() / 1000L) - epochSeconds + + return if (seconds < 0) "" else (seconds / 60L).toString() + } + + /** + * The bands the station is **not** on, which is what the heading says. + * + * Every QRV flag starts true — a station is assumed to be on every band until it + * says otherwise — so this column is empty for most rows and fills as the operator + * or the server marks bands off. + */ + private fun qrvBands(member: ChatMember, activeBands: Set): String = buildString { + if (!member.isQrv50 && kst4contest.model.Band.B_50 in activeBands) append("6m ") + if (!member.isQrv70 && kst4contest.model.Band.B_70 in activeBands) append("4m ") + if (!member.isQrv144 && kst4contest.model.Band.B_144 in activeBands) append("2m ") + if (!member.isQrv432 && kst4contest.model.Band.B_432 in activeBands) append("70cm ") + if (!member.isQrv1240 && kst4contest.model.Band.B_1296 in activeBands) append("23cm ") + if (!member.isQrv2300 && kst4contest.model.Band.B_2320 in activeBands) append("13cm ") + if (!member.isQrv3400 && kst4contest.model.Band.B_3400 in activeBands) append("9cm ") + if (!member.isQrv5600 && kst4contest.model.Band.B_5760 in activeBands) append("6cm ") + if (!member.isQrv10G && kst4contest.model.Band.B_10G in activeBands) append("3cm ") + }.trim() +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/StationFilterBar.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/StationFilterBar.kt new file mode 100644 index 00000000..6d11792c --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/StationFilterBar.kt @@ -0,0 +1,282 @@ +package kst4contest.view.compose + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.luminance +import androidx.compose.ui.unit.dp + +/** + * The station filter bar above the station table. + * + * Laid out to match the JavaFX original: three tight rows of controls separated + * by thin vertical rules between logical groups. + */ +@OptIn(ExperimentalLayoutApi::class) +@Composable +fun StationFilterBar( + filters: StationFilterState, + activeBands: Set, + onChanged: () -> Unit, + modifier: Modifier = Modifier, +) { + val strings = LocalStrings.current + + Column( + modifier = modifier.fillMaxWidth().padding(horizontal = 2.dp, vertical = 1.dp), + verticalArrangement = Arrangement.spacedBy(1.dp), + ) { + // ROW 1: Reset | QRB | QTF + bearings + Row( + modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Min), + horizontalArrangement = Arrangement.spacedBy(4.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + // Reset filters + FilterButton(strings.filterReset, on = false, isAccent = true) { + filters.reset() + onChanged() + } + + VerticalSeparator() + + // QRB checkbox + field + CompactCheckbox( + checked = filters.maxQrbEnabled, + onCheckedChange = { + filters.maxQrbEnabled = it + onChanged() + }, + ) + Text(strings.filterShowOnlyQrb, style = MaterialTheme.typography.bodySmall) + CompactTextField( + value = if (filters.maxQrbKm.rem(1) == 0.0) filters.maxQrbKm.toInt().toString() else filters.maxQrbKm.toString(), + onValueChange = { + val parsed = it.toDoubleOrNull() + if (parsed != null) { + filters.maxQrbKm = parsed + if (filters.maxQrbEnabled) onChanged() + } else if (it.isEmpty()) { + filters.maxQrbKm = 0.0 + if (filters.maxQrbEnabled) onChanged() + } + }, + modifier = Modifier.width(50.dp) + ) + + VerticalSeparator() + + // QTF checkbox + field + bearings + CompactCheckbox( + checked = filters.qtfEnabled, + onCheckedChange = { + filters.qtfEnabled = it + onChanged() + }, + ) + Text(strings.filterShowOnlyQtf, style = MaterialTheme.typography.bodySmall) + CompactTextField( + value = if (filters.qtfDegrees.rem(1) == 0.0) filters.qtfDegrees.toInt().toString() else filters.qtfDegrees.toString(), + onValueChange = { + val parsed = it.toDoubleOrNull() + if (parsed != null) { + filters.qtfDegrees = parsed + filters.bearing = null + if (filters.qtfEnabled) onChanged() + } else if (it.isEmpty()) { + filters.qtfDegrees = 0.0 + filters.bearing = null + if (filters.qtfEnabled) onChanged() + } + }, + modifier = Modifier.width(50.dp) + ) + Text("± BW/2", style = MaterialTheme.typography.bodySmall) + + Bearing.entries.forEach { bearing -> + FilterButton(bearing.name, on = filters.bearing == bearing) { + filters.toggleBearing(bearing) + onChanged() + } + } + } + + // ROW 2: Find | Hide worked: wkd 50 70 144 432 | Inactive stations | Only new grids + Row( + modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Min), + horizontalArrangement = Arrangement.spacedBy(4.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + CompactTextField( + value = filters.searchText, + onValueChange = { + filters.searchText = it + onChanged() + }, + placeholder = strings.filterFind, + modifier = Modifier.width(90.dp), + ) + + VerticalSeparator() + + Text(strings.filterHideWorked, style = MaterialTheme.typography.bodySmall) + FilterButton("wkdany", on = filters.hideWorkedAny) { + filters.hideWorkedAny = !filters.hideWorkedAny + onChanged() + } + WorkedBandFilter.entries.forEach { band -> + if (band.modelBand in activeBands) { + FilterButton(band.label, on = filters.isHideWorkedOn(band)) { + filters.setHideWorkedOn(band, !filters.isHideWorkedOn(band)) + onChanged() + } + } + } + + VerticalSeparator() + + FilterButton(strings.filterInactiveStations, on = filters.hideInactive) { + filters.hideInactive = !filters.hideInactive + onChanged() + } + FilterButton(strings.filterOnlyNewGrids, on = filters.onlyNewGrids) { + filters.onlyNewGrids = !filters.onlyNewGrids + onChanged() + } + } + + // ROW 3: Grid color | Tropo | New bands | AS next 5m + Row( + modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Min), + horizontalArrangement = Arrangement.spacedBy(4.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + FilterButton(strings.filterGridColour, on = filters.gridColouring) { + filters.gridColouring = !filters.gridColouring + } + FilterButton(strings.filterTropo, on = filters.tropoReachable) { + filters.tropoReachable = !filters.tropoReachable + onChanged() + } + FilterButton(strings.filterNewBands, on = filters.newBands) { + filters.newBands = !filters.newBands + onChanged() + } + FilterButton("AS next 5m", on = filters.airScoutNext5Min) { + filters.airScoutNext5Min = !filters.airScoutNext5Min + onChanged() + } + } + } +} + +/** + * A compact toggle button that does NOT use Material 3 Button (which enforces 40dp). + * Instead it is a plain clickable Box with border and background, matching the tiny + * JavaFX filter buttons. + */ +@Composable +private fun FilterButton(label: String, on: Boolean, isAccent: Boolean = false, onClick: () -> Unit) { + val palette = LocalJavaFxPalette.current + val isDark = palette.windowBackground.luminance() < 0.5f + + val accentBrush = if (isDark) { + androidx.compose.ui.graphics.Brush.linearGradient( + colors = listOf(Color(0xFF008000), Color(0xFF90EE90)) + ) + } else { + androidx.compose.ui.graphics.Brush.linearGradient( + colors = listOf(Color(0xFF00FFFF), Color(0xFFFF99FF)) + ) + } + + val bgModifier = if (isAccent) { + Modifier.background(accentBrush, Density.BUTTON_SHAPE) + } else { + val bg = if (on) MaterialTheme.colorScheme.primary else Color.Transparent + Modifier.background(bg, Density.BUTTON_SHAPE) + } + + val fg = if (isAccent) Color(0xFF395306) else if (on) MaterialTheme.colorScheme.onPrimary else MaterialTheme.colorScheme.onSurface + val borderColor = if (isAccent) Color.Transparent else if (on) MaterialTheme.colorScheme.primary else MaterialTheme.colorScheme.outline + + Box( + modifier = Modifier + .heightIn(min = 20.dp) + .then(if (borderColor != Color.Transparent) Modifier.border(Density.HAIRLINE, borderColor, Density.BUTTON_SHAPE) else Modifier) + .then(bgModifier) + .clickable { onClick() } + .padding(horizontal = 6.dp, vertical = 2.dp), + contentAlignment = Alignment.Center, + ) { + Text(label, style = MaterialTheme.typography.bodySmall, color = fg, maxLines = 1) + } +} + +/** Thin vertical separator matching JavaFX's group dividers. */ +@Composable +private fun VerticalSeparator() { + Box( + modifier = Modifier + .width(Density.HAIRLINE) + .fillMaxHeight() + .background(MaterialTheme.colorScheme.outline), + ) +} + + +@Composable +private fun CompactTextField( + value: String, + onValueChange: (String) -> Unit, + placeholder: String = "", + modifier: Modifier = Modifier, +) { + BasicTextField( + value = value, + onValueChange = onValueChange, + singleLine = true, + textStyle = MaterialTheme.typography.bodySmall.copy(color = MaterialTheme.colorScheme.onSurface), + decorationBox = { innerTextField -> + Box( + modifier = modifier + .background(MaterialTheme.colorScheme.surfaceVariant, Density.BUTTON_SHAPE) + .border(1.dp, MaterialTheme.colorScheme.outline, Density.BUTTON_SHAPE) + .padding(horizontal = 4.dp, vertical = 2.dp), + contentAlignment = Alignment.CenterStart, + ) { + if (value.isEmpty() && placeholder.isNotEmpty()) { + Text( + placeholder, + style = MaterialTheme.typography.bodySmall.copy( + color = MaterialTheme.colorScheme.onSurfaceVariant, + ), + ) + } + innerTextField() + } + }, + ) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/StationFilterState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/StationFilterState.kt new file mode 100644 index 00000000..b2f75d08 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/StationFilterState.kt @@ -0,0 +1,161 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateMapOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue + +/** + * The filters the station list can have switched on. + * + * One entry per predicate the JavaFX bar added to the controller. The controller does + * the filtering — it has since Etappe 2 — so this names which predicates should be + * attached, and nothing more. + */ +enum class StationFilter { + ONLY_NEW_GRIDS, + TROPO_REACHABLE, + NEW_BANDS, + AIRSCOUT_NEXT_5_MIN, + MAX_QRB, + QTF, + SEARCH_TEXT, + HIDE_INACTIVE, + HIDE_WORKED_ANY, + HIDE_WORKED_50, + HIDE_WORKED_70, + HIDE_WORKED_144, + HIDE_WORKED_432, + HIDE_WORKED_23, + HIDE_WORKED_13, + HIDE_WORKED_9, + HIDE_WORKED_6, + HIDE_WORKED_3, +} + +/** The bands the "hide worked" row offers, under the labels the bar shows. */ +enum class WorkedBandFilter(val label: String, val filter: StationFilter, val modelBand: kst4contest.model.Band) { + B_50("50", StationFilter.HIDE_WORKED_50, kst4contest.model.Band.B_50), + B_70("70", StationFilter.HIDE_WORKED_70, kst4contest.model.Band.B_70), + B_144("144", StationFilter.HIDE_WORKED_144, kst4contest.model.Band.B_144), + B_432("432", StationFilter.HIDE_WORKED_432, kst4contest.model.Band.B_432), + B_23("23", StationFilter.HIDE_WORKED_23, kst4contest.model.Band.B_1296), + B_13("13", StationFilter.HIDE_WORKED_13, kst4contest.model.Band.B_2320), + B_9("9", StationFilter.HIDE_WORKED_9, kst4contest.model.Band.B_3400), + B_6("6", StationFilter.HIDE_WORKED_6, kst4contest.model.Band.B_5760), + B_3("3", StationFilter.HIDE_WORKED_3, kst4contest.model.Band.B_10G), +} + +/** + * The eight bearing buttons, with the degrees each writes into the QTF field. + * + * They were one ToggleGroup, so only one can be picked, and picking one filters + * nothing by itself — it sets a bearing the QTF filter uses once that is switched on. + */ +enum class Bearing(val degrees: Double) { + N(0.0), NE(45.0), E(90.0), SE(135.0), S(180.0), SW(225.0), W(270.0), NW(315.0) +} + +/** + * What the filter bar has switched on. + * + * Deliberately free of the drawing: its 25 toggles are not 25 states, and which of + * them mean what is worth pinning where it can be tested. Getting it wrong puts a + * station in front of the operator that their filter excludes, or hides one it does + * not — and in a contest that is a missed contact either way. + */ +class StationFilterState { + + private val switched = mutableStateMapOf() + + var onlyNewGrids: Boolean + get() = isOn(StationFilter.ONLY_NEW_GRIDS) + set(value) = switch(StationFilter.ONLY_NEW_GRIDS, value) + + var tropoReachable: Boolean + get() = isOn(StationFilter.TROPO_REACHABLE) + set(value) = switch(StationFilter.TROPO_REACHABLE, value) + + var newBands: Boolean + get() = isOn(StationFilter.NEW_BANDS) + set(value) = switch(StationFilter.NEW_BANDS, value) + + var airScoutNext5Min: Boolean + get() = isOn(StationFilter.AIRSCOUT_NEXT_5_MIN) + set(value) = switch(StationFilter.AIRSCOUT_NEXT_5_MIN, value) + + var hideInactive: Boolean + get() = isOn(StationFilter.HIDE_INACTIVE) + set(value) = switch(StationFilter.HIDE_INACTIVE, value) + + var hideWorkedAny: Boolean + get() = isOn(StationFilter.HIDE_WORKED_ANY) + set(value) = switch(StationFilter.HIDE_WORKED_ANY, value) + + var maxQrbEnabled: Boolean + get() = isOn(StationFilter.MAX_QRB) + set(value) = switch(StationFilter.MAX_QRB, value) + + /** Only meaningful while [maxQrbEnabled]; a distance alone filters nothing. */ + var maxQrbKm: Double by mutableStateOf(0.0) + + var qtfEnabled: Boolean + get() = isOn(StationFilter.QTF) + set(value) = switch(StationFilter.QTF, value) + + var qtfDegrees: Double by mutableStateOf(0.0) + + var bearing: Bearing? by mutableStateOf(null) + + /** + * Colours the locator cell by grid status. **Not a filter** — the JavaFX toggle + * sat among the filter buttons but only redrew the table, and a station must not + * disappear because of it. + */ + var gridColouring: Boolean by mutableStateOf(false) + + private var searchTextValue: String by mutableStateOf("") + + var searchText: String + get() = searchTextValue + set(value) { + searchTextValue = value + /* Blank is not a search: leaving it on would hide every station. */ + switch(StationFilter.SEARCH_TEXT, value.isNotBlank()) + } + + /** The filters that should be attached to the controller right now. */ + val activeFilters: Set + get() = switched.filterValues { it }.keys + + fun isOn(filter: StationFilter): Boolean = switched[filter] == true + + fun setHideWorkedOn(band: WorkedBandFilter, hide: Boolean) = switch(band.filter, hide) + + fun isHideWorkedOn(band: WorkedBandFilter): Boolean = isOn(band.filter) + + /** Picks one bearing and writes its degrees, or deselects if already selected. + * Mirrors JavaFX ToggleGroup behavior which also toggles the QTF filter checkbox. */ + fun toggleBearing(direction: Bearing) { + if (bearing == direction) { + bearing = null + qtfEnabled = false + } else { + bearing = direction + qtfDegrees = direction.degrees + qtfEnabled = true + } + } + + private fun switch(filter: StationFilter, on: Boolean) { + if (on) switched[filter] = true else switched.remove(filter) + } + + fun reset() { + switched.clear() + searchText = "" + qtfDegrees = 0.0 + bearing = null + gridColouring = false + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/StationRowStyle.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/StationRowStyle.kt new file mode 100644 index 00000000..8d70b7a6 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/StationRowStyle.kt @@ -0,0 +1,42 @@ +package kst4contest.view.compose + +import androidx.compose.ui.graphics.Color +import kst4contest.model.ChatMember + +/** + * The row colouring of the station table (chat members). + * + * Mimics JavaFX Kst4ContestApplication.java:2663 + */ +object StationRowStyle { + + // > 1000 = NUCLEAR (Imminent Sked) -> Blinking Red (simulated here with solid red) + val SCORE_NUCLEAR_BG = Color(0xFFFF4D4D) + val SCORE_NUCLEAR_FG = Color.White + + // > 200 = High Prio (AirScout / Good Sked) -> Orange + // > 100 = Medium Prio (Unworked / New Multi) -> Light Yellow + // <= 0 = Low Prio / Not Reachable -> Greyed out text + + // We only hardcode light mode colors here to be safe and match JavaFX for now. + // In JavaFX it checked `isGUI_darkModeActive()`, but Compose might have its own dark mode check. + val SCORE_HIGH_BG = Color(0xFFFFCC00) + val SCORE_HIGH_FG = Color.Black + + val SCORE_MEDIUM_BG = Color(0xFFFFFFCC) + val SCORE_MEDIUM_FG = Color.Black + + val SCORE_LOW_FG = Color(0xFFAAAAAA) + + fun accentFor(member: ChatMember, isDark: Boolean = false): CellAccent? { + val score = member.currentPriorityScore + + return when { + score > 1000 -> CellAccent(background = SCORE_NUCLEAR_BG, foreground = SCORE_NUCLEAR_FG) + score >= 200 -> CellAccent(background = if (isDark) Color(0xFFCC6600) else SCORE_HIGH_BG, foreground = SCORE_HIGH_FG) + score >= 100 -> CellAccent(background = if (isDark) Color(0xFF888800) else SCORE_MEDIUM_BG, foreground = SCORE_MEDIUM_FG) + score <= 0 -> CellAccent(background = null, foreground = if (isDark) Color(0xFF666666) else SCORE_LOW_FG) + else -> null + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/StatusBar.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/StatusBar.kt new file mode 100644 index 00000000..0eb2dbfa --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/StatusBar.kt @@ -0,0 +1,242 @@ +package kst4contest.view.compose + +import androidx.compose.animation.core.Animatable +import androidx.compose.animation.core.keyframes +import androidx.compose.animation.core.repeatable +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.TooltipArea +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.ExperimentalLayoutApi +import androidx.compose.foundation.layout.FlowRow +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import kotlinx.coroutines.delay +import kst4contest.controller.On4KstConnectionState + +/** + * The status bar along the top of the main window. + * + * In JavaFX this was one FlowPane holding the menu bar and the indicators side by side. + * Compose puts the menu bar in the window's own scope (see [Kst4ContestMenuBar]), so + * only the indicators are left here — which is also what finally makes the bar wrap + * properly on a narrow window instead of pushing the badges out of sight. + * + * Nothing in this bar is clickable. The three indicators were mouse-transparent and + * non-focusable in JavaFX and stay that way: the operator is typing into the chat, and a + * status badge must never take the keyboard. The background-thread buttons were ordinary + * focusable Buttons there, with no action attached — they are drawn as plain labels here, + * which is what they always behaved like. + */ +@OptIn(ExperimentalLayoutApi::class) +@Composable +fun StatusBar( + connectionState: On4KstConnectionState?, + connectionDetail: String?, + skedNotice: BlinkingNotice, + bandUpgradeNotice: BlinkingNotice, + threadButtons: ThreadStatusButtons, + showConnectionBadge: Boolean = true, + modifier: Modifier = Modifier, +) { + FlowRow( + modifier = modifier.padding(horizontal = 4.dp, vertical = 2.dp), + horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP), + verticalArrangement = Arrangement.spacedBy(2.dp), + ) { + // On macOS the connection state lives in the system menu bar instead. + if (showConnectionBadge) { + ConnectionBadgeView(connectionState, connectionDetail) + } + + BlinkingNoticeView(skedNotice, SKED_BACKGROUND) + BlinkingNoticeView(bandUpgradeNotice, BAND_UPGRADE_BACKGROUND) + + threadButtons.buttons.forEach { ThreadStatusButtonView(it) } + } +} + +/** rgba(255,0,255,0.85) — the sked reminder, the one colour nothing else in the UI uses. */ +private val SKED_BACKGROUND = Color(0xD9FF00FF) + +/** rgba(255,255,0,0.85) — the band upgrade hint. */ +private val BAND_UPGRADE_BACKGROUND = Color(0xD9FFFF00) + +private val NOTICE_SHAPE = RoundedCornerShape(6.dp) +private val NOTICE_PADDING = PaddingValues(horizontal = 8.dp, vertical = 2.dp) + +/** + * The connection badge, at least as large as JavaFX pinned it (44 × 22). + * + * A minimum and not a fixed size: JavaFX also set setMaxSize(44,22), which this does not, so + * a larger base font grows the badge rather than clipping its label. The three labels are + * within a character of each other, so the bar barely reflows either way. + */ +@OptIn(ExperimentalFoundationApi::class) +@Composable +private fun ConnectionBadgeView(state: On4KstConnectionState?, detail: String?) { + val badge = ConnectionIndicator.badgeFor(state) + val colors = badgeColors(badge) + + TooltipArea(tooltip = { TooltipCard(ConnectionIndicator.tooltipFor(state, detail)) }) { + Box( + modifier = Modifier + .defaultMinSize(minWidth = 44.dp, minHeight = 22.dp) + .background(colors.background, NOTICE_SHAPE) + .border(2.dp, colors.border, NOTICE_SHAPE) + .padding(horizontal = 5.dp, vertical = 1.dp), + contentAlignment = Alignment.Center, + ) { + Text( + text = badge.label, + color = colors.text, + fontSize = 10.sp, + fontWeight = FontWeight.Bold, + maxLines = 1, + ) + } + } +} + +private class BadgeColors(val background: Color, val border: Color, val text: Color) + +/** + * The badge colours are deliberately not taken from the theme. They are traffic-light + * colours and have to mean the same thing in both designs; a red that turns into the + * dark theme's accent would be unreadable as a warning. + */ +private fun badgeColors(badge: ConnectionBadge): BadgeColors = when (badge) { + ConnectionBadge.ONLINE -> BadgeColors(Color(0xFF238636), Color(0xFF56D364), Color.White) + ConnectionBadge.BUSY -> BadgeColors(Color(0xFFFFB300), Color(0xFFFFE082), Color(0xFF1B1B1B)) + ConnectionBadge.OFFLINE -> BadgeColors(Color(0xFFD50000), Color(0xFFFF6B6B), Color.White) +} + +/** + * A notice that blinks and then removes itself. + * + * The blink is the JavaFX timeline: bright, quarter-dim after 250 ms, bright again at + * 500 ms, twenty-four times, then gone. It is long enough to catch the eye of someone + * looking at the chat, and short enough not to become furniture. + */ +@OptIn(ExperimentalFoundationApi::class) +@Composable +private fun BlinkingNoticeView(notice: BlinkingNotice, background: Color) { + if (!notice.visible) return + + val alpha = remember { Animatable(1f) } + + LaunchedEffect(notice.revision) { + val generation = notice.revision + try { + alpha.snapTo(1f) + alpha.animateTo( + targetValue = 1f, + animationSpec = repeatable( + iterations = BlinkingNotice.BLINK_CYCLES, + animation = keyframes { + durationMillis = BlinkingNotice.BLINK_CYCLE_MILLIS.toInt() + 1f at 0 + 0.25f at 250 + 1f at BlinkingNotice.BLINK_CYCLE_MILLIS.toInt() + }, + ), + ) + } finally { + // Also on cancellation: a blink cut short by the bar leaving the composition + // would otherwise leave the notice showing for the rest of the session. + notice.hide(generation) + } + } + + TooltipArea(tooltip = { TooltipCard(notice.tooltip) }) { + Box( + modifier = Modifier + .alpha(alpha.value) + .background(background, NOTICE_SHAPE) + .padding(NOTICE_PADDING), + contentAlignment = Alignment.Center, + ) { + Text( + text = notice.text, + color = Color.Black, + fontWeight = FontWeight.Bold, + style = MaterialTheme.typography.labelMedium, + maxLines = 1, + ) + } + } +} + +/** + * One background thread's state. It flashes in the accent colour whenever a message + * arrives, which is how a running worker is told from a stuck one at a glance. + */ +@OptIn(ExperimentalFoundationApi::class) +@Composable +private fun ThreadStatusButtonView(button: ThreadStatusButton) { + LaunchedEffect(button.revision) { + try { + delay(ThreadStatusButtons.HIGHLIGHT_MILLIS) + } finally { + // On cancellation too, so a button that left the composition mid flash does not + // come back still lit. + button.clearHighlight() + } + } + + val scheme = MaterialTheme.colorScheme + val background = if (button.highlighted) scheme.primary else scheme.surfaceVariant + val foreground = if (button.highlighted) scheme.onPrimary else scheme.onSurfaceVariant + + TooltipArea(tooltip = { TooltipCard(button.tooltip) }) { + Box( + modifier = Modifier + .defaultMinSize(minHeight = 22.dp) + .background(background, NOTICE_SHAPE) + .padding(NOTICE_PADDING), + contentAlignment = Alignment.Center, + ) { + Text( + text = button.label, + color = foreground, + style = MaterialTheme.typography.labelMedium, + maxLines = 1, + ) + } + } +} + +/** The tooltips in this bar carry the long text the badges had to cut. */ +@Composable +internal fun TooltipCard(text: String) { + if (text.isBlank()) return + Surface( + color = MaterialTheme.colorScheme.surfaceVariant, + contentColor = MaterialTheme.colorScheme.onSurfaceVariant, + shape = Density.BUTTON_SHAPE, + tonalElevation = 4.dp, + ) { + Text( + text = text, + modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), + style = MaterialTheme.typography.bodySmall, + ) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/StatusIndicatorState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/StatusIndicatorState.kt new file mode 100644 index 00000000..c9344f52 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/StatusIndicatorState.kt @@ -0,0 +1,225 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import kst4contest.controller.On4KstConnectionState +import kst4contest.model.ThreadStateMessage +import java.util.Locale + +/** + * How the connection indicator reads at a glance. + * + * Three badges for nine states: mid contest nobody parses "SYNCING_SECOND_CHAT". What + * the operator needs to know is whether something can be sent right now. + */ +enum class ConnectionBadge(val label: String) { + ONLINE("LINK"), + BUSY("LINK…"), + OFFLINE("LINK!"), +} + +/** The badge, its tooltip and the macOS menu title, all derived from one state. */ +object ConnectionIndicator { + + /** No state at all is the state before the first callback, and that is not a link. */ + fun badgeFor(state: On4KstConnectionState?): ConnectionBadge = + when (state ?: On4KstConnectionState.DISCONNECTED) { + On4KstConnectionState.ONLINE -> ConnectionBadge.ONLINE + + On4KstConnectionState.CONNECTING, + On4KstConnectionState.WAITING_FOR_LOGIN_PROMPT, + On4KstConnectionState.AUTHENTICATING, + On4KstConnectionState.SYNCING_MAIN_CHAT, + On4KstConnectionState.SYNCING_SECOND_CHAT, + On4KstConnectionState.STOPPING -> ConnectionBadge.BUSY + + // A scheduled reconnect is not a working link, so it reads as offline. + On4KstConnectionState.DISCONNECTED, + On4KstConnectionState.RECONNECT_WAIT -> ConnectionBadge.OFFLINE + } + + fun tooltipFor(state: On4KstConnectionState?, detail: String?): String { + val effective = state ?: On4KstConnectionState.DISCONNECTED + return kst4contest.view.i18n.CurrentStrings.get().statusLinkTooltip(effective.name, detailFor(state, detail)) + } + + /** + * The detail line, as its own string. + * + * The tooltip carries it as a second line; the macOS menu carries it as its single + * disabled item, which is the same information reaching the operator by the other route. + */ + fun detailFor(state: On4KstConnectionState?, detail: String?): String { + val effective = state ?: On4KstConnectionState.DISCONNECTED + return if (detail.isNullOrBlank()) effective.name else detail + } + + /** + * Title of the macOS connection state menu, e.g. kst4contest.view.i18n.CurrentStrings.get().statusLinkConnected. + * + * Finer than the badge: in the menu bar there is room to distinguish shutting down + * from connecting, and a reconnect from a dead link. + */ + fun macOsMenuTitle(state: On4KstConnectionState?): String = + when (state ?: On4KstConnectionState.DISCONNECTED) { + On4KstConnectionState.ONLINE -> kst4contest.view.i18n.CurrentStrings.get().statusLinkConnected + On4KstConnectionState.CONNECTING, + On4KstConnectionState.WAITING_FOR_LOGIN_PROMPT, + On4KstConnectionState.AUTHENTICATING, + On4KstConnectionState.SYNCING_MAIN_CHAT, + On4KstConnectionState.SYNCING_SECOND_CHAT -> kst4contest.view.i18n.CurrentStrings.get().statusLinkConnecting + On4KstConnectionState.STOPPING -> kst4contest.view.i18n.CurrentStrings.get().statusLinkDisconnecting + On4KstConnectionState.RECONNECT_WAIT -> kst4contest.view.i18n.CurrentStrings.get().statusLinkReconnecting + On4KstConnectionState.DISCONNECTED -> kst4contest.view.i18n.CurrentStrings.get().statusLinkDisconnected + } +} + +/** + * A non-clickable notice that blinks for a while and then disappears. + * + * Both the sked reminder and the band upgrade hint work this way. They are not + * dialogs on purpose — a dialog steals the keyboard, and the operator is typing. + * + * The blink itself belongs to the view; this holds what to draw and a revision the + * view restarts the blink on, so a second reminder blinks again instead of sitting + * there statically. + */ +class BlinkingNotice { + + var text: String by mutableStateOf("") + private set + + var tooltip: String by mutableStateOf("") + private set + + var visible: Boolean by mutableStateOf(false) + private set + + var revision: Int by mutableStateOf(0) + private set + + fun show(text: String, tooltip: String = text) { + this.text = shorten(text) + this.tooltip = tooltip + visible = true + revision++ + } + + fun hide() { + visible = false + } + + /** + * Hides the notice only if it is still the one that [generation] showed. + * + * The blink runs in the view and is cancelled if the bar leaves the composition — a + * splitter dragged shut, a profile switch — so the cleanup has to hide the notice, or + * a magenta reminder stays in the status bar for the rest of the session. But a second + * reminder arriving mid blink means the first blink's cleanup runs after the second is + * already showing, and it must not take that one down with it. + */ + fun hide(generation: Int) { + if (revision == generation) { + visible = false + } + } + + companion object { + /** The badge shares a row with the menu, so the text is cut and the tooltip keeps it. */ + const val MAX_LABEL_LENGTH = 38 + const val BLINK_CYCLES = 24 + const val BLINK_CYCLE_MILLIS = 500L + + val blinkDurationMillis: Long get() = BLINK_CYCLES * BLINK_CYCLE_MILLIS + + fun shorten(text: String): String = + if (text.length > MAX_LABEL_LENGTH) text.take(MAX_LABEL_LENGTH - 3) + "..." else text + } +} + +/** What makes a notice appear. */ +object StatusIndicators { + + /** The wording the operator has learned to recognize; the double space is deliberate. */ + fun reminderText(callSignRaw: String?, minutesBefore: Int): String = + "REMINDER: ${callSignRaw.orEmpty()} T-${minutesBefore}m" + + /** + * The band upgrade hint rides on the ordinary thread status messages, recognized by + * name. Returns the badge text and the tooltip, or null if this message is about + * something else. + */ + fun bandUpgradeNoticeFor(key: String?, message: ThreadStateMessage?): Pair? { + if (message == null) return null + + val nick = message.threadNickName?.lowercase(Locale.ROOT).orEmpty() + val lowerKey = key?.lowercase(Locale.ROOT).orEmpty() + if (!lowerKey.contains("bandupgrade") && !nick.contains("bandupgrade")) return null + + // ThreadStateMessage has its own fallback, so this rarely fires; it is here so a + // blank badge can never reach the status bar. + val badge = message.runningInformationTextDescription + ?.takeUnless { it.isBlank() } ?: "BAND+" + val tooltip = message.runningInformation?.takeUnless { it.isBlank() } ?: badge + return badge to tooltip + } +} + +/** + * One button per background thread that reports itself, in the order they first did. + * + * The flash on every message is the point: it is how the operator sees a worker is + * still alive without reading anything. + */ +class ThreadStatusButtons { + + private val bySource = LinkedHashMap() + private val ordered = mutableStateListOf() + + val buttons: List get() = ordered + + fun update(sourceName: String, message: ThreadStateMessage) { + val button = bySource.getOrPut(sourceName) { + ThreadStatusButton(sourceName).also { ordered.add(it) } + } + button.report( + label = "$sourceName: ${message.runningInformationTextDescription}", + tooltip = message.runningInformation.orEmpty(), + ) + } + + companion object { + /** How long the flash stays on; JavaFX used a 0.2 s PauseTransition. */ + const val HIGHLIGHT_MILLIS = 200L + } +} + +/** One background thread's button. */ +class ThreadStatusButton(val sourceName: String) { + + var label: String by mutableStateOf(sourceName) + private set + + var tooltip: String by mutableStateOf("") + private set + + /** True while the flash is on; the view clears it after HIGHLIGHT_MILLIS. */ + var highlighted: Boolean by mutableStateOf(false) + private set + + var revision: Int by mutableStateOf(0) + private set + + internal fun report(label: String, tooltip: String) { + this.label = label + this.tooltip = tooltip + highlighted = true + revision++ + } + + fun clearHighlight() { + highlighted = false + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/Theme.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/Theme.kt new file mode 100644 index 00000000..525a7183 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/Theme.kt @@ -0,0 +1,169 @@ +package kst4contest.view.compose + +import androidx.compose.material3.ColorScheme +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Typography +import androidx.compose.material3.darkColorScheme +import androidx.compose.material3.lightColorScheme +import androidx.compose.runtime.Composable +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.remember +import androidx.compose.runtime.staticCompositionLocalOf +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.unit.sp + +/** + * The application theme for Compose windows. + * + * Release 1.50 gave the JavaFX side one base font size per operator profile. + * Compose windows take the same value so a Compose window next to a JavaFX one + * does not look scaled differently. + * + * @param darkMode the operator's configured day/evening design + * @param baseFontSizeSp the configured base font size, in scale-independent points + */ +@Composable +fun Kst4ContestTheme( + darkMode: Boolean, + baseFontSizeSp: Float = 0f, + content: @Composable () -> Unit, +) { + val store = LocalPaletteStore.current + + val palette = if (store != null) { + /* + * Read from the store's state, not remembered: that read is what makes a palette + * change recompose every open window. remember(darkMode) kept the palette until + * somebody toggled day/evening, which is why a colour change used to reach nothing. + */ + store.resolved(darkMode).palette + } else { + /* + * No store yet. Not caution: the operator profile picker composes before a profile, + * and therefore before a store, exists. + */ + remember(darkMode) { JavaFxStylesheet.shipped(darkMode) } + } + + val fontSize = if (baseFontSizeSp > 0f) baseFontSizeSp else palette.fontSizePx + val typography = MaterialTheme.typography.scaledTo(fontSize) + + MaterialTheme( + colorScheme = palette.toColorScheme(darkMode), + typography = typography, + ) { + CompositionLocalProvider(LocalJavaFxPalette provides palette, content = content) + } +} + + +/** + * The palette in force, for the few places that need a colour Material has no slot + * for — the button hover gradient and its pressed border. + */ +val LocalJavaFxPalette = staticCompositionLocalOf { + JavaFxStylesheet.shipped(darkMode = false) +} + +/** + * Maps the stylesheet onto Material's colour roles. + * + * Only the roles the settings windows actually paint with are taken from the sheet; + * the rest keep Material's defaults, which nothing in these windows shows. + */ +private fun JavaFxPalette.toColorScheme(darkMode: Boolean): ColorScheme { + val defaults = if (darkMode) darkColorScheme() else lightColorScheme() + + /* + * The tint behind a selected row. Mixing the accent into the base keeps it legible + * in both designs, where a fixed colour would disappear into one of them. + */ + val selection = blend(accent, base, 0.30f) + + /* + * The sheet's own separator colour is #3C3C3C on a #373E43 surface — a brightness + * difference of 0.002, which is no line at all. Where the declared colour cannot be + * told apart from the surface it is replaced by a step away from that surface, so + * the section rules are actually visible. Making them visible is the point: they + * were asked for because a bare line of text did not read as a division. + */ + val declaredLine = separatorLine + val contrast = brightness(declaredLine) - brightness(windowBackground) + val visibleLine = if (contrast > -0.08f && contrast < 0.08f) { + JavaFxStylesheet.derive(windowBackground, if (darkMode) 45.0 else -25.0) + } else { + declaredLine + } + + return defaults.copy( + /* + * The green of .text-field .text, not -fx-accent: the blue accent only paints + * JavaFX's selection bar, while the green is what the operator sees on column + * headers and inside every field, and therefore what reads as the accent. + */ + primary = textAccent, + onPrimary = contrastingText(textAccent), + background = windowBackground, + onBackground = labelTextFill, + surface = windowBackground, + onSurface = labelTextFill, + /* The interior of a text field: JavaFX sets -fx-control-inner-background. */ + surfaceVariant = controlInnerBackground, + onSurfaceVariant = labelTextFill, + secondaryContainer = selection, + onSecondaryContainer = labelTextFill, + outline = visibleLine, + outlineVariant = visibleLine, + ) +} + +/** The brightness JavaFX measures with: 0.3R + 0.59G + 0.11B. */ +private fun brightness(color: Color): Float = + 0.3f * color.red + 0.59f * color.green + 0.11f * color.blue + +/** [amount] of [foreground] over [background]. */ +private fun blend(foreground: Color, background: Color, amount: Float): Color = Color( + red = foreground.red * amount + background.red * (1f - amount), + green = foreground.green * amount + background.green * (1f - amount), + blue = foreground.blue * amount + background.blue * (1f - amount), + alpha = 1f, +) + +/** + * Black or white, whichever reads on the given colour. Uses the same brightness + * measure JavaFX does, so the decision matches what the rest of the application + * would make. + * + * Internal rather than private because the menu row needs it too: once the operator can + * choose the accent, a menu title drawn in any fixed colour on an accent background can + * collapse into it. + */ +internal fun contrastingText(background: Color): Color = + if (brightness(background) > 0.5f) Color.Black else Color.White + +/** + * Scales every text style by the factor that turns the body size into + * [targetBodySizeSp]. A value of zero or less is ignored, so a missing or + * malformed configured size keeps the default design rather than collapsing it. + */ +internal fun Typography.scaledTo(targetBodySizeSp: Float): Typography { + if (targetBodySizeSp <= 0f) { + return this + } + val factor = targetBodySizeSp / bodyMedium.fontSize.value + if (factor == 1f) { + return this + } + fun TextStyle.scaled() = copy(fontSize = fontSize.value.times(factor).sp) + return copy( + displayLarge = displayLarge.scaled(), displayMedium = displayMedium.scaled(), + displaySmall = displaySmall.scaled(), headlineLarge = headlineLarge.scaled(), + headlineMedium = headlineMedium.scaled(), headlineSmall = headlineSmall.scaled(), + titleLarge = titleLarge.scaled(), titleMedium = titleMedium.scaled(), + titleSmall = titleSmall.scaled(), bodyLarge = bodyLarge.scaled(), + bodyMedium = bodyMedium.scaled(), bodySmall = bodySmall.scaled(), + labelLarge = labelLarge.scaled(), labelMedium = labelMedium.scaled(), + labelSmall = labelSmall.scaled(), + ) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/TimelineState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/TimelineState.kt new file mode 100644 index 00000000..1746fd66 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/TimelineState.kt @@ -0,0 +1,212 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateListOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import kst4contest.model.ChatCategory +import kst4contest.model.ContestSked +import kotlin.math.abs + +/** + * How promising an aircraft reflection is, in the four steps the timeline distinguishes. + * + * The colours are the original ones and they are not theme colours: this strip is read + * like a radar screen, where magenta means "now or never" in both designs. + */ +enum class PotentialLevel { + HIGHEST, + HIGH, + MEDIUM, + LOW; + + companion object { + fun forPercent(percent: Int): PotentialLevel = when { + percent >= 95 -> HIGHEST + percent >= 75 -> HIGH + percent >= 50 -> MEDIUM + else -> LOW + } + } +} + +/** + * One priority candidate on the timeline: a station worth calling at a given minute, + * placed on the next minute an aeroplane is expected. + * + * The Kotlin counterpart of TimelineView.CandidateEvent, built from the score service. + */ +data class TimelineCandidate( + val callSignRaw: String, + val displayCallSign: String, + val preferredChatCategory: ChatCategory?, + val timeUntilMs: Long, + val minuteBucket: Int, + val laneIndex: Int, + val targetAzimuth: Double, + val score: Double, + val opportunityPotentialPercent: Int, + val tooltipText: String?, +) + +/** + * Where things sit on the strip. + * + * Time runs left to right as it *increases*, so "now" is at the left edge and the end + * of the preview window at the right. Imminent events are therefore on the left, which + * is the opposite of a progress bar and worth knowing before reading the numbers. + */ +object TimelineGeometry { + + /** How far ahead the strip looks. */ + const val PREVIEW_MILLIS: Long = 30L * 60L * 1000L + + /** + * The height the strip is drawn into, and the height the JavaFX call site actually + * gave it. The class itself claimed 40 and then only ever used the upper half, which + * is why the candidate labels and the sked labels landed on top of each other. The + * lanes below are laid out for the real height. + */ + const val HEIGHT: Float = 80f + + /** The time axis, with the candidate lanes above it and the skeds below. */ + const val AXIS_Y: Float = 44f + + /** Candidates keep further from the edges than skeds do, because their labels are wider. */ + const val CANDIDATE_MARGIN: Float = 30f + const val SKED_MARGIN: Float = 10f + + const val LANE_BASE_Y: Float = 2f + const val LANE_HEIGHT: Float = 20f + + /** + * How many candidate lanes fit above the axis. The producer keeps at most two + * candidates per minute, so this is a guard rather than a limit in practice: a third + * lane shares the second one instead of being drawn across the axis. + */ + const val LANE_COUNT: Int = 2 + + /** Skeds get their own lane below the axis, which is what frees the labels. */ + const val SKED_Y: Float = 52f + + const val DEFAULT_BEAM_WIDTH_DEG: Double = 50.0 + + /** + * The x for an event that many milliseconds away, or null when it falls outside the + * preview window and is not drawn at all. + */ + fun xFor(timeUntilMs: Long, width: Float, margin: Float): Float? { + if (timeUntilMs < 0 || timeUntilMs > PREVIEW_MILLIS) return null + + val x = timeUntilMs.toFloat() / PREVIEW_MILLIS.toFloat() * width + + // A strip narrower than two margins leaves no room to hold the marker off both + // edges, and coerceIn refuses an empty range rather than picking a side. Centring + // is the honest answer: on a strip that narrow the position carries no information + // anyway, and this window lives on a tiling compositor where that happens. + val lowerBound = margin + val upperBound = width - margin + if (lowerBound > upperBound) return width / 2f + + return x.coerceIn(lowerBound, upperBound) + } + + /** + * Where a label starts, given how wide it turned out. It sits to the right of its + * marker, and flips to the left rather than running off the strip — near the right + * edge, which is half an hour away, there is always room on the other side. + */ + fun labelStartX(markerX: Float, labelWidth: Float, stripWidth: Float, gap: Float): Float { + val toTheRight = markerX + gap + return if (toTheRight + labelWidth <= stripWidth) toTheRight + else (markerX - gap - labelWidth).coerceAtLeast(0f) + } + + fun laneY(laneIndex: Int): Float = + LANE_BASE_Y + LANE_HEIGHT * laneIndex.coerceIn(0, LANE_COUNT - 1) +} + +/** + * How strongly a marker is drawn, given where the antenna points. + * + * Off-beam markers fade rather than disappear: the operator has to be able to see that + * a chance exists in a direction they are not pointing, otherwise turning the rotator + * would never occur to them. + */ +data class AntennaEmphasis( + val iconAlpha: Float, + val glowing: Boolean, + val scale: Float, +) { + companion object { + /** Full strength, no glow — also what an unknown azimuth gets, so it stays readable. */ + val PLAIN = AntennaEmphasis(iconAlpha = 1f, glowing = false, scale = 1f) + + const val OFF_BEAM_ALPHA = 0.30f + const val ON_TARGET_SCALE = 1.10f + + /** + * Within half a beam width the marker glows and grows; out to a full beam width + * it stays bright; beyond that it fades to a ghost. + */ + fun forAzimuth( + currentAzimuth: Double, + targetAzimuth: Double, + beamWidthDeg: Double, + ): AntennaEmphasis { + // An unknown or negative azimuth is not a direction, so nothing is implied by it. + if (!targetAzimuth.isFinite() || targetAzimuth < 0) return PLAIN + + var delta = abs(currentAzimuth - targetAzimuth) + if (delta > 180) delta = 360 - delta + + val onTarget = delta <= beamWidthDeg / 2.0 + val inBeam = delta <= beamWidthDeg + + return AntennaEmphasis( + iconAlpha = if (inBeam) 1f else OFF_BEAM_ALPHA, + glowing = onTarget, + scale = if (onTarget) ON_TARGET_SCALE else 1f, + ) + } + } +} + +/** + * What the timeline draws. + * + * Compose state throughout: the strip is redrawn on the score service's pulse, on every + * rotator movement and on every resize, and each of those has to reach the screen on + * its own. + */ +class TimelineState { + + val skeds = mutableStateListOf() + val candidates = mutableStateListOf() + + /** Where the antenna points now, from the rotator or the manually set QTF. */ + var antennaAzimuth: Double by mutableStateOf(0.0) + + var beamWidthDeg: Double by mutableStateOf(TimelineGeometry.DEFAULT_BEAM_WIDTH_DEG) + private set + + /** A station without a sensible beam width keeps the default rather than a nonsense one. */ + fun setBeamWidth(degrees: Double) { + if (degrees > 0 && degrees.isFinite()) { + beamWidthDeg = degrees + } + } + + fun replaceSkeds(newSkeds: List) { + skeds.clear() + skeds.addAll(newSkeds) + } + + fun replaceCandidates(newCandidates: List) { + candidates.clear() + candidates.addAll(newCandidates) + } + + fun emphasisFor(targetAzimuth: Double): AntennaEmphasis = + AntennaEmphasis.forAzimuth(antennaAzimuth, targetAzimuth, beamWidthDeg) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/TimelineView.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/TimelineView.kt new file mode 100644 index 00000000..b2a66095 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/TimelineView.kt @@ -0,0 +1,311 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.TooltipArea +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxWithConstraints +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.offset +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.graphics.drawscope.scale + +import androidx.compose.foundation.onClick +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.rememberTextMeasurer +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import kst4contest.model.ContestSked +import kotlin.math.roundToInt + +/** The strip is read like a radar screen, so it stays dark in both designs. */ +private val STRIP_BACKGROUND = Color(0xFF2B2B2B) +private val AXIS_COLOR = Color.Gray + +/** The glow that marks a target the antenna is centred on. */ +private val GLOW_COLOR = Color(0xFF32CD32) + +private val MARKER_SIZE = 12.dp +private val LABEL_GAP = 4.dp +private val CHIP_SHAPE = RoundedCornerShape(6.dp) +private val CHIP_BACKGROUND = Color(0xA6000000) + +/** + * The strip above the send field: what is coming in the next half hour. + * + * The one view in this client that is read as a picture rather than as text. Skeds and + * priority candidates are placed by time, coloured by how promising the aircraft + * reflection is, and faded when the antenna points elsewhere — so one glance answers + * both "what is next" and "could I even hear it right now". + * + * Time grows to the right, which means the imminent things are on the LEFT. That is the + * opposite of a progress bar and it is the original's choice, kept because operators + * have learned it. + * + * Markers are drawn rather than built from widgets: this is a diagram, with no rows and + * nothing to select. Only the candidates answer a click. + */ +@OptIn(ExperimentalFoundationApi::class) +@Composable +fun TimelineView( + state: TimelineState, + onCandidateClicked: (TimelineCandidate) -> Unit, + skedTooltipExtra: (ContestSked) -> String? = { null }, + modifier: Modifier = Modifier, +) { + val nowMillis = androidx.compose.runtime.mutableStateOf(System.currentTimeMillis()) + + androidx.compose.runtime.LaunchedEffect(Unit) { + while (true) { + kotlinx.coroutines.delay(1000) + nowMillis.value = System.currentTimeMillis() + } + } + + val density = LocalDensity.current + val measurer = rememberTextMeasurer() + + BoxWithConstraints( + modifier + .height(TimelineGeometry.HEIGHT.dp) + .background(STRIP_BACKGROUND), + ) { + val widthPx = with(density) { maxWidth.toPx() } + val axisY = with(density) { TimelineGeometry.AXIS_Y.dp.toPx() } + val candidateMargin = with(density) { TimelineGeometry.CANDIDATE_MARGIN.dp.toPx() } + val skedMargin = with(density) { TimelineGeometry.SKED_MARGIN.dp.toPx() } + + Canvas(Modifier.fillMaxSize()) { + drawLine(AXIS_COLOR, Offset(0f, axisY), Offset(size.width, axisY)) + } + + // The candidate lanes, above the axis. + state.candidates.forEach { candidate -> + val x = TimelineGeometry.xFor(candidate.timeUntilMs, widthPx, candidateMargin) + ?: return@forEach + + TimelineMarker( + centerXPx = x, + topDp = TimelineGeometry.laneY(candidate.laneIndex).dp, + stripWidthPx = widthPx, + label = candidate.displayCallSign, + tooltip = candidate.tooltipText, + level = PotentialLevel.forPercent(candidate.opportunityPotentialPercent), + emphasis = state.emphasisFor(candidate.targetAzimuth), + shape = MarkerShape.CANDIDATE, + labelWidthPx = { text -> measurer.measure(text, CHIP_TEXT_STYLE).size.width.toFloat() }, + onClick = { onCandidateClicked(candidate) }, + ) + } + + // The skeds, in their own lane below the axis. In JavaFX they shared the space + // above it, which is why their labels sat on top of the candidates'. + val now = nowMillis.value + state.skeds.forEach { sked -> + val x = TimelineGeometry.xFor(sked.skedTimeEpoch - now, widthPx, skedMargin) + ?: return@forEach + + TimelineMarker( + centerXPx = x, + topDp = TimelineGeometry.SKED_Y.dp, + stripWidthPx = widthPx, + label = "SKED: ${sked.targetChatCallsign}", + tooltip = skedTooltip(sked, skedTooltipExtra), + level = PotentialLevel.forPercent(sked.opportunityPotentialPercent), + emphasis = state.emphasisFor(sked.targetAzimuth), + shape = MarkerShape.SKED, + labelWidthPx = { text -> measurer.measure(text, CHIP_TEXT_STYLE).size.width.toFloat() }, + onClick = null, + ) + } + } +} + +/** + * The sked tooltip: who, on what band, in which direction — plus whatever the caller can + * add about the chance itself. + */ +private fun skedTooltip(sked: ContestSked, extraProvider: (ContestSked) -> String?): String { + val base = "${sked.targetChatCallsign} (${sked.band})\nAz: ${sked.targetAzimuth}" + val extra = extraProvider(sked) + return if (extra.isNullOrBlank()) base else "$base\n$extra" +} + +private enum class MarkerShape { SKED, CANDIDATE } + +private val CHIP_TEXT_STYLE = TextStyle( + color = Color.White, + fontSize = 9.sp, + fontWeight = FontWeight.Bold, +) + +/** + * One marker: the symbol on the time axis and its callsign beside it. + * + * The label is never faded, only the symbol is. A ghost marker still has to be + * readable — that is the whole point of showing a chance in a direction the antenna is + * not pointing. + */ +@OptIn(ExperimentalFoundationApi::class) +@Composable +private fun TimelineMarker( + centerXPx: Float, + topDp: Dp, + stripWidthPx: Float, + label: String, + tooltip: String?, + level: PotentialLevel, + emphasis: AntennaEmphasis, + shape: MarkerShape, + labelWidthPx: (String) -> Float, + onClick: (() -> Unit)?, +) { + val density = LocalDensity.current + val markerSizePx = with(density) { MARKER_SIZE.toPx() } + val gapPx = with(density) { LABEL_GAP.toPx() } + + val labelWidth = labelWidthPx(label) + val labelX = TimelineGeometry.labelStartX( + markerX = centerXPx + markerSizePx / 2f, + labelWidth = labelWidth, + stripWidth = stripWidthPx, + gap = gapPx, + ) + + val symbol: @Composable () -> Unit = { + Canvas( + Modifier + .size(MARKER_SIZE) + .alpha(emphasis.iconAlpha), + ) { + scale(emphasis.scale) { + if (emphasis.glowing) drawGlow() + when (shape) { + MarkerShape.SKED -> drawDiamond(markerColor(level)) + MarkerShape.CANDIDATE -> drawCandidate(markerColor(level)) + } + } + } + } + + Box( + Modifier.offset { + IntOffset( + (centerXPx - markerSizePx / 2f).roundToInt(), + with(density) { topDp.toPx() }.roundToInt(), + ) + }, + ) { + val clickable = if (onClick != null) Modifier.onClick { onClick() } else Modifier + if (tooltip.isNullOrBlank()) { + Box(clickable) { symbol() } + } else { + TooltipArea(tooltip = { TimelineTooltip(tooltip) }) { + Box(clickable) { symbol() } + } + } + } + + // The label is placed on its own so it can flip sides without moving the symbol. + Box( + Modifier.offset { + IntOffset( + labelX.roundToInt(), + with(density) { topDp.toPx() }.roundToInt(), + ) + }, + ) { + Box( + Modifier + .background(CHIP_BACKGROUND, CHIP_SHAPE) + .padding(horizontal = 4.dp, vertical = 1.dp), + ) { + Text(text = label, style = CHIP_TEXT_STYLE, maxLines = 1) + } + } +} + +/** Magenta means now or never; deep sky blue means it is barely worth turning for. */ +private fun markerColor(level: PotentialLevel): Color = when (level) { + PotentialLevel.HIGHEST -> Color.Magenta + PotentialLevel.HIGH -> Color.Red + PotentialLevel.MEDIUM -> Color.Yellow + PotentialLevel.LOW -> Color(0xFF00BFFF) +} + +/** The diamond of a sked: an appointment, not a chance. */ +private fun DrawScope.drawDiamond(color: Color) { + val w = size.width + val h = size.height + val path = Path().apply { + moveTo(w / 2f, 0f) + lineTo(w, h / 2f) + lineTo(w / 2f, h) + lineTo(0f, h / 2f) + close() + } + drawPath(path, color) +} + +/** A candidate: a downward triangle over a dot, so it reads even at this size. */ +private fun DrawScope.drawCandidate(color: Color) { + val w = size.width + val h = size.height + drawCircle(color, radius = w / 3f, center = Offset(w / 2f, h / 2f)) + val path = Path().apply { + moveTo(0f, 0f) + lineTo(w, 0f) + lineTo(w / 2f, h * 0.85f) + close() + } + drawPath(path, color) +} + +/** + * The glow for a target the antenna is centred on. JavaFX used a drop shadow; here it is + * three fading rings, which costs nothing and reads the same at this size. + */ +private fun DrawScope.drawGlow() { + val center = Offset(size.width / 2f, size.height / 2f) + listOf(1.6f to 0.10f, 1.3f to 0.18f, 1.05f to 0.28f).forEach { (factor, alpha) -> + drawCircle( + color = GLOW_COLOR.copy(alpha = alpha), + radius = size.width / 2f * factor, + center = center, + ) + } +} + +@Composable +private fun TimelineTooltip(text: String) { + Surface( + color = MaterialTheme.colorScheme.surfaceVariant, + contentColor = MaterialTheme.colorScheme.onSurfaceVariant, + shape = Density.BUTTON_SHAPE, + tonalElevation = 4.dp, + ) { + Text( + text = text, + modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), + style = MaterialTheme.typography.bodySmall, + ) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/TopPriorityCandidatesWindow.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/TopPriorityCandidatesWindow.kt new file mode 100644 index 00000000..2fa2bd46 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/TopPriorityCandidatesWindow.kt @@ -0,0 +1,173 @@ +package kst4contest.view.compose + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.ExperimentalFoundationApi +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.combinedClickable +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import kst4contest.controller.ScoreService +import java.util.Locale +import java.util.function.Consumer +import java.util.function.Supplier + +/** + * One line of the candidate list. + * + * Kept as a function rather than inlined into the row so the wording stays under a + * test: the JavaFX cell spelled it `callsign + " | score " + %.0f` for two releases, + * and an operator scanning the list reads the shape before the content. + */ +internal fun candidateLabel(candidate: ScoreService.TopCandidate): String = + candidate.displayCallSign + + " | score " + + String.format(Locale.US, "%.0f", candidate.score) + +/** + * The full priority list, opened by the "more" button beside the two priority buttons. + * + * It exists so the main window can stay compact while the whole ranking is still + * reachable. Its JavaFX predecessor was the only Stage this application constructed + * itself, which is why it is ported before anything is deleted: no JavaFX dependency + * can be dropped while it stands. + */ +object TopPriorityCandidatesWindow { + + private val host = ComposeWindowHost("TopPriorityCandidates") + + @JvmStatic + val isOpen: Boolean get() = host.isOpen + + @JvmStatic + fun applyDarkMode(darkMode: Boolean) = host.applyDarkMode(darkMode) + + @JvmStatic + fun hide() = host.close() + + /** + * `Supplier` and `Consumer` rather than Kotlin function types: the only caller is + * Java, and a Java lambda cannot produce Kotlin's `Unit`, so the Kotlin shape would + * force `return kotlin.Unit.INSTANCE` into the call site for nothing. + * + * @param candidates read afresh while the window is open; the ranking changes as + * scores do, and the JavaFX list was bound to the roster for that reason + * @param onPicked called with the chosen candidate, after which the window closes + */ + @JvmStatic + fun show( + candidates: Supplier>, + onPicked: Consumer, + darkMode: Boolean, + baseFontSizeSp: Float, + /** + * The palette of the active profile, handed to the theme. Null draws the shipped + * palette. + */ + paletteStore: PaletteStore? = null, + /** + * The interface language of the active profile, handed to the window. Null draws the + * base language. + */ + languageStore: kst4contest.view.i18n.LanguageStore? = null, + ) { + host.show( + title = { kst4contest.view.i18n.CurrentStrings.get().candidatesTitle }, + darkMode = darkMode, + baseFontSizeSp = baseFontSizeSp, + paletteStore = paletteStore, + languageStore = languageStore, + widthDp = 360f, + heightDp = 500f, + ) { close -> + var ranking by remember { mutableStateOf(candidates.get()) } + + /* + * Polled rather than pushed. The ranking lives in the score service, which + * is not Compose state, and this window is open for seconds at a time while + * an operator reads it — wiring a callback in and out for that is more + * machinery than the question deserves. + */ + LaunchedEffect(Unit) { + while (true) { + kotlinx.coroutines.delay(POLL_INTERVAL_MS) + ranking = candidates.get() + } + } + + Surface( + color = MaterialTheme.colorScheme.background, + contentColor = MaterialTheme.colorScheme.onBackground, + modifier = Modifier.fillMaxSize(), + ) { + Column(Modifier.fillMaxSize().padding(5.dp)) { + CandidateList( + ranking = ranking, + onPicked = { picked -> + onPicked.accept(picked) + close() + }, + modifier = Modifier.weight(1f).fillMaxWidth(), + ) + HorizontalDivider(Modifier.padding(vertical = 4.dp)) + Text( + LocalStrings.current.candidatesDoubleClick, + style = MaterialTheme.typography.bodySmall, + ) + } + } + } + } + + /** The list on its own, so a test can render it without opening a window. */ + @Composable + internal fun CandidateListForTest( + ranking: List, + onPicked: (ScoreService.TopCandidate) -> Unit, + ) = CandidateList(ranking, onPicked) + + @OptIn(ExperimentalFoundationApi::class) + @Composable + private fun CandidateList( + ranking: List, + onPicked: (ScoreService.TopCandidate) -> Unit, + modifier: Modifier = Modifier, + ) { + if (ranking.isEmpty()) { + Text(LocalStrings.current.candidatesNone, modifier = modifier.padding(4.dp)) + return + } + + LazyColumn(modifier) { + items(ranking) { candidate -> + Text( + text = candidateLabel(candidate), + modifier = Modifier + .fillMaxWidth() + .combinedClickable( + onClick = { }, + onDoubleClick = { onPicked(candidate) }, + ) + .padding(vertical = 3.dp, horizontal = 4.dp), + ) + } + } + } + + /** Fast enough that a changing ranking is not stale, slow enough to cost nothing. */ + private const val POLL_INTERVAL_MS = 1_000L +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/TopPriorityState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/TopPriorityState.kt new file mode 100644 index 00000000..1b556a09 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/TopPriorityState.kt @@ -0,0 +1,44 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.mutableStateOf +import kst4contest.model.ChatMember + +/** One priority button: what it says and what pressing it does. */ +class TopPriorityEntry(val label: String, val select: () -> Unit) + +/** + * The two priority buttons beside the station list. + * + * A shortcut to the station the score says to work next, so what they name and what + * they do when pressed is the whole of their value. Everything below the first two is + * behind the "more" button, as it was. + * + * @param topStations the ranked stations with their scores, highest first + * @param onSelect selects a station in the list, which is what pressing a button did + */ +class TopPriorityState( + private val topStations: () -> List>, + private val onSelect: (ChatMember) -> Unit, +) { + + private val _entries = mutableStateOf>(emptyList()) + + val entries: List + get() = _entries.value + + fun refresh() { + _entries.value = topStations() + .filter { (member, _) -> !member.callSign.isNullOrBlank() } + .take(SHOWN) + .mapIndexed { index, (member, score) -> + TopPriorityEntry( + label = "${index + 1} ${member.callSign} ${score.toInt()}", + ) { onSelect(member) } + } + } + + private companion object { + /** Two, as the JavaFX pane had; the rest sit behind "more". */ + const val SHOWN = 2 + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/UpdateWindow.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/UpdateWindow.kt new file mode 100644 index 00000000..9ace7b74 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/UpdateWindow.kt @@ -0,0 +1,168 @@ +package kst4contest.view.compose + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Surface +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextDecoration +import androidx.compose.ui.unit.dp +import java.util.function.Consumer + +/** + * The update window. + * + * Shown at startup and only when there is an update; [UpdateWindowState.updateAvailable] + * decides that, and it is tested. Non-blocking like the settings window: the operator + * reads it when they get round to it. + */ +object UpdateWindow { + + private val host = ComposeWindowHost("update-window") + + @JvmStatic + val isOpen: Boolean + get() = host.isOpen + + @JvmStatic + fun applyDarkMode(darkMode: Boolean) = host.applyDarkMode(darkMode) + + @JvmStatic + fun close() = host.close() + + /** + * @param openReleasePage opens the given address in the system browser; passed in + * because reaching the browser is the host application's business. A + * Consumer rather than a Kotlin function type: this is called from Java, and + * a Kotlin lambda parameter would force the caller to return Unit by hand. + */ + @JvmStatic + fun show( + state: UpdateWindowState, + darkMode: Boolean, + baseFontSizeSp: Float, + /** + * The palette of the active profile, handed to the theme. Null draws the shipped + * palette. + */ + paletteStore: PaletteStore? = null, + /** + * The interface language of the active profile, handed to the window. Null draws the + * base language. + */ + languageStore: kst4contest.view.i18n.LanguageStore? = null, + widthDp: Float, + heightDp: Float, + openReleasePage: Consumer, + onResized: (Float, Float) -> Unit, + ) { + host.show( + title = { kst4contest.view.i18n.CurrentStrings.get().updateTitle }, + darkMode = darkMode, + baseFontSizeSp = baseFontSizeSp, + paletteStore = paletteStore, + languageStore = languageStore, + widthDp = widthDp, + heightDp = heightDp, + onResized = onResized, + alwaysOnTop = true, + ) { _ -> + UpdateContent(state, openReleasePage::accept) + } + } +} + +@Composable +private fun UpdateContent(state: UpdateWindowState, openReleasePage: (String) -> Unit) { + val strings = LocalStrings.current + Surface(modifier = Modifier.fillMaxSize()) { + Column( + modifier = Modifier.padding(10.dp).verticalScroll(rememberScrollState()), + verticalArrangement = Arrangement.spacedBy(Density.FIELD_GAP), + ) { + Text(strings.updateAvailable, style = MaterialTheme.typography.titleMedium) + + Form.section(strings.updateVersions) { + Form.labelledRow(strings.updateInstalledVersion) { Text(state.installedVersion) } + Form.labelledRow(strings.updateLatestVersion) { Text(state.latestVersion) } + } + + Form.section(strings.updateMainChanges) { Text(state.majorChanges) } + + Form.section(strings.updateAdditionalInformation) { Text(state.adminMessage) } + + Form.section(strings.updateDownload) { + Text( + strings.updateOpenReleasePage, + color = MaterialTheme.colorScheme.primary, + textDecoration = TextDecoration.Underline, + modifier = Modifier.clickable { openReleasePage(state.releasePageUrl) }, + ) + } + + /* + * The JavaFX window drew these as a TreeView with a hidden root. The depth + * is fixed at two — a heading and its lines — so two expandable sections do + * the same job without a tree component. + */ + UpdateBranch(strings.updateChangeLog, state.changeLog) + UpdateBranch(strings.updateKnownBugs, state.knownBugs) + } + } +} + +/** One branch of the former tree: a heading, and sections that fold open. */ +@Composable +private fun UpdateBranch(title: String, sections: List) { + val strings = LocalStrings.current + if (sections.isEmpty()) { + return + } + + Form.section(title) { + sections.forEach { section -> + var expanded by remember(section.title) { mutableStateOf(false) } + + Column(modifier = Modifier.fillMaxWidth()) { + Row( + modifier = Modifier + .fillMaxWidth() + .clickable { expanded = !expanded } + .padding(vertical = 2.dp), + horizontalArrangement = Arrangement.spacedBy(6.dp), + ) { + Text(if (expanded) "▾" else "▸") + Text(section.title, fontWeight = FontWeight.Bold) + } + + if (expanded) { + section.entries.forEach { entry -> + Text( + entry, + style = MaterialTheme.typography.bodySmall, + modifier = Modifier.padding(start = 20.dp, bottom = 1.dp), + ) + } + } + + HorizontalDivider(thickness = Density.HAIRLINE) + } + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/UpdateWindowState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/UpdateWindowState.kt new file mode 100644 index 00000000..a674c1e3 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/UpdateWindowState.kt @@ -0,0 +1,96 @@ +package kst4contest.view.compose + +import kst4contest.model.UpdateInformation +import kst4contest.utils.VersionUtils + +/** + * One branch of the update window's tree: a heading and the lines beneath it. + * + * Both branches of that tree have the same shape. The change log and the bug list + * arrive as arrays whose first element is the heading and whose remaining elements are + * the lines, so one type serves both. + */ +data class UpdateSection(val title: String, val entries: List) + +/** + * What the update window shows, and whether it opens at all. + * + * Free of any toolkit so the decision can be tested. The decision is the interesting + * part: an update window that opens when there is no update is a daily annoyance, and + * one that stays shut when there is an update defeats the whole mechanism. + * + * @param currentVersion the running version, `ApplicationConstants.APPLICATION_CURRENT_VERSION` + * @param currentVersionNumber the running version as a number, for the older + * comparison that is still used when the server reports no semantic version + */ +class UpdateWindowState( + private val updateInformation: UpdateInformation?, + private val currentVersion: String, + private val currentVersionNumber: Double, +) { + + /** + * Whether an update exists. + * + * Two comparisons, as in the JavaFX window: a semantic one when the server reports + * a semantic version, and the older numeric one otherwise. Absent update + * information means no update — the check runs at startup, and a failed download + * must not stop the application from coming up. + */ + val updateAvailable: Boolean + get() { + val information = updateInformation ?: return false + + return if (information.hasSemanticVersion()) { + VersionUtils.compareStableVersions( + information.latestSemanticVersionOnServer, + currentVersion, + ) > 0 + } else { + information.latestVersionNumberOnServer > currentVersionNumber + } + } + + /** "KST4Contest 1.50.0", as the window prints it. */ + val installedVersion: String + get() = DISPLAY_NAME + " " + currentVersion + + val latestVersion: String + get() = DISPLAY_NAME + " " + (updateInformation?.latestVersionForDisplay ?: "") + + val majorChanges: String + get() = updateInformation?.majorChanges ?: "" + + val adminMessage: String + get() = updateInformation?.adminMessage ?: "" + + /** Opened in the system browser by the "Open release page" link. */ + val releasePageUrl: String + get() = updateInformation?.latestVersionPathOnWebserver ?: "" + + val changeLog: List + get() = sectionsOf(updateInformation?.changeLog) + + val knownBugs: List + get() = sectionsOf(updateInformation?.bugList) + + /** + * Turns the stored arrays into sections. + * + * A row with nothing but a heading yields a section without lines rather than being + * dropped: the heading is the version, and a version that brought no listed change + * is still worth showing as released. + */ + private fun sectionsOf(rows: List>?): List = + rows.orEmpty() + .filter { it.isNotEmpty() } + .map { row -> UpdateSection(row.first(), row.drop(1)) } + + companion object { + /** + * The window prints "KST4Contest", not `APPLICATION_NAME`. That constant is + * "praktiKST" and names the application directory, not the product. + */ + const val DISPLAY_NAME = "KST4Contest" + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/WindowShortcuts.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/WindowShortcuts.kt new file mode 100644 index 00000000..24a82ef3 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/WindowShortcuts.kt @@ -0,0 +1,70 @@ +package kst4contest.view.compose + +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.KeyEvent +import androidx.compose.ui.input.key.KeyEventType +import androidx.compose.ui.input.key.isCtrlPressed +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.type +import androidx.compose.ui.input.key.utf16CodePoint + +/** + * The keys that belong to the whole main window rather than to one control. + * + * JavaFX hung all of these on the Scene, and the tables even re-fired the send button from + * their own key filter. An operator who has just clicked a station, a message row or a button + * must still be able to press Enter and have the message go; and Ctrl+1…Ctrl+0 is how + * snippets are used at all, because the hands are already on the keyboard. + */ +object WindowShortcuts { + + /** + * Which snippet a typed character selects, or null if it is not one of the ten digits. + * + * Ctrl+1…Ctrl+9 are slots 0 to 8 and Ctrl+0 is the tenth, because the digit row reads + * 1 to 9 and then 0. + */ + fun snippetIndexFor(typed: String): Int? = when (typed) { + "1" -> 0 + "2" -> 1 + "3" -> 2 + "4" -> 3 + "5" -> 4 + "6" -> 5 + "7" -> 6 + "8" -> 7 + "9" -> 8 + "0" -> 9 + else -> null + } + + /** + * Handles one key event for the window. Returns true when the event was consumed, which + * is what keeps Enter out of the text and stops the key travelling further. + * + * @param send what Enter does, wherever the focus is + * @param clear what Escape does + * @param insertSnippet what Ctrl+ does, with the slot it selected + */ + fun handle( + event: KeyEvent, + send: () -> Unit, + clear: () -> Unit, + insertSnippet: (Int) -> Unit, + ): Boolean { + if (event.type != KeyEventType.KeyDown) return false + + if (event.isCtrlPressed) { + val index = snippetIndexFor(event.utf16CodePoint.toChar().toString()) + ?: return false + insertSnippet(index) + return true + } + + return when (event.key) { + Key.Enter, Key.NumPadEnter -> { send(); true } + Key.Escape -> { clear(); true } + else -> false + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/map/ComposeStationMap.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/map/ComposeStationMap.kt new file mode 100644 index 00000000..9e81f338 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/map/ComposeStationMap.kt @@ -0,0 +1,916 @@ +package kst4contest.view.compose.map + +import androidx.compose.foundation.Canvas +import androidx.compose.foundation.gestures.detectTapGestures +import androidx.compose.foundation.gestures.detectTransformGestures +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.derivedStateOf +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.snapshotFlow +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.clipToBounds +import androidx.compose.ui.layout.onSizeChanged +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.PathEffect +import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.graphics.drawscope.Fill +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.graphics.toComposeImageBitmap +import androidx.compose.ui.input.pointer.PointerEventType +import androidx.compose.ui.input.pointer.pointerInput +import androidx.compose.ui.text.TextLayoutResult +import androidx.compose.ui.text.TextMeasurer +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.drawText +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.rememberTextMeasurer +import androidx.compose.ui.unit.IntOffset +import androidx.compose.ui.unit.IntSize +import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.unit.TextUnitType +import kst4contest.view.map.MaidenheadGridRenderPlanner +import kst4contest.view.map.MaidenheadGridUtils +import kst4contest.view.map.MapCallsignRawSnapshot +import kst4contest.view.map.MapMarkerCluster +import kst4contest.view.map.MapMarkerClusterTooltip +import kst4contest.view.map.MapViewport +import kst4contest.view.map.StationMapClusterer +import kst4contest.view.map.TileFetcher +import kotlinx.coroutines.flow.collectLatest +import org.jetbrains.skia.Image +import java.util.concurrent.ConcurrentHashMap +import kotlin.math.ceil +import kotlin.math.floor +import kotlin.math.log2 +import kotlin.math.sign + +/** + * Where the map is looking. Compose state, so a pan or a zoom reaches the screen. + * + * Holds no canvas size: the size is whatever the canvas is measured at, and a + * [MapViewport] is built from the two together for each frame. + */ +class MapState( + zoom: Float = 6f, + centerLon: Double = 10.0, + centerLat: Double = 51.0, +) { + var zoom by mutableStateOf(zoom.coerceIn(MapViewport.MIN_ZOOM.toFloat(), MapViewport.MAX_ZOOM.toFloat())) + var centerLon by mutableStateOf(centerLon) + var centerLat by mutableStateOf(centerLat) + + fun viewportFor(widthPx: Float, heightPx: Float): MapViewport = + MapViewport(centerLon, centerLat, zoom.toDouble(), widthPx.toDouble(), heightPx.toDouble()) + + fun applyFrom(viewport: MapViewport) { + centerLon = viewport.centerLon() + centerLat = viewport.centerLat() + zoom = viewport.zoom().toFloat() + } +} + +/** + * The station map as a Compose canvas. + * + * **Everything but the tiles is drawn in canvas pixels.** A station dot is 12 px wide at + * zoom 4 and at zoom 17; so is its label, and so is a grid line. Leaflet behaved that + * way because its overlays sat in the DOM above a scaled tile layer, and the sizes here + * are the ones its stylesheet declared. [MapViewport] makes that possible by folding the + * fractional zoom into the projection. + * + * The previous version instead wrapped part of the drawing in `scale(scaleFactor)` and + * divided every size back out by hand. The geometry that came out of it was right, but + * two things were not. Text was measured at a size divided by the zoom fraction and then + * magnified by it, so glyphs were rasterised at the wrong size. And the scale block + * closed before the beam, the path line and the home marker were drawn, which left those + * three using unscaled coordinates while the markers beside them used scaled ones — so at + * any zoom with a fraction, the antenna beam did not start where the map said home was. + * Neither failure is possible here, because nothing is scaled. + */ +@Composable +fun ComposeStationMap( + markers: List, + tileFetcher: TileFetcher, + mapState: MapState, + groupingEnabled: Boolean, + selectedMarkerCallsign: String?, + ownLocator6: String, + antennaAzimuthDeg: Double, + antennaBeamWidthDeg: Double, + maxQrbKm: Double, + onMarkerClicked: ((MapCallsignRawSnapshot) -> Unit)?, + darkMode: Boolean = true, + modifier: Modifier = Modifier, +) { + val imageCache = remember { TileBitmapCache() } + val fetchingTiles = remember { ConcurrentHashMap.newKeySet() } + val textMeasurer = rememberTextMeasurer() + + var hoverPosition by remember { mutableStateOf(null) } + + /* + * Measured, not read off the draw pass. Writing Compose state while drawing costs a + * frame at best: the first frame would group the stations against a zero-sized + * viewport and the second would correct it, which is visible as a flicker of + * wrongly grouped markers whenever the window is resized. + */ + var canvasSize by remember { mutableStateOf(Size.Zero) } + + /* Bumped when a tile arrives, which is what asks for the frame that shows it. */ + var tileRevision by remember { mutableStateOf(0) } + + /* + * Grouping depends on where the map is looking, so it cannot be cached on the + * stations alone. + * + * It is NOT off the drawing path: derivedStateOf computes lazily at first read, and + * that read is inside the Canvas lambda. What changed against the first port is the + * cost of the pass, not when it runs — that one searched for the nearest existing + * cluster for every station, which is quadratic; this one buckets by screen cell in + * one linear pass over a few hundred markers. + */ + val home = remember(ownLocator6) { homePosition(ownLocator6) } + val clusterResult by remember(markers, groupingEnabled, canvasSize) { + derivedStateOf { + StationMapClusterer.cluster( + markers, + mapState.viewportFor(canvasSize.width, canvasSize.height), + groupingEnabled, + ) + } + } + + /* + * Fetching belongs here and not in the draw pass. A tile the fetcher already holds + * completes its future inline, so a fetch started while drawing would write the + * cache and ask for a redraw in the middle of the frame that needed it — and the + * frame would go out without it. + */ + LaunchedEffect(tileFetcher) { + /* + * Read inside a snapshotFlow and not as effect keys. Keys are read during + * composition, so keying on the zoom and the centre would recompose this whole + * composable — and rebuild its gesture nodes — on every frame of a drag, when + * all the frame needs is a redraw. + */ + snapshotFlow { + TileRequest(canvasSize, mapState.zoom, mapState.centerLon, mapState.centerLat) + }.collectLatest { request -> + if (request.size.width <= 0f || request.size.height <= 0f) { + return@collectLatest + } + val viewport = mapState.viewportFor(request.size.width, request.size.height) + for (key in visibleTileKeys(viewport)) { + if (imageCache.contains(key.cacheKey) || !fetchingTiles.add(key.cacheKey)) { + continue + } + tileFetcher.fetchTileAsync(key.zoom, key.x, key.y).whenComplete { bytes, _ -> + try { + if (bytes != null) { + imageCache.put(key.cacheKey, Image.makeFromEncoded(bytes).toComposeImageBitmap()) + tileRevision++ + } + } catch (undecodable: Exception) { + /* + * Bytes that will not decode are a truncated or corrupt cache + * entry, and serving them again on the next pan would blank that + * square for good. Thrown away so the tile is fetched afresh. + */ + tileFetcher.discardTile(key.zoom, key.x, key.y) + } finally { + fetchingTiles.remove(key.cacheKey) + } + } + } + } + } + + Canvas( + modifier = modifier + .clipToBounds() + .onSizeChanged { canvasSize = Size(it.width.toFloat(), it.height.toFloat()) } + .pointerInput(Unit) { + detectTransformGestures { centroid, pan, zoomChange, _ -> + var viewport = mapState.viewportFor(size.width.toFloat(), size.height.toFloat()) + if (pan != Offset.Zero) { + viewport = viewport.pannedBy(pan.x.toDouble(), pan.y.toDouble()) + } + if (zoomChange != 1f && zoomChange > 0f) { + viewport = viewport.zoomedTo( + viewport.zoom() + log2(zoomChange.toDouble()), + centroid.x.toDouble(), + centroid.y.toDouble(), + ) + } + mapState.applyFrom(viewport) + } + } + .pointerInput(Unit) { + awaitPointerEventScope { + while (true) { + val event = awaitPointerEvent() + when (event.type) { + PointerEventType.Scroll -> { + val change = event.changes.first() + val scrollDelta = change.scrollDelta.y + if (scrollDelta != 0f) { + val viewport = mapState.viewportFor(size.width.toFloat(), size.height.toFloat()) + mapState.applyFrom( + viewport.zoomedTo( + viewport.zoom() - scrollDelta.sign * ZOOM_STEP_PER_WHEEL_NOTCH, + change.position.x.toDouble(), + change.position.y.toDouble(), + ) + ) + } + } + + PointerEventType.Move -> hoverPosition = event.changes.first().position + PointerEventType.Exit -> hoverPosition = null + } + } + } + } + .pointerInput(markers, groupingEnabled, onMarkerClicked) { + detectTapGestures { offset -> + val viewport = mapState.viewportFor(size.width.toFloat(), size.height.toFloat()) + val result = StationMapClusterer.cluster(markers, viewport, groupingEnabled) + + val hitCluster = result.clusters().firstOrNull { cluster -> + within( + offset, + viewport.screenX(cluster.centerLon).toFloat(), + viewport.screenY(cluster.centerLat).toFloat(), + clusterRadiusPx(cluster.size()), + ) + } + if (hitCluster != null) { + /* + * A cluster click does not select a station. It moves towards the + * cluster and zooms in until the stations inside become visible, + * which is what the Leaflet map did. + */ + mapState.centerLon = hitCluster.centerLon + mapState.centerLat = hitCluster.centerLat + mapState.zoom = minOf( + StationMapClusterer.DISABLE_AT_ZOOM, + mapState.zoom + 1.0, + ).toFloat() + return@detectTapGestures + } + + val hit = result.individual().firstOrNull { marker -> + within( + offset, + viewport.screenX(marker.longitudeDeg()).toFloat(), + viewport.screenY(marker.latitudeDeg()).toFloat(), + MARKER_HIT_RADIUS_PX, + ) + } + if (hit != null) { + onMarkerClicked?.invoke(hit) + } + } + } + ) { + @Suppress("UNUSED_EXPRESSION") + tileRevision + + if (size.width <= 0f || size.height <= 0f) { + return@Canvas + } + + val viewport = mapState.viewportFor(size.width, size.height) + + drawRect(color = if (darkMode) MAP_BACKGROUND_DARK else MAP_BACKGROUND_LIGHT) + + drawTiles(viewport, imageCache, darkMode) + drawMaidenheadGrid(viewport, textMeasurer, darkMode) + drawBeamAndPath(viewport, home, antennaAzimuthDeg, antennaBeamWidthDeg, maxQrbKm, markers, selectedMarkerCallsign, darkMode) + drawStations(viewport, clusterResult, selectedMarkerCallsign, textMeasurer, darkMode) + drawHover(viewport, hoverPosition, clusterResult, textMeasurer) + } +} + +/* ------------------------------------------------------------------ tiles */ + +/** The view a tile request was made for; the unit snapshotFlow deduplicates on. */ +private data class TileRequest( + val size: Size, + val zoom: Float, + val centerLon: Double, + val centerLat: Double, +) + +/** One tile of the current view. */ +internal data class TileKey(val zoom: Int, val x: Int, val y: Int) { + val cacheKey: String get() = "$zoom/$x/$y" +} + +/** + * The tiles the viewport covers, east-west wrap applied. + * + * The world wraps at the antimeridian but the tile index does not, so a view straddling + * it asks for indices outside 0..last and they are brought back round. + */ +internal fun visibleTileKeys(viewport: MapViewport): List { + val tileZoom = viewport.tileZoom() + val lastTileIndex = (1 shl tileZoom) - 1 + + val firstX = floor(viewport.worldXAt(0.0) / TILE_SIZE).toInt() + val lastX = floor(viewport.worldXAt(viewport.widthPx()) / TILE_SIZE).toInt() + val firstY = floor(viewport.worldYAt(0.0) / TILE_SIZE).toInt() + val lastY = floor(viewport.worldYAt(viewport.heightPx()) / TILE_SIZE).toInt() + + val keys = mutableListOf() + for (tileY in firstY..lastY) { + if (tileY < 0 || tileY > lastTileIndex) { + continue + } + for (tileX in firstX..lastX) { + keys.add(TileKey(tileZoom, wrapTileX(tileX, lastTileIndex), tileY)) + } + } + return keys +} + +internal fun wrapTileX(tileX: Int, lastTileIndex: Int): Int { + val span = lastTileIndex + 1 + val wrapped = tileX % span + return if (wrapped < 0) wrapped + span else wrapped +} + +private fun DrawScope.drawTiles( + viewport: MapViewport, + imageCache: TileBitmapCache, + darkMode: Boolean, +) { + val tileZoom = viewport.tileZoom() + val lastTileIndex = (1 shl tileZoom) - 1 + + /* + * Rounded up. A tile scaled to a fractional width leaves a hairline of background + * between itself and its neighbour otherwise, and a grid of hairlines reads as a + * broken map. + */ + val tileSizePx = ceil(viewport.tileSizePx()).toInt().coerceAtLeast(1) + + val firstX = floor(viewport.worldXAt(0.0) / TILE_SIZE).toInt() + val lastX = floor(viewport.worldXAt(viewport.widthPx()) / TILE_SIZE).toInt() + val firstY = floor(viewport.worldYAt(0.0) / TILE_SIZE).toInt() + val lastY = floor(viewport.worldYAt(viewport.heightPx()) / TILE_SIZE).toInt() + + for (tileY in firstY..lastY) { + if (tileY < 0 || tileY > lastTileIndex) { + continue + } + for (tileX in firstX..lastX) { + val tile = imageCache[TileKey(tileZoom, wrapTileX(tileX, lastTileIndex), tileY).cacheKey] + ?: continue + + drawImage( + image = tile, + dstOffset = IntOffset( + floor(viewport.screenXForWorldX(tileX * TILE_SIZE)).toInt(), + floor(viewport.screenYForWorldY(tileY * TILE_SIZE)).toInt(), + ), + dstSize = IntSize(tileSizePx, tileSizePx), + alpha = if (darkMode) DARK_TILE_ALPHA else 1.0f, + ) + } + } +} + +/* ------------------------------------------------------------- grid */ + +private fun DrawScope.drawMaidenheadGrid( + viewport: MapViewport, + textMeasurer: TextMeasurer, + darkMode: Boolean, +) { + /* + * The planner decides the precision, whether labels are shown at all, and how many + * cells apart they sit. Without it every cell gets a line and a label, which at + * six-digit precision is a carpet of text rather than a grid. + */ + val plan = MaidenheadGridRenderPlanner.createPlan( + viewport.tileZoom(), + viewport.southLat(), + viewport.westLon(), + viewport.northLat(), + viewport.eastLon(), + viewport.widthPx(), + viewport.heightPx(), + ) + + val cells = MaidenheadGridUtils.buildVisibleCells( + viewport.southLat(), + viewport.westLon(), + viewport.northLat(), + viewport.eastLon(), + plan.precision(), + ) + + val lineColor = if (darkMode) GRID_LINE_DARK else GRID_LINE_LIGHT + val lineAlpha = if (darkMode) GRID_LINE_ALPHA_DARK else GRID_LINE_ALPHA_LIGHT + + /* + * Unique lines, not one stroked rectangle per cell. Neighbouring cells share an + * edge, so a rectangle each paints every interior line twice: at 0.48 a shared edge + * reaches about 0.73 while the outermost line stays at 0.48, and the grid comes out + * visibly uneven. Leaflet drew each line once. + */ + val verticals = sortedSetOf() + val horizontals = sortedSetOf() + for (cell in cells) { + verticals.add(viewport.screenX(cell.westLon()).toFloat()) + verticals.add(viewport.screenX(cell.eastLon()).toFloat()) + horizontals.add(viewport.screenY(cell.northLat()).toFloat()) + horizontals.add(viewport.screenY(cell.southLat()).toFloat()) + } + + for (x in verticals) { + drawLine( + color = lineColor, + alpha = lineAlpha, + start = Offset(x, 0f), + end = Offset(x, size.height), + strokeWidth = GRID_LINE_WIDTH_PX, + ) + } + for (y in horizontals) { + drawLine( + color = lineColor, + alpha = lineAlpha, + start = Offset(0f, y), + end = Offset(size.width, y), + strokeWidth = GRID_LINE_WIDTH_PX, + ) + } + + if (!plan.showLabels()) { + return + } + + val labelStyle = TextStyle( + color = GRID_LABEL_COLOR, + fontWeight = FontWeight.SemiBold, + fontSize = TextUnit(plan.labelFontSizePx().toFloat(), TextUnitType.Sp), + ) + val labelBackground = if (darkMode) GRID_LABEL_BACKGROUND_DARK else GRID_LABEL_BACKGROUND_LIGHT + + for (cell in cells) { + if (!plan.shouldShowLabel(cell) || cell.locatorLabel().isNullOrBlank()) { + continue + } + + /* Centred in the cell, the way the stylesheet's translate(-50%, -50%) was. */ + val centerX = viewport.screenX((cell.westLon() + cell.eastLon()) / 2.0).toFloat() + val centerY = viewport.screenY((cell.southLat() + cell.northLat()) / 2.0).toFloat() + + val layout = textMeasurer.measure(cell.locatorLabel(), style = labelStyle) + val x = centerX - layout.size.width / 2f + val y = centerY - layout.size.height / 2f + + drawRect( + color = labelBackground, + topLeft = Offset(x - GRID_LABEL_PADDING_PX, y), + size = Size(layout.size.width + GRID_LABEL_PADDING_PX * 2f, layout.size.height.toFloat()), + ) + drawText(textLayoutResult = layout, topLeft = Offset(x, y)) + } +} + +/* ------------------------------------------------- beam and path */ + +private fun DrawScope.drawBeamAndPath( + viewport: MapViewport, + home: Pair?, + antennaAzimuthDeg: Double, + antennaBeamWidthDeg: Double, + maxQrbKm: Double, + markers: List, + selectedMarkerCallsign: String?, + darkMode: Boolean, +) { + if (home == null) { + return + } + val (homeLat, homeLon) = home + + if (antennaBeamWidthDeg > 0.0 && maxQrbKm > 0.0) { + val polygon = Path() + buildBeamPolygon(homeLat, homeLon, antennaAzimuthDeg, antennaBeamWidthDeg, maxQrbKm) + .forEachIndexed { index, point -> + val x = viewport.screenX(point.second).toFloat() + val y = viewport.screenY(point.first).toFloat() + if (index == 0) polygon.moveTo(x, y) else polygon.lineTo(x, y) + } + polygon.close() + + drawPath(path = polygon, color = BEAM_COLOR, alpha = BEAM_FILL_ALPHA, style = Fill) + drawPath(path = polygon, color = BEAM_COLOR, style = Stroke(width = BEAM_STROKE_WIDTH_PX)) + } + + val selected = markers.firstOrNull { + it.callSignRaw() == selectedMarkerCallsign && it.hasUsablePosition() + } + if (selected != null) { + drawLine( + color = if (darkMode) CONNECTION_COLOR_DARK else CONNECTION_COLOR_LIGHT, + alpha = CONNECTION_ALPHA, + start = Offset(viewport.screenX(homeLon).toFloat(), viewport.screenY(homeLat).toFloat()), + end = Offset( + viewport.screenX(selected.longitudeDeg()).toFloat(), + viewport.screenY(selected.latitudeDeg()).toFloat(), + ), + strokeWidth = CONNECTION_STROKE_WIDTH_PX, + pathEffect = PathEffect.dashPathEffect(CONNECTION_DASH_PX), + ) + } + + /* + * The Leaflet map drew no home marker; the beam's apex was the only hint of where + * home is, and with the beam switched off there was none. A small dot is kept here + * deliberately. + */ + val homeX = viewport.screenX(homeLon).toFloat() + val homeY = viewport.screenY(homeLat).toFloat() + drawCircle(color = BEAM_COLOR, radius = HOME_RADIUS_PX, center = Offset(homeX, homeY)) + drawCircle(color = Color.White, radius = HOME_INNER_RADIUS_PX, center = Offset(homeX, homeY)) +} + +/* ---------------------------------------------------------- stations */ + +private fun DrawScope.drawStations( + viewport: MapViewport, + clusterResult: StationMapClusterer.Result, + selectedMarkerCallsign: String?, + textMeasurer: TextMeasurer, + darkMode: Boolean, +) { + for (cluster in clusterResult.clusters()) { + drawClusterBubble( + x = viewport.screenX(cluster.centerLon).toFloat(), + y = viewport.screenY(cluster.centerLat).toFloat(), + count = cluster.size(), + containsWorked = cluster.getMarkers().any { it.worked() }, + textMeasurer = textMeasurer, + ) + } + + for (marker in clusterResult.individual()) { + val x = viewport.screenX(marker.longitudeDeg()).toFloat() + val y = viewport.screenY(marker.latitudeDeg()).toFloat() + val selected = marker.callSignRaw() == selectedMarkerCallsign + + drawStationDot(x, y, selected, marker.worked(), marker.warningToMyDirection()) + drawStationLabel(x, y, marker.markerLabel(), marker.warningToMyDirection(), textMeasurer, darkMode) + } +} + +/** 12 px across, 16 px when selected — the sizes `.station-dot` declared. */ +private fun DrawScope.drawStationDot( + x: Float, + y: Float, + selected: Boolean, + worked: Boolean, + warning: Boolean, +) { + val radius = if (selected) SELECTED_DOT_RADIUS_PX else DOT_RADIUS_PX + val borderWidth = if (selected) SELECTED_DOT_BORDER_PX else DOT_BORDER_PX + val borderColor = when { + selected -> DOT_BORDER_SELECTED + warning -> DOT_BORDER_WARNING + worked -> DOT_BORDER_WORKED + else -> DOT_BORDER_DEFAULT + } + + drawCircle(color = DOT_FILL, radius = radius, center = Offset(x, y)) + drawCircle( + color = borderColor, + radius = radius - borderWidth / 2f, + center = Offset(x, y), + style = Stroke(width = borderWidth), + ) +} + +/** Up and to the right of the dot, as `.station-label` placed it. */ +private fun DrawScope.drawStationLabel( + x: Float, + y: Float, + label: String, + warning: Boolean, + textMeasurer: TextMeasurer, + darkMode: Boolean, +) { + if (label.isBlank()) { + return + } + + val layout = textMeasurer.measure( + label, + style = TextStyle( + color = if (warning) DOT_BORDER_WARNING else if (darkMode) LABEL_TEXT_DARK else LABEL_TEXT_LIGHT, + fontWeight = FontWeight.Bold, + fontSize = TextUnit(LABEL_FONT_SIZE_PX, TextUnitType.Sp), + ), + ) + + val boxLeft = x + LABEL_OFFSET_X_PX + val boxTop = y + LABEL_OFFSET_Y_PX + val boxWidth = layout.size.width + LABEL_PADDING_X_PX * 2f + val boxHeight = layout.size.height + LABEL_PADDING_Y_PX * 2f + + drawRect( + color = if (darkMode) LABEL_BACKGROUND_DARK else LABEL_BACKGROUND_LIGHT, + topLeft = Offset(boxLeft, boxTop), + size = Size(boxWidth, boxHeight), + ) + drawRect( + color = if (warning) DOT_BORDER_WARNING else if (darkMode) LABEL_BORDER_DARK else LABEL_BORDER_LIGHT, + topLeft = Offset(boxLeft, boxTop), + size = Size(boxWidth, boxHeight), + style = Stroke(width = LABEL_BORDER_WIDTH_PX), + ) + drawText( + textLayoutResult = layout, + topLeft = Offset(boxLeft + LABEL_PADDING_X_PX, boxTop + LABEL_PADDING_Y_PX), + ) +} + +/** 32, 36 or 42 px across, by the thresholds `buildClusterMarkerHtml` used. */ +private fun DrawScope.drawClusterBubble( + x: Float, + y: Float, + count: Int, + containsWorked: Boolean, + textMeasurer: TextMeasurer, +) { + val radius = clusterRadiusPx(count) + val borderColor = if (containsWorked) DOT_BORDER_WORKED else DOT_BORDER_DEFAULT + + drawCircle(color = CLUSTER_FILL, radius = radius, center = Offset(x, y)) + drawCircle( + color = borderColor, + radius = radius - DOT_BORDER_PX / 2f, + center = Offset(x, y), + style = Stroke(width = DOT_BORDER_PX), + ) + + val layout = textMeasurer.measure( + count.toString(), + style = TextStyle( + color = CLUSTER_TEXT, + fontWeight = FontWeight.ExtraBold, + fontSize = TextUnit(clusterFontSizePx(count), TextUnitType.Sp), + ), + ) + drawText( + textLayoutResult = layout, + topLeft = Offset(x - layout.size.width / 2f, y - layout.size.height / 2f), + ) +} + +/* ------------------------------------------------------------ hover */ + +private fun DrawScope.drawHover( + viewport: MapViewport, + hoverPosition: Offset?, + clusterResult: StationMapClusterer.Result, + textMeasurer: TextMeasurer, +) { + val position = hoverPosition ?: return + + val clusterUnderPointer = clusterResult.clusters().firstOrNull { cluster -> + within( + position, + viewport.screenX(cluster.centerLon).toFloat(), + viewport.screenY(cluster.centerLat).toFloat(), + clusterRadiusPx(cluster.size()), + ) + } + val markerUnderPointer = clusterResult.individual().firstOrNull { marker -> + within( + position, + viewport.screenX(marker.longitudeDeg()).toFloat(), + viewport.screenY(marker.latitudeDeg()).toFloat(), + MARKER_HIT_RADIUS_PX, + ) + } + + val text = when { + clusterUnderPointer != null -> MapMarkerClusterTooltip.build(clusterUnderPointer) + + markerUnderPointer != null -> markerUnderPointer.locator6().let { locator -> + if (locator.isBlank()) markerUnderPointer.displayCallSign() + else "${markerUnderPointer.displayCallSign()} ($locator)" + } + + else -> return + } + + val layout: TextLayoutResult = textMeasurer.measure( + text, + style = TextStyle(color = Color.Black, fontSize = TextUnit(LABEL_FONT_SIZE_PX, TextUnitType.Sp)), + ) + val boxWidth = layout.size.width + TOOLTIP_PADDING_PX * 2f + val boxHeight = layout.size.height + TOOLTIP_PADDING_PX * 2f + + /* + * Flipped away from the edge it would cross, then held inside the canvas. Flipping + * alone is not enough: a cluster tooltip is as tall as it has lines, and one taller + * than the canvas would otherwise be placed at a negative offset and cover the map + * it exists to explain. + */ + val left = ( + if (position.x + TOOLTIP_OFFSET_PX + boxWidth > size.width) { + position.x - TOOLTIP_OFFSET_PX - boxWidth + } else { + position.x + TOOLTIP_OFFSET_PX + } + ).coerceIn(0f, (size.width - boxWidth).coerceAtLeast(0f)) + val top = ( + if (position.y + TOOLTIP_OFFSET_PX + boxHeight > size.height) { + position.y - TOOLTIP_OFFSET_PX - boxHeight + } else { + position.y + TOOLTIP_OFFSET_PX + } + ).coerceIn(0f, (size.height - boxHeight).coerceAtLeast(0f)) + + drawRect(color = TOOLTIP_BACKGROUND, topLeft = Offset(left, top), size = Size(boxWidth, boxHeight)) + drawRect( + color = TOOLTIP_BORDER, + topLeft = Offset(left, top), + size = Size(boxWidth, boxHeight), + style = Stroke(width = 1f), + ) + drawText( + textLayoutResult = layout, + topLeft = Offset(left + TOOLTIP_PADDING_PX, top + TOOLTIP_PADDING_PX), + ) +} + +/* ----------------------------------------------------------- helpers */ + +private val MapMarkerCluster.centerLon: Double get() = getCenterLon() +private val MapMarkerCluster.centerLat: Double get() = getCenterLat() + +private fun within(point: Offset, x: Float, y: Float, radius: Float): Boolean { + val dx = point.x - x + val dy = point.y - y + return dx * dx + dy * dy <= radius * radius +} + +private fun clusterRadiusPx(count: Int): Float = when { + count >= CLUSTER_LARGE_FROM -> CLUSTER_RADIUS_LARGE_PX + count >= CLUSTER_MEDIUM_FROM -> CLUSTER_RADIUS_MEDIUM_PX + else -> CLUSTER_RADIUS_SMALL_PX +} + +private fun clusterFontSizePx(count: Int): Float = when { + count >= CLUSTER_LARGE_FROM -> 15f + count >= CLUSTER_MEDIUM_FROM -> 14f + else -> 13f +} + +/** Null rather than a guess when the operator has no usable locator configured. */ +private fun homePosition(ownLocator6: String): Pair? { + if (ownLocator6.length < 4) { + return null + } + return try { + val location = kst4contest.locatorUtils.Location(ownLocator6) + Pair(location.latitude.toDegrees(), location.longitude.toDegrees()) + } catch (malformedLocator: Exception) { + null + } +} + +fun calculateDestinationPoint( + startLatDeg: Double, + startLonDeg: Double, + bearingDeg: Double, + distanceKm: Double, +): Pair { + val earthRadiusKm = 6371.009 + val angularDistance = distanceKm / earthRadiusKm + val bearingRad = Math.toRadians(bearingDeg) + val startLatRad = Math.toRadians(startLatDeg) + val startLonRad = Math.toRadians(startLonDeg) + + val destLatRad = kotlin.math.asin( + kotlin.math.sin(startLatRad) * kotlin.math.cos(angularDistance) + + kotlin.math.cos(startLatRad) * kotlin.math.sin(angularDistance) * kotlin.math.cos(bearingRad) + ) + val destLonRad = startLonRad + kotlin.math.atan2( + kotlin.math.sin(bearingRad) * kotlin.math.sin(angularDistance) * kotlin.math.cos(startLatRad), + kotlin.math.cos(angularDistance) - kotlin.math.sin(startLatRad) * kotlin.math.sin(destLatRad) + ) + + return Pair(Math.toDegrees(destLatRad), Math.toDegrees(destLonRad)) +} + +fun buildBeamPolygon( + startLatDeg: Double, + startLonDeg: Double, + centerAzimuthDeg: Double, + beamWidthDeg: Double, + radiusKm: Double, +): List> { + val polygon = mutableListOf(Pair(startLatDeg, startLonDeg)) + + val segmentCount = maxOf(12, ceil(beamWidthDeg / 4.0).toInt()) + val angleStep = beamWidthDeg / segmentCount + val startAzimuth = centerAzimuthDeg - beamWidthDeg / 2.0 + + for (segment in 0..segmentCount) { + var azimuth = startAzimuth + segment * angleStep + if (azimuth < 0.0) azimuth += 360.0 + if (azimuth >= 360.0) azimuth -= 360.0 + polygon.add(calculateDestinationPoint(startLatDeg, startLonDeg, azimuth, radiusKm)) + } + + polygon.add(Pair(startLatDeg, startLonDeg)) + return polygon +} + +/* --------------------------------------------------------- constants + * + * Every size is in canvas pixels and every colour is the one the Leaflet stylesheet + * declared, so the two maps can be held side by side. + */ + +private const val TILE_SIZE = 256.0 +private const val DARK_TILE_ALPHA = 0.82f +private const val ZOOM_STEP_PER_WHEEL_NOTCH = 0.5 + +private val MAP_BACKGROUND_LIGHT = Color(0xFFEDE9DF) +private val MAP_BACKGROUND_DARK = Color(0xFF23282D) + +private val GRID_LINE_DARK = Color(0xFFE1E7EC) +private val GRID_LINE_LIGHT = Color(0xFF46586C) +private const val GRID_LINE_ALPHA_DARK = 0.48f +private const val GRID_LINE_ALPHA_LIGHT = 0.56f +private const val GRID_LINE_WIDTH_PX = 1.4f + +private val GRID_LABEL_COLOR = Color(0xFF63067A) +private val GRID_LABEL_BACKGROUND_LIGHT = Color.White.copy(alpha = 0.18f) +private val GRID_LABEL_BACKGROUND_DARK = Color(0xFF22262B).copy(alpha = 0.20f) +private const val GRID_LABEL_PADDING_PX = 3f + +private val DOT_FILL = Color(0xFF1D1D1D) +private val DOT_BORDER_DEFAULT = Color(0xFF4DA6FF) +private val DOT_BORDER_WORKED = Color(0xFFFFD24D) +private val DOT_BORDER_WARNING = Color(0xFF00FF66) +private val DOT_BORDER_SELECTED = Color(0xFFFF9900) +private const val DOT_RADIUS_PX = 6f +private const val DOT_BORDER_PX = 2f +private const val SELECTED_DOT_RADIUS_PX = 8f +private const val SELECTED_DOT_BORDER_PX = 3f +private const val MARKER_HIT_RADIUS_PX = 10f + +private val LABEL_BACKGROUND_LIGHT = Color(0xFFF8F8F8).copy(alpha = 0.95f) +private val LABEL_BACKGROUND_DARK = Color(0xFF24282D).copy(alpha = 0.96f) +private val LABEL_TEXT_LIGHT = Color(0xFF1C1C1C) +private val LABEL_TEXT_DARK = Color(0xFFF1F3F5) +private val LABEL_BORDER_LIGHT = Color.Black.copy(alpha = 0.20f) +private val LABEL_BORDER_DARK = Color.White.copy(alpha = 0.18f) +private const val LABEL_FONT_SIZE_PX = 12f +private const val LABEL_BORDER_WIDTH_PX = 1f +private const val LABEL_PADDING_X_PX = 5f +private const val LABEL_PADDING_Y_PX = 2f +private const val LABEL_OFFSET_X_PX = 10f +private const val LABEL_OFFSET_Y_PX = -22f + +private val CLUSTER_FILL = Color(0xFF202428) +private val CLUSTER_TEXT = Color(0xFFF1F3F5) +private const val CLUSTER_MEDIUM_FROM = 8 +private const val CLUSTER_LARGE_FROM = 20 +private const val CLUSTER_RADIUS_SMALL_PX = 16f +private const val CLUSTER_RADIUS_MEDIUM_PX = 18f +private const val CLUSTER_RADIUS_LARGE_PX = 21f + +private val BEAM_COLOR = Color(0xFFFF4D4D) +private const val BEAM_FILL_ALPHA = 0.12f +private const val BEAM_STROKE_WIDTH_PX = 2f +private const val HOME_RADIUS_PX = 6f +private const val HOME_INNER_RADIUS_PX = 2f + +private val CONNECTION_COLOR_DARK = Color(0xFF2FD7FF) +private val CONNECTION_COLOR_LIGHT = Color(0xFF00A4CF) +private const val CONNECTION_ALPHA = 0.85f +private const val CONNECTION_STROKE_WIDTH_PX = 2f +private val CONNECTION_DASH_PX = floatArrayOf(6f, 6f) + +private val TOOLTIP_BACKGROUND = Color.White.copy(alpha = 0.92f) +private val TOOLTIP_BORDER = Color.Black +private const val TOOLTIP_PADDING_PX = 4f +private const val TOOLTIP_OFFSET_PX = 12f diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/map/MapOverlayControls.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/map/MapOverlayControls.kt new file mode 100644 index 00000000..53c24649 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/map/MapOverlayControls.kt @@ -0,0 +1,120 @@ +package kst4contest.view.compose.map + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.BoxScope +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.text.style.TextAlign +import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.unit.TextUnitType +import androidx.compose.ui.unit.dp +import kst4contest.view.map.MapViewport + +/** The zoom range the tile source serves, as the viewport defines it. */ +internal val MIN_MAP_ZOOM = MapViewport.MIN_ZOOM.toFloat() +internal val MAX_MAP_ZOOM = MapViewport.MAX_ZOOM.toFloat() + +/** + * The two things Leaflet drew on top of the map itself. + * + * The zoom buttons, because a map without them can only be zoomed by a wheel or a + * trackpad and neither is a given on a contest laptop. And the OpenStreetMap + * attribution, which is not decoration: the tile licence requires it to be visible + * wherever the tiles are. + */ +@Composable +internal fun BoxScope.MapOverlayControls( + darkMode: Boolean, + tilesUnavailable: Boolean, + onZoomIn: () -> Unit, + onZoomOut: () -> Unit, +) { + val strings = LocalStrings.current + Column( + modifier = Modifier.align(Alignment.TopStart).padding(10.dp), + ) { + val strings = LocalStrings.current + ZoomButton("+", darkMode, onZoomIn) + ZoomButton("−", darkMode, onZoomOut) + } + + if (tilesUnavailable) { + /* + * Said out loud. An empty map and a map with no stations on it look the same, + * and an operator in a contest should not have to guess which one they have. + */ + Text( + text = strings.mapTilesUnavailable, + color = TILE_WARNING_TEXT, + fontWeight = FontWeight.Bold, + modifier = Modifier + .align(Alignment.TopCenter) + .padding(top = 10.dp) + .background(TILE_WARNING_BACKGROUND, RoundedCornerShape(4.dp)) + .padding(horizontal = 8.dp, vertical = 4.dp), + ) + } + + Text( + text = "© OpenStreetMap contributors", + fontSize = TextUnit(10f, TextUnitType.Sp), + color = if (darkMode) ATTRIBUTION_TEXT_DARK else ATTRIBUTION_TEXT_LIGHT, + modifier = Modifier + .align(Alignment.BottomEnd) + .background(if (darkMode) ATTRIBUTION_BACKGROUND_DARK else ATTRIBUTION_BACKGROUND_LIGHT) + .padding(horizontal = 4.dp, vertical = 1.dp), + ) +} + +@Composable +private fun ZoomButton(label: String, darkMode: Boolean, onClick: () -> Unit) { + Box( + modifier = Modifier + .size(26.dp) + .background( + if (darkMode) CONTROL_BACKGROUND_DARK else CONTROL_BACKGROUND_LIGHT, + RoundedCornerShape(3.dp), + ) + .border( + 1.dp, + if (darkMode) CONTROL_BORDER_DARK else CONTROL_BORDER_LIGHT, + RoundedCornerShape(3.dp), + ) + .clickable(onClick = onClick), + contentAlignment = Alignment.Center, + ) { + val strings = LocalStrings.current + Text( + text = label, + color = if (darkMode) CONTROL_TEXT_DARK else CONTROL_TEXT_LIGHT, + fontWeight = FontWeight.Bold, + textAlign = TextAlign.Center, + ) + } +} + +/* The `--control-*` and `--attribution-*` values of the Leaflet stylesheet. */ +private val CONTROL_BACKGROUND_LIGHT = Color(0xFFFFFFFF).copy(alpha = 0.96f) +private val CONTROL_BACKGROUND_DARK = Color(0xFF373E43).copy(alpha = 0.96f) +private val CONTROL_TEXT_LIGHT = Color(0xFF242424) +private val CONTROL_TEXT_DARK = Color(0xFFE2E6EA) +private val CONTROL_BORDER_LIGHT = Color(0xFFB7B7B7) +private val CONTROL_BORDER_DARK = Color(0xFF556068) +private val ATTRIBUTION_BACKGROUND_LIGHT = Color(0xFFFFFFFF).copy(alpha = 0.88f) +private val ATTRIBUTION_BACKGROUND_DARK = Color(0xFF22262B).copy(alpha = 0.86f) +private val ATTRIBUTION_TEXT_LIGHT = Color(0xFF2D2D2D) +private val ATTRIBUTION_TEXT_DARK = Color(0xFFD2D8DD) +private val TILE_WARNING_TEXT = Color(0xFFFFE0B2) +private val TILE_WARNING_BACKGROUND = Color(0xFF5A2B20).copy(alpha = 0.92f) diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/map/PathAnalysisDetails.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/map/PathAnalysisDetails.kt new file mode 100644 index 00000000..3324c7a3 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/map/PathAnalysisDetails.kt @@ -0,0 +1,151 @@ +package kst4contest.view.compose.map + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.TextUnit +import androidx.compose.ui.unit.TextUnitType +import androidx.compose.ui.unit.dp +import kst4contest.view.map.PathAnalysisResult + +/** + * The path and terrain analysis column of the station map window. + * + * It lives in its own file so that it can be composed in a test. The window around it + * needs a running application runtime and a chat controller; this column needs nothing + * but a result, which is what made the layout defect below invisible to the suite for + * as long as it existed. + */ +@Composable +internal fun PathAnalysisDetails( + result: PathAnalysisResult?, + darkMode: Boolean, + modifier: Modifier = Modifier, +) { + val strings = LocalStrings.current + Column(modifier) { + Text( + strings.pathTitle, + fontSize = TextUnit(12f, TextUnitType.Sp), + fontWeight = FontWeight.Bold, + modifier = Modifier.padding(top = 2.dp), + ) + HorizontalDivider(Modifier.padding(vertical = 2.dp)) + + if (result == null) { + Text( + strings.pathSelectStation, + fontSize = TextUnit(12f, TextUnitType.Sp), + ) + return@Column + } + + DetailRow(strings.pathFromLocator, result.fromLocator6().ifBlank { "-" }) + DetailRow(strings.pathToLocator, result.toLocator6().ifBlank { "-" }) + DetailRow(strings.pathDistanceQtf, "${result.distanceText()} / ${result.bearingText()}") + DetailRow(strings.pathEndpoints, result.endpointSummaryText()) + DetailRow(strings.pathSource, "${result.analysisMode().ifBlank { "-" }} / ${result.profilePoints().size} samples") + DetailRow(strings.pathFrequency, result.analysisFrequencyText()) + DetailRow(strings.pathRefraction, result.effectiveEarthRadiusText()) + DetailRow(strings.pathRadioHorizon, result.radioHorizonText()) + DetailRow(strings.pathTerrainHorizon, result.terrainHorizonText()) + DetailRow(strings.pathFresnel, "${result.fresnelText()} / ${result.worstFresnelClearanceText()}") + DetailRow(strings.pathObstruction, result.obstructionText()) + + val severity = result.propagationSeverityLevel() + val textColor = if (darkMode) Color(0xFFF0F0F0) else Color(0xFF202020) + val backgroundColor = when (severity) { + 1 -> if (darkMode) Color(0xFF1F4D2B) else Color(0xFFD8F3DC) + 2 -> if (darkMode) Color(0xFF4A4420) else Color(0xFFFFF3BF) + 3 -> if (darkMode) Color(0xFF4D3520) else Color(0xFFFFE0B2) + 4 -> if (darkMode) Color(0xFF5A2B20) else Color(0xFFFFC9A9) + 5 -> if (darkMode) Color(0xFF5A2020) else Color(0xFFFFCDD2) + else -> if (darkMode) Color(0xFF33383E) else Color(0xFFEEEEEE) + } + val borderColor = when (severity) { + 1 -> Color(0xFF3AA655) + 2 -> Color(0xFFD4A017) + 3 -> Color(0xFFE69138) + 4 -> Color(0xFFD96C2C) + 5 -> Color(0xFFD63B3B) + else -> if (darkMode) Color(0xFF666F78) else Color(0xFFCCCCCC) + } + + Row(Modifier.padding(vertical = 2.dp).fillMaxWidth()) { + Text( + strings.pathAssessment, + modifier = Modifier.weight(LABEL_WEIGHT), + color = MaterialTheme.colorScheme.onSurfaceVariant, + fontSize = TextUnit(11f, TextUnitType.Sp), + lineHeight = TextUnit(13f, TextUnitType.Sp), + ) + Box(modifier = Modifier.weight(VALUE_WEIGHT)) { + Box( + modifier = Modifier + .background(backgroundColor, RoundedCornerShape(4.dp)) + .border(1.dp, borderColor, RoundedCornerShape(4.dp)) + .padding(horizontal = 6.dp, vertical = 3.dp), + ) { + Text(result.propagationAssessmentText(), color = textColor, fontWeight = FontWeight.Bold) + } + } + } + + DetailRow(strings.pathLinkBudget, result.linkBudgetText()) + DetailRow(strings.pathRxPower, result.linkBudgetRxPowerText()) + DetailRow(strings.pathCwHint, result.cwHintText()) + DetailRow(strings.pathMechanisms, result.propagationMechanismsText(), valueColor = textColor, valueBold = true) + DetailRow(strings.pathLos, "${result.losText()} / worst ${result.worstClearanceText()}") + DetailRow(strings.pathStatus, result.statusText()) + } +} + +/** + * One label and its value. + * + * Both columns are weighted, and the assessment row above follows the same two weights + * rather than a fixed label width. A fixed width does not shrink: at a narrow pane it + * keeps its dp and the value beside it gets whatever is left, which was 35% of the pane + * at 200 px and nothing at all at 60 px. + */ +@Composable +private fun DetailRow( + label: String, + value: String, + valueColor: Color = Color.Unspecified, + valueBold: Boolean = false, +) { + val strings = LocalStrings.current + Row(Modifier.fillMaxWidth()) { + Text( + text = label, + modifier = Modifier.weight(LABEL_WEIGHT), + fontSize = TextUnit(11f, TextUnitType.Sp), + lineHeight = TextUnit(13f, TextUnitType.Sp), + ) + Text( + text = value, + modifier = Modifier.weight(VALUE_WEIGHT), + color = valueColor, + fontWeight = if (valueBold) FontWeight.Bold else null, + fontSize = TextUnit(11f, TextUnitType.Sp), + lineHeight = TextUnit(13f, TextUnitType.Sp), + ) + } +} + +private const val LABEL_WEIGHT = 0.38f +private const val VALUE_WEIGHT = 0.62f diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/map/PathProfileChart.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/map/PathProfileChart.kt new file mode 100644 index 00000000..6e8e7ebc --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/map/PathProfileChart.kt @@ -0,0 +1,585 @@ +package kst4contest.view.compose.map + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.Canvas +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.geometry.Size +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.Path +import androidx.compose.ui.graphics.PathEffect +import androidx.compose.ui.graphics.drawscope.DrawScope +import androidx.compose.ui.graphics.drawscope.Fill +import androidx.compose.ui.graphics.drawscope.Stroke +import androidx.compose.ui.input.pointer.PointerEventType +import androidx.compose.ui.input.pointer.onPointerEvent +import androidx.compose.ui.text.TextMeasurer +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.drawText +import androidx.compose.ui.text.rememberTextMeasurer +import androidx.compose.ui.unit.sp +import androidx.compose.ui.ExperimentalComposeUiApi +import kst4contest.view.map.PathGeometryUtils +import kst4contest.view.map.PathHorizonSummary +import kst4contest.view.map.PathObstructionSummary +import kst4contest.view.map.PathProfilePoint +import java.util.Locale +import kotlin.math.abs +import kotlin.math.max +import kotlin.math.min + +@OptIn(ExperimentalComposeUiApi::class) +@Composable +fun PathProfileChart( + modifier: Modifier = Modifier, + profilePoints: List = emptyList(), + totalDistanceKm: Double = Double.NaN, + darkMode: Boolean = false, + homeAntennaHeightMeters: Double = Double.NaN, + targetAntennaHeightMeters: Double = Double.NaN, + analysisFrequencyMHz: Double = Double.NaN, + effectiveEarthRadiusFactor: Double = PathGeometryUtils.DEFAULT_EFFECTIVE_EARTH_RADIUS_FACTOR, + horizonSummary: PathHorizonSummary = PathHorizonSummary.empty(), + obstructionSummary: PathObstructionSummary = PathObstructionSummary.empty(), + onProfilePointHovered: ((PathProfilePoint?) -> Unit)? = null +) { + val strings = LocalStrings.current + + val textMeasurer = rememberTextMeasurer() + val textStyle = TextStyle(fontSize = 12.sp) + + Canvas(modifier = modifier + .onPointerEvent(PointerEventType.Move) { event -> + if (onProfilePointHovered != null && profilePoints.isNotEmpty()) { + val position = event.changes.first().position + val x = position.x.toDouble() + val left = 58.0 + val right = 18.0 + // For a proper hover, we need the total width of the Canvas, which we can get from the layout or event + // event.changes bounds? We can assume the size is roughly available if we store it. + // Alternatively, we use awaitPointerEventScope inside pointerInput which gives access to size. + } + } + .onPointerEvent(PointerEventType.Exit) { + onProfilePointHovered?.invoke(null) + } + ) { + val width = size.width.toDouble() + val height = size.height.toDouble() + + if (width <= 1.0 || height <= 1.0) { + return@Canvas + } + + // --- Colors --- + val background = if (darkMode) Color(34, 39, 43) else Color(248, 248, 248) + val border = if (darkMode) Color(96, 106, 116) else Color(180, 180, 180) + val gridColor = if (darkMode) Color(95, 105, 115, (255 * 0.70).toInt()) else Color(185, 185, 185, (255 * 0.75).toInt()) + val textColor = if (darkMode) Color(230, 235, 239) else Color(40, 40, 40) + + val terrainFill = if (darkMode) Color(70, 165, 95, (255 * 0.35).toInt()) else Color(90, 180, 110, (255 * 0.35).toInt()) + val terrainLine = if (darkMode) Color(95, 210, 120) else Color(45, 150, 70) + + val losLine = if (darkMode) Color(255, 182, 80) else Color(220, 130, 20) + + val fresnelFill = if (darkMode) Color(170, 135, 255, (255 * 0.16).toInt()) else Color(150, 105, 240, (255 * 0.16).toInt()) + val fresnelLine = if (darkMode) Color(205, 155, 255) else Color(130, 75, 210) + + val endpointMarker = if (darkMode) Color(245, 245, 245) else Color(45, 45, 45) + val horizonMarker = if (darkMode) Color(95, 190, 255) else Color(30, 120, 200) + val criticalMarker = if (darkMode) Color(255, 100, 100) else Color(210, 45, 45) + + val terrainHorizonMarker = if (darkMode) Color(255, 220, 105) else Color(185, 125, 0) + val obstructionMarker = if (darkMode) Color(255, 135, 75) else Color(225, 85, 30) + + drawRect(color = background) + drawRect( + color = border, + topLeft = Offset(0.5f, 0.5f), + size = Size((width - 1.0).toFloat(), (height - 1.0).toFloat()), + style = Stroke(1.0f) + ) + + val left = 58.0 + val headerTop = 12.0 + val headerHeight = 34.0 + val endpointTextHeight = 18.0 + val top = headerTop + headerHeight + endpointTextHeight + val right = 18.0 + val bottom = 56.0 + + val plotX = left + val plotY = top + val plotWidth = max(10.0, width - left - right) + val plotHeight = max(10.0, height - top - bottom) + + // Draw Grid + for (i in 0..4) { + val y = plotY + plotHeight * i / 4.0 + drawLine(gridColor, Offset(plotX.toFloat(), y.toFloat()), Offset((plotX + plotWidth).toFloat(), y.toFloat()), strokeWidth = 1f) + } + for (i in 0..4) { + val x = plotX + plotWidth * i / 4.0 + drawLine(gridColor, Offset(x.toFloat(), plotY.toFloat()), Offset(x.toFloat(), (plotY + plotHeight).toFloat()), strokeWidth = 1f) + } + + fun estimateTextWidth(text: String?): Double { + if (text.isNullOrBlank()) return 0.0 + // Simple approximation like in JavaFX code + return text.length * 6.2 + } + + fun drawAxisLabels(minElevation: Double, maxElevation: Double) { + val style = textStyle.copy(color = textColor) + for (i in 0..4) { + val fraction = i / 4.0 + val y = plotY + plotHeight - fraction * plotHeight + val value = minElevation + fraction * (maxElevation - minElevation) + safeDrawText(textMeasurer, String.format(Locale.US, "%.0f", value), topLeft = Offset(8f, (y - 6).toFloat()), style = style) + } + val xFractions = doubleArrayOf(0.0, 0.25, 0.50, 0.75, 1.0) + for (xFraction in xFractions) { + val x = plotX + xFraction * plotWidth + val distance = if (totalDistanceKm.isFinite()) totalDistanceKm * xFraction else 0.0 + safeDrawText(textMeasurer, String.format(Locale.US, "%.0f", distance), topLeft = Offset((x - 8).toFloat(), (plotY + plotHeight + 16.0).toFloat()), style = style) + } + safeDrawText(textMeasurer, strings.chartHeightAxis, topLeft = Offset(plotX.toFloat(), (plotY - 14.0).toFloat()), style = style) + safeDrawText(textMeasurer, strings.chartDistanceAxis, topLeft = Offset((plotX + plotWidth / 2.0 - 30.0).toFloat(), (plotY + plotHeight + 34.0).toFloat()), style = style) + if (analysisFrequencyMHz.isFinite() && analysisFrequencyMHz > 0.0) { + val freqText = strings.chartFrequency(String.format(Locale.US, "%.3f", analysisFrequencyMHz)) + safeDrawText(textMeasurer, freqText, topLeft = Offset((plotX + plotWidth - estimateTextWidth(freqText)).toFloat(), (plotY + plotHeight + 34.0).toFloat()), style = style) + } + } + + if (profilePoints.isEmpty()) { + safeDrawText(textMeasurer, strings.chartNoSamples, topLeft = Offset(plotX.toFloat(), (plotY + plotHeight / 2.0).toFloat()), style = textStyle.copy(color = textColor)) + drawAxisLabels(0.0, 1.0) + return@Canvas + } + + fun terrainDisplayElevationMeters(point: PathProfilePoint?): Double { + if (point == null) return Double.NaN + if (point.curvatureAdjustedElevationMeters().isFinite()) { + return point.curvatureAdjustedElevationMeters() + } + return PathGeometryUtils.calculateCurvatureAdjustedElevationMeters(point, totalDistanceKm) + } + + fun determineMinimumElevation(): Double { + var minElev = Double.POSITIVE_INFINITY + for (point in profilePoints) { + minElev = min(minElev, terrainDisplayElevationMeters(point)) + if (point.lineOfSightHeightMeters().isFinite()) minElev = min(minElev, point.lineOfSightHeightMeters()) + if (point.fresnelUpperHeightMeters().isFinite()) minElev = min(minElev, point.fresnelUpperHeightMeters()) + if (point.fresnelLowerHeightMeters().isFinite()) minElev = min(minElev, point.fresnelLowerHeightMeters()) + } + return if (minElev.isInfinite()) 0.0 else minElev + } + + fun determineMaximumElevation(): Double { + var maxElev = Double.NEGATIVE_INFINITY + for (point in profilePoints) { + maxElev = max(maxElev, terrainDisplayElevationMeters(point)) + if (point.lineOfSightHeightMeters().isFinite()) maxElev = max(maxElev, point.lineOfSightHeightMeters()) + if (point.fresnelUpperHeightMeters().isFinite()) maxElev = max(maxElev, point.fresnelUpperHeightMeters()) + if (point.fresnelLowerHeightMeters().isFinite()) maxElev = max(maxElev, point.fresnelLowerHeightMeters()) + } + return if (maxElev.isInfinite()) 1.0 else maxElev + } + + var minElevation = determineMinimumElevation() + var maxElevation = determineMaximumElevation() + var elevationRange = max(1.0, maxElevation - minElevation) + val paddingMeters = max(20.0, elevationRange * 0.08) + + minElevation -= paddingMeters + maxElevation += paddingMeters + elevationRange = max(1.0, maxElevation - minElevation) + + fun normalizeDistance(distanceKm: Double): Double { + if (!totalDistanceKm.isFinite() || totalDistanceKm <= 0.0) return 0.0 + return max(0.0, min(1.0, distanceKm / totalDistanceKm)) + } + + fun normalizeElevation(elevationMeters: Double, minElev: Double, elevRange: Double): Double { + return max(0.0, min(1.0, (elevationMeters - minElev) / elevRange)) + } + + fun hasEnrichedLosGeometry(): Boolean { + return profilePoints.any { it.lineOfSightHeightMeters().isFinite() } + } + + fun hasEnrichedFresnelGeometry(): Boolean { + return profilePoints.any { it.fresnelUpperHeightMeters().isFinite() || it.fresnelLowerHeightMeters().isFinite() } + } + + // Draw terrain fill + if (profilePoints.size >= 2) { + val path = Path() + path.moveTo((plotX + normalizeDistance(profilePoints.first().distanceKm()) * plotWidth).toFloat(), (plotY + plotHeight).toFloat()) + for (point in profilePoints) { + val x = plotX + normalizeDistance(point.distanceKm()) * plotWidth + val y = plotY + plotHeight - normalizeElevation(terrainDisplayElevationMeters(point), minElevation, elevationRange) * plotHeight + path.lineTo(x.toFloat(), y.toFloat()) + } + path.lineTo((plotX + normalizeDistance(profilePoints.last().distanceKm()) * plotWidth).toFloat(), (plotY + plotHeight).toFloat()) + path.close() + drawPath(path, color = terrainFill, style = Fill) + } + + // Draw Fresnel fill + if (hasEnrichedFresnelGeometry() && profilePoints.size >= 2) { + val allFresnelFinite = profilePoints.all { it.fresnelUpperHeightMeters().isFinite() && it.fresnelLowerHeightMeters().isFinite() } + if (allFresnelFinite) { + val path = Path() + path.moveTo((plotX + normalizeDistance(profilePoints.first().distanceKm()) * plotWidth).toFloat(), + (plotY + plotHeight - normalizeElevation(profilePoints.first().fresnelUpperHeightMeters(), minElevation, elevationRange) * plotHeight).toFloat()) + + for (point in profilePoints) { + val x = plotX + normalizeDistance(point.distanceKm()) * plotWidth + val y = plotY + plotHeight - normalizeElevation(point.fresnelUpperHeightMeters(), minElevation, elevationRange) * plotHeight + path.lineTo(x.toFloat(), y.toFloat()) + } + for (i in profilePoints.indices.reversed()) { + val point = profilePoints[i] + val x = plotX + normalizeDistance(point.distanceKm()) * plotWidth + val y = plotY + plotHeight - normalizeElevation(point.fresnelLowerHeightMeters(), minElevation, elevationRange) * plotHeight + path.lineTo(x.toFloat(), y.toFloat()) + } + path.close() + drawPath(path, color = fresnelFill, style = Fill) + } + } + + // Draw terrain line + for (i in 1 until profilePoints.size) { + val prev = profilePoints[i - 1] + val curr = profilePoints[i] + val x1 = plotX + normalizeDistance(prev.distanceKm()) * plotWidth + val y1 = plotY + plotHeight - normalizeElevation(terrainDisplayElevationMeters(prev), minElevation, elevationRange) * plotHeight + val x2 = plotX + normalizeDistance(curr.distanceKm()) * plotWidth + val y2 = plotY + plotHeight - normalizeElevation(terrainDisplayElevationMeters(curr), minElevation, elevationRange) * plotHeight + drawLine(terrainLine, Offset(x1.toFloat(), y1.toFloat()), Offset(x2.toFloat(), y2.toFloat()), strokeWidth = 2f) + } + + // Draw Fresnel hull + if (hasEnrichedFresnelGeometry()) { + val dashEffect = PathEffect.dashPathEffect(floatArrayOf(6f, 4f)) + for (i in 1 until profilePoints.size) { + val prev = profilePoints[i - 1] + val curr = profilePoints[i] + if (prev.fresnelUpperHeightMeters().isFinite() && curr.fresnelUpperHeightMeters().isFinite()) { + val x1 = plotX + normalizeDistance(prev.distanceKm()) * plotWidth + val y1 = plotY + plotHeight - normalizeElevation(prev.fresnelUpperHeightMeters(), minElevation, elevationRange) * plotHeight + val x2 = plotX + normalizeDistance(curr.distanceKm()) * plotWidth + val y2 = plotY + plotHeight - normalizeElevation(curr.fresnelUpperHeightMeters(), minElevation, elevationRange) * plotHeight + drawLine(fresnelLine, Offset(x1.toFloat(), y1.toFloat()), Offset(x2.toFloat(), y2.toFloat()), strokeWidth = 1f, pathEffect = dashEffect) + } + if (prev.fresnelLowerHeightMeters().isFinite() && curr.fresnelLowerHeightMeters().isFinite()) { + val x1 = plotX + normalizeDistance(prev.distanceKm()) * plotWidth + val y1 = plotY + plotHeight - normalizeElevation(prev.fresnelLowerHeightMeters(), minElevation, elevationRange) * plotHeight + val x2 = plotX + normalizeDistance(curr.distanceKm()) * plotWidth + val y2 = plotY + plotHeight - normalizeElevation(curr.fresnelLowerHeightMeters(), minElevation, elevationRange) * plotHeight + drawLine(fresnelLine, Offset(x1.toFloat(), y1.toFloat()), Offset(x2.toFloat(), y2.toFloat()), strokeWidth = 1f, pathEffect = dashEffect) + } + } + } + + // Draw LOS line + if (hasEnrichedLosGeometry()) { + for (i in 1 until profilePoints.size) { + val prev = profilePoints[i - 1] + val curr = profilePoints[i] + if (prev.lineOfSightHeightMeters().isFinite() && curr.lineOfSightHeightMeters().isFinite()) { + val x1 = plotX + normalizeDistance(prev.distanceKm()) * plotWidth + val y1 = plotY + plotHeight - normalizeElevation(prev.lineOfSightHeightMeters(), minElevation, elevationRange) * plotHeight + val x2 = plotX + normalizeDistance(curr.distanceKm()) * plotWidth + val y2 = plotY + plotHeight - normalizeElevation(curr.lineOfSightHeightMeters(), minElevation, elevationRange) * plotHeight + drawLine(losLine, Offset(x1.toFloat(), y1.toFloat()), Offset(x2.toFloat(), y2.toFloat()), strokeWidth = 1.5f) + } + } + } else if (profilePoints.size >= 2 && homeAntennaHeightMeters.isFinite() && targetAntennaHeightMeters.isFinite()) { + val startAntennaMeters = terrainDisplayElevationMeters(profilePoints.first()) + homeAntennaHeightMeters + val endAntennaMeters = terrainDisplayElevationMeters(profilePoints.last()) + targetAntennaHeightMeters + val x1 = plotX + val y1 = plotY + plotHeight - normalizeElevation(startAntennaMeters, minElevation, elevationRange) * plotHeight + val x2 = plotX + plotWidth + val y2 = plotY + plotHeight - normalizeElevation(endAntennaMeters, minElevation, elevationRange) * plotHeight + drawLine(losLine, Offset(x1.toFloat(), y1.toFloat()), Offset(x2.toFloat(), y2.toFloat()), strokeWidth = 1.5f) + } + + fun buildEndpointLabel(name: String, groundMetersAsl: Double, antennaHeightMetersAgl: Double): String { + val hasGround = groundMetersAsl.isFinite() + val hasAntenna = antennaHeightMetersAgl.isFinite() + if (hasGround && hasAntenna) return String.format(Locale.US, "%s: %.0f m ASL + %.0f m AGL", name, groundMetersAsl, antennaHeightMetersAgl) + if (hasGround) return String.format(Locale.US, "%s: %.0f m ASL", name, groundMetersAsl) + if (hasAntenna) return String.format(Locale.US, "%s: +%.0f m AGL", name, antennaHeightMetersAgl) + return "$name: -" + } + + // Endpoint markers + if (profilePoints.size >= 2) { + val first = profilePoints.first() + val last = profilePoints.last() + val firstGround = terrainDisplayElevationMeters(first) + val lastGround = terrainDisplayElevationMeters(last) + val firstAntenna = if (first.lineOfSightHeightMeters().isFinite()) first.lineOfSightHeightMeters() else firstGround + homeAntennaHeightMeters + val lastAntenna = if (last.lineOfSightHeightMeters().isFinite()) last.lineOfSightHeightMeters() else lastGround + targetAntennaHeightMeters + + val x1 = plotX + val y1Ground = plotY + plotHeight - normalizeElevation(firstGround, minElevation, elevationRange) * plotHeight + val y1Antenna = plotY + plotHeight - normalizeElevation(firstAntenna, minElevation, elevationRange) * plotHeight + + val x2 = plotX + plotWidth + val y2Ground = plotY + plotHeight - normalizeElevation(lastGround, minElevation, elevationRange) * plotHeight + val y2Antenna = plotY + plotHeight - normalizeElevation(lastAntenna, minElevation, elevationRange) * plotHeight + + drawLine(endpointMarker, Offset(x1.toFloat(), y1Ground.toFloat()), Offset(x1.toFloat(), y1Antenna.toFloat()), strokeWidth = 1.2f) + drawCircle(endpointMarker, radius = 3f, center = Offset(x1.toFloat(), y1Antenna.toFloat())) + + drawLine(endpointMarker, Offset(x2.toFloat(), y2Ground.toFloat()), Offset(x2.toFloat(), y2Antenna.toFloat()), strokeWidth = 1.2f) + drawCircle(endpointMarker, radius = 3f, center = Offset(x2.toFloat(), y2Antenna.toFloat())) + + val homeLabel = buildEndpointLabel(strings.chartHome, first.elevationMeters(), homeAntennaHeightMeters) + val dxLabel = buildEndpointLabel("DX", last.elevationMeters(), targetAntennaHeightMeters) + + val headerLabelY = plotY - 20.0 // Adjusted for Compose text drawing top-left + + safeDrawText(textMeasurer, homeLabel, topLeft = Offset((plotX + 4.0).toFloat(), headerLabelY.toFloat()), style = textStyle.copy(color = textColor)) + + val dxLabelWidth = estimateTextWidth(dxLabel) + safeDrawText(textMeasurer, dxLabel, topLeft = Offset(max(plotX + plotWidth - dxLabelWidth - 4.0, plotX + plotWidth * 0.45).toFloat(), headerLabelY.toFloat()), style = textStyle.copy(color = textColor)) + } + + // Find Point By Sample Index + fun findPointBySampleIndex(sampleIndex: Int): PathProfilePoint? { + if (sampleIndex < 0) return null + return profilePoints.find { it.sampleIndex() == sampleIndex } + } + + // Radio Horizon Markers + if (totalDistanceKm.isFinite() && totalDistanceKm > 0.0) { + val homeHorizonKm = PathGeometryUtils.calculateRadioHorizonDistanceKm(homeAntennaHeightMeters, effectiveEarthRadiusFactor) + val targetHorizonKm = PathGeometryUtils.calculateRadioHorizonDistanceKm(targetAntennaHeightMeters, effectiveEarthRadiusFactor) + + fun drawVerticalHorizonMarker(distanceKm: Double, label: String) { + val x = plotX + normalizeDistance(distanceKm) * plotWidth + drawLine(horizonMarker, Offset(x.toFloat(), plotY.toFloat()), Offset(x.toFloat(), (plotY + plotHeight).toFloat()), strokeWidth = 1f, pathEffect = PathEffect.dashPathEffect(floatArrayOf(4f, 4f))) + val fullLabel = String.format(Locale.US, "%s %.1f km", label, distanceKm) + val labelWidth = estimateTextWidth(fullLabel) + var labelX = x + 5.0 + if (labelX + labelWidth > plotX + plotWidth) { + labelX = max(plotX, x - labelWidth - 5.0) + } + safeDrawText(textMeasurer, fullLabel, topLeft = Offset(labelX.toFloat(), (plotY + plotHeight - 18.0).toFloat()), style = textStyle.copy(color = textColor)) + } + + if (homeHorizonKm.isFinite() && homeHorizonKm > 0.0 && homeHorizonKm < totalDistanceKm) { + drawVerticalHorizonMarker(homeHorizonKm, strings.chartHomeRadioHorizon) + } + val targetMarkerDistanceKm = totalDistanceKm - targetHorizonKm + if (targetMarkerDistanceKm.isFinite() && targetMarkerDistanceKm > 0.0 && targetMarkerDistanceKm < totalDistanceKm) { + drawVerticalHorizonMarker(targetMarkerDistanceKm, strings.chartDxRadioHorizon) + } + } + + // Terrain Horizon Markers + if (horizonSummary != null && profilePoints.isNotEmpty()) { + fun drawTerrainHorizonMarker(sampleIndex: Int, label: String) { + val point = findPointBySampleIndex(sampleIndex) ?: return + val x = plotX + normalizeDistance(point.distanceKm()) * plotWidth + val y = plotY + plotHeight - normalizeElevation(terrainDisplayElevationMeters(point), minElevation, elevationRange) * plotHeight + + val path = Path() + path.moveTo(x.toFloat(), (y - 8.0).toFloat()) + path.lineTo((x - 5.0).toFloat(), (y + 2.0).toFloat()) + path.lineTo((x + 5.0).toFloat(), (y + 2.0).toFloat()) + path.close() + drawPath(path, color = terrainHorizonMarker, style = Fill) + + drawLine(terrainHorizonMarker, Offset(x.toFloat(), y.toFloat()), Offset(x.toFloat(), (plotY + plotHeight).toFloat()), strokeWidth = 1f, pathEffect = PathEffect.dashPathEffect(floatArrayOf(3f, 5f))) + + val fullLabel = String.format(Locale.US, "%s %.1f km", label, point.distanceKm()) + val labelWidth = estimateTextWidth(fullLabel) + var labelX = x + 7.0 + if (labelX + labelWidth > plotX + plotWidth) { + labelX = max(plotX, x - labelWidth - 7.0) + } + var labelY = min(plotY + plotHeight - 22.0, y + 18.0) + labelY = max(plotY + 20.0, labelY) + + safeDrawText(textMeasurer, fullLabel, topLeft = Offset(labelX.toFloat(), (labelY - 10.0).toFloat()), style = textStyle.copy(color = textColor)) + } + + if (horizonSummary.hasHomeTerrainHorizon()) { + drawTerrainHorizonMarker(horizonSummary.homeTerrainHorizonSampleIndex(), strings.chartHomeTerrainHorizon) + } + if (horizonSummary.hasTargetTerrainHorizon()) { + drawTerrainHorizonMarker(horizonSummary.targetTerrainHorizonSampleIndex(), strings.chartDxTerrainHorizon) + } + } + + // Obstruction Marker + if (obstructionSummary != null && obstructionSummary.hasDominantLosObstruction()) { + val point = findPointBySampleIndex(obstructionSummary.dominantObstructionSampleIndex()) + if (point != null) { + val x = plotX + normalizeDistance(point.distanceKm()) * plotWidth + val y = plotY + plotHeight - normalizeElevation(terrainDisplayElevationMeters(point), minElevation, elevationRange) * plotHeight + + val path = Path() + path.moveTo(x.toFloat(), (y - 7.0).toFloat()) + path.lineTo((x - 5.0).toFloat(), y.toFloat()) + path.lineTo(x.toFloat(), (y + 7.0).toFloat()) + path.lineTo((x + 5.0).toFloat(), y.toFloat()) + path.close() + drawPath(path, color = obstructionMarker, style = Fill) + + drawLine(obstructionMarker, Offset(x.toFloat(), y.toFloat()), Offset(x.toFloat(), (plotY + plotHeight).toFloat()), strokeWidth = 1f, pathEffect = PathEffect.dashPathEffect(floatArrayOf(2f, 4f))) + + val label = strings.chartDiffractionCandidate( + String.format(Locale.US, "%.1f", obstructionSummary.dominantObstructionPathDistanceKm()), + String.format(Locale.US, "%.1f", obstructionSummary.estimatedKnifeEdgeLossDb()), + ) + val labelWidth = estimateTextWidth(label) + var labelX = x + 8.0 + if (labelX + labelWidth > plotX + plotWidth) { + labelX = max(plotX, x - labelWidth - 8.0) + } + var labelY = min(plotY + plotHeight - 34.0, y + 30.0) + labelY = max(plotY + 34.0, labelY) + + safeDrawText(textMeasurer, label, topLeft = Offset(labelX.toFloat(), (labelY - 10.0).toFloat()), style = textStyle.copy(color = textColor)) + } + } + + // Critical Marker + fun findCriticalPoint(): PathProfilePoint? { + var worstFresnelPoint: PathProfilePoint? = null + var worstFresnelIntrusion = 0.0 + var worstLosPoint: PathProfilePoint? = null + var minimumLosClearance = Double.POSITIVE_INFINITY + + for (point in profilePoints) { + if (point.fresnelIntrusionMeters().isFinite() && point.fresnelIntrusionMeters() > worstFresnelIntrusion) { + worstFresnelIntrusion = point.fresnelIntrusionMeters() + worstFresnelPoint = point + } + if (point.lineOfSightClearanceMeters().isFinite() && point.lineOfSightClearanceMeters() < minimumLosClearance) { + minimumLosClearance = point.lineOfSightClearanceMeters() + worstLosPoint = point + } + } + if (worstFresnelPoint != null) return worstFresnelPoint + if (worstLosPoint != null && worstLosPoint.isLineOfSightBlocked) return worstLosPoint + return null + } + + val criticalPoint = findCriticalPoint() + if (criticalPoint != null) { + val x = plotX + normalizeDistance(criticalPoint.distanceKm()) * plotWidth + val y = plotY + plotHeight - normalizeElevation(terrainDisplayElevationMeters(criticalPoint), minElevation, elevationRange) * plotHeight + + drawCircle(criticalMarker, radius = 4f, center = Offset(x.toFloat(), y.toFloat())) + drawLine(criticalMarker, Offset(x.toFloat(), y.toFloat()), Offset(x.toFloat(), (plotY + plotHeight).toFloat()), strokeWidth = 1f) + + val label = if (criticalPoint.hasFresnelIntrusion()) { + strings.chartCriticalFresnel( + String.format(Locale.US, "%.1f", criticalPoint.fresnelIntrusionMeters()), + String.format(Locale.US, "%.1f", criticalPoint.distanceKm()), + ) + } else { + strings.chartCriticalLos( + String.format(Locale.US, "%.1f", criticalPoint.lineOfSightClearanceMeters()), + String.format(Locale.US, "%.1f", criticalPoint.distanceKm()), + ) + } + + val labelWidth = estimateTextWidth(label) + var labelX = x + 8.0 + if (labelX + labelWidth > plotX + plotWidth) { + labelX = max(plotX, x - labelWidth - 8.0) + } + var labelY = max(plotY + 22.0, y - 10.0) + if (labelY < plotY + 18.0) { + labelY = plotY + 18.0 + } + + safeDrawText(textMeasurer, label, topLeft = Offset(labelX.toFloat(), (labelY - 10.0).toFloat()), style = textStyle.copy(color = textColor)) + } + + // Draw axis labels + drawAxisLabels(minElevation, maxElevation) + + // Draw legend + var legX = plotX + val legY = headerTop + 12.0 + val textY = legY - 10.0 // adjust for compose text drawing top-left vs baseline + + safeDrawText(textMeasurer, strings.chartLegend, topLeft = Offset(legX.toFloat(), textY.toFloat()), style = textStyle.copy(color = textColor)) + legX += 48.0 + + fun drawHorizontalLegendLineItem(lineColor: Color, dashed: Boolean, lx: Double, ly: Double, text: String): Double { + val pe = if (dashed) PathEffect.dashPathEffect(floatArrayOf(6f, 4f)) else null + drawLine(lineColor, Offset(lx.toFloat(), (ly - 4.0).toFloat()), Offset((lx + 14.0).toFloat(), (ly - 4.0).toFloat()), strokeWidth = 1.6f, pathEffect = pe) + safeDrawText(textMeasurer, text, topLeft = Offset((lx + 18.0).toFloat(), (ly - 10.0).toFloat()), style = textStyle.copy(color = textColor)) + return lx + 18.0 + estimateTextWidth(text) + 18.0 + } + + fun drawHorizontalLegendTriangleItem(markerColor: Color, lx: Double, ly: Double, text: String): Double { + val path = Path() + path.moveTo((lx + 4.0).toFloat(), (ly - 10.0).toFloat()) + path.lineTo(lx.toFloat(), (ly - 2.0).toFloat()) + path.lineTo((lx + 8.0).toFloat(), (ly - 2.0).toFloat()) + path.close() + drawPath(path, color = markerColor, style = Fill) + safeDrawText(textMeasurer, text, topLeft = Offset((lx + 14.0).toFloat(), (ly - 10.0).toFloat()), style = textStyle.copy(color = textColor)) + return lx + 14.0 + estimateTextWidth(text) + 18.0 + } + + fun drawHorizontalLegendDiamondItem(markerColor: Color, lx: Double, ly: Double, text: String): Double { + val cx = lx + 4.0 + val cy = ly - 6.0 + val path = Path() + path.moveTo(cx.toFloat(), (cy - 4.0).toFloat()) + path.lineTo((cx - 4.0).toFloat(), cy.toFloat()) + path.lineTo(cx.toFloat(), (cy + 4.0).toFloat()) + path.lineTo((cx + 4.0).toFloat(), cy.toFloat()) + path.close() + drawPath(path, color = markerColor, style = Fill) + safeDrawText(textMeasurer, text, topLeft = Offset((lx + 14.0).toFloat(), (ly - 10.0).toFloat()), style = textStyle.copy(color = textColor)) + return lx + 14.0 + estimateTextWidth(text) + 18.0 + } + + fun drawHorizontalLegendDotItem(markerColor: Color, lx: Double, ly: Double, text: String): Double { + drawCircle(markerColor, radius = 4f, center = Offset((lx + 4.0).toFloat(), (ly - 4.0).toFloat())) + safeDrawText(textMeasurer, text, topLeft = Offset((lx + 14.0).toFloat(), (ly - 10.0).toFloat()), style = textStyle.copy(color = textColor)) + return lx + 14.0 + estimateTextWidth(text) + 18.0 + } + + legX = drawHorizontalLegendLineItem(terrainLine, false, legX, legY, strings.chartTerrain) + legX = drawHorizontalLegendLineItem(losLine, false, legX, legY, strings.chartLos) + legX = drawHorizontalLegendLineItem(fresnelLine, true, legX, legY, strings.chartFresnel) + legX = drawHorizontalLegendLineItem(horizonMarker, true, legX, legY, strings.chartRadioHorizonShort) + legX = drawHorizontalLegendTriangleItem(terrainHorizonMarker, legX, legY, strings.chartTerrainHorizonShort) + legX = drawHorizontalLegendDiamondItem(obstructionMarker, legX, legY, strings.chartDiffraction) + drawHorizontalLegendDotItem(criticalMarker, legX, legY, strings.chartCritical) + } +} + + +fun androidx.compose.ui.graphics.drawscope.DrawScope.safeDrawText( + textMeasurer: androidx.compose.ui.text.TextMeasurer, + text: String, + topLeft: androidx.compose.ui.geometry.Offset, + style: androidx.compose.ui.text.TextStyle +) { + if (topLeft.x.isNaN() || topLeft.y.isNaN() || topLeft.x.isInfinite() || topLeft.y.isInfinite()) return + this.drawText( + textMeasurer = textMeasurer, + text = text, + topLeft = topLeft, + style = style, + size = androidx.compose.ui.geometry.Size(10000f, 10000f) + ) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/map/StationMapWindow.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/map/StationMapWindow.kt new file mode 100644 index 00000000..98710e8b --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/map/StationMapWindow.kt @@ -0,0 +1,399 @@ +package kst4contest.view.compose.map + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.draw.alpha +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.unit.dp +import kst4contest.model.Band +import kst4contest.view.ApplicationRuntimeLauncher +import kst4contest.view.compose.PaletteStore +import kst4contest.view.compose.ComposeWindowHost +import kst4contest.view.compose.MainWindowState +import kst4contest.view.map.MapCallsignRawSnapshotBuilder +import kst4contest.view.map.PathAnalysisResult +import kst4contest.view.map.StationMapStatusText +import kst4contest.view.map.TileFetcher +import java.util.EnumSet + +@OptIn(androidx.compose.foundation.ExperimentalFoundationApi::class) +object StationMapWindow { + + private val host = ComposeWindowHost("Map") + var isDarkThemeState = androidx.compose.runtime.mutableStateOf(false) + + fun show( + mainWindowState: MainWindowState, + darkMode: Boolean, + baseFontSizeSp: Float, + /** + * The palette of the active profile, handed to the theme. Null draws the shipped + * palette. + */ + paletteStore: PaletteStore? = null, + /** + * The interface language of the active profile, handed to the window. Null draws the + * base language. + */ + languageStore: kst4contest.view.i18n.LanguageStore? = null, + widthDp: Float, + heightDp: Float, + onResized: (Float, Float) -> Unit, + ) { + isDarkThemeState.value = darkMode + host.show( + title = { kst4contest.view.i18n.CurrentStrings.get().mapTitle }, + darkMode = darkMode, + baseFontSizeSp = baseFontSizeSp, + paletteStore = paletteStore, + languageStore = languageStore, + widthDp = widthDp, + heightDp = heightDp, + onResized = onResized, + ) { _ -> + val strings = LocalStrings.current + + val window = this.window + androidx.compose.runtime.LaunchedEffect(window) { window?.minimumSize = java.awt.Dimension(900, 600) } + val tileFetcher = remember { TileFetcher() } + + /* + * Released when the window closes. The fetcher owns a thread pool, and a + * live pool thread is a GC root: without this, every open of this window + * leaves its whole tile cache reachable for the rest of the session. + */ + androidx.compose.runtime.DisposableEffect(tileFetcher) { + onDispose { tileFetcher.close() } + } + + /* + * The fetcher is plain Java state, so nothing about it recomposes on its + * own. Polled rather than wired through a callback: this drives one line of + * text, and a callback from a background fetch thread into Compose state is + * more machinery than the question deserves. + */ + var tilesUnavailable by remember { mutableStateOf(false) } + LaunchedEffect(tileFetcher) { + while (true) { + kotlinx.coroutines.delay(1_000) + tilesUnavailable = tileFetcher.isTileSourceUnavailable() + } + } + val prefs = mainWindowState.prefs + + var groupingEnabled by remember { mutableStateOf(prefs.isGUIstationMapClusteringEnabled) } + var pathAnalysisVisible by remember { mutableStateOf(prefs.isGUIstationMapPathAnalysisVisible) } + + val selectedMember = mainWindowState.selectedStation.selected + + val ownLocator6 by remember { androidx.compose.runtime.mutableStateOf(mainWindowState.prefs.stn_loginLocatorMainCat) } + val antennaAzimuthDeg = mainWindowState.antennaQtf.value + val antennaBeamWidthDeg = mainWindowState.prefs.stn_antennaBeamWidthDeg + val maxQrbKm = mainWindowState.prefs.stn_maxQRBDefault + + val markers by remember(mainWindowState.stations.rows, mainWindowState.stations.contentRevision, selectedMember, mainWindowState.activeBands) { + derivedStateOf { + val builder = MapCallsignRawSnapshotBuilder() + val activeBands = mainWindowState.activeBands + + val bandSet = EnumSet.noneOf(Band::class.java) + if (activeBands.isNotEmpty()) { + bandSet.addAll(activeBands) + } + + builder.buildSnapshots( + mainWindowState.stations.rows, + selectedMember, + bandSet + ) + } + } + + var pathAnalysisResult by remember { mutableStateOf(null) } + val mapState = remember { MapState() } + + LaunchedEffect(selectedMember) { + if (selectedMember == null) { + pathAnalysisResult = null + return@LaunchedEffect + } + + val chatController = ApplicationRuntimeLauncher.getCurrent()?.chatController + if (chatController != null) { + val selectedSnapshot = markers.find { it.callSignRaw() == selectedMember.callSignRaw } + + if (selectedSnapshot != null && selectedSnapshot.hasUsablePosition()) { + /* + * Pan to the station and leave the zoom alone. The Leaflet map + * did exactly this (focusCallsignRaw) and touched the zoom only + * when the station was hidden inside a bubble, and then only far + * enough to break the bubble open. An earlier Compose version + * recomputed a zoom from a bounding box on every selection and + * clamped it into 4..12, which threw an operator working at zoom + * 15 out to about 7 every time they picked the next station. + * AGENTS.md names zoom first among the things not to change as + * an incidental side effect. + */ + mapState.centerLon = selectedSnapshot.longitudeDeg() + mapState.centerLat = selectedSnapshot.latitudeDeg() + mapState.zoom = kst4contest.view.map.StationMapClusterer + .zoomToRevealStations(mapState.zoom.toDouble(), groupingEnabled) + .toFloat() + } + + pathAnalysisResult = PathAnalysisResult.loading( + prefs.stn_loginLocatorMainCat, + selectedSnapshot?.locator6() ?: "", + selectedSnapshot?.callSignRaw() ?: "" + ) + + val overrideBand: kst4contest.model.Band? = null + + chatController.reachabilityService.requestPathAnalysisForMap( + selectedMember, + selectedSnapshot, + overrideBand + ) { result -> + pathAnalysisResult = result + } + } + } + + androidx.compose.material3.Surface( + color = androidx.compose.material3.MaterialTheme.colorScheme.background, + contentColor = androidx.compose.material3.MaterialTheme.colorScheme.onBackground, + modifier = Modifier.fillMaxSize() + ) { + Column(Modifier.fillMaxSize()) { + /* + * The status line takes the room, so the buttons sit at the right edge + * the way the JavaFX header had them (HBox.setHgrow on the label). The + * controls are the shared ones: a raw Material button paints itself in + * the theme's primary colour, which in the evening sheet is a bright + * green, and the map window was the only one wearing it. + */ + Row( + modifier = Modifier.fillMaxWidth().padding(8.dp), + verticalAlignment = Alignment.CenterVertically, + horizontalArrangement = Arrangement.spacedBy(10.dp) + ) { + val statusText = StationMapStatusText.build( + markers.size, + mainWindowState.stationFilter.activeFilters.isNotEmpty() || + mainWindowState.stationFilter.searchText.isNotBlank(), + markers.firstOrNull { it.callSignRaw() == selectedMember?.callSignRaw }, + ) + + /* + * The tail of this line carries the bands and the frequency, and on a + * narrow window that is exactly what the ellipsis eats. The JavaFX + * header put the same text into a tooltip for that reason + * (statusTooltip, StationMapView.updateStatusLabel). + */ + androidx.compose.foundation.TooltipArea( + tooltip = { kst4contest.view.compose.TooltipCard(statusText) }, + modifier = Modifier.weight(1f), + ) { + Text( + text = statusText, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + ) + } + + if (selectedMember != null) { + kst4contest.view.compose.Form.button(strings.mapTriggerClusterSpot) { + ApplicationRuntimeLauncher.getCurrent()?.chatController + ?.dxClusterServer?.broadcastSingleDXClusterEntryToLoggers(selectedMember) + } + } + + kst4contest.view.compose.Form.button(strings.mapResetView) { + mainWindowState.stationSelector?.invoke(null) + ?: mainWindowState.selectedStation.select(null) + val home = runCatching { + kst4contest.locatorUtils.Location(ownLocator6) + }.getOrNull() + mapState.centerLon = home?.longitude?.toDegrees() ?: 10.0 + mapState.centerLat = home?.latitude?.toDegrees() ?: 51.0 + /* The zoom is deliberately left alone; see AGENTS.md, UI behaviour. */ + } + + Row(verticalAlignment = Alignment.CenterVertically) { + kst4contest.view.compose.CompactCheckbox(groupingEnabled) { + groupingEnabled = it + prefs.isGUIstationMapClusteringEnabled = it + } + Text(strings.mapGroupNearby, modifier = Modifier.padding(start = 4.dp)) + } + + if (!pathAnalysisVisible) { + Text( + text = strings.mapPathAnalysisHidden, + fontStyle = FontStyle.Italic, + modifier = Modifier.alpha(0.85f) + ) + } + + kst4contest.view.compose.Form.button( + if (pathAnalysisVisible) strings.mapHidePathAnalysis else strings.mapShowPathAnalysis + ) { + pathAnalysisVisible = !pathAnalysisVisible + prefs.isGUIstationMapPathAnalysisVisible = pathAnalysisVisible + } + } + + // Main Layout + Column(Modifier.weight(1f).fillMaxWidth()) { + val mapSplitterState = androidx.compose.runtime.remember { + kst4contest.view.compose.SplitterState( + paneCount = 2, + stored = doubleArrayOf(0.65), + save = { } + ) + } + + val leftPane: @Composable () -> Unit = { + Column(Modifier.fillMaxHeight()) { + val isDarkTheme = isDarkThemeState.value + androidx.compose.foundation.layout.Box(Modifier.weight(1f).fillMaxWidth()) { + ComposeStationMap( + markers = markers, + tileFetcher = tileFetcher, + mapState = mapState, + groupingEnabled = groupingEnabled, + selectedMarkerCallsign = selectedMember?.callSignRaw, + ownLocator6 = ownLocator6, + antennaAzimuthDeg = antennaAzimuthDeg ?: 0.0, + antennaBeamWidthDeg = antennaBeamWidthDeg, + maxQrbKm = maxQrbKm, + darkMode = isDarkTheme, + onMarkerClicked = { snapshot -> + val chatController = ApplicationRuntimeLauncher.getCurrent()?.chatController + val variants = chatController?.lst_chatMemberList?.snapshot() + ?.filter { it.callSignRaw == snapshot.callSignRaw() } + .orEmpty() + /* + * A marker stands for a raw callsign, not a category. Keep the + * category already selected when it is one of the variants. + */ + val member = variants.firstOrNull { it === mainWindowState.selectedStation.selected } + ?: variants.firstOrNull() + if (member != null) { + val selector = mainWindowState.stationSelector + if (selector != null) { + selector(member) + } else { + mainWindowState.selectedStation.select(member) + } + // Mirror old JavaFX handleMapCallsignSelection logic: prefill /cq + mainWindowState.chatInput.prepareCq(member.callSign ?: "", forceOverwrite = true) + } + }, + modifier = Modifier.fillMaxSize() + ) + + MapOverlayControls( + darkMode = isDarkTheme, + tilesUnavailable = tilesUnavailable, + onZoomIn = { mapState.zoom = (mapState.zoom + 1f).coerceAtMost(MAX_MAP_ZOOM) }, + onZoomOut = { mapState.zoom = (mapState.zoom - 1f).coerceAtLeast(MIN_MAP_ZOOM) }, + ) + } + + if (pathAnalysisVisible) { + val points = pathAnalysisResult?.profilePoints() ?: emptyList() + val isDarkTheme = isDarkThemeState.value + PathProfileChart( + profilePoints = points, + totalDistanceKm = pathAnalysisResult?.distanceKm() ?: Double.NaN, + darkMode = isDarkTheme, + homeAntennaHeightMeters = pathAnalysisResult?.homeAntennaHeightMeters() ?: Double.NaN, + targetAntennaHeightMeters = pathAnalysisResult?.targetAntennaHeightMeters() ?: Double.NaN, + analysisFrequencyMHz = pathAnalysisResult?.analysisFrequencyMHz() ?: Double.NaN, + effectiveEarthRadiusFactor = pathAnalysisResult?.effectiveEarthRadiusFactor() ?: kst4contest.view.map.PathGeometryUtils.DEFAULT_EFFECTIVE_EARTH_RADIUS_FACTOR, + horizonSummary = pathAnalysisResult?.horizonSummary() ?: kst4contest.view.map.PathHorizonSummary.empty(), + obstructionSummary = pathAnalysisResult?.obstructionSummary() ?: kst4contest.view.map.PathObstructionSummary.empty(), + modifier = Modifier.fillMaxWidth().height(210.dp) + ) + } + } + } + + val rightPane: @Composable () -> Unit = { + val scrollState = rememberScrollState() + androidx.compose.foundation.layout.Box(Modifier.fillMaxHeight()) { + PathAnalysisDetails( + result = pathAnalysisResult, + darkMode = isDarkThemeState.value, + modifier = Modifier.fillMaxHeight() + .padding(horizontal = 4.dp) + .padding(end = 12.dp) + .verticalScroll(scrollState), + ) + androidx.compose.foundation.VerticalScrollbar( + modifier = Modifier.align(androidx.compose.ui.Alignment.CenterEnd).fillMaxHeight(), + adapter = androidx.compose.foundation.rememberScrollbarAdapter(scrollState) + ) + } + } + + if (pathAnalysisVisible) { + kst4contest.view.compose.SplitterPane( + state = mapSplitterState, + orientation = kst4contest.view.compose.SplitterOrientation.HORIZONTAL, + panes = listOf(leftPane, rightPane), + modifier = Modifier.fillMaxSize() + ) + } else { + Box(Modifier.fillMaxSize()) { + leftPane() + } + } + } // main layout column + } // window column + } // Surface + } // host.show content + } + + @JvmStatic + fun applyDarkMode(darkMode: Boolean) { + isDarkThemeState.value = darkMode + host.applyDarkMode(darkMode) + } + + fun hide() { + host.close() + } + + fun isShowing(): Boolean = host.isOpen + + fun toggle( + mainWindowState: MainWindowState, + paletteStore: PaletteStore? = null, + languageStore: kst4contest.view.i18n.LanguageStore? = null, + ) { + if (isShowing()) { + hide() + } else { + show( + mainWindowState = mainWindowState, + darkMode = mainWindowState.prefs.isGUI_darkModeActive, + baseFontSizeSp = 12f, + paletteStore = paletteStore, + languageStore = languageStore, + widthDp = 1000f, + heightDp = 700f, + onResized = { w, h -> } + ) + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/map/TileBitmapCache.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/map/TileBitmapCache.kt new file mode 100644 index 00000000..8732005a --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/map/TileBitmapCache.kt @@ -0,0 +1,54 @@ +package kst4contest.view.compose.map + +import androidx.compose.ui.graphics.ImageBitmap + +/** + * The decoded tiles the map draws from, bounded. + * + * A decoded 256x256 tile costs about 262 KB against roughly 20 KB for the PNG it was + * decoded from, so this cache is the expensive one and the one that has to have a limit. + * It had none: an evening of panning at zoom 12 to 15 retained hundreds of megabytes of + * bitmaps of squares nobody would look at again. + * + * Least-recently-drawn goes first, because the tiles worth keeping are the ones around + * where the operator is looking, and reading a tile to draw it is exactly the signal for + * that. + * + * Written to from a tile-fetch thread and read from the composition thread, so every + * access is synchronised. A LinkedHashMap in access order is the eviction policy; it is + * not thread-safe on its own, and access order means a plain read mutates it. + */ +internal class TileBitmapCache(private val maxEntries: Int = DEFAULT_MAX_ENTRIES) { + + private val entries = object : LinkedHashMap(16, 0.75f, true) { + override fun removeEldestEntry(eldest: MutableMap.MutableEntry): Boolean = + size > maxEntries + } + + val size: Int get() = synchronized(entries) { entries.size } + + operator fun get(key: String): ImageBitmap? = synchronized(entries) { entries[key] } + + fun put(key: String, bitmap: ImageBitmap) { + synchronized(entries) { + if (maxEntries <= 0) { + return + } + entries[key] = bitmap + } + } + + fun remove(key: String) { + synchronized(entries) { entries.remove(key) } + } + + fun contains(key: String): Boolean = synchronized(entries) { entries.containsKey(key) } + + private companion object { + /** + * Enough for several screens' worth at any zoom, so panning back and forth over + * the same area never refetches, and about 130 MB of bitmaps at worst. + */ + const val DEFAULT_MAX_ENTRIES = 512 + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/AirscoutTab.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/AirscoutTab.kt new file mode 100644 index 00000000..47a6a159 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/AirscoutTab.kt @@ -0,0 +1,92 @@ +package kst4contest.view.compose.tabs + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import kst4contest.view.compose.Form + +/** + * The Airscout tab: the UDP link to AirScout and how the queried frequency is chosen. + * + * Labels, defaults and the closing note are the JavaFX ones, including that the server + * identifier, the client identifier and the frequency mode take effect at once while a + * changed UDP port needs a reconnect. + * + * The identifier, port and band fields keep what the operator typed and mark it as an + * error until it is valid; see AirscoutTabState for why an invalid value must not be + * written rather than merely corrected. + */ +@Composable +fun AirscoutTab(state: AirscoutTabState) { + /* See LogSynchTab: the facade holds no snapshot state, so writes need a revision. */ + var revision by remember { mutableStateOf(0) } + val strings = LocalStrings.current + + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + @Suppress("UNUSED_EXPRESSION") revision + + Form.section(strings.airscoutUdpSection) { + Form.check( + strings.airscoutEnabled, + state.airScout_asUDPListenerEnabled, + ) { state.airScout_asUDPListenerEnabled = it; revision++ } + + GuardedTextField( + label = strings.airscoutServerIdentifier, + value = state.airScout_asServerNameString, + accepts = { AirscoutTabState.isValidIdentifier(it) }, + onAccepted = { state.airScout_asServerNameString = it; revision++ }, + ) + + GuardedTextField( + label = strings.airscoutClientIdentifier, + value = state.airScout_asClientNameString, + accepts = { AirscoutTabState.isValidIdentifier(it) }, + onAccepted = { state.airScout_asClientNameString = it; revision++ }, + ) + + GuardedTextField( + label = strings.airscoutUdpPort, + value = state.airScout_asCommunicationPort.toString(), + accepts = { typed -> + typed.trim().toIntOrNull()?.let { AirscoutTabState.isValidPort(it) } == true + }, + onAccepted = { state.airScout_asCommunicationPort = it.trim().toInt(); revision++ }, + ) + } + + Form.section(strings.airscoutFrequencySection) { + Form.check( + strings.airscoutAutomaticFrequency, + state.airScout_autoBandSelectionEnabled, + ) { state.airScout_autoBandSelectionEnabled = it; revision++ } + + GuardedTextField( + label = strings.airscoutForcedBand, + value = state.airScout_asBandString, + enabled = state.bandValueEditable, + accepts = { AirscoutTabState.parseBandValue(it) != null }, + onAccepted = { state.airScout_asBandString = it; revision++ }, + ) + + Text( + strings.airscoutAutomaticHint + ) + } + + Text( + strings.airscoutApplyHint + ) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/AirscoutTabState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/AirscoutTabState.kt new file mode 100644 index 00000000..36304efe --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/AirscoutTabState.kt @@ -0,0 +1,111 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatPreferences + +/** + * The Airscout tab as a typed facade over ChatPreferences. + * + * Every property writes through immediately and there is deliberately no apply(), the + * way the JavaFX controls behaved. + * + * Three properties are guarded before the write, and the guard is not decoration. The + * ChatPreferences setters do not keep the previous value on bad input, they substitute + * the factory default: an empty identifier becomes "AS"/"KST", a port outside 1..65535 + * becomes 9872, a band value that is not a positive number becomes "1440000". The + * JavaFX window never let that happen — it validated on focus loss and put the stored + * value back into the field. Writing through on every keystroke without the same guard + * would silently reset an operator's configuration while he is typing. + * + * The accepted ranges are the JavaFX ones, unchanged: AirScout ports and the band + * value are protocol values and neither the defaults nor the bounds are touched. + */ +class AirscoutTabState(private val prefs: ChatPreferences) { + + var airScout_asUDPListenerEnabled: Boolean + get() = prefs.isAirScout_asUDPListenerEnabled() + set(value) { prefs.setAirScout_asUDPListenerEnabled(value) } + + /** Logical identifier of the target AirScout server; invalid input is ignored. */ + var airScout_asServerNameString: String + get() = prefs.getAirScout_asServerNameString() + set(value) { + if (isValidIdentifier(value)) { + prefs.setAirScout_asServerNameString(value.trim()) + } + } + + /** Identifier of this KST4Contest instance; invalid input is ignored. */ + var airScout_asClientNameString: String + get() = prefs.getAirScout_asClientNameString() + set(value) { + if (isValidIdentifier(value)) { + prefs.setAirScout_asClientNameString(value.trim()) + } + } + + /** + * AirScout UDP port, default 9872. Must match the AirScout network settings, and a + * change takes effect after a reconnect — the JavaFX tab said so and nothing about + * that changes here. + */ + var airScout_asCommunicationPort: Int + get() = prefs.getAirScout_asCommunicationPort() + set(value) { + if (isValidPort(value)) { + prefs.setAirScout_asCommunicationPort(value) + } + } + + /** + * Pick the AirScout frequency per station instead of forcing one value. Uses the + * station's current QRG first, then station-name and chat-category evidence. + */ + var airScout_autoBandSelectionEnabled: Boolean + get() = prefs.isAirScout_autoBandSelectionEnabled() + set(value) { prefs.setAirScout_autoBandSelectionEnabled(value) } + + /** + * The forced AirScout band value, a protocol number such as 1440000 for 144 MHz. + * Stored as the protocol spells it, which is what Long.toString of the parsed + * value produced in the JavaFX field. + */ + var airScout_asBandString: String + get() = prefs.getAirScout_asBandString() + set(value) { + parseBandValue(value)?.let { prefs.setAirScout_asBandString(it) } + } + + /** + * False while the frequency is selected per station: the JavaFX band field was + * disabled then, because a forced value is the fallback for exactly that case. + */ + val bandValueEditable: Boolean + get() = !airScout_autoBandSelectionEnabled + + companion object { + + /** + * AirScout encloses the identifiers in quotation marks, so an empty identifier, + * a quotation mark or a line break would produce an invalid protocol message. + */ + @JvmStatic + fun isValidIdentifier(candidate: String?): Boolean { + val normalized = candidate?.trim() ?: return false + return normalized.isNotEmpty() && + !normalized.contains("\"") && + !normalized.contains("\r") && + !normalized.contains("\n") + } + + /** The range the JavaFX field accepted. Not narrowed. */ + @JvmStatic + fun isValidPort(candidate: Int): Boolean = candidate in 1..65535 + + /** The normalized band value, or null when it is not a positive number. */ + @JvmStatic + fun parseBandValue(candidate: String?): String? { + val parsed = candidate?.trim()?.toLongOrNull() ?: return null + return if (parsed > 0) parsed.toString() else null + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/BeaconTab.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/BeaconTab.kt new file mode 100644 index 00000000..c9c549ac --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/BeaconTab.kt @@ -0,0 +1,58 @@ +package kst4contest.view.compose.tabs + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import kst4contest.view.compose.Form + +/** + * The beacon tab: one CQ template per chat category and the interval they share. + * + * The interval is one field for both categories. The second category keeps its own + * stored value for the sake of the configuration file, but the operator never saw + * two intervals and setting them apart was never possible. + */ +@Composable +fun BeaconTab(state: BeaconTabState, onRefused: (String) -> Unit) { + val strings = LocalStrings.current + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + Form.section(strings.beaconSectionFor(state.mainCategoryName)) { + Form.check(strings.beaconEnabled, state.bcn_beaconsEnabledMainCat) { + state.bcn_beaconsEnabledMainCat = it + } + Form.committed( + label = strings.beaconMessage, + stored = state.beaconTextMainCat, + commit = state::commitBeaconTextMainCat, + onRefused = onRefused, + ) + } + + Form.section(strings.beaconSectionFor(state.secondCategoryName)) { + Form.check(strings.beaconEnabled, state.bcn_beaconsEnabledSecondCat) { + state.bcn_beaconsEnabledSecondCat = it + } + Form.committed( + label = strings.beaconMessage, + stored = state.beaconTextSecondCat, + commit = state::commitBeaconTextSecondCat, + onRefused = onRefused, + ) + } + + Form.section(strings.beaconIntervalSection) { + Form.committed( + label = strings.beaconIntervalMinutes, + stored = state.beaconIntervalMinutes.toString(), + commit = state::commitBeaconInterval, + onRefused = onRefused, + ) + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/BeaconTabState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/BeaconTabState.kt new file mode 100644 index 00000000..905d8ccb --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/BeaconTabState.kt @@ -0,0 +1,104 @@ +package kst4contest.view.compose.tabs + +import kst4contest.controller.ChatController +import kst4contest.model.ChatPreferences + +/** + * State of the beacon tab: the two CQ templates and the one interval they share. + * + * The two commit methods are the ports of `applyBeaconTextSetting` and + * `applySharedBeaconInterval`. Both returned nothing and opened an alert; here they + * return the refusal text instead, so the tab decides how to show it and a test can + * read it. + * + * @param validateBeaconTemplate throws IllegalArgumentException with the reason, + * the contract of `ChatController.validateBeaconTemplate`. + * @param restartBeaconTimer called only after the interval actually changed; the + * JavaFX code restarted the shared timer there and nowhere else. + */ +class BeaconTabState( + private val prefs: ChatPreferences, + private val validateBeaconTemplate: (String) -> Unit, + private val restartBeaconTimer: () -> Unit, + val mainCategoryName: String, + val secondCategoryName: String, +) { + + var bcn_beaconsEnabledMainCat: Boolean + get() = prefs.isBcn_beaconsEnabledMainCat() + set(value) { prefs.setBcn_beaconsEnabledMainCat(value) } + + var bcn_beaconsEnabledSecondCat: Boolean + get() = prefs.isBcn_beaconsEnabledSecondCat() + set(value) { prefs.setBcn_beaconsEnabledSecondCat(value) } + + val beaconTextMainCat: String + get() = prefs.getBcn_beaconTextMainCat() + + val beaconTextSecondCat: String + get() = prefs.getBcn_beaconTextSecondCat() + + /** + * The interval both categories share, never below the minimum. + * + * The clamp is not cosmetic: a stored zero would otherwise be displayed as a + * valid setting while `ChatController` sends at the minimum anyway + * (ChatController:3425). The JavaFX field applied the same `Math.max` when it + * restored the value after a rejected entry. + */ + val beaconIntervalMinutes: Int + get() = maxOf( + ChatController.MIN_BEACON_INTERVAL_MINUTES, + prefs.getBcn_beaconIntervalInMinutesMainCat(), + ) + + /** @return null when stored, otherwise the reason it was refused. */ + fun commitBeaconTextMainCat(template: String): String? = + commitBeaconText(template) { prefs.setBcn_beaconTextMainCat(it) } + + /** @return null when stored, otherwise the reason it was refused. */ + fun commitBeaconTextSecondCat(template: String): String? = + commitBeaconText(template) { prefs.setBcn_beaconTextSecondCat(it) } + + private fun commitBeaconText(template: String, store: (String) -> Unit): String? { + try { + validateBeaconTemplate(template) + } catch (refusal: IllegalArgumentException) { + /* + * The stored template stands. MYCALL and MYQRG are resolved by the timer, + * so a refused template that replaced a working one would silently stop + * the beacon instead of reporting anything. + */ + return "The beacon message is invalid: " + refusal.message + } + + store(template) + return null + } + + /** + * Applies the shared interval to both categories and restarts the timer. + * + * @return null when applied, otherwise the reason it was refused. + */ + fun commitBeaconInterval(entered: String): String? { + val minutes = entered.trim().toIntOrNull() + + if (minutes == null || minutes < ChatController.MIN_BEACON_INTERVAL_MINUTES) { + return "Enter a whole beacon interval of at least " + + ChatController.MIN_BEACON_INTERVAL_MINUTES + " minute." + } + + prefs.setBcn_beaconIntervalInMinutesMainCat(minutes) + + /* + * The second-category value is legacy XML which nothing reads any more, but + * it is written to keep the two in step, exactly as applySharedBeaconInterval + * did. + */ + prefs.setBcn_beaconIntervalInMinutesSecondCat(minutes) + + restartBeaconTimer() + return null + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ColourShortcuts.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ColourShortcuts.kt new file mode 100644 index 00000000..65d60cb5 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ColourShortcuts.kt @@ -0,0 +1,83 @@ +package kst4contest.view.compose.tabs + +import androidx.compose.ui.input.key.Key +import androidx.compose.ui.input.key.KeyEvent +import androidx.compose.ui.input.key.KeyEventType +import androidx.compose.ui.input.key.isCtrlPressed +import androidx.compose.ui.input.key.key +import androidx.compose.ui.input.key.type + +/** One of the three ways back, in the order the tab shows them. */ +enum class ColourAction { BACK_TO_PREVIOUS, DISCARD_CHANGES, RESET_TO_SHIPPED } + +/** + * The keyboard path to the three ways back. + * + * The spec asks for one for all three, and says why: there is no "not yet applied" state, so + * the ways back are the only way back, and they have to be reachable without colour + * perception. Default focus traversal technically reaches the buttons, but tabbing blindly + * past six hex fields to find them is not a rescue. + * + * Control is required on all three. Six text fields live in this tab and `#DDEEFF` contains a + * D: a bare letter would swallow the typing it exists to protect. + * + * Split the same way [kst4contest.view.compose.WindowShortcuts] is — a pure decision plus a + * thin event adapter — because a desktop `KeyEvent` wraps a native AWT event, and a test that + * built one would be testing Compose. + */ +object ColourShortcuts { + + /** + * The action a key combination means, or null when it means nothing here. + * + * @param ctrlPressed whether control was held + * @param key the key pressed + * @return the action, or null to let the key travel on to the fields + */ + fun actionFor(ctrlPressed: Boolean, key: Key): ColourAction? { + + if (!ctrlPressed) { + return null + } + + return when (key) { + Key.Z -> ColourAction.BACK_TO_PREVIOUS + Key.D -> ColourAction.DISCARD_CHANGES + Key.R -> ColourAction.RESET_TO_SHIPPED + else -> null + } + } + + /** + * How the shortcut is written where the operator can read it. + * + * Shown in the tab beside each button: a shortcut nobody is told about is not a second + * safety net, and this one exists for an operator who cannot read the buttons. + * + * @param action the way back + * @return the key combination as text + */ + fun labelFor(action: ColourAction): String = when (action) { + ColourAction.BACK_TO_PREVIOUS -> "Ctrl+Z" + ColourAction.DISCARD_CHANGES -> "Ctrl+D" + ColourAction.RESET_TO_SHIPPED -> "Ctrl+R" + } + + /** + * Handles one key event for the colours tab. + * + * @param event the key event + * @param perform runs the action the keys named + * @return true when the event was consumed and must travel no further + */ + fun handle(event: KeyEvent, perform: (ColourAction) -> Unit): Boolean { + + if (event.type != KeyEventType.KeyDown) { + return false + } + + val action = actionFor(event.isCtrlPressed, event.key) ?: return false + perform(action) + return true + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ColoursTab.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ColoursTab.kt new file mode 100644 index 00000000..1b893d11 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ColoursTab.kt @@ -0,0 +1,266 @@ +package kst4contest.view.compose.tabs + +import kst4contest.view.i18n.LocalStrings +import kst4contest.view.i18n.Strings +import androidx.compose.foundation.BorderStroke +import androidx.compose.ui.input.key.onPreviewKeyEvent +import androidx.compose.ui.focus.focusRequester +import androidx.compose.ui.focus.FocusRequester +import androidx.compose.runtime.remember +import androidx.compose.foundation.focusable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.material3.Button +import androidx.compose.material3.ButtonDefaults +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import kst4contest.view.compose.ContrastPair +import kst4contest.view.compose.Density +import kst4contest.view.compose.Form +import kst4contest.view.compose.JavaFxPalette +import kst4contest.view.compose.JavaFxStylesheet +import kst4contest.view.compose.PaletteSource + +/** + * The colours of the lifeline, taken from one palette and nothing else. + * + * A value type rather than three expressions inside the composable, so the one property that + * matters — that these come from the shipped sheet — is testable without rendering. + */ +data class LifelineColours(val container: Color, val content: Color, val border: Color) + +/** + * The lifeline's colours from a palette. + * + * @param palette must be the shipped palette; passing the resolved one is the fault this + * whole arrangement exists to make impossible + * @return container, content and border + */ +fun lifelineColours(palette: JavaFxPalette): LifelineColours = LifelineColours( + container = palette.base, + content = palette.labelTextFill, + /* A step away from the container, so it reads as a control and not as a patch of colour. */ + border = JavaFxStylesheet.derive(palette.base, -35.0), +) + +/** + * The colours tab: six roles, where each of them comes from, and three ways back. + * + * @param state the tab's own state over the palette store + * @param reportRefusal shows a refused colour, the same channel the notification, shortcut + * and beacon tabs use for theirs + * @param reportOutcome shows something that went right; a success told through the refusal + * channel arrives looking like a failure + */ +@Composable +fun ColoursTab( + state: ColoursTabState, + reportRefusal: (String) -> Unit, + reportOutcome: (String) -> Unit, +) { + + /* + * The palette in force when the tab is opened, which is what "back to how it was" goes + * to. Remembered on first composition because there is no "not yet applied" state to + * go back to -- a change is live the moment it is typed. + */ + val focus = remember { FocusRequester() } + + val strings = LocalStrings.current + + LaunchedEffect(Unit) { + state.rememberCurrentState() + /* + * Focus the tab itself, so the shortcuts work the moment it opens rather than only + * after the operator has clicked something. The one case this is for is the operator + * who cannot see what to click. + */ + runCatching { focus.requestFocus() } + } + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + /* + * onPreviewKeyEvent, so the three ways back are reachable while the focus sits in one + * of the six hex fields -- which is exactly where it will be when an operator has just + * made the client unreadable. + */ + modifier = Modifier + .focusRequester(focus) + .focusable() + .onPreviewKeyEvent { event -> + ColourShortcuts.handle(event) { action -> + when (action) { + ColourAction.BACK_TO_PREVIOUS -> state.restoreRemembered() + ColourAction.DISCARD_CHANGES -> state.discardChanges() + ColourAction.RESET_TO_SHIPPED -> state.resetToShipped() + } + } + }, + ) { + + Form.section(strings.coloursSection) { + state.roles().forEach { row -> + /* + * The provenance sits in the label, beside the field it explains, rather than + * in a column of its own: it answers "why is this colour this?", which only + * means anything next to the colour. + */ + Form.committed( + label = strings.coloursRoleWithSource(row.label(strings), provenanceOf(row.source, strings)), + stored = row.hex, + commit = { typed -> state.set(row.role, typed) }, + onRefused = reportRefusal, + ) + } + } + + val warnings = state.warnings() + if (warnings.isNotEmpty()) { + Form.section(strings.coloursReadabilitySection) { + warnings.forEach { warning -> + Text( + /* + * Both numbers, because the message is comparative: the guard reports + * that a pair got worse than it shipped, not that it fails a standard. + */ + text = strings.coloursWarning( + nameOf(warning.what, strings), + "%.1f".format(warning.ratio), + "%.1f".format(warning.shippedRatio), + ), + style = MaterialTheme.typography.bodySmall, + ) + } + Text( + strings.coloursWarningKept, + style = MaterialTheme.typography.bodySmall, + ) + } + } + + Form.section(strings.coloursKeepingSection) { + /* + * The tab with the most visible immediate effect is also the one where "it looked + * right, so it must be stored" is the easiest wrong conclusion to draw. Every + * other settings tab has the same contract; none of them changes four windows + * under the operator's hands while they decide. + */ + Text( + strings.coloursKeepingHint, + style = MaterialTheme.typography.bodySmall, + ) + } + + Form.section(strings.coloursWaysBackSection) { + Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { + Form.button( + strings.coloursBackToPrevious(ColourShortcuts.labelFor(ColourAction.BACK_TO_PREVIOUS)) + ) { state.restoreRemembered() } + Form.button( + strings.coloursDiscardChanges(ColourShortcuts.labelFor(ColourAction.DISCARD_CHANGES)) + ) { state.discardChanges() } + } + + /* + * Always drawn in the shipped colours, and deliberately out of place under a + * customised palette: an operator who sets text and surface to the same black + * cannot see any other button, including the ones that would undo it. Not fitting + * in is what makes it findable. + */ + ResetToShippedButton(state.shipped()) { state.resetToShipped() } + } + + Form.section(strings.coloursFileSection) { + Text( + if (state.stylesheetExists()) { + strings.coloursFileReads(state.stylesheetPath()) + } else { + strings.coloursFileAbsent(state.stylesheetPath()) + }, + style = MaterialTheme.typography.bodySmall, + ) + Form.button(strings.coloursExportButton) { + /* + * An existing file is never replaced -- it is the operator's own work, and a + * misclick here would be the one loss this tab could cause that cannot be + * undone from inside the application. + */ + reportExport(state.exportStylesheet(), strings, reportOutcome, reportRefusal) + } + } + } +} + +/** Says what the export did, through the channel that matches the outcome. */ +private fun reportExport( + outcome: StylesheetExportOutcome, + strings: Strings, + reportOutcome: (String) -> Unit, + reportRefusal: (String) -> Unit, +) = when (outcome) { + is StylesheetExportOutcome.Written -> reportOutcome( + strings.coloursExportWritten(outcome.path) + ) + + /* Not a failure: the file is the operator's own, and leaving it alone is the point. */ + is StylesheetExportOutcome.AlreadyThere -> reportOutcome( + strings.coloursExportAlreadyThere(outcome.path) + ) + + is StylesheetExportOutcome.Failed -> reportRefusal( + strings.coloursExportFailed(outcome.reason) + ) +} + +/** + * The rescue control. + * + * Takes the shipped palette as a required parameter and reads no composition local, so there + * is no path by which it could be drawn in the operator's own colours. + */ +@Composable +private fun ResetToShippedButton(shipped: JavaFxPalette, onClick: () -> Unit) { + val strings = LocalStrings.current + val colours = lifelineColours(shipped) + + Button( + onClick = onClick, + shape = Density.BUTTON_SHAPE, + contentPadding = Density.BUTTON_CONTENT_PADDING, + border = BorderStroke(Density.SELECTION_BORDER, colours.border), + colors = ButtonDefaults.buttonColors( + containerColor = colours.container, + contentColor = colours.content, + ), + modifier = Modifier.padding(top = 6.dp), + ) { + Text( + strings.coloursResetToShipped(ColourShortcuts.labelFor(ColourAction.RESET_TO_SHIPPED)), + style = MaterialTheme.typography.bodyMedium, + ) + } +} + +/** The pair a warning is about, in words. */ +private fun nameOf(pair: ContrastPair, strings: Strings): String = when (pair) { + ContrastPair.TEXT_ON_WINDOW_SURFACE -> strings.contrastTextOnWindowSurface + ContrastPair.TEXT_INSIDE_FIELD -> strings.contrastTextInsideField + ContrastPair.ACCENT_ON_WINDOW_SURFACE -> strings.contrastAccentOnWindowSurface + ContrastPair.TEXT_ON_MENU_STRIP -> strings.contrastTextOnMenuStrip +} + +/** Why a role is the colour it is — the spec's mandatory answer to "why is this colour this?" */ +private fun provenanceOf(source: PaletteSource, strings: Strings): String = when (source) { + PaletteSource.SHIPPED -> strings.coloursSourceShipped + PaletteSource.FILE -> strings.coloursSourceFile + PaletteSource.CHANGED -> strings.coloursSourceChanged +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ColoursTabState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ColoursTabState.kt new file mode 100644 index 00000000..f13d0e7f --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ColoursTabState.kt @@ -0,0 +1,171 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.PaletteRole +import kst4contest.view.compose.ContrastWarning +import kst4contest.view.compose.OperatorProfilePaletteFiles +import kst4contest.view.compose.JavaFxPalette +import kst4contest.view.compose.PaletteSource +import kst4contest.view.compose.PaletteStore +import kst4contest.view.compose.contrastWarnings +import kst4contest.view.compose.hexOf +import kst4contest.view.i18n.CurrentStrings +import kst4contest.view.i18n.Strings + +/** + * One row of the colours tab: a role, what it is set to, and where that came from. + * + * @param label the role's name as the operator reads it + * @param hex the colour in force, in the one form the field accepts + * @param source why it is that colour — the mitigation the spec calls mandatory + */ +data class RoleRow( + val role: PaletteRole, + val label: (Strings) -> String, + val hex: String, + val source: PaletteSource, +) + +/** + * The colours tab as a typed facade over the palette store. + * + * Writes through immediately and has no apply(), like every settings tab: the JavaFX controls + * wrote as they changed and "Save settings" only persisted. + * + * @param store the active profile's palette + * @param darkModeNow which design the operator is looking at; the tab always edits that one + * @param paletteFiles where this profile's own stylesheets live, for the hand-editing route + */ +class ColoursTabState( + private val store: PaletteStore, + private val darkModeNow: () -> Boolean, + private val paletteFiles: OperatorProfilePaletteFiles, +) { + + /** + * The six rows, in a fixed order, for the design in force. + * + * @return one row per role, always all six + */ + fun roles(): List { + val resolved = store.resolved(darkModeNow()) + + return PaletteRole.values().map { role -> + val it = resolved.roles.getValue(role) + RoleRow(role = role, label = LABELS.getValue(role), hex = hexOf(it.colour), source = it.source) + } + } + + /** + * Sets one role of the design in force. + * + * An unusable value is refused rather than stored: a mistyped hex value must not leave + * the operator with a black client. The refusal is returned rather than pushed, which is + * what `Form.committed` expects — it puts the field back and shows the reason. + * + * @param role the role to set + * @param text what the operator typed + * @return null when it was accepted, otherwise why it was not + */ + fun set(role: PaletteRole, text: String): String? { + val before = store.resolved(darkModeNow()).roles.getValue(role).colour + + store.set(darkModeNow(), role, text) + + if (store.resolved(darkModeNow()).roles.getValue(role).colour != before) { + return null + } + + /* + * Setting a role to the colour it already had is indistinguishable from a refusal + * here, and saying so would be wrong -- so the value itself decides. + */ + if (kst4contest.model.PaletteOverrides.isValidColour(text)) { + return null + } + + return CurrentStrings.get() + .coloursNotAColour(text, LABELS.getValue(role)(CurrentStrings.get())) + } + + /** + * The pairs that now read worse than the shipped sheet makes them. + * + * @return the warnings to show, empty in the shipped state + */ + fun warnings(): List = contrastWarnings( + resolved = store.resolved(darkModeNow()).palette, + shipped = store.shipped(darkModeNow()), + ) + + /** + * The shipped palette of the design in force. + * + * The lifeline is drawn from this and never from [roles]: a rescue control that took the + * operator's palette would disappear in exactly the palette it exists to undo. + * + * @return layer 1 + */ + fun shipped(): JavaFxPalette = store.shipped(darkModeNow()) + + /** Remembers the palette in force, for [restoreRemembered]. Called when the tab opens. */ + fun rememberCurrentState() = store.takeSnapshot() + + /** The first way back: the palette as it was when the tab was opened, both designs. */ + fun restoreRemembered() = store.restoreSnapshot() + + /** The second way back: empty this design's changes, so file or shipping applies again. */ + fun discardChanges() = store.discardChanges(darkModeNow()) + + /** The third way back, and the one that beats a stylesheet file as well. */ + fun resetToShipped() = store.resetToShipped(darkModeNow()) + + /** + * The path of this design's own stylesheet, shown so the operator knows where to look. + * + * @return absolute path, whether or not the file exists + */ + fun stylesheetPath(): String = paletteFiles.fileFor(darkModeNow()).path + + /** + * Whether this design's own stylesheet is there. + * + * @return true when a file exists at [stylesheetPath] + */ + fun stylesheetExists(): Boolean = paletteFiles.fileFor(darkModeNow()).isFile + + /** + * Writes the shipped stylesheet into the profile so it can be edited by hand. + * + * Never replaces a file that is already there: that file is the operator's own work. + * + * @return what happened, for the window's notice bar + */ + fun exportStylesheet(): StylesheetExportOutcome = + exportShippedStylesheet(paletteFiles.fileFor(darkModeNow()), darkModeNow()) + + private companion object { + + /* + * One place for the six names. Stage 9 moves the interface text into a resource + * bundle; keeping them together is what makes that a single move. + */ + /* + * Each label says where the colour is actually painted, because the role names alone + * mislead: "Surface" is -fx-base, which reaches the screen only through the menu + * strip and the selected-row tint, while "Window surface" is what the windows are + * filled with. An operator reaching for "Surface" to darken the client and seeing + * almost nothing happen would reasonably conclude the control is broken. + * + * Resolved from the texts at the point of use rather than held: the tab must retitle + * its rows when the language changes, and this object outlives a recomposition. + */ + val LABELS: Map String> = mapOf( + PaletteRole.SURFACE to { it.coloursRoleSurface }, + PaletteRole.WINDOW_SURFACE to { it.coloursRoleWindowSurface }, + PaletteRole.FIELD_INTERIOR to { it.coloursRoleFieldInterior }, + PaletteRole.TEXT to { it.coloursRoleText }, + PaletteRole.ACCENT to { it.coloursRoleAccent }, + PaletteRole.SEPARATOR to { it.coloursRoleSeparator }, + ) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ExternalInterfaceFields.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ExternalInterfaceFields.kt new file mode 100644 index 00000000..263a8660 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ExternalInterfaceFields.kt @@ -0,0 +1,156 @@ +package kst4contest.view.compose.tabs + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.width +import androidx.compose.material3.MaterialTheme +import kst4contest.view.compose.CompactTextField +import kst4contest.view.compose.Density +import kst4contest.view.compose.Form +import androidx.compose.material3.Button +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.focus.onFocusChanged +import androidx.compose.ui.unit.dp +import androidx.compose.ui.window.AwtWindow +import java.awt.FileDialog +import java.awt.Frame +import java.io.File + +/** + * Controls the three externally-facing settings tabs need and the shared form controls + * do not provide. + * + * Both exist because of the JavaFX behaviour they replace, not for decoration: + * + * - [GuardedTextField] keeps the text the operator typed and only hands up values the + * caller accepts. The JavaFX fields validated on focus loss and put the stored value + * back on bad input. Writing through on every keystroke without that guard would be + * worse than the old behaviour, because the ChatPreferences setters for the AirScout + * identifiers, the AirScout port and the AirScout band value substitute the factory + * default on bad input instead of keeping the previous value. It also reports focus + * loss, which is where a port change may rebind a socket. + * - [FilePathRow] is the read-only path plus "Choose..." button of the Log synch tab. + */ +@Composable +internal fun GuardedTextField( + label: String, + value: String, + enabled: Boolean = true, + accepts: (String) -> Boolean = { true }, + onAccepted: (String) -> Unit, + onCommit: () -> Unit = {}, +) { + /* + * Keyed on the stored value: the draft is only reset when the stored value really + * changed. A keystroke that is rejected, or one that round-trips to the same stored + * value such as a trailing space that is trimmed away, leaves the typed text alone. + */ + var draft by remember(value) { mutableStateOf(value) } + var hadFocus by remember { mutableStateOf(false) } + + LabelledRow(label) { + CompactTextField( + value = draft, + onValueChange = { typed -> + draft = typed + if (accepts(typed)) { + onAccepted(typed) + } + }, + enabled = enabled, + isError = !accepts(draft), + modifier = Modifier.fillMaxWidth().onFocusChanged { focusState -> + if (hadFocus && !focusState.isFocused) { + onCommit() + } + hadFocus = focusState.isFocused + }, + ) + } +} + +/** + * A stored file path the operator changes through a file chooser only, the way the + * JavaFX tab did: it showed a Label, never an editable field, so a typed path was never + * possible there and is not introduced here. + */ +@Composable +internal fun FilePathRow( + label: String, + value: String, + chooserTitle: String, + onChosen: (String) -> Unit, +) { + var choosing by remember { mutableStateOf(false) } + + LabelledRow(label) { + Row( + horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP), + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxWidth(), + ) { + Text( + value, + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier.weight(1f), + ) + Form.button("Choose...") { choosing = true } + } + } + + if (choosing) { + FileChooserDialog(chooserTitle) { chosenPath -> + choosing = false + if (chosenPath != null) { + onChosen(chosenPath) + } + } + } +} + +/** + * The AWT file dialog, opened from Compose. The JavaFX chooser started in the user's + * home directory and a cancelled choice kept the stored path — both are preserved. + */ +@Composable +private fun FileChooserDialog(title: String, onResult: (String?) -> Unit) { + AwtWindow( + create = { + object : FileDialog(null as Frame?, title, LOAD) { + override fun setVisible(visible: Boolean) { + if (visible) { + directory = System.getProperty("user.home") + } + super.setVisible(visible) + if (visible) { + val chosenName = file + onResult( + if (chosenName == null) null + else File(directory ?: "", chosenName).absolutePath + ) + } + } + } + }, + dispose = FileDialog::dispose, + ) +} + +/** The label column width the shared form controls use, so the tabs line up. */ +@Composable +private fun LabelledRow(label: String, field: @Composable () -> Unit) { + /* + * Delegates rather than repeating the row: the label column width and the row height + * are defined once, in Form, so this file cannot drift away from the other tabs. + */ + Form.labelledRow(label, field) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/GuiOptionsTab.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/GuiOptionsTab.kt new file mode 100644 index 00000000..357b3699 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/GuiOptionsTab.kt @@ -0,0 +1,80 @@ +package kst4contest.view.compose.tabs + +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import kst4contest.view.compose.Form +import kst4contest.view.i18n.Translations +import kst4contest.view.i18n.SYSTEM_LANGUAGE +import kst4contest.view.i18n.LocalStrings + +/** + * The GUI tab: startup design, the startup message filters and the band-column hints. + * + * The four startup filters stay four independent checkboxes. The JavaFX tab offered + * them that way, and turning them into a choice of one would take a combination away + * that an operator may have configured. + */ +@Composable +fun GuiOptionsTab(state: GuiOptionsTabState) { + val strings = LocalStrings.current + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + Form.section(strings.guiStartupDesign) { + Form.check("Start in the evening design", state.gUI_darkModeActiveByDefault) { + state.gUI_darkModeActiveByDefault = it + } + } + + Form.flowingSection(strings.guiStartupFilters) { + Form.check("Public messages", state.guiOptions_defaultFilterPublicMsgs) { + state.guiOptions_defaultFilterPublicMsgs = it + } + Form.check("Private messages to me", state.guiOptions_defaultFilterPmToMe) { + state.guiOptions_defaultFilterPmToMe = it + } + Form.check("Private messages to others", state.guiOptions_defaultFilterPmToOther) { + state.guiOptions_defaultFilterPmToOther = it + } + Form.check("No filter", state.guiOptions_defaultFilterNothing) { + state.guiOptions_defaultFilterNothing = it + } + } + + Form.flowingSection(strings.guiBandColumnHints) { + Form.check("Mark a callsign seen for the first time", state.guiOptions_showFreshCallHintInBandColumns) { + state.guiOptions_showFreshCallHintInBandColumns = it + } + Form.check("Mark a worked large grid field", state.guiOptions_showGrossFieldWorkedHintInBandColumns) { + state.guiOptions_showGrossFieldWorkedHintInBandColumns = it + } + } + + /* + * Appended last so no established section position moves, the same reason the colours + * tab was appended after Profiles. The label and the "system" entry come from the + * texts, so the picker is itself in the language it switches. + */ + Form.section(strings.guiLanguage) { + Form.choice( + label = strings.guiLanguage, + items = listOf(SYSTEM_LANGUAGE) + Translations.BY_LANGUAGE.keys.sorted(), + selected = state.language, + describe = { code -> + /* + * The code in capitals rather than a name for the language: a display name + * per language would be another key every contributor has to maintain, and + * DE/EN is unambiguous for two. A longer list is where a name earns itself. + */ + if (code == SYSTEM_LANGUAGE) strings.guiLanguageSystem else code.uppercase() + }, + onSelect = { state.language = it }, + ) + } + + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/GuiOptionsTabState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/GuiOptionsTabState.kt new file mode 100644 index 00000000..e28368d7 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/GuiOptionsTabState.kt @@ -0,0 +1,57 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatPreferences +import kst4contest.view.i18n.LanguageStore + +/** + * The GUI tab as a typed facade over ChatPreferences. + * + * Writes through immediately and has no apply(), like every settings tab: the + * JavaFX controls wrote as they changed and "Save settings" only persisted. + */ +class GuiOptionsTabState( + private val prefs: ChatPreferences, + private val languageStore: LanguageStore, +) { + + var gUI_darkModeActiveByDefault: Boolean + get() = prefs.isGUI_darkModeActiveByDefault() + set(value) { prefs.setGUI_darkModeActiveByDefault(value) } + + var guiOptions_defaultFilterNothing: Boolean + get() = prefs.isGuiOptions_defaultFilterNothing() + set(value) { prefs.setGuiOptions_defaultFilterNothing(value) } + + var guiOptions_defaultFilterPmToMe: Boolean + get() = prefs.isGuiOptions_defaultFilterPmToMe() + set(value) { prefs.setGuiOptions_defaultFilterPmToMe(value) } + + var guiOptions_defaultFilterPmToOther: Boolean + get() = prefs.isGuiOptions_defaultFilterPmToOther() + set(value) { prefs.setGuiOptions_defaultFilterPmToOther(value) } + + var guiOptions_defaultFilterPublicMsgs: Boolean + get() = prefs.isGuiOptions_defaultFilterPublicMsgs() + set(value) { prefs.setGuiOptions_defaultFilterPublicMsgs(value) } + + var guiOptions_showFreshCallHintInBandColumns: Boolean + get() = prefs.isGuiOptions_showFreshCallHintInBandColumns() + set(value) { prefs.setGuiOptions_showFreshCallHintInBandColumns(value) } + + /** + * The interface language, as the picker offers it: a language code, or the empty string + * for the system language. + * + * Read and written through the store, both ways. The store writes the preference itself; + * reading the preference here instead would give one value two sources, and they disagree + * the moment a caller hands the state a store wired to anything else. + */ + var language: String + get() = languageStore.stored + set(value) { languageStore.use(value) } + + var guiOptions_showGrossFieldWorkedHintInBandColumns: Boolean + get() = prefs.isGuiOptions_showGrossFieldWorkedHintInBandColumns() + set(value) { prefs.setGuiOptions_showGrossFieldWorkedHintInBandColumns(value) } + +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/LogSynchTab.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/LogSynchTab.kt new file mode 100644 index 00000000..64414e58 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/LogSynchTab.kt @@ -0,0 +1,100 @@ +package kst4contest.view.compose.tabs + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import kst4contest.view.compose.Form + +/** + * The Log synch tab: how worked callsigns reach KST4Contest — by polling a log file, by + * UDP from N1MM+/QARTEST/UCXLog/DXLog, and by the Win-Test network. + * + * No confirmation callback: LogSynchTabState writes through to ChatPreferences, the way + * the JavaFX controls did. "Save settings" persists, it does not collect. + * + * Labels, units and default hints are the JavaFX ones. The Win-Test port field is + * disabled while its listener is off, as it was there. + */ +@Composable +fun LogSynchTab(state: LogSynchTabState) { + /* + * The state is a plain facade over ChatPreferences with no snapshot state in it, so + * a control would keep showing the old value after its own write. Counting revisions + * is the device WorkedDatabaseTab uses for the same reason. + */ + var revision by remember { mutableStateOf(0) } + val strings = LocalStrings.current + + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + @Suppress("UNUSED_EXPRESSION") revision + + Form.section(strings.logSynchFileSection) { + Form.check( + strings.logSynchFileEnabled, + state.logsynch_fileBasedWkdCallInterpreterEnabled, + ) { state.logsynch_fileBasedWkdCallInterpreterEnabled = it; revision++ } + + FilePathRow( + label = strings.logSynchFileLabel, + value = state.logsynch_fileBasedWkdCallInterpreterFileNameReadOnly, + chooserTitle = strings.logSynchFileChooserTitle, + ) { state.logsynch_fileBasedWkdCallInterpreterFileNameReadOnly = it; revision++ } + } + + Form.section(strings.logSynchNetworkSection) { + Form.check( + strings.logSynchNetworkEnabled, + state.logsynch_ucxUDPWkdCallListenerEnabled, + ) { state.logsynch_ucxUDPWkdCallListenerEnabled = it; revision++ } + + Form.int( + strings.logSynchSharedPort, + state.logsynch_ucxUDPWkdCallListenerPort, + ) { state.logsynch_ucxUDPWkdCallListenerPort = it; revision++ } + } + + Form.section(strings.logSynchWinTestSection) { + Form.check( + strings.logSynchWinTestEnabled, + state.logsynch_wintestNetworkListenerEnabled, + ) { state.logsynch_wintestNetworkListenerEnabled = it; revision++ } + + GuardedTextField( + label = strings.logSynchWinTestPort, + value = state.logsynch_wintestNetworkPort.toString(), + enabled = state.logsynch_wintestNetworkListenerEnabled, + accepts = { it.trim().toIntOrNull() != null }, + onAccepted = { state.logsynch_wintestNetworkPort = it.trim().toInt(); revision++ }, + // Rebinding the socket belongs to the finished entry, not to every digit. + onCommit = { state.commitWintestNetworkPort() }, + ) + + GuardedTextField( + label = strings.logSynchWinTestStationName, + value = state.logsynch_wintestNetworkStationNameOfKST, + onAccepted = { state.logsynch_wintestNetworkStationNameOfKST = it; revision++ }, + ) + + GuardedTextField( + label = strings.logSynchWinTestBroadcast, + value = state.logsynch_wintestNetworkBroadcastAddress, + onAccepted = { state.logsynch_wintestNetworkBroadcastAddress = it; revision++ }, + ) + + Text( + strings.logSynchWinTestHint(LogSynchTabState.DEFAULT_BROADCAST_ADDRESS) + ) + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/LogSynchTabState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/LogSynchTabState.kt new file mode 100644 index 00000000..0bfdff49 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/LogSynchTabState.kt @@ -0,0 +1,127 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatPreferences + +/** + * The Log synch tab as a typed facade over ChatPreferences. + * + * Every property writes through immediately, and there is deliberately no apply(). + * That mirrors the JavaFX window it replaces: its controls each wrote into + * ChatPreferences the moment they changed, and its two buttons only persisted + * ("Save settings" calls writePreferencesToXmlFile) or closed the window. + * + * Two things this tab controlled are not settings at all but effects on the running + * session, and no coverage test can see them because they are not ChatPreferences + * setters. They are taken as callbacks rather than from a ChatController so the rules + * stay testable without opening a database: + * + * - the Win-Test UDP listener is started and stopped with its setting; + * - the Win-Test broadcast address is auto-detected while it is still the catch-all + * default, which the JavaFX window did while building the settings pane. + * + * Ports, transports and framing are untouched: the accepted values, the defaults and + * the moment a socket is rebound are the ones the JavaFX window had. + * + * @param restartWintestListener rebinds the Win-Test UDP listener; maps to + * ChatController.restartWintestUdpListenerIfEnabled() + * @param stopWintestListener maps to ChatController.stopWintestUdpListener() + * @param detectWintestBroadcastAddress the detected subnet broadcast address, or null + * when none could be determined; maps to detectPreferredWintestBroadcastAddress() + */ +class LogSynchTabState( + private val prefs: ChatPreferences, + private val restartWintestListener: () -> Unit, + private val stopWintestListener: () -> Unit, + private val detectWintestBroadcastAddress: () -> String?, +) { + + init { + autoDetectBroadcastAddressWhileStillDefault() + } + + var logsynch_fileBasedWkdCallInterpreterEnabled: Boolean + get() = prefs.isLogsynch_fileBasedWkdCallInterpreterEnabled() + set(value) { prefs.setLogsynch_fileBasedWkdCallInterpreterEnabled(value) } + + /** + * The log file polled for worked callsigns. The JavaFX tab showed it read-only and + * changed it through a file chooser only, so the Compose tab does the same: a typed + * path could not be checked for existence there either, and letting one be typed + * would be a new capability, not a ported one. + */ + var logsynch_fileBasedWkdCallInterpreterFileNameReadOnly: String + get() = prefs.getLogsynch_fileBasedWkdCallInterpreterFileNameReadOnly() + set(value) { prefs.setLogsynch_fileBasedWkdCallInterpreterFileNameReadOnly(value) } + + var logsynch_ucxUDPWkdCallListenerEnabled: Boolean + get() = prefs.isLogsynch_ucxUDPWkdCallListenerEnabled() + set(value) { prefs.setLogsynch_ucxUDPWkdCallListenerEnabled(value) } + + /** + * Shared UDP port for QSO and TRX messages, default 12060. The JavaFX field + * accepted any number here and rebound nothing — that listener comes up at start — + * so neither a range nor a restart is added. + */ + var logsynch_ucxUDPWkdCallListenerPort: Int + get() = prefs.getLogsynch_ucxUDPWkdCallListenerPort() + set(value) { prefs.setLogsynch_ucxUDPWkdCallListenerPort(value) } + + var logsynch_wintestNetworkListenerEnabled: Boolean + get() = prefs.isLogsynch_wintestNetworkListenerEnabled() + set(value) { + prefs.setLogsynch_wintestNetworkListenerEnabled(value) + if (value) restartWintestListener() else stopWintestListener() + } + + /** + * UDP port for the Win-Test listener, default 9871. The setting is written at once + * like every other, but the socket is only rebound by [commitWintestNetworkPort] — + * the JavaFX field did that on focus loss, and rebinding per keystroke would bind + * and unbind a UDP port for every digit on the way to the intended one. + */ + var logsynch_wintestNetworkPort: Int + get() = prefs.getLogsynch_wintestNetworkPort() + set(value) { prefs.setLogsynch_wintestNetworkPort(value) } + + /** Applies the entered port to the running listener, if there is one. */ + fun commitWintestNetworkPort() { + if (prefs.isLogsynch_wintestNetworkListenerEnabled()) { + restartWintestListener() + } + } + + /** The name KST4Contest uses as source of Win-Test SKED packets. */ + var logsynch_wintestNetworkStationNameOfKST: String + get() = prefs.getLogsynch_wintestNetworkStationNameOfKST() + set(value) { prefs.setLogsynch_wintestNetworkStationNameOfKST(value.trim()) } + + /** UDP broadcast address used for sending to Win-Test. */ + var logsynch_wintestNetworkBroadcastAddress: String + get() = prefs.getLogsynch_wintestNetworkBroadcastAddress() + set(value) { prefs.setLogsynch_wintestNetworkBroadcastAddress(value.trim()) } + + /** + * Replaces the catch-all default 255.255.255.255 with the detected subnet + * broadcast address. An address the operator or a previous detection chose is + * left alone, and a failed detection keeps the default: guessing an address here + * would send SKED packets somewhere nobody is listening. + */ + private fun autoDetectBroadcastAddressWhileStillDefault() { + if (prefs.getLogsynch_wintestNetworkBroadcastAddress() != DEFAULT_BROADCAST_ADDRESS) { + return + } + val detected = try { + detectWintestBroadcastAddress() + } catch (probeFailure: RuntimeException) { + null + } + if (detected != null && detected.isNotBlank()) { + prefs.setLogsynch_wintestNetworkBroadcastAddress(detected) + } + } + + companion object { + /** The stored value that still means "not configured for this network". */ + const val DEFAULT_BROADCAST_ADDRESS: String = "255.255.255.255" + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTab.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTab.kt new file mode 100644 index 00000000..f89ed4ac --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTab.kt @@ -0,0 +1,46 @@ +package kst4contest.view.compose.tabs + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import kst4contest.view.compose.Form + +/** The message-handling tab: the automatic answer and the automatic QRG reply. */ +@Composable +fun MessageHandlingTab(state: MessageHandlingTabState) { + val strings = LocalStrings.current + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + Form.section(strings.messageHandlingAutoAnswerSection) { + Form.check(strings.messageHandlingAutoAnswerEnabled, state.autoAnswerEnabled) { + state.autoAnswerEnabled = it + } + Form.text(strings.messageHandlingAutoAnswerText, state.autoAnswerText) { state.autoAnswerText = it } + } + + Form.section(strings.messageHandlingQrgAnswerSection) { + Form.check( + strings.messageHandlingQrgAnswerEnabled, + state.autoAnswerToQRGRequestEnabled, + ) { state.autoAnswerToQRGRequestEnabled = it } + } + + Form.section(strings.messageHandlingDiagnosticsSection) { + Form.check( + strings.messageHandlingDebugToFileEnabled, + state.debugModeToFileEnabled, + ) { state.debugModeToFileEnabled = it } + Text( + strings.messageHandlingDebugToFileHint, + style = MaterialTheme.typography.bodySmall, + ) + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTabState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTabState.kt new file mode 100644 index 00000000..ff4e61bc --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/MessageHandlingTabState.kt @@ -0,0 +1,51 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatPreferences + +/** + * State of the message-handling tab. + * + * The JavaFX window offered one checkbox and one text field for the automatic + * answer and wrote both chat categories from each of them + * (Kst4ContestApplication:12004 and :12039). Exposing one property per pair keeps + * that: a tab that wrote only the main category would leave the second chat on its + * previous value, which no part of the window ever displayed. + */ +class MessageHandlingTabState( + private val prefs: ChatPreferences, + private val applyDebugModeToFile: (Boolean) -> Unit = {}, +) { + + /** Drives both category flags, as the single JavaFX checkbox did. */ + var autoAnswerEnabled: Boolean + get() = prefs.isMessageHandling_autoAnswerEnabled() + set(value) { + prefs.setMessageHandling_autoAnswerEnabled(value) + prefs.setMessageHandling_autoAnswerEnabledSecondCat(value) + } + + /** Drives both category texts, as the single JavaFX text field did. */ + var autoAnswerText: String + get() = prefs.getMessageHandling_autoAnswerTextMainCat() + set(value) { + prefs.setMessageHandling_autoAnswerTextMainCat(value) + prefs.setMessageHandling_autoAnswerTextSecondCat(value) + } + + /** Independent of the automatic answer; its own checkbox in the JavaFX window. */ + var autoAnswerToQRGRequestEnabled: Boolean + get() = prefs.isMessageHandling_autoAnswerToQRGRequestEnabled() + set(value) { prefs.setMessageHandling_autoAnswerToQRGRequestEnabled(value) } + + /** + * Records the whole session to file. Beyond the preference it opens or closes the + * error-log handler and the history recorder, which only the application can sequence; + * [applyDebugModeToFile] carries that out in the order the JavaFX checkbox kept. + */ + var debugModeToFileEnabled: Boolean + get() = prefs.isMessageHandling_debugModeToFileEnabled() + set(value) { + prefs.setMessageHandling_debugModeToFileEnabled(value) + applyDebugModeToFile(value) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/NotificationTab.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/NotificationTab.kt new file mode 100644 index 00000000..73c21e7d --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/NotificationTab.kt @@ -0,0 +1,151 @@ +package kst4contest.view.compose.tabs + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Button +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.OutlinedButton +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import kst4contest.model.Band +import kst4contest.view.compose.DataTable +import kst4contest.view.compose.Form + +/** + * The notification tab: sounds, band-upgrade hints, the local DX Cluster server and + * the QSO monitoring list. + * + * The port and the spotter callsign are committed when the field is left, not while + * it is typed: both are validated, and a rule applied per keystroke would refuse + * every prefix of a valid entry. + */ +@Composable +fun NotificationTab(state: NotificationTabState, onRefused: (String) -> Unit) { + var askForCallSign by remember { mutableStateOf(false) } + val strings = LocalStrings.current + + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + Form.section(strings.notificationSoundsSection) { + Form.check(strings.notificationSimpleSounds, state.notify_playSimpleSounds) { + state.notify_playSimpleSounds = it + } + Form.check( + strings.notificationCwCallsign, + state.notify_playCWCallsignsOnRxedPMs, + ) { state.notify_playCWCallsignsOnRxedPMs = it } + Form.check( + strings.notificationSpeakCallsign, + state.notify_playVoiceCallsignsOnRxedPMs, + ) { state.notify_playVoiceCallsignsOnRxedPMs = it } + } + + Form.section(strings.notificationBandUpgradeSection) { + Form.check( + strings.notificationBandUpgradeHint, + state.notify_bandUpgradeHintOnLogEnabled, + ) { state.notify_bandUpgradeHintOnLogEnabled = it } + Form.check( + strings.notificationBandUpgradePriority, + state.notify_bandUpgradePriorityBoostEnabled, + ) { state.notify_bandUpgradePriorityBoostEnabled = it } + } + + Form.section(strings.notificationClusterSection) { + Form.check(strings.notificationClusterEnabled, state.notify_dxClusterServerEnabled) { + state.enableDxClusterServer(it) + } + Form.committed( + label = strings.notificationClusterPort, + stored = state.notify_dxclusterServerPort.toString(), + commit = state::commitDxClusterServerPort, + onRefused = onRefused, + ) + Form.committed( + label = strings.notificationSpotterCallsign, + stored = state.notify_DXCSrv_SpottersCallSign, + commit = state::commitSpotterCallSign, + onRefused = onRefused, + ) + /* + * Shows the band prefix, as the JavaFX ComboBox did: the prefix is what the + * stored setting contains. + */ + Form.choice( + label = strings.notificationFallbackBand, + items = Band.entries, + selected = state.notify_optionalFrequencyPrefix, + describe = { it.prefix + " MHz" }, + onSelect = { state.notify_optionalFrequencyPrefix = it }, + ) + Row { + /* + * A refusal is the normal outcome here: the JavaFX button reported + * "no logger connected" the same way, which is exactly what the + * operator is testing for. + */ + Form.button(strings.notificationSendTestSpot) { state.sendTestSpot()?.let(onRefused) } + } + } + + Form.section(strings.notificationMonitoringSection) { + DataTable( + state = state.monitoredCallSigns, + addButtonText = strings.notificationAddMonitored, + newEntryTemplate = "", + onChanged = state::commitMonitoredCallSigns, + onRefused = onRefused, + /* + * The JavaFX button asked for the callsign in a dialog before adding + * it, so there was never a placeholder row to edit. + */ + onAdd = { askForCallSign = true }, + ) + } + } + + if (askForCallSign) { + var entered by remember { mutableStateOf("") } + + AlertDialog( + onDismissRequest = { askForCallSign = false }, + title = { Text(strings.notificationMonitoringSection) }, + text = { + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + Text(strings.notificationAddCallsignToList) + OutlinedTextField( + value = entered, + onValueChange = { entered = it }, + singleLine = true, + label = { Text(strings.notificationCallsign) }, + ) + } + }, + confirmButton = { + TextButton(onClick = { + askForCallSign = false + state.addMonitoredCallSign(entered)?.let(onRefused) + }) { Text(strings.dialogOk) } + }, + dismissButton = { + TextButton(onClick = { askForCallSign = false }) { Text(strings.dialogCancel) } + }, + ) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/NotificationTabState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/NotificationTabState.kt new file mode 100644 index 00000000..9deb9fd4 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/NotificationTabState.kt @@ -0,0 +1,214 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.Band +import kst4contest.model.ChatMember +import kst4contest.model.ChatPreferences +import kst4contest.observe.SimpleRoster +import kst4contest.observe.SimpleValue +import kst4contest.view.GuiUtils +import kst4contest.view.compose.CommitOutcome +import kst4contest.view.compose.EditableListState +import kst4contest.view.compose.EntryRule +import java.util.Locale + +/** + * State of the notification tab: sounds, band-upgrade hints, the local DX Cluster + * server and the QSO monitoring list. + * + * Three of these reach past the preferences into the running session, which the + * settings coverage test cannot see, so they are constructor callbacks rather than + * plain properties: starting and stopping the server, restarting it after a port + * change, and sending the test spot. + * + * @param monitoredRoster `ChatController.getLstNotify_QSOSniffer_sniffedCallSignList`; + * it lives on the controller, not in the preferences, which is why it is + * passed separately. + * @param applyDxClusterServerEnabled starts or stops the server, the work the + * JavaFX checkbox did beyond writing the flag. + * @param applyDxClusterServerPort restarts the server; called only when the port + * actually changed, as the JavaFX field did. + * @param broadcastTestSpot delivers the spot and returns null on success or the + * reason it could not be delivered. + */ +class NotificationTabState( + private val prefs: ChatPreferences, + private val monitoredRoster: SimpleRoster, + private val applyDxClusterServerEnabled: (Boolean) -> Unit, + private val applyDxClusterServerPort: (Int) -> Unit, + private val broadcastTestSpot: (ChatMember) -> String?, +) { + + var notify_playSimpleSounds: Boolean + get() = prefs.isNotify_playSimpleSounds() + set(value) { prefs.setNotify_playSimpleSounds(value) } + + var notify_playCWCallsignsOnRxedPMs: Boolean + get() = prefs.isNotify_playCWCallsignsOnRxedPMs() + set(value) { prefs.setNotify_playCWCallsignsOnRxedPMs(value) } + + var notify_playVoiceCallsignsOnRxedPMs: Boolean + get() = prefs.isNotify_playVoiceCallsignsOnRxedPMs() + set(value) { prefs.setNotify_playVoiceCallsignsOnRxedPMs(value) } + + var notify_bandUpgradeHintOnLogEnabled: Boolean + get() = prefs.isNotify_bandUpgradeHintOnLogEnabled() + set(value) { prefs.setNotify_bandUpgradeHintOnLogEnabled(value) } + + var notify_bandUpgradePriorityBoostEnabled: Boolean + get() = prefs.isNotify_bandUpgradePriorityBoostEnabled() + set(value) { prefs.setNotify_bandUpgradePriorityBoostEnabled(value) } + + val notify_dxClusterServerEnabled: Boolean + get() = prefs.isNotify_dxClusterServerEnabled() + + val notify_dxclusterServerPort: Int + get() = prefs.getNotify_dxclusterServerPort() + + val notify_DXCSrv_SpottersCallSign: String + get() = prefs.getNotify_DXCSrv_SpottersCallSign().get() + + /** + * The band a spot falls back to when its frequency carries no band information. + * + * Stored as a prefix string, so an unreadable value is possible; reading it + * repairs the stored value to 144, which is what the JavaFX window did when it + * built the combo box (Kst4ContestApplication:11349). + */ + var notify_optionalFrequencyPrefix: Band + get() { + val stored = Band.fromPrefix(prefs.getNotify_optionalFrequencyPrefix().get()) + + if (stored == null) { + prefs.setNotify_optionalFrequencyPrefix(Band.B_144.prefix) + return Band.B_144 + } + + return stored + } + set(value) { prefs.setNotify_optionalFrequencyPrefix(value.prefix) } + + val monitoredCallSigns = EditableListState( + monitoredRoster.snapshot(), + rule = EntryRule { candidate, _, others -> judgeMonitoredCallSign(candidate, others) }, + ) + + /** Writes the flag and lets the running session start or stop the server. */ + fun enableDxClusterServer(enabled: Boolean) { + prefs.setNotify_dxClusterServerEnabled(enabled) + applyDxClusterServerEnabled(enabled) + } + + /** + * @return null when applied, otherwise the reason the port was refused. + */ + fun commitDxClusterServerPort(entered: String): String? { + val previousPort = prefs.getNotify_dxclusterServerPort() + val port = entered.trim().toIntOrNull() + + if (port == null || port < 1 || port > 65535) { + return "\"" + entered.trim() + "\" is not a valid TCP port. " + + "Enter a value from 1 to 65535." + } + + prefs.setNotify_dxclusterServerPort(port) + + /* + * Restarting on an unchanged port would drop a connected logger for nothing; + * the JavaFX field guarded the restart the same way. + */ + if (port != previousPort) { + applyDxClusterServerPort(port) + } + + return null + } + + /** + * @return null when stored, otherwise the reason the callsign was refused. + */ + fun commitSpotterCallSign(entered: String): String? { + val spotterCallSign = entered.trim().uppercase(Locale.ROOT) + + if (!GuiUtils.isCallSignSyntax(spotterCallSign)) { + return "\"" + spotterCallSign + "\" is not a valid spotter callsign." + } + + prefs.setNotify_DXCSrv_SpottersCallSign(spotterCallSign) + return null + } + + /** + * Appends a callsign to the monitoring list and fills the roster at once, as the + * JavaFX dialog did. + * + * @return null when added, otherwise the reason it was refused. + */ + fun addMonitoredCallSign(entered: String): String? { + val verdict = judgeMonitoredCallSign(entered, monitoredCallSigns.texts) + + if (verdict is CommitOutcome.Refused) { + return verdict.message + } + + if (verdict !is CommitOutcome.Stored) { + return "Please enter a valid callsign." + } + + /* + * Appended, not inserted at the top: the JavaFX button called add on the + * roster. The order is the order the operator entered them in. + */ + monitoredCallSigns.addAtBottom(verdict.text) + commitMonitoredCallSigns() + return null + } + + /** Fills the monitoring roster from the list. */ + fun commitMonitoredCallSigns() { + monitoredCallSigns.commitTo(monitoredRoster) + } + + /** + * Builds the spot the JavaFX test button sent and hands it to the server. + * + * @return null when delivered, otherwise the reason it was not. + */ + fun sendTestSpot(): String? { + val testSpot = ChatMember() + /* + * The Java setters are called by name rather than through Kotlin property + * assignment: the foreign-write coverage test looks for these three names, + * and it is the only check that the test spot still carries its values. + */ + testSpot.setFrequency(SimpleValue("300")) + testSpot.setQra("DXC test: You donated \$100!") + testSpot.setCallSign("DO5AMF") + + return broadcastTestSpot(testSpot) + } + + /** + * Monitoring works on the base callsign, so every SSID and portable suffix maps + * to one entry. A blank text removes the entry, the removal gesture of every + * list in this window. + */ + private fun judgeMonitoredCallSign(candidate: String, others: List): CommitOutcome { + if (candidate.isBlank()) { + return CommitOutcome.Removed + } + + val baseCall = ChatMember.normalizeCallSignToBaseCallSign( + candidate.trim().uppercase(Locale.ROOT) + ) + + if (baseCall == null || !GuiUtils.isCallSignSyntax(baseCall)) { + return CommitOutcome.Refused("Please enter a valid callsign.") + } + + if (others.any { it != null && it.equals(baseCall, ignoreCase = true) }) { + return CommitOutcome.Refused("This base callsign is already in the monitoring list.") + } + + return CommitOutcome.Stored(baseCall) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ProfilesTab.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ProfilesTab.kt new file mode 100644 index 00000000..8298ee5e --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ProfilesTab.kt @@ -0,0 +1,380 @@ +package kst4contest.view.compose.tabs + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.background +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.RowScope +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.border +import androidx.compose.foundation.layout.heightIn +import androidx.compose.foundation.layout.size +import androidx.compose.material3.HorizontalDivider +import androidx.compose.material3.LocalMinimumInteractiveComponentSize +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.unit.Dp +import kst4contest.view.compose.Density +import androidx.compose.material3.AlertDialog +import androidx.compose.material3.Button +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField +import androidx.compose.material3.RadioButton +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.unit.dp +import kst4contest.model.OperatorProfile +import kst4contest.view.compose.Form + +/** + * The profiles tab. + * + * Every action that cannot be undone asks first, and the question names what will be + * removed — the JavaFX pane did that for the deletion and it is the one action here + * that destroys data. + */ +@Composable +fun ProfilesTab(state: ProfilesTabState) { + val strings = LocalStrings.current + + var notice by remember { mutableStateOf(null) } + var dialog by remember { mutableStateOf(null) } + + fun act(action: () -> ProfileNotice?) { + notice = action() + } + + Column( + modifier = Modifier.padding(4.dp), + verticalArrangement = Arrangement.spacedBy(10.dp), + ) { + Column(verticalArrangement = Arrangement.spacedBy(2.dp)) { + Form.labelledRow(strings.profilesActive) { Text(state.activeProfileName) } + Form.labelledRow(strings.profilesSettingsFile) { Text(state.preferencesPath) } + Form.labelledRow(strings.profilesWorkedStations) { Text(state.workedDatabasePath) } + } + + ProfileList(state, state::select) + + Row(horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP)) { + Form.button(strings.profilesNew) { dialog = ProfileDialog.Create } + Form.button(strings.profilesDuplicate) { + dialog = ProfileDialog.Duplicate(state.duplicateNameSuggestion()) + } + Form.button(strings.profilesRename) { + state.selected?.let { dialog = ProfileDialog.Rename(it.displayName) } + } + Form.button(strings.profilesDelete) { + val profile = state.selected + if (profile == null) { + act { state.deleteSelected() } + } else { + dialog = ProfileDialog.ConfirmDelete(profile, state.describeDeletion(profile)) + } + } + } + + Row(horizontalArrangement = Arrangement.spacedBy(Density.BUTTON_GAP)) { + Form.button(strings.profilesChangeWorked) { + val profile = state.selected + if (profile == null || !state.canChangeWorkedDataMode(profile)) { + act { state.changeWorkedDataModeOfSelected(false) } + } else { + dialog = ProfileDialog.WorkedData(profile, profile.isSharedWorkedDatabase) + } + } + + Form.button(strings.profilesSwitchTo) { act { state.activateSelected() } } + } + + Text( + strings.profilesExplanation, + style = MaterialTheme.typography.bodySmall, + ) + } + + dialog?.let { open -> + ProfileDialogs( + dialog = open, + onDismiss = { dialog = null }, + onCreate = { name, shared -> dialog = null; act { state.createProfile(name, shared) } }, + onDuplicate = { name -> dialog = null; act { state.duplicateSelected(name) } }, + onRename = { name -> dialog = null; act { state.renameSelected(name) } }, + onDelete = { dialog = null; act { state.deleteSelected() } }, + onWorkedData = { shared -> dialog = null; act { state.changeWorkedDataModeOfSelected(shared) } }, + ) + } + + notice?.let { shown -> + AlertDialog( + onDismissRequest = { notice = null }, + title = { Text(strings.profilesDialogTitle) }, + text = { Text(shown.message) }, + confirmButton = { TextButton(onClick = { notice = null }) { Text(strings.dialogOk) } }, + ) + } +} + +/** + * The profile table. It observes ProfilesTabState directly: the selection and the list + * are Compose state, so a row redraws when the selection moves off it. + */ +@Composable +private fun ProfileList(state: ProfilesTabState, onSelect: (OperatorProfile?) -> Unit) { + val strings = LocalStrings.current + + if (state.profiles.isEmpty()) { + Text(strings.profilesNone) + return + } + + Column(modifier = Modifier.fillMaxWidth()) { + Row(modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp)) { + HeaderCell(strings.profilesColumnProfile, 0.4f) + HeaderCell(strings.profilesColumnWorked, 0.4f) + HeaderCell(strings.profilesColumnLastUsed, 0.2f) + } + + LazyColumn(modifier = Modifier.height(200.dp).fillMaxWidth()) { + items(state.profiles, key = { it.profileId }) { profile -> + val isSelected = profile == state.selected + + Column { + /* + * The selected row carries a full frame in the accent colour on top + * of the tint. Unlike the editable lists there is no field border + * here to compete with, so the frame is the clearest marker. + */ + Row( + modifier = Modifier + .fillMaxWidth() + .background( + if (isSelected) { + MaterialTheme.colorScheme.secondaryContainer + } else { + MaterialTheme.colorScheme.surface + } + ) + .then( + if (isSelected) { + Modifier.border( + Density.SELECTION_BORDER, + MaterialTheme.colorScheme.primary, + ) + } else { + Modifier + } + ) + .clickable { onSelect(profile) } + .heightIn(min = Density.ROW_MIN_HEIGHT) + .padding(horizontal = 4.dp, vertical = 3.dp), + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + profile.displayName + if (state.isActive(profile)) strings.profilesInUse else "", + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier.weight(0.4f), + ) + Text( + ProfilesTabState.describeWorkedDataMode(profile), + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier.weight(0.4f), + ) + Text( + ProfilesTabState.describeLastUsed(profile), + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier.weight(0.2f), + ) + } + + /* A hairline between rows, so the list reads as a table. */ + if (!isSelected) { + HorizontalDivider(thickness = Density.HAIRLINE) + } + } + } + } + } +} + +/** Extension on RowScope because only that scope provides the weight modifier. */ +@Composable +private fun RowScope.HeaderCell(text: String, weight: Float) { + Text(text, fontWeight = FontWeight.Bold, modifier = Modifier.weight(weight)) +} + +/** The dialogs the profile actions need, so each action asks before it acts. */ +private sealed interface ProfileDialog { + data object Create : ProfileDialog + data class Duplicate(val suggestion: String) : ProfileDialog + data class Rename(val current: String) : ProfileDialog + data class ConfirmDelete(val profile: OperatorProfile, val consequences: String) : ProfileDialog + data class WorkedData(val profile: OperatorProfile, val shared: Boolean) : ProfileDialog +} + +@Composable +private fun ProfileDialogs( + dialog: ProfileDialog, + onDismiss: () -> Unit, + onCreate: (String, Boolean) -> Unit, + onDuplicate: (String) -> Unit, + onRename: (String) -> Unit, + onDelete: () -> Unit, + onWorkedData: (Boolean) -> Unit, +) { + val strings = LocalStrings.current + + when (dialog) { + ProfileDialog.Create -> { + var name by remember { mutableStateOf("") } + var shared by remember { mutableStateOf(false) } + + AlertDialog( + onDismissRequest = onDismiss, + title = { Text(strings.profilesNewTitle) }, + text = { + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + Text(strings.profilesNewBody) + OutlinedTextField( + value = name, + onValueChange = { name = it }, + singleLine = true, + label = { Text(strings.profilesNameLabel) }, + ) + WorkedDataChoice(shared) { shared = it } + } + }, + confirmButton = { TextButton(onClick = { onCreate(name, shared) }) { Text(strings.profilesCreate) } }, + dismissButton = { TextButton(onClick = onDismiss) { Text(strings.dialogCancel) } }, + ) + } + + is ProfileDialog.Duplicate -> { + var name by remember { mutableStateOf(dialog.suggestion) } + + AlertDialog( + onDismissRequest = onDismiss, + title = { Text(strings.profilesDuplicateTitle) }, + text = { + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + Text(strings.profilesDuplicateBody) + Text( + strings.profilesDuplicateHint, + style = MaterialTheme.typography.bodySmall, + ) + OutlinedTextField( + value = name, + onValueChange = { name = it }, + singleLine = true, + ) + } + }, + confirmButton = { TextButton(onClick = { onDuplicate(name) }) { Text(strings.dialogOk) } }, + dismissButton = { TextButton(onClick = onDismiss) { Text(strings.dialogCancel) } }, + ) + } + + is ProfileDialog.Rename -> { + var name by remember { mutableStateOf(dialog.current) } + + AlertDialog( + onDismissRequest = onDismiss, + title = { Text(strings.profilesRenameTitle) }, + text = { + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + Text(strings.profilesRenameBody) + Text( + strings.profilesRenameHint, + style = MaterialTheme.typography.bodySmall, + ) + OutlinedTextField( + value = name, + onValueChange = { name = it }, + singleLine = true, + ) + } + }, + confirmButton = { TextButton(onClick = { onRename(name) }) { Text(strings.dialogOk) } }, + dismissButton = { TextButton(onClick = onDismiss) { Text(strings.dialogCancel) } }, + ) + } + + is ProfileDialog.ConfirmDelete -> AlertDialog( + onDismissRequest = onDismiss, + title = { Text(strings.profilesDeleteTitle) }, + text = { + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + Text(strings.profilesDeleteBody(dialog.profile.displayName)) + Text(dialog.consequences) + } + }, + confirmButton = { TextButton(onClick = onDelete) { Text(strings.profilesDeleteConfirm) } }, + dismissButton = { TextButton(onClick = onDismiss) { Text(strings.dialogCancel) } }, + ) + + is ProfileDialog.WorkedData -> { + var shared by remember { mutableStateOf(dialog.shared) } + + AlertDialog( + onDismissRequest = onDismiss, + title = { Text(strings.profilesWorkedTitle) }, + text = { + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + Text(strings.profilesWorkedBody(dialog.profile.displayName)) + WorkedDataChoice(shared) { shared = it } + Text( + strings.profilesWorkedHint, + style = MaterialTheme.typography.bodySmall, + ) + } + }, + confirmButton = { TextButton(onClick = { onWorkedData(shared) }) { Text("Apply") } }, + dismissButton = { TextButton(onClick = onDismiss) { Text(strings.dialogCancel) } }, + ) + } + } +} + +/** The two mutually exclusive worked-stations options, as the radio buttons were. */ +@Composable +private fun WorkedDataChoice(shared: Boolean, onChange: (Boolean) -> Unit) { + Column { + CompositionLocalProvider(LocalMinimumInteractiveComponentSize provides Dp.Unspecified) { + Row(verticalAlignment = Alignment.CenterVertically) { + RadioButton( + selected = !shared, + onClick = { onChange(false) }, + modifier = Modifier.size(Density.CHECK_SIZE), + ) + Text( + "Own worked stations for this profile", + modifier = Modifier.padding(start = 6.dp), + ) + } + Row(verticalAlignment = Alignment.CenterVertically) { + RadioButton( + selected = shared, + onClick = { onChange(true) }, + modifier = Modifier.size(Density.CHECK_SIZE), + ) + Text( + "Share the common station worked stations (multi operator station)", + modifier = Modifier.padding(start = 6.dp), + ) + } + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ProfilesTabState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ProfilesTabState.kt new file mode 100644 index 00000000..6b68052d --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ProfilesTabState.kt @@ -0,0 +1,246 @@ +package kst4contest.view.compose.tabs + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import kst4contest.controller.OperatorProfileManagementService +import kst4contest.model.OperatorProfile +import kst4contest.model.OperatorProfileSelection +import java.time.Instant +import java.time.ZoneId +import java.time.format.DateTimeFormatter + +/** What the profile tab has to tell the operator after an action. */ +sealed interface ProfileNotice { + + val message: String + + /** Succeeded, but there is something the operator needs to know. */ + data class Info(override val message: String) : ProfileNotice + + /** Did not happen, and why. */ + data class Error(override val message: String) : ProfileNotice +} + +/** + * State of the profiles tab. + * + * Every rule of `OperatorProfileSettingsPane` lives here so it can be tested without + * a toolkit: the default profile cannot be deleted and always uses the common worked + * stations because that database belongs to the installation, the profile in use + * cannot be deleted, and switching to the profile already in use does nothing. + * + * @param activeSelection the profile in use; a function rather than a value because + * it changes under the tab when the operator switches profiles + * @param requestActivation hands the switch to the application, which restarts into + * the other profile — the tab must not do that itself + */ +class ProfilesTabState( + private val service: OperatorProfileManagementService, + private val activeSelection: () -> OperatorProfileSelection?, + private val requestActivation: (OperatorProfile) -> Unit, +) { + + /* + * Compose state, not plain properties. A LazyColumn row only redraws when + * something it observes changes; with plain properties the selection moved in the + * state and the list went on showing the old row highlighted. + */ + var profiles: List by mutableStateOf(emptyList()) + private set + + var selected: OperatorProfile? by mutableStateOf(null) + private set + + init { + refresh() + } + + val activeProfileName: String + get() = activeSelection()?.profile?.displayName ?: "unknown" + + val preferencesPath: String + get() = activeSelection()?.preferencesAbsolutePath ?: "" + + val workedDatabasePath: String + get() = activeSelection()?.workedDatabaseAbsolutePath ?: "" + + fun select(profile: OperatorProfile?) { + selected = profile?.takeIf { profiles.contains(it) } + } + + /** + * Re-reads the registry and keeps the selection when the selected profile is + * still there, as `refreshProfileTable` did. + */ + fun refresh() { + val known = service.listProfiles() + profiles = known + + selected = when { + selected != null && known.contains(selected) -> selected + known.isNotEmpty() -> known.first() + else -> null + } + } + + fun createProfile(name: String, sharedWorkedDatabase: Boolean): ProfileNotice? { + if (name.isBlank()) { + return null + } + + val created = service.createProfile(name.trim(), sharedWorkedDatabase) + ?: return ProfileNotice.Error( + "The profile could not be created. The profile registry could not be written." + ) + + refresh() + selected = created + + /* + * Said explicitly because a new profile that cannot log in looks broken + * otherwise: callsign and password are deliberately not copied or invented. + */ + return ProfileNotice.Info( + "The profile \"" + created.displayName + "\" was created without callsign and " + + "password. Enter them on the Station tab after switching to it." + ) + } + + fun duplicateSelected(name: String): ProfileNotice? { + val profile = selected ?: return notASelection() + + if (name.isBlank()) { + return null + } + + val duplicate = service.duplicateProfile(profile, name) + ?: return ProfileNotice.Error("The profile could not be duplicated.") + + refresh() + selected = duplicate + return null + } + + /** The suggested name of a duplicate, the one the JavaFX dialog pre-filled. */ + fun duplicateNameSuggestion(): String = + selected?.let { "Copy of " + it.displayName } ?: "" + + fun renameSelected(name: String): ProfileNotice? { + val profile = selected ?: return notASelection() + + if (name.isBlank()) { + return null + } + + service.renameProfile(profile, name) + refresh() + return null + } + + fun deleteSelected(): ProfileNotice? { + val profile = selected ?: return notASelection() + + if (profile.isRootProfile) { + return ProfileNotice.Error( + "The default profile uses the files of the installation itself and cannot be deleted." + ) + } + + if (isActive(profile)) { + return ProfileNotice.Error( + "The profile currently in use cannot be deleted. Switch to another profile first." + ) + } + + if (!service.deleteProfile(profile)) { + refresh() + return ProfileNotice.Error("The profile could not be deleted.") + } + + refresh() + return null + } + + /** The folder the deletion confirmation names, and what happens to worked stations. */ + fun describeDeletion(profile: OperatorProfile): String = + "The following folder is removed permanently:\n" + + service.getProfileDirectory(profile) + "\n\n" + + if (profile.isSharedWorkedDatabase) { + "The common station worked stations are not touched." + } else { + "The worked stations of this profile are deleted as well." + } + + fun changeWorkedDataModeOfSelected(sharedWorkedDatabase: Boolean): ProfileNotice? { + val profile = selected ?: return notASelection() + + if (profile.isRootProfile) { + return ProfileNotice.Error( + "The default profile always uses the common station worked stations, because " + + "that database is the one of the installation itself." + ) + } + + if (sharedWorkedDatabase == profile.isSharedWorkedDatabase) { + return null + } + + service.setSharedWorkedDatabase(profile, sharedWorkedDatabase) + refresh() + + if (isActive(profile)) { + return ProfileNotice.Info("The change takes effect after switching to this profile again.") + } + + return null + } + + fun activateSelected(): ProfileNotice? { + val profile = selected ?: return notASelection() + + if (isActive(profile)) { + return ProfileNotice.Info("This profile is already active.") + } + + requestActivation(profile) + return null + } + + /** Whether changing the worked-stations mode is possible at all for a profile. */ + fun canChangeWorkedDataMode(profile: OperatorProfile): Boolean = !profile.isRootProfile + + fun isActive(profile: OperatorProfile): Boolean { + val active = activeSelection() ?: return false + + return active.profile.profileId == profile.profileId + } + + private fun notASelection(): ProfileNotice = + ProfileNotice.Info("Select a profile in the table first.") + + companion object { + + private val LAST_USED_FORMATTER: DateTimeFormatter = + DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm").withZone(ZoneId.systemDefault()) + + /** + * The root profile always reads the installation's own database, whatever its + * stored flag says, which is why it is checked first here too. + */ + fun describeWorkedDataMode(profile: OperatorProfile): String = + if (profile.isRootProfile || profile.isSharedWorkedDatabase) { + "common station database" + } else { + "own database" + } + + /** Blank for a profile never used, rather than an epoch date. */ + fun describeLastUsed(profile: OperatorProfile): String = + if (profile.lastUsedEpochMs <= 0L) { + "" + } else { + LAST_USED_FORMATTER.format(Instant.ofEpochMilli(profile.lastUsedEpochMs)) + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ShortcutsTab.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ShortcutsTab.kt new file mode 100644 index 00000000..5f04cb15 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ShortcutsTab.kt @@ -0,0 +1,48 @@ +package kst4contest.view.compose.tabs + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import kst4contest.view.compose.DataTable +import kst4contest.view.compose.Form + +/** + * The shortcuts-and-snippets tab: the two editable lists. + * + * The move buttons are shown here because the JavaFX tab had them for both lists — + * the order decides the button order above the message field and which snippets get + * Ctrl+1 through Ctrl+0. + */ +@Composable +fun ShortcutsTab(state: ShortcutsTabState, onRefused: (String) -> Unit) { + val strings = LocalStrings.current + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + Form.section(strings.shortcutsButtonsSection) { + DataTable( + state = state.shortcuts, + addButtonText = strings.shortcutsAddButton, + newEntryTemplate = ShortcutsTabState.NEW_ENTRY_TEMPLATE, + onChanged = state::commitShortcuts, + onRefused = onRefused, + showMoveButtons = true, + ) + } + + Form.section(strings.shortcutsSnippetsSection) { + DataTable( + state = state.snippets, + addButtonText = strings.shortcutsAddSnippet, + newEntryTemplate = ShortcutsTabState.NEW_ENTRY_TEMPLATE, + onChanged = state::commitSnippets, + onRefused = onRefused, + showMoveButtons = true, + ) + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ShortcutsTabState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ShortcutsTabState.kt new file mode 100644 index 00000000..cc599984 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/ShortcutsTabState.kt @@ -0,0 +1,51 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatPreferences +import kst4contest.view.compose.EditableListState + +/** + * State of the shortcuts-and-snippets tab: the two single-column lists from + * `grdPnlShorts`. + * + * Both lists write through to their roster on every committed change. The JavaFX + * tables did the same — their Add buttons called `mutate` on the roster directly — + * and the shortcut buttons above the message field are rebuilt from the roster, so + * a list that only wrote on Save would leave those buttons stale. + * + * @param refreshShortcutButtons rebuilds the button row above the message field, + * as `refreshShortcutButtons` did after every edit commit and move. + * @param refreshTextSnippetContextMenus rebuilds the Ctrl+1..Ctrl+0 menus, the + * counterpart for the snippet list. + */ +class ShortcutsTabState( + private val prefs: ChatPreferences, + private val refreshShortcutButtons: () -> Unit, + private val refreshTextSnippetContextMenus: () -> Unit, +) { + + val shortcuts = EditableListState(prefs.getLst_txtShortCutBtnList().snapshot()) + + val snippets = EditableListState(prefs.getLst_txtSnipList().snapshot()) + + /** Fills the shortcut roster and rebuilds the buttons built from it. */ + fun commitShortcuts() { + shortcuts.commitTo(prefs.getLst_txtShortCutBtnList()) + refreshShortcutButtons() + } + + /** Fills the snippet roster and rebuilds the context menus built from it. */ + fun commitSnippets() { + snippets.commitTo(prefs.getLst_txtSnipList()) + refreshTextSnippetContextMenus() + } + + companion object { + /** + * The text the JavaFX Add buttons inserted, kept verbatim: it tells the + * operator both how to edit the entry and how to remove it again + * (Kst4ContestApplication:11743 and :11797, identical in both lists). + */ + const val NEW_ENTRY_TEMPLATE = + "CHANGE THIS TEXT VIA DOUBLECLICK or remove by deleting all text. Then hit enter key" + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/StationTab.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/StationTab.kt new file mode 100644 index 00000000..be45ae6c --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/StationTab.kt @@ -0,0 +1,106 @@ +package kst4contest.view.compose.tabs + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import kst4contest.view.compose.Form + +/** + * The Station tab: own station, server, active bands and path-analysis defaults. + * + * No confirmation callback: StationTabState writes through to ChatPreferences, the + * way the JavaFX controls did. "Save settings" persists, it does not collect. + */ +@Composable +fun StationTab(state: StationTabState) { + val strings = LocalStrings.current + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + /* + * These are the login credentials, so they are locked while the session is + * logged in: the running connection would not pick up a change. + */ + Form.section(strings.stationOwnSection) { + Form.text(strings.stationCallsign, state.stn_loginCallSign, state.loginFieldsEnabled) { + state.stn_loginCallSign = it + } + Form.text(strings.stationNameMain, state.stn_loginNameMainCat, state.loginFieldsEnabled) { + state.stn_loginNameMainCat = it + } + Form.text(strings.stationNameSecond, state.stn_loginNameSecondCat, state.loginFieldsEnabled) { + state.stn_loginNameSecondCat = it + } + Form.text(strings.stationLocator, state.stn_loginLocatorMainCat, state.loginFieldsEnabled) { + state.stn_loginLocatorMainCat = it + } + Form.password(strings.stationPassword, state.stn_loginPassword, state.loginFieldsEnabled) { + state.stn_loginPassword = it + } + } + + Form.section(strings.stationChatSection) { + Form.choice( + label = strings.stationMainCategory, + items = state.availableCategories, + selected = state.loginChatCategoryMain, + describe = state::describeCategory, + enabled = state.loginFieldsEnabled, + onSelect = state::selectMainCategory, + ) + Form.check(strings.stationSecondChatEnabled, state.loginToSecondChatEnabled) { + state.loginToSecondChatEnabled = it + } + Form.choice( + label = strings.stationSecondCategory, + items = state.secondCategoryOptions, + selected = state.loginChatCategorySecond, + describe = state::describeCategory, + enabled = state.loginFieldsEnabled, + onSelect = state::selectSecondCategory, + ) + } + + Form.section(strings.stationServerSection) { + Form.text(strings.stationServerHost, state.stn_on4kstServersDns) { state.stn_on4kstServersDns = it } + Form.int(strings.stationServerPort, state.stn_on4kstServersPort) { state.stn_on4kstServersPort = it } + } + + Form.flowingSection(strings.stationBandsSection) { + Form.check("50 MHz", state.stn_bandActive50) { state.stn_bandActive50 = it } + Form.check("70 MHz", state.stn_bandActive70) { state.stn_bandActive70 = it } + Form.check("144 MHz", state.stn_bandActive144) { state.stn_bandActive144 = it } + Form.check("432 MHz", state.stn_bandActive432) { state.stn_bandActive432 = it } + Form.check("1240 MHz", state.stn_bandActive1240) { state.stn_bandActive1240 = it } + Form.check("2300 MHz", state.stn_bandActive2300) { state.stn_bandActive2300 = it } + Form.check("3400 MHz", state.stn_bandActive3400) { state.stn_bandActive3400 = it } + Form.check("5600 MHz", state.stn_bandActive5600) { state.stn_bandActive5600 = it } + Form.check("10 GHz", state.stn_bandActive10G) { state.stn_bandActive10G = it } + } + + Form.section(strings.stationDefaultsSection) { + Form.decimal(strings.stationMaxQrb, state.stn_maxQRBDefault) { state.stn_maxQRBDefault = it } + Form.decimal(strings.stationQtf, state.stn_qtfDefault) { state.stn_qtfDefault = it } + Form.decimal(strings.stationBeamWidth, state.stn_antennaBeamWidthDeg) { state.stn_antennaBeamWidthDeg = it } + } + + Form.section(strings.stationRotatorSection) { + Form.check(strings.stationRotatorEnabled, state.stn_pstRotatorEnabled) { state.stn_pstRotatorEnabled = it } + Form.text(strings.stationRotatorHost, state.stn_pstRotatorHost) { state.stn_pstRotatorHost = it } + Form.int(strings.stationRotatorPort, state.stn_pstRotatorPort) { state.stn_pstRotatorPort = it } + } + + Form.section(strings.stationPathSection) { + Form.decimal(strings.stationOwnTxPower, state.stn_pathAnalysisOwnTxPowerWatts) { state.stn_pathAnalysisOwnTxPowerWatts = it } + Form.decimal(strings.stationOwnAntennaGain, state.stn_pathAnalysisOwnAntennaGainDbi) { state.stn_pathAnalysisOwnAntennaGainDbi = it } + Form.decimal(strings.stationOwnAntennaHeight, state.stn_pathAnalysisOwnAntennaHeightMeters) { state.stn_pathAnalysisOwnAntennaHeightMeters = it } + Form.decimal(strings.stationTargetTxPower, state.stn_pathAnalysisDefaultTargetTxPowerWatts) { state.stn_pathAnalysisDefaultTargetTxPowerWatts = it } + Form.decimal(strings.stationTargetAntennaGain, state.stn_pathAnalysisDefaultTargetAntennaGainDbi) { state.stn_pathAnalysisDefaultTargetAntennaGainDbi = it } + Form.text(strings.stationDemDirectory, state.stn_pathAnalysisDemRootDirectory) { state.stn_pathAnalysisDemRootDirectory = it } + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/StationTabState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/StationTabState.kt new file mode 100644 index 00000000..eedec553 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/StationTabState.kt @@ -0,0 +1,213 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatCategory +import kst4contest.model.ChatPreferences + +/** + * The Station tab as a typed facade over ChatPreferences. + * + * Every property writes through immediately, and there is deliberately no apply(). + * That mirrors the JavaFX window it replaces: its controls each wrote into + * ChatPreferences the moment they changed, and its two buttons only persisted + * ("Save settings" calls writePreferencesToXmlFile) or closed the window + * ("Apply/Close prefs" just hides it). Buffering edits until a confirmation would + * change behaviour an operator may rely on: today a changed setting takes effect + * in the running session at once, whether or not it is ever written to disk. + * + * The property list was derived mechanically from the setters the JavaFX tab + * called, intersected with the setters ChatPreferences declares. + */ +class StationTabState( + private val prefs: ChatPreferences, + /** + * Applies the chat category to the running session. Passed in rather than taken + * from a ChatController so the rules stay testable without building a controller, + * which would open a database. + */ + private val applyMainCategory: (ChatCategory?) -> Unit, + private val applySecondCategory: (ChatCategory?) -> Unit, +) { + + var loginChatCategoryMain: ChatCategory? + get() = prefs.getLoginChatCategoryMain() + set(value) { prefs.setLoginChatCategoryMain(value) } + + /** Null means "no second chat" — the JavaFX window wrote null for exactly that. */ + var loginChatCategorySecond: ChatCategory? + get() = prefs.getLoginChatCategorySecond() + set(value) { prefs.setLoginChatCategorySecond(value) } + + var stn_antennaBeamWidthDeg: Double + get() = prefs.getStn_antennaBeamWidthDeg() + set(value) { prefs.setStn_antennaBeamWidthDeg(value) } + + var stn_bandActive10G: Boolean + get() = prefs.isStn_bandActive10G() + set(value) { prefs.setStn_bandActive10G(value) } + + var stn_bandActive1240: Boolean + get() = prefs.isStn_bandActive1240() + set(value) { prefs.setStn_bandActive1240(value) } + + var stn_bandActive144: Boolean + get() = prefs.isStn_bandActive144() + set(value) { prefs.setStn_bandActive144(value) } + + var stn_bandActive2300: Boolean + get() = prefs.isStn_bandActive2300() + set(value) { prefs.setStn_bandActive2300(value) } + + var stn_bandActive3400: Boolean + get() = prefs.isStn_bandActive3400() + set(value) { prefs.setStn_bandActive3400(value) } + + var stn_bandActive432: Boolean + get() = prefs.isStn_bandActive432() + set(value) { prefs.setStn_bandActive432(value) } + + var stn_bandActive50: Boolean + get() = prefs.isStn_bandActive50() + set(value) { prefs.setStn_bandActive50(value) } + + var stn_bandActive5600: Boolean + get() = prefs.isStn_bandActive5600() + set(value) { prefs.setStn_bandActive5600(value) } + + var stn_bandActive70: Boolean + get() = prefs.isStn_bandActive70() + set(value) { prefs.setStn_bandActive70(value) } + + var stn_loginCallSign: String + get() = prefs.getStn_loginCallSign() + set(value) { prefs.setStn_loginCallSign(value) } + + var stn_loginLocatorMainCat: String + get() = prefs.getStn_loginLocatorMainCat() + set(value) { prefs.setStn_loginLocatorMainCat(value) } + + var stn_loginNameMainCat: String + get() = prefs.getStn_loginNameMainCat() + set(value) { prefs.setStn_loginNameMainCat(value) } + + var stn_loginNameSecondCat: String + get() = prefs.getStn_loginNameSecondCat() + set(value) { prefs.setStn_loginNameSecondCat(value) } + + var stn_loginPassword: String + get() = prefs.getStn_loginPassword() + set(value) { prefs.setStn_loginPassword(value) } + + var stn_maxQRBDefault: Double + get() = prefs.getStn_maxQRBDefault() + set(value) { prefs.setStn_maxQRBDefault(value) } + + var stn_on4kstServersDns: String + get() = prefs.getStn_on4kstServersDns() + set(value) { prefs.setStn_on4kstServersDns(value) } + + var stn_on4kstServersPort: Int + get() = prefs.getStn_on4kstServersPort() + set(value) { prefs.setStn_on4kstServersPort(value) } + + var stn_pathAnalysisDefaultTargetAntennaGainDbi: Double + get() = prefs.getStn_pathAnalysisDefaultTargetAntennaGainDbi() + set(value) { prefs.setStn_pathAnalysisDefaultTargetAntennaGainDbi(value) } + + var stn_pathAnalysisDefaultTargetTxPowerWatts: Double + get() = prefs.getStn_pathAnalysisDefaultTargetTxPowerWatts() + set(value) { prefs.setStn_pathAnalysisDefaultTargetTxPowerWatts(value) } + + var stn_pathAnalysisDemRootDirectory: String + get() = prefs.getStn_pathAnalysisDemRootDirectory() + set(value) { prefs.setStn_pathAnalysisDemRootDirectory(value) } + + var stn_pathAnalysisOwnAntennaGainDbi: Double + get() = prefs.getStn_pathAnalysisOwnAntennaGainDbi() + set(value) { prefs.setStn_pathAnalysisOwnAntennaGainDbi(value) } + + var stn_pathAnalysisOwnAntennaHeightMeters: Double + get() = prefs.getStn_pathAnalysisOwnAntennaHeightMeters() + set(value) { prefs.setStn_pathAnalysisOwnAntennaHeightMeters(value) } + + var stn_pathAnalysisOwnTxPowerWatts: Double + get() = prefs.getStn_pathAnalysisOwnTxPowerWatts() + set(value) { prefs.setStn_pathAnalysisOwnTxPowerWatts(value) } + + var stn_pstRotatorEnabled: Boolean + get() = prefs.isStn_pstRotatorEnabled() + set(value) { prefs.setStn_pstRotatorEnabled(value) } + + var stn_pstRotatorHost: String + get() = prefs.getStn_pstRotatorHost() + set(value) { prefs.setStn_pstRotatorHost(value) } + + var stn_pstRotatorPort: Int + get() = prefs.getStn_pstRotatorPort() + set(value) { prefs.setStn_pstRotatorPort(value) } + + var stn_qtfDefault: Double + get() = prefs.getStn_qtfDefault() + set(value) { prefs.setStn_qtfDefault(value) } + + /** + * The chat category is held twice: in ChatPreferences and in ChatController. + * The JavaFX window wrote both on every selection change, and the second write + * is invisible to the settings coverage test because ChatController is not + * ChatPreferences. Dropping it would leave the running session on the old + * category while the stored setting said otherwise. + */ + /** + * Whether the station logs into a second chat category as well. + * + * It lives on the Station tab because that is where the JavaFX checkbox stood + * (Kst4ContestApplication:9779, "2nd Chat:"), right next to the two category + * pickers it governs. It decides what the Connect button does, so it belongs with + * the login settings and not with the display options. + */ + var loginToSecondChatEnabled: Boolean + get() = prefs.isLoginToSecondChatEnabled() + set(value) { prefs.setLoginToSecondChatEnabled(value) } + + /** + * Whether the login fields may be edited. The JavaFX window disabled callsign, + * password, name, locator and both category pickers once the session was logged + * in: changing them there would not reach the running connection, so an edit + * would look applied and be ignored until the next login. + */ + var loginFieldsEnabled: Boolean = true + + /** + * The categories the operator can log into, built the way the JavaFX choice box + * was: one per entry of `getPossibleCategoryNumbers`, numbered from 1. + */ + val availableCategories: List by lazy { + val probe = ChatCategory(0) + + (1..probe.possibleCategoryNumbers.size).map { ChatCategory(it) } + } + + /** + * The categories offered for the second chat. The main category is left out — the + * JavaFX box did that too, and logging into the same chat twice is not a thing. + */ + val secondCategoryOptions: List + get() { + val mainNumber = loginChatCategoryMain?.categoryNumber + + return availableCategories.filter { it.categoryNumber != mainNumber } + } + + /** The label a category carries in the pickers. */ + fun describeCategory(category: ChatCategory): String = + category.getChatCategoryName(category.categoryNumber) + + fun selectMainCategory(category: ChatCategory?) { + loginChatCategoryMain = category + applyMainCategory(category) + } + + fun selectSecondCategory(category: ChatCategory?) { + loginChatCategorySecond = category + applySecondCategory(category) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/StylesheetExport.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/StylesheetExport.kt new file mode 100644 index 00000000..42a9ff23 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/StylesheetExport.kt @@ -0,0 +1,59 @@ +package kst4contest.view.compose.tabs + +import kst4contest.view.compose.JavaFxStylesheet +import java.io.File + +/** What writing the shipped stylesheet into the profile did. */ +sealed interface StylesheetExportOutcome { + + /** Written; the operator can now edit it by hand. */ + data class Written(val path: String) : StylesheetExportOutcome + + /** + * There was already a file, and it was left exactly as it was. + * + * The important case. That file is the operator's own work, and replacing it on a + * misclick is the one thing this button could do that cannot be undone from inside the + * application. + */ + data class AlreadyThere(val path: String) : StylesheetExportOutcome + + /** Nothing was written, and this is why. */ + data class Failed(val reason: String) : StylesheetExportOutcome +} + +/** + * Writes the shipped stylesheet of one design to a file, unless something is already there. + * + * The file is the middle of the three palette layers — the hand-editing route the copy in the + * application directory has been promising since it was first written and never read. Giving + * the operator the shipped sheet as a starting point is what makes that route usable: the + * roles live on three different selectors, which is not guessable. + * + * @param target where to write; its directory is created when missing + * @param darkMode true for the evening design, false for the daylight one + * @return what happened, never an exception + */ +fun exportShippedStylesheet(target: File, darkMode: Boolean): StylesheetExportOutcome { + + if (target.exists()) { + return StylesheetExportOutcome.AlreadyThere(target.path) + } + + val resource = + if (darkMode) JavaFxStylesheet.EVENING_RESOURCE else JavaFxStylesheet.DAYLIGHT_RESOURCE + + return runCatching { + target.parentFile?.mkdirs() + + val source = JavaFxStylesheet::class.java.getResource(resource) + ?: return StylesheetExportOutcome.Failed("$resource is not on the classpath") + + target.writeText(source.readText()) + StylesheetExportOutcome.Written(target.path) as StylesheetExportOutcome + }.getOrElse { failure -> + StylesheetExportOutcome.Failed( + failure.message ?: failure.javaClass.simpleName + ) + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/TrxSynchTab.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/TrxSynchTab.kt new file mode 100644 index 00000000..3e14847b --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/TrxSynchTab.kt @@ -0,0 +1,70 @@ +package kst4contest.view.compose.tabs + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.dp +import kst4contest.view.compose.Form + +/** + * The TRX synch tab: which source may update the own QRG. + * + * The hint below the sources is not filler. PROJECT_CONTEXT records that an automatic + * QRG update needs an enabled source *and* valid incoming RadioInfo or Win-Test STATUS + * data, so a checked box must not read as "my QRG is being kept current". + * + * No confirmation callback: TrxSynchTabState writes through to ChatPreferences, the way + * the JavaFX controls did. + */ +@Composable +fun TrxSynchTab(state: TrxSynchTabState) { + /* See LogSynchTab: the facade holds no snapshot state, so writes need a revision. */ + var revision by remember { mutableStateOf(0) } + val strings = LocalStrings.current + + + Column( + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + @Suppress("UNUSED_EXPRESSION") revision + + Form.section(strings.trxSynchUcxSection) { + Form.check( + strings.trxSynchUcxEnabled, + state.trxSynch_ucxLogUDPListenerEnabled, + ) { state.trxSynch_ucxLogUDPListenerEnabled = it; revision++ } + } + + Form.section(strings.trxSynchWinTestSection) { + Form.check( + strings.trxSynchWinTestEnabled, + state.logsynch_wintestQrgSyncEnabled, + ) { state.logsynch_wintestQrgSyncEnabled = it; revision++ } + + Form.check( + strings.trxSynchWinTestPassFrequency, + state.logsynch_wintestUsePassQrg, + ) { state.logsynch_wintestUsePassQrg = it; revision++ } + + GuardedTextField( + label = strings.trxSynchWinTestStationFilter, + value = state.logsynch_wintestNetworkStationNameOfWintestClient1, + onAccepted = { + state.logsynch_wintestNetworkStationNameOfWintestClient1 = it + revision++ + }, + ) + } + + Form.section(strings.trxSynchHintSection) { + Text(strings.trxSynchHint) + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/TrxSynchTabState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/TrxSynchTabState.kt new file mode 100644 index 00000000..e2c4034b --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/TrxSynchTabState.kt @@ -0,0 +1,78 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatPreferences + +/** + * The TRX synch tab as a typed facade over ChatPreferences. + * + * Every property writes through immediately and there is deliberately no apply(), the + * way the JavaFX controls behaved. + * + * The tab carries the two sources that may update the own QRG. Both live under the + * logsynch_ and trxSynch_ prefixes, but the JavaFX window put both controls on this + * pane — the Win-Test QRG controls were built next to the Log synch ones and then + * added to the TRX synch grid. + * + * Switching a source on is not itself a frequency: PROJECT_CONTEXT records that an + * automatic QRG update needs an enabled source *and* valid incoming RadioInfo or + * Win-Test STATUS data. [QRG_SOURCE_HINT_KEY] names the text the tab shows so an operator + * cannot read a checked box as "my QRG is being kept current". + * + * @param applyOwnQrgFollower attaches the own-QRG follower when any source is enabled + * and detaches it otherwise; maps to attachOwnQrgFollower()/detachOwnQrgFollower() + * plus the tooltip on the own-QRG field. Not a ChatPreferences setter, so no coverage + * test can see it, and passed in so the rules stay testable without a controller. + */ +class TrxSynchTabState( + private val prefs: ChatPreferences, + private val applyOwnQrgFollower: (Boolean) -> Unit, +) { + + var trxSynch_ucxLogUDPListenerEnabled: Boolean + get() = prefs.isTrxSynch_ucxLogUDPListenerEnabled() + set(value) { + prefs.setTrxSynch_ucxLogUDPListenerEnabled(value) + applyOwnQrgFollower(anyQrgSourceEnabled) + } + + var logsynch_wintestQrgSyncEnabled: Boolean + get() = prefs.isLogsynch_wintestQrgSyncEnabled() + set(value) { + prefs.setLogsynch_wintestQrgSyncEnabled(value) + applyOwnQrgFollower(anyQrgSourceEnabled) + } + + /** Use the Win-Test pass frequency from STATUS instead of the own QRG. */ + var logsynch_wintestUsePassQrg: Boolean + get() = prefs.isLogsynch_wintestUsePassQrg() + set(value) { prefs.setLogsynch_wintestUsePassQrg(value) } + + /** + * Win-Test station name filter. An empty filter accepts every station, which is + * why blank is a legal value here and is stored as the empty string, trimmed the + * way the JavaFX field committed it. + */ + var logsynch_wintestNetworkStationNameOfWintestClient1: String + get() = prefs.getLogsynch_wintestNetworkStationNameOfWintestClient1() + set(value) { prefs.setLogsynch_wintestNetworkStationNameOfWintestClient1(value.trim()) } + + /** + * True when at least one source may update the own QRG. One source switched off is + * not all of them off; the follower stays attached while the other is on. + */ + val anyQrgSourceEnabled: Boolean + get() = trxSynch_ucxLogUDPListenerEnabled || logsynch_wintestQrgSyncEnabled + + companion object { + /** + * Shown on the tab. Both halves are load-bearing: an enabled source without + * incoming data leaves the own QRG exactly as the operator typed it. + */ + /** + * The key of the text the tab shows. The text itself lives in the translation files; + * keeping a copy here would be two sentences that can drift apart, and the operator + * would read whichever one the tab happened to use. + */ + const val QRG_SOURCE_HINT_KEY: String = "trxSynch.hint" + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/WorkedDatabaseTab.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/WorkedDatabaseTab.kt new file mode 100644 index 00000000..c376126d --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/WorkedDatabaseTab.kt @@ -0,0 +1,150 @@ +package kst4contest.view.compose.tabs + +import kst4contest.view.i18n.LocalStrings +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.material3.AlertDialog +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.lazy.items +import androidx.compose.ui.text.font.FontWeight +import kst4contest.model.ChatMember +import androidx.compose.ui.Modifier +import androidx.compose.material3.Button +import androidx.compose.material3.Text +import androidx.compose.material3.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue +import androidx.compose.ui.unit.dp +import kst4contest.view.compose.Form + +/** + * The Workedstn database tab: refresh, and a confirmed reset of the contest flags. + * + * The warning text is the one the JavaFX dialog carried, including the note that a + * reset before every contest is normally unnecessary — these data expire on their own. + */ +@Composable +fun WorkedDatabaseTab(state: WorkedDatabaseTabState) { + val strings = LocalStrings.current + + var revision by remember { mutableStateOf(0) } + + Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { + @Suppress("UNUSED_EXPRESSION") revision + + Form.section(strings.workedSection) { + Text( + strings.workedExpiryHint + ) + Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) { + Form.button(strings.workedRefresh) { state.refresh(); revision++ } + Form.button(strings.workedReset) { + state.requestReset(); revision++ + } + } + state.lastAffectedLines?.let { Text(strings.workedLastResetAffected(it)) } + + WorkedStationsTable(state.workedStations, revision) + } + } + + if (state.confirmationPending) { + AlertDialog( + onDismissRequest = { state.cancelReset(); revision++ }, + title = { Text(strings.workedResetDialogTitle) }, + text = { + Text( + strings.workedResetDialogBody + ) + }, + confirmButton = { + TextButton(onClick = { state.confirmReset(); revision++ }) { Text(strings.workedResetConfirm) } + }, + dismissButton = { + TextButton(onClick = { state.cancelReset(); revision++ }) { Text(strings.dialogCancel) } + }, + ) + } + + if (state.resetFailed) { + AlertDialog( + onDismissRequest = { state.dismissError(); revision++ }, + title = { Text(strings.workedResetDialogTitle) }, + text = { + Text( + strings.workedResetFailed + ) + }, + confirmButton = { + TextButton(onClick = { state.dismissError(); revision++ }) { Text(strings.dialogOk) } + }, + ) + } +} + +/** + * The worked-stations table: one row per callsign in the database, a cross for any + * band worked and one column per band. + * + * Read-only, as the JavaFX table was. The band columns are those the JavaFX table had, + * in its order and under its labels — 23, 13, 9, 6 and 3 are centimetre labels for + * 1240, 2300, 3400, 5600 and 10 GHz, which is what a microwave operator reads. + */ +@Composable +private fun WorkedStationsTable(rows: List, revision: Int) { + val strings = LocalStrings.current + + @Suppress("UNUSED_EXPRESSION") revision + + val bands: List Boolean>> = listOf( + "wkd" to { m: ChatMember -> m.isWorked }, + "50" to { m: ChatMember -> m.isWorked50 }, + "70" to { m: ChatMember -> m.isWorked70 }, + "144" to { m: ChatMember -> m.isWorked144 }, + "432" to { m: ChatMember -> m.isWorked432 }, + "23" to { m: ChatMember -> m.isWorked1240 }, + "13" to { m: ChatMember -> m.isWorked2300 }, + "9" to { m: ChatMember -> m.isWorked3400 }, + "6" to { m: ChatMember -> m.isWorked5600 }, + "3" to { m: ChatMember -> m.isWorked10G }, + ) + + if (rows.isEmpty()) { + Text(strings.workedEmpty) + return + } + + Column(modifier = Modifier.fillMaxWidth()) { + Row(modifier = Modifier.fillMaxWidth().padding(vertical = 4.dp)) { + Text(strings.stationCallsign, fontWeight = FontWeight.Bold, modifier = Modifier.weight(2f)) + bands.forEach { (label, _) -> + Text(label, fontWeight = FontWeight.Bold, modifier = Modifier.weight(1f)) + } + } + + LazyColumn(modifier = Modifier.height(260.dp).fillMaxWidth()) { + /* + * Keyed by the raw callsign: the database holds one row per callsign, and a + * positional key would reshuffle every row when the list is re-read. + */ + items(rows, key = { it.callSignRaw ?: it.callSign ?: "" }) { member -> + Row(modifier = Modifier.fillMaxWidth().padding(vertical = 2.dp)) { + Text(member.callSign ?: "", modifier = Modifier.weight(2f)) + bands.forEach { (_, isWorked) -> + Text( + if (isWorked(member)) "X" else "", + modifier = Modifier.weight(1f), + ) + } + } + } + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/WorkedDatabaseTabState.kt b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/WorkedDatabaseTabState.kt new file mode 100644 index 00000000..34d849d9 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/compose/tabs/WorkedDatabaseTabState.kt @@ -0,0 +1,96 @@ +package kst4contest.view.compose.tabs + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import kst4contest.model.ChatMember +import kst4contest.observe.ObservableRoster + +/** + * The Workedstn database tab. It holds no settings at all — the JavaFX tab offered + * two actions, "Refresh worked database" and "Reset worked, NOT-QRV and grid data". + * + * Neither coverage net can see this tab: both check setter names, and an action is + * not a setter. That is why its behaviour is pinned by the tests around this class + * instead. + * + * The actions are passed in rather than taken from a ChatController so the order + * they run in stays testable without opening a database. + * + * @param resetInDatabase clears the flags and returns the affected row count, or a + * negative number when no successful reset could be confirmed + * @param refreshGuiLists drops the worked and NOT-QRV marks from the runtime lists + * @param refreshView re-reads the worked database for display + * @param workedRoster the callsigns read from the worked database; the JavaFX tab + * showed them in a table with one column per band, which is the only place the + * operator can see what the database actually holds + */ +class WorkedDatabaseTabState( + private val resetInDatabase: () -> Int, + private val refreshGuiLists: () -> Unit, + private val refreshView: () -> Unit, + private val workedRoster: ObservableRoster? = null, +) { + + /** + * The rows to show. A snapshot, taken when the tab is built and again on every + * refresh and reset, exactly as the JavaFX table behaved: it mirrored the roster + * and was told to redraw after each of those actions. + */ + var workedStations: List by mutableStateOf(workedRoster?.snapshot() ?: emptyList()) + private set + + private fun readRoster() { + workedStations = workedRoster?.snapshot() ?: emptyList() + } + + var confirmationPending: Boolean by mutableStateOf(false) + private set + + var resetFailed: Boolean by mutableStateOf(false) + private set + + var lastAffectedLines: Int? by mutableStateOf(null) + private set + + /** Opens the confirmation. Nothing is touched until [confirmReset]. */ + fun requestReset() { + confirmationPending = true + resetFailed = false + } + + fun cancelReset() { + confirmationPending = false + } + + /** + * Resets the database first and the runtime lists only afterwards. On failure the + * lists are left alone: clearing them would show the operator a state the database + * does not have. + */ + fun confirmReset() { + confirmationPending = false + val affected = resetInDatabase() + if (affected < 0) { + resetFailed = true + return + } + lastAffectedLines = affected + refreshGuiLists() + + /* + * The rows are re-read after a successful reset, or the table would keep + * showing entries the database no longer has. + */ + readRoster() + } + + fun dismissError() { + resetFailed = false + } + + fun refresh() { + refreshView() + readRoster() + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/feed/ConnectionStateFeed.kt b/app-desktop/src/main/kotlin/kst4contest/view/feed/ConnectionStateFeed.kt new file mode 100644 index 00000000..dfeb39dd --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/feed/ConnectionStateFeed.kt @@ -0,0 +1,32 @@ +package kst4contest.view.feed + +import kst4contest.controller.On4KstConnectionState +import kst4contest.observe.UiDispatcher +import kst4contest.view.compose.MainWindowSurroundings + +/** + * Fills the connection indicator in the Compose status bar. + * + * Separated from `updateConnectionStateIndicator()`, which wrote this state and then + * touched a JavaFX tooltip in the same method. The tooltip belongs to the window that + * is never shown; its live callers do not, and they must not be taken down with it. + * + * The substitutions are the JavaFX method's own: an absent state reads as DISCONNECTED + * and an absent detail as the state's name, because "null" in a status bar tells an + * operator nothing. + */ +class ConnectionStateFeed( + private val target: MainWindowSurroundings, + private val dispatcher: UiDispatcher, +) { + + fun push(state: On4KstConnectionState?, detail: String?) { + val effectiveState = state ?: On4KstConnectionState.DISCONNECTED + val effectiveDetail = if (detail.isNullOrBlank()) effectiveState.name else detail + + dispatcher.runOnUi { + target.connectionState = effectiveState + target.connectionDetail = effectiveDetail + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/feed/SelectedStationMessagesFeed.kt b/app-desktop/src/main/kotlin/kst4contest/view/feed/SelectedStationMessagesFeed.kt new file mode 100644 index 00000000..64cfb949 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/feed/SelectedStationMessagesFeed.kt @@ -0,0 +1,27 @@ +package kst4contest.view.feed + +import kst4contest.model.ChatMessage +import kst4contest.observe.UiDispatcher +import kst4contest.view.compose.DataTableState + +/** + * Fills the table of messages belonging to the selected station. + * + * Its own class for the reason it was nearly lost: the feed used to be a listener + * registered two hundred lines inside a JavaFX table builder, so a reader asking "who + * calls that builder" never discovered that deleting it would leave this table + * permanently empty — with a green build and no compile error. + * + * Copies what it is handed. The caller's list is the live mirror of a roster and keeps + * changing; a table holding a view of it would show rows that are no longer there. + */ +class SelectedStationMessagesFeed( + private val target: DataTableState, + private val dispatcher: UiDispatcher, +) { + + fun push(messages: List) { + val copy = messages.toList() + dispatcher.runOnUi { target.replaceRows(copy) } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/feed/TimelineFeed.kt b/app-desktop/src/main/kotlin/kst4contest/view/feed/TimelineFeed.kt new file mode 100644 index 00000000..0bb6ac8e --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/feed/TimelineFeed.kt @@ -0,0 +1,50 @@ +package kst4contest.view.feed + +import kst4contest.model.ContestSked +import kst4contest.observe.UiDispatcher +import kst4contest.view.compose.TimelineCandidate +import kst4contest.view.compose.TimelineState + +/** + * Fills the timeline above the send field. + * + * A class of its own because of how it was found. The feed used to sit inside + * `updateTimelineVisuals()`, behind a guard on a JavaFX field that the never-shown + * window construction created; deleting that construction would have emptied the + * Compose timeline without a compile error and with a green suite. A feed that can be + * constructed on its own cannot hide inside something else's lifetime. + * + * Knows nothing about JavaFX. Delivery goes through the [UiDispatcher] because the + * controller's listeners fire on network threads. + */ +class TimelineFeed( + private val target: TimelineState, + private val dispatcher: UiDispatcher, +) { + + /** + * Replaces everything the timeline shows, in one delivery. + * + * One delivery and not four: four would let the operator see a frame with new skeds + * against an old antenna heading. + * + * The lists are copied before they are handed over. The caller's are snapshots of + * roster state that keeps changing, and the timeline must not follow them. + */ + fun push( + skeds: List, + candidates: List, + antennaAzimuthDeg: Double, + beamWidthDeg: Double, + ) { + val skedsCopy = skeds.toList() + val candidatesCopy = candidates.toList() + + dispatcher.runOnUi { + target.replaceSkeds(skedsCopy) + target.replaceCandidates(candidatesCopy) + target.antennaAzimuth = antennaAzimuthDeg + target.setBeamWidth(beamWidthDeg) + } + } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/i18n/LanguageStore.kt b/app-desktop/src/main/kotlin/kst4contest/view/i18n/LanguageStore.kt new file mode 100644 index 00000000..cc4a753b --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/i18n/LanguageStore.kt @@ -0,0 +1,128 @@ +package kst4contest.view.i18n + +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.setValue +import androidx.compose.runtime.staticCompositionLocalOf +import java.util.Locale + +/** + * The language in force, held as Compose state. + * + * **This is what makes a language change reach every open window** -- the same arrangement the + * palette uses, and for the same reason: in Etappe 8 a remembered value meant a change + * reached nothing until something else happened to recompose. + * + * Two ways out, one truth: [strings] for Compose, which recomposes on the state read, and + * [CurrentStrings] for the Java call sites, which pick the new language up on their next call + * without needing any machinery of their own. + * + * @param storedLanguage the preference, possibly empty for "follow the system" + * @param storeLanguage writes the preference back + * @param systemDefault injected so tests need not touch the JVM's global default + */ +class LanguageStore( + storedLanguage: () -> String?, + private val storeLanguage: (String) -> Unit, + private val systemDefault: Locale = Locale.getDefault(), +) { + + private var chosen by mutableStateOf(storedLanguage().orEmpty()) + private var current by mutableStateOf(languageFor(storedLanguage(), systemDefault)) + + init { + CurrentStrings.set(stringsFor(current)) + } + + /** The language code in force, after the system default and the fallback are applied. */ + val language: String get() = current + + /** + * What the operator actually chose, which is what the picker shows. + * + * Not the same as [language]: [SYSTEM_LANGUAGE] stays itself here and resolves there. The + * picker has to show "system language" and not the code it happens to mean today, and + * having both on the store means a caller never has to decide whether to ask the store or + * the preference -- which is two sources of truth for one value. + */ + val stored: String get() = chosen + + /** + * The texts in force. + * + * Reads the state, so a composable calling this recomposes when the language changes. + * That state read is the whole mechanism and must not be cached. + */ + val strings: Strings get() = stringsFor(current) + + /** + * Switches the language. + * + * A language this build has no texts for is refused rather than stored: persisting a dead + * setting would leave the operator with English and no way to see why. + * + * [SYSTEM_LANGUAGE] is stored as itself and not as the code it resolves to, so an + * operator who later changes their system is still followed. + * + * @param language a language code, or [SYSTEM_LANGUAGE] + */ + fun use(language: String) { + val asked = language.trim().lowercase(Locale.ROOT) + val resolved = languageFor(language, systemDefault) + + if (asked != SYSTEM_LANGUAGE && resolved != asked) { + return + } + + current = resolved + chosen = language + storeLanguage(language) + CurrentStrings.set(stringsFor(resolved)) + } + + private fun stringsFor(language: String): Strings { + val texts = Translations.BY_LANGUAGE[language].orEmpty() + val base = Translations.BY_LANGUAGE.getValue(Translations.BASE_LANGUAGE) + + /* + * Chosen first, base second. A key the translation leaves out falls through, which is + * what lets a partial contributed language ship at all. + */ + return Strings { key -> texts[key] ?: base[key] ?: key } + } +} + +/** + * The texts the Java call sites read. + * + * A volatile field rather than a parameter on a few hundred signatures: those call sites are + * AWT dialogs and menu builders that run once per interaction, so reading the current value + * on the next call is both correct and all they need. + */ +object CurrentStrings { + + @Volatile + private var strings: Strings = baseStrings() + + /** The texts in force. */ + @JvmStatic + fun get(): Strings = strings + + internal fun set(value: Strings) { + strings = value + } +} + +/** + * The texts for the windows below. + * + * The default is the base language rather than null: a window composed before a profile + * exists -- the operator profile picker -- still has to be able to draw. + */ +val LocalStrings = staticCompositionLocalOf { baseStrings() } + +/** The base language's texts, with the key itself for anything the base somehow lacks. */ +private fun baseStrings(): Strings { + val base = Translations.BY_LANGUAGE.getValue(Translations.BASE_LANGUAGE) + return Strings { key -> base[key] ?: key } +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/i18n/LanguageStoreFactory.kt b/app-desktop/src/main/kotlin/kst4contest/view/i18n/LanguageStoreFactory.kt new file mode 100644 index 00000000..0c548714 --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/i18n/LanguageStoreFactory.kt @@ -0,0 +1,37 @@ +package kst4contest.view.i18n + +import kst4contest.model.ChatPreferences +import java.util.Locale + +/** + * Builds the [LanguageStore] of the active profile. + * + * The store itself takes lambdas so it can be tested without a profile on disk; this is where + * they are tied to the real preferences. It exists for the same reason `PaletteStoreFactory` + * does: a Kotlin `(String) -> Unit` is not a void lambda seen from Java, so assembling them + * here keeps the Java call one line and the lambda types out of it. + */ +object LanguageStoreFactory { + + /** + * Creates the store for one profile. + * + * The language is written through to [prefs] at once, which is what switches the open + * windows. The XML is written by the existing "save settings" path, exactly like every + * other setting. + * + * @param prefs the active profile's preferences + * @param systemDefault the system locale, used when the preference is empty + * @return a store for the interface language + */ + @JvmStatic + @JvmOverloads + fun create( + prefs: ChatPreferences, + systemDefault: Locale = Locale.getDefault(), + ): LanguageStore = LanguageStore( + storedLanguage = { prefs.guiOptions_language }, + storeLanguage = { language -> prefs.guiOptions_language = language }, + systemDefault = systemDefault, + ) +} diff --git a/app-desktop/src/main/kotlin/kst4contest/view/i18n/LocaleChoice.kt b/app-desktop/src/main/kotlin/kst4contest/view/i18n/LocaleChoice.kt new file mode 100644 index 00000000..f7f28aef --- /dev/null +++ b/app-desktop/src/main/kotlin/kst4contest/view/i18n/LocaleChoice.kt @@ -0,0 +1,33 @@ +package kst4contest.view.i18n + +import java.util.Locale + +/** The stored value that means "whatever the system is set to". */ +const val SYSTEM_LANGUAGE: String = "" + +/** + * The language to use. + * + * An explicit setting wins; an empty one follows the system; anything this build has no texts + * for falls back to the base language. A pure function so it can be tested without touching + * the JVM's default locale, which is global state and leaks into whatever runs next. + * + * @param stored the value from the preferences, possibly hand-edited or from another build + * @param systemDefault usually `Locale.getDefault()` + * @return a language code [Translations.BY_LANGUAGE] has an entry for + */ +fun languageFor(stored: String?, systemDefault: Locale): String { + val wanted = stored?.trim()?.lowercase(Locale.ROOT).orEmpty() + + val candidate = if (wanted == SYSTEM_LANGUAGE) { + systemDefault.language.lowercase(Locale.ROOT) + } else { + wanted + } + + return if (Translations.BY_LANGUAGE.containsKey(candidate)) { + candidate + } else { + Translations.BASE_LANGUAGE + } +} diff --git a/src/main/resources/KST4ContestDefaultDay.css b/app-desktop/src/main/resources/KST4ContestDefaultDay.css similarity index 97% rename from src/main/resources/KST4ContestDefaultDay.css rename to app-desktop/src/main/resources/KST4ContestDefaultDay.css index cbe2ba01..1b277b0b 100644 --- a/src/main/resources/KST4ContestDefaultDay.css +++ b/app-desktop/src/main/resources/KST4ContestDefaultDay.css @@ -1,3 +1,8 @@ +.root { + /* Same base font size on all platforms: macOS/Linux default to 13px, Windows to 12px. */ + -fx-font-size: 12px; +} + .button:pressed { -fx-border-color: #ff0000; } diff --git a/src/main/resources/KST4ContestDefaultEvening.css b/app-desktop/src/main/resources/KST4ContestDefaultEvening.css similarity index 98% rename from src/main/resources/KST4ContestDefaultEvening.css rename to app-desktop/src/main/resources/KST4ContestDefaultEvening.css index 14419f6d..460151e6 100644 --- a/src/main/resources/KST4ContestDefaultEvening.css +++ b/app-desktop/src/main/resources/KST4ContestDefaultEvening.css @@ -1,4 +1,6 @@ .root { + /* Same base font size on all platforms: macOS/Linux default to 13px, Windows to 12px. */ + -fx-font-size: 12px; -fx-accent: #1e74c6; -fx-focus-color: -fx-accent; -fx-base: #373e43; diff --git a/src/main/java/kst4contest/test/MessageVariableResolverTest.java b/app-desktop/src/test/java/kst4contest/test/MessageVariableResolverTest.java similarity index 90% rename from src/main/java/kst4contest/test/MessageVariableResolverTest.java rename to app-desktop/src/test/java/kst4contest/test/MessageVariableResolverTest.java index 92442ed7..62bf66d4 100644 --- a/src/main/java/kst4contest/test/MessageVariableResolverTest.java +++ b/app-desktop/src/test/java/kst4contest/test/MessageVariableResolverTest.java @@ -7,9 +7,7 @@ import static org.mockito.Mockito.when; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import javafx.beans.property.SimpleDoubleProperty; -import javafx.beans.property.SimpleStringProperty; -import javafx.collections.FXCollections; +import kst4contest.observe.SimpleValue; import kst4contest.controller.MessageVariableResolver; import kst4contest.model.AirPlane; import kst4contest.model.AirPlaneReflectionInfo; @@ -25,11 +23,11 @@ class MessageVariableResolverTest { void setUp() { chatPreferences = mock(ChatPreferences.class); - when(chatPreferences.getMYQRGFirstCat()).thenReturn(new SimpleStringProperty("144.388.03")); - when(chatPreferences.getMYQRGSecondCat()).thenReturn(new SimpleStringProperty("432.088.00")); + when(chatPreferences.getMYQRGFirstCat()).thenReturn(new SimpleValue<>("144.388.03")); + when(chatPreferences.getMYQRGSecondCat()).thenReturn(new SimpleValue<>("432.088.00")); when(chatPreferences.getStn_loginLocatorMainCat()).thenReturn("JO51IJ"); when(chatPreferences.getStn_loginCallSign()).thenReturn("DO5AMF"); - when(chatPreferences.getActualQTF()).thenReturn(new SimpleDoubleProperty(135.0)); + when(chatPreferences.getActualQTF()).thenReturn(new SimpleValue<>(135.0)); resolver = new MessageVariableResolver(chatPreferences); } @@ -46,7 +44,7 @@ class MessageVariableResolverTest { @Test void shortValuesRemainSafeWhenTheConfiguredValueIsShorterThanExpected() { - when(chatPreferences.getMYQRGFirstCat()).thenReturn(new SimpleStringProperty("144")); + when(chatPreferences.getMYQRGFirstCat()).thenReturn(new SimpleValue<>("144")); when(chatPreferences.getStn_loginLocatorMainCat()).thenReturn("JO5"); assertEquals("144 JO5", resolver.resolveGlobalVariables("MYQRGSHORT MYLOCATORSHORT")); @@ -67,7 +65,7 @@ class MessageVariableResolverTest { secondAirPlane.setArrivingDurationMinutes(9); AirPlaneReflectionInfo reflectionInfo = new AirPlaneReflectionInfo(); - reflectionInfo.setRisingAirplanes(FXCollections.observableArrayList(firstAirPlane, secondAirPlane)); + reflectionInfo.setRisingAirplanes(java.util.List.of(firstAirPlane, secondAirPlane)); selectedStation.setAirPlaneReflectInfo(reflectionInfo); assertEquals( diff --git a/src/test/java/kst4contest/test/PrivateMessageRowStyleResolverTest.java b/app-desktop/src/test/java/kst4contest/test/PrivateMessageRowStyleResolverTest.java similarity index 100% rename from src/test/java/kst4contest/test/PrivateMessageRowStyleResolverTest.java rename to app-desktop/src/test/java/kst4contest/test/PrivateMessageRowStyleResolverTest.java diff --git a/app-desktop/src/test/java/kst4contest/view/AwtUiDispatcherTest.java b/app-desktop/src/test/java/kst4contest/view/AwtUiDispatcherTest.java new file mode 100644 index 00000000..3dbd9d15 --- /dev/null +++ b/app-desktop/src/test/java/kst4contest/view/AwtUiDispatcherTest.java @@ -0,0 +1,90 @@ +package kst4contest.view; + +import org.junit.jupiter.api.Test; + +import java.awt.EventQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * The contract the user interface depends on everywhere. + * + *

{@code core} hands over every user-interface change through this interface, so a + * mistake here does not show up as a compile error but as an occasionally stale window. + * The four rules below are what the specification names for this stage.

+ */ +class AwtUiDispatcherTest { + + private final AwtUiDispatcher dispatcher = new AwtUiDispatcher(); + + @Test + void deliversWorkFromAForeignThreadToTheEventThread() throws Exception { + AtomicBoolean ranOnEventThread = new AtomicBoolean(); + CountDownLatch done = new CountDownLatch(1); + + dispatcher.runOnUi(() -> { + ranOnEventThread.set(EventQueue.isDispatchThread()); + done.countDown(); + }); + + assertTrue(done.await(5, TimeUnit.SECONDS), "the task was never delivered"); + assertTrue(ranOnEventThread.get(), "the task must run on the AWT event thread"); + } + + @Test + void runsInlineWhenAlreadyOnTheEventThread() throws Exception { + AtomicInteger runs = new AtomicInteger(); + + EventQueue.invokeAndWait(() -> { + dispatcher.runOnUi(runs::incrementAndGet); + // Inline means: already done when runOnUi returns, not queued behind us. + assertEquals(1, runs.get(), "a task handed over on the UI thread must run at once"); + }); + + assertEquals(1, runs.get()); + } + + @Test + void reportsTheEventThreadAndOnlyThat() throws Exception { + assertFalse(dispatcher.isUiThread(), "a test thread is not the UI thread"); + + AtomicBoolean onEventThread = new AtomicBoolean(); + EventQueue.invokeAndWait(() -> onEventThread.set(dispatcher.isUiThread())); + + assertTrue(onEventThread.get(), "the AWT event thread must report itself as the UI thread"); + } + + @Test + void aFailingTaskNeitherReachesTheCallerNorKillsTheEventThread() throws Exception { + dispatcher.runOnUi(() -> { + throw new IllegalStateException("boom"); + }); + + CountDownLatch stillAlive = new CountDownLatch(1); + dispatcher.runOnUi(stillAlive::countDown); + + assertTrue(stillAlive.await(5, TimeUnit.SECONDS), + "the event thread must survive a failing UI task"); + } + + @Test + void aFailingTaskHandedOverOnTheEventThreadDoesNotReachTheCaller() throws Exception { + AtomicBoolean reachedTheLineAfter = new AtomicBoolean(); + + EventQueue.invokeAndWait(() -> { + dispatcher.runOnUi(() -> { + throw new IllegalStateException("boom"); + }); + reachedTheLineAfter.set(true); + }); + + assertTrue(reachedTheLineAfter.get(), + "an inline failure must not propagate into the caller"); + } +} diff --git a/app-desktop/src/test/java/kst4contest/view/CoalescingTriggerTest.java b/app-desktop/src/test/java/kst4contest/view/CoalescingTriggerTest.java new file mode 100644 index 00000000..c5e22606 --- /dev/null +++ b/app-desktop/src/test/java/kst4contest/view/CoalescingTriggerTest.java @@ -0,0 +1,101 @@ +package kst4contest.view; + +import org.junit.jupiter.api.Test; + +import java.awt.EventQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * The coalescer behind the station list. + * + *

Untested while it ran on a JavaFX {@code PauseTransition}, and both ways of being + * wrong are invisible in a build: too eager and the table redraws on every message under + * contest load, never and the table stops updating altogether.

+ */ +class CoalescingTriggerTest { + + @Test + void aBurstOfTriggersProducesOneRun() throws Exception { + AtomicInteger runs = new AtomicInteger(); + CountDownLatch ran = new CountDownLatch(1); + CoalescingTrigger trigger = new CoalescingTrigger(120, () -> { + runs.incrementAndGet(); + ran.countDown(); + }); + + // What a busy chat looks like: many updates, one intended redraw. + for (int i = 0; i < 25; i++) { + trigger.trigger(); + } + + assertTrue(ran.await(5, TimeUnit.SECONDS), "the burst never produced a run"); + Thread.sleep(300); + assertEquals(1, runs.get(), "a burst must coalesce into a single run"); + } + + @Test + void theActionRunsOnTheEventThread() throws Exception { + AtomicBoolean onEventThread = new AtomicBoolean(); + CountDownLatch ran = new CountDownLatch(1); + CoalescingTrigger trigger = new CoalescingTrigger(60, () -> { + onEventThread.set(EventQueue.isDispatchThread()); + ran.countDown(); + }); + + trigger.trigger(); + + assertTrue(ran.await(5, TimeUnit.SECONDS)); + assertTrue(onEventThread.get(), "the action redraws tables and must be on the UI thread"); + } + + @Test + void aLaterTriggerPostponesTheRun() throws Exception { + AtomicInteger runs = new AtomicInteger(); + CoalescingTrigger trigger = new CoalescingTrigger(250, runs::incrementAndGet); + + trigger.trigger(); + Thread.sleep(150); + trigger.trigger(); + Thread.sleep(150); + + // 300 ms have passed, but the second trigger restarted the wait at 150 ms. + assertEquals(0, runs.get(), + "a new trigger must restart the delay, not let the old one fire"); + } + + @Test + void cancellingBeforeTheDelayElapsesSuppressesTheRun() throws Exception { + AtomicInteger runs = new AtomicInteger(); + CoalescingTrigger trigger = new CoalescingTrigger(120, runs::incrementAndGet); + + trigger.trigger(); + trigger.cancel(); + Thread.sleep(400); + + assertEquals(0, runs.get(), "a cancelled trigger must not run; shutdown relies on it"); + } + + @Test + void triggeringAgainAfterACancelStillWorks() throws Exception { + AtomicInteger runs = new AtomicInteger(); + CountDownLatch ran = new CountDownLatch(1); + CoalescingTrigger trigger = new CoalescingTrigger(80, () -> { + runs.incrementAndGet(); + ran.countDown(); + }); + + trigger.trigger(); + trigger.cancel(); + trigger.trigger(); + + assertTrue(ran.await(5, TimeUnit.SECONDS), + "a cancel must not disable the trigger for good"); + assertEquals(1, runs.get()); + } +} diff --git a/app-desktop/src/test/java/kst4contest/view/CommandLineOptionsTest.java b/app-desktop/src/test/java/kst4contest/view/CommandLineOptionsTest.java new file mode 100644 index 00000000..e9256c02 --- /dev/null +++ b/app-desktop/src/test/java/kst4contest/view/CommandLineOptionsTest.java @@ -0,0 +1,46 @@ +package kst4contest.view; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; + +class CommandLineOptionsTest { + + @Test + void profileArgumentIsAcceptedInBothSpellings() { + assertEquals("OP2", CommandLineOptions.parse(List.of("--profile=OP2")).getRequestedProfileName()); + assertEquals("OP2", CommandLineOptions.parse(List.of("--profile", "OP2")).getRequestedProfileName()); + assertEquals("DM5M Contest", + CommandLineOptions.parse(List.of("--profile", "DM5M Contest")).getRequestedProfileName()); + } + + @Test + void missingOrEmptyProfileArgumentsAreTreatedAsAbsent() { + assertNull(CommandLineOptions.parse(List.of()).getRequestedProfileName()); + assertNull(CommandLineOptions.parse(null).getRequestedProfileName()); + assertNull(CommandLineOptions.parse(List.of("--profile=")).getRequestedProfileName()); + assertNull(CommandLineOptions.parse(List.of("--profile")).getRequestedProfileName()); + } + + @Test + void unrelatedArgumentsAreIgnoredInsteadOfFailing() { + assertEquals("OP2", + CommandLineOptions.parse(List.of("--verbose", "--profile=OP2", "somefile.adi")) + .getRequestedProfileName()); + assertNull(CommandLineOptions.parse(List.of("--verbose", "-x")).getRequestedProfileName()); + } + + @Test + void rememberedOptionsDefaultToEmptyInsteadOfNull() { + CommandLineOptions.remember(null); + assertNull(CommandLineOptions.remembered().getRequestedProfileName()); + + CommandLineOptions.remember(new CommandLineOptions("OP2")); + assertEquals("OP2", CommandLineOptions.remembered().getRequestedProfileName()); + + CommandLineOptions.remember(null); + } +} diff --git a/app-desktop/src/test/java/kst4contest/view/ComposeMainWindowOptionTest.java b/app-desktop/src/test/java/kst4contest/view/ComposeMainWindowOptionTest.java new file mode 100644 index 00000000..8b566e5c --- /dev/null +++ b/app-desktop/src/test/java/kst4contest/view/ComposeMainWindowOptionTest.java @@ -0,0 +1,52 @@ +package kst4contest.view; + +import org.junit.jupiter.api.Test; + +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * The switch that opens the Compose main window beside the JavaFX one. + * + *

Off unless asked for. The two windows are meant to run side by side while the operator + * compares them against a live session, and until that comparison is done nothing about an + * ordinary start may change.

+ */ +class ComposeMainWindowOptionTest { + + @Test + void anOrdinaryStartDoesNotOpenTheComposeWindow() { + assertFalse(CommandLineOptions.parse(List.of()).isComposeMainWindowRequested()); + assertFalse(CommandLineOptions.parse(null).isComposeMainWindowRequested()); + assertFalse( + CommandLineOptions.parse(List.of("--profile", "contest")) + .isComposeMainWindowRequested()); + } + + @Test + void theSwitchOpensIt() { + assertTrue( + CommandLineOptions.parse(List.of("--compose-main-window")) + .isComposeMainWindowRequested()); + } + + /** Alongside a profile, because the comparison is run inside one. */ + @Test + void theSwitchCombinesWithAProfile() { + CommandLineOptions options = + CommandLineOptions.parse(List.of("--profile", "contest", "--compose-main-window")); + + assertTrue(options.isComposeMainWindowRequested()); + assertTrue("contest".equals(options.getRequestedProfileName())); + } + + /** A near miss must not switch it on by accident. */ + @Test + void anUnrelatedArgumentIsNotTheSwitch() { + assertFalse( + CommandLineOptions.parse(List.of("--compose-main-window-please")) + .isComposeMainWindowRequested()); + } +} diff --git a/app-desktop/src/test/java/kst4contest/view/ExternalDocumentsTest.java b/app-desktop/src/test/java/kst4contest/view/ExternalDocumentsTest.java new file mode 100644 index 00000000..2de7e3bc --- /dev/null +++ b/app-desktop/src/test/java/kst4contest/view/ExternalDocumentsTest.java @@ -0,0 +1,44 @@ +package kst4contest.view; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * The one decision AWT forces that JavaFX did not. + * + *

{@code HostServices.showDocument} took web and mail addresses alike. + * {@code Desktop.browse("mailto:...")} silently opens nothing on Linux, so the scheme has + * to be read before the call is chosen.

+ */ +class ExternalDocumentsTest { + + @Test + void aMailtoAddressGoesToTheMailClient() { + assertTrue(ExternalDocuments.isMailAddress("mailto:praktimarc+kst4contest@gmail.com")); + } + + @Test + void theSchemeIsReadWithoutRegardToCase() { + assertTrue(ExternalDocuments.isMailAddress("MAILTO:someone@example.org")); + } + + @Test + void webAddressesGoToTheBrowser() { + assertFalse(ExternalDocuments.isMailAddress("https://ko-fi.com/praktimarc")); + assertFalse(ExternalDocuments.isMailAddress("http://www.x08.de")); + } + + @Test + void anAddressThatMentionsMailtoLaterIsStillAWebAddress() { + // Would be a mail client launch for a perfectly ordinary link otherwise. + assertFalse(ExternalDocuments.isMailAddress("https://example.org/?to=mailto:x@y.z")); + } + + @Test + void nothingIsNotAMailAddress() { + assertFalse(ExternalDocuments.isMailAddress(null)); + assertFalse(ExternalDocuments.isMailAddress(" ")); + } +} diff --git a/app-desktop/src/test/java/kst4contest/view/LayoutAutosaveTest.java b/app-desktop/src/test/java/kst4contest/view/LayoutAutosaveTest.java new file mode 100644 index 00000000..871fed11 --- /dev/null +++ b/app-desktop/src/test/java/kst4contest/view/LayoutAutosaveTest.java @@ -0,0 +1,83 @@ +package kst4contest.view; + +import kst4contest.observe.UiDispatcher; +import org.junit.jupiter.api.Test; + +import java.awt.EventQueue; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * The debounce behind the column widths. + * + *

Untested while it ran on a JavaFX {@code PauseTransition}, and the failure mode is + * silent: a timer that never fires means the operator's column widths are simply not + * saved, with nothing to see until the next start.

+ */ +class LayoutAutosaveTest { + + private final UiDispatcher dispatcher = new AwtUiDispatcher(); + + @Test + void aRequestFromAForeignThreadEventuallyWrites() throws Exception { + CountDownLatch written = new CountDownLatch(1); + LayoutAutosave autosave = new LayoutAutosave(written::countDown, dispatcher); + + autosave.requestSave(); + + assertTrue(written.await(5, TimeUnit.SECONDS), + "a save requested off the user-interface thread must still happen"); + } + + @Test + void burstsOfRequestsCollapseIntoOneWrite() throws Exception { + AtomicInteger writes = new AtomicInteger(); + CountDownLatch written = new CountDownLatch(1); + LayoutAutosave autosave = new LayoutAutosave(() -> { + writes.incrementAndGet(); + written.countDown(); + }, dispatcher); + + // What dragging a column divider looks like: many events, one intended save. + for (int i = 0; i < 20; i++) { + autosave.requestSave(); + } + + assertTrue(written.await(5, TimeUnit.SECONDS), "the burst never produced a write"); + Thread.sleep(300); + assertEquals(1, writes.get(), "a burst must collapse into a single write"); + } + + @Test + void cancellingBeforeTheDelayElapsesSuppressesTheWrite() throws Exception { + AtomicInteger writes = new AtomicInteger(); + LayoutAutosave autosave = new LayoutAutosave(writes::incrementAndGet, dispatcher); + + EventQueue.invokeAndWait(() -> { + autosave.requestSave(); + autosave.cancelPending(); + }); + + Thread.sleep(1_200); + assertEquals(0, writes.get(), "a cancelled save must not be written"); + } + + @Test + void flushingWritesAtOnceAndOnlyOnce() throws Exception { + AtomicInteger writes = new AtomicInteger(); + LayoutAutosave autosave = new LayoutAutosave(writes::incrementAndGet, dispatcher); + + EventQueue.invokeAndWait(() -> { + autosave.requestSave(); + autosave.flushPending(); + // A second flush has nothing left to write; shutdownRuntime calls flush then cancel. + autosave.flushPending(); + }); + + assertEquals(1, writes.get(), "flushing a pending save must write exactly once"); + } +} diff --git a/app-desktop/src/test/java/kst4contest/view/MacOsConnectionStateMenuTitleTest.java b/app-desktop/src/test/java/kst4contest/view/MacOsConnectionStateMenuTitleTest.java new file mode 100644 index 00000000..04d531d7 --- /dev/null +++ b/app-desktop/src/test/java/kst4contest/view/MacOsConnectionStateMenuTitleTest.java @@ -0,0 +1,34 @@ +package kst4contest.view; + +import kst4contest.controller.On4KstConnectionState; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +class MacOsConnectionStateMenuTitleTest { + + @Test + void everyStateHasTheAgreedTitle() { + assertEquals("🟢 LINK: Connected", + Kst4ContestApplication.macOsConnectionStateMenuTitle(On4KstConnectionState.ONLINE)); + for (On4KstConnectionState state : new On4KstConnectionState[]{ + On4KstConnectionState.CONNECTING, + On4KstConnectionState.WAITING_FOR_LOGIN_PROMPT, + On4KstConnectionState.AUTHENTICATING, + On4KstConnectionState.SYNCING_MAIN_CHAT, + On4KstConnectionState.SYNCING_SECOND_CHAT}) { + assertEquals("🟡 LINK: Connecting…", Kst4ContestApplication.macOsConnectionStateMenuTitle(state)); + } + assertEquals("🟡 LINK: Disconnecting…", + Kst4ContestApplication.macOsConnectionStateMenuTitle(On4KstConnectionState.STOPPING)); + assertEquals("🔴 LINK: Reconnecting…", + Kst4ContestApplication.macOsConnectionStateMenuTitle(On4KstConnectionState.RECONNECT_WAIT)); + assertEquals("🔴 LINK: Disconnected", + Kst4ContestApplication.macOsConnectionStateMenuTitle(On4KstConnectionState.DISCONNECTED)); + } + + @Test + void missingStateIsShownAsDisconnected() { + assertEquals("🔴 LINK: Disconnected", Kst4ContestApplication.macOsConnectionStateMenuTitle(null)); + } +} diff --git a/app-desktop/src/test/java/kst4contest/view/OperatorProfileBootstrapTest.java b/app-desktop/src/test/java/kst4contest/view/OperatorProfileBootstrapTest.java new file mode 100644 index 00000000..908a68c9 --- /dev/null +++ b/app-desktop/src/test/java/kst4contest/view/OperatorProfileBootstrapTest.java @@ -0,0 +1,161 @@ +package kst4contest.view; + +import kst4contest.controller.OperatorProfilePaths; +import kst4contest.controller.OperatorProfileStore; +import kst4contest.model.OperatorProfile; +import kst4contest.model.OperatorProfileSelection; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class OperatorProfileBootstrapTest { + + @TempDir + Path temporaryDirectory; + + @Test + void installationWithoutRegistryStartsSilentlyOnTheHistoricLayout() { + + AtomicInteger pickerInvocations = new AtomicInteger(); + OperatorProfileStore store = storeAt(); + + OperatorProfileSelection resolved = new OperatorProfileBootstrap().resolveAtStartup( + store, new CommandLineOptions(null), countingPicker(pickerInvocations, null)); + + assertNotNull(resolved); + assertEquals("preferences.xml", resolved.getPreferencesRelativeFileName()); + assertEquals("praktiKST.db", resolved.getWorkedDatabaseRelativeFileName()); + + // Nothing may be asked, and nothing may be written. + assertEquals(0, pickerInvocations.get()); + assertTrue(store.loadProfiles().isEmpty()); + } + + @Test + void singleProfileStartsWithoutAskingAnything() { + + AtomicInteger pickerInvocations = new AtomicInteger(); + OperatorProfileStore store = storeAt(); + store.saveProfiles(List.of(OperatorProfilePaths.buildRootProfile("Default")), "default"); + + OperatorProfileSelection resolved = new OperatorProfileBootstrap().resolveAtStartup( + store, new CommandLineOptions(null), countingPicker(pickerInvocations, null)); + + assertNotNull(resolved); + assertEquals(0, pickerInvocations.get()); + } + + @Test + void twoProfilesAskTheOperatorAndPreselectTheLastUsedOne() { + + OperatorProfileStore store = storeAt(); + OperatorProfile secondProfile = new OperatorProfile("OP2", "DN9APW", false, false); + store.saveProfiles( + List.of(OperatorProfilePaths.buildRootProfile("Default"), secondProfile), "OP2"); + + AtomicInteger pickerInvocations = new AtomicInteger(); + String[] observedPreselection = new String[1]; + + OperatorProfileSelection resolved = new OperatorProfileBootstrap().resolveAtStartup( + store, + new CommandLineOptions(null), + (profiles, preselectedProfileId) -> { + pickerInvocations.incrementAndGet(); + observedPreselection[0] = preselectedProfileId; + return Optional.of(profiles.get(1)); + }); + + assertEquals(1, pickerInvocations.get()); + assertEquals("OP2", observedPreselection[0]); + assertNotNull(resolved); + assertEquals("profiles/OP2/praktiKST.db", resolved.getWorkedDatabaseRelativeFileName()); + } + + @Test + void aValidProfileArgumentSkipsThePicker() { + + OperatorProfileStore store = storeAt(); + store.saveProfiles( + List.of(OperatorProfilePaths.buildRootProfile("Default"), + new OperatorProfile("OP2", "DN9APW", false, false)), + "default"); + + AtomicInteger pickerInvocations = new AtomicInteger(); + OperatorProfileBootstrap bootstrap = new OperatorProfileBootstrap(); + + OperatorProfileSelection byId = bootstrap.resolveAtStartup( + store, new CommandLineOptions("op2"), countingPicker(pickerInvocations, null)); + + assertEquals(0, pickerInvocations.get()); + assertEquals("profiles/OP2/preferences.xml", byId.getPreferencesRelativeFileName()); + assertNull(bootstrap.getStartupWarning()); + + OperatorProfileSelection byDisplayName = bootstrap.resolveAtStartup( + store, new CommandLineOptions("DN9APW"), countingPicker(pickerInvocations, null)); + + assertEquals(0, pickerInvocations.get()); + assertEquals("profiles/OP2/preferences.xml", byDisplayName.getPreferencesRelativeFileName()); + } + + @Test + void anUnknownProfileArgumentWarnsAndFallsBackToTheNormalSelection() { + + OperatorProfileStore store = storeAt(); + store.saveProfiles( + List.of(OperatorProfilePaths.buildRootProfile("Default"), + new OperatorProfile("OP2", "DN9APW", false, false)), + "default"); + + AtomicInteger pickerInvocations = new AtomicInteger(); + OperatorProfileBootstrap bootstrap = new OperatorProfileBootstrap(); + + OperatorProfileSelection resolved = bootstrap.resolveAtStartup( + store, new CommandLineOptions("NOPE"), countingPicker(pickerInvocations, 0)); + + assertEquals(1, pickerInvocations.get()); + assertNotNull(resolved); + assertNotNull(bootstrap.getStartupWarning()); + assertTrue(bootstrap.getStartupWarning().contains("NOPE")); + } + + @Test + void quittingInThePickerYieldsNoSelection() { + + OperatorProfileStore store = storeAt(); + store.saveProfiles( + List.of(OperatorProfilePaths.buildRootProfile("Default"), + new OperatorProfile("OP2", "DN9APW", false, false)), + "default"); + + OperatorProfileSelection resolved = new OperatorProfileBootstrap().resolveAtStartup( + store, new CommandLineOptions(null), (profiles, preselected) -> Optional.empty()); + + assertNull(resolved); + } + + private OperatorProfileChoiceRequester countingPicker(final AtomicInteger invocationCounter, + final Integer profileIndexToChoose) { + return (profiles, preselectedProfileId) -> { + invocationCounter.incrementAndGet(); + + if (profileIndexToChoose == null) { + return Optional.of(profiles.get(0)); + } + + return Optional.of(profiles.get(profileIndexToChoose)); + }; + } + + private OperatorProfileStore storeAt() { + return new OperatorProfileStore(temporaryDirectory.resolve("profiles.xml").toString()); + } +} diff --git a/app-desktop/src/test/java/kst4contest/view/RosterListBindingTest.java b/app-desktop/src/test/java/kst4contest/view/RosterListBindingTest.java new file mode 100644 index 00000000..164afa41 --- /dev/null +++ b/app-desktop/src/test/java/kst4contest/view/RosterListBindingTest.java @@ -0,0 +1,153 @@ +package kst4contest.view; + +import kst4contest.observe.DirectUiDispatcher; +import kst4contest.observe.SimpleRoster; +import org.junit.jupiter.api.Test; + +import java.util.Comparator; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class RosterListBindingTest { + + @Test + void theMirrorStartsWithTheCurrentContent() { + SimpleRoster roster = new SimpleRoster<>(); + roster.add("DN9APW"); + + RosterListBinding binding = RosterListBinding.mirror(roster, new DirectUiDispatcher()); + + assertEquals(List.of("DN9APW"), List.copyOf(binding.list())); + } + + @Test + void theMirrorFollowsLaterChanges() { + SimpleRoster roster = new SimpleRoster<>(); + RosterListBinding binding = RosterListBinding.mirror(roster, new DirectUiDispatcher()); + + roster.add("DN9APW"); + roster.add("DO5AMF"); + + assertEquals(List.of("DN9APW", "DO5AMF"), List.copyOf(binding.list())); + } + + @Test + void theMirrorIsTheSameInstanceThroughout() { + SimpleRoster roster = new SimpleRoster<>(); + RosterListBinding binding = RosterListBinding.mirror(roster, new DirectUiDispatcher()); + List list = binding.list(); + + roster.add("DN9APW"); + + assertTrue(list == binding.list(), + "a caller holds on to the instance it was given; it must not be replaced"); + } + + @Test + void disposeStopsFollowingAndReleasesTheListener() { + SimpleRoster roster = new SimpleRoster<>(); + RosterListBinding binding = RosterListBinding.mirror(roster, new DirectUiDispatcher()); + + binding.dispose(); + roster.add("DN9APW"); + + assertTrue(binding.list().isEmpty(), + "a disposed binding must not keep the old runtime alive across a profile switch"); + } + + @Test + void anUnchangedResultNotifiesNobody() { + SimpleRoster roster = new SimpleRoster<>(); + roster.add("DN9APW"); + RosterListBinding binding = RosterListBinding.mirror(roster, new DirectUiDispatcher()); + + AtomicInteger changes = new AtomicInteger(); + binding.onChanged(rows -> changes.incrementAndGet()); + + binding.refresh(); + binding.refresh(); + + assertEquals(0, changes.get(), + "an unchanged station list must not make the message pane drop its selection"); + } + + @Test + void aRealChangeNotifiesOnceWithTheNewContent() { + SimpleRoster roster = new SimpleRoster<>(); + roster.add("DN9APW"); + RosterListBinding binding = RosterListBinding.mirror(roster, new DirectUiDispatcher()); + + List> seen = new java.util.ArrayList<>(); + binding.onChanged(seen::add); + + roster.add("DO5AMF"); + + // Nothing covered this before: a mirror that never notifies leaves the pane blank. + assertEquals(1, seen.size(), "a real change must notify exactly once"); + assertEquals(List.of("DN9APW", "DO5AMF"), seen.get(0)); + } + + @Test + void aDerivedBindingAppliesTheDerivationAndFollowsItsSources() { + SimpleRoster members = new SimpleRoster<>(); + SimpleRoster filters = new SimpleRoster<>(); + members.add("DO5AMF"); + members.add("DN9APW"); + + RosterListBinding binding = RosterListBinding.derived( + new DirectUiDispatcher(), + () -> members.snapshot().stream() + .filter(call -> filters.snapshot().isEmpty() || filters.snapshot().contains(call)) + .sorted(Comparator.naturalOrder()) + .toList(), + members, filters); + + assertEquals(List.of("DN9APW", "DO5AMF"), List.copyOf(binding.list())); + + filters.add("DO5AMF"); + assertEquals(List.of("DO5AMF"), List.copyOf(binding.list()), + "a change of a source roster must recompute the derived content"); + + members.add("DL1ABC"); + assertEquals(List.of("DO5AMF"), List.copyOf(binding.list())); + } + + @Test + void refreshRecomputesWithoutASourceChange() { + SimpleRoster members = new SimpleRoster<>(); + members.add("DN9APW"); + members.add("DO5AMF"); + String[] wanted = { "DN9APW" }; + + RosterListBinding binding = RosterListBinding.derived( + new DirectUiDispatcher(), + () -> members.snapshot().stream().filter(call -> call.equals(wanted[0])).toList(), + members); + + assertEquals(List.of("DN9APW"), List.copyOf(binding.list())); + + wanted[0] = "DO5AMF"; + binding.refresh(); + + assertEquals(List.of("DO5AMF"), List.copyOf(binding.list()), + "a newly set filter must be visible without waiting for the next roster change"); + } + + @Test + void aDisposedDerivedBindingDetachesFromEverySource() { + SimpleRoster members = new SimpleRoster<>(); + SimpleRoster filters = new SimpleRoster<>(); + + RosterListBinding binding = RosterListBinding.derived( + new DirectUiDispatcher(), members::snapshot, members, filters); + + binding.dispose(); + members.add("DN9APW"); + filters.add("DN9APW"); + + assertTrue(binding.list().isEmpty()); + } +} diff --git a/app-desktop/src/test/java/kst4contest/view/ScreenBoundsTest.java b/app-desktop/src/test/java/kst4contest/view/ScreenBoundsTest.java new file mode 100644 index 00000000..2f662874 --- /dev/null +++ b/app-desktop/src/test/java/kst4contest/view/ScreenBoundsTest.java @@ -0,0 +1,51 @@ +package kst4contest.view; + +import org.junit.jupiter.api.Test; + +import java.awt.GraphicsEnvironment; +import java.awt.Rectangle; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.junit.jupiter.api.Assumptions.assumeFalse; + +/** + * The startup size correction has to survive the move off {@code javafx.stage.Screen}. + * + *

A stored size from a larger monitor is reduced to what the current screen offers; + * that rule lives in {@code MainWindowFrame.startupSize}, and this class only has to hand + * it honest numbers. Returning zero would give Compose a 0x0 window.

+ */ +class ScreenBoundsTest { + + @Test + void theAvailableAreaIsPositive() { + assumeFalse(GraphicsEnvironment.isHeadless(), "needs a display"); + + assertTrue(ScreenBounds.availableWidth() > 0); + assertTrue(ScreenBounds.availableHeight() > 0); + } + + @Test + void headlessFallsBackToASizeTheWindowCanActuallyUse() { + // Packaging and CI run headless. Returning zero would hand Compose a 0x0 window. + assertEquals(ScreenBounds.FALLBACK_WIDTH, ScreenBounds.widthOf(null)); + assertEquals(ScreenBounds.FALLBACK_HEIGHT, ScreenBounds.heightOf(null)); + } + + @Test + void aKnownBoundIsPassedThrough() { + Rectangle bounds = new Rectangle(0, 0, 2560, 1400); + + assertEquals(2560.0, ScreenBounds.widthOf(bounds)); + assertEquals(1400.0, ScreenBounds.heightOf(bounds)); + } + + @Test + void aDegenerateBoundFallsBackRatherThanReportingZero() { + Rectangle nothing = new Rectangle(0, 0, 0, 0); + + assertEquals(ScreenBounds.FALLBACK_WIDTH, ScreenBounds.widthOf(nothing)); + assertEquals(ScreenBounds.FALLBACK_HEIGHT, ScreenBounds.heightOf(nothing)); + } +} diff --git a/src/test/java/kst4contest/view/TableLayoutManagerTest.java b/app-desktop/src/test/java/kst4contest/view/TableLayoutManagerTest.java similarity index 100% rename from src/test/java/kst4contest/view/TableLayoutManagerTest.java rename to app-desktop/src/test/java/kst4contest/view/TableLayoutManagerTest.java diff --git a/src/test/java/kst4contest/view/TruncatedTextTableCellTest.java b/app-desktop/src/test/java/kst4contest/view/TruncatedTextTableCellTest.java similarity index 100% rename from src/test/java/kst4contest/view/TruncatedTextTableCellTest.java rename to app-desktop/src/test/java/kst4contest/view/TruncatedTextTableCellTest.java diff --git a/app-desktop/src/test/java/kst4contest/view/map/TerrainProfileCacheRepositoryTest.java b/app-desktop/src/test/java/kst4contest/view/map/TerrainProfileCacheRepositoryTest.java new file mode 100644 index 00000000..6720529d --- /dev/null +++ b/app-desktop/src/test/java/kst4contest/view/map/TerrainProfileCacheRepositoryTest.java @@ -0,0 +1,111 @@ +package kst4contest.view.map; + +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Guards the property that made the terrain cache useless with several operator + * profiles: it used to drop every cached profile whenever the configured callsign or + * locator changed. + */ +class TerrainProfileCacheRepositoryTest { + + private static final String USER_HOME_PROPERTY = "user.home"; + private static final String PROVIDER_ID = "test-provider"; + private static final int SAMPLE_COUNT = 3; + + @TempDir + Path temporaryHomeDirectory; + + private String originalUserHome; + + @BeforeEach + void redirectUserHomeToTemporaryDirectory() { + originalUserHome = System.getProperty(USER_HOME_PROPERTY); + System.setProperty(USER_HOME_PROPERTY, temporaryHomeDirectory.toString()); + } + + @AfterEach + void restoreUserHome() { + if (originalUserHome == null) { + System.clearProperty(USER_HOME_PROPERTY); + } else { + System.setProperty(USER_HOME_PROPERTY, originalUserHome); + } + } + + @Test + void profilesOfDifferentOwnersCoexistAndSurviveSwitchingBackAndForth() { + + TerrainProfileCacheRepository repository = new TerrainProfileCacheRepository(); + + repository.save("DM5M", "JO51IJ", "DL0ABC", "JN49FK", + SAMPLE_COUNT, PROVIDER_ID, profileData("station-a")); + + // Another operator profile with a different callsign and locator. + repository.save("DN9APW", "JN59AA", "DL0ABC", "JN49FK", + SAMPLE_COUNT, PROVIDER_ID, profileData("station-b")); + + Optional firstOwnerEntry = repository.load( + "DM5M", "JO51IJ", "DL0ABC", "JN49FK", SAMPLE_COUNT, PROVIDER_ID); + Optional secondOwnerEntry = repository.load( + "DN9APW", "JN59AA", "DL0ABC", "JN49FK", SAMPLE_COUNT, PROVIDER_ID); + + assertTrue(firstOwnerEntry.isPresent(), + "Working under a second operator identity must not discard the first one's cache"); + assertTrue(secondOwnerEntry.isPresent()); + assertEquals("station-a", firstOwnerEntry.get().sourceName()); + assertEquals("station-b", secondOwnerEntry.get().sourceName()); + } + + @Test + void anUnknownOwnerSimplyMissesTheCacheInsteadOfClearingIt() { + + TerrainProfileCacheRepository repository = new TerrainProfileCacheRepository(); + + repository.save("DM5M", "JO51IJ", "DL0ABC", "JN49FK", + SAMPLE_COUNT, PROVIDER_ID, profileData("station-a")); + + assertTrue(repository.load("DL0XYZ", "JO60AA", "DL0ABC", "JN49FK", + SAMPLE_COUNT, PROVIDER_ID).isEmpty()); + + assertTrue(repository.load("DM5M", "JO51IJ", "DL0ABC", "JN49FK", + SAMPLE_COUNT, PROVIDER_ID).isPresent(), + "A cache miss of one owner must not remove the entries of another"); + } + + @Test + void theCacheLivesInItsOwnGlobalFileAndNotInTheWorkedStationDatabase() { + + TerrainProfileCacheRepository repository = new TerrainProfileCacheRepository(); + repository.save("DM5M", "JO51IJ", "DL0ABC", "JN49FK", + SAMPLE_COUNT, PROVIDER_ID, profileData("station-a")); + + Path applicationDirectory = temporaryHomeDirectory.resolve(".praktiKST"); + + assertTrue(Files.exists(applicationDirectory.resolve("terrainprofilecache.db"))); + assertFalse(Files.exists(applicationDirectory.resolve("praktiKST.db")), + "The terrain cache must not pull in the worked station database"); + } + + private static TerrainProfileData profileData(final String sourceName) { + return new TerrainProfileData( + List.of( + new PathProfilePoint(0.0, 51.0, 10.0, 100.0), + new PathProfilePoint(10.0, 51.1, 10.1, 220.0), + new PathProfilePoint(20.0, 51.2, 10.2, 150.0)), + sourceName, + false); + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/BuildInfoTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/BuildInfoTest.kt new file mode 100644 index 00000000..85e1a531 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/BuildInfoTest.kt @@ -0,0 +1,24 @@ +package kst4contest.view + +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue + +class BuildInfoTest { + + @Test + fun `an unstamped build reports a version that cannot be mistaken for a release`() { + // Tests run from class directories, where no jar manifest exists. + assertEquals(BuildInfo.UNKNOWN_VERSION, BuildInfo.version) + assertFalse(BuildInfo.version.first().isDigit(), + "an unstamped version must not look like a release number") + } + + @Test + fun `the window title carries the version`() { + val title = BuildInfo.windowTitle("KST4Contest") + assertTrue(title.startsWith("KST4Contest ")) + assertTrue(title.endsWith(BuildInfo.version)) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/StartupStylesheetCopyTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/StartupStylesheetCopyTest.kt new file mode 100644 index 00000000..08591cb0 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/StartupStylesheetCopyTest.kt @@ -0,0 +1,56 @@ +package kst4contest.view + +import kst4contest.controller.OperatorProfilePaths +import kst4contest.view.compose.JavaFxStylesheet +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +/** + * The file the startup copy writes is the file the root profile's palette layer reads. + * + * These were two independent literals of the same string in two classes, and they had to stay + * equal for the root profile's own stylesheet to be read at all -- the copy is written under + * one name and resolved under the other. A rename on either side would silently restore the + * defect this stage was commissioned to fix: a file written at every startup that nothing + * ever reads. The build would stay green and no other test would notice. + * + * Both now derive from `ApplicationConstants`, so there is nothing left to drift. This pins + * that it stays that way. + */ +class StartupStylesheetCopyTest { + + private val rootProfile = OperatorProfilePaths.buildRootProfile("Default") + + @Test + fun theCopyTargetIsWhatTheRootProfilesPaletteLayerReads() { + assertEquals( + OperatorProfilePaths.paletteRelativeFileName(rootProfile, false), + Kst4ContestApplication.STYLE_DEFAULTCSSDAY_FILE, + ) + assertEquals( + OperatorProfilePaths.paletteRelativeFileName(rootProfile, true), + Kst4ContestApplication.STYLE_DEFAULTCSSEVENING_FILE, + ) + } + + @Test + fun theCopySourceIsTheSheetTheThemeReads() { + // Written from one resource and read from another would be the same defect, inverted. + assertEquals( + JavaFxStylesheet.DAYLIGHT_RESOURCE, + Kst4ContestApplication.STYLE_DEFAULTCSSDAY_RESOURCE, + ) + assertEquals( + JavaFxStylesheet.EVENING_RESOURCE, + Kst4ContestApplication.STYLE_DEFAULTCSSEVENING_RESOURCE, + ) + } + + @Test + fun theResourceIsTheFileNameWithALeadingSlash() { + assertEquals( + "/" + Kst4ContestApplication.STYLE_DEFAULTCSSDAY_FILE, + Kst4ContestApplication.STYLE_DEFAULTCSSDAY_RESOURCE, + ) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/AirplaneCellTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/AirplaneCellTest.kt new file mode 100644 index 00000000..d5a1067c --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/AirplaneCellTest.kt @@ -0,0 +1,107 @@ +package kst4contest.view.compose + +import kst4contest.model.AirPlane +import kst4contest.model.AirPlaneReflectionInfo +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Test + +/** + * The aircraft-reflection cell, shared by the station list and the directed messages. + * + * Both JavaFX tables built this text by hand and identically: the minutes until the + * aeroplane arrives and how promising the path is, for at most the first two. The + * Compose station list was reading AirPlaneReflectionInfo.toString() instead, which + * yields "DL0ABC > OK1XYZ at 3 planes: [...]" — a defect from Etappe 5a that this + * test closes. + */ +class AirplaneCellTest { + + @Test + fun `one aeroplane gives its minutes and its potential`() { + val info = reflectionInfo(plane(minutes = 7, potential = 85)) + assertEquals("7 (85%)", AirplaneCell.format(info)) + } + + @Test + fun `two aeroplanes are separated by a slash`() { + val info = reflectionInfo(plane(7, 85), plane(12, 60)) + assertEquals("7 (85%) / 12 (60%)", AirplaneCell.format(info)) + } + + /** Only the first two fit in the column; the rest are in the tooltip's business. */ + @Test + fun `a third aeroplane is not shown`() { + val info = reflectionInfo(plane(7, 85), plane(12, 60), plane(20, 30)) + assertEquals("7 (85%) / 12 (60%)", AirplaneCell.format(info)) + } + + /** + * "nil" and not an empty cell: the operator has to tell "no aeroplane is coming" + * apart from "nothing has been computed for this station yet". + */ + @Test + fun `no aeroplanes reads nil`() { + assertEquals("nil", AirplaneCell.format(reflectionInfo())) + } + + @Test + fun `an unset aeroplane list reads nil too`() { + val info = AirPlaneReflectionInfo() + info.risingAirplanes = null + assertEquals("nil", AirplaneCell.format(info)) + } + + /** Nothing computed yet leaves the cell blank, as both JavaFX tables did. */ + @Test + fun `no reflection info at all leaves the cell empty`() { + assertEquals("", AirplaneCell.format(null)) + } + + // ---- the colour --------------------------------------------------------- + + /** + * The colour is what an aircraft-scatter chance is spotted by; the numbers are read + * afterwards. Both stylesheets use the same three: purple for a certain path, red for a + * good one, orange for a fair one. + */ + @Test + fun `a certain path is purple, a good one red, a fair one orange`() { + assertEquals(AirplaneCell.PURPLE_100, AirplaneCell.accentFor("7 (100%)")?.foreground) + assertEquals(AirplaneCell.RED_75, AirplaneCell.accentFor("7 (75%)")?.foreground) + assertEquals(AirplaneCell.ORANGE_50, AirplaneCell.accentFor("7 (50%)")?.foreground) + } + + /** + * Pinned as found: JavaFX matched the rendered string, so only exactly 100, 75 and 50 + * are coloured — 85% gets nothing. Colouring by threshold instead would light up cells + * the operator has never seen lit, which changes what the column means at a glance. + */ + @Test + fun `a potential between the three steps is not coloured`() { + assertNull(AirplaneCell.accentFor("7 (85%)")) + assertNull(AirplaneCell.accentFor("7 (60%)")) + assertNull(AirplaneCell.accentFor("7 (49%)")) + } + + @Test + fun `nothing coming is not coloured`() { + assertNull(AirplaneCell.accentFor("nil")) + assertNull(AirplaneCell.accentFor("")) + } + + /** With two aeroplanes the better one decides, as the original's if-chain did. */ + @Test + fun `the best of two potentials decides the colour`() { + assertEquals(AirplaneCell.PURPLE_100, AirplaneCell.accentFor("7 (75%) / 12 (100%)")?.foreground) + assertEquals(AirplaneCell.RED_75, AirplaneCell.accentFor("7 (50%) / 12 (75%)")?.foreground) + } + + private fun reflectionInfo(vararg planes: AirPlane): AirPlaneReflectionInfo = + AirPlaneReflectionInfo().apply { risingAirplanes = planes.toMutableList() } + + private fun plane(minutes: Int, potential: Int): AirPlane = AirPlane().apply { + arrivingDurationMinutes = minutes + this.potential = potential + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/ChatInputStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/ChatInputStateTest.kt new file mode 100644 index 00000000..35f250fd --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/ChatInputStateTest.kt @@ -0,0 +1,435 @@ +package kst4contest.view.compose + +import androidx.compose.ui.text.TextRange +import androidx.compose.ui.text.input.TextFieldValue +import kst4contest.model.ChatCategory +import kst4contest.model.ChatMember +import kst4contest.model.ChatMessage +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertSame +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * The line the operator actually types into. Everything here is the JavaFX behaviour; + * two places where that behaviour is inconsistent are pinned as they are rather than + * quietly repaired, because both decide what gets transmitted. + */ +class ChatInputStateTest { + + private val mainCategory = ChatCategory(2) + private val memberCategory = ChatCategory(3) + + // ---- sending ----------------------------------------------------------- + + @Test + fun `sending queues the resolved text and empties the field`() { + val actions = FakeActions() + val state = ChatInputState(actions) + state.value = TextFieldValue("test de dn9apw") + + state.send() + + assertEquals(1, actions.queued.size) + assertEquals("test de dn9apw", actions.queued.single().messageText) + assertEquals("", state.value.text) + } + + @Test + fun `the enter key sends the same way the button does`() { + val actions = FakeActions() + val state = ChatInputState(actions) + state.value = TextFieldValue("cq cq") + + state.send() + + assertEquals(1, actions.queued.size) + } + + /** A variable may legitimately resolve to nothing; then there is no message. */ + @Test + fun `a text that resolves to nothing is dropped and the field cleared`() { + val actions = FakeActions(resolved = " ") + val state = ChatInputState(actions) + state.value = TextFieldValue("%qrg%") + + state.send() + + assertTrue(actions.queued.isEmpty()) + assertEquals("", state.value.text) + } + + @Test + fun `nothing is queued for an empty field`() { + val actions = FakeActions(resolved = "") + val state = ChatInputState(actions) + state.send() + assertTrue(actions.queued.isEmpty()) + } + + /** Sending a private message to yourself is a mistake, not a feature. */ + @Test + fun `a message addressed to the own callsign is refused`() { + val actions = FakeActions(addressedToSelf = true) + val state = ChatInputState(actions) + state.value = TextFieldValue("/cq DN9APW hi") + + state.send() + + assertTrue(actions.queued.isEmpty()) + assertEquals("", state.value.text) + } + + @Test + fun `the category comes from the resolver`() { + val actions = FakeActions(category = memberCategory) + val state = ChatInputState(actions) + state.value = TextFieldValue("/cq DL0ABC hi") + + state.send() + + assertSame(memberCategory, actions.queued.single().chatCategory) + } + + /** If the category cannot be resolved at all, the main chat is where it goes. */ + @Test + fun `an unresolvable category falls back to the main chat`() { + val actions = FakeActions(category = null) + val state = ChatInputState(actions) + state.value = TextFieldValue("hello") + + state.send() + + assertSame(mainCategory, actions.queued.single().chatCategory) + } + + @Test + fun `an outgoing message is never addressed to the server`() { + val actions = FakeActions() + val state = ChatInputState(actions) + state.value = TextFieldValue("hello") + + state.send() + + assertEquals(false, actions.queued.single().isMessageDirectedToServer) + } + + /** A /cq starts the reply clock, which is what the no-reply tracking runs on. */ + @Test + fun `sending records the outbound cq and asks for a recompute`() { + val actions = FakeActions() + val state = ChatInputState(actions) + state.value = TextFieldValue("/cq DL0ABC pse 23cm") + + state.send() + + assertEquals(listOf("/cq DL0ABC pse 23cm"), actions.recordedCqs) + assertEquals(listOf("outbound-tx"), actions.recomputeReasons) + } + + // ---- which station the text is resolved against ------------------------ + + @Test + fun `the panel selection wins over the table`() { + val panel = member("DL0ABC") + val table = member("OK1XYZ") + val actions = FakeActions(panelSelection = panel, tableSelection = table) + val state = ChatInputState(actions) + state.value = TextFieldValue("%call%") + + state.send() + + assertSame(panel, actions.resolvedAgainst.first()) + } + + @Test + fun `the table selection is used when the panel has none`() { + val table = member("OK1XYZ") + val actions = FakeActions(tableSelection = table) + val state = ChatInputState(actions) + state.value = TextFieldValue("%call%") + + state.send() + + assertSame(table, actions.resolvedAgainst.first()) + } + + /** + * Pinned as found, not repaired. On the send path the score service's selection is + * consulted only AFTER the variables have been resolved, so a station that only it + * knows about does not reach the resolver — while the shortcut buttons, which use + * the three-step lookup, do see it. Repairing this would change which station a + * variable resolves against, and therefore what gets transmitted. + */ + @Test + fun `on the send path the score service selection reaches the category but not the variables`() { + val scored = member("S50ZZZ") + val actions = FakeActions(scoreSelection = scored) + val state = ChatInputState(actions) + state.value = TextFieldValue("%call%") + + state.send() + + assertNull(actions.resolvedAgainst.first(), "the resolver saw a station it did not see in JavaFX") + assertSame(scored, actions.categoryResolvedAgainst.first()) + } + + // ---- the shortcut buttons --------------------------------------------- + + /** A shortcut button APPENDS, so several can be strung together into one message. */ + @Test + fun `a shortcut button appends to what is already typed`() { + val actions = FakeActions(resolved = "pse sked") + val state = ChatInputState(actions) + state.value = TextFieldValue("/cq DL0ABC ") + + state.appendShortcut("pse sked") + + assertEquals("/cq DL0ABC pse sked", state.value.text) + } + + @Test + fun `a shortcut button resolves its variables before appending`() { + val actions = FakeActions(resolved = "144.300") + val state = ChatInputState(actions) + + state.appendShortcut("MYQRGVAR") + + assertEquals("144.300", state.value.text) + assertEquals("MYQRGVAR ", actions.resolvedTemplates.single()) + } + + @Test + fun `a shortcut that resolves to nothing changes nothing`() { + val actions = FakeActions(resolved = " ") + val state = ChatInputState(actions) + state.value = TextFieldValue("keep me") + + state.appendShortcut("%unset%") + + assertEquals("keep me", state.value.text) + } + + /** The two QRG buttons append the field contents rather than a resolved template. */ + @Test + fun `the MYQRG button appends the own frequency`() { + val actions = FakeActions(ownQrgMain = "144.370") + val state = ChatInputState(actions) + state.value = TextFieldValue("qrg ") + + state.appendOwnQrg(mainCategory = true) + + assertEquals("qrg 144.370 ", state.value.text) + } + + @Test + fun `the SECONDQRG button appends the second frequency`() { + val actions = FakeActions(ownQrgSecond = "432.200") + val state = ChatInputState(actions) + + state.appendOwnQrg(mainCategory = false) + + assertEquals("432.200 ", state.value.text) + } + + // ---- the snippets ------------------------------------------------------ + + /** + * A snippet REPLACES the field, unlike a shortcut button: it builds a whole + * directed message, so whatever was half typed would only corrupt it. + */ + @Test + fun `a snippet replaces the field with a directed message`() { + val actions = FakeActions(panelSelection = member("DL0ABC"), resolved = "/cq DL0ABC pse 23cm") + val state = ChatInputState(actions) + state.value = TextFieldValue("half typed") + + state.insertSnippet(listOf("pse 23cm", "qrz?"), 0) + + assertEquals("/cq DL0ABC pse 23cm", state.value.text) + assertEquals("/cq DL0ABC pse 23cm", actions.resolvedTemplates.single()) + } + + /** Without a station there is nobody to direct it at, so nothing happens. */ + @Test + fun `a snippet without a selected station does nothing`() { + val actions = FakeActions() + val state = ChatInputState(actions) + state.value = TextFieldValue("keep me") + + state.insertSnippet(listOf("pse 23cm"), 0) + + assertEquals("keep me", state.value.text) + assertTrue(actions.resolvedTemplates.isEmpty()) + } + + @Test + fun `a snippet index nobody configured does nothing`() { + val actions = FakeActions(panelSelection = member("DL0ABC")) + val state = ChatInputState(actions) + state.value = TextFieldValue("keep me") + + state.insertSnippet(listOf("only one"), 5) + state.insertSnippet(listOf("only one"), -1) + + assertEquals("keep me", state.value.text) + } + + @Test + fun `the snippet uses the three step station lookup`() { + val scored = member("S50ZZZ") + val actions = FakeActions(scoreSelection = scored, resolved = "/cq S50ZZZ hi") + val state = ChatInputState(actions) + + state.insertSnippet(listOf("hi"), 0) + + assertSame(scored, actions.resolvedAgainst.single()) + } + + // ---- the context menu ------------------------------------------------- + + /** + * The same snippet roster reaches the field three ways, and all three differ. Ctrl+N + * replaces the field with a directed message; a right-click APPENDS the snippet with + * no trailing space and no /cq prefix; a shortcut button appends its own roster's + * entry followed by a space. Pinned because collapsing any two of them would change + * what goes out. + */ + @Test + fun `a context menu entry appends the resolved snippet without a trailing space`() { + val actions = FakeActions(panelSelection = member("DL0ABC"), resolved = "pse 23cm") + val state = ChatInputState(actions) + state.value = TextFieldValue("/cq DL0ABC ") + + state.appendSnippet("pse 23cm") + + assertEquals("/cq DL0ABC pse 23cm", state.value.text) + assertEquals("pse 23cm", actions.resolvedTemplates.single(), "a space was added to the template") + } + + @Test + fun `a context menu entry needs no selected station`() { + val actions = FakeActions(resolved = "qrz?") + val state = ChatInputState(actions) + + state.appendSnippet("qrz?") + + assertEquals("qrz?", state.value.text) + } + + @Test + fun `a context menu entry that resolves to nothing changes nothing`() { + val actions = FakeActions(resolved = "") + val state = ChatInputState(actions) + state.value = TextFieldValue("keep me") + + state.appendSnippet("%unset%") + + assertEquals("keep me", state.value.text) + } + + // ---- the caret and the focus ------------------------------------------ + + /** + * After every insertion the caret sits at the end and the field takes the focus + * back — the operator is mid sentence, and a caret left at position 0 turns the + * next keystroke into a corrupted message. + */ + @Test + fun `an insertion puts the caret at the end`() { + val actions = FakeActions(resolved = "pse sked") + val state = ChatInputState(actions) + state.value = TextFieldValue("/cq DL0ABC ", selection = TextRange(0)) + + state.appendShortcut("pse sked") + + assertEquals(state.value.text.length, state.value.selection.start) + assertTrue(state.value.selection.collapsed) + } + + @Test + fun `an insertion asks for the focus back`() { + val actions = FakeActions(resolved = "x") + val state = ChatInputState(actions) + val before = state.focusRequests + + state.appendShortcut("x") + + assertTrue(state.focusRequests > before) + } + + @Test + fun `a refused insertion does not steal the focus`() { + val actions = FakeActions(resolved = " ") + val state = ChatInputState(actions) + val before = state.focusRequests + + state.appendShortcut("%unset%") + + assertEquals(before, state.focusRequests) + } + + // ---- clearing ---------------------------------------------------------- + + @Test + fun `clear empties the field without sending`() { + val actions = FakeActions() + val state = ChatInputState(actions) + state.value = TextFieldValue("unsent") + + state.clear() + + assertEquals("", state.value.text) + assertTrue(actions.queued.isEmpty()) + } + + private fun member(call: String): ChatMember = ChatMember().apply { + setCallSign(call) + setChatCategory(memberCategory) + } + + /** Real behaviour, recorded; no mocking framework needed for a boundary this small. */ + private inner class FakeActions( + private val panelSelection: ChatMember? = null, + private val tableSelection: ChatMember? = null, + private val scoreSelection: ChatMember? = null, + private val resolved: String? = null, + private val addressedToSelf: Boolean = false, + private val category: ChatCategory? = null, + private val ownQrgMain: String = "", + private val ownQrgSecond: String = "", + ) : ChatInputActions { + + val queued = mutableListOf() + val resolvedAgainst = mutableListOf() + val categoryResolvedAgainst = mutableListOf() + val resolvedTemplates = mutableListOf() + val recordedCqs = mutableListOf() + val recomputeReasons = mutableListOf() + + override fun panelSelection(): ChatMember? = panelSelection + override fun tableSelection(): ChatMember? = tableSelection + override fun scoreSelection(): ChatMember? = scoreSelection + + override fun resolveVariables(template: String, member: ChatMember?): String? { + resolvedAgainst += member + resolvedTemplates += template + return resolved ?: template + } + + override fun isAddressedToOwnCallsign(text: String): Boolean = addressedToSelf + + override fun resolveCategory(text: String, member: ChatMember?): ChatCategory? { + categoryResolvedAgainst += member + return category + } + + override fun mainCategory(): ChatCategory = this@ChatInputStateTest.mainCategory + override fun recordOutboundCq(text: String) { recordedCqs += text } + override fun requestRecompute(reason: String) { recomputeReasons += reason } + override fun queue(message: ChatMessage) { queued += message } + override fun ownQrgMain(): String = ownQrgMain + override fun ownQrgSecond(): String = ownQrgSecond + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/ComposeAlertTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/ComposeAlertTest.kt new file mode 100644 index 00000000..719593dc --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/ComposeAlertTest.kt @@ -0,0 +1,152 @@ +package kst4contest.view.compose + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import java.awt.EventQueue +import java.util.concurrent.atomic.AtomicBoolean + +/** + * The rules of the alert dialog that hold without a screen. + * + * The drawing is covered by the GUI acceptance run, the way `raiseSteps` and + * `deiconifiedState` of ComposeWindowHost split the same way: the rule is the part that + * can be wrong silently. + * + * Button order is in here because getting it wrong is not cosmetic. The operator reaches + * for a position, not a word, and both confirmations this class shows give something up — + * a running contest session, or the whole client. + */ +class ComposeAlertTest { + + @Test + fun anAcknowledgementHasOneButtonAndItConfirms() { + val buttons = alertButtons("OK", null, ConfirmKind.OK_DONE, BUTTON_ORDER_LINUX) + + assertEquals(listOf(AlertButton("OK", confirming = true)), buttons) + } + + @Test + fun closingTheWindowCountsAsNotConfirming() { + // The JavaFX Alert returned Optional.empty when dismissed, and every caller + // treated that as "do not proceed". The window close button must do the same. + assertFalse(dismissalConfirms()) + } + + /* + * The four cases below are the JavaFX ButtonBar orders, read off JavaFX 21.0.5 on this + * machine rather than from memory: + * LINUX = L_HE+UNYACBXIO_R -> YES < CANCEL_CLOSE < OK_DONE + * MAC_OS = L_HE+U+FBIX_NCYOA_R -> CANCEL_CLOSE < YES < OK_DONE + * WINDOWS = L_E+U+FBXI_YNOCAH_R -> YES < OK_DONE < CANCEL_CLOSE + * The quit dialog used ButtonType.YES, the profile switch used OK_DONE, so the two + * disagree on Linux — which is why a single "confirming button first" rule cannot be + * right for both. + */ + + @Test + fun theQuitDialogKeepsYesFirstWhereJavaFxPutItFirst() { + val linux = alertButtons("Yes", "Cancel", ConfirmKind.YES, BUTTON_ORDER_LINUX) + val windows = alertButtons("Yes", "Cancel", ConfirmKind.YES, BUTTON_ORDER_WINDOWS) + + assertEquals(listOf("Yes", "Cancel"), linux.map { it.text }) + assertEquals(listOf("Yes", "Cancel"), windows.map { it.text }) + } + + @Test + fun theQuitDialogPutsCancelFirstOnMacOsWhereJavaFxDid() { + val mac = alertButtons("Yes", "Cancel", ConfirmKind.YES, BUTTON_ORDER_MAC_OS) + + assertEquals(listOf("Cancel", "Yes"), mac.map { it.text }) + } + + @Test + fun theProfileSwitchPutsCancelFirstOnLinuxAndMacOs() { + val linux = alertButtons("Switch profile", "Cancel", ConfirmKind.OK_DONE, BUTTON_ORDER_LINUX) + val mac = alertButtons("Switch profile", "Cancel", ConfirmKind.OK_DONE, BUTTON_ORDER_MAC_OS) + + // The regression this pins: a plain "confirming first" rule put the button that + // gives up a live contest session under the cursor's resting place. + assertEquals(listOf("Cancel", "Switch profile"), linux.map { it.text }) + assertEquals(listOf("Cancel", "Switch profile"), mac.map { it.text }) + } + + @Test + fun theProfileSwitchKeepsItsConfirmFirstOnWindows() { + val windows = alertButtons("Switch profile", "Cancel", ConfirmKind.OK_DONE, BUTTON_ORDER_WINDOWS) + + assertEquals(listOf("Switch profile", "Cancel"), windows.map { it.text }) + } + + @Test + fun confirmingStaysMarkedAsConfirmingWhateverTheOrder() { + val mac = alertButtons("Switch profile", "Cancel", ConfirmKind.OK_DONE, BUTTON_ORDER_MAC_OS) + + // Reordering must never move the meaning onto the other button. + assertEquals( + mapOf("Cancel" to false, "Switch profile" to true), + mac.associate { it.text to it.confirming }, + ) + } + + @Test + fun theOrderStringIsChosenByOperatingSystem() { + assertEquals(BUTTON_ORDER_MAC_OS, buttonOrderFor("Mac OS X")) + assertEquals(BUTTON_ORDER_WINDOWS, buttonOrderFor("Windows 11")) + assertEquals(BUTTON_ORDER_LINUX, buttonOrderFor("Linux")) + // Anything else follows Linux, the way JavaFX treated unknown platforms. + assertEquals(BUTTON_ORDER_LINUX, buttonOrderFor("FreeBSD")) + } + + @Test + fun enterConfirmsAndEscapeCancels() { + val buttons = alertButtons("Switch profile", "Cancel", ConfirmKind.OK_DONE, BUTTON_ORDER_LINUX) + + assertEquals("Switch profile", buttonForEnter(buttons)?.text) + assertEquals("Cancel", buttonForEscape(buttons)?.text) + } + + /* + * The two below pin the rule that cost three failed application starts: a ComposeDialog + * is a Swing component wrapping a Skia layer, so building it anywhere but the AWT event + * thread makes skiko fail to create its GL context ("Can't wrap nullptr") and the dialog + * never paints. Since a modal wait on an unpaintable dialog cannot end, the client hung + * at startup. No unit test saw it; only running the application did. + */ + + @Test + fun aDialogAskedForFromAWorkerThreadIsBuiltOnTheEventThread() { + val onEventThread = AtomicBoolean(false) + + // The startup path: main() asks for the profile picker and the startup warning. + openOnEventThread { onEventThread.set(EventQueue.isDispatchThread()) } + + assertTrue( + onEventThread.get(), + "a dialog built off the event thread cannot create its graphics context", + ) + } + + @Test + fun aDialogAskedForOnTheEventThreadIsBuiltInline() { + val ranInline = AtomicBoolean(false) + + // The menu path: already on the event thread, where invokeAndWait would throw. + EventQueue.invokeAndWait { + openOnEventThread { ranInline.set(EventQueue.isDispatchThread()) } + } + + assertTrue(ranInline.get(), "the dialog must still be built on the event thread") + } + + @Test + fun escapeOnAnAcknowledgementPressesItsOnlyButton() { + // No cancel to fall back on: dismissing an acknowledgement is acknowledging it, + // which is what the JavaFX Alert's ESC did with a lone OK button. + val buttons = alertButtons("OK", null, ConfirmKind.OK_DONE, BUTTON_ORDER_LINUX) + + assertEquals("OK", buttonForEnter(buttons)?.text) + assertEquals("OK", buttonForEscape(buttons)?.text) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/ComposeWindowHostCloseTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/ComposeWindowHostCloseTest.kt new file mode 100644 index 00000000..c1ec9651 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/ComposeWindowHostCloseTest.kt @@ -0,0 +1,146 @@ +package kst4contest.view.compose + +import androidx.compose.material3.Text +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Assumptions.assumeFalse +import org.junit.jupiter.api.Test +import java.awt.EventQueue +import java.awt.GraphicsEnvironment +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit + +/** + * Closing a window from the user-interface thread has to work. + * + * Since the dispatcher moved to the AWT event thread, every window toggle in the Windows + * menu — and the whole teardown in `shutdownRuntime` — calls [ComposeWindowHost.close] + * from that thread. The window's own `application { }` can only advance as continuations + * posted to the same thread, so a plain `Thread.join` there can never be satisfied: the + * interface froze for the timeout and `close()` returned with the window still registered + * as open. The documented consequence is the worst one: a profile switch then found the + * stale flag, raised the dead runtime's window, and the rebuilt profile got no settings + * window at all — the window that carries the Connect button. + */ +class ComposeWindowHostCloseTest { + + /** + * Waits until the window with this title is actually showing. + * + * `ComposeWindowHost.isOpen` turns true the moment the window thread enters + * `application { }`, which is well before the window is realised — so a fixed sleep + * after it is a guess, and this test failed on that guess once the machine was busy. + * Frames are read on the event thread, which owns them. + */ + private fun awaitShowingFrame(title: String): java.awt.Frame { + val deadline = System.nanoTime() + TimeUnit.SECONDS.toNanos(20) + + while (System.nanoTime() < deadline) { + var found: java.awt.Frame? = null + EventQueue.invokeAndWait { + found = java.awt.Window.getWindows() + .filterIsInstance() + .firstOrNull { it.isShowing && it.title == title } + } + found?.let { return it } + Thread.sleep(50) + } + + throw AssertionError("the window titled '$title' never became visible") + } + + private fun openHost(name: String): ComposeWindowHost { + val host = ComposeWindowHost(name) + host.show( + title = { "close test" }, + darkMode = false, + baseFontSizeSp = 12f, + widthDp = 200f, + heightDp = 120f, + ) { Text("close test") } + + // Wait for the window to really be on screen, so the close has something to close. + awaitShowingFrame("close test") + return host + } + + @Test + fun closingFromTheEventThreadCompletesAndClearsTheOpenFlag() { + assumeFalse(GraphicsEnvironment.isHeadless(), "needs a display") + + val host = openHost("close-from-edt") + val worker = Executors.newSingleThreadExecutor() + + try { + // invokeAndWait so close() really runs ON the event thread, as the menu does. + worker.submit { EventQueue.invokeAndWait { host.close() } } + .get(20, TimeUnit.SECONDS) + + assertFalse( + host.isOpen, + "close() must not return while the window still counts as open: the next " + + "show() would raise the dead window instead of building a new one", + ) + } finally { + worker.shutdownNow() + host.close() + } + } + + @Test + fun theWindowManagerCloseRunsTheHostsOwnCloseRequestWhenOneIsGiven() { + assumeFalse(GraphicsEnvironment.isHeadless(), "needs a display") + + /* + * The main window's close has to run the application's quit flow, not just close + * the window. Compose's default `onCloseRequest = ::exitApplication` ends that one + * window's `application { }` and leaves the process running with the chat still + * connected and no main window — which is what a tiling window manager's close + * produced: the window vanished and gradle kept reporting the task as executing. + */ + val asked = java.util.concurrent.CountDownLatch(1) + val host = ComposeWindowHost("close-request-override") + host.show( + title = { "close request test" }, + darkMode = false, + baseFontSizeSp = 12f, + widthDp = 200f, + heightDp = 120f, + onCloseRequest = { asked.countDown() }, + ) { Text("close request test") } + + /* + * Matched by title rather than by type: the suite runs in one JVM and other tests' + * Compose windows can still be showing, so a type filter sent the event to the + * wrong window and this latch waited for ever. + */ + val mine = awaitShowingFrame("close request test") + + try { + // What the window manager sends: a close request on the window itself. + EventQueue.invokeAndWait { + mine.dispatchEvent( + java.awt.event.WindowEvent(mine, java.awt.event.WindowEvent.WINDOW_CLOSING) + ) + } + + assertTrue( + asked.await(10, TimeUnit.SECONDS), + "the host must route a close request to the handler it was given", + ) + } finally { + host.close() + } + } + + @Test + fun closingFromAForeignThreadStillWorks() { + assumeFalse(GraphicsEnvironment.isHeadless(), "needs a display") + + val host = openHost("close-from-worker") + + host.close() + + assertFalse(host.isOpen, "a close off the event thread must still wait for the window") + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/ComposeWindowHostRaiseTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/ComposeWindowHostRaiseTest.kt new file mode 100644 index 00000000..e513b705 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/ComposeWindowHostRaiseTest.kt @@ -0,0 +1,80 @@ +package kst4contest.view.compose + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import java.awt.Frame + +/** + * What a second press on an opener does to the window that is already open. + * + * `ComposeWindowHost.show` refused silently when the window was open, which is correct + * about not building a second one and wrong about everything else: the JavaFX originals + * built a fresh Stage per press and came forward as a side effect, so the operator who + * clicks back to the main window and presses "more" again used to see the window and now + * saw nothing. Six windows share this host, so all six had it. + * + * Only the rules are tested here, but there turned out to be two of them: what to do, + * and what to write when de-iconifying. The first version of this file called the second + * one untestable AWT and got it wrong in the one line it had excused itself from + * covering. `toFront` really is not drivable — its outcome belongs to the window manager + * and is not observable from the JVM — and that is the whole of what is uncovered. + */ +class ComposeWindowHostRaiseTest { + + @Test + fun `an ordinary open window is brought forward`() { + assertEquals( + listOf(RaiseStep.TO_FRONT), + raiseSteps(displayable = true, iconified = false), + ) + } + + /** + * The order is the point, not the content. `toFront` on an iconified frame leaves it + * iconified, so restoring afterwards would raise a window the operator still cannot + * see — the same dead button, one step further along. + */ + @Test + fun `a minimised window is restored before it is raised`() { + assertEquals( + listOf(RaiseStep.DEICONIFY, RaiseStep.TO_FRONT), + raiseSteps(displayable = true, iconified = true), + ) + } + + /** + * A window on its way out is left alone. `close()` drops visibility and waits for the + * thread; a press landing in that gap must not fight the close and must not raise a + * frame that is about to be disposed. + */ + @Test + fun `a window that is no longer displayable is left alone`() { + assertEquals(emptyList(), raiseSteps(displayable = false, iconified = false)) + assertEquals(emptyList(), raiseSteps(displayable = false, iconified = true)) + } + + /** + * De-iconifying clears one bit; it does not assign a state. + * + * `extendedState` is a bit set — `NORMAL` is 0, `ICONIFIED` is 1, `MAXIMIZED_BOTH` is + * 6 — so a window the operator maximised and then minimised holds 7. Writing + * `Frame.NORMAL` there hands it back restored-down and drops a maximisation nobody + * asked to drop. That is what the first version of `raise()` did, one line after + * taking care to *detect* the mixed state with a mask rather than an equality. + */ + @Test + fun `restoring a maximised window keeps it maximised`() { + assertEquals(Frame.MAXIMIZED_BOTH, deiconifiedState(Frame.MAXIMIZED_BOTH or Frame.ICONIFIED)) + } + + @Test + fun `restoring a plain minimised window leaves it normal`() { + assertEquals(Frame.NORMAL, deiconifiedState(Frame.ICONIFIED)) + } + + @Test + fun `a state without the iconified bit is returned untouched`() { + assertEquals(Frame.MAXIMIZED_BOTH, deiconifiedState(Frame.MAXIMIZED_BOTH)) + assertEquals(Frame.NORMAL, deiconifiedState(Frame.NORMAL)) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/ContrastRuleTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/ContrastRuleTest.kt new file mode 100644 index 00000000..0008578f --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/ContrastRuleTest.kt @@ -0,0 +1,172 @@ +package kst4contest.view.compose + +import androidx.compose.ui.graphics.Color +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import kotlin.math.abs + +/** + * The readability measure, which only warns. + * + * A pure function, and therefore the part that can be wrong without anyone noticing: a + * warning that never fires is indistinguishable from a palette that is fine, and a warning + * that always fires teaches the operator to ignore warnings. The reference numbers below are + * the ones WCAG itself states for black and white. + * + * The pair is an enum rather than its name, deliberately: a translated name here would make + * every one of these filters depend on whichever language ran last in the shared JVM. + * + * The comparison is against the shipped sheet rather than against the bare floor, because + * the shipped sheets do not meet that floor themselves -- measured: the evening accent sits + * at 2.26 on its own surface. What is reported is therefore "this change made a pair harder + * to read than it shipped", which is the question the operator is actually asking. + */ +class ContrastRuleTest { + + private val day = JavaFxStylesheet.read("/KST4ContestDefaultDay.css") + private val evening = JavaFxStylesheet.read("/KST4ContestDefaultEvening.css") + + private fun assertClose(expected: Double, actual: Double, what: String) { + assertTrue(abs(expected - actual) < 0.05, "$what: expected ~$expected but was $actual") + } + + @Test + fun blackOnWhiteIsTheMaximumOf21() { + assertClose(21.0, contrastRatio(Color.Black, Color.White), "black on white") + assertClose(21.0, contrastRatio(Color.White, Color.Black), "white on black") + } + + @Test + fun aColourAgainstItselfIsTheMinimumOf1() { + assertClose(1.0, contrastRatio(Color.Black, Color.Black), "black on black") + assertClose(1.0, contrastRatio(Color(0xFF8899AA), Color(0xFF8899AA)), "grey on grey") + } + + @Test + fun theRatioDoesNotDependOnWhichIsTheBackground() { + assertEquals( + contrastRatio(Color(0xFF123456), Color(0xFFEEDDCC)), + contrastRatio(Color(0xFFEEDDCC), Color(0xFF123456)), + ) + } + + @Test + fun midGreyOnWhiteIsAroundFourAndAHalf() { + // #767676 on white is the canonical WCAG AA boundary example: 4.54. + assertClose(4.54, contrastRatio(Color(0xFF767676), Color.White), "#767676 on white") + } + + @Test + fun aShippedSheetNeverWarnsAboutItself() { + /* + * The property the whole relative rule exists for. Both sheets have pairs under the + * floor -- the day accent at 2.86, the evening accent at 2.26 -- so an absolute rule + * would warn on a client nobody has touched. + */ + assertTrue(contrastWarnings(day, day).isEmpty(), "the daylight sheet warns about itself") + assertTrue( + contrastWarnings(evening, evening).isEmpty(), + "the evening sheet warns about itself", + ) + } + + @Test + fun theShippedSheetsReallyDoHavePairsUnderTheFloor() { + /* + * Measured here rather than asserted in prose, because it is the premise of the rule + * above. If a later change to the sheets makes every pair pass, the relative rule + * becomes equivalent to the absolute one and the deviation can be dropped. + */ + val accentOnSurface = contrastRatio(day.accent, day.base) + + assertTrue( + accentOnSurface < CONTRAST_FLOOR, + "the daylight accent now passes at $accentOnSurface; the relative rule may no " + + "longer be needed", + ) + } + + @Test + fun blackTextOnABlackSurfaceWarnsAboutEveryPairItAppearsIn() { + val unreadable = day.copy( + base = Color.Black, + windowBackground = Color.Black, + controlInnerBackground = Color.Black, + labelTextFill = Color.Black, + accent = Color.Black, + textAccent = Color.Black, + ) + + val warnings = contrastWarnings(unreadable, day) + + assertEquals(4, warnings.size, "every pair must warn: ${warnings.map { it.what }}") + warnings.forEach { + assertTrue(it.ratio < CONTRAST_FLOOR, "${it.what}") + assertTrue(it.ratio < it.shippedRatio, "${it.what} is not actually worse than shipped") + } + } + + @Test + fun blackeningOnlyTheWindowSurfaceWarnsAboutTheTextOnIt() { + /* + * The pair that actually carries almost all the text, and the one the guard missed. + * Theme.kt maps background and surface onto windowBackground and onBackground and + * onSurface onto labelTextFill, so every label in every window sits on this pair -- + * while `base` reaches the screen only through the menu strip and the selection tint. + * Checking text against `base` alone let an operator black out every window and be + * told nothing. + */ + val blackWindows = day.copy(windowBackground = Color.Black) + + val warnings = contrastWarnings(blackWindows, day) + + assertTrue( + warnings.any { it.what == ContrastPair.TEXT_ON_WINDOW_SURFACE }, + "no warning when every label in every window went black on black: " + + "${warnings.map { it.what }}", + ) + } + + @Test + fun theAccentIsMeasuredWhereItIsActuallyDrawn() { + /* + * Material's primary is textAccent, not accent, and it is drawn as text and as tab + * underlines on the window surface -- not as `accent` on `base`. Measuring the wrong + * colour on the wrong ground answers a question nobody is asking. + */ + val invisibleAccent = day.copy(textAccent = day.windowBackground) + + val warnings = contrastWarnings(invisibleAccent, day) + + assertTrue( + warnings.any { it.what == ContrastPair.ACCENT_ON_WINDOW_SURFACE }, + "an accent identical to the surface it is drawn on did not warn: " + + "${warnings.map { it.what }}", + ) + } + + @Test + fun anImprovementDoesNotWarnEvenWhileStillUnderTheFloor() { + /* + * The evening accent ships at 2.26. An operator who moves it to something lighter has + * made things better and must not be told off for it -- that is how a guard loses its + * authority. + */ + val better = evening.copy(accent = Color.White) + + val accentWarnings = contrastWarnings(better, evening).filter { it.what == ContrastPair.ACCENT_ON_WINDOW_SURFACE } + + assertTrue(accentWarnings.isEmpty(), "an improvement warned: $accentWarnings") + } + + @Test + fun aPairThatStaysComfortablyReadableDoesNotWarn() { + // Worse than shipped but still well over the floor: nothing to say. + val slightlyWorse = day.copy(labelTextFill = Color(0xFF444444)) + + val textWarnings = contrastWarnings(slightlyWorse, day).filter { it.what.name.startsWith("TEXT") } + + assertTrue(textWarnings.isEmpty(), "a readable pair warned: $textWarnings") + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/DataTableStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/DataTableStateTest.kt new file mode 100644 index 00000000..3d248afd --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/DataTableStateTest.kt @@ -0,0 +1,559 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.snapshots.Snapshot +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertSame +import org.junit.jupiter.api.Assertions.assertTrue + +/** + * The rules of the multi-column table. + * + * Row identity, selection across a refresh and stable sorting are the three places + * where Etappe 2 lost time, and all three were found by watching the window rather + * than by a test. They are pinned here. + */ +class DataTableStateTest { + + private class Station(val callSign: String, var qrb: Int) + + private class Spot(val text: String) + + private fun stationTable() = DataTableState( + columns = listOf( + DataColumn(id = "callsign", title = "Callsign", value = { s: Station -> s.callSign }), + DataColumn( + id = "qrb", + title = "QRB", + value = { s: Station -> s.qrb.toString() }, + comparator = compareBy { s: Station -> s.qrb }, + ), + ), + rowKey = RowKeys.byValue { s: Station -> s.callSign }, + ) + + @Test + fun `the selection follows the row, not its position`() { + val table = stationTable() + val dn9apw = Station("DN9APW", 100) + table.replaceRows(listOf(dn9apw, Station("DO5AMF", 200))) + table.select(dn9apw) + + // Something arrives above it, as happens constantly in a live list. + table.replaceRows(listOf(Station("DL1ABC", 50), Station("DN9APW", 100), Station("DO5AMF", 200))) + + assertEquals("DN9APW", table.selectedRow?.callSign, + "the station the operator picked is still that station after it moved down") + } + + @Test + fun `a selected row that disappears clears the selection`() { + val table = stationTable() + val gone = Station("DN9APW", 100) + table.replaceRows(listOf(gone, Station("DO5AMF", 200))) + table.select(gone) + + table.replaceRows(listOf(Station("DO5AMF", 200))) + + assertNull(table.selectedRow, + "sliding the selection onto the neighbour would point the operator at " + + "someone they did not choose") + } + + @Test + fun `equal rows keep the order they arrived in`() { + val table = stationTable() + table.replaceRows( + listOf(Station("A", 100), Station("B", 100), Station("C", 100)), + ) + table.toggleSort("qrb") + + assertEquals( + listOf("A", "B", "C"), + table.visibleRows.map { it.callSign }, + "the sort is stable; Etappe 2 lost this and rows jumped", + ) + } + + @Test + fun `a column with a comparator sorts by it, not by its text`() { + val table = stationTable() + table.replaceRows(listOf(Station("A", 9), Station("B", 100))) + + table.toggleSort("qrb") + + assertEquals(listOf("A", "B"), table.visibleRows.map { it.callSign }, + "9 before 100 numerically; by text it would be the other way round") + } + + @Test + fun `a column without a comparator sorts by the shown text`() { + val table = stationTable() + table.replaceRows(listOf(Station("DO5AMF", 1), Station("DL1ABC", 2))) + + table.toggleSort("callsign") + + assertEquals(listOf("DL1ABC", "DO5AMF"), table.visibleRows.map { it.callSign }) + } + + @Test + fun `clicking the sorted column again reverses it`() { + val table = stationTable() + table.replaceRows(listOf(Station("A", 1), Station("B", 2))) + + table.toggleSort("qrb") + assertTrue(table.sortAscending) + + table.toggleSort("qrb") + assertFalse(table.sortAscending) + assertEquals(listOf("B", "A"), table.visibleRows.map { it.callSign }) + } + + /** + * The third click clears the sorting and puts the rows back in arrival order. JavaFX + * TableView cycles ascending, descending, unsorted for free; losing that meant an + * operator who had sorted the message list once could never get back to "newest at + * the bottom" without restarting. + */ + @Test + fun `a third click clears the sorting and restores arrival order`() { + val table = stationTable() + table.replaceRows(listOf(Station("B", 2), Station("A", 1))) + + table.toggleSort("qrb") + assertEquals(listOf("A", "B"), table.visibleRows.map { it.callSign }) + + table.toggleSort("qrb") + assertEquals(listOf("B", "A"), table.visibleRows.map { it.callSign }) + + table.toggleSort("qrb") + assertNull(table.sortedColumnId) + assertEquals(listOf("B", "A"), table.visibleRows.map { it.callSign }, "arrival order not restored") + } + + /** After clearing, the next click on the same column starts ascending again. */ + @Test + fun `sorting the same column after clearing starts over ascending`() { + val table = stationTable() + table.replaceRows(listOf(Station("B", 2), Station("A", 1))) + + table.toggleSort("qrb") + table.toggleSort("qrb") + table.toggleSort("qrb") + table.toggleSort("qrb") + + assertEquals("qrb", table.sortedColumnId) + assertTrue(table.sortAscending) + assertEquals(listOf("A", "B"), table.visibleRows.map { it.callSign }) + } + + /** Switching to another column is a fresh ascending sort, not a continuation. */ + @Test + fun `switching columns does not inherit the cycle`() { + val table = stationTable() + table.replaceRows(listOf(Station("B", 2), Station("A", 1))) + + table.toggleSort("qrb") + table.toggleSort("qrb") + table.toggleSort("callsign") + + assertEquals("callsign", table.sortedColumnId) + assertTrue(table.sortAscending) + } + + @Test + fun `an unknown column is ignored rather than clearing the sorting`() { + val table = stationTable() + table.replaceRows(listOf(Station("A", 1))) + table.toggleSort("qrb") + + table.toggleSort("a-column-this-release-no-longer-has") + + assertEquals("qrb", table.sortedColumnId, + "a stored layout naming a dropped column must not undo the sorting") + } + + @Test + fun `the sorted order is computed once, not on every read`() { + /* + * visibleRows is read on every recomposition. Sorting there means sorting up + * to thirty thousand rows per inbound message, on the thread that draws, and + * a column without a comparator would call its value function once per + * comparison on top of that. + */ + var valueCalls = 0 + val table = DataTableState( + columns = listOf( + DataColumn( + id = "callsign", + title = "Callsign", + value = { s: Station -> valueCalls++; s.callSign }, + ), + ), + rowKey = RowKeys.byValue { s: Station -> s.callSign }, + ) + table.replaceRows(listOf(Station("C", 1), Station("A", 2), Station("B", 3))) + table.toggleSort("callsign") + + table.visibleRows + val afterFirstRead = valueCalls + repeat(20) { table.visibleRows } + + assertEquals(afterFirstRead, valueCalls, + "reading the sorted rows again must not sort them again") + } + + @Test + fun `rows read once and then replaced are the new rows`() { + /* + * The regression this pins: caching the sorted order in a plain field meant + * that once the cache was warm the getter never read `rows` again, so nothing + * subscribed to it and the table went on showing what it had. On screen that + * looked like a monitor window that stayed empty while the JavaFX tab beside it + * filled up, and only redrew when an unrelated click forced it to. + */ + val table = stationTable() + table.replaceRows(listOf(Station("DN9APW", 1))) + table.toggleSort("callsign") + + assertEquals(listOf("DN9APW"), table.visibleRows.map { it.callSign }) + + table.replaceRows(listOf(Station("DN9APW", 1), Station("DO5AMF", 2))) + + assertEquals(listOf("DN9APW", "DO5AMF"), table.visibleRows.map { it.callSign }, + "a row that arrived after the first read has to be there") + } + + @Test + fun `reading the rows subscribes to them even when the order is already computed`() { + /* + * This is the defect a value-checking test cannot see. Compose repaints a + * composable when state it *read* changes. A cache that returns early stops + * reading `rows`, so the next recomposition — triggered by anything else — + * leaves the composable subscribed to nothing, and later rows never arrive on + * screen. That is what a monitor window sitting empty beside a filling JavaFX + * tab looks like, redrawing only when an unrelated click forces it. + */ + val table = stationTable() + table.replaceRows(listOf(Station("DN9APW", 1))) + table.toggleSort("callsign") + table.visibleRows + + var reads = 0 + Snapshot.observe(readObserver = { reads++ }) { table.visibleRows } + + assertTrue(reads > 0, + "a read that touches no state means the table will not repaint when the " + + "rows change") + } + + @Test + fun `changing the sorting after a read re-sorts`() { + val table = stationTable() + table.replaceRows(listOf(Station("B", 1), Station("A", 2))) + table.toggleSort("callsign") + assertEquals(listOf("A", "B"), table.visibleRows.map { it.callSign }) + + table.toggleSort("callsign") + + assertEquals(listOf("B", "A"), table.visibleRows.map { it.callSign }) + } + + @Test + fun `unsorted rows stay in the order they were given`() { + val table = stationTable() + table.replaceRows(listOf(Station("C", 3), Station("A", 1), Station("B", 2))) + + assertEquals(listOf("C", "A", "B"), table.visibleRows.map { it.callSign }) + } + + @Test + fun `two identical messages are two rows, not one`() { + /* + * The reason event lists need reference identity: a key built from their + * fields merges them, and repeating a macro is ordinary operator behaviour. + */ + val table = DataTableState( + columns = listOf(DataColumn(id = "text", title = "Message", value = { s: Spot -> s.text })), + rowKey = RowKeys.byReference(), + ) + val first = Spot("tnx om, 73") + val second = Spot("tnx om, 73") + + table.replaceRows(listOf(first, second)) + table.select(second) + + assertEquals(2, table.visibleRows.size) + assertSame(second, table.selectedRow, "the second one, not the first") + assertFalse(table.isSelected(first)) + } + + @Test + fun `the key a row is drawn under is its identity, not its position`() { + /* + * The list draws rows keyed by this. A positional key would reshuffle every + * row whenever something arrives at the top, which in a live list is constant. + */ + val table = stationTable() + val dn9apw = Station("DN9APW", 100) + table.replaceRows(listOf(dn9apw, Station("DO5AMF", 200))) + + val keyAtTop = table.keyOf(dn9apw) + + table.replaceRows(listOf(Station("DL1ABC", 50), dn9apw)) + + assertEquals(keyAtTop, table.keyOf(dn9apw), "same row, same key, new position") + } + + @Test + fun `a reference key stays with its row across a refresh`() { + val table = DataTableState( + columns = listOf(DataColumn(id = "text", title = "Message", value = { s: Spot -> s.text })), + rowKey = RowKeys.byReference(), + ) + val kept = Spot("first") + table.replaceRows(listOf(kept)) + table.select(kept) + + // The roster hands back the same instances plus a new one. + table.replaceRows(listOf(Spot("newer"), kept)) + + assertSame(kept, table.selectedRow) + } +} + +/** + * Column widths survive a restart, and the table is what remembers them. + * + * Storage is ChatPreferences.getTableColumnWidth/setTableColumnWidth, which is + * toolkit-free; only the JavaFX glue around it stays behind. The ids are part of the + * stored layout, so this is also where a renamed column loses an operator's sizing. + */ +class DataTableColumnWidthTest { + + private class Station(val callSign: String) + + private class RecordingStore : ColumnWidthStore { + val stored = mutableMapOf() + var saveRequests = 0 + + override fun width(tableId: String, columnId: String): Double? = stored["$tableId/$columnId"] + + override fun setWidth(tableId: String, columnId: String, width: Double) { + stored["$tableId/$columnId"] = width + } + + override fun requestSave() { + saveRequests++ + } + } + + private fun table(store: ColumnWidthStore) = DataTableState( + columns = listOf( + DataColumn(id = "callsign", title = "Callsign", value = { s: Station -> s.callSign }), + DataColumn(id = "qra", title = "QRA", value = { _: Station -> "" }), + ), + rowKey = RowKeys.byValue { s: Station -> s.callSign }, + tableId = "dx-cluster-monitor", + widths = store, + ) + + @Test + fun `a stored width is used`() { + val store = RecordingStore() + store.stored["dx-cluster-monitor/callsign"] = 140.0 + + assertEquals(140.0, table(store).widthOf("callsign")) + } + + @Test + fun `a column never sized yet has no stored width`() { + assertNull(table(RecordingStore()).widthOf("qra"), + "the caller falls back to the column's own weight, rather than to a " + + "number invented here") + } + + @Test + fun `resizing stores the width and asks for a save`() { + val store = RecordingStore() + val table = table(store) + + table.resizeColumn("callsign", 180.0) + + assertEquals(180.0, table.widthOf("callsign")) + assertEquals(1, store.saveRequests, + "saving is debounced by the layout autosave, not written per pixel") + } + + @Test + fun `resizing a column this table does not have is ignored`() { + val store = RecordingStore() + val table = table(store) + + table.resizeColumn("a-column-from-another-table", 180.0) + + assertTrue(store.stored.isEmpty()) + assertEquals(0, store.saveRequests) + } + + @Test + fun `a width at or below zero is refused`() { + val store = RecordingStore() + val table = table(store) + table.resizeColumn("callsign", 120.0) + + table.resizeColumn("callsign", 0.0) + + assertEquals(120.0, table.widthOf("callsign"), + "a drag past the left edge must not store a column the operator cannot " + + "grab again") + } + + @Test + fun `a table without a width store simply has no stored widths`() { + val table = DataTableState( + columns = listOf(DataColumn(id = "c", title = "C", value = { _: Station -> "" })), + rowKey = RowKeys.byValue { s: Station -> s.callSign }, + ) + + table.resizeColumn("c", 100.0) + + assertNull(table.widthOf("c"), "the two monitor tables may be built before " + + "preferences are reachable; that must not throw") + } +} + +/** + * The reference keys must not turn into a memory leak, and they are handed out from + * two threads at once. + * + * Both stores behind these tables are capped on purpose — ten thousand cluster + * messages, thirty thousand chat messages — so that memory cannot grow without bound. + * A key map holding a strong reference to every row it ever saw would undo that cap + * from the outside. + */ +class ReferenceRowKeysTest { + + private class Spot(val text: String) + + private fun table(keys: RowKeySource) = DataTableState( + columns = listOf(DataColumn(id = "text", title = "Message", value = { s: Spot -> s.text })), + rowKey = keys, + ) + + @Test + fun `keys of rows that have gone are released`() { + val keys = RowKeys.byReference() + val table = table(keys) + val first = (1..100).map { Spot("message $it") } + + table.replaceRows(first) + // Keys are handed out when the list draws, which is what this stands in for. + first.forEach { table.keyOf(it) } + assertEquals(100, keys.size(), "one key per row on screen") + + // The store trims, as ChatController does to stay inside its cap. + val remaining = first.takeLast(11) + table.replaceRows(remaining) + remaining.forEach { table.keyOf(it) } + + assertEquals(11, keys.size(), + "a key map that keeps every row it ever saw undoes the cap the store keeps") + } + + @Test + fun `a row that stays keeps its key across a refresh`() { + val keys = RowKeys.byReference() + val table = table(keys) + val kept = Spot("kept") + + table.replaceRows(listOf(kept, Spot("other"))) + val before = keys.keyOf(kept) + + table.replaceRows(listOf(Spot("newer"), kept)) + + assertEquals(before, keys.keyOf(kept), "same row, same key") + } + + @Test + fun `keys handed out from several threads at once are unique`() { + // The rows are replaced from the JavaFX thread while Compose draws on its own. + val keys = RowKeys.byReference() + val rows = (1..500).map { Spot("message $it") } + val handedOut = java.util.concurrent.ConcurrentHashMap.newKeySet() + val threads = (1..4).map { + Thread { rows.forEach { row -> handedOut.add(keys.keyOf(row)) } } + } + + threads.forEach { it.start() } + threads.forEach { it.join() } + + assertEquals(500, handedOut.size, + "two rows sharing a key make the list throw; one row with two keys makes " + + "it jump — both were seen in Etappe 2") + } +} + +/** + * Columns can be dragged into another order, as the JavaFX TableView allowed. + * + * Within the session only: JavaFX did not persist the order either — TableLayoutManager + * stores widths and ChatPreferences has no column order at all — and 1.50 is a + * functionally equal port, not an improvement on it. + */ +class ColumnOrderTest { + + private class Station(val callSign: String) + + private fun table() = DataTableState( + columns = listOf("a", "b", "c").map { id -> + DataColumn(id = id, title = id.uppercase(), value = { _: Station -> id }) + }, + rowKey = RowKeys.byValue { s: Station -> s.callSign }, + ) + + @Test + fun `columns start in the order they were declared`() { + assertEquals(listOf("a", "b", "c"), table().orderedColumns.map { it.id }) + } + + @Test + fun `a column dragged to the front lands there`() { + val table = table() + + table.moveColumn("c", 0) + + assertEquals(listOf("c", "a", "b"), table.orderedColumns.map { it.id }) + } + + @Test + fun `a column dragged to the end lands there`() { + val table = table() + + table.moveColumn("a", 2) + + assertEquals(listOf("b", "c", "a"), table.orderedColumns.map { it.id }) + } + + @Test + fun `a target outside the table is clamped rather than dropping the column`() { + val table = table() + + table.moveColumn("b", 99) + assertEquals(listOf("a", "c", "b"), table.orderedColumns.map { it.id }) + + table.moveColumn("b", -5) + assertEquals(listOf("b", "a", "c"), table.orderedColumns.map { it.id }) + } + + @Test + fun `moving a column this table does not have changes nothing`() { + val table = table() + + table.moveColumn("a-column-from-another-table", 0) + + assertEquals(listOf("a", "b", "c"), table.orderedColumns.map { it.id }) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/DirectedMessageColumnsTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/DirectedMessageColumnsTest.kt new file mode 100644 index 00000000..8729bfa8 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/DirectedMessageColumnsTest.kt @@ -0,0 +1,123 @@ +package kst4contest.view.compose + +import kst4contest.model.AirPlane +import kst4contest.model.AirPlaneReflectionInfo +import kst4contest.model.ChatCategory +import kst4contest.model.ChatMember +import kst4contest.model.ChatMessage +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * The messages addressed to this station. Its own pane above the send line, not one of + * the tabs — the operator must be able to see a private call without switching away from + * whatever tab they are reading. + */ +class DirectedMessageColumnsTest { + + private val columns = DirectedMessageColumns.all { "formatted: ${it.messageText}" } + + /** The stored column widths are keyed by these ids; renaming one loses a setting. */ + @Test + fun `the column ids are the ones the widths are stored under`() { + assertEquals( + listOf("time", "callsign", "name", "qra", "qrb", "message", "last-qrg", "airscout", "category"), + columns.map { it.id }, + ) + } + + /** The order operators read left to right, character for character from JavaFX. */ + @Test + fun `the titles are the ones on screen today`() { + assertEquals( + listOf("Time", "Callsign", "Name", "QRA", "QRB", "Message", "Last known QRG", "AP [minutes / pot%]", "Category"), + columns.map { it.title() }, + ) + } + + @Test + fun `a message from a known station fills the sender columns`() { + val message = message(sender = member("DL0ABC", name = "Hans", qra = "JO40AA")) + + assertEquals("DL0ABC", cell("callsign", message)) + assertEquals("Hans", cell("name", message)) + assertEquals("JO40AA", cell("qra", message)) + } + + /** + * A message whose sender is not in the user list any more still has to render. The + * JavaFX cells all guarded for it, and a station leaving the chat mid contest is + * normal, not exceptional. + */ + @Test + fun `a message without a sender still renders every column`() { + val message = message(sender = null) + columns.forEach { column -> + val value = column.value(message) + assertTrue(value.isNotEmpty() || value.isEmpty(), "${column.id} threw") + } + assertEquals("", cell("callsign", message)) + assertEquals("", cell("qrb", message)) + } + + @Test + fun `the message text comes from the formatter the controller provides`() { + val message = message(sender = member("DL0ABC"), text = "pse 23cm") + assertEquals("formatted: pse 23cm", cell("message", message)) + } + + /** The odd degree sign outside the bracket is JavaFX's; operators read it that way. */ + @Test + fun `the qrb cell carries the distance and the bearing`() { + val sender = member("DL0ABC").apply { + qrb = 342.7 + setQTFdirection(88.4) + } + assertEquals("342 km (88)°", cell("qrb", message(sender = sender))) + } + + /** Own messages get no distance to themselves. */ + @Test + fun `a message from the own station has no qrb`() { + val sender = member("DN9APW").apply { qrb = 0.0 } + val cols = DirectedMessageColumns.all(ownCallSign = { "DN9APW" }) { "x" } + val cell = cols.single { it.id == "qrb" }.value(message(sender = sender)) + assertEquals("", cell) + } + + @Test + fun `the airscout cell is the shared one`() { + val sender = member("DL0ABC").apply { + airPlaneReflectInfo = AirPlaneReflectionInfo().apply { + risingAirplanes = mutableListOf( + AirPlane().apply { arrivingDurationMinutes = 7; potential = 85 }, + ) + } + } + assertEquals("7 (85%)", cell("airscout", message(sender = sender))) + } + + @Test + fun `the category names the chat the message arrived in`() { + val message = message(sender = member("DL0ABC")).apply { chatCategory = ChatCategory(2) } + assertTrue(cell("category", message).isNotBlank()) + } + + private fun cell(id: String, message: ChatMessage): String = + columns.single { it.id == id }.value(message) + + private fun message(sender: ChatMember?, text: String = "hello"): ChatMessage = + ChatMessage().apply { + this.sender = sender + messageText = text + chatCategory = ChatCategory(2) + } + + private fun member(call: String, name: String = "", qra: String = ""): ChatMember = + ChatMember().apply { + setCallSign(call) + this.name = name + this.qra = qra + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/DirectedMessageRowStyleTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/DirectedMessageRowStyleTest.kt new file mode 100644 index 00000000..bdff809e --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/DirectedMessageRowStyleTest.kt @@ -0,0 +1,75 @@ +package kst4contest.view.compose + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Test + +/** + * A new private message is highlighted and the highlight fades over five minutes, so a call + * that arrived while the operator was looking elsewhere is still findable — noticing one is + * what that pane is for. Own messages get their own colour instead. + * + * The steps and the colours are PrivateMessageRowStyleResolver's and the stylesheets', which + * both designs share. + */ +class DirectedMessageRowStyleTest { + + @Test + fun `a message just arrived is brightest`() { + val accent = DirectedMessageRowStyle.accentFor(ownMessage = false, ageSeconds = 0) + assertEquals(DirectedMessageRowStyle.FRESH, accent?.background) + } + + /** Six steps, each dimmer than the last, so age is readable without reading the clock. */ + @Test + fun `the highlight fades step by step`() { + val ages = listOf(30L, 60L, 90L, 120L, 180L, 300L) + val colours = ages.map { DirectedMessageRowStyle.accentFor(false, it)?.background } + + assertEquals(ages.size, colours.distinct().size, "two steps share a colour") + colours.forEach { assertNotEquals(null, it) } + } + + /** The step boundaries are inclusive, as the resolver's `<=` is. */ + @Test + fun `a boundary age belongs to the brighter step`() { + assertEquals( + DirectedMessageRowStyle.accentFor(false, 30), + DirectedMessageRowStyle.accentFor(false, 29), + ) + assertNotEquals( + DirectedMessageRowStyle.accentFor(false, 30), + DirectedMessageRowStyle.accentFor(false, 31), + ) + } + + /** After five minutes it is no longer news and the row goes back to normal. */ + @Test + fun `an old message is not highlighted at all`() { + assertNull(DirectedMessageRowStyle.accentFor(false, 301)) + assertNull(DirectedMessageRowStyle.accentFor(false, 60 * 60)) + } + + /** Own messages are blue at any age: they are context, not news. */ + @Test + fun `an own message keeps its own colour however old`() { + assertEquals(DirectedMessageRowStyle.OWN, DirectedMessageRowStyle.accentFor(true, 0)?.background) + assertEquals(DirectedMessageRowStyle.OWN, DirectedMessageRowStyle.accentFor(true, 9999)?.background) + } + + /** The resolver in the JavaFX view decides the steps; this must not drift from it. */ + @Test + fun `the steps are the resolver's own`() { + listOf(0L, 30L, 60L, 90L, 120L, 180L, 300L).forEach { age -> + val styleClass = kst4contest.view.PrivateMessageRowStyleResolver + .resolveStyleClass(false, age) + val accent = DirectedMessageRowStyle.accentFor(false, age) + assertEquals( + styleClass != null, + accent != null, + "age $age: the resolver says $styleClass but the accent says $accent", + ) + } + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/DrawingLayerRegressionTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/DrawingLayerRegressionTest.kt new file mode 100644 index 00000000..3c7bd4c1 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/DrawingLayerRegressionTest.kt @@ -0,0 +1,207 @@ +package kst4contest.view.compose + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.width +import androidx.compose.material3.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.test.ExperimentalTestApi +import androidx.compose.ui.test.hasSetTextAction +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performScrollTo +import androidx.compose.ui.test.performTextInput +import androidx.compose.ui.test.runComposeUiTest +import androidx.compose.ui.unit.dp +import kst4contest.model.ChatPreferences +import kst4contest.view.compose.tabs.MessageHandlingTab +import kst4contest.view.compose.tabs.MessageHandlingTabState +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * The four ways the drawing layer went wrong while the build was green. + * + * Every one of these shipped in the branch at the same time as a passing suite of 382 + * tests, because not one of those tests drew anything. The state-level tests and the two + * settings coverage nets answer "was the setter called"; these answer "did it reach the + * screen", which is a different question and the one the operator asks. + * + * | Class | How it showed up | + * |---|---| + * | A control reads a non-observable value and never redraws | every keystroke in the settings was written through and not displayed | + * | A layout clips instead of wrapping | the tab strip cut "Workedstn database" mid-word | + * | Content is taller than the window and unreachable | a tab's form ended mid-way with nothing to say more was below | + * | Colours do not come from the stylesheet | the window surface took `-fx-base` instead of `derive(-fx-base, 26.4%)`; the accent was Material violet | + * + * All four run without a display: `runComposeUiTest` reaches the semantics tree headless, + * and the colour check reads the palette the theme hands out. That was measured before + * these were written, because the spec left it open and a net that only works on a + * developer's desk is worth saying so about. + */ +class DrawingLayerRegressionTest { + + private fun themed(content: @Composable () -> Unit): @Composable () -> Unit = { + Kst4ContestTheme(darkMode = false, baseFontSizeSp = 12f) { content() } + } + + // ---------------------------------------------------------------- class 1 + + @OptIn(ExperimentalTestApi::class) + @Test + fun aTypedSettingAppearsOnScreenAndNotOnlyInThePreferences() = runComposeUiTest { + val prefs = ChatPreferences() + prefs.setMessageHandling_autoAnswerTextMainCat("") + val state = MessageHandlingTabState(prefs) + + // The real tab, not a field in isolation: the fault was in the wiring between them. + setContent(themed { MessageHandlingTab(state) }) + + // MessageHandlingTab has exactly one text field, so this finder is unambiguous. + onNode(hasSetTextAction()).performTextInput("qrv 144.300") + + assertEquals( + "qrv 144.300", + prefs.getMessageHandling_autoAnswerTextMainCat(), + "the value did not reach the preferences", + ) + onNodeWithText("qrv 144.300").assertExists() + } + + // ---------------------------------------------------------------- class 2 + + private val tabTitles = listOf( + "Station", "Log synch", "TRX synch", "Airscout", "Notification", + "Message handling", "Beacon", "Shortcuts", "GUI", "Profiles", + "Workedstn database", + ) + + /** + * The strip inside a box of a given width. + * + * The width is forced with a modifier rather than by sizing the test window, which is + * what makes this a measurement instead of a does-it-crash check: the same content is + * laid out twice and the two results are compared. + */ + private fun stripAt(widthDp: Int): @Composable () -> Unit = themed { + Box(Modifier.width(widthDp.dp)) { + SettingsTabStrip( + tabs = tabTitles.map { title -> SettingsTab(title) { Text(title) } }, + selectedIndex = 0, + onSelect = {}, + ) + } + } + + @OptIn(ExperimentalTestApi::class) + @Test + fun theTabStripWrapsRatherThanSqueezingItsTitles() = runComposeUiTest { + setContent(stripAt(WIDE_ENOUGH_FOR_EVERY_TAB)) + + val wide = onNodeWithText(LONGEST_TAB).fetchSemanticsNode() + val wideWidth = wide.size.width + val wideTop = wide.positionInRoot.y + + assertTrue(wideWidth > 0, "the longest tab title was not laid out at all") + + setContent(stripAt(TOO_NARROW_FOR_ONE_ROW)) + + val narrow = onNodeWithText(LONGEST_TAB).fetchSemanticsNode() + + assertEquals( + wideWidth, + narrow.size.width, + "the tab got narrower when the row did, which means it is being squeezed " + + "instead of wrapped — that is what cut '$LONGEST_TAB' mid-word", + ) + assertTrue( + narrow.positionInRoot.y > wideTop, + "eleven tabs fitted on one line at $TOO_NARROW_FOR_ONE_ROW dp, so nothing " + + "was measured; pick a narrower width", + ) + } + + // ---------------------------------------------------------------- class 3 + + @OptIn(ExperimentalTestApi::class) + @Test + fun aFormTallerThanTheWindowCanStillBeReached() = runComposeUiTest { + val fieldCount = 40 + val lastLabel = "field $fieldCount" + + setContent( + themed { + // The window's own scroll region, with content that cannot possibly fit. + SettingsContent( + tabs = listOf( + SettingsTab("Tall") { + Column { + (1..fieldCount).forEach { Text("field $it", Modifier.height(40.dp)) } + } + }, + ), + notices = SettingsNotices(), + buttons = {}, + close = {}, + ) + } + ) + + /* + * performScrollTo fails if nothing in the chain scrolls. That is exactly the fault: + * each tab used to scroll for itself, so content simply ended mid-form with no + * scrollbar and no way down. + */ + onNodeWithText(lastLabel).performScrollTo().assertExists() + } + + // ---------------------------------------------------------------- class 4 + + @Test + fun theWindowSurfaceIsDerivedFromTheBaseAndNotTheBaseItself() { + val evening = JavaFxStylesheet.read("/KST4ContestDefaultEvening.css") + + /* + * The fault was taking -fx-base for the window surface. The sheets derive it, and + * the two are visibly different greys — which is why the first Compose windows + * looked flat against the JavaFX ones beside them. + */ + assertTrue( + evening.windowBackground != evening.base, + "the window surface is the raw base colour again", + ) + } + + @Test + fun theAccentComesFromTheStylesheetAndNotFromMaterial() { + val evening = JavaFxStylesheet.read("/KST4ContestDefaultEvening.css") + val day = JavaFxStylesheet.read("/KST4ContestDefaultDay.css") + + /* + * Material's default primary is a violet (#6650a4 family). The sheets name their + * own accent, and the two sheets name different ones — so a palette that agreed + * with Material, or a palette that was the same in both sheets, would mean the + * stylesheet is not being read. + */ + val materialViolet = androidx.compose.ui.graphics.Color(0xFF6650A4) + + assertTrue(evening.accent != materialViolet, "the accent is Material's, not the sheet's") + assertTrue(day.accent != materialViolet, "the accent is Material's, not the sheet's") + assertTrue( + evening.accent != day.accent || evening.base != day.base, + "both sheets produced the same palette, so neither was really read", + ) + } + + private companion object { + const val LONGEST_TAB = "Workedstn database" + + /** Comfortably more than the eleven tabs need, so none of them wraps. */ + const val WIDE_ENOUGH_FOR_EVERY_TAB = 2000 + + /** Narrow enough that the row must break; the wrap is the point of the test. */ + const val TOO_NARROW_FOR_ONE_ROW = 300 + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/EditableListStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/EditableListStateTest.kt new file mode 100644 index 00000000..c0f69146 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/EditableListStateTest.kt @@ -0,0 +1,220 @@ +package kst4contest.view.compose + +import kst4contest.observe.SimpleRoster +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNotEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertSame +import org.junit.jupiter.api.Assertions.assertTrue + +class EditableListStateTest { + + @Test + fun `a new entry lands at the top and becomes the selection`() { + val state = EditableListState(listOf("alt")) + + state.addAtTop("neu") + + assertEquals(listOf("neu", "alt"), state.texts) + assertEquals(0, state.selectedIndex, + "the JavaFX table selected row 0 and opened it for editing") + } + + @Test + fun `an entry edited to blank disappears`() { + val state = EditableListState(listOf("a", "b", "c")) + + state.updateAt(1, " ") + + assertEquals(listOf("a", "c"), state.texts, + "clearing the text was how the operator removed an entry") + } + + @Test + fun `an edit keeps the other entries and their order`() { + val state = EditableListState(listOf("a", "b", "c")) + + state.updateAt(1, "B") + + assertEquals(listOf("a", "B", "c"), state.texts) + } + + @Test + fun `removing the last entry clears the selection`() { + val state = EditableListState(listOf("a")) + + state.select(0) + state.removeAt(0) + + assertEquals(emptyList(), state.texts) + assertNull(state.selectedIndex) + } + + @Test + fun `an index outside the list is ignored`() { + val state = EditableListState(listOf("a")) + + state.updateAt(5, "x") + state.removeAt(-1) + + assertEquals(listOf("a"), state.texts, + "a stale index from a pending edit must not corrupt the list") + } + + @Test + fun `every entry keeps a stable key across an insertion at the top`() { + val state = EditableListState(listOf("a", "b")) + val keyOfA = state.entries[0].key + + state.addAtTop("neu") + + assertEquals(keyOfA, state.entries[1].key, + "a row must keep its key when another is inserted above it, or the " + + "selection jumps in a LazyColumn") + } + + @Test + fun `duplicate texts get distinct keys`() { + val state = EditableListState(listOf("gleich", "gleich")) + + assertNotEquals(state.entries[0].key, state.entries[1].key, + "keying by text would collapse duplicates into one row") + } + + @Test + fun `committing fills the existing roster instead of replacing it`() { + val roster = SimpleRoster() + roster.add("alt") + val state = EditableListState(listOf("neu")) + + state.commitTo(roster) + + assertEquals(listOf("neu"), roster.snapshot()) + assertSame(roster, roster, + "replacing the roster would orphan every listener registered on it") + } + + @Test + fun `a new entry can also be appended`() { + val state = EditableListState(listOf("a")) + + state.addAtBottom("b") + + assertEquals(listOf("a", "b"), state.texts, + "the monitoring list appended: chatcontroller.getLstNotify_...().add(call)") + assertEquals(1, state.selectedIndex) + } + + @Test + fun `moving the selection down swaps it with the entry below`() { + val state = EditableListState(listOf("a", "b", "c")) + state.select(0) + + assertTrue(state.moveSelected(1)) + + assertEquals(listOf("b", "a", "c"), state.texts) + assertEquals(1, state.selectedIndex, "the moved row stays selected") + } + + @Test + fun `moving the selection up swaps it with the entry above`() { + val state = EditableListState(listOf("a", "b", "c")) + state.select(2) + + assertTrue(state.moveSelected(-1)) + + assertEquals(listOf("a", "c", "b"), state.texts) + assertEquals(1, state.selectedIndex) + } + + @Test + fun `a move past either end changes nothing`() { + val state = EditableListState(listOf("a", "b")) + + state.select(0) + assertFalse(state.moveSelected(-1)) + + state.select(1) + assertFalse(state.moveSelected(1)) + + assertEquals(listOf("a", "b"), state.texts) + } + + @Test + fun `a move without a selection changes nothing`() { + val state = EditableListState(listOf("a", "b")) + + assertFalse(state.moveSelected(1)) + + assertEquals(listOf("a", "b"), state.texts) + } + + @Test + fun `committing an edit stores the text when no rule objects`() { + val state = EditableListState(listOf("a", "b")) + + val outcome = state.commitAt(1, "B") + + assertEquals(CommitOutcome.Stored("B"), outcome) + assertEquals(listOf("a", "B"), state.texts) + } + + @Test + fun `committing a blank text removes the entry`() { + val state = EditableListState(listOf("a", "b")) + + val outcome = state.commitAt(1, " ") + + assertEquals(CommitOutcome.Removed, outcome) + assertEquals(listOf("a"), state.texts) + } + + @Test + fun `a rule may rewrite the committed text`() { + val upperCase = EntryRule { candidate, _, _ -> + if (candidate.isBlank()) CommitOutcome.Removed + else CommitOutcome.Stored(candidate.uppercase()) + } + val state = EditableListState(listOf("dn9apw"), upperCase) + + state.commitAt(0, "do5amf") + + assertEquals(listOf("DO5AMF"), state.texts) + } + + @Test + fun `a refused edit leaves the stored text alone`() { + val noB = EntryRule { candidate, _, _ -> + if (candidate == "b") CommitOutcome.Refused("no b here") else CommitOutcome.Stored(candidate) + } + val state = EditableListState(listOf("a"), noB) + + val outcome = state.commitAt(0, "b") + + assertEquals(CommitOutcome.Refused("no b here"), outcome) + assertEquals(listOf("a"), state.texts, + "the JavaFX table refreshed the cell back to the stored value") + } + + @Test + fun `a rule sees the other entries but not the row being edited`() { + var seen: List? = null + val rule = EntryRule { candidate, _, others -> seen = others; CommitOutcome.Stored(candidate) } + val state = EditableListState(listOf("a", "b", "c"), rule) + + state.commitAt(1, "b") + + assertEquals(listOf("a", "c"), seen, + "the duplicate check skipped the edited row, or renaming it to itself would fail") + } + + @Test + fun `committing on a vanished row is ignored`() { + val state = EditableListState(listOf("a")) + + assertEquals(CommitOutcome.Ignored, state.commitAt(7, "x")) + assertEquals(listOf("a"), state.texts) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/JavaFxStylesheetTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/JavaFxStylesheetTest.kt new file mode 100644 index 00000000..f79ea56d --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/JavaFxStylesheetTest.kt @@ -0,0 +1,340 @@ +package kst4contest.view.compose + +import androidx.compose.ui.graphics.Color +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue + +/** + * The colours the Compose windows show come from here, and nothing that renders is + * covered by a test. This class is where that gap is closed: the reader takes plain + * text and gives plain values. + */ +class JavaFxStylesheetTest { + + private fun hex(color: Color): String = String.format( + "#%02X%02X%02X", + Math.round(color.red * 255), + Math.round(color.green * 255), + Math.round(color.blue * 255), + ) + + @Test + fun `derive gives the values JavaFX gives`() { + /* + * A handful of values spelled out, so the most-used derivations are readable + * here rather than only in a data file. The full comparison against JavaFX + * lives in `derive matches the frozen JavaFX reference`. + */ + val expected = mapOf( + ("#373E43" to 26.4) to "#525B61", + ("#373E43" to 35.0) to "#5B646A", + ("#373E43" to -20.0) to "#2C3236", + ("#ECECEC" to 26.4) to "#F4F4F4", + ("#ECECEC" to -20.0) to "#BDBDBD", + ("#FFFFFF" to -30.0) to "#B2B2B2", + ) + + expected.forEach { (input, want) -> + val (rgb, percent) = input + + /* + * Compared with a tolerance of one step per channel. derive(white, -30%) + * lands on 0.7 * 255 = 178.5 exactly, and the two paths round that half + * step differently; a test that flips on a half step pins nothing useful. + */ + assertChannelsClose(want, JavaFxStylesheet.derive(parse(rgb), percent), + "derive($rgb, $percent%)") + /* + * No live JavaFX comparison here. It lives in the frozen reference data + * instead (javafx-derive-reference.txt), because a reflection call into + * com.sun.javafx stops working when JavaFX is removed and would take the + * only real check with it. + */ + } + } + + @Test + fun `the window background is not the base colour`() { + val palette = JavaFxStylesheet.read("/KST4ContestDefaultEvening.css") + + assertEquals("#373E43", hex(palette.base)) + assertEquals("#525B61", hex(palette.windowBackground), + "Modena paints a window with derive(-fx-base, 26.4%), not with -fx-base; " + + "taking the base raw made the Compose window visibly darker than the " + + "JavaFX one beside it", + ) + } + + @Test + fun `the evening sheet gives its declared colours`() { + val palette = JavaFxStylesheet.read("/KST4ContestDefaultEvening.css") + + assertEquals("#373E43", hex(palette.base), "-fx-base") + assertEquals("#1E74C6", hex(palette.accent), "-fx-accent") + assertEquals("#D3D3D3", hex(palette.labelTextFill), ".label -fx-text-fill is lightgray") + assertEquals("#3C3C3C", hex(palette.separatorLine), ".separator *.line") + assertEquals("#FF0000", hex(palette.buttonPressedBorder), ".button:pressed") + assertEquals(12f, palette.fontSizePx) + } + + @Test + fun `the control interior resolves its reference before deriving`() { + val palette = JavaFxStylesheet.read("/KST4ContestDefaultEvening.css") + + assertEquals( + hex(JavaFxStylesheet.derive(palette.base, 35.0)), + hex(palette.controlInnerBackground), + "-fx-control-inner-background is derive(-fx-base, 35%): the reference to " + + "-fx-base has to be looked up in the same sheet first", + ) + } + + @Test + fun `the accent is the green of the field text, not the declared accent`() { + val evening = JavaFxStylesheet.read("/KST4ContestDefaultEvening.css") + val day = JavaFxStylesheet.read("/KST4ContestDefaultDay.css") + + assertEquals("#1E74C6", hex(evening.accent), + "-fx-accent stays what the sheet says; it drives the JavaFX selection bar") + + // green (#008000) and lightgreen (#90EE90), averaged. + assertEquals("#48B748", hex(evening.textAccent), + ".text-field .text is what the operator reads as the accent") + assertEquals("#48B748", hex(day.textAccent), + "both sheets declare the same rule, so the accent does not change with " + + "the design") + } + + @Test + fun `the hover gradient keeps its stops in order`() { + val palette = JavaFxStylesheet.read("/KST4ContestDefaultEvening.css") + + assertTrue(palette.buttonHoverGradient.size >= 2, + "the sheet declares linear-gradient(#f0ff35, #a9ff00)") + assertEquals("#F0FF35", hex(palette.buttonHoverGradient[0])) + assertEquals("#A9FF00", hex(palette.buttonHoverGradient[1])) + } + + @Test + fun `the daylight sheet falls back to Modena`() { + val palette = JavaFxStylesheet.read("/KST4ContestDefaultDay.css") + + // It declares only a font size and a few button rules; everything else is + // JavaFX's own default theme. + assertEquals("#ECECEC", hex(palette.base)) + assertEquals("#0096C9", hex(palette.accent)) + assertEquals("#FFFFFF", hex(palette.controlInnerBackground)) + assertEquals("#000000", hex(palette.labelTextFill)) + assertEquals(12f, palette.fontSizePx) + } + + @Test + fun `the daylight sheet still carries its own button rules`() { + val palette = JavaFxStylesheet.read("/KST4ContestDefaultDay.css") + + assertEquals("#FF0000", hex(palette.buttonPressedBorder), + "the daylight sheet declares .button:pressed too") + } + + @Test + fun `an absent sheet yields the defaults instead of failing`() { + val palette = JavaFxStylesheet.read("/there-is-no-such-sheet.css") + + assertEquals("#ECECEC", hex(palette.base), + "a missing stylesheet must not stop a window from opening") + } + + + /** Each channel within one step of the expected colour. */ + private fun assertChannelsClose(expected: String, actual: Color, message: String) { + val want = parse(expected) + + listOf( + Triple("red", want.red, actual.red), + Triple("green", want.green, actual.green), + Triple("blue", want.blue, actual.blue), + ).forEach { (channel, wanted, got) -> + assertEquals( + Math.round(wanted * 255).toDouble(), + Math.round(got * 255).toDouble(), + 1.0, + "$message: $channel", + ) + } + } + + /** The reference pairs, as `(rgbHex, percent, expectedRgbHex)`. */ + private fun referencePairs(): List> { + val resource = javaClass.getResourceAsStream("/javafx-derive-reference.txt") + ?: error("javafx-derive-reference.txt is missing from the test resources") + + /* + * Comment lines begin with "# "; a data line begins with "#" followed straight + * by hex. The header's format line contains semicolons too, so filtering on + * those would read it as data. + */ + return resource.bufferedReader().readLines() + .filterNot { it.isBlank() || it.startsWith("# ") } + .map { line -> + val (rgb, percent, expected) = line.split(";") + Triple(rgb, percent.toDouble(), expected) + } + } + + /** + * The one colour this reimplementation does not reproduce exactly. + * + * Found by widening the reference data past the greys the old pin covered. Every + * grey and both stylesheet bases match JavaFX to within the rounding tolerance; + * this saturated blue drifts by up to three steps per channel. + * + * Why that is tolerable, checked rather than assumed. derive() has four callers: + * `Theme.kt:86` and `JavaFxStylesheet` lines 96 and 106 all pass the window + * background or `-fx-base`, which are near grey. The fourth is the CSS parser at + * `JavaFxStylesheet:249`, which passes whatever colour a sheet names inside a + * `derive(...)` expression — and **every** such expression in both shipped sheets + * derives from `-fx-base` and nothing else. So no saturated colour reaches derive() + * today. + * + * That is a fact about the sheets as they are, not a guarantee. Etappe 8 of the + * migration makes the colours operator-editable; a sheet with `derive(#4da6ff, 20%)` + * in it would walk straight into this. Revisit then. + * + * Named rather than removed from the data: the data records what JavaFX does, and + * hiding the pairs that disagree would turn the record into a flattering one. + */ + private val knownDivergentColour = "#4da6ff" + + /** + * derive() against the values JavaFX itself produced. + * + * Against checked-in data rather than a live reflection call, because the live call + * disappears with JavaFX and would take the only real check with it — leaving a + * test that compares derive() to derive(). + */ + @Test + fun `derive matches the frozen JavaFX reference`() { + val pairs = referencePairs() + + assertTrue(pairs.size >= 100) { "only ${pairs.size} reference pairs; the file looks truncated" } + + pairs.filterNot { (rgb, _, _) -> rgb == knownDivergentColour } + .forEach { (rgb, percent, expected) -> + assertChannelsClose( + expected, + JavaFxStylesheet.derive(parse(rgb), percent), + "derive($rgb, $percent%)", + ) + } + } + + /** + * The known divergence, pinned so it cannot grow unnoticed. + * + * Three steps per channel is small enough to leave alone for a colour derive() is + * never called with. It is not small enough to stop measuring: a later change that + * widened it, or that started calling derive() with saturated colours, should fail + * here rather than go unseen. + */ + @Test + fun `the known divergence from JavaFX stays within three steps`() { + val divergent = referencePairs().filter { (rgb, _, _) -> rgb == knownDivergentColour } + + assertTrue(divergent.isNotEmpty()) { "the reference data no longer covers $knownDivergentColour" } + + divergent.forEach { (rgb, percent, expected) -> + val got = JavaFxStylesheet.derive(parse(rgb), percent) + val want = parse(expected) + listOf( + "red" to (want.red to got.red), + "green" to (want.green to got.green), + "blue" to (want.blue to got.blue), + ).forEach { (channel, values) -> + val (wanted, actual) = values + val delta = Math.abs(Math.round(wanted * 255) - Math.round(actual * 255)) + assertTrue(delta <= 3) { + "derive($rgb, $percent%): $channel is $delta steps from JavaFX, was at most 3" + } + } + } + } + + /** + * Writes the reference data the frozen test compares against. + * + * A generator, not an assertion: it runs once, while JavaFX is still on the + * classpath, and its output is checked in. Kept rather than deleted so the + * provenance of the data stays readable — the values come from + * com.sun.javafx.util.Utils.deriveColor and from nowhere else, which is the whole + * point of pinning them. + * + * To regenerate: remove @Disabled, run, restore @Disabled. + */ + @org.junit.jupiter.api.Disabled("generator; run by hand while JavaFX is present") + @Test + fun `generate the JavaFX reference data`() { + /* + * The greys are chosen for where they land on the brightness staircase + * deriveColor switches on — 0.2, 0.3, 0.4, 0.5, 0.6 and 0.85 of + * 0.3R + 0.59G + 0.11B — and two of them are there because mutation testing + * showed the first set left holes: + * + * #e0e0e0 (0.878) sits above the 0.85 step but, unlike white and #f4f4f4, + * has room left to brighten, so changing that branch's 1.6 factor moves it + * further than the rounding tolerance. Without it, 1.6 could become 1.5 and + * every test stayed green. + * + * #606060 (0.376) and #5a5a5a (0.353) sit between the 0.3 and 0.4 steps, + * which nothing else covered: the 0.4 threshold could be moved to 0.35 + * unnoticed. + */ + val colours = listOf( + "#ffffff", "#000000", "#ececec", "#373e43", "#1d1d1d", "#4da6ff", + "#2b2b2b", "#808080", "#333333", "#4d4d4d", "#666666", "#999999", + "#d9d9d9", "#f4f4f4", "#63067a", "#ff9900", + "#e0e0e0", "#eeeeee", "#606060", "#5a5a5a", "#707070", "#454545", + ) + val percents = listOf(-80.0, -50.0, -35.0, -30.0, -10.0, 10.0, 26.4, 35.0, 50.0, 80.0) + + val lines = buildList { + for (rgb in colours) { + for (percent in percents) { + add("$rgb;$percent;${deriveWithJavaFx(rgb, percent)}") + } + } + } + + val target = java.io.File("src/test/resources/javafx-derive-reference.txt") + target.parentFile.mkdirs() + target.writeText( + "# Generated from com.sun.javafx.util.Utils.deriveColor by\n" + + "# JavaFxStylesheetTest.`generate the JavaFX reference data`.\n" + + "# Format: ;;\n" + + lines.joinToString("\n") + "\n" + ) + println("wrote ${lines.size} pairs to ${target.absolutePath}") + } + + private fun deriveWithJavaFx(rgb: String, percent: Double): String { + val fxColor = Class.forName("javafx.scene.paint.Color") + val utils = Class.forName("com.sun.javafx.util.Utils") + val source = fxColor.getMethod("web", String::class.java).invoke(null, rgb) + val result = utils + .getMethod("deriveColor", fxColor, Double::class.javaPrimitiveType) + .invoke(null, source, percent / 100.0) + + return hex( + Color( + (fxColor.getMethod("getRed").invoke(result) as Double).toFloat(), + (fxColor.getMethod("getGreen").invoke(result) as Double).toFloat(), + (fxColor.getMethod("getBlue").invoke(result) as Double).toFloat(), + ) + ) + } + + private fun parse(rgb: String): Color { + val value = rgb.removePrefix("#").toLong(16) + return Color(0xFF000000L or value) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/MainMenuModelTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/MainMenuModelTest.kt new file mode 100644 index 00000000..6014d611 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/MainMenuModelTest.kt @@ -0,0 +1,184 @@ +package kst4contest.view.compose + +import kst4contest.view.i18n.Strings +import kst4contest.view.i18n.Translations +import kst4contest.controller.On4KstConnectionState +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * The menus, their labels and which of them can be used. + * + * None of this was covered while the bar was declared straight into Compose's `MenuBar`: + * the structure only existed inside a composable, so it took a running window to look at. + * It is now a plain function of the state, and these are the parts that go wrong silently — + * a label that stops following the away state, an item that stays usable while the station + * is not in the chat, or a menu that loses an entry when a second renderer is added. + */ +class MainMenuModelTest { + + private class RecordingActions : MainMenuActions { + val calls = mutableListOf() + override fun connect() { calls += "connect" } + override fun disconnect() { calls += "disconnect" } + override fun switchOperatorProfile() { calls += "switchOperatorProfile" } + override fun exitApplication() { calls += "exitApplication" } + override fun setQrgAsNameInChat() { calls += "setQrgAsNameInChat" } + override fun toggleAwayState() { calls += "toggleAwayState" } + override fun toggleSettingsWindow() { calls += "toggleSettingsWindow" } + override fun toggleMonitorWindow() { calls += "toggleMonitorWindow" } + override fun toggleStationMap() { calls += "toggleStationMap" } + override fun useDarkDesign() { calls += "useDarkDesign" } + override fun useDefaultDesign() { calls += "useDefaultDesign" } + override fun openDonationPage() { calls += "openDonationPage" } + override fun openHomepage() { calls += "openHomepage" } + override fun openNewsgroup() { calls += "openNewsgroup" } + override fun openChangelog() { calls += "openChangelog" } + override fun openOv3tDonationPage() { calls += "openOv3tDonationPage" } + override fun contactAuthor() { calls += "contactAuthor" } + override fun showAbout() { calls += "showAbout" } + } + + private fun model( + connectionState: On4KstConnectionState = On4KstConnectionState.DISCONNECTED, + away: Boolean = false, + settingsOpen: Boolean = false, + monitorOpen: Boolean = false, + actions: MainMenuActions = RecordingActions(), + ): List { + val state = MainMenuState() + state.connectionState = connectionState + state.awayFromChat = away + return mainMenuModel(state, actions, settingsOpen, monitorOpen, baseStrings()) + } + + /* + * The base language's texts, built here rather than taken from a store: these tests + * assert over real titles ("File", "Options"), and a store would make them depend on + * whichever language ran last in the shared JVM. + */ + private fun baseStrings(): Strings { + val base = Translations.BY_LANGUAGE.getValue(Translations.BASE_LANGUAGE) + return Strings { key -> base[key] ?: key } + } + + private fun items(menu: MenuSpec) = menu.entries.filterIsInstance() + + private fun labels(menu: MenuSpec) = items(menu).map { it.label } + + private fun item(model: List, label: String): MenuEntry.Item = + model.flatMap { items(it) }.single { it.label == label } + + @Test + fun theFourMenusAppearInTheOrderTheyAlwaysHad() { + assertEquals(listOf("File", "Options", "Windows", "Info"), model().map { it.title }) + } + + @Test + fun noMenuIsEmptyAndTheSeparatorsSurviveTheTranslation() { + val model = model() + + model.forEach { menu -> + assertTrue(items(menu).isNotEmpty(), "menu '${menu.title}' has no items") + } + + // Windows has two separators, Info one. A renderer that drops them makes the + // design switch read as just another window toggle. + assertEquals(2, model.single { it.title == "Windows" }.entries.count { it is MenuEntry.Separator }) + assertEquals(1, model.single { it.title == "Info" }.entries.count { it is MenuEntry.Separator }) + } + + @Test + fun theConnectItemCarriesTheStatesOwnLabel() { + val state = MainMenuState() + state.connectLabel = "Connect to 144/432 MHz" + + val model = mainMenuModel(state, RecordingActions(), false, false, baseStrings()) + + assertEquals( + "Connect to 144/432 MHz", + labels(model.single { it.title == "File" }).first(), + "the label names the chat the station lands in; it must not be hardcoded here", + ) + } + + @Test + fun connectAndDisconnectAreNeverBothUsable() { + for (connectionState in On4KstConnectionState.values()) { + val model = model(connectionState = connectionState) + val connect = model.flatMap { items(it) }.first() + val disconnect = item(model, "Disconnect") + + assertFalse( + connect.enabled && disconnect.enabled, + "both were usable while $connectionState", + ) + assertTrue( + connect.enabled || disconnect.enabled, + "neither was usable while $connectionState, which would strand the operator", + ) + } + } + + @Test + fun theChatActionsNeedASessionThatIsReallyOnline() { + val offline = model(connectionState = On4KstConnectionState.CONNECTING) + + // Logging in is not being in the chat: a command sent then goes nowhere. + assertFalse(item(offline, "Set QRG as name in Chat (main category)").enabled) + assertFalse(item(offline, "Show me as AWAY FROM chat!").enabled) + } + + @Test + fun theAwayLabelNamesTheNextActionAndFollowsTheState() { + assertEquals( + "Show me as AWAY FROM chat!", + item(model(away = false), "Show me as AWAY FROM chat!").label, + ) + assertEquals( + "Show me as ACTIVE in chat!", + item(model(away = true), "Show me as ACTIVE in chat!").label, + ) + } + + @Test + fun theWindowTogglesSayWhatPressingThemWillDo() { + /* + * "Show options" with a capital S in both menus. The JavaFX wording had it capital in + * the Options menu and lower case in the Windows menu for the same action; pulling + * both onto one key settled that, and in German the two would have been identical + * anyway. + */ + val closed = model(settingsOpen = false, monitorOpen = false) + assertTrue(labels(closed.single { it.title == "Windows" }).any { it == "Show options" }) + assertTrue( + labels(closed.single { it.title == "Windows" }) + .any { it == "Show cluster / stranger QSOs" }, + ) + + val open = model(settingsOpen = true, monitorOpen = true) + assertTrue(labels(open.single { it.title == "Windows" }).any { it == "hide options" }) + assertTrue( + labels(open.single { it.title == "Windows" }) + .any { it == "Hide cluster / stranger QSOs" }, + ) + } + + @Test + fun everyItemIsWiredToSomething() { + val actions = RecordingActions() + val model = model(connectionState = On4KstConnectionState.ONLINE, actions = actions) + + model.flatMap { items(it) }.forEach { it.onClick() } + + // One click each, and nothing silently wired to an empty lambda: the JavaFX bar had + // an item whose handler was commented out, and it looked exactly like the others. + assertEquals( + model.flatMap { items(it) }.size, + actions.calls.size, + "every item must reach an action; one of them did nothing", + ) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/MainMenuRowStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/MainMenuRowStateTest.kt new file mode 100644 index 00000000..fc34b02d --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/MainMenuRowStateTest.kt @@ -0,0 +1,83 @@ +package kst4contest.view.compose + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * Which menu of the in-window row is open. + * + * Small, but it carries one thing that is not cosmetic: [MainMenuRowState.anyOpen] is what + * keeps the window-wide keys out of the way while a menu is down. `MainWindow` hangs + * `WindowShortcuts.handle` on the window's `onPreviewKeyEvent`, and a preview runs *before* + * its children — so without this, pressing Escape to dismiss a menu would first clear the + * operator's half-typed message. + */ +class MainMenuRowStateTest { + + @Test + fun nothingIsOpenToStartWith() { + val state = MainMenuRowState() + + assertNull(state.openMenu) + assertFalse(state.anyOpen) + } + + @Test + fun aTitleOpensItsOwnMenu() { + val state = MainMenuRowState() + + state.toggle("File") + + assertEquals("File", state.openMenu) + assertTrue(state.anyOpen) + } + + @Test + fun theSameTitleAgainClosesIt() { + val state = MainMenuRowState() + state.toggle("File") + + state.toggle("File") + + assertNull(state.openMenu, "pressing the open menu's own title must close it") + assertFalse(state.anyOpen) + } + + @Test + fun anotherTitleSwitchesRatherThanStacking() { + val state = MainMenuRowState() + state.toggle("File") + + state.toggle("Info") + + // Two menus down at once is a thing no menu bar does. + assertEquals("Info", state.openMenu) + } + + @Test + fun closeAlwaysEndsUpClosedAndIsIdempotent() { + val state = MainMenuRowState() + state.toggle("Windows") + + state.close() + state.close() + + assertNull(state.openMenu) + assertFalse(state.anyOpen) + } + + @Test + fun anItemBeingPickedClosesTheMenu() { + val state = MainMenuRowState() + state.toggle("Options") + var ran = false + + state.pick { ran = true } + + assertTrue(ran, "the action must run") + assertNull(state.openMenu, "a picked item must close the menu it came from") + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/MainMenuStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/MainMenuStateTest.kt new file mode 100644 index 00000000..94d506ad --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/MainMenuStateTest.kt @@ -0,0 +1,113 @@ +package kst4contest.view.compose + +import kst4contest.view.i18n.Strings +import kst4contest.view.i18n.Translations +import kst4contest.controller.On4KstConnectionState +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue + +/** + * Which menu items can be used, and when. + * + * A menu item that merely looks usable is a worse place for a stale value than a form + * field: the operator presses it in the middle of a contest and nothing happens, or + * the wrong thing does. The JavaFX window drove these from onConnectionStateChanged. + */ +class MainMenuStateTest { + + @Test + fun `disconnected - connect is offered, disconnect is not`() { + val menu = MainMenuState() + + menu.connectionState = On4KstConnectionState.DISCONNECTED + + assertTrue(menu.canConnect) + assertFalse(menu.canDisconnect) + } + + @Test + fun `while connecting, connect is no longer offered`() { + val menu = MainMenuState() + + menu.connectionState = On4KstConnectionState.AUTHENTICATING + + assertFalse(menu.canConnect, "a second attempt while one is running helps nobody") + assertTrue(menu.canDisconnect, "the attempt can be given up") + } + + @Test + fun `online - disconnect yes, connect no`() { + val menu = MainMenuState() + + menu.connectionState = On4KstConnectionState.ONLINE + + assertFalse(menu.canConnect) + assertTrue(menu.canDisconnect) + } + + @Test + fun `the chat actions need a session that is really online`() { + val menu = MainMenuState() + + menu.connectionState = On4KstConnectionState.AUTHENTICATING + assertFalse(menu.canUseChatActions, + "logging in is not being in the chat; /AWAY would go nowhere") + + menu.connectionState = On4KstConnectionState.ONLINE + assertTrue(menu.canUseChatActions) + } + + @Test + fun `switching profiles and leaving are always possible`() { + val menu = MainMenuState() + menu.connectionState = On4KstConnectionState.DISCONNECTED + + assertTrue(menu.canSwitchProfile) + assertTrue(menu.canExit, "an operator must always be able to leave") + } + + @Test + fun `an unknown state is treated as disconnected`() { + val menu = MainMenuState() + + assertTrue(menu.canConnect, "before the first callback there is no session") + assertFalse(menu.canDisconnect) + } + + /** + * The away item's own label is the only place the AFK state is visible at all — there + * is no other indicator for it. It names the next action: away when active, active when + * away. JavaFX flipped setText() inside the handler; here it follows the state, so it + * is right even when the state changes from elsewhere. + */ + /* + * The base language's texts, built here rather than taken from a store: this test asserts + * over the real English wording, and a store would make it depend on whichever language + * ran last in the shared JVM. + */ + private fun baseStrings(): Strings { + val base = Translations.BY_LANGUAGE.getValue(Translations.BASE_LANGUAGE) + return Strings { key -> base[key] ?: key } + } + + @Test + fun `the away item says what pressing it will do`() { + val state = MainMenuState() + + val strings = baseStrings() + + state.awayFromChat = false + assertEquals("Show me as AWAY FROM chat!", state.awayMenuLabel(strings)) + + state.awayFromChat = true + assertEquals("Show me as ACTIVE in chat!", state.awayMenuLabel(strings)) + } + + /** Nobody is away before the session exists. */ + @Test + fun `a fresh session is not away`() { + assertFalse(MainMenuState().awayFromChat) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/MainWindowFrameTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/MainWindowFrameTest.kt new file mode 100644 index 00000000..ae353538 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/MainWindowFrameTest.kt @@ -0,0 +1,158 @@ +package kst4contest.view.compose + +import kst4contest.controller.On4KstConnectionState +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * The frame around the main window: how big it opens, and what its title says. + * + * Pure arithmetic and string building, which is why it is tested here rather than looked + * at. The clamp exists because a window remembered from a larger monitor opens + * unusable — its buttons off-screen, and no way to reach them. + */ +class MainWindowFrameTest { + + @Test + fun `a remembered size is used as it is when it fits`() { + val size = MainWindowFrame.startupSize( + stored = doubleArrayOf(768.0, 1234.0), + screenHeight = 1440.0, + screenWidth = 2560.0, + ) + assertEquals(768.0, size.heightDp) + assertEquals(1234.0, size.widthDp) + } + + /** The margin leaves room for the window decoration and the screen edge. */ + @Test + fun `a window remembered from a larger screen is cut down to fit`() { + val size = MainWindowFrame.startupSize( + stored = doubleArrayOf(1400.0, 3000.0), + screenHeight = 1080.0, + screenWidth = 1920.0, + ) + assertEquals(1040.0, size.heightDp) + assertEquals(1880.0, size.widthDp) + } + + @Test + fun `no remembered size at all opens at the default`() { + val size = MainWindowFrame.startupSize(null, screenHeight = 1440.0, screenWidth = 2560.0) + assertEquals(768.0, size.heightDp) + assertEquals(1234.0, size.widthDp) + } + + @Test + fun `a half written size falls back per dimension`() { + val size = MainWindowFrame.startupSize( + stored = doubleArrayOf(0.0, 1500.0), + screenHeight = 1440.0, + screenWidth = 2560.0, + ) + assertEquals(768.0, size.heightDp, "a stored zero height should fall back") + assertEquals(1500.0, size.widthDp, "a usable stored width should survive") + } + + @Test + fun `an unusable stored array falls back entirely`() { + assertEquals(768.0, MainWindowFrame.startupSize(doubleArrayOf(600.0), 1440.0, 2560.0).heightDp) + assertEquals( + 768.0, + MainWindowFrame.startupSize(doubleArrayOf(Double.NaN, Double.NaN), 1440.0, 2560.0).heightDp, + ) + } + + /** A screen smaller than the margin must still yield a window with a size. */ + @Test + fun `an absurdly small screen still yields a positive size`() { + val size = MainWindowFrame.startupSize(doubleArrayOf(768.0, 1234.0), 20.0, 20.0) + assertTrue(size.heightDp > 0.0) + assertTrue(size.widthDp > 0.0) + } + + // ---- the title --------------------------------------------------------- + + @Test + fun `the title carries the chat state`() { + assertEquals( + "Connected to: 2 as DN9APW", + MainWindowFrame.title(chatState = "Connected to: 2 as DN9APW", profileName = null), + ) + } + + /** The root profile is the only one, so naming it would only add noise. */ + @Test + fun `the root profile is not named in the title`() { + assertEquals("DISCONNECTED!", MainWindowFrame.title("DISCONNECTED!", profileName = null)) + } + + @Test + fun `a named profile is appended so two windows can be told apart`() { + assertEquals( + "DISCONNECTED! - Contest station", + MainWindowFrame.title("DISCONNECTED!", profileName = "Contest station"), + ) + } + + // ---- the chat state line ---------------------------------------------- + + /** + * What the title says while the link is not up. The operator reads this to tell a + * scheduled reconnect from a dead session, so the wording is pinned. + */ + @Test + fun `every connection state has its own offline wording`() { + assertEquals("CONNECTION LOST – reconnect scheduled", MainWindowFrame.offlineChatState(On4KstConnectionState.RECONNECT_WAIT)) + assertEquals("Connecting to ON4KST…", MainWindowFrame.offlineChatState(On4KstConnectionState.CONNECTING)) + assertEquals("Connected – authenticating with ON4KST…", MainWindowFrame.offlineChatState(On4KstConnectionState.WAITING_FOR_LOGIN_PROMPT)) + assertEquals("Connected – authenticating with ON4KST…", MainWindowFrame.offlineChatState(On4KstConnectionState.AUTHENTICATING)) + assertEquals("Connected – synchronizing ON4KST chat data…", MainWindowFrame.offlineChatState(On4KstConnectionState.SYNCING_MAIN_CHAT)) + assertEquals("Connected – synchronizing ON4KST chat data…", MainWindowFrame.offlineChatState(On4KstConnectionState.SYNCING_SECOND_CHAT)) + assertEquals("DISCONNECTED!", MainWindowFrame.offlineChatState(On4KstConnectionState.DISCONNECTED)) + assertEquals("DISCONNECTED!", MainWindowFrame.offlineChatState(On4KstConnectionState.STOPPING)) + } + + @Test + fun `no connection state at all reads as disconnected`() { + assertEquals("DISCONNECTED!", MainWindowFrame.offlineChatState(null)) + } + + /** + * The title carries the whole connection line while the chat is usable. + * + * The JavaFX window did that -- "Connected to: 2: 144/432 MHz as DN5PW (Testing) in + * JO50JP (73 users online, 73 shown), 29 messages total." -- and the Compose window + * opened with a fixed "KST4Contest (Compose)" instead, which told a tiling window + * manager nothing and told the operator less. + */ + @Test + fun `the title carries the live connection line once the chat is usable`() { + val detail = "Connected to: 2: 144/432 MHz as DN5PW (Testing) in JO50JP " + + "(73 users online, 73 shown), 29 messages total." + + assertEquals(detail, MainWindowFrame.chatState(On4KstConnectionState.ONLINE, detail)) + } + + @Test + fun `an unusable chat says what it is doing instead`() { + assertEquals( + MainWindowFrame.offlineChatState(On4KstConnectionState.CONNECTING), + MainWindowFrame.chatState(On4KstConnectionState.CONNECTING, "ignored while connecting"), + ) + } + + @Test + fun `a blank detail falls through rather than leaving the title empty`() { + // The feed substitutes the state name for a blank detail, but it may not have run yet. + assertEquals( + MainWindowFrame.offlineChatState(On4KstConnectionState.ONLINE), + MainWindowFrame.chatState(On4KstConnectionState.ONLINE, " "), + ) + assertEquals( + MainWindowFrame.offlineChatState(null), + MainWindowFrame.chatState(null, null), + ) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/MainWindowStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/MainWindowStateTest.kt new file mode 100644 index 00000000..f1288a96 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/MainWindowStateTest.kt @@ -0,0 +1,173 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.snapshots.Snapshot +import kst4contest.controller.On4KstConnectionState +import kst4contest.model.ChatPreferences +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * The shortcut and snippet rosters are ChatPreferences.SimpleRoster, which notifies + * nothing Compose can see. Mirroring them into Compose state is what makes the button row + * above the send line follow the settings window — the reason ShortcutsTabState has been + * calling refreshShortcutButtons into thin air since Etappe 3b. + */ +class MainWindowStateRosterTest { + + @Test + fun `the shortcuts start out as what the profile holds`() { + val prefs = ChatPreferences() + prefs.getLst_txtShortCutBtnList().setAll(listOf("MYQRG", "pse sked")) + + val mirror = RosterMirror(prefs.getLst_txtShortCutBtnList()) + + assertEquals(listOf("MYQRG", "pse sked"), mirror.entries) + } + + /** + * The roster is written through by the settings window on every committed edit. The + * mirror only catches up when it is told to, which is what the refresh hook is for. + */ + @Test + fun `a roster change reaches the mirror when it is refreshed`() { + val prefs = ChatPreferences() + prefs.getLst_txtShortCutBtnList().setAll(listOf("MYQRG")) + val mirror = RosterMirror(prefs.getLst_txtShortCutBtnList()) + + prefs.getLst_txtShortCutBtnList().setAll(listOf("MYQRG", "SECONDQRG", "qrz?")) + assertEquals(listOf("MYQRG"), mirror.entries, "the mirror moved without being refreshed") + + mirror.refresh() + assertEquals(listOf("MYQRG", "SECONDQRG", "qrz?"), mirror.entries) + } + + @Test + fun `an emptied roster empties the mirror`() { + val prefs = ChatPreferences() + prefs.getLst_txtShortCutBtnList().setAll(listOf("MYQRG")) + val mirror = RosterMirror(prefs.getLst_txtShortCutBtnList()) + + prefs.getLst_txtShortCutBtnList().clear() + mirror.refresh() + + assertTrue(mirror.entries.isEmpty()) + } + + /** + * The button row is drawn from this, so reading it has to register as a read — the + * failure that produced most of this migration's invisible defects. + */ + @Test + fun `drawing the buttons subscribes to the mirror`() { + val prefs = ChatPreferences() + prefs.getLst_txtShortCutBtnList().setAll(listOf("MYQRG")) + val mirror = RosterMirror(prefs.getLst_txtShortCutBtnList()) + + val read = mutableSetOf() + Snapshot.observe(readObserver = { read += it.toString() }) { + mirror.entries.forEach { it.length } + } + + assertTrue(read.isNotEmpty(), "the mirror was read without subscribing") + } +} + +/** + * The splitters of the main window against the positions the profile actually stores. + * + * A mismatch here is silent and total: SplitterState falls back to an even split, so + * every operator would lose the layout they arranged without any error saying so. + */ +class MainWindowSplitterDefaultsTest { + + private val prefs = ChatPreferences() + + @Test + fun `the message column has as many dividers as the profile stores positions`() { + val stored = prefs.getGUImessageSectionSplitpane_dividerposition() + assertEquals( + MainWindowState.MESSAGE_PANE_COUNT - 1, + stored.size, + "the message splitter has ${MainWindowState.MESSAGE_PANE_COUNT} panes but the " + + "profile stores ${stored.size} positions", + ) + + val splitter = SplitterState(MainWindowState.MESSAGE_PANE_COUNT, stored) {} + assertEquals( + stored.map { it.toFloat() }, + splitter.positions, + "the stored positions were rejected and silently replaced by an even split", + ) + } + + @Test + fun `the station column has as many dividers as the profile stores positions`() { + val stored = prefs.getGUImainWindowRightSplitPane_dividerposition() + assertEquals(MainWindowState.RIGHT_PANE_COUNT - 1, stored.size) + + val splitter = SplitterState(MainWindowState.RIGHT_PANE_COUNT, stored) {} + assertEquals(stored.map { it.toFloat() }, splitter.positions) + } + + @Test + fun `the outer splitter takes the one position the profile stores`() { + val stored = prefs.getGUImainWindowLeftSplitPane_dividerposition() + assertEquals(1, stored.size) + + val splitter = SplitterState(paneCount = 2, stored = stored) {} + assertEquals(stored.map { it.toFloat() }, splitter.positions) + } +} + +/** + * What the window draws about its surroundings — the link, and which other windows are + * open — has to be Compose state as well. + * + * These come from the controller and from AtomicBooleans inside the window hosts, none of + * which Compose can see. Reading them through a plain lambda at composition time draws them + * once: the badge would freeze on whatever the link was when the window opened, and the + * menu's "hide options" would keep saying the wrong thing. + */ +class MainWindowSurroundingsTest { + + @Test + fun `the connection state starts disconnected and follows what it is told`() { + val state = MainWindowSurroundings() + + assertEquals(On4KstConnectionState.DISCONNECTED, state.connectionState) + + state.connectionState = On4KstConnectionState.ONLINE + assertEquals(On4KstConnectionState.ONLINE, state.connectionState) + } + + @Test + fun `drawing the surroundings subscribes to every value`() { + val state = MainWindowSurroundings() + val read = mutableSetOf() + + Snapshot.observe(readObserver = { read += it.toString() }) { + state.connectionState + state.connectionDetail + state.settingsWindowOpen + state.monitorWindowOpen + } + + assertEquals(4, read.size, "a value was read without subscribing: $read") + } + + /** + * The menu and the badge must never disagree about the link — they are two renderings of + * one fact, and an operator comparing them would not know which to believe. + */ + @Test + fun `the menu follows the same connection state as the badge`() { + val menu = MainMenuState() + val state = MainWindowSurroundings(menu) + + state.connectionState = On4KstConnectionState.ONLINE + + assertEquals(On4KstConnectionState.ONLINE, menu.connectionState) + assertTrue(menu.canUseChatActions) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/MonitorColumnsTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/MonitorColumnsTest.kt new file mode 100644 index 00000000..70008049 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/MonitorColumnsTest.kt @@ -0,0 +1,133 @@ +package kst4contest.view.compose + +import kst4contest.model.ChatCategory +import kst4contest.model.ChatMember +import kst4contest.model.ChatMessage +import kst4contest.model.ClusterMessage +import kst4contest.observe.SimpleValue +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertDoesNotThrow + +/** + * The columns of the two monitor tables. + * + * Two things are worth pinning. The ids are part of the operator's stored layout, so + * renaming one silently loses their column widths. And every value has to survive a + * half-filled message: these tables are fed straight from the wire, and a + * NullPointerException in a live table during a contest is the worst possible moment. + */ +class MonitorColumnsTest { + + @Test + fun `the DX cluster columns keep the ids the stored layout uses`() { + assertEquals( + listOf("time", "call-tx", "locator-tx", "call-rx", "locator-rx", "qrg", "message", "worked"), + MonitorColumns.dxCluster().map { it.id }, + ) + } + + @Test + fun `the DX cluster columns keep their headings`() { + assertEquals( + listOf("Time", "Call tx", "LOC tx", "Call rx", "LOC rx", "QRG", "Message", "wkd"), + MonitorColumns.dxCluster().map { it.title() }, + ) + } + + @Test + fun `a DX cluster row without sender or receiver reads as empty, not as a crash`() { + val bare = ClusterMessage() + + MonitorColumns.dxCluster().forEach { column -> + assertDoesNotThrow({ column.value(bare) }, "column ${column.id}") + } + } + + @Test + fun `the worked column shows a cross, as the JavaFX table did`() { + val worked = ClusterMessage().apply { isReceiverWkd = true } + val notWorked = ClusterMessage() + + val column = MonitorColumns.dxCluster().first { it.id == "worked" } + + assertEquals("X", column.value(worked)) + assertEquals("", column.value(notWorked)) + } + + @Test + fun `the QSO monitor keeps the nine columns the JavaFX table actually showed`() { + // Ten were built there and nine added; the "Name" column was never shown. + assertEquals( + listOf("time", "call-tx", "last-qrg-tx", "worked-tx", "call-rx", "last-qrg-rx", + "worked-rx", "message", "category"), + MonitorColumns.qsoOfTheOther().map { it.id }, + ) + } + + @Test + fun `a QSO monitor row without sender or receiver reads as empty, not as a crash`() { + val bare = ChatMessage() + + MonitorColumns.qsoOfTheOther().forEach { column -> + assertDoesNotThrow({ column.value(bare) }, "column ${column.id}") + } + } + + @Test + fun `the time column shows a clock time, not the epoch off the wire`() { + // The server sends epoch seconds; the JavaFX cell ran them through + // Utils4KST.time_convertEpochToReadable, which is H:mm:ss in Etc/UTC. + val spot = ClusterMessage().apply { timeGenerated = "1759000000" } + + val column = MonitorColumns.dxCluster().first { it.id == "time" } + + assertEquals("19:06:40", column.value(spot)) + } + + @Test + fun `an unreadable time is shown as it came rather than throwing`() { + val spot = ClusterMessage().apply { timeGenerated = "not a number" } + + val column = MonitorColumns.dxCluster().first { it.id == "time" } + + assertEquals("not a number", column.value(spot)) + } + + @Test + fun `the QSO time column is formatted the same way`() { + val message = ChatMessage().apply { messageGeneratedTime = "1759000000" } + + val column = MonitorColumns.qsoOfTheOther().first { it.id == "time" } + + assertEquals("19:06:40", column.value(message)) + } + + @Test + fun `the cluster QRG is padded the way the main window pads it`() { + val spot = ClusterMessage().apply { + receiver = ChatMember().apply { frequency = SimpleValue("144.3") } + } + + val column = MonitorColumns.dxCluster().first { it.id == "qrg" } + + assertEquals("144.300", column.value(spot), + "the same column in the main window pads to three places; two tables of " + + "the same data must not disagree") + } + + @Test + fun `the category comes from the sender, as it did in the JavaFX table`() { + val sender = ChatMember().apply { chatCategory = ChatCategory(2) } + val message = ChatMessage().apply { this.sender = sender } + + val column = MonitorColumns.qsoOfTheOther().first { it.id == "category" } + + assertEquals( + sender.chatCategory.getChatCategoryName(sender.chatCategory.categoryNumber), + column.value(message), + "the old cell read getSender().getChatCategory(); the message carries a " + + "field of the same name that is not always the same value", + ) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/ObservedValueTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/ObservedValueTest.kt new file mode 100644 index 00000000..97e74adc --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/ObservedValueTest.kt @@ -0,0 +1,93 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.snapshots.Snapshot +import kst4contest.model.ChatPreferences +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * ChatPreferences hands out MutableValue, which notifies its own listeners and nothing + * Compose can see. A field drawn straight from one renders once and then goes stale — and + * these three in particular move on their own: the rotator writes the QTF, and the + * frequency follower writes MYQRG. + * + * The JavaFX window solved it with attachQtfFollower() and attachOwnQrgFollower(); this is + * the same idea, ending in Compose state instead of a TextField. + */ +class ObservedValueTest { + + @Test + fun `the mirror starts at the stored value`() { + val prefs = ChatPreferences() + prefs.getMYQRGFirstCat().set("144.370") + + val observed = ObservedValue(prefs.getMYQRGFirstCat()) + + assertEquals("144.370", observed.value) + } + + /** The rotator moving must reach the screen without anything asking it to. */ + @Test + fun `a change to the underlying value reaches the mirror by itself`() { + val prefs = ChatPreferences() + prefs.getActualQTF().set(90.0) + val observed = ObservedValue(prefs.getActualQTF()) + + prefs.getActualQTF().set(135.0) + + assertEquals(135.0, observed.value) + } + + @Test + fun `a null value is carried through rather than turned into a default`() { + val prefs = ChatPreferences() + val observed = ObservedValue(prefs.getMYQRGSecondCat()) + + prefs.getMYQRGSecondCat().set(null) + + assertEquals(null, observed.value) + } + + /** + * The field is drawn from this, so reading it has to register as a read. Without this + * the whole exercise is pointless: the value would be correct and invisible. + */ + @Test + fun `drawing from the mirror subscribes to it`() { + val prefs = ChatPreferences() + prefs.getMYQRGFirstCat().set("144.370") + val observed = ObservedValue(prefs.getMYQRGFirstCat()) + + val read = mutableSetOf() + Snapshot.observe(readObserver = { read += it.toString() }) { + observed.value + } + + assertTrue(read.isNotEmpty(), "the mirrored value was read without subscribing") + } + + /** + * A mirror that is dropped must stop listening. A profile switch builds a new window + * over the same preferences, and a leaked listener keeps the old one alive and writing. + */ + @Test + fun `releasing the mirror stops it following`() { + val prefs = ChatPreferences() + prefs.getMYQRGFirstCat().set("144.370") + val observed = ObservedValue(prefs.getMYQRGFirstCat()) + + observed.release() + prefs.getMYQRGFirstCat().set("432.200") + + assertEquals("144.370", observed.value, "a released mirror kept following") + } + + @Test + fun `releasing twice is harmless`() { + val prefs = ChatPreferences() + val observed = ObservedValue(prefs.getMYQRGFirstCat()) + observed.release() + observed.release() + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/OperatorProfilePickerStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/OperatorProfilePickerStateTest.kt new file mode 100644 index 00000000..9bb3902c --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/OperatorProfilePickerStateTest.kt @@ -0,0 +1,69 @@ +package kst4contest.view.compose + +import kst4contest.model.OperatorProfile +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue + +class OperatorProfilePickerStateTest { + + private fun profile(id: String, name: String = id, root: Boolean = false, shared: Boolean = false) = + OperatorProfile(id, name, root, shared) + + @Test + fun `the preselected profile is selected when it is in the list`() { + val state = OperatorProfilePickerState( + listOf(profile("root"), profile("contest")), preselectedProfileId = "contest") + + assertEquals("contest", state.selected?.profileId) + assertTrue(state.canConfirm) + } + + @Test + fun `an unknown preselection falls back to the first profile`() { + val state = OperatorProfilePickerState( + listOf(profile("root"), profile("contest")), preselectedProfileId = "gone") + + assertEquals("root", state.selected?.profileId, + "a profile that disappeared must not leave the dialog unusable") + } + + @Test + fun `no preselection falls back to the first profile`() { + val state = OperatorProfilePickerState(listOf(profile("root")), preselectedProfileId = null) + + assertEquals("root", state.selected?.profileId) + } + + @Test + fun `an empty list cannot be confirmed`() { + val state = OperatorProfilePickerState(emptyList(), preselectedProfileId = null) + + assertNull(state.selected) + assertFalse(state.canConfirm) + } + + @Test + fun `selecting changes the selection`() { + val state = OperatorProfilePickerState( + listOf(profile("root"), profile("contest")), preselectedProfileId = "root") + + state.select(profile("contest")) + + assertEquals("contest", state.selected?.profileId) + } + + @Test + fun `the worked database label matches the JavaFX dialog`() { + // The dialog this replaces showed exactly these two strings, and the rule + // behind them: the root profile and a sharing profile use the shared file. + assertEquals("shared station worked database", + workedDatabaseDescription(profile("root", root = true))) + assertEquals("shared station worked database", + workedDatabaseDescription(profile("sharer", shared = true))) + assertEquals("own worked database", + workedDatabaseDescription(profile("owner"))) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/OperatorProfilePickerWindowTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/OperatorProfilePickerWindowTest.kt new file mode 100644 index 00000000..f42ee5d5 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/OperatorProfilePickerWindowTest.kt @@ -0,0 +1,88 @@ +package kst4contest.view.compose + +import kst4contest.model.OperatorProfile +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Assumptions.assumeFalse +import org.junit.jupiter.api.Test +import java.awt.EventQueue +import java.awt.GraphicsEnvironment +import java.awt.Window +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit +import javax.swing.Timer + +/** + * The picker must be openable from the user-interface thread. + * + * Since the dispatcher moved to the AWT event thread, `ComposeMenuActions.switchOperatorProfile` + * delivers the File menu's profile switch there. The picker's former thread-plus-latch + * construction deadlocked against that: a `CountDownLatch.await()` does not pump events, while + * every continuation of the window's own `application { }` — composition, the button callbacks, + * even the return that would release the latch — is posted to that same thread by skiko's + * SwingDispatcher. The window never appeared and the client froze for good. + */ +class OperatorProfilePickerWindowTest { + + private fun profiles() = listOf( + OperatorProfile().apply { profileId = "root"; displayName = "Root" }, + OperatorProfile().apply { profileId = "second"; displayName = "Second" }, + ) + + /** Closes whatever window the picker opened, the way the operator's X would. */ + private fun disposeOpenWindowsAfter(delayMs: Int): Timer = + Timer(delayMs) { + Window.getWindows() + .filter { it.isShowing && it.javaClass.name.contains("ComposeDialog") } + .forEach { it.dispose() } + }.apply { isRepeats = true } + + @Test + fun opensAndReturnsWhenCalledOnTheEventThread() { + assumeFalse(GraphicsEnvironment.isHeadless(), "needs a display") + + val closer = disposeOpenWindowsAfter(1_500) + val worker = Executors.newSingleThreadExecutor() + + try { + closer.start() + // invokeAndWait so the call really happens ON the event thread, as the menu does. + val call = worker.submit { EventQueue.invokeAndWait { OperatorProfilePickerWindow.showAndSelect(profiles(), "root") } } + + // The deadlock had no timeout of its own: without a fix this never completes. + call.get(20, TimeUnit.SECONDS) + } finally { + closer.stop() + worker.shutdownNow() + } + } + + @Test + fun opensAndReturnsWhenCalledOffTheEventThread() { + assumeFalse(GraphicsEnvironment.isHeadless(), "needs a display") + + val closer = disposeOpenWindowsAfter(1_500) + + try { + closer.start() + // The startup path: main() resolves the profile before any window exists. + val chosen = OperatorProfilePickerWindow.showAndSelect(profiles(), "root") + + // Dismissed rather than confirmed, so the caller is told to quit. + assertTrue(chosen.isEmpty, "a dismissed picker must report no choice") + } finally { + closer.stop() + } + } + + @Test + fun theSelectionRulesAreUnchanged() { + val state = OperatorProfilePickerState(profiles(), "second") + + assertEquals("second", state.selected?.profileId, "the preselected profile must win") + assertTrue(state.canConfirm) + + state.select(profiles()[0]) + assertEquals("root", state.selected?.profileId) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/PaletteResolutionTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/PaletteResolutionTest.kt new file mode 100644 index 00000000..fe50d960 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/PaletteResolutionTest.kt @@ -0,0 +1,169 @@ +package kst4contest.view.compose + +import androidx.compose.ui.graphics.Color +import kst4contest.model.PaletteRole +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +/** + * The three layers and which one wins, role by role. + * + * The provenance is not decoration. Two sources that can decide the same colour is a place + * where nobody can later say why a colour is what it is, and saying so per role is the one + * thing that makes the arrangement defensible -- so it is pinned as hard as the colours. + */ +class PaletteResolutionTest { + + private val shipped = JavaFxStylesheet.read("/KST4ContestDefaultDay.css") + + private val red = Color(0xFFFF0000) + private val green = Color(0xFF00FF00) + + @Test + fun withNothingSetEveryRoleComesFromTheShippedSheet() { + val resolved = resolvePalette(shipped, emptyMap(), emptyMap()) + + assertEquals(PaletteRole.values().toSet(), resolved.roles.keys) + resolved.roles.forEach { (role, it) -> + assertEquals(PaletteSource.SHIPPED, it.source, "$role") + } + assertEquals(shipped.base, resolved.palette.base) + assertEquals(shipped.accent, resolved.palette.accent) + } + + @Test + fun aFileOverridesTheShippedSheetForTheRolesItNames() { + val resolved = resolvePalette(shipped, mapOf(PaletteRole.SURFACE to red), emptyMap()) + + assertEquals(red, resolved.roles[PaletteRole.SURFACE]!!.colour) + assertEquals(PaletteSource.FILE, resolved.roles[PaletteRole.SURFACE]!!.source) + + // And only those roles. + assertEquals(PaletteSource.SHIPPED, resolved.roles[PaletteRole.ACCENT]!!.source) + assertEquals(shipped.accent, resolved.roles[PaletteRole.ACCENT]!!.colour) + } + + @Test + fun aChangeOverridesBothTheFileAndTheShippedSheet() { + val resolved = resolvePalette( + shipped, + mapOf(PaletteRole.SURFACE to red), + mapOf(PaletteRole.SURFACE to green), + ) + + assertEquals(green, resolved.roles[PaletteRole.SURFACE]!!.colour) + assertEquals(PaletteSource.CHANGED, resolved.roles[PaletteRole.SURFACE]!!.source) + } + + @Test + fun theResolvedRolesReachThePaletteTheWindowsDraw() { + val resolved = resolvePalette( + shipped, + emptyMap(), + mapOf( + PaletteRole.SURFACE to red, + PaletteRole.WINDOW_SURFACE to green, + PaletteRole.FIELD_INTERIOR to red, + PaletteRole.TEXT to green, + PaletteRole.ACCENT to red, + PaletteRole.SEPARATOR to green, + ), + ) + + assertEquals(red, resolved.palette.base) + assertEquals(green, resolved.palette.windowBackground) + assertEquals(red, resolved.palette.controlInnerBackground) + assertEquals(green, resolved.palette.labelTextFill) + assertEquals(red, resolved.palette.accent) + assertEquals(green, resolved.palette.separatorLine) + } + + @Test + fun theDerivedFieldsStayWithTheShippedSheet() { + // The hover gradient, the pressed border and the font size are not roles the operator + // sets here; they follow the shipped sheet rather than becoming further decisions. + val resolved = resolvePalette(shipped, emptyMap(), mapOf(PaletteRole.SURFACE to red)) + + assertEquals(shipped.buttonHoverGradient, resolved.palette.buttonHoverGradient) + assertEquals(shipped.buttonPressedBorder, resolved.palette.buttonPressedBorder) + assertEquals(shipped.fontSizePx, resolved.palette.fontSizePx) + } + + @Test + fun aChosenAccentIsAlsoTheAccentTheOperatorActuallySees() { + /* + * Theme.kt maps Material's primary onto textAccent and not onto accent, because + * -fx-accent only paints JavaFX's selection bar while the green of .text-field .text + * is what reads as the accent. Leave textAccent on the sheet's green and setting the + * accent changes almost nothing visible -- a setting written through and not drawn, + * which is precisely the fault class the drawing-layer tests exist for. + */ + val resolved = resolvePalette(shipped, emptyMap(), mapOf(PaletteRole.ACCENT to red)) + + assertEquals(red, resolved.palette.accent) + assertEquals(red, resolved.palette.textAccent) + } + + @Test + fun anUntouchedAccentLeavesTheSheetsOwnTextAccentAlone() { + // Without an override the sheet's gradient midpoint stands; it is not the accent. + val resolved = resolvePalette(shipped, emptyMap(), mapOf(PaletteRole.SURFACE to red)) + + assertEquals(shipped.textAccent, resolved.palette.textAccent) + } + + @Test + fun aFileRestatingTheShippedAccentDoesNotRepaintTheTextAccent() { + /* + * The root profile's stylesheet is written by copyResourceIfRequired at startup and + * is the shipped sheet, so layer 2 declares the accent on every existing installation + * with nobody having chosen anything. Keying the text accent on provenance rather + * than on the value repainted the evening primary from green to blue on upgrade. + */ + val evening = JavaFxStylesheet.read("/KST4ContestDefaultEvening.css") + + val resolved = resolvePalette( + evening, + mapOf(PaletteRole.ACCENT to evening.accent), + emptyMap(), + ) + + assertEquals(PaletteSource.FILE, resolved.roles[PaletteRole.ACCENT]!!.source) + assertEquals( + evening.textAccent, + resolved.palette.textAccent, + "a file that merely restates the shipped accent changed the accent that is seen", + ) + } + + @Test + fun resettingToTheShippedAccentRestoresTheShippedTextAccent() { + /* + * resetToShipped writes all six roles as explicit overrides, because it has to beat a + * stylesheet file. If the text accent follows provenance, the one button the spec + * names as producing "exactly the shipped colours" produces something else -- and + * disagrees with "discard my changes", which clears layer 3 and does restore it. + */ + val resolved = resolvePalette( + shipped, + emptyMap(), + mapOf(PaletteRole.ACCENT to shipped.accent), + ) + + assertEquals(PaletteSource.CHANGED, resolved.roles[PaletteRole.ACCENT]!!.source) + assertEquals(shipped.textAccent, resolved.palette.textAccent) + } + + @Test + fun theWindowSurfaceIsNotDraggedAlongByTheSurface() { + /* + * The reason these are two roles rather than one: the sheets state the window + * surface separately, and an operator who sets only the control surface must not + * have the window surface changed under them. + */ + val resolved = resolvePalette(shipped, emptyMap(), mapOf(PaletteRole.SURFACE to red)) + + assertEquals(red, resolved.palette.base) + assertEquals(shipped.windowBackground, resolved.palette.windowBackground) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/PaletteStoreFactoryTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/PaletteStoreFactoryTest.kt new file mode 100644 index 00000000..4ff99d7e --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/PaletteStoreFactoryTest.kt @@ -0,0 +1,109 @@ +package kst4contest.view.compose + +import kst4contest.model.ChatPreferences +import kst4contest.model.OperatorProfile +import kst4contest.model.PaletteRole +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import java.io.File + +/** + * The factory binds the store to one profile's preferences and one profile's stylesheet. + * + * Two wires, and each of them is a place where one profile could end up reading or writing + * another's colours. The stylesheet path is injected here rather than derived inside, so the + * test does not have to write into the operator's home directory to check which file is read. + */ +class PaletteStoreFactoryTest { + + private val daylight = OperatorProfilePaletteFiles( + dayFile = File("/nonexistent/day.css"), + eveningFile = File("/nonexistent/evening.css"), + ) + + @Test + fun aChangeLandsInTheDesignsOwnPreference() { + val prefs = ChatPreferences() + + val store = PaletteStoreFactory.create(prefs, daylight) + store.set(darkMode = false, role = PaletteRole.ACCENT, colour = "#FF0000") + + assertEquals("accent=#FF0000", prefs.guiOptions_paletteOverridesDay) + assertTrue(prefs.guiOptions_paletteOverridesEvening.isEmpty()) + } + + @Test + fun anEveningChangeLandsInTheEveningPreference() { + val prefs = ChatPreferences() + + val store = PaletteStoreFactory.create(prefs, daylight) + store.set(darkMode = true, role = PaletteRole.ACCENT, colour = "#FF0000") + + assertEquals("accent=#FF0000", prefs.guiOptions_paletteOverridesEvening) + assertTrue(prefs.guiOptions_paletteOverridesDay.isEmpty()) + } + + @Test + fun whatIsAlreadyStoredIsInForceFromTheStart() { + // The store is built at startup; a colour saved last session has to be there at once. + val prefs = ChatPreferences() + prefs.guiOptions_paletteOverridesDay = "accent=#FF0000" + + val store = PaletteStoreFactory.create(prefs, daylight) + + assertEquals(PaletteSource.CHANGED, store.resolved(false).roles[PaletteRole.ACCENT]!!.source) + } + + @Test + fun aMissingStylesheetLeavesEveryRoleWithTheShippedSheet() { + val prefs = ChatPreferences() + + val store = PaletteStoreFactory.create(prefs, daylight) + + store.resolved(false).roles.forEach { (role, resolved) -> + assertEquals(PaletteSource.SHIPPED, resolved.source, "$role") + } + } + + @Test + fun aStylesheetInTheProfileSuppliesTheRolesItNames() { + val file = File.createTempFile("kst4contest-profile", ".css") + try { + file.writeText(".root { -fx-accent: #123456; }") + + val store = PaletteStoreFactory.create( + ChatPreferences(), + OperatorProfilePaletteFiles(dayFile = file, eveningFile = file), + ) + + assertEquals( + PaletteSource.FILE, + store.resolved(false).roles[PaletteRole.ACCENT]!!.source, + ) + assertEquals(colourOf("#123456"), store.resolved(false).palette.accent) + } finally { + file.delete() + } + } + + @Test + fun theFilesOfAProfileFollowOperatorProfilePaths() { + /* + * The one assertion that ties the factory to the project's path convention. A + * different shape here would have one profile reading another profile's colours. + */ + val other = OperatorProfile("OP2", "DN9APW", false, false) + + val files = OperatorProfilePaletteFiles.of(other) + + assertTrue( + files.dayFile.path.endsWith("profiles/OP2/KST4ContestDefaultDay.css"), + "the daylight file is ${files.dayFile.path}", + ) + assertTrue( + files.eveningFile.path.endsWith("profiles/OP2/KST4ContestDefaultEvening.css"), + "the evening file is ${files.eveningFile.path}", + ) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/PaletteStoreTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/PaletteStoreTest.kt new file mode 100644 index 00000000..f45867da --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/PaletteStoreTest.kt @@ -0,0 +1,278 @@ +package kst4contest.view.compose + +import androidx.compose.ui.graphics.Color +import kst4contest.model.PaletteOverrides +import kst4contest.model.PaletteRole +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * The store, and the three ways back. + * + * Built over four lambdas rather than over ChatPreferences, so none of this touches the + * operator's home directory: that constructor copies resources into it. + */ +class PaletteStoreTest { + + private val stored = mutableMapOf(false to "", true to "") + private var fileRoles: Map = emptyMap() + + private fun store() = PaletteStore( + shippedOf = { dark -> + JavaFxStylesheet.read( + if (dark) "/KST4ContestDefaultEvening.css" else "/KST4ContestDefaultDay.css" + ) + }, + fileRolesOf = { fileRoles }, + storedOverridesOf = { dark -> stored.getValue(dark) }, + storeOverrides = { dark, encoded -> stored[dark] = encoded }, + ) + + @Test + fun theImmutableLayersAreReadOnceAndNotOnEveryResolve() { + /* + * resolved() is called from inside Kst4ContestTheme, so it runs on every recomposition + * of every window. Reading the classpath and the profile's stylesheet there means two + * CSS parses and a disk read per recomposition, on the UI thread -- and this project's + * standing lesson is that a green build says nothing about what the UI thread is doing. + * + * The override state is the live part; the two layers under it are immutable for the + * run, which is also what both manuals promise ("changes to the file take effect after + * a restart"). + */ + var shippedReads = 0 + var fileReads = 0 + + val store = PaletteStore( + shippedOf = { dark -> + shippedReads++ + JavaFxStylesheet.read( + if (dark) "/KST4ContestDefaultEvening.css" else "/KST4ContestDefaultDay.css" + ) + }, + fileRolesOf = { fileReads++; emptyMap() }, + storedOverridesOf = { "" }, + storeOverrides = { _, _ -> }, + ) + + repeat(20) { store.resolved(false) } + store.set(false, PaletteRole.ACCENT, "#FF0000") + repeat(20) { store.resolved(false) } + + assertEquals(1, shippedReads, "the shipped sheet was parsed more than once") + assertEquals(1, fileReads, "the profile stylesheet was read more than once") + } + + @Test + fun eachDesignReadsItsOwnLayersOnceWhenItIsFirstNeeded() { + var reads = 0 + val store = PaletteStore( + shippedOf = { dark -> + reads++ + JavaFxStylesheet.read( + if (dark) "/KST4ContestDefaultEvening.css" else "/KST4ContestDefaultDay.css" + ) + }, + fileRolesOf = { emptyMap() }, + storedOverridesOf = { "" }, + storeOverrides = { _, _ -> }, + ) + + repeat(5) { store.resolved(false) } + assertEquals(1, reads, "the daylight sheet was read more than once") + + repeat(5) { store.resolved(true) } + assertEquals(2, reads, "the evening sheet was not read, or was read more than once") + } + + @Test + fun aChangeIsVisibleInTheResolvedPaletteAndInTheStorage() { + val store = store() + + store.set(darkMode = false, role = PaletteRole.ACCENT, colour = "#FF0000") + + assertEquals(Color(0xFFFF0000), store.resolved(false).palette.accent) + assertEquals( + PaletteSource.CHANGED, + store.resolved(false).roles[PaletteRole.ACCENT]!!.source, + ) + assertEquals("accent=#FF0000", stored.getValue(false)) + } + + @Test + fun anUnparsableColourLeavesTheRoleAsItWas() { + // The operator typed something that is not a colour. Nothing may turn black. + val store = store() + val before = store.resolved(false).palette.accent + + store.set(false, PaletteRole.ACCENT, "rot") + + assertEquals(before, store.resolved(false).palette.accent) + assertEquals("", stored.getValue(false)) + } + + @Test + fun theTwoDesignsDoNotDragEachOtherAlong() { + val store = store() + + store.set(darkMode = true, role = PaletteRole.ACCENT, colour = "#FF0000") + + assertEquals( + PaletteSource.CHANGED, + store.resolved(true).roles[PaletteRole.ACCENT]!!.source, + ) + assertEquals( + PaletteSource.SHIPPED, + store.resolved(false).roles[PaletteRole.ACCENT]!!.source, + ) + } + + @Test + fun resetToShippedBeatsAFileAsWell() { + /* + * The acceptance criterion of this stage: "exactly the shipped colours". With a file + * in the middle, clearing the changes would not get there -- the file would. + */ + fileRoles = mapOf(PaletteRole.ACCENT to Color(0xFF00FF00)) + val store = store() + val shippedAccent = store.shipped(false).accent + + store.resetToShipped(false) + + assertEquals(shippedAccent, store.resolved(false).palette.accent) + assertEquals( + PaletteSource.CHANGED, + store.resolved(false).roles[PaletteRole.ACCENT]!!.source, + ) + assertEquals(6, PaletteOverrides.parse(stored.getValue(false)).size) + } + + @Test + fun resetToShippedReproducesEveryShippedRoleExactly() { + /* + * The acceptance criterion says "exactly the shipped colours -- not something that + * resembles them", and the path goes through hex: resetToShipped writes each role as + * a six-digit string and reads it back. That is only lossless because Compose packs an + * sRGB Color at 8 bits per channel, so every channel is already an exact k/255. Pinned + * for all six roles and both designs, because the day the packing changes, nothing + * else would notice. + */ + for (dark in listOf(false, true)) { + val store = store() + val shipped = store.shipped(dark) + + store.resetToShipped(dark) + val after = store.resolved(dark).palette + + assertEquals(shipped.base, after.base, "surface, dark=$dark") + assertEquals(shipped.windowBackground, after.windowBackground, "window, dark=$dark") + assertEquals(shipped.controlInnerBackground, after.controlInnerBackground, "field, dark=$dark") + assertEquals(shipped.labelTextFill, after.labelTextFill, "text, dark=$dark") + assertEquals(shipped.accent, after.accent, "accent, dark=$dark") + assertEquals(shipped.separatorLine, after.separatorLine, "separator, dark=$dark") + assertEquals(shipped.textAccent, after.textAccent, "text accent, dark=$dark") + } + } + + @Test + fun resetToShippedAlsoWinsOverAFileThatRestatesTheShippedSheet() { + /* + * The root profile's real situation: its stylesheet is the shipped sheet, written by + * copyResourceIfRequired. Resetting there must land on the shipped palette and not on + * something the file nudged. + */ + val evening = JavaFxStylesheet.read("/KST4ContestDefaultEvening.css") + fileRoles = JavaFxStylesheet.declaredRoles( + JavaFxStylesheet::class.java.getResource("/KST4ContestDefaultEvening.css")!!.readText() + ) + val store = store() + + store.resetToShipped(true) + + assertEquals(evening.accent, store.resolved(true).palette.accent) + assertEquals(evening.textAccent, store.resolved(true).palette.textAccent) + assertEquals(evening.labelTextFill, store.resolved(true).palette.labelTextFill) + } + + @Test + fun discardingChangesLetsTheFileApplyAgain() { + fileRoles = mapOf(PaletteRole.ACCENT to Color(0xFF00FF00)) + val store = store() + store.set(false, PaletteRole.ACCENT, "#FF0000") + + store.discardChanges(false) + + assertEquals(Color(0xFF00FF00), store.resolved(false).palette.accent) + assertEquals(PaletteSource.FILE, store.resolved(false).roles[PaletteRole.ACCENT]!!.source) + assertTrue(stored.getValue(false).isEmpty()) + } + + @Test + fun theSnapshotRestoresWhatWasInForceWhenItWasTaken() { + val store = store() + store.set(false, PaletteRole.ACCENT, "#FF0000") + + store.takeSnapshot() + store.set(false, PaletteRole.ACCENT, "#0000FF") + store.set(false, PaletteRole.TEXT, "#00FF00") + store.restoreSnapshot() + + // Including the change that was already there: the snapshot is not "shipped". + assertEquals(Color(0xFFFF0000), store.resolved(false).palette.accent) + assertEquals(PaletteSource.SHIPPED, store.resolved(false).roles[PaletteRole.TEXT]!!.source) + } + + @Test + fun theSnapshotRestoresBothDesignsAndNotOnlyTheOneInForce() { + /* + * takeSnapshot captures both, and the button says "back to how it was". An operator + * who changed a colour, switched day/evening from the main window's menu, changed + * another and then asked to go back means both -- undoing half would leave a state + * they never chose. + */ + val store = store() + store.takeSnapshot() + + store.set(false, PaletteRole.ACCENT, "#FF0000") + store.set(true, PaletteRole.ACCENT, "#00FF00") + store.restoreSnapshot() + + assertEquals( + PaletteSource.SHIPPED, + store.resolved(false).roles[PaletteRole.ACCENT]!!.source, + "the daylight change survived", + ) + assertEquals( + PaletteSource.SHIPPED, + store.resolved(true).roles[PaletteRole.ACCENT]!!.source, + "the evening change survived", + ) + } + + @Test + fun restoringWithoutASnapshotChangesNothing() { + val store = store() + store.set(false, PaletteRole.ACCENT, "#FF0000") + + store.restoreSnapshot() + + assertEquals(Color(0xFFFF0000), store.resolved(false).palette.accent) + } + + @Test + fun theLifelineReadsTheShippedSheetAndNotTheResolvedPalette() { + /* + * The rescue button is drawn in these colours. If it ever read the resolved palette, + * it would vanish in exactly the palette it exists to undo -- and nobody would find + * out until they needed it. + */ + val store = store() + val shippedBase = store.shipped(false).base + + PaletteRole.values().forEach { store.set(false, it, "#000000") } + + assertEquals(shippedBase, store.shipped(false).base) + assertEquals(Color.Black, store.resolved(false).palette.base) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/PublicMessageColumnsTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/PublicMessageColumnsTest.kt new file mode 100644 index 00000000..39952e45 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/PublicMessageColumnsTest.kt @@ -0,0 +1,70 @@ +package kst4contest.view.compose + +import kst4contest.model.ChatMember +import kst4contest.model.ChatMessage +import kst4contest.observe.SimpleValue +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertDoesNotThrow +import org.junit.jupiter.api.Assertions.assertEquals + +/** + * The public message tab, the third of the three below the station list. + * + * The other two reuse the monitor tables of Etappe 4 under their own layout ids; this + * one is its own. Its ids are the operator's stored widths, and its rows come off the + * wire half-filled. + */ +class PublicMessageColumnsTest { + + @Test + fun `the ids are the ones the stored layout uses`() { + assertEquals( + listOf("time", "callsign", "name", "last-qrg", "message", "category"), + PublicMessageColumns.all().map { it.id }, + ) + } + + @Test + fun `the headings are the ones the operator reads`() { + assertEquals( + listOf("Time", "Callsign", "Name", "Last QRG", "Message", "Category"), + PublicMessageColumns.all().map { it.title() }, + ) + } + + @Test + fun `a message without a sender reads as empty, not as a crash`() { + val bare = ChatMessage() + + PublicMessageColumns.all().forEach { column -> + assertDoesNotThrow({ column.value(bare) }, "column ${column.id}") + } + } + + @Test + fun `the time is a clock time, as it is in every other table`() { + val message = ChatMessage().apply { messageGeneratedTime = "1759000000" } + + assertEquals("19:06:40", PublicMessageColumns.all().first { it.id == "time" }.value(message)) + } + + @Test + fun `callsign, name and QRG come from the sender`() { + val message = ChatMessage().apply { + sender = ChatMember().apply { + callSign = "DN9APW" + name = "Philipp" + frequency = SimpleValue("144.3") + } + messageText = "CQ contest" + } + + val columns = PublicMessageColumns.all() + + assertEquals("DN9APW", columns.first { it.id == "callsign" }.value(message)) + assertEquals("Philipp", columns.first { it.id == "name" }.value(message)) + assertEquals("144.300", columns.first { it.id == "last-qrg" }.value(message), + "padded like every other QRG column") + assertEquals("CQ contest", columns.first { it.id == "message" }.value(message)) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/SelectedStationStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/SelectedStationStateTest.kt new file mode 100644 index 00000000..41a83daa --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/SelectedStationStateTest.kt @@ -0,0 +1,226 @@ +package kst4contest.view.compose + +import kst4contest.model.ChatMember +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue + +/** + * The panel below the station list, for the station currently selected. + * + * Its nine "tag not qrv" marks are written back to the station and propagated to the + * active members, so getting one wrong hides a station from every list that filters on + * it. The sked controls create a real reminder. Both are worth pinning. + */ +class SelectedStationStateTest { + + private class Session { + val propagated = mutableListOf() + var skedsCreated = 0 + var lastSkedMinutes: Int? = null + var lastSkedMode: String? = null + val failMarked = mutableListOf() + val failReset = mutableListOf() + + fun state() = SelectedStationState( + propagateNotQrv = { propagated.add(it.callSign.orEmpty()) }, + createSked = { _, minutes, _, mode -> + skedsCreated++ + lastSkedMinutes = minutes + lastSkedMode = mode + true + }, + markSkedFail = { failMarked.add(it.callSign.orEmpty()) }, + resetSkedFail = { failReset.add(it.callSign.orEmpty()) }, + ) + } + + private fun member(call: String) = ChatMember().apply { callSign = call } + + @Test + fun `without a selection there is nothing to act on`() { + val state = Session().state() + + assertNull(state.selected) + assertFalse(state.canCreateSked, "a sked needs a station to be with") + assertFalse(state.canLookUp, "there is no callsign to look up") + } + + @Test + fun `tagging a band writes it to the station and propagates`() { + val session = Session() + val state = session.state() + val dn9apw = member("DN9APW") + state.select(dn9apw) + + state.tagNotQrv(NotQrvBand.B_144, true) + + assertFalse(dn9apw.isQrv144, "not QRV means the QRV flag goes false") + assertEquals(listOf("DN9APW"), session.propagated, + "every list filtering on QRV has to learn about it") + } + + @Test + fun `tag not qrv all covers every band`() { + val session = Session() + val state = session.state() + val member = member("DO5AMF") + state.select(member) + + state.tagNotQrvAll(true) + + NotQrvBand.entries.forEach { band -> + assertTrue(state.isTaggedNotQrv(band), "band ${band.label}") + } + assertFalse(member.isQrv50) + assertFalse(member.isQrv10G) + } + + @Test + fun `clearing tag not qrv all puts every band back`() { + val state = Session().state() + val member = member("DO5AMF") + state.select(member) + state.tagNotQrvAll(true) + + state.tagNotQrvAll(false) + + NotQrvBand.entries.forEach { band -> + assertFalse(state.isTaggedNotQrv(band), "band ${band.label}") + } + assertTrue(member.isQrv144) + } + + @Test + fun `selecting another station shows that station's tags`() { + val state = Session().state() + val tagged = member("DN9APW").apply { isQrv432 = false } + val untagged = member("DO5AMF") + + state.select(tagged) + assertTrue(state.isTaggedNotQrv(NotQrvBand.B_432)) + + state.select(untagged) + assertFalse(state.isTaggedNotQrv(NotQrvBand.B_432), + "the panel shows the selected station, not the one before it") + } + + @Test + fun `a sked needs a selection and is created once`() { + val session = Session() + val state = session.state() + state.select(member("DN9APW")) + state.skedMinutes = 10 + + assertTrue(state.canCreateSked) + assertTrue(state.createSked()) + + assertEquals(1, session.skedsCreated) + assertEquals(10, session.lastSkedMinutes) + } + + @Test + fun `creating a sked without a selection does nothing`() { + val session = Session() + val state = session.state() + + assertFalse(state.createSked()) + assertEquals(0, session.skedsCreated) + } + + @Test + fun `the message filter is one choice, not four`() { + val state = Session().state() + + state.messageFilter = SelectedMessageFilter.PM_TO_ME + assertEquals(SelectedMessageFilter.PM_TO_ME, state.messageFilter) + + state.messageFilter = SelectedMessageFilter.PUBLIC + assertEquals(SelectedMessageFilter.PUBLIC, state.messageFilter, + "the JavaFX radio buttons were one toggle group; two cannot be on") + } + + /** + * No filter is chosen until the operator chooses one. JavaFX has the + * setSelected(true) on "pm to me" commented out, so the group starts with nothing on, + * and starting on a filter would silently hide messages the operator never asked to + * hide. + */ + @Test + fun `no message filter is chosen to begin with`() { + assertNull(Session().state().messageFilter) + } + + @Test + fun `the lookup addresses carry the selected callsign`() { + val state = Session().state() + state.select(member("DN9APW")) + + assertTrue(state.qrzComUrl().endsWith("DN9APW")) + assertTrue(state.qrzCqUrl().endsWith("DN9APW")) + } + + @Test + fun `the sked offers the minutes the JavaFX choice offered`() { + assertEquals( + listOf(2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 20), + SelectedStationState.SKED_MINUTES, + ) + assertEquals(5, Session().state().skedMinutes, "the default it selected") + } + + @Test + fun `the sked offers the two modes`() { + assertEquals(listOf("SSB", "CW"), SelectedStationState.SKED_MODES) + } + + @Test + fun `the reminder offers the three offset patterns`() { + assertEquals(listOf("2+1", "5+2+1", "10+5+2+1"), SelectedStationState.REMINDER_OFFSETS) + } + + @Test + fun `the chosen mode reaches the sked`() { + val session = Session() + val state = session.state() + state.select(member("DN9APW")) + state.skedMode = "CW" + + state.createSked() + + assertEquals("CW", session.lastSkedMode) + } + + @Test + fun `marking a sked as failed names the selected station`() { + val session = Session() + val state = session.state() + state.select(member("DN9APW")) + + state.markSkedFail() + + assertEquals(listOf("DN9APW"), session.failMarked) + } + + @Test + fun `resetting the failure names it too`() { + val session = Session() + val state = session.state() + state.select(member("DO5AMF")) + + state.resetSkedFail() + + assertEquals(listOf("DO5AMF"), session.failReset) + } + + @Test + fun `marking a failure without a selection does nothing`() { + val session = Session() + + session.state().markSkedFail() + + assertTrue(session.failMarked.isEmpty()) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/SettingsFieldCoverageTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/SettingsFieldCoverageTest.kt new file mode 100644 index 00000000..7c9c37cd --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/SettingsFieldCoverageTest.kt @@ -0,0 +1,44 @@ +package kst4contest.view.compose + +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertTrue +import java.io.File + +/** + * Guards against a setting quietly disappearing during the port. + * + * The JavaFX settings window called these ChatPreferences setters. Every one of + * them must still be called from the Compose settings sources, or an operator + * loses a setting they could configure before — and nothing about that fails to + * compile. + * + * The list was derived mechanically: the setters called between settingsStage and + * the Profiles tab, intersected with the setters ChatPreferences actually declares, + * so JavaFX control setters like setDisable or setPrefWidth are excluded. + * + * This checks text occurrence, not runtime behaviour. It cannot tell whether a + * setter is called with the right value, only that it is called at all. That is + * little, but it is the only check that covers all of them mechanically. + */ +class SettingsFieldCoverageTest { + + @Test + fun `every setting the JavaFX window could write is still written`() { + val expected = File("src/test/resources/settings-fields.txt") + .readLines().map { it.trim() }.filter { it.isNotEmpty() } + + val composeDir = File("src/main/kotlin/kst4contest/view/compose") + val composeSources = if (composeDir.isDirectory) { + composeDir.walkTopDown().filter { it.extension == "kt" } + .joinToString("\n") { it.readText() } + } else { + "" + } + + val missing = expected.filterNot { composeSources.contains("$it(") } + + assertTrue(missing.isEmpty(), + "settings not written by any Compose source (${missing.size} of ${expected.size}):\n" + + missing.joinToString("\n") { " $it" }) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/SettingsForeignWriteCoverageTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/SettingsForeignWriteCoverageTest.kt new file mode 100644 index 00000000..b293fbe1 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/SettingsForeignWriteCoverageTest.kt @@ -0,0 +1,50 @@ +package kst4contest.view.compose + +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertTrue +import java.io.File + +/** + * The second net. SettingsFieldCoverageTest only covers ChatPreferences setters, + * so a write to any other object slips through it — and the JavaFX settings window + * had five such writes: + * + * - setChatCategoryMain and setChatCategorySecondChat on ChatController, called on + * every category selection alongside the ChatPreferences write. Dropping them + * leaves the running session on the old category while the stored setting says + * otherwise. + * - setCallSign, setFrequency and setQra on the own ChatMember, kept in step with + * the station fields. + * + * The list was derived mechanically: the setters called in the settings range that + * ChatPreferences does not declare, intersected with the setters the project's own + * classes declare, which drops JavaFX control setters like setDisable. + */ +class SettingsForeignWriteCoverageTest { + + @Test + fun `every write outside ChatPreferences is still performed`() { + val expected = File("src/test/resources/settings-foreign-writes.txt") + .readLines().map { it.trim() }.filter { it.isNotEmpty() } + + val composeDir = File("src/main/kotlin/kst4contest/view/compose") + val sources = if (composeDir.isDirectory) { + composeDir.walkTopDown().filter { it.extension == "kt" } + .joinToString("\n") { it.readText() } + } else { + "" + } + + /* + * A name counts as covered when it appears as a call or as the target of a + * function reference. The category writes reach ChatController through the + * callbacks StationTabState takes, so the wiring in SettingsWindow is what + * satisfies them. + */ + val missing = expected.filterNot { sources.contains("$it(") || sources.contains("::$it") } + + assertTrue(missing.isEmpty(), + "writes outside ChatPreferences not performed by any Compose source " + + "(${missing.size} of ${expected.size}):\n" + missing.joinToString("\n") { " $it" }) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/SplitterStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/SplitterStateTest.kt new file mode 100644 index 00000000..f5ff2c75 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/SplitterStateTest.kt @@ -0,0 +1,225 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.snapshots.Snapshot +import org.junit.jupiter.api.Assertions.assertArrayEquals +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * Compose brings no SplitPane, so this is ours. An operator arranges the main window + * once for their screen and expects it back at the next contest, which makes the stored + * divider positions a setting rather than decoration. + */ +class SplitterStateTest { + + // ---- what it starts from ---------------------------------------------- + + @Test + fun `the stored positions are what it starts from`() { + val state = SplitterState(paneCount = 2, stored = doubleArrayOf(0.51)) {} + assertEquals(listOf(0.51f), state.positions) + } + + /** + * A profile written by an older version has fewer positions than the window now has + * dividers. Falling back beats starting with a window whose panes have no size. + */ + @Test + fun `too few stored positions fall back to an even split`() { + val state = SplitterState(paneCount = 5, stored = doubleArrayOf(0.62)) {} + assertEquals(listOf(0.2f, 0.4f, 0.6f, 0.8f), state.positions) + } + + @Test + fun `too many stored positions fall back as well`() { + val state = SplitterState(paneCount = 2, stored = doubleArrayOf(0.3, 0.6, 0.9)) {} + assertEquals(listOf(0.5f), state.positions) + } + + @Test + fun `positions out of order fall back rather than drawing inside out`() { + val state = SplitterState(paneCount = 3, stored = doubleArrayOf(0.8, 0.2)) {} + assertEquals(listOf(1f / 3f, 2f / 3f), state.positions) + } + + @Test + fun `a position outside the pane falls back`() { + assertEquals(listOf(0.5f), SplitterState(paneCount = 2, stored = doubleArrayOf(1.4)) {}.positions) + assertEquals(listOf(0.5f), SplitterState(paneCount = 2, stored = doubleArrayOf(-0.1)) {}.positions) + } + + @Test + fun `a single pane has no divider at all`() { + val state = SplitterState(paneCount = 1, stored = doubleArrayOf()) {} + assertTrue(state.positions.isEmpty()) + } + + // ---- dragging ---------------------------------------------------------- + + @Test + fun `dragging a divider moves it`() { + val state = SplitterState(paneCount = 2, stored = doubleArrayOf(0.5)) {} + state.drag(index = 0, to = 0.7f, totalPx = 1000f) + assertEquals(0.7f, state.positions[0], 0.001f) + } + + /** + * A divider stops at its neighbours. In JavaFX pushing one along shoved the next out + * of the way, which is how operators ended up with panes they could not get back. + */ + @Test + fun `a divider stops at its neighbour rather than pushing it`() { + val state = SplitterState(paneCount = 3, stored = doubleArrayOf(0.3, 0.6)) {} + state.drag(index = 0, to = 0.9f, totalPx = 1000f) + + assertTrue(state.positions[0] < state.positions[1], "the first divider passed the second") + assertEquals(0.6f, state.positions[1], 0.001f, "the second divider moved") + } + + @Test + fun `a divider stops at the previous one too`() { + val state = SplitterState(paneCount = 3, stored = doubleArrayOf(0.3, 0.6)) {} + state.drag(index = 1, to = 0.05f, totalPx = 1000f) + assertTrue(state.positions[1] > state.positions[0]) + } + + /** Every pane keeps a minimum, or a table can be dragged away to nothing by accident. */ + @Test + fun `no pane can be dragged smaller than its minimum`() { + val state = SplitterState(paneCount = 2, stored = doubleArrayOf(0.5), minPanePx = 100f) {} + state.drag(index = 0, to = 0.01f, totalPx = 1000f) + assertEquals(0.1f, state.positions[0], 0.001f) + } + + @Test + fun `the minimum holds at the far edge as well`() { + val state = SplitterState(paneCount = 2, stored = doubleArrayOf(0.5), minPanePx = 100f) {} + state.drag(index = 0, to = 0.99f, totalPx = 1000f) + assertEquals(0.9f, state.positions[0], 0.001f) + } + + /** A window too narrow for the minimums must still lay out, not divide by zero. */ + @Test + fun `an impossibly narrow window still yields usable positions`() { + val state = SplitterState(paneCount = 3, stored = doubleArrayOf(0.33, 0.66), minPanePx = 100f) {} + state.drag(index = 0, to = 0.5f, totalPx = 50f) + assertTrue(state.positions.all { it.isFinite() }) + assertTrue(state.positions[0] <= state.positions[1]) + } + + // ---- saving ------------------------------------------------------------ + + /** + * Saved on release, not on every mouse move. The JavaFX version called + * requestLayoutSave() on every pixel of a drag and wrote the profile to disk while + * the operator was still holding the mouse down. + */ + @Test + fun `dragging saves nothing until the mouse is released`() { + var saved: DoubleArray? = null + val state = SplitterState(paneCount = 2, stored = doubleArrayOf(0.5)) { saved = it } + + state.drag(index = 0, to = 0.7f, totalPx = 1000f) + assertNull(saved, "a drag in progress wrote to the profile") + + state.dragFinished() + assertArrayEquals(doubleArrayOf(0.7), saved!!, 0.001) + } + + /** A drag that changed nothing must not write the profile either. */ + @Test + fun `a release without a change saves nothing`() { + var saves = 0 + val state = SplitterState(paneCount = 2, stored = doubleArrayOf(0.5)) { saves++ } + + state.dragFinished() + assertEquals(0, saves) + + state.drag(index = 0, to = 0.5f, totalPx = 1000f) + state.dragFinished() + assertEquals(0, saves, "a drag that moved nothing was saved") + } + + /** The counterpart of the deferred Etappe 4 minor: a refused move is not a change. */ + @Test + fun `a refused drag is not saved`() { + var saves = 0 + val state = SplitterState(paneCount = 2, stored = doubleArrayOf(0.9), minPanePx = 100f) { saves++ } + + state.drag(index = 0, to = 0.99f, totalPx = 1000f) + state.dragFinished() + assertEquals(0, saves, "a drag that was clamped back to where it started was saved") + } + + // ---- the dividers take room too --------------------------------------- + + /** + * The panes and the divider handles are laid out as siblings, so the panes may only + * have what is left after the handles. Distributing the full length instead overflows + * the splitter by one handle width per divider — 20 dp for the five-pane message + * column — and the last pane is clipped off the bottom. + */ + @Test + fun `panes and dividers together fit the splitter exactly`() { + val state = SplitterState(paneCount = 5, stored = doubleArrayOf(0.62, 0.7, 0.75, 0.9)) {} + val total = 800f + val handle = 5f + + val available = SplitterState.availableFor(total, dividerPx = handle, paneCount = 5) + val panes = state.paneSizes(available) + + assertEquals( + total, + panes.sum() + handle * 4, + 0.01f, + "panes plus handles must be the splitter's length", + ) + } + + @Test + fun `a splitter with one pane needs no room for dividers`() { + assertEquals(500f, SplitterState.availableFor(500f, dividerPx = 5f, paneCount = 1)) + } + + /** A splitter too small for its own handles must not hand out negative lengths. */ + @Test + fun `a splitter smaller than its handles hands out nothing rather than less than nothing`() { + val available = SplitterState.availableFor(10f, dividerPx = 5f, paneCount = 5) + assertEquals(0f, available) + + val state = SplitterState(paneCount = 5, stored = doubleArrayOf(0.2, 0.4, 0.6, 0.8)) {} + assertTrue(state.paneSizes(available).all { it >= 0f }) + } + + // ---- what a draw subscribes to ---------------------------------------- + + @Test + fun `drawing the splitter subscribes to the positions`() { + val state = SplitterState(paneCount = 3, stored = doubleArrayOf(0.3, 0.6)) {} + val read = mutableSetOf() + + Snapshot.observe(readObserver = { read += it.toString() }) { + state.positions.forEach { it.toString() } + } + + assertTrue(read.isNotEmpty(), "the positions were read without subscribing") + } + + @Test + fun `the pane sizes follow from the positions`() { + val state = SplitterState(paneCount = 3, stored = doubleArrayOf(0.25, 0.75)) {} + assertEquals(listOf(250f, 500f, 250f), state.paneSizes(totalPx = 1000f)) + } + + @Test + fun `the pane sizes always add up to the whole`() { + val state = SplitterState(paneCount = 4, stored = doubleArrayOf(0.1, 0.2, 0.9)) {} + assertEquals(777f, state.paneSizes(totalPx = 777f).sum(), 0.01f) + } + + private fun assertNull(value: Any?, message: String) { + assertFalse(value != null, message) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/StationColumnsTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/StationColumnsTest.kt new file mode 100644 index 00000000..5afcc76c --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/StationColumnsTest.kt @@ -0,0 +1,136 @@ +package kst4contest.view.compose + +import kst4contest.model.ChatMember +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertDoesNotThrow +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue + +/** + * The 22 columns of the station list. + * + * The ids are the operator's stored layout — renaming one loses their column widths + * without a word — and these rows come from the network, so every value has to survive + * a half-filled station. + * + * "wkdany" sits at the END of the worked group, not the start. Pinned to the JavaFX + * table, which adds the band sub-columns under `isStn_bandActiveXX()` and only then + * `workedCol.getColumns().add(wkdAny_subcol)` (`Kst4ContestApplication.java:2496`). + * + * A band cell's text comes from the `formatBand` the caller supplies, because the + * JavaFX cell factory distinguishes worked from new from unavailable; the production + * caller passes `formatBandCellStatus` (`:10460`). + */ +class StationColumnsTest { + + private fun columns() = StationColumns.all( + tropoOf = { "" }, + priorityScoreOf = { 0.0 }, + formatBand = { _, _, worked -> if (worked) "X" else "" }, + ) + + @Test + fun `the ids are the ones the stored layout uses`() { + assertEquals( + listOf( + "callsign", "name", "qra", "qrb", "qtf", "qrg", "airscout", "tropo", + "score", "activity", "band-50", "band-70", "band-144", "band-432", + "band-1296", "band-2320", "band-3400", "band-5760", "band-10g", + "worked-any", "not-qrv", "category", + ), + columns().map { it.id }, + ) + } + + @Test + fun `the headings are the ones the operator reads`() { + assertEquals( + listOf( + "Callsign", "Name", "QRA", "QRB", "QTF", "QRG", "AP [minutes / pot%]", + "Tropo", "Score", "Act", "50", "70", "144", "432", "23", + "13", "9", "6", "3", "wkdany", "NOT QRV @", "Category", + ), + columns().map { it.title() }, + ) + } + + @Test + fun `the worked columns are grouped under one heading`() { + // Without the group, ten columns headed "50 70 144 432 23 13 9 6 3 wkdany" + // say nothing about what they mean. The JavaFX table put them under "worked", + // and added wkdany last. + val grouped = columns().filter { it.group == "worked" }.map { it.id } + + assertEquals( + listOf("band-50", "band-70", "band-144", "band-432", "band-1296", + "band-2320", "band-3400", "band-5760", "band-10g", "worked-any"), + grouped, + ) + } + + @Test + fun `columns outside that group carry no group`() { + assertNull(columns().first { it.id == "callsign" }.group) + assertNull(columns().first { it.id == "category" }.group) + } + + @Test + fun `a half-filled station reads as empty, not as a crash`() { + val bare = ChatMember() + + columns().forEach { column -> + assertDoesNotThrow({ column.value(bare) }, "column ${column.id}") + } + } + + @Test + fun `a band column shows a cross only when that band was worked`() { + val worked144 = ChatMember().apply { isWorked144 = true } + + val band144 = columns().first { it.id == "band-144" } + val band432 = columns().first { it.id == "band-432" } + + assertEquals("X", band144.value(worked144)) + assertEquals("", band432.value(worked144)) + } + + @Test + fun `the NOT QRV column names the bands the station is not on`() { + /* + * Every QRV flag starts true — a station is assumed to be on every band until + * it says otherwise — so a fresh row leaves this column empty and it fills as + * bands are marked off. Listing the QRV bands instead would put a full column + * on almost every row and mean the opposite of its heading. + */ + val member = ChatMember().apply { + isQrv432 = false + isQrv1240 = false + } + + val notQrv = columns().first { it.id == "not-qrv" }.value(member) + + assertTrue(notQrv.contains("70cm"), "432 was marked off") + assertTrue(notQrv.contains("23cm"), "1240 too") + assertTrue(!notQrv.contains("2m"), "144 was never marked off, so it is not listed") + } + + @Test + fun `a station on every band has an empty NOT QRV column`() { + assertEquals("", columns().first { it.id == "not-qrv" }.value(ChatMember())) + } + + @Test + fun `tropo and score come from outside the station`() { + val columns = StationColumns.all( + tropoOf = { "12 dB" }, + priorityScoreOf = { 250.0 }, + formatBand = { _, _, _ -> "" }, + ) + val member = ChatMember() + + assertEquals("12 dB", columns.first { it.id == "tropo" }.value(member), + "reachability is computed by the controller, not carried by the row") + assertEquals("250", columns.first { it.id == "score" }.value(member)) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/StationFilterStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/StationFilterStateTest.kt new file mode 100644 index 00000000..08e9b506 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/StationFilterStateTest.kt @@ -0,0 +1,157 @@ +package kst4contest.view.compose + +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue + +/** + * The filter bar's rules. + * + * Its 25 toggles are not 25 states. Eighteen switch a predicate in the controller on + * or off, eight are one mutually exclusive group that only writes a bearing into the + * QTF field, and one colours a cell without filtering anything. Getting that wrong + * would put a station in front of the operator that their filter excludes — or hide + * one it does not. + */ +class StationFilterStateTest { + + @Test + fun `nothing is filtered to begin with`() { + assertTrue(StationFilterState().activeFilters.isEmpty()) + } + + @Test + fun `a toggle switches exactly its own filter`() { + val filters = StationFilterState() + + filters.onlyNewGrids = true + + assertEquals(setOf(StationFilter.ONLY_NEW_GRIDS), filters.activeFilters) + } + + @Test + fun `grid colouring is not a filter`() { + val filters = StationFilterState() + + filters.gridColouring = true + + assertTrue(filters.activeFilters.isEmpty(), + "it colours the locator cell; a station must not vanish because of it") + assertTrue(filters.gridColouring) + } + + @Test + fun `each band hides only stations worked on that band`() { + val filters = StationFilterState() + + filters.setHideWorkedOn(WorkedBandFilter.B_144, true) + + assertEquals(setOf(StationFilter.HIDE_WORKED_144), filters.activeFilters) + + filters.setHideWorkedOn(WorkedBandFilter.B_432, true) + + assertEquals( + setOf(StationFilter.HIDE_WORKED_144, StationFilter.HIDE_WORKED_432), + filters.activeFilters, + ) + } + + @Test + fun `a bearing button picks one direction and its degrees`() { + val filters = StationFilterState() + + filters.toggleBearing(Bearing.NE) + + assertEquals(Bearing.NE, filters.bearing) + assertEquals(45.0, filters.qtfDegrees) + } + + @Test + fun `the bearings are mutually exclusive, as their toggle group was`() { + val filters = StationFilterState() + filters.toggleBearing(Bearing.N) + + filters.toggleBearing(Bearing.SW) + + assertEquals(Bearing.SW, filters.bearing) + assertEquals(225.0, filters.qtfDegrees) + } + + /** + * Pressing a direction switches the QTF filter on. + * + * Verified against the JavaFX toggle group rather than assumed: its + * selectedToggleProperty listener does + * `chatMemberTableFilterQtfEnableChkbx.setSelected(true)` whenever a direction is + * selected, and `false` when the selection is cleared + * (`Kst4ContestApplication.java:8758-8767`). An earlier version of this test claimed + * the opposite and had to be taken on faith; it is pinned to the source now. + */ + @Test + fun `picking a bearing switches the QTF filter on, as the toggle group did`() { + val filters = StationFilterState() + + filters.toggleBearing(Bearing.E) + + assertEquals(setOf(StationFilter.QTF), filters.activeFilters) + assertEquals(90.0, filters.qtfDegrees) + } + + /** Pressing the selected direction again clears it, and the filter with it. */ + @Test + fun `pressing the same bearing again switches the QTF filter off`() { + val filters = StationFilterState() + filters.toggleBearing(Bearing.E) + + filters.toggleBearing(Bearing.E) + + assertNull(filters.bearing) + assertTrue(filters.activeFilters.isEmpty()) + } + + @Test + fun `the QTF filter can also be switched on without a direction`() { + val filters = StationFilterState() + + filters.qtfEnabled = true + + assertEquals(setOf(StationFilter.QTF), filters.activeFilters) + } + + @Test + fun `the maximum QRB filter needs its own switch`() { + val filters = StationFilterState() + + filters.maxQrbKm = 300.0 + assertTrue(filters.activeFilters.isEmpty(), "a distance alone filters nothing") + + filters.maxQrbEnabled = true + assertEquals(setOf(StationFilter.MAX_QRB), filters.activeFilters) + } + + @Test + fun `a search text filters while it is there and stops when it is cleared`() { + val filters = StationFilterState() + + filters.searchText = "DN9" + assertEquals(setOf(StationFilter.SEARCH_TEXT), filters.activeFilters) + + filters.searchText = " " + assertTrue(filters.activeFilters.isEmpty(), + "blank is not a search; leaving it would hide every station") + } + + @Test + fun `switching a filter off removes it again`() { + val filters = StationFilterState() + filters.hideInactive = true + filters.onlyNewGrids = true + + filters.hideInactive = false + + assertEquals(setOf(StationFilter.ONLY_NEW_GRIDS), filters.activeFilters) + assertFalse(filters.hideInactive) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/StatusIndicatorStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/StatusIndicatorStateTest.kt new file mode 100644 index 00000000..8391b22f --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/StatusIndicatorStateTest.kt @@ -0,0 +1,414 @@ +package kst4contest.view.compose + +import kst4contest.controller.On4KstConnectionState +import kst4contest.model.ThreadStateMessage +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNotNull +import androidx.compose.runtime.snapshots.Snapshot +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertSame +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * The status bar tells the operator whether the link is alive and reminds them of a + * sked. Both are read at a glance mid contest, so the mapping from state to badge is + * pinned here rather than left to the eye. + */ +class StatusIndicatorStateTest { + + // ---- the connection badge ---------------------------------------------- + + @Test + fun `online shows the plain badge`() { + assertEquals(ConnectionBadge.ONLINE, ConnectionIndicator.badgeFor(On4KstConnectionState.ONLINE)) + assertEquals("LINK", ConnectionBadge.ONLINE.label) + } + + @Test + fun `every step of the handshake counts as busy`() { + listOf( + On4KstConnectionState.CONNECTING, + On4KstConnectionState.WAITING_FOR_LOGIN_PROMPT, + On4KstConnectionState.AUTHENTICATING, + On4KstConnectionState.SYNCING_MAIN_CHAT, + On4KstConnectionState.SYNCING_SECOND_CHAT, + On4KstConnectionState.STOPPING, + ).forEach { + assertEquals(ConnectionBadge.BUSY, ConnectionIndicator.badgeFor(it), "$it") + } + assertEquals("LINK…", ConnectionBadge.BUSY.label) + } + + /** + * A scheduled reconnect is not a working link. It reads as offline on purpose: the + * operator must see that nothing is being sent right now. + */ + @Test + fun `waiting for a reconnect reads as offline`() { + assertEquals(ConnectionBadge.OFFLINE, ConnectionIndicator.badgeFor(On4KstConnectionState.RECONNECT_WAIT)) + assertEquals(ConnectionBadge.OFFLINE, ConnectionIndicator.badgeFor(On4KstConnectionState.DISCONNECTED)) + assertEquals("LINK!", ConnectionBadge.OFFLINE.label) + } + + /** Before the first callback there is no state, and no state is not a link. */ + @Test + fun `no state at all reads as offline`() { + assertEquals(ConnectionBadge.OFFLINE, ConnectionIndicator.badgeFor(null)) + } + + @Test + fun `no connection state is left unmapped`() { + On4KstConnectionState.entries.forEach { + assertNotNull(ConnectionIndicator.badgeFor(it), "$it has no badge") + } + } + + @Test + fun `the tooltip names the state and the detail`() { + assertEquals( + "ON4KST link: ONLINE\nLogged in as DN9APW", + ConnectionIndicator.tooltipFor(On4KstConnectionState.ONLINE, "Logged in as DN9APW"), + ) + } + + @Test + fun `a missing detail falls back to the state name`() { + assertEquals( + "ON4KST link: DISCONNECTED\nDISCONNECTED", + ConnectionIndicator.tooltipFor(On4KstConnectionState.DISCONNECTED, " "), + ) + assertEquals( + "ON4KST link: DISCONNECTED\nDISCONNECTED", + ConnectionIndicator.tooltipFor(On4KstConnectionState.DISCONNECTED, null), + ) + } + + // ---- the macOS menu title --------------------------------------------- + + /** + * The menu title splits finer than the badge: shutting down and reconnecting each + * get their own wording, because in the menu bar there is room to say it. + */ + @Test + fun `the macOS title distinguishes what the badge merges`() { + assertEquals("🟢 LINK: Connected", ConnectionIndicator.macOsMenuTitle(On4KstConnectionState.ONLINE)) + assertEquals("🟡 LINK: Connecting…", ConnectionIndicator.macOsMenuTitle(On4KstConnectionState.CONNECTING)) + assertEquals("🟡 LINK: Disconnecting…", ConnectionIndicator.macOsMenuTitle(On4KstConnectionState.STOPPING)) + assertEquals("🔴 LINK: Reconnecting…", ConnectionIndicator.macOsMenuTitle(On4KstConnectionState.RECONNECT_WAIT)) + assertEquals("🔴 LINK: Disconnected", ConnectionIndicator.macOsMenuTitle(On4KstConnectionState.DISCONNECTED)) + assertEquals("🔴 LINK: Disconnected", ConnectionIndicator.macOsMenuTitle(null)) + } + + /** + * The detail line under the macOS menu title. Same text the tooltip's second line + * carries, because it is the same information reaching the operator by the other route. + */ + @Test + fun `the macOS menu carries the detail as its own line`() { + assertEquals( + "Logged in as DN9APW", + ConnectionIndicator.detailFor(On4KstConnectionState.ONLINE, "Logged in as DN9APW"), + ) + } + + @Test + fun `a missing macOS detail falls back to the state name`() { + assertEquals( + "DISCONNECTED", + ConnectionIndicator.detailFor(On4KstConnectionState.DISCONNECTED, " "), + ) + assertEquals("DISCONNECTED", ConnectionIndicator.detailFor(null, null)) + } + + @Test + fun `no connection state is left without a macOS title`() { + On4KstConnectionState.entries.forEach { + assertTrue( + ConnectionIndicator.macOsMenuTitle(it).contains("LINK"), + "$it has no macOS title", + ) + } + } + + // ---- the blinking notices --------------------------------------------- + + @Test + fun `a notice starts hidden`() { + val notice = BlinkingNotice() + assertFalse(notice.visible) + assertEquals("", notice.text) + } + + @Test + fun `showing a notice reveals it with its text`() { + val notice = BlinkingNotice() + notice.show("REMINDER: DL0ABC T-5m") + assertTrue(notice.visible) + assertEquals("REMINDER: DL0ABC T-5m", notice.text) + assertEquals("REMINDER: DL0ABC T-5m", notice.tooltip) + } + + /** + * The badge sits in one row with the menu, so a long text is cut. The full text + * stays in the tooltip — nothing is lost, it is only not shouted. + */ + @Test + fun `a long text is cut for the badge but kept in the tooltip`() { + val long = "REMINDER: DL0ABC/P T-10m on 1296 MHz, please turn the antenna" + val notice = BlinkingNotice() + notice.show(long) + assertEquals(38, notice.text.length) + assertTrue(notice.text.endsWith("...")) + assertEquals(long.take(35) + "...", notice.text) + assertEquals(long, notice.tooltip) + } + + @Test + fun `a text that just fits is left alone`() { + val exactly38 = "x".repeat(38) + val notice = BlinkingNotice() + notice.show(exactly38) + assertEquals(exactly38, notice.text) + } + + @Test + fun `a separate tooltip survives the cut`() { + val notice = BlinkingNotice() + notice.show("BAND+ DL0ABC", tooltip = "DL0ABC is still missing 23cm and 13cm") + assertEquals("BAND+ DL0ABC", notice.text) + assertEquals("DL0ABC is still missing 23cm and 13cm", notice.tooltip) + } + + @Test + fun `hiding a notice takes it out of the bar`() { + val notice = BlinkingNotice() + notice.show("REMINDER: DL0ABC T-5m") + notice.hide() + assertFalse(notice.visible) + } + + /** + * A second reminder while the first is still blinking must blink again, not sit + * there statically. The revision is what the blink restarts on. + */ + @Test + fun `a second notice restarts the blink`() { + val notice = BlinkingNotice() + notice.show("first") + val afterFirst = notice.revision + notice.show("second") + assertTrue(notice.revision > afterFirst) + assertEquals("second", notice.text) + } + + /** + * The blink runs in the view, so it is cancelled if the bar leaves the composition — + * a splitter dragged shut, a profile switch. Without a generation-aware hide the + * notice would stay visible for the rest of the session: a magenta reminder stuck in + * the status bar for a sked that has long passed. + */ + @Test + fun `a notice can be hidden by the generation that showed it`() { + val notice = BlinkingNotice() + notice.show("REMINDER: DL0ABC T-5m") + val generation = notice.revision + + notice.hide(generation) + + assertFalse(notice.visible) + } + + /** + * And a stale blink must not hide the notice that replaced it. When a second reminder + * arrives while the first is still blinking, the first blink's cleanup runs after the + * second has already been shown. + */ + @Test + fun `an older generation cannot hide a newer notice`() { + val notice = BlinkingNotice() + notice.show("first") + val firstGeneration = notice.revision + + notice.show("second") + notice.hide(firstGeneration) + + assertTrue(notice.visible, "the stale blink hid the reminder that replaced it") + assertEquals("second", notice.text) + } + + @Test + fun `the blink lasts as long as it did in JavaFX`() { + assertEquals(24, BlinkingNotice.BLINK_CYCLES) + assertEquals(500L, BlinkingNotice.BLINK_CYCLE_MILLIS) + assertEquals(12_000L, BlinkingNotice.blinkDurationMillis) + } + + // ---- what triggers a notice ------------------------------------------- + + @Test + fun `the reminder text names the call and the minutes left`() { + assertEquals("REMINDER: DL0ABC T-5m", StatusIndicators.reminderText("DL0ABC", 5)) + } + + @Test + fun `a band upgrade is recognized by the key`() { + val notice = StatusIndicators.bandUpgradeNoticeFor( + key = "BandUpgradeWatcher", + message = threadState(nick = "watcher", description = "BAND+ DL0ABC", info = "23cm missing"), + ) + assertNotNull(notice) + assertEquals("BAND+ DL0ABC", notice!!.first) + assertEquals("23cm missing", notice.second) + } + + @Test + fun `a band upgrade is recognized by the thread nickname`() { + assertNotNull( + StatusIndicators.bandUpgradeNoticeFor( + key = "worker-7", + message = threadState(nick = "bandUpgrade", description = "BAND+", info = "x"), + ), + ) + } + + @Test + fun `any other thread message is not a band upgrade`() { + assertNull( + StatusIndicators.bandUpgradeNoticeFor( + key = "ClusterReader", + message = threadState(nick = "cluster", description = "12 spots", info = "running"), + ), + ) + assertNull(StatusIndicators.bandUpgradeNoticeFor(key = "bandupgrade", message = null)) + assertNull(StatusIndicators.bandUpgradeNoticeFor(key = null, message = null)) + } + + /** + * ThreadStateMessage never hands out a blank description — it falls back to "on" + * or "FAILED" itself. So the notice shows that, and the tooltip, which has no such + * fallback, borrows the button text rather than appearing empty. + */ + @Test + fun `a band upgrade without its own wording borrows what it has`() { + val notice = StatusIndicators.bandUpgradeNoticeFor( + key = "bandupgrade", + message = ThreadStateMessage("x", true, " ", false), + ) + assertNotNull(notice) + assertEquals("on", notice!!.first) + assertEquals("on", notice.second) + } + + // ---- the background thread buttons ------------------------------------ + + @Test + fun `a thread reports itself into the bar once`() { + val buttons = ThreadStatusButtons() + buttons.update("ClusterReader", threadState(nick = "cluster", description = "12 spots", info = "running")) + buttons.update("ClusterReader", threadState(nick = "cluster", description = "13 spots", info = "still running")) + + assertEquals(1, buttons.buttons.size) + assertEquals("ClusterReader: 13 spots", buttons.buttons.single().label) + assertEquals("still running", buttons.buttons.single().tooltip) + } + + /** The bar is read left to right; a thread keeps the place it first took. */ + @Test + fun `threads keep the order they first reported in`() { + val buttons = ThreadStatusButtons() + buttons.update("Cluster", threadState(nick = "c", description = "a", info = "a")) + buttons.update("Sked", threadState(nick = "s", description = "b", info = "b")) + buttons.update("Cluster", threadState(nick = "c", description = "c", info = "c")) + + assertEquals(listOf("Cluster", "Sked"), buttons.buttons.map { it.sourceName }) + } + + /** + * The flash is the whole point of these buttons: it shows the thread is alive. + * It is on when the message lands and the view times it out again. + */ + @Test + fun `a fresh message flashes the button`() { + val buttons = ThreadStatusButtons() + buttons.update("Cluster", threadState(nick = "c", description = "a", info = "a")) + val button = buttons.buttons.single() + assertTrue(button.highlighted) + + button.clearHighlight() + assertFalse(button.highlighted) + + buttons.update("Cluster", threadState(nick = "c", description = "b", info = "b")) + assertTrue(button.highlighted) + } + + @Test + fun `the flash lasts as long as it did in JavaFX`() { + assertEquals(200L, ThreadStatusButtons.HIGHLIGHT_MILLIS) + } + + // ---- what a draw subscribes to ---------------------------------------- + + /** + * The bar is drawn from these values, so reading them has to register as a read. + * A plain field would draw once and then quietly go stale — the failure mode that + * cost this migration eleven defects, none of which any assertion could see. + */ + @Test + fun `drawing a notice subscribes to what can change`() { + val notice = BlinkingNotice() + notice.show("REMINDER: DL0ABC T-5m") + + val read = mutableSetOf() + Snapshot.observe(readObserver = { read += it.toString() }) { + notice.visible + notice.text + notice.tooltip + notice.revision + } + + assertEquals(4, read.size, "a notice value was read without subscribing: $read") + } + + @Test + fun `drawing the thread buttons subscribes to the list and the labels`() { + val buttons = ThreadStatusButtons() + buttons.update("Cluster", threadState(nick = "c", description = "a", info = "a")) + + val read = mutableSetOf() + Snapshot.observe(readObserver = { read += it.toString() }) { + buttons.buttons.forEach { + it.label + it.tooltip + it.highlighted + } + } + + // the list itself plus three values of the single button + assertEquals(4, read.size, "a button value was read without subscribing: $read") + } + + /** + * A thread that reports again does not change the list, only its own button. If the + * label were not state, the bar would freeze on the first message a worker sent. + */ + @Test + fun `a later message changes the button without touching the list`() { + val buttons = ThreadStatusButtons() + buttons.update("Cluster", threadState(nick = "c", description = "a", info = "a")) + val listBefore = buttons.buttons + val button = buttons.buttons.single() + + buttons.update("Cluster", threadState(nick = "c", description = "b", info = "b")) + + assertSame(listBefore, buttons.buttons) + assertSame(button, buttons.buttons.single()) + assertEquals("Cluster: b", button.label) + } + + private fun threadState(nick: String, description: String, info: String): ThreadStateMessage = + ThreadStateMessage(nick, true, info, false).apply { + setRunningInformationTextDescription(description) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/StylesheetDeclaredRolesTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/StylesheetDeclaredRolesTest.kt new file mode 100644 index 00000000..d8748673 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/StylesheetDeclaredRolesTest.kt @@ -0,0 +1,163 @@ +package kst4contest.view.compose + +import kst4contest.model.PaletteRole +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import java.io.File + +/** + * Which roles a stylesheet actually names. + * + * Not the same question as `read`, and conflating the two is the trap of this stage: `read` + * fills a missing role from the Modena defaults, so a file saying only `-fx-base` would + * silently override all six. A layer needs presence, not a complete palette. + * + * How far apart the two questions are is visible in the shipped sheets themselves -- the + * daylight one states no colour at all, and `read` still returns a full palette for it. + */ +class StylesheetDeclaredRolesTest { + + private fun shipped(name: String): String = + JavaFxStylesheet::class.java.getResource(name)!!.readText() + + @Test + fun aSheetNamingOneRoleDeclaresOnlyThatRole() { + // The accent, deliberately: nothing is derived from it, so one named means one role. + val declared = JavaFxStylesheet.declaredRoles(".root { -fx-accent: #0096C9; }") + + assertEquals(setOf(PaletteRole.ACCENT), declared.keys) + } + + @Test + fun aRoleStatedOutsideRootIsFoundAtItsOwnSelector() { + /* + * Three of the six live outside .root. A reader that only looked there would never + * find the text colour or the separator line -- which is half the palette. + */ + val declared = JavaFxStylesheet.declaredRoles( + """ + .label { -fx-text-fill: #112233; } + .separator *.line { -fx-background-color: #445566; } + """.trimIndent() + ) + + assertEquals(setOf(PaletteRole.TEXT, PaletteRole.SEPARATOR), declared.keys) + } + + @Test + fun aSheetStatingTheBaseWithoutTheBackgroundStatesTheDerivedWindowSurfaceToo() { + /* + * What JavaFX itself does: Modena's -fx-background is derive(-fx-base, 26.4%), so a + * sheet that states -fx-base and says nothing about -fx-background has stated the + * window surface as well. Without this the most natural hand edit is nearly inert -- + * an operator sets -fx-base to #303030, restarts, and the windows stay light grey, + * because base reaches the screen only through the menu strip and the selection tint. + * + * The file layer only. In the settings tab the two stay independent, which is the + * whole reason the spec keeps them as separate roles: six fields are visible there and + * the operator can set both. + */ + val declared = JavaFxStylesheet.declaredRoles(".root { -fx-base: #303030; }") + + assertEquals(setOf(PaletteRole.SURFACE, PaletteRole.WINDOW_SURFACE), declared.keys) + assertEquals( + JavaFxStylesheet.derive(declared.getValue(PaletteRole.SURFACE), 26.4), + declared.getValue(PaletteRole.WINDOW_SURFACE), + ) + } + + @Test + fun aStatedBackgroundIsNotReplacedByADerivedOne() { + val declared = JavaFxStylesheet.declaredRoles( + ".root { -fx-base: #303030; -fx-background: #112233; }" + ) + + assertEquals(colourOf("#112233"), declared.getValue(PaletteRole.WINDOW_SURFACE)) + } + + @Test + fun aSheetWithNoBaseDerivesNoWindowSurface() { + val declared = JavaFxStylesheet.declaredRoles(".label { -fx-text-fill: #112233; }") + + assertEquals(setOf(PaletteRole.TEXT), declared.keys) + } + + @Test + fun theSamePropertyUnderAnotherSelectorIsNotARole() { + // -fx-background-color appears a dozen times in the evening sheet. One is the role. + val declared = JavaFxStylesheet.declaredRoles( + ".scroll-bar { -fx-background-color: #445566; } .button:hover { -fx-text-fill: red; }" + ) + + assertTrue(declared.isEmpty(), "found roles where there are none: ${declared.keys}") + } + + @Test + fun aSheetNamingNothingDeclaresNothing() { + assertTrue(JavaFxStylesheet.declaredRoles("").isEmpty()) + assertTrue(JavaFxStylesheet.declaredRoles("/* just a comment */").isEmpty()) + assertTrue(JavaFxStylesheet.declaredRoles(".button { -fx-padding: 2px; }").isEmpty()) + } + + @Test + fun theShippedDaylightSheetStatesNoColourAtAll() { + /* + * Measured, not assumed: its .root carries only -fx-font-size, and every colour in + * the daylight design comes from JavaFX's Modena defaults by way of `read`. If this + * ever starts declaring a role, the daylight palette has gained a second source and + * the resolver's layer 1 needs looking at. + */ + val declared = JavaFxStylesheet.declaredRoles(shipped("/KST4ContestDefaultDay.css")) + + assertTrue(declared.isEmpty(), "the daylight sheet now declares ${declared.keys}") + } + + @Test + fun theShippedEveningSheetStatesEveryRole() { + /* + * It states the surface, the field interior, the accent, the label text and the + * separator line outright, and the window surface by implication -- it names -fx-base + * and no -fx-background, which is how JavaFX derives one. This pins the + * selector-and-property mapping against a real file: get a selector wrong and a role + * drops out without any other test noticing. + */ + val declared = JavaFxStylesheet.declaredRoles(shipped("/KST4ContestDefaultEvening.css")) + + assertEquals(PaletteRole.values().toSet(), declared.keys) + } + + @Test + fun aMissingFileDeclaresNothingRatherThanThrowing() { + val absent = File("/nonexistent/kst4contest/does-not-exist.css") + + assertTrue(JavaFxStylesheet.declaredRolesOfFile(absent).isEmpty()) + } + + @Test + fun anUnreadableOrNonsenseFileDeclaresNothingRatherThanThrowing() { + /* + * A client that will not start because of a broken colour file is worse than one in + * the wrong colours. Half-written files and files that are not CSS at all both exist, + * and this one is hand-edited by the operator. + */ + val nonsense = File.createTempFile("kst4contest-palette", ".css") + try { + nonsense.writeText("this is not css { -fx-base") + assertTrue(JavaFxStylesheet.declaredRolesOfFile(nonsense).isEmpty()) + } finally { + nonsense.delete() + } + + val directory = File.createTempFile("kst4contest-palette-dir", "").let { + it.delete() + it.mkdirs() + it + } + try { + assertTrue(JavaFxStylesheet.declaredRolesOfFile(directory).isEmpty()) + } finally { + directory.delete() + } + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/ThemeReadsPaletteStoreTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/ThemeReadsPaletteStoreTest.kt new file mode 100644 index 00000000..0e994749 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/ThemeReadsPaletteStoreTest.kt @@ -0,0 +1,83 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.test.ExperimentalTestApi +import androidx.compose.ui.test.runComposeUiTest +import kst4contest.model.PaletteRole +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +/** + * A colour change reaches a composed window without anything else happening. + * + * This is the one mechanism the stage's acceptance criterion hangs on, and it used not to + * work: `Kst4ContestTheme` took its palette from `remember(darkMode)`, so a change reached + * nothing until somebody toggled day/evening. A state-level test of the store cannot see + * that fault -- the store was always right, the theme never asked it again. + * + * Headless: no window is opened, only a composition. + */ +class ThemeReadsPaletteStoreTest { + + private var stored = "" + + private fun store() = PaletteStore( + shippedOf = { JavaFxStylesheet.read("/KST4ContestDefaultDay.css") }, + fileRolesOf = { emptyMap() }, + storedOverridesOf = { stored }, + storeOverrides = { _, encoded -> stored = encoded }, + ) + + @OptIn(ExperimentalTestApi::class) + @Test + fun aColourSetAfterTheFirstDrawReachesTheComposition() = runComposeUiTest { + val store = store() + val seen = mutableListOf() + + setContent { + CompositionLocalProvider(LocalPaletteStore provides store) { + Kst4ContestTheme(darkMode = false, baseFontSizeSp = 12f) { + // Reading the palette is what a control does; record what it was handed. + seen += LocalJavaFxPalette.current.base + } + } + } + + waitForIdle() + val firstDraw = seen.last() + + store.set(darkMode = false, role = PaletteRole.SURFACE, colour = "#FF0000") + waitForIdle() + + assertEquals( + Color(0xFFFF0000), + seen.last(), + "the composition still holds the palette from before the change, which is the " + + "remember(darkMode) fault this store exists to fix", + ) + assertEquals(store.shipped(false).base, firstDraw, "the first draw was not the shipped base") + } + + @OptIn(ExperimentalTestApi::class) + @Test + fun withoutAStoreTheShippedPaletteIsStillDrawn() { + /* + * Not caution: the operator profile picker composes before a profile, and therefore + * before a store, exists. It must still have colours. + */ + runComposeUiTest { + var seen: Color? = null + + setContent { + Kst4ContestTheme(darkMode = false, baseFontSizeSp = 12f) { + seen = LocalJavaFxPalette.current.base + } + } + + waitForIdle() + + assertEquals(JavaFxStylesheet.read("/KST4ContestDefaultDay.css").base, seen) + } + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/TimelineCandidateFieldsTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/TimelineCandidateFieldsTest.kt new file mode 100644 index 00000000..a1cdd25c --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/TimelineCandidateFieldsTest.kt @@ -0,0 +1,51 @@ +package kst4contest.view.compose + +import kst4contest.model.ChatCategory +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +/** + * Pins the field order of the timeline candidate. + * + * The JavaFX builder produced its own DTO and copied it across field by field; the builder + * now constructs this type directly. Three of the ten values are plain numbers of the same + * kind — minuteBucket, laneIndex and opportunityPotentialPercent are all Int — so a swapped + * pair would compile, run, and quietly draw the right station in the wrong lane at the wrong + * minute. Nothing else checks that. + */ +class TimelineCandidateFieldsTest { + + @Test + fun theTenValuesKeepTheirPositions() { + val category = ChatCategory(ChatCategory.VUHF) + + val candidate = TimelineCandidate( + "DL1ABC", "DL1ABC/P", category, 90_000L, 3, 1, 215.0, 42.5, 77, "tooltip", + ) + + assertEquals("DL1ABC", candidate.callSignRaw) + assertEquals("DL1ABC/P", candidate.displayCallSign) + assertEquals(category, candidate.preferredChatCategory) + assertEquals(90_000L, candidate.timeUntilMs) + assertEquals(3, candidate.minuteBucket) + assertEquals(1, candidate.laneIndex) + assertEquals(215.0, candidate.targetAzimuth) + assertEquals(42.5, candidate.score) + assertEquals(77, candidate.opportunityPotentialPercent) + assertEquals("tooltip", candidate.tooltipText) + } + + @Test + fun theSortTheStripReliesOnIsByMinuteThenLane() { + val category = ChatCategory(ChatCategory.VUHF) + fun candidate(minute: Int, lane: Int) = TimelineCandidate( + "DL1ABC", "DL1ABC", category, 0L, minute, lane, 0.0, 0.0, 0, null, + ) + + val sorted = listOf(candidate(2, 0), candidate(1, 1), candidate(1, 0)) + .sortedWith(compareBy({ it.minuteBucket }, { it.laneIndex })) + + // The builder sorts before handing the list over; the strip draws in that order. + assertEquals(listOf(1 to 0, 1 to 1, 2 to 0), sorted.map { it.minuteBucket to it.laneIndex }) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/TimelineStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/TimelineStateTest.kt new file mode 100644 index 00000000..7230a171 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/TimelineStateTest.kt @@ -0,0 +1,316 @@ +package kst4contest.view.compose + +import androidx.compose.runtime.snapshots.Snapshot +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * The timeline is the one view in this client that is read as a picture rather than as + * text, so its geometry and its fading rules are pinned here. Everything in this file + * is the original JavaFX behaviour; where it looks surprising, it is surprising there + * too and the test says so. + */ +class TimelineStateTest { + + private val width = 400f + + // ---- the potential colours -------------------------------------------- + + @Test + fun `the potential steps break where they always did`() { + assertEquals(PotentialLevel.HIGHEST, PotentialLevel.forPercent(100)) + assertEquals(PotentialLevel.HIGHEST, PotentialLevel.forPercent(95)) + assertEquals(PotentialLevel.HIGH, PotentialLevel.forPercent(94)) + assertEquals(PotentialLevel.HIGH, PotentialLevel.forPercent(75)) + assertEquals(PotentialLevel.MEDIUM, PotentialLevel.forPercent(74)) + assertEquals(PotentialLevel.MEDIUM, PotentialLevel.forPercent(50)) + assertEquals(PotentialLevel.LOW, PotentialLevel.forPercent(49)) + assertEquals(PotentialLevel.LOW, PotentialLevel.forPercent(0)) + } + + /** A missing potential arrives as a negative number and must not fall through. */ + @Test + fun `an unknown potential is the lowest step`() { + assertEquals(PotentialLevel.LOW, PotentialLevel.forPercent(-1)) + } + + // ---- the geometry ------------------------------------------------------ + + /** + * Counter-intuitive and deliberate: the strip is not a progress bar. Time grows to + * the right, so what is about to happen sits at the LEFT edge. + */ + @Test + fun `now is on the left and the far future on the right`() { + val imminent = TimelineGeometry.xFor(0, width, TimelineGeometry.SKED_MARGIN)!! + val distant = TimelineGeometry.xFor(TimelineGeometry.PREVIEW_MILLIS, width, TimelineGeometry.SKED_MARGIN)!! + assertTrue(imminent < distant, "time must grow to the right") + } + + @Test + fun `the middle of the window is the middle of the strip`() { + assertEquals( + 200f, + TimelineGeometry.xFor(TimelineGeometry.PREVIEW_MILLIS / 2, width, TimelineGeometry.SKED_MARGIN)!!, + 0.01f, + ) + } + + /** Both edges are held off, or half a marker would hang outside the strip. */ + @Test + fun `a marker never reaches the edge`() { + assertEquals( + TimelineGeometry.SKED_MARGIN, + TimelineGeometry.xFor(0, width, TimelineGeometry.SKED_MARGIN)!!, + ) + assertEquals( + width - TimelineGeometry.SKED_MARGIN, + TimelineGeometry.xFor(TimelineGeometry.PREVIEW_MILLIS, width, TimelineGeometry.SKED_MARGIN)!!, + ) + } + + /** + * Candidates are held further from the edge than skeds. Their labels are wider, so + * the original picked two different margins — the difference is real and kept. + */ + @Test + fun `candidates keep further from the edge than skeds`() { + assertTrue(TimelineGeometry.CANDIDATE_MARGIN > TimelineGeometry.SKED_MARGIN) + assertEquals( + TimelineGeometry.CANDIDATE_MARGIN, + TimelineGeometry.xFor(0, width, TimelineGeometry.CANDIDATE_MARGIN)!!, + ) + } + + @Test + fun `an event outside the window is not placed at all`() { + assertNull(TimelineGeometry.xFor(-1, width, TimelineGeometry.SKED_MARGIN)) + assertNull( + TimelineGeometry.xFor(TimelineGeometry.PREVIEW_MILLIS + 1, width, TimelineGeometry.SKED_MARGIN), + ) + } + + /** + * A pane dragged narrower than two margins used to throw: coerceIn(30f, 10f) is an + * empty range, and Kotlin refuses it rather than picking a side. The operator runs a + * tiling compositor, so a strip narrower than 60 px is a Tuesday, not a corner case. + */ + @Test + fun `a strip narrower than its own margins still places a marker`() { + val x = TimelineGeometry.xFor( + timeUntilMs = 5 * 60 * 1000, + width = 40f, + margin = TimelineGeometry.CANDIDATE_MARGIN, + ) + assertEquals(20f, x!!, 0.01f, "a narrow strip should centre the marker") + } + + @Test + fun `a strip of no width at all does not throw`() { + val x = TimelineGeometry.xFor(0, width = 0f, margin = TimelineGeometry.SKED_MARGIN) + assertEquals(0f, x!!, 0.01f) + } + + @Test + fun `the window looks thirty minutes ahead`() { + assertEquals(30L * 60L * 1000L, TimelineGeometry.PREVIEW_MILLIS) + } + + // ---- the lanes --------------------------------------------------------- + + @Test + fun `the lanes stack downwards in even steps`() { + assertEquals(2f, TimelineGeometry.laneY(0)) + assertEquals(22f, TimelineGeometry.laneY(1)) + } + + /** + * The candidate lanes stay above the axis and the skeds below it. This is the one + * place where this port does not copy the original: there the lanes were laid out + * for a 40 px strip that the call site had already made 80 px tall, so the candidate + * labels, the sked diamonds and the sked labels all landed on the same pixels while + * the lower half stayed empty. + */ + @Test + fun `nothing is drawn across the axis or off the strip`() { + val laneBottom = TimelineGeometry.laneY(TimelineGeometry.LANE_COUNT - 1) + TimelineGeometry.LANE_HEIGHT + assertTrue( + laneBottom <= TimelineGeometry.AXIS_Y, + "candidate lanes reach the axis: $laneBottom vs ${TimelineGeometry.AXIS_Y}", + ) + assertTrue( + TimelineGeometry.SKED_Y > TimelineGeometry.AXIS_Y, + "skeds must sit below the axis", + ) + assertTrue( + TimelineGeometry.SKED_Y + TimelineGeometry.LANE_HEIGHT <= TimelineGeometry.HEIGHT, + "the sked lane runs off the bottom", + ) + } + + /** A third lane would land on the axis, so it shares the last one instead. */ + @Test + fun `a lane beyond the available ones folds onto the last`() { + assertEquals(TimelineGeometry.laneY(1), TimelineGeometry.laneY(2)) + assertEquals(TimelineGeometry.laneY(1), TimelineGeometry.laneY(7)) + assertEquals(TimelineGeometry.laneY(0), TimelineGeometry.laneY(-1)) + } + + // ---- the labels -------------------------------------------------------- + + @Test + fun `a label sits to the right of its marker`() { + assertEquals(54f, TimelineGeometry.labelStartX(markerX = 50f, labelWidth = 60f, stripWidth = width, gap = 4f)) + } + + /** Near the right edge it flips instead of running off — half an hour away there is always room. */ + @Test + fun `a label near the right edge flips to the left`() { + assertEquals( + 336f, + TimelineGeometry.labelStartX(markerX = 400f, labelWidth = 60f, stripWidth = width, gap = 4f), + ) + } + + @Test + fun `a label wider than the strip still starts on it`() { + assertEquals( + 0f, + TimelineGeometry.labelStartX(markerX = 10f, labelWidth = 900f, stripWidth = width, gap = 4f), + ) + } + + // ---- the antenna fading ----------------------------------------------- + + @Test + fun `a target dead ahead glows and grows`() { + val e = AntennaEmphasis.forAzimuth(currentAzimuth = 90.0, targetAzimuth = 90.0, beamWidthDeg = 50.0) + assertEquals(1f, e.iconAlpha) + assertTrue(e.glowing) + assertEquals(1.10f, e.scale) + } + + @Test + fun `the glow reaches exactly half a beam width`() { + assertTrue(AntennaEmphasis.forAzimuth(0.0, 25.0, 50.0).glowing) + assertFalse(AntennaEmphasis.forAzimuth(0.0, 25.1, 50.0).glowing) + } + + /** + * Between half a beam and a full beam the marker stays bright without the glow. The + * station is still workable; it is just not centred. + */ + @Test + fun `just off centre stays bright without the glow`() { + val e = AntennaEmphasis.forAzimuth(0.0, 40.0, 50.0) + assertEquals(1f, e.iconAlpha) + assertFalse(e.glowing) + assertEquals(1f, e.scale) + } + + @Test + fun `the full beam width is still bright`() { + assertEquals(1f, AntennaEmphasis.forAzimuth(0.0, 50.0, 50.0).iconAlpha) + } + + /** + * Beyond the beam the marker fades but does not vanish. An operator must be able to + * see a chance in a direction they are not pointing, or turning the rotator would + * never occur to them. + */ + @Test + fun `a target outside the beam fades to a ghost but stays visible`() { + val e = AntennaEmphasis.forAzimuth(0.0, 120.0, 50.0) + assertEquals(0.30f, e.iconAlpha) + assertFalse(e.glowing) + assertTrue(e.iconAlpha > 0f, "a ghost is still a marker") + } + + /** North is the case that breaks a naive subtraction: 350° and 10° are 20° apart. */ + @Test + fun `the beam reaches across north`() { + assertTrue(AntennaEmphasis.forAzimuth(350.0, 10.0, 50.0).glowing) + assertTrue(AntennaEmphasis.forAzimuth(10.0, 350.0, 50.0).glowing) + } + + @Test + fun `an unknown azimuth is left readable`() { + assertEquals(AntennaEmphasis.PLAIN, AntennaEmphasis.forAzimuth(0.0, -1.0, 50.0)) + assertEquals(AntennaEmphasis.PLAIN, AntennaEmphasis.forAzimuth(0.0, Double.NaN, 50.0)) + } + + // ---- the state -------------------------------------------------------- + + @Test + fun `the default beam width is the one the original assumed`() { + assertEquals(50.0, TimelineState().beamWidthDeg) + } + + @Test + fun `a nonsense beam width is refused rather than drawn`() { + val state = TimelineState() + state.setBeamWidth(0.0) + assertEquals(50.0, state.beamWidthDeg) + state.setBeamWidth(-30.0) + assertEquals(50.0, state.beamWidthDeg) + state.setBeamWidth(Double.NaN) + assertEquals(50.0, state.beamWidthDeg) + state.setBeamWidth(12.5) + assertEquals(12.5, state.beamWidthDeg) + } + + @Test + fun `the antenna direction decides the emphasis`() { + val state = TimelineState() + state.antennaAzimuth = 200.0 + assertTrue(state.emphasisFor(200.0).glowing) + assertEquals(0.30f, state.emphasisFor(20.0).iconAlpha) + } + + // ---- what a draw subscribes to ---------------------------------------- + + /** + * The strip is redrawn on the score pulse, on every rotator step and on every + * resize. Each of those has to reach the screen on its own, so reading any of it + * must register as a read. + */ + @Test + fun `drawing the timeline subscribes to what can change`() { + val state = TimelineState() + val read = mutableSetOf() + + Snapshot.observe(readObserver = { read += it.toString() }) { + state.skeds.size + state.candidates.size + state.antennaAzimuth + state.beamWidthDeg + } + + assertEquals(4, read.size, "a timeline value was read without subscribing: $read") + } + + @Test + fun `replacing the candidates replaces them rather than appending`() { + val state = TimelineState() + state.replaceCandidates(listOf(candidate("DL0ABC", lane = 0))) + state.replaceCandidates(listOf(candidate("DL0XYZ", lane = 0), candidate("DL0QRS", lane = 1))) + + assertEquals(listOf("DL0XYZ", "DL0QRS"), state.candidates.map { it.displayCallSign }) + } + + private fun candidate(call: String, lane: Int) = TimelineCandidate( + callSignRaw = call, + displayCallSign = call, + preferredChatCategory = null, + timeUntilMs = 60_000, + minuteBucket = 1, + laneIndex = lane, + targetAzimuth = 90.0, + score = 1.0, + opportunityPotentialPercent = 80, + tooltipText = null, + ) +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/TopPriorityCandidatesWindowTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/TopPriorityCandidatesWindowTest.kt new file mode 100644 index 00000000..9ff879a8 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/TopPriorityCandidatesWindowTest.kt @@ -0,0 +1,140 @@ +package kst4contest.view.compose + +import androidx.compose.ui.ImageComposeScene +import androidx.compose.ui.geometry.Offset +import androidx.compose.ui.input.pointer.PointerEventType +import androidx.compose.ui.unit.Density +import kst4contest.controller.ScoreService +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Test + +/** + * The window the "more" button opens. + * + * Its whole content is one line per candidate, so the line is the thing worth pinning: + * an operator reads the callsign and the score and nothing else, and the JavaFX version + * spelled it a particular way for two releases. + */ +class TopPriorityCandidatesWindowTest { + + /** + * The category is irrelevant to the label and is left null on purpose: a candidate + * that reached the list without one must still read as a line rather than as a + * crash. + */ + private fun candidate(call: String, score: Double) = + ScoreService.TopCandidate(call, call, null, score) + + private val twoCandidates = + listOf(candidate("PA6I", 968.0), candidate("DK7SE", 895.0)) + + /** Runs [block] against a rendered list of [twoCandidates] and reports what it picked. */ + private fun picking(block: (ImageComposeScene) -> Unit): String? { + var picked: String? = null + val scene = ImageComposeScene(width = 360, height = 500, density = Density(1f)) { + TopPriorityCandidatesWindow.CandidateListForTest(twoCandidates) { + picked = it.displayCallSign + } + } + try { + scene.render() + block(scene) + scene.render() + } finally { + scene.close() + } + return picked + } + + private fun ImageComposeScene.clickAt(y: Float, timeMillis: Long) { + val at = Offset(100f, y) + sendPointerEvent(PointerEventType.Press, at, timeMillis = timeMillis) + sendPointerEvent(PointerEventType.Release, at, timeMillis = timeMillis) + } + + @Test + fun `a candidate reads as its callsign and its score`() { + assertEquals("PA6I | score 968", candidateLabel(candidate("PA6I", 968.0))) + } + + /** The JavaFX cell used %.0f; 967.6 showed as 968, not as 967.6 or 967. */ + @Test + fun `the score is rounded to whole points`() { + assertEquals("DK7SE | score 968", candidateLabel(candidate("DK7SE", 967.6))) + assertEquals("DK7SE | score 895", candidateLabel(candidate("DK7SE", 895.4))) + } + + @Test + fun `a score of zero still reads as a score`() { + assertEquals("DL1ABC | score 0", candidateLabel(candidate("DL1ABC", 0.0))) + } + + /** + * Review Focus 3. Empty is the state the window opens in before the first score + * run, and a list that throws while measuring takes the window with it — which is + * the failure class the map's layout tests exist to catch. + */ + @Test + fun `the list renders with candidates and without`() { + listOf(emptyList(), twoCandidates).forEach { ranking -> + val scene = ImageComposeScene(width = 360, height = 500, density = Density(1f)) { + TopPriorityCandidatesWindow.CandidateListForTest(ranking) { } + } + try { + scene.render() + } finally { + scene.close() + } + } + } + + /** + * A double click picks the candidate under it, and picks the right one. + * + * Both clicks need an explicit `timeMillis`. `detectTapGestures` discards a second + * press that arrives less than `doubleTapMinTimeMillis` (40 ms) after the first + * release, and back-to-back `sendPointerEvent` calls default to the same timestamp + * — so a synthetic burst reads as one click, not two. The gap below is 50 ms. + * + * Note the asymmetry if you change these numbers: the 40 ms floor is measured + * against the timestamps supplied here, while the 300 ms ceiling is measured + * against the wall clock, so an implausible 2000 ms "gap" would also pass. 50 ms is + * used because it is what the assertion claims to be testing. + * + * The y of 32 is the second row, so this pins the per-row binding rather than only + * that something fired. + */ + @Test + fun `a double click picks the candidate it lands on`() { + assertEquals("PA6I", picking { scene -> + scene.clickAt(y = 10f, timeMillis = 1000L) + scene.clickAt(y = 10f, timeMillis = 1050L) + }) + + assertEquals("DK7SE", picking { scene -> + scene.clickAt(y = 32f, timeMillis = 1000L) + scene.clickAt(y = 32f, timeMillis = 1050L) + }) + } + + /** + * A single click must not pick a candidate. + * + * The window exists so the operator can read more than the first two candidates, + * which means clicking about in it has to be safe: picking closes the window. The + * JavaFX list required `getClickCount() >= 2` for exactly that reason. + * + * This is the half that protects the window's reason to exist, so it stays even + * though the positive case above now covers the binding. + */ + @Test + fun `a single click does not pick a candidate`() { + val picked = picking { scene -> + scene.clickAt(y = 10f, timeMillis = 1000L) + Thread.sleep(400) + } + + assertNull(picked) { "a single click picked $picked and would have closed the window" } + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/TopPriorityStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/TopPriorityStateTest.kt new file mode 100644 index 00000000..4debce3b --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/TopPriorityStateTest.kt @@ -0,0 +1,122 @@ +package kst4contest.view.compose + +import kst4contest.model.ChatMember +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertSame +import org.junit.jupiter.api.Assertions.assertTrue + +/** + * The two priority buttons beside the station list. + * + * They are a shortcut to the station the score says to work next, so what they name + * and what they do when pressed is the whole of their value. + * + * `refresh()` is what fills them, and the score service is what calls it + * (`Kst4ContestApplication` wires it to `topCandidates()` and calls it once at + * startup). Reading the ranking on demand instead would never reach the screen: the + * ranking is not Compose state, so a button derived from it could not ask for a + * redraw when the score changed. + */ +class TopPriorityStateTest { + + private fun member(call: String) = ChatMember().apply { callSign = call } + + @Test + fun `the buttons name the highest scoring stations and their score`() { + val pa6i = member("PA6I") + val dk7se = member("DK7SE") + val state = TopPriorityState( + topStations = { listOf(pa6i to 968.0, dk7se to 895.0) }, + onSelect = { }, + ) + + state.refresh() + + assertEquals(listOf("1 PA6I 968", "2 DK7SE 895"), state.entries.map { it.label }) + } + + @Test + fun `only the first two are offered`() { + val state = TopPriorityState( + topStations = { (1..5).map { member("DL${it}ABC") to it.toDouble() } }, + onSelect = { }, + ) + + state.refresh() + + assertEquals(2, state.entries.size, "the rest are behind the more button") + } + + @Test + fun `fewer than two stations gives fewer buttons`() { + val state = TopPriorityState(topStations = { listOf(member("DN9APW") to 10.0) }, onSelect = { }) + + state.refresh() + + assertEquals(1, state.entries.size) + } + + @Test + fun `with no stations there is nothing to press`() { + val state = TopPriorityState(topStations = { emptyList() }, onSelect = { }) + + state.refresh() + + assertTrue(state.entries.isEmpty()) + } + + @Test + fun `pressing one selects that station`() { + val pa6i = member("PA6I") + var selected: ChatMember? = null + val state = TopPriorityState(topStations = { listOf(pa6i to 968.0) }, onSelect = { selected = it }) + state.refresh() + + state.entries.first().select() + + assertSame(pa6i, selected) + } + + @Test + fun `a station without a callsign is skipped rather than shown blank`() { + val state = TopPriorityState( + topStations = { listOf(ChatMember() to 500.0, member("DN9APW") to 400.0) }, + onSelect = { }, + ) + + state.refresh() + + assertEquals(listOf("1 DN9APW 400"), state.entries.map { it.label }) + } + + /** + * Nothing is shown until the score service has spoken. + * + * Deliberate: the ranking lives outside Compose, so the buttons are pushed from the + * score service rather than pulled during composition. An earlier version derived + * them on read, which looked simpler and could never have updated the screen. + */ + @Test + fun `the buttons stay empty until the score service fills them`() { + val state = TopPriorityState(topStations = { listOf(member("PA6I") to 968.0) }, onSelect = { }) + + assertTrue(state.entries.isEmpty(), "nothing should appear before the first refresh") + + state.refresh() + + assertEquals(listOf("1 PA6I 968"), state.entries.map { it.label }) + } + + @Test + fun `a later refresh replaces what the buttons said`() { + var ranking = listOf(member("PA6I") to 968.0) + val state = TopPriorityState(topStations = { ranking }, onSelect = { }) + state.refresh() + + ranking = listOf(member("DK7SE") to 1200.0) + state.refresh() + + assertEquals(listOf("1 DK7SE 1200"), state.entries.map { it.label }) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/TypographyScalingTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/TypographyScalingTest.kt new file mode 100644 index 00000000..7ba8e231 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/TypographyScalingTest.kt @@ -0,0 +1,31 @@ +package kst4contest.view.compose + +import androidx.compose.material3.Typography +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals + +class TypographyScalingTest { + + @Test + fun `the base size replaces the body size and the rest keeps its ratio`() { + val original = Typography() + val originalBody = original.bodyMedium.fontSize.value + val originalTitle = original.titleMedium.fontSize.value + + val scaled = original.scaledTo(originalBody * 2f) + + assertEquals(originalBody * 2f, scaled.bodyMedium.fontSize.value, 0.01f) + assertEquals(originalTitle * 2f, scaled.titleMedium.fontSize.value, 0.01f, + "every style scales by the same factor, so the design keeps its proportions") + } + + @Test + fun `a base size of zero or less is ignored`() { + val original = Typography() + + assertEquals(original.bodyMedium.fontSize.value, + original.scaledTo(0f).bodyMedium.fontSize.value, 0.01f) + assertEquals(original.bodyMedium.fontSize.value, + original.scaledTo(-5f).bodyMedium.fontSize.value, 0.01f) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/UpdateWindowStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/UpdateWindowStateTest.kt new file mode 100644 index 00000000..3d2d57d8 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/UpdateWindowStateTest.kt @@ -0,0 +1,123 @@ +package kst4contest.view.compose + +import kst4contest.model.UpdateInformation +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue + +/** + * When the update window opens, and what it says. + * + * The decision matters in both directions: a window that opens without an update is a + * daily annoyance, and one that stays shut when an update exists defeats the whole + * mechanism. + */ +class UpdateWindowStateTest { + + private fun semantic(version: String) = UpdateInformation().apply { + latestSemanticVersionOnServer = version + } + + private fun numeric(number: Double) = UpdateInformation().apply { + latestVersionNumberOnServer = number + } + + private fun state(information: UpdateInformation?) = + UpdateWindowState(information, currentVersion = "1.50.0", currentVersionNumber = 1.50) + + @Test + fun `a newer semantic version on the server is an update`() { + assertTrue(state(semantic("1.51.0")).updateAvailable) + assertTrue(state(semantic("2.0.0")).updateAvailable) + } + + @Test + fun `the same or an older semantic version is not`() { + assertFalse(state(semantic("1.50.0")).updateAvailable, + "the running version is not an update to itself") + assertFalse(state(semantic("1.49.9")).updateAvailable, + "a server rolled back must not push the operator downwards") + } + + @Test + fun `without a semantic version the numeric comparison decides`() { + val older = numeric(1.49) + val newer = numeric(1.51) + + assertFalse(older.hasSemanticVersion(), "this is the path the test is about") + assertFalse(state(older).updateAvailable) + assertTrue(state(newer).updateAvailable) + } + + @Test + fun `absent update information is not an update`() { + // The check runs at startup. A download that failed must not keep the + // application from coming up, and must not claim an update either. + assertFalse(state(null).updateAvailable) + } + + @Test + fun `the version lines carry the product name, not the directory name`() { + val state = state(semantic("1.51.0")) + + assertEquals("KST4Contest 1.50.0", state.installedVersion) + assertEquals("KST4Contest 1.51.0", state.latestVersion) + } + + @Test + fun `a change log row becomes a heading with its lines`() { + val information = semantic("1.51.0").apply { + changeLog = arrayListOf( + arrayOf("1.51.0", "Compose settings window", "Tabs sized to their titles"), + arrayOf("1.50.0", "Gradle build"), + ) + } + + val sections = state(information).changeLog + + assertEquals(2, sections.size) + assertEquals("1.51.0", sections[0].title) + assertEquals( + listOf("Compose settings window", "Tabs sized to their titles"), + sections[0].entries, + ) + assertEquals(listOf("Gradle build"), sections[1].entries) + } + + @Test + fun `a heading without lines is kept`() { + val information = semantic("1.51.0").apply { + changeLog = arrayListOf(arrayOf("1.51.0")) + } + + val sections = state(information).changeLog + + assertEquals(1, sections.size, + "a version that brought no listed change is still worth showing as released") + assertTrue(sections[0].entries.isEmpty()) + } + + @Test + fun `known bugs read the same way as the change log`() { + val information = semantic("1.51.0").apply { + bugList = arrayListOf(arrayOf("Profile switch", "The confirmation opens behind")) + } + + val sections = state(information).knownBugs + + assertEquals("Profile switch", sections[0].title) + assertEquals(listOf("The confirmation opens behind"), sections[0].entries) + } + + @Test + fun `an empty update information yields empty text rather than null`() { + val state = state(UpdateInformation()) + + assertEquals("", state.majorChanges) + assertEquals("", state.adminMessage) + assertEquals("", state.releasePageUrl) + assertTrue(state.changeLog.isEmpty()) + assertTrue(state.knownBugs.isEmpty()) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/WindowShortcutsTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/WindowShortcutsTest.kt new file mode 100644 index 00000000..c62488cd --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/WindowShortcutsTest.kt @@ -0,0 +1,45 @@ +package kst4contest.view.compose + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Test + +/** + * Enter, Escape and Ctrl+1…Ctrl+0 belong to the whole window, not to the message field. + * + * JavaFX hung all three on the SCENE (7455-7474), and the tables even re-fired the send + * button from their own key filter. An operator who has just clicked a station, a message row + * or a button must still be able to press Enter and have the message go — and Ctrl+1…Ctrl+0 + * is how snippets are used at all, since the operator's hands are on the keyboard. + */ +class WindowShortcutsTest { + + @Test + fun `control and the digit keys map to the ten snippet slots`() { + assertEquals(0, WindowShortcuts.snippetIndexFor("1")) + assertEquals(1, WindowShortcuts.snippetIndexFor("2")) + assertEquals(8, WindowShortcuts.snippetIndexFor("9")) + } + + /** Ctrl+0 is the tenth, not the first — the row of digits reads 1…9 then 0. */ + @Test + fun `control zero is the tenth slot`() { + assertEquals(9, WindowShortcuts.snippetIndexFor("0")) + } + + @Test + fun `any other key is not a snippet shortcut`() { + assertNull(WindowShortcuts.snippetIndexFor("a")) + assertNull(WindowShortcuts.snippetIndexFor("")) + assertNull(WindowShortcuts.snippetIndexFor("12")) + } + + /** All ten slots are reachable and none is reachable twice. */ + @Test + fun `the ten digits cover the ten slots exactly once`() { + val indices = listOf("1", "2", "3", "4", "5", "6", "7", "8", "9", "0") + .mapNotNull { WindowShortcuts.snippetIndexFor(it) } + + assertEquals((0..9).toList(), indices) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/map/ComposeStationMapDrawingTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/ComposeStationMapDrawingTest.kt new file mode 100644 index 00000000..6f5932b4 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/ComposeStationMapDrawingTest.kt @@ -0,0 +1,278 @@ +package kst4contest.view.compose.map + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.ui.ImageComposeScene +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Density +import kst4contest.view.map.MapCallsignRawSnapshot +import kst4contest.view.map.TileFetcher +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import java.awt.image.BufferedImage +import java.io.ByteArrayInputStream +import java.io.IOException +import java.nio.file.Files +import javax.imageio.ImageIO +import kotlin.math.abs + +/** + * What the map actually puts on the canvas. + * + * Asserted on the rendered image, because that is the only place the answers live: the + * drawing code takes a viewport and paints, and no amount of reading it proves a dot + * came out 12 px wide. These are the acceptance criteria of the projection rewrite and + * of the grid planner, in the form the operator experiences them. + * + * Tiles never arrive here. The fetcher is asked asynchronously and the test renders one + * frame, so what is measured is the map's own drawing over its own background — which is + * also the case an operator meets without a network. + */ +class ComposeStationMapDrawingTest { + + private val canvasWidth = 900 + private val canvasHeight = 600 + + /** The default station-dot border, `#4da6ff` in the Leaflet stylesheet. */ + private val dotBorder = 0x4DA6FF + + /** The home marker and the antenna beam, `#ff4d4d`. */ + private val homeColour = 0xFF4D4D + + /** The Maidenhead label colour, `#63067a`. */ + private val gridLabel = 0x63067A + + private val darkMapBackground = 0x23282D + + /* + * An empty cache and a source that always fails, so that "tiles never arrive" holds by + * construction. The default fetcher read the user's disk cache and the real tile + * server, and on CI a tile now and then made it in before the frame was rendered. + */ + private val offlineTileFetcher = TileFetcher( + Files.createTempDirectory("kst4contest-tile-cache-test"), + { throw IOException("no tile source in this test") }, + ) + + private fun station(call: String, locator: String, lat: Double, lon: Double) = + MapCallsignRawSnapshot( + call, call, locator, lat, lon, "", emptyMap(), + false, false, false, false, 0.0, 0.0, 0, 0L, + ) + + private fun render( + zoom: Float, + markers: List = listOf(station("DN9APW", "JO50JP", 51.0, 10.0)), + ownLocator6: String = "", + ): BufferedImage { + val scene = ImageComposeScene(canvasWidth, canvasHeight, Density(1f)) { + ComposeStationMap( + markers = markers, + tileFetcher = offlineTileFetcher, + mapState = MapState(zoom = zoom, centerLon = 10.0, centerLat = 51.0), + groupingEnabled = false, + selectedMarkerCallsign = null, + ownLocator6 = ownLocator6, + antennaAzimuthDeg = 90.0, + antennaBeamWidthDeg = 0.0, + maxQrbKm = 0.0, + onMarkerClicked = null, + darkMode = true, + modifier = Modifier.fillMaxSize(), + ) + } + try { + return ImageIO.read(ByteArrayInputStream(scene.render().encodeToData()!!.bytes)) + } finally { + scene.close() + } + } + + private fun countColour(image: BufferedImage, rgb: Int): Int { + var count = 0 + for (x in 0 until image.width) { + for (y in 0 until image.height) { + if ((image.getRGB(x, y) and 0xFFFFFF) == rgb) count++ + } + } + return count + } + + /** The widest horizontal run of a colour, which for a ring is its outer diameter. */ + private fun widestRun(image: BufferedImage, rgb: Int): Int { + var widest = 0 + for (y in 0 until image.height) { + var first = -1 + var last = -1 + for (x in 0 until image.width) { + if ((image.getRGB(x, y) and 0xFFFFFF) == rgb) { + if (first < 0) first = x + last = x + } + } + if (first >= 0) widest = maxOf(widest, last - first + 1) + } + return widest + } + + /** The mean position of a colour, or null when it is absent. */ + private fun centroidOf(image: BufferedImage, rgb: Int): Pair? { + var sumX = 0L + var sumY = 0L + var count = 0 + for (x in 0 until image.width) { + for (y in 0 until image.height) { + if ((image.getRGB(x, y) and 0xFFFFFF) == rgb) { + sumX += x + sumY += y + count++ + } + } + } + return if (count == 0) null else Pair(sumX.toDouble() / count, sumY.toDouble() / count) + } + + /** + * The invariant the projection rewrite exists to make obvious: a size written in the + * drawing code is the size that reaches the canvas. The previous version reached the + * same geometry by dividing each size by the zoom fraction inside a scaled canvas, + * which held only as long as every single site remembered to divide. + */ + @Test + fun `a station dot is the same size at every zoom`() { + val widths = listOf(6.0f, 6.3f, 6.5f, 6.9f, 11.5f, 16.25f).map { widestRun(render(it), dotBorder) } + + assertTrue(widths.all { it > 0 }) { "no station dot was drawn at all: $widths" } + assertEquals(1, widths.distinct().size, "the dot changed size across zooms: $widths") + } + + /** + * Home, the beam and the path line have to sit in the same coordinate system as the + * stations. + * + * In the previous version they did not: `scale(scaleFactor)` closed before the beam + * block, which then used the unscaled formula while the markers above it had been + * drawn scaled. At an integer zoom the factor is 1 and the two agreed; at any zoom + * with a fraction the beam started somewhere other than home. + */ + @Test + fun `home sits exactly on a station at the same position, at every zoom`() { + /* Off the centre of the view on purpose: at the centre a scaling error is zero. */ + val home = kst4contest.locatorUtils.Location("JO50JP") + val homeLat = home.latitude.toDegrees() + val homeLon = home.longitude.toDegrees() + val stationOnTopOfHome = listOf(station("DL0HOME", "JO50JP", homeLat, homeLon)) + + for (zoom in listOf(6f, 6.5f, 7.25f, 8.25f)) { + /* + * Two renders of the same place rather than one: the station dot is drawn + * over the beam layer and would simply hide the home dot. + */ + val withStationOnly = render(zoom, markers = stationOnTopOfHome, ownLocator6 = "") + val withHomeOnly = render(zoom, markers = emptyList(), ownLocator6 = "JO50JP") + + val homeCentre = centroidOf(withHomeOnly, homeColour) + val stationCentre = centroidOf(withStationOnly, dotBorder) + + assertTrue(homeCentre != null && stationCentre != null) { + "at zoom $zoom: home=$homeCentre station=$stationCentre" + } + assertTrue( + abs(homeCentre!!.first - stationCentre!!.first) <= 1.0 && + abs(homeCentre.second - stationCentre.second) <= 1.0 + ) { + "at zoom $zoom home sits at $homeCentre but the station at the same place is at $stationCentre" + } + } + } + + @Test + fun `an unreachable tile source leaves the map in its own colour, not the system grey`() { + val image = render(6f, markers = emptyList()) + + assertTrue(countColour(image, darkMapBackground) > image.width * image.height / 2) { + "the map background should cover the canvas while no tiles have arrived" + } + } + + /** `#63067a`, centred in the cell — not white, not in the corner. */ + @Test + fun `grid labels are drawn in the colour the Leaflet map used`() { + assertTrue(countColour(render(6f), gridLabel) > 0) { "no grid label was drawn" } + } + + /** + * At six-digit precision the grid has far more cells than it has room for labels. + * The planner answers that with a stride; without it every cell got one and the map + * disappeared under text, which is what the 30 September screenshot shows. + */ + @Test + fun `grid labels stay sparse where the cells are small`() { + val image = render(12f) + val labelPixels = countColour(image, gridLabel) + val canvasPixels = image.width * image.height + + assertTrue(labelPixels < canvasPixels / 20) { + "grid labels cover $labelPixels of $canvasPixels pixels, which is a carpet rather than a grid" + } + } + + /** Four-digit squares at zoom 6, two-digit fields at zoom 4. */ + @Test + fun `the grid gets finer as the map zooms in`() { + val atFour = countColour(render(4f), gridLabel) + val atSix = countColour(render(6f), gridLabel) + + assertTrue(atFour > 0 && atSix > 0) { "labels missing: zoom 4 -> $atFour, zoom 6 -> $atSix" } + assertTrue(atSix > atFour) { + "a four-digit grid should show more labels than a two-digit one: $atSix vs $atFour" + } + } + + /** + * Every grid line has to be drawn once. + * + * One stroked rectangle per cell paints each interior line twice — once by the cell + * on either side — so at the specified 0.48 a shared edge reaches about 0.73 while + * the outermost line stays at 0.48. The result is a grid of visibly uneven weight, + * which is the kind of thing that makes the map not look like the original. Leaflet + * drew each line once. + * + * Asserted as "no pixel carries more line colour than one full pass can put there". + * Antialiasing of a 1.4 px line at a fractional position legitimately produces many + * shades BELOW that value; none can legitimately exceed it. + */ + @Test + fun `no grid line is painted over itself`() { + /* #e1e7ec at 0.48 over #23282d — one pass, fully covering a pixel. */ + val singlePassRed = (0.48 * 0xE1 + 0.52 * 0x23).toInt() + + val image = render(6f, markers = emptyList()) + + /* + * Only rows that cross vertical lines. A row lying on a horizontal grid line is + * bright across its whole width, and where the two cross they legitimately + * overlap — Leaflet's polylines crossed too. + */ + var brightest = 0 + for (y in 0 until image.height) { + var lit = 0 + var rowBrightest = 0 + for (x in 0 until image.width) { + val pixel = image.getRGB(x, y) and 0xFFFFFF + if (pixel == darkMapBackground) continue + lit++ + val red = (pixel shr 16) and 0xFF + if (red > rowBrightest) rowBrightest = red + } + val crossesAHorizontalLine = lit > image.width / 10 + if (!crossesAHorizontalLine && rowBrightest > brightest) brightest = rowBrightest + } + + assertTrue(brightest > 0) { "no grid line was drawn at all" } + assertTrue(brightest <= singlePassRed + 2) { + "a grid pixel reached $brightest where one pass tops out at $singlePassRed — " + + "the line was painted more than once" + } + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/map/ComposeStationMapLayoutTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/ComposeStationMapLayoutTest.kt new file mode 100644 index 00000000..e4adeaa0 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/ComposeStationMapLayoutTest.kt @@ -0,0 +1,80 @@ +package kst4contest.view.compose.map + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.ui.ImageComposeScene +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Density +import kst4contest.view.map.MapCallsignRawSnapshot +import kst4contest.view.map.TileFetcher +import org.junit.jupiter.api.Test + +/** + * The map canvas has to survive every zoom and every canvas size. + * + * Markers carry labels, and a label is measured against the canvas it is drawn on. A + * label whose anchor has drifted outside the canvas makes Compose build text + * constraints from a negative remaining width, which is not a Constraints value that + * exists. Fractional zoom levels are included deliberately: the canvas scales its whole + * drawing by the fraction, so sizes that are fine at zoom 6 are not at zoom 6.5. + */ +class ComposeStationMapLayoutTest { + + private fun station(call: String, lat: Double, lon: Double, selected: Boolean = false) = + MapCallsignRawSnapshot( + call, call, "JO50JP", lat, lon, "144, 432", emptyMap(), + true, false, false, selected, 100.0, 90.0, 0, 0L, + ) + + private val stations = listOf( + station("DN9APW", 50.5, 10.5), + station("DL3JIN", 50.9, 11.9), + station("F5JMI", 44.0, 5.0, selected = true), + station("SM7KOJ", 60.0, 15.0), + ) + + private fun renderAt(widthPx: Int, heightPx: Int, zoom: Float) { + val scene = ImageComposeScene( + width = widthPx, + height = heightPx, + density = Density(1f), + ) { + ComposeStationMap( + markers = stations, + tileFetcher = TileFetcher(), + mapState = MapState(zoom = zoom, centerLon = 10.0, centerLat = 51.0), + groupingEnabled = true, + selectedMarkerCallsign = "F5JMI", + ownLocator6 = "JO50JP", + antennaAzimuthDeg = 229.0, + antennaBeamWidthDeg = 60.0, + maxQrbKm = 800.0, + onMarkerClicked = null, + darkMode = true, + modifier = Modifier.fillMaxSize(), + ) + } + try { + scene.render() + } finally { + scene.close() + } + } + + @Test + fun `renders at a normal window size and integer zoom`() = renderAt(900, 600, 6f) + + @Test + fun `renders at a fractional zoom`() = renderAt(900, 600, 6.5f) + + @Test + fun `renders when the canvas is narrow`() = renderAt(40, 600, 6.5f) + + @Test + fun `renders when the canvas is short`() = renderAt(900, 30, 6.5f) + + @Test + fun `renders at the highest zoom`() = renderAt(900, 600, 17.5f) + + @Test + fun `renders at one pixel`() = renderAt(1, 1, 6.5f) +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/map/PathAnalysisDetailsLayoutTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/PathAnalysisDetailsLayoutTest.kt new file mode 100644 index 00000000..77e8b77e --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/PathAnalysisDetailsLayoutTest.kt @@ -0,0 +1,65 @@ +package kst4contest.view.compose.map + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.ui.ImageComposeScene +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Density +import kst4contest.view.map.PathAnalysisResult +import org.junit.jupiter.api.Test + +/** + * The analysis column has to survive being narrow. + * + * The station map splitter can be dragged until this column is a sliver, and the + * window may be resized below any width the layout assumed. Both happened, and both + * ended in an IllegalArgumentException out of Constraints rather than a squeezed + * column — the window then put up an error dialog over the map. + * + * Rendering is the assertion: ImageComposeScene measures, lays out and draws, which is + * exactly where invalid constraints are built. It ships with compose.desktop.currentOs, + * so this needs no test dependency the project does not already have. + */ +class PathAnalysisDetailsLayoutTest { + + /** Narrower than the 130 dp the assessment label used to reserve for itself. */ + private val narrowWidthPx = 120 + + private fun renderAt(widthPx: Int, result: PathAnalysisResult?) { + val scene = ImageComposeScene( + width = widthPx, + height = 600, + density = Density(1f), + ) { + PathAnalysisDetails( + result = result, + darkMode = true, + modifier = Modifier.fillMaxWidth(), + ) + } + try { + scene.render() + } finally { + scene.close() + } + } + + @Test + fun `renders when the column is narrower than the assessment label`() { + renderAt(narrowWidthPx, PathAnalysisResult.loading("JO50JP", "JN24JB", "F5JMI")) + } + + @Test + fun `renders at a width no operator could drag it below`() { + renderAt(1, PathAnalysisResult.loading("JO50JP", "JN24JB", "F5JMI")) + } + + @Test + fun `renders without a result`() { + renderAt(narrowWidthPx, null) + } + + @Test + fun `renders at a comfortable width`() { + renderAt(350, PathAnalysisResult.loading("JO50JP", "JN24JB", "F5JMI")) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/map/PathAnalysisDetailsWidthTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/PathAnalysisDetailsWidthTest.kt new file mode 100644 index 00000000..3de304f9 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/PathAnalysisDetailsWidthTest.kt @@ -0,0 +1,83 @@ +package kst4contest.view.compose.map + +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.ui.ImageComposeScene +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Density +import kst4contest.view.map.PathAnalysisResult +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import java.awt.image.BufferedImage +import java.io.ByteArrayInputStream +import javax.imageio.ImageIO + +/** + * The value column keeps its share of a narrow analysis pane. + * + * Every row of this column pairs a label with a value, and the value is what an + * operator reads: a locator, a distance, a propagation assessment. The JavaFX original + * used a GridPane whose value column took the remaining width. The Compose port gave + * the assessment label a fixed 130 dp instead, so once the splitter narrowed the pane + * the label kept its 130 dp and the assessment was squeezed — visible as clipped text + * in the 30 September screenshot. + * + * Measured on the rendered image rather than through a callback, so the production + * composable carries nothing that exists only for this test. The assessment box is the + * one opaque coloured band in the column, which makes its left edge findable. + */ +class PathAnalysisDetailsWidthTest { + + /** The severity-0 assessment background in dark mode, as PathAnalysisDetails paints it. */ + private val assessmentBackground = 0x33383E + + private fun render(paneWidthPx: Int, heightPx: Int = 600): BufferedImage { + val scene = ImageComposeScene(width = paneWidthPx, height = heightPx, density = Density(1f)) { + PathAnalysisDetails( + result = PathAnalysisResult.loading("JO50JP", "JN24JB", "F5JMI"), + darkMode = true, + modifier = Modifier.fillMaxWidth(), + ) + } + try { + val png = scene.render().encodeToData()!!.bytes + return ImageIO.read(ByteArrayInputStream(png)) + } finally { + scene.close() + } + } + + /** The smallest x at which the assessment background appears, or -1 when it does not. */ + private fun assessmentLeftEdge(image: BufferedImage): Int { + for (x in 0 until image.width) { + for (y in 0 until image.height) { + if ((image.getRGB(x, y) and 0xFFFFFF) == assessmentBackground) return x + } + } + return -1 + } + + @Test + fun `the assessment value starts where every other value starts`() { + val paneWidth = 200 + val leftEdge = assessmentLeftEdge(render(paneWidth)) + + assertTrue(leftEdge >= 0) { "the assessment box was not drawn at all" } + assertTrue( + leftEdge <= paneWidth * 0.45, + { + "the assessment value starts at x=$leftEdge of $paneWidth px; " + + "DetailRow starts its values at about 38%, so this column is out of line" + }, + ) + } + + /** + * The real column scrolls, so height is not what limits it. At 60 px every value + * above wraps into a stack of lines and pushes this row far down; the height here + * is generous for that reason, not because the pane is ever this tall. + */ + @Test + fun `the assessment box is still drawn in a sliver of a pane`() { + assertTrue(assessmentLeftEdge(render(60, heightPx = 3000)) >= 0) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/map/PathProfileChartLayoutTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/PathProfileChartLayoutTest.kt new file mode 100644 index 00000000..3884b9b6 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/PathProfileChartLayoutTest.kt @@ -0,0 +1,46 @@ +package kst4contest.view.compose.map + +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.ui.ImageComposeScene +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Density +import org.junit.jupiter.api.Test + +/** + * The terrain profile chart has to survive being small. + * + * It is the only part of the map window that draws text onto a canvas whose size it + * does not control: the splitter above it and the window around it both shrink it. A + * canvas narrower than the chart's own margins puts the axis labels outside the canvas, + * and Compose builds the text measurement constraints from the distance between the + * label and the canvas edge — a distance that is negative once the label is outside. + */ +class PathProfileChartLayoutTest { + + private fun renderAt(widthPx: Int, heightPx: Int) { + val scene = ImageComposeScene( + width = widthPx, + height = heightPx, + density = Density(1f), + ) { + PathProfileChart(modifier = Modifier.fillMaxSize(), darkMode = true) + } + try { + scene.render() + } finally { + scene.close() + } + } + + @Test + fun `renders at the height the window gives it`() = renderAt(800, 210) + + @Test + fun `renders when narrower than its own left margin`() = renderAt(40, 210) + + @Test + fun `renders when shorter than its own header`() = renderAt(800, 20) + + @Test + fun `renders at one pixel`() = renderAt(1, 1) +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/map/StationMapBodyLayoutTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/StationMapBodyLayoutTest.kt new file mode 100644 index 00000000..3e44f7fd --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/StationMapBodyLayoutTest.kt @@ -0,0 +1,119 @@ +package kst4contest.view.compose.map + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.fillMaxHeight +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.runtime.Composable +import androidx.compose.ui.ImageComposeScene +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Density +import androidx.compose.ui.unit.dp +import kst4contest.view.compose.SplitterOrientation +import kst4contest.view.compose.SplitterPane +import kst4contest.view.compose.SplitterState +import kst4contest.view.map.MapCallsignRawSnapshot +import kst4contest.view.map.PathAnalysisResult +import kst4contest.view.map.TileFetcher +import org.junit.jupiter.api.Test + +/** + * The map window's body, assembled the way the window assembles it. + * + * Each part of this body renders on its own at one pixel. The window still put up a + * Constraints error dialog, and the answer was a barrier that leaves the window blank + * below 500x400 dp — so the combination is what was never checked. The splitter hands + * its panes a width it computed, the left pane stacks a weighted canvas above a fixed + * 210 dp chart, and the right pane scrolls. That arrangement is this test. + */ +class StationMapBodyLayoutTest { + + private val stations = listOf( + MapCallsignRawSnapshot( + "DN9APW", "DN9APW", "JO50JP", 50.5, 10.5, "144, 432", emptyMap(), + true, false, false, false, 100.0, 90.0, 0, 0L, + ), + ) + + @Composable + private fun Body(pathAnalysisVisible: Boolean) { + val splitter = SplitterState(paneCount = 2, stored = doubleArrayOf(0.65), save = { }) + + val leftPane: @Composable () -> Unit = { + Column(Modifier.fillMaxHeight()) { + ComposeStationMap( + markers = stations, + tileFetcher = TileFetcher(), + mapState = MapState(zoom = 6.5f, centerLon = 10.0, centerLat = 51.0), + groupingEnabled = true, + selectedMarkerCallsign = null, + ownLocator6 = "JO50JP", + antennaAzimuthDeg = 229.0, + antennaBeamWidthDeg = 60.0, + maxQrbKm = 800.0, + onMarkerClicked = null, + darkMode = true, + modifier = Modifier.weight(1f).fillMaxWidth(), + ) + if (pathAnalysisVisible) { + PathProfileChart( + modifier = Modifier.fillMaxWidth().height(210.dp), + darkMode = true, + ) + } + } + } + + val rightPane: @Composable () -> Unit = { + PathAnalysisDetails( + result = PathAnalysisResult.loading("JO50JP", "JN24JB", "F5JMI"), + darkMode = true, + modifier = Modifier.fillMaxHeight().verticalScroll(rememberScrollState()), + ) + } + + if (pathAnalysisVisible) { + SplitterPane( + state = splitter, + orientation = SplitterOrientation.HORIZONTAL, + panes = listOf(leftPane, rightPane), + modifier = Modifier.fillMaxSize(), + ) + } else { + leftPane() + } + } + + private fun renderAt(widthPx: Int, heightPx: Int, pathAnalysisVisible: Boolean = true) { + val scene = ImageComposeScene(width = widthPx, height = heightPx, density = Density(1f)) { + Body(pathAnalysisVisible) + } + try { + scene.render() + } finally { + scene.close() + } + } + + @Test + fun `renders at the window's minimum size`() = renderAt(900, 600) + + /** Below the barrier that commit e7c8a9b9 installed. */ + @Test + fun `renders below the barrier that hid the defect`() = renderAt(499, 399) + + @Test + fun `renders when shorter than the chart it stacks`() = renderAt(900, 150) + + @Test + fun `renders when the detail pane is a sliver`() = renderAt(120, 400) + + @Test + fun `renders without the path analysis`() = renderAt(300, 200, pathAnalysisVisible = false) + + @Test + fun `renders at one pixel`() = renderAt(1, 1) +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/map/TileBitmapCacheTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/TileBitmapCacheTest.kt new file mode 100644 index 00000000..eabe0e64 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/TileBitmapCacheTest.kt @@ -0,0 +1,82 @@ +package kst4contest.view.compose.map + +import androidx.compose.ui.graphics.ImageBitmap +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Test + +/** + * The decoded tiles the map draws from. + * + * A decoded 256x256 tile is about 262 KB, against roughly 20 KB for the PNG it came + * from. The encoded cache below this one is capped at 2048 entries; this one was not + * capped at all, so an evening of panning at zoom 12 to 15 retained hundreds of + * megabytes of bitmaps that will never be looked at again. + */ +class TileBitmapCacheTest { + + private fun bitmap() = ImageBitmap(1, 1) + + @Test + fun `a tile that was put in comes back out`() { + val cache = TileBitmapCache(maxEntries = 4) + val tile = bitmap() + + cache.put("6/1/1", tile) + + assertEquals(tile, cache["6/1/1"]) + } + + @Test + fun `an unknown tile is absent rather than an error`() { + assertNull(TileBitmapCache(maxEntries = 4)["6/1/1"]) + } + + @Test + fun `the cache does not grow past its bound`() { + val cache = TileBitmapCache(maxEntries = 3) + + repeat(10) { cache.put("6/$it/0", bitmap()) } + + assertEquals(3, cache.size) + } + + /** The one dropped is the one that has gone longest without being drawn. */ + @Test + fun `the least recently drawn tile is the one dropped`() { + val cache = TileBitmapCache(maxEntries = 3) + cache.put("a", bitmap()) + cache.put("b", bitmap()) + cache.put("c", bitmap()) + + /* Drawing "a" again makes "b" the oldest. */ + cache["a"] + cache.put("d", bitmap()) + + assertNotNull(cache["a"]) + assertNull(cache["b"]) + assertNotNull(cache["c"]) + assertNotNull(cache["d"]) + } + + @Test + fun `a tile that turned out to be unusable can be removed`() { + val cache = TileBitmapCache(maxEntries = 3) + cache.put("6/1/1", bitmap()) + + cache.remove("6/1/1") + + assertNull(cache["6/1/1"]) + assertEquals(0, cache.size) + } + + @Test + fun `a bound of zero keeps nothing rather than everything`() { + val cache = TileBitmapCache(maxEntries = 0) + + cache.put("6/1/1", bitmap()) + + assertEquals(0, cache.size) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/map/TileKeyTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/TileKeyTest.kt new file mode 100644 index 00000000..db881d4a --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/map/TileKeyTest.kt @@ -0,0 +1,64 @@ +package kst4contest.view.compose.map + +import kst4contest.view.map.MapViewport +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * Which tiles a view needs. + * + * The world wraps east to west; the tile index does not. A view straddling the + * antimeridian asks for indices outside the valid range, and asking the tile service + * for one of those is a 404 — a hole in the map rather than a wrapped tile. + */ +class TileKeyTest { + + @Test + fun `a tile index past the eastern edge comes back round to the west`() { + assertEquals(0, wrapTileX(64, 63)) + assertEquals(1, wrapTileX(65, 63)) + assertEquals(63, wrapTileX(-1, 63)) + assertEquals(62, wrapTileX(-2, 63)) + assertEquals(0, wrapTileX(-64, 63)) + } + + @Test + fun `a tile index inside the range is left alone`() { + assertEquals(0, wrapTileX(0, 63)) + assertEquals(33, wrapTileX(33, 63)) + assertEquals(63, wrapTileX(63, 63)) + } + + @Test + fun `every tile a view asks for exists at that zoom`() { + for (zoom in 3..10) { + val lastIndex = (1 shl zoom) - 1 + /* Hard against the antimeridian, where the wrap actually happens. */ + val viewport = MapViewport(179.5, 0.0, zoom.toDouble(), 1200.0, 800.0) + + val keys = visibleTileKeys(viewport) + + assertTrue(keys.isNotEmpty()) { "no tiles requested at zoom $zoom" } + assertTrue(keys.all { it.x in 0..lastIndex && it.y in 0..lastIndex }) { + "zoom $zoom asked for " + keys.filter { it.x !in 0..lastIndex || it.y !in 0..lastIndex } + } + assertTrue(keys.all { it.zoom == zoom }) + } + } + + @Test + fun `a view beyond the poles asks for no tiles above or below the world`() { + val viewport = MapViewport(10.0, 84.0, 3.0, 1200.0, 800.0) + + val keys = visibleTileKeys(viewport) + val lastIndex = (1 shl 3) - 1 + + assertTrue(keys.all { it.y in 0..lastIndex }) { "asked for a row that does not exist: $keys" } + } + + @Test + fun `the cache key is the path the tile service uses`() { + assertEquals("6/33/21", TileKey(6, 33, 21).cacheKey) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/AirscoutTabStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/AirscoutTabStateTest.kt new file mode 100644 index 00000000..5a9c8e5e --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/AirscoutTabStateTest.kt @@ -0,0 +1,132 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatPreferences +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue + +class AirscoutTabStateTest { + + private class Session { + val prefs = ChatPreferences() + val state by lazy { AirscoutTabState(prefs) } + } + + @Test + fun `reading comes straight from the preferences`() { + val s = Session() + s.prefs.setAirScout_asUDPListenerEnabled(true) + s.prefs.setAirScout_asServerNameString("AS") + s.prefs.setAirScout_asClientNameString("KST") + s.prefs.setAirScout_asCommunicationPort(9872) + s.prefs.setAirScout_autoBandSelectionEnabled(true) + s.prefs.setAirScout_asBandString("1440000") + + assertTrue(s.state.airScout_asUDPListenerEnabled) + assertEquals("AS", s.state.airScout_asServerNameString) + assertEquals("KST", s.state.airScout_asClientNameString) + assertEquals(9872, s.state.airScout_asCommunicationPort) + assertTrue(s.state.airScout_autoBandSelectionEnabled) + assertEquals("1440000", s.state.airScout_asBandString) + } + + @Test + fun `writing reaches the preferences at once, without a confirmation step`() { + val s = Session() + + s.state.airScout_asUDPListenerEnabled = true + s.state.airScout_asServerNameString = "AS2" + s.state.airScout_asClientNameString = "KST2" + s.state.airScout_asCommunicationPort = 9873 + s.state.airScout_autoBandSelectionEnabled = true + s.state.airScout_asBandString = "4320000" + + assertTrue(s.prefs.isAirScout_asUDPListenerEnabled()) + assertEquals("AS2", s.prefs.getAirScout_asServerNameString()) + assertEquals("KST2", s.prefs.getAirScout_asClientNameString()) + assertEquals(9873, s.prefs.getAirScout_asCommunicationPort()) + assertTrue(s.prefs.isAirScout_autoBandSelectionEnabled()) + assertEquals("4320000", s.prefs.getAirScout_asBandString()) + } + + @Test + fun `identifiers are stored trimmed`() { + val s = Session() + + s.state.airScout_asServerNameString = " AS " + s.state.airScout_asClientNameString = " KST " + + assertEquals("AS", s.prefs.getAirScout_asServerNameString()) + assertEquals("KST", s.prefs.getAirScout_asClientNameString()) + } + + @Test + fun `an invalid identifier keeps the configured one instead of falling back`() { + // The AirScout protocol carries these identifiers inside quoted fields: + // empty, quotation marks and line breaks are what the JavaFX window rejected. + // Guarding before the write matters because the ChatPreferences setter does + // not keep the old value on bad input, it substitutes the factory default — + // an unguarded keystroke would silently reset the operator's identifier. + val s = Session() + s.prefs.setAirScout_asServerNameString("AS7") + s.prefs.setAirScout_asClientNameString("KST7") + + for (rejected in listOf("", " ", "A\"S", "A\rS", "A\nS")) { + s.state.airScout_asServerNameString = rejected + s.state.airScout_asClientNameString = rejected + assertFalse(AirscoutTabState.isValidIdentifier(rejected), "must be rejected: <$rejected>") + } + + assertEquals("AS7", s.prefs.getAirScout_asServerNameString()) + assertEquals("KST7", s.prefs.getAirScout_asClientNameString()) + } + + @Test + fun `a port outside the accepted range keeps the configured one`() { + val s = Session() + s.prefs.setAirScout_asCommunicationPort(9999) + + s.state.airScout_asCommunicationPort = 0 + s.state.airScout_asCommunicationPort = 65536 + + assertEquals(9999, s.prefs.getAirScout_asCommunicationPort(), + "the ChatPreferences setter would have substituted 9872 here") + + s.state.airScout_asCommunicationPort = 1 + assertEquals(1, s.prefs.getAirScout_asCommunicationPort()) + + s.state.airScout_asCommunicationPort = 65535 + assertEquals(65535, s.prefs.getAirScout_asCommunicationPort(), + "the JavaFX field accepted 1..65535; the range must not get narrower") + } + + @Test + fun `the band value is stored as the protocol spells it`() { + val s = Session() + s.prefs.setAirScout_asBandString("1440000") + + s.state.airScout_asBandString = " 04320000 " + assertEquals("4320000", s.prefs.getAirScout_asBandString(), + "the JavaFX field stored Long.toString of the parsed value") + + s.state.airScout_asBandString = "0" + s.state.airScout_asBandString = "-1" + s.state.airScout_asBandString = "144 MHz" + assertEquals("4320000", s.prefs.getAirScout_asBandString(), + "a value that is not a positive number was rejected, not stored — the " + + "ChatPreferences setter would have substituted 1440000 here") + } + + @Test + fun `the forced band value is only editable while automatic selection is off`() { + val s = Session() + + s.state.airScout_autoBandSelectionEnabled = true + assertFalse(s.state.bandValueEditable, + "the JavaFX band field was disabled while auto per station was selected") + + s.state.airScout_autoBandSelectionEnabled = false + assertTrue(s.state.bandValueEditable) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/BeaconTabStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/BeaconTabStateTest.kt new file mode 100644 index 00000000..c531ab33 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/BeaconTabStateTest.kt @@ -0,0 +1,138 @@ +package kst4contest.view.compose.tabs + +import kst4contest.controller.ChatController +import kst4contest.model.ChatPreferences +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue + +class BeaconTabStateTest { + + private class Session(private val templateRefusal: String? = null) { + val prefs = ChatPreferences() + var timerRestarts = 0 + var validated = mutableListOf() + + fun state() = BeaconTabState( + prefs, + validateBeaconTemplate = { template -> + validated.add(template) + templateRefusal?.let { throw IllegalArgumentException(it) } + }, + restartBeaconTimer = { timerRestarts++ }, + mainCategoryName = "144 MHz and up", + secondCategoryName = "50 MHz", + ) + } + + @Test + fun `the enable flags write through at once`() { + val s = Session() + val state = s.state() + + state.bcn_beaconsEnabledMainCat = true + state.bcn_beaconsEnabledSecondCat = true + + assertTrue(s.prefs.isBcn_beaconsEnabledMainCat()) + assertTrue(s.prefs.isBcn_beaconsEnabledSecondCat()) + + state.bcn_beaconsEnabledSecondCat = false + assertFalse(s.prefs.isBcn_beaconsEnabledSecondCat()) + assertTrue(s.prefs.isBcn_beaconsEnabledMainCat()) + } + + @Test + fun `a valid beacon template is validated and stored verbatim`() { + val s = Session() + val state = s.state() + val template = "CQ MYCALL MYLOC QRV MYQRG" + + assertNull(state.commitBeaconTextMainCat(template)) + + assertEquals(template, s.prefs.getBcn_beaconTextMainCat(), + "MYCALL and MYQRG are resolved by MessageVariableResolver; " + + "any rewriting would break that silently") + assertEquals(listOf(template), s.validated) + } + + @Test + fun `the second category has its own template`() { + val s = Session() + val state = s.state() + + state.commitBeaconTextSecondCat("CQ MYCALL on MYQRG") + + assertEquals("CQ MYCALL on MYQRG", s.prefs.getBcn_beaconTextSecondCat()) + assertEquals("Hi, pse call us", s.prefs.getBcn_beaconTextMainCat(), + "the main-category template is untouched") + } + + @Test + fun `a refused template is reported and the stored one stands`() { + val s = Session("Message too long") + s.prefs.setBcn_beaconTextMainCat("CQ MYCALL") + val state = s.state() + + val refusal = state.commitBeaconTextMainCat("x".repeat(500)) + + assertNotNull(refusal) + assertEquals("CQ MYCALL", s.prefs.getBcn_beaconTextMainCat(), + "the JavaFX field restored the previous template on an alert") + } + + @Test + fun `the shared interval never reads below the minimum`() { + val s = Session() + s.prefs.setBcn_beaconIntervalInMinutesMainCat(0) + + assertEquals(ChatController.MIN_BEACON_INTERVAL_MINUTES, s.state().beaconIntervalMinutes) + } + + @Test + fun `a valid interval is written to both categories and restarts the timer`() { + val s = Session() + val state = s.state() + + assertNull(state.commitBeaconInterval("7")) + + assertEquals(7, s.prefs.getBcn_beaconIntervalInMinutesMainCat()) + assertEquals(7, s.prefs.getBcn_beaconIntervalInMinutesSecondCat(), + "the legacy second-category value stays synchronized with the shared interval") + assertEquals(1, s.timerRestarts) + } + + @Test + fun `an interval below the minimum is refused and the timer is left alone`() { + val s = Session() + s.prefs.setBcn_beaconIntervalInMinutesMainCat(5) + val state = s.state() + + assertNotNull(state.commitBeaconInterval("0")) + + assertEquals(5, s.prefs.getBcn_beaconIntervalInMinutesMainCat()) + assertEquals(0, s.timerRestarts, + "restarting the timer per rejected keystroke would disturb the cooldown") + } + + @Test + fun `an interval that is not a whole number is refused`() { + val s = Session() + s.prefs.setBcn_beaconIntervalInMinutesMainCat(5) + val state = s.state() + + assertNotNull(state.commitBeaconInterval("2,5")) + + assertEquals(5, s.prefs.getBcn_beaconIntervalInMinutesMainCat()) + } + + @Test + fun `the category names are the labels the tab shows`() { + val s = Session() + + assertEquals("144 MHz and up", s.state().mainCategoryName) + assertEquals("50 MHz", s.state().secondCategoryName) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ColourShortcutsTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ColourShortcutsTest.kt new file mode 100644 index 00000000..a1e2f444 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ColourShortcutsTest.kt @@ -0,0 +1,80 @@ +package kst4contest.view.compose.tabs + +import androidx.compose.ui.input.key.Key +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Test + +/** + * The keyboard path to the three ways back. + * + * The spec requires one for all three, and says why: with no "not yet applied" state the ways + * back are the only way back, and they must be reachable without colour perception. Tabbing + * blindly through six text fields to find three buttons is reachable in the sense that a + * locked door with the key inside is openable. + * + * Only the decision is tested, not the KeyEvent plumbing -- the same split WindowShortcuts + * uses, and for the same reason: a desktop KeyEvent wraps a native AWT event and testing it + * would test Compose rather than this. + */ +class ColourShortcutsTest { + + @Test + fun theThreeWaysBackHaveTheirOwnKeys() { + assertEquals(ColourAction.BACK_TO_PREVIOUS, ColourShortcuts.actionFor(true, Key.Z)) + assertEquals(ColourAction.DISCARD_CHANGES, ColourShortcuts.actionFor(true, Key.D)) + assertEquals(ColourAction.RESET_TO_SHIPPED, ColourShortcuts.actionFor(true, Key.R)) + } + + @Test + fun eachActionHasExactlyOneKeyAndNoKeyHasTwoActions() { + val keys = listOf(Key.Z, Key.D, Key.R) + val actions = keys.map { ColourShortcuts.actionFor(true, it) } + + assertEquals(ColourAction.values().toList(), actions) + assertEquals(ColourAction.values().size, actions.toSet().size) + } + + @Test + fun withoutControlTheKeysAreJustTypingAndMustReachTheFields() { + /* + * Six hex fields sit in this tab. A bare letter shortcut would eat the typing it is + * meant to protect -- #DDEEFF contains a D. + */ + assertNull(ColourShortcuts.actionFor(false, Key.Z)) + assertNull(ColourShortcuts.actionFor(false, Key.D)) + assertNull(ColourShortcuts.actionFor(false, Key.R)) + } + + @Test + fun anyOtherKeyIsNotAShortcut() { + assertNull(ColourShortcuts.actionFor(true, Key.A)) + assertNull(ColourShortcuts.actionFor(true, Key.Enter)) + assertNull(ColourShortcuts.actionFor(true, Key.Escape)) + } + + @Test + fun theKeysDoNotCollideWithTheMainWindowsOwnShortcuts() { + /* + * The main window takes Enter, Escape and Ctrl+1 to Ctrl+0. None of the three here may + * be one of those, or an operator with the settings window focused would fire both. + */ + for (digit in listOf("1", "2", "3", "4", "5", "6", "7", "8", "9", "0")) { + assertNull( + kst4contest.view.compose.WindowShortcuts.snippetIndexFor("z"), + "a letter key became a snippet slot", + ) + } + + assertNull(ColourShortcuts.actionFor(true, Key.Enter)) + assertNull(ColourShortcuts.actionFor(true, Key.Escape)) + } + + @Test + fun everyActionIsLabelledForTheOperatorToRead() { + // A shortcut nobody is told about is not a second safety net. + ColourAction.values().forEach { + assert(ColourShortcuts.labelFor(it).isNotBlank()) { "$it has no label" } + } + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ColoursTabStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ColoursTabStateTest.kt new file mode 100644 index 00000000..4e8516de --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ColoursTabStateTest.kt @@ -0,0 +1,219 @@ +package kst4contest.view.compose.tabs + +import androidx.compose.ui.graphics.Color +import kst4contest.model.PaletteRole +import kst4contest.view.compose.ContrastPair +import kst4contest.view.compose.JavaFxStylesheet +import kst4contest.view.compose.PaletteSource +import kst4contest.view.compose.OperatorProfilePaletteFiles +import kst4contest.view.compose.PaletteStore +import kst4contest.view.i18n.Strings +import kst4contest.view.i18n.Translations +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import java.io.File + +/** + * The colours tab as a typed facade over the store. + * + * Built over a store made of lambdas, so nothing here touches the operator's home directory. + * What is pinned is what the tab shows and what it refuses: a role's colour, where that + * colour came from, and the fact that nonsense typed into a field changes nothing. + */ +class ColoursTabStateTest { + + private val stored = mutableMapOf(false to "", true to "") + private var fileRoles: Map = emptyMap() + private var darkMode = false + + private fun baseStrings(): Strings { + val base = Translations.BY_LANGUAGE.getValue(Translations.BASE_LANGUAGE) + return Strings { key -> base[key] ?: key } + } + + private fun state(): ColoursTabState { + val store = PaletteStore( + shippedOf = { dark -> + JavaFxStylesheet.read( + if (dark) "/KST4ContestDefaultEvening.css" else "/KST4ContestDefaultDay.css" + ) + }, + fileRolesOf = { fileRoles }, + storedOverridesOf = { dark -> stored.getValue(dark) }, + storeOverrides = { dark, encoded -> stored[dark] = encoded }, + ) + return ColoursTabState( + store, + { darkMode }, + OperatorProfilePaletteFiles( + dayFile = File("/nonexistent/day.css"), + eveningFile = File("/nonexistent/evening.css"), + ), + ) + } + + @Test + fun everyRoleIsShownWithItsColourAndItsProvenance() { + val tab = state() + + val rows = tab.roles() + + assertEquals(PaletteRole.values().toList(), rows.map { it.role }) + rows.forEach { + assertEquals(PaletteSource.SHIPPED, it.source, "${it.role}") + assertTrue(it.hex.matches(Regex("#[0-9A-F]{6}")), "${it.role} shows '${it.hex}'") + /* + * The label is resolved at the point of use rather than held, so the tab retitles + * its rows when the language changes. Resolved here against the base language. + */ + assertTrue(it.label(baseStrings()).isNotBlank(), "${it.role} has no label") + } + } + + @Test + fun aSetColourIsShownAsChanged() { + val tab = state() + + val refusal = tab.set(PaletteRole.ACCENT, "#FF0000") + + val row = tab.roles().single { it.role == PaletteRole.ACCENT } + assertEquals("#FF0000", row.hex) + assertEquals(PaletteSource.CHANGED, row.source) + assertNull(refusal, "a valid colour was refused: $refusal") + } + + @Test + fun aRoleTakenFromTheFileSaysSo() { + /* + * The mitigation the spec calls mandatory: with two sources that can decide the same + * colour, "why is this colour what it is" has to be answerable per role. + */ + fileRoles = mapOf(PaletteRole.ACCENT to Color(0xFF00FF00)) + val tab = state() + + assertEquals( + PaletteSource.FILE, + tab.roles().single { it.role == PaletteRole.ACCENT }.source, + ) + } + + @Test + fun nonsenseTypedIntoAFieldChangesNothingAndIsReported() { + val tab = state() + val before = tab.roles().single { it.role == PaletteRole.TEXT }.hex + + /* + * The refusal is returned rather than pushed, which is the contract Form.committed + * expects: it puts the field back to the stored value and shows the reason. + */ + for (nonsense in listOf("rot", "", "#GGG", "#1234567", "ECECEC", " ")) { + val refusal = tab.set(PaletteRole.TEXT, nonsense) + assertTrue( + refusal != null && refusal.isNotBlank(), + "'$nonsense' was accepted or refused without a reason", + ) + } + + assertEquals(before, tab.roles().single { it.role == PaletteRole.TEXT }.hex) + assertEquals(PaletteSource.SHIPPED, tab.roles().single { it.role == PaletteRole.TEXT }.source) + } + + @Test + fun settingARoleToTheColourItAlreadyHasIsNotARefusal() { + /* + * set() decides by comparing the colour before and after, so a valid colour that + * happens to equal the current one changes nothing -- and reporting that as "'#ECECEC' + * is not a colour" would be a lie the operator cannot argue with. The field commits on + * focus loss, so this happens whenever somebody tabs through without editing. + */ + val tab = state() + val unchanged = tab.roles().single { it.role == PaletteRole.SURFACE }.hex + + assertNull(tab.set(PaletteRole.SURFACE, unchanged), "an unchanged colour was refused") + assertNull(tab.set(PaletteRole.SURFACE, unchanged.lowercase()), "case alone was refused") + } + + @Test + fun theRowsFollowTheActiveDesign() { + val tab = state() + tab.set(PaletteRole.ACCENT, "#FF0000") + + darkMode = true + + // The evening design has its own overrides; the daylight change must not show here. + assertEquals( + PaletteSource.SHIPPED, + tab.roles().single { it.role == PaletteRole.ACCENT }.source, + ) + } + + @Test + fun theWarningsDescribeTheResolvedPaletteAgainstTheShippedOne() { + val tab = state() + assertTrue(tab.warnings().isEmpty(), "the untouched state warns: ${tab.warnings()}") + + tab.set(PaletteRole.TEXT, "#FFFFFF") + + // White label text on the light window surface is unreadable and worse than shipped. + assertTrue( + tab.warnings().any { it.what == ContrastPair.TEXT_ON_WINDOW_SURFACE }, + "no warning for white on light grey: ${tab.warnings()}", + ) + } + + @Test + fun theLifelineColoursComeFromTheShippedSheet() { + /* + * The reason this accessor exists at all. A tab reading its rescue colours from the + * resolved palette would draw them in exactly the palette they exist to undo. + */ + val tab = state() + val shippedBase = tab.shipped().base + + PaletteRole.values().forEach { tab.set(it, "#000000") } + + assertEquals(shippedBase, tab.shipped().base) + assertFalse(shippedBase == Color.Black, "the shipped base is black, so this proves nothing") + } + + @Test + fun theThreeWaysBackDoTheThreeDifferentThings() { + fileRoles = mapOf(PaletteRole.ACCENT to Color(0xFF00FF00)) + val tab = state() + + // Back to how it was when the tab opened, including a change already present. + tab.set(PaletteRole.ACCENT, "#FF0000") + tab.rememberCurrentState() + tab.set(PaletteRole.ACCENT, "#0000FF") + tab.restoreRemembered() + assertEquals("#FF0000", tab.roles().single { it.role == PaletteRole.ACCENT }.hex) + + // Discard my changes: the file applies again. + tab.discardChanges() + assertEquals( + PaletteSource.FILE, + tab.roles().single { it.role == PaletteRole.ACCENT }.source, + ) + + // Back to shipped: beats the file too. + tab.resetToShipped() + val row = tab.roles().single { it.role == PaletteRole.ACCENT } + assertEquals(PaletteSource.CHANGED, row.source) + assertEquals(tab.shipped().accent, kst4contest.view.compose.colourOf(row.hex)) + } + + @Test + fun theFileRouteNamesThisDesignsOwnStylesheet() { + val tab = state() + + assertTrue(tab.stylesheetPath().endsWith("day.css"), tab.stylesheetPath()) + assertFalse(tab.stylesheetExists(), "a nonexistent file was reported as present") + + darkMode = true + + assertTrue(tab.stylesheetPath().endsWith("evening.css"), tab.stylesheetPath()) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/GuiOptionsTabStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/GuiOptionsTabStateTest.kt new file mode 100644 index 00000000..9e146fdd --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/GuiOptionsTabStateTest.kt @@ -0,0 +1,84 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatPreferences +import kst4contest.view.i18n.LanguageStore +import kst4contest.view.i18n.LanguageStoreFactory +import kst4contest.view.i18n.SYSTEM_LANGUAGE +import org.junit.jupiter.api.Test +import java.util.Locale +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue + +class GuiOptionsTabStateTest { + + /* + * Over lambdas rather than over the preferences, so switching the language in a test does + * not write into the operator's home directory. What this file is about is the GUI tab's + * booleans; the language is covered by LanguageStoreTest. + */ + private var storedLanguage = SYSTEM_LANGUAGE + + private fun languageStore() = LanguageStore( + storedLanguage = { storedLanguage }, + storeLanguage = { storedLanguage = it }, + systemDefault = Locale.UK, + ) + + @Test + fun theLanguageIsWrittenThroughTheStoreAndReachesThePreference() { + /* + * Over the real factory rather than the lambda store above, because what this asserts + * is the wiring: setting the language on the tab state has to land in the preference + * that gets saved, and it has to do so through the store, which is what repaints the + * open windows. A store wired to anything else would pass a weaker test. + */ + val prefs = ChatPreferences() + val state = GuiOptionsTabState(prefs, LanguageStoreFactory.create(prefs, Locale.UK)) + + state.language = "de" + + assertEquals("de", state.language) + assertEquals("de", prefs.guiOptions_language) + } + + + @Test + fun `reading comes straight from the preferences`() { + val prefs = ChatPreferences() + prefs.setGUI_darkModeActiveByDefault(true) + + assertTrue(GuiOptionsTabState(prefs, languageStore()).gUI_darkModeActiveByDefault) + } + + @Test + fun `writing reaches the preferences at once`() { + val prefs = ChatPreferences() + val state = GuiOptionsTabState(prefs, languageStore()) + + state.guiOptions_defaultFilterPublicMsgs = true + state.guiOptions_showFreshCallHintInBandColumns = true + + assertTrue(prefs.isGuiOptions_defaultFilterPublicMsgs()) + assertTrue(prefs.isGuiOptions_showFreshCallHintInBandColumns()) + } + + @Test + fun `the four startup filters are independent switches`() { + // The JavaFX tab offered them as four separate checkboxes, not a choice of + // one. Turning them into a radio group would take a combination away that + // an operator may have configured. + val prefs = ChatPreferences() + val state = GuiOptionsTabState(prefs, languageStore()) + + state.guiOptions_defaultFilterPublicMsgs = true + state.guiOptions_defaultFilterPmToMe = true + state.guiOptions_defaultFilterPmToOther = false + state.guiOptions_defaultFilterNothing = false + + assertTrue(prefs.isGuiOptions_defaultFilterPublicMsgs()) + assertTrue(prefs.isGuiOptions_defaultFilterPmToMe()) + assertFalse(prefs.isGuiOptions_defaultFilterPmToOther()) + assertFalse(prefs.isGuiOptions_defaultFilterNothing()) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/LifelineColoursTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/LifelineColoursTest.kt new file mode 100644 index 00000000..71879671 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/LifelineColoursTest.kt @@ -0,0 +1,76 @@ +package kst4contest.view.compose.tabs + +import androidx.compose.ui.graphics.Color +import kst4contest.view.compose.JavaFxStylesheet +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import kst4contest.view.compose.CONTRAST_FLOOR +import kst4contest.view.compose.contrastRatio + +/** + * The colours of the one control that refuses the operator's palette. + * + * The fault this guards against closes itself in: an operator who sets text and surface to + * the same black can no longer see the buttons that would undo it. So this control is drawn + * from the shipped sheet, always, and that is checked here against a palette in which every + * role has been changed. + * + * The composable itself takes the shipped palette as a required parameter and never reads + * LocalJavaFxPalette, so it has no way to reach the resolved palette at all. These tests + * cover the colour decision; that it cannot be fed the wrong palette is structural. + */ +class LifelineColoursTest { + + private val shipped = JavaFxStylesheet.read("/KST4ContestDefaultDay.css") + + @Test + fun theColoursComeFromThePaletteItIsGiven() { + val colours = lifelineColours(shipped) + + assertEquals(shipped.base, colours.container) + assertEquals(shipped.labelTextFill, colours.content) + } + + @Test + fun aFullyBlackedOutPaletteGivesDifferentColoursThanTheShippedOne() { + /* + * The palette an operator locks themselves out with. If the lifeline ever read it, + * these two would agree and the button would be invisible exactly when needed. + */ + val blackedOut = shipped.copy( + base = Color.Black, + windowBackground = Color.Black, + controlInnerBackground = Color.Black, + labelTextFill = Color.Black, + accent = Color.Black, + separatorLine = Color.Black, + ) + + assertNotEquals(lifelineColours(shipped), lifelineColours(blackedOut)) + } + + @Test + fun theShippedColoursAreReadableAgainstEachOther() { + /* + * A lifeline has to be legible on its own terms. Both shipped sheets pass here, which + * is not true of every pair in them -- the accent does not -- so this is a real check + * and not a restatement. + */ + for (sheet in listOf("/KST4ContestDefaultDay.css", "/KST4ContestDefaultEvening.css")) { + val colours = lifelineColours(JavaFxStylesheet.read(sheet)) + val ratio = contrastRatio(colours.content, colours.container) + + assertTrue(ratio >= CONTRAST_FLOOR, "$sheet gives the lifeline a ratio of $ratio") + } + } + + @Test + fun theBorderIsVisibleAgainstTheContainer() { + // The border is what makes it read as a control rather than as a patch of colour. + val colours = lifelineColours(shipped) + + assertNotEquals(colours.container, colours.border) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/LogSynchTabStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/LogSynchTabStateTest.kt new file mode 100644 index 00000000..7e5afc61 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/LogSynchTabStateTest.kt @@ -0,0 +1,156 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatPreferences +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue + +class LogSynchTabStateTest { + + private class Session(detected: String? = null) { + val prefs = ChatPreferences() + var restarts = 0 + var stops = 0 + val detectedBroadcast = detected + + fun state() = LogSynchTabState( + prefs, + restartWintestListener = { restarts++ }, + stopWintestListener = { stops++ }, + detectWintestBroadcastAddress = { detectedBroadcast }, + ) + } + + @Test + fun `reading comes straight from the preferences`() { + val s = Session() + s.prefs.setLogsynch_fileBasedWkdCallInterpreterEnabled(true) + s.prefs.setLogsynch_fileBasedWkdCallInterpreterFileNameReadOnly("/tmp/wkd.txt") + s.prefs.setLogsynch_ucxUDPWkdCallListenerEnabled(true) + s.prefs.setLogsynch_ucxUDPWkdCallListenerPort(12060) + s.prefs.setLogsynch_wintestNetworkPort(9871) + s.prefs.setLogsynch_wintestNetworkStationNameOfKST("KST") + val state = s.state() + + assertTrue(state.logsynch_fileBasedWkdCallInterpreterEnabled) + assertEquals("/tmp/wkd.txt", state.logsynch_fileBasedWkdCallInterpreterFileNameReadOnly) + assertTrue(state.logsynch_ucxUDPWkdCallListenerEnabled) + assertEquals(12060, state.logsynch_ucxUDPWkdCallListenerPort) + assertEquals(9871, state.logsynch_wintestNetworkPort) + assertEquals("KST", state.logsynch_wintestNetworkStationNameOfKST) + } + + @Test + fun `writing reaches the preferences at once, without a confirmation step`() { + // The JavaFX window had no value-collecting confirmation: each control wrote + // straight into ChatPreferences, and "Save settings" only persisted them. + val s = Session() + val state = s.state() + + state.logsynch_fileBasedWkdCallInterpreterEnabled = true + state.logsynch_fileBasedWkdCallInterpreterFileNameReadOnly = "/home/op/log.adi" + state.logsynch_ucxUDPWkdCallListenerEnabled = true + state.logsynch_ucxUDPWkdCallListenerPort = 12060 + state.logsynch_wintestNetworkPort = 9871 + + assertTrue(s.prefs.isLogsynch_fileBasedWkdCallInterpreterEnabled()) + assertEquals("/home/op/log.adi", s.prefs.getLogsynch_fileBasedWkdCallInterpreterFileNameReadOnly()) + assertTrue(s.prefs.isLogsynch_ucxUDPWkdCallListenerEnabled()) + assertEquals(12060, s.prefs.getLogsynch_ucxUDPWkdCallListenerPort()) + assertEquals(9871, s.prefs.getLogsynch_wintestNetworkPort()) + } + + @Test + fun `the Win-Test station name and broadcast address are stored trimmed`() { + // The JavaFX fields committed getText().trim(); a stray space in a station + // name or a broadcast address is a protocol value, not decoration. + val s = Session() + val state = s.state() + + state.logsynch_wintestNetworkStationNameOfKST = " KST " + state.logsynch_wintestNetworkBroadcastAddress = " 192.168.1.255 " + + assertEquals("KST", s.prefs.getLogsynch_wintestNetworkStationNameOfKST()) + assertEquals("192.168.1.255", s.prefs.getLogsynch_wintestNetworkBroadcastAddress()) + } + + @Test + fun `enabling the Win-Test listener starts it and disabling stops it`() { + val s = Session() + val state = s.state() + + state.logsynch_wintestNetworkListenerEnabled = true + + assertTrue(s.prefs.isLogsynch_wintestNetworkListenerEnabled()) + assertEquals(1, s.restarts, "the running listener must follow the setting") + + state.logsynch_wintestNetworkListenerEnabled = false + + assertFalse(s.prefs.isLogsynch_wintestNetworkListenerEnabled()) + assertEquals(1, s.stops) + } + + @Test + fun `a committed port change rebinds the listener only while it is enabled`() { + // Deliberately not on every keystroke: the port write goes through at once, + // but rebinding a UDP socket is bound to the commit, as the JavaFX field's + // focus-lost handler did. + val s = Session() + val state = s.state() + + /* + * Switched off explicitly: ChatPreferences ships + * logsynch_wintestNetworkListenerEnabled = true (ChatPreferences.java:254), so + * a fresh configuration already listens. + */ + state.logsynch_wintestNetworkListenerEnabled = false + val restartsAfterDisable = s.restarts + + state.logsynch_wintestNetworkPort = 9872 + assertEquals(restartsAfterDisable, s.restarts, "a keystroke must not rebind the socket") + + state.commitWintestNetworkPort() + assertEquals(restartsAfterDisable, s.restarts, "a disabled listener has nothing to rebind") + + state.logsynch_wintestNetworkListenerEnabled = true + val restartsAfterEnable = s.restarts + state.logsynch_wintestNetworkPort = 9873 + state.commitWintestNetworkPort() + + assertEquals(9873, s.prefs.getLogsynch_wintestNetworkPort()) + assertEquals(restartsAfterEnable + 1, s.restarts) + } + + @Test + fun `a still-default broadcast address is replaced by the detected one`() { + val s = Session(detected = "192.168.178.255") + s.prefs.setLogsynch_wintestNetworkBroadcastAddress("255.255.255.255") + + s.state() + + assertEquals("192.168.178.255", s.prefs.getLogsynch_wintestNetworkBroadcastAddress(), + "the JavaFX window auto-detected the subnet broadcast while the stored " + + "value was still the catch-all default") + } + + @Test + fun `a broadcast address the operator chose is never overwritten`() { + val s = Session(detected = "192.168.178.255") + s.prefs.setLogsynch_wintestNetworkBroadcastAddress("10.0.0.255") + + s.state() + + assertEquals("10.0.0.255", s.prefs.getLogsynch_wintestNetworkBroadcastAddress()) + } + + @Test + fun `a failed detection leaves the default in place`() { + val s = Session(detected = null) + s.prefs.setLogsynch_wintestNetworkBroadcastAddress("255.255.255.255") + + s.state() + + assertEquals("255.255.255.255", s.prefs.getLogsynch_wintestNetworkBroadcastAddress()) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/MessageHandlingTabStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/MessageHandlingTabStateTest.kt new file mode 100644 index 00000000..4e6ea1a6 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/MessageHandlingTabStateTest.kt @@ -0,0 +1,65 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatPreferences +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue + +class MessageHandlingTabStateTest { + + @Test + fun `the state starts from the stored preferences`() { + val prefs = ChatPreferences() + prefs.setMessageHandling_autoAnswerEnabled(true) + prefs.setMessageHandling_autoAnswerToQRGRequestEnabled(true) + prefs.setMessageHandling_autoAnswerTextMainCat("qrv 144.300") + + val state = MessageHandlingTabState(prefs) + + assertTrue(state.autoAnswerEnabled) + assertTrue(state.autoAnswerToQRGRequestEnabled) + assertEquals("qrv 144.300", state.autoAnswerText) + } + + @Test + fun `one checkbox drives both category flags`() { + // The JavaFX window offered a single checkbox and wrote both preferences from + // it; keeping only the main one would leave the second chat on its old value. + val prefs = ChatPreferences() + val state = MessageHandlingTabState(prefs) + + state.autoAnswerEnabled = true + + assertTrue(prefs.isMessageHandling_autoAnswerEnabled()) + assertTrue(prefs.isMessageHandling_autoAnswerEnabledSecondCat()) + + state.autoAnswerEnabled = false + + assertFalse(prefs.isMessageHandling_autoAnswerEnabled()) + assertFalse(prefs.isMessageHandling_autoAnswerEnabledSecondCat()) + } + + @Test + fun `one text field drives both category texts`() { + val prefs = ChatPreferences() + val state = MessageHandlingTabState(prefs) + + state.autoAnswerText = "qrv 432.200" + + assertEquals("qrv 432.200", prefs.getMessageHandling_autoAnswerTextMainCat()) + assertEquals("qrv 432.200", prefs.getMessageHandling_autoAnswerTextSecondCat()) + } + + @Test + fun `the QRG reply flag writes through on its own`() { + val prefs = ChatPreferences() + val state = MessageHandlingTabState(prefs) + + state.autoAnswerToQRGRequestEnabled = true + + assertTrue(prefs.isMessageHandling_autoAnswerToQRGRequestEnabled()) + assertFalse(prefs.isMessageHandling_autoAnswerEnabled(), + "the two options are independent") + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/NotificationTabStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/NotificationTabStateTest.kt new file mode 100644 index 00000000..4b561158 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/NotificationTabStateTest.kt @@ -0,0 +1,272 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.Band +import kst4contest.model.ChatMember +import kst4contest.model.ChatPreferences +import kst4contest.observe.SimpleRoster +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertSame +import org.junit.jupiter.api.Assertions.assertTrue + +class NotificationTabStateTest { + + private class Session { + val prefs = ChatPreferences() + val monitored = SimpleRoster() + var serverEnabledApplied: Boolean? = null + var portApplied: Int? = null + var spotSent: ChatMember? = null + var spotRefusal: String? = null + + fun state() = NotificationTabState( + prefs, + monitored, + applyDxClusterServerEnabled = { serverEnabledApplied = it }, + applyDxClusterServerPort = { portApplied = it }, + broadcastTestSpot = { spotSent = it; spotRefusal }, + ) + } + + @Test + fun `the sound settings read from and write to the preferences at once`() { + val s = Session() + s.prefs.setNotify_playSimpleSounds(true) + val state = s.state() + + assertTrue(state.notify_playSimpleSounds) + + state.notify_playSimpleSounds = false + state.notify_playCWCallsignsOnRxedPMs = true + state.notify_playVoiceCallsignsOnRxedPMs = true + + assertFalse(s.prefs.isNotify_playSimpleSounds()) + assertTrue(s.prefs.isNotify_playCWCallsignsOnRxedPMs()) + assertTrue(s.prefs.isNotify_playVoiceCallsignsOnRxedPMs()) + } + + @Test + fun `the band-upgrade hints write through`() { + val s = Session() + val state = s.state() + + state.notify_bandUpgradeHintOnLogEnabled = true + state.notify_bandUpgradePriorityBoostEnabled = true + + assertTrue(s.prefs.isNotify_bandUpgradeHintOnLogEnabled()) + assertTrue(s.prefs.isNotify_bandUpgradePriorityBoostEnabled()) + } + + @Test + fun `enabling the DX cluster server also tells the running session`() { + val s = Session() + val state = s.state() + + state.enableDxClusterServer(true) + + assertTrue(s.prefs.isNotify_dxClusterServerEnabled()) + assertEquals(true, s.serverEnabledApplied, + "the JavaFX checkbox started or stopped the server as well, and the " + + "settings coverage test cannot see that call") + } + + @Test + fun `a valid port is stored and handed to the running session`() { + val s = Session() + val state = s.state() + + assertNull(state.commitDxClusterServerPort("7300")) + + assertEquals(7300, s.prefs.getNotify_dxclusterServerPort()) + assertEquals(7300, s.portApplied) + } + + @Test + fun `a port outside the TCP range is refused and nothing is written`() { + val s = Session() + s.prefs.setNotify_dxclusterServerPort(8000) + val state = s.state() + + val refusal = state.commitDxClusterServerPort("70000") + + assertNotNull(refusal, "the JavaFX field alerted and restored the previous port") + assertEquals(8000, s.prefs.getNotify_dxclusterServerPort()) + assertNull(s.portApplied, "an refused port must not restart the server") + } + + @Test + fun `a port that is not a number is refused`() { + val s = Session() + s.prefs.setNotify_dxclusterServerPort(8000) + val state = s.state() + + assertNotNull(state.commitDxClusterServerPort("acht")) + assertEquals(8000, s.prefs.getNotify_dxclusterServerPort()) + } + + @Test + fun `an unchanged port is stored but does not restart the server`() { + val s = Session() + s.prefs.setNotify_dxclusterServerPort(8000) + val state = s.state() + + assertNull(state.commitDxClusterServerPort("8000")) + + assertNull(s.portApplied, + "the JavaFX field only restarted the server when the port actually changed") + } + + @Test + fun `a spotter callsign is upper-cased and stored`() { + val s = Session() + val state = s.state() + + assertNull(state.commitSpotterCallSign(" do5amf ")) + + assertEquals("DO5AMF", s.prefs.getNotify_DXCSrv_SpottersCallSign().get()) + assertEquals("DO5AMF", state.notify_DXCSrv_SpottersCallSign) + } + + @Test + fun `a spotter callsign that is no callsign is refused`() { + val s = Session() + s.prefs.setNotify_DXCSrv_SpottersCallSign("DO5AMF") + val state = s.state() + + assertNotNull(state.commitSpotterCallSign("not a call")) + + assertEquals("DO5AMF", s.prefs.getNotify_DXCSrv_SpottersCallSign().get()) + } + + @Test + fun `the fallback band round trips through the stored prefix`() { + val s = Session() + val state = s.state() + + state.notify_optionalFrequencyPrefix = Band.B_432 + + assertEquals("432", s.prefs.getNotify_optionalFrequencyPrefix().get()) + assertEquals(Band.B_432, state.notify_optionalFrequencyPrefix) + } + + @Test + fun `an unsupported stored prefix falls back to 144 and is written back`() { + val s = Session() + s.prefs.setNotify_optionalFrequencyPrefix("4711") + + val state = s.state() + + assertEquals(Band.B_144, state.notify_optionalFrequencyPrefix) + assertEquals("144", s.prefs.getNotify_optionalFrequencyPrefix().get(), + "the JavaFX window repaired the stored value the same way") + } + + @Test + fun `the monitoring list starts from the roster`() { + val s = Session() + s.monitored.setAll(listOf("DN9APW", "DO5AMF")) + + assertEquals(listOf("DN9APW", "DO5AMF"), s.state().monitoredCallSigns.texts) + } + + @Test + fun `a monitored callsign is appended as its base call`() { + val s = Session() + val state = s.state() + + assertNull(state.addMonitoredCallSign(" dn9apw-70 ")) + + assertEquals(listOf("DN9APW"), state.monitoredCallSigns.texts, + "monitoring works on the base call, so every SSID maps to the same entry") + assertEquals(listOf("DN9APW"), s.monitored.snapshot(), + "the JavaFX button added to the roster at once") + } + + @Test + fun `a monitored callsign that is no callsign is refused`() { + val s = Session() + val state = s.state() + + assertNotNull(state.addMonitoredCallSign("hello")) + + assertTrue(state.monitoredCallSigns.texts.isEmpty()) + } + + @Test + fun `the same base call is not monitored twice`() { + val s = Session() + val state = s.state() + state.addMonitoredCallSign("DN9APW") + + assertNotNull(state.addMonitoredCallSign("dn9apw-2")) + + assertEquals(listOf("DN9APW"), state.monitoredCallSigns.texts) + } + + @Test + fun `editing a monitored entry normalizes it and reaches the roster`() { + val s = Session() + s.monitored.setAll(listOf("DN9APW")) + val state = s.state() + + state.monitoredCallSigns.commitAt(0, "do5amf-2") + state.commitMonitoredCallSigns() + + assertEquals(listOf("DO5AMF"), s.monitored.snapshot()) + } + + @Test + fun `an invalid edit of a monitored entry is refused and the roster is untouched`() { + val s = Session() + s.monitored.setAll(listOf("DN9APW")) + val state = s.state() + + val outcome = state.monitoredCallSigns.commitAt(0, "still not a call") + state.commitMonitoredCallSigns() + + assertTrue(outcome is kst4contest.view.compose.CommitOutcome.Refused) + assertEquals(listOf("DN9APW"), s.monitored.snapshot()) + } + + @Test + fun `clearing a monitored entry removes it from the roster`() { + val s = Session() + s.monitored.setAll(listOf("DN9APW", "DO5AMF")) + val state = s.state() + val rosterBefore = s.monitored + + state.monitoredCallSigns.commitAt(0, "") + state.commitMonitoredCallSigns() + + assertEquals(listOf("DO5AMF"), s.monitored.snapshot()) + assertSame(rosterBefore, s.monitored, + "the roster is filled, never replaced: a swap would orphan its listeners") + } + + @Test + fun `the test spot carries the values the JavaFX button used`() { + val s = Session() + val state = s.state() + + assertNull(state.sendTestSpot()) + + val spot = s.spotSent + assertNotNull(spot) + assertEquals("DO5AMF", spot!!.callSign) + assertEquals("300", spot.frequency.get()) + assertEquals("DXC test: You donated \$100!", spot.qra, + "deliberate test data, kept verbatim") + } + + @Test + fun `a refused test spot reports why`() { + val s = Session() + s.spotRefusal = "No DX Cluster client is connected to KST4Contest." + val state = s.state() + + assertEquals("No DX Cluster client is connected to KST4Contest.", state.sendTestSpot()) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ProfilesTabStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ProfilesTabStateTest.kt new file mode 100644 index 00000000..50249f53 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ProfilesTabStateTest.kt @@ -0,0 +1,168 @@ +package kst4contest.view.compose.tabs + +import kst4contest.controller.OperatorProfileManagementService +import kst4contest.controller.OperatorProfileStore +import kst4contest.model.OperatorProfile +import kst4contest.model.OperatorProfileSelection +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.io.TempDir +import java.nio.file.Path + +/** + * Rules of the profiles tab. + * + * Creating and deleting profiles is deliberately not exercised here: both reach into + * the real application directory under the operator's home, and a test that writes + * there could destroy a profile in use. Every rule below refuses before the service + * is called, which is exactly the part worth pinning down. + */ +class ProfilesTabStateTest { + + @TempDir + lateinit var registryDirectory: Path + + private fun service() = OperatorProfileManagementService( + OperatorProfileStore(registryDirectory.resolve("profiles.xml").toString()) + ) + + private fun state( + active: OperatorProfileSelection? = null, + onActivation: (OperatorProfile) -> Unit = { }, + ) = ProfilesTabState(service(), { active }, onActivation) + + @Test + fun `an absent registry still offers the default profile`() { + val state = state() + + assertEquals(1, state.profiles.size) + assertTrue(state.profiles.first().isRootProfile) + assertEquals(state.profiles.first(), state.selected, + "the JavaFX table selected the first row when nothing was selected yet") + } + + @Test + fun `the default profile cannot be deleted`() { + val state = state() + + val notice = state.deleteSelected() + + assertTrue(notice is ProfileNotice.Error) + assertEquals( + "The default profile uses the files of the installation itself and cannot be deleted.", + notice!!.message, + ) + assertEquals(1, state.profiles.size, "nothing was removed") + } + + @Test + fun `the default profile always uses the common worked stations`() { + val state = state() + + val notice = state.changeWorkedDataModeOfSelected(false) + + assertTrue(notice is ProfileNotice.Error, + "that database is the installation's own, so the choice does not exist") + assertFalse(state.canChangeWorkedDataMode(state.profiles.first())) + } + + @Test + fun `the profile in use cannot be deleted`() { + val plainService = service() + val profile = plainService.listProfiles().first() + val state = ProfilesTabState( + plainService, + { OperatorProfileSelection(profile, "preferences.xml", "worked.db", false) }, + { }, + ) + + val notice = state.deleteSelected() + + assertTrue(notice is ProfileNotice.Error) + } + + @Test + fun `switching to the profile already in use does nothing`() { + val plainService = service() + val profile = plainService.listProfiles().first() + var activations = 0 + val state = ProfilesTabState( + plainService, + { OperatorProfileSelection(profile, "preferences.xml", "worked.db", false) }, + { activations++ }, + ) + + val notice = state.activateSelected() + + assertTrue(notice is ProfileNotice.Info) + assertEquals("This profile is already active.", notice!!.message) + assertEquals(0, activations, + "a switch restarts into the other profile; doing that for no reason would " + + "drop the operator out of a running contest") + } + + @Test + fun `an unchanged worked-stations mode is not written`() { + /* + * The registry is seeded in the temporary directory so a non-root profile + * exists without creating one, which would write into the operator's home. + */ + val store = OperatorProfileStore(registryDirectory.resolve("profiles.xml").toString()) + val shared = OperatorProfile("p1", "DN9APW", false, true) + store.saveProfiles(listOf(shared), shared.profileId) + + val state = ProfilesTabState(OperatorProfileManagementService(store), { null }, { }) + + assertEquals(shared, state.selected) + assertNull(state.changeWorkedDataModeOfSelected(true), + "the mode already is the requested one, so nothing is written and nothing is said") + } + + @Test + fun `selecting a profile that is not in the list clears the selection`() { + val state = state() + + state.select(OperatorProfile("stale", "gone", false, false)) + + assertNull(state.selected, + "a profile deleted elsewhere must not stay selectable, or an action would " + + "operate on a profile that no longer exists") + } + + @Test + fun `a blank name creates nothing`() { + val state = state() + + assertNull(state.createProfile(" ", false)) + assertEquals(1, state.profiles.size) + } + + @Test + fun `the duplicate name suggestion is the one the JavaFX dialog pre-filled`() { + val state = state() + + assertEquals("Copy of " + state.profiles.first().displayName, state.duplicateNameSuggestion()) + } + + @Test + fun `the worked-stations column names the shared database for the root profile`() { + val root = OperatorProfile("root", "Default", true, false) + + assertEquals("common station database", ProfilesTabState.describeWorkedDataMode(root), + "the root profile reads the installation's database whatever its flag says") + assertEquals( + "own database", + ProfilesTabState.describeWorkedDataMode(OperatorProfile("p", "DN9APW", false, false)), + ) + } + + @Test + fun `a profile never used shows no date`() { + val unused = OperatorProfile("p", "DN9APW", false, false) + + assertEquals("", ProfilesTabState.describeLastUsed(unused)) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ShortcutsTabStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ShortcutsTabStateTest.kt new file mode 100644 index 00000000..ac19a9e3 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/ShortcutsTabStateTest.kt @@ -0,0 +1,117 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatPreferences +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertSame +import org.junit.jupiter.api.Assertions.assertTrue + +class ShortcutsTabStateTest { + + private class Session { + val prefs = ChatPreferences() + var shortcutRefreshes = 0 + var snippetRefreshes = 0 + + fun state() = ShortcutsTabState( + prefs, + refreshShortcutButtons = { shortcutRefreshes++ }, + refreshTextSnippetContextMenus = { snippetRefreshes++ }, + ) + } + + @Test + fun `both lists start from the stored rosters`() { + val s = Session() + s.prefs.getLst_txtShortCutBtnList().setAll(listOf("cq", "tnx")) + s.prefs.getLst_txtSnipList().setAll(listOf("qrv 144", "73")) + + val state = s.state() + + assertEquals(listOf("cq", "tnx"), state.shortcuts.texts) + assertEquals(listOf("qrv 144", "73"), state.snippets.texts) + } + + @Test + fun `a new shortcut lands at the top and reaches the roster at once`() { + val s = Session() + s.prefs.getLst_txtShortCutBtnList().setAll(listOf("alt")) + val state = s.state() + val rosterBefore = s.prefs.getLst_txtShortCutBtnList() + + state.shortcuts.addAtTop(ShortcutsTabState.NEW_ENTRY_TEMPLATE) + state.commitShortcuts() + + assertEquals( + listOf(ShortcutsTabState.NEW_ENTRY_TEMPLATE, "alt"), + s.prefs.getLst_txtShortCutBtnList().snapshot(), + ) + assertSame(rosterBefore, s.prefs.getLst_txtShortCutBtnList(), + "the roster is filled, never replaced: a swap would orphan its listeners") + } + + @Test + fun `committing the shortcuts rebuilds the shortcut buttons`() { + val s = Session() + val state = s.state() + + state.shortcuts.addAtTop("cq") + state.commitShortcuts() + + assertTrue(s.shortcutRefreshes > 0, + "the buttons above the message field are built from this list") + assertEquals(0, s.snippetRefreshes, "the snippet menus are a different list") + } + + @Test + fun `a cleared shortcut disappears from the roster`() { + val s = Session() + s.prefs.getLst_txtShortCutBtnList().setAll(listOf("cq", "tnx")) + val state = s.state() + + state.shortcuts.commitAt(0, " ") + state.commitShortcuts() + + assertEquals(listOf("tnx"), s.prefs.getLst_txtShortCutBtnList().snapshot(), + "clearing the text was how the operator removed an entry") + } + + @Test + fun `moving a shortcut reorders the roster`() { + val s = Session() + s.prefs.getLst_txtShortCutBtnList().setAll(listOf("a", "b")) + val state = s.state() + + state.shortcuts.select(0) + state.shortcuts.moveSelected(1) + state.commitShortcuts() + + assertEquals(listOf("b", "a"), s.prefs.getLst_txtShortCutBtnList().snapshot()) + } + + @Test + fun `a new snippet lands at the top and reaches its own roster`() { + val s = Session() + s.prefs.getLst_txtSnipList().setAll(listOf("alt")) + val state = s.state() + + state.snippets.addAtTop(ShortcutsTabState.NEW_ENTRY_TEMPLATE) + state.commitSnippets() + + assertEquals( + listOf(ShortcutsTabState.NEW_ENTRY_TEMPLATE, "alt"), + s.prefs.getLst_txtSnipList().snapshot(), + ) + assertTrue(s.snippetRefreshes > 0, + "the Ctrl+1..Ctrl+0 context menus are built from this list") + assertEquals(0, s.shortcutRefreshes) + } + + @Test + fun `the placeholder text of a new entry is the one the JavaFX button inserted`() { + assertEquals( + "CHANGE THIS TEXT VIA DOUBLECLICK or remove by deleting all text. Then hit enter key", + ShortcutsTabState.NEW_ENTRY_TEMPLATE, + ) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/StationTabStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/StationTabStateTest.kt new file mode 100644 index 00000000..80f0cf86 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/StationTabStateTest.kt @@ -0,0 +1,98 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatCategory +import kst4contest.model.ChatPreferences +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertTrue + +class StationTabStateTest { + + private class Session { + val prefs = ChatPreferences() + var mainApplied: ChatCategory? = null + var secondApplied: ChatCategory? = null + var secondWasApplied = false + val state = StationTabState( + prefs, + { mainApplied = it }, + { secondApplied = it; secondWasApplied = true }, + ) + } + + @Test + fun `reading comes straight from the preferences`() { + val s = Session() + s.prefs.setStn_loginCallSign("DN9APW") + s.prefs.setStn_on4kstServersPort(23001) + + assertEquals("DN9APW", s.state.stn_loginCallSign) + assertEquals(23001, s.state.stn_on4kstServersPort) + } + + @Test + fun `writing reaches the preferences at once, without a confirmation step`() { + // The JavaFX window had no value-collecting confirmation: each control wrote + // straight into ChatPreferences, and "Save settings" only persisted them. + val s = Session() + + s.state.stn_loginCallSign = "DO5AMF" + s.state.stn_pstRotatorEnabled = true + s.state.stn_qtfDefault = 135.0 + + assertEquals("DO5AMF", s.prefs.getStn_loginCallSign()) + assertTrue(s.prefs.isStn_pstRotatorEnabled()) + assertEquals(135.0, s.prefs.getStn_qtfDefault(), 0.001) + } + + @Test + fun `a band toggle round trips`() { + val s = Session() + + s.state.stn_bandActive144 = true + s.state.stn_bandActive432 = false + + assertTrue(s.prefs.isStn_bandActive144()) + assertEquals(false, s.prefs.isStn_bandActive432()) + assertTrue(s.state.stn_bandActive144) + } + + @Test + fun `selecting the main category writes both places it is held`() { + val s = Session() + val category = ChatCategory(2) + + s.state.selectMainCategory(category) + + assertEquals(2, s.prefs.getLoginChatCategoryMain().categoryNumber, + "the stored setting must follow the selection") + assertEquals(2, s.mainApplied?.categoryNumber, + "so must the running session; the JavaFX window wrote both, and the " + + "settings coverage test cannot see the ChatController write") + } + + @Test + fun `no second category is expressed as null`() { + val s = Session() + + s.state.selectSecondCategory(null) + + assertNull(s.prefs.getLoginChatCategorySecond(), + "the JavaFX window wrote null for 'no second chat'") + assertTrue(s.secondWasApplied, "the running session must learn about it too") + } + + @Test + fun `the second chat switch lives with the login settings`() { + // It moved here from the GUI tab: the JavaFX checkbox stood on the Station tab + // next to the category pickers, and it decides what the Connect button does. + val prefs = ChatPreferences() + val state = StationTabState(prefs, { }, { }) + + state.loginToSecondChatEnabled = true + + assertTrue(prefs.isLoginToSecondChatEnabled()) + assertEquals(true, state.loginToSecondChatEnabled) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/StylesheetExportTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/StylesheetExportTest.kt new file mode 100644 index 00000000..556d8223 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/StylesheetExportTest.kt @@ -0,0 +1,124 @@ +package kst4contest.view.compose.tabs + +import kst4contest.view.compose.JavaFxStylesheet +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotNull +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import java.io.File +import java.nio.file.Files + +/** + * Writing the shipped stylesheet into the profile, so it can be edited by hand. + * + * The one rule with teeth here is that an existing file is never overwritten. The file this + * writes to is the operator's own hand-edited work, and a button that silently replaced it + * would destroy an afternoon's work on one misclick. + */ +class StylesheetExportTest { + + private fun tempDirectory(): File = + Files.createTempDirectory("kst4contest-export").toFile() + + @Test + fun aMissingFileIsWrittenFromTheShippedSheet() { + val directory = tempDirectory() + val target = File(directory, "KST4ContestDefaultDay.css") + + val outcome = exportShippedStylesheet(target, darkMode = false) + + assertTrue(outcome is StylesheetExportOutcome.Written, "outcome was $outcome") + assertTrue(target.isFile, "nothing was written") + assertEquals( + JavaFxStylesheet::class.java.getResource("/KST4ContestDefaultDay.css")!!.readText(), + target.readText(), + "the written file is not the shipped sheet", + ) + + target.delete() + directory.delete() + } + + @Test + fun theEveningDesignWritesTheEveningSheet() { + val directory = tempDirectory() + val target = File(directory, "KST4ContestDefaultEvening.css") + + exportShippedStylesheet(target, darkMode = true) + + assertEquals( + JavaFxStylesheet::class.java.getResource("/KST4ContestDefaultEvening.css")!!.readText(), + target.readText(), + ) + + target.delete() + directory.delete() + } + + @Test + fun anExistingFileIsLeftAloneAndReported() { + /* + * The operator's hand-edited sheet. Overwriting it on a misclick is the one failure + * this button could cause that cannot be undone from inside the application. + */ + val directory = tempDirectory() + val target = File(directory, "KST4ContestDefaultDay.css") + target.writeText(".root { -fx-base: #112233; } /* mine */") + + val outcome = exportShippedStylesheet(target, darkMode = false) + + assertTrue(outcome is StylesheetExportOutcome.AlreadyThere, "outcome was $outcome") + assertEquals(".root { -fx-base: #112233; } /* mine */", target.readText()) + + target.delete() + directory.delete() + } + + @Test + fun aMissingProfileDirectoryIsCreated() { + // Only the root profile's directory exists already; every other profile's may not. + val directory = tempDirectory() + val target = File(directory, "profiles/OP2/KST4ContestDefaultDay.css") + + val outcome = exportShippedStylesheet(target, darkMode = false) + + assertTrue(outcome is StylesheetExportOutcome.Written, "outcome was $outcome") + assertTrue(target.isFile, "the directory was not created") + + target.delete() + target.parentFile.delete() + target.parentFile.parentFile.delete() + directory.delete() + } + + @Test + fun anUnwritablePlaceIsReportedRatherThanThrown() { + val target = File("/proc/kst4contest-cannot-write-here/day.css") + + val outcome = exportShippedStylesheet(target, darkMode = false) + + assertTrue(outcome is StylesheetExportOutcome.Failed, "outcome was $outcome") + assertNotNull((outcome as StylesheetExportOutcome.Failed).reason) + } + + @Test + fun whatIsWrittenCanBeReadBackAsRoles() { + /* + * The round trip the whole hand-editing route depends on: the file this writes has to + * be a file the layering can read. The evening sheet is the one that states colours. + */ + val directory = tempDirectory() + val target = File(directory, "KST4ContestDefaultEvening.css") + + exportShippedStylesheet(target, darkMode = true) + + // All six: five stated outright, the window surface derived from the stated base. + assertEquals( + kst4contest.model.PaletteRole.values().toSet(), + JavaFxStylesheet.declaredRolesOfFile(target).keys, + ) + + target.delete() + directory.delete() + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/TrxSynchTabStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/TrxSynchTabStateTest.kt new file mode 100644 index 00000000..a70cb9ca --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/TrxSynchTabStateTest.kt @@ -0,0 +1,120 @@ +package kst4contest.view.compose.tabs + +import kst4contest.model.ChatPreferences +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue + +class TrxSynchTabStateTest { + + private class Session { + val prefs = ChatPreferences() + val followerCalls = mutableListOf() + val state by lazy { TrxSynchTabState(prefs) { followerCalls.add(it) } } + } + + @Test + fun `reading comes straight from the preferences`() { + val s = Session() + s.prefs.setTrxSynch_ucxLogUDPListenerEnabled(true) + s.prefs.setLogsynch_wintestQrgSyncEnabled(true) + s.prefs.setLogsynch_wintestUsePassQrg(true) + s.prefs.setLogsynch_wintestNetworkStationNameOfWintestClient1("STN1") + + assertTrue(s.state.trxSynch_ucxLogUDPListenerEnabled) + assertTrue(s.state.logsynch_wintestQrgSyncEnabled) + assertTrue(s.state.logsynch_wintestUsePassQrg) + assertEquals("STN1", s.state.logsynch_wintestNetworkStationNameOfWintestClient1) + } + + @Test + fun `writing reaches the preferences at once, without a confirmation step`() { + val s = Session() + + s.state.trxSynch_ucxLogUDPListenerEnabled = true + s.state.logsynch_wintestQrgSyncEnabled = true + s.state.logsynch_wintestUsePassQrg = true + + assertTrue(s.prefs.isTrxSynch_ucxLogUDPListenerEnabled()) + assertTrue(s.prefs.isLogsynch_wintestQrgSyncEnabled()) + assertTrue(s.prefs.isLogsynch_wintestUsePassQrg()) + } + + @Test + fun `the Win-Test station name filter is stored trimmed, and an empty filter is allowed`() { + // Empty means "accept all" — the JavaFX label said so explicitly. + val s = Session() + + s.state.logsynch_wintestNetworkStationNameOfWintestClient1 = " STN1 " + assertEquals("STN1", s.prefs.getLogsynch_wintestNetworkStationNameOfWintestClient1()) + + s.state.logsynch_wintestNetworkStationNameOfWintestClient1 = " " + assertEquals("", s.prefs.getLogsynch_wintestNetworkStationNameOfWintestClient1()) + } + + @Test + fun `the own-QRG follower follows whether any source is enabled`() { + val s = Session() + + s.state.trxSynch_ucxLogUDPListenerEnabled = true + assertEquals(listOf(true), s.followerCalls) + + s.state.logsynch_wintestQrgSyncEnabled = true + assertEquals(listOf(true, true), s.followerCalls) + + // One source off is not all sources off: the follower must stay attached. + s.state.trxSynch_ucxLogUDPListenerEnabled = false + assertEquals(listOf(true, true, true), s.followerCalls) + + s.state.logsynch_wintestQrgSyncEnabled = false + assertEquals(listOf(true, true, true, false), s.followerCalls) + } + + @Test + fun `an enabled source alone is never presented as a frequency`() { + // PROJECT_CONTEXT: automatic QRG updates need an enabled source AND valid + // incoming RadioInfo or Win-Test STATUS data. The tab must not let an + // operator read "source on" as "my QRG is being kept current". + val s = Session() + + s.state.trxSynch_ucxLogUDPListenerEnabled = true + + assertTrue(s.state.anyQrgSourceEnabled) + /* + * Read from the translation rather than from a constant beside it: one sentence, one + * place. What this asserts is a content requirement on the English text, which is + * where that text now lives. + */ + val hint = kst4contest.view.i18n.Translations.BY_LANGUAGE + .getValue(kst4contest.view.i18n.Translations.BASE_LANGUAGE) + .getValue(TrxSynchTabState.QRG_SOURCE_HINT_KEY) + assertTrue(hint.contains("valid", ignoreCase = true) && hint.contains("data", ignoreCase = true), + "the hint must say that incoming data is required as well, not just a source: <$hint>") + assertTrue(hint.contains("RadioInfo") && hint.contains("STATUS"), + "naming both sources tells the operator what data he is waiting for: <$hint>") + } + + @Test + fun `no enabled source means no automatic QRG at all`() { + val s = Session() + + /* + * Both sources have to be switched off explicitly: ChatPreferences ships + * logsynch_wintestQrgSyncEnabled = true (ChatPreferences.java:258), so a fresh + * configuration already has one source enabled. + */ + s.state.logsynch_wintestQrgSyncEnabled = false + s.state.trxSynch_ucxLogUDPListenerEnabled = false + + assertFalse(s.state.anyQrgSourceEnabled) + } + + @Test + fun `a fresh configuration already has the Win-Test source enabled`() { + // Pins the shipped default rather than assuming it, which is what made the + // test above wrong on the first attempt. + assertTrue(Session().state.logsynch_wintestQrgSyncEnabled) + assertFalse(Session().state.trxSynch_ucxLogUDPListenerEnabled) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/WorkedDatabaseTabStateTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/WorkedDatabaseTabStateTest.kt new file mode 100644 index 00000000..efa3ca39 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/compose/tabs/WorkedDatabaseTabStateTest.kt @@ -0,0 +1,80 @@ +package kst4contest.view.compose.tabs + +import org.junit.jupiter.api.Test +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue + +class WorkedDatabaseTabStateTest { + + private class Recorder(private val resetResult: Int) { + var resetCalls = 0 + var guiRefreshed = false + var refreshCalls = 0 + val state = WorkedDatabaseTabState( + resetInDatabase = { resetCalls++; resetResult }, + refreshGuiLists = { guiRefreshed = true }, + refreshView = { refreshCalls++ }, + ) + } + + @Test + fun `a reset asks before it touches anything`() { + val r = Recorder(resetResult = 5) + + r.state.requestReset() + + assertTrue(r.state.confirmationPending, + "the JavaFX button showed a confirmation dialog first") + assertEquals(0, r.resetCalls, "nothing may be reset before the operator confirms") + } + + @Test + fun `cancelling a reset changes nothing`() { + val r = Recorder(resetResult = 5) + r.state.requestReset() + + r.state.cancelReset() + + assertFalse(r.state.confirmationPending) + assertEquals(0, r.resetCalls) + assertFalse(r.guiRefreshed) + } + + @Test + fun `confirming resets the database and then the lists, in that order`() { + val r = Recorder(resetResult = 12) + r.state.requestReset() + + r.state.confirmReset() + + assertEquals(1, r.resetCalls) + assertTrue(r.guiRefreshed, "the runtime lists must follow the database") + assertEquals(12, r.state.lastAffectedLines) + assertFalse(r.state.confirmationPending) + } + + @Test + fun `a failed reset reports an error and leaves the lists alone`() { + // resetWorkedDataInDB returns a negative number when it could not confirm a + // reset. The JavaFX handler stopped there and did not touch the GUI lists. + val r = Recorder(resetResult = -1) + r.state.requestReset() + + r.state.confirmReset() + + assertTrue(r.state.resetFailed) + assertFalse(r.guiRefreshed, + "clearing the runtime lists after a failed database reset would show the " + + "operator a state the database does not have") + } + + @Test + fun `refreshing is a plain action`() { + val r = Recorder(resetResult = 0) + + r.state.refresh() + + assertEquals(1, r.refreshCalls) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/feed/ConnectionStateFeedTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/feed/ConnectionStateFeedTest.kt new file mode 100644 index 00000000..6842cf02 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/feed/ConnectionStateFeedTest.kt @@ -0,0 +1,76 @@ +package kst4contest.view.feed + +import kst4contest.controller.On4KstConnectionState +import kst4contest.observe.UiDispatcher +import kst4contest.view.compose.MainWindowSurroundings +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +/** + * What fills the connection indicator in the Compose status bar. + * + * The JavaFX method this came out of did two things in one breath: it wrote the Compose + * state and then touched a JavaFX tooltip. Deleting the construction that creates the + * tooltip would have left live callers running into the second half. + */ +class ConnectionStateFeedTest { + + private class CountingDispatcher : UiDispatcher { + var deliveries = 0 + private set + + override fun runOnUi(task: Runnable) { + deliveries++ + task.run() + } + + override fun isUiThread(): Boolean = true + } + + @Test + fun `the state and its detail reach the status bar`() { + val target = MainWindowSurroundings() + + ConnectionStateFeed(target, CountingDispatcher()) + .push(On4KstConnectionState.ONLINE, "logged in as DN9APW") + + assertEquals(On4KstConnectionState.ONLINE, target.connectionState) + assertEquals("logged in as DN9APW", target.connectionDetail) + } + + /** + * Review Focus 3. The JavaFX method substituted DISCONNECTED for an absent state + * and the state's own name for a blank detail; an operator reading "null" in a + * status bar learns nothing. + */ + @Test + fun `a missing state reads as disconnected`() { + val target = MainWindowSurroundings() + + ConnectionStateFeed(target, CountingDispatcher()).push(null, null) + + assertEquals(On4KstConnectionState.DISCONNECTED, target.connectionState) + assertEquals("DISCONNECTED", target.connectionDetail) + } + + @Test + fun `a blank detail reads as the state itself`() { + val target = MainWindowSurroundings() + + ConnectionStateFeed(target, CountingDispatcher()) + .push(On4KstConnectionState.CONNECTING, " ") + + assertEquals("CONNECTING", target.connectionDetail) + } + + /** Review Focus 2. */ + @Test + fun `one push is one delivery`() { + val dispatcher = CountingDispatcher() + + ConnectionStateFeed(MainWindowSurroundings(), dispatcher) + .push(On4KstConnectionState.ONLINE, "x") + + assertEquals(1, dispatcher.deliveries) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/feed/FeedIsTheOnlyWriterTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/feed/FeedIsTheOnlyWriterTest.kt new file mode 100644 index 00000000..d6109b53 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/feed/FeedIsTheOnlyWriterTest.kt @@ -0,0 +1,192 @@ +package kst4contest.view.feed + +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import java.io.File + +/** + * Nothing outside the feeds writes the Compose state the feeds own. + * + * This exists because of how two bypasses survived a review of my own making. The claim + * "one path writes it now" was checked with `grep getSelectedStationMessages().replaceRows` + * and `grep getSurroundings().setConnection` — greps shaped like the code that had just + * been written, which therefore could not match a call through a local variable. Both + * missed a live second writer. + * + * A source-level assertion is the right instrument for that claim, because the claim is + * about the source and not about a run. It also catches the next bypass, which a + * hand-run grep does not. + * + * The first version of this test repeated the original mistake in a new spelling: it + * matched `selectedStationMessages` case-sensitively, so the accessor spelling with the + * capital S slipped through, and it required `getTimeline()` and the mutator on one + * line, so a two-line write through a local was invisible. Both are closed below. What + * remains uncovered is named in `the residual limit` at the foot of this file — stating + * it is the point, because claiming completeness is what failed the first two times. + */ +class FeedIsTheOnlyWriterTest { + + /** + * Where the feeds themselves and the state declarations live. + * + * These files contain the mutator names legitimately: the feed is the one caller, + * and the state classes declare the methods. Everything else is a bypass. + */ + private val ownedByTheFeeds = listOf( + "/view/feed/", + "/view/compose/TimelineState.kt", + "/view/compose/DataTableState.kt", + "/view/compose/MainWindowState.kt", + ) + + /** Resolves whether the test runs from the module directory or the repository root. */ + private fun sourceRoot(): File = + listOf(File("src/main"), File("app-desktop/src/main")) + .firstOrNull { it.isDirectory } + ?: error("cannot find app-desktop/src/main from ${File(".").absolutePath}") + + /** + * Every live line of the module's main sources, as path, number and text. + * + * The whole tree, not one file: the three states are reachable from the Kotlin in + * this source set too, and a bypass in `MainWindow.kt` would be unscanned otherwise. + */ + private fun sources(): List { + val files = sourceRoot().walkTopDown() + .filter { it.isFile && (it.extension == "java" || it.extension == "kt") } + .filterNot { file -> ownedByTheFeeds.any { file.path.replace('\\', '/').contains(it) } } + .toList() + + assertTrue(files.size > 20) { "only found ${files.size} sources; the scan is not reaching the tree" } + return files + } + + private fun liveLines(): List> { + return sources().flatMap { file -> + file.readLines().mapIndexed { index, line -> Triple(file.name, index + 1, line) } + }.filterNot { (_, _, line) -> + line.trim().startsWith("//") || line.trim().startsWith("*") + } + } + + private fun report(feed: String, offenders: List>) { + assertTrue(offenders.isEmpty()) { + "these write the state directly instead of going through $feed:\n" + + offenders.joinToString("\n") { (file, number, line) -> " $file:$number ${line.trim()}" } + } + } + + /** + * `replaceRows` on the selected-station message table. + * + * The receiver has to be part of the match, because `replaceRows` belongs to seven + * other tables as well — stations, directed, public, cluster and the monitor's two + * fill themselves the same way and are none of this feed's business. Matched on the + * lowercased line so that both the local `selectedStationMessages` and the accessor + * `getSelectedStationMessages()` are caught; the first version matched only the + * local, which is the spelling the bug happened to have. + */ + @Test + fun `only the feed fills the selected-station message table`() { + report("SelectedStationMessagesFeed", liveLines().filter { (_, _, line) -> + val lowered = line.lowercase() + "selectedstationmessages" in lowered && "replacerows" in lowered + }) + } + + /** + * Nobody outside the feed takes a writable handle on that table. + * + * This is what closes the two-line write — `var t = …getSelectedStationMessages();` + * on one line and `t.replaceRows(rows);` on the next, the exact shape that defeated + * the original verification. To write it at all you must first call the accessor, + * and the feed's own construction is the only place that may. + * + * Scanned per statement rather than per line, because that construction spans two + * lines: a line-wise rule reports the feed building itself as its own bypass. + */ + @Test + fun `only the feed takes a handle on that table`() { + report("SelectedStationMessagesFeed", sources().flatMap { file -> + val code = file.readLines() + .map { if (it.trim().startsWith("//") || it.trim().startsWith("*")) "" else it } + var line = 1 + code.joinToString("\n").split(";").mapNotNull { statement -> + val start = line + line += statement.count { it == '\n' } + if ("getSelectedStationMessages()" !in statement || + "SelectedStationMessagesFeed(" in statement + ) { + return@mapNotNull null + } + // Report the line the accessor is actually on, not where its statement + // began: a statement starts after the previous semicolon, which can be + // several lines of unrelated code earlier. + val within = statement.lines().indexOfFirst { "getSelectedStationMessages()" in it } + Triple(file.name, start + within, statement.lines()[within].trim()) + } + }) + } + + /** + * The connection state and its detail belong together. + * + * A writer that sets the state without the detail leaves the badge beside + * "No ON4KST connection" until something else corrects it, which is the stale-pair + * case ConnectionStateFeed exists to end. No receiver is needed in the match: both + * names belong to this state alone, so a two-line write is caught as well. + * + * `.connectionState =` is matched too, because `MainWindowSurroundings` is Kotlin: + * Java call sites spell it `setConnectionState(`, but a Kotlin one would assign the + * property and the setter spelling would never appear. `MainWindowState.kt` itself + * is out of the scan — it declares the property and propagates it to the menu. + * + * The leading dot is required, and is not decoration: without it the rule reports + * `connectionState = state.surroundings.connectionState` in `MainWindow.kt`, which + * is a named argument handing the value to a composable — a read, not a write. + */ + @Test + fun `only the feed fills the connection indicator`() { + report("ConnectionStateFeed", liveLines().filter { (_, _, line) -> + "setConnectionState(" in line || "setConnectionDetail(" in line || + Regex("""\.(connectionState|connectionDetail)\s*=[^=]""").containsMatchIn(line) + }) + } + + /** + * The timeline's four writes are the feed's business for the same reason. + * + * Matched on the mutator names alone — they belong to `TimelineState` and to nothing + * else — so a write through a local is caught too. `setBeamWidth(` is spelled with + * the bracket on purpose: `TimelineView.setBeamWidthDeg` is the JavaFX view's own + * method at `Kst4ContestApplication.java:6942` and is not this state. + */ + @Test + fun `only the feed fills the timeline`() { + report("TimelineFeed", liveLines().filter { (_, _, line) -> + "replaceSkeds(" in line || "replaceCandidates(" in line || + "setAntennaAzimuth" in line || "setBeamWidth(" in line + }) + } + + /** + * The residual limit, stated rather than papered over. + * + * A Kotlin bypass could reach the message table as `state.selectedStationMessages` + * without the accessor, and split over two lines it would pass every rule above. + * Nothing does that today — `MainWindow.kt` only hands the table to the composable + * that renders it — and closing it would mean forbidding that read as well. If a + * Kotlin writer ever appears, this is the test that has to grow, not the place to + * conclude that none can exist. + */ + @Test + fun `the residual limit is the Kotlin property path`() { + val kotlinReads = liveLines().filter { (file, _, line) -> + file.endsWith(".kt") && "selectedStationMessages" in line + } + + kotlinReads.forEach { (file, number, line) -> + assertTrue("replaceRows" !in line) { "$file:$number writes the table from Kotlin: ${line.trim()}" } + } + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/feed/FeedLifetimeIsTiedToTheWindowTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/feed/FeedLifetimeIsTiedToTheWindowTest.kt new file mode 100644 index 00000000..947a3700 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/feed/FeedLifetimeIsTiedToTheWindowTest.kt @@ -0,0 +1,81 @@ +package kst4contest.view.feed + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import java.io.File + +/** + * The feeds are built where the Compose window's state is built, and nowhere else. + * + * This is the executable half of a warning that part 3 would otherwise have to read and + * believe. All three feeds are constructed inside the method that also constructs + * `composeMainWindowState`, which today is reached from `start()`. Part 3 removes + * `start()` piece by piece; if it follows the warning's table faithfully and rehomes the + * four timeline triggers, the constructions still go with the rest of `start()` and all + * three feeds stay null — a silently empty timeline, message table and connection badge, + * with no compile error and no failing test to show for it. + * + * Asserting "same method as the Compose state" rather than "not inside `start()`" is + * what makes it structural: part 3 cannot drop the feed construction without dropping + * the window's own state, which it will never do, because that is the window. It also + * survives the line numbers moving, which a range check against `start()` would not. + * + * This says nothing about who writes the states once they exist — that is + * `FeedIsTheOnlyWriterTest`, and the two together are the whole claim. + */ +class FeedLifetimeIsTiedToTheWindowTest { + + private val source: File + get() = listOf( + File("src/main/java/kst4contest/view/Kst4ContestApplication.java"), + File("app-desktop/src/main/java/kst4contest/view/Kst4ContestApplication.java"), + ).firstOrNull { it.isFile } ?: error("cannot find Kst4ContestApplication.java from ${File(".").absolutePath}") + + /** A method declaration at class level; the body ends at the matching outdented brace. */ + private val declaration = Regex( + """^\t(?:(?:public|private|protected|static|final|synchronized|abstract)\s+)+""" + + """[\w<>,\[\]. ]+\s+(\w+)\s*\(""" + ) + + /** The name of the method whose body contains [line], or null at class level. */ + private fun methodAt(lines: List, line: Int): String? { + var name: String? = null + for (index in 0 until line) { + val text = lines[index] + declaration.find(text)?.let { name = it.groupValues[1] } + if (text.startsWith("\t}")) name = null + } + return name + } + + @Test + fun `every feed is constructed where the Compose window state is`() { + val lines = source.readLines() + val live = lines.withIndex().filterNot { (_, text) -> + text.trim().startsWith("//") || text.trim().startsWith("*") + } + + val stateAt = live.filter { "composeMainWindowState = new MainWindowState(" in it.value } + assertEquals(1, stateAt.size) { + "expected exactly one construction of the Compose window state, found ${stateAt.size}" + } + val home = methodAt(lines, stateAt.single().index) + assertTrue(home != null) { "the Compose window state is built outside any method body" } + + val feeds = live.filter { Regex("""\b\w*[Ff]eed = new\b""").containsMatchIn(it.value) } + assertEquals(3, feeds.size) { + "expected three feed constructions, found ${feeds.size}:\n" + + feeds.joinToString("\n") { " :${it.index + 1} ${it.value.trim()}" } + } + + val strays = feeds.filter { methodAt(lines, it.index) != home } + assertTrue(strays.isEmpty()) { + "these feeds are built outside $home, where composeMainWindowState is built, " + + "so removing start() can leave them null:\n" + + strays.joinToString("\n") { feed -> + " :${feed.index + 1} in ${methodAt(lines, feed.index)} — ${feed.value.trim()}" + } + } + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/feed/SelectedStationMessagesFeedTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/feed/SelectedStationMessagesFeedTest.kt new file mode 100644 index 00000000..9dd8b38b --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/feed/SelectedStationMessagesFeedTest.kt @@ -0,0 +1,76 @@ +package kst4contest.view.feed + +import kst4contest.model.ChatMessage +import kst4contest.observe.UiDispatcher +import kst4contest.view.compose.DataTableState +import kst4contest.view.compose.RowKeys +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test + +/** + * What fills the "messages of the selected station" table. + * + * Found the hard way: this feed was buried two hundred lines inside a JavaFX table + * builder, so "who calls that builder" answered a different question than "is it safe + * to delete". A feed with its own name and its own test cannot be lost that way. + */ +class SelectedStationMessagesFeedTest { + + private class CountingDispatcher : UiDispatcher { + var deliveries = 0 + private set + + override fun runOnUi(task: Runnable) { + deliveries++ + task.run() + } + + override fun isUiThread(): Boolean = true + } + + private fun emptyTable() = + DataTableState(emptyList(), RowKeys.byReference(), "test") + + @Test + fun `the messages it is given reach the table`() { + val target = emptyTable() + + SelectedStationMessagesFeed(target, CountingDispatcher()).push(listOf(ChatMessage())) + + assertEquals(1, target.rows.size) + } + + /** Review Focus 2. */ + @Test + fun `one push is one delivery`() { + val dispatcher = CountingDispatcher() + + SelectedStationMessagesFeed(emptyTable(), dispatcher).push(listOf(ChatMessage())) + + assertEquals(1, dispatcher.deliveries) + } + + /** Review Focus 3: no station selected is the state the window opens in. */ + @Test + fun `an empty push clears the table rather than failing`() { + val target = emptyTable() + val feed = SelectedStationMessagesFeed(target, CountingDispatcher()) + + feed.push(listOf(ChatMessage())) + feed.push(emptyList()) + + assertEquals(0, target.rows.size) + } + + /** The caller hands over a live mirror; the table must not follow it. */ + @Test + fun `the table keeps its own copy`() { + val target = emptyTable() + val source = mutableListOf(ChatMessage()) + + SelectedStationMessagesFeed(target, CountingDispatcher()).push(source) + source.clear() + + assertEquals(1, target.rows.size, "the table followed the caller's list") + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/feed/TimelineFeedTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/feed/TimelineFeedTest.kt new file mode 100644 index 00000000..579f641b --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/feed/TimelineFeedTest.kt @@ -0,0 +1,88 @@ +package kst4contest.view.feed + +import kst4contest.observe.UiDispatcher +import kst4contest.view.compose.TimelineState +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * What fills the timeline above the send field. + * + * It has its own class because of how it was found: the feed sat in a method guarded by + * a JavaFX field, inside window construction that is never shown, and deleting that + * construction would have emptied the Compose timeline with a green build and no + * compile error. A feed that can be constructed in a test cannot hide like that. + */ +class TimelineFeedTest { + + /** Runs inline and counts, so a test can tell "delivered" from "delivered twice". */ + private class CountingDispatcher(private val uiThread: Boolean = true) : UiDispatcher { + var deliveries = 0 + private set + + override fun runOnUi(task: Runnable) { + deliveries++ + task.run() + } + + override fun isUiThread(): Boolean = uiThread + } + + private fun sked(call: String) = + kst4contest.model.ContestSked(call, 90.0, 60_000L, kst4contest.model.Band.B_144) + + @Test + fun `it puts what it is given into the timeline`() { + val target = TimelineState() + + TimelineFeed(target, CountingDispatcher()).push(listOf(sked("DL1ABC")), emptyList(), 229.0, 60.0) + + assertEquals(1, target.skeds.size) + assertEquals(229.0, target.antennaAzimuth, 1e-9) + assertEquals(60.0, target.beamWidthDeg, 1e-9) + } + + /** Review Focus 2: two feeds writing one state is invisible until one goes stale. */ + @Test + fun `one push is one delivery`() { + val dispatcher = CountingDispatcher() + + TimelineFeed(TimelineState(), dispatcher).push(emptyList(), emptyList(), 0.0, 0.0) + + assertEquals(1, dispatcher.deliveries) + } + + /** Review Focus 4: the controller's listeners fire on network threads. */ + @Test + fun `it hands over rather than writing from the calling thread`() { + val dispatcher = CountingDispatcher(uiThread = false) + + TimelineFeed(TimelineState(), dispatcher).push(emptyList(), emptyList(), 10.0, 5.0) + + assertTrue(dispatcher.deliveries > 0) { "the feed wrote without going through the dispatcher" } + } + + /** Review Focus 3: empty is the normal state before the first score run. */ + @Test + fun `an empty push is not an error`() { + val target = TimelineState() + + TimelineFeed(target, CountingDispatcher()).push(emptyList(), emptyList(), 0.0, 0.0) + + assertEquals(0, target.skeds.size) + assertEquals(0, target.candidates.size) + } + + /** The caller hands over snapshots of state that keeps changing. */ + @Test + fun `the timeline keeps its own copy`() { + val target = TimelineState() + val source = mutableListOf(sked("DL1ABC")) + + TimelineFeed(target, CountingDispatcher()).push(source, emptyList(), 0.0, 0.0) + source.clear() + + assertEquals(1, target.skeds.size, "the timeline followed the caller's list") + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/i18n/LanguageStoreTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/i18n/LanguageStoreTest.kt new file mode 100644 index 00000000..f2ca4f42 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/i18n/LanguageStoreTest.kt @@ -0,0 +1,140 @@ +package kst4contest.view.i18n + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNotEquals +import org.junit.jupiter.api.Test +import java.util.Locale + +/** + * The store, and the two ways out of it. + * + * Built over two lambdas rather than over ChatPreferences, so none of this touches the + * operator's home directory: that constructor copies resources into it. + */ +class LanguageStoreTest { + + private var stored: String = SYSTEM_LANGUAGE + + private fun store(systemDefault: Locale = Locale.UK) = LanguageStore( + storedLanguage = { stored }, + storeLanguage = { stored = it }, + systemDefault = systemDefault, + ) + + @Test + fun theStoredLanguageIsInForceFromTheStart() { + stored = "de" + + assertEquals("de", store().language) + } + + @Test + fun anEmptySettingFollowsTheSystem() { + stored = SYSTEM_LANGUAGE + + assertEquals("de", store(Locale.GERMANY).language) + } + + @Test + fun choosingALanguageWritesItThroughAndChangesTheTexts() { + val store = store() + val englishSave = store.strings.settingsSave + + store.use("de") + + assertEquals("de", store.language) + assertEquals("de", stored) + assertNotEquals(englishSave, store.strings.settingsSave) + assertEquals("Einstellungen speichern", store.strings.settingsSave) + } + + @Test + fun theStoredChoiceIsReadableAndIsNotTheResolvedCode() { + /* + * The picker shows what was chosen, not what it resolved to: an operator who picked + * "system language" must keep seeing that and not "EN". One source of truth, so a + * caller never has to decide whether to ask the store or the preference. + */ + stored = SYSTEM_LANGUAGE + val store = store(Locale.UK) + + assertEquals(SYSTEM_LANGUAGE, store.stored) + assertEquals("en", store.language) + + store.use("de") + + assertEquals("de", store.stored) + assertEquals("de", store.language) + } + + @Test + fun aLanguageThisBuildDoesNotCarryIsRefusedRatherThanStored() { + /* + * The picker cannot offer one, but a hand-edited preferences file can name one, and + * so can a build that dropped a language. Storing it would persist a dead setting. + */ + val store = store() + + store.use("klingon") + + assertEquals("en", store.language) + assertEquals(SYSTEM_LANGUAGE, stored, "a language with no texts was stored") + } + + @Test + fun choosingTheSystemLanguageIsStoredAsTheSystemLanguage() { + // Not as the code it resolves to: the operator asked to follow the system, and a + // system they later change must still be followed. + stored = "de" + val store = store(Locale.UK) + + store.use(SYSTEM_LANGUAGE) + + assertEquals("en", store.language) + assertEquals(SYSTEM_LANGUAGE, stored) + } + + @Test + fun aKeyOnlyTheBaseHasComesBackInTheBaseLanguage() { + /* + * The fallback the whole contribution workflow depends on, and it cannot be tested + * through German: German is a shipped language and the boundary test holds it + * complete, so no key is ever missing from it. Built from maps instead, and read + * through real generated members so the test goes the same way a window does. + */ + val base = mapOf( + "settings.save" to "Save settings", + "menu.file" to "File", + ) + val partial = mapOf("menu.file" to "Datei") + + val strings = Strings { key -> partial[key] ?: base[key] ?: key } + + assertEquals("Save settings", strings.settingsSave, "the base text did not come through") + assertEquals("Datei", strings.menuFile, "the translation did not win") + } + + @Test + fun theJavaBridgeSeesWhatTheStoreSees() { + val store = store() + + store.use("de") + + assertEquals(store.strings.settingsSave, CurrentStrings.get().settingsSave) + } + + @Test + fun aPlaceholderTextIsFormattedInTheChosenLanguagesOwnWordOrder() { + /* + * The reason MessageFormat is here rather than concatenation: in German the argument + * comes first, which no amount of "Connect to " + x can produce. + */ + val store = store() + + assertEquals("Connect to 144 MHz", store.strings.connectionConnectTo("144 MHz")) + + store.use("de") + + assertEquals("Mit 144 MHz verbinden", store.strings.connectionConnectTo("144 MHz")) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/i18n/LocaleChoiceTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/i18n/LocaleChoiceTest.kt new file mode 100644 index 00000000..019b8355 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/i18n/LocaleChoiceTest.kt @@ -0,0 +1,54 @@ +package kst4contest.view.i18n + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import java.util.Locale + +/** + * Which language a stored setting and a system default add up to. + * + * A pure function on purpose: the alternative is a test that changes the JVM's default locale, + * which is global state and leaks into whatever runs next. + */ +class LocaleChoiceTest { + + @Test + fun anEmptySettingFollowsTheSystem() { + assertEquals("de", languageFor(SYSTEM_LANGUAGE, Locale.GERMANY)) + assertEquals("en", languageFor(SYSTEM_LANGUAGE, Locale.UK)) + } + + @Test + fun aSystemLanguageNobodyTranslatedFallsBackToEnglish() { + // The spec's rule: default from the system language, falling back to English. + assertEquals("en", languageFor(SYSTEM_LANGUAGE, Locale.FRANCE)) + assertEquals("en", languageFor(SYSTEM_LANGUAGE, Locale.JAPAN)) + } + + @Test + fun anExplicitChoiceBeatsTheSystem() { + assertEquals("de", languageFor("de", Locale.UK)) + assertEquals("en", languageFor("en", Locale.GERMANY)) + } + + @Test + fun nonsenseInTheSettingFallsBackToEnglishRatherThanFailing() { + /* + * The stored value can be hand-edited in the preferences XML, or left over from a + * build that carried a language this one does not. + */ + assertEquals("en", languageFor("klingon", Locale.GERMANY)) + assertEquals("en", languageFor("de_DE_x", Locale.GERMANY)) + assertEquals("en", languageFor(null, Locale.UK)) + } + + @Test + fun theSettingIsCaseInsensitiveBecauseAHandEditedFileMayShout() { + assertEquals("de", languageFor("DE", Locale.UK)) + } + + @Test + fun surroundingSpaceInAHandEditedSettingIsIgnored() { + assertEquals("de", languageFor(" de ", Locale.UK)) + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/i18n/StringsReachTheCompositionTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/i18n/StringsReachTheCompositionTest.kt new file mode 100644 index 00000000..70444522 --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/i18n/StringsReachTheCompositionTest.kt @@ -0,0 +1,75 @@ +package kst4contest.view.i18n + +import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.ui.test.ExperimentalTestApi +import androidx.compose.ui.test.runComposeUiTest +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import java.util.Locale + +/** + * A language change reaches a composed window without anything else happening. + * + * The one mechanism the acceptance criterion hangs on, and the one a state-level test cannot + * see: the store is always right, the question is whether the composition asks it again. + * Etappe 8 shipped exactly this fault for the palette, and found it with a test shaped like + * this one. + * + * Headless: no window is opened, only a composition. + */ +class StringsReachTheCompositionTest { + + @OptIn(ExperimentalTestApi::class) + @Test + fun aLanguageChosenAfterTheFirstDrawReachesTheComposition() = runComposeUiTest { + var stored = SYSTEM_LANGUAGE + val store = LanguageStore( + storedLanguage = { stored }, + storeLanguage = { stored = it }, + systemDefault = Locale.UK, + ) + val seen = mutableListOf() + + setContent { + /* + * store.strings is read INSIDE the composition, which is what makes the state + * read belong to it. Reading it outside and passing the result in would hand the + * composition a value that never changes again -- the remember(darkMode) fault. + */ + CompositionLocalProvider(LocalStrings provides store.strings) { + seen += LocalStrings.current.settingsSave + } + } + + waitForIdle() + val firstDraw = seen.last() + + store.use("de") + waitForIdle() + + assertEquals("Save settings", firstDraw, "the first draw was not the base language") + assertEquals( + "Einstellungen speichern", + seen.last(), + "the composition still holds the texts from before the change", + ) + } + + @OptIn(ExperimentalTestApi::class) + @Test + fun withoutAStoreTheBaseLanguageIsStillDrawn() { + /* + * Not caution: the operator profile picker composes before a profile, and therefore + * before a store, exists. It must still have texts. + */ + runComposeUiTest { + var seen: String? = null + + setContent { seen = LocalStrings.current.settingsSave } + + waitForIdle() + + assertEquals("Save settings", seen) + } + } +} diff --git a/app-desktop/src/test/kotlin/kst4contest/view/i18n/TranslationBoundaryTest.kt b/app-desktop/src/test/kotlin/kst4contest/view/i18n/TranslationBoundaryTest.kt new file mode 100644 index 00000000..b134bfef --- /dev/null +++ b/app-desktop/src/test/kotlin/kst4contest/view/i18n/TranslationBoundaryTest.kt @@ -0,0 +1,122 @@ +package kst4contest.view.i18n + +import kst4contest.model.ChatPreferences +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import java.lang.reflect.Modifier + +/** + * Nothing that goes to the server or to another radio amateur has got into the texts. + * + * The third of the three boundary checks, and the one that catches the follow-up work: the + * remaining ~380 strings get pulled into these files over time, and a beacon template or a + * `/CQ` sitting among them would be translated by the next contributor in good faith. + * + * German is held complete here because it is a shipped language. A contributed language is + * deliberately not: a partial file is the normal state of a contribution in progress, and a + * check over every language would turn the arrival of one into a red build. + */ +class TranslationBoundaryTest { + + private val everyText: List = + Translations.BY_LANGUAGE.values.flatMap { it.values } + + @Test + fun thereAreTextsToCheckAtAll() { + /* + * Without this, every assertion below would pass over an empty list -- the shape of a + * boundary check that guards nothing. + */ + assertTrue(everyText.size >= 16, "only ${everyText.size} texts were found") + } + + @Test + fun noTextIsAProtocolFrameOrAChatCommand() { + /* + * Deliberately conservative, and the reason is worth stating: a pattern cannot tell a + * protocol command from an interface label that names one. "Update MYQRG from + * RadioInfo messages" is a setting's description, and its German translation even + * begins with that word, because that is where German puts it. A check for "contains" + * or "starts with" fails both and teaches the next person to delete the test. + * + * So only the unambiguous shapes are checked: a text that IS a token, a wire frame + * (an opcode followed by its pipe), and anything beginning with a slash. The real + * guarantees are the other two boundary tests, which measure behaviour rather than + * text -- the frames built under three locales, and every preference default by + * reflection. + */ + val opcodes = listOf("LOGINC", "SDONE", "ACHAT", "DXQ", "SETNAME", "MYQRG") + + for (text in everyText) { + assertTrue( + opcodes.none { text == it || text.startsWith("$it|") }, + "'$text' is a protocol token or a wire frame; that text goes to the ON4KST " + + "server and must not be in a translation file", + ) + assertTrue( + !text.trimStart().startsWith("/"), + "'$text' looks like a chat command; those go to the server as a message", + ) + } + } + + @Test + fun noTextIsOneOfThePreferenceDefaultsThatGoToOtherRadioAmateurs() { + val prefs = ChatPreferences() + + val defaults = ChatPreferences::class.java.declaredFields + .filter { it.type == String::class.java && !Modifier.isStatic(it.modifiers) } + .mapNotNull { field -> + field.isAccessible = true + (field.get(prefs) as String?)?.takeIf { it.isNotBlank() } + } + .toSet() + + assertTrue(defaults.size >= 10, "only ${defaults.size} defaults were found to check against") + + for (text in everyText) { + assertTrue( + text !in defaults, + "'$text' is a ChatPreferences default; it goes to other radio amateurs and is " + + "in every operator's stored XML", + ) + } + } + + @Test + fun germanIsCompleteBecauseItIsAShippedLanguage() { + val base = Translations.BY_LANGUAGE.getValue(Translations.BASE_LANGUAGE).keys + val german = Translations.BY_LANGUAGE.getValue("de").keys + + assertEquals( + emptySet(), + base - german, + "German is shipped, so a gap in it is a defect and not a contribution in progress", + ) + } + + @Test + fun onlyTheShippedLanguagesAreHeldToCompleteness() { + /* + * The counterpart of the test above, and a real assertion rather than a note: a + * language this build carries beyond the shipped two must be free to be partial. The + * check is on the rule itself -- exactly two languages are held complete -- so adding + * strings_fr.properties with ten keys cannot turn the build red, and removing German + * from the held set cannot pass unnoticed either. + */ + val held = setOf(Translations.BASE_LANGUAGE, "de") + + assertEquals(setOf("en", "de"), held, "the set of shipped languages changed") + + val base = Translations.BY_LANGUAGE.getValue(Translations.BASE_LANGUAGE).keys + val partialLanguages = Translations.BY_LANGUAGE + .filterKeys { it !in held } + .filterValues { (base - it.keys).isNotEmpty() } + + assertTrue( + partialLanguages.keys.none { it in held }, + "a shipped language turned up among the partial ones: ${partialLanguages.keys}", + ) + } +} diff --git a/app-desktop/src/test/resources/javafx-derive-reference.txt b/app-desktop/src/test/resources/javafx-derive-reference.txt new file mode 100644 index 00000000..152bf927 --- /dev/null +++ b/app-desktop/src/test/resources/javafx-derive-reference.txt @@ -0,0 +1,223 @@ +# Generated from com.sun.javafx.util.Utils.deriveColor by +# JavaFxStylesheetTest.`generate the JavaFX reference data`. +# Format: ;; +#ffffff;-80.0;#333333 +#ffffff;-50.0;#808080 +#ffffff;-35.0;#A6A6A6 +#ffffff;-30.0;#B3B3B3 +#ffffff;-10.0;#E6E6E6 +#ffffff;10.0;#FFFFFF +#ffffff;26.4;#FFFFFF +#ffffff;35.0;#FFFFFF +#ffffff;50.0;#FFFFFF +#ffffff;80.0;#FFFFFF +#000000;-80.0;#000000 +#000000;-50.0;#000000 +#000000;-35.0;#000000 +#000000;-30.0;#000000 +#000000;-10.0;#000000 +#000000;10.0;#0F0F0F +#000000;26.4;#282828 +#000000;35.0;#363636 +#000000;50.0;#4D4D4D +#000000;80.0;#7A7A7A +#ececec;-80.0;#2F2F2F +#ececec;-50.0;#767676 +#ececec;-35.0;#999999 +#ececec;-30.0;#A5A5A5 +#ececec;-10.0;#D4D4D4 +#ececec;10.0;#EFEFEF +#ececec;26.4;#F4F4F4 +#ececec;35.0;#F7F7F7 +#ececec;50.0;#FBFBFB +#ececec;80.0;#FFFFFF +#373e43;-80.0;#0B0C0D +#373e43;-50.0;#1C1F22 +#373e43;-35.0;#24282C +#373e43;-30.0;#272B2F +#373e43;-10.0;#32383C +#373e43;10.0;#41494E +#373e43;26.4;#525B61 +#373e43;35.0;#5B646A +#373e43;50.0;#6C757B +#373e43;80.0;#8F979D +#1d1d1d;-80.0;#0F0F0F +#1d1d1d;-50.0;#141414 +#1d1d1d;-35.0;#171717 +#1d1d1d;-30.0;#181818 +#1d1d1d;-10.0;#1B1B1B +#1d1d1d;10.0;#2B2B2B +#1d1d1d;26.4;#414141 +#1d1d1d;35.0;#4C4C4C +#1d1d1d;50.0;#616161 +#1d1d1d;80.0;#898989 +#4da6ff;-80.0;#0F2233 +#4da6ff;-50.0;#275480 +#4da6ff;-35.0;#326EA6 +#4da6ff;-30.0;#3676B3 +#4da6ff;-10.0;#4598E6 +#4da6ff;10.0;#5DB1FF +#4da6ff;26.4;#77BDFF +#4da6ff;35.0;#85C4FF +#4da6ff;50.0;#9DD0FF +#4da6ff;80.0;#CDE7FF +#2b2b2b;-80.0;#161616 +#2b2b2b;-50.0;#1E1E1E +#2b2b2b;-35.0;#222222 +#2b2b2b;-30.0;#232323 +#2b2b2b;-10.0;#282828 +#2b2b2b;10.0;#383838 +#2b2b2b;26.4;#4D4D4D +#2b2b2b;35.0;#585858 +#2b2b2b;50.0;#6B6B6B +#2b2b2b;80.0;#919191 +#808080;-80.0;#1A1A1A +#808080;-50.0;#404040 +#808080;-35.0;#535353 +#808080;-30.0;#5A5A5A +#808080;-10.0;#737373 +#808080;10.0;#8B8B8B +#808080;26.4;#9E9E9E +#808080;35.0;#A8A8A8 +#808080;50.0;#B9B9B9 +#808080;80.0;#DBDBDB +#333333;-80.0;#0A0A0A +#333333;-50.0;#1A1A1A +#333333;-35.0;#212121 +#333333;-30.0;#242424 +#333333;-10.0;#2E2E2E +#333333;10.0;#3F3F3F +#333333;26.4;#535353 +#333333;35.0;#5E5E5E +#333333;50.0;#707070 +#333333;80.0;#959595 +#4d4d4d;-80.0;#0F0F0F +#4d4d4d;-50.0;#272727 +#4d4d4d;-35.0;#323232 +#4d4d4d;-30.0;#363636 +#4d4d4d;-10.0;#454545 +#4d4d4d;10.0;#595959 +#4d4d4d;26.4;#6E6E6E +#4d4d4d;35.0;#797979 +#4d4d4d;50.0;#8B8B8B +#4d4d4d;80.0;#B1B1B1 +#666666;-80.0;#141414 +#666666;-50.0;#333333 +#666666;-35.0;#424242 +#666666;-30.0;#474747 +#666666;-10.0;#5C5C5C +#666666;10.0;#727272 +#666666;26.4;#868686 +#666666;35.0;#919191 +#666666;50.0;#A3A3A3 +#666666;80.0;#C8C8C8 +#999999;-80.0;#1F1F1F +#999999;-50.0;#4D4D4D +#999999;-35.0;#636363 +#999999;-30.0;#6B6B6B +#999999;-10.0;#8A8A8A +#999999;10.0;#A3A3A3 +#999999;26.4;#B4B4B4 +#999999;35.0;#BDBDBD +#999999;50.0;#CCCCCC +#999999;80.0;#EBEBEB +#d9d9d9;-80.0;#2B2B2B +#d9d9d9;-50.0;#6D6D6D +#d9d9d9;-35.0;#8D8D8D +#d9d9d9;-30.0;#989898 +#d9d9d9;-10.0;#C3C3C3 +#d9d9d9;10.0;#DFDFDF +#d9d9d9;26.4;#E9E9E9 +#d9d9d9;35.0;#EEEEEE +#d9d9d9;50.0;#F7F7F7 +#d9d9d9;80.0;#FFFFFF +#f4f4f4;-80.0;#313131 +#f4f4f4;-50.0;#7A7A7A +#f4f4f4;-35.0;#9F9F9F +#f4f4f4;-30.0;#ABABAB +#f4f4f4;-10.0;#DCDCDC +#f4f4f4;10.0;#F6F6F6 +#f4f4f4;26.4;#F9F9F9 +#f4f4f4;35.0;#FAFAFA +#f4f4f4;50.0;#FDFDFD +#f4f4f4;80.0;#FFFFFF +#63067a;-80.0;#33033F +#63067a;-50.0;#450455 +#63067a;-35.0;#4E0560 +#63067a;-30.0;#510564 +#63067a;-10.0;#5D0673 +#63067a;10.0;#6B0E82 +#63067a;26.4;#781D8F +#63067a;35.0;#7F2596 +#63067a;50.0;#8C36A2 +#63067a;80.0;#A75EBA +#ff9900;-80.0;#331F00 +#ff9900;-50.0;#804D00 +#ff9900;-35.0;#A66300 +#ff9900;-30.0;#B36B00 +#ff9900;-10.0;#E68A00 +#ff9900;10.0;#FFA31A +#ff9900;26.4;#FFB443 +#ff9900;35.0;#FFBD59 +#ff9900;50.0;#FFCC80 +#ff9900;80.0;#FFEBCC +#e0e0e0;-80.0;#2D2D2D +#e0e0e0;-50.0;#707070 +#e0e0e0;-35.0;#929292 +#e0e0e0;-30.0;#9D9D9D +#e0e0e0;-10.0;#CACACA +#e0e0e0;10.0;#E5E5E5 +#e0e0e0;26.4;#EDEDED +#e0e0e0;35.0;#F1F1F1 +#e0e0e0;50.0;#F9F9F9 +#e0e0e0;80.0;#FFFFFF +#eeeeee;-80.0;#303030 +#eeeeee;-50.0;#777777 +#eeeeee;-35.0;#9B9B9B +#eeeeee;-30.0;#A7A7A7 +#eeeeee;-10.0;#D6D6D6 +#eeeeee;10.0;#F1F1F1 +#eeeeee;26.4;#F5F5F5 +#eeeeee;35.0;#F8F8F8 +#eeeeee;50.0;#FCFCFC +#eeeeee;80.0;#FFFFFF +#606060;-80.0;#131313 +#606060;-50.0;#303030 +#606060;-35.0;#3E3E3E +#606060;-30.0;#434343 +#606060;-10.0;#565656 +#606060;10.0;#6B6B6B +#606060;26.4;#7D7D7D +#606060;35.0;#878787 +#606060;50.0;#989898 +#606060;80.0;#B9B9B9 +#5a5a5a;-80.0;#121212 +#5a5a5a;-50.0;#2D2D2D +#5a5a5a;-35.0;#3B3B3B +#5a5a5a;-30.0;#3F3F3F +#5a5a5a;-10.0;#515151 +#5a5a5a;10.0;#666666 +#5a5a5a;26.4;#787878 +#5a5a5a;35.0;#828282 +#5a5a5a;50.0;#949494 +#5a5a5a;80.0;#B6B6B6 +#707070;-80.0;#161616 +#707070;-50.0;#383838 +#707070;-35.0;#494949 +#707070;-30.0;#4E4E4E +#707070;-10.0;#656565 +#707070;10.0;#7B7B7B +#707070;26.4;#8E8E8E +#707070;35.0;#989898 +#707070;50.0;#A9A9A9 +#707070;80.0;#CCCCCC +#454545;-80.0;#0E0E0E +#454545;-50.0;#232323 +#454545;-35.0;#2D2D2D +#454545;-30.0;#303030 +#454545;-10.0;#3E3E3E +#454545;10.0;#505050 +#454545;26.4;#626262 +#454545;35.0;#6C6C6C +#454545;50.0;#7D7D7D +#454545;80.0;#9E9E9E diff --git a/app-desktop/src/test/resources/settings-fields.txt b/app-desktop/src/test/resources/settings-fields.txt new file mode 100644 index 00000000..8f57ac5a --- /dev/null +++ b/app-desktop/src/test/resources/settings-fields.txt @@ -0,0 +1,72 @@ +setAirScout_asBandString +setAirScout_asClientNameString +setAirScout_asCommunicationPort +setAirScout_asServerNameString +setAirScout_asUDPListenerEnabled +setAirScout_autoBandSelectionEnabled +setBcn_beaconsEnabledMainCat +setBcn_beaconsEnabledSecondCat +setGUI_darkModeActiveByDefault +setGuiOptions_defaultFilterNothing +setGuiOptions_defaultFilterPmToMe +setGuiOptions_defaultFilterPmToOther +setGuiOptions_defaultFilterPublicMsgs +setGuiOptions_showFreshCallHintInBandColumns +setGuiOptions_showGrossFieldWorkedHintInBandColumns +setLoginChatCategoryMain +setLoginChatCategorySecond +setLoginToSecondChatEnabled +setLogsynch_fileBasedWkdCallInterpreterEnabled +setLogsynch_fileBasedWkdCallInterpreterFileNameReadOnly +setLogsynch_ucxUDPWkdCallListenerEnabled +setLogsynch_ucxUDPWkdCallListenerPort +setLogsynch_wintestNetworkBroadcastAddress +setLogsynch_wintestNetworkListenerEnabled +setLogsynch_wintestNetworkPort +setLogsynch_wintestNetworkStationNameOfKST +setLogsynch_wintestNetworkStationNameOfWintestClient1 +setLogsynch_wintestQrgSyncEnabled +setLogsynch_wintestUsePassQrg +setMessageHandling_autoAnswerEnabled +setMessageHandling_autoAnswerEnabledSecondCat +setMessageHandling_autoAnswerTextMainCat +setMessageHandling_autoAnswerTextSecondCat +setMessageHandling_autoAnswerToQRGRequestEnabled +setNotify_bandUpgradeHintOnLogEnabled +setNotify_bandUpgradePriorityBoostEnabled +setNotify_dxClusterServerEnabled +setNotify_dxclusterServerPort +setNotify_DXCSrv_SpottersCallSign +setNotify_optionalFrequencyPrefix +setNotify_playCWCallsignsOnRxedPMs +setNotify_playSimpleSounds +setNotify_playVoiceCallsignsOnRxedPMs +setStn_antennaBeamWidthDeg +setStn_bandActive10G +setStn_bandActive1240 +setStn_bandActive144 +setStn_bandActive2300 +setStn_bandActive3400 +setStn_bandActive432 +setStn_bandActive50 +setStn_bandActive5600 +setStn_bandActive70 +setStn_loginCallSign +setStn_loginLocatorMainCat +setStn_loginNameMainCat +setStn_loginNameSecondCat +setStn_loginPassword +setStn_maxQRBDefault +setStn_on4kstServersDns +setStn_on4kstServersPort +setStn_pathAnalysisDefaultTargetAntennaGainDbi +setStn_pathAnalysisDefaultTargetTxPowerWatts +setStn_pathAnalysisDemRootDirectory +setStn_pathAnalysisOwnAntennaGainDbi +setStn_pathAnalysisOwnAntennaHeightMeters +setStn_pathAnalysisOwnTxPowerWatts +setStn_pstRotatorEnabled +setStn_pstRotatorHost +setStn_pstRotatorPort +setStn_qtfDefault +setTrxSynch_ucxLogUDPListenerEnabled diff --git a/app-desktop/src/test/resources/settings-foreign-writes.txt b/app-desktop/src/test/resources/settings-foreign-writes.txt new file mode 100644 index 00000000..898ff93d --- /dev/null +++ b/app-desktop/src/test/resources/settings-foreign-writes.txt @@ -0,0 +1,5 @@ +setCallSign +setChatCategoryMain +setChatCategorySecondChat +setFrequency +setQra diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 00000000..d4e76fa5 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,48 @@ +plugins { + java + alias(libs.plugins.spotbugs) apply false +} + +allprojects { + group = providers.gradleProperty("group").get() + version = providers.gradleProperty("version").get() + + repositories { + mavenCentral() + // Compose Multiplatform pulls its androidx.lifecycle and androidx.annotation + // artifacts from Google's repository; they are not on Maven Central. + google() + } +} + +val pmdVersion = libs.versions.pmd.get() +val spotbugsVersion = libs.versions.spotbugs.get() + +subprojects { + apply(plugin = "java") + apply(plugin = "com.github.spotbugs") + apply(plugin = "pmd") + + // Both tools report only; the Maven build had the failing goals commented out. + extensions.configure { + toolVersion = pmdVersion + ruleSetFiles = files(rootProject.file("pmd-ruleset.xml")) + ruleSets = emptyList() + isIgnoreFailures = true + } + + extensions.configure { + toolVersion.set(spotbugsVersion) + ignoreFailures.set(true) + } + + extensions.configure { + toolchain { + languageVersion.set(JavaLanguageVersion.of(21)) + } + } + + tasks.withType().configureEach { + useJUnitPlatform() + } +} diff --git a/core/build.gradle.kts b/core/build.gradle.kts new file mode 100644 index 00000000..180bd184 --- /dev/null +++ b/core/build.gradle.kts @@ -0,0 +1,21 @@ +plugins { + java +} + +// No user-interface technology here: the domain layer observes through +// kst4contest.observe and hands UI work over via UiDispatcher. + +dependencies { + // Test classes live under src/main/java in this project, so JUnit and Mockito + // are needed on the main compile classpath. This mirrored pom.xml before Gradle. + implementation(libs.junit.jupiter.api) + implementation(libs.mockito.core.compile) + implementation(libs.jetbrains.annotations) + implementation(libs.sqlite.jdbc) + implementation(libs.jlayer) + testImplementation(libs.junit.jupiter) + testImplementation(libs.mockito.core) + testImplementation(libs.mockito.junit.jupiter) + // Gradle 9 no longer adds the launcher implicitly. + testRuntimeOnly(libs.junit.platform.launcher) +} diff --git a/src/main/java/kst4contest/ApplicationConstants.java b/core/src/main/java/kst4contest/ApplicationConstants.java similarity index 99% rename from src/main/java/kst4contest/ApplicationConstants.java rename to core/src/main/java/kst4contest/ApplicationConstants.java index d6bfc128..d5a81214 100644 --- a/src/main/java/kst4contest/ApplicationConstants.java +++ b/core/src/main/java/kst4contest/ApplicationConstants.java @@ -20,14 +20,14 @@ public class ApplicationConstants { /** * Version shown to the user and used for semantic version comparison. */ - public static final String APPLICATION_CURRENT_VERSION = "1.44.0"; + public static final String APPLICATION_CURRENT_VERSION = "1.50.0"; /** * Legacy numeric representation used only while older update feeds and * application versions still exist. */ @Deprecated - public static final double APPLICATION_CURRENTVERSIONNUMBER = 1.44; + public static final double APPLICATION_CURRENTVERSIONNUMBER = 1.50; public static final String VERSIONINFOURLFORUPDATES_KST4CONTEST = "https://kst4contest.hamradioonline.de/kst4ContestVersionInfo.xml"; public static final String VERSIONINFDOWNLOADEDLOCALFILE = "kst4ContestVersionInfo.xml"; diff --git a/core/src/main/java/kst4contest/controller/ActiveOperatorProfile.java b/core/src/main/java/kst4contest/controller/ActiveOperatorProfile.java new file mode 100644 index 00000000..9a1febd5 --- /dev/null +++ b/core/src/main/java/kst4contest/controller/ActiveOperatorProfile.java @@ -0,0 +1,48 @@ +package kst4contest.controller; + +import kst4contest.model.OperatorProfileSelection; + +/** + * Holds the operator profile the current runtime works with. + * + *

The state is deliberately static, which is safe here for reasons that did not apply + * to the former static database connection: the value is immutable, it holds no live + * resource, and it is set on the JavaFX Application Thread before anything reads it - + * during startup, and again during a profile switch after the previous runtime has been + * shut down completely.

+ */ +public final class ActiveOperatorProfile { + + private static volatile OperatorProfileSelection currentSelection; + + private ActiveOperatorProfile() { + // Utility class. + } + + /** + * Returns the active profile selection. + * + * @return the active selection, or null when startup has not resolved one yet + */ + public static OperatorProfileSelection get() { + return currentSelection; + } + + /** + * Sets the active profile selection. + * + * @param selection selection to activate + */ + public static void set(final OperatorProfileSelection selection) { + currentSelection = selection; + } + + /** + * Returns whether a profile has already been resolved for this runtime. + * + * @return true if a selection is present + */ + public static boolean isInitialized() { + return currentSelection != null; + } +} diff --git a/src/main/java/kst4contest/controller/AirScoutPeriodicalAPReflectionInquirerTask.java b/core/src/main/java/kst4contest/controller/AirScoutPeriodicalAPReflectionInquirerTask.java similarity index 100% rename from src/main/java/kst4contest/controller/AirScoutPeriodicalAPReflectionInquirerTask.java rename to core/src/main/java/kst4contest/controller/AirScoutPeriodicalAPReflectionInquirerTask.java diff --git a/src/main/java/kst4contest/controller/BeaconTask.java b/core/src/main/java/kst4contest/controller/BeaconTask.java similarity index 100% rename from src/main/java/kst4contest/controller/BeaconTask.java rename to core/src/main/java/kst4contest/controller/BeaconTask.java diff --git a/src/main/java/kst4contest/controller/ChatController.java b/core/src/main/java/kst4contest/controller/ChatController.java similarity index 88% rename from src/main/java/kst4contest/controller/ChatController.java rename to core/src/main/java/kst4contest/controller/ChatController.java index c3e5e38b..2c04e4a9 100644 --- a/src/main/java/kst4contest/controller/ChatController.java +++ b/core/src/main/java/kst4contest/controller/ChatController.java @@ -11,13 +11,11 @@ import java.util.*; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; -import javafx.application.Platform; -import javafx.beans.property.*; -import javafx.collections.FXCollections; -import javafx.collections.ListChangeListener; -import javafx.collections.ObservableList; -import javafx.collections.transformation.FilteredList; -import javafx.collections.transformation.SortedList; +import kst4contest.observe.DirectUiDispatcher; +import kst4contest.observe.SimpleRoster; +import kst4contest.observe.UiDispatcher; +import kst4contest.observe.MutableValue; +import kst4contest.observe.ObservableRoster; import kst4contest.ApplicationConstants; import kst4contest.controller.interfaces.PstRotatorEventListener; import kst4contest.locatorUtils.DirectionUtils; @@ -28,7 +26,6 @@ import kst4contest.test.MockKstServer; import kst4contest.utils.ApplicationFileUtils; import kst4contest.utils.PlayAudioUtils; import kst4contest.locatorUtils.Location; -import kst4contest.view.Kst4ContestApplication; import java.io.*; import java.util.concurrent.ScheduledExecutorService; @@ -40,6 +37,7 @@ import kst4contest.logic.FrequencyTextParser; import java.util.logging.Level; import java.util.logging.Logger; import java.util.concurrent.ScheduledFuture; +import kst4contest.observe.SimpleValue; @@ -97,15 +95,9 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList */ private volatile double lastReportedRotatorAzimuth = Double.NaN; - private Kst4ContestApplication view; //effectively final, for recoupling of the controller to the view - private StatusUpdateListener statusListener; //update info interface for the threads - public void setView(Kst4ContestApplication view) { - this.view = view; - } - private UpdateInformation updateInformation; private ChatPreferences chatPreferences; @@ -604,12 +596,12 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList * must be updated on the JavaFX Application Thread. */ Runnable fxUpdate = () -> - chatPreferences.getActualQTF().setValue(normalizedAzimuth); + chatPreferences.getActualQTF().set(normalizedAzimuth); - if (Platform.isFxApplicationThread()) { + if (uiDispatcher.isUiThread()) { fxUpdate.run(); } else { - Platform.runLater(fxUpdate); + uiDispatcher.runOnUi(fxUpdate); } } @@ -1086,9 +1078,35 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList rotatorClient.stop(); rotatorClient = null; } + + releaseBackgroundExecutors(); } } + /** + * Stops the background executors that live as long as this controller. + * + *

These are not bound to one ON4KST session, so disconnecting leaves them running + * on purpose. When the controller itself is discarded they have to go, otherwise a + * discarded controller stays reachable through its own threads.

+ */ + private void releaseBackgroundExecutors() { + + on4KstConnectionManager.shutdown(); + skedReminderService.shutdown(); + + if (reachabilityService != null) { + reachabilityService.shutdown(); + } + + if (pendingRotatorRetry != null) { + pendingRotatorRetry.cancel(false); + pendingRotatorRetry = null; + } + + rotatorCommandScheduler.shutdownNow(); + } + private void cancelTimer(Timer timer) { if (timer != null) { timer.cancel(); @@ -1128,7 +1146,7 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList // } // public void addSked(ContestSked sked) { -// Platform.runLater(() -> { +// uiDispatcher.runOnUi(() -> { // this.activeSkeds.add(sked); // runContextLoopCycle(); // Trigger sofort // }); @@ -1138,10 +1156,9 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList // private ScheduledExecutorService contextLoopService; - private ObservableList activeSkeds = - FXCollections.synchronizedObservableList(FXCollections.observableArrayList()); + private final SimpleRoster activeSkeds = new SimpleRoster<>(); - public ObservableList getActiveSkeds() { + public ObservableRoster getActiveSkeds() { return activeSkeds; } @@ -1162,7 +1179,7 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList } public void addSked(ContestSked sked) { - Platform.runLater(() -> { + uiDispatcher.runOnUi(() -> { this.activeSkeds.add(sked); scoreService.requestRecompute("sked-added"); }); @@ -1623,16 +1640,22 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList } public List snapshotActiveSkeds() { - synchronized (activeSkeds) { - return new ArrayList<>(activeSkeds); - } + return new ArrayList<>(activeSkeds.snapshot()); } public void requestRemoveExpiredSkeds(long nowEpochMs) { - Platform.runLater(() -> { - synchronized (activeSkeds) { - activeSkeds.removeIf(sked -> (nowEpochMs - sked.getSkedTimeEpoch()) > 300_000); + uiDispatcher.runOnUi(() -> { + /* + * Only mutate when something really expired. An unconditional mutate would + * wake every roster listener on each cycle of the periodic score service. + */ + boolean anyExpired = activeSkeds.snapshot().stream() + .anyMatch(sked -> (nowEpochMs - sked.getSkedTimeEpoch()) > 300_000); + if (!anyExpired) { + return; } + activeSkeds.mutate(list -> + list.removeIf(sked -> (nowEpochMs - sked.getSkedTimeEpoch()) > 300_000)); }); } @@ -1716,24 +1739,21 @@ public class ChatController implements ThreadStatusCallback, PstRotatorEventList // ******All abstract types below here are used by the messageprocessor! // *************** - private ObservableList lst_globalChatMessageList = FXCollections.observableArrayList(); //All chatmessages will be put in there, later create filtered message lists -// private ObservableList lst_toAllMessageList = FXCollections.observableArrayList(); // directed to all - // (beacon) - private FilteredList lst_toAllMessageList = new FilteredList<>(lst_globalChatMessageList); // directed to all + private final SimpleRoster lst_globalChatMessageList = new SimpleRoster<>(); //All chatmessages will be put in there, later create filtered message lists -// private ObservableList lst_toMeMessageList = FXCollections.observableArrayList(); // directed to my - // call - private FilteredList lst_toMeMessageList = new FilteredList<>(lst_globalChatMessageList); + /* + * The four message views used to be FilteredList views on the global message + * list. They are now stored predicates: the derived list is computed on demand + * from lst_globalChatMessageList.snapshot(). A null predicate lets everything + * through, exactly like FilteredList.setPredicate(null) did. + */ + private volatile Predicate toAllMessageFilter; // directed to all (beacon) + private volatile Predicate toMeMessageFilter; // directed to my call + private volatile Predicate toOtherMessageFilter; // directed to a call but not mine + private volatile Predicate selectedCallSignInfoFilter; - private FilteredList lst_selectedCallSignInfofilteredMessageList = new FilteredList<>(lst_globalChatMessageList); // directed to all - -// private ObservableList lst_toOtherMessageList = FXCollections.observableArrayList(); // directed to a - // call but not - // mine - private FilteredList lst_toOtherMessageList = new FilteredList<>(lst_globalChatMessageList); - -// private ObservableList lstNotify_QSOSniffer_sniffedCallSignList = FXCollections.observableArrayList(); -private ObservableList +// private SimpleRoster lstNotify_QSOSniffer_sniffedCallSignList = new SimpleRoster<>(); +private SimpleRoster lstNotify_QSOSniffer_sniffedCallSignList; /** * we do some trick here with the chatmemberlist to not make it neccessary to change all boolean properties if the @@ -1742,27 +1762,34 @@ private ObservableList */ // private ObservableList chatMemberList = FXCollections.observableArrayList(workedInfoChange -> new Observable[] {workedInfoChange.workedInfoChangeFireListEventTriggerProperty()}); // List of active stations // in chat - private ObservableList chatMemberList = FXCollections.observableArrayList(); // List of active stations + /** + * The canonical station list. SimpleRoster serialises its own writes, so the + * former FXCollections.synchronizedObservableList wrapper is gone and + * lst_chatMemberList is this very field. + */ + private final SimpleRoster chatMemberList = new SimpleRoster<>(); // List of active stations + private final SimpleRoster> lst_chatMemberListFilterPredicates = new SimpleRoster<>(); + private final SimpleRoster lst_clusterMemberList = new SimpleRoster<>(); - // of active stn in chat - private FilteredList lst_chatMemberListFiltered = new FilteredList(chatMemberList); - private SortedList lst_chatMemberSortedFilteredList = new SortedList(lst_chatMemberListFiltered); - - private ObservableList lst_chatMemberList = FXCollections.synchronizedObservableList(chatMemberList); // List - private ObservableList> lst_chatMemberListFilterPredicates = FXCollections.observableArrayList(); - private ObservableList lst_clusterMemberList = FXCollections.observableArrayList(); + /** + * The order the station list is presented in. Fed by the TableView column + * headers, which used to drive the SortedList comparator directly. A null + * comparator keeps the incoming order, exactly like an unset SortedList + * comparator did. + */ + private volatile Comparator chatMemberOrder; /* * Thread-safe active-member model. * - * MessageBusManagementThread must not use the JavaFX TableView backing list as - * its primary data model. Otherwise every add/remove fires FilteredList, - * SortedList and TableView selection listeners on the MessageBus thread and JavaFX - * can throw "Not on FX application thread" or internal listener NPEs. + * MessageBusManagementThread must not use the UI-bound station list as its + * primary data model. Otherwise every add/remove wakes the mirror and the + * TableView selection listeners on the MessageBus thread, and JavaFX can throw + * "Not on FX application thread" or internal listener NPEs. * - * This map is the worker-thread safe source of truth. The ObservableList below - * remains a UI mirror and is mutated only on the JavaFX application thread. + * This map is the worker-thread safe source of truth. The roster below remains + * a UI mirror and is mutated only through the UI dispatcher. */ private final java.util.concurrent.ConcurrentMap activeChatMembersByCallAndCategory = new java.util.concurrent.ConcurrentHashMap<>(); @@ -1773,8 +1800,8 @@ private ObservableList * Do not write directly to lst_globalChatMessageList from worker threads. * Use publishChatMessage(...) instead. * - * The actual ObservableList mutation is batched and executed on the JavaFX - * application thread. The visible list order remains newest-first. + * The actual roster mutation is batched and executed on the user-interface + * thread. The visible list order remains newest-first. */ private final Object pendingChatMessagesLock = new Object(); private final List pendingChatMessages = new ArrayList<>(); @@ -1791,7 +1818,7 @@ private ObservableList private final List pendingClusterMessages = new ArrayList<>(); private boolean clusterMessageFlushScheduled = false; - private ObservableList lst_DBBasedWkdCallSignList = FXCollections.observableArrayList(); + private final SimpleRoster lst_DBBasedWkdCallSignList = new SimpleRoster<>(); // private HashMap map_ucxLogInfoWorkedCalls = new HashMap(); //Destination of ucx-log worked-messages @@ -1809,10 +1836,10 @@ private ObservableList return; } - if (Platform.isFxApplicationThread()) { + if (uiDispatcher.isUiThread()) { action.run(); } else { - Platform.runLater(action); + uiDispatcher.runOnUi(action); } } @@ -1905,20 +1932,20 @@ private ObservableList activeChatMembersByCallAndCategory.put(key, member); - runOnFxThread(() -> { - int existingIndex = findChatMemberIndexInUiListByKey(key); + runOnFxThread(() -> chatMemberList.mutate(list -> { + int existingIndex = findChatMemberIndexInList(list, key); if (existingIndex >= 0) { - lst_chatMemberList.set(existingIndex, member); + list.set(existingIndex, member); } else { - lst_chatMemberList.add(member); + list.add(member); } - }); + })); } /** * Removes an active chat member from the worker-thread model and from the UI - * mirror. Removal from the ObservableList is always performed on the FX thread - * because the list is bound to FilteredList/SortedList/TableView. + * mirror. Removal from the roster is always performed on the user-interface + * thread because the roster is mirrored into the TableView. */ public boolean removeActiveChatMember(ChatMember member) { String key = buildActiveChatMemberKey(member); @@ -1927,17 +1954,18 @@ private ObservableList } ChatMember removedMember = activeChatMembersByCallAndCategory.remove(key); - runOnFxThread(() -> lst_chatMemberList.removeIf(currentMember -> key.equals(buildActiveChatMemberKey(currentMember)))); + runOnFxThread(() -> chatMemberList.mutate(list -> + list.removeIf(currentMember -> key.equals(buildActiveChatMemberKey(currentMember))))); return removedMember != null; } /** * Clears the active-member model and the JavaFX UI mirror. Use this instead of - * getLst_chatMemberList().clear() from timers or worker threads. + * getLst_chatMemberList() mutations from timers or worker threads. */ public void clearActiveChatMembers() { activeChatMembersByCallAndCategory.clear(); - runOnFxThread(() -> lst_chatMemberList.clear()); + runOnFxThread(chatMemberList::clear); } /** @@ -1983,12 +2011,18 @@ private ObservableList if (!on4KstConnectionManager.isActiveSession(connectionSessionId)) { return; } - lst_chatMemberList.removeIf(member -> member != null - && member.getChatCategory() != null - && member.getChatCategory().getCategoryNumber() == categoryNumber); - lst_chatMemberList.addAll(safeMembers); + /* + * One batch: replacing a whole category must wake the mirror once, not + * once per station. An ON4KST user list can hold several thousand of them. + */ + chatMemberList.mutate(list -> { + list.removeIf(member -> member != null + && member.getChatCategory() != null + && member.getChatCategory().getCategoryNumber() == categoryNumber); + list.addAll(safeMembers); + }); if (workedDataFromDatabase != null) { - getLst_DBBasedWkdCallSignList().setAll( + setLst_DBBasedWkdCallSignList( workedDataFromDatabase.values()); } fireUserListUpdate("Complete ON4KST user list received"); @@ -2155,7 +2189,7 @@ private ObservableList int changedMembers = markSimpleLogWorkedMembers( activeChatMembersByCallAndCategory.values(), normalizedWorkedBaseCalls); int changedClusterMessages = markSimpleLogWorkedClusterMessages( - lst_clusterMemberList, normalizedWorkedBaseCalls); + lst_clusterMemberList.snapshot(), normalizedWorkedBaseCalls); if (changedMembers > 0) { fireUserListUpdate("Simplelogfile Worked status updated"); @@ -2384,22 +2418,22 @@ private ObservableList continue; } member.addKnownFrequency(detectedBand, detectedFrequencyMhz); - member.setFrequency(new SimpleStringProperty(displayFrequency)); + member.setFrequency(new SimpleValue<>(displayFrequency)); } // Also cover dummy senders that are not in the active model, e.g. [n/a] senders. sender.addKnownFrequency(detectedBand, detectedFrequencyMhz); - sender.setFrequency(new SimpleStringProperty(displayFrequency)); + sender.setFrequency(new SimpleValue<>(displayFrequency)); fireUserListUpdate("Frequency detected"); } - private int findChatMemberIndexInUiListByKey(String key) { + private int findChatMemberIndexInList(List list, String key) { if (key == null) { return -1; } - for (int i = 0; i < lst_chatMemberList.size(); i++) { - if (key.equals(buildActiveChatMemberKey(lst_chatMemberList.get(i)))) { + for (int i = 0; i < list.size(); i++) { + if (key.equals(buildActiveChatMemberKey(list.get(i)))) { return i; } } @@ -2433,13 +2467,15 @@ private ObservableList return resultingIndexes; } - for (Iterator iterator = lst_chatMemberList.iterator(); iterator.hasNext();) { + List currentMembers = chatMemberList.snapshot(); + + for (Iterator iterator = currentMembers.iterator(); iterator.hasNext();) { ChatMember chatMember = (ChatMember) iterator.next(); if (chatMember.getCallSignRaw().equals(lookForThis.getCallSignRaw())) { //Change for stations with -2 or -70 in logincallsign // System.out // .println("chtctrlr: Found raw " + chatMember.getCallSignRaw() + " // " + lookForThis.getCallSign()); - resultingIndexes.add(lst_chatMemberList.indexOf(chatMember)); + resultingIndexes.add(currentMembers.indexOf(chatMember)); } else { @@ -2465,10 +2501,10 @@ private ObservableList return; } - if (Platform.isFxApplicationThread()) { + if (uiDispatcher.isUiThread()) { statusListener.onUserListUpdated(); } else { - Platform.runLater(statusListener::onUserListUpdated); + uiDispatcher.runOnUi(statusListener::onUserListUpdated); } } @@ -2482,10 +2518,10 @@ private ObservableList return; } - if (Platform.isFxApplicationThread()) { + if (uiDispatcher.isUiThread()) { statusListener.onUserListUpdated(reason); } else { - Platform.runLater(() -> statusListener.onUserListUpdated(reason)); + uiDispatcher.runOnUi(() -> statusListener.onUserListUpdated(reason)); } } @@ -2534,24 +2570,65 @@ private ObservableList // } - public FilteredList getLst_selectedCallSignInfofilteredMessageList() { - return lst_selectedCallSignInfofilteredMessageList; - } - - public void setLst_selectedCallSignInfofilteredMessageList(FilteredList lst_selectedCallSignInfofilteredMessageList) { - this.lst_selectedCallSignInfofilteredMessageList = lst_selectedCallSignInfofilteredMessageList; - } - - public ObservableList getLst_globalChatMessageList() { + public ObservableRoster getLst_globalChatMessageList() { return lst_globalChatMessageList; } + /** + * Applies the stored filter to the current message store. + * + * @param filter {@code null} lets every message through, exactly like + * {@code FilteredList.setPredicate(null)} did + */ + private List filtered(Predicate filter) { + if (filter == null) { + return lst_globalChatMessageList.snapshot(); + } + return lst_globalChatMessageList.snapshot().stream().filter(filter).toList(); + } + + public void setToAllMessageFilter(Predicate filter) { + this.toAllMessageFilter = filter; + } + + /** The public messages, newest first. */ + public List toAllMessages() { + return filtered(toAllMessageFilter); + } + + public void setToMeMessageFilter(Predicate filter) { + this.toMeMessageFilter = filter; + } + + /** The messages addressed to the operator, newest first. */ + public List toMeMessages() { + return filtered(toMeMessageFilter); + } + + public void setToOtherMessageFilter(Predicate filter) { + this.toOtherMessageFilter = filter; + } + + /** The messages between other stations, newest first. */ + public List toOtherMessages() { + return filtered(toOtherMessageFilter); + } + + public void setSelectedCallSignInfoFilter(Predicate filter) { + this.selectedCallSignInfoFilter = filter; + } + + /** The messages shown in the info window of the selected station. */ + public List selectedCallSignInfoMessages() { + return filtered(selectedCallSignInfoFilter); + } + /** * Adds a chat message to the UI message store. * * Important: * - This method may be called from worker threads. - * - The ObservableList is modified only on the JavaFX application thread. + * - The roster is modified only on the user-interface thread. * - The backing list remains newest-first. * - Old messages are trimmed to avoid unlimited memory growth. */ @@ -2573,7 +2650,7 @@ private ObservableList chatMessageFlushScheduled = true; } - Platform.runLater(this::flushPendingChatMessagesToUi); + uiDispatcher.runOnUi(this::flushPendingChatMessagesToUi); } /** @@ -2639,30 +2716,40 @@ private ObservableList */ Collections.reverse(batch); - lst_globalChatMessageList.addAll(0, batch); - - trimGlobalChatMessageListIfNeeded(); + /* + * Insertion and trimming happen inside one mutate, so a whole batch wakes + * the listeners exactly once instead of once per message. + */ + lst_globalChatMessageList.mutate(list -> { + list.addAll(0, batch); + trimIfNeeded( + list, + ApplicationConstants.CHAT_MESSAGE_STORE_MAX_SIZE, + ApplicationConstants.CHAT_MESSAGE_STORE_TRIM_TO_SIZE); + }); } - private void trimGlobalChatMessageListIfNeeded() { - int maxSize = ApplicationConstants.CHAT_MESSAGE_STORE_MAX_SIZE; - int trimToSize = ApplicationConstants.CHAT_MESSAGE_STORE_TRIM_TO_SIZE; - + /** + * Drops the oldest entries once the store grew past its limit. + * + *

List order is newest-first, so the old entries sit at the end. + * + * @param list the list being mutated + * @param maxSize size above which trimming starts + * @param trimToSize size the list is cut back to + */ + private static void trimIfNeeded(List list, int maxSize, int trimToSize) { if (maxSize <= 0 || trimToSize <= 0 || trimToSize >= maxSize) { return; } - int currentSize = lst_globalChatMessageList.size(); + int currentSize = list.size(); if (currentSize <= maxSize) { return; } - /* - * List order is newest-first. - * Therefore old messages are at the end of the list. - */ - lst_globalChatMessageList.remove(trimToSize, currentSize); + list.subList(trimToSize, currentSize).clear(); } /** @@ -2670,7 +2757,7 @@ private ObservableList * * Same policy as for chat messages: * - batched UI update - * - JavaFX thread only for ObservableList mutation + * - user-interface thread only for roster mutation * - newest-first visible order * - bounded list size */ @@ -2689,7 +2776,7 @@ private ObservableList clusterMessageFlushScheduled = true; } - Platform.runLater(this::flushPendingClusterMessagesToUi); + uiDispatcher.runOnUi(this::flushPendingClusterMessagesToUi); } private void flushPendingClusterMessagesToUi() { @@ -2707,30 +2794,17 @@ private ObservableList Collections.reverse(batch); - lst_clusterMemberList.addAll(0, batch); - - trimClusterMessageListIfNeeded(); + lst_clusterMemberList.mutate(list -> { + list.addAll(0, batch); + trimIfNeeded( + list, + ApplicationConstants.CLUSTER_MESSAGE_STORE_MAX_SIZE, + ApplicationConstants.CLUSTER_MESSAGE_STORE_TRIM_TO_SIZE); + }); } - private void trimClusterMessageListIfNeeded() { - int maxSize = ApplicationConstants.CLUSTER_MESSAGE_STORE_MAX_SIZE; - int trimToSize = ApplicationConstants.CLUSTER_MESSAGE_STORE_TRIM_TO_SIZE; - - if (maxSize <= 0 || trimToSize <= 0 || trimToSize >= maxSize) { - return; - } - - int currentSize = lst_clusterMemberList.size(); - - if (currentSize <= maxSize) { - return; - } - - lst_clusterMemberList.remove(trimToSize, currentSize); - } - - public void setLst_globalChatMessageList(ObservableList lst_globalChatMessageList) { - this.lst_globalChatMessageList = lst_globalChatMessageList; + public void setLst_globalChatMessageList(Collection lst_globalChatMessageList) { + this.lst_globalChatMessageList.setAll(lst_globalChatMessageList); } public String getHostname() { @@ -2785,84 +2859,109 @@ private ObservableList // this.map_ucxLogInfoWorkedCalls = map_ucxLogInfoWorkedCalls; // } - public ObservableList getLst_chatMemberList() { - return lst_chatMemberList; + public ObservableRoster getLst_chatMemberList() { + return chatMemberList; } - public ObservableList getLst_DBBasedWkdCallSignList() { + public ObservableRoster getLst_DBBasedWkdCallSignList() { return lst_DBBasedWkdCallSignList; } - public void setLst_DBBasedWkdCallSignList(ObservableList lst_DBBasedWkdCallSignList) { - this.lst_DBBasedWkdCallSignList = lst_DBBasedWkdCallSignList; + public void setLst_DBBasedWkdCallSignList(Collection lst_DBBasedWkdCallSignList) { + this.lst_DBBasedWkdCallSignList.setAll(lst_DBBasedWkdCallSignList); } - public void setLst_chatMemberList(ObservableList lst_chatMemberList) { - this.lst_chatMemberList = lst_chatMemberList; + public void setLst_chatMemberList(Collection lst_chatMemberList) { + this.chatMemberList.setAll(lst_chatMemberList); } - public FilteredList getLst_chatMemberListFiltered() { - return lst_chatMemberListFiltered; - } - - public SortedList getLst_chatMemberSortedFilteredList() { - return lst_chatMemberSortedFilteredList; - } - - public ObservableList> getLst_chatMemberListFilterPredicates() { + public ObservableRoster> getLst_chatMemberListFilterPredicates() { return lst_chatMemberListFilterPredicates; } - public void setLst_chatMemberListFilterPredicates(ObservableList> lst_chatMemberListFilterPredicates) { - this.lst_chatMemberListFilterPredicates = lst_chatMemberListFilterPredicates; + public void setLst_chatMemberListFilterPredicates(Collection> lst_chatMemberListFilterPredicates) { + this.lst_chatMemberListFilterPredicates.setAll(lst_chatMemberListFilterPredicates); } - public ObservableList getLst_clusterMemberList() { + /** Adds one station-list filter. Nothing happens if it is already active. */ + public void addChatMemberListFilterPredicate(Predicate predicate) { + if (predicate == null || lst_chatMemberListFilterPredicates.snapshot().contains(predicate)) { + return; + } + lst_chatMemberListFilterPredicates.add(predicate); + } + + /** Removes one station-list filter. Unknown predicates are ignored. */ + public void removeChatMemberListFilterPredicate(Predicate predicate) { + if (predicate == null || !lst_chatMemberListFilterPredicates.snapshot().contains(predicate)) { + return; + } + lst_chatMemberListFilterPredicates.remove(predicate); + } + + /** Drops every station-list filter. Nothing happens if none is active. */ + public void clearChatMemberListFilterPredicates() { + if (lst_chatMemberListFilterPredicates.isEmpty()) { + return; + } + lst_chatMemberListFilterPredicates.clear(); + } + + /** The order the station list is presented in; {@code null} keeps the incoming order. */ + public Comparator getChatMemberOrder() { + return chatMemberOrder; + } + + public void setChatMemberOrder(Comparator chatMemberOrder) { + this.chatMemberOrder = chatMemberOrder; + } + + /** + * The visible station list, derived on demand from the canonical list, the + * active filters and the current order. This replaces the former + * FilteredList/SortedList chain. + */ + /** + * How many members are currently visible. Deliberately not + * {@code visibleChatMembers().size()}: that would sort several thousand rows to + * produce one number for the status line. + */ + public int visibleChatMemberCount() { + return ChatMemberListView.countMatching( + chatMemberList.snapshot(), + lst_chatMemberListFilterPredicates.snapshot()); + } + + public List visibleChatMembers() { + return ChatMemberListView.compute( + chatMemberList.snapshot(), + lst_chatMemberListFilterPredicates.snapshot(), + chatMemberOrder); + } + + public ObservableRoster getLst_clusterMemberList() { return lst_clusterMemberList; } - public void setLst_clusterMemberList(ObservableList lst_clusterMemberList) { - this.lst_clusterMemberList = lst_clusterMemberList; - } - - public ObservableList getLst_toAllMessageList() { - return lst_toAllMessageList; - } - -// public void setLst_toAllMessageList(ObservableList lst_toAllMessageList) { -// this.lst_toAllMessageList = lst_toAllMessageList; -// } - public void setLst_toAllMessageList(FilteredList lst_toAllMessageList) { - this.lst_toAllMessageList = lst_toAllMessageList; - } - - public ObservableList getLst_toMeMessageList() { - return lst_toMeMessageList; - } - -// public void setLst_toMeMessageList(ObservableList lst_toMeMessageList) { -// this.lst_toMeMessageList = lst_toMeMessageList; -// } - public void setLst_toMeMessageList(FilteredList lst_toMeMessageList) { - this.lst_toMeMessageList = lst_toMeMessageList; - } - - public ObservableList getLst_toOtherMessageList() { - return lst_toOtherMessageList; - } - -// public void setLst_toOtherMessageList(ObservableList lst_toOtherMessageList) { -// this.lst_toOtherMessageList = lst_toOtherMessageList; -// } - - public void setLst_toOtherMessageList(FilteredList lst_toOtherMessageList) { - this.lst_toOtherMessageList = lst_toOtherMessageList; + public void setLst_clusterMemberList(Collection lst_clusterMemberList) { + this.lst_clusterMemberList.setAll(lst_clusterMemberList); } public LinkedBlockingQueue getMessageTXBus() { return messageTXBus; } + /** + * Hands UI-visible changes over to the thread that owns the user interface. + * Headless construction defaults to running them on the calling thread. + */ + private UiDispatcher uiDispatcher = new DirectUiDispatcher(); + + /** The boundary worker threads use instead of touching the user interface. */ + public UiDispatcher uiDispatcher() { + return uiDispatcher; + } + public ChatController() { super(); @@ -2887,9 +2986,40 @@ private ObservableList * @param setOwnChatMemberObject */ public ChatController(ChatMember setOwnChatMemberObject,StatusUpdateListener listener) { - super(); + this(setOwnChatMemberObject, + listener, + ChatPreferences.PREFERENCES_FILE, + DBController.DATABASE_FILE, + true, + // Headless construction: callers with a user interface use the + // constructor that takes the dispatcher explicitly. + new DirectUiDispatcher()); + } - chatPreferences = new ChatPreferences(); + /** + * Creates a chat controller bound to the files of one operator profile. + * + *

Both file names are resolved below the application directory. This is the only + * place where the active operator profile enters the controller; everything below + * works on the resulting {@link ChatPreferences} and {@link DBController} instances + * without knowing about profiles at all.

+ * + * @param setOwnChatMemberObject chat member object representing the local station + * @param listener callback for thread status updates + * @param preferencesRelativeFileName preferences file name relative to the application directory + * @param workedDatabaseRelativeFileName worked-station database file name relative to the application directory + * @param seedWorkedDatabaseFromResource true to seed a missing database from the bundled template + */ + public ChatController(ChatMember setOwnChatMemberObject, + StatusUpdateListener listener, + String preferencesRelativeFileName, + String workedDatabaseRelativeFileName, + boolean seedWorkedDatabaseFromResource, + UiDispatcher uiDispatcher) { + super(); + this.uiDispatcher = java.util.Objects.requireNonNull(uiDispatcher, "uiDispatcher"); + + chatPreferences = new ChatPreferences(preferencesRelativeFileName); chatPreferences.readPreferencesFromXmlFile(); Path historyFile = Path.of(ApplicationFileUtils.getFilePath( ApplicationConstants.APPLICATION_NAME, @@ -2920,7 +3050,7 @@ private ObservableList - lst_toAllMessageList.setPredicate(new Predicate() { + setToAllMessageFilter(new Predicate() { @Override public boolean test(ChatMessage chatMessage) { @@ -2939,7 +3069,7 @@ private ObservableList } }); - lst_toOtherMessageList.setPredicate(new Predicate() { + setToOtherMessageFilter(new Predicate() { @Override public boolean test(ChatMessage chatMessage) { try { @@ -2958,7 +3088,7 @@ private ObservableList } }); - dbHandler = new DBController(); + dbHandler = new DBController(workedDatabaseRelativeFileName, seedWorkedDatabaseFromResource); reachabilityService = new ReachabilityService(this); rebuildWorkedGrossFieldCacheFromDatabase(); @@ -3032,20 +3162,16 @@ private ObservableList return false; }; - lstNotify_QSOSniffer_sniffedCallSignList.addListener((ListChangeListener) c -> { - -// System.out.println(c.toString()); - - // Wir zwingen die FilteredList zum Neuscannen, indem wir das Prädikat neu setzen. - lst_toMeMessageList.setPredicate(null); // kurz resetten (manchmal nötig in älteren JavaFX Versionen) - lst_toMeMessageList.setPredicate(chatFilterPredicate); - - }); + /* + * The former FilteredList had to be told to rescan when the monitoring list + * changed. The derived view is recomputed on every read instead, so the + * user interface only has to watch the monitoring roster as a second source. + */ // lstNotify_QSOSniffer_sniffedCallSignList.add("DF0GEB"); - lst_toMeMessageList.setPredicate(chatFilterPredicate); //sniffed callsign filter predicate is here! + setToMeMessageFilter(chatFilterPredicate); //sniffed callsign filter predicate is here! // lst_toMeMessageList.setPredicate(new Predicate() { // @Override @@ -3124,11 +3250,11 @@ private ObservableList - public ObservableList getLstNotify_QSOSniffer_sniffedCallSignList() { + public SimpleRoster getLstNotify_QSOSniffer_sniffedCallSignList() { return lstNotify_QSOSniffer_sniffedCallSignList; } - public void setLstNotify_QSOSniffer_sniffedCallSignList(ObservableList lstNotify_QSOSniffer_sniffedCallSignList) { + public void setLstNotify_QSOSniffer_sniffedCallSignList(SimpleRoster lstNotify_QSOSniffer_sniffedCallSignList) { this.lstNotify_QSOSniffer_sniffedCallSignList = lstNotify_QSOSniffer_sniffedCallSignList; } @@ -4049,11 +4175,11 @@ private ObservableList HashMap finalWorkedDataFromDatabase = workedDataFromDatabase; - Platform.runLater(() -> { + uiDispatcher.runOnUi(() -> { applyWorkedAndQrvStateFromDatabase( activeChatMembersByCallAndCategory.values(), finalWorkedDataFromDatabase); - getLst_DBBasedWkdCallSignList().setAll(finalWorkedDataFromDatabase.values()); + setLst_DBBasedWkdCallSignList(finalWorkedDataFromDatabase.values()); fireUserListUpdate("Worked database state refreshed"); }); } @@ -4111,7 +4237,7 @@ private ObservableList */ public void resetWorkedInfoInGuiLists() { - this.chatController.getLst_chatMemberList().forEach( + this.chatController.getLst_chatMemberList().snapshot().forEach( chatMember -> chatMember.resetWorkedInformationAtAllBands()); } @@ -4120,7 +4246,7 @@ private ObservableList */ public void resetQRVInfoInGuiLists() { - this.chatController.getLst_chatMemberList().forEach( + this.chatController.getLst_chatMemberList().snapshot().forEach( chatMember -> chatMember.resetQRVInformationAtAllBands()); } @@ -4217,17 +4343,18 @@ private ObservableList final long now = System.currentTimeMillis(); // Ensure property updates happen on FX thread - if (Platform.isFxApplicationThread()) { + if (uiDispatcher.isUiThread()) { lastUiReminderEvent.set(new UiReminderEvent(raw, minutesBefore, now)); } else { - Platform.runLater(() -> lastUiReminderEvent.set(new UiReminderEvent(raw, minutesBefore, now))); + uiDispatcher.runOnUi(() -> lastUiReminderEvent.set(new UiReminderEvent(raw, minutesBefore, now))); } } - private final ObjectProperty lastUiReminderEvent = new SimpleObjectProperty<>(null); + private final MutableValue lastUiReminderEvent = new SimpleValue<>(null); - public ReadOnlyObjectProperty lastUiReminderEventProperty() { + /** The most recent sked reminder; {@code null} until the first one fires. */ + public kst4contest.observe.ObservableValue lastUiReminderEvent() { return lastUiReminderEvent; } @@ -4276,7 +4403,7 @@ private ObservableList } if (lstNotify_QSOSniffer_sniffedCallSignList == null - || lstNotify_QSOSniffer_sniffedCallSignList.isEmpty()) { + || lstNotify_QSOSniffer_sniffedCallSignList.size() == 0) { return false; } @@ -4290,7 +4417,7 @@ private ObservableList ); boolean observedCall = - lstNotify_QSOSniffer_sniffedCallSignList + lstNotify_QSOSniffer_sniffedCallSignList.snapshot() .stream() .anyMatch( monitoredCall -> { diff --git a/core/src/main/java/kst4contest/controller/ChatMemberListView.java b/core/src/main/java/kst4contest/controller/ChatMemberListView.java new file mode 100644 index 00000000..64aa991f --- /dev/null +++ b/core/src/main/java/kst4contest/controller/ChatMemberListView.java @@ -0,0 +1,77 @@ +package kst4contest.controller; + +import kst4contest.model.ChatMember; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.function.Predicate; + +/** + * Derives the visible station list from the canonical one. + * + *

This replaces the JavaFX {@code FilteredList}/{@code SortedList} pair that + * used to sit in {@link ChatController}. Being a pure function, the filtering + * and ordering rules are testable without a running toolkit for the first time. + */ +public final class ChatMemberListView { + + private ChatMemberListView() { + } + + /** + * @param members the canonical list; never modified + * @param filters combined with AND; an empty list lets everything through + * @param order {@code null} keeps the incoming order; sorting is stable + * @return an immutable result list + */ + public static List compute(List members, + List> filters, + Comparator order) { + List result = new ArrayList<>(members.size()); + for (ChatMember member : members) { + if (matches(member, filters)) { + result.add(member); + } + } + if (order != null) { + // List.sort is stable: within a tie the arrival order is kept. + result.sort(order); + } + /* + * Collections.unmodifiableList and not List.copyOf: the JavaFX list this + * replaces carried null entries, and List.copyOf rejects them. A + * NullPointerException raised here would be swallowed by the listener guard + * and the station list would stop updating without a word. + */ + return java.util.Collections.unmodifiableList(result); + } + + /** + * How many members pass the filters. Same rules as {@link #compute}, but it + * neither sorts nor builds a list: the status line only wants the number. + */ + public static int countMatching(List members, List> filters) { + int count = 0; + for (ChatMember member : members) { + if (matches(member, filters)) { + count++; + } + } + return count; + } + + private static boolean matches(ChatMember member, List> filters) { + for (Predicate filter : filters) { + try { + if (!filter.test(member)) { + return false; + } + } catch (RuntimeException e) { + // A broken filter must not empty the station list during a contest. + System.err.println("[station list] filter failed, keeping the member: " + e); + } + } + return true; + } +} diff --git a/src/main/java/kst4contest/controller/DBController.java b/core/src/main/java/kst4contest/controller/DBController.java similarity index 90% rename from src/main/java/kst4contest/controller/DBController.java rename to core/src/main/java/kst4contest/controller/DBController.java index 3c32db5d..9409c4cb 100644 --- a/src/main/java/kst4contest/controller/DBController.java +++ b/core/src/main/java/kst4contest/controller/DBController.java @@ -6,9 +6,13 @@ import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; +import java.util.Objects; import kst4contest.ApplicationConstants; import kst4contest.model.ChatMember; @@ -52,34 +56,128 @@ public class DBController { */ private static final long EXPIRATION_CLEANUP_MIN_INTERVAL_IN_MILLISECONDS = 60L * 1000L; - private static final DBController dbcontroller = new DBController(); - private static Connection connection; - private static String DB_PATH = ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, DATABASE_FILE); + /** + * Lazily created controller for the root installation database. It is created on + * first use only, because an eagerly created instance would open a database file + * before the application knows which operator profile is active. + */ + private static volatile DBController defaultInstance; + + private Connection connection; + + /** + * File name of this database relative to the application directory, for example + * "praktiKST.db" or "profiles/OP2/praktiKST.db". + */ + private final String databaseRelativeFileName; + + /** + * Absolute path of the database file, resolved once during construction. + */ + private final String databaseFilePath; + + /** + * True if a missing database file should be seeded from the shipped template. + */ + private final boolean seedFromResource; + + /** + * Shutdown hook of this instance. It is remembered so it can be deregistered when + * the connection is closed. Without that, every operator profile switch would leave + * another hook behind that keeps a dead connection alive until the process ends. + */ + private Thread databaseShutdownHook; /** * Remembers the last timestamp at which the expiration cleanup had been executed. */ private long lastExpirationCleanupExecutionEpochMs = 0L; + /** + * Creates a controller for the worked-station database of the root installation. + */ public DBController() { - initDBConnection(); - } - - public static DBController getInstance() { - return dbcontroller; + this(DATABASE_FILE, true); } /** - * Closes the database connection if it is still open. + * Creates a controller for the worked-station database of one operator profile. + * + * @param databaseRelativeFileName file name relative to the application directory + * @param seedFromResource true to copy the shipped template database when the file + * does not exist yet, false to create an empty database and + * let the schema creation build all required tables + */ + public DBController(final String databaseRelativeFileName, final boolean seedFromResource) { + this.databaseRelativeFileName = + Objects.requireNonNull(databaseRelativeFileName, "databaseRelativeFileName"); + this.seedFromResource = seedFromResource; + this.databaseFilePath = ApplicationFileUtils.getFilePath( + ApplicationConstants.APPLICATION_NAME, + databaseRelativeFileName + ); + + initDBConnection(); + } + + /** + * Returns a controller for the root installation database, creating it on first use. + * + * @return the shared controller for the root installation database + */ + public static synchronized DBController getInstance() { + + if (defaultInstance == null) { + defaultInstance = new DBController(); + } + + return defaultInstance; + } + + /** + * Returns the absolute path of the database file this controller works on. + * + * @return absolute database file path + */ + public String getDatabaseFilePath() { + return databaseFilePath; + } + + /** + * Closes the database connection if it is still open and deregisters the shutdown + * hook of this instance. */ public synchronized void closeDBConnection() { + + closeConnectionQuietly(); + + if (databaseShutdownHook != null) { + try { + Runtime.getRuntime().removeShutdownHook(databaseShutdownHook); + } catch (IllegalStateException shutdownAlreadyInProgress) { + // Expected while the JVM is shutting down; the hook is running anyway. + } + + databaseShutdownHook = null; + } + } + + /** + * Closes the connection without touching the shutdown hook. This is also the body of + * the shutdown hook itself. + */ + private synchronized void closeConnectionQuietly() { + try { if (connection != null && !connection.isClosed()) { connection.close(); + System.out.println("Connection to Database closed: " + databaseFilePath); } } catch (SQLException e) { e.printStackTrace(); } + + connection = null; } /** @@ -91,22 +189,17 @@ public class DBController { System.out.println("DBH: initiate new db connection"); try { - ApplicationFileUtils.copyResourceIfRequired( - ApplicationConstants.APPLICATION_NAME, - DATABASE_RESOURCE, - DATABASE_FILE - ); - if (connection != null && !connection.isClosed()) { return; } + prepareDatabaseFile(); + System.out.println("Creating Connection to Database..."); - DB_PATH = ApplicationFileUtils.getFilePath(ApplicationConstants.APPLICATION_NAME, DATABASE_FILE); - connection = DriverManager.getConnection("jdbc:sqlite:" + DB_PATH); + connection = DriverManager.getConnection("jdbc:sqlite:" + databaseFilePath); - System.out.println("[DBH, Info]: Path = " + DB_PATH); + System.out.println("[DBH, Info]: Path = " + databaseFilePath); if (!connection.isClosed()) { System.out.println("...Connection established"); @@ -115,25 +208,50 @@ public class DBController { throw new RuntimeException(e); } - Runtime.getRuntime().addShutdownHook(new Thread() { - public void run() { - try { - if (connection != null && !connection.isClosed()) { - connection.close(); - - if (connection.isClosed()) { - System.out.println("Connection to Database closed"); - } - } - } catch (SQLException e) { - e.printStackTrace(); - } - } - }); + databaseShutdownHook = new Thread(this::closeConnectionQuietly, + "DBController-shutdown-" + databaseRelativeFileName); + Runtime.getRuntime().addShutdownHook(databaseShutdownHook); ensureChatMemberTableCompatibility(); } + /** + * Makes sure the database file can be opened. + * + *

The database of the root installation is seeded from the shipped template so + * existing installations keep their historic content. A database that belongs to an + * additional operator profile is created empty on purpose: the shipped template + * carries several thousand foreign callsigns and an outdated schema version, which + * would present a new operator with foreign data and trigger the full callsign + * normalization rebuild. The required tables are created by + * {@link #ensureChatMemberTableCompatibility()} in both cases.

+ */ + private synchronized void prepareDatabaseFile() { + + if (seedFromResource) { + ApplicationFileUtils.copyResourceIfRequired( + ApplicationConstants.APPLICATION_NAME, + DATABASE_RESOURCE, + databaseRelativeFileName + ); + + return; + } + + Path parentDirectory = Path.of(databaseFilePath).getParent(); + + if (parentDirectory == null) { + return; + } + + try { + Files.createDirectories(parentDirectory); + } catch (IOException e) { + throw new RuntimeException( + "[DBH, ERROR:] Could not create database directory " + parentDirectory, e); + } + } + /** * Ensures that the ChatMember table exists, that all required columns are * available for newer software versions, that existing old callsign keys are diff --git a/src/main/java/kst4contest/controller/DXClusterController.java b/core/src/main/java/kst4contest/controller/DXClusterController.java similarity index 98% rename from src/main/java/kst4contest/controller/DXClusterController.java rename to core/src/main/java/kst4contest/controller/DXClusterController.java index 521f7c87..771045eb 100644 --- a/src/main/java/kst4contest/controller/DXClusterController.java +++ b/core/src/main/java/kst4contest/controller/DXClusterController.java @@ -184,7 +184,7 @@ // String singleDXClusterMessage = "DX de "; // // singleDXClusterMessage += client.getChatPreferences().getLoginCallSign() + " "; -// singleDXClusterMessage += aChatMember.getFrequency().getValue() + " "; +// singleDXClusterMessage += aChatMember.getFrequency().get() + " "; // singleDXClusterMessage += aChatMember.getCallSign().toUpperCase() + " "; // singleDXClusterMessage += aChatMember.getQra().toUpperCase() + " "; // singleDXClusterMessage += new Utils4KST().time_generateCurrenthhmmZTimeStringForClusterMessage() + "\n"; diff --git a/src/main/java/kst4contest/controller/DXClusterSpotFormatter.java b/core/src/main/java/kst4contest/controller/DXClusterSpotFormatter.java similarity index 100% rename from src/main/java/kst4contest/controller/DXClusterSpotFormatter.java rename to core/src/main/java/kst4contest/controller/DXClusterSpotFormatter.java diff --git a/src/main/java/kst4contest/controller/DXClusterThreadPooledServer.java b/core/src/main/java/kst4contest/controller/DXClusterThreadPooledServer.java similarity index 96% rename from src/main/java/kst4contest/controller/DXClusterThreadPooledServer.java rename to core/src/main/java/kst4contest/controller/DXClusterThreadPooledServer.java index 699d58d5..2f27cfe4 100644 --- a/src/main/java/kst4contest/controller/DXClusterThreadPooledServer.java +++ b/core/src/main/java/kst4contest/controller/DXClusterThreadPooledServer.java @@ -18,6 +18,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; +import kst4contest.observe.SimpleValue; public class DXClusterThreadPooledServer implements Runnable { @@ -157,17 +158,20 @@ public class DXClusterThreadPooledServer implements Runnable { try { String frequency = Utils4KST.normalizeFrequencyString( - chatMember.getFrequency().getValue(), - chatController + chatMember.getFrequency().get(), + // Bridge until ChatPreferences moves to the observe types: + // Utils4KST only reads the prefix, so a snapshot is enough. + new SimpleValue<>(chatController .getChatPreferences() .getNotify_optionalFrequencyPrefix() + .get()) ); clusterPayload = DXClusterSpotFormatter.formatPayload( chatController .getChatPreferences() .getNotify_DXCSrv_SpottersCallSign() - .getValue(), + .get(), frequency, chatMember.getCallSign(), chatMember.getQra(), diff --git a/src/main/java/kst4contest/controller/ExternalLoggedQso.java b/core/src/main/java/kst4contest/controller/ExternalLoggedQso.java similarity index 100% rename from src/main/java/kst4contest/controller/ExternalLoggedQso.java rename to core/src/main/java/kst4contest/controller/ExternalLoggedQso.java diff --git a/src/main/java/kst4contest/controller/InputReaderThread.java b/core/src/main/java/kst4contest/controller/InputReaderThread.java similarity index 100% rename from src/main/java/kst4contest/controller/InputReaderThread.java rename to core/src/main/java/kst4contest/controller/InputReaderThread.java diff --git a/src/main/java/kst4contest/controller/LoggedQsoBand.java b/core/src/main/java/kst4contest/controller/LoggedQsoBand.java similarity index 100% rename from src/main/java/kst4contest/controller/LoggedQsoBand.java rename to core/src/main/java/kst4contest/controller/LoggedQsoBand.java diff --git a/src/main/java/kst4contest/controller/MessageBusManagementThread.java b/core/src/main/java/kst4contest/controller/MessageBusManagementThread.java similarity index 99% rename from src/main/java/kst4contest/controller/MessageBusManagementThread.java rename to core/src/main/java/kst4contest/controller/MessageBusManagementThread.java index c629cd74..4ad58b5c 100644 --- a/src/main/java/kst4contest/controller/MessageBusManagementThread.java +++ b/core/src/main/java/kst4contest/controller/MessageBusManagementThread.java @@ -7,6 +7,7 @@ import java.sql.SQLException; //import java.util.ArrayList; import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Hashtable; import java.util.Locale; import java.util.regex.Matcher; @@ -14,8 +15,6 @@ import java.util.regex.Pattern; import java.util.logging.Level; import java.util.logging.Logger; -import javafx.beans.property.SimpleStringProperty; -import javafx.collections.ObservableList; import kst4contest.ApplicationConstants; import kst4contest.locatorUtils.DirectionUtils; import kst4contest.locatorUtils.Location; @@ -23,6 +22,7 @@ import kst4contest.model.*; import kst4contest.logic.FrequencyTextParser; import java.util.concurrent.LinkedBlockingQueue; import java.util.function.LongPredicate; +import kst4contest.observe.SimpleValue; /** * @@ -578,7 +578,7 @@ public class MessageBusManagementThread extends Thread { * @param lookForThis * @return Integer (index), -1 for not found */ - private int checkListForChatMemberIndexByCallSign(ObservableList list, ChatMember lookForThis) { + private int checkListForChatMemberIndexByCallSign(List list, ChatMember lookForThis) { if (lookForThis == null) { @@ -1168,12 +1168,12 @@ public class MessageBusManagementThread extends Thread { // // automaticAnswer.setSender(itsMe); // automaticAnswer.setReceiver(newMessageArrived.getSender()); -// automaticAnswer.setMessageText("/CQ " + newMessageArrived.getSender().getCallSign() + " KST4Contest Auto: QRG is: " + this.client.getChatPreferences().getMYQRGFirstCat().getValue()); +// automaticAnswer.setMessageText("/CQ " + newMessageArrived.getSender().getCallSign() + " KST4Contest Auto: QRG is: " + this.client.getChatPreferences().getMYQRGFirstCat().get()); // // if (this.client.getChatPreferences().isLoginToSecondChatEnabled()) { -// automaticAnswer.setMessageText("/CQ " + newMessageArrived.getSender().getCallSign() + " KST4Contest Auto: QRGs: " + this.client.getChatPreferences().getMYQRGFirstCat().getValue() + " / " + this.client.getChatPreferences().getMYQRGSecondCat().getValue()); +// automaticAnswer.setMessageText("/CQ " + newMessageArrived.getSender().getCallSign() + " KST4Contest Auto: QRGs: " + this.client.getChatPreferences().getMYQRGFirstCat().get() + " / " + this.client.getChatPreferences().getMYQRGSecondCat().get()); // } else { -// automaticAnswer.setMessageText("/CQ " + newMessageArrived.getSender().getCallSign() + " KST4Contest Auto: QRG is: " + this.client.getChatPreferences().getMYQRGFirstCat().getValue()); +// automaticAnswer.setMessageText("/CQ " + newMessageArrived.getSender().getCallSign() + " KST4Contest Auto: QRG is: " + this.client.getChatPreferences().getMYQRGFirstCat().get()); // } // // this.client.getMessageTXBus().add(automaticAnswer); @@ -1308,7 +1308,7 @@ public class MessageBusManagementThread extends Thread { String detectedFrequency = sender.getFrequency() == null ? null - : sender.getFrequency().getValue(); + : sender.getFrequency().get(); if (detectedFrequency != null && !detectedFrequency.isBlank()) { /* @@ -1447,7 +1447,7 @@ public class MessageBusManagementThread extends Thread { newDXCListSender.setQra(splittedMessageLine[8]); ChatMember newDXCListReceiver = new ChatMember(); - newDXCListReceiver.setFrequency(new SimpleStringProperty(splittedMessageLine[5])); + newDXCListReceiver.setFrequency(new SimpleValue<>(splittedMessageLine[5])); newDXCListReceiver.setCallSign(splittedMessageLine[6]); newDXCListReceiver.setQra(splittedMessageLine[9]); @@ -1487,7 +1487,7 @@ public class MessageBusManagementThread extends Thread { newDXCListSender2.setQra(splittedMessageLine[7]); ChatMember newDXCListReceiver2 = new ChatMember(); - newDXCListReceiver2.setFrequency(new SimpleStringProperty(splittedMessageLine[4])); + newDXCListReceiver2.setFrequency(new SimpleValue<>(splittedMessageLine[4])); newDXCListReceiver2.setCallSign(splittedMessageLine[5]); newDXCListReceiver2.setQra(splittedMessageLine[8]); @@ -2058,10 +2058,10 @@ public class MessageBusManagementThread extends Thread { if (incomingCategory != null && secondCategory != null && incomingCategory.getCategoryNumber() == secondCategory.getCategoryNumber()) { - return this.client.getChatPreferences().getMYQRGSecondCat().getValue(); + return this.client.getChatPreferences().getMYQRGSecondCat().get(); } - return this.client.getChatPreferences().getMYQRGFirstCat().getValue(); + return this.client.getChatPreferences().getMYQRGFirstCat().get(); } private String autoAnswerCooldownKey(ChatMessage incoming) { diff --git a/src/main/java/kst4contest/controller/MessageBusManagementThreadFrequencyContextTest.java b/core/src/main/java/kst4contest/controller/MessageBusManagementThreadFrequencyContextTest.java similarity index 100% rename from src/main/java/kst4contest/controller/MessageBusManagementThreadFrequencyContextTest.java rename to core/src/main/java/kst4contest/controller/MessageBusManagementThreadFrequencyContextTest.java diff --git a/src/main/java/kst4contest/controller/MessageHistoryRecorder.java b/core/src/main/java/kst4contest/controller/MessageHistoryRecorder.java similarity index 100% rename from src/main/java/kst4contest/controller/MessageHistoryRecorder.java rename to core/src/main/java/kst4contest/controller/MessageHistoryRecorder.java diff --git a/src/main/java/kst4contest/controller/MessageVariableResolver.java b/core/src/main/java/kst4contest/controller/MessageVariableResolver.java similarity index 97% rename from src/main/java/kst4contest/controller/MessageVariableResolver.java rename to core/src/main/java/kst4contest/controller/MessageVariableResolver.java index 9a0033c5..abe8b36f 100644 --- a/src/main/java/kst4contest/controller/MessageVariableResolver.java +++ b/core/src/main/java/kst4contest/controller/MessageVariableResolver.java @@ -49,8 +49,8 @@ public final class MessageVariableResolver { return null; } - String primaryFrequency = valueOrEmpty(chatPreferences.getMYQRGFirstCat().getValue()); - String secondaryFrequency = valueOrEmpty(chatPreferences.getMYQRGSecondCat().getValue()); + String primaryFrequency = valueOrEmpty(chatPreferences.getMYQRGFirstCat().get()); + String secondaryFrequency = valueOrEmpty(chatPreferences.getMYQRGSecondCat().get()); String ownLocator = valueOrEmpty(chatPreferences.getStn_loginLocatorMainCat()); String resolvedText = template; @@ -60,7 +60,7 @@ public final class MessageVariableResolver { resolvedText = resolvedText.replace("MYLOCATORSHORT", abbreviateLocator(ownLocator)); resolvedText = resolvedText.replace("MYLOCATOR", ownLocator); resolvedText = resolvedText.replace("MYCALL", valueOrEmpty(chatPreferences.getStn_loginCallSign())); - resolvedText = resolvedText.replace("MYQTF", formatHeading(chatPreferences.getActualQTF().getValue().doubleValue())); + resolvedText = resolvedText.replace("MYQTF", formatHeading(chatPreferences.getActualQTF().get().doubleValue())); return resolvedText; } diff --git a/src/main/java/kst4contest/controller/On4KstConnectionManager.java b/core/src/main/java/kst4contest/controller/On4KstConnectionManager.java similarity index 98% rename from src/main/java/kst4contest/controller/On4KstConnectionManager.java rename to core/src/main/java/kst4contest/controller/On4KstConnectionManager.java index 2e4f9d32..902d9411 100644 --- a/src/main/java/kst4contest/controller/On4KstConnectionManager.java +++ b/core/src/main/java/kst4contest/controller/On4KstConnectionManager.java @@ -137,6 +137,20 @@ final class On4KstConnectionManager { scheduler.execute(() -> openConnection(token)); } + /** + * Stops the supervisor thread of this manager for good. + * + *

{@link #stopByUser()} only ends the current ON4KST session; the periodic + * session monitor keeps running. That is correct while the application lives, but a + * manager belonging to a discarded runtime must release its thread, otherwise every + * operator profile switch would leave another supervisor behind holding the dead + * controller.

+ */ + void shutdown() { + scheduler.shutdownNow(); + LOGGER.fine("ON4KST connection supervisor shut down"); + } + /** * Stops the current session and invalidates every scheduled callback or reconnect * belonging to it. diff --git a/src/main/java/kst4contest/controller/On4KstConnectionState.java b/core/src/main/java/kst4contest/controller/On4KstConnectionState.java similarity index 100% rename from src/main/java/kst4contest/controller/On4KstConnectionState.java rename to core/src/main/java/kst4contest/controller/On4KstConnectionState.java diff --git a/src/main/java/kst4contest/controller/On4KstProtocol.java b/core/src/main/java/kst4contest/controller/On4KstProtocol.java similarity index 100% rename from src/main/java/kst4contest/controller/On4KstProtocol.java rename to core/src/main/java/kst4contest/controller/On4KstProtocol.java diff --git a/src/main/java/kst4contest/controller/On4KstProtocolTest.java b/core/src/main/java/kst4contest/controller/On4KstProtocolTest.java similarity index 100% rename from src/main/java/kst4contest/controller/On4KstProtocolTest.java rename to core/src/main/java/kst4contest/controller/On4KstProtocolTest.java diff --git a/src/main/java/kst4contest/controller/On4KstSocketThreadTest.java b/core/src/main/java/kst4contest/controller/On4KstSocketThreadTest.java similarity index 100% rename from src/main/java/kst4contest/controller/On4KstSocketThreadTest.java rename to core/src/main/java/kst4contest/controller/On4KstSocketThreadTest.java diff --git a/core/src/main/java/kst4contest/controller/OperatorProfileManagementService.java b/core/src/main/java/kst4contest/controller/OperatorProfileManagementService.java new file mode 100644 index 00000000..06a7a8c5 --- /dev/null +++ b/core/src/main/java/kst4contest/controller/OperatorProfileManagementService.java @@ -0,0 +1,312 @@ +package kst4contest.controller; + +import kst4contest.ApplicationConstants; +import kst4contest.model.ChatPreferences; +import kst4contest.model.OperatorProfile; +import kst4contest.utils.ApplicationFileUtils; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; +import java.util.stream.Stream; + +/** + * Creates, renames, duplicates and removes operator profiles. + * + *

Kept free of user interface code so the behaviour can be tested without a JavaFX + * runtime. All methods work on the registry and on the files below the application + * directory.

+ */ +public class OperatorProfileManagementService { + + private static final Logger LOGGER = + Logger.getLogger(OperatorProfileManagementService.class.getName()); + + private final OperatorProfileStore profileStore; + + public OperatorProfileManagementService() { + this(new OperatorProfileStore()); + } + + public OperatorProfileManagementService(final OperatorProfileStore profileStore) { + this.profileStore = profileStore; + } + + /** + * Lists all profiles, including the implicit root profile of a plain installation. + * + * @return the known profiles, never empty + */ + public List listProfiles() { + + List knownProfiles = profileStore.loadProfiles(); + + if (knownProfiles.isEmpty()) { + knownProfiles = new ArrayList<>(); + knownProfiles.add(profileStore.buildImplicitRootProfile()); + } + + return knownProfiles; + } + + /** + * Creates a new operator profile with its own preferences file. + * + *

Creating the first additional profile is also the moment the registry appears: + * the root profile is written alongside, so both are selectable afterwards.

+ * + * @param displayName name entered by the operator + * @param sharedWorkedDatabase true to use the common station worked database + * @return the created profile, or null when it could not be stored + */ + public OperatorProfile createProfile(final String displayName, final boolean sharedWorkedDatabase) { + + List knownProfiles = listProfiles(); + Set takenProfileIds = new LinkedHashSet<>(); + + for (OperatorProfile existingProfile : knownProfiles) { + takenProfileIds.add(existingProfile.getProfileId()); + } + + OperatorProfile createdProfile = new OperatorProfile( + OperatorProfilePaths.toProfileId(displayName, takenProfileIds), + displayName == null || displayName.isBlank() ? "New profile" : displayName.trim(), + false, + sharedWorkedDatabase); + + knownProfiles.add(createdProfile); + + if (!profileStore.saveProfiles(knownProfiles, createdProfile.getProfileId())) { + return null; + } + + createPreferencesFile(createdProfile, null); + + return createdProfile; + } + + /** + * Creates a copy of an existing profile. + * + *

The preferences are taken over completely except for the login credentials: + * callsign and password are cleared on purpose, because a duplicate is meant for + * another operator. Antenna, locator, layout and integration settings are exactly + * what the operator does not want to enter twice.

+ * + *

The worked-station database is never copied.

+ * + * @param sourceProfile profile to copy + * @param displayName name of the new profile + * @return the created profile, or null when it could not be stored + */ + public OperatorProfile duplicateProfile(final OperatorProfile sourceProfile, final String displayName) { + + if (sourceProfile == null) { + return null; + } + + List knownProfiles = listProfiles(); + Set takenProfileIds = new LinkedHashSet<>(); + + for (OperatorProfile existingProfile : knownProfiles) { + takenProfileIds.add(existingProfile.getProfileId()); + } + + OperatorProfile createdProfile = new OperatorProfile( + OperatorProfilePaths.toProfileId(displayName, takenProfileIds), + displayName == null || displayName.isBlank() ? "Copy" : displayName.trim(), + false, + sourceProfile.isSharedWorkedDatabase()); + + knownProfiles.add(createdProfile); + + if (!profileStore.saveProfiles(knownProfiles, createdProfile.getProfileId())) { + return null; + } + + createPreferencesFile(createdProfile, sourceProfile); + + return createdProfile; + } + + /** + * Changes the visible name of a profile. The identifier and all paths stay as they are. + * + * @param profile profile to rename + * @param newDisplayName new name + * @return true if the registry was updated + */ + public boolean renameProfile(final OperatorProfile profile, final String newDisplayName) { + + if (profile == null || newDisplayName == null || newDisplayName.isBlank()) { + return false; + } + + List knownProfiles = listProfiles(); + + for (OperatorProfile currentProfile : knownProfiles) { + if (currentProfile.getProfileId().equals(profile.getProfileId())) { + currentProfile.setDisplayName(newDisplayName.trim()); + } + } + + return profileStore.saveProfiles(knownProfiles, profileStore.loadLastUsedProfileId().orElse(null)); + } + + /** + * Switches a profile between the common station database and its own one. + * + * @param profile profile to change + * @param sharedWorkedDatabase true to use the common station worked database + * @return true if the registry was updated + */ + public boolean setSharedWorkedDatabase(final OperatorProfile profile, final boolean sharedWorkedDatabase) { + + if (profile == null || profile.isRootProfile()) { + return false; + } + + List knownProfiles = listProfiles(); + + for (OperatorProfile currentProfile : knownProfiles) { + if (currentProfile.getProfileId().equals(profile.getProfileId())) { + currentProfile.setSharedWorkedDatabase(sharedWorkedDatabase); + } + } + + return profileStore.saveProfiles(knownProfiles, profileStore.loadLastUsedProfileId().orElse(null)); + } + + /** + * Removes a profile and its directory. + * + *

The root profile can never be removed, because its files are the installation + * itself. A profile using the common station database keeps that database untouched; + * only its own directory is deleted.

+ * + * @param profile profile to remove + * @return true if the profile was removed + */ + public boolean deleteProfile(final OperatorProfile profile) { + + if (profile == null || profile.isRootProfile()) { + return false; + } + + List remainingProfiles = new ArrayList<>(); + + for (OperatorProfile currentProfile : listProfiles()) { + if (!currentProfile.getProfileId().equals(profile.getProfileId())) { + remainingProfiles.add(currentProfile); + } + } + + if (!profileStore.saveProfiles(remainingProfiles, + profileStore.loadLastUsedProfileId().orElse(null))) { + return false; + } + + deleteProfileDirectory(profile); + + return true; + } + + /** + * Returns the absolute directory of a profile. + * + * @param profile profile to resolve + * @return absolute profile directory + */ + public String getProfileDirectory(final OperatorProfile profile) { + return ApplicationFileUtils.getFilePath( + ApplicationConstants.APPLICATION_NAME, + OperatorProfilePaths.profileRelativeDirectory(profile)); + } + + /** + * Creates the preferences file of a new profile. + * + *

The file is either seeded from the bundled template or copied from the source + * profile. In both cases the login credentials are cleared, so a new profile never + * carries another operator's callsign or password.

+ * + * @param createdProfile profile that needs a preferences file + * @param sourceProfile profile to copy the preferences from, or null for the template + */ + private void createPreferencesFile(final OperatorProfile createdProfile, + final OperatorProfile sourceProfile) { + + String createdRelativeFileName = OperatorProfilePaths.preferencesRelativeFileName(createdProfile); + + if (sourceProfile != null) { + copyPreferencesFile( + OperatorProfilePaths.preferencesRelativeFileName(sourceProfile), + createdRelativeFileName); + } + + // Seeds from the bundled template when nothing was copied, and always resolves + // the preferences of the new profile. + ChatPreferences createdPreferences = new ChatPreferences(createdRelativeFileName); + createdPreferences.readPreferencesFromXmlFile(); + + createdPreferences.setStn_loginCallSign(""); + createdPreferences.setStn_loginPassword(""); + + createdPreferences.writePreferencesToXmlFile(); + } + + private void copyPreferencesFile(final String sourceRelativeFileName, + final String targetRelativeFileName) { + + Path sourcePath = Path.of(ApplicationFileUtils.getFilePath( + ApplicationConstants.APPLICATION_NAME, sourceRelativeFileName)); + Path targetPath = Path.of(ApplicationFileUtils.getFilePath( + ApplicationConstants.APPLICATION_NAME, targetRelativeFileName)); + + if (!Files.isRegularFile(sourcePath)) { + return; + } + + try { + Path targetDirectory = targetPath.getParent(); + + if (targetDirectory != null) { + Files.createDirectories(targetDirectory); + } + + Files.copy(sourcePath, targetPath); + } catch (IOException e) { + LOGGER.log(Level.WARNING, + "Could not copy the preferences of the source profile, using the defaults instead", e); + } + } + + private void deleteProfileDirectory(final OperatorProfile profile) { + + Path profileDirectory = Path.of(getProfileDirectory(profile)); + + if (!Files.isDirectory(profileDirectory)) { + return; + } + + try (Stream containedPaths = Files.walk(profileDirectory)) { + List deepestFirst = containedPaths + .sorted(Comparator.reverseOrder()) + .toList(); + + for (Path currentPath : deepestFirst) { + Files.deleteIfExists(currentPath); + } + } catch (IOException e) { + LOGGER.log(Level.WARNING, + "Could not remove the directory of the deleted operator profile", e); + } + } +} diff --git a/core/src/main/java/kst4contest/controller/OperatorProfilePaths.java b/core/src/main/java/kst4contest/controller/OperatorProfilePaths.java new file mode 100644 index 00000000..810ba481 --- /dev/null +++ b/core/src/main/java/kst4contest/controller/OperatorProfilePaths.java @@ -0,0 +1,228 @@ +package kst4contest.controller; + +import kst4contest.ApplicationConstants; +import kst4contest.model.ChatPreferences; +import kst4contest.model.OperatorProfile; +import kst4contest.model.OperatorProfileSelection; + +import java.util.Collection; +import java.util.Locale; + +/** + * Derives the file names of an operator profile. + * + *

This is the single place that knows how a profile maps onto files. The registry + * stores only the shared/own flag, never a path, so the two can never drift apart.

+ */ +public final class OperatorProfilePaths { + + /** + * Directory below the application directory that holds the additional profiles. + */ + public static final String PROFILES_DIRECTORY = "profiles"; + + /** + * Identifier of the profile that uses the historic flat installation layout. + */ + public static final String ROOT_PROFILE_ID = "default"; + + /** + * Maximum length of a generated profile identifier. + */ + private static final int MAX_PROFILE_ID_LENGTH = 32; + + private OperatorProfilePaths() { + // Utility class. + } + + /** + * Builds the profile descriptor of the historic flat installation. + * + * @param displayName name to show for the root profile + * @return the root profile descriptor + */ + public static OperatorProfile buildRootProfile(final String displayName) { + return new OperatorProfile(ROOT_PROFILE_ID, displayName, true, true); + } + + /** + * Returns the profile directory relative to the application directory. + * + * @param profile profile to resolve + * @return relative directory name + */ + public static String profileRelativeDirectory(final OperatorProfile profile) { + return PROFILES_DIRECTORY + "/" + profile.getProfileId(); + } + + /** + * Returns the preferences file name relative to the application directory. + * + * @param profile profile to resolve + * @return relative preferences file name + */ + public static String preferencesRelativeFileName(final OperatorProfile profile) { + + if (profile.isRootProfile()) { + return ChatPreferences.PREFERENCES_FILE; + } + + return profileRelativeDirectory(profile) + "/" + ChatPreferences.PREFERENCES_FILE; + } + + /** + * Returns the worked-station database file name relative to the application directory. + * + *

A profile using the common station database always resolves to the historic flat + * file, which is what a multi operator station wants: the existing contest state stays + * the shared one.

+ * + * @param profile profile to resolve + * @return relative database file name + */ + public static String workedDatabaseRelativeFileName(final OperatorProfile profile) { + + if (profile.isRootProfile() || profile.isSharedWorkedDatabase()) { + return DBController.DATABASE_FILE; + } + + return profileRelativeDirectory(profile) + "/" + DBController.DATABASE_FILE; + } + + /** + * Returns the stylesheet file name relative to the application directory. + * + *

The operator's own stylesheet for one design, which is the middle of the three + * palette layers. Shaped like the preferences and the worked database: the root profile + * keeps the historic flat name, every other profile gets it inside its own directory.

+ * + *

The root profile's name is deliberately the one copyResourceIfRequired already + * writes at startup. That copy has never been read by anything; reading it is what gives + * the operator the hand-editing route the file has been promising all along.

+ * + * @param profile profile to resolve + * @param darkMode true for the evening design, false for the daylight one + * @return relative stylesheet file name + */ + public static String paletteRelativeFileName(final OperatorProfile profile, final boolean darkMode) { + + final String fileName = darkMode + ? ApplicationConstants.STYLECSSFILE_DEFAULT_EVENING + : ApplicationConstants.STYLECSSFILE_DEFAULT_DAYLIGHT; + + if (profile.isRootProfile()) { + return fileName; + } + + return profileRelativeDirectory(profile) + "/" + fileName; + } + + /** + * Resolves a profile descriptor into the runtime selection used during startup. + * + * @param profile profile to resolve + * @return resolved selection + */ + public static OperatorProfileSelection resolve(final OperatorProfile profile) { + + boolean usesSharedStationDatabase = profile.isRootProfile() || profile.isSharedWorkedDatabase(); + + return new OperatorProfileSelection( + profile, + preferencesRelativeFileName(profile), + workedDatabaseRelativeFileName(profile), + usesSharedStationDatabase + ); + } + + /** + * Derives a stable, file system safe identifier from a display name. + * + *

The identifier becomes a directory name and is never changed afterwards, so a + * later rename of the profile does not move any file.

+ * + * @param displayName name entered by the operator + * @param takenProfileIds identifiers that are already in use + * @return an identifier that is not yet taken + */ + public static String toProfileId(final String displayName, final Collection takenProfileIds) { + + StringBuilder sanitized = new StringBuilder(); + + if (displayName != null) { + String foldedDisplayName = foldGermanUmlauts(displayName.toUpperCase(Locale.ROOT)); + + for (char currentCharacter : foldedDisplayName.toCharArray()) { + boolean isAcceptable = (currentCharacter >= 'A' && currentCharacter <= 'Z') + || (currentCharacter >= '0' && currentCharacter <= '9') + || currentCharacter == '-'; + + if (isAcceptable) { + sanitized.append(currentCharacter); + } else if (sanitized.length() > 0 && sanitized.charAt(sanitized.length() - 1) != '_') { + sanitized.append('_'); + } + } + } + + while (sanitized.length() > 0 && sanitized.charAt(sanitized.length() - 1) == '_') { + sanitized.setLength(sanitized.length() - 1); + } + + if (sanitized.length() > MAX_PROFILE_ID_LENGTH) { + sanitized.setLength(MAX_PROFILE_ID_LENGTH); + } + + String candidate = sanitized.toString(); + + if (candidate.isEmpty() || ROOT_PROFILE_ID.equalsIgnoreCase(candidate)) { + candidate = "OP"; + } + + if (!isProfileIdTaken(candidate, takenProfileIds)) { + return candidate; + } + + int suffix = 2; + + while (isProfileIdTaken(candidate + "_" + suffix, takenProfileIds)) { + suffix++; + } + + return candidate + "_" + suffix; + } + + /** + * Folds German umlauts so a name like "Muller" written with an umlaut still produces a + * readable identifier instead of a placeholder character. + * + * @param upperCaseText already upper-cased text + * @return text with umlauts replaced by their base letters + */ + private static String foldGermanUmlauts(final String upperCaseText) { + return upperCaseText + .replace("\u00C4", "A") + .replace("\u00D6", "O") + .replace("\u00DC", "U") + .replace("\u00DF", "SS"); + } + + private static boolean isProfileIdTaken(final String candidate, final Collection takenProfileIds) { + + if (ROOT_PROFILE_ID.equalsIgnoreCase(candidate)) { + return true; + } + + if (takenProfileIds == null) { + return false; + } + + for (String takenProfileId : takenProfileIds) { + if (candidate.equalsIgnoreCase(takenProfileId)) { + return true; + } + } + + return false; + } +} diff --git a/core/src/main/java/kst4contest/controller/OperatorProfileStore.java b/core/src/main/java/kst4contest/controller/OperatorProfileStore.java new file mode 100644 index 00000000..c2c3e9e3 --- /dev/null +++ b/core/src/main/java/kst4contest/controller/OperatorProfileStore.java @@ -0,0 +1,386 @@ +package kst4contest.controller; + +import kst4contest.ApplicationConstants; +import kst4contest.model.OperatorProfile; +import kst4contest.utils.ApplicationFileUtils; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import javax.xml.XMLConstants; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; + +import java.io.File; +import java.io.OutputStream; +import java.nio.file.AtomicMoveNotSupportedException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Reads and writes the operator profile registry. + * + *

The registry file is created lazily. As long as an installation has only the + * historic flat layout, no registry exists and none is written, so a single operator + * installation behaves exactly as before. The file appears when the second profile is + * created; at that moment the root profile is materialised as well.

+ * + *

A missing, unreadable or malformed registry is never fatal. It is logged and + * treated like an installation without additional profiles.

+ */ +public class OperatorProfileStore { + + private static final Logger LOGGER = Logger.getLogger(OperatorProfileStore.class.getName()); + + /** + * Name of the registry file inside the application directory. + */ + public static final String PROFILES_REGISTRY_FILE = "profiles.xml"; + + private static final String TAG_ROOT = "praktiKSTProfiles"; + private static final String TAG_REGISTRY_VERSION = "registryVersion"; + private static final String TAG_LAST_USED_PROFILE_ID = "lastUsedProfileId"; + private static final String TAG_PROFILE = "profile"; + private static final String TAG_PROFILE_ID = "profileId"; + private static final String TAG_DISPLAY_NAME = "displayName"; + private static final String TAG_ROOT_PROFILE = "rootProfile"; + private static final String TAG_SHARED_WORKED_DATABASE = "sharedWorkedDatabase"; + private static final String TAG_LAST_USED_EPOCH_MS = "lastUsedEpochMs"; + + private static final int REGISTRY_VERSION = 1; + + private final String registryFilePath; + + /** + * Creates a store working on the registry of the current installation. + */ + public OperatorProfileStore() { + this(ApplicationFileUtils.getFilePath( + ApplicationConstants.APPLICATION_NAME, PROFILES_REGISTRY_FILE)); + } + + /** + * Creates a store working on an explicit registry file. + * + * @param registryFilePath absolute path of the registry file + */ + public OperatorProfileStore(final String registryFilePath) { + this.registryFilePath = registryFilePath; + } + + /** + * Returns whether a registry file exists at all. + * + * @return true if the installation already has more than the historic flat layout + */ + public boolean isRegistryPresent() { + return new File(registryFilePath).isFile(); + } + + /** + * Builds the in-memory descriptor of the historic flat installation. + * + *

Nothing is written. This keeps a single operator installation untouched.

+ * + * @return the implicit root profile + */ + public OperatorProfile buildImplicitRootProfile() { + return OperatorProfilePaths.buildRootProfile("Default"); + } + + /** + * Reads all stored profiles. + * + * @return the stored profiles, or an empty list when no usable registry exists + */ + public List loadProfiles() { + + List loadedProfiles = new ArrayList<>(); + Document document = readRegistryDocument(); + + if (document == null) { + return loadedProfiles; + } + + NodeList profileNodes = document.getElementsByTagName(TAG_PROFILE); + + for (int profileIndex = 0; profileIndex < profileNodes.getLength(); profileIndex++) { + Node currentNode = profileNodes.item(profileIndex); + + if (currentNode.getNodeType() != Node.ELEMENT_NODE) { + continue; + } + + Element profileElement = (Element) currentNode; + String profileId = readText(profileElement, TAG_PROFILE_ID); + + if (profileId == null || profileId.isBlank()) { + LOGGER.log(Level.WARNING, "Skipping operator profile entry without an identifier"); + continue; + } + + OperatorProfile loadedProfile = new OperatorProfile(); + loadedProfile.setProfileId(profileId.trim()); + loadedProfile.setDisplayName(readText(profileElement, TAG_DISPLAY_NAME)); + loadedProfile.setRootProfile(readBoolean(profileElement, TAG_ROOT_PROFILE, false)); + loadedProfile.setSharedWorkedDatabase( + readBoolean(profileElement, TAG_SHARED_WORKED_DATABASE, true)); + loadedProfile.setLastUsedEpochMs(readLong(profileElement, TAG_LAST_USED_EPOCH_MS)); + + if (loadedProfile.getDisplayName() == null || loadedProfile.getDisplayName().isBlank()) { + loadedProfile.setDisplayName(loadedProfile.getProfileId()); + } + + // The root profile always uses the common station database, because its + // database is the historic flat file itself. + if (loadedProfile.isRootProfile()) { + loadedProfile.setSharedWorkedDatabase(true); + } + + loadedProfiles.add(loadedProfile); + } + + return loadedProfiles; + } + + /** + * Reads the identifier of the profile that was activated last. + * + * @return the identifier, or empty when unknown + */ + public Optional loadLastUsedProfileId() { + + Document document = readRegistryDocument(); + + if (document == null) { + return Optional.empty(); + } + + Element rootElement = document.getDocumentElement(); + + if (rootElement == null) { + return Optional.empty(); + } + + String lastUsedProfileId = readText(rootElement, TAG_LAST_USED_PROFILE_ID); + + if (lastUsedProfileId == null || lastUsedProfileId.isBlank()) { + return Optional.empty(); + } + + return Optional.of(lastUsedProfileId.trim()); + } + + /** + * Writes the complete registry. + * + * @param profiles profiles to store + * @param lastUsedProfileId identifier of the profile that was activated last, may be null + * @return true if the registry was written + */ + public boolean saveProfiles(final List profiles, final String lastUsedProfileId) { + + try { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); + Document document = documentBuilder.newDocument(); + + Element rootElement = document.createElement(TAG_ROOT); + document.appendChild(rootElement); + + appendTextElement(document, rootElement, TAG_REGISTRY_VERSION, String.valueOf(REGISTRY_VERSION)); + + if (lastUsedProfileId != null && !lastUsedProfileId.isBlank()) { + appendTextElement(document, rootElement, TAG_LAST_USED_PROFILE_ID, lastUsedProfileId); + } + + for (OperatorProfile currentProfile : profiles) { + Element profileElement = document.createElement(TAG_PROFILE); + rootElement.appendChild(profileElement); + + appendTextElement(document, profileElement, TAG_PROFILE_ID, currentProfile.getProfileId()); + appendTextElement(document, profileElement, TAG_DISPLAY_NAME, currentProfile.getDisplayName()); + appendTextElement(document, profileElement, TAG_ROOT_PROFILE, + String.valueOf(currentProfile.isRootProfile())); + appendTextElement(document, profileElement, TAG_SHARED_WORKED_DATABASE, + String.valueOf(currentProfile.isRootProfile() || currentProfile.isSharedWorkedDatabase())); + appendTextElement(document, profileElement, TAG_LAST_USED_EPOCH_MS, + String.valueOf(currentProfile.getLastUsedEpochMs())); + } + + return writeDocumentAtomically(document); + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Could not write the operator profile registry", e); + return false; + } + } + + /** + * Records that a profile has been activated. + * + *

Does nothing when no registry exists, so a single operator installation is not + * turned into a multi profile installation by merely starting the application.

+ * + * @param profileId identifier of the activated profile + * @return true if the registry was updated + */ + public boolean recordLastUsed(final String profileId) { + + if (!isRegistryPresent()) { + return false; + } + + List storedProfiles = loadProfiles(); + + if (storedProfiles.isEmpty()) { + return false; + } + + for (OperatorProfile currentProfile : storedProfiles) { + if (currentProfile.getProfileId().equalsIgnoreCase(profileId)) { + currentProfile.setLastUsedEpochMs(System.currentTimeMillis()); + } + } + + return saveProfiles(storedProfiles, profileId); + } + + /** + * Returns the absolute path of the registry file. + * + * @return absolute registry path + */ + public String getRegistryFilePath() { + return registryFilePath; + } + + private Document readRegistryDocument() { + + File registryFile = new File(registryFilePath); + + if (!registryFile.isFile()) { + return null; + } + + try { + DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); + documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); + + return documentBuilderFactory.newDocumentBuilder().parse(registryFile); + } catch (Exception e) { + LOGGER.log(Level.WARNING, + "Could not read the operator profile registry, continuing without additional profiles", e); + return null; + } + } + + private static String readText(final Element parentElement, final String tagName) { + + NodeList matchingNodes = parentElement.getElementsByTagName(tagName); + + if (matchingNodes.getLength() == 0) { + return null; + } + + return matchingNodes.item(0).getTextContent(); + } + + private static boolean readBoolean(final Element parentElement, + final String tagName, + final boolean defaultValue) { + + String rawValue = readText(parentElement, tagName); + + if (rawValue == null || rawValue.isBlank()) { + return defaultValue; + } + + return Boolean.parseBoolean(rawValue.trim()); + } + + private static long readLong(final Element parentElement, final String tagName) { + + String rawValue = readText(parentElement, tagName); + + if (rawValue == null || rawValue.isBlank()) { + return 0L; + } + + try { + return Long.parseLong(rawValue.trim()); + } catch (NumberFormatException e) { + return 0L; + } + } + + private static void appendTextElement(final Document document, + final Element parentElement, + final String tagName, + final String textContent) { + + Element createdElement = document.createElement(tagName); + createdElement.setTextContent(textContent == null ? "" : textContent); + parentElement.appendChild(createdElement); + } + + /** + * Writes the registry through a temporary file so a crash can never leave a + * half-written registry behind. This mirrors the established preferences writer. + * + * @param document document to write + * @return true if the registry file was replaced + */ + private boolean writeDocumentAtomically(final Document document) { + + Path targetPath = Path.of(registryFilePath).toAbsolutePath(); + Path parentDirectory = targetPath.getParent(); + + if (parentDirectory == null) { + LOGGER.log(Level.SEVERE, + "The operator profile registry path has no directory: {0}", registryFilePath); + return false; + } + + try { + Files.createDirectories(parentDirectory); + + // The temporary file has to live next to the target so the final move can be + // atomic; both must be on the same file system. + Path temporaryPath = Files.createTempFile( + parentDirectory, PROFILES_REGISTRY_FILE, ".tmp"); + + Transformer transformer = TransformerFactory.newInstance().newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); + + try (OutputStream outputStream = Files.newOutputStream(temporaryPath)) { + transformer.transform(new DOMSource(document), new StreamResult(outputStream)); + } + + try { + Files.move(temporaryPath, targetPath, + StandardCopyOption.REPLACE_EXISTING, StandardCopyOption.ATOMIC_MOVE); + } catch (AtomicMoveNotSupportedException atomicMoveUnsupported) { + Files.move(temporaryPath, targetPath, StandardCopyOption.REPLACE_EXISTING); + } + + return true; + } catch (Exception e) { + LOGGER.log(Level.SEVERE, "Could not store the operator profile registry", e); + return false; + } + } +} diff --git a/src/main/java/kst4contest/controller/PstRotatorClient.java b/core/src/main/java/kst4contest/controller/PstRotatorClient.java similarity index 100% rename from src/main/java/kst4contest/controller/PstRotatorClient.java rename to core/src/main/java/kst4contest/controller/PstRotatorClient.java diff --git a/src/main/java/kst4contest/controller/ReachabilityService.java b/core/src/main/java/kst4contest/controller/ReachabilityService.java similarity index 98% rename from src/main/java/kst4contest/controller/ReachabilityService.java rename to core/src/main/java/kst4contest/controller/ReachabilityService.java index a12f07d7..42dda3d5 100644 --- a/src/main/java/kst4contest/controller/ReachabilityService.java +++ b/core/src/main/java/kst4contest/controller/ReachabilityService.java @@ -10,7 +10,6 @@ import java.util.Locale; import java.util.Map; import java.util.function.Consumer; -import javafx.application.Platform; import kst4contest.locatorUtils.Location; import kst4contest.model.Band; import kst4contest.model.ChatMember; @@ -377,10 +376,10 @@ public final class ReachabilityService { chatController.fireUserListUpdate("Reachability calculated"); }; - if (Platform.isFxApplicationThread()) { + if (chatController.uiDispatcher().isUiThread()) { updateTask.run(); } else { - Platform.runLater(updateTask); + chatController.uiDispatcher().runOnUi(updateTask); } }); } @@ -518,8 +517,8 @@ public final class ReachabilityService { return latestFrequencyInfo.frequency; } - if (member != null && member.getFrequency() != null && member.getFrequency().getValue() != null) { - double parsedFrequencyMHz = PathGeometryUtils.tryParseFrequencyMHz(member.getFrequency().getValue()); + if (member != null && member.getFrequency() != null && member.getFrequency().get() != null) { + double parsedFrequencyMHz = PathGeometryUtils.tryParseFrequencyMHz(member.getFrequency().get()); if (Double.isFinite(parsedFrequencyMHz) && parsedFrequencyMHz > 0.0) { Band parsedBand = Band.fromFrequency(parsedFrequencyMHz); if (parsedBand == null || parsedBand == band) { @@ -583,10 +582,10 @@ public final class ReachabilityService { return; } - if (Platform.isFxApplicationThread()) { + if (chatController.uiDispatcher().isUiThread()) { fxCallback.accept(result); } else { - Platform.runLater(() -> fxCallback.accept(result)); + chatController.uiDispatcher().runOnUi(() -> fxCallback.accept(result)); } } diff --git a/src/main/java/kst4contest/controller/ReadThread.java b/core/src/main/java/kst4contest/controller/ReadThread.java similarity index 100% rename from src/main/java/kst4contest/controller/ReadThread.java rename to core/src/main/java/kst4contest/controller/ReadThread.java diff --git a/src/main/java/kst4contest/controller/ReadUDPByWintestThread.java b/core/src/main/java/kst4contest/controller/ReadUDPByWintestThread.java similarity index 99% rename from src/main/java/kst4contest/controller/ReadUDPByWintestThread.java rename to core/src/main/java/kst4contest/controller/ReadUDPByWintestThread.java index 6b276499..b74358dd 100644 --- a/src/main/java/kst4contest/controller/ReadUDPByWintestThread.java +++ b/core/src/main/java/kst4contest/controller/ReadUDPByWintestThread.java @@ -1,6 +1,5 @@ package kst4contest.controller; -import javafx.application.Platform; import kst4contest.ApplicationConstants; import kst4contest.model.ChatMember; import kst4contest.model.ThreadStateMessage; @@ -568,7 +567,7 @@ public class ReadUDPByWintestThread extends Thread { if (client .getChatPreferences() .isLogsynch_wintestQrgSyncEnabled()) { - Platform.runLater( + client.uiDispatcher().runOnUi( () -> client .getChatPreferences() .getMYQRGFirstCat() diff --git a/src/main/java/kst4contest/controller/ReadUDPByWintestThreadTest.java b/core/src/main/java/kst4contest/controller/ReadUDPByWintestThreadTest.java similarity index 100% rename from src/main/java/kst4contest/controller/ReadUDPByWintestThreadTest.java rename to core/src/main/java/kst4contest/controller/ReadUDPByWintestThreadTest.java diff --git a/src/main/java/kst4contest/controller/ReadUDPbyAirScoutMessageThread.java b/core/src/main/java/kst4contest/controller/ReadUDPbyAirScoutMessageThread.java similarity index 98% rename from src/main/java/kst4contest/controller/ReadUDPbyAirScoutMessageThread.java rename to core/src/main/java/kst4contest/controller/ReadUDPbyAirScoutMessageThread.java index adef1261..2187b290 100644 --- a/src/main/java/kst4contest/controller/ReadUDPbyAirScoutMessageThread.java +++ b/core/src/main/java/kst4contest/controller/ReadUDPbyAirScoutMessageThread.java @@ -9,9 +9,8 @@ import java.net.SocketTimeoutException; import java.util.Comparator; import java.util.List; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; import kst4contest.ApplicationConstants; +import java.util.ArrayList; import kst4contest.model.AirPlane; import kst4contest.model.AirPlaneReflectionInfo; import kst4contest.model.ChatMember; @@ -275,7 +274,7 @@ public class ReadUDPbyAirScoutMessageThread extends Thread { String[] fullStringSplitter; String[] apStringSplitter; AirPlaneReflectionInfo apInfo = new AirPlaneReflectionInfo(); - ObservableList airplaneList = FXCollections.observableArrayList(); + List airplaneList = new ArrayList<>(); if (udpStringToProcess.contains("ASNEAREST: ")) { udpStringToProcess = udpStringToProcess.replace("ASNEAREST: ", ""); diff --git a/src/main/java/kst4contest/controller/ReadUDPbyUCXMessageThread.java b/core/src/main/java/kst4contest/controller/ReadUDPbyUCXMessageThread.java similarity index 99% rename from src/main/java/kst4contest/controller/ReadUDPbyUCXMessageThread.java rename to core/src/main/java/kst4contest/controller/ReadUDPbyUCXMessageThread.java index b09970f3..05208720 100644 --- a/src/main/java/kst4contest/controller/ReadUDPbyUCXMessageThread.java +++ b/core/src/main/java/kst4contest/controller/ReadUDPbyUCXMessageThread.java @@ -22,7 +22,6 @@ import org.xml.sax.SAXException; import kst4contest.model.ChatMember; import kst4contest.model.Band; -import javafx.application.Platform; /** * This thread is responsible for reading server's input and printing it to the @@ -584,10 +583,10 @@ public class ReadUDPbyUCXMessageThread extends Thread { return; } - if (Platform.isFxApplicationThread()) { + if (client.uiDispatcher().isUiThread()) { runnable.run(); } else { - Platform.runLater(runnable); + client.uiDispatcher().runOnUi(runnable); } } diff --git a/src/main/java/kst4contest/controller/RegexTester.java b/core/src/main/java/kst4contest/controller/RegexTester.java similarity index 100% rename from src/main/java/kst4contest/controller/RegexTester.java rename to core/src/main/java/kst4contest/controller/RegexTester.java diff --git a/src/main/java/kst4contest/controller/ScoreService.java b/core/src/main/java/kst4contest/controller/ScoreService.java similarity index 88% rename from src/main/java/kst4contest/controller/ScoreService.java rename to core/src/main/java/kst4contest/controller/ScoreService.java index 20fcfe37..8b72f5be 100644 --- a/src/main/java/kst4contest/controller/ScoreService.java +++ b/core/src/main/java/kst4contest/controller/ScoreService.java @@ -1,13 +1,11 @@ package kst4contest.controller; -import javafx.application.Platform; -import javafx.beans.property.LongProperty; -import javafx.beans.property.ReadOnlyDoubleProperty; -import javafx.beans.property.ReadOnlyDoubleWrapper; -import javafx.beans.property.SimpleLongProperty; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; import kst4contest.logic.PriorityCalculator; +import kst4contest.observe.MutableValue; +import kst4contest.observe.ObservableRoster; +import kst4contest.observe.ObservableValue; +import kst4contest.observe.SimpleRoster; +import kst4contest.observe.SimpleValue; import kst4contest.model.ChatCategory; import kst4contest.model.ChatMember; import kst4contest.model.ChatPreferences; @@ -17,14 +15,11 @@ import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -import javafx.beans.property.ObjectProperty; -import javafx.beans.property.ReadOnlyObjectProperty; -import javafx.beans.property.SimpleObjectProperty; /** * Calculates priority scores off the JavaFX thread and publishes a small UI model. * * Design goals: - * - No per-member Platform.runLater flooding. + * - No per-member UI hand-off flooding. * - Score is computed once per callsignRaw (e.g. "SM6VTZ"), even if it exists in multiple chat categories. * - A routing hint (preferred ChatCategory) is kept using "last inbound category" if available. */ @@ -42,15 +37,15 @@ public final class ScoreService { private final AtomicReference latestSnapshot = new AtomicReference<>(ScoreSnapshot.empty()); // UI outputs - private final ObservableList topCandidatesFx = FXCollections.observableArrayList(); - private final ReadOnlyDoubleWrapper selectedCallPriorityScore = new ReadOnlyDoubleWrapper(Double.NaN); - private final LongProperty uiPulse = new SimpleLongProperty(0); + private final SimpleRoster topCandidates = new SimpleRoster<>(); + private final MutableValue selectedCallPriorityScore = new SimpleValue<>(Double.NaN); + private final MutableValue uiPulse = new SimpleValue<>(0L); private volatile String selectedCallSignRaw; private volatile long lastComputedEpochMs = 0L; private final int topN; - private final ObjectProperty selectedChatMember = new SimpleObjectProperty<>(null); + private final MutableValue selectedChatMember = new SimpleValue<>(null); public ScoreService(ChatController controller, PriorityCalculator priorityCalculator, int topN) { @@ -59,19 +54,19 @@ public final class ScoreService { this.topN = topN > 0 ? topN : DEFAULT_TOP_N; } - public ObservableList getTopCandidatesFx() { - return topCandidatesFx; + public ObservableRoster topCandidates() { + return topCandidates; } - public ReadOnlyDoubleProperty selectedCallPriorityScoreProperty() { - return selectedCallPriorityScore.getReadOnlyProperty(); + public ObservableValue selectedCallPriorityScore() { + return selectedCallPriorityScore; } /** * A lightweight UI invalidation signal that increments after every published snapshot. * Consumers can refresh small panels (timeline/toplist), but should avoid refreshing huge tables. */ - public LongProperty uiPulseProperty() { + public ObservableValue uiPulse() { return uiPulse; } @@ -88,19 +83,19 @@ public final class ScoreService { public void setSelectedChatMember(ChatMember member) { // keep a central selection for UI actions (FurtherInfo buttons, timeline clicks, etc.) - if (Platform.isFxApplicationThread()) { + if (controller.uiDispatcher().isUiThread()) { selectedChatMember.set(member); } else { - Platform.runLater(() -> selectedChatMember.set(member)); + controller.uiDispatcher().runOnUi(() -> selectedChatMember.set(member)); } selectedCallSignRaw = member == null ? null : normalizeCallRaw(member.getCallSignRaw()); // Update score immediately from the latest snapshot - if (Platform.isFxApplicationThread()) { + if (controller.uiDispatcher().isUiThread()) { updateSelectedScoreFromSnapshot(latestSnapshot.get()); } else { - Platform.runLater(() -> updateSelectedScoreFromSnapshot(latestSnapshot.get())); + controller.uiDispatcher().runOnUi(() -> updateSelectedScoreFromSnapshot(latestSnapshot.get())); } } @@ -191,12 +186,12 @@ public final class ScoreService { latestSnapshot.set(snap); lastComputedEpochMs = nowEpochMs; - // 4) Publish to UI in ONE batched runLater - Platform.runLater(() -> { + // 4) Publish to UI in ONE batched hand-off + controller.uiDispatcher().runOnUi(() -> { applyScoreSnapshotToChatMembers(snap); - topCandidatesFx.setAll(snap.getTopCandidates()); + topCandidates.setAll(snap.getTopCandidates()); updateSelectedScoreFromSnapshot(snap); - uiPulse.set(uiPulse.get() + 1); + uiPulse.set(uiPulse.get() + 1L); }); } @@ -349,7 +344,7 @@ public final class ScoreService { public List getTopCandidates() { return topCandidates; } } - public ReadOnlyObjectProperty selectedChatMemberProperty() { + public ObservableValue selectedChatMember() { return selectedChatMember; } diff --git a/src/main/java/kst4contest/controller/ScoreboardUpdateTask.java b/core/src/main/java/kst4contest/controller/ScoreboardUpdateTask.java similarity index 100% rename from src/main/java/kst4contest/controller/ScoreboardUpdateTask.java rename to core/src/main/java/kst4contest/controller/ScoreboardUpdateTask.java diff --git a/src/main/java/kst4contest/controller/SkedReminderService.java b/core/src/main/java/kst4contest/controller/SkedReminderService.java similarity index 88% rename from src/main/java/kst4contest/controller/SkedReminderService.java rename to core/src/main/java/kst4contest/controller/SkedReminderService.java index 99e16f90..5bb9ad5e 100644 --- a/src/main/java/kst4contest/controller/SkedReminderService.java +++ b/core/src/main/java/kst4contest/controller/SkedReminderService.java @@ -1,6 +1,5 @@ package kst4contest.controller; -import javafx.application.Platform; import kst4contest.model.ChatCategory; import kst4contest.model.ThreadStateMessage; @@ -33,6 +32,24 @@ public final class SkedReminderService { this.controller = controller; } + /** + * Cancels every armed reminder and stops the scheduler thread. + * + *

Called when the runtime that owns this service is torn down, so a discarded + * runtime does not keep a thread and pending reminders alive.

+ */ + public void shutdown() { + + for (List> remindersOfOneCall : scheduledByCallRaw.values()) { + for (ScheduledFuture armedReminder : remindersOfOneCall) { + armedReminder.cancel(false); + } + } + + scheduledByCallRaw.clear(); + scheduler.shutdownNow(); + } + /** * Arms reminders for one sked. Existing reminders for this call are cancelled. * diff --git a/src/main/java/kst4contest/controller/StartChat.java b/core/src/main/java/kst4contest/controller/StartChat.java similarity index 84% rename from src/main/java/kst4contest/controller/StartChat.java rename to core/src/main/java/kst4contest/controller/StartChat.java index 37bf4350..e16a7305 100644 --- a/src/main/java/kst4contest/controller/StartChat.java +++ b/core/src/main/java/kst4contest/controller/StartChat.java @@ -3,8 +3,6 @@ */ package kst4contest.controller; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.value.ObservableStringValue; import java.io.IOException; diff --git a/src/main/java/kst4contest/controller/StationMetricsService.java b/core/src/main/java/kst4contest/controller/StationMetricsService.java similarity index 100% rename from src/main/java/kst4contest/controller/StationMetricsService.java rename to core/src/main/java/kst4contest/controller/StationMetricsService.java diff --git a/src/main/java/kst4contest/controller/StatusUpdateListener.java b/core/src/main/java/kst4contest/controller/StatusUpdateListener.java similarity index 100% rename from src/main/java/kst4contest/controller/StatusUpdateListener.java rename to core/src/main/java/kst4contest/controller/StatusUpdateListener.java diff --git a/src/main/java/kst4contest/controller/ThreadStatusCallback.java b/core/src/main/java/kst4contest/controller/ThreadStatusCallback.java similarity index 100% rename from src/main/java/kst4contest/controller/ThreadStatusCallback.java rename to core/src/main/java/kst4contest/controller/ThreadStatusCallback.java diff --git a/src/main/java/kst4contest/controller/UCXLogFileToHashsetParser.java b/core/src/main/java/kst4contest/controller/UCXLogFileToHashsetParser.java similarity index 100% rename from src/main/java/kst4contest/controller/UCXLogFileToHashsetParser.java rename to core/src/main/java/kst4contest/controller/UCXLogFileToHashsetParser.java diff --git a/src/main/java/kst4contest/controller/UpdateChecker.java b/core/src/main/java/kst4contest/controller/UpdateChecker.java similarity index 100% rename from src/main/java/kst4contest/controller/UpdateChecker.java rename to core/src/main/java/kst4contest/controller/UpdateChecker.java diff --git a/src/main/java/kst4contest/controller/UserActualizationTask.java b/core/src/main/java/kst4contest/controller/UserActualizationTask.java similarity index 100% rename from src/main/java/kst4contest/controller/UserActualizationTask.java rename to core/src/main/java/kst4contest/controller/UserActualizationTask.java diff --git a/src/main/java/kst4contest/controller/Utils4KST.java b/core/src/main/java/kst4contest/controller/Utils4KST.java similarity index 98% rename from src/main/java/kst4contest/controller/Utils4KST.java rename to core/src/main/java/kst4contest/controller/Utils4KST.java index aeaad7f9..4429ce7e 100644 --- a/src/main/java/kst4contest/controller/Utils4KST.java +++ b/core/src/main/java/kst4contest/controller/Utils4KST.java @@ -1,6 +1,6 @@ package kst4contest.controller; -import javafx.beans.property.SimpleStringProperty; +import kst4contest.observe.ObservableValue; import java.text.DateFormat; import java.text.SimpleDateFormat; @@ -119,7 +119,7 @@ public class Utils4KST { */ public static String normalizeFrequencyString( String qrgString, - SimpleStringProperty optionalPrefix + ObservableValue optionalPrefix ) { if (qrgString == null || qrgString.isBlank()) { return ""; @@ -190,7 +190,7 @@ public class Utils4KST { String fallbackPrefix = optionalPrefix == null ? null - : optionalPrefix.getValue(); + : optionalPrefix.get(); if (fallbackPrefix == null) { return ""; diff --git a/src/main/java/kst4contest/controller/WinTestIhaveInventory.java b/core/src/main/java/kst4contest/controller/WinTestIhaveInventory.java similarity index 100% rename from src/main/java/kst4contest/controller/WinTestIhaveInventory.java rename to core/src/main/java/kst4contest/controller/WinTestIhaveInventory.java diff --git a/src/main/java/kst4contest/controller/WinTestLogSegment.java b/core/src/main/java/kst4contest/controller/WinTestLogSegment.java similarity index 100% rename from src/main/java/kst4contest/controller/WinTestLogSegment.java rename to core/src/main/java/kst4contest/controller/WinTestLogSegment.java diff --git a/src/main/java/kst4contest/controller/WinTestLogSyncService.java b/core/src/main/java/kst4contest/controller/WinTestLogSyncService.java similarity index 100% rename from src/main/java/kst4contest/controller/WinTestLogSyncService.java rename to core/src/main/java/kst4contest/controller/WinTestLogSyncService.java diff --git a/src/main/java/kst4contest/controller/WinTestMessage.java b/core/src/main/java/kst4contest/controller/WinTestMessage.java similarity index 100% rename from src/main/java/kst4contest/controller/WinTestMessage.java rename to core/src/main/java/kst4contest/controller/WinTestMessage.java diff --git a/src/main/java/kst4contest/controller/WinTestNetworkAddressResolver.java b/core/src/main/java/kst4contest/controller/WinTestNetworkAddressResolver.java similarity index 100% rename from src/main/java/kst4contest/controller/WinTestNetworkAddressResolver.java rename to core/src/main/java/kst4contest/controller/WinTestNetworkAddressResolver.java diff --git a/src/main/java/kst4contest/controller/WinTestPacket.java b/core/src/main/java/kst4contest/controller/WinTestPacket.java similarity index 100% rename from src/main/java/kst4contest/controller/WinTestPacket.java rename to core/src/main/java/kst4contest/controller/WinTestPacket.java diff --git a/src/main/java/kst4contest/controller/WinTestSkedSender.java b/core/src/main/java/kst4contest/controller/WinTestSkedSender.java similarity index 100% rename from src/main/java/kst4contest/controller/WinTestSkedSender.java rename to core/src/main/java/kst4contest/controller/WinTestSkedSender.java diff --git a/src/main/java/kst4contest/controller/WorkedGrossFieldCache.java b/core/src/main/java/kst4contest/controller/WorkedGrossFieldCache.java similarity index 100% rename from src/main/java/kst4contest/controller/WorkedGrossFieldCache.java rename to core/src/main/java/kst4contest/controller/WorkedGrossFieldCache.java diff --git a/src/main/java/kst4contest/controller/WriteThread.java b/core/src/main/java/kst4contest/controller/WriteThread.java similarity index 100% rename from src/main/java/kst4contest/controller/WriteThread.java rename to core/src/main/java/kst4contest/controller/WriteThread.java diff --git a/src/main/java/kst4contest/controller/interfaces/PstRotatorEventListener.java b/core/src/main/java/kst4contest/controller/interfaces/PstRotatorEventListener.java similarity index 100% rename from src/main/java/kst4contest/controller/interfaces/PstRotatorEventListener.java rename to core/src/main/java/kst4contest/controller/interfaces/PstRotatorEventListener.java diff --git a/src/main/java/kst4contest/controller/keepAliveMessageSenderTask.java b/core/src/main/java/kst4contest/controller/keepAliveMessageSenderTask.java similarity index 100% rename from src/main/java/kst4contest/controller/keepAliveMessageSenderTask.java rename to core/src/main/java/kst4contest/controller/keepAliveMessageSenderTask.java diff --git a/src/main/java/kst4contest/locatorUtils/Angle.java b/core/src/main/java/kst4contest/locatorUtils/Angle.java similarity index 100% rename from src/main/java/kst4contest/locatorUtils/Angle.java rename to core/src/main/java/kst4contest/locatorUtils/Angle.java diff --git a/src/main/java/kst4contest/locatorUtils/DirectionUtils.java b/core/src/main/java/kst4contest/locatorUtils/DirectionUtils.java similarity index 100% rename from src/main/java/kst4contest/locatorUtils/DirectionUtils.java rename to core/src/main/java/kst4contest/locatorUtils/DirectionUtils.java diff --git a/src/main/java/kst4contest/locatorUtils/Latitude.java b/core/src/main/java/kst4contest/locatorUtils/Latitude.java similarity index 100% rename from src/main/java/kst4contest/locatorUtils/Latitude.java rename to core/src/main/java/kst4contest/locatorUtils/Latitude.java diff --git a/src/main/java/kst4contest/locatorUtils/Location.java b/core/src/main/java/kst4contest/locatorUtils/Location.java similarity index 100% rename from src/main/java/kst4contest/locatorUtils/Location.java rename to core/src/main/java/kst4contest/locatorUtils/Location.java diff --git a/src/main/java/kst4contest/locatorUtils/Longitude.java b/core/src/main/java/kst4contest/locatorUtils/Longitude.java similarity index 100% rename from src/main/java/kst4contest/locatorUtils/Longitude.java rename to core/src/main/java/kst4contest/locatorUtils/Longitude.java diff --git a/src/main/java/kst4contest/locatorUtils/TestLocatorUtils.java b/core/src/main/java/kst4contest/locatorUtils/TestLocatorUtils.java similarity index 100% rename from src/main/java/kst4contest/locatorUtils/TestLocatorUtils.java rename to core/src/main/java/kst4contest/locatorUtils/TestLocatorUtils.java diff --git a/src/main/java/kst4contest/logic/BandOpportunityResolver.java b/core/src/main/java/kst4contest/logic/BandOpportunityResolver.java similarity index 100% rename from src/main/java/kst4contest/logic/BandOpportunityResolver.java rename to core/src/main/java/kst4contest/logic/BandOpportunityResolver.java diff --git a/src/main/java/kst4contest/logic/FrequencyTextParser.java b/core/src/main/java/kst4contest/logic/FrequencyTextParser.java similarity index 100% rename from src/main/java/kst4contest/logic/FrequencyTextParser.java rename to core/src/main/java/kst4contest/logic/FrequencyTextParser.java diff --git a/src/main/java/kst4contest/logic/PriorityCalculator.java b/core/src/main/java/kst4contest/logic/PriorityCalculator.java similarity index 99% rename from src/main/java/kst4contest/logic/PriorityCalculator.java rename to core/src/main/java/kst4contest/logic/PriorityCalculator.java index 0a3d341c..0c936e07 100644 --- a/src/main/java/kst4contest/logic/PriorityCalculator.java +++ b/core/src/main/java/kst4contest/logic/PriorityCalculator.java @@ -145,7 +145,7 @@ public class PriorityCalculator { // 5) BOOST IDEA #1: Beam direction match (within beamwidth) // -------------------------------------------------------------------- if (member.getQTFdirection() != null) { - double myAz = prefs.getActualQTF().getValue(); + double myAz = prefs.getActualQTF().get(); double targetAz = member.getQTFdirection(); double diff = minimalAngleDiffDeg(myAz, targetAz); diff --git a/src/main/java/kst4contest/logic/PropagationFrequencyResolver.java b/core/src/main/java/kst4contest/logic/PropagationFrequencyResolver.java similarity index 100% rename from src/main/java/kst4contest/logic/PropagationFrequencyResolver.java rename to core/src/main/java/kst4contest/logic/PropagationFrequencyResolver.java diff --git a/src/main/java/kst4contest/logic/SignalDetector.java b/core/src/main/java/kst4contest/logic/SignalDetector.java similarity index 100% rename from src/main/java/kst4contest/logic/SignalDetector.java rename to core/src/main/java/kst4contest/logic/SignalDetector.java diff --git a/src/main/java/kst4contest/model/AirPlane.java b/core/src/main/java/kst4contest/model/AirPlane.java similarity index 100% rename from src/main/java/kst4contest/model/AirPlane.java rename to core/src/main/java/kst4contest/model/AirPlane.java diff --git a/src/main/java/kst4contest/model/AirPlaneReflectionInfo.java b/core/src/main/java/kst4contest/model/AirPlaneReflectionInfo.java similarity index 83% rename from src/main/java/kst4contest/model/AirPlaneReflectionInfo.java rename to core/src/main/java/kst4contest/model/AirPlaneReflectionInfo.java index fbb75380..eaa155af 100644 --- a/src/main/java/kst4contest/model/AirPlaneReflectionInfo.java +++ b/core/src/main/java/kst4contest/model/AirPlaneReflectionInfo.java @@ -1,13 +1,13 @@ package kst4contest.model; -import javafx.collections.ObservableList; +import java.util.List; public class AirPlaneReflectionInfo { String date; ChatMember sender, receiver; int airPlanesReachableCntr; - ObservableList risingAirplanes; + List risingAirplanes; public String getDate() { return date; @@ -41,11 +41,11 @@ public class AirPlaneReflectionInfo { this.airPlanesReachableCntr = airPlanesReachableCntr; } - public ObservableList getRisingAirplanes() { + public List getRisingAirplanes() { return risingAirplanes; } - public void setRisingAirplanes(ObservableList risingAirplanes) { + public void setRisingAirplanes(List risingAirplanes) { this.risingAirplanes = risingAirplanes; } diff --git a/src/main/java/kst4contest/model/Band.java b/core/src/main/java/kst4contest/model/Band.java similarity index 100% rename from src/main/java/kst4contest/model/Band.java rename to core/src/main/java/kst4contest/model/Band.java diff --git a/src/main/java/kst4contest/model/ChatCategory.java b/core/src/main/java/kst4contest/model/ChatCategory.java similarity index 100% rename from src/main/java/kst4contest/model/ChatCategory.java rename to core/src/main/java/kst4contest/model/ChatCategory.java diff --git a/src/main/java/kst4contest/model/ChatMember.java b/core/src/main/java/kst4contest/model/ChatMember.java similarity index 96% rename from src/main/java/kst4contest/model/ChatMember.java rename to core/src/main/java/kst4contest/model/ChatMember.java index c2686a27..84b1d640 100644 --- a/src/main/java/kst4contest/model/ChatMember.java +++ b/core/src/main/java/kst4contest/model/ChatMember.java @@ -6,11 +6,9 @@ import java.util.Locale; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; -import javafx.beans.property.SimpleBooleanProperty; -import javafx.beans.property.BooleanProperty; -import javafx.beans.property.SimpleStringProperty; -import javafx.beans.property.StringProperty; import java.util.OptionalDouble; +import kst4contest.observe.MutableValue; +import kst4contest.observe.SimpleValue; public class ChatMember { @@ -39,7 +37,7 @@ public class ChatMember { // String frequency; // last known qrg of the station - StringProperty frequency = new SimpleStringProperty(); + MutableValue frequency = new SimpleValue<>(); String password; // only used by own instance of the chatmember instance to login to the chat ChatCategory chatCategory; //Source category @@ -507,13 +505,13 @@ public class ChatMember { this.name = name; } - public StringProperty getFrequency() { + public MutableValue getFrequency() { return frequency; // return frequency; } - public void setFrequency(StringProperty frequency) { + public void setFrequency(MutableValue frequency) { this.frequency = frequency; } @@ -613,7 +611,7 @@ public class ChatMember { } if (frequency == null) { - frequency = new SimpleStringProperty(); + frequency = new SimpleValue<>(); } String currentFrequency = frequency.get(); @@ -689,6 +687,13 @@ public class ChatMember { * @param anotherChatMember * @return */ + /* + * Deliberately an overload of equals, not an override of equals(Object). + * FxRosterBinding compares a mirror against a freshly derived list and relies + * on List.equals falling back to reference comparison; with a real override two + * different rows sharing a callsign would compare equal and a genuine change + * could be dropped. Do not "fix" the signature without looking there first. + */ public boolean equals(ChatMember anotherChatMember) { if (this.getCallSign().toUpperCase().equals(anotherChatMember.getCallSign().toUpperCase())) { return true; diff --git a/src/main/java/kst4contest/model/ChatMemberDirectionOpportunityTest.java b/core/src/main/java/kst4contest/model/ChatMemberDirectionOpportunityTest.java similarity index 100% rename from src/main/java/kst4contest/model/ChatMemberDirectionOpportunityTest.java rename to core/src/main/java/kst4contest/model/ChatMemberDirectionOpportunityTest.java diff --git a/src/main/java/kst4contest/model/ChatMessage.java b/core/src/main/java/kst4contest/model/ChatMessage.java similarity index 100% rename from src/main/java/kst4contest/model/ChatMessage.java rename to core/src/main/java/kst4contest/model/ChatMessage.java diff --git a/src/main/java/kst4contest/model/ChatPreferences.java b/core/src/main/java/kst4contest/model/ChatPreferences.java similarity index 93% rename from src/main/java/kst4contest/model/ChatPreferences.java rename to core/src/main/java/kst4contest/model/ChatPreferences.java index 5e9936d4..45230b3c 100644 --- a/src/main/java/kst4contest/model/ChatPreferences.java +++ b/core/src/main/java/kst4contest/model/ChatPreferences.java @@ -23,7 +23,6 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; -import javafx.beans.property.*; import kst4contest.ApplicationConstants; import kst4contest.utils.ApplicationFileUtils; import org.w3c.dom.Document; @@ -32,8 +31,9 @@ import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; -import javafx.collections.FXCollections; -import javafx.collections.ObservableList; +import kst4contest.observe.MutableValue; +import kst4contest.observe.SimpleRoster; +import kst4contest.observe.SimpleValue; /** * refactored version if ChatPreferences @@ -50,7 +50,13 @@ public class ChatPreferences { /** - * Bump this when you change the XML schema written by {@link #writePreferencesToXmlFile()}. + * Bump this when a change to the XML schema needs a reader to act on the version. + *

+ * Adding an element does not: reading must stay backwards compatible, every setting falls + * back to its own default, and nothing in this application branches on the number -- the + * only use is a best-effort warning when a file is newer than the application. Release + * 1.50 added the two palette-override elements and deliberately left this at 7. A bump + * that no reader acts on only invites the next person to bump it again. *

* Reading must stay backwards compatible: missing/unknown tags should fall back to defaults. */ @@ -79,7 +85,7 @@ public class ChatPreferences { * TODO: delete this from the kst4contest.view/Main.java! */ public ChatPreferences() { - ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, PREFERENCE_RESOURCE, PREFERENCES_FILE); + this(PREFERENCES_FILE); } /** @@ -93,6 +99,25 @@ public class ChatPreferences { throw new IllegalArgumentException("Preferences file must not be null"); } storeAndRestorePreferencesFileName = preferencesFile.toString(); + } + + /** + * Creates preferences bound to one operator profile. + * + *

The file name is resolved below the application directory, so both + * "preferences.xml" for the root installation and "profiles/OP2/preferences.xml" + * for an additional operator profile are valid. A missing file is seeded from the + * bundled template, which gives a new profile the same clean defaults a first-ever + * installation gets.

+ * + * @param applicationRelativeFileName preferences file name relative to the application directory + */ + public ChatPreferences(final String applicationRelativeFileName) { + ApplicationFileUtils.copyResourceIfRequired(ApplicationConstants.APPLICATION_NAME, PREFERENCE_RESOURCE, applicationRelativeFileName); + this.storeAndRestorePreferencesFileName = ApplicationFileUtils.getFilePath( + ApplicationConstants.APPLICATION_NAME, + applicationRelativeFileName + ); // lstNotify_QSOSniffer_sniffedCallSignList.add("DF0GEB"); @@ -181,8 +206,14 @@ public class ChatPreferences { int stn_pstRotatorPort = 12000; boolean stn_loginAFKState = false; //always start as here - String stn_loginCallSign = "do5amf"; - String stn_loginCallSignRaw = "do5amf"; //for example: do5amf instead of logincallsign do5amf-2 + /* + * The login credentials default to empty on purpose. A missing or empty value in + * preferences.xml means "not configured yet", and falling back to a real callsign + * would let an operator transmit under someone else's call. This matters for every + * additional operator profile, whose preferences are created without credentials. + */ + String stn_loginCallSign = ""; + String stn_loginCallSignRaw = ""; //for example: do5amf instead of logincallsign do5amf-2 String stn_loginPassword = ""; String stn_loginNameMainCat = "KST4Contest"; String stn_loginNameSecondCat = "KST4ContestSHF"; @@ -213,7 +244,7 @@ public class ChatPreferences { ChatCategory loginChatCategoryMain = new ChatCategory(2); ChatCategory loginChatCategorySecond = new ChatCategory(3); boolean loginToSecondChatEnabled; - DoubleProperty actualQTF = new SimpleDoubleProperty(360); // will be updated by user at runtime! + MutableValue actualQTF = new SimpleValue<>(360.0); // will be updated by user at runtime! boolean stn_bandActive50; boolean stn_bandActive70; @@ -251,9 +282,9 @@ public class ChatPreferences { /** * TRX Synch prefs */ - StringProperty MYQRGFirstCat = new SimpleStringProperty(); // own qrg will be set by user entry or ucxlog if trx Synch is + MutableValue MYQRGFirstCat = new SimpleValue<>(); // own qrg will be set by user entry or ucxlog if trx Synch is // activated - StringProperty MYQRGSecondCat = new SimpleStringProperty(); // own qrg will be set by user entry or ucxlog if trx Synch is activated + MutableValue MYQRGSecondCat = new SimpleValue<>(); // own qrg will be set by user entry or ucxlog if trx Synch is activated boolean trxSynch_ucxLogUDPListenerEnabled = false; @@ -281,19 +312,19 @@ public class ChatPreferences { //DXCluster section boolean notify_dxClusterServerEnabled = true; int notify_dxclusterServerPort = 8000; //default 8000 like db0sue.de - SimpleStringProperty notify_optionalFrequencyPrefix = new SimpleStringProperty("144"); + MutableValue notify_optionalFrequencyPrefix = new SimpleValue<>("144"); - SimpleStringProperty notify_DXCSrv_SpottersCallSign = new SimpleStringProperty("DO5AMF"); + MutableValue notify_DXCSrv_SpottersCallSign = new SimpleValue<>("DO5AMF"); boolean notify_DXClusterServerTriggerBearing; boolean notify_DXClusterServerTriggerOnQRGDetect; - ObservableList + SimpleRoster lstNotify_QSOSniffer_sniffedCallSignList = - FXCollections.observableArrayList(); - // ObservableList lstNotify_QSOSniffer_sniffedCallSignList = FXCollections.observableArrayList(); - ObservableList lstNotify_QSOSniffer_sniffedWordsList = FXCollections.observableArrayList(); - ObservableList lstNotify_QSOSniffer_sniffedPrefixLocList = FXCollections.observableArrayList(); + new SimpleRoster<>(); + // SimpleRoster lstNotify_QSOSniffer_sniffedCallSignList = new SimpleRoster<>(); + SimpleRoster lstNotify_QSOSniffer_sniffedWordsList = new SimpleRoster<>(); + SimpleRoster lstNotify_QSOSniffer_sniffedPrefixLocList = new SimpleRoster<>(); // Scoring / interaction metrics int notify_noReplyPenaltyMinutes = 13; // if we ping via /cq and no response arrives within X minutes => penalty strike @@ -309,8 +340,8 @@ public class ChatPreferences { */ // String[] shortcuts = new String[37]; // String[] textSnippets = new String[16]; - ObservableList lst_txtSnipList = FXCollections.observableArrayList(); - ObservableList lst_txtShortCutBtnList = FXCollections.observableArrayList(); + SimpleRoster lst_txtSnipList = new SimpleRoster<>(); + SimpleRoster lst_txtShortCutBtnList = new SimpleRoster<>(); /** * Beacon prefs @@ -357,6 +388,24 @@ public class ChatPreferences { boolean guiOptions_showGrossFieldWorkedHintInBandColumns = true; // show "o" (grid square already worked on this band) in the band columns boolean guiOptions_showFreshCallHintInBandColumns = true; // show "a" (band available, call not worked on any band yet) instead of always "B+" in the band columns + /** + * The operator's colour overrides for the daylight design, encoded by PaletteOverrides. + * Per profile, like every other preference: the file this is written to is the profile's + * own. One string rather than six elements, because this file is written element by + * element by hand and twelve more would be twelve write blocks and twelve read blocks. + */ + private String guiOptions_paletteOverridesDay = ""; + + /** The same for the evening design. Two designs, two independent sets. */ + private String guiOptions_paletteOverridesEvening = ""; + + /** + * The operator's interface language: empty for the system language, otherwise a language + * code such as "de". Per profile, like every other GUI preference -- at a multi operator + * station two operators may want two languages. + */ + private String guiOptions_language = ""; + private double[] GUIstationMapStageSceneSizeHW = new double[] { 1000, 800 }; private double[] GUIstationMapStagePositionXY = new double[] { Double.NaN, Double.NaN }; private boolean GUIstationMapPathAnalysisVisible = true; @@ -408,7 +457,7 @@ public class ChatPreferences { this.messageHandling_autoAnswerEnabledSecondCat = messageHandling_autoAnswerEnabledSecondCat; } - public StringProperty getMYQRGSecondCat() { + public MutableValue getMYQRGSecondCat() { return MYQRGSecondCat; } @@ -432,7 +481,7 @@ public class ChatPreferences { return messageHandling_beaconUnworkedstationsPrefix; } - public StringProperty MYQRGFirstCatProperty() { + public MutableValue MYQRGFirstCatProperty() { return MYQRGFirstCat; } @@ -500,25 +549,27 @@ public class ChatPreferences { this.stn_on4kstServersDns = stn_on4kstServersDns; } - public ObservableList + public SimpleRoster getLstNotify_QSOSniffer_sniffedCallSignList() { return lstNotify_QSOSniffer_sniffedCallSignList; } - public ObservableList getLstNotify_QSOSniffer_sniffedWordsList() { + public SimpleRoster getLstNotify_QSOSniffer_sniffedWordsList() { return lstNotify_QSOSniffer_sniffedWordsList; } - public void setLstNotify_QSOSniffer_sniffedWordsList(ObservableList lstNotify_QSOSniffer_sniffedWordsList) { - this.lstNotify_QSOSniffer_sniffedWordsList = lstNotify_QSOSniffer_sniffedWordsList; + public void setLstNotify_QSOSniffer_sniffedWordsList(java.util.Collection lstNotify_QSOSniffer_sniffedWordsList) { + // Fill the existing roster: replacing the field would orphan its listeners. + this.lstNotify_QSOSniffer_sniffedWordsList.setAll(lstNotify_QSOSniffer_sniffedWordsList); } - public ObservableList getLstNotify_QSOSniffer_sniffedPrefixLocList() { + public SimpleRoster getLstNotify_QSOSniffer_sniffedPrefixLocList() { return lstNotify_QSOSniffer_sniffedPrefixLocList; } - public void setLstNotify_QSOSniffer_sniffedPrefixLocList(ObservableList lstNotify_QSOSniffer_sniffedPrefixLocList) { - this.lstNotify_QSOSniffer_sniffedPrefixLocList = lstNotify_QSOSniffer_sniffedPrefixLocList; + public void setLstNotify_QSOSniffer_sniffedPrefixLocList(java.util.Collection lstNotify_QSOSniffer_sniffedPrefixLocList) { + // Fill the existing roster: replacing the field would orphan its listeners. + this.lstNotify_QSOSniffer_sniffedPrefixLocList.setAll(lstNotify_QSOSniffer_sniffedPrefixLocList); } public String getLogsynch_wintestNetworkStationNameOfKST() { @@ -746,6 +797,63 @@ public class ChatPreferences { this.guiOptions_showFreshCallHintInBandColumns = guiOptions_showFreshCallHintInBandColumns; } + /** + * Returns the colour overrides of the daylight design. + * + * @return the encoded overrides, empty when the operator has changed nothing + */ + public String getGuiOptions_paletteOverridesDay() { + return guiOptions_paletteOverridesDay; + } + + /** + * Sets the colour overrides of the daylight design. + * + * @param guiOptions_paletteOverridesDay the encoded overrides; null becomes empty + */ + public void setGuiOptions_paletteOverridesDay(String guiOptions_paletteOverridesDay) { + this.guiOptions_paletteOverridesDay = + guiOptions_paletteOverridesDay == null ? "" : guiOptions_paletteOverridesDay; + } + + /** + * Returns the colour overrides of the evening design. + * + * @return the encoded overrides, empty when the operator has changed nothing + */ + public String getGuiOptions_paletteOverridesEvening() { + return guiOptions_paletteOverridesEvening; + } + + /** + * Sets the colour overrides of the evening design. + * + * @param guiOptions_paletteOverridesEvening the encoded overrides; null becomes empty + */ + public void setGuiOptions_paletteOverridesEvening(String guiOptions_paletteOverridesEvening) { + this.guiOptions_paletteOverridesEvening = + guiOptions_paletteOverridesEvening == null ? "" : guiOptions_paletteOverridesEvening; + } + + /** + * Returns the operator's interface language. + * + * @return a language code, or empty for the system language + */ + public String getGuiOptions_language() { + return guiOptions_language; + } + + /** + * Sets the operator's interface language. + * + * @param guiOptions_language a language code, or empty for the system language; null + * becomes empty + */ + public void setGuiOptions_language(String guiOptions_language) { + this.guiOptions_language = guiOptions_language == null ? "" : guiOptions_language; + } + public boolean isGuiOptions_defaultFilterPmToOther() { return guiOptions_defaultFilterPmToOther; } @@ -900,14 +1008,10 @@ public class ChatPreferences { } } - public SimpleStringProperty getNotify_optionalFrequencyPrefix() { + public MutableValue getNotify_optionalFrequencyPrefix() { return notify_optionalFrequencyPrefix; } - public void setNotify_optionalFrequencyPrefix(SimpleStringProperty notify_optionalFrequencyPrefix) { - this.notify_optionalFrequencyPrefix = notify_optionalFrequencyPrefix; - } - public int getNotify_dxclusterServerPort() { return notify_dxclusterServerPort; } @@ -1214,22 +1318,18 @@ public class ChatPreferences { * */ - public StringProperty getMYQRGFirstCat() { + public MutableValue getMYQRGFirstCat() { return MYQRGFirstCat; } - public DoubleProperty getActualQTF() { + public MutableValue getActualQTF() { return actualQTF; } - public void setActualQTF(DoubleProperty actualQTF) { + public void setActualQTF(MutableValue actualQTF) { this.actualQTF = actualQTF; } - public void setMYQRGFirstCat(StringProperty mYQRG) { - MYQRGFirstCat = mYQRG; - } - public void setStn_loginCallSign(String stn_loginCallSign) { this.stn_loginCallSign = stn_loginCallSign; @@ -1324,26 +1424,14 @@ public class ChatPreferences { this.trxSynch_ucxLogUDPListenerEnabled = trxSynch_ucxLogUDPListenerEnabled; } - public SimpleStringProperty notify_optionalFrequencyPrefixProperty() { - return notify_optionalFrequencyPrefix; - } - public void setNotify_optionalFrequencyPrefix(String notify_optionalFrequencyPrefix) { this.notify_optionalFrequencyPrefix.set(notify_optionalFrequencyPrefix); } - public SimpleStringProperty getNotify_DXCSrv_SpottersCallSign() { + public MutableValue getNotify_DXCSrv_SpottersCallSign() { return notify_DXCSrv_SpottersCallSign; } - public SimpleStringProperty notify_DXCSrv_SpottersCallSignProperty() { - return notify_DXCSrv_SpottersCallSign; - } - - public void setNotify_DXCSrv_SpottersCallSign(SimpleStringProperty notify_DXCSrv_SpottersCallSign) { - this.notify_DXCSrv_SpottersCallSign.setValue(notify_DXCSrv_SpottersCallSign.getValue()); - } - // public String[] getShortcuts() { // return shortcuts; // } @@ -1364,20 +1452,22 @@ public class ChatPreferences { return bcn_beaconsEnabledMainCat; } - public ObservableList getLst_txtShortCutBtnList() { + public SimpleRoster getLst_txtShortCutBtnList() { return lst_txtShortCutBtnList; } - public void setLst_txtShortCutBtnList(ObservableList lst_txtShortCutBtnList) { - this.lst_txtShortCutBtnList = lst_txtShortCutBtnList; + public void setLst_txtShortCutBtnList(java.util.Collection lst_txtShortCutBtnList) { + // Fill the existing roster: replacing the field would orphan its listeners. + this.lst_txtShortCutBtnList.setAll(lst_txtShortCutBtnList); } - public ObservableList getLst_txtSnipList() { + public SimpleRoster getLst_txtSnipList() { return lst_txtSnipList; } - public void setLst_txtSnipList(ObservableList lst_txtSnipList) { - this.lst_txtSnipList = lst_txtSnipList; + public void setLst_txtSnipList(java.util.Collection lst_txtSnipList) { + // Fill the existing roster: replacing the field would orphan its listeners. + this.lst_txtSnipList.setAll(lst_txtSnipList); } public void setBcn_beaconsEnabledMainCat(boolean bcn_beaconsEnabledMainCat) { @@ -1746,12 +1836,12 @@ public class ChatPreferences { trxSynchUCX.appendChild(trxSynch_ucxLogUDPListenerEnabled); Element trxSynch_defaultMYQRGValue = doc.createElement("trxSynch_defaultMYQRGValue"); - trxSynch_defaultMYQRGValue.setTextContent(this.getMYQRGFirstCat().getValue()); + trxSynch_defaultMYQRGValue.setTextContent(this.getMYQRGFirstCat().get()); trxSynchUCX.appendChild(trxSynch_defaultMYQRGValue); Element trxSynch_defaultMYQRG2Value = doc.createElement("trxSynch_defaultMYQRG2Value"); // Safe null check falls Property noch nicht initialisiert ist - trxSynch_defaultMYQRG2Value.setTextContent(this.getMYQRGSecondCat().getValue() != null ? this.getMYQRGSecondCat().getValue() : "1296.200.00"); + trxSynch_defaultMYQRG2Value.setTextContent(this.getMYQRGSecondCat().get() != null ? this.getMYQRGSecondCat().get() : "1296.200.00"); trxSynchUCX.appendChild(trxSynch_defaultMYQRG2Value); @@ -1862,7 +1952,7 @@ public class ChatPreferences { Element shortCuts = doc.createElement("shortCuts"); rootElement.appendChild(shortCuts); - for (Iterator iterator = lst_txtShortCutBtnList.iterator(); iterator.hasNext();) { + for (Iterator iterator = lst_txtShortCutBtnList.snapshot().iterator(); iterator.hasNext();) { String string = (String) iterator.next(); Element temp = doc.createElement("t"); temp.setTextContent(string); @@ -1875,7 +1965,7 @@ public class ChatPreferences { Element snifferWords = doc.createElement("snifferWords"); rootElement.appendChild(snifferWords); - for (String word : lstNotify_QSOSniffer_sniffedWordsList) { + for (String word : lstNotify_QSOSniffer_sniffedWordsList.snapshot()) { Element temp = doc.createElement("w"); temp.setTextContent(word); snifferWords.appendChild(temp); @@ -1886,7 +1976,7 @@ public class ChatPreferences { rootElement.appendChild(snifferCallSigns); for (String callSign - : lstNotify_QSOSniffer_sniffedCallSignList) { + : lstNotify_QSOSniffer_sniffedCallSignList.snapshot()) { Element temp = doc.createElement("callSign"); temp.setTextContent(callSign); snifferCallSigns.appendChild(temp); @@ -1896,7 +1986,7 @@ public class ChatPreferences { Element snifferPrefixes = doc.createElement("snifferPrefixes"); rootElement.appendChild(snifferPrefixes); - for (String prefix : lstNotify_QSOSniffer_sniffedPrefixLocList) { + for (String prefix : lstNotify_QSOSniffer_sniffedPrefixLocList.snapshot()) { Element temp = doc.createElement("p"); temp.setTextContent(prefix); snifferPrefixes.appendChild(temp); @@ -1909,7 +1999,7 @@ public class ChatPreferences { Element textSnippets = doc.createElement("textSnippets"); rootElement.appendChild(textSnippets); - for (Iterator iterator = lst_txtSnipList.iterator(); iterator.hasNext();) { + for (Iterator iterator = lst_txtSnipList.snapshot().iterator(); iterator.hasNext();) { String string = (String) iterator.next(); Element temp = doc.createElement("t"); temp.setTextContent(string); @@ -2077,6 +2167,18 @@ public class ChatPreferences { guiOptions_showFreshCallHintInBandColumns.setTextContent(this.isGuiOptions_showFreshCallHintInBandColumns()+""); guiSaveableOptions.appendChild(guiOptions_showFreshCallHintInBandColumns); + Element guiOptions_paletteOverridesDay = doc.createElement("guiOptions_paletteOverridesDay"); + guiOptions_paletteOverridesDay.setTextContent(this.getGuiOptions_paletteOverridesDay()); + guiSaveableOptions.appendChild(guiOptions_paletteOverridesDay); + + Element guiOptions_paletteOverridesEvening = doc.createElement("guiOptions_paletteOverridesEvening"); + guiOptions_paletteOverridesEvening.setTextContent(this.getGuiOptions_paletteOverridesEvening()); + guiSaveableOptions.appendChild(guiOptions_paletteOverridesEvening); + + Element guiOptions_language = doc.createElement("guiOptions_language"); + guiOptions_language.setTextContent(this.getGuiOptions_language()); + guiSaveableOptions.appendChild(guiOptions_language); + Element guiOptions_darkModeActive = doc.createElement("guiOptions_darkModeActive"); guiOptions_darkModeActive.setTextContent(this.GUI_darkModeActive + ""); guiSaveableOptions.appendChild(guiOptions_darkModeActive); @@ -2594,14 +2696,14 @@ public class ChatPreferences { String qrg1 = getText(trxSynchEl, null, "trxSynch_defaultMYQRGValue"); if (qrg1 != null) { - this.getMYQRGFirstCat().setValue(qrg1); + this.getMYQRGFirstCat().set(qrg1); } String qrg2 = getText(trxSynchEl, "1296.123.00", "trxSynch_defaultMYQRG2Value"); - this.getMYQRGSecondCat().setValue(qrg2); + this.getMYQRGSecondCat().set(qrg2); System.out.println( "[ChatPreferences, info]: trx qrg synch=" + trxSynch_ucxLogUDPListenerEnabled - + ", default=" + this.getMYQRGFirstCat().getValue() + " // " + this.getMYQRGSecondCat().getValue()); + + ", default=" + this.getMYQRGFirstCat().get() + " // " + this.getMYQRGSecondCat().get()); } /** @@ -2821,7 +2923,7 @@ public class ChatPreferences { callSign ); - if (!lstNotify_QSOSniffer_sniffedCallSignList + if (!lstNotify_QSOSniffer_sniffedCallSignList.snapshot() .contains(normalizedCallSign)) { lstNotify_QSOSniffer_sniffedCallSignList .add(normalizedCallSign); @@ -2862,7 +2964,7 @@ public class ChatPreferences { if (normalizedCallSign != null && !normalizedCallSign.isBlank() - && !lstNotify_QSOSniffer_sniffedCallSignList + && !lstNotify_QSOSniffer_sniffedCallSignList.snapshot() .contains(normalizedCallSign)) { lstNotify_QSOSniffer_sniffedCallSignList .add(normalizedCallSign); @@ -3151,6 +3253,11 @@ public class ChatPreferences { this.setGuiOptions_showGrossFieldWorkedHintInBandColumns(getBoolean(guiSaveableOptionsEl, this.isGuiOptions_showGrossFieldWorkedHintInBandColumns(), "guiOptions_showGrossFieldWorkedHintInBandColumns")); this.setGuiOptions_showFreshCallHintInBandColumns(getBoolean(guiSaveableOptionsEl, this.isGuiOptions_showFreshCallHintInBandColumns(), "guiOptions_showFreshCallHintInBandColumns")); + // Added in release 1.50: the operator's own colours, one string per design. + this.setGuiOptions_paletteOverridesDay(getText(guiSaveableOptionsEl, this.getGuiOptions_paletteOverridesDay(), "guiOptions_paletteOverridesDay")); + this.setGuiOptions_paletteOverridesEvening(getText(guiSaveableOptionsEl, this.getGuiOptions_paletteOverridesEvening(), "guiOptions_paletteOverridesEvening")); + this.setGuiOptions_language(getText(guiSaveableOptionsEl, this.getGuiOptions_language(), "guiOptions_language")); + // Added in later versions: dark mode flags this.GUI_darkModeActive = getBoolean(guiSaveableOptionsEl, this.GUI_darkModeActive, "guiOptions_darkModeActive"); this.GUI_darkModeActiveByDefault = getBoolean(guiSaveableOptionsEl, this.GUI_darkModeActiveByDefault, "guiOptions_darkModeActiveByDefault"); @@ -3503,7 +3610,7 @@ public class ChatPreferences { } // public ObservableList getTxtSnippetsAsObservableList(){ -// ObservableList lst_txtSnipList = FXCollections.observableArrayList(); +// SimpleRoster lst_txtSnipList = new SimpleRoster<>(); // // for (int i = 0; i < textSnippets.length; i++) { // lst_txtSnipList.add(textSnippets[i]); diff --git a/src/main/java/kst4contest/model/ClusterMessage.java b/core/src/main/java/kst4contest/model/ClusterMessage.java similarity index 100% rename from src/main/java/kst4contest/model/ClusterMessage.java rename to core/src/main/java/kst4contest/model/ClusterMessage.java diff --git a/src/main/java/kst4contest/model/ContestSked.java b/core/src/main/java/kst4contest/model/ContestSked.java similarity index 100% rename from src/main/java/kst4contest/model/ContestSked.java rename to core/src/main/java/kst4contest/model/ContestSked.java diff --git a/core/src/main/java/kst4contest/model/OperatorProfile.java b/core/src/main/java/kst4contest/model/OperatorProfile.java new file mode 100644 index 00000000..bcb91ab6 --- /dev/null +++ b/core/src/main/java/kst4contest/model/OperatorProfile.java @@ -0,0 +1,133 @@ +package kst4contest.model; + +import java.util.Objects; + +/** + * Descriptor of one operator profile. + * + *

A profile always owns its own preferences file. Whether it also owns its own + * worked-station database is decided by {@link #isSharedWorkedDatabase()}: a multi + * operator contest station keeps one common log and therefore shares the database, + * while two operators sharing a private computer usually want their worked data kept + * apart.

+ * + *

The descriptor deliberately carries no file paths. They are derived in exactly one + * place, {@link kst4contest.controller.OperatorProfilePaths}, so a stored path can never + * drift apart from the flag that produced it.

+ */ +public class OperatorProfile { + + /** + * Stable identifier of the profile. It is assigned once and never changes, so + * renaming a profile never moves a directory. + */ + private String profileId; + + /** + * Name shown in the profile picker and in the settings window. + */ + private String displayName; + + /** + * True for the profile that uses the historic flat installation layout directly. + */ + private boolean rootProfile; + + /** + * True if this profile uses the common station worked-station database. + */ + private boolean sharedWorkedDatabase; + + /** + * Timestamp of the last activation, used to preselect an entry in the picker. + */ + private long lastUsedEpochMs; + + public OperatorProfile() { + // Default constructor for stepwise construction while reading the registry. + } + + public OperatorProfile(final String profileId, + final String displayName, + final boolean rootProfile, + final boolean sharedWorkedDatabase) { + this.profileId = profileId; + this.displayName = displayName; + this.rootProfile = rootProfile; + this.sharedWorkedDatabase = sharedWorkedDatabase; + } + + public String getProfileId() { + return profileId; + } + + public void setProfileId(final String profileId) { + this.profileId = profileId; + } + + public String getDisplayName() { + return displayName; + } + + public void setDisplayName(final String displayName) { + this.displayName = displayName; + } + + public boolean isRootProfile() { + return rootProfile; + } + + public void setRootProfile(final boolean rootProfile) { + this.rootProfile = rootProfile; + } + + public boolean isSharedWorkedDatabase() { + return sharedWorkedDatabase; + } + + public void setSharedWorkedDatabase(final boolean sharedWorkedDatabase) { + this.sharedWorkedDatabase = sharedWorkedDatabase; + } + + public long getLastUsedEpochMs() { + return lastUsedEpochMs; + } + + public void setLastUsedEpochMs(final long lastUsedEpochMs) { + this.lastUsedEpochMs = lastUsedEpochMs; + } + + @Override + public boolean equals(final Object other) { + + if (this == other) { + return true; + } + + if (!(other instanceof OperatorProfile)) { + return false; + } + + return Objects.equals(profileId, ((OperatorProfile) other).profileId); + } + + @Override + public int hashCode() { + return Objects.hashCode(profileId); + } + + /** + * Returns the display name so the descriptor can be shown in a list control directly. + * + * @return the display name, or the profile id when no name was set + */ + @Override + public String toString() { + + if (displayName == null || displayName.isBlank()) { + return String.valueOf(profileId); + } + + return displayName; + } +} diff --git a/core/src/main/java/kst4contest/model/OperatorProfileSelection.java b/core/src/main/java/kst4contest/model/OperatorProfileSelection.java new file mode 100644 index 00000000..50d40375 --- /dev/null +++ b/core/src/main/java/kst4contest/model/OperatorProfileSelection.java @@ -0,0 +1,70 @@ +package kst4contest.model; + +import kst4contest.ApplicationConstants; +import kst4contest.utils.ApplicationFileUtils; + +import java.util.Objects; + +/** + * Resolved runtime view of the active operator profile. + * + *

This is the only profile information the rest of the application needs: two file + * names relative to the application directory plus the flag whether a missing + * worked-station database may be seeded from the bundled template. Everything else is + * derived from the descriptor.

+ */ +public class OperatorProfileSelection { + + private final OperatorProfile profile; + private final String preferencesRelativeFileName; + private final String workedDatabaseRelativeFileName; + private final boolean seedWorkedDatabaseFromResource; + + public OperatorProfileSelection(final OperatorProfile profile, + final String preferencesRelativeFileName, + final String workedDatabaseRelativeFileName, + final boolean seedWorkedDatabaseFromResource) { + this.profile = Objects.requireNonNull(profile, "profile"); + this.preferencesRelativeFileName = + Objects.requireNonNull(preferencesRelativeFileName, "preferencesRelativeFileName"); + this.workedDatabaseRelativeFileName = + Objects.requireNonNull(workedDatabaseRelativeFileName, "workedDatabaseRelativeFileName"); + this.seedWorkedDatabaseFromResource = seedWorkedDatabaseFromResource; + } + + public OperatorProfile getProfile() { + return profile; + } + + public String getPreferencesRelativeFileName() { + return preferencesRelativeFileName; + } + + public String getWorkedDatabaseRelativeFileName() { + return workedDatabaseRelativeFileName; + } + + public boolean isSeedWorkedDatabaseFromResource() { + return seedWorkedDatabaseFromResource; + } + + /** + * Returns the absolute preferences path, for display in the settings window. + * + * @return absolute path of the preferences file + */ + public String getPreferencesAbsolutePath() { + return ApplicationFileUtils.getFilePath( + ApplicationConstants.APPLICATION_NAME, preferencesRelativeFileName); + } + + /** + * Returns the absolute worked-station database path, for display in the settings window. + * + * @return absolute path of the worked-station database + */ + public String getWorkedDatabaseAbsolutePath() { + return ApplicationFileUtils.getFilePath( + ApplicationConstants.APPLICATION_NAME, workedDatabaseRelativeFileName); + } +} diff --git a/core/src/main/java/kst4contest/model/PaletteOverrides.java b/core/src/main/java/kst4contest/model/PaletteOverrides.java new file mode 100644 index 00000000..23b298c6 --- /dev/null +++ b/core/src/main/java/kst4contest/model/PaletteOverrides.java @@ -0,0 +1,120 @@ +package kst4contest.model; + +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; +import java.util.regex.Pattern; + +/** + * A set of palette overrides, encoded as one string. + * + *

One string per design rather than twelve XML elements: the preferences file is written + * element by element by hand, and twelve more would be twelve write blocks, twelve read + * blocks and twelve fields in a class that is already three thousand lines long.

+ * + *

Reading is deliberately forgiving and never throws. The input is not always this + * version's own: a hand-edited XML, a file from an older release, or a write interrupted + * half way. An unknown key or an unparsable colour is skipped and the rest survives -- + * losing one colour is a nuisance, losing the readability of the client is not.

+ */ +public final class PaletteOverrides { + + private static final Pattern SIX_DIGIT_HEX = Pattern.compile("^#[0-9a-fA-F]{6}$"); + + private static final String PAIR_SEPARATOR = ";"; + private static final String KEY_VALUE_SEPARATOR = "="; + + private PaletteOverrides() { + // Utility class. + } + + /** + * Reads a stored set of overrides. + * + * @param stored the stored string, may be null or malformed + * @return the roles actually named with a usable colour, never null + */ + public static Map parse(final String stored) { + + Map overrides = new LinkedHashMap<>(); + + if (stored == null || stored.isBlank()) { + return overrides; + } + + for (String pair : stored.split(PAIR_SEPARATOR)) { + + int separator = pair.indexOf(KEY_VALUE_SEPARATOR); + + if (separator <= 0) { + continue; + } + + String key = pair.substring(0, separator).trim(); + String value = pair.substring(separator + 1).trim(); + + if (!isValidColour(value)) { + continue; + } + + for (PaletteRole role : PaletteRole.values()) { + if (role.key().equals(key)) { + overrides.put(role, normalise(value)); + break; + } + } + } + + return overrides; + } + + /** + * Writes a set of overrides for storage. + * + * @param overrides the roles to store; entries with an unusable colour are left out + * @return the string to store, empty when there is nothing to store + */ + public static String format(final Map overrides) { + + if (overrides == null || overrides.isEmpty()) { + return ""; + } + + StringBuilder stored = new StringBuilder(); + + for (PaletteRole role : PaletteRole.values()) { + + String colour = overrides.get(role); + + if (!isValidColour(colour)) { + continue; + } + + if (stored.length() > 0) { + stored.append(PAIR_SEPARATOR); + } + + stored.append(role.key()).append(KEY_VALUE_SEPARATOR).append(normalise(colour)); + } + + return stored.toString(); + } + + /** + * Returns whether a string is a colour this application can use. + * + *

Six hexadecimal digits with a leading hash, and nothing else. The stylesheets use + * named colours and functions too, but those are the shipped sheets' business; what an + * operator types has one form so that what they typed is what they get.

+ * + * @param colour the text to check, may be null + * @return true when it names a colour + */ + public static boolean isValidColour(final String colour) { + return colour != null && SIX_DIGIT_HEX.matcher(colour.trim()).matches(); + } + + private static String normalise(final String colour) { + return colour.trim().toUpperCase(Locale.ROOT); + } +} diff --git a/core/src/main/java/kst4contest/model/PaletteRole.java b/core/src/main/java/kst4contest/model/PaletteRole.java new file mode 100644 index 00000000..52deee08 --- /dev/null +++ b/core/src/main/java/kst4contest/model/PaletteRole.java @@ -0,0 +1,97 @@ +package kst4contest.model; + +/** + * A colour the operator may set, and the stylesheet declaration it corresponds to. + * + *

In core and therefore free of any toolkit: a role is a name and three strings, and the + * colour itself travels as text. Turning text into a drawable colour is the user + * interface's job.

+ * + *

A declaration is a selector and a property together. Three of the six roles are stated + * outside {@code .root} by the shipped sheets, and {@code -fx-background-color} alone appears + * a dozen times in one of them -- on scroll bars, buttons and toggle buttons. Without the + * selector, half the roles would never be found and the rest would be found in the wrong + * places.

+ * + *

All three strings are part of a file format. The selector and the property are what a + * hand-edited stylesheet writes; {@link #key()} is what the stored overrides are written + * under. Renaming any of them silently drops a colour an operator chose.

+ */ +public enum PaletteRole { + + /** The control surface; the window surface is normally a {@code derive} of this. */ + SURFACE(".root", "-fx-base", "surface"), + + /** The window's own area. Neither shipped sheet states it, so both derive it. */ + WINDOW_SURFACE(".root", "-fx-background", "windowSurface"), + + /** Inside a text field or a list. */ + FIELD_INTERIOR(".root", "-fx-control-inner-background", "fieldInterior"), + + /** Label text. Stated on {@code .label} and not on {@code .root}. */ + TEXT(".label", "-fx-text-fill", "text"), + + ACCENT(".root", "-fx-accent", "accent"), + + /** The separator's line, whose selector is what tells it from a scroll bar. */ + SEPARATOR(".separator *.line", "-fx-background-color", "separator"); + + private final String selector; + private final String cssProperty; + private final String key; + + PaletteRole(final String selector, final String cssProperty, final String key) { + this.selector = selector; + this.cssProperty = cssProperty; + this.key = key; + } + + /** + * Returns the stylesheet selector this role is stated on. + * + * @return selector + */ + public String selector() { + return selector; + } + + /** + * Returns the stylesheet property this role is read from. + * + * @return CSS property name + */ + public String cssProperty() { + return cssProperty; + } + + /** + * Returns the name this role is stored under in the preferences. + * + * @return storage key + */ + public String key() { + return key; + } + + /** + * Returns the role a stylesheet declaration belongs to. + * + * @param selector a selector from a stylesheet, may be null + * @param cssProperty a property name from a stylesheet, may be null + * @return the role, or null for the hundreds of declarations that are not ours + */ + public static PaletteRole of(final String selector, final String cssProperty) { + + if (selector == null || cssProperty == null) { + return null; + } + + for (PaletteRole role : values()) { + if (role.selector.equals(selector) && role.cssProperty.equals(cssProperty)) { + return role; + } + } + + return null; + } +} diff --git a/src/main/java/kst4contest/model/ThreadStateMessage.java b/core/src/main/java/kst4contest/model/ThreadStateMessage.java similarity index 100% rename from src/main/java/kst4contest/model/ThreadStateMessage.java rename to core/src/main/java/kst4contest/model/ThreadStateMessage.java diff --git a/src/main/java/kst4contest/model/UpdateInformation.java b/core/src/main/java/kst4contest/model/UpdateInformation.java similarity index 100% rename from src/main/java/kst4contest/model/UpdateInformation.java rename to core/src/main/java/kst4contest/model/UpdateInformation.java diff --git a/core/src/main/java/kst4contest/observe/DirectUiDispatcher.java b/core/src/main/java/kst4contest/observe/DirectUiDispatcher.java new file mode 100644 index 00000000..af1ceb2a --- /dev/null +++ b/core/src/main/java/kst4contest/observe/DirectUiDispatcher.java @@ -0,0 +1,22 @@ +package kst4contest.observe; + +/** + * Runs every task on the calling thread. Intended for tests and for headless + * use; it is not a user-interface thread in any real sense. + */ +public class DirectUiDispatcher implements UiDispatcher { + + @Override + public void runOnUi(Runnable task) { + try { + task.run(); + } catch (RuntimeException e) { + System.err.println("[observe] UI task failed: " + e); + } + } + + @Override + public boolean isUiThread() { + return true; + } +} diff --git a/core/src/main/java/kst4contest/observe/MutableValue.java b/core/src/main/java/kst4contest/observe/MutableValue.java new file mode 100644 index 00000000..965d50b8 --- /dev/null +++ b/core/src/main/java/kst4contest/observe/MutableValue.java @@ -0,0 +1,11 @@ +package kst4contest.observe; + +/** An {@link ObservableValue} that can be written to. */ +public interface MutableValue extends ObservableValue { + + /** + * Replaces the value and notifies the listeners. Setting a value that + * equals the current one notifies nobody. + */ + void set(T value); +} diff --git a/core/src/main/java/kst4contest/observe/ObservableRoster.java b/core/src/main/java/kst4contest/observe/ObservableRoster.java new file mode 100644 index 00000000..e43af500 --- /dev/null +++ b/core/src/main/java/kst4contest/observe/ObservableRoster.java @@ -0,0 +1,33 @@ +package kst4contest.observe; + +import java.util.List; +import java.util.function.Consumer; + +/** + * An observable collection that hands out immutable snapshots. + * + *

There is deliberately no incremental change protocol: consumers receive + * the whole new content and decide for themselves what to do with it. That + * matches how a declarative user interface redraws, and it keeps the domain + * layer testable without a running toolkit. + * + *

Listeners run on the thread that performed the mutation. Anything that + * touches the user interface must hand over through {@link UiDispatcher}. + */ +public interface ObservableRoster { + + /** An immutable view of the current content. */ + List snapshot(); + + int size(); + + default boolean isEmpty() { + return size() == 0; + } + + /** Registers a listener that is called with the new content after each change. */ + void addListener(Consumer> listener); + + /** Removes a previously registered listener. Unknown listeners are ignored. */ + void removeListener(Consumer> listener); +} diff --git a/core/src/main/java/kst4contest/observe/ObservableValue.java b/core/src/main/java/kst4contest/observe/ObservableValue.java new file mode 100644 index 00000000..a0678736 --- /dev/null +++ b/core/src/main/java/kst4contest/observe/ObservableValue.java @@ -0,0 +1,22 @@ +package kst4contest.observe; + +import java.util.function.Consumer; + +/** + * A value that can be observed for changes. + * + *

Deliberately minimal: this replaces the JavaFX property types in the + * domain layer without pulling in a reactive framework. {@code null} means the + * value is unavailable, never a default. + */ +public interface ObservableValue { + + /** The current value, or {@code null} when it is unavailable. */ + T get(); + + /** Registers a listener that is called with the new value after each change. */ + void addListener(Consumer listener); + + /** Removes a previously registered listener. Unknown listeners are ignored. */ + void removeListener(Consumer listener); +} diff --git a/core/src/main/java/kst4contest/observe/SimpleRoster.java b/core/src/main/java/kst4contest/observe/SimpleRoster.java new file mode 100644 index 00000000..34d0a765 --- /dev/null +++ b/core/src/main/java/kst4contest/observe/SimpleRoster.java @@ -0,0 +1,119 @@ +package kst4contest.observe; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Consumer; + +/** + * The default {@link ObservableRoster}. Writes are serialised on the roster + * itself; reads hand out an immutable copy taken under the same lock. + */ +public class SimpleRoster implements ObservableRoster { + + private final Object lock = new Object(); + private final List items = new ArrayList<>(); + private final List>> listeners = new CopyOnWriteArrayList<>(); + + /** + * The last handed-out snapshot, reused until the content changes. Several + * consumers read the same roster per batch — four message tabs, for one — and + * copying the whole store for each of them is wasted work. + */ + private volatile List snapshotCache; + + @Override + public List snapshot() { + List cached = snapshotCache; + if (cached != null) { + return cached; + } + synchronized (lock) { + if (snapshotCache == null) { + snapshotCache = newSnapshot(); + } + return snapshotCache; + } + } + + /* + * Collections.unmodifiableList and not List.copyOf: the JavaFX list this + * replaces carried null entries, and List.copyOf rejects them. A NullPointerException + * raised here would be swallowed by the listener guard and the mirror would stop + * updating without a word. + */ + private List newSnapshot() { + return Collections.unmodifiableList(new ArrayList<>(items)); + } + + @Override + public int size() { + synchronized (lock) { + return items.size(); + } + } + + public void add(T item) { + mutate(list -> list.add(item)); + } + + public void addAll(Collection newItems) { + mutate(list -> list.addAll(newItems)); + } + + public void remove(T item) { + mutate(list -> list.remove(item)); + } + + public void setAll(Collection newItems) { + mutate(list -> { + list.clear(); + list.addAll(newItems); + }); + } + + public void clear() { + mutate(List::clear); + } + + /** + * Applies several changes and notifies listeners once. This is what keeps + * a batch of several thousand chat members from producing a snapshot and a + * listener round per element. + */ + public void mutate(Consumer> change) { + Objects.requireNonNull(change, "change"); + List snapshot; + synchronized (lock) { + change.accept(items); + snapshot = newSnapshot(); + snapshotCache = snapshot; + } + notifyListeners(snapshot); + } + + private void notifyListeners(List snapshot) { + for (Consumer> listener : listeners) { + try { + listener.accept(snapshot); + } catch (RuntimeException e) { + // A broken listener must not keep the remaining ones from running, + // and must not terminate the message-processing thread. + System.err.println("[observe] roster listener failed: " + e); + } + } + } + + @Override + public void addListener(Consumer> listener) { + listeners.add(Objects.requireNonNull(listener, "listener")); + } + + @Override + public void removeListener(Consumer> listener) { + listeners.remove(listener); + } +} diff --git a/core/src/main/java/kst4contest/observe/SimpleValue.java b/core/src/main/java/kst4contest/observe/SimpleValue.java new file mode 100644 index 00000000..f8979fd6 --- /dev/null +++ b/core/src/main/java/kst4contest/observe/SimpleValue.java @@ -0,0 +1,57 @@ +package kst4contest.observe; + +import java.util.List; +import java.util.Objects; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.function.Consumer; + +/** + * The default {@link MutableValue}. Safe to read and write from any thread; + * listeners run on the thread that calls {@link #set}, so anything touching the + * user interface must hand over through {@link UiDispatcher}. + */ +public class SimpleValue implements MutableValue { + + private final List> listeners = new CopyOnWriteArrayList<>(); + private volatile T value; + + public SimpleValue() { + this(null); + } + + public SimpleValue(T initial) { + this.value = initial; + } + + @Override + public T get() { + return value; + } + + @Override + public void set(T newValue) { + if (Objects.equals(value, newValue)) { + return; + } + value = newValue; + for (Consumer listener : listeners) { + try { + listener.accept(newValue); + } catch (RuntimeException e) { + // A broken listener must not keep the remaining ones from running, + // and must not terminate the thread that produced the value. + System.err.println("[observe] value listener failed: " + e); + } + } + } + + @Override + public void addListener(Consumer listener) { + listeners.add(Objects.requireNonNull(listener, "listener")); + } + + @Override + public void removeListener(Consumer listener) { + listeners.remove(listener); + } +} diff --git a/core/src/main/java/kst4contest/observe/UiDispatcher.java b/core/src/main/java/kst4contest/observe/UiDispatcher.java new file mode 100644 index 00000000..5938d40b --- /dev/null +++ b/core/src/main/java/kst4contest/observe/UiDispatcher.java @@ -0,0 +1,18 @@ +package kst4contest.observe; + +/** + * Hands work over to the thread that owns the user interface. + * + *

This is the boundary the project has always had, named explicitly: worker + * threads never mutate user-interface state themselves, they hand it over. + * Before this interface existed the boundary was {@code Platform.runLater}; + * the rule is unchanged, only the dependency is gone. + */ +public interface UiDispatcher { + + /** Runs the task on the user-interface thread, now or later. */ + void runOnUi(Runnable task); + + /** Whether the calling thread is the user-interface thread. */ + boolean isUiThread(); +} diff --git a/src/main/java/kst4contest/service/path/FresnelMathUtils.java b/core/src/main/java/kst4contest/service/path/FresnelMathUtils.java similarity index 100% rename from src/main/java/kst4contest/service/path/FresnelMathUtils.java rename to core/src/main/java/kst4contest/service/path/FresnelMathUtils.java diff --git a/src/main/java/kst4contest/test/MockKstServer.java b/core/src/main/java/kst4contest/test/MockKstServer.java similarity index 100% rename from src/main/java/kst4contest/test/MockKstServer.java rename to core/src/main/java/kst4contest/test/MockKstServer.java diff --git a/src/main/java/kst4contest/utils/ApplicationFileLogging.java b/core/src/main/java/kst4contest/utils/ApplicationFileLogging.java similarity index 100% rename from src/main/java/kst4contest/utils/ApplicationFileLogging.java rename to core/src/main/java/kst4contest/utils/ApplicationFileLogging.java diff --git a/src/main/java/kst4contest/utils/ApplicationFileUtils.java b/core/src/main/java/kst4contest/utils/ApplicationFileUtils.java similarity index 100% rename from src/main/java/kst4contest/utils/ApplicationFileUtils.java rename to core/src/main/java/kst4contest/utils/ApplicationFileUtils.java diff --git a/core/src/main/java/kst4contest/utils/PlatformUtils.java b/core/src/main/java/kst4contest/utils/PlatformUtils.java new file mode 100644 index 00000000..1efb1141 --- /dev/null +++ b/core/src/main/java/kst4contest/utils/PlatformUtils.java @@ -0,0 +1,29 @@ +package kst4contest.utils; + +import java.util.Locale; + +/** + * Small helpers for operating-system specific UI behaviour. + */ +public final class PlatformUtils { + + private PlatformUtils() { + } + + /** + * @return true if the running JVM reports macOS as operating system + */ + public static boolean isMacOs() { + return isMacOs(System.getProperty("os.name")); + } + + /** + * Checks an {@code os.name} value for macOS. A missing value is treated as "not macOS". + */ + public static boolean isMacOs(String osName) { + if (osName == null) { + return false; + } + return osName.toLowerCase(Locale.ROOT).startsWith("mac"); + } +} diff --git a/src/main/java/kst4contest/utils/PlayAudioUtils.java b/core/src/main/java/kst4contest/utils/PlayAudioUtils.java similarity index 100% rename from src/main/java/kst4contest/utils/PlayAudioUtils.java rename to core/src/main/java/kst4contest/utils/PlayAudioUtils.java diff --git a/src/main/java/kst4contest/utils/VersionUtils.java b/core/src/main/java/kst4contest/utils/VersionUtils.java similarity index 100% rename from src/main/java/kst4contest/utils/VersionUtils.java rename to core/src/main/java/kst4contest/utils/VersionUtils.java diff --git a/src/main/java/kst4contest/view/map/ChainedTerrainProfileProvider.java b/core/src/main/java/kst4contest/view/map/ChainedTerrainProfileProvider.java similarity index 100% rename from src/main/java/kst4contest/view/map/ChainedTerrainProfileProvider.java rename to core/src/main/java/kst4contest/view/map/ChainedTerrainProfileProvider.java diff --git a/src/main/java/kst4contest/view/map/CopernicusGlo30TerrainProfileProvider.java b/core/src/main/java/kst4contest/view/map/CopernicusGlo30TerrainProfileProvider.java similarity index 100% rename from src/main/java/kst4contest/view/map/CopernicusGlo30TerrainProfileProvider.java rename to core/src/main/java/kst4contest/view/map/CopernicusGlo30TerrainProfileProvider.java diff --git a/src/main/java/kst4contest/view/map/DemDataset.java b/core/src/main/java/kst4contest/view/map/DemDataset.java similarity index 100% rename from src/main/java/kst4contest/view/map/DemDataset.java rename to core/src/main/java/kst4contest/view/map/DemDataset.java diff --git a/src/main/java/kst4contest/view/map/FallbackTerrainProfileProvider.java b/core/src/main/java/kst4contest/view/map/FallbackTerrainProfileProvider.java similarity index 100% rename from src/main/java/kst4contest/view/map/FallbackTerrainProfileProvider.java rename to core/src/main/java/kst4contest/view/map/FallbackTerrainProfileProvider.java diff --git a/src/main/java/kst4contest/view/map/GeometryOnlyPathAnalysisService.java b/core/src/main/java/kst4contest/view/map/GeometryOnlyPathAnalysisService.java similarity index 100% rename from src/main/java/kst4contest/view/map/GeometryOnlyPathAnalysisService.java rename to core/src/main/java/kst4contest/view/map/GeometryOnlyPathAnalysisService.java diff --git a/src/main/java/kst4contest/view/map/MaidenheadGridRenderPlanner.java b/core/src/main/java/kst4contest/view/map/MaidenheadGridRenderPlanner.java similarity index 100% rename from src/main/java/kst4contest/view/map/MaidenheadGridRenderPlanner.java rename to core/src/main/java/kst4contest/view/map/MaidenheadGridRenderPlanner.java diff --git a/src/main/java/kst4contest/view/map/MaidenheadGridUtils.java b/core/src/main/java/kst4contest/view/map/MaidenheadGridUtils.java similarity index 100% rename from src/main/java/kst4contest/view/map/MaidenheadGridUtils.java rename to core/src/main/java/kst4contest/view/map/MaidenheadGridUtils.java diff --git a/src/main/java/kst4contest/view/map/MapCallsignRawSnapshot.java b/core/src/main/java/kst4contest/view/map/MapCallsignRawSnapshot.java similarity index 100% rename from src/main/java/kst4contest/view/map/MapCallsignRawSnapshot.java rename to core/src/main/java/kst4contest/view/map/MapCallsignRawSnapshot.java diff --git a/src/main/java/kst4contest/view/map/MapCallsignRawSnapshotBuilder.java b/core/src/main/java/kst4contest/view/map/MapCallsignRawSnapshotBuilder.java similarity index 96% rename from src/main/java/kst4contest/view/map/MapCallsignRawSnapshotBuilder.java rename to core/src/main/java/kst4contest/view/map/MapCallsignRawSnapshotBuilder.java index 85956153..100891c7 100644 --- a/src/main/java/kst4contest/view/map/MapCallsignRawSnapshotBuilder.java +++ b/core/src/main/java/kst4contest/view/map/MapCallsignRawSnapshotBuilder.java @@ -92,8 +92,14 @@ public final class MapCallsignRawSnapshotBuilder { boolean worked = variants.stream().anyMatch(this::isWorkedAtAnyBand); boolean selected = callSignRaw.equals(selectedCallsignRaw); - double qrbKm = representative.getQrb() != null ? representative.getQrb() : 0.0; - double qtfDeg = representative.getQTFdirection() != null ? representative.getQTFdirection() : 0.0; + /* + * NaN and not 0.0 when the value is absent. Zero is a legitimate reading — + * a station at the operator's own locator is 0 km away — so collapsing null + * onto it destroys the difference between "right here" and "not known", and + * every consumer then shows a distance that was never measured. + */ + double qrbKm = representative.getQrb() != null ? representative.getQrb() : Double.NaN; + double qtfDeg = representative.getQTFdirection() != null ? representative.getQTFdirection() : Double.NaN; int reachableAirplanes = variants.stream() .map(ChatMember::getAirPlaneReflectInfo) diff --git a/core/src/main/java/kst4contest/view/map/MapMarkerCluster.java b/core/src/main/java/kst4contest/view/map/MapMarkerCluster.java new file mode 100644 index 00000000..fd4a2088 --- /dev/null +++ b/core/src/main/java/kst4contest/view/map/MapMarkerCluster.java @@ -0,0 +1,53 @@ +package kst4contest.view.map; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +public final class MapMarkerCluster { + private final List markers = new ArrayList<>(); + private double sumLon = 0.0; + private double sumLat = 0.0; + + public MapMarkerCluster(MapCallsignRawSnapshot first) { + add(first); + } + + public void add(MapCallsignRawSnapshot marker) { + markers.add(marker); + sumLon += marker.longitudeDeg(); + sumLat += marker.latitudeDeg(); + } + + public double getCenterLon() { + return sumLon / markers.size(); + } + + public double getCenterLat() { + return sumLat / markers.size(); + } + + public double getCenterX(int zoom) { + return WebMercatorProjection.lonToX(getCenterLon(), zoom); + } + + public double getCenterY(int zoom) { + return WebMercatorProjection.latToY(getCenterLat(), zoom); + } + + public List getMarkers() { + return Collections.unmodifiableList(markers); + } + + public int size() { + return markers.size(); + } + + public boolean isSingle() { + return markers.size() == 1; + } + + public MapCallsignRawSnapshot getSingle() { + return markers.get(0); + } +} diff --git a/core/src/main/java/kst4contest/view/map/MapMarkerClusterTooltip.java b/core/src/main/java/kst4contest/view/map/MapMarkerClusterTooltip.java new file mode 100644 index 00000000..401f32f5 --- /dev/null +++ b/core/src/main/java/kst4contest/view/map/MapMarkerClusterTooltip.java @@ -0,0 +1,51 @@ +package kst4contest.view.map; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * What hovering a cluster bubble says. + * + * The count first, because that is the question the bubble raises. Then the callsigns, + * alphabetically and capped, because a cell at low zoom can hold a hundred of them and + * a tooltip taller than the window hides the map it was meant to explain. Then the hint + * that clicking zooms in, without which a bubble looks like a dead end. + * + * Kept as the Leaflet tooltip had it (buildClusterTooltipHtml); only the line breaks + * differ, because this one is drawn on a canvas rather than written into HTML. + */ +public final class MapMarkerClusterTooltip { + + /** Twenty, as the Leaflet tooltip did. Beyond that a list stops being readable. */ + public static final int MAX_PREVIEWED_STATIONS = 20; + + private MapMarkerClusterTooltip() { + } + + public static String build(MapMarkerCluster cluster) { + List callsigns = new ArrayList<>(); + for (MapCallsignRawSnapshot marker : cluster.getMarkers()) { + String label = marker.markerLabel(); + if (label != null && !label.isBlank()) { + callsigns.add(label.trim()); + } + } + Collections.sort(callsigns); + + StringBuilder text = new StringBuilder(); + text.append(cluster.size()).append(" stations"); + + int previewed = Math.min(MAX_PREVIEWED_STATIONS, callsigns.size()); + for (int i = 0; i < previewed; i++) { + text.append('\n').append(callsigns.get(i)); + } + + int remaining = callsigns.size() - previewed; + if (remaining > 0) { + text.append('\n').append('+').append(remaining).append(" more"); + } + + return text.append('\n').append("Click to zoom in").toString(); + } +} diff --git a/core/src/main/java/kst4contest/view/map/MapViewport.java b/core/src/main/java/kst4contest/view/map/MapViewport.java new file mode 100644 index 00000000..0a9bdb56 --- /dev/null +++ b/core/src/main/java/kst4contest/view/map/MapViewport.java @@ -0,0 +1,230 @@ +package kst4contest.view.map; + +/** + * What the map currently shows, and where a position lands on the canvas. + * + * Everything the map draws except the tiles is drawn in screen pixels: a station dot is + * 12 px at every zoom, a label is 12 px at every zoom, a grid line is 1.4 px at every + * zoom. Leaflet behaved that way because its overlays live in the DOM above a scaled + * tile layer. The first Compose port instead computed positions at the integer zoom and + * then scaled the whole canvas by the fractional part, which made every drawn size a + * function of that fraction and forced the drawing code to divide each size back out + * again. Sizes were then right at one zoom and wrong at the next. + * + * This class folds the fraction into the projection instead. {@link #screenX(double)} + * and {@link #screenY(double)} answer in canvas pixels, so the drawing code needs no + * scaling and no compensation. Only the tiles are scaled, by {@link #tileScale()}, + * because tiles exist at integer levels only. + * + * Immutable: a viewport describes one frame. Panning and zooming produce a new one. + */ +public final class MapViewport { + + /** + * The range the tile source serves. Leaflet was configured for exactly this + * ({@code KST_MIN_ZOOM}/{@code KST_MAX_ZOOM}); outside it the requested tiles do + * not exist. + */ + public static final double MIN_ZOOM = 3.0; + public static final double MAX_ZOOM = 18.0; + + private static final double TILE_SIZE_PX = 256.0; + + private final double centerLon; + private final double centerLat; + private final double zoom; + private final double widthPx; + private final double heightPx; + + private final int tileZoom; + private final double tileScale; + private final double centerWorldX; + private final double centerWorldY; + + public MapViewport(double centerLon, + double centerLat, + double zoom, + double widthPx, + double heightPx) { + + this.centerLon = normaliseLongitude(centerLon); + this.centerLat = centerLat; + this.zoom = clamp(zoom, MIN_ZOOM, MAX_ZOOM); + this.widthPx = Math.max(0.0, widthPx); + this.heightPx = Math.max(0.0, heightPx); + + this.tileZoom = (int) Math.floor(this.zoom); + this.tileScale = Math.pow(2.0, this.zoom - this.tileZoom); + this.centerWorldX = WebMercatorProjection.lonToX(this.centerLon, this.tileZoom); + this.centerWorldY = WebMercatorProjection.latToY(centerLat, this.tileZoom); + } + + public double centerLon() { + return centerLon; + } + + public double centerLat() { + return centerLat; + } + + /** The zoom actually in force, after clamping to the served range. */ + public double zoom() { + return zoom; + } + + public double widthPx() { + return widthPx; + } + + public double heightPx() { + return heightPx; + } + + /** The integer level the tiles come from. */ + public int tileZoom() { + return tileZoom; + } + + /** What a tile of that level must be scaled by to match the fractional zoom. */ + public double tileScale() { + return tileScale; + } + + /** The on-screen size of one tile, in canvas pixels. */ + public double tileSizePx() { + return TILE_SIZE_PX * tileScale; + } + + public double screenX(double lon) { + return widthPx / 2.0 + (WebMercatorProjection.lonToX(lon, tileZoom) - centerWorldX) * tileScale; + } + + public double screenY(double lat) { + return heightPx / 2.0 + (WebMercatorProjection.latToY(lat, tileZoom) - centerWorldY) * tileScale; + } + + /** Where a world pixel of {@link #tileZoom()} lands on the canvas. */ + public double screenXForWorldX(double worldX) { + return widthPx / 2.0 + (worldX - centerWorldX) * tileScale; + } + + public double screenYForWorldY(double worldY) { + return heightPx / 2.0 + (worldY - centerWorldY) * tileScale; + } + + public double lonAt(double screenX) { + return WebMercatorProjection.xToLon(worldXAt(screenX), tileZoom); + } + + public double latAt(double screenY) { + return WebMercatorProjection.yToLat(worldYAt(screenY), tileZoom); + } + + public double worldXAt(double screenX) { + return centerWorldX + (screenX - widthPx / 2.0) / tileScale; + } + + public double worldYAt(double screenY) { + return centerWorldY + (screenY - heightPx / 2.0) / tileScale; + } + + public double westLon() { + return lonAt(0.0); + } + + public double eastLon() { + return lonAt(widthPx); + } + + /** North is the top of the canvas, which is y = 0. */ + public double northLat() { + return latAt(0.0); + } + + public double southLat() { + return latAt(heightPx); + } + + /** + * The same view moved by a drag, in canvas pixels. + * + * A drag of n pixels moves what was under the pointer by exactly n pixels, which is + * why the delta is divided by the tile scale rather than applied to the world + * coordinates directly. + */ + public MapViewport pannedBy(double deltaX, double deltaY) { + return centredOnWorld( + centerWorldX - deltaX / tileScale, + centerWorldY - deltaY / tileScale, + zoom + ); + } + + /** + * The same view at a different zoom, with the position under + * {@code anchorX}/{@code anchorY} left where it is. + * + * Zooming about the pointer rather than the centre is what makes a wheel zoom feel + * like a map. The anchor's position is read before the zoom changes and the new + * centre is derived from it afterwards, because the world coordinates of a position + * change with the tile level. + */ + public MapViewport zoomedTo(double newZoom, double anchorX, double anchorY) { + double anchorLon = lonAt(anchorX); + double anchorLat = latAt(anchorY); + + double clampedZoom = clamp(newZoom, MIN_ZOOM, MAX_ZOOM); + int newTileZoom = (int) Math.floor(clampedZoom); + double newTileScale = Math.pow(2.0, clampedZoom - newTileZoom); + + double anchorWorldX = WebMercatorProjection.lonToX(anchorLon, newTileZoom); + double anchorWorldY = WebMercatorProjection.latToY(anchorLat, newTileZoom); + + return new MapViewport( + WebMercatorProjection.xToLon(anchorWorldX - (anchorX - widthPx / 2.0) / newTileScale, newTileZoom), + WebMercatorProjection.yToLat(anchorWorldY - (anchorY - heightPx / 2.0) / newTileScale, newTileZoom), + clampedZoom, + widthPx, + heightPx + ); + } + + /** The same view on a canvas of a different size. */ + public MapViewport resizedTo(double newWidthPx, double newHeightPx) { + return new MapViewport(centerLon, centerLat, zoom, newWidthPx, newHeightPx); + } + + private MapViewport centredOnWorld(double worldX, double worldY, double atZoom) { + return new MapViewport( + WebMercatorProjection.xToLon(worldX, tileZoom), + WebMercatorProjection.yToLat(worldY, tileZoom), + atZoom, + widthPx, + heightPx + ); + } + + /** + * Brings a longitude back into [-180, 180). + * + * Panning east is unbounded arithmetic. The tile indices wrap, so the basemap keeps + * drawing, but nothing else does: a centre at longitude 262 puts a station at -170 + * thousands of pixels off the canvas and hands the grid a span it clamps to + * nothing. The stations and the grid then disappear while the map underneath looks + * perfectly fine. + */ + private static double normaliseLongitude(double lon) { + if (!Double.isFinite(lon)) { + return 0.0; + } + double wrapped = (lon + 180.0) % 360.0; + if (wrapped < 0.0) { + wrapped += 360.0; + } + return wrapped - 180.0; + } + + private static double clamp(double value, double min, double max) { + return Math.max(min, Math.min(max, value)); + } +} diff --git a/src/main/java/kst4contest/view/map/NoOpTerrainProfileProvider.java b/core/src/main/java/kst4contest/view/map/NoOpTerrainProfileProvider.java similarity index 100% rename from src/main/java/kst4contest/view/map/NoOpTerrainProfileProvider.java rename to core/src/main/java/kst4contest/view/map/NoOpTerrainProfileProvider.java diff --git a/src/main/java/kst4contest/view/map/OfflineDemImportService.java b/core/src/main/java/kst4contest/view/map/OfflineDemImportService.java similarity index 100% rename from src/main/java/kst4contest/view/map/OfflineDemImportService.java rename to core/src/main/java/kst4contest/view/map/OfflineDemImportService.java diff --git a/src/main/java/kst4contest/view/map/OfflineDemManager.java b/core/src/main/java/kst4contest/view/map/OfflineDemManager.java similarity index 100% rename from src/main/java/kst4contest/view/map/OfflineDemManager.java rename to core/src/main/java/kst4contest/view/map/OfflineDemManager.java diff --git a/src/main/java/kst4contest/view/map/OfflineDemTerrainProfileProvider.java b/core/src/main/java/kst4contest/view/map/OfflineDemTerrainProfileProvider.java similarity index 100% rename from src/main/java/kst4contest/view/map/OfflineDemTerrainProfileProvider.java rename to core/src/main/java/kst4contest/view/map/OfflineDemTerrainProfileProvider.java diff --git a/src/main/java/kst4contest/view/map/OpenMeteoTerrainProfileProvider.java b/core/src/main/java/kst4contest/view/map/OpenMeteoTerrainProfileProvider.java similarity index 100% rename from src/main/java/kst4contest/view/map/OpenMeteoTerrainProfileProvider.java rename to core/src/main/java/kst4contest/view/map/OpenMeteoTerrainProfileProvider.java diff --git a/src/main/java/kst4contest/view/map/PathAnalysisRequest.java b/core/src/main/java/kst4contest/view/map/PathAnalysisRequest.java similarity index 100% rename from src/main/java/kst4contest/view/map/PathAnalysisRequest.java rename to core/src/main/java/kst4contest/view/map/PathAnalysisRequest.java diff --git a/src/main/java/kst4contest/view/map/PathAnalysisResult.java b/core/src/main/java/kst4contest/view/map/PathAnalysisResult.java similarity index 100% rename from src/main/java/kst4contest/view/map/PathAnalysisResult.java rename to core/src/main/java/kst4contest/view/map/PathAnalysisResult.java diff --git a/src/main/java/kst4contest/view/map/PathAnalysisService.java b/core/src/main/java/kst4contest/view/map/PathAnalysisService.java similarity index 100% rename from src/main/java/kst4contest/view/map/PathAnalysisService.java rename to core/src/main/java/kst4contest/view/map/PathAnalysisService.java diff --git a/src/main/java/kst4contest/view/map/PathGeometryUtils.java b/core/src/main/java/kst4contest/view/map/PathGeometryUtils.java similarity index 100% rename from src/main/java/kst4contest/view/map/PathGeometryUtils.java rename to core/src/main/java/kst4contest/view/map/PathGeometryUtils.java diff --git a/src/main/java/kst4contest/view/map/PathHorizonSummary.java b/core/src/main/java/kst4contest/view/map/PathHorizonSummary.java similarity index 100% rename from src/main/java/kst4contest/view/map/PathHorizonSummary.java rename to core/src/main/java/kst4contest/view/map/PathHorizonSummary.java diff --git a/src/main/java/kst4contest/view/map/PathLinkBudgetSettings.java b/core/src/main/java/kst4contest/view/map/PathLinkBudgetSettings.java similarity index 100% rename from src/main/java/kst4contest/view/map/PathLinkBudgetSettings.java rename to core/src/main/java/kst4contest/view/map/PathLinkBudgetSettings.java diff --git a/src/main/java/kst4contest/view/map/PathLinkBudgetSummary.java b/core/src/main/java/kst4contest/view/map/PathLinkBudgetSummary.java similarity index 100% rename from src/main/java/kst4contest/view/map/PathLinkBudgetSummary.java rename to core/src/main/java/kst4contest/view/map/PathLinkBudgetSummary.java diff --git a/src/main/java/kst4contest/view/map/PathObstructionSummary.java b/core/src/main/java/kst4contest/view/map/PathObstructionSummary.java similarity index 100% rename from src/main/java/kst4contest/view/map/PathObstructionSummary.java rename to core/src/main/java/kst4contest/view/map/PathObstructionSummary.java diff --git a/src/main/java/kst4contest/view/map/PathProfilePoint.java b/core/src/main/java/kst4contest/view/map/PathProfilePoint.java similarity index 100% rename from src/main/java/kst4contest/view/map/PathProfilePoint.java rename to core/src/main/java/kst4contest/view/map/PathProfilePoint.java diff --git a/src/main/java/kst4contest/view/map/PathPropagationAssessment.java b/core/src/main/java/kst4contest/view/map/PathPropagationAssessment.java similarity index 100% rename from src/main/java/kst4contest/view/map/PathPropagationAssessment.java rename to core/src/main/java/kst4contest/view/map/PathPropagationAssessment.java diff --git a/core/src/main/java/kst4contest/view/map/StationMapClusterer.java b/core/src/main/java/kst4contest/view/map/StationMapClusterer.java new file mode 100644 index 00000000..6b755237 --- /dev/null +++ b/core/src/main/java/kst4contest/view/map/StationMapClusterer.java @@ -0,0 +1,160 @@ +package kst4contest.view.map; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * Groups stations that sit on top of each other on screen. + * + * The rules come from the Leaflet map and are kept as they were, because an operator + * has learned them: grouping is by screen cell rather than by distance, a cell holds a + * bubble only from three stations upwards, grouping stops once the map is zoomed in far + * enough to show everything, and two kinds of station are never hidden in a bubble. + * + * Screen based and not locator based on purpose. The problem being solved is too many + * labels in one part of the window, and that is a question about pixels. + * + * The first Compose port replaced this with nearest-neighbour grouping at a fixed 50 px + * from two stations upwards and never switched it off, which put a "2" bubble over + * most of the map. + */ +public final class StationMapClusterer { + + /** + * Two nearby stations are still readable and should stay individually clickable, so + * a bubble starts at three. + */ + public static final int MIN_STATIONS_PER_CLUSTER = 3; + + /** From this zoom upwards the map shows every station. */ + public static final double DISABLE_AT_ZOOM = 8.0; + + private static final double CELL_SIZE_HIGH_ZOOM_PX = 55.0; + private static final double CELL_SIZE_MEDIUM_ZOOM_PX = 70.0; + private static final double CELL_SIZE_LOW_ZOOM_PX = 95.0; + private static final double CELL_SIZE_VERY_LOW_ZOOM_PX = 125.0; + + private StationMapClusterer() { + } + + /** + * What the map should draw: bubbles for the crowded cells, single markers for + * everything else. + * + * @param clusters stations grouped into a bubble; never fewer than + * {@link #MIN_STATIONS_PER_CLUSTER} in one + * @param individual stations to draw as themselves, with their label + */ + public record Result(List clusters, List individual) { + + public Result { + clusters = List.copyOf(clusters); + individual = List.copyOf(individual); + } + } + + /** + * @param viewport decides both the cell size, through its zoom, and which screen + * cell a station falls into + * @param clusteringEnabled the operator's "Group nearby stations" setting + */ + public static Result cluster(List markers, + MapViewport viewport, + boolean clusteringEnabled) { + + if (markers == null || markers.isEmpty()) { + return new Result(List.of(), List.of()); + } + + List positioned = new ArrayList<>(); + for (MapCallsignRawSnapshot marker : markers) { + if (marker != null && marker.hasUsablePosition()) { + positioned.add(marker); + } + } + + if (!clusteringEnabled || viewport.zoom() >= DISABLE_AT_ZOOM) { + return new Result(List.of(), positioned); + } + + double cellSizePx = cellSizePxForZoom(viewport.zoom()); + + List individual = new ArrayList<>(); + Map> buckets = new LinkedHashMap<>(); + + for (MapCallsignRawSnapshot marker : positioned) { + if (mustStayVisible(marker)) { + individual.add(marker); + continue; + } + + long cellX = (long) Math.floor(viewport.screenX(marker.longitudeDeg()) / cellSizePx); + long cellY = (long) Math.floor(viewport.screenY(marker.latitudeDeg()) / cellSizePx); + + buckets.computeIfAbsent(cellKey(cellX, cellY), key -> new ArrayList<>()).add(marker); + } + + List clusters = new ArrayList<>(); + for (List bucket : buckets.values()) { + if (bucket.size() >= MIN_STATIONS_PER_CLUSTER) { + MapMarkerCluster cluster = new MapMarkerCluster(bucket.get(0)); + for (int i = 1; i < bucket.size(); i++) { + cluster.add(bucket.get(i)); + } + clusters.add(cluster); + } else { + individual.addAll(bucket); + } + } + + return new Result(Collections.unmodifiableList(clusters), Collections.unmodifiableList(individual)); + } + + /** + * The zoom at which a station the operator just selected is drawn as itself. + * + * Their current zoom, unless grouping would hide the station inside a bubble — and + * then only far enough to break the bubble open. Selecting a station is not a + * reason to throw away the zoom they chose. + */ + public static double zoomToRevealStations(double currentZoom, boolean clusteringEnabled) { + if (!clusteringEnabled) { + return currentZoom; + } + return Math.max(currentZoom, DISABLE_AT_ZOOM); + } + + /** + * The cluster grid size in screen pixels for a zoom level. + * + * Smaller cells make grouping less eager: stations have to be closer together on + * screen before they are grouped at all. + */ + public static double cellSizePxForZoom(double zoom) { + if (zoom >= 7.0) { + return CELL_SIZE_HIGH_ZOOM_PX; + } + if (zoom >= 6.0) { + return CELL_SIZE_MEDIUM_ZOOM_PX; + } + if (zoom >= 5.0) { + return CELL_SIZE_LOW_ZOOM_PX; + } + return CELL_SIZE_VERY_LOW_ZOOM_PX; + } + + /** + * The station the operator is working, and the one pointing at their antenna. A + * bubble over either of them hides the thing it was opened for. + */ + private static boolean mustStayVisible(MapCallsignRawSnapshot marker) { + return marker.selected() || marker.warningToMyDirection(); + } + + private static long cellKey(long cellX, long cellY) { + return (cellX << 32) ^ (cellY & 0xFFFFFFFFL); + } +} diff --git a/core/src/main/java/kst4contest/view/map/StationMapStatusText.java b/core/src/main/java/kst4contest/view/map/StationMapStatusText.java new file mode 100644 index 00000000..2052f36b --- /dev/null +++ b/core/src/main/java/kst4contest/view/map/StationMapStatusText.java @@ -0,0 +1,99 @@ +package kst4contest.view.map; + +import java.util.Locale; + +/** + * The one line of text above the station map. + * + * It is the only place the operator is told how many stations are on the map, whether a + * filter is hiding some of them, and what is known about the one they picked. It lives + * in core rather than beside the window because it is string building with rules, and + * because the Compose port lost all of it but the callsign — a loss no test could see + * while it was written inline in the window. + * + * The wording and the separators are the ones {@code StationMapView.updateStatusLabel()} + * has produced since release 1.4x and are not ours to change casually. + */ +public final class StationMapStatusText { + + private static final String SEPARATOR = " | "; + private static final String UNAVAILABLE = "-"; + + private StationMapStatusText() { + } + + /** + * @param visibleStationCount how many markers the map was handed + * @param filteredViewActive whether a filter is hiding stations, without which the + * count reads as "that is everyone on the band" + * @param selected the station the operator picked, or null + */ + public static String build(int visibleStationCount, + boolean filteredViewActive, + MapCallsignRawSnapshot selected) { + + StringBuilder text = new StringBuilder(); + text.append("Showing ").append(visibleStationCount).append(" visible stations"); + + if (filteredViewActive) { + text.append(SEPARATOR).append("filtered view active"); + } + + if (selected == null) { + return text.toString(); + } + + text.append(SEPARATOR).append("Selected: ").append(selected.displayCallSign()); + + if (!selected.locator6().isBlank()) { + text.append(SEPARATOR).append(selected.locator6()); + } + + text.append(SEPARATOR) + .append(distanceAndBearingText(selected.qrbKm(), selected.qtfDeg())); + + text.append(SEPARATOR).append("Bands: ").append(bands(selected)); + + /* + * "-" is kept rather than dropped. A station whose frequency is not known is + * different from one whose frequency fell off the end of an ellipsis, and the + * operator can only tell the two apart if the field is there. + */ + String frequencies = singleLine(selected.detailFrequencyText()); + if (!frequencies.isBlank()) { + text.append(SEPARATOR).append("QRG: ").append(frequencies); + } + + return text.toString(); + } + + /** + * Distance and bearing can both be absent, and absent is not zero. + * + * Public because the JavaFX status label shows the same pair and must not disagree + * with this one while both windows exist. + */ + public static String distanceAndBearingText(double qrbKm, double qtfDeg) { + return formatRounded(qrbKm, " km") + " / " + formatRounded(qtfDeg, "°"); + } + + private static String formatRounded(double value, String unit) { + if (!Double.isFinite(value)) { + return UNAVAILABLE; + } + return String.format(Locale.US, "%.0f", value) + unit; + } + + private static String bands(MapCallsignRawSnapshot selected) { + String bandText = selected.bandSummary().isBlank() ? UNAVAILABLE : selected.bandSummary(); + return selected.offersSelectedBand() ? bandText + " B+" : bandText; + } + + /** The detail text is written over several lines; the status bar has one. */ + private static String singleLine(String raw) { + if (raw == null) { + return ""; + } + return raw.replace('\n', ' ').replace('\r', ' ').replaceAll("\\s+", " ").trim(); + } +} diff --git a/src/main/java/kst4contest/view/map/SyntheticTerrainProfileProvider.java b/core/src/main/java/kst4contest/view/map/SyntheticTerrainProfileProvider.java similarity index 100% rename from src/main/java/kst4contest/view/map/SyntheticTerrainProfileProvider.java rename to core/src/main/java/kst4contest/view/map/SyntheticTerrainProfileProvider.java diff --git a/src/main/java/kst4contest/view/map/TerrainCatalog.java b/core/src/main/java/kst4contest/view/map/TerrainCatalog.java similarity index 100% rename from src/main/java/kst4contest/view/map/TerrainCatalog.java rename to core/src/main/java/kst4contest/view/map/TerrainCatalog.java diff --git a/src/main/java/kst4contest/view/map/TerrainCatalogClient.java b/core/src/main/java/kst4contest/view/map/TerrainCatalogClient.java similarity index 100% rename from src/main/java/kst4contest/view/map/TerrainCatalogClient.java rename to core/src/main/java/kst4contest/view/map/TerrainCatalogClient.java diff --git a/src/main/java/kst4contest/view/map/TerrainCatalogPackageEntry.java b/core/src/main/java/kst4contest/view/map/TerrainCatalogPackageEntry.java similarity index 100% rename from src/main/java/kst4contest/view/map/TerrainCatalogPackageEntry.java rename to core/src/main/java/kst4contest/view/map/TerrainCatalogPackageEntry.java diff --git a/src/main/java/kst4contest/view/map/TerrainCoverageResolver.java b/core/src/main/java/kst4contest/view/map/TerrainCoverageResolver.java similarity index 100% rename from src/main/java/kst4contest/view/map/TerrainCoverageResolver.java rename to core/src/main/java/kst4contest/view/map/TerrainCoverageResolver.java diff --git a/src/main/java/kst4contest/view/map/TerrainPackageDownloader.java b/core/src/main/java/kst4contest/view/map/TerrainPackageDownloader.java similarity index 100% rename from src/main/java/kst4contest/view/map/TerrainPackageDownloader.java rename to core/src/main/java/kst4contest/view/map/TerrainPackageDownloader.java diff --git a/src/main/java/kst4contest/view/map/TerrainPackageInstaller.java b/core/src/main/java/kst4contest/view/map/TerrainPackageInstaller.java similarity index 100% rename from src/main/java/kst4contest/view/map/TerrainPackageInstaller.java rename to core/src/main/java/kst4contest/view/map/TerrainPackageInstaller.java diff --git a/src/main/java/kst4contest/view/map/TerrainPackageManifest.java b/core/src/main/java/kst4contest/view/map/TerrainPackageManifest.java similarity index 100% rename from src/main/java/kst4contest/view/map/TerrainPackageManifest.java rename to core/src/main/java/kst4contest/view/map/TerrainPackageManifest.java diff --git a/src/main/java/kst4contest/view/map/TerrainPackageService.java b/core/src/main/java/kst4contest/view/map/TerrainPackageService.java similarity index 100% rename from src/main/java/kst4contest/view/map/TerrainPackageService.java rename to core/src/main/java/kst4contest/view/map/TerrainPackageService.java diff --git a/src/main/java/kst4contest/view/map/TerrainProfileCacheRepository.java b/core/src/main/java/kst4contest/view/map/TerrainProfileCacheRepository.java similarity index 78% rename from src/main/java/kst4contest/view/map/TerrainProfileCacheRepository.java rename to core/src/main/java/kst4contest/view/map/TerrainProfileCacheRepository.java index c01b5e0e..94b29701 100644 --- a/src/main/java/kst4contest/view/map/TerrainProfileCacheRepository.java +++ b/core/src/main/java/kst4contest/view/map/TerrainProfileCacheRepository.java @@ -1,9 +1,11 @@ package kst4contest.view.map; import kst4contest.ApplicationConstants; -import kst4contest.controller.DBController; import kst4contest.utils.ApplicationFileUtils; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; @@ -15,30 +17,44 @@ import java.util.Locale; import java.util.Optional; /** - * Persistent terrain profile cache stored in the application's existing SQLite database. + * Persistent terrain profile cache, stored globally in its own SQLite database. * - * The cache is intentionally owner-bound: - * if the configured own callsign or own locator changes, all cached terrain - * profiles are cleared automatically. + *

Terrain profiles are pure geometry derived from two locators and a sample count. + * They do not belong to one operator, so the cache is deliberately not part of an + * operator profile: at a multi operator station both operators share one location, and + * duplicating the cache would double the traffic against an external terrain service.

+ * + *

Entries are separated by owner identity through the primary key instead. Earlier + * versions kept a single owner identity and dropped the whole cache whenever the + * configured callsign or locator changed; with several operator profiles that would + * discard every computed profile on each switch.

*/ public final class TerrainProfileCacheRepository { - private static final String META_KEY_OWNER_CALLSIGN_RAW = "terrain_cache_owner_callsign_raw"; - private static final String META_KEY_OWNER_LOCATOR6 = "terrain_cache_owner_locator6"; + /** + * File name of the global terrain profile cache below the application directory. + */ + public static final String TERRAIN_CACHE_DATABASE_FILE = "terrainprofilecache.db"; private final String databasePath; public TerrainProfileCacheRepository() { - ApplicationFileUtils.copyResourceIfRequired( - ApplicationConstants.APPLICATION_NAME, - DBController.DATABASE_RESOURCE, - DBController.DATABASE_FILE - ); - this.databasePath = ApplicationFileUtils.getFilePath( ApplicationConstants.APPLICATION_NAME, - DBController.DATABASE_FILE + TERRAIN_CACHE_DATABASE_FILE ); + + // SQLite only creates the database file itself, not the directory holding it. + Path applicationDirectory = Path.of(databasePath).getParent(); + + if (applicationDirectory != null) { + try { + Files.createDirectories(applicationDirectory); + } catch (IOException exception) { + System.err.println("[StationMap] Terrain cache directory could not be created: " + + exception.getMessage()); + } + } } public synchronized Optional load(String ownerCallsignRaw, @@ -183,60 +199,37 @@ public final class TerrainProfileCacheRepository { """); statement.executeUpdate(""" - CREATE TABLE IF NOT EXISTS TerrainProfileCacheMeta ( - meta_key TEXT NOT NULL PRIMARY KEY, - meta_value TEXT NOT NULL + CREATE TABLE IF NOT EXISTS TerrainProfileCacheOwner ( + owner_callsign_raw TEXT NOT NULL, + owner_locator6 TEXT NOT NULL, + last_used_epoch_ms INTEGER NOT NULL, + PRIMARY KEY (owner_callsign_raw, owner_locator6) ) """); } } + /** + * Records that the given owner identity is in use. + * + *

Entries of other owners stay untouched. The cached profiles of an identity are + * separated by the primary key already, so a different callsign or locator simply + * misses the cache instead of invalidating everybody else's entries.

+ */ private void ensureOwnerIdentity(Connection connection, String currentOwnerCallsignRaw, String currentOwnerLocator6) throws Exception { - String normalizedOwnerCallsignRaw = normalize(currentOwnerCallsignRaw); - String normalizedOwnerLocator6 = normalize(currentOwnerLocator6); - - String storedOwnerCallsignRaw = readMetaValue(connection, META_KEY_OWNER_CALLSIGN_RAW); - String storedOwnerLocator6 = readMetaValue(connection, META_KEY_OWNER_LOCATOR6); - - boolean callsignChanged = storedOwnerCallsignRaw != null && !storedOwnerCallsignRaw.equals(normalizedOwnerCallsignRaw); - boolean locatorChanged = storedOwnerLocator6 != null && !storedOwnerLocator6.equals(normalizedOwnerLocator6); - - if (callsignChanged || locatorChanged) { - clearTerrainCache(connection); - } - - writeMetaValue(connection, META_KEY_OWNER_CALLSIGN_RAW, normalizedOwnerCallsignRaw); - writeMetaValue(connection, META_KEY_OWNER_LOCATOR6, normalizedOwnerLocator6); - } - - private void clearTerrainCache(Connection connection) throws Exception { - try (Statement statement = connection.createStatement()) { - statement.executeUpdate("DELETE FROM TerrainProfileCache"); - } - } - - private String readMetaValue(Connection connection, String key) throws Exception { - try (PreparedStatement statement = connection.prepareStatement( - "SELECT meta_value FROM TerrainProfileCacheMeta WHERE meta_key = ?")) { - statement.setString(1, key); - - try (ResultSet resultSet = statement.executeQuery()) { - return resultSet.next() ? resultSet.getString(1) : null; - } - } - } - - private void writeMetaValue(Connection connection, String key, String value) throws Exception { try (PreparedStatement statement = connection.prepareStatement(""" - INSERT INTO TerrainProfileCacheMeta (meta_key, meta_value) - VALUES (?, ?) - ON CONFLICT(meta_key) DO UPDATE SET meta_value = excluded.meta_value + INSERT INTO TerrainProfileCacheOwner ( + owner_callsign_raw, owner_locator6, last_used_epoch_ms + ) VALUES (?, ?, ?) + ON CONFLICT(owner_callsign_raw, owner_locator6) DO UPDATE SET + last_used_epoch_ms = excluded.last_used_epoch_ms """)) { - statement.setString(1, key); - statement.setString(2, value == null ? "" : value); + statement.setString(1, normalize(currentOwnerCallsignRaw)); + statement.setString(2, normalize(currentOwnerLocator6)); + statement.setLong(3, System.currentTimeMillis()); statement.executeUpdate(); } } diff --git a/src/main/java/kst4contest/view/map/TerrainProfileData.java b/core/src/main/java/kst4contest/view/map/TerrainProfileData.java similarity index 100% rename from src/main/java/kst4contest/view/map/TerrainProfileData.java rename to core/src/main/java/kst4contest/view/map/TerrainProfileData.java diff --git a/src/main/java/kst4contest/view/map/TerrainProfileProvider.java b/core/src/main/java/kst4contest/view/map/TerrainProfileProvider.java similarity index 100% rename from src/main/java/kst4contest/view/map/TerrainProfileProvider.java rename to core/src/main/java/kst4contest/view/map/TerrainProfileProvider.java diff --git a/src/main/java/kst4contest/view/map/TerrainProfileRequest.java b/core/src/main/java/kst4contest/view/map/TerrainProfileRequest.java similarity index 100% rename from src/main/java/kst4contest/view/map/TerrainProfileRequest.java rename to core/src/main/java/kst4contest/view/map/TerrainProfileRequest.java diff --git a/src/main/java/kst4contest/view/map/TerrainTileMetadata.java b/core/src/main/java/kst4contest/view/map/TerrainTileMetadata.java similarity index 100% rename from src/main/java/kst4contest/view/map/TerrainTileMetadata.java rename to core/src/main/java/kst4contest/view/map/TerrainTileMetadata.java diff --git a/core/src/main/java/kst4contest/view/map/TileFetcher.java b/core/src/main/java/kst4contest/view/map/TileFetcher.java new file mode 100644 index 00000000..58ddf2b3 --- /dev/null +++ b/core/src/main/java/kst4contest/view/map/TileFetcher.java @@ -0,0 +1,311 @@ +package kst4contest.view.map; + +import kst4contest.utils.ApplicationFileUtils; + +import java.io.IOException; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.StandardCopyOption; +import java.time.Duration; +import java.util.Collections; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * Supplies map tiles, from memory, from disk, or from OpenStreetMap, in that order. + * + * Three rules it has to keep. The tile service asks callers to identify themselves and + * not to re-download what they already have, which is what the disk cache is for — a + * contest station restarts the client more than once an evening and the view it comes + * back to is the view it left. The retired {@code a}/{@code b}/{@code c} subdomains are + * not used. And a request that fails is counted and visible through + * {@link #hasReachedTileSource()}, because the alternative is what the first version + * did: return null quietly and leave the operator looking at an empty map with no idea + * whether the problem was the network or the band. + */ +public final class TileFetcher { + + private static final int MEMORY_CACHE_MAX_TILES = 2048; + + /** + * OpenStreetMap's tile usage policy allows a client at most two concurrent + * downloads. Going wider fills the map faster and gets the application blocked. + */ + public static final int MAX_CONCURRENT_REQUESTS = 2; + + /** + * How long a tile that failed is left alone. + * + * The map re-requests every visible tile whenever the view changes, so without a + * pause a server answering 429 would be asked again on every drag — which the same + * usage policy calls abuse, and which is how a client gets blocked rather than + * throttled. + */ + private static final Duration DEFAULT_RETRY_PAUSE = Duration.ofSeconds(30); + + /** + * OpenStreetMap's tile usage policy asks for an identifying agent. A generic one + * gets the whole application blocked rather than throttled. + */ + private static final String USER_AGENT = "kst4contest/1.0 amateur-radio-contest-tool"; + + private static final String TILE_HOST = "https://tile.openstreetmap.org"; + + /** Where a tile comes from when neither cache has it. Replaced in tests. */ + public interface TileSource { + byte[] fetch(String url) throws IOException, InterruptedException; + } + + private final TileSource source; + private final Path cacheDirectory; + private final ExecutorService executor; + private final Map memoryCache; + + private final AtomicInteger failedRequests = new AtomicInteger(); + + /* + * Which happened more recently, an arrival or a failure. A single latched "we got a + * tile once" flag cannot answer the question the warning is for: after a restart + * without a network, the first tile out of the disk cache would set it and every + * failure after that would be silent. Counters rather than timestamps, so the + * comparison does not depend on clock resolution. + */ + private final Duration retryPause; + + /** When each recently failed tile may be asked for again. */ + private final Map retryNotBeforeNanos = new java.util.concurrent.ConcurrentHashMap<>(); + + private final AtomicInteger arrivals = new AtomicInteger(); + private final AtomicInteger lastArrivalAtFailureCount = new AtomicInteger(-1); + private final AtomicBoolean closed = new AtomicBoolean(false); + + public TileFetcher() { + this(defaultCacheDirectory(), new HttpTileSource()); + } + + public TileFetcher(Path cacheDirectory, TileSource source) { + this(cacheDirectory, source, DEFAULT_RETRY_PAUSE); + } + + public TileFetcher(Path cacheDirectory, TileSource source, Duration retryPause) { + this.cacheDirectory = cacheDirectory; + this.source = source; + this.retryPause = retryPause; + this.executor = Executors.newFixedThreadPool(MAX_CONCURRENT_REQUESTS, runnable -> { + Thread thread = new Thread(runnable, "map-tile-fetch"); + thread.setDaemon(true); + return thread; + }); + + this.memoryCache = Collections.synchronizedMap( + new LinkedHashMap<>(MEMORY_CACHE_MAX_TILES, 0.75f, true) { + @Override + protected boolean removeEldestEntry(Map.Entry eldest) { + return size() > MEMORY_CACHE_MAX_TILES; + } + } + ); + } + + /** The tile directory beside the rest of the application's files. */ + public static Path defaultCacheDirectory() { + return Path.of(ApplicationFileUtils.getFilePath("kst4contest", "tile-cache")); + } + + public static String tileUrl(int zoom, int x, int y) { + return TILE_HOST + "/" + zoom + "/" + x + "/" + y + ".png"; + } + + /** + * @return the tile, or null when it could not be had. Null is a gap in the map, not + * an error to act on; {@link #hasReachedTileSource()} is what tells the map + * whether to say something about it. + */ + public CompletableFuture fetchTileAsync(int zoom, int x, int y) { + String key = zoom + "/" + x + "/" + y; + + byte[] fromMemory = memoryCache.get(key); + if (fromMemory != null) { + return CompletableFuture.completedFuture(fromMemory); + } + + return CompletableFuture.supplyAsync(() -> loadTile(zoom, x, y, key), executor); + } + + private byte[] loadTile(int zoom, int x, int y, String key) { + byte[] fromDisk = readFromDisk(zoom, x, y); + if (fromDisk != null) { + memoryCache.put(key, fromDisk); + recordArrival(); + return fromDisk; + } + + Long notBefore = retryNotBeforeNanos.get(key); + if (notBefore != null && System.nanoTime() < notBefore) { + /* Still inside the pause after a failure; do not ask again yet. */ + return null; + } + + try { + byte[] tile = source.fetch(tileUrl(zoom, x, y)); + if (tile == null || tile.length == 0) { + recordFailure(key); + return null; + } + + memoryCache.put(key, tile); + writeToDisk(zoom, x, y, tile); + retryNotBeforeNanos.remove(key); + recordArrival(); + return tile; + } catch (InterruptedException interrupted) { + Thread.currentThread().interrupt(); + recordFailure(key); + return null; + } catch (Exception unreachable) { + /* Held back, not cached: after the pause the next pan tries again. */ + recordFailure(key); + return null; + } + } + + /** + * Whether the map should say that tiles are not arriving. + * + * True once a request has failed and nothing has arrived since — from the network + * or from the disk cache. It therefore covers both the restart without a network + * and the network lost halfway through an evening, and it clears itself as soon as + * a tile comes in again. + */ + public boolean isTileSourceUnavailable() { + int failures = failedRequests.get(); + return failures > 0 && lastArrivalAtFailureCount.get() < failures; + } + + /** Whether any tile has ever arrived, from either cache or the network. */ + public boolean hasReachedTileSource() { + return arrivals.get() > 0; + } + + public int failedRequestCount() { + return failedRequests.get(); + } + + /** + * Forgets a tile that turned out to be unusable, on disk as well as in memory. + * + * The caller is the only one who can tell: this class hands out bytes, and whether + * they decode into an image is discovered one layer further up. Without this a + * truncated file — the process died mid-write — is served again on every later run + * and that square of the map stays blank for good. + */ + public void discardTile(int zoom, int x, int y) { + memoryCache.remove(zoom + "/" + x + "/" + y); + try { + Files.deleteIfExists(tilePath(zoom, x, y)); + } catch (Exception undeletable) { + /* Then it stays, and the map has a gap rather than a crash. */ + } + } + + /** + * Stops the fetch threads. + * + * Not optional housekeeping: a live pool thread is a GC root, so an unclosed + * fetcher holds its whole memory cache reachable. The map window builds one per + * open, and an evening of opening and closing it would retain every one of them. + */ + public void close() { + if (closed.compareAndSet(false, true)) { + executor.shutdownNow(); + } + } + + public boolean isClosed() { + return closed.get(); + } + + private void recordFailure(String key) { + failedRequests.incrementAndGet(); + retryNotBeforeNanos.put(key, System.nanoTime() + retryPause.toNanos()); + } + + private void recordArrival() { + arrivals.incrementAndGet(); + lastArrivalAtFailureCount.set(failedRequests.get()); + } + + private Path tilePath(int zoom, int x, int y) { + return cacheDirectory.resolve(String.valueOf(zoom)).resolve(String.valueOf(x)).resolve(y + ".png"); + } + + private byte[] readFromDisk(int zoom, int x, int y) { + try { + Path path = tilePath(zoom, x, y); + return Files.exists(path) ? Files.readAllBytes(path) : null; + } catch (Exception unreadable) { + /* A cache is an optimisation. An unreadable one is a cache miss. */ + return null; + } + } + + /** + * Written under a temporary name and then moved into place. + * + * A plain write is not atomic. If the process dies partway through — battery, a + * kill, an operating-system shutdown — a truncated file is left under the real name + * and is served as a tile on every later run. + */ + private void writeToDisk(int zoom, int x, int y, byte[] tile) { + Path path = tilePath(zoom, x, y); + Path partial = path.resolveSibling(path.getFileName() + ".tmp"); + try { + Files.createDirectories(path.getParent()); + Files.write(partial, tile); + Files.move(partial, path, StandardCopyOption.ATOMIC_MOVE, StandardCopyOption.REPLACE_EXISTING); + } catch (Exception unwritable) { + /* A read-only or full disk costs the cache, not the map. */ + try { + Files.deleteIfExists(partial); + } catch (Exception alsoUndeletable) { + /* Nothing further to try; a stray temporary file is harmless. */ + } + } + } + + /** The real source: one HTTPS request per tile. */ + private static final class HttpTileSource implements TileSource { + + private final HttpClient httpClient = HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(10)) + .followRedirects(HttpClient.Redirect.NORMAL) + .build(); + + @Override + public byte[] fetch(String url) throws IOException, InterruptedException { + HttpRequest request = HttpRequest.newBuilder() + .uri(URI.create(url)) + .header("User-Agent", USER_AGENT) + .timeout(Duration.ofSeconds(15)) + .GET() + .build(); + + HttpResponse response = + httpClient.send(request, HttpResponse.BodyHandlers.ofByteArray()); + + if (response.statusCode() != 200) { + throw new IOException("tile request answered " + response.statusCode()); + } + return response.body(); + } + } +} diff --git a/core/src/main/java/kst4contest/view/map/WebMercatorProjection.java b/core/src/main/java/kst4contest/view/map/WebMercatorProjection.java new file mode 100644 index 00000000..bde98234 --- /dev/null +++ b/core/src/main/java/kst4contest/view/map/WebMercatorProjection.java @@ -0,0 +1,33 @@ +package kst4contest.view.map; + +/** + * Standard EPSG:3857 Web Mercator projection mathematics. + */ +public final class WebMercatorProjection { + + private WebMercatorProjection() { + } + + public static double lonToX(double lon, int zoom) { + double n = Math.pow(2.0, zoom); + return ((lon + 180.0) / 360.0) * 256.0 * n; + } + + public static double latToY(double lat, int zoom) { + double latRad = Math.toRadians(lat); + double n = Math.pow(2.0, zoom); + double y = (1.0 - Math.log(Math.tan(latRad) + (1.0 / Math.cos(latRad))) / Math.PI) / 2.0; + return y * 256.0 * n; + } + + public static double xToLon(double x, int zoom) { + double n = Math.pow(2.0, zoom); + return (x / (256.0 * n)) * 360.0 - 180.0; + } + + public static double yToLat(double y, int zoom) { + double n = Math.pow(2.0, zoom); + double latRad = Math.atan(Math.sinh(Math.PI * (1.0 - 2.0 * y / (256.0 * n)))); + return Math.toDegrees(latRad); + } +} diff --git a/src/main/java/kst4contest/view/map/mapTest.java b/core/src/main/java/kst4contest/view/map/mapTest.java similarity index 100% rename from src/main/java/kst4contest/view/map/mapTest.java rename to core/src/main/java/kst4contest/view/map/mapTest.java diff --git a/src/main/resources/LTTR0.mp3 b/core/src/main/resources/LTTR0.mp3 similarity index 100% rename from src/main/resources/LTTR0.mp3 rename to core/src/main/resources/LTTR0.mp3 diff --git a/src/main/resources/LTTR1.mp3 b/core/src/main/resources/LTTR1.mp3 similarity index 100% rename from src/main/resources/LTTR1.mp3 rename to core/src/main/resources/LTTR1.mp3 diff --git a/src/main/resources/LTTR2.mp3 b/core/src/main/resources/LTTR2.mp3 similarity index 100% rename from src/main/resources/LTTR2.mp3 rename to core/src/main/resources/LTTR2.mp3 diff --git a/src/main/resources/LTTR3.mp3 b/core/src/main/resources/LTTR3.mp3 similarity index 100% rename from src/main/resources/LTTR3.mp3 rename to core/src/main/resources/LTTR3.mp3 diff --git a/src/main/resources/LTTR4.mp3 b/core/src/main/resources/LTTR4.mp3 similarity index 100% rename from src/main/resources/LTTR4.mp3 rename to core/src/main/resources/LTTR4.mp3 diff --git a/src/main/resources/LTTR5.mp3 b/core/src/main/resources/LTTR5.mp3 similarity index 100% rename from src/main/resources/LTTR5.mp3 rename to core/src/main/resources/LTTR5.mp3 diff --git a/src/main/resources/LTTR6.mp3 b/core/src/main/resources/LTTR6.mp3 similarity index 100% rename from src/main/resources/LTTR6.mp3 rename to core/src/main/resources/LTTR6.mp3 diff --git a/src/main/resources/LTTR7.mp3 b/core/src/main/resources/LTTR7.mp3 similarity index 100% rename from src/main/resources/LTTR7.mp3 rename to core/src/main/resources/LTTR7.mp3 diff --git a/src/main/resources/LTTR8.mp3 b/core/src/main/resources/LTTR8.mp3 similarity index 100% rename from src/main/resources/LTTR8.mp3 rename to core/src/main/resources/LTTR8.mp3 diff --git a/src/main/resources/LTTR9.mp3 b/core/src/main/resources/LTTR9.mp3 similarity index 100% rename from src/main/resources/LTTR9.mp3 rename to core/src/main/resources/LTTR9.mp3 diff --git a/src/main/resources/LTTRA.mp3 b/core/src/main/resources/LTTRA.mp3 similarity index 100% rename from src/main/resources/LTTRA.mp3 rename to core/src/main/resources/LTTRA.mp3 diff --git a/src/main/resources/LTTRB.mp3 b/core/src/main/resources/LTTRB.mp3 similarity index 100% rename from src/main/resources/LTTRB.mp3 rename to core/src/main/resources/LTTRB.mp3 diff --git a/src/main/resources/LTTRC.mp3 b/core/src/main/resources/LTTRC.mp3 similarity index 100% rename from src/main/resources/LTTRC.mp3 rename to core/src/main/resources/LTTRC.mp3 diff --git a/src/main/resources/LTTRD.mp3 b/core/src/main/resources/LTTRD.mp3 similarity index 100% rename from src/main/resources/LTTRD.mp3 rename to core/src/main/resources/LTTRD.mp3 diff --git a/src/main/resources/LTTRE.mp3 b/core/src/main/resources/LTTRE.mp3 similarity index 100% rename from src/main/resources/LTTRE.mp3 rename to core/src/main/resources/LTTRE.mp3 diff --git a/src/main/resources/LTTRF.mp3 b/core/src/main/resources/LTTRF.mp3 similarity index 100% rename from src/main/resources/LTTRF.mp3 rename to core/src/main/resources/LTTRF.mp3 diff --git a/src/main/resources/LTTRG.mp3 b/core/src/main/resources/LTTRG.mp3 similarity index 100% rename from src/main/resources/LTTRG.mp3 rename to core/src/main/resources/LTTRG.mp3 diff --git a/src/main/resources/LTTRH.mp3 b/core/src/main/resources/LTTRH.mp3 similarity index 100% rename from src/main/resources/LTTRH.mp3 rename to core/src/main/resources/LTTRH.mp3 diff --git a/src/main/resources/LTTRI.mp3 b/core/src/main/resources/LTTRI.mp3 similarity index 100% rename from src/main/resources/LTTRI.mp3 rename to core/src/main/resources/LTTRI.mp3 diff --git a/src/main/resources/LTTRJ.mp3 b/core/src/main/resources/LTTRJ.mp3 similarity index 100% rename from src/main/resources/LTTRJ.mp3 rename to core/src/main/resources/LTTRJ.mp3 diff --git a/src/main/resources/LTTRK.mp3 b/core/src/main/resources/LTTRK.mp3 similarity index 100% rename from src/main/resources/LTTRK.mp3 rename to core/src/main/resources/LTTRK.mp3 diff --git a/src/main/resources/LTTRL.mp3 b/core/src/main/resources/LTTRL.mp3 similarity index 100% rename from src/main/resources/LTTRL.mp3 rename to core/src/main/resources/LTTRL.mp3 diff --git a/src/main/resources/LTTRM.mp3 b/core/src/main/resources/LTTRM.mp3 similarity index 100% rename from src/main/resources/LTTRM.mp3 rename to core/src/main/resources/LTTRM.mp3 diff --git a/src/main/resources/LTTRMINUS.mp3 b/core/src/main/resources/LTTRMINUS.mp3 similarity index 100% rename from src/main/resources/LTTRMINUS.mp3 rename to core/src/main/resources/LTTRMINUS.mp3 diff --git a/src/main/resources/LTTRN.mp3 b/core/src/main/resources/LTTRN.mp3 similarity index 100% rename from src/main/resources/LTTRN.mp3 rename to core/src/main/resources/LTTRN.mp3 diff --git a/src/main/resources/LTTRO.mp3 b/core/src/main/resources/LTTRO.mp3 similarity index 100% rename from src/main/resources/LTTRO.mp3 rename to core/src/main/resources/LTTRO.mp3 diff --git a/src/main/resources/LTTRP.mp3 b/core/src/main/resources/LTTRP.mp3 similarity index 100% rename from src/main/resources/LTTRP.mp3 rename to core/src/main/resources/LTTRP.mp3 diff --git a/src/main/resources/LTTRPOINT.mp3 b/core/src/main/resources/LTTRPOINT.mp3 similarity index 100% rename from src/main/resources/LTTRPOINT.mp3 rename to core/src/main/resources/LTTRPOINT.mp3 diff --git a/src/main/resources/LTTRQ.mp3 b/core/src/main/resources/LTTRQ.mp3 similarity index 100% rename from src/main/resources/LTTRQ.mp3 rename to core/src/main/resources/LTTRQ.mp3 diff --git a/src/main/resources/LTTRQUESTMARK.mp3 b/core/src/main/resources/LTTRQUESTMARK.mp3 similarity index 100% rename from src/main/resources/LTTRQUESTMARK.mp3 rename to core/src/main/resources/LTTRQUESTMARK.mp3 diff --git a/src/main/resources/LTTRR.mp3 b/core/src/main/resources/LTTRR.mp3 similarity index 100% rename from src/main/resources/LTTRR.mp3 rename to core/src/main/resources/LTTRR.mp3 diff --git a/src/main/resources/LTTRS.mp3 b/core/src/main/resources/LTTRS.mp3 similarity index 100% rename from src/main/resources/LTTRS.mp3 rename to core/src/main/resources/LTTRS.mp3 diff --git a/src/main/resources/LTTRSPACE.mp3 b/core/src/main/resources/LTTRSPACE.mp3 similarity index 100% rename from src/main/resources/LTTRSPACE.mp3 rename to core/src/main/resources/LTTRSPACE.mp3 diff --git a/src/main/resources/LTTRSTROKE.mp3 b/core/src/main/resources/LTTRSTROKE.mp3 similarity index 100% rename from src/main/resources/LTTRSTROKE.mp3 rename to core/src/main/resources/LTTRSTROKE.mp3 diff --git a/src/main/resources/LTTRT.mp3 b/core/src/main/resources/LTTRT.mp3 similarity index 100% rename from src/main/resources/LTTRT.mp3 rename to core/src/main/resources/LTTRT.mp3 diff --git a/src/main/resources/LTTRU.mp3 b/core/src/main/resources/LTTRU.mp3 similarity index 100% rename from src/main/resources/LTTRU.mp3 rename to core/src/main/resources/LTTRU.mp3 diff --git a/src/main/resources/LTTRV.mp3 b/core/src/main/resources/LTTRV.mp3 similarity index 100% rename from src/main/resources/LTTRV.mp3 rename to core/src/main/resources/LTTRV.mp3 diff --git a/src/main/resources/LTTRW.mp3 b/core/src/main/resources/LTTRW.mp3 similarity index 100% rename from src/main/resources/LTTRW.mp3 rename to core/src/main/resources/LTTRW.mp3 diff --git a/src/main/resources/LTTRX.mp3 b/core/src/main/resources/LTTRX.mp3 similarity index 100% rename from src/main/resources/LTTRX.mp3 rename to core/src/main/resources/LTTRX.mp3 diff --git a/src/main/resources/LTTRY.mp3 b/core/src/main/resources/LTTRY.mp3 similarity index 100% rename from src/main/resources/LTTRY.mp3 rename to core/src/main/resources/LTTRY.mp3 diff --git a/src/main/resources/LTTRZ.mp3 b/core/src/main/resources/LTTRZ.mp3 similarity index 100% rename from src/main/resources/LTTRZ.mp3 rename to core/src/main/resources/LTTRZ.mp3 diff --git a/src/main/resources/NOISECQWINDOW.mp3 b/core/src/main/resources/NOISECQWINDOW.mp3 similarity index 100% rename from src/main/resources/NOISECQWINDOW.mp3 rename to core/src/main/resources/NOISECQWINDOW.mp3 diff --git a/src/main/resources/NOISEERROR.mp3 b/core/src/main/resources/NOISEERROR.mp3 similarity index 100% rename from src/main/resources/NOISEERROR.mp3 rename to core/src/main/resources/NOISEERROR.mp3 diff --git a/src/main/resources/NOISENOTIFY.mp3 b/core/src/main/resources/NOISENOTIFY.mp3 similarity index 100% rename from src/main/resources/NOISENOTIFY.mp3 rename to core/src/main/resources/NOISENOTIFY.mp3 diff --git a/src/main/resources/NOISEPMWINDOW.mp3 b/core/src/main/resources/NOISEPMWINDOW.mp3 similarity index 100% rename from src/main/resources/NOISEPMWINDOW.mp3 rename to core/src/main/resources/NOISEPMWINDOW.mp3 diff --git a/src/main/resources/NOISESTARTUP.mp3 b/core/src/main/resources/NOISESTARTUP.mp3 similarity index 100% rename from src/main/resources/NOISESTARTUP.mp3 rename to core/src/main/resources/NOISESTARTUP.mp3 diff --git a/src/main/resources/VOICE0.mp3 b/core/src/main/resources/VOICE0.mp3 similarity index 100% rename from src/main/resources/VOICE0.mp3 rename to core/src/main/resources/VOICE0.mp3 diff --git a/src/main/resources/VOICE1.mp3 b/core/src/main/resources/VOICE1.mp3 similarity index 100% rename from src/main/resources/VOICE1.mp3 rename to core/src/main/resources/VOICE1.mp3 diff --git a/src/main/resources/VOICE2.mp3 b/core/src/main/resources/VOICE2.mp3 similarity index 100% rename from src/main/resources/VOICE2.mp3 rename to core/src/main/resources/VOICE2.mp3 diff --git a/src/main/resources/VOICE3.mp3 b/core/src/main/resources/VOICE3.mp3 similarity index 100% rename from src/main/resources/VOICE3.mp3 rename to core/src/main/resources/VOICE3.mp3 diff --git a/src/main/resources/VOICE4.mp3 b/core/src/main/resources/VOICE4.mp3 similarity index 100% rename from src/main/resources/VOICE4.mp3 rename to core/src/main/resources/VOICE4.mp3 diff --git a/src/main/resources/VOICE5.mp3 b/core/src/main/resources/VOICE5.mp3 similarity index 100% rename from src/main/resources/VOICE5.mp3 rename to core/src/main/resources/VOICE5.mp3 diff --git a/src/main/resources/VOICE6.mp3 b/core/src/main/resources/VOICE6.mp3 similarity index 100% rename from src/main/resources/VOICE6.mp3 rename to core/src/main/resources/VOICE6.mp3 diff --git a/src/main/resources/VOICE7.mp3 b/core/src/main/resources/VOICE7.mp3 similarity index 100% rename from src/main/resources/VOICE7.mp3 rename to core/src/main/resources/VOICE7.mp3 diff --git a/src/main/resources/VOICE73.mp3 b/core/src/main/resources/VOICE73.mp3 similarity index 100% rename from src/main/resources/VOICE73.mp3 rename to core/src/main/resources/VOICE73.mp3 diff --git a/src/main/resources/VOICE8.mp3 b/core/src/main/resources/VOICE8.mp3 similarity index 100% rename from src/main/resources/VOICE8.mp3 rename to core/src/main/resources/VOICE8.mp3 diff --git a/src/main/resources/VOICE9.mp3 b/core/src/main/resources/VOICE9.mp3 similarity index 100% rename from src/main/resources/VOICE9.mp3 rename to core/src/main/resources/VOICE9.mp3 diff --git a/src/main/resources/VOICEA.mp3 b/core/src/main/resources/VOICEA.mp3 similarity index 100% rename from src/main/resources/VOICEA.mp3 rename to core/src/main/resources/VOICEA.mp3 diff --git a/src/main/resources/VOICEB.mp3 b/core/src/main/resources/VOICEB.mp3 similarity index 100% rename from src/main/resources/VOICEB.mp3 rename to core/src/main/resources/VOICEB.mp3 diff --git a/src/main/resources/VOICEBELL.mp3 b/core/src/main/resources/VOICEBELL.mp3 similarity index 100% rename from src/main/resources/VOICEBELL.mp3 rename to core/src/main/resources/VOICEBELL.mp3 diff --git a/src/main/resources/VOICEC.mp3 b/core/src/main/resources/VOICEC.mp3 similarity index 100% rename from src/main/resources/VOICEC.mp3 rename to core/src/main/resources/VOICEC.mp3 diff --git a/src/main/resources/VOICED.mp3 b/core/src/main/resources/VOICED.mp3 similarity index 100% rename from src/main/resources/VOICED.mp3 rename to core/src/main/resources/VOICED.mp3 diff --git a/src/main/resources/VOICEE.mp3 b/core/src/main/resources/VOICEE.mp3 similarity index 100% rename from src/main/resources/VOICEE.mp3 rename to core/src/main/resources/VOICEE.mp3 diff --git a/src/main/resources/VOICEF.mp3 b/core/src/main/resources/VOICEF.mp3 similarity index 100% rename from src/main/resources/VOICEF.mp3 rename to core/src/main/resources/VOICEF.mp3 diff --git a/src/main/resources/VOICEG.mp3 b/core/src/main/resources/VOICEG.mp3 similarity index 100% rename from src/main/resources/VOICEG.mp3 rename to core/src/main/resources/VOICEG.mp3 diff --git a/src/main/resources/VOICEH.mp3 b/core/src/main/resources/VOICEH.mp3 similarity index 100% rename from src/main/resources/VOICEH.mp3 rename to core/src/main/resources/VOICEH.mp3 diff --git a/src/main/resources/VOICEHELLO.mp3 b/core/src/main/resources/VOICEHELLO.mp3 similarity index 100% rename from src/main/resources/VOICEHELLO.mp3 rename to core/src/main/resources/VOICEHELLO.mp3 diff --git a/src/main/resources/VOICEI.mp3 b/core/src/main/resources/VOICEI.mp3 similarity index 100% rename from src/main/resources/VOICEI.mp3 rename to core/src/main/resources/VOICEI.mp3 diff --git a/src/main/resources/VOICEJ.mp3 b/core/src/main/resources/VOICEJ.mp3 similarity index 100% rename from src/main/resources/VOICEJ.mp3 rename to core/src/main/resources/VOICEJ.mp3 diff --git a/src/main/resources/VOICEK.mp3 b/core/src/main/resources/VOICEK.mp3 similarity index 100% rename from src/main/resources/VOICEK.mp3 rename to core/src/main/resources/VOICEK.mp3 diff --git a/src/main/resources/VOICEL.mp3 b/core/src/main/resources/VOICEL.mp3 similarity index 100% rename from src/main/resources/VOICEL.mp3 rename to core/src/main/resources/VOICEL.mp3 diff --git a/src/main/resources/VOICEM.mp3 b/core/src/main/resources/VOICEM.mp3 similarity index 100% rename from src/main/resources/VOICEM.mp3 rename to core/src/main/resources/VOICEM.mp3 diff --git a/src/main/resources/VOICEMEEPMEEP.mp3 b/core/src/main/resources/VOICEMEEPMEEP.mp3 similarity index 100% rename from src/main/resources/VOICEMEEPMEEP.mp3 rename to core/src/main/resources/VOICEMEEPMEEP.mp3 diff --git a/src/main/resources/VOICEN.mp3 b/core/src/main/resources/VOICEN.mp3 similarity index 100% rename from src/main/resources/VOICEN.mp3 rename to core/src/main/resources/VOICEN.mp3 diff --git a/src/main/resources/VOICEO.mp3 b/core/src/main/resources/VOICEO.mp3 similarity index 100% rename from src/main/resources/VOICEO.mp3 rename to core/src/main/resources/VOICEO.mp3 diff --git a/src/main/resources/VOICEP.mp3 b/core/src/main/resources/VOICEP.mp3 similarity index 100% rename from src/main/resources/VOICEP.mp3 rename to core/src/main/resources/VOICEP.mp3 diff --git a/src/main/resources/VOICEQ.mp3 b/core/src/main/resources/VOICEQ.mp3 similarity index 100% rename from src/main/resources/VOICEQ.mp3 rename to core/src/main/resources/VOICEQ.mp3 diff --git a/src/main/resources/VOICER.mp3 b/core/src/main/resources/VOICER.mp3 similarity index 100% rename from src/main/resources/VOICER.mp3 rename to core/src/main/resources/VOICER.mp3 diff --git a/src/main/resources/VOICES.mp3 b/core/src/main/resources/VOICES.mp3 similarity index 100% rename from src/main/resources/VOICES.mp3 rename to core/src/main/resources/VOICES.mp3 diff --git a/src/main/resources/VOICESTROKE.mp3 b/core/src/main/resources/VOICESTROKE.mp3 similarity index 100% rename from src/main/resources/VOICESTROKE.mp3 rename to core/src/main/resources/VOICESTROKE.mp3 diff --git a/src/main/resources/VOICESTROKEPORTABLE.mp3 b/core/src/main/resources/VOICESTROKEPORTABLE.mp3 similarity index 100% rename from src/main/resources/VOICESTROKEPORTABLE.mp3 rename to core/src/main/resources/VOICESTROKEPORTABLE.mp3 diff --git a/src/main/resources/VOICET.mp3 b/core/src/main/resources/VOICET.mp3 similarity index 100% rename from src/main/resources/VOICET.mp3 rename to core/src/main/resources/VOICET.mp3 diff --git a/src/main/resources/VOICEU.mp3 b/core/src/main/resources/VOICEU.mp3 similarity index 100% rename from src/main/resources/VOICEU.mp3 rename to core/src/main/resources/VOICEU.mp3 diff --git a/src/main/resources/VOICEV.mp3 b/core/src/main/resources/VOICEV.mp3 similarity index 100% rename from src/main/resources/VOICEV.mp3 rename to core/src/main/resources/VOICEV.mp3 diff --git a/src/main/resources/VOICEW.mp3 b/core/src/main/resources/VOICEW.mp3 similarity index 100% rename from src/main/resources/VOICEW.mp3 rename to core/src/main/resources/VOICEW.mp3 diff --git a/src/main/resources/VOICEX.mp3 b/core/src/main/resources/VOICEX.mp3 similarity index 100% rename from src/main/resources/VOICEX.mp3 rename to core/src/main/resources/VOICEX.mp3 diff --git a/src/main/resources/VOICEY.mp3 b/core/src/main/resources/VOICEY.mp3 similarity index 100% rename from src/main/resources/VOICEY.mp3 rename to core/src/main/resources/VOICEY.mp3 diff --git a/src/main/resources/VOICEYOUGOTMAIL.mp3 b/core/src/main/resources/VOICEYOUGOTMAIL.mp3 similarity index 100% rename from src/main/resources/VOICEYOUGOTMAIL.mp3 rename to core/src/main/resources/VOICEYOUGOTMAIL.mp3 diff --git a/src/main/resources/VOICEZ.mp3 b/core/src/main/resources/VOICEZ.mp3 similarity index 100% rename from src/main/resources/VOICEZ.mp3 rename to core/src/main/resources/VOICEZ.mp3 diff --git a/src/main/resources/icons/kst4contest.icns b/core/src/main/resources/icons/kst4contest.icns similarity index 100% rename from src/main/resources/icons/kst4contest.icns rename to core/src/main/resources/icons/kst4contest.icns diff --git a/src/main/resources/icons/kst4contest.ico b/core/src/main/resources/icons/kst4contest.ico similarity index 100% rename from src/main/resources/icons/kst4contest.ico rename to core/src/main/resources/icons/kst4contest.ico diff --git a/src/main/resources/icons/kst4contest.png b/core/src/main/resources/icons/kst4contest.png similarity index 100% rename from src/main/resources/icons/kst4contest.png rename to core/src/main/resources/icons/kst4contest.png diff --git a/src/main/resources/praktiKST.db b/core/src/main/resources/praktiKST.db similarity index 100% rename from src/main/resources/praktiKST.db rename to core/src/main/resources/praktiKST.db diff --git a/src/main/resources/praktiKSTpreferences.old b/core/src/main/resources/praktiKSTpreferences.old similarity index 100% rename from src/main/resources/praktiKSTpreferences.old rename to core/src/main/resources/praktiKSTpreferences.old diff --git a/src/main/resources/praktiKSTpreferences.xml b/core/src/main/resources/praktiKSTpreferences.xml similarity index 100% rename from src/main/resources/praktiKSTpreferences.xml rename to core/src/main/resources/praktiKSTpreferences.xml diff --git a/src/main/resources/sk.mp3 b/core/src/main/resources/sk.mp3 similarity index 100% rename from src/main/resources/sk.mp3 rename to core/src/main/resources/sk.mp3 diff --git a/src/main/resources/tick.mp3 b/core/src/main/resources/tick.mp3 similarity index 100% rename from src/main/resources/tick.mp3 rename to core/src/main/resources/tick.mp3 diff --git a/src/test/java/kst4contest/controller/ChatControllerInitialWorkedStateTest.java b/core/src/test/java/kst4contest/controller/ChatControllerInitialWorkedStateTest.java similarity index 100% rename from src/test/java/kst4contest/controller/ChatControllerInitialWorkedStateTest.java rename to core/src/test/java/kst4contest/controller/ChatControllerInitialWorkedStateTest.java diff --git a/src/test/java/kst4contest/controller/ChatControllerSimpleLogTest.java b/core/src/test/java/kst4contest/controller/ChatControllerSimpleLogTest.java similarity index 100% rename from src/test/java/kst4contest/controller/ChatControllerSimpleLogTest.java rename to core/src/test/java/kst4contest/controller/ChatControllerSimpleLogTest.java diff --git a/core/src/test/java/kst4contest/controller/ChatMemberListViewTest.java b/core/src/test/java/kst4contest/controller/ChatMemberListViewTest.java new file mode 100644 index 00000000..05b28f03 --- /dev/null +++ b/core/src/test/java/kst4contest/controller/ChatMemberListViewTest.java @@ -0,0 +1,164 @@ +package kst4contest.controller; + +import kst4contest.model.ChatMember; +import org.junit.jupiter.api.Test; + +import java.util.Comparator; +import java.util.List; +import java.util.function.Predicate; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +class ChatMemberListViewTest { + + private static ChatMember member(String call) { + ChatMember m = new ChatMember(); + m.setCallSign(call); + return m; + } + + private static List calls(List members) { + return members.stream().map(ChatMember::getCallSign).toList(); + } + + @Test + void withoutFiltersOrOrderTheInputIsReturnedUnchanged() { + List input = List.of(member("DN9APW"), member("DO5AMF"), member("DL1ABC")); + + List result = ChatMemberListView.compute(input, List.of(), null); + + assertEquals(List.of("DN9APW", "DO5AMF", "DL1ABC"), calls(result)); + } + + @Test + void severalFiltersAreCombinedWithAnd() { + List input = List.of(member("DN9APW"), member("DO5AMF"), member("DL1ABC")); + Predicate startsWithD = m -> m.getCallSign().startsWith("D"); + Predicate endsWithF = m -> m.getCallSign().endsWith("F"); + + List result = ChatMemberListView.compute(input, List.of(startsWithD, endsWithF), null); + + assertEquals(List.of("DO5AMF"), calls(result)); + } + + @Test + void anEmptyFilterListLetsEverythingThrough() { + List input = List.of(member("DN9APW"), member("DO5AMF")); + + assertEquals(2, ChatMemberListView.compute(input, List.of(), null).size()); + } + + @Test + void theOrderIsStableForEqualRanks() { + List input = List.of(member("BBB"), member("AAA"), member("CCC"), member("AAA")); + Comparator allEqual = (a, b) -> 0; + + List result = ChatMemberListView.compute(input, List.of(), allEqual); + + assertEquals(List.of("BBB", "AAA", "CCC", "AAA"), calls(result), + "equal ranks must keep their incoming order. This is deliberately not what " + + "SortedList did: it inserted single elements by binary search and left " + + "them wherever the search ended, so the position within a tie was " + + "undefined and drifted as stations came and went."); + } + + @Test + void theComparatorDecidesTheOrder() { + List input = List.of(member("CCC"), member("AAA"), member("BBB")); + + List result = ChatMemberListView.compute( + input, List.of(), Comparator.comparing(ChatMember::getCallSign)); + + assertEquals(List.of("AAA", "BBB", "CCC"), calls(result)); + } + + @Test + void filteringHappensBeforeOrdering() { + List input = List.of(member("CCC"), member("AAA"), member("BBB")); + Predicate notB = m -> !m.getCallSign().equals("BBB"); + + List result = ChatMemberListView.compute( + input, List.of(notB), Comparator.comparing(ChatMember::getCallSign)); + + assertEquals(List.of("AAA", "CCC"), calls(result)); + } + + @Test + void theResultIsImmutable() { + List result = ChatMemberListView.compute(List.of(member("DN9APW")), List.of(), null); + + assertThrows(UnsupportedOperationException.class, () -> result.add(member("DL1ABC"))); + } + + @Test + void aFilterThrowingDoesNotDiscardTheWholeList() { + List input = List.of(member("DN9APW"), member("DO5AMF")); + Predicate broken = m -> { throw new IllegalStateException("boom"); }; + + List result = ChatMemberListView.compute(input, List.of(broken), null); + + assertEquals(List.of("DN9APW", "DO5AMF"), calls(result), + "a broken filter must not empty the station list mid-contest"); + } + + @Test + void aSecondOrderIsDerivedFromTheCanonicalListNotFromThePreviousResult() { + /* + * SortedList always ordered the unsorted source. Sorting an already sorted + * result again would make equally ranked stations keep the previous + * column's order instead of their arrival order, which is what the + * operator sees as rows jumping when switching the sort column. + */ + List canonical = List.of( + member("CCC"), member("AAA"), member("BBB"), member("DDD")); + + Comparator byLastCharacter = + Comparator.comparing(m -> m.getCallSign().substring(2)); + Comparator allEqual = (a, b) -> 0; + + List afterFirstOrder = ChatMemberListView.compute( + canonical, List.of(), byLastCharacter); + assertEquals(List.of("AAA", "BBB", "CCC", "DDD"), calls(afterFirstOrder)); + + List afterSecondOrder = ChatMemberListView.compute( + canonical, List.of(), allEqual); + + assertEquals(List.of("CCC", "AAA", "BBB", "DDD"), calls(afterSecondOrder), + "a new order must be derived from the canonical list, " + + "never from the previously shown order"); + assertEquals(calls(ChatMemberListView.compute(canonical, List.of(), allEqual)), + calls(afterSecondOrder), + "computing the visible list must not depend on what was computed before"); + } + + @Test + void countMatchingAgreesWithComputeWithoutOrdering() { + List input = List.of(member("DN9APW"), member("DO5AMF"), member("DL1ABC")); + Predicate endsWithF = m -> m.getCallSign().endsWith("F"); + + assertEquals( + ChatMemberListView.compute(input, List.of(endsWithF), null).size(), + ChatMemberListView.countMatching(input, List.of(endsWithF)), + "the status line only wants a number; it must not pay for sorting thousands of rows"); + assertEquals(3, ChatMemberListView.countMatching(input, List.of())); + } + + @Test + void countMatchingKeepsAMemberWhenAFilterThrows() { + List input = List.of(member("DN9APW"), member("DO5AMF")); + Predicate broken = m -> { throw new IllegalStateException("boom"); }; + + assertEquals(2, ChatMemberListView.countMatching(input, List.of(broken))); + } + + @Test + void aNullMemberDoesNotBreakTheComputation() { + List input = java.util.Arrays.asList(member("DN9APW"), null); + + List result = ChatMemberListView.compute(input, List.of(), null); + + assertEquals(2, result.size(), + "the JavaFX list this replaces carried nulls; throwing here would freeze the station list"); + } +} diff --git a/core/src/test/java/kst4contest/controller/DBControllerProfileDatabaseTest.java b/core/src/test/java/kst4contest/controller/DBControllerProfileDatabaseTest.java new file mode 100644 index 00000000..cf237885 --- /dev/null +++ b/core/src/test/java/kst4contest/controller/DBControllerProfileDatabaseTest.java @@ -0,0 +1,127 @@ +package kst4contest.controller; + +import kst4contest.model.ChatMember; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.sql.SQLException; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Verifies that one DBController instance works on exactly one database file, so two + * operator profiles can keep independent worked-station data inside the same process. + */ +class DBControllerProfileDatabaseTest { + + private static final String USER_HOME_PROPERTY = "user.home"; + + @TempDir + Path temporaryHomeDirectory; + + private String originalUserHome; + + @BeforeEach + void redirectUserHomeToTemporaryDirectory() { + originalUserHome = System.getProperty(USER_HOME_PROPERTY); + System.setProperty(USER_HOME_PROPERTY, temporaryHomeDirectory.toString()); + } + + @AfterEach + void restoreUserHome() { + if (originalUserHome == null) { + System.clearProperty(USER_HOME_PROPERTY); + } else { + System.setProperty(USER_HOME_PROPERTY, originalUserHome); + } + } + + @Test + void profileDatabaseIsCreatedEmptyAndKeepsWorkedDataSeparate() throws SQLException { + + DBController firstProfileDatabase = + new DBController("profiles/OP1/praktiKST.db", false); + DBController secondProfileDatabase = + new DBController("profiles/OP2/praktiKST.db", false); + + try { + // A profile database must not inherit the several thousand callsigns of the + // bundled template database. + assertTrue(firstProfileDatabase.fetchChatMemberWkdDataFromDB().isEmpty()); + assertTrue(secondProfileDatabase.fetchChatMemberWkdDataFromDB().isEmpty()); + + assertNotEquals(firstProfileDatabase.getDatabaseFilePath(), + secondProfileDatabase.getDatabaseFilePath()); + assertTrue(Files.exists(Path.of(firstProfileDatabase.getDatabaseFilePath()))); + assertTrue(Files.exists(Path.of(secondProfileDatabase.getDatabaseFilePath()))); + + ChatMember workedOnFirstProfile = new ChatMember(); + workedOnFirstProfile.setCallSign("DL0XYZ"); + workedOnFirstProfile.setQra("JO51IJ"); + workedOnFirstProfile.setWorked(true); + workedOnFirstProfile.setWorked144(true); + + firstProfileDatabase.storeChatMember(workedOnFirstProfile); + + Map firstProfileContent = + firstProfileDatabase.fetchChatMemberWkdDataFromDB(); + Map secondProfileContent = + secondProfileDatabase.fetchChatMemberWkdDataFromDB(); + + assertEquals(1, firstProfileContent.size()); + assertTrue(firstProfileContent.get("DL0XYZ").isWorked144()); + assertTrue(secondProfileContent.isEmpty(), + "A worked station of one profile must not appear in the other profile"); + } finally { + firstProfileDatabase.closeDBConnection(); + secondProfileDatabase.closeDBConnection(); + } + } + + @Test + void twoProfilesPointingAtTheSameFileShareTheirWorkedData() throws SQLException { + + DBController sharedStationDatabase = new DBController("praktiKST.db", false); + DBController sameSharedDatabaseAgain = new DBController("praktiKST.db", false); + + try { + ChatMember workedAtTheStation = new ChatMember(); + workedAtTheStation.setCallSign("DL0ABC"); + workedAtTheStation.setWorked(true); + workedAtTheStation.setWorked432(true); + + sharedStationDatabase.storeChatMember(workedAtTheStation); + + Map seenByTheOtherOperator = + sameSharedDatabaseAgain.fetchChatMemberWkdDataFromDB(); + + assertTrue(seenByTheOtherOperator.containsKey("DL0ABC"), + "Operators sharing one station database must see the same worked stations"); + assertTrue(seenByTheOtherOperator.get("DL0ABC").isWorked432()); + } finally { + sharedStationDatabase.closeDBConnection(); + sameSharedDatabaseAgain.closeDBConnection(); + } + } + + @Test + void closingTheConnectionDeregistersTheShutdownHook() { + + DBController profileDatabase = new DBController("profiles/OP3/praktiKST.db", false); + profileDatabase.closeDBConnection(); + + // A second close must stay harmless, and the hook must already be gone. + profileDatabase.closeDBConnection(); + + assertFalse(Files.notExists(Path.of(profileDatabase.getDatabaseFilePath())), + "The database file stays on disk after the connection was closed"); + } +} diff --git a/src/test/java/kst4contest/controller/DXClusterSpotFormatterTest.java b/core/src/test/java/kst4contest/controller/DXClusterSpotFormatterTest.java similarity index 100% rename from src/test/java/kst4contest/controller/DXClusterSpotFormatterTest.java rename to core/src/test/java/kst4contest/controller/DXClusterSpotFormatterTest.java diff --git a/src/test/java/kst4contest/controller/ExternalLoggedQsoTest.java b/core/src/test/java/kst4contest/controller/ExternalLoggedQsoTest.java similarity index 100% rename from src/test/java/kst4contest/controller/ExternalLoggedQsoTest.java rename to core/src/test/java/kst4contest/controller/ExternalLoggedQsoTest.java diff --git a/src/test/java/kst4contest/controller/ExternalLoggerListenerValidationTest.java b/core/src/test/java/kst4contest/controller/ExternalLoggerListenerValidationTest.java similarity index 100% rename from src/test/java/kst4contest/controller/ExternalLoggerListenerValidationTest.java rename to core/src/test/java/kst4contest/controller/ExternalLoggerListenerValidationTest.java diff --git a/src/test/java/kst4contest/controller/MessageBusManagementThreadDxClusterCommentTest.java b/core/src/test/java/kst4contest/controller/MessageBusManagementThreadDxClusterCommentTest.java similarity index 94% rename from src/test/java/kst4contest/controller/MessageBusManagementThreadDxClusterCommentTest.java rename to core/src/test/java/kst4contest/controller/MessageBusManagementThreadDxClusterCommentTest.java index b3e579ff..aa9e3f8d 100644 --- a/src/test/java/kst4contest/controller/MessageBusManagementThreadDxClusterCommentTest.java +++ b/core/src/test/java/kst4contest/controller/MessageBusManagementThreadDxClusterCommentTest.java @@ -1,8 +1,8 @@ package kst4contest.controller; +import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; -import javafx.collections.FXCollections; import kst4contest.model.AirPlane; import kst4contest.model.AirPlaneReflectionInfo; import kst4contest.model.ChatMember; @@ -25,7 +25,7 @@ class MessageBusManagementThreadDxClusterCommentTest { AirPlaneReflectionInfo reflectionInfo = new AirPlaneReflectionInfo(); reflectionInfo.setRisingAirplanes( - FXCollections.observableArrayList( + List.of( firstAircraft, secondAircraft ) diff --git a/src/test/java/kst4contest/controller/MessageBusManagementThreadFrequencyTest.java b/core/src/test/java/kst4contest/controller/MessageBusManagementThreadFrequencyTest.java similarity index 100% rename from src/test/java/kst4contest/controller/MessageBusManagementThreadFrequencyTest.java rename to core/src/test/java/kst4contest/controller/MessageBusManagementThreadFrequencyTest.java diff --git a/src/test/java/kst4contest/controller/MessageBusRawRxLoggingTest.java b/core/src/test/java/kst4contest/controller/MessageBusRawRxLoggingTest.java similarity index 100% rename from src/test/java/kst4contest/controller/MessageBusRawRxLoggingTest.java rename to core/src/test/java/kst4contest/controller/MessageBusRawRxLoggingTest.java diff --git a/src/test/java/kst4contest/controller/MessageHistoryRecorderTest.java b/core/src/test/java/kst4contest/controller/MessageHistoryRecorderTest.java similarity index 100% rename from src/test/java/kst4contest/controller/MessageHistoryRecorderTest.java rename to core/src/test/java/kst4contest/controller/MessageHistoryRecorderTest.java diff --git a/src/test/java/kst4contest/controller/On4KstConnectionProbeTest.java b/core/src/test/java/kst4contest/controller/On4KstConnectionProbeTest.java similarity index 100% rename from src/test/java/kst4contest/controller/On4KstConnectionProbeTest.java rename to core/src/test/java/kst4contest/controller/On4KstConnectionProbeTest.java diff --git a/src/test/java/kst4contest/controller/On4KstHistoryIntegrationTest.java b/core/src/test/java/kst4contest/controller/On4KstHistoryIntegrationTest.java similarity index 100% rename from src/test/java/kst4contest/controller/On4KstHistoryIntegrationTest.java rename to core/src/test/java/kst4contest/controller/On4KstHistoryIntegrationTest.java diff --git a/src/test/java/kst4contest/controller/On4KstIdlePracticeTest.java b/core/src/test/java/kst4contest/controller/On4KstIdlePracticeTest.java similarity index 100% rename from src/test/java/kst4contest/controller/On4KstIdlePracticeTest.java rename to core/src/test/java/kst4contest/controller/On4KstIdlePracticeTest.java diff --git a/src/test/java/kst4contest/controller/On4KstProbeVariantPracticeTest.java b/core/src/test/java/kst4contest/controller/On4KstProbeVariantPracticeTest.java similarity index 100% rename from src/test/java/kst4contest/controller/On4KstProbeVariantPracticeTest.java rename to core/src/test/java/kst4contest/controller/On4KstProbeVariantPracticeTest.java diff --git a/core/src/test/java/kst4contest/controller/On4KstProtocolLocaleTest.java b/core/src/test/java/kst4contest/controller/On4KstProtocolLocaleTest.java new file mode 100644 index 00000000..13ed89da --- /dev/null +++ b/core/src/test/java/kst4contest/controller/On4KstProtocolLocaleTest.java @@ -0,0 +1,84 @@ +package kst4contest.controller; + +import org.junit.jupiter.api.Test; + +import java.util.Locale; +import java.util.function.Supplier; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * The frames on the wire do not change with the interface language. + * + * A translated frame breaks the connection, and nothing about the user interface would show + * it. This checks the output rather than the translation files, because the output is what the + * server reads -- and because a boundary that is only documented is a boundary that holds + * until the next person pulls a string into a bundle in good faith. + * + * Turkish is in the list deliberately: it is the locale under which "I".toLowerCase() is not + * "i", the classic trap for any protocol code that case-folds without Locale.ROOT. + */ +class On4KstProtocolLocaleTest { + + private static final Locale[] LOCALES = { + Locale.GERMANY, + Locale.UK, + Locale.forLanguageTag("tr"), + }; + + private T underLocale(final Locale locale, final Supplier body) { + Locale previous = Locale.getDefault(); + try { + Locale.setDefault(locale); + return body.get(); + } finally { + Locale.setDefault(previous); + } + } + + private void assertLocaleIndependent(final String what, final Supplier frame) { + String reference = underLocale(Locale.UK, frame); + + for (Locale locale : LOCALES) { + assertEquals(reference, underLocale(locale, frame), what + " under " + locale); + } + } + + @Test + void theLoginFrameIsLocaleIndependent() { + assertLocaleIndependent( + "login", + () -> On4KstProtocol.login("DN9APW", "secret", 1, "KST4Contest", 0L)); + } + + @Test + void theSettingsDoneFrameIsLocaleIndependent() { + assertLocaleIndependent("settingsDone", () -> On4KstProtocol.settingsDone(1)); + } + + @Test + void theAddChatFrameIsLocaleIndependent() { + assertLocaleIndependent("addChat", () -> On4KstProtocol.addChat(1, 0L)); + } + + @Test + void theLivenessFramesAreLocaleIndependent() { + assertLocaleIndependent("clientLivenessProbe", On4KstProtocol::clientLivenessProbe); + assertLocaleIndependent( + "serverLivenessProbeResponse", + On4KstProtocol::serverLivenessProbeResponse); + } + + @Test + void theFramesReallyAreTheOpcodesThisTestClaimsToGuard() { + /* + * Without this, the four tests above would still pass if the frames became empty + * strings: identical under every locale, and identically useless. + */ + assertEquals( + "LOGINC|", + On4KstProtocol.login("DN9APW", "secret", 1, "KST4Contest", 0L).substring(0, 7)); + assertEquals("SDONE|", On4KstProtocol.settingsDone(1).substring(0, 6)); + assertEquals("ACHAT|", On4KstProtocol.addChat(1, 0L).substring(0, 6)); + } +} diff --git a/core/src/test/java/kst4contest/controller/OperatorProfileManagementServiceTest.java b/core/src/test/java/kst4contest/controller/OperatorProfileManagementServiceTest.java new file mode 100644 index 00000000..9a37e637 --- /dev/null +++ b/core/src/test/java/kst4contest/controller/OperatorProfileManagementServiceTest.java @@ -0,0 +1,177 @@ +package kst4contest.controller; + +import kst4contest.model.ChatPreferences; +import kst4contest.model.OperatorProfile; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class OperatorProfileManagementServiceTest { + + private static final String USER_HOME_PROPERTY = "user.home"; + + @TempDir + Path temporaryHomeDirectory; + + private String originalUserHome; + private OperatorProfileManagementService managementService; + + @BeforeEach + void redirectUserHomeToTemporaryDirectory() { + originalUserHome = System.getProperty(USER_HOME_PROPERTY); + System.setProperty(USER_HOME_PROPERTY, temporaryHomeDirectory.toString()); + managementService = new OperatorProfileManagementService(); + } + + @AfterEach + void restoreUserHome() { + if (originalUserHome == null) { + System.clearProperty(USER_HOME_PROPERTY); + } else { + System.setProperty(USER_HOME_PROPERTY, originalUserHome); + } + } + + @Test + void aPlainInstallationReportsExactlyOneImplicitRootProfile() { + + List knownProfiles = managementService.listProfiles(); + + assertEquals(1, knownProfiles.size()); + assertTrue(knownProfiles.get(0).isRootProfile()); + assertFalse(Files.exists(applicationFile("profiles.xml")), + "Merely listing profiles must not create a registry"); + } + + @Test + void creatingTheSecondProfileMaterialisesTheRegistryIncludingTheRootProfile() { + + OperatorProfile createdProfile = managementService.createProfile("DN9APW", false); + + assertNotNull(createdProfile); + assertEquals("DN9APW", createdProfile.getProfileId()); + assertTrue(Files.exists(applicationFile("profiles.xml"))); + + List knownProfiles = managementService.listProfiles(); + + assertEquals(2, knownProfiles.size()); + assertTrue(knownProfiles.get(0).isRootProfile()); + assertEquals("DN9APW", knownProfiles.get(1).getProfileId()); + + assertTrue(Files.exists(applicationFile("profiles/DN9APW/preferences.xml"))); + + // The historic files must stay exactly where an older release expects them. + assertFalse(Files.exists(applicationFile("profiles/default"))); + } + + @Test + void aNewProfileStartsWithoutLoginCredentials() { + + OperatorProfile createdProfile = managementService.createProfile("DN9APW", false); + + ChatPreferences createdPreferences = + preferencesAt(OperatorProfilePaths.preferencesRelativeFileName(createdProfile)); + + assertEquals("", createdPreferences.getStn_loginCallSign()); + assertEquals("", createdPreferences.getStn_loginPassword()); + } + + @Test + void duplicatingKeepsTheStationSetupButClearsCallsignAndPassword() { + + OperatorProfile sourceProfile = managementService.createProfile("Source", false); + + ChatPreferences sourcePreferences = + preferencesAt(OperatorProfilePaths.preferencesRelativeFileName(sourceProfile)); + sourcePreferences.setStn_loginCallSign("DM5M"); + sourcePreferences.setStn_loginPassword("secret"); + sourcePreferences.setStn_loginLocatorMainCat("JO51IJ"); + sourcePreferences.setStn_antennaBeamWidthDeg(17.5); + assertTrue(sourcePreferences.writePreferencesToXmlFile()); + + OperatorProfile duplicatedProfile = + managementService.duplicateProfile(sourceProfile, "Copy of source"); + + assertNotNull(duplicatedProfile); + + ChatPreferences duplicatedPreferences = + preferencesAt(OperatorProfilePaths.preferencesRelativeFileName(duplicatedProfile)); + + // The work worth keeping. + assertEquals("JO51IJ", duplicatedPreferences.getStn_loginLocatorMainCat()); + assertEquals(17.5, duplicatedPreferences.getStn_antennaBeamWidthDeg()); + + // The identity that must not be inherited. + assertEquals("", duplicatedPreferences.getStn_loginCallSign()); + assertEquals("", duplicatedPreferences.getStn_loginPassword()); + } + + @Test + void switchingBetweenSharedAndOwnWorkedDataChangesOnlyTheDatabasePath() { + + OperatorProfile createdProfile = managementService.createProfile("DN9APW", false); + + assertEquals("profiles/DN9APW/praktiKST.db", + OperatorProfilePaths.workedDatabaseRelativeFileName(createdProfile)); + + assertTrue(managementService.setSharedWorkedDatabase(createdProfile, true)); + + OperatorProfile reloadedProfile = managementService.listProfiles().get(1); + + assertTrue(reloadedProfile.isSharedWorkedDatabase()); + assertEquals("praktiKST.db", + OperatorProfilePaths.workedDatabaseRelativeFileName(reloadedProfile)); + assertEquals("profiles/DN9APW/preferences.xml", + OperatorProfilePaths.preferencesRelativeFileName(reloadedProfile)); + } + + @Test + void deletingRemovesTheProfileDirectoryButNeverTheRootProfile() { + + OperatorProfile createdProfile = managementService.createProfile("DN9APW", false); + assertTrue(Files.exists(applicationFile("profiles/DN9APW/preferences.xml"))); + + OperatorProfile rootProfile = managementService.listProfiles().get(0); + assertFalse(managementService.deleteProfile(rootProfile), + "The root profile is the installation itself and must not be removable"); + + assertTrue(managementService.deleteProfile(createdProfile)); + assertFalse(Files.exists(applicationFile("profiles/DN9APW"))); + assertEquals(1, managementService.listProfiles().size()); + } + + @Test + void renamingKeepsTheIdentifierAndTherebyAllPaths() { + + OperatorProfile createdProfile = managementService.createProfile("DN9APW", false); + + assertTrue(managementService.renameProfile(createdProfile, "Philipp portable")); + + OperatorProfile renamedProfile = managementService.listProfiles().get(1); + + assertEquals("Philipp portable", renamedProfile.getDisplayName()); + assertEquals("DN9APW", renamedProfile.getProfileId()); + assertEquals("profiles/DN9APW/preferences.xml", + OperatorProfilePaths.preferencesRelativeFileName(renamedProfile)); + } + + private ChatPreferences preferencesAt(final String relativeFileName) { + ChatPreferences preferences = new ChatPreferences(relativeFileName); + preferences.readPreferencesFromXmlFile(); + return preferences; + } + + private Path applicationFile(final String relativeFileName) { + return temporaryHomeDirectory.resolve(".praktiKST").resolve(relativeFileName); + } +} diff --git a/core/src/test/java/kst4contest/controller/OperatorProfilePathsTest.java b/core/src/test/java/kst4contest/controller/OperatorProfilePathsTest.java new file mode 100644 index 00000000..c6c4bb20 --- /dev/null +++ b/core/src/test/java/kst4contest/controller/OperatorProfilePathsTest.java @@ -0,0 +1,109 @@ +package kst4contest.controller; + +import kst4contest.model.OperatorProfile; +import kst4contest.model.OperatorProfileSelection; +import org.junit.jupiter.api.Test; + +import java.util.List; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class OperatorProfilePathsTest { + + @Test + void rootProfileKeepsTheHistoricFlatFileNames() { + + OperatorProfileSelection resolved = + OperatorProfilePaths.resolve(OperatorProfilePaths.buildRootProfile("Default")); + + // This is the downgrade guard: an older KST4Contest release reads exactly these + // two files. If this test ever fails, existing installations would silently lose + // their configuration and worked data when the operator reverts a version. + assertEquals("preferences.xml", resolved.getPreferencesRelativeFileName()); + assertEquals("praktiKST.db", resolved.getWorkedDatabaseRelativeFileName()); + assertTrue(resolved.isSeedWorkedDatabaseFromResource()); + } + + @Test + void additionalProfileWithSharedDatabaseUsesItsOwnPreferencesButTheStationDatabase() { + + OperatorProfile sharedProfile = new OperatorProfile("OP2", "DN9APW", false, true); + OperatorProfileSelection resolved = OperatorProfilePaths.resolve(sharedProfile); + + assertEquals("profiles/OP2/preferences.xml", resolved.getPreferencesRelativeFileName()); + assertEquals("praktiKST.db", resolved.getWorkedDatabaseRelativeFileName()); + assertTrue(resolved.isSeedWorkedDatabaseFromResource()); + } + + @Test + void additionalProfileWithOwnDatabaseIsFullySeparatedAndNotSeeded() { + + OperatorProfile ownDatabaseProfile = new OperatorProfile("OP2", "DN9APW", false, false); + OperatorProfileSelection resolved = OperatorProfilePaths.resolve(ownDatabaseProfile); + + assertEquals("profiles/OP2/preferences.xml", resolved.getPreferencesRelativeFileName()); + assertEquals("profiles/OP2/praktiKST.db", resolved.getWorkedDatabaseRelativeFileName()); + + // Seeding would hand a new operator the several thousand callsigns of the + // bundled template database. + assertFalse(resolved.isSeedWorkedDatabaseFromResource()); + } + + @Test + void profileIdIsFileSystemSafe() { + + assertEquals("DN9APW", OperatorProfilePaths.toProfileId("dn9apw", Set.of())); + assertEquals("DM5M_CONTEST", OperatorProfilePaths.toProfileId("DM5M Contest", Set.of())); + assertEquals("A_B", OperatorProfilePaths.toProfileId("a/../b", Set.of())); + assertEquals("MULLER", OperatorProfilePaths.toProfileId("Müller", Set.of())); + assertEquals("OP", OperatorProfilePaths.toProfileId(" ", Set.of())); + assertEquals("OP", OperatorProfilePaths.toProfileId(null, Set.of())); + + String longName = "A".repeat(60); + assertEquals(32, OperatorProfilePaths.toProfileId(longName, Set.of()).length()); + } + + @Test + void profileIdNeverCollidesAndNeverClaimsTheRootIdentifier() { + + assertEquals("DN9APW_2", OperatorProfilePaths.toProfileId("DN9APW", List.of("DN9APW"))); + assertEquals("DN9APW_3", + OperatorProfilePaths.toProfileId("DN9APW", List.of("DN9APW", "DN9APW_2"))); + + // "default" is reserved for the historic flat installation. + assertNotEquals(OperatorProfilePaths.ROOT_PROFILE_ID, + OperatorProfilePaths.toProfileId("default", Set.of())); + } + + @Test + void theRootProfileKeepsTheHistoricFlatStylesheetNames() { + OperatorProfile root = OperatorProfilePaths.buildRootProfile("Default"); + + assertEquals( + "KST4ContestDefaultDay.css", + OperatorProfilePaths.paletteRelativeFileName(root, false)); + assertEquals( + "KST4ContestDefaultEvening.css", + OperatorProfilePaths.paletteRelativeFileName(root, true)); + } + + @Test + void anotherProfileGetsItsStylesheetInItsOwnDirectory() { + /* + * The same shape the preferences and the worked database already take. A different + * shape here would have one profile reading another profile's colours. + */ + OperatorProfile other = new OperatorProfile("OP2", "DN9APW", false, false); + + assertEquals( + "profiles/OP2/KST4ContestDefaultDay.css", + OperatorProfilePaths.paletteRelativeFileName(other, false)); + assertEquals( + "profiles/OP2/KST4ContestDefaultEvening.css", + OperatorProfilePaths.paletteRelativeFileName(other, true)); + } +} diff --git a/core/src/test/java/kst4contest/controller/OperatorProfileStoreTest.java b/core/src/test/java/kst4contest/controller/OperatorProfileStoreTest.java new file mode 100644 index 00000000..4e23067f --- /dev/null +++ b/core/src/test/java/kst4contest/controller/OperatorProfileStoreTest.java @@ -0,0 +1,117 @@ +package kst4contest.controller; + +import kst4contest.model.OperatorProfile; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class OperatorProfileStoreTest { + + @TempDir + Path temporaryDirectory; + + @Test + void missingRegistryIsNotAnErrorAndIsNotCreated() { + + OperatorProfileStore store = storeAt("profiles.xml"); + + assertFalse(store.isRegistryPresent()); + assertTrue(store.loadProfiles().isEmpty()); + assertEquals(Optional.empty(), store.loadLastUsedProfileId()); + + // A single operator installation must stay untouched by merely starting up. + assertFalse(Files.exists(temporaryDirectory.resolve("profiles.xml"))); + } + + @Test + void profilesSurviveAWriteReadRoundTrip() { + + OperatorProfileStore store = storeAt("profiles.xml"); + + OperatorProfile rootProfile = OperatorProfilePaths.buildRootProfile("DM5M station"); + OperatorProfile secondProfile = new OperatorProfile("OP2", "DN9APW", false, false); + secondProfile.setLastUsedEpochMs(1757328000000L); + + assertTrue(store.saveProfiles(List.of(rootProfile, secondProfile), "OP2")); + assertTrue(store.isRegistryPresent()); + + List restored = store.loadProfiles(); + + assertEquals(2, restored.size()); + assertEquals("default", restored.get(0).getProfileId()); + assertEquals("DM5M station", restored.get(0).getDisplayName()); + assertTrue(restored.get(0).isRootProfile()); + assertTrue(restored.get(0).isSharedWorkedDatabase()); + + assertEquals("OP2", restored.get(1).getProfileId()); + assertEquals("DN9APW", restored.get(1).getDisplayName()); + assertFalse(restored.get(1).isRootProfile()); + assertFalse(restored.get(1).isSharedWorkedDatabase()); + assertEquals(1757328000000L, restored.get(1).getLastUsedEpochMs()); + + assertEquals(Optional.of("OP2"), store.loadLastUsedProfileId()); + } + + @Test + void atomicWriteLeavesNoTemporaryFileBehind() throws IOException { + + OperatorProfileStore store = storeAt("profiles.xml"); + store.saveProfiles(List.of(OperatorProfilePaths.buildRootProfile("Default")), "default"); + + try (var directoryEntries = Files.list(temporaryDirectory)) { + assertTrue(directoryEntries.noneMatch(entry -> entry.getFileName().toString().endsWith(".tmp"))); + } + } + + @Test + void malformedRegistryFallsBackToNoAdditionalProfiles() throws IOException { + + Path registryFile = temporaryDirectory.resolve("profiles.xml"); + Files.writeString(registryFile, "OP2"); + + OperatorProfileStore store = storeAt("profiles.xml"); + + assertTrue(store.isRegistryPresent()); + assertTrue(store.loadProfiles().isEmpty()); + assertEquals(Optional.empty(), store.loadLastUsedProfileId()); + } + + @Test + void entriesWithoutAnIdentifierAreSkippedInsteadOfBreakingTheRegistry() throws IOException { + + Path registryFile = temporaryDirectory.resolve("profiles.xml"); + Files.writeString(registryFile, + "" + + "broken" + + "OP2DN9APW" + + "false" + + ""); + + List restored = storeAt("profiles.xml").loadProfiles(); + + assertEquals(1, restored.size()); + assertEquals("OP2", restored.get(0).getProfileId()); + } + + @Test + void recordLastUsedDoesNothingWhenNoRegistryExists() { + + OperatorProfileStore store = storeAt("profiles.xml"); + + assertFalse(store.recordLastUsed("default")); + assertFalse(store.isRegistryPresent()); + } + + private OperatorProfileStore storeAt(final String fileName) { + return new OperatorProfileStore(temporaryDirectory.resolve(fileName).toString()); + } +} diff --git a/src/test/java/kst4contest/controller/ScoreServiceRefreshTest.java b/core/src/test/java/kst4contest/controller/ScoreServiceRefreshTest.java similarity index 78% rename from src/test/java/kst4contest/controller/ScoreServiceRefreshTest.java rename to core/src/test/java/kst4contest/controller/ScoreServiceRefreshTest.java index 31128a98..dcbd37a8 100644 --- a/src/test/java/kst4contest/controller/ScoreServiceRefreshTest.java +++ b/core/src/test/java/kst4contest/controller/ScoreServiceRefreshTest.java @@ -13,10 +13,8 @@ import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; -import org.mockito.MockedStatic; import org.mockito.invocation.Invocation; -import javafx.application.Platform; import kst4contest.logic.PriorityCalculator; import kst4contest.model.ChatCategory; import kst4contest.model.ChatMember; @@ -54,20 +52,26 @@ class ScoreServiceRefreshTest { } @Test - void userListRefreshKeepsDiagnosticAndReasonlessCallbacksSeparate() { + void userListRefreshKeepsDiagnosticAndReasonlessCallbacksSeparate() throws Exception { ChatController controller = mock( ChatController.class, org.mockito.Answers.CALLS_REAL_METHODS); + /* + * CALLS_REAL_METHODS runs no constructor, so the dispatcher field stays null. Give + * the mock the direct dispatcher the no-arg constructor installs; it runs inline and + * reports the calling thread as the UI thread, which is what the fire methods branch + * on. This replaces the old static Platform mock -- core no longer touches JavaFX. + */ + java.lang.reflect.Field dispatcherField = + ChatController.class.getDeclaredField("uiDispatcher"); + dispatcherField.setAccessible(true); + dispatcherField.set(controller, new kst4contest.observe.DirectUiDispatcher()); + StatusUpdateListener listener = mock(StatusUpdateListener.class); controller.setStatusListener(listener); - try (MockedStatic platform = - org.mockito.Mockito.mockStatic(Platform.class)) { - platform.when(Platform::isFxApplicationThread).thenReturn(true); - - controller.fireUserListUpdate(); - controller.fireUserListUpdate("Reachability calculated"); - } + controller.fireUserListUpdate(); + controller.fireUserListUpdate("Reachability calculated"); verify(listener).onUserListUpdated(); verify(listener).onUserListUpdated("Reachability calculated"); diff --git a/src/test/java/kst4contest/controller/UserActualizationTaskTest.java b/core/src/test/java/kst4contest/controller/UserActualizationTaskTest.java similarity index 100% rename from src/test/java/kst4contest/controller/UserActualizationTaskTest.java rename to core/src/test/java/kst4contest/controller/UserActualizationTaskTest.java diff --git a/src/test/java/kst4contest/controller/WinTestIhaveInventoryTest.java b/core/src/test/java/kst4contest/controller/WinTestIhaveInventoryTest.java similarity index 100% rename from src/test/java/kst4contest/controller/WinTestIhaveInventoryTest.java rename to core/src/test/java/kst4contest/controller/WinTestIhaveInventoryTest.java diff --git a/src/test/java/kst4contest/controller/WinTestLogSyncServiceTest.java b/core/src/test/java/kst4contest/controller/WinTestLogSyncServiceTest.java similarity index 100% rename from src/test/java/kst4contest/controller/WinTestLogSyncServiceTest.java rename to core/src/test/java/kst4contest/controller/WinTestLogSyncServiceTest.java diff --git a/src/test/java/kst4contest/controller/WinTestNetworkAddressResolverTest.java b/core/src/test/java/kst4contest/controller/WinTestNetworkAddressResolverTest.java similarity index 100% rename from src/test/java/kst4contest/controller/WinTestNetworkAddressResolverTest.java rename to core/src/test/java/kst4contest/controller/WinTestNetworkAddressResolverTest.java diff --git a/src/test/java/kst4contest/controller/WinTestPacketTest.java b/core/src/test/java/kst4contest/controller/WinTestPacketTest.java similarity index 100% rename from src/test/java/kst4contest/controller/WinTestPacketTest.java rename to core/src/test/java/kst4contest/controller/WinTestPacketTest.java diff --git a/src/test/java/kst4contest/locatorUtils/DirectionUtilsConsoleOutputTest.java b/core/src/test/java/kst4contest/locatorUtils/DirectionUtilsConsoleOutputTest.java similarity index 100% rename from src/test/java/kst4contest/locatorUtils/DirectionUtilsConsoleOutputTest.java rename to core/src/test/java/kst4contest/locatorUtils/DirectionUtilsConsoleOutputTest.java diff --git a/core/src/test/java/kst4contest/model/ChatMemberFrequencyTest.java b/core/src/test/java/kst4contest/model/ChatMemberFrequencyTest.java new file mode 100644 index 00000000..cf6983c4 --- /dev/null +++ b/core/src/test/java/kst4contest/model/ChatMemberFrequencyTest.java @@ -0,0 +1,34 @@ +package kst4contest.model; + +import kst4contest.observe.SimpleValue; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; + +class ChatMemberFrequencyTest { + + @Test + void aFreshMemberHasNoFrequency() { + ChatMember member = new ChatMember(); + assertNotNull(member.getFrequency(), "the holder itself must exist"); + assertNull(member.getFrequency().get(), + "an unknown frequency must stay unavailable, never become an empty string or a default band"); + } + + @Test + void theFrequencyCanBeSetAndReadBack() { + ChatMember member = new ChatMember(); + member.setFrequency(new SimpleValue<>("144.300")); + assertEquals("144.300", member.getFrequency().get()); + } + + @Test + void clearingTheFrequencyReturnsToUnavailable() { + ChatMember member = new ChatMember(); + member.setFrequency(new SimpleValue<>("144.300")); + member.getFrequency().set(null); + assertNull(member.getFrequency().get()); + } +} diff --git a/core/src/test/java/kst4contest/model/ChatPreferencesLanguageTest.java b/core/src/test/java/kst4contest/model/ChatPreferencesLanguageTest.java new file mode 100644 index 00000000..2343c6c8 --- /dev/null +++ b/core/src/test/java/kst4contest/model/ChatPreferencesLanguageTest.java @@ -0,0 +1,33 @@ +package kst4contest.model; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** The interface language is stored per profile, like every other GUI preference. */ +class ChatPreferencesLanguageTest { + + @Test + void theDefaultIsTheSystemLanguage() { + // Empty means "follow the system", which is what the spec asks for on a first start. + assertEquals("", new ChatPreferences().getGuiOptions_language()); + } + + @Test + void aChosenLanguageIsKept() { + ChatPreferences prefs = new ChatPreferences(); + + prefs.setGuiOptions_language("de"); + + assertEquals("de", prefs.getGuiOptions_language()); + } + + @Test + void aNullSetterValueBecomesEmpty() { + ChatPreferences prefs = new ChatPreferences(); + + prefs.setGuiOptions_language(null); + + assertEquals("", prefs.getGuiOptions_language()); + } +} diff --git a/core/src/test/java/kst4contest/model/ChatPreferencesLocaleTest.java b/core/src/test/java/kst4contest/model/ChatPreferencesLocaleTest.java new file mode 100644 index 00000000..7ae47efb --- /dev/null +++ b/core/src/test/java/kst4contest/model/ChatPreferencesLocaleTest.java @@ -0,0 +1,91 @@ +package kst4contest.model; + +import org.junit.jupiter.api.Test; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.LinkedHashMap; +import java.util.Locale; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * No default that goes to another radio amateur changes with the interface language. + * + * Over every String field by reflection rather than over a maintained list. The beacon texts + * and the auto answers are the ones anybody would think of, and they are also in every + * operator's stored XML, so translating one would alter existing profiles. The fields nobody + * thinks of are the reason this is reflective -- including the ones added after this test was + * written. + */ +class ChatPreferencesLocaleTest { + + private Map stringFieldsUnder(final Locale locale) throws Exception { + Locale previous = Locale.getDefault(); + try { + Locale.setDefault(locale); + ChatPreferences prefs = new ChatPreferences(); + Map values = new LinkedHashMap<>(); + + for (Field field : ChatPreferences.class.getDeclaredFields()) { + if (field.getType() != String.class || Modifier.isStatic(field.getModifiers())) { + continue; + } + field.setAccessible(true); + values.put(field.getName(), (String) field.get(prefs)); + } + + return values; + } finally { + Locale.setDefault(previous); + } + } + + @Test + void everyStringDefaultIsTheSameUnderGermanAndEnglish() throws Exception { + assertEquals(stringFieldsUnder(Locale.UK), stringFieldsUnder(Locale.GERMANY)); + } + + @Test + void everyStringDefaultIsTheSameUnderTurkishToo() throws Exception { + // The locale where case folding differs; a default built with toUpperCase() would show. + assertEquals( + stringFieldsUnder(Locale.UK), + stringFieldsUnder(Locale.forLanguageTag("tr"))); + } + + @Test + void thereAreEnoughStringFieldsForThisTestToMeanSomething() { + /* + * Without this, the two tests above would pass just as well if reflection found no + * fields at all -- two empty maps are equal. + */ + long count = java.util.Arrays.stream(ChatPreferences.class.getDeclaredFields()) + .filter(field -> field.getType() == String.class) + .filter(field -> !Modifier.isStatic(field.getModifiers())) + .count(); + + assertTrue(count > 20, "only " + count + " String fields were found by reflection"); + } + + @Test + void theTextsThatGoToOtherRadioAmateursAreStillEnglish() throws Exception { + /* + * Named as well as covered reflectively: these are in the stored XML of every + * operator, so a change to them is a change to existing profiles. If a later stage + * moves them, this test is the place that says it was deliberate. + */ + Map values = stringFieldsUnder(Locale.GERMANY); + + assertEquals("Hi, pse call us", values.get("bcn_beaconTextMainCat")); + assertEquals("Hi, pse call us", values.get("bcn_beaconTextSecondCat")); + assertTrue( + values.get("messageHandling_autoAnswerTextMainCat").startsWith("Hi, sry I am not qrv"), + values.get("messageHandling_autoAnswerTextMainCat")); + assertTrue( + values.get("messageHandling_autoAnswerTextSecondCat").startsWith("Hi, sry I am not qrv"), + values.get("messageHandling_autoAnswerTextSecondCat")); + } +} diff --git a/core/src/test/java/kst4contest/model/ChatPreferencesObservableTest.java b/core/src/test/java/kst4contest/model/ChatPreferencesObservableTest.java new file mode 100644 index 00000000..35d448ed --- /dev/null +++ b/core/src/test/java/kst4contest/model/ChatPreferencesObservableTest.java @@ -0,0 +1,39 @@ +package kst4contest.model; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ChatPreferencesObservableTest { + + @Test + void theDefaultsMatchTheFormerJavaFxProperties() { + ChatPreferences prefs = new ChatPreferences(); + + assertEquals(360.0, prefs.getActualQTF().get(), 0.0001, + "actualQTF defaulted to 360 as a SimpleDoubleProperty"); + assertEquals("144", prefs.getNotify_optionalFrequencyPrefix().get()); + assertEquals("DO5AMF", prefs.getNotify_DXCSrv_SpottersCallSign().get()); + } + + @Test + void theQrgValuesStartUnavailable() { + ChatPreferences prefs = new ChatPreferences(); + + assertNull(prefs.getMYQRGFirstCat().get(), + "an unset own QRG must stay unavailable rather than becoming a fixed band"); + assertNull(prefs.getMYQRGSecondCat().get()); + } + + @Test + void theListSettingsStartEmpty() { + ChatPreferences prefs = new ChatPreferences(); + + assertTrue(prefs.getLstNotify_QSOSniffer_sniffedWordsList().snapshot().isEmpty()); + assertTrue(prefs.getLstNotify_QSOSniffer_sniffedPrefixLocList().snapshot().isEmpty()); + assertTrue(prefs.getLst_txtSnipList().snapshot().isEmpty()); + assertTrue(prefs.getLst_txtShortCutBtnList().snapshot().isEmpty()); + } +} diff --git a/core/src/test/java/kst4contest/model/ChatPreferencesPaletteTest.java b/core/src/test/java/kst4contest/model/ChatPreferencesPaletteTest.java new file mode 100644 index 00000000..24739277 --- /dev/null +++ b/core/src/test/java/kst4contest/model/ChatPreferencesPaletteTest.java @@ -0,0 +1,46 @@ +package kst4contest.model; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; + +/** + * The two designs' colour overrides are stored independently. + * + *

That is the part worth pinning: two designs sharing one storage mechanism is exactly + * the shape in which a change to the evening palette quietly drags the daylight one with + * it.

+ */ +class ChatPreferencesPaletteTest { + + @Test + void theTwoDesignsAreStoredIndependently() { + ChatPreferences prefs = new ChatPreferences(); + + prefs.setGuiOptions_paletteOverridesDay("surface=#FFFFFF"); + prefs.setGuiOptions_paletteOverridesEvening("surface=#000000"); + + assertEquals("surface=#FFFFFF", prefs.getGuiOptions_paletteOverridesDay()); + assertEquals("surface=#000000", prefs.getGuiOptions_paletteOverridesEvening()); + } + + @Test + void anUnsetOverrideReadsAsEmptyAndNotAsNull() { + // A preferences file from an older release has no such element at all. + ChatPreferences prefs = new ChatPreferences(); + + assertEquals("", prefs.getGuiOptions_paletteOverridesDay()); + assertEquals("", prefs.getGuiOptions_paletteOverridesEvening()); + } + + @Test + void aNullSetterValueBecomesEmpty() { + ChatPreferences prefs = new ChatPreferences(); + + prefs.setGuiOptions_paletteOverridesDay(null); + prefs.setGuiOptions_paletteOverridesEvening(null); + + assertEquals("", prefs.getGuiOptions_paletteOverridesDay()); + assertEquals("", prefs.getGuiOptions_paletteOverridesEvening()); + } +} diff --git a/core/src/test/java/kst4contest/model/PaletteOverridesTest.java b/core/src/test/java/kst4contest/model/PaletteOverridesTest.java new file mode 100644 index 00000000..d30d1ae3 --- /dev/null +++ b/core/src/test/java/kst4contest/model/PaletteOverridesTest.java @@ -0,0 +1,101 @@ +package kst4contest.model; + +import org.junit.jupiter.api.Test; + +import java.util.LinkedHashMap; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * How a set of colour overrides survives in the preferences XML. + * + *

One string per design rather than twelve elements. The parsing is where an operator's + * stored colours are either kept or quietly lost, and the input is not always ours: a + * hand-edited XML, a file written by an older version, or a half-finished write.

+ */ +class PaletteOverridesTest { + + @Test + void anEmptyStoreMeansNoOverridesRatherThanAFailure() { + assertTrue(PaletteOverrides.parse(null).isEmpty()); + assertTrue(PaletteOverrides.parse("").isEmpty()); + assertTrue(PaletteOverrides.parse(" ").isEmpty()); + } + + @Test + void onlyTheRolesActuallyNamedComeBack() { + Map parsed = PaletteOverrides.parse("surface=#ECECEC"); + + // The whole point of the layering: one named role overrides one role. + assertEquals(1, parsed.size()); + assertEquals("#ECECEC", parsed.get(PaletteRole.SURFACE)); + } + + @Test + void aRoundTripKeepsEveryRole() { + Map original = new LinkedHashMap<>(); + for (PaletteRole role : PaletteRole.values()) { + original.put(role, "#10203" + role.ordinal()); + } + + assertEquals(original, PaletteOverrides.parse(PaletteOverrides.format(original))); + } + + @Test + void anUnknownKeyIsSkippedAndTheRestSurvives() { + // An older or newer version may have written a role this one does not know. + Map parsed = + PaletteOverrides.parse("surface=#ECECEC;chrome=#123456;accent=#0096C9"); + + assertEquals(2, parsed.size()); + assertEquals("#ECECEC", parsed.get(PaletteRole.SURFACE)); + assertEquals("#0096C9", parsed.get(PaletteRole.ACCENT)); + } + + @Test + void anUnparsableColourIsSkippedRatherThanStored() { + /* + * This is the difference between an operator losing one colour and an operator + * losing the readability of the whole client: a bad value must not become black. + */ + Map parsed = + PaletteOverrides.parse("surface=rot;accent=#0096C9;text=#GGGGGG;separator="); + + assertEquals(1, parsed.size()); + assertEquals("#0096C9", parsed.get(PaletteRole.ACCENT)); + } + + @Test + void garbageIsSurvivedWithoutAnException() { + // Half-written files exist. None of these may throw. + for (String garbage : new String[] { + ";;;", "=", "surface", "surface=", "=#ECECEC", "surface==#ECECEC", + "surface=#ECECEC;", "\n\t", "a=b=c", + }) { + PaletteOverrides.parse(garbage); + } + } + + @Test + void whatCountsAsAColour() { + assertTrue(PaletteOverrides.isValidColour("#ECECEC")); + assertTrue(PaletteOverrides.isValidColour("#ececec")); + assertTrue(PaletteOverrides.isValidColour(" #ECECEC ")); + + assertFalse(PaletteOverrides.isValidColour(null)); + assertFalse(PaletteOverrides.isValidColour("")); + assertFalse(PaletteOverrides.isValidColour("ECECEC")); + assertFalse(PaletteOverrides.isValidColour("#ECECE")); + assertFalse(PaletteOverrides.isValidColour("#ECECECE")); + assertFalse(PaletteOverrides.isValidColour("#GGGGGG")); + assertFalse(PaletteOverrides.isValidColour("rot")); + } + + @Test + void formattingAnEmptyMapGivesAnEmptyString() { + assertEquals("", PaletteOverrides.format(new LinkedHashMap<>())); + } +} diff --git a/core/src/test/java/kst4contest/model/PaletteRoleTest.java b/core/src/test/java/kst4contest/model/PaletteRoleTest.java new file mode 100644 index 00000000..c36e8fbf --- /dev/null +++ b/core/src/test/java/kst4contest/model/PaletteRoleTest.java @@ -0,0 +1,87 @@ +package kst4contest.model; + +import org.junit.jupiter.api.Test; + +import java.util.HashSet; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * The six roles the operator may set. + * + *

A role is a selector and a property, not a property alone: the shipped sheets state + * three of the six outside `.root`, and `-fx-background-color` on its own appears a dozen + * times in one sheet. The selector is what tells the separator's line from a scroll bar.

+ * + *

All three strings are part of a file format -- two of them the operator's own + * hand-edited stylesheet, the third the preferences XML. Renaming any of them silently + * drops a colour somebody chose, which is why they are pinned here rather than inlined.

+ */ +class PaletteRoleTest { + + @Test + void thereAreSixRolesAndEachNamesOneDeclaration() { + assertEquals(6, PaletteRole.values().length); + + Set declarations = new HashSet<>(); + for (PaletteRole role : PaletteRole.values()) { + assertTrue(role.cssProperty().startsWith("-fx-"), role + " has no CSS property"); + assertTrue(role.selector().startsWith("."), role + " has no selector"); + assertTrue( + declarations.add(role.selector() + "|" + role.cssProperty()), + role + " names the same declaration as another role"); + } + } + + @Test + void theThreeRolesOutsideRootKeepTheirOwnSelectors() { + /* + * These three are the reason a role carries a selector at all. The values are the + * ones JavaFxStylesheet.read already uses, so the two must not drift apart. + */ + assertEquals(".label", PaletteRole.TEXT.selector()); + assertEquals("-fx-text-fill", PaletteRole.TEXT.cssProperty()); + + assertEquals(".separator *.line", PaletteRole.SEPARATOR.selector()); + assertEquals("-fx-background-color", PaletteRole.SEPARATOR.cssProperty()); + + assertEquals(".root", PaletteRole.SURFACE.selector()); + } + + @Test + void theStorageKeysAreDistinctAndStable() { + // These strings land in the operator's preferences XML. Renaming one drops a colour. + assertEquals("surface", PaletteRole.SURFACE.key()); + assertEquals("windowSurface", PaletteRole.WINDOW_SURFACE.key()); + assertEquals("fieldInterior", PaletteRole.FIELD_INTERIOR.key()); + assertEquals("text", PaletteRole.TEXT.key()); + assertEquals("accent", PaletteRole.ACCENT.key()); + assertEquals("separator", PaletteRole.SEPARATOR.key()); + } + + @Test + void aDeclarationResolvesBackToItsRole() { + assertEquals(PaletteRole.SURFACE, PaletteRole.of(".root", "-fx-base")); + assertEquals(PaletteRole.TEXT, PaletteRole.of(".label", "-fx-text-fill")); + } + + @Test + void theSamePropertyUnderAnotherSelectorIsNotThatRole() { + /* + * The whole point of carrying the selector. Both sheets set -fx-text-fill on a + * dozen selectors and -fx-background-color on more; only one of each is a role. + */ + assertNull(PaletteRole.of(".button:hover", "-fx-text-fill")); + assertNull(PaletteRole.of(".scroll-bar", "-fx-background-color")); + } + + @Test + void anUnknownDeclarationIsNotARole() { + assertNull(PaletteRole.of(".root", "-fx-font-size")); + assertNull(PaletteRole.of("", "")); + assertNull(PaletteRole.of(null, null)); + } +} diff --git a/core/src/test/java/kst4contest/observe/DirectUiDispatcherTest.java b/core/src/test/java/kst4contest/observe/DirectUiDispatcherTest.java new file mode 100644 index 00000000..0d1aa33b --- /dev/null +++ b/core/src/test/java/kst4contest/observe/DirectUiDispatcherTest.java @@ -0,0 +1,32 @@ +package kst4contest.observe; + +import org.junit.jupiter.api.Test; + +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class DirectUiDispatcherTest { + + @Test + void runsTheTaskImmediately() { + AtomicInteger runs = new AtomicInteger(); + new DirectUiDispatcher().runOnUi(runs::incrementAndGet); + assertEquals(1, runs.get()); + } + + @Test + void reportsEveryThreadAsTheUiThread() { + assertTrue(new DirectUiDispatcher().isUiThread()); + } + + @Test + void aFailingTaskDoesNotPropagateToTheCaller() { + AtomicBoolean reached = new AtomicBoolean(); + new DirectUiDispatcher().runOnUi(() -> { throw new IllegalStateException("boom"); }); + reached.set(true); + assertTrue(reached.get(), "a failing UI task must not terminate the calling thread"); + } +} diff --git a/core/src/test/java/kst4contest/observe/SimpleRosterTest.java b/core/src/test/java/kst4contest/observe/SimpleRosterTest.java new file mode 100644 index 00000000..4c306db4 --- /dev/null +++ b/core/src/test/java/kst4contest/observe/SimpleRosterTest.java @@ -0,0 +1,168 @@ +package kst4contest.observe; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotSame; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertSame; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SimpleRosterTest { + + @Test + void snapshotReflectsTheCurrentContent() { + SimpleRoster roster = new SimpleRoster<>(); + roster.add("DN9APW"); + roster.add("DO5AMF"); + + assertEquals(List.of("DN9APW", "DO5AMF"), roster.snapshot()); + assertEquals(2, roster.size()); + } + + @Test + void theSnapshotIsImmutable() { + SimpleRoster roster = new SimpleRoster<>(); + roster.add("DN9APW"); + + List snapshot = roster.snapshot(); + assertThrows(UnsupportedOperationException.class, () -> snapshot.add("DL1ABC")); + } + + @Test + void theSnapshotDoesNotChangeWhenTheRosterDoes() { + SimpleRoster roster = new SimpleRoster<>(); + roster.add("DN9APW"); + List taken = roster.snapshot(); + + roster.add("DO5AMF"); + + assertEquals(List.of("DN9APW"), taken, "a handed-out snapshot must stay as it was"); + } + + @Test + void eachMutationNotifiesOnceWithTheNewContent() { + SimpleRoster roster = new SimpleRoster<>(); + List> seen = new ArrayList<>(); + roster.addListener(seen::add); + + roster.add("DN9APW"); + roster.add("DO5AMF"); + + assertEquals(2, seen.size()); + assertEquals(List.of("DN9APW"), seen.get(0)); + assertEquals(List.of("DN9APW", "DO5AMF"), seen.get(1)); + } + + @Test + void mutateNotifiesOnceForTheWholeBatch() { + SimpleRoster roster = new SimpleRoster<>(); + AtomicInteger calls = new AtomicInteger(); + roster.addListener(list -> calls.incrementAndGet()); + + roster.mutate(list -> { + for (int i = 0; i < 500; i++) { + list.add("CALL" + i); + } + }); + + assertEquals(1, calls.get(), "a batch must wake listeners once, not per element"); + assertEquals(500, roster.size()); + } + + @Test + void setAllReplacesTheContentAndNotifiesOnce() { + SimpleRoster roster = new SimpleRoster<>(); + roster.add("OLD"); + AtomicInteger calls = new AtomicInteger(); + roster.addListener(list -> calls.incrementAndGet()); + + roster.setAll(List.of("DN9APW", "DO5AMF")); + + assertEquals(1, calls.get()); + assertEquals(List.of("DN9APW", "DO5AMF"), roster.snapshot()); + } + + @Test + void aListenerThrowingDoesNotStopTheOthers() { + SimpleRoster roster = new SimpleRoster<>(); + List> seen = new ArrayList<>(); + roster.addListener(list -> { throw new IllegalStateException("boom"); }); + roster.addListener(seen::add); + + roster.add("DN9APW"); + + assertEquals(1, seen.size()); + } + + @Test + void concurrentWritersDoNotLoseEntries() throws Exception { + SimpleRoster roster = new SimpleRoster<>(); + int threads = 8; + int perThread = 250; + CountDownLatch start = new CountDownLatch(1); + CountDownLatch done = new CountDownLatch(threads); + + for (int t = 0; t < threads; t++) { + final int base = t * perThread; + new Thread(() -> { + try { + start.await(); + for (int i = 0; i < perThread; i++) { + roster.add(base + i); + } + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } finally { + done.countDown(); + } + }).start(); + } + start.countDown(); + assertTrue(done.await(20, TimeUnit.SECONDS), "writer threads did not finish"); + + assertEquals(threads * perThread, roster.size()); + } + + @Test + void repeatedSnapshotsShareOneCopyUntilTheRosterChanges() { + SimpleRoster roster = new SimpleRoster<>(); + roster.add("DN9APW"); + + List first = roster.snapshot(); + List second = roster.snapshot(); + assertSame(first, second, + "four message tabs read the snapshot per batch; copying it each time is wasted work"); + + roster.add("DO5AMF"); + assertNotSame(first, roster.snapshot(), "a change must produce a fresh snapshot"); + } + + @Test + void nullEntriesSurviveASnapshot() { + SimpleRoster roster = new SimpleRoster<>(); + roster.add(null); + roster.add("DN9APW"); + + List snapshot = roster.snapshot(); + assertEquals(2, snapshot.size()); + assertNull(snapshot.get(0), + "the JavaFX list this replaces carried nulls; throwing here would freeze the mirror silently"); + } + + @Test + void isEmptyReportsTheContent() { + SimpleRoster roster = new SimpleRoster<>(); + assertTrue(roster.isEmpty()); + roster.add("DN9APW"); + assertFalse(roster.isEmpty()); + } +} diff --git a/core/src/test/java/kst4contest/observe/SimpleValueTest.java b/core/src/test/java/kst4contest/observe/SimpleValueTest.java new file mode 100644 index 00000000..93d37c16 --- /dev/null +++ b/core/src/test/java/kst4contest/observe/SimpleValueTest.java @@ -0,0 +1,86 @@ +package kst4contest.observe; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.function.Consumer; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class SimpleValueTest { + + @Test + void anUnsetValueIsNullRatherThanEmpty() { + SimpleValue value = new SimpleValue<>(); + assertNull(value.get(), "an unset value must stay unavailable, not become an empty string"); + } + + @Test + void getReturnsTheInitialValue() { + assertEquals("144.300", new SimpleValue<>("144.300").get()); + } + + @Test + void setNotifiesListenersWithTheNewValue() { + SimpleValue value = new SimpleValue<>(); + List seen = new ArrayList<>(); + value.addListener(seen::add); + + value.set("432.200"); + + assertEquals(List.of("432.200"), seen); + } + + @Test + void setToAnEqualValueDoesNotNotify() { + SimpleValue value = new SimpleValue<>("144.300"); + List seen = new ArrayList<>(); + value.addListener(seen::add); + + value.set("144.300"); + + assertTrue(seen.isEmpty(), "an unchanged value must not wake listeners"); + } + + @Test + void settingBackToNullNotifiesAndReportsUnavailable() { + SimpleValue value = new SimpleValue<>("144.300"); + List seen = new ArrayList<>(); + value.addListener(seen::add); + + value.set(null); + + assertEquals(1, seen.size()); + assertNull(seen.get(0)); + assertNull(value.get()); + } + + @Test + void removedListenersStopBeingCalled() { + SimpleValue value = new SimpleValue<>(); + List seen = new ArrayList<>(); + Consumer listener = seen::add; + value.addListener(listener); + value.removeListener(listener); + + value.set("50.200"); + + assertTrue(seen.isEmpty()); + } + + @Test + void aListenerThrowingDoesNotStopTheOthers() { + SimpleValue value = new SimpleValue<>(); + List seen = new ArrayList<>(); + value.addListener(v -> { throw new IllegalStateException("boom"); }); + value.addListener(seen::add); + + value.set("1296.200"); + + assertEquals(List.of("1296.200"), seen, + "one failing listener must not keep the others from being notified"); + } +} diff --git a/src/test/java/kst4contest/test/BandOpportunityResolverTest.java b/core/src/test/java/kst4contest/test/BandOpportunityResolverTest.java similarity index 100% rename from src/test/java/kst4contest/test/BandOpportunityResolverTest.java rename to core/src/test/java/kst4contest/test/BandOpportunityResolverTest.java diff --git a/src/test/java/kst4contest/test/ChatPreferencesDebugModeTest.java b/core/src/test/java/kst4contest/test/ChatPreferencesDebugModeTest.java similarity index 100% rename from src/test/java/kst4contest/test/ChatPreferencesDebugModeTest.java rename to core/src/test/java/kst4contest/test/ChatPreferencesDebugModeTest.java diff --git a/src/test/java/kst4contest/test/ChatPreferencesLayoutPersistenceTest.java b/core/src/test/java/kst4contest/test/ChatPreferencesLayoutPersistenceTest.java similarity index 100% rename from src/test/java/kst4contest/test/ChatPreferencesLayoutPersistenceTest.java rename to core/src/test/java/kst4contest/test/ChatPreferencesLayoutPersistenceTest.java diff --git a/src/test/java/kst4contest/test/ChatPreferencesStationMapClusteringTest.java b/core/src/test/java/kst4contest/test/ChatPreferencesStationMapClusteringTest.java similarity index 100% rename from src/test/java/kst4contest/test/ChatPreferencesStationMapClusteringTest.java rename to core/src/test/java/kst4contest/test/ChatPreferencesStationMapClusteringTest.java diff --git a/src/test/java/kst4contest/test/FrequencyTextParserRegressionTest.java b/core/src/test/java/kst4contest/test/FrequencyTextParserRegressionTest.java similarity index 100% rename from src/test/java/kst4contest/test/FrequencyTextParserRegressionTest.java rename to core/src/test/java/kst4contest/test/FrequencyTextParserRegressionTest.java diff --git a/src/test/java/kst4contest/test/MapCallsignRawSnapshotBuilderTest.java b/core/src/test/java/kst4contest/test/MapCallsignRawSnapshotBuilderTest.java similarity index 73% rename from src/test/java/kst4contest/test/MapCallsignRawSnapshotBuilderTest.java rename to core/src/test/java/kst4contest/test/MapCallsignRawSnapshotBuilderTest.java index 5425dad0..7c4660e2 100644 --- a/src/test/java/kst4contest/test/MapCallsignRawSnapshotBuilderTest.java +++ b/core/src/test/java/kst4contest/test/MapCallsignRawSnapshotBuilderTest.java @@ -149,4 +149,43 @@ class MapCallsignRawSnapshotBuilderTest { chatMember.setActivityTimeLastInEpoch(activityEpoch); return chatMember; } + + /** + * An absent QRB is not a QRB of zero. + * + * ChatMember.getQrb() and getQTFdirection() are nullable Doubles, and the builder + * used to coerce a null to 0.0 before the snapshot existed. Zero is a legitimate + * reading — a station at the operator's own locator is 0 km away — so the coercion + * destroyed the difference between "right here" and "not known", and the map's + * status line read "0 km / 0°" for every station whenever the operator had no home + * locator configured. AGENTS.md: null means unavailable, not zero. + */ + @Test + void anAbsentDistanceOrBearingStaysAbsentRatherThanBecomingZero() { + ChatMember station = buildStation("DL1ABC", "Hans", "JO50JP", 1_000L); + + MapCallsignRawSnapshot snapshot = + new MapCallsignRawSnapshotBuilder() + .buildSnapshots(List.of(station), null, EnumSet.noneOf(Band.class)) + .get(0); + + assertTrue(Double.isNaN(snapshot.qrbKm()), "an unknown QRB must not read as 0 km"); + assertTrue(Double.isNaN(snapshot.qtfDeg()), "an unknown QTF must not read as 0 degrees"); + } + + /** A station at the operator's own locator really is zero away, and must say so. */ + @Test + void aGenuineZeroDistanceIsKept() { + ChatMember station = buildStation("DL1ABC", "Hans", "JO50JP", 1_000L); + station.setQrb(0.0); + station.setQTFdirection(0.0); + + MapCallsignRawSnapshot snapshot = + new MapCallsignRawSnapshotBuilder() + .buildSnapshots(List.of(station), null, EnumSet.noneOf(Band.class)) + .get(0); + + assertEquals(0.0, snapshot.qrbKm()); + assertEquals(0.0, snapshot.qtfDeg()); + } } diff --git a/core/src/test/java/kst4contest/test/PlatformUtilsTest.java b/core/src/test/java/kst4contest/test/PlatformUtilsTest.java new file mode 100644 index 00000000..abd01ff0 --- /dev/null +++ b/core/src/test/java/kst4contest/test/PlatformUtilsTest.java @@ -0,0 +1,24 @@ +package kst4contest.test; + +import kst4contest.utils.PlatformUtils; +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class PlatformUtilsTest { + + @Test + void macOsNamesAreDetected() { + assertTrue(PlatformUtils.isMacOs("Mac OS X")); + assertTrue(PlatformUtils.isMacOs("macOS")); + } + + @Test + void otherOrMissingNamesAreNotMacOs() { + assertFalse(PlatformUtils.isMacOs("Windows 11")); + assertFalse(PlatformUtils.isMacOs("Linux")); + assertFalse(PlatformUtils.isMacOs("")); + assertFalse(PlatformUtils.isMacOs(null)); + } +} diff --git a/src/test/java/kst4contest/test/PropagationFrequencyResolverTest.java b/core/src/test/java/kst4contest/test/PropagationFrequencyResolverTest.java similarity index 100% rename from src/test/java/kst4contest/test/PropagationFrequencyResolverTest.java rename to core/src/test/java/kst4contest/test/PropagationFrequencyResolverTest.java diff --git a/src/test/java/kst4contest/test/TestApplicationFileUtils.java b/core/src/test/java/kst4contest/test/TestApplicationFileUtils.java similarity index 100% rename from src/test/java/kst4contest/test/TestApplicationFileUtils.java rename to core/src/test/java/kst4contest/test/TestApplicationFileUtils.java diff --git a/src/test/java/kst4contest/test/TestChatPreferences.java b/core/src/test/java/kst4contest/test/TestChatPreferences.java similarity index 100% rename from src/test/java/kst4contest/test/TestChatPreferences.java rename to core/src/test/java/kst4contest/test/TestChatPreferences.java diff --git a/src/test/java/kst4contest/test/TestDBController.java b/core/src/test/java/kst4contest/test/TestDBController.java similarity index 100% rename from src/test/java/kst4contest/test/TestDBController.java rename to core/src/test/java/kst4contest/test/TestDBController.java diff --git a/src/test/java/kst4contest/test/TestLocatorUtils.java b/core/src/test/java/kst4contest/test/TestLocatorUtils.java similarity index 100% rename from src/test/java/kst4contest/test/TestLocatorUtils.java rename to core/src/test/java/kst4contest/test/TestLocatorUtils.java diff --git a/src/test/java/kst4contest/test/TestReadUDPASListenerThread.java b/core/src/test/java/kst4contest/test/TestReadUDPASListenerThread.java similarity index 100% rename from src/test/java/kst4contest/test/TestReadUDPASListenerThread.java rename to core/src/test/java/kst4contest/test/TestReadUDPASListenerThread.java diff --git a/src/test/java/kst4contest/test/TestReadUDPUCXListenerThread.java b/core/src/test/java/kst4contest/test/TestReadUDPUCXListenerThread.java similarity index 100% rename from src/test/java/kst4contest/test/TestReadUDPUCXListenerThread.java rename to core/src/test/java/kst4contest/test/TestReadUDPUCXListenerThread.java diff --git a/src/test/java/kst4contest/test/TestUCXLogFileToHashsetParser.java b/core/src/test/java/kst4contest/test/TestUCXLogFileToHashsetParser.java similarity index 100% rename from src/test/java/kst4contest/test/TestUCXLogFileToHashsetParser.java rename to core/src/test/java/kst4contest/test/TestUCXLogFileToHashsetParser.java diff --git a/src/test/java/kst4contest/test/UDPAirScoutSendMessages.java b/core/src/test/java/kst4contest/test/UDPAirScoutSendMessages.java similarity index 100% rename from src/test/java/kst4contest/test/UDPAirScoutSendMessages.java rename to core/src/test/java/kst4contest/test/UDPAirScoutSendMessages.java diff --git a/src/test/java/kst4contest/test/testTimeGeneration.java b/core/src/test/java/kst4contest/test/testTimeGeneration.java similarity index 100% rename from src/test/java/kst4contest/test/testTimeGeneration.java rename to core/src/test/java/kst4contest/test/testTimeGeneration.java diff --git a/src/test/java/kst4contest/utils/ApplicationFileLoggingTest.java b/core/src/test/java/kst4contest/utils/ApplicationFileLoggingTest.java similarity index 100% rename from src/test/java/kst4contest/utils/ApplicationFileLoggingTest.java rename to core/src/test/java/kst4contest/utils/ApplicationFileLoggingTest.java diff --git a/core/src/test/java/kst4contest/view/map/MapMarkerClusterTooltipTest.java b/core/src/test/java/kst4contest/view/map/MapMarkerClusterTooltipTest.java new file mode 100644 index 00000000..859996e9 --- /dev/null +++ b/core/src/test/java/kst4contest/view/map/MapMarkerClusterTooltipTest.java @@ -0,0 +1,80 @@ +package kst4contest.view.map; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * What hovering a cluster bubble says. + * + * The Leaflet tooltip (buildClusterTooltipHtml, MapHtmlResources.java) led with the + * count, listed at most twenty callsigns in alphabetical order, said how many more there + * were, and ended by telling the operator that clicking zooms in. The Compose port + * listed every member and nothing else: at zoom 3 a European roster puts a hundred + * stations into one cell, which is a white box taller than the window, and the + * click-to-zoom behaviour became undiscoverable. + */ +class MapMarkerClusterTooltipTest { + + private MapMarkerCluster clusterOf(int count) { + List members = new ArrayList<>(); + for (int i = 0; i < count; i++) { + members.add(new MapCallsignRawSnapshot( + String.format("DL%03dAA", i), String.format("DL%03dAA", i), "JO50JP", + 51.0, 10.0, "", Map.of(), false, false, false, false, 1.0, 1.0, 0, 0L + )); + } + MapMarkerCluster cluster = new MapMarkerCluster(members.get(0)); + for (int i = 1; i < members.size(); i++) { + cluster.add(members.get(i)); + } + return cluster; + } + + @Test + void it_leads_with_the_count() { + assertTrue(MapMarkerClusterTooltip.build(clusterOf(5)).startsWith("5 stations")); + } + + @Test + void it_ends_by_saying_that_clicking_zooms_in() { + assertTrue(MapMarkerClusterTooltip.build(clusterOf(5)).endsWith("Click to zoom in")); + } + + @Test + void it_lists_the_members_in_alphabetical_order() { + List lines = List.of(MapMarkerClusterTooltip.build(clusterOf(3)).split("\\n")); + + assertEquals("3 stations", lines.get(0)); + assertEquals("DL000AA", lines.get(1)); + assertEquals("DL001AA", lines.get(2)); + assertEquals("DL002AA", lines.get(3)); + } + + /** A hundred callsigns is a box taller than the window. */ + @Test + void a_crowded_cluster_is_summarised_rather_than_listed_in_full() { + String tooltip = MapMarkerClusterTooltip.build(clusterOf(100)); + List lines = List.of(tooltip.split("\\n")); + + assertEquals( + MapMarkerClusterTooltip.MAX_PREVIEWED_STATIONS + 3, + lines.size(), + "count line, 20 callsigns, a remainder line and the hint" + ); + assertTrue(tooltip.contains("+80 more"), tooltip); + } + + @Test + void a_cluster_of_exactly_twenty_needs_no_remainder_line() { + String tooltip = MapMarkerClusterTooltip.build(clusterOf(MapMarkerClusterTooltip.MAX_PREVIEWED_STATIONS)); + + assertTrue(!tooltip.contains("more"), tooltip); + assertEquals(MapMarkerClusterTooltip.MAX_PREVIEWED_STATIONS + 2, List.of(tooltip.split("\\n")).size()); + } +} diff --git a/core/src/test/java/kst4contest/view/map/MapViewportTest.java b/core/src/test/java/kst4contest/view/map/MapViewportTest.java new file mode 100644 index 00000000..e5a9a924 --- /dev/null +++ b/core/src/test/java/kst4contest/view/map/MapViewportTest.java @@ -0,0 +1,206 @@ +package kst4contest.view.map; + +import org.junit.jupiter.api.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * The viewport that turns a position into a place on the canvas. + * + * The Compose map used to compute positions at the integer zoom level and then scale the + * whole canvas by the fraction, which made every drawn size — dot radii, stroke widths, + * font sizes — depend on the fraction. Leaflet drew overlays in screen pixels and kept + * them constant. This class is how that is recovered: the fraction is folded into the + * projection, so the drawing code works in screen pixels and needs no scaling at all. + */ +class MapViewportTest { + + private static final double TOLERANCE_PX = 1e-6; + private static final double TOLERANCE_DEG = 1e-9; + + private MapViewport viewport(double zoom) { + return new MapViewport(10.0, 51.0, zoom, 800.0, 600.0); + } + + @Test + void the_centre_of_the_viewport_lands_in_the_middle_of_the_canvas() { + MapViewport viewport = viewport(6.0); + + assertEquals(400.0, viewport.screenX(10.0), TOLERANCE_PX); + assertEquals(300.0, viewport.screenY(51.0), TOLERANCE_PX); + } + + @Test + void the_fractional_part_of_the_zoom_is_folded_into_the_projection() { + MapViewport viewport = viewport(6.5); + + assertEquals(400.0, viewport.screenX(10.0), TOLERANCE_PX); + assertEquals(300.0, viewport.screenY(51.0), TOLERANCE_PX); + } + + /** + * Half a zoom level is a factor of sqrt(2) in scale. This is the property the old + * drawing code faked by scaling the canvas, and the reason sizes drifted with zoom. + */ + @Test + void half_a_zoom_level_doubles_the_distance_on_screen_over_a_whole_level() { + double atSix = viewport(6.0).screenX(15.0) - viewport(6.0).screenX(10.0); + double atSixAndAHalf = viewport(6.5).screenX(15.0) - viewport(6.5).screenX(10.0); + double atSeven = viewport(7.0).screenX(15.0) - viewport(7.0).screenX(10.0); + + assertEquals(2.0, atSeven / atSix, 1e-9); + assertEquals(Math.sqrt(2.0), atSixAndAHalf / atSix, 1e-9); + } + + @Test + void a_screen_position_maps_back_to_the_position_it_came_from() { + MapViewport viewport = viewport(6.5); + + assertEquals(12.5, viewport.lonAt(viewport.screenX(12.5)), TOLERANCE_DEG); + assertEquals(48.25, viewport.latAt(viewport.screenY(48.25)), TOLERANCE_DEG); + } + + @Test + void the_edges_of_the_canvas_are_the_edges_of_the_viewport() { + MapViewport viewport = viewport(6.5); + + assertEquals(viewport.lonAt(0.0), viewport.westLon(), TOLERANCE_DEG); + assertEquals(viewport.lonAt(800.0), viewport.eastLon(), TOLERANCE_DEG); + assertEquals(viewport.latAt(0.0), viewport.northLat(), TOLERANCE_DEG); + assertEquals(viewport.latAt(600.0), viewport.southLat(), TOLERANCE_DEG); + + assertTrue(viewport.northLat() > viewport.southLat()); + assertTrue(viewport.eastLon() > viewport.westLon()); + } + + /** Tiles only exist at integer levels; the fraction becomes the scale they are drawn at. */ + @Test + void tiles_come_from_the_level_below_the_fractional_zoom() { + assertEquals(6, viewport(6.0).tileZoom()); + assertEquals(6, viewport(6.99).tileZoom()); + assertEquals(7, viewport(7.0).tileZoom()); + + assertEquals(1.0, viewport(6.0).tileScale(), TOLERANCE_PX); + assertEquals(Math.sqrt(2.0), viewport(6.5).tileScale(), 1e-9); + } + + /** + * Leaflet was configured for 3 to 18 and the tile source carries nothing outside + * that; a zoom beyond it would request tiles that do not exist. + */ + @Test + void the_zoom_stays_within_the_range_the_tile_source_serves() { + assertEquals(MapViewport.MIN_ZOOM, new MapViewport(10.0, 51.0, 1.0, 800.0, 600.0).zoom(), TOLERANCE_PX); + assertEquals(MapViewport.MAX_ZOOM, new MapViewport(10.0, 51.0, 25.0, 800.0, 600.0).zoom(), TOLERANCE_PX); + assertEquals(3.0, MapViewport.MIN_ZOOM, TOLERANCE_PX); + assertEquals(18.0, MapViewport.MAX_ZOOM, TOLERANCE_PX); + } + + /** + * A canvas can be measured at zero before the window is laid out. The viewport must + * answer rather than divide by it. + */ + @Test + void a_canvas_without_a_size_still_answers() { + MapViewport viewport = new MapViewport(10.0, 51.0, 6.0, 0.0, 0.0); + + assertEquals(0.0, viewport.screenX(10.0), TOLERANCE_PX); + assertTrue(Double.isFinite(viewport.westLon())); + assertTrue(Double.isFinite(viewport.northLat())); + } + + @Test + void a_drag_moves_the_view_opposite_to_the_pointer() { + MapViewport dragged = viewport(6.5).pannedBy(100.0, 50.0); + + /* Dragging the map right brings positions further west into view. */ + assertTrue(dragged.centerLon() < 10.0); + assertTrue(dragged.centerLat() > 51.0); + } + + /** A drag of n pixels moves what was under the pointer by exactly n pixels. */ + @Test + void a_drag_moves_a_position_by_the_distance_dragged() { + MapViewport before = viewport(6.5); + double xBefore = before.screenX(12.0); + + MapViewport after = before.pannedBy(100.0, -40.0); + + assertEquals(xBefore + 100.0, after.screenX(12.0), 1e-6); + assertEquals(before.screenY(49.0) - 40.0, after.screenY(49.0), 1e-6); + } + + @Test + void a_drag_and_its_reverse_return_the_view_it_started_from() { + MapViewport roundTrip = viewport(6.5).pannedBy(130.0, -70.0).pannedBy(-130.0, 70.0); + + assertEquals(10.0, roundTrip.centerLon(), 1e-9); + assertEquals(51.0, roundTrip.centerLat(), 1e-9); + } + + /** + * The point under the pointer stays under the pointer. This is what makes a wheel + * zoom feel like a map rather than a jump to the centre. + */ + @Test + void zooming_keeps_the_position_under_the_pointer_in_place() { + MapViewport before = viewport(6.0); + double anchorX = 650.0; + double anchorY = 120.0; + double anchorLon = before.lonAt(anchorX); + double anchorLat = before.latAt(anchorY); + + MapViewport after = before.zoomedTo(8.25, anchorX, anchorY); + + assertEquals(8.25, after.zoom(), 1e-9); + assertEquals(anchorX, after.screenX(anchorLon), 1e-6); + assertEquals(anchorY, after.screenY(anchorLat), 1e-6); + } + + @Test + void zooming_about_the_centre_leaves_the_centre_alone() { + MapViewport after = viewport(6.0).zoomedTo(7.5, 400.0, 300.0); + + assertEquals(10.0, after.centerLon(), 1e-9); + assertEquals(51.0, after.centerLat(), 1e-9); + } + + @Test + void a_resize_keeps_the_centre_and_the_zoom() { + MapViewport resized = viewport(6.5).resizedTo(1200.0, 400.0); + + assertEquals(10.0, resized.centerLon(), 1e-9); + assertEquals(51.0, resized.centerLat(), 1e-9); + assertEquals(6.5, resized.zoom(), 1e-9); + assertEquals(600.0, resized.screenX(10.0), 1e-6); + assertEquals(200.0, resized.screenY(51.0), 1e-6); + } + + /** + * Panning east forever must not walk the centre off the world. + * + * The tile indices wrap, so the basemap keeps drawing; the overlays do not wrap, so + * a centre at longitude 262 puts a station at -170 nine thousand pixels off the + * canvas and leaves the grid with a degenerate column. Stations and grid then vanish + * while the map underneath looks fine. + */ + @Test + void panning_east_past_the_antimeridian_keeps_the_centre_on_the_world() { + MapViewport viewport = new MapViewport(175.0, 0.0, 5.0, 800.0, 600.0); + + for (int drag = 0; drag < 10; drag++) { + viewport = viewport.pannedBy(-200.0, 0.0); + } + + assertTrue(viewport.centerLon() >= -180.0 && viewport.centerLon() < 180.0, + "centre ran off the world at longitude " + viewport.centerLon()); + } + + @Test + void a_longitude_handed_in_past_the_antimeridian_is_brought_back_round() { + assertEquals(-179.0, new MapViewport(181.0, 0.0, 6.0, 800.0, 600.0).centerLon(), TOLERANCE_DEG); + assertEquals(179.0, new MapViewport(-181.0, 0.0, 6.0, 800.0, 600.0).centerLon(), TOLERANCE_DEG); + assertEquals(0.0, new MapViewport(360.0, 0.0, 6.0, 800.0, 600.0).centerLon(), TOLERANCE_DEG); + } +} diff --git a/core/src/test/java/kst4contest/view/map/StationMapClustererTest.java b/core/src/test/java/kst4contest/view/map/StationMapClustererTest.java new file mode 100644 index 00000000..a45e04b7 --- /dev/null +++ b/core/src/test/java/kst4contest/view/map/StationMapClustererTest.java @@ -0,0 +1,206 @@ +package kst4contest.view.map; + +import org.junit.jupiter.api.Test; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Grouping stations that sit on top of each other on screen. + * + * The rules are not ours to invent: they are the ones the Leaflet map ran for the whole + * of release 1.4x, and an operator who has learned them must not have to relearn them. + * They live here rather than in the drawing code because they are decisions about what + * the operator sees, and because the drawing code has no test harness. + * + * Every constant below is pinned against the JavaScript it came from — + * MapHtmlResources.java, KST_CLUSTER_* and renderClusteredStations(). + */ +class StationMapClustererTest { + + private MapViewport viewportAtZoom(double zoom) { + return new MapViewport(10.0, 51.0, zoom, 1000.0, 800.0); + } + + private MapCallsignRawSnapshot station(String call, double lat, double lon) { + return station(call, lat, lon, false, false); + } + + private MapCallsignRawSnapshot station(String call, + double lat, + double lon, + boolean selected, + boolean warning) { + return new MapCallsignRawSnapshot( + call, call, "JO50JP", lat, lon, "144", Map.of(), + false, warning, false, selected, 100.0, 90.0, 0, 0L + ); + } + + /** Stations close enough to share one cluster cell at the given zoom. */ + private List huddle(int count, double lat, double lon) { + List stations = new ArrayList<>(); + for (int i = 0; i < count; i++) { + stations.add(station("DL" + i + "AA", lat + i * 0.0001, lon + i * 0.0001)); + } + return stations; + } + + @Test + void two_stations_on_the_same_spot_stay_separate() { + StationMapClusterer.Result result = StationMapClusterer.cluster( + huddle(2, 51.0, 10.0), viewportAtZoom(6.0), true); + + assertTrue(result.clusters().isEmpty(), "two nearby stations are still readable"); + assertEquals(2, result.individual().size()); + } + + @Test + void three_stations_on_the_same_spot_become_one_cluster() { + StationMapClusterer.Result result = StationMapClusterer.cluster( + huddle(3, 51.0, 10.0), viewportAtZoom(6.0), true); + + assertEquals(1, result.clusters().size()); + assertEquals(3, result.clusters().get(0).size()); + assertTrue(result.individual().isEmpty()); + } + + @Test + void clustering_stops_once_the_stations_are_far_enough_apart_on_screen() { + StationMapClusterer.Result result = StationMapClusterer.cluster( + huddle(5, 51.0, 10.0), viewportAtZoom(StationMapClusterer.DISABLE_AT_ZOOM), true); + + assertTrue(result.clusters().isEmpty(), "at zoom 8 and above the map shows every station"); + assertEquals(5, result.individual().size()); + } + + @Test + void clustering_can_be_switched_off_entirely() { + StationMapClusterer.Result result = StationMapClusterer.cluster( + huddle(5, 51.0, 10.0), viewportAtZoom(4.0), false); + + assertTrue(result.clusters().isEmpty()); + assertEquals(5, result.individual().size()); + } + + /** + * The one the operator is working and the one pointing at their antenna are the two + * they must not lose in a bubble. + */ + @Test + void the_selected_station_is_never_hidden_in_a_cluster() { + List stations = new ArrayList<>(huddle(4, 51.0, 10.0)); + stations.add(station("F5JMI", 51.0, 10.0, true, false)); + + StationMapClusterer.Result result = StationMapClusterer.cluster( + stations, viewportAtZoom(5.0), true); + + assertTrue(result.individual().stream().anyMatch(s -> s.callSignRaw().equals("F5JMI"))); + assertFalse( + result.clusters().stream().anyMatch(c -> c.getMarkers().stream() + .anyMatch(s -> s.callSignRaw().equals("F5JMI"))), + "a selected station inside a bubble cannot be seen" + ); + } + + @Test + void a_station_warning_towards_my_direction_is_never_hidden_in_a_cluster() { + List stations = new ArrayList<>(huddle(4, 51.0, 10.0)); + stations.add(station("OE5SOS", 51.0, 10.0, false, true)); + + StationMapClusterer.Result result = StationMapClusterer.cluster( + stations, viewportAtZoom(5.0), true); + + assertTrue(result.individual().stream().anyMatch(s -> s.callSignRaw().equals("OE5SOS"))); + } + + @Test + void a_station_without_a_usable_position_is_dropped_rather_than_drawn_at_zero() { + List stations = List.of( + new MapCallsignRawSnapshot("DL1AAA", "DL1AAA", "", 0.0, 0.0, "", Map.of(), + false, false, false, false, 0.0, 0.0, 0, 0L) + ); + + StationMapClusterer.Result result = StationMapClusterer.cluster( + stations, viewportAtZoom(6.0), true); + + assertTrue(result.clusters().isEmpty()); + assertTrue(result.individual().isEmpty()); + } + + /** The four sizes the Leaflet map used, by the zoom thresholds it used. */ + @Test + void the_cell_grows_as_the_map_zooms_out() { + assertEquals(55.0, StationMapClusterer.cellSizePxForZoom(7.0)); + assertEquals(55.0, StationMapClusterer.cellSizePxForZoom(7.9)); + assertEquals(70.0, StationMapClusterer.cellSizePxForZoom(6.0)); + assertEquals(95.0, StationMapClusterer.cellSizePxForZoom(5.0)); + assertEquals(125.0, StationMapClusterer.cellSizePxForZoom(4.0)); + assertEquals(125.0, StationMapClusterer.cellSizePxForZoom(3.0)); + } + + @Test + void stations_in_different_screen_cells_are_not_grouped_together() { + double cell = StationMapClusterer.cellSizePxForZoom(6.0); + MapViewport viewport = viewportAtZoom(6.0); + + /* Two huddles, placed more than one cell apart on screen. */ + List stations = new ArrayList<>(huddle(3, 51.0, 10.0)); + double farLon = viewport.lonAt(viewport.screenX(10.0) + cell * 3.0); + for (int i = 0; i < 3; i++) { + stations.add(station("PA" + i + "BB", 51.0 + i * 0.0001, farLon + i * 0.0001)); + } + + StationMapClusterer.Result result = StationMapClusterer.cluster(stations, viewport, true); + + assertEquals(2, result.clusters().size()); + assertTrue(result.clusters().stream().allMatch(c -> c.size() == 3)); + } + + @Test + void every_station_handed_in_comes_back_exactly_once() { + List stations = new ArrayList<>(huddle(7, 51.0, 10.0)); + stations.add(station("F5JMI", 51.0, 10.0, true, false)); + + StationMapClusterer.Result result = StationMapClusterer.cluster( + stations, viewportAtZoom(5.0), true); + + int clustered = result.clusters().stream().mapToInt(MapMarkerCluster::size).sum(); + assertEquals(stations.size(), clustered + result.individual().size()); + } + + /** + * Selecting a station moves the map to it. It must not throw the operator's zoom + * away doing so. + * + * The Leaflet map panned and kept the zoom, and touched the zoom only when the + * station was hidden inside a bubble — then just far enough to break the bubble + * open (focusCallsignRaw, MapHtmlResources.java). The first Compose port instead + * recomputed a zoom from a bounding box on every selection and clamped it into + * 4..12, so an operator working at zoom 15 was yanked out to about 7 by clicking + * the next station. AGENTS.md names zoom first among the things not to change as an + * incidental side effect. + */ + @Test + void selecting_a_station_that_is_already_visible_keeps_the_zoom() { + assertEquals(15.0, StationMapClusterer.zoomToRevealStations(15.0, true)); + assertEquals(9.0, StationMapClusterer.zoomToRevealStations(9.0, true)); + } + + @Test + void selecting_a_station_hidden_in_a_bubble_zooms_just_far_enough_to_open_it() { + assertEquals(StationMapClusterer.DISABLE_AT_ZOOM, StationMapClusterer.zoomToRevealStations(5.0, true)); + assertEquals(StationMapClusterer.DISABLE_AT_ZOOM, StationMapClusterer.zoomToRevealStations(7.9, true)); + } + + @Test + void with_grouping_switched_off_every_station_is_already_visible() { + assertEquals(4.0, StationMapClusterer.zoomToRevealStations(4.0, false)); + assertEquals(3.0, StationMapClusterer.zoomToRevealStations(3.0, false)); + } +} diff --git a/core/src/test/java/kst4contest/view/map/StationMapStatusTextTest.java b/core/src/test/java/kst4contest/view/map/StationMapStatusTextTest.java new file mode 100644 index 00000000..246f6d26 --- /dev/null +++ b/core/src/test/java/kst4contest/view/map/StationMapStatusTextTest.java @@ -0,0 +1,150 @@ +package kst4contest.view.map; + +import org.junit.jupiter.api.Test; + +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; + +/** + * The one line of text above the map. + * + * It is the only place the operator is told how many stations are on the map at all, + * whether a filter is hiding some of them, and what is known about the one they picked. + * The Compose port showed "Selected: F5JMI" and nothing else. + * + * Pinned against updateStatusLabel() in StationMapView.java, which is what an operator + * has been reading since release 1.4x. + */ +class StationMapStatusTextTest { + + private MapCallsignRawSnapshot snapshot(String call, + String locator, + String bandSummary, + boolean offersSelectedBand, + double qrbKm, + double qtfDeg, + Map frequencies) { + return new MapCallsignRawSnapshot( + call, call, locator, 51.0, 10.0, bandSummary, frequencies, + offersSelectedBand, false, false, true, qrbKm, qtfDeg, 0, 0L + ); + } + + @Test + void without_a_selection_it_reports_only_the_count() { + assertEquals( + "Showing 49 visible stations", + StationMapStatusText.build(49, false, null) + ); + } + + @Test + void a_filtered_view_says_so_because_the_count_alone_would_mislead() { + assertEquals( + "Showing 12 visible stations | filtered view active", + StationMapStatusText.build(12, true, null) + ); + } + + @Test + void a_selected_station_adds_its_callsign_locator_distance_and_bearing() { + MapCallsignRawSnapshot selected = + snapshot("PA3EKM", "JO33GE", "", false, 316.4, 251.0, Map.of()); + + assertEquals( + "Showing 50 visible stations | Selected: PA3EKM | JO33GE | 316 km / 251° | Bands: - | QRG: -", + StationMapStatusText.build(50, false, selected) + ); + } + + @Test + void the_band_summary_is_marked_when_the_station_offers_the_selected_band() { + MapCallsignRawSnapshot selected = + snapshot("DG1BHA", "JO43", "144, 432, 1296", true, 100.0, 90.0, Map.of()); + + assertEquals( + "Showing 1 visible stations | Selected: DG1BHA | JO43 | 100 km / 90° | Bands: 144, 432, 1296 B+ | QRG: -", + StationMapStatusText.build(1, false, selected) + ); + } + + /** The detail text is multi-line; the status bar is one line. */ + @Test + void known_frequencies_are_folded_onto_one_line() { + Map frequencies = new LinkedHashMap<>(); + frequencies.put("144", "144.300"); + frequencies.put("432", "432.200"); + + MapCallsignRawSnapshot selected = + snapshot("DK2EA", "JO50UF", "144", false, 79.0, 125.0, frequencies); + + String status = StationMapStatusText.build(3, false, selected); + + assertEquals( + "Showing 3 visible stations | Selected: DK2EA | JO50UF | 79 km / 125° | Bands: 144" + + " | QRG: 144: 144.300 432: 432.200", + status + ); + assertFalse(status.contains("\n"), "the status bar is a single line"); + } + + @Test + void a_station_without_a_locator_is_not_given_an_empty_field() { + MapCallsignRawSnapshot selected = + snapshot("DL1ABC", "", "144", false, 50.0, 10.0, Map.of()); + + assertEquals( + "Showing 2 visible stations | Selected: DL1ABC | 50 km / 10° | Bands: 144 | QRG: -", + StationMapStatusText.build(2, false, selected) + ); + } + + /** + * QRB and QTF can be absent. Absent is not zero, and "NaN km" is not a reading an + * operator should be shown. + */ + @Test + void an_unknown_distance_or_bearing_is_shown_as_unavailable() { + MapCallsignRawSnapshot selected = + snapshot("DL1ABC", "JO50", "144", false, Double.NaN, Double.NaN, Map.of()); + + assertEquals( + "Showing 2 visible stations | Selected: DL1ABC | JO50 | - / - | Bands: 144 | QRG: -", + StationMapStatusText.build(2, false, selected) + ); + } + + @Test + void the_count_is_the_number_of_markers_the_map_was_given() { + List markers = List.of( + snapshot("A", "JO50", "", false, 1.0, 1.0, Map.of()), + snapshot("B", "JO50", "", false, 1.0, 1.0, Map.of()) + ); + + assertEquals( + "Showing 2 visible stations", + StationMapStatusText.build(markers.size(), false, null) + ); + } + + /** + * "Known to be unknown" is information. The JavaFX line appended " | QRG: -" + * because "-" is not blank, and dropping the segment instead leaves the operator + * unable to tell a frequency that is not known from one that fell off the end of an + * ellipsis. + */ + @Test + void a_station_with_no_known_frequency_still_gets_a_qrg_field() { + MapCallsignRawSnapshot selected = + snapshot("DL1ABC", "JO50", "144", false, 50.0, 10.0, Map.of()); + + assertEquals( + "Showing 2 visible stations | Selected: DL1ABC | JO50 | 50 km / 10° | Bands: 144 | QRG: -", + StationMapStatusText.build(2, false, selected) + ); + } +} diff --git a/core/src/test/java/kst4contest/view/map/TileFetcherTest.java b/core/src/test/java/kst4contest/view/map/TileFetcherTest.java new file mode 100644 index 00000000..f1c81b57 --- /dev/null +++ b/core/src/test/java/kst4contest/view/map/TileFetcherTest.java @@ -0,0 +1,279 @@ +package kst4contest.view.map; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.time.Duration; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; + +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +/** + * Getting map tiles, and admitting when it cannot. + * + * Three things were wrong with the first version. It asked the {@code a}/{@code b}/{@code c} + * subdomains, which OpenStreetMap has retired. It kept tiles in memory only, so every + * restart re-downloaded the same view from a service that asks callers not to. And a + * failed request returned null and said nothing, which is why a map with no network + * looked like a map with no stations. + */ +class TileFetcherTest { + + /** A source that records what it was asked for and answers from a script. */ + private static final class RecordingSource implements TileFetcher.TileSource { + + private final List requestedUrls = new CopyOnWriteArrayList<>(); + private final byte[] answer; + private final boolean fail; + + RecordingSource(byte[] answer, boolean fail) { + this.answer = answer; + this.fail = fail; + } + + @Override + public byte[] fetch(String url) throws IOException { + requestedUrls.add(url); + if (fail) { + throw new IOException("no route to host"); + } + return answer; + } + } + + private TileFetcher fetcherWith(Path cacheDirectory, RecordingSource source) { + return new TileFetcher(cacheDirectory, source); + } + + @Test + void the_url_is_the_one_openstreetmap_still_serves() { + String url = TileFetcher.tileUrl(6, 33, 21); + + assertEquals("https://tile.openstreetmap.org/6/33/21.png", url); + assertFalse(url.contains("://a.") || url.contains("://b.") || url.contains("://c."), + "the lettered subdomains are retired"); + } + + @Test + void a_tile_is_fetched_once_and_then_answered_from_memory(@TempDir Path cache) throws Exception { + RecordingSource source = new RecordingSource(new byte[]{1, 2, 3}, false); + TileFetcher fetcher = fetcherWith(cache, source); + + assertArrayEquals(new byte[]{1, 2, 3}, fetcher.fetchTileAsync(6, 33, 21).get()); + assertArrayEquals(new byte[]{1, 2, 3}, fetcher.fetchTileAsync(6, 33, 21).get()); + + assertEquals(1, source.requestedUrls.size()); + } + + @Test + void a_tile_survives_a_restart(@TempDir Path cache) throws Exception { + RecordingSource first = new RecordingSource(new byte[]{9, 9, 9}, false); + fetcherWith(cache, first).fetchTileAsync(7, 1, 2).get(); + + RecordingSource afterRestart = new RecordingSource(new byte[]{0}, false); + byte[] tile = fetcherWith(cache, afterRestart).fetchTileAsync(7, 1, 2).get(); + + assertArrayEquals(new byte[]{9, 9, 9}, tile); + assertTrue(afterRestart.requestedUrls.isEmpty(), "the disk cache should have answered"); + } + + @Test + void a_cached_tile_is_written_where_its_coordinates_say(@TempDir Path cache) throws Exception { + fetcherWith(cache, new RecordingSource(new byte[]{4}, false)).fetchTileAsync(8, 5, 6).get(); + + assertTrue(Files.exists(cache.resolve("8").resolve("5").resolve("6.png"))); + } + + @Test + void a_failed_request_is_reported_rather_than_swallowed(@TempDir Path cache) throws Exception { + TileFetcher fetcher = fetcherWith(cache, new RecordingSource(null, true)); + + assertNull(fetcher.fetchTileAsync(6, 33, 21).get()); + assertFalse(fetcher.hasReachedTileSource(), "nothing has arrived, and the map should be able to say so"); + assertTrue(fetcher.failedRequestCount() > 0); + } + + @Test + void a_source_that_answers_is_reported_as_reachable(@TempDir Path cache) throws Exception { + TileFetcher fetcher = fetcherWith(cache, new RecordingSource(new byte[]{1}, false)); + fetcher.fetchTileAsync(6, 33, 21).get(); + + assertTrue(fetcher.hasReachedTileSource()); + assertEquals(0, fetcher.failedRequestCount()); + } + + /** + * A failure must not be cached as an answer, or the tile never arrives at all. + * + * Retried after the pause, not on the next request: an immediate retry is what the + * tile service's usage policy calls abuse, and the map re-requests every visible + * tile on every change of view. + */ + @Test + void a_failure_is_not_remembered_as_an_answer(@TempDir Path cache) throws Exception { + RecordingSource source = new RecordingSource(null, true); + TileFetcher fetcher = new TileFetcher(cache, source, Duration.ofMillis(1)); + + fetcher.fetchTileAsync(6, 33, 21).get(); + Thread.sleep(20); + fetcher.fetchTileAsync(6, 33, 21).get(); + + assertEquals(2, source.requestedUrls.size()); + } + + @Test + void a_cache_directory_that_cannot_be_written_does_not_stop_the_map(@TempDir Path cache) throws Exception { + Path notADirectory = cache.resolve("blocked"); + Files.writeString(notADirectory, "this is a file, not a directory"); + + TileFetcher fetcher = fetcherWith(notADirectory, new RecordingSource(new byte[]{7}, false)); + + assertArrayEquals(new byte[]{7}, fetcher.fetchTileAsync(6, 1, 1).get()); + } + + /** + * The banner has to reach the one case it was written for: a restart without a + * network and a cache that holds some of the view. + * + * A latched "we reached the source once" flag cannot do that. The first cached tile + * sets it, every uncached tile then fails quietly, and the operator is left looking + * at half a map with no explanation — which is the screenshot this whole step + * started from. + */ + @Test + void a_cache_hit_does_not_silence_the_failures_around_it(@TempDir Path cache) throws Exception { + fetcherWith(cache, new RecordingSource(new byte[]{1, 2, 3}, false)).fetchTileAsync(6, 1, 1).get(); + + TileFetcher offline = fetcherWith(cache, new RecordingSource(null, true)); + offline.fetchTileAsync(6, 1, 1).get(); + offline.fetchTileAsync(6, 2, 2).get(); + + assertTrue(offline.isTileSourceUnavailable(), + "one cached tile must not hide that the rest cannot be had"); + } + + @Test + void a_tile_arriving_again_clears_the_warning(@TempDir Path cache) throws Exception { + TileFetcher fetcher = fetcherWith(cache, new RecordingSource(null, true)); + fetcher.fetchTileAsync(6, 1, 1).get(); + assertTrue(fetcher.isTileSourceUnavailable()); + + TileFetcher recovered = fetcherWith(cache, new RecordingSource(new byte[]{5}, false)); + recovered.fetchTileAsync(6, 1, 1).get(); + + assertFalse(recovered.isTileSourceUnavailable()); + } + + @Test + void nothing_requested_yet_is_not_a_warning(@TempDir Path cache) { + assertFalse(fetcherWith(cache, new RecordingSource(new byte[]{1}, false)).isTileSourceUnavailable()); + } + + /** + * A tile that cannot be decoded has to be removable, or it is cached forever. + * + * The process can die mid-write; a truncated PNG then sits in the cache and is + * served on every later run, so that square of the map is blank for good and there + * is no way back except deleting the directory by hand. + */ + @Test + void a_tile_that_turned_out_to_be_unusable_can_be_thrown_away(@TempDir Path cache) throws Exception { + TileFetcher fetcher = fetcherWith(cache, new RecordingSource(new byte[]{1, 2, 3}, false)); + fetcher.fetchTileAsync(9, 4, 5).get(); + assertTrue(Files.exists(cache.resolve("9").resolve("4").resolve("5.png"))); + + fetcher.discardTile(9, 4, 5); + + assertFalse(Files.exists(cache.resolve("9").resolve("4").resolve("5.png"))); + + RecordingSource again = new RecordingSource(new byte[]{7}, false); + assertArrayEquals(new byte[]{7}, fetcherWith(cache, again).fetchTileAsync(9, 4, 5).get()); + } + + /** A half-written tile must never be visible under its real name. */ + @Test + void a_tile_is_written_whole_or_not_at_all(@TempDir Path cache) throws Exception { + fetcherWith(cache, new RecordingSource(new byte[]{1, 2, 3, 4}, false)).fetchTileAsync(9, 4, 5).get(); + + try (var paths = Files.walk(cache)) { + assertTrue(paths.noneMatch(path -> path.getFileName().toString().endsWith(".tmp")), + "a temporary file was left behind"); + } + assertArrayEquals(new byte[]{1, 2, 3, 4}, Files.readAllBytes(cache.resolve("9").resolve("4").resolve("5.png"))); + } + + /** Closing has to stop the threads, or every window open leaks a pool. */ + @Test + void closing_the_fetcher_stops_its_threads(@TempDir Path cache) { + TileFetcher fetcher = fetcherWith(cache, new RecordingSource(new byte[]{1}, false)); + fetcher.fetchTileAsync(6, 1, 1).join(); + + fetcher.close(); + + assertTrue(fetcher.isClosed()); + } + + /** + * The tile service caps a client at two concurrent downloads and treats sustained + * retrying as abuse. This class quotes that policy in its own javadoc, so it had + * better keep it: eight connections plus an immediate retry of every failure is how + * an application gets blocked rather than throttled. + */ + @Test + void it_does_not_open_more_connections_than_the_tile_service_allows() { + assertTrue(TileFetcher.MAX_CONCURRENT_REQUESTS <= 2, + "OpenStreetMap's usage policy allows at most two concurrent downloads"); + } + + /** + * A tile that just failed is not asked for again on the very next pan. + * + * The map re-requests every visible tile whenever the view changes, so without a + * pause a server answering 429 would be hammered once per drag. + */ + @Test + void a_tile_that_just_failed_is_not_asked_for_again_immediately(@TempDir Path cache) throws Exception { + RecordingSource source = new RecordingSource(null, true); + TileFetcher fetcher = fetcherWith(cache, source); + + fetcher.fetchTileAsync(6, 33, 21).get(); + fetcher.fetchTileAsync(6, 33, 21).get(); + fetcher.fetchTileAsync(6, 33, 21).get(); + + assertEquals(1, source.requestedUrls.size(), + "the retries should have been held back rather than sent"); + } + + @Test + void a_tile_is_asked_for_again_once_the_pause_is_over(@TempDir Path cache) throws Exception { + RecordingSource source = new RecordingSource(null, true); + TileFetcher fetcher = new TileFetcher(cache, source, Duration.ofMillis(1)); + + fetcher.fetchTileAsync(6, 33, 21).get(); + Thread.sleep(20); + fetcher.fetchTileAsync(6, 33, 21).get(); + + assertEquals(2, source.requestedUrls.size()); + } + + /** A tile that arrives after a failure is not held back by the old failure. */ + @Test + void a_pause_does_not_outlive_a_successful_fetch(@TempDir Path cache) throws Exception { + TileFetcher failing = new TileFetcher(cache, new RecordingSource(null, true), Duration.ofMillis(1)); + failing.fetchTileAsync(6, 33, 21).get(); + Thread.sleep(20); + + RecordingSource working = new RecordingSource(new byte[]{3}, false); + TileFetcher recovered = new TileFetcher(cache, working, Duration.ofMillis(1)); + + assertArrayEquals(new byte[]{3}, recovered.fetchTileAsync(6, 33, 21).get()); + } +} diff --git a/docs/CONCEPT_IN_APP_UPDATE.md b/docs/CONCEPT_IN_APP_UPDATE.md new file mode 100644 index 00000000..6953fd8e --- /dev/null +++ b/docs/CONCEPT_IN_APP_UPDATE.md @@ -0,0 +1,306 @@ +# Konzept: In-App-Update für KST4Contest + +> Status: Konzept, noch nicht umgesetzt. Zielrelease **1.50**. Alle Zeilenanker beziehen sich auf `nextMajorRelease/version1_50` (Version 1.50.0) und wurden gegen den Branch verifiziert. + +## Ziel + +Stable-Updates werden nach Zustimmung des Nutzers heruntergeladen. KST4Contest beendet sich danach kontrolliert und startet den plattformspezifischen Aktualisierungsvorgang. Updates dürfen den Programmstart nicht blockieren und während eines Contests nicht erzwungen werden. + +## Ausgangslage + +Der vorhandene Mechanismus erfüllt das nicht: + +- `UpdateChecker.downloadLatestVersionInfoXML()` (`src/main/java/kst4contest/controller/UpdateChecker.java:54-71`) benutzt `new URL(...).openStream()` + `Files.copy(..., REPLACE_EXISTING)` **direkt auf die Zieldatei** — ohne Timeouts, ohne HTTP-Statusprüfung, ohne temporäre Datei. Ein Fehlschlag beschädigt zusätzlich die lokale Feed-Kopie. +- Der Aufruf steht **synchron im Konstruktor** von `ChatController` (`ChatController.java:2937-2941`); `ChatController` wird in `Kst4ContestApplication.start(Stage)` erzeugt (`Kst4ContestApplication.java:6971`, `start` ab `:6914`). Der Netzwerkaufruf läuft damit unbegrenzt **auf dem JavaFX-Application-Thread während des Starts** — genau der Punkt „darf den Programmstart nicht blockieren". +- `parseUpdateXMLFile()` (`UpdateChecker.java:73-236`) liest Kindelemente **positionsabhängig** über einen Zähler in `String[7]` bzw. `String[3]` (`:144-145`, `:182-183`). Ein achtes Kindelement in `` erzeugt eine `ArrayIndexOutOfBoundsException` und killt den gesamten Check. +- Die Anzeige ist ein eigenes `Stage` mit `setAlwaysOnTop(true)` (`Kst4ContestApplication.java:9162`), inline in `start()` aufgebaut (`:9152-9294`) und beim Start automatisch geöffnet (`:9280`). Es gibt **keinen Menüpunkt** zum erneuten Prüfen. Ein Catch-All bei `:9289-9292` schaltet die Funktion stillschweigend ab, sobald der Feed fehlt oder nicht passt. +- Toter Code: `main()` (`:27-34`) und ein Testdatenblock (`:208-234`). + +## Bestätigte Festlegungen + +| Punkt | Entscheidung | +|---|---| +| Contest-Schutz | Hinweis wird unterdrückt, solange eine ON4KST-Verbindung besteht | +| Update-Starter | Kein eigenes Starter-Programm; Installer/Paketverwaltung wird direkt gestartet, danach beendet sich KST4Contest | +| Flatpak | Nur Hinweis mit Update-Befehl, kein Download, kein Artefakt | +| AppImage | Kontrollierter Dateiaustausch, kein `AppImageUpdate` | +| Kanal | Ausschließlich Stable | +| Feed-Auslieferung | Bleibt wie bisher: der Webserver zieht das Repo alle 5 Minuten per Git und baut die Website selbst | +| Zuschnitt | Drei Stufen | +| Signatur | SignPath Foundation, als **optionaler additiver** CI-Schritt; unsigniert bleibt lauffähig | +| Windows-ZIP | Bleibt als portable Alternative | + +## Was unverändert bleibt + +1. **Alte Clients (≤ 1.44) am erweiterten Feed.** `UpdateChecker` sucht per `getElementsByTagName` nach `latestVersion`, `versionNumber`, `semanticVersion`, `adminMessage`, `majorChanges`, `latestVersionPathOnWebserver`, `changeLog`, `bug`. Das ist eine **Descendant-Suche** — deshalb kommt der neue Block als *Geschwister* neben `` und benutzt ausschließlich neue Elementnamen. +2. **`` behält exakt seine 7 Kinder** (`changedVersionNumber, date, description, added, changed, fixed, removed`) in unveränderter Reihenfolge, `` seine Struktur. ``, ``, `` bleiben unangetastet. +3. **`~/.praktiKST/`** — nur ein neues Unterverzeichnis `updates/`. `kst4ContestVersionInfo.xml` behält Name und Ort, damit ein Downgrade auf 1.44 funktioniert. +4. **Windows-ZIP als Portable** — die App verändert ihr eigenes Verzeichnis nie und führt für diesen Typ keinen Installer aus. +5. **Kein Eingriff** in Flatpak-, AUR-, DEB-, RPM- oder Arch-Installationen; **kein `sudo`/`pkexec`** aus der Anwendung heraus. +6. **Offlinebetrieb** — ein fehlgeschlagener Check ist stumm (nur `java.util.logging`), der Programmstart ist davon vollständig entkoppelt. +7. **Legacy-Vergleich** — `APPLICATION_CURRENTVERSIONNUMBER` und `` bleiben als Fallback; `VersionUtils.compareStableVersions` wird wiederverwendet und nicht verändert. +8. **Bei unbekannter Installationsart** wird ausschließlich die Downloadseite geöffnet. + +--- + +## Stufe 1 — Feed, Paketkennzeichnung, Prüfdienst, Hinweis-UI + +Kein Download, kein Installationsstart. + +### 1a. Installationsart zur Buildzeit kennzeichnen + +Es existiert heute **keinerlei** Build-Metadatum: kein `--java-options`, keine `.properties` unter `src`, kein Resource-Filtering in `pom.xml`, keine Manifest-Einträge. + +**Gewählter Mechanismus:** jpackage-Flag `--java-options -Dkst4contest.packageType=`. + +| Alternative | Warum nicht | +|---|---| +| Gefilterte `.properties`-Resource | **Alle Pakettypen entstehen aus demselben Maven-Artefakt**; die Unterscheidung fällt erst im jpackage-Aufruf. Lokale Builds und Tests bekämen einen falschen Marker. | +| Manifest-Eintrag | Gleiches JAR-Problem, mehr Bewegungsteile. | +| Verzeichnis-/Prozessheuristik | Laut Zielbild ausdrücklich ausgeschlossen; bei ZIP-Portable ohnehin frei verschiebbar. | +| Reines Env-Sniffing | Erkennt Flatpak und AppImage, aber nicht deb/rpm/arch/zip/msi. | + +Vorteile: keine Auswirkung auf `mvn`/Tests/lokale Entwicklung (Property fehlt → `UNKNOWN` → sicherer Fallback); der Wert landet in `lib/app/.cfg` des app-image und wird dadurch vom AUR-`-bin`-Repack (`packaging/aur/kst4contest-bin/PKGBUILD` macht nur `cp -a usr`) und vom Flatpak-Build (bindet das app-image als `type: dir`-Source ein) **automatisch mitkopiert**. + +Werte: `windows-zip`, `windows-msi`, `macos-dmg`, `linux-appimage`, `flatpak`, `linux-deb`, `linux-rpm`, `linux-arch`. + +**15 Aufrufstellen:** + +| Datei | Zeilen | Wert | +|---|---|---| +| `.github/workflows/tagged-release.yml` | 53 / 104 / 184 / 238 / 292 / 403 | `windows-zip` / `linux-appimage` / `linux-deb` / `linux-rpm` / `linux-arch` / `flatpak` | +| `.github/workflows/nightly-artifacts.yml` | 69 / 127 / 214 / 275 / 338 / 458 | dieselbe Reihenfolge | +| `packaging/macos/build-signed-dmg.sh` | 72 | `macos-dmg` | +| `packaging/aur/kst4contest/PKGBUILD` | 44 | `linux-arch` | +| `packaging/aur/kst4contest-git/PKGBUILD` | 37 | `linux-arch` | + +`packaging/aur/kst4contest-bin/PKGBUILD` erbt korrekt — **keine Änderung**. + +PowerShell-Syntax (tagged-release:53, nightly:69) braucht einfache Anführungszeichen, sonst frisst PowerShell das `-D`: +`--java-options '-Dkst4contest.packageType=windows-zip'` + +**Auflösung zur Laufzeit** (`RuntimePackageTypeResolver`), bewusst konservativ: + +1. `System.getProperty("kst4contest.packageType")`; unbekannter Wert → weiter. +2. `/.flatpak-info` vorhanden **oder** `FLATPAK_ID` gesetzt → `FLATPAK`. Diese Prüfung **überschreibt** die Property — eine Fehlklassifikation richtet ausgerechnet im Flatpak den größten Schaden an (Download in eine Sandbox, die den Host nie aktualisieren kann). +3. `APPIMAGE` gesetzt → `LINUX_APPIMAGE`. +4. sonst `UNKNOWN`. + +### 1b. Feed erweitern + +Der Feed wird **von der Website** erzeugt (`website/src/_data/versionInfo.js`, ausgeliefert über `website/src/version-info.njk`), gespeist aus der GitHub-Releases-API — nicht aus den Build-Jobs. Der Webserver zieht das Repository alle 5 Minuten per Git und baut selbst; eine geänderte `versionInfo.js` wird dadurch automatisch wirksam, **ohne** Upload-Schritt in den Workflows. + +**Platzierung: neues Top-Level-Element als Geschwister von ``.** Ein Kindelement *innerhalb* `` wäre riskant, weil der alte Parser dort per Descendant-Suche liest; als Geschwister ist jede Kollision strukturell ausgeschlossen. + +```xml + + + linux-deb + linux + x86_64 + KST4Contest-v1.45.0-debian-amd64.deb + https://github.com/praktimarc/kst4contest/releases/download/v1.45.0/… + 142335488 + 9f2c… + unsigned + …/releases/tag/v1.45.0 + package-manager + + + flatpak + linux + x86_64 + gpg-repo + …/releases/tag/v1.45.0 + hint-only + flatpak update de.x08.KST4Contest + + + +``` + +**Datenherkunft in `versionInfo.js`:** + +- `fileName`, `downloadUrl`, `fileSizeBytes` stehen **bereits in der vorhandenen `/releases`-Antwort** (`release.assets[]` mit `name`, `browser_download_url`, `size`) — kein zusätzlicher API-Aufruf. Aktuell werden die Assets weggeworfen. +- `packageType`/`operatingSystem`/`architecture` über einen deterministischen Klassifikator auf die Assetnamen, die die Workflows fest vergeben (`tagged-release.yml:783-791`): `-windows-x64.zip`, `-linux-x86_64.AppImage`, `-debian-amd64.deb`, `-fedora-x86_64.rpm`, `-archlinux-*.pkg.tar.zst`, `-macos-*.dmg`. `.flatpakref` erzeugt keinen Download, sondern den synthetischen Hint-Eintrag. Manuals und der Feed selbst werden übersprungen. +- **`sha256` muss der Release-Workflow erzeugen.** Im Job `release-tag` liegen alle Artefakte bereits unter `release-assets/*`, bevor `ncipollo/release-action` läuft. Dort nach den `download-artifact`-Schritten und **vor** „Create tagged release": + ```yaml + - name: Compute release asset checksums + run: | + cd release-assets + find . -type f ! -name SHA256SUMS.txt -print0 \ + | xargs -0 sha256sum | sed 's#\./##' > SHA256SUMS.txt + ``` + und `release-assets/SHA256SUMS.txt` in die `artifacts:`-Liste (`:783-791`) aufnehmen. Die bestehende Reihenfolge (Release zuerst, dann Website-Build, `:771-825`) bleibt korrekt — die Summen liegen zum Zeitpunkt des Website-Builds bereits am Release. `versionInfo.js` lädt die Datei **nur für das neueste Stable-Release** und baut daraus eine `filename → sha256`-Map; das ist ein Download-URL-Abruf und belastet das API-Ratelimit nicht. +- `signatureState` aus einer statischen Tabelle je packageType (`macos-dmg → apple-notarized`, `flatpak → gpg-repo`, Rest `unsigned`). In Stufe 3 wird `windows-msi` nur dann auf `authenticode` gesetzt, wenn ein signiertes Asset tatsächlich existiert — der Feed darf nicht lügen, wenn der SignPath-Schritt übersprungen wurde. + +**Robustheit:** Weil der Server unabhängig vom Release-Workflow baut, kann er einen Feed erzeugen, bevor `SHA256SUMS.txt` am Release hängt. Fehlt ``, gilt das Artefakt als **nicht automatisch ladbar** — der Client öffnet nur die Downloadseite. Ein Artefakt ohne Prüfsumme wird nie geladen und nie gestartet. Die bestehende `try/catch`-Klammer in `versionInfo.js` bricht den Website-Build bei einem unvollständigen Feed ab; die neue Sektion darf **nicht** so scharf sein — bei Problemen wird `` weggelassen, der Rest des Feeds bleibt gültig. + +**Mitzuziehen:** +- `website/scripts/validate-version-info.js` — bekannter `packageType`; `sha256` matcht `^[0-9a-f]{64}$`; `downloadUrl` beginnt mit `https://github.com/praktimarc/kst4contest/releases/download/`; `fileSizeBytes` numerisch > 0. **Zusätzlich neu und wichtig:** `` muss weiterhin exakt die 7 Kinder in der Altreihenfolge haben — das nagelt die Alt-Client-Kompatibilität fest. +- `website/test/version-info.test.js` — Klassifikator, SHA256SUMS-Parsing, „Release ohne Assets". + +**Warnung, nicht Teil dieser Umsetzung:** `.github/workflows/test-publish-version-xml.yml` (ungetrackt, nur `workflow_dispatch`) erzeugt mit einem eigenen Python-Generator einen konkurrierenden Feed **ohne** `` und lädt ihn per WebDAV hoch. Würde er ausgelöst, fielen alle Clients auf den kaputten Double-Vergleich (`1.41.1` → `1.411`) zurück. + +### 1c. Prüfdienst neu bauen + +Neues Package `kst4contest.service.update` (konsistent zum vorhandenen `kst4contest/service/path/`). + +| Datei | Verantwortung | +|---|---| +| `model/PackageType.java` | Enum + `feedId()`, `fromFeedId()` (null/unbekannt → `UNKNOWN`, wirft nie), `updateStrategy()` | +| `model/UpdatePackageInfo.java` | Transport-DTO, **explizite Klasse, kein Record** (AGENTS.md) | +| `model/UpdateCheckResult.java` | Ergebnis-DTO inkl. `resultSource` (`NETWORK`/`CACHE`/`NONE`) | +| `service/update/UpdateFeedParser.java` | **Reiner Parser**, kein IO, kein Netz | +| `service/update/UpdateFeedClient.java` | **Nur HTTP**, injizierbarer `HttpClient` + Timeouts | +| `service/update/UpdateCheckService.java` | Orchestrierung, injizierbare Abhängigkeiten + `Clock` | +| `service/update/RuntimePackageTypeResolver.java` | Installationsart, Test-Konstruktor für Property/Env/Pfad | + +Muster: `OpenMeteoTerrainProfileProvider.java:76-88` (injizierbarer Client, konfigurierbare Timeouts), `TerrainPackageDownloader.java:107-145` (Temp-Datei → Statusprüfung → `Files.move`). + +Verhalten: + +- Aufruf **asynchron im Daemon-Thread, erst nach `primaryStage.show()`** — nie vorher. `ChatController.java:2937-2941` entfällt. +- Ergebnis über eine `ObjectProperty` im `ChatController`, gesetzt via `Platform.runLater`. Muster: `lastUiReminderEvent` (`ChatController.java:4236-4243`). Der Worker fasst **keine** `ObservableList` an. +- Versionsvergleich über `VersionUtils.compareStableVersions`. **Achtung:** `parseVersion` wirft bei leerem oder nicht-numerischem Input (`IllegalArgumentException`/`NumberFormatException`) — der Dienst muss das fangen und auf den Double-Pfad zurückfallen. Heute ist das in der View (`:9266-9278`) nicht abgesichert. +- Ausschließlich Stable. Fehlende Verbindung erzeugt **keine** Meldung, nur einen Logeintrag über `java.util.logging` statt `System.out`. Höchstens eine Meldung je Sitzung. Bei Netzfehler Rückfall auf die zuvor gecachte Datei. + +**Positionales Parsing entschärfen:** Primärpfad namensbasiert (`readChildText(element, "changedVersionNumber")` …), Ergebnis weiterhin als `String[7]` in derselben Reihenfolge, damit der TreeView-Aufbau im Update-Fenster unverändert bleibt. Kompatibilitätspfad für uralte Feeds behält den positionalen Walk, aber mit `if (counter >= entry.length) break;`. Präfixe (`"Date: "`, `"Desc: "`) exakt erhalten. Bei `` ist `aChangeLogEntry[2]` heute uninitialisiert → explizit `""`. + +`UpdateChecker.java` wird durch den Dienst ersetzt. + +### 1d. Hinweis-UI + +Wiederverwendet wird das etablierte Muster `initSkedWarnIndicatorButton()` (`Kst4ContestApplication.java:5790-5807`) und `initBandUpgradeIndicatorButton()` (`:5965`): versteckt per Default, `managedProperty().bind(visibleProperty())`, eingehängt in `flwpne_StatusBar` (Aufbau `:7158`, `setTop` `:7161`, Indicator-Buttons `:7163`, `:7166`, `:7189`). + +Abweichung: **nicht** `setMouseTransparent(true)` — der Button ist klickbar und öffnet ein `ContextMenu`. + +- Text: `KST4Contest 1.x.y is available` +- Aktionen: Änderungen anzeigen · Update herunterladen (Stufe 1: deaktiviert bzw. „Release-Seite öffnen") · für diese Sitzung schließen +- **Contest-Regel:** `visible = updateAvailable && !dismissedForSession && Verbindungszustand != ONLINE`. `onConnectionStateChanged(...)` (`:12566`) ruft zusätzlich `refreshUpdateHintVisibility()` im vorhandenen `Platform.runLater`-Block — der Hinweis verschwindet beim Login in den Chat und kommt beim Trennen zurück. +- FX-Thread-Guard-Idiom aus `:5833` übernehmen. +- **Neuer Menüpunkt** im Info-Menü (Info-Menü, `helpMenu.getItems().addAll(...)` `:5774`): „Check for updates…" und „Show update details…". Damit existiert erstmals ein manueller Re-Check. +- Das bestehende `stage_updateStage` wird aus `start()` in eine eigene, **lazy** aufgerufene Methode herausgezogen; gespeicherte Fenstergröße (`getGUIstage_updateStage_SceneSizeHW`, `:9253-9260`) bleibt. Das Auto-`show()` (`:9280`) entfällt, `setAlwaysOnTop(true)` (`:9162`) wird entfernt — ein Always-on-Top-Fenster über einem laufenden Contest ist genau das, was das Ziel verbietet. + +### 1e. Versionsdrift absichern + +`pom.xml:9` und `ApplicationConstants.APPLICATION_CURRENT_VERSION` werden **von Hand gepflegt, ohne jede Prüfung**. Für einen Mechanismus, der genau diese Zeichenkette vergleicht, ist das die riskanteste Stelle. Analog zu `packaging/AddModules.java --verify-pom` (an `validate` gebunden, `pom.xml:219-240`) einen `--verify-version`-Wächter ergänzen. Kein Auto-Bump. + +`docs/PROJECT_CONTEXT.md:198` beschreibt zusätzlich die Kodierung von `APPLICATION_CURRENTVERSIONNUMBER` (`1.43.1` → `1.431`) — beim Bump mitführen, solange das Legacy-Feld existiert. Auf 1.50 stehen die Werte in `ApplicationConstants.java:23` und `:30`. + +### 1f. `--app-version` nachziehen + +Außer im macOS-Skript (`build-signed-dmg.sh:75`) setzt **kein** jpackage-Aufruf `--app-version`. DEB und RPM tragen dadurch intern die Vorgabeversion `1.0`; ein `apt install ./KST4Contest-v1.45.0.deb` wäre für dpkg **kein Upgrade**. Vor Stufe 3 zwingend, sinnvollerweise überall — dieselbe `sed`-Ableitung wie `build-signed-dmg.sh:59-65`. Nebenwirkung: bestehende DEB/RPM-Installationen springen einmalig von `1.0` auf die echte Version. + +--- + +## Stufe 2 — Gesicherter Download + +Erst nach „Update herunterladen". + +| Datei | Verantwortung | +|---|---| +| `service/update/UpdateDownloadPolicy.java` | Reine Validierung, kein IO | +| `service/update/UpdateDownloadService.java` | Download + Verifikation | +| `service/update/UpdateStorage.java` | `~/.praktiKST/updates/`, Aufräumen verwaister Dateien | +| `model/UpdateDownloadResult.java` | Ergebnis-DTO | + +**Ablauf** (Muster `TerrainPackageDownloader.java:93-165`): + +1. Download nach `.download`; +2. Prüfung von Dateigröße **und** SHA-256 (`computeSha256`, `:175-187`, 8-KiB-Puffer + `HexFormat`); +3. `Files.move` erst nach erfolgreicher Prüfung; +4. bei Abbruch oder falscher Prüfsumme temporäre Datei löschen, verständliche Meldung; +5. **niemals** ein ungeprüftes Artefakt starten. + +Empfehlung: `BodyHandlers.ofInputStream()` + `DigestInputStream` statt `ofFile` — ein Durchlauf statt zwei, und ein Fortschrittsbalken ist bei 150-MB-Dateien Pflicht. Short-circuit, wenn die Zieldatei bereits mit passendem Hash existiert. + +**Sicherheitsschranke — nicht optional:** SHA-256 aus dem Feed beweist nur, dass die Datei zum Feed passt. Da der Feed über einen selbst gebauten Host ausgeliefert wird, ist eine **Host-Allowlist** (`github.com`, `objects.githubusercontent.com`) die eigentliche Schutzschicht: selbst ein manipulierter Feed kann keine beliebige URL unterschieben. `UpdateDownloadPolicy` prüft zusätzlich: Schema `https`; `sha256` matcht `^[0-9a-fA-F]{64}$`; `fileName` ohne `/`, `\`, `..`; `fileSizeBytes` > 0 und < 1 GiB; ausreichend Plattenplatz; `packageType` erlaubt Download. + +Stufe 2 führt **nichts** aus. Nach Erfolg: „Jetzt beenden und aktualisieren" / „Später installieren". Flatpak erhält gar keinen Download-Pfad, sondern den Hinweistext aus ``. + +--- + +## Stufe 3 — Plattformausführung, Windows-Installer, Signatur + +### 3a. Windows-Installer + +`--type msi` mit **dauerhaft konstanter** `--win-upgrade-uuid`, dazu `--win-menu --win-shortcut --win-dir-chooser`. `choco install wixtoolset` steht bereits in beiden Workflows (`tagged-release.yml:33-35`, `nightly-artifacts.yml:49-51`) und wird bisher **nicht genutzt** — die Voraussetzung ist vorhanden. Der ZIP-Build bleibt bestehen. + +Die GUID muss dokumentiert werden (z. B. `packaging/windows/README.md`) — ändert sie sich, sind MSI-Upgrades dauerhaft kaputt. Asset in die `artifacts:`-Liste und in den SHA256SUMS-Schritt aufnehmen. + +### 3b. Ausführung je Installationsart + +| Installation | Verhalten | +|---|---| +| `windows-msi` | `msiexec /i "" /qb` detached, danach beenden | +| `windows-zip` | Keine Ausführung. Installer laden, Ordner öffnen, Benutzerdaten bleiben. **Hinweis nötig**, dass der alte ZIP-Ordner bestehen bleibt und künftig der Installer-Eintrag zu starten ist — sonst startet der Nutzer weiter die alte `praktiKST.exe` und sieht nie wieder ein Update | +| `macos-dmg` | `open ""`, danach beenden; der Nutzer zieht selbst. Ein laufendes `.app` kann sich ohne separates Updater-Binary nicht ersetzen | +| `linux-appimage` | Neues AppImage neben `$APPIMAGE` ablegen, `chmod +x`, Ordner öffnen, beenden. Kein In-Place-Overwrite einer laufenden Datei | +| `flatpak` | Nur Verweis auf `flatpak update de.x08.KST4Contest`; keine Datei im Paket anfassen | +| `linux-deb/rpm/arch` | `xdg-open ""` → GNOME Software / Discover / gdebi übernehmen inkl. Rechteabfrage. **Bewusst kein `pkexec`/`sudo`** aus der Anwendung heraus | +| AUR | Verweis auf den vorhandenen AUR-Helper | +| `UNKNOWN` | Ausschließlich Downloadseite öffnen | + +Kein eigener Update-Starter. Der kontrollierte Ausstieg: Verbindung prüfen und ggf. bestätigen lassen → ON4KST sauber trennen → Layout/Preferences flushen → DB schließen → Installer starten → `Platform.exit()` + `System.exit(0)`. Kein `Runtime.halt`. Der vorhandene Weg über `Kst4ContestApplication.stop()` (`disconnect("CLOSEALL")` + `System.exit(0)`) bleibt die Basis. + +### 3c. SignPath + +Eigener Step im MSI-Job, gegated über das Vorhandensein des Secrets. Fehlt es (bis zur Foundation-Freigabe), läuft die Pipeline unverändert durch und liefert ein unsigniertes MSI. Signiertes Ergebnis unter eigenem Namen hochladen; `versionInfo.js` setzt `signatureState` nur, wenn dieses Asset existiert. + +**Vorbedingung für die Abhängigkeitsprüfung:** `module-info.java:14-15` deklariert `requires org.junit.jupiter.api;` und `requires org.mockito;`, weil Testklassen unter `src/main/java/` liegen (u. a. `controller/On4KstProtocolTest.java`, `controller/On4KstSocketThreadTest.java`, `controller/ReadUDPByWintestThreadTest.java`, `test/MockKstServer.java`, `view/map/mapTest.java`). `pom.xml` deklariert `junit-jupiter-api` und `mockito-core` deshalb mit `compile`, und JUnit, Mockito, ByteBuddy und Objenesis landen im ausgelieferten Runtime-Image — im Flatpak in `lib/app/` nachgewiesen. Ausgerechnet ByteBuddy/Mockito (Bytecode-Manipulation, Agent) in einem signierten Produktionsbinary ist für so eine Prüfung ungünstig. Als **eigener, abgegrenzter Commit vor dem Antrag** bereinigen: Klassen nach `src/test/java/`, `requires` entfernen, Scopes zurück auf `test`. + +--- + +## Tests + +Alle neuen Tests unter `src/test/java/kst4contest/service/update/` bzw. `.../model/`, Fixtures unter `src/test/resources/update/`. **Nichts Neues unter `src/main/java`** — die dort liegenden Testklassen sind Altlast, keine Vorlage. + +| Testklasse | Assertions | +|---|---| +| `UpdateFeedParserTest` | Legacy-Feed 1.44 ohne `` parst korrekt; erweiterter Feed, Reihenfolge irrelevant; `` mit 8 Kindern → **keine** `ArrayIndexOutOfBoundsException`; kaputtes XML → leeres Ergebnis statt Exception; XXE-Payload wird nicht expandiert; `sha256` in Großbuchstaben wird normalisiert | +| `UpdateFeedClientTest` | 200 → Zieldatei ersetzt; 404/500 → Temp gelöscht und **vorhandene Zieldatei unverändert** (die konkrete Regression gegenüber `UpdateChecker:54-71`); Timeout → `success=false`, kein Throw; leerer Body verworfen | +| `UpdateCheckServiceTest` | 1.44.0/1.44.0 → kein Update; /1.45.0 → Update; /1.4.4 → kein Update; /1.44.1 → Update; kaputte `semanticVersion` → Double-Fallback statt Exception; Netz down + Cache → `CACHE`; ohne Cache → `NONE`; Paketauswahl je Typ; `UNKNOWN` → kein Paket; injizierte `Clock` für den Prüfrhythmus | +| `RuntimePackageTypeResolverTest` | Property gewinnt; unbekannter Wert → `UNKNOWN`; `/.flatpak-info` → `FLATPAK` **auch gegen** widersprechende Property; `APPIMAGE` → AppImage; alles `null` → kein NPE | +| `UpdateDownloadPolicyTest` | `http://` abgelehnt; fremder Host abgelehnt; fehlende/zu kurze/nicht-hex `sha256` abgelehnt; `fileName` mit `../` abgelehnt; Größe ≤ 0 abgelehnt; `FLATPAK`/`UNKNOWN` abgelehnt | +| `UpdateDownloadServiceTest` | Ohne Netz über `com.sun.net.httpserver.HttpServer` auf Port 0 (JDK-only, keine neue Dependency): Hash-Mismatch → Temp gelöscht, Ziel **nicht** angelegt; Match → Bytes identisch; Non-2xx → Temp gelöscht; bereits gültige Datei → kein HTTP-Call; Progress monoton bis `totalBytes`; Abbruch → Temp gelöscht | +| `UpdateLauncher*Test` (Stufe 3) | Injizierter `ProcessStarter` fängt die Kommandozeile: MSI → `[msiexec, /i, , /qb]`; deb/rpm/arch → `[xdg-open, ]`; dmg → `[open, ]`; **kein Kommando enthält `sudo` oder `pkexec`** (explizite Assertion); `FLATPAK`/`UNKNOWN`/`WINDOWS_ZIP` → `ProcessStarter` nie aufgerufen | +| `website/test/version-info.test.js` | Klassifikator für alle Namensmuster; SHA256SUMS-Parsing inkl. Doppelspace; Release ohne Assets → Feed bleibt valide; erzeugter Feed hat weiterhin exakt 7 ``-Kinder | + +Versionsvergleich: bestehende `VersionUtils`-Abdeckung um nicht-numerische Eingaben ergänzen. + +--- + +## Dokumentation + +Nach jeder Stufe eine gezielte Einordnung, kein Voll-Audit (`AGENTS.md`): + +- `github_docs/de-Installation.md` und `github_docs/en-Installation.md` — Windows-Installer, Verhältnis zum ZIP, Update-Weg je Paketformat, Flatpak-Hinweis. Beide Sprachversionen semantisch gleichziehen. +- Neuer Abschnitt zur Updatefunktion (Hinweis, Zustimmung, Contest-Regel, Verhalten je Installationsart) — DE und EN. +- `docs/PROJECT_CONTEXT.md` — Abschnitt „Website / Deployment Relationship" (`:192-200`) um Feed-Format, Paketkennzeichnung, Host-Allowlist und die Entscheidung gegen ein Updater-Binary ergänzen. +- `website/src/features/` prüfen, ob die Funktion dort dargestellt werden soll. +- Screenshots des Hauptfensters veralten durch den Hinweisbereich — als veraltet markieren, nicht erfinden. + +## Verifikation + +1. `./mvnw -B test` — **Surefire-Berichte einzeln lesen**, nicht am Exit-Code messen (`AGENTS.md`: Testfehler brechen den Build nicht ab). Hinweis: auf Host-JDK 26 schlagen 8 Mockito-Tests umgebungsbedingt fehl; mit Temurin 21 prüfen. +2. `cd website && npm test && npm run build && npm run validate:version-info` gegen einen erweiterten Beispiel-Feed. +3. **Abwärtskompatibilität:** erweiterten Feed gegen den **alten** `UpdateChecker` laufen lassen und bestätigen, dass `` und `` unverändert gelesen werden. +4. **Startverhalten:** Anwendung mit nicht erreichbarer Feed-URL starten — die UI muss ohne Verzögerung und ohne Meldung hochkommen. +5. **Contest-Regel:** mit ON4KST verbunden erscheint kein Hinweis; nach dem Trennen erscheint er. +6. **Paketkennzeichnung:** je Artefakt einmal starten und die erkannte Installationsart prüfen. Der Flatpak lässt sich lokal testen — die Sandbox ist netzwerkseitig transparent (verifiziert). +7. **Stufe 2:** Download mit absichtlich falscher Prüfsumme — es darf keine Zieldatei entstehen und nichts gestartet werden. + +## Offene Punkte + +1. **Zweite Feed-Quelle?** Wenn der serverseitige Build hinterherhinkt, sehen Clients einen veralteten Feed. Soll der Client hilfsweise `https://github.com/praktimarc/kst4contest/releases/latest/download/kst4ContestVersionInfo.xml` verwenden? +2. **`test-publish-version-xml.yml`** bleibt vorerst unverändert, ist aber scharf (Feed ohne ``). Bei der späteren Umstellung auf GitHub Actions zusammenführen oder entfernen. +3. **`--app-version` überall setzen** ändert die Paketversion bestehender DEB/RPM-Installationen einmalig von `1.0` auf die echte. Akzeptabel? +4. **`UpdateChecker.java`** löschen oder als deprecated Fassade behalten? (`module-info.java` exportiert `kst4contest.controller`.) +5. **MSI vs. ZIP** — soll MSI der empfohlene Windows-Weg werden? Beide Installationen können parallel existieren; ein MSI-Upgrade findet eine ZIP-Installation nicht. +6. **Opt-out-Preference?** Soll `ChatPreferences` ein „Check for updates on start" bekommen? Der Abruf verrät IP und Version an den Feed-Host. +7. **Prüfrhythmus** — einmal pro Start, oder höchstens alle 24 h über einen Zeitstempel in `~/.praktiKST/`? +8. **Beta-Nutzer** — `1.46.0-beta` gegen Stable `1.45.0` ergibt „kein Update", weil `compareStableVersions` das Suffix abschneidet. Gewollt? +9. **Signaturzustand** darf nur automatisch aus dem Build stammen, sonst driftet er. +10. **Vertrauensmodell** — soll der Feed mittelfristig selbst signiert werden (Detached-Signatur + eingebauter Public Key)? +11. **ZIP-Migration** — der Hinweistext für den Wechsel ZIP → Installer muss formuliert und in beiden Sprachversionen dokumentiert werden. diff --git a/docs/PROJECT_CONTEXT.md b/docs/PROJECT_CONTEXT.md index 65675bae..ec9f9a71 100644 --- a/docs/PROJECT_CONTEXT.md +++ b/docs/PROJECT_CONTEXT.md @@ -6,16 +6,16 @@ This file is the durable technical project context for KST4Contest. It is not a ## Purpose -KST4Contest is a Java/JavaFX desktop client for ON4KST chat focused on VHF/UHF/microwave contest workflows. It combines chat handling with contest-oriented station prioritisation, sked/timeline workflows and integrations with logging, aircraft-scatter, rotor and DX-cluster tooling. +KST4Contest is a Java/Kotlin desktop client for ON4KST chat, with a Compose Multiplatform user interface, focused on VHF/UHF/microwave contest workflows. It combines chat handling with contest-oriented station prioritisation, sked/timeline workflows and integrations with logging, aircraft-scatter, rotor and DX-cluster tooling. ## Current Architecture -- Java 21 / JavaFX desktop application built with Maven. -- Main code is under `src/main/java/kst4contest/`. +- Java 21 desktop application built with Gradle in the modules `core` (domain, free of user-interface technology) and `app-desktop` (the Compose Multiplatform user interface). +- Domain, controller and network code is under `core/src/main/java/kst4contest/`, the user interface under `app-desktop/src/main/java/kst4contest/`. Package names are shared across both modules. - Responsibilities are separated across controller, service, logic, model, utility and view areas. - Network/parser/service/controller/UI boundaries should remain explicit. - Long-running network/message processing must tolerate malformed or incomplete external input without terminating processing threads. -- JavaFX `ObservableList` state is a UI projection, not the canonical worker-thread domain store. +- `ObservableRoster` state in `core` is the canonical store; the `ObservableList` a `TableView` is bound to is a mirror of it, not the store. ## Important Invariants @@ -36,23 +36,30 @@ KST4Contest is a Java/JavaFX desktop client for ON4KST chat focused on VHF/UHF/m - Features that depend on frequency should use the current/actual QRG according to current implemented rules; do not silently revert to a fixed 144 MHz default. - Complete digit-only frequencies use their final three digits as the kHz part and are accepted only when the resulting MHz value lies within a supported `Band` range. The same full-frequency parser is used for station names and public or directed chat messages. Relative QRG rules and bare three-digit context handling remain separate. -### JavaFX/threading +### Threading Conceptually: ```text -thread-safe canonical domain state +thread-safe canonical domain state in core + | kst4contest.observe: ObservableRoster / ObservableValue | - | projection on JavaFX Application Thread + | hand-off via UiDispatcher v -JavaFX ObservableList / UI state +mirror on the user-interface thread (FxRosterBinding -> ObservableList) ``` -`MessageBusManagementThread` must not directly iterate or mutate UI-bound JavaFX collections. UI-visible changes should cross the controller/UI boundary and run on the JavaFX Application Thread. +`core` contains no user-interface technology. It observes through `kst4contest.observe` and hands UI-visible work over through `UiDispatcher`, whose implementation is `AwtUiDispatcher` in `app-desktop`. It delivers to the AWT event dispatch thread, which is the thread Compose composes on. The former `JavaFxUiDispatcher` was deleted with the JavaFX lifecycle. + +`MessageBusManagementThread` must not directly iterate or mutate a UI-bound collection; it works on snapshots. UI-visible changes cross the controller/UI boundary through the dispatcher. + +A roster hands out immutable snapshots and has no incremental change protocol: listeners receive the whole new content. `FxRosterBinding` mirrors a roster into the `ObservableList` a `TableView` holds, and must be disposed when its owner goes away — `shutdownRuntime()` releases all of them, which is what keeps a discarded runtime from surviving an operator profile switch. + +A batch of changes belongs in one `SimpleRoster.mutate(...)`, not one call per element: with several thousand ON4KST users the difference is not cosmetic. ## Configuration and Layout Persistence -- The current `preferences.xml` configuration version is 8. Version 8 adds the default-enabled `messageHandling_debugModeToFileEnabled` setting. Missing entries in older files retain the enabled default. Version 6 introduced optional managed leaf-column widths below `guiOptions`, identified by stable table and column IDs. Parent-column widths remain derived from their leaf columns. +- Configuration and layout live in the `preferences.xml` of the **active operator profile**; see "Operator Profiles and Per-Profile Persistence" below. The current `preferences.xml` configuration version is 8. Version 8 adds the default-enabled `messageHandling_debugModeToFileEnabled` setting. Missing entries in older files retain the enabled default. Version 6 introduced optional managed leaf-column widths below `guiOptions`, identified by stable table and column IDs. Parent-column widths remain derived from their leaf columns. - `GUIstationMapClusteringEnabled` is a layout preference below `guiOptions`. It defaults to `true`, is selectively autosaved and controls only screen-based clustering of nearby map markers. Missing or malformed values retain the enabled default for backward compatibility. - Stored widths take precedence. Without a usable entry, a managed column is sized once when meaningful table data first becomes available. Message and similar free-text columns use a flexible initial width instead of following the longest value. - Main-window and separate-monitor DXCluster/QSO tables use distinct layout IDs even though they share the underlying message stores. @@ -61,6 +68,27 @@ JavaFX ObservableList / UI state - Full and selective writes are synchronized and replace `preferences.xml` atomically. Missing, unknown or malformed width entries do not prevent loading and fall back to initial sizing. - Older configuration files require no migration. Older KST4Contest versions can ignore the additional elements; a complete rewrite by such a version may discard column widths without invalidating the remaining file. +## Operator Profiles and Per-Profile Persistence + +- One operator profile owns one `preferences.xml`, one worked-station database, its own pair of stylesheets and its own interface language (all since release 1.50). Everything else under `~/.praktiKST/` stays global: audio files, DEM and terrain packages, the error log and the version-info feed. +- The **root profile** is the historic flat installation: `preferences.xml` and `praktiKST.db` directly below the application directory. It is never moved, and it always uses the common station database, because that database is the installation's own. +- Additional profiles live under `profiles//`. `profileId` is a stable, file-system-safe slug assigned once; renaming a profile changes only its display name and never moves a directory. +- The registry `profiles.xml` is created lazily. An installation that has only the flat layout gets no registry and no `profiles/` directory; the root profile is synthesised in memory. Startup with no or exactly one profile therefore asks nothing and writes nothing, and a downgrade to an older release is a no-op. +- The registry stores `profileId`, `displayName`, `rootProfile` and `sharedWorkedDatabase`, never a path. Both file names are derived in `OperatorProfilePaths` alone, so a stored path cannot drift apart from the flag that produced it. +- `sharedWorkedDatabase` resolves to a path, not to a schema change: a sharing profile points at the flat `praktiKST.db`, an owning profile at its own file. There is no owner column, and no SQL statement in `DBController` knows about profiles. +- A profile database is created **empty**. The bundled `/praktiKST.db` resource carries several thousand foreign callsigns and `user_version = 0`; seeding an additional profile from it would show a new operator foreign data and trigger the full callsign-normalization rebuild. Only the root installation is seeded from the resource. `preferences.xml` of a new profile *is* seeded from `/praktiKSTpreferences.xml`, because its defaults are what a first installation gets. +- Worked-state semantics are unchanged and now apply per database file: normalized base callsign as key, worked state shared across suffix variants, three-day expiry, manual reset. +- `stn_loginCallSign` and `stn_loginCallSignRaw` default to empty. The preferences reader treats an empty element as "not set" and falls back to the field default, so a non-empty default would make a profile created without credentials come up carrying a compiled-in callsign. +- Passwords remain plaintext per profile. Profiles separate configuration; they are explicitly not an access-control boundary. This is documented in both manuals. + +### Runtime profile switching + +- A switch tears the current runtime down through `Kst4ContestApplication.shutdownRuntime()` and builds a **new** `Kst4ContestApplication` instance. Reusing the instance is not possible: many controls are inline-initialised instance fields, so a second `start()` would re-parent mounted nodes and register every listener twice. The approach is only sound because the class holds no mutable static state. +- All exits run through `ApplicationRuntimeLauncher.exitApplication()`, including the main window's close request: a profile switch closes every window of the old runtime before the new one exists, so a window close must never be what ends the process. The former `Platform.setImplicitExit(false)` and `Application.stop()` are gone with JavaFX; a shutdown hook on `shutdownRuntime()` covers a SIGTERM instead, and the guard is atomic because the hook runs on its own thread. +- `shutdownRuntime()` is idempotent and must release everything that outlives a disconnect: the ON4KST supervisor thread, the sked reminder scheduler, the reachability executor, the PSTRotator retry scheduler, the station-list coalescing trigger, both view timers and every Compose window. Several of these were real leaks before; they only became visible once a second runtime could exist. +- `ApplicationConstants.sessionRuntimeUniqueId` must not be regenerated during a switch, so UDP readers started earlier still recognise their own poison pill. +- The layout autosave is flushed and then cancelled before a switch, so a pending debounced write cannot land after the profile changed. + ## External Interfaces Treat current implementation/tests and authoritative upstream documentation as source of truth before modifying any interface. @@ -98,7 +126,7 @@ CR/LF framing, XML framing, ports/transports, callsign normalization and frequen - Automatic QRG updates require both an enabled source and valid incoming `RadioInfo` or Win-Test `STATUS` data. Merely enabling a source does not provide or validate a current QRG. - UCXLog-compatible QSO packets and Win-Test `ADDQSO` packets are converted into one validated external-QSO state. Logger-specific numeric, metre and centimetre values and Win-Test band IDs are normalised once; the resolved band is then the sole source for per-band Worked and worked-grid state. - A missing or unknown logger band sets only the global Worked state. Worked-grid state requires both a recognised project band and a valid locator; no band or locator is inferred. Packets without a usable callsign are discarded without terminating the listener. -- External logger threads do not read or mutate the JavaFX user-list projection. `ChatController` applies global and per-band Worked state to every active variant of the base callsign on the JavaFX Application Thread before evaluating a band-upgrade notice. +- External logger threads do not read or mutate the user-list mirror. `ChatController` applies global and per-band Worked state to every active variant of the base callsign on the user-interface thread, through `UiDispatcher`, before evaluating a band-upgrade notice. - The established Win-Test handling for 24, 47 and 76 GHz remains unchanged. Their Worked flags are retained, while only frequencies represented by the project `Band` model can create worked-grid state. ### Win-Test log recovery @@ -114,6 +142,8 @@ CR/LF framing, XML framing, ports/transports, callsign normalization and frequen ### Terrain data providers - The active terrain profile provider is Open-Meteo using Copernicus GLO-90 data. +- The terrain profile cache lives in its own global database `~/.praktiKST/terrainprofilecache.db`. It is deliberately not part of an operator profile: terrain profiles are pure geometry derived from two locators and a sample count, and at a multi operator station both operators share one location, so a per-profile copy would only double the traffic against the terrain service. +- Cached entries are separated by owner identity through the primary key (`owner_callsign_raw` + `owner_locator6`). Earlier versions stored a single owner identity in a meta table and dropped the whole cache whenever the configured callsign or locator changed; with several operator profiles that would discard every computed profile on each switch. The old `TerrainProfileCache*` tables inside `praktiKST.db` are left in place and are still readable by older releases; the new file starts empty and refills itself. - `OfflineDemImportService` only prepares a local directory and copies manually selected Copernicus GLO-30 GeoTIFF files into it. Importing files does not activate an offline provider or change the active calculation chain. ### ON4KST session and authentication @@ -166,8 +196,8 @@ CR/LF framing, XML framing, ports/transports, callsign normalization and frequen ## Build / Verification -- Use the repository Maven wrapper (`.\mvnw.cmd` on Windows). -- The project uses Java 21 / JavaFX 21.x at this context snapshot. +- Use the repository Gradle wrapper (`.\gradlew.bat` on Windows). +- The project uses Java 21, Kotlin 2.2 and Compose Multiplatform 1.8.x at this context snapshot. JavaFX has been removed; no `org.openjfx` dependency remains. - JUnit 5/Mockito, PMD and SpotBugs are part of the verification environment. - Build/test configuration has historically allowed some test/static-analysis failures not to fail the process exit code. Always read actual summaries/reports. @@ -240,9 +270,76 @@ section records only the durable architecture and operational boundaries. ## Important Decisions and Workarounds +- **The interface language has four kinds of text, and the rule is the addressee** (release + 1.50): interface text is translated; protocol text (the pipe-framed opcodes in + `On4KstProtocol`, and the `/`-prefixed chat commands) and amateur shorthand (the + `ChatPreferences` defaults, snippets, shortcuts, and QRA/QRG/QTF/LOS/Fresnel in labels) are + not; and diagnostic text -- the `println` calls in `core` -- is not either, because a German + stack trace is worse for whoever reads the bug report. Ask who reads it, not what it looks + like. +- **`core` produces no display text.** It returns a key or an enum and `app-desktop` turns it + into words. That is the language half of "core stays toolkit-free", and it also means no + German string can reach a protocol or a log line by construction. Two violations predate the + rule and are named in the stage 9 spec: `PathPropagationAssessment` and `PriorityCalculator`. +- **Incompleteness is allowed in a translation, incorrectness is not.** A missing key warns and + falls back to English at runtime, so a partial contributed language can be submitted; an + orphan key, a placeholder mismatch, a duplicate key or an unreadable file fail the build. The + argument count always comes from the English base. +- **Anything built outside a composition needs its text read inside one.** Window titles, tab + titles and column headers are all built once at startup -- the columns from Java -- so each + holds a function rather than a string. A stored string freezes at whatever was true when the + window opened, which is how the main window's title said "KST4Contest (Compose)" for a whole + session and the tab strip stayed English while its contents switched. +- **A column's `id` is never translated.** It is what the remembered column widths and order + are keyed on; translating it would read an operator's stored layout under names that no + longer match. + +- **The palette has three sources, and the later one wins role by role** (release 1.50): the + shipped stylesheet from the classpath, then the profile's own stylesheet file if present, + then the six role overrides stored in that profile's preferences. `resolvePalette` is a pure + function and reports the provenance of every role, which the colours tab shows per field -- + with two sources able to decide the same colour, that is the only thing that keeps "why is + this colour what it is" answerable, and it is not optional. +- **A role is a selector and a property, not a property alone.** Three of the six are stated + outside `.root` (text on `.label`, the separator on `.separator *.line`), and + `-fx-background-color` alone appears a dozen times in the evening sheet. `JavaFxStylesheet.read` + returns a complete palette with Modena fallbacks and is right for layer 1; + `declaredRoles` returns only what a sheet actually names and is the only thing correct for + layer 2. Measured: the shipped daylight sheet states no colour at all, the evening sheet five. +- **The root profile's layer 2 always exists, and that is not a bug.** `copyResourceIfRequired` + writes `KST4ContestDefaultDay.css` and `…Evening.css` at every startup, and those are exactly + the paths `paletteRelativeFileName(rootProfile, …)` resolves to — reading them is what fixes + the long-standing defect that the copies were written and never read. Consequence to keep in + mind: on the default installation most roles report *from file*, not *shipped*, with the same + values. Anything keyed on provenance rather than on a colour's value will therefore misfire + there; `textAccent` did, and repainted the evening accent on upgrade. +- **A file stating `-fx-base` and no `-fx-background` states the derived window surface too**, + because that is what JavaFX does with it. The settings tab keeps the two roles independent — + the spec separates them so an operator can set one without the other — but a hand-edited + sheet follows the stylesheet language, or `-fx-base: #303030` would leave every window the + shipped light grey. +- **The contrast guard's pairs come from `Theme.kt`'s Material mapping, not from the role + names.** `background` and `surface` are both `windowBackground` with `labelTextFill` on them, + and `primary` is `textAccent`, not `accent`; `base` reaches the screen only through the menu + strip and the selection tint. Measuring text against `base` alone let an operator black out + every window and hear nothing. +- **`Kst4ContestTheme` must read the palette from the `PaletteStore`'s state, never from + `remember`.** That read is what makes a colour change recompose every open window; + `remember(darkMode)` held the palette until someone toggled day/evening, so a change reached + nothing. `ThemeReadsPaletteStoreTest` pins it. +- **The contrast guard is relative to the shipped sheet, not an absolute WCAG floor.** Measured: + the shipped sheets have three pairs under 4.5 themselves (daylight accent 2.86, evening accent + 2.26, evening text-in-field about 2.9), so an absolute rule would warn on an untouched client + and teach the operator to ignore warnings. It reports a pair only when it is both under the + floor and worse than shipped, so the shipped state and any improvement never warn. +- **The "reset to the shipped colours" button never takes the active palette.** It receives the + shipped palette as a required parameter and reads no composition local, so it has no path to + the resolved one. An operator who sets text and surface to the same black cannot see any + other control, this one included, unless it refuses their palette. + - Preserve full callsign/category identity while applying base-call normalisation only to specifically defined features. -- Keep canonical worker-thread domain state separate from JavaFX UI projections. -- Preserve the established JavaFX WebView/Leaflet workaround that avoids problematic CSS 3D transforms unless the original rendering/flicker issue has been reproduced and the replacement is validated. +- Keep canonical worker-thread domain state separate from the row lists the user interface draws from. +- The station map is a Compose canvas that fetches its own tiles. The JavaFX WebView, the bundled Leaflet resources, the CSS-3D-transform workaround and the `TileProxyServer` were removed with JavaFX; offline DEM, terrain packages and the profile cache are unaffected and must stay that way. - Deliberate test data, comments and Easter eggs are preserved unless explicitly changed. ## Planned Technical Direction diff --git a/docs/superpowers/notes/2026-10-01-javafx-lebendbefund.md b/docs/superpowers/notes/2026-10-01-javafx-lebendbefund.md new file mode 100644 index 00000000..3d663e40 --- /dev/null +++ b/docs/superpowers/notes/2026-10-01-javafx-lebendbefund.md @@ -0,0 +1,670 @@ +# Lebendbefund: was im JavaFX-Aufbau von KST4Contest tatsächlich benutzt wird + +Grundlage für Teil 2 von `docs/superpowers/specs/2026-10-01-javafx-entfernen-design.md`. +Erhoben am 1. Oktober 2026 auf Linux, Branch `nextMajorRelease/version1_50`. + +> **Teil 4 abgeschlossen am 2026-10-03.** Etappe 4 und 5 der Spezifikation sind in einem +> Zug umgesetzt. `UiDispatcher` liegt jetzt auf dem AWT-Ereignisfaden (`AwtUiDispatcher`, 5 +> Vertragstests), `JavaFxUiDispatcher` ist gelöscht. Alle zehn `Alert`-Aufrufe sind +> Compose-Dialoge (`ComposeAlert`: `show`/`acknowledge`/`confirm`/`showWithLink`, modal über +> `ComposeDialog`, damit die vier blockierenden ihre `showAndWait`-Semantik behalten). +> `getHostServices().showDocument` → `ExternalDocuments` auf `java.awt.Desktop`, mit der +> Schema-Entscheidung Mail gegen Web, die JavaFX nicht brauchte. `javafx.stage.Screen` → +> `ScreenBounds` auf `GraphicsEnvironment`. Der Lebenszyklus ist frei: kein +> `extends Application`, kein `init`/`start(Stage)`/`stop`, kein `launch`; `main` liest die +> Kommandozeile selbst und ruft das neue `startRuntime()`, ein Abschalthaken ersetzt `stop()`. +> `ApplicationRuntimeLauncher`, `LayoutAutosave` und `GuiUtils` sind JavaFX-frei. +> **Bilanz:** Dateien mit `javafx.` unter `src/main` von 16 auf **11**, `javafx`-Importe in +> `Kst4ContestApplication` von 41 auf **19**, Datei von 5.117 auf 4.933 Zeilen. Build grün, +> **821 Tests, 0 Fehler** (Grundlinie 800 + 21 neue). +> +> **Zwei harte Lehren aus Teil 4:** +> +> 1. **Der grüne Build sah den Startabbruch nicht.** Der erste Start nach dem Wegfall von +> `launch()` starb mit `IllegalStateException: Toolkit not initialized` in +> `Kst4ContestApplication.` — über `javafx.scene.control.Control.`. Ursache: +> die Klasse hält noch **19 abgehängte JavaFX-Steuerelemente** als Wertbehälter +> (`txt_chatMessageUserInput` und Geschwister). Sie hängen in keiner Szene, aber das +> Erzeugen des ersten läuft durch `Control`s statischen Initialisierer, der das Toolkit +> braucht. Behelf: `startJavaFxToolkitForTheRemainingDetachedControls()` als erste Zeile in +> `main` (`Platform.startup`, `setImplicitExit(false)`). **Diese Methode fällt in Etappe 6 +> mit den 19 Steuerelementen** — sie ist ausdrücklich so dokumentiert. +> 2. **Zwei `Platform.runLater`-Stellen durften *nicht* auf den Dispatcher.** Ihr Zweck ist +> das Aufschieben über den laufenden Ereignisdurchlauf hinaus, und `runOnUi` führt auf dem +> UI-Faden sofort aus — genau der Fall dort. Sie liegen jetzt auf `EventQueue.invokeLater`: +> die Fokusübergabe nach dem Vorbelegen von `/cq` und das Zurücksetzen von +> `markOperatorChatMemberSelectionIntent`. Der Kommentar an der ersten Stelle hatte das +> vorausgesehen; wer ihn überliest, baut einen Fokusverlust und eine falsch zugeordnete +> Bedienerabsicht ein. +> +> Zusätzlich: `LayoutAutosave` benutzte `javafx.animation.PauseTransition`, was ein laufendes +> JavaFX-Toolkit braucht — jetzt `javax.swing.Timer`, und die Klasse nimmt die Schreibaktion +> als `Runnable` statt der `ChatPreferences` (deren Konstruktor ins Benutzerprofil schreibt +> und darum nicht testbar war). Erstmals mit Tests: vier, darunter „ein Stoß von 20 +> Ereignissen wird zu einem Schreibvorgang". **Offen (Etappe 6):** die 11 Restdateien, die 19 +> Steuerelemente, `org.openjfx` aus Build und Versionskatalog. +> Behoben in Etappe 4/5; der Plan ist nach seiner Ausführung entfernt worden, die +> Begründung steht in der Commit-Nachricht und hier. + +> **Etappe 6 abgeschlossen am 2026-10-04 — JavaFX ist raus.** Nachgewiesen, nicht +> geschlussfolgert: `grep -rl "javafx\." core/src/main app-desktop/src/main` ist leer, es +> gibt im ganzen Projekt keinen `import javafx` mehr, `:app-desktop:dependencies` zeigt +> JavaFX auf **keinem** der beiden Klassenpfade, der Build ist grün mit **849 Tests**, und +> die Anwendung läuft ohne JavaFX: Einstellungen gelesen, Datenbank verbunden, ON4KST +> verbunden, vollständige Benutzerliste, Nachrichten geparst, Frequenzerkennung — null +> Ausnahmen, kein `QuantumRenderer`-Faden. `Kst4ContestApplication`: 11.179 → **4.165** +> Zeilen. +> +> **Zwei Stellen waren lebend und mussten ersetzt werden, nicht gelöscht:** +> der 300-ms-Entpreller der Benutzerliste (`PauseTransition` → `CoalescingTrigger` auf +> `javax.swing.Timer`, fünf Tests) und `FxRosterBinding` → `RosterListBinding` +> (`ObservableList` → gewöhnliche Liste plus Rückruf; `SelectedStationMessagesFeed.push` +> nimmt ohnehin nur ein `List` und kopiert es). Beide waren vorher ungetestet. +> +> **Die Falle dieser Etappe**, und sie wäre ein lautlos falsch kategorisiertes Senden +> gewesen: `lastAutoPreparedCqTargetCallsign` und `-Category` sehen wie toter Schatten aus, +> werden aber von `resolveOutgoingChatCategory` gelesen, das Compose über +> `resolveOutgoingChatCategoryFromCompose` ruft. `ChatInputState` führt den vorbelegten +> Text selbst mit, aber **keine Kategorie** — dieser Zustand hat kein Compose-Gegenstück. +> Geschrieben wurde er nur von der Methode, die zu löschen war. Also an der Naht getrennt: +> `prepareCqTextForCallsign` → `rememberAutoPreparedCqTarget`, Kategoriebuchführung bleibt, +> Textfeld und Überschreibschutz fallen. +> +> **Zwei vorbestehende Defekte kamen dabei heraus und sind behoben:** +> (1) Niemand rief `refresh()` auf dem Compose-Spiegel der Kurztasten und Schnipsel — die +> Haken des Einstellungsfensters gingen auf den JavaFX-Knopfbau in `flwPane_textSnippets`, +> das seit dem Abklemmen `null` ist. Eine bearbeitete Kurztaste erreichte den Bediener erst +> nach einem Fensterneubau. (2) Das Schließen des Hauptfensters beendete die Anwendung +> nicht: `ComposeWindowHost` gab jedem Fenster Composes Vorgabe +> `onCloseRequest = ::exitApplication`, die nur das `application {}` dieses Fensters +> beendet — Fenster weg, Prozess lief mit offener Verbindung weiter. Von Marc gefunden, +> weil ein Tiling-Fenstermanager genau so schließt. Das Hauptfenster führt jetzt in +> `closeWindowEvent`. Mit demselben Griff kam heraus, dass die **Fenstergröße** gar nicht +> mehr gespeichert wurde — der Verzicht war mit „solange beide Fenster leben" begründet, +> und das zweite Fenster gibt es nicht mehr. +> +> **Namensfallen, an denen ein Löschen nach bloßem Namen scheitert:** `TimelineView` und +> `PathProfileChart` existierten doppelt, je einmal JavaFX und einmal Compose. Gelöscht +> wurde nur die Java-Fassung. `TimelineView.CandidateEvent` war ein reines Zwischen-DTO, +> das 1:1 in `TimelineCandidate` umkopiert wurde; der Erbauer baut jetzt direkt den +> Compose-Typ, vorher mit einem Test festgenagelt, weil drei der zehn Felder `Int` sind und +> eine Vertauschung lautlos durchgeht. Und `RosterMirror` war schon vergeben — die +> Compose-Fassung in `MainWindowState.kt`; die Java-Klasse heißt deshalb +> `RosterListBinding`. +> +> **`TableLayoutManager` bleibt**, auf `calculateInitialContentWidth` zusammengeschrumpft: +> sechs Compose-Dateien nennen die Klasse namentlich, wer dem Verweis folgt, soll die +> Regel finden und keine Lücke. **`MessageVariableResolverTest`** lag in `src/main/java` +> und wurde nie ausgeführt — verschoben, daher die Testzahl von 842 auf 848. + +> **Teil 4, Prüfung und Korrekturen vom 2026-10-04.** Die Abschlussprüfung durch einen +> frischen Prüfer fand **zwei Critical-Fehler, beide dieselbe Fehlerklasse** — und beide +> waren im grünen Build unsichtbar. Behoben in `72d35f84`; Build grün, **835 Tests**. +> +> **Die Fehlerklasse, die jeder künftige Umbau hier treffen wird: ein blockierendes Warten +> auf dem Ereignisfaden.** Seit der Dispatcher dort liegt, laufen alle Menüaktionen auf dem +> AWT-Ereignisfaden. Skikos `SwingDispatcher` stellt **jede** Fortsetzung von +> `application { }` über `SwingUtilities.invokeLater` zu und überschreibt +> `isDispatchNeeded` nicht — im Bytecode nachgeprüft. Wer auf diesem Faden auf etwas +> wartet, das nur als Ereignis auf diesem Faden vorankommt, verklemmt ohne Zeitlimit. +> +> 1. **`OperatorProfilePickerWindow`** wartete auf einem `CountDownLatch`. Menü → Profil +> wechseln fror die Anwendung dauerhaft ein. Jetzt ein modaler `ComposeDialog`: der +> blockiert über eine verschachtelte Ereignisschleife und zeichnet dabei weiter. +> 2. **`ComposeWindowHost.close()`** wartete mit `Thread.join`. Jeder Fensterschalter im +> Windows-Menü fror für das Zeitlimit ein und kehrte zurück, **während das Fenster noch +> als offen galt** — womit ein Profilwechsel das Fenster der toten Laufzeit hervorhob und +> das neue Profil ohne Einstellungsfenster, also ohne Connect-Knopf, dastand. Genau der +> Defekt, den das Javadoc derselben Klasse als behoben beschreibt. Jetzt eine +> `SecondaryLoop`, deren `exit()` über `invokeLater` gepostet wird, um das dokumentierte +> exit-vor-enter-Wettrennen zu schließen. +> +> **Eine dritte Lehre, die der Fix-Durchgang selbst erzeugt hat:** ein `ComposeDialog` ist +> eine Swing-Komponente um eine Skia-Fläche und **muss auf dem Ereignisfaden erzeugt +> werden**. Vom Hauptfaden aus erzeugt, bekommt skiko keinen GL-Kontext +> (`Can't wrap nullptr` → `RenderException: Cannot init graphic context`), der Dialog +> zeichnet nie, und ein modales Warten darauf endet nie. Drei von drei Startversuchen. +> Gefunden nur durch Starten der Anwendung und einen `jcmd Thread.print`; kein Test sah es. +> Dafür gibt es jetzt `openOnEventThread` und zwei Tests. **Merksatz: der grüne Build sagt +> über Fadenzugehörigkeit nichts.** +> +> **Knopfreihenfolge:** die JavaFX-`ButtonBar`-Reihenfolgen wurden gemessen, nicht erinnert — +> `LINUX = L_HE+UNYACBXIO_R`, `MAC_OS = L_HE+U+FBIX_NCYOA_R`, +> `WINDOWS = L_E+U+FBXI_YNOCAH_R`. Der Beenden-Dialog nutzte `ButtonType.YES`, der +> Profilwechsel `OK_DONE`, und die beiden ordnen auf Linux **gegenläufig**. `ComposeAlert` +> trägt deshalb die Knopfart und ordnet nach diesen Zeichenketten. Der Prüfer hatte hier +> aus dem Gedächtnis eine macOS-Reihenfolge für Linux behauptet und das nach dem Nachmessen +> zurückgezogen — beide Seiten irrten, die Messung entschied. +> +> **Zwei offene Entscheidungen für Marc**, bewusst nicht im Fix-Durchgang erledigt: die +> Dialoge haben die Warn-/Fehler-/Info-Symbole der JavaFX-`AlertType`s verloren (Symbolwahl +> ist Gestaltung, keine Fehlerbehebung), und die vier blockierenden Dialoge sind jetzt +> `APPLICATION_MODAL`, sperren also die Eingabe in den Compose-Fenstern, solange sie offen +> sind — was der toolkit-fremde JavaFX-`Alert` nicht tat. Ebenfalls unverifiziert: +> `ScreenBounds` auf einem skalierten Bildschirm (hier ein unskalierter, beide Quellen +> lieferten denselben Wert). + +> **Teil 4, Sondenergebnis vom 2026-10-03.** Ein modaler +> `androidx.compose.ui.awt.ComposeDialog` (Compose 1.8.2) hält seinen Aufrufer an **und** +> zeichnet sich dabei — gemessen von beiden Fäden: vom AWT-Ereignisfaden 1514 ms blockiert, +> komponiert; von einem Fremdfaden 1503 ms blockiert, komponiert. Damit ist die +> `showAndWait`-Semantik der vier blockierenden Dialoge erhaltbar, ohne den Ereignisfaden zu +> verklemmen. Das ist die Voraussetzung für den Dispatcher-Tausch: nach ihm laufen alle +> Menüaktionen über `ComposeMenuActions` auf dem Ereignisfaden, und das Muster von +> `OperatorProfilePickerWindow` (eigener Faden plus `CountDownLatch`) würde dort verklemmen, +> weil es genau den Faden blockiert, auf dem das neue Fenster zeichnen will. Der +> Einzelkonstruktor `ComposeDialog(Dialog.ModalityType)` existiert und wird benutzt. +> Behoben in Etappe 4/5; der Plan ist nach seiner Ausführung entfernt worden, die +> Begründung steht in der Commit-Nachricht und hier. + +> **Teil 3 abgeschlossen am 2026-10-02.** Der gesamte durchsetzte JavaFX-Aufbau in +> `Kst4ContestApplication` ist gelöscht; die Klasse ist von 11.179 auf ~5.100 Zeilen +> geschrumpft, der Durchlauf meldet `0 of 0 init methods`. Erledigt in Scheiben: die drei +> Statusindikatoren an ihrer Naht getrennt (S1), `initMenuBar` samt macOS-Menü gelöscht +> (S2), der tote `scn_ChatwindowMainScene`-`try`-Block aus `start()` entfernt und die +> lebenden Trigger (Sked-Reminder, Zeitleisten-Listener) herausgerettet (S3), die sieben +> Tabellen-Builder, der Info-Pane-Cluster und die Snippet-Kontextmenüs gelöscht/entflochten +> (S3b–S4), und zuletzt der tote `timelineView`, die Szenen-Theming-Maschinerie +> (`registerThemedScene`/`themedScenes`) und die tote CW-/Voice-Ausgabe samt +> `javafx.scene.media`-Importen (S6). Zwei Laufzeitfunde aus GUI-Abnahmen wurden behoben: +> ein NPE auf dem gelöschten `flwpne_StatusBar` in `updateStatusButton`, und die +> Compose-Menü-Regression — die 16 Menüaktionen hingen über `ComposeMenuActions` an den +> gelöschten JavaFX-`MenuItem`s und wurden auf eigene `menuAction…`-Methoden umgestellt +> (vorgezogen aus Etappe 5). Build nach jeder Scheibe grün, 800 Tests. **Offen (Etappe +> 4–6):** `UiDispatcher`-Tausch, Lebenszyklus (`extends Application`, die zehn Alerts), +> die Restdateien und das Entfernen von `org.openjfx` aus dem Build; in +> `Kst4ContestApplication` stehen noch ~41 `javafx`-Importe. + +> **Zweite Fassung.** Die erste kam aus einer Prüfung, die nur fragte „wer ruft diese +> Methode auf?". Eine Abschlussprüfung hat daran zwei kritische Fehler gefunden: zwei +> Blöcke, die als folgenlos löschbar geführt waren, speisen in Wahrheit die +> Compose-Oberfläche — die Nachrichten der ausgewählten Station und die Zeitleiste. +> Beide hätte Teil 2 gelöscht, ohne dass ein Test oder der Übersetzer etwas gemerkt +> hätte. Die Methode ist unten berichtigt; sie ist der eigentliche Inhalt dieses +> Dokuments. + +## Wie geprüft werden muss + +Drei Fragen pro Kandidat, nicht eine: + +1. **Wer ruft ihn?** Auch aus dem Compose-Pfad heraus — die Compose-Fenster rufen in + `Kst4ContestApplication` zurück, etwa über `focusChatMemberAndPrepareCq` bei + `:10720`, `:10884` und `:10916`. +2. **Was tut er innen?** Eine 200-Zeilen-Methode, die eine JavaFX-Tabelle baut, kann + mittendrin einen Listener anmelden, der in eine **Compose**-Tabelle schreibt. Genau + das war Fehler eins. +3. **Meldet er Controller-Listener an?** Die überleben die Oberfläche, die sie + angemeldet hat, und sind oft das Einzige, was ein Compose-Fenster speist. + +Frage 2 braucht einen **transitiven** Durchlauf, keinen einstufigen Grep. Das ist +bezahltes Lehrgeld: ein einstufiger Grep über die Methodenrümpfe fand zwei Fälle, die +Abschlussprüfung einen dritten, und erst der transitive fand den vierten. Ein Rumpf, +der sauber aussieht, kann eine Hilfsmethode rufen, die schreibt. + +Der Durchlauf: jede `init…`-Methode bis Tiefe 3 über ihre Aufrufziele verfolgen und auf +diese Bezeichner prüfen — + +``` +composeMainWindowState MainWindowHost SettingsWindow MonitorWindow UpdateWindow +StationMapWindow OperatorProfilePickerWindow replaceRows replaceSkeds +replaceCandidates DataTableState composeMemberListener +``` + +**Nicht** auf das Wort „compose" prüfen. Menüeinträge öffnen Compose-Fenster, indem sie +`SettingsWindow` und Geschwister rufen; das Wort kommt dort nicht vor. + +Der Durchlauf liegt als Skript daneben, damit der nächste Leser messen statt glauben +kann: + +```bash +python3 docs/superpowers/notes/javafx-compose-sweep.py +``` + +Am 1. Oktober 2026 meldete es **drei** der 18 `init…`-Methoden als Compose-erreichend. +Die vierte Zuführung — die Zeitleiste — sitzt in `start()`, ist keine `init…`-Methode +und wird vom Skript nicht erfasst. Wer die Liste `COMPOSE_TOKENS` im Skript nicht +pflegt, sobald ein neues Compose-Fenster dazukommt, bekommt eine Methode fälschlich als +sauber gemeldet. + + +Ergebnis: **vier** der 18 `init…`-Methoden erreichen Compose-Zustand — +`initFurtherInfoAbtCallsignMSGTable`, `initMenuBar`, +`initConnectionStateIndicatorButton` und (über `start()`, keine `init…`-Methode) die +Zeitleiste. Die übrigen 15 sind bis Tiefe 3 sauber. + +--- + +## initFurtherInfoAbtCallsignMSGTable — **zu entflechten** + +**Belege:** + +- Erreicht aus dem **Compose**-Pfad: `:10720` / `:10884` / `:10916` → + `focusChatMemberAndPrepareCq(member, false)` (`:2728`) → + `handleChatMemberSelectionChanged` (`:2770`) → + `generateFurtherInfoAbtSelectedCallsignBP` (`:2799`) → `:893`. +- Innen bei `:3400`–`:3409`: `selectedCallSignInfoMessageBinding` wird erzeugt, und sein + Listener schiebt in `composeMainWindowState.getSelectedStationMessages().replaceRows(...)` + — eine **Compose**-Tabelle, erzeugt bei `:10492`, übergeben bei `:10588`. +- Alle Schreiber von `selectedStationMessages` (`:319`, `:3405`, `:10659`, `:10866`) + laufen über diese Bindung. + +**Folgerung:** Wird die Methode gelöscht, bleibt `selectedCallSignInfoMessageBinding` +`null`, alle vier Zuführungen sind null-geprüft und tun still nichts, und die Tabelle +„Nachrichten der ausgewählten Station" im Compose-Hauptfenster bleibt für immer leer. +Der Build bleibt grün. Die Bindung muss **vorher** aus der Tabellenkonstruktion +herausgelöst werden. + +**Scheibe C erledigt am 2026-10-02.** Die Erzeugung sitzt jetzt in +`rebuildSelectedCallSignInfoMessageBinding()` ohne `TableView`-Bezug; +`initFurtherInfoAbtCallsignMSGTable` ruft sie nur noch vor dem `setItems`. Der Durchlauf meldet die +Methode weiterhin als Compose-erreichend, aber über die neue Hilfsmethode +(`-> rebuildSelectedCallSignInfoMessageBinding @:selectedStationMessagesFeed`), nicht +mehr über den Tabellen-Builder selbst. Damit kann die Tabelle in der nächsten Scheibe +fallen, ohne die Compose-Tabelle leerzuziehen. + +## `start()`, Zeilen 7356–9573 — **zu entflechten, kein toter Zweig** + +**Belege:** + +- 2.217 Zeilen, in denen toter Oberflächenaufbau und **lebende** Verdrahtung + durcheinanderliegen. +- `:7379` `timelineView = new TimelineView()` und `:7428` + `chatcontroller.getActiveSkeds().addListener(skeds -> updateTimelineVisuals())`. +- `updateTimelineVisuals` (`:4885`) steigt bei `:4886` sofort aus, wenn `timelineView` + `null` ist — und schiebt bei `:4914`–`:4919` in `composeMainWindowState.getTimeline()`: + Skeds, Kandidaten, Antennenazimut und Keulenbreite. +- Weitere lebende Anmeldungen im selben Rumpf: `:7431` `uiPulse()`, `:7446` + `getActualQTF()`. +- `:9565` ruft `openSettingsWindow()`. + +### Nachtrag nach Teil 2: das Ziel ist abgelöst, der Auslöser nicht + +Teil 2 hat `TimelineFeed` eingeführt und die Wache auf `timelineView` aus +`updateTimelineVisuals` entfernt. Das löst das **Ziel** der Zuführung vom +JavaFX-Aufbau. Die **Auslöser** liegen weiter in `start()`: + +| Stelle | Was | Status | +|---|---|---| +| `:6896`, `:6905` | `timelineView`-Breite/Höhe | **tot** — der Knoten wird nie gezeigt | +| `:6931` | `chatcontroller.getActiveSkeds().addListener(...)` | **lebend** | +| `:6935` | `chatcontroller.getScoreService().uiPulse().addListener(...)` | **lebend** | +| `:6951` | `getActualQTF().addListener(...)` — fasst auch `timelineView` an | **lebend, gemischt** | +| `:9073` | `Platform.runLater(this::updateTimelineVisuals)` | **lebend** — die Erstbefüllung | + +**Warnung für Teil 3:** `updateTimelineVisuals` hat ausschließlich Aufrufer innerhalb +von `start()` (6859–9075). Wer diesen Rumpf löscht, ohne die drei +Controller-Listener und die Erstbefüllung vorher umzuhängen, nimmt der +Compose-Zeitleiste jeden Anstoß — bei grünem Build und ohne Übersetzungsfehler, also +genau die Fehlerklasse, die dieses Dokument verhindern soll. Bei `:6951` muss +zusätzlich der `timelineView`-Zugriff herausfallen. + +### Und es ist mehr als die Zeitleiste + +Eine erste Fassung dieser Warnung nannte nur die vier Zeitleisten-Zeilen. Eine +Abschlussprüfung hat gezeigt, dass das zu eng ist. **In `start()` liegt nicht nur der +Anstoß, sondern auch die Zuführung selbst:** + +| Was | Wo | Folge beim Löschen von `start()` | +|---|---|---| +| Alle drei Zuführungen werden erzeugt | `:10137`–`:10141`, in `openComposeMainWindowIfRequested` (`:9919`), gerufen aus `start()` bei `:9049` | `timelineFeed`, `selectedStationMessagesFeed` und `connectionStateFeed` bleiben `null`; jeder `push` ist ein bewachtes Nichts. Zeitleiste, Nachrichtentabelle **und** Verbindungsanzeige werden leer | +| Auslöser der Nachrichten-Zuführung | der Listener in `initFurtherInfoAbtCallsignMSGTable` (`:3411`) samt der Bindung, die er beobachtet | die Nachrichtentabelle bekommt keinen Anstoß mehr | +| Auslöser der Zeitleiste | `:6931`, `:6935`, `:6951`, `:9073` | siehe oben | + +**Damit ist eine Behauptung aus dem Plan zu Teil 2 falsch.** Dort stand: „Nach diesem +Plan ist der tote Aufbau zum ersten Mal wirklich tot." Das gilt nicht. Teil 2 hat die +**Ziele** der Zuführungen abgelöst — sie haben Namen, Tests und einen einzigen +Schreibweg. Ihre **Erzeugung** und ihre **Auslöser** liegen weiter im Aufrufbaum von +`start()`. Teil 3 muss beides umhängen, bevor dort irgendetwas fällt; `start()` ist +nicht zu beschneiden, sondern Zeile für Zeile zu trennen — was dieses Dokument weiter +oben schon über `start()` sagt und was für die Zuführungen genauso gilt. + +Der Grund, warum das erst nachträglich auffiel: `openComposeMainWindowIfRequested` liest +sich wie Compose-Verdrahtung und ist es auch — sie hängt nur am falschen Aufrufer. + +**Folgerung:** Die Zeitleiste über dem Eingabefeld des **Compose**-Fensters hängt an +einem Objekt, das wie toter JavaFX-Aufbau aussieht. Ein Löschen des „toten Zweigs" +nimmt ihr Skeds, Kandidaten und Antennenrichtung — ohne Übersetzungsfehler und ohne +Testfehler. `start()` ist Zeile für Zeile zu trennen, nicht am Stück zu löschen. + +### Die empfohlene Form für Teil 3: die Erzeugung umhängen, nicht die Warnung lesen + +Diese Warnung ist ein Dokument, und ein Dokument schützt nur den, der es liest. Die +Abschlussprüfung hat die bessere Form benannt, und sie gehört hierher, damit Teil 3 +nicht erst darauf kommen muss: + +> Die drei Zuführungen dort erzeugen, wo `composeMainWindowState` **deklariert** wird, +> nicht dort, wo `start()` sie zufällig erreicht. + +Dann kann das Umhängen von `start()` die Zuführungen nicht mehr mit `null` +zurücklassen, weil ihr Leben nicht mehr an `start()` hängt. Die Garantie wird +strukturell statt dokumentiert. + +Das ist **Scheibe B von Teil 3**, nicht Teil 2 — dort wäre es ein Umbau ohne Auftrag. +Wer Scheibe B beginnt, fängt damit an. + +`FeedIsTheOnlyWriterTest` deckt diesen Fall ausdrücklich **nicht** ab: der Test prüft, +wer schreibt, nicht wann die Zuführung entsteht. Ein grüner Lauf ist hier kein +Freibrief. + +Inzwischen gibt es dafür `FeedLifetimeIsTiedToTheWindowTest`: er prüft, dass alle drei +Zuführungen in derselben Methode entstehen wie `composeMainWindowState`. Damit ist die +Kopplung strukturell und nicht mehr nur hier beschrieben. Die empfohlene Form oben +bleibt trotzdem die bessere Endgestalt — der Test hält den Zustand fest, er stellt ihn +nicht her. + +### Ein Aktualisieren, zwei Zustellungen — vorgefunden, nicht neu + +`applySelectedCallSignInfoFilter` (`:317`) und die Stationsauswahl (`:10380`) rufen beide +`selectedCallSignInfoMessageBinding.refresh()` **und** schieben anschließend in einem +`Platform.runLater` selbst nach. `refresh()` geht über `FxRosterBinding:75` nach +`applyNow`, ändert die Spiegelliste, und der Listener bei `:3410` schiebt dadurch schon. +Jeder Filterwechsel und jede Stationsauswahl ersetzt die Tabelle also **zweimal** mit +demselben Inhalt. + +Das ist geordnet und harmlos, aber es ist festzuhalten, weil es leicht falsch gelesen +wird: „ein `push` ist eine Zustellung" gilt für die Zuführungsklasse und **nicht** für +das System. Entstanden ist es nicht mit den Zuführungen — der Listener stand schon vor +`21c8e62a` dort, die Zuführung hat die Doppelung geerbt. Aufzulösen ist sie, wenn in +Teil 3 die Bindung aus dem JavaFX-Aufbau gelöst wird: dann fällt einer der beiden Wege +ohnehin weg. Vorher einen davon zu entfernen hieße raten, welcher bleibt. + +### „more" holt ein offenes Kandidatenfenster nicht nach vorn + +`ComposeWindowHost.show` kehrt bei `!open.compareAndSet(false, true)` zurück (`:106`). +Das JavaFX-Original erzeugte je Druck eine frische `Stage` und hob sie damit an. Wer +also zum Hauptfenster zurückklickt und erneut auf „more" drückt, sieht nichts +geschehen. + +**Es betraf nur das Kandidatenfenster — eine erste Fassung dieses Abschnitts behauptete +das Gegenteil.** `ComposeWindowHost` trägt zwar sechs Fenster, aber fünf davon sichern +die Stelle beim Aufruf ab und erreichen die frühe Rückkehr nie: + +| Fenster | Aufruf | erreicht `show()` bei offenem Fenster? | +|---|---|---| +| Einstellungen | `:5393`, `isOpen` → `close()` | nein | +| Monitor | `:5376`, dieselbe Form | nein | +| Karte | `:400`/`:406`, `toggle` bzw. `isShowing()` | nein | +| Update | `:10610`, einmal beim Start | nein | +| Hauptfenster | `:10185`, einmal | nein | +| **Kandidaten** | `:4772`, ungeprüft, nur öffnen, kein Umschaltweg | **ja** | + +Damit ist es **keine geerbte Eigenschaft des Hosts, sondern eine mit dieser Portierung +eingeführte Regression**. Dazu passt, dass `TopPriorityCandidatesWindow.isOpen` mit +`@JvmStatic` angelegt wurde und **keinen Aufrufer** hat: die Prüfung wurde gebaut und +nie angeschlossen. + +Die erste Fassung schrieb „betrifft alle sechs" und überzeichnete damit die Kosten der +Reparatur — und zwar gegenüber dem Betreiber, der genau danach entschieden hat. Die +Entscheidung wurde mit der berichtigten Lage noch einmal gestellt. + +**Behoben am 2026-10-01, nach erneuter Entscheidung des Betreibers, im Host.** `show` +holt ein offenes Fenster jetzt nach vorn, statt stillschweigend zurückzukehren. Die +Regel steckt in `raiseSteps`, getrennt von den AWT-Aufrufen, damit sie prüfbar ist: ein +minimiertes Fenster wird erst wiederhergestellt und dann angehoben — `toFront` auf einem +eingeklappten Fenster lässt es eingeklappt, also wäre das derselbe tote Knopf in anderer +Verkleidung — und ein nicht mehr anzeigbares Fenster wird in Ruhe gelassen, damit ein +Druck im Schließfenster nicht gegen das Schließen arbeitet. + +Im Host und nicht an der Aufrufstelle, obwohl heute nur ein Fenster davon profitiert: +die vier Geschwister sind wirkungslos abgesichert, und ein künftiges Fenster, das `show` +ungeprüft ruft, macht sonst denselben Fehler noch einmal. Ein Umschalter an der +Aufrufstelle wäre die Alternative gewesen, hätte aber ein anderes Verhalten ergeben — +das JavaFX-Original schloss beim zweiten Druck nicht, es erzeugte eine frische `Stage` +und holte das Fenster damit nach vorn. + +Was **nicht** geprüft ist: `toFront`. Nur das — und nicht, weil das Gerüst zu schwach +wäre, sondern weil das Ergebnis dem Fenstermanager gehört und aus der JVM gar nicht +beobachtbar ist. Es gibt kein „liege ich oben" zum Prüfen. + +Eine erste Fassung zählte hier drei ungeprüfte AWT-Aufrufe auf und hatte in genau der +Zeile einen Fehler, die sie sich zu prüfen erspart hatte: das Wiederherstellen schrieb +`Frame.NORMAL`, also eine Null, statt das Bit zu löschen. `extendedState` ist ein +Bitfeld; ein Fenster, das maximiert und dann minimiert wurde, trägt 7, und die Null +hätte es wiederhergestellt-klein zurückgegeben — eine Maximierung weggeworfen, um die +niemand gebeten hatte. Herausgelöst als `deiconifiedState(current)`, reine Arithmetik, +drei Prüfungen; die alte Fehlerform wird rot. + +Ein `requestFocus` stand ebenfalls in der ersten Fassung, ohne Beleg, dass es je etwas +bewirkt. `toFront` ist der dokumentierte Weg; `Component.requestFocus` auf einem Fenster +ignorieren die meisten Fenstermanager, und unter X11 entscheidet ohnehin die +Fokusdiebstahl-Sperre. Entfernt — zwei Schritte sind die ehrliche Regel. + +## initConnectionStateIndicatorButton — **zu entflechten** + +Vom transitiven Durchlauf gefunden; ein einstufiger Grep über den Rumpf übersieht ihn. + +**Belege:** + +- Der Rumpf (`:6180`–`:6198`) ist innen sauber, ruft aber bei `:6195` + `updateConnectionStateIndicator(...)`. +- Diese Methode (`:6200`) schreibt bei `:6217`–`:6219` + `composeMainWindowState.getSurroundings().setConnectionState(...)` und + `setConnectionDetail(...)` — den Verbindungszustand in der **Compose**-Statusleiste. +- Sie hat weitere, lebende Aufrufer außerhalb des toten Aufbaus: `:9844` und `:9871`. +- Danach fasst sie bei `:6224` ein JavaFX-Tooltip an (`tipConnectionStateIndicator`). + +**Folgerung:** Eine gemischte Methode wie `updateTimelineVisuals`. Wird +`initConnectionStateIndicatorButton` gelöscht, verschwindet das Tooltip-Objekt, das +`:6224` anfasst, während `:9844`/`:9871` weiter rufen. Der Compose-Schreibzugriff ist +vorher aus dem JavaFX-Teil herauszulösen. + +**Scheibe S1 erledigt am 2026-10-02.** `updateConnectionStateIndicator` ist an seiner +markierten Linie getrennt (Feed-Push und Log bleiben, der JavaFX-Indikator fällt); +`initConnectionStateIndicatorButton`, `initSkedWarnIndicatorButton` und +`initBandUpgradeIndicatorButton` sind gelöscht. Mitgefunden: +`showBlinkingSkedWarnIndicator`/`showBlinkingBandUpgradeIndicator` waren dieselbe Naht — JavaFX-Knopf plus +Compose-Notice-Push. Beide behalten nur den Compose-Push; die Blink-Timelines, die +`hide…`-Gegenstücke und die Knopf-/Tooltip-Felder sind weg. Die Compose-Notice regelt +ihr Ausblenden selbst. `menuConnectionStateMacOs`/`menuItemConnectionStateDetailMacOs` +bleiben noch (fallen mit `initMenuBar`, S2). + +## initMenuBar — **zu entflechten** + +**Belege:** + +- Zehn Compose-Berührungen innen (`:5863` `SettingsWindow`, `:5884`–`:5888` + `MonitorWindow`, und weitere): die Menüeinträge **öffnen** die Compose-Fenster. +- Installiert nur auf der Szene des Kandidatenfensters (`:4858`). + +**Folgerung:** Nicht löschen, sondern die Aktionen übernehmen. Der Abgleich ist unten +gemacht — und er fällt kleiner aus als erwartet. + +**Scheibe S2 erledigt am 2026-10-02.** `initMenuBar` und `installSharedSystemMenuBar` +(aufruferlos) sind gelöscht, mit ihnen das tote `Macros`-Menü, die zehn `Alert`-tragenden +Menü-Handler und die zwei macOS-Menüfelder `menuConnectionStateMacOs`/ +`menuItemConnectionStateDetailMacOs`. Der `start()`-Aufruf und die Menüleisten-Einhängung +fielen mit; `flwpne_StatusBar` bleibt (wird von `updateStatusButton` mitbenutzt, fällt in +S6). **Noch stehen geblieben:** die `menuItem…`-Felder und ihr `setDisable`-Update im +ON4KST-Connection-Callback — die Felder sind seit dem Wegfall von `initMenuBar` `null`, +die Aufrufe null-geprüft und wirkungslos; sie gehören zum toten Aufbau und werden in S6 +mit der Callback-Naht aufgeräumt. `macOsConnectionStateMenuTitle` und sein Test bleiben +bewusst (reine String-Funktion, macOS-Punkt der Spec, später zu klären). Der Durchlauf +meldet jetzt 1 of 10 — nur noch `initFurtherInfoAbtCallsignMSGTable` über die +rebuild-Hilfsmethode, die in S4 fällt. + +### Abgleich mit `MainMenuBar.kt` (Stand 2026-10-01) + +Die Leiste wird bei `:5546` zusammengesetzt: +`menubar.getMenus().addAll(fileMenu, optionsMenu, windowMenu, helpMenu);` — mit dem +Kommentar `// macromenu deleted`. + +| JavaFX-Eintrag | Aktion | In Compose? | +|---|---|---| +| File → Connect (Beschriftung dynamisch) | `connect` | ja (`state.connectLabel`) | +| File → Disconnect | `disconnect` | ja | +| File → Switch operator profile... | `showOperatorProfileSwitchDialog` | ja | +| File → Exit + disconnect | beenden | ja | +| Options → Set QRG as name in Chat (main category) | QRG als Name setzen | ja | +| Options → Show me as away in chat | Away/Back | ja (`state.awayMenuLabel`) | +| Options → Show options / hide options | Einstellungsfenster | ja (dynamische Beschriftung) | +| Windows → Hide/Show cluster / stranger QSOs | Monitorfenster | ja (dynamische Beschriftung) | +| Windows → hide options | Einstellungsfenster | **fehlt** — in Compose mit „Show options" zusammengelegt | +| Windows → Use dark mode design | Design | ja | +| Windows → Use default mode design | Design | ja | +| Windows → Show / hide station map | Kartenfenster | ja | +| Info → Donate for kst4Contest development via PayPal | PayPal | ja | +| Info → `_______________________` (`help3`) | keine | **fehlt** — reiner Trenner | +| Info → Visit DARC X08-Homepage | Browser | ja | +| Info → Donate for OV3T´s plane feed service | Browser | ja | +| Info → Donate for ON4KST Chatservers… | **keine** — `setOnAction` ist auskommentiert | **fehlt**, und tot | +| Info → Contact the author using default mail app | Mailprogramm | ja | +| Info → Join kst4Contest newsgroup | Browser | ja | +| Info → About… | Infofenster | ja | +| **macOS:** LINK-Menü mit Zustandsdetail (`:5553`) | nur Anzeige, `setDisable(true)` | **fehlt** | + +**Zu portieren:** nichts, was eine Aktion trägt. Die drei Lücken sind ein Trenner, ein +in Compose zusammengelegter Doppeleintrag und ein Eintrag, dessen Aktion seit +Längerem auskommentiert ist. + +**Nur macOS:** Das `LINK`-Menü samt `menuItemConnectionStateDetailMacOs` wird nur bei +`PlatformUtils.isMacOs()` eingehängt, zusammen mit `setUseSystemMenuBar(true)`. Es +zeigt den Verbindungszustand schreibgeschützt in der Systemmenüleiste. Compose hat +dafür keine Entsprechung; ob das auf einem Mac auffällt, ist auf Linux nicht +entscheidbar. + +**Tot, nicht fehlend:** Das Menü `Macros` (`:5361`–`:5370`) mit sechs Einträgen wird +gebaut, bekommt keine einzige Aktion und wird der Leiste **nie** hinzugefügt. Die +ursprünglichen Makro-Handler stehen bei `:3193` ff. auskommentiert. Mit `initMenuBar` +zu löschen, nicht zu portieren. + +## FxRosterBinding — Klasse **bleibt**, ein Feld ist löschbar + +**Belege:** + +- `chatMemberListBinding` (`:299`): `list()` hat **genau einen** Leser, `:2517` + `tbl_chatMemberTable.setItems(...)` — die nie gezeigte Tabelle. Mit ihr löschbar. +- `selectedCallSignInfoMessageBinding` (`:307`) ist dieselbe Klasse und **lebend** + (siehe oben). + +**Folgerung:** Das Feld `chatMemberListBinding` entfällt, die Klasse `FxRosterBinding` +nicht. Sie benutzt `ObservableList`/`FXCollections`; solange sie lebt, lebt dieser +JavaFX-Bezug. Ihr Ersatz ist eigene Arbeit in Teil 2. + +## registerThemedScene / `themedScenes` — **folgenlos löschbar**, mit dem Kandidatenfenster + +**Belege:** + +- Zwei Aufrufer: `:7554` (tote Hauptszene), `:4856` (Kandidatenfenster, lebend). +- `applyTheme` (`:6111`) durchläuft `themedScenes` **und** benachrichtigt jedes + Compose-Fenster getrennt über `applyDarkMode` (`:6122`–`:6126`). + +**Folgerung:** Die Compose-Themenumschaltung hängt nicht daran. + +## LayoutAutosave — **bleibt** + +**Belege:** + +- `requestLayoutSave()` hat **vierzehn** Aufrufer, nicht drei: `:1564`, `:7563`, + `:7571`, `:8280`, `:9461`, `:9495`, `:10442`, `:10605`, `:10615`, `:10625`, `:11017`, + `:11062`, `:11096`, `:11125`. Sieben davon liegen oberhalb `:10400`, also im + Compose-Bereich; `:10442` ist die `requestSave()`-Umsetzung des Breiten-Rückrufs, den + die **Compose**-Tabellen bekommen (`:10432`–`:10444`). + +**Warnung für Teil 2:** Eine frühere Fassung dieses Abschnitts zählte drei Aufrufer. +Wer danach aufräumt und `requestLayoutSave()` entfernt, weil „seine drei Aufrufer weg +sind", bricht sieben lebende Compose-Speicherungen. + +**Folgerung:** Speichert die Spaltenbreiten der Compose-Tabellen. Bleibt. Die drei +JavaFX-Bezüge in `LayoutAutosave.java` sind in Teil 2 gesondert zu prüfen. + +## Kandidatenfenster — **zu entflechten, und Sperrriegel der Etappe** + +**Belege:** + +- `showTopPriorityCandidatesWindow` (`:4806`) baut die einzige `Stage`, die dieser + Quelltext selbst erzeugt (`new Stage()` bei `:4810`, das einzige Vorkommen in der + Datei), gibt ihr eine `Scene` (`:4855`) und zeigt sie (`:4860`). +- **Nicht** die einzige JavaFX-Oberfläche, die erscheint: die zehn `Alert`-Dialoge + (`:476`, `:5756`, `:5777`, `:6040`, `:6693`, `:6741`, `:6794`, `:9755`, `:9787`, + `:9896`) bringen ihre Bühne selbst mit und sperren die Etappe genauso. +- Zwei Aufrufer: `:4706` (toter JavaFX-Knopf) und `:10707` aus dem **Compose**-Pfad. +- Trägt `registerThemedScene` (`:4856`) und `installSharedSystemMenuBar` (`:4858`). + +**Folgerung:** Solange es steht, kann keine JavaFX-Abhängigkeit fallen — aber es ist +nicht das Einzige, was sie hält; die zehn Alerts müssen mit. Es steht trotzdem zuerst, +weil es als einziges eine eigene Bühne, ein Thema und eine Menüleiste mitbringt. + +**Nicht geprüft:** macOS — und auf Linux auch **nicht prüfbar**: +`installSharedSystemMenuBar` steigt bei `:6075` sofort aus, wenn +`PlatformUtils.isMacOs()` falsch ist. Was dort sichtbar an der JavaFX-`MenuBar` hängt, +kann kein Lesen auf Linux beantworten; vor dem Entfernen auf einem Mac nachzuholen. + +--- + +## Ergebnis in einem Satz + +Von den 18 `init…`-Methoden sind 15 bis Tiefe 3 sauber und nach Prüfung ihrer Aufrufer +löschbar — vier davon haben gar keinen Aufrufer; **drei** erreichen die +Compose-Oberfläche und sind zu entflechten; dazu kommen `start()` selbst, die Klasse +`FxRosterBinding`, `LayoutAutosave`, das Kandidatenfenster und die zehn +`Alert`-Dialoge. „Toter Aufbau" ist deshalb die falsche Beschreibung: es ist +durchsetzter Aufbau. + +## Die `init…`-Methoden + +„Kein Aufrufer" heißt hier wirklich keiner: `getDeclaredMethod`, `getMethod(`, +`Class.forName` und `FXMLLoader` kommen in der Datei **null**mal vor — es gibt keine +reflektive oder FXML-Hintertür, über die eine der vier dennoch erreichbar wäre. + +| Methode | Zeile | ca. Zeilen | Aufrufer | erreicht Compose? | +|---|---|---|---|---| +| `initShortcutTable` | 4561 | 38 | **keiner** | nein | +| `initNotifyAtCallSignTable` | 5146 | 100 | **keiner** | nein | +| `initTextSnippetsTable` | 5248 | 46 | **keiner** | nein | +| `initWkdStnTable` | 5441 | 286 | **keiner** | nein | +| `initChatMemberTableContextMenu` | 3173 | 43 | 5314, 5315, 8017, 8433 | nein | +| `initBottomGlobalMessageTabPane` | 3577 | 23 | 8257 | nein | +| `initDXClusterTable` | 4156 | 181 | 3590 | nein | +| `initChatToOtherMSGTable` | 4339 | 220 | 3594 | nein | +| `initSelectedCallSignCompactControlsPane` | 3451 | 108 | 1521 | nein | +| `initChatGeneralMSGTable` | 3607 | 169 | 8162 | nein | +| `initChatprivateMSGTable` | 3778 | 376 | 8015 | nein | +| `initChatMemberTable` | 1824 | 852 | 8293 | nein | +| `initTopPriorityListPane` | 4671 | 44 | 9442 | nein | +| `initSkedWarnIndicatorButton` | 6161 | 17 | 7611 | nein | +| **`initConnectionStateIndicatorButton`** | 6180 | 18 | 7605 | **ja — über `:6195` → `:6217`** | +| `initBandUpgradeIndicatorButton` | 6361 | 16 | 7634 | nein | +| **`initFurtherInfoAbtCallsignMSGTable`** | 3218 | 213 | 893 | **ja — :3404** | +| **`initMenuBar`** | 5729 | 337 | 7599 | **ja — 10 Stellen** | + +## Reihenfolge für Teil 2 + +Nach jeder Scheibe `./gradlew clean build` — und bei jeder Scheibe, die etwas löscht, +vorher der Durchlauf aus „Wie geprüft werden muss". + +**Vorab, ohne Löschen:** + +- **A — Kandidatenfenster nach Compose.** Der Sperrriegel. Mit ihm fallen + `registerThemedScene` und `installSharedSystemMenuBar` als einzige lebende Nutzer. +- **B — Die Zeitleisten-Zuführung aus `start()` lösen.** `timelineView` und die + Listener bei `:7428`, `:7431`, `:7446` bekommen ein eigenes Zuhause, das nicht am + JavaFX-Aufbau hängt. Prüfbar: die Compose-Zeitleiste zeigt weiter Skeds und + Kandidaten. +- **C — `selectedCallSignInfoMessageBinding` aus `initFurtherInfoAbtCallsignMSGTable` + lösen.** Prüfbar: die Nachrichtentabelle der ausgewählten Station füllt sich noch. +- **D — Die Menüeinträge aus `initMenuBar` gegen `MainMenuBar.kt` abgleichen.** +- **E — Den Compose-Schreibzugriff aus `updateConnectionStateIndicator` lösen** + (`:6217`–`:6219`), damit `:9844`/`:9871` ihn weiter erreichen, wenn das + JavaFX-Tooltip fällt. Prüfbar: die Verbindungsanzeige in der Compose-Statusleiste + wechselt weiter. + +**Dann löschen, Blätter zuerst:** + +1. ~~Unreferenziert: `initShortcutTable`, `initNotifyAtCallSignTable`, + `initTextSnippetsTable`, `initWkdStnTable`~~ — **erledigt am 2026-10-01**, + 474 Zeilen, Suite unverändert bei 769 Tests. +2. `initDXClusterTable`, `initChatToOtherMSGTable`, dann + `initBottomGlobalMessageTabPane` — ~424 Zeilen. +3. `initFurtherInfoAbtCallsignMSGTable` (nach C) und + `initSelectedCallSignCompactControlsPane` — ~321 Zeilen. Vorher prüfen, ob die + Aufrufer `:893` und `:1521` nach C noch erreichbar sind. +4. `initChatGeneralMSGTable`, `initChatprivateMSGTable` — ~545 Zeilen. +5. `initChatMemberTable` (852) und `initChatMemberTableContextMenu` — größte Scheibe. +6. `initTopPriorityListPane` und die drei Statusknöpfe — ~95 Zeilen; + `initConnectionStateIndicatorButton` erst nach E. +7. `initMenuBar` (337) — nach A und D. +8. Der Rest von `start()`, Zeile für Zeile: was nicht in B übernommen wurde, die + `scn_ChatwindowMainScene` samt Listenern, `themedScenes`, `chatMemberListBinding` + und die tote CW-Ausgabe (`:6966` ff.). + +Erst danach sind `UiDispatcher`, Lebenszyklus, Dialoge und der Build an der Reihe. diff --git a/docs/superpowers/notes/javafx-compose-sweep.py b/docs/superpowers/notes/javafx-compose-sweep.py new file mode 100644 index 00000000..ca371d53 --- /dev/null +++ b/docs/superpowers/notes/javafx-compose-sweep.py @@ -0,0 +1,128 @@ +#!/usr/bin/env python3 +"""Which methods of Kst4ContestApplication can reach Compose state. + +The question this answers is "is this block of JavaFX construction safe to delete", +and it is harder than it looks. Three weaker versions of it were tried first, and +each missed something the next one found: + + - grepping a method body for the word "compose" misses menu handlers, which open + Compose windows by calling SettingsWindow and its siblings by name; + - grepping a method body for those names catches that, but misses a method whose + body is clean and which calls a helper that writes; + - only following the calls finds all four. + +So: follow the calls, and key on the names of the things that hold Compose state, +not on the word "compose". + +Usage, from the repository root: + + python3 docs/superpowers/notes/javafx-compose-sweep.py + +Prints one line per init… method. A method reported clean is clean to depth 3; the +depth is a limit, not a proof. +""" + +import re +import sys + +SOURCE = "app-desktop/src/main/java/kst4contest/view/Kst4ContestApplication.java" + +# Everything that is, holds, or opens Compose state. Extend this when a new Compose +# window or table appears; a name missing here is a method wrongly reported clean. +COMPOSE_TOKENS = ( + "composeMainWindowState", + "composeMemberListener", + "MainWindowHost", + "SettingsWindow", + "MonitorWindow", + "UpdateWindow", + "StationMapWindow", + "OperatorProfilePickerWindow", + "DataTableState", + "replaceRows", + "replaceSkeds", + "replaceCandidates", + # The feeds are the Compose sinks since part 2: the mixed init methods write + # Compose state through feed.push(...) rather than through a replace… call + # directly. Without these names the sweep reports those methods clean and would + # wave through a deletion that empties a Compose table with a green build. + "timelineFeed", + "selectedStationMessagesFeed", + "connectionStateFeed", +) + +MAX_DEPTH = 3 + +METHOD_DECLARATION = re.compile( + r"^\t(?:(?:public|private|protected|static|final|synchronized)\s+)+" + r"[\w<>,\[\]\. ]+\s+(\w+)\s*\(" +) +CALL = re.compile(r"\b(\w+)\s*\(") + + +def read_methods(lines): + """Maps a method name to the line ranges of its declarations.""" + methods = {} + for index, line in enumerate(lines): + match = METHOD_DECLARATION.match(line) + if not match or line.strip().startswith("//"): + continue + end = next( + (j + 1 for j in range(index + 1, len(lines)) if lines[j].startswith("\t}")), + len(lines), + ) + methods.setdefault(match.group(1), []).append((index + 1, end)) + return methods + + +def reaches_compose(name, methods, lines, seen=frozenset(), depth=0): + """The path by which `name` reaches Compose state, or None.""" + if depth > MAX_DEPTH or name in seen: + return None + seen = seen | {name} + + for start, end in methods.get(name, []): + for k in range(start - 1, end): + if lines[k].strip().startswith("//"): + continue + for token in COMPOSE_TOKENS: + if token in lines[k]: + return [f"{name} @{k + 1}:{token}"] + + for k in range(start - 1, end): + if lines[k].strip().startswith("//"): + continue + for callee in set(CALL.findall(lines[k])): + if callee in methods and callee != name: + path = reaches_compose(callee, methods, lines, seen, depth + 1) + if path: + return [f"{name} -> "] + path + return None + + +def main(): + try: + lines = open(SOURCE, encoding="utf-8").read().split("\n") + except OSError as unreadable: + print(f"cannot read {SOURCE}: {unreadable}", file=sys.stderr) + print("run this from the repository root", file=sys.stderr) + return 1 + + methods = read_methods(lines) + inits = sorted(n for n in methods if n.startswith("init") and n[4:5].isupper()) + + live = 0 + for name in inits: + path = reaches_compose(name, methods, lines) + if path: + live += 1 + print(f"{name:42s} REACHES COMPOSE: {''.join(path)}") + else: + print(f"{name:42s} clean to depth {MAX_DEPTH}") + + print(f"\n{live} of {len(inits)} init methods reach Compose state.") + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/docs/superpowers/specs/2026-09-25-compose-migration-design.md b/docs/superpowers/specs/2026-09-25-compose-migration-design.md new file mode 100644 index 00000000..251df570 --- /dev/null +++ b/docs/superpowers/specs/2026-09-25-compose-migration-design.md @@ -0,0 +1,490 @@ +# Konzept: Ablösung von JavaFX durch Compose Multiplatform + +> Status: Konzept, noch nicht umgesetzt. Zielrelease **1.50**. Alle Zeilenanker beziehen sich auf `nextMajorRelease/version1_50` und wurden gegen den Branch verifiziert (Stand 2026-09-25). + +## Ziel + +KST4Contest verlässt JavaFX und wird auf Compose Multiplatform umgestellt. Ergebnis ist eine wartbare, optisch aufgefrischte Desktop-Oberfläche bei **unverändertem Funktionsumfang**. Der fachliche Kern wird dabei von jeder UI-Technologie gelöst. + +Drei Treiber, gleichrangig: + +1. Die Oberfläche soll modern aussehen und sich modern anfühlen. +2. Der UI-Code soll wieder änderbar sein. +3. Die JavaFX-Abhängigkeit soll verschwinden. + +## Nicht-Ziele + +- **Kein UX-Neuentwurf.** 1.50 ist ein funktionsgleicher Port. Bedienabläufe, Fensteraufteilung und Funktionsumfang bleiben erhalten. Ein echter Neuentwurf der Bedienung ist Thema für 2.0. +- **Keine Mobile-App.** Die Modulgrenze wird so gezogen, dass ein späteres Mobile-Repo den Kern abgreifen könnte. Mehr nicht. Mobile ist in diesem Konzept Randbedingung, kein Lieferergebnis. +- **Keine Kotlin-Konvertierung des Kerns.** Siehe „Bestätigte Festlegungen". +- **Keine Protokolländerungen.** Kein Framing, kein Port, kein Transport, keine Normalisierung wird angefasst. + +## Ausgangslage + +Gemessen am Branchstand: + +| Kennzahl | Wert | +|---|---| +| Java gesamt | 61.572 Zeilen, 196 Dateien | +| Kotlin | 0 Dateien | +| Dateien mit direktem JavaFX-Bezug | 33 | +| `Kst4ContestApplication.java` | 13.564 Zeilen, 387 Methoden | +| davon reines JavaFX-Gerüst | 82 `call()`-Cell-Factories, 64 `changed()`-Listener, 77 `handle()`-Eventhandler | +| `Platform.runLater` / `ObservableList` | 51 / 93 Vorkommen | +| Tests | 43 Dateien, 148 Testmethoden | + +### Die JavaFX-Kopplung ist flacher als die Zahlen vermuten lassen + +- `ChatMember`: **ein** gekoppeltes Feld, `StringProperty frequency` (`ChatMember.java:42`, Zugriff `:510`, `:516`, Neuanlage `:616`). Der Rest der Klasse ist reines Java. +- `ChatPreferences`: fünf Properties (`actualQTF` `:228`, `MYQRGFirstCat` `:266`, `MYQRGSecondCat` `:268`, `notify_optionalFrequencyPrefix` `:296`, `notify_DXCSrv_SpottersCallSign` `:298`) und vier `ObservableList` für Listeneinstellungen (`:307`, `:308`, `:324`, `:325`). +- `ScoreService`: bereits sauber getrennt. Es existiert ein Snapshot-Modell, `topCandidatesFx` (`:45`, `:62`) ist explizit als FX-Projektion benannt, und der Klassenkommentar hält „No per-member Platform.runLater flooding" fest. +- `MessageBusManagementThread`: eine einzige Methodensignatur nimmt `ObservableList` entgegen (`:577`). +- `ChatController` ist der Brocken: sieben `ObservableList`-Felder (`:1164`, `:1742`, `:1759`, `:1768` mit der synchronisierten Hülle `:1775`, `:1776`, `:1777`, `:1817`) und eine `FilteredList`/`SortedList`-Pipeline (`:1745`, `:1749`, `:1751`, `:1756`, `:1772`, `:1773`). + +Die Klasse dokumentiert ihr eigenes Muster bereits: der Kommentar ab `ChatController.java:1783` begründet, warum eine threadsichere Map die primäre Quelle ist und die `ObservableList` nur die gebündelte Projektion. Die hier vorgeschlagene Trennung setzt das fort, statt es zu erfinden. + +### Die Karte hängt nur flach an Leaflet + +`MapHtmlResources.java` nutzt aus der Leaflet-API lediglich `L.map`, `L.tileLayer`, `L.marker`, `L.divIcon`, `L.circleMarker`, `L.polyline`, `L.polygon`, `L.rectangle`, `L.layerGroup`, `L.latLng` und `L.latLngBounds`. Geometrie (`PathGeometryUtils`), Gitterplanung (`MaidenheadGridRenderPlanner`), Kachelbeschaffung (`TileProxyServer`), Terrain und Pfadanalyse liegen bereits vollständig in Java. + +### Weitere betroffene Stellen + +- `javafx.scene.media` wird ausschließlich in `Kst4ContestApplication.java` benutzt (`:33`, `:34`, `:6599`, `:6900`). MP3-Wiedergabe läuft ohnehin schon über `jlayer` in `PlayAudioUtils`. +- Lombok ist in `pom.xml` als Abhängigkeit deklariert, wird aber in keiner Quelldatei verwendet. +- `src/main/java/module-info.java` bindet das Projekt an JPMS; `pom.xml` enthält eine Enforcer-Regel, die die jpackage-Modulliste gegen Drift absichert. + +## Bestätigte Festlegungen + +| Punkt | Entscheidung | +|---|---| +| Zielrelease | 1.50. Die Compose-Migration findet auf `nextMajorRelease/version1_50` statt; 1.50 wird das Compose-Release | +| Funktionsumfang | Funktionsgleicher Port. UX-Neuentwurf frühestens 2.0 | +| Sprache Kern | `core` bleibt **Java 21**. Kotlin nur dort, wo Compose es erzwingt | +| Sprache UI | Kotlin, `app-desktop` | +| Build | Maven wird durch **Gradle** ersetzt. Compose Multiplatform wird offiziell nur mit Gradle unterstützt, Desktop-Packaging inbegriffen | +| Modulsystem | `module-info.java` entfällt. Compose Multiplatform liefert keine echten JPMS-Module | +| Packaging | Etappe 1 behält den direkten `jpackage`-Aufruf, nur aus Gradle statt aus Maven. Die Umstellung auf `compose.desktop.nativeDistributions` erfolgt in Etappe 3, wenn Kotlin und Compose ohnehin einziehen. DMG-Drag-Layout, Icon-Erzeugung, Flatpak und AUR werden dabei nachgezogen | +| Karte | Native Compose-Canvas-Umsetzung. Kein eingebettetes Chromium (KCEF/JCEF) | +| God-Klasse | `Kst4ContestApplication` wird in Phase 1 **nicht** zerschnitten. Compose löscht den Widget-Code ohnehin | +| Mobile | Nur als Modulgrenze berücksichtigt, nicht umgesetzt | +| Lombok | Entfällt (ungenutzt) | +| Entwickler | Marc (DO5AMF) und Philipp (DN9APW). Kein Termin | + +## Zielarchitektur + +``` +kst4contest/ +├── core/ Java 21, KEIN JavaFX, KEIN Compose +│ ├── model/ ChatMember, ChatMessage, ChatPreferences, Band … +│ ├── controller/ ChatController, MessageBus, Score, Reachability … +│ ├── net/ ON4KST, AirScout, Win-Test, UCXLog, PSTRotator, DXCluster +│ ├── map/ Geometrie, Terrain, Kachel-Proxy, Pfadanalyse +│ ├── audio/ Wiedergabe hinter einem Interface +│ └── observe/ Beobachtungs-Abstraktion +└── app-desktop/ Kotlin + Compose Multiplatform + ├── ui/ Fenster, Panels, Tabellen, Dialoge + ├── state/ UI-Zustand, Projektionen aus core + └── map/ Compose-Canvas-Karte +``` + +`core` hängt von keiner UI-Technologie ab. Das ist die Grenze, an der parallel gearbeitet werden kann, und dieselbe Grenze, die ein späteres Mobile-Repo abgreifen würde. + +### Das Paket `core/observe` + +Bewusst minimal. Kein Reaktiv-Framework, keine Bibliothek. + +- **`ObservableValue`** — `T get()`, `void addListener(Consumer)`, `void removeListener(Consumer)`. +- **`MutableValue extends ObservableValue`** — zusätzlich `void set(T)`. +- **`ObservableRoster`** — **snapshotbasiert**: `List snapshot()` liefert eine unveränderliche Liste; Listener erhalten die neue Liste. Es gibt **kein** inkrementelles Änderungsprotokoll. Das passt zum Neuzeichnungsmodell von Compose und ist ohne UI testbar. +- **`UiDispatcher`** — `void runOnUi(Runnable)` und `boolean isUiThread()`. + +`UiDispatcher` ist der Schlüssel der gesamten Umstellung. In Phase 1 wird er von `Platform::runLater` und `Platform::isFxApplicationThread` implementiert, in Phase 2 vom Compose-Main-Dispatcher. Die Invariante aus `AGENTS.md` bleibt dabei wortgleich gültig: Worker-Threads mutieren keine UI-gebundenen Sammlungen, UI-sichtbare Änderungen laufen über den Dispatcher. + +### Was aus der JavaFX-Pipeline wird + +`FilteredList` und `SortedList` werden zu einer **reinen Funktion** in `core`: aus Mitgliederliste, Filterprädikaten und Komparator entsteht eine unveränderliche Ergebnisliste. Die Stationslisten-Logik wird damit erstmals ohne laufende UI testbar. Das ist der wesentliche fachliche Gewinn von Phase 1. + +Die vorhandene Bündelung und Entprellung (`flushPendingChatMessagesToUi`, das Coalescing der Mitgliederliste) **bleibt erhalten**. Sie ist Leistungsschutz bei mehreren tausend ON4KST-Nutzern, kein JavaFX-Beiwerk. + +## Etappen + +Jede Etappe ist für sich abgeschlossen, lieferbar und bekommt einen eigenen Umsetzungsplan. + +### Etappe 1 — Gradle, zwei Module, JPMS entfernen, Packaging + +**Ziel:** Die unveränderte JavaFX-Anwendung baut, testet und paketiert unter Gradle. + +**Umfang** + +- Gradle-Wrapper ersetzt `mvnw`/`mvnw.cmd`. +- Aufteilung in die Module `core` und `app-desktop`; in dieser Etappe enthält `app-desktop` noch die JavaFX-Oberfläche. +- **`core` darf in dieser Etappe noch von JavaFX abhängen.** `ChatController`, `ChatMember`, `ChatPreferences` und `ScoreService` benutzen es; Etappe 2 entfernt die Abhängigkeit. Etappe 1 bleibt damit eine reine Build-Umstellung ohne fachliche Änderung. +- Paketnamen und `import`-Anweisungen ändern sich nicht. Gradle-Module erzwingen keine Paketumbenennung; die Aufteilung ist ein Verschieben von Verzeichnissen. +- `src/main/java/module-info.java` wird entfernt; die Enforcer-Regel zur jpackage-Modulliste in `pom.xml` entfällt mit ihr. +- SpotBugs- und PMD-Regelsätze wandern mit; `pmd-ruleset.xml` bleibt unverändert gültig. +- Lombok wird aus den Abhängigkeiten entfernt. +- Packaging für Windows, Linux und macOS ruft `jpackage` weiterhin direkt auf, künftig aus einer Gradle-Aufgabe. Das DMG-Drag-Layout, die Icon-Erzeugung, Flatpak und AUR bleiben inhaltlich unverändert; nur die Herkunft der Eingabedateien wechselt von `target/dist-libs` auf `app-desktop/build/dist-libs`. +- Die Projektversion wandert nach `gradle.properties`. Zehn Stellen in fünf Workflows und zwei PKGBUILDs lesen sie heute aus `pom.xml` und müssen umgestellt werden, bevor `pom.xml` entfällt. +- Die GitHub-Workflows unter `.github/` werden auf Gradle umgestellt. + +**Abnahmekriterium:** Alle 148 vorhandenen Tests laufen unter Gradle. Auf allen drei Plattformen entsteht ein installierbares Paket, das sich wie das bisherige verhält. Stable-, Beta- und Nightly-Strecke funktionieren unverändert. + +### Etappe 2 — `core` von JavaFX befreien + +**Ziel:** `core` compiliert ohne JavaFX auf dem Klassenpfad. Die JavaFX-Oberfläche läuft unverändert und beweist, dass die Schnittstelle trägt. + +**Umfang** + +- `core/observe` entsteht wie oben beschrieben. +- `ChatMember.frequency` wird von `StringProperty` auf `MutableValue` umgestellt (`ChatMember.java:42`, `:510`, `:516`, `:616`). +- Die fünf Properties und vier `ObservableList` in `ChatPreferences` werden auf `MutableValue` beziehungsweise `ObservableRoster` umgestellt. +- Die sieben `ObservableList`-Felder in `ChatController` werden zu `ObservableRoster`; die `FilteredList`/`SortedList`-Pipeline wird durch die reine Filter-/Sortierfunktion ersetzt. +- `ScoreService` gibt seinen Snapshot über `ObservableRoster` heraus statt über `topCandidatesFx`; `Platform.runLater` wird durch `UiDispatcher` ersetzt. +- `MessageBusManagementThread.checkListForChatMemberIndexByCallSign` (`:577`) nimmt eine `List` statt `ObservableList`. +- Audio wandert nach `core/audio` hinter ein Interface. `javafx.scene.media` (`Kst4ContestApplication.java:33`, `:34`, `:6599`, `:6900`) entfällt; MP3 über `jlayer`, WAV über `javax.sound.sampled`. +- `app-desktop` stellt die JavaFX-Implementierung von `UiDispatcher` bereit und adaptiert `ObservableRoster` auf `ObservableList` für die bestehenden `TableView`. + +**Absicherung:** Jede herausgelöste Einheit bekommt **vorher** einen Test, der das heutige Verhalten festschreibt — insbesondere Filterung und Sortierung der Stationsliste, die heute in `FilteredList`/`SortedList` steckt und nicht testbar ist. + +**Abnahmekriterium:** `core` hat keine JavaFX-Abhängigkeit mehr. Die Anwendung verhält sich unverändert: Stationsliste, Chat-Tabs, Prioritäten, Skeds, Cluster, Worked-Zustand, Profilwechsel. + +### Etappe 3 — `DataTable` und Einstellungsfenster in Compose + +**Ziel:** Das erste Compose-Fenster ist im Produkt. + +**Umfang** + +Der wesentliche Baustein dieser Etappe ist eine wiederverwendbare **`DataTable`**-Komponente. Compose kennt kein `TableView`, und die Anwendung hat fünf Tabellen: `TableView`, `TableView`, `TableView`, `TableView` und die Top-Prioritätenliste. Alle brauchen dasselbe: + +- Spaltenbreiten mit stabilen Tabellen- und Spalten-IDs, wie sie `preferences.xml` Version 7 bereits kennt; +- Sortierung nach Spalte; +- Zeilenauswahl und Kontextmenü; +- Zeilen- und Zell-Styling, heute `PrivateMessageRowStyleResolver`, `MessageTextTableCell`, `TruncatedTextTableCell`, `TruncatedTextTooltipSupport`. + +Umgesetzt als `LazyColumn` mit eigener Kopfzeile. Wird diese Komponente gut, ist der Rest der Portierung Fleißarbeit; wird sie schlecht, zieht sich das durch die gesamte Anwendung. + +Mit dieser Etappe ziehen Kotlin und das Compose-Gradle-Plugin ein. Das Packaging wird dabei von den direkten `jpackage`-Aufrufen auf `compose.desktop.nativeDistributions` umgestellt — der Zeitpunkt ist hier richtig, weil JavaFX dann nicht mehr über `jlink` gebündelt werden muss. + +Danach das Einstellungsfenster mit seinen zwölf Reitern: Station, Log synch, TRX synch, Airscout, Notification, Shortcuts, Macros, Beacon, Messagehandling, Workedstn database, GUI, Profiles. Es ist in sich abgeschlossen, hat wenig Domänenkopplung und eignet sich deshalb als Lernstück. + +**Abnahmekriterium:** Das Einstellungsfenster ist vollständig in Compose, alle zwölf Reiter sind funktionsgleich, und geänderte Einstellungen landen unverändert in `preferences.xml`. + +> Nachzuschärfen nach Etappe 2: der genaue Zuschnitt der `DataTable`-Schnittstelle. Er hängt davon ab, wie sich `ObservableRoster` in der Praxis anfühlt. + +### Etappe 4 — Update-Fenster und Monitor-Fenster + +**Ziel:** Die zwei letzten Nebenfenster portiert; die Muster aus Etappe 3 sind an +Live-Daten bestätigt. + +**Umfang zurechtgerückt nach Etappe 3b.** Die Spezifikation nannte hier ursprünglich +vier Dinge. Zwei sind bereits erledigt und entfallen: + +| ursprünglich genannt | Stand | +|---|---| +| `OperatorProfilePickerDialog` | in Etappe 3a nach Compose portiert | +| `OperatorProfileSettingsPane` | gelöscht, ersetzt durch `ProfilesTab` (Etappe 3b) | +| Update-Fenster | offen, `Kst4ContestApplication.java:9458` | +| Monitor-Fenster für Cluster und QSOs | offen, `:9396` | + +- Das **Update-Fenster** ist das einfachere: ein Textfeld, ein Fortschritt, zwei + Knöpfe. Es prüft vor allem, ob ein Compose-Fenster aus einem Hintergrundfaden + heraus sauber auf- und zugeht. +- Das **Monitor-Fenster** ist der eigentliche Prüfstein: es belastet die `DataTable` + erstmals mit **Live-Daten**. Genau dort saßen in Etappe 2 die Sortier- und + Fokusfehler, und zwar nicht in der Tabelle selbst, sondern in der Kopplung + zwischen Roster und Anzeige. + +Die Layout-IDs für das Monitor-Fenster bleiben von denen des Hauptfensters getrennt, +wie in `PROJECT_CONTEXT.md` festgelegt. + +**Abnahmekriterium:** Beide Fenster sind funktionsgleich. Fenstergrößen, Positionen +und Spaltenbreiten werden unverändert entprellt gespeichert und beim Herunterfahren +geschrieben. Das Monitor-Fenster hält eine Stunde Dauerlast aus dem Simulator aus, +ohne dass die Auswahl springt oder die Sortierung kippt. + +> Nach Etappe 3b gelernt und hier anzuwenden: Ein Bedienelement, das an einem Wert +> hängt, der kein Compose-Zustand ist, zeichnet sich nicht neu. Bei Live-Daten fällt +> das nicht als „reagiert nicht" auf, sondern als veraltete Anzeige — schwerer zu +> bemerken und schlimmer in der Wirkung. + +### Etappe 5 — Hauptfenster + +**Ziel:** JavaFX wird nur noch für die Karte benötigt. + +**Umfang** + +- Stationsliste mit Filterleiste und Prioritätenspalten. +- Die drei Chat-Reiter „Public messages", „DXCluster messages", „QSO of the other". +- Der Info-Bereich zur ausgewählten Station (`generateFurtherInfoAbtSelectedCallsignBP`, `Kst4ContestApplication.java:707`) samt seinem vertikalen `SplitPane` und dessen gespeicherten Divider-Positionen. +- Die Top-Prioritätenliste (`initTopPriorityListPane`, `:4416`). +- Die Statusleiste mit ihren Indikatoren: Sked-Warnung (`:5868`), Verbindungszustand (`:5887`), Band-Upgrade (`:6045`). +- `TimelineView`. +- Menüleiste, einschließlich der macOS-Systemmenüleiste. + +**Profilwechsel:** Der heutige Mechanismus reißt die Laufzeit ab und baut eine **neue** `Kst4ContestApplication`-Instanz auf, weil viele Bedienelemente inline initialisierte Instanzfelder sind. Dieser Grund entfällt in Compose — der Zustand hängt nicht mehr an Feldern einer Riesenklasse. Der Wechsel wird zum Austausch des Zustandsobjekts. `shutdownRuntime()` bleibt trotzdem verantwortlich für alles, was eine Verbindung überdauert: ON4KST-Supervisor, Sked-Erinnerung, Reachability-Executor, PSTRotator-Wiederholung, Kachel-Proxy, Zeitgeber. `ApplicationConstants.sessionRuntimeUniqueId` wird weiterhin nicht neu erzeugt. + +**Abnahmekriterium:** Das Hauptfenster ist funktionsgleich. Der Profilwechsel im laufenden Betrieb funktioniert, ohne Listener doppelt zu registrieren und ohne Ressourcen zu halten. + +> Nachzuschärfen nach Etappe 4: ob `Platform.setImplicitExit(false)` und `ApplicationRuntimeLauncher.exitApplication()` in der Compose-Fassung noch eine Entsprechung brauchen. + +### Etappe 6 — Karte und Entfernung von JavaFX + +**Ziel:** 1.50. Keine JavaFX-Abhängigkeit mehr im Projekt. + +**Umfang** + +Die Karte wird als Compose-Canvas neu umgesetzt: + +- Web-Mercator-Projektion, Zoomstufen und Schwenken wie bisher; +- Kacheln über den bestehenden `TileProxyServer`; +- Marker, Linien, Polygone, Rechtecke und Kreismarker direkt gezeichnet, entsprechend der heutigen flachen Leaflet-Nutzung; +- Maidenhead-Gitter über den bestehenden `MaidenheadGridRenderPlanner`; +- Pfaddarstellung und Geländeprofil (`PathProfileChart`) als Compose-Zeichnung; +- bildschirmbasiertes Clustering als Vorschalt-Schritt vor dem Zeichnen. `GUIstationMapClusteringEnabled` bleibt eine Layout-Einstellung unterhalb `guiOptions` mit Vorgabewert `true`. + +`MapHtmlResources`, `StationMapBridge` und die JavaScript-Brücke entfallen ersatzlos. `StationMapView` wird zur Compose-Komponente. + +Zum Abschluss werden die JavaFX-Abhängigkeiten aus dem Build entfernt und `opens kst4contest.view.map to javafx.web` verliert seinen Gegenstand. + +**Eine Abhängigkeit, die hier zerbricht.** `JavaFxStylesheet.derive` ruft heute +`com.sun.javafx.util.Utils.deriveColor` über Reflexion auf, weil eine Nachbildung in +Etappe 3b nachweislich falsch war: die Helligkeit, von der JavaFX ableitet, ist nicht +der HSB-Wert, sondern `0.3R + 0.59G + 0.11B`, und der positive Zweig folgte keiner der +naheliegenden Formeln. Mit dem Entfernen von JavaFX greift die Rückfallnäherung — und +die ist messbar daneben. **Vor dem Entfernen** muss `derive` durch eine eigene, +gegen JavaFX gepinnte Umsetzung ersetzt werden, sonst verschieben sich alle +abgeleiteten Farben still: die Fensterfläche und die Innenfläche jedes Eingabefelds. + +**Abnahmekriterium:** Die Karte zeigt dieselben Informationen wie die Leaflet-Fassung. Offline-DEM, Terrain-Pakete und der Profil-Cache funktionieren unverändert. Im Projekt existiert keine JavaFX-Abhängigkeit mehr. + +> Nachzuschärfen nach Etappe 5: Leistungsverhalten des Canvas bei mehreren tausend Markern. Falls das Zeichnen nicht trägt, ist eine Vorabaggregation der Marker im Kern der Ausweg. + +### Etappe 7 — Compose-Oberflächentests + +**Ziel:** Die Zeichenebene bekommt ein Netz. Die Fehlerklasse, die in Etappe 3b +ausschließlich durch Hinsehen gefunden wurde, fällt künftig im Bau auf. + +**Warum am Ende** + +Die Oberfläche ändert sich durch Etappe 4 bis 6 weiter. Tests, die heute gegen die +Fenster aus Etappe 3b geschrieben würden, wären dreimal neu zu schreiben. Die +Beweislage wird jetzt festgehalten, die Tests entstehen, wenn die Flächen stehen. + +**Beweislage: was in Etappe 3b kein Test gesehen hat** + +Sämtliche folgenden Fehler standen gleichzeitig mit einem grünen Bau aus 382 +Testfällen im Zweig. Keiner davon zeichnet, deshalb sah keiner etwas. + +| Klasse | Erscheinung in Etappe 3b | +|---|---| +| Ein Bedienelement hängt an einem nicht beobachtbaren Wert und zeichnet sich nicht neu | Jeder Tastendruck in den Einstellungen wurde durchgeschrieben und nicht angezeigt; die Auswahl im Profil-Reiter wanderte nicht mit; die abgewählte Listenzeile behielt ihren Akzentrahmen | +| Ein Layout schneidet ab, statt umzubrechen | Der Reiterstreifen schnitt „Workedstn database" mitten im Wort ab; die Knopfleiste quetschte „Disconnect & close Chat" zu einer 540px hohen Farbsäule | +| Inhalt ist höher als das Fenster und unerreichbar | Der Reiterinhalt endete mitten im Formular, ohne Hinweis, dass mehr folgt | +| Farben stammen nicht aus der Stilvorlage | Die Fensterfläche nahm `-fx-base` statt `derive(-fx-base, 26.4%)`; der Akzent war Material-Violett statt des Grüns aus `.text-field .text` | + +**Umfang** + +- `org.jetbrains.compose.ui:ui-test-desktop` als Testabhängigkeit, benutzt über + `runComposeUiTest { }`. **Keine** JUnit-4-Brücke: das Projekt bleibt auf Jupiter, + und `runComposeUiTest` ist aus einem gewöhnlichen `@Test` heraus aufrufbar. Die + Funktion ist als `@ExperimentalTestApi` gekennzeichnet; die Einwilligung wird an + einer Stelle gebündelt und begründet. +- Je ein Rückfalltest für die vier Klassen oben, geschrieben gegen die dann + aktuellen Fenster. +- Die beiden Abdeckungsnetze aus Etappe 3b bleiben bestehen. Sie prüfen + **Text** — dass ein Setzer irgendwo aufgerufen wird. Diese Tests prüfen + **Verhalten** — dass der Wert auf dem Schirm ankommt. Das eine ersetzt das andere + nicht. + +**Abnahmekriterium** + +Für jede der vier Klassen wird der ursprüngliche Fehler **absichtlich wieder +eingebaut**, und der zugehörige Test muss fehlschlagen. Eine Prüfsammlung, die den +Fehler nicht fängt, für den sie geschrieben wurde, ist wertlos; das ist die einzige +Abnahme, die hier etwas aussagt. + +> Zu klären vor Beginn: ob die Tests ohne Bildschirm laufen. Skiko zeichnet in einer +> Softwarefassung, aber das ist für diesen Bau nicht erprobt. Falls sie einen +> Bildschirm brauchen, laufen sie in der CI unter Xvfb oder gar nicht — dann wären +> sie nur lokal etwas wert, und das gehört vorher entschieden, nicht nachher +> festgestellt. + +### Etappe 8 — Farben anpassbar machen + +**Ziel:** Der Operateur bestimmt die Farben seines Clients, ohne Dateien im +Installationsverzeichnis anzufassen. + +**Ausgangslage, die dafür spricht** + +Die halbe Voraussetzung ist bereits da, nur nicht verdrahtet: + +- `ApplicationFileUtils.copyResourceIfRequired` legt beim Start Kopien von + `KST4ContestDefaultDay.css` und `KST4ContestDefaultEvening.css` im + Anwendungsverzeichnis ab. +- **Gelesen wird diese Kopie nie.** `applyThemeStylesheet` übergibt den blanken + Dateinamen an `Scene.getStylesheets()`, und JavaFX löst relative Namen gegen den + Klassenpfad auf. Wer seine Kopie bearbeitet, sieht keinerlei Wirkung. +- `JavaFxStylesheet` liest aus demselben Grund die Klassenpfad-Ressource: solange + JavaFX die Kopie ignoriert, würde ein Compose-Fenster, das sie liest, als einziges + anders aussehen. + +**Umfang** + +- Die Kopie im Profilverzeichnis wird zur maßgeblichen Quelle. Ab Etappe 6 gibt es + kein JavaFX mehr, das dagegenhält — vorher muss beides dieselbe Datei lesen. +- Die Palette wird **pro Profil** gehalten. Ein Profil ist heute schon der Träger für + Einstellungen und Layout; Farben gehören in dieselbe Schublade. +- Eine Oberfläche zum Anpassen im Einstellungsfenster: die Handvoll Rollen, die + `JavaFxPalette` bereits benennt — Fläche, Feldinneres, Text, Akzent, Trennlinie — + statt eines freien CSS-Editors. Zurücksetzen auf die Auslieferung gehört dazu. +- Ein Kontrastwächter. Eine frei gewählte Textfarbe auf einer frei gewählten Fläche + kann unlesbar werden; die Oberfläche muss das sagen, bevor sie es speichert. + +**Abnahmekriterium:** Eine geänderte Palette überlebt den Neustart, gilt für alle +Fenster gleichzeitig und ist pro Profil verschieden. Das Zurücksetzen stellt exakt die +ausgelieferten Farben her. + +> Setzt Etappe 6 voraus, nicht wegen der Karte, sondern wegen `derive`: solange die +> Ableitung an JavaFX hängt, ist die Palette nicht frei wählbar, ohne dass dieselbe +> Rechnung in Compose nachgebaut ist. Siehe den Hinweis in Etappe 6. + +### Etappe 9 — Mehrsprachigkeit + +**Ziel:** Die Oberfläche spricht die Sprache des Operateurs. Deutsch und Englisch zum +Start. + +**Umfang** + +Grob 232 sichtbare Zeichenketten in den Compose-Quellen und rund 492 im verbliebenen +Java-Teil — die Zahl schrumpft mit jeder Etappe, weshalb diese Arbeit ans Ende gehört. + +**Die eigentliche Schwierigkeit ist nicht das Übersetzen, sondern die Abgrenzung.** +Drei Sorten Text liegen heute nebeneinander im Quelltext und sehen gleich aus: + +| Sorte | Beispiele | übersetzen? | +|---|---|---| +| Oberflächentext | „Save settings", „Active bands", „Callsign" | **ja** | +| Protokolltext | `/AWAY`, `/BACK`, `/CQ `, `SETNAME`, `MYQRG` | **nein, niemals** — das geht an den ON4KST-Server | +| Funkerkürzel | „Pse Sked?", „qrv 144.300", „tnx om, 73" | **nein** — das geht an andere Funker und ist international | + +Ein übersetzter Protokollbefehl bricht die Verbindung, ein übersetztes Funkerkürzel +macht den Operateur unverständlich. Beides fällt in keinem Test auf und erst im +Contest, also unter Zeitdruck. + +- Vor dem Herausziehen wird jede Zeichenkette einer der drei Sorten zugeordnet, und + die Zuordnung wird festgehalten — nicht im Kopf des Übersetzenden. +- Die Vorgabewerte in `ChatPreferences` (Beacon-Vorlagen, Antworttexte, Kurztasten) + sind Funkertext und bleiben, wie sie sind. Sie stehen zudem in der gespeicherten + XML jedes Operateurs; sie zu übersetzen würde bestehende Profile ändern. +- Ressourcenbündel pro Sprache, Auswahl im GUI-Reiter, Vorgabe aus der Systemsprache + mit Rückfall auf Englisch. + +**Abnahmekriterium:** Die Oberfläche lässt sich umschalten und bleibt nach Neustart +umgeschaltet. **Kein einziger an den Server oder an andere Funker gehender Text +ändert sich mit der Sprache** — das ist gegen die Protokoll-Zeichenketten und die +`ChatPreferences`-Vorgabewerte zu prüfen, nicht durch Hinsehen. + +## Invarianten — was unverändert bleiben muss + +Diese Punkte sind in `AGENTS.md` und `PROJECT_CONTEXT.md` festgelegt und werden von der Umstellung nicht berührt. + +**Chat-Identität** + +- Vollständiges sichtbares Rufzeichen plus Kategorie bildet die Identität eines Chat-Teilnehmers. +- Basisruf-Normalisierung nur für explizit basisrufweite Funktionen. +- Worked-Zustand wird über Suffixvarianten desselben Basisrufs geteilt. +- Suffixe werden nicht global als Band, Kategorie oder Frequenz gedeutet. + +**Bänder und Verfügbarkeit** + +- Kategorien 2 und 3 sind die Hauptkategorien; unerwartete Werte müssen sicher fehlschlagen. +- `NOT-QRV` hat Vorrang vor positiven Band-Hinweisen. +- Fehlende Frequenz-, QRB- oder QTF-Werte bleiben unbekannt. `null` bedeutet nicht verfügbar, nicht null. +- Kein stilles Zurückfallen auf feste 144 MHz. + +**Externe Schnittstellen** + +- CR/LF-Framing, XML-Framing, Ports und Transporte bleiben unverändert. +- Die lokale DX-Cluster-Ausgabe behält ihre feste 75-Zeichen-Zeile, das DX-Rufzeichen ab Spalte 27, den 30-Zeichen-Kommentar ab Spalte 40 und die UTC-Zeit ab Spalte 71, gefolgt von zwei BEL und CRLF. +- Unerwartete Eingaben beenden keinen Verarbeitungs- oder UI-Thread. + +**Persistenz** + +- `preferences.xml` bleibt in Version 7, einschließlich der verwalteten Spaltenbreiten unterhalb `guiOptions` und der Regel, dass Elternspalten ihre Breite aus den Blattspalten ableiten. +- Selektives Schreiben aktualisiert die Datei auf der Platte, bewahrt unbekannte XML-Knoten und schreibt keine unbestätigten funktionalen Einstellungen. **Save Settings** bleibt der vollständige Schreiber. +- Vollständige und selektive Schreibvorgänge sind synchronisiert und ersetzen `preferences.xml` atomar. +- Operator-Profile behalten ihr Verhalten: Wurzelprofil flach, weitere Profile unter `profiles//`, `profiles.xml` wird verzögert angelegt, die Registrierung speichert niemals einen Pfad, ein neues Profil bekommt eine **leere** Datenbank. +- Das SQLite-Schema und die Worked-Semantik samt Dreitagesablauf bleiben unverändert. +- Simplelogfile-Verhalten bleibt unverändert, einschließlich des minütlichen Lesens und der Tatsache, dass daraus abgeleiteter Worked-Zustand nicht in SQLite landet. + +**Quelltext-Konventionen** + +- Kommentare und Javadoc ausschließlich auf Englisch. +- Log-, Protokoll- und API-Literale in ihrer kanonischen Form. +- Kommunikation mit Marc auf Deutsch; Commit-Nachrichten knapp auf Englisch. + +## Risiken + +| Risiko | Bewertung | Umgang | +|---|---|---| +| `DataTable` wird der Engpass | hoch | Etappe 3 baut sie zuerst und belastet sie in Etappe 4 mit Live-Daten, bevor das Hauptfenster davon abhängt | +| Packaging auf drei Plattformen neu | hoch | Etappe 1 macht das zuerst, mit unveränderter JavaFX-App als Vergleichsmaßstab | +| Canvas-Leistung bei vielen Markern | mittel | Ausweg ist Vorabaggregation im Kern; wird in Etappe 6 gemessen, nicht angenommen | +| Compose-Erfahrung fehlt bei beiden Entwicklern | mittel | Das Einstellungsfenster als erstes Lernstück ist bewusst ungefährlich gewählt | +| Funktionsgleichheit ist schwer nachweisbar | mittel | Vergleich Fenster für Fenster gegen die noch laufende JavaFX-Fassung; Protokoll und Persistenz sind durch `core`-Tests gedeckt | +| 1.50 verschiebt sich erheblich | angenommen | Bewusste Entscheidung. Kein Termin gesetzt | +| **JavaFX und Compose können auf macOS nicht koexistieren** | **eingetreten** | Am 28.09.2026 auf einem Mac nachgewiesen. Siehe den Abschnitt darunter; noch nicht entschieden, wie damit umgegangen wird | + +## Eingetretenes Risiko: macOS trägt die Koexistenz nicht + +Am 28.09.2026 auf einem Mac (macOS 27, arm64, Temurin 21) festgestellt: Übersetzen und +die vollständige Testreihe laufen dort sauber — **660 Testfälle, keine Fehler**, genau wie +auf Linux. Sobald aber ein Compose-Fenster geöffnet wird, hängt die Anwendung. + +Thread-Abzug eines hängenden Starts: + +``` +main → wartet in Application.launch (JavaFX besitzt den Haupt-Runloop) +JavaFX Application Thread → wartet in OperatorProfilePickerWindow.showAndSelect +operator-profile-picker → hängt in sun.lwawt.macosx.LWCToolkit.initAppkit +``` + +Kein AWT-, AppKit- oder Skiko-Thread existiert. Auf macOS muss AppKit auf Thread 0 +laufen; JavaFX nimmt diesen Runloop mit `Application.launch` in Besitz und gibt ihn nie +her, also wartet `initAppkit` auf einen Hauptthread, der nie wieder zuhört. X11 und +Wayland kennen diese Einschränkung nicht — deshalb ist es vier Etappen lang nicht +aufgefallen. + +Der Profilwähler ist nur der Auslöser, weil er zuerst dran ist. Einstellungsfenster, +Monitor, Update-Fenster und Hauptfenster benutzen denselben `ComposeWindowHost`. + +**Das trifft das Verfahren dieser Spezifikation im Kern:** der Vergleich Fenster für +Fenster gegen die laufende JavaFX-Fassung — der Umgang mit dem Risiko +„Funktionsgleichheit ist schwer nachweisbar" — setzt Koexistenz voraus, und die gibt es +auf macOS nicht. + +Drei Wege: + +1. **Startreihenfolge umdrehen.** AWT/Compose besitzt den Hauptthread, JavaFX wird + eingebettet gestartet (`Platform.startup` statt `Application.launch`, ggf. mit + `-Djavafx.embed.singleThread=true`). Wirkt sofort und für den Rest der Migration, + fasst aber den Anwendungsstart an und betrifft damit auch Linux. Als eigene Etappe + nach 5c zu führen, nicht hinein: sonst sind zwei riskante Umbauten gleichzeitig offen. +2. **macOS bis zum Ende zurückstellen.** Das Problem verschwindet mit JavaFX. Kostet + nichts, aber bis dahin ist auf macOS nichts zu testen — und Etappe 1 hat Packaging für + drei Plattformen ausdrücklich zuerst gemacht, um genau das zu vermeiden. +3. **Compose-Fenster auf macOS abschalten.** Arbeit, die später wieder herausfliegt. + + +## Offene Punkte + +Diese Fragen werden bewusst erst beantwortet, wenn die vorangehende Etappe Erfahrung geliefert hat. Sie blockieren Etappe 1 und 2 nicht. + +1. Genauer Zuschnitt der `DataTable`-Schnittstelle — nach Etappe 2. +2. Ob `Platform.setImplicitExit(false)` in Compose eine Entsprechung braucht — nach Etappe 4. +3. Aggregationsstrategie für Kartenmarker, falls das Canvas-Zeichnen nicht trägt — nach Etappe 5. +4. Ob das Geländeprofil als eigene Compose-Zeichnung oder über eine Diagrammbibliothek entsteht — nach Etappe 5. +5. Ob die Compose-Oberflächentests ohne Bildschirm laufen — vor Etappe 7. +6. Welcher der drei Wege beim macOS-Befund gegangen wird — zu entscheiden, bevor Etappe 6 + JavaFX entfernt, denn Weg 1 wäre danach umsonst gebaut. +6. Ob die Farbpalette pro Profil oder pro Installation gilt — vor Etappe 8. diff --git a/docs/superpowers/specs/2026-10-01-javafx-entfernen-design.md b/docs/superpowers/specs/2026-10-01-javafx-entfernen-design.md new file mode 100644 index 00000000..8ed0e652 --- /dev/null +++ b/docs/superpowers/specs/2026-10-01-javafx-entfernen-design.md @@ -0,0 +1,286 @@ +# Entwurf — JavaFX aus KST4Contest entfernen + +Vertieft: `docs/superpowers/specs/2026-09-25-compose-migration-design.md`, Etappe 6, +zweite Hälfte („Entfernung von JavaFX"). + +Die erste Hälfte — die Karte als Compose-Canvas — ist umgesetzt und abgenommen +(Plan entfernt nach der Ausführung). Dieser Entwurf +behandelt ausschließlich, was danach noch zwischen dem Projekt und einem Build ohne +`org.openjfx` steht. + +## Ziel + +Release 1.50 ohne jede JavaFX-Abhängigkeit. Erfolg ist nachprüfbar: + +- `grep -rl "javafx\." core/src/main app-desktop/src/main` liefert nichts. +- Der `org.openjfx`-Block ist aus `app-desktop/build.gradle.kts` und + `gradle/libs.versions.toml` entfernt. +- `./gradlew clean build` bleibt grün (Stand heute: 766 Tests, 0 Fehler). +- Die Anwendung verhält sich unverändert: Ton, Dialoge, Farben, Fenstergrößen. +- Offline-DEM, Terrain-Pakete und der Profil-Cache funktionieren unverändert + (Abnahmekriterium der übergeordneten Spezifikation). + +## Der Befund, der die Etappe umkrempelt + +Die naheliegende Lesart — „11.655 Zeilen `Kst4ContestApplication` nach Compose +portieren" — ist falsch. + +**Das JavaFX-Hauptfenster wird bei jedem Start vollständig aufgebaut und nie +angezeigt.** `primaryStage.setScene(...)` und `primaryStage.show()` sind beide +auskommentiert (`Kst4ContestApplication.java:9508`, `:9517`). Angezeigt wird +`MainWindowHost.show(...)` (`:10667`), also Compose. Die Szene +`scn_ChatwindowMainScene` wird gebaut (`:7548`), thematisiert und mit +Größen-Listenern versehen, aber an keine Bühne gehängt. + +Der Aufbau läuft trotzdem: 93 `new TableView` / `new TableColumn`, Kontextmenüs, +Tastaturhandler. Das kostet Startzeit und hält Listener, ohne je sichtbar zu werden. + +Ein zweiter Irrweg, den dieser Entwurf ausräumt: die **CW-Tonausgabe** sieht nach +einem harten Blocker aus, weil `Kst4ContestApplication` `javafx.scene.media.Media` +und `MediaPlayer` benutzt und 91 MP3-Dateien im Projekt liegen. Diese Kopie ist tot — +`playCWLauncher` bei `:6966` ruft niemand. Die **lebende** Ausgabe sitzt in +`core/src/main/java/kst4contest/utils/PlayAudioUtils.java:182`, wird aus +`MessageBusManagementThread.java:1105` gerufen und spielt über JLayer +(`javazoom.jl.player.Player`). Kein JavaFX, keine Ersatzentscheidung, keine neue +Abhängigkeit. + +## Die lebende JavaFX-Fläche + +| Was | Wo | Ersatz | +|---|---|---| +| Anwendungs-Lebenszyklus | `extends Application`, `launch(args)` (`:9806`), `start(Stage)` (`:7356`) | Compose-Anwendung aus einem einfachen `main` | +| UI-Thread-Zustellung | `JavaFxUiDispatcher` → `Platform.runLater` | AWT-Ereignisfaden | +| Dialoge | 10 × `new Alert(...)` | eigene Compose-Fenster über `ComposeWindowHost` | +| Farbableitung | **bereits erledigt** — siehe Korrektur unten | — | +| Fensterrahmen | `Screen` (Startgröße), Anwendungssymbol | Compose / AWT | +| Kandidatenfenster | eigene `Scene` + `stage.show()` (`:4855`–`:4860`), geöffnet aus dem **Compose**-Pfad (`:10707`) | Compose-Fenster | +| Systemmenüleiste | `installSharedSystemMenuBar(candidatesScene)` (`:4858`), `initMenuBar()` (`:5729`) | hängt am Kandidatenfenster, siehe Etappe 1 | +| Roster-Spiegel | `FxRosterBinding` nutzt `ObservableList`/`FXCollections` | **Status ungeklärt — siehe Etappe 1** | + +Dateien mit JavaFX-Importen unter `src/main`, nach Größe: + +``` +11655 Kst4ContestApplication.java 49 Importe + 1777 StationMapView.java 20 + 1161 PathProfileChart.java 4 + 480 StationMapBridge.java 5 + 376 TimelineView.java 11 + 353 JavaFxStylesheet.kt 1 + 326 MessageTextTableCell.java 11 + 280 TableLayoutManager.java 9 + 136 ComposeMenuActions.java 1 + 129 FxRosterBinding.java 2 + 123 GuiUtils.java 4 + 110 MessageVariableResolverTest.java 1 (Testdatei im main-Quellbaum) + 109 TruncatedTextTableCell.java 4 + 106 ApplicationRuntimeLauncher.java 2 + 50 LayoutAutosave.java 3 + 31 JavaFxUiDispatcher.java 1 +``` + +## Der Dreh- und Angelpunkt + +`core` kennt JavaFX nicht. Es kennt die Schnittstelle `UiDispatcher`, und +`JavaFxUiDispatcher` ist die einzige Umsetzung, die sie an den JavaFX-Faden bindet. + +**Diese 31 Zeilen sind der Hebel.** Wird die Zustellung auf den AWT-Ereignisfaden +umgestellt — dort läuft Compose Desktop ohnehin —, fällt die Thread-Kopplung zwischen +`core` und JavaFX in einem Stück. Lebenszyklus, Dialoge und Fensterrahmen hängen +daran, nicht umgekehrt. + +Der Vertrag bleibt derselbe: `runOnUi` stellt zu und führt sofort aus, wenn es bereits +auf dem UI-Faden läuft; `isUiThread` beantwortet dieselbe Frage; eine geworfene +Ausnahme darf den Faden nicht reißen. Diese drei Punkte sind testbar, und genau das +macht den Austausch beherrschbar. + +## Vorgehen: erst löschen, dann umhängen + +Abgewogen wurden drei Wege. + +**Erst umhängen, dann löschen** wurde verworfen: der Eingriff am Lebenszyklus fände +genau dann statt, wenn die Datei am unübersichtlichsten ist. Das Nebenwirkungsrisiko +wäre dort am höchsten, wo es am schlechtesten zu sehen ist. + +**Zweiter Einstiegspunkt daneben**, umschaltbar, wurde verworfen: zwei Lebenszyklen in +einem Prozess mit globalem Zustand (`ApplicationRuntimeLauncher`, Profilwechsel), und +der Schalter wird selbst zur Sache, die gepflegt und getestet werden muss. + +**Gewählt: erst löschen, dann umhängen.** Der tote Aufbau ist das Volumen und zugleich +das Risikoärmste. Danach steht eine kleine, lesbare Datei, und erst darin die +schwierige Operation. + +## Etappen + +### 1 — Feststellen, was lebt + +Keine Löschung. Ergebnis ist eine belegte Liste. + +Zu klären ist für jeden Teil des nie gezeigten Aufbaus, ob er Nebenwirkungen hat, auf +die der laufende Betrieb angewiesen ist. Drei Verdachtsfälle sind benannt: + +- **`FxRosterBinding`** (`chatMemberListBinding`, erzeugt bei `:2513`, genullt bei + `:6877`). Es spiegelt den Roster in eine `ObservableList`. Speist es noch etwas, das + die Compose-Oberfläche liest, oder nur die tote Tabelle? +- **`registerThemedScene`** — drei Aufrufe. Hängt die Themenumschaltung der + Compose-Fenster daran? +- **`LayoutAutosave`** (`:7420`) — schreibt es Layoutwerte, die auch die + Compose-Fenster benutzen? + +Dazu die veralteten Begründungen, die beim Lesen auffallen: der Kommentar bei +`:10446` rechtfertigt eigene Spalten-IDs damit, dass „beide Fenster auf dem Bildschirm +sind". Das stimmt seit dem Abklemmen nicht mehr. + +**Abnahme:** eine Liste, die jeden Block des toten Aufbaus einem von zwei Töpfen +zuordnet — „folgenlos löschbar" oder „zu entflechten", letzteres mit der Stelle, die +davon abhängt. + +### 2 — Toten Aufbau löschen + +In Scheiben, jede für sich gebaut und geprüft. Eine Scheibe ist ein zusammenhängender +Block: die Stationstabelle, die Nachrichtentabellen, die Kontextmenüs, die +Filterleiste, die Szene samt Listenern. + +Mit fällt die tote CW-Ausgabe (`:6966` ff., `musicList`, `mediaPlayer`) und damit der +Import von `javafx.scene.media`. Die 91 MP3-Dateien in `core/src/main/resources` +**bleiben** — sie gehören der lebenden Ausgabe in `PlayAudioUtils`. + +**Abnahme:** `./gradlew clean build` grün nach jeder Scheibe; die Anwendung startet und +verhält sich unverändert; `Kst4ContestApplication` ist auf die lebende Fläche +zusammengeschrumpft. + +### 3 — Den `derive`-Pin einfrieren + +**Korrektur gegenüber der ersten Fassung dieses Entwurfs.** Dort stand, `derive` rufe +JavaFX über Reflexion und müsse ersetzt werden. Das ist falsch, und die übergeordnete +Spezifikation ist an dieser Stelle inzwischen veraltet: `JavaFxStylesheet.derive` +(`JavaFxStylesheet.kt:131` ff.) ist eine vollständige, JavaFX-freie Umsetzung. Das +einzige Vorkommen von „javafx" in der Datei steht in einem Kommentar, der noch die +alte Reflexionsfassung beschreibt. + +Mehr noch: die Umsetzung ist bereits gegen echtes JavaFX gepinnt. +`JavaFxStylesheetTest.kt:165`–`:170` ruft `com.sun.javafx.util.Utils.deriveColor` per +Reflexion **im Test** und prüft, dass beide Fassungen übereinstimmen (`:48`–`:50`). +Die Reflexion sitzt also dort, wo sie hingehört. + +Was bleibt, ist klein und trotzdem zeitkritisch: **dieser Vergleich hört auf zu +funktionieren, sobald JavaFX weg ist.** Der Test fiele dann stillschweigend auf die +Prüfung gegen sich selbst zurück. Die von JavaFX gelieferten Werte müssen vorher als +Daten eingecheckt werden, damit der Pin das Entfernen überlebt. + +Der veraltete Kommentar bei `:116`–`:129` wird mitkorrigiert. + +Zur Einordnung: die übergeordnete Spezifikation hält fest, dass eine freihändige +Nachbildung in Etappe 3b nachweislich falsch war: die Helligkeit, von der JavaFX +ableitet, ist nicht der HSB-Wert, sondern `0.3R + 0.59G + 0.11B`, und der positive +Zweig folgte keiner naheliegenden Formel. + +Vorgehen: solange JavaFX im Prozess ist, die Paare, die der Test heute zur Laufzeit +von `deriveColor` holt, über den benutzten Wertebereich erzeugen und als Testdaten +einchecken. Der Test vergleicht danach gegen diese Daten. + +**Abnahme:** die von JavaFX gelieferten Werte liegen als eingecheckte Daten vor; der +Test prüft `derive` gegen diese Daten und nicht mehr gegen einen Reflexionsaufruf; er +bleibt grün, wenn JavaFX nicht auf dem Klassenpfad ist. + +### 4 — `UiDispatcher` umhängen + +`JavaFxUiDispatcher` → eine Umsetzung auf dem AWT-Ereignisfaden. + +**Abnahme:** Tests decken Zustellung von einem Fremdfaden, sofortige Ausführung auf +dem UI-Faden, korrekte Thread-Erkennung und ab, dass eine geworfene Ausnahme den Faden +nicht reißt. Die Anwendung läuft unverändert. + +Dies ist die risikoreichste Etappe: `core` stellt über diese Schnittstelle **jede** +UI-sichtbare Änderung zu. Deshalb steht sie hinter dem Aufräumen und vor dem +Lebenszyklus. + +### 5 — Lebenszyklus, Dialoge, Rahmen + +- `Kst4ContestApplication extends Application` und `launch(args)` weichen einem + einfachen `main`, das die Compose-Anwendung startet. +- Die zehn `Alert`-Aufrufe werden eigene Compose-Fenster über `ComposeWindowHost`, + modal, wo sie es heute sind: die Bestätigungen liefern eine Antwort, die den + weiteren Ablauf steuert, und müssen weiter blockieren. +- `Screen` für die Startgröße und das Anwendungssymbol gehen an Compose beziehungsweise + AWT. +- Das **Kandidatenfenster** (`:4855`–`:4860`) wird ein Compose-Fenster. Es ist die + einzige JavaFX-Bühne, die tatsächlich erscheint, und sie wird aus dem Compose-Pfad + geöffnet (`:10707`): der „more"-Knopf neben den Prioritätsknöpfen. Solange es steht, + kann keine JavaFX-Abhängigkeit fallen. + +**Abnahme:** die Anwendung startet ohne JavaFX-Bühne; jeder der zehn Dialoge erscheint +an derselben Stelle im Ablauf wie bisher und mit derselben Wirkung auf den Ablauf. + +### 6 — Reste löschen und den Build befreien + +- `StationMapView.java`, `StationMapBridge.java`, `MapHtmlResources.java` und die + Leaflet-Ressourcen unter `app-desktop/src/main/resources/web/leaflet/`. +- `PathProfileChart.java` und `TimelineView.java` — Compose-Gegenstücke existieren. +- `MessageTextTableCell.java`, `TruncatedTextTableCell.java` — kein Compose-Nutzer. +- `JavaFxUiDispatcher.java` — fällt in jedem Fall, sein Ersatz entsteht in Etappe 4. +- `FxRosterBinding.java`, `GuiUtils.java`, `LayoutAutosave.java`, soweit Etappe 1 sie + als entbehrlich ausweist. +- `MessageVariableResolverTest.java` liegt im **main**-Quellbaum und gehört nach + `src/test`. +- `app-desktop/build.gradle.kts` Zeilen 3, 9–11 und 19; `gradle/libs.versions.toml` + Zeilen 2–3 und 28. + +**Eine Falle:** `TableLayoutManager.java` sieht genauso tot aus, wird aber von sechs +Compose-Dateien benutzt. Er muss seine JavaFX-Importe verlieren, nicht gelöscht werden. + +`TileProxyServer` in `core` verliert mit `StationMapView` seinen einzigen Nutzer. Er +war eine Antwort auf TLS-Probleme der JavaFX-WebView in AppImage- und +Flatpak-Verpackung; der Compose-Canvas holt seine Kacheln selbst. Mit entfernen. + +**Abnahme:** die drei Prüfungen aus dem Abschnitt „Ziel". + +## Prüfung + +Das Netz, auf das diese Etappe sich stützt, ist seit heute belastbar: `./gradlew clean +build` ist grün (766 Tests, 0 Fehler), erstmals seit dem 30. September. Jede +Rotfärbung während dieser Arbeit ist damit ein Signal und kein Rauschen. + +Dazu kommen: + +- die gepinnte `derive`-Tabelle (Etappe 3), +- echte Tests für den neuen Dispatcher (Etappe 4), +- die Compose-Layouttests aus der Kartenetappe, die die Fenster von 900×600 bis 1×1 px + abdecken, +- nach jeder Löschscheibe ein Start der Anwendung, weil kein Test beantwortet, ob ein + entfernter Listener gefehlt hat. + +## Was unverändert bleibt + +- Die Fachlogik in `core` und sämtliche Protokollformate. +- Die **Schnittstelle** `UiDispatcher`; nur ihre Umsetzung wird getauscht. +- Die Invarianten aus `AGENTS.md`: `ObservableRoster` ist der Speicher und die Listen + sind Spiegel; kein Worker-Faden fasst UI-Sammlungen an; Zoom, Auswahl, Fokus, + Sortierung und vorbelegter Text ändern sich nicht als Nebeneffekt. +- Die 91 MP3-Dateien und die CW-Ausgabe in `PlayAudioUtils`. +- Verpackung und Vertrieb, soweit sie nicht am JavaFX-Modulpfad hängen. + +## Risiken + +**Etappe 1 kann das Vorgehen kippen.** Ergibt die Prüfung, dass der „tote" Aufbau +lebende Nebenwirkungen hat, wird aus Löschen ein Entflechten und die Etappe wird +länger. Das ist der Grund, warum die Prüfung eine eigene Etappe ist und keine Annahme +im Plan. + +**Der Dispatcher-Tausch wirkt überall.** Ein Fehler darin zeigt sich nicht als +Übersetzungsfehler, sondern als sporadisch nicht aktualisierte Oberfläche. Deshalb die +Tests für den Vertrag und nicht nur für die Anwendung. + +**Die Dialoge sind Ablaufsteuerung, keine Dekoration.** Wer eine Bestätigung +nicht-blockierend macht, ändert den Ablauf. Jeder der zehn Aufrufe ist einzeln zu +lesen. + +## Offene Punkte + +- Der Status von `FxRosterBinding` ist Gegenstand von Etappe 1 und wird hier bewusst + nicht vorweggenommen. +- Ob `ApplicationRuntimeLauncher` und `ComposeMenuActions` nach dem Wegfall der Bühne + noch eine JavaFX-Berührung behalten, entscheidet sich in Etappe 5. +- Die macOS-Systemmenüleiste ist eine JavaFX-`MenuBar` (`:172`, `:5729`) und wird auf + die Szene des Kandidatenfensters gesetzt (`:4858`). Ob sie darüber hinaus an etwas + hängt — und was von ihr auf macOS tatsächlich sichtbar ist, seit das Hauptfenster + Compose ist — gehört in Etappe 1. diff --git a/docs/superpowers/specs/2026-10-04-farben-anpassbar-design.md b/docs/superpowers/specs/2026-10-04-farben-anpassbar-design.md new file mode 100644 index 00000000..c39c7e15 --- /dev/null +++ b/docs/superpowers/specs/2026-10-04-farben-anpassbar-design.md @@ -0,0 +1,240 @@ +# Entwurf — die Farben pro Operateurprofil anpassbar machen + +Vertieft: `docs/superpowers/specs/2026-09-25-compose-migration-design.md`, Etappe 8. + +Dieser Entwurf ersetzt den dortigen Abschnitt. Er ist im September geschrieben worden, und +zwei seiner Annahmen stimmen nicht mehr. + +## Ziel + +Der Operateur bestimmt die Farben seines Clients, ohne Dateien im Installationsverzeichnis +anfassen zu müssen. Erfolg ist nachprüfbar: + +- Eine geänderte Palette überlebt den Neustart. +- Sie gilt in **allen offenen Fenstern gleichzeitig**, nicht erst nach einem Fensterneubau. +- Sie ist **pro Profil** verschieden. +- Das Zurücksetzen stellt **exakt** die ausgelieferten Farben her — nicht etwas, das ihnen + gleicht. + +## Was sich gegenüber dem Ursprungsabschnitt geändert hat + +**Die Voraussetzung ist entfallen.** Er schreibt: „Ab Etappe 6 gibt es kein JavaFX mehr, das +dagegenhält — vorher muss beides dieselbe Datei lesen." Es gibt kein JavaFX mehr. Und der +`derive`-Pin, auf den er ausdrücklich wartet, ist seit Etappe 3 eine JavaFX-freie Umsetzung, +gegen eingecheckte Referenzwerte geprüft. Diese Etappe ist frei. + +**Ein Befund kommt hinzu, den er nicht hatte.** `Kst4ContestTheme` liest die Palette als +`remember(darkMode)` (`Theme.kt:32`). Eine Palettenänderung erreicht die Fenster damit **gar +nicht**, bis jemand Tag/Abend umschaltet. Das Abnahmekriterium „gilt für alle Fenster +gleichzeitig" hängt also nicht an der Speicherung, sondern hier. Der Weg dafür existiert +bereits: `applyTheme` (`Kst4ContestApplication`) ruft `applyDarkMode` auf sechs Fenster-Wirten, +jeder hält einen `mutableStateOf` — nur trägt der heute bloß ein Boolean. + +**Der Defektbefund bleibt richtig.** `copyResourceIfRequired` legt beim Start Kopien von +`KST4ContestDefaultDay.css` und `KST4ContestDefaultEvening.css` nach +`~/.kst4contest/` (`Kst4ContestApplication:2138`–`:2139`). Geprüft: **nichts liest sie.** Wer +seine Kopie bearbeitet, sieht keinerlei Wirkung. + +## Die Quelle der Farben: drei Schichten + +| | Schicht | Woher | Vorrang | +|---|---|---|---| +1 | **Auslieferung** | die Vorlage aus dem Klassenpfad | Boden, immer vorhanden | +2 | **Datei** | die CSS-Datei im Profilverzeichnis, falls vorhanden | überschreibt 1 | +3 | **Geändert** | die sechs Rollen aus den Einstellungen des Profils | überschreibt 1 und 2 | + +**Die spätere Schicht gewinnt, Rolle für Rolle.** Eine Datei, die nur `-fx-base` nennt, ändert +nur diese Rolle; die übrigen kommen weiter aus der Auslieferung. + +### Warum drei und nicht eine + +Abgewogen wurden zwei Wege. + +**Nur die CSS-Datei maßgeblich**, wie der Ursprungsabschnitt es wörtlich sagt, wurde +verworfen: eine Farbänderung müsste `-fx-base` in die 6,4-KB-Vorlage zurückschreiben, und das +braucht einen Serialisierer, der jede übrige Regel unverändert durchträgt. Ein Rundlauf, der +eine Regel verliert, zerstört das Aussehen still. `JavaFxStylesheet` ist ein Leser; ein +Schreiber daneben wäre die risikoreichste Stelle dieser Etappe, und die Anforderung — „ohne +Dateien anfassen zu müssen" — verlangt ihn nicht. + +**Nur die Einstellungen** wäre das Einfachste und wurde bewusst nicht gewählt: es nimmt dem +Operateur den Handweg, den er heute zu haben *glaubt* (die Kopie liegt ja da), und der +Defektbefund würde gelöscht statt behoben. + +**Gewählt: beide, mit ausdrücklichem Vorrang.** Der Preis ist benannt und wird im nächsten +Abschnitt bezahlt: bei zwei Quellen ist später nicht mehr ersichtlich, warum eine Farbe so +ist, wie sie ist. + +### Was diesen Preis bezahlt + +**Jede der sechs Rollen zeigt in der Oberfläche, woher ihr geltender Wert kommt** — +*Auslieferung*, *Datei* oder *geändert*. Die Auflösung weiß das ohnehin, es kostet nichts, und +ohne das ist die Frage „warum ist diese Farbe so?" unbeantwortbar. Das ist keine Zierde, +sondern die Bedingung, unter der die Dreischicht-Lösung vertretbar ist. + +## Die sechs Rollen + +Die, die `JavaFxPalette` benennt. Der Ursprungsabschnitt zählt fünf auf; es sind sechs, +weil `base` und `windowBackground` getrennt geführt werden — siehe unter der Tabelle. + +| Rolle | im Palettenobjekt | +|---|---| +Fläche | `base` | +Fensterfläche | `windowBackground` | +Feldinneres | `controlInnerBackground` | +Text | `labelTextFill` | +Akzent | `accent` | +Trennlinie | `separatorLine` | + +`base` und `windowBackground` sind getrennt, weil die Vorlagen sie getrennt führen und die +Fensterfläche aus der Fläche abgeleitet wird (`derive(base, 26.4%)`) — wer nur eine davon +setzen könnte, bekäme die andere ungefragt mitgezogen. + +**Nicht anpassbar** bleiben `textAccent`, `buttonHoverGradient` und `buttonPressedBorder`. Sie +sind abgeleitete Werte, keine Rollen, die jemand einzeln wählen will; sie folgen dem Akzent. +`fontSizePx` ist eine bestehende Einstellung und wird hier nicht angefasst. + +**Tag und Abend sind zwei Paletten.** Jede Rolle existiert zweimal, und eine Änderung am +Abendentwurf lässt den Tagentwurf unberührt. + +## Die Wirkung ist sofort, und es gibt drei Wege zurück + +**Eine Änderung gilt unmittelbar in allen offenen Fenstern.** Kein Musterfeld, kein +„noch nicht gespeichert"-Zustand. + +Der Grund gegen ein Musterfeld ist die Geschichte dieses Projekts: die Fehlerklassen, die hier +wiederholt mit grünem Bau auslieferten, waren „sah einzeln richtig aus und war an seinem Platz +falsch". Ein zweihundert Pixel breites Muster ist genau diese Isolation. Es sagt nichts +darüber, wie die Stationsliste mit 22 Spalten in einer Palette liest. Das Einstellungsfenster +selbst ist die bessere Vorschau: es färbt sich mit und enthält Beschriftungen, Felder, Knöpfe +und Trennlinien — alles, was die sechs Rollen betrifft. + +Weil es keinen Zwischenzustand gibt, sind die Rückwege keine Bequemlichkeit, sondern der +Ersatz dafür: + +- **„Zurück zum Stand von vorher"** — beim Öffnen des Reiters wird die geltende Palette + gemerkt; dieser Knopf stellt sie wieder her. Das ist der Rückweg für den Normalfall: eine + Farbe im echten Fenster ausprobiert, gefällt nicht, weg damit. +- **„Meine Änderungen verwerfen"** — leert Schicht 3. Es gilt wieder Datei oder Auslieferung, + je nachdem, was da ist. +- **„Auf Auslieferung zurücksetzen"** — setzt alle Rollen auf die ausgelieferten Werte, als + ausdrückliche Änderung der Schicht 3. Damit spielt eine vorhandene Datei keine Rolle mehr. + **Das ist die Aktion, die das Abnahmekriterium erfüllt**, und sie erfüllt es auch dann, wenn + eine Datei im Spiel ist. + +Mit einer Datei zwischen Auslieferung und Änderung kann **ein** Knopf nicht alle drei Fälle +abdecken: löscht er nur die Änderungen, gilt wieder die Datei und nicht die Auslieferung. + +### „Auf Auslieferung zurücksetzen" wird immer in den ausgelieferten Farben gezeichnet + +**Dieser eine Knopf nimmt die aktive Palette nicht an.** Er wird in den ausgelieferten Farben +gezeichnet, ganz gleich, was der Operateur eingestellt hat — Fläche, Text und Rahmen aus +Schicht 1, nicht aus der Auflösung. + +Der Grund ist die Fehlerart, die sich sonst selbst einschließt: wer Text und Fläche auf +dasselbe Schwarz stellt, sieht die Knöpfe nicht mehr, mit denen er es zurücknehmen könnte. Ein +Tastaturweg allein hilft dann nur, wer ihn kennt. Ein Knopf, der die kaputte Palette nicht +annimmt, hilft immer. + +Dass er dadurch bei einer stark angepassten Palette **fremd aussieht, ist beabsichtigt.** Er ist +eine Rettungsleine, keine Zierde; dass er sich nicht einfügt, macht ihn auffindbar. + +Die anderen zwei Rückwege nehmen die aktive Palette an. Sie sind Bequemlichkeit für den +Normalfall; die Rettungsleine ist diese eine, und genau eine ist leichter zu merken als drei. + +Ein Tastaturweg kommt zusätzlich, für alle drei. Er ist jetzt die zweite Absicherung, nicht +mehr die einzige. + +## Die Datei im Profilverzeichnis + +**Für das Wurzelprofil existiert sie schon:** `~/.kst4contest/KST4ContestDefaultDay.css` und +`…Evening.css`, von `copyResourceIfRequired` geschrieben. Sie wird jetzt **gelesen**. Das +behebt den dokumentierten Defekt, statt seine Spuren zu beseitigen, und gibt dem Operateur den +Handweg, den die Datei ihm die ganze Zeit versprochen hat. + +**Für andere Profile wird nicht ungefragt kopiert.** Der Pfad folgt dem Muster, das +`OperatorProfilePaths` für Einstellungen und Datenbank schon benutzt: Wurzelprofil flach, sonst +`profiles//`. Eine Datei, die ungefragt entsteht und niemand braucht, ist dieselbe +Falle wie die bisherige ungelesene Kopie. Stattdessen schreibt ein Knopf im Reiter die Vorlage +ins Profilverzeichnis, wenn der Operateur von Hand bearbeiten will. + +**Eine unlesbare oder fehlerhafte Datei darf den Start nicht verhindern.** Sie wird +übersprungen, die Rolle fällt auf die Auslieferung zurück, und der Reiter sagt es. Ein Client, +der wegen einer kaputten Farbdatei nicht startet, ist schlimmer als einer in den falschen +Farben. + +## Dass es alle Fenster erreicht + +Ein **`PaletteStore`** hält die Palette beider Entwürfe für das aktive Profil als +Compose-Zustand. `Kst4ContestTheme` liest daraus statt aus `remember(darkMode)`. Damit zeichnet +eine Änderung jedes offene Fenster neu — über denselben Weg, den der Tag/Abend-Wechsel schon +benutzt, und ohne dass `applyTheme` oder die sechs Fenster-Wirte etwas Neues lernen müssen. + +Der Store wird beim Profilwechsel neu gebildet, wie jeder andere profilgebundene Zustand. + +## Der Kontrastwächter + +Eine frei gewählte Textfarbe auf einer frei gewählten Fläche kann unlesbar werden. Die +Oberfläche **sagt es, speichert aber trotzdem**: ein Funker, der im Contest bewusst eine harte +Kombination will, bekommt sie. Das Maß ist das WCAG-Kontrastverhältnis aus relativer +Leuchtdichte — eine reine Funktion, und damit der Teil, der falsch sein kann, ohne dass es +auffällt. + +Geprüft werden die Paare, die tatsächlich übereinanderliegen: Text auf Fläche, Text auf +Feldinnerem, und Akzent auf Fläche. + +## Prüfung + +Das Wertvolle hier sind die Regeln, nicht die Oberfläche. Alle ohne Bildschirm prüfbar: + +- **Die Dreischicht-Auflösung** samt Vorrang und Herkunftsangabe, einschließlich: Datei fehlt; + Datei nennt nur eine Rolle; Datei ist unlesbar; Änderung und Datei widersprechen sich. +- **Die drei Rückwege** — besonders, dass „auf Auslieferung" auch bei vorhandener Datei exakt + die ausgelieferten Werte ergibt, und dass „zum Stand von vorher" die Palette herstellt, die + beim Öffnen des Reiters galt, einschließlich einer damals schon vorhandenen Änderung. +- **Dass der Auslieferungs-Knopf die ausgelieferten Farben benutzt und nicht die aufgelöste + Palette** — geprüft mit einer Palette, in der jede Rolle auf etwas anderes gesetzt ist. Das + ist der Test, der die Rettungsleine davor bewahrt, still an der Palette zu hängen, die sie + retten soll. +- **Das Kontrastverhältnis**, gegen von Hand nachgerechnete Werte. +- **Dass Tag und Abend getrennt bleiben.** +- Dazu die Rückfalltests aus Etappe 7: Klasse 4 prüft, dass die Farben aus der Stilvorlage + kommen, und muss mit dieser Etappe weiter gelten. + +## Was unverändert bleibt + +- Die ausgelieferten Vorlagen selbst. +- `JavaFxStylesheet` als **Leser**. Kein CSS-Schreiber, nirgends. +- Der `derive`-Pin samt eingecheckter Referenztabelle und `JavaFxStylesheetTest`. +- Die Speicherung pro Profil über `ChatPreferences` — dieselbe wie jede andere Einstellung. +- `fontSizePx` und die bestehende Schriftgrößeneinstellung. +- Die Invarianten aus `AGENTS.md`. + +## Risiken + +**Die zweite Quelle ist der Preis dieser Etappe.** Zwei Schichten, die dasselbe bestimmen +können, sind eine Stelle, an der später niemand weiß, warum eine Farbe so ist. Die +Herkunftsangabe pro Rolle ist die einzige Gegenmaßnahme, und sie ist deshalb nicht optional. + +**Eine Änderung, die alle Fenster erreicht, erreicht sie auch alle falsch.** Der `PaletteStore` +ist eine Stelle, an der ein Fehler sich überall gleichzeitig zeigt. Dafür zeigt er sich +wenigstens sofort und nicht erst nach einem Fensterneubau. + +**Der Kontrastwächter warnt nur.** Ein Operateur kann sich einen unlesbaren Client bauen. Das +ist die Entscheidung, die hier bewusst bei ihm liegt, und der Ausweg ist der Knopf, der die +kaputte Palette nicht annimmt. + +**Die Warnung des Wächters hat dieselbe Angreifbarkeit wie die Knöpfe** und ist nicht +ausgenommen: in einer unlesbaren Palette ist auch sie unlesbar. Sie auszunehmen wäre +folgerichtig, würde aber den Reiter mit zwei fremd aussehenden Flächen besetzen statt mit +einer. Ich lasse es bei der einen Rettungsleine und halte den Punkt hier fest, statt ihn +stillschweigend auszuweiten. + +## Zwei Festlegungen, die sonst im Bau beliebig würden + +**Die Wirkung ist sofort, der Rückweg gemerkt.** Kein Musterfeld — die Begründung steht unter +„Die Wirkung ist sofort". Beurteilt wird im echten Fenster, zurück geht es über eine beim +Öffnen des Reiters gemerkte Palette. + +**Alle drei Rückwege bleiben.** Ohne Zwischenzustand sind sie der einzige Weg zurück, und alle +drei müssen ohne Farbwahrnehmung erreichbar sein — also auch über die Tastatur. diff --git a/docs/superpowers/specs/2026-10-04-mehrsprachigkeit-design.md b/docs/superpowers/specs/2026-10-04-mehrsprachigkeit-design.md new file mode 100644 index 00000000..57c38348 --- /dev/null +++ b/docs/superpowers/specs/2026-10-04-mehrsprachigkeit-design.md @@ -0,0 +1,301 @@ +# Entwurf — Mehrsprachigkeit + +Vertieft: `docs/superpowers/specs/2026-09-25-compose-migration-design.md`, Etappe 9. + +Dieser Entwurf ersetzt den dortigen Abschnitt. Er ist im September geschrieben worden, und +seine Zahlen und eine seiner Annahmen stimmen nicht mehr. + +## Ziel + +Die Oberfläche spricht die Sprache des Operateurs, Deutsch und Englisch zum Start, und +weitere Sprachen können von außen beigetragen werden, ohne dass der Beitragende Kotlin anfasst. + +Erfolg ist nachprüfbar: + +- Die Sprache lässt sich umschalten, wirkt **sofort in allen offenen Fenstern** und bleibt nach + dem Neustart umgeschaltet. +- Sie gilt **pro Operateurprofil**. +- **Kein einziger Text, der an den ON4KST-Server oder an andere Funker geht, ändert sich mit + der Sprache.** Geprüft, nicht angesehen. +- Eine fehlende Übersetzung fällt auf Englisch zurück, statt zu fehlen. +- Eine fehlerhafte Übersetzung bricht den Bau ab, bevor sie ausgeliefert wird. + +## Umfang dieser Etappe: die Mechanik, nicht die Texte + +Gemessen am heutigen Stand, nach den Etappen 4 bis 8: + +| | Zeichenketten | +|---|---| +`app-desktop` Kotlin | 852 +`app-desktop` Java | 417 +davon nach Oberflächentext aussehend, verschieden | **~394** +`core` | 2.968, davon 273 `println` + +Die Zahlen des Ursprungsabschnitts (232 Compose, 492 Java) sind durch den JavaFX-Ausbau +überholt. + +**Diese Etappe baut die Mechanik und zieht ein Dutzend Texte als Beweis heraus.** Die übrigen +rund 380 sind mechanische Folgearbeit, die häppchenweise gehen kann und keine +Architekturentscheidung mehr enthält. Der Grund für diesen Schnitt: die Mechanik trägt alle +380, und sie jetzt falsch zu bauen kostet 380 Mal nach. + +## Die vier Textsorten + +Der Ursprungsabschnitt nennt drei. Gemessen sind es vier, und die vierte ist die größte. + +**Die Regel, die entscheidet, ist der Adressat des Textes** — nicht, wie er aussieht. + +| Adressat | Sorte | Wo sie heute lebt | übersetzen | +|---|---|---|---| +Der Operateur am Bildschirm | Oberflächentext | `app-desktop/src/main` | **ja** | +Der ON4KST-Server | Protokolltext | `On4KstProtocol` (`LOGINC\|`, `SDONE\|`, `ACHAT\|`, `CK`, `DXQ`), dazu die `/`-Chatbefehle und `SETNAME`/`MYQRG` | nein | +Andere Funker | Funkertext | `ChatPreferences`-Vorgabewerte, Schnipsel, Kurztasten | nein | +Der Entwickler beim Fehlersuchen | Diagnosetext | 273 `println` in `core` | nein | + +Die beiden mittleren sind dasselbe Risiko aus zwei Richtungen: ein übersetzter Protokollbefehl +bricht die Verbindung, ein übersetztes Funkerkürzel macht den Operateur unverständlich. + +Der Protokolltext hat dabei zwei Ebenen, die nicht zu verwechseln sind: die **Rahmen** auf dem +Draht (`LOGINC|`, `SDONE|`, `ACHAT|` in `On4KstProtocol`) brechen bei einer Übersetzung die +Verbindung, die **`/`-Chatbefehle** (`/CQ`, `/AWAY`) gehen als Nachricht durch und werden vom +Server nicht verstanden. Beide dürfen sich nicht mit der Sprache ändern. + +Keiner dieser Fehler fällt in einem Test auf, der nur die Oberfläche ansieht — und im Betrieb +fällt er erst im Contest auf, also unter Zeitdruck. + +Der Diagnosetext ist neu benannt und gehört ausdrücklich dazu: ein deutscher Fehlerbericht ist +für den Wartenden schlechter als ein englischer, und die 273 `println`-Aufrufe sehen im +Quelltext genauso aus wie Oberflächentext. + +### Die Regel für `core` + +**`core` erzeugt keinen Anzeigetext. Es liefert einen Schlüssel oder einen Aufzählungswert, +und `app-desktop` macht daraus Text.** + +Das ist die Fortsetzung des bestehenden Schnitts „`core` bleibt toolkit-frei" in die Sprache +hinein: `core` hat nicht zu wissen, welche Sprache der Mensch liest. Der zweite, praktische +Grund: weil `core` keine Nachschlagefunktion bekommt, **kann kein deutscher Text in eine +Protokoll- oder Diagnosezeile geraten.** Die Regel erzwingt die Abgrenzung, statt sie zu +verlangen. + +Abgewogen und verworfen wurde, `core` ein Bündel mitzugeben. Ein `ResourceBundle` ist reines +JDK und hätte den Toolkit-Schnitt nicht verletzt — aber es hätte die Nachschlagefunktion neben +die 273 `println`-Aufrufe gestellt, also genau dorthin, wo Deutsch nicht hingehört. + +**Zwei heutige Verstöße** werden benannt und bleiben diese Etappe englisch: + +- `core/src/main/java/kst4contest/view/map/PathPropagationAssessment.java` — die + Ausbreitungsbeschreibungen („Aircraft scatter, tropo ducting/enhancement, …"). +- `core/src/main/java/kst4contest/logic/PriorityCalculator.java` — die Prioritätsgründe + („Active now"). + +Sie zu verlegen ist Folgearbeit. Der Nutzen der Regel jetzt: die ~380 Folgetexte haben eine +Regel statt einer Diskussion pro Fall. + +## Die Übersetzungen sind Dateien, die niemand kompilieren muss + +`app-desktop/src/main/i18n/strings_en.properties` als Grundlage, `strings_de.properties` +daneben. Flach, ein Schlüssel, ein Text: + +```properties +settings.save=Save settings +alert.armedFor=Armed for {0} +``` + +Wer eine Sprache beitragen will, kopiert die englische Datei, übersetzt die Werte rechts vom +Gleichheitszeichen und öffnet eine PR. Kein Kotlin, kein Gradle, keine Escapes für Umlaute. + +**Warum `.properties` und nicht JSON.** Gemessen: `java.util.Properties` ist JDK und liest +seit Java 9 UTF-8, funktioniert also im Erzeuger ohne jede Abhängigkeit. JSON hätte entweder +eine neue Bauwerkzeug-Abhängigkeit gekostet oder einen selbstgeschriebenen Leser, dessen +Escape- und Unicode-Fehler dann hausgemacht wären — `groovy.json.JsonSlurper` steht nur im +Gradle-Kontext zur Verfügung und nicht in einem Modul, dessen Tests im normalen Lauf +mitzählen. Für Beitragende ist das Format zudem robuster: keine Klammern und Kommas, die man +kaputtmachen kann. + +**Eine Datei pro Sprache**, nicht eine Datei mit allen Sprachen nebeneinander: so bleiben +Sprach-PRs voneinander getrennt. Den Vorteil der Nebeneinander-Form — der Übersetzer sieht das +Original neben seinem Feld — bildet ein Arbeitsblatt nach (siehe unten). + +Englisch ist die Quellsprache, weil der Quelltext es so hält und `AGENTS.md` es für +Oberflächentext vorschreibt. + +## Der Erzeuger: Unvollständigkeit ist erlaubt, Unrichtigkeit nicht + +Ein Gradle-Task liest die Textdateien und erzeugt daraus Kotlin. **Die Fehler entstehen +dort**, nicht in einem Prüfer, der danebensteht. + +| Befund | Erzeuger | +|---|---| +Schlüssel fehlt in einer Übersetzung | **Warnung**, Rückfall auf Englisch zur Laufzeit +Schlüssel steht in der Übersetzung, aber nicht in der englischen Grundlage | **Bau bricht ab** — Tippfehler des Beitragenden +Platzhalter weichen ab (`{0} {1}` → `{0}`) | **Bau bricht ab** — verschluckt Daten lautlos, und `MessageFormat` sagt dazu nichts +Datei unlesbar oder doppelter Schlüssel | **Bau bricht ab** +Schlüssel lässt sich nicht eindeutig in einen Kotlin-Namen übersetzen | **Bau bricht ab** + +Diese Trennung ist der Kern: eine zu 80 % fertige beigetragene Sprache **muss** einreichbar +sein, sonst ist die ganze Auslagerung zwecklos. Eine falsche Übersetzung darf dagegen nicht +ausgeliefert werden. + +Erzeugt wird nach `build/generated/`, nicht in den Quellbaum — damit kann das Erzeugnis nicht +von den Textdateien abdriften. + +**Der Erzeuger ist ein eigenes Modul, kein Bauskript.** Die Spezifikation verlangt, ihn zu +testen; `buildSrc` leistet das nicht — gemessen: `buildSrc`-Tests laufen bei +`./gradlew build` nicht mit, was genau den Fehler ergäbe, den der Erzeuger verhindern soll. Er +wird deshalb ein drittes, **reines Bauwerkzeug-Modul** `i18n-generator` im Hauptbau, von +`app-desktop` über eine `JavaExec`-Aufgabe vor `compileKotlin` aufgerufen. Seine Tests sind +gewöhnliche Projekttests: sie laufen bei `./gradlew build`, zählen in der Test-XML mit und +werden von der bestehenden CI gefahren. + +Das Modul wird **nicht** ausgeliefert: es steht nicht im Laufzeit-Klassenpfad von +`app-desktop`, nur in einer eigenen Konfiguration für den Aufruf. `CLAUDE.md` und +`docs/PROJECT_CONTEXT.md` nennen heute zwei Module und sind entsprechend nachzuziehen. + +**Kein Parser zur Laufzeit.** Die Texte stehen als Kotlin im Jar: kein `ResourceBundle`, keine +Datei-E/A, und **keine neue Abhängigkeit, weder im Jar noch im Bau**. + +### Die erzeugte Form macht auch die Stelligkeit prüfbar + +```kotlin +class Strings(private val lookup: (String) -> String) { + val settingsSave: String get() = lookup("settings.save") + fun alertArmedFor(arg0: Any): String = MessageFormat.format(lookup("alert.armedFor"), arg0) +} +``` + +Also `strings.settingsSave` statt `strings.get("settings.save")`. Ein Tippfehler ist ein +Übersetzungsfehler, und `alertArmedFor()` ohne Argument übersetzt nicht. + +Das ist der Teil, der die ~380 Folgetexte trägt: bei stringbasierten Schlüsseln wäre jeder +davon eine neue Gelegenheit für einen Laufzeitfehler, und die Fehlerart wäre „Text fehlt im +Fenster" — dieselbe stille Sorte, die diesen Zweig schon mehrfach erwischt hat. + +Form und Stelligkeit kommen **immer aus der englischen Grundlage.** Deshalb bleibt ein falscher +Platzhalter ein Bauabbruch, während ein fehlender Schlüssel nur ein Rückfall ist. + +### Das Arbeitsblatt für Beitragende + +Ein Task erzeugt `strings_.todo.properties`: die fehlenden Schlüssel mit dem +**englischen Text als Wert**. Ohne das müsste ein Beitragender zwei Dateien diffen, um zu finden, was fehlt. + +### Deckung + +Der Erzeuger gibt beim Bau eine Zeile aus — `de: 394/394, fr: 120/394` —, damit einer PR +ansehbar ist, wie weit sie ist. + +**Deutsch wird durch einen Test auf Vollständigkeit gehalten, weitere Sprachen nicht.** Deutsch +ist eine ausgelieferte Sprache; dort ist eine Lücke ein Fehler. Bei einer beigetragenen Sprache +ist eine Lücke der Normalfall. + +## Dass es alle Fenster erreicht + +Dieselbe Bauform wie bei den Farben in Etappe 8, damit es nur eine zu verstehen gibt. + +Ein **`LanguageStore`** hält die Sprache als Compose-Zustand. Zwei Aufrufwege, eine Wahrheit: + +- **Compose:** `LocalStrings.current.settingsSave`, bereitgestellt in + `ComposeWindowHost.show` neben `LocalPaletteStore`. Der Zustandszugriff ist wieder genau das, + was die Neuzeichnung auslöst — in Etappe 8 war `remember(darkMode)` der Grund, warum eine + Änderung gar kein Fenster erreichte. +- **Java:** `Strings.current()` gegen ein `@Volatile`-Feld, das der Store beim Wechsel setzt. + Die verbliebenen AWT-Aufrufstellen holen damit beim nächsten Aufruf die neue Sprache, ohne + eigene Mechanik. + +Der Store wird beim Profilwechsel neu gebildet, wie jeder andere profilgebundene Zustand. + +## Die Einstellung + +Ein Feld `guiOptions_language` in `ChatPreferences` — pro Profil, wie jede andere +GUI-Einstellung. Bei einer Mehrmann-Station ist das auch das Richtige: zwei Operateure, zwei +Sprachen. Drei Werte: leer (Systemsprache), `en`, `de`. Ein `Form.choice` im GUI-Reiter. + +Die Vorgabe ist eine **reine Funktion** `localeFor(stored, systemDefault)`, damit sie ohne +Systemwechsel prüfbar ist: leerer Wert heißt Systemsprache, und ist die nicht Deutsch, dann +Englisch. + +## Die zwölf Beweistexte + +Bewußt **über mehrere Fenster verteilt**, nicht die zwölf nächstliegenden aus einer Datei: die +Save- und Close-Knöpfe des Einstellungsfensters, die Abschnittstitel des GUI-Reiters, die +Beschriftung der Sprachwahl selbst, ein Menütitel im Hauptfenster, die Verbindungsanzeige in +der Statuszeile und ein `ComposeAlert`-Knopf. + +Der Grund ist das Abnahmekriterium: beim Umschalten im Einstellungsfenster muss sich **das +Hauptfenster dahinter sichtbar mitändern.** Zwölf Texte aus einer Datei würden das nicht +zeigen, und genau diese Sorte Scheinbeweis hat diesen Zweig mehrfach erwischt — eine +Einstellung, die durchgeschrieben und nicht gezeichnet wurde. + +## Prüfung + +Das Wertvolle sind die Regeln, nicht die Oberfläche. Alles ohne Bildschirm prüfbar: + +- **Die drei Abgrenzungstests.** (1) `On4KstProtocol` baut seine Rahmen unter + `Locale.GERMAN` und `Locale.ENGLISH` zeichengleich — `login`, `settingsDone`, `addChat`, + `clientLivenessProbe`, `serverLivenessProbeResponse`. Geprüft wird die Ausgabe, nicht das + Bündel. Die Klasse ist paketprivat, der Test gehört also nach + `core/src/test/java/kst4contest/controller/`. (2) Die `ChatPreferences`-Vorgabewerte ändern sich mit keiner Sprache, **über + Reflexion über alle `String`-Felder**, nicht über eine gepflegte Liste: das deckt auch ab, + was nach dieser Etappe dazukommt. (3) Kein Wert in einem Bündel ist ein + Protokoll-Opcode, ein `/`-Chatbefehl, `SETNAME`, `MYQRG` oder ein + `ChatPreferences`-Vorgabewert. +- **Der Erzeuger selbst**, je ein Test für die fünf Befunde seiner Tabelle, gegen kleine + Textschnipsel. Das ist der Teil, der falsch sein kann, ohne dass es auffällt — ein + Bauabbruch, der nie abbricht, sieht aus wie ein sauberes Projekt. +- **`localeFor`**: leer und deutsches System → Deutsch; leer und französisches System → + Englisch; `"de"` gespeichert und englisches System → Deutsch; Müll gespeichert → Englisch. +- **Der Rückfall**: ein Schlüssel, den nur Englisch hat, kommt unter Deutsch englisch zurück. +- **Deutsch ist vollständig**, über die erzeugten Schlüssel. +- **Dass ein Sprachwechsel die Komposition erreicht** — dieselbe Bauform wie + `ThemeReadsPaletteStoreTest`, das bei den Farben genau diesen Fehler gefunden hat. + +**Die PR-Prüfung fängt das alles schon.** Der `compile`-Auftrag in `pr-compile-check.yml` läuft +`./gradlew -S classes testClasses`; der Erzeuger hängt an `classes`, also schlägt eine kaputte +Übersetzung dort mit seiner eigenen Meldung fehl. Der `test`-Auftrag fährt die +Abgrenzungstests. **Kein neuer Workflow nötig** — das ist eine Folge davon, den Erzeuger in den +Bau zu hängen statt in ein eigenes Prüfskript. + +## Was unverändert bleibt + +- Die vier `ChatPreferences`-Vorgabewerte und alles, was in der gespeicherten XML eines + Operateurs steht: `bcn_beaconTextMainCat`, `bcn_beaconTextSecondCat`, + `messageHandling_autoAnswerTextMainCat`, `messageHandling_autoAnswerTextSecondCat`, sowie + Schnipsel und Kurztasten. +- `core` bekommt keine Nachschlagefunktion. +- Die Reiterreihenfolge im Einstellungsfenster; die Sprachwahl kommt in den bestehenden + GUI-Reiter. +- Keine neue Abhängigkeit, weder im Jar noch im Bau. +- `app-desktop`s übrige ~380 Texte bleiben englisch, mit der Regel aus „Die vier Textsorten" + für die Folgearbeit. +- Quelltextkommentare und Javadoc bleiben ausschließlich Englisch. Mehrsprachigkeit betrifft + die Oberfläche, nicht den Quelltext. + +## Risiken + +**Die Abgrenzung ist der Preis dieser Etappe, nicht die Mechanik.** Ein übersetzter +Protokollbefehl oder ein übersetztes Funkerkürzel fällt beim Bauen nicht auf und beim Hinsehen +auch nicht. Die drei Abgrenzungstests sind die Gegenmaßnahme, und der reflexionsbasierte unter +ihnen ist der einzige, der auch das abdeckt, woran beim Schreiben niemand gedacht hat. + +**Ein Sprachwechsel erreicht alle Fenster — also auch alle falsch.** Der `LanguageStore` ist +wie der `PaletteStore` eine Stelle, an der ein Fehler sich überall gleichzeitig zeigt. Dafür +zeigt er sich sofort. + +**Eine beigetragene Sprache kann halb englisch sein.** Das ist gewollt und der Preis dafür, +Beiträge überhaupt annehmen zu können. Die Deckungszeile macht es sichtbar; ob die Sprachwahl +dem Operateur den Deckungsgrad anzeigen soll, ist hier **nicht** entschieden und wäre eine +eigene kleine Erweiterung. + +**Der Erzeuger ist neuer Bau-Code und damit eine neue Stelle, an der der Bau brechen kann.** +Dagegen hilft nur, ihn zu testen wie Produktionscode — deshalb steht er in der Prüfliste. + +## Festlegungen, die sonst im Bau beliebig würden + +**Die Regel ist der Adressat, nicht das Aussehen.** Wer beim Herausziehen unsicher ist, fragt +nicht „sieht das nach Oberfläche aus", sondern „wer liest das". + +**Unvollständigkeit ist erlaubt, Unrichtigkeit nicht.** Das entscheidet jeden Zweifelsfall im +Erzeuger. + +**Die Stelligkeit kommt aus der englischen Grundlage.** Eine Übersetzung kann einen Schlüssel +weglassen, aber nicht seine Platzhalter umdeuten. diff --git a/github_docs/de-Benutzeroberflaeche.md b/github_docs/de-Benutzeroberflaeche.md index 470ea951..8ca0765b 100644 --- a/github_docs/de-Benutzeroberflaeche.md +++ b/github_docs/de-Benutzeroberflaeche.md @@ -482,8 +482,9 @@ Die serverbezogenen Funktionen sind nur bei vollständig aufgebauter ON4KST-Verb - **Hide cluster / stranger QSOs** beziehungsweise **Show cluster / stranger QSOs** blendet das zusätzliche Cluster- und QSO-Monitorfenster aus oder wieder ein. - **hide options** beziehungsweise **show options** blendet das Einstellungsfenster aus oder wieder ein. -- **Use dark mode design** aktiviert das dunkle Farbschema. -- **Use default mode design** aktiviert das normale helle Farbschema. +- **Use dark mode design** aktiviert das dunkle Farbschema für die laufende Sitzung. +- **Use default mode design** aktiviert das normale helle Farbschema für die laufende Sitzung. + Das Farbschema beim Start wird pro Profil im Einstellungsreiter **GUI** unter **Design** festgelegt. - **Show / hide station map** öffnet beziehungsweise schließt das separate Fenster mit Stationskarte und Streckenanalyse. --- diff --git a/github_docs/de-Changelog.md b/github_docs/de-Changelog.md index 622bb446..a4d04f7f 100644 --- a/github_docs/de-Changelog.md +++ b/github_docs/de-Changelog.md @@ -8,6 +8,47 @@ Die veröffentlichten Stable-Versionen und ihre Programmpakete stehen unter [Git --- +## v1.50 (in Entwicklung) + +**Operator-Profile** + +Mehrere Operateure an einem Rechner können jetzt eigene Rufzeichen, Locators und Layouts verwenden, ohne sich gegenseitig die Konfiguration zu überschreiben. Damit ist [Issue #57](https://github.com/praktimarc/kst4contest/issues/57) umgesetzt. + +### Neu + +- **Operator-Profile:** Jedes Profil hat seine eigene `preferences.xml` und damit eigene fachliche Einstellungen und einen eigenen Layoutstand. Verwaltet werden Profile im neuen Reiter **Profiles** des Einstellungsfensters: anlegen, duplizieren, umbenennen, löschen und aktivieren. + +- **Gemeinsame oder eigene gearbeitete Stationen:** Pro Profil wird entschieden, ob es eine eigene Worked-Datenbank bekommt oder die gemeinsame Stationsdatenbank benutzt. Eine Multi-OP-Station mit einem einzigen Stationslog teilt den Worked-Status, zwei OMs mit verschiedenen Rufzeichen an einem Rechner trennen ihn. + +- **Profilwahl beim Start:** Mit nur einem Profil fragt KST4Contest beim Start nichts und verhält sich unverändert. Ab zwei Profilen erscheint eine kleine Auswahl mit vorausgewähltem letzten Profil; Enter oder Doppelklick starten sofort. Der Aufrufparameter `--profile=` überspringt die Auswahl. + +- **Profilwechsel im laufenden Betrieb:** **File → Switch operator profile...** trennt die Verbindung und baut die Oberfläche mit den Einstellungen des gewählten Profils neu auf, ohne Programmneustart. + +### Geändert + +- **Zwischenspeicher der Geländeprofile getrennt:** Berechnete Geländeprofile liegen jetzt in der eigenen, gemeinsam genutzten Datei `terrainprofilecache.db` und werden nach Besitzer getrennt gespeichert. Bisher wurde der gesamte Zwischenspeicher gelöscht, sobald sich Rufzeichen oder Locator änderten; bei einem Profilwechsel wäre damit jedes berechnete Profil verloren gegangen. + +- **Rufzeichen-Vorgabe ist leer:** Fehlt in der `preferences.xml` ein Login-Rufzeichen, bleibt das Feld jetzt leer, statt auf ein im Programm hinterlegtes Rufzeichen zurückzufallen. Ein neu angelegtes Profil startet damit bewusst ohne Anmeldedaten. + +- **Dark Mode pro Profil:** Im Reiter **GUI** legt jedes Operator-Profil unter **Design** fest, ob KST4Contest hell oder dunkel startet. Die Menüeinträge unter **Windows** schalten weiterhin schnell um, gelten aber nur für die laufende Sitzung. Das Farbschema erfasst jetzt auch das Update-Fenster und die Liste der Top-Kandidaten. + +### Behoben + +- **Einheitliche Schriftgröße:** Unter macOS und Linux verwendet JavaFX eine etwas größere Standardschrift als unter Windows. Dadurch wurden Beschriftungen in fest bemessenen Bedienelementen abgeschnitten. KST4Contest verwendet jetzt auf allen Systemen dieselbe Grundschriftgröße; unter Windows ändert sich nichts. + +- **Dark Mode nach dem Neustart:** Das Hauptfenster startete immer hell, auch wenn zuletzt der Dark Mode aktiv war, während die Stationskarte dunkel blieb. Jetzt starten alle Fenster einheitlich mit dem Farbschema des Profils. + +- **Freigegebene Hintergrundressourcen:** Der ON4KST-Überwachungsthread, der Sked-Erinnerungs-Scheduler, der Reachability-Executor, der PSTRotator-Wiederholungs-Scheduler und der Kachel-Proxy der Karte werden beim Schließen des Chatcontrollers freigegeben. Bisher liefen sie bis zum Programmende weiter. + +### Hinweise zur Aktualisierung + +- Bestehende Installationen werden **nicht** verändert: `preferences.xml` und `praktiKST.db` bleiben genau dort liegen, wo sie sind, und werden zum Profil **Default**. Es wird keine Datei verschoben oder kopiert. +- Eine Profil-Registry entsteht erst beim Anlegen des zweiten Profils. Wer nur ein Profil benutzt, merkt von der Änderung nichts. +- Eine Rückkehr zu einer älteren KST4Contest-Version bleibt möglich; sie findet ihre Dateien unverändert vor. +- Passwörter stehen weiterhin im Klartext in der `preferences.xml` des jeweiligen Profils. Profile trennen die Konfiguration, sie sind kein Zugriffsschutz. + +--- + ## v1.43.1 (2026-09-03) **Korrigierte Versionsmetadaten** diff --git a/github_docs/de-Funktionen.md b/github_docs/de-Funktionen.md index 09d2fef6..f1259ad9 100644 --- a/github_docs/de-Funktionen.md +++ b/github_docs/de-Funktionen.md @@ -318,12 +318,101 @@ KST4Contest meldet sich mit einem lokalen Login-Rufzeichen und Passwort einmal b ## Dark Mode (ab v1.26) -Aktivierbar über **Windows → Use dark mode design**. Mit **Windows → Use default mode design** wird wieder auf das normale helle Farbschema umgeschaltet. +Welches Farbschema beim Start gilt, wird pro Operator-Profil im Reiter **GUI** unter **Design** festgelegt. Über **Windows → Use dark mode design** und **Windows → Use default mode design** lässt sich für die laufende Sitzung schnell umschalten. Die grüne Altersskala der Privatnachrichten bleibt in beiden Darstellungen erhalten. Textfarbe, normale Tabellenfarbe und die separate Hervorhebung eigener Nachrichten folgen dem jeweils geladenen Standarddesign. --- +## Eigene Farben (ab v1.50) + +Der Reiter **Colours** im Einstellungsfenster setzt sechs Farben pro Entwurf und **pro +Operator-Profil**: Fläche, Fensterfläche, Feldinneres, Text, Akzent und Trennlinie. Tag und +Abend sind getrennt — eine Änderung am Abendentwurf lässt den Tagentwurf unberührt. + +Eine Farbe wird als sechsstellige Hexzahl mit führendem Rautezeichen eingetragen, etwa +`#3C7A4B`, und gilt **sofort in allen offenen Fenstern**. Es gibt keinen „noch nicht +gespeichert"-Zustand. + +**Sie überlebt den Neustart aber erst nach „Save settings".** Das ist derselbe Vertrag wie bei +jeder anderen Einstellung — nur ist dies der einzige Reiter, dessen Wirkung man sofort in +allen Fenstern sieht, und „es sah richtig aus, also ist es gespeichert" ist hier der +naheliegende Fehlschluss. Der Reiter sagt es deshalb auch selbst. + +Was nicht als Farbe lesbar ist, wird abgelehnt und das Feld springt zurück; ein Hinweisfenster +sagt, warum. + +### Die drei Wege zurück + +| Knopf | Wirkung | +|---|---| +| **Back to how it was** | die Palette, die beim Öffnen des Reiters galt — einschließlich einer damals schon vorhandenen Änderung | +| **Discard my changes** | leert die eigenen Änderungen dieses Entwurfs; es gilt wieder die Datei oder die Auslieferung | +| **Reset to the shipped colours** | setzt alle sechs Rollen auf die ausgelieferten Werte, auch wenn eine eigene Stilvorlage vorhanden ist | + +**Der Knopf „Reset to the shipped colours" ist immer in den ausgelieferten Farben gezeichnet, +ganz gleich, was eingestellt ist.** Das ist Absicht: wer Text und Fläche auf dasselbe Schwarz +stellt, sieht die übrigen Knöpfe nicht mehr — auch die nicht, mit denen er es zurücknehmen +könnte. Dieser eine nimmt die kaputte Palette nicht an und bleibt deshalb lesbar. Dass er bei +einer stark angepassten Palette fremd aussieht, macht ihn auffindbar. + +**Alle drei haben ein Tastenkürzel**, als zweite Absicherung für den Fall, dass gar nichts mehr +zu lesen ist. Sie wirken, solange der Reiter offen ist, auch wenn der Schreibzeiger in einem +der Farbfelder steht: + +| Taste | Rückweg | +|---|---| +| **Ctrl+Z** | Zurück zum Stand von vorher | +| **Ctrl+D** | Meine Änderungen verwerfen | +| **Ctrl+R** | Auf Auslieferung zurücksetzen | + +„Zurück zum Stand von vorher" stellt **beide** Entwürfe her, nicht nur den gerade +sichtbaren — wer eine Farbe am Tag ändert, auf Abend umschaltet und dort noch eine ändert, +nimmt mit diesem Knopf beides zurück. + +### Woher eine Farbe kommt + +Hinter jedem Feld steht, woher der geltende Wert stammt: + +| Angabe | Bedeutung | +|---|---| +| *shipped* | aus dem ausgelieferten Entwurf | +| *from file* | aus der eigenen Stilvorlage im Profilverzeichnis | +| *changed* | hier im Reiter gesetzt | + +Eine Einstellung im Reiter überstimmt immer die Datei, und die Datei überstimmt die +Auslieferung — Rolle für Rolle. + +### Lesbarkeitshinweis + +Liegt ein Paar, das tatsächlich übereinanderliegt — Text auf Fläche, Text im Feld, Akzent auf +Fläche — schlechter als im ausgelieferten Entwurf und unter dem WCAG-AA-Wert von 4,5, erscheint +ein Hinweis mit beiden Verhältnissen. **Gespeichert wird trotzdem:** eine harte Kombination im +Contest kann gewollt sein. + +### Die Stilvorlage von Hand bearbeiten + +Wer mehr als die sechs Rollen ändern will, lässt sich mit **Write this design's stylesheet into +my profile** die ausgelieferte Vorlage ins Profilverzeichnis schreiben. Der Reiter nennt den +Pfad. Für das Wurzelprofil ist das `~/.praktiKST/KST4ContestDefaultDay.css` beziehungsweise +`…Evening.css`, für jedes weitere Profil `profiles//` darunter. + +**Eine vorhandene Datei wird nie überschrieben** — der Knopf meldet dann nur, dass sie schon da +ist. Änderungen an der Datei gelten nach einem Neustart. Eine unlesbare oder fehlerhafte Datei +verhindert den Start nicht: die betroffene Rolle fällt auf die Auslieferung zurück. + +**Beim Wurzelprofil liegen diese beiden Dateien schon.** KST4Contest legt sie seit Jahren beim +Start an; bis Version 1.50 hat sie nur niemand gelesen. Deshalb steht dort bei den meisten +Rollen von Anfang an *from file* und nicht *shipped*, und der Knopf meldet, dass die Datei +bereits da ist. Inhaltlich ist es die ausgelieferte Vorlage — es sieht also aus wie +*shipped*, weil es dasselbe ist. + +Wer dort `-fx-base` ändert, bekommt auch die Fensterfläche mit: KST4Contest leitet sie daraus +ab, genau wie JavaFX es getan hat. Wer beide getrennt haben will, nennt `-fx-background` +ausdrücklich — oder setzt sie oben im Reiter, wo die beiden immer unabhängig bleiben. + +--- + ## Opposite Station Multi-Callsign Login-Tagging (ab v1.26) Unterstützung für Gegenstationen, die mit mehreren vollständigen sichtbaren Rufzeichenvarianten gleichzeitig im Chat aktiv sind (z. B. Expedition-Setups). Vollständiges Rufzeichen und Chat-Kategorie bleiben getrennte Teilnehmeridentitäten; Worked-, Band- und Prioritätsdaten werden über das Basisrufzeichen gemeinsam ausgewertet. @@ -993,11 +1082,11 @@ Sofern die gespeicherten Werte gültig sind, verwendet KST4Contest zunächst die - 1.234 Pixel Breite und - 768 Pixel Höhe. -Als verfügbare Fläche verwendet KST4Contest nicht die vollständige Bildschirmauflösung, sondern den von JavaFX gemeldeten sichtbaren Bereich des primären Bildschirms. Taskleiste, Dock und vergleichbare Bereiche des Betriebssystems sind darin bereits ausgenommen. +Als verfügbare Fläche verwendet KST4Contest nicht die vollständige Bildschirmauflösung, sondern den vom Betriebssystem gemeldeten nutzbaren Bereich des primären Bildschirms. Taskleiste, Dock und vergleichbare Bereiche des Betriebssystems sind darin bereits ausgenommen. Von dieser Fläche wird zusätzlich ein Sicherheitsabstand von 40 Pixeln abgezogen. Überschreitet die gespeicherte Breite oder Höhe den verbleibenden Platz, wird nur der betreffende Wert verkleinert. -Nachdem die Oberfläche mit dieser Scene-Größe aufgebaut wurde, prüft KST4Contest zusätzlich das tatsächliche native Fenster einschließlich seiner vom Betriebssystem erzeugten Rahmen und Titelleiste. Das Fenster wird bei Bedarf noch einmal verkleinert oder in den sichtbaren Bereich verschoben. +Das Fenster wird dann in dieser Größe geöffnet. Ein Fenstermanager kann sie überschreiben — ein Tiling-Fenstermanager tut das immer —, und KST4Contest speichert die Größe, die das Fenster tatsächlich erhält. Damit werden zwei unterschiedliche Fälle abgefangen: @@ -1017,3 +1106,60 @@ Die Prüfung verwendet immer den **primären Bildschirm**. Sie stellt nicht die Die automatische Größenbegrenzung gilt derzeit außerdem nur für das Hauptfenster. Das Einstellungsfenster, das separate Cluster- und QSO-Monitorfenster sowie weitere Zusatzfenster verwenden weiterhin ihre jeweils gespeicherten Größen, ohne dieselbe zusätzliche Prüfung gegen den primären Bildschirm. Im Klartext: Die Schutzfunktion verhindert vor allem, dass das zentrale Hauptfenster nach einem Wechsel auf einen kleineren Bildschirm unbenutzbar startet. Sie ist keine vollständige Verwaltung aller Fensterpositionen in einem wechselnden Mehrmonitor-Setup. + +--- + +## Sprache der Oberfläche (ab v1.50) + +Die Oberfläche spricht Deutsch oder Englisch. Die Wahl sitzt im Einstellungsfenster im Reiter +**GUI**, im letzten Abschnitt **Language**, und gilt **pro Operatorprofil** — an einer +Mehrmann-Station können zwei Operateure zwei Sprachen haben. + +Drei Werte stehen zur Wahl: + +| Wert | Bedeutung | +|---|---| +| **Systemsprache** | die Sprache des Betriebssystems; ist das keine, für die Texte vorliegen, dann Englisch | +| **DE** | Deutsch | +| **EN** | Englisch | + +**Ein Wechsel wirkt sofort in allen offenen Fenstern** — Hauptfenster, Einstellungen, Karte und +Monitor zugleich, ohne Neustart und ohne ein Fenster zu schließen. Dauerhaft wird die Wahl wie +jede andere Einstellung mit **Einstellungen speichern**. + +### Was nicht übersetzt wird, und warum + +Drei Sorten Text bleiben unverändert, in jeder Sprache: + +- **Alles, was an den ON4KST-Server geht.** Protokollbefehle und Chat-Befehle wie `/CQ` oder + `/AWAY` würden übersetzt die Verbindung brechen oder vom Server nicht verstanden. +- **Alles, was an andere Funker geht.** Deine Bakentexte, Antworttexte, Textbausteine und + Kurztasten bleiben so, wie du sie eingetragen hast. Sie stehen in der gespeicherten + Konfiguration deines Profils; sie zu übersetzen würde bestehende Profile verändern. +- **Funkerkürzel in der Oberfläche.** QRA, QRG, QTF, QRB, Tropo, LOC, wkd, NOT QRV, LOS, + Fresnel, Sked — die sind international und lesen sich in beiden Sprachen gleich. + +Drei Tests wachen darüber, und zwar an der Ausgabe statt an der Textdatei: die Protokollrahmen +werden unter drei Locales gebaut und verglichen, sämtliche Vorgabewerte der Konfiguration +werden über Reflexion verglichen, und kein Wert in einer Übersetzungsdatei darf ein +Protokollbefehl sein. + +### Eine Sprache beitragen + +Die Texte liegen als gewöhnliche Textdateien unter `app-desktop/src/main/i18n/`, eine je +Sprache. Wer eine weitere beitragen will, kopiert `strings_en.properties` nach +`strings_.properties` und übersetzt die Werte rechts vom Gleichheitszeichen. Kein Kotlin, +kein Gradle. + +**Eine unvollständige Übersetzung ist willkommen** — ein nicht übersetzter Schlüssel erscheint +englisch statt zu fehlen. Eine *fehlerhafte* bricht dagegen den Bau ab: ein Schlüssel, den die +englische Grundlage nicht kennt, oder ein Platzhalter wie `{0}`, der in der Übersetzung fehlt +und damit stillschweigend Daten verschluckt. + +`./gradlew :app-desktop:classes` baut und meldet jeden Fehler mit dem Dateinamen. Was noch +fehlt, schreibt der Bau als Arbeitsblatt nach +`app-desktop/build/generated/i18n/todo/strings_.todo.properties` — die fehlenden +Schlüssel mit dem englischen Text als Wert, zum Ausfüllen. + +Deutsch wird durch einen Test auf Vollständigkeit gehalten, weil es ausgeliefert wird. Eine +beigetragene Sprache nicht. diff --git a/github_docs/de-Konfiguration.md b/github_docs/de-Konfiguration.md index 1bbaa949..12a4093a 100644 --- a/github_docs/de-Konfiguration.md +++ b/github_docs/de-Konfiguration.md @@ -901,9 +901,66 @@ Anzeige und Herleitung: [Gearbeitete Rufzeichen, neue Bänder und neue Großfeld --- +## Operator-Profile (ab v1.50) + +Mehrere Operateure an einem Rechner brauchen unterschiedliche Rufzeichen, Locators und Layouts. Ein Operator-Profil bündelt genau das: **jedes Profil hat seine eigene `preferences.xml` und damit seine eigenen fachlichen Einstellungen und seinen eigenen Layoutstand.** + +### Wo die Profile liegen + +| Profil | Einstellungen | Gearbeitete Stationen | +|---|---|---| +| **Default** | `~/.praktiKST/preferences.xml` | `~/.praktiKST/praktiKST.db` | +| weitere Profile | `~/.praktiKST/profiles//preferences.xml` | je nach Einstellung gemeinsam oder `~/.praktiKST/profiles//praktiKST.db` | + +Unter Windows entsprechend unterhalb von `%USERPROFILE%\.praktiKST\`. + +Alle übrigen Daten bleiben gemeinsam: Klangdateien, Farbschemata, DEM- und Terrainpakete, der Zwischenspeicher der Geländeprofile (`terrainprofilecache.db`), das Fehlerprotokoll und die Versionsinformationen. + +Das Profil **Default** benutzt weiterhin genau die Dateien, die eine bestehende Installation schon hat. **Bei der Aktualisierung auf v1.50 wird keine Datei verschoben, kopiert oder umgeschrieben.** Wer eine ältere KST4Contest-Version wieder installiert, findet seine Konfiguration und seine gearbeiteten Stationen unverändert vor. + +### Gemeinsame oder eigene gearbeitete Stationen + +Beim Anlegen eines Profils wird entschieden, woher dessen Worked-, NOT-QRV- und Großfeld-Daten kommen: + +- **Eigene gearbeitete Stationen** (Vorgabe): Das Profil bekommt eine eigene, zunächst leere Datenbank. Sinnvoll, wenn sich zwei OMs mit verschiedenen Rufzeichen einen Rechner teilen. +- **Gemeinsame Stationsdatenbank**: Das Profil benutzt `~/.praktiKST/praktiKST.db`, also dieselbe Datenbank wie das Profil **Default**. Das ist der Fall der **Multi-OP-Station**: es gibt nur ein Stationslog, also soll auch der Worked-Status für alle Operateure derselbe sein. + +Ein Wechsel zwischen beiden Einstellungen verschiebt keine Daten. Bereits gesammelte Worked-Daten bleiben dort liegen, wo sie entstanden sind. Der Drei-Tage-Ablauf und die Reset-Schaltfläche wirken jeweils auf die Datenbank des gerade aktiven Profils. + +### Profile verwalten + +Der Reiter **Profiles** im Einstellungsfenster zeigt alle Profile mit Name, Art der Worked-Daten und letzter Benutzung. + +- **New profile...** legt ein Profil an. Es startet **ohne Rufzeichen und ohne Passwort**; beides wird anschließend im Reiter **Station** eingetragen. +- **Duplicate...** übernimmt die komplette Konfiguration des gewählten Profils — Antenne, Locator, Layout, Beacon, Integrationen — **außer Rufzeichen und Passwort**. Gearbeitete Stationen werden nie mitkopiert. +- **Rename...** ändert nur den angezeigten Namen. Verzeichnisse und Dateien bleiben unberührt. +- **Delete...** entfernt das Profilverzeichnis endgültig. Das Profil **Default** und das gerade aktive Profil lassen sich nicht löschen. Bei einem Profil mit gemeinsamer Stationsdatenbank bleibt diese unangetastet. +- **Change worked stations...** schaltet zwischen gemeinsamer und eigener Datenbank um. +- **Switch to selected profile...** wechselt das Profil im laufenden Betrieb. + +### Profilwahl beim Start + +- Solange nur **ein** Profil existiert, fragt KST4Contest beim Start **nichts** und startet wie bisher. Es wird auch keine Profil-Registry angelegt. Erst das Anlegen des zweiten Profils erzeugt `~/.praktiKST/profiles.xml`. +- Ab **zwei** Profilen erscheint beim Start eine kleine Auswahl. Das zuletzt benutzte Profil ist vorausgewählt, **Enter** oder ein Doppelklick starten sofort. +- Der Aufrufparameter `--profile=` überspringt die Auswahl und startet direkt das genannte Profil. Erlaubt sind die Profil-ID und der angezeigte Name, Groß- und Kleinschreibung spielen keine Rolle. Ein unbekannter Name führt zu einem Hinweis und danach zur normalen Auswahl — der Start wird nie verweigert. + +### Profil im laufenden Betrieb wechseln + +**File → Switch operator profile...** oder die Schaltfläche im Reiter **Profiles** wechseln ohne Programmneustart. Nach einer Sicherheitsabfrage wird die ON4KST-Verbindung getrennt und die Oberfläche mit den Einstellungen und dem Layout des gewählten Profils neu aufgebaut. Der Layoutstand des bisherigen Profils wird vorher gesichert; noch nicht mit **Save Settings** bestätigte fachliche Änderungen gehen dabei verloren. + +Sobald mehr als ein Profil existiert, zeigt die Titelzeile des Hauptfensters zusätzlich den Profilnamen. + +### Hinweis zu Passwörtern + +Das ON4KST-Passwort steht wie bisher im Klartext in der `preferences.xml` des jeweiligen Profils. Auf einem gemeinsam genutzten Rechner kann jeder, der Zugriff auf das Benutzerkonto hat, die Passwörter aller Profile lesen. Profile trennen die Konfiguration, sie sind **kein** Zugriffsschutz. + +--- + ## Dark Mode (ab v1.26) -Der Dark Mode wird über **Windows → Use dark mode design** aktiviert. Mit **Windows → Use default mode design** wird wieder das normale helle Farbschema geladen. +Mit welchem Farbschema KST4Contest startet, legt jedes Operator-Profil selbst fest: im Reiter **GUI** unter **Design** mit **Light mode** oder **Dark mode**. Die Auswahl wirkt sofort und wird mit **Save Settings** in der `preferences.xml` des Profils gespeichert. + +Für einen kurzen Wechsel während des Betriebs gibt es **Windows → Use dark mode design** und **Windows → Use default mode design**. Diese Umschaltung gilt nur bis zum nächsten Start oder Profilwechsel; danach gilt wieder die Einstellung im Reiter **GUI**. --- diff --git a/github_docs/en-Changelog.md b/github_docs/en-Changelog.md index af1cb47b..3f267d29 100644 --- a/github_docs/en-Changelog.md +++ b/github_docs/en-Changelog.md @@ -8,6 +8,47 @@ Published Stable versions and their application packages are available under [Gi --- +## v1.50 (in development) + +**Operator profiles** + +Several operators sharing one computer can now use their own callsigns, locators and layouts without overwriting each other's configuration. This implements [Issue #57](https://github.com/praktimarc/kst4contest/issues/57). + +### New + +- **Operator profiles:** every profile has its own `preferences.xml`, and therefore its own settings and its own window layout. Profiles are managed on the new **Profiles** tab of the settings window: create, duplicate, rename, delete and activate. + +- **Shared or own worked stations:** each profile decides whether it gets its own worked database or uses the common station database. A multi operator station with a single station log shares the worked state; two operators with different callsigns on one computer keep it apart. + +- **Choosing a profile at startup:** with only one profile, KST4Contest asks nothing at startup and behaves exactly as before. From two profiles on, a small selection appears with the last used profile preselected; Enter or a double click start immediately. The `--profile=` argument skips the selection. + +- **Switching profiles while running:** **File > Switch operator profile...** closes the connection and rebuilds the user interface with the settings of the selected profile, without restarting the program. + +### Changed + +- **The terrain profile cache is separate:** computed terrain profiles now live in their own shared file `terrainprofilecache.db` and are stored per owner. Previously the whole cache was dropped whenever the callsign or locator changed, which would have discarded every computed profile on each profile switch. + +- **The default login callsign is empty:** if `preferences.xml` has no login callsign, the field now stays empty instead of falling back to a callsign compiled into the program. A newly created profile therefore deliberately starts without credentials. + +- **Dark mode per profile:** on the **GUI** tab each operator profile sets under **Design** whether KST4Contest starts light or dark. The entries in the **Windows** menu still switch quickly, but only for the running session. The colour scheme now also covers the update window and the top candidates list. + +### Fixed + +- **Consistent font size:** on macOS and Linux JavaFX uses a slightly larger default font than on Windows, which cut off labels in fixed-size controls. KST4Contest now uses the same base font size on all systems; nothing changes on Windows. + +- **Dark mode after a restart:** the main window always started light, even if dark mode had been active, while the station map stayed dark. All windows now start consistently with the profile's colour scheme. + +- **Background resources are released:** the ON4KST supervisor thread, the sked reminder scheduler, the reachability executor, the PSTRotator retry scheduler and the map tile proxy are released when the chat controller is closed. They used to keep running until the program ended. + +### Upgrade notes + +- Existing installations are **not** modified: `preferences.xml` and `praktiKST.db` stay exactly where they are and become the **Default** profile. No file is moved or copied. +- A profile registry only appears when the second profile is created. Anyone using a single profile will not notice the change. +- Going back to an older KST4Contest release stays possible; it finds its files unchanged. +- Passwords are still stored in clear text in each profile's `preferences.xml`. Profiles separate configuration; they are not an access control mechanism. + +--- + ## v1.43.1 (2026-09-03) **Corrected version metadata** diff --git a/github_docs/en-Configuration.md b/github_docs/en-Configuration.md index d763ad1b..fa90c9db 100644 --- a/github_docs/en-Configuration.md +++ b/github_docs/en-Configuration.md @@ -958,9 +958,66 @@ Display and derivation: [Worked Callsigns, New Bands and New Grid Squares](en-Fe --- +## Operator Profiles (from v1.50) + +Several operators sharing one computer need different callsigns, locators and layouts. An operator profile bundles exactly that: **every profile has its own `preferences.xml`, and therefore its own settings and its own window layout.** + +### Where the profiles live + +| Profile | Settings | Worked stations | +|---|---|---| +| **Default** | `~/.praktiKST/preferences.xml` | `~/.praktiKST/praktiKST.db` | +| additional profiles | `~/.praktiKST/profiles//preferences.xml` | shared, or `~/.praktiKST/profiles//praktiKST.db` | + +On Windows the same files live below `%USERPROFILE%\.praktiKST\`. + +Everything else stays shared: audio files, colour schemes, DEM and terrain packages, the terrain profile cache (`terrainprofilecache.db`), the error log and the version information. + +The **Default** profile keeps using exactly the files an existing installation already has. **Upgrading to v1.50 moves, copies and rewrites nothing.** Anyone reinstalling an older KST4Contest release finds their configuration and their worked stations unchanged. + +### Shared or own worked stations + +When a profile is created you decide where its worked, NOT-QRV and grid data come from: + +- **Own worked stations** (default): the profile gets its own, initially empty database. This is what two operators with different callsigns sharing a private computer want. +- **Common station database**: the profile uses `~/.praktiKST/praktiKST.db`, the same database as the **Default** profile. This is the **multi operator station** case: there is only one station log, so the worked state should be the same for every operator. + +Switching between the two settings moves no data. Worked data already collected stays where it was created. The three day expiry and the reset button always act on the database of the currently active profile. + +### Managing profiles + +The **Profiles** tab in the settings window lists all profiles with their name, the kind of worked data they use and when they were last used. + +- **New profile...** creates a profile. It starts **without callsign and password**; both are entered afterwards on the **Station** tab. +- **Duplicate...** copies the complete configuration of the selected profile - antenna, locator, layout, beacon, integrations - **except callsign and password**. Worked stations are never copied. +- **Rename...** changes the displayed name only. Folders and files are untouched. +- **Delete...** removes the profile folder permanently. The **Default** profile and the currently active profile cannot be deleted. For a profile using the common station database, that database is left untouched. +- **Change worked stations...** switches between the common and an own database. +- **Switch to selected profile...** changes the profile while the application is running. + +### Choosing a profile at startup + +- As long as only **one** profile exists, KST4Contest asks **nothing** at startup and starts exactly as before. No profile registry is created either; only creating the second profile writes `~/.praktiKST/profiles.xml`. +- From **two** profiles on, a small selection appears at startup. The last used profile is preselected, and **Enter** or a double click start immediately. +- The `--profile=` argument skips the selection and starts the named profile directly. Both the profile ID and the displayed name are accepted, case insensitively. An unknown name produces a note and then the normal selection - startup is never refused. + +### Switching profiles while running + +**File > Switch operator profile...**, or the button on the **Profiles** tab, switches without restarting the program. After a confirmation the ON4KST connection is closed and the user interface is rebuilt with the settings and layout of the selected profile. The layout of the previous profile is saved first; settings not yet confirmed with **Save Settings** are lost. + +Once more than one profile exists, the main window title also shows the profile name. + +### A note about passwords + +As before, the ON4KST password is stored in clear text in the `preferences.xml` of each profile. On a shared computer, anyone with access to the user account can read the passwords of all profiles. Profiles separate configuration; they are **not** an access control mechanism. + +--- + ## Dark Mode (from v1.26) -Enable Dark Mode through **Windows → Use dark mode design**. Use **Windows → Use default mode design** to restore the normal light colour scheme. +Each operator profile sets its own startup colour scheme: on the **GUI** tab under **Design**, choose **Light mode** or **Dark mode**. The choice takes effect immediately and is stored in the profile's `preferences.xml` with **Save Settings**. + +For a quick change during operation, use **Windows → Use dark mode design** and **Windows → Use default mode design**. This switch only lasts until the next start or profile switch; after that the setting on the **GUI** tab applies again. --- diff --git a/github_docs/en-Features.md b/github_docs/en-Features.md index 6ef74616..2c4f1b43 100644 --- a/github_docs/en-Features.md +++ b/github_docs/en-Features.md @@ -317,12 +317,99 @@ KST4Contest signs in to ON4KST once with one local login callsign and password. ## Dark Mode (from v1.26) -Enable it through **Windows → Use dark mode design**. Use **Windows → Use default mode design** to return to the normal light colour scheme. +Each operator profile sets its startup colour scheme on the **GUI** tab under **Design**. **Windows → Use dark mode design** and **Windows → Use default mode design** switch quickly for the running session. The green private-message age scale remains available in both designs. Text colour, normal table colour and the separate highlight for locally sent messages follow the selected built-in design. --- +## Own Colours (from v1.50) + +The **Colours** tab in the settings window sets six colours per design and **per operator +profile**: surface, window surface, field interior, text, accent and separator line. Daylight +and evening are separate — a change to the evening design leaves the daylight one untouched. + +A colour is entered as six hexadecimal digits with a leading hash, for example `#3C7A4B`, and +applies **immediately in every open window**. There is no "not yet applied" state. + +**It survives a restart only after Save settings.** That is the same contract as every other +setting — but this is the only tab whose effect is visible at once in every window, and "it +looked right, so it must be stored" is the easy wrong conclusion here. The tab says so itself +for that reason. + +Anything that cannot be read as a colour is refused and the field snaps back; a notice window +says why. + +### The three ways back + +| Button | What it does | +|---|---| +| **Back to how it was** | the palette in force when the tab was opened, including a change already present then | +| **Discard my changes** | empties this design's own changes, so the file or the shipped design applies again | +| **Reset to the shipped colours** | sets all six roles to the shipped values, even when an own stylesheet is present | + +**The "Reset to the shipped colours" button is always drawn in the shipped colours, whatever +has been set.** This is deliberate: an operator who sets text and surface to the same black can +no longer see any other button — including the ones that would undo it. This one does not take +the broken palette and therefore stays readable. That it looks out of place under a heavily +customised palette is what makes it findable. + +**All three have a keyboard shortcut**, as a second safety net for when nothing can be read at +all. They work while the tab is open, including when the caret sits in one of the colour +fields: + +| Key | Way back | +|---|---| +| **Ctrl+Z** | Back to how it was | +| **Ctrl+D** | Discard my changes | +| **Ctrl+R** | Reset to the shipped colours | + +"Back to how it was" restores **both** designs, not only the one on screen — change a colour +in daylight, switch to evening, change one there, and this button undoes both. + +### Where a colour comes from + +Each field says where its value in force came from: + +| Label | Meaning | +|---|---| +| *shipped* | from the shipped design | +| *from file* | from the own stylesheet in the profile directory | +| *changed* | set here in the tab | + +A setting in the tab always overrides the file, and the file overrides the shipped design — +role by role. + +### Readability notice + +When a pair that actually sits on top of each other — text on the surface, text inside a field, +accent on the surface — reads worse than the shipped design makes it and below the WCAG AA +value of 4.5, a notice appears with both ratios. **It is saved anyway:** a hard combination can +be deliberate in a contest. + +### Editing the stylesheet by hand + +To change more than the six roles, **Write this design's stylesheet into my profile** writes +the shipped template into the profile directory. The tab names the path. For the root profile +that is `~/.praktiKST/KST4ContestDefaultDay.css` or `…Evening.css`; every other profile gets it +under `profiles//`. + +**An existing file is never overwritten** — the button then only reports that it is already +there. Changes to the file take effect after a restart. An unreadable or faulty file does not +prevent startup: the role concerned falls back to the shipped design. + +**For the root profile these two files are already present.** KST4Contest has been writing +them at startup for years; until release 1.50 nothing read them. So most roles there show +*from file* rather than *shipped* from the outset, and the button reports that the file is +already there. Its content is the shipped template — so it looks like *shipped* because it is +the same thing. + +Changing `-fx-base` there also changes the window surface: KST4Contest derives it from the +base, exactly as JavaFX did. To keep the two apart, name `-fx-background` explicitly — or set +them in the tab above, where the two roles always stay independent. + +--- + ## Opposite Station Multi-Callsign Login Tagging (from v1.26) Support for remote stations which are active in the chat under several complete visible callsign variants at the same time (e.g. expedition setups). The complete callsign and chat category remain separate participant identities, while Worked, band and priority data are shared through the base callsign. @@ -913,7 +1000,7 @@ The **Mechanisms** indication lists propagation mechanisms which may be consiste Aircraft Scatter information is not currently coupled to the terrain-profile calculation. AirScout data and the path analysis may both describe the same remote station, but they remain separate assessments. -OpenStreetMap tiles and the active elevation provider require an Internet connection. Leaflet and the map application itself are bundled locally, and tile requests pass through a local proxy, but this proxy is not a permanent offline map store. +OpenStreetMap tiles and the active elevation provider require an Internet connection. Tiles are fetched directly and cached only for the running session, so this is not a permanent offline map store. Offline elevation data (DEM) is a separate matter and does work without a connection. In plain terms: the analysis helps to identify plausible paths, obvious obstructions and incorrect assumptions. It does not replace propagation experience or a real signal. @@ -974,11 +1061,11 @@ If the stored values are valid, KST4Contest initially uses the last saved height - 1,234 pixels wide and - 768 pixels high. -KST4Contest does not use the complete screen resolution as the available area. It uses the visual bounds reported by JavaFX for the primary screen. Taskbars, docks and similar operating-system areas are already excluded from these bounds. +KST4Contest does not use the complete screen resolution as the available area. It uses the usable bounds the operating system reports for the primary screen. Taskbars, docks and similar operating-system areas are already excluded from these bounds. An additional safety margin of 40 pixels is subtracted. If the stored width or height exceeds the remaining space, only the affected value is reduced. -After the user interface has been built with this content size, KST4Contest checks the complete native operating-system window, including its title bar and borders. The window is reduced or moved into the visible area again if necessary. +The window is then opened at that size. A window manager may override it — a tiling window manager always does — and the size KST4Contest stores is the one the window actually ends up with. This catches two different cases: @@ -998,3 +1085,57 @@ The check always uses the **primary screen**. It does not restore the previous p The automatic size restriction currently applies to the main window only. The settings window, the separate cluster and QSO monitor window and other auxiliary windows continue to use their stored sizes without the same additional check against the primary screen. In plain terms: the protection mainly prevents the central main window from becoming unusable after moving to a smaller display. It is not a complete window-position manager for a changing multi-monitor setup. + +--- + +## Interface Language (from v1.50) + +The interface speaks English or German. The choice sits in the settings window on the **GUI** +tab, in the last section **Language**, and applies **per operator profile** — at a multi +operator station two operators can have two languages. + +Three values are offered: + +| Value | Meaning | +|---|---| +| **System language** | the operating system's language; English when no texts exist for it | +| **DE** | German | +| **EN** | English | + +**A change applies at once in every open window** — main window, settings, map and monitor +together, with no restart and without closing anything. The choice is kept permanently the +same way as every other setting, with **Save settings**. + +### What is not translated, and why + +Three kinds of text stay as they are, in every language: + +- **Anything that goes to the ON4KST server.** Protocol frames and chat commands such as + `/CQ` or `/AWAY` would break the connection or not be understood if they were translated. +- **Anything that goes to other radio amateurs.** Your beacon texts, auto answers, snippets + and shortcuts stay exactly as you entered them. They live in your profile's stored + configuration; translating them would alter existing profiles. +- **Amateur radio shorthand in the interface.** QRA, QRG, QTF, QRB, Tropo, LOC, wkd, NOT QRV, + LOS, Fresnel, Sked — these are international and read the same either way. + +Three tests guard this, and they check the output rather than the text files: the protocol +frames are built under three locales and compared, every configuration default is compared by +reflection, and no value in a translation file may be a protocol command. + +### Contributing a language + +The texts are ordinary text files under `app-desktop/src/main/i18n/`, one per language. To +contribute another, copy `strings_en.properties` to `strings_.properties` and translate +the values to the right of the equals sign. No Kotlin, no Gradle. + +**A partial translation is welcome** — an untranslated key appears in English rather than +going missing. An *incorrect* one fails the build instead: a key the English base does not +know, or a placeholder such as `{0}` missing from the translation, which would silently drop +whatever it was carrying. + +`./gradlew :app-desktop:classes` builds and reports every mistake by file name. What is still +missing is written as a worksheet to +`app-desktop/build/generated/i18n/todo/strings_.todo.properties` — the missing keys with +the English text as the value, ready to fill in. + +German is held complete by a test because it is shipped. A contributed language is not. diff --git a/github_docs/en-User-Interface.md b/github_docs/en-User-Interface.md index d69ff8e7..7feda25b 100644 --- a/github_docs/en-User-Interface.md +++ b/github_docs/en-User-Interface.md @@ -486,8 +486,9 @@ Functions which communicate with the server are available only after the ON4KST - **Hide cluster / stranger QSOs** and **Show cluster / stranger QSOs** hide or restore the separate cluster and QSO monitor window. - **hide options** and **show options** hide or restore the settings window. -- **Use dark mode design** activates the dark colour scheme. -- **Use default mode design** restores the standard light colour scheme. +- **Use dark mode design** activates the dark colour scheme for the running session. +- **Use default mode design** restores the standard light colour scheme for the running session. + The startup colour scheme is set per profile on the **GUI** settings tab under **Design**. - **Show / hide station map** opens or closes the separate station-map and path-analysis window. --- diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 00000000..05f225af --- /dev/null +++ b/gradle.properties @@ -0,0 +1,8 @@ +version=1.50.0-nightly +# nativeDistributions requires MAJOR.MINOR.PATCH with digits only. MSI and DMG +# reject a qualifier, so the nightly suffix from `version` cannot be used here. +composePackageVersion=1.50.0 +group=de.x08 + +org.gradle.parallel=true +org.gradle.caching=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml new file mode 100644 index 00000000..b1a411c5 --- /dev/null +++ b/gradle/libs.versions.toml @@ -0,0 +1,29 @@ +[versions] +sqliteJdbc = "3.43.2.2" +jlayer = "1.0.1" +junit = "5.10.1" +mockito = "5.7.0" +mockitoCompile = "5.17.0" +jetbrainsAnnotations = "24.0.1" +kotlin = "2.2.0" +composeMultiplatform = "1.8.2" +spotbugsPlugin = "6.0.26" +spotbugs = "4.9.8" +pmd = "7.17.0" + +[libraries] +sqlite-jdbc = { module = "org.xerial:sqlite-jdbc", version.ref = "sqliteJdbc" } +jlayer = { module = "javazoom:jlayer", version.ref = "jlayer" } +junit-jupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "junit" } +junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } +mockito-core-compile = { module = "org.mockito:mockito-core", version.ref = "mockitoCompile" } +jetbrains-annotations = { module = "org.jetbrains:annotations", version.ref = "jetbrainsAnnotations" } +mockito-core = { module = "org.mockito:mockito-core", version.ref = "mockito" } +mockito-junit-jupiter = { module = "org.mockito:mockito-junit-jupiter", version.ref = "mockito" } +junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" } + +[plugins] +kotlinJvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } +composeCompiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } +composeMultiplatform = { id = "org.jetbrains.compose", version.ref = "composeMultiplatform" } +spotbugs = { id = "com.github.spotbugs", version.ref = "spotbugsPlugin" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..eddabd2eef8d94a5437d6168ff9c87a78ff725b3 GIT binary patch literal 47505 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/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# +############################################################################## + +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +# This is normally unused +# shellcheck disable=SC2034 +APP_BASE_NAME=${0##*/} +# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) +APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s\n' "$PWD" ) || exit + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD=maximum + +warn () { + echo "$*" +} >&2 + +die () { + echo + echo "$*" + echo + exit 1 +} >&2 + +# 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 ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; +esac + + + +# 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 + if ! command -v java >/dev/null 2>&1 + then + 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 +fi + +# Increase the maximum file descriptors if we can. +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. + # shellcheck disable=SC2039,SC3045 + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac +fi + +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) + + # Now convert the arguments - kludge to limit ourselves to /bin/sh + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) + fi + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg + done +fi + + +# 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"' + +# Collect all arguments for the java command: +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# and any embedded shellness will be escaped. +# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be +# treated as '${Hostname}' itself on the command line. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi + +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 00000000..8508ef68 --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,82 @@ +@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 +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem gradlew startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@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% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +"%COMSPEC%" /c exit 1 + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +"%COMSPEC%" /c exit 1 + +:execute +@rem Setup the command line + + + +@rem Execute gradlew +@rem endlocal doesn't take effect until after the line is parsed and variables are expanded +@rem which allows us to clear the local environment before executing the java command +endlocal & "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* & call :exitWithErrorLevel + +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/i18n-generator/build.gradle.kts b/i18n-generator/build.gradle.kts new file mode 100644 index 00000000..9680221c --- /dev/null +++ b/i18n-generator/build.gradle.kts @@ -0,0 +1,17 @@ +plugins { + alias(libs.plugins.kotlinJvm) +} + +kotlin { + jvmToolchain(21) +} + +dependencies { + testImplementation(libs.junit.jupiter) + // Gradle 9 no longer adds the launcher implicitly. + testRuntimeOnly(libs.junit.platform.launcher) +} + +tasks.test { + useJUnitPlatform() +} diff --git a/i18n-generator/src/main/kotlin/kst4contest/i18n/GeneratorMain.kt b/i18n-generator/src/main/kotlin/kst4contest/i18n/GeneratorMain.kt new file mode 100644 index 00000000..fe5b0767 --- /dev/null +++ b/i18n-generator/src/main/kotlin/kst4contest/i18n/GeneratorMain.kt @@ -0,0 +1,184 @@ +package kst4contest.i18n + +import java.io.File + +/** + * What generation reported. + * + * @param warnings incomplete translations -- allowed, and the reason a partial contribution + * can be submitted at all + * @param coverage one line per language, so a pull request can be judged at a glance + */ +data class GenerationResult(val warnings: List, val coverage: List) + +/** + * English, because the source text lives in the code and AGENTS.md requires it there. + * + * Deliberately a second declaration: the generated `Translations.BASE_LANGUAGE` says the same + * thing on the application's side. They cannot be shared -- this module is build tooling and + * is not on the application's classpath -- and the generated source is written from this + * constant, so a drift would show up in `GenerationTest`. + */ +const val BASE_LANGUAGE: String = "en" + +/** + * Reads every translation file in a directory and writes the generated Kotlin. + * + * Incompleteness is allowed, incorrectness is not. A missing key warns and falls back to the + * base at runtime; an orphan key, a placeholder mismatch, a duplicate key, an unreadable file + * or two keys collapsing to one identifier all throw, which fails the build with this + * message. + * + * Anything in the directory that is not a translation file -- a README for contributors, say + * -- is ignored rather than refused: documentation must not break the build. + * + * @param inputDirectory holds `strings_.properties` + * @param outputDirectory receives the generated source and any worksheets + * @return the warnings and the coverage lines + * @throws TranslationException on anything a contributor has to fix + */ +fun generate(inputDirectory: File, outputDirectory: File): GenerationResult { + + val translations = (inputDirectory.listFiles() ?: emptyArray()) + .filter { languageOf(it.name) != null } + .sortedBy { it.name } + .map(::readTranslation) + + val base = translations.firstOrNull { it.language == BASE_LANGUAGE } + ?: throw TranslationException( + "strings_$BASE_LANGUAGE.properties is missing from ${inputDirectory.path}; the base " + + "language is where every key and every argument count comes from" + ) + + refuseIllegalIdentifiers(base) + refuseIdentifierCollisions(base) + + val others = translations.filter { it.language != BASE_LANGUAGE } + val warnings = mutableListOf() + + for (translation in others) { + refuseOrphans(base, translation) + refusePlaceholderMismatches(base, translation) + + val missing = missingKeys(base.entries.keys, translation.entries.keys) + + if (missing.isNotEmpty()) { + warnings += "strings_${translation.language}.properties is missing " + .plus("${missing.size} of ${base.entries.size} keys; they fall back to ") + .plus("$BASE_LANGUAGE: ${missing.sorted().take(10).joinToString(", ")}") + + writeWorksheet(outputDirectory, translation.language, base, missing) + } + } + + val target = File(outputDirectory, "kst4contest/view/i18n/Strings.kt") + target.parentFile.mkdirs() + target.writeText(stringsSource(base, others), Charsets.UTF_8) + + return GenerationResult( + warnings = warnings, + coverage = translations.map { "${it.language}: ${it.entries.size}/${base.entries.size}" }, + ) +} + +private fun refuseIllegalIdentifiers(base: Translation) { + val illegal = illegalIdentifierKeys(base.entries.keys) + + if (illegal.isEmpty()) { + return + } + + throw TranslationException( + "strings_$BASE_LANGUAGE.properties has keys that do not form a usable name -- a key is " + + "letters and digits with . _ - between words, nothing else. A key carrying " + + "anything more would be written into the generated source as code: " + + illegal.sorted().joinToString(", ") + ) +} + +private fun refuseIdentifierCollisions(base: Translation) { + val collisions = identifierCollisions(base.entries.keys) + + if (collisions.isEmpty()) { + return + } + + throw TranslationException( + "these keys would become the same Kotlin name: " + collisions.entries.joinToString("; ") { + "${it.key} <- ${it.value.sorted().joinToString(", ")}" + } + ) +} + +private fun refuseOrphans(base: Translation, translation: Translation) { + val orphans = orphanKeys(base.entries.keys, translation.entries.keys) + + if (orphans.isEmpty()) { + return + } + + throw TranslationException( + "strings_${translation.language}.properties names keys the base does not, so nothing " + + "would ever read them -- a typo? " + orphans.sorted().joinToString(", ") + ) +} + +private fun refusePlaceholderMismatches(base: Translation, translation: Translation) { + val mismatched = translation.entries.keys.filter { key -> + argumentCount(translation.entries.getValue(key)) != argumentCount(base.entries.getValue(key)) + } + + if (mismatched.isEmpty()) { + return + } + + throw TranslationException( + "strings_${translation.language}.properties uses different placeholders than the base " + + "for: " + mismatched.sorted().joinToString(", ") + + ". A placeholder the translation leaves out drops its data silently." + ) +} + +/** + * Writes the keys a translation still lacks, with the base text as the value. + * + * A worksheet, not a build output: a contributor copies its lines into their own file and + * translates the right-hand side. Without it they would have to diff two files of several + * hundred lines to find out what is left. + * + * Only written when something is missing -- an empty worksheet is a file somebody has to open + * to learn there is nothing in it. + */ +private fun writeWorksheet( + outputDirectory: File, + language: String, + base: Translation, + missing: Set, +) { + val file = File(outputDirectory, "todo/strings_$language.todo.properties") + file.parentFile.mkdirs() + + val header = "# ${missing.size} of ${base.entries.size} keys are not yet translated into " + .plus("$language. Copy these lines into strings_$language.properties and translate the ") + .plus("values. Partial is fine: anything left out falls back to $BASE_LANGUAGE.") + + val lines = missing.sorted().joinToString("\n") { key -> + "$key=${base.entries.getValue(key)}" + } + + file.writeText("$header\n\n$lines\n", Charsets.UTF_8) +} + +/** Called by Gradle: input directory, output directory. */ +object GeneratorMain { + + @JvmStatic + fun main(args: Array) { + require(args.size == 2) { "usage: GeneratorMain " } + + val result = generate(File(args[0]), File(args[1])) + + result.warnings.forEach { println("[i18n, warning] $it") } + println("[i18n] coverage -- " + result.coverage.joinToString(", ")) + } +} diff --git a/i18n-generator/src/main/kotlin/kst4contest/i18n/StringsSource.kt b/i18n-generator/src/main/kotlin/kst4contest/i18n/StringsSource.kt new file mode 100644 index 00000000..64ef084a --- /dev/null +++ b/i18n-generator/src/main/kotlin/kst4contest/i18n/StringsSource.kt @@ -0,0 +1,121 @@ +package kst4contest.i18n + +/** + * Turns translations into the Kotlin the application compiles against. + * + * Two things come out: a `Strings` class whose members are one per key -- a property for a + * plain text, a function for a parameterised one -- and a `Translations` object holding the + * texts. The class is what makes a typo and a wrong argument count compile errors rather than + * things an operator discovers. + * + * @param base the source language; every key and every argument count comes from here + * @param translations the other languages, each carrying only the keys it actually has + * @return the complete Kotlin source file + */ +fun stringsSource(base: Translation, translations: List): String { + + val members = base.entries.keys.sorted().joinToString("\n\n") { key -> + memberFor(key, base.entries.getValue(key)) + } + + val tables = (listOf(base) + translations).joinToString("\n\n") { translation -> + tableFor(translation, base.entries.size) + } + + val byLanguage = (listOf(base) + translations).joinToString(",\n") { translation -> + " ${kotlinLiteral(translation.language)} to ${tableName(translation.language)}" + } + + return """ + |// Generated from app-desktop/src/main/i18n by the :i18n-generator module. + |// Do not edit: edit the .properties files and rebuild. + |package kst4contest.view.i18n + | + |import java.text.MessageFormat + | + |/** + | * The interface texts of one language. + | * + | * One member per key, so a mistyped key and a wrong argument count are both compile + | * errors. Generated -- see the module named above. + | */ + |class Strings(private val lookup: (String) -> String) { + | + |$members + |} + | + |/** The texts themselves, and which language has which. */ + |object Translations { + | + |$tables + | + | /** Every language this build carries, by its code. */ + | val BY_LANGUAGE: Map> = mapOf( + |$byLanguage, + | ) + | + | /** The language every lookup falls back to. */ + | const val BASE_LANGUAGE: String = ${kotlinLiteral(base.language)} + |} + | + """.trimMargin() +} + +/** + * A text as a Kotlin string literal. + * + * The `$` is the one that matters and the one a translator cannot be expected to know about: + * in Kotlin it opens a template, so an unescaped one produces source that either does not + * compile or means something other than the text. The backslash goes first, or it would + * escape the escapes added after it. + */ +fun kotlinLiteral(text: String): String { + val escaped = text + .replace("\\", "\\\\") + .replace("\"", "\\\"") + .replace("$", "\\$") + .replace("\n", "\\n") + .replace("\r", "\\r") + .replace("\t", "\\t") + + return "\"$escaped\"" +} + +/** A property for a plain text, a function for one with placeholders. */ +private fun memberFor(key: String, text: String): String { + val identifier = identifierFor(key) + val arity = argumentCount(text) + val documentation = " /** ${commentFor(text)} */" + + if (arity == 0) { + return "$documentation\n val $identifier: String get() = lookup(${kotlinLiteral(key)})" + } + + val parameters = (0 until arity).joinToString(", ") { "arg$it: Any" } + val arguments = (0 until arity).joinToString(", ") { "arg$it" } + + return documentation + + "\n fun $identifier($parameters): String =" + + "\n MessageFormat.format(lookup(${kotlinLiteral(key)}), $arguments)" +} + +private fun tableFor(translation: Translation, baseSize: Int): String { + val entries = translation.entries.keys.sorted().joinToString(",\n") { key -> + " ${kotlinLiteral(key)} to ${kotlinLiteral(translation.entries.getValue(key))}" + } + + return " /** ${translation.language}: ${translation.entries.size} of $baseSize. */\n" + + " val ${tableName(translation.language)}: Map = mapOf(\n$entries,\n )" +} + +/** `pt_BR` becomes `PT_BR`; the code is already identifier-safe. */ +private fun tableName(language: String): String = language.uppercase() + +/** + * The source text as a KDoc line, so a call site shows what it says. + * + * The comment terminator has to go: a text containing one would end the KDoc early and leave + * the rest of the text as stray source. + */ +private fun commentFor(text: String): String = + text.replace("*/", "* /").replace("\n", " ").take(120) diff --git a/i18n-generator/src/main/kotlin/kst4contest/i18n/TranslationFiles.kt b/i18n-generator/src/main/kotlin/kst4contest/i18n/TranslationFiles.kt new file mode 100644 index 00000000..0064eb90 --- /dev/null +++ b/i18n-generator/src/main/kotlin/kst4contest/i18n/TranslationFiles.kt @@ -0,0 +1,95 @@ +package kst4contest.i18n + +import java.io.File +import java.util.Properties + +/** One language's texts. */ +data class Translation(val language: String, val entries: Map) + +/** What the generator refuses. The message is read by a contributor, so it names the file. */ +class TranslationException(message: String) : RuntimeException(message) + +/** + * Reads one translation file. + * + * `Properties` does the parsing -- separators, comments, escapes, continuation lines -- and is + * battle-tested at it. What it does *not* do is complain about a key that appears twice: it + * keeps the last one silently. In a file of several hundred lines that is an easy mistake and + * an invisible loss, so the keys are counted separately before the values are taken. + * + * @throws TranslationException when the file cannot be read or names a key twice + */ +fun readTranslation(file: File): Translation { + + if (!file.isFile) { + throw TranslationException("${file.name}: no such translation file (${file.path})") + } + + val duplicates = duplicateKeysIn(file) + + if (duplicates.isNotEmpty()) { + throw TranslationException( + "${file.name}: these keys appear more than once, so one translation would be " + + "lost without a word: ${duplicates.sorted().joinToString(", ")}" + ) + } + + val properties = Properties() + runCatching { file.reader(Charsets.UTF_8).use(properties::load) } + .onFailure { throw TranslationException("${file.name}: cannot be read -- ${it.message}") } + + val language = languageOf(file.name) + ?: throw TranslationException("${file.name}: the file name does not name a language") + + return Translation( + language = language, + entries = properties.stringPropertyNames().associateWith { properties.getProperty(it) }, + ) +} + +/** + * The language a translation file name names, or null when it names none. + * + * `strings_de.properties` is German, `strings_pt_BR.properties` is Brazilian Portuguese, and + * `strings.properties` is not a translation file at all. + */ +fun languageOf(fileName: String): String? = + FILE_NAME.matchEntire(fileName)?.groupValues?.get(1) + +/** + * Keys that appear more than once, found by reading the lines rather than the parsed map -- + * which is the only place the information still exists. + * + * Deliberately does not understand continuation lines (a trailing backslash): a continuation + * whose text contains a separator would be counted as a key. That is acceptable here because + * these texts are one line each, and the alternative is reimplementing `Properties`' parser + * to find a mistake `Properties` itself does not report. + */ +private fun duplicateKeysIn(file: File): Set { + val seen = mutableSetOf() + val twice = mutableSetOf() + + file.forEachLine(Charsets.UTF_8) { raw -> + val line = raw.trim() + + if (line.isEmpty() || line.startsWith("#") || line.startsWith("!")) { + return@forEachLine + } + + val separator = line.indexOfFirst { it == '=' || it == ':' } + + if (separator <= 0) { + return@forEachLine + } + + val key = line.take(separator).trim() + + if (!seen.add(key)) { + twice += key + } + } + + return twice +} + +private val FILE_NAME = Regex("""strings_([A-Za-z]{2}(?:_[A-Za-z]{2})?)\.properties""") diff --git a/i18n-generator/src/main/kotlin/kst4contest/i18n/TranslationRules.kt b/i18n-generator/src/main/kotlin/kst4contest/i18n/TranslationRules.kt new file mode 100644 index 00000000..9be4add2 --- /dev/null +++ b/i18n-generator/src/main/kotlin/kst4contest/i18n/TranslationRules.kt @@ -0,0 +1,82 @@ +package kst4contest.i18n + +/** + * The rules that decide whether a set of translations is usable. + * + * Pure functions over key sets and texts, with no file and no Gradle in sight, so the part + * that can be quietly wrong is the part that is tested. + */ + +/** Keys the base has and a translation does not. Allowed: they fall back to the base. */ +fun missingKeys(base: Set, other: Set): Set = base - other + +/** Keys a translation has and the base does not. Not allowed: a contributor's typo. */ +fun orphanKeys(base: Set, other: Set): Set = other - base + +/** + * How many arguments a text needs. + * + * The highest placeholder index plus one, and deliberately not the number of occurrences: + * `MessageFormat` addresses arguments by index, so `{1} {1}` needs two and `{0} {0}` needs + * one. Counting occurrences makes the first throw and the second swallow an argument. + * + * A brace followed by anything but a digit is not a placeholder -- braces occur in real + * interface text. + */ +fun argumentCount(text: String): Int { + val indices = PLACEHOLDER.findAll(text).map { it.groupValues[1].toInt() } + return (indices.maxOrNull() ?: -1) + 1 +} + +/** + * The Kotlin identifier for a key. + * + * `settings.save` becomes `settingsSave`. Dots, underscores and dashes all separate words, + * because a contributor will use whichever they are used to and the generated name must not + * depend on which. + */ +fun identifierFor(key: String): String { + val words = key.split('.', '_', '-').filter { it.isNotEmpty() } + + val joined = words.mapIndexed { index, word -> + if (index == 0) { + word.replaceFirstChar { it.lowercaseChar() } + } else { + word.replaceFirstChar { it.uppercaseChar() } + } + }.joinToString("") + + /* A key may start with a digit; a Kotlin identifier may not. */ + return if (joined.firstOrNull()?.isDigit() == true) "key$joined" else joined +} + +/** + * Keys that would produce the same identifier, grouped by that identifier. + * + * Generating both would emit Kotlin that does not compile, and the compiler's complaint names + * the generated file -- which tells a contributor nothing about the line they wrote. + */ +fun identifierCollisions(keys: Collection): Map> = + keys.groupBy { identifierFor(it) }.filterValues { it.size > 1 } + +/** + * Keys whose identifier would not be a legal Kotlin name. + * + * [identifierFor] strips only `.`, `_` and `-`; every other character a `Properties` file can + * carry in a key -- a space, a brace, a quote, a `=`, a newline decoded from a `\uXXXX` escape + * -- passes through into identifier position unchanged. Emitted there it does not merely fail + * to compile: the member is written as `val : String get() = lookup(...)`, so a + * key that reads `x: String get() = "" ... init { ... } ... val y` breaks out of the template + * and leaves a property initializer or an init block of the contributor's choosing, which + * runs when `Strings` is instantiated in the application. The value is already escaped before + * it becomes a literal; the identifier was not checked at all. So a generated name that is + * not letters-then-letters-and-digits is refused before any source is written. + */ +fun illegalIdentifierKeys(keys: Collection): List = + keys.filterNot { IDENTIFIER.matches(identifierFor(it)) } + +/** A letter, then letters and digits: the plain Kotlin identifier this generator emits. */ +private val IDENTIFIER = Regex("[A-Za-z][A-Za-z0-9]*") + +/** `{0}`, `{12}`, `{0,number}` -- a brace, digits, then either a brace or a comma. */ +private val PLACEHOLDER = Regex("""\{(\d+)\s*[,}]""") diff --git a/i18n-generator/src/test/kotlin/kst4contest/i18n/GenerationTest.kt b/i18n-generator/src/test/kotlin/kst4contest/i18n/GenerationTest.kt new file mode 100644 index 00000000..62b8a83c --- /dev/null +++ b/i18n-generator/src/test/kotlin/kst4contest/i18n/GenerationTest.kt @@ -0,0 +1,197 @@ +package kst4contest.i18n + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertThrows +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import java.io.File +import java.nio.file.Files + +/** + * Generation end to end: what breaks the build and what only warns. + * + * The distinction is the whole arrangement. A translation that is 80 per cent finished has to + * be submittable, or nobody outside this project can contribute one; a translation that is + * wrong must not ship. + */ +class GenerationTest { + + private fun directories(): Pair { + val input = Files.createTempDirectory("kst4contest-i18n-in").toFile() + val output = Files.createTempDirectory("kst4contest-i18n-out").toFile() + return input to output + } + + private fun write(directory: File, name: String, content: String) { + File(directory, name).writeText(content, Charsets.UTF_8) + } + + private fun generated(output: File): File = + File(output, "kst4contest/view/i18n/Strings.kt") + + @Test + fun aCompleteSetGeneratesAndWarnsAboutNothing() { + val (input, output) = directories() + write(input, "strings_en.properties", "a=one\n") + write(input, "strings_de.properties", "a=eins\n") + + val result = generate(input, output) + + assertTrue(result.warnings.isEmpty(), "${result.warnings}") + assertTrue(generated(output).isFile, "no source written") + } + + @Test + fun aMissingKeyOnlyWarnsAndStillGenerates() { + val (input, output) = directories() + write(input, "strings_en.properties", "a=one\nb=two\n") + write(input, "strings_de.properties", "a=eins\n") + + val result = generate(input, output) + + assertEquals(1, result.warnings.size, "${result.warnings}") + assertTrue(result.warnings.single().contains("b"), result.warnings.single()) + assertTrue(generated(output).isFile) + } + + @Test + fun anOrphanKeyBreaksTheBuildAndNamesItself() { + val (input, output) = directories() + write(input, "strings_en.properties", "a=one\n") + write(input, "strings_de.properties", "a=eins\ntypo=zwei\n") + + val failure = assertThrows(TranslationException::class.java) { generate(input, output) } + + assertTrue(failure.message!!.contains("typo"), failure.message) + assertTrue(failure.message!!.contains("strings_de"), failure.message) + } + + @Test + fun aPlaceholderMismatchBreaksTheBuild() { + /* + * The one that would otherwise swallow data in silence: the base passes two + * arguments, the translation prints one, and MessageFormat says nothing. + */ + val (input, output) = directories() + write(input, "strings_en.properties", "a={0} of {1}\n") + write(input, "strings_de.properties", "a={0}\n") + + val failure = assertThrows(TranslationException::class.java) { generate(input, output) } + + assertTrue(failure.message!!.contains("a"), failure.message) + } + + @Test + fun anIdentifierCollisionBreaksTheBuild() { + val (input, output) = directories() + write(input, "strings_en.properties", "gui.startupDesign=x\ngui.startup_design=y\n") + + val failure = assertThrows(TranslationException::class.java) { generate(input, output) } + + assertTrue(failure.message!!.contains("guiStartupDesign"), failure.message) + } + + @Test + fun aKeyCarryingKotlinSyntaxBreaksTheBuildRatherThanInjectingCode() { + /* + * The key, not the value, becomes the member name, and only . _ - are stripped from + * it. A \uXXXX escape lets a contributed .properties file carry a key that, dropped + * into `val : String get() = ...`, closes the template and opens a property + * initializer -- Kotlin that runs when Strings is built in every client. The base + * file is the vector: only base keys become members. This must fail the build the way + * an orphan or a collision does, not ship. + * + * The escapes below decode to the key `inject: Int = run{ pwn() }`. + */ + val (input, output) = directories() + write( + input, + "strings_en.properties", + "ok=fine\n" + + "inject\\u003a\\u0020Int\\u0020\\u003d\\u0020run\\u007b\\u0020pwn()\\u0020\\u007d=value\n", + ) + + val failure = assertThrows(TranslationException::class.java) { generate(input, output) } + + assertTrue(failure.message!!.contains("inject"), failure.message) + assertFalse(generated(output).exists(), "source was written despite an unusable key") + } + + @Test + fun aMissingBaseFileBreaksTheBuild() { + val (input, output) = directories() + write(input, "strings_de.properties", "a=eins\n") + + assertThrows(TranslationException::class.java) { generate(input, output) } + } + + @Test + fun aThirdLanguageIsGeneratedToo() { + // Prüfschwerpunkt 6: a contributed language must not need any wiring. + val (input, output) = directories() + write(input, "strings_en.properties", "a=one\nb=two\n") + write(input, "strings_de.properties", "a=eins\nb=zwei\n") + write(input, "strings_fr.properties", "a=un\n") + + val result = generate(input, output) + + assertTrue(generated(output).readText().contains("\"a\" to \"un\"")) + assertTrue(result.coverage.any { it.startsWith("fr:") && it.contains("1/2") }, "${result.coverage}") + } + + @Test + fun theCoverageLineNamesEveryLanguage() { + val (input, output) = directories() + write(input, "strings_en.properties", "a=one\nb=two\n") + write(input, "strings_de.properties", "a=eins\nb=zwei\n") + + val result = generate(input, output) + + assertTrue(result.coverage.any { it.startsWith("de:") && it.contains("2/2") }, "${result.coverage}") + } + + @Test + fun anIncompleteTranslationGetsAWorksheetWithTheEnglishTextToTranslate() { + val (input, output) = directories() + write(input, "strings_en.properties", "a=one\nb=two\n") + write(input, "strings_de.properties", "a=eins\n") + + generate(input, output) + + val worksheet = File(output, "todo/strings_de.todo.properties") + assertTrue(worksheet.isFile, "no worksheet was written") + + val content = worksheet.readText() + assertTrue(content.contains("b=two"), content) + assertFalse(content.lines().any { it.startsWith("a=") }, "an already translated key was listed") + } + + @Test + fun aCompleteTranslationGetsNoWorksheet() { + // An empty worksheet is a file somebody has to open to learn there is nothing to do. + val (input, output) = directories() + write(input, "strings_en.properties", "a=one\n") + write(input, "strings_de.properties", "a=eins\n") + + generate(input, output) + + assertFalse(File(output, "todo/strings_de.todo.properties").exists()) + } + + @Test + fun aFileThatIsNotATranslationIsIgnoredRatherThanRefused() { + /* + * The input directory may hold a README telling a contributor what to do. Refusing it + * would make the documentation break the build. + */ + val (input, output) = directories() + write(input, "strings_en.properties", "a=one\n") + write(input, "README.md", "# how to contribute a language\n") + + val result = generate(input, output) + + assertTrue(result.warnings.isEmpty(), "${result.warnings}") + assertTrue(generated(output).isFile) + } +} diff --git a/i18n-generator/src/test/kotlin/kst4contest/i18n/StringsSourceTest.kt b/i18n-generator/src/test/kotlin/kst4contest/i18n/StringsSourceTest.kt new file mode 100644 index 00000000..d3890b4b --- /dev/null +++ b/i18n-generator/src/test/kotlin/kst4contest/i18n/StringsSourceTest.kt @@ -0,0 +1,126 @@ +package kst4contest.i18n + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertFalse +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * Turning translations into Kotlin. + * + * The dangerous part is the escaping. This writes Kotlin source, and in Kotlin `$` opens a + * template: a translation containing one produces either source that does not compile or -- + * worse -- source that means something else. A translator has no reason to know that. + */ +class StringsSourceTest { + + private fun base(vararg pairs: Pair) = Translation("en", mapOf(*pairs)) + + @Test + fun aPlainKeyBecomesAProperty() { + val source = stringsSource(base("settings.save" to "Save settings"), emptyList()) + + assertTrue( + source.contains("val settingsSave: String get() = lookup(\"settings.save\")"), + source, + ) + } + + @Test + fun aKeyWithAPlaceholderBecomesAFunctionWithThatManyArguments() { + val source = stringsSource(base("c.to" to "Connect to {0}"), emptyList()) + + assertTrue(source.contains("fun cTo(arg0: Any)"), source) + assertFalse(source.contains("val cTo"), "a parameterised key became a property") + } + + @Test + fun theArityFollowsTheHighestIndexAndNotTheOccurrences() { + val source = stringsSource(base("x" to "{1} {1}"), emptyList()) + + assertTrue(source.contains("fun x(arg0: Any, arg1: Any)"), source) + } + + @Test + fun theBaseTextsAreEmittedAsAMap() { + val source = stringsSource(base("a" to "one"), emptyList()) + + assertTrue(source.contains("\"a\" to \"one\""), source) + } + + @Test + fun aTranslationIsEmittedWithOnlyTheKeysItHas() { + /* + * Incompleteness is allowed, so a translation carries only its own keys and the + * lookup falls through to the base. Padding it with English would make a missing + * translation indistinguishable from a deliberate English term. + */ + val source = stringsSource( + base("a" to "one", "b" to "two"), + listOf(Translation("de", mapOf("a" to "eins"))), + ) + + assertTrue(source.contains("\"a\" to \"eins\""), source) + assertFalse(source.contains("\"b\" to \"zwei\""), "de gained a key it does not have") + + // b belongs to the base table and to nothing else. + assertEquals(1, source.split("\"b\" to ").size - 1, "b appears more than once") + } + + // ------------------------------------------------------------------ escaping + + @Test + fun aDollarSignIsEscapedBecauseKotlinWouldReadItAsATemplate() { + assertEquals("\"5 \\\$ only\"", kotlinLiteral("5 \$ only")) + } + + @Test + fun quotesAndBackslashesAreEscaped() { + assertEquals("\"say \\\"hi\\\"\"", kotlinLiteral("say \"hi\"")) + assertEquals("\"a\\\\b\"", kotlinLiteral("a\\b")) + } + + @Test + fun newlinesAndTabsBecomeEscapesRatherThanBreakingTheLiteral() { + assertEquals("\"a\\nb\"", kotlinLiteral("a\nb")) + assertEquals("\"a\\tb\"", kotlinLiteral("a\tb")) + } + + @Test + fun anUmlautStaysItselfBecauseTheGeneratedFileIsUtf8() { + assertEquals("\"Grüße\"", kotlinLiteral("Grüße")) + } + + @Test + fun aTranslationFullOfHazardsSurvivesIntoTheSource() { + // The end-to-end version of the escaping tests above. + val source = stringsSource(base("x" to "a \$b \"c\" d\\e"), emptyList()) + + assertTrue(source.contains("\\\$b"), source) + assertTrue(source.contains("\\\"c\\\""), source) + assertTrue(source.contains("d\\\\e"), source) + } + + @Test + fun aTextContainingACommentEndDoesNotBreakTheKdoc() { + /* + * The texts are echoed into a KDoc line so the call site shows what they say. A text + * containing the comment terminator would end the comment early and leave the rest as + * stray source. + */ + val source = stringsSource(base("x" to "ends a comment */ here"), emptyList()) + + /* + * The KDoc line only. Inside the string literal in the table below, a comment + * terminator is ordinary text and perfectly valid Kotlin -- asserting over the whole + * file would be asserting that a harmless thing does not happen. + * + * Writing this comment is itself the demonstration: the first version quoted the + * terminator and ended this comment three lines early. + */ + val kdoc = source.lines().single { it.trimStart().startsWith("/** ends a comment") } + + assertTrue(kdoc.trimEnd().endsWith("*/"), kdoc) + assertEquals(1, kdoc.split("*/").size - 1, "the KDoc line terminates twice: $kdoc") + } +} diff --git a/i18n-generator/src/test/kotlin/kst4contest/i18n/TranslationFilesTest.kt b/i18n-generator/src/test/kotlin/kst4contest/i18n/TranslationFilesTest.kt new file mode 100644 index 00000000..d05d55e5 --- /dev/null +++ b/i18n-generator/src/test/kotlin/kst4contest/i18n/TranslationFilesTest.kt @@ -0,0 +1,105 @@ +package kst4contest.i18n + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertNull +import org.junit.jupiter.api.Assertions.assertThrows +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test +import java.io.File + +/** + * Reading a translation file. + * + * The one rule with teeth: `java.util.Properties` keeps the last of two identical keys + * without a word. A contributor who translates a key twice -- easy in a file of several + * hundred lines -- would otherwise lose one of their translations and never find out. + */ +class TranslationFilesTest { + + private fun createTempDirectory(): File = + java.nio.file.Files.createTempDirectory("kst4contest-i18n").toFile() + + private fun fileWith(name: String, content: String): File { + val file = File(createTempDirectory(), name) + file.writeText(content, Charsets.UTF_8) + return file + } + + @Test + fun aPlainFileIsReadKeyByKey() { + val file = fileWith("strings_en.properties", "settings.save=Save settings\nmenu.file=File\n") + + val translation = readTranslation(file) + + assertEquals("en", translation.language) + assertEquals("Save settings", translation.entries["settings.save"]) + assertEquals("File", translation.entries["menu.file"]) + } + + @Test + fun umlautsSurviveBecauseTheFileIsUtf8() { + // Java 9 and later read .properties as UTF-8, which is why no escapes are needed. + val file = fileWith("strings_de.properties", "settings.save=Einstellungen speichern\nx=Grüße\n") + + assertEquals("Grüße", readTranslation(file).entries["x"]) + } + + @Test + fun aDuplicateKeyIsRefusedRatherThanSilentlyWinning() { + /* + * Properties would keep the second and say nothing. For a contributor that means one + * of their two translations vanishes with a green build. + */ + val file = fileWith("strings_de.properties", "a=erste\nb=zwei\na=zweite\n") + + val failure = assertThrows(TranslationException::class.java) { readTranslation(file) } + + assertTrue(failure.message!!.contains("a"), failure.message) + assertTrue(failure.message!!.contains("strings_de.properties"), failure.message) + } + + @Test + fun aDuplicateKeyIsStillFoundWhenTheLinesAreNotAdjacentOrAreSpaced() { + val file = fileWith("strings_de.properties", "a = eins\nb=zwei\n a=drei\n") + + assertThrows(TranslationException::class.java) { readTranslation(file) } + } + + @Test + fun commentsAndBlankLinesAreNotKeys() { + val file = fileWith("strings_en.properties", "# a comment\n! another\n\na=one\n") + + assertEquals(mapOf("a" to "one"), readTranslation(file).entries) + } + + @Test + fun aValueMayContainAnEqualsSign() { + // Only the first separator splits; the rest is text. Operators do write "a=b". + val file = fileWith("strings_en.properties", "formula=a=b\n") + + assertEquals("a=b", readTranslation(file).entries["formula"]) + } + + @Test + fun aMissingFileIsRefusedWithItsName() { + val absent = File("/nonexistent/kst4contest/strings_de.properties") + + val failure = assertThrows(TranslationException::class.java) { readTranslation(absent) } + + assertTrue(failure.message!!.contains("strings_de.properties"), failure.message) + } + + @Test + fun theLanguageComesFromTheFileName() { + assertEquals("en", languageOf("strings_en.properties")) + assertEquals("de", languageOf("strings_de.properties")) + assertEquals("pt_BR", languageOf("strings_pt_BR.properties")) + } + + @Test + fun aFileNameThatIsNotATranslationNamesNoLanguage() { + assertNull(languageOf("strings.properties")) + assertNull(languageOf("gradle.properties")) + assertNull(languageOf("strings_de.txt")) + } +} diff --git a/i18n-generator/src/test/kotlin/kst4contest/i18n/TranslationRulesTest.kt b/i18n-generator/src/test/kotlin/kst4contest/i18n/TranslationRulesTest.kt new file mode 100644 index 00000000..12dbcb85 --- /dev/null +++ b/i18n-generator/src/test/kotlin/kst4contest/i18n/TranslationRulesTest.kt @@ -0,0 +1,134 @@ +package kst4contest.i18n + +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Assertions.assertTrue +import org.junit.jupiter.api.Test + +/** + * The rules that decide whether a set of translations is usable. + * + * Pure functions, and therefore the part that can be wrong without anyone noticing: a build + * break that never breaks looks exactly like a clean project. Every rule here has a failure + * that reaches an operator -- a lost translation, a swallowed argument, or Kotlin that does + * not compile with a message a contributor cannot read. + */ +class TranslationRulesTest { + + @Test + fun whatTheBaseHasAndATranslationLacksIsMissing() { + assertEquals( + setOf("b"), + missingKeys(base = setOf("a", "b"), other = setOf("a")), + ) + } + + @Test + fun whatATranslationHasAndTheBaseLacksIsAnOrphan() { + // A contributor's typo. Silently keeping it would mean a translation nothing uses. + assertEquals( + setOf("typo"), + orphanKeys(base = setOf("a"), other = setOf("a", "typo")), + ) + } + + @Test + fun aTextWithoutPlaceholdersNeedsNoArguments() { + assertEquals(0, argumentCount("Save settings")) + assertEquals(0, argumentCount("")) + } + + @Test + fun theArgumentCountIsTheHighestIndexPlusOneAndNotTheNumberOfOccurrences() { + /* + * The trap. "{1} {1}" occurs twice and needs two arguments, because MessageFormat + * addresses them by index; "{0} {0}" occurs twice and needs one. Counting occurrences + * makes the first case throw and the second swallow an argument. + */ + assertEquals(1, argumentCount("Connect to {0}")) + assertEquals(1, argumentCount("{0} and {0} again")) + assertEquals(2, argumentCount("{1} {1}")) + assertEquals(3, argumentCount("{2} {0}")) + } + + @Test + fun aFormattedPlaceholderStillCounts() { + // MessageFormat allows {0,number} and {1,date,short}; both are arguments. + assertEquals(1, argumentCount("Seen {0,number} times")) + assertEquals(2, argumentCount("{0} at {1,date,short}")) + } + + @Test + fun somethingThatMerelyLooksLikeAPlaceholderIsNotOne() { + // Braces appear in real text. Only a leading digit makes it an argument. + assertEquals(0, argumentCount("Press {Ctrl} to stop")) + assertEquals(0, argumentCount("100 {}")) + } + + @Test + fun aDottedKeyBecomesALowerCamelCaseIdentifier() { + assertEquals("settingsSave", identifierFor("settings.save")) + assertEquals("menuFile", identifierFor("menu.file")) + assertEquals("guiBandColumnHints", identifierFor("gui.bandColumnHints")) + } + + @Test + fun aKeyWithUnderscoresOrDashesBecomesOneIdentifierToo() { + assertEquals("guiStartupDesign", identifierFor("gui.startup_design")) + assertEquals("guiStartupDesign", identifierFor("gui.startup-design")) + } + + @Test + fun anIdentifierNeverStartsWithADigit() { + // A key may legitimately start with a number; a Kotlin identifier may not. + assertTrue(identifierFor("2.metres").first().isLetter()) + } + + @Test + fun twoKeysCollapsingToOneIdentifierAreReported() { + /* + * gui.startupDesign and gui.startup_design both become guiStartupDesign. Generating + * both would produce Kotlin that does not compile, and the compiler's message names + * the generated file -- which tells a contributor nothing about their properties file. + */ + val collisions = identifierCollisions(listOf("gui.startupDesign", "gui.startup_design")) + + assertEquals(1, collisions.size) + assertEquals( + listOf("gui.startupDesign", "gui.startup_design"), + collisions.getValue("guiStartupDesign").sorted(), + ) + } + + @Test + fun distinctKeysReportNoCollision() { + assertTrue(identifierCollisions(listOf("a.b", "c.d")).isEmpty()) + } + + @Test + fun aKeyThatWouldNotFormALegalIdentifierIsRejected() { + /* + * identifierFor strips only . _ -, so every other character a Properties file can + * carry in a key -- a space, a brace, a quote, a newline decoded from a \uXXXX escape + * -- would reach identifier position verbatim. Emitted there it does not merely fail + * to compile: it breaks out of `val : String get() = ...` into whatever the key + * says, which is Kotlin that then runs. So the generated name is held to the shape of + * an identifier before it is ever written. + */ + val illegal = illegalIdentifierKeys( + listOf("settings.save", "a b", "x\": String get() = \"\"", "init { pwn() }\n val") + ) + + assertEquals( + listOf("a b", "init { pwn() }\n val", "x\": String get() = \"\""), + illegal.sorted(), + ) + } + + @Test + fun ordinaryKeysFormLegalIdentifiersAndAreNotRejected() { + // A digit-leading key is fine: identifierFor prefixes it, which is a letter again. + assertTrue( + illegalIdentifierKeys(listOf("settings.save", "gui.startup_design", "2.metres")).isEmpty() + ) + } +} diff --git a/jstack_dump.txt b/jstack_dump.txt new file mode 100644 index 00000000..d891562b --- /dev/null +++ b/jstack_dump.txt @@ -0,0 +1,198 @@ +2026-09-28 22:09:12 +Full thread dump OpenJDK 64-Bit Server VM (21.0.12.1+1-LTS mixed mode, sharing): + +Threads class SMR info: +_java_thread_list=0x00000078070997c0, length=17, elements={ +0x0000000102ba9020, 0x0000007807110000, 0x0000007807110700, 0x0000007807110e00, +0x0000007807111500, 0x0000007806d6c000, 0x0000007806d6c800, 0x0000007807111c00, +0x0000007807112300, 0x0000007807113800, 0x0000007807468000, 0x0000007807469500, +0x000000780746a300, 0x000000780746b100, 0x0000007807794000, 0x0000007807797800, +0x0000007807c22300 +} + +"Reference Handler" #9 [29699] daemon prio=10 os_prio=31 cpu=0,18ms elapsed=71,66s tid=0x0000000102ba9020 nid=29699 waiting on condition [0x000000016edea000] + java.lang.Thread.State: RUNNABLE + at java.lang.ref.Reference.waitForReferencePendingList(java.base@21.0.12.1/Native Method) + at java.lang.ref.Reference.processPendingReferences(java.base@21.0.12.1/Reference.java:246) + at java.lang.ref.Reference$ReferenceHandler.run(java.base@21.0.12.1/Reference.java:208) + +"Finalizer" #10 [24579] daemon prio=8 os_prio=31 cpu=0,04ms elapsed=71,66s tid=0x0000007807110000 nid=24579 in Object.wait() [0x000000016eff6000] + java.lang.Thread.State: WAITING (on object monitor) + at java.lang.Object.wait0(java.base@21.0.12.1/Native Method) + - waiting on <0x0000007017008078> (a java.lang.ref.NativeReferenceQueue$Lock) + at java.lang.Object.wait(java.base@21.0.12.1/Object.java:366) + at java.lang.Object.wait(java.base@21.0.12.1/Object.java:339) + at java.lang.ref.NativeReferenceQueue.await(java.base@21.0.12.1/NativeReferenceQueue.java:48) + at java.lang.ref.ReferenceQueue.remove0(java.base@21.0.12.1/ReferenceQueue.java:158) + at java.lang.ref.NativeReferenceQueue.remove(java.base@21.0.12.1/NativeReferenceQueue.java:89) + - locked <0x0000007017008078> (a java.lang.ref.NativeReferenceQueue$Lock) + at java.lang.ref.Finalizer$FinalizerThread.run(java.base@21.0.12.1/Finalizer.java:173) + +"Signal Dispatcher" #11 [29187] daemon prio=9 os_prio=31 cpu=0,16ms elapsed=71,66s tid=0x0000007807110700 nid=29187 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"Service Thread" #12 [25091] daemon prio=9 os_prio=31 cpu=0,07ms elapsed=71,66s tid=0x0000007807110e00 nid=25091 runnable [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"Monitor Deflation Thread" #13 [28675] daemon prio=9 os_prio=31 cpu=4,73ms elapsed=71,66s tid=0x0000007807111500 nid=28675 runnable [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"C2 CompilerThread0" #14 [25603] daemon prio=9 os_prio=31 cpu=94,63ms elapsed=71,66s tid=0x0000007806d6c000 nid=25603 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + No compile task + +"C1 CompilerThread0" #17 [26115] daemon prio=9 os_prio=31 cpu=99,66ms elapsed=71,66s tid=0x0000007806d6c800 nid=26115 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + No compile task + +"Notification Thread" #18 [28163] daemon prio=9 os_prio=31 cpu=0,02ms elapsed=71,66s tid=0x0000007807111c00 nid=28163 runnable [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"Common-Cleaner" #19 [26371] daemon prio=8 os_prio=31 cpu=0,28ms elapsed=71,66s tid=0x0000007807112300 nid=26371 waiting on condition [0x000000016fe4a000] + java.lang.Thread.State: TIMED_WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.12.1/Native Method) + - parking to wait for <0x0000007017020078> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.parkNanos(java.base@21.0.12.1/LockSupport.java:269) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.12.1/AbstractQueuedSynchronizer.java:1886) + at java.lang.ref.ReferenceQueue.await(java.base@21.0.12.1/ReferenceQueue.java:71) + at java.lang.ref.ReferenceQueue.remove0(java.base@21.0.12.1/ReferenceQueue.java:143) + at java.lang.ref.ReferenceQueue.remove(java.base@21.0.12.1/ReferenceQueue.java:218) + at jdk.internal.ref.CleanerImpl.run(java.base@21.0.12.1/CleanerImpl.java:140) + at java.lang.Thread.runWith(java.base@21.0.12.1/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.12.1/Thread.java:1583) + at jdk.internal.misc.InnocuousThread.run(java.base@21.0.12.1/InnocuousThread.java:186) + +"JavaFX Application Thread" #21 [259] daemon prio=5 os_prio=31 cpu=156,80ms elapsed=71,59s tid=0x0000007807113800 nid=259 waiting on condition [0x000000016d9dc000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.12.1/Native Method) + - parking to wait for <0x00000070178d17f0> (a java.util.concurrent.CountDownLatch$Sync) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.12.1/LockSupport.java:221) + at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(java.base@21.0.12.1/AbstractQueuedSynchronizer.java:788) + at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(java.base@21.0.12.1/AbstractQueuedSynchronizer.java:1133) + at java.util.concurrent.CountDownLatch.await(java.base@21.0.12.1/CountDownLatch.java:230) + at kst4contest.view.compose.OperatorProfilePickerWindow.showAndSelect(OperatorProfilePickerWindow.kt:132) + at kst4contest.view.Kst4ContestApplication$$Lambda/0x000000c0011c5fb0.requestProfileChoice(Unknown Source) + at kst4contest.view.OperatorProfileBootstrap.resolveAtStartup(OperatorProfileBootstrap.java:69) + at kst4contest.view.Kst4ContestApplication.resolveOperatorProfileIfRequired(Kst4ContestApplication.java:6642) + at kst4contest.view.Kst4ContestApplication.start(Kst4ContestApplication.java:7319) + at kst4contest.view.Kst4ContestApplication.lambda$main$84(Kst4ContestApplication.java:9777) + at kst4contest.view.Kst4ContestApplication$$Lambda/0x000000c00109e388.run(Unknown Source) + at com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:456) + at com.sun.javafx.application.PlatformImpl$$Lambda/0x000000c00109fc68.run(Unknown Source) + at java.security.AccessController.executePrivileged(java.base@21.0.12.1/AccessController.java:778) + at java.security.AccessController.doPrivileged(java.base@21.0.12.1/AccessController.java:400) + at com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:455) + at com.sun.javafx.application.PlatformImpl$$Lambda/0x000000c00109ebd8.run(Unknown Source) + at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:95) + +"AWT-Shutdown" #22 [60947] prio=5 os_prio=31 cpu=0,33ms elapsed=71,56s tid=0x0000007807468000 nid=60947 in Object.wait() [0x000000017037a000] + java.lang.Thread.State: WAITING (on object monitor) + at java.lang.Object.wait0(java.base@21.0.12.1/Native Method) + - waiting on <0x0000007017030078> (a java.lang.Object) + at java.lang.Object.wait(java.base@21.0.12.1/Object.java:366) + at java.lang.Object.wait(java.base@21.0.12.1/Object.java:339) + at sun.awt.AWTAutoShutdown.run(java.desktop@21.0.12.1/AWTAutoShutdown.java:291) + - locked <0x0000007017030078> (a java.lang.Object) + at java.lang.Thread.runWith(java.base@21.0.12.1/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.12.1/Thread.java:1583) + +"QuantumRenderer-0" #23 [78875] daemon prio=5 os_prio=31 cpu=31,70ms elapsed=71,45s tid=0x0000007807469500 nid=78875 waiting on condition [0x0000000170792000] + java.lang.Thread.State: WAITING (parking) + at jdk.internal.misc.Unsafe.park(java.base@21.0.12.1/Native Method) + - parking to wait for <0x0000007017000120> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) + at java.util.concurrent.locks.LockSupport.park(java.base@21.0.12.1/LockSupport.java:371) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionNode.block(java.base@21.0.12.1/AbstractQueuedSynchronizer.java:519) + at java.util.concurrent.ForkJoinPool.unmanagedBlock(java.base@21.0.12.1/ForkJoinPool.java:3780) + at java.util.concurrent.ForkJoinPool.managedBlock(java.base@21.0.12.1/ForkJoinPool.java:3725) + at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(java.base@21.0.12.1/AbstractQueuedSynchronizer.java:1746) + at java.util.concurrent.LinkedBlockingQueue.take(java.base@21.0.12.1/LinkedBlockingQueue.java:435) + at java.util.concurrent.ThreadPoolExecutor.getTask(java.base@21.0.12.1/ThreadPoolExecutor.java:1070) + at java.util.concurrent.ThreadPoolExecutor.runWorker(java.base@21.0.12.1/ThreadPoolExecutor.java:1130) + at java.util.concurrent.ThreadPoolExecutor$Worker.run(java.base@21.0.12.1/ThreadPoolExecutor.java:642) + at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:126) + at java.lang.Thread.runWith(java.base@21.0.12.1/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.12.1/Thread.java:1583) + +"InvokeLaterDispatcher" #25 [77323] daemon prio=5 os_prio=31 cpu=0,20ms elapsed=71,42s tid=0x000000780746a300 nid=77323 in Object.wait() [0x000000017099e000] + java.lang.Thread.State: WAITING (on object monitor) + at java.lang.Object.wait0(java.base@21.0.12.1/Native Method) + - waiting on <0x00000070170100e0> (a java.lang.StringBuilder) + at java.lang.Object.wait(java.base@21.0.12.1/Object.java:366) + at java.lang.Object.wait(java.base@21.0.12.1/Object.java:339) + at com.sun.glass.ui.InvokeLaterDispatcher.run(InvokeLaterDispatcher.java:126) + - locked <0x00000070170100e0> (a java.lang.StringBuilder) + +"DestroyJavaVM" #26 [5123] prio=5 os_prio=31 cpu=115,75ms elapsed=71,40s tid=0x000000780746b100 nid=5123 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"PulseTimer-CVDisplayLink thread" #27 [76291] daemon prio=5 os_prio=31 cpu=220,70ms elapsed=71,40s tid=0x0000007807794000 nid=76291 runnable [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"operator-profile-picker" #36 [88579] daemon prio=5 os_prio=31 cpu=16,50ms elapsed=71,31s tid=0x0000007807797800 nid=88579 runnable [0x0000000171e15000] + java.lang.Thread.State: RUNNABLE + at sun.lwawt.macosx.LWCToolkit.loadNativeColors(java.desktop@21.0.12.1/Native Method) + at sun.lwawt.macosx.LWCToolkit.loadSystemColors(java.desktop@21.0.12.1/LWCToolkit.java:232) + at java.awt.SystemColor.updateSystemColors(java.desktop@21.0.12.1/SystemColor.java:475) + at java.awt.SystemColor.(java.desktop@21.0.12.1/SystemColor.java:467) + at jdk.internal.misc.Unsafe.ensureClassInitialized0(java.base@21.0.12.1/Native Method) + at jdk.internal.misc.Unsafe.ensureClassInitialized(java.base@21.0.12.1/Unsafe.java:1160) + at jdk.internal.reflect.MethodHandleAccessorFactory.ensureClassInitialized(java.base@21.0.12.1/MethodHandleAccessorFactory.java:301) + at jdk.internal.reflect.MethodHandleAccessorFactory.newFieldAccessor(java.base@21.0.12.1/MethodHandleAccessorFactory.java:141) + at jdk.internal.reflect.ReflectionFactory.newFieldAccessor(java.base@21.0.12.1/ReflectionFactory.java:145) + at java.lang.reflect.Field.acquireFieldAccessor(java.base@21.0.12.1/Field.java:1185) + at java.lang.reflect.Field.getFieldAccessor(java.base@21.0.12.1/Field.java:1164) + at java.lang.reflect.Field.get(java.base@21.0.12.1/Field.java:442) + at javax.swing.plaf.basic.BasicLookAndFeel.loadSystemColors(java.desktop@21.0.12.1/BasicLookAndFeel.java:427) + at javax.swing.plaf.basic.BasicLookAndFeel.initSystemColorDefaults(java.desktop@21.0.12.1/BasicLookAndFeel.java:367) + at com.apple.laf.AquaLookAndFeel.getDefaults(java.desktop@21.0.12.1/AquaLookAndFeel.java:252) + at javax.swing.UIManager.setLookAndFeel(java.desktop@21.0.12.1/UIManager.java:591) + at javax.swing.UIManager.setLookAndFeel(java.desktop@21.0.12.1/UIManager.java:637) + at org.jetbrains.skiko.Actuals_awtKt.setSystemLookAndFeel(Actuals.awt.kt:15) + at org.jetbrains.skiko.Setup.init(Setup.kt:25) + at org.jetbrains.skiko.Setup.init$default(Setup.kt:6) + at org.jetbrains.skiko.Library.load(Library.kt:59) + - locked <0x0000007017969990> (a org.jetbrains.skiko.Library) + at org.jetbrains.skia.impl.Library$Companion.staticLoad(Library.jvm.kt:12) + at androidx.compose.ui.ConfigureSwingGlobalsForCompose_desktopKt.configureSwingGlobalsForCompose(ConfigureSwingGlobalsForCompose.desktop.kt:49) + at androidx.compose.ui.ConfigureSwingGlobalsForCompose_desktopKt.configureSwingGlobalsForCompose$default(ConfigureSwingGlobalsForCompose.desktop.kt:37) + at androidx.compose.ui.window.Application_desktopKt.application(Application.desktop.kt:112) + at kst4contest.view.compose.OperatorProfilePickerWindow.showAndSelect$lambda$6(OperatorProfilePickerWindow.kt:110) + at kst4contest.view.compose.OperatorProfilePickerWindow$$Lambda/0x000000c0011c6850.run(Unknown Source) + at java.lang.Thread.runWith(java.base@21.0.12.1/Thread.java:1596) + at java.lang.Thread.run(java.base@21.0.12.1/Thread.java:1583) + +"Attach Listener" #37 [44883] daemon prio=9 os_prio=31 cpu=0,84ms elapsed=0,10s tid=0x0000007807c22300 nid=44883 waiting on condition [0x0000000000000000] + java.lang.Thread.State: RUNNABLE + +"GC Thread#8" os_prio=31 cpu=0,66ms elapsed=71,39s tid=0x00000078077a4400 nid=88067 runnable + +"GC Thread#7" os_prio=31 cpu=0,83ms elapsed=71,39s tid=0x000000780775bc00 nid=87555 runnable + +"GC Thread#6" os_prio=31 cpu=0,65ms elapsed=71,39s tid=0x000000780775b800 nid=74755 runnable + +"GC Thread#5" os_prio=31 cpu=0,60ms elapsed=71,39s tid=0x000000780775b400 nid=75267 runnable + +"GC Thread#4" os_prio=31 cpu=0,85ms elapsed=71,39s tid=0x000000780775b000 nid=74243 runnable + +"GC Thread#3" os_prio=31 cpu=0,64ms elapsed=71,39s tid=0x000000780775ac00 nid=75779 runnable + +"GC Thread#2" os_prio=31 cpu=0,75ms elapsed=71,39s tid=0x000000780775a800 nid=73731 runnable + +"GC Thread#1" os_prio=31 cpu=0,54ms elapsed=71,39s tid=0x000000780775a400 nid=73475 runnable + +"VM Thread" os_prio=31 cpu=2,69ms elapsed=71,67s tid=0x00000078070bd400 nid=20227 runnable + +"VM Periodic Task Thread" os_prio=31 cpu=27,45ms elapsed=71,67s tid=0x0000000102b9d350 nid=17411 waiting on condition + +"G1 Service" os_prio=31 cpu=1,35ms elapsed=71,67s tid=0x00000078070bc000 nid=16643 runnable + +"G1 Refine#0" os_prio=31 cpu=0,01ms elapsed=71,67s tid=0x0000000102b99870 nid=14595 runnable + +"G1 Conc#0" os_prio=31 cpu=0,01ms elapsed=71,67s tid=0x0000000102b96d90 nid=14851 runnable + +"G1 Main Marker" os_prio=31 cpu=0,02ms elapsed=71,67s tid=0x0000000102b962e0 nid=13571 runnable + +"GC Thread#0" os_prio=31 cpu=0,85ms elapsed=71,67s tid=0x0000000102b95450 nid=13059 runnable + +JNI global refs: 24, weak refs: 0 + diff --git a/mvnw b/mvnw deleted file mode 100755 index 8d937f4c..00000000 --- a/mvnw +++ /dev/null @@ -1,308 +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. -# ---------------------------------------------------------------------------- - -# ---------------------------------------------------------------------------- -# Apache Maven Wrapper startup batch script, version 3.2.0 -# -# Required ENV vars: -# ------------------ -# JAVA_HOME - location of a JDK home dir -# -# Optional ENV vars -# ----------------- -# 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 /usr/local/etc/mavenrc ] ; then - . /usr/local/etc/mavenrc - fi - - 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 - # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home - # See https://developer.apple.com/library/mac/qa/qa1170/_index.html - if [ -z "$JAVA_HOME" ]; then - if [ -x "/usr/libexec/java_home" ]; then - JAVA_HOME="$(/usr/libexec/java_home)"; export JAVA_HOME - else - JAVA_HOME="/Library/Java/Home"; export JAVA_HOME - fi - fi - ;; -esac - -if [ -z "$JAVA_HOME" ] ; then - if [ -r /etc/gentoo-release ] ; then - JAVA_HOME=$(java-config --jre-home) - fi -fi - -# For Cygwin, ensure paths are in UNIX format before anything is touched -if $cygwin ; then - [ -n "$JAVA_HOME" ] && - JAVA_HOME=$(cygpath --unix "$JAVA_HOME") - [ -n "$CLASSPATH" ] && - CLASSPATH=$(cygpath --path --unix "$CLASSPATH") -fi - -# For Mingw, ensure paths are in UNIX format before anything is touched -if $mingw ; then - [ -n "$JAVA_HOME" ] && [ -d "$JAVA_HOME" ] && - JAVA_HOME="$(cd "$JAVA_HOME" || (echo "cannot cd into $JAVA_HOME."; exit 1); pwd)" -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="$(\unset -f command 2>/dev/null; \command -v 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 - -# traverses directory structure from process work directory to filesystem root -# first directory with .mvn subdirectory is considered project base directory -find_maven_basedir() { - if [ -z "$1" ] - then - echo "Path not specified to find_maven_basedir" - return 1 - fi - - basedir="$1" - wdir="$1" - while [ "$wdir" != '/' ] ; do - if [ -d "$wdir"/.mvn ] ; then - basedir=$wdir - break - fi - # workaround for JBEAP-8937 (on Solaris 10/Sparc) - if [ -d "${wdir}" ]; then - wdir=$(cd "$wdir/.." || exit 1; pwd) - fi - # end of workaround - done - printf '%s' "$(cd "$basedir" || exit 1; pwd)" -} - -# concatenates all lines of a file -concat_lines() { - if [ -f "$1" ]; then - # Remove \r in case we run on Windows within Git Bash - # and check out the repository with auto CRLF management - # enabled. Otherwise, we may read lines that are delimited with - # \r\n and produce $'-Xarg\r' rather than -Xarg due to word - # splitting rules. - tr -s '\r\n' ' ' < "$1" - fi -} - -log() { - if [ "$MVNW_VERBOSE" = true ]; then - printf '%s\n' "$1" - fi -} - -BASE_DIR=$(find_maven_basedir "$(dirname "$0")") -if [ -z "$BASE_DIR" ]; then - exit 1; -fi - -MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}; export MAVEN_PROJECTBASEDIR -log "$MAVEN_PROJECTBASEDIR" - -########################################################################################## -# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -# This allows using the maven wrapper in projects that prohibit checking in binary data. -########################################################################################## -wrapperJarPath="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" -if [ -r "$wrapperJarPath" ]; then - log "Found $wrapperJarPath" -else - log "Couldn't find $wrapperJarPath, downloading it ..." - - if [ -n "$MVNW_REPOURL" ]; then - wrapperUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - else - wrapperUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - fi - while IFS="=" read -r key value; do - # Remove '\r' from value to allow usage on windows as IFS does not consider '\r' as a separator ( considers space, tab, new line ('\n'), and custom '=' ) - safeValue=$(echo "$value" | tr -d '\r') - case "$key" in (wrapperUrl) wrapperUrl="$safeValue"; break ;; - esac - done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" - log "Downloading from: $wrapperUrl" - - if $cygwin; then - wrapperJarPath=$(cygpath --path --windows "$wrapperJarPath") - fi - - if command -v wget > /dev/null; then - log "Found wget ... using wget" - [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--quiet" - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - wget $QUIET "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" - else - wget $QUIET --http-user="$MVNW_USERNAME" --http-password="$MVNW_PASSWORD" "$wrapperUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath" - fi - elif command -v curl > /dev/null; then - log "Found curl ... using curl" - [ "$MVNW_VERBOSE" = true ] && QUIET="" || QUIET="--silent" - if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then - curl $QUIET -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" - else - curl $QUIET --user "$MVNW_USERNAME:$MVNW_PASSWORD" -o "$wrapperJarPath" "$wrapperUrl" -f -L || rm -f "$wrapperJarPath" - fi - else - log "Falling back to using Java to download" - javaSource="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.java" - javaClass="$MAVEN_PROJECTBASEDIR/.mvn/wrapper/MavenWrapperDownloader.class" - # For Cygwin, switch paths to Windows format before running javac - if $cygwin; then - javaSource=$(cygpath --path --windows "$javaSource") - javaClass=$(cygpath --path --windows "$javaClass") - fi - if [ -e "$javaSource" ]; then - if [ ! -e "$javaClass" ]; then - log " - Compiling MavenWrapperDownloader.java ..." - ("$JAVA_HOME/bin/javac" "$javaSource") - fi - if [ -e "$javaClass" ]; then - log " - Running MavenWrapperDownloader.java ..." - ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$wrapperUrl" "$wrapperJarPath") || rm -f "$wrapperJarPath" - fi - fi - fi -fi -########################################################################################## -# End of extension -########################################################################################## - -# If specified, validate the SHA-256 sum of the Maven wrapper jar file -wrapperSha256Sum="" -while IFS="=" read -r key value; do - case "$key" in (wrapperSha256Sum) wrapperSha256Sum=$value; break ;; - esac -done < "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.properties" -if [ -n "$wrapperSha256Sum" ]; then - wrapperSha256Result=false - if command -v sha256sum > /dev/null; then - if echo "$wrapperSha256Sum $wrapperJarPath" | sha256sum -c > /dev/null 2>&1; then - wrapperSha256Result=true - fi - elif command -v shasum > /dev/null; then - if echo "$wrapperSha256Sum $wrapperJarPath" | shasum -a 256 -c > /dev/null 2>&1; then - wrapperSha256Result=true - fi - else - echo "Checksum validation was requested but neither 'sha256sum' or 'shasum' are available." - echo "Please install either command, or disable validation by removing 'wrapperSha256Sum' from your maven-wrapper.properties." - exit 1 - fi - if [ $wrapperSha256Result = false ]; then - echo "Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised." >&2 - echo "Investigate or delete $wrapperJarPath to attempt a clean download." >&2 - echo "If you updated your Maven version, you need to update the specified wrapperSha256Sum property." >&2 - exit 1 - fi -fi - -MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" - -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$JAVA_HOME" ] && - JAVA_HOME=$(cygpath --path --windows "$JAVA_HOME") - [ -n "$CLASSPATH" ] && - CLASSPATH=$(cygpath --path --windows "$CLASSPATH") - [ -n "$MAVEN_PROJECTBASEDIR" ] && - MAVEN_PROJECTBASEDIR=$(cygpath --path --windows "$MAVEN_PROJECTBASEDIR") -fi - -# 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 - -# shellcheck disable=SC2086 # safe args -exec "$JAVACMD" \ - $MAVEN_OPTS \ - $MAVEN_DEBUG_OPTS \ - -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ - "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd deleted file mode 100644 index c4586b56..00000000 --- a/mvnw.cmd +++ /dev/null @@ -1,205 +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 Apache Maven Wrapper startup batch script, version 3.2.0 -@REM -@REM Required ENV vars: -@REM JAVA_HOME - location of a JDK home dir -@REM -@REM Optional ENV vars -@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 keystroke 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 set title of command window -title %0 -@REM enable echoing by 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 "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %* -if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\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 - -@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 - -set WRAPPER_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - -FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperUrl" SET WRAPPER_URL=%%B -) - -@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central -@REM This allows using the maven wrapper in projects that prohibit checking in binary data. -if exist %WRAPPER_JAR% ( - if "%MVNW_VERBOSE%" == "true" ( - echo Found %WRAPPER_JAR% - ) -) else ( - if not "%MVNW_REPOURL%" == "" ( - SET WRAPPER_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.2.0/maven-wrapper-3.2.0.jar" - ) - if "%MVNW_VERBOSE%" == "true" ( - echo Couldn't find %WRAPPER_JAR%, downloading it ... - echo Downloading from: %WRAPPER_URL% - ) - - powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ - "}" - if "%MVNW_VERBOSE%" == "true" ( - echo Finished downloading %WRAPPER_JAR% - ) -) -@REM End of extension - -@REM If specified, validate the SHA-256 sum of the Maven wrapper jar file -SET WRAPPER_SHA_256_SUM="" -FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( - IF "%%A"=="wrapperSha256Sum" SET WRAPPER_SHA_256_SUM=%%B -) -IF NOT %WRAPPER_SHA_256_SUM%=="" ( - powershell -Command "&{"^ - "$hash = (Get-FileHash \"%WRAPPER_JAR%\" -Algorithm SHA256).Hash.ToLower();"^ - "If('%WRAPPER_SHA_256_SUM%' -ne $hash){"^ - " Write-Output 'Error: Failed to validate Maven wrapper SHA-256, your Maven wrapper might be compromised.';"^ - " Write-Output 'Investigate or delete %WRAPPER_JAR% to attempt a clean download.';"^ - " Write-Output 'If you updated your Maven version, you need to update the specified wrapperSha256Sum property.';"^ - " exit 1;"^ - "}"^ - "}" - if ERRORLEVEL 1 goto error -) - -@REM Provide a "standardized" way to retrieve the CLI args that will -@REM work with both Windows and non-Windows executions. -set MAVEN_CMD_LINE_ARGS=%* - -%MAVEN_JAVA_EXE% ^ - %JVM_CONFIG_MAVEN_PROPS% ^ - %MAVEN_OPTS% ^ - %MAVEN_DEBUG_OPTS% ^ - -classpath %WRAPPER_JAR% ^ - "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^ - %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* -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 "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat" -if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\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% - -cmd /C exit /B %ERROR_CODE% diff --git a/packaging/AddModules.java b/packaging/AddModules.java deleted file mode 100644 index e3d8f2b9..00000000 --- a/packaging/AddModules.java +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Derives the jpackage --add-modules list from module-info.java so that the - * packaging scripts never drift from the module descriptor again. - * - * Run as a single file source program, which behaves identically on the Linux, - * macOS and Windows runners: - * - * java packaging/AddModules.java print the module list - * java packaging/AddModules.java --verify-pom fail if pom.xml drifted - * - * Only platform modules are emitted. Third party requires such as jlayer are - * skipped because they are supplied as ordinary jars on the class path, and - * automatic modules cannot be linked into a runtime image at all. Test only - * requires such as org.junit.jupiter.api are skipped for the same reason. - */ - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.Set; -import java.util.TreeSet; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public final class AddModules { - - private static final Path DESCRIPTOR = - Path.of("src", "main", "java", "module-info.java"); - - private static final Path POM = Path.of("pom.xml"); - - /** Matches "requires [transitive] [static] some.module;" in any order. */ - private static final Pattern REQUIRES = Pattern.compile( - "requires\\s+((?:transitive\\s+|static\\s+)*)([A-Za-z0-9_.]+)\\s*;"); - - private static final Pattern ADD_MODULE = - Pattern.compile("\\s*([A-Za-z0-9_.]+)\\s*"); - - private static final Pattern BLOCK_COMMENT = - Pattern.compile("/\\*.*?\\*/", Pattern.DOTALL); - - private static final Pattern LINE_COMMENT = Pattern.compile("//[^\\n]*"); - - private AddModules() { - } - - public static void main(String[] args) throws IOException { - boolean verifyPom = args.length > 0 && "--verify-pom".equals(args[0]); - - Set required = platformModules(read(DESCRIPTOR)); - if (required.isEmpty()) { - fail("No platform modules found in " + DESCRIPTOR); - } - - if (!verifyPom) { - System.out.println(String.join(",", required)); - return; - } - - Set declared = new TreeSet<>(); - Matcher matcher = ADD_MODULE.matcher(read(POM)); - while (matcher.find()) { - declared.add(matcher.group(1)); - } - - if (declared.equals(required)) { - System.out.println("pom.xml matches module-info.java (" - + required.size() + " modules)"); - return; - } - - Set missing = new TreeSet<>(required); - missing.removeAll(declared); - Set extra = new TreeSet<>(declared); - extra.removeAll(required); - - System.err.println("pom.xml drifted from module-info.java."); - if (!missing.isEmpty()) { - System.err.println(" missing in pom.xml: " + String.join(", ", missing)); - } - if (!extra.isEmpty()) { - System.err.println(" not required by module-info.java: " - + String.join(", ", extra)); - } - System.err.println(" expected: " + String.join(",", required)); - System.exit(1); - } - - /** Returns the platform modules required by the given descriptor, sorted. */ - static Set platformModules(String source) { - String stripped = LINE_COMMENT.matcher( - BLOCK_COMMENT.matcher(source).replaceAll(" ")).replaceAll(" "); - - Set modules = new TreeSet<>(); - Matcher matcher = REQUIRES.matcher(stripped); - while (matcher.find()) { - // "requires static" is a compile time only dependency and must not - // be linked into the shipped runtime image. - if (matcher.group(1).contains("static")) { - continue; - } - String module = matcher.group(2); - if (isPlatformModule(module)) { - modules.add(module); - } - } - return modules; - } - - private static boolean isPlatformModule(String module) { - return module.startsWith("java.") - || module.startsWith("jdk.") - || module.startsWith("javafx."); - } - - private static String read(Path path) throws IOException { - if (!Files.isRegularFile(path)) { - fail("Not found: " + path.toAbsolutePath() - + " (run this from the repository root)"); - } - return Files.readString(path); - } - - private static void fail(String message) { - System.err.println(message); - System.exit(2); - } -} diff --git a/packaging/aur/kst4contest-git/PKGBUILD b/packaging/aur/kst4contest-git/PKGBUILD index 947014d8..44685281 100644 --- a/packaging/aur/kst4contest-git/PKGBUILD +++ b/packaging/aur/kst4contest-git/PKGBUILD @@ -7,7 +7,7 @@ arch=('x86_64') url="https://github.com/praktimarc/kst4contest" license=('GPL-3.0-only') depends=('gst-plugins-base' 'gst-plugins-good') -makedepends=('java-environment=21' 'maven' 'git') +makedepends=('java-environment=21' 'gradle' 'git') provides=('kst4contest') conflicts=('kst4contest' 'kst4contest-bin') source=("kst4contest::git+https://github.com/praktimarc/kst4contest.git") @@ -15,8 +15,8 @@ sha256sums=('SKIP') pkgver() { cd "${srcdir}/kst4contest" - BASE=$(grep -m1 '' pom.xml \ - | sed 's/.*\(.*\)<\/version>.*/\1/' | sed 's/[-.]nightly//') + BASE=$(grep -m1 '^version=' gradle.properties \ + | cut -d= -f2 | sed 's/[-.]nightly//') printf '%s.r%s.g%s' "${BASE}" "$(git rev-list --count HEAD)" "$(git rev-parse --short HEAD)" } @@ -26,24 +26,13 @@ build() { export JAVA_HOME=$(find /usr/lib/jvm -maxdepth 1 -name 'java-21-*' -type d | head -n 1) export PATH="${JAVA_HOME}/bin:${PATH}" - mvn -B -DskipTests package dependency:copy-dependencies \ - -DincludeScope=runtime \ - -DoutputDirectory=target/dist-libs - - cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar + ./gradlew --offline -S :app-desktop:createDistributable + # package() reads dist/KST4Contest. Application name, icon and the JDK + # module list come from app-desktop/build.gradle.kts. + rm -rf dist mkdir -p dist - ADD_MODULES="$(java packaging/AddModules.java)" - jpackage \ - --type app-image \ - --name KST4Contest \ - --icon packaging/icons/kst4contest.png \ - --input target/dist-libs \ - --main-jar app.jar \ - --main-class kst4contest.view.Kst4ContestApplication \ - --module-path target/dist-libs \ - --add-modules "$ADD_MODULES" \ - --dest dist + cp -a app-desktop/build/compose/binaries/main/app/KST4Contest dist/ } package() { diff --git a/packaging/aur/kst4contest/PKGBUILD b/packaging/aur/kst4contest/PKGBUILD index 79aab26f..5c2e2f2a 100644 --- a/packaging/aur/kst4contest/PKGBUILD +++ b/packaging/aur/kst4contest/PKGBUILD @@ -7,7 +7,7 @@ arch=('x86_64') url="https://github.com/praktimarc/kst4contest" license=('GPL-3.0-only') depends=('gst-plugins-base' 'gst-plugins-good') -makedepends=('java-environment=21' 'maven') +makedepends=('java-environment=21' 'gradle') provides=('kst4contest') conflicts=('kst4contest-bin' 'kst4contest-git') source=("${pkgname}-${pkgver}.tar.gz::https://github.com/praktimarc/kst4contest/archive/refs/tags/v${pkgver}.tar.gz") @@ -19,38 +19,14 @@ build() { export JAVA_HOME=$(find /usr/lib/jvm -maxdepth 1 -name 'java-21-*' -type d | head -n 1) export PATH="${JAVA_HOME}/bin:${PATH}" - mvn -B -DskipTests package dependency:copy-dependencies \ - -DincludeScope=runtime \ - -DoutputDirectory=target/dist-libs - - cp "$(ls -t target/praktiKST-*.jar | head -n 1)" target/dist-libs/app.jar + ./gradlew --offline -S :app-desktop:createDistributable + # package() reads dist/KST4Contest. Application name, icon and the JDK + # module list come from app-desktop/build.gradle.kts, so this PKGBUILD no + # longer has to keep its own copy of them. + rm -rf dist mkdir -p dist - # This PKGBUILD builds from a released source tarball, which may predate - # packaging/AddModules.java. Older tarballs carry the same list in pom.xml, - # which the build keeps in sync with module-info.java from v1.42.0 onwards. - if [ -f packaging/AddModules.java ]; then - ADD_MODULES="$(java packaging/AddModules.java)" - else - ADD_MODULES="$(sed -n 's:.*\(.*\).*:\1:p' pom.xml | paste -sd,)" - fi - # Same story for the packaging icon: without --icon jpackage silently ships - # its own Duke placeholder, but tarballs older than v1.42.0 have no icon to - # point at, so only pass the flag when the file is actually there. - ICON_ARGS=() - if [ -f packaging/icons/kst4contest.png ]; then - ICON_ARGS=(--icon packaging/icons/kst4contest.png) - fi - jpackage \ - --type app-image \ - --name KST4Contest \ - "${ICON_ARGS[@]}" \ - --input target/dist-libs \ - --main-jar app.jar \ - --main-class kst4contest.view.Kst4ContestApplication \ - --module-path target/dist-libs \ - --add-modules "$ADD_MODULES" \ - --dest dist + cp -a app-desktop/build/compose/binaries/main/app/KST4Contest dist/ } package() { diff --git a/packaging/icons/generate-icons.sh b/packaging/icons/generate-icons.sh new file mode 100755 index 00000000..c661a49e --- /dev/null +++ b/packaging/icons/generate-icons.sh @@ -0,0 +1,90 @@ +#!/usr/bin/env bash +# Regenerate every raster icon from kst4contest.svg. +# +# The rasters are committed, so nothing in CI runs this — it exists so the +# icons can be rebuilt reproducibly whenever the SVG changes. Requires +# rsvg-convert (librsvg) and Python Pillow. +# +# packaging/icons/generate-icons.sh +# +# Outputs, all regenerated in place and mirrored into src/main/resources/icons +# so the in-app window icon matches what the launcher shows: +# kst4contest.png 256px, the size jpackage --icon feeds to every Linux +# package and the size hicolor/256x256/apps expects +# kst4contest.ico 16/24/32/48/64 as BMP, 128/256 as PNG (Windows convention) +# kst4contest.icns ic07-ic14, the modern macOS set up to 1024px + +set -euo pipefail + +ICON_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +REPO_ROOT="$(cd "${ICON_DIR}/../.." && pwd)" +cd "$REPO_ROOT" + +for tool in rsvg-convert python3; do + command -v "$tool" >/dev/null || { echo "Missing: $tool" >&2; exit 1; } +done +python3 -c "import PIL" 2>/dev/null || { echo "Missing: Python Pillow" >&2; exit 1; } + +# The SVG asks for 'Space Grotesk' and falls back to Helvetica Neue, then Arial. +# Whichever is installed is baked into the raster, so a machine with a different +# font set produces visibly different icons. Warn rather than fail — Arial is +# the author's own third choice and renders acceptably. +if ! fc-list 2>/dev/null | grep -qi "space grotesk"; then + echo "WARNING: 'Space Grotesk' is not installed; the KST wordmark will be" + echo " rendered with a fallback font (checked: $(fc-match 'Space Grotesk' 2>/dev/null | head -1))." +fi + +python3 - <<'PY' +import struct, subprocess, os +from PIL import Image + +SRC, OUT = "packaging/icons/kst4contest.svg", "packaging/icons" +_cache = {} + +def render(size): + if size not in _cache: + p = f"/tmp/kst4contest-icon-{size}.png" + subprocess.run(["rsvg-convert", "-w", str(size), "-h", str(size), SRC, "-o", p], check=True) + _cache[size] = p + return _cache[size] + +# --- Linux ------------------------------------------------------------- +Image.open(render(256)).convert("RGBA").save(f"{OUT}/kst4contest.png", optimize=True) + +# --- Windows ----------------------------------------------------------- +def bmp_entry(im): + w, h = im.size + px = im.load() + hdr = struct.pack("I", len(data) + 8) + data +open(f"{OUT}/kst4contest.icns", "wb").write(b"icns" + struct.pack(">I", len(chunks) + 8) + chunks) +PY + +cp packaging/icons/kst4contest.{png,ico,icns} src/main/resources/icons/ +echo "Regenerated packaging/icons and src/main/resources/icons from kst4contest.svg" diff --git a/packaging/macos/build-signed-dmg.sh b/packaging/macos/build-signed-dmg.sh index e3691e65..6cb136dc 100755 --- a/packaging/macos/build-signed-dmg.sh +++ b/packaging/macos/build-signed-dmg.sh @@ -4,8 +4,9 @@ # # jpackage cannot sign the app itself: it ad-hoc signs the embedded runtime and # then re-runs codesign on the same files without --force, which codesign -# rejects with "is already signed". So this builds an unsigned app-image, signs -# it from the inside out ourselves, and only then wraps it into a DMG. +# rejects with "is already signed". So this takes the unsigned bundle from +# :app-desktop:createDistributable, signs it from the inside out ourselves, and +# only then wraps it into a DMG. # # Required: # SIGNING_IDENTITY The name part of the Developer ID Application certificate, @@ -49,42 +50,29 @@ elif [ -n "${NOTARY_PROFILE:-}" ]; then NOTARY_ARGS=(--keychain-profile "$NOTARY_PROFILE") fi -echo "==> Building JAR and collecting runtime dependencies" -chmod +x mvnw -./mvnw -B -DskipTests package \ - dependency:copy-dependencies -DincludeScope=runtime -DoutputDirectory=target/dist-libs -JAR="$(ls -t target/praktiKST-*.jar | head -n 1)" -cp "$JAR" target/dist-libs/app.jar +# The DMG carries the same version the Compose packaging stamps into the +# bundle. gradle.properties keeps that value free of a qualifier, because the +# DMG and MSI formats reject one. +APP_VERSION="$(grep -m1 '^composePackageVersion=' gradle.properties | cut -d= -f2)" +[ -n "$APP_VERSION" ] || { echo "composePackageVersion missing from gradle.properties" >&2; exit 1; } +echo "==> Bundle version: $APP_VERSION" -# jpackage only accepts a numeric major[.minor[.patch]] as the macOS bundle -# version, so a Maven qualifier like "-nightly" has to be trimmed off. -POM_VERSION="${JAR##*/praktiKST-}" -POM_VERSION="${POM_VERSION%.jar}" -APP_VERSION="$(printf '%s' "$POM_VERSION" | sed -e 's/[^0-9.].*$//' -e 's/\.*$//')" -[ -n "$APP_VERSION" ] || { echo "Could not derive app version from $JAR" >&2; exit 1; } -echo "==> Version: $POM_VERSION -> bundle version $APP_VERSION" +echo "==> Step 1/4: building the unsigned app bundle" +chmod +x gradlew +# createDistributable builds the bundle including its jlinked runtime. Name, +# icon, bundle identifier and the JDK module list all come from +# app-desktop/build.gradle.kts, so this script cannot drift from the CI build. +MACOSX_DEPLOYMENT_TARGET="13.0" ./gradlew -S :app-desktop:createDistributable -echo "==> Step 1/4: jpackage app-image (unsigned)" rm -rf dist -mkdir -p dist -ADD_MODULES="$(java packaging/AddModules.java)" - -MACOSX_DEPLOYMENT_TARGET="13.0" jpackage \ - --type app-image \ - --name KST4Contest \ - --app-version "$APP_VERSION" \ - --icon packaging/icons/kst4contest.icns \ - --input target/dist-libs \ - --main-jar app.jar \ - --main-class kst4contest.view.Kst4ContestApplication \ - --module-path target/dist-libs \ - --add-modules "$ADD_MODULES" \ - --mac-package-identifier "$BUNDLE_ID" \ - --mac-package-name KST4Contest \ - --dest dist/appimage +mkdir -p dist/appimage +# ditto and not cp -R: the signing steps below depend on extended attributes, +# and only ditto preserves them. +ditto app-desktop/build/compose/binaries/main/app/KST4Contest.app \ + dist/appimage/KST4Contest.app APP="dist/appimage/KST4Contest.app" -[ -d "$APP" ] || { echo "jpackage produced no app image" >&2; exit 1; } +[ -d "$APP" ] || { echo "createDistributable produced no app bundle" >&2; exit 1; } echo "==> Step 2/4: signing bundle contents (this takes a few minutes)" @@ -208,8 +196,92 @@ STAGE="$(mktemp -d)" ditto "$APP" "$STAGE/KST4Contest.app" ln -s /Applications "$STAGE/Applications" -hdiutil create -volname "KST4Contest" -srcfolder "$STAGE" \ - -ov -format UDZO -quiet "$DMG" +# The installer window shows a background with an arrow from the app to the +# Applications folder. Finder only stores that layout (.DS_Store) when it has +# arranged a mounted, writable image itself, so this drives Finder through +# AppleScript. That can fail, e.g. without automation permission for Finder or +# on a headless CI runner; the DMG is then built without the layout and only a +# warning is printed. Window size and icon positions must match +# packaging/macos/dmg/render-background.swift. +DMG_BACKGROUND="packaging/macos/dmg/background.tiff" +VOLUME_NAME="KST4Contest" + +build_dmg_with_layout() { + local mount_point="/Volumes/$VOLUME_NAME" + local rw_dir rw_dmg size_mb + + if [ ! -f "$DMG_BACKGROUND" ]; then + echo " $DMG_BACKGROUND is missing" >&2 + return 1 + fi + # Finder addresses the disk by its name; a second mounted volume of the same + # name would get another name and break the stored background reference. + if [ -e "$mount_point" ]; then + echo " $mount_point is already mounted, eject it first" >&2 + return 1 + fi + + rw_dir="$(mktemp -d)" + rw_dmg="$rw_dir/KST4Contest-rw.dmg" + # Some headroom for the background picture and the .DS_Store Finder writes. + size_mb=$(( $(du -sm "$STAGE" | cut -f1) + 20 )) + + hdiutil create -volname "$VOLUME_NAME" -srcfolder "$STAGE" -fs HFS+ \ + -format UDRW -size "${size_mb}m" -ov -quiet "$rw_dmg" || { rm -rf "$rw_dir"; return 1; } + hdiutil attach "$rw_dmg" -readwrite -noverify -noautoopen -quiet || { rm -rf "$rw_dir"; return 1; } + + local layout_ok=0 + mkdir -p "$mount_point/.background" \ + && cp "$DMG_BACKGROUND" "$mount_point/.background/background.tiff" \ + && osascript <&2 + rm -f "$DMG" + hdiutil create -volname "$VOLUME_NAME" -srcfolder "$STAGE" \ + -ov -format UDZO -quiet "$DMG" +fi rm -rf "$STAGE" [ -f "$DMG" ] || { echo "hdiutil produced no DMG" >&2; exit 1; } diff --git a/packaging/macos/dmg/background.tiff b/packaging/macos/dmg/background.tiff new file mode 100644 index 0000000000000000000000000000000000000000..ddbe52e624575c64e54f776bd4fab1640bedd948 GIT binary patch literal 761748 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%0Dq2W|hOYucR}SByZGIHYNHD!RdoG>v2&e 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 z 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 !6=Ox^DYY_7{L8Vc3#WrwvzkE=hlwBqD(`J^~ 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­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

8_)%K=?|Jm(BGqxXhimL2P17e?}*U@3vqv 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

1P&h-0HoHk!c98OePQMmg3a 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 literal 0 HcmV?d00001 diff --git a/packaging/macos/dmg/render-background.swift b/packaging/macos/dmg/render-background.swift new file mode 100644 index 00000000..c67d9565 --- /dev/null +++ b/packaging/macos/dmg/render-background.swift @@ -0,0 +1,131 @@ +// Renders the background of the macOS installer DMG window. +// +// Run from the repository root after changing the design; only the TIFF is kept: +// TMP="$(mktemp -d)" +// swift packaging/macos/dmg/render-background.swift "$TMP" +// tiffutil -cathidpicheck "$TMP/background.png" "$TMP/background@2x.png" \ +// -out packaging/macos/dmg/background.tiff +// +// The layout (window size, icon positions) must match build-signed-dmg.sh. +// Colors follow the green KST4Contest website theme and the application icon. + +import AppKit + +let windowWidth: CGFloat = 640 +let windowHeight: CGFloat = 400 +// Icon centers in Finder coordinates (origin top left), same values as in the build script. +let appIconCenter = CGPoint(x: 170, y: 180) +let applicationsIconCenter = CGPoint(x: 470, y: 180) +let iconSize: CGFloat = 128 + +func color(_ hex: UInt32, _ alpha: CGFloat = 1) -> CGColor { + CGColor(srgbRed: CGFloat((hex >> 16) & 0xff) / 255, + green: CGFloat((hex >> 8) & 0xff) / 255, + blue: CGFloat(hex & 0xff) / 255, + alpha: alpha) +} + +func render(scale: CGFloat, to path: String) { + let pixelWidth = Int(windowWidth * scale) + let pixelHeight = Int(windowHeight * scale) + guard let ctx = CGContext(data: nil, width: pixelWidth, height: pixelHeight, + bitsPerComponent: 8, bytesPerRow: 0, + space: CGColorSpace(name: CGColorSpace.sRGB)!, + bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue) else { + fatalError("Could not create drawing context") + } + + // Draw in Finder coordinates: origin top left, y pointing down. + ctx.scaleBy(x: scale, y: scale) + ctx.translateBy(x: 0, y: windowHeight) + ctx.scaleBy(x: 1, y: -1) + + let space = CGColorSpace(name: CGColorSpace.sRGB)! + + // Background: dark green gradient of the website theme. + let background = CGGradient(colorsSpace: space, + colors: [color(0x0b140f), color(0x050806)] as CFArray, + locations: [0, 1])! + ctx.drawLinearGradient(background, start: CGPoint(x: 0, y: 0), + end: CGPoint(x: 0, y: windowHeight), options: []) + + // Soft accent glow behind the arrow. + let glow = CGGradient(colorsSpace: space, + colors: [color(0x54d63d, 0.16), color(0x54d63d, 0)] as CFArray, + locations: [0, 1])! + let middle = CGPoint(x: (appIconCenter.x + applicationsIconCenter.x) / 2, y: appIconCenter.y) + ctx.drawRadialGradient(glow, startCenter: middle, startRadius: 0, + endCenter: middle, endRadius: 260, options: []) + + // Radio waves like in the icon, above the arrow. + ctx.setLineCap(.round) + ctx.setLineWidth(4) + let waveCenter = CGPoint(x: middle.x, y: middle.y - 18) + for (index, radius) in [CGFloat(14), 26].enumerated() { + ctx.setStrokeColor(color(0x8aef64, index == 0 ? 0.55 : 0.3)) + ctx.addArc(center: waveCenter, radius: radius, startAngle: -.pi / 4 - .pi / 2, + endAngle: .pi / 4 - .pi / 2, clockwise: false) + ctx.strokePath() + } + + // Arrow from the app to the Applications folder. + let arrowStart = appIconCenter.x + iconSize / 2 + 22 + let arrowEnd = applicationsIconCenter.x - iconSize / 2 - 22 + let arrowY = appIconCenter.y + let headLength: CGFloat = 22 + let headHalfWidth: CGFloat = 16 + + ctx.saveGState() + ctx.setShadow(offset: .zero, blur: 12, color: color(0x54d63d, 0.6)) + let arrowPath = CGMutablePath() + arrowPath.move(to: CGPoint(x: arrowStart, y: arrowY)) + arrowPath.addLine(to: CGPoint(x: arrowEnd - headLength + 2, y: arrowY)) + ctx.addPath(arrowPath) + ctx.setLineWidth(10) + ctx.setStrokeColor(color(0x54d63d)) + ctx.strokePath() + + let head = CGMutablePath() + head.move(to: CGPoint(x: arrowEnd, y: arrowY)) + head.addLine(to: CGPoint(x: arrowEnd - headLength, y: arrowY - headHalfWidth)) + head.addLine(to: CGPoint(x: arrowEnd - headLength, y: arrowY + headHalfWidth)) + head.closeSubpath() + ctx.addPath(head) + ctx.setFillColor(color(0x54d63d)) + ctx.setLineJoin(.round) + ctx.setLineWidth(4) + ctx.setStrokeColor(color(0x54d63d)) + ctx.drawPath(using: .fillStroke) + ctx.restoreGState() + + // Label plates: Finder draws icon labels black in light mode and white in dark + // mode, and the color cannot be configured. This mid tone keeps both readable + // (contrast about 4.6:1 for white and for black text). + let labelTop = appIconCenter.y + iconSize / 2 + 4 + for center in [appIconCenter, applicationsIconCenter] { + let plate = CGRect(x: center.x - 80, y: labelTop, width: 160, height: 26) + ctx.addPath(CGPath(roundedRect: plate, cornerWidth: 13, cornerHeight: 13, transform: nil)) + ctx.setFillColor(color(0x5c7d63)) + ctx.fillPath() + } + + // Thin accent line at the bottom, as used on the website. + ctx.setFillColor(color(0x31b54a)) + ctx.fill(CGRect(x: 0, y: windowHeight - 4, width: windowWidth, height: 4)) + + guard let image = ctx.makeImage() else { + fatalError("Could not render image") + } + let rep = NSBitmapImageRep(cgImage: image) + // 72 dpi for 1x and 144 dpi for 2x, so tiffutil can combine them into one HiDPI TIFF. + rep.size = NSSize(width: windowWidth, height: windowHeight) + guard let data = rep.representation(using: .png, properties: [:]) else { + fatalError("Could not encode PNG") + } + try! data.write(to: URL(fileURLWithPath: path)) +} + +let outputDirectory = CommandLine.arguments.count > 1 ? CommandLine.arguments[1] : "." +render(scale: 1, to: outputDirectory + "/background.png") +render(scale: 2, to: outputDirectory + "/background@2x.png") +print("Rendered background.png and background@2x.png into \(outputDirectory)") diff --git a/pom.xml b/pom.xml deleted file mode 100644 index f1d0b923..00000000 --- a/pom.xml +++ /dev/null @@ -1,510 +0,0 @@ - - - 4.0.0 - - de.x08 - praktiKST - 1.44.0-nightly - - praktiKST - - - DO5AMF - - - http://www.x08.de - - jar - - - - ${project.artifactId} - ${project.artifactId} - ${project.artifactId} - kst4contest.view.Kst4ContestApplication - 21 - 3.6.3 - ${project.artifactId}-${project.version} - - - 21.0.5 - 24.0.1 - 5.10.1 - 1.18.44 - 5.7.0 - 3.43.2.2 - - - 3.3.2 - 3.11.0 - 3.3.0 - 3.1.1 - 3.4.1 - 3.1.1 - 3.3.0 - 3.3.1 - 4.0.0-M11 - 3.2.2 - 3.2.0 - 1.0.0.RC2 - 0.1.3 - 3.28.0 - 7.17.0 - 2.16.1 - 0.0.8 - 4.9.8.2 - 4.9.8 - 3.1.0 - - - UTF-8 - ${java.version} - ${java.version} - ${java.version} - VERBOSE - - - - - - org.openjfx - javafx-controls - ${javafx.version} - - - org.openjfx - javafx-graphics - ${javafx.version} - - - org.openjfx - javafx-fxml - ${javafx.version} - - - org.openjfx - javafx-web - ${javafx.version} - - - org.openjfx - javafx-media - ${javafx.version} - - - - - javazoom - jlayer - 1.0.1 - - - - - org.xerial - sqlite-jdbc - ${sqlite.version} - - - - - org.projectlombok - lombok - ${lombok.version} - provided - - - - - org.junit.jupiter - junit-jupiter-engine - ${junit.version} - test - - - org.junit.jupiter - junit-jupiter-params - ${junit.version} - test - - - - - org.mockito - mockito-core - ${mockito.version} - test - - - org.mockito - mockito-junit-jupiter - ${mockito.version} - test - - - - - org.jetbrains - annotations - ${jetbrains.annotations.version} - compile - - - org.junit.jupiter - junit-jupiter-api - ${junit.version} - compile - - - org.mockito - mockito-core - 5.17.0 - compile - - - - - - - - ${jar.filename} - - - org.apache.maven.plugins - maven-wrapper-plugin - ${maven.wrapper.plugin} - - - org.apache.maven.plugins - maven-enforcer-plugin - ${maven.enforcer.plugin} - - - enforce-versions - - enforce - - - - - ${required.maven.version} - - - - - - - - - - org.codehaus.mojo - exec-maven-plugin - ${exec.maven.plugin} - - - verify-packaging-module-list - validate - - exec - - - ${java.home}/bin/java - ${project.basedir} - - packaging/AddModules.java - --verify-pom - - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - ${maven.compiler.plugin} - - ${java.version} - - - org.projectlombok - lombok - ${lombok.version} - - - - - - - org.apache.maven.plugins - maven-clean-plugin - ${maven.clean.plugin} - - - - org.apache.maven.plugins - maven-deploy-plugin - ${maven.deploy.plugin} - - - - org.apache.maven.plugins - maven-install-plugin - ${maven.install.plugin} - - - - org.apache.maven.plugins - maven-jar-plugin - ${maven.jar.plugin} - - - - org.apache.maven.plugins - maven-resources-plugin - ${maven.resources.plugin} - - - - org.apache.maven.plugins - maven-site-plugin - ${maven.site.plugin} - - - - org.apache.maven.plugins - maven-surefire-plugin - ${maven.surfire.plugin} - - true - - false - - - - - com.github.spotbugs - spotbugs-maven-plugin - ${spotbugs.maven.plugin} - - - - com.github.spotbugs - spotbugs - ${spotbugs.version} - - - - - prepare-package - - - spotbugs - - - - - - - - - - org.apache.maven.plugins - maven-pmd-plugin - ${maven.pmd.version} - - 100 - ${java.version} - false - - pmd-ruleset.xml - - - - - prepare-package - - - pmd - - - - - - - - - - org.codehaus.mojo - versions-maven-plugin - ${codehaus.version.plugin} - - - validate - - display-dependency-updates - display-plugin-updates - display-property-updates - - - - - - - - org.openjfx - javafx-maven-plugin - ${javafx.maven.plugin} - - ${main.class} - - - - - - - - - - - Image - - - Image - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - ${maven.dependency.plugin} - - - - copy-dependencies - package - - copy-dependencies - - - ${project.build.directory}/modules - runtime - false - false - true - - - - - - copy - install - - copy - - - ${project.build.directory}/modules - - - ${project.groupId} - ${project.artifactId} - ${project.version} - ${project.packaging} - ${project.build.finalName}.jar - - - true - - - - - - - com.github.akman - jpackage-maven-plugin - ${jpackage.maven.plugin} - - ${appName} - IMAGE - - - - - javafx\..* - - - - - - - java.desktop - java.net.http - java.sql - javafx.controls - javafx.fxml - javafx.media - javafx.web - jdk.crypto.ec - jdk.jsobject - jdk.net - jdk.xml.dom - - ${main.class} - ${project.build.directory}/modules - ${jar.filename}.jar - - - - install - - jpackage - - - - - - - - - - - \ No newline at end of file diff --git a/scratch/AAA01.png b/scratch/AAA01.png new file mode 100644 index 0000000000000000000000000000000000000000..6ea093e4c2b01441b54a3be735b06000071a4e97 GIT binary patch literal 621654 zcmZs?cTkgUw>^vv5Tr}50s;yFK?Uh86h)dy30;bSp(ssSK&00YX-bD6pb%;Z(nWgj z2@rZS^p;RU`*`2y{hjZeGv}|&WG0#Wy7t~{?R&4aqx5t%s3_PdNJvPio@)YMk&xU5 zlaSonCMUi6hPei(MshoV^EpuYwNJ+8`RxWzEkiEqGQYXhg+KOpMO$wzUyr^P3%pMo z_gT698tpIRxK9_hccPVJvxT1NT4(GZ9No|EnCB3*bC0~iqr-9;t$H`^x(+#YWF&7_ z{(D_WVf~u!sddo( z*!QH8gQ@3xYo%5Mrnj=SPIh*sbU!CT-kfV!nOnqIbVjJAnfS%rztF6g(>17i`fODS zmTq3_t|>@G9j57|;C1pIkZ(Df3%;pUP^y6fHB2d7^9I!+XCJb}&Q?B#{rYX4Yg2Sk zkRfC$P~*@e;cG~Ap>OfNhxPlT2jr%Zr)!E7VR~W44mb}>ax&@FEDNChpf4BE7iIkPXKKB zy1kAqDXNg{Z(h7GO@8_);J-hZ*=H+INBH-Ufsny>6w+S11ClHjp@BoigNCb02WAe^ zE)cVDyLYTp+v5Ztje{k3%F(^Flo)*hWxs$XX4%2JN@9P`0Hjc8X0fR|eUwL3*8y-N zS2;8_85GgD3cys7spi%{st-$CaqhUd>S7wU8j|B~I_B`vTtNvnd zX1}1>zy556efD9{5$cBTV2i!)irXdk3Bl?r6zNh8f!(h+7Uo)7)(;Xsd}yRCZ)pDD zWwGtmPi7?T_Z+&bkXgM=M}xA9KF(rcg+-P`VvZ(uTKvY6H2G6-Ao80-&l9rN))#CkVaeb50xbj= z#VQwZHZkRex;F(Wwi*kde=4;@p}93N-H*~VH*Z>MZr=XJD|g4q7dBMr>o;$YNYl}r zILe)R>2( zL|%yoNwtm^%6G5}>4u=eINqSMI;mdp#s1d5V9>F~{s?oE^~nf&@fIQ^ggsRZ3}^;` z_byi`&B%J0Q9X@2XDwbn`ry6K=oMjOqqzdFA;EkDl zC?Uq-cUZ0_Gtwbs@~iq!nz6(E>r6qf19@Q+4;pB}VL*Z2-p!w_8)3|JvPiy3`UJO0 z5gP}XLFO?@|7mJeWCt-dVZ(2x=Gf{PFVJ$VlA3<<4WI1YjD4D|X#3@nA;JGw1OL8z zAe}FL-NWpxH$Dymu?|Yhw}h`v+fE*bhBlgyuiMX|w}-3TUTa90T$VVUd$iXc)%D5r z+Ce|d)t7i^!+fxMGoE-`$k0fPb-KuTR9l#mY!tQ<7yQ`2+*)2%{j8+#%Z~hS<;u2s z+d+?8NsoacfTe@$VE&1UL%(aF4e2(ki~joMkC(XqePP9;gMG@&4UOfQoj@o@5FEXT ztVVB|zahcH&`1Q$;PO%)1_kHr-RBl*_^Y$jdf>KP#%+}=kN>tnJ z>xj{-?6%M4O(Rp=oP5G>wqW!LkdD&gS2&*(TvC>Jni-b0`zPhTO9*4Zpk%`>qf}5# z#Qp4+eQG!TO7+%*{C_azzooQE&R;u=kVeMe>vVA}4V!OrZhC2CU(bM;407tRvfa0E z>$V*vpLi~{f0NX0Ibz?aP_XmMcYD)8O%We17Q$@T zebvizv*rGv19jiQIH{g>Y&G?A#|j}X#trSK2S^naYgPjj9!I7wyJBWEE@u7)1qTeB zZ}VWL52ODDdwJY2HAQ02=Oc+bOJH9*-ko+sjjWpcZ=P80PmO4K4BEvUi;;k=qtZH4 ze+l7czVKvaAq<5X_DqN+e&Rg{fX;u1&;J}1Fk!&5VVH{(ex<44=NG0R56qsA+7&d4 zI=G3qvp3Uy(cq8-D}2#akU}=Dkp(?$AZK1UavtB!N+a|gLNapQ&Q6cIE`3+#dXCO9 zZYj+^{n=eDi|iW|q(~X7a#!8omosYHG3&r65L9&Ak!O$qeQ>bZ z?Ae#;HR_rq@b*FQzD8NV_Xa}0Tgt1Rk@@yPUdxB}dtcD@ptJ2Am!0<-C-}ij72n+( zvs$iR$^WLTPuI5*W7^FF`ZvXVTxzTJ7!3uqePKW3$IEX3-gU*}{**GmN|69Jp}EkC z*PWFiWdx=Ll%_#e*-w77l9=k6jAXjMWuMJ#lpSME^Y;TgpC5kzM>y}yGL&|K*-X)T zrP*gW2X1&ftsthn88Ni zMGeD#@;|`x|FsVTvL%8okpq4gpO?#1$MW2qd74x<*CDbzuxE-sOJ>x|%t0&A<)DBq zwa~Bp5d{QoDvAu?U$R&yB&}wtzrDs-lA$cOcd`=4Ew0ktJCn`;5h)3We&Ru0+=;_yxgI zN!9iuk}oKz8>XnRsCPJI90goN(mszIUU$4-A*6z)W;eB9x}^O;t@O?E!Emqbjk5TF zymbkk`~TNHzRW&^|9!sca{Dmp^wSW}BtXp1EU#MoPA#$9SAph*xybY$+WtfVtszJJ zus_1>+p?coBAhB_1(UV#mpVy^P&D5TDl7iZ#qo7?QB91vHhkXF;i9oo~&MIAMT=ynvOC|ytciM%TV^!pLZzsu3HYK&u-)fF;!A?SZVWn$KW=;(MdDz zqRw#s>kkv)xxOeWrc8e$d9Ankmwv`~i$&S!5acYd)PK;W;$DN8IAJz!=eYsj+5=(L zeSXbWTuBgqYLsT=4cxvgvaEH3UA=Rvj>;mEY{nm(g<~;sdGloWLggquBM}}{oO=qd zuJ}HVFNuvC<*1K&qZL}H5yXEO*=8HOTCvVb6{9glov(2>llqv9SY*-(TO{P=qKXIzl8yEb! zu|n8}BlT;U2Ah7ru+wjh%*4g)0!*{W*V!&}XSWN}yCry-G(ma4|Ob#U@bn`rVA555+zS@=Co({}1p^ zJkaYg=J4yl9Lyt&Hm01IWkY~88vy^I6YJBzxlbD89sG&T>#GW}yn{vsNp*HtWdVo08c)D<34J#mV>00%*Oa~1}TxOWRq@V48 zkEc}y3K;+pdx*hIxm5#jVX${yYLHSFS8UtnZq~JmiY-nIeS^k9?1?O!o2ON*%m>e^ zy-H^#TTBWFoJtM_0{|hb_7y*?pJV?V1CPG~iB_Gmy{Lt$cm8zKOvtz8zc3@F71#T@ z^)Z$KFaCoVn{-p!IW??f&jaW(Cg8;N2_A`=U%A@q0?7`yV~#4AcI+WzOQnhpO(MqI zKB@IRUOWEWwX3L9mAN|G;efMFMfZ~v14TmOz1iSEk|it?(>}8#(vL~<&YT@m$ZDE~ z(5GNA8<;-Eqk4cOCRjwO_ofNEF`SL*mb$QX=x*341mnEsG^Qp-;6AoQLx$G)&K(#u zBdL02szbSB1Rc!WHS;ijDryS7lC7pbH&)FuXq1A+pan(n8KKp?I)6$Gq`lMnbwtC) z_%4h}S?rx#pc%iTTd;wLyE*XIpQa#63Ly z&=$Zqb`V~j0u;c4kIZF(K33w=k?I>e6%M~JM8s>7Zua#Cg*Oj0sCsM_pmyu-05dyF z)5n6G(Zo$9xNk!2h*P?;!z6E8K_sYXL-zM8kje9suX?~LROO7!;GVOV zU2JBnn5T{(+nR(#f>b5Zs+S4`0 zqO~fYWTzJSMBVR9*0-J&7te5mKQzc%=qqM+Z z4&J%U6(tI6n{n~>VoYKW&zE)2ZX%tAn%iK+C{BA*bkm*jbx@D&2;r*2*M9}-d&>#f z|0E-#VQ0bHCZ*fLb{`)HJ>AkdJryeDnPg~w_HM3C5lYlP{abk!={A3C{3npWE58C>+!@}`(3@ncT)RTA&3!I~1U?m+gIDI1exDz#IODI2N; zS9c@NSas)QVxJj?NHub+Mf@fO%$cTXsbVdSZBk3Y!|P*s!_DvdVyCD0sz9MOb+=}y4^l2=mPfjeo0^1XU&~u3*NZC>^4@hX+Byg|AfU$iY~9-_h$E7iUvVVisoQhzsM34H|3RiZ)=+-#oHF+bgnJH_E zIq8f*V-4-^GT)L1gNF|_z0EocH0~4mmUu}oc`lU-AVM}+;ZLPqV`QL4QH}G^fCvI3 zB}3XETMSyXSTO;LTIuqZR3tT}n=K=n9z9MQt?btgB1V{3f_E=hs_!Fr1{)oJzT`TyP(^xI<-U zc<~5RN~D;#$Zqom2CD1W;AT2v9}=sfNMuOahxNJq2E$9aoy{ifyUUkN@gbYJy889l z$`mt@iSJW9=U92R^a^ z*Yg|#m06e@FOS<*Aq*d&^d;ObbW3%+vH^SIcaduwZit?5U*?QI; z(iv*c@^=J=jYR3dA-HXDF1P2@C`wyXdcdXh`w3rX2u+9jvjbR7eyAY+|X-{x627HN7Y=w z8zqg2n$E9)*~q@z$d_(dR90A5Vw}MH;;Kewz1byM&1QQ8Glh8`9vbbJOur~{4w&dH zO0yT$Ruc*nldCC>v?4ssVqQT9q+4E`3a2g2nyXiY0CLEHiiv>FwuY}s;SVG@M^*5* zA3*zJxUf^Yupbs=q*hvU=ryob&`mYx%SfEeBWI5FZ|3q`MKmIoV}hEZBTfidUvq++ z(d zU`8f{eN-I7fj#VNW7l7NfKYtA=G?zpO`8a%sFzejM`-c17Yg!zo^kY5n)KcDC7P8B z0CRmAP*b*7bI@L}`&wm#nW$Bd;iES>+U6k0a@PIK#U$ehu009XNK_-VBiTZSRW}eh zCn5t*bT62f)(~I!(m>Wf(T0EAG;KyZOn&)S|8i5QUc?vdXDG*e{7Jvp#{K8ZRJkPP za=CkT95tBnT!MQp+UPCK(ztsfEP(5rfCW(Q3zHhT3o z&e#iAvbVdA+;WkA7qcy;JvUYIH(pfZ)W5*sAi6SrvU~OVJF?MwKsgKQNQpY0wDG&f zwfy8@4(OVym!G~+IOj`mPaZuz6~g$B(KFcX;!|0Q#(Cd?SYj9iwU5j?WV>Z}m*nBl zo5}9aG^W2zhEO@3eU!fu7B4NqiKu=Gy_C2uhh76&XOYi;?;I$i2eN!Ivu3vF9(8fG z$d_&D7w7m zFzX6Ldql?HmqT+@Eiy*STE;T&Ee-H+@A-SQs3bdKpEm5x-J3|LR{f;XuiJ<^)y z6lM^59XIJ78ZN$g(bezym6o-pnf5&8oHy{RvQ~U#;~37{-_|C~;t3;2=vJzg>?E7wL zC$N{{p>WPw(bdoK8ih!uRbY@fKDB~I)Q9`vYiGQp?YYa<8{hg6;Vv23yTYMz#Cpdf z2E{bJs;my0IJedCQd>hdEvnqGpDu!+2l~ErJIZlctZwnh6D_BvE%@o#TdAReML**2 zB=z1-V5Y>_`bJuPb~gn99uBu3!vclN#tt{YJ56jT-!~1>LAblHQ9cju;d*EBESZq- zWZy`UOgeuNR;=Y)|CH0B46eGL*C|hLum9YL*m(OzpZx_N{5ybjErS`8vPtB7M{XX2OiS3`_(^FzNhW05x;G*PT-A0IldmAN;jDrE=^HE)gpY7=s ze{X=7`BJD%xqmWrlBzQRpgCL6u8T^UY$lq~x#H18Mpj)5_|$2bFQHN?CIEWv1i6&{aIy(iH-# zgV%&I2_6tf15WfrQHJm5u2tsl5Bu3acc6B6YH{z&2(R-C7qTaw>~anpRG+_2 z-b!?JnUa1mN)(YTIjftoVq`t~UYCWmTFZV}WhAvOHr~v~jyN+K`}F_<_jgHr;?0mP zf5?eQ-=tH2H`Pe8AN-K7*>g)3l7B*AG1>Cglg05Zun!v+2Bf<;9O6?nmNo3uJ8kE3 zTS?MHd3}f`UY6es2iB_*DGGE^95Y|tft%hj_@l5}0#-7|tS)1ux`FvFjv}-yR1{lL zKq(#UhgDn+Q-h_iJY@;X6Y*N(xij@z_x>%nz^~Xgs<#P4V;WzTWjZWcyL+)<(#Z2^50zIs=*_a#Wtb$Fh^4pBK%&+ zZ~PGB58O50HIlK8y}!0Kf|fPVgj+S8+dJHhav(3GvC>~1l%bt2#fjb}>uIg2&o9vh zFFPdSO}MTSKh{M-0z93GD|}FL$9mqW7xW%@9*n!H$1otfz>_KW!yjeCZ@+(*;Rowq zsUb9+Q>KA1CrvwcVU)P77Fm^5o2!S}T(~XgNQ_6>%38TAA#ogvV*{|(Y1hfYCfM(^ zgsy0c;Hr^KG+$z_Cv=WZ{oJDc)4QDW$y(d4p!Z8>Db{;^F1Q>Iw~n$i^{#gJ)9HGb z!v&z#go+*zGXc@KBaUIkZ6#s?mz|bwc4b(|3|zWps*x&VY;lR;l;l?0q-{OP=0dgz zR{VIaS5S;Xr>^mIs9Er7p%||p@vvc_+M=_hDpFI_b4n6;0-B8pT%wt4Bu$| zqp z;jm>z*Qmj#+?d6sRZ{@=s?48UQeKJGXf4*o=aTjotCnq)ykFTHsJJ&3Z<#5-GAwz7 ztWG5z9|Wna;{V=Km!^0zj?1~#pBH$HJT{&BATLv)w2v8ce_5MS*o!YDr`~g{W$9g# zqt9WSRF6FRY`6m)c{2QaVb5emUpjqie0Fe+S+~=iwK3SAUB;haQs>{vm`sQ#m`_Cl zJj$a6cVq`%v9I=hhx`@|*e_Yg$NCQwrCMN33D1gg-Ttf=I~Tz#=2^2YLx-#Wbk17F zJ5Bs)sz>pv(2~e3$C+ulx9qlaOTE}l;rf0Tgje{`Ec_tG$Y|#S@|gr#W=QCvWp)Mb zAj9bJYs3+!4EO%00gtaQZ);X_8D`wZhvKt-3>Oc=qry>HPO=VbI2eQDMw^?APp%F> z9~)85mn&0ER?vC-#=vquwF+6FH%`PxjP@mUV$}LW*xH(g7pyWe9@V#4Z~cpaa1}^( z^{(ob*sfS`6H;}exW4YvhOKfhXT0faakpJ)E==%_yHr$0do6VTk=XsPpzzAq|y*B6C?jI6B{N_p_h0pgNw$GLC%ODa4Q<(0C z>w!)k?(=FIi$&L!Do*WY;n*4Z-Ys{e{E9pqG4+MT8q>MWxquvJU}3jA>mS3=8FCw&w{$j3L8#{`mdmNY2+-2ZUw>a}id9#L#BvLC)WfumDTi>9c~=m7bN})U<5VD!D~m zDYg9;xg*_pjF`P`&PmDrpco3pj`4m(`J$paY7Mu!~CsId(F8&DY!w= zQpe6C%5T#bD6yWA6n58NZ}$5wmoCck<2U9Zj{Ve!j7_-WWOmkwR5726gHFFOkJ|3R z?QYZ8E>^2D1!a6E;HefXqd6n*R>9eF=Z(E{Dyi75XL%MW%pU^4&dkMDUFrCb2QC%` z)2uAcZeES^Ct{zF+qy5f;$jNemjS09$3}oBOi>5H@60!T3>0_$sp}zhiknWBW_*=LlZO@H%&jmGWu!hH5O0!Q%zRZRy)36Bl&eM#M;gYSnuW>C{rnR~eo zJx{(QDPECiH_P~ZqQY8Yd|CEU!{6t;A4ES{Mk)szDxLu4Y<8pWX(d^DB2Mxqe|_hp zK<)Z?)%7icoyhti6tPUj0eKnE?EAVyR$bFX{OlsK{uB+QR}QzbFuC&KXJ5y6?N2@C zhUFOCI4f~>eH63rkn{4YVf`N`$EuwgK+hVgj^wIeu17G>6a+NVpjR^@2c_HR?iL~B z@q#WpY_m&Rl74BW8VX;oI29t?>Bsbn6XZ-9Ibk`OvgR(p+#QYV4SAZVGgnN{-s0|R zMI$2$?yvBi#Y@fgd4kMjl13JLtLi;8OFczuBM z9jJBi!bj$6WSrItF24M@e6RUPuQ}OG{{F~*v9jAtmEik6YF*}<5#gA4%hye!(D*!! zrD3&3VbizW$yA=*cPxfkM@M`HakM2E6X5ZIp7^>M2wh?)A;R7cD|10+IlbdF+_~{Fv3SyiLNvpbcS&K$GSS_Qz>P1s==g2nCUcRSR_s;qh22}xAGa3Hg zbSInLtH*vEbx&li@|wu<+HS{kZfcl`;|6G~r0rHRBfQB%A#cN63!1_m!?lL;eCLojzCc zjZLe+rke#{7S0zL$aZ(7LIHMmc!yiw$<}?}{G2z$_pTpth!ZPA*WQt{0#Xh8a)0>-Hi-4NUp8*k!MlCo;gGV z+o}FxK2aUTRB>FFM&Xknx3#s|eI9K6TB+9)C+Yk69!ztSYG|?3lIYZ{cdT|#B_c1R zK<5Dd{x#KUTlr`RW9gKn>3N7<<;u0;HTwmnMVF!8J74HP3QsfbtI+os#gt=7Preq^ zEDL^($i4Xj6BFye&Q4W^(Z3$rlRw;ThsnwMABFQz86DDj43;Cvc5jq;1f91z{=(?S zl9mf5AFE8W6Ry%-)u%7n86| z8m2c%YtAhpb#`+4MkS;#t0jEpIQx$%#gdyaNKP}A;$xP1SfcOd^|Ngt1d(bk=RZ{I z0L`?S2s@6Df%H%P+%WZ>HL6Gs!!>T1BQtR&Uo&;9z(!@~N_S364&3>zFz}|4C8jOz zCqdD+H^A_fX7riLF0u7sXL?(Zo`cAmuIUV@M(YT#mcyG~*sb{^w~_X0=O8eT>`%L` zEOxCI^L5p^MgFig(_GBt_2V#Hr8|S2ZgC>QV2YHE<8*k!iS?gsCK=)tw&4zcR44hZ z+|jf=?$MWa$@k6+ip{rwCx?XGcy2B?_U*~=x95V4sW)~JjXU8=?fBEvKS{O4Vx~_Q3 z4Qq{vAzOsn3#WG5oJXO3ip3~$T(CS!q%v%-*ndysfHq{2{5Ex#Za!ql7wJKQ8_uHRVWM}gif-9C*Gfy7z=t}w@; zLKeyAN?DQ35$jI={MF?hZCa{+*qyjwFHJ=6l=}ytXjS;e#678f)=+Y)CG3-1wqzIW zIc_b~hw}0%mWM;3Cnbgcg1Z8}1IhEJmGjH3w5c>rJ*?K#XO+|w809EW%sxQL7C+Wuz6HStV+bv#2sd0(X2 z=E=+Ol)+_ju4M=M9Mw8G#Tq>20^M4S*~=6byu76P)Prz2y1BR7A*&$%S>H-H#G$%B zS~u%5>b=!gh}7e}tThCw5!AN|qoI4p8q&SYEA4#tNJLlFNKFGB<4I>iC)Dwy>?xIM zw&dej-ZaOF>X%gFwwUZ?OC zE&0ePZjj~Vnez@^8TldBk*9i9KCyMxKc9LM2N0fe)v|1Ze%mI8whwMbis+?q^tuf_ ztyETOT-DBa4CEA-_&^%Vx!MD^I-R=Be$c<5@a|py%MH7|u^7f#^NQ6+X@yML%&o{f z;y8f6X`n!Bv{R%}8@DQ$Q_1tHc0Rb5Gsy~n7N6CWMB8fEg@M=pclYo(I*Y9L^iU~S zo|bi;6v&;z<3m%*5?5d^36|arZte<PVDO0v@bB*dZrW`)FO9s{ zPgBgSUmN_XpwB5h8o3-n4CCX6PWD-v{Or&E&OBU0h%6MEM8{||2D}T@&qi>fV~mM) z6=A+rS$7>aWgxt;SUKgXU%*GTRvNyNvs_FDUx~eWt*Zy&Y`d zyJ3<%eJ7m}b(g^7XL*%26K^Iv@f8v=7`F5xD!Qyg%RADrLzB9M%`Q3miu2yl2%Nls z==4!i6kq*!*rz_Wa^uhY00qhBzbH`e2$C1_p>4#z|Nf3;=Urhg^^Pa&8zKV~Lv-H+ zOBDT_hcV=^Kt|r|aVLBmsrWH`Bcf&&nrsZV?iqMg-$^HB{7r!nC7gJ)` z80Z2(A44TN)aJB-%-iBwoI1yS+tmO2mf>Y6+3VglfS;BzM^-QL$>KC0rP|_x)8Wlc zuiC6%9>Z^_*55;kK}}k&@m*u_CHEb!4HE?FMBNfyxjzx%hyx;yA1hOM3DU7025Hgt z-j_2gQM*@p*YD(Z)wg?R3Mi+6Gze(MG$h&}%oJPn9Pw@HZIPT^w%RDE`bY;`Nf zS(yDpQ#X|dn=<7|*w^t^$xc7VQr0|mLa`wuWs4JC>nuUbyOjv=sZtGyyUzEA@C&|b zPQ&gBJBicbr;CVqSAMH(Izx9r8|tCK3{Jr>GK#2+VQeq%eYn5~r|QyZ_@Ls=bCL#) zQ(c}~XTNsna}ZBpUUWOX9Ty@bt*MyyIIV14@G~TI4eic56eu#!(9Ybe`_&@MoHF6f zaOAu+bXEDD_oG0`rmP^oMrRR|jHr0Q^pL*7Z-Y)JQ%uX3VMEdLO*RLw=iuOC8bIJp zv?K(2JTzgVfL;gNKQb+-IZw(_knc3vtXhmA0ht=>2c;Df+9PR9_VN*BHiHZACU`$D zWt6Hy459+;;9X;Gd4VEVhF3R%J{Za3jc*H7D|+Fjr}H07Ll%Rn(x_FgruIN@3BTzS z>D*vY_;e}N(o2D*7!W%yW@O=-%zz`~4ejflrgTkB;8|Y=4-X!xVa!x+;{z0pkh-*) z8?b|6n4&Igj#+h9;l|0Xp6dz4L)Ad~t%%xldjOrxQRGcmmydP|U{hF zC;g}N7w@!SBT!Fdwkmu~{g5<=K6HRehOPD(TfQo_JAPwK`3BthD%EE$4)~n@bzM*N zr|qyL|0Tz3nRHRdOB=&LuXR+_!ClXRR%+_Wg_3H3(%F^MNSaMbGSHMd-AXNh8%!`$ zup)1!m0A55sf*3+rOl+p(oS#;A4W|?VEZJswv~#v%BOyBj(V3r3t8p=vUT#4q;^V| zRdK{n*4gH~hbU-6X_nq5#L#jO6(9t!JJ)LZ5>ylqe( zPb^!hIJ;Nr8EIe~Wv)e|vg01=P6NfPYoPRiOpHbm?&U_@rasZ{>%R`hmE53c+==7x13h4#q5%i0m#r|v2V{@mkUcj%R@T3N z22-F@H5Nbi8@Q%-sxQOw9Imz*^29r`W78T%T{)x-;&0dRuBc+wF2v?}nJz6RgUAY1 zYZD~AccW=1*+6DO7JsV&5~TpdQ<_N-^GHZQXmzcOq<>S)HXUB_OZzj)%bx}vzdd;s znZFUgxZZ#dZ>biAYj?dZ?%NMy`e-u8v~Uo)X75=N$Lnnca(Sz;wrBR?7ws%cd%P$n zDW)>9-)&Vlg`pqxA%cV?I+AF;1{NDx?=TInOUcNR%mjVH2Uv zY+Xz;vkf~#J!>%fV!dXwCEZ;+8-`m}^i7hwAh0{7p3kOR0WO=HiK4Zhy;^d|qQ9?~ z8os@<{KwpsiP@$lb5l$xoLzaGVo&pH>-1k}pCN`PMWf7blD)SO)dq=|HV*!W;pIuN zA1gzu*M}mNq4=oX8ys5kw^F96y<8wja}HTvf1i!n5HA5*SUYi8795FUUMuftsyV-t z6$Co0UIFkvsIOKlABd1+HDwZp#@-*{oJ`?4#mdkHo$`IA(NNoT88bJLjG3@~<8lKq zw~O+#Z1&&3ujddaSS7e_R;MF#BBwY~p`Kqx#d~mmw_3UF$bPU8Hj}k!d8H||uZ#Et zk9{7?CfpIIqL;ZnQ9|G|1v2b0*rf`w>&qqcKrwCzDpP@d@q3k53alguZ)xS|ua+!6 zD_u^6CEv3YC`M4S{<&Ls{bkfC>2ekTCEu6+o1%>OVn2ZC4M1^x#reSv07|MItgI0yTw6{gCuN3nBS80>LzzEUs~|UhqywJ_xN;hm z%YbbAQmYjLd8-Mp>$py3R`5yzW2K zm9N3Szsat|$Zf`O$Vm9saeOyGt0JeA1xd?To@~mve~R_=i9lyjYh^`db{uB?Fj?xy zu_7FF2k*Upvb7z&;$Ig#xz0J~bLC!&*#%rX$nIjwBgHi$62^6k<21vcok@h~9GDQl zI@6sxmNp)C2w#6&C|ZR#)rd?HJB-a9*We9MP$zcpYZnLQ|FAuvn|Yj;<=gJaI%htK z%i05OAbv4KG4OidvGxM+R;ci!%Z7dPoI=Oo-jT=RST-pEVHN1HnZn!70wto!DS%DA z*ei*oadmGSG?y#WJE!rIx8gZ#B8v05Aeq=pjR*wuY&nfR*B@1g&hJ+lGIK;aB zLi80eKAuy%8D{)h2N@qtd>QLpeN9ckv%fuQL*tP8(=j?gr_#Y^$mJ&o6I`d7?Ndi_+E@2`zC&?!LzpORBqYw zY9oiK9n-kM^6rx%KxrT;gzKUr?7Lfkx(G`4lhx#!lp*=1{ye#EmnUrxwP?z>j5DwM$(IGA;cs z*aJV&X9pg8w@pO@HyynkP0r`n#_?%lY~Zg5*oB%W6ZC#Bo0}HXmjwd!6HznU)DPZd z-5r_YPXw4XNLx?x+SI@%c}JS7p~tD{ZoE%J%F8i9N3JMmw-SUjM{-DqQX7=;GAp6Z zsFd+;PGs6_ zU5x^RFh2aK6c%0D(sRy~HO(XblbXZn0Pfx*rEW~#|QT8c^#X1`-T3pG9r=fHz1)~}H0+2~M3d0a%; z5JzVLr`x|~_jA(~=OZ3cgcC?u`FRt@~%Y-fL~s|q!Zu%J7g z@@o?e4?KMEIXeSa1?>vKcKz~mDkhPgLLC+iv{s{gH?6nqh+nVBWborxMMs&K)Du!R zgH_73nw2+)d~Amqh?~ogkf_HeF05&zE>?zy1rVJij%5wUO^S+;>ZrJ6@;P-0v#->i zWe}BAkWjcwS}FOCfxe%-kNA(|PU1*nzvH)TQ*n}Uc%6~k23%!xNWq~$!jZfDSI8pS zXuIC6n(AZ&^3125_-Doh<2z;(X&q2CiQq<^i|=T>hl{jmm(RDVSUz#C8-x)b3%JX3*L~otK>38^f33BZR-}b?0-B$Tv<6Zo1!Z z6ntd9-FM@}V25MRos?3>2L`07w8i@JG!ZU&HF9p7yeTWMT0!fk zT_~R1t+to3Mq9Du`=5>@g-#mC{R#EOC395`YYuEh{gjEbi3ls9LU4Hg!lDgT3v`b7 zd146qNGs$^@#U+vqH#$VV}1LVqFQc~!y1f%ZNnqH3Pxr272a^NjVo&*GsMJ#N@j~Y z%^2H{V!2YsvFmmy|43)4iM_k)4r5SWasMHX(d^l0JeT$#UiOxs8T2~)BD3$At^S@e zI^1`=zSWv#-fKnYvb8+=fhO+FT||aaQ`6fD-BbNBZ?usZ>Ygc6y-2+t`{c9NJjPZu zo?XjhZ>~?czYUg8@RG`>EnWGFtW( zl5hPgo|*~jr)1HWQ}L)0U~+CZC*_N-WSa~Jn)@bi0eeMR!&#U>xd&~hWmL%RHc(Xt zbNSaA!&|n4mdz%HuO}YzMWbT1Fk(&!d#KkIt+V{F=y!~WcF=VJ@w&{f!R}G>chh+m zvrBe*!`&GKsgrVn;RXjhzESdFvse-9l||VIYRmd-7jF^8J?lHWmzTQ*HBnT^KRNzJ z0ybrueq>Gn_I4qwZfV!S1((`~g>SD)b0bppu8^?n#*@qxgf6*SxA1(^_d%b3JoYvb zv*zMd3z@;(QL8_w7%S1_zUt8q%e;xDIj4)Ueq1mglWKwm&faJnGQaP(BWf{-@y9Q;C@y&YS4i)HiCGq|CSvCTS#y-ryzKiQMJ$$SLjG( zP1%{$n#huy9_PsZ@vRbfv_X^L+rw)s+(pWD7fI~wl&oEvojzk75blYr57;l2646hK z{qw!kEjm@*Ss^;osMsIZWC^KGW|&Jv<@TvW9_WTk%+PV41UsUoj|LPk&?97l?%Db9 z6Ovu?_)~|l45oolY}|~x*HdP|lbKh8Op!%C80RoE%!Azgz0G50Ul+syD@0_cadn z`K#g8fVhLSy0ADWJD79$9NK_{RIK`+~)a4HEoX z2l#;quDXNInseKU=9D5SYTMXjIuL_r!<$NzO!9b|>yC7d1y!s3KacQ_%%)CLQr46p z12*rq7(m#c%4Jw6zKRgOB5>W)v6d^7Bt3LOJgI_^FkEv;K2JFNv7!ty2!?FQ1f%09 zmh-CBFpuk_-=zNCDfr?uU#ZfM*0WnTYcJ9`U}3F$95TqFcjT`Dul);L`l#1N9kh11# z=QC}Gu-!YxX3sr9T&?c99Z<(ZFKX9oML&eb^6sjK7D6nKxqSHEG<}k}Cm}a8f{dtc zl(A3K!15|j;k+&HW)~2Mnr++MTFv+CpZT>7-TR%zko~sg8aw-EInw^TnFR{Ow~4n@ zaB^?3*i>Z)vs%b9Q(lNy&X=YBKUeHKq2*KY;ZuB+kU9#PBH9?IhKW_Y;qnhqGmv22 zQH0GYe;(7QO%?n);-}Y(*U22-58HeE259iAZD^fhnuHlZT=jSjk)#^_3|U0wjJ4tf z!4A!SJl!^n9`Zm*>xy_p`r&3j_J;VS(`aGJzcIHEpl zStRdTa?%o4`izzl*OMft>~XL|zOP8()Qud`qH8kukgh^xE8pQwo;_>HbmMO(<&2HT z0*%5u#1>sGy8zUX{6;2StzHx#UCA$GVqUhIab7sIDRT{+Z?2{C_;X1zS|z_dhHM z(%_KN(hbrbQUlTg!!UHmFd)bvjY><2lz_A}Lor;z0+sD?VTazd|bWi=_dcQtED`vEEcY92Tj_=JviO=EB+zE%Y4$>9a$az*En15f< zH`kjqlE>!tGi=M7r$RAW#0|0BdCmpq6Z;jvCl)}Aor5~#`qE6F<; z#+WF2HT#RFxu-I3pk6`35(`X~GtW6+t1LTr?-SQ-h_$+Wc&e`tQTT|jEE%zTH?T9186bui3f1W9tN*PUm2 zHQ8z%WQI?TJ2Lj@j?kf=l^CzxpN~qTRKAw~U8B$1Hgp%X&D~XFU_e0Ue)}m}T+vcS z;z<8(*#Y922K=(xccB!CAC;6C{CB3<VfQhe}N^+8XT3h}5z#uQ-0b^9#1}bEtiD zyHD`f-RJbZr;Od$2z-t1O`I?M+tZAW6kINA8tZjAPsFbqo?I#IJP$NW%Bty;kZ^JE z+0=nT=P3F;kj{FR3c~K7ml?FG40lfb!zq@Xeg}AoM6a&W4;?bdUz%O?X)o@Muh}5l zNjlHlU_8J@Vte$$eB{97=%+lQVJS%*5@Zy*3?36Vpp6zCUR_xn?^^MwY9y2JJ(c0` z06=Ps_$)=fyf3q=$98neuhf4E4M@#|3W@#c4OhdUowGErCMZE~g(x~i>_Y_Ccr?!JzNM5n-NUCTzOwXVKn9cST~S6H z-~CQm0+Kr5cI;v6WH-IG<>us+tnA@#W9#AcM}9An^vaCegJjF$$^D0iUHy|n*|T`7 z#VxtxKEr(A?;hEO-m~Qvo3sOTBS_Q9Ol4H z3CC+(2)U|(WWofnPR)R$db1r6Xm2KYKk)~tKFh# z?mf|OoJMTa6Z0${MGgm4!-+lKzs%uV>`)Ye< zl~*0(P~kbNYT{Py4F=T~7~LK8gyz@XCPKw`f4oa6OL0j%a`jauC4mM@h#}`(18y(w z)xKLq!tV*9n~vb#!m965!oHjS+KB|+2--M!&LK#xGOSk!n&x?@F*9<@dLe$JcxW?L$9N9m}KxWtZMbEhvl{HoD}1qG^t~$oI2&}cI`*!m1x&R3Y;2f*sps+#=k^M)z|A%}J?M?3 z1rLgKH^(^|xyneJB2y@~`~}@r=TdfiHtl`tR%f4lATte-(7bOsFlhN;cuhu+67rhz zxz|a*gDzps{0-Q;>18^+&^d`KyQK_YKBm7E^V)8b)$_kVl|hPb9{)FxCD7*|m1;-e zT`Lg3qts^f(nyBKj1TFAX31vyKQ5El=-J$1&NybSVu5Dgh<6F83i{b(VqC68SV&Fi z&dIg>M|_W$rr}O~puNUCY#C6&Xsr!!E7`lGbC|>OB3C9~zECI|C_(AHtKGtw26BwC z2M74T6sJlSOqX8CR$ODv^bRV`h`B(W1_d{fsOp=ZR3D1YkO+MD^$Nss`KsiX50SNR z`n7PEr_7<1li`*nHu<&4F!P%kDia#-GFfoCIl>QpTj_|3S=o@w;AxZ&1H50e?*neE z^zauQ*+P6kOo0eGO3{G?pT0+|Y}BGelk`WL zn)KmgsPVa~;Gj~Oxv74UzZ}+a2|4?K-s1qo({P05d`I{vmY-XI*pC%As?)TINaDQO z@{br60aYMc=h-i4={kF@UdP1&7FSo10jGLi-Lg%({u^2We$0nu_bX9-Lz45W=O>o| zuF_tHP{iR$u3F#F!_hKZ&)oen{krVK?SsKiH7K6(f564!Z^-oY>Q>sVC*B78a$p09 zb(Y~j>EAv!w{!)awlZM@$`7-$=qON*RX1qPBG-6z`*|C6?7-kNCT~M(@SB1?#eFOi zhzr0c<8Mu_UBJ-(IpL?8G;S849FVI(i^r(QA}&{}Z^T`H|Jc?IEL#r48?%@huc~pl z8iB9gTGDr2m0VG!YJrT!@xDWA$;`a1Vt_H%(-1tcR8920uxusC1~(*xJxwLLruh|V zwr<~^q21TT0+U!_k{QPug`f+xJs)?MsEFL0_ke}#c)sq3@YrX)$_b#w@Y{*6YAOVO zC7NMhkc88T%_E%DlcC?i&0l&YIw0BNb_bJC)zpTB4d3XO7^Dw#5;11@_s-R-m)dWU z8C33gl@cx?>};C-?Y^JZ7`kPJ>j8|f$q{x{TO-#SRS5T*gt2|jbE>?T>c9vVO*W@@ zmRQpeW+^7~P|0nQjr6&ymyrm30PZ(3V;8J*Q7G*aSQ5{p(l%?O*ln#fs;_v-|L!4y zsCn+`Mo7SYfxcg7l;7|Iecf&2#6W4{*6n#rZ}I&#QMf5nLf`lAD$Md?h0Jd<6nCH) zdw;sLhXh=zdmQQ91-`4={MRu9a}{8?Z~r_x`MhxbW=qC09ETlguW7Q;O-!$?CwvZ$ z2A}Xy#ZD`HS`4));A?apvEuzLlNWmY<wrWTlm_CJw{ieMCf$!*KeAR9e7uGj?mH@-t!68g zt?|W?h-Zig6m)29_^p{e!F^} z%BCJYxikt!?o-t#B*)C-vWj#noo7%L0D-SkC_16!7fO~;^fBl$SvHs3k9EWhLVdh> zTfzka1T|Zu*nZjGt<1=iQH7p(8VC}}A?a#G$tEo2J{nb&dXC5mSJEt?Ma-p z_E1_&-njsB4stkaYBO9!rZ2=Km~bW~87$pFWtr*UC1LfjNgt6U zUSMHibqn!0dtcf14SiU;r1LtGmeKC=2wz2OPeS8}RSA0a!48&ovOOKVd7^2G@Ia>BKRZjQ-~beERnqu zB$=Izdh4acZv+NoMb(5mKVg|53d(in?PuqIIPvUG?4GqG_}PIy>as;?qz`ZhYI(i) zGtZ@GVoI@UflQ;31YHY|=UP0BVII0oCTm9-wH`RT;aW};z(_f(856QYVHp#;Emedj z!Nmr%QFKzcvl&seNia9j6X~r{*hA!Vv-W5>6amAAH^(60q|E1~Dx%q069OQfRN!O6 zV#5Pd%N0cn5B^2`eb8kpmbjE9t9^#%=g{S=R0gcJ={6tcoE~` zKh~1}Q}ibJv@XD<9n=bUb@yq-+p(rZ>-$;#<3AFa7A;qm9d6;vy&*49((XF2bdnu- zw%aplbKNY4;?bA`0sJpnK8m zyIqlk5VsmBjflT2zm3rN`ZTmBb4j(b8_S zw?h7+s5RHqRjAZt^!(OpWC|Js*U~~Z0 z+whGI32i=kdR}_H049sR<-Ci1TV|c`&d=-iKCBTtYHmuzi;Ica!yOmcH0EY+jj?TX zq@RLyBi8m^G}pU2Q3EgPsy5j-lXH6qrKSezl104sT<^46E)M?kn%%gXH8zMd`^-T7 zQFVW9lUz7adHOQz4Ol#T{u?zdS#`y}H+=zeGTY8X#)~FCdy;?5no(tJ4TQVBx%e1G(|F_1U3o|NGm)~>l zG4OHfTCs60lwZiCm_Ds=*VXB2R)EzY=q6k2T5*EEe%~}q8c~WILV;eJF(va5P))H9 z_9Zgb0@-4!rnl0Yc7Qigu*d;pO7=vflVrXcSD!i{l&(*l5vY@B3YAuZQbCD~hLk)B zKYPZOfNB#2D;kyi0PVKLKSmzg0k%+qOpO-K3rS|VF9P+`PibaG?}f~0C%zYwBuu$& zHx|8Wo)!z)&pKrwey54odpttJYCKWI(TuN#wA~QQL|CMz#s!gS!|y^CwHv>{V}hlJ z1!cp8Q&+I5FT;dNig!%nn+sD6x2@^+&2yygpH)VOgl^jCB)UTl`!bsBVIdB99#R1{ zxQS{9T$|H&8z43th1K=nZl-aqG99?#g*x&bLF5?+U7xw~9;ujKe{7S~{@HVvB zBAG}2(-NKQCWhJ88*8yD)tpV0Y&vw;9bXZ?Pa5^-KTY}c6Ig=)Tkh+^guKEatm9g# zlqGNWg4VZ<_P7qY-YHu2+LKRs#)htOb|~6;_3UzgO?oV-H5tm1%5_^Cx_yVK(2tRb zMQ2uHZri{u$9G)K??g>0kB_B*> z_8UUE%Urz1jJO|U_82mdjSmU3cTqSGT=ypz>ru)K0r2`cViStW zZl?GhnoeRb&ch?=T>jP})?qHTC0t#1k^L(-!v%nnhkiFHOdWY=eqcLC2s2pqeOdcH zd`$Uz+4*;Lybu9IH-ZV+G3e3=*Tm~QBp{S;lT=;@PFk1-nV6tQUr$-sc& zmyP)oR~&ycW2N|k!NGIN&0aEmQY>-(z3_N@>=KE{V`qQA%r1bH$Q6UP^~Y{Cn#cD2 zZ%!tw>@Rj;VdKfz=SI$kQCt1tzr7Q7v#FbqfoFal=xV$!`ZNb8&`be4+=^h3wP^07i?&xY`xnpYxPt|>jM@W8Wd<0g@|x6TNZR` z-sOc)p)4nJQKlPF0e4;D9Yg*Lg3<7%RizfT`$2WNyB`>&f0R(_TKGh_(>L^H0dvwV zum82I=pMpqDmbHjMvrHzC@ayQGbiHCV)*~fbkDh!MJLCHUs} z7E^n`HA~p&MG3B2Nz|kC=_#ry>BSV&Agv#pc7>Ds{Pxc*E3N{On*a)uIfY{!`HF?v zc8_N~RT&NI<7u60MEB~cyo-TNk{=cqZ@C^>UTjRX>hpo;6SVKpz4{a11@C5Le%(Ws za5BIQG2Oj6M$S6Rvzmqq5>%KyqE_Q`l-hh|+qY-EtDlg)4Ye%J@8nppqDgJ%rzV&mz$C@S?_3XS6q~LU zD?fB~(7h3XQ5*FQ!xQdNza=U;(To_OId&9%AEws=Igedm*T=EYqs>qZP=CK;XelSg zQJ2QEA^BD}iH?g~Mv(1VSub9IMDrCK<5keZ(RVc4jx(91R(V~IK1wiarBibU&i*C* za%7!DB7jnQP}K5<+dW;N)o*3X4J(V{CSRC$XUG9Pp25OJk!z+p8w!S) zQuv*jV|dRib8{UYAQC&}FsKpozndA^*?GltszmaNr1!JqSRrg9_DfPGo*7eCq-x}e%%hy-Aal-TeM~~q*BipTD0bx zSL3s26w6=@gvZDXo|c4*>gvP;Z;i;38OAY`X|0yR99P?^CUXnVloW`tV>c+CB9xHx znB!MFEK5|xkkTY*oYYU({j(^=EC=WU@3>vm0|jMg4NO=?F)jwW?tZEqPE}pOSynOQ z*cLGV1JLgj9vKxM*7aQo44#b4_okN1=ivoHzHCpabiq+7`DCjeg4qL&j&HETTVs@e zy&&DF)0#A3bmqdV{f$D#{U9EHvQ?91F8ZWm&4)yoH9zSgoJYs67)@EB z6!4*aNqG$1{pmn+T&-C%zPI*|LZ9BpCyF^*1&3?Q0uAJ_^UmVZ7^WChKm4nuqLcw&MZbBVXrH?a`+TJ*v2V820 zXtnHt?zuaE{y0nX2O$)|+=4oxe(#)#@ltakR9;ODt4Y<+T9-+(90W=^-qkfzPZfn} zhCg?zX<>|8`#C)A=1xg?`qNBZcA>nU9skQREOU_+(f*e5&-X;Kf-<@UJ; zV>aib6S!A_LDbvRR7mR96ZRi9OYD`o_x;O*P=`Kb)aSgz{Mx# zt#rrIsN+3uFMvp5p&*Fpk9j@=Y_{tfd#3X`J-4MKt$@h=p|aV^q3k&ok3yd<3}(ZS z+~Yq4R6GKQy)N_O$xyo236lMzs$Ow;7e80>e>FN&i;N(3X%bGQB{39FQ`WCMWBLfn zv!OORZSpPQTwt8$wHA~}soEsy#cZ0-tBKih+EFj>(i~9CyT3s8{2yR6Mv!0O-)}pG$V^W^#X95M|rM zeAq$deqYXz$Gddhvumd_^?@6~`Brb7(iE#ijna#m|4D8fYysKcdK7-s5`v;|LpX3> z{1`)u=+C^!V*(}VZ&pZ55A@fOvQ4y$%o{0yqXZ`PjiQaQDIJKzgQzh|4v6ODDHLJ` z`@iF}#>^O5r??#pITbzp)Ls2wb++id_X@@sOl)%>6H*hXcCgH{OA+ImVg71_Z(7{N zSM44H%sOck1+w*qI4LME*5*merE#CHh-^!6-A%YJ@&`VV;X_S`yqd%1m=aNn=9vzB z7rVnj!x^*8od$Ipn>=ky5LdHGQTc&oJkA7&r!e%2kx_G*DtogH=6%GBf?7J(XAX`l z=Bw^V-wmBeo0u^t`h;81ui;$fX*N`dnL^Qs7MT;InvaFKRr_}Ndf!*F@5Qug;?z1Z zvi4>zOwrt{+LXZ$p6r)Dd|+P;uqc+hJI9Z`dk=gn!F>2Qac=LG3aqAf#K7u*rs$C@ zQA{<8Er}e!Iq^oRld--!NYcvq&E!)|7|VRX@r~EBE|%>t2yBG=kA{ofK^CTT7S4jx zcfb>y0S(Tc4tw~)9cgW9HcH4UU()2fYDi3iNVXfE@H^RVlUj*^4bqT*@AI{9$c+7E!rt2r_`HDRt#M694-4yRh_sjSXvvz{4M`b1=Rq4!;T9P2O^;gVI6#ofxQSD<9R z?cAE24Oy@yWaUKT*_cdvta7JLM!t^0+n!e1`hoA^jQR zJ3NLB_aJI>!6rC6-KRMpM>%q}IkV-z=lV%O2anYhB`mfweKj*eRb&(ZIba!PGkdGas$VTR70B+0_zKvg7 zRYDXyzkgroA`6C`?%(*uJyt1#khbiMgvO6{rRGc#Mr=tGk;T60E%pBmi_FBY%g1}( zgbJmV9_Ef!XL~AMswwSnWHF9mS;guS+G;UNSC4AOfX09*;HcpweTr%Oo-8X-RGfQ! zg@*y7?6(uaSIOiA-(nrEc3$4d#D+0#_1&)tb=yZfdl+|amo&C{&zsX`=&t~+M=I@` zScdxQ<^ARcp3_%azKHAb7L?Kc0=dNC&-E35YCm!Fk8>A!<5;}^D~?68weZ{ zV=-%br4#eGfXy(B=2i@c&*-5u44a8&Wf?kwUo zIjhdFvy4N6OfABSy3^s6Wmt$?<-Nr}7pf?}IZ6K4irq^*+_B*-$cdN(r|5f{+`*5G z=lgec7wc$0yPVecyN19%pI@0xUN^M_)cE%8wLq`h$j4(EKaPZDD^VAR!`npp80SOU zU=p6)pQKQ{85NBIzhO&SkK>?aRDI!_bs<%2PLf>J$MZtFiB0vtS1o8RtxjF)vkoqd zO8D%xu}vAJvLA%*_a?uY9o+C|R36a0q`YIb&fM)|9(D%dCn&1~w&5v6Uo`?`_? z|4bx~R+oimYq#UtwNmC6PP^=)BpDh=TISG#q`HgmB!MTqyVR^;7B*dK;zvdq!SR~t zAXs4~n5EyK(Goc9u6$#3_&ZZ0grZ+dDI#LEfi=_5{LGbzNW#qg)u4Gl5~Q`?=t=Fz zZ$m97i{qIsdtIxb52D{im7_A@^y{LID0EsK7-O-LULricYx~0E2NS_NZ>euGXCKfd zJ08=gTuh09qIwoE-ZMCCn=zH1xn)*_u8*C7?|64v<{z4&vi-3W{mX~8oU+d4$6R&Q zx9j10Y7{u>|GiT*@D9Nn;gUNr<`k?6UKe)mi_mQ1QZ*kzOvnKVcPvX_}acx*7;b>y6Cq_6^ z{0wtW;gYZ!?)=+`>G#s49k^d!@&^^78i=3EA^3h+5t~M^MfUJEemMbr)-XGr8Ff_7 z3h;2veSi0Dbg&}$>Kk}@3RvPSNRne3#)M5zzE!uo-l$22>?uqEp4<&RfR2P+BTxrOA-5Ay-@ng~k zvbmZ=7xMi>>0)owRIX3&*wP`#V{8F0abr*M)1(hnR)5Anl{A$q=JP6?XTD?$()`br zt>T0oZ<$HjIcErQ6KY8~e@Us5l(4Ea+ESm-t1j~m;n1;sdfsJk3~o{;7`FFDhSu7L z`T)`!KyC*!ySW3>G81@1n{kg$=6|!lUvRA{Oc!VwWpbuE)UdZ<+%PCfHSVT$%RVT{ z_2X@5CvmhueYonvc0Q4sPkoaMJSDFeZZg7R<4bK-hSa(C{@gt2@|aLnw9KqvM0@{u z$4)KrPSU;RH50RYBC{sLcd@Myt$UOP2+*mMDLs3Ye4a3>9C5g zKslQ|F$3ISGU|1WrtD7t-t~4mS`X_#WYU|m91JIvr8|k|iT6SLi@ZAo3ps}RAAKLpAX?p#h zsD0{9SbjMp&>?Mi*A>Z1xc8OD>rX)?Zmqo$;ppjV!tR=hMz1Yy$xT(m+3HA0!#=Yq z8mD#g(kg@m(&rO2p&QXj&fAM;#14n|7mico4-}%nI{cC^0SP%~kb9d7Tw<(uR0QmXxN`;EzZ!7#!JHx+CWrF`<=t7sZ2ZF4jn?#R zX6+!REa!SF2LN-f;<2g698bHGnHO(#%e?SLtaj$v_9YNypBm;tj}M?IdoJxkUJsVL z(p$$FlgmG)O?;o-sAioq#XyDJOtm5luqLN++xqiBQ_Hc;*{=s8!kZ$>`><8Fq2e#y z9Jd2bo`+t)GSYK@9h};WeL`zSZsKk!c7Ij6tIPXf7U})gdqkd5DOqO&o<3KA3`fE1WMp7{;|S^|XjW=3ZHKLU@nITtV&*1W6A z4G-7*Adf=d&sI(GQDvbLXNm>JO&wnOz=R{P7Ulm?W@hZ+r;KUNFCh;0I*x(X z>RLoy84wD!K->c0&ex<-vh2QMyW#wo`&GGQ+WERF{OkO*+zaFEnv@cO_73h6k)u0_ z1{ur_GH7l(w0ls7>(1f&h-$B@s$_nTpdRs$e-O?-mbTiumy?yH{C&cMk(iWe z9J&z?a*jMRM6r%N+a96t)Xj`sWXHzl`|9T`KT=cR&sJKQc?oQ)4Q zp0*!DN45PTbTuw=S-PY7IeTNK`w3|hU@VE}!_`S=S!`*+XJSrX0G%#y=kMGfSQ4b# zD+UJ)WK*cHJ4Mg(tiEUM9PiWT6c3rrCUKSyD#7^MR|`grrZkA2|G+3=QdbtN z{ScC_1PuORcg+m3PDz{lzY5ODCA6l%Q(Uf&Z^)#-)M(nrMLT<9GBq zi{OZTy?je7Rxsuhy|m8=3c|)!95nUIc4$yaQakmhuIx9RrvfBffW=6Xj|@$&YHHMnZ-WA>8vb_M|$|9*(?xh`p4^b;!$n3HXU8H_Phkdb=L z@HIJkp@xYb-ho}p)TP@cFUY9%mKf!8c53#{6>E2=EfGfox?3~dZ9{a|D?|y3jFIUR z$6wErOwR?b-mP239(6AMwBq_vdu`ajbSO2Ts@PGHbPP2lUVrV&eVaydJKE>(aCNmp zboWk`nVZ|!W`hm%+}tZ#_|v;5lp?3?sPEtQj81oaT~IT~dJJL;V$y0TH#F5H28wYxKy zo@*u&z2AMcTz>NC$l!sfF~_||x+>=yCeIkfgv)*7N2=w{8l*-a81Ltyhf2q<%&bHp z@5N^`68*~vOvQ_1hM{xh;LTMcKla>!8_C7y+uMO9@Lgatk^eAOU+3qEs>L^gF9nQv zAQ~}$0X!$$D%Ssg7>r;|Rz?(nF4mzg`iM>tBHtCyi@U`hKbhF*&CmXmc9+O4{e?0g zNu8QQRiA9IP3=*{lenIeBqCPcZ~<4WPlJ$Xg`W=`hO~YKZ3Kl} z;O>Is4|dRV{!E_K<0R58H!(*ucv5wfh)0Q{Gn7aPV_{uxT#5VRi^C=6yXP{qn;MD0 zVxnZbM|={L&u06YHUs`Xm|b+;tLeZyD(Y|`s2wjZy6p@;U{6z6$0^rTz5#LuJaav4 zCBI}`Lo3rr?&kVQ^JiE>X=mIWW|FYurlV(qDb*0g(-Mq(IqL?qLi5I3E_91lSmxIh z(@^~(oH_h)moh3nq(qbE{>`QPr9Dcoy~}YPYREnhYR{A3Kb0?ih8w}I$1j=VO&pGg zmzLw%s-Sf*l0k{}71gI#tZ{UiivWd2Zinuz1gDO^tG+lmoT=qAuZf>!Oje7fwi(<1tZ0Ih;R$D*CW2kmbRO*Ab>w?{4jgSTkk&ZS0^^l>g1z#n>m)> ze2gk7ql_^avJEXbQMr3()?o^o+w1uj`8dgX3A;O_qRjeqUpJle3wfv{Vk75%kz10W ze{r)M-b21xvfDAlna;n7o_Q&kv_-vmhQ;nU8Z(nqzR+H(WVbo?5lT#F=lcabdv9mRXkqUB z1VKG{NUhnv7&lIdGv{rUC5y0OoKNh52!eLLMCc{_>BQ(`H*!kBQK04RGgaQP2&L(6 zAj_XjH_c5Q%vtM5+Au~7>WR=YKx`_)IQ`b`$ds1E=PGxzExm^?8BCNqsUBZ(xB{?ZmoAoaIbfKZc34e@OiASj`Y(sZi{VzgFBSdX%r$f_V^gX7@UIS{%ld}nv#$o+cPpNGtXps3 zu?vzuYB;ARAGxGD6n7uDo(Qi4(21%c+29O4>S+V;fD}H^7-rLx$TRtEan#WpIy1Im zKhMcNCZ&>?IJL-h*K_Z<4ZQAHo`B2mD_(OiRnA8Der-a~&|Yy%`h0vVwjc}h!Hkc1 zH>Yjrx(>F=xiKA6m6NUP%pPf&y+L0GH-~K!Q5!M)_|tGHi&ssr?!;#KWZsRZ+jxmL z*j5(3GfF1h)c5WjKf(Q~L$jbl&dDd&GC|=)Ud68a;|9%}9GQ{c0v5#nGqNG=0T~gB z{d)CRN2Fv)^hZb&Tj3ZkaGQ>&pS!x^xolsiW)X1#Cz@q)td`!X2VXf|Vm2QBxYcZ& zv##|05KWinB;#1TWhl6iLk6HkFl_wf_i>R-Oan*tB0$&p%Rx?u!|t)hPGaEwjP--N zUKuGI<2ZLh`h8`2+qRgVE*%-YBBj#uYNF(%YQlNYS&%uceGtFq%OcK$WZ}K>pT8yC zo4OJMuK8oXM+xL?Vp9*Prp+5Ao(&{DI`zj}3Fn`IL;Yd{i?e%+6zIi!9&Jcnm9CeH zSh15UoRTj~6az5Nu8Ag$Y{EM*<$QSg1ky?)O@l(I9d?yGRXBr8KT0d*o$tD-`S;mL zPn^i}6?26+KRd6Es=-6~=ov7&T4V)IYCoc#^)Z8d-$Mi%QZx_XN0k1S?{1qw*KBxw zJ;c^?db$bcl9j`IMq^J41&XGKjqX5`U%W|BV%Z9mbdNpC$w%!ukn%3cD{v5BS^~`@ zVilEGl-1uGGSjNdGDU}&G@^wpnCcBBK8F9q8;aQ1_Yl32BPs%VWAxDP4!bR+qQ5i) zWSA8xV<*MfbFM&doQ;mIv1*zSQ-#K8Q}z?1 zBClF1oI1?OjdXrTyif=AxhUZPWE>Z{DRyG)>E2|fE2;L8L*Y3ltfK4*KrTYT z90~R6X;*p|P*K5W38c_U+=?S_LE2Hsd@3ag=dntSm{*c_v9E38ZQobyFxx}YYt+Ry z6>o;=oG&RE97uWxw+VYJkhIrM{xG#BI(IUxDKk2&xEXL;ttjEi`YuchYt(kFqIsA) z%$gmEuwhOW9E^TxA+ECnZP*20JQAAW-sc5msL)?V7djgbyXzpoK{K6*g)h#g(M&L?ECm-A3{AZxw zR)5&r+C5pO@}LoqyHYAbS8!#+a*t%XNmUF$<*B0?C zK*{wlrSum7yQU*ONpf`lx!{8HdR1871V_|9Kc)g^;@;#As5*mjK2Y%;sYRo-j`~xj zP;~cKR1t(IffH}?iLbnRp;8McF9t$AF~@hBl?5MVwc40-k(UU2GXnpEJDxHdib~ZB zBQ>Uv%BSAd>=35rj^y@cf|a}#ff1tdE$*4ueby>yxlGVCrK{ zilLfXHlgnmw!iWcsDC+*)t0Wi+T-C~M68YuYf+XCSzL)K&unGhgzBqLaI`rX%9^SU zF9Ls5Dz-h5aD1gR@QpF#J0~@(&AyZpp4}EH&Ettv*ggmL!jfXVeO`od#TiRhQHU-3 z-8$5B3=`hlw?Bd9t}Y@$47_E$eRp8V!(AWA$|^VXe46t9V;B>EGWQRBA#aG$Ejy{_ zdHL3Jgg>pN;f;?xV3g%eC}G5Gbhb5cHcjP+&$g*eCC)^Njs-m3iVwmQ&T2 z3^XL)&`x=@b@+6jnogzgz!7oA#KU9AYPo>L&zvVR)$U9!mN4gyS2rPhyVJp*P5es! zZN88Wv+Gzb@SRbVk1{pNPsf8F!nK>_I<-NUhU_e|S_|KVase-d9Wyo#**9O#eK(C@ zML$@QxMwt~E_)@b*zna<3g}Kc76AG3f(rW8)VR1j&1oH+ESmFuo^!fb%4nuv5l|Jj zgvAc=1ZeFQcknVGAwoTbeQGGN>M8x58sBGLuJC=iDTpoCoTHksCkkwDG$-3f576!y zLzVDWyzf6a-#)rvTriI^K~*SQt4`Y+m+V^+B;rM4E1$?ssMxvk?6y_(ym9|a-+Qz) z{GxO_k56u&T&+xu&UXrLQeEI8SbUMv!YiLNU!?ll$%0~lv-QpUW>QnB{xo!fjM1-{ zR*pNnfl*K4p>_JXWeD|pq?0W+Ek8o&LAvW%YcuDc;^NV9Bj_p)LZHdPPi`DNpE5a* z>yNkfR9P#**0SW^t=)OHLAny2GmK8s_vm!&$k^*2FX?`s+8}hX+%gv1Umw0Opm(bw z)V21W*85l@?{0YEeF~PNjbr+l_{Vv#q?tx$1g;jq&*WPQr6Bcw^D@(6BBa!E7&p^l z$6ZBUXjYTiAoQ)R;OfMA=Jj?%uY6jqf2{;=EC2_^C@n7c=(f*d3+=Iu%aJDk?yNXR zQPZ_jK<8p=W*H$NZV9l#naNlhaAfp-}iuQ%~S^A&Lc0nrL&#W*Fusa8?#)K^JmP9luNpQZF6CctyUC9cQeMKR)EIoYL!70j=TvNs%whJ@L~w*ad8LByM&X-mIPr1}*%)y8xj4i4GUg2>-cnGN z=Wt+WVzT(6;2Yha1p8L?1^w^YV|UPWbtE=1tPa1HaYEb?USBn~zYbKg#ENwf|DqDI zITJe0!@{+*Pco(T0!>>sj#TYZl_v$u186iG*PqWAvxAhpR{*5{YBExhAFKvr+Ngq z@Wu@DkcQS&*#I!o@Q-w_a}C=|q6%2?KtP{Lhz%d!oW0?&+H3u{BPRx!7Yw5jvz)!r zjGoEkG9SApQ(y%&SNN4mQw+)Wg;NsMd=zbgv#ni_CutKyD(Okz!ls+Ex z>>FdH8K>O5-p4)qq{t-Z^+=|%I4ZlP9$*+ z_5d9kRf$eGvLT_+j&kgeGN}?48WQO?qat|2tu-;l6Z6+jBfn4EntZL9r^?9*=Gdor zv_EoNK+8CP`jtojw!k>7DNGq-XkOllVnr}4Yr~G~TV70$@`2m|f{=$@$iAb#vGgzrv--b>DQCB(lb4`;VGqTA({gSbol=b%17`C>M^<3-FSCCIkZN;i`CUxw1Y)z3HOD0tqY<-hHSsYdorig}NlsD6%}Fdzcrz&amIM)=2MAf2_{aj+}z zy{%b3+yX2Ak}||J!{@oe4bN+JH^_}HvwV@+Grf6a4 za6$G2+C)XcbB9!=KHD(tb8RkfFfvT1`?fWEs$tICZ@~V022NIOZzFpyyhbXrtfqx{ z79`?G0ZG<&x4#nNsWgc^Q4}rO=X0}%d9K7*K<~a_R**eCr2tD1i!{G_?!L)7j{pAv z6hZ60`i^VI^6ks;^vi((iwC{NBPYu&X7d<^PB{| zP&4{QEk<47<&>tt;!WZ}bdLEx7$_{kKSxOskFMbe%Vk9UIoq1DPAUqZLbsG=3sY^J z`SS11+JdV2nB~-ZUpSQ25yiIGPA*I5{A_Sre@-l>i>}7X{MY ze(n-hJK5HBtIlaRRu7#iVyl5*PUBi@r~CMPS?k1s0vlT>k@q0yY!7$}p%>w^L?6H~ zN7JjQbpTXE=pj;ccBB5NhCK{A(rTL%i3^H$DpaGq5?++V4A<7wY-P542zFMid6`UB z#unsad|Khj3X@{+Rl%VV^|R&?Vq=l1ZHdIWh3DXv+_MRW?$Lyr{?uSS`foj=t4DXk z%U3PsaA+{luBEQ^u7C0nO=tZgS5@_;k*8%86(-6gq(n0}EBsmqB5j7*(j%GUgO+i7 zMb!;`u6bo7yTY)kb)Zn~Eo1B+Wy^?0mucI^wA0>4_M!epXfyvR)13g?I=1o!*v-b$ z@*5$tJe^|HAzy3d4duxHy!Pt(V);F4hqeiU^&^sv>QU6w{h(>8@N@&&Qq{HBpDhov zAN5zuQ-Qp8?xH?Ic4&Ep&|9)B8r0w7*dyRt$0#k&>gQHJiv@nHLo?2bYEh4_fqEnp zMJZ2zHOi&ot73am6~7G(c2vjF1Vx=z7Hd-lGAog(Wg}0sJO`Dr{zDN*^J?e_<9RTX z=S2p_hv>C$dN$}bAUP-!SoX0fsbyQbbs1YxBJ*dU_r{d@ZDNARl-pOFC0loa=rXu9 z#Mh;hnte+>y=`qm&G3(phT;Q=SJuz@) zMS`Ym-M`rWyeJxEA(}_|&041n%dCJWHFluUe>2brk*F#p_B1= zeTwEV`)qm97+bbjZPR{?WEa742#t>ypTyB$VXa0xn?33J)3eN*X_1*?(Rj1plEdn) z862s%Xqb)2%UJZ)Wn%D(L625Yw3>+Ul}v>D0Glb6&qQar0C|iL%{F~q$aMwfZC_cD zpY>n++1ki#(zYSrV79kltFH)O?Zl9eq7$<}F~M2tmK;Kko%D^hZjEcK=(k3UYAqE@ zsKZ4s>hQ5%KUhw-bxcBa=~B94Ee>B9sq4e$4phMvCyH9Qrqhu<%3V#Kx}&)>ZC^;u z&K+@w2=?Rly1UMkw;1xWxgF(5R+v^@`E=XpsdeNyzNK^xN3rD**71E|yffQY;{CXy zC{V^Wv6IlTDP|dk_H^aAX4mc1UQtb|4Oi_}#92kV1@4_vdO$0=j@rP=wT*3kM2;9d zJ44-|_9S4P%tiRd=OG)tto7EnzEvLe=ts-5zx~^ne+div@JiRUQOSx>`tV1@K4j6n zmOazMlN)aMMETbr_OF+J3%uz~e=E1X^{tkF&wAFggdZxc^}qG4Z(07WeC63PwUyaf zg&z{>h*E_g@`;@Nh`)R6WipePhe$%8&vQj^9>~Ip$ap$hG)SfZ{Vg2|afnWYXOGe3 zqHO~@hxUNlV1-{1zYls7Bh=4{#9l)?@FvbXPHxv|1D(!sTE1!B@RHQ}H7htPgrSy-(y&3xDO zQ;X0Dv(eT%(GtOI6XDB?2p%KETMT*ab!!Krso)CHiD9F)oS-Gw>bJJOE!VVdIcg)) z$(BORgJiK3Km;$(tUuTs((Tl8^!#OGUdc7Gxfpeku@z;rmebbjI?K0Mzqa-;I!z;j z+ls(^5ZT9Kj+V#fH`3kGSHb?OZDD1sZ>(`*Wot)=TIp=U4} zm1yg{D14To`=b35RmXTeIw5qrU(qaJJfe78ei4D$36sg_=0p^hDYP^eKeJ2QglrT? zADaUMowrJ`a@|j842w+rMud-ds{=)0q>Dvl1T?1;iHnX{taGV~&mS$F*4lIvvWlwK z`9e_IW>~7LGs8{H!hX>`S$~f_Ugc^jQ?_W{s&i@}&MfUg4az+c-#RHoQbLEVi?+BF zMt$jHn+-0w2I>6TC{}|q8k%C!@>@^MQb%e2R6WMb*)WoC+g(xNP_$tu?`5XAQM*b= z^q2X%0y=Ez<=N)qREWO4#`;oiALFa?tH1j4<<$@T!1v3` zU;c8r?QL(jy#KHd``7Z+r#@BQ>%HC!$f(lk>cCc!aq7L|zjBkCEbqp?g4(9bHH~+G zBZ3d3w0*g7AVf#|;SYcK^7A)-<2U3hzVa*N3!e4`qxuIu=t0ZR>#u*De9;$uu_P3j z>qqN7*&_JNbtu=$Qcqu~#ofhW4L@UaD+``qUq`q*zT zeQbe`{K$`#fA{JCPOiD;nq%5O_yg=?3oQKXiBEXqp^sfz(=KA+(HP$9R=1K5_<#?P z5C8BFU*13IGoRF~#TOmpoPkd!eXW7&5I@eHro8LB#k%(!zy9m;g0rk8}yKUCYpNM5Z>2@Cd=|)Ija-^=&lvY@S(&%N+$ZyfGBv<8Q$l zKLnJLR-zyApuX|i%IbBQ*SFek)PJbotZ`}UH4XC52x{|Ru1!Y})caNh(lfdM{>1(R zjWx?KtW8ZJylnPbe35$rG9#;xD0@(wSmY3~+rw5T7AeFjD;+jegT8`KZ^z!|a(E zmTK0NFm;q*8?g4X!}WB{WBYaZverj@#78VY@B6;*E3bOhtK@sW=X;j-Pk!=e%XRm< zPVRlLdoAy;y6P(V`mg^wNkq{unP^9#>)AmAI=ETY|Lo7c^!Vk22fY9L%O`!(C(AqE z`HtoN|M{)ol3U&S){4(Mn9}I+@U@+{IP{an_1Ay>*Q+`ad{E{cLZSZC^ynVRPHcj& z|GKY}>yP~Hy6f&Ws>|h>pa$x_*d5_*r!fi_h|iijtgZ!Gn;0#U+qC<+Km1&I(vzMf z4}S22m-nCYDW4*5_^UU_*FNiOm-jFG#h1zRpZ|Qh<<++wiG2JM9>0{icq!(W{`W7* z=RWmwm*rR8{3`k6fBVTJy+8YNKPwM;$U~Mzix*q}_y7Li$NV&GpgxXdub_=I{95&` z4J>3PLKu8(fd@b2!SeV|dA$79U;Wkce(}wbzxa#4xb(3Fj{WSY-xq%J;UBj0u>}@> zHuA9}EdA*aAMvn{kXO9o74o0I?msX2-}SC{$ya^#S4m=k&Vj6Y?eJcpL3NzA{iZ6B z^~+NW{Me8G*z)s>zxa!fU(8$34Sq0+t4}l?Yr7@Ch>eJy)v-l{_ge&d z>?)Dr)q6Um;rDz+lrHaDh%9TI_}q>83X9R&7E89*2iDxR^iO4Z5mw|KZ-4vp^YyQP z{qoz^4-O6_k+^8Mbm@}Z`sjS^u6Mnw+~StQz7(y@(@cS95-p8@a#-9 z6|q)s6j>vyk`+zSy#RhoE~@Wch0ZvTJ0(sRI~|WQqb5#y>`uoQzSO=KgQ8gPmv_>g zgi>lM9vwJLo>K+e>)M%sri^nOK_B?;1m41H)lCiD=w}cUQFuqMZ5i7k zv^;E($zlo%TUphyqX(t=YwwZmdZrXZo&dVGUn|kim}x^i4l4_xf1^3$oDpA zh5UIkkxgi&)MvFQta)Ls$9**YCgH2K3AL%!!E71$t0R-itAg94`?mc|oE$Q=Z4o*c zSQE<%L@f={;ivQZ#i_Qe8iRiP1?Fgeil5aGwn+$Se?W2lZCfJkku~Z8tJf;k<%Q95 zOgFqbh5p?wS^~VxY@o&cwthjZwbPPkElr~A)5~WybQHt>DfPOp$TVAJGFm&dL{yHv zv|Zw>@MRzQ0HQAtSw&-y~{BdLm>U)G$^V=fM_rF-D<<};JujuY!EP3zfH zfPO^lwY9ZbWI9iZL05&_hU^q2qovi69QA{qH_R_Z_*k&M67k0ajcIGYB_G8ck*TeE z9JK9)*krZKs#{Bm&WJ?f0%9~h^vcqfx1R+FK+&(2DdIW(orJs=uCk* z=I0dExYnn4oTHHXkopbWG7cU0t-U+CUYEgd)_T;V9(8>E6F>12$KR~=aUcJ2^00?K z^tkTt{_gMOp7*@x@y{ZD41z;9hvQCk$1o6-SRbG^GvzZo$tIXdH(aBC)Zwkw_~~+ zZ#JGx)K2^RMK5}hJpcL6li&HB-(B8cd+lB2Nh5y~x#5Nz zR^N1V$bS3V-(J4;TfSAUz1y`*Xx4 zxBY{B$9JrLzV#=6@+al0t8TvhcDV(f@Wdy`w-{y!gd0lIyR( zVI=$g-~auWpO1h12`?sAvIHR-3; z->fCTZhaPAjCP6YgDTVYTI)b{Y#+P({q4ENKfdc9<(bcX=F-O&c+PX4BX_vN9ggc4 zezx+l7ccLxzv223|NB4S{g=M-u!lWtdB5;8?PH5ETF@=9_{Ob8eEW{?_>SfMt6%+U zIiEli#>;UKO%XeYuq2=9&>P*NsOoX)`o{_Dh<5SqenUKZ54_f)~7C zxyJn95By+bW|f13m5dj>@C8dBd()fVw7mbAkNFt+kN@#M%583Yo8|q%VSe`Q-~R1O zISahyEpJ(_g+qRQk9*u>T>sX?`UkJ;?|I#I^83H{dx!b;YW@4I-}|WqM zKIPE%+uZiJhx7=rtShqI_{(1*XoyZSad2!mM`GaYdX)lVNMR1>Z zQ8to}FyCQ*A_2R^DMP$oTUr{_Z>Y|yFT#CTgpV^DCokSwevD9zJA}ozY7KeJVn24> z;rYz!j3JS@Sh(@V8|82R_HUQhi#hRr@ArO3->!vbbsOc|auGX&&^+xu%K%zg(X4_+ zC@mAoLMxrM`n6?RR~3IX)_mSdB}7-^Twv~yo>^D$vVb|ja&Xi*;f@;_(Esy%5GNn8C8wL^ry?W~MGXuU@DNw$Vaq!%@WBZSAGcGB+w(57I{fIyzO zuriQKjHT?tX`rL1!m_rt2IY)150;-5%?8Iz* z&CcPr5(Z8*jc+PWHFGKvd|MuUO5Bi1|!WLtB^P69F z{IZsA%kTc~|CRsn8J{5^`H>&BEcw`v{aE=g-}Ft2ZtUEj`l(Mm_Mcnd>Q?e!|LcF1 zfA-J*+46qzat7i_#L(Mo_qoq~Z_Lb|MuVhTlv5b{2(gt9q)L%-0#re zZn)tSm-ma8K%el0C&;T_^~&Y_@M7WDe9hM^KNs=i(?0Ff+OdRDqsJXuRrv$mmZfbeXK>1<@&c6uD|)4zmeblo!^yz`lo+dR($XYT(`dTaJ?K}CSCZ}yWjopmD3mvn{NMoe@Wtze4!5 z>`G)0qd)w-WJ_b|WJ^Q=`t_2o`NXK3+RAMa#m{yh$R2HPF=P~=kIg!Lub0J2=(J7| z-Yz6Z+a?ZOt4pUa-pnRgH%WkhjkSuS1=G`MZ(ELVwEzj;sQy9)+ z*N1RwaYMIMuL@O_PqEXNwI2QGM=xK%T7C1<>Se7D`>+o?{${1czeM}4@A@wJlRx>B zW1g42>}AVu$64S%96n6?fCoNM{_!9Gae2RZ8Dv3wzoVCP_7f;H>Vaa12cmccl(EBw zB5!@`Tb3nvy3?JGsE`e7-8Wo+{Yd89-u5 z@RL9Jla|+uZ@pqX3;gmY*N=K_4X7-RnB}f7-NhEq^>Q5*~Wv*y81@CqMbK<-5Ln^-Xz;m-W8;d%j1mT)7P8 z>6dC2^ZX?*d5QeRU;O3re)+OiGgOO**0;UwZRO=JfBEu$@vTRT7sIZ->&h?x=#Tzr z`7K(jcv0l0H@(U7MXlkby~jTGu}d4C|Geif?_c&yFFU=LwMY(2Y1^r)uMw>!Lx667 zZ5XeP#gN71M09|k!X6dYNJP{JO9Ey5;959mS=A z_Gf?YXAgbmrpvgqz@6^2I%pr_&+=t07KWA1NqY+6(foSt7QpX~dxp1JSgdyoOnmGJ zx4F&A&))oZZ-(RXtY(&A{y~$1Gvp(yyY<;4qE!v^vu zH(kAi^#_0W2g}bz{nL(K%pY*S``>^0($&y|ix;ZD^}m1XvTpJ6{GxpEZMOryHN)AAvQeS>IVJL?yOr zc_LGL*<54yg~$?Oi)V)j?hn@AY`$9Z85ZA8d)=A&w(~^dWU$y%{KcRDc~er?v`^GEyS4QNtT`>)Af@JGNNzyVTLl>o%0J=?=t3^mj#x zXh=V<5Mg~?j(N8*CIFj+kqJVb#AA2eN(`-QHO=kb11+`3SdY^7!@iOobhDj&tCq0g z0;NS_?@%f~V40XE_faMm7Kg6L_Ltvd`==KZ#HRw7JV5L^q=Cw=fVpSbc#vZ2yZ+n; zm@L0Zr#V>b*;q&3G`w0k#HVV+u<3m(wXGY6xT;ukf&^0j}IOxpYa?c9*E2+22^yI2UHs-L)=Fkwn z3d**M6AJ~20V@C6HoSy2UUR}|r<`RJTh&DI<28L z^GH`%oIV_>q^zYyJG4s5TRuiBN{6OT^rNTmw9gk(H!7}X{rO&&yda0_QKE__i6vLd z8fwb%=lYwp2FmtF52qVDW^I}1M07^^%SUO5K5v((lg6KQcMqggrg?BDx9*+kfn1zkS z5wxzau->?J>CXgE%DRz|Dcq^P1K4>*QGdHfZ5F|G_^W_!P0?oCBI9M$3Za$SFg*+M zcw}U4H7RPK)T-swQ`;kQ3ZN-O=BePsmv45m*WMLUmw$c)JJ{PMCS5aF7^_7V_s$4>1ZG{4U=o#%dxCmUVZiQ z>P>HYlakolwD?A|gXQNB{J{4wzuD-uuY29{e)yJ}p+1Vof6Aw<_z%bC8@}P|mwyW^ zzIo)cKI_SXkCp53H?CcCr#l_j-07M-nY!Nlz3(YQTW)#eSMPbxdjKUn#7Z#q_R_*n z7C*uCjHf?idB6C%!6!cPiE@iu+;U8JaN~0Lf8YmxVEN5$ubcSWjcejVy7yWBbbu_s zRcnFU-R^eB)pu-uX5iMhzRigLO@I5=<>%t3R@=`3>>G4;g7K6amsg`6@#EMn=F=H{ z&WBcBZ40s!$!0W2x29*dHMF<9dhI`pSf=rozkkc|^>R#A|2*Y$p0fOW$U`0?pZdg4 zl}nda?<6mOp7oIKt#4WR$#Z`AhnL?bv-ozt1>SSxDvtcbPyEF4bMX_MBYO+6xd;yH z`dat1mMIRM7&M7)Tz$)<_404u1nb}OmX)8q*B#yqX6TD}_uz*-c=>a!i~EJ2t$qS{ zh2e#j&w1+Vn;;+in8z-E8fEy|#l`31TM0|q=fRBRCn!*iop$_!6iQO9dz3%4dVHSt z1)}x0X5nCI{o9y>g9CZ+gCD%S{*o{K5_#QgUn@WMV?VaMf7;WYwl<}a@Taf&)8+Nz z=P&QE_{ne8l*PA`Eb!oe`CxhWv!5;B{LSCIr1`$@`#$;ipZ@QUe-?3B|38lE%e4OL z!~AdYlfch??sJ#-i*KI%yEm`%<;6O=P(9>b3k=`FT8^&Q{k6iv_J4Z!>SsIe@!t0k zjko^8TMyUi+o{l4M!nj~)8(kls?+vGme~r*+WQLRBAHCKmM1dxW+CNsmwyqwBngoj z*@N(&H}EHQMTNLv7%fI6$K zECnpYW>k)7P+yAh`D67xx^MYf`6AqB^~$5|Vty=wW0es5SR1VNu(o@1WDXYVVVm0If~jWx)(mSaHc3TZ z_Of4G)<5;BPnBmr^O^Du-}sHo`|W|u3o+*R^%Dac!qr1|MO|`^+!KD z_VlMeefhImt$&YeM@4QjL@fw?JLW%a^?LWT}2OuxPshrf3PE&&>?^XU3M z|9|$r15l3I_T4DK0LivQyG`4zmrcs zIU~-!_ui|Y>U!0YQJL;*?5?Ku5t`;V#TPQsXBJst+#3Sp@$x- zjmHz*e_veB)>?BdGXCJfgX223{{h;qjFWX8Q`cugW#K3)m*m>kb=F-+KX1SNcKuX! z``mNSh2DL7L-WI>hEpAtthj_nJY2Dzs{fj?s#0a;A3Jue zeyV=vl1naumtJ~FyOj~wbI(1OX^SfUz=5&OI$*#6ZP>LG(u;fb>J_IN>1KQGxhL$n zLwrr98c&Zu;dt0)+ikUb+ikYdS1l&jXja4HYZ=Fn8xK3}yc6ub_m8v)mtS!?O#N&s zY`x9aneUJwRCeTs?FGThEF4*hXZ`pL@qVf$*n#Hd~Kv8&M_L zM|y5#0fsl1e?Y{=^tO>4r&lJt1tB271+HooVgNw5%aRbRBbQ>vQ)FKJ*n72kPw1p& zR-B^o6ETE?#shvWQF;*8(54HN3lS+Rf{RC*e>9y>>h^4iI5gzQB?0E0cit(q)&7l? zJ1#S?PZIgKMa?6fwXqrUHrMP*v_tRjDB4~`0ow9NHI&S!*U%ri@|04EY=M-D*UX?Q zeoHk5N>%0ZO<3GS99#AmDx$i4YO;PG>-E+u1^(+dzBIK|!?No!w&E1byKNnas-iYG z5NS%NEiXzT5x&&~poB5sUGrcwE@Z+RV5}vGH-But*=EqQvH^7c_1D85d+d?^LhbFh z-+^Bs1B~VXw}@fZ7MnkQ_bo)o@b22RE1Y!ViE!}22W$84yYCL$Znte}JoDeD{|kTr z`)x39-n=yC{P_#ulaD{v?+-ux5R}1{S6&rM5h>FH2M&OR3*!@NI(P0I{dHkt30P;s z1pRi_S@B6+%CPH>JMIKG+RDhhWFR?7>*%A8uAW8|;k#SKC*#eVH$U~8zhFLm{P8FH zJyYM%h+3xaP)37?9d>wp@<@cW)>>1a#Fm`SG;-uf7%^fbG!$l6P((Z6sx;<@6)wt6 z@t}AL;vJZGPUE3Qe~QK@UgbUMGfqC~B-nrd19U&8u+?|Bit5hCaP76%YWHTFZL0lj zmF2*n9tc-lafNtFv&!=HQpx%4DAmG*u2-KWPKg~uO%ylSikNM74w zj!hZ2#f1VqISnkp8=bp!j_TOSQ61Y~yH!0)>X^#YYp=OBs$-kwPxwUj`M{t4RC`=; zlBkg;zfFlx;L1{W?bc0)?Y#5OaN$K4>Zih>L4)8~ zWvqpyO2Tis^%l6{#v5US4c6BobLY&7bftx`@+vFq@JAngR2zP+u;L0jd`=Xu&@IyI z((spGN`Jsm4UdhR)yZ87iz1#1Uw`#AJow;)Ie8{j^e%<7es`AEyARS1ZiQI(RdPcFE(xl%fCx9=&Dv9)eCOj)Zaka;Lq`p9zJ5u3uGUNN@92w8 z--JaT%o8AAHm2;r#BoWE)0B>IQx1Ep^{XcoZ;qBzN2q!L3@sN9D2%E%wlXy#9lRw& zyXVE^s3arm?jh&h3+)Z=TwK>l>gnY;Iq_BK6AErvdo( zTmb(I$#~hSz6Th^n+iEaa7SS_7LK!qYE<(j%E&2H!jr<$2iqbA~}( z%2FEtwhh!nR*9ar_o9Af({B|tMZr_^&;+LJTWlC@t?^T zuN|84xvqrj)^Herdt8zp{EEOnfRvBVR0qfD0k{#^KS~fCgFqBKzigTU@X1&*mqxaEnP+Q>)W?j8Wy5~?CB3YtWVpC| z@^FoS^{zaEO(kDG)E8BA+8jPOjW|E7Np=Xz8r)?i5rm%^pQEEd4T)7h^I!XLlU-1v z)1bP1$?~CjVA^VaW#eO+xqPI1HJTo$$%W%I0BBVp3CHPCL!b>@ox^S}54djyOSmNd zs5Cg(>M55moT@>U2Uuv$CjeisCFH*qEPQPKl)PLUFw?|+2ChT6?NYM1`erk(`ORFO z34*t++-+q;)pP96)dA|y2Cn>YTMP&Y2*`pOeFX5M67IpcQ4YYZ<>6kR^5@dQw33L! z@#ErBBau(;E$El%8~Uk6gdd;@z=udhl@y)d`Vz2{*0Je6KO^X$QhdSEca#3PHSO7`3%_=vASM zeUx`EEgVb=LNILjH3bPiUcRWV=gXGwCjwdr($lY1;3FKhx@-DXbMtW_q4x|-5k%YxfpgZUM~&yj<(Elr0%rTN;?3$tR1w_S!qWmhhHaZiZ{F zxdsMRuHo5alTEb$rkif6-3J|fFkJnYtKp@WUes=NLde4pKfZA-p9?!BRzOxT8gKSe8AA!y2c82+kJQF z-MbI`?Qb_~_YF5(4=^`U34p8EanyYGg5e!NfiySRxMCj%G8t?^1C+?QuSVeGd1 zZc!bJPq+Hp-~JZWu^XZ~_My&ORnM-v`l`5&nLu@UwbfSBPgT!U9s7ReTG(ZlUPeD} zyfLo7>SV2PGkQ;2cG)RQ(7ldP$zZ$?yTRz#v5;}-7mlVGCcKE6#i#Aykp0XaP}Y0hRZL%T(dmk z#1r9&s7~(iy&W>&K7P$L^}FJ8#g$jWU3bPOYJD$~^MMDmW4DrB$*mB}ev_74LCJ1g zXyJym{BR@KAxS{K>$MF(mJgVW0_dSzGQ2PyP6x~3;z89{Amqk=RNVqbMoKP@KSc)) z87LWX+P3s@y`$=naPY=qws5Y_*~-gSr-9)IMEb(Q-xb#cR|j0}m!n}JARr(hpa7^& z1CNN@NFWFv+^A(6r3CW?3xBRxr@n)d+ecHOMnu;r$;HPq*ywGe%My$>F}~q?$qVh$ z-7ZK|9q$rfapmgteTD}Q{42_|Y0jhBoZ5TIb|`?-a>rU50CZ63>Y4DnOUnmH>p zjneQ{GpWhF@P424*kjtY$;63{bh*lb(@osmqKFT@1b)GUasvvB2XrB_aqhnRAF%h{ zdui9*|M*Aco9i%81vv58W0PRw#7!WeB#I0eTvMUC0asdFlg02=(kMF0jd==pI+;2~ z#lvYCH0nCn-~7Mdq}N<9ov032*@|+s*w%X5&816Rb*L7Nxe~VvT@C83#FrjRR2zz zG)dQ!#8}HT97=dp4Y_~}H~G=@_+1e3^H)Vmlm`^JuHTwdm6eo4_eyC0arfP@SEPIW zBhtYXCT_9`n~v#+{W&>hiFjOmju+Rp7nRR8#d3AswqejUG*NN^kygKFK=( zpD(`eTsoMyue`RN#HUOtP%|A{nl`z(dI4asCmb*7;RjGW|9r}Tb8~gWHy)t)KIz)% zUGVKoY;n1=@R6$}%8sJNG>=7N-zJqlp6b(*Yj&S~<{AB*u+BO;zAB9J4+vP&@$9ov z+n5mAh99_55eTZ`+MVo1tY){xivJhrCqN7%d&oM*PAgjZa_yDSXsRn1igi}x}z{f7nHZevTbL1$MdiDu<1Dul z)ia!@)z08EWouLLZuBG?aI)5t0!{_xCcw5yGFS6#HBvhGxYS=k$U@0T(PRFCaZ3xW zgcn|T97;Ppgb;4VQjytyWA zYt}Zc$(9DyB}lM0WiAa{GZh3a5OK}#l<^Y5FMs(BBV z#S|~;V8bR}AF8G!hz24vG9_H_DO>A{UeK42bu5t#)vDV2vQj4Bb@iqKnU?^a>ViyD`+NA^+P9$~4|KTfDZpBc`KP z3#;e=0d)Y?O<|O+ZNl=77aVZ+D8Vi#$Csl6;|S)99ol-1NiUDOZyqR|3^{ddQOG@KTjc zu-&gu-U#4_Na;a`<0Q1^6Th3Z_?@G*4SlvD+9o46lu>fy@-&AsZm1QEye?U#BixkJ zHniK~gGCPMkq%#9X?~mEQvLIhS5}8TE6-j{Y8->-` zCSc8M&xW6iQ;b$RqgiT#bhiNvk^WNxl8aiDVZLT*AK~Iuk4k2)!T=O0Gw(hPL0DWk zNZ9DuCTD4>&Dt)p`o^l{^NiXYX~CG(C!DKVIi>msCsE<%qUJ>b?`Zv_&*71-A8nO!&~x9i(+ zSMJI?Grw)$PstO|5cKHTLqFMi)^1@NyHzOu{YtgrX0Q0mcO-&{&G}cGVm7RL#UT~P zj0KFO)i7#$XEt4#QfGNpV+w-COc_g&KOG9vxLFyv?pGM;&>Ewe-+3f{{g>{qpEGC9 zgo~B#Rf(o`uLBQ+WtLqA%2$`v&9DtXH3KN$2HW@j7SZ*5+KyiHhU1g8uvX!%KXt(8u%WbRQl5v}K zl&tujiVK9FS$6>V{Bu1MS}HCjudSVO^_h~1 zLw11?Jx2oFqf=TJ1*)T^;!(W4dU8ZVjo?KznifWZ_Qb+AmNhFfGIN?riwnXdC#%1F zX$m6eQxKx|qAtlGou}8-L}ccHe7!jc$`gS7E*;19-RjeXWrLhxf?0BIXU}2@#(_n97I|e1&Y(&?^}Ssf%+cmU64X#`QbPK z{9+F!i@E3n3_t8&raswZwAB%t9QZqZ{HbqkH=qg^HyT&v3)diez?O+-I6%IJ;R12B zHq67-T3x*X*E+z#$0ncY2LwNxfA%{^j2H=*U3Mwt^Vme09w;E7fuIKFvfu`?B+M3W z#y8ywoozg@jTZp!E=gG4F)i1P*?3WWTs$yrN)Z=sqjzefCfZq^c}+wT@v@CVR>ABOvnavfE@yn(ptX*qDtMo2~OE0?&I610ulibeo5u|KYKgh{OPg#Hn z&(<<}QJ6~0O+$C2KD^9uYM7K3ezx+!bX0tb2gRSOKR6w#%zy|p(*_G)j;BoqJUrU! zD|m!)X>fUsK@HbtedO|v$}h~1D;p~BZEgUnedP1omPeEvT)L**68!1`Kwc)Q-rDLN zr!D~@4_809a-qVwe#jPXx-kv)ZtIt+dTo9u2d;il@{->m?QOm48ToQ|fYkp!l7N6E z2FgfF;kU1z8Vt1B7#7L}@ch^DmEx~_^D6v$?8y~_tpqL&h#Kk4r?j{w;z4QT6kOUR zr=4IrO53w(eoX>yxRREz)`p-wD2<^QOIt}7MTSR?aj}%rugSj@K%EM-U{#j67lul@ zSm)btnO0Rk7u+$e6hxr3kO=Te(bli|lhhtp7Nl=-uo)i*_?L0Eo%=Lj9aOR-V(W}* zTcXb0c_lG>k=tfCvU-tXp*`f*mRRi`quA|rOh-a#V^mEyT`FNNgX_30jNEYOz9x)J{-$Lh2v9YP?O zL8XKql0&P(Ug`v2jH*{xtP|TfsyI9sQsg5(jwSFHyH4ig=n~|TgZX@T~Zw3hPjiAt3GlWpORnMN#2Enlc$O8sagj) z7Qrwv>a~O3!TlN~0fTA*F=(XfZcW894w4eVwX-Hl{02$KTY@oRo?RtG97B2%2#&C}%SgUn0u9^6&-#+tssqcf6_pe6Mp0o4hBJDtCCD!v zjE$(8u}-t}X))R?LH=t%661Dmgg()2e4;NVPrvT%g7xDmp4cxc8+TPH4cg5wvvG`` zLgG2RcoLFgjhIsgc|^4wmR8qb`0otNJQ%FTxf#y-a!bA3cUo3%x&!HOipb*QDv6A( z$SaZ(En9LKnAmQkV;P1mQ&cYoSyF6L0aqD(8&w+zu*QbHbmv8SW9i|@PHGChQwT!j zp@IsEvojVsA!cIC!cvFZ-?fWDaBG1Sr+O0g^N=PDd8Q0Wf1CC#7@$G!^J;gs$1I~A zA$r$ibK{Ggs+h=!7#$T3-|YK5FCn3tK}ldIcK=yK#6>{tX{~A-JUpc9vkVG@87Fv> zE|w`ziB52Lmm(XgYI4gfzCcZ$O2?&-V1c9e0`p5V00iU$#`rFgHvbVPmfWm?L{2WZ z`tTH5>lKfdwa&)16370K7Q?y2IR8RDO#=uEue!q78O9aG5QlkgRh%Z{&3##F~&_1t-z8tb<+=K?&a&@C!hJkc=O2;z)5yt8*yT<Ck6kRsaU(`2Ul+-80}LqcXkhM(!_!7*S7jTQMSx78kO$d9a6lrt8vgAY*MY``HL z7fK&jeEiP;JD^KI63L-nUd2DfY}h3!c-~MDEfE>1QEaed1PVaMY;79d4>S90B7B;+ zp88D{WPY^V8vh;Qv?IZ);M-)qluyO-ClxzCyLlHTvC)K(*54G0H6oAjoZ2<6S1HFn z!LHAwmfKi+umj`vgjkp8LGM9W&?ZD=le*Rxat~fa!*B<*lwWH5NDGvkVvCv9zXhYE z6-F{%1$wy)^@I5viJWTk2@1GuqB*_Z<4KC~!X$lZB;_OYQPhrw3lk zK{o&$fRfrso`qfl)k`bO$HhvrEBCHbKntc|mV+wt6fi_5@3^Txa+HP0WF*7SoVNso z?+%NA4$`tRe5++CJ6Aen(by6Vi*#Tu78kn3*9yAx7ZW|fKU9kn4VxOAriDAp3`>YvI5JDP>ksF8! zc{7*x%NUom&i^&#DG3(fWFLnDd@a;-<$_ zo^$LNp?a`fa^(63f)L1xf6Y5RD`0mHEPTnDYr5^1b9|X!*KeXDF4Qc|E1a4qw8=IghD0(4yx`gE47Nui2Il@}xkyn>v zhTqT3+995fi6$daVct=ib%T)5M^HBmGX%jBb0vWelN&VQZ`BuCtn%gyWo2M#C}vJqq)7eB{83YEW1%!*Sz!h-3zQ{g z^+PGBbzJYQndY4lF72(MzJ+!Fm6R5$h?(@oL)0I9nsGuMl{>d=q+Lcn_h&~eAw$X< z)!~#W=<8O=Vp`fdxg7VG9Z0x2`4EeeCIL({pQ&IAg6h6}r1Sn%TfUe?uI2B>_?00R z=O4IunwS47&C>`cNo&-6AF30b~{(?aI6;-`Mt(){g44w)ScnVL!XlLK6 z1Pilp^bXKVOe|I)&#L^lN#yQOnIhykGW3Gw1BiSZteL2 z{kG`n&a?ce35=v?QX_MqFwftpuwmh(fPwAtSG!Ty%$0V38GXh8YB@B8g^^gu6$$%d zaZ|vKCF?{FZ_t6}-DOe~kPcIGmxWEIp@lNC;u+COi@JXY1$Bp1kM`q&+@IhWkrLGH zAZ2AaAr886Ug)oUzq= z0bBeRb(C>q`pQ-B11X1t#&{*!rcG$DoH9;Mc+$ScJd66btA>slQTi2nGQ9g|laf-KqN5P+zlJQh=Dz!+Hw>-D-KL`aF-H0A9^kS*H2>g`*f` zWP;-!NJv5Ubh&Jqqm4=?wCv9)DSsI^ND4-JJWdhtmAUx}2$w-f^ySD5x`cJY3B+HQ zCcS;347v4@IZ@TOBy8l_(QI^)ULJUaJFSG8LJA>viap1yca!TQ0wyQTA-O zN3oZ1KPZpLvb}UNR8oQbcGufnw!?!-i)fXcv?%(^W#$SA#s;Qly6{wPWT+g69M`7e zM9Rxq)gnKtw~I1?`O>aO3_F|%TSBqbDVZ_5G9G#P&(2$-D}@WVE}lZ&ejB6n!k&Yl zfnbANYSI(g0?+#J{Jx|cBo{&`fW&MWL>LqdF^A5g8)fQLMX1Z2`8)@;ql}=PK#({d5D4Ih%y7Znp$a6_rlj zu@S7oR_D3qGT>ixKQ?&AW$Xi}8>~~KtV2sjj%evlHdKdaRq5jXpy2fiuYQz4x+4?j zQe$Ni96O$%N6`c9-Yz2y^^yYKV|UCaK(acyIz-r8U9IFv984}yhz5E;rnI)z_!Qsm z9v~P#!llA%fie~}jE%XQ`{cOdkslPg1AvV51*ijT|0mGvw?H&0pVwh)lbzm<8w)%j zkqyN(_%sc$Hl?RWudglq+`^*qa;H$SlAO9a9Ccy1;db|jNqgnoO4+f}kZ_26#V*#s z!j{ufZyz@OAy5^c`uDGYtTFbO%?`2NRFI|w#ZS<{rS1jyt=UTN9RH;zyRo0fhUvp> zP)@zikaH6zUd8JMJ3*22h0U*U`97uBxzxdEa{)c+q2!*NGhCbaOUdXbx~M!Ej0R>E zh_*{#I^ZD1o${Z`lqE}?#}!9W42 zsh3qU#9!PVe1LO!O30B_^QL1zZ<-(~v?oec{}5JqWBvp_i$}28c1#eikB2XC{%o3{ zNIEwb0J*}&%Tm#gn()@&%7wG+^=mK%r0Unaam=i!1c%@(lGR?TEG z1_9iiDxSFm&IS|W{r8iq!y0Tfd?zkh&PZp4aKQCYi$O*LZ@g|n>8^_{=s^60F+I3= z>;Mgf4t7ja$BcbsrbuZvF8?^gA)&gkQ~hZinK`ZQ`t`FCV>77g&XG z5)z6H)uBTZ<3fo2%6MN1jr}iCN>u1^kYdsp_#TIWQ9A4S`)*HW-LMcE1*x7aZPqqn z)I!T_<$_AI{9+}Q@tL}U7{-E-#=C+-ha&zw@}-H3fLllO(QN@PkOQde#$wrQJwfT& znTM*)Gh?em*2_oK@bY4lhv_e3Y4Ls5fB$W;m#mH`pyk7y?+Kx zyEI5@W*jRlNn5JIdz{QHGH>HJulIql#y04`vPVKwJ7A%>}tnfA4)>mV|5tcETs;tYA4d|7&xI zGa3XKDwDKo(ZU$tbxCZ)PpUGcVkFgebXndd6!;)6v7A?AXceY8`eu-^7rb?H8r032 z;mQka35UYidT(;gw_!VMvohaQ-&vj|Sj$t=(@ea^Q-5MA%hUYys!3%h(ZXwcDXlH9 zyE!p(!jPSj?}vwCrLXHrjeuxhr*}Y zCL`0CL+;7a6Y!8UEcZJ4=mk{t)h~#5@93OMDeE-xTZPp&e(&hrDT&I%3b`PBI?O38 z1niAWOvOOG&|G57YX)-pW@`jliq|4WW12;j*rp(XfaqYa3UqT%syxKd=rgVVw~eU6 zKSN|)Tr>heY&S5#E+!vf(cfN0%y=JGg=8}Cy2gkz{8D%1Cir^SbHk)&4OsD1#@|H!_AyzVFGoe*& zYc~<0vPbE$4KfXRm8^0+zR{8XHp7YqWWQNHW-y_Y;n)*J9 z7LyZqhldez|2@T&N{ewnKLt5zNFk~6ND1g{OG_!9OaD`?H^&tr&#%=qwV^I7s!X>b&+=SZ*k-$9nh8HS zunWwP%wO72_RlLp)3-*iru%$Jm^ABlCu!htT{js@f9$@;>SN$f% zJoeDy+CTu~0xX(G3)iHi`c+Yb4OY7es5-wl+){?6kAhhibdB47?3QvM>!d_^={~2z zd@3f9ZMan29z~8NRXE+cH_ZSX>K8XTY$T}A`k<`P^(gHM6WvqBc&?O2fpqqtUNN(i z^zn{KF$&-=S|sUXTB39Wa2TWYCq2|NJ-%90rSLyT(orb?w**LwSVm>xIsqK$qT#JP*71r*rJC_L}!(ESvrG*hf~9#24RCY2SfXwd9V*97=mOE4&yJoPR!C&2FXw( zKCojsDZ2?O*-G>_s`L>Ccq*dB>pIaizv>g&K@L~6#*^XO|3QTG=dk zcGrmItl1hE;4b-N8b28f&pP9Xy{L?-WSQPLJFfcLdQfwPZxPcPA#7r}Js>#&^>zF( zV$vEX3YQ$P`X?b{zj~%kslp9;`EPLaEu9LXRH-Kk*;3^Hzv*e^%)@l>#|s~|d#CXL zzb!6PaTQeqCtiI~J>u>#y1(Eo!Ae~5;qiF&=glX&7(28n@fw@=T%>^!ALXIPb7Lm5^;N~rj{q#mjp z5KgIY`E8P*8W1%bV%1?BvdvXrYbH4||Tzh1k>PE^oO-B8{1^oqHGV0Y(tl@sqYl8OQdg@qpZAm5; z@f&?MjF;{1r9uiuR4E1^gmMr9*3;481E>4(+=P8yhs_t+?_r$tU4I70_-=UY&ecni zWjg$o?94aP=gP*yO!Sf+GYki^Z@FIB}&-Icqp%2U=+LUaxDxGsf$P2*{)#y)|3v%%6|=EbjanWNMpg4E78?- zmS>aRFZfnJoxHYgoJaO`-!EXXv&kn3H>cR^A&I;o|98FMg*=gMX#jKWihW; z&kXstrARybM zU=I`2I9|x1E82k4RVy4o3|a@BC~cd!2-l}S<8Lo?37R-F)x%AodfY*D26QG4$23eP zJaY~owA{Spqxr(T57gjafBurKf^}{mV={ZPCedx;>&OSsmqj{ zR|w6!Akw89`ElG;k}V1kB#CXDH7;LYgT!hrOQe{@ zqBtk>rQ{(!vaj~D>4t)nB+n}ka)(@AaL12wzn>!ycb|eKqdQ?t!Nudyw`94z3g$Eq z`~T-%2W!=$27BB-qT5X?K~e}XSOJ6p%Z~B{|jt7j(+c8-3xc4Qhv*iJR!t&Q0-s|o4RHK)2u1ew%ztOA0 zh|!+rL)%A6q(FGWF3+$gqhHl-$umJ(l44#V`&&Mu@t)%E9Y)-5fAGwwA-R7F z4g74!bTLQ2zl3wYDP4`OD_o665hZLq{|e;M?4wR(#FE49ID5VGU+9ceBPvKY1b^Od zF&fXMjF03h9z6jnEvJRJNeS22;jq1!uw4E>hX6Y_1;!1VyR8PI?X(voGh`-?}1EbcY%*MIp^ZH(qqG<(k2fo?X#;tg?h^nehU3)Do1bB}AsX7G@!y)wRpM~I0U)a8qxmkI z$xw<)uI@oiLKR%2)xuwfv(=@!VNG0QEKOecP`Eb62Q~1l5LzI$mqe@4daLeH zQ@+^{SP{y}3)IqOre>NE6_XVy<3rkp&ZZ;GpLHO#J-J6VewwGGw~)@pRQcX%rnezfC`EUtBKfA$K7?BLhl4l3m=-R)HfNSkW-l;(9c=jnJKnMpW>P7Slsb-}Z75 zM%oFpBmBRPHqvge@dFp)!f&_58!GloZl?qVBbo;ELc7-u)y2Z7-P@f4Phz22U>`TC?K&shdb&HF7k{@&kcDbgg~ zZ4oGgV`daJp25sPl?;Jq+h=kYKPLL| zWbn-!MinyCm+eV0@=U0bxD)wyTH~iTqaW<`0|#8fKG`5C27Kz#Z~+AN%Tq`-_|mnC zTl@<1|2w%LSy@;Xl+h%Py=vNUX%c?asG;=Q%#+hJ8C&A;y@TOj@;Y$AWQt|8uTrG& z)=Ex3MC*~us1;&s_7Nw0@S&6!GGfzGGo|1ZUvB;M#FhuC`Q_wFcqxc~y#K(}(YR&3 zqEzimMbBXc81v&>($T0KvhJxKiW!{5jXM1=Q2x*LTRcDmtL1aT{e?y-;|UKlnH;v& zVsZI5NfI9#PI^&`QWWPwMU)pZAeCE399qyuxRs9U(pDwqj; zWANjEw zZ^kCxC3=pbwY|P^vVSf*`E9OdokV6(JZo#nf%f*IMnt6+&`iWnAL~esmeDX5qFd1Z zv?hQ)B5n%rxE_b;Ug#v`&g}*DFbz}STtyV)W&mcUfHAt0;+VgBuTRe$x4oK)L!`qZ zuh$V(-_3V*QfXZ=SH4WK?QsLZd(ti2)61gcD zb0U^?73FN@ZY?zV1BgtQB4h5Yb8-TmDqrlb6j>2#f2h8%YvT4ZpGy5ILO0u5C7dRx zUgUqcGvHEtZ??m8^r#wC=mbWU=~@YJFiotwzMzbq+gL^IyzbyDk*3oKOkDof=@SjtF!4a#}vy*?HjhhLSK zD?N+e+_T%seG#(i<8gR$n{;6<{_26kO7rlMkSLjomMGP>JV$8eHPJ7jMeAa6P1hpr9lVN{(kd*w*_9Hi5n4ZZlWd5jsDGn%sRhKO?mfWil1hX?LI&Pe3hUtcr8p5v zApR9h%NE8tP0)oK*D*xen8V_8cQl-i{|mPO7}bLi3_{Oh%#+fF1Zi0T1ehAfdg0sc zBxz!4g|~g<5QGnc$EI&t|0=?^~~z^sEhHS?ZGf{S2AIJg8_n#_0|WwE$FbP(|CB}5&WTe z)-o)7y?s)|9~848&8LY0$|nkI}!SoK!3-WqO(!Wz*TEJ`1#fIrI{?srS zxc^F0c5H=)!h>pC-^%vs^nm>CKN@7P*c2LM-EvgYd-M7dd7D@vAYwXS zKOI)p{PVBhb_h|yo9l_!{fFK7YVsSq8{75hbN6rD#M8r-==#!va;VS9k<^q13zgsZ zlU^se%+HtNF?g9PqAnss&j-ENL6(g_kHS=%R3OJasHY8Qb_&Po1Jp zL!ssesh|t$?M5>6om>_sxKfWSS8z5*TBGJ>rlHut^Yh8xxX;=7#V8%RqI$Pi|_TE(sgUAm|0mMQ=oag+6#WS z#wCNv`*YJUf?*54e0@_V2=>h9u0nDBCRq!q&pY-IUXY)1;{V3T5wszgi4fTR#9r9w zc2nJ6*KY!Ec+dho92zI;!bUbGyHOuZNdIJqWCN=P#73>s3< zlCN29ftirJt>eQ`H`A-$QDHJF0cQHD(~30YGDUVf z-^T{Y#vVRYJf|HEkyM~O^g5154gPfI10KCVy@lmU#Y4G*6#%hWD~M?mVl8gGe{>?! z=-)r^R#262AA6hnQ$>}AiZBU+ol7@tPWrk^KpVzc2ARn6M4zBaWl>(a=tug%e+p7T z=vU> z>Qa@WSShYsSmzU5ai$Jujj;sw7HZc;XeD%~(LAnA10Ul@r%I9SuJ5_vW{CF2ziv13 zx|imv_pWhOt448QzHvojhKVD*}}BtG=3T^G8a&>n}{XOv|B1TQF+c4gHeD0fcFKc>IQz!N-r&1Nu|0kUde>*?vV$xuDgA z`ayEfUi1C+o;kJGQQN}PM;l^qNdYY8Qs05>O#pm_-j_)B_jOLfVqj$63*oT&JdF=Z5t2lhaH z1O8x|E}W&ZZBC?zI?}(cuHQ=38j(T;cR5GX^n6_~5zQiw%&# z=5(@CzUKGYH`dF*D!WykP-?16G1*Kaoa@EW5_TG&5E&03#PR;-L?3v4?b7)6hqFnFotG zHm-N9afO%@hYOTq@IE_jc-{mflkxRnzEF0Z$4NkNZnSR}7aGC1j~XGya^}{bwtah1 z^jDDhZSVVL%4tDW)u^Ot#`>imHFD&~z6C|^rNL9RgGEdxuJRo~Bbs^om;Nj`eI`@J zUzwcGQtflT`w~1-E$VAau%RATVUTc&ANjA9<_cww8!g$*qxLh1lsXn(Gcmr+ubZ4b zqw6ezll9R{AZgZnNH+TEwsc(X#Xf^Cml5F7Evj}NuJ;g967?JUe4#5u<${8G0E z$qR-pLJ)s(vocQ;;ws-&xM%%Xoym`16uS7HzoQ&6*E`Ms0Oo{~sk4Ktm00=zpK4spIjN#nz+Fbz7ER?D4#D zBdGi%W2U0y;><$r~|>GyKufhqyoA(AuDYZ#2fQ8Rmfg9$@-0 zq^sEvZperFb8FNVsxbqbc1`o12+R*L(S1zGiaA{Kw;uw4vz$Ef>$T**i}iYN|9f&2 zqFV#@QCHZ$SZ2hsX=8NihQdtmq~^hc%=E&;PeV9)*2V>^RF6DL&!{EBjLtG)s@?H&vTvZfh9HU(6)q8-adYoHpbL3eK=ra)@ z<~ip<6VjEa{|w91;Og@$S%-e28yJ_8Dkt&#C@&3OC zQUh6!(e-O7Gq=eEUA~roNh(HD%ukdI)1Z3}3c8P?bwJJipv!s*TAqxz?ME$1W`c+3 zlL7_VX5cyj;snY1&N1+}s{3NWRCHx4Hv5~LE^Wzf9uzl(-lnCVrf*>qEhm#@&}~wg zibZa&5YO@lo#aREY^93>M)nm%2JwL{zFlsF-o`tgrfJqahAM#xuiWo_p)dobPO!w0 z)mujB#IgoP%%He5mt;`eR39kkP467TvQA#k=pN|brBB*g`&UrrA#H zwv-xAeieoLglHN=rDU3usL)~36XVa6j$-e-_i5Ha+DpZd$0fYN?oKVMl%vqkdHO{g zMWFAQ|7+k+M|l9DV6|ZH>->h(7BjBZi)6tAMnF-D} z8NIvu(Yj2++1IMALCA!`yWCHfl)|J;J?ECw(`#wa9zV~>TVNn)xn{kz8l`i*ZWEy$ zM}QE8L5`T(yz5`akjVTWwIAx-r|3rz&ilp9}QCc<2eJ$Y+Hw^wlXiMqLF9 zKtzSVNinwURntFFVRn~ea!S2N60a*Zf)vMwf^9D?+E8Dfq??WMt7n`k!$gF%nQawX zCo|HG%IbGobo68wIY&wdNzyOg_?b9T`TVrT$4C00IOnWi5d3@lY~GrmEaP^1NhPn` zhe1(_Wr@dsV3M6+VdaGeQ4-oT5*k9VTirZ6KM8+izXZR05bOrNkutToxgYl`Dh5Nx zsf(azExx8QTo39Qk5Q8-`d+bfeK)%sS0e7Fl&7Y29x%r#ZK?g=K62nX@@v};Gfy6^ z)nG7xW1Kg)U=E6V_7?3Plj?h{NM*1qu5TNM7Tt=U=-9dQck(=?@@mT-)?hz8Mt8xW zYG~u6pRa(I`w8gwtUYa;NLc93grGxkAJHQS9pgxU*-yno2n;83Sn8_Mg_;uZRrgrTxa}#cv&I0kE>z>S7u7u_LT}+iq8T2>Pmk!$ z%3+vnN|ANoN4(V{jgj789W+e!IZS8s*+FUKrG((c?z{|T!9#I`DWCt_s46uLwucDrv>Pk z+;6nH#oRM6cW%236J@e`BJ*i)8TDLUf1<}sFUsiuEot;<-Fg{ot#;nqAyka~H^9o~ z9_X1T%;fqk;sr1<v5bPr;;Z>w-28dhC)Ke#;Q<_!-F*p^_Ot+papJ8 zL>U_Fs}!oaKJLU)#ZJ*y%$m{sC^m?o43So3EShL25&GpxY9>)>7l!DjG^%EPyTs26 zw{m}y*PxXs^4XS|;+trUp$k?sXS{HhT3|>u2&l`p+BGJr3qp!Ys?G6JHwr-^TP17t zyV{*}N^>e}UQqNt4tm~i2Jw&L$=t{Cy1U=%W1199yhhz)ryFhVSGSnFvK+8~67Y{S z+~z=U1{(rd2%dL5$p7_U^mn-O@rb==E}NnTP@K|5xoz!f>wC;b_1}K--mwQxpV{2d zYXaeFU~Sg8*q4MQE%_GbP*VY%lbL6!-5U5CSi(SNT#Na5_-qOIn1)R005ayM9Bw5v zQb-Bc1nf2LNE%pm1Q-i#HdK^j`m)Pli$zEY68*5 zxx>qSfTpV_zJmofF~?Q!Z3~ayjoRS?%HVs~? zPmnnYlUTOyI@O?dd>-DNNBN!k^7%ZlAlsl+;UKiY^+`LL#?Vle@cKRDrs*vG!np%T7z;nCCAQ1pzn#-w&pbAAs&mxb|nQ%QAPH-tXrXJIP`B{JtWxB2#O2 zEZ}UQcsbYr2va_a1eUd2aJ{7Z(oK8&{Y>lkUM>DGqu8c(-XWTIJemVrVL{yrkCk_- zX(mSE?Atn#w6tj5AL_=jNPFT{a#+V0a|$~8rmx6TrU+N64u#yrv^Qk8U7@U=Rh5M2 zhNnFLonJCiF*-LqRD58-KHi1M#a<2*+$rO`awP}qizi@(HV*P|SSaQm%bjI+^U!p~=E zRmEko0hR2r9DPf+L)gQxr}(m)P&e+00bYYFn47)pe4Xbk@r#|&#P0srdC0VBBl1bR zhFB6W=?W@?ZT6W` z$zRbdg)9P;040c;Mr6!>1f&N=E0&7bENfKpU)okk>I08HVxb0DE>I68(R@f^SV3iK zX5YMb)YjOHP{WJA0#Njbvh8MGRiVm9z`;{TY{X0cid-|Y1nZ<%MTIs6}*WGno*QQ~`S z4r9e}5S?Xz1SzBl0myP@!>$g)q9gobpKhkVUzMaeAJOl8GsDLy0h8o9HO{EX_a-6w zYOBEHgMxLRLN_@_-njaf_rxcXlAHpAdy`o+;y?uZM;VKyyme+mp`l?Ou}$ur*^bt0 zbZ#PfL0&fse}+xX)_5yszc%GpL2f4&-hxKA!I*|F+MIyaPkt=E!Gc~b@%mC3f9)_m zCqx&j2_4+GQt`awBnn6o>qwm)D9RL~^K?W|ZV}+v>%K!I`PbDX;~^~~WzsZrZ@b1o zxk#qWT%bo;)Fo2>YZ^+i=MHaQPQnnEGBc~gQCHq^Az@^&{w1#On%O0Tbhk9F2i1Xd@%V!gGFilii7 z;z5}MX6$DuLd-uxzL+9`TI7fTWhK!0NNXcp(Qm({XYXd?JUl1+z6^s{3`1HWM_{L? zUuYuz7>)wwXLTdQ-Uy=NkrO5E+7{*4B-}#usMY)Oe66n; zN@c9(TWce`K&zJx?C-8^%kISJk$}pg4)KkiXMs^r;XsT%_Km7 znAp*qUE%tybb~Ir)9}MulVyD>zri><= z`456E1r$aE-)s=#bgKm6DsyLV2NEp+g$0*Gtu8~=u;rj38bJ2!swYY6d|)X8>EMDb zci=N67ow3^YzXmDES<$iPMUZ}FTbnQq{e5fw9WFp6vu?{_5^HdNok$LSwx^4b{*?p7 zz)!s|LNV`mn$Ze7q)^5@{z31^K+1bnisgo$we?qm;<}38ntB`_f&V${ru$LU?EQ4yc68(Y z>$Qh=aD>qhVzfnopU3hOgFz2& zm&e`gxN>E*+cROrF~H4*LT=7~PlV@IRQcPk@tx~SK!9fANz)KPpmx@gB9H^M{b&B5 za@I6pO4=B@U!Ts{+D-oSryLBw$39pWcvMD01okX%g;`e^89=abdR&scq(xxtW$Hgw z`oc0#-1UrHDgmHq0F65yJ@+;B_dd%7gT)F(LV(N#&wZtoAjY|R=-+%_hS@AuO8)bU z&Eo{yTWSsG9)RuBe|+dXP6)4S-=^V5mzzqPEG_)QqcF8fnp@juHnhIq{fJP1gGu20 zKRXz|A4Q)Yv$HrjHMF5LV-9pYB*}Db2A+P6E>DB#m8{GOqgB}g4MnDTC4S+Bg# znskxvL0$jH9R`c#;TGrJ2A=>nt>*FB0pq~@&+?=jm%4-3Zod{uydHf$r{kfVLic+g z4K=nygG_v-*>FA@d1Xt#YYwu7QnZIzm~V8@i{VB5JwCBd`rpB!zYnmOv^gqwL@--P zJ!Tc#lhMzEpoTyu_-(!@ z1Sx&shpyw83EJy7!q4x**X`iC4QvpB%HPFM514cw(Z52sH*p1s`o{}(Hx%A4(!p*5 z_+T~g*KyO&adB;TA15IJ$+7NV2!g6j&Dt|S$P`7LCg~Lo29a0~wFbj!c}(V|9Lb~& z%xK=G#6ThQ2jcqnQvC8hfbMO^1rTx;iXRe7e9UuDLY~ zpFXcCoAP}R|2dXw+L)-yh7v>zAHTRLsPC|=S0I(ZoB1vl$OpG_9B64iXowWKB}u16L>3|JmwnVxzy;*W^NCR6>L_ZEjc4 zxkXtMsBypa-5!N&kR$+bU?>HArF7QM^sWq#(kLi0sshsjh4Qkb(gGHLt=u-qr#NXi zAxnfjxHxi-xV=X`lIqqThf!#HhRI-cs>VQ`%zX|?W`ETsrL?V$=(CTvsyrr(p!}m=58Ig9NB8faw)<_u{%1;r@PePX1)J`C z0@zO*#$-Os`~q#KZQs5{IX!>fr`Wd4+VD9|t zTR-YfZT7WIqv`b z{?vRn;Pm!5Mc%u)!U31KvBNGnys0*p+> z|A9|NW#pJTqdTv5srx}Chj*9<|CqfD0meq#U3t<#Iu}tr&UAW3DG^-1OJ46|0-@PoPiRZ@T&i56_Ztq;b_-2y4(Ej@H7nWsLI#x}wy^=>y>c2A_U#|J3 z#NXB0wj&7mJ20jng|$;W!4EF)kKz5`{{HxpLRo(8UWcZO7Te=E zTKb*Kk=>WMlE?m+pR2vHQ@rAc*BN2{y37c;+*u3T zy~G}|UqQpxyj#2ZdHTXtEG#~}+|Co@AVtQ$pZyi43wzWKB~Srv2Cy?4N2(NCsdy`b zY6$%8bl~p%N?C;b4)+p??CNa~B zs**(mg)YOWNiRfzl2@lcN=9j<5|^ci-Usu#Mw1>TBAVzsAP7In0OD;iIb zqD%N|a)Jsx$_EYrHO6RF0`Gr-KUO9))I>0pF0~wdN`kMNtYx*K@ z@#1GL&HhY%6_$}=(M1k<>kI=%$I_hqxM1#QF6bh1)3RL-cMw&EX4Tpd3WPzC`rXnvP+e0kae+`>~o|Fh)mIth9d(4nxo#TrWQT}R?4)|ads){-!NV= zlz3_-rJ1uV`x#Jb9^Ybs!3|C0+V=Et8Dnpu5p(o?CZNd98sHX8-3FRFCoc^>h(+i; z(n*5QA0M(29$@OFgqkU#h3qNKjDZ(R`aN&@mxYcREUnuR=@GX-FT#SxF>U^) z#p(X3tf}IPTpeh;pZy?e5c%n6YPDE3%2bdJ0XTYj3+B_ZnSj1!ynKH+DXd{u@~5yb z)5Z7r6xZ`9!$ zz4Fn8Kk7zB`t148B0~VdJM~mIfAd{sD&0+#;ydZbv zBl~6>pO}Y+6(*l~i(ytMHs@60@K=5&J~gM0cB*VJfF?~uqknRtCjQ~3#LRhHQsft% zAW?VE4GA3k0DBbvf)Wyej}p4H8OM=k8ow9xlQkxwPw4 z^M3P(kG-H9tYQhlbQa-xAE8_pc*@47;PrWbP3NFHP_AWxB_xY%a&g;=j<<#KOFgG}o2^>Ph+ zqiQw%@w|`y7SaTEwpfcx7}?`c0w3NlCQ+TE@5Xf)_1E#9^jbuyAwUPAL_NM9$B;t+ z9TMv8zfH9KqXgkLX&M%jvGPSxr+@-4LBLrgM%w`>2mx#B1wVkm#ZlAFOI1gt1R;x< zC|66k8rT>F+He8!lU+gyR}L6`DJAi&%tu58r|ER}VmUrk%@XGq&W{Olva}{EL`hl` z0eN4Vp!FN@p_YaOS1|WM4Dc)58#q+KE*W-_i}Vcb{58u?uszq@WKE!FI?F~x5i2ij z=j(Qrn#iLx1=Xi!bfl@KtIjqv0voan$5gBA;Mg2F5YA94yb366!Y%}GF}WmLm7IV8 z^?=p8(T*SN|0v{!!t|=j$qe0k)XlSfe#L@G=Ingl_{MvnWkv{0x-5PW^c=k?t2dA@ zQbCt%B4boH{Wk+)TE$Mt>X0sN=7Y!89Em{KCUo~YU`WtNL(%ubiee5KGm@||rlyWV z4RgVvCFEX!Y!l;{u#Q0X)d%6@%K?B+ITua}{?U*On5(HPCb**IhRwC}tWfwhK5M_* z6196kn-d-Y#94|?N;m{eRKpZ9$DfN;Ex6132Iyy+IXe!4_7pKf7k`BWqdUE^!u9vM zS9p8%{mp6|*v;HH0*#_x6Ty}=8)&cYgtly^!)L)ox@Q8^2(#TYLTDkRw z2&Bh2+0$aqE*N4!0+eZU3#l>urU;o&MPLJyzAVK9hUR25JGxN78aJYTTbm`J%58&0 zraDbJei-L>XP35}O!Gv(w*+;dOo_eWwtW6@Gz~Jp!RNWA=3=}~!owV}3`26zzoiBQ zY9?+m-5TjN;+h(6Xeq~|FAnXhXy32KEWiTa$>D_3v)2Ry!HN*E^}ht2A0{DPGU5&B`Nye9`?q=xpC@?lXV= zuV}2r2_e!0gqr9a|Kb!0L=e$-^P?i*Kc7zjOE2sqzvD=wxJ#K^Z-RXSg}`r7-C*w; z2eb4RDwfj2r{5|dxOsB0sVz@_Y0YeO8jv1U<|dc21U42R?KLr_CNs8zCI+tA(Jd}itord?8Y7<$4{2b@U77^M3<+9Sn$I^XQ2U7*O-kFcvY?9` z0jMi(Xo}ie2>vr@lqv6r%^${0?_{ivqVt2n4G{bW26$GvRvw&lMlA) zf@nT0cpz|Lz4a^cFZ7S3?^9q+Y+9hBJ=)J8wV|$9wuxY0s5y5zHKnu~RZBvL#J551pu?4jXYXaK~21ht%6??g} zwL`-gTfR*@7ZdP~qo8lOGJRXpB&2EvFBnlaJtlVJ9*YCXZfEjN0S1ow@js1JKuAq| zfua2AR2=^MzWdk>>%OtyU)9n?uFC4?9hLI< z*j)Kq>7XgwUdjM;tuHx+W0r$H?|dsSJX@pI7e_wfo7}yZo1K0z58A|R)1p&A_Xx|^ z>&3_$W3F3VqA+XnkOu2fU$+H+_O16zr~>Ou06Fv#P&A}hn5LI2viCX10(^pjCotwH@F0<{c zG?8@t?RnT~`=a%Va6@)^_mrus*o-};Ve3W)(4y*Sy;6|if3chXu}iA}y6Y%76IA-%{o71QnHScK zg|rjM(whVPaB@Bqo}%BTDl)2xK6G#kimfgTgnlB#D@J z;zGDEFN1pMwVCECB7|f%Y4o?}C8rx*YRGyZGb7_Uv9@?MQm;Pw25f6cZqOTt9_aPE ziPh;B4vVWg<`mlZ4hs~`ACHG?^X~1Lv_rT_yRppoR~RnUV4}N&@~Qy>^LTwBp)BNT z;eU=&QW#tR6-(>y3wfiekIG*ZfSz|ebyUd;!NboIOHAp@Je3=G9Lvq~Zg5nt^iQ){ zb|g8G;A_8gng$=mb~=`mR3RG0hx5G&Fn4g%AR}qX=y(c75;fENZU`dR20cl zV8O1X4w7)me^eDq10*3@2#+0(Q(vLeoFa{#olVKjs zW#o-{MQVyf^2C}v9awgP&K@;T+=jzn8y!G%rR*&09QHy&pa2BVzxz~1O6H*>6NxQh zW+=jQID@wEa*7@d)73U9s*52jU8s>2p~7Qi|AWG&V7n^zH4pxp(H8Ck)NACg>a>Fg z$g(RMth7;1R0d3!p<+5Ikb4=4`^bI^W`itC1NT~$hMt}miZ07!)c`m?|6OuWDHI8_ zjiVZJZ8L9GYQO08P8|lrh~=1?XlX!9-juogw(1J=mNOsZKpjZX$~>A>6&n^D zaSgd$h)oK{2LB{NF0e}7{Msg3+_)<161N3kCKK0DHPB#@@}5ef>f_1%#jOX<9H2(yLF!_ZTZka{=|ZXm`z6T=uScUJZP6dXOz>sOQds0;hYF!8 zfOrd8<7k5HK)!yw6DAlTnp(^+J9BQx^oPmhuF3%O=$i~FJ#a`L#yF#qby(}kO^YIg zHkLX1j-``VD-DooMF#h+L%^2YX_lKj$^Vpn5q(t{WjZ@tT3_(GP6T+mK_hd zWxLWm>aPUul;0Rv>C#S#_Jy+@@7>}zllzHNcLgt7e=0}NTd31+-@GW1YDKft1l?(_ zBwh{SBlA1!Cf5lJ>R~JX66un=$S)L&Y$my!lRX!FF#1_!%EwALRjvdcO+sj0_kw5fAVaD;C-q^hh`cdL(uS|pFqjFwDkwD(s)a1( zKl8|OUla|)>R8kYrk>={?n2wrr?MzS?lhV>=2*qhfvG!RhaGzey+;9-DsW+4+{>Pc0dLNt3^xqqJ&5Yz%QG9LED zYHg9Gxz@TnTVFCSFn;d6*WB_E={bZBliUx?Pj2KBOcEymJ1LX2Jgh1vu3kK|mfo43 zYibk|TUy(1wuCClw0SaezLOE%BWRHcjFreUJ%OPpzGFrpYqa+$YGXuvS?`KW*~L?C z&F;KKlia5}v&iIs^zE7zjK%BVq}zNK&-G3S%ev1|D8dm=(VbfvNfG6WgZ-!I zCr4WplBX_8)JhaG>W_zLp3mFMFe(mIe|kC`H0HA~1XB~CIMWu%FhVhlPGapw5yE9A zcBhb4#YCKEtdKPg*-gppPLg8TwdmZxmVJrW()3hNctQ!|1H#^CzQ>i4Oyr7>+cX(+ zA)%S{;j9RoIRFj^4`uq_q60=cK@9&3VS)#F9tha7F@e_`a0}9+!RW4iH%?Q~WsRkN zp&6QrM*nSRV6B7YW!V?od@nfG{{7WbbL=Xz<8`E9BqauIDM@SOCjBz=Vp@_CWcC7% z`1B7l*co0PJbTnsIRO>LZiilUVM5hI1&ht`6D=*$vbW;PBACktUql4L6T1Ooc`Lb)}f8-+~a>Z#QD4y~~ii#koWuwWHf zN~Iv(KZyaD%t0-(K)#p>D_nB;fy!}j;{&s7xUdyU7H)@(0@C1y1I8|axs3$mR|k@) zr6OAse_i+(N9Vh-OLX8{0zi5WxD-Ja4I>}>&C=SgYqnOyJi2l?&z_+a(iJAcDZ;(Yi>10) z(bIBW{UXy^a9Ke>U= zQDtIa)&|&!+l$tyK$_20)B>5d9BuH^aYIwj$?!b`CAwZo4xH3X*rsH~pi;HcLLM=$xfo7Pr zQR{_+PLMmd23#oi?-ESxc{br@ac}3tt351t*X-qE>oYqGk6E*oZ+ZsD3nnR&p@)MRoq;~n)gsq$9@Q#gF0a1ThS@-?v@JPL z|BbP0!tkzim`KQ=4X%4vPcF{5GA||+K>43Ht^j7tmWG87=%G2q2?3jhT@&C9?N z&-lHwCTr@zEs+DKDF6u#Bnp$(Ea+`1-z~-#@f50SV0%F9w2d)rHOBA zQ65JpZ0L{^O1gTQ29u#Xa6FToAwp(!v@lIB)zd51-g<0x+>cBnpWg`E2QQ`MjfyCb%RFC&+R;S>IfXEco4X#77Y+VG@_Ko zX=wH{acTF3bXeYWyt>YK5} zuaLCb*WFei*Ke{^_w`)iHYdDl1()00{?_Zp+Z_m_X*=ADkkIV&nLbiIdE_0_Mrw@z z983&Inbf(xZtK3slvKz<$Hn4s5%=m#yE#YQA&`e~x^Ad#cU~n)EYfJf1)nt1B(2T{ zyR$u1;p-6{Zp7XyHw8n@o2ipmcoWjb_Wn#s9M!VBYFW{)n6C|UcK25z1Kq|(krAdA zPHS>H_c5yhu;_U@Ejrj=HrS@p%GifI3&oo8ZK@slX2~u`_((Ai$McNlPMfFBDj^m^ z()rqSR4A40fOeuxfPj1U3~89K$#9%rT7|E7$LOwJ&XYVLOb9T`G78g<`!&Przv3;R zhys%vX4VNZB^P-+Yd_png{pMU*!-!ZQUsJsc@^-Y*!z>KTI?6eS*b(pYCzpWO{Ge5;QS(v};Ikz|E)h)q9EV3xwNSVn z$|?l%n=RM_opqVfhNQkZ;A-IE1XhvYa@}}ru^K07hYz!Y_hCZ>L2GBev?~wFU40Hior|Svhg@x6p}KQ zkXPDfpZXd=jQ8L%tyJRxdDMZ2@87q0KQGPeqyyF>aLRe2M$EUjSJqkcV=nBD5xK<0!0{P)sBg^Yo=HR0a4e ztK{Zp1QhEiMx)&6O;?bD{-e!-b)oS#55mlPcG&3_FDpI}=VZ!buHt%j4r0;GGmz{&^-jQPFmXR-R55}6NmDnIh2R&3bIsRL=hD{=yLUK4gv4hFhvusnL0M7qe+JN;NmVs6e52p-m zp=SCWW!QRE9D!YmQn6JporAjoW|81-ZW*>X3Cg=tKj^F%eo;X?#)s{V zwlV;?R*GHyN+40wJ9WquQ(Fi<$;%$gzB$I*0&}?#xCallA-oSP;WbLzDP{#nk#+VPLSMMK7=TMnlhq=-r@9eqM(G=*oSa05yGGJx5$Tpl^Q zKa~QR`AB7WLAsokj=O;sQb0lY>i)SoHYCl^CVB>wL*#HHflPmt6zK%*Kj1Pxfu_K@ zm>%o-PyYj#DOxCsFg!tyB38sh?|YbN1Ah#r<8=3t&`N-Ub=kZeFCr8AdBmz~?->yU zK@W7waZ&@6Ed4L z(8B7+B0y37`Y*&C=%tTW#tE)~JjSqM7Ieu&qxI8GCG!9h3Ep2n_=nd7)D?qzFVoUR zsL&x5BFm)e?Fe!1S#wfTq$K9{@^bPagE-Mg4#qCaq#*@s3vI%j-X~u4n4GBDqxbsC z)KlFn0#PDqHMe0V&;u&&05+%*uk`1*n{BfP2WK{=^Z_H^N$Eq`Yst(87NYE;;rNsd zH=35((7g$vHj^n>E+o2a#;nt}(9}Em03lJ0uHrrzIWL352ZEu7E7^bslh2L&>i8er zlmC_QYf0n7A0uVIk>!7!8mmgxjF#eTpN1P3m6%{BNL%qu_29%2mW|)D*XN4m!tva# z5HABcuNJxTN?9{>E0($F&($ZjYVwB`gO|WBqcT+0ppl)AdU5hxlfM=8 z>unVsBvvX^!`gz7=`|&CjFtUr26`Wn%JG;d*fQ*3fiuRfMJ60hjDPw+3r&~D6mDjHQmjrt z)g{femwL@rZ6k;}l1CAaGSs&#R5&8HXm{HdL0xp@=z8Q`#exCcq;VzPLvWf5(ozPP z^-Dv5z#2%4wk#Y>uv)2Ux1?tDRH=nDo4m7dyW4zzCJ8=(+hSucKk7E!ET0h-by)O9 z3;e*hYCb43r}E*LYR3tIc)u7^yRI47<@kqw~vOlE;O-(Z?!8j zCe+62+F5Kgk5bfIhOW=T6X7h7nQR`lFv-+ZqaOZnM?ys=XHcx)8eeylm`vF+ zcs#M59gl4MGw|`_EB{Y51w~hIVazlwyaYvK6~%d21w&i$y4V6s&Ly7H`gk^0`Xg-| zvPU~^aWQcAf1w6Ea1&6p8qWeEQWyP(Ma%qwnLr>kr>F9%3$Ams*!sT*0H{!*`Z{UR z@Dc3Zhdh$xG*75n>@*en%eow_84ZHG3GsT~FThQ>sr)>^WrdhKKqjN&$JjlalM);{ z+XsqmD0UZ*xN<$J;XM*CM<{c(kl7xZp*9$9VF>lvT$>~|B3$gYO7vVnlgKP5U3J66 z<9DRyltIytV1*_IsuI^A;Ord->YZ;(g<*cZ%#(nE^Kq8!b<9Hy4!F8JhK!3;mbT6( zDpn%M{9st=jWKgxO8M`Wf0MXdwZZ9|zQxkcC2qKj)|Y7cA4t$!%d5e;@tjn+t}R(i zwdn(pp9``H>c+ZPx87Tn61vi+W0`jeB?DHg2@e#uFsqH{UU^IkyJHf{$VFM*z=V>E z@=s%cd4`<_hbp5}iMIWVpyme3rwbRCqCB35S$?6ZMV6{l_WQXsbdLnZ0%SK!)AiYD zW;*upP(qrKce8U1cyFRxZw7}HM9YkI1406Z#BhKnrstx$kGsL&NJ=En~Ue4RKD9m)U~c*oc*2Bg4iH*4Nc%R zlB1~%L{f3M@TQgQ+|7=wcG!!a?=Qz8bPdaA-{;Mei3Xh(`!o*;d|%fOzB4K;W*-j< z*~6&?1;MIq|F8QTi+;3iM1dC|dEU#$=x@*CoSGcKPohrTq$R+u#zou%MnS9hxLW^+S&wcRzP*e=_iWy_l43f4su(jMLUE zUY8Tlb!<30j`jg0?1K@wpkZ&#Cb9esNi8xd(55o=ur zi7ouz578SLme2U^8wdcoy)AihNI0P%m^}Ak;>m06)9GSag5THYwg1Y@jKDh_0{6k6 z#O}yeO#j;<%mRltkZkWO&r5xim^vkV0Tl6AefWCVhDBq_rqT#VoCQ78ICe%Gtjm8k z6(kuA&v$X|2EYpI2i$GtCZ?VbGT&!T$!>MW)%+FU9qA!Pxg1X}*%ujn9#9Gf!gH(& zbu7J9yB28}c#3sM#A1VXTsPy|_Iy6AeHL{2gME9Q5GPu@UGN`YxENk{Jx_;pKg`S2 zK60#|Jg<=aP1g51b+t^1Dq05q_Vcdv?|d7tVDcC>T(ug>YV-!kQ+DH}opuxuL+n~M zLC8ewfw8@MB_J};-(@Nyy71d>ieLJ+D_gPu5(G1}i(wFO18}@FAFDv}dsI$cW8d5#i{TNONR#d<# z#hRsj?hSxV&t!5Wt68EK z;uEFS5O`nI&1GKYv~la9bT7#BN|?E_+p3&0GTXQAhLv98gDMDM*C3X9mPS_WDYc%J z(;9VLHiP;rX8oDri_vi_5^}5DfT@P{AfV0#a3cWPr|q*@+s%skn|p=68@EvMFRYh! zAj^GHpmuggP((G1W{3XZaJxTj19nEbT;MZ-tF*r_-+dtTg&r~q?O|14gGuSf>FMn= ze>cve2V0|-+x-h>8!;x4>nJ{FNb3bohom(AZq^`iNK?|ov~-Eu?F+LK>2R>G{GxNV zrYND*8s2X=Wls7XoXw82OSER|YuUJ%C_V~95|1fq0u^b*U>pX_Jy2J^$dLwx9JNe^ z>8;FmeRM*>2H(t*XqL`PUimPFczQ{12c~apYQ&t(wKHzvjW`;}u|@+_{&&yHRVVMG3Y{c?AyqD zs4e{+8E=Vv=d>AEqji;{l7iUNPpcDDZ)xTZ}Ndtcc4mmltAHon256JV3~ zac=v70w$C9T)~CI;e*gd1dHRJ7*j zjNLCm)3NA_N8w*z$2%tlvGdzSNG+iDee)Jzwe&0|P3wzm>1L7m{}mo*dH%taOh~gl zMyG}C);_o@G09+h-p(qT7#^cc_6Swr2nF!E z(>UOZ#duJ-twdqju6w=(9!|DE0VCV(FPi{Hd@w=N-eBpM&0Y-W)@*jH;1`#yrUi(c z%;gj;#pEccvL5h*{3YkUD;S~R-1DLe_62%qIw^JOod7k>0+@77W{;u3hW8AA9aS8` z%QWw`(DjyYmsXc0rrmcjOj*$SW{21HiR4AtOBo0yOz;90bzQ zc2C>>f+x#OxSgL*>uYvjH@Vq72F8Ph(X(fEl|^UE`)jFE%eIw8N8FgYj>0_KfIke> z;7h838OK`4MBJJ3PC}eO!~*)R#Iou7TC@45{_o%Zdg8n+K5C16PP53&+h%M#K;h>U zWKAET;X|2PYW}!#4-_d_30Cc?9jB={;ZErXxIPHMt>ck5$R9Mfc>`hA-|yEw27*hm z*7A|di0ax_iTZ}w1XES^owpENhlvK~H`||A?n+r0Oa=A&jz1bP98dDX1OLt`dL|wm z1I+By^eNiU4JSx?SdQiRq$PW^)%K}oPmyZCBWegL@Uy>@79rsKtU;OK8NZn*W+hDJ zhO%(w@rW=8uv3DO_+8Za^(Ib!r|8&okGfY@b5j6q{tX(6y*s`O$g!5{1#}P>$k4f=c6to8%kx zzRXV6X|$#!uA}mb91YxAPL%A((^$ zIkG09wzxX(LJT1j(nL#_-5rr!?`M0*yPEx>m2014-rCQf>!)H`;AR^ptewgL4Ao=B z`oYSPe*{Ot+tVrPSglEzd6ngy`tEPu>)9D>R`auC6@^cU92g3kwF;gktI1SmKumGV z*h49+iMxiHsI)nR`Hju7PR9|3!{aK+{^x{ERe=9~+hQkVzkyP_>&DpDw(!nowRYEQ zLC)wn%N@dh(6d@zLPxM16XyH+`?JUL_N&km)f)9ueq1k0GS6|EaApoyJB!!dysaEQ zYM-XZR->nsfXUEv)xW2eK#;(WAaz)K{N}7_ML*O)17P^bb}^n%OW&FR#$@C!)8)4x z#jrkO&t0TI8_{dgZ9xLTk`*l}Ex1|b<7G?KV}#C;yBYDq8vxGo>~CnTj!IEkps=6L z%(~TiveIIJL)imm6|`1Vm?%9N1@nLXIYEXxH+2`Gw4h}NBM2Q=^-;xg4+d`av(^<= z$?=FdY)q_lHv0&1>~|-tc_!)W zmBpvh6YkJ%DAT01B858N6~=J4(*U8aG;LMlc%}Sf`>g|Kzm`RIk`n&UziyavjsW3J zZ)e;6JfW-)n;8t>^M*_9ivFz>&$?X?z7NirmlIh@5X(|J%ov&Jf4?;Ai8ur2@juFeL@|3&$jL` zd3Jz{+2bSKCP<43pEoi(a+x^N;f{&*3&5-mvDfQR_aie58)>}_!_BY%i~e)n_c=Ox ze+4fm@BLxnMYJ}Gu^TGemx2KmT#cbvco7g8BPU(!+8Gw-`kmy-NANtQ0GMj%5;60F zPp>1J?l#a%Wu1B?dSB@_H8JE-5Bg?4KQ|v&Y+87BJpsXLaMsT?YB`aqXNLBZAD|LSk4{biT?RU_#V1-j~*H#X%0b(il5{?C93T1w;! zmDH7pZboisg{yV_R=;RV>nlvhpMy0O;dq_acykH@`X3F;TYVMsEV~g zgrwKYS)6wRN=B1X z7S+St+`XwxZq_~Al;hixZ|Qs9>(2W|oli~cjaK&gR(>zn*dtMifo$(#%Fr%A=)r?n ze-8e%V2x%M?{BSdk+DF%HSX~Uc(8@5Kv2k&`2`;Y%#n7|GwgJ`ThV3HA1#uS_C(~i3cGo)z2 zk%fc(eC7eWZ9TLgPX}76bj)tg=oRKk$Bg)}#Pr1(izQvn)5SG;<5n)Saf#aT@(KWh zSV+jGk3V1fhERjg(sxy=hp61W2C|S{wDnh~O5AP1Pj$C2(P3ryIU2wSkAe#3KI3q` zvG``B}W^dQon>47Hw1FVFOl#*uzjO3u{8x^! z=2i-ISl#pTDiEdFZBD+Zw};s7wBrn%rd9_X#X=1HTVpbyp47_@B0Boce+d-eSR7b) zfU^ZsH?fB4%ho#@jqsXSb5=fOBSf3n$8>D$s4QWuo~=nXyNcGh3e3n|XDCTPw3m@V zdv96luwr7Z>*ioiyrzOmh4ga|?U>Hmo=|K&S9-nKAv=#pgMqLp6k(=~iszm>kVE?J z@*yw|6lQRwB358K7!r3q?AJ{03F|jFETNE3x?Qv;%C1c!IhL0$BK22L#LN&hpt@%% zuSjae(fGBW{)QZ&p-_g_c`#EC&q!Q@?#M6rQ-;DXj7G{J{Yra|<015H@~^&1I%-{K zdp9}?zXQeIZ~NuABk-cEmcr4)s61xnwQ-Da&lTYL9w?Z?Gj_LIn;u<%DzhhOdHL*9 z6yaAajQo1bI}V)LX5xqz9>8ofqB>P%V>kX`u6=FZ$0!@O%RuNynNMU=@v~>fo)45T zcwCr@*a-i>{EodspQ=6G>aAC6=MOn=;0^tN{1b%tqE-Yzvaw1ZXNQSISSY3a!2u9* z|E&PPFS*l}PNiBld>Z@|_UMzN9vi%4uTE=BQA<@Ii{-OmE|CGCx)9P>9+odNp1~e8 z%w(CPrJCPr+4N1S&FLTaeJ`e=fb2y78|PJ{CsJYSj#n$n;6=5kUcE>1<0V1C)e~`H z#T*I{gfjE^e6%{ft-J%U+qe^YpUyhp%9|%2Z;w$5KP0P3Wp4&i6;2H1DNA%Z-?zNq ztkVxtc0ISE3T|q42)}>Tr0I4z->s!G7d)zbDu2z2AOyN^`)YKIR12u*P`EoEmg7D~ zJt7Kb!qHZ@8jCZ$PusZd-UN>kT57#Nox-ZcgsrV6z{S!D3eem4W$gX0B0l^351hNl zV}7soYS;4y>~+txz{gQb&)6&iEaHVgU;M@&&sUqLpFdFtYv0$-Z>4Gp z71Ht*6uJ&({HF__wGRui-S(<@^v27qa~}UI1dh)8u!+O2MNw84b6gf$L z)g9Lw4eablN+^4Lal2LB&z*Amcf9EM!fz<}-J#-tt*iLMCJ3g&g{xN!YfuuvmrtUj z0ia%IG;Lh|;F-Qpggcbq&!{gGOa61a|AeEz6EX+gb^;;KD%OU7<5z5!WP8y}W^p2# zPo`%31@M?1H;zA=pQSek21A_Lz$QI#irquG)nmMoIdp#Zv^+L>9q0IW|8zg!f}f1e zXdR<){9BYF?()Zs?OIJkhaEo3NFBkxL92gqe5_AH&y79vy+p8xQpyY*^JZ2AvG3aN zo45AVSvp7EEI)T#EX$bhH5jo`Cn<^{VO&ZF22jl)ILq=0ko!A!rC$qoLixWSOBBA<^8nKF_F{Qk`Hi#jt|FSp zI*scso{QJxoE3Y$7AV;b50g(-Gpp>%BKb>YjrjC!lkCKEP&bw&K0xkrNGs%srQ zS~5*F2M5ePpUxt5&tw}o{df~^PVc?Rq z$YhdAy|V_z-=@MB3X0l@njhuF=v~7Ybvv2AWu?Y7FVa1g?z`XmJ8_u1)9RT|7YWrw zs&Mi#nWO{Tm*d3qPHgkrc1pcH-r`|_e&>qnv++EiG|Txxb55DOwm$*+22K?CWJ?kn zL`|h=NUm4h0NWugEvuO@t~c|Z2VjJy)GcEg_~hlBr3<^%(_y7^-0i*yS~$n*N`UP5%<$5I`x0(64*V(lS=F zQ?uW_Wdr4^>skL&9d`W`Jz3NuFS;Iq?v9_8L$=a`JNGZ#z1^bl(b0 z5|0V0SB%m-TT28?4>&wf=h_JX&5sEo92ks1ZPL+W4a(yXCusc!{;aN6R2o)m`TXSA zB;1<{>$q;0aiAiHu;KM_fb23d)$hnha=?)0VtCtPAFc*ow{3`dQs7`0|E()5DCqGG z+U1$3i(1A(1A#~Y=5jQ-Z0|M|QywejI}xN&3qU!P=2$0Or<(jOn>64J&?7GR>C+}f zC?+%ZPa_97JOvBTt}w)mF88Qo`RaLFt6;KTl;#e8Iaq6e&Aampy{f_%a42 znr;@b4=ld$#UX&IOUZ152BW9}y=hU@)1^(%{O!P4f?FDuZT%R<8+X3(M!~pPN<{ls z14xql_zra+fItrkSeVST!O(7@ZSBJVmv_egXWh1ooewoBB8X*L+h_>ADK2dLfBpXETer-4;u(T`4Q?! z@JxV4w>X+iqw_~^0hE-mdl>ZEPc~Fn{?LeE-><2{J%VN&jBwIiFCyB;f2iHlvP&q7 z+rZHDEa52)QNx;b-T+F-C+_4K+Ng>yeBf8%KR(}v?%Qh$+7kPpyGz!3Lg<&!^OU}* zg4sj&V`r){sY;ux@3?ns&Mcj)sIyn7JvpL}dPcs_G}gLwRG$H8Y^d+wXMz1Qem{|3 zqdpHtc*fi!pr`qt6_mbWfCxN@H&?i#aDLeagGx-ebszB#fmYro^(6=4oLjz3i`ju9 z=e__L$*)ZZR1h_FDlOzUo1)xW>6mkYr`-HY)#+i6U7Je#Fka@=_a#eDP1UEdDC-!c zx4QP&>lLP--VYIv`(JI&?3>-*)?D){JLe_K(p)Rc{|w!0ESs;-nGSF-vpCXQ$vNra z_&{L%;25n?0mVd4&<@OOh*Mt3>X)TsCDBSOF%3b5%L-8Ts(iS;BNTaQofk(#npGTR zuN{sYfj=mZfYi* zQ%$x#VX|!-lWo`Z&$cyLlWp7e-k!J5eW-KqJ!hZ2ers*ePWsJ1!=(!E&FAD!?aZP| zZ;jV|0X?LBJv199+Q(@#GN?2ibPHup z_U!ZiobA1?@Wp%d0g7$zvP22n{M)=DwOaetNcm*#FD65V$~z--ht1z2sD4t6QOGbc zl^F-d!g%sJ&WnYY&oMqw^kM|!!^0L~mm9ECFbO@tbq$XIL3KKf#iN0}ZG`bis_7sv z;%522vy)!_K>gA99b3yfSML02!sji&pMNW~SLoZiW$l>L1CWybr*mQ@Qkj5am}wYG zmiH2h^W}nqRH0cV3n(uZxux-ZN|A@@F32hF@?W^HNJ20Ell*)s(He#mj6(^(+WJQS ziL6c-_XPS1=I=T#i)_8MF4=3glM~)B0w7#3dXZ?BaZX5Co>$iUa4qApt>ELz1sGj~ zrH26Z-cyZl-c#=Qg5Ik@To$;I>g!u!lp)yJE5TC;iIz=o6Wo++Oa(?OX4vpZi~Uv z;!K!Prba?S=ZDQS=gAzurGLZ(Q;vt92=X_T0wcD7DKCM~=dDa^1B%rCD#)r^ks2=T zPPf@Tqp=+i<=fE#4sWi}D7q@yU=dCn@FrCJ*X!>^hZXrzN1+G`Va1Nmhf^=(ysHQS z4Dkrc&C==YU$#T8Wp_KXC=eur8H&95vBtTtr8$9ifs%kRP0~w~_-0ivid5A3?68WK zO+D60>$>-n%&TpvaNK_QIffiRxJdB8wVZLFgUqgSmF8sml_4qg?Q82P@w@urN8bJT z#74mkQlP^nAw7>E;_1hcRJu^Hgt#^+xaZ%unE5Z)Kn#n>Ohl?th zjml$aYM#*k4Gr1CT^A-@j&5ZA>nwbihjfxU(sx5F|EZxJ+o;@JC*7V`XHF=)+jh7v zohEk5Rxr{%Ixq2XS=J)+uLswe|9511`kQ)(vOQ+uvs!xI>D4_&qUiJ&LcJEa4+(Dx zi(Amw?{4jS;qjRUx{oK0g28LdoV+kmaCxatW%*X3dhK?AI>u5msaepvBVhB_wiP4y zf8H^uIwiQRO6ix#kR5n!4>x0+z(Clju~YR2xCD|4$`Nc{9P(sxq$6HjBisG+xzZ1v= z*ZLW=k~!UIRyEq_z|vZlI6Q{ye&-6DbeYU{U2oKP1x5eavU@TNf^}tv3RaCUgMYhx zeWOff_&ahe8;7GqX24U)j@cXd4s>5#5eezi$BHM3SMbR@@ssCCsmB-gvl%LG59 z|Fw89XPJ$g3z0G&6)pdpN=aNkf|yX%OKn}xuyyl^tAK$_D2-`ols>P7jX+8EVU>X_ zUDJ45%|vxlkw!)KFk&CajrykrsuRry`39ZHfD*R`W~8DITFv#(9~>mVe%2VR0Feq5 zAa}N#Hlt-!xD5k74U4_M8c*TAkUmdJI$s8X77skhSAD@fwPu7Pwa&^md_9k^`j6o9 zP)8%7XREDq(uTsXOPa4wnnIcOIo@M`c2sfsJ#jODl7qIQ#oD^E{mwsIY<-!1)BMqH zpV__-4!9FDbUyB-=Q!-k;+5^-!#M>(z3pBDw?4=PU5`v}5^l#(Svyr_IZTU0n>>2gk>FYSY-L)!1!4R#u1pC%i%&GD{PFetJtv#MsxH@C*8N7|we6w@ z(IDarJ1j=$%Wm~kA6$?^;<4fjsljRe{B-fJ_Uk*IrC;AEvlle!-;A4EqD6L3Cs3X= z@BwLa>SFO%b|LRyl^;&PblUyQ^!Wuo=XIi~)D2a684f|!eizyS1HX@9iljM25a-6} zZ>}tp4P2%u6*)I+4@PQEnVZ#vM9Enhg*O2=bS8!erwUw;=75+qzhIx~zEt{+=g1wF z)w6uYU?K8>Zcr2;FMNSG`SPdc^NwfpOqV$owK;1i;WGd)08)jC7cTT3shlX6F|fQY zKs@JvGgk6JIvy9@u-ozVMi8A*lKT$dLjER$YCoChr*4R&5 z*yqWzr48-2r?NL!)0ew%1QS?;-LHC(WVj9BEqQeZ;RvpKdu_(Y2n-kGcL;6f@APHG znNI=Q6{?5Wbp!<+wHx0<7bGBbYf*HU%dxF1s!g_E?xioaAC;Bk)w#OxMCZ$9KH2O# zR(y|nzlneFn7xe=cpR3~&pwbd*rH1BikIULdN4sx9u6@|p-Tp|5#yI3?s6bXZap`E zu90_@S&9kr`Nfq)9W{H_L{O(WHRE&f9`(`eG9dMdw%#xPBBAj|=2$_K<$g3$&u6aG z@j6jISnm{=B^VyI2jp?P1xB4|3*u){w{lr~7P)CfD`TMJYv5L@G`Z$+-X6I=2+$na z>(x725KeJvZY@cY>%3n)0!n1G<+;q<0pU9sxL{)?={Rf9L`cLF&n)1iU6q&rz|!@8 zOe~46jLm(&TejKU4B3u<0S@WU^yi`x9b*|qcc!eBtrvNwvW;%uvc+_{BgQRIYdt3!xlzdiJLo)nVXE&UB;;6Jw4S@n+Rf^h2Zwr;?KxJ|xxSTXaX zb4V2Ey6Ys$DH2(*d>COf)?yWcy95GH?GY>YKro+&JA^ya%Ep%`urR{S-{A?@Rpy7%f}7f3OcvodE`@ z=LC_J3?|eIOpc}6Hk?L7`t9mZJMnVn_uNzD*E%k%6*yB^?l+;89!-qdS zETOGno$aecOKt&(O#yKiRp2Gm88r$!Y%ItOtH?C|y!|D7)L=%2!(zzai{)nwpEn$! zddLn2e<%Tm1RPzP;XAvzWt` zyZq{|%pb#8Rv{+JNAAv#=I2ggS_O&}ZFgt5q z@8EvPa2WR!3V<~u5;lk-IRgiJSqOx7edtSkoYNtRNJnK~`>o;ZR#!3Pcw==%ik*Im zSZVkKAaC5v$jMdqD7B1@GPOh1QV=QRicb(<{4W*(RPW?OBNN# z$-1BP@+$y5o6{DI*Y^E&DXQ{?9;FnSPnP#v2fqy7Oq7mcR1?Z~g9-j?hDdFL&o^g8 z6E6JEH%fes+-FVO47|1J10$qzyQN{Hl}*9|Y9uT$RI-0`yDK8!6a6-T#J7rVdWr_? z)t26UrQ)Lta7b7&V`jzVF#odbbgKr9gpl}ptwf-~_lU^pr@9tj{;AmWCiaa?nECzR z&(SZNPsf!Z3iK5Pt7RRuhUBz{hQ)8M$-yq`ZsMZ_IeWQBu;_q(sxqQA_r>b(XJgGq zs9N+wq%q7G9_vn>)=mpttVf6mfw_90VYaIyO;~Xwg|8T#mfc4%oCon6*yp~BJ@sUhan_X$Iu)H^}c;6SMxNL zZ}x0_#Y(OKi34x=B~>>c;50mrxCP8-X)a*vORTj{2baI5#E?EbSuW~#Ks+kd2{w7L zuU%+Qo1FO1Y-Cx1iDIi>qBJv+ls(z@cOMcdxA=!r0I5`xTFftYPPs-L+3G0WL&KLv zWmOf2V0jLV0rDjDgy#*e{%COkojda3Xxo6TO-47;U;Os3kQ!|#kze*zl_GT?duQ4l zF!f2y=r9d@vQ+Z69;z|dnRZ3TbmID^gomj`7V+=VP8<1ck0$}DhIBXt^QRK(j~Ew> zmvQ-J;nP#@QNQy0&q9lRT$!sZbj9QDqU_m@;$vcvj55E9xQy}~jm)yc6dBdzbGOKE z@8(5Mo%nLT08xAMg`e!L7)ZhVSm)iZhN*9qzSNZoL=F=BXbY%CW9R$amTzy~`#iKe zm+Mu@Mq<0qRo=_Ay*&{;;V~)41jNvH%D=CkkNZyuyc4QweR(s!2bh|CIaSGv%RwbY zd}z@SGhna6vV!9S(Z6^Um7mgXz3{I(D~HfA!a_4-&}qu-==czNNpBVr*yC zSy72N6bQwhTxJYM#u-VG{W5!AGs;-H4m%|#UE{`%lxg(UY&yTn%Xl-r2e?vj@SAm; z|DpVkL9sEPk+cdfy;9(OM*X#q)J^j_9cQHK>?8g#urz)xZp;@T9S@%#TGt0}m8=qI z4Qsv`idi(8H6;rUUu};t-S{YS`E{Xw5{t%#2VlD(0AvIkZlwDx7GantlX4^mrW^Ig zTqWD{soELfEjs7;i!+_wsS2eSo4*UVthxOfs%)`0hin9cCw}{AYyd7p+&wgSuoJ3m zu8g#Eup8mub;Zq(Ch3Q2PFqvR3+un}VQCEMj4kJCe|A-yeNSfji?08gwC3f$zjN@9 zjD72Du3XKsMCDT8s3adC$E>GeJ|Wn&T?X?X9_Iw0Ok3Y>BffkYA>9Yy6Dl0b7RSRs zPQM4~uly* zKePByR^XJ?>cSov7Gdf=%4o>7IasuYYhcrUt7?8y+39wn&w2LGQ0aby2Gv``?wvf% z;%^pKN)oos}f|pT;wVD`q`HIbDw)2&ixpl+1w+e#r2oF#tVtvg3nG{@zX+y zLTYy+C94;>BZ44FjC=><@qAgwqxp7^qsquEP}`B@!?9lFl(h;;;^i9f#L8F87!tn4 zyVKE7kQrw*D)y%w-IQpLWV95>PAERSlDy?ar6%|#`Ew6T;GGZ>&XEO`0()Zf+6Thd z?p_&L51h9AO`Sh^izA2TLyx9o#fej|RGlmq!@s34d%kEWHyZM#4glLrazjXdG&e%H z@R$IJ&&jt}&|WrzPbqE{Ed|9~14m`XjpHAM2~6j8D-KSMvg35?nlMIDwoVnd>H439 z#W{Ob67MONZC?D833;IlKWz<`Hl#kf$Q!V-6rqsD z1`!0S`NJbxcoszMn|i0)1!$IX%W=Pppzw}An-U_uF;>KTaJ*iGLYi@b&-RJ(1tpXg-NBFQ3~Ctu9rdHwLZ8I1c4-D_3W zZ2OHIxuFXyemuKoogo5>OEZHZE`b5Fkxl5X*=Yl3GO|j>-$F3u4w|zHa~7+9j#UE@ zSrP188+YfV{E8{0+blPE3sM11<7np}r0FZ`X@kxj^8Z&RcJdXr`lO*@I8gMJ+&eO-Aru6*mR%splnnGVsW~L??%7 zN`}z?reJ%2X_cu z&=pX@2>aLOM? zzCDukm3?1n(-v1SW&o2Hi5%Z;f;az7WynTByqtdntQPgJ^!(k%`va88xiIkf;Ha!M z-JN|uFz@T{IH(+1UUzt}8D9;EOdYD63NgQc3EVl%4Tp4o0Yzm;VW&8P9ne{9n-Q2x z^W%2RA$Rfp0e@gajAq&sxx5{N)qjY+u##&)DuM#PsFeOV9Gp3Sp;9uOitZJNDfWm&11hYqE-pMdgzHR0kn&?E066+3`Z^L9H7tz4y?g%dsmvT|IhM=5IN(r3Y0ueI4zlQ&eYm*;Wz2W=0e|blQna>TrN5`I% zjC`-7U;4!NO`C1GFzXqd{-3%UJ@&H1515n*=8Y63Nj4Ex&L+mFW>!nL(=Fi&i zmJrhjI_Py8P%@9COJ!x4<>D)Ce!&sHl-h<<_cwN!*2mXdE{;dha}xV{{HeLzFuIZ% zEH=&c&7RTgFrrNqo9UUx6mn7-D zBr)xO!m5uRW7HoOf(2lm5{#zJEc~^2ff>{p1po1ZTzB_m^VkP?xT6nd3K-HGz-5^x zQqFZEu@NF<{;%*s!I7{%l`5EYx@Z>8oFy&~qp$V646=VvnxwU~o^E&u<@dWPi&c8t z7x?qKYQ{ko8cjqb3`P z!%Mc@V0+xO<@0tnfE$vM@h`H^Ho#OJ#UV-``9hhxg`K*YDJB@kxF#DzwjnGwDCiME zluO(W7bgulX}7FoOHA;X>Arn(MR)%dVw44)=TH%aItOfQFVL)F#qviQULe~1wO9e+05=)c7l6a=!*2CMYY zv!*HjhD7HT&xYjL+tb1JcmDA7WiKgu@Z@Zax7G^2%!LPd20xy!Ad!4-T(#oU8QR4? z9kAVfUG0p$15&LUqc6(|jWi_d)mYcXEiT6u4^eXm;Re!;@68>EOU~GeuxYC4HP`O64pYq~1ln6N3)QkENnDvEGd-~LZ%_wFcV-$Q zQ5PH8$~NFi;ko(i1)Q9zXAzXP-GegTGG+}85dK-DP`Q>@Uk_P^WNW6}D-{jnNDdCJ z$^Z?V9Zq2Nwqg}ak{4ROkVAJz5K~yO0Q3K)w?-Ofo zU5^UNs4ruM_kn`Kz|Rl3K$P73ydTx{FIbogr3ljzIi%AC2sEPd+%%!kqJp&K>hQTD z5PoQi@C7bEYTh#!?Q3n;(^J=1&(FL&TkpsAYg%h(oSmIb*3$3OyAPM$Ul?MDAawDIYej;5s~>-b7_CsJ}vyoYgYuTHMTik>Li{KWPp_*o;@CBN{3 zGQV9G_`^|d3Pm(z3~iIEu<3AF8Set)#dG1v@1x*S6WBqi-FSRdJ8wy*VDkwY0g#6_ zrM(xcKdIwqPn{oZGvCaN#F!ft;z!=gA;}v}llhg}8~?0?F411Kh-ls`xmbSfPozay zW&M*pADJwIOtECcgwM?RM-~AK+7>37&`)?5L_>Os(B|+Yvfmq$C@s3XKaJJ0#Ok{t zc}Ak6svfKoh*9Zj{3EOoFT+%@U03o1vZT!!A~r;_WL_<5y&j?I+@bdjuY!%6Cj8)K zFlU-j^h6vBjB=p9$Axs3MJCP*IfPq-PGRtq2z)I*_rAp+hXPy&cZ|B998vxSla1@b)HC@Nh4J z-4KL;bOjK}P8p&L z{E=>!ATg_0eBW0Zno5lF#GC?J=zzwyLNY&p&VX>5@R0#Iw@SdN%l!7mmn{u3|(NPoSBnuo1_x(qt zcA7$7|Gk}1I8BVBQd%q6Ih>7|1xb$i58BvAPCH_KH%ia_^Aa?qgR*4nN-<0Q@g&B2 z=CGF1EThq^m;|{pe>2W^fLv*);rvPA>cgZY2UdxxgW?fLAhNTlf4}ogN}qnh&669#{0KpeWx0Zj(NQ^N})Rz@oj?^Nhq(xHLw8&`G@9W z2{P)8<;B-&lzejjj-#aVIn=ZozcNwX*ER(Fg(@1FDz7?<&lJ%;TS}WkWe{w-Mnngn z^275eHG{t@#6D)S3$%vGQ zG9JO?O}YgKE*rYXL7Dzu96~hPc_nJR*=7j1U=f z^aTCicaiIe9Xn_P^|F%WH4&ZcA6I~dj*|$RAvZ#Tz0$<%VE2G2v+}!-dQMRUBio3O z{F`|61NcjvGfl@nIYwV1Y-{r@ZMdyVsVC+TuFQdYU>UPrKo1+QbDOdz=)ucw^PCl; zYFml zrnyPe)4us9?XpZy6&%de>t`f4+=Z^i+fCpx=-N8fS0Hl~46Xk5Q!!bYI|#FBRPL7A zA@URZTRj$b^*(Kpz%s{fD3|O`VT7x}muJ$+njHvq-^%6{7sLt3?foe{E&Q)fU-FdY zS$&1&HNPZxRyC!n<^+w#D)Ic(p7ts{ZI^QR-5k^x|CrmiGZb5ND%P(c;Z%Gj(vK?b z?MdE9Pt2%$Mtm3Ws&L+4NR_h{D%sq{ti(d^i0FeV{QNz#9x7L(sYQ8Ro)yTAMt12& z`<*4{!0_?*J3&x-*(>5xml_JF!yv{!(Mq7?TO4#8168vqfN1Eo`Us2 zAfD}B6O~KM{n~u&r^x@P+{3IS44_ z$MUK^tcoE=sL!vcQR_YvS$qM#j9MMqYd*+%>!o6y3jjo>d?UjY(|M>-`zzhy5XT(# zrTtE_b78B5{`BUw0z9|6T{pqIQsK_JwgU1?CsD*ug+K{!1F3fWE>>f{ z$Ts`;8I~#{vyp!_siMSa9-1(VM><2zK`fKz2~XDuOK)hJDvD)snWE(wH-{>Bi6JGV zUiWSMnz0m&NI%45;KM9g)7Z<;I8#-V5_=KvrlxS zsJl0|NC}m6jwk-|Waekj4u$jZ!u?J7mJ8n@I%0CE;B_Fsd3M(LrIP}W1V}Gx^DJQy zmGB}n@Iv5H)R$+L#xO@HWpZG0xa%vM_ zVmzDPa;S0V`uxe+>(P;|g$<0_dTAf4Ef^jni)HYV=R_W%*7A`#h1V>Oi-g^i6N!)$ zjhoG}OnPSw4lB${zOpv%LO5Q%)&%))I>$uDL<&FAfOSjhLK8)Ltxj@>7Fup1j zC1d3R_QrD)^$nbGTM85X*~)>NmeFoOTv=9MhBub~yw`1SEfS9Y9}`2cQ7)2FBIyB?ULYgcanit_`QWsNUIX6tezV-G@|K0`I)94yU=TN z14JuRLnK}(^3NQ3@4vlEjFh@8he1RXeDl{p8x0Wa3@7G($gvL%jY6`AN@euN&q{ zxjeADvn}W<>?XGbLK5fo0T#CFgywPr=*)FEikx<7w;M`F3c}!Y}LfHp{m&D=2#dQMsul%B;XqvcaU+6(*^f_!ao`NzfNc0cP<+d&DMCIUhjYz4PgzL^&MoBj7sY{X45#o-TY99$<>F0767 z9DJTLBeTUGxgAE?HBAT92$s3|ig3owc2_8(l-_(lD5#X-H7qpI(t^s_8rZD0e;MmN zv+g*%YvUdg0i|jnckmIr-2!Z%)81YjR=%$Tp+I8vX$WF(;kMMm?z(Jzns|Of+8rMw zv2CD=v@Q*0^y`_Y@j{+0KGnj5gxgja#LTC_=+My-Fg+#a*sH)ze6v=vKFNkq3CO|C z>zN)~D~BIR}nLJPiZ5O7Y^(WYBSY9Gv>labLg(I3^gZ<8jB1}>iY}?`A=T$TJM5_(x3yTLoot4wOGHqLO;)=O}0%m^5a`}dy(4)`Lccv$IosI}GWiT7A*A)cYnQtqTopYfcyAgdZHM0sC# zP}(t{dV1m=x??uaNDm~99phAe?)p5}p^)fKgStj<_MDDL*%A6<5-AS>w0uCZ84N;q z%sHR!qBW)UVRVrNLk*)YBehCqoZAP5*4eIr8e=R%rRGfoGy@|l4ONVCM?wP`;IQ&T z^UL$QGSTlsLWxjs;%gTRSm z4(2GxuY-uVYjsI9%QeTJQ=1!mIVvJuYSdfz<)ot${x}0F*Ncqa0^T1-Zx9bUu)8*2 z*|S4Kbv&D<`@apL_w3W<4kib+++*QZ&*ljyi-0rl2s+1CJEb%jI@u#U(n*0Nvr_vF zs<}%q9+WdT%qAx&1^p*0F-oS%j*tnjZ9Y5~cwq?ZCN5E;!ry(HRz3+3a$M6J9k2L) zGhB-O!hF%?>$MZjTaY==q@>dqScN~M{YhDg7UVx0{TX75aOSntLd*Vc_T5AUlRS?X ziOu!~8Ac~6rqbXORIX~tkCR>)tr7bPWYLQAHFl~mf1cDR^KJxqPW`*h1Fz88o-D|O zl@Svkj%gkW><(q%Xi~f7wXWi&A`G7uqQ54o*RT`|$$TQW z7uzLPuy<+GP!n0;i$*giO#YL+y5AxKqQ7xU*IvqXQ;Fsc9vB?%orP*Y=K_04%aRO+ z%OIS1%mrCMXwztHLf941MatdMZ!-%0$iYVjeH&ayT~J?^Y?Tk9T=>xlPSzr!*D1s& zhG`o!J!t>xUm0a%?L!VH?6f(MbLRrWeV^6-k&9e~ggta=f-f{Y)Wb$AVvN?c8Vc_( zU)~hVA@mPM0UbS}JxF(Nu!GTR6`|iFfq)$*LVhWMOcg7tmJ@!4jZaph3}L0>b0P{q zghMCs#+78ER!9yl)5Ie3g0qZmm~vuZ{z}O?WU+Cp(viTj+zy;Yh|T#eRzzCGb6W>$ z!BRzbWsrU0ez^fBKTl*O`;xbvH&{<1Ryh2`E^3Nv=}SvbbBP~Q=&?3*F2WFdsQ*R~ zfr+toMiGI0le|kZ&54pTJWwJC6A2EdvpXk?J9RQ{4zY3cIkgKGWIr~(m$(Yo{UEci zsBr4D3v_;LV2JE(4Q9lZ-3Jp)7BAmSOYFmo!0mM96_ugca<#=3ItbN=&Xr1nw}P|l z9qd=gUngBKS+VtvUm87f~-{wC-F*z5D znzf2(?o2Lf^YE>Im34>s*xG`-F(hYKcqlvVG%;i`%twnr5@z~mo4id(g-xzlu}q{} zyFK=r=R>h1bh_3}TQlUF52Y@G?GxCr6NDxYm2LQb(hvb5PuQ3<5@;>&}*i zsB#yVwQSR16ybe!D}wF*6SHh!!B#Bro*$9CScxCt$1GnoO-DoO?QHkaAma!blz-hd zACg3;AcrG}2VOoYc}=qyHYINz>w1)8#vDz?1$pGb;ZotWaH*RG8gi?V3d)Tmgu*p& zdYjzc#oQ8Q%Q*jXc=8yY1*)c=1{jbtQMsWOM|KmXL!u^IkRH}={<#`EzEI))u0WOV zD`X4GYhhT;A^L19lWW(%zaI|T8TH2M&m|te(oJx ze;61H_p8bR&>a#Xo zjHa(U)wmqy#yVD3fW=g^My%$S(eTo}0Oci0NgT~Tkixc?TY8__z- zE8e|gt)cfwuVh~>6?Q^Ylv>E^B2!sdcAKxqe+a= zLL~{nX!Plq_M7QZc|OiB2|uGj!QoHXewPGqM6&63j31Vi$-E75^Kfvi1#wZo!{7sD zQC>_avH$`H`)!Nms5IE#UWRL&LKq-M&YGntr)~*56~}sV1YPK#pe9!6ZBP`OS==n@qK zz!;uw+C)FW&~nyid&NXVnD=U-fP(r5q!Soprg4HBXb=i_M@R~#>(93-h^3WmNVjS~ zE2El|3VHniq2}K5!{kCvr`peAz@&*2dtrVg*QBsH6g96|RJH?3wXDC>f)2+$U{ajf z7%2y_?lVbyg5RzEvf+HanHjtFeS01LuIKaW{eCF2Dv!HlQ|Nf z4dEy@kzTDE5PbEYPY2VFnLIbIFDh)j5Ul}9$l-N}BBt;Bn)qNU--B#rxH#h{ermiN z7ao98DKr(2?sdMuR&oj4&MG0^JGKGfIO9ja2K2o}W$QTM`_n(YO~3^nED^s})${U+ zvF$>9uML<3{nhm%=i&9l2!zUaGYWWNcrdq~?ixFZI%A^79`8GSWDng0F2m%ySSDU5 zT(s(sC?0m1e9Z92VSS#pa9M$P4WAeIy)__&4IKB?@>iA{_5lO{8NI^*&cXUKy6Z>{ z@8`QySOS|iyBDGpGmz8b-O=2#Cr+Bc%jSL6ntK4LMSHgAl?3Pe%k`MTOraEx!^`Tq z_pfNcYUzg|%Sn6yE(FEYaT6!uvvrLTHL9v*g}1PI-rZ!kE%@KgfX&b+KOhZO*N#Lf zrF7La+L;NnACuOWR~H6G34WU3x^nZ8_ePa&`7^`YyLV#Dbt^Z7n0Wz5&%PSI^XDUi zgO@#T1Mk%kg~5W33)=!y#|61IPE4Y%+b)(vI{;tyCU?FVb3XhIkZGbo5r81}*@E9d zI4`5G4D5~JY?EhXYJd1dcu^{sI=ZmchOF(PZ#+yTl`j-byhB8;8}M#N#CcZN1Sy5f*M^P6qTs-e zVZ;bnM{7E}x-79icyVVD#Lq*f_eWrNQyC7XIqG&&o(zn}%snJ=vXDxd6hL4w5AHeTSe&*qu$WCeOyxy;K3<57`S13A#!#%(U z_oD0ZK%^nhXWFx8g0*%0>lo}$Z&v7s{Z7m&fM#16tZ^~r>Comh!nCT6v>8n4d)E{>0Jd7Em3vXtpt4waUF*{l@5iOa8ER!PH~& z${ygp_srzIPMGZ3hMQEOfuf_FXLz_YN$LG|x>*tx<9|1lW{RxMaj2Ps@57WvoaxaM zmhOoYe2YIG?54j2`S_SD?unE>0_S_;_1GiUvM$P( zvHV(+phbF<^y_@Fdhd3gGoQh38J;z$)39FxuJeTF+0FvmJa0=6r@)Q(6?x@yoM`VQ zQM9s0+~Vh}OJ(fdQ>5K5L9Hrw$vxROp7YMC(U#V#H>xjLP|2Nd7zb;m;%5yDIqe%& z=pjNLdrU0vKchRdFFkNq48OkUUtj-qYLp$$fXafb-|X`y?U5I$$H8s`OTSy3&A30v zNO)dk$})}?Si0)rL|sL=l)qGqUmX3_eN|5{O-^tRAD`Lubo(}PzlmeBiX`ywDr9o{ z`@xUZ>qp2v-TKkz?Rt{*?RKT}pnV)^Up5PjRgwMR@r%dJ?2vZY^KB#_L*A_EleV?- zs#7p;UZ)kGn4om$7Cg=HH2jJA(u}FBO;+O!yF~kk;i^|#vwEXvb?MdOdx!pRosc6q z+GC=XUfV}QP_0$pa5o#;K2btZo3*6Rc0R2Y{;fH5ZjkBQh-Q!^@tl{ynsrBG5xead z6iWYkHZn~oZsih-?RGfI?G%PcBkhkK`7E9@PPnlS0Yi)fK7^Y1kA83(FLP!h-{i#8 zw(rq5UGYo^yZ6G+@}8dI@FFm3o{D#R7AXAWBYrhTT_Z?m{adc&ay_#T6GXy44oL%M zqp#P1z~o-*4Urv^ar4r|ji)3u9jm>VqlFWGNJ6_sZ=J)97bhCJiU4817Fu?tYZXt=6qnqcmE&sDE%$34n@L*Meh%Xjs+{3l1J|(ouVB%9ceoA}uWx5AogsRMiBUgm z^g<19%+*?~v#(#zdtExOGke;B#`5ld#7`f7fs`0EAEehAtaj_xS7#t2ii!6j=WW*m zO5pu*0mPFC^`C&UohP3@i^^G7{^8I@wd8a zjC~nQ_9V^1+kCv^p`R(G1$e3%E(JwRs;} zVGR~*jGj{f_ZPZ)l|H!V@$x$JLT?CaKot8@$;NvnaH0|J-xVQINxPx|&?-mQ7aK$G zPB=uIFM-S6xAYEP$6p%LRCYe1VHlWs>urt5j=Sa%$As3}_}vIX>^()@--m z6FZayUGGnXV2vj4cb~T%%d%j*+AOg;yatfGfSom6kMlyhV^LLQ$yILLM(Djj-2L-H zwP!qT&|5VbP%JLqz5)Vjy8MF>4K{nA`CEMmqo-em^lO6{+It-%Y zsbu^`faP{>%~KU?h)dDcXmTO?^QRuZxc5}YUtZAv$-v$=b^Liu2>UM3{Zv0gv2;R( zt)OGKOQ4pzJ^$JmJj2fOYa`1m-{n=Ix@ ztEW)THfgnVArqGfTbo!fOPoGrQ;`}I`HSBbX8ttkZ$%L3kMWV3GDt6=1=T-aoCH!h z_Lz#gwe6r`v&M=kAS)9iRkU*N>2hgq?IHvwrg+J2J0`@GNRSGB2|}_MHp-fkDA%d3 zaf7knfY#<3tKzrEX6X6yW%JE%#{L@AY+{TNZfLquWn6Qlb>-@aX$9Lukb#M4&lqF9Tz`;S{962^dgI=NN|kp z^WSroV74a~f^gCh8Joa>h)UjnfUj`OsaO`7%8H+#*rso@u|^I^`Iw4LS=$e=&`-rEG?Sc<^E z1e?OL@1KYJ)V>Up(gXDwxo7X{P{mcJ$ypko?Kvz_(jL`_&{~OoXi+dfThB z1C_D$q(-=d|NW6EWgCcsfudLY6Bsc=A`T=eLISC)ZV!N?*c^lkxGPflJlI#z_LcIZ zRzI|7YC@m3=5eIf8|N8rd#is%jU^s?i$>*`?Ll`E)LC$yl2M1ZO^)Ri4gTlZ>6VEF zjU~EYeZaMWc-6h9T{Ycr#vXm>!}DfKxB`g9&6mMOh=EK-XO|C`{v{>COS8 zo6#G!?RWkD{)KbzJ@=gV^E|IdulMx$G{U8|5$gTJYZ?Iq1Mz|?rwvula+u$D*nUDR z2l#q!q>IMDgkWp$*loXHU=u6pdBOs5X$*RLs17@n@syV3!+>Sav}=Q@1-y54tw)Q} z07>`qSiT|aN({jcZW}cYbFO2&%s}1{EkXBqJ+b*sd@O#;AK6FJft*XPOF(wm;X)d< zxdt6pcK8w}=?2Vy|i2j|gkaq590ww^|_PB^VyNc@;`2D_|KfdF9|)-k3WH z*6fd=I!`_XE@7ckI-#$xTL(vldNjn@j34qE)=_3Y!=ULMqOT z+FMSCTS+&*!~S}rFo}m6kbA&$iRf#K(+U}?41ndwF8$%?4&e$ zHgD4pxT1C55RzF8ZjWtVwVeiAkl%$&Zh+Wo@^F@^$so}eDBzoU!H@sR6HF3NfSAOi zKN4H?f8)FqtGkL23%WWR>Ok59U`6~Upl$;kUk2Dpt5$d0`DVt^F9^&zQ*74ajt=ZR zU@DWYQ7PcC-goIfUp#`_l!XOvJRW@C3>L(CCmA+6>5*DvL&}4fxb#@gWxdb4aJ_Ie zl6G(C^=J09J&kKuQgGIp&by9l3s3CskC{QVZw_6;cEP_#U>BL^37fo#KXAb58A)~x3{*DEXd(|NBT1eCpr=fF>C%mikeSJ{?_Z z0H2P@3v-rT_7p+B7_0A=6P|0Yv^!$bcw=i`fPeNrDEcJ+7*5by(P$hDU;CA{JnV}S zIoHl>{2X90k3Bl1#9LQfd+ji3Nnk=L0^GJ^#1UdnS#H_oDhIDKYDh~XAqy@yihuk( zteEq7W$slXj~8_k+fhw|y$Np|Ls^C(1y~0C-a~0;wf5G&sAG&5CHZ#x_M~iWr~PvA z1qjZM>k$z@a8E3zDulbYG~;kho+psL;mw64mQ?Ai>yu_XP!F)cj&8Pyr|r$_8lG*~ zEJSSe%lOGx>w_Nla)%f6%vt9}QCo}o6U(7Vo|d>?vO(+{xL62PZ+0q&sPmuwrs2g0 zUa@r=SLR#Q2a`oReKthv01yg)so37zkv&Qun@`@C$L6YKsszDiD+93K*DECM(}>JH%Iv_o37hcX5FOz zhAq%2!RKBc(`5FY$#)X2PIp5LhNfMKDKuiTm@}}cj*zqIsC0gp3&JA%v(}3ZM2Em zJE#$*gO?V*d~ze~VH&gA{uWc6&hK`SKQ3&G{H_eqDMILDDV)wQSA)bO^0Y~R1@O2d zq`TWfW2O4FEjDwLeggdtycKB%NWgZ z*Vphm50R`zA@d~`vQ$F3Qs8&fyqu@lFm;Gz_FNyyYt+!~J2hbfYheoL*od~n@8&vc zhbkkQxV+yczj^#J&jbAZde)B{L;J*`)EA`;hX0mCkIQVkc} zX5~eUlJ8kPaVrrlUE!enBd~)PHdw_c)$f&r{)1mvv<@M^JlPAyk)GL17lN@n(tHQ} zr+MH3p@hNEOh!P5*@!OTs7PRx4d-(L1894;u#{ z)xL+aNAScBTCI7uJ4e8;sP6bOig>!mrKRln=U*f){dopu9LLOAtJL-W@6=Mx9wRYh z2wYG4qd1e@aJu73-d>#SoYiMVf|j9aPU3hdS@ro1xGk|o+ z{4oKN(#ch)d{P-xTO!c6`*2Lb2KPe|E_}BWqIF^^_OylbY;T6;e`aD04~@}TmH#SO zRU|efMsD87)7e&SJZdnx%>5)lNXZ9Dx-!vWq)CA%?dy@y8}6Gh7>Yb;1l%# z-*m%|>YfATja{R;v5D#P&($i=5|a*-49xDS1h2hn!Zsj=&M#?AEMfqndc?X4g9;1Q z)!OApuWdSux!1$8NLzCFI3!%`aqDyJafDd#c#l=b_2S{+ImAlxsqn%tTV0JX_Ixe( zO;Nl6;qa{rd8Rw+s(mJ5Jo0UTKam#euYH~>^gkdyybRUp`~tMwd8l! zQ;o8)vD&BaJ>R-8KA5Ye9n6&M{#`Ku5CqX5`121oHje`qd~l!rLpmEX8rrU+>H!#}1 zo$a?8WfO)X8H^r;iq=F7U8~1DjgQ*92z9)EOIg~W2a=%&|KtF7%9d?a&5i^V%+?FW zDr+%1@y%cT@T+km$h@|Ci+pZfE;EhjW~}!JZ_lC6YlGX6IzP`(t2uLRawz?5;a6$H zc3&o~AXdDNAZ@eSFg~r%2W}Lq43alJ+5K~=s&c1=;)A0aGOS`}-Mn%bzIt!Wz|)#n zCQZ5m+4Qz$&So*|_}PkMM%KTZk#(4H;eyf0b$^$^^0rrvJ}BcEwG^xM4MCsH5)H!i zp%z21L&Zqo%AmZ7799V~q<(Sg^3!HXed+h9A}eHHE&wK(L%-b~;}rav+3xb|rlA8~0zGM2RLz(a3lTi(14a*U1eTQYAvM(+Q0hq1oM}$0}7~ z{D+4SkNf1?Lbrm^c0b61POuynr@ zm2qfz4@FL?2@`;HcuUn!0O!0u$v&=(t&YHUN8?8NWwF5NgBHH!&y6j!blQtTY?qb; zI)`A}d7s4!=en^`TZD<-y!Q}WrKwd+eS5Qq)jQl8Fs97AiV-@9-uzJ>>@xo)G=kZs z!u;LQ?Lhm)!>Y^C9#4E0#$2b@D`}h?!zg>=PPb_9g|fd)-w>z^7#C-*K6vPkkZNS> zu@r1^D>JGk9rimW_cT51F}hNl?%|?!O)C451_xoyM6MPc?xfU;YXwJ^kKoTcJC?s1 z_VH0={65ugshl7RPIvA#cP5XoMH|4x<9iRVoEh0x6}2?wEzFtqO8xvi}s8+!NS=n2G|UgZR`zPTxjOH zqQe|#!hp@36Lw-w!;%C-_A$%L6g5|(f)(bmC%^V5BcEFySs| zxsPym`f#0?vxR8_+nwi#HGK%%GjQ>>HGw7K@NKjsp}-Bn zv8RI?x{$jj^}L)?XBEc>@}$nTx5k{3$RjK`1<1C5H`~W@4mo~8S^p8b(QoKKC{-(|G+A_}P7fC3k7vbUO32 z;q7S);i%=<#=I@h~tFuu+Kihrhj9QVqrP4pi{nZ(DKM|FYEdmxIxDdIdC?bn-AvhF1Esp!VVd6Dd#G)M82 z1QxsJhAx!c2Xn>7fM~;d6r=;y$WaP^QeMty-Q)(&Gg7`e?d>erDF6iRWz#Td*>g#? zsCUwq;|6hm8Pj>SKz*XMbEXS15i1G#ktE!_^9A|}57*MwFKMP6ET@v_Pu^I zsJFd3HMb<5p3`3Y52^T?^S)kYCM)ruhtwR))J(A7W_7nKJW5F4pY-qtseXJu8~SuB zEF*-JPT}79>(M4w*B|p&2cF&?{XZPfixfL1LSBpHs9s(7GZ!^`b2$x*B>$(&x0)1)PSdKZFk?fAbZ&Ps<^qKwnn7IJ!% zE1!OrDLd^J?3X$ZIw@D(n|#mRY$jq&HM!=pHdInB2Z814y8k0TTu&cs5|kMFRQ z8zu2yLMAGK(YZ+jPxT}4e%0y;8X7<}1Q1Ig4MM51GIPE-06Qeukv-JFIf@ekGyFR> zj^V;75VzW|7gzb;0W;FejSV~&XpsQ)WCD)NBc@Y1WjxCKEH9i64;ZkFmb&biH*+97M9|OY`tL&n{**T? zkjkDHug|!s1oFDtuK0M~39y*?ttjar&(LvD=a`LwMDy#xtm}`(@rFTp z0e??EC_{LEGy|-aLH(zGq7wf+s1ABn%Y@pG$E$w*zV~@jX2b@}J?nwvgqcX7=Dx8G zi*)c8a5L>3)T#8YJ!zBoZHTQ!jU2)cWiQ^hh|XC?FxfQ(PjI(~@7^+~Fd>{VPbu5< z7*nF9=_PWM9cn-dh7wV5kv4p6yO0-JLfEEc44L3**f51>IN^yt^a%lx$1tg1hf}EWSr~lkqu3Zi}5)C`I<84V4C$G8LjD;+|sRz zChT19?9+b?b-C>N9d$`+XowT`nhW0GHt*Zuh)vGryMA3${}fyi7kVM9hg2 zXC-GXB^$fm`-dWsoGIm+J3j~5E<(nXcH0<9fJ?NU*zcT%$dvR98OOQYES;%p%|#DD z7i8?w`+>H+@RC#<`i#_?J_3uhv@2DLWyToP)Xb6{`~KMLudT^))K9`&x&y51a8a#A{Y_0gK*=u0}b~lh+r&Il%Y2BPb%itMs2l z&To$d@m*%u(nJYg?jiB7^}l2sEqJm&!Y*dijjN0up491R@fJqRZvxjA{oo}?2Ub03 z+BI6a5erSKa}jL_K*7b`0&uAiP%(lNP6L$lb+}ddzCujJeNx3=Vnu5XUH~5g6j9?s z#slZl^U40|N>+QZ#%8w>**Na{S8P{?%iK0fzOwCWc}YI~k~7_)h5=CAlT>}yU<`D0Wkjp12l;*d+H+{wT=dg!D7AshtmPup(5}dws!Y4z9tBn!eH|P$=3M2NqXDe5 zS}E-&hjo_A##h0hgd~OYGYOob9S5vl#ADHho=JVDW53XVDN=Y%#blwXiStysaFpGei!NBA8t@%htsTAPLCY9yadj zg%r2id;r&F;C3$@#4=}X;l!w+aa(D6JriCcZ|NO&Cf#1yNPW|F#LvJ1A6jnSNzSDg zP9FJm$-;)vHa+bT-E88*G86lD?__Xp+nbUPJsPTSj_@SC+Py zqHwj&EeQkq*aX*W^`M=OBtw~3r$>Vkmadsw&7}!Rt|zX|<0{kKs^?WpSxd5>axG5j zoA8Z^<<{wb4d_O(IsCNr2I|)mGEY;3#=j`(#)%$&GRZNcr4QPh$fqnrS_iEa zj3H~yc()>q*$)o?iBC5^^LOmRgeaOzlEx2^FLhuwG|u4|_4$i^nQb3aVdsr~E5!ZR zh-}wH|K%^C%LxYjAFWk55J%_R3wO9ys1#%gfO7~0$Fz5YJesC(Kld>JR74-J!VE!x ztsu70z+s%`Er#0^)FKc6(ZRVWK8H}+^-YA+#xBXDW+sANhf^xdoEq*;A`Q_pnr6~- zE(V2T)}$q|UbzNBS3o;f8notO?T?4Kz*t@G3*VNqbJgTiSyg>Fc5DEwdYbjK;xx*D zM5BlDwRK@f_ZNr&g8gu20`)n^!?2y#D*q5&-vk4JFpxzVtg$1{)M#H_K9ona&0viy zh8?f4c7uWZ5&M}&wQbb?o7)L{kz_;TwkQsn4NzP z;|xl$%zM_~L~_l$L3X3v;xHpB+EXz88ycWW8&_D-+%~sTd{NxivPskA$;Z+z`!g*l z=D)hfX4bs$*zaQfV?c?6KjEK%N;CM7*wa+D&xw7x6^kujJ?s#>=R1ky>Iny^M|pg% z+X?i}jdL0Z`4Em4 zf~8d(1}JhzpHG7r$|IM=^dH;zuf+^XKzau0d;I!0b4FyH8`#He65p{5t0hmf2-~TD zsD6wj+i@i__utT~HDwK38a|RjN)ouWND9(PZ|$Evn|Y|hNYHViR0F}zw4+6Z=V}qC zz7O7Wk&krEr=^J@#?i`Kn{YHGSUFn~H z);jj~#PQeZLF45w%%GQSr-6MoHeEm~D-mGoGY<|zH6!CWd^KzOZ8X{`V#ILsmJxA< zqqP4_;E~#$WFKh%(+k6x_~*J11$O1Uzvw(xQkVGfR(3|K@w^=e{DM<2<6-JCVeKDc zysyxEWW7uQJb?$1zqgGcIX-=CDZi9x&F`9x2QCC0$}}H$x9sJXGmW=lG$}038rFSg zwf`B(JSU9`bK+gvQuVm zspZ)6Orp%ZBbco*-ay<9|AT_7CI5ZY649FhQY6+*h_kp6Y+Pj_hg%Dc8N|L?@6#3fGfP{K7>JrX@4J%RQR-*&Gu+xN8|Y)T~n^kWb-)>abKv&jLwv`hhsWXBMLEwJ3;)F#Ye1H!ez*6JsNuK2vfag7?4 z!rfXX%a~$_V2un9Fosc^6l!Lo>Tk`&?4F8{dVg| z8}kmPK=2?Y|J^>&3K+vA)o>G8q(#?mDO4PGS`d4;{-z=D^1UY(P;!3>_A=`n)q3?k zlDJq7&CUDKXnVbO2Cl-`^W=Pm@FqRj2p87W79BHwx5MjvW|I-@Dpj$UoLAg8Mxw_9 z*Bf05#jtlfcc9ZfCa46_4^bZL8QqGXz1_lZrN#o_ErhRfgt!$9j8m$)26F z3iotxw~QMmA=4`Eq=SEZ2M_npU7`(WUH#tNXfmh=&0I9d?Xzh89=>*vos}7go*KwC zPYL$FYLeN#8@v{_NOWMweA&`BBR2&g=^dLEUXp1==kxcbDkSxD{z0yZcllu;0H#Hd9ph;E(JW~tTH`jT7BsiK3N$XwQiTYAx&RUpfZwOlFA2O zL#|U?$s%I8>Ynub9Jju3U3J`qj;VY;@pYW2r*b`e>x5W)zdG+jh2IT3mfE$8fu={h zs{cH#Y?K^q=o~_M@9FOE{XJOFmBgQiSM-@m2cejB4*xd(nGDyeP*<_%+qe9 z==1W5A*BM_Cp09#`rA}b@(I2IjIaM4X%=feQ08{?pC~HOdJJ@gz%W0*;ONy+_wL_K zbMqZ~$nc9;PkiQ=k^ab3@yDEOzyaBp%Ie?2(u?7yXLX2D>#SR=?j+_1l;-NVpE2iBKKwp8(j6B8d1{{bZJ-zV#VN=&HKbyPZI1<(SzA z|3v$RO0&-GQgdvH{}NhSbIxJ?mFFaP$|4L8QRQZpzIHj;dj|hOpnq|5xe@`iDklWB zMo?;%;k;$W9F*$J9COuD3JxkRk$7D1^Iq}UU)kDR1+ZTPIsFDi1Ns*=W2IGD(ZLi! zmm7VR12uZT&-iym|LN?jeXXmCf9dTr>9yq9JAy%QL2*N+SR2;a;MRlX{1mfrPMw4! zRuwm!ID}hc`7svg7XEE}&BGXAvc~_kCl=IOLH(VhwgR}Ew6!z)Y+L?|aFe)_a)`8O ztG_D};4^Nz^PH@HmLTcRgGEp?M1 z5B^xGPcb2yx>7)GkzWEI;urW;{rRH1f>0-Bm%B23O}yQM`sP38Q@56#f=#3N4WM_$ zi>^v@`I*PhULUoXkL{be5x7)t4pDyi*`u5DO4v|rJ;MucAtH>})fHgTwp(jtc?IhK z=OXyUkM2I}z0*Au|AK)`ktVoY#qst2Ue9kItyqjN;862>#;j%r?PJ@#y7H4QIu&r< z0bp-WAvG3D&Nvc#MJ)GH&)4ML<&2iIo~p-EQodD?oYg(TJTce>}sx&E7F zhG9Oip?OghL{_8Q01QQ|?~WZ=b`Qq?xq8Sg@2jhPPEQDLbqF0KK>_yMK*w(WjYCZQ z1fFCO)Us7d!S;Z^p$e`<+Ops|nr-(~w=yp8a=Hf@vMJDT_|DG`1-58Bf0PxHt%!G@ zin#38gC@mY7s`CmYS~LNY1r-1lWlJE$cgRqJKq&d-*8T*@6K`|Or_oGxTRs4XBKte z%1U~!We?iAS$aBX@@9YSaZuf8*?Lm>D^IA?*{JkwP`Q}E?z~ViSgQ?xx9pVx-x#;{ z&XntZlClV-fV;ZfsI{NY9A39<>xn&&O%QWQY>yJ$0&mJv5Z{*}Dd2hS1)hK414r#8 zjc2uZl}Mrl+@)h!niO_|(d|Lp&aT21#uu0fycjo^V|E4xoM>h@m}_u1z-l=0Qq`@6 zS<^`9Uc+`{zVOn$(`@lxxkX~R&vJ0LfTs~z>u;5O8BSYkn|T+rg`UU-y7g+w_^#kkOay@`QEJtEy=pQ~)b2GzllPL<~(t|Oa`srs+YfqBer%MSO8}>VBujB7B>2OkawTZ02NtzMSIW_g(!hV1qwOkVIC>zz&!RzB|MC^r8p z$mm^7GtuGNINY$Tyb-md2WMcstn@zHEjGOVZlHd%`?qquCyr11&!9f&dL{xNf}KXP zWao%?n%FBRGqMIi?!sXBLw9W>w-)4>>vWUXhJh)>7gQ(3qlMhdP-E}5kANk|YGHJ= z3a#%CePe^91w-I<$ms*MS_kZtH0?_F9*JgxZ%%E)zpQbQRgBS3pVRMbaoY;|SFQEO z)_e(!G}wAd@%M<5K>J17$Hz&Oq#I2IF?m(yDHZd>w6r<58^6-&=joT^HC6__@I<|^ zLbY~Xp~Mv+>?HMyUmnjV=j^l|kkJ=9Z0l?Gvv*IB75(Ta;`I2pWy>4?NX-iZTP+-~ ztF0d^-23?Lzo;far@7ega13wy%< zOa!d)x6$}z34NDFC6|9{5xuW*azTNqXDPL=sFbdPt4_sW?9dmrwO7A&${{~EkKKbP zK#eEYL#yS#;P=zR7;@>^XdZ@{E0n&_i+~0)>(THJDR}YlxSHn6_e@VVEoMKjMO;4r zfe1-ZVSM6O@>+E7L3F94wF;!+Cx-LEi(BY#&Tj%;tmp?yi%EI)V(KTHi(ZP)8%*>^ zq}6UmnsVwy>hVWIohj#yO}|)LP5g~1+^4Cis;2ffr7JYV)CN4HjxE3C&w)&Fl75b0 z6=KlQH$rIu&07Nw1dwehbx(WG6)G}{xa>NqNWQpQRMsHIcs)v7 z5zJ2_FR=dT)j%@a02+p0IPA_f$Gva=k!&WamWX8toUNi5?AOCz8Ptdz-3NvmD2V2?JMGk&{h>}AkZU#2V|Q=ElB0pZ%Vy4 zG(bu185zrOZt z#|L>98w|EQVP**w5I5vh#cVsWF$Q(% z7nBo({)j2i2#sLT?8$5VvnFa}Ef=5n+$%72+;zOQ*D*G_*KeS_e4!EHCe?IVU;}Cx z2}IWl*!+Fqw?C#bR6iFkxDFI70zsxUmHo+4PII;ac0@y)8eph~y~GEWb_WMtckPNg zw;e;8^=eAGH&V>+1G;(m>9CCW%~wX{hb<=O@4Q1P81|+*a9D@~Zy=Q;G(ZkMwIqgk z){#BK{hthwEBI$@U|*TAA87cKDQF#TxRGq^p+1w9;r4<(1y+A^354lVr|RX$tbrOX zl;@@iB*O0(0WlrDl(mvc!Cb>fY^c7&TY+cgl(3+E!P;_*WPAtq0794pJd~NXN|)JneyetCs(yFM6t z1L?S!JIj~}KKIRWf%pHm@7-%k>dON{s^ZH4fIA!#%xyUJx)BT=7;@QDKREms?%>Zy z%-?4aAwjjR-LJj<-EM6x&l=mWuo>`HzkM&ur46hg4_3+rLdYQ>7YO(NO>sPNZl>Ot7>2AC|TJ+HTKV`Q#Pw4DJ+yo7l12 z*2{3qe(%Yg{nR*WE%K{*s586i9hnzwrGM?Y`9#@r()T#bDec?c3k)d~g-b9+AsyVv zCNA@^*PhxfRtf`DOTGre!B{gisEs8Pv+BQTgeiyCM`Oob?+FuOUiFZsv_qo|36(12 z3i1}-zx;7$K!5h?G6NjSu_c`Z$?*r$TYtUIckQMuX1smFqE0!wUT+4Bao_Wfpb~Rj zNO$(i5v;;~I9T4N9TuCxww#G_tI^4MAyUwuf=WzMDuybzb~OS<|aukFkvcV>s7g z5?u?ODp>1f zgj_uz!n#eNMWSv7{QmJ}OXt z0xhXF(98IDVMvkJsqNMl$O}ZP-HGTX6z~`%y4In(MWJl<9@Q+y;dFBWHn?`!O@COy z!FD!!gw`#{lCy%+fE_UF&9I(QxOw?4xg9hwF}ol9bRN3I%ige|^7G^&`%=SI( z%NbMNGS1seF~goT3BJbe&J{OpELJta5Hq_-hH;#$`D91)f2Zauu92H{LkTqUFwqSI z_x@9kEn})Z%!{SELuTy&kBi94^gPFaE$OsM6Q@QvH59ZDTDpFu_C8xXPy z1BEIk7~rd$J02_xUm9khH==+YRjj=-{;Fk;%P?M21iIi+R!^FHD4DLIMu{-WNDgLp zQ}4bkRw|+?A}uvAbPMAx)fhrX?fX>)?!@lIBf^X0c8n|R?N;>@<$*jM0;|5*h7j|Z*E%&S5oSl(84p_ zmrXUt`QWi&f_UtCC9^dzVd1u`jMZ=~M_4$yAs7ZWF!8YMdl2(f_{Vs-w{M|wnawt@ z1yJPj#^M~c$Waj=kox*L)(aZYv&EsQ9$Wa-`J}p~E~a zpA(v@pbAAT6h@VUUyMb3SY7*q==uDuH^lHGm8e^OfTBr@LVnX^59Z67eE5%$^7!Lh zq1oI2aeN8?buWysBR6sL+bA93Qe&9D<_B*}4S|E!5m_MmgU3>$;9F+1-ZM5`sFKpk z5Cb!Rnya5g5&^xq;TP9s@69Bhx;BkAJ`?d(r3ntYLUYp90%_(xcRVE6y5Y`D+i?#_ z!0I=N1gc5VQ3DvUD-^G3Nf12e{eT+_XAYH4?7st~Bu09fVA6qGQb@t}ddmp0W&C@m zz%PHQ|0MU(X@NK$*6OS$&cK-FkuG4?K?+#lvzps4etfnVWVc>k^~&f1rtiA_3Oj^c z1>eU(i5yzPu~^ah2kT|E!-I#EATjb`iBomYU?`6>k8wL=+^fcF#>!sr@+vDbzMcI` z$`{-J%>t2kRh)2Wf|?cVRQ5&yU)_gk$H>%*vd}`5?ap8pjCdICl*Rh@)+#U_73l?z zN7RGql2pST%eOt@f>$1)!5vU;Ww>aIa>@Z9=M(2dZhWeWFKTX@0IGjvEO0lMJ(28d zR5=%l*~l0dgeKnYY6RK7$Q` zBcot-C?1O$@@L;_in5q7O+aq~%BX#VsK~hj+xcsdwOwpRg-XhAq`93*F_z7{XzaOq zic(E^Aa#n;UCcrNrPrZ8Ps9>D0j)leY?M6i`av20z&?Hv^FhfmNJiF;dnxByHfHhJ z*R2tWH7`1bMow_-hF2_3zkdI$?@q$K*kh>}al=JC)pf=mi|G;TKaqd1v3cgi)N1>V zEupQo$G3`z{Bu(nW=_0v4EWtYA$n6GJ0K5obiC6x5+pXaq?m$4uQiS!)`qjBGFV8N zE{Z3=*pL2~3Y?)USjNm}e!fop?kRQsb@)R?6mA1Z1N&jK+jjcc8uxnfW%~^Za~hDK zpN*yO1?%jsW+NMOuXUv#y5w;<#h=pEE#EV7_4DrK^L-{UFmu$6T9G96i}#6O{nmgX^vta#F%^&n8?GiwjxYlQvajGr zqEFs0cr>}5H+($CO8GX|era0Lua+LrrzRIt$T{KB&%;;7T#z<7#N?4w^v?U8u9oxL ztpk_x7siSJ-G@t-nj#nx+UF{YyPh=1U|?T#FsuF5{lYizn+nmw$> z)aO1D)9(Ue$WuNBUr~mzl|6A0=zz5Am+sugo>sdXEi$*cQ;(4}dWg0|g2rCN;Mc&!pw*qq+ip=M)G#7E5`_Mvjt|2)4HkZFkulT;o-6CY8=M zEkwNBO3gcywvt{Ed)kQ!B;sgqy4BxJ_}}o8UvS>42(e4Qn7Bz zbDgcp`u|9VsG?@!fVqO2{msYKM|t2RdRXTPJGSBWE745TG^-GACMX-QsEORRjNvH&7jmW#4J zTj2yI%#wkmArC^{p-Al5XX|9Cp{{YhWJeTN>G zntQq+xYOv99m;2CC0#+ly)b!oGXo-4inie{zBgqFI8;S?BbcwO+etlin$KzmEdEU% z3z^=s7AYq{)GD(J$G8JySvu}~3KGwhUL!NGmCv9ufOU!Tw%ZZsc3kgg%*-N#RIIu@ zN7B|V-UdyS=73YCtLK#~zj>^1gG0C{UeCG^{xq_kANRFXJp6ij&a2}lSZbe|B)NOn z)j=Zo#xFi+Yq0UvRC&YZm|^^{{Up!9%Qty(w{wNOT2}%pD;mN+CCc1#F#I{0Wta%L zvdis|qY7B}kG)M$aZbxPxUjFhvpAVKA|bpUTpsoE(sp(EX4&&Y0R@eM*U?2g0De`tLn7b$N9>;db|jWl>s=tyr(1@9D$x_* zk^$JDq^eey1)4XBjNfiC2;o1p_LAgx-|Lu@F%XZ!>X^Dve?dkz>&LV@yRloXE@$Tq zq{zce7^j~3Np#VOwKs6n70xZ!87_RT9P>!j->mD3HZD&HAHA(DBv+qX*L^Ec!Abo2 zZ2X~AnUIfh?>X3~!9*3Jbg=?N;T4-XCrJ-#E+P5tIu0!ErU`1y0jfLNC~m}o1m4an*_9+s=*kvD~q*Z+9W z*bgO0`j%_hS1Rb>IBVbP;j!HEvcURMPf_AO6k^A-#pT0M3mb{N#yI^apU`Njyv|VK zLIlIED-+msemqaK31{DzP_89={EVDMmVBPs?MKM2?Xe`9WtaVben9f40bb&W_wn-%tZQBXQ{#4;IFFyWt>3S(&O_F3 z7WjpMJoX<&!2G6eq&Q6!Wj0XjG{u$r!n;J0MFv_o_f!B8?KUEV7AW15zWhzaZV&$4 z+x(9d6aF~U1(0FH_S4;{+#1?k2<(PmHRR(DATY9yfFnSiPANWYyMxH|dEvn!^y1G{ zDL6b$*q%N`Ht6c5p%?+l=%9S*>RWd!wih(vPIpX)9>~K^8L*4?$hJ*>N<1NOIE=p! zSgP8PRulO~&rH`A>t0=8Mc{)x$#GTYgzR`654TUzh^G92UjT+{D zit7ElG=f9BbhV0aj$hGFax~qDC4bV!o5^A{$}dgw(IbF(UOg)pB9U*HJGf59#G0^d{S#wr1`G) zSy9GoFFxlV7uk2wJ4JG404FXY@@pF5VqGyJd+p-6Aifyx)^RqQK+g1n8t88~ap2UH zI@kS&aPbTVd;u?W9t)9BmFT3vjz627BNF-*osOXKE`~8)8;pH2oIn8o9 znZfDuqtYT=s3%zNq3O;25sVo+GC>^h`Qt~tIg;^^Dac;y(aV~L) zwtW-(8;zXr3zm5z7JYxoOxHdJ$?j~WJLcJ~SAEa_1$`LGJS{;7MnEN2r{*I=%%-I?^WkK(pA~IPLM!KJ%Y%UV{P+^w$*lD; zsN(w<z3S>+wU&CTF)ZJ<2?*e;e7NwXbVtm6rEs0K(#(((aZN4Pvz1za-mbesFo> z-Ad{}NM`U@*U!AIA|UfYd~Sbnaeo%O9Gs*-9c2X`_z;{ z=xB}f>7cMSlY1VC1x%q8)dB+Cb;wg^qk)+EY9B_uVRp^ijg|dtDQ}Z?=7_(4e)a%Z z-xuS)=A!cr&5w7PXTB>xNdIUx+*jRXFE2p$Ma!gsNmHydRg2o_I3Y2dkKn_ElJX~( zVSd`2f8#yNT*Y701#A-)B4%9tCOC=nr1ziB|1e3SuFvv(F1~E}B(-ugyDWcerpG&m zyL58|5SB~3BrE^k>ifjMClaFH*+uluf9cjNFN4QBgEpVw+WpILGrzyei+MMH-8CNE z4Iz5)$%j~6s53eqXcHif40w34mSAS^&;DuYlK)Z5@Ixi%#>>b!1pYH@qCnDW%P@poTN@J%^mQwX}1e5 zCmj~`2lG}}KmPn|6eOc~XRD+baLSQAQ-jBtOrv-^ybS;;@RJz&RGhsW%^3 zGoPLe%~3BOEj*K*3G(!KKSCboXL@XlD`ur3B0G|h?JqAb`T}}*8o>b#r0-^U8sorz zx06!zlEMGRN?gh$Y2y(fcU+P5Yxu9`-n8BT)V6iQ-25+4wz}K89dgCE6SwK~1)ZX` zE(J^NjVQTm{`Vw`(T~a`EQavkc9oo)Cpt6aZdBeioAm+4>f-vy7x&K+oGPC3MHz?nZUS5y0=9nW$$+idO6NoM`vtgz_ zsL&PEybg{Wd(2GxR)MD`&^<6F=kG)12X{N=8|0|x2{OA_y&96q_TI)_tWqmQ0R_h|5r%c zM|PrOi9DV%H9wEoJ5AL->&=C!7ZQyZOy#DaGfmNXWV)#HnlD!eaV2p`hrv`hvQ!&m zWBq5eU9Km&Ue4iK`&1kHTGhU9=bq%EBimEoNX>DdtsZu+W$D{y$lZkQfGwLj+f6~57FOQOKCBWnq{kdaHF<8Q_1p=5Px$|KD>ew zdxbu|nmFeuRgk}y>lkSdx`qPld{t?Ogz>TDdI&etXvumwUe+H*{5F52{Xw!f2%N3w zLyq%fP9`)51{uJF-;WmxZ zmkiB%fVEkVj36abf486VzI*3=jWAnnXg7b#eesIE^IvZ~0`tZ*9_pi%wHKiCnren4 z4{0WDaj}#LGK%%z<|9|Fqy|&xd@i{YCNcU3SUGwC=`JsI3zPnY>T!jcE@8_*)adOW zk1XjT1|p@8JxK2|(xM(Wi~M>B-lFZ**f5a1Y3c9t=KuZt^U1(sUVo3Tx#UUbW&Wod zF{*tg8ujLzH<*3mpJq+}k*v7KvZ1?0U(Lel-E*XUT_d7yy|U#;g9yM|JavL6kM7EC zFE1Yl5ZMkUX+1J>^Jh#BP*f^me4nEB%ER_szt_5i73|lif0n^d3|(wBO=m?-+~k5j zKdyGQ7r%1{&jhKay!$_z&MGXbwr#^hmy~puw9?%SrF4TZv~y#AR(zBT~b3x zcT0D7gVOac-tYML*jvLBcR$xzG#{(Q4A=I}7aFgMJK_Z6ruLSQpJ-^+Tux7zb`xn} zhVmiq;Hv&`S-eyz$=Z@N>9Hfvz4!t__1Sdos%sa= zZ~t4mmH<`!!^MaX`!{x)WIBp*xX7=H)vJM~sf z6S2NQyimWM_kX*e??Qwa(d`sWJElFpiUi*x4J`I|)z0qTQ(%P+ZjltoWMc6Tf2NZ$ z9p8L+bI}%rWI33Q6Sd67Y=~lU8?#rrH>>j7%3uZ4M$847(n5I^~vPOzmnn3$;CYsEq4XQEE6)vmKhK!H<` za_h`trd^`Hw7_{GBj(CM44L%N#TZ@xRrigdrD9(wy)QltyARcH`B zKnJi=z+KFhP2ucs5ED$Z6!cKQW|+qu9}ZukCrk6ol4UgcWseiAP|)J`peK)0UH~8tlmU&qdeA~&Ht&| zs{5$d-1Rr0Esi%&{h-SK5$m<1*q>_a(SLC!sgM?5;i0H!o`;@yL2cNL@kH5h4ZiNE z@iXnigt&EK?)*2Z^d2hY@s}$_N}(~i&&DIDq1q2O=Z+(vi2rn_e}8^#QmEeAbfr>^ z%5X&S4z8H*XgRjW-tNZ0&+yUgvA@+i#XA)&CY7~ ztRki2d-}W149nO#l+3nC8t--tKUHFdn*8@P2eB+)#AVNfHQ~INx&BM&Ht>(=ZtBM`6rfDrwtqax;pMfsgO$ zK0?S)F@nbs0r6$P%b=lnD5%DUp9(v_ik^y2wv!#T`qx%PQdMr%p@6wfhH@qite1P=N4Pt<~ioy;=+nOd`CN zyQ5~|bM)mvM+9W7T@Cb1WEPMiei

z80(iyl?d|EoRxmX5vp>yH~-)Sp{tz7D1; zn&WuOuc}DQ#Kr5Zze>9vUsx5U#TQ z^l)+*QcB{PfegG-+bwBT^yeNU@7k8)DV=znUWRf($TfW9?fB@KlzD%x+Lu&`PSt5X z;4_;4Cxq?O&A0<^3{d_M+fZHR1=nf#<#R)$Z@Wq+uN2tN{GN5~b9&kq@>m~%F7Pu8 zmG-A*^Add*TpZpCEl3tP=XF3o>QkuBDCVQAeyyl7UbsBbypawJP6P&#pXg6+8;Ps&Pgh$_|tExi$Y z*-hc#U+1*4W;u~!8nB42jR9Vwx~XvT3|%>Vg*$4GUe1_ktseDYJe;Z1xvM0G7gAeP z$e6{EHjsf0#d&cJgXhW*c!I_4Vy?@|W0YKUmR&s6UMfHX2Ik4GiOH#XnezQ5=OW0s zursY7R6PMm6Y%!GespYM?-!i5u&eZcS<(%%(IJz#Z3L@cy)D{t@I1^G*%|-twj?CR zftK<}z7wq_D6js)=049Nb!cpH+QLQT{kdNbxW88#KcPH0@r=Z}OU}_GHaok77x*nY zU?3S4>EIVtjLkcg6s0^q%C`n81cg{^I<(LZUPkTtD+nSRQ9!toP4z}?6Z0Yw%qVd% zj)@PqZL|MU31cC-t3BDMuW5r2UFeOX>CYEvEMb@z)Sz8DR6U7-1T>%lYYxT5P=C#G zj}RJ)#st73?xC^BmoogR@G86Y`iO-JfL^(%XkGr$1yh=!okT3J3S@sVQ{d{?d=78u zu?F~g%8<^3#KTZ>e4oUsnnYqLGjs0j7b>EDc3_@plN+8xaxV3mx^K?+4FA=tf|V+E z_D6hg6`ayvuKbvE)u#$P*|WPQ)WaP<8C*z4~LN2~Cn_mq#yb{>srar7dRV z_aGI!h;I}&k5=7I!tf6L*co3iD_ z^{&C7f3niMG*j74apkwzp^{sXG}%aBvh01C(ZRh4YCp}-Jrw?!^@Bk9M0Mvse)S+~ zY`n7Zm$dt*7uCjyr5@{nY#F3XF8u7Uv0iPO|=#Z!k(~yB}HFl(|@_n8Laf1%jgVKY1(ofVc!$j`}IMCYo zfS~(6a<)Kc%V;c9CC%P@z%JTRr}$y=BlI*NT!*RHA##`>!;Ib%;?*P8R}MC~B66ro ziZ+htmivA58faC!#*H1#U(I1sgu&4}n!Hv-yP$swlMtEmUa&FMATI1=^q^6${ql0O z$Ck!p3$d%IYC5v=dYmdTu1$5N_-UmaVW{sRR3v~AZ`1%9zL z&zYZKO)nGW)fb3o_=7^6mxCb4SdDVN3~|k>S7pyyM@mTVzT9_}Da zvL8#53GFymY;XQ9bQopTH;IWc63!}$&LK`S+0=11Ym0Ebfz8S*5NO`95px?OnZ$qt z`Xhi2)>tXj?Rb|(K+fs)4W_N3 zDLk3yCp!f2OU0U#pJjy*l9xL=vZy{OrG5&WnOXPBM|ieRcIc|w1#Uk$mKbLuni>_@ zI9K6nVfo{*Sejq<*{aD=Xe+%ijoa(PjMrK|kYG$UlcRwsLJIG#9bKr;*6ZeuuUKry zVB?_a0^nx-#|E$?b#iNub%CU-iJ2!FYXfOFKcFO|;-6VJ3m{ZW`P+_}6xZZJQoC^QEe z*P%^U-K?FT!`A4x5~qL{%2gPiJpt8pQ3*Sb#Do^yGO;On9Z$}D#X_9vWn0g{WWLTF z7#D=ehI!uLBj;XL-C5i9;o)DM)@nJD=M$vp=FPc#Xa~}_#U{S-R1d+Wy>|t_XAJ>t zYw(x=yk{1E_v2n+^*BN}nQ}T)9`EPVzoKgvPgTjGJxv`H+u184ODSxOLb?z~8{^qx zJnR_4T<885b-#3)d`oPT*K1cNC3qZw?6!A^!Z$a zT96Vy+W8z-E=zB%%Qb-ks>w_ovoPBy8NASWX%yoPe`D|a9hqdeaURz}F;;t1JTvJy zg37k2j6}Ucdqw!pXL+S(FOLA(un+uIJhGF$U&4Abkgwaew|1O7Zr$YeT_empGH@nd zO9UO%Y8OgDz4@rUkzgP`NZl%H`+-j0K3Z zA^%c=W#>l|@EsUA0?;5cRNCgf>jTl|=OpAL#63n)E~e}4U~$VX*@mz@G=#N6H`X;_ z?N-(NevG5{J$k(UA&L^{>tH>*saSBVysv@z3i@+m zY~$+NXySX6uH6AxXA0zm{fj}OCo69OM@6iIN)I0P@wcE9Dsete%D<&E_cMlqyQG)NVE~vn&R>jiA z8d~(TeX0%jnRgG1;^T!guK_M+^}vw6@%KKFqVl>Jcp! zPE{QGY>!3>3Xc8y8^rUn5s?JAyU4ki&)4F|?C-{&scNmCYjo8e&jD6+Cq}`gpTq0W zZ;qvZyTNSMzMUB1kY;U&hZsjt;=xaNc~mqF7CcFsB$=8x3Sj`TM#+Sl`%Lo$yA`+% zBP2Oo9CXVCfu~dWrsYQ78%b<$q8?1UIz`-3JcN$()#ph8Hxyw3lw4RX6Ett`eo0@*oi7jpu!0$N54I%xUb1SC&A^q%m&V~EmhhdLGZSHHs{ zxfqk;cFf@rz*OMH#5^prjQ;+7{-aSt(fQLw&UF?QNr6v~2x76Q`(8;=Gdq(Q|45G8 zZ|!va(~nE{?-^+Ieh-W|UiEoIlP^`SfQ{2q^b|=x%+jHQr}kb1t81xO7hb26+p0en z2?72%R5xOx8*wZ+{RpRzsu!z`f&pgRST2m>5ov}uW2uwqtQwi0h0*)YJ*3LKs?ZlQ?MHG_cA{D560-qOY<8P0CSUu=l<20E=L?87q&&cVq{7UfX zC@CZkY8?-pAbal4gDG;^-0DvnWJzMwB4V0U6^GX*zRkn5j5zRs_{mSiVZZT%vg#{c zeOo1>hdD!rdG=3M;reyb#Pu$EEf3$5C4o<|(E>OqepJT5J9);yVjz?<`$(%~Ms z7=bgLUGN2O=>EF2U4J4ChVt~HA?kJ_gVA@b={zV9qRg+o30G0SuovR}m zXsLyjUQ7zB-U2)5iB#`SP)~(8Z@Jgj0gTHP?vhO{l6jV{kH@VCd_{_ zMKo|B@I_iN*b`HcGx~x=$f;C9Lpg&Zvz7|Y5*~&PKV>u2Apa!Z)4s-o#335vmq`}; z=~xa}Bl>5H5oE1&L_NPe1ROdL$#N<|H9@iT9a>)$hL4!wTuIQM z08r+Whi^6;vv0g+ovU|ls9~{^&Jcd~hD%JU7bKJgpG5}wUMztjK>KFijO&d=sJb#W zga-R^=a$sLlZ*fZJn<=K@f|E(Q}xSRvInAy{U6!1;K zl$G%awPBnlgkbt;agsV*43Cqz%blgi5*FF4t?|!?|-Ydl2(LD-xhpCP2ggzBZe~{9- zb%8=M>gZh-Ns!yIr!*{&L1wXGZ1ug`N#&yy0X+i=D!CR?7iUM`ab6`i=;tS2q!zn< zB~xG1_br0o7fA`yj{k)GxNp$@h`lQ!9Dm*f$u?1dQ|D5NWzp8KR}NuH4MI@_la1M5 z#Vf=*HDp-aFrz5xl^A~FI&jreUL0ouDlF|qI%MF@1s;iz0z4yxsg4c*D<$_o+P7g`Uy*8)>2Ny9tk#6i>*_{`goTzf}mHsX+II9 zKFT~FvJS?)+7A;k?yVjY-`k*R0UV=ArjZ*3NsAJ{Yp4J<<_QMZ4tD0Qg|)*U_L?dv zaMxg-5dwiqMDz*@3A1I@&JhL^?uI&gT?};W^Ry>^Giq`on>)HM)asobDU;MA2}_* z)u-i;32H?>>O(YHc?p+FKnc(;vQuSj-oG#sQ~rHm4;$ugGP6*7vb`9Kl_evbK%hHPZ0gcJ!I;ntT>Pd%wg5Cyr^`Uy`zITe;61Qa zv0JxoiJ%ls#MLX*u_&1c^zL{Qv2w!eEv@7?HRG7U>SWp$W-@+0_%zraof@kG?}R&C z))f zoZAZlzbox-lug}xD|&WHem?Eoe#@EilTM-$_t+(N){W2qcm-!tNyBs!{EAMG?qB~R zPwF}EM$+M^A`d0!nVbCc108H6!%wHp5LbcaG#!@Kr#=I_!1(hCwq!-KX-r5JQP+E}lc*Q+4cx^e9Hqjr>nb&p zKVex08oXn7_(<~`h)gHR>Zm93(aL1s zwg;1?lpm2Cyk}65ppP(NlMstg>plXqu7m*9rxL``D%G@)%o<@gh=gd2cnKf1?MD=nl7qCObv^B*VkkRe<#Naau^s8m?C?(< zYB{`lA_-w!F{g$mJ2B4wm1$WP)1WCvJ_UqhZHnFfg-RN`vG8Ps=b)n6CdywQok7-l z*gZGxn+rtCRI*OW#xqmjsoJVBRS~3+*DK!7Qavj9U7?>zj|jUdKIrKq*&C$3^~x zjdzXhuCSlvI~$zY{T-eGu42}Y9)1a7b^I&E6`m<87__6lL<<-N13e-jEM2j30zVy@ zlkQj57+)br9L25cgD{s<5_Rf0zv~jb#AkcF>n6{Qdy?06R{s4!)GKqh2CK00Lz{=W zp7*9poS{|cjGd^`c!rI^>W^S1-RB6RIG55%;=!gbFH@;-Ba~vX?D}+6 zWgJ!hx&^VGE>R6Hj&e`KvJj{|aF%1dQEfv36(A6y>3mJn3=}~-Jy>b@6+b4dg9f1A ziQoe&!(jCti6i7Jx5|kmSR5@MjR{g5g+mX!U_s=M?RhWJ43^V*PKdbeg)(#|wnu!H zhM$k+;y{~(<)Y!Exk6yi*EH1RdDnOM3Pmwq zQn5h!X3K4UHg&+*i2ZMBZ*ESd%hzAj;}F9$KyEL&`Lr$?ICKa=W->OQ{w3|2dTK)f z7?3IaFZCtYmyB{x%=qotwHTfA+85UG4ZKzf-4)gJ-g@C9WX9{}AHBZ}4z*AO^~kGv zWPrBB8pk`#3cZSsQ+!D30s<>{hVH{wi?NbMmPgbIU*^osCjU_sib_?6q2#4{e1#DNvSi=@89S`LC_52!XHMR_nQ80w7mxZ~@(>~K8rt#Qt&&q@|!a1X|;khwh z5s^edD_QoPrq_Z*yD!YGXrPy*->8;gQGB)E~P{<-M0R#rE<=1cz{c*g(IMLt^HY2hGmQZBr)8`eTFvIF0pRoaz5CsVp)PVjoVpZ;G zNvkqzyexthdN_zn_1^}aX4qKLgH zb%rws6*O<{<)R;0yuc(rQV4z(os1~-xQz#kn^Z<58oTOfZ#?HE`s7# zM3y>R@Ld@BNzJ~f9*&^Sc`j*1!-&DY{he&`llH#Ts19G24iAeH1H72ClUdqE+`$Ne zaly);5O#E~rAfkm@NEZG4}T*ZMF|AO9ES7ey&fYRqmuCV`fqy+ug;7OJqdF6HXaQL z@D;k@uCmmEs`cP}tSm#kp6H>~lRyBm?1Pj(vA%b;S`^0yFiZk$Sjr#wtm=f@7fG>XhjhawwK^sE?g!Jdr}sLkv!~v!q86G(YO;|vwbB{p5w(~qGOb;_ z-w1Y|{fi981)$!%|07jWb)>d4O!?6Kech|lb%eB|2#QIKU*yDYFd7Qsd(AXdLX!Wo z2tEv3#gdQ`KoGuP9bY;Zs{in*2?7@AuYfh{?_h&UmzmT$qX?b73kxIU9wBFQCC(bQ zeftK%v|i7~IBZp3Ss(6h3(z%iO`7XgpF0(N6!OM&?s*=ha@QywoFL9pSm?fd)!G+M zN&K~*e3d=Fs+@tnkL~#3;|xeiD5e=WJMjbT1wy!gSlO8z?-jPNBd=LA>y;F6y1b*M zV&Abi2KmJg&|bOF)5p-FPemm1QpO57bvm46P)s=izN#Bu`_45^bQ>AMKj-WHmz}7g zGq5<(aVUlCiGP~M$ydAcLXKMjIA>@n%{#Z$tbaU;7rW zx&+LakN`Ko1}!H7Jqq1Khh-R{=OVE%xPtEoj}w0A*Y=C0pQ}u5Gd)^=`k5E2Y|gG! zu(R6Mtd^>rNZdL#6{4?u%BZM(;t-;C2F^dLr(b!ezZwM!RMm!lT5Tx;<+)#n*GC9OK!(g5CQG<|VM}8?~ z1mHdA_OEV}Vo4=1D0|SDEcnBj=4ZrLn^_BosG0bl23%K2&;}KcUu!{R?3lR=>Y38sW*z(Hxmj}iVSTN_TBRySL za$phl6{m{snMXazZGt|t!v(_0ziG+{NaLl)D;e1fQe@0_`BgxCu<%YFG&4m<2rm^Z zahOR_x@=9F$QgjJ1ShU<{sLth3+eRM{IFL-6K3umH4*X!%q=uohe=gyQo_m6?_U># zK4x=>qE3pm*}=C)k{x{tRMMh=$nOm@V_qY&T5-YfB9IQqI|6&4(lfQG`S&&GK96u~ zWRK%a82MHw#zb$X1H&bWMpPX5WA8mHLJ~WTa%hLf&Bii`RFy+I{i(|%hOHmK=? zR2Vf8+a>C9C{2BKP#vpqHX-G4L;trw$KG1+aO09HZvR!-q{fR|w${MPQA#Ex7#N3Z z2Zo)7+yR-q;0}Pu^v4}`wk`(~FYSrmmXI&bqz&cV_@FW^moUYY%Qg2~Y<{v8x4gaH zCi1|11x{@j{(_1e@{|0pU$47645G%*f9F@vgS~gPG~>G>GjZ~*nDZLae!ewms(brz z;F8Sa_^PBtCgKIZ+%zy}lLH;x5YXXeFDudf8Ov7)SH5Fhc^ZQo9ldYAY888YwB8eN z*SLL9D1@*lz~E{f5QT0SWZCLxR<$cip*Z8qf;uuJ!t%**SEo7eGwJh_R+HAB$wj_T zuWqhr>Wk9HT#T|VpUxjrs_p`e%2kR=#-B*4?w*>J8LVEQ7oSDOHl7X`d0dYd8|yX$ zyUcBOeCL`khi8z0r$Roh%x8%z2RNJ4m)|=hDb09=?g$4Yb$8+CM2RM+U2B85BWP17 zbB~2k2`Wh`VVXGMK(KFHC=$I`fqrz`10*Rx%GPBRML7$qZ$fQ|t=HXl1xcPJF~$p> z?w;YE9pEEcR@0aP-~H72c3wGBH7QyPU1m~FHI3WojgKhSBFBB-gEe6NT7#3uqR+HG znB~`jE-i0d8lUY;;K>FhDh{Phxv2X-A@w`iEP7nJkQ;%vFSY#kGpRm*w}(Uac&*xg zev2DMQcmY13&*9fx(Dd2v~G5VIYaZp08@|KQh#$XhXih3E z;?Wh^?TB7n3jcQVyZj3zqi8_ux;WCgZmtEbP0ejx2=rkZh$wPVpmW)w12_^}EY?qm zV|-+?_^^#;_@NC1HV>2)N4sw>$fRIf(I*xGkaUQM_C4Nb0p!gUw4L~B&tlZ_=B+CT zL0h>Z&3OXooE^wI*7sA#1R>W%g7~lUsEFq|%Pz}xKF2p>*11rXrdR3OzFtq<0p6-P zDly9FFIU*-^mh%Q*dqK?PBV|YP1yp3hl8!mYV)!R#xZVmT@1qQqx(rRK<{b`Frw_ zY|MXd`=17}YN=@Ic_VlZB-IZMz}}^4KIldU2Y+FgS+vVpdLh;F^p)-)8a$xQ;Fp}8 zr=oIu^~XYN>vo#3dLS*S=-d4r?qP|WWPXB+yO!QVK)#3#r9jBIyB179t|kWhBpI&C z3zj!*_?D@La=#yN*}3`xD|k%979?Frj!!816`hKg?GK+7jExEBIVPM_AO5xUPg4bY zslci)(+HGxNy0{soZ5*Zf`1NQnXM&6MeL^^-ph71fMM${8bL5kGniPE7qO~({vv%Z zKN<%CWjSNhSzj+Cl&)>03OeXFdLf(bcLl6s*XVd+;e;8Gx=B-XDWOIITU4OsYo zV!*vqqvmrasKe<#_CBjfrVIORpVSyJO^#MT{Cz`szlWCAzk=6KY`^VZ72qR4Ja1dt_x zvTq8=VXEbBtX!22Z0KN}gi*yDyeZ=ebdA{gMvoUW5qH}Zh1|#`b+KX=Md&xtiLQTp zk*l!l2w|iCyC11~ff6_WbDtBD!*-UKwrU{pr9MIwn3dSva$W0x3&%ElN9M?`}T6ANNTfBL4A7uCsbQtn@ z7gf?zTGkBo((cUz+Q}!W%3oOk2I!CmLgjyDgI+bZUp@SsP>it*m!PH~ZIS z54EoLB<+3w%;Okz(!{vhh#7XQwZ9gL(Ya(z3Lj}}ZuZ3|8cebeWT5{6={ajKKen`0 z2YXZ0rM*BxE4P0)EuKF!8Ie&MIwJZ(Z1%XqUvXD zB9G(5qokXDh1eBe9VooBVH<%EzYb5~B`v#_R(YC4zrd!ZzJ707)%`5Hy<8Va_C*b{ zbmi`g;IY?*?{R+hhWwIWyevR(%}}4;=KcK~q#=#;MZEL}d9C$qkpxa_X~G)PJ=j!0 zo+&b0(a{q`Bh0VOg&yn(KjWgf)kkjp%o@JJAxc0^7TlLm{T9sbJP;7=xwSYr6zWh+ zk2sdh6AV3s^5_DgWthFg!~u&|4#HAhFavz-5&dYPBr$U7(>XwLZyNSB6j^O-d(^4A z>E^nko0>*y2=}2=2|9N6z}I2HP`5Buzp(&jJmoW0`CrL&<6%| zH`$%D1OE)<#O(7#ji2+(U}us))M^mhXO?dynh9U&&}wv2RNef@B>JTs&7DZw@pH0SQ8 zB*)8diw^HnTG&E+9wq_4vXr*t(VuR9U;8-O*u2(i zp8x8YXXzY9nv2#q{~<-)xqcz+4S^Ch5ZuKD#rTFXnX_kCt-ifM*<_Xt%zNcvSeQJb z2wV7lYa+DJAZaYNjz=RCwUjHgnqMob!hBp zr(}cw7u~9oLvI1O4>}B>BIt-Pa6sVt~4qMoUo@>Y&Q$)aV~Uc)kI6oG)#&j}m#i~W1AXrMULH6eluI3(&Fkd66~DOO<%wMR}!Z7Mac#s(#-aTx-Up zZhZW3!!$}G9>mVH+#XWE7Fq+Q#0FKLv`f>K5y@~1hMUPx3?y4`57P<{4N#T~?i>Ea zCS^LxcBy3|jRhxB(V(z9;6FkkNx>v35pRSV*WELb2#DFEg)LZ9I>>rA2C`55-!{x1 z>!bIaG)-+O?K5g6|G6Cet-pZl9$SmfBLE!Q&c`g_v`)DYNp% zyp0ifPN^=;vGE#HQBI}ki=!k&0Y3>3#3|LpgGlYEN71{~Y4L&0|9&i(HYq_BQmD0G zWZU}y+YWDH(bFp+t?z?vo(Gu)WI}}Xw4-o5OdF%h4l%IM__?{WPsN| zY{+Vgh)F&QD9x`NOth-kKy4%Uny}}&4V4bdl$YF(m01b)9WedZgfPUHcxTW(3wj0p zMR!&Oec$Yl)LVTa=J%RQdR?1g?A9ZkDSCSKSRmC-6xHm(Zp%A&qk0w`;NfNVmqjB^ zqn=m6V|85EIlq0yrij;bz;_)}3bk*|%MZ@qxOj%tedk+NzlVPh|N8VjoE7xXUN25) zUUJ~pgr+FSY$HQzcv30wd%JErx4*Um_U6K>E#v`TMuHacadeMC{a z)i<_`KA4iLn1t7mLQWYGN`xGw5UMC`!^6@3#^t);_VV)$qAJ=+GYLQDEBt9;x$d`z zNBHdn1dIw_3}0)e4G_330;4VB&%JdbForwCI_P1ZcZ+l@Qi)CySQRiA#}*SK`kcau z6C>8(P3|@@@zLG2Mlcfi$&eey29-qfjO%O+6tcdc@NZQjOvpyxG&qcjucHQYA4I}yq1J`{9Usq#So{K4brm$qlM!>Q{T)AiW(N)}KTBrT;B2^kR?$0@#ZvZde~;s8zjj-5KY9i2HFw6* zo||aId#%~6_^>~(CGM>Y)ZFtu7Cn6N;nsXr6z(eB7;$1X7)ju7e?nfi1*iO59yocWYUy57-x`kh3 z0?mjECi|)w)eWt9-+SPgWGViJc=Hs%GahXa|3rD<$r4L|KHfi!a2_te0@=JQmBL%a zr9fG;qKv#QB;%tb!P^P!FbiWBoWoJ3BuvUtaF@*W&Tj-ma6oR};rj+hLXZyTWWjQ! zo~=EX-cc0wQY^=~hd}MHzc)IoU+?8ki9+jo`C-YdEl{-lC{^%X_l%?-BSK0>RI`D5 z9EDx2NSGsbgETq`@qChEgygurAc_CiR~5^bzDWETc5;={d7aFYL#ssb4@YN$x@8z( zCG{UY4Z~pW9gg>82O^b?ySn@VS!FwE&xAEss8@+CoJHI0tHUI zKqY&^TuCvR7}1x8B@r7xt-|GwfTsgvuL`T0u8O-Q*m;hPee=Hp+N+r-}}uNsf05jOZ6{t?`gw zzDC#NZJgt07Gi@cRb6M9k3T!M;Hqzyigcg8>8Gson8$%0e`YIwQDor58OcHo6l_~} zi_<1gdc6^~;vP3qaGpbX1;0{g(7M?^9|WcwS|Fp-#p*;UJ`MO|M6)`x*Ddyo^gue- z)(ggh~(Dtmw@I^2R)~dB+6Sei|LC*!5Dywe?S$N^4tZ4U?~9=<-rfwF z+bvER{?)A3GWEEUUxwQMa!U=g7?VfTm>(u7Jpo!4sU%eFfV1SXg7ahNtB2KpXlskZ zqcUl^Bj3{6tx!3;{=^(oKCJx6Rgy`${}_@*(KQ<2-=9EW8cBN}pX*Gm=<3dqr!jZ{zt80|fNi(Ub6rA@OLCM`!>T<|+n zbVN_WML$qLlUyu&$?3y6CWa!8)8_dMr(iF2W@G0k3$xGo^}&)f!>L4%cnzVN0}?XQvV3zC<-; zZQ;74@3|0I__%-l#(C)(*fJG^;dYEm0b@Djf-2ypkD#$j1_G*aQ#FAn6<##cC&I{p zejKrzO*);MO8i}cXu-1W2#IeE7qv`TxZm_juk3A_SvG4y=f#9XW;}a_eR-FHldoJ? z0%KxDXc&F%lCsbN0z-zpY`t`nq1jd$A8xE*?(fT);IU<(q#x9-%ik2rW4E2Pj}6NJ zS=O@CdQut#H7MHlVb-Y_^EG4&5CR;91ar}C!3k*Kr`mU4=bv|rvon_>G^!<21U4PQ z;q(!$V;p}jX@oo0g$hq+O>AcIe76kwp_c0Egc4H8euf6WHQ>&@IwVx?LBCMTG12aq*Vs%3kLIJAyj-`@hH<4~<0 zfE5>hL5>5E@Fbe4Qi`lL3^-c0@&Mek1A6^cp6tcm^&mIXXU5+qa%VTT#mc}<)Last! z4?SBePbggi)FGFFnKMgskWnMynVK|!+gY!=w9d0k(&Na(aTU-$NRrAk?Z9hFffx1asGV^e zLP5ZJUpPy>+t_rHM*I;)i8EwP;+)amf zO%rR1pQ_e5in1}$7h(`6#o84L@LUDGBIo)(Fb+Og*EzQ{l@?tlq4D+Yd+uTDp8VDA zJXgif`S(D9=$5P6E`KT{XL0$H(4R+WtYvyEIKY?s7Zom|Z#^aBM(J0UBmtjB#Bwuo z{viaLHHe<*`R6s25-r<~`|EzEsNw8j-4%^K0pcGMJtBonR+Z_aTZuo?6S|3QB}88` z!sx#{*GwtC&fS|{Rpc&9XGrm9I1k|{T_slnc>aT4ez*RjhNqI83@a9%9T!OLi4kOgYtku0R*BwpV^>P^rQSv{(&rir4DPVNd3q;_(ZvqKZKCe<8TWX`a<_-iNS< zZLuw%=mZgK2T(O1I*yPf@}mpXqR`U zAnPOBJ)nGLc9sa}@&g1kVL($0snPA7|8KwZe&)_Te1>!14A^!Ww2v;L4O?*0w0!i* z%$vP;MdF(Fwb}+Cb>Et``Ea?QjB29v*MAY#n|?4n-Yl8nL{&6M>*KGYi>fAZk>~wO z&%_%=Rb(&EJh&VN)3H^|>_9TL1L2%Lq$HNzwERA+2h`>%+GCxUY|2Uen$bt7Jq2E0 z+XOYV>`u{i>MR%;p_k~*H2kYolCA)9@Krz4QE8tJ*S}f3SN`HhGh@|SYNX>9Z&~kV zTN1MVR@&=exAhaSoHQ=--OjOEm8YgHo-88CU)q(f0Q7f!rlD^@mW1;CVD9s=jA^FR zLFxh7ptV%|h&Z6dWu9hr0o#!HkvoM^73xqcAj_P;8tP^UpJTV`G_iiF-BfT6``G|6 z(^n6E#D$iuz@uUgp0!4eLoUOaR{~xZf3A{;|BTw-mFf8=1gReU7Ny)CQ6dpou=6Z> zFFdyRZa*^^b>nw?X>tCag&W(iWyUxm=Z*|Shuk)vmAv&%R~PG-7YwUJ-12e9N*01zFjU2C0Xk_3&z|P&5-;?T_~#-M^EN;+-n+p?_Qiq zR68F;?kY9oK4j9Xc~Pf9ngd)w{!oYNIe<3HtSOnD1Z(W1ux zf>Q=DxzzQIN-7b>vvPn}Fw?-4BtrY}wbl%2_N3Atx7Ecs257DF-L_F_~vB9Rxe!&gq_i*IFbY$_!jxcN~tSoIg zoFYD+OT5s!u-mLMc^<{5!IW^cR&$j?wM7qVoj5VEq=QB|vw$}Xb;*9`n}X6iTagTL zEO1WXAv%um_2=)_>?PG!!#wheGbRDQ0m+pjf(-Y|IRG^ca1>E*FAl6nDq8m0Qd>)cfmI^j|BRTvDz;Z3e zuKh6Ovs!_nxbH1`4+vc(XceBtY^~1IR%Fv+}Vq(^6NsyWYRA^+*=>3)s4Y z_F!43Vi?21`3bW{;M_jHZ1Wd#4fh)Vm-0^sw&wS@duG|;x#HpU0Us%*x~|_+I8lq= zE`$kP2d}!_bi)@2Mu+@RnqZqZ-w~vKU5gm6(uHOe1-VfLav=#1IM+O^y0Sv zJfz;SVOq_PI`Qj7HI1143#{r(X$p!rL^5Seyq0@}7W!^;_9^KHj3p@@|3}kRhDFtN z(O2n4y1S&iQ@Tq!1R1&;hEhO6y1To(OFD;U=xz{@Zuzc1zW?)_XYRfG>{xs6wLD;& zgV-D%q^+=hPauM2^{SKdku`7ZulJX_chvm;6VB)VWkzSr-kV)YzWc(ed|Z-5O%CvX z{3km0COM?VAo}YZ8M(q~Sw?T3H+)Qm4bAaN>H*-GDFzZoN;nk5|MoYc<}#Uf(q|de z8wQ*5oPa8*RFUC(peBWeL(+tJdoZyVPM^9z?j>p_ zdr7LRQ(?sTsHYfmSjMRb2M_hqu5-}TdN=;p%zZEifFZJehKZTv8pHz0o_5?eg?{qu zy}f3^s#_Hzi*5ujjJ1f#C6!0<<>Cm#jtbpEaX z)bxJHrE!}76tJPL2L23N+h*+kD{X@3*{gKoJ&!H4Pv~M`s>kPQ{G}4rV|ftlpH#_P z%pq%NZ)9e(8>V&euMz!@+vP(^XPh+%Yr$P^x80k zN#na-1H}!_!$Uj&XpZj2nUJs^?~BD;rl+!u?Ds4`RTKBt{=imz-ElicW!$P;j!7#p zrd1_wR7t%jiF*gv4@T!>!e)K2>UM5_imEVubqF$Dy!C()!fxqu%@A;y32T?N9J+RYFtQ5L&bk(ZJYZ)EoKN(L*c*B+c#JAIwfnJ~ulf18b^$6bfxr4$ z-t#k`4cDyvJ?T{9X*XOgRywWNurR+l*x}oLNtv3`2_#uF^E;Yr<3m)ItVu5!))rg4 zLO5u*mE>#PN$AFb2UKzWBDZN$|G z?!h$Mg-++SvTXLHNhHy&7*EfczcXpbZ=OJ1qOEU-!yeZDa~{&?zvM13P_)$(!G1u2 zta>VH&UFFP@DUMGvg1;h*$*agQ5E8~ zmG&iYN1c;IjMh38DzA;7@&u9;s1WT#sH)5S@jO*UU->EC{%eesDLT`Tv}~_Z>e0fq z(JZJCu0bc{;F@53DgE$4Z}&gD5$QodKqG@1K!fo_DJS6XwM9)M)7RlcJAe@@liYN* zMLTS0iu3@Fd-h<^6g8sbP;UY&?qtdD8xdk$KIuKD!yUM--JwSfCEse{r?GFR3b@mc zCBcJgl#N*FMEGUw#Wcp{v+s5>`f-CP5Svi0*LUqPE)Pjp{-QLgMs!LJW_ENn+qg5n zerk5Yw!xQu`#sWZ>@Gt&SZn+d#TAe{NZ)S2& zh0sZ7!KHp8<55zQSBc8eeS$|v$dtX3iRsBkSjmMol_dX;`B%Z!E}=tq61mlZJ5A`J)b@FwAr{#NlYK{b+u7R z@}~8_rmwX{Ehp&?%_0$71BU=mg;!;4SALhqmWdQ<@5L~ociHVMc2RUa;e2^Qd*HP_ zE*99pD~7`Ro9DegDzoFNL$$|p5whp8)BA_1PLTNshPJ=S*u`#Bg)$9!)hmI6@2LzB zn~>n%VA^SzPLH&*AYAI@Ryl~@8k!n%|&!D%5qMZ zch~4ShgtOZ+xD8_rv-ythptIpiw^Fn%F2DpTwru}-QpK?sDgEo_v4(JWC#%Y`r2feKy7F_H_NyB7b%Fk+AA*)+1Bj#5ZpY+bwW*K(lK16zc#Kg-Z~YN?>S_a zrFErtHoot6P7LV!$V4^?a<4J-XRi--5$)&voJt|XuK}z%wx4HsDHk!fKAc2F?U%!U zjnnzU=Z5Ls)#4J%(;tOOvX^O180pANu7IUos$mg|+1$ReZ!g;}pSSQHaHikWM^gve zAfHG$KMoPDDHb3{`OM6>0W`!IC2$QZfeh|!m7Kx(ajG4E%fMV`39@mESJtNmhA>h3 zA)_?~53=^c$o{TxuTFr9cKY;+nr&Y&($JreW)&mJh|?;5)SK=?>Zp2 zbUjdV1vJKNjy7v@TJC;lI;?t4OCa=y(`O?Z*u~ieae7UgEZI~HbvpL=#otRu#CP7G zF5=5X5y9QR9q=7IP4}bo+|vvHlT|YR)4PVDG&A|^l)VhClV>bl$;+d zl_)v_q}(Wfy6Wf;&to9|-1jXi!s@n%?kTq(-@D*1;98U(e>elm#t{&x+_*Ly*CIHA z$iDPuHZUbuAklwdGFjfwYj$qnce70x^oY%vTMyTT9UR+|pDG1R;i}_Wa6e(N^P}Xr(bc zjX(RgiAhcWa^CQUm5Aopd3rrIr)2CxV21JgGM{JL4!mZU5=@-#d#B5t&TQamSDtou z2J}L%TUv9Svh0H%{-HFeO%wOzi{tPM|G~6Z!;sg!F0BRFZ`;;B=dNE5ya^t1m_2}> zEK0BmcN0;8_;d}>u8xSh1a%<~*;R#|>r|(^;rg2I=_sSuIsfU@x}N1!dHQHHSu@6=YsMvtK@b(%^H2U!u09jbnS;dDWohEpK%%EH0P? z0F#~o>qeOuiqXfSXASvPtPijBJUO2v2%Xg(6lR>AT}6TXkKk+N0_8TH*kz>)>_#|_ ziw9vCdv)W#C1b34SmdImhV95)-y!X^07g*wy0Rkopwfi^2^_ne#uV+PrFk^>M~b3dE|IiW!x4S9A6G(pDG9 zCE{&FjjF9i@Vr2l#i?SE_0Haas)+W%n4&`vT1fBT=L-x#`L+J%*gv+m1ZCcj4>Rze zFH|xtCSw3~c3?gV;dkSl%E42{<_jJ1{li&HD4-gFdULv1vsI1OZP$I*RFk&bv}lZS zFZSm@U`BFIc(m;>TM@knS(opo+yFo`kPW@}lX5pVRarYw@7ByzQ|}z&?;U-28IHoQ zMD3Q~4<2t%q2}x$znd557e}RZkP0B~i@W63!1$)WxtQ#t)c}WcYxW%VLkF+(r#6#1 zd-+u9OK05|IdlVzCFJZJu}Q-Xfm_yxe-e8DDDQA?^g5(9-Qdbbuz3>YS|;Rs*fx~Z3O(y)HEdjvjz-;W z`!6FlI#APTo(u!xJ3@fI_Hcj(cTcUc+jr|ziNOb0GVd7=YnHEmdG>0UpfD{ngYc}^zGXm!2bmz5$da7zNf$FcnyiFO_{QX+ zS5a)_^zaU*C6vQ&_}er$9a}c4&fuerqAmR`BJOIKf& z^qKUcscldpvXLu%E7&=N9ZNsgS3lr-Hz)8{O^Ia8nQadS3pUT4lFp@ZmO)brS9?Zd zKljt?PWoa6`2E<~AaD0K?Q>c~h1vFk=BLHtWScMt(Sa}0;oj5{@v~96<_AqoaVQLL zTI#!{x%{mk@|< zB~?=KyX|(Y(=lENV28)lsND$n+AmG=a@|q9xd?qLZ=~*4z8iZ|P~^B9)xe$bnam7X z{?d>*IaLJr>B<#+>5;BY16en5Y{B(Hw=p{3U^pf-QNdS<$e+S;GI?@b9x&>LSu{ODww5pj`hWo)sd>_ zH|-(_@H%xe|YWIl6Y!rstSEqY<^AT{x7Zsx zX`i8vP$5Q-h2g!Y6s$B8N$V_aKCd}#n3zy9Ly=9uH;HRkCrM1;^ICDdL=!P?I~`;9`;+%lclf(hGQFgX5+k#s7WjJr5+ zd$O`-jUeV~jHSx6FC9&P4I=^We3WkWo?^E!@?I8HCA`0A9Y~QH<<$U{&uzI!H~LR` zM|YT~eZOsTarPh6=e!eLX4&R?Jim$zKa3G4TEba?B1n~0_xR&6)ZBlg?;A;d=hX)} z#b~n6WE%B_eT`&#Q{lg#`&C4>H#Az3=N_>bY)9SCNsK;blWKe|p`jX>1L~iwLBqbNB<5m`X!$DQ;U~qgY<4nwuo$#+UsYkS0S` zfC8x^m&h2HAJuLk}o9k+#f23 z#>mV&blL=6t2uBS!i z*+j~P+>EXWiX<)z-CQJetFsmRJOkaSXOx-*=pkmw)|hNgpUH6HHp7{1h-sHL%i)y5yEuwD z^*U1Pe?B9*?2cs>1WP7G|!tArg#c5%#x3}sp0W&k`mbr zzK3VkL^p(qyO;&OF=n0KsnrZu?^@+_I=8imz(p<(vHfKKPqaXaqiy#pu$iXhB)$yA z8fRvc=8U3HW2SygQ$T3g1VlmV(N7T8?Np14@Fw5S3mlg0KL4hq? z3V#k11%(R;5&oO%;6#}b0l39C999r4rECQ6EX0Gb`E|t;EdqjdcIbI zH@y-<40Lh%i+mFm%{2Q<*rMM>1(j4+m>%K7xp=`Y(w&t2T!i;;yf8sDi$XU@Q66Zb z398L4xk#%<^ccd@W?H@;nG|eX7pL&ojw;;sQ8O&drRZ-Ps^Tc%bbmkn-&E?fJNNm@ zyhtq|$X&~MO@ZqJ2*8^War4YL1z68?ju~UQi;)VYGx~2t32nd26;sR7t8WaKxO+vw zC4ZS3Low>$i5zwDk}Tl!)hPC@C*fq zUw*sAzqHT_cQs?1*+ISHqBc~?LQ6O-=TICO*OsLP`D9_+%+kTZ`Suu+9c8~_pzyH_ z=iWDz!qtBy6A;bdY;^oSF962Fek8rX6q~hj3&}2`J$%4A{Z#oqGV3MC1Oat@?*nY_ z)z&-CqT)8(Y~;Ru!Jm;0LoN>p{39{R?N<<)YN?DUBM4nJozkhzPWaQ)@}D!>U4t(G z?UCL;Q~3_|u>IcnD3j50vs0#GhKjgr2oUYSmdJ-wI+{K<36}`|WYX)b3xUn*$#kQ+ z8V?151k?pZIgJ=Y3Ylv^}8x7;l^zYt4VrFInv`2~e8y z{&OGY%^X7G{M@)T`CAo29+F#%+38HLatD=>^a*C=c+`m`+GChP3=-9!W@va*APG#fi4_;t*BOm`k*s-75xi0Q8bhgGKXGw;V zlK6dqkl@q%+aCuGPMEOcCa=B?UeyUin4MAj+rI>aK`ll$UvNH7gq3zq|8~V&Stq8t z(4=Mo{cbWu+kkB9_b;(NX;`keO3(9+|93c9E@cWiHOMbIit=L3E9>}HwqKj2UhRt7X=B=|Wgvn=1WV#N*4+Cf>V`m88W^|Q;`>}5q z#cr0A=9?;-j8V=+7atcB==1NQ^qGfsS7@yGOh#{J+v1&CqZhle&iJhSZPX8e3EOdH z9Flh|*0h8gec~)UEzNwY30SsYBNV-sSmv3Qs{Q2UzQV zy}y4(Pjdn~(Zz@8;b$lD=s~?iEOP`AG92OTq2tz84zFRm{<8FjxJExIAdMRrg)fr6 zYiM2sy=$%Q^f9@UMQ`($dH_V|PcHyHUkZ^!fvHjJ)Af3R@~YRM-?vU0!iNlV)!onD zi+Z?w_Yb=((Wozi~Yjhm!ng3acj;zA=YlvPLCZ0eaJgjBTZJ!mo#$#mAaV`Nn=fhu`$+qz&wy z=$Isj-tZimWgMKlv^DFC^A@R29MAm~2R97cCaLY|j3Bb^jcG{BiE!m$wL4Pq@96|fqdDy8|lTuS+cg2N?a zqHZLwq;#>ds4N2|ymll(s)#qSN28dgVqdXUeh60b{@VM}PteT6?0TKk)LxGAjR-kT zOp_Klg9;Hnve;2>htRPjl!ioZmJ){q$Avj#efa=Ye@!gQG0at)yC5x^`jGX=E}qKf z8CjvPSIH(6J%T1&khodjy|3CTC~1BB)ll*ioND8;UIA*8$eme3Q-E2u6Cj7Uu!$k| z;`Hh_OzN4rKkRn?(w6T6G2(K01G$P`C~iJw>67L=zUmixQ%f|(ULO_2%=)EV*utd? zR+OHcy*ysSwM8-Q=1*TsPd8U@wyMMg{BZ{FRZcRpe(6>cI2X2!pmhhAf3~mFoAAGx zkv-~uMn1Wj6gs`|?D4tw)sgC|J`&!H$y~6O5UOgut`<68cWu&I4yXDOn5d{i#AA1x ztx4FTrSa-fsg?66M>-quw<#|6q|R#Tx`ypf>#^ut%~y9IG@yLG(6}WW!upf z$MeNu?1J@htW2vu`{j?tRS>VmagO9XamN;Mb98_bdSF{vj)X9xOP7Dp&Cihy(%U^3 zs($g%WNIo;{BOxX8j7gzrc>VGzHUxk;_0x7@}B4l&iOND3Nk3&sS!vnHuJuKS*+@V zLg*BmLAvIM zlpN>Fdj^`^2L|08zfo1Hz9>DgySY=moV7PMC_=#=v{ zUjFKiB($)XpZj_SYQ!tty>VveQg4%u;PcH}tzLf?AcsIR&@p01J;FdjKEfrc)0E}3 zK>LR5COsOyDs+UO%15_Bt`u`ED}$G~IsM^IEi#EYv2J4|X~fS5ZzZ#c-lov^8)T2= z0A9kRkKF4Gq4`)7$s+Ig^43$OTcG&8H;q{o)l33F7c=p*X}g3bbA%i(WJLdX?wb=% z4)GAEl@2Y8ehkAJ%5HNkBUt5{$Z9_Jt8sc;%Li<})V`IKBR!8_5+nbEmL3TBhji?hCc)Lm7ZLqWJn>wiB=iePm33f2Q|0RhbsvEEw@CK9d>#6zpIV7@;!uF3t zUO=Y7Zi1?)yiT=Yp6z1w!Xcl-T5dnxg{rNY-3LKWhuiz=g{gwij{a?D&8sV|^phvQ z>ly?rTEW_m^7DGK3okuq{6votbkIcSQXR~q?FMj#KlIP!ZN@6AVQW>zL~i-q&vIk; ztZYFo13UlX60jK*(7gURCwe)6eFKPoR^?o{-TA6oN0=Qr4FQ^WBZ9g=T1FRq8!TfO zU$ZtpCp~)R^h2)w%KTAA?Ilke{r^5z8rP6XG@iw&UsER&H`9UM4 z)k}!?uD^6~oHnDh;FkDZg*RNj*4;k%YcKH4#?4nO;_kmVmX*&f$lo@EEUeat2*0Uj zi@fPfKF$BM)v39A{w$Jv(p_!k8M3d$9L^@6GEOYO8)tamS-x1TTE$ScSgyiUZRo9Z zTh>lauf;l!6a`WPYb zkx~AsB1si^D$e^~dos@)oX}gZ{%{pr$hG`2RedO1K4-vp^o9_%#AY`t^J8*BoD0&^ zkb_w{g-jUY2Hg z3nG#-ClN-eL}2^O)24aos7cF&tAuX~6|zrV4ntgBu9g``s%!1u`*H1~SxT~6m`XT# zRpyvJB!n)b4e077^xQfR950RZ_{m7pdHaHAOB&4YbWeZB!vFY=pa4j;b?Md zU_)*IXZ*mUZc^hHwb!%v7x=suV|lMVeD3L#Tr%&1ZYJl<9B{eWnhwk)F!x3uLmS0D zg^s()k6!HQNkx;ext>y0xsE&jqrZYR5O438xgktD&5p<pJ%p|MRvz^HuoS7Y!85=o?`>zTpqmAqhDF6y-r+lyIx&uT1 zQ|{kKl(Kv$>F#7JvGnzPvZLIRA#hnG9`H7VR6Qz%*V9Z0j3r9DXrXq6(@WSC+Puc+c$v~{TJY2Aq2g3L7VU_(Ramgi$Sbw5spA)v^5J|`rNUMOW7ilVSg z`ZU`Ln4Fl3AU!jL|GAYof&Gm$byz7TKq`5CvlF+u%4J%T*LbXKFdFOHcr2Lld1IEi z4ky(DJW9Qy)fjFnqMAy{*Xlfuf%!vs8X}P)4r+ym$Olmnpo61@zr?l>bYjQC3=$7^ zqQ5s%0zNzDZ^S+07Q;h9<$(5?6v~sBV}?y$X7|HqB$ni`_intJv>Z3c0*?r?ux?}W zy3Z-xHvK6t;im-ELAeKX$ap``AuNXx?#A`;S;RRq3;TRohjRDV~USfh1pk zp}OvISf2%AAdGYm&p4Q;JrNBZ!%>*HQYu?0f4}#Kx8|4LkG%3AA$KYl{~u>tZK3Kf z8g({xpECOAIA@8Qp(_H1prOrXn)Kz}OhvA(eQPVLXw+`v z4)0rJT_RMByYj|S0)Gu(kM6xlOL+&3{66}W%>M->`2IL{<46gJwt=L(X!b?eLma2* z_T9_}2^6l}Ehf%uPtPEted75aGh!(Wufg)iz?0K%R5p1{?^w#mur>o^{FSpB7`1%mbs2Anc%J33evlzTPMhV=i#hkL={Tw$*aBLW!BO+{=+RVSBB*m6fBa)PH_zXC6Ps8S`R%UQ?IKu}R$0 zDpKB)(S)}5DI*<)b5Tg+s)O5MDmUZ^qG~n)U?+_jlF#2d4-uhdFh`0a0@Qa&a{6*$Qxuze?!1ldwH$0LU)%LBtyO8dOR4ce% ziGnXW)qK{2Uk2bvZwTT(s7ve`V0(6}MAKlzelaa^V98~@CW&2wlMY|DHP&*`dQ zujtapS*V29o|LFyR4S@$z4427ZKmqT#a2;67&>qbCL2SAoZgq6j@UtSF)&~n>CKegVaYqcW zkqZ@56i?|HU2%$)I^9(pBeN-vDf!UkYIZ%~#$mX(FD=}(&8{s{Hlol2x7abKYW?lK zC*DPeR;`V_I}7dz4X48?^Ui{l@lMf1VNJCzyKo?8h}!cbOWj$=!VlwoOmP1F zBd;D*zM;VROj?mtd~S))k8id<>sNovYF6wYK2zsAzpNN;E#Y9n9!I@{5#I9xwp4ktNE0{eqcO3;_+g%qU-VLA{Gz^VjnMLs%rib49yKdX8anrdKtWJ8@#d79Ex@zZ@q?)hT#78J?}3zymiE z`ODuWTP)=qdiV=nYF=A@Bcd{9)7ve)B%a>C&}b8w3Sj~`wuWkya{3s5D0G$?wDqkP zJ|#0?z~{WOc2swgLStJ4&nT6()jU^f_+QBT{SMS~0Htxcq@+GnipFaI@|GV)5Tc4gy0Npf9&gw8UvCcP6bJvXiS!^9NT=@VW##Fh;i5t$fnFFdG) z3C{VD)yA-94PQ+7aAdrOi4Bl`mc|p z-kOg*CeGPs{ljGurbLUA%%;uke~_K;2@sKqtm~JcTavbAGc|jc_zM);RmkGVb^9rX zjz{TpW^2KlZX(c20avmnm#lfuFl1EgYa>B~;TS^{RQWS+8?bfFZ|Zhm8D(BmK})}O za;2`HCB~guCdN%6GD65YM-_m#f&zMk0PVq6*3MJ;AJ#XZPbCc@Bb5GPjtuKaNAG8T zPo_ik@Rb!p`7}`h#~z3NVVmE2(l$;CTe~)>Kw?UA8J{Px*q(ohEO|LDVilQm)viP! zp?fws2xX4CASts}lG0NoBrYox!AxAGLHL99EBQT7K2ut@j*gzGYQ0gUO4&_Jmm-di zDNGqC4Agt3(4_GpO)?1GG*85-D#4m|5!N??_?%%x6pPC{F-AMib3<@ep!5? z1s6d0+uGU=zr^cE@6=U%hPGBJKWp6g+}-jxuG(DN(#d>{{QZc~MhqP($dOAVZt8p> zhz`Q0;4foh)*^k`F;m$MlxGRgu8m*sA)xmzgLvsTAF(f*5FK@*3$$ zLe=Lyi%Hysjz52<`YGmP|4+_zmgqVwI)^l>kxoLhKykGLp_Re~d#W;aTTmm|r9_62 z-yx6_EyMooS_CT3uxor{7n7~gyab&=^|8+8ykou%&k8YrOyRISU1kxux5N$wmLCz> zlP_e3yjc+xH!Den@ktD{GvT8~izaLTy_&t{ANG3n+6e|7l=X|*f~L$Mtv)C|B8eg- zgc%Qtmr8a)by_?SuC+ zHMQ|K2lQ0fK1T5VXYI{RlY71%F=Z;y8pk%_l9+(aI+u5|;S?MqSEX3oqODo=D!YN1 zj(qc*#5)hl&o)(cbF|j}tLuv!CTxOQP}Eu^&lz8CAnm&s>$$`{Gs(oW`Tpy@^WzEK zzp7Mrj8=MtqE%t?{CqR1-K6oYh@0e$HN4;dm=Nurw>bng;82e8rnakd!}#3_*sPpl)vDtzAsH7&9}2xR6I@Bf;mO^6^rc{E_bbc2wWCEQ!gGRN^@*VQR= zz@kceOBs>*-pK`2m4+qI9)>=~0T@m##_X?$H46%w3N(AgmZni)xjF=HZ$w5i-owqO zA64IarXp>F=*xRk*fFW#al270ewF#nghX+Dx2{o!ewEOvcw)OEb!^54Q-#-~12_q% zRPMVmCGYvH2GdVlB(fkC(&*V62S6 zqH3vCWN*s7CY&n-+V0s{Yg>hyLR7my6Zho#%E<*W6dSo$y948ipXQq1>0UxA-X{Dn*EAXSdQO@S zwwstPJ~Q>6e)CLBQ7~G;(yt7feq`b5m zL09?vRS@mMN%OP>$__qg0<~Arce|P^=GEYlo?}xn*xs4x?sLPMm+>r;I$h^!rSp0e zgdV++kahkoX3atz?p;>Ga36*A3lHW^(KGTYtnXsl5N}6(IU>xQ24Z}qm4SuKax_Ez zOkd3awGXpT;@s(a6`DrFxt7-WVJc=T8~c!fAfZEXP%yMICFbnvrUzf(F)cb1#vtq7 zAtWD&!OWiD4;3$W=!3}g^Br<{+=}#tY6@Wh+5(_e_^r`^)}?ih)9O_|ls;EyWw^_w zl22exQqRkOIFVVp(c2ZD(Fv0TpHIEk><0GzAkSs8s}x%;7^R#uDsr)6 zhvN}A&S_@7=G+TBE_M3ul^82_Xk9d$KQ3#!+aH`_TyEv&_zb-1ri zQ9t(P+6fMp=8t>KjRq+zy5U5DH(Ysq*umK{3<4c}7OUE`p4L*sKZ-@VJn~5@2%BJFiFM#zL4ak6!Vmc%TCCWX*pv_9*RM&1a?p!pdFVm3NqD|9jS|E_zAGXghSFeE|CkCr0%4+06noSI@tk
    0$OE3Qi8&JEgpdb@KybV18ux= zg!-`KG#^lz;59An7zwZ7t)OiaRSl_NFXNaQp_S4FP{#@~)hn70!D^gdT;%m$Az>Vg z#_G5}EDghd-7G(ZDmH?}uBr@v3h-+7nh9AM^7>fio0UE%%_OxSw-Um|%o`*MSFEP* zfx8D`f>3rkz0Fb;d&`1`M8>DMc3Zo9U9brF2s@_Q}6aT6Ja_O_P7fYb}s(IwZsQrW1UdbS?Q zXMTkW*f4ya-+bx#ZTnYyOoK^A?Rs#HvPIs&e9pIMEZH>H7*zVJSCE;T5AkF?b`A+? z=?05my`f+itr!z6?>ieSq(XY!l50u|E~hx4d9(ku%f)bL^Z`J$yhd09psT|{1w-aN ztS^z~Q)#f85(WEIYW_2gQ?uUP3*mz{)fHeSbsz-`Pv?jC?6g%ca<{2!c_!FbQlaBq z=Y<$Rz;H`?_#KlC*)BK7rqO{_G{r$&PKIs zh!SSz`;B-RR><$Eh<##f&L&?n4Z4p;ay^MHZouRwEd8L$p(p%CI;xNh*nWI|YFz*h z+<<3T8Gj7LZlCw17xq?=A4L%}zlyw~;I{+%&rpd;OxvLvqri4qb4iRVM$EJE5C1X` z?%Z=NqPmeSbIBN~;+DHDOjDs0aedp7Y11NJmMh0RN|Ybow-n}akvswnMh4>dKco2l zE?g>{3-?-nF8l%YhP`CanBOYT;1*odAwN?hMt`?3Clj8s(h}gcCgp8d>o%GsKXi0V zMq=mNU|7LsP9gh}I(bajGeg`ILX&ZO)owneC%G1<*yU7c6zT?aq3m6fi2FeT&fb}{ zU+lZj3deD26UEpVkyl`+t|o3gN+H9(3n6x!-r35wjyC{MEOFugu9~JT0c5&% zc^w#mgF)~zNIx@PDs@!^_E6)UuUbLDACEErg`WhoP08ZWUit2Y&B(o-imrOTxYrl@Kvvemzg!w^=!p(TyA1Zpd1t#( zR-)w+r#LjO5M!<7#OOrFir<5M(_cn@4jP%_Q~){&u)V$%&!0n1DOIP0s&1(pd8z#( zZ6;f0vY@~tVIuwLa?b%(&eVP=j`~BvPX@SAgMQANTdMMNlXyYsm3|KmZs9+np`UfA z+Bl2B)?(4;$#MRiH(aI#xJ70}yp?hy;DC z6|C|%#}z!sud_jj(AgrDiI!5uUGp0%xYA6ZFva#bHHW* z?k{V{e7&n~rjT$l1ONgHX*MscZR1)26&a%Z?zymEEuwdL*8fDUsA8vzkO1s}xWy}} zxC33B&=30Od+m+aUur**4K=gnfijB7vIzu>1*A{VBCYPs_3H5oKQBS_qN4Z9RIwr^ zkow98sn?%%!nxq$BJ;35e*mp4+ABdNMhJgFY29+F4GB|6RU3dEzA=^7!}l-FSz8N@ zn7s1*I-16n+zsJ%BCg~jF6_4T8EH{D_B6M4RV>*U_FESvK+lBnFn%HcAna4>P}ZXSGhKJOr6UDz{`MZ_6##WOjX&d2`5GmEA%E;}Ng$aFF6h*dcq%JA5c@1J`aq|~Uc50#<9HW(1pvhi z(*f=w-)g8Z(0{JA^68gJ5@o(W>Q)?6UjGm*k`Jz^NJXw>wtjGEKftNf^^0TEwIAJY#(IPKoH*P!E0cZ+#*cg( zq`%Fio$o27;1>owXoJbEQa$~3U%C@p)JtE}*pa9f|~c% zPe2qyR{DZPe}|;on&~Mp=u?bl0|OHdT*oKMyEYDf7GbHJvPV1S$` z-D`VydV|OJ0)edjwaLb35e5uaHMjR7VSGJ}2d`4EAGb< zH=a%eP6xj68m!pYL1R}Ly61yUEB3#k3hN0`-kjHTECkzx>91;J>5y)5fUNchbLxD< zTk6eF)l=obMviX$o#%(ec3Hhtdu*kuvGuj&M1h*Ez*f%b=~V|WN!L`YESp_p*FW*-Sv5vuUJ;GI0r+OYJi`ms7vtQt^>k@2`k;RZ`*_{+vG_i+MRwk z|0BXs6CYlhbU6vonC(CsZWCDrj**MABx*g~RvVMGZ+`KXiWtb0c|=pv;|Mm-o;vN( z{3})hkx;W@^sm}Dv{s*>wMS@G77~l^tGcCLzr4o;@4>2$d$^tK68Hr5ZN3mM@U@)5G%KgL0R5=%Ss>%t>iNZEz@RMagLQcFbo^BNRH!H?YNn(s%; z|LoFxHDk6{J+ee+n5ZiNjsCWQooJC7MDHDon4`Q9^*$kk*}Tu3k*nc&ednW?c6&J(KX zeg%|*B`}phM}KyrDj?3I?O{+eNGP^@=qC~1vCf-;xFoS~DCgB7#(qW<0U_oJ0eWCR z1+OidOb4@u3{>dO0#ZNR&>1%CN(da|=1T+dbOAN07KOL8J5t%1oB*}%N2Hb;`OO$; z!P#8qdAu!sESr!Zvt;JTUHFH`2y2EfX$b8xPvDza1?~ys9PWv+2s3J9e?CI}W_aSK zs-du1pgPhR_#a7E9oF>wwQW>NK}95`rKNKNDFFfL5+>5!H5gM65J9?Y(%mI3ARVI{ zCJh@s1`gQv?)!WH;}5RSuIss;=bZc8=RWt*Vq$zIsj|Qo8ahO!$=4Z~6va!3H*th# zswyTh1Thqp(1^yE(|+r4*MV;`kk=m7xASkvFw{M^WQU zZ{fRYM&qpYVq#Ecp$(;R5L~DwLTdTVc|2GsSJA_S{%Lc42HQRDB%(>txoSN_CSqxo}d;o)#rYpXWF&0>~Xh;V?&z5g!a&zI!)6&wY? z?R`RB7(rvoJQOv~OsTPj%9|je`KQ5k+5}p(`D8?xE%>89ky7lk+aWhuQzoq(xSfn* zv+DmO$@Sk?D3WiMSf{%lJeurS)lqqbT$k;vX{7U(;>$zJUCcO}B46i;wS?+ZA`D|%*R z`H3y{+#CBD4i&4i(L|+*L#Z@BPq4I=&5hDGn(ES$PgN;?dzkKyM7Ot2jvdGnee*U9 zx<_paGfk{ZP&=?(2i~3pl(~Iz*hy%1)sg2m4fVEM$c4hdHOFZCFXrV8xt%k5$!271 zQ0#J`WMNuYqkIsDIt8}#dv&J6VC)nvYY}VQLF`oj3G;uIwDi3S$RJv|@Mgu#uEiJ~ zRm5@i+?A>VAJ4;S#>%bufnxu&>y~r(4wd z5@kISFvnSSo4lPJ>ukMC@8QWS&9cK*|Dyc7ltkXm%d6#C-`EdDIu#|Sd8v1s5~Aw9 z*>um*CBxrq#)|AiZp#;r=e}iE*3cx0*es!$q2wD69l1q+U;oM0>pPpj8}{M43K@P6 z=#OqXf9LcURBxXBu0wE(DorfJiG1Sj5OWOHNf)5&@6nB+rMy&)8eF~K?!$Qd>8RM4 z=tGSAEeq2uGDb1;BxdN%^dL>gbNSD4G37445ganJ$qJO#*`7jM*V5Un|J!ilbH_yG zCAaUuPxtwF^mgYD_}h+`j-m_Hh-r*75(aP@Bf)h!M74L-MvR&$4P-y`_Z{aJOOVY| z+OwA8aaAX(@BhB7Y3m+%Wk;KFXUzH{^Rs3Z>O5N8Jfd0wT&!DSHKCr;@0pFvAur(k zNxG-1%($Nj8@PykX?)aS+)=N1-cI{QfFV8SCtVExFRv4l6*30fBw`xR%h}o3Ic)Os zON|Kb{q$olA!+F7jk~+aamDK8tv{8)--h{HeF#mZHI!d6#8 z?S10|t0(`MNqizIfR2xKu7KXrreD&AnE83h_d%aae*lAiC7-{-5S^#od5tUDI4=_VN7qSy|i`0Kr%cnQ#Q4N1lpRuJ`5yczT5 z`XjLG8=gp=H<%UfKsXQD5l0|ek-Yh+|tC2Ij z^*!=|$|HJFu%$t$*E?q0J1Jg2yIAH;!~t@zC?6iG)gL5$m*ewvQ%{1bHiwd%@*qH^ zz&uxq<&${u%ifmwr$&{7!k|dnY-hn|BH{B6HY*#^C5NM-%9}~EK%PZ>%dP~UNbcK0yt!U#`cUg|7-!A1f*WEWqlFY?U z1=yBy#JoFgtxoY(KHoH5yyCJ&%x??*h@{pus1;BnO-FOHnmSP$DJ^@PY-*AFwCUG1 zhE50lSgfDP=OH*N4B($EXkY8de+@V4|!^qX+Zkuck4&B}Yp_30B+v|IU4 zNsh=MuO;?_!lh{vHzt=z4dvN%_jf1TjAXB`47e^cI#%C0EXOR5^F0(O1=y6Ypgm?1OE8%AO!3e-V5iVQFCRg?KNNLi$~9Mtl>Wq6b;d-3TUK|9&L- z!Ybo9lY9+xx21FZc9YM41NZ;Uh-|Q#^o_f-S(W?SxeQIy@;9S~oggq4%I!)abHW@& zS4mk_N*bfBZTj(@u95$ebn#eD!Jjy;0CD)+6!1MbKQU4yKajRC$ZRb6R*lf}Z5?=4 z7s%6c)mR;+YesR;-%n`Zo6=V7R^6oFz%YxXg~1|~?R>18S<$YE7lVVbM|YEulZj>B z+;8oT+P(k?^(>Q(3K7DqDBuQe+up8XozRTmeV9ynN}E&T9Dn-8IuHG1WBjWJ`q3Au z;rg*;aYUxDN7!o&xvU!9O9tanmvgMp%Q~M&Sznj-_1Z{h`YJo%1z|b1%apH~tt6?{D_oB>4^549;k!xOh2-JL}hHKdRyBt(ABel93HljN)YV z3c!wvEx)uj^}jCHiOE8b8juzZ$099}O*H-)Ua7wHyfnkM?4u;Ii5b;-BegfxoFCK9 z3VV_Nk9erI-aIo2dyE~s+n$^U=aY1GSUtghyVDT#nqm%GzL+V7*P-R?c^|ea!FcCt zgX7_i$$)4w=UeVVnNer?>)-Z`^LD-wQN6@RncJGaS>`mw*5&*Q=rlFifeRMzpEB)d zAKokTk1%b8kZoA~$&r~5>`?|h$e#hv4}{2N@{1Em%WQ?h@b9^eznW;cjK?xB58y?hs;sbxG`F?1p?7i$Rp*?P2G%8ypqF{A<_SK^3@Z za>hZK*KgGB4h`vj@R)wbu`SEnLzTBGwA?^H;d79iD5GypEL7X>vk4F$SSp4 z3$Z7NUZh{!6{{LVM0$SS&cFT8|1^SgcZk@y*dQvfCx6h@R;6xrQzm=vj7{{GYOMMj zLOL8${Iewj#&{UZvN2_IVsJ@htqk<`1KQlYUkrf;MKhk}+CWrOiPTI_#@`4|*w6m4 zMdVB!zK*KZ-SRD=*|q#+$kSwt-m>4R1PC+VWq6$thzG;^QazF5W!V zmzK<`v5P{iY2nYG{ZI~D8lT~|5I zvn2r?e8`tgf9z_eSeJed(5r>8D!+XoV;V@s9(}IE>N^{JKnoYv*bJz$9b$aSNyOBn zbi{EK!4(L6<*b{gqZ$B&;$;%6#NM;V-L%Yk>_m0)?Mz1KbsOFK<|St4)A>dWQ1b{- zmUqPus)P%Sw8VyR*bMSIa(=wAN_4U8VaK|$O5_%Ixy;fsJ66bYDIz;<%Yc}k@!o-aZHH9`0zV<15wa3XTQ@jGK4 z2R&c!6K$c-CPK;Na#l+>d!$OYu~0vp3P!=SL^ir5IkcLAovJ9r3MUnLi7g*@8VogfM z_CmIpw96@~#N_*w)>iqW6${ee`ekSyHknx+C1Cch(C)O#iHFP{|eC z7D%$f9WcMFwq*Kj)aG*#0Xyi@QhIpw3WBfLX_4e`+m9DgD+&{5?$j|ZB8Cds3bMTK zWEl+_)XS*nUdJBg!3YjyL$iC9qiCqs^eZ_a!5fk#de8_GO%=hzZnQUo#VD*%XG4|; z+fBuD088YVogC^d7ey$_o52yVuHmVHxci)R3(hEp;!^!H=;ptgalp`g@|6Awu|ia) z`*WG07pNI?nDp)Vj@gB#U7vVL5AnHvRQXw1-(?aru<+JkF6x?gRFc|fjG6Pt)387e zMV~n*+QNZiCGUhO)t^q;UowhEjAp^w0QR|`Q+ED*MH?Q@cMAmK_*iKBxe~VNMJfEv zJwmhrIx*KoxvE_(bS;U#UxAf#OWN$s8D*p*C8^|Gn8ZbD|aLSMh?BhN~j z_+yvu{JJ~6dm_3+k4ElE_p`g)L0!+!pEnHdyue;4C&}|DM2m?DowyXUo0^PQ&_d+} zfd!+Yg;es@(&ZQi9`mq(VXoPKjtrbSB=62M8WsI)Z_k-9Cq4T&PhR==k%Y<@W?Dq@ zhme^iqf?FN)Q5M89V`m6O;~K7kgoVMy5muje zfCb(_rh<3}*?AIobhI|oOtBFxs0XW!8jMKkZz11vRN8x2PJ5qb!10Ki_HLYNo0YP9|>Cf7JtKucRD`1Jsfai0Zu$1;_U znuv2=vhC*9WXnyLNj;XY9h@O#*zaGQUke@wY8F@gunQLy{63ef(9%4fbF(asZ#C`d2LVpO0LhAl+;+7QAJL;}mlwq4Cj3^o|)P!)S6`GrsD@S$2!BtRF za!BIClCF9-i<*Bu=)Lj;^Fxvl>!W9E|NiJ};5%?ziaUO^V_qL{-LqiE+8fe&9!5S2^Ec$(>VGy_iF&Q3_pThz|MZsd z)9tRX64CghH4sv(s`t&SV^EH#>QnFCX$7H}#p5;hK?ijMxfjV!_2W-sEm|?}LKp|e zVKoWHWkd{T*p#w1nxHG*Lcgt`s1s9zZ zRb>(6M1!XVD;N1t-6qi{waj*!gLZd*2={TrNb6OGAYUuyO@$q@xU?#hw^FxES)Kom zq;zyhX|_u~opE#Fs_hOY^vScOr(QT` zmlhIo)kAFNC+!WY9xe3cPntO2@6Ay291~dO75qI?EFiG8Sf8yDt7ig#M*Mv7I540X zk=v`m^atnF9>jSWF=dr~1uv+%UH6I#9=*T~7~N$vmA<~`I*m+yq&wMtgFEKw8^w@F zoyzIDkl?NNr-I~Gj!ouH)5v>T1GYF`N(dY3rLR%nmf3GWb_)L2U(FQ{bW3pN5c^!3 zq{5t7Ijs*sF`@K^Ek~#KP400S#=Uu31A9Km6)CPC!Q+Y%!*_dY& zz0a~O$FXc_W&N!mr_^ci;Kug(Z#*90|0+Gxwck#0&BsnJ>N`R|B$vGJv}UP&^mf!& zXY2jl-NcX*LU>j48;$gz_qy0L{pykfV;i*JaaR(DqNduD-0CGzy;-|Ai1ngHoN%#P zYt!bRoiS?(p?eee*mOJwYOI|BYP8LnIT4kdlI}u?Olbe)9yWlB+LhdSmV?Lj8!HmQ zT6VB``o=yrbHwYWHtR%atxKVIPr1k{8If;Gc;hl2PuKL94jUXIPf52b_&V)Ye;nhL zd?M_9rpsM8m!7uiLa``^nP+U^WAWU-tJ;Wb;ZR;v-$&V13d47YZ>}^Mzfc50Z^0%^ zT7l6L>nDO3m!Q*6@89IsWHi~5j)vU7^W z@L6i6XY@A5<3Zxu9p?Lu!w=x082a~=N_JTqg_bHREORkBRo$O{>RzRL_!v5ozw*Z+vZAGS038Bu)E08DHjUWt)Oy z-AR75L}hQ&d!r3}0e>2&FgxV(I+`dsd#Z19{w877wt9KjgM%4Ddv6oNGliOWN$YKH z6bHADoEcRSPd9&PLzekJ%vc#}6Ad^|Qr^;Wnuy7ltZ z6EbeWF=*HUNAzRQ!%Y==-TTUkTh7QS1S|htYTS@T9$m<}=;-Ww13z@u7q+sOG1FNu zvTjc{u@_VJ*=D}~yE?vcCz3$=hjVi}W@g9Z7F;jUNyUi$(?(|2KY9J{*JP5C0=LI@ z7hX6$c@v&Tac6MX4Yl0Dnykz2tD<$oSc%>F==s{0wZflsh1^z9Tge7q=#%dP2ZF@Y z_1K>>kX3v(k2pMi1`ewbIf*#scxj?OEj18V(UUMPKs5-AYH)+ROO~a*)4IVSrCNW& z)0yzHj5B#~V&<#qPRq_4Srg*ry(JH5OpHkJkP%$&L1s%*yAJM2Sh<y`!TCvoBQ{(0JLjFT?u*cU$$6R z_#5}93@Rb_W3XLoH8V?_TPwm!-!pN)%e`2jrtzK`b za>dS;obVo{Cdas?VCCBoak)~Kr~>x1KJVsLn3_xzYH7EGj43l3q#7EuH})v6UIKMq4Dc`h4w1bwY()4h- z0xx``F)Dp~3oJK{UBlA(5{tf)3R${EjnRbe{E?@b95D7(NEqnk!4`ddO>ClnQ3pfq;|}jUubB3GS6swUewd1(IRO zW=6C{yh3~bKGNp1BCpctxxRYel&_Z6w5m&PdQ-loMrMb4$(J>){e@@%(8WkAb)k|0 z@uCS2G;!LU*qM~Gj0LGK#OCZ^7rX!l&(+GvH8<~TqyIQ$Z7tS^p7%e`fQXkUqJ`Qi~DxaE=_jS*v zp-p>XcW+T^*v8zXQ1{2XEYT{lRWzwz(`bufa&*P-P$7dam}cuT(=jR@;87s_XJ11@ z)Ol1Rs=bjywNG3d;cs7{f(De)@VWo~FVUghSs)cng?VtyqojvZ1A+C7!;h4$_ZPUj zW7r^-SwcpZ?t`f<`PdI`Bbfs>6%VH)+1#S6tY3(ECFGbE)p7jCjF2iy@q6s@&v;bk zRi+3NMGTNywZ42;|?uFRf_g|s{ z9d$(I3Pd?+%egB$10H{69Xi{}KKjunp~i~JrKzqz2^97n0&`$KROCyG$8&0Nm365W z4f|U82`^`s>x+VIoSGdx4r8KSp1Ci}+PYO4w zuvd~MwEne2vjSg}a{H^u&*s|C?VWtc)V?xiG`LsWn(|6KaLG-$C2J>1>-^EtI2Zp= zIDIxg{s)Q7{ov5N)*&j>Uep`))9Pz-_C7|sJ#}ZEm6;tf#aAJdND;fY)q#>+z? zjHsIZ)urw(l7AS5P5^ncv%C&&Z%1T1>)+{7h@=vB%5$|VxPRMXNR-`ALQ|f2$e$%61t(gb$VOz(g$3qWsN!BZK#2wW@F5Qgv=uE1P? zaAnX2JaL5%FsUzu;}x|&IZ`AxUD4^)^PjDGMa*U<1o8S^pCj2C7NP4%=m{Kk1U-wv zPZ+mKsUVKYK_FNsQr{rpqjw+bXe8#n$yCmp?UI|a+6-Je>l9c!bvRveJ+ zi`V9kI=A_7;rYTw1Hh%n5K)%r^7#3akw(Feb()S`e1{jhK=U7Qb_0=XyL?Laf~<6T z@c5k&b>xk}Pjjvxsyd;&O+nxA2Q#3&7;}Oh1RqQ)knb9_Al|eNIw1v_zwe)wt;?1$ z<0?~7s15JMctOni35|d%B=#7y)^@rdhTVtfe^k(qX_pE-E~hxc#-KI| z8Ox-~i;=I9)x#-O{ny{&pqQ(fRM1IsoqOjCH1uCn&@TYtE4pbCdVVe7GDXyeBQ$p4 zS$S3dgL91*z>@%={80cBf;llTo-?wyla+W%FtD{=Nd46$b{04C{>)Zi-}qfJ zLCVSbfzCCXaLd0dR^@%4KQ>PYjDMV{Nf$RbIM>P{E3=z(8@qOPY`Nv^uT3q{RO!E4 z9qN_im{{BE??Z_h3dfJ2khQuuii!CAQ&2YD0Ug+M-E7ow& zQ^GD{;Fl!2Ql@A4ub2OzZ3Jk3h2XC#Bf-TVUOxD9%8qsbdrjH<$P?CSkxRtu82_PeQ6DE;|f_ZgA3$V zOeLT8#ie!X?3X|`qA`fbhn!P8R&nwCq(3>}*fj;DB2%8s`!ufr6kGjR`@`v>h|8y` za;e^|pWP9ya#qA~BDd*!NRiRn1T<+zg7m(`o#)=`U7seRe^RGS8gpc1{eGd&XX9{H zf^+>I9JhCBpFktX?P&E`Roa?^qvT;galgFYVDiI=?fbVADx(t^jPrTCcSMZ+b4RtD z60MWLB&dWeGK{5ATte53EkaI;C?lZ-dcA>8{{3kdG7&zQ`CzeK~IBA?^eX^`3-x={Vozg*i>5M zCL{0~`%W}SCSlGVR{24>rzGN17evzYMmtwY z&nxP}jf%=Nxgfpw6#V0k2PJ#pUzgYcSF<3FP8YI_>K$A8o@jpQ5D!y@`=v}?@1_M{ z)&XGuoWKehZ^-MUl`Hd}+H!x=MA|rLh?TtR;7eOt2SH*7|IR_TXD;5g%m^2u>C{US z`R9c#=LYRfIT6-)xTA|Im2;3;_2i%1Vsc~?+WD^&d_8WTN-_&KBzPTL?~qOMow4^p z-r3?-N5!j_-_DpeaA#x6ZN04k=QS}i2n1Rdp-x;)*}B&qx`afFcVbO<&zA(Ifdxh< zl!P^4zHb|j;jEwOYUA>Hxbu2=uMT)sw@0`JLh}L8ZDE)y^i-=On=!CI1cQa*5ZB^o z)W8$1vGnCqH|SQ?^;2R*!e3qfTkk#0FfNsOfqSaY_yZqygj*#<95(M9UjEyG;&=8S zM*&RjYviuQaNrRd5Fg^I`xd zow(w4_;ng^D&k5PibU@b@SOyK%PfSyD>3iU$aH2b{5HMZ&FfTwZn$3msB^?yyoeD! z$ymmo)!lT!W0RnoKwJmZSj7N%=Xz<>>>E2 zPMqo4It@bIGdAmsdkM3q2~rkQ!NC|y^;B1qSp|5YN*g`J!7Y8{~Mj99(K)BTqE3-(u?st1jOKY0|&mqBMs7#o%XY*a2C=Kd}! zZTcRxQn9$BE>OAu1qLC&XAwu&A)v}m&_y{sABygRP7N6XIek&hrhE1%ag}>!=HR^o zX9fd3%)b`f5Gk3?OaIg2en8WTm)JHCw}m+YULOcA?XhRP?%b>4ZY^CW!Q&{WEvEy3 zr_vZ~fvEuoE6s#GxV*aC)L9L{579u`527ufPdDBd>S~DW&fs}2rsdOKGE;zK>t;&Q z^F!S>8J>nF)}8Nhh&;fjt=*dml#Gv?%jQ>aI}{Mz4ve@KV_CXU z@qN)t}lSckqR*!^0_bghL&NJ=61J%gbK_>HWZVb=I)}x~{k4OfM zPlZ18<>e%hY^I=9Fvmi*FQO`$^GUY8cI4K*%qhX;OEMNHNvgyxN=lg-4=U#{5ZH@ZO2iA!< zoz|?m_OdyB)u!SL+(Dm{um!~$+L@o-aeqS+|GWA9#V&Qsq*nV;(XJ^7Q{jDFu><_l zu_4|Og5SC_a4uO$#NdloK~N})r!xsa3^lppxS z^cnb|#Z=YV`40=t#$O8H8ZL|cxU&P6R#u$i<7T4&rdc)i_U}nSPS72x_(f>~7=k~l zY!5$lK|VTOIl{Zt7;{XBx1aquYa_iFKTXXssCaejwE45u>2*wHRo|@Zzup}MUjYDIv=$MNZ$p3@uDFJ#aj3@ytO5?gMH%{TmV)tppzE;n zYic+W+ZiweRav3vLW^(pnQYQbom~3$XN}z<{!iKkj;tMHh%kW>76S0R5Tr05=@v}m z>ch+mtbGSq0tb4p06-^ahSLb(KU1I)l+f3JDDLb$ZU((2;3E*Zh_>?#3^o9EopsJh z?K@;40&ii29wP`J1I%YEb;D2MuI!$whN?4MAASpaKBMS!&a#ZY?y!rO0$_MUBQ%cUefTQH{FN`KD~5=;`1D zCnoomp6~)vtHrJ^A~MOc?|83~u2F_H2!1cf?TmiVhOd48;Yz-hw2~K?rPa4O$}y|I zEjpD*2pd=L-yi-Qzmq(nWaZn+?*Fs4;GJ0)a!zI*eg`m*cK$~aJ-P7hX zGQCI9V{tN4oZS~RgS(9uTS{tGfWs9pNVH4x*Z_Ci%>DB3^;SKPD1)bhm3(Wn|IBrj zcPoPO#J#=OEzR8?@t*idS`We{lv?RiLUY6ps-ktYA3b{OqX%#o!vz}LI#bp`lt}{3 z14>s5F|$n_1ps^l=t}hR3)8=w;6ZhB9T;@R5TcL6Ex;PU0s0NvW$SkZ{N!Nl8ap)+J@y?ZbcUqeP0O`IN39(w>5}Gb`1J@p z-+!VHkp4AFucUZ2(Hm=@vPV4^Df$$KFV`ya4cg7ZxD$U=6dtHiwoBV2leh9)yFCIW zlf`7-)~)W)`yPmN0ywt}OizhqD)V54_R3?OC=n3aJ?~BmRtC*p0-Oe=>Yh zX3k>$|02^WiWm22WRKttk$+u-uo=z`T*L8udylmw%fRKxWB3YM34^7~n%T%mm%8J9 zfl2AiK5U0f9`@`J>s!w)S5dPGmvsDDE8w8@evMimi!s#>HQnD|Bp%w!frs0dSA11| zJngs(0y%E?2v010(VYa(GtkO~=z*wy23ZI7?CVoUe@%(BXmVK-*i)#)Q}Y?Lsrkt> z@D&Nd97Y%jfPM|CEZs=CHhePgw764x7_`}5cHUgtT4fI-5KEVQ1Z3TJuZFW~dPku7 z9~F3^H)TSa@HYjCro^9+?CJ8iXP$T8{H0V1E*HCpJET6UfR}-tkkz@R{ggpx90H2;j%}O4oiEZ0w7#XsLQR3)gS>}-;D1>&)lm1#V5j^EWsYiT#k`*1oW%OnT=%;>e%_s{T+Ox>aFgAXr(=)VpA`I@a*S=>|%u2N_sV z=;-v+%%qlGSIo_7OQX`$KJ)QGEg|*#v@SOwb9pM$&)kT8zUF~=!NU}5XBIlYuttd- z}5a`$&YhT6W*Xgqrtjq9nXvQ7b{RyTfbjyP_C*x8N`g=5>5(W|?^gRzpeF!@9+K9j#Ql~2Sr(>>v)aBg~x)PF=P z5j%MK7Pm@h3~k0ui(7Z!&kXQ40zAxWV!TyusV4>psat_UW?v0Qd9l6s;n8A&`mF_T zYz`QC^JfjN9uFikF-kL&E;}&4%6nh1cIRQRix;)lO0~Jc>q?TY!7unpwN5j2O=Lhu zOBfk{m-$KGS%sAity!3#GIhWM(#kI3n{Kztx~mUOg!cR|?#IKzVJ>nVx=Jc$xz_I~ zI;0cUx_Ln--wnr`AWKaXbgRdNGI-~vdPhFK!|m!W7oz@44D@_8DQkwpqA0}_UgOma{AG>0Cbu+9oyn^ zC}q%b2&VaBwz=72LS-<{BDi~@wQc#yf`|Os_sM&LkVEJ(=dSH4LD>6PtCLU^x|;av zOa0R?!Xe}gp}HT3uqw|!hKVWtqqg-nI;ms&XMCAPd0qd#Krn5m+u=+}HLGd&2Vaki zM!J1DEKRF(1DHQ2gPtPRQus;niJ2JOOS6`(z1xdibUOu_a{hTv=6q7`)@W?pN;tZ79bX6X6~JSq&*0G^ow z74@&M1O31^pwnxCf_67%$aN`&A#fNn=L~m7{TFXy0WR( z^|dfBYQMdLlu3c0U7Eey(6cX>ZI=;a4)oyb7{)3%Q^%!X``MmA!HS0w#9n>ybWpFo z8S_$r`~}`aA*Ug8%CoBC?jlV5!_wSnAI~%QA52Xb!w+_I&)gr441eh`F7wY71ryZ< zIkY^qL?t^FQheZlv~Smey3NqO6|}r`@nA0L)ii|kPYxIM9W`j1?71?8Wu`Pi__sIO@7!tKhB4K z>qF0)MpX5~yg{Ei4o24@Xagq6F4sxH7xSMgtBt~|FYx#G@2BS9DKkb{FL4~ zoMw=@E7mH41Ef32`9O7HFMM;yQnYVHT=S^H1p1Ez`j+Wxz8|U8s{%N^V@CMbkJ73e z9J2BLQ5A$KnuYy81c!l#}^r^UKTTG^Q=Xw)L&ED*Q}mDG+*H11zM3{_8m#^X;g^ zw;hKH{9KuAvvw55JFT|rC$>p@jf$Bk+G?fc3O)+ziCmR)^;@Icg_&cE);Wb}1MhEs zw%Q6b7)`SHO5`JBj2Cicto3A@ilx+RoTLS;%m1=}t@Z+y|VI zZhzA(?1pZWmbR~c`(TUXufRPa*)tN#iDCZsa=f0*Q8yYzt~{e$@f~Sf;2Z5UOIlRf zLn*5VwPFy%7-`R}nIlhb*!Nu{^Td0n(O=3ar#xL-Tk#^6aI_0F2#1{kUh9K<3k=6y zB;U7Mnf8t?1c9UG)Wt8KV?Wl@$E|?u5=@Xk`-;@1a$_>*8iEkYP1bPVuUz*FJwCh6 zPAZpUQFHyL%e5A<@GlJQ25D#B$z)Fr zq;#y`gyrk|&W?X3)4Au*Y<%nTefIuW7ChS>1c@yl=+GDNC1GrRv9V z32?_=?1vJsIH~A(Jv6l7^7B|(b!fTXhEGe^r-2`Prh|_dXugGTK}jFefaZPDqP4&0CpnamZyiTh9j-;LddNKIv(weB!==NV zIRZ&lkvQQr1BFKKj7_O$pHp4N0QN8s5=ga zv~5cdLNB^@vs~q=@^kW(v+;Q-`t3!%{wDuijlWlIpXc#KZc+O;KtpK{C1IO8XXx;V zxN~{ZAArb)4x&51nqTbC@mc)(AfmP6SBl4{lXNz=|Cq5^>%^6IwlC<#dZygpG;K@| z5@R?a|M#P;QyWT{{|~PoG?k10zQ)#_Up&|W(*1*$rU8{&QU(wYDX!J(Gqp1Y|7*>6}_7llj%daO36 zE#o*zQv^ucQHm9s9KZa_n!*&7Uj~1qCuuZR7x%LiT6myKDqy3fmyBf+8aVusio3DEKdWMBp%Z1|966)&OJWS@+CEKXDLZYWAv|=^~YN&1Z zCM*<&);}4q3JJdocM*)&_pf*Ds(A?4#10I&PKFXWYr%og5^w1G0l%tR$BYHWtZRL| z$y=f@mO8E>%`}j@qG~y!WAL4i zXu|g$>G|30M98G;(dOn*9kwY2DsCtU;^G>!VeKCGNEvoLZ!PSyk3>I8znDrM|0Ahk zI`lVN3cA|vI8V`NQMQWQ=c^;q9p zpLj3N%*%O18>jF}H6>wTA$F(v=NxexcJ?e?Ye@#hs>tvs&hNyw*R5~Yg9-xXlLNIg zh&z$DD;N&Fc$W+Br`%6c+;|ej^Dw5xzTIVbgT`Fv3M4RJPoZ;kLq*p>9#H>BR=d*q zwanRH15pvQ&;DD~ecba)^^s9+NlN zOW$CL_G6)P%JQuDtMAQ_qmQ4m;O*WFpRT#HrK(93Kz9Yln*H1#n~!yjE|7^sJdKZ2 z8QRtSNoL+WKy=GJbIQFlv_{UbT0>SB#xgblzOcIAy!MT=kFrmvSm3!x?T1NCMoB}_ z$CaBH_v>EsM|a3QzUaGje0r^&Qq}FU+A{NQm6q?$-AJWX4oQaPhjxdOW=mc265M5&n?<1`Y$)!}an@k9Es}F@Ri9+mleYW=(&*x) zB;WPaZ@#m4_f$Oznd_HRMW{RQxKXZp@p!m z%e{C8)=p+v`gYnoxfcF?>hsx@G*XAMAgGN!cil18S(o#?Z`5k{jlDM=W$RaZHeex@~{lgtyqY@4BqnPw;ZlvOW5tp;vrqw`quRKPM3Y2I7k#>=lLK~(vX+Un?KIl*<>JI(YqjOv6T}G(tsduAcOHlN@$oaj^10~zrnY&+lk^3d7 zTLzlt8J4y=E4x5^KOq&r0KBrroXkOSb6Q}YS@FOP@o{@W%W!Fy=H>ccR&*5<$>T0Y zn0Z===^AhAn~O=)dG`fu)+`i|+_SARlTN_YgL5zW?Y<@J_EU$?h|}&E{2xbW!4PHB zg<%Cm8U*R?23bnFyFmBbtc5Sx>ePw0`Wm38N};PPTNoUh(gCkn2FObhho zD^SCU)YOD{XS&iO5C?_l+&HrwAOQ?G6;6FV6;|&(w>M|0-EeGZ6;76j$y0{ZFbwf) z>okZi`z9$edY;`e?ZB%n(tFS&pXrBtQ%`or`{=G9AP`dro;Vgp@-RuG@U()S z(TTJ%r&&Y+C+oZrKmTF7g`p}twQq~+`QyT_h}M!DJW%VO^z6P4Sfwo3iEHQhPiwMP zDHYYHe|dCWY1MLD-q~uNACCDY{mpY;Z8Brd;`{3OI<@GZeai7mF3W169xK1|jg3L| z0s7eK(E#`OBqCwBKcEwv_(bZ){9r@Hk`GNA;LCPQcu)9vn~YuV>8fOt+KXmL4ytP? zaxo%m(;ar5!-aDz;0v%8 zh^}t$tl@TIm14C8E+O5X_OwMV8h)npPiyghTcET{0sE?*dj@r{T6?%I+s}L~+efWFQ%<$Aj@z=- z*Y{|MFp-}CZ*7?`#HaRyKmV4Uv<;aYCj00;)o1oYNp>Q(T!o%{KI#YL_RRsji@X%r zp$@mK?3_=$JIa(V+#F&3=|Gy=w2X&#s~eonGcJ6+kliRlNHd3g#6&N2MCI2c^6@6N z?=<#orjh%VGs5s&N3z#%x?5v`EE&NK~A<1~|QmI|{5BYxjB#j2`n z5j>l_?J@^shA*|cqLsVEJ0rUWtZRW8g6+sD)P3xS!He&t-(iJ{Xg!0Z-7!NCitl`n zCp+;Yja)8g$IcI=^D%YS_0#TFF#;f`x+Ifa-q?{C0Oo2cwpF43*8C=is{Xq*W@&W> z|0Rhz72MVHf>`A0Ri&74AZ1^F8!33WX4T;xwY>t>WIB@hH5<-yq}D5X$o==3Z1f>-}b$isl!GifMdjh zcqkn4t^)Ao32K06ujytXeb4%9dg$~OwCb7^xfAoNG!{23G8@!U7C02?FcJ(Y(dXvU zu{l&?`XPo_J>!VbORKOnwH(2|mo%+jeQ`LbCO?}P@FmA(OTyl_D64&$Ba#UScSxLn z(7RRTKxVd%h%YHlOm|Yd;5rWj%9BdAi>?TFjk)FGWt@h4n#8{!@s?oN(GZjAzKe|c z8!1?)hsq2Da1awud`7*ghIzoPVHFD#ZR-9zQ9AGsJ#eO!+-%DeknO9hDV{Zh>!j2+@s8`Fhv_1)Ysm?b%JRF+0y8#)b;Sj|n{} zB3C8o()=J)#wOBtVIDR|12x+Ed}X;z4Eho-cHdDwZ^8UF^cGYeJ2m+3;WD({0hU4z zFAv3BSVd7Ha+C4Q9R+)tak^J8G~TTI*#>S;>*Wfx^Jd9uGxkm6RF_$&+{hth4a|6I zER$V7#y?NPKI7xL{gx7vvcdz9{q`xpe^od!G{UGTBhgU2{i2uC%o6!|PwDueMZY`g zkE9JbUtKP1cgUJ+gZpN_y}^R}p~)%>lNJDNkXU5fw}D=fHAk*|kzF9#f}%XTJF5KB zUiEm=I{I?cO+m#?gt}Yfc_q%*o|W-H{VQ9LKF&p!R%2}#E!Fb`xF|DQo$N!wIseWD zNV3#5X%0TEIOQ$j zXf30@)8rk?%V0^PLp&I`YD*z#YqhD+SZamgJ} zx#0{B?a~6XAX+Q3PwY5ZMQnokN_{+fv$b+^$w;3*0&%6^&kH7n(2sm*PG_30b2nLSL+xltde~w z8JTZW&pbawZrijyucq-~L1pE-d@Lzc3>Iy`onJT-_pk>_cHK`-H`h*{@6THdtxo0c z1M2mJp1xfi;ay)O!4v!79IVa$^^P`80tRnW6*q^&eF*RmZ@_1a27ft;MO9&&PSid~QFV7!@Nt4;Sb!D|$rvv(RRX`BDX6v_MS>0Jo)h2# zCB_u+maH=dtGwVBhbwz?&@5OKKG%0fer!+YJ6c>>O2w028AgNXWWC)X!q%qgW?N$G zziww)K&*!wc|&eTW8lQhD(0Nv_Qt5oqp`2;KObQDi|5Jg)oi>u-SQ%B>g_KwEn_)C zP7?>!-UI+ALP}Zl)8cIVjK|Hd<7Xksde@f3*8%F={U1t(PN~abo2DLnd`3{lD(0xG zjIJk)^F%QZ9XWi*ZjUNU3R9@}+0t!fP9CttcZRdNqQU0w$K^Yu-!V_hO~^-?kFw-dBl z$K@z|TSV*E%U2wAHa%C2FWpVXbv*r?bZ30)INP3&RB0#5B=*LWzqB{{Eua6mX#RDk z-(T;y%zb$`-7E;Ufos~qe`egfuf+I$zQ}rJWvHWe52Yr(oX{qU&Oa0iTy?oG=&-Jz z1VuCGUJa6h(Zvr2I3)+`0 zHT_XLy(F~{)?)0b2`_h$q>~`igV(RKaDFG`WXBq)6(Y)81rvTnTtCxjp7ISRD^O(6 zhCD1NiLdU$Dqz23&lNJ661@PSlDx2^W44y+T5I8H;pwK-{5r!#qJM;g2tmkmb`qmV zG_lH2Rv{Sy@TUSv+b(W`a*3F6{+XYfI*-OnxsuALgS z0-0ZzO+{e*PBLO{L>P_uR>OcQv~}gL&59OySfSM~#IwgnWJm5sV%(`Q8I!X-R4M>G z2L8n9admzvHK=I(ps#Cv+1RhBcTP-ZMX>|uG5Y%5mr&TiO0lKYS39cL_Pb&>LCDTT`F?}vS`ZzFy8^DbG3 zKcpl4Ijn3oiQEQ;kwQ9^g>ezv&KiY&NJK}hWosB2OLxN#6uJ=XXAil^QqT*G5S4{l z%GLI}!$LXeJ)7E$33!${GK(GASa?wqNTA_$4aYE~1f|>Rh3dD4*zNK4p!|#q6{1D< z{nh02_yg{^&WxNxh%I*rq%Z+VCP?h~c0lzW8Bc zV|D%ZeF-Dg!I!EPmt&hZa8(C|Nuk`LfAezDiayf&;c4gUqdB6a01qBQpso?ki7(_# z-e*{Q`tJpbb(!YR0oByW)3_c^oq^Nv*yG~&lr{Z7gLc0eLYl`~$<)3(TaNB$H+4QG zr7a0YUpy&0nP>wj*P9jojNqxwTIf=g*8WEUg^glrwXxR_Ig$D}Gx$kZ3l%9(@ezx* zKl`toozT>_+iZI6@f9acX8MWV%}RN^zC1d&U{<3a4}KYYwk*~vd%qGmg?Qdq(Ojsq z2)uteOjVmrZ|2i?y#yI=yR2Ih@(Ai%Jb68P)Y~(AHu~fV*=H`Pxq!DXBt43qGEJOV z3w-v+pZ`o)=$@`GH4Cc1sQ~KhJ16t$zZ--VkH~Ta!ByLmExyaQ!oE87aCB+)hOLaR zA^Wg0dz!v#TQght$F3|Qe0 zPp18AaIz@}$YK_;v$KP-&`9j{yiL$sNW@Zb<~83N4hMzPO8FdH&$L(>9&454#5iRs z`~CiP{?i}c^Yr8UC)P&sT5lp^Uu&DHTPG#`(4LXp^#1X$`$nZs+OqwZO8j(V&&!;u zg(C2OAk?UqB{Nw!K6;IBsI2_23KPgpgWOzr65I^8pfZjFB^h5}LMLNv=*9$`X&n+c(!tS{Vc6DanoZk z-N>Vni%WN&zDAo)okoN;I*~OYfO8Gaf$(Y4-$jGejwNSWT&`BLC*y@u7uD9ZGiGy# z7t!FNG4dHI?vzAa3r;w3g)y%DcIoq142p{uMOyPq*3&zh=By8LW{GKhBs0g44ndZF zB~DuaLcH1Pqq3gzl^iA8g&Y*qFb?#IL=0mca@qx5sQ+z=8MF#*X8Bc?3XBal+{A-a zgZt<8+l{y1>{@gVJRCd}jcT{u>YW>o&_?E@MxrMu&1Zxk{YBDF%J?#|)I8Gr>lpNB zx5*EXqhdnpXiFZ;_bprPjz_U}E@ng0zrA@?lYI7AmCxIZm9R~TZDp%UNlG>tm}NUW z#+oO}kj^K#0H5hgwa#=`Z@H>m!JJcwO($6vHycG%q zq}yYztyAt{ZmbJaovoxFc{9&ZP7VnekW~STqVpdQd3PXLtqE|G5rW7oEU<)DR5}Mr zQAk%ZD{;8UN!ViTaP~7YVYM@ZLs9zgN4GxInX1w_QDZBTDtkWAB-}JkHq}j4E-=i^ zH`aq~VLYF2UpWi`y2c?<#NM8Ag?dLV4UkOZnxvY`xdKnOWr&kCW(zNZAd|& z$#83Yc&=qc@|!KqDBW+mi|Z*R!Ea=9z6z0O19k6spy?=PmT&qxx#x|gtm1;kgl)4r z)Q_)|@9|DJH14hdb~Y6VQK-LtoUo1H-Fr@5sE4{VosRPCuaPFRC9l_U6_rAF>UcWj zrRsAkSyln1a`T>&FWk8*l%{f|_RNmYyYk{#H1Fq2{kw#2&O?k zSRJ-vU-O$~Ll6nc*i%p?DWi>pdsh>v!h*B81=YPXxz$sy9bt>c^$*48pOHwPJ{)!1 zr4cIDpO1GFXnXZ`NN4|L&;Y3FyH>O1vFAS{bW(9DA;&|j2HlR0jtMP%aPqLKoIf#i z0F+0I`^^-$gYg2D%=V^u-!o9MjSATo$ef)Qud*GndGO1u%9_~yYgVR|a(;<7!ua7+ z&_GKa&Dl9BXW1^(f&e_@8JdMux=kzE`4(7i~YA&WYl&?fI>7 z`5R{rU-(9VEZafcdqI)mg>7oY=F8Y-AWT#-D`JX7X-s-?oRP0~H)|IGRYxx4XX#U0 z0GpwM%V~DjtmA&|+ZC?s6ux_bqDsSk_gu8$n1=PlOa%^Za1<)37NdnFJli8Fm3zp~ z50{hSmWxT`62mbUW!S_oAI)Ls0duuM`U$;w@x(0!3X7EM8stUpYTjAMh8APFtsurx ze?PYZQC18XT;-$p86v?s3?9^_JRuk4|M`!lZn1M2z31JT5=X z^G!bIU9Gru2cY$FiiOIn{)pY=XK1gBBMhe4O43q}&Aa&DJb^QgVPP(wQM!rKqTT%B zm|*>>7FMX{A2a)lVba0;dP$h%IP*#>nk2}QnRA}33_*ZME6L^8k)iBC^3c%D%`uXn zqneJGAY;=BVn(*2s-Tk9^v1yyJI^V}(O(HDR}w2TdX7K2Z|Vi$S{6Q=3lzVhwrw_V z4FnW1AqMSm0uc!Y+Elp8P5WJ1Z{;hTgt_kd{UTsQNk5CtTo%1~l9TPA?jJ9uNV676 zVgwb(2zq^w567uXS?wR7*Lj_ghWP{yRJWUgG}r%(M%lXWw~=FS3L651RzW}&!&yl%V{PTTDta0b zrvLj<6vMh^i>rm-{5$@hanwCKYJlhD4oj*^4K&Y5i=|ND7Mes zF%TmKP7;4=e#4!tVv%1a+(;oTGftKC$ zIkl|W7{G$X783t6`s^XPBW+q1Oc&EG>a=3(liGsH|LyDN&mYRVzgPXdJXJKny|Brj z<5O031^5g0EG?-SOVWL(4zWF8z&EvmaJy4QCx5Pj^U6&DdCg?yJ)L+%9%f7D44&59s*Shh3hf1rY) z%Hc6CV7Tj=VeeYTeulepwVyiG!m!-kodY@IvB5h46LsA)Vu9HX4d2r%Ba_5(ydPW; zJkLK>qIWoDFC?8mu(cDw#bcABZzi`;^d*?_R2TbwpG&|V-w(r!n@)e@S_5&A;F_cW zs6<%&c3rF}&7v zbHQ@l3~$63H?q`Uzmgct+-g>vrtTZtUPZXCKmIxkiFYQh&!qyK%stJmG#1oi^z05E zpm_5u0GpK%4>hxG*m)*1zNT$eaV_SK6?bliSgev?rk7N^;c}4aP=2Uuo)cTC+Bra_K~BEPGc5MNMVQT*$R|$E>vM z`A_X1D}x;<{XkS3C7<2qK570EU)`Uq^qeE(XMWa`(wkX$Lef`{;eTz_0z zPmFoKZ7J~_DvuwXM}yql9K~<1kV0F^_%fcXw7bcz{a;2!BVhyga;$U4h$FU%%58zm z-yfAisi6s$!p2ob(yK1Bk@{B#K!L-tnD(1&@-$l~8RZFBBm#zTR;8x~eR>R8gh2tS ze}y6m9NRV)P4UT+QUdsmU>N0HRrv z%b=Uq0rJtxr=5{<ib*U!g07WOw~Fe^NU2BSIaYoZS&PbmfhB zAU@j4IFXw0+Sy^N^7tD9He`DuX})otIg7gi48{#iqfLj{rZ@FQoSX&*nY2e`aRWov zocCC0jjS=AA7Z{x`ULH58QE_a9rWB8EazGy`3g7pMa#JhLw{7<7dRynR zcc!-5X?(e(^Sy=Hb6ChPci&$S6K^05V@->UW+k}Ir!D}H^*yq|_Q#4JNRPyIl? z?U)QlY1)B&`*cEJ@X=(rA8OVFRe&3 zy5p3E{>tA{6xflDl#A3j(zZBrSc$<0%37V(^{wZmW^S*TNLQ}N0}a-B%CkK_@BbTe z1HZuo*b=8r$DofULnt_u@@AKXqtNciF!4x_zgx-#!f+h-x2?67n~t8FXL!@B&V+Cr z_-OT8Tg~sCJwf*d)kog5gE{li&$VcCE#yy8!Y>%}I2;DFpAr!3AAL_pvAE{xNvd3XeRg}Qz?`$C|5Df<6ufsK?|P#EWXxqiUP?6nNxc{3$8_9RB2cE<3JwP zeQC)?gO6CcMt>}uW6bwN_ndtGfXbcLH)B!c z%Xfea7V6=b!DK#Ih?6viX}aV`1F@2ij*`?5Qcjx`5l3WgWEDt58h)CtI^U${IRD%E zv4c5(4EAnv^F7F=q<^pZId^L+w!9jg*)0^Et4Ag(Ck_eP<~E^|XJD2L-}@>UWxZ|Y zKFDp=3-C~qW2cCq&5sXIfJ%blpi8r_F2}2+RH)(hx#C{gH(~I>B2Z_Do>#Alx8u}x zudqlE!iP?Dx%HqVaf&XJve&hm`ZaOk6(YfWOMhLjx3ikLu?c#oJMok_?O*M{ltl> z{^eIdV$(s=R;!DmQ&rm%aT%}j0Nwe3TRT$sprP1(US*Y#)Z;IkD;NeL;O4qMHN8S9 zpOY;qJ$b)c&r2^eCl{L!m+hb95FbD#4xAq!1Tfw1gJ1V>^8^UAkYAv@ph>dNy^wfs zLx+S7XIMtzcgR$)c(@ylGPlug$o;!{vPUD2QVGO>_Scbj)aldQI3=%`@b;ON*~YDE zXB%S_Z_B@^iBXm!-&%qjUMMP+7JuWv^I+Ak@W9 z+}xtUD^DVu*!Cb;X@Zcey|FUS1>=X(dI6>+a7wd;)s&Gn8#;Fo^(wS5s*F5?lq8+2 z`m`yPIO}oykbc6l0y2~B=c>oBD^94?%_X@$E~oPaPDXC5IT613cHXx%?>Ress*0Rw z@(m~u(*(x8oOd#B^ODgohgf&}N$E@*f9mZ~>8*2H7+*S95)T}oPapkg{^(=jg~!*iAT68!w@v)rEG#uu7HWAV^&h83 zzD-1hw5#nT{zpN5*OvT`z=(M4Zg#D+Z|5!u&#kJOf<&++!urFcbFDv^3~Tg*WRt(F z*k|yhS$Ynqxz{M@eL2K5b%~?%$%WXeij?#>$2_2GJNwB&L0Wc!l)TKdEZM3CLU|d;;mfr z?|SK2XEC2l=a-(ZIL}f=e)ON*XpOm}wSL!XSmn0hoOr%czjCh``0OFXj(n6tvHx$Q zW41JS=NCQ_iNMP#W@*9G_i1ah;4gw&s_#18vI(@z2Y&2ka#lJJNIBkthr=`5zB6EH zWrSsE%Yx8C8}iyQhCKiMSMZNFeGCd|-DZjsZxN1CE)sMC%VRexuqctf>d0ZIc2lGG zuH*k(EOxn(FEph&duf&Eu3$>>8*Ve9QI0f%L*n4~E#KS2i7q}QFyp`tRk6F{p27bI z=jEmg!A|Nk^&f0Zz=;|p`EsfK1uIYvk;+UAVh&-ocY?Dx7UdS{s-vY{476%=rWiu+ znnpF#>Y^89Ns|M$EM;6nOgNaLjxgp&I>?a5(3^hH7ZuL3X6N?<_NVMB1 zliZ0e4!vkfYeyQ0XRMH{$OQ0TbiKl~W388-*z38tKJ#U}c_~+4QLhSc#LUwe+`jjP zJ8A4|>ryy_1*lqx>$~}!Pw$Si-tQn;%3$iv!7T^8aX1iMFp!BnM zQi){PgYoL=vmEmyu3?{?BM;q8V5-#6f3;<*d9-Yc*X_|VAuqh?&nHixoD}luxpP?c z+c~D*DWMN9lg^HB0P^*{3WAu` z?v^MV<|OccNnLg#4_fzOs{4LFCV>&hxm@a|s&*NeDhR$JNsene%)^hz5VFO?{8d&B zfZ69^uzV*u$7Sg#m#bhLs&%FMX*muJV6R$)E$cehLfZM-2iOq+IDQl$jhRAhCnJN#Ay<&A){soywibYXQx(!AdwUN4A60m9&=mYBry` z9qreN+k=peU)^H1oT*->t$*ygM&*YuKj%DrIeyk4F2LwKMg4E(-xWs*5?3UPDzqH0 z_86lJ)-Lxs82qV&7cu34G}6|b-vxpd+sEt(04tL0LdBD(cR9Ctu*_Ph87}`Eldy%l zAELVsL(VZb$_lbgOC;PR1f|w+(YTrqL!IBwGf@H7v>)xjNjnkt#do%S8oS)yqlCi* zN>>?IP%M6E+RyP`QA}udVk6IMNW{|M{P+#|#TFgSAFHCz9;zQL+;H+}3i9h@j_6Wl z=3Anj!!-F-etL7NGg7coI9B?!{aBtmU_#^6mKsj^^jWg3Xag zUI%ZW_~BkeMxUTIqGn0GO5x|o!Sm%I+umaBV8K z*k-|w>sa%DUPSrA9Yq*Ut|JKIwvF}zJPhrV8z?n}qM#~1JCU1H+W+9b+}6q59CyMw z#oD@F_ic5u{ND5YxQD0X-JjU9cYldXIWVR`9$}qmXg8~ZRJzV2@;bz|s+`#{9!Jxq zi4)`|hqn*04~Yo~@s2hH!?MSM>~=+v@BaaMLNROrfQ24A4*}5ExcGyIfJ;^>(h@;G z-`n(MTfd{V$(4(C^N^ngoCoeRi7U^`(Yv_x)t@{#rXp!Q%Gsme=C-y_TZ_0FEZ<<2 z2-Pg`k7-f@nEop;;|e&>-zhD!`=ve{<{83zBvuVa=AMc|44}=aVtAMj9Mmt6)tjEu z?OCorNhM>SJQ}O0Aqd3>o4>Pb-+-ea?IRw39_(BM@KjLr2bl*&er+*-(JLipoY|Fs za?^w6Px0<Th=3Q`mNx9xzgB=-{?u`9Ufu(l=0N|z zGTRranT=$bR9Q@ispvfJ50oJ2qCao^HRr?gbmC?%yw==s$#pgO2-P!rZUa|b3lhA& zsa7p1n}K5fV#d2tIV6IRpQn<;GxW#dh_BrPx6z05t;6}hjN$J=-M%abtc=CY&CJm6 z?cZF7HX-yAl`q%Jhasrg2M!P$W3G#tq2NLZX)Phx+evDXNH$S}$SN@fSy`)=V0cs# zu104|qAv)5g1z6e@`UL!xJ8+bn@Cr_b_IZjAShDqzO@(1FMHz9Gr@(Y@gBut&mKl@ z6zvZ;M8GP}%^D_T!7_@#IPutz7m#9~H9a>>Zj{hr*~hn4iHeauSq==P+*is7E2%Sl zsui?(qMzA7dv+&MC=&tF8|z=)*(U7fXDC@troNXoLnOJG(yK|dy)1n=;kG( zcX=Gg+dc7Zci(Bm`J%gw9$ftt@P%oFNul^Q~V` z^ec4&rkmj9t=^kuGkWqpfO2S;zVkGAG)OCI+k&=xt=gD{C2SHe;@rnALBtp^-DQ$3 z`{xr5ZQh)54=J3Ha6?M0yWR1*jE(Mws3Z!-&;ed)Q$iBt9(vA9{eoVGYiiX4qaRl! z2fvm$B3M!u-R1|Q@df9-G_aDlQt&Ndm+W>9la`?^lq>&*&jWwX-4(wiuvZNpy5lGH z3tjl(zEXT|Qqlxp<=|s$_xbv=(GhqT7a{Pb_YvXgANA+*K9QreZv&*QtHN_3TjzqO zR&U0iidwl5JSR`HY?>|`@jT?zNh%Mj#h2lbcJg|l-V$T(%(ZOY8cAmw38h1uo+1)` zYp+(EWSK+B87q*}?CzfZy0N({caDGIyu0Uw-CUzDG6v6 zRTB70fNI#=gPO5-Go^pSZhWd&ka(ZYpYS2G=p}s#n-^3=`C8Qh)TCTshqootLL8%2XP39iZ_R=@G*)$Bb zG^W?eK|d`Vk%sp*W`t=G;KFSBl4+%(3V-}MzIrDcwbfCRy34#=ZCihL2ebn5$Ndk{V4nRb>s z**d55S6(Yt^aYyO!rWSMgR7UX-s`v}A5JTiV2w4tc+~0d}GS1U&W?Mwr>p7V-@!>D*=~Ds8O45O=jc z27ZIqru>$#FWKQ!G&}_Qc+@3*gmV7K3gh~IU<*ybSyyOq|!3LRVy6NIMonZ%SHTm8Hsy|K!XjGmQ^dbAA@s>-_uQ z^eJe1l_U>WXV9M9F96B~W84bu4UH`7-B#rh%eTRaQ{)TyP%H0Xw`IkrR`G#LB-#>s zz$CVEooTfGmK_J$BR!*EvgeK#Tz3*h;WtZ0EUZ|8VKCY~^X%qE!2jVvFF9ojR;Emp zY+8`g<11cp2)R4zcFvk>R4@wpE5WT@+3DX&=#?R$7ITH#kS-lhSQ1J+4p2s2bjvo< z?IzdoIhbq4M-l+_`5q><8LPit*^7oyYAt@F0pTH4jc>f zbF9F$?rbF*%PG7(lBf%{iITUrpueU6H54s; zf=FfRe&bPI9i3cq=BoKbZrqh(c|_lYol+f@q9`0#A{J(U2s!FwwQC(2yGV(Ig0g%Q4RlzcDSqK$T?6np9OA##EbE528+=&JH zB1iS}zvCmUi;w4k(FJr#qxL?BD2X~zhvoaPnm2fDP*C04&0*=)wxFu&TGX?9JD+wH zkY+jCk01F9Q%$%LFcq%=qj!;02;@^-`33&~E{_uHq7*0ZoU>i2RKAR?6=ZQ7S})|) zKFQaWc>f-|$$9ppTV;gAf$emai*^Fbct^NQ^*}SXHGZy+WKx3Wi zOsCHqp9es)<2+^^Yo6oq$+xQ$O`Hot=W>TA{hX4E%t&;EHM|p}6wfz*u4TC*<8)K) zH**le`ao-i)Kju|=Tv@)xjg*-TeQwYNjN}e{cTSh{9AqDc?{b5~1o{xv9 zou0%29==uZG;nXO-FjbfMyI4n;WJC(Kb}Tk)zO2ekBg)eo;m?USPARq7U3RUFeV@^}&yd;N^s5 zm*R2$+3h~j#wk2S;keUoa7ZHu>Wkkl=u2s(kCg#BwNn(E4?;F_(Gcg*1bEYTFpMT3 zT}QItz-d6sA-DWbO~dj>W4l>4kH;Ta_>+yjXu7XrhSDTuAH!r`+{C7)S#7O)y2wlI zDcDPjg-(en?ImZxidkTW0zhpUy;{?ChH6>QoAm z$`$HT;01KKY;%!ZxF5k&lHMniAdvN>)br0g6ZZ4?Hu{Xn7F;)O)sm)85|&clI@sQi zrb9(A1H#P@J&Sa{_*pYm%N-xb$mDtYUb0c`!nJX^%oTTLoct790;I}#{&J}Wz&_qU_Hv(w%bLEDaF1dDs8 zcB8201}!~a`hf-Ht)Da{dYtwlyxe$(>H=aJtm8RyY0sX>lwba)ik*-j-De2=Ax!2y+NzT@-g?fW;D>fzm9G}4Ot|70Ms z*JiURFm~W-za|fw-Y6pYzMXur*j%5gZnC=xS?nh27{NNYhL&l?X)$=oN*dLvSMmv~6qB*yC} ze_|V8n}P}xfzjA_@W5DY6^!lD+GJa#UdH{27Xl3^g%g<^(0~0SAZ+{EC$+%}*sphd zb#)j}l2&CDaBQ`mAkH|^5#TS{aUx7lPEO|18VMk(4#c!!-JnX&E)hv)q?o^A5RYAH zRTQmc@JBu?WD1~_;)kdQ z;96Q*f{@ELCF=|afZWO)OI~Vv5)-(8G0aELXe#>O|0IiWF-O)#Skqad^YGx*+EM;p z%}u9LN=3t04j=J)Zr#Jp)oFKahoZ61%V`sCG>OjqBzA8{PFBNF)8wUD z3ASlyoI#Pe1tXu;yz^~UP_$As9b~v1qiHQ~BNKXyQ!Cul?m(=>Z)gZz*G{%_k^7pt zuRwYvuigK#q$^8Ki_7XL{I`6hEZs*+v~lx-v46jRer9pr%$a3L!D}Ca_ystv+KSK& zIbWl~A}P42UPRP!NmFRt{$V*vNE2hyNY=_= zp+u|#nJ!~Fj-)xSNERxlZ5g^8TA72fhxQfg2-d8O2oo6q#vhy)CX-jJ+@toYRW3pkm< zfz9m-P?h3YbA)L>Ymm{5LodD*u8>pwfo*8S~d>S zLV%3Q1)5thx8PG(+ZGzk{pw!Y6r%LY?4pdMNtd_JU!2gsOlgDXY{|X<%LvwJ+#@O} zk3y1ldEBfLZG0xFCQpfb8iSqKeX>tF>2cZlj0*E>$?il2tCm{n49mpxX->JGB0h79 zZYPB~bb!edvuGxt@L(x5T&c<8$h#aTvg$I!>}3KDSX4rgUO-t(~>A?BLf~*x?@2XjfEsU zFVV^ShtMokLI5`JMxXVh#~n|QxU3G40*&>l)QZL4qFzRY-m)c&()S5Lt^X*}F^i(X zzBT7^(Zt!j6=AbM!n0ieb#@4v%4`2UXI#nz?s3Roz;XV|wYpw@>C5dk){lj1AXsE+!Q?EEGm`b_fP+2-kJh%}z3^ zAZeCSR5Jcx`CwAeigHZHquyt;p>sYSuLlU&o$>t!hh5_#$M14mq0x*iCXnH2%RN+Q zf0s_-)Y6Y$;CHaiBb`fqdxZ2k$+NXvmBw`2n5I`vNVkv1f_bA`e zmN=q9HOlx~p1*Sz$b}zO>rl8|#=EHoo06Uq9ubS1KB%EllBjG`bPA-%emCWLXmmBi zv}sn%hyazSQ&fgoxsvcHquR79+?E`ESfUlzG9>sfs!CX_|Afor7=Zk^VCF#AXKL^? zYz*`cZ#Q;jCn>!cCN(bPOc}vLZK14`%3iie50Z?kY<<2Vi=dHLu!f)5 zoE>?)H^^%@Y$a#3U>*U2HBg{}4n&y3Q)SMY7>Y=YPo=nU8z#=plyp5C>T!PF5Dz|1r765BCeR zn6jlQNHYBh*aGeV#7gCU<#PYp|DhzQ$-__3#RerIF{RaL>@eGTtX_vEtRY#`0wt z-dYfq@^9TJn-1%TeR6&(Ge;48ioAdQ!-1wPuD@&(Mk+ZEoYYAk z12z6f(pUI3*?4c$lF}_Px^sXaouj);V88|p6+uY_>E38YZj3I00n$j0ZV(VqX^=;y z6cqjK`@a9c{n_qwpSZ4b&ULU(a7#k;Cnk$S_t@G8-3vcXQ&bj<8g`;< zJvjHyt%|JH5}e0Q$LDbb#nRdxSf70U=RuE0T;f*Y2y;`@_(*Z8zZT9`=Lk`A$|!XA zI(Ii~Qd2+=$x^U#bf5_7xev|MU)FWehV{o*GbYc@t|*r{YQI!nfQ;AJa*cB{bo=Qq zlZILciNZM~`~S1|pz;4q8QiFQc4cl~;?22N@svs|d!M&=$erzD=SB&NBNMM4QRZlR zI`OG320rEdgteBwxVl69rt*#AekDbMi6qmpE>M~4iu;z1$aKYceJqiM!MiSb{Y9Lf z61^R>?yqp=Oeg2*l*XJ15$SH5PBH~<7}mhJ;L!}OJtq9zj8E|WoY$m+;(5&u-V%;P zjaINLm2&2<7nNyL6SfkkZ!w6-Lb5+jLkGNBk-eoD^JoLANy~q|<`p?p;Z7y+ezc}a zdq9-nvq^HJdS1K48uiV^_uCD*Z{9+!eARs{MvlDkwUY!sl0=V`T}DeD+ohS0N6MRS zRxfL@Aedok+DcWUIe4S`|A~m983T=Y$bz)cV-3 z*0QsolA1d5{#@3YWOSBpij>#IvHqRV`5Q%SOoQJ;Sk&yPmSuj(X7Ry*>T3GF{`Gp8 zi9~!Ui(-#ae`&0m&|%fkiE#McSSRhe4HfweR#)gj>yB^ttcv!nGRHUEy<|Og1$nm% zk9SF$>ItiM=a0#YPO`|(O@aBIh5sE70rrlJ`go@v1+PczUTg=*6k1qFGpibeAwRr~ zH8*8vEZkc+Jk+lXdA;m%sCZ|7E0(#TBA7QI=C8=&Nj~cCL%JlhgQ9g4_WGjqFGu=8 zXR3ur7JtuG7QCYTijTS2_MNu9ly5w+DqX}N z*m6L>xcT_Y46cCjUGdsS-hKC7{Eo%$l_8eD((J-=o6gM>dAu4&2p03vD@Gt% z_>v}E_k<^cpn?kR+G#;KAo`xgd;Ei}okVo5Gb(_2vo^})r#Ue>*Qj1zuU-$_Gr`3Y zhgTVYLwRI3Oryyp`T4z~c$t$VjGr}XZCYW!lOJKEb(Y9Q|4lil@%BltaK~J{_sH$# z{xdbZ=E1on*TV3&AK9Y(S@cg-!HfKiX(5|?!olhsTVoauPu@qbQhU0O#U2D3rXR+c z@-m#~V>YzI{)qfmjFDS^4XMNYQs~u?V$`{-2zQKnp$l1rb}VRak%?Wm$H9Vp-pS;a z2}LUPk693deMdI1q(SRZuW%vmFK`c2M?MDhW+eUKDAJMpPXX$M?UtN>@i4KQhO7#k zyl^jIpH7dDbJZ_|^@G#{0=e5H6FP>FjU<M~CK)XhE*%8$;})z{a5 z30c(6mQakz$f>MpMBxPik1CC*N2FsE7ikO*73a-CbvHrv7|GB6I=isk=dP50&y^VH3;wIL0Ko@nCse^z^bl8_Tm z9_oIGw`B;x8+qV#&fh#|Sa{OX;B$JTpscr!bq^U?UNf0 z)S6w@?hGh2<@~1SB(_AvDcp$JDBr7~uZ5#}HOX68k&7)I#OM_md=0g-)FjPf_a#^- zYSiSe;Psnx9igbB?uMaQjH%IG8VP8N&e}ySWL=Yvv$%1UmcBDdGj+f z#c)8gp+8UE@Kh8hlUtLnkkIKU<(FLNleL`MsYt3JmVJ)PV28xq88`ibQyht&S3H^* zx0h|eaMo=iy~*3@me8abl-#r|cBm;bWU0$vk>1U0Ffon>O{Jx+=uMLzgutmJrVuu= z(LybXOf@`9-X6|XW}H7BEXB4qDc&cCm_$Ajc(&i3eI$<=Z-2J%pK%_R8}t&jfQggS zeZ)V0sYJDm4*U&kPGI{c7I! zB9z0CrB~95*y$By+dnVMX9Du)Jz*|!vI&o)5}4se47pVFpA@w?eUd6pw9Swo_~+tl4>*gXt8GtYan$jzJrvy{HFTXiUHC)L*l4?vFl2>v{B|5S9Z7Y< zvAEW6xEHgubjw?}^L+i@7Y%+w&@8~9<4}sT!Q7Uz`YkilXO>b1zeO?j5AhrRt(%b7$kb6t8_&Wwx_qTAi4~;Su2jVVk4X z52Lc_XV8bSueA~|R6`v7^CzE3*6~+Vp+v-9();}!CumDb)LQQXri)9Z&>9r@X+(BI zc0Kt2OmzgQ&i{gZk@qp$U^xr9kBK%|mi(mK;}kZV$x)4?)1Nq?SpLGNyT>qiFOt+Z~5|18U;pC6^5t`mVzIUCZ|8uy`x{lLoubn2Z9t`tzwXAN* z_|p1VZqD|O-nlJ`V1iuKKJ-R&$=`yvly!2<`7!yO)!$d%6w~x1uI(g3I&*7~NA@5@ zTymPk@kd%c!KjU4F>kxvjxoY^8eb;s++8kT- z822?LSqmniy^m52djeE>RzTvnNFYc#cYlUX-@d%Pjj|Emy3d%vgMarvF>rOQs%GH6 zH6*CJCS9geOe!`ROJP`Efcb(KU1<=$Fy%FkQAcb_pYp|Bc3Sl0{+YjXrNORn$)qLY0Nnaw2gfj(wYDhy{v8mKg^Lh#O?O4AHND#O+^-CcLz81rxG; z7oMV*5HWAD0&a(Ktq))sfa?Br20bD)FxE9prd-zGF~Bwdi^XJ8DMs?-esWcZ9-g-# z8YDXhvYO%q_?L8Z%i8irO+det0-vp~=u-Pi&|;J{UUDk11m_*+Ww)*A$Mr5I|6PCaFq)&5**B@-MRf|Uwg3=JlwABz zC~0DWzB+e|XsAO$%!Kvdb?qBPJ?Vd8kfAj}vn83*vpD-H6G>}@D>y|U@mjHG>9cSS z0kzu6`8z){OtFQ!Ut(Gy`u3}qS*mVQLW3`Vh{UKt$7T&aqinnB4Q;y;##L{R&DT5N; z$*rmg4e1kFy8ghUP8+!3t|u{6T}rI7d1$n%G7^ua3{5chOAg(+1~5%M&^DChm!> zW_)PxtlS7?wrf#2JBp7QFmyMWhpx8#1E=!X)D3UZ0*9vel~K|I8%I~)w}z^ijGpC0 zJ`)LT9fSi|UIWppqdCPC0>s(CFS0&$LF^3pO-z!^8--MYF!w0#fzst#vEe5o663#} z-qdPnfcE3#jA@BKXwyKAt7#rBK|SgV-%2@;*B+HW<#5jc8VWn+?mPr2%LX^R0p+_h zOkstrU6RvO0<_s(KB*iie}zVg8@)S?>?C&Sfw{cRA}=(zDh8yQ4@GylfI+t+ByQ(> zIt>jbFZ`HtT?0R!u~VxuN;6MCJk{Pvh_Or6-bSF;XszkUvBS=2|M1hJkRP-v%Erj zBD8Y`0_G#Da(;{3s;;%4I}Z>RIX^-;GQ6yz%hi`DZ7OlZ53fv@5+_NFhd#H) z`NM-ChN$>71WQ_bK40OI_Gd!y_3}_(!Vtg}nE?1x<_+_wryV1RTw*ajB;&bf6`Frc z>Hd|Co;3Gb#EAd5qS01x0f>9xk?uR;3HIb`%>3Kvgy~&_^hBYQ?P&G(V0<~tiFsGy zGR8T-Di$1oF*nqiS_cbXyb zh5E7=d^};sdFeg^odGrsX z-@nIdoc9d{>DV>mhvaXSV2(srpr0biGCPnotGrJ7*G#pE)2d1XP8DXyZrvjP*y!txQ4X+Et!F_lLjWfg56@eXx5ZV!cWXnZs!4d>6K|%ca zoup7s!+S>Yr$^T~nPLYVFa`5Usps!&}U2dQZplWG*w>wxI+rL`YeuqGF z?+;U&=z{|pruZ$nlb)^)y6S>YjJPd+8*v0P{O0KKR`(lCD>X6y``b-kSybt@WqV2U zcyqFQtRfeXQ6q;Z_PU^aN0eP|v7LJX2ieaX8XE{Oh)aL`*MO;XMYlV9q4PZ)(ei5E zj?2>350@*p&%VeGI>+EV&qUopFN_TH`F8h}HG9?} zTcaws_5%S!DluEHsr71S4$jMjEDH3~@eMsZ_5fJDX>7S>zaY&Tcj`KDrC(`eTvxa4 z_46#u=jX1>%SeV`jxD+BmuX!Sv7vv=%Z$u7mI^{w6s(2Ef^k|v%%gZfx9oFseiY3E z6`{dv8)3ZfX#toGMO=hSh((FDbQhz`?Y(vK-#368gfQK@>bow%MiLLa7*1$uJf12% zeqVz%8Gb>SV=j>6d6HuDCA@EvSy(;}yq!j$auUzyd}riO%QcJ#Rl%;lX*QMptKG_q*UjBWP!wcBK+?cQ_C%9@wF*Z(|LkPIUn{eZDoiA z#D_WJw{g#|CA;LwIyDWhPu^2vS7L}v&^D>zO75@fv^d7JesHP?Y{FhCBx}K310trlceFi#$1-zZ1>wI6AtS|Y9 zzCC?E-6vp{T=Z`dA5#1bp{#5TihYn9qcjdx94N*B{_%OGIOG&$!s?zFGW{f7V-QV& zb(rOt=2dcw{<(TS+-Ncr#BHcBAoBbn_J01tKYjBkh9VR;9kaksv)re;wy~~Rr1zfB zoQmBkZP>&sD2lDhlv>mI@4eJT(L%R631VacHN`b>##2Y5SKe3ZEPO#@2My zd+V6+Y4K9~7rw7?RX#Mvh1QE620%rTtcnTYy|WXqk74gAoD{9hvs>l#N1O9N zFQ0156J0eM-p)7B0D@=mjSm>Fw=-xvEDl3yxupoClw=e!=uQIV2jWYciVnra%z)-& z1`@^zoh+6uViEz=4O>%3@bYCW%+j7y5`6PCJR!K5%u6RX8jmb0d^{E8|3`=uxj3T~ zidqU}l5ZAiDWGyevFMM11{oktF1U z4nqT?Dn(5g&LnI2b87>}PXQ{9JU(DBFYj+h%BV&uzwxYu&bF_?L9-R*vRm*L75HsI zjrx{PU_IZ~@r5YdjUd?5P=2)z68R`#c+|zN)9=|0fxw{Ym4|V0q7P^L-p2w)?H`;_ zGKSBheKJc98$C|&YIsxd+6nS8E5F+t#?TBt=t;r`3_w?ya zhlG3Jm0amTnbIZ7i~U3-thFH^>$<3a@5*qSx&C3z@WQ+28>(um7MUPVeuIQg`Irt} z2fl2pz#KW#6n}Y{RUwQXJ{NTpbk*rPyn&oma<|yHcOiAPZ^Z?&!@8)qAXPM31-c<_ zbUc8&luH?Det71s>B<~(MvapTE27DtG6`00%|OnltTZ1!!6R)GAm(!Qo1!nc=987Y zbn0mAC2fETP=|nbd-IL@UoCw60!&PIEv@*>TTQi|3PKw!zJO%xM2Tn zbfDz22{7u%wd$b)YuS|4Z-z03#+>cx+>w55`UjFO9U}CFC;?M@@ zljQd*0c=?jPg*!Vch;$Q;r7Z(IepmZvP=8JpD2Pd-%|=O=COgHR z9Spw_*h~`9f<-5v56$6lHQLsS+%C~ZJsc$!0aJUzjK5y(*8efA0}B>?J0-;YJ-Clm z_XK3Jz^_46L{-SI1lG!Nc`tVZk?N#W!4})>Q_nqJH+cIrJKeykpxpR)>D>3UmFBj+45_sNq1uG;-2WT6605p5DwDz$!v7py-45hqzw&4GL<; zc3_+Fw>U8*{bBeHQJ;6}YZgnhnIJdvg!Ff8k5Dj2B;D({{d+IP9Wn37j6=TyyF)J3 zWOW`OaQPL3nSc$eA)tcO4PxmnllzSmPu|H(u@M72${-I?IM2;*MZzOjz!>_wgj;ij zqKgq=LpA+qLeWk%o7|8?H=m>oL<_w{Tpk?a%-q~DE^2E4xw4uj=k|55s9rv-=H=rY z{dw#p4o41<&K`a9bdfiJx8$Vay9#bcGcRU!`w$?mdqRa7MUXCzj4%EX;L|fVRRO+9 z4tfwdm>>3K+qtQ)+3AHzfe_Fe%vrljjzz>$kbS_(jrh9#!gsf5j%NX%zn($~`9-S* zTzOxo<@8BN<0$|KTFA*0sWcFomA3eWp7%Qmg*P$FU+xt2m+nE&+@8%-?qB+UtVHEi z$UeX(AyxB*_FYh;;cwqR0Wzd^0-ZhIALNkDNbikXxR%aJO%e^AtSh3Lv`l{&ZQ2Qi z^KPY#V4m>Ez3o7{*H*WGBSx~hDn|d%@$_7mGPiDj-j_j|-Q}=5&f$3CUy*nGY}lTo zGJz_@aSgaqQ7E$4peGP{$3&lELIbR}((m8PoeDv397vXy?RA6Hv{s%1X&>>2qx=`T z*BboYGHweRli*q0qXkw9noH$bX^m5V=Pk1x@T83J?hP5%^@VpSLYAkTIi7FD4r*NP zvc&%vXWu0>u_x>E4MYK9QbAoX^{^XqRLpB1A}@1-1v2%a;w|b7Z%=diT;qJGTCtwt z0muQA8BQ#HFKB8~f}cO7*M#LB@;Y~4HC=*0AQiFI9M;mS>eB__Zg9Qe}MEABDnSI-m--&eb6_TZC&)cLcZT^l+v=3uf?W!ah0fnj zTBL6Bmjy3JG_GYXHk8<;AgSxG{wZ|7B~4d`RPi$WP<<`+37~>WOv3(l)=A-MlhJGu z|LaQxWBEP=T*YF0&z$bs-#pMf7Qg?|6?4+C5NXZYU#{5u(q*y;X` zP1K{-I~rRC-!}yI_+LmlJ{oR%&HGJ0Z33qkFb($WNVjO{l>H&raB!m2V+7{=psOMx zkfuGhSV!4a==2XK`NcYe$Di{Z#Aq1;l%&!jRypt1sUw|WbW51D442iG-^f)&FtjY_ zyy(OZVAuJ6Q~dDPDkV#w4acRXr8Q~RBgs!Gw-Yq)9Qv0PdhgS(Y9u8vUs(>=q4+Pr zMey{Aaii=v2}8HaBbl}k%ecI;3qRxc9ro2TGOwu}LAtkfgRphHLRKM-OfItnp3rg{8q8k|TWl@!8V73PO6TQ^~^>i?Avm!L}RUlFm+2Ql9K}4K0KmIUpUy zvIZK?y6glqvGv6J;18NQr9Yp2sLYSFWUEU&@_8|%nzq8&)pW*LfcXXW>aQOjp0k;)Wc$KQ?XtUT z3>@~lIvKIpq2Kn_rXuKWBq4j-fMwL)^ATzrpm;kwn_MJ)l=1D?;#wbkY3>B-gNxB8 z1xE?m3pyq1FSigP0bz}XI0x5}G9g)TzYtWxZLa`em>8;gws)6hNxv?|pTNX*kSS|i z)9(5sryXMOMp4Ff5g5u`<$hUl+%aIKep!}JQyUBE4G}WNTV^Udo^_{&Cjo+O?g`|RVm6M zC}NwW&p*O;x@5NT-KRJg9#+=Ut@-Nn$NvVXZE?x$PD&RMbq}})c{-%5^94oTYX(gd|8;2!!2T+2)K*9A zBo}4+`e%*FuZ!PY#!!SiRH4mQbPUEDf~cp2PrQiEKoj{ugrE<3L|m(zWqy3d-68FM zHGXX(rA^e21ZAXdJ105y3B__;TX&YD3JYlOxGVBCt$~K<$PAVJXUUw*o!p^V3-YDd`M^+A)k`j(A#sK5$9v;su4)OV}^G8|CYmI^agW3w)&*Qx9WX6lSldcs0j5xt(*% zavVUp*B;FxY8a@h=0A+kQl_Bo;rO|7B*GS2@XB z@IQqBsK2tLa*~%Jt5#j^?kNP|2i^ivC26`gmRUGCM+mycRu{{z@M|>3(sT4&=%>1xiw41n*&HkVY$vAjSPc4scrZoxh2DdOdkY?t{xMe2-7nTzSr{c|a+gU!a^}fEtZY(0el~%5-_b&oc;08ZPiK z1_+td&o*ssJP?XW@~DI?ChnhUMlG9;oy69w+=KE=N2-I!9x~!IPZ95JLYmRmUXgZa_{i3GnsH~%2 z2$txM;V=i>U?1-$@eQkTP38mbI2L)RZxCuBYvrxK?eo{)1&Tl~69oM6pJqZyb12Kj z>c3Kyl_C?1g_TOH!bGmw7=Bo4d}XRvpR#S-vH*e)5`zW94^_Q@`5)e_k*E zB#ujpoH<8aMfPJG$g%q&)}dKKDZ!@nk~faJT`hI3%BlO$)b}@8r{=`7hS*jlP0cdh zA5C_ar-f+vV)q9{!aB6vBNeL%W*GJu%b%lvO=Ae297#B@j+GvR0i`zl57&3P?hqi3&B?8s~G zqYCrCB}vxnuWtEZs|Fd{{>TGh7Y)ztdPh}-Iq0d zDQssc@8njxMY+Ak{P^~MPn;LZpxIqrzWJH_9MLv#Fs}!wSu4xS$y*En!a16g%+J*3xti8)$SgqnpCVF4Ts4RwE5_eav8^bJB32SMl@Fs*D+2ljGs6? z#Y#dev07G})!u_T9K=E~QZ3iISL&c7}C{8>2n%d4Y^lua0o} zrn;b5s=UX09vK!$yuWz!`BI`rc&YW9gM$q>%_rht`rnac{r5VwIBrV({grSLA9kaR za;Q3f{CWEx>?P3I$z>D~owUSO*u3&2)s~j^!^q}?Mti&Gna?3YKkN7?dmMur zSIbN%jR;;=G1lFe>P;YQ^@E3rwHI3+#r4WFm6HDuXspbs{4~%lssx!(g8hhuAvqRi zn@#N>C;R#BhzSwov)UaeYFfh@@)>2F9qUs!jCvf}Pzz}aMz6`R6pduF=D2DH1DZkv zB7>=`DeTxu&CNcWJ7^`rPCSc97us!o&Aj;9>J|>kbb-xwRz-Mu35KnN^2g)b^;de+ zlUfy^uQLvk;9ineDW1?W?BQ>f#m%5ANNAQVi-h}PI%olaJ*aXX7Aw)lQKja3%g z=)due`igzRr)HD>GA4;8X4DtqG`6Stu*iXr@_7b1iN##CMUid+(HO^J=%fmP;~9RQ zKvT!*(Mu2w6Z=PI^Y1?|Bf>b(7l|(W z+Y>}hXi5(X{=EM}E!RA@kpeigbnllBg2}e`mvudRBJ=vv@s|Kz=E*%$8lP*1rf1Nr ziC{{ME&q(WVX8TlX^t2MEZv~z>F-0*bz;&JUvPsWCQwsOX3xjZd&4Lj zc9WtMBZqBmKcbM^)m|jNdXmfEEbXDSlXXwIU)Fi>O*epB&I<1N0}`U(Y7@AsO$p-v ze@%JWDgqDb{i*iqphO?=C3bI9fIP|`F~?YF!z9~1_V~s; zZq$7&JbLFRldUqNk1C@&ExTyT^~DH5b7i}wdn3oP6J90;lUX7k zb>to0xK-BR|D6tFU891LL4B1Pjpb>7BU>{(pkp#j%nqi;=Cp}dI0-Jf5BLs8o(Ode zPETh{ZeA40yR8Mo-gV^4b2c%2@(l6q4F0E359**uHVCW*O&MkQ;O_Q9tUSn_jpVQ{ zX6DAZN>6{x0qimu-yC_-dvnTH?n|3&&X3mFgbJVdK1hg%74Q%_c?H2~JRZ5tx>3%5 zKNN~#t+>p*&HgiT`ziP?45IK1S?{BXA9?W@ls$-=Qth%TG7>y4;ooA*rmiVrVJ83K zm)p&;BNA@83 zyF7uJ_{wkX4LiSA6T~stOJS4pO!OJ1g+898CX8oA;-=MBy1<~&Ps17cr_iu0p^CfB z<5G-uv~cCIXv2qh6hjx}*d-I$_yBz9)~67C+b(A_E^??YxsUZ;(B}Mkopch8r@DDz zRLSr0YW#w1Ln!=}pXjf_yjEQ)EWtFB4rH9edH+76g}^n(Oh7FBO`5p}_!WbA8P#v( ztK(S? zCCksj)_;0F4VF#_s0mslPMfNwSFtm%NV%Tik?_Sct@8NIZuCb3>9c#@kBicNeywur zEXDg_0GJbd9D$blJVNWpF6W+59>$I4OfBVuL7BHPh4hbpUQRyeF1`NjGst$^_jEmP z3Akd>{wH0o+L|IJ)hk`9Qm^}vYDq?8tfh*nGH!*)Uc|ftFonJS(^T#lzk%mpVZSW~ zIJDRD5O@Twf;)@=9c$XShis&nImXv!nIZjK197K^y;+Ma`~LG7dlTC6V1_JDkoIIN zHHm3;c>xp8osBDScE`cqsMeVGe}#=E8LZ4w^0NU0fYc$^6OX(dS8>r!f* zIywSLCWNb}y^hFZ-ruH@gepth23ug6-K2J+_ow;}ofJ#3hi*>{=SZZaNY*nhnhT{x z+)p}`0X|TCV3ojAtbHqMu0Sbn+|z0h7-05$U9AlB`GlelRx=8ZUdt|%Kn6!CH1 z<)ckV3O8&7OjVb?VRl+n?G+Ulx^e<8?80a=GUcLP0B8$34=)AJNhTfC0#wyu6 zTJY#k8NlM2sdwCn)6ue}+Mquk6R`YXrm5e_l1ZWWF?}c^-9Y?S&L(PHe(K_|_*wtL zZW-iDFp%twy{KQ-cQ#*BQhP;C6~(>;WN;PN8+Tfa%H&+leRZ7=%s2r_Wu%i3K2%jpeK z;WBLl?ht_)R?+?=f-OCYdj}T~M!o z5*I*kJTY@uEskt`HIUfv&7u}Ty;7ZUS}d2Cf4IELm2 zKWPxRvg_$Udv?DO;jW`d4tzZe%Y|<*A60>fX{K z9JP5A&E`xUaP3ux+_8iP^8aB&%Dg+}5nzS)VZw?mx_B*LP6=}(NW&1taQrvgyB8NO zw3vqt8l`CpsPl~b6;UEy)Jtu;1AtY-(mcF-sir2?CJf8++(o)UW4`Gx%}ustl%FbE zn8ozs?VQH;?kl{NOq6{+Z;c;rH(R;g`X;{MFU~=l_mOYl{Ax1s;vw-bB$8_-1;^C! zro6l$_}kQUvv{U(9H0xo}7DqbBK#*Tz^6=x`A=#2>oYr3h<)w%Fi8ipD8^{ax>^| zjCxFb3^!~Gc%iIh`yuR^y}jNaN}R3Q2g&S%Cz;@TPwY?PGt!j2SL>2L%SNY^Faxs{ z1gFy)uuP^9P}#OD>&lz!MHR~APkb=LEf+u7UDD8Q@!RTsolkkPPCtSqE5vVCw3Ro+ zoccxa>tMmcjUw6V(K)jKXk&Vyi2K;@J^IE6KpllwR{wp?qAW^F)8#d1$+Z+1Fg)56 zTFmWbqr70vK5SW$s4Uc{I`$MrNO&BJ+~jxzN<&LkGgq9WfL%^dW<&qP{LwFucQ48O zW=#H5bW?Kj%tNJ~qx`b(=?AKZRRk1}yj z2sSnI*5>D5%*&NA{%HqToXy!Mu8QZBdsE3D+cMc(897lLa-yclgs*i0BuAI3e1ZY7 zr2$tOF2Z19G76=}hs#L<+GB=b?v%J0CREEw8T)2k0*n4v*n25<%wQh5=q-C%iDEu1 zI$c?M>GM4BXr55s?f&;X(Wp-PpHYAgr^m#E{JW1#o3$7laSETty%}L0+(u%3<;*U- za=mMzO_i51E+ZCEMh4DqobC0~`#x%RV@s<+i@#Z58$0~3YIGu?t5GK`;0nGdJQE zlR9#ith6DE2F@)2DEeydLc3l?fC9|1kZd>)ZxXIMeZkkT(+XZ3^i5YZ3L=|ecWUhP zFv73F@OznQI%yqD-TqMpSNNX^STG5%DuQ>7!%?pcm-nBve<`Z|Rn*dJFtM}l@>c+7 zr{-v85Z+}44gI#lVEd}u=BA6@a)mR`hd?gO!gcR}??N*#Rtr`!CLzhvDmIIAka=2I zfiqdz0>dZ~Y~&}r=3-U9@z=a@I{N)vCcNpuS9^!@kIgRPvn`btH~KBn=Y};*o6S^w zCU)H&`>#Xfa^{&UEAF^xNn3qMjISOVrDzadZp!yT>}z;`^a)=qd!zHvw$)r}Ef;p3#{Ilm?b+%#g9mK6Jmcyt8ZG4ZA0 zur`C8ZQeH&d&WKX9TYPzOVL#<%{n2WPGbZJdd>1a(!01&xC0-4Q;nV=KO5v`RPy=a z2BGWJWMoQK(U0w};o)-)hu&HmB?$EzMS0}B=xsFNjJKx>HH;VBlEQu0d^vH*__?Rn znTS*5e`YNuhx)pi8FekIS`la0h%X6QH7Eb`6yX9z{7y?5H&mhh{&_&~S2k|a+|=<< zfp&X!e11T=zLkPnnJvi@d>?c#sV1<0G~>LNR7DZrvUl*|Ewo}x!rXfUM4CXRI@z5n zRV*D=eZdcbg(-bQLOK3`RKkVY)Y~`Wd0zfV6FY&XT~uC#n5(s2NAd_TjJ!_I1Nx30 zLOzlJE#PJn8X9aEXNY&T)(Jh=(jQ|Io%JuG^Cv)U4&M2fb}sf?izLbLu%+`9YzaV6 z_MH^L5)V&_)Af0#ciw;FW*D6km<$zxFf4u^*vTH4DFO?7a1YbCI;@k@IJlf8JhQjXEwkbBG{LAR75k9IhiDtK1<6zy%!?k4FJ1)@u~u^vxL!_ zBcq?5I~pXc7`rvTbxD6m<`!6wI{y$d^ta|ERg-W*LdfkWw^^33SzjaTS77SQIjPc2 zNY#f;z;-~K)S+nHXq%qA+=k|4B)U7}vq6#OxCjjY{n&|E-2hw@f90Mf$ut98Q$yP) zEl&)JaMG6DKm>zDcG4*gC(fWvP2YHlUFgXwzI9(f4E*inH_LR!+t*W&o_a5)my(ChvX?cxhzqlWvzbn7SZNF07yWQ><9) zqlJbtp$4CU*uw}`7!i3bZe}46aMMx&X6m79nXV( zo1(aMQ%5~9S>T57W)d+7m%};3cd!-F0yB7Sg=ccYb|$jnwBlHkQ(9C2Zm!&0KsFMVwae^AZOEin)uH z%l;Sk!@r|k^XaZl>@%MKSlB~VA_oY8h&5RLQtQUiqNH55v3+p)&L!P>7J2bSFMJ#W zs5;inNwpe^j^&pt^J(GEss{d4;FM#rx|g2hPzv{Tef%Zrx1V_Vz%OsyQ{omNzI8(F zQE$d4K)m-oTm>(dH_THs{+%(A+B>wUazWTFD#taD%ZsdIHw7T_9Ej{024-(?yXzl#+5=Gu1=akWbr;**s@+nar|4qhF`y( zehI(sSpL{s8t}yMXU;oG^Z!W+fqwF1{Xgw%r3cntvWcsjn)R+7Q8>K3S0gYM~DAExbauyGBuCl}IjEyRBecNW6$wNW33lYs4#3w{gimsz+Z zO!(9q18L!9oRf0CC4jrGQd{SpW567>GMti$M%)Z@*;H5m$eV*F1#iX^h>PFz z*tw!9vhq%92Y(j*D!-vt#9JQ737y|h2|L0d>7ny4?pHjFWDVEhSNN+3-1_)9hpw=Z zn`SECLuxsMkwxd&VV!pabo(smLBxM(dxsn0E0bPj%hu$Y;l~|FY^}BCA-#%m!+`b$ zm!qF37E_5z7h^41)K0!?)Qd7LH__gVv^_S!)r6CN`u0{Pgk4>U682dGtsDSdF~JDg zdvWAJ<)f+okEpM3YwCZ)wow!iDU}is5GiSCrF%3;igb?dZ6YN(Lb|&_x|xb}x70?D z5gR>XgLmKG`(D@k51g}e&OT4v_x;=t*EN^S>^fvYmHt%$eiMcgCVNtfX9#;~1&0=)%C=Rnif^b@Dyy-uL`wV+(` zSp|yaphMHaj7CB*w0S%-Dt~(3I;&9+iwDu~4r!XS+h><RN6 zJNJx9v%~P$7XfrjxibhVfmH`{1_sa0qjHUUfRvhDmbR(ud^_ z|McapTh%L!fT@HD>0QCJEK^$#R$N}_`}`OR@wy{xi46;1h%E4J2>pj;GCVIX5Rzf$wA9;uw5{`ZWG#}W|nxErjn+2d6=WQaj9Crmdq&2 zMd|$DSnJ1Z5M`GVr=jN9SFzWZ37!+j#LrHJoa%tAkyianZ9zMZk|Ly%9&h9O1&5FdnJInLd9%X>Dd=zMQTjt+ zUp6Zn&DQ`kN`3&PSYYsTr$qV$LIc^AH$YRSS@%O>+F|*J9+b zm;&<6z2CbBalOp4wH0C$cN@Y?#^Q70GT5R8*Xl7*JI7M5nP;<3B;#uM1(F+ozLY<@ zRBWUHBU*B0f|Dlb7sOV*iR*y=duFl@9d2dh#QA4S>LG=Tl$lb0Cu56xxoGA1i_E85 zcfn8jZME0-oUalA>N0K>e!qlkx@F%dOV5xO=TKR?1aTYN^IjcoJ_xW(==5{UT%h&2 z6Wy>{>zq;OE#&dON+d(`v++9@e`7j&o9_JfcjW!0ytRT6o{`E?%#GR|Lv`c94(fsq zc%^J|E2)JRDgvIe*>Zjmla-vNd|y>Zw7;f)>AS<>`LL=2Nq85HDn%#>}i#0s&2_@etHmOqe+ke+)aZ9%Jb4pI|8WH3l6eYjkDOctg zfAZlnZSJFlQ4yo)1MRix6V{m`s{0EiDnFkP73z#XAuc-pzlZUW{asacg&%BvN*e_d zW%rAyo=)0ybj`A_eVY0#|LHH&0q7#)Y9`gvPXYWjv%+I^`n$iZa0`vCZ0RD7`t(N9nIkB~6_DO5C&G+w@Gq!Hk<1U-t}m z9)S)y_vzd+@0O1(N1OGrjoZJ2&uVvH2@nN^Ps{vrB59(h>-U?Gai|a5=&|Ja=Fr20 z@f+;K=o#t{s2qLoObSsS-ffLispY=Oxvzc2SDII5E411^B&1N18&jC!UEBjbC+{JE zbF5c+@3czuW`>GLf`oDZ!cb`+9_O4YH7RE(aQ$0Q?kKNx&X|}eWmj%uayg(=n_zl+ z)Gs*qY*Sf8AtLY>YgLtEqGtF9(;o_cn)-%xk+qR;YeL6^o?yKkRvGU04t*Eo?mP#6 zFE*&?flE|TDw6bE7P`w^M^Q625QE-{>cYN%V64^azc8u!lvtY{C)TeCI<!wE=7D8^W5K~QyF2=adJ!@XoVh>bN z%48?ni&tzlgd!5Q8S0tc_$rs`RNR{be-OvD<)wdTGDktm6>55FP({k%9+$S(AaJXS zEzsx1r>O6_arcZAOkb4{ONX5d<;zlV%UT9)KD?Q>R97#!6qHDCQRjY;QOu&d;JoiX z>wJVHOZ=|w5oQC_KP9yXE=Yo?0)XS z1}_|JX9f`(^}-UAx~T3-kJOT?TXQaPTdARxoq1%S^KMTp?AlT6=G(C%gho?{`uh)K zVi3oP4v5)a&O@p}uidPk&C)9n~Y7CU@?-YKl5OSay}r2RQ?Q1sVi$f{hc%zkf!`Df+yYJ;|^V!{k-rG;oC+= zW@OL56X=d!{@bnQ>5G4caH0vJ$(}vdrAP2U&*^@q*?Kx-bGs?BB$8P^{zzZ?LWJ!~ zdf%)D=a(m0D4y9h^-dP$QwNW+unOUHQh`))jt^R*8$QF7N{WYdFRG=9M_jlvuXkbB z74N$+AWXr{HRh&x*A#e_pS|dLTF5RLQ4PWG>R2*}@zkmd&xf2LAdm$=q^X_7mYJnp zAPeJ@B6063^>)gXpSEvQCnnRulN ze+F!qKb{ZOQarXU?2r{MdiE;>KL$Y`%O7KK*>x@&Y;q+$3KFeMPV%y0?R7l9N2t<}FU|ZIHJ)Z6@3VKk)3o3gL$AGb%v9_6R z3T{gtW0D+}cR0+g%%BI@Mad=U5d?-jwrgnO1Pi&rZsNV0Mgia>OEE527^7GlBEw0d z3*q8I=Y8IQo;3!l6EOz9TR!Y(iHht~|wphFgJ~?O| zgTzYV^2li9dyE$COJqjd9iXYvcp~Y8-}w`kj92fKZi+=Z?cH#rK3%FgH#j8fHkt3O zy~|~cRD7)H*0r(|k642p51B2+8{ zQI_mfSj2j-NEaWy+b+wt78I;YxMp7Sm&TI%6QLSEb+Z-`Au+Hh}KZ31U=k3LIhs_9Yn;SL?&@&csZ41K#d~A zg@6Y2i-Y`+HM)rB>f?SdABN_N0Sn>AtVfT1S zC(in$u?7?)bvXg0MpZSz%Vl<$$UqP2{rXr?KWcKc3v+OV>{HYkz>j@W+y4eX1YQiS zk32-L7BBw0JgtF%madt|@){K#qN__b4d8^6-ZF9yz6wY1Lgt4Qu~!=?Jlvr|WpNPS zw0_lju??2CE4(?kKELuuiX+lABu{nyH#yC;3TwJ{9Q-Gu%yi8(jQ<(tu{E=FF4)~J zx5&Q-svu+#*`9yxURx`3>9jsX(q|%_DBr|>N3&yxw)3?pR8mc#b-XulqyxW?`H+#6 z!B>uJQC|~jn}``~Kuqgdc)V~nERW>3=PnLgdbDx)Q?j<9FI-Bn%@*pX7B6bbyB=P~ z%Q+jB2xX_ThYbu;fVb`Fm)si6x}@TvfVZM3#W$zNQk z%*lhCn~R*yi+vX#@ykCnU7DFgBSs7W(4bD#daU@q5=Qh;@}w~lre6rVoT-_tZr@W$ zKae`=XF(AnEyusi;7lRGp$b12fzZXzrlv1A#xD~#*ToRxrvW{O@z6l4+6kw2=jMXT z!HH3FD~N@K*AWMM3Q~h{m3lr^J z5AmVg1b}vQIB6T{uFqDAN%gcBy>ZZoz$BzXVpw{obF(v^s-3Q4}x?;|5%#sY=?>>K4hORZns z%RAU}=reo)gvpcwx<>y_pV-;EYPgjihZQ z7Hd+e$E~mWH}&hDG7aJ%LGHyh=o{QxSA|}rn37!m_z>A)Y!o-Duydc?Uo}-px|Oojp@m% zW1=Uk`T$MP(YfL2qx!!px<FHj2}K6JuE6}F0wC;d%*O^ySkA4PF-JP zhe}$@_>rwh*hx<4mDpPTIly}Z@GX#D#lno#bNKLgCr_Kt7{lXCqFs~SC-YqWv4+&se(1|jLN};ng5$XLv|4|*Q?Ra)za&Lf zUgOTOm{D$osKgXU&3#wu&%-K8<`&V8HF$x}jUrxdDWc5-!ubjDMu4z&I9|xbW9Nnm z1?$WD9K6$EQ}h%-x>KpW4ZZ&o+kuoUd&JYWoxgV8HrE;3b>72EjYN;IqwAx_z-RSQ zCrJio$^n>8pF_V#1eX~pzE#AJH7UmxDcRHWKItx{c5|by8$5>BPxN9VG3s~>g!YiX z4584-WyGxzoxrZ=&SUP31#SsM0gOke^_4w7(I4Fve`N(8QPPvxvmh&gs!0VO@B;BP zmwgai-)H=nE|66q3~+OeYPcd%INs-57eSq01rGDAkJ+?}+}-=xO?pBoURnt^K8KyN z@)iRjj=1>{pN?bthCYUX$@=WmVP?=@@^z6%Cg2O}^&_8-`t!~Il8#v+bprM(cm&-X5LMW2tGJ9R%^$-;R_<;Z3s^~p zTS6t1(S()>y3v2Gqa=Mj0WIZj$Sc)-^=$0>S_P+JK@|t{f+^@!Padvnel#f~-R|ad zV2MG5ZT4Q*7t~5`U9XS%)BA5%ZKuF+@)tJT*cVl`=-%k%(`p~us-6O+%?N2X6G{Qj zJCr@+`LFW)^Dct-0(`)ydIl4!io4c1pfjE$LOub`)YO^9uI5+@=msXB z^FjmZ5Q$itqeDe&2r@gs9e&CqfBBaJA-m|@>^y%XkbM~ahfxMf+Ofxb{QUS` zp~gM@??_T|WEZ2TGgpaq=*}t=$Vh|mr^w-m)uWc3Fs4Fsy%qjfG<6?eL5zwJ3I;a@XtHLd3#)zlu23}9b+=8aP{SojaL?UkO_*INzzUr$+akVbz|r2# z+>^#JPFSDLT~k)TD8Lm6Ir2GUpb)>Q?>U9~x#u_q&J*fXlai~yNY)e+nX%N4N29+% z-plKCs=S=rfmh-Pj!7VB*ZA?xYEv^k_NJjks?pbY%>3HjG+t_zo_$=I1+f8Tq5b`P zz96;)q`=P~@?TEsIV6Yr-rKJm8g-DgMYf5E)4Q(RmS4Ega8Z}K@f+i;wuMD3Nn$&W zBiD`LIO@xtxh@rPOoNBp1q9m+G3fX>KjwwRf=&vd$-BQg`6f|K2ts8n-+CqS(|8x{ z>`RKwg23(Q4gCofq;VnabRRh5>$!edVSbao$rbTg<11D~3XcNN^icpLY7bajWBu{8 z@DGUWz~cQ-Ufh#ga&Xj198IUPpIkjH`<#&&|@3cx3>#!%J(pl@z6c#k?q+Fsuc5&eG;F!nzPKi zW|EC3D8dD$UhWe80D5~_;=>U)*=O@UxUj~tXxul<_1Mk0ID!vM zkrhy|N&p`W&htob_>P2@GdQwLQ7eHXB*SylGDAmV7p)}IAFV0-cOMsBi|&+0Ui)1? z4!M3YkPHRwS)K&N)1wcja`2Ug6ucS35RqgTZj->n_udWrO^f5}3|H^{)nA8=^ETub z1bH3XR1r{?`B%k+akvK~6+h}o?@MYu$@nEoo}6JV&UldFsd=_P=A2ZG`_)O7deFA5 zN5=O07bg`9YPyXnks}m(??ldq&5+GZfM5S*8NbqF`M2@SMzkZ}i_0}`_rx_mMG>&= zoMeu-EpxFECz|0;pmuq&LE{BwwKQ3>INe%?OwrmMD$-4>$W=0kubTwAW!)}g z;w~%A6Q35scalPqP^Z_w6wna+P)$}9z`ab4uICu@LwiJeU?0^INpJu5+^!$8FFwuvRWxHmcNYs*J*Xa%IoLmRudH-#3FHXF;-H;a51Cx4);-hVI(7^ zW22~m=?o;*Qc;?5DOk2SZ|oFx@Rwbx_95HN2m(hUAMe|)7XCZB$;q`w?Yq*U zXZl;RG27dWk!6d|66H27!BPp<$V`w%?I`^QG8OHOZKooG0L1YP%-kXv6Sp2J&uc&A z6b5jzuK%c8cpUFL8UCnySLNhz1 zxd*C=-{%KzVCNUSk@fXsqV3NE8b;|NW2j5A%v@$8y~io@N}!L4QJtSON4wX$s=1({ zJaIxhvqSSPof7yK<|*gtwZNs$AJFv?zN8T&K{F!4N=dkq6u7JqGaFTc5t(TLsEZ!N z7+E5Qe%S9DZ7$aPn(d1@3*lTk(+>oH_yXj64g#rp5?0w+?6@9}!d7rceIzc&{Y>F> z+Ti3#(AKD=M0lzRQpmvElx^82{%NoJj=&M-X6%L|7T`Civpoj67U&E-`L#R)x_SiU z6&7%ALY)hg*5FGZ`NoXk^NnLeh5gmd#Ifmrj!+02V3I z56)pX*qg~A^XsE8cayrY*T?{h`BFe;4jzZ>A-hK>gHmz&y|lo z6IUOwj8#6(6SF{J_nZii3{##qUnh(S#(%D$xof|w2Wd~g)JxT@wH(vFzJH^JJ{Id< zMvb+Pb;P(}TalT@=j<*NmEARCQWXsv5y!}rM?h%{%Jr6S+3$`7=$mrR(@oet@OCWg%uGe3 z{s~`_+CZz{CZ2;&3J-0Q%+J5kj5CE35Dz5B_DxS`>ZS6Kid$)5KepBhee#4Z8 zy#JWw*&E?PGyi#w`}HnUuq7u6iSzGzTr_uL9SKI_1a0_Jr&rvpurYzcfpRgmSG*eo z4uPR}Buy5n>}d~NS`8G|{C&mE0ltYz0A{0K_x2hzf_fh~3r{za>cdvi-@n)K$jnW{*0kM^SD7+~PtCcm9G+sK0u zc8Q=-QDo*($|?-E$!mW-9{o(P#DC|l&9{ML2EE9DuLmuC($(*MfbylEtAs_zhpDv@}ON}!6&Dy ztgg(;z4>8b%}UI_0Y;(Uf&LlwcrQ8|&_#{tf6i_6;>vso-hkslG0u`KnB)ws`&CcplriK(DU8+7XLg`NQ z&7Ze|4&zr7K&1$K)WVUUVwfQ=+-NNmZpyaRlC`+86*QY}Zc9pI9>~`dMYTeLTmP;wCU{1Y^{d&7a*Kyk7?)qrBND zKpw9}@p8nvPy}JH+XYaDc_#$NV&?nFQ`|mV!i_fOyX*VQ6DFb>^R8iEcMCX@FEV{2 zzU-x>l>m3V6Cotx#*T1=0+xRHD7m?i7Jd*We|c+?91!)M_>nc?Q_+^@@z%r33fM~+$L_|2$-jWQ ziJA3tTZv#&+W9n6m+G7S(k18TKCZwn586hC>!0CND0aZ?{0nKini3J%g?cEaeKXm3 zJnlnr`>^7soENfnze>HUn~p=AWCR=MPPn7He`v^seKZm8|e}S;V5$6Ak>h;U2QQ&V2=$DM%*lg zG0myitFHGV-A+Q5e1$UijUKI-I^V4HIs-A@W1M?v#Dnmc(7Orrf1M$`Y(?R}EPdk< zzvW%n{k!0FO}N2N9-J~z-0mI6k`QTVQf$NkhZC&y<0mMUwq60_9KWc;m8%>d`pW8( z%syRR`KdK(4Px$bc$$^6Fm_9d{gg|~d0lrt+&U1T5pAXP&bjJyLI!*G1MQ-(H%6j0 z;SaoC4d+Isoe`!8CRhY}KHohRnhPm?TN(d5+KO$aASJIl;^*j)AwVf0oH6G8*+SVp zV#|=d&=)e6WkOuVi1eni1eebM&#uh=tqNlNb94O~U0#)yj>8@j`q@Wc5h5JdT3Kl_ z#1H+tlv3%<;p)W6&0lQwsOmf`FAz_v=O2vHfcu5=-i20W-BV&Uc#vh-X*X<5A?gr3 zz^7J7XCU-jswAozRRz>V+*?p1deUT1BB!%M!-u3zdsWsvE9YzE^$Ill2iR0mO`JBd zTKUSRW`4^5$t-_|elX`x+_b{3?&QGoy$uT`{D`K|*`vf%cMSB?Ue9w-=jb&g%3%rh%+|JWrlT54Rkl@(8zOBnlMH` z(ToZoPS}4!r~-34{l@7BW%{ATUNMvU4j}EzB#B(l32LiZcv#Q#P2e(r*OKlSr*)<> z?PsNEbF%TI$wu*GBkXy*?)N4?zUT-+6nLj26Z>06Mep-Vpd%YzN^09mq1~6AHwVeh=XG)sT5H z|Hf3#wV>pQ1sTb4mcv5TB{tylygsE*a^L=>+6NXu30I{_5H6Bo7Ud}CF8@lA zwc=T7dx(WRbsSOaTV~>s_Ug($*sP-T@gu>Og+r95-(t7310 zcGzB|GTW6(F{&A!&B!0*Ek)(^ic;v|<3V-=~9HK2V*&cLHCYj9q5 z;6sK=qE=;9FllY!81hlY?yjK%bn4qys+H%XE%<+5;t02)qd@@Nkc$mNqn7RSAngUv zORee&kuFqBj~k43-=HJZ9+xJLebKQW46^U8?L!CrK$_V=kNbeD%kD#m9d5E>O#>x& zW93%W6}+=6-0-_l>7X9OuRHjs3Mk$=d{M9Kw*K{&2u-r}e}IgmSC-@s{Q3I9Su-rl z4BIwG1=MtR&AIOh^j}WDpre~JwM7-MgBoy7Snov_Rf|*^2A9UoX$`nn^YY-aDsN}Q zcxbjFhVkM$3lw;LK{GuNd9lBL3;?eso`g%|^33|IljpSfOir@ z5vYTP63HZ~vqPxCUZ13bCHvfa7;k`D?<{t+_p)w))@(T={i5VcmWiuWX$f*Rq5Deu zAZTzR7~#lStvt1#C+5!8_%OIoaXQCg{j#r9bQtu<0~ui=b|{I-qv>!hhb*z%l1UtV zSctticvjoWC;oi1BYpIL5}?c52}=^ZTk6cf_^H{Q!G@hiEz?C7=M4ZZeCNWZGCy0> zdCBsaMt@R(LX6t@fr6#5U>uXcU$%__59b3Tnfk9bGyfTp%RkkAscjaP8%nR0{u8|R zTP)v~klYAzBXzIDggHlB{xOz~KVuea#XRe;R~)y!^=wqU7-S3aOYK5jqsn{v%FFhT zQTK+)jXVdDBb0$oz6@gK_dbIO_*@S2tqTIW(4r(wp!2Goz;y)|y9^3B62uLnEr44c zCq=wPa~)ek@|Taz&t)#sKF0o=#?o?TUku+EOI7;LRG57VWc~y3b{XPsu54Vi2&W(P zpt17mFn1qdrTo)N%d68r{8rHno(N+nuS@dZTUbxMVwAN|GG{)T&( zXvfw}O&)I``ItyJck{nzTNzrnOf3TlP$!49BY`eo&dHXV|Gru~ZI*+5?+)!UpB zu(8HqL-)Xbw%lt@;^fZ0yE*mO0L>PxRKS!nqj*{AWeB@e9`leCcK#5VMJjnR{`OEA z(hg;Kiy*XN#fp+UTJmQ@W@nRY^_2wZ-9W1cq(22>uKf4z{h;slagI3(A(?u<$qN>R z4;P`{R+!-0WCk;zH5rkj@i8t92)jybF*F9<9K5JjH>I%$21p^j`t!ndFON-IiJY-t zu!{pPd|($_X5qAI!c=qwiG}CCZ47~3my4G|Suz&P!B$CFUOWrv&vuQY6oD zdshMY)Ev=mf$3Cq+%HUw9D6KI={R!f#)z1fB^3=>SgZEwq+Ld7D8~09@>7e{pH6OZ zq~w>`=(?1NscA@|1=?&G#qI0N6tK=E6OzXbQdje1)P1t-*kNL}tiTQ*LXi4o1>Ibi zjPzS6U)r+~;oJea)U__myOBZ8ySEA1#Vr1eFcpk^+heT-FtKu$rJ5O1?e}-8R%&mU z7RULs3N$`wI5@_19FK9%mh^F&9Yz{u0l~)^o3_6taCg12X^m{-VGiptBHxON|NVP6 z(wwA!`O8J?@_zAbB(`I|ID;zZ{)u-{#$%Um$b6)_AjE&!Yfi7!8P=oe;T z+`+BY$6L0jJI=N5`ENFyX0Sz#<;1Q?-3I?9SDY@@7yilT)P`bfSafNhoXfIQbtorF$uv`SL$9Bhx$BGo;&^|EE*Z_1Z5gzQ0UN~3h z%B-%~wQA}PrMYf;Pwg=o3-Mjs`b7XAbWnXI%j|GGnZ8X>Djq6V$wX(gd0HjIGF<~) z7k&j4h!Aq>>e=cc!0hkWqnY=&j;IP6e?wM0e&45wMh|5tT{mSpJ@E1z6~!(Q=eSfZ zzZY+*J)_O07fvOiGHZGvKUZ$z5%qwRkk9#;f(mg<%}t8Sk9`@n(4!$9Sd(D4b+mv6@m0U=w# z_r3ggr@v`v8W!;Sw6UtaUQT^(=D9!c(pA_}5MD@F!RCGISu0+bfngH3av?xeH=hFV zbLzU-I$1(Wr7+x__tBt;qz(+*`XtdG!J4qsD&SO~^fljqIMbl8fjP+QFpNCBCUBE8 z&c*2xwrh%c8|%XI&n3}3++3XaPiu?-`1r}UtE9@l3bWJlwV)Mt>5Bn<2` zPPuNLz)AmwscZ!@(6;PQM|%vzcz}u5sqbj(#a60286)gyv*yk80v}44B+!WyST&_ACzYlaWU#M`5#C; z(eWI}e?FPgr8|v>-{1gRW3bir`kWU)_xET2EK$4WH<#N%XephT+*aAgF)w!byqwfp zx?TVa1GC!^P&y!kUoH%RRL5Ym(1A#q;*i4N#oWCWOfy1v?JyVvfxQP4D78Y5QK<|m zsrgDTY&$}-O^Z|c?aYSD<+(9;{rY|dPqzbahKBG@DG2|W%M$%ko7hdqag>|So8D^| zpCUMUBKc!dR1Z^1g7J^nI|Ij0oi#k_C%RXVk{Cahi}&!%_h!64^aFjzQ71Q7bMb*4 z$61j=8*g4+Y#*fdNff{D^04Zr+O;keF{Nt$v|C$H*9^mldG(%tUT?{j&2@q!q?B&2u=O%cu5)6aKln~Khy=trew`3JL0wAb7P7ZB~ z$u*?$C-G=RN_EHDV8SJJQ1eUB1)-9~yLhsQ;by~iC|cA%lM;*t2|P|4fydP;^qIFt zeqn*uyDi;sZEQVc%NVyW$=3g2?lB^?NoGOUG;g!G#ti^dTxAFBY5i+gWDs30^x1EO z6pM6O;EIKsTQ~d{ofWV4Mc|cJ$q>KCS^f+5o@l>y5-xPOG@a_(Y;oBPgwJ&aET6s! z(RH4eSmA-009|eLCm+z3$7Xf}#jPjR_*&Plj{WW&m|3ndX7JP`NMqEl!r3MA0tHS- z6pxpkg>mB>;Rd{fyl9^|fzP>*6LQR#RUtLYQ38Egc+cH^WiGu*d70AO)u@D6J@d)s zZd%G;stn8tK$JZ17GGK=wGJp@WIX>$M2SSJ+ckGCJEI7Y56|Sy0a-yUc%)J}+ z<^4oPXQ#^OMwou{{B8umU;ASHb#pwZrW4D9*xQ_iE}jq9D3{Ycn^Rfyzj$u=hx{$^ z_zwx6--b8OFXtvYyjsTOZZZXGiCo-%aYx21gX@!{#6=e`Th?PaC(+#5E|yt{=`FCy zs<5YM)+T`u_futRhl0j~?ao$yE0MjZVPE(_Fd}*3{A)AnM?VvH)J}oFwuhZW;cUuF zrCILka6ilB)?d~yeVvwcIFDoEV5J_Uv;+Zqu&!(WZT?&al;5rcJ;4uf_)+@fprg2e zuq8p>5TQ-0^}YUL9N7%kS;n8!vhg=kB3(Rve&cI#IkZUn$z2vfg_uXDo!j?3 zI^p%;r=&6^bA0jo`?arn3-2qchYsTy3St9{pL@s<*Vn*6`!V?fM}=|OHG3Z2eb`SiQibrnR+Rwwhg}h zqq3CsC^XQ9w9wGczqf6;Z}r(_W5j9=o55%C5? zdxRtZ_k$gMgHPXNKSuFgztQFxioeu&)c&kzUtINeJKb+Vs`dR4@U~gs!hzsTlzgVs zSN-oUv}TJ1LzP)`(S7c)bm^EOq=+NIv!X$^Upv;`z@>z_$}#CO?2E8Vr#ZZ9*wQTh zwwgchsK#g%Gv`9>sQBof>fGxf zy_1k4XV}HDsYF>)7w)N*oU{8_eY0eNt4d6cM|j7?<4MHYuJtWD)n+O+ZGD||xQWwC zuhgW6Z$7C;kc3ClnwZzGzN<1mBOakULrzNMaA=<_t*tYW`6*p|`U3@@6!h>O0$qa- z7pr5%c1qWLOT?GU-nWUkb|NL&Cs8F(NYy^P?tq|Nqnadf{^t&3^Y*}+V*J_hd$!V? zN2FrgulxxbaC30mUVao$d87FGN-)Y97+~y%hKC%L0YK$}0$;CQv-BOo$)Rx=<>`!u zIu!;3>AQ~)(D8&^5||p~q5*6&fyoKb1^|k+ z0Gz-ZER5XJj2`_=L{o=-jDV`#?fy4&@x(hrt;pymwvRo39?c&|`2M=fsM)o@Ez5ZM z6tr>|Q&P{K6Y2)s48TTUc;MUmmfu#l2pHe*Z&&w_8SsS1xXTd*}FzDBY5R=YKdF5$bAMs*m8!>sAzyc z3=oKIx97YTHFfnvgT>FUK*JjXLTH1l>b8IaYV}xj74?5ST4V#HTk{W9NW9Y%Hnj}m zDjRR*O`nQK`?!CQZP~=bi(f>MwOAlb;&7RLGTGRLHC5G`Eur}<|4)*_%vX~bI(PXZ zQ8i)`^PAgbfh*hD&IVS2c7i#}lAId_UO5+@M~89?ZcHQbfNF< z6WZvbePi!7i9rc-MC56x3+ZYX^~ArEoJLPz_-e~)_PU7TGL|5wcEZzi9>`mN%70$| zNBYYneg33+@9v@=)pxQ`+L7ico=aI2FCE@Maq0?z1^aJzGZ>ZO=X@Apt=pJuG)BSW zY|8Uj5D}$4mY`-qjsMp<%k#2l9>m61ovSTaAGNj>VB9??=DZWf3h{Fg!p-)pfEni+ z#lGw0mp?XU2(m^x>GzWc|3TmOQ6nNH)4M*7!!>z6F*rtSaSc)eD=NRxDe6?OF2W7> z-CTixKLy;JLyJ0(;Mi-a}b@3d89O_I>Rl%EjfQsBJ6V<;pz zC15=!_$o8w>K=O6OdPBehp{ys_aw#CW8o(gi5mG3zabbU$^f>b7g~+`yD>73uK%80 zoil^3Pse0+q}lb+`_PS)8Bi%gO9hZXh>HuJ?5s2+Ed;yHLp{C24dmlzWH3BN!9jRk8rKNvWis&c&;ud;2!o z`{KfzhV@w57|d*e+w})6^yspo$O~JfqnPy6?;fMf8oz^$`tCkyJW5FXgPA4mZq_|| zU9uf`?DJhl<4Z+`0Jv)<1nq;kqP|3i@&;N=)YP*O6xJ%22a3JGuq(JRpr{~LqV7mk zPGpwm+8ZZ2?i0O%s7-8c8zoKeT18H23Bo!Ld>-4q{BP~A#22$%eZ?&nz`J|2rRmzZ(BIKDAPf*+MTfJ?cthfX)g!~urJ?&D7K~+SKn3&d1 z5fvo3v2T_3gIvbR;Y`IO+3(f5oyK;jqYj|%mA^r{I_kvV?@@cH(GEL0*3SQ{@%Q z^I`z@9Cvp&iJks7ld>nYhLh+jFJ5nKMlWIbAkZVH(O!JXc|piQC+$htx2Dg}suZ}3 z8`)<7FJkcVn=K-_7WjWKJ3;h~iB)vpbx?G2v0eH*70%F9x<~e4bMWAXfD_mfqK^9ibjN&E0r=v+Xq>CZGrm}FsM|0AcU z`Tez4r82gqBvA)nel-MVny=T{F|Z(EL(e^uwwTo(%Ox zehXLG>7!3j49+vc>W&ZnGUO}(4ICrS8B3){@&S36{g};zE8E+Wb_t08h~NoQ{edY# zYn4C>`@d}7jkl2xW@>f7IJSxe8bn@xScjs1m-^5*aNLeebYUuGCgZ2#iCHyLhphsx zm&s|^=;$Y5O}~i>H4EvctyuH#mOJpJ#LcDD!s9%Gk)g#F!0~7vE0)U1ze4ZlQO`)O zAhi=}-@c?RZd4iRvlpB+-}>NApN4dv)^b#8&lX7J6C?=1r`MdHl3rn8kXpZ?PKzOn zF-dG;1_t6`#QiE@Am_M))NwYFC4%SC&!3*mQ{@HfJGDF0!K z`desy@luBJb<5>bj~*rO-Mh|OoU(lYG?r``4=!v+v{QOve68xkYn?HAN7IdU^5OFq z7s|(1TAQu(j4pf2Mpvt3V{ay*?v}8jYEP@$(KrhD&m1bD+6K+GAACnk54QW=E5>Uz zq!`9F*9%lGd<*N$z6d-CwGiAdkneF^NE>2j_VS>~fPKd~f6GV>uVPq(vTg+opNiQa?J=u6um9DJ`U^G zs0myFGn;_G>e(80Gd$x@8J^!8X_`saae?ofV`fFkYrkI$jH45p!|XdqBRlgs)?fWGuXT-Jmi5|qk za{lx-CT42G>l>PHw<1CD8>9B%?XkCY<%I8JC>L_)wNjTok72+1)HnXzM?vNMv&{3a zBcoQLPi6YMURY(n68~VVBOyuDZ$1B*R$&CK0RBzwHAwMpv3BY8bY2sgxX?PJ_q%+v zP1yJy!>?{e6#uD=Jqc5a)X4vool)zn;RNR{#^cn!aSic(xeAh#H&fccJ7R^&Rw=5^ ziuO#{)!h5=t0Ijc&>wY|g-jP$=<;QI+sv#nRUb6lGhwGkF!a%h{f|I|%X9UhfKulI z6_iPvTk(rA{L-H@+Fwm@2Y*-wc7b%_YLEt&l;(f>rZQbAxQZ^l@h(m0jK1-dvg?xg zXyA(yGk&`~FYqXIp(sq@X=A*05F`F#mgQnQ7T2X5B@^XpTm&3Z`6#G#@H`ko_exfQK0(40Sx5p)`9KBn9}*c{cLwg1*0~fByY-{KVb4_GLL1f zN?>Ch*>%{Y|GDC^I|20P7h3P$I3Y^KMQY~B@P!L7#%M^czbY^%q zN1a*VzW^ehcszgmO;$pQa>hTe=W%_z)oCwxABwK`_5Y7?nEaagbVOf$LZVDVrGJ*h zK6@>b^$GiECvW~G8xLIn%%bd!FF-b8*j`DiF|#XTn&1xKZ}__ZATNaa4bvYBMLB?n z;qdEn&PxghLJ)LN-f^Y$l+yL_vYguzTK53Pm$4eVc*_;rSAp3U=Sv9XHWp^SflNs*3dHEOGgtXV+Z+%PaVA?38n($!Kx!OUv z{HO`*1+Xa#r9HjBFQoSSo@#K&l#!tyr}O4JwdRp(2dX^D5AvH*BXf$8-_;JeEca!} zCL7!Bet4wW8c(mn2DUO9#>2SOd&`+1#P9NFY94x(o8w-pA1-?@SGhYub-BOlt8M@O z;lv3v+73&5$f)!pO#gF0rst%h{Y32*S|m5x#dlCATbnLNOq7RZBT+-Inu0ou%~i_T z^6h?=5%B+zbe2(3{CyOcmIi4MkdPEmYUu{)?r!NW>F!3lTN+{M?(Xi61?f(o;s5L# z-f#|wnVtE4lzYV3= z&uS{R;qyuk#pQEBeWC-hxl#m|Y2e?2n!QXUHdCq_x-$-{zZG+p)W#wqtMa=Qx$cAv z6}oS3aPoJE*5qFfUpO6fQ08y~M?vH5x*J;v~kL=>kbHZ zkdS)H#lj-3UFb2q&z^MndM&W(^yRGhjuTmqa$|2}RQ*>jFJyB!R<(aJ#m~=((5da0 zz?SFk$ephMzM=RbQC&Zrmo>hH2ZQ{=9naV0o&*i(TgzWp^P9ufY5CZ$XXCwe$}Lp( zV95x+MXQ(i3TaMc>LtH^V-$=0(@d`1r|Y-BM`*S_}b;^7tLrAUdyBoV_^m z^mCDAEe;~S_2zVtF} z2OP_31Rs%m|K#NQ?!-bVbn*P{@;@0d2Wv5``FCS1!x*;e}+b)Jv0U1Gz|T(i}ZZI>Sp$ikgc z1=_kW6~7V?)cRr%4hkGKekykmDgW|W2)^^(+V%Xp*s#)YKir?Py0Dtclg~*fu{u>w zE7xcQb|UCT!D3_SN10)Nq<@bckuk})1=HgFLC_PfUI;c#=FFI#A5_J*N)@Rs3k8r< zR@Ke%Oc}o$T2^EGM88X4^^#Na^pYSgB`As&eE)6Y^9Nx)gH#spB42dcgj*vd zuKXj0>O^sr99Ck-ze;Bz$%9;X%9K%ke94DE(@zsSwKBD^k&67R0ZNgTxpmra;Dic3 zbdtxdX0*ER2ddAQDmNxrX@?~U(?%KI(!~SPzp>k`C^x9i$slGfqN=vm2LD%czb_yr zif>e`m1s#k7@%yp9!5Eo8u@Len#(xc@Z&)|pb%n7pxsn5Pmz`+2o8IvejcJ+rhHLQ zkdDKIZRjmNe-7LY_}x5lC0!-><)1WQ@dCPVbt{pYPF`$=_4q&Su_S*t9fh<=zvY)k z=}cq6UrfqG#ABz;%u`{1)=<8-;7^@jV=V+>1 zeWnNCULI}KZxKkAITJ}h;1Pxr4V9+hnXSR=V57s< zBtoI$bd>*6&QTg_m9M%ruusgY-)HezI5*#mGMkE#Y%+dgE0N>K0WmumIWoT?LPBf6PaRI(y9;IL$)w4MG7utTpW)1a`8%OvsP3oyVH7*$#}( zOw+|BJm)U)@Kp(z-A=IozXxAg$9~TVqoHHoQn3wHnFqxdBS5~!ls~e3RUL<@yHuE_ z;r$g?;#V{wyE%zm zmJ%q^3`b}`bLy*pk(MrYX?Qo79vm3l#f*ddPYGq~ymh{mI?)3^~Tv2vnF@v|5->nMb)CO1V z9r02JYP>^ZoR` z!D_Nyng*F_DB%Z@<~@c32d8b|bN1v6Tmch`CBcUtGQRhdh2jL$9l7q zBPLuyF|l;BP90=lOjuZ@&s6`D)nbOszWehV@3Q&+PZ(-=My4WBiuE~LL*tl;nDdMTPm@|Q`Do25j?_%R5D_Uie365bZ z>y=tp#)&V+DR+%gn;+J_g{Yx2Nn0wYV$BKJ(=nwj;J#9pxFV#wT-8+0 zzVfhS5)fAXYhoJV915=2sW$;NMX6x1f%Re_YVz7uGM2U;O>x@%&am!jO~#YpNT>&O zxkC~PIJ3YfHT@UbKpcn#5%jfTS^N6;OxNDx@?wc> zZ0}Gf5~ByQHpZW1@@mVtJj=0Dusd-h|5Zla0@Jt>y1FsqGvVg43ZX824}a#^r^Oi8 zi}uXF2GfCM5^>#Ol5N$FiApqOKAT&x`zxO$NxBe&3r$OaVKT~l%0Qvh06;t#NQi}3 z7q&}bpSc5U@RwOhL>kT|2#}8yKDBixEIN4!%$@Y3+9(#Z_7973{E5q>LWd#JJI@ei znZ`RmaMbyr2pRnu$;^Bt%ffM6ZDx$}X_t?Q!L&B%xD9qURK{G-);O^q6%h{S`@xiu z9F8%ka4DG0pQonN6!A0~U-><9+Kv2@cCEanJYV>63>|;HHNR83g_PEaHHhm(lhxeN z9nwrqWd13UUCN9ihxbcV-9e2^S;Vl?ef6*Ykc^f?8<5xH%CU9gX#Y`>6C+Oe$1i(R z!eUrX1gtYT(v{>tjp`67cevj>n3N++4_rn%3z*H}e~wbcnn-94PL}$_OLb-9W!)D- z!ml1{i`^{ZzDQr-D*SBDwE(|tZZxiJBizUgQ-e%O~v08)sf+tC9EI*UW<(lS%@HkW197k*^0p<_IT`nI5MF4Di$d1<%z#X^t1AeCem3?He182j9H{6 zS{|_~&=D@aZ%Y-S{@Pv((|}#T2r%tCNrmkX^XMjo!Eg3e_`vJWV2rjWG^a4J_h zBIpjz;1|qhEysip+M_D>br8)KVI|wM`Nayc{!*a`wqu{%*CiQ#BYK|BD=-uH2Z{$*fq+DkRkOujOV!*gI?THB}($82F@oGo+(e z)~mzvJKcq^mrIrqeE$H=OjG#NC;f0MTfSbbL4xf%VzDcK!3@}CRFnwHw-5- z42R_dKnR-*_$CkrGiCXhuz8U8ieZ<@+rcX+KtU(U1Y1=SxoUU=c0bgfAv^W z=)fff9bN%@p%COgO}fxtR;%)ObIsN5tt?F~!YfDLYn^?x6DXzHsj)$I?@wN!9Z|xW zt-)5}kEq=qiomkUowz700#kS#%RD#+`t{dp0f5~E9(S&MDPo^pJbhqi+b^MLLB&d-c>OxT`Q zW;k#e7$pOrQK)Y{5+lfb0iZ>N+RLSATZ+Fw)#RS0g83)X!4`Ju;E&$V`J_|8{7j9u zWj9`GcuWh_wlro21H3woISTISHQS?R(I1R|XBvd(&Ekpiz%b7=doS3U;8oeuV+Y|l z|IGeOq1dDG`Didk3dj!vtomU8r~qKQ{>}a5!%!$~^TVTanvBNTm16z`cX?roeE22S%3l*AMQIYB4)yJYuQc~u z#7-yu`XwZ^BZKN{IlnJZ@Ct4>36=sCQPIPHs~)07c%XDC`(KZ(9P=oHKJ0z%#W>_E zRn1zG7x>zBczBfy9Ca_T(xNhfeb5>18$&M$^efk^7)&I1Y#TP%h zNX{B;u)T=VCL^>ApUoZo|2NT}9*RI|&Xb7#2*1$!FgFbDAQ5DYSoLRn;g5(6?fX83 z7G0Jx&|$Z6mN9!i=H;Y`@t1F4{p5X#K`!{o>BrDHDH=3q(vb;u+ngW6ERac8NlEu{ zESK1ePz<&gXEm0qG%zH8LwvolQ~qzR>2>N4+F&Cbsql*M>)|5vp4U$=DA_**9yY(^ zh44BOCPzjFy<;Ao%*%u#qMeBR(XH5X43f}5#4*ISC+# z*BO#f9OpH+>dXwtBs_g}|1?)pu{X*}`g@*d(M+thpx(n0pGZ`aV_j*QVboNKKej=Q z$W!^pSHJXSzoMKtzp5J}3a5%`s+H5XiuUppGz;EyI1 zGR&c5S+2NNj843(RmbDmUY7jd5;zhQD{Z--F6#%3vjlicvS_~H{b7zAwyJK6S=r0u zCHaJOOc$z__{tE%m*DA--E0Cx#a3m6H=$?^ejLGK0a#ZQM(~rK%1$CD#%+XNuiBY`CrrdVs_0PG zN0(mW?ep@Pj}sq@W=FCGfr($I08x#222tswW-AXiY~m!zZ#8oFym*w@dpS~E;It0V z9SfDGPsS4$vAYrsJf$;=V&bJRdiey$>F-HXF(-HU{t7)_sE&Li4HW)ucp)xxuAID90WbECkM(G*M5M zWf;@Gi#$-Ckzumaw$_u55IhX9vVK|qm6hI8JL)z37+qnk_%fz96Zsm6hvw0XKmj|= z5R#%6k{Sx}g&^@_|=J5`aP+_<777NKTuT!ji78J8HnS*H%Txk5S4CUL*0ILfeJ zzgp5gmLpv3y)`&|N)WA;N%-Km*Wel2*yv{X+i(`xs^E!z#4MkdRZ9MCuQ1^|rmeaN zmjL}bnt71?l72L`Ot*#-`XAFbpYfi}Z~O&+7eOO7#`9Ck9evPZ2Y}+C;Ad_!* zSsl>|Hoe=n^V^bnmlZlnXVm#Vqhx5=z;X{x(QLq9MSF3CSvQ+zY(-puBGj=U-#D3o zz+oLj9KA+Dg0FvaJ~Y?v{HH)c?_kJLvtx(S{+QzO$29~#u3#~$M^6W?fe^gsCREII z3O2|2Se8W8tw?7C_fK3#O9t4uq1{w}$$bZU5GAn7=3}NT=c^5nwO$tpr6_ot8nbC< zlFI*9tNcsi^@KQLhC)Fst$NcAVdj}N71=45W$P8J3;&3wZc$xy2d`3&?byS8_9rqE zG-)x+s0m}`P7zqwZ=RqzSPp>m5dp}mA^WqS)WU+8rq?QaHVlw`m5%*^^mZ(Zz<1YksiT@rff$<*R$+D|Sq985~ zGcAk7NFd7+N?&sD4Aav#Ozv(SN{XQL1-}fvIl~(Z$$Ckh5);d7a&EUv&*&+R87cvfw4t8Y&GUO^=mczA?_Tl1SjHxT3tQI~ud3t_RbqoDJXn3|$i#S%Hubt7 z$1;Q&f0SVJ;9HMX@TB2(CgOb9?G^Ilqm0#~Y6WBR%7J|0Bw>t3?Lb}+3_~erHHLd7 z3ut~)I2X_#A1N8e5L9ByFia@R+8HEH{+ZHZf|ds7@HR;On4ajvgZw;UU7VmuPI%5A zZlc}L4mx5psJgGUsg-}4u)GXbYME6f{nC}?teE*ZHPK5W5vHsz#Ojvwdq1%mRdSM; z?$kXWd&33`p^$8vGUuGBAADHQFsu3Y)UE*>X8YkHTrL7pO>43G|6g}vbOlJ#s67|4 z*qCm;6j^8Z>yyP%@>5BhRYsq6t{re>5qNF#1l&<$--?xTEa}aU4`RP7M{74}ygt!$ zU9>o(+SN5-<4>QN#!XkU1gva-r@FalBu&;lK;Z zmv~D`Ir`ZX74-=Pj`p#w;h~$F35l5^-x7zq%v$3-D2l5Au7Q_|pYDO*8xj;He%;pS}IUl*P* zN7vnfA?);SnvRPKEAl>6xlCCbyIq5i+u!*g6)x^xW;*nS{=LcD)pYGY|M$qFz*dqg z+!H|DH1L)t6G2uF2M}ykpG1&Jm}81*dj0$Jru|YEBVc8%PP*91dHIu-n)rcTaG7}< zBw@*IAK@vNQg?B~<}TvKqLxY;#)XoLQNs@sBMAW-Wf95QaTtv;9y#tagA0mVFxM*& zMGp)wTkHXgNp~?`Cl+zR(>YbesqJhjlZy>`eeN`J^9N}{{I-N)A~OFy1I^&Hb&3aH zqkaJ?iPD_Z+QdAtD)K?LkGK6ZK*y6&)3z7AIA1ZCkpUI1xo%_vlsNvy(`hNDLR+7w z74V&|2Oi|bhNtol@DW#Vtl#&87?(Ysuc`TSk-e{oxVA$n!mmw|b;OFZz1{7-ucy8* z9Qyna@i?}wryajr`a${#i0&i+tL|9DH2_Xh{rCos#Tz&SemJeHtS8kk8X^y;z=8WB zE&!yQSh{UJ=h{AdL&>h5*Uent1;FoFWB9E&fIy zJPJ$hl}3%FX}Sn?5}6HX6Db~U%9z{Us8KSu?la6@uMY=P04t0BaVEPTJ!foibJ3!# z0-0dX4p72%2%U|xOcZQ9@B1s_>i&D=o)$zP79nEa+>p|9SyIP6-80$pmd1?^J|zTA zeD|^e8|0I>-TXd#6MZZLCgFi+Y-c&fg@7H~{3uW!u?zl{^Q0d_ce^D$J)lc0S2fA;pL`!}ju zHlhe0-2~!puhwk`o$Eu&Y9UnVxDYQ}Fw+UAW={zRfNThVas@bu8WlT_c0@`aGf0-- z@K+00#pEaKPr4o_b$zXNjZ0%TV#w%YY&Ws#_2=NfVNlo!;m$=2pM;(Drs%Bqg1=a+ zY87Ty1uR$cxh$C^Zy)X%hTRZ_0|T~g5T3R`2O)&AVZO5cv6Osb#ciCV4I+;4hBixN zUy%OWqxAi898&fs>h9u`C7pA$Yrc?$T64P<0g>4EF7mIOy01*pZFa|v9c=!^0J&({ z)TzYro%_O=rCT=?rV5vm8Xx5iu)!WB3^JLg9hsK;2j3A%g+!N#kp11G#@v%qbMvyP zRkL!H!h1C}{ugD)ht{`f+w_^(ZF7-t!}P;~hROdA9RJuVtjh$}jo^jE;k-PIMqjFK z+rgT@xkzQC?w3>`8;Q?QE9T4pF@AME!6?ye8YjAFk{}JZh)C<1U}ncb+l<& zKcX2*moEp(tQ45IH(9|vnfbFT=?}_*3#^PIQZFIpOB_rW7LoJ5FbUA$-n8Eh>z_z( z12anI{5*Ug0Dmf&V*|j6nf*&YlS{W@_trmxZcVqU30t1GHlrD)5Oz9kI*5)r$o&3B zoiM8%W2c|Csa2(8-|%!?_NZzLmmxrFIc>K5liS6Q;$reMf4(xWx{O)~Z&)avnE+<>MZ^A)x-+ z8KdydpMPTr*gMq>TW>BK#c1I|jw@TD$N3JdxL&R=ddjsnfJ`6v;|fTILe|bJV6kH$ zc3Iq_&|pgn+ITp1jR?^IgjM{1|3$Kl7eujXaHcUfH1olg7PEf%@-l$*++fcF?6}HiOeC@YV z{q!_#o$l4;uHv1+gN872BZ$0Pq4yc2m%C^CtC$OxtIo$iEOmFUQ z>f6KKXAcNP3)=41Tio)E1kYl83alHnIuYiVqlEV99LzmJ{${vJ`^L#o)hwndxPx&}n&4 z*ICixYHX+dG>BsD@Y+y3@8Pwy*`CcfrcBrhErD|2K z3q4wk7(s%Bx@o%ee|;#-?kUu&R8J3Uq+bY%9`9Mah3i1ZLwdOuM6L1~=@VbCE%HZ6 zAO5R_{n?jQBl4*l>Vyc+eZvZmg6T_+;{Gc8U!={?kpReDhwIfy){|Xx#$MVs)mxQG<9m5M3Z40GdgIfLk}R!ttYBQ8W89H2 zd`fx5vP#w;Ii&KO&-_M*D-X@EM}sn2m$iG{(T^v+a(CGQt_5o=(QAz@X=(s-)9f$E z$Vx4#Gz%-#u4>JnhpfXN|?kBwN)FR2;-y?wy()njVGUmHWjO@4B zuq85)gh%g}XZe=k(7s*_2@=tgI7=3`Y8gj-^#Qiy#N?zT$rwjS%9|r>o-l`5qOe^^CuI)Qgx3Wb$JmUEd#Du zuREEIL#Kzmm70L)Hb zvwaM)EHu;}M7RF)AoDO@ijgt?G(jDK*iHU&+5w$p)w2yCx6@4n_0pbOew3NdUUq-F zrYyi{%}4n6giN#<@?}Sez8VZBFsAzoThE7N>rkIDl|G0QyZWN6urD0VJxN>YqrQo zCBiXzqqjrQ@m~Dc*Ud84e`I@^-|-e@Ypwxsh;V@HXwoe}g&Jk8vzW*7x0E79AT#Yd zE4lm9-p&nh+P*YvOQA99d6y1(y}Ip04a8KhQpZjODE{+x-icx_0*scyLU!32*Xaax zGMfjHBre?ERqc<2T-TH7v+R~9uK7eb1Ei58n%VsBzU@6|+>sE5ZE6hO0&6RQruk^~ z^z~6H0?X~6bqI)4%OtS7wjI^Pfh ze)@Y%;=z@fr+u|u26&kZd+u3QL|RTZe9dr(^646@G+{4n*Agf#ObuhZmFZYi0@3)+qFcN zhRO^I+}2C;h!Rp|ODm5z31lc!{wZer-e!FJdh*AIrJ{in;Wx0<_f(`3A>C;Mmxzwm9VX?qe7K39Bu| z%XmNQ<A1m$xndj=Cef-9v+DS!cP+C`v%^c&knwmp69k;%i!8R;#Vp5I=to>^`MIOWB-0|00-^>*op?Gfn- zG)`RjRbo9nNT>ZHzh=7}p{Sk2Xkxt#XwtAl!5PvK?*YC-=HG2KG^n}*wWx4%|?7^hr z{{?{#+MgV*VUFvF#96s)UZY~Jw8DArq{F6czOBN;a!!-lMtKzr8wyAM78hgi-&i{J znPbxd<52DTO&hwW&qTtm!%zZsQ;YWHJ|vdK$Wu}m+9pkOhw}Cy%aPIZ%ws^tsl`Wa z#kNBj3|WCZ+Z}!Gce+{)yf8`Dn-_N^8t9SG0P-LNj9LvEWpr#PhTmFs^LziHZPGqq zmcY(!eH;wp`L)+@!@eS2^_}D=WjP9mo_8Z&5gRIs#r!r2cK16^+ipnkmLC~|v7Kil zb49FL>BQsGqmmYJMqBIBwe1t}GyGr#Q&VFeM%GWSVqT=aZo8>I?^PY6Y_H9~wd0lS z1nCg5iV?;()@g;)b%+801;$R(d>CGEBzyJV-yBK z*E{s~Q(Q3-twyB54!`kb1%2B^FV=|fM+6-mi;vmn$zel_q=UN|S4+MY@yNsC%ufeM zrh^-sR_F|fso1$Vm1vUQDQ|MC`$cO)lovxHEK1)ag$O{m$*} zW5UmuRxh!aP~`kGL$JG-x-2(|+ouuAx$LxV)E#J*=?Y3o9N;e*su+xTmPFS3kULuP zyGgY|B$+PFQr|!}d7?-iWM>pCHKK14OmLHd*Uj8RwVlk!5QAG&3SOpaF6R{cC2J;A zp!86L!}bjv*_#I=PD)f_q<#yrqFO~2jhVDbais)*k_dGmITRqm*71&gsW*#Rp zWoC=_2iV+B>QcTAPP!G$|4BslO4af)V;LOESc<&->$B&jT@vo=VeMDCe#7-f<|*or zYDDfeNkV@rbC460BwzrfsT*``Q!JT3sJsYMO#Lg7@;9R(CvC=Uwh@aX@ah4&8sZ}g zQcxaO?S4(^b65bHAtR~yT z-*E7@(59x*qFNxvpUZ>ou$w0OzhLs(JHyt=Vz*OitFDbJZdGI=uWcS73U_>!q|nPCY?`i~712JmJu&R1?kr z3fl-Ev`{|VWe2TT99P7PHqA6Zvu{{A;*)%i7={gQGr132a*#&43=voAFDkY)mH1LZ zyNW1) zdz|pnPYhK6!8$E=0P(<3a+@E5V0YeyAO~1`>eRw@pe$b4B60I?FRQB=lvWWv7Bavu z*E0!9pn@RYyG5hhc7UsO457u6b@EYedcuslNG+cA+%QSb+^Tv#sxp0f08zi1&Sw+n&OEJ_d>UW3v&-h}wF7Se3@%gZ z6^R|XbDr1xovk;f%U>@?JL;vAZxAfBdl9jJ`XiKu?*8fHnq)vObXUSpU(>#Gudskn zMmIZm{42P95~P_0gcW7#0XSF>E|PRvLz)n>4%(4$k`i|{wBl-*r*OS3ddODQ9vLaq-;9O4&I7K^9}mnimz+b+N( zjV#Mg9NLFkX-qZhy7HVv`K_DkQO6NfziyWu??428GXTnDyLG(Wr3b$h6TAb^Z{4A< z*E4bKQA2OOp7CEcYetwt%B*#5o9$VF=VAEzHC7lcb>CU`M@ULgpTyHLyycIbzBFfBHmuxPl#Xs>Q27+e*S|R{oT|fhP zDS7d(DDDt`ok!~Xq28=cyX;Ps`mhzdQ{0vw>MS|lIiFW%&(qn&1NOkJ*IHch3ff=2 z4bY$%x*Ptf_3uB$%jQ)#84~+Aixtg}P43crV`wpOfaB@n&%?f!bQPYi8`NL6RHE#k zMcG6^D2rb9a?aD4Pbcg18^P9P+5Y=t!(*g5)|lW+NSICQwcP2!di3d z#RR1W2iWjbOh@?jdo3?^&F!QuXj-o|uHCNmm|*!p*_2c_tuB!n7~Sh18evHtQ!9%) z{N(5vBZrov3!Wk5N-XJ#1l5*EhB~%qN)7#>q5vL;w$D%KW*W6^u(5R>$(YR=Qn~7& zO*kZ*mo`*%M%zV7QIH~B?wEJ?*Y^q|2Zb9IWAiaKk3u)9qol;R@;FF+ld&IFR-pwm(xa$#E2TEDQ?)0xS|hw^(|{hcIUk{Cj2(mpk zxvtF;hSQ^O5fPis32++>_2=V%m1Ox$G}|4`5T1dhQ%Yv+A7HjBTLoas&P>hS@>2|T zWB<;vt`>D3YaejU+_CS)b3%-hbzJ;rWcg8DHjM7f7p-A=0CY|<5gH8phT+wc1Raos z)?Z-ziW1!pnG$^-`Lwj~pdHXDlB{fOdta3A!qlK_LZ==1o+=3+RLt9pX($=9Q~ ztg^;#*j6spTAcSVCx9GHcD#x25g56+3{Twfw)!2P_oUZMW?o{m>zwe@x~k%^Qg#~# zachhWEdgkK67_2pZiD>!S@v)G9%s*V5#y@n0)ei(o3cZXZ`?C(&XF!is9nu6Kpnq= zaJ#toby;6KGZ%gwL)Gk)(T||;IPbZ+%p8Z-Q?sFC`iW|`&N6;Z?PtXtS6um$F}8UQ zba?K|^W3U08#mU}jy^h>rA_~grylOHqO+~tR^7`giir-}{{@grOED+hxdjB+U@U!% z{=O*hIwguHv*8?j=9D{E*y8HB8~0tdN0$GMR|XS)=6S$9Q^pOcTzk?}v{OpOm}uMV z8q-*ovP&7QBDAMc5_IXq-{mTB|Mp`>>S2E6G=_}l;F88M$Z*TfWhKVvdS?l~2mmD&iL7t-b#z zT1eDTDZ8BDl<$G2J)sg@`>(t8tT(K!ZKIceYyTai>B>ocKt;nkA-pJ2>QKo?_iUxG z42#I=i)P;0r*}fII{zBr6Rpd>(up{TOpmE1*qJ@qmAacfL57a{mwdGPeiC_LiSu-Z zvX62s!eS%!S#)Agt8eLU`^_AFL=<;(iO0bmP8v3#|U=3jlp2p&j9gS{!ViXr-MP-AfYwt11wt!eGj!B4AX%vU+^d?S@ zBhxZ63~G+k$T?K(j{xo0_*9BaxE(i)Bk>tEjI!U|IN_fI%n3HamflZpbrgKyQK3!G zkvT!=yi-#7zVIy5hB-`b2`n#>&I8G0rBvU&*L!z56Je^#^wC`4l~8RHl_yD??RZEN zsgF(|4a43Mmn*%Vz}uSD4$Q*#zV9ge5MPMM_8jSYx7-hZ%!=UqEFt+`jHYc^Wd+E(A4U(HrQ!#*cl^g-JKSV(ejz7LdO$xipKjn(n z$A84pO4w40pVS&4`WD+qF5^Spuv)BRwO8iQvF(z*yb2Jqiw#`kJ5(sg)#{}8Li^Wa3|IG5d`ZWV{B4F+;D1L4Ma)Og(8zZ`iP zQakMp9AWD46l*zQU+E@8AlpoWKIv zbjzsS0Y(3B+X7JXivH^%eYSHiO{!J<*zJaDN1dH=bj1zz3%+LwXX;5$^p~{lIWHav zf0@ItAY7e{zi1B^OEJ1c`GxE7S|t!7P;Fl%fFz1*({A4dchIwUxcl9;bY2usmz9VQ zm;ynruY%E3?-O-6Qb)$reC`8CJL@XHN7%>!wJS6=I#b~}jx{AJ_rj-eGvI*RaKbtBd(CALKG(j( z?F$gtfTArXk;xbJk1bks6Xy*4eoR_o5`xjuIX;BCg^5qZ__NyKU1Lb6<5T^r=3du$ zD9O2%)vD1K872XXTGhVUVGS}B$-nvH3;p{N1=3Qfr4{vQ$%IQ6x0tG%qTR9qI?( z0ksWFRHF#fPmGfcg_|xuE0v_dTHz=HT{o>HqB1s#OhwHfLw&0lg&8XbXzwG|^?+Jn z>vw*%q)q3t-KJBfad))oxMV%cyDE@*;mY(52cs@hL*2!}v>Q^8A%HJB!d@n&La_Yb7(Aw)h9KOBFxO}e?#2sPM2YW6e@jua;V+c!iZ%Mii)vq<; zxLi$pHnw7q;P%nN`_?xIefv>RKK7}FlUhZBRnO zlAS#C!xTa%GETJg4>f|r6jCF^!)A$v7Q%YbkZbASs4~5ArzK?PRB{DXPArkBnA-`MZaxh z_C#i9(G5BTP3f(GBCq#be$+C&&p!c4h~Orh2R&8R6*-%bSYeZIQX!u3Tek`MON7A`q5oaK!i@77QCHlM|F<;&UF*Q{zG zkgRZ2SS4{`6+(Cr+fGvC7px5$di)!lKZVU$4;sbU93oHezl;n2%=3bQ-%I6v_wK2W zNy?4#%m6ZXNtGi{ql%Dmf-armw~vx`m2cKgqixiMyye zF8CGYFyni!yp?`Rw^J#$o%^t5nj#8=uZrk!u}R=IZKmN4*_`tqnXj6DzDQDqRa{3= zLib!fIWg90oxPBwCIGb3Iyl=ZDFXq+*)aSUrT#W`kqRzOGEi z+MW0DFkeu?@2X`JoFO5lBOTzY+7HeD)ZI=$gx=4YP#`-v1^upNIFs->eg=6#BUc`% zF)+zWcx4ME_*_a=DR4eUa%E6kftkPQC})L%EDX|UI)eHI8KW-oU$r%^`G(P@P=<56E#iDmO0ZY-!SXaexGdwdneup9z7z0z2ZfM%+G;ft66z=Nu zIJN$%c{8TlZD0X~Rj|!alu6%5Kd<81qTGuBJjp+u(P3T#_qGE2MTT^^-^5dyVOW^b zZ4_gNWR9d3u@%0J`*w|(;VzvHmE*6x0)v!q!zC8d6~&Rz!j;$FaJlXp-&_k+L%x4; za01ixf@Nv8O`4~{CCwT?OB$Frf7no^|B%-wLL-Qq5@V1AeMfn0tq<(2slE1oezKi) z$T@a~KVqp9;z~|T7%Wj6nqm?vr$_R;!?8bpPn+N}`;DQ39OgU`e$(Sy;;&UYR)zq8 zxTzOq$%-@=js$!s)iF@64my`itk=}HHgRpPa2m#K&)cD}l6fO4rzwjmd86nh1Kj`l z3py8oGr07a{~PHL#HDdeA!28G!Q>7&X>-ode+XV(dSZc!xFXQ+ppNJw<{d;FiDkzc z{>b!pqX643%=~6sS#X9Xzz7}aP(}x zp;?2kv(|K}`PQ6u+n7tqeo`&W+)!;DPMHy^PzezyUV3VGr}g?>Q3sN%$C*+$l!e8T zGP!0Uv)z9~MHOe<OAA3@;09;71D<|>Xh z=Np3rU8>S_LP6`mExt$-j~uN+p-?CkBY@NA)Nhuv&vFyYDB1wK#&1d5Or@d;xPdrt ziJCOregxCpyTH-nat5_!hJ$_vQK48gkc>(SPs8LXU4ys4&s%1K8*QM%UKa85g-F*-y1 zYLO%5`%3Z6Ih%}dkHPuYa6G-IBV+IeQz#S)#kyb&BgzQZP#&g})TE?}gVQjz?r*8# zK;uKSz$3LUA!bn3iEP}WhsMxDW@a17py>}-0#&UiYbg|qfI)u&bdwe*IJij@oqYqL z%?aLcW<3>ffg$zqG`{z0h`?huewBEMY+P)keH1*#Xd`WRg<{FTIft;&r%HiSE>uYj zIM8zw3`wS|tWg9|yNGiR4+@Ftf@WuP7z^xaTBF!nCMt1=&mFeUZl!H$1D7)dGdt^c z^7`FS{n8|>(GE-C$q1mbV<8owGG)aT+!DQB#YO>jc!aot#}c(K24{{7D9C|aDaAzq z*D^*TO~woXgZ^y;6*J{1@3P(B@hZI!>N*^)fVuMR_U@<)xak(AAuC!dl6yL3V$nR& z%_#E>#UP+6mtIqgn4<~{-0Qd=jcHO9lNLY#${)ZAb>S9iKnTyR;S>smLa}O))YQDn z#JXNmw*bVhBb%Qv=tir?GL&i3;V`>-i=pQnsI&bDOj-C3V-fA2fo|4PDCPw`pWr4$ zoM7Z8OqibDQ%I95%!`vojZ>~rMP{42Xd0vib?`(|0ZAu=wEk^`rOtg63dP!hvl=-e zjvYpv5XIK_z}`~BR0E*t-8D=#S$(9~aG>3s>ldT;4>~Ru)EP$`qV<1F;z$eC^iGN> zV(ze+ z@JPjs!n|w%nbry}x}ZolLFQo^w=qE}yB=zQy2TV}jIG}K@SgWO9Ch0R^~G9fMEL*4 zD7XVxTQ-YHNmmQywc=d2?38{97rzt&3=^hn2>3deieTG1r7gJG8?7w2n34kZt4YoY z%fzLyB=aVPLZMJBCx%uLIkhPncpRTx-RRnX*r-KSUt_bB5z@%M1j86B9ItR{7FSjS zjNf(%)UuTnuBP*VLO6-zz5rM@i1`h(N`6ocv| zsgp|SBLk0xL4CIcOExKy(W_iT?w}X{E?NC&4@X_bD?o5mu(3P}{QEXXFjp+PjUm=C z3#$fQ3|cZzPao*KKrwgZ^z^_*4L(HMGqt6>N?4m@FcH~-W&jL0D_LuF)3(0D*l@c> zn9E*E%O&;Ppe5QWJ&YKe-dkp7v0j!++x}DAPjI|MXA<>OEIFi?4$ypmCK2u>XKX>3 z_C9F>KznP5OI2PfE5(!M!B=4F3Lrbq6bgkxp%?+2&poBGBm<9|k~i{)y#*Fs8AFiU zCxGK=0n!({4B=-{nB~XR1Ah*Y6uU@l1`35@KA=J`yNOB&OL1H|QrUq=^o?1I!WBU@ zFG7MB3sbfZ2E-k#VIvs#%u(GyF;8fFD-=rt>=5F1u>!er^dk@GrYE?*w@kG-sLa{8 z;NHEoIxuK~Qo(cXj3X2m4>yx08oXpC)Z-buW;G`Do`)|l&CRkYx#kyXten<<0oU?8 zEVS$+c!?ap7Z!HAUENM)O!9j-~??Ow$%Hty1)W z*6bgl64v=&@zEXOVxG!0|=RT20 z_YmNNT%-eFC_NB-x17z^CoAmz)qOjybTkQTZr zIx1Z02CYUuoR0G{f|6cwn)F>-!b+h~C^jxQhmqu*!t|0ei7J=@s+Q6zIh~jCn<+L1 zB>(8#3Y3-{7JvbYkDt!u2}gM3Az60iWlXo6alcQSeCU9=BWjX%Hm{m>k{NPv|L%)GV**` z^1;!PvE-6i1Jh?nP@Nzx13-uP$PBSf;u*co*U^%?a_RJ5qT%uYQ$~&kAaCBMTu=(` ztx5tg*K*w3lkQ7<6Ae?t8VdL+6bi*Sz`q`+4QVE=sD1}c!DfBal3dN8x=nt=9;6Kg|rPsg< z#~H#8mj_H5Fy+j6R~hjsSr!*!5N}2^K}J)t#~+6JFv5;Le;X;h?$9}jLa{+$I?zZ0 z-(>Q&L|~he(bShh^^_s}6dMzvpKyI;5Fk6IVE}Q))|_C-br6=OYEC-9#0&$%RR2X$ zP+Aq9V=1ATWpJCc%-H3%f)#^3dM#8(wzZe^Ap{0H6<@F-y|4jDrXqpsbzOsC;Vl(9K#3#ZaKm;1EZBBXnFF z;hJ(d1MsqeOPiI0GFzl+Qre&)dkn}&5=wQUGe>AjdC7)Xw3X=!g<_?El>|0x0mWfj z8Yj`EP0!ZgszE`mVVW;aFo8-WO-x z7ia7=d~Gt;=1CKL3o?xQQaUitt*j{`aHaq?Ik+a}dIvUVW_c=?{w$45jqq=?=?NUO zc!=vp%j6){RnqV&b1l`4I4hf@QC(9C$!Ex=g=@(qi|UkAuQG}JTv!E-LZO%wD$#?N z#>3&X(MD%M>2M#JVv8}cex8+$(m8rs7QWK^X&7WL73T)wTqHSAHw!R)B^{ob;wH-s zkh}|4s7IN-BBkOq$qM51Sv%-vErntzOh7t{+a z*-L}NkiP{f$ia%`&d@R(*$C}wniKJ!Wwg$Y&h+-?Ww(YMS43H{Fq6t-b2Pbn_kXH( zCzLJN*yOx2{d^)lv8KlNvON~oA#@%~=>l@|Ziz>VUP?=qrSr22Ik)YcfXxDGQnzG5 z?~5|bB4pBLa+98y+i^j1-HH?xN;V*6Pv=wg!64#8>?gwrCJW<>xnBIKpS5F&^f@g} zY{k2E@dJVyP%X1!{i`Sfw@^rtOACA=lO?$ML%NL@XX)>?x!+v_fVjM9m^!4qSgHIH z+IAzG2`e0^vnA>kz#FdAD3V%QTJ*~02O-`7?<@kQJhdtm3dP7U@e((Mbix+iJcT!G zaT~i*r*u(Wi_;oaHT*T=%jFZol6#HQ8dTCt<>WMiK?PDx5Tz47RO0{>kMAW-lD8pp zx(AoUacghT>t-#5qAxfvUCNH7d2K;Fmmkm6I9rxVttp*ga9hN1R%Zj^xr#WRY9YGm z3qY2#(hRT^?c`k^W*{1eHgy}~IdXkXp-?OtQbr$Vo|Y(vlC(mkSV+~N_bQJR4qO)= ztZ$Td)Eww;=GrP7wmWAgX}5-5Ns(kbrVUg?ntH)4iswS9 zIK_HE(k0wI2KABA`MNaEE{UW0IWevF5W5cW5Gg)y4gON^K9EE_97k$JsM^is=s33mIVv7=UuZeyN(F*0#;e_J?U1P}s;%8y18kGT=vglAYBuz~$4&0k5%_rrdMy*ZI z;y9b&Ac_50~Fr$OwTO|SGrtIKTsuY>IxsFnk~;8Xe`Ck`q53;bjhES zvXb;nxl_0_EU7uWz%sN_c%~W1G?U|j<0(%d{BkJKl6;$SR*}@Y?e*1Wpin6Kfs-5@ zjU@3n$tKa8f_hNC(`%K;ZQV7P5Rmk<0xj^oC>=MO0#dKOSd@)kQvWt}TjjP;C=@Nh z33nV%9ThZ95a3jssFXO0Q5j&^|)%dxPtwhNRD_Lk?iy@GJ@#kMf8X8r!sb zmeV>rvQdrcR``6y5s~k@&0AJz<989?Y$&(FD%Qudkbh>}{UozBvewG@gWfoCOHI&m{KP8t}27tV*% z=zXIu6@wYAt^cMoIY1hrikqb|Oj94jl}^;c5|m2URfSZ43krooAs}TIQxljf1ddPO zm2#5w0H<@-MTRTJ2kzE1ey{@YJvU8kKQZc!j>S zu%#I`Q!E=NEzG7&bVKqRCJhpCeP!qRK{9$JBe@Myy%oP@$zYd+NSimb$SO(p!rBL)iYG#E;d&)nFy?#_`*aV-HU27PD&^W`f zs_?8nhUdf0;-ru6N}7n1$m@uq=L;#Vs8A?Y4AlGukQD+4&d{5KlY;6a&T8kZd&S0t z^!^9cV>yFDa!8Jdjzv+k(TJ%+#(^KvFn6h__IwK{P5gfQJmSK|(O_$IMr1Y8I%Nh+ zBJeqVH1{guiQF1t*&az+{o~R&;JGNCcN=KVQ>h0JplJgEG`)}#9e~*1EP4u)jcCSZ7^gRBnV8O`X-XcVQMba^x8b|{oFR7UtQ@DdMgGmT9zHG5iZ885 z=SoqBYg4ORN?MGTBVm-r<($bK>ZK@x?MWjpRsz!>Q3Bqag%@)z3R73UbfRv`yyCo8 zTyMhTC&i2F@;N;#nS-i#FgSy!jnPcO$&nN-T?XeC&T=zb$!_fP914X((GHw$p{HBX zjnMc6tPsy_q_Ug>Oei$^S;dkwRHo%XURQH@0AvYFt0~zIR0B|VOIDKGCLgX&RO_Iu z4Q(RT8^@*W5WePCxNi^Ltff$tf*al3ShR_JMxf)Izin*NhQzUi)}T7u`Whn1!dNt` z0|54?H|&;T1C9ExiY>j2^^@i&3WZ|Lz&TN{Qv@TYEINR*xTzJ4b(l@0DK<88GoxOR zre;#wNZ|T@M;4s9Br?rR-n+oF!zXDOoY3p}x@8Ss2j+CI4s{p`oq3s}r~=qbG|x45 z*4R!(q%$l)=wsQ!>7%(95Nix3%h_HX%H8&bseTGqhowo_$n z_tc{DTG~jXb^z*x9-uJQaU!Gz#hkg2TP^@0|I{rHv*}YT-_h`vKH)?^zr+nGNkVXD zH~{|)2KaezZrQ*>b8)vM-^Pa2t3n(k!jy;98>~Pd?zssYPLoClbvjz1T(ve73dI~j zbST{@g*R|To2G4@2h&l^cv@gLVoChCbZNsD7e`G7NwQNZO(nU3wC0h@qv60{R+ogR zm$ZarlSpy2-iFjKw&y4{s&teC$G3xS)>0_?f|FdFJxiq?9=`@;8&u+nX(5*833Gb#WHEM*p#0|v9U2| zUyux}l;Jf32J#VN)6XOp1Vc6E{*6bk^IOU=DXR2~ifhBq#3L0Zl;XBb-Qb>sRB$KNn%((7JGUtD%@2IHK^ zO0ghsYROh8%n)@ElV{K-wmaRpEEG-j(Hdgj)Eusn#0gGbfQ_Nyk~}4OYauOzi%Ya@ zDoZ|wxEhl;yNrgfE!e1elLTi{aBlyc3gUWZ&J>#E!LEM1Sc_geKIwy=_%S6BD#tw! zz5+B&EMU@b9!q$0-3#|%Q@~q+fm>SYRZ`2F1V5=P&c@5h8Y|r6u*uM;><9KM2; zwMkSL1LB#<97=5eb%f3x6bi)@)ND1-6y}_x9E3C}PX};S;b>^l04n1YHBw!95G0MC zF$?Ca(GjLYN*j`P*%=vQMB*OhlxFhp*O=~w577fm!F`^CZJCOfQa}@&RbtNO)CI?Vpz5I@Ej`@qfSR zudjJOz?NG8eDFm+{F~ncJo`-mXP)Q7uYW4Qf%`$f+L>%b99vijuNqA=l;KxG<4Fw3 zR0bUuY0O2WT5?U0@Ud9n)#G-^x)+O3D(ib!!iq6TmDgGyE}I>|DZdU_BNJyx(Egkn zg4Fb&CavU_$(cLTFc~k64OwK+qe&0J=_}Pa5w%?|XNZpqyYjAK5K@SovI6$N3vCN_5)|1 zG%0aw($XQxAq72IOQ9%%B#G!B290B-Eb!p+re=N9c#C8J7LOM3!V=p+a=R~%qnf1= z2mH(vKMU7Ji^iC?{jxo)LZMh7I8(2UD~X!30|^*vW7+~*YTYU}E>g3n!3&^q3+Q|; zo{=_<5vfd?NzdUPXHQHb2PmT*3lps>nAyMG>(CdbkVdBK+9z#6;igse0K|p77N`Wc zK{j{2WQFh=D91J?%A!E$pOSZuvvV+g%EZEXxpYM#@XMHE1Dft6tw*uRM#QnEfC*NW z4LY05T1T1;O@d9!SEbVe8AG)V^6>GXb2TP!J|oUC&U-E5*>)AFh*=#H*(MVu-q|

    -0f5^3b_yKnWxcjYY{`=gyS(hh2$X}oRD1f(o4B(aT_2KIu0Pr7=1GtVW zL+UG>yf=k(iUj(Pi@QH*(r=yuuK^qX3uu$%h|&7l4OM{x+$8E`8Ni0H6Lk zz}x@Fhfn<@z-=b{o?OYo-FEiZzk8Oye*Bo2|8@5R`0jt#;j_-2)NjJ;^WXB}b1ne5 z>0tm5yBkcq%VF1rLU7A1IKDkvSqr(n0-Z~bV;r0=`mahCoqXCv|Llu&(KP@*_T|Yt zdp600@b$L=Y_p~JliuiW`3k<_>Hhk+cSMn+nh7a`s70Za%|LdR>-P?!@1J^x58vh{ zzVC;A?=ZC$KIrdHISttg#=jqjGtTwbm%bC=tKYBt`M*B6wkIT9b~(T+-sA7jobY+Y zlhX7*nAjz^dX&Ha%_jkN-Kiemulum)aqG&~xzo-3mFxR$Eof?Whqy*wAqj-#*;qb!@KSbE02pOy8Q#6_xB%~T+hE4;OIkq*!dau+7+ha z2kTO2cRSqei2yHn%%n|jTF_&w0|s=6liGecW-s@bj&w{=EA}U<;xqioVJ;Ly@vSgVV}Bm%}d2*4cjCHXgfb=SPGK@lSywfYFz|h zXrAY2D6Z$czzy7`t7Ln$7#u%59^fBe?C+oPaDach-(&%MDpXBe| zVtHeu7H9KF-bos#HcnB-@_@qNooJB*$58`G|49ftW# z{lzg&I+NrO4q);^8M={t`ih-!ZO&l$tW?a@2Pmt>Y|D6xyR&Po%`jO>-iV?>wTUAaNtCK zY_+B5PxX+)BPTo#J5Z?7Xc$PgQoRT$+yfU?I{dV=0ABZR^`dU*`=Q@Y-_NA|K2&|S zcKUvPGf_u00mzh+_+><2~o z)1{O8eyHAz74VsF`0LFN132nnfakr%hmV}x@491iu7D*tZCX0p<%R=*Ff*3qW4V;OY#Sdm2ai(=sScDz6pzZCsREHk`didBlQwk6jGN#xvz> zGU+r9mmT5;6h;cgisH-10es>s6Fql-AHL?^{(8x!{^~aOzu>JCefkI=cJln}$$aQ( z|K-Cadhf*FP3+Der)ffYoNiooT>fW(owoD$@15A!J5B8S4^*4u{`0*6FL?sY#9Gjo zuYSKzKX6}v#hawhy(E9+YN2wIH zLY+C=0P~bQW(E^Y{+>Fq&;Idme3Y9feeeqaZ~TZ4KkcEwg0nMdx0@WNYW<a)+U{iSh8`eMDi*W3dM#) z${gkd<(ynfST9gt3$?6)x#z-)jRmRS4B9WGPKqlrB091++0;ZsaUx@o@=3V^HC-<@ z$gb?lr)=^(KKf0;38!Gc3&~d?TTvAD2{&E*e{Y{G zP(Ip+Z~GT<`gQk@!|v1?ce2Jc_Ne2ovv0kC>u}zM00&f#=NnWfYSB|`FlN6Tmb`$a z;kG(WZK48$X1pyFW}8@+S-D-}{9RyUi7Uf46$^ z;YTL`JmPr(x44n7PdL%22(0WeNzzjKe4*(m8d zf73iA!Ql(v@z<;G3hywK?hBpF7rH?|=KSQOkqAo1gyLUk|z_%*iYmp^%&py8~RmcX;%@ z;&|8hpZlgde8pAu`w7Lm&2bl9Qqx>;vERVu@ali{@9U`Qq$qj&oI~niM zlku|U=05z^Pe2kb{eHKvH&f2KYobl0?I$)tlcL38b|I2^PX;qGnffwmw62D!ALrTP zX7PB2FV;aQ15g~d3<1zI=M(`_O9F~-I(csWD1c`_+J|5LJ~Q2HaNoc3>raolx9?jY z{*vc)&UqFdb+42SA-z@FD`>C5`K(ZPg<@mi%yazJ*`=?0D!?}?{r7^&TxavmYMbO$ z{{rxecY7V^aKi&9>6?3<=dk63_N||k%W?M6OWrk^Bi+-7U;GZ9F6hns{nbP_egxJE z?gu{i`pY=(CI@+m^N}xA5lA7q&HmFLXH4!7y-uAc=v8;>)-F5vbZRehOYo7NLvBL4 zNz2+eojY}lvqfy;-ZJ+9O)1T35ekkLSA?G8>F7>6-9OtcZ&atbcX5kq^WhU7Q2!8y zs~;(1_8b7R?Ltl6yk?P}ELTz)HUWh~(G8L$;%s1Ua+`A&C&5VINJ1mJhLkmRK5jI!oLCP#=!PKtf81D5J8b1uMh)?&2@7o*3>ro8Xl6JSbv>X##TpgCImD<5dVL^%^ zyuhWH} z8J3b6jNN8Q53o%~qM5BJmA(yHmqhvENKz=)9BsNg8P21QlnpWrS>2p*{b4 zTf_&Sm^Itv#g!GaXy|7U?x{UufPZex%L;iU-9L+~wkym&`v~PWUrGaT&xGp*iMo~B zoSd!%A+DTjfS#=G zTo>TQ$y`JWH^>$!(}qOBBmChkfN%fAes@Z{>++TF0lf9u09V_gut0HGn`D+|vS2xwa^7udbMU#U&fmjkScl=m zz20Mv^H+C@0i|=#d(#{G`}cj;pRDCRkLU>K=hxilRDN;-Bys#H05`r~JMHn~>IA3T z904;|AI1>}`RjfD4d4||0@!ME%7MPQ;of5La}3&XEc#bQ&_&@SvwPjTsf#H7day-TV!5^~E=Em;M_md1_v49A}gaHH$h;qA8epHzNs^_j!j`+0Cp z<4)e%uKMIMm5J`NqJKCWL~OsUFYjk3LK5MGwBMfr@VNT|yypFNnrn`~zL~#&?S}w9 z^aX(19_hp3R6WkE!nyvf5ayN_u*uRecTqc-gu975orC-Ip#+<_=e%P8{FIy18=SjA ziUZ)gDkS(T%3A59)7)py-RGe#eDFmEF8#ARjnudL%?}4S^xCw;(6_|BJ*hqb@|)7d zCxyZxoTU1|JNeJNzxm@n{MLU5*m_HVyFRg|y~Sa*{<`6Hyw1CErDH?91oyc=r_1); zL#A<`+5Y_>{XNx<>j-zU;QRj1-{0fbahm%)_M1LBu>-1k!ka(luXySG;y(dA*fZ`>5I%DVPB)!k+a7qIpo0U{koPH+2 z^$&>au+jHo-#*LnaSb zhGEhGGLqIJY3|~y#31dX@`-fEGqxxVnlnsVKZQb}*l@6!G%7fyd?^Lg5jh>7L>qySpjfMcMfST4*Ym({AU-W?vVEQ@L0wk)fE%aivw{eKv)%fLh8Sq~G- z6SbKSjE12LnZsC>ilY773bb?4VO=JGD}chsa1P4DCr-xAHm&2%n>aM@jXt+^@U{FW z83JxMaR7g;`h>vGe&aW19dfNY-F>RzjZgRY|NR+&yG)$V5Bh5#zCW{ZYlmCL;kP~8 zSO4C(g?7;S?0_h74fn(6zvDkehWo>vZ(e_f?vU&7`Fgo9Og17;DJ`H)MNC;_{-hKm z+_%RZwZYu+qv|sAI`J_2$=Td8>--cyF z7hOHpMHFBCfrY;~*x$R)PI5T?tcv#g^(QFj18n&8Xx!XN*1&N6-r+5unDqT;#c9*` z^J0Jh^AiE~C$@s?^ZV@S@4x;7fSXMgr+;yh4}a=w-uCE&%P#kyl5%*-6M!8aZquJ@ zntyu;-()l{Wu9_VZf+qFGI>LwVH%s5CjhXEyx|_#g+52bH&a*6gs1HRBpsmH?KlZV z%ShE#5g@&p=G$~XsBmzfSaW}Fla`A=?Mw@YUK=3#4i|cJ)^fd>mL0Hg|IulSm$0GxF$Pj{))jqjQ0 z#m84gt*M|58@})HWN#z7&+oZMy~{0Py4QUO;2-Z>f99FPvmObsN%d_zCriKoOMpjJ zKO*|fs{nT2g|s8m$5Tlc#4G`K-U_#2YsLqKDLctN;iNUyu^g`ypGeQ!SW8^?XaAW) zY76XK&9}nmunoiCFy(O1OEn*NkIT+$8$?R(Xsu?$y0XWSY@VQBYU;)My(<0G!HQr_w2Us zMA9cXIYX0iALM9CayKzY1z`%(yFJ7JSmT9*f>-P|0-Sn=KjFf`IU;wMIMY7#A|F2S z_wlc7-Nu4{emTIa{?&)~n=Foh?pT1wzto4{^6!4L){fiz@Z;_W@X)&gyz!$jZCZB< z%5>2b;exM%V(B2cc89|sCrK_Z=bn4%MD889Z#|keuRQrXRVTxpe=)GQFvJ^vvlwf; z%mclOqWadNf6KC;cOlV5d)B(h@p;QL0k+s2BL46G%q0E(Y1W^t^pQJdZOhGJWTYnV z9o{FmcVk4jckrZF`1|KQI_~?k_fu{3ZrBRX^tQr(JkEz-^*+CN{Fg`idb`bxVIyT% zyz^54_q&6?-*so6#tK)C2H%&wofJ=rN6{ zbXulO#G6FCLTU;6Ry>{C`nuB&xJ3ar+r-~rbrpT{q_wBnxHr?bzVv?0=2;3w3taRk ze|0CMy3-@WNn1{4ANO;B%dhZZw@K?8KLohdjmvqvJZ?VaM%Ysx0ZILAJl~(z?Akows6(J3V)0yT`eO@I>)e|h1aOC=eA>@{1F-wf zRd%9Wsnn*MvS?ZCshLo3N5G&umD}O~adnb9pXy!!$ZnkgXzFUW3I3AH;y8ye&)I^U zT%0N&r{VG?jY6N(lDc6YF*tu<{A4?C{=;eL>_7hnq~Pduvz9`EA!MI76dM{THxZ?y<|@tyFp5y+bPTN)rp0tB;}rph zTzfOKLfo7>T}xkKSvuEiGIE$TNL_at|2@^tcVU*J~2xa`zh# z(i@ZMj3^LLueG#C9O6b(o87Y`A-9RmV3=8DC z(Cq>#q;zdmFKAkvbjb-{A;H%|`Dz+Xr*%(RzgCFjXaM9k&DAZY;!@iWBHgT|*w~<> zQ5w12=%i96#Wy8^xEUE&J|}SvS8*iOr@>0HQ>}o#c_t;kRsbtlWraeqP9Tm8Rwzjh zh=Cz_$|P$QppPA?SXT^Y7Ni_)7Ul|*PcDDd0%iqdT=}gjTE3e>hxyF$Ks*rrSuPEq z|kVp#%6o|jRv1afUm6gs{f!?4@Z!gVVyQ77zk)l3~+;Vuull=9H>SU37J!QiCzR(L#f9<4?9OUoa$z84;e&lSONt@jN=>X6F z2Y{mvl@}i+OBshb7ff!k6qr180ToQV3_wrdnEh7U#BuDRaK)IG!96dnlTFl-J|lfz z+7?_pQqXjhq2GAmS|7(76k{j$eCRxaVU(Ts8=+jTe4K}lAWAcm%u^_q7<*JFS^e=G zfP=0HaKPR^{J0lS?8}1zp7LNHe*8=PCrb~%ZaME?oiec_zv=IP^Lu~2;!1yYpI^Mw zKLNbw1wK60jT8InRqw6yJKgB?q7w=3l-Q#Wg|&h^8S73r_4iMCmG^Ia?8`p zB1vS}>{>zi&^4-bVKd$Vry>^xJ({h0+A2M~7>=SDD$Q|97$rbY-W6ai_!T?gbk3_=X@V_o4QUuZQ>X{)rZ|D2Y&xY|G5E& zYwYgJ`24qh_-?mqik>U4io=_rDX(G?kX)w&pE(60`-GmMs{_z< z7sA{%*zaiU3RE+(eFL+o>z-|^@l$X@OO7kk29yI?tF89&wb8v9Hf@iIPb7HlK96nEkKf&zA)ayU&!|pSPSO=Vck^6)j z|0z%jCw?3Ss&;wcGkx&Y{|d0r9+2FA62LVlw-_kVb4v$Sh>OI!L1mzVEI?ynct&r5 z{cSh)a-~#9>RBnBAv7Gl)D@+9d#YUrP+VlB z10fuB2(-qvCv&OqzdMdQ^E^MooW6d?a{zXzKIc<`~&)0rXZ~oqD3%|k3+2{`c z{>VBnUb>%c1Hhsf(FM?xxM=!}SD*)8mzUTioXsOiYy)ZAM#4T5-_JH%PTH*cG0ag1 z1AO#Lew;XLvlXz<#;r1NI$yG};yg~znMNK;BU>-fNZW4HUrn!vZTnO> zG7pooUj;6M0@;v5@g9QD0wgU{e*Wb&Da_2H(&DvB%x16!F$HWAXrE&gB zM6_tf+e{Wkx2k?1_^wY+9FRY*H%vKa@*Qtl(_U*IfJfaE;2*1v4Q_FD_sOE`E1u}X z+i&ZCks3A_xD&fv-0i9j3D}_-u=B0s@RJ|pug`uIz*|2tajt&HKhN(cd|&w3=E+@( zpPM+T23Q+dfhM(%o$oz5P*MW;wj=ITLv@S)h8xYkhdjExlZN z=W~5{r|tbUCNx|4&8rSC{bzp?;jFyLBEJv-qKjVS!|qh9 zJ*K+IXV`ule?6^QO#R$sk?yH~FPGuu(>wmh>zMh#7RD8_lGd9BwyE4Wb9mop{U615 z|Jz@$yI*B1RPX1K+57R~?W;{!VR8F4AMl&A!eZY2Zy)o0&Kvz^@7o*!#n^HC`aU#C zSU`8D+-cXbZ<5{!p!n1q1(179XC;fbn)3oimV<~SdI^u74aTDQEBzkc>xeuMtKDt+gE_~bVG z|MWy3b|(|Qv>&HdQIZ8mb7ih_9j%J(OB$eaAV+uU{JL7tDpc3T5`p2|#8Q$0+s$Ua35XXH9%KFMO-Nf5OYW?e?^X@;qpnZFGFh!y?^P!iB2|r~BeG zw`uDJTfYEcYpJ!}DO(D~Mgca8_^ErW)TkR!7^VCe;ht7CMX%U6pkCC$x+TYW@IunXCz8r* zP(WSCtj)Af%#j<%0*AqXJO**gbQd54OT*xq9kT0qyEqLg+ z*AjRvaC5P_RE=}OEL|^DIOuB`8F&B=Y*d;S(ZN^J_EJ1AN+^u3 z6YJajlg0wl5EgwwMenkK+bqzhzBvDo&uxLJtBup+n>@evlr~FQ#MhDxof^ubJKL_! zTa{Z8S{ubIH%7FABOjLL5DvD@a>hW$r$NQ#xCk1Ep+q zo8beAypZ9S%SUxSwljR*Fu(ArxUKSCpSG-InQ;0H7}`2)&iLb*s?`)51Dw?_%_som z8H8o>0m&nkRho{=3r291PY@g2&tXK+%C9)q>~Rzd#j+sfe8B0FVwf{>dL_gw6r=P5 z&alGqBY_S>CV5b1Er)rh@;iLPt3%Z?42gHZ1m44xFjPGkEz+zMvL*BY*^{-b71MlH z%a>srF>-xcdjyuig+Rs3LMi~zoIEbHQiI^QXdxAnyj)A1|gv}Y} z_}iO59NxqX#C;NiZ%CBzO*} z`ql`!H&)Wq4e*L9)#FodeF%DmVm;wbX8QEktCOQAIQu+*`qiP=_Th)#)qfgZF(*jM zDJ0wGe2x2zAw9t|uoERB5sA{L5IMdLULZ^IoOEv^^(7k4PQb{~rnG`oPad%+p~gbkETllFr4?(h&m-$Xf%*GiYlj7RLiLPtXc9 zY+KnqJcTRHLc#wXp*M#92hf<;263mET0%7a=*+gP%o5l2G@*q{n~2WOr0&C|(O1IdP4$2oeRVU7 z_fxxiu{flMsS6Sn^n{L3h9PyL;Oa=}=rfxH4=#Ty-W1$Rb>Dd4gg}YDpgteN@T0si zADiKi>&NxB9&%5iSYf!0S$Dsc|5Gdp1X~I($8(=BoMkuUO89Vk*%A?oKZ|JiDJEN8 zeC22*d!;46PEfBtXyc(iCY6gl2ZzWLb3G7DTkDBp94}=$>|%##)Q;Q zdi9CY3Ce&lWhCV_;S9V4*Q~Mob}X3cUMbZb)^>xmQh^7_K&s`|fem$I_Fv6f#EA`H0=+mroWYs-Kr`vIz*K zwP2{T*)h=ubB^2v=wo*S<9yD zP=cKMNfN`>eg!cST-WP8GNNT@`v1&XDc@Lw`a0qq_lHrR_2bOikW@ z+5=8(030M2t2YWOY)UPGutkWHQcm&`PP~9wT$s7N6I#A+g2@k3$Fm6x)=70>((oyY z6avVd`=!9a1P51gPi|sWRC_VUk-k(!44eFp4#nu$irML|=61aVGh7XPy+onWcagsN z*dIHA*Z`H{LSAowhQr+-6#|Z|Swbl=~bdFKlKG6kOOZ?)_t?RG_x| zqe9`89lW@Q62^raEF<_Oj^C1<6s0_lspV#*oMagUCL}I7DJ>Xx$XRT**MHYbT_tT| z%NMsRyIc}affZyUY7?Y@;0v*Cs-HNdMqE53Zlvne3cNjtCdax6W$-}lkU4`#s6Z*hIqR{A?jJ}5@kef!6PAYX+Q7OEe0s^3n4Q9*ADFccg6G+BIEq%& z$5U{i7Z#*zV3D#C>a1DS@9}(;l~Pu})wnp3Cd{=S-QqFYHf!2kF_D^rxl*B_q%&pP z?~&I{@GYtYlL0ItWo(GZiK$jSyCOEwVrY;jUj7qU+Vdl|ICFJ6bKE_}X-OWd(-D+@ zvicA6w?r)&yPbCQT4hr+OwP~9OIa9`SHsQ7hdd2Zql-uHdB2u9DtU$g9gf?yS&IUn zw)LPiQyiF0H2+by$=mqwLs`}TZj3!GT_@<_r6VHiS$-I@`Yg=$RlJ3VnI_@oO=!#N z`gu^2%_q)EktzR_u*9(6NLif2nAbEMX7_uLwN*01#_hWrWNWZahhvN|1sl6CFwsbV zytH7td76f1+r+^1E^*wmZp2V{BQTpM*SJDny=b>3TT>W}egU}%sPiZPnFCHh3a9Ks zcCXRf+yuqkmabJ)jcf9%fyY)WxX6zMZNwSma0MVZV*i+bNidITb8lizED3Z25?Hkj za9lCF=s?jT{WIb#qDU15|C*fM!AGUpX92XGP<@}KStN?9uJ}eSu@0AsSkLa|>^msi zKr^;cg;JDS@7F^ug4I|WROUZ1`p z`u<{zLi?XW2AkM}q_|nxXZP_f>7+iHv@;?Kfdi3~GMBeU_%i!O`)^;jJNJpFR=mny zi!J^>h1?dzXz})^haaU69Jk)IR9Q{qiir^7^k*Llw8Pd*EoSvfJmcV@V9k`tLr6?lgFw=@0wQ+w@2q0&FNi8HRuXJQi%-Ob{eHoW9a26MI+ zES_Bm`{qfD{31s5H{}^FmQQRD+sU}!A zv_+QS{zmCo(9&5lp9XT$wb!!jvl!$V?cd;$iklio6}CGtv(4r?H8YdiMgeb#3w)*b z$cZ`#`_CKYYmUd%0?v>F=pdrCib|7MZP-o{H>&ttU081f()zxX4)K&Eb1yDE zwUSi$L#XfvH5Qb7m_2_bbdINd7Se+1gDGKqa;9m6Pr-^*@TRTdn-HmouP!~dpPQdDIAIYR z_=h}|Hl&ljtzLbv5Uma_V{J}LL*n*LwR3;3zRp$N{$g6}aIEUDC>CA?px#feughl+;*q}m5c+{VGj=QM0Y|{x$LO0^tR`hwLaMubtE%hjPr1TV7T6yLV zIOL^Zdl7~V1Z_>JPT>Iw*y23lH+)Plg;|2MsR25R{qJG}Rl^tt=G-J0)zz&hRc(e| ziUrP959i*Z4`U=^IRU?@pZTQYg|z%vv?+-Pf^_)LJ%Tb@nGzlHuA%N~kzh6w9o-7o zbIkYHTTW+#q4hDJizL(3MR*)EWl?<LJ zxgdok+UEaa!c&RX^Tf>4JDrFKL1D>dbB;1<1m7jSq1QW%VDtp8H;FAF7!R9bEs%!m z?ZT3Z*pKAS-Vt&Tdw_rba+b^nm!hhpUaT@x&b#A$V6dw}*p_Y^XmP1TbSw1iSL95AkM`Pht?+V6)fVbkp(1~fO z?RliU*pS$12K<8aGbB;J!I14JHhKspAcOr#5fb>Gz`J=#EcykYy(W2`3lfocByR8+ zpHFaAJx{~VzCL&J-4Bln(uHAgp1DJsHb*{1<~@59qxqdT_^<&fK8^BmkB?YQQ)hr) zy5l<TwZANOez8=$Ro)DO9=K&J#h^R693*wpJ1Jvc5eecI7Ehd zAeLEd&5II~jsAGQRu-aOeIZ3BpNi^b%&DS8Q{`Uxydt}m^M;)7aF&QN$l|PmR8IH2$^mcM2`2`DFaNB>zq`Zw0d4&XJNCGf zMzs8~4T#*|29&+!6xO9vT`A(?PwtfPhTuHt`Z!H*f2<}@?u;HbL==d%aPQxDQoPCK zqfBTys43J#gS($b??M!if~_WTN4QN!E+XbY*04xXf5Q}5T-vY|*0aLWG&il|nZ&W#S!%+9I zq{=|BQ0iZ$Kq;z`b;MDYOmwSc*)iS;gFKr^jBz};=VEoTF66-&($*!X$prxMG91A?T*E*6i^E6UPSWj>nS+!?b@Cp+i=h z2o%Jye7Bq{xH0h5)*u`bxJSxBrdUyZQXO(G3XgDV(HJ|SEyYYviUe!W6-4B}7{rD& z*Jz|>srv@ir5s_TWTI5G_nA4e_`)!U5~-Oz!KJkDOrQy!l%cYqz!xQcl!`8-FlB4r z$eW8pbK|@31LOhFT-*ujjdFt+cz^GYk{d&O%#9cHE0+*xP$d<$CcRl;fX!3*v09KZ zybAfhPbUy9lKpGa8rAMZq+=Ts=EV;tV^blX%+W~Wc4lR1M-%>o_mIpB!Vtp^?%1fo zR(92tA9ALvp-XSTAW?Q(ZaGgYV6=y0)Lr({%J*N|HaU1Yw_ND-sp1Yf+?I}?Ttx;tSd46Ysr?nR6Q`;Re zrlfTeR-o7~H*0}9c@0BNZmC^0{ z%MzAGRyDyFCo^AW+!eoMmqQK(9O5*YuzNr*)3T5Mx;mhb2gzG4HPCWG1Q}%t+VJBm zR8ycp#KXxDWoO>hH>w~D@L6WWndUynW0?In<UEX6x*~`l*4juOX``BFXV(UpT}z1UN*M zU@c#@;G)^#4rVxRMFnQ8+E{BsVTW49Ak!BaA;%)1X^G?o4%)f%RRdSC$}1C=OucBO zXOy?75?~f2CuHeInZPlt133aoxg&KErD*pY?>Bp4C0pjtUj7#Roq@j(aNFmJ{2&a!9p~cHwG|-`R8Daf6&CpTlO8QT|Y9 zCTk04uUykn2gP%1EP$MT-+ZFdU&`U%OCqhY7(1iLA=*r%Q1^%`sF>mKWBPOVL8t@eK6GFr^$}N`+tUz72YPlfd

    A^sJ1h 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℘h@h1d_j~$DKuYASG)7&z!Q*C$ct5Z66eScKv7?(zMyCbUe9nnMZ zxNXKqbJ>8XuG^fQv`1WT`WeKPk*ypU*+rXQhUHOwb5!TP@Oc*w(r0--n6_uENAZ}w z*|aAxcFh_zMQyl!G-l)ZYO`qkW;zsOMWkn$4#kMa?Q{SA-;oY&X2K_b-~-s{t6#-) z(U^=&nh>Qu@ZImCl73ch^vYFuZOWFI+DASQl-<`pmzG}A`FTyMTQ>cM$e+r5F~q)F z{0X?!H$3pL!|?CtpU0h1yTusw!ylp{J|J|=F(y3nzyqNle9(M)HpcwOSGeQw!!dMS z!f|ml@9%%c8PI8ejydZrto`Xvao;u9Bn3ovckMw3VW;DctBI@0d{SM!($y>d?v-!F zUGL5Sudh$ucOPCz52s!k)hpJd!7VK&yz9q5j-f+`Vn)<1F_yjOJ-Fq(^KkF~e9wem zUbzD2{NWGSEA^!x|M8FU?<=pwfYe^9XfD~#`gH2LwQI4Ikz?P;$BuFL%P(We`R8NS z&l3B%s&yk;BL8=*tFJ~!g6h}Ww14N_eK)o};e>*{+ByBK@MF=u_}mp&;P`ZWU-$G= zcqSTuvm%=w7t+ILAL^jb3ftqsmj8iB{DH=f3_gm!>w(UN7|!3SYf`dRc_ zueu7A$R6(z^;wK(qw6!5UxDY-&+M%lHVgy)-~Yqd*IqN>g%@3fMVoAbRq!HrF@HW5NBzA+ zG;U+W^Tbv=?~E5VPYxTd{=_FSJZk&l>1X1#{R0HuJ?qH4>uk#)$&%T^HkZhRZTniZ zwc`9#kfp+u;o5btK$efnNx#=f^D5Cl>2hcxPTKgVG+B_=C!5=~r)-*D=7E7dHFI=S zMYwn_-J)~$59LW^=j7)ewrJsM%UU5X@s(O5lk$ z#7XHMISbbe+QF|Z1T$pD-{?_(x!{o(0!HpDv+r}(Of5Fl7ZE0CU;>yp@wY3zT zhIs|lOuAQOK1oJjAC{eJ;gA(|@OHIr znXyq%nyY-22y^Xb%j_FFaPZM>khN_n+X{f&q9}Na0eB_n?gIk)10sEY_@U(2;!~$i zH3z2Ftxq0UtY5bt^P)}g3{$2|!J0K|3M}To@rJp+@YIuNX&HoF_DUXT3?7uc1>mLh zOGq7A{PVOvS&VA3l6I7N@^%j^E}G`|NAhCS^VoA0S$~ z6x;8yhY1ghHvcm$Sg^o6471-nuwvOVJU{bMb3b;gt+DX)XJXBv$!2=|pm0s}0Dal= z5chsVD#wG7?>VB>x~!`JurObl~>IDl&zw^TV3nBH=;h@~f z!zmiemM+8i@#D>}#esiDSfj;jQGLP zo6$qs7#Xi@6E)5ozcs75x%PgDRjXFwx%=-o_l=S6Y(H(9sY5_t1Lu8mWGS5zyfG#{ z)0bH9jlD`AcIOUwMR@)7*D?FqXYpeCaIP_WIC*UJaCo%!=8_tuZMV%rv#J1~0i7~8hKhC!*ledXm>QX8|HrK9cL6t(v;zxowMZ@Ouf z#@F7lJsFes&;01&X@aE98yb}9gRa7$$UeRD%F9umw=yaj+eeDIQJr6l>Kx6>0+J(6@N#<+3$_d>>PKkwr0~##4`TdBKWfq&|M3sJ75Q$B z>3qM_o_nVDQl-m19r>H<@Z19rm~<8SeLL;EbJhPS*n0b6Y}K}xUENdEzmkpZUQS{P8YxC1&GRr{Z|#i~?a;_yQ1`+70m=kso^uYQqLI8g|-yZ(|cO8=C3f ztLc2UbkSn$xcBsEeUz>rqT%!W1NWP^X~med-FBE@+0Vt%`Ye9STyw-P9%(y9YfY|g z<8@pnFE?gv+^2P_LDB^=+&!unv8@~DG*fxDbw2e1k zebroFkFGoHwO6j)mPc#F@nlZO{E+!Cy@Xw6>=WrkVn^b&(9CH3Zh78$CcH~D*1HNQ7eAdpjCtC0RI*qrH`7^OCjAdMD$>`hT?Me)df+hgr1J(5SUJ}c21@#-tDR`1g{C2F`8LV42c{M>?@>tw26+|IZb z%I5MyD5K{oQa}%etuAHN#`k2-zS_{jy&Y!{D>~F@Ue^$I(Q?Dn1x_XxjUC6C50|;2 zG}Kd&o+Q$+)Teg5ZH9a@x#Uvd<)l|i6VT6LD^Cn=uu~crB*#q?Q=w97T^J6OleXw3 z)t0;g%DYCdoi*ZGh4U076HJFT$3v4pT0T(D>`F3Aa=G%`SIW1n$41SQR0o%Ak}Mnz zM@MOWkjx@A_1cqe(0J!x_nriKMsZ4n2CA&v$2!(6R+E=drT)ZtO!0VoC4A6e(>Pp)l%sn9Yt7|;A z4cZf@;4ewJqijWYO)Ne|4hZONP>yh!q2=P`i?2%5svTp$dN5R5(skSU zbrkx1$Mj}&MCVX1FufMuoT5@PJ3h^uy|utTgvI^ZU6quZ9OkMU;=(GGGoXXPdA40# ze2ieLx)3_FcSpjtz*8mT?Klkw5t2_Sav(NR({ib;x5M-xucE?mD`rt}0d2H1^~@&% zt&>AfombjAkM@N6=&rLd#oE?cuuHXB0zYy~LS0YcJ-{$`w)$}T*^7KTZoiS4J9Sy1tSa1z2y z%h4#;2egd#m@lEPs&Cek^1FD~lcyWeZ{DmGwSUj5r(^(J^D4)KGa!l#k>V#1?N1@v zpE|5vU1@U3l7xWYx#!FYAe%W#BgMJOmpl{gNt2+2@_i;0CF09!iLahMUQ%0@EgSGp zOTO}@aw#7;rmkhiiT1<;<@Kx{%jA-^Y=2W(+iDx&;pZEF zW&61-%J6gP9Hq5+mK|3vnaZ|x+u^DOtTb2eGFhdL1j9BUpf5w3P?)&VZ`Rss3RbUL zjSi73lcS7La!pt?EybPj=U=wm0^{O0pF~)B@4eXc;@{%=uYSdZ-*)oJXfs?+B7|@j zXUomScOV828EoEo6Qe`=E+C+XV=#GB#_H8>ou8Y&N#Wkldec>wKN!_{{=no-C-05w-P`KinHWsoROBDG zucc!)Y0uL_d$Oq49(E)ie(0g;u!()l z7zO>3<}hD*)i{m90cvSZwQ0FeBy;y^zUusy$zPbiRDMp*#n}}ADJLbM_14Kh@ms=v z@!=1fH^;>kjhk|yQ?w09UUNmhz$}hkkJ)(`rDI(S65%^A zPju<_+i%CFXPjZ~cfI2dRI1N0U4BgG;>q+4S}%V8`#=N@!5G9M+z z&O7g%d$U#sX(>&6kXyP+dyo*~xoh@jt*4)U+Q=Bc;mKvbx~Er@H)~}w#&Ew`%V%II zowRwt8E;Bshhfo6{(KS_zlo|?AIb1b{JOhWYADvHcfMKcwaBl{kiJKg>sY!a&nXcH z)^d|{A2`L7l!k*#se3cJe-QLp_~vtIIAn1?8to|~OIL&krJ?27dANKon+iuhDP9Tp zU}W``R%V%ynqK(QS-8G!O~Do6f$O^Np8>uaW|x1mS1f0;qc(MtJ>^vQ87o3ci$ z$e`AOjC7dNYu@Z>F%KuLR3k1;GP`i_0AzFE^H?+!U#u_RGp?QjnL=N4i~> zE1s55>9s>1USHgNxapC~pgiSrWw@qSAEar-Rc>3RIZj8o_L0gdqu(4~Y3c-X40Dz%mxwDfru(tQ^Y(2G&8&QIEMOLIN&!V57wdSJUM{Y=;h zv;+1-Q0}2}c2CoD27#b(2utPZmBl~jG?!TgxK_xn6FxUO#_I|m8 z+PgcTeJhAO;(E{cO{`5n|Y$mzIhcspSw&PcQ5(3RKKcIlE9FC`=x76ESb(7 z2(u4wafip~;UMl1n7O8P$mUq+S{yeoRu3&HD}Q#A%-36OyB&UV@4fkQY?1;m`?<+d+Kciq@u-GOO+y6;+#$)0tWgAm&_MquBjT&VTJ{(`yP8Q9>8RNc) zzFMzt22~{+Tv$>)$zF0ZnZ#RyE^+S~e%#QLhBL>{p25r3QJQF@(==&naK%aHmW}`}kFN}$ zT)uvn%Hw46@wca4FlD;(O7cm0T$h;+9u72n4ix$vd2EDh_ zU3{c*DYXsFW9x`yZ?#aKL@&t*$T~#nI|tn8bZL|wFIf!-TaHCQKwpH*C`$&3gL20e zHo>Hc!)LfrM_L=O$M?VQOz$y=mt1X>?S*m^OPR?!BT&gd;lNfve?wWFA2(@|`Kvdd zUx4&l9jhAbTSI7h*@IMLN9_kGs+Mkeqz`7YaK#E|VBc85d6wLYfqL`B2QZ0EoqXL;XJNF@(%d$C*9@w&Jv$TwkJM>dHRA%MNv9ssrn1`J& z{i`;VT`8SLX{(L3W!5Zyn#j%_cw={(H8VBaX|!#s|D-ac*NPn<=S%ZvGFDk?tEy>T z?RY95t81FbplWf_o3v~`m5P-QIbKH`aRl(Tw;3L-1=;3n`+ur|ytb`ohV>4&s#fvY-*0GL9nD(xB z<)~^;@M^j9+n_q71IxcyAIe8#@uEfe)mdkm_+9tkAMg6mhp;&QN>PM=|KSf<^yHIh zU6Z^?ap=TJIO$7Y!k7sYO#bD|m*dvUF2nNs?>Fg{RVy)Q@)kJp8{aVDra^;p@@aPR z$$tqbqf>-VTmEA0YE`NVMR*n|F8c6C%=P%6{4b`YZ)K<3EYvca`n9%V&aW@PV)NBP z;MlXihW4T%FF3t&vnf|4+Y_*PXoi=oiV{DLp6g7Y-QGoyM*p2$IvvWBX8&>OO2amt zG%UEhHl1S1x8rFZNiN&@w$n6o&+(&j_~Pv}DvLdI6_ciz^11eNnGZX^Z^%e}TGou% zGHIs#fB+GS3EM7K1})J0c-NHEcGz^PtoEj=f+9msvqK#u%+1QW8j?+d1FvydSL5`VrV%Xf>53$htvnk z!%s2!xi+>z`_83voQoy7GMXs^3@wcVc$)yvJsf!e*|v2o%8pJ(Qxs}pS0_qSY(PL? z0cXfudS0jg=QhKXKb~aH%M-?4+deO(F>kOc0UZO*nGXo)L+B1;NjDoZ*qewxTAHs+nPqr!{IbJR z_JJunFZvF~WpB;O_}OvxTeV#Isc@N0)pUmpn#_~-JfE9VtvTCHgCf3v8rIrsTg|Ko z=)zDF8MMVi72Bb3c-)dpSu#|~D80_Nlg zl@ASq2Dj^u-LiuIl`x5$k{kjO$s@3C=a=rq`k6KSV zKb3=CCAH@ul_5Rnf`gAF7YHv(5AgMegQsL(TzM3U=jgcnWgwMR7K*tK!?kCkTc-*- zIJr2g=-i;Qt%9~n=zbk(|(~WCnNb+k(85|Fn zEGWSnC3s6yCx-X!5@UDR0b8bTqKe<*GitNVsx)uC^%nl~t#3h@&)8~gf9N5Ychk-I{TIGy z(m(r~-=HH<(X}_VRw|Wh`I95L8dtB*y;*DN(xsSv_0>t;-u`whSg^pzXyhL;9NQlf z$$0b4CLGJzQ8L2cl`{P!nEw>#g|HnP=h)fB(CAao^Q{yA&(`_BU*nz8Or7 z9ErwTZoyTjpKih@U3@XS|E$xu6>7E?^qFQ&Vy-^<+?rf#b+y~F+0LW$v?$10;}P4P z23W_!I>6Uz$`=c}I7TE&OVvRO^b!v)KR2V>9Pcuq^4FU`pm(5KrVFav zbg{!-VTHN;HgDweCOHyEMqBfy{mDby;j#1bB^5u7NX-oxskjM8bcfS{j3<{~HhaJ?vNe)=(+JHWQUUxV_m57%fOlDX6fwJU)SMM2bnR~N`=;`KZ;x?{MOWIX< z-$FR7)v?I8XK2%oLO86|Ip~$+Us{rvS&rNJt#vl5U)-iAx9P%`Yt3r_@2i63vuW)^ zR@tE+x}LJi^NtTX_vW@RbTOSC>axqGVW8Ybk9H9#t1VT&4ea!sK-S_Q*IoeoM$cTG zm35!;9 z$K&AmGm^P1NuK*|x(RDve;sG1hjW?-48Zl{#^bs4aMX&WOEJ_O-gew^ zK>TOnqNwbV+ihp=k2v83b8u))Bx8)P|KmO*;|=4-oA9#{ZAZyy%c;}PoW^ptwzlHx zKmO5Z)4}h4H=exa>gwS#&X!zp@x@sE{PX61^iDgWk)gZ(kAE=N^)I}D%Fa7E`4waY zO4GPL>loi%@uxpw;d9Sn)VAB2xQ3MGeV_P5LX=%oT-(%y)xY^omEWl!`VbKPH80@-!nC7s{t-KDJOF;M^~N8Aly^tO*`)=%HA@em#DWe%5iu!3P^1tEBYj zf9-47|LCJlpH%roe+yoiWx`kd?spiq#~wKK)KiTFv!Z@{?usk0@y$0)`lvmop&_1X ztoD5EvB&ZJRacr|^U`H#h;(!FlTR|?t+v?~3*K6Q>%a3I6W;TbQ?UG&Te11aK31(& zQ?(}Sj0%8#{9~sB<#^CEZf2Ie1fMbO2Zq)_A)uY$RMG{yFF_v+QJ%CMNe1QMDGdQh zCO{r~Qh6L-l!&LYaTZp2^1wl7$NNkWz%MkwTbP*(cdo42^MVwg(I(M#q_GJ`JfgEQxx`QT7CkBg5am&9KSJZSk+TV-*Q z7Y0H@O(-pcqw#5|louuVae1grG@q-Df%^JP(ld!xO5;YNtKT?X;N+3w;E;jiryXTc zD?@qGdzTEH99$n#o?Jd|3`%|A8{?Aw;CM*T0xw@4MP%dZ2e`)wcW={5I%LynhfDxp zKQ6s~aF)WBjM9QhSMDrQ!*DFQ&JPIaDd5&Uu;P>_Uz-bU`v?yY{CX!$ujd|g*a`4Y z+5rK*5WVtYIyWA3iwshy+yj?%Kvy4D()jpNVany&slo_Iy<1KcX%zzWRihH-#g0Ov zW1&4e2cca%2c6okuC+j0cuAWm75Fz^eC#X4$8>FaWaZiA+VPsXN<3L%Vp?6~@2HEm z|1srhd7}l$&&8T$B&69g3Te_tBljk;98c;8Sp2lr7^dyDm1d_~4DC0aK`5shXYtpx z;jQwr_KA5{Dzysc>aVOmAoZwJ7+FX-$2(U^^atcsB012qXwf1QZdkbzPdxlERxVgz z!eggQ!Cw3BTcuw!cP=)WJQ+>tVVgMbcDwC{1%p})ui8@4?uIqcHV&|qX7lfD@&mNU+~O(bKCH(OddOhzMH+M4ECNo0*>_~m7nRcW5P z`s(Uo9a@hkX3oSbmtKma&ppSq-{XJ$qd5R&)7^9X?O1i$Kh6DN=beXF{_qDh3jEq# zAHp}gzWVaZrj~dA?squ$^Pk6)mtSt;8<@V?xN#$%ed;N5zv%9}F=V^#sx(baO*y_X z*3X@TrcE{}#CKMGR!6#h*Y($%@cxG!f}5_r7O&lSqY0~J%W%Xy--#!qeu?#OL6kP= zl#^?3vx>*cE3e|$AO5fjZXM~}QAZzz*VDs+Grw^jmaSTiN&D?*!Y}^o-`IKfY^>O0 z&uaP4|MN1mMl>;6CQbxyxf!$Hc*BGzpMO3UEnI|yZ%W<-_rSByV#@;#$ki!5sK?Fx z3i7VEYX+f@Xq1Om3;FGG=p>*8Is3ZN?H`j$mw-BY^?<51<>?w8S)4sQw5Ke9ckZO2 z;!3BGhLqhtzWVsmTy?O+v_0%F9p-jD>3u+e4{aIu?Jk6yt88WF=1Skd<>T_N`Bdp$ za$g%RS)3*%*1~jH(KrQuIMP~xq2>0TDG$y}P$(e}XI>?5MdAfUM$Y_erd-K;0->{c zWbv9Q7w~I^G@a1)rfCu%`e(}_>4Kf#Wwrsn4J1A^FE?dL`x#Pya8n2v9#XukTu$%m z(KmqaPp%E5{-yoJ^$QptQhRaw?;8_bdrLBM{Z8|8^>p=-_LN%&J~^a*a@hsSgXZ(0 zOr2H9G|A@F(?)r4CEF5EI!&%5fA!4~0!!MsWg0LbpeKOSS#DD7(86ry0sR5ac~~;` z+QB3sAfRhdX53X>C&_n;uJmmdIhyoOrC~)UCeC}+UUAyzdRd@#Ch z)}Auy22Gg_0*=nL*;OW<+oW>kb8Q@<4!NX_n=+e+oUBT?x@6!s{Bmy+Lviy?rE_}x z58YrZ$fij>6}h*3h+G@!yd3G9XsYy*-%-ne+5s%m!FIWtkd*+ix7LW}%H0 zP!>s7bV8eT;B;TcM70UhUX72IMwYcr-3rCt_DOWLyIDtjnuB9YmMlgbp0_fT zU3j?C>+u_VCbaa)5Dto5vwNvIdVli-^hMO8^Sueu(llr0tiem?it2dPwQJ#%L=@Un zc)~|p_k7_TTx;N-51l@k4sR;z803F!7|>A&pF!*#^vcg5`nJwEGw)h=XpeqLJm@`0 zye^hg;K#*tya0JBQV#jE{Hi{F1-Yd>cD$>d#qC<TkDN~X1w9V7v4U4BKN9F64(+!=!($6Hq%GXz6>vpAL^gDa=)99_Y!p0|_z;h2j zY{E~!`YIki>@a-l2R}&Y*RI9jL4$H*V)(FO7&>H#xnDA8PKVe&GvDjly~Ok17hZ^g zQ6CeVLqoj?64Hap+| z>=w0gjHmzjhumin=g*&y*M9$dY;nX9Mu#WtxhLjE;oN8WIuP8Os49_;T=LETHsL8V zX5jGSj>EH;CvW(l>p*@x~iQrtvBLxZ{q;UZ43d%$xT{wNB=+){sb%1G*R7_8`Tol`E@#CHYZ+ z+aJ=7G6nyuP#z%rM_jt(%ec}wI!<=(KA`PbxpEbT4jqE-12+Q7Xt7O4p&33ddb_OJ z{mN+k)!L?SYFbjqzC9nTT(#14X6v2S%8P&ZifDQ);`A!E}1K5gRQ+M{sysI)1s zJ@nea1KtvSdn9}=5NhAfN_}$WN^8#ssrH1kxb}${5YVCMlLr)hW{ifVHgL8LV++mr z*3R)=d-#^k*%phOiPJ@c+2bJj5k-NEO<8t_TAELNG<_T4U{U8Fv}@;}*S2d}m$;1o z2caFxxYuRMsZ*A=m`(Om;ZnF1!#e5eDMOcxE70ir^VmKB$A^B7QJ1KYcUh+MS39E? z82Wg@kuL2emdTfupE)_M;<$Z`!a+ynm${BD7mY->$4!`E!slLjRWAL8zyBQzzWr@H ze8LGP+&pj~n%1w+jfZvX)}cB2i$M=^wH5TRB;~nb!v=GG>y}$E;gCaehqDF@Y{9xn zMw`#NRKBL@+EFsv{LN=x$sx}S%~3)Fp}+carvjc-)r4Q+ZrD#qRMXAzez z!$D`AWx^{~tU$9ufnP@{0YgJ z=B-rTO?KV2Fx;CE(Ctv3G;M{lu!g+-%q{H{Nux_g#n5YqOmOhi;C(8^$fDt%VqT)r2Q^ubHyp;1zbC`vii)2nYxW=svifd$7+eRB=N{rHt%D9o01D zh)c^12ekqM9H1*Y*XoS(*=d;bpXtib&X$c?D~+`S${}}HDT;73y|1Y>yDp=;!ZY=) z`#F&$ag=@IQ&Vo~=Ueho{w0=xzI_V5$rWL*n8M5K_VBRZQqm<46S>W$nlME=8XpkQ zPJ}nfbRw9!quR#V11!$aX-Al|3*FLf+)lJS1C@KTj%zpDrjh1VDNo-+x%LdG7r`EO z4uZZW=R*Gskyel+d7)PKndktzU;l zcifTWn?E1F-fzF^;io;;t-~u%K8f=lc))}Yi2jz(nS(25%rN2j(9kgv&7Ds?X~H)= z`z(&U@IrJHOg%__X5D-fHqL+3#Q)&XLyZiZuS*WYz4g@7`2JH*;j4fCvk4CwJQ&;U zytDa>@xZ2=V#B9Cg;ySW$b`2&@IX9t*IiigqaT{^;HX~Hzx?G+v$0%#_KM0JHEt~8 z{`l=LevY+Emg2~Fz01%oc=~C~e&k^+nKjFVr<``0$&($B+V1Ud$J77*H+H!9UK4&} z$DJ^K{CKG50Vb^0Z^+eU{f6~u+_({yH2lP+f5X^+UXB+&{&5q2-_b|o&8x1$n)EPR zQ#x4Jr}T{j2Nc>S9M0RaI4r6Bn;CeE5$UHg(b8et*mI;5hQeGVG7-(2Qe zceZ=k*PZ@EPxfWXtgR)VOgp&+bRgIOd&BY9y?@d>z-0G|Z&)l2tRGy`> z@^HUqqUUeuVIB38zt%JTJpi9JYa#{MWt+4hK zrQoNtDROTOK-PB(UE4?mt~Qf4km#mRK!AX}&Lg}nqcfr5{fv!slNyliK}=UcJw~sS zkvCFFJ+<|Qoh;2YBUY?!Pw(xF{D3PE2Jc-^qHR(_SNwr`@z+sNba(~mq- zjoNw7JeM0~g=`xct{gkV!M_WtTuO54Y{tI_uJoM=_Z@ty&wIE39neT93xv>tLObz zuU(5LF1-{BMvXG*2cB_8huS8tKF6K+4XjzUGAHMg+1tD(O~l(j@B!R*%{3;t(;m|> zcG6~5{dxVayD+M$2@`fqJ}3Cl-FIX055AApQ6I$E{$n4-oVjzVd?!tugpNdY9!|$c z9Byc6z-Bw_VB(*i`51Pdx*LWK8)m{=MDpKx(Zv|Ba)k-+d(1H=Pxcwa5!-K%Prvh> z`1AYTXLxRm^y#>dehdRP-`u2+TCxO>UwbX49($|_-~I1@W5#Q*;qmm%XiHyw5rZa9 z!0tyJVZtLvj>JQ^--a2DNeL^+T*J*h;jmUW!nF*`z-^67dsJnXbc)GCuUg1&@0W2) zLT)dOD~rnm!kd-@5AT590+)tmakO{q(PSwPr)54FgO>G4giZc{fPjF`hjdUHQ z135_h8Oq1Ezc1>28zr<+RkHt|k#H;D{Io0WqR>Ks9=R~$HlRS_fZ{enK!EK(h6k@* z2gxWYfrgG_I+;i&t4DOH;b*}rmuloQOCZ6o>g9YEe>7lt+=_!$h>wbwSn>6&>9Iw$c5M59XoN zfh7;C5i~l`%W&3g*x1zJp!X-xc7|)XnUaJJQt#uoqU2r5Z|>e8PM_kR1cJaTYtyA( z$aq;9^g?`Ot^UKK$HW)ZD$ucQ+y5@$(-ThOeuC=X9JRZajjd7W?BK&9EWELA?{%b` z?S(Q#A9302SDyp!**9FI`jPW{KQyiMWSeyTlMw&Q|My$R$)sxE>O`Kh`w_~pD8tZ$ z1iUrOzm{a*@IFj+Nc8NU*7U+8G;d?C3ptj5aWbbbxDq(x1}~%V8y8&;2<5ou53#Gp zTj%Cyi4|3WC!gt8Ti}J*)so;x?h$Whxmysoc_(E!c2$q1oU|5~x1}TsJ}((>+q;6>&uY-+ zylA9>dCs)fH`z=NYQ7b5{^d4+&_gWSh4Mw+Bm=? z^vr@!p&-+rfZG|qWtEN0%v*Oo4<|PEOkr1wvu#{>RU^3U>mAq5dK;em{VC(H%ifeh zrSFpGU;VbxpxHA0P>=KFKUJARzz;L!y72O<=OS+xe})jV|J37hv#-(>0m42`y1~HM z9yN;067cbnm|?0izJlEj%~vO;YBf1DZtII4=Ul+`&wq8BNYOGvr6*)s-?o&u6bQ$q zirVAwydvPK<1Yd8G4|?IhfFp7{hhE_#et>m$efV}79TmGoRR*CnF3|WEc($+F!X#O zx|^nVgBJ)NFQ@)FcVsTWDeISE=~?!mIsr!zyo@on{oeSP*4#s?Q|;-(Z->h0xStL% z=Bx`oe4ad4X;S3{bM=&Rw#1LOJ&M$=c!6*!#NJYeMXnso8k(99_ihB8Ze)1>5H=;R zk1&hmZXo)f@-)SyBM@WSvbgokbit%6RQr%1bdCYC-( z577T09Ew|p#dDwi@5({bJ#LtZl zm_&?9e|yF6E+%z|P9c>;k9VdwRfxADY`ag10qi=ohk4>|$36^;d?LaJ0)CI)L{S7X zy`j}xZ7D&0(Gd%D6cLV1<}X1rdzf>IBqKo`i;9lsGp^x)_d#n+s@MqgGaUGZi?kl8 z!ad(+BgTc9nRrQX4Q^`AcGO|Orh2AVn1q#jo7B$Me|un5@WpD5l-!$itlF2<55w=1 zEbs%->1YXK{LhOE;;TlRmYhy8GxDgl0UApA? zEig97Idg#*##0>RzZ*e~tBy9yTmbfxkT|$W;Se#qJ#NEFe-Gmm9c;u;VEnC?h;thdD#{9a-CI`*o8H|^?MY1_G)$z=CY%J z<4CxpVHn)QS}z|*&m29BhS8A7PYpm19p`N!3&-RG9}kpf6x$guCd3H*&9BBnYoVf8 zTlJM%a+nXRDjaco|(S$Vg<-jlh&nVqms)H(OhreUl2bycW34JkG`$ zEYr6;RL6ydoBbMBvTRLCNojr}e0fC4R znV|h*gSC*aSJFcv#{$iNq1T_ovB4*|s!umxXvIlBw-On!`)loHO^1MaWZC#G zT&DUqwRAI3K5br#fIlgP5T$?mvTnPP94rhccmoo&YJKl?_>0S4^cD0}7yD6P?){EU z;IjSG-N8M{`0?7*;a)4tU!Sz=i};qLI71wQE&1jy)sjX`0XD&agx|McQ<=L^597vl zo7!>=J|~+fYBlcbGAZK-ba=++hS)LK=eO=^;G^%)#_-H`xBc>SrS#h;U&QLbgiQ9v zL8a_m>#@%X5L#1eGU=$TuTe`E1t<1bla-wPw=7w7^BVW-f0K8&2L65++)8bkeJ;i) z1EPh+3Xt*8pcdOIRxl|nU$dCH=)v4Pi)XmkA<-x=d1d*UHQ4tc4ji$|!Bnj@8?^nl z1?Q@_zQJQ)mz*2Nxg^Qp*)0C=tF0rgxgTMzc%Jz?X#C@$l4uzb67c2n5u1c*&29W{ z5szn&WvW>tzpX^@rp6srF?WtyY>pF3Z9mcC16}Z)Hh7ivs4F zmpi3QR6&D`3jsS%i`Xn7m@|p7gk!HvR_45#2MpEKW$h4^0u0U+A+nW9Uk2Z!8m6#^ zewN#f6ASKArWQ_evKizF{Zi$XhSisrW250S7{6xi%M#HYnv1>y3mp@ZY>X^%?n-S# zL(9Oo4?|gQw`A{g58~i*igL2c;D{CY7<+m21g|m4h09=jMyb3v;slNytdopW|MP+< zMsxs)4GuI!2K#0l+^-eR{Buwmoc~6@^g=Y}ctOPeVh1kd9$o|U&@J$r7Rq+$XN}0K z3St(`Hj>dBxVg7vU+j{u_{&{%z9B&L9@)+_WNMd9B4My6BT2rh(BS$awtSc1aM_Q6 zfc_}cotJd@r=ljwkpGZ8^)G?JS>5dQuar(Elg#hlMK6mmEPSYc;F?Imf0WjDbxDyQ z1-L3wfAY*4*ZR4}4kK=1&6AB*C+Ei)|QHumQt&%*BhrG+!ne=ZIh#bX2U;s$UEnxC{ zNrqm37X&@65ciMkxKNk?3a_F@I}WOWyB^cT7<+NNPSNWNaOg!$l21e4!8$5gF($Jh zzpADFO=1=s{gY{~Myn<=b$-`)B{y`{9-MtutxsAb;ZwPL)^YT3DO|6(Hh;nXU0weW zG$QPp_WhEkpIXdcoYNLJ8h`VM-ZV>c+ z+e_ICtRH&0Rh>7o{gaI%Ezwsw#<8}0jDuyfO>9Ts%Y}vSb$GA(+F?lcX&u2g=0xIN zyCM`fiA8rwBGbgM!*Jq_MOXi@3Y?nQhPwp~tFO26V)H@FHInfqhs!qw8#TIveZcs9YFPg|pZNdgUJ89X-wCI?lMz=PN0Feenr{}Z zY;_d_JwKaO#-6de)<(nPOHx6Rcg>(Bw>Dyh>6JrXADjFyj_b{^17}4=oadfc2db3a z$in0PGkq^NT`$6q=VXL2ffDz?rWU6|iMoWOlOVb@ZJc?&SD=g$2|GP4WHD&e!v4;f zr3Tp^utSiYC2b4brM*028xOVX7~6U4oGyOQv3kYeO^`IWIkE(=n}f|NoW<9h8!N`f zh~BH7ZD(6wK%M0s7&vieMJ6zg<|89Ge)A%m#AY7rwP{wiG{nUscIIwMGkvjN?f|Uz z<-VRiWYbvP?Osz(@w^m&JtestW~WQ=>XLkl7v92ltKgH!VW8KdUBBYml-UTkM}6r! zvAY#0-aD93%4N1gn26b#pMI&HsPqv*#&ql*sNLyu0q zulRDZAVJG37))JshslnVqdIIO_po%l)rV~*>N`Q;M?=3o6l57i-_C3h@Pl&iRIe>b zXcdU7QOKP;#QowMa4?}1pX$X#M~w^Gc#mwh8w~R?_C}fz@FV(HL-#YVM-BZ;ub9jO z$egpV-k^peMgrk*0+!1eHY(C$|A!$z&oRXC20K5-Ug7L>=W%4hyo;$3cUuZgRB3I` zjanH@UOIorbYFkoNCYc?HT^P+K|Ok4OBdBCd8YH9`UJy8QUJ-+hyRv7glDoGTc1d7 zlw1jPAZRJw-xrK3JLUf9G|ul_`|C%vQz@Y&AvI~B6KgI5009P;K8hUj%thJ_t`!qi@*Ov zu1-ORj(ug~fH5k?27c7xdgtzJ9CMWcSC4!*hYiV>ebBY^AKat)|YZk-`zx;#SWg6L&o_{V6? zG&1zx&$b30m5=?^t>&`b;p#pt`+%jx&zEcyiK*EX{o1d*GM9CFOh9XWj9Cte;v~vo zeDAU~a(>fNl;;$xQ8nJ!*kR{>d;F)Lc+@1Y)5T!^ zaum>c>|mwW%c`hNgA9T*yF!y5Zz|kX-O_>Oo7r059L;OfLl`c07gGzTuV$9|H7P?wOVYs4=px58c<(W8C|yfz0e$jAWgcB~aL@!2vC z{y23dh`dREA-6#vb~qgD?OV#_NwsJmFE8q@`d{j6t7Gc#@-LIX8qM?xj(%50)c&pkP63e7^Q7!yh;8OmCF})Uo zR%iTjj-8W0+n4*Ci2e`$)16ZSZnCvInf_PfH8~0o_&pDAfz>ewZ!UvsXp<@hS4E@~-wGjt&G3|R}b9q!0$uY!pZ7+AmF?Q& z!xsSatRjcY&GzXrO{35x&OL*a;!Z?Yf^Npn8>E2I3eijZ+kBVPTK?In@++;Vv-~q3 zLkx5ZQQK|SJV6c$6^YS02k(5bHvoaLaWRde_ zkKd>0B8I(ntPNGHhdRG1xvQa45h%AW7uZ+`VI32s@o@=$2iB!#<88IejFm{B))tWD zIM|rH-0^r*OJMFf6ao@(00s@+&N*KW601=xw5nq?5o6K#Y))7^EYtvT(d67PSgQy!a^Y%6dmxAT=Z!}R4McAZ zDpV}mygqPGt+?%0!A2lW8%U2b44J|<%qDoSj#Sr|C$c{{d6B?+y`)5cfl1oyLkPrzfiASV-p0JIH&&I>qPS7b;%ZmM z(?7xwhwRm5^#=c9ro^@!S~HxnmYZFB0a}l6RwhztC_0<4RCNHL`bT9cJParF6|fTT z7Bl3JyfChH&YgwuIzEPk*PT7AwLcd%Ynj;4upjDMU5BH?2&9kBMA5euS zM+sZ|HTZ7#;*~KL`6=|vNMAw{8F!y0NSEMfGwMkegAD3=iij3|7owAQ1o>R%^3{0* z4E`7tYy|wYIFolct=>P(T|1(uP?3Z>s`Vzi;CV)UJPfS}{ZrWFDTB>-@#?+p&qT6u zb0%J9q98#V7s8KNFFqOyTLEqwoZ|Crd*bCc0CANgIQTS#?hQM_BIN+)vf*y>aq?Bq zbQDsVZ#4u%@Pl)0%!{P^87EM3ivLDK(JT|}5n9s%&-CFLSuQBLCSwRM?=8LKucWqVYe8XiJe5{XiNq-*}NIfyUti#iqfQ7}gvj+&c^?F%*bM1{mF?uD1^zY3{-Krw0hj6AGR zxWwH`I2>OltKiutwYo^UftKvaa~vlJCr4x|v7z`-MVWI%BF7T|v{Z$tS4?O&(Y|xI zFmJYK`flE{!xB8&GxeiZ)3-J7%JTJ%v!u`yL=C zn#uEj>i-v#VW^(p(sGjxcG?!W7N#1aT0Y_ZaiZ?b)dW(E^`tP)L6SFW_X=-Z))BtQIuoKcPwrb9JDf)7OyemLKEV#JP;Zsc98xnhf2#ayaq~F0en?xXnR7TGl_*P>eV>h4 zPAut&#|DiWPu}K`Z-5;PMf*0^*`es9@0Hjz!8&1t`CTmz1-Bkw0xctCF463~HNT*2 zxaBp114j;j!BQ-y)Y{6{xcnesforlw(3 zagXqle~jw-&}C@p7{KSFvb^!x!o@{#0N;@nx$&7zLmwCVG9Yu&99BkRZQ# z>dVO`KbE%WHwxw`8!T-udh}o#_XpnzHysEX^ArRYw$d%{scdeJq`gmyOE-Ri=tOl z-f#DDuj1L1>nQ6G|L5y7zTR7=?uWIrO4sokD$)htM5A0_@{Ai*LmZ_cZg4y698n6w zagO*2P!gRqbz9v@(Sn3fTqRX;}#`jQ>=}RR?EQzbQ(Znt_(kkAN zSI-<#S^WLh2+~x=xU zz4x~=W38aJBugmAdpZNO##;>>vEt!3;+HIZ*Pe~eU)HxNOewrq8ZH9Qy=&gRV8lX{ zQJn>BZr{psSE-A~UIZt;2;d}R+eX4vfm1Hyy-~9(DBRi1XEq0h$}!b#8>4j;gQ>aDvOF(z(OpeXWj0d2r!l|gQFU@fEwU8J&Mr=d!S!js_r=r)s+bNE_c z0XQz`&6#5J^Ts!^n2mgKjTjtubsHaNgY=!yAupN2vN=%r=K)Wmj|&qy|LK+;C(7^@ z>IJhp=;xLniogY3Pg#WvOH5~${nd@hyuS~xzNPq#b|yEHGE&biUT@qd8-E*DW7L$()*kt?aaVQj3KAgY3PB+kjSYybjxQN!kzMSRO%bvX%eNH<)pMIOl0EwJq`-u!$`7S5 zVqp(~;SOqYe{OPh9H%b{qB`LMkDD2qb)B1thFe zZC(`9spl#aM28RKc_o5P6# z;>gM_@quJ9n&!X-MYHc%n*(SgfZ<{3E^3UV_9~dtad!!(ySrrYX-L@{N z60r>36~G@M=ugWMCvo&MNVuAP5A+kyyqImv%<|7uUBKFK+7REXNUMGnA-_|td2^|k z(-w=VbJwY??l&TB@m#qYe~BC!m2Q4@=ZM@N=u0roP_7gup>Tp=jAxDe*mP ziR%vW+NQY@1*P21maj;zeptlvU-{kVLp`5k!7K)IiJe;cbdsR zh$^>N%i91EBzL}Z=+R5|#$sWsy^6;IYtZR1vp>)S=YxUd*UGnx;gj@v6(GC$26q*# z!AQlHE0;yE@+OGJJv?Wg^U&BxAM6qbAl1+0G0hm-&tu&i^CUtp7D%>JYmBxRA<2QA zl(bKh-UoZd*AH${Jm2#Y;14){_@*LcAjMH8CKA>Vc{EN zE2xS7jM-PrR`xh4@;Ksg&DBL*%Eirh>?oi*x|CC6ZWf#P#{3%n-wweDX{0YJa}*E@X%(FGW8$#omlhLAF6+MQld&_)3SRjnz%^zjt?T<%u&q;acTKrr^gPngq*K+_>CIKv z)Z5}sDx%i?T-x<$R~fUd=U z!NFv%eb*1M*O%In0h6#tPlnwJNh2ZJF}w%m%C@6{+x^dA9mNV&{H{fpHGX!%p=!@C*i9easVa^XJUuP@QpJK4_=WPVjMT8|WXC)s%_eU@rk=dJa1)RyiRY!MtU1Tynd<3GWma#P93$Sv0m(|&Jh&~~$d^mlw(=y=XpJn| z{%2g23O*}D?~;$>ZiRE>lJlWANV4h9_~Ip7^E80t`i5@qHb3t)O1)I+y4dfLvz6~o zvEih;DeWZtOT8BGN4GP%a-?KdE2WmW>+9CD$$F*hIn}IR;?va)_g zAh$dlPWI%1MziqY_cre_;Mb6^1NYI>EtygZ?>8@9gKvRsXouz>OhMN#0F8v&1wU8J z*Oj98Z-UL%nFt0IFn6l$uM%`EL4(n%+7DBhEAV*ZlmBzx@?GQ@rl{9p=a1zSHM9+_L|v>*E#1c3Gr% zM_g=|-szO;klxc^Lc{7)Igg|2u@E_}kcDVhU!r3d>%iJVGDqIPVBTfUs#n(vg8&OS zwkshC(Dt&4)&=*9yb2bS)wDNzeHPIkY$U&6sgtnlnTNw^bjo^vTT)cHu}P3Tcl|HX z@Zw{6n_VXMn2?=hWY{?$E?=-ckD5o3(P0d{0O#A?S3Aa}yh`8EjIE2Z!_@R4l|hb;Og#Nj z?6^UU0lEn(ChgQYW{?U4Aq8ap^R_jmb{eL$K!agT#k}~Tk3uQ+#T$d(p@NROJ7T^9 znQ_{!o$L?)0ey@`d>LFvGC+|ZDa83LEAsGF5Wk_6vvBL+lqd zh!@(rB|o^=Km4ZrXF^y{K(D>yjHR=R9-=?yY9gv8!j36Y_gdk6eWn!_g;(Ee$4G24 z7S=W4M)aNK`z2U)zCu2(yHUu6=|FrB|9~bt@^b3YJ)ilCR! z_cV;7?i-D1U2E0!!GuG2%*S~1jzf$Yp$i-W*`#omH}RRWnn$BHwehU#>$W}2F=I3{ ze|EMBc?D-{s}JD9n2VXI7r0$zc@!7p34=GcB?{&mR)slLW31o&DwGUtMUGM;l=Fhc zB=oqPuB`w}8;uT5>edFiK|GVc4@uQpnDQ8@0FzcuwJte9{8LcHOT#_MyUeuQYQCP$ z?apuj^#>7Y_%IE7Y^x2!Xpdx*LRqOef(Z-M7+dcV{~PiMl*UwH@bYHevQ9Eh!fLo| zXXIqWD%dzOc<6<2uIRW7D48QJB4O65#=q`LN?$uh<|3Y!MrxtqSC|tARFi+x=S=&Oq z*4K{KVjwCM&JEzWgiS(+`+y&J*E>JwcbK#7v++jFC!@G#_x)F>pXX>~Uid%5?D&IX z=Pt;;7cIF<7j_(k(;>URy?!x3y_cIMjvlCtw-fr$N6Wr+xVE$U!L*lAV8Bc>F=CR5 zCO3#JSK|>z?kPFQ!MlKKk{7vu^ajy1bCwbAxf0dzh)Ssz^j1nPPN3_5KYPu@Z>31I zyb&Yw568nK&d^n|+>6TtKF!$nC~=RL_0EiP z-1Y~`b+Pv+m#_)o+D5j1sekqaQ3fr+YuQj>@r&I>M#(jc?x% zSi8XEk2^@8!pq!Ww!-wRo}ricVVTE#QYMO+Q6mS0$w3|Z{@ zi(=%H1j}UbNUP6B(k_%{k(KMyp&!VNI;#pR8JZs=AGlCOfY#H3!ya$zIg)?TT_sy} z4y45{cbf__-U@8R?9TlyCZU{V$WmUgvbDt+GV*N?I`+OMVbkd1GAZ3u7V$as2*e8AXlmR0f<2lt!ml@F zq?lx~P7}Iz($)JNOg7Gi5lR)~&9IROH|&t7UBJ`?7tb1RjYOl=cX5Jk>;_6b2|xc;nb{I-NJ4RApZN4QH_Z!H-rm1F{bh|PN+)V24CWGqIbyI`Yz-8$p}T| zQ2?dVb#EAL`>{%Tz-yq)VM7mQ^K~(+!l$zp#&=TCg*OOh12b z%i!`b{oyC+aw8+O`}akpatU6otdj4xw(@m4%SzeEaDxX{1dXD-YeIY2{mJRh53OW;BkxrnkF zY1#hduWw=*VY?e6>9|auYyM(!FYYe}PD=`yzsV}+9-KI}E`A_0C>ZH9J}zd9y@#FC zkrA+;IE-?5=E%2QTDJ8nV);?8z&R(9AVbUT%{`Rd9?=_0*TXN6J$|j1ZP$14w8txpavO^MbhftSaQ4W#0Zcm{G}pbW{9Go48sfijC{Xy-ZY^zJv zPU$t;pm0MRhZ)fumBe5$fQB|;nWQ)wFQsbkcbnAYpQ4FzSxcr9(%LdXO)F%F+ZkKM zx)%4pJe``QMQ%t)l1fS-pOkj4#7AYkucX0|)ps+SYY%vB_q+nF$8zp>7PWLZ=d_JD zoX0mD;3vs6{w{jkjl{`HWJuO}$9xfa9b5%iGsp^KjIj-JUKtQqiEt(@s$BnVw4q2= z&Xq&A41U+!>cZN3*Tbm1KrVSh>`MEsV-YKE>|PA&Nom{Ufn#CdlZlWX~{kBU?OftP9WcpyGNEa()t*m0=w;pF81c#%}kHn}-8>%(!)gL&n~> zRzwpbPiaXmk>qozAa*)UyCx&bn3b!0*V%R&aTneG9@UO-M%!_+;t|zydUy^ejldI6 z(7*wLeJtVwQu4g4xP~DO1p=u~JLvuu_~LL%-lfVLaYH2kns<-(6yZ^e*NC47(QY)a zEZYAl%J6#IJGZ<0@QXZ)YYoNY-V@A953JQB3?=3PFFrK$u?p8t3fVpvpq1oX7`Mwq zoQzPHkBFxA)~fg05lq~b2bB&FsQW=6cl-E6>8?jP1C~WjDI1Ts4cI;&Au4wfD;CqgxGmfK6hyiDUTQ)7YA0(_;6456k8_C2ZmWp8=RvcFVt zx!28|PmDfApxiVzGD~Bj-@Xf8fAu+1~Z0><#R+lRihgB1M zQ#c1cI&o;c(HbsyEpu_EutAypYpKkf>o(T8m+~!Z3K;oiH;1_#o+z4#9*0=QjgcCO zuYUJ-TQPA*goBl@{b(17z3d3YTqXfB9y_XS(RnKKG)4{dH*D)(^=aW-{bcvM^vX^%INqXT4<;&Ct(AM|*G``MwC*FS6Y%qOu;`;%wF zSg%>D@A{TkrTtj6Ni}A~_JZX}Jx=U~E|$-l7%GicwP;eN;H^^%tbrO`z}VP;R3WEn zjE_^}g$uDElLUHlM=Z5JZA!2-jO-g#d+%NjUw0=dyBoC-&UzAm6CKpBO2b*BfG-Yb z?9a~hONu=eF^Jjh84BI6igUNp-*9&twRsb5JzNwCxj6Aiws=lfoKzG~a+{t>#Rs!6 zgHl}4WcFD#xW!Q0PiNL7)YFbhTac^Du_|zYa|9!Hc#&%D6{~b>;OI+dhZDpWLpfEL z-29o4AcLkk&=d(~_s?CjqPN_;m7#q2*6j z4bj1^5Xn{At#YA(j&lTp3T^ZwI?)7?TJPb&P6JK8Ghi-(0hnOZiESl#D>I2n@(LxN zu~{utBg$f!YudTM(*-mtCoRD*P=^70m@8?0@rSb1okUvRLZ>6ajeibDl_1H&wyxT* zc0|0hGdz2Gj}DYI1~U+r2f138>5NVN+dWntQFG4onG(R>S<05@bPw5v#5tGn`?>p7 zg4I8ESl=ToF{;fM8eT*6GlIsby$Z1(k)WgQBTL%&R>g>c2(96!H8O^aZOCyC!Ahma zkwf=71`e0!k28i)QX^AA+Yr0D)Cf_F3i(crkj`kHSB!R(tPCy7OCREiI9tY!r$@UW zexA>o{H{I_iJ4npjLWNHWIkkLKkcs(7$bj%{utzbGVi2Stv(do6h;|_W>x=F0zpiG z-UW^X&B#bMZGtT0UbW_n$I{b-GYuupy0>Lco@zd7hb7kgRErl$nM>DN&ussS=gf z7K*y*6m{#<#p2Iv_5FJ}{%fEq=WKJjVXI(s!~rBOPE;-U^sd!M>x?0~Oz+QQyoCX+ zcv0-)Bp0E`=$wnc!YqbdhO%GAg)r3}6y@Q8bG(3ONiFouH$-gmwf;fWpoXI#J;>f` zKShq)tNKsdsLI{YLAQ2xF9S$V_(x}w!%!S;uZq`4bB@+y*z=P$l6|=8}mb>W7mGa zty%8AI8H@0ku1bd2v>zukUcUA14L{>^SB*1SQ~C&oBs|L@j_GTbrzaqZJgYVAN^V( z6%RL#&9xsVik2krUA*n0b9$;St%)){5d2m`M|Y@dmbYmPZFpHvNAS6vRLah9-EbaL zxGSn$k@+F<7l%BK;>47}zmW*DaG|)a8$h#s33c7s#LTc+r$GVqP|$LEvv%VQtIm2h zw@GyfT&D1mci)<9;9N~-6w`(OG)X7S>@*{und?O!lvzax#6kI_QT#->no@z0p$MKsPSd8Kb>9aLr?)_{v#t)S9Tv6NF;bwu@re-tirHg_ZZOk6RN)p^Rz->i zlRSHGk@B38DWFl&}$%mE|tQ) ze7bY{rim;TnG@u!VmhSbRDzKn@`;HxyKH;{AmO*{&1RTRHM9KBL?)mR3Pq*F7(*-j zAe7o)kD-!MyB%tqsU0+L{Nbn1;so?oyv^~tG1OJ*+J!4_iWk%L3|fW-gP5M6+;(?yAjB9K>>xX>{Qt(&H1l+OF{86r$$vjUfZ zM{PF>AaFF?U>5$OO9joO_VYNih2oq@MKzWE&t{D>+tK(*&ARnv4q zdKDTWB!d5-a+t0Z^$#n$Y6o_r4VyoR(~_UiiR0Vzc}qvK?JTDzCBXQ5Q6I%L$;K3P4+ z)akD$u5vFi%*MJ$O_P`}(|(*On&^e_ftcg~;)jg2GKqy4%My>}B28Q3z+uM+yiZu2 z8r&u;$@z{{kW#;bW`m!eY_djD6E=SggduC5W0{N(eG!ktg#Y(lxKOcY5 zCBkIL*m7A)l5V-UG(`+*qC%6>--GF^>?BTOj^%t9c182(go5B4b&gVIq;-rh;g7o!R;?r;nc=Az-N2|OC6OkD3T%pm8z;6r=;*@ z|GmKN2)dBGF3iGbZkP3--@hVz2@|Be(&+{rtLZ?!g+m}ziTBUPk7lglzWchR+2oTD&hqKC|^2+#X(fZRt%(w%o)jQA%Mw&sHG%f zD$SE_Shj@-!URukcPS;5JclxAdy}%Bf|>W5Xm6MpsC{{sePF*sT=y78%=JX0(ctUx zWAs^2(G5|u_2uHMU~9D>H($^;-o({A+JRxh*GKY+=#<;5;T7JPZEdU`)pPYL0U~HkaH8(*p|6OAZ*^B} zG%@N;l;yYKD{oM~(T5)YhOfn@(RA!B6(*k;2$r>XWWir4S9D-zPWmA0maIM)bT8M1tkz z`GDnk>%&mJ!@A&DXVg#66EWzX$NhtT8(%#r<61erMdOqxK_oZq6bX8G4$6oxLJ4!K zPZC`GxRHLhN6x=Y`^-Z}Sa4cON-F%}^zfI}hp$^lGP=N-xummiNIB2b!aW1=bFMuDt4$mE<<*N(-P&yN5PpuZo0eP zy+YBV&nL-|9&r=*=8nYATu)QWcmTFp?LdUZ^gXexbD<+nsUf((FZGrrdYz!{{{XQ- zPQP1dZjb-^ComyWPWpZd9nr*y>0+Aksa@Gf>4bW4dSTaD>U-s*8-Fy;x#)1LTe-l5 zpS$@Y{NT%%;FACQfT3OS=pXRAg~#KZPbQx=ZA9_S8%^7sgs*?sj@gJgmnU!H`poa| z!hzp90;3okK<{1SRT?9J+%L2(!SJFxh^}^&+PsVl!0Ekql<(?0&J96h@}{=Qku#g* zO%!a<;1+D$K()**GpB=P+K|gn?Uzl@^*fhOY8Oc^8s}?s7o>J~$w=?*E9E1}t0B9i zG@mq|NOkkg8xqR!D>EjfcBA}IB7Z9-hmN^qanbexc-y8Az}T1`T}R&__2-T27-N)q z(Rk_QBR-M%a_wTsVs@cw_K5U=#u5y`2fGZl$EF6G3B!jK>Nq8 zRCdO@EPdH}OZQS9u5OZSzHtV$-OiM)gD(vzZqV00so}7i)h81m3P)jqn zH<$qd^*|cLbuj>VMQx)<3f=HUSF0XfRIqE#knj@fMT6nmJYWFUFI}IMXBDCbO*Yrv z4>}0DG-YaW*aqVM|1a{GY`S(-~T-xeQ)x>B=;4^);Dm&FaLxM@BWbqzJ2rJ zhrlLoyB*g5;R$p9>c-u%O_QtK3f8UL5Y^F1)J0I_K5M^{v#ToRF6JA6=Aql;egE@Q z6MNET^xKxv=Hkp>;48mN;y?fWZ(;hFW^8;kp?~i`NSO@{PMuT3x5MG@8jZE77!5sRO*rg3$!9>v^{{Vf zY@Bs1uAFx`&fJ%NwlJ~Nn@&3wpO5}BRNlA>U)GV07?V{*W6g_~nI0(cB7RQuamIJYh~u%s#TCj*RCpMs7uP?Gc~UI1Mc-_kq4j4UK1wt zwL@L}o3^yKJjp!MRiG^QJ<5bzR8gKhG?w0X1+ISX856qu%=aTc=Bd{thf|lVz6(Rt!GgGX&{!h4=@BBuZ2qDW8QX~Oqi zaW$TM=5BoM{Z)yvHhSK$>dxc?)1Q9j>-g12cQH1j#=i*@w%yv?4Y_SGR#bqIjrpmR zYfDukUNLnqvyPC)KBrewJ~}2{I!oy}o-_|vJ|~-E`6TmCgL3PL6z0m)C1l~+kM@Jl z&H-}Y`RWcKj5_3m5JzRO!}Wl(V{pXLc%N>$cyf6-J$C7-loyceCfRGBPS|0Z4{+;d zfDbM$FAK?1O0g1&)g_5c1jS(v{v*S$wlH zhcccB^~5BPkKTjG~G;CDY&nS2OLP6m1~eNzYJ;nNQ-!jUCB0aJ&HCP2uzfgkF2{L7=1QV9JtY15=0m%u$K zVuwag7?0I6=VKLiF|i{wN0&;WBr7h3i)n**c|Sh4|LOStC2LH$b>Cy6huf{@e*O)= z#Glr^8$Wu-<|fP?u^PPRad^kYXPf(<|9Kaj_kleyruw|U73v1$%a)4W%FRHS}+eQCM9o* z+97H=`}+173d(^EMn{!do?0u=L@3F*7}^wO^r}sLNNc!rGQ0COmlP zWbAX|yYcjm7ntzt%PQD+cw;F)DbIMYx$OM@&td=1eh-(dNj7WuJ*H%SoxE9p@uCKd z95V>n5xCYRGjZp`1F-8C#&d;2UbS$JK^?VHbq;j4t8oz z+IY=NSK>S8KZirkJIjQR+T6#eo3J`L`h4Yg&&RWeoQJcIOy;8jsz_&O4nEiDWlT3v zf!%Y+))DJozX=y#k%W%_&JJddt1M35%yrMK0oZ@x9kC2etlx^jz53r>f5#?*lW5BuC-P6lHF>Zi0QFk#7j|F)=*iLpN=yf zoV;}X=rTFfOI1ReO8?aYO@1xNAJ{^buC{)xU28H*a=YqpP+5!@?oI4X^R#_1Wk>~! zp1;?GXAPK!8B+%3!uw1a0@@ancTElt&3fQTteJiw{_Bk7hq3?o+eLV8n>IfHz}8&shDUy3s6TSk?pU~H1I9!&F^Y6QH#EQa z+98J5XvQJrR^eP*+U@DKsT%8-Ei!j&hK#}R^zEc^{#DOEjHmSENKcdcAAa7|IM99- zsosD`fAL}5xckpd@N0*R#@fXT(J(T3)8L?Z+_o;k%sU@8;Q_mTq52jvP9NDZCDgMp zZkc>#yamp)aOI)&)V@eMqQScszI6{5$K{dw*q7fGSC+SiTgSNeQcM}#N?Ni-0PnK7 z^10+HBfDgyIC~)JG^a08evZGS$8g9d@pP31M_k#lYx8!sk5o51Z<+DQ+vETqKFx0n zAIa)US|V8xCD7>5!JUW=8#b7?X)Ry2T%?KLtTk}cfmM3iAAo;k(g`Lml=St%iLXvr>@_@)IwW${9rG9ahZ^ub`#kIFhCzT07PVU}Eufb1; zuKe5*K{@yD@tmyX$X%{8st z_X@l{@=>wC0ohybm^cJcF85#lWY!2X!*HGE`brqeCHzzfHX`RP=e)j8DB!` zRqlWQ4%9Gom>zW~GXu>Gjm`lXSc-}6ywY-it~s;A3YQ$I0#aM1x!H!$In#wK0cm%r z>V0;#=OS&*(28SFye;r^OMt4{w@2q(`Bmx2&V%{fR$I$#_n}Q!e%k}%(z5({uf=U8 zIPs&BjSi z?h}c%eN0(L?D9F?kz6&NqbsIZCoi-=e?5B^^+SmK5U)Dw~NYVd8XJb5`jAbE62UY;&0@U16as+$(#Xg*3;7Pifo z;(huejU!HWAn*2R2M?PM$D?eYQ*d%gbR0il*-GG}7#V1NG$WJ5kIUz46HfMe=K9V< z*O%BcL3>ED=8`3sMk}NB3J$u^ADxGCGfY!C2At~$CY?(Q2(9yRXt zja#xCm4%gXb=AN%bU1o=(z)4Ny0_(qM|PhxFL@1IK9?Eb%BAuvMs5nOeWf;(+K7gA zNjYg5u0C~{Z>bN;mRnX9F0E|+Xurc#wuU^?r84RPT>z^RvVoy>>4a3KO9k%mJ;}ekel1qmmGiO(9ev+(`PP*E`We21&LgjVQ(6C!)WNSv}8hM7Wc+j7X zgJvbP*&DU8cv&1$>}>Prb})llsA!85SmJzqA#TjPIPUp4nP{_|cec>NK4^0&ho^P0a;)8=QcH~AZS(dyB=sn;2 z29BNnP8@mVPfYkTr~e0I(2Sjrm|?=Z%wYtpdkjWIl{d}ZWnX+JuCYHsH~1)g>u+ab z?@uIeMtkM_AK+8}H3FMd-ZJ6klir21zqm{7?J&C@hYyW87hnG51130SbOV~V+68+} zoXeJc)F@!hBY(hW&QIQ4F?7PFXk4}c4bwkk!se57wxng$)xICH8$Ni(ez@mLxB4^M zW3Q6DspHP`zlOig8H!DZC((-+DeV5fb8-4E&G372b{d`ZIVZq1_}c)f6`y|7}8d|zlNm!rK0{q)L-Y|^qtdJ`BiAfftY&4AsBeuLKAx1 zKBGz$Yt^KA3QqXcA^5K!{=ozv+T;IW`mpYI?DV{w%=Mp-?S_+2pI9&p&`Eu7``P#K z@7LF1@%+^$Jo%W<bdi`7vP>*jhOlA`%L)fY4(PR?>5)-|L=p?t`Xe~ zjU{*e*4+K-o>^#o^wYTSXI650pZ~fEpD?-6wBzE3{$SMLTNjMO4Of2z&;0d^CjF=PRWN4kFzChejh3w4 z@|`&Q|Lubz)yA)2?#=(i%&8|EKA)Y`0BOxGfp|X7by7^=T6-1vDvQ>#ANJ?0?W?_1 zD!g?|kd0bH$udeSH_l_#LVarG*`GKp8an$2rp2{m5!^}=@XKcImp+6)d^>q_jEry)b-8BV6n40-6S3F!^+0b4xnNn+9S~%YZ7Aj4qR{IetTGMuX%n6|_Ig z$l|l0bP8Ji^xw?&OFz30l`&&6tdhJ5bpF~c@Q$zlzp4k;IB*aK!!EB017nc~ByZvz zG_Vn~uR9-K`)lG@4UH#~XcAGoz0ZWtJ!2O%quh7`cwGj$m-O4mvrM{s|AdeC*$aLI zxtFJ$%!<%SZi&s0yN4r>G&Wsw`pQ-ezbxLTw;WF;l;P?lKz8Az{*rhpMh=%QO5QC{ zY*#?`gt;*RCXWxCE#}IR?2nW$OQ(?fAMlS&j*gQ*psU~-*>)U9Pt&a(^u6ym?i+>C^X0ZmI>Zz&$@W9oJ7g-$Z}w$T5iwoQ)|6YbDZe8FAMfG&;hNwXRu) zWvi1@6U{@1W7xp>L0}S|bLAIt&fE{-g3s=5!h?I6z06u?$&z&KGir32lC+s#eII^& z+GW`8S3fqf$B%D-tzjEhFT=|9jTk(9s0k0uKA)wN?+C73wh|aJ0z;dX>bu@()3M_^csd;&zTzCUWi zf0+Aiqjo%gTmw22t?O1`#hRpkgN6;qz?^8@SdhFxE?-+crw#@uW*bE0_BHgH`*D7x z^D)_Wzxq+<_t*NBSg|_oui?XLW2g_Jz57VU7OznlJR&)b*wXC>ul(rzy|Y%VS+>mR z^_qr37&&|ps0yh{@|n41s~RwT*ud&AsH|BL&21adI5_$2+VDY1gHkU`T8sIX50tLV zdfzUW$`D@{XM52MfzKr<{H{e<9s&L}wX1EUH8fCtO3@ zEnQ>H@|7m8Vc0P9sZPB%`E1Y1hR7cpV26ic_y8r>ea-8*^Y4Ge)ekL5;)f4G^V&!U zHzc2t-sfXy<3rPidDr07{JV6mY(G*yzH+rEF5|g4YSYnCo3b*uuEmPwtFWOl`E=yS z;Vo!Hxp9)KOKb8W+!ZTUL$?ge`6FfO?~9Y#rR;QD^D~pS0C-OXp0eO6kLH7eztnde z9f)P78s{!B3I1lj@Gy4p%0na6;DUIOh2XR0m5+j(4ZWrvEy!{y~^AzxW9 z3_?0rhASVebX}6h$19+F(Cy}2a$nuc6#wU?EIL&zGy4Tw?Mh4VbLU(k?TGV%%23v2 z;>z+ZXl$NR-CX8@@}&GJt{@=G$3&hje4!{StZ0>QL|1|LV? ztW{;HP&lx~HG-rJ0Ra+x#;nacMHRJejFdH8RHx`SGl;ri9C3D!&Ierz+el&<_WkHb zaNp0bH&M?X_b{vqiUC{1M)L>}1nakZmje|yD^dQ1|#Y}U( z?vbtWUtip<#~;#?{HrW2ht`*I?N2W;>GwVVBwpR?bbNSh1Dm5cddNR&Fi@EJRI-IQ zbmYjK3_#KMu*W1M$D++pXdXHOBXe;&P06Oy1`HTB!bA)xS-xsc4}Xmw%o9Xy7~|TX z{ss3w|AcA77;!sFFU0I9G!7hwkprbvm!e9ZndEH&ZqJmXYa?9qh&?6voMlObO1{5d z+v^MyPV~NW(KuizMh-wg32?SJpb>*cj5aE6zlA3^3>uO~8!;?D3>pRvGwsQZY-yg5 zh8Gua=PPRsxb;=`Qef`9c6AA)iZ)dXE&}sa$sB$43-gS;+`LKKhMFsv=>hn1vOULa zEl3Yv>6E5MtE>00c-YtcCy#4aCCHGK+%kMvE?u<@H#Ebtye-M$$>AvKU#^Tno8#aQ zpM!%woTOCNug6B!i~-FJqW(y7(OD_G*8)9-7Vho58vN8zX1s7|g)$mjFnm;tSdLB0 zl~K*pIKbQwwI&ie?zF%Qgcl7Ua}z4NTYdOR)JbeN%I5RhcbGA?1vegX|{=7 ziXasf5YS7&sdA>`w)bMk!%71a=4NCrj|<$el)_ZrGBdEtW3}U49v0=JgnOG;K+i?D zn{(G7q|nw~{y&xeSL3Ki4tq#unx%8Lv zq4!)KpZm|XFG|Sg>%Z(?3FUEe(s-91bD%m16m^p0;pz`c%cZ%-1=V9E@RI68%j4RO z>O1XMJ1tVSUA@}(Hcc(R#ZeJ0)>ezDEZr(G4lAn_ zT#ai#A?F%Q8ejndHaNYZ4nUijfnn^TDZyRw_nm{TA4J*{*C`UY90;*cmBwj{R$E=H zQ2l06!RTw`KIsZ8F1xp%=+cuhIxSyw!f^((Oj^$eoqz54GQOo0(-v@}+3x!G*^qJ) z6n=cey=k%&QT186eV%oB)pSK+(*ykKLlK_vi0mS&F@$%yu^I{Z269{9&$Qxzv1erdKkzoc?iPwr>eP$ur}88JB0qjRTN%gRl2-XEQIrqn9 zVgmwt5hU-6v%8!JNqK?rqW5Jz5Zjxfar8=M;L4MRwklBugfhyQfnX{Es^I1mm(!3B z(_fa+H=0mYQ^e8XhHJ)I`izyd*pg_Z*^&-5pLubWr69MYR329rSB7M^D4oik z}P=S;#{b~-u%bY51>eW#02(uru;^bmaM+d{s=#HEYz<{H_?C{5WZBhy^;@x>0D@p62?A@9c@*0-ygEyJf?FVXG}S#UN3U zB(Iy^`=OY7-H8gE|IrR==a*^Mw*^rf#+ZJ>iBTJV+O%PetQ~Vxc74s%!BBP3NS+a_ zd*$Inyy>Cm4&8J{#-dy zxnROlANk7VY!9WAmIqS5`_?{O-_de7T9+;>PZ$olxcbmEiC39&C0-i5Ed%&+HFzE8 z>YzO3`{b792U;%IcU&7tdZr!ueY)Y&V@~ceC2)Bslm;kz zK6K{hW_4-y1qpLyXh(UHJYdq5P_C5UWuKLU-lmh}=*{R4rmj=x+_G+MCW!5_XR*cn z31zm4QQNjC{z8qGqEot>94=EJ#n}U(9DO;{1A&(E^4)W$iOK>LhcnG5nZ|llhBFnC z3AO2^Hgxe;klR(4q@(7p9y2N}h`78`8@l9nwT&bXN8{qh@u7Kqab?>Fj(eMr6z7_{ zIr)53eOq+|jxss;^ixWcbit()O32UgFGE|e{%J-=YHxh)$&D+ne4lP|?I+pCyv)fR z_qoHoocXvaow7JcCWNkC4r5hn)8k?31ZMBF3)Ivt^Fh${ zTwhXe4OW_+PeaxLpJ&?!aL%6c(B_I9XyV6iy;Ge!9}v(xAgy0G8fi_x$Uu5kmB zA0Aq2w}J99OYPvYfi_&_a{0OOOJylz>)@f2`q|Z8XC0@?w^ z{Keor5SRBx=>Xn~2kP@gD4mN|nu)c82Jo*6Xq+xVYqzHcFFS3^fS!#mHS3bHml-_v zugO5Ji9)(2z8ak@k;`e#yF027CoKr1;qG$9sF`w^2nhMDuca9 z0g7@;J;#}2S_W61&op!WAk~FVB{bb<#_ckxe3aI8b?KLDYVpy!z_lZtHaQt-n@Edb zmp)LPq5J_^4&M~W>6sGpyUOQy+4;C7kFWh*GH_nIq@TVz0&ZE#xF&$yhX6zyLHTKq z3}wcq)c0JyrLmZA*Zd)1dQhwO77zJNjY&Zowa*>K8B{)8r6Cg26Dib?7Y>prTlj#0 z`XCM3HtCXUR&GDc%a_p6YOeE)yJ!q?_LTZWzIm-H;j`zR%U|dIwS9i`pHBW_+gat4 z-s{|F7}FNE@44?LQvY|5AYKP<>xT0oYJ}$JhnJ4h4;;4!A}b4L*Ulg_Rx{i0e-~W z`6(}(59OhSIGRQoY4C~FDH?gXYys@)+diO`a}vu6+SncO~6}AQR2Q zm8%@QXdk-Dl=Q_#?~9jgfFvtQ&~xokFSs#m*I&|oiI-3Bx&DGsmNb63aYM_Kbl$~V z%A*AS+*ow!6$m|zv&$<(*MHHSt-$rV4VT5__}KaEtIsOhWd*oU?kgO{7mQ?RpoIC( zk%oTgn1EgYIumlcUyTEy8B>zc^WUD=)s-@R*Cwa9n2sM#{o8gp0Voqw;P~p-g$D7M5Em*jPq$Ib? zt&)apJqt5VPEI!3!&DBJ{E`XRkWD=;)8@&^&&At(I5W@51`jU^X;D-UUpq|OKT5d=Qa=MSPdXNwZy+i%h`*;UQ<(l=~X zi&WL3i}MolX&MlHA?>Rhc(arpCbkb1XOuNhLRaJL9}(5oq8SbE6WOwH^3nbV6ZYwo z63Q#X%a%i$p|nsI9CS3^}pqcTf$V0h9t=JMI)yKI35uPZb^*N#+oUA6=ajbv9Lgk3UnZQ&YQQkvw( zxpWqg$C1z0K**=sknXCB_RvcCXdInKe6~WPTwPqcz}3rVyD0yFwzh(jdq(x!(FF<7`j9o@m^X2a#)M&a5^-lX(Aw?hrwrK0JkSw#&hy{B4waG zu!=IjWkBYcGWI{OK%H%wIf^ zC55Yea|4d)K}GLvL3Ggw+Ib`ec2zVWfPxz^(qL;7q#31cun%x>b4Q)rP~hO2SUL#G zEkR+pb2hXmK$>4D4OKD8AL0BG2((~m+oEMOUtKcVMD`P3t>wuyOV1@LUr8N+q$fCW zI<|~rnQa-VIbVWvEIJHy=12VwN?S@*`D^!r^CW2+)lqI#(<}8F>yf36ki>;`?{dI9 zx!(f}4bljv!=xtYT<%`susMJ3~$P7(IOELH}M!W*}8FVzI! zK2kg@JBfGYgUC-6*4MQIT3OrWk9I+fo`JhU^AtlBd{S zdD^m|a>7$KEPBbCv)e*3abU{kcyawCwV6auc}X&Jc_e6$4EEKg;bfwJk`8cVl!ML3 zj-z~h?W!2QHmx1+(l1#X;4JbnEu)r||&^0+d%{8ZOm;|XxLPya$&TS3*4raWc)w2F>!$IPkh zyf!W63ws**R0aCfX znI8;2<>jg;wdp?kfZl-)>$iH9jmGQrUtP$lt@xViX@)~_(BxeYmCHkiCBW4pFAt~w zbl7q^IfvI@wo8)Y%w5K*=3F;!p_IvEFKB?`0*5oV)SPg=PumI}TFPHqq`6Eh7=C44 zU|+kI)qa;8oIarhUrw)l3o+WS5^qjU<)PQ$^|9^P2|%4O%}7O$=}&TeQy zHp(+^or;jg8icYqNM%U*s9X}1ryQxjxiTafl_S4TF0Nkyw|%hZlSC$Em1+N4S(YIA zoKk*1vfr+id$M3Z5s2e-E?4qb{V8~jED_GCnKZxy0_uftQub!d&uw+}nV>K;1W8l<{cYxs>F5bpUb) zwmPYdLYbVS(k+{?d{EfwVmfFGJbzc&aQ!24i$UFP?J^9Ou9v@%M{QJzhB){a1 zNp0e~+Vz4^hO0bj#-`I5$46>MuHFDY2BdzaSB;{s(|iEm&(f9Vfxx#+e^HsZe)93K zwy>&WS> z=n9+Gl;`B?P#|t8yoX$|}}D$@F7;rK~I zPI9>b*>p+f1`IFBL}?G7vaTPcfj}>rXqVabElMO=TMTC%QaSL*)~6y9{hjyz68#WqWJ&Y zyUA`g_eDYiNq|5&0!e^y1i9~16cGO+c#Dc4hl1RS{sa$DL_rQwR7B;zZ{!xa@B0!+ z!WFW)@7?~t*YoDRo|>xep7-8vHoNo9Cp**K)zvlK)m7C!^JZN2C0ii%4TY;sS6JY) zha7KCUIe5=cycmwWpsQZ`sCZQ=w^5Fle zfkwE2$dMz4G@-LNoD@S?jA&jJ>@>>u@Qp zvvYgZndpiBVU@mSpJVdPXD;6b<)@$BsdLuV0U;~-&hv%!Kpwx;Fu8)k;B7>$w{C0W~l3qvKv>g}=&}E;rp5nxjZUCv$^|(SC=@`a4@7M_tBD!S6E^llFITg{!irLv%wu`48YWuc`W0BPo@IP7@c; zkXVYNwd*KSM=~c8Br_8-os~l#fFD(wR-U$$M^3387<${xD^Hye)t90qpIPMknv+?o ztB|cfG?7hmfg$`jHz4t$y1=3b$s*K<{{~_M9<~h?b7<%AtP5FGA5jz zaq*DG1y;Ed_;EZXej)wC@u9RK@Qq)HjGRtZe2V;;Ll?>q0$XIs2eslxEXmBp=wyWu z1&-OkI?vLHIdT*sIRtth49-J^SY-j01EX)9sZHG#-%clh+Ch5=TzINWc(ay$tZOS)S|Oty;-Wl`^GclADlp#; z_-Sy*#XGeIkvVeYNF(bU;^IbH=HoB9os|O4*hn;?7cJ4|$dMyQjvP7a19|-#mX^xs zE)BOp;bf`P#**)biF8AN+u&E8cIaNRwFj5r>s$W&x;Z3#qHT3EaQ76V`wl#MQPLba zx()2jAD@wt_8^r&Tg}~7YVf3X;&Tmovx*v3c-qgh!AboL-3R2_b~%n5-4re*_SKU; zbL_C9l>BCsh(<9SD)OjA9hH)T*5xFWZb5Qa;Dct`rTO;sm*l0>kdv(%lR@ci*`!gH z&H>p3(tUZ_7Bzufe}L5Ct^ttcm0W{s>|JB*GUYyfak(l=y0U^J7lq?1X{aXGmKc@BWbUsu@t_TCcP?MuyA3)uJ%KY`e4C=LVxzp z`?Dj^BkZATs&lqRN=s`ba$bzB%5jy`&${eZR&XmLpQ8`4i(H;73P|#eY+--MviJfK zCA2~7heRJzTb%3>5@X4>9l}3Hj;@8`yey)t$0@5qEEU;^?h~IRZQiPnl^x^E`earj z&DnULqrGaOaJDwb?Ah=l5KDxl&N#r&QfUvuOT1eY@t~k?`uLZuGth6n~@RQoI z)2=;>9Nh;&N8J^^&J<`&11$pV{0ynL- zCts0vHTe(7=7F}Y3IC8`mP`d_W_)m&D$0xN0~cS(v`Kws)6nx!xMcOY5xc%!PLC1~ zdL0Vx{?dSV%h{Eta&Y;Y)aT^kTo&a^dHXDii>E#Qu5Bn+pWE~-Li_+$<-LryKT2zeD!mS) zc#QwsS8Lv=rBKOJmIU$LVf$4fbl|jbp_0Pp$l-%aXEHfLm!+zYVoH9!dQKe=+6yi} zXw!wnIrWD2q|+62I;~4J6AoIk`jV%v4w^Y~u|sIQOVZ2967o# zy4n2B7iAra?Ans7;rI+GOkxab=O|dt5a&{5 zE7b0&fI1PQ(y~2l^(Jb+>rU^Bo__Y zyzhS1Y(z2@39&S%}tCzMV9uyEAelk)sw!)1RBpA%S`p z*rp{FPn0sK*-4ahY0i#ud0gNXV&6EP8tH(6J8FR!1X&>Pg+S|y@M$MgXCXx+(kjU2 zEwvXCtLKqUjvU<=-7Ln-O;v|N2mCm%NF&je9@cW)XvmRcRRP@rcP;RJ>v$j?|8eE6 zx~_aJ$YJjt&~iF0UDu!???rI(NT6}PX4<7R-4(e>EI|q9zBISMp^LZT--@!wZ#1dA zO$!N{%1!rVUHaKWdwPXH3+Dho4Y_?s*RqZ?EiMya^8?8T+}B0RbYK|*%5(rtoNr&7 zP0L*y$B)*x>jK$L88xjEA8ENyuSt@hyI#(%NG=9KJFdRxu8^B)+bxCxta5C9#(Q`UB^m^&sr1g}eEy`O3w50^TT993N+6LUZ;~Gm2F1>Zh zOs|pi1QNX@19znT9_7cM*Hxu_UC!sgy=BYLt7I=mNyU`uqyV}^#|J8$SIviX>oP&<@x%0Y!GFKv%a+B25YWX1&B~f;ggC`1X zKR-_AgA~KN;RXB_Eshe7*P^#8CU~b;2eR?eOdbS!f4QxF3=WQvSk3jk_ov`YCCB_ry2fSI@F%h z2qR=wAjz+ZoRp73deAi^hl1RvKIFb3M~+nw-E7|G@m8loWz-+?8N}Ra|BR&(;65J!wpBI>qp}^QCL&be6WI1bJwh8(VsP zQW_39T=|ktaPv;m3r;3}F2@h>CVhsT@2W%V**#mi&u*2+ujoj0uy%KvOYuUKKSvG@ zG(M+BA-Hk}D52oQHL3-Xv(92mHrzh%N>i1y)h^%W;=?Dx<)AXbaqP;V{$30Jff}wS z@$eS&zeaR=f78H_3yf@9o2EnIHW12BlBp&87$r)~RVP~y&L^N`D^!w1T3^7*lhzCX zAMYwh-5fm?vEpg>VvJVd$`cMRR&FLfXIB(d+bNy2BBlaxnx7*Wd3WWg6*SJ^rlLLV zxxg4!9d4t-WqUYTI6A{yTX6u_5NEIKbL9|BdxYY4V?sA8v_oEMLphtu*;`32$(FjJ z3U0*{YFx4mE*I3g+L06}M~)m_AKh%;=J8gSM(JTK8U*CXu?oQz7r8bAi_ihQxE*f} z+L6aC2qd{R()$K94%OhV!?ob>#k`#SoD4a7C~QS=?Vj03P8sA zb&bjmb>S)dj8>vdk8dxqX9&JIDCAs9FY-QyJAV-c+xST;|a27J5 z*tJ8YZA3QCb(BTm9;2qNTnV5)yJmHWp~H%GjWnw=xYbVm`d@?pY+`oqb(hW6ND(wh zpiUi?auph2)dh-8l|`t|IE6Q>q=HU{PWL+(*V$!KJgp(eYIa?2P0?NLLJl7kdzvDl z8wt*^q@>j4Slp)L3=^rFXo#NMG(y{{Ivr(9x)E{%kfT;m=R(UQNTHR>9s#oHP~bO0 zV9Tc}N2k}M4M_IMC7>;s>%u_jLF$FjQ8{foscj}06zwf{O)5YpJFSKMxIVZ3l>%1{ zcmFFUUrOi5k)vxOpQ|~lht3$_k~eGR$gv8-wKL?4(`cC%XkGDDXnS-|z_o@4L(6SO zxMEC>pDRyXL@;?h(NFaR6Pdb3x-fxtP8FIm;1)6*f179Vud-T5Dj+Ja#QHUHxmfO_#fNIpr6+eUN3@t00?T zzwhqJiP9&&Ha zqV?zlTFGz9>*yYkV#@5dqr^9gd`2xtj#@ySTwU~yS_Gek3xKK|s87o#GVuhifTjv4 z=A8P8t~jMb;)|flsWQ&O^S+StD|OJEZUI-El8uorG1AHNDiIpP1cN$m&Z!4fkL!wG z5Ud%2v$;-_-fNyZ`%PQ4Sya@CKA#>Eb5a}0fyRZlAJC}tmFIESstsE~xD5iypq3qx zvXoU3JE6EaHTYHbiEEdL z{*N1Td0*ShN}g7-g*1g{1=7-xTi&|NALYZzDw$c1w~rskpUUDJ7iu0u z`V$Oo$i5HY-(r#4ru;S1W8&fshE{S}9533p+`g5hD^%wsSE!jXju#+b6O~b-<+e?@ zYv%fv(sNrfnz;_zwr?&XLm7lNA;>^^y6V|^%2A)wEgirsWUNB$hVsb5$w42|O1?cy zm-BVv2=Ya$bZe*`fq$ypsR zZ#s~5P2lV=jdQBv${1nEpV0WkWrsTySsZKty+A_0NO>oLa}70%#(pl*&()5n>e@Zh zg-PZ_C5u%_AYD4wBmh!%otQM*C9)t@RC7y;W~8WqPP0DN;43S@rFtq!!woe(m*PN> zye=|Db95D?CJa+<)6oU2Q7BF`RYlp${56uFCDTkpk^lhM)i9S2B4j7c^Bg&P8hq1B z+Vr61c92A;GZ&Og{9Wy53N*AJBrUVcT{eunDDK?O<7^~nKdG&gI*bmM_Oxx+1NiH6 zMHEy9J`UugA6Klc1s)t~wf(v8$dRLS(9KpSx#{RsWYwMq*(oquza?!~~NsEk3w~47d4R`GjG7b39qgzM*cb zVv-+yi;8P0)J%QQ){a$Awgag@vz z-3Otvg3yIP3w0#f#h_YAo8!#CbaIOpV%=DQBy3&K|myt07KJ8sUqbPb+5JbmmX zDqcmCvbY?u<%=Y=Z~R8*k_K8dh5tIfgKR&X#VNU~6I})`M-C30@ya?;Sx^g615?Sk zR?UoDbX~5u!m5t!>ITUqP@ljZvw`CXr%WAUuBf5sE=~({5>1wJ?U11Z;JUo(nU*+c zpW|`MQddxaC`HoK z4{yj7(9kE`5_!;p^ESsygl$W>xS1-b0#Ylmgu_=3qe~+LEeHh2t50sFrNBG59*(>l za&!c!gNgIFSWj|rDj=-_+7E%#-E;Pa^SG{hLI4)Ds8r;?)RtXNJKEm#a2atW@Ki#3 z^xSm~8rgQ5IKFa!>tzctd)^YX7tY(^LZ}a@mvZIEks}9k)6wb3*5SR7Bgd)$*RBwa zt)#fm6$eV?zBXz55NNfK=ZmLl94W#}>TfTfw52(y>UP$}g9P#Oqi$)81 zA#;T5YnN=2PWohpAUl})Tpub&Img>Ra#omwq|bJrNxDhf&zi@L4GmFT^<{nK9@6D| zkiN6gu2bUF6ehE5r{fZpQ_lFohkK@R;vADJbA+-=(YW)4fDxERf5W- zbSs{{`QIjQ$(EnRRwHZpttS_h0Ex+{m%W0k&VI;bkNeKovDFY|eQvnoZp-Hui(+ct zOSj>=$3IRr5uq9D@Af%tJvtgmz3@%kf5UBfVn&;x9=6fW*l&+X7~Ts=_I63YVqe^J z6P{^}V+V!CmLV9k{${4FEjL~ReXZ_U_R3W_`=N0-;_F+Q^k8NHsU4!%zvbZ0w@8&3 z2;~=sf~2MRjayRyd@KsczJQB+GxtQQg2wD;Z^F&bw3gac=(o|HIB05QF`m8YX1u=o zZusn$tDAIrzAt^t9PYW{Lu`29G>nc5mVbg5@4XH8zwlv{954o(?y?uQU1xwvHiXow74tzT;+- z_3=iZ!}jAU+xL3mtGM&}S21$${Y-kwkkTxe{j@pW`0r)d>VU1VdKdY5wqE=m{&Q== z-h3*${;h~$dcm8xuP`5N6oO}&zW$4aAsgaT<_Q;VEmkY*P!Wr#{|C1|(hHwD za4VA*$F*&qIhekB>MhexMNHUsZ|pvKMAT2F`PXrG!4J<&G~d7AgFkCdjUQg}E*`q} zCX;^rsH12+FY=oGb4NU;C+wdmG>8*VbD4zy~Un;VyiV<%KX~qzKKWfxgSrxJ;$Wg zunE|9uiY_aWHjj&bv~RR(!v06J0T{&ZT8Ff_wD!M#gC(zvijs*vG)$^VxZN2Z1ajJ z+P&E36=Cci7bgYnuuy>|j||8j-Nhqxy;z~sOQu`)Ul(FYP6nTs=i1eRe6)@h>PS#b zeU5&)`TNRMXXBx9-@!Mw9AeTdp1T;|x@i(F`SEV1-e5&}0&*n9$)Fu{9B&u0(B{aI zBS((TM*gr?j#UG`J9>(t^##;Yyyc^nVk{|McI`^JVn>jAQl3USZk5`W_<@m$wwK3p zJq%O{Bn9AOzftiGb~*Qs#yG9YUcydS>Xo0hifff_%A_CIiqa-k{zhU+3j4KO zK4qsJlOsn6B;(J~WM-DBa<(RrwjX=C*`KPW7$=B9}seP(bMFQF|eqb~+CO|5ci!@bsXgu6yJ1c91VYriO~d*?w?2kD?w?`OTOBeD!yAgGwArMGG)1kp z&wJUVi+r{@Vt0%w+}JK+&dg`=w;x`Drca-0(x)7>0S1kV>b`LHpD=ub)3D3%(n#vX zc#-zWq+gM;}D`r0XHM8i#27QgZ{l*N# zJKz5U{yi>gYq!+`AJ_5)uT`RE7O~$dD}F1Uzx7V^nX<1*P9E9-x=us;T)cc|bhCcJ zI{Vl5uvVEVa~?O_Yc)*VZgX=wq+jxC?Jo?|yqI6F0jp!&xRxaQrLUR8O&33n0lR*# za81#}HFy2uC%9|vZ{RDR?r+j>-|##9=#%f`*N1Ij(#a%3d3_Sa{6HWS$y+4gpPdx}5^o@k-z1l|DZu24N>lw7fTC8{R`Zr5ne^~@q6j)y< zZh@#R8=i=pDr8a|4Tc@1>-PFI|2zemm>4`0jz*nsm!Y58%=t z{Q?Wm{)tKNRk#^F|Jh4%((k96^t3|{zX)Prag^Dj2Jr*&;RfOQ$AqakFm$< z4TWj>ut{HX!ISvmCHnv~?lS2sKG_nV8aKXBE9!+MFW!nv|8_q%SnX4W-{jqg8m{x6 zi5_0P{N)|6<4SjG8cSzH4~4FT^pHg_;OgI=i0Q{h{r9cOEy*t!E`J+0TzD~VdSwHnt7E^g zC)O)Isl+Wl%1?f3B%W4`Y3%%zrY7g5o^`J|UUb1TSm!glVeg^Q!@@6I{ac(k<5*m9 z_#{K$Qn0@--g!S}Y;}k!pEfMAzkP-@mAOJM!;FV6HR*Hy{$ISmU>i*Mtm|Pdjam0y zXlh^ZbfK?y-y1^~zGzBJUmbHnp`ZFhl(S#No%hYeR$rWE(oyrx1s@z=TN~cI=0ZF% z_L!)D_xS|Zp8aP$e$vqBEB>o;Kj%vVhM zwqIU}CA%Drqjwu;(#>?NmqqjS##f^GKBhQddril^|G3knKbf>EcAwfG3tx-u+l42+ z1)P5zwjS__N#A?X1$bti&tkW|qlaY{y>K;td*XB)d%?F%dUA`h<~#fj%B71^-9o-z z^qe{U)5+)I<2}EL&+H!AoL8><6;7Y=ef;8!6AWE*!R{HGSBOE1_{x6$@%D{T3{pff z4r#VGOA>M`CKTYjr)xLHF6Y*SHVp#v(|Jp0K4^|9`#&=DRcx5H*b`XSwh-L|iNyZpvF*#WXg(6ytDltAZTsaf^D6XGk6g#mK>3CnqD4Vp8I1=K%4|bXEQrx1F92im0$kEjOtIIwev1oYMN%^!9Y6d32MR^0o6_@+v`Q z+8#aELOwMy+<&`WkhXwqT0+~k`&2SR+H+3pgqkfS&~Rpu(`KqCQhUmguOQDl>73Ie zNfv3`xNB9Owvd4yLYk}3={(@RE?QqX>Pp)j%E8wqlTAl?a6CC%!^spf$6UG;AMG|= z<0j2fFmjc=ZEbBvaApEjia0Tvz4Cn<%t{+aT^L6Pc;eCMc`jvm~yxmi6c zDT8Et+z+=C9k=lmLlECQxz9a79B5c|Abwo2sEbRTmPWmKAUK z7CiMtDuC-;Yh}OHtUN@FnsD(Sg+08S{&MjvN25@K{)=5#cg?Owhz_P(1ySv#rDA$M zKb=Pi%MZBPaejuCRy~HMp2M4IA=u-hq8zINYBAN^Mv`k&hN~N&YjUpP-h>0ww#1+2 zX$X#0c`9;tNvh-W+KQp$_|#%EIJ;`gAVE9o*}S=H@$vBSf~OuWmo|tfZ%I~#u>O~H zg7$G|#yvT5tm?>Pq8!yjXSBEZo3(PRTA;zSl(ylDaeQg*sVn9AK--{k7Z4WI+q`T( zH0Fbc7q?)s>*ju`8}|XHFw$a23H7*1!PQepzbUIom3(U!Ep%G za!WH;k4b4;Hp%30W`W}&$qIq5%UnsOiIWu$S$#5arphh@-1{ifIDq8YM|$o8XO>;p zEsbM{3@V^K%Ez^L!;M##G38{o+oa%hJ(MRLw7xRhSDY)SbvVRzee_b_x!O~LtP&KV zbA<*j9g|$Qq$gAc-<+Y>!(AUYj@+E)b=rQoS6h5kBF!y&C{3J~l)v(>t#Y2Ov~Egt z{Ha52y-h3PhWN-`j5JXy!i3S~$YG-{dgHTFwk50|BzxqhCRsj1?%_!73_b7asH@4) z-VAp!O)q;MH{PhR$ImuE(P%a+jp9e;RNu8s@s#bh$3(K@)b`pO%pV=SJ!q$$cEm8( z#kGvZFMw!xH9mCqC{pZO&2|7bLJnlj3y&3lX5KEkv2MsF?}zWr3J(W?zBmPDUH zTcIOw-8T1alYZ=>C-A>{4d}o6I)>-usZ%g!Kyp_19lIHJ9GjH3_5Mf9*`GJtA3Ke1 zgns{Fa}9US+#X*)eLHMe8q|#rKNwFQaSNXLT=ZGYty(yH)E8qXM{iQvZesN2rQP=4 z-5l@#)iF5x9}{uGH#RcqUTrI|bVZvr)Edh^ei08o{DP7HV>JqsKD7yYz4nfw@3+;a z7_ExeAAOc_g(f|n2o6J|-1;D;K9(%0PbPwo`v5*R%}(7FBe*zCcZ@<12n;)_(Ca+UcptT2J zrEY9H(380H(eD5|Ih~f(sCo z)wb1&52Y-q;ky{R6VBcx(a41V_Zsdz_XW(kw+{w`FG%U?a&wmDY zJT}stfBnSIUu@1K}#Z+v7&ce(9nc=`QyY&~$eN$+~X zIY^p^-gxcK-{8g4cRnYNZ{!^Xo%7P>4Yd*6f}%jT^o8h6h#Ity- zHH!PjY`#6VT4!MSO_yyemK6SLxCe#XK~qAxD-FmyZGeBA?0S?}jvP67bhCNVp_j89 zt#3SmhaZdH?E3bH^P&5X#-yG1GU@Hd53K*2qgM8M$AheI*2*8&%F(r9$2xZG%+Tx}Or^+q! zxP8q|h-8kmcCPSMtW~sAf%?H=a&SLI4H|x`P z0E}ESx*+OFSHaz<8xM$y!OnTVAZb0J! zKf{&-eF_xad>OvYzS!|kzr-VNe%YiaZqy6orcTB3^PVv2_YPSXYX^P_(G7=Jj32_0 z9C#r26sguu`mCr}5{=eJ&ogHyTsjv!9=IdcXnVtyU3=<{c;WkJ;?Rwvhhvt$b}KG; zY!_^2KdjaM4(_?|Hk00T%gwPy%e%PyqMJ>6Qlan1G`^01p7=|X{@*TN#LissZD%?%?b2=KImj-L2M1 z4>r5PY>aLeZ?oTy_|q>R!5d$R^l`$w_u!(NCt>OqV+>i-tOsz;5B>_h&mpGXw!=Tc z-M>E_PrSIMq5tMzH^t~)@8X_|qwC*f>J}K&>=Ym=M@Jf_5)x|xVxa6#BP#Iri(5ay zDx>tYO`8uFUR96CTa4M~NUV1587AkF2R6mYJ2FqusOVvY$=j}p>;H8Prj3jq_FV1F zt8nL{J@EAjy^KI@GoQrcdTV@V^-qj^FFpAl7WEy24b~rR==&R!*@)G5`?g6R@Zf1U z|H4P{!AJWT`jd|wZRSYBgy`YYiSOKxR~GDt)mx&6N1u3Rb!>6!_84&b119~#!X5Cb z!u)yhh1JZpOxb_f%Kwap8icLBcAPogO3%V=jC#iN@x67XVytEV)xdSI?vQKoMm!(K zlliC@;o}b$V&v3lJfdsWSp3Sr%<;mPw!<+ekH$6EkcYLTn4MifDogn+ZPTPeOv|p0 z+s*l+k3Yo1)u&=;aiSC-h;3Vlx$}Bq$S2WwzR}u<0jrO}$o`FGrfT3;_}Xz>M$ON< zy}H?5=%*q+{&11$t5_#iES!tE1wUN$!9~P=xZ;C*VdH&w$Af?Tu}S^7tsPC9d=WGsME;3Hb);iKW-oB@#; z>AXUGdiQUCXL8=$cysKu-DVis{ESKe>!g3<{j<-;fn%caeE05)aPy?8*kVi*{L154 z1EgpbyefVkSwGeHR@-VTa%ofL&liAe{z{{i|n>fiVa-%FQ-=r~+_6S_dQBEF7M#*F= zMsCVSlApU4``l$hrR(Kn1N`PStNDhb%pMavpKhgavP#<>5ZdsKr(MR?^XUt%Z}WhI zPsm)!0*=4ydO>Jy9xi?1=8(Bhg6fZr01La?%P;0u5bf`-bbJRv^m~%*`M&J*^i4h z<;HCP1?)IzEGD%_8+JF}@)nkV{4$<-H+o>@i$6XA`>frJ_{KOdc_W6691*qu${dv5 zV}o9Uw#5JY%yl^B?4Ou)^P+8W^bw=NA6RG{hLI!Y;*~jNj%Zk8Jl1+YdKlupB^qn@ z>u7^cJ*IV}PBwr`O(L*dk~2%UO~>8;h#qE}^zBP<$Y#YiX+>{}*mS^I_|`uj!d^ew z!=(G53an_w2eSv6)A3Wb#MbNfh5A%zWsOD8-iTWoqBnc|-$s23x}dRSVf63<`t(DS zvZl1^gMR%M;KPO5!I7deK8?dhV8q;4F}E#AF<7-3vUl&j7B6jaBrf^frcv{SyicvY z6h|HNzX~hDS`0VJ1)UpUC`Up01#Tr_ZB6mT={}S1THDb2+1*D;I=upIjcenxM?}B; zKJKS~#6y!$z_z_9ePry`-0K*8>4l^5gF`QkxD4D1NB!n>Of0<(W%;a`n7-s){Nub& zOdIR0KN3q{x&-Gpe!-NVb@iAU``aP`i#UGjU z3Hz*5un|;B}=W8QODMD4$~N1?9i{6JPvM^k%N2AMU;8 z&iLMscSfh7bInP;|ckv(6(Xy$8binT}dx1V_mu6XVf%xRj0VgrYsbUZfg&nQgk&4nDx>$w-jQK$Q~NIN9~ZyRsrsf88)_bT_jfyp>f~l2e&r^ha6z|ad5=T zDH<9@_+*Z&MSgVCgO9*L8x@0r=;7J^Z+{s#y*dvEj_D7#yxP$Yr&Q8_O313TN+{O> zG&Y@2e{$sLZpZ_aa5Q71uUv>Lz8=|6y<`Dizv=@V^Ot8$FTVJ{71(n`6LQE{=|8r~ zk;4mVpOEg#aI|(T!Np?|y`5G3_*?@F*wKQnm|r)vk}P1B)l1`HK9nTtkM-~ z6ftvk)~S{r zoE2Z>;#kXA>Z&+t=1iuk3e^POB%LrlD!jTYHyE|r6Jx)q@$3L2MNoEEDtV0UsiHw~ zvN*wmgA|u*Pklw`!@$_~x^bX~_*)d$sFj}EBirBI&ygid%gSJ`EZoz#@M z3ywAvGqJh@x|>q>0BCPUMhL2{5)Fjtz6vLy)0*2Lk~Vobep%+Gz4=0+8CtH)mP-+y zN+RMIb55HZ5Y5z;$^nQwN8F~0Z8xQU| zBvvi7wzeWij*dj@>`v4%X<9oMKafp_uPqn<02(v@Xxp@o6k|)Y$dJdK`|`514eJ`E zHUalK0uK3CIw}e?yX^NQe-p#!iyWOPb~-JW{G+5?60PJT;ozejd0cr`#R@5N(fItn z^(pEL-QWGjijvRGIKwx8j-EWg?Bpxh@fBmm=ThU`s_n~(AS5Gy6 zRt6bR*K4b{N3IsSDq>eWQag0!!syc<3+BzofI=ikKPYwU>69`sq0-fffN=p9$*&^`+fT>A*t|4j7e zq4-5ZjlH9j_O=yhPv}(}mbdjrQ?KgAST9+KMSc3Br6IjODCT@PeFoNCe@x}mNJUvj zjV;WN|9N>!tD{6g`8qmBN1ZD~CIsQ=6ghIMKGzD>t|P4sxfNj=m6GOlBmFvZ=i_kJ zrT@jo-;QdRt%8p1!LyhC1Xs2kjz3-%y~%3n6Mx6~Kl&MZopG8;@3L$emZ^z2`1r4w z^oGTOU%n}NANd=TzUzNG;;`bU{q!u8e(;8;vDWtE@Z@#(ne>N~_Q1$uqYcrg7$;5{ zhU=ey3-9)i-dfl&^(c&N?2kTMtYiB6(#KxHCmTMG4>#W1T+iC6H-dFdH1>`@_R+qg zt>jfo(53mz34Sub=DtDy;+|<9Vcv9eDh$5Nw0PBnIE2kgeRPFJx>1KU(NZ$ z+n$bH1`EHf*RK7kim(e`yBcTxA=0nUoL=awJ{1{zk1zP)GpHXv#rWVNK6U!e7}DA9 zE?>5+a+o_inq)&J_b!;S_wnKAwM=@=;!88y=3~yBC@vUXuz&4y7h-Y0=q;*)F&|G! z^VL@6hUgR7yPbF;c3ipuAHDi-lm64$C*dC_{Thc%u)YvPr_{$&g z*V~^&ajw2Iceyd08j-(lYwLM^DgD@7g7G;0`u9h@;B!S;Osd4ozu5Nk%-TMzHeFrJ zxqZ&%(ssbqq4^6JEJXkQ{n)*J%K|#mr zXAim)OyBhD-hH!RVb8e6BD(u^=E#vF1Efz|#AQXq<*qb+NG5R}^FxjtIfB5%&OP`6 zG--Xutp$3L8i{nzeQsnfn3%U1L@jTdj8Q9kAHVWp}h z=};r1^474A#S=Af0(SiLP%JHFHVhb5_&c{krIEhJf+qCoz1SodFR2W!X?^KpEH2#8 zia#}|O8TE*v3v=ZtcY@0iFI#`*y2!g`lHQ1i|J3@iog8&`zHO$x6j9MTgmIW}EXiI6j=X zKO*(fkxp28(bUw0Wy_b9pXn$*>!#a_52#o%Xn+zqRXH)QR7j1Qpsb^23TUWYzC4}Y zwep3@F)gj97@0VGs37@4I;mUCVS|H@#P-Mh3YR^7ut_(@*R=RK!|=Ad*1#A3vOUJe z55VmFZ5%u6IGp+K=(BRWZ8;RH4IPTX_QOWKhG6)x=rdREE{f*M?1!SyC|;=##!ru* zh{w-}9$vWkzRhv!&ch2bmp;3=$z-%$_6Y84jviEEUl5iT|DWTYNd;kkay`PPxr}Hef1F=!%x<#c$%ev(Ck< z+eHr|pRmgsrH4zErJ%_@-d?M(i*@?lZ&Ixb3i*Qt3#5SbK5=}E@)x~%z3Hp%PL4in zxa(-wbr(_a!|SetzV}BDlob8&kX7MJnmJY~`j$TXx?n*Y8rB4aUeM%D*bQ*#^X`A_pxX>&&!!zUkz zqoy2KuG{|MjW`kO;iVN3;ra!;H}vC=Obk+dN_A9mu9a+F5$nWukGp9{132m&xq4ND z_nLfXC_%8OOsDut5rAU&au>!$X`HvG#@jcLHqU4r8rbJ%m5`^Iwz+awj7G21&ZpNy z^C%DH;Lk-=E~Nu_rzk0$q>xm8*LB!+fMk0TZH^o{Iv>$oY<=J&{OVs%Vy!Rz%A~LQ z!bVth^AGU#^It^CL*uBr8#cZdMO_G-<~*lohFl>^W?wr#E7Zbe`vDLq+3@;yd|^n z>I0V>iu0~gIQXn-r8%ImqD&Qaz*?JZf*ChIiW&PvZ*CgXTVw9CkKy^!+eEfU7&v`T zAT`~+HR^^`OUlZ#LTyFLpwqYNKzO4^Zn5FgB(hk#E9OF*!`RPnG5*$>3_mQn;wttO0PHSwa#R0GV>hV z(SK)?K4qOquNsC&Z}!@v-xc`RlVfn$p#w_SwQ4||k5Aoe=HrpWBf7lpT zf8S`rHd~Ct;J{PokE?9?+Z*DWG;5l71F=JxFdR24LuspS%wp40niG%}Fe zbw?D^27?q+`|@nw^qkg_>T}8`U585sDMCU3A1NYp@ug!VwWk8=ae3MyU&yuQ$dRLr z4w)tq(`Abmo1Zc1rP0IMAG~@W?z!tVtUw2%i!FLI+4JMpn%c21*pRH8JW}}FAV-@L z#>3NrIiQW>Zbe^P(xn|tKtCL7qW&gm#j)-Z3fHU zVW@BHNpDqXx}l-z3O=NL%{LHOPy3ddOulxNd)lL?uy2NIN+8t?;+{~ zu36hNBtmC9%+^U7ZeQ57zw4sa@L#PCQdZ?Bag073G^r7(WoT3#=5SX(v_vwkahdG`eWsL}aNAUBfu8bFOgZOj zmB5F(5?>o3y6SV4Qfx=-Qa;qpfba{EL4tPhhfv1JpCc4h>p}u3JFNnF`9_AL-t^rd6*&YhlwJ55=zzkKWESwwW}-Hf|jY{qxavryAy8xUER&wU#(p^d=#9`6OE7U?96Ia_ob;W? zP5Iix6nd?-F*X}D1ETE9UdCUKJQu}Zq&_)d6oxm>#YYWO%@us>#L;Y@wa@&wIbQqB zCOF_*qmcS~P18o^@VO(W;LJ0=h5H6J8h&#Zu7%H^yf@ag-YAnA2K^DPJM9ota7U4@ z*C4DlWk(br`1#_m4#%g)HmB;$DSh{F@Tb0p?>_w#oOt;CCOu|&BYLmBCdT&We`_4N zH)+I@3d<_#@(3LV>Yox{fCJHUjr7ZFwc7{Ud0c-bXJb1)e)tmn?xwd*YUYabaqhSi z@ckX6o>u6$$rtgRX^)uHN%xi7ZJK2G9bB+gzdYkRcx2QXCck;kbj%xj5RTow^kL2B zQ8@VfyW+QJf7c|x)2BZc&jvR8dh}VmT?Ws`6X#!w>3f`F(npPs6tDN#ea!J&yZ!)Y z{`paCa;$mh90vDUA5+#}j7J7-X431%pZIEs+S_!CLAdn6$=G;U16C=J`FMX}J{HGp z-okN(`M6i1!{?at2QRw_kG$E4XODW+q%SB{Zy0@$IsW2zhhn|Hc1y*d3t^TRmzw0~lHzvyj-12G$) zs7d&LCmvza8};V2JwC5!_M9jFW^&KGXasJ)>aapTU2M{EUnQGAsL)SeH0MnZpKJVZ z|J6z#9WMFdlL~rm%8{eHL(h2ve>?Lcb3WoH|G-h37Hrbr&NP~J@oGQ8)km!rr3)Ds zkN64x@x9GJzbx2yvjfa=@0)*#-`{ZzzO(yhO!`}sO9XAvo3Hl$+U6M0&z_&X(9F!& zUb-@0vFJJc^Q7MyRew|u!)pE8(fYwsQ$B9*AL4sk_Agw+ohE(RMUUW(#%FO8Ns zLBB9(7aY1CL}YQcMYwLuw9hgQ?7rXq0=G?HhEG0>u7AuPN8+SUk12mnw`lhcF4(-E z6>MG+MY}gQws{4t*+6)6H}$y102j)0*VmyT0Jk#r(b97+&D90?D1cs|9GlDXBy0QY z+3kea#kbUbM4pbKHk%3Fw_aa^Vm4k=mzaShrzFA^eB^)X5965S0I%FC|j%&oH z4#3{Gyp9|Hb(%?k?~aXe&{qz^ly|R2hatq&u0l}v-Fu&&GoXk9L! z*_?>2lrN7M!mQUkD+|E75XTuwWtj_3y{J8tG`u=|fif91^JZ`ev04NxQUz zFXiLYWO<|)ELed4{h7}RASIN$zkTS#D-BS((|6VsN%)6yI&Peq-ar`0ZORzbM7Be^aJSvA0wuDTypRYf+5 ze_dRnqMyO+s$d7IzB^&M{D&<8zt#-Hv(G+jj*})$!qTNn3;&lHZcCRf#mt#A%XE_` zO(spx!z1S$i#w)7H^hFl>u@58uvTqbX3iGOUj*GU5CfXK-~$HjGjYQYe}wlB{hg8i z@X38@RKx7G>+#T5wDv(^?b9!juNOat-+c92toPe9O+)*QXmE-daMa9*?bCP9&)9ZMIK?165DT_NACVZ&AdtWdH`Q0vRh82c^y2sM&{coKO;1D*Yc~w+hh9tOW8RABv#e9Ud;$*JbU+nuI{HxJ;(7D1 zctrzR1`RUlmd;dFVJ@3KE&3RytgX;*a|=_mEN=tPBYv1|Ucv4)7j2#^6qau5NVki) z`W@u*{r3?<@0$7$!Uy2*oykbbFRjLvkgjF}Fw5Os7ks+|l$LATClfNX;geIUD=9Ze z10d)=Xbx%p*VV8p`2Oy8ue8IjM;F#dbEEhY{RW|5$a=p9tn6nQ{`b!RFra@F?>zV1 zbJ%|S?Xh^t;%LjOy$$Vc?PzO@;+f*H_~5v&qkNQ52TZ$?3~=z0mAKVq+-x0~W z;F;U;^!RV$m`TyYLA9$P?G-;q`@xmOyw4(xU9s(L-1fVFn$!Qj{yg5<>^u0^o>^=`k?E)e7sBwAm)1u@43f?gKA` zjkhebUC)0TFTLLfW5$gzbp~J#Ubyxayu9Haru>NBOndd3(kXtOAFwJV6A(4Lp^r%q8o+5T1+CkR0bSAu=ja?Xpk?5IWKK);rnQ0P^q@pqf@&Fq z?Y?w!;eVueZA+J8MZrEc_pbFp{OGBymVraisg}W>cFI%ElrTIcI)k5Y@D${A2JI70fw=zU z>S#}!5b7vLJ#Iot{tu)c*N#*#glCQ%Jpdi8_Noc}dT@NH%_q>|H0@f;gOG@vH2H6X zGh;3np&Y#6p||s?`R3dcw|8RmrTjSaPI*b?+9R)G>OtU1-AD+iEOy)Wk&}szFD;Ym z<){UAPjVV*gVS~{Kd!4Cb-6b35zUb!55{xk=wUGKG~N_v?f}K<81VyGv8^zHHe)xs z=_lB7ny6KGqzgVV2n2!nYx)rKBc-9F7?o&#Iy9i z&AnPdLdqIgR1zwLFpRHrA5Td{&RTVc3dtiGTo*+UQ;?DF7K17c}hS=qEzWNRcU0YS0>q%~Z+V`9^El#$GlV-*FR7Fh!xS{HCn zMec@We9rx+bzE|A&WLkBE8PT0@rNy_hC6bgoy_s%2GixSLt%UNtUNipO_hLaOEc|q zpx3P6zK>}0wA<&R8M_VyIe}zUMauxU{9NRwAp1L;j@IGIavzu@6x~cua<%Vx)X>Mh ze0*s<;WFit-`B!9kaWFL+b*{da)gk!+mRqGZ6q0`>*MN5^wK%tj?XxE9kMi&Tw6YO zeUJhd9dOR2LjxW=c#>w9YZm6H3cffyM~)mha&#@kuUbgGHLG-<`XnMsF4M}h`Pk`1 zJIIkE2Me-NO3bC=+_Ylf_$F53K}s-tmECW`aofo>KkHR<>$~_l)Y_gk71k*NPlYPB zLRY1SVRihczA_s(gics~gfeYyA!>rz*U85bN*)|t1-tb3U z^45nYIlsLxMo-)UCw^}ilU|LuKD&){W*tD>bEPrY&8^Nu!vDo#x<=x&mo${84={4R z)eb3KxBH}WHY{Q2?KG|HE6dT{pc02vk!`@)H$a#E*jvF7F~HuXfsjYfB_26)REtPC z8=I|9dag>47GBb=7Q0+A^<73^;_JI{>2uL`yOh?&uggI4+>)SNCx`F__)cTp4wM3W;&j(k4k$k7Afx_c9Y`>dfvC%%;nxk<^9 zg9Wpyp`RIzZ&1Z=*Xn@_64!PorSWaC+DMhhCK1(uTLoK14shGLavP{tz)Z-xcOW9M zz^)6&)bqpj;#+9|nL5BcoKfyYkO=f5z{NrN;Nas6|GgZd%BgAU+h(He`AAhrK}Lho!JscCO1-2A zNW2_3Ro^rDVx#=fON!K*jjNBRHh?NJsgY2|@&Usk7 zK9>);SKD?St|KKmHQaYw<2>$qBwC4=uP-=yDl>O3Ayiqk&^{dU*)$R_m%Oh251FjW z(UzT;`@puEiVPi8pVlq$|&TLyjB*n3YO-zH#~JQSfcY+BBi%abChi z#pbJI&Z_Tcl};)@wc=~@)E%S)+}gTk#NS)1*Jlr{8BCFtbMJhvK;(TZR6V2f&jT@ z=IG&Y-C(3Q)?Bw{xWydj6u7#sJn5EF2p{g|W0wNGf5vqZ9RwQmNgf>*Z^}n`WU>cb zF?DSk5LziH)kGHVdR($giY5)TVt7z`Nlr@7jR{>5a6Ek1=8}V6i`0&S9BE18EJbU% zKg^LMN9UpZu$IdNxlBF~Znh*o++tOd#bxFtHvyqtjyGq@eajmaKpWa;8fn+Y$*7rg z&K*(LCACY#0au99v%v)gv<&di8YyUSLBqW&klM&cGe?dj@?bkhj#VD)-ho2mZCTu% zGH%10rlq%XN&5sja^$eUtb~%U3JR~=1Gru*FQeea0OH z7E+n=l+%3bqc!B^#7Z|OIXW2`=M;S-w4G1atlDSnB<-wAl$0Y!_X9T_q$wud%%e2i z%|h2L9mV{2wFy#>yG>=&bUAPVPnNs6bhRzjx9iy*r3qgRA>eTE3sDm8z8-BC;0K=G zBednTj{qOjNsAiE7jSZiDm?95mqK!Bny&-ux@5Oya+Sq-xlio5$j81*L!(>4Jgi0i zw#&uQb4}_?=8>+G6_d{)WZ}#4b=Buw86dkNE~asrbrIe6dyUC$GivZ#vNof7Juu+Ql4>H1v_n8wSFROT zu#Bd&?Ov}D@iZ`}t{s9Z`09{CU2Y$V9H~x~vS|k^E-lqv*^oAUH1nU*aP>P3oaL}e zHN<=V+1mlQx6IY!QnijAB&G%(~)zVSWNWB!N8pIE5sdRzcnK0zRq9jZaXHB`X zE(FN|(M{P-guQfe(Ex4{JI##b=z5^v{bb)BUDA-U@u7E1RFck#T+_M_x~Q#Q)j*9n zHQF|f67p$X3EV9vF7EX4Q~~_E1*CvT3AEgri}K*&A1TP^@_ct-X}*h(t6jw$HPcqL zHeHgJlTkV9a&jx?oNJ$+yXakhPC59|=u0D;&&<(%k&k_jaA>pH;-}HVMofd9aG7t; zeA#7O9haH4;}@3B#3sjvT8jXfS46qe^aAb8pYmB&xINxgeQ- zGmN_09654WuvSrutc(&#dZP*azFs$nz1{@UUBIm>Xx;c++~y2jG}Z|UX?bMg5>=gE z_oW=?(%PR}Njc$tOGQSQJscgMRx)eg2d9YX!gLkwA`k2*$eSnCZfvZIkgi?9-!B~^ z1dtkkT@pv5esA20nU$KZ`to!#QNPEw2s+aDsN`ua=1%-DB4^ONyfP4q+e+M?)GFf0 z72FPs=GFPKLWasWq+IXk=z&m7cq-{tFZPRK;S%{xfo^*~JF>>9=Q9ZJ{*rjYZv6Jz`Sr z%?Kz7qguFN0YYkX`zJYSLpmG@&`XPC;ev&AQf0*^Yi3;x+v*^oavI3a2DjVkr`BQQ zPChK>@)LTf3N_E=PBsb)iaMWYmtMy0O=H*!B`ywC99NiTi;#cd8t|w!9-4MwrttYsf z2Ap4}0fj5TQ1Cw`tIs*vxH3)7ZFxcD1yjbgp%^)7x%RY4<k7wm!!GhStLh$tWnoA6 z9Ju|6R0UOs6|+trYkEr%-2`CSD3RRHm@m;8M522dIqCyC-z$3L&?l-VenkkB#QI-) zlUB{F4Xer(Rn102cv~3P86Aymv!M>wCc!I}3OCjw&#Fzht|zmskoMf9oqt&QzVYj{ zi&(kfwoq(+k~ZO~qxB6%jvVy{z3BwVQyx}%mkVI*NhD1+X~D&rXdaahj&qw<>iUr7pZ3(R zGTiC~2T%J*<*?h-f;?PZIQT*+*FyVJTX3{vAHkH-zLfIe$#>~)EU$09%Uzphc)R+} zPAiXWIVfD#$~7}6IBivqe6GH4_U9v+BS#oq9wSGN99$*r|{ z;`$6ackQ8^UAM4OC>PckGnSWmb>PFDi$tF5bJmm#h71{kte|@lQo1KX+E+`@t?GAh zT3cJq(TrVPZLdltYi6(N@NO+uj@r0}?9_1MSRJ%Kx5@^*)#~&;%nq5;t^r_B)cb1e zRriHYgX8lU(w+&wyKVY==n#RvldU}GWJ1mX_ar8llIvJ~(N+7?Wp=pTeWzcyi0vg& zDxYj;07(5Njs7;x-uj@3`<9bey3UYUTj8V2af)W57hNi+4`Ro8b{QuJwK{HD!tz4; z0N{Om5wi<@I+W4Z5OX7yQ48z>m5V!u@Ie4A7n{<)u=NW9zw8mL+_rYKL22wXS9i8$ zd$_)oWS3lxIRC-xl4Lt5Pr$7wE|=z#Pm2D|3TKxEOOIwE*~DbIXR2A)OUSZ*ia&iQa{`J6c%AIyzdY=jj;@JZ z(R1YJvT(Xe#xK(c02GOM>>W+Yi+}Y(QjXkQ^ZCZNNj`m!!j;%l3_;P(m+XQ$yUHKq#QI~3ROy{C?wZ+kOUFgzV$9*(f2EnEtapicj z!aC|}q#d4=PwPqYQzs=E7tWbc-atB#aXAQ(dR)IK$o)*OiL1-WzUrv=$^_L8t{jj< zN*i2=LyrpbNOGY;2aRN|967o@e4%NM9644RxWFn!qagmI)TTkH%zjXddpN6H2H6eg z$dQAfG)e3Su(*e@YJYmDTR@81?bU{YYy!D;XriF1E|xY-vU91nwEpdd!MhQv;y+b7 zgTyki(n3|-5&~-B$dG1jBbCg~jc%Mu(&mwPI5=HR?*WOLTrSrg+T*%%D1})ywH7m| z@rkQs^;J#lc;l|a$edjLq{MI6;KQk3vwa;0$DZc%YOfMUn@X3X%jiv7+3Klwa(UcWcPX7~o=LWhYfI8&AS@cNb->jhfO|f1ZF22OeMRe2U9#)?WaO@en@gdQ z793@+`3!--cE}W`CB8oU0D%{s>j;pOw#WG>>c4t6I=UBpmV}NjXN_E=7^+o01Lk2Z zYNT8a43HpO5&$IZE()OWq>(; zIYQtw8a}sg=et59khVC@&54w<=1zX1S?mirW2qCJbo^$KfUVYHD5EV`k}R^lOtU#b3ym_7k%q?J-!t;oGLF8CE=9!<)A3BR#J>XhYK0 zTn+}(;*5fGAkr?ha@2LvcEX_fZaUcd19l!g=lI+0+iltBoN3a8P7AyNw18K;fdr-FCJP6bVV3H<420dbG+aJopdkl3T)QrC{Q*W! z&75;8>T08!>$lrc0PAFP#E>*Ibff^;7};qsG_F}jH7Os#PDdUEbQ8F|RgN4vIu))J zxpBRPKlD>-_BnmS7JV4Yrist(Bew&P#ogz~(c@5>oa|i#konqkV^!@)D}kPxAlKT| zl*gvcGI!Y|bW~FAY!2z+Q!UTp16x*XR}CAjYiOVH zLN?SsKUC^Gy4B6_mga}RF-$IE)9XCprQNc+G$C!Jfu!j%M*x&3j~Wscz{_Rm>0ok^ zQwI%R=oYS|%&_t$F>~GP@^Iaw^38^Fof2_;R93!ma~u;*XslzIC*;cRJ}Mc7$b1yIH*MJudr>(gxm?x*kgbJu=Y^}wrKR!b^0Qh+mu|WEhspXxR zS>WnxI;O6*F~G~k>4>YZI2j4! zM@K*!MNUI~9@S+5wa`YK*TqM@2C*9K`U3CSEsY7?BZQC!R_c<&-oi}gW@J#uYv8^_ovCu^SQCqKjf%I;?RL0!}p!GU%AhYTY*CkZ(bF32Z zX_N-zW#T22b#(be&4knR!DH?v;wf2GMPg}fV#f=%%&zdt=RsAXmH3QCCAxg1-aYy7 zmLF2c$N3hU)-Ly5yRTnj{`L`&{Th{7vS^gv#b4sZh13eXRhC?27E8+Yr)1H&@lvE7 z2o052Gj+K>vd?|j<1)>Xw*lO`W2d?C=47|ar0a0;qWK(8Zk_;PeGihS1)g?&S6z-) zx(-Ui*)xtFOxu!8)6&=h>3K})=^W%_0Nmr@ zoBx2@2ImNXj{j8ClXQfAv&PkyOY1ps9;=HY>!n#}uoEsP8e-s-CvEew)6{`W0ZNDi zk%AX6^%P{|FF8TUd2q6D{OGmXWp*CduG9|4n`=LZ3o0;Qa#ePjOS9~HAzBQ9e~wN^ z9u0I88#bMVa{5cmtoV(K`Z({;%azorwi_bmG#1R9(1;wb)!H zc-sjquTPa^pV7@HN&|E~UoCBB(ejXuqz=9wZa*u1Lo`5$suYh_t}uz+L@g|JmGf4Y z+9yT;wGM`_w(AB)b*OM-`DSQL3FqNr)Wm^h$(?HlZCxa=nT2e>^}raXc1SmPim)Rf z8U=At5#ZJUSJb71x*1W6*^s(|`_I+s=s+ol6TVQOh?JJ8$~K4n0^-D5u;Ozd^&1%a z1^W10+5+Jo?4luxD-_FO_UL-05^Gc2MkAgK+G zw@ssv&5XF{ZJwNY;QG*IVX3Y_pyB9jIpQ*Dd?ag3-LEfFbBzV{DlXGW+ffW3+Kvy} zApy*TEzMgl+LQR@Ac%vKntF=X_gTj*8cgYZ zZFen%>{AqJB)WzaF=T^Jjg>TEZ71Y1hM|xQi;JGhW4G-J02Fv5qDcJ^11tqAcHg)R zC~a4Q4xq{50;lnkONsL&Bg3UbT$JtBB$tzq@JdDA{oMqTXUdTyN2h=bv{C_)hWu`S zyS(t9?p%i6z*FRZjvP4zD6kJt+W!-@=+WRVUpw;cauq_al67mB4o*8L?F+D!b$C## zBSGB^U(yNSHV(=ed~XLysG0v+paK87HiI01dt(N0^u;O+ZbL{1($=vbw6jc?{{}bA zjcc_i@v4qZNovO?XHfHX>g#H{q<*$e@)o4A3=L+JtwddZssJ_n0j>r65~Tgu)PAwz z>s8e_6+}7ca#RWKrVqD=>e`33^A+5KMk6r0UGAJgXN|cOAadQ3>tUxsvMs(4zzm@^ zhV~Lmk+F?^RlNP-lt(4EL+H|t)|X}#El;%repV?$r3gj(%~?@iB_2ta$DB0WW;WuL ztY@Ed*FwWnfVVpFxnxCbpQIgaP8N^)4t_&-=+iHed@YK z&G6&;SvlmUG!W$FWRhGwm6eVcn06(dboD*W<7BqmlWdO!7dCuI10OAAYLV2-J);QT$~tif zV_~zR8ynK5O-}{4iQ}JW9U=xm_m={csZ`vycs4$m@e$@P)8>DaxdgL6m{IsY6CcfA zE@-vYhDOZ~P3amwjhL)RWXlNUDo}EEZ9|^iRa8~T;Udi>8~1IlIzPCTXpS7?b8gF@ z^Ud5&Tvb9y0&p9?-5MQvfzk+NiLN9gn}`gM-m`VJ4|Mv#a{6YANqq~@19WfYfb*dt zNDQHZ_&`;8C{>AnDclCL)nOm$i;zLuquU}hB%vxs&m~W(*<-{x{-j}?7e9c7QmNgN zPAGIGEv>C2IVhc7?lRAkrJ(*JK5Bs%7v^!6hW01tmy&T>y05{=%2_sgR1SGblBIXZT30+v(If> z4S8-$@X=_<`l|&Qee;6y;P|<&mAeL)Zc91}=3HurUMFWO?0n^DpPTa>sP4Gtj5J@Q z`9;T$jt8ylvxD>~jTI*^r&mglmBQ73If{@pwOSrFA8DkiXRvulS}R#lhDBEb=TrjG zD?Xvd({&!Fef2m)6{lU!)@2l=YgL{+>Y%vbfRh18J3@{x<sgRoCP$|{=RGO$(+xK|^e2b*4#F$rD%G%4z%6T6yoZNxc+H%yzR%7W-=|Wzc*c{s@4hGS z>dd(&-PUIaMy@px)3%>x(&Gm;6zb2y3wPgQ()Yda0hSFIi_Lf4$279t_yOkEg?jl% zru?}(Z^MHxzmG+|hnn=54YtBAyG%CctIc}`H{AFXX16Cr?z8?L=JgI=J>v_XYWI#Q(8kBXWxu%k2wKwPn7r*O{Zj=!NaUW~Ue);ozf_q+!Y?E4j3ijA{ zC#*ZDqVVl=-^9ar{o9;B@m4DuhHrrF_u12=H(kBS^vCRHZ!qbbo|;|0scZP@K3IRx z&tsd>C7ZNl2A;V4Zv6L^874Wey+1~6ur+quZ3~lLv!!dsV=HDoZ;p50avz@mU^xbk z+sveQ-Di7@AD}S*#mM$w`{+k#OV#d!uYGl2bN1pb*W$5{+S4wmWdoDm^WbeTnl<0t zPI`g^NlWz9CQt(&*NLuT?wb$eu75v)w^}287{0;w*k{iv7}-?ev0~N>reBJ9;e%xu zFm`j(FGZf?2NvtKWA;mTnetoic>y1(QP^~ks6TdGZy^86`?5#{eSYs@-1MKQQ?@&J z8dkS&6cDsce*l-?vH;V*y0=MBD5~e;cktjfk$yh*VP9;t*XOY3MuSXRH0wPOlKqyV zEzK}6boRCf*)8*@;j4R3KogNu z6=;g*(;v7Tw=9TgifE#ulB4hXTs}I{e|oVwpYhba`1fNkW9GbQ{taGlOYFVZw3MAL zx4B|E9{Bq$m_O~SCV!v81k_7j!=3+pDB>5#wW_~4Y_#`5*m`7xSHE1Lqt7C8p!Qcg z_#|XnQdlS4_#ZTE_c@b4ZB&EP!rHP>J#}5HH0ONR?#q|?EjQ;c|MTa#f9<32?X3oz z+!fDWh_Br+34i{-X#Fun$({uQZw-EKN+v?$ZPRks6dILLddVC5Jg94IIa;o5X`E?& zSo~>!a`{q!&})+VPU0i!wPIw}4jvkAJH**Ft{jBUH}@o;kfr^YhHGCcr+i)Yd}9)- z=iMK!Sy~N3W}uxH;*BT|*X+n*#X1?~OUT~O<%hMni7$0W=p+YZ=c1YNIIRRZ;E;ne zz9GXO0-qz`)LfFyW!znPF4?FIzB)NLxQvGO&`VlR)7%KV_yC=5bh@aG>k`N(RX0Iy zA#>#D6mTnIDR{JZ5A8d4+>RrCaHP!3%Gb<1&!>Hk9D%T6Rc>D94``LaMetl?@7h{$ zZe=LT1X}gNA+2Kw2?Kw7B}rEibx8EWN_b$vY8VWABB-jp_?$atL_)dSF#X2g z;4ibkW{Q4i9@JWn8Tb6kq))zZCMF;J8Ems_^dwN@!cXwtYwzHr<=dF_cr3+Be>nla zo^_B(AAQjF==0%yxcHPaO?u&P&&1v%=Hrobk2dLxmmYv`?6W(X7JO*Z|9j_SEG%8# zuz4@x_M2YEHb?Ak(qkJVVS5j6iNqeX9=2Zhew^_8B_{oqvkPq&ZhVa!{&v*%@9)N1 zKi&f)R_0x3?Z~h9T+_4h+)cNkd9&!||E5D5%S{#kM$J)6wF0l)5#7A+^~LjW_Wq;F zH|>`{eKl_AbqLNo`!gmzDyScmmZtiLwzO3@TV-=~3BxPxY-ZrcWyT=RfxD?*JLsGj zNCMimucaz6>3DR^1*e-$ohuBQur=1b{{)lz{gSWXSDzbJ(BDXwdCy#m6Mp(A);jnQ zliqpnp=g}<79RN9_f7hyr%%Q?hfl!(EHeC_x#W19`|;lR)&bGOSL)?!an{K*@WWpp zX3`UyKEXW~oQJ2zA868h?mGkvU$`3Q{NO#4KK|k(Fu89#=Dl>gN#FSTHaKGUF(^N8 zq?$0iPhk?xf5s#)J>jQ#bghH&g`J~^X@)hRIB16!e0c9gCVk4!7U7>i-wVA4j5O)7YqccxYw4@F{(>iguSWJ{!0KZ$ zu5VIrmcDvDE_iByIp6(YQ~@O%DY!cgLY-On7>WzddkW(Z+!Ol_S!l9fxcVIY;JxE< z@e$F(#VyNT!e37KHD(^-d~Ymz<`SH6?#Cv*_qPwgUg~9B zbJocwJ-yJchppelNW9Gao$!gP9AqH6m|t&@`;xi1Z|09{Im(FSrmlytpC8 z9lDoEPiSh#8&{o=$JY9RNguJ_C%E$Gf5fAw9%s_i`mG|tUnf8Zlu5B&!ZoP$8lhY- zF4IW;cFp%JtajYa;MOayb&TlB7QK#}&pRIv_K9M<-M5*DEjCb?H{)fKzU8cc;M(1P zfa7)_Yic#A;$v7#F}&qbgv1po_#cO zEGy6yalwT*lxd1+R_VUy)^DlnvhuimSp8DWZ<`)H{D1lFpJ2)!dt)bvmnmCq;~lWYkbVMK% zJ_H)tmee0T8y(dfJ})B88lPr{ly%_|*5yB$kk~?zjHhHoA<%QQbaHa#l$T=af}wZu zmJALjql-Vy^R*Y#OMS>W2PM>VT?g0aF4fLKdslMVAo(_(hHP|Pv%r=?N^@G#iH4^O z+qfJ#>Vw=u=E%`u;No)EbW6R9Usd?fhp)I#s?Z0xwBwJudNIEfKgfGPYJ3)SA9fs;kuZRJ9JW zP|S8yN7=&o<5Nm%K?&y_1v}2S(_Ip({MXe@eqUK9gsOFCI@cb9Y!gK}$%Fyw$T5>{ zG3DI`fTNJ?M? zC|_f;BvDD#QQ^32%o2BVp_q$?MaXh2^d_djmI*I{?^00_q_Nc=Ie76EIr4m|rPTm? zH%)ok)Zo|Sv>!s+xA}20ghH|f(%5K028HzXNqp%1c9n6fM#abkL4GaBFWE(o7s$C1 zXr%t5IwSQtm9v`VEZ0x2_)wGois2*W1N^+=`d`vZ?MZVyxiJBePdRvV^ON=)cfAU- z?z(Il)jQr6<;aeZ9&}mEYUziIythy*Rv{s&IRq@Nz>KvuM=`FmZRGv zSMnS=Is~p2RoShTe4F%{!*ZJBOFtcDAK*gmE;~n#o{YqIGRQpS&dcaIlg-{Dpa@w< z#`)aloNXrUuekd7B{>6PyraTuJ4ETm=WuV9_Zjx>M5u zSoR#QzfNQCUv6YtF8tYgHs4_{Wp(31Gv+rzrd|;?uxIh$5iYp(8AGIM+MLrv}6AN9y4bT zKKeH1_Z^2VcHG(!6ov(J|Mxf^e=Yi?<>I#g;?_IX#$H=TpT&CO@z*hTQ9J&7%N>S( z?Jal5l#$iHrmXt6Y*prambYw`ZEWf!Mm9mjZs+!v6_TH0)b*UP8I8Wf7)g7w*`b(? zUJ~PX02=$PhS4LUw_o&GG#aA^6y|!{nL3CBNb)z25lS?@dSFI_kT)_=h`VnALTYHk*QxzdGEU z|L)qIaM4#LAYr|@aKPzo>Wn#W;kBjFXBrRNV+zI>E^eLub~Pg0bo(24X1T(Yu~GR> zW04Sc&VB#EAEzFGR`fOLu~T=(Sev(=gZuvTM@&6nS5s$=PW*zc6T_nsKk3}v6WJRy zy^7n;ehxF+qc>}fpIhjgWn18|-KRw9UK-=~+r{)tgr#`yjyo~x&_9_jIl$Q2jWBk3 zRQ|1N9>;+veF~`;T+NF z1@qf6dd+A)^c~a(E$`!ap$T$BUuAj;VroNr0h4T>kX&Qg+wH{puDK}sJtp5Z-ziUpusM+<3$n}zpXH8^lC}f9 z_HpRCBO9{s=%PvOL~+L26^u|Ct~-^3FL%zRX};~KY`G~v+NNYEAn=jovuQ)(p^D9S=4h6dtAj~`Vtyz|_rDgPO zTl8TsZhq%eK1Ysl&I|kSOJ-T7F&9VDp#2f#@9SfsRF&(~sVY{kf4Xn3b^x4BJZ+R3ueRCRCZ>pmv zHLh(AQ@31>b02#bhpo3xl#Nvgz8z}qsarak|KuO=gNqlK)UKc379&5t7iWI|d6WL* zMTcSTta(^o8qtR4X6(DiBrJUQNt2$tyl{iHu?cV^L^PpCORt?1FyKHUFe{<2}c<-4kfJ6YF!&#kNJa^Y6U+b!>b1 z@fadZp!WCfz}2sBi^Go}oRGikA?mP&AH9!-qqoGchLWU(zS(ZgYjDL?(Zd_XzIpv$ zcNF^N@KUuESiGbS{Yv&UzQVq%k1{;_zWo+HXx|p&8%cyYDAI>-9A7xjx>cT>N@K~3 zSKxw|wl~S|pSA|ByxMxYMfJuepWXxaUv#QTp4Q%u=1mU6F+;m+R1V`SqCKY z$+ieoa*HJ19x3xw{yD2G-@}noKW3+wzY=|x@P?+(<7dQlPoO&=gUmqcogvr7<{NtARhuKqqT7WRv#06AhLh2bbD~fNFj|W7rSH$ zqZ0k824Smj9&hrt(z9@zrNq8@5Sp(X?K9z(_nH#@*Y*zXI_F%IetptZ?6SjDtllSz z7p^$|F3ddlTpT=B8(sb1T^Hb{Nn2p+u}uh-J*1rK9(OHpoJ-@%?P2)FS$pK7W%L|^ zTy&g(FgvN3I#NG?X^)#L>>L*O+j%aYl&>udEz?YWZVchzFZmkI-nqc>5$&9Vr(|n5 z-co%ZPibtW`Z-+iSppwIypT_msCD5qMf1&O(((?5YhrlNi}K*QAVlFgN67I3?MCb`csfz)#uYS+0h&B-J=4@%F0Gwz%WIbuk&#N`I5!O%ioCDfISlxt??=(5O% zshc35b2)N!2wW>Q-@_kT@UPsR0sDb1+IEf{IjRRYKc%~MQ35@A@^S0hkPRgWbar>r z6-Ib3dni?=>^czFT&*UU{_DWEv?QQ27x1N-#HCxqb-Y%^Wu$jp=KSw}SiE-O28MM5 z>XQ#Yz_2x=2NL?Ih<4#CcbfF|kAH;r0#dEM_q~fHI(k^E->PQX=oUj(^V~iYcmCy3OgZ9@Ci%I^ zg_}-#67(xyGU=b*|3#d(;|`c|`}u}%>n1yz2KtSiYK}Whz60mCPQng5M>qfbQrR;1 zr!M_1980ek$@-S9s4grradi#g_9sQc02#O)u^|3V zZZu1wqu#is=X_$=&mOuOhO!TVM)qash@qJEaVu2I`X;^U_=|Dtt*>Lly+#|+R=j-| z{&n|EEZ@0JXlOp3x%_XKzSl7(dE6kYrwXU@p1A>kyyTI}L!u31@y#!ggRh$N7rt{W zK7X;oz-h;tO27N*#%M`(x5naUt~X~lHhdaC-?&d&4fP@;&(qi4goaO_g^io}IVtVx zCR=mY^XDr^s?^5(XUy^PzfH&9#~g>j@e;Rj4E8Pb&GSbbYto;;DC(Qv{bb`3K|9u; zG9DM-daFskzTuu2z5H$5{m;8iddBjd(Uy`(uv3g+dcpJf>&5@W9w$cjea&7^r7p17 z*j;hV|Lt1qr0(&cbIes{o4drP&`S#q4RW+9+7E02Zhx726PMjSl4~0~O^@$A9ldFA z^wwWM-`4x_m)qAe1xKFu4Q$x!9bEa$rKY^O8R$J~3+GjJNkV(Uc#yW-mNN1s*gGliOb~r#IaACYFEv5}tlH zy1p;{^knR}PIF2=TV`ntX}RxuxzUlXoohc0o$?{H9m+ z7mmW`C-yF!Mh_SEfAbLB@bWwyJa#~^d?Dostm_&Ro8G43`qZT((#)jiA+m9Nr8-<) zyN=W@mkw!vn(`(fQH~RK}ZUiMWZ`TL-8Q~f+IA}P! zm4IAva`Xt~;aZLyHG>OMQh}MnsnEA#aq%|&d1#6UsoN3jiyS$+GuY3NlCtsxk}L!C zG}zI95#0LDwV}ivO`Xzmg4eqEcCxrUlv4^>-xI)yGDUHu~M z4%_g1CK*afE1pWF_PE^~ll`c}1mTn>hZFvhsN~rrr-<^V)*TwDtrqDwaiO3OYEr)y zq~D4?EoYQ%hzS9sRGN}NZTCR7VQHi@bL8y*PgFG?0lCV()k3q?TF2jn{O_ilzfU$k7+-Lj;|K} z1M=MEVlA$19Z1W`%k?jqypFK7-4j_YOjh2U)^OTlmr>6YGFxn{X03$_ z7J@e$oau9!Ar2ulTpg7mzvp0q8LJ#Qs(=*j+8(fg1q&CX@>pJ>)08tAHV+p+mv@H1 z6AqaqQ-%QfQ0g10E4$c#MRM4o^tStual$k zwd3=5J|&d$UHpAz+;{-)$p?l8kQEm28wE)=WGu^(BS#JiQt%+yCULjgs%uU){Ga{H z(d{9{p&iy(NIaB*ozQ~vRm#w8CJB{af*{oE6*Id0Cn&Pv>TyLZ4=pmvgrF<0Q}?8J zIy0lscP*SZ9|H#sNNlM!H8*3?!o`Ui4Sk}wS`8Vx3^O0N47c>!)};5{q!*sOEoB~`XZD5;gK)m#NQun zS}MNZsbS=S`1xhuGSW=sKC#7KQzUs)|AFW|e?AtL#=D=A7Ht5(_K|sa3HV%Q+YG$@ z`iFSroMLkm|2w7IK6{3$L6_YAc{dgLe-sq6^ONPE1h@}o8mo8p{ zmOjl`(Ga~gaNiS8z|z0}4L>_AdXv`hO?JZ;Ta3W$A><8ydXYK2dgV{?`;QOA87FOI z()6uTy@!s&gb8CRZ`NuYUK9>}nj%}eKoV|Q#D8&1A2ioVM-@3DFiq>~1<&B()Bk1C zeUJDHuA96Rk6->b7n$-8dyvO?dSi_?A*b;$qycyFw^?@2ge+2y9jU(Y-Z?ZYNv*Qr~W@)4~=Fwp9l zv}qUCK6;)xd-BhJ!mRyI#o?n$zu#XT*YM0%U+3gVfa*$o^MXanm zm8?gX#PsFKi83VRvWMN4f6naXCV%LZCg@LQ;)Bs^oAjE+ufes=N9&yE?N6hd6x!!5 zz>aoc&KZ9IF?m#tJ&q=0~4lF4Dy`MXX>sR*u|!2lyRT z$_Jvv6*P?86Q^FXE0!*ZKH>e!-Iw4O$6t=iFFe$w=Rb8B{xoZUochh^vxbc+i3>hq z-2-sS&knHKY{PrkoM0L|;?ECayPxc8-qa^ui+xQ}8JEwfS;EfwXx;7d7RnVtD0EW$0hj#RaSg6|v`jl>rTjQZx}-^av<;sN4|VIb|2cWMF@iuxd1wz0 zsSmr#oXNq>)(|>cM(fj=M)Q0;I|(|LBOA;X%#a~NkfV#hVXa$RTMHYULu6~^v*KJ^ z61~sjX@s@snkyi@qM8S71lWi#lFJQO~oQ zKuIo#+4l1Fm2v$onHS02gp8+4gMl!&;&L0hMtV+W9-tY z(6n#vRD+N{jge&zadp7d2V|X`5a`bS~)YTzem(&T#GQD&eR`lv!`g|g# zt6Vc5MR0rpS(8@+v~^@f>W$w0*T*4eo@-JEuGzrQEJ?9)H>Sd5%G5=r@hZkMRd#Rj zO*(%wO=_4nrIrCM_dN2p@^7S|+oU87kdx9#`EkdR=o|Z|UFh z(u_7t9!I_-*#40@yz;_4tpAy@<%g-%YMbKVV+#MvbRXdQ<2Babd3dF+UW_-c`KdWQ z`{f;Q+R3|P&E7}}SQM*e+@{!mhlxl$W2zTo-Sw6jnk!zOfwsxxkd&?+AHMRUIh(is zXE2WW1Y)Owv73vYxfyq?afnG>zT;T*Ezs=t-4jfD*7tslyWiXcU!719dim?O;JTSR zoAaZm4PwHK<#_#;Yt7lrosY(}!HS?}FhCyj+#J%#_Z3#2l`>@fE!E@b_@YALDCYg4wML@!&VVZEC)K@&)+nCJu$7 z7v8ZGdzFQ>qTtrVT)jkOX6dc6(*$B<66-Zt_j3<~X`LKSZXI4k-_rMv=PzhO!}@Ds z?0b)y^iwl8#|H1*hv%2hH|assKg9D7Jb{tZ_Au!_<^6-oo<))~Fz1o$aKkGvne&H^ zJ_N-NTIuv+9EtVX!PGH!yq!cR$&<5IfZ zv2W{F6iAvXnrTsLm4hqLgQG3i^pyDe%!|)_0PX-iL}qwoq;-{tha{JsA0mf+q;329 z84R6d0y!RFcmaI4CH04$mSh0reo&BSi3V?~DV@ZhlS`5rjxw&#wBuZ&cg-{H$oJ_u zmC-f-UGq~TTlm1aN(KKs53yNVXx~TY>t_(zUFASnUnKh>`FK|8{SiVN_U5Ka_<~A# zg;(XFtqRw8vzA*YNDpw8pN}Xt$l5?=a>jYwe4@G+YTrY2Hb)Oe=!6!nOK3T@W*r1o z3yCFP6=K%w%ChhgX^VEJV2C37lwszVyFjyTXv?bOU4P z>Z@bn(;r}=j^2DVNNMz)dH@c({D&s}n@cC)w6AQ1kxe`o)w>`1H-CtkAD7-LFt)Hg zr5ED;8PVH62Cvf(STPSD&y5%i8`j6P+&1SOlYVQ~YFK?3x1|+w;mL??*36k`Sz`|j zP@D&H&40U1JCgB5ZmNp1IzcB65qeF)R$I=(Ww%EUf9&z~P0+t6#`1-RZc%$*^lOf4 zsQ~$+tB8MEq=Muz$Z+X~x6ec~b<8p216#2fP#M}{d00>x0vY=)DT(J*5zZq7l^C{i z<|L-Ud?0@=p07K~uarqESXqvKo15eQ`~4X|zVJG1cJhHHz5ak=2QR|gw_Iq_|C+xK zPT8`5dg%31b9nErKjPZ<{qeI6O7=)E#+%puAI^DYN0U7Lt(^GKZ`U6Z+Lm_YB+qdANe?_)(pHsGs=4+RMLhpV9(EQ;{lPa3{alMOO z`o2leoI4on^s@xk^YG|3x1-%-#Z&m*SMJ2* z^G-C$orY$7@{jgyhs7SNE?ln4yZ54!dFH72@Kk$vmfxh+J{zz7=XG=5d&-tryPw7< zul~oRU++ByTd&g>v#s=2YxhseRKVDc$D5qj9(^8*x7;4zIWqcT?3Gvi5wEPb8&3aq z^k%?2ue=~h~de>ykTD%OyclnV? zb96wPNg|@FUC8|=6+(*i~A49pvKCs%fi>5zzcd@fhd~a zyZq<|Bt>41r_TE-?woR-Nu9XUP%N1}3k`##hksj&4`#Nt;^_yTFzKdEjw`=KjN2!Z z_E3`YCiCD)XAHH3KGiH=vTc+yxnR;<3_soV!pq^HWj$E8aXP9p$c_ST9c_*L-Wotl=&WCMrIX!jNap{}NP}gPY5m-iLkz~}6 z=cB|^A?*oi8}_;VUom`WeJKKPMSR@#*!4IsqmcHnt|%Wuy0fsd+Fcc(LJRD$AO;uO z`53Fx-{@bgJc_iVOEhsSDAV(BCL85ZRPNUNAJY z9Vw62QKm>Pr0aK?QBGF-zugwcTXHX1U6Nhb$4_coa;-i+ z1!O&kBdwVK++5}Qmg8;npt=OY!v{_$An}-^f6!fqvIkR4%G)HxCs*>l5AUQ`TMPaTP(Fyh> z1Nfd0`ris3REkUB9Pmy`o6sV!#w6(Mm6B~$H_;TwG{97|=9kv1llrK#V96YTFo@LO zUiw%y6ip}(4J}hC7pi=H5SpI}vW}_pU$xTBhRR$}MTM1ljZ9dmt#g(pi@HlpT%HeFi1ek=$^iM9Z||mDOPS?CY`f>}yaSdM;|E{iFnXN^9pOBVHxSZp+M5 z^7*uV1wM@AB2X?u=gyPuCwoCTuMVlUGFA>6@}-qD9S1G&fIuJf;@7V^>W`3K<+Rf0RqTBF zAIPS8D*@%p$SzC%X04S8+50DHILl;PVyT?ca&sfZ3rKBCmQOj(rFxvq0Pit;URMk9 zaB})QFK6{#v|6C!@-$NiSh>+#?zu98PB1_Yw|t!|Es5eYWpSx23N!+Lu}oUArH{|S zv>dl9O;o9RyLzn-m6mN+1>9(c1fZIfJ0lyTW(zJcuE?KlA ztpeNOc!D_xV>2yiYW)&V-C3WPC01dkbx_MqaJro^(D^Z zWNm~4zqOz`;45&0eZ5do+6gqY}x&f#G=khq?>72M(G)uCW zp_ZWv1U8{Ua|1;c$y|4Ns^OOr)jU`cRZN{2C^nbNlx%YrWbrl#YcDid>p(QGKLs0} z`y^gmw5v&P)35NS_qzD}Pfs`L#tVLrZyoS!3|V8S5v+OX9DJ~7Ft$6QU&NqkEWYr) zjd0d!-!#dGMvX>u>kQ0WtN3v-h2!@e4ZZvc{Oi~=O!*y)hG4{yM$B)Gwy~xhdICPT zZt3@j?-aj8b|sGc^o=GNea=u}@Tbo->AxK?9~b`S2D~*rdY!>}zaEE^kJ}Y%HbifN zcUatfONag>b~L{>)G(j(s9iNOdEyK9?D4^DR|MSQaU$ zuM+gf15T@12h~-=QD`wE+VSy2f52~UjNW`SeZ_hB^|+I8+-}ilswRHm?U`S~zYx7?WoW}( zeB3r3`yKVOVrw{TVoPUQk03Nn{sO+Y;aTSVv~NCy(Q7oLb$awBuyLP19(#YoChv7XBRyDIvSt)HXb?8 zn%E6%;Q#$PdQ;n%3Vn0*MrRiKMo#rEHvMa8p;_Q1Dlssxokh<^*5V@cyavZ^J|B-?7Jat$f)PK% z4acmLNMCcz)Wi+MBJY-|=KGx3_r|ku?ybk+$h{6Q>F-P~HQT<((Cz#xAI-GkGXi|vm~2;C zjoUOFt*aks8-O(JxVPRXW~&oj%|~}P&`}6+J9G}abP4d=1db==A@O(3K|o%C((M3V zcX@g$FKy2^X8^vBL;9U-%jXxVERyY0j=EA_j%pEV**MJ%^|oNjEGi1@6%JKZh;&f49OBm7KHH@t*xyXGGs_teK_)5ZN-r4Naa5L_sPawuLw%Rr6J@2 zvWEfO^H~Mdmv}13UNcm-PC)DIf{qOxf*fgt_YJpn1N_cMdw5prMyce3R9uTd_>?MQ zcI)hdjTxGf&?T{JG3GLDS>!_i9~Un>zi3B`DB4n&>65Ml3~g2!q&{#R?KYLCeK6%x ze<7p1J{hyR1_*pZXzetZc3e6eGAmuzl12Y$T_1e<0EFq8lo!H>lLe6b*GFrY({niT zTyoL2f!b}7Yuo|1-oPUd%Wag|-3xC7x5i6P}HD;H4)esMwe z>t-a$4ATwOJgBA1f7~R_OdVFw&nPprt00Th48RjlJZ_GYCQZW9rArI{mzi|&{QdW5 zmgy?{MkOKiJUsl1BXRp?zc#r)*?lZE?hqfZ|-)$nYD%lA94 ztEx*bMMxRzs`zg;wlaNEMcZ5=8_FiH1A`{boOvs_0@0e~;L&RBYh*%O^x3X?a~Bov zm=DIl7Qx80EyCP6i=p}sHpzj-?^J;appCHg8h|z|nK##5`(pIPpn-i*2NPHquzS@O z+LsmmzzQ@Cj6MU_w;TLy+;`0(DE3Pcao;5Sr45Vb%r$3AR0{?TYN?EOJfGT2`nsS2 z0|qqLJvz15oVp&9*TJG5{kf_@iU7Rk(kie&h08`7rHmro?8095(9&LZ#T>O4>`A15 z4Fd;65C1HQ^ld@IKn!S7rL-!f2beS@`4+#62d?}JZg}jYh^7!X^e)5@bC(Y^>8-wg z6283Yz<@oNh%@bz3XLwE+xsB)kJgYV_vx(E_aJg{^J;cMUx$|TH5K2qEy27(->zuv zXUYZ->{EVVjN>Incx_Q^Jb(To=#~K(SO|K#eJvNCkbM;wLh94L2$4ym@s-8x({qVN ziqviXvF)kGe$qKB<>ly_2+>cPU#PzLn_0cLYtB(R&L-&$ zb*S%mT{oox{C2@5LnyjieA2Pk3KJQ2{Yi_9giM+2nC90St|c*2hQU>nf+beKSQlcyMVukLyR;E~WGF=3KH=4!HG|qv6s3 zuLoRvVCvX(T>nY#RI(ec{^jK5T(I`=qiIgRIbJG*ywY{s?YZi~!ArU(eyp^`r?R=o zZ8qBZK;`XO_5-_IE9_XQQhw=aE9FvVh2*`Za^1>#Sw3sfQ+=#TEUiwLY$L$W+mL?F z(F4F4bDEz}jIi05EaN?Jg2|YBvM63p&6U zu`=3vzS0rv*Fa4B+E?+&?`|{6m$y3<8<~flDv~!e_s8Joehyv*+J@fdtl!|F&i0!7 z4@NWU2)zK$-1>w$9sivlU{dgdTBfp)uNWE{!EjN9#Iufr-u4!5IrnmN`kz;y$2(Jx z#8*~pVA?Be6t)b);1(igr8pC4EQiFo!?2JzB)q*sMXfSDUs{cIPuI!LMTv>*Fn!Fq zu{t7Ym$-qw&naW(hqxNiXJBL_ zGnuL`fQF`i7+l4(bKM=qekp?Qn@03474)S=u{t%B^mPFE#dD2Fe&VZgZa*|r)f=}u zAZ}Wfz^zVvQ9yjcMiH7fIT{r+Lur(1DA7hzh9(_b5)-~rp^GJls7emEn~6$ zmrpDFk8<0WEyaq4CN%YGNL+*8^wUTo9X(a#i1tG0+rw44%+6EdK8sxsaC;7EUnqsf zJ{UNpkF%bOe|(O{CX*g8xGA~60$xr|hoq1|!@ugK^|@6sCxdjoIzxM|B|oL*Odofh z+_|d{xP2+wPFiD=b#ruWghq}&^GeYUPEUwEFxU3zJv}9c5BjvlSxHLZ~jopT3>bqnBco`_IWG|FQE|=_-Hq;~12;OH8 zve>YWLRXNX%Y!O&4BzsJmh&NyDwjnmRsLJq5U8yh#8fKbU-%X{0T2VF2aL^^s&kT~kLh=d@p3JUBB1M|~A2pQOoLpL4R+zHsG~FUOzK zO8i{l^iBzRzU#4hYEM1ic*QhS9&Vf}=lqD#w`VD4^pw?ldSkLO^F=$UQU3HH{jq;s zR(=@(qVw{vb~O@fjSxLe^uJ2dNVMGiR!Hk(sP5!g#UU9CSFoXI#khh3@BM+aHKi88 z<+(ZtoH4PGNfH%CB9fIqe~6WWsy}}yK=ePcvGZ6MEhg;DaGAA`)*OK==;{FYA9e|e z{yfUutq?LmoGk))!^UZ=D=KlxRVP%bgH(;vR~Eo9sLcwI&M2#ngB_i1{%XHbaMmv$ z>oC7lw%oOls;Q0SK1C+R(iEr>3Tf6Z&tG3SxGOsru|~WspaOY{f{dA?EJuzal;@mI zhPpIa!-HBKI~i9=aGu_d0yx(YGNkqw%xz!AJ>W&_uzV2iqCz9Vq)J436=k(fhUGAXvMX3`WcwdEpT%2Rpr6~OLM(XjG|D*E3M7l?w6ZTp6k?lRSw_i#V-z$=6ZH?g8>Q zYjq|hYhsttXhpJiO5jWRfGMLqT+tI48mS&v$CjDOCqeQW63-C6oVQXL&O`WwT$@j> z9IFtdFov77l5!|QQ3=EBbn-DRBvQ)LlGJK)>L#f;lL5%VkPFlt*?C~vgOD#>qbrE! z>ey7u(Y|)b4cB{(_?pZO=DW+LP~+Pb%l;iOa2ox<08te0}P=CW)47+c)--ec;-XLMAE$)f+C& z@zCD3Z3`s7Ju9NL%M?OF5)Ja%!$Ky#&&X}i((;%|;=wBGq7yo=tvp5Lkr85_B)y=> zGGBA7qL38EX`Cd@;byI5RXD5EiBNtL?IR1|5r%Ax>eg%tRXwOB)NzhxKr=dsKD)e5 zTgRztXF}|(%EW9Ku_J!))3_|eD|aEN{@CoB|7T7&Lq~#(h|5A)M=5d!q1Q}ZSKFoX zhSAvKGY6W}wHm&I@oTMyKGjaz(7=G@`L7 z`s`oQ&+{@Ut4vv3IQtCPZzQLG?YfnHm8hK8PnSie`wA7g7_Bc6x zGcjv;!S#o9jgo%_WS!;s+kHd($t52*cWByf6L9yt)X&;M3!zSqt__!-OY@Y|56R6+ z^PED`8_n>u+tLgj)pu!L(DfPTdz7OMFf>$dZhlI2B%8pMyZTy^rDucd?Rr3EEaS8> z%QI|a4V)15ov}$mBr=V zxG2wMwS92SahKPiawws^6YWHfYT;ATn1)kWJEg=aQK?<|q*a`j`S}+*06&GKMKvI+ zG36x%QZ^k8_P9JQ=(BlnZGoW+_k$`y?^?{+?fcsC1*B34!kGq}4j!JN{Y0S3Rf z-@KMwrZgU0eLCOlbJz8R=qc@YZcbKsB{vA|jY2J0Wc%%jNJw6Jm^b-Ke@bWZDtZtOWb=9^C(FV~#r8}+b6-2sxoeKuv>ZJI*`+xdDtnHV1#9D*?Qwbs$0<7K8jVh@A<}qQ>XSlP~eItrr)Cxgrx+gh8z%h+LFEy#~(1 za8Z#&OWUGt_#j1KK1;1K@S)cmQjgZn(Z%7K2sV5ni#_a>-}iFUI4W19Hcj&Z4mYh` zzaC0UsZunOs#8}fEy^J9a+xQ9H!WNl7f8Cy7FSB^(7vT10)=GS6jMfnPM=Al{Yq)I z&>qd#j2v0alTS`CZAhUNELrXUc3lW*?U9SR93|v)vikVL(-v))UYpd8)HVeEG_5@} zS>0ZoryOZ`__%b7lhZXXIJ@GLg|-W%b&-QKSG0#FrlWPDyx8(hV@vxZ)xMCH=0=t=&#?+3#8^s(JLTzMDR)+{ z!}04x?bGgJ&Zi|yvO%`(3IX50OYvIi(D5HW)^lfSk)@_2+DR1z)~AIS%Z`TfHP1z$ zoh@Wffh$_%y!1){Cq|VbB{eJX`U2ZZ+?dVKZMuq!spXT1i~t=1RsI8i0AB^~r02Ci zI+d}pP*>gokk)oZXt+h_1n~kPt-Rt>&eyACne++9^2190Y2^v?VobpaO| zSJCB_S)P8gQ9$J$3ES^+COJ+!_i##Uee)kEfBsjhW3T5^<@VlycH}F0E$_3PTqrHs z(dekiPDq+x#miLoUFZXYT%NKtl*;XLzub~k!9P}1Zq3k1k)Ia$asA1zF(9`owXFp? z>@z!m0_TyzqqjEHTK0k_4M8j`$_Jcm03)Yve^ z+DW3=)9M7#mD9i)^+(#iIpO&9p{JrqrNu;0L2zs3G*#6Og$5^$?(lYVxZ$!-uBe)$ zSqb0*vyV@xrk&=p zIcd3Yr3fxEaf#c>QAd@qV+|s)z0ims;<6w5k{;Be^jwp)KG!z)fLX|Os26sXiJ9V(IwAES2l@FiyOC6sA_ zHy7b*p`5m5*Rjv(oZpU z9!E>{TZ6X&)E;P|Jt`wTr}l}SbA2e;S>N3A`J#O8b|z@_K+9Z5sa{OOc@nB=U2nAW zhqdYj$pTAJg%7UCPCMG~ap8NhRNwm2AbnZLghtXz&K+JYAEv#|KNCsnQO9zBT|p zaHDP8d0^-za8sFUI~@pWmL71M4O+)#ekIdDO|BB!lE#+nJG&iflBIqJM?N zoGhGPEAYCnA-i!2lKyZsoLtGa!fl+f{_jcwQDKaQkfl%LjiG-K6ui0%ZNAgu#BDgaBy@N|Vosj6ZsFLFBBd~u=xd=vr)9USys z2K5xq_23ovBnkU~m(2rdIz{MQ=f1X9hH`ZlYPd9=_?y9qt)%(7G9iVg-jzzMlH7(1 z(rf(q$5-V>Ngq4krUhYISnMchG{WseQP|hV@1j)pNbH_du=Pxp{;EXHIM06HBW)8z zZiRGgq6N97>quS!&qF!#xCl=(d^M>{%ek^pKcpGCAk?*wTp8C6qmJygDn}UvTIqVF zYqI+pNROF=&RZ$xv*+6N&No^>?hw3q>lbYcz$<3A1xk1n2kjb8_ z+&R~-B%2McF2@Vt$3pV2F8kJf&=FUth4T<_8t1a^Ts^Kn=QTClo~m|e``7Od8ZG=v zGJjaBUa-fWS^*&K<*5bYbcM4ZV0eS6C+VFlEk%<5pS|koV#dnbgF0;z-$NFgBw0wg4X{G=BW0tt{pdO|n76M8en^kOhzY*UPl?dR_I^xtW3 z@3gZslJ?%+Yu*q1R%J9ANu$w7ySK|(H3(_0mBGbZ;&0PZxoJO1`C#gh_|tjrY7e(E z(ecjFgFyyUGihbGU7gAe`-+mNQeOO@A_`46j~qBhB4kRtmMxpk*GiXjM3+K4Y+qew zlFCEr?J{8ayZVBw%jMj~X>{tlOf)UyGW%RPsjuNlcl9?lS+1o7NXkshQa)hnl1#46 zlj{SQKGHsw(xh1_wbwNk+?;XgJJm16Tsd9lbOey~oO2uKlC2=O5#Z-31U{4pr`s;u z!S%fs>H||Btry_?8x9$`v9NiD*2n2QJ@`vMlvR<&UI`+~m~WCZWj>HU@;ITo1{!)2SY4foF~$4$jbVG-4vv4xi=c(y3=5S=>4! zusZE4C^g+(D$OA9L9M{*vO!k@LGxZG%Q&;aMYNwSI5L;Tllf^E|C$;)?Mc&O<^DHo z$0 zvT-P`xW=&CLxt!fNZqT1d?ow~;pg&@5XeVH7j~i-t_>0VVfHOvB&-1W&0*lvdlIU! z1M!@$%y7W@hAr2UwuXS4i}VaaGx=pT)#>e3V&_y!OsJ;feLwq0UiKAMeeseg*$}Q> zbgxh8WDhp^m=)En%DGFW<&_`L*}Swxk8-{(PpW?*!>6V?kWPX$o_1QC&W%G%rviAp z^11TVb)q|K#n5Vohh4_U2Mj$OJ6B)RK9kZVT?Uih11)-vjNojSL}y=Po#&QN&6MTl z6Foza%KO00J?)^C=88}6wIfZMtNh;2Kc8t?sgGTD+%+aSvLM82X5kf&KAi#ftg@05 zWo;fDG~r(dbbxIWa?}oz7sh!JlJyGFXK96SSticI(++;rYAQ!L!0qL5e0)~lMMJ^0 zjmEiM02fAJJt0=UC!(jz-(g7G3S}ip+Z5TQw{O_f+fV5?uc$Id%H6(lk^}PQ2aYll zIJ2c3`7~_Debbbh8HsO5ol?HCxNFF!K?}0FAem)uT&Q#E>I+F0X`H!Dft1Jbr@UOt z1g&2(k&;f(`lPx!S+qdUU43&$s@pa1vdl9n-_<8{E^sde8dItFQCr1wkXDm1+0FC>siOT{=mCy=1 z83ENRUk=xAS@~rsThBSEGjk85*Zwjo61K70$%CU#Xrg2oYYJ*T>3pcZ;spy9AV<%{ zf(7#fDY@0R&Ni}28;jzhu9^_oc64`?J^Si#|I|D)O zi#n$x^V#T7Z|h5!%En=U-%!^OwX=t=oxXC=^ghhbed02DdSB%Gn;g9rJwdl~8ACz+ zVqHZzDxW?Vpnfz>@1VFY*WSm2b1jHiWq%wFTFzAg+}$Q^MF4l#bfDYvH*0k!=ozU3 z@3hl%Rc?;hbehSdb<%WA(lsN83Xn@PGASaD9S0+u3ywXula{vCxABqqY9?Q*C)Cj7 z=w@(DL{0$!I%({;VkNm%CO}jo`OsG7hJNxbD+<&^=+wGGrxl%|t`@qcRl08X+9Rb) zJxa|7N6(ot&a}|53!JR(QB9|F{m7YQSO2+8lbz4;a=Th-Svgv2+9gOn46V+{!@K_vL$^EGa!Dxisp4T>>nl6 zkZJl~HwN{wm4{Ypp2WwM&(U#p!b9UOl?7BvE>EI&(Uks~?07SzPZ+R*E{=`VVO>`Q&E~ubn0_($>Nij zGm|b^IG#%6oUVuRq%ue@5JwNl=9=>rIC(j_XgLTp+|rxS%M>a`29B@I zkCPoj9<7JwOXCL*Z!YfRMIkMbwtSM#XrT-zS7^UV;{eEg&C$^IxOB#*1=3^WN^|L{ z)F(

    zbFePEMD2R4C&Is*(>^X`xJ9q9TnVH6_O}Y2Uerv+R2Xnrk@R^URLKZ`CUE zQfYd-pA;*zdmeE#(wxoF3m_Q<*91-xN!BZdl&6IXI3Aq@MXs3(>vU3J$&R4jy%jv? zGdvs-%3V1rvgrzEBQ+o!zYf7Cn=}_(*1A%T<_s7xko7Y-uAGEYIh!tYhKBeuK3@P# zS$N{wQ_dwT7nk^kmZLlpvJ@h%t*s_l9J_L|Ah7*rP1iVg4l)?F;3=xCzlo&qvY}#S zc=}0||D;lT2;BChDs$IC8`-*~6$34u@2ChayAsaLH@i7hS6fZsGNi;fw6-oO^!EUs zk7PJ|I3gVzfZl?{XYLT~R2fgEgO$jvIyPrrtG~5z?!xKRl`!*jVDHh@?tr3iHE>|Z z)|hS!mrunwoMK-{+Y8rn$JNgr1pxd8qYBi*U&uibdR8OtU|c?ubcp1uOX5Y#Nbyjb zj>6@9Ni^weQLl^W?tV(^k|nu}os8aQ^SZh{^WLAwXYd<*FY-5Q)eEi@$T(j!d7%!5 zhP-ZMaZ=)wWWc)tXV*e)@lb@G1MLH;9~AgCJd51$$f21q1(mTz&S1Ait$mCh0ha^h zAME(%JXNan)YN58+Da{Qu+_`1Ri)}mh83HWrl;!e<4dOmm5+lor6k^*IdRDa@N#Il z<>RNhV(F+1l2*{Tq%qv6NPWQ7O~+3fL+z=LgNED&?V#nxm6qYmI=xCXp$IiqKAo`n zNqXtxr#wfrbR{5DV0$F!wO=5zF%9r8i4ywrW5=@OmGuF>+` zSn&2K{ZLlrtyyVWDo^FFBDP$CKIm1J#}a~jU@QI?)2UL!?H51L2fHegBzcv~t27Na zf3<_3YaLMFb&lhcqZh&+czQL^LMCU;z%byfk!|g|FQj=<$wj6ns48+g1={7Ex#`(# z8quj#mR=|5DTPA#3YN5UCM-D*HG#BZYNRbLEyI-yt4-ETSsFT zw2t1q709`x6x{>%np*+4)O(?rf1M1@d*HkgSAHezvoNj(hgdPLgIwj{C?~L&8XE@{ zOktuxdQBpq~3=x7+|OT+XORfC_DJ!RjJBS-Ipwm)Se%thBZLH@8-t>M~yaBGEROO>Y%$9t_Uor@Im>tnD%t9-OLI z-hvX}hF2w8ExMZ50|^9N)#b(FXipqZ@JubU%F%-IkO>ML)=tu7-`LyXS7@(JK1^ zEeigvT8fmZyb)0+(khlXp=(xzeszaFe5Ffix>9wyT!K&Ok1j`0R#Hx1LiC7Xm6%`L zx+LkIYhLB(0pN_CWMI96t(kvzMUr-Av7DWNz-r}rrr4m5mzWdy<`=ql)eG8}ndLz( zPin0xIBGMF)WFrvut^>u2OXFb)}waQI6sH;7Xi0FPrFMoe3T#qH8 z7lqIANPIZ|#09#>()GB^H})TNx-K8OZcUb2!;l3FsXJ6QOJC?f=IMvPvT8wB!k*1? zdlf@%rw3O9q#1Srlqak_VVC`g^5_pbAe2&`nrW?C;Ncn}7jH=pM>W)lj3rXY; zYtK$c4~5t^y5qkA~t8Y{IG;M*ygQHi&!U+wzr@uK7EGJ|xPp!~qp z=c3n){5CJig!{&sYaho`(hs}5PftUa2(ArT##aKjyoWA*F8dK84>vEkF?G#vUq9Jt zoQ`Wx89J5{J(bTDm-tk4qVndf`#s!40}+ip|JBbEyOY6@_egFoagcux(ETH z@Di&uQAes&u1rtaj>3KwU=TgL(r6mdsZ@U%uuL)`Wy@;TfjS`1)_JasUl>Jr%IhIS zzuu@5!$E`C|4$hKDZ3n}XYZH|Lp85d3{VsowuF14M#gs{{;iZJ~ z1Kqk3PrQ{AN%^zSj#@y6kpz)xe%c4h5&SjQ42Hmno-$057IaroP2;pMnZi*8RRPCU zO6y`so{nV0B%t=h8mgtq^pNls*Y=seW!*rkEXli;;!7<21aIX?X}x!r%R`q zKw1V@J9G3hC`X#x=_w!MDw{%EDx?$X5vfXW))oV0HgvP(DF772o1oS69A4;l4&H@TcYR8uGAk=f79)Pi!Zml zgtS2;-KVsyV&vh8#l|PoE1yNQd2w&qiYStw(N!hd zI9I3jxRgL|pqhWBa9k*UNGsJp7SqIM6~WKnWV@5{0J7dyTA3^hCQlmg96c1Ak+Soo zGMQFHsWQsPw{mnpsF2jaW(D!;GF0T?*5EW`DlJCb+_IJl1~qUsLFl+~-U@<+(Vn;h zSfA77Gf`gJ!`}{b5-U=NtE*G%C}gB(@} z8edqlWzuLtNay0&)+z~Fs7Z;nCh2IpD_`O(mGfk&4F3Rs_1#QQsZwoFm7Y4(`xTa*TaWF&EbYAN%kL%r(>nl9q)WJsh?I(9=a*S?JD5@(nao zhEtx9-Jo=uN#*5siQ2&zOc`k(q!Bhre11-jH4D8=4|-~I1phOCSStj|a}6oyIz5cR zIY*Mc=HgO4Hg6w4jy7cD=vuRY@O6WuS8%U^(i%p?HZQ3kLLI^0ie9@>^$ohKTm_1m z4D^#&aaa=`DnaX>u69XIN?M+C+oUN=X_Dqli_@LD$Ud3ve=2~77OslnN9zii))bt( zZ>RhE07AZGQhjmGh3EFVK03PJm1O3&Jjy{6$7#J<$mhnMwgpUC8s^%j1NhN&-`K^p zAtsP+>+F93zhu(6%*jK`adW|rOQ5oWln2T8=_eq!iPq_pjnfUlJ+{8M#77}57uROj zJVK%@uR)b@(dDa3l#HZErdQStZShWyTlzD*#hZQ7A-S@IPxWOX5Wg)W)yJBj%iNes z^N8xG9j10hDod|9dLVp8jT!*aFmtO7wQ3R*VS;oAWDreNof(4IAoyjdeQ%b=Rt2uO zWy7I;97#l1QN}J8W{FaEGh{)n3Ak0NHda)5;+!PPk!MS4kGkY{`dXnFI&K}OJVNp$ zpUAiNar~*AG>!U%A-+wVPV++NDc4U5jBln;dEi@HR#zkZZBlgu=bZ?!mkTdXe-cj= z{z*h_{q@qO`ntlLZxQaOny_`Hznfo`Xp@msbkZ`@IR?gwI!>)xy z+SX8)PcwBYramw-@{3K5ZV%;%Yq)n{l5&FZpgVd>rv!cqZvR|TG5+AQdN*BKg#eS0(ebY)>l{LHH0Qmif z4?efemmkNIbSh<%xbk+MWQr6cOX$?IM@*`daZj`XZkt)1di(lYi1|2l#%VGEjPH>7w-l{IU)~ zeyU4=tWVPX0x8G!iH|0fKc^QQqQ_Bljm8Jw9%JI)t&K2imlw@&(Qz9kganb

    x@oDVlP_VjI1N5Ph_o*)G6ssV&}-wo#1jjCFfi+X>>YP3zzdu53zI&>&?;4 zKo!unTXgN%BtDdeP6E2-(K;j#h}%hOrXH%yQa!F+pIv8;97W{1P)~&Xl&kndd@XGB z^M|#vLJMhGPQ#?NgO=msO5i8iUFF~fM>#FjZRc~&kF*}rwZ|uyCcNopG^7u+Y__`F zp0caZYwWelGq=Ghi%a<w{LnLNB=IVQ@>#lr`XNX-vnKriAl?S#e^s0QVaMlT$xNN0fMQp1|$!GiR@r_aL zb3~~dgxX588X3POgKH$$msGF0xyjMRVc*=R5g#LLAns? zKX7T%%(YwO;>npB2t2d+jS_zic^w4g5lHEahn~yhET-f~ht6TUk12oZhuE+m61U&J z)w$q2TY}8YA&bBc!ejuH=_&N>e|n` zberybxH%D`S1LoQTX{leAtRAAnd>qsWGJgXl@cVB3F-hr4%-p2uQ_t$h+t2hkolp7 zG|8Ezb#R8)X4PMQBH!O~cbETbarS(P=|K->qWDshTFIs$$ijrn#mkSC4Y= zllD&_GSax~#)8X@w988-OOl1F%cjwgZ+y_O7HBy038ZDGb6Ig&OSi{^(s9cy zS3ewdROjt0SDx~r?UMRklFKy*rTRf+=4>b@ujFRgwETGL5>3*+M>$DODiNxD`Y`#1 zuH@V;%cYRM0b05mE{t&84b;RNwp67BIw@dTN|&AF=A?FnePbledkFbCdLT4&Wfg!X za@s_-(_R5wn$=AJ#6Ua05Ga-sQ?s{A$(CP{NhUz~xah1W!GhDMMvPhB`R&XY-+cA?*uJ2I_}${pVUw zRe-#-ZWHH(LDF9Vp{?7LNFam#&mfRSyYbalw7!ppE84S_)wLpG3!)lu`X|BGFIpyK zKGqgg8g51^u@nSK1-_k`#DY+P^5lo`%h4^N!0Qgx%Ib7W(pcB5Q|`En6sW7-sYHF! zYUN^pIv5(kS#upi{9gSi|lIAoF>JdP)&>6{b89GwDga&SsT zKgIS7j(1e3dq%v>HD$~njVc)-#9?W7N;8Ipwtww9b*F(c}JbiPXmIu;q zoMZ!N{oEMj=)vF&A4+jWt%jsU+|1=PG{lm3fABU+p{DQ|e2c6uAg={)&7Eh zcG-2P{+dT85KXI}_4Mfgt=VApTX^`oS4?o-L-xWZ%bvy!cP%&ZosZlZ>owSAS7GKo zm*cfj$C$Le$F!JV55^BNw?2Cvu9&$QK6=2J;a1$WWFijRaa|K{AbrG* z5{*l~H-s`;;HLwxF%Qa@tzR!F^wnLapNfe)uiKEQ&!(qu&x(DKm@r}DEv$U;3jE^! z(I))G6DDC;ilz+1AMYi+Tci64Bxc&yil6ws}B{?^-!RAYDD5;tG- z7~a!dOM#Xx_s7R4k2Gb9cG7C(JZV7Tgq%khf`;{Ms0=^u(fV=hRSrIbrg>$X;S;hJ6P89?P# z?eAgQ)JWf&_BHKBLL9)&3*3z=>6P5gyB zZ^8ebdk+okk2mps58eZt4Jp{0MbDY|&DTuBdr0FmpE}fBpPYIVo?fK+HWrcxZFdNc z++;Sczy2wcx_~SJeYe;j$4nWCM%OaYrO;UX{LQ%LvG+Ot2Wv&n2^iYDPph$TB=41A)?{;RJq@b72hTOV*V4j4P6roZN|ym>MC)d5L4Q^0?zizwJ1Z=ie3o}=uPG45g)td^sTGZ1bMzD&w8gJeI z9}~J|@y__v!JDInp(&zB7t<8cf-XXA&;DJqXIqpc(MvJs$$N3nV=tK=nA@r_WXvQS zbWqg(4f`&}b2nX!Y4Zf7Y}pd~e`GR7Hlp*OJl8nPY}Iwa7RENNh@FcY1D}IT9b;*Z zR!m-)+|uDzRaj~MzIeqiaR2Bp;`5V+nfU6bFU3jMZ-+~Nu)m29?K-C^2MemC@l`q% zb@`q#E#TjYaX!4Q;9zLM@PtDKu3i_9eBoO&k&k<&>T~70;M>&DexYlStNq-%2!Wo~A+51F+~^VgL2tTj$&7B-@pgmE+4zZ>g*#H&=&L zmNR!QGb@`!>6k!nD_2T8cu+oEzjNlD@(VG8l8MW*ji55R`hk{rEpt-8y2cF*j}SRr zd|=UW{H3}nZ=Vjj+9Zt=;MS!$?rNK>KHnUob-COQ5L&5z&W2^FoAQwQJSHoSGiZ}Im9pE0ptwG`ICcV574*S8v?O^>KNtQGNE zjoA-fg$MM9Ol+Sq(Tyvm=bN?j!OQ=Pn_k@lqjufer0+kxw0`OZ=KB0?_h9zU$6?A^ zl}D#qhBcRm1MQ3O!fnyR7p-HCFb`|lZA(~_LY;AaMHK5S))(I}9yn?(y#CGKuzL{7n;6m-Sh~P9zU!l`HwcE_(3hrq}y-e zYF>M5>^?ENc{PABGJ4+saPdV?n(&w-_s1c_mg3nf&o_n7cjmH zc-Mr_*<(knx6x?yO9;9GFJFI&2|hV!Uwj8u?ar^*$-jhYg3J!7kux1 zeDl|z!d5M{w0^4GFW!f{3LVw7?l#W;u}CBCs=9TL^W|y*i7%%^^@B89n6!c&dG@B; zOiIgy!_324i(ZK0|NhI{czNK3IOm}COx)Z9*DEpWq3B_)XV*FsyR5$yPyhKW6aVdd z2jRpI9{}~@wI=@a@6X0Je|j7?ZyIdkBSw!#|AZJt-Mkq1^id`@bc2nt$#9MKx9>Ia zKTg#+{KP%6enYgk=s&EbV9s8|Z8y#^`BP5b52G3@dx}15_d^5MbXQ#R-MDyh@8X_6eIGwv@(U9`w=izqj{+N zD6c5d6j7ur(v%<8D%`3WG-5PH_e&1iikGAH?UE-4A=Q1x{;V*eIrskwzx?OJn7eov z6W{Wv$)yKiqK8pmz3LB`Hu_YYeCYcoe$_Ajg2&GM8g}kqTW_$kCb$%;k|Q(n5%}P+ zezi7?YasNJ8Mx`fKj49WQ%ronDO+KOK@C_u=S360`Dd47`F^M3Yx`|v;%3<`=<4i( zo)%Hm)wc_}y2VlQ!&)n6PQ}HSTxY^BY&8nU9<({=@?E4UqDU9hlr3{m^srX@TX*B%x4n;X`yF87I}Kcdm#+H*&U`H@`S)*(E6o3muu*am!OGJ7zql~} z_x%XE7Lqeto~x0KE5g{qxsi=4!q_?A7C%mNIoK{a0NL!+%t2{3f7jV&cT5~M06BUJ zybd~KuU1kvj=y&Bv}vh=D<)4fWgyTgk35~{q37tX=w(h%m#ecNfO6zHkbed-D_kd- z_Q9=9t4N-7QU`_?1fH%%wK-&Df_(`Tp!*4n@bCvqq zwU70gXGv~=-#-I z?qt_k zw@~>|<>U%le|%<1r(%-s@nvvIixCPYKjdVLDN=x3X zk5Q_NImf6>jmjqwVU?$@nPMc-Dftv5b-G@cJE(;`sh28dLOb_8KJ&rR`^=;w`HCs8 z0(feHFWvXWxt!@yLOTGr8REuS>MtoRbPU1B;~Ha5_gwp4SAWy8KAmvwskt^~G3%~< zx5U%8{Avds*Uzpc%cY|n4{2_~;zP?&UQ#(pw|sJGxb=Zs;$7`f4mn(X&B-XG`{I%g zRNAD;`e2upwKF-6=|{a%<5m)&TyJrSQAj=4K;NL1cwmd8iCM?|5^{y>F$j$W-<*>2 zeY%pPo5D44RFNd5PY^&T#4)pZgsv1_fDDSQe5o0lshq<2ZCBl(sh8_5kRc}vZFsIk zZQJYGgBvRy5UxF>*=Oe`q*?I{uDed-pdXDjebZN!-rJ#)JW{h)CHd*O_nGVM^AEuB z`#pj??t9zh?|a1h(XR_jpR)U4@%os!_deKrExK>haNCv29x#@neeV6``idylxz7y8kHbu-B-h z{2$zlhyF6rgpb&#AV>QgJaF4w6W`;6v$6ZwW?<}zCjPOdi2^+Pj4m}9h zVVm!A;2lM}9xf@OBk^&E?~T^KUyQpa6yKz$vERDP@0wRUi`(y5-vp1n`P9T0?zl|nhuZ`?9jSud5$mIQH;t|+qgGS5XX{?-a zH7=Sq&ZHeVWhP!Qlu?Tpz5WVT?sy#b8$ZT$LK8N@p?lwe+h#;-MVl(US&MF7L)ui! zPSue;oPNt=Snq^0@bQ0t-^AZ!=$^W@K=Zk8o9M^>^8?IE$kiVkP23B~?)w1uJp30E zoOs0Eu)EJ>8@ADBGjDxtJ)CgH$MNs))0!j8(z>`EBR5n~Yn|J0DkWe4few#O8epx;owHX%Q!U`(yae58jlkSuq1w{r+)mcU1J|uGgOD zX|68N6o;`$$I)~iG*-;G3Ku=TorxW_%WJU3X&iMZzIjHn#F&*uo#A?VxXK&pE`>!4h?{HB*+0OEMLFx2GSB z-aI&R+rF4NZ8~0C5cvzEcGw*|j~Pu_5oVfP=8CHaBuz2tQr#{(Nf!ZmIdPc*X?x&mr>nh^9Ija{%`Gm@%@uA;X+2Wk z_;ds4SbMoS?9yvmKOH+M?&2Ypllqm?aAl-<%<&4PbJ+lz7W4JV64Ax$Lqx3^4d))} zO4_i>I+3z-g+G#C?o2N+r!?g^YuWWEs|?&@=NfBQe^U5#!ZoK{8v6PAw% zgxXQ5V(7amx>K+q+=S46SSH%s+JXvD@l?u6C9on~UQj@!)2i<^=D zp^qZhIIM*{36gJ3dDuP(9BEV*%`l}r+h#wCyPsWV(#C8y3Vml>k8{5FmWluHx5r^q z^#LCF-M38q;`esJhxZ%>ESP7?E?iZ(*Y(DoxcG+XX624MjY122&{+Cj^zg-!^>)H= zTdmsW;Ql)oWB0E_pEYVum2JbDw_k%-cR9htzEOOTX4PAm`DXNR)sCY}N1tkNsXaq+ z^{a)tb{-=PNE=?c>QdaW{~jhbVf{8t|L>W&>z(McYd=3~6dD#hf(uTMKI61#?_;p% z$kmu})pt$&x@W$LAANFb^ly8^^yZxx{u>Lo?T=xlhq=bC+YfDTTwCa$ai#v*2tyj1 z(XVgcQtic0I^BXl-ZR?7zq`jy=Eg16vn&X<`H~ru962D!Y`Jv0)>hB=P@A&o%nu?q zJQQC!?0lSaY4lmb31{tvwMZGgdKs3rM-TT6h`+0)qWF62_ruIL-T`(ULrO&t$Gmw* zq?<-B89`)E#}#vf8}BNIE>$LLIfJ%YxZ|4W;n!VG_y+8*(92)Me=dF=yPq0;W^#k8 zt}+j6>C!+BAHN$mxc0xedP?+g$06&yiYsngh67HBK4aU&3FzxAX+s=BUoJ$;NA_jX z=e~hSdLC}krDBwCfo|sl&CaEVU2YEO%(hv#aJMz z;tl3{ealC1&dvkz#m?Ka=;qs@dGI8B z?i-U#T+h3O9|0ZtA20s*4|rksQ*q|Vt4;js=hJjWn&%5NMHK0-?!t$)^s*Q6-#@%i zuxDqQ_{giShEtr?3-HX{4`bzo&zR^2j7#12<{h}^ReAn*3nWa)5Mu|6nA9HG!ZKV3 zP5?he?Q*WEOC4Y>)F*Xd%&+|o+;RQ|Civ>MJ7DkKCt|&p=waCZo_Qzc{^A!ndQ`l= zUxFLP?TDR5`Mum6y%Exy!kvKH$_b{NE6r6e7q{s+-XPa}E$kY!VfO$2h`&9$j){%i zv@hn|axIKFmVdE#JXP)r>*Etod==v82xvh#n%ewSX z3H-EhwRxs%k7J7Psyt>@xgym9O-53ed8=|bWn&5f_F*fX4AV4IgT+WOle7HBEo)G@ z@#1WdWXsd7=Ixw|my{>fk)sDeGHk3y`9@x{Ha!R#6gs_rt299%A2BC@N8RRNrq3U` z$6K=z4{h4;JIhH(*g27BM_^m!IPSBu^#!+H+nE)qqMw+2@a9Y`8(p}8L4M({--&Lh zo%OL>(5!408Y`Esz)q8`v{f(S?z^K09`-qB6q-gfVV~x6O+|OVd^9#5TRgHFZ0Z|5 zt{u8g!#{J`dQHiU6U&%unVa|sOwWe{pOKYTZR3jTUJ_sis zZ`D1eA6~lsS`(hJu+SfiZ^J(yjUG1o(jSkb+zP&MjgsGQ4jq7e~z@h)QwTbstg^^gX1WOP-{4}6B>EZMp*dMKL zFM$iqJADjaIws;*taaysGx3@0Uo`Q?qef!Z9skB-<4!j5OOKt1eg)RMPaI_G_{kUk zh5HUZ7Y7cF^rL;nYz)}<5`1;a;Ib5}rX}lZSbH1nvG+DndsfWAf391Ey-)qLiI3|S zJA{d5WI|98m-0}Doy!CK8!)Dr&!?;(w9(hqZB5wZ$S>pIZ~oAv{_*~CIDNO~iXg>h zwf`0vKPGxO@0MF;V5z0U4FE!U^|M@4p zx&LYScbftzo3 z8g)+XeCj+X2OnCWx87)TGvT9O!ZBMH{ekG=!hthCgX>>fgri3dM2;N1^1CKPoaR`M zz?}zB2g4P2@s-f|9(ax-TCnwJ|A2p;5ZN2OdqV0ec}mGYABIf)PMf#iX@PH@m#xT z9c&IlO|LYT0KadPwNvf` zu5O853w3kw^^tAvL;9H09nN%Xp*~uc(-YcXoPKcS;NWAoldFU4b1I{28K&}59$Y_i zvPgUZxo^3$6u!RV%2Qr;|8s51qVtk|Q}>0YQyt)tY=dp%<2PXGR9;L`d5@yDXyco| z@k$bh?2?YY_jJDW`9r%s_BAe};);>%BU>iB95>H2(zXsr+dgi-O7lY@-5-)2$k9!~ zDT~W!2hVs4swJV8stZwT5j)IJd3n^WXJdoK+?3E zUK3f8|7;n2O;qHccF@axVNE?x8M>bPz|I?+t5*RWH3b_jt7jAHq|;>CxFyrIyHu2& z!P07>t{R$wAXd^cENuo{%4~;Sn+T>TCqiwYGNhKExqP2gu9+#dD&0Zu_A5`kb3tYG zjiIw`I!&WuwC6 z`+xii+*PL6SoZWCxMRUm6CZcY#hBgDjt^EupN4wo&S!A!Ruj;#c{3xxhrfLej;M%( zw%Jp0)>r>#Xdl?^``C9-QvQg}{;^FvmQBCInq}e6D8oA(zJT*$?CTYopP6 zdd_m7aUot`8g=rfZH3-^=Pk_HXe%?NH*T?dMKjWPOs!t>GOqaXA29F8vrYW;v3*PA ztIXe*@3{wq_B{t1Hqw&O_|3cTYCN>%hjGyc7C~b(n%bhzUbeN{y805FN zdZ`iT#s8d-`?vWrel{U`b3+lgU;oLU@$hyhK{Z$vHH^d|r+w1|SN{8-_{q6#SZmvee#afx#)6@P3Bz`y zmqk2GbyEasY143X*=V!PF{&}nR~SC10V>rC0lt1B4-Bm>2Y0xpg*>S(rTq4Jxc8ce zu;qs@GSR3jG!{P@+3(BVKOASCuwG%-t*#UW5I+jCc>14l&gFe^(xq3J__&qR@UP$f z0OvKHW8!BYv;i80+9loTwAERa8zYl|&=4Wp=iQ5I9@-KgzGwpz578uF^`WE4uR`e1 z1S}UVSDwL+)pX)>`i)Ljke-VV=11%Eu<=dM^XA~4^*2GW<2Ee5G^1@1KKLMdd&bB< z3hf`XV%dP`%~v5Giz~iW@NbvBZ^DP4c>+c>#@;}Zridb4OjE=vbOoqA8&R02vLp@b z?T<75u$Kw1Xnhwi-Subu;>>@W_*uU?4x3w@)RFn$>EMp&+nF?*p4vU1IiS;4vI)K= z4MMoQ=12WKYDDY_Mm^uRUtg?V*@hfB-0&%~Yu6|FUX)fl;H*p#?s6*zy6+SPjOLG^=VHx>!Ns%?mYK!oQIkf zXW+mA5n(CObs%J?hnO83J|0{=F6Y{I!c!(>gO*`y&}C?CT~Z#au7%_Y37fbSjc?=; zn8(r5x^iSe>ylOs9FV`tmBX6QH)}>4i?60ug?4raTbd(>2d@26;#Er;iSOmn@98DJ zrN{6n(?WKfa^%QSJ=l9*^bWa3&`)o3IN{nKQlw0ybwkUyld;1pMd3je_oONbD#%86 zNRvnhRDEP8972e^G*6+~fL|*A=XJvPbQsdT@;FJ6IKs~{LYC}~oOdWkq{z3qxer#Z zSe5R^iVeL)%KMS{>b_>C>zd?cv^? zWVe;RY0FMaKh&jCyeOn`3Zo;1FV{1 zE;nC07yEo==ftO#RNr;5{_yCNneWUm=*RlS($NjJdGEZ7^)^`>Y(JEEG&H6^L}2%I zpT5mlwmfQo@m^$f8!w74TiO@>T9TtuWGBx@ZT?^Kbo5!I3!c~+r~YIc4DcyM6%$)5 zCfKRW^(aT2E}$-Yhly6%$Q`AV>3z5QhzWgV_pjp@mpz4#G$v^q*WTV-k3MC499;~w zzir~zodImV*IG$-1>G#_Wf6N9baRNxE|cmv+FZx)wmY_I%2Hkl*AUtww1bA3ES~bK zX55UabN0bkb{>kd9n~M;;i)&6{Fh&N5a0OBpUdTzFZcjU?>`yX;}0hO^v$#i#hvz z1v?MP&QN=*(T=#k1kw&kRwT;NQ3x$p4LIGknASuAdN=y_kNT~3NgEnAAB_#)ioWgp zHUSZaSwb@pedqA7t^3bSEM=ll-EuCjPpO^v7a@7UWiAob=$L3UO&Uc&;QIeXi^Pm zYL1@BY8o~Q6F+nWcDyob!Bg*i44ZFMG-&bspBl}7|F2@u znHuT~NOk7m;5rVpN5Hl9Rl*g7R;o`kd6Z8+k~wOO++WF&BS&XK(MZ7v#SdQ>(C&7J@sLZUc@Vd4}uUL^J8B zcxlK8rO+M&xeSap38NwyuwTw}>7<>7z6jKmQn>X^p5hFZ^p7GXWFkMsK>g=e2|J@y+@{ z>FD9T)$Pq`&O}-D^4Bo+C+C~!OM9G&)At{R#PdxBqNUUSXF`u`vJXB!JlzWmAHCLu zZtZ^p18mW6)>e<0gLhW9wqaBZh&6eY8a~DiSnevq?K+ z{@?F4v6+V)i_Q8LZdyNgw~0U4z5`Af)tKqfQ7@W?%PxA!_CLhF<(aSOWuIT3a zRDBrE*)pl~iwe4VTmQpN>}O*`-X+tW;2Nk9#fa_wB6E54+S}0o@Sh>-hEkpyioMT@ z?8mOgCp`806LI_aUl(YiKJ7oK1@Fv$7poDy$*#H3zf0bkjYWgUnD_t{GPs(J zt3(>0EIP?LXZ0Ms^HY`oBx_q3JzRY4Z3A%l&&Cq_SX@J+n|Tk<=!0=PZH$2uYhTq& zn%|4F`cVZHlsQ#nYdYk^uuKW)k+w?OyahD+` z?jLT2A$y;ND|Ri~-^xI&e(Lw;dgATlFmLHftW}^X;)-39Z#gQ`6={Bb+8!o8tlkf5 z8IgxzukS?mY?rb)(VGH|JsbCHe1HGQpIZ6B`&cw^Eey8q$hN-x1fJ8QO>D>Ek#Aa_ z|F`y!=0AEc+?!~Aji-4o$CpcY)u|lim}1rjC`XPeU@MR!X>k}#o`zfbl%u{7I*y+X zNXyZ2M18t)>2mWkBE2GdxcTju?!le6zuZM{i0laB_AE0iU$Q-~#P7|m59+aB?GWrU z|Lnpw*hQ(Cplh4!P=}fq*P*rz>eKVvC%!Bv16|J*6PC*72!SS78jj09Vo@q)33jPhLMGA?u9xjYSrdn4gdtsre9r5G1 z(~UYp+VYY#y0f+8TrsLf(yrM)-leoDRV)!pH>TqtJ-cD)Y(Yx_4aVkyyH}zlj-@p1 zoI;ABugFUum#WBB&eQ3#Nq%LINES$Y>rTc)#0j!?T9;`+iVsTKusaZNzx8cC0!vT|Fp)MD=DsGzF8l;>cbD$LPYkjyT1Vl`7nGV88Io!cNuTS88C za&^j4H6%rp6j=*pTuMllnscHh9^7s&SNP6@Z?lz;MbCro&^|ixe7WzSM~W-R?sO)d(e2!Xxhpkcr=v$|p$HPh7!{O$yh zj?uF2joe^IKTsVydM`xUwFS4#@dSd-NbfG_AagyD(pe6@q(CH#*QabdUdFmO(;dawFrv35y|2dMV`qNJgtsofRLT4_^&Jzx@{FT# zgY^lsYp%TtZ{HWySHy$?v2>*esS0)OuzysaiSBzC7QFBz=4=;zwrA5OyDJpz2eeeF zqbd(wMKL=~l}eY}SWc6mSsG3^09lvPT&?^t!I~cH4NSbpZ`|$S%aVd@I>4-cqkfLqqke_clOV5BvX0WRV^6b z5AM4R7e5qz2C;GaDR|@}i?(4TuD$AKc=CVKO?2yhPDp=7u6-`Xo-oB{^(gac!Sh;(>$omqEFQqBN}9} zR5riCOI_7sQb)KBo2gOd7H(_Hl*~^il;>9e?eK{&O~FHF-ecuyynoN{4E4`$nuV3` zzk_8P9c0R%a>j?Sp{-8sb8z=H(=qPIlTCDeVd%W;QYS83^+5aFyUq2Q>Em$J$s@^U zOck11qBogUZcIcIrlqO)mDPTQrbqT<+(*BHu|GW*UwmkN(Dqd+vX5%7jIj z_V*u~_{HmkyU+43C+#u*RQ4QPq1_)nj*5U^wmMOXMG9+H23LOPF?oGe{ja{ z9zpwB>zMe!_62xn#b_Mz?XQ~nPUcOn#rc1=iBBJQ6g&TWG`I~qUDKsCK7=oIkU75q zBwgUII2m)~$OOg2CB>#Ye`$9w?fmFTj%%`kp`{4*S#o4UWYgE(^(Y*2<13i@-?L5p zYqxHPqd$8zwtw@g5?xQ}_hfsnE4AmVh4vhiXipu`?YgLA3x)dM-T%|$$48!2rh^@U zo-+Xeza>!_`1?#t2t6R1vYvp})+HD?Z~(dn(vC|q*xZ65m3562;MTOBIFj8LtxH-l zaKJ$1NMlXto7N=-8#AD*Y)t2%*v2AydpmRVAf%Q{1@_^p_%tf zO|QX&TFgzjYR`LUKP1Yv&%xAhe;;!{d4WkkX?$PreI?&%MmoQ8bD00&Rx;hyPOdFQ z6!)-23@GhmCH(`NuCZ$A!ibL^fFT2#%MV+m^sjvdS{E%V+%+9+;)D7$u=SM7Ip&FX zLR5t|EL+ryRV{-|Y;a3MSOqGKK(Ahc#Y>CLkM@|&%EM5lQW#R@r?CjKehRU=%$@;r zb~<1{qAhyqqxkjl(anO*fBRz`zOJRCZWB~N+cHDD@Pp+>*N61Y_80)22d?TuMd}V% zQm``v>V8(%j+ILyd$eSAUkn=351sLKGYPG&h4aCIa+|f7qCC_}NN3Ok{peNjith<;aJpjGYFHk7np;nNU+i^JyK*QQpTdM-eV#tOID3BcD4? z<+Ovwvub6IAmk2cjx_?gqUY!a5bww``bodp71Pl)j^5^J(^cc(<;ao44b8>v(|%pK zORc0r`GgDw_uz_jYsdA>s`kW9c`H4+JE_IZevT~UPJZp6bb1FCSDndg%JiTXWLh1> zrTf9N6%N%`iLJDA=E58g3Qa5EO4;s2DN=p|g&Ks(pZ+u+{{3wx{^D-OVr*Y!6^U+y zDyyaRj7C|K_;&uqUv2goIMlprMe55?NcXE_=@&nBE1uZ&M4URVuRxcSFMXO}zg5dF zrz{!b{z<-p%f5k3Zze0N$LJ}Go$kw*!bvqyXzD-Iqz|)FSygFh!N8#{?D(-RCud|j zI;c)GqTk>l=$A<2&ZP*nJ3AIqH4VVv!3c-dHnEvm+F!KcDib+RTeJS|YLxt~wwWe& z^Kbu+hhKRXZ|v|z6aVzur3bZQJ#*?&Tdb)Q%jxQkF{VtCu$lj*5dj_IZbFF z)GzUoHmo@)dvljuyl=pc}bhLqdp{OzP36W!sK(6RHx&btp0|b@4(y%Ef zcrmUAx8iI5Im8?}Iv?c+ENO;oKIU^Z1k!zdddx&Wd8kVN?A?k2zmJvbNWyW4D}&3S z9WfuO_G~;43j|AHKS1o`p~aj^it=(v<^%~^C;!j2H7zL(m+XpD7eTsz01qFDUrd`& zQ6-eLi0lW8c=e7S%i`V#mA+jae{P7>SiZVWBj`MrXrxmF>3m8~NGIEMqeOcs; zq(zLv&krxnNTbo#)TwyvdOIdbHv6I5xUoB3AqSrwgp z(hdvAC#WA%&rvIyGOfj7QR!WTeB&m)C*>(R4#mY(mNM1XOON5|?l?}l~v#Mi&CExyXCN2Ta}a!GpVY9E*8 zI~R&+?YyX5B=x`v$K#v{yp56M)SfyjX~_q&qLfO!lJB=K+zARdhgA@_3T;~ES5A0|LAOP+W#xy1MOx(wTBNqm?-L;dZCa8FT<%E^L0RO6^-XNY4}BOLH+%sb zZ@jii?nf0>Qf8MS;S52DW6@1f%VAcYw9s|YXU}>neD>O13P>uP&5h<)A(TUhsc8sf z7%oSdZ}y^@nw;#(H#jREcg1D9655-26Q7+p1Qh}9?wm?5H}(7iJ1ki z-38q@!ZMX6sw;V}qbAqRCs~s)cAjh*iVfBjq?71Q%hxw4I36_CY(&en+Q}ib+Mx0^ zf#bkLI&+ZDETr>`xV&UFv=HaSq+ymo%F~oI{&Zh@M%oV>apykL4xd)(Y7?b}gI^X} zuAimT38@U12c+9R*J zMhEO@N5E7lbxaD%%gUGOo1fn9NIX^Ghmu5d67(Rb=reKaY`QhpK@|u!B=MCSAkL6+ zhD54gd-8!WUiCm|J37GLzH)gkPndIOkklZni{XC^qQd2 z)^@HtDp8Icy&00zLpKrtzmbsEYk=SEyXfP5E%3;ZqiRSyGk{lYUm2-9N6+o%?6O** z&6Ph#jtI;gD^C$=Zp!ngfn%-UKTxCW>6Dh%NWi^WqI6USdu_DW$dC<=v?i~)kWLj2yilxedwDg-9%G3hdjo=tEcb69#b^WtFEWKZ&5z z`MHhHk)w97Hy&m8nfR;mO;auHqH<(~bQ~q^Anbg)UzQ%Y0OWJuOb8rq#gPV-?T|L9 z#D(3(bre~6Xf{P>ps${)DsWS})Om^Lt;y9cBIzI1W$x?+>1q>Yxp4&(b~0x2Di2}B ze^sfzI8^xv8$H_P&V&@?vm!t~f3nMGJ+jsg-clDx^F*>Wl$S$Y%3)pZyX0H8Dj~(x zrLA0*lG!H%NWQNyR;Qtm;cG%i(9!agPsinwI?gvJ z9+tvb(={fTUltM_SSTjT(6nf3DJ!1b)Ros)RbgNJ(<4n{ZpU-<2KY8r_Bu=*P+HEW zk?H}`w<|&F%#oue@a@uEWoVjf$Hh$;n(nK^=9eQ!4hn5gEs;ixzeOlNti|oK;<(FX z&^1gkVI}aA&Rs(GcXXc%M_rt(Yqm*o?dm1CdXs7(^=4e2krv8Ox*R!j)F1h7BS((9 zA+?N_61dM6rl2Z3xVLV_IDt_H_2MosKhqj$`=s;T z^iIjMcgkpMbrl7xHs{v%jN6Gx$9p0&zwtoJ`B_+X^_1ZbFsy#1WOTf^^L{O`&N3!k zJ={Hqw9*L&rw24F(Q#*G zm2_1q8@&M}^%juw2x)Ks*{3xsKt7~oN%xQT&z^Iy^mcd`rSrMPk~%DJ`+ z4@NGXEak2=kWQ@6m(g)}R?(gZ`+%Cu^QCc<%{OW20XH>(vJpv#5kRAbt6h$UHRQgb z27?+D<&cHzD+I{HkZ}JTMe2_Fn710VhOxb2c0G(rELtZp%`u>BA}!EsY*vmOJqgq} zhpcxH=yhPZ7}O|m&UkQ>0 zG|(*90h@-ru5ndq`1_0Uavi8?$Oml-@?OuT%Ta`Oq)R(-8uo2tZEr>)Jp!(UgxfZC z`OI50kWZ2|9JvDI$Wa&AOQDH7=33&Rt5R6SWi-;?^3ut&iMMhgcYt!_s29xKB6H5T zzt)bVoKJU7t~*>gBuEcM#9=!S-ylzYg;D_Bjqv-}+K*GEUShlJRgrL`jk_1>h47$O zs_%3v5W=QP@FQ1Ka5t=VD#)H2G|P*Y<9YFVq~Uf) zC@mmcN?)E$053t%z7t|)LtP|SS=Tv~OCM}HyAFN?Dy20OPClTe5^)gzfPALs(+JTQ~rmerO?GvM*Aa%g*%}RMP<0 zBI4>$AJ33{<)P;m0-7%k9G4!tkW$6aaLeG3SIJp*NBwk~v(~=BWLOY{n~9G2xwY+) z^jchbPiP#c^_BM($dMyQr$dvgZR4q<>T*V@ft8$epUIK@(;PWE1TBPPaL$oW`Lu_h zxk~DuZ1IEtexljvUn@cO-LkGU!2o3G3uFen88<#%1ZlSqa_> z{HG8hJ6<_*21lqw*IrsvV+cxPO z2h*w$uLr0P99t^soVsT9CIcN}rRySOMmWwTm5}Yz9N!Mvrxx6t;E#JX;ahsJr&J)M zYc

    mr;A-)I|zur%kIIaR_lcT{&c;*U&J)*%02=aB$H?d}FJmNF9|2wUqTA&ja3j zP%b*V-{{!6`Xv*5%BTWpI$XJSXJ_Q7ow-PLm=?(V{E%1-L&at3lq)kEUpiN5HFU0U zr;+shms_`UbUsu)d!HH=?x>lg4@sws0#!E4t&hX16BW&8t2@rUiW*hs63+7B^npf5 zg_9(GFP#X}Pdd}jA@(Tb#xX}vh07_2BdrLR(;=0$9S`lGllbIwEk}nCvO|ln_HH&# zbL|dndT!_HQ+O?ubCt=FqZ3fK^MDQ@XgcsjO>tJ}0a-ZfN}jZFrsqT54TBcK9RyXffMqxax2xsOM?!T}f^;u~x&`zTdUjel>}X%> zk|lDcw8d8*dajWgd_#O?r16oIoTHbHJA68jC7ljFO%E_RS<$+r6}=DQDo{K2!K8{y z6sbMIG;Ii-mxkf2#2k0I9)KmSOVB&uGm@b<&@|jemeOZK?fP4u%l6v??Y9WVGccK+ zr5ynad>IwGB~{qfns_Ii*|Wm&??`Is2?Yp5qJjXTOa=PZ)@=Q$v-*&o*CF+VYuOY0 zrLzCVnSpKrPH?6novhg|WYyQ+jGo>Xz0*g|k;Aih?K*z~L%&C`LUi*S++7P-b-lml#_OAjRU4wE|18O8d;wnQKuDnEFgiDj^ zWssCu7k$W>zC)0{dC=WU+-j=8ufp~}->U6KP391{z7d<%xyyxeMroD`;o$-Qne#Qs zLP^V?0;>;YP^Yq6fC>&F?s5i!HER5GJ@qrR#s_|Z_i58dI%AFm##NhgY zT!#(o$z$i5L3OGwfFzo0stO(|74$y5zy~WSN-QZ$p+YI^-s3e#QSW=U&i5?z_WtIU z#RUuI7uq}=^{j)>p@$Cc(wSwb4XY$qE#{PAbZEHMpBa7_Ap4Xa@4x14?Hai5i50^O z=123>)f>`23lKDr+`3j2+= zwl7ZK7D#FB@^KmY;7{5myV5vtb;z_)U-Vr2Kfhpmdb0dE)@(?2ZGLJ0SJZ7{u33BM zvMdnNBwI=$S)*9a5dV?0;UTnCCYlzq!wiv;E9dgmq%~8LPYFCJUr9E*T-=_l>u7g{ z@yCaU`r|I`2i!f*kKnv{?d(7-Jt*Ua#vJbTPz$s>~LK(L& zshwDWa8+wld=o|ShdbH$XOO^g0Flnpem2@gQOCJvE0E^1ePEpj)L_e|%YOoE_SRXaIi>@`NbhXzFui8kS%-+jX{P)+5zHodFm64*xJ#LE;W&nMM z#z4Lw%29Xt)U~6$rC73d<%m~5Q_Gxeb{&Fdn6tSZu0`h6I}L$vq`9La->!x;wHo|= zKa{q`#j8yd?>WjxUDjSC!9!QJ*4z=8ef(w90=${$WRAl$PRmj{%Afk{5O{NZll0o6 zv41|H*|nH^6IXUn`#|$Jdf$D&ni+^3IdWuxZ_NyKrQ<7IN4T>g<%o0iuKMhB*HH_# zyPT&(<&n-?B>8B4cAQ%ar1EhY2(;1~A+2NFRjNx1dA|Bwv_90zZ|i(W8c0`nY2^8n zxA1zyQGT-)=ZLuu1(hQYOnK@kLCE8p&2=X?2{}av)^s<5>v?;GLrk-s$0;owWw>QP z3pAW|EPtZQF|oZT$MaU zww)w<&ZkiA);C8CMGTkL&P^JM*CDG)Y?i6DzcjTswbXJV%bs2c3{H z$hut5s+>hCH(9euquCVgqIDZ-M@%Y`p`rDJ27gQlqz{<2m8_ZVmQEKnVcVU9yiLoI zBMa)GM%D9lO&%^kO_{PA9X7GV%hAqUrfgs>$~C8ZrzhjOujVU5*BWVMrFU_tTdXa6 ztObUNyFIpjRwzHzMPEXnkXfgX$2fl&L~gczA*=w$eNJ8G!+9Otoiz>GXO;gz_yS1z z?wmi*gOiws;YknOb@RQGq{|o9969Oa^(*k}Cbwn)>9tWa^jy8%8tRjgj#Eg#a_4$dyKP=v`R)ac+Cf_RY0q+?BNMnZDl`_9R1cL3M6lRRejf~qf*MfcUUhn7>dpU#~V=hkx63G2YqE{;sf z2lzJm4oc~mapxlGPZ?Hj{Mh^K^bIGSTdN#B2%W60weqn!;~>$cgP}!A3EG{{GU4Co z5nN|Apoh8km6FC=qS*biwoCCf{tb(Cny7%pLjmPCwUqdAZ)>s3=E&iKOZPg$vty;D zGkkZcM3~;gsudi5YKkuKsmk))Mh+I*tp(hj8keVCzRjsD-U^9_w+x*ttGxDa67VmUF`_yHroDFMtp-H@mwpa z-&trOEDBadCCd7ny<8xeGjndQZIinBX#~FF%E>UxOwig_fF88e2(CjAoebLlY>DE0 z*O*bg4iSml%~y8T%A%(aUMMT1QhYhtT=5`2KCWfbBDl9=C0=}L8DZW|qVi&5opkHUaY9E=FQqh)`VFPi7b52H?*wD2)QYQ|5d#PNSrr%#kBUE#R72bSB4F z-&sI4v(@D!EE*t$UEqgaEl8ZC+#>BaV|Kn>3!Z zZtakvM_Xr|m6#h@Fmcyf$(4)9G<|ZNlcM-zsrXmN1m({l+E)ZrZ#z94jrN4OrCzF^ zbF36(hbv$Hi%_0)pOSHAMsnI*&K@;WIl4768MrkKYeMJbb2UefAaGNK{yfn2;1-1P z^o?3EFWoC#=o~q^C%8L-iMgmsG}6w)hVsO7_&^U@l$~LjNoq=chZU~6DrJ>_l(SSo ziis76mdgUo22;HKO;KUhqytGBO=)zsRZ`BifqhEm5if=`gsh7oROQ;4bK>bl8T<2V z(M_KCKW+V2xhZ7dCUPHW_6SIaN!(Q$Q{~`I`RC|D=qmF%SY@Css1(szi%RO> zpJZd{8bI@-a8i;emi)nmVhtMQp4=IvTWr%okSb(VO&``3dp0%sRbI_IikF5NX{gex8}k( z{j!+GxNL~IqN5SwKIiB*$cMv$ymNBo$YFuLC94STfh_I;5c^33?lXuSk3`+bkt0V( zk=kIybJ2nbdXQDV=9}eCQ7S3m}PUbe~BOG)3cI_-ZS+n zn_Cxxb`saIc0*hzqEejW2e{3>7Q)>XJwe7ypxVq0WDTpTg1uNIBr&8eXOZgrBDAD5 z9XkYuSz=41t!Yfp%B2pMRK>n}mi!PXPuxyZ42@#a>FFz{ikw*sl_MAu6KSEd`!`PG z1S9`!pC$2|rxGs{jknR1&ejcGp##9b#mBWa)DU%KT?M#Flcs=}TT3~7DHgK$kD4P7 zXh|M>XWtHJdKOmWlH~~<1x<1jjxiw3&`e* z&K6q61vt>LZ`FBe@XIDXt{pYc(J=0-vttV-uRmP z2DN}|cTq%acI_Ju_RYC!Mj?4nAsvx83TCXU{18}RdFcQp6!CM1+zu_MzdYX})TxM; z>6BQ~!+$E`OQHyG;}_5^itd|Ut>rnNAgOly)BVR5E|$DhX|=?IfY25WS_VPnqNVl2V(NL2@Wu^1MHw~0Ps~Gj#)L_GnY}WqaT@nZT8RFof=R{*mDAP+U-}#mhQ5-8$;6hhU?%A zkdJ}l&mG1$aa8GV{Prw6PYd$64)vdPiL;?RAtX}_Y~TxQ~Prrm+tAAS*Y z7Dcx!2CP38llR{bJB{jJkzdcp^r?54`0~leVCVH35=LRw%)9X4S4W%ZNB7$leLxzr zdX~A|`_CKEI^}pAvPDZ|!skDQsduix#i$vvCkl#_PG&=k`)BjmzYAHeN*O~b1T8cgciTkU~E51N1xeNuv3Md#t^o31gz z+n;?OjU#u!;m7P};+qbrL+1yMX*^G}me-4)#f?`#YQpc9hQ%iDx79&7c9#uG#I1Ps zu4{4QV{e)0>b1AQz8^jW+ppbNsmo#zs*cKkgtQ27 zHqEwmA&O$<>1Bm=;`#^Cxcf&;e9DNDoiD8wvmd`3cR%_9W-pHPcj#u5aLB<^Fsi>Q z)wK%qp1Bh@{_h!+|MsfE*l6N@IBbtiP5z*U3QZA3y0=#rXm*I~!J!4Z!PY&NSU-%5 zPZr0Ht%=JFgV|5;?b)!O&|!sjEMCKkFzc8Ddik4p;JRXee$>RLtWU;WFU6aW-iA9K znPH;uE^EQWk9`RTY}{DNejWE-Jr$3>6RpKtAM_C%yv-2fL9mZ&)y!!uG12K%ksK<$ zXOlUvk>G|W)ZdiK+E>o)iNodTqgP@6YfqZ=$Der>Z!ZG+uRYqtx0|#BHeaiyV&f5S zv7;K6&w2pYKiG)fKN|TTBgoNNbhNe_Z{7D#lYZmkDLDR+EsTw|rgh=E+T_nF(8V-G zq}&Jw+_K~APvzia=4ip@712;*$H$StXxbAvRdDa)9jK z0_n36ZVlkd(R#TwCDet$a$KG*hiePu+Gc?%$HiS^)3d>is$%k_^^DUl!J*}r<`9v< z>;bt!cTHGIW7BcGIYs4^3~)~t4ZhwSMbMsx73NHq3Z&J9fA5{XYb^31&5W z+~aL%YyH*nRm(i=pAaU($d}q2IqC)Jdkfk+c20dmMcT2Xm?KAaNP9k5Cea>=TJ~}@ z>KCXsv*bI7y$!DMVkn*71$Mkb*qH~wA8Jaw zZks;28&Chr-p*52=@3gLofdSe%OO?99Rkt(YWUixm%!8SM;ou^-uK zu57(4$zUI1^6V8L)nRE{qSF~Pk0Yo~n%aXqhGZN7o#hD9Hmn+8?_5Ywo_NimyN`D$ z-R0r(XuoH1#A@X#b9IH-Rz-qJAW=LI73xeSN1HRs% zo)x!N63@b=FdP_VX>##$J6@G^j!tr9l!J#&&xJWhQ^V~rt$C1~IH?!u$aB5SDJ9qI zoHpbm)1#0NSB@Mxazx;~{vup&(~84oI#oFZcD+?ARhE$>M~)oT!!?gn?y+y{oKMPn zAho-Q&88JD6Q+Y5th+vAs%_r&Qk!zeRXRxr7RjE83V)r5ISAu`+yR~a^(}*}r)z|S zc9ZK2McP4g=OpwDq(a9Z5mp}5ic0&=VrX3*->tXdt?Pb`zs~=hiCxgQsE3O&{ZFTv z__>d4jE^0=FAiBN`i zTMyvB_eIeoif`6RjL}NWy!s*&`op!)VeCeq#KEOEYqc+W9=A?igw2mCy;&!?!Q^tl>Sjj}jzuiCo#MWIbc9x~F-Am&~U|mpee_3@hbT(D@gN zwx&>S;bun~TcZ~}ZLC+(V{}RMbF=Y>t^hRuN*kaRMfukbv*E!FXF0w zero71{N(1Ccjtxp?Gu}s_|XR)hGDJG;mTh|wr|#Hm*7j|`$4~RtBL>Ud$(cCNuR@q z2fb$ESD$|t=AC{4jvpHtriIVnim8h>!%^a!wN~M+JAaO|{xHYHw*TmdvCDqL(YR#3 ziNE>Mn|OECF4z=ueq=aUJ7k@XFaye_m4T&pE~ZJO*}u78KfCp1S1QIRC9(@tLDP zY~p(j0a}I^Y1&MD#+4W0vC-ecmkyt2;#d6SPk8t{-@ufCs54@pSeH9COvU^o5q}Pk zC(|8e-=pBVe+J0++iV)!Pn39;%Pe^XH~jWO+}CdxlX$=`+hC`y3O?QJ7YyAEKl%?= z9Pmwi3* zTcCvqR-`GSNEg!-5x;>8V5dCmwsC$k$0J!P%3D#Gr|}#urWfbwuHGA?{&7@6FUtZfE+n`61ds!I!BOPLvG!O!;)Qfx$K-ZkmTZI2g65N z$2hCz;z{{wfzBl}gtE>x7IHslaoa=AhSofU^q{15F_QE;;BeDL(?nTI1LvAFAbHwB zM<=cJ@O5G(d zqSIv+b`-6)-*iAqIW>``GL)7$)^OJ^op@!af)=G|E_z!88YV|Qh;P)`pFfPIgJNs+ zoyFL))C4P@#7I!&V-NN^))%;JSH5rZXFT~No`3yaENzKC!#81%U9r{hVwvdX|Dx9(!M%^o z#6mU5#Md7)0h4wZh5l{PXNi`tUY-8DT`{`${^ok-`THl*x9syWZvMs7nA09TjJ0Va z6}}xy7A(ZTttOh-cAIXFMO%-+vZq=R-3ldxp;zMl8BgHJ=ie~VcbB$cg9&?J*R9NB zd4+?~cDytFKFk{#JzUoJm51@cbn^jf7%g8?px^l_UK`q`)`?pJ-=`c_S~j9BHZSSIQFqG;JPP1ZlYtS^eZul znOCAtl`Hu`byrQ{2s1VXiLX!d2C{kqO?d=s8?___GbuEkFjwv~iX=)chf z?6K!ICf-yiv*#A8apJkrcszUT7T9+Gv+$dQ+HQqDFW+oJzj%5M)c8#>`~F)Z{(GH> zbN1K<&Dh4oPd@fBoOJyYIDYITgrNQHTX6pG-o_!n{H2M1Y)tZDo}G3>HrR_r9JgWj zeYMJ<7vag9qtAM-`-Sh~xPN{ZZxWKmjSe^0Z+|zLzG=%Vxar*IF-S!ZZ@l~3%UHS7 zr*Xjc(c@@M7=y$2y$-j`c-zDqupSncXo@J(8JhjBGx8Vd+Asn^ABiMe1baL0yZ_QS zs??tEkoNSA+B2s;dRS}A#;Br|g*B{*-#s=ixrT9K75ejuVt*E7Snou>Kig(rXRd#E zVkeyO+fQPv)bqB{_f;1!YRCGc*1~|nEvC5}4OomtD`T1(`dcoPstHpq?PV1})@#A} zqH#KybUQBjv0BJW@X^u3es}-oBD}iSck$z0)-v(cAI!m=`Kz(f#1EPH*Y=oF(EnfI zzhi!C%71$EKET2!ar2|=nfxz&=M(tnci*V6C38@(cmN;KRW34yo7x01IC^Iv%s_dgPS=KHm`TcHPTfbshsX5xEo zHV6%n*Jo~=T-GR5uIjN03kvPIuh5<%->5w!%k9~7v%z7$c&CA`m(r+8`HtSMa#?7i zLn2KoAh}Q0ByN|LoIR@S(nRKz&E+K3R;hX-Ty8d)ywD!=nL%#E?XuO>nIlJz9654y zF%sUdLgL|#_)}A^6WhewwJ2{5_JNSvd&xO+tl6ORxSSrJ>{{`}16*-opk7Enq(_wF#+PsBRw2~RYHKkD;Rrkk$;wVTW64kj zcYeX8D^EICb)}55(kc&X@fJz5GH~Orm^#6f4Z-RekKmDEyWqp?RgT@}KKUr#-RW2p zp1c;}SWwczJM4?ezrNT+ADi_lY%v=0fe?qH8@4>UrTy=Vp2HsBJlljfxco}zjqa#^ zi+>UAGjZqbt4wguGY-V$zBl3LcfW4pA3AOf%>DGnjZJ*VNvm-FBeU?S%{MXS8$*sn z?6z>HtKDvCQD|t4#dCbn{W@`%3gM!1vCag&$w^NsNB=Unc&| zAI-%6pWY9n^?N2h^TpS(XyPceym32<4ZiTYaoB0nM(E>}A?lo^@6N@Nk(02Nc%s{Y zQG0#}>z(x{6Z^;TE%Dq`jZc3kdU&guDpC7ec=XO^v24@LO>|V>S8(0;&cv)AM{j2P z-WfgY_p2WtjtyI9;I98f4=Rq{{xFOm-Uv6^ zFzdF6{*_(7fYXK++OukwY1XT6jKQSQO_nYVE{xAmTsb3pn5%Fn5wf)iQ@t$SPi9Za zWp8~4#kIidw{iEc&clP_&oI&dJ7_~Rr-;ZJ+t7%H(i_W~SUHyB-MLFlXyl~gLkp|% z)~m0Z_@Zo*X|cF;0KQ{dC4{p;4Z-9S zqc@FB*7I;v$QrvkdQ;dlcRq*}6HmYr9aX;8_Pb-ltNw{AcKN!AAGYocTz>0P9Q=hX zO}w}|#xz9~>54S}y=AEpzev{<5xU#MEugvs{oNL|=V{ZP&tXH$o)y=ze_a$kd{JD- zd~290_UGqa{n>^&(;hZLx9@ri)}Qwrrp;Pvn$dsMSd86ZV8LoeTE5+f4#Yi|d>7ws zYd3A{Gwzc(br?73_3-+1;^IZ1^QpB&+qs@=S3|lhL|qVAG_E{XJ*!@rYQj@nK8EwA z48+WX$cnkmJH-3l2uu`+2ad*R z9dpkA4L-V2^ziHJw_Swm$L)m48~Hul967oZe6ya0T~7(b&`i1lzaDXAXg+ri$XN=z zKG#}jhq-zr{Qkp7Gc7aPYbf ztgInvoE%hkSAKRx?YS(~p6Fq;xINty(z+TFXAnTbp}`hKBRK)2iR7A4oDwR5pM9le zK+1A*=7`~%TC^8qI<6O$qpW0JT&9Zh$kFYQPplj{a;(WnI47R9i@rsxd@Y6Po43k! zl;Yec56irfBS(&oKv@C$@MOwmC37_8|K@&dJwOjhxc#MOXgfX{(L*osqb<6WA_`em z4T>hz7UdHdRc7ydN6NM=NZbd z@?N-XsMVb3wc9UEm9s+286k(|NeX#$z}n7Qird*xa+0pse9(NdD2Z|sRgbQ4FO?8> zrF9W%AxdgCXJJbHh0^w2DF=;@p_0gJY4<7!UhcG%sCc@LimRPbCR2IYDJO~VTn9ZG zoX?l=D;d{?EAOJQ^MM+4nIcyPT8vmpS%kO9xT4At*FqWY8jO;>nflUOi57^Z$;-7= z3t`46vc1Ukh+QO+sL7SeQ7hY6YxHoVkt2r%?MSD#kJ|#%e9o%4&Z4;OG2OOP`^?oH zGAkvSeMOdAM{A+QUzxchRhQ2<-{3_oSZpxvefoisPH3MV>V;Hqmxe5UtCmgU zIwZ;pZS7?$=2nFXnV}8^M(-TRT$LuhqmD-BKowRviACP4^ zm!Q>Baa=s;=MRx6qlGd_I!;z89FFMj(g&}Y3|lw)v>f{z^QK`~ zcX;&aoc9*A1EUL!+TStpD^EKTH#Mu|Fs)dM6+7>0F=)jzf4jtlUO(^*d}>tmcA+Qj z{*X>FNhhv);SSu@Z$Fdte;YMp{ic1<=X-aW_)8xhgRRZ0Sfa*_+H4cd`QMvZuE&`8 z0FJj7>XT^bNpHP;L6O%Ay!Yy}CiLv8RfX`qxcrtOCVuFTH;vvbHs)XxKY2{4$SzUK zU%d57ys}VZ!v%9qeE!hQF>%rqY&I~eEdDCnDrAFR9DOG6AAg^PgHQbihB*46y>Tcu z=o|g=__E*3#9`-MiX+BETBr09%z0@x8b(KN(i+ik3=S?g!ZZW}Uc41ozOpciZd&|& zV>|ln_z}}zCmlJqa9FxKhRwX&WS`e|G=BWi2?d>wKKr=w`w!vV=Vk$ux2nkAJPF5s z>1Z>2V~a1anX*3SfBxr&->t74g3oWYFV4AopVF2=dB<5VdlJ`N7tP`i{bXD7nNh4* zVu~$AfAqH}m{#aJU;tW+Z+7B7W0*y!3~f|^+OD9YfwV6B%YKpCZ7c&TZZ&_Oxb$pX zGh+Zg_wh|kygy?USG+d^&ps1r@Tx-i-pg;nkVAiB;+r;rEK?ebpZW*>J}a6pr+#CI zscT8}qAm0*3|69wegiO|b#9_cm-zGEc^hkOII{fN&0>A6FW!!+k43h#_Z?5aJ{b%vrGbUg_EXSzB@U7#Y#h1SRF%!L5 z4aStO{|@JF+pjEkV~M7SB3(>VM3Jt;O|tsN8iwRGZqM7KJ>x%%@0>XS1Iv7t;OW0z zT3ExrZSp_0VI!Ul@WUKardTW9ojuEhmcRK=od5n9Y&BxJi9h>?-=Oi6KgZeoMV}~c z-e`Y({r@W8@J#a*6vZt-ePHU8D=iO!b}OZRZ60Pl`HV>! zIr&)hpMNj@dh5m}{VTuyJjOP?fyDhd_p49%xTnRt;-as#FING=-?c0!Qiqh(X-+JcnJEO{D# zyJV(GJMfH8VN}x-@lqp5!L8P`7D}UpG&sU84YKQ`VaigPmy*m~0NrS+pLpz7@v&`+ z8-mFudEl$ZVd@Ku@X?J1AxDnh0Od&MEDN{g4dG9%2WMfZEp=__eKs8oFOH70I(8nF z(WaqtQF-9t5z(|@+t2?ISDX~RZCNj0f|vg@7hm~vv>$$E=4u?gZl4q%Fm0s#XI+4u3{r=YY-f%fIo4cATR9-iu2)%Q5zCN~DW>0cJLWGNZ=zRS_!b)47hu_Y z(QEo|pZ-aV-JxH3&i5HO1kH;VV@Zj}0OhEUJK>G%r#^tq2P7P_U-rSdHC>8VAHK~5 zZ<)~-gGY?TiNF4`iBA~WY${$h>p>HrdexnnK6e?=xX8q3whqMR1vO}y_*oM_{lyD# z-seuh2KyXs;vYTc0E}C^8Cjs0zKqMyjUKLe@91-I*4BMR@%6$-@Y~Zb20j-(xcBb? zH{zUMo`)-jeb2;?S?gY0@cn0T#9yM%hOM`379N~>74DoKJs`6TjaW3Z6$3YKx41T9 z0Jj^=%%7O*f7nOnmsA70_Gt zFWg)X9mICLclT9zV5_J8$;5`{sIIovXw%8{wS9FP`m{7#DbZi)lf2^6#n_FI zWiIp5O6P;F1ikbW!4*g2Jz%%f@wSaea3VAuRo2gicdn7>(E&G>chD0))^+h z@1XTD_QYS~%M(YMcymM&{VC8ded%(X`@8pW^f_mm{H^;InKYuQDSEhX_3HLyQ;Or) zrzO=q2`w!xShi$Yf~KMGAPgHG+1lCnUWOZ+cEiD?hqas^*yQ?A3E@sc!-#|M-9PS! z6|K?3XD{A9T80eEiDC@Q?G)#<`9EXW~CRWP>tI z5nn9OZC|AM&Do~CMY~%{Q2+_}OWd_AGj$ zxQ=}Y-#u}CQ?@blW34<^u2^ZV4cmMSXPmHg^nhmpM@?wPNx!%aukHOABl>2IjNA!0 z7C42Px>mZw1U``hEfZaDdl0zW7a?wtO{*Prk_-94{77$yZ{G*{{n>bX=Kx#e~IA;IcnQ>*o>Q{Q^cb6hACW=oUS0 zu0^^c&H9ZIUuiZaS4`f$;#@L`2f+8IE8ni$(5vJ!7zGyL@yq^J+_BDH%sE9gcO;#B3a8svW(4?AS$yvtR$dSiQ&SN3!*KNZ{fCS;o(Pl#C_wM#x9w-trDfxsLL3 zEpIfPE9Y`kd`m2)^Nj}=ccr`B0$*QpGTU)Zc3-^+;Hv}je30yl4xr=m{pF+9+HaHL ze$QxIc53^R>w(SRZ3R;OR3eRkk#Ao?=yZv-0@yEAmh*trKudk&(lNlV7n}}fg*1=2 z`VmNL^YvYG)BqvI&{=@f!Zi#vYqqlfrjj#qu|g`8z77a@LqRg4Wm*r7ySgxop~Fct zAY_$XgYc@4K#^b+Z|c*Gl^?83^xVkJHplXRK5xRa+s0#b{05p*m$$$3BA#2cg^7H4 zqei(p&V1>GcWa+&p;^diUnY@ekh7)?xW4Ptv(fII} z_BHV>OF#15rf+m}@S@wN;d49ej`(-;dc_K?Zf-`CA~JFgqAM+Km(RJCc+}E3s9~7= ziEo(TN!vE1^Orw`Kc4<)Q)k21eu8r*t%E+RpDd++4(a+#EwVL!s9na zZ_@brS6{%FFa9QWKp6DW8Myj~zrYK7oo(W09k2nK9Q3PSxCi&FcNG4(M|AUd9d#0Z z^6fw2taGCApRw6uynoQQF}Z*AFw2t{oQ}UVoQfZxJIVCpI(=5-iSv)ee+l0P;bAK8 zLskWzdf9TUNSKsmSh}Rq1pBl!^1~>N>8e+7|HMJX-VK#=Gln3es#58*I51R{r@Zys>(miEmmkMEy6Of|c z?NRxIKUStGVz1HtBAU}8dtRh_^}yq?MTei(l3SJR(grj&wVB@_ZYXwoJKw*2Z8_1m*DS?jLVuHlAz@O%qo@K`3);2V3xiL1H z^{9zIF=t0?^~ODTX2oI?A2RzLJaf-9tT*K#6YtBMr_dTdc<5?OeKGPS@Biv2P@Fw_ z`TM5Sf+hDBZ1rAP@X$3TzesogSC2C^ru6dphUW7p&ouGxT=+R`*O+XF^7IGif=PMO zuG{9#^{FZaQvJK|AzU-{MLd6hv_2gdH6HWlM?W~e_wy%X=65c{=MsJ!<-$3s95g8d z(gKM;N1td#BCb+JLiS)G#zxZGTA(Dms)=WlBS(*fNTI-2FtEH6`%RdODTTTB1>zS zYka`SSQ|u~-oHC)&nAWT6zh!I^EG_>H!q|6!(KOiqwhiJvca%zsLz7d1>m$WzDiz} z4&=pI5^lVt8N$(V{*83-!10B^i<8Hv9JHOiL?wC(x?gv@lz^L1w$f_0L>$uPYeg|5 zj%kIDZ{TYyT!9v2oD@__JDuk9TMIc)F?{IMlcpiJfYLVD{5V>WG!3~A;7F%2&a_B% zO7QWZ&W|)Uc70qwagHACdu|MT^fV9PwOuo56jUF4aG7<9hLc4H)pM+gBZE{3mOn4&)P3*3wixK4F8aW4bK$bYQSEH%F)Ijs1H?H)BD5 zkpsdStX=fASc7z6T883PBV;pCH&kno`~udrkFr)kH*Zz&Q{_LMgRrXTqGTm^1iB7Q z_4*5I2B>#L&8u`S0q{M=9Ge8140pe)Ffzi=k|N`WApOFX4Kz~NbS9QI&}_2l&fakr2jJHk z-+JT9=gy!h9a$j~GD;SYs|x|?VC2zEnk^TQmcdt7sFjh9B3x~(n+0QzO5#}kt!76S zRl0uBwU1jz8L$q40}Pv{9=E_qjpb%)h-QYQ#buRn1(T+QIypbb_Mv=!2*(FVdx2o& zvg4GGhP(b8YX)@uhf{K?fTS={*@z;3P%Dn9QY@*A6*}1fDw4)cL7MJ^&tU)~EmsHU z%!Dk$k|_ar^B|cxu1<~@ggBTyS9w?4e0er+YMxx};7k@LW61bt?GGC&uuLd_uAEEX zxb`VQM!?@69B*#CxH+aBJf)@4w{%J4=+Y4&Y!14XSgG&1G>Mm_kJ9o>!yLa*Ic+)} znC{}^mZS1uR+^T6az&99p~3}Lik<4xAJA|iVn47Ir`ZQ!HVu7imbMg4S+wOkl{_ao z-PUmH3pbBAo-{7$k_&W>adrtpJY;SofIde6I0NBbKqPJBtcGO$doeoHWNM{4#wi*; zb`Zrf-2>X4s;ep8mGD{6+=@}8R_C%BN5A=7YyA;e^5olCqPH{ILkj=;?{EYT|H}_d z{P$N+#CML~5`*I6OJ2i`fA|j;9U6VwWl}Mt9SENuL$J^Huf^_dcG_yg;PDHN$L-@U zz!`f-Zwbbn0F^*$zh?v<(Kx^V&@Fgw$D{G}J$Etj0delO(Fb%MIPq3IJbyRrKRlwJ zH+K&DjXbdYrY*uwUO;^+CoRs(QJyPP2k52mV$P!I%~ktvwKkfIpP_v25fh)jSfluU zwDzUZn;us59e{oVM`6-YA2ad2Z@UPyK4|y8SxYaCUh8)4dA~Go)jI2d=uI?zJZ)2h zhhy+tFX5F1hnV;}!y7Po%L8%vRyUjYPwwuABR{l$QRz(l-8qY~;r?4;?Gj_X_&Gc> zeG&8)tW?gZM85jP2k_Y3=*>AF+Mo%mXWftgy|#5xS{%4pA7Is7JpJG-Gj4--*a@4& z-_lfRW{V!V3bzbA0>9k4CCZM+yK#)k-+A(UTzb#zIOO9|ywAdExc#wpvC~n*g}sk* zil53Yzt&3mX+wERgt2(`W|MQ4Yo+t$I@iV?U;U;DK7GnB@cZpAz-dzk%Z_ql3DH>g z>NWVkU%qIv_B#7a95AX65w8(rcAjhs&A;>>yng7%F{XK;$(eThV_0|6k*ru81{7@7 zG5d^)A=uKq< z2KB)^v)@A-HZt+10^QQLXJgTjF(tOm7&xfK&=gUmGcrV`Lv<;`@GoDp|)?71prN7S^!en%K7s>sZ75mvH|p(JLRfpR`F?etAhL z=-V#4nb4w(ZpBLneimcu&U=^yEGBf`1LtuE(?Bmr%R zbzh;jP3>fGX9e;4k!o7|e7yYND<;^y{UmHMP-Ff}(PxieX`X<|WBTF!a(sL2JZ4~u z$41*mZwGw&k!P@M(jNHYSE8>NT>kG%@#1Ft<9okaZsNCH{!cuz`R8!*ZbK?Ex!O@! zcZTl!Jxonb60CaS0&_k7w(arWvXxkS-{`Z)9NqD^jmHIN>}}%1i+4V?+vT$5;#5E? zo01*nC4%Ke>*bahHFRHmZ|d$ynusTG!ST^&tH=NL4D3C;N#H8gl#>l3rvXSbF?lG2@blfd2|dVYvl6uLcBkK*AeBR zSEOFaqUPvQ)Yf2DgODYMGhBc)*&;6X4SS&S7M5fkbOCmyNz+F~c1h)Dt1j zfy)`;OqI*j#pNg;`|4U=Xx&_2ad|%T5Nf)lGLkG1t|9cuAWx`i)SfuyXP0*^^L9SB zMELaBHCq9Hp8@Il#g*3?_}P4vM<$)2jITZox$j(h>eC-?Od-UzC+^}c(TBJp+?xN(Y=sBc+nfz@&6_gMLMHc>8v8SdiHEi<#;TO3RfR4t%gIOk zFAj6-mNdt-hbPxo$p+FM*Wl*@SGNQOe|xB1$k74#CL&8*jg{=h2r(2vi2AJ-y%+Ha z=Tg_v^8AE5p@IUbmIFLpDmA=?wbx#1K_SG~R7k&gwEBlE04-Z=kFmdg9M3J;&m`?K zprGx2x4~!5`?`t${Ws^~Q~!+~q$y(Idu`bC@UP;$Pi<@B{gTytvA9s_pg#S{r=g+YovY$AVC`>Tfo~jsor%YvFTC-F=tDX8-ZBfje0pN}A+2(=2Jd99 z2kiWN{P(`O*#C&WCjR^rb1?qk%`$$L3jAh3a>zhvX*%c7)e&mgjyU{)t4;XVUpfUh zt*z0#O*Gb%x0!`Q)&`bOyUfJD^sC1)VEwhxv@m*DqG6{m;yW7_#$v9k28|Ey`;!S> z_`oY@eBxw0^qaWy;=c{>v0we(L_bZwU)D7CD4e>_dHBg^KW^fet~&rr7dBw*5vQ5> zA3rn$zyIl(z`rjv@f{C809XI|OE~4G=re)3c^m9Ed0WhauM-fArp?#Jn-@m9f9mpf zygzFhw*BI{CcbZ>+VUEb+yki!P~ER6622fGB#+iDlp?7 zJ-o5av8Q6fnCbpMKwBw!2zlp=IYqYBBkAu$rw+Vf9 zht2S@AAS!F7yZuUopjVMF?56B=)3X*lmGUTA=v#({lmH_#C@zAk^{Z;xu|{L`prXV zUwd5)YM*c7bC-?A;b(olKpj1-HSXB2V(TBBjT7%*-^54uU4Yq(HpWL!JE+99xlB_; zkuIhwqDZ%X1L}^Y&zIVBK55VLs6FkaPHyVc56KUhHI>$|=(}?L3hUT{$1cMUFIvyU z&%5$e?ARRB%4pg8I79L6{eOj@eBng&9k|S-&(}NP3*Xxd!>bx&*Uq#WL>u#L+&Wsf zr+g=_tDOOQ4gfGc@WEra?1vYcjCFr>6;9n@F&?|@hbHTy^?rn@U)v-Rzv|Q-5P#$~ z?xy}be#G!S?7E-e{F{g2D+e8A(!aQUiLPy_xgPQP9WZEMQ_{65oyjPbmd$Ke8e7Vr zS&Xr&r8H}r`k-IGmgt;Dmp;d6EmwxFsm0I~(MaT`XJkN91*CHpyDSZZrYrxf;mSw# zHld|oQ&J_HTMDUB`&;_=LrbPlx=N=wTbN2+OC_VGVr= z*Zk{DlltYG#^IwUd=wMkxI974om^>0o*A|hJ9onASq8|2GS`Q_Upo7)eT>p3X z|MZSK?u2d)Nz=G6AkRF>0q16|uMS#P3w4F?qJECho&^gQVA$|s>AC^GPX$44uKpZd z3dv2aZ*9@l=-9B*uaUjx9&j(+x|rsTe)bB416PYn`Xp`T4P8=s-*$p47xm3B zwr-bPcARrKeC7j=Iw0_o+UJ|z^Gj`XnFE)(b#2!|%#o`dQW+mFN?UAW5yP#ql(bml z;giMJcYxpIy7VNAxpvL5kR>2Xd0#n~j37LHd_tEvZjNzsbA9X5!)nKl)(=uIkj=Kx zJiy%+F5OkPY)g`F)vEBK4{8B+k8tyf^5EL#?Y}~z^bA7cZCWJ;DvptOT1b0x5cmvzf-b8CSVK{hrYnA3tb(_){)UvV>&RvK z1fq{tv!xiCRB9&F?h_$#{nF~VW@Fl8)68|daob_#ij`Qga)pVnT(JUk<`f?uiTZ2D zoyfV7UW^BR`eocQ;a4Vl?g498%$3Op+LkZG!lhC9{zHeLZztR^uO-@NUt_M{`tEFe z=AtiSe7_FP(h!Hix3LIKD`3I=Xz!CaN6Lgqz*Vh_umt@vWMFeb+%nawrC79hIU4#$ z4-XCMo9Rws)o5F>*jyJcE8MUhGzfjzYNL+UtCnC<^r9{FA2JZlwKBK`KC2)3IgYu0 zeBtKzJ|?MU;S#j>AB+KgDg(Rtu5)qfOVQ2j-+yr&`XF?TQ36dHmM>~Gp;dhcVQ}1d zC2{euMX4;M!sw8JXV!w+;t|NKsQ1mw<29kQ$#(ik)&hBZ)q>Jr!i{JkV1QWGNe?fz+=&psFwx}YRRH%5#6fR zf?aGd^aBR>XCE~7^Rh;|R<4uqpq8XVE`L*t5htY^y}&i3!&KDO;RRhy&c${tUl=Wj z4TA@vrI6UZESg`f4TCVKkf5#j;1(sTz|uEy@8y5R)W_b7?DdcVXkNA$i&jPNBAs-? zS@_JvL0&Uce!F?80=oRrH>Jn4Wt$`z8JnNhyo*Kc6r};E&6{61Qy$Kir+l-nfz_0$ z9$B1Fe(@`wu}A0Yp=T8eVLjB*)26U875Q`I=sn=>eN_X_0?=>>9kn!Z-U2fJB%5r5 zGxZXG4w645SqzttE7jwZJ7N9wO0+JF9&W~fAsEoCSpHIZ?a8C{$9-Nmcc;*vB}{wj z1<`+G;ag#;_5$3xXQ#jN%8bH3Y@kVb`st^!?Y7&ZU;k+T(bm?E_O`adwXGD7!p+Um zdCIfTK8tbV#^J5E-YQGbbB@ZS*+w->d&=4Usx5lW@Ku3zaNu}J9vmFBoDOm6F8)&6 zT$V3KhY$}3mmXGLSyz>zWLD_pwY(9wl|wOMs!-C>QH?}BE^(P?Ps(K4jxog=IQ>)_gG=W%W3>awpsr$Y%>4%FPbcqm7CfNv|u zi=(ByByjBvx?67YYT@z7R z!PBW$NOEps(1k+Ti8%~x$HwI_aE_(qKmmC-JE1*k9W*$)Iu45ABUa$0@$=F4JPs1L zla)%SPT7ueSAg4y+qST#>s2R%`konz*rqJ*1J_VVdzNw<-HZ_Q2otB_-iOuzS=meU zVMA{zJ6*G?MGZShiII$Ot+71>KF`+Iw2tP7fa_*@E<+#4ivQX9W}Xq=@q=21v}AH$2%1rY4$b@)_b!3tM@X}i%jdLF%2ys)Tz-km*HA(|oWCRSr(s&BV$wMo zG{W1QBQv-z<DWhvUkyb3tPJjwcXse{@N2dT^i);pHi?mpK zx*Vm~&XT;mHY6v4E6?$>)8OFE@o@2@JZOJ&ZPJeVT;`4&A2{lPr*5gQ?R*ZdK2ebS zla5=6`SzJ$SKBE+K<+!huRAu4D_^22|)Wew#;Tib7* zD$q3c9gN|9(L=EqPu={u32l1vH!-eXjbv!MrghI%4fNbO@o)SUzMDzVP8~40Rug zk+}AAXhh$^Q9b=o8zieQI?Af^7AVdc?GB5h%MZw~gcNPzkQ&*-hCTx^bS+c|*M`+o zjGHx*E31Tb_Kc#jF9r|m3-@_N1NsacYU0BgnPQqEnhSKp(REOT_6)KYzG~czhC-hV zLe(hRyTQ%rbS;D(oGP1VrLz>|k;S>w5}yTcdInbGz@uT0U*&w2hnXHhs(&42^f@1n~9ELdm-W zcrTEvM@p0G=BynYb#Zm)$PCW04>i(Al&irk4~7nibIQcg7AfL~u;R}WYAa1S<%n4E6hSp`CTyjVn;nEZ($mx=WlNSsh z8h7PU9+JtVeNEf09d)>%1IkF_&6VMtO-iR7yzMlX9@6%64yz<17@1ub2ZD?)NES;o zvWD>R$pw-|%Silf9+Ve1PBfjf8(bMFO{yD^?3ZoNwUw64Px459p4QbLE_qzw&V9?j zqAcdC3SHtM0F|yE@b?R+p#$VKL$WnKUOszdH<#8S>0C&iIjV%T;L~u7vU0k# zF?7}GC8$et8IP|+T^n9dXD(4Y=tO|GzB(1~F{@sfvKTdkYjw*lnLX}4e}?O>hIRJF zw|Z}3l>~JvF zv1$(=GNK@2LG7hUzV%$LP1&*7iB=K~GVlw8H3t&qyGqaLoD6mRyE7bpNt;XaQgJ2c z({!r)QeB)`q%?MUY2VhV;2K|JfjYN+rCv21TZ@`?74plY8b03IUqugx%T2Js%`xeG zh=wITm3Z{Gp`|Zc;6IB>Jy2zZxjg<l8~@_FH`wU9vRUUfVo%QYPsDnU)XEnj(Q@JDy$?@gaW0@DQCR#wQr@1_M!rYoCpvncl`#!AY z(j?y+Oli5M`pO(zYw=jS5d|fPU&@; z#OplUG;z$n2_J>DMVqY6zhwK=k(100a|;&Nr?fnm?_2CuM&7RJXG1gjn&ItRLKNI) zQ90z3`Z0u`q%p33Rp90JA=H#{O9!pTH6A{Bd^+PRXV)d=xysP`U40?xAE$2;AD5-z z@_kF4#2@g_XD~8^ju#yCT%A%sb9}fmoZXPz5zUm9_|f_}w@2c`fqN(`DzB|;<)K`= zWK`OgO|fmFB>_QStOD_?@a@Ao?z4vWEAwHcL6LNg#9O$ev7j#J4x@2$Ux-r4_-=X4^D! z=L}tedZ|lC+mx+5wVxeBbdiGPBRW<~irL^mzY2v{IcyO)t z`Cpv&xlXERIc~&UX|=U!IdZJYuq}!mkHeHU1~&sa8!H`|a+ZpM`h#3Pl}~%(Hs4Tx zlcsa^(mZOVBuf>V&hc6EEMdsHfxLtJ5Is15sXYq;Ad+L;MPE{FS)S9i`Fm63V|1`&o!=gd5)H=D?}!0t|ik>!HrYs z{GdyuLRt^0d|cg}-b!{ zI?;g%#f+!sXxO5D0X40t26I1iPZLK~btn7N)7`EfEW2ypO80Tx9;-8<>)-=+)M8~9 ziP>;>2DDW_la;L>Jk-6!xA8SY2c)^&4{7Ceos&r0U1cRIa*g)__Cs3qty(do#9O&a z|ER!d;7!6xHq=IdX)8J4=q!LuM3bQ6wA5(Ma`&SR30)x$5WIq9LEq`r7WY`5a#mIi+=o z1|KA$0s)veJ588)%!4 z&7YG?IrvEq7AJ#mrh%cA^qcDgPUpBb(y`!lkJ8z7gQ2(ibNWkZC0(ZS)4DiF%Q)9J z+QCPv!!?JLCrx{3xcLnx%-Jz+Zux8$Hy(=Ea2lp7m||!u>59=EzI>{mN(tE^&}oDvwec)k^?Dt`XHwm;RRJKw1|${+i)U^FZVU!_Q?$C@m+4M90bLn?E@m z;08ZMAi-I%_ajuvt7Ph$58>RD9r4iC8J@Rl={SHyfG4gB;VrC9UvS=sod@KWs|1~n zD3YP1GFcX!ZiybE1JuE=({uo>jUGQ{y%AbY)&aDND_T3n&%_L)$4A&pu+sHJN7z*iWjj1#p7yNBG_9$ogO zGl`f!#DsFL2B%XYJztj9w(Cfr1KH_8KkA_C1T3>>sj~vl&(#*!nF*z%eZgk#4*Y8zT&-Coh?DkK&?y7qA>Q&XN_g+=^_HbL;IG?k<@zq}CzH@o) z;K}jl`T)pV3@W$JYI55KCGg_zCF@D~P#Kj_m!kcxV5lc;w5OaeN=G}|1R8L2D$!^m zplOYlwK&b@e6nKd+4nlI4XKQau58|1dz{>w@bMk4alHBYPV=h=)T(kZOMzTK)grnN z*|JEJ9}3C+aqYzSoD#dFaasv!&g}ZOOQFFJXNGA$H*S=klbM!ra}#3X?EZ14SP5-Y z8Kp6mRu!0Xz&{>f+M?|PvW{}|tp&c6Kj-#rT4}v%q^$(E-huSE`_?V352g*y1#(sk z;OB!IU#@*=jdNoKB>Twqlk1aZXlVXyh;mAUQ8BlV}&OmUa$Oq)Kfo zSEmI#CW$7crEU&thb~1wO|l6YRH;9vCHqTVe240hy`lapB)+Ob%cMHFU?8~<5=MsX z)!G3xGPa{a`rX#0vBpbmBdrm&Vx8UwBIh*;@W~r_J&KhMtCOmG>et+jUE?}()df# z7TS(WUhZT}LbHQ~0tE&(q-`eWE9^R8=pp25Qjhu%-?6F^>bi~+wZMnw(K@ae(;h3y z3M#n$vr8T=@PdbzB=f+wg7x-J(y;g{@C|Y7Ox4!;vX*ps2*^=jNT=y}jLWyvw1WGf zOWO5G8m@$UyM0a;iB1AtvC6}-b2U3@ZP%d5)q=L^!?z2yhxyTc+5suj zjJE2gos;YEkeUU>l+k>xC#-&6*U7aTHC_d;nU_d@wfW9F0F=N4(c^6*wj>j14s z*Cw?}l%C36U_jOtiqyWtX_Q;Kou1jPX#PUi=G`s$r5=h4lekdQ{47+*AhI7KN_8@xEXM|)L$|%Qus2& zwXGdI5Xgg8udEI2q6tG?E6fUu67P-p!lFX&{m^Z1`MjWeY|cwGwecLok49zAw3En5 z=De3-IKQx1)Syilf$MC?wa@3)0e9ZzI=`S%7`=w-nxVCX<^E95PE#L{lBd#eLS|tN z(w|V2#?0=Evi_z0kj`DWbEoD-AXzwav{C@+nt6#{F?7BFmD5T|16_eH$6rI%&OY@F z1q!q+s9)e#7)Ty>Pid%~mCmqT775_&b-FDMK3Yyb$zsra$4DN|=FfjhD52{*`JWjeuMc5!VLY*lWUv^6?uE0dlhasI;c&Nrw>kRI$==C7Muip*%GO zd|gRm+1Yc>)-I>_)NDvjj+Rl=qlCJWNdvm8M*rQSF|+Ki>Q7iNwR+Yzcg;BhIqQ1`zDAb1kyE7$@%<8Chk|S&L6mRXkn&hlftxr1@xXWwA70o1(!-(t~u} zltH`RmIj=gSI(1j_tc|Ho|d*n?>T-g3SUrOfPmAB9ANvbT&2+Ic0%a#LJmV!mt^)5 zw&Q%eoI{>d+Xl-&2+ZcP(Jr;3X$jqrHWND6m^B|{7AM|-H`;E$j6(*wTX3#I;4({6 zm+UBt(zs%CX*3nXlRs-p=Zhgrg-}~(IrI!D&a+jN?n@N2ElY*OmHN~)(lJQZ(>yQ8 zV@v6{9e+N^!p(QW#L;pRYX=`GF1Pv8eVfa{E2IxwxILds+W>j*;L0mdpa6yKGq~*! zJ=LVhVm%~3Bh_=+T<)}0@_(A}peF`4Uzgv7qdm#8D)1*1^gj-?oQ?}OKJ5pM#t>4U z8#!j=xq%H~Yhg&^9m)YzGb!wjN)aC&A8D0oM}1es>eE=4EK(bQY!yP<<6;qsPU6|V zE3s{%Erkv-;5a(Dmdm7YWlCsE2{a*mIkP8?vkKrv<>lto z*KZ&#kIPI-tIf_+3_ouCT;oG^#U&r@hs%|4`5`*U$>yu$qRry!Ty{YR$ZPWmahpD# zzIwiJLNR=_qb=zwL0U^(o3*sE+P1%PS8_goo58K-MkI@F@@gZc@0xR8nP^Hu*GdfFqag zrplPfrC#tqPH_)gjOT;liAq6kOkoZPv;lhRB zqsNdavp^W6orI0-I=yhgLgWfAxCqd(_5z&?dfy;h4}tR5QJ(T-obPJ4O6R0ua_X=n zVZ7^u%_n!A&mHyXQXefWZewKKa!bGLAG9T+T~6!5ksy2^8v;t5q>G%= z`K(qgy&x46a|1ItuwY@U`&%~_EL?zr3QmIoS#!DiHnM0nx1({DbF`AV0m58%h}p{0 z53bC$Q&<<;JVIgCmBfLMM8f@oFW!#F8R=;nx+i7L>N8*vAKX!G~ zmmh#34b`p}z97yn3kmeNdDf)N&ZBdrg)10(-#knDO6zj+OS%ey7ss3OEzpwSzgiN( zKW#n=Da7Hz6T6Pf+SHU+TYT&X^id1+=dx6AFQ}9NZ-O=C01t34UrOskNI*wNSc1I8 z;{#Ml7LYoCJX;cfCEQC;9(i;ipL%%Pc`?26&}DHS5?o;bgf_Tw&e9fz64G2BIXcNL za4y(4|C0XstO>VXLdFh+KPQJzE|QUBj;*|8&_8T(hc|3Ea`m&TiG$2DeJppp6l zCN0S&$t=mkwNt`~DqQ31C<=4f2qg{OUq#zv@op^(OaOS}3c$!Vjf zyT@EdmFAA4ag8TDGS!FvuzU@GDs@AQ8X;4uqza(n_$X(2ipoP52Bor4XXj7R)7@Rt z`O(OVu=bK3REnPis;3t|mmg9We%qHu_8Jnpd%7`tRQB<1N5mu6U5Aco>)!}UY(Z14 zlAIop;+hx2^tsNKb@Cjd?5kow#nE~)QX&PfN3lUEx`?2v|7!jZ%9=4Db)vhcr?fst zp+J78Jk&5s8y{Mx8NQ7f-vT+I z9G8{R+}O;e2wd9EkLtVqQ%Eq}d<--nTJ$Gh%$qmAdOvjNP^?_J62nIfhorx%6fl-) z4E>Oysq!J{4{!&B+~J{udmp15{D9;ct%Cd1&E?4KtJFT_AvtQ-sT`GygJ#<1c*7$T zkmugKKt{-_UvE?+IYuqe#rISpl4Z40TT!Ci+KXEDm$Yg%eZBCz>@*~oA7V;u`6y3n zDkR=nHo$d^<2P|3%UpYSDnTA<2EoW6(Md8XPaZc<06&I+du#xH1t?Ej zTpPZ+()>zpK{EHgG1m@xTyk^#q`7j*;^IT~i-ROTz*{U%|3mx5(S+!b)L&^Wa&2i( z9c~<4kYuA(Go0^J7(GpYS_C&#Jx5`Fks1-)5s{bH^KrT=v8N?PUizCu}u?teXBv~xU z|Jd}tSc;lX7f;Fy;JYiyCz%^p49X!SW|PKDA>C)%zRoCHJ)VS5zejY z;1r@^lahZQ(;P$Eup@UjRp^%@y-@LVRplzyN|zA*5(q3v^t%o?UE# z0)3AO6DHu5S6{8B%P((HtXZ?BN>iq%=sB|2AKDG>z z+~&?L5sr?FX}P87i#P2n<-x_@_3XnHkrM)6kT$sSpyiwivaej*t~r2E<}w?uve12s zREINrw2adD%s*GxCzo$!x?Dww=?3^Yw_Qz$JlwjVX(h-UI)|ZS#?_^|&CLtl%V~i> z)lcQ&C&}x!g6=iT-7CoQNc_3Jxb%az=hK*IQO7oa=A9Y6CU${?#2p zhC#G;Z0An{3t0DpX;Cqg2IoZ+aR9eJTd z6wh*bK)R1yKIcV3r;f@<)rA{pjyAkCDT3mBU_V0&wsT=zFNtQ8^(|F9u=a=&X4XB7 zw8TBEI+_E{-h{vx_XkyO68dW;HEWJq75R-b-895|ZL)!&CKG7dpzBOc)E~&{&<oX-6}8 zTRP{3#WL#d@$*x(!>wyrMS#i zoQNj5u({=~1PK8?7Nzy2<6WtDT)SMGT!;}8M{@mf)d`8Msd@8-JCZr&%pf<0@bI;H zL8wc4OQt8p?9ln4Wq{m|5FK&NCnpEj4yQw4WTAE7sN<5I^3g&)PG-qHaBXpOR!?66 zzrIQR^vyBA_sLg>w&hy`)E?3Ll3qx1aO=@mriA;fy3DniLN~6Nibqm9pxWwPG5Tfm z2w{*|EzT*0(2=5QT^$}b(R(TOlzbMY<3!aC8Nl$e)07|AhD4_rKGHoP`%Nj&7k^9B zDYZ-UTr^Y$$rf_sk=<@etxM?^fMl#15;MnsR^n(#{6m^@(&RZOw&vJrH~PYQXVd9; ze*!cp%MOE+E{ zk>nq?=_F0{cMx?;y0QYzKwo&L0&NFZAa5hod5h;r;J3S3gA~($7tfIK;r0ex*htH``J-iAJFYx#ob0lY zd2@|B0_)p+xDZ&wJ*V|RT5|}<2a%D>3z?5B@b%m0T3zd#tIydQEwt;hJ1)yk^O6UQ zb~^pSR`MrpV;X)X_zyd=NI(Q>kLddam{paN-NR7l#j;tN!f>u{)4%B+z*+GvAmt7=P#Zh*d^2n97+@;!~u>&_A z(*6MOPZO=o3cIIK&Ey}xWb9R_8gL8NDvQRnUW8ifa882(^=Pnma+6xHya!#fO;|#l z&k#{>`&sLy2Ady!>fiDkp4z}`Yt1We?a;WoHOyRr0tNaKD&XD+*M`AP(*r*{ppiB= z^vXdwWD)j{Y`k39zyS!VM2XonmC zZ~A~R**UXK%k8VpgBxepJlOdXtxs>#t1dZ?ocXrpmGma7+vIq-bP|Nd{1w`Hc&q8)N5 zK@P6W2gOLQn6}ci>3mu*pC!z3qdu`kz)eiU(Ej4O+aVgPWhy@>YbTILzpFg*)1*e= z3g6P8yMx-^su7JUT)0!Ba^S%0*2aTn;Vyb(EwVO)tD; zd{&G0ltXbt4!N@~6)<$Z7*ndJn5!+HW^3`Y!YwV|g9%OsFzFCeqexv^5AetS94~1s zH6xSV7b>SqE>0%st}r4jp!TyY-kGBW6rPQW84tt*vtV+}_h zE#vOBqdiI!(k}?IQW<@En5Dfz1I{_yMgkxU!(~AzW69bLaL|S08>&o<(__ln>g>?T zDGrb%moBlQxOGN5QmI@m(`m7Kpx!Fv_`(*AxH#`U$iNwQ&cXQRpi)PQ-IS1~`5arR z%m+K(;NmPv#t{EZwTQ-Fod1>lxy?_CFMa;jzDnh^EqX84aMLSKUVf{~j?!{7_{{_L z^>xGUcRh9atPmS7^3nlxxld1ahPk;8B&7(G#I^u&TBmr~SE-#KRnm~{dAvW;joH*Z zM|6;S+y=k}y&eb6404`pB6tqds-J%wc3XjbtCqE4`)qTqtz7zV{HJa@L0YVY0tE&o z6sXBa+e%lc>)KS%jfczeD-U03W5NX~c6csr2swE)BQGbrMtZyov@k*^%T^wm4^rQy z_%@wgUijGp6s>1Gl3GeOaUOIuwL`Xnmrl!E&VuHJ_Dw3wVhddMfIF>o$sy5l_DeHz zxHdx#Y?KQ0J;J7n9$ZQ_IVBB8(oH5G-KSfMAJ!+MDQ-E}>bODUw-7nGc5Hq&y%O&2 z5miXXp3-u3<=L`vv!^_=fyiX@qWMyrTt8@i&IGyoBAGgAyeL0cyFSw)pMBf;eZs1M=Bgz5vwi?c)0d;{+8yKJ2O zpG)_+@hiYUaxTt+Q%q&b)U}ER0qlj9I~)e1PJY!tS_tIPlx}53h*K8`HJ@F9^0SqU zP~EUS6Xyk6V#J#ZE>N<;t*6joaV#0_XhLG|60u%BuDFEK&~oKypEC`#oXP_DEjV=@ zzWSWp+!(pXiZ5*qU!SEn{fykj3vhNiFjLnzmtkE|HDcW;ulkYIb%e;H7<%obrYkgg zb;a0p_=4OaXOJotwZ*)?wM?V`#%8cZS8cBFEP)L5C>Lejk=>ZqO*f64ZwafFQ6L?i zJ2(mIXpiov8-o%!$6q6l&sE~SNPocG|K7Dgfdc&uDVVpNzw6*qA-%n|d2n!TEVLjG zrQ@I+X(=?a%XL8g0=c5OUWkiswNNf8xugWXT{zcHfx(T|(t~tNEuH-E$nVQqz7r{A zDCe96=iJ~ZmmC>)&+Sa?JrcDCnv_X)#>GDw_ov}=cF3u`K%0SV-cx1qopRJIBR;y7 z9ji(?*O*5-vQsRFw8WGf98yZIU6VYj;#{n$!G{QRdHO~T0v)%!sl1xWr*)MeJ2mSX z?(l@RBgsqK0o>-18!Mk_kz4@P50JFfzHg798Gdlcz|9lK6G-cjYgKS_Ey*sq08X!b zG?aIIPt)8y`o=A7L1ft>wC8i(oGZ86Rsuf-c^zs&77!j>+FpZPT?yR$+x%!g;9rB1 zzWMA?vMhcvD=A&_Ck{37CMsov(tHUj4Cq(146Q{>U)rMmO8ji1s+4QK9OaWQpxB<$&Km@v0T35ta%Lt}2|ZKFHRp~$O)=eHzy0=j?cL`fW~~3pM9?gJvY@l)hd_YpP(aXk3@_4KyI!16h4S) zj(t^98|hn-293~!Lu>m_L7JzL^^UCamhurY-Ca>zK-aIR@pN(1=B@n3T&fl%tPd@= zYMX-m`pEAxYb%28#(3nhdN{w+6zJNiLzX%<$n}($qF&J0QdRD>HFLt~>86ipfqute zuzCgRfnKo$3l=R$Z|T1LU&`cD(;_m0ylJ7lxFAD84n{!u*==$gG%fH0`FkNQE}=VBNipoYuKkasJT8T!k#&K=ht`U@lG^A#rQt9nH)VF6NckWcdoIlx zb50KF`3I#{o-z$yPR^0IY>E=-xqboZQ#hYJ1my85>{T0q9@~UOZfS?9Q%AJ+#!@9{ zYF}JYghNspb#*(cteQzRm849{!k>9^%SS<88kCk>Mv{A%%nLW_Sd4Tx>4&&8Fq%nzqUD;@XE$PWe%u(pbZhFPTr54smo6e@+HYW(aA@ z*HzBZQ%Gx=vqE%@`E*V}?vDzPS2^lQda6D3fw2Bkeo`AQJ0X=zGW)_8O=P1qQNCjR zK+Wz)|JHaVHC9)-$hr}V#LpKh)V`Kw-D{>()t^jMNc?=FR`V(kglUbnqM^=cV7LhxnJ+?`(m>Zr8q(_ zGv#w1xCuAh{S;nV5;Z(>(pK1Q|F>br6yE<6n1j@I^eU@Z{y^nA9B`eHtIzbprYgE>Zg%Is@xk_LD{=q}5Ajo9jK---vske;q5jb~5SreewWo)Tyy%(F-Ph=M6XG{ukdw$68yO z^qy}&2s^Gfti)iU;q~yE@$B+>izrp61zRM0KJ$ZDNmC9Km2zmKHFPnw`{PRu>dF%U3dbdebUX7)*@4@vq z+-p+LzrF%p)8B_r?!S>qn_1CIG3(yzP5Q=rpTq0RhhwMrf6}B6nA%z8Q^vB{|G_`+ z9D=vLcQ=!s)Sw{?*1eL9Wz2o>R@{8=Q<&QwH9UUPU2yOryJPZ*c5E^)O4rx@@LKUhRgqhIlWea z8ij2RIRd+`+ffm7E*`w?7To*PT$5hXF%FyUatIFDZL&!ZFE_vJW!(PP$Y0+3#z<^? z@DVs@>v1NXbvQM1m#wxEOA`0FhJQ4uO8!ZkuKb($Luq>8F_@rNu&3zjXHtxcSO|8P&Rf&T6c+?S44y;Ay68?I9RY z@Z0}(#Y*$_8%L(RxYZ66>za4_Zh@39Ls9h`F5 zN+c}|I}fOR3nc*6Kq|kwuc?%(aH%P*c1B(RRYq=EaBfWvK?W{{ zr6C4yT+=+I@yHT3NMi%=<|ULDNFCq&gyez9o*`z7+hfr7sEK#ADc#3usZVx) zxxQ7*^2c9gsFeD=g8hjPdx>50@n7h-U2&~lrn z&t-E~mXnnWFEmq^lPzhnRKn)lFY9tOZAt8}X;BKAuJ%>cuJ%h<^h;XY7q+P3R~A2e z@}+V2tu09(>?Z87=jM%Dhd@$9ZmrO{<>ZmiV#L|q4e2y$|DxENClbd-P7JGO2%MRlL8UA14oXAJ5B=9`##D;!R@$Qfe+V?7V^2ebYtV%qN@NI3bYuw4N;bp zXGxKyATZRoaItNH0l!PrU8!%bx#a8#$E(Iuv-dHF^w+j(zM@8xY(ojMrf4kI@e5n=m3~djeqoE&tIBWZ z3vF|A>zh;88Ue%0r5BRlkk*IP8; zn}r`TsUHq6e^qM<9{ttnCjISuH^%#q+!u$e75$Ci;ur3~?@s*^9zOMZCjHSJ$6g z1Z=p;#+az1&xyQx%cZzdABK4s;t(PixCv~y@up5q&6ro zCsg!}iSd&+#>PuEdSAWOq%XZn%K`(h2zc}Lplb${ESRC=LeK4l- z&6e?H6Q}3lri(5#>4!Ew90wjc5lbKYvq_(S+8li0!cSm_VT(;KpZxb__~mQQVDtsw zF#SGwQuJjgz4E{2dgqmoW3Bg;zpNG6v$Ea#$8&q&goC2540f*S#;kiU#^?XAt4W{z zH42RtbE2;x{^H!<;jUMgV2>@MuPD~OtP-`^{qQev`USHw^Vq2T zUHgmyhK;ZNb$Q9JJp7B(alxFKCVA|8-i5u#0$t2@l)$%Tp_e{~e_n7A z?idm2_W?7v#?E6puw?F2CjGA;T#n@jd=8&GAo|i)ml>Awdi|wISJ&$i@_JqQ(v`UA z;;YR4lUq;02M^vN;zMZ4DAUC>)%J2nnyK!2#9V)Q#*gvF!Jok42Sqeb{q2A8)wy59 z_m7UgwAiIz!*xIS2Cm!WV0~=j5^X!?mNf?E(> zdNwbPFTgK1jz5>D17wr>89r0VE3KcN4>>e(wL|km^5V8Qx$H72ECT#yOfrEAatMcj zE3L!13@*6fu2>2#tM#jZV@LQ31?mY~teD}8B83x-Q4 z#WGhF=a=g%PrFE#yYiHS77QH`Rjk9=AZZ;dhKF|K!$Ie>+dh7rOfDTCG~fnJQl=C* z4NxH!2L~j>+_E4-wu;=LPDb;@)f^?$nB35II7mi2S8$eYfPf2*sAKUtoI0UBO{*1; z;;Jh(4*t$Iro8;qNo$_J8W&y@y#V#;3%`hc*RtY_?RUcV>-`8P{_F}D#V)V-L%8@L-%hk!cEi9GU)@>WgZ@>F_`|&ea!8z z&bbCJlw{pvh}*BaG|?50bCBYLbPVX?MW|Kuw13lG_Qs|t&sX%a%AaoP#m;;0gDtF| zdhC7u5!^mM`dO?Q<6g!s|9J)n9}xXa&#jLrOxtT~Oi(omm%n^3Zkr#yOmg7#Nm%*D zs!$IO!P9!mNTc~iCdn)km+xY(v{x_(#u~q*Sl|j6T2U7WUhNHfHoQ9}c5q|rHQ9c;Kx^gy+1*#=mD z^blhb3_mpj8||bMtd1b@UcnJ#_C%NL9w# zIN;RiXFCswi?;lLxjb|2d3bED#ts`-@`p^rVf%ICHy7PxlGD%HAM13u_Hzm&H`)Pv z?zLT1z5LH!>tn(3(aR2xy?Q*h-N^Slt(?=a??ZOj8K4*A;eSUzYq;J=zl;z3;p_M> zrCIZ$xm(aS7j*FFHJo_j!o{}w}^!M}g>n7Np=3sXk-VDXAd>z?-#s(bfpPQJ#I?zQs|{gmUrwh64+PL0Ip z#jE!NFebI3qn}m2<${aw;@+p>o4Zdm>D7x~!K({bW86;BdN^^<-Eqx#&cmNK{*Fl> zv&B&J^6S6vUDu>PdfHLW^{Q7qhreEUKej(2dRfy7{ZcgL5iiqmG|k3}$FDQj>n9zJ zix1xw<0=ZW&E!>h{-i5#-@7CKF>}!!`1jns@v*a_m(jNw3T*rFqj3KT|1jx?-nUiI z3z032@(Z?A`+pifaM{<8k45ey^uCTq?wD_GH+ai%ym;TkcyZwnqhC{Y-W$7ZHnwC< zqxD^mQ`fBataW+}M4`x)E2Hk1bI&?}hfSx2_I;*H3e{}B(q5Ii18zf8pba1?qwS$% zI?d3zlvfL7T499s&-8}O;zP$(<4RANyNol zbosfKBWDJbqaG&*z%K)rS#p^c%3lk4G!FIEuV{6yv_}a2^GIMLt zH%2b~aE%@1@6zFz77Q<14!GynweF=cmuwV-G?ka<86E1&U)4&kmZTq0qV14mr1r(+ zRfxH-XvO&;wAFlNwWU%0X|ZZuyJ6Zc-o{wPwt<6 z47S{43mkr2^s?9Ies=@jdD`0e!40sPWCnby#YVHY_Yk2%gFKAV)t#JhOaW|Cw}?=@Wv+R;C)jnFNo+K z-2cb(aMSkZndAZUZo|1>`Ze^SA2h=3x%PZqcfnV2|KriiT>m%obLe^aBK&D_^fKM| z-?ctEN>VJo=l3T4<2!c6?g#YZ8|WKKqH zP}$nbR6RvWBTyhj-q1FDX3)<^p`)`CLsjLwerx99fqOJ&o)EnZH2;bFFl*^3OxZg6 zQpyISg)bc~eZyQ|?U{rbl{aTpMZziXI1%fdceY7ga_f#bec!b}C70yX=tcL7PvC`- z+nV&A>x6u%gxht{xu9r3!PPkI`jL~(?XG$ru3^}(dF26fy+_Z)36tjIiTh`n^s%@V01_H^6e}4-wQqS1WcMA+5G!vFU6?ITVtyYMw@iG_iF5J_{ho8mwEKOe^vj; zr$0~~)zu43`q7*2!pfaKgbh2SIJFnc-gp&DCq*x3ZQ9X`Sr3%^{ArV3uhj4RW-Y_W zDO;PWTWv53+>H13L@#SC9x?&*Uw94+JENC#*PFZ^#*n8!_H?XS_$Y3=YbBUo+`%tm(zj?T^7{$JaBc^#&z6jG}3wU&J`Q0vrKY)i>zmVaNc*s;B;L zu2*-xAK%z*G+w^q8zz1JeQRTS$uvH3{aiC9`<(M_9C*Z*`0|a>m$r`FVtWi7yK8B^ zMqdWh^RD5iQAaOpKlR6p@Wfu9$LSmX#ialGM4IlYKmNQ#6MdQP^bP)!rfE7fRxe$K za)*0Ij!b+ROO0F)>yLa1FTWmrDRGy1FJjiFGceU!lWOdy*nGlY&HeMQ_F}h9eJ|g( zIMmpr{YRT&&3|$I`9C(d&u=#a`|Y(8)*b$kN&oTm8}Q0G=it3lqxt;r^%t8Mb(g7* z7&YWDPNJh54Z2AnW{3rMpvZ+^AsZRHj&ul0>-q9rGG*y!fj&ZN#|=5g1aoimvH4NH zl9F=DKWXs4IaN2pv~fGj&4F3piTpKwV=* z`MMkr=cG6uzV-^V7$gTKD|7NE3~PDzPa3L9x%2{;wiHxV>)3U{)^)kQ*a*cxl}J_A zWsZDiz~p^WDQ{Qk652Lx$8OKnKbubCL*<~n zLrkd43`)H1d}(}Kyp%&`DYTS$Q%Kf8D$@aFR3Vlg2PaFC|%N zJ{;{z<(zB)-zVCpPyb~LFY9KSXY#9x$=sSvrmfaeHI9;8fO|bu>sbZ%i(B+(5396F z=F2rM>93b5kPKrT3hdu=Az3Q*ueJc9WdlP(f4~k?BFT9f`FtxZtm0 zh5=xwF_}SQ?r>C?J5(i6B+zAcjn%*Ki2upYxn|*_Gv=pT(qUvlBxFvVv{_*XvT>R# zr|EjUDLG%?OeDukC(c@`Q&Bwt zadB#V9keC-qszGmGcDh6>ti6Rel>>4LQn3w>h{JU3t!I7&;v%=P6!`vBV?D;`f$|K zj{4jNiPkCLMRPq4x0~k`u%N5 zu7vWH@;IG=Lp}&~eY}0NbX-DtQQDC8;*!he;kL|4D4{MO>y(QxAJS;6Zp{y9Pph%# z09)#pz5EZSgZ2X=`fN@Esg6}&=CWn57{+BGc3+b+$+t+fK7N3_9sqvKTsGXN55Bd^ z$>icG$t2~|`#}jh$W9~Aji3@LOI~M?AZ1Yc2HcCI895|)Wv|sFB~6qlw&Y?$b(V7=41<# zef63l*z`Ro;*gWSY0|&AeFvPnXZmwV2#nCg7OnS~c-is+6i*Vn~ z(dRIBJm52yWGw_bG4Xva4Eq2?IhCheq-#iqc+XOHW44CV)xlInm@HYeCgQgOufOmF z9$U4-q~^VFJN|s_7##YoO(LS+M=@v43e5WbPfUgRn{I_k%OA%jKaFh02fuqd_Mg;Y zaV$wt{u!v>M_-DYb?`~}Z22>Ry|I9+v1Z7oc+ZK4nB>XdycD-jI~98lva*yzC-0BXeEn_68dzvYDzK7RFJ*rF$UW4w+}aP= zC8;;Vt-R`iM;`=feT+GeL_gcPK`DkC`Q~l-&Gj3Z^rz1KA8a#Z7A}AIS0+7dSV^DO zpNz3@yk@%Jqqj%;BW>x^kDkYVXYMY2`9Pd<%!U~9P|bJ1y6buDwAqN>+YM7bJ|!)br9l59j`aD{92sV3xp3h^ z6lf1DTrj}q%H{aAhu&wWHIvQ~AWG*CwA@Z}?fK3zl&5XL@5^$;f`to^AEZc-8!WDj z8zk;1T#EQy&fmqC$AY?SWgkskPFOHV{6XRO3KYl_l9S8oM6=msQIxp4R2I@idztP6 zt%i^greUVOK(h^z+gM3VD>)7Ft$uwrkWcQj;&?$zCvH4+J{s+8!NWHzT)v{k;o5Ub zTb@1QM;IDsW((?~H9Uq-kdU&!5LH+QWl&;Nj#7X;`+b?|g z7r5&!pM;{nEv1H;%cwC!v1D;i`3_Qh)hghRrV${QeMC)pE2f=hqjQVs;p3KL;?|;< zQ#O6uK^XnDoAC5e(aRI--*Ypb-0>j962CTk4yJ591;Z^NJ10%WMnhh%rn|P@7yB-Y zerD$OS?|FIM&FH_Uf9K?4?nd$&TA@^E$rKJ6V2oFR9GGU#blXxsH;sLIP(=V4TV|T zUhZMsTy zhhwLqCz*tvtEj4F8?lmKJPsydDf}hm=_kQ6kVGiVeU@a{|or;FYm%z zJ{b`u%}`_!);;`eT>7!-XAg(ym00-PzwzU<&ob#heC%3|soM;%Fj-w1no^&)eZQ$+?sxgcj>C71=J>=?zhBzt*i@f~Zg#l2p7xEy zD>>22wX?4{1E2f#9eC?k-)7R|OO9^cgHFTG_ltaW_v=sNhF_k8(|>=4NuPW47KmQ! z${0gvZZv$AxJqq`r%uYVQ2*nimR9|0Ho=_L=D zVg2>5=9g$bYG}&vgorsIJ(nFD9BQtod~qc%``!0&c5n3Z`di*M13Rx>JAdvR+KDx* zS6AQNjo9^K)tboP3>(_QF;Bf{N7e6`Z1ii&da-Yf6m0m2F05X;22BG!+Hq|fR6zYW zkJh1X+9eAhZ!J|on>L*!OMzU`{2>kBJ^1sKhn~Ba>I^{pS-^vKFd&ivO~ZJc(W6H> zmqVfEHn>6M9-c^b0rv?mz#p=fHc;K&X0BwJikT|V7`l5(IyS1we;v@K=m=$>NoT(J{*5Thr%TmD9{MFH72e%VO^?X5w;B+=Ogs& zEo8^jm>~QPR5}N2d>f=vjnt#MqO`*Kl-Sd1C*7l~#Z2v{7iiMi0w3?BH>efORj{1E zY9bmHSUMF@bxIP-hdcJ<%944}D~m&i4aLegS0!ZMVDrtf;j#gNAjH>d}Z{CF~{{D5OGHM{ws{wI(iuXnZ3V&|NYfNcz-8d&C%num8(``NU6U*{`9e| zf;<<}z0KS8Y$F^hh=Qf+h#pSSci1}C-x~)_J_R>D5Z4v+P-ufK&o^Uf>-Qzfu-hOy~YpW^9T_le)Ysk-qz-pk*wlY=I z^)-{%5Ty91aoFtxpT)|kTOvJ?TL#_HlFkzkY!+4FJmzPC!I=Vjpx9{S- zr}x6?rygL^8xG~1S~(bqUR>S!{U>4XFPwv4Jrvoa&Qy?tWPLRZ6Sg=I`)_LuBCdF1 zK91geJv0W*q?J&{$w&DlBR9?P?id$+g>jvU6EWU?L1D;vth3fq#Fl5=#C0%n;&>!T zCajIMdj4zJFU@H^*2^YUPjz6((5{kTUaK(3j zWa>V>*BLlv{|!+4uv$l@&l5~)NTuJM6V@@;wU+)ju+Nb`Pugr#jJ$aPx+`yoj4%7; zjv*M*6_t;lG9B-J_s;msFCQ}L*FUfYrgX49bB{qn9RdTnKr&_(^a0}ErckMz6jW5o z8@8q!@P5I_$`}2*dwS8a#YUJs`#zI?;FX=Q<$rI(N78y^l9gP z2-`LCE-QTU#)#sXwRe0kK2!QHM(?Xv;WTW4Cssvuwpw?6Onl=tEU2u<^~-B*%^P_A z^~i>AvUUds9NJO+D}TMw5i}h+S|;J_Ahi+jZ5*Y|2G<6+*`V#%X?msda-3mJL4fqd3luF%4LU5u2UBp}oKQmwCC1!Xl1`}K#=!OKenve;Qa!^g3Hptliw(O78MAyxFMF8dx{%~9F(F_Po8}SwDoT)JG#|5bPVDB(y2to_7j7c zVMMi)5l`YR$Pej#kKpkeRiXmfF`&j=4Qv%^*N*8>`<|m8cEy#hGaOovx>HSPrA>2!ctkTiy64(eY~fAmASn>lbcL-(k4He|DEDRA0uA4=wfdb{p=9IhOBS=y`7Mt^2LVbXf& zdFWMi>+MW>T!~=BPVdA!e*G(jwOejX41PFSS;tct$=@w1O#hiN~IewJ+Si9@O~W>OdDOY_wqVXfGvnot^}?eOQT|IZ}nzP2Zh z*?u_UQQ7z{+hfk(@5JnPL_hO3b*RRhkKBz%E5A>)kNLL~Q}%kBX<^(qufiWkEy3QO z+{%=6B_wD;_$IkoZL&xm(t~)O}H^I!eF2>KVd&bl_;J9rtYV~Wl z|Gxj4;?4Hl5aq9Gy>R9CO!~a1_cmYEnqq#|PqG-+oQ>QTA3Sj;KL3NuOnT{>-Epu} zLX8!#{0Fx`KGLK%I(QuNg%knii_T4UH`li=xd_)ib0Ch}dX#Bz^=tRz-dUTWYhg5g zd(M0-mRxi#o;l!nL%;Q?)p+fJ`|#h*_cZCr+)p3|s8t?4)7IU}Hy4<@<)hca*deuN z0^QF%fXDSz%$OMUM=yH;SAOq2JhS&1rv51hOh#2z3_7rBsn3f`eJKMNkhL`xMHE){q!?!(vVcUHUlRH+L^rHF8 zF>0-`sD5lncjK7{o`9Y@!z3qkgpZ64$O*5^*G;X0K5z@F@-OF?qpxcvGAac0TuRj$ z)As>-7vh<_o-?;YcbI`qMrka3<}Qw?sdK{OmoCW7*Do z;*+0>zI^rPKmHQWY<2+7_2i&{ahw$+|B0J?@nx&Xv-!pLe9*G|c#OjAG zG}n(`zXRqiU5T~!`wGf~fB9R}bRWNN2mI)iy-a#S?qAgkgI+$T{4Z|!<(24t=Qprb z<JMvm*8ZqVqvFFSiWjw77~I(gAZ|6d^Ea*09NcOrKi?v=TbrI&q_A8XeGPP@@eTh}q-Nvgc~_aIkd*RRQ;0 zx}J3$(+%HpM{ND$2l3?6x0&?JQ6=spw#Bhu|Ex*>{(|r0BYy(co~TU2i(c==rtdrv z-#9vYxof!M?Mb37H3Y*(lAkwRHO!3QaxPnhe2bEo0p&5}?2q$6lRevY9aKU1Nm+OE^Meey#IdD7$aF*_ZAoqqad zlX~!w3n~vHBQE3L`VpM?;Mq9s6Stc5l(kE?d%~BY4+R2h;kB8{+LLua)MgiPac0lxHJt_hQ~1m*6K?zhqdUX)%3-0@kNq^^}b#eA(pTSyp zoM+N!{b4pntv#+p5WT#mrX7XTPT00|7yT^VlYcl37u?;8wbqFQ>RtFMmQOttU;gZ_ zMxN2i<&|sD>`hqRhDZXNXaxLw2fETci82yqOj{c!DGKTT*ipZEAAa-Qi_HDHXa518 z*>N%M`^|Sv`l5Bu#-C5xD3QMGGdo#7(-~ppPSH>O9s2hl;DT#EhZ7Dw-1O{|J5&hP zL_b;mu8&N|=#kmpm{LQ!K&z~({A?$N48@2MUDcxpmTqW7Q${EH2s&DCHz31|LCQp0n>cBP&q|g`p#x&^8)<-AhaVL=w z%Bd1d*8&3twPzb$Kh(`P-J*BcVOqxH^1%eoV@ckIE9Z<&=!s6!xO8`SWAy0J zC{UnT=?27QlKTl9lluzHJv(uwOfGtbVP}XhPhRfS=p+@U8Qd-v<`u( zuAKuZA1G@#y_RdIt7@K4(D_0Ghb7#WyQR)vxIO&9z{3weY_8L$O~Z;6D@y-GU*A}{ zas}qjom-`ww!;p|>CuaE*STN7zjye)DgWAmYo}KEnq`ZyDEhbpMvNPW;gyF_u9Fa& zFIf%gK@R?p|*-b+UP0i{V0#l*EeO+id@yR7|YZsj17JPfwNGy zB<<}}y1Pr~NTVA(U(u`4vm|=CL5&=Tkwem!Q?H87auzRB7&Uez>iu9&9;4mu(y=wm zuz2xOtnP@ud^T>}aCF%791!Cqo=vY_iX}@GMvjeMPOkR5H+mUnQIEpdFi?-!2theKAX0_mrl3 z;l895pIP63Hx{pn*2jzweHq8?IJ%uYx)-kJbLF+QsI)Xkj2&yzBczwF%*$*VimmaXbKdvj(L5T7X4Q>G^JXcv|ZjZ+eFx z`KQtF?9Nm5YH3N~IMnBN2imjJqCffKrI%mEn2HZ6?`u^@2Rc;rW!8?4Qd-qMom>8i z^WI)v{i$=^+iUJ;&z@c7XFfQL*5G$XOttRiN8+3Qhyc~W^Z3iLPZ?S#Gc zAa*n4{L9|qQ1;m#?PNbBsfydMeJ2bm$$HqP9vcUIT~7H51BNDZ_t}R;R#8ZfS1yfu z<~32h4Cz3(UqSoUKtEd?+LNZ{BpW~Wl@QkE*d~e|!D^vyl_q}gL)X$ajs0E-P1}Dr zka&ND0VlT>V3m82ui4}q5;G}a!*yIH z(b9Biw8|MCo2HnZ0tE^bDA4Mt_%iOV32h{vfGJ0vN*VW;iE(qjGw;HE78vx9Ho6+@ z2~G7SEuB1M7GI!5vCdi@^ngq;*TCu!$OUZ*FvpY*SR9eqmA~y5y)-Y_gK6#*MWzK!aE{wDP5@p_FqN`etNHt#l5@*a;&Le~n4g;6`v-l5A?oNQ@oJ z6m&#Ce>rXp$?xpK=z0Hj2}*04;vi~jx=y|eZIQx!u(O2J5^1mVd-FXUahmS zm?X6dXu7Y_fe~YqiqkPXQnIl^T7nur8G9Xndg;HYFKbq;#OjWr=o;FA!HCWgV@=!} zKxi&w$D^&$f>GJPMAi*JJrg5sI(+9z+QEyX$x2@ zO>@yCRU$C7K>z#Q0)qibEtF1*WYqiB-~kSuk;Zj8<2rnhyli1e3KS?%pg=po@=x4P z8QS?}NH1S;Un5DqFaka%hv&XPfk6xDv;|1SmG(Q#0u0U%-I_QF&=5{PL zD;L6cDbk6Y%(E&3cP5h=%~V*GymfbthpD6Bd*dWE9}fED!?g5FYCm^@E@#+tOAljP z23bz02R`gxcdWY)PX0Q7!eLLR%LLIgdYeZ3_%NX)_Y1zMkWwc@SMH@PjGm5++sX+4G6atq$3vfwl#=!HUya z?kP`7!_kK3+4-)vL(Ls0PrIASK?!MRO!MM=*N!<(`y)wrn*|02THPPh!%nvj7B6c# z!5tR@X-~ml`SM{-R_{t+JA)S=jm8gi znXoY-0|`xST9Ep7SQ>|)G!(U;y;44juX8~*v-H%5j!TG%=8pRM+FN%{In-RgcHyB; zIyHU=9Cb?RKQs#N$y7@jh@|~$ctYxN20{T#XJuAyvx}YP0o2iT=NlPmg1*-E{GbBz zsa}WbI6qc-K-)K#4NPqFN!MKOo5!JuCiPsW>1irbS*W2s>3X2OrOEkA(<|inCDaC? z>5X6C6j!b8c9WUfPtpfwzotu6y=@7V806Dnqav`Dgm-!V7V~ih3OLa2n%cgxMFrGc za2pPKZ_@(xZ*@5bt|2>NseO(Ir7O&0CiL%6(H(1iFL`^as2o3Ac{pXE%18H)67K>9 z@<&qJZQa(X9E!pDP0|#UaBmv}$*5?77iXBj)DJnDEKs08fdU0u3CePJ%#$zsATsq= zhL!r2y^pN7xO1zl}b1Rz#Wzk4awu^AIeIRXX7;w88*T#|3gb70r zSHhI3s+F<5uiNHx2Q{^&!Y(r=%&d|;M@U+cyqwYe=v2q8dlkwn9068CAoNH5+!Xri zh>U~`?|e1Y?7MVHLsz5z=zqyNagy18E3OSm<2B@{p+JGwM!Rcj(@aZWzz(16|7=hb zC%Gq@M>ia50_D{>DjkJ5lC=Xe5gq-NJElx1L|^{lu~ zrL?0wiQ;9g6gV%&U2PhUp4Q>&)4H5-Dhx@10tE^bXf%*K)BtU=dRB$Vqq_%wJh!X4srY|7p>NE-oBPWK zrC6@+Ji@m?i=vpH7{y4m0JM+}36~XfRfLDb^f{fb&c~B(qzVNT(SPx-&%fD| zDAl18ZI`Qnb}4VFfc-Z*1qKtS?)p)@td%&#cP(mZU^(Lf@J7VteF}q7pg@5F1=;|q zjg{upitOaH#h~gQl~70V8@OUKR-k|YZeb|vQhC~(cvv7kH6Ty1*~9$;Ed}n}!f~F# zJ^XU*a-_5y-2N)OW_~)S#H@PUiK2Z9SRZ+HC3Go<^h+fOwVTda+Cc9}m;k{f^)GCp zT2jEahON`wQ5N^26!+2;eUU5Gjt2W2wOY@9;e^zezPRQ4;#{I$TnGHAk0x{y2CwGX zXKgJw3Y>B7M==vk2fUo2f*55g%my>P@nYo9P8;+#2|le0*8?f4`}{aH(sJS^Gut{| z`r(el9pp6&khGY(lBaWi@h6N=avpRwPqXFqwc)N8%p;@u)L?9h+qlS#90jfD*R*vP z|F8C4En)N%feJ_fBduL6w%qF0sz8B(f&sD8xI-JxzjB)pyUc#4B_zy{jv(#&w9IZx z3Hd%bDL;BG&_X*Vdf*dZL#3m81F9Sv^1B(dT`EgnyNdz^YTz|WJ4NuM#`o@$xT8i03|+)p8zc97m+7IAce0t9q} zN;aVOmkN{>YgT`Tl(4J*rW0y)ignl8pwICdoG;1ThOw3QLfQ5=eW7yo9L*?>f%4Z0 ze~{*vNIOzIabph%bq*BHsv+CweuWb53*-Urk#-r}$68%KO(^|>cH$=xZN8+<>Qb>x zmh^%bm4muiTNYa1^=w3XykBUb4ed$yBXnS15CUde2XgSq(9jTOublFUiACXhI+qVx z&c!4^`^`lV39Ci&vZHGDZ2Q+&;FfbpScBRNS~cXWGuehBvefcBNt$I??{IUWQ&1(% zW!6()lWTnlR=GabOqO~;L zKHCBFLZNTRQoO8X;PVjF2-x|YXX0q%bbMux2vK;K0tE^bDA5040$by{tS3>`Vukb* zG-bKYN?Gb>4oSND*N90riEDgc#M1=|AUtNY)}ToWY5TqiN81DTA(lq^P>X?0Mt3#z zKDn**?N+Fv=Jq=>*iCDmdT5DM4_ifRW$;5m?Pc|A!4Ke7ef5J#8ax?oSv#Z2z5Oap zVI1>>q+`;1{OtS3NT%rvTK4SO?b;vlQ9v?WMLO(Fy?CY4vf3}1aUpN&W3+Ii&^8Gz ze0F9#&${<40hLq(b;BJsgWGVU^fU2EZ6%OCuo9+O zJJ=`(jq9u~ZLB>)1k|n{&CqXq{e;!XBt`5mGtt+_PiJA4`GIK$aNF&cg783Y5P?oj zcXu}mv?sF79X$`D*1wO|gX`F>Es&Go%9pKz=o2p?D4AQlg>&(6(~ug0F=wNrMeFzE zVXs^d8eK=nln!W7f9H3^LE@{5jght_Dm@fwuFYBKjSRW3E@xNkZBM6eB&sk)3Zm5B z47sZRjjjysMu^s|d$&<9@4=4lo*v{1E<|wA#_)v~HcgA8yW1X9IuKHtb~Gzo7MZiB zAp=?enu}ZHY#}$r+z8NosTVFc8^RxupX$c)OLXwG8`76nLFgD!TB@zSdGm!$S-ERC5~YYCd7Y z1Qci|C@fsKz}(g5E@!7t*>U+X+BU|J3{;Z>ClykxGSszdD0e00DKFm!c=Swv6VS-$ zDK4WlB?}iW#Dt0Y*el=c$M+$SmV_%m)n1>uA-X9~=f+sDU?C=!#yh=Jksc@ZJrcu~ zA?A?CjE*^cVm;H8sZK%}aYHo6nBe-7V|t z#0e9;$84N7ajR7eGD!4XeHBoig$|NTRw4a5EBCjk^y{dK8_*IKRMx)=*(!*}d|*Ic zyZwc1!RLaK{1X%Mht}sN+NPIm7PrEDN>iXfHk9pt8Lhr|Ur_N+He4%^yZ6P?2%x9_ zPcbq|t2S#|f@{A4`1c~AJbm%2&ni(1*58(@zkSfWdGizLdVEZDCw6F366NwkDRGM|78I`P;`aKz;UV#FG z7Oq&)UaOifs-95Bd~|Xh+95Hw{tC1QGVG2OlhzKlArEBbv@hQ;LpC^+Sl6%G(dx0* zV&E1oTYDNIU)4(RbbU2TJ6m#bP0~3#;nxs^R_9K|`W3cqErOB)?F@SUMDKI3z|xT! zZ8E3k`Ug_L)VGGK=6?Fx7I9~uF4}%V&ao`_u!Rc&vNUI(AWM&NV>-J{pua{|vsp&| zO6XEG0hTSO^;1`}G|?hmEo(MRyNbyStXprJ^&nW6G_BFVSnAYGCa4s%JbN!aYR!nY z^gDjgQ#(!@IL~jpZQm0uuAEy=A=@JzP)=o+G|J_b6EZ2Jjv=|1vN$MyOPMU!wY`_N zg;i1|fu@bo+~t*(JGT<(dAC&0rq=>L>cL}ry3#cGIFWjNmxdQ8&=}fLizHu0X(+uW zWiCq)x`WdUUkEb9e3eix`DF-vBwA{1IKEOj2WrJQ7sbU6lz;!avsQMd{A{{nra|@=Qul3i*svH9>ONIVjSi%E zPBF+uqW`=zBm7CEn9-mmTjyT;<R<1)c zeV0eMZW*!5P%6@-IKGLb6LQVL7UjBcRVg&#WtWo7Cy)1epjc2cM|&Jan;MY$OErJe zdWlxaOq1Cq&4MtGrGHB7QXy1#w$+`ho=YNYdnbMif$4#v<3)d1LvqEDCO!<}K7$T7 z#A#(ob{T$Z$~WazW%&Gtnla7h|BWI_?n?9H;)O2}+a%amq=m#GXW_ZnIn8jB2JZ0R zHIHi(Xui;*#D}}W+*=L0g}-h-EBU-mU{YR;gE!uQ^<98_}r00l>|$>d~Z+Rk2ng=6=oqFUsrk9=$_v=XZa0$g)FHcL`C$QxUA5A z<5#fu46+EF<2#M8)F}Ym&c5GUq~k1g32)b@JQ=gr!R_JK`k=t55Kz=Y#I?-GZ4i|w zzf=9=Xj9(0bPThMK|eTc8w{bkGpeJSbZRMu?PnL-_26Ve1^mK z-hAxdOsi(>*unZ=gUZ~?j?Fa1Iv0q-W5HX8idv_llfdFn_WBYv#NW~Qs1Efii=yD>Duo$g)7n?{=QC3K+k-w89 z5}Nz&;CGeJGBj_45oeQ0wi4yQx(sEL;ShCQx)iza*-$Wk!(OEcr_|jz9w}hH<>*8WMsXEyqy&R)}r#0w3 z(`$Juu8A!DY+oKIGCy;@_gP;9U4s>^n>6?*ZkKhNrW4~F12Q`mv#05{&q%SM-GvQh`lPY22sxXsjDnWOWLtM<FHf|`H7zbJ&$!}Zs%g?Ol9^ubHRP%yF%59fyR5mx(-X&ux z;U7es$0w8ApE%tx3JD$S1;1Xt!4={^F`4C@gM{Q+uS&|EaVbR-2aw4=?f+E%@G2H} zLP+%eX-rW;dmMS0O_&8Yi}2w&M5Kjyo{fikS=jmtaVK6-H3D;oAud~R+eDTAlREay zL&3MxlSc@D;}7yq<3`|Q$=-ddJHvP_Jr*S+WzdO$DW2%)uz8~W9pQR6GL+ge5#v6w zz6jqAJ+g#z&pV%G`P+t$+5cK;L7;D7HuKPKOoqgiz^~BKte8rA;^p1)S@$iA7S)1i zqu^3{xxZb$E3S4(f5yJ#V}4WJiu;1Nj6KuP_x9A=+YDV4;aoJvL9!S#u10X?7mDuM z8zml7M}=&_?MTN*gDEvmI)P*1d05Mc3qG`Xxp1nde!W}Tbre}OOAz54aZ9kbg}9|+ zg@YnGqBC_)%Ic=RkS~vp=KMwl=>yG;Q?*7U@A9}Q4VFEWcz}(dI9LEg`Xe=J=FrGV z?pRp*)4E@!Q7|}BC*yd_fJy^pBIOq!0sFXN49AxMDtzjABzwy>6%gQBUi%G#()B6fmFjp`KVBc4q;R7iPrz zPYk1i=^Mg^V#gW#!++Mk6BUWBVnY+_W%#Q+ z${W$NIm2Z*{~eoDH9F9)))eVa!{5$Kmid|tr~IU_jK>Nlq`Ecy0}mb>5s#urC))#8 z8<*Mn^jxm(ge&)~08n zzo!+%Yvrud%#`;y0G98qh9$KnmQaK!oArjvsDzM^NIpG&#>r@4hZKbK4rCRkIb!n>S zm!Hs9ei@gv?EW!My&lggmMnLl-8B4r$;u`)MFb?2msQ>$ITaH{8L1s!qgM;Md9Pf2 z@J+RoLEJ$=QEmpKXY0|#^B5Gx4<8J49aoB}0FS%u%*iN!9gMLJ;D3Z% zCFtXX2-1PpK+rg_YjFsB4*M(h7HC7qyh@jyip707xe{nR2>5cPL?+BSX($O#)0VkldG-w%Z>Ye!=q1dGCuUBKX5+KI`04w zxv;Ipe8;o^Mz0JwDAZ50NZITi7JGUl3b@0HSP);d3*VWeKi&I*)NW55R3{Qe5(zj#B=qKLX5pRkHZ5PpSfJ&}-Wkqh*v``8(Ap*RR8 zTUwfUBFj!Z%5_!{-k7-X+cjxr?>wE?mgk?Cn%++*)3CFD7&j%17E8z5?sGB%$8aQ|ub9#t91n|~*Pj*O zR#VR+PD@cQOMHO8>tunbK>$(t%{zkJBy9cNL$Hfz!5#^l{bZW}bmFPNOABTYz@2#% zSD2gBl;OZw2InWy9E*PvLKb!wJD>DP1c|v%RaQB+lOtNtmt}9bP20sU6mzJYW0rvP5XoVeSABkJHB6n|_=>fr@PD3TThjMlQy|bnX z$eIJ}N^Po|qhaldh~njzh*G!c->z}Du@)TYh$ZH9X-k8}M-uFYfDAS`T!VX1si!s)2s3CJ`Y zVAxs@&gL>G6sO>qinmt;)edb%N@{r0ulS*nS-D1 zz|(>UMvt8BsP@E7!|+dWGB&BU>Fajm;(Q*4$CH#4o;<$)8r0}-X7epZlZOmT31Rzc zHkTdv3&qX7!0W$Opsc{{K=4o_q5BT;B9mW8MI(64)wQ^JtQlqmQ9HbXkVngHbFR-{ zyIhK4iZVV`Hm}*+p^=)F(%R9qH*OX|B%NM6J67tUR$Q zD+u*x2u|F;uT_JMaA&{V={bh%x;}3wh)O?{(hlk!UL%}Gv~#i^R1-lf+QKwpcKPD# zSIfv2Pq%m5Co2)0JhN?`kFtau>>o_GXGM^?i8geurqGEY#8Y=0DQO~As{6`n=UaZe zx38i)U8Rz2A{Fh?;?|v`6N`E$6@8wpW@K9}$DN>!LzshJC0Xvh{tJ34#ady-K$)hO z@#X6@|5up(e!{-QaMQBZr~^z*A;)Dfp`Z*!?2MmlZhPdbZG_tkLFypd{h@l(O(RV3 zju@t2gRz=};`+eabQ{?y`m8rwD3Uzd5Y$1^TDbyPUz-|*Y1Z2sE;?0seYWEoC+b>s zfx=W$=3>3>iLI7)SnubowxwU;&d(mv3J5XmOfx9yGUVT7EnE(8@_BcopJnm|G+>e_ zJ}6n2#;X?(@!k2l<;xkq z|6mWAkq4>(Uc7&ODLw29FuDqGr&yI*$aJw|Nt!N%g6{m}>>c}N{&y5RHLjW0#mIo)u z9!ve+@WjQn?-0LLN_uwC(@}^O%z?5elp$rv98i6*0|7YBG60rWR=qaP^o^B98GWCn*hW@lL*1yalnrnF{)Dt?5ld8(a-^6!t}(#fGE;6(im8a+V= zm&gmHXi7T~-`U9*E!~wXjbtWFvw;CPXw%#`=?}}75_V08zEd_YF$0jb+q-FT<5AKW z8vfXd#qzMXmxlC*blmZ~LK-QI^qeWX38B9=|5we~zRvA&KNH<4281M5(LirURhO;& z{QX995{ZYf7-|IHHes0L(Hm)%#aL@Bnx2|#NEj(+{mEu2_?S1&$=-=?YMxPsBha=T zKeT2`{oX3H*-~A{rpSwf0$&{?MbpyM&@FCY_I|If+wU{Alxgx+d<&aU?o~CH*+-(#H$zu|t*4?}-`t?5iW zJBO$!R^2TjslI+%jni8T$JwI169qnTZAF3f^d`5Po*{}-t_z6_10lTVtaqWAZ68$m zTaje=OeB)MpLkyzo;a01@Wz_97u#q=x8=b zxu+oE8y4eiM3=%0ty-OUPgz) znu{=V+1exaRE~_Py0qi1>42mLVJdsAb(eKzvh^v5@BU=bQHe97<Q*7fZ(sz^x!C(* z@K7r@sT%9i2m699;CF%>5ZQb~8sZ(fb6r^E_sKX0NrfYT2i~ zcba^-pU6H+zEmb}QS`bG%%;{q`%<~Ni#ZNT$S|H+=XW6Db9)GA0&T;Ojy?vB_hxq7 zp+G!#aim;#iv(9k`8IB4^5527ymCsOHE(mC!Wr}K7WnIQa+N_D#us-aFs#P#;OnO> z{)T=Aee7?OE;D(si*$j%58c3?VI*mGQ~j3fPh%bIH9-RRH|fs#Pvwh`9@B~SBct9K z5oNBMl}+cys!7+|D^mT{@Dvhw9^6cvJp2->I7$MKX5fH?W@HC97-!|SiQ#9a0g~s?mCdGLP_5)d$m2!JhxL(`vO=r?4fFkHuU07y3K@8Cpg97 zAomLraGU+}@TA${QoalY2n-RK`V1>(@NjsI=TWzpR;EM?|3hrDTmAswQZ!mO0iGt( zul|@n{Elx*a3gtY+c6Q_p4o-}Pn1lo8f(X>{}NvQuO1|q#V8nQT!c~Mp7WBE@Dii! zTc=RbJSCI=Kwh!&Cw2z$6RNX6A?V!%m%<9v;3?srTQT0MM$P^Np@nvW2}HVsxuW5D z9g|SeR)B64@$wn1*vtX-_Dt+ZD5s5A5L3@edHj+OE~46j~lua;!ama0~^?LI~W`|u?~HG6(3esi?=Ssi$7vBF`iZn8r&g;e_`#Coe> z4-ib>7z!Le=%;ObCO|=dO%f+^0M|D`;}I@0(9AH7!GLpzG*H&+{sQi!!*x$TcjN@3 z6QoIk*KRw#deUy=?YU@dj$V4c&ReEn)Hz>H*mySSVO2JAbec}1~%hzl2%`Hk-KXs%g7^v&dOpZVDTkWU&c-*b@_@f$?&p{<)ZFN|uxuHz% z546K=P*BQC&Rpj#6}f`8OdYoWk*Y9nWKv>`d^5j!Tf4>U#H&?y|l7k*yV@>O|z$l zGaM|-lk?N&mYKJcYfCz5Zja++FoS48+~`OrRqDf@a1cY#i5GT-%V|6&*iqVb8bwyW zzhZDZi-_z=tAM~>Fl2X0l}5keTT9}#-pjCg^4w6h_M*u(CY_GFe9P1wCJULv8Q~OQ z6{S&KjWQj53YmRWSOG^igoHD0-szgp-fQ~-XY0XZvJZ3@d~JA>)11WXg;pRF=_%s6 z*KV9}4GX&OrC8@Yz_8>-b)ELR2lG#l`eojaOy932GuEEqmpOm)YS{otxvgtTUp@@R z+AXpf#vSN56Y6G#n~FB)rNp<@jML_t-O)Ux5@DCan&WQ-8ZPbgXfv82Q(89bY;9-d zj9D~x#Sy1E{`~~U7BNpGRRRklslP-yD#C6goKBP06$rp1RMHY>=Fa=KE)?u8%gB6Q zlYY*gzpm{T=Cp6S$HoWZkFBv_73%GTr7D`n4(trSmGhKEC+^3Y``vBmsh*Wq(KmQXzI#M^w8R36h&u|5f^_rcj$W?0p$`I*JU3$_w9=^sKxp zsAv_?wly=FiZjIj(`*`f=Z9Z$l4xV0p&jIe9nd$bzT2RtWQme^GWJHqt>l=LO;@07 zHe_61>zh@L@~$u4=One$QUKGFfO6tb4`g-uHr~zO${DhLX1E_*eP^%X9Ot_i=0}6y z%lPIQtpp(1MTDTrBTb@dV@w|2z+X$UiQu+if(p$L4;g{JpCFP8+2^xy#%*m;YrUD{ zD^NRDW#^3ky=B#r#)OJnB4h7iG}-t|uxmlBz5dvuBlbvmI%txPu(6-Q@>xh8*|l2l zfySQGY%X|4H+vxFiIMGqQ5zDD0I0%QaN8D%eZ9pY>4qNzh#xc2xF+vFk0$zECS`iV zUhX&!@M1+ay4N#(k9J>&@+Nuh$Q0D(r01^aeP2ZG zvQ6sWm54MBp5Ll26%h@KIf6?m`;7#8(wW;(ANI&>4|WR39tiKjEG zQ!j_<_9RD0!eSh*_dE(QJDA|L7IRjB1##<6h{kEuxRy%6X!LHUAHnh^6-Nuh7E`#z z^(}Gps{n<4|8=CEolDh%1Hsmx(7?Z2&wJ;`z9!y-Wdhi-W20Gglx4{`*3ZzT#;xtb zu*e3f-x+*up!S=uH!7+fgigI)5+1L}1xnZkd`_@?>P2l)Muca@v>lC!l$eV6n=(`# zFxJAdEgTK}z}Ptmb#s4vrp5U<0wsa1`ZapF)9#Om#UB(rLqYemV{i(vVT*uHEtWN` zPbL0C5Paq(3e#lxr-Q?5F3s3dKomMD8@xPB(jgj%r*2ECo%%~%70gT!1uz?B@tv7Y zA5UBxRD0Qp-*q(v%irIQO*>yy!ii}ZXX;3-5+&D*_0x&jx4f_?uKO3w&7GrMMoXf0 zC^{~WC&>LcZZ-FI_a&Co(lxo6&vr@nq7MM;NA2kT~G-T52 zRGsda&`(@3moYlRG)Pb>-U2e1Q@N3F0uh*&p_2Z4CfRff*_ZU2v=TsgI%7qM4HPh$ z=@fu!jPakj6LPb=!n4fG8T;mEow`pIM>Ek1B6qcEZQtOQK&JlMDE^iE#ca9)Gb}FU zcL4|-@yuXu>l&;~*sz!sKz7mm`!VVw;s#HgnmfcVf-vvV-KVAxq@fCRn?aC+>t&il z%>)|Zjy$s%S5Ez2h5t<^a!oxf#s7BIe|C%sUt%7!3ma<}i%Dcf|7e8EOITVf`CR4x zJUr@F3$Z`4D`HY(E#G{t(OI>ng9>=5mH%=veIS)T}Dg-!f({1y6cZe5D)(==>j zU8v#Bj|)OZvxkD&tM5$ye|pg&Ycj^%*=9UV*b49INQbQ9ULKjZ*|WJq5kG|S2~fpu zXP>$|TLS+ugHAp{#rJ0YQ_YhALE;7W8(#)!v8cfi(THwqZ@I@NU@>11043O$%W%t- zt-3oxaCIDA0D?c8v?tGx10<0z(fKy`)V|GB9^$#mqaMhJ;6(o$@bYh}o&K z(Nwi`6Zaw)Y7h=C#3#MY375}DHMEAz5^aMh@ZFsy6McRs8oI#w5))L{t#IS$d$eNw zRfuVi#(c)@Or=q>UVH_^NoAf%vVA4IK|`LxodH?UOwA_NU@EisCD#3OoL}2G*6(tc zNVT)VA+xMAhhC^Q|1B@jZ^I7GtMCCD@wne z`s8fm<{@ov=F$wmz0KLUtS&eb-pg__a<<~*P5V%%TI-$eu3fSu97!{oeSgqw$C`vV z)i<|aF6ms4HDhoJ)R&5TJ)5T{20Ecvyxgo(v~PzbZoSO5NH{h`HlWFRBCD=~P@NWy zodeVvc?!KgXL8%|*5-^Lg||j}5{m-Ac!=j-4N)iApTIUxiDZ}#BqJejdnInIQ#?oV zB0CRt2y1&ga926Dk9dX0A{}$J^aW&DwE6%>AM=Lnom0icKOPh{L{P-*_&=cJWNvDK zwwMxLqC%!82c*;PK731%mNwpL(|OqAv|Y9)=_Y_?{-IG`ybw0tsynz$+)Ut8s?n@n zkC@El>zI*Xbl+&9@Stm5DthYMjNcFCUgtY$bT(KMLS5bLrGSmig8o?)6C3kzIS%UZ zxk8nlJ(ZV0RD7=+qe<@1oVEkH)06jTl`RMPyO$g56+(lp9YKw#cLLW#Kdsa2>U6A& z*P#G`XOU~ebX{IgTp+il>-CWjB$hLMw_Jkf(oB4EgzKacV>>*cx2iWNXI+&y{ZJ#{ zb8iQfa+LVGC!coykZTi-Z$87?dHyx+CE?3FPrBlosR`gEAXn;f3o|`?$;u!e8byt? zb+yj(W*pJj20u;uV6iOxZzsQzlbARL(zhUNtOF2c};4ZAxF zM;jLxc*SiXx&%JMX(dSxs>5yQtA9TYw7;f^gAxy=wRp?oAf+DR?kg#FQmrA+*vh{jIVyjdO$Ou0Dx&wUy1U zuKK+@@i{%U;`|l7tBB7)L}t)$Te`R_Jc}tr_jzM&((p!vbU`-9_Qd9Kj@C}Ikd8>lc^9XPd)6&`q?b-YibcuJ*kSAEX`Hz=ih8f%) zBTdG>wq+9#-ORaV1X;Y&?l+q6t*Ja*tO^2**jVr9=$%m2a<`5cw)_s!Bt+uU2XfZ# z_CjTzl)P1N$r4eanH`Gz>TS6CgW)n~EQ$Qq6`+?Vd_GQhx`p-KZ3>UI5MJGv?7*%( zk`B0~L#>7E)m`^mk(;O;rTREr)Mk}zFy)$qcMv1@hk63wh0^_s(t4xaIMb@8fk;Lp zBJ+C!)7hqGm2>CWb}TEn;#)int%kKkM8HDoy2@=ohJ2s8o;yotp(bk%F71#0IKF$? zhrVI8C^g;=FwPAs1!X*$LX2fFa+}p|2UyB#Uvg%&pKDYoDP*+;F2L}4LFDg!$_Rm- zE1FT~J)KVLl~(MtLtk0mr|D3SQLqcjw|KS2N%&eaNEFS<_g*)-H0G$aNDWln#{yi% z8j~E7P7<2{7`xa-Q>jjw;Rb^KG!(f7$XWhT>ae)CaVSm_(w!kS-kNz)&3dXY3{wLG zA3f3@S88ouZ8h;9DC5vUM?7I_} z=IM(|b2)fbn|{I1XgO7gg}o?xhSp99pldo=TFr>MLsz(ZO5iC0K-HeimmK_NXtp|exr@M?rS`o;b5QBu<56|LiOdmFxX z){S3Y?r+V_GoBt*Pdx3!l$2<3ddU}HI#Beq|K{oboPaB`)qWbp$N>Vr^dh@I!d?T3 zR3YXwo!l_GwABZC_p2#1Y1d(4ob6IC!jP|?jsfClRa?Z*4Zp9#Bdn9J!5HZZHT#ZX zV!JdhW=&l!0m3rqkW&R$1AS2Bsho$o3h%Pq2FcMB{dVeAZl-ib(>Bw-i~afGht#C& zof^+d^{@bI5yoySCaG+YJZD09n#D{nY0!%DYbZ%qr6=Bt)PC#a^ZSLf_bSZ)nYZAj zKqXs7%os^)@7GAVxeHv!H?D*!dWEjP9;+!DUwCx(Fz&Sz7<=k@D6S2Q@i~OvZH-xX zg11`nYhPVU#52xeR=qmwe4oF{WikK$N_(hld~F92IU0<%%==3w;-q_1!mi8`zlAqb zpIB?7QaPLLbz1_>3=Z@idFKWFvd{-Zqhz+JONVHy}N1o7P-chL{h8C4v*FgfE z;?P){!n70#9OF3XLbJGN)HN_fJLIaR1JFvHDB9}@87&TW1S0G*D2`AxIRf6L+#6zK z)>|WpMfm*yZ4+))=LNIV#ywc?SLv!f7(J54;*-4GJXBM9VXiQ*+kqu>kcPmJdS-Ni zP0PiRN8be}?JJwjdie*@g0leTe59MvjHgg>ud6i5YPc(?>lXpKp&@=fREO(W8!ikD zGW6OE;4pMMKK;SSTn7|is{zBig1=0YP&hJ5iw9(!TA>o*wYw|55Da0{jv<#5v!Dup zNYRuhtA^?XC9i-i!9LnS89tLhyK?cfyYfbT%s}16qH?Lnq_echJFB5~eEC#Z1p3_@ zGy)!cO`;bfd#^P&%3MFi!3H0!_FW_fgA%08SBdJrk;g`zIpq~%Z;Jh(!^JnL)?eE5 zZ(1phazR1iQO{yo1Lm^)MyKDbJ-7;-mL1_N3-g~8Qt4JRXD*WrP0uqy=ZDkNqZ$P9 zCW#5h3yl+S4tL|3y79)wu&~(P^H7Vi#kV?I;cBe-njs?x^pl>UkBZDM{AbJu+69)tB6Mn)9zIf$jI-rEwXpkAQ`6HGKv44brF^i+fMQytLT6Ci zBcH*RQY_t_8(2X59}t>9jalXF1AXc{$12=r@wFgzLhdH>g_hcN|O%8pAPA49I zyM_FlHUrYpP5)Q>{VxUUSdlU1TGjLMi^bWaHYxbmH+t2GN9B}}$IQ>=uyn~IuS9`( zpc4OB-1G|AO&_=B&P@}xA?YgaUZ($#U0C2N~cYgr0koEjzioCF{$7;`cIDkl% zI`Gk@qkQ>|k{hD+x2;;8kJE3Ad0XW|cu(>+Wr$WFQ6U?TW{K0@7-E@GW`V%BA1xcp zOTLmCCGVOSbYLDDPV@9nJ*YGuJ-ngJt<%t&By8gHEzKpelssjA?=WwSm+9lT942or zG96tc%#O7|)+UFhk{6NZ!XZl&^zBgc#6CrB@%$Yfm+_gRX9SWOv4n}Z@mOQCT_9Rm z9BC?R1!|r&vP;^9(<<$*K!k`{WKTV)=4j?MFhbX-`>mDR-@;DpQUC6C&6k+f%`QYA29S*5TYK4Tz6UEeoEwT5+1NBSC&T%96&~(S zF%U@Fl(09KG;r?U6+7$ZMWw0o5e2RYOq^pnL1zZX^x4$Lde+7~SSW?Df(Y^Mam!&8 zTFb>>=$Kbe6`o(`w0|!LNSoZbUvc?-DFl|t6vp>&l9Ehb@Rfsztwgaod;6hF;#FK& zxo-2}&x*FR#4J5H#9yTO+um2%m2y+=PhHZH5mOkyGMb62q$kvWEHeFMTY~0u)z!e% zU^~A-#vEbXw8k-qJ>k!Zy@a;?{hEr}f83TRqxDTBf0M8MtZJ-sF`&q1B^ATvz}%}-&-P~rD9OpsH>6@` z6Kuyp9G<2-Q!;L}%TJKs(YF`q*d=Qc+~a0ng-<)YN86fj?`H6%v?3cV!~d+M5r_D{ zi}ULnZN;;fBC0sb>aWm;8P6^TNnm!;kb+1Q8reTz=f-+$wH})1srQyHeJ@Z+;ZXC~ z-*`fuW3qpemoQ(qPpFm-clRmqL2G`W!jfn63#E>2azd3DU)toL7!^$HNZH{2&ouKg zXCd(NjbhLUZGhrU8lh>PcCNoqRZHx)1pIl!$nQWeP6#w%6BQLr&CPeY9kZ{^!^K}F zPHIW^%X#OA5aYY@Zy=eqB28@ z4pbUMB8Nz_Ak=)NW2)MmiRX$u{BBJDvyp5*{A{y`cKVH7)eby4n-e9QFoH+jmtGTH z@HEz1<|qEdw`n_>51vxFmHNda!3BF_Daxspm@BczI{d-FEeWj?j(CeZ(~KQ!3k}}& ze$~r{4yQbp@Vd3;>m~B9l&wE83P~6=tlaY($i+OBQ+OvRpvC&lzc6Qv+cy5`?I`n6 z{R%3P4fHoFyo}+bNZ269Kc+SA*Y*-xk+UZa{2mqdw55l7vbhj!iF_=Su9c5mU|6Qk z)g&lxSAgcn`bL8)a@Je(O=f|p*A=Jj%+G7Sdm7hkO(~vZVM_d~v**NSH}^fV^8k-q zvFExh&rvhT#l`;7cm25xwcF?Q^K$!4mIDuXd_)Qhoe7asnb&u~#i`dum?Ruow%Sp{ zNZ}+iFwrU!y?j^Mgm8A>v!>Q~8C|hP9=Ul29_v0Gv@{f<;GsI|Z)>hhYW+e$99E66 zyhS2O zchK&>9OB2iZf!(v(FZQk^mY~&;*g1g>Z3&qyQRXOzcr>RE{Yiv%PNpgw|+K4dwri{ zXUJAYXuvivcKm$0KWYa%I}#WK7H0a~S+Nhu#nWp|qQJT)VYnW6yF|bxY<{2Vo3S_bnnJI>O~1yC z4&9aQ9r5}}-h+P7b|pBB2DE@$q80opRviiiqZ3E<-r0@D-Ws zW>zv(_x?^dNlQwjGIQrjG~Cv6lc&T;F+EH2JdJ44G0bK~Waf_Z6|tcYn=()J25?oP zZ7gp}82|kKK-gze1$vwDI$68xv@g@D7b~B?czgg$x~}bY>aj`<>+=2Wsx-1Ky$X1o znXLu!2O72>hs$PSz5MIWWN3XaYw7vD|IUudY`#$PnhR93%Pjm!d5-4 zr-*Jn^vO&*f@!sqt*NzOnkSl!Z0wJ)32<8iV>9+2OA_eCP#FRf50ysEk2)>x2I8ev z4Rcj=V37xxa6#$y3^q?2h2_Fdd_Npydx9qTw(urM`Z43mVEJB9efgu z#J6z zsQ<g4)+zcS*&Javi55jna6tT1pbu=*LdY|DUMIa`cM-L$fbPlA zNmj0ERc=h5dnw<{wbFfY3~KTX_P;2iYO0~NO(AC{>5D>5o!sB0@z%;|S9)MejTf+P zru{rn`3l(YBggpN;cc9B9KJhxqy}g)4IIE$uRFj`^d%E?YIE$x{x}s#UP;))8eUQE z)W@;68abGFYCYo?_DPMry>g?$+(`6#@C;SsPxuld(#d1(KV0jr1)x?iZ$>!rqQHGI z?}dJ7gT7y`%?4de30n>)$+Ke%a51YS1?W7jsL=%a2_vzO6@Ir=vgDMRc5db zhs#6I-j+TIe#p(h9|5-}n~R_B8?C^>Yy$sk&s?^gqvKogw2K)G=|@N;QRJ7S@WGOR zP$}0J40jx$+hAZ(+tExApiHMJXX!(L>M{MVq}-Z2=C|We{}c;#=UV29Je21B;GWzH+&<6wJ@C1-B;2YfM*DE0Wv>sEcsqc1Tz znVZO+Xz7kSao=-Fp0aNkpy_p?sNYCTwN%EU*E(OlDZl%8SF@_n?tF3?EB#ni8mQF5 z+VkvozU0-lXXM|eyCGsn;ZQYc+frzz1>BV3^ung|*t)yldH^Lqt<{6O7uOJ-4VMNe zJQneQT~_4V>ra>E1ryDMFT}N?@g`MWd3&Wqw%6*Ex~;m*vpQq#r*?c?Cmsc_Aq2NC zsh?7`xanx&Rg5tMWL!LXq$g#4&9YoN$~mA5d~h$GH1%|!VBvdxV#MdC)jx3@ZMmgM zu*7QDx{qf(Hgezdb%Vpj*Pjns?r(vB$aKKHdhFV5tMTS`V`U^->kp5#c4sm|M|jd) z>%L(HQN$}x*o8uspG|QzWAt3PI`1BN?)m<8X3g=mW zWygb}V#6uu)pt@B2!Ev;>DUgN_Op$VNy`{981#x)pUTvHXX1<#4AQybPrIv(wVfdq zO}hTbtFjENotx@>%H`ER-Y3=TZ02LnLm>h*ZYk9d6v{|@5F=8@UNAM}I|*le@99Y==M0j8Za z`SEf(f3t*nD8W+6=IM&AshybnT~qe%KfR=(c@-kO_a;7x)&X+dZ#<9RJUDZY(%6?j z)A7BqmDk_8U?`@NTV;G@x9T|f#;-qss`KPtPcAO>LsYz%yga`xwL#Zf8-CLH`74E# zppV>r9M{jo1gR{8f!VZtJ`z!KvA0c$v6C)~jwWmGa`Z{bkbOkhczoMj=z!~E@Z_Re z>s&sLuSoZg1auyBy{CnByY3bLa#6Is0Afeo^)f$sr^48GW63_?T>He?KMP+{c>$X( z#?8r;x0OqyGXxClzqXh4*LM#iyk8zxc>7|Ou$dbRbuxB$-HSyzcWa_^ieHEx5Jj4@ zg`dm^P5p`rr>*TCjwLU#SqhuZ3RQ5Q#sIRRm!Md8fWIzo9)Q|%YP+ZP*1usaYs=ZIsM$7A1agO@{KuflJu=UTDw8~8)B#+h2hF=3F+6_1o( z!@MfT?PJ10k^5K@g9A&85+i;%RnsFiQEiB8qV7cwaoK6u+C)wZ7L6?2sH+C4{gj?N zpnGi7lMiyqZ_8yfx&^PeR@WFaCzPGCyxnZNATvKX!XGcm5L+L0fXlmryI_PP{KY(A z$n?||I@m{upv$r1vz^iA(V>vt1i|#3-ow`Zs5g=RK$c|uyi>I}2o%M%+8B%LRoaH3OqbpC<8LmWUmmTw_&6I_kEGOwO%PWqx#W%EnClOm_SYY9)s{9D3K zX4eQwPIO1CuUa*44p48j9Y`G?pFEO{Gd;fPi$rqVl{h3orl)l$ z;zln^X4-2e5=Zx1TN-iN<9nAcJ-DsmpaJESedqoRX;pu*E9xRN=wVY1E3zfdZKL4l zyze2jAjFRs{5S@-e7Uf=u4F~G)B>k@>g^Qe8}{PSn;(7O?Nm=pCU+%8lV3$$XfS{k zW5(Af4R1XusHJ_nkxToQJSIJ_p772OOqfzle)zzKzjzrhUzdcCFPR7&d@8=lKFuQ>@n{EEtGUw+^ium4>C z?jl;8mdZPE_Ru2~ZsGdo{AiMMA?BF@cAO%dC}Uf*auD^p1e8;7kFIzv9>bzJM_hzd2SyPh#YE%*h@JI*!srng zqQax5?o(#S9%j0Gt#sfhCCg0u{4{cs-tq68Up0zQ{KudF)=c{K&n%!>JxCP95=d!g zbF*%6pbe8ND(cA4tnE`3{;tzWOGpSYfM`MMNMhvkP9$&Ma4R{|tM^Yyu;vE1rj;SA z{>DNMs*BO?4$2#K;+FwYr-uTGO$svXkHnbSYypir+D=1=nfyEZd0Cj$+)5 z3qX2wo7nS@gqNIePcz@LD_xni40~{0wmuP;l2A^s(oG=`&u_ zZC-=WfLKgqZsSUhrI{$v$GA*%6L5c}>6E%joFgfJl>jZJnbF%y`H6Z`Sd;3Bb!@tp z=W%_a>9%D&T3ZEsB7&9$7c4qItz6NH6`a3UJL05HPzI7wnm!;av=R>mUa~n6hpTbF zM=l!pyDR#N1bW@Uk9D`J)UP@TF2Ku%Omn-VQlR5}a^xg_1ivgE&rVNfNSpUonz2XZ zb)XV46K{)VF)KL$(eO+=Zez?wuuU51F0q%biF=k6y6XTB%Fb2@6Tp7hj_##C^FrHS z1{mKNsA>B^^!zexGU+-9Ed9D_=Z_u+PX*BKE!<5flW54DuHW#+9W=%zk*0k=hoV=0 zLI975SxS#*G;~2K{i>Zim>X&Y&X#rggZk?WBThryH1j)sN>tg4VH!<%^-cQzP#jV8 z7m|bz6N^Jfr48TvZQT1wSTvjy)V(AU&fu`4q`*hp4JWrA_Ybg#fCMB z{sy)Xe!U_!rLXgY2mjp#P13#K@XxE&>LIFtP=&!$=!I?n;%SG0Jm#jZNnIa%r)^e} zCoUgJqRY-QPyzmD!E{?m7uwAX$40qwWqIXnX3K zuF+T~m|DBZqp>QqeAf=_v$yO$buqIxD?$eR*rR&Vb$*$WI+>I65gc4RrpMZr0c94z z=UKY_teKsnrU3^r8HR=eD`@84@uy?HDaI^N~#({PS7MZKh3ejj&uP^QcyDq&V%x z$XaW}I#ID-hB^4kGL%Mr^;d)|svd>ErVirHPZZ8|`5GO~94*VDDV`g_+D4aZ2ORSb zID@0<3-9T!8L-~QQdew($$>1s^}CiQswP)rV9=z~V9V2%eewENa z3WB;Yh411^oU4uO2oK2V&Z_MbPFSKxU!|)XiyDFIW>gH(gU=uf6NXm8R~-w;g{ei$ z#WDrIR(;0^Ih{=~@WOsLgeCBj)xtsWAaGGMVj!y7(@ckLwDSJ|kU($0?)XW2Gg9LC zDI1)ahU1qeue7GbSIvd3Cw4l%r}HYEWzc)>%t9I-CGe4=M$T=Q&&$f`&Mx^UWbO87 z+qA8InaX5`_{rc7ae%O`3wNBs@pZM`YR;8n;5P6v1!pj&_HE~rv06 z17TVG9k8w+a3uF?g6vi)UDUN|nYv+Yn-~kM}sDN-s)=;C|JtI~w za&Vpksiqri%C<_1WtQ)dR=73zQ$8t{E_S;9suH{At~h&*w}qukf-~lJzT~*-Mz;N^ z+ta%ugaQR9vglm^3l7aUI5~l{Rrv_+_osOeP>2o5flWxYyysst%*^glv$ql&@xCb+81GGy13U|&uAylZtP4#_60#2tY9j+VI}WLgI!7zF0nT~0 zRP$K(1$+@1=XIqWvTtjkgsUVM$CI|nU1?Nrx9^e(42`S*O##;t`%uTG;p%cBI^7qz z_6DxWqXV+Eyco(uLzRNdZ+CDDA-<;;&owq$;E90z0)qwi>{D%UnOc_# zw(}%<<*38C63SCbOD8ujf2k=fhm}w9q!ax675Ij!om+&~RhHtqYgTbWL$GNcz{O@a-K^gX)`2 zdzEveIS3)`vzmf%#%6|ckwb{`R60J+%2lzsXyW)$Xur`Q@RNqDg)|rWoiXj?5`O`* zIgq0IKAWJ%!EKaiS8^Xe>S2{5&#vS0LLhYu3|?>%qOCs-u;th9Z4{Tg534f|5X zWvFm+5jw1{_LMgyL*t-lRjn3LI_1eIa6Nr%csvx(lUwdSIXLS>ubRoP2b5P(1xI1S zaA19X7Ghte5Y{gD$!4b|K2#HE zh%Cvf(a#|P7fRE7Y2n+#b38b30})?aGBz5F`vq=ANc&l?EY71VW*|UX@i91y!i|As z9Vxg4R$wr$$}%{A!f9I!*WN%{nUbb)zKS#FuC1=i_xtEvko3XlmZ+PH^JqD>W+8mJ zvMjEV<7cORbI~kF@fk?IRNhhLLZc+9NA?VWxuTR!bWMmno3K ze*0?Ik(4@Jhf_bF%DeWHTqwgW0V)YKh|+x)11^ndC?Cl=O3o%Uts(Q~jIrcg3ls=J zp*!_K3O+cCD%lxdcp@$$D6%b99Bb3anFq zyNc$77%D@j14u(8O>>dw%gs+I8fZrWSLfLhEv~4{8 z1)7Wob;IS}+eYnZ#ND`otbTddPw6aGfpkJ8z96J~bp`}|HRb&lD+eNfc@%rgA&)sQ zdsGL1*Eyhe)S>nA)R*9pTKg+BM~~gUJzQr(Vg#X@eXWZ@6E`qioYiUzTYxL-wIeXs z*^1qLiHGlO$3D|=twRW9K37g>UkP-8f9gV`-CPkG4l5)(sKK9;_zr?>es=r5L#Td5 zpUy~&!)NQLlF+N9DD8l(vfJapt!!yQfvMMWi=y8#*j6PC10-`R?cO-wN})(S?o1v` zS_v{xdAWXshBnkyaD2H~f{V~NE5-SG8mn;f+i=Av937Az!%!>ZiWQn|DP;b-`mZar z=tyyKjfhRdMO@r$NcWUimWV4$G*@7NKvG6(K4=*i>}a8mWTwNU;#vUQ22p}$?m5HF zmHGHlS)}EiWtnkCMj8)*p9#(pP_rUAJK9EJ777&Tdq{z4sB4#axymVTmrVg9U38bW zgxqUg%F407tLO@Nt9cd^?m3420#@~2r)lhls`QXOW2zlbnyc>$@Zrgi%eb)7=Fj;E zt{%Y6N3tzWekuzDp0tk7M^Sp$=EkLy+(rqEoLrjQ6!j}y%3#2GZ+oUWhJzd-i?C@8 z_f;F5VdU*YR?f9lg`49^c%wb0wm&spp$#Oc-=&GQsM5dBTl!sM1@Q~%JZwyj? zvI+A}XR2l5=Dvcbvzb=3UGdP@617EZgAgEnOn#-qnArQCD_leQ~(K^pKFuGpUr zm}_k+q$db)Pe`8+hJ=<7!h^op1JTI`=5_GU6Fw%dW_O)M`jpi&{Rr9_3Bj zZUXxlKdOh8tQB9d+F4g*0tN0Rxjin4UZdnu2L*X_1kE0UWV zZpx~9F0AnlFn&Qdz#@z z^C0lH`Pg}`5ZSKJ<%5y0so-LEE-2DAv0WgIK4&ckA*A)*lwgOhASF^6dj#bCvxkb! zu6}J0^>b!RG~Z++UGm$V$|MG>wGJq*BZAkieri9vrsyAMZQE@9`wX+sk!FI+>q_ZH z+A1)(;d4L@>Kb=Q;3{u9Dy=Y2lDrR z7B>}4=?1e`t?px}xd_tf{y`?OG+!y2FYO}92JLCEamM`wEnMq_v_WR#`&LEh((s*w zN%S^<8Z9ah4_AK7Bjn6Rid3~jX70?RUv~*~uq54c)#L0U$4h%;;P}M({jT>dYUsT& zET!?$O7w9ZX;QMD61FR}<6iOuoC3Qnhi~x>gmEm870Qz*nb|C+)7J*gS8!`~oVI0? zo(phoN&FRfAFUiR0CL+6X>dq=dAz#FU3u=nT*^3Kvh#rb;`0SJVney2)C^L+TX0ryFH%5a>Y_ zcZfuxJhDlHT)=_~qRFOHz7tO=Uphqv9FC^VAvqr8RUUduV_PdO_K^6}ao}8)M%pcEQYXupQ7a4P-bY&xv?rZz z-Hjm$T5jZ}5w#_71uwKrGxa#0E}04p5^#zoZ3jZ@!jpC>X4**lHzg`T%PlGGs89KG z^?XZ{qtlMQr2CMp2gt_HH7ioN3aIaLUU?eW0tE`xk1XyTNC%oA^<8$7+KsgJR;gO5 zdR2^ENh=e-uoc%*2|C4k7z*=CTblIEN+@kfX))AxhseO_bVvEN!P|anXSw-s`8QV( zN`q-F(AYc?z)uUZb9HUK;pCS5rZf&AemaB?N6-0Pi7#!#=VM*~sYxQeS9S&J zxjBs+7F%PHk%m|fQ2rjZ0_pjitG7cNAB_C){89T$=2Xn8pm=Yq$62`3t8Ty|SvOO#Zi z0;(t<%P1wYA{Dbf_zd955p(K9@)j;w$k*))G@^HPm~AbkbZ8wvbItCEfY^UW<1Ovl zEz*WT)|QoY#wn~zzWwl=}i2pD)46dn^Ta!JN zl#b;0w+F&E#7wzlY87x=66bSKycT$bXq1m8#582#q2V_(F1Y%yJoO}cjr7=ZdJ?ia zIi0r4%YHRW`y7;`PjK)K#ez0CUuXvzvtXc|>A2^|x8kL}fNwQMP@Xhx%eOv;ROswF za?7C>TB;AY`==ayvslssZ3?PnoN`GnQF-zK*`>)L1$9WS0L!(Ew2&`JLffHB&owe2 zyg2?650^{`;2{MWA$0-Sxl(1F<1z*UdiG5H4rG0o1 z^Hl<6vIUB2d)jKZa+C5pjDb~zdHl19RsJe%OQmou)OSd}PD8f;66pMLwp`j2x@^4^ zKHKd8ZeOed>Spz&c758eYbP7YUW_hYcTghBUA?$@GuR-XO6`yFXxh=Nw`j^aDy#`){%LBTE%cIR2 zMvop1u_;c(AW=Vn-0mL3O+IpEK~G^C1q2(cK39fEOG7zBwPVYA2y%4 zX%$SOT=kSxqWtADD^j4`m&SB-F{Wj-`&jgp{MV>~9wYkblZ4RMbe~93++%| ze447HBoQ_J^xjn$b(F>YLgEQ~Nro;T*Cto$t0rZfo1}6mp}nl~arp%b6le`__K#X` z&dzXqBF-MCExk%`h+nT#mHhaBE=Zn*%D^E$XjT;>&L33sE6*p*t(N(L@UZQ>6n1f2 z4vCKQb*?>Z$bQ)8_p~4@JaxD&7p+gr!L%j$DlSif_hDSywyab~DGyGs;&RvA0{!Ig zXkd}(bgcLa$)7(2{92k~Hn>11ydRpUX(bglNq|P0k%vyPw?MPn^VOnv4(R&Il71x1 zno`c@8vF&KI%H@=dq9o2FIcD>$|FFYW2eL9r%n4DmZJPC{-Y^X>o<-kuNXB&M*01zHj9 zt(OCSRq4RIGJM-{?pRMcJPkb%=FD8kq;Lnj+CxtdX#t3#6+L`zGYqb+A*Z;mrv(zd zJ?Rp-rvU{9GqP%dkG}S@mMY zDRvs{W}!fVb_6|GqeoM&kU{2|wAQ-HE$K__Z)52ymA3fE-h#7nTnI#Ae+;2|K38cd zE~5{_xdT?(p5#|-aDIXF6C59||B_b)(ms!q(d8>3v}5PPBeR{>9=W*wyFh&&JaPc? z_<-b587ZB1@UZi9M~GvuUTqDNG?l|3^yV(5XlkRjE%d}$xlD&5|B+JFSTpYEJ+w}E zTX_sg9#ifAk*Tb$c=kA1oN>eL_UWQ%9Jb1F_AysTky1Z^Ix=p7a6v~^GQpiWNbMBE3nkL8NyGA(SK}+4Str|Gl~Iy`6jRIWu$LyYKDW-TTvU@64Pz z=S(~2%-p;8+0~U$-ltGa#8;&lAjAy`2&?GzMaom40!Y)dssib1SKXbx2&$fqs`+=0 zBi*?DpCAz3fqF^}`Gc^!LU&!{;gp<44d{loM!jWyP(}Y}(!Yv3QK8`c6L+f7*J7j` zIU0jLv9gqqrh7D+N4Fv_aQhIh%%%a{+aW2Spht}^T@~T)(n|@~9*DlP?eiT#XoilP zY_vYThleglUq!ViuhOh(iIv*(lo~|s;pQ^*oK{MxOXXS%^TM5|fuoK)8lY=|CO;AhhU$=F3&!V+Ie7uWLTuC__xcqrjsl8->z z9653{2Yh=bE=_F}XZe#hOIQ9I*@vW+&=qT5{@FuR(&e8()P!ELv4CZVl%-ecTuzrN z#Jp6g3?({KRUvk+$G)Vc<1+0l-JfzcUD7`Up&r=2()yepl!o(5cG{=6)Mi@-S4X<% z<|F6FB;V?aOhD)rQ(t@TeX=rz^5vB@(A2xT82Co455U(&nM23KCFX9X`q1c)6ah7T zt%;8TmA4Jmh~#Be4?izmHG{4`<%z0(7F)OZ*^r4}Ur3u1>M&{+!g*l3yg`sQlW?T% zeC=bvdHlZMD_jvAiNrV(EnFoweF9uOQfJh>-W`>dl&M4-Mem$l5zT>C_9%Es3)F7^K!yKTFH1-8*XZ<=)Pbgzwpu%WSn&IJk@-kThaGgDxE+ zxz-C^6Vf45Uqzp3yK5qF6V>*nu1-onp)`}C(xQJVMnyHF{FEr8tK9AdTF+kCAu?!P zA3|dp*Ez6DzAN5yJ&y3jU^#N+Xg+YZjFtiXkyJUKh7NH%qAGL%eYvXqm96++x<&`8 zDq(YyGUS(Z?M$sL9?H5Z%O;lcxtFxK7q+CcKHI-2gzZo19v5)?9u3|e(|RsnM)jid zB@Zw8s8Ih&X+j`v%OpQmzNhtQze(+(k&M*WK+<OgsG8?2FqX4s`W)JHkU4zpn87PV~A7@rO-gO4{LQ8N!{iuwVIrb zXku{A)iW2X7h-!FTWABpZQhiS79BhnF=%i$qi-M{)$)-J7o{+4;34ZX-Akji28ykz zq7sYKniECulvK_XLXwrv=EQxyZ5YB@(pN1)RdD!e@2FL#pQ_5Mr1waT8P!I3%J}(0 zRSZHiS6&yK?`Lz za{rsdjcR9zRIlsHT9Prg)AXFsCrLp*bERv8%ChUzIyrg~xJl*OR=Xyis+mSva=0Ta zT27}Vx6rt9>DX0y>Pg@>rCO+KFFh5&la35`lq_u@r5G#(oJ?AlBS(&&1KaL|SZTn$ zSJRam<+@RAF2DT0sIIQucU}2V#I`?Tn52<-0l~byRsL7zLC*6k)rny498W>spGu*T z3ZS9BfVLS9zGZqYpX09)HnxeV&QeyHIK z7ut4A8KM3k+~CHshuVoWjxLxX$G96ogAsc}OoJvMKyAs(^(9c}z(t(aKPjl>0uxS5 zpMu?&bzVb?T(joe2>4{B{Hj(Q)sI6}@|whCHViejSE1GywSr{CuB0eK`(&^BOxS97 zW_@0u596uJ{|O?`NY8E#N$9S!`%pgkv67~5%6sBcM){zK9VgEJ+Z#nnmm^1x92tQg zvfBA}p6lRJgFk$w+Zk@ZV*j)AY#Pqs(|UkA#N>Ezx;5dpyH@l~&%w2to-=WN*2haR zWx1cuAQ)7-DkTV_|UoSinx1;v8)=sa^3qTm1|N;Q(u}y{=>Si z>8N5;Ga0|A#1U!;xW(w(ig9(Mc&D7l#avSSMEOv;l57xuQaRU$T;I9cL}RADZVGbb z=!u|vEuZyw1w38$r0bhm_D>vk(JM#?s8p_EWJuwOCYiB6pe#K{Q>yD9Wn}ba)QWvw z3x0bGN4ew^I69Y|r+Z=uwDf3EJNVOn)!==VU0=h!XNRLcH?~qa)sbrxttt{G&%kSao>F0w1h(zX1oA_K1A zS7b=NbTTtXNMEbENUk0YQ-_NXdJrUMP*YPluhj(e!*0vBB%f8OW^u} z8GCKfb3sk{O1rjCb!#^@yiTS|u{nw*O7HhnKu%a$jLzO4rK;IQ-B&FE2My0FLDUvl z*{Psvojnq?yK)VK?b>tJ1jhz76FHj82zsp9t9$9Fntm}oX@)x#fn8EGc0C!lTtPEu-p(LZF ztXtLf4Gg&g;skQaJ}7!zy*Be{5p!XuOdPDzGht{>w(BV zs@g^9ggk8-Ok~=h8M7#KkvrK*J1w3x z@ssW;(dVYB13`UJqYJH6)#-xOaFO+kt}>4vw5!N^ZLS)jqB{@w^BSR~(yp=w)N^6# z@M3%K-0jgLxBaag?3Cwr7Jt=R^$dPn{gHI1czAB4wMG4#h(}|%4egHpNbM!@2V$OGnbv72j}6PtsGWU)D!4c^r-8?rc=kCpmKDXg>J%bu>JV+ZS!|uwTAX3A*zC z?4LlCj=Q)JU9`{2ZL4&NfhJ7YpExW%(6E0tk?JMcZ0c_$o30$RoL`VVXIwVtnGulo z>8k_lar*h@7FSP-KBTBa5m^YRQ@)qt2T2z$9}EvlUlq8CRz6g&bWC~j`(_EOaw$gZ zBM9xP446B=q$Tb3YL?9x(HBx{krHQPtx_e^R}(|meRkHoNNW_W#1a-Ev3d2NUZ{tG zGtil@v9cgZKm*{~P;zu)08qLqzX%X}Sg8US^>#?!pQcMbxcuO^{5e<3Mhdk0j0@(X z-8zb?2LqLYz4B(bOO&r%xy#*EQ0G9X*CIY^71GY*>SjF+-U7!=r7nnXW>Y{5*G!?g ztc)aSZ-&209cp-4b)yeaNS-}(Lqt@94$2bWSQP_u*C_!#rOA<_nUK#*8+zpuELgMx zorU{OG%gM*>?b~JUY@tXdvzssIQ`XAda^Je{fFq?SaTwB^^i#&Zma- z8dop(&pG07nMm98ap=c#E7!C+Ylk#yJf*`+UqsE7yNq^ULl1Qj$-(C~A+CHNJ`toz zk$$^IkBMErTnE&lOTpHh(%3vg^rG>JU6<=Yj^4F&IoWm|m*#W<(Sg#J)5<}s1zx!s z$dRMxL9#`hU7{faVr5aTicywdzEVV{2LA;v<<--c&*fE!5ig+6&8W?y=XKoq9Zgfa zDB0VDEK*NGnmslInJyn=%W?7Ld>%IjK+=awdQrXr@5?y-nc)>>yL^+>zpglf_A95q zW@s~oIB`qTl&u8?H&gql_pW=h>8n|)fw5B3%Bj+S=(_{8N|91M3)b4vwXNA|9~K(X zRaC9-hrXm4TNlfgEnEQ&HS$$~+wX>W+>GIJ>}7RU&%yoIzhJW0K41?_Zd;9ap1jqh zZ@TwcyuG|XMorw*q<7qNPi(zbKP-6SI+MPBw#L>69g1mVS`hEJ=<&v!`>w=oFRg`L zj@r|tC-+~0xwG%aoew{2(r+zk!HCJz&HeuS&%nfiMI*G(q@Vc59aypBVVE(l>+cgg z-hB+$-@e$~A9mDkc<0gU@Ib%aO#0AmN0-{X!d&J)emib^@Y#ZlNTZDq2kdLoQ^yT3HX|<2MjMXX zZzEiDPqfq6`S6`EuGN~o3m(UHcdWurhs`i~<6GT6plT1H?3-F-#2ukt@doa@;ePbn z`NJk>#`qTAPp+9`F8BQDMl9LscpR{C8!K1f2Gnlo0tGgjWlXaEzS1*s+TtuntkMb3UY!S8Ri0Nya zIhFMKQ4qO&&O^B6wukZ3J1b4@z-b@GNqeu4){aFc{qp^{;m*fi#``T}4E-j%9DseN zj>7;|7XLc#`TO;F_}xLKe2e`)gnc(3ftFZ4=P`GVZ+YU*`VNH`idy7JK55{kAdbvHj4ipqCe7$s6vA+y5p)^{Z-?`R}uT zy#V*D|2ceW#z>Q1^PgYhGuLm8Uw(5RlOEa3akFG@fTZ1b`2fyH`()92oDQ@s4P5f1 zwn%%Y96boN4x&`o6?HW8BF|B8aAwTDLMWGJWlM~+{mS5HlZ%&-c6upCnr;{+pU+KeX`AMfrwLCWxh$Du-2^|5k1NKaI!Iea+ibYn z0YR3uWzCTzN6&*4MsT3}K}xG*9OGQeFKF2hvhA;HA;G7Mf5?8)NVAL->vhU!a0;=X zL##Yc;|_oYXJp$@mv7-bB3Dj%LEt5MUwSX;3qg+L1A%aV974zW9J}pW;HSa2kE55i zZ%Uw-q7C;vSMgB&rb7HJv8h&kb<>31u@*VjfL_NR0G8(v;Ufwauxcr zgXPs1I(Df=o(ig+q>*2`lKE*rNez&^QV+8kz9wYS9M1bR2+EVLxqZ?hRAbYc4>IEUTm$p%%7O}37=8on9e(IpPGAV86H?4Kdk$|%P8%EnRp##eEdE3;W?wlU( zO80h5#O)EagO{Cl9ccNcj&ww+!5^e5$U1Xv$kD^V1uk@=NhkCmdECTw<>$!ZLVOn| znYQ@*+SEWwPn=xz%2C&*;S8dNI~vc?1Hla_^_tXRg3!7QA7^OYlZW%qfIPKn{K09) z!PP3xC2%cOo_t9^ZaGOkt%SPTp|5h3mGd~6E>POs1mwukJK(b!%1hT}8IpS^ZBeP% zHU9Ee;_-wxJWtq9#+cc^<|DpzReGLA)8#zrS(zW^FCk2`6yqRq$j}J zdYAoI3@=Vc&QEgkC=VrExq94Oo(1AJs{0V-)@C1`}=|Eu71DD_{zly&0ao8vJ$E>!cnD^RiCjIWx7GSMT zEPmz|lm5rGZ{xAS+hf}gPcrGscTZMDU$430@+)!UyHm0L;d`3&2JhUCKixbZ+sxX} zD7(XurFibTpPOZK)=R)ozq}KMcSc{%dgkWq(Z124m9LrTCI7|c-~J_*eDqtDCMtfkxWpUclQ>F+$eAwF`{?%01!q}Ae=?!h0YLbJeZHter7yt6i%BOF@ z<$t@;+`qf+`Z&D!Wi13^_0#ynPhZ7eUpUYtCp7d!3N-4<*pP7nVb;7;(kebfN`fly z6C0{lvP-J#q?)^yTS|H%{(HmC=C*CSgUpw;7Cn2DiK+hi(g*O_eI}w~QDm#`yW|VF zde86RCr3{)>81bq4bJ|_yV&of!%TW#^(_AWgKuE&X^}lRcH97s(zx$0x zi(X*T_x|!yJT~=PIJlMDp;*YmH7Ge#Cw4}z*k5Di+&sf&%*Cf}x(jd4 zIL746EPY+FZPWm`+t6IZqK@S4rU&I1P<+LU|}w4ym#j>4F8`#J{gDab09`7 zd&(4Fb^Vx{7OuLI3 z9`WJo3AJIvKMi~CBMMEgJu>}m^E`VY(K0OOWu0Ml>h7h zuEdI2U&I$@MPJ%7U+C1U@a8?yeE#7d9>Bcznb_nA`O8|XUcDB-xa>O9{AV_ugroP{ zIPs;=B25uRx@R_vXe#m=0KN1{bN$WP7vbIgPQqdPMuMOH`w#H-xu@a#$7~Ymqu<6Y z|92j4+3=Gl{qaMG6>Q&6@QwMWne>m2->ipx#k34gS#9iK5s@uyFWAAuO}g2>tW`ZC zd%D(^yJFg?!RWDYyYb{+f|?@NA!*1w)(DTQeP?Z2$cI3~nOOV2QT{JS9T0ME%}r!j z>5$2iPmmlulIAL!H$Jn{kLAJ{Kkj@mG_4r^Tpf7wbMzqa!CIIX)!-+ID}qP|ZW?kX zIK)(Q^|^&-({T@FxjMAmbq=c?^*EjE`e1bBViYdzk^#8;+2$2eH%E>fJrCSIhYK}0 zd(ib_0xH+&E-LG?D_t)yl<(=wTQ0o-*$b7=*UCTbWxu;Z&)syXqOuBoKYhp{*$-}? z63VaEZG_AJNo7(w;Eohr?UwwVUCz;z%i+++?t4i$fcMK(e`(%x?QyLWY3yqTRkYlI za#?xe14L-E9QFb_b$fVgT9V4XO1nEbbzAcmFw`c8z&ewKl`&UV~^1m zv#q9L>v2EE|6KZalicm6AHya?r{Un;FE{B6ZhRSg9zO-u|9VYGlwjFn`!5En5miL% z2H0)q=*7A_?s^4>+xqKec;fci*ldsOO>$vn7$Ui=7QBSnk3WOg-;I8Dtp7SwvC9WG z#hB8|B~ShHZ@BUC!p)75urU*+V*l;d#-djqHtBmFc@>LWhGP7N(aUl>Y&Q|ZGBwP; zokxvqrC_lZzTjA@Kzik49nVql)Km_g1UXK^be&am*NP01Ypl4G2CcU(cG-2y%KYDL z<2Cr~ckcv_j$R~v>XutE{+P>f*p4GgwKm7Z)i2?cYaTJ_51zg=W}Wdv%(7W;(jU*? ze4)Ah@7zvoyHQbm)USiq-wwO&zGcE*>~-={=6d(pzsB7=oQY{K{m!JXXg>^JpEa(A zpIYVN^dy{{c8&}+zKik1P0@NE_sOr~s6YKL-hiZs#;O;t!p|Pv+N2NP>18~VAX)mM%B@~8(fKN_zwB|7+~M>e;TWcYWA{GYTz|NCIVXBK zr2q3b;liip0^3IOxqWdb)>(H929FqM(vya^V{y?H3?VX`0Ni%9X&{Da)m>Zv1Rn z`Bd~W@U0V$!DWZ-h!G_fHlMf}FP(A?9{FIjK4&hv7dOq_6`%Uru2Fe^V2hKE!lR%2 zr%BKL@TQnCxanrQ1I+v^zC2s8|7YT(fBptuM-M{hJNVDN(aWssY&8h4JTeuW3NTXGQWkXhN&u4#`6gUb(v3A&0g>s_$w8t)HU@ zfd;Xa18#(!%2OWj)Ccm3lA{b?%<7sc{hZWXO*$_XQ-^!tL$911X>H_)&|~_8Gg2;Z zDS20)7v&7ETPw+TOWJ8c3Kx68L1*Vl+b~H_&K3A#1)Hy}EA4f_y&R>sDB+&+QvzQt z=t_CyCLl+S-T}^LaJDXfZ~rx`{VEo3cR(m@bjd0Im28*1Bn`2l+L96As$x7fQoWqj z)dtySN_l{6k2(J*g=$*Rfh%*_b)SA3?k$cA;K%Wod>Fv%D3#lFLqgs(Izo`G82Pjw zS5`HoAcL02paddUOZoun)a+C*X4Pc~6uDX@8OczIlweT3b$b9TLs8Wl*43|l*9W^o z#{rX+()Ni%TfpF#gF3l=eNVYN4{^;_f&?V)BN|%hi=DH%QwQ5Nzudp7q34LU!U_W zT=K!_b&{paJF%vv4Q*{v`Je%GUo+|Usae0Q#o3rT zuuTP(D%;0KdCHwM4MljTaq)T8B1H*=juE6~RcIN%ueqLl#69@hPk)XF-+tGm4?6qv zSf|zQ9UgV_qM;xaw;Ajg1b>ee5CVnV&PM@$;X?BX2CjkV%`F^rq_!MGNPvVfTO9 z-s9*;7-q$G@2F{;twiTiyuY{~M$UiPBwtwAis9oXV(nr5L@hezK8lBR^s>rl$Ir*p zkG_HBgQJ(PHrsRphH$<|FE^KW=Pkqd9Yz;;M+Sb&gZIV1fAzokW=Aw9`)_p&zA%ay zjwTApGP4WyfbDZ*2S(^xG)8fbG^RpBlzZwp?K|@Z<_Q) zkBr5%O@OCwn`_d$U+^95bHpb2>g~^(^pP8HjsC-T#EDE}IvnIpSDX8n=5=DmMp?g_TTgIKbU1cAv1I=Xw(!QDw#Dms9k*We z6Lb60mOEh2UAM!yfwNI;>tD{k4R8J60(@w_XgpuP?K1ph>*<)jUhubPdk)eZQqpa! zYg;32aTFt4F?4nsj2z9-Q~g}+;^>;pFZ$4w{<2|^PTIM9d!lit{WQ-dGe=*967pPY z&}GJ2oYb~KQb^8WN(bgX#4;%G#xqA8J!;)^%F@$p&f{^O8Q{Gv$IA_BW;x#r=DwWf zq-dc`^7FJ+RD12=Bjs^&B-y?g#g;?O0KmsxR0lYCQW_eY_3fY{M~>bL+ZNH#*rq9$ zblIIQD^Y&g%KmFtnzn1i?U=G;Bz2=Y((tEvrltk=rHLWq4z$b9D(!PS?a)W^Ng8gw z)4*ldC11tKhfr=qldH@3ar7?P@aSRl^7WH6F4R{6NqrQd<9xofU9{5*vfoWR#t8+b zINs!|u8FFAqie5XO4kPo?fOQ825b<@ji{47l&QB_&y zK{a+mSL0Nw2Im=?9MYzRn#HP_mmzuJI>5)?xm2|r&}g)+<0d#3~pvc7khX~4+zar_z z#ePXBM}AYfFsEYHLMR^s#rih%WTTr0B~z$W*%4CMz*ICja-@asJxehS>|ll4s+6zX zfvL}g*;^c22KA@X9@DO)869aEZ4=d%06|-V1$!i}Q{EZ$mYyLsVqTr7Pg~PgJ%q&~*8LP)I&CgqH%Z z6CC<*zMSSOp^V;3zFpFlJ5P{!x#R{zs-(D{u_wHwWx33%(^tGXXGk(?zKYquxNQ?E zR52NR40-lSHrg3T(s6+S&8}T$?FhGXnGO;!!6!m2=O>ZvNFFj{_!dcJ=%PUA{nuW>^7W@-Tx+SUP&j6f&*K}5es0Kra>{Y|{dNcALm&B| zN$;`oh|Hs20y3m?R-b9XZ7<2UV(tBDGoZ{LLT&-tUd z|IhsQF<|THClt>*eJX~=Hl0iH*ss5VYhD>&A1NeSbX3_iw7_nCLGd=@2+SXB6 zdvx@(KkqK=1U6_v%fu-ry}?^|8`kvGHJq;nSf^tGOA!ICt*V?cc($m;pS^z#KNPaF9U7A z{RSBN@G$JO$DSrVu~2QrgY&Rp#AK76I(-JF3{lt_Jp`HfdBtX_P+B%yiDlKRtE~Tq zA^A07S2W$7;C4X3%6DGI)BjzKRqwrQDDJ)LCJa09+lAu6rhJoaHo~uOyb&*M7R~Po zt6#%YXA=*I!S!Ov0{5&%%_p zXnn1-@6nk4=da-Incp|*Q`fB+Sxax7Xjw>HShELFj(l!osvJ5L>~s-N{oz-5eV@~D z?8N91#cUGP=%xR~6~B57`<{NRNl)zeIB7>G-hJ~;tau~x4HwU!j7`U{z*E2csY&-c z`nx!5uko>;k<^L*)&L!xSt=Qh^|$H7Q~!v5_Uz@=@8X%qU&qAb{@0|>IA}xAZ?x!l z-^831(ND$w>Eij=Xp`|+@$@fE`lqc&lqFC6!QB1vjs0-S7e-WuqW`45 z@cD1<1t$XLQl_wC&K|YHOl;6CV`%cq{@Ny@u^sjCAZ3jnj4;gk&wq_(>+JYZ41WLL z`2DTxoAk*)`~)`d_Xe(f;&MYbU_fEcO_+$`@4ju)OZ8S5Ne5LYV*muHelYaH~D{=eW zRrt+Dk;Px~>M~%^ka(P_24cwI$R5sH+I(Z}Mo-f>4$;1JMh11eqdtodZ&CazVe}=q zp)Y?N*FU!eA6jn+`UGqvtb{V|aFe5v@`P9+an?pns76>@Yi_g$oxVM@mQro!g*tb?m${m@_z9&x}$HU%0rkQq`l2aMCkuR|xcm&t0 zR$e`z6Svw$>!Q()#}3;4xH0)6mqQD=C>B-))rS4%B)Y0)?R{|O&-XORSexgaS*Tj7b~ish?>(qa==V)=?e=5|o&H*VB`=wZ#U z{!6g9_<(J2tyV?~@~ra8gI^~03=wbBv_vnb?Ko=+{&>f1EZuf}lfLKnCD`?I8=~Kv zRDATaT5}$_9@pIdB;Hz4VzcN~EE_h({79lSy9Z7?4yV2FGjspFPk#pM?s+&qe0cOT zj9ZU&{Xk_c$S6LqN2p)o6~tC?w`^t=eC+a+4OBiqUPStitGTO16HC`rr^#FK%0syI zmX|SLSoE`no1J(8J~MSfg=(DxPseGi{)j((@4Tqin60qa4%=hw!jUFj`3cX`%SX@u z?YsE-{KN3I(>FKiL8L2MM^D0(jn}hY)*6jrEnT|3_wQ@*_y)UU{YRshCGUKDYwS0! z1>7c2CvLJujIDGwOUnr@A6sa&KmI#&clrE7aONkAFH^0yN((IX5_A99?=HvuL(ak{ z%WosCMxwo|SFeQHBKjHI(@)qOZH4YSY-(gzPWkaIcxCtFF{K{AEEd%7aU#`!G7dZQ zoA{uW*D>cBoc+b$n)`cq{s#7a?d4^gh|LItQ_untxD6CV6mpT_M#qz{{Z^CIGELR+LM;&+!XDA0Towt46dw5)TWxt@O7D*WjW-@|#G zV@!Ihy>`I%W4q3uTl)7y$C@>zAC)dacVcx%6u=JX-y>#yuYtI#S|^&zq;chqMKr+% z4r;@iRcp|v!JP$4&uk?cfPZAF1bJX+xq8w*o*QVp4X$(d<}<%R=z%KN0o>%V^QFlo z`D4ntp%O^TT0Q*1$zk7Q-h7K8u969QR z_N7Y;bF7d2bwEn=g}&(-ZA=>_$9+}%(spwf*;4Ldh!n^HqCYZKiSM$1Ml5!Ms*w3h z4pi;jjppc;;CAxmdpOcu9ms2jlILrv=fHKik~woAGXa_FT4trV%sS6$BDG36)ogeZ z8El^>JHRh1Gw=)%r<3HE=C#weM$e#_|_U`joq##TTaU5a&5;d+fQ@ug&dk4?c;> zceP-zGouH3t(cS4RkfgBzX9g9-^huWc4+jtd;7or22Z^GQEakqnQk~X-C_zh-r|cU z`MD=g!v(+F8bAE>wvkxorIZO%Hpa?7KVw9`*|`Vvob6DhMtrbs1 zFUOtz+ZKHO+h4;DW23QH^Vr2W{;H(d82Yb`9gq8lx!wM-Ie6?}zr~MEd)A~+zT``o zF)WMzlj6k;Sf*yBsw_=eqC&Ei7zTG`rtys>=&tt=5(O1b={l}%Aqp!Yx*sv)qxiz7 zwzPhFf}nLQrhe!Pg@5IYPRzUROkm?ZO=?Wh9Oz|u@$cU==?kCR6=$733+tBNLA0!* zNeo_ZDt6g*OVD?R^ul}0_1Ayx#8Kb=DzVtlx#+vdm%U;KF*m0A~#?}Wu$*tojW23=$ zn)`+AoxsTW>`)^{W3AEA%e5oB8femMjai1*mgx%T~_`}CU5U`>-92h z_Nf2*<|4Dxs)>!nwHTcK#&zL6PciP8cti$r?g{SwI--97)SG-@K zDWXVs-uTeX3R#-X*R4M!s&h1d4GD>iI% zN6%TMI&{l!=Sg~mm`3TmP!pY+!_4NW3EVS3yUd<=TA-oeqBw3+=M$)}Ani!|=shl{ z5r<9XaxgT#)#2yJkt0WrY(P&6=|8|7`2+GU!+H>6f66>ojeF>)tc{4a)KKyGjZ=+_ z`2@8@x-w5`1C=93j{)60**j=}pX78wkzKdFKBVVJKJ$>Hxxl#rdY_2^d-B-n3|VIY z1^b6!V+HYRW>A)7R4s>k?wY_I?lA`_VX~+lvhxM6IAhbBkfEje=J z=)0i)rVN)0bnPO_JUJO9f20_G<%c2mU$5IIuZBgbtV~D$(p`Df0A1Pf#Z)X{(u1W;H6Z zyGGU&*ztoZ<)u8t09y5A9rPsp_qd6NGeOYCf&wUC1IrT#P za+@EUW}mjxumtJgX$Rq;-+kNMUv}-bIP-&>U|2~Nz3f%|>z98+`vGT~^z@;Ttj_sw znd{s^>tNQftmaps<7h^RoZ$kx)App@@7~yFE(nan(JKH$u7a6{z&Vk zBia>nZo_Y`?Zm;~+|;D|>*aXq+V7b!Y87$z>HA<}o08w5}Sbdy}!*@_Kk?u^C1xY?wi+vj80Z15Vq{n#TW z{rcoxux?i7CDowvRC?(GENB^tF@wr~Ki`4(pZGT(9k8WIeQ{hXIu|~V2VRW6h_&qw z8(_$WJ7MP~k-fa-`B^xAv%y&N_G2df$m^5w^{rd6;^k{i`ujhA9=n}&I%Z9ZesE6t zl%mfq8w5^dopxRIfn@5mWgHXd4y7_}+a8+{W$Jq_S0y?Z;`s+6e?MT`9k9U=jfKxY zVA3xR*cQ__7!*tIu)&bTSWMh%BXfP>p{KBX`%!P(zmX3B59 z>d$z1@(K9#2S!v{;D*A8J zDzOSF%hCPd+(c$$M(1Eg%sE4~lE>N7bk(4tGqC-}?q0((pJUnodZL!(KkK>tTdzrkMgI3{% zD^JJyw=Of~Bi9~MJ*<}Wzwk_XW_ zW-XH*T6owvZ^e4%{=lz(0Xq&+#a}10^zD+RhE2tZr|*q3zVp*4W2dtc{MEoMaNIY) zVDA5T$^YTRzXD^;`(+A?-tELj2Yn9zd+Zjbd{C($-hX|GlsM3BGvhO&Fu2r;l6gH3M6` z*`-SB#1CM<@n_?_Q=*?a{L?RffR)eu4xhg;dbwceI%Cng=pD4|aI#6Cxo#7^s8wc@ zWkpqe9VO9vbyNX4P6=-AisQot+kyPh9oyT$mu%+WiHpDgFU(mTt&g{tO~QVkKMRLW zjOML=|KGU$vIp=|%M&L3`3Em8)r?-onedVCpA;{_Bu?A=B9p%0e?E(WLzZI!rkV7o&fX0*z5h_t z#MIV*OF8e|iwnQ@XS_KidYO25LDTta8yt1!=S+Hwf>~Yo$nWsoU#xA?=l$vP*sg6e z9Cg~>CVkNb|AWu94Z-s0-56~DsdG^LS;>E2ewiu1|D{&U{`>>@sU@>z!bkA^OO7@7 z8@Iy!7^eYH0ryQ0MXr^6a_FbY;e(c5*rLoeBP<)}_aDLUzZ<>$xAu8|#^2n= zu95PKwa>%fPFWw16w)ZA|MdCoKz~eg@OIHp{T=v^|HCCWe-WSE=P;B0%(f+hjuqx| z$cfW1Y;d|arc}QHpjB44l`{JE$Dl!Nm2PI~N;E}e7Ml5>BmZ#cCEv%t-dK(KZ$~ey zP1^7CIP1`fU3v`I0!N-Q72o;aV*I0V*N9duZr=b$o^zlnp4c#jbL6N3(({W@KS}p2 zX+n1CoWbT{?|~#5n;*v;gqM`g(F4Fe^Rx5I_o2HGX#!-l|IE=V;CsyEG9&8FJMPlk zZo5qYIalVgdcFzT_-%MkNBh!t3>`8QIdaqs?Ms&y=GYMANTM(FP4l#o`WCKCs%Im~ zqu9nGy4uOevVTUz_Em<2(g?egGHr|(+-_2Gn^c5vbCM%RuK>4+q6@*kXBL$GvLxa~ ziM0phYp5rI4tXXvkg?_ULJh3Dn(i?Eb)L)Y%UUUAR;!|-3C(2!$+s3%#@(W8%+|3? zwwl(Cvf}@FVaYFM=>Qr*NG+(bdi_A>Mjr#?HlKJRdck0ut+&C-RV%S_sK^86_4iS%sFt!!dkdJ)TNd*}$4(3gs+PY3eENR*B@vY$fpEDylF# zxmsLql^vMn^lWc0oShDhpPlMu58}rsUTy9-zUaF+WLz4%)Pd!T-^X%9FBgp%KFGX= z#qCD2MOTk#Ns32!H9DoOWA}GWeIT8g1Xe9~gI==~OO`1N86LgNRkM|0bcoL9hk)z+ zFqJ#7YRO`Aw@eShuwet^dUh_y;-%3X9X4!0d|l`@Shl2KOA9u%h{0*U9K^VjMu$Um z?Qm>?t(JyA=j|-mw8%fV3>$_vRSd79`Pkkv48sflnx-Y_ z6?1UUUw@D5AAK+4H+(SqEpNx-j%Yl0IN_@}e(KOnYO&s20ZeiLm6HGzjtqL^tR{Q-QAv7UwaM1Np&`4|5Gw~HCm@}aQjn<;x0Y4x!1^-sF3OQ3 zN1uRnn4vsZO|JA_f)#a_U+$=gR#9I0p%guwiQjakxfiuKu{I0IB`QZ<<)F!tqep`~ ztp}6mIMlRF0u5PRA!&~026teR$@tmEKcmgI68=@qPQ|Xi2fSH9S@IS4usDUxTDrjb zTsW3UPK@qc;yNIwI)olJRf7z4Y}yzlqxIcqLDrY%$|#!M$p+}xkmQ_0}>~61$g_5(Ci>2F-hk7yPNQKr)1Nm1ItM0(2Mzm!3UY1sBHc+K$>EWKy zi&`4BwWH=fC8XF`Y^7%CX<4s!;5l+M9KA1MsUuwWj@$Rs^DnMGbp~lo9k)%gc}kC!d?vUT zAfMZ1*ptu&E;8ZDxjf0Q=cCZuA-w?=N>9-*9eJ5X5-A0f)M9g!KcBoga^%R7qX^E= zgglj}Pw=@b1Rlh9aVOA<@nw~tO9aHP_)ziEJ*^{^OLcPO=rNFDMa|Gi6F$Y_sIV%P z+h)P8O6hYn2V5q+=CP9Ios_PEbw=|^g*3VjbGQ5jFI9fpT;*D+MK$HitUM5jD;N5Z zyWU7fHKm+nK}s~~iK0F4Yi?tfkQ8YuCF>75Hcpcw1-0emaLoAF$8i78ZZ^qhcR2=| z4+L5U3^R12MwbaQ?BAAw7(Q|!szWDU{?|{;-Jc(L0Z+cZJwErbwM6RHfx|Ic6s57` ziJS1)yo!R$P871`Z#MflPV5puOi8BwN$^jYVpCoLN(lw}u2=RW)G}*_q+} zQ9X3kh5m@5QrL12tNS z7`W8A=B&_;pX{`P{{T=DTrFBKX!x*r&cJ9+4Hwc9)WC_@^Q`4&}d)Tqv1P#EvKnnRHQx)^d$HKK_%pIdQly@ zdZwx}U;#7Zldn z;ZSpT*aj^)X~Xp~c3|}uYS?z4z&E!;9iTjAI!P8drm=c`aO$(D+IBhSbdUoNDOI6W zkg5uK<0`o6s_H^7q-T6pGb^HHg1JmT^e}ALauPOJf2>IlQeoBUeIsDKa%AOt0zOUa z)*`pQbt;hdY}`HQoJhue^+!@6ss%&kWRU@3deE(RgD1F4WK)NaE;t{7srbDvCph@d zIXT*9Le$pQwl?(8U-ZjS74l%R&p>j$G=KyATNz)Of&6mhXiE6vOvyfQ zo1Bo{KONX0KBBo58EM`Ws0(hZB- zF;A_YXK~`tFjvy;BQz^6Z zN1)bKGrnCsSWE~&pO0sALHQe7o8ePI)A1Qlx0!Y^H+YU5ZA!E8276R&XbWBq4L(?SL2 zCEyBFQ!~p^f%2qj9sH9 zvW4_q%=L^dvAtGqFJ{+krmcWZ93+&XC}B+bYTME1dNBrpB=NDW(}-y#`ZP(<1#TA+ z#6O6z4xq7E6WIM4BF!cM(}DEJ(vXz`cBQ)REA*xF#Kd}+o~_ws5YjnvbO(BNyq~Y4 z8bG%twn?*Xp=Qbf-ZzC#C&{mJuOisjG`y?cBXmD#*Y<6c{V2D?;09WgGB7kQ-)!^A zElh7m+Q`heE?eScbh1(w(gCM-)aU4ORE50za^%R-W1tX!(n~>~=7G6)(fAHFd_ISi zE5;Af1C-d;v$*J=XU#$fm@FpDzQwcsQ!`I#u_F!|AKoC5)Ai zzaTCVGlUAQrn{^}vSOTm7I8E>T&w<5OvskS}c(ht(J zGD0HfDF;=R(5`~69@Zq+Sv5N)vPU;A0NbnC_qFUDx*c>s7@Hua8+$5M8c!{h)C;jn zBtJ)v967oXI*^7MdlkUPrVk1JsB@;VhGzJ3@-&f~o7%dfasJ;PU?3T5a~o)%b~KvF zkt0H=Y2?t-b?dW&oK>Y|N)W9{y&P2`@4g&4a`YI)54Ym^O2~5^`1+z`*Wrd#Zl64t z=*piWSEX|Mp|uuRO3zU2yu=AI+?xO`@XR*~IeH9eTsRd#(X{g6o?>ab!R%gJ~I?a9GH#Yj~mH-(%af;!Dkdgdg#?mB|&yKYdUMrd~t z^|$34&CFZVcy0M^IzZe#7y;SZ-W)k{#2 zM-%!ulOC7Rpo;R+9u=&ElGve%Rh4@PLQjGL_eqp=@@%KMru4j%tQ)H@; zbpN}%efwQkXvSTn9J3J23>sw+|iA603AFpxZspd0In>D8{!jR#H~2-7v--3 z)2$HgcFKaI>2XM5%&Kmyau+F=e`iYABr~o8H$N{3m9re|`Ulfe#O6!8cr^>Ow}g4C zrj*70a#|*`{q<_<$AA~Kbb`2MseWiK5tpmjTo2D6;s&(M6`OSfxTCY?Mu4^zpQ@8? zyL=NnpD6LvlFzq^IbEdqD@Ts*K(l$+9Cbz6hj3?jfd9EiC@p91I8&z_G}6?R&M54? zQO|NzEb^5p1Y9;vut)L%%p{Iw84}Jg!W#mN_y-Ze?@i$kEi` zPJpRqCdyCj*}_N^j6W(YWqglN)r&1s5BL7MM5AASTtJ&fw_M5={VOB_Ox<^)O8kbi|l!B zC(WKw$$7TFt{7G6%+qy>g-l^Ho`dG-0?6u^lW?9`=>;m16gN1o{eeV4hv#GAaFdHj>qntShCXMj5IaRFa}i4lY$eQ620|WhdlC zo#nLg9ks~NL0OJ$xxD*bt@Ps5fgea}Nz`~_jw7F)LrSr3Hgk%6bs^u|8{m{O2DS9lp7dw2% z$~Fza#}+j%mG<_Y*r#dVehE3NSEaS99Q@s#U5-GsgRV$ZERU{m)=+RC$J4T+E!R%{ z{H^g#F|HRS-4GxrLWc9e(t30x# zI+Bj`x|HnyLfS&dJ!CG1no~|j_wP~t=+QouLEfJFp}Zz|+t9UIq;=CT&c+o{yJ&o7 zB}a}NIdb$4xWai?_)9}ykaXx4gZdci-Z)>SWOZpZ@*ESfw#ZC+$L93!BhoU#49+Fee zzV{>xB&itRS~FX0CQHl~Xd^+PM_xW;#V3V0R~Xmr5XP-HgSt}fp><%?s8Pt#v#@aC zLUYZ2?0g%gfa-Mz@9yk3n;;tW1qD0PaQ~oPSsD3wN64^n;et||Gma^^C$0?#T{zN) zC_CjUYu0AV9Tzka=rFlXL|whfJs5|;i{s%#F%B4An5$aQo0AKHmg*3)k4kgI3c??Z zeiGkmWK@dQ(demIU~GAJ=`T$R z7oDAUO@_2Gs5}Jn2GUKO5X-~Wv1L{i8rQqD8Ug5;WC*wS*YvqNj_?W_i> zF7O@y^m4dP)_~ks<_LhaFASJGbU#)1`PTIX23tJ6_aoegtMEc8D}^R1fQBO5j!*b@ zDcxPRB~&h*&ZTrEn>%W#(S2m$eKL&_g2#*Nj0VABZgh+wBZy6Ooq5#&EnMpk+Of)$ zS4YKsaY_@w_JV-BSEM6CU(d?~` z7eZDk)dfttNgYNvBJYvz19zqx&mceZLN%p?Q=q7h#6BUxLep z(y@?Sp44ZW;Q>!N#G*+wEnVsWepU+nv6tbI~oH(Mchr8#;5q-_A;4rN^j2Cg+uAgwzDsp1y|CkgrHN*2Pwsh@V8U>X;VN;vTPwur0Juz3^sE*g&Jl0CJ9IE-5m{eX^%m2fI)*~(bIy<3b*PK5%{J%9e5-^r`;xx2Zuu&$cB&JtC+TEgHPIC$AEZ1a9^u@a z0PZ=>c?kGLAh(Fa?~BU@5zxPN5df5d%K)-(VQFS4tPR>>QI+X zdD1*4bTD76K(d)&L~@?iAG#!9Z7Qe_n+4_$J(<>}#2H?ZB|U-$LUsT!V2%&n*6)&b=;=-{kc zW4r9JZYmqh*^V0fv8TXpx)feJs^!QLp$cbC?SE$RfLox-%;_m_wsO&XtNZDdk01!y zcY0z-o86QOTaJnskWTG0Xj2xRCMzE940r@|bxK2rTC=zC<<=^zMxt~wn{xedN@cJ( zBy-fmLNe*}gG+-++cdPCnkvoEae7d@OuJe^KE;*V!^zM>U0WyZ(2>&>;QLB}??(z+ zt~~S&fost0JgGx`&)kq{+5xFX4v<_`q4GFOK=W<>u9ZhunHF@F z(p-JXUvL)AzDiaGklT~PMo;OL9^&qUK>OU~+d}Gqsq2!h1zw!*4vp;S>T|7BF!F6Z z0C()dwOxuqe0;&kae=mni=`wtS&ckbd5g@J>r%=#H;OrOtheE0t736g zc_cFUaKcerHP)@`mNXLNE!$L6hl$UKf zr8TY`deBo(#pH4NNGGR&`{NmLo<2sUd z7L5s9&LYItcUuQ_A2gdI%}Rgmbg(A^wFuG*w(D|14i|aQJURhwp0-|G9e`hboMn)# z0Y@uMa_;=kwQzFe=pJyZNt(T`l?fz$vm}T5{SbP9Uu9f(U%KngU#S%h7P_8}M%rz~>n@B|e&z zOC~2@H{B2JT&E^xbPHI+KE!3GJ=OfB0^x^TEY*|(Zsz@I?)1XVPoaeEJ-meqo=tGbuQFFmL zy@S=TtlrMxVEeR~~u_X=|lY z(sL$II>F(}wZI2R&K3y#=sl+omrwbDp_QVP26;powDUqHjtyy0An*!3wzKPVbWZea z+o%F^($r25&IWVkbiybP9|{$a=bKdA%9rYKG?b_9V_ZDAJqXa#=U$E`u*n&M^MQ6+ z@>9OJ0g(N$4$z0nL!cg#o1u9wUQ%62p3O%}OP0=O0g*yptq8ToTpzaZq#S$Ny$Zc+ zN%a8aJ}5_y9GQUHa93#H+7i3!z){EL@}=#*v^fykQa+e2|J)(qSKYM_sKx%ecyRl& z+`Z;#I&ddSWk{zw)OK(ieb4qnGyJ)|J{(mJ;q+VlN1DA)D(YKgP&W z=7Y4Q(4}lmNV(^Q89^gxhZD@FnV``7LanyWgS^G7Ts@JLin?`K(t6T$V!8h2Cp{ zXO5nXCUWhWf%8M0-%{X19d5;itjcm-DGj*Yj?ZUH@wh97&>lW;)Gh1eqI1n3>ho!z zyR1(d>mv1Iwc&nCoE6uFwR-;?IdbI4(Ol5Ny`5*fQ5qi56BLOL=L!|%ExgYS+p@WG z&6Bty4lS?`^~|oQ#OA3yJo0@;j;4nWD5slzC6rgO;g@z5S`eS3dr+4#@EOr;S@=m6 zpQde3Ikm&c$#y=lT`o^s3u5Ax@K1~b;(Y9D7JAv&`ap2rN~U&aq<~7?bg|7uPzF7h z<|L(|@WsG=1X4InhCV;_$q~Wc0|q#rkbPK@d?MIWdwohrW!UC#IMuM!@$8pcPHe{7+YhFqbcU(?c@ zd&>AlG5g7llc)}`Lt>iOEpRF1dd%nTz}i&cVw7%x%Vf}#52?N;^dZgUdRjWAb(vX7 zN5#-9hrV1nh>nz>7GzKw+Aqq%pF44)b-4buW!e842A4qF9@$p_bn7qj@HK|xZOc`H zJ|Vn&IGV3{bfwcg8`2t2VYmd3odyQjYLabWVwuUV^Y6E(1+^mvVIWiRD%|oRW;E; zj=Cc6_8d8KWCG3=!ph@9i4X&%g)0b8&d-39arbmLsoZKPB=;Q>xXrQh(1-4Q=w5?H z8o6!H(UfqVCfViO1lJy3bPWe=w58pO60SKK1Ic7(%DBF)(jD4z+d-x{0GwC!*I+6K z%E%HizT8e)ERg#zD?RIN3L*<<2Mblgt6&K45SnUwA|!B1DYhwWbNW@+YY;k|gf9OX z#J&y%y=sa1H-FJebh=5CTf90=pW?jKrK_@LsY((CaT5uZub!WU$jB>FRp-PN@0)70 z=)9=Pf4G9I1eCySKgeEOm&%kiA++?Aqef`RyPjJ3)yl(Lpu&jDuSR9nJ}-o@O0k3) z$#RBq4QX|^iQ^TZi%W`ixrJGyXqz>+W$4EKNws_kXmcdD$oVjPnnI{cAG&h&HABmF zsTT6Ma$i5tBTu^ythA&H$6MN~`&^K8-)&RMCs>;Iu4U+3Biuyb^rDm0SErXC>*ncI ziwiOH3KKJThS#$0>EPP`s6_$zRYq5f7G(HVi?rfgE0nW3A<&Q)Kvsce-$74Vw!PWB zNaj>pRrXb~0_8N_hq(N*&riBmn&f(Qpm_ zUA+4tp@tOV<>+?w@&GAEjvTc>vfp-@l%K}MB7lE6kE8dwM;d1MLIJy8i65=PMJ=w= z0V+yziByhe=r~^7UMfe9rh;otyB3IaAiymGsUCRol+*@3qgH+wlkQiOFrN@y-*snDoEyc?R>A^~dN*o0;^Cz4yX4Yxl!~ z+1Hx%b&q#on?nxAw6XMW2s_Mw=iKub-2CF&*!}3eO?q-$G-k`+c*vx0y5&K<_|9^3 zKXChx;*`Ay;o+|{De585eCyvGoxBMCZo+CVJ z8MGNr{OHzr>R-2-i<qhmKzJxpe{!cvo z=IV(5mV4u{1Eyk3KkC|+n9EcDx~VYcAHw!+ubA|`x7?0LUtWlovC&-L?Vtm&-T3|$ zZ?SCdqqy_-hw#kYsDA6nDcJGA12J>bpo&JeoFz~H6F0W+fDdoI#-ty+^A0@p%$r!! zI?_;1+3`ReFmoaXv)x%gKWn41)h?M*ZQWM{hu9bwjc1>(nP-)n3qMTy9X#^)`^;_Y z9v{SZqq`XC6?5_EEw|wQXXl#qVm$;CHromN>@(e@Ck-l%OCE^6hA zxb4cXwuV0lX(vZVtpVH(Ss9ORvlKq7q$Pkf8K>B=dHr9 z^`@EhJ_qfF$-`SL)`d0l`a`(+mIsUqFTS$^ZPSjz=l0nE#n;AKme0jwcidiB1JU>t z*Fkv=6fr2xB(JCI*O5PZ^U*tS$3xHH%_Wgf7&&D}9C*M?Oe!u|&DVSWmcQVh_@u&+ zEe|wzADJ<(^q2NgN#s3M>Z}`s%ZVzG_+iswuzws%!Dk+k>&?{vR>v{kI&+ z{iS|PR{UOi*scY-4BKu^gl0S-V%+$W7jw7t*38~jmNez!x*JjynZjPzpoX$9y!ybC$w-!uxs$f-G4CY zf40xWCl1^MZJ=#jW72a9bY+?%1|T^$zBX5d()xe?=E7QjldR<}4#Y=x8fOHx6a;oG zd>Xg><91W})VqcFdFp;Rc+ZVZdPLb2TYIQAbMD3;{@HGlGe2=4Hfci`xVVfSvnSet zOxK)V@jC9kzTm%hJ<_CSj&DITq5833W&ZojpTCE@HvBwJo-xX#*UbKfiJAZ3xA!yL zM+XU@0h2UKm7}g*&o{^%U&&%fa;SylXsJHhp@)mE2^~O=93DuknDh0t9=GCMt4Laz zK)9Kge55M|@R>K2B2U8~2LZh9u5D!6ErP^H;#Z9iaapvMq$ujiGxX3oYC|T`V~!j- zszLKEKUXkLZ8zyI;besQhyeQgxbkMJBddJ})eJ z{@iuu=&|6!UTzaEt!1t*C&Q7g9aTBxYpwA}Gd{r#YaB@FY|BILrxF^QQcn8rVrr_? zH8O#duX1H5Qd{}?Re{W>V*t|r9FJl+_?1rIs^rfgdhBgIKtsT$vC%2~QEvn1#>@Gx zbiGi|MVrS2nWNIBwa%BS#ym@>UcD#w5vd^iqF9QAcT^Ro0X*%Z2HP`*#Lo+A$;L=e z3g~eJS6`7T8nK@{Oz@P_9@}7wg)ZbyHoVY5SvA4wVzrL|mBNUu>woozuKdSVFOgvq zN~&Lt(4hVZ!yEbpah{X;gdzMhD4;Jt)#((tBE8 zn!q_yAkASW9hfv0pi8) zlr&xzVwyqf+AGs%%0sOS)xo6?7Z=zT&J|0!cG8-W8|wRMSV{AhpsV)qs}?@p`^Cl4 zszC0Qn+QF@%I3(?OVPc{&vr!s@7g$*CmjKB_sTjX=C-WdPR}mmHUnH(!i5H1I)K%o zbXZ+Hk*$0(Ldg*b5H?`Gh>5D@%X86ib#mlrI&ii|d+2Fhu8iYh$x$8>y3VzrZjQ#G z=6;v_R2596GbKWjUS(BPQSIawb*iE;!MoE*l6ey6+-<=@%W^zDu?8DWl9ke*I_s^WACK z@I&PA^;}#)A9)XwrXq=OZ|v-*AjuZv&&!Ae5*4O0(;I?wX(CvElpRXg$x+-*o=haq~te z;gg3&UtW9Z>WgspduQO{k8f^jwv|-Z3!*PG{qe8w;5!E{z%Ads*rXqud<6DCcr=zi zb)`xF@bouu`epxvscq3*z3qw{F@Ng*IAF#QqsNkGuf@;K_zBcyXBhq;7*=lZ0@JVe z{_!vP$anU`8`oc8a&Mf!9rin5M+|L$)}*ib+39#uU4}DeMio_~U(_n1H2${evJX>GlZXOeTN#?+9Mj-ZGzE!W{-+z7p13y&y zvR2Ci{HLIMTS4z4rWJLEtE~v>kfP$K+sj!6JO0}k=+L2?K>m;dCvLE zaMAe(V!VoEFMgshmoI#yVADTr(jVM&xUuOir7!EfaqAU@H89nzfg*+!*1@%xo{krA znMt2fSU}3vOt=cGTRU8>jyIw&Enacsd`#W%0L&N~eF^8;Yc9p{Bz?(ZAZ*=;A`P!tyz|n1%tfK!bwfDj~CI46AROqYLLSMab<)tS1@cLiD{~Yoj z{`$RNoAiU{ei<`|NY8!f;*^562H2P;j2D@cNwIghd}*gE^{!^FoH?aoHmp3~F)3$0 zT|0B>6u81`=?l32Czs;igCcvj?+3QP^x+DN-;BPj`H%DejFtO+1z+AbiuKxzZC{Bw zcmL9)|L=GA;jQ+avDt^C`r})Yy03cqYFzrWYfQmYo2`fA4%h?(RJ;$0G({BYp4vR3 zDPn+1&TQH~AcGlRSjR;~Yx%g+I*vFG920$6toR?jbT)o@#)WwIz>`hs5!)*~bJcfo z_M2Zd=^q`xDcbCgU;PTMzVzp~=Ben*o$DQU05+)vB}fi9H&`(};T~}N3W3gxLbUbf z-RADH|N9;8o7;|EHjC_gvwc}hJ4;-%qQCj?T3hdq>7$0Q6k&5p1=QkJd-=-EY)*z2 zWVu$o6sU0rLz2E)&gfPl8(hEI=m$}JjvP61jH&zO`<%c=*QR9d9<9Pso~prOD8~zDW?mBLM26L z2Mg_Cm!omWtp7vi3Bq+z;iOej1u)30Yhq761(MRW9*7oA!RsGB1{;>&fY8e^`;PnZmp4CZl0Q6b4{TIq z`C{}U*&lE1#16affsL&f)`%CxXo=09b>7|1= z!1Uc`V)BSmhjqSW$RZ;M}k5O+WP z3Kps8Wupm`x5JLpCSfR@lVkTaTAh92zOn4h20VvWp62n%o-caPO^e6}83A zpV$&=aDPnSYdx!0!EV2Qhq=4&SJQFC-V@O|_bQXVaqjLo>6^P_i~iBF*z&VSA_may3XbA9e#7vRacotQc$l7Glo z&yBZh@<6uxO3jUrueqEcE+UDt=RIA=;7@-C@Af+T?5W= zrrL=lqjkOLWxB+2Z+ihZocA>5c9ve&qVFo`b}U-F4z}MbdNFzLvCLo^|M!@=oo@Py z`oGm!vLv#v>r5Jh!Nc3I-q0ncd5eqhPxJ2*locRX?r^J4n{nFxDlo6kkRn9wspEsR zRPCPU^0{)UTci*`!~7 zDz2+dQ$&&OrKjR;cR@OSN(~*ooN3nb-n001T)>JaZ^F$J0J=a$zmCOkj@ZehM;6Go zSZ_66{7e*&Jbc7i*u?}x(H}m%@Yjp+$TlCs&c%k?gQtb73v^cu;zN()pE+fm?dDo=lz}54e7gJ>KpZglR!EIKB-aNvtmC&^UR%5{n z58<8%|7%h&&szdLbX{ya>tK`KW6CgdYQn8tn&$2~3qkApVhOGtluy@+U5$mNJx`X} z)1GKgsAb{eo^rl&=tlckGj%!M8t%4oI!RV6#JWlS-j62_VVxsKjvP7a4;s{Rd-1_wcra`*DXyD6~?zp zG{ds5eFhif7+oVH-@@b!BHQ;VdJ{K z9!pw3j)ykD-X9-t(y9Nhzhf?Ly5tIU9Q^~+D+jGxdNrVRgGkpM*Wkj3-oWu2Zy05x zxzYLd!-f9Y9*3Vl(WIk;!DM__zUz4YulV`3`(ckAqSx0t9{&?gzvV4lbm2!#dQ#_W zxaHzMV9{3Q8&?>)=?AdoxPb-2*G&56pI(P;rtgS#UyHtc^_BBq!K{zX!UiaP$?KWd zuw=Wgm$j5@V^%0y_Rd>aHem)vw^%yPxf{1E-oxB~ant@*oeBlsxH)lTw-w8s~*S^v29rgrJePPg8-3fq5j zqH`WM%9*DnWWtrIGOIh^AEZ9{QQ=fu6%?|~w)A1G_d*~e_c>2*hVYDJ7YB+Y7 z6+KM<@y{Q|oZ~ma#P;ZAt;PLDWByAoU}0+(L|nD{J7zUzDt4U|t+zk^btX6rU49w_*~qQ=F(O8US4 z*!s}@O#1F$oQtn@bfRsW<4pQXqkLn{9hCXb8B;=_x|jbWPWWK~khwW_$@1pKEl z(rGCe-KadNo?R}DtYTzPUTdDY)?BY`I}+cSITWv4{WX*R(L-xthfRV1-V(h`xyOay z$NnGL6kope8N>MKO}0h<5j)}2r$_cxzjuTA+uQ{7a&vk5PnY89-M@^ltrLB@@^4QO zT?%w%nj(sHHVthzH_dHKcEgJ_BNm{dP1v-Wd!9ZKD z!Q(Mu@GIv2<$0ahWl9T{Km8|@{^`@Ziz^cihx@3moVM#o^=w)fO)y4cr%#=3 z?smd^xB<-zc8oh-#VtRKUdDf6>*?5g_w6x$;NvF!r_*o7+zT(lk?TeA;cGWvitDzS zjv4E

    {3kAh`yVgJeVj_e9|a-9>Nbh46LBaam1{M~+a`H_FQfJweA>LH$mAMt9=P z+b+ZZdvGmNvh9>Xg}vZE@b_!~V=A0^`FC*O+AZD{BgGiLFv?{KxIFEZU2e}y6MV6GrEuHy~qXh0+Or@CAO0=PZ11ZiVR-67?z z86FVw@;ye5rUPB)V6MK?)wlb?TU}r^djy3#l4a?ll}+6@_YdGNggh{BzW< z4vM{%D68zTAT3mgP_OW$jmTQxdi6nCXqTM}R!}o{sjGUx+ijJKM-|`(N~1{zkd9sE z#;tilT(tPrn(l(Mq?&AadT;n4dz$bz6F-_PsU0Oox^%CYvUo-{l2wwq!xt*9P)VXiKy=||64x(T`g z8faI6LM<8uy;N8gW4S2%Wx<`hkzgUQ8LU!^&}vQOWbFu%JN=}zuxMR8DZO1sGxQQI z$5)YhzV4Jm(txA(h(Dv@0X&|ZPS#46RDI_Z=rEO5x$jOHz-#5PS$d+jO zCCSosYmOW_a`X*kA3#*I>!I#S3SOxjbM3@*06iyH33^dFn+6`44tH$-Mgml#I3bRM z&R9qUr*hO6hoV=C~bkN zU}axPGJGea{CUdHp}J{E25(Eb|9suSAJDo$IVdk;j`3N5#jrYyhsZrM~kf z-dOQE{&3-Zliq0a@mTrfFUCm!8o z7CyaJ+HY!gnE%eb>0aGsH~VARH#He)6>9uhs++y%CWVRR_Z-NjFs>lMGBg9E;F8b(w|JMijVw?of5 z+oU$^m*kF8(N z&e^b^tyT$(G5d<&o4Yv&dxOUP%q#wbcNg|IGPnKsxj1Xu&{T)gb%E=I9afl6!w2oC3pB)6 zXuSyY7mPCZYmXkl_Fe0!=x4e{zxOT{6oz8ri0Ef6x9$8duD$LhtbRB8(#hkmPr~uv zItzzv6n!hDb<)8&?GsPpbEh6<(!Wr{G4s?*a9-)lbI}*pN_tSeivLl`vP73ieaN*n zt5`e@S|{P)uYAJj_vGhJ#Zi|j4BsjG(%8k{+6qO}v!-Cvi<-T$GP3JMn_fiGu9t0k z5#w7sOKTun|L-jrP*?-!6xP6yu2xCMP!-S)tKTH+oOc7xJM#+s=iP-SJz(kyIOoi1 z7%J8nf%T?#;>l~TGpUzWzl*0HdkvF5_HC0s>yVAm`p(=!KfPwsQD2S2iYI?=(ifV( z+6NORML)>;rEl+pFwl8H8D{nwd<5%0Wh z((MHX-jBT%q_qF%cjoT0SNFr2$4^4P$28GJ8$F72m%XyTp(&zB7jmN2#YHXylP^!j z=x3nU-!@vy#dTc7Q;)xni68qG&ORji8STNFPQ~QQZomyML_Zvr);FUc zp5CkAYxL6p;CGk38kL`UJSO#ftl+aWuULpbq`cf1Eu9A7FW*c#qr{-2t0Lj)PlShyBErH zA6?t9)u(=iD?d~E68MUxc>d3C;gsLZHt8o{S%U-C9#En8nQzG&xI!t(q5$rAgo`J1 zV0&CK6Q>)sW>R~!Ku7r@pq{OhhP$6Q_~HqvuG#;$x3{C$!`Bm15W~$%9}mFq-z45Z zawb`M?MoeF#nq!_)JKQbQ7L#*zLk6Hltz^*YU|z$muUzYKu)<5;}1k0Od^9#w;a?YpJG^AHb;Yy{n4#Eti>MS+TAn?I@FJ-1J!>!_KV-d>eqe3u@lJk=JMR0?E?F zOE7%I(D>)tTSj8551(spe|_-Vc`_p9;I9~_K{iQhMj7!DXV9Q_wB z#?q3$&Hl2M8ZZ!T%i6IrHuYpD-7;x?jJJRHuXP{>x2?hI4vW0sCfItjp&X|Q+NPag zuBShHF~0MOPh#D@KV+zn`p~}EW^8{((XLy)^f~KecQx%kzrm1uwaS(Co?SKr6!S9~2mIert99)Jcz zGFwufv|pli>SziRtknRtwM9R(wRDvrcxCi5-||6)^-|Ee|CH#(({sO5CRk(m&bjKV z_}u@y2Zw%ZZoR;5&BOtmk*sw*76(CTK@O0=b7|A>l}=;&RB^ne)k>2^J|@BvCXXMn7(%Ov#Foh zco`n~>2L7f2cuZ}qzQ$FtyZ#vR8hN8t_jB-4^`!ln_z*~1Fca!xqc=1jV9Qj!G(Cu z4t^a-*E6mY5^4qPd@yCc!)V_`C|~V~#jRK^=+Dtgek8q}&#?t2NG%HB_s1M>Dc0dEk3zWL z=lVJgr1l$+Givmxq%`G7=V&mZ;aj+1VREdTPc3|oIJ-fu#?5k?yTTD}(S+!vs?b4_ zCB?p>difT8i17(A9@Q?{1q&Bq^r%tDk;KA6-;C(rR z1UD-)_9X}{@E|IPUy&d(U9FL}qM<>a&t6OSRJN^yB%jjIdPqs@@_jx?{uD^>GehJ7 z^3j0g(=&slY-RG5h$=6yOO6DC#V%Dc2yAm8No@#gP_`puO`!7AJQXjk2kJ4) zV)mOFfCfXdwW*N87-@Q^xiVTw{$5vPHngKGq&!g~<|=2sERoj2Hwj#uwakV1ymdB6 z#7;7$`EURJ1F&kxxMB7Co$#r z7R)-Q{Pn6gVx%o2$70;*F&Nq3QncS_b6IQbGQ4hm1*vttU9s2Dui>7D*Ei|6o}P-m zPaToY{B*p9n=XmIl(gokAK;*g@`G@_awXOj`lDadyXi>5mUTA9CaW*U6R$*%HMgD8 zFG*^JDypR=pzm7H+TxMjKl)P9PA7Z|(?9$M9{J~QO#1)6_zX_@`Dxf`81L-#vKMjH zw=cl6dqgj1oVD+|uwU(3`Sk6$XZ$Q&Fs>!OF3b0;U%(AlzlFWO_yLoQK6=%Hf#cRO z=`ruTjrpC0hsrIbIvw-z*1O{{d2FdcEB}kz?;VF(KNw$XX_;~KGS7=weH#}%y9d60 z*1jgaZhzYH!v9+PqiskuU)S6Ia2&DYmH6f3ZyR~XZ!#WF-El9*&H91iJf8HUYVC*q zg@2>g+uo!PJA6m{^;eH$-Z9b3TI;2KN23c7(wP4Xhi|8?;67={0FphSc?|-$3zyPTWG0;@ zNj=Qfp?o#NPcp-j9F25cEQPpb`oV*u>yo7%XxVfFtoQmuCjHpl9kAJJcj3uZ(aXsr z-h3NR-t`E^&D`Il2P#HS9hdU{{a54K=bkpHd%k!qep$3DE25W~7B0IRL)0FIrig2w zeH!Y? zXF26UCa%jIINeFp2fkGz3dCypIri$Ra@K^i!(8CSmD_MdN7|9^I-ivI0kWl$CR2kA zelLbJ19CJDu9%=0Cl{~t@4OV>{o}*f=o8T&GhB1rmRNS(mvF*G&n5W4;-?|U8m<-0 zSrl4VlIKGC1hd?p4GZll*86**JrFvAm{#saW z6#44zX7~n0S^sDqE)-V?TWaBu3=oB{T$6v*@Rk-BM^Af%>O$+&-qZrEB79wjfU8IE z!Q@LZH07Bi8|3|&qi@3(_Jtl*#B0)^k@IBb_Y}AX#>G54cq-DC|5eI$oSwd@MP*X$ zecskCJv02A{7#O0REBheyGe;qccm%WB@w}72InzTo22bD4v45uMM;@rSEpAEZXFjn)NJG zt_9gZP#fopowJ1Iv`~p0QYl0$RbzQfph#aCzJ`oh8jsRMkQ^viUK6w@T|fAm5UPnr z4O$D%KD2vl_XS~S+^E!w08Q%_b_DiPszK`_R%K_Ih6if51m~` z>-r{4FG4+=Ro$B5Rw2M2swhW&2(+OyT+%HBE{j5CyCz+Z96cAVRcv3=@Zn+x4S#$< z>q4LlwFo}<<&*8I$Ay4g`#3(5Yt<=qQJ#C+?`hqo&*Jq<#VtpJK$k8p1NbGaNqx!- zq;7VDZA+wkQ>l#BgQH9f@+96|jH(@1$v}qcN9nXs7f7~A!EK}^9?GFtzKnBJgM8lP zkV6g0kNC>ml0sCee2fT)z2jnkq$sATMPt9TRnD_Dv{D~H> z9ADRnQvIZSUwtWB@%el%&#tFDawuO)3kPqh&uWI)VH(L#yGcFdnk~(PSaa-V)r5d{ zbGxr}9Q@2xGRr}o9V$kx_?K4E&l*N|^+8?qx8}d%7I6cowQsFgWd{QE*8w>^?`ToE z_0H0Ic_d}Fu0wSxU+ZqEvjcTl_Px)M1~V_;+o(_fgnvmb`kTKo6UJld?0HzKw=(Gw zY7G{@y9fiuL|^|HSS0IsAFsU}{glnv@nhm_On(i*_IvMWl9zn%yLe&qPva-!N`F&W z{KYFvr`C;TV&_Gd;-=^JGwF|SJ{W7>jy|*h@ar36H~Y(1trM~HUZZjDZ=#>!TE5+h zIDJ@}3EhEtH(iY1tvb@^aKXV7nZvUpqAw-PpZgXDt-C)`iD)S7xm2(-L$=4E2mcCZ z|K#^3XX|eqhwZGNA?#SS0%#kU$y8I;onF4w+$|qC6oZGXhZ#qF)TE!f`KNe&Q73j9 z9{=KuUiOl?{{1^YG+)&^Yv1TgHEm^osiQAV%)a#jY`D+y7!wy5wYBiyMGsz$8;5=n zKiqOajG%R+8Rj~3!LM-Fs|Vtv8%00cwCIsr@bKEx@x`?whRYwk4G(NM3&)SOnJ>dj ze~*3-?}yJsU)7q_X1BH=ef1*Kee;(O#n=&DGpP8Jj*mR4vHtYZnpi#?w>_{SW*s*M zT}@bxMf0OCFAW(xBAS1?-K3v?HTlCfL*>^pH{#$*y zz%yDyLx#2C?Kj`W8mw>9{fqqO&Bfvo8=3Un&Q?s?en;r;>{VyW7G1K=|n*LyM7M4yZmRDRE7RShGM|mZ<^G*Yc$sDUtF$lne>~BM_{8N z3aw+KFWv3D_@}tBVAqQ_y@;Y+FWU6;wuu_P=)J{-H88x(1{c=BbHz2Ve)OeA_d2Lg zUnoY-s`uxcyX8a2VnorDDQ(2JKlccp)azk-Sy8+@KNGPZA`3`mtK%Xik{% zv6rWvjuC-(&Ro=%PP{bHrHM^7)NmUMTb9kAE2F&O$ft|mx7gv}3&%J-&7^Y;=Beb~&&r1mr!Oeb}h zXeD1Md1hKB`7kg#`uO|&tmLmj$~k`~%?9oYkG>o~J0Fna2VcOg0_Zb?B#8SBPO*o8 zX7)O&^q<%|RJCZVY9^^ZvJKDn6x9xEZj@ios@H2;b!&(2njei5%8T;F>JqIN0mP|! zR(RLPI;H&y#O{T(TWeBqn=vhvrEU_Pximj}g#Qd;gtkqmV)F|h!BfljHt7!xUXADf zaw@)gQ}hDOsI^C-b;&}sPCd?~&-lm`#NIk63257TmbvcHb_d>@H3Or#el>(!;Fz!O zgCBnHB$NE~z@b>aAY!upNngkAqiy0AOxSrZjQ+*1O=`kP(=a%V9qM=$H~;NEyz|Cm zCVA2ae-$5z{yXE0E6&31L*6&ZryhS3+wMO_c%iGAP;SLQY;nT*IODg`&n{eW!eLl5 zb{qz;US!hCCVmVTeD{Nxz)it2pTPb!BUG4N`;7utJbJmw``iy7#n5%uLhGV;OuA+I z=WuS~XC^h?|93Qgm)`pVS|2|d_y5EyZdn)q_~XaS?d?x&g}pyBJQ?$M&NcFH{oCW% z=0pF3bzAIBL*d_m=taYierY?L_q9*r_7VL|_M-Onam?2bg3|4#{-d|g##XaV!f>m) ze*fS2^`-Zk`xjat$H@=Gl*775{Ro$RFnYP?PhYtR_jiuP+QXvxzhK^StbfQk_}0w9 zM&9Co-;UW^?TwRc0a%8o{`eJhchLi#7`xW6!t?ccCcR>VLvYTiGccs4_$xy+EYR)} zQM)Bn7_{XH=I%SE{vH>de?0zzwG7kIEsOAO$7CG*`RHZ5>5qUnUw^>{^z6k<%lt8T^#Yl=11b(FVDmbu1 z*y4PX`r1kNV4ZaaV!@k{ec9m1)3JZ?H%HaxCSA7cMVnqk(XJP5dg0EbpZeozxaj`E z8dy8(k>Wa7zWyON`_$-V%b`kAtbTo>nT%ym|H<5b<-+^XId*Lf>x{;8-ii%y$T_EC z#*j!+z2IS7{;i*4-1%3T^yk;Q8$Uerk9cF~T1M;PdI9FEZE?)Gr_WbTxUbB5sA^fAI-rc z)-KG$Q>QJ#!PxgLDo_i*9AzKm1$Kf;uK zZfc39W0{fl!B1|F;X~t(A2p|(UDmG+gZss4%RhsP)&UqasI3x)3?eUM8M-n}ksR`v zNhdRO-)QG4hQ5f-`FERZc`Xk|>E*4$T0Zt`r}^i|L2Bn zaO5YC#I)D`ny62C0dAA8g!*9W*l8)=;jBSdUU+*Xxg1|GZAcqG`P`pmWnHed7OQ3J z!n^w{Wisnm@%Uu&$k^~RE%MeK50%@OKA^J&W zK7D9Ci3csG2&oImAyF;Pc)`Mj7(HqfawO3g`etFFjiY*b8;j#uL_W_cBnu}UQAl~| z;Ie1-7g=I-#E>VxwpC&#-b?a?JfFP=WFHm+NsiC|adfUx^!Z7NUeb~Csjg@Qq@Ihf z523W7?ad5|Bh%5?qeB`m&}0a4;59iQpU15ok3156 zonxDAw!zAkE6u+mR;^rxxo^#_(Cx4TIXBWvaPRj|!Hv_R7Z}dlcdXH_b5*-haq-es zXdN;F!`iC(;)eq|`g_x*OO~T$@NjcKsGHuB>U{I>=K7U$=Hi5(eGc0WY9=2Zogo#` zb&kZ60UgV+`2A(*91y)MF>F{HvKX~4_Ym(Fy=EyEEnaEnhmkihM4GB0TX9Oo(Xj%H z+oQQPaOkkY!%!tLb0YS0j9tvJV##7GT^+S^$cW)6H#tGd1X>--mtgU-)o2|Y_1Ex0 ztwd(ug3khS=NfwX1GwP0;==-kO@8_Vd~iJd98(9DFD|{Th`|^!e4xArI#!~+V1M+$ z=;a}9{%Uk$b$j%e#Ul0h@GpJ7S`4pv<;8i$J*vTX9(`GDxgJ!o z!H)T7`f3?e$sP=@$^UW2&@Qtf?c%HKb4#@8PkKhz_^Is#*J7?mq&l!@IetnggQKo3 zhnAPIfY`&RZYNeOj=pqRoQK6Z*ttBiSM4psFuagqr-zlk8p%fM%ih4mg zS`8n9{wtPX(duY^&p7dHoG@*e*gtUOQ)r=_J7ePNNaH8*msZDu()#Dd(5&SpOR!82 zG^ybQU(#aB)y2MEgheZqv897Y7VKSVvD;rQcPiqV95%R#5psYhO=PBCPk&Ytf7aSe z;AW}sG*znaI(c6uMGY_^5vuw$lNp4nxOWzk? zcmYF)M&~E0;J{m2TFlj?t$S0y;N&|yJI&RcnU(J6%$ZZ6Y4K{4qd`#QUXgp<71gmz zmDaI&xu#->K5eNOCwo=DUZ$i<6@RXzV;Xey)B?6MR<%u7hKfp)^Sq ztVt-XGcHnU4sfwZZ5nc;;}One*9H~4NHS`d!--ave|3|=iADCP{M;&+;af&qP9^>EaE99_NNsMS#;e4E*t&APqFBq2Gv9nC&nxkC)< zgzDq;prpu7h0bQiTPiqX1SQpV`28f8P}(j+)rjAYRnBCugJ%9!kGMgW_h^18y2`TJ zh|8funq63SaP80K)8I4$sxGWvW|puzrFu=mS9CUOKkW`rd(tT(1?x4(PU+!`M!8T= zLq40Kb)=@c>d||erx^aOuvBt^<@2?2f#!%HKht0dnJiAe4rdXoOZ$`diCv}~d_d}Q z{9Ss4uAs8%w*R1%rPD~R0pC8`xBs9qAXkS@8g7zy!@6v4WZfCmn$W?brxz}31jGkV zvI?OmzP4P7kd@Qhqt)g^Pw4T!GAn2dVCRMSC%SrdfDF!LbLDA{0({m(%Jb<`PILa7 z^6-J{JD2Q`*ny5!t@GAZzn_;PM}r_aPirbDKz7uW2c6E@1rS^y8nSJc@;FU7jk(xR zLk_UHO^IX#X`S-Dq_-08;oyyc@{sV$RX<1l&=>kRpGSQW-s1%D7K-yTcD?koNx?0S zd-=-FOZ>uIDUZ@6nACS_fkIh(XCcNdRJB(_-tjV&Je*80aD~ z1$;^CpkWv_h|28!sM*?eylgK2yzmdW@45fr)g7XrmHYVGEzG{CFh;|puWJnS@ojCx zFvh^e^=(1_p(D-RXg6VjbRdR}9vCm|c**Ep#J$fwiPxr|f)m#6o>8Y?tTtDfI+4>d zU`S!T!;OMnA2Oo9$gXwZaEux#$!mPSXjf)S!JdwC+0zyb8cu)YvK4Km`Qmk*#l9+i zrL1;@_8%9g)fkh|ZF2VvWd+inm)m1-s)n9vNcAPzwp_}?ch)1HLq&5iHll?!R=f@` z%NQ7axpX+(=RbPzB<%k2bFtgUqc25ttXzpTEdwy1e+!Z6A8M+vM3-jYrvw@;(8ED1 zjamGBt+1Adjl=*Xr+7J|_?65tr4T6g60E)F3YjEnmY+1iB^vF>>qV%oN%b;VboOzx zT?=)jeYJ}xg>=x#@p4%^&RXTj(S_bVE4Ub>bNwp<&D;0&acFKr~GkqaHs9JL`2D|7TN z_(D7>q_pe1c-O90<(4t_Cf_bay{PO08{BBqgO%?0?3KBhnJR&dRPxrh z&Vm^VNiLGk6s395kgsi&MUrc#U{4rO>p)ed0xVUi3S2C&7#=>m<`f)EmdsHpa?31q zkifK@Q}sZd!0ln1L9Z%69atGPH>G>}Cd6#Dti1=m@-6gDsG*qlsc)OxY3MF+(V|Kg zNpmw(>B4JTRmoF9S@9wjOz*6nQeWfWYh996#0U*^yA4IA)~#h7bD4hF5!j&RWNfs- zS|&X(!;aH66Hr9T>6Ud1dVk2=Z_x7Dg6?ArdNnVM#X{H>suc9LX+oomaTdf4DOZn;*BYag7of9k>VqkmXDKd}ZakB27!%K=Z;O zZG&$Xaebu%^sxI>s?UYw(#)p_>Fbaao&;a!9JBH=tR{RdChSio(tEDKR4G~p2M>w1 z7ohp#D9$iaYrw4zj)vpMSr%Is&G+%5dfIdvy>{X>Il9q}=3qd5p^wIfwBlTO98ceB zl;RcY1AYEb;;XADlPnCiF0R->iqBkpIXYk6Q24eC`O8|}4mw1fLoPuB{1O59u)mrq zW6O?13Sc>7q8#)bUsssG#hf~@oQp}7kYA?fdM@n(m5d3PIWf+;pI}IXq`BD4u0Znuew}p>*f~;KbG50aQWd-6 zw5nt><0VtFPD7J!lyE7P!dFDoacY6|a^#RI2P$d;)l=P(o*YF5#-f1TU%O zsc!Y3&4jE?O@*HtXztgVyd~B`wn(LOij9}9Y=qkidT(L!*0M?)3HssyDMei;uowXd2YluCs`cvlQ2P2zMet`BT1vmruwG=^j_xT;(*p z)l3~A-e%f2(q5Wn(n=^poM}wCZ$P<8QVmUx?nXW$%>l*SyH+Z#Bdu;g zUe#dgb9%W}c8IlrhbGj|Q+mMfg1DH9i#vi{nN>!4Qhu)ft`#lF(M_P8$x@n`&3=#z|1tKdGL?hc47Ki8kwT)QZAy@y%y49#aNS%f&}nv9!kH(K-L%+aHvGNK9Nl8h4> zN6y^`OYmp$Br2Kdts49U*P@*m)s9gni^w(tQaSM{}wt?h{2%Ys(%RKk`33cJ{w=cs^k!(O8M*|igl<_PTN;1!WYEZ zG$Fwv7+Txk`RZ|j9!KNah6Bkiw0ToKe1WCQ1}H`+&S!CTG||b|Zl5ip?W@!53{#>k z-6#~&v#zaH_rZ*j68bV#2TPF;A@OIWge8|zK_N)9+EuW=q*Yg0sDFDZyd{I!fQ6@o zJlmUb{lMjG@H;I@4y#DOa@9@-sVfo|RoV;Xs_E9P^6&sTfcu-4DvXo1{?|3K&5k7$+qdXiASmyp3&NC)tC9=)$4LPYw`=C#0!a~Vpg zlcu@cnGe^U+EdR3+7?M)dv9jbyV}i_x%86Gv$*jHIlr^>T>eQaP3lW?C-wiK`88=#U1| z+|Pdov0;#=N$8SM773kZX`EpQU7VlfhNX0w11;xbJ~+}+h+$tPI_;66gnJ1-TFMUy z3wJ1;%ShNXdFYcPNA>92>qqh(l3$`n4RwSdhJG>2kSHYn+LxpAiIajvR}ay0o6Z*` z`*d*yw*Vg$yUto@T`G^0Z(nJ9DIZrJ&F6S=WwcI6jKS%gDY&q!l3$*98t(Xvjxd<} z#(`>T(1-wo5nP){GHX<_wC=EegP;*Vci4zFsq%kZMh;dPP#49hZID(Pg$l?^r7m@k z)gWN22kj72qimV8n=$uu9QA=@LwgWx^_5UoHSE<;zy8U8_OMw&A|Ecau!^1O8lbF6 zUdz{|*h(stnt4?$Sib7|Z)%-Y)$do?x@R>Wb#S?vqfzFh9&%E7B5pJ0ghKJRTchnAaKoRhTkYeCl`mZUv5kzI>hfnS(uCb&x<--d}A4=J4BXno+? z2Xar_4u`I^9%qzu*K(Bpg?X4;=-Y);Eu(AXy`+XGkC#vT5MzNxFnaMRwmyeJ<6_1kQk^l*zuZ zRW1i}-+f>=Lp7=9njuLtb5UJc)yo7b{Y)Crke;>-kZO?RMzl-$+<^_wFlM0xiZ&(4SM<@ood+dm1m3wvDX3R+)U)6 zSIIO`S5D>F`*kpUr98#R;K0ey0#7Onjyiy>AIH;mhQ#d$X-Ewu!y&2NG@=5MW;`^s z;`*5zZ%J2kZyjUUFJIX&WYKa;Ya{l>E!V`d)AZ__V7=7*W)n+stFTr+lqa>%uGJL+ zZg9CgmtV-y%;=>{w#R|<8PZDPRvTU6E?+8H4qE1#8$No;;z%^Ex}5Li`her%Yma7R zl+#i@Zd{~zgyS6wDP}4ne_5*`kcL$XL8W>i_gMu4Jfw-s83-xx<~A8V7w=k#5;$2d zqa@w?;?odgX3GZrhERF(l!rD)V~__qIeI2+>!pM;JMH3O(^MOhFi2x?i33UeWf|mv z%+(W;Iy8`W1`E6)`T*yRY+(U+gbZ_)Ni_3bh#qVdU*?o|NK`bIw%oS~YPsa!J; zOn!#zCnaKiS3L9!SrlHVpkn)l%50!w%o@_8rJpy{x^Z98YQ$_&wy-jM#;8t8g^I1V zUpRX!*)FznY7&=q41`YHBoLR7R-S`z_n4}l3)ecTVG6{-dBGazSdMN)NDQIk#dThn z@vuk9M5(#TNjEid_Ng3zie18CeMhX8{?6ElHY^4XKnC6|wY;X2p+kyYdxORz76a+7 zylz42b=*WgPTJh|NYKXE*Ydq|U{eFA>nmTSLx2YNv$R)G0v)9V{8QX_9wg;Uyui>& zb*YRHT1ln`KSMxd_|BQ6HgMBH@`b*W7%j;1jiba{8uJkS?C`+#2Qi^xgpxXtDoFFC zJjJ9NxCVO`0tYFGk8hT8tHCuhDL-kp0=P5 zewT(-aPX685s=TtMB2f_HO|_Trv>>T2#KGl9LaCneO}J1hZW3U)~Y+G6XSLxQauSF zA!6+a*(h-Lc3Oj97V>{C$NJV< z;;dcyUfP`5mYLQoBcooF9E@xKCq#p~MDOyBDj=U>&5CwG^3v2F__ovva_`gb(U7}M zN=x0&(YXAa&ma5hasE^qeu-D+;5w&Lrn(eR`V_eHHbSzE81L_pdN;B209(58j7B2!iN7#^NP$Ng1!MN%dZDUd^c9nL!t^e?^Z z2hm#fEN~lKyR4?BDTY}#3pWvR5w;5#E<}z-!gE59V)&~cI~CWWrm2?Rc`GiJN{6VE zRF@M^S+{goL%U;DyYUU!X1A)`Szj&S=Df>Q^5A?@T+6`lpkYYwud~sdwJ~1S>14ak zY^8lZKWfQD<&VGwJ{+?5iPWHT>9R&mFymaETZM{wj8Q-I$-b4AlQeHr&e;VE`tp2@ zckTjlen~;9FL;dxq8Phr&pm~7CJM;soeLK(V5H0EraC}YH3&Hl2$3bxczt33Lgklv z(@~bjgx2Bu+eME6IX-#?x7YR2+Vnozlt-GC;)+c)xi8v&pUG2#%#gW3>A1e*=e3az-xRG~(o zs1>fh=@wKJD#c_<8d+}bG~SC#^Ig%xs=3O=*;)9;```cEg&Qd1Ly9KI|VlbSV3CE%v?i(=K+O zRA@@s+)ukCe(Kt)142jTa`kQ6m<-ErRq`R5#0Hzl8W3sOzO>z3hYlH^uFj*wkHcn8zU|s z;KM{aErA|jR&zMa=>vvm2rr+GO@^hV{ojxw%{{k^`_!SC=}0FTS1wIfX;PPc=+Hp= z=J&H*F+uM@ceiK$d+#Ajv>-?N^o}ltW%BxD0bz9yLLw%C=?eYWUg|3Jv(GmXU;H zFwl@ypDn1v&0-FTf*RXb+{;&91fI4|w9&H^faoC!yb*V~B0|VNu zK$mxbs`g0GvyBFgQjRpB=DQ4P6zmOf#g8QFnyx3A@LTe24NLikI0zFq^72l#v0MZ?i@X*$YM9KwO} zv3bxoaHE?2Nax7WH_^M-QK%KOtq--3+)k@by+#ci=N35^tCIQ3!CtbhoL%Mij@%y5 z#Y+e9(E()=xDn=jA?J5!9nK%ak#E;`#Rh=v_awf)GGD)B2C3svzISl zs#OS?m8f(0EhxrPMd86nL+B5Qf6p=&Cx9}$?luL}LW*B{2z(p4nw!IU^z5y#Ni%HAFJaLavV!K9O7gb(Noh$3`jQsqE$QHj zcWBJSRBu8s(Ix$BhME;ua+VUcaPvr|Q!PI;ptwuAy5&@c6CjvXA^=kG?>Okak2!bc zWYT)pPZ3pqL(Zbh$nm6&5kkavhi3_~ZvkA;5a^KERA*i2Mn07|?Z`{btTB)}TyR>P zC7@-LMUEze9ZcExiGvj@zg)=v=BZtY&T%dvZNhbsqlckqTbJB6Rsqh1y3CD6GR$=G z@|C3tSLwEy#ufCQtMAgmN0*};!A&|HK=0boYK9LdBcBj`1zG!${AI1GL9IL>dnUTT zHIv63v=Ckjjyl$Gu;xfOw$h%goEKt~ee$?y zKnL>Ucv4-st^tt+$Xk>&ep`F$aCK>YyZsV;d+xfx6?}-%krewi4s=}XYcf%-1czXi zRf|>Pwh=w4D&rf?%J_rWY{#>)GlN+-bn!_Bs*Z|s^VPm@WFH0Fm0Fe3?5!Xujb%(h zmw^GT?cs82X(UZ2Y7c-E5Kx+$nxq&3)lXRMNgIg@>`PM8i(RxX&6mE~R>@Ml4)&GS zllIwQ@HmbUqnU(V8u=o%5a-w@Gc3pw^;Yvn&dHIZq@`lMO5J(aI-gln!!23-R*5N;xH zlb)7YP(rcYV#)XAXcANgiUd>i)1+kwSjo4IiOnpLNs!No962cR6_FA?6H}&<&Q>LU zoKy2{>Lh-ldvLDY6P9t3 zJgdPIIi6((h0sEuAiM&l7AK&QKFb_S5HaIX*rc4MA1K=#s{F zNTI*Ww}kMA#fK}S?a)HGhCAw!_QD~v6%M|2higNwID(Yxpw3XinN@L0kf=b?v@%r# zx-@nUUKvK^)T<_W=su`Wf(9um*$6J?u7!U!I@Ar8Ft=Ro$*!l?{+&*&Z|mNH($2F7 zLJ9XYHma&WrRbr$0SfJ9`V}l6E&K5YAo+X}VJ3;r2v?j`d#^MjR5GdgqD*DLo0Xb} zt6t=qt7(vm-PYPA^|C$*%a#b1Rabt(OLA9^Ye;M(?-#qinpOCJ>}|`g{1}@Wpab)& zVb*ZJPi5QouWDOgKTz8oPg8%~U{o!Z-OM#Fl&4IX)4mnnl!G5v*C(Sc zkOqX7c_(ILytvpeuE~&!vl5H4dzmU?q#Dy@T@uUZ+2x!%%ddGzvXsXK`gXoANX-Ds zlV7V?pB;4NIZ=xt(qS|rSw@DiRyLLT4VlcYU0x4^FMg@1S*~b=di!h;J3nyD1@^03 zg2|1&lj4wDrs3iWQ4fZP4y@Z;P<+xizp9m?+!Q*5ha=0UgGya5UZ38kW1(th5hMo0 z-EtGN^6;M4qJ*w{7rHdi;@+_&vm88SXj1AKA5rVqXb++-1;S->d-D2f?*D>TgMBc! z@lMSENcLS1h#@@gn|gdo(sTS-jyTFeP-&A&U)17W+A?V%`KeKt%_x`EH%`ovBS$X> z_0u8278jI-m>%0~(Qw3ds7z(syd<3{ynIN|Y2edLkQ}`c zS&wr5vQ|xy7AI$|>Eh?|6jP_F9e&Ml`AphskTmBrT|L5?O{q6^pq|q4z9d(w?>iph zbmK-vi+jHc|ku7>hxTI2)bCwXKT*1#XBdf%@K0BW?h+yagz_IYzY%Qq8`2?xw zT)hv0Kc(lQ3ovqA`&~(nL~qkl_@WzWzsp5DwhYNXgVD9_u$8j^I#o%%)%{*t)TV0H zxW#Fq)Fs(K#V(D25mow>mTJHoVl|kr`pDxJB(=GAUY)?j*Y)ln&R(WMKxG}GfRj$k zBC;5hpvLYFjU-UWn4t%9NyMCDlk|-rzVOsH(<(;qKuQ{ z^Piz6PBDDAdYl=y+icTuR}flTe@S1dUpa8*K1XvQce%X-J$rqHScp&>8=SRLo;oQY zsiYlhKqyNY|N5S3Nwywfy)b*vL3`+Yds1#6C~YM;-yw}2w`bIza>_>Mp+FhRt zG%sYG*P;Tg8!9sfPbKZsAV{D?i0{EmB8%r0*6uK>%9N_AL(`(}0_qPbw5og4((N)e zsjEG-X~QHkNam#2+i;ZPf{dJJdN!pNTED~DXg{7<3_wX2 zZWoXsf_!S##klxdR{3=}9gAVLB} zS={+i2z&?IzPcf_p@-c-(nQ+yDxf~6AH6mReKQ{5f~k;vj)sfNrIU^FHDr?I$l*o{ za#R6&fWa+5*P)muJft96p!VX;6{fksg(o?RpB zE`M(EPqC!<8AJ3;5NNDiv;a$1YV*&bb5PZ8It+yd+q&mVmUSsV z_LIWaHNbS|=xL}NGccp71wWA3zm@Z)jUIQO&!QZ)AfG=r^vWezuxJH33-_JqW#IO% zw5(iSHdFK;w?*X+t$owVrHkz#HKP;2A1{F6Ny7_YAf;30*9jr2_D*n5M7Rl|J$1Nz zsh)Pw+^YtXtM~)nEa25+pUZ{1Ye5JI+Ck2FqNAW&{PfGDF z+smoo>nXZl<9rTB>(h_(VK$vK^3>P3A`Z##Q=Pc9g5SS#{uF}zDu=W-_y$)|A};c1 ztk;%e9(JOnf|7GGYEtnl4wW-!U7vnZHI(*5P}`HLqHj^sJbM!W$VSSc47XA!xzvuD zrZ?g3vVlQNI3rAo>kUyxL4o4OP_&=2KDxR#Lz#k3$VT;i#^9VTT@X^(mKt0{5W-YB zIZ_on7QSH0?!WyW%zo`XtZW@_(i5gk$I&x@YySD9NiSwa4Z~Ik9%gR0AKOx3xEycX zcSFRlb!Qy8(|AkxLOgN(^_aboX+zs4*ykfNu}*6#z2<#9fB$W`clK*0`QFNY7{1OF zeCC+_OnTnK*WjMcopJb#h<|ITb@Ly;&fML(dIk>LaXeblD5x3?ypwCW9Ij*2QMicQVPX#t&rvvQr@>%b+lh5B>C0xOcZdn&g?g42oB)s(p%0re~F` zSaV2~Qo1hP&<~+hp0k$=it_EdR+g+!ct0M$maXw!_)hlbkVLn(YX~4I&_*zkD-&lV-D`U@;1D*)~=@ZQF~6t z04&GzxBkr(-}h$uk!;lRp<5h)!>6xZSVJ8qcfm8a;l?|k!n-XKOnRHW55VqIMwHfA zVFVZc2miQz1$I1qN0T#7__J!gY_6ey{O*6_vFGPvksfIBM~+<|TkNzeW=xK3Z%eG@ z2pp7JM$BDTFMk8~-Ecqp?fhYro-sb&z>Wpa;PxBuz*Fx=`Qx{pg#&k+g5edij!GXE zQS8V6&)#Ac&xd z3J8*O4#yGh$oaS&xO}^}w|Bc!|LN-Knd+KXp=Ww#XZQN2+;mmFdiAR6)qAh1d%OKH z%=DLU#+4QPgR$f9_ux-mHHq}e(DP%`-Qz3Ic}@#vGU;G+$G2m0;4FOE8V5(d^} z7GK&vu6Xq+JTdPbkzC$bh2Fc&z>!DJ66v9J-um5+wQoHx()U0423BwHf#FjQ5$U7$ z*#$i^V-s4^&CA8_t4}?NdG9PoV^uGa-ety-IC9o7)MpJ`n)jQJ;l8K*@f5r#AA+Oy z-9@B5-hAsKJafn0B0cYu28=!YL>w{J=a>A|e=)FZnzGj!=MdQO;5wTRglxOWW4UW> zySh`OBEeg+;p6$@^5xeTVpStYeZLVRJ%0LB?AEV_=(XQ|^U~*V-}7Ct&xyYN4vyhdOi8jRhmxqRySTgN#t>$>o4vK4@r}K~Cyg zN5?d@B|@p=@VF4~@~|DU1T>VA0Wcnn%Je!VRj(5yh>j%2HbS?!Y~F?P0Jg;{2hC9y zw$6jNL+4M`JQrVO%Cohhlf`y$#z6aE^%!4`D>%X_BZ62G-Gx;2uP90^cObzMP zu9@1?&AMD}l27H$LHiDVg>_wq6lv68gv8b`4Dd^N)s{ykbU;|cRY_?1XX5r}yUO=5tWo{?Y z!*Qlq1X`;A8m(lmV_=tq9Mgi8(-o>UY&UOGJh;D!7fZ{Fx@d4Cn~DUAiIRmON9-fx_7ohbrsX_Ao(o#J$dv zH*1lQce1KCQ1fJ{`P{&lS@K<{x-gZHd*b42)V;mzD|P0N>Xqtasd8IdEpsuQwwY7u zO=VOc)bTO-c!vBqBZ`a(5|j!%LP(*m)yjr#=R;W`ZsA2)*AiJA%FxOAvKWBb{c%H? z1+v{$^VMc4AEVlA4t>|udOCh`8bn(4E4o>wd=Gcvt=47GYnI7ZslRIbHlNxq>ygs3O zHQ5ZACTibYXek>U8AUU2tjI0244JoQak9*{8TH+{KR-=`S5P7*(tReS)`*v@FBZ*I$9ZzpzpyH}AbWPM#&bSu3>>Z$Ef1-rxHx zLV&}D=U$V-YWkthdmBj0$0B{tCFkQ`se^FJ(Fcn3q}pbzS-21nf8@Ub=a3P-@cOw| zqsPdLMEZz9Rp9HN#hA!xML5|Q{jRn>6Yta}y#3I<_;By9iR9tKQrNiY zdHms9{}Jf}Fa0%6A6=WrGO`p>Kcll?%q7<~7c&awn_rKi=jfT(^{Mkk>W|yb#4k_in_dUY1ohhw-GjSUzl{2+ zlSKJRBdRmCd|un$x(_$r_5ePaG*YBLeef=*Nv+454?Q91md`pJdx_U^`J+|LdBA~QkUI*7&lPOiyqS@w*$y8ep4WA2L0 z*lYI_M0%FjK~IO9UK8mX&i_Ara^#nA{NcXP@7#GgezNTQ`0W|~n{k@b;~0#g2X7pM zG4yc8=q~6vXe357@Q^^;-t*rK^{4qgamYz1Iry3<#P2m%zlvQyeK_Xy@#p8w+pffU zOTUY&zvAmx*QJl)mWS42(xHco^z?2`c=zsWaNb8gpR2w*8?|r!4L|yw?@N#W`ia=D zZZ)2~;U^;f%cje5$&mvUQ`Uy1kNrbjJ+yWr4n2H2x;4Ek(sy5T9zMd=_}=UuBE2om z`}{QTBi&z)b$tQvMpDL^v{m$j}LGE6J8qe9g+UZ(Q9$X<$uAv^S&*{c2>6v zF`^v?E*mV}MoL=9*=wncOTPhK&}Qh>jcSl?+7w0u-|_+O`@^5`Z2ev$edu0eF|9`x zHm`VFv~~Zl|BbDOd>h|B)PK`ft!RE5mOXR5NMG^y7qGH%FYNwl{hPJ6eS8=Gbe;d^ z)3^5+j?<19?ekG+JpAd}|7K~j?Uex`dv?T^bN1{%zs7~jzmLmK-`$soufjvWx)_h_ z{6&%epHKC`!n=NtpRE19NdM-{J<29?JfMUP+y56lwHw;!hV zX;8{KnT=$cJZ_;?51Iivzzx&Lw6MMn~T4 zsD6;z5bFFerMNn!N|2yIHRl?NR)6{$1u{@~Jw%XriHD8o#nZ zyRmlJm;t4>lIk+xrow`_Yf573mi#uYxQB|0y>bcL3hdY@YwsxIWTMp>H){Kmz6idA zNyW#-s<};tTnXFT8ZL9Ct359({^#vks5%+ zkbxRIW=RLNvtp!{;r`#>jJ8vMBl0deZdmq!$t$0>kN-P!|D7|rZTMixzwkJpF8J(! zz;4;k4|>=*_d(1X_ywGMs{g5*ixv|SR@GzFUxan`${OJpY%!dss=20zWB8&Fnu5H4(4d0J8 zVC1BIMQXosUVrz;=vM#Xt)D;n0Z!h1TzWqJhub!P{1TpfX(2W?j1=h^`^~`4J#u5j zw|#;)pLrHF7+In7x`^? z!fmYH3A@kQ8z_R!a(g9o+bxK;JpHro-!$2*{8 zX1zrGtGn%lAp^RJ>$>J47~G>v=Bst-0jnN~{r7Ic<4=Ap%0K(|S|HDco?|Fecu4?GwL_ER-#E8ckMVR1G1^lNea%wFl1_7Le|+dsfJ?wp6? z&hc$hy;wfE~kC!APgA3fP2*w0344(=rAEt}fjv7N*B(DJXU~Rh7xwI> zpU!IOr_x$oHc=>{U3MX+PPrc*Vv9&sXWRQ zQ3ucJp{dSPt+K*a@ATkURVw3BMud6(C6kSbsB zI-o1D7`w!Ranr5gqIfIuQJxZ&XKqT+HK+C}9wx&@ZJ`Kqo6U>@o%aj!ieg$Ycs!HI zG%kSbJU5~@*`wtMTHavD6?px4`QTqk$v|;h1 zSK}X>#tHg{-lH*l>}c%bKZ}J8bAOL>uHTey<3N!f+M2%c`s4rN_3!^&q|e;5TZAEG zp&z28eXT^^n$}1o=S!bP43$wqe2kqd=Qx$GEiPT z*}wV!*n3lO_{kga%##wEl=rZff27`L?T7eaeKmRv@*fu(*gd_Dcq_JS^&fVuZ>Y=Y zp8s#dz`hQv9 zTk;6*{BUoP`uz8Ll`V!3!dRcS& ze~5plc^~ol-7{i!#rR_m!_$AhNTe@nOQB}M>G)>v_8G+;1I(E8^B6*(ILv+~k>%5< z;8Y-~{zk+0ckU6tch{bTi)VGmqB}1Z>EFH7A5+t+^wy)xMf!ltFU4Uej>fr<`)?LJ zdGrKy?Kv~OF8wzN@-+{Dd{~ul6+iF%^BTOh-*<4{&^tu>4)sAS-YjU|-p_v%oJV&@ z*&o(Q+p{ehdsg3|*t3Bc-0(3Lt@i!Fj5Q0fWS8j}AuVFoV;Ah!+wb3pD^r-YOBtRn zjSa-y+3bI%qir!B`JMmAA0LjJj)V4_f`N4lMEalSKZ+H!qu1h|2{SNb zL@hc!s6DCf(3>fADy=Q8wg;Hcn_S{x7d@m7!R2dRpQ#%HMeo^*!;ayxsdEhmv*JOa z0a4Bk?a6#O%u1RdK{RxhcTdIy)v8lgUT2l%a&DpJ%6~v97PETZtMhv@WRs@m$!Q8E zAEY}JNvtupE;B>OMZd`2}%Q<4QPLuqITv`PqivGUM|+G z05D5))CP+BEzuS8jkPGK0C%vAm1Oh*Fb9s=$mT+BL#lh~hxIdYAZN+QiG7_1MOeMaovg zI2X>0$h3+dB{+%&g)lZKcI-N@Ogy!|4E3DXsltyzS3#4OZ5e6TbkVJz%xwtW76ujn zmmMajr6TljmQsn@*u-EC)sxCnfjSi}4;XRfLp%qOO-T7DybTk$=Gvtmr!uK)cMjzP zFS6W7;Oe0&0E(LAJ+M;hX=+zPm_Q3vg+re+1oHO5BFPmWD*Fx@QBR~|LMIE=6YQu+ z6gh8S&owlF{$PgMOqzI^wh?L|X^pFux^mm5Z3HLkazX|h4^@s5ncf{kQ>h?HRTfnl z)k$OuAEv2C-AST&CP+{mk~eD!P#!^dO3I=4Dl({3Rg=|@e_>NThcYpg4>i%dwBwSm z1GBUPLQWmHr47pGt20dbV`h-WBon0xJB9=8_}CF#ZxUX#2h_ljDhKqt9F>MS@U>aa zBB0w`QBFm-IZX-sss zN5`{haHlL9X#q1|LX6sk$|ggjv0n_%LKQYX_6DpJC2mXR;ivj1CQWT-r(EY$MScrbfB2TTeq;MKtoi5} z-2Pw>K{4lNI|Hc|c=&HGiuA;E!UDHu2WF_FCEz1jHMpFe|X zfiBD%j?J&Vj3u(h@D?mr0sQ)$4HD)Znv+`(a9tU*OCC zct)g;`soqqZyRG)RB?IXx&iSr8Nviq5FVpgrA9?qWghxTU!=eW?1e)IpDU7&zy4W_ zol=YSa~~1u6|>L8n67syJbGfpq?BOt#y$7qqwSyI?fJew4?E*0xZs$P*nQ%zqLu3( zxE~+vaRdf$Unt5S`}gBmzU_d_M@AK)2&C4o!m7SQF-Wqtyy-nW`d|MuQ{D?(Snr8A z>Zl1KZGHh#{4-EcbLoJvVfV~u0k6Lw4}35NhY#`Jr1kNmx8boB+wob}AkyAAUjM)Y z=`lQ9q`h$r#?V7ss39-lYQ}>9-ixZEeE;1Z{q6Dix0;+XADD^`8-pSqw&!6#^2L4hY1=F9$oqUjBL*y zNZYeLaQNWuBK`4W|Hfm>x8a6e{Frsq$6J8x_jTyj&?GKbHg&YUOGQOj@ge1J z2&SC!HJs$VY7_o`q5H!B!QJm}#)%`6@4-TMBbhoVR_Ww?Rpo>Fx_s)O8gM_HR`aOC zcEJ7c8%iCS25{?#iDv=mq^nYa?vzlcfVP7axxNk74P1f*1wlNlwSL`t!~)gW=nNd7 zKbSD-IaS7>zmsSJMH5B#C~!TEG#Thj{q^hCMQC4VZgCNcuffy*eMMZ3I$#uDzT*k3n&3YSFtExHujUN|VuV9` z5jg2m0(>hL&hsBedHACm^cXl6|L^jz3d+fY(>JEJFT=+lej=*Q{oS|la&>M@x2|nL z|8bj;s`Ec{v}(j27%4vxQ9T$VMs&fFP=nPNJ#mb<>drDErB;ZG#Y;zE>JC>2R z`^eE4xOfq~o71b>fd15b?JY^@A==p36Ji3Ar6^ywkZGp zwtwL7zq}Z2{l*J94xTm*{nz*QA6RsNu(ewhTU(W0vwixA%a&!&;O6_QvG);~hqbEZ zUYCCK3vHol@Eq}b&iA+BAGchFpSJZA>G20o!}NaZ@!yp`-KXZ9lODrcaLX_K@owuk z4hK*7$IwF$<&SVuYo5Y?o*#qbt}gVmw#CDHnC`Y;{83!5IsQWYU~KpS;;Mm%;fL28 zD6U%?Kf$|?-GIx_`-e#X<*L)LdBOGg>A(DkSHJS-e`8|HOSt8#pNRCOT`tB2M+_tS zv8eF>jhsA6IdZ2kH zC@XZfA@B3JnLO1Oa@(rZZKB+H~62-u5;kc8|UMu8`lakkNx2nFet5%+w*8%6~7+cvFG_T9=4->P&GudXMg`C zewqsG*>p_rpSzb(-L)ERt*zmQb$JTg+x#G>rfX;1@pr&JRr?SB4IdN)pT2_C)zzYP zTdSpVCq1>H&Ro=drnz>lBbTYP@-HLusX9#h<;dG&<<)VyWnsEmrM3&AEo#qix-nHC z+B^0xA8eDVrfo_X&`>cnrIayESb_w|Jgn8ddv_$Ld^9#SCUcdbq-bnvLicWk{B?lo z5Xj|@8MEZ+q92tW8akIiSx4*VH;J+7PLy??AY9m(ppUjG1?*F}oz$ zrl7I0QIK>?Y-xgaK~!4_L|Y85(AX~B{w40_cQojxHWC9%X;Hj6a-TCq(XK78yR7H| zh}3q`40QYP0$6nPC1P{mg>eEZIev(Q52!vY z_kb4n|4$4;k7@p!-zHrD2W@y$smW^+?3@4^o;8V3dgRNXH;iE&-ypyN3Dg!+40(qY}6c1|g z+;0%OaF=s)HP0OlnK%74HnpK@^e7Bl;=k$d)s<7Q`=Y1t=C;iu-D~M;yz%tQ7&z-N zk+#3+j$`8scjBJ+-xeZ1_x-crtqk7mKk&4n`5AO$`(wikcZu{p@4b!ZzUR}3upmvh zVaqf4>Nh_Ygc+=NkUpu`RV7 zrtqQYp`oD;%v8CkKI!@wllpY@?U6f76U;2MR6Rtb>7?sDffM4M{p2%<2@)iT2~^Z1 zgBxh58#q*yqoY;Zk$+upG3suvm>fAH+M;CX03ni2bd`ph9#a_=%mex%4ronNM9CRp zh?6iXLHoh9uuOK-RKE}~y~)#UdSS^=K*O}@w^p)H6g>z2#IwAc#3&g0?v_VkD0dT? z0iX|M9MM^p2W1utiI(h!Mde;zn4(v6EeXN>5vRuN#5P{^+p!oams`j32}3!i(Ax=& zxQ;O*)5VQt3;J|{ZdrxsFsRf~$;re*KY7=&K-nZI$tYY9s_M#s<@?b7X=^;96OgGy%vz0WOQkfAG9p|n8i(81GDn^r3L)d+G=Y@^ z=3d05e}hY=l;kXJ4D*^8$96&lC!co{U)eikAJn4Cxn;khJH)LV822BYG^|c`4DEx& z92N-m-c6J(h3*~@C-|AR(=L-|I)dPuJheU*>e=pTfv7{tzz7;!`w0~26i5D*%Rtal zH%4>{?xG|Kb`-?zLz0KJ5+q3A2r5$2ZSJUYwTw!uQ4QDdqoN$H;V;uMjjR+XIk={d zE;8#tVLvq_wkdX@HSPUPH`eGAEPEiEAVI|M0SX!cd7Ti({v0$y879y*m|m9u(GIrb=V`Iif?#x3K{!)cRuf;a9$ zsR;c?M3t zrV)=jIrC!lwRhQNSIn5o|OSV0B(&TbKH8F1q2a6pp!Q3<7J}rU;l9j&_@Z<4?E+=l}k% zBE9>0pT+b6wRtX1m+C0sE&l7v9{bCGkvirgj3Mt>_~R(X@Zvp0jz5m+IoUKAhF*CLiIa ztGb|}do5Ni|3uVj!$?%6f16e=6UCc)?F{dG2&wh&iS!E})L`%FL$G1pR*~-Bucz;K zd80_b_wrl7h#Bc2@<+<&y&A1)z8<;?-pjG6=guPCZAUerB?ooD!rVwjo)rAcZ_x@> zvUq`jJhdM0J^z8YteG?&qq=ddfA0m6{-9iPrSdbAsWWFj7iWjvB<(fR3gQVJ_BF-E=57m|BhM`^u4UcR=W{}Sev=pc* za#0PrKGlB2gZm_ON>E3>uqcrhF zxF{C6Ab!N!luOuP@LL7Ar1+tllORtGcU%sls60)G!yLrO2W4>N{L+tPoTe?x3p66V zY{MX->jPUBHd=C+s!(BhWT*;NCfMTH*c<664%D=d)2vBWhq0giDZc-=-;3mxUpg7B zeFvbvb)!f(4?P3FyyRF6kNtB>`a1)4W6u;uUHMS4JeD>gO{#jSt) zp-8`U^9@*f#E+b`{?fn9#l-KF`PD{Rf8-~AR}`$7W-^lB9}8#WHY$(Q^HM-JIf(0<{6U&SRq{0g2L-cO{f zYj(%PX#=pz)ULSjKTSXV|DA({S6+^#rFJE14mVJ({=(x;yHb?jM_rds=iNdNw_`>}M}TC8gJAI3T28|UFu z8NfBeR&xU%OE^r`b7A=|jR z3BC6I3hG$}%uE!&%GZjYC;o65?q9kMYghRXcZ@jV8#wP%!?Pbn^~UiJ=`mcg-KSr* zWjK!f<`40yVO3INZCLTxf5g>-37^JShm`wMVjLTvzENEL>G=;)z2F;|d$m+tH3WCw zag~s7%iI6N5C1S1ykCEj?vYxLl`SJN=Uo5c)D&tk@#L>#?5{2s>90LM7(;3|VA&>L ze@^`FVdB$i>t4E9q<{XW0l4SipTpb#^!?i(=BChZr|w9tUnPd7W#k+C|K4xj=MNotX6X3(mvHkhe0wtB zr?=vplQ*T~qF;#gp9cICw|!$|DE*IbPC-|NRl`*OQ-5>r`4#@~(6{lm!;Tl}uT0Dk zwD}JY9{c&J=+O}E_9N?33$@Dj+Dt~58r0Xp>R~5{UrMnkMbiy3C)($l@&pMA z1AF4}C;6mFlaQeD(b&|8?%ld0L4s1Dv8gGoW8IWo%Bh(m5w)%@pFtmSxa6t4bh5%C zyO}<>{?xWr*vcyuX;B*+B^zTKX4f*J9V2X02~FA*%uDe4=#h2np4id^<$_LuZbGe>zz%ABohsQ`GBruA0$+9^JY|8onJNR4uP%sGRl#e;0(B zS^uXwN@_}<-H82u!2-LUccnyrOXFs2;q~a*Lwz{Ff8$H@#*IR!d-bZzmRm(L#doO| zG;L}`i+EFDdVTlkftu>}(++WtWIJCmh}X7tBQ`bz^*wuubbYm2DTU@u8?ZG!h8}wM ztWS?&`>uwjv~BIyy_*v)sXb|bxjF4GJ+xNUr*)&=*BhRhdQmAQ%C|LbLSt(!dZuYS zWNmAzS#aOj#Dwm#EbGl_TilAOhMpqbtB!JfDZy9tCC$4>ns2UThN;XM$Y+Un~=V^t6ItYLX+t#n(L;+cQljJsd<-^5wfGwuJk zHezFIcOmukv(Cktle>2+A8pdtw&qRPxYe^~{`#xe#hsal*)}z9M{W0V#;5V3qp#h> z_BbNS_SGePViEXIzp@=G+o-vuK93|g~mcFC!FJ^2o@wZ+gC=1 zqZ*nbV$8xCmD94((fyVIWo#-M)OblsGom=JZYiNE42z{nM$Nymp9GJPi)LyAM4RSe z%#|^R3N-IRN?p*|L)G@^A4mB^j64}6yUc?a!*+H76euuvxYp2H+vDz}9^}0mw{fm8 z?U#eBqLfEx7bt&OxyXxfxkhRpb*L)8?+N07GSBjxwL~$aN!9&1lVTHA9^L8eez`cb zr)N!&zyQ;I8q=9s;IifWM=B4d;j6or`I*kH0duHEY}G>iRX#QoY3ds%($wunDrVK? zyU4IZKxa3pn;RhVsNkAu=w&d2JV`8;AU-6YK}?V!L4ly6r9xqfL@4Jex3A-)9^O!q zkL;u=+9>E?&e=9~^7P8X#58qPb(mW^>uxY6&85sK zwdUkBwGI=|aItY&n2m7!!_5k2S_xBcI`fGgwmo|$KlF#px{%1`D^*aTj>~U*f@`kf zk54dR^0j>qb%!c)?P!LHqK-a%R18_nG??u`acshw+_|2v3Fdw?xafhV0>3gSyD8o* zW{Xge0704x$Wa=hm?kUA@K@KNSD!k#!?d0aYusiAvU%00@6|_K)uR-UZ;&#*-bCig z@~?|_eoQ~dj`h3N^+NADeMQ!_J9_n!Yq;~yw$aUJ&=u||dT1&L>WUBY+DnG^M7Di( zK;(S6JXEPrn1VVA{;N=GyZ1(|rrhIF*Q;;V204jn3vsGy(XDs-zfgq=K>-R>owhA~ z>rBk5P~WqkV#g~*Q}xhovxU2;szcAfUvfWA=9#i=rOe;g*L3TRzElHMe*IoO!r9ez zJz#gmRf4bJj|A-l+d_9?p=?TRulvo~N|s(zVa2Jc^WOy3Qo8FlXlntDt_qqeV}NdwW& z(&Rj@T&pta&dPOLZs%Na>F1`<%T~cglSViO%{keN_pjcYG6$}vmJ6G5|jwZ z!&(UvB*=p0UD+It=>`HUJZw=MRhNoPm_;U?oD>b$v}KDzJ0Pf`4Sv;tFiPA(4JRY` zQZW*hPpOGaTfj6VVN`3`%o4b-jw_mhYKwc$siV7HircD&cLrYW| z<)DVN>}tph%-4kuw)(cRjs|HwxaL5v@Mr+HKuEtzcUYq5Muj)UfoFeQ?v0owilL6t zcyMiG9Zd|~!IlB0bFD~i7R99SW`icFIGIY9Oc2T%swcdr{f}Ii>zlEOp)EA+wE+8i zB^sdoOS?M;7QT#09{*uTVs;ARM+t@^$BKo1;sK*oBpQcK19de6fWxE{T!lF zt~Sd<7jB|*7b2j#rWPIai+%|TLSnEwHB2#yY5NJH9u@af^`WV+wyA5wrEQMrs!MFI zviT-Z+i_FfsOOL!7}30-8XL;_CR%y2O@};co{6WLpI}Et+_Rs21~EZ`9Ui(!LypMg z=!tS6|E(_L-)REo#&8Rb|#W=xE_Y#lbWTAj;G{ZlQB&-xPpz2bqeP zf(|}=2|5g11AKL7%8Bb3MA4mVb4@zgZ@57{TyTPJlb2(ey@44g}=p^ zP;sGw%#>p!iLEd4Zy8|P4p7?@>bE4qxD2lBZ>W8l>)r>3y3|3ZYT>DR3aO?zui3Ie z=baRig1IxvUn?VLS+W$jP^GM&w%2gt=_rrt!)XeoG;&|fTiA|<5=H)z+HS9~Kd*i2 zcnHv+4On=)QBa1wu+iWe?oM!SdPmu)nG~P^g(x%R>2&q5S=!D%wF!!Yyax|9qny}i zf#sKF-@X+va!|Gcd~|{Y2|6K|B`*j~blXh;dC$+tdA9pZYFnla2PgPZ$4SgWQw*5G zS50$EU8YIf_R1M_?ofidSx60#Lu;v?PtR$V@~?(Z zzQoo>p(QW0`>w*43Z`>F)4?#sCw8%2tY)!mL6b*q#Z2LkjcvPuIb{{jorTtHajX?3 za$v?>DIy4_E^C%onkivGT=9e2b|u4f^06byAcF`0PTO$Z+3C3~DHqM}yj*>*`VW$JD*8j*sf}8Idp3!XhsfL_|Dt z>G&w*K8fyB(H2`$`L+q@^bRtC1#xRY@~~EiLJ~YCCgE(IdCWjZO_h3G1QJV{p!AS!jEg;`>`_dbYT8&r zX)@-fJ0*1X&be}aC1xUxz%`T+VaLFn3F1=>omuY)URXVU*?}X6;-J`|;8TfeSfPsw z2^N`p)B=s7W$u9o&%3ZAT!-7~0A)=(Xd4w@>9Zn(X0OKcj!X=)7A6(qVpte#XNflT za`D-^vqzguQR4f&%5*XhYM*T5(e5DnR}!PH`2C{!v)qqoJR_I|YiUH;Ow%1&=rN9M z#i@}3mlKq7K{YuQ(Y|WisC@}_9g8%O8ZRD^#+I`G&i!jI4KhIW`t<}mHq=5 z&9nI;sw@eyipSctjwPV6W(OFX9cBJYHoCQcu(Y5yvoQd01|YaAO9y z(`z#U9;GLoyfhO=S5=4&++)%o)4MssTixrD;ZkH=%p@}SufW?oB99yc_PKd0q6&}q} zF=s4u88D_!hJpA3-S|N5edS(I`*roXnoy;Ri%k+#3}ht=y`D`{DBYgJ_Mn!$Q2{er*S|>-^Z2@$vAZ?sG&!pOM(hvOnU;CB`MR|Y?O{B3O{wj;p(3Y3Ey;q1eEIt zp-{&*xYov8?Q#4;0z0KS;^^%KXdFEv~ z)XJx4;mZP+1#>AWvF@~oYDTy}Qg&2=JlPeeEIZzA_cqiU^My4mKXjw!7tB!pHMVLc zEI-r%iG4Ae4u2|f^_frhR2s4}P_fgUpu(VAZ}Nj$>O)-eukL{^>X^GzfI4J0b+p1Z zo(U3^5~gQai0xB|4g{^bZIPE9RnOF>%AaaqZU;nL%uq+A(K&5OcHJ#EsxP|xTTu9L z*llkFc{;xJVg=Bs3Zpp(AP12eTncI(8-0QV(U5!wF+qX^6$UD5GewYcJ(FXlA|@&y z3J>jW7nmRRTrFbz1ehCs(9CWryJv>tLbvtC0HU?08 zn`BM-u(<{jOq(iX#z<}@HTyQ7a0qFUav&g3&@ zTll)zsRYoSp#*v5hJ4mjtX&jObAV)&KQ~l?gAf`!o=fTuwKTjW0fW!>a3=vA5bJz0 zgDi`XP+rpv!^da>}A-X>l;c{Kx!SzsQC%A!5EobOBad3O1qZ_Lo*x0J>R^3ujaZHq@ z!IWQ{3~D=aT31hZ??_EkA%%J^*9FXD!U({Tx_U+pd8(j8Zs$mNWr_cfV zHKsZTfOZxtFPGCIlYBa7q@yWls&qowJf3b)peX~)UdzOTx(O2O7%(|b z89F~xV3SeY50JQ^9R&r)P*IdAzb2iC)_S2gK#imY#{6=vE?v8#PoF**G-yzUr8`gN zm>1-Cgk>6CzFed6Vd;ZGpygAe@(>dx*h)f|YFa%Hj@qVR}_GAV>@8HUwthol(wzCN~78^Domlkpg$Xi z0}t0@4w+udNI_#`lfor}rM3-TOi z8xzD0USxk6y=ebv`CfnXDCN#j<5+YikqNvu4dgZEY|tU>fKm_TU=O51}bKHt{S$HxeW$ zEnIAa!Cr{0%pC#9#R{EuZJ2CD2S-8OV$#24ks}8+Co|3tJeJivMB!2ynpS`_@s^rKdZw<+N(M9JODe(g3QU#D2a^UDA{`YuW(!ms zi+maK3K-P}cax2imwF--s|;CIbff7hVt$JC?9l;szD5n06WNYQfCevA8O&fs0a0Lt)Qyf%gZM z9{Tp_8yioGP5x>pV$hh{>xiJDfr6MYA}>Pa;1OT0^-={(7dxnv2v>M|@BLvx`p*usMJU1j-5cy`TU$yXO`{9wk17H4k*8X|KC?beN1r;`N(YyNSxq%ZnC60_ z1@vQ}rseg|G-BqrAM8ake`>>!|20Z!D5y_q=k3FgU#`Afjp8AHsymM-&xoL#4n;xN zt#h>hx`m`$-zKwSlFj7O2)^sqtwZ0wef9MW_9ygrS322^uo<)j2?~Q3mwB31>2XR& zh#x5#Dc?f*Zc_}d+vhM%TIKBuwSM5gTs*KT9s$f=oRV9HF19hnS881^Z=KQ~IPh?B zBY-^?@UV8x8pH|Xo3&njZ94DAGzy=qG zt&7TBR*C5saF;U@Y)ivdrsf4OnFy5zC~+qflo7V2V4|b==<4hE*p?LxywrA0`L0Wr z6ZEPKCZnyB$3;HC+)qjlm$swM2iKHQ?bxi2DzhnHU5_pA4$2t1)`?XuSOL z%OX8=*f6D5`z*ZnX_e=G#3U+GWIuBUXeHbc>=dKZj4UXR@ixVUWtkG?1l+sQJtRc? zL+_x!3fv{)h%q<`eYw#ZAeka-TSL-yWVu=9U%yQz<>k`(aj#t46cb16Nkzar(+Q9} z+mT^g0r9O0bsW{PrN&#Xo6ilPXHuVK%y)t!l>;wkNk@{sP?W&L=C30uhh_fhJR74( zpzK9aLlN1Qb1AlDnQH2TTC#+dIZ*{k6{V8ACL$U53fuil;;8mC03*pw9go<^ zpWH!fO*l`cE#ZKgj42fk6gj`9b3tyP)ite(uf{<-T9vPQZIg}SOT}R2g*_??A>tOo zH1(8~Q*EZsx-*SvYIwy69wG0WA&|F&qFpIZevnF3VaWSiO0LMoh@%Jqp$D=kzS+L; z+&E|#fZC{Tq^W=(YF&jzc);{)Ubhg`cA@Z7+Xyl^L5DECC}LrjA%4)763-yeG6M0k}ZYT?&GhsT50Yh6lv!=!jI_smBLsLfiBv-So8xtK5UD{U9 zCBX(lt&ryL0-Gi6dtCJjn^ zFwjvZOlOX4R)M191W&olY<8-h-+;wI8kzVP^+UanS!U>$dn`h&rEf+ zj(G{P;}Y^F;+)jaDTOZTrmp>_DBQ9&ZpaG~S#;T%#D)`vdEh!WS#r)?sua1YrUK;1 zm4j6H%`);EX4E)e7b~jVJ6+tzH2o=ZVXAvP)7UcQ*Y53@TA>7BPFZTPZofq`iA{c% z{Wm+-`GXo8nDnoI$-_U{ohinxds;*ukFRwBznA+8{NJSl7SWzM4 zra5fVoh#{?$QHVjLOna+C^Ej-QJ^#Al!v1{d<>S55!bq~RSh=evI3zVL#g@D#9+2;|D09dxZ3B8=r8BiUD@2)GD$;|( zOQtiKa;}lvHg>j9Ko+Oj2+8}4@a5HvVg=F)Wzxq;-!xvzX$YO>|}06nO>a&?ki71|gW z8Oo_L8@~hz5+q1a3b=Rxm0pG^WC7efMg&k%5*6L)oTe%s40RKyl)wU;s*szFOa?D_ ziP%Ex!l7GETH*p)VEI`QYU>K@Ok%M_%zu+^w{G3U9>7CY6{B}tdG;xjFwVO)@_BUB zTyv?6=M{wxIF(|z{wiBkUBwEvl{`HF!CRC$5B6gKb^4p7wS8luM95PGuFKRCxba5( zQ>NR~<_a^iGTLf7^+Y1_FQc#MKos-T1~Ss``Xcwhvo(f}vF>KNc8li^EvZ z`i88wX)DD9^$ndIEKc?TTjULXsf}!fL3f@(V%Qn^e}1%gUOEAG%dJ}ah;d~KHZv*(fpa>OI?{d z5`aE*QN^>398>DqLZU+KY`hlE5MQ}gb>yy#!*u&KldDzvGELinxp#gU%R8qK^@DAq zOmEnZhvb&%Y%f!n%T@mB8@C|wHm7;mb=anvQbN^1aV1}^%PcaPCP~Lf1D$o#xfHof zosX~%s$Mw0m6jkuN71GNyg|jl77giahn&`#IvC1zew^}qFwmId1S*En#Sl8*%3%)G zRJn9+g!@ITP!G_oIXIi(EtJl2<^JrgGZh=D;+01&T(kDOEIp zT4&*W4mwuinzYJOUa7W7)}-nxEiAkW2W@@wC2?Tm*b+D7yQl!u@Y8u$4j1u)$SMC3 z`rs&y^ZetE5QofBT;4KZ3NMK^PXb*?$|U|A;m`O<^<)`IMbb@xOmCWgn`)^1b;@o7 z3pdIQP2{NZyKGvo>KtZ|S$M9++*{Uol+}GTq@czQylT7?3NU%eIiZXSkNM`~~@a80)=-Qay zzmW?liD7cy4Qr1{Q7S~^uAdj@ zFjrbfp-*KL11cWX5`_s#xlL=`${TR*mF1*}5oBt0+FY3i#JN)yhhPmiZ)q04;>@SO zuF!{Z;Ww%K`MI~Fvrv6zW}ahOA~1bk0d1OHd^BI~)*3=BW^b&a9LRmRWk-8HOWl^2 zjHyE-+?rcC0h4ZRw3~zlO=M|fiKqyqQQv~1+9Lf?ly93EseC|3^>a>O%5`N;ZH0l3 z{oDr4c7STB7PUOPD2Qe$ni%6Bxs1wJo7d$Byw%v08)V>yJU}1GLX%&bmCrOSIW9b^ zlMXGKjvI9271X8ZbfT&DRxYE`ERzs+n6v!1Suunjni5$o{F~*;k@s+xTt{7fkbbF$ zxzu*3STEFGKqNM%u+NXWP61_L2wDz$&j(Gtg21GI5xUl`aS-J$`2iy){pD2Y)?R`H zm5+|B`#KxTl{}rtb1`MAiPV`uQyY|=l#ercXC5&Pr5#-xx_YYI(A0C)AFh#$8eb|6 zBEM9&y9=FNz^l>|&yrw=foVC**QT&e7cwJ4olXv&$CJwgm^=>UnWF4kRsNVsVIH?E|a3lTRF7lk;cp%5NCPbG9g zsUs*~V<2Q1BBK@5#k*EPA|8J*&95}=!Ph5U4qn1Jy2b+P0_1IXu+R@xloTu$27qJJIXx$D^44jvNTksj2d4u)d`Wj?r0 z4%6{@Wlu;&SV(<1U}{&{5oX*+KbF zRbQxsNu7Qf5Jib}b7)rlqRgdfBq-JdFm?~?}rL-JtQE%0f^W}z_MwSp6%WqGG=`CH1+H+A2 z1!*dnVwyZ#xKrdh&eIJReLF(w8FQ$YtDkw3R%TL}tCA;35CMrs6%W%G>dcY4n$_(d z<*VfObT(Y|Q>Iu#Z5NihOv4}0#}79DYLhXFEL0u9JSNosNabbo{|xTq9T&vITJm2@ z&zLa-RaO4?N$$Dl9?Y3D2eoyzMkZ}3|5GT*o3(ZT=qw6lZA`0Mx2m(2M2!jw^P)ys zrV~pw@}%AeYmcT14hRz@NRS{wR8WqB+RX=P(~jOmQ$X_+YaLyJ%0ZEbJ8DHEJBK!y zsRD~q*F+ec_UUUCG92<}5KHkUr}lzwQ)oJKyfq6v;SDBB9^!l1&7U%`{68iL8G3}D#Ipp6GSSes<<PfQ zj}0yc>Y59^{e;tAL#|8nQ4ONWBX$x5-PN6GC(wYhJ%F3;a0i+gL<;h#IabSnf|s?e z8YK!0b*PBN){bmb8S?j+x;ChC+ZL+$*&_D2c?(d}N&zZk^4l^yYWbVSk860F##?S9 zzsEfEW~JE z+PYHpDBdQ&s$T1$8#`#)rs{DEPg}im+GFvsRw|XsW;AbY#?+}(vuW>vtxunD0(3*y zwQE;wZQd%bJ*Si6sW3sO^DLAaxvHQ{3#ASxKx>FL=PdAuy$7{*+cR z=#8&VlPH5~f$3dF1 z;U>D2#M`%PL1_y4TjI_LR^GR<$V1A4j9{!y;MUT@W{DHQPdKB{+2?r|&NZS{(^SgW z`vQByqZUxnq@BO!c|zy{Ws$C!wY z83<{R*9o${vaNHI@7DOnB4m?W3;FVr^p}yz(hRL3!jO!15Vv>qw`%G3&n5G|)WX)3 zQ?k*ea=K)a7X)re$KF`UhM@f8s``t(0y$q2kL8n*U=+hFqsr2w*r9X6oxIz{fwDPr zzN$x*_Nu|SVZp{R7p4QVm{{w~xSa25nsg%wr7bF-;-Q-@l^+besO!SPh+l_RDD^Us z>C(`&q_ch|ex|w5nU(x9KPP)en+~YN!#j}9SuN+MK{`v$q&$`{2el+z-f^IwbU~4Bqf+&c` zhL;|dE~o0fD7&EM>&zV$Cz$wB@qsP^qhwLbsQy4B2L)9IXk-QSevpHf$rKM!F_$ZJ z@sgZJ$>PFG$D>$CZ`R5UO|y4+m%g4dWs2V@PeC_refspl;w4K&-q0aKQCCxk1PKzv z37g3@Z4YdGA<^s1y{l=n)sx%RxfNYFtjZ|UCukSAcyKu#z_bygRL2BWZIj(hf(`}B zw(IPzZgEf{twWPket|4IEh6DAsfPCtQw!XJ2U8SYkX#{#9K1-*TKSyV za(7a?s)eM$zByM@kGvvPE)1@xGl30YQc|`Hl#5sFM(9ykVhhEU5F*b8WoW&Jv^-3i zl6g=|rL$@{BQL?%Vg6nJ#VhM_kE2%C_r>tB)5P`6i9^x7O6A3|W$7#8>d7Zx!n?~h zqOIQdCj&?AiM{sU8@u+(G_rjyUVro+Jo)-6(eAb$BQW*Qqp|<4Jw>s{dfkFM#r1#R z9fTuKnvFr#a$7C<@L|7v<(?;DpP^D=>w3KR>?3%3{>LJ@rnwqDhmOX~gAW&NO&d}x zy4t+_B~kv!!!O{S<(rV|Hdv&`&OQu>&K!;g6bpkL(hPg?NOMcA#0$60L$@Q25jhij zg>_)t2an)iOLoPn2k#=%T{=lTNNIZP7DHasa-&W*(^hKRSeFNsCoO4XfPPz~*ujun zkda!Am+pK{WLF<}9H#cojV0f@3@<(W2wr$+nMiNq-7t8M**NU5nIb*BKA?L~{62K+ zGgu}YXx1Hj&N&IQ2UcYpZ~X9a{O8^mMQYjh{up=2@i=yJUy)w@;_Y~f9e@*N3=rvD ztrpRR4?aMQG^5Hnz&o03=`!|)qQAa9Nm%|_;##c=*M<1zxEMUZsus{KT4!0%$SDJ{cAx_2(WeWv$*@Y zYV3FNULq~*TwVuSvGnP`i>rG#?}h(2XLr;z4C)%}g)=du&mYhAs&vJ)L+D8p*LzVeZTVLCf0!ZU>5ap8tNgjyatFx5!gbnj~+xnnMP0x zI8nv6t7n>eK>oRe$wcJq$2RfrJOB74p4{bI_{yx_BHg;+8hqid3HZy;juh#>!Es*j zpqBE4o&1(+2HK*k@+L@NL!vA3Lbd(6H08%Bdj%yAaGNt-Y(UA%4RUY`Z)j+#kc%sH zwmcJmZfMiSM@MIxCpFI$hpF_XLYG`qGHhX}oSz^;g3^LARUW9YQfD$$T3xv2)EZdW~>>)kRS2 zH_8s7vm^2t7<>^crkUU%C!aXpY2r#7f&S@qECDAnI7y*%Y9yCV44(awk0XPJSW2c@ zx*-qVB$WLYUjBTQbhadQ;7$Ql5$y!vW}!S6Y6qy}L&dHt z9cAlvKHBEDBQLC?99Fan%vK;92d2<7P5nYG3GHB+syne6D%HON;r{03mJuvxA6fRF z4vP|6*Ki}YP>JiSg{_qC99EYuKhy*DND|pXNvfPWK{suuI5Y(j!6_l)fnZIrb7?{T zgl}|-WJLvW9WUBfQwdP};IbGAw7)5h(l_Q(#bo%@gFU%U%rGqmZV)4e`7re+-?q~t z>5gb9T3s7zcU;|&PX1CXgB(xQm>VjnD#dNQr7GNwH7D|HbEmrwM|M2FQGGIpAQWT( zwO3@%OEHr1xdo9eI6*htQR)QsC@nX6Vz~}8@UeMwSlWO?9XQY#5p^I<13{^#Dde*a zN`eH@VA8@U^`NO^;_1?kN{@(j5+vw6Fs+y<&ND)D0XwyMlOLDM6YN+hdfu5KWh9Nx zjk(sdHNvz@F3x4(eg4pUtJc6l0|n>K_!-24!L^A5A!Lj-iynW)DuVYZh5MtD=ejI=L(WTh(yPu2l zIfFPhy>-8k@o(3zz`H%J#n0vp5@q6rBYZm+KX->nzt;am>@zf-)v{2y%eyZ80d7ql ziqnrhNR&^hZ^kF-^Q^VanOBvhZ=h_Ne?5M1$y|{fb@FLAWKKU+ZTd*0pT7C~`1bts z@tZGC7U>>VN6YfZwdBVshTA>-6U@KsLG;^ujz~`E9ezbi%g4{)pD)zoq=R=B>8_}3 zm`p+Jt66vItCm^pYreY(I22-;&pIr)`vGxT zH|1DN?OP4LdA>+rf6gVCyYtC7?O=aB^sC;4kDj^--~X0he%^1sgemDo&ey&n(hoeo z9J9~d8~uat8?jpStIf5UTKOP;e!)Z7EnBRggdT0A8XG2y-1&4y%M)y|2Sq$ zJw>EPR%g1?{F+GL^{2TQ_M6kvCiX4Smk00Kh}}+@g@M)b@NUP_XKxi(Pvbc8W-WQ> zS>6Du<708sMWRd3K^QTzAuPeRcg4@0SG|HBhn)<*Wr0Xvcg}C|$(*m^gd=^a-@g49 zIDgr>xZ+Izt&p|F+DYo{y(HcCnQmM56t4Z%O?Ym3qe$<&$4Pl_%?W5ccy#-YIZ1l^ zRyBGI8i7#_VIf=I_1_eE^(#Ga_{sTguX*fharOI`cg2ZE9)mtjzP|qZH)mtX+1KKK zC;Rik_$Dm4_FP=KbZ?P9>%`-5P_Ohj_X*l>!w0urjTc9rEmB`Ub`Adh%j+@sN8c0a zy}Ik}6{vR0b&;buUq~GyyWGDiQU^>vhZ$&e>PUG2PUNXFxO9UV@{3*yTi(arzq<<0 z)cg8$_}=3%qbI|rWp9i0y+8j4?l|IXeDCm)B3&aI-G*gPT`SVRy6HJA-@GsOI4SdH ztuDwLu;Ic$N8qzZ?Jn$sOtx*IAMag#&7D~q4}twq#}eTt9Cm^}wDYv) zG4Xr#?_a^LCmxAo`ZS4>H~xJE&R%j3uKoHXQKKQ9*AiO)n}v;-owgCdgHe1{+J{{D zpeWzvD__X^5YbH9kNnTrS~aR9uS0p60`=2|jOF)-DYPoR=~InXyL|045NE#`AzjNWbQcu;*y zkU$61x=CP%YFhwkV(c)ziJvJQ@K>)HoFXWar_Hyk{HVU!XV0@MQ<+eTWYH}M2$lWpT;GQX6ol=bHc`p$4ZhWp|(6N!{-gLV*IwOJ8R=Ct6DEjH3tL2b5 zwCT4tXjHrqRZ)UK7uGp)=H`5^Day6y(2k2Jsv9+~)naE`x7UD82*k5K^4n(zK{+C?IL*g)$0Sscsmy;5A=*m?$j|I1Hfco*buOikY}Hw0}T;;uj3he2PzPGp^X zaKB8^B=PUm$pi80FaI95A9RiA!2j&t1)2fUCmlnxXfWwkbksF|D1M)LVGH&+c!K|M zir2!rH}Uwqtr&C2G?5X={c1KmC|CzZ>L#E=8Lk>p&yk+J80mJfV9>DSg zzl4hq7$?$QFb-cmZ63bzU;i^<|MT4gu>Z!Z@ysIs=Jm*3s^PuUvuXb0V*H*TdI)~! zeIjsCSaYl)Izbl(*Zjr}hK3Q-aqx(6+Z!JDKMQ#Mj1zF^uxhl-^&g&lXvk;rmlI|q z_yX>pBevs%uiTD#C!8nJ`*ttRD&{Rf)g{L@41AOLdFB2WG4RVj#_50iu}ClG`E&t| zhtvP|BP4Nxe01QC@r%8EeQDje9Lv|W zV#KshiS)Pk-wXHt^f$P5=gUO;bGvs1Hok)UUmPgXU;feQ`1_9+>jm2OKK}KGd6;<8 zJ|g+yo5&wnLF0e6+M^RRftUnKlS@(~WNxS%;?v(>c<1F7puiqA@8SN-U&Hd$BvE6x zs*QM6tp6X0@-zPaV=Mxs2c%M1_RRfhAL9ET&yRHBz7O%>`H@rh*b5CzFTb3p>Si{d z(fJhA&mQJIu*Jf3JZWuvEfhcuXhe0QnKdr?gvxK``w=mNO|*`gweND?GS zkf6drg-(FkfS1X*+oI$^6j#~=m4~9{i{+(^D!^PhX>y4M3Kl=K%$SaSPfhG7yr&M)82{j zZ}?5wZy4^l<=@!ryT^#)0U!Je4{kXMUmg=Y7$v>garm+L_VJhF!aqIf*S+9i^j8_D zR$|`M3&rKMPyZalx++aeq;1Pz!HcVB;u<)IahK!x!G8YoC;p5puG@f54fEfO@s)91(Dcf`@VjUI zC+_}zFvq5s|A=$0-7M0FoU$JVe)1SD{r>Ah#&7=iE129Zx837yvG&9F zvA(*8NDmr52tCAupRHoNmVWp#c9}T}fu-_%P_NxaqxWqe_!%{);=lv8;y2Iu_UP1I zc0)C9#H)|{4>yiF4gD|*ZAr`LkZT!C7i+i|JYZl|~KIUJW%e>F z=1_;q;}$v*wbY3uaeC!$O5+4$l)vwZ>9-ly>~zI}M>A6Mh8{lAY3hW<;WZ+p|H;lZ|# zZ^fIpcr^Z--!2&XZ=Z$$r3#b=Q=U1B#q?=?>Za8z&@^}^`epxypciI+@odb(T0wVj z9@ADV`EXI%hl~`dF5(;^?L&4QEz+JJS)SSpyHOA2oGQ3|8d9r6Q|>l{ik72z5k}oTh4hH z%dfl=Cy(&`)5i~AjsH%ZfmtJKb=)`)6r9K4cNEK zrtN5vBB?&pbTW{jW5TvOu~ufGR0Q&Z+5j__Mq`UG+Zb0;!N@MJjC`TL5y;YHsCZB# zS62nga`zRm2<*sv5@z}R^l>l|_GJTc0TDk|fc<3ht^&1Z{v_u_vlp2(W zB~Mb+d~V`Z=lS=8v9|Wxzj52~q zzAdMQt6Z~>v%#bj#X`60nPYphj;mwJG_*{USIGH~j?QU(lp_absmDX-BRqTL$Mxb==#APKK!7 z$)rX$UZ$y5>*#1*;kt`Tkf6iB<%mqTfT@KA(2LE{ZknQdU2{7+B92GApFm_uVZesBus-wELcVep`VAj~x-1<> z(>o92&UvduDwSr?XVNh^dSY*p9(K&x_x@InH?GCHz5~#=hK2i^MHloL z&=+eyS)Y+T-CxH!(s6XF=@7(`^Mu0Cb&U9#HgO3ad}}j~8`vz;FF)UgV?I3?FTePa zNVkpK8Sl=26T40Ss$Va)91qjuzN_{itx6k zlXQX{k?KtPt_n~V@NRF1K7I8IeA87i` z4P#Qy$>i8F|3A39>QmzS7vudmkkpTvEPi*r?mpc2{#YD2*#C^`!bkpzN0)8KL2ZZ! z4ra5Y;6)PfEtvnG|Dx*HUy9_oI+spxY+mp;adp$uqwwADd49E3q*pIrik3xx!cF+X&~CcW&{LcFr_)U+;m-} z7+etpiWt<$8DkLS-(++dEz=2M-Zm9Z2mVd3{Z&YQ?ZPAQ!wZL_%PZC_s~1rHBQcb?vL5FqOmFM zLmFzcyhIq6_8}g+HLk!GuJ4-;x-EsebZlwLlS^D^DdW1P^Zhq%cK`4U-1W{Td}d_#+!%2kzucRh{ZuBM>6Gq|{A}Z*+ahw9ZBBv& zJ2G^BLA7nB`Zikw=+~fW7a!FZyV^8npwZQ_MRU4%2QY_TI+*+yH_&p2d=U9Mzix_B zsd+4wjTH}TwY0P#K^fr^?b$4ZZiTzn0rVC^hY)?{B2-sm9MCxb8NF+$mmooc1PMA9 zbdJpCv~;1eqhr%Ws=8(qbRIaVh))zejO9e`o*gb>u5}8B_v-xY!JzhY*DSB`+>2QK za`{E8@|&XMPmFbVxa?rH71{|AL@*udg>E~d6QZVb)gpUFDYj#^{3s)`5$F_P@=+xV=iAno_OP$H5l!9$3YllCYSVY@ znwz$UXshaapif`_JZkxqH{#wd`{I}h{tMt2Tz4UEt^Z&A^-lkf3tQ&>4ZpkKr>Oqf zMIt?CSkQU~wWINwZ~Hfwzj?{Ecy8i1z^Y_HYtuIk{fCVjx0>gb)z+e>xd|eS3rk$Xw0x~Hi@Rg>;%CnpWAVHB@1l9)C!*;2%~SFJj_!+v zKbt4g3(w$~KYt*mo#;OdhqifG_}(f!f5q2C@+C2)9L=BjpEcTP{D$1>@&% zR>ze}?(%a>y8RG3@a7Ig9R`M54y?wv2kB(vHcjVRngxAxeVzDBUzgoZ5FCDdX+YpV z{IcZsbMe1_c?QS+bZ=4KwYm+ht*MYI@wRkcO^u-U9=fXD^t7C-@I<4$JhT zYUnZI_q=nq;qNzJiVNEOkJnB-bUJ1XScg76VhT7-cUwvhUUb}?`s4}R_Us-w@jBu3 zVE-s2$Ch{hiA#R(+v^iAJ|AQ2b3$xO-vg=|e=5%V!k!}SJ(GOGl&<*7wNpycTx@bn&ntI zbZ3zs=9#&+%~-#|kB^3=4PI(P6Sj66D$;d2!DIn9y@DHWSSymp{pd>=R25iTsp{re z#P5watVz>+8H1~RcC7?ExhWSH$2Gqul?lz=miO?_Oa36PKRMxIoIf_#>)>1lT0Yh2 z+9mBT+WgP#WzS>U{GPSe)G80|((13Ox(cqzGli78e3OprqtGy&F3%*FL&#cOJ}2Ygq|8zO5Q^9d&Ms4J>vk=+^-R?>@lj>c@njBiQrD)w$Z5G9*SaRVpJ!VQd~|V= z3xAa^PWTUNZR-pVYf-LMH`VH}Q%lOWbX=Bof+(@;PI)$un4wYDHJK?g-aPE@}FoY^s#Y)u5AiRg=t2N?UIp=t#@xMi zElVdBrRc4txy}TQYs&LeL^TugO^1IIW7)j9SUKSY?BYLrg|1`vz_uG+#iG^;BE4%D zhWb%^Va_Q3hSUJHKuW*cD{hB(>y0?#wG=T|4Z-N$w~6$PuYHWx$-AKoD6ll?XpC<8JKkRE zzuINe$ZF&mrIA{Nciz~9F~^S-N&C(7@EEz7ACtEt5XFYG`t%K_Ml?06YVN1DG;Kyr zLtT0%eTKcpPsQ-R&Bv?rmWuS+S!ZC^!QC;d_A-%vab68x>pBJB80HYOJ{C8ag>EGV&@8C7Y1A0*ojD3^&uI?ZIxN{j=~}-dc*bi6gV? z*r!Ti)jMy9^rkV#V?;H@&9@+fNAHSmkFQI|H2%X01Bdj(>Q!sg3cbfVcd?)>1fYgdRaW)@=gZoz@Hc*GjWeF!(5j6gr#@@g84y-uj+t{m@i#Gdr=xbS?DK4Mt#mPvm+d-ofNzWsWmi^Q(F?@s8yWs$fJzqKbAD5hKk_5rk= z&=7}8g@6+x*@mi&=9^MGxhxPzJ)xk|)US>Y6?1SzSA89AL%sjIxv33RV@6@b;ul5w zmF3g0$D$|j`nJs?-D}w@y#C}%7`WFFB3)+T_@7( zo1Q{9cA%i~;L!y%$k2H-U;OGqk^a%upT~si{Bf}Lm7-OzNlV-O0dD`<<#_vm3q$;Ee-Iezb%p_Bby*+c^Bt1)As$u_+)en9LeyNR6SjH*9W#`h>QSxO^ib7x z9^ywYd7Z@pQCC-%gKsaZ96}2&n=u}ifGg5*Kiev++?;BG<$Sg8l&zuKO3=Ac^3bLO z!+EO=v(1p|Oi(CHftp&T3p7kKF8}Hl7-c+l296Ul!a^%+ zRiZHo5_CM64?cJ{P33Wki*E<~|H%&|1o;7#{8u>YwMrB4Lx>k0G*TWAFxxR8n#aq% zkw@ao%$rGiDsmGNIH#w;NLJ2`N!3BN?MgL_Hc;zSg1t+sgVY2=6^7DCNA1Ma zGFu%;X&pTyc++i}`^NJqxaL~NTb*fh-5i|9T_LpX(IYYIFpD-u8Fl`+r!Ghgd@Ha|;~NpR~Ph)RWZ!t_hkQF+R`!Yu8>#R+86Lc;lb4{ZVyDrnK^<8Z)WtU7c>g=vf zPThLv1RvGLP<$vb4Nrjf6ENg)OU{~p^P?iC zN|hpiY+%k5qW2}&ZAM;}7kaIR zrD0S)mDaJ#(WSP2f_I*{SzQ0-)+(Iw>wVBOQ_iNJh?D;I1N`xOBc@;|%v=kxy$H&6HpK0C$#?3QSutp!`*zZs{l+cbRY*uUVSYy3AiOgaBVjOke= zWbm-?-ap}=n~%niXLbiE2IxaTno3VWR*3=~ef2O*pUH9AozIHo(cj%41JZ+#+U&nc z=$;3bVb+;ra(~^q(zp4U)>c|RSeT+`fo+M?A9l+Wy;quDtP-))o9F` zxdt~r@TL&rh%bys_p~g0dy^>Ml4?M=+IBL`T%UGd;iltTpi*rGIpVR2N}a#REt|$k zUNI)WU^{fM$p?vbL)so3D>D9a(I0Wglpo>5F+DPzIGPsTi);S5Nu-bd(JXjhG(v7zDBK_))sW=&%NIj`_9@K z%^&_pqvSaLy`W^&#n+})jIzO|1)|up!=xu5^2x&v+9fw zc|znZoO4>*hipju5dY0(1JZt^FR`aouc@@DAEth*`om;;p1=Ba`Yc1OBj=gwoARkB z!Zm_$2GiwbT4r)4%8UQ`PBI7^t#Y%01mN7f=WXPTw6uMX1C?_!ZmrS z9W?o66(-wD`Ek=PV78&UU8qhrD7@4M|B>X*L=P0W5?N&b6hP*Od@EH5 z;^2`WL4pJc$^q?cUOUbW@*+wLsZhps zth7i)G(jS}{g!`aVqI)uIT2DnEzQFsRajT@#YHAg3|KUmE@`3b?bza>YyG-*R zK=|BmzlQxr*7`oqtI~BhoN~#9sJ{9SqWr5TT!G%h`l7aFgGjI1(hK{2ts#A9%fG>O z+PBBz7Z-dP&kPwN(sk>XVbjQyarO~IGP0!fQg)k!&wXMKle{yr@pA#_=!lj?RqS} zdFh!L*FcXhb*!U5!&K#Y4xQlhitgoDhMZdX1B)|B%1`O=I z9qTs^7U@%e@e|A$>hkf(n8E2RX01f+TLP3hwkQzXIWsaBqMSSCgUENeruL6E*;u%0 z`l5c^S@7QIdg*s>#_xXqIsB9R4{!FZ+K5k5yW-eyUMkXOj`tq|UHg=;&p*6nDZ1~} z6Ikaj7&hs2T=0$Y;-OE$e*9_p&eV%>!RLMZ)2quSG>$wC7ar}~wyHq#!TSjML;C&+ z*AMwJrgURr5hKH7^~Q|q~|4Fn}Lr%pN*L+S~@4n}0_`zXU;Ic1&Nu+DLZ^1e~9bdWdK#}en5?Nkj zl&w?C)qLt#rA7R)v(8k@zf^e)`am^FHNg$_Y_xJ7HM*1>p&OJN=HbRmt`e66ettW? zJ9RVW-FS&eUp?^Wxa-?HhtjuyXIkE;dFrS6pDsP-zrVzl_xHg!jyyr6zcxA3dYk{S z)^T5$jvn13uIB1m)Ys=^_prS#BSDv%bXje-Or{f|rbp+|)cG`3x-n2dX{SYNv+(@L z`lqfJ*H=CFKB`~+DxME5z@a$hifaUe&yB9modGF4gZ)EI#)o*g;Pa28ciM++9_fGP z+w&t;gnX*ZlAl>RERSg|P%@X>+p&-&axN{2ysyjNP6a)m zfPPLn^z&*msisJbsu#C;PEdN3KjNzlQ0|>M(lVt?7u~4k%)(cu2WVTS_buUaPRPqO zJZ;uUrPW)kFb$v&qf|Or=%{=bUV#i$A5|H3{ZxI2E@IWi13b9h%Jx#>m6g zmaSGEg~2pPfPO$_a0mHYLi8QQ{npj`0k`PeuwmK!WlNX(`Wxz3WxtgFIB)va(W2a&kB*%lhcFF z)|W?47l*D|8A$nlUR|AJA2WRk9wyJTk0zs~Ybs_`qCJm-jxK*>sLser?ik!LI$4{s zAs&Wh?8wrLKCc#Qvn5-hV? zuR|sOy(|;IZq=}QyWTUFUstzL~5!hchT2c_SD4c*4P2)ns{z5k|*K7INa>Dsn##>OqF zboc!J)yMXfgx{g+YC8S}D#^x}kmoldg%mn#Q~7;g zm)85fiq7-q7jXG!{fA$6zv|aGZct7M{T`+5!6x4xY(WEh_pF0XO#w+Lp1-$ZX+PgJZTmKE?Z){r-L3+5TPxcd<5(s&Dgfgn!);?gj zgX0%OK#Vt?)&e*j~?AKZ(2_q^(ybIFL%<0z~uH z*;<_DVCti4jkSA9=*N$YLzJ{U=g_o~AVDR7vIDB!V+MN4Z*WZ=)B0luIaC_e@0ivk zK!-8hA|GJxE1QDYLF-BQO;H?B6nK>2fOeqHRQ$#+wALDZ%A76qx(;>}t;dh`(K zrp89>x#ym!sjUss%EC|`u*JC)FWmr83q%FQ8;IXocz;pq{gr9=?zwMsH)h7jLv3v> zDj7olx6|@>ljLto%Rjbb$ge|7=8X$)z5RB&Z{4!_jZICWZ?&~Gs8qDHY!h?hA&}jZ z+e4+w?#b-I*Cl1V(`%u&rgCI%*|shFm*IKiTVb*m3a^hIgl($u`A`v_AKxx{HpxT2 z?7D563Y%8~XwO82U$U$j`>)zh+5YR;>7oqXHK2EPy0Spdz#eLRRY$V(fzS02^rf*e zSifT{t}niieOp}T+w;nkS4Df+ODb-2S>>S$1;KC0doZKm2Q-*5nFnut-_DG0w~QTW zlI>lQ`oRn-H<*rWRNh=$s}O8!@pZ3T_nZ%FYHSkg+(V6NYzl2O7Riffnkn|0@GUhp z#pr}-*94f4>2yAm&fAvpkKLp`G)ew3=ts7O+1*A!1V$3+HsM>|&eONCX?^o-L5(%` zw!{qu_AiL%-WFpi$=2k_=Gov{6uaAvuIYY9f*8nyX}@B!9L6RTgxgc%Lt=mAdYIxQ zi_HYa0Iz?tKNvA$I4KI?b{0|!gx{>S&9_&X^|L(tW-W&4Gp3^yU@=hSk=w)lSP-_Z z1;|-qxV~Ad!$WuQNEAnB*fEh^0_lt3<}c??HPF!!{1rTJ`$+WYo-6;3=ihw|AMgB4 zQGVsQ`=h_Z+udxwMi(*Z+>3gxR*uhXQRg6~Lq)u0$`!haiii%?=b}LknyE~;&(Pm7 zD$96M3(GY31?UE~#%)c=qM3GXw)S*T$5wY_X_{3x_>`%1?ATgWgPN|)i9>b_xVz1@ zjWN|nwVvxW)kg4UE!*iymPf`32M=szAKcPFH$NsHVKZ%}F>&%!8mMobv5kofDEb0T zwH5K$o(Pg@NL{@(Wl?oam~_R&hq4DY8np~?)1L&T!H)E1twQyUvWFDUb&|bj5$e0x zYAUVPhtiJ8x4A%lGbF{|B#S9NG5IS~zjb5jG7eOKY;x%2vCSDJLo9FB^1fn_X+%7% z)s#7Woj!fKAZlxCgBGsd(dPACy$g$w4@;XsBo9?xU5zSMg_mA>DVrz8h^NH0KTa9u ze)NUHLP{5N5`8dy`57TUm*nqw@cQM!Q~sCc&CBLbpE1L(zwHQbma4otsq#;SeA#n{ z-hu2UqZi}>dPAXtQgM?Os>Uf8ZzjfD(xn-`y+}#p9mTLw4lb&xQ1im$`%+d;L96J7 zZAG~{R&MEwt0T2Js{mpB*UyKGLvzVvj=ZS(qGZp`PsT2JHpxREyQwX}uFo#x@8ZG& zS@Y~?O1A&)kB~kPvX)j(7Y)#8MD|bTa;wK5b3dK09~^BdLtk_Yx`e3Cv**4a@=(dX zC_qP-zaTj32#Zdfy_9`t@TseLX?^y7WqX&4Av1N$tiSDoj2Q@YZ{AC}7;c8JSwVc- z3U_N=0w`g9TvFuhbtX2?Fb@28tZObxFeT@kf}aes{xK7Sc%(CCnEYdb%FXDQH7auY zmh+J_rq9U9>-mWm--KDt;o{F^{|%NBo#0+ zaTtpNQSgJ{Ws-A;dRR+7nv=54l>)S5+))B>_d!r=qN9PbBiS1(yhW6){^&z|QneFy z8MTuruhYcux*e=eJ4{+*I;RN9&+TEFJ1l$f5}`vpxMVs=0wSA$9phmw)5bxC?zGl+ zg6HS2UzZ-wz9kw@-8{#r4-{PNgK67kI_EU;SM%l1AOdtZ%ux=Eubc>Bf}`1(^d~a9zm5TEVk9T>T6p&wK_k_)Bl^ zulzS}-mLe`Tq6}=o;~?Gm7z(&4Lo8#EbVi5+Sb%cYb1%09TPaSCvNQ ztDAR*V19atgzR^`O0w)Gv#-iaO>1 zt045gZ~w<1^UV5f@%>it_Mxn8=Wvgt)aIqO;(*PbS2{Yn`~`tB`bOdaZk6O3-uQO+ z>>d1@-5#>~Os&mGvQ;1`N2h@poAg@WCfO|SZCZ_+)%e=IS=(%dY`;{=^ri{!CW1wx z+;wZKZ!^0qdkgPPRE>=e_S(hPQFQ>?LE30FTbe+(sva8-Q1YhUY1!5@Z||hB~qDwah{8>w`FXw9AC?IbRrg{q7Dezuk<|oas~c4Vr;?f z1Z}NtsP9o9PkZ*}d_-DH+>o{}OyA~({XzSgd);bbxqq3VYD~yYgBsLD0JEfHM|hs) zhqIg>)GDH@2?%iFl9R;_i0WKB2nx1wl?!SssM`*TYgQ|MciMGN43P6xI+#Nx>iopE zjCC=p`Z;K(lotoxsYfT(@j{??feG^95)inq9Mei;rJVzH8R(3NOi$G>qUqo|Xja!8 zC+e%$x>c@Tt91Z#H;c6t`E_Z@m`WnGZ{lfF5z02}wztgjTING(Ff*k6nA+#UGY1gr z8?{28e`NXXnf#4ht}|=Ycu@HijoOw>N9hT-lR8k)+7Ze|>+IdawMm(G;wc)64V zW}6_>=;$arqtZl`F+qX=I{U7(S3#M{hZMt;5p_)d7%;C5if18+YFBl3K+fZuJO;BJ zvGv2XoIB8~GV0QWw!<~og+ez^RZcZ@JyNAqHOdsp$TMH*$n!*M1~(ByKh^5Mn$n5O z>PV2)+r=mVdLt9i4o-IRKI8;($$Z+CW()=1`v#bz~VReWv&_Q@MkOGX+L4lrhb3f;hk}*VIfH zEQtKt8u?F(Rk|RlWKm?5iY~*cE&fhX8ot;I)Le1DUO*owJo==o}XlYS(sT?uGr>`V$?ZwyeKH+ z9zwYTs}2K~U4nelXj*+b2OiWdF?44}wx){^&$Q!_M?&6LsNn-Q@RRdZdR=#!Lta!< zM0-+Zq!si$wlKK%Xh;VT{wEOO|036Slh0Q9 ztMe_dK$(UkUwu{or1ph^&RpuoRUJnV?NhRK98jYkp{fNY-LuVE{*J|>qoC)KvPU|b zL|yB)KPIy)$5jaus4&?xl`beV`30GW$)>5aR9h4swRYsRi+?fkv4Mde1Ewhl!eb$? zMMlUS$rqLpvduHiy9|>Z1)`0+%#TMc&t!B7=sxsu^KublTo#7GF5jb;s8F7pJrGvVlxu#s5HIt-jKWu$ddFmFM%|Pn{8OkV; z%Y>_GzcwX1#mCji6jE15m)%4J*O|0#ybCcQCV8W*2wx-Zi;yfnbhg1X#yW38@uBiL%r*$BETC;? zNH!%+txx$=E$Uo^Udf$3M9A^>^LXwx<(XekFdK+mU&oE+4SN|lPLo#UPt zuVoAz=Sm-3VX2UfH5C63t}~4elM|C{1@U6?nx@u=Hu{7;QiO(=<27}BlKo`{-Y$|b z>DmWZo1iNe*7aCHHO@jM*6JV#+odm^3^{X9P;v))5#DKP;I4}Z>k5-4p9v}+G*fj zCsG6q6Rguu zoi){snaRAVqL}h2-FM}!%0jJ2^;)e%@dC^yJgR&N$`5spY;&g4%6V#C=2$<-SL>>_ zlakTao(YsM($P`ZCcniD^`nd-B@0!bTk^^cDo&EqQF!RmDwrm1v#lZClA!qyYgOD0 zI+F?p;F>%S)Q7s5RHhDH_@+zt06jxinPa2}5B{`HfVI2)yol>OUJ)PGqJmT^5Y?5- ze02FP;5@8%!5me(UfFJ}RtnUcNS*cJgQ)snDX5f(LtKIu-53Y-x?A*=*HY~Zhdp@k z`Q$>bTs!{5R*=&4gJpi1&&z)}E2x{wa?bhB+(TMCdr%N&8_ws7p$yvxsSjK_bdfq8 zjA5>?@|cJ9qEdCcQuMh{baeS6Lt2RP8V-uWMA61TeNfBK(~YnCp;_b`5Y;f18-)#n zh7pmQ${(9l_F;{%jWly|Zn8*FQ6e;H3n%3S+W&5SbfHz1(f!)$>v)0Smy03SWe46PL7~+4{rJYWE8E^* z&ZEpimJd^|d0Zxg6D@Z@oi7$9XQYoz39oG%6&SI5$GIVhWH0c7sE%|DX zsS!}a3TpHy8>wDXHj`@8HUl~txt1F8?kB&$(m2ZxEXiq;Y%XJ{%h!z&hv$%Y>PZ2xm^hoB=_H`^kP&${9jD}A zhWe^)0wF6S>e}X?Yvk9_Qti3aP0)Uz?6wL@*O`V_A$+)o#?%I7+iZ4E$4lKmQ0qgt zj-hEw=lgVg<@(%EkCK^6R~pJ8n=Z@lI8w%(9$JN_V!05Ax=NSLS@E$X~bRoF9FN z!ijK)l2v-qgH(@69A&Q*4xPf@4B4`f7s`s5&J|BMNjF@j*HvZT!jox&lvR;Rz2+e~ zf@bwrn0|mupC@x6UNA)3UY&lRLUp^N$*V%hE2(7GuJHU=%H=vpw>zla6VJ$*w}z>T z(V7Cu%UixWdnb>dQcE4&a)Vpa&J4_*pzSMVl^mNa%Puh-zZKeORu3{9LiRcWJGI+c zJ4(<6(yDc-Yx!4~C-)&p2M_bKD^!D&fxrLBBv=tKtcJh6O89~6j2Pm|wiZl$b1_74 zohy+kxrGabl)-+G;1|<7HrsMGWdx&P6Ag z=GsK(C76yNSD;-M`eP%SuIymeQmyFJK~TH(qZ5K5`^O$0wEKxHbc>?BostA1E+utF z=b(vGb@^>f475L|8>mcBL!?62&vNz3wH?y52W}wHYb9N{MCzzfQQQs&7e7a=sRSOV z7)e)V3Sx9NS!1O*kyk2E;^fJqTodH)Q+nhR6Qs%>6cOXt^Uj) zi2Qbb+27~yH1eSfk996r$495Z)HsuKkqMpE2em@y9HIgX`EelJe`xxsUYk~yuHPy> zMJGe$M|m5yOs-e?9*H}YoBV8qX5@fPLn4#Pc{+dDCquLgfx|A%c?%QlD<-e&l z4MJ`zA26>O%7#$&sXC^0SfC~B^zg={3hwJ7l;FX`T3SaztFwIItTW=OKrYIlQ{H?D z^b1@kIRI@CL)A4YoJpAzv?n@{iRg%m!wse)L4tOHDV&jMs1OKB9_7U-=)xrA*U7Sx zc=|hcXhR{+qz#G_N`s|)p-%RS;@nBjvO@C z?F7{aQYOaa_B0M(Wb@pw!;aLcq&=Z}6rJU*lo?iUh?rtAIUkJJ-m44>f;@thq9qWZ zwl3Lo7wq7mbcl-es5&}>M(s4@d}Xz?hfg(x`vSU!UI28X!yKDr2JwLCc9Wxc)n{M>Z;(RgvdUqr9Q9~Fjvo#C?BGe!)5+-zEvGV zrm1V2U){KMF2v+lBP=*|?m5inNX=&iFBxiRs{7ShZXG{p>gn{C;vvhXvlmo7iXY(a z(R6a@_>~KVv`hILm-?!GkiiV}Y8%vCnqZncM)0HTAZ6c7a_IC`CmVAt<1nv3Q^X|q z7og{Xvf(a%Kpqbm_=1pw8vo8`=i`Tq-gAPui%g;Wj8?94?k`+(4{XW*ssWKdjV_9# zDnJ0;M-0{WOvaQEZRiv_&%wywwaJW;{Kg4agV$c@sGmx6LEh_dlh44F6dcND5K-uO z`*m6xH(*;$Z}g~%cLj0vGfFXyFW=UL4J}>Kt4EDUS0OGGHXh|)+Z@}PHehSlUc#yu zI&bmnKeZ(Q!dBlDg6Q&SndHv{g4`}CUd4M$k^HB#-evY}hpBLT**~Moy!}J{6RY42 z7xGR%^w(LP!`62+``A(Kc>wBDbfMoMA4=@Sx1n)E3%d5|A=0%~^ePDZj533VmyvU& z?D}-Gae_Ltywxh&&y#Xn^eJV_eAOM4wr{?@Zb{o~4?SwCz_&MI!`7}M-K$5fqYqOX zRP(q|WYt23=yW!VFr_)7ZQ`dXqkA>6Ibvg@hz!#v!~0R*jL9u;#^jbXl~2-G#?NKF zX0^aHeHA`+#BQM6gySWwdPuW7P5 zQju3qs!)IG`J?q|o$j6UM_F;yuq^W%^eY7$sL^vd*`PQnbt?G)0ebP)uU{Xc;SP12 znU@^}_aL8IcdE@P;`V_&cO{3i?x+YNzk=;HK$)T15b0XAvp^I{<5CKfkBoWTOysTSFH7KW1PJmp}EVxsffIp|7UZ#IP||BFI+pw_QnhgeW{ z{dPGmU_{!qAStD>`J||e+f}A0e09E5T~7c#Zj>w(A3(p5OuS9=RJ!PGU94-fG_tM} z>yH}uxDbUe9iQi9)bWj~Yc^vH=yfoPe$jP1p3OF+J^RCmw2NidWp=!5IvQ%*s0 zJ>GigS#jAibq=QNR2Aadw&*$BwRotwK6c+x=(_zq+;#N}B0c=`pT*Rk`G3h89A0i+ z`5K;n`W1Yzs?pDH*a^E$-5>i+8Y0ql%%|S)=7S>r&>Ja?J^VnmRyFsfX97Ty&Nj_!QJbZ)(0O5$b1RvY#ZY^oOC$Bfd4OTBP5<>nhA0@p*i9N>3DnyoU^8dU&Gs&6{xcBja)9_kDZP zJ+Am6Z#?SUs+E0hx8aSO&c;JyuMnvp9MG$v5Gvk>TRaJZhbp)wPYtR~C(Zt^evGLg ziX-e*GUa&=My1I-&?Wx~x%zNc_EU9Ae((U8QPz%yc=e<7;L5yJy1XjX4?ze1NwuSS z*R5~jrtd$9vA_9&NFUgXQJNjPAs%)69tZfg_eHyRUNtuzgPwsYJ$;GHZ^DWuC1nk= zWy)Vq27dq${@kB`ZTy>4k~s`$#hW*M9}i~i^|=T1M(Z0l;rkDb73trcb0F$JxC>X$ z9WK(JKVvF-GF!hnnWM9`Tw4nv9m{5U4=e=_59&l|eM9`*boN6Sd&LiMK(DA9?%-NS zQy?PFPyQbpB7Or{;B5$eBS#KEg+4pR$Z1 z1JQ2eJ_VInRu(xw*lW7f4r_K`OPKmNc-AII0#|lgnY7-&`S}~(dJqr2z9HS7FIl%S zhv4YR{TzlS!#C)dt3UPp(b-{tlts{K#Yl6yWk+yJ8DYcW(2q(3qZ8e`cSGTbZgWDl z8S>vs)1g2`3)BIxoUenbW2)}uew&(_1Vy)Q-8DQ+-n?TVyT!_g9_?X$(^z%_ICdxh z4|3ac3}`zV1&vLO=$@zZI;e4?EoSV%P)&@^3`9gzdc3AWUa7QDGL{8_c| zUY5FrrQ=!*8XKDm_lcCsbwYKEf@o{DvxCx7lT9=z5%|5xzZEE9bDQQ5Y%v&APx z+3cvW#Tk?j;D-8ytt)GP2&`GNCNIwxY2=kjiO^>d<+n!Vv&f)rGv0f`e^{z<s}{uD8aNu?x>a0X`n&lUe(Z7B`=CA|UA=h` z=H7M*9(m*IBK_mj$Ds#n!>0G16zPW^_yh~;C*tB`{fEP<10lA(EBHTr>)m*4&3Fu( zvyaFg*%eL*9hqm}Y=Y1jbrc_%cXI+RH}JQMf8V?PFIc?q7jfvo_}(EDC))qvgjT$F z#|>D#&lg3?b(}id!w3PwHJH2G!E_*X*oK)- zxon5tED$iufpZr0 z2aKhzNlfJj5>#HwFFD2pT^ND=OxuQizofAXN?q!%w|cFPx00Vctkpiq#R&dgp$_-3 z7MIsHJ>FzbvMMaw1EQG7v&sbe42EfF0Yf01jzK-yyg0O1U9JW_J<(5oLi+~7+-4tM z$u4!CizV}TsJoD2bV#+=JY+(=beDc(Fl&c*3P^A6#EtK%eM0@Nw&WhgW${LwH{7 zD%mKq{mg|D4i@TGLy=><+{wPNi5!3`2 zR6rheMi5ngT);HfQF(;tx==PDQ^9jvgpT=umIv7e1^KdHVhTN^dd$FAmv7^z@{M8M z+5v%XCLt+a_5j*PtJ)pVv9RMaDfkX+_H<*Lpj}|tQyD?+%j9%L=&>%o zhzW_WNRS{wM*(&GVY2@ey?kx*0UZQ3vHkPy#K^m$BPu~rGAD|WARi@N1~D>c#uAft zrw%9?L80<79r~)g3W=^=>#2ubYJFKI(=nEdd`$Td3XdpYp&wE#ioNdshUvbB?hG(N zfTRY+!WcBndVpaGL-N+B# zWL1>dB2+%8Xhtog_I6xD>(ZXxf9v;&a=pscSRq}YAIh&|ZRGT{vR7uoC@3zGE4K$^ zha}IDS{?^%XFr`(F9Mj{al05c6btYMz=;(GiM7nKqS-!Mx$@)aY1I0tB-+1$zPmA;$yY7QY8#loCm$nw9#9xYs)7CLc`L92F>&3MgIJOoa zzWAC*FW=q^yG@^saRX{a+UsXq<6_L8yFjEDZ>mD~0mCtF$^?-f(%?->6P7HPE7A)V zH=%CWB+QyTLZo|C!!Cb{=cUc^w_^RfkBF?s)4-Jw(2zNGTf_P<)@*tUL=xO(%A_pxm47Ss$HC(<*g?}px8y#BnM zk$+%D#>JwZC#Nr?&uRU;5998~-tfoBYqsAYjNfk@23ALxTS#WrtF?G*-Z~5#QzMce zzxpPYwe-U7GiQtRZe5n(l^5T@vaP;=yG-8;69?5|85=Z9jc`cgR6|W_8+Y!_(`56AwzSPyaK)Z(~o)8ZCWV zlDA;#{Pg-99IVeSFrjdJ__4V1?O}7CJq#vg+uC>W;=FgU76U|j&zWOU{n1i%n=)Rc z2eLJ3`?MZ|#`^wk(fqftctbUYO!V#3)KNX)V%-b3k5v0z((TU@x-?^CH#9AJ8Lu|) zBFgvPqi;Hr;92|lYV)qxcjCZwP~^AM`0-14ZTs%ndvq@cd2==?72(ZVeET}Q|Dta% z-d@8naNJDnQT2gHFYPup?PFP5XXc6Y`XQ6hbMbSSx6uDg>i8o(Teux--}URydv`6^ zfITr|tUt;hF71Y?;|E&DJQZ4ZL7F?og5KXSw{7zM`|~fnj+L#wF?xnS-+S&D)2qp5zFNKc$K86$;J^zEwWmjj>dRqQ%&oY28Of!YW2oAG}O)BbOHOHaxF zEyc?(zK-Qt|F<_Lr2QXD$Dm#Vt=qO|Vo<-oYu=uR^@GNuc99={y|s7)x(u0!*;7XX z!e09}b9-9vJ?q&)B;~ zX?xdW5XMfQA<{c{-;VW*-ozX4FB5gvZmGebwEj%rt+y!e68Ms=K8F2+_{>^s8(Lah zGjegXt$ka>Js!o_+QnG#)?#d^_CG@|VxM%-nKRLz?#&f?=Yj3y>)uDp{8tZ8@pMmh zxe9V?ooCaodyo`@Jw}^I2fo|$+a3lCPy6l(gVDe<@wgW|?NNut3;cL>k+2Q3({{4UJNP!kgJ(Aao8iH;8_Uu*V_YTxZEIYF1#@2$`w9=i-ePb~aAPaI zb~k>67t-t2L$G$o?v&e~*pNSe>YGQ2Gt~4t_VT>7JY;fDEPl?nZwu=t;JDe{@YY;k zpS-=(2kE`jinLrFgWYC$d#4(-t@qbsFgK5)uSgFXzkk|ZRw=DAQeHBK)#++hf7a*e z&(KM;F=b>Ak*-c_q_8Q2{dmsv@1CumkhaqvM%I~67_|P|`@ilXmDZJb?b)@WVBkK% z-Xn;gpTW|;voSdnHw3a}z3A((2TzYZ9X?{Oks|F)H}w#S+P~6*S_d5ZQ!-{u z26@a#V9M7NDvQ|$zh+m-XwIu(jwd&m&O-$<0XpE`9Y zRXdTZg+D9Te$buQlxpCph^4~UL7{LN&UWcGWuxS4HBYV?{uH9DztsJFu4%PhKnay# z2LR;^D9yC(i38G%L!{y>m8H(ibyAa;paXykQ&mvCCrWu0t1@%Iy<*;m<(PpGe5v4B~A|@YGEY zi}W57Ct*lUm|JSqn^>@Rg6P7rQ+okiIU?vb4tr1bzq5MFf@L^q=V95ynbhDJ*mw2c z@Z5)=66sO9cTLxC#Db?6iuCvcj={zkUywedfXLvfaNz6onU=Pt;^(RBuE)YXC*y#b z{>|^cEwA9_i=M@yKRQ>W4;`=wcV2Q8mh5+;NbfT=h4o85z|u`V{ouMSc>U&|;~!1_ z&H7_z_QU$;{(wv0IZLE3IBicfSYm+4pT^?b(72`9??xL#ZEa2Zzb=`vXu-lqZ^A44 zdWYXUedENxG19uke>m=@$Hu2`jtv4^`iw~5c-JP3sq2NEr|l-v{nLEfmOhQ^Zt&-4 z%!GY0Yr;;bdGk&&#J_lIB`)~M(HQFZt(n3;`<24V`M$jGHjl!nv_gLT@NY!=vK2qT zCC85hU;30tdvcDMn3i#Tf03?D%jwB@%|!=`bmNw-{utHxH@9kQs>RKJ`@Kd^ra7k$ zB!KJ^_SVv$ugBtX(?#C?Gsd7{>BIQV#gB>Nore#=xS12td!s-8*ZuT8eE!#8#Mtfc z2^RnO=UNO;kMEG+VU{iPao4raVvmdW&9o1t&9DqyS)1lh5Cw~LEuQ|rpNPvlyB>)X zX7|U&r~fX}kG|E4;WK&m;jE=k--L(un1D%x{hOytpScltZ61TVp8mrX(?<74T^D8@ z-{6KPljIEdk3Jb`U3e!hxq317JHa21p{aFP^1%{p+H>otAjFK;}a`MVG$Hy)fGOC?R~KM2*y(53TRKe`h? zyLz!m?03RG7|Q)VdT2MWgFNHiiVyF;MWi1+ zcrQ%ow;8YAe33{$cj%AtgF^=SkJ1V`I62;0{a5>`jsxF_S8wvx8S;4H{;O3KNsoKckhCx*YCz(=J_|be>HnI*wi<= z{cJ&FQ^tO#Jo{Ojv!7|bS@QH>(>ncvn4-F#J7enF*RkIK|K@Yv`fN(C&+Fv%X;%Eg z>|q;LzUteHceaki&S`tN@S%)7Tz(EN`Sd7Mt@9sdy5^$Wzz;nhGyC`t0GL2$zY9Eh z{bhLV-61&R_rAXx&?Rl3uDbyrkMSRl+jrIk>{Rn6?)rsqZ&zLL6CCYe+|BmU)Rm=~ z_9x`pul3r0D%<|yn_tJRcdQjRdPbjrI0j%9p8v;nqWmA54#nV~pN`$T`0>UYcmD-1 z&Go4;kzIb=Y>G=J)0jM)eA;oMw zly-V(ru9SI{r5*j^5DHDpkL#B+V5)v);G=o?m{a+0#M)d({ime)(4!pX{O9n_uDorit`^Gj>n=zem#k?{Se9 z{x3b}f&aVqr|%2@H>EZckKObT_Lwj+9fSJzd&yIO#$P@jg9-c266py$)!@y$evYSB zT`1B&IeI8qTKE5W@oj#05Ak*XskGjEc!6hR7>5)7X(+B=RPPe6Fotqxo zL!>889E_?ZPxB0lr*i>HJ5%(v9*p8q2*zKsjL^U^~1e)T%u8+^K;|NWi= zte>VU$Yx1TKzOv=2oJ#H}SQ@(!-Y}3B8{D(_-s(DM;2G1^d z$k`^Je@o*QG`FR7rKU#ANNxJJOPVCL;T2K-=bznz#=VcmUW5FH@jkxiGCcV9SMb9V zb{FMTY%b4p?h}yQz3&;D;o;7--8epDGdy^9WAGWj$DVyx_~n_s#lA!RcGji$7E985 zi$VP|ZFp<iiW<<;kkdGQd;jkibf;LVLK#*3tH z!NSb$=T!Z96LcWefJ7nyS3zBRu-o zSH<-{GXq=XKYY3PshjZl_{o?wuwL-+{D>D%dp^X2=SS+gX5ub2)KcUCktT2E%UhUC znoD-j7L6F&bFm9;AK~7=`R5G>%pQ+{ZEvOLC=-8Ncp>HtVQBRHQ5rx0hvJVe4g8U> zsckFg;juuxic1^j_<->X4kV`OdrJ_ z;H!$EyO~WrBt+$_Y#CifClFOk`HSZr_tSPsv_c;EK)^ zCSn=;B~P)c|K(~say5f(Z#R_dsW$4tpvqeZv4DCwL)yc(Z@2UPR_@^|CY7k4dd}%C z%d01MGo0rlP05#RMT~oep+m<4Cdl?h-Tg;dgp9b%?Ttg@N9`dfGiTUqBuEfDT(>GJ zsPL8wyJg;GgDgPIhP~6;!~_XsB#PdtptHx6{pSQNb&O%+W0Hg7L+yu(1Sgud!PJc| zG6hdL-Y7}=e`$K(&%cVtyM{&J+nTX$^3)8e!jE{kqixfAtnb-hl=Z0w(S9|0_4D6s zv3}jgboo$eQ`QgD_8EXnpM6K9PuOidYBs)vr&mq!)4O)X{g4lP5g9!ACwn6n5pE`R z#l&OJ#F4uN&%{l^fDPy2Pfz=AqB!LE%~-v$Cq`x7tTT0FJ=pXdo3@ot;r97s@!4O@ z5$Un%dlGzij`z>@-`uj`xIHl2^0Zd;n_+brI^Mr|Gpu1gdQ9F6duN^=;CxG{e(umd z%RN-SbwvaA`PJt!t$R+!*7SX(RF!|Ti~% z#sACsy$7?*7|`tk;c-*@5zbH1^;2n`n&aOLJ$$$Hf|=P1i=Y34U*m{#aP&A&Nrnp2 z^)LS)-d&Nxq|yGvH~Y3+i{};}ffGmie?7i={&RS9xBYQOUnaFrSuB46$TycW6%f1? z3z`G3)Us!A|3|((_}t}3W1{z0{8Ril4Q+n=HLT$3n;2yMYQc*7eekQ#`-{R?Be#d) zLee|l>}lPw8XJ4;jB%5Ec}J#i+Dw-uYt0yg4X^)Q{9bcsSDbS8XRwF=A`!H$dJ1>U z-vgih<ydA&C3OxOOBM$AiRis~gC53|z-wChJUnClD9X%W$z4abO zOz_u#y`wIvX|tU57&>8s=VbWQ@66s^c*TGxO z!&`nV(ibhwf54WMKVS25vlGq_25$Ar3yN0Z-pC zU!=!=_7|Ar2Qhy2_s_<|^N+*W+5W?po?kviV(6m86#RmI?#PiZ7u`@d3`DCR)wI3)wI8WWtP6+o z97A#787E8irlJ1BCvpEm|ILSdME8trx%OmHQsQ9{CCzj3*)i$ZXN(w>2Ek$Rchd1$ zI`$ddbA{mf?7i<{@>##e(c^94O~Z^2tLZLk_lO|M;fJiN90r}Vn@u>Z-sSl`NL z^Ev9$U{W34vI6z{{0g6+);%{)Z7amS$-~6-Tpi`bxNNGJ^8xG6!}o6e5LcYy>*oY- zZhA}+^WvdO@K)dI8C+-hr+7#x$avM>0G&?7=TO{KNtmfaErvJv)xI&{g1 zUayLh!_D5YMe{>EWk^E8Bumcb>uT$&s z;ZyhFQuvaM5hBz?>^I9?nzc>8PVsGOVp=3NK3e32sjLUI zWaRtt;&|x>wNm?EBAE2lWa3JW+! zs-G2|W;}G-C6~!*nMQRMa+S=5`e2sYgsy37jVC&opp?)VR%%Ju;v`P+;|fi?Kqpj8 zpx7qsHbJLCqR^cNy7M3o^E6XF!nQ}DXjGomH7xltnQ_xz!sfcVWJ@FMNNlGD5s?Wt z<6fTeY_ilqxV%QBBpXFnkkecOi7LV_^9XVjItGOvnwk#tiM)cxlZt+G?Wo3thh%fH zq(FO2cInm-v!o@ItJ}8w2s(OVt&4;4s{AtbtiUKs*%77lrIo?`@Vg=m;0}ry#-7V} zli(iM8EGOe9$s)wkcWLdPMwS#V1}x4>Dq~pdZ=S!A7&mA+_9KCT{2gR&vbGk>3%}X zb-CGd4?%qYAQuMOR-s_1(%aJI?wx6Yfhem?sA2X0XYV=y@5?B$QABp@g2F5NhZILJPeY(`}5w9XH&2@4ntv|BN&(FMl1OriDT{4wE)@B66>^JL8Lxp=Xz&5vNja(NP@WM#s z8k|Lsw@wFxJZcHNX|SG+s@j^p#%MhwtB#_^igDH&44;Cfv7Rz5iec(lJ7_c;3!0$r zLFVHTNf?B97bUTkm#B;LGj=q(KHmg~JgAn#_+i*>E-4Pv^=7o)z^{W=OY&aR!KS|4 z1WnKcjSWQm<#f!WeUVreip2bWrg$PPq6l*vTRiM-)F(AXxJXV#HpxNE*RR_3|21|E z&(SwLfU|l!NT7W7W4P*jo*q9oOMbqP$1}IEYmKO+NjdgZu=t+) z!yst^Z~g^5mXizkYjkA4ly;UuxHNigJM~7_bO^t+CkW)RYbDwQO??Q2Xui~x8dOyi z-|ZA%-72tk9y{sivzg1Vy<9`Em|c@on$a269RCKNZHy~_tY52ZA)Uu+R99P4Aa8wAdw@5O>QfS(=)M}Je={geVNaIHz zmW~I%Uyb8BuzTX>&s>Fmhh2+D|Y1fpzrOHO%hrghUX_? zt3$ucYT9@ZoqBgeI%4d<#QEDgZFj)&IdG*Rg9#b4N|aF;m8&cgtjx zJ%aG|FYx3e8z|oFynmn|J8}X|_0|n~e_f#W*TocP{k05x%FX_IAncS!ipf(zArBw* zbfUy*A1$?$)X@N=p0tifvy<0)w@g95lYfgA{qb47NDdX5RSuK+d+5zO| zF@CKpKZCjLDW1P~K6X}w(Ir)j9^|+YDBhD3s&{O{R$X@OQbaoJ8k+8f-SEPaH7M`J zPJWzQ+z+QsY=#YwE~NOT6M&`5TA^S{wnYG5l8(>Du!ps1=(LYarwvHA#={`jKWFOw zvttg$=g(Y;zT+#j-h%D9J?*QZnJs9IcI}u?W!nP6 z>eH!L*NDzg0z0vJYc9Iy*#wNy6>ZwJqiE75QwQJ<_BB|1|J3}-I|sRK`0*%++;;ht z)ZY0!L8?R8u#WY|1<&4sMM2mFmF+1<%bxpnd9nOk=Y4LE$wrc3$tF4`*KjA55Unk8 z9OGXKQqA!%qeYN~g_*t?<6p5c{yB!1$kk$+K3?bLw?UAjuZ2QLsjf2V8@j&@dEJeZ zdo+5z6%|dJe40N$$aFupeo3VI%#T-=*{sbR`Ggh>?cX*a@5 zi%GB(db0^aL<tZjXP!#hCq>SV)n=mu8brdJ)3h?HaRDs|YoL>1t}>a$F@bTJVn zo@5&qWGncI(qPA6g~lv}Isv|esXmZ5ph%qV1aHsSJVm}?3tSxGVl<8>;Zno#P9%7p z*i6w>H^CtUs>XF$6jgpKnIt}i^TV== z5`lGyuxz2*@u5Zh@FMxJrM2yhjur3I_m$gf(5s!W`6#>#t5+1$*RDtAM{f{GFT|+c zuhG}<=PpCX9|9Qtdv+~|Mn89gTU!&q7kkQ&2Vca z4Ux94DreUM)ewumNhhGuU&WIs(yStOocU3aK*-NhLEhUnMcp8)ke#<;>Fc=fO;(2s zue%zBEt62QdpE>!O zTSFrJSUj3vvDywFkG#8Q;+Kh?DgNW;L73bxEy9;mR8dwVOo)RW`(rQPJYrKNr69So zl15b8?Oj8os;fB}TKrlzh<&d|AiyoUh_pp9X%Rjhwv#wF*FmhO1;Li+fAXJj?_~Bd zcJbG5;^{kA;oLhfp?HB&RsBQZaaXWwkv@I?1x)XC6~?s=GFnN=dVf6@*WALcHIwz% z>RpyRxXr1SJZhZs@Pe>c-u7*c&&A)og{SXe*M1rG9N20APW}_S26f7oMfm#7 zr*P-0b1DAdZwo1Jl@%3s`ILRL|Ca}okQ@M{AEStqPmym~coZ1Aq?cV`ZH5u#o6)lX zx$iH<;)UBNzHh(@=+HV115%!%_<{u~_$Am6=e5@Sm518d&#>_YQW&o+op#dZ`sZEx z$H57mDgNW8L6~IpPp&^Fn%9aYujAe~*iz@!1)J$9GpczDRN);+A z!)AJR3|_dpCOW?t|C~LfIl_MAZ6vDH?SZrW@=CV3KA3E5Z_;^8>q7D4{`^-=kr>7D zr7zN_p@$cmI%q)6lIL;tM?@H3J;p!NCxP{sh?^zpmRsB3&;*$}@>AVU*5zBp#pw`c z@~yGt>mjBv*MHeC&UPlKhit;FXr(0n9T=M$8cvHI&*Iv!+b*tnWEPnoK zd`u#B;m19jS3cfsd&1#F6a6#MpGcw=NlK|iMJ4aw64X?O?fQlN>Yji*+Do2^la!u5 z$TmX{(8smH$y>2VAGZy7>JDS zA;J~9e{XE)hk_oW>Z-2095iDLtYYJ>(|;h;ZZH~bvkIMC+&dXt7kxwVH=nwL&Mht} zv=l&`pXhy8*SA1Yk}0kDY@grp(eSSWf_DR0r^yFUOlAAiF|ei@k0JK& zsBY^FAP!#ul7igJbCV~vt=#y}j{=VN(w97v=y*hM+%>mgN>226L@L;3?bq&m6WWE> z;_AXy6i=>MjOVZZ7?wpKbe<95{0+^GJNw-pZxadP!jctiZG6$xS$q>$&>)ac{S;Xm zG4R}4wUULYaMcQ8T>z1kr}~N$0ecyt5rb`B{H2EPmC~4)@F3d|GOSgZvdsL}mBtFH zfx_>yx8@Qq_8TbhLl9)5;j7(9svogv5oYc058zoQLY%XL)&?$~rf4ZO$i64>8^96- zL@2Zg4pETV6b;ed5`nbCi4GO7v_w%%V;ZlTpa~3cQSm5u+6r@84ti|yH5GkF_NVBJPd$mXT~EWUEzJoQ_tDdO?q4$xtF#`J-rz3T z@Pe@L%ki+EUyhrL;Uv5UbAR4}iAS)LQj)5+VD_vH=rOJ%jZdyAM`=|u(n9Q)ym^I_ zF?Hk&yu9TA#RG>8K;hoE@$E`>^37>I)9DA4sxtO5l%%F1Mf2i69EE%HpG=!Klv09y zMf!q&j%J5vWF}$jCbk)(YH$Z6kpoyXcNxPmIO+p~V}TwJKBhW99@=sv;xt<1mxYOS zBd&F0dCGR}KuO!t^t}r`b)gt57W_g}l#tFK5I0vi7yEggC%QaRsEo{C*5@R{56Jjt zDpPqRT7*W)8hdxN##&LJnEr*Wv6by5J~%962Q@@XZd zx+L@ukw&0h5A@jjHGQAA^>9qdOGbD0WCCIE|&OYo3@Cl z2Lhj#e8jXoop5<6s#4MsO3$Nlg_DoL$nXD)EeBZsetQ03Za4HS7)kMVCq9h({{1OB zUC%aWweQql@2~IRJF~x@+B1Xo*HU(JAkxy2GS=|7VKtoOlGYVuMm9eL+rMm*~8MD(G=_2T<1GngcS>!JuEitq5iSFL+@S`-}c2kY@Ij- z`R36q2bRu5k>t^Z%M8uJ$Ir09gh z+ajrY2j>68P9E$&q9aHkg#P{aQv99oR$|<#J&|s03ac)ImXwOJoja%vHuSIy)j_s7 z-x!yf4!YmE_qtT5cOaqX!mttl&|cx6f&QqywLfAUm{kNo~+Y}Lo^fuV@LP@ckeZ3KOa z<~BJcgpz$sAB|I2lk{b_jspfzeBawYV*TOAqcc0m6s5~&Vs5w)zsV0M>4|l9;KX}u z(b{wVgKjr0n_<8L%b%)Y_N%Ni1!<}2$n8Ig;&g7Y^#DkLS>Kv9nD_HeeSXrG@^AFr z1+zEk{k9X0Pm0s_`JF?G{Sg)(Ud`&K&z%m}=T1r0Td2!7d)7uece0914zaeWHf=z% zkJ+$#jI=yP6~BW0u*VkSut!e&5r*p&T`1CR{HFca$^&lmO>!o(l9_+Dd3!a6bO<7R zfca;0mg)L1hzRoq|Nf^_VdxdBeH_8u}EH?zwuujAFMWV#0NTIK>s}yfBRc~ zJUY!BkBqjfE=4)fZAd9Q`Fclb4n}urq4#-Ke({P0_@zXjHxgoRbBOjgl-xz$takR& zSJ~neQO8qM^6q<;NLIcFIM^Y3vG9WruwXB-2?WwwphK_06dP994jJ563bJ=0KKO7Y za*jHQ;v;f{4%!uKzQTLkd*hT*Y0dfWg?uZ70q_AFpOJp8(H1Wp>B8~stHWS1=vQw zo@0;3qyage>p9UN+ipOFI9np>{zu#HL#)g_isn0Mcn%z`QLzSJzPBBHPGP4s=9?$d zm2F|Z(AQth!Y^BjK+@R{A$pBC0*4Q6ulFsc>$~Q?hmRK>0B1V+-~B<$F2K|ihM=`M zH!I&V4_|%tBc(}`XXH|vM+{-7IHy?~B=<5~_rVAAVW^!JWOLVMc|9>?KR z-5JovorocAgchk_`tj9UE0BM}B=pX3amb<|j9v5Jqi-Moe1Pxauw<`gu~RP3KdFn^ zH~9Q|x>Po|I_lI>`ns{|1)xZr%M(?%cl7lG(n@7hvtnQPJD?E3SR>%*H3BTWDzuzMGD@E4E-iVe)O>x)b`2 z8ix^G*&1qGA0J}^akB#typiPJ-8z#oPuPh$@BKirq{EKGz?Kmjq2~X*nb8P1Ed$FbCHBfG@w9i?#a#l!aD3$71TFfoPi& z*>GjCX>F;BSUrA|7VOZ-lW=LQZC%d6RHP8^5DJb?>Biak;w!dRwrWQ?QU{%iOONP8 zaihCc?OuYfKKYj7OLSi@tK&c%e)L$1cgytA!>Tu7#%rI_*P;>U;piSANBL!&X5!-? z*kp0cDI**|CMD(TG2`tIFncG{pFWdL#^gTD>!DvCNxtfh31{mW=5*jH;bdr>B((7p0|5GSFg8$KsIOpL({7xm}^#Wo+JQHl~ z_Lu+t12Z~bj!T9&r+D?xPvO!J`s1nFkEE%a$2y?!8y-|~P0$2Q&;*SERNFU*B;I;z zk|%_C)#fcRkIX~^>Zzib$19E7GK&YOhBx4-v2d<(+T;lxX7t3;U zwq;%?@gfeVDyW=vN%AQ0n*0(Z-sp%>*YxYS_=d}``R=HR5OJfl2@L|C#=7x?yEjyO zx;*$+K7Y(;F~n2T7;_zo;ynQ%G52=30h}#Qm~TcTk;ErI>HsB4FCeNA0;P*W9BH{t zW+Ejbq07CB!#m;1lV+9q5YmcD5)w&8l!WToLX-G4Sy^R8TKhfT0!2dg2(@x|hzG6& zMTzF-)F?HU^*NQE5;!+xdV(c^+BSg7sF2vQND}aE{Xe4>FCd=wJtauGMjRG3Nur)>?KH?i>fUO&Fo8QRN z2`)N?=&7d~uTxO@9RBq>W>)!bqmo-ww`zhWXoAKBDx0K9;$;rJuQ^tn;Y9Lo;a+2l zAHGye+wjMlrpTSdr}TC5g>dae)X7@*AC`dsmAv>XY6c;6Kj~`vcENiu;_>S~0$Mbq zc%XPMYC25BxmO=g@$M-C4U^xLp6u6PBa(l_-q8b)Wi4*5S$}c>8b9VR3p}injD|G zq_fC_(;sfZlvw=9JP@8|Gg@|ChSzVmvkE3)%;zuA_uFp&2F;O-9;4XFY(2LTr+%5I zQblgJAU2Qmq2*%8xYl^!;ae%by8S>ZqyFh0%U=?{IqE`UM?zvV0$ zUWl`o{T)xd&FXX483S^d4?)YGaX zjSW{|)!Vn>xy9_Hzcwv`DB2T1;aR_r(AU~vSl1mCf9b9}QK=PSM>+dt`{T~X{FqL;=+mbN@5~-X@zXj4DK9w% ztbbR%ISsvz?}(tF$6mZTQ6KH2v0s-D8OvUIMue$(|QJMBjlopki$`scViy7)TX zM8zw7=u%dpZV#vZho-&l4$B@6pm>k11bg)1yTy>xXxj4@J&gNq_z}4+1GLYkbj(Ly za9=`tuivF0}62X*C$Zf|?VyiUe73S*aq?w5!r=5pI53}+3 zh97g#Dv*K>d3h91u0eEPld><4wd{`{Ur=i^6kT_`MA5tdUIFdEPU_}G1Fea-*g>pfn=Jmr>=*F4%+Q0oUme# ze+Clf`liWt7?G2uB2^W~8*zMzyzka&wj6T0uJ`|<_`Rm?8+va*zN!0u?41+k^py9| zMLLGP`|Vmh{V>yy?=!OzC{4lL53up2V8R%D{=(mI$2V-eLQ)Tm>fZxfIe$VN|D668 zvD@0h!vfApij#LH#hLEitLq)JcP(|@>zJ31Wd0gYE=L8DR#^r4_Q*ShZexy8yJRG1QcgR?@e&At>-MYFR1|EAAPA@#2 z;+JlC4p05{Z^&%H^m0#84vxC)B6Lr(9Wc0$#v}^&YcmWm?8c8dy3Gi6qIhn8GPN1u z3U;mWTeq>fMT5Q#O@pJ+{9N0 z!v;gt$w(Z6o$0GFce+cTI~nsP1In$rlPTBSA>(M<80}&JZJPmUaLzR#X>TX))HfpK zH#$8ZCG;2N_$~pi--{=FMfFdfL#uvzpPzUln@|4hzMHV1U2|y3?DUzQ{n}y&XWyju z&Id#d4;D`fI@XA_XU?m5{>u&6QT-o^KbLghxa|&n%fzdTdK3oq*cxTOt&uhVTI_`}`xU9(_4w_^6J0pWU|wKfm-B%Ky_T$K#fp zPqj}k3h!Tr&tH8G+g7mguR=xrXv~@7X;O;^yjmX1)CM(`X1TR@j3p$vd{6+YIdsZK z@O^el@v`v~aB`G@2zGt*Bz=2qepj4y)Ks)6WxoDf|GEL2{`5F5?Vl#dn!sK1!~^#U zwC(i%x@`qTGatPTQ@E4PNaaTS@ZMsyI>|a&i=gP|7jVPf?4+13r=E_(rnJ(>-Zd1T z@$z5r(ZcKS#3ci0KMXZ*k1m}{^)AXz4gU6-_dt&OEhgldr`o2qpr>jTFM5IEH{A6T zI-hn1CQM-`j~R4lynH>bS#UkY@4HxE=hFw;%-&Hskr z^(W7!c+%E)@xs?bG4QmGRGduB2+Dr`fXeLY+3oSb>9O~kl;&*g>D;*`t=qTHvXi!G z-Esra(pzxy{Rk^ZT}E5;$o5ROT1snEo?+~t^$4zgnynR{c+nIb87jfH_3O=&G+I{Y zF6_!@T9zq81B|l1o4poe`mvKpx_x&Oo~Sqv_x5RJmcNO%?{h-?+G9$Uvwe+|wW>FN zjR$Xin#r^ODL8)A;ku8<izh0`WhN^EC#mJ$A{uY z6o27{yD+=+X*hkt6pFVB?#G%LFXQ@a7Si0;-FFcN>Iz8qvbCJgzuAHj=Zr!to4pWP zaHpn(w@<_Uw@*WtOMXM~<1^Rdy+{6r-Pb%w@$-8pQG4`3F%#$sBP1tlkz)M(0-Fom zJ-ahbJ$(YEv|_0atoa@h z#b0O0r_{JKJZR9&@Y>hefTD%Z;>JfeW7N6q6v^Wb%hr{yMWl@@m*T(r*tYAWD=2#M zxHRni_F4Sx-cm~A|L!OZ73k6tMKuo|Hk)eY&VUH*_u%}$NE!p4eCh)%>)ny2vCFFmu)XwQt3LMt}Upmx!KS=)*+y5~ubleMfd!~kO)IX;VxAqE)Z$a%d( zXmq{R(Jk~kI_y8IqXCYSwKPdy9w$Orz4Qm!NFxI_jpZ&v^=ylH@F)GBaQ7H|lAu}z>*-)eg<;5(%B9Mlxj1_Ol5B(+VsM4|`T@Gp4NK5wF%M@V9$N)o5wv1fB;M)L;cY|-5 zzpU>2UiHe?aLa4#>%$*zo`Sp>&bf|T-X@T$QWTeKNY7&RPhih>KyBn}T+LNn%=9~u zmW7N^90!4$_peqIm+JjB6`6XUru4*QwUkG^?P1i>0HdDKbtI@RE2cVJTp2)GRt8d3 zBB;@2RZ0-bWJjm_?MAiMf6M+D_pGt6sycR{y-I zp8BU{4~zA*saY=e(74jGnCi4)gEMO8;E}&9#$gZrmYU>&{%(Qw1gal83-jig`Z3tl zkB0V56p)^7=(DEt%lrh!ujW0@nn0?|{#cft60r2-H3^7;jG_DGnr_c)*i|Nm?vK}X-%IbAd~2c4#I$!sy1h%& z?Ok$2Xmq?X)htaPM-m~jn80YW64PG~Wuj)z!}!bM!zlXDZwH#Xr~dMjru(P!Ih!>| zw^?OnKKc#sD_S3Js>}5;P45Gy{$$o-TyU%h>f;R^4@+wh%3w0K;=+30EvaBwYDOv@ z1O3hw4ZWCe>V%OeE`LfdJKbCpocF|^oHj%EL&}Rwn7!5^D)gJWms9cv>CF>Pw;&^2GJEbu7PwyK6)V`jU|7+;sn6YEs)Yaso*27m!uyiTg z4BEece^gXd=>ORGQ(0MoEnBwO=?0kB!P-!>9^po2MSuFXC2qOr1kRrhWBu!Y z#NUc8r`R)>^o6l9Q?>kgieG+DHJ*9lJk0smZz%qHmxplQ@wo_8ETE0?_~q}RveyQb z4riM!Zk*5zTE%Sq>o;uUaJPTmjbq#T8Go4VTJfLD@KEv%c;xJEFoY3|vPXb?^^gY* zUfNk)%r@I(W(psYjJEspfC z#M(2Sp!m%bS~|E3@1KQ-u6Q1;Zhe&E7xYYK%R@D6Bk{{u{sZA_9>aOvxmj<`YP@nK z`{9j2_a=cRIWPKmPL)8vjQ32XX)Lc`h4C#V>>s(98Vql@GA`>vcQdQ8%k^ zJVW!_eIt?pi=Vs*|89N<#r}0hXZQ60U5@|NWk~dL3}A9J_+lGY*Xp``SLu~_@yF8h&003F_SpRPb@B_ zBO_Cwy&pe4&o*Oh8hH{@U%d?*&v=&7zO>N&60fi>=gS^S!VQm{L-DRbf6L7DBZm+p z+ngoy{P-Ut_|Z7Swnp34we<1IAN~(j`o9Z$$}eCeJ3q$F*KfqxPhUz4D=_v2@BR$8 z{E=O=dFu05D(0Dt#|nMj=$7Y#7~O_#PFXtmDcpFN&dY%xDgOL3n=sE4J;eMyNSEh@eg8E_`~|zp(G@yC{B6 zj}+a!{-o>aMv9L(ISsGfwt?!Y0it;z6|3;tEzco1x(&tOTRIp|-FO%rw-}pgjG%y? z&ProIUF<=OMPF;EJxj)okFd?;T>}Sn+xQGNj$oTt(_Z@}Sojszw-}FM9ogD{)$9jx_6Pm( z^zBDd-18blx6J{f?P!7~@Ck+=Y(Qp4;~rO;zuv@SeL}s|$8DKaW#i&pl6Cmwva$gG zG*!IHcsAeHtzVBUa}3cmeZ~<8u&05W?>0H(hw|aD<6r{gebeU6Ho+vm5MQT;)HMWB zkdd8Yqlx5)lqaF%@l(-1-P&8^O*{6}YiJ_&081N4VGWjP#yN8b^lx0*^erTfXK4&b z$;d*AgT4u((;s&78yEkEfOLh?k~5HzWGe_OMoXse=^06&C#~5VwM?#L4M^%V02 zQ<=TWPGwvvN$MYg+1PH$7rvm@`meE7tMsho*z&~z@!J>%T5>wG3oNs=jqUoEZ@`!D z=>7A^`1@ykyqfkfGfPgVWD|X^+L401cCC?)1Jouj|MV-Y?miCZ24ib~FAz`bBgSz* zKF8~ZfG~Gbi~-i^O}_a}GW(;^45ZvSl)BO&DA~LUJCfN+TJ2lwj?IDPnD#Y0O``kQ zbLlB^-s2Ii1$h1e60^Jmp$yx{VcbPSFeL+7DG~miMI_le7~!LqK!m3Ou{iz3o3UzV z3gt7eeQRW3Kh=8!R++l*#b%f|f1w@wc<*BGjPc4AS#0(qeqe=^Y|?cvB^T{ln-d~k z_dfkYqeqtmeXFUTUWM+p1+VU*w?WmD>o4hsNWF*sm zPI&XA_uY)7NbYcq_L_)zto{_W8D(aE_9sFkNaq%zNCDD58AxUAm+6v51$-T}c3f2$c7*ZII9I-1l}t^SKZV-jE$j%> zT*(-|My5Fjv6944yb@yZ*JS-CW*`J%0auk*TL|i7R>WjP+s~x5Ok{I>IQpwVOLGYq z`#BVO#djHA?@-$h13|WdVDxc^;ko-~VfAm=W-VhIiALJv*ei~s_&@J>2Hy?55ffTD zvnN|0q)W>YPD^*3ilC+CATNC_eP6$wU`$sQS+nkId{I3f*B>>U;%T2gi0?KWhch}` zn_6T*=pq_rImzfqDd;(X@w)!IUr>Bp4${`JjoR~bhvAm-nYi^kb~0A!VPlZGehC)0 zW~b<$&?+FMAJv+KZ9v?)tpvHlS_+$mH16rNTh4fylM@dRbU5}3N~X<2ci`#o2I3~M zF-)l0x&U)_4#DXoS~xhdIcqiu6NW#GXXdiG!?``Wc%GZ+ORSe7kB8 zPW)?UiZ|RwEr%xtch60e3Wx=BcG37Dr;k93Xa&TeiNk63ho7B`&FAz$ zyORAh>OfKp>|V19dxOjw&uyQ>d^4~g?rmPX5nYFNa$IGR)vY_4zq8uJhr$cCEu4*= zL(ZV@Bcqu^_TUK^{xI7NHFwiF=+PyHpZ}=_twavFS~Cp4=+E?ZIN60yovyztW2HN{ zp(J-GS_Z@zjy$5{G+~n#A0}!6iApDi$37O1>}4b6?4+XC|Gf<3{&XYq-(s7Ems)kp zW+xL}^yd*EyFOucaR`q2&IQLFh3U`!4Y$>>$dtmfaaHqJYx`>fenP4tZU@QDnLJ3L z>X#4c^MlZ7xP3$>*1vl@#UGl}8bf;Odif>W?0?ul?!r+g_rzbmUQY4TdlVu$d$_Kr z%wHqBK2^+L*j)FQ*Z+-W#WDf`0sqxNeCxiAZ1SQ~ z6kmC@$WxPOG65W?W$|DMPt5E1iiOBzU)AYk?@@fB$uVg}km&WBx`d{sh9)?upvlfL za9f3KgrL|<+#nEN*+haL!q$^W{<$S55*I0sBE{klb|49@g+eN|SezmXT=o%$2=OY{ zwJzH2Q0ZyWAA;hh;u@oxI=Ft;CbBsnk-UkabM>CD^~o(>MnfE#>e$;%C;+HH zSHC&pBQBN#i9bWAY!V{a68??&Am9$(xnf?VlTeS;fZ17@btK-*_^4vT+gzDdHNdNH zxrM=lj*nW$+Kn44xXrVzDPUa>P?~p?hS<_LdotnD^4B3c(`y1%b`7F4j@KI1+`$1p z&5{*aJ5{m>B&fj-X1%UgP`180xd;b^6Ie&^tJbr4D}RtHOtisOr;8`9Rv?ZHZUx2O z4z6sAo3!|aCID zMD~<1OC&Vl5e7szo(y-Jd-LhiyJGZkGoiS6ugUWpN0adh=uu@L(R?_7{aPivZF8j3 z{Z7RE+NbhTh#*5zV1V?CArbP^O;*k_BK${iV$tKDGQvcK!#!_2PL`JjOV*>Lb*rDF zC29pSz741w-ox1T_2cyIi7)mcXXFJqXPEh0@fc50u=vzCyfMnVe&yS6(4_x$4`Jc7 z3jl=5YILxl`Y1@4`etW?vG&i|Slvu*- zc$Ekqw&*ub-4^wk)P`R@PbfQwR^K@B!|PxC3QW^=Z{u!uwNf~>jjnsYV|r&M^U^-$7$&;Paf*s~gz@u4%_ZIfuc=HdV2^ti z96IFz_P^(ygWPBOCEHluGLjktdB@@fn56fWcG<}*3lT{e-85kwufIpq^L zc~SAkJ|4y+S3xpyR4dFMR|fC#A)e`bBbq8 z{W~o;voAX-tLu{su%dDtTFhlvb2b|~73~T#(d&tyD0fRLMxx!~pAjCwuBmAk?ETzyY)cn{BJR@$3%)>+$R1j zlP&Pi=4Z;C&B)wy_S(6KoAv=b;kp+_?W zh4zjNFOo4u#!Ogm-=MR7zt`K>$T3zpxhK4PJ9e~ehrBdSBTH7`%lFyIayxXBtTivh z(Nha4UN?vEBud}KKBQol?8ojs%y(_uQhptDQVVvCSIb>Hu}7CdyJqa9lm6i)`0%4O zsM@)V;tMvk$2qrMk7GNtD`bt^N7FK#G_}+Wq!(|4U)Z;M51N_!pDbri=bN3(vU6|P zyzA2i_$6sg2!jx(a**p7NYO%C+$*na#N;dgK(D^F*o1`DXf~raXL*6O2~y)I@pQ#+ z=x(YX-pNi9+ElRtuRgLHU3=wFykf~ycr58G+;hVb6weK|$JDFO$C5u@M=784jD}_- zuEK-2vXdR9*PH3KZt;KFHDc>0U59hpCt*H`&$meKa0LEv+Yx9286;}Pryy}?xV02E z|GbD+Cx7^vNZ&UdFMZL8hF|{Rh3FI9h&L9#KxL4k&r_50+9P}Cb{bzo3Vn{~#c%s1-@IDTUv(juv?(=^$K75)kfzfNUXlEy8ctRdVQ z42rx~K8@qSO%i;1S>sCwM~zz`Hl0FSMqFWb`DR$4Cq+;BYfrF6ZIKZkC6T;@!yOyE zOfav5vdL(&N;=D^?KNJF84lLE#d57k?LkA%1a|cOZ4>Mg&GHZvh#$2GL8Fwn-GxN_ zP}+O|iJ5Jr?ID6{cxcSJ#N&zOQ}3ULCANR^ctUv1>_Z<@FX@A+@GiHuK!k~Wyw~#8 z7ewnwZR~jn1!vz%-wJ)u$m}x}7x$T}i1l|ZUj2?o4FqCU>>bBYIR54WeO4bFqwBqa zO_exb@m{6vH*ezv#&>3)qj3qR28%?b+xcr7^<*SJL2-wGoVTztx= zGI8@Ju^aK)3OJct?#HVMn{urGmUVEupcyMPFd?+03>KGOu_qTk|8uznHcf zp{!i=x#%CP?18y#Lsu)t%fMFeVbSUh$ehRM4gEt7f*Gk8-j!WDHhbxA6ffS6f}^`o zJUP4r-@otzrtdHphl1U4?3E{@AkC^%7^N%T#NAJ@%@rrzay|N_d2Pg|^jLa4kH6&#CV_cX4pOiK;!4Z2u0cvm zONACSk<{1gb}gc>(~AznU6+hNYt6DaN$4{EFeKmk9krt?&dR}#Z+}ML376CKEhRjL zcYKc*UYJhbjb;pXKNeS>!t^0c^JpDuWE-4xC)-?cNk7TGW?FOfJNX9s`tPH6V9E5i z@$AiiqWF^Q9>P__vZbPw+7s1)XhNv_$++T(KjB`peG6&(a!ErWq?DGRjHeR_A*%(u z_OfD&{vrO807g$SH)|#Q`X#lV5C>ovT3QN1DdqIFv;uOdVAqzGrKZvASd+V* zNbwtPKhaFUu07oJ?oIgPi{IneTSrnnIjIKK)xsv^nks~o{a=$5(%YoMWK6Dml_)J| zKcq@ab&-`Qk|-a=1hENZ?}-57EYgB-=?c7gH`~0p>!e$7eV;VPzA}+b(Q?Yd`SfCW z&T45O-r zngiIkkJ-C?-FSxg7o#klZKewOpiPSBhW;%;}c7Q!3X_^*k6rvizz_CLf7dNRmy#S{$~&n!p{12kr%~GaQcv zSHgu8ACizM1#y{#aB0MiS!@9v^1@s{PI(B3NLIaw$0CdmnIDRqwd}qw`v_`(+>oS) zdP*jXQ%&zwdE9J>WAQ*#XJU6iG-j|r(r|cV1c=D~vsRD*@rQi_=0EnHLZZ9Qf3A|CwKB^*rl^H8z%gvd_T&<-lO%fjmeRJ^!B zO-+p>t%Y09gAUx*byWkjkX43xW>&x`}K)sK1OZ9!I?E(q(6dzlV1>FgFnxe zayMr!A-XjkvLsG_4v@6HFF{GPCPqb)`W1+Od?O0n&97xo#7Q|GaMR9O0y!AAYiW|V zc!AmTO><^rd%+3lnj|d-T52zxe&u*v{f`%@nCG7!6v_^u^?;LcmHyAl9NzXGZa@!; z{XSR2f$7ue`%j&Y$L}WgL}V*OUxao&iD`3xL$N_)(rNx?BhI4uA1>*qFNR61T#$WC zEF4gS7k>B#q0%8V{=5#xjvl4Wt&;s z7IYML>x6e;`H}d}L33eER30b$(_?dG%V(YU0nD_^FilcPA&hCi`$Fq}+ zjLl<#%sg0oEr^)d1>))JT3TBaO!^(JFIz?NE5H2(mkt{){iyA`fAYhNmKxQ*0gg~0 zuP1s{{RcmX>cOt|qAdrvl-PvZS z*M8ZIn!=87YG4>UmM^7mMZJzkN9hJN){k?$bw$QEd-UR2i?z*biJjYx)8O)0QTo4{ zT|2NNrwjZ-e)sOEc$J;pwWX#I(OqsimK^9oYka)5vqvU2l}KeGhsS#&Kyy4Ogmt}t z_nv=Z`S=?te*F>c=;m1h_u^$$b@M}2eyu%c;XFbsB@w(tNa$LH1)4GY(WYffG*9AE z1zVtXs}da3jm?)zzW)T%+Mk6N#

    !jLo1&T>2;MzUFRPE=1GjjB{c~2=!Etg*-4D^w+%wi_0zGWijCjR zHtoRT>GO~?ViLtuJqIy@{j=V~hbx)=n|aLzpc-Gs^nG913}k5Iu}@E9z=tcAu{5U4 zjdc4;XW+7{*3tMI9=ZVi>e1yQrK|DIy$?m%GvA<(*VY(ffH98HF=XcsiW}od>)Ia< z`YVN4W;jg9L8-y#pFV*%qkNc*HJPbxf+lE!CTQ%SvRR_*$%pfKH6gtAi&FItepx0_ z8CXalCMxv;DrZ|9(NuY3iFb4U-SYXR-vo65ZvF}%=QRzq(#WQ8JS|a6yr!>iyl7D| zk<VS0J*a z8e7G94eILf)MeTRm$3Q(chM8iJUp)QCER4?M%NcezCpSF&Or2pYAJbXgZrl$$xh^v zp1EVq;|_ji;_=ec8qHYmriHS!hl-CO+BET?LQ4oSEI6!Rrbnb6CM z$)f%7)KIoO7DzmgwV>$b0}xdvF-S1{CSBDSu4Gvp{KZ8hILEUlh!=PPdo{XhbxxDS z*RoaosIpf7Ew9;s_yD)W9$}hG-UL_AYqXX1B~6mX%S@>Hx^q-v6}0|~@D_>X^G88E zZeyJe3T~3{ic^hgVw|is{P5*fo)yl22NJETtUfYLAc&rAXdZcL0ele_{%Zu+!88UE ze!-7zYs7HytI5IQ;fnSrUWie-MAyVCZ6a7~f+lE!CTJ)ST{Y412Hc%|nTzOZ6B~iS zbX(SPPac(l?kx|cuwVaFR#wu9iQ|{;^$rHR)~}iUERu?8WWR*wH9(B#?@)B64F-c$ zCYF2*U@`)oh|5n#Xgniog#XCzODn6Y?9&hqrjs4`)-md3fKeA&-K=`?Ev}+TxHNvI zn$cR~%qz1)Je`2iCROa{T8noJH+T;lr!BxA$n08OK)@kyt}j$o(tZ$j(W6B4hFI#! z%W~QDg6tRPM!k%q@vR8HJ^WZs9#j@rwJZau z$67aFHp$fgP-NU;1fA^@&w5uP!M2~F6q_Sz{~MY8wC$lT*9fl+*OcQ_;{>OEnD)`s zkH%OROGgY4^|{{oZL?v<6<{)GW$ zWu@$dDb$616-Q)Ekw!J5X^@ZVKBP?|^0E3^d3iaKlauZ6iV9{o>@lzbKK8`|maVqz zo&nT$Yi#R(RlKI_yx`1h`Q$o)9oRuoLQ;2Hk-cP0Df!rTNBw#=#B4vm`Y2dIfUm+mRO^i%)NP9y5mjh2rB| zX!Hu3F%#KIH@E)he<&aH8~iC-<8wQ#yq4MqU3!}>7*QiRNW$$bzQkRP{kskzr6uE! z-j-RjAM4lcrgU28v_z8sqJ4pu9%KipJnu=AsoSASJuDA9C#AbRvd}*dS_6)ddFPM z+1L%K>|h{_%g98^j?LJ?4zfe1WSvauHf-LXP4TW7`r6pu6_~Y(oyRkJSZ7SU=?#o= zxL;LR@WgNF+qC`<;=1uIxvNv4sJTiain>L;!$)``A>P@qN_p#$=Xxq8VG!Pn6|>k$ zjwu6%qH_kp-WBYc+*K+4F|2bshY!He&KXhtrhP$I`ds(60D zw747f7=#O1xm1w1>F~Ck| zHo1}Rw|bg?UN@cwx2UI6wMf|-`h4#`cB+EW*xi9&AesH z7UbpUAuS~hO`uPGs;ZbwO!*jK$;g1T)KoNPsH(1x=6~~Moqu+8fBo?KPVDWC_I`64G@3DTZ6%Ci$cSpB;!h2N}FYjDCno$W^pQBL!+xt@g-` zZlAP9#Jk07UarD^`sUS7M|4qYC1^IEHg6JM)6!BAZ9Fs&UR51Ym0p%N_73CJk7)bY znDoPdhSq0(1B~@`pnhqlbmF& zYFVr08rPIun>xZp(9H4_3Eb3+rxBHyxTI?wV0@V0zTGL`_3PKsXHHHo-K^sVn$Ix5 zd20jWX01RVp#RelFt0w;B<*YKqsH{n+K6Rfx2AG5VAIBp$ZyvUA=57xH^VhHh>VZX zK8OL0%@1Moxy{k@ITKH<&AdVL7a?;mt@+I6&0BQc&!ehoq}ig`p3l#<1owsBHfeP?)to?L_nA&@q3^U^2qL(#Hj&o2=iFXk)Nk_^ zR-atXSF3+e*;8j@#cY1a4!nB{yISyb!+a+-N2h^@QT&_-F2$IRDH2WNlt)WP;klR7 z*HJ&*h;O(QAiMC*qxa*Jjcl{q?j2?5IQdH4cs#qRFue6We70#MeLruY^&v5$lvzWM z#L%bTF!71*uC;?V{o`7%f#_BC1DXx#PH}704&)7@&!O4RV*0=Wv~s(OhU~}m7oMW8 zKdcU7!IeMau}CBW`KRH&N6w*Gk09y@d{x>64e14ppUX%6fE&Nzqtej#+}rSnS01J4 zeHZ-?Xx$Rp{++CpuE*f_x1EE2X|X5}qiMh&UVhA^*@_jnZyTz*9*-;UIGf`AJj_6H z=M!+r_$%;#FV3Y+IPj{W$kzRo+))!~e5IQuDHgGDV7bhU=nlO3 zms4o?hvt=NTC-#5^PLyY!OH(#i@U#I8~K~JZGpgny+|6s`qDKgb%RVLoNR@$^ZTc1 znU8$14qIv-!$Tdfr(FDb0;Jrf7oJP0{9bHdq@derx8bJ1zbW?bE6&72&DxjCa&Tv;8 z^ZVN=ezvZF2IXDfKSZB@eQh%`+hhaA<}G9F>wgAr{C(fZHLQJ4$CZQb!tIxSL(%Nu z0Tg#S9XB7{&P))dJZyiHZ7w|J!z7b)HohKp>x;Nza9^Bv+aD}p!31JU#nMYsiWr#w0yh_;`0f<^$UX{aQb12ku-_RZJdl7fN)ifqt77HriQ5-Tbz z)RZ(AW_&Uw&F5ec?sIb)&WFQiT1TPL(=y}aBV$3jLx&D_=tf;eTg=7QXgPT??3E_5 z;LU#}4o0v}q@s1}*pUSiqi!2$-5PVfj9;hco16V8?Xgcd1LPV7s5IDJ z>)g`wVJYS>>J7f5<-OJJ2Qr(h`Q(%5O%vQ=jSQfXX_UGbdkmY#wizh`p43aQ8G5{r`BlXY@NnoeAw+E z;k7Zz)C(+`8~x9!%Lct32HqI!V(GJCD>_E$bKUkuYm=6>8Ozw1RYNz#uwNA#r=A#_ zW9)ctQK`CAT9#&V5pWrSus~a0~-5?!8U6J?9E2(gdk^O#z{E*=0UoF(A2*a zT{dmowxxcY#ip^DX8ZOXH2zT2JxhL;|7vV%>eQ(tf&sS7x=q&yrV~|cjv7#Jf@=(5 z*}e{qe0;Qk@@x389XNhXAJzar{8}53A}vzOw$UOdRvG%xv14Se#^&SZ7@|dGQ)2#D z(tJf5x@v8{>uAbtgE?Q>>f%qw1BP6gPO@jRwzt_71#6&c{7}nn)AnCC5%$TAW+gO)&Tw#={k?efF1BA()EPec;MB_+tr$N=wTld_-i&kNtCSdV|*jpK5}ot8By zJ8*!$l_L$=*{SLe;x&~hE-D2{&7x?QqTOoB7`@`E5Hhnvwfewr(AvL^oviZg9WQ~L ze-HjVk*%%x+6LiwOTA*z}oh1y|bsg$PC*`?W&3?QiYPD zGD<~DZwA?3m2joi|ErOj)f{O_ob?Lp_OO`gXm)l=t$RmfhvH(r&t_&IK2T{#r2i)r zNZpc8G!*OoGc&4xhIM<#PR0ymWzo~0!sVvD(z1}P2Z*=|Nckqr_}`28VD2tPFFONC z<;B=v%{D6zz2Gl6Z(!yjrNeTW)(sf8zqnc-L$c~{^I0vRK4sw#V*9dFJKG~ETJymD zv(^Mn5H}e8(tyU*H>08P*^g*A75k=#KvULFL%k6XUKcZ!)bsC{SEKR5a@MtPAZt`y_br-ORfN*EBy+rbEp*rwF- z>z?CUPy4U4m&8;AaY;|?KT#bqg2uB^%Ta(wbp5rZzmkY!o}=;=YR@%qjAazXxxV;p zD3D1+#k(xMTc~%Ozf@ieJmM^jc$CpJdc+J86|kl0DNdQw!pFtPhetCL7tD*a0pe_p zm}L^N+&WgH=&>Wg^v$Q6eN0>_^#OjJToq`NrzoXF!9iw&)RR^QswIv_nPh<)i$2Twa75dx`&pKvfhQx|Q-P|tG(w<(tD zLtaBq9h;yDnxF~l8~CL&z-a?DNt|p-NK}Ly7`VBBYD(n}+^obnS*v$%c2uu%Dv@y| zPI-BGgnF!W#e8mqmRmk6+$B$HYAU_Lv1^wucJP|DYq4!B`}JpeMY)qkR5@OYm@-`U z6p72iWo5=bI;YZK=CWT;busI`RNp8uLq3QpKVk|yynJYU}R-_@hbKfw{qRqkF0Q`e!02wlVY}Q+ius7 zc$D85!LWD6l|!A)b~8@SS-)-_Jpso6+io`?SUegKrCP*&Dyo=D86mm)&{SG!5_WqNq?tuCTz^EOa4;LqtA_N z6|J^4z-Zg82`-cRB<4v=M9``#!kr)^vNWE;aCR8>}Da}7IL>whV! zn4J>BhGg~=-f}H~fSy$|4V=*i1|BeR>z)6!A;w!_G~S5w!Z~^YD;`dInxuSd)0ve= z#-D`;xcX>3zb0;{H~xirdh9pT&h(ms9--+2BERsE563^B$F)9)P+yUr zBfY?1Kr`iG4uG=uw(=PZtpOPICkPq=M!M80BxjZ*l*@EFC0(P}B3fXa>b4~u#@i|E z&Z0T`b7NAnu7@m5&@3w$j_@B8$`5k-YNr?U#Y%7dy42aeW*!p{vfCJ4%j4;5=6g`! zC*aclL9YCugr0$?fH9CAs6y*tDY|5uS0800(<=~@%&SK?Z`wpp+iJ{X=C1)#&1)$Q zzqw17uJ%cCae-vIXMMv6>vp@krrHiS^njjLr-`2oHD7ci5hTVuPUdRN@ua%C#^%d_ zKrrCr)Hj*O4<%2=*j5v^%ByDm)hy4DMPt4e)DIAcJgX5uxXqBfW;lon<8v4%YZ-W< zaCg_uVBT*S!qczyq#3mB>-XgvqeBd%}Nx?m>{j2esH5C8kk=HP5jU>sk!!4F{}s%U8XHTWk~}4Sh0#5>(A~5H(f(oua`6QltBh)xi{mk`78E z>kFd#|F0Mt_SBi$cg9-T9@W??+6}L%Q4=&lf}!bTt;9jo$yx~lnagY8ex`wn_=X;j z>B(AI=E+*dw-aOC*j&riBqwVbr)h-=`!T9@%GRdMo9r}nvsP9XJG$AZT;INZ=~4Zv z@uV>=l^TnO#=;`sAXXg=u&xU`lz`TG*)sahj`fZ#z*%kgYX#$qjHSz#+Hx_#IR3nE zpT1Oat?Org&0t&+XrV+g`q+?@b*0+D3a<4t`o}@616JLl^xLv`ji7D^v-}SR z`FeqIEz#1Y!uVjzzmI+8QbR#Q=m)#1NmI0KVr5bv^|Ka@%gV~JWbtC8m}9>-ImPFsXGCp|a%{#T?whg1%_y2Io~SoZ1-LS3end798Hm?rCwsGz$S-0mU*mAc zW++70Uq;W`JQlrqO5--a5jj1W8!Zec+^VnXS+mVz{ARESO~xN_;LiG(o2Q7i*-R7C z6OMn4lP8JZ{ACKm+UR6FE$3fsA91r9-M5v>u13(>>_MK$m~PcjD5(> z2KMdSM+InX>^#_gmIeXUhPvF4imwenF}JOX_c>y<-u%c}WGtES*f zIFaOa2s|fl?@oqPDWM1>LVj6Vf`$bdzcL9#*ITu1OAO;-nc=_a5ru_*HfyPPbCaE0 zIMDR9qHe(0AXH*5*2lJyB7yDUiRvm-5w4_>|R4i)I`ZU7LS_T9Zo3*Ti z7{c~7h>^`&bY^Fqre(m;p+o5}dn<~#(;sBxpW7@@CRDc-1wSej6rX8rgheXnTQ63?`3g}LS?F?&;tx%tN0Bw`sHYx5OvKY3iV#TvNH zR(v>#&MT$IeL%D0h)_OpmM`OtFHcs!j0dR7BGL5~^BZ;M?X_K=@D)%dPnwhC&)7`G z$3-?@SzD@zgKy2mtzUL)=39h+YXl+mT_gN8VJwdQB^*sScw#4K3A_^*dE03S{ihYD zQ?#n89A)7H*ptEf+ly^-u`oT;b+c3=aH~GD&3}A)adTqa{8;62G{KdvD$m~R$I&x* z*k8r^>-r*sjHKPzxpOBaIBeMPMn7i$8o)Vz%u#RF;?03325J&4PDlt5H^OcnJDkop z+>?5das$otUE^3WJ0W1(yJ(9lV@9luEKY;FmoCP~I&-k{sQBQ+BecagvEEiL)m%jO z?i-}~9T|(F<9Oh?(j@7dAYs5YL2T`u;I<&OPM{B%NpSrwqNz?irPw!WMfbDlxY_|R z|HOK-mYXRRxlYK?kT62AK&>qk2NL_EF$HSVwIA9XV)iDG970Un`c>n&Oe_te3y=>J ze)A-d3F}-fafB25o1KRE6_;#`Y@~WAttixbql&L1f3Z$LJ%=}IfV_>w zHW$YUNb;)IyZoeUf+lE!CP)}0(1A?|885GtgW7sEnyhS}hM0F%6X#v2Mk!Uewc$X; zv|A;JkXMmR1)`hlHNeJMOhQ0QND>OfPl7tFT$5LD&;yYL5N{nMo&i$ORO$KYYN9|k z-zSPRi8Guoj98mkd0$=Q;w)Pp83;9q{=B%wN!DH(G|vjTjTo|7BhMF+l%~O|pOaI< zr2%BM0KDg@P*p(%Qe9Fx7_yn9Y}VEUzJPdyixc6vCYlK{76dWap4iHZsxE=OIfBH^ ze%u0!DSecgB++q>dO>bV`7qJiB+T8fQ`;>oD4qh{8eCkh0iqY9f5o60qvgX?!>IVj_c{R8m_QV)$n3Y~LEEcr&4a$G4B~+&8b~eUo8Z?8 zO?uIQ(12sPYCf!T(rW8!HbE0KK@%K`pzGn-uYz*;c1*CRUJlFW|qyr5f!O}=1422WdL{QOVlz4Kf*#t!!NL^ zG%4{8gz-!JEc0kLERs>Ng zI{Sxd*XT7u8np|e6(AD+WwMivAsWdC$tE z*Qr`yTnk!Mbnw_!TmBmCdeEy)N#l^eQ$I}p>R3OllhIh;soS=-bjXmmqkejOB%&b7vSpC<4k(t=PQP9I5e8Y;FV;k|*Ze=p3=wyz2VBJ$&}b&R^!QlKx3 z7q5j3n1Z#gKvZ3uD7{8gM$aYQ&Tq6|SRSu&`DNE0s;+q~s>;OXqB7J}R#E(58+#5_ zu*Z+AtlFQ9=r@rj%cZ$yiKHO%w8WK!3q_ZVMDgysoZ0|y`FKk$OJiZ0f)e3k#Wc>- zs^m1H^8mc$G$G6>Q~u<{2nDg+2wl~ttXhFM`B9}&#`A3;YZJG)Lje5rubBFvB#%nH zg?95VWZ4rG;Zl*1r_g2rlAR%pb>&3}Ai(gaP=1Wn)v+z+qr{knblFYkX{w8N++h3#Y2)_=BimA4;^U<3)6hiax2db_X-!|iANY*(s|ML zilgfpTmUb#c=g9`Pg3P^OBYL=U8ebBuiseqfDq5#n<&0wNyDd8>2)NXpxRMBCN62Bs4nUPt3Yyg-DXp4JzCQF>WNZ5yRS zW_u)}EQ3ba+N>3>0jeUK3Ff4w+3W7Gp2YdAx6N2WUdvI{I67A6R&FK|%ZC$Wxx_m*e}yAqR=h}`uVVl%o3FUCT{n|yus8b!I38f~p$Yu>-uz{zEviUE zx``i*V^4j7%uiCK@p>2Yt9*`_+k$7%5y(oBMl17b@-&JlrFZ9As2d$2qe|dnR#|w$ zKy0}El?T~mpGL=5g+AoSv2^OEAgGu7b(wjJQFI(vULj34NR69j-6}bf!7Aa z(M8^O9L>uW&(}>nBwrKqimjG#GplC5o4)iwBp^3UA=Kt=kab<#HzR6x1IF z+*X$O^M)*9vJpzfhU|PHzrgY9S%*Uh61`c=ZB0?c-R4?hNthTeqs#NaFGz{u5NL{v zSM=m4aq-eTBVSyT@Z#rC23}7HYOgolPD-&NK!%9=_xBZj$6P_pvj zBhJeLi+xxu|$a z`F{Ben)MIXnDLr=S@>tX^kRu4if1i~CHxyv6%=P7z8f$8a_mh^07zYyl@N%(?C7;Cv+jU&zMUvF zje>f$-+W=U9kpaO*VVxN`atu*`7lxO8UkcI@MK6snF;mWPVlbMI^}X0^V)o zHO3?=Pi;XtU=e2+KNhL<`5;(^x%XmU1G0|CHKY@+iu zK@&7V6Es2X!OKq*eL0m~ZXi&(UXCRdiEkgUV>LIjvPrNN?l#*K!-z-PSUt!lkF%~o zwcO#g^eisDh;g#kmMuPsK9Ov$E?>NIU8;2O)#O7R`q0pA%eLY4lGJ|5c$S36%dhCQ z#tXHPm+!pdw0-$NkYaAf+V`}5uI0$f!tePW9 z^STE}qayq!+N1JGOLSoCRKXMZu|Jlwcw96NUb9_(b}OS>#~@CyAz{Nun>lq%oQGH+ zyfyA!KIbQJpC8pJh`K6<9RwgTF}`EtE>QNaEITpfc~ffqjmEooDxJ443(%bD0q45& zL8hh>&^+*X=((*?H;9F4eBkE;hfGoHTYNI*SH%;T{4o_sqCx;QDbYXl7Ezo+l-2Rz z?)?5hbQA!&o2QyPd+Eim)g=5Hbf*apQfLgyDd9o3?&CH_HTAJ3Xo4nag1QCOyg-&F z!E5)ig61P$#hT+9M0#R_BPFr_Y62c1ZiVqzTshM@86Z&~|9ScZ>NP}J80DEu!0K>l zkCN8O8c}!xuCbGadCh%f;eO_o#7CSeoholwkU==?emcRg(Vw!eEiyo}aASe+5a~C3 z{dl|~>*v-VNDOJB^jkQ6!>fP#>C39TDmqa-hOKk&ES#;R$mHKxG|n1#q_$N!sZEt1 z9`UMWWcfJh{uz?Eq_O(56ZN@ymC)MBTOtEk{~EEg@y`r|lRgYZ-kjY@V!D zt_2-w9c%2iazt<%C$J=5V<BIZIK#^dv9{^%2YE zI++H!3LV^Z_NsB}yXJ zTAmdelYC-of?7&EA^KtfZ_8wzAWoZdFqj~y=a%l^)BXdEMh?X##fTMbjUcd3z~v*{ zCBW;HD6d1`uPcc|-i-oC%n>#ybu8xQKJ@j&4-^;2t3!>vpEUxu;+L%tkU0>LgsBXu z%w*OTh{L&f%0q48fGLMlVHGPa9!r=|SSxyGB zIipOzVM3zDIMrH%cquT1ILUgibRI2B4;Pv|9;pM%-RQ1CY@q(xu-70arYxRkWAlKf ze?f@QB~hDnY~A2C8fhF3z`6Mch}rm^)F5E@ zXUXO#;=Osw?=^|`W-XH!ezO*VdUIINjUG{KuCm_4h`LtM?=^}lJm{!Tq>-AgL2N`o zYB@exoy&xn)})2Ju@|f$k`THI5FMR*fjA5FaCyTeN6_ z1_7S$#3XdhEyE8gb>YOYckf;raK@!tK~K9xP_@k6e!A5#mTf0K6w}4Wjwm6 zh$>z+8p5SazqNw0SZe7Qu}#KwXDeWDze!+wgd-s|<)s zTm*LQ+6`~;N6UaDn7c*M31? z3m&=#<1+m<6c4m^lGAh&Q}0TweD87k_G8D3aPFXNo#huPe$8jS@!<6n&@6VA>kUNb z$G{u?2e0bI^zq^~pQF!%*I_~(3s^jf$@gXnollEL112<5MQGZr)vzG46Zw{3|9q+( zXA8u$GNiggNYwb{<$TG;F(To~ji#mu7spL?9h`bkh-&K3LW`DviBA^nLiG6|sq}BR z!;ZtSoJwq4`~$^j&R>abB|&6&8btBK4AxT}?rfxoxEhf#!fRipulv{5AbrTW$jWry_N}3s)#sOIv3q+ST8%o6;#tAnI56iG z94O&Vo;2#0Tu9&B4L<@ITv1HkyRc^glgFO$P;?qN8tHsq<0ZU~;+y8ai~X6C(Z9n1 zimzCGif-^$O*yv~&!z`*qR7nEYy1zK;XT7oet;9WNJbHV|2b$0NH{MkK$^ zPl>Jr28%_-VFYyfC8aa@Wpz0Mty*L{`8V`!&n${>T|ONL_U(a|)SBXHtp=lg_lam} z?rQhktOhtvb&Gjy*W2=!&)&njE+F1cXXdlaGCrF{x z>3EbIK;`abH1xZ#f5fUC6-a8HNAXL}J`Q^peTr#Ii_F@{it2+SkM2+3TX~rFTH9}K zASYTRQ1dg>>N{UY`L|G<(NkxZCe3#+%4XTwt zFMi!t@pxL`=(&kcMYFDfc;Jo*x61n~N^_yws6oXj5fk_!W9~y4qnvXoPdb!~;2b8$bQoYv!$kc~t*UcB>)2nn$ zm0uIe68TZ7QG=Ksl@lu)!!#isPeXIOi5eiQu9p@QrLJgP2vK@e&K!{qJduskGN;_H zU9iGsI^KvuR=s*>K!oUV*tw}rvqOoXIefdy=KH*^$*dU9kxXw@ATtSm#p7ay9>bSiKg zq22fq?Yf^bRF+aUB+L4xA4{t$OE!{;x@MKD>T4>R#DxzL{Pqc%UW(~udRzaXk}@Bs za(rYod={xiD9bIsGr0-^VhWz1^)4DD{wcnT3Ixf!pS*6$6%Cd&H2i9y9_rdK9jXbM zpb45Fc94x1ngkae9Osy(Nhzo%Jn?{R=$DPL#06J5`C3$nIt@WAV{BbOLys_ZRel}U zE0#vn(-9A)b=BoK6kT+0m5E%UT&w5eJJ-Uku5<8`3GtajHW8Dh_S5x z;^L%%$Rc9kfW#FQ8#Fo4wFX~0Oby0CB5Yx<9TgZaF+RwXTwTb@qhPNUpIQUIV&G%- zfKTe?Btj7{=9AI!0?i}b%~|s!N7)LWs%|1ZKPz)}34A?c(iuO?i|)nxSbufTwECwz>6sVIsutca0A}BiAF@ED@z-lnz*r6r*)4H zR3@!nS(S;~H@K|?G)QfJUEo`^bhE0~mK;RNz_ zB`*18G@vL`l~){6RKp4+G-dTw~T>YmZLG?~Tt6n4M+kj>v$7w89*^OAb2gS)l zQQ#DCoqu-{PtWsz4Wdnef4D>S3cU5)M*2GTk|U5)4_7C~f3j9JR=oWjHjKH1Vn^mQ zzIz@Io@)@Jac@4WO!@zoV)4qK_y{M8FgN)U4_bcsaU1W5M_w;H(mkD10dM&;n;y(; zgLdswon=(5!DlZnrnVw;+_9+MG6QdYy@y8iJ8UBQr&XaAx2UF!($xoilsJiM*g zuW78Ie|K-x?MR2Am@trqZkzcU9(X>8yDuL`aqn`Yac`Tq8$W;aEq!f0c2OzYdIs=ii)S9%ADVTX1YjLfXN0uDe1r$$ogUn4ct9uKhj@19odx^)A*9n zCj+IMkhE~!pJL=)- z5e7EAhN{okA)NXNWh`rWJCmt zSAT+)Y{fgb6;ipeu z#^$jvv-Ek*bbj|?%WBp>JKEib!t5|Aie^&&zWU+`tRM3>j%s6`d{na@3uj%3&r8No zd`!0^FgQ1eiqf?d-+W*z!uh?U7c7`rp)NP!PSUbYAPjKkhd(XKzNQcn`5F8s|MWb? zllOj$fbM&Sb6NfDYYx}EN(&5s`yxo!9taNZ#TW_xh_X*|5IXmS2>tRoD0!dBJ8;UW z2$KD%n06k;cdzV?W@C;+W+tN_-u4-G{r6>*oxtSRz9W-g=^`e-^6s~xO$%M$_RggE z`d6Mn(Ft#(N4|A(R29mW-iZ0r*HOIHpbL=Ks|^Ab+bLeMeKpFeCnAu7NPP&RPacC4 zhb_+7#&)vzC%pUKS6JV*9hJ|B9^=tG%3Klb{pmgW_TE?P(6!xgTrn*Wj>dg0x%%tg=U3GoIqjRi-jIn?7>ecR+K5vEv7Jvf5|lD4a7oN0&z$ zqpRDG11rA4v~@!$e*U<8u$D`ve_N#LI&okwp1qB=U&WNOaQOHXlvrO8=er3P9^*muKlEEv`5zLRa zuHK4*lz)gJbFIr#5hU;=E?YT@r#LtI#77)a#EJ2;l`~nKtPGJC5(6JHARh6x1z8<^ zWlAgy(m*e{#7*31dOs6{xCpz2F_2b0uCi517en@#^+QEK>~Lboi4hWN&n$u>f3fD3 zeXejlft9wM%#xataIOYe|8>l9Qf6|>ID+Dp`nCP+B=5^W5FVN7G0*XO?`h=6Q7 z;lmQ)?A0Td_6!sI?-s&U8I%xw&hz(JPnPnfZO$lex_cc#(Q(? zKVD{PWNH13aw@l66)uLUWZ~uQ$lOp_dYK9Ja?gk&Ty7Zh&1ovGM2G_<3Csf~~tze9+K-$f4IHv1@3y{`@_5=Zr-` zPUK@;c-Iol*xZtGJaS+jQs52-&yiE6H2NXay$+>VKX)E|E$ccOy;}xoy$o3S!+ex= z8;kxqrdUV`*3Mao>Yk%0+M^jk@ur3NX~71Hm!!2v{}BVxDKo-9soaZoOWCz{D>v;% zSxPSY4IfJJ?#*?&{AL{Uy?WPDiq2Y*gn|)0(L4z6I`cST*AaPsObGA7(%E~F+lO6i zwSK`8Y}l8C`~f2=KDbk+{xKws>go!LS5-%Ee)G3ki+x-#+OQBmF5G~k0Q>mZwnIM* zEX+fid2Pw;y?Gdry%95Kuci3JaeXjrnTCENx>KB~7eU45g%qE)Cl6x^bDT;mR#B9V zmrm0}>~7Jev-cpkR|?k6UqbQC71`)Hd=$DTvCT&Fep-yp<(cR@l<7lZZiscjDs~U> z`Xx(fo0q1rkFWiP4@386#k9{Dp!FMx?%9!IN#$n!W9c3Y9Ai0d8fp%#!K_(Kf3{XP zM~`76(bv4@$C@^jY+~1P{kUMGu7m9`Uj(CLrQL63?J5=>SJ^4#quvcz}Jh-++P7La|VYu_Iu^bh)WchcL%Xp{Vb%_zEI=1*7~D#YYbohYulaZRQJaIGKH*S*W9;e)Rh zGe!+)nTsPP^ueyBvsrv@FQlxSk0qN~|H$q+93#6YVbeVJv2xLta%6TLictl*6c3ec zz?^xd=r+1HBS%fmO8l^ZUGvp#Od$+YLrT_Be9pou^c>a0^_tPR^qcIW?P2u&{DIlJ z99ew~S)MR5gN7Sm#TnrSSaC+U0aje%<RO@+vz^c$7s^`PIX1Y4Na^7ovf21YV zd$97ypRjB1bOB;uS9=#oduy!VjQ|IZ8$ zuR&-~pF+ac^4M8hp6JO7KBtJpPsV@|jiz0w1b%{{rJ&?)0ay!_LDDBku)z7?O8o{ftqu+4e-LAJ~kFxzVYac(YxP;aJB zBr1;gLS&nfto-&yt^ku)xS$Nd`75AJ?h}cxDSKtx|VjzY8S8?nmVY})GLKhP^5 zsr+;%({w#(+g_Jnn8~k&F2BXUEJgQxW^aOf-^S8!H=x5w|D|}3HmSN#6RB^ot67Jz zv%Z=j8^>lgPImt66HQ6~ZkzQj_KiOSV;6i&@gH`K!IZXwPe`_7*0*fDA9uz$EckX7 zwvV06FB@R3qP?g+zcU$QqLOwnX0MC_9x0NhEE0?nMBTa!r5${GXmiDiU_KS;V zLXX0)KYk={^vWhY|&Mg4sh={^$98?AmdLJM_g!%E$sZH z2!Wy}dyNG6T4{>7ItQ<>G@j6)-2ZwZ=C<)#dqabbYfWH4Bb22|eTXDX7Vf7?v7}M? zf-)L1zg2_WS*Y`2)J|N}P!i^REWE!_JpLxLicSwVVndABhi2@Z(}x zI4_Jw1R{%0)wWi?q8aC}JCtqG61^-pk4zR1sJoh59wMm|pI&oG!&Jl*Dwn^4*LSnk@4p?BuP@valq`Ig5_$Uj-gs=>KFodQ zP8$De@n{^QfBmgl_aVja{cIU7yYUqCOs${=uKn^qm^XF=`f-c;)f=bd#jgtJ`=I{0 zNOrR}1{LB|Bky0MC!uK3>-6pI-92#gq_)8JA1MCH)32iF$UNMAc2AbFbP+y$eh#jD zjBREr`uQc?{b~uu96Oxit@h5uV}Jhz7uHtYDBh`aK2p|A!-My2 zrMz8t=Sk>HB3;b;O_s78eWXH#0Kby6x*D`(h`{Nrh?&Ps(7iK51Y+St& zMg4M-vS~WSUwH2TdZji)mmxh^#?&e-fAux&?(jE?9+PkEZYjmWcb}s8_kHfbSda4M zC*#mJb*37&8SA@ep2dcKLoj|=FPc7m(-(N~_OH>UJ=zZ z2Bzz6zKw03ny$Bdr_Omu*4x|wqun37d#c`NUZwc!yF1!_#(>fV@8YTN`{1$BY;z)N zR^fwJzQW-nnf|vbUVxWwpNXUXdOgJt&jE@T>pJ*K3B?UPG<5J$T?Y-g;MTKs9keQ? zb~VM5g2Kf7-GF1YT9VhX>4QDDFPM&B$~x2N&iN@=H|;^(x0UgG*W@IWmWNTJvCS5t zloW)5`p42R+syg%OZVW_lF>MJcxy^;@65;W_g^l+t!MS6@oC|WnEt|hDC)&3mEC19 zdUQ=ivfY0m1$F=6Yt1KMo3DyX%TZIK>3oJvev|Y(Mt^vQO5xe{{V-(wF!an|n^V7d z@OFINwFBDp9YN{#Z@wQhp1K1oE_#5*|E{12i(h{mdwSeNab{{>#nZ2``X8BlH_q-E zM9HELDE;T>48#2+yT_s5-u>PHCd*W0cO62-(4%VzB)o}+8(_#eyQ?na)~x zBcBnMta17y8DTu_QOYq3!`|!t`*-1I=c6@<O9-Z%X@+&_OAa?g2$;{94~#k+rh3>(LuLh&)Wt=+R}6*d+1qa^cE zi!krmJMn7KXc}*goyNFn03AEiJO)JYW1@w}xmm~ zT-on5lV6nUs5vK)no|u}96@9=S9m?re%gbwGuUPbEwB&O?KdHP#;-fO-;Tr#B+noQ1UP8z@@((I-ef`xrYNpU1Ax)(=ozb1cQ%44jDI-0M)Z z{VbX$HOG0P6-=<3`n$aNz#z|HC7qiWh*@c&*dc}uw-Vo(>N6F8Yfmy?h z?x&)3`uo^Blx;R@qqCz`Ovi?u<7j2O4%~yyt0MH0+MJI8ZI8#o<>yemMfww1ru`06 zI!8`A+P~!+6z5+~@y;0mNBPF6o!ahrbeVMz#n0_~b}6(ClfSO#MgeoC@FmXfVB ze8t9j=+@&=q- zBry%qo3r@MY??5RI>sJe*gTm2>-W>EFyiv@7!+cgou8b!2}hmSft6?GtJ&~9zN=#M znajryLg=f1W9G&qDSl$dfLRW!?}qQEqk6>U7(a-Ow_pEzCN>^<0y+jcesmwrDAxe1 zY@=KQjy$1*eHxtuIDY87lN*$2o$aB)8XL5TJOp}ywq4M9*GKgI%lRX5=HRw;)24iq zY)Vt+4{|!|cybmjVJB#g`PU9LQx~p0rPu(1E z7Eh!Ca5p8t%HA$>3*&cB>kOPMM*omXJUxq#SN-5hQ&iM#IwoqB7$@`aHMn<2uc@Bq zlE$w`!l!`;eHmYxOPPT8u&ScT(^JXL%13;ZC(_|*sM15ihb*nCoA{B18xJy2m7$7P zfr>{JEiqj4peKt{S^O-JgkoAW;(yX|cuT5XC4S3jIuWXG9q8TER8J{LM@ID}Zeespk4?i)m&?uY8 zhKAuR7L)25TYJL!lR&P^ zVim-v7syudVrkR5Hg&Q(`|78)R7y#9@nF*05my-|BBY6h9*?WaQ^m`|{c%7kyH!b< z%K#sJ&@Z`Kk%>2>Xas6mkAwqp3Fq5DljM;b7UyXY5z`?x1&z@6Ym^|f!@fY)_a%-| z6C@rQTUT#_gBxVSwCvx(0s#3KJ$IM1l+BqS$g5{0Y2GW}{S zxXN{sxrL2P_Zf@CevgD}4lhYOJxhGb^dc4>WKaJdzC4X8zgL*WgE*Z8++7UMTXa;#EVFOh^3EwBl9sD9r~ww>)mkL|*;Ii>}C%SPzw) zWIEy}ty>;(MYiEVWi{NiIRcu4jwYongCstc_em2e=rMjQDxRE4vGtQqLFZr*7S3eX z_;nwDE^4-Xhj)KwC*z!V|A{Cx?#dd@P72C+^m@EAYa*^cER_~WBxMr*ua8rloNkn# zleL2AT)?g++d6$EijQoC@}K82T8B?Un?(z;p_-la)M51!EbmwVQnQWX-@Uy6ea^iH zQ~Q{gGm@SlE3d^D3r?VDpONVZv^xyvoX!Zg94rDMh94e9c*=D&`j~!tyNBCj z@7#wezIb`@{Wsy?->jk7#M3hH-CKqZ-b-<+ho%l1VCbQtgHU?I(RyOM zMW3uC%L_z~z+rMEL_@p7&H=CPgVR>y+fUZf_x;C@M?pb*q|Im7U=AETnqJdXv;AX= zzrCP0&b@ak`Xrluw`UkDubqYkC$RoGGNgx9Y(@H*`ze0$5c3*4;bbt8&)EA1I~k*0 zVF5a%&qwBmShHjWRkx0XXX~7}pG*|j z=|EQfby=qAvNYrfm=?2UD-AcminDu&8JA|se`uyX%{Bjrh4Nm3r~LV`jfysvhP5j! zMEmpw$Qs1186BM$(DPL5QB3}Ue#hbbsXgt}76+!U$DgLH!oI2bG=H-pXXCt|@4&O~ zuxlF!E&Bp(&i*TgHe+Q;^*-#_myOPS2T*))r!;6oBXnxE>SO1^zBuoJ6DeL8Vq>QwBh{=91ao@XoI({>c6B;g`Mpk=%!!6n4dB z{g94WPS&z;CUal>5#zMF2kGl8`;NpPF7B!KJ4?SjveNiSc(Ysn58=_j zL&e0Y6tBrJ$EEOk`UpNX41uHwMXlF8AZJa9;KK0gnEV<2(dbY$Nk|%Z8;wtS;xd#h z8iDMB6u!covtEgcpWj2E@L7t7lG-6yn2PO-7E!!a&OkGrrT_V8R@ez^m&{>U`_a&f zzrvoqM^U_8yA*7PFhL;evGuKC6yIT83)qRBTs7k8DUNHo?V6kYP0KzU9kS2H=FNYk zc-sysC|~^!N;)yTRq#1yKCL<05B@Edeay!1uYw2ANtZ=4u8i`MZAi~(L*J8$v;F8v zOu;tDO4~y5;=|{rmGMe&7||`t-R6ty>0c`qf3-5Ny`Q#)Djb z`mVJ>D1*tbO83vT7Dhdo{7RRUiLkKtDV4acvxBFA(fBgQt zB+yUENvxk=c+aI6(R>sxx_TeQUwrOnT=ix@95I!hta=yqi7deE=>r z0roqp7z4PrjsH5tr~ua}&clf*U+lokOsfO>vhoB6%_}*eUipe8KVQ6Tl}}_%WK)$6 zl6P^%(k*SQP}}@&G&M!IG=tZ2Y%TcUz*}2njT~!1@e0*XzSv~rGL%GQ5wo~s?00Tt z;?9_W@@qr0PV5;EGG2&BxR@_`5a!=BXi=u{V1>HS2+sn6*vv!}0Zl8 z62{9-olgYSv{zHaX)b(;UXoXtvOEyV6w`@mRqa3&X;u7q(Gkm&wKrVotHM-m@25Qg zdD{?0St>ey^^Ult6Lp%W54g9PDhwXH`QbYrn(#r(O9xeU!c7+dZ~G*s^V6@zaK0@q z8Y-IvsC8aOzu`c^i57W8*Mm5cxz#1fQB>Ib<7KeJXdIToK9-J@&D)U8mOAylICX)`4SF*sR5QGF}^VSbAr(S{uOJAhkQ& zJl5@nC0Je23%lpC%@lo4n}FsUAH{-A$1_?>m!Va`6#W|q+pM)=-EJ&+_7*G(+NGmx zPX$`_+;5hhit=sqFzr*enQhsQGH8JkY${8qJa(!!H>iafy)Xa$FxEFa5C160_Fdmd zouhH@O&j|ES|0M+1i17XLLv4Evbw68g%Qq?<*#C)1iX1n>31@1lHaX<5szGV19C@A zrs2m-8He62lWcmy&b`q!o##7%4x&Sk-Sl#dY-(>KHvlxL<=v zlyadDEeCB|1?KaZKxe(pjXq<5(Qm$AbsRe6uxk^IeskExS&=g zQP;uwx(*t!D2Xv&zMEa+*RtmUJ#U&IA6b2gW6-m4Wy6xlL*x5x1-8zehRjK`!m8}W3M2px3X({*6yBF+!vadn#I@=K=HDw$}Q;U}yB| zn&IHvSwCm{GX{ygzC=tLEtg0Pr#FOMT$z*8ihhu_a;BuEqjh=jdb17} z2_`Ju04t7g`RqIfgeANY;pyO!$y;fkqDJwE93$zO{0+#h*fD7~0%rmfKJbLtoOBK<+OnZ5i^e?vIUD5Dd_YkvDBYPu#n zuC)u8bZnl$l}ns)cA6x%*){F>Q*q$+`%&5HuPj^>MzD&XQ2O&$kdDt&bocInad#@J zH?nK+%Ek>qRtlddfaIPhA$QE)|QdQEA+bMpZq1oySGnv zY^Jg6psY_D7b!FMDMRnw>ttE}w3GN=^qUFL#vZ)YmeQN+!Qx zvP6H$cI;cZmzI@t@)O9-4A}XNwy7>JbI?OlGu>xo<&~`d2UcrGp?7Xen;&+qVkAAk znN8FuyMNOL7pAh-c%=JaOQ*BVTKmd-`H9c4sK^8@!})c0eP^iq{$J<7nLJV4T1?fGDS0jA6L(gkc&`nJG(EIm^Ovl4 zAnTi6a#tA(rzgpOg!GhPz0@^!P?_3#WmR+=ATZ(zd?vR~ElrRR5Qn=&h*+fI*>p{9 z>k0>z&k41!_G<*Uex>q>RpE66)+R0M-6}f520t#U{9@-OE{AVr61P4(XrfyyTZ>jR zE0>oaS&4e-m0vX_kmZiG+6T7lZ7gVM~r30D=f3mu`>5~i>!-z+mtPXrT$oiF=Jl)FX!~A;W zGIQ>ye3e`wp&_H|$8M-hx}W@-2OpY(K7{mM;j$T!s-AB3YE)n{r_x^@qLyX8wW+oqxopfs-lae#UpEq!3an%4mGK@o}Gi2xMQ^EA$T=si`TE zGK?}E9~=p)$}3P~qJ;R}ti|I#P7ulHNgoAy?_=4bpRsix`=#~?9aCFfkbPXZy09gZYnI^ot3QG%-N*(6 z9XcL&B?f-_JYJa2K1N+Nu8sX6C$>5hX}BaK450@!5a(WeeYcW3X-EJPs}!FQ)kO zfBe`u&qn|5)Ry8#zqxDXGEC_5BgHoloJ9MKb$WuPfBdSfH1s!MikG0gvO@oem~3*M zgd{@;uVI_DrsM>oEEKW+nE7SZ4fC5LA<-Y1S7OP7Q;3Qsuj9TqHC%WtJDIJpRWfQ8 zKaZ8mF2L?RW|A~gyNIuItDzB?3- zz_GhQ{FuiK6m3KLi&IUD#A|kUa%ds3|1dnGX905GXD1IX{&_3*4LkuITC>eh142(? z!GdHg4>0{cueHW~oQ2e~OZD5!N^+Ya4Ox!IHs{+|@pRC1;x-2|Gs5X}a%DLx?J>`Y zt437~ETz!@3!>$KlkulQcKXnkMPK8sr|!h6bMK`1g&}?H)W^tj(;ir3XGIwsPmQq? z-cpo~iBRR_o63Z$wO`TaXFEpWH-j=G`flf8iG#sp1hewcZxY)q(f{Muv1G^b=-e*g zq%U}5*0>YlPvBeTby;Caxfpd68^2oy6tW!X9plBM~?4F@n=~;&GinmbS`VzD(EPyrD z4`2|2MR(BnqE&xFcArcq<s(&{8QG$JB7+L|5 zwl!W$7GZNG^Ir#NTU%MO=-=FqXJA;HAbJEYp}hTP{(BfO{#3LGbf)p`TU6kS?W+)O z(}&_gq$4-~ROE+$rubg-#3oI!5&Vg1M63_kCM1H$MlEr3mTI#W^-X)70P-=DA6eB8 zVO@Tyt(p9c&04%p1t|>;!R(FZ}p$|(ey!8XTN*9=37<}6>^y9mYQOn!MS zlUSI>5keum*|(^k|NBy?84*}U?~GsFl2 z5n+6;I}jZL&6O?bDw_CIk>uwwM8SeshND~p=f+G44NoADPN<+M;zWjGY;2paJy`hO z`e zQjkjRJsD?=YA0P!vFwZHki)M7h%7|^zij0+ygq#s!cnno^LXzmXJB-GP(q~^vWvU# zt2$hwLDo-P*hz?u^eV)9uT6cqG0l96V~s2IIaK^obE1@C`=dAo%knA(fdn0&?<eZWI)c?DeKSJ@S3o*54C=y4?u<^&wXd_SiaTRuyrDDh#m(!@DI{R2jC$&xxQ+86m z0pEWxlZFS!osLm?{JK;bw#@w+U;V^>_`0Pii00jgW9rfDl==4QM%o(eS^5RVKl*Yp zc4&DRH2GMHPwbJc&~%yw7YrYY zo~=?O?au^PzTta(Ff)j8r!)P}|Ds_|fQAom7vtc(GLs6EO%-w(}$|4e8 zMVhiOxbP_}lTRb-uBtk?*~@rAWwyk4mE4IUom&`jDPL8#A6JIJU8aCjkNNzvG@6gR zGX4qNS9w%=?AGq8{-WwX#D#_`+^yfZm7}r;jS0lI6v2z<1dWglEtSHS{wEw19p3`J??madU>!uyP80sc!VaW-FQz? z{O2~4k=VzCLp-!i-fA z07U#)1s4s;90!RuADUZ1ankeCx83VeyBfx8j}96jj)%#6f~}I!Kr!oGqKza!9M_8h z76)`9k8*Qcy;h)9LiMAJguwrVFxH8I$fOq?;=%)$-Yr?opmEt1b&GQzL`<5Ik8Cbw z9PA+KqO6IDDw8wBw)+H#!(ym;1LXb97lC*u$MHa8(vL*eH8P@W+-T!kLL(kfMb;Xs z)#CTHwS!aebq>T|TrA^)ue4rcu}9W;;$j4cC!-p^{mjWE{+EnRSGPvCh9Yx0h(`gj zq_0nqt%0fHo4^Nf{-ew%P=RCUC%%e^%Bvu&Qc2AvOsWd9DF$&VI98C!Oy%D5xF+Ov zTi4+$#^)1VFEO9^?g9-rs>y`F!lJvi^W-#^k~rcbp~OMa4+o-%`KQ-R(8~mgG-dgt z%eOAVw!$snkVM5rgXV&Zb2}F1e$+sOLzPPVc^6wdR$9EAyi{A&CT?vib|pY=U;K1) z6`!)QRXXH`^Wox9ud1I+3*6|6?_%4j^2+2WYkOHAfeUTofr}uMjVzyASsLUnmEW=e zZ+FT|o|>c_xTF>PiAv{y=r(YpE9RAj!6WQo0L>%7yx)yQgu`K9zaGvW%&sBo@zFHA zxoszgp2U7R88QrSrvVtSkNq5Gd#m^3;bE zpH8h27=`813GL(qk=}J$Nj7eEbF8+|I5w9CBhWr0^%D)U3h0pLb%y5pC&VbV)Tk zuweEEbRWS^jv#>$2IxBY_O~l3Zs;M^!73*2a*~F$WI=mK^t+`myo^|QL=N&%j>&&) zHjCK5YX?f&jz*Uj)=>#XSh3(2l#tG_H7hxUPzk%1r`Wg#)VOM>6FaG<|K4}--HLHI zwI}{X9#-(cRB z!!e~DJ83Jte=!y;*XuIM)R&qvlvbu7J(XQmn%934rjDF}m$w?%=;~w7cs6$axPBsy zKfbeW_ez#y=3MscFk|ct_!<-W&dce)SP!e2G#)R;f=|DrXxb4spj#5Lubnh#Rvp-f ziu4u~%QUZHEnTyS7Pp+_qkl8lV+bPI96HVTi=3L^;7?o(&^SJg@`IUZmc-;yt>ejI zNjb!=+(-oNJ7E&-{qcCX4B-$vU4WG7>C<_Fkb2@_mHpx6BAtos$C|mTq4gL{Bf9WE zosJBdj`7G*mS#H0rVL~gFT;`re|ewcq5Kn3+$<2ehOK%Zg2gEaXQxN<6t66rk(~KDct;(q`Ue^H0CLa#m$R8So z_8r*Cm-D_{h!!K>My5Svk*GXknY0X3uZ;Il`*YBD{$(_7#^O;px?cgTi;hX<3M`)e z1j@TVO!4j^jpgO|F-}Qq+4V0J9k%8|e7<1<&gjIhRqfI1clhSpTkv^HmVZ)SK0Db< zJgv>_69#QJ8Q6Nq=^i~<%Y2VINea%BwP@PZQP6ra`BndKAp(=$hUL;|g1*=%RdIX- z#PYhIgXZ5d`EC1Y6gm$pK$1xyP`&~?zkVFm1&>g?Wtwh-tDXE9Cwpf0W%BE|_(CjS zJ^@2}GWi8N{07}-pNj=Q^rvk*X83qy1vTfjh#cPmM4zO^UmI!hZb{$UcO}?6Z#q^M zu+s^CGi)$;^F(@7VcuV->o%?{#ph06iGGuQgJFYBf6JuNql#T~`q%065$+nscPrU7 z@socu9D_0(1W`5juNacSc-s3NEBiOY2UFZC+bGunqwMMXhG1+5R(?y4Z~B)F>dv8p zL@$eK(l`dyMSD=3%;sCoQw`~babOd>W_wS|)@TuMp4{au-=o6|Almi12d|l+7l?zI z-(Yc&^3EGK#MT4}Do{4yGe6$}ZmWg-)1hCQb5OAo5`mVq-kJ}7z4FKkAPTzvKvSg_ z1H=2V^pp3oYV_}E)Z~uliIT~!%>+rv%I%2G>CTK5%h@%?kI&1(MQ08~c5Ww%cTOXY zVk-4?kIl=*MW?d(ww*d5$al%=&G_=kHyA59Q*oxF4$jXi2?beq5sT0u*CR;6f#_9F zBG7^)%&W)o3}xEpboY|1PwpmOtf zc?91qGQ4%qO%&hsm;b~0#yYv93i{g2Lbmp31M5>~zO7-o0Amg2uZZWrFT?-|Ux`Og#|l_Bw+WOh)Kyb}e^(*YN! zx!^L8`D}oDKCf|?NYXb!1WH%pgNGl-jMUK-oiw^HhV|BPVDm39g!R$gui@=U*W%BU z*|&`pD!)o>{`M(~-~ZxFY$+Ox-lv);Ye^Q8s@A-N$Dd%nY1p?& zBb}9omdDXj^?2L8Hv@^azM-)&P2sK+Gc(Os%5Ld-`uc}-n|CQr9>Ov$d+T1)=9&DE z?fCTWTk(0gQxF-b;`<=+3!;%s-ON9e8T`iZp$;DL4$nT4cZvN0HK_O_hvOm1&aUq8V0Q z)u@^q5sr#%!&)?FG7eQnSH>Y9Cwg^!8SX%QgvX-FwHczsG_p4JDo>>AC0SY73UlR1 z=apYIt>t+T(|gHW=Euvz{esw+0H-#2xf8N7RXnKVA>x{Z2Niu)UH#YsFPV7&d_aT0 zl_QhCEDhi-H#gac=`_gON|jG-!4Gb5j5$ID*^G{plCK5qG6dPx@y|W^SNtujh5iwpO;B=n=tQqtVxPwb zoN*~OKmQzVx{gg4TW3{cUvV28^XIE5KA~+PCXShg7j9$M@_eIzLrCs13Ilpu+K$16XR`^^-=BCJU2Z-dz0(2ZaH|1OUbBRV7bzVtSvQEJ*UWaaDbfF|Yu~IZ zO8EFJ{p(Wk(hq39XJ!q>y#u@GPHaT>#@DCHm2c4k|MuKsq_=H>U=ceiJWzNRF3-{B zu-)Rx+zcl4vb2J+^jYxIJy<;cc63SN>gNGbZBN|yZd+-rhePLxa19F;7HoPnI9qS? z(bFjY!fm(XTfNPbdawz`fF9eN^wJA3w%<#*cgc8)-mdo>!Zm=_W+=MtcnNpkS;6q4 z9VqL5CjKz8g;_q(|BTD9>G@|VZs=j_tQzbuX4gU-bInyaEXUjF6|c^Ux~5AuB3Sa! zAK&d`0b>g$V9e();I`Ypp?GuMQSC9RKYDD7^j|G^FvhihfZ`9|x*F{U9*gTwA3*Ul zF58UfpSuayhuDHtR?U7CwLS*d{9yvca|jXm)1cllM5OftqT5f1jJ#{P7&5Lk9(edx zimq-y5I0?aGHmT5oNH_81ra_1kO)m;((Kc>nBs5G9){C82JFpyIRyhy_2%d3b%JSs zOj9kbBa!fH;?X*fs5Ibs6gOl=UgdGN-uvl*0!^Doz}qfsIT)4Ym*;qBX=!{RifziMa^Jb*ocLY#Fu+w7?uOPqe$ z20Zr^+pO@nOg47r9K|*pu(8v-5n{e3mkSPW`yQVx>qYzBae1Ylzij0Pxc5c2 z8I?3|i43wIyDIW2KH;(pQJAhMN1<~(F7KZ_QiCnuzl6tsK8#}b+%g4Gb9~~rToM@@ zT=J0pKjYoUUZL-;{`?4jQ;_6BUsevd@rB6qS?m-o!3WRI!jO9h(L9}HV&txQj=BcX z*i2*Y_Ru(Y!FGD-@O%KNKYdT}s^QlotZ|!4s`T;tq2D1?p2PZUW)igGWQ31o_Peru z5-WqOrFh`q{SXLfc6GFj3!(kx2F8O~9uML*g2evA@tQgm8ON||7c2hr7E8bTGm4k& zo`U9GvxH4M8Uj7o0&~WfPwLpQ5vScu7wC9AeKt>e2i1KiAcSbJTm~&^5JnzxFMXf= z!yoXU#Xx2nvtnh%$tKW|4$pH|$}fUK_uxN`W-S$3WI@^ty-ozCR93pDk3lBCuA`5`j4%I%T^*QzpO@MPeWpHv;Pl%lKJA6SAe7w}$<@24xJs&8 zqvP;&d&~()P!k&6Ayd^ zG=Ird?>reITV&CE@F6ZQs`&F-ZmkO-j)!MbEe)N9OrYq5eo0XoI}V+Qj*dM0@b%1R zXw8P6bc8O#G@6E{<F=G35`$gnTZpW(z+0>r?3ZTlTSjvh}qz%+~VO&7O|g ztM((QEwi;F#tcNhv0FFH#)bvcccJ63=2-hRv&}2ghT^P=T~WD~l8vJ?FWTF|xT%q%X5t zRjV$=TeDBbO=B2--1UET=Is{3%8&2B(#>pjW3=&mFV1#O>=(UKQSCB)oqQw4W=6)sij{BRkvaXT4|K|yHCW2ktY*!7 z`1ibFxZz<&uQxxb6CD~?5XamEOONcQk9i;egq+{rjI&>6dayxA7VLN&qE%!iKE7kA zi4DfjpM8eBbDpQz$s>(l#q~wUYGzL_eQP#Oxp6Fb+_&om{JZIWG0}Q*zY~Bqt%jkVG@adKb_}%U7+fd(R zpxa^f5isW z7q}S`NW=M)v*^3-+b*2W^t=6lG_3k*KGy7E{zAuL6ELb1(RXQB^~fCdIFR zqHb=@Y$oC`YvL#tJ*p8qpEtvZhioFK4mV0iZ-BjJ7n7BN5j0#u2>FS=*r6Q zvQBP2!%uGzWi9fpNz$ogB+~&|on+}%e7W&K6f|V~X$m?G0diSK#uIrSdAI?NFOOkA zAEr4722#*{+z7Nczgk&YGrF^nKUdv331uba`Ug0+!#Fj`945?k$?YfNkN1s5Nhv!? zB_$&b&Vzx7=lZyHI#eXR|2hP_orVXVJwx3`&Njmw&jKTjozVkRue=MBDoQ9? zS`k2MR=U08ouC;8o_8A_C}o>7%Jk0|S!u=xh9e_oX#H{VqlJ$8We@o+E$4n?-Ad!@ zBvDZU^~ZSQm){!K5Td0C=w(0F-zLlQ1<>>C2Pl3mt1kLq{5Zu6P1?c2i)nTvD+yO) z<7&1bSEzru$rMim((|SCVRaM`jBLnf8pQR^Y}8hAX-XNk(r(h>!S%xo2l#IRqW%{J^W@V;0Ha8e!=T&#I4pge!PGjthoR;T39;)gf3zvbGa};iV zNKGqq(7E_~e>P^86qlje=(Aa&h!oEVJ2Y zT>cO{=`$%a7_)ulaj(49o7P}k!5H+<gsMF*m~K0glZyS~HYg{58cZ zNaS=M3aPp;cI#r@XJa2ngVjN38O>~>lwP1aYOdXAmtjN&IFsbu%#(z`Q6D4K;?Is_ z{Uzz}chHP*`Asf^-PmTuoI7q|apXLT=U(mP*M6q31+M(7#?!FWvFz9H-L3isS^IUo zY=N_^LU;cTP1f#$MZMZo8$sQ{rHV$EWIJ$?&x{O>yh;OzhEBwHRRNb;W&9L z*!3Scql>e?#>q|13SXt~XF;HEmKV&PNbymVCSr8uK9m=+Unfrg`X4}x?#Q&h>k!7z z*rUI*`H66dfSqb*raKtYjGk(DB5-)3?7zm8qfK zv3KCPW2G4>+0=q_aQ|a$JSr_NMODBUQ$r?YfnJ~!PW=1dx%}?-IJ&&p(#H&1^lM}> zR&&owqG`ZuBqq-EL=qf%7ZSVB@drF_5+-7%7Z3PZX4KRRK7^|{;b{Oe2}a{$8d*ui zgXekx;uhh?k2jw+8$QQdE7*^-etT_mX|o$?3|eok9E0Cp*F0*&aLv}wXj?q`-)fxo zz%jJgc0s{!f(z8MI2!|4zu+W}UT*+9@pkKHkKn)6`uyq`wjqxB_IvTeKiNqtPwzhh zryt%9)hqu;@f+V+i0dD?0R2+dQ~ZlZUcvr?G&JwYPS)s`n@VYK{)wG}x~QxhdUOb3 z<@@Z1IX7;+8;_sc9pUxthj0J)&`R_ldIZJ~VJ91 zMseB1`UTBgS<<9&jkjCWixhd-Y158V3iZzwwW*2B?SNJ6ShQC`DNA8yX} zrLV=>?O}{HCo`mMDPDbS2@bo4%>~=N@dk`-OPaYc_y5`Z4gg7ts{dcjhTFZ{OWeT) zF36GN5iW4#oCHyl0{RyP#ejl=926DAPw*osN{|l$69@tVA~_>D=WvAM0$kv7+MW7O zS5MDY*SuF%Jv+NQyIViF?Fz46y{dZk>Q!}5_splCKz_ULVbt9C35=&dD4e#B+Xx$v zj^A9C^HN^Z_GN@mF%j>jw*AJBv8|kkJAA8ZosXC9eGIF%KDt;}8I`%*Qp+ATvW4egum7RX1&MqRl6b%e|U5zPsoYIBj znTVwHS6wAqmn~Pxk=<+3X$p34WdC5jN?v?w*nzY3d;| zNYYHwMvZQPQIEXk`zBVA4a1y6`xx5#AdnQY7m?jFAvaa4|Ok4_j zJ0z1P;O-YrZcav%j^d-I0sMGSynIexY_xj1Yd+g_1dg&?8MD6uzoo!7mM*=fWaO-c z3zFeM>875Zr5>(5odr%uxCKuZ|KlFm%ITbGl8zwDFjWK9Z$X(u@1pf-j=J+D=ydaj zfJo>8=OF1kISa_mWQwlEDv@Fk`}4LqBVzL z(*sBlK7ws?@8aP|v}WlCZ{$@sis&-e+Yw*(D(^R&X+)@&rD?e$L!_4j^rRPfv&G6rHfP7pX>E7=;pG9yFtInryui? z=C?-LLEWG*5AnOrzbflEwe{+#qLl8L68pxhsy zJIFr#K!ja!vy4D+AUXnbdX@FJ^e;=nb6lj&&2iZrePJ{pblxsqO5!QABkXl^Y33qm zvXcb8i+6W`bvCM9iGI~lzTZmw$ojr8TWw~T1E*r{Tg{0FFFi{Oiww54&@{lV`gE_1 zQ$Uj!mFC(H>-A9bbpG0I>or{pYC3Yuvn}21O_Psnn%hi@EzXU461QnvC8LnV9N6|Q z=J*H)A2V$7rD%OLvQiT#EOAbUOqWH%E;}{D%szE2gVr>vuUtC8mC<#v8v4}{9+g4+ zG8cjN6G%G0UN7r@vsRqH;=_AY?4Qq!!5*iLfM9<)U5};#?T?C+yhQ{04`|T%BNL?5 zRTQ3YLdjA=dAP1|fU0s}^w6~ac8}t|Q}cQEo3%7q ztZS_~yUqIY2Cd3lf%@_Bt8Dk1H~`i+snj*0WpGoOoGjGXEysuV#BauUX6-$3+6a+p zJS%%MP6v_bMRQAW%=P)uUjK>@?k&ujwbh)7Aeg?(74@g3$cvLc*RN1tKdmOuW=dne zW_j~YISO-p;J`B8X~YUxKcGb!oHR`x8e8HwuQkRDDq7fdbmYxK5ky1$rZQ!gO7a-5 zk4s(62}ZeS)j|60K%Q^b>S9FeNXkLT-2cU2tET$DYtUi)QD3lmElJ@O@tctH`sX}z zXe#P^Q(OVjzW5hZ%`Nq$OfFDu5J2_xBp3f$sQ;kGq=NY3S-eB@v%WtD*2ABktT&6V zAPVEvzf`U>-)y$Bemp+6-$e9J+4HpPntCf@@t0|$xaL!v1pUoUFyge6ohuA%{29;4 z;w5hv0>LXuE7e8S50roAk0@K>@5-0PrbU9?RGIac$szeN03*9+ACUZra<2A7kXks` zFa#|_7K9R?%bbMeBW`S$o80ZmbWMV%|>Ix8t7NAjdwz)EoUkIGW}`0 zoGfUMNb8HPKjvouUHQpdwaVV4#l#cZ)SIugd=)PAU&ESl|E>4APw?6eU&TAc{@Zwi zQDywI)E~W3tAF#rRQ+aq^f!eivX$PvmGDYj_!?Z>YZ4;fKQ<2>9DlGr<9g(aE*Xoo zxlhggjx!dSv)V~?pRPI*>D*I1yIkdE*|u1k15xJd$A>Gjj6*xmG=yiGjYkhaehzLt z`CzqZ+*y2+dgIg|sH`hb-U$O!8-wL|{-3uZ_qp>F-DXYN*+oK^U#4hOQh{!>e#WZU zHVgl`aZ6Dr^KR+42iRHUjABkjGcaI} ztMS9_2d3&@XWwtD>oLXnb^~5l*Z=(EEi9DlA~{LO*KLi%zjqimO^yb)ZNWQ7-i+54 z9ipP+hgRDLRT;^!)S#HLXz`6nQ+r6g=7Q$w0({|&L_x|b{Nciiz7Hr{6xR!@)L9QU_-Kf>x=+uDiqvv9}HPr-FB zexmAH(6}XzI^z^^o{T-o58^s*S`>dwWeR;zD2{Ru^2Qb{z^+U>xbx! z$iA0Y`r@Au4d&(3_r@t_jY0jh=3XxjEq(Et5>14NjvY>OedE?UZP7`+SHX1UO8O?y zzhLtstXr^qkG%9y*}QAkjs4Zd?=3ByyY)xElw8r5M&hqb%vvVxvH_LN zlkNmHA3GJM7eS{>?V5gz6(Yw}1-3r?`}pFf^@W`HO>iym9EqD>TZlu)4P-rkP9n|+ zqjwiBPevGXK{#rrYW3N_fQeJ}+2pYCh9Q$=%9xX)>y*k?tIu>arS~}zpw4%tk>}zm zJnEoiqiDG_sw}7DW}SMTDYvPeCQqG?(hiCzB?DL1oU0tI1V5YLktUh8xMT+^pAj~l z^%;N8nwWWRE9RD&+W%2?x?I1mvlcE$tG>oNp<=E~9t7evG(Q^;{OVp`|Br0gw*>>GiSo zoALq9hs#7!Zmxcq^%JgXYBQL3)DPp~9ix0IPV`gehs$Jn|Cyg*Ob%=shaHW>4>_`+ z1F;*Q13eZw$N0gN!IZVE{urgIN)HPb4vGpyO|9{#URE~LlMgqUpD8TmLwk6sNLNRc zryjqv-vJ;`6V_{s8z#ZnK4p8-at*yIKX0-K^e9n*Zc}{Nu3=anR+(PwnX{AQPGg@Q+6~QsINI z7*o6fp9s>1ng6*M*R1}Miv4>3G03@^pL2%4PWQvG_AdH{JUp zW-c#``J#7Kd`Zjtx+{jdG2<{wSD(6OG&i-P=vs6UI$(IZz-Cp7cK=h5$Gj0_66r!4 zYy&4J7q1HXt&c;#A3vP(y`Nu>$2R{igl=HO+Svcplaz2P|9lP3IWv#po5%E%C$EM1 zLkFT{J98tk&ly)@_mzuP{>QK1gDZY@BCb30Vio^N^h}MioqtmCV>c~-)TmX6^xlPl z=2iZNh?+O&)1xTGuwt^^F1f2_~fC2jcW^Mh{%A zCfTl9wGz3_zKB!59^0eFLLFb&ssYEIAAd4;`mSHadUfWiUZwU_g{XX-#K?Vc#+7@h z@+%jAjMwkE0>3&bet7H5i@t&l_CFOTt&D$Ia_zZiqHXvV*mIIPF~C~$hhk6}#~el< zaHA?JRC z*=t7+Q%a19e%INy2n#-qf8aT~Fk$lxmtw_$*!OGlVZQiTTz%DCM04lBGrob5x#Xj= zKxu#rG!Y`Y15b}>B3Ru9A6L!T1W77i&q&S$3N|mosVA+%b=RI-uzAB&JhFR{%}Y>M zI4fx@I5(*srfe(tJ8^&YYY;@m0p-vKLlAjMIu%Z%>_M#vbz{|KT**1DQ+dt(`=M=h zYgJt)$w+6O2hg80Z{LkVqfFEI)Gkoor_#vR%joq}lY$x>P9EPjm_5}A>wYJ~cNZs! zFf}q%>&-OjsE5)fvz%{_n;Ha18A?tcO|q5ac)2u%qM_<`wI!=&Qey!4pCXv`nPVWC zbYaPJ=?qn`PkBm4+X)A!Ptw5~=vqrb$>;j$y=~1%ou-w3$<4JyjKI#v{S-SxOP8|z zo6Vf{G4p(Ssw7L1*x=2-Eh9Qy%(s_Qr%keWrzmlJ^ta`-wMFFdB3*_GC-Gda$@(ysDYvlDQSE`FJ<;D>F_bI#+WE#-thqG4AvJSw zllx6oaKxqYW-LiR{3XCW{FHuJOVyumkJm;0C(`oi<6`ow^N`1UQ}AA-bEMPb3q;3;l}1*!(KX0!WDkG=gc zN|xxlPx?-RWFs9!d_(W8+i$|m-Hyk!!JM+Kj%jv3Ud5&jP7}1vx)Z;>wiRFcpUPSAS7OfBo4p={M6v>teqqG%j1FqAQ{`R3liv zY$=+W3b$Ov^4QUpxx(6-u42XWSK{QW;=~iqI~$YNY(VR?7b@O|UvE^F%hkYK>cEU< z?Qi#kvvqp7Gy`ft{%Xud-}1tUHE$e02zvZ3$KkyHdlrY+r77x$Z>_F}ov<|yQx(lp zmEC-z#D=>MPtoS;8qlwQ{P4@zt-pYSCf|T7o}aDaUs)G!*_xZtyd-|})G{+uF2$0? z4QOt1-45s=7$2d0sz}0=)?v-94pV6-Y^8b&`PnzC>xpv10^O&0{HFL}&evak1jiq7 zMXB)e`3tb@;bVYZ;)j)n3>$$p))<0%tn|LH$v0e~;?K`M0vn856I&e`ziDl&L!-ZW%)aHvF}DqO!*FWob88mqPbig% z5S2@pSyQ7a^1eByi7>pA)heKOpnvqDw!)lTyrd1e4L^f%A3mw{_t}|~u+e)D;-%ul zs)J|D!AlQ4g%Q*CR&n>kS`wc=eiLqa{Z$ov!lO0qQ#wBgv(1JW{>qU zFnGG4_!|t=C<%hFcujucr$0$1G;>pWpi4450s;a8vcfc!l;JaJq0yM-D7t`vjOfwJ zn#<+mATscB)lKoMr2dYhWF16%yrb23hlS}#?^Ig0J1wbooTyzAsw1y$1K@(t171wJ zzK5-%)yUFWkr-jw@4L`kz^p5lo3Va%kXf?ZxBikZkXd+wmxX<`VS4L&oH{hK9go;N z|2_?Bi$f9_^d4;e`P(@3e8WqviDj+I*j%p<(vuGtOB>S~MkPnI25Pu{+@W+SubXAp zb=W+_PtX}6N{c+%3sb8`mh#;Qn}V2kVsyoEZBDD+#x8UaoT!2vwc;=Y$0eXwp*S~9 zr=1{4g@q>_7Z0cs%mHydej*uK>ab0uI3-sfRgp#tw>PB9x{!W@GgaF4XaXgPK=}^A zY_)9@MeQs&IrK8-m`IBpw#ldS186z9ow_Yt+u+-qYX%NLBS!V))S zqWXjarPH=N8$DO2Ai}1_v&qyEYvH5cHvZ*r)+!ZC61DCoof2X6lBG&nVUts%ksgxx zm*+ASm*!^#xnHNd@@o`b{pJ+YQ0Rt{Gk!ii5>OM*tVhq|qXl+`7br#N3@!5mcOugAkp#05K)Mo=rpPQ7#o2r1a z&l(Cxeom7+2aO+5zE11kM7C_7F{I!8mDAf}DPPyP7+6{C-fmrc0!&ERwVy$xQOO!v zAwQQJfU*^~coj5JCehPtbs76=cLUPRrB;7(FNL&}lHe79RENk#PpG6D?;L;wf3qq2 zrHFu}r{$vm#xxhipSmj1wZ(6vx%0QzVC7-wWB)Pr>Ecd7Dug*7Ojc$Zw|R9P0NCiL za(aD)NUG0G*<|{fpYtDFa?MH{c7FWXo-yTLVMG1;+hW`Ke^P}Wc=rGtxqcI{^d*&d z-y?ZU`N6nCXg*OvRCylDKAwd|W8%-mZ8W^0upTbPD^I+jvKPw@jB>Sr4jLKPn0Eto zQJlNWZkE|Ky*k9q8~xSa&5ry&wma@TT(>O#O!c&VsXA8R!@I9k!JG02;+zfZAy!e)O~W!A@(Tq4=hx z#V_B6J7-SCS2nbNde$4#GcK8Yj}DhBKg8Wv#&5#OANY&H01v@#KZ)P0wPWdP;PG1+ zpSk#JxO>ZsvApOTPnfm?7GC-vys`IDs;-Uuw_(oHPvL|0cT)M3{i+DwdQ+)_#pPCi zIuFZRhNE3YB$mGM6ke9&6v^bWH|t2OoN+gIn2NvExFx2p)8B}< zl(87MdHjmNH=lSJ%O~%IZymQl+3oB9as^&rZ%>@{n-wbmuIvAdC)WEqzP0^ei$H1T zX2|Ym;g%iKd$85d#GjG<+TB}X?($U_UZ9CkM)&N+_}X1t;^I?wQRilBWU&v`bV*ju zP?x)|{HL;c8x<#3ZbIZ+U4aLt@2BF2PiVxaPv4EF)|#T?2Mwzc2cp`@4f^=G#+~DD z+r{^6ShjLyVJ^)!$_cnp5KP^AzO5{kPRT>bMQH@rUT!uB;%Zt90sEHTRxd?M$pEH4 zs$N%HsJdP9`W{(Ob(%CjWw|si-5e7eJ+n8&(zjzh6H^lEl;fPr0k+x*Q=7_d2bY zEB`E@uGebKw(3V79rq2=<)S`G>Y>KAn&X;opKgDur2pCj9MMBs5%2!Z%__d{qEGQ! z^8ma$XsBvF`*2WkXsBzlDM-;1W%W4sFqQz%FCxiFls|}M)CZ#e=%3Wf81${T*ZHdPF`SjOJfbkO1#-oQwN^GQM%x<8 zFm=Ill{;t9aC|s$c!|C)U;Ol7!XL)NQ$_wcGhdI(^ut%elAn|pdOY8rUsoLeI_UIdz{RD7&ZoQsN?b{&rvoP9zMlS{f8eo?Kg6@& zjK}KA(!7d&*zHfg7N_kr8Q(bVT@}CJykqh0!NZWByGX^yeEu~2XtM%sD>&&ebkhFV z`=tX)+88Xffu zGPSz{om4Ek?A5>G#}_@0{IK}5X9M%|F>A$m9B|qXRD9}yLWAbshYNpsn~Hz9az17+ zACG-cI9&1BL>YuClr6bP4Eyqtt#cw=eQrSa%&D+GE`rH53^Kjw6 ze~9DuIY`C7J+Vm87JtC?z+<+-zyTQ_0j%qX;!#%#4NXNJ^^It5>Q}N~Wpw?N0V$l7 z#rwCe`>5bt_4ob@e_6D7QTv6md#4{bwq1^fP4T4@w!+WOJUXTyT#toI#^Z>y;)l1! z_PDPgR>OlZcVp%P#VuIe*)~w_Rg`->lAvghr|T0A>21AW)|~8_W%0kXmt)&-Q0=tU zl%!E%s!wh7S>WPrw%0~Wji2-=o8;*_)pxwyYB$qyMjgMSE8R z`W?wQv)KQ`hYeTPx%1);>*$hxbt5cloX9?`D0f5{_3!A!e)NF#WcBK(4YO2ucu`O0 z7WIGh=x$!yWxEbX7^cY=4U3weiGFYK%YH)mUxG`r+npBw7a zWhh=$okeUL3s{Gdm4^=F>`Ob z70L9&D8dpKpx+!+;-|?VwX!+**AGcN9Fw8`)WbN%hjq&8XZY!FNTT{P$Mq-CCSCqi z9_Vqg_Kz0V+h@MXiR>SuJ*xf!v3i(I6zOGof2-Hhi&nib{8O$3?0MB;s?rxL`rN)(jmw6xlgzog`babn#M%=D{l7zrk|?%2q|c zbkS0v|6mMg=;Vo8HFQwUnrUXcAd<+DJbAZ)v$I)5TQGkChOUv;dAaPrIR7ixtMCTD zJ0Ay*%-Q!}6p9ZYEL^x8qW=&KYRZA`$u=xsya>xy#}B{sA3O-n9eNI?4J#He#Ik(+ zRKnoF&G2St+PkVPT1Q+wI#bya~L$RACiZ0 zqjE`^2<6Xyw3TQgki5GXnfo)q8+701v0_oIf4PAJ(HNaKt%x7SUXmM#frSJ!&SLoo zcOFM^IwAw*xpL_}d_z}dRKEXngS+bwBkpsZU$mv%xeK&(t{xwGr6V8UwaT>j z+)S=y7K5SZEMhgZd_mFX>AdwixiJ8d&y~~jT>WEiQ2>5r0Kt!1kA23Rs>9Y79Nv2C zEevdleVph=*CH3cFh9nk1QgY0x+!`i6Sd0Aj68 zej!praCtv0Au{M$ZJ?&a)jTfi5D2)vJdR$!R-@sjET-+DyiIGxlDB;l<>p<_H`}NQ zDPd7#2P!QWp(9;vHZe;%{h9^cITy0t1L#g!qdkN)*V_s@+^Y?p(a?@4wI_TJ13I;W zfW8B5y@`YE4{Bvn6hQDKS?n&ijq3RN&fWLZ^SQ%flZRyTyLzoQWuqJ{&gr7kx%;4IeN^8C zR2$StCZHb3aa~obU zu&~ewqkhV2b9D%UmvodB8RHZvYXekjF{M{|?eVR$JoQ7AapT4nDFxnt|9z}nwbHD| zq_y=Sz!Zz1WMv17-T(v&_F`Xw6oGQIADDAym+tMn(;zHzSkVKYvYfuoj~u0zS* z726ew5bJkh@48>VBN>x7eT^&5!}k7vzozG4B6}itG}N`$zb-_dX&N;u*8g#){zq&3 z%A^gH`<$c$ZvCd{%1$54_(bxJF32Yh`Jy~{Oj@xVqh`nYdiRorc&%kH<}~$J@zuHd z(%Y#bc)gh_O4s7%RiOM$LZvr5A^j#T^`;}OOW8Mf8Tss+u8__*+mrmpy_8>kvym>J zkoGrM36J)cHX^e8O;<4ZmGYJTY5byeQNDpnwcorN?JJct=xm-Zx$+egOB5T*2o3nBm>eJ;->N4fg-^5mD=tHcNt;O+J2GO_(jV+(5 zp6%aKkA8)@n*16l`poJ3?-zWQm3`NzuLbn$7kvs$s5dr8d*ysSk1mIPVo{v1`i=KY z@7SUyeJT?+g7gWAvr_$o4ua-GWch=Tms+0t3iP&{=~S34BrWtl0+?y~H5-znA$REv z{3{csCZP8)H_U#0B^+rMr75i80|pIFBJf6W?H@3B2&#fEnd4P4RB2Y-Y?qRUeXTpE zF0!B0;X6mu;bo#N{*34C7hZ?Q-gpV`O*&5TJZi06x*{th%}cL~_f~_~XoekiXc{;a zO{f+kerx#itD3#5+~P#2YmRM(v%5SY8sg7L4syMG)||o>^@nv4^=H9t#B$9TIMmiL zb!Z+OzpaL)%EdW@2DX<`^o4TvF0b>T3FzI(p=nV1ZC9cx{_4&^CeEUH9CkYD%)-BT zp5zPXdaa@njSYSC{Sdi=-Se_}x!9r)8eF}VqUXT(?AhF}xV#29==fT)K;NSKm(Z_N z?dHbccAtt$=j!C*T>+{sT>BDG9-z4sqV8pwI#TiCAJ73%qvKOX2Q|N>r5vR(oJP3n z6BZd=$1NN`*AAR&r(pQNQ3jy?2tB=hDSKB$$Lw9XyU_l|26`Dw zZV3;1HHA5N6sU=6Qw$rZ`nVl}Yx?+1Cs!GtX=+n?Tc33VTwQ{p1>Cy~ zTR(gBzYsa(3i=y8L=>UEp+SA3ud%T~5$nEIgh=0_&w?hOk&CX8E++FsZQ>-c9ZvL9 z7@eLn!kUm}KlCsmm`<==VRQ}^_fdlOJgWa18ynRFo)P*rHKD1gU*SMIjt^*QQJ+oC ziSPpC?nL7Aw6*0+YihTESa5~*xB8z&^diV)>x8X9M{OoGH;F#$73h%TOf4AgNIrwO z`4(FgdYf(>f?9b!6&)3FkziFRos3b zotm#TJa;HmB(ATYTaKFggk4pJ%Dv7x+f41{dYBq@CBkPAI}f36tB=s9?chIyNUiif z2T+tp;98$J55tYlA4}Ug66X<_i-!(wPrbRmlu zNqu4v8OodW+N^+0E?XJ>Q;pKIUZ0sxAuAtv(3xcxSUx>z$#=~2cgIf}8 zbX1;gNy+YjCl5{N4{FpLvdn#rR@u9*Y*z)tn(BYf&(5MI)H+as-Sk11_ira4S<_ol zo9*bX`Po%t%eT+hEl%gl;;WC62d|=sJ`zL^b|eqyMGw-fZd{Fg@zqHAwtVaavYTek z!J=rWJhKceG_G4Uoiw2XDn{h4M*5Xg4`fO8@MjcmDC%FNcgcfD5h7hvdy3Vo)rhtg z!qGR`^F==+Z$3EK%MoqP)WcfI!|}Ozt~L}O)`}i_QxA|9=kMy`gKf#CF8tV_k3(`v zQi~_I;xq6RE`kK2LLMfm)Lc7re_YC_0K{Q|G_sQHS_icxdKKcxruq|4&>#j{1E(t+f`Oxl-ojXO}~j;TIu_nf%y>k_xIgZ^nv*`fA! zlzHKTKY^(ROf7ZYZ0I-=?oEp6TI+6#wRAzO@R_eQg3NU-k!N|yTX9| zESf@CXlnr-8HH+;by*3YJbjkwaf*iG!5!<^W(3FEMMtGere5DWIIgzn^>Te=)(`l} zz{ySZgRqpB1Z~2@);APQ7EtY`Aj_y@^t_*J>%FbR94%8j1RU#@acC?wChB`NqS${D zrH8D{hpxnhsV}uP&xuPzhq9NBwh1Eo&WpJcFS6|Y%kYZwQQW+(y~srmzQnp zWV==^njPG2gHHK(RKp={d zqd>i)er_D95uS~U|8Ga7`P!3m`p`^M-guO%q3S`q19yztU*aHJRsibv+&d$lbpx`w zmm@5$*A?W$K*s+zcvi595(&XRn(h#hKY;9Oe7%E6ee{vbDYHU+_K58E@IGPL&%O8J zS{w40L`rH1V05~THoZ0+tj$p1-|=Oe{iF9Wz)_ov6_^nW**C{KU`3S!}C2l~sOzaAF)Buyv)7UpB&pwL;ks-dde%(8nv9%->V9=ZwG_NKl&Q z;pHw>`k5>uNT>2f^w%FssZ{F`|6TI;O{L;2pUTT$!+b-?d>1^~7~iehqYn|Su#_(3O4m1OnT+rMbt^F!?(pMo(LxzHcV{y&1eQYPU zeI~Q zJw!g>N46;7h{W~+%UPEmJ}_c-?1ImY+k8#Lwk}$*c^C<)l)RKBV^s2>sUkD<=@+Yu zXCfZxwBgIIkb;g1kqusFA11MLx^aOoBPRnlXO1qLq@CVYX{r zJ9AI=`>0fU<%U+?U;ZIh{%f`l=eAw$H!Q=wYY2U;l=~DNE%Ny@?pJ9dsZ7=HBT*l< zV@Ft!PHj2-1P0`B&f#$d-3|{M!$V$xqP=od{8a6$M*Smru3TY2-<9igu3Yc(cj)KB zSUi5;Ure4x6^Hl{p1aPicaxQpIYP|7i0$e@mk#po4op1=*W#4I1%T+wn=`6iY_mE^zDjg;6KwI(DR zKT!9f!Dg-uF+Gc|)BJY2ShtHRmt7$uJZ{0duON`nW^N-(vIosXCY4Z>Uk!Fwpw$U^}W0sf1!)d8(DYEqe8zh~m{%dvZ?u+aFIxn5WS05f##Vb9* z+Xhu{$dsLmTm_@jQM`b&0~}{oYEnuZjsLgRzVHMZVy!|t+{vZIWws>6jL1nN=n2%> zyP@0+4X7uYDPWy#<{34=wcr;8?_sB2GFQ;0D3(zcb@5hz`JAiP%fPjn?S2|TAzFhs zJH#4EFZ>cG#EeTmg;I)8iWqx?7*UEC34A?1ZabXy+wa$dhE^neQ&=&>AqALs;bAGm zcxdYD&58;A(oFJUXnFGQhc+Va!oQGZjagRkC;q#niU*(m3dLMJkoX`Uj4Cj- zW#{yuGfy5$)jcP{K66O0oQ;u3#zrLc;~{g($?PFu7$c3NJN@;f{=7;+AiCB^k8@?V zvL@?Jd8j%wsXiPK(AbEY6zsC^sRJlPe9(F#isjeJ3Mq{_qWYmk4CY-*iFK3o?7$Ug zdDUNig@$&83qdRW)HJU%xnswyY?)cRJ2OU7f^)OIv9^iNXQyA>L237z|CEdP!2Lzf z#Qc~b1s175{v)ZXj91yxn9(@HV^_}!yV+HX<#?)i8*f1u3pKa3#PG|LgPsJg6DKyl zl~@nwEo>Da@2^yqsCZr1xfl|bm>TV3oqF5yskSK5q`%19R@@29s4brQGxoV5Z_%b_ zpIdJWPiMT+g1}`=ZZW1{Oq$20`3X2PT$+)4{^Ivzf%Al#=7ItT4+`@&UY!^}`-K62 z;$V@j_^*6hd*$dV|!+&R!6`?39=ArDYGwQuVJ72ef$ZMlCJ)$ z24|A&KE=Qgnj3khfj9@{8#m|S{&zpU{_^Q|uTiP30F;OZf(G_K-^nyWyCi3X`C?d! z2=Zu9wBVZ}>JyJ_4{uyuUti9~tmp-qMmSG+rF3SHG?U0QWR;9ZHU*durBaKh&6zW! zZmjvla2!32H%Ha=(hTz0xApyr58wQu$hY>D{W0lbrPi!I+SM;tw$`98?rI)gQ^Kb@ zP%gf5Rg$Yu--V-!Q=mPEzU_EEM0Il5Cvwdu)b;Me!)DE#H%TnP?5+Kw8e-t@`V|D)U8F2F#$A~!f>i|Sy6I_{f!#z1CvV-8%Fh@c zZdDFVZ6Va6c}I%Nuuq@qse6mS7!)_nm*0W>I{-)7+MpdQWwIraYl5R}BFrEC3x3eh z>ow`XvRAxi7STrgCL9z#Q6dfLwP4dC-B$JHW`cB4Kar1F z+SJzBjp^q{Q!sBipK)&>JkkYJqY{W%jf+Lx46jH&*Jvi3n|Sr@FYFwk;G27?F>@~4bMEV>9$z}&=Y48`lvHW>cedH}S7K@wo&oGv(5*q1~s z)27#sp)vlT39YVM=F2lnPyO#U4X%^+hcp>$D;OIraW<9CsVDMcZ5GvrxOS|yeDnK? zPhb&r2c)QXd-|6sDn9NkYp>@jnp=`fcj)@3_85CbO<0+UBgu}bz+&#s0_&Dri>Rjy zlxiK}`>tjcZti;{{lx?42(kUnBpYB91W;7>y)iMu#}b!StE#}Z4#4VX9-{?YoZ zlcL;B#)RkKl<*yTIN9FPl7a3VtB{9|##lpNrTn!MS1y@ZV=*}yx)i@(U28!m2ABmx+buaIvYE`HUk3*Z^up_P_1y^>;aQpcCVV2G zDO(o#{qaDRtKjL5t&VHHfrD9Kpj7?NUm~TkHTLt3#R27w?d^2IQ(_yCWF{>M?YcRtZp^Paf!6ib%wHr(jKYq6V~q~WYy%962X9j(3Ky{j3c>pR z7?a(sVoHBFP(7u*Uha>9UZu!q{TWO{w(B(e6ImIu^=qvKUw-HCTTND+@>#2(61p*d ziE;wm0bowig2mNW;87FTn>1wU6b;9?QOvvMh>aGzM>co7;pf>dl z)VLG#%s*S^*_rR z(#!AY)>jOy`5VNA^3s?htS|3!El&P~4L zOPmO8pQfC}*a+k0j(55u2Nmcx*Na8#zi>*c?91q8FK)OF^kj|BkE>xz;1%gaUd1_H z@m;=yf?gIs&GXJqovId~;ObU;jq~@<#uy1W$n>NjZyJYcHYtJRjyOqu!`bt{QZUuw zRgtnllqsUwRhDC?;o+Mx&jg#Kqf%%nVucinC`-an&fpa(=0%N+u7f0zN<>SG-qAF3 zDglVv$|}5XW-vS%K+%_p}B^Ur|It`(2?#zy(=IS3K+Hqhhz(0 zU|!FEaH5Uhj>{ia)TZ!aoC0A4Fu=k4ncq7rZ;*nJ5aB-ThSBsw%k)w-7xpZAF+ScH z9WsS8zfMjIKAl~JiQtq~Sl=z~&;`ySvcIPReYe#yGlim#ipGk4T5Nb9^lHfWmSH(64)`^G3~xum z{jr-^AWto*`I!xg##|AYYDw#v@QK1k8coN^o86K|Q&99?OesVQy^V(X*JRo2o62V5 zCAVcqKG>n(kV3P$P!hH1$T)$xbvKp^9PI5QW_&yQC1Wmp^RDHM;vf^oqH&eIg?Rt}%m8|JSMc|2McjpxN8`4qiqf}8 zYDt!8qTFU$E9B+Sv#TBY=J0>{F&raA&|{Qvs;Lq8B~7cx9tD)@XZ%HuYl0p^tC*9YFNig)>!l@!IAV0^F-FkpGe{ zF6r=NQU9){e$(XF63jdgRM(KSxez~s;+`3P_{y^jM+;BvF+>q}dR0P=t0p9VW9uBG0;rkn=3yNzpp^xrZWiBd!Ms4<(8?KI(yq zbU2<%8)ZwGH(@xY&us>$ppzA|oj03$6Q8$(&zUhsTP0(W?TO5WYsW?R-}@jxZ?m8g zFADzv!_cL@B#Qh>T3*kkiSmX}R_^A=m=w!YIRboDiSe&a99*o!o)ZN_rlL_Tz82Eh z>CxCTTM^?NJ<9i*`SCwhntaR!OW7@k_`Rr*1yFjAsKs1Tfm7gLh13ddfOM1U*;Zid zVo!s#Pw|!pg2ig-ZNQ9LMo_}8noz(d`~SQL+jL1beV`QYAK=FmmWnavRn#BJfScyu zMdS(z+3!#*YqhNzdaXZOPP8c{7g+h(u%`C9w9=5&snfbx16QW&x?IDITm|B)PzV0p zvi_SZVwNAc1=^A9wQNx$H}VMUuk93d7=ee8;h~?WtFx4zs)CY>i`-{2XN*mH3 z>6yJfBhL_S#2*NMjyUp(v#@&#@bSZmm$1nLATTG0IOy>6C&clUj2+KpIPLVd>GChOvEtVsr;JDzBF(KE#A#`dwWXRRKRHJZm zv+iEd&|d`RT+BDrc1)(??Bxog5}EM}1{b-Rk;BK~KH$OWY1eU#CcLqAIU);@+th?Q zST0Zv9f74mu+z6@dtXWRM%l!IZ2enflJRx4x9{Ma&=Ohik)7pllT7=dU6;@*S_joU zZHd|J?EZT}xEo95t_A`R(h=o`EOE)dV{QLzYdNW2u~hVO7VXz<>&7>SdT(nnN>X*gjYSOH${H3 zAEzYKBJGTjX{o~kVvsB4IgyiU;nN=7D90Le^IP@wb>+xtWDv9RW%h$y)hj`g2)_M2 zWQi`&R!+y3cj-6(3(_}Y4j2iax7CTX$cIK4_QF;jxl$OvxRAiDdITT}ORE zC8OpoyIY$xa=L=?HQ{!IgJ(gue_Ys`nxaw^&n4veKV?Q`_GvHCnPxRTm-0BEBfbo> z=aLm)?%pIGYsntjAdnpHjS&4;Gl=ziStbv3UwVGC?e1J71p~s8miq4@7o5orTx%SC zltGVBBc(AM2@ z(VqO60VK`77RbEg5R!V=7fXHLW|HDDvK1PYr(+r^gaR3&=QICF*VPJY{pa_Xpcyht zYJ6f_m2OFnNee!U>O9o_meZ&TU3q!FJ4rD*$|!v?f7~Xp3Lq2RXF9LxXIp1;t0b*x zPos*{b-9_T&P&`GtX04{s~;1!4T$o3t|Njf zu&3NINVJ)S%w?DTsf^DUk1L+f5;-3yk7M?_EJr!*NG6j^#SZ4i0cee@=c6rD<0>MA z$YRK)6PVGH7+1mJaL0q3F(GJnQ2Ldd9Mo3Esh(~0%cfzq&3NT^aHy`eO~>;WdgKsI2oa zThgR83V&OcuJs01pstnrcfll#Aeg^VRaqp^^3H@)4+NT+=#wHXz|XhhJWSbB;kA&{9;bwQ4(mS4=uB$O$@c_lj& zh*ix_F6}lO_TGudin?HjG%|z&SS5U`^(y6Qre?o}$bFtM(Hb1hrJ-wW_@{0{rs$Gj zJK=Erdx9Dnd{UBar|Sk3uo5o#U=Ty!r_-Skr@V-p1( zzKyc3+<)P(=(<6fyV73ZY^kDeTq}ygH>0<;mL<&juOxwjoe2|*-~GViCF#?;;~(zQ zfV>e2-w_|GdNlBYaYlf>6&fjpID)MPICHeI{$2N|hx}7F^m}Xgu~UUjYqFi0%AtSvetb@?$euhUp!ba6&D)8gD0{L! z{>_jehM1X4ELE%EwD)t&u;rW2KBGOWZejmaV{YiT$@;ZAuIfx3=$o437n2dYNlLB)__=H$F zDVaHVDTI2AjF9O^HPon4Y3@-K4jI+8_DU?UX5p1G-Pq z&N6uk6?icc>nU*)StARNGCB8IV2$_{CJjsa!N-Gj*5LM?hZoP!de`9LB{8mamPzN4^{m}22E`6|!5sxk(7yO4 z@3#@b@X(it&6vq0seb`u*X~DC?Cl#75nI}s!{Ew>Vsih@_#|6tP;sun<8Wo^*OfZn znzyO5xS;0NEy;w|rSza5;)mF4An03Kbli$c>W?9{BjQf->THJ1yUr(`=))~V@m-f+ z0v1h0GI>$L#_2{I+jV^%kWaaB?{Jf=S1l+D=iX4XpnyP@$CQYTyM-Sow;>FKDkTKk z;cn-hk|84N4@UAN`u`H;)CoGSd#WDpxhV2nq7~G0PMY4=mwvkYI93Lj)o1rhUI7a#r5Ujnxbe_!p~ z?Nety@;`dl%28_$B=YOt4H1|Zjc)qDCYlt#-$Q5aq_<#-{B1Sq{U}+~u7N9}2-A4Jp^rJPe9U~M7i zeQxAKotPq#M>&Hq7+@pBllH~$QNKRXv`NCJd!hVC@(up@GF?h{h?kwaJo@F>-GG|Q z5bZO0@US&@&}!2U{dJ!ga-oYcpm#b+@ixgx4cpy{6P)b43D16~ljz&)<|yNbqMumQ znw8s0dp{f=MQY^W39OKlnviJrQz22ti4XhTihE5&*dBK-niG#m)>|No$n_O)48S}s zWRn?T&uht4$=5;Ajv{p}kT#1g6_2tIK@|I<5OSs`glD+y_8KV6ToR5oO~Z}-lxIE7 zd(N}!_A%1gOK2IOraKFGbv3{Y0(v#>>I*rHc56JOrBx9&U4p(E<*=xGxA>MU2sx#! zB!Pn+hpw8uxIcX*knZa=_%)R56k`0Y5Z0j?6E`l>G|iB%!T9uadoUz&HMb;f=W~fd z`dmHkII!$h{(uF!li@p2($}z-(9}f8)rcq$+D4vgmTb}Q^0i*|4$?f@(bCabX7QBz z{mHQ5n!N-dW)JIDJ#b)NrzF5LeA`yq2EAegHYI=~bF0>zM8tNR4q&iIE;8q^xcKt$ z7Dr_EDN0W-o#+5x8LaIfRNvdU>+;&Kleo7q%WoMH5^KwoyS=}*Z6^WQYwV5>i)gb#{+%r!|Ih(D@FZ6r8AqEfaZV$zB) zznH(MrHqo*5=F)+ES2{+c!Ba1#m3|@VN}Wa;UbHw09g31a-c$jWXidxb=uRQWX$nwb2`)F=#e(U z5rCrQh?umTtx{*sykd6Pg*-+ET|o_2g^3CtnPaWO&VsXI;l38EcUq`sKlqca6`;&h z*Y*5+b6#Lj3^+7)_#)8HFLjWY@!X_^VH?6l6&cNW$}6^kQOIjdi7vWqrOF9hgPWBoT7}9vD>;g3yQ6>CX*9)KJdGLUkt4XdX3gV2xRee6;o^MYJrkrdURkOQ zwBuVxA4?`CW)Iq|DvB20#yu@W)(QRhnq=hijTR3HfNTzY_AF1zZPCquyq4p#Vu9aR zKFY-485CKh&JF+r4HARA4y!TKB++LDyIvx6!aAZ3Roh$vfaxaUMG$>-6N-t;{s)HI zd$G`EpdFi+?e`TgePi9SNGEy5ld`_NOTy^cD2i!P4cI6_G(}UQf5l^SKa~G)HFu@Y z2fOJl$`v81iaOqt_o2)DWlyBa#yG`PI5{J$rKLQhMHY^Z063^Ajz;bPNWg$_h) z{Q@~*)^0k|pIoiKs^r`!*lujM8v@V9XiN(a{;e*;j_#L5JLq;IAb+6u)$NO$4IQxG z{Y6~99X%aeaus>;Z}@uxzh$E3Lz2DVaZYKE2dgzt*e)oaC_8et0u^IK8)5z0{w0;$my(GNaLe{0`nmPwf8E-rm~R_xPN#A52SO*c{XI)!7y zR6nXgAVInPVU&Tw&>l=yMX{flf2v)&9nL*yzBnshj)i?KEmxuEcnkBoSpbw(QzwZaz zT2higr-sP&@pB2RZcLfMr=y~Biz+{2>vzLfZ-Nj-R4>bY)hO)B*e z+^u3tqzu?kJPk>f7!6|j#+uOamOYefRrgyGj1LfWdDReCk!6Su2Kl`p`!;g>CTz3a zk;S;#y})LZ`vpc&JTH5+9KF2vtCf&bjB@32d2(jbxsVGq+waXZI}V+{`AcUMmpzcr z^7iqP?AQF-Ken29{m8vN5o@tSmtKSRE0B_tV_BXOYF+H{28h>r6C;nRm|y^(b3gxo}44zGVOo9<(nd|z|A2LTkXNZkTd zzQ;DA{D^L^5Svx5EkYh{X&(^$tbHq-Xxcq>(tE~xv&suEJ0!J6JuQxw)KcB!j2zXa zIxN25(_ZT5-k7xd6$RS^*PEbqt@*pN>+)BJTTN8f=E9SfM)8ovRiJcx?CP=;?jQNv zrgot@GTnsGK#>!WZjhOvdzJFll!lXa^9i&^?n@Owl6>`95D3t7>-oyFII3)%>(z0% zj=Evsa%%EbWbRjbIu)`GS>J~?nbK2Y9-O^DKYHV3Q_(US2@PhW$3Al;dZt;mi>>)gcV7PwgxU0EYMX;5#@G03PH(?y^BBZK}V?F`J*2pw9%C6d!^hH8Ix zKfLJ^mo9@fYJS}(y|1nPBnr}_>0dt<=SPHxAXR(FZ@P}G%a^^&$aVJ z?M%J#)k3XJanKkw&*$b*87)C5XQhL7bd?*#q8%=0u=YE@Z~3Hjk5TaKZRJw`Vrnt_ zzFP`C-2j=b$g8&#Tr;DPVUJOkDJmW!V<-Ao5)gM@5qBn&JC_@Hx*AL(WnUT)^zLL^7v>o6m(1s|mU-_-s2%A(KWWr&{F?u$YQN z1YI3=&(NKEF$8CR7$m2hGLi($?0c+BYkjM0D)p^iXUzoUFD@?*r>M3u@Dv88hY+1^e|9;Uvq{J$@i-XNNpPVR^*MfXh8`Ki>tgO%hJT?n6- zDYg>TSKw~IuZnmA2aRd}?As~p(&H+z`rWh^6Ihpole)zFGg^-Q40|iRUuqVDVaQ~h zx0uS0soE~(@PA&G+N!UE+D`+GCu%47aVm6pL^2QKv`wNA|{h zywXOo;g=Se$F&$D?Z>tcli>Quy@j6b0goshLEj6{p3RR*G$2BfDN;umD$C!&VA|ub zuq(-Vey?{!KlDg2J0eF(S7Ja{G%Eyvs>9(r`f+^3%`G)TaIzKY{b7t>Hj#SKK3MMt z=IweH2`_g4cEk4x+HicN*>UGQr*|K505hobnNbOsGQZ%L011;}m#+Rfkp~>>`^%@& z*iihH=F8N1_k)&<%bNow^~YI!k%)Hl(_oW{2#U~+7NbGF$3bKFC&A{5hwCuA-(|1x ze(zy|6N_19cK`IHqd^6-37CZBkN@68i}K@a-)9W{X6zPQy_A}s0U%eGPy12@o1y^l}Ilj>6tiKn*wcwNBGF*f_koyMjRRUPY?6KDGa=}jKjFs0h(^}5Mgf<#= z2K(;vtWYKI%@IeJ2vVr)SD}fsXoeG&DS&ysP{fbt@01N@ zee!_01s+YUG%Qa3Tf^hJS&IHY;ASYgSU@xT2RNhq;ZqQWU-5OkCOg(pwxbyH0CS>* zW+>5cIQ{O;sK`mU-4$~Zp@uPF_WW`NM%v(uC2>6Fsd@2!6WGmc zsPTmfhLm1+exA7g!yx21haQ0VDS8lXJl;+(D+(p$6gOzPb@Cic-a0Mk8B&U@1PYFLw(&*Cc^nfx8D>? zX)epK?mLmkKW9UKF65UuZe-{hS4)U$TuPG%leBIvo%v^JT$I0ike-t^GVmTXlq5v? zlz+KG@!`5X7FB0Z+tYi=;O2LHmjp6LQ)L8JzdNApt_sTWv`n>anytQXXfSrnYYpXk z8Gs1o+D;OdwFR6w7yez6C*%`x00u(w53fGLgo@7#{)oqUM>M<(EXPlq7uw-~E;pxL zCznUlJI<)o2B~2-U6XALLg(uZ$DM}M4PWc7Ad)kkn9kT3^0NqX3fms@=kpM0&`VkT zeTl6Hx1BFs7aw;f*Nr?d=2ido$rkcdJt*OL*93df;ILodhK7 z`;j4UfbVW<7Q&SSpjw=&(VfTS^9|A4+{!~yn1b|;{%7ayFc-SXtQbr>`MwsjjPF^1$39h6>5ceV<94m@WK2#Z9OXW%r;^YshMXP;D0lDHQLoL90KJUTuXJ+w z%65vuFNiG%`H>n=f*A^ZAVIqj?AL59fS=&4!I;3iH>nV7_0>lA!Bt?a5K+R=UH$dB z>Ge??-j8XAH82f1Nr5gWGS?sSBlG9c3K`5FR}0{~4(^n@Pn~G0k3a*jj%Q7!5yC^` zjM^F^igF=~LcQBmmnAf;)V4zEacL_o?l5;D+2sl81m*^5FRJ{pX7+)M)0Qwu1r9{f z;yE~(I6d5)HB-t6;hZ|OY#JO92!#K*TbXJd%{B7Bt$VsT9IN5r$2{@# z+jy+9D|3srj;WIsLmn>B4!^f##`{l%m>I_n!X1^epd3QyF32N$;zETcb3#O{t^UIX zi1{Oqv6vJW6?*$g)$X{a2PTA!?S3Y^nnx)=PEl)jb)u`LkzH~_@kS4%|2&M7Y{LSm z+haUSsu@4xewd(oPotN!)ED`X^(~00!BIC-1S*Nz;ua0AyZW0LN1Y6;qUl=-Lp@Df zbDVg|TO{vX4UfdPm>z!78pK^~swsB>%@C8}ff^>(k>di2t-bQRy#+O@VA`Q|*;#hH*rGHpce{h+kZMVI60 zMUb)S5_w%qMlCx~Ea78iP;N#g`giwE3lnB=1R0Vq zqJ7nFT~v1Sh)A(jOg$z^QM}xPlo;s}&>T{3J*3t_-K^$sL*w~pOa_KOGjDg|CMj-! z0>-B$9#>Hg_t>L-a9oK@7R`}kuKqt05Q(z@6n}PMHR37tEwBJIl6fZh?p*%rWk|_f zRIs*Gna8JKe15a_w~f_|`z@0v>HcP@RWYTZ^!J=~I67MN)M+j|r+4!bH_ngW_qp%% zymFAPS~M1OK}2=H&vVA2R#8ISbvg9#M|+honfIIE^QLrni|U?e-GIzep13^+^*6B) z?U2~W4HQq0TiG$6dzF_RPyl1s2HS#+N_htQV_M6>3f;W2jql01g8YzQua*arP4F(A$;~-bP1l zj|o@!Vr-1dK^mJ~OqNbtZ^_=o$DJqVEB?O?9v7!-jjzQ@1GDwi7P`WC!C7)?qLw%V zTMJE|@(+D(wUd~Bplv^IQ`F1`35oQ@ks|Ggk5j0xBs2Ie9z9UZS)G+xyrPJ1*fFe>%E70?X;X@vQ95XFB8zcbf;XtQuqM|-U&P5PrcqF>v?T8FMorKPwXDv zmfI;m`}a$;bre?i9F`e=dxyu|S!o}txUqlVw_a*_lUTjjo@ZRwW-mf77&Mw1a#r^) zTP2kk3#mrKku!|By&u86>kBs|4|+O?pRdi5y7YQ%qZ(gfB%jt87x2iLM!DHALd8qJ z7!q_m0FxM3Pk$Vs?DVql@u}C`DtFn@I%e_oW0>NGie^|>AY?ZRkC-qh7Q9F&EhZ{H zBSPL8xr9<%K$Dxg_ZbtQ_a$Y_i<56Nnu)9RCPMlC=nlOGsj=VrbJ&>T6p?SA=KIOc z$AkleoG*9RB$0gWXxof~h+I*@R^gT?v^-E?pZB&L7Q;&rIr(iDFpQ)7$ zCnWGks%%Fo5RiNTU&23PK+!QB-=xn-AN^2L^ZbF}D8stU)Mk}v>lUFq3 z@*}XB0g=b1se{>vViSr-Ngh6TKY6&oo;vdAP~Mcsr2M<(1Drq)eeS+EKa+W?lerD= zw?Nmnz^ng32Gp@v$@>65!i=0-_07v=b9|H}FV--RA4S4Q$bzm@^HV7+s3L0V=unGi z3oD0+O%~O*ZinzF7Idh6H!WPYS}fOKl?In{79*N`f-{t!yCMv(4>2BwSsgWY$Gd4Fa;oEvE7XuHJ!?s4b2_Bq&wZP*VWsVYtKXlr@iwf~Z*oT< z+&*CWj{Aur#)rQl8$lG1C%yaK6IM$c- zdJcd}S1VIk#Y1r<%5B43siB;LA{c;kGDI(v?n_-lHD7{eX%E#5|8t^S_DiJ#6D=Po zEU2r!J>q4vqvGOWf9Tt8!;2m)1gwMCywI`Uiep;=o|-Bpt3FuhGbnk1ZU;r#clmuV za9bcRYL_Xqtjc?_naa!=x)OUz%O*ZAdv6Cdz-@Otzuhj$rAxu%+&5}P?P8+Qou}m6 z39or;=yq9<)Aaw5L4_xdgY5jl4$YL2~e#|0E^7*0nSEn6ww zT3fA#Us367_1+vbzJIh>a=)m)1JRFt$V*;Mu8Cck%vZhBQONwpO_sLk+KVXMWt<0R z_}&8y-za^xFRm@Je@AD4tH!qp-hS6t+Yi=it>X~`FQXg+WL1M%l&s;%OP4e#T)uWJR^8h9i-va8rL0EeZGIiDmR_cRcA@DP}=mV~{ z_wfAfD}>9kw2F99+N=&A$LX@a)@nmJKznFvUU0)S_9wEt%6GPW)66zWQxnTDPi#=WYVu@kaz?{ z0M>Z{^3+EA&U@ao#{Z0Ca>)5SmM6#<=U1&Py;CMK{Y9c6B9%!lG!ARdg?+ptfV~|E zraRAg(j_qG$R zimlk-;ejgArimv_b|>_2;?bw39P}kf=WF?cUv(uvwWcfU$H&67yKd8L#_2jKgM^OuJW*dtsE*#UU!ly z^;B2;l85a#WY{QJ|C}Rs)_B-?3;~}MP|?_`UA8)l4E{#$SL<-Py*<pH|>g2ERnT8Cnji^rAiAse!9K((a7&6Q+=PWI!8Z7PB8Jo6$1V5jFNu*|5egL^_iBl6g!e()GF;xH zL6@B@n5=OJ78?<2H6jMK(a3yy)}Iz0OfmKeau$g3XqtTj`6-6%r83!t77Z{P5AyLj zDQ0cS$xs3jH3kPI5cmEn+kEMrY#Icw44g{y>wpaECJFtLf_f!f112S13{$FB6L->s z`8|^Z6ph-;WY!4kzkkDCk9U7n|t>%!t~^xd$5feuDK-Bx4E#(&%u)>8223Xv5D z$1x6Er^B2{ahf*+U6@WJy+PkMxnZ&SMg7g)_?l4$VRu!N-FkDn+m)Nda;1aOX$KRT zz5XB0{E30B>BcbxNuX;SaIoGeO-W$4ppr^*JE)@c>=0u zPLNHOL1AHgR3dD6Dj@(<%vmX6>wGj;fI`{zzf8ZwH9&kgtFJ-8*l=}Jv$QSf7h2yY zkq-oH_&+OWhNp>Vw0!adQkWxv=43%8tTSba`_ZEaQyK%4S+{)HP}2t@nS3@63t#8s z;(x(#h7*wfgQ$_zvk1LS%9zu@eAPBcFOxt|q2??PrGr`8HpbyN4<8s)kzVF7p)YHwRXg$o)MTF{SO;Dn`O%0L zD)S-2+&Nvp!*aqmu4<1ir*+}XlkjlIGfI!QHnKu-eP0Qft-+ca?QXK=HEs};#C_eH z5?_7!>`&c*!}NB8{%mR6hyY2SKNTrI0Uz2cyNt8jPc9`!R~^<4i`E}&c$Ewc^=3Ft zHr?Xw$9?F-#aVrw>($5_$v#!>WDcC994h5HD6)nvA_(v4@6*gwe~(02inSy^&0?E# zL)UD4aJd48D8{Vf1I3FAAY){Mms7;$*l1)9p7A{vvoqEQLl-d`HAm(0ImZAs0fQ8! z)haJy(oh7dAEB9|d6dR}ds&NSP>EPaJ}o7=;yroE?5gPN`=WitL#W}qVWmc?8{Y3w z+<(=nk$mKB_ymR&xTJTZmV|mzqh#*)f9vTB9RI^Ubd$35Bb5DmA(}68zh2hbez{Dj zks|1*QeySf(zj>m(l{;@-kJQB*2I*r#x3~KkZI&{Std_pgso0Ja9NFCZif?)$B5#B zTaGRXRkR52AMMLQ59hkkOLimf%zkvfvs2Zq-mrpMu2gq~Bz_K{zdC;fmb;56_PuX7 zbT||TNKkgVfp^l{+`q{1D6nEMJw>ljFZTURyk=_#zEsXq)ozZzmp_2faXCD)_SL;- z1Yk$TCQ}u5_&PgpcPq3-ED=ectCmFGcI>sb#&7R>EZ=dvhflNpUeJ}Qo;AEp+Itxd ziVeQ^{n1zIM+Y|-A?f6FtLt|=-hUs{Z$jyJjXsz}2Op>vX%QTD0dgNVaNX1|^T=AS z%c@n%T;v+U$_kqQnHlg)z@K+Q@OSUu8F+1e&mJ$N1(u<{{SI5-klv$cQl!QgaTd)s zu#S(QXbGjS&WKREPqnfA2Ln;g0;{EcPA2NTL{N!U%35`zB@+3>Y$82^FgK<;d>U5P zpoj;P`>g%+)eXmYB1b8*&EBX5-+{5ewL5+bIdFYon~n;(tU0OZ07Ja2@Ft{7C!3?y-8MjventN0&jS!cpR%?r$p& zg-d{8FjEloKezQ~4YWOqb{2yQ&$xCK9rxd67NhFU z6lG-1qlf!VAJ;{5td2U+eM{u&#REpy`%)e6eS$U`p19mdZ_$4|_HT2EaLg<@dsAgd zOtjuMKVNoKkbT9XEVprNJxC+Zp5V-JH1<6p0kcbC;5c%d@7yuD&A@qeAx23N{!m#L zivvq7h95An(S7K5d0LQByYT1198!WRy*ZVW6X3JRoRr&g@uEw+bC|H+Kk)u+iznLl zu0y!`#DE_yq@MKrc=T)pw0~kw+38Tzt{;7l6LcN@f~rC3VmDNj0n;0Q9w8`3aV|qW zej*9DOEJYyBC8>adAZ{jGT;=M&XKZl`t=gNP&FY;G9>a9$ptl~^x=UmJI1GA5})-$ zH0ZWj%`cMfs=vlu&Sn#T%pkz=IV*Ulq~TNZ?R6A!M$IEgFmEHs@rhh5bgI5+E;06U zk}IZ1e>mLt)hKGi$%6Fp*hB;P?D!gWHAiW7Un!OqWaj>AU$PlbxBW)mWR7};x^J}C z@~Zw)xIUhPyR&&D#6X zTL0#HCl)=KuG`=Ibs4<09m(hmapPt9WkPv$#_{aF21M&g8q-EvtVdzZQ33 z-Q9z`ySoI3;O_Ee@BN;WUy!U>d1juOd#-zU{(==$S>Od^JixwOu0+KY0y3ojaYtc6Tz2_5KsAX3MVzd3L)6sH-mV6wx^Gfx0 z2HUDng>RICpFbPYw1Cw~ea{9?r)E=2CrEG;z6n8I2iR>IoW>}p3*em@#gc*}ZfJRq zX=e%W`Cz(hj5=${!oi=${pJ}Ko4$|au_@No(#cccs{B;A{I5C8Uiqq^kxJP&#Bzj% z$i1eX22tqg4qcgC7Ss=u^C(Jv*DdnXe>$vcHmj7%PbA)7ot)gy0DDtrysB7Tgu0W=oH z^0Be%om^TsD)7txubjf+uSHTfdv>sC<;P(bsXol3g#g+fET4Qj@pY^t;utgyXNThG z+p6u-_^eDrhI^Q(vtjWGB{%=k!WfzF>pwA*Le^Ad&!~lc>nSUXUW^_xJ4|3WICNL; z^(uxqSwX~ew`1w7)#iq(vHf6VCkv{n(-aX{=l5V0C0*UO{d@4P01LcT(XcwzRIgWU zO!uZ1{0 zs_DvY;C7^V>-R%*-U4Jb1ibTS)_L+mV>=ne(9Us>iCcGS7wpEQ*J93Rd?|{-PB8w2 z=B!ow&0sy#i_kMgP=iS;_p7W<3aj0BRT_{-FL_{K)gm(Bs{VF7M9ivCy`x2Th2A#UA5ga;G-3U-g zJUo-Jo=z47pE>f_D`1yoG)J_M8J(a)qs?B#GrV$@1^G_gJmc|)!6r$=W4r{Tmi7^P z=93;_@9-Ws+TUZZ3PM-X3Wtjnr-^+Vqv;T-a;+07r{rITR`rA@czWi?9eZoo5;aa1 z))1XH7_`GVZrv(aakkB*nAG7z`YL}_6RPkhag0a&^ybrnH{_6CubvokV_E^C%n1yD zpYoc9$9m->vfCzl&u6S(g)^kC7}5zjgy|h(Mv{WRJ&u$I^SVliZ;sPlFsD6Yj?ujUalgd}bh{SnMQp#G6DB6QB>{ zg^AP%3mqX6m(dAmqU15CWi)NG?}aa-#9Dhi1KO`;8u)4b7NIlW=J7&^zr7cPy}Jqb z!BJ)k-l2VUoc3dET*!1D@FE<86nTw-5&))yY6MAmF1Rth#AK>O5HZZN%E9U18##g{ zT+)gWa2mnbuqQ6Jy!<%IN_NyHMOPpy!hfmR4mz^iIE@rb+see9sY!8YF9QcZ^!G;x zso5Z-oF&Hb@!utglUM8z=@#|tzQfM7lO@)D`mnQ1uScS##rSl%%*4F43gqLg&(Neg z(bON#NtgZ7y+-bL+-s(IE9azj>y7chJW*MPyJ@ZXac81(2m513x3xm(6NB$k3C+o~8!}X?MXYbB-fLu!!E=$07*?fmBsLj6jI0!*{t*QK zGQlNZ9t=p|ts!-&n~W#ttWC&{Ikr__H_0{fyK(JXuGPxW+WooR{5i43nsX{A?31~{ zfa#F*Z1139x{uQJQmn6Iet@{%@{fg5ioKbn>ckdWtx*rdtoaIVyW`oda<;r7)v74ffGP^bOkW z{5TbM@U@3r+mehEch+>3c(Tp$Z=MxDO;BU=KCr>2k`XLwzQKv-Os3>wJCS3jXm=AoMU<~CfNu(>G?Fm6Q1O7Zdja)IgRDW|af6{gj?G1fv?hJt2k@X94VQnY+ue2KoxGOh^)&0>C>BLvO1bMV*A_Arj}KDK~un( zf{NArAv;i^*6^TVd|jUZy2)^Gj&Mpha?qUVptT^KS86ZUPNf#dd#DyEpQbmuERl)3 z{Mr<@f?MNNPu*ALr(FL8n{<23tW%ILN`)Tc^2K5DQEJNHp1d3kJgj|MYlXjLV7{Mf zWW6XDSdI@4)WP&ve!-)tPUk@qL9szNR>l`o2sNbTJ1m*af1QzN5p6Be>VG5un{#I1 z3QdMwZFSz9*mYFIVuhb&R;-<5QU(*jW@4=fZF{P;BA?}TB3#~7J5cJdSDd5W)4b14;=0q z=_Ez^@`C%s>tspW6tGZ{&{Ue*sp{`k`Eqd$=sM~`+FQ$W4wH##8-<`GMcCi7chs#M zGgPA@quOD`Pw~7yj_q-PvAYguec7@`o0^G)-CiMb)H1p9x-7ge*O9Lr) z4UE<$X7$yT-o~jFpy!neg~roy)9Hud}IT9FK?j1t@)RR>0Ea@ z`=wXtkJ`cJ(G}k$YkIXJcom5rx6HBVROWdVW7V0GnyfYAMdG7_IDt+h9#Y6#JlJJ? zhB&2Aoj#Xz)QRvT_L?J(&;N`#`TaZxFis{GbJ?)ei+*|8O(aVF(mIW@M;QcnJHT>F zLgq3h;|^WoqwtTrCd|tXX4%}F4fPTpzx!EL@(M2`=pMnJYD(rgkb`F?PA8bid%mh^_|j?#d_0^l{yMBEShsi0x=bz zHuGoW@Cl>YS-ZN#%np+1C=*$!1ZMY4$sIj0DZ?EHkUkVVWDHH4_$g!Yct0RnBT5jG z`)C@+*owOPrSy@c0bOXPJNQ7RTE$_JjeGeG^3wo|)XPCJKNla_>Tm5JI@9k-%rvAR zgeL4*W!P77ti@4+dOBqN6BAey=dav~S>$3C8o+55Y5wDo|2B7vF1m$elV+-qPaFE> z4}VsQm8!TlO&hG?pOZHwv@bM&UXws_I#i1s3ArtdaX8xP-{W?+WqBf(ydSf^`kRo^ zD}gIyZ75u)I!Ke>{PR~-dpDC+b@*vkunkd+h2);qO$ntz_`3OoP8x;$V8})tfDWc3 zm}eH!_c^ugBB#&cd7KDa9y)Y5d@AI2xV`fUjkKU6AK<#e%aTKZk(DyBx|}Vu_8OmD z6jpgJdy?LUR=D>k!uCejM`BnH;D<)hQA~;Zr@rs%`}l@|>uN+pm3=42;w;E}JHYEo zOT|`nQnqMvOux$|Ahih8t%HAb)a1QZjyCYE-`AS94T~X|ALic{gwym#3N&so7FG^? z<1;l)AJhM6ufXkTP20w-%brFlJ%G8;pMHoVq@OUDile5B4T32^3JX&B2M9CBY>V=! z#t2aeB7L+`cucN9s9yXuCRZgEut?=hJA&v4c{%#xI1V=sTz6z;)06ap)W$^^^`QHa za-T7{JoQvb_}Uz!t#FL1|Hk)RaLZn7A+F|H96XOJrlU`0@hC&BYMO+Q>o)H9w~}WR zFeDp3SiTf~IVyveJ*vnvN9{HGDnPPA33pmvhk`R5we|2jb^u5nlB0rxF4{=QbJ>i% zBF5nAfc;OVoS?>=?4Kw9Bu-dHN>_O6@JZ zodTuS|L8uYQhzuQ+Z1fJyF7%39$r#G59caS+x^M*GcLl^3JwYkyEy$`h2{&jidWnB zX*9n+&c@xrcX4KO5=oe>Pn`o8K^k2^GP&>Bf?V@-G3N1A=O_;Ya^=2~OMTr1r4b|o z{s68-^onw2;Xln4IoX#9-&TEoWo;W=$aeYsirQQH86QJ9>`QB_lO!*@PFZ0~w(|+T zb|=^Eo|l!mHERk9ha0NvtU8v?Oknm*w-^xEUO6MyxvMnq17A!=i=6p}y2Ku>kV}bD zItddf(#IzxoUhO7(6K%`D?8YqBr)%WgRez*DaPa-ojGap`!d&~JN_ZC_9nl~_|@b~ z)HC)(QYOC8L9VZ(&q(#e)JRef6YYP25`xR$nug-pyKCK2aaG%IrG6KRv`3QoH$XVM zK~0Fek`N)|)#0x9{sMZ_huJ`0rx1$*Oma(8oFk(``3G1V1Wq5xyL{T9S<{$oyfFf5 zZPjQzgw}x7SJZ8a*_A^^zG%}QJ*C3p3Q!o|dk+fJ3n`{kxQi|Q9&)@D6kn* z9!y11b3a}nR1SVq>rZ5+8e9@`GyZAmL?cBdG1&}9=HpHSX^XozHW91_g$fo58qQca zN;WJGSv2q+ismLg_Yb0;p?f&s;d`WDe7Z}r54m{ZHfz!1QSYn$VM^GlCquw{-@x0u zi~{zu3y(>Mts#b1gkuHk+0r>9gPFMCTame^%chma5+bE9?FFre-T0F}79H7d&jFaLpN|hw@FB?6k!mmCNr_tGFkgr|jJMwP09$@;lZVKxj%?5~YqL1qyx~ z$xhrCSbD3e@sjz|xoy8QT50p8s3|~7OUE6@ zFAC-ywloJx1%bVs&Nus_vmI&a4hLY9s%h9$H+E}Y>d14{RtmcL>h~l zH4?!>zWf>Ev-}TpdSnx#hCE-yI>6GBF*AIsJHpW~4NI3e;|Sp>+MgDi!Qg-gh}k`A zAwGb}*zqlZ2q8fEzh};od6O^Q)EG85buqx_xzd)lT%h?&)?}l`7>Z3JFKY91Fq-P^ z{+C2%p`AY0WyxVv0Ke?V2-|t0i0IY>ppwn45Bg(f$QK_4IfBc>XGl)5MPKz~eR!i0~tVE@R{>V}8E*(?30chNNRAFRhi}p9_-fTBpoRV8Bw=cRr2>^0mDv>+YU^ZD=Hf`wJJtk z%oObR4f0VkXnwSrj$(X#aHnsfhC?C$R#E>@3rVO>N;?t=T*(YC2;^D;!Wb{9IM6L5 z4MIS|JDBN3QU`x_Jjjy6FusbfaVl!}koEDRD!k4n477u&TJT5e13EsV(tLH*@Mi{f z5zX}Fb-VSY!oA0lJiSwFM?^@90l2~ekqqi-`b!;s9ULr8w(d%{)Vp8xyb6ES%k4`2 z)!T*aD@21F9e;%73Q9D9nKHfQP+eX6+@?@HJh^?b-e_@p8r}97)T2zoO;2@4gq9^<|D-Vl+y? zLU;ki_fA?E`Nrj4_OleC376^ zpC|#Lhyn10o_6`48k_QqhLM)`1Erd*?)Mp$hI2-d8lR{_B^B$Lir`w2r1J%NfW_|u z!(~Adgk9Fha(3u+dx?wq)?;j_|HgEG%kH@3+M8df&bGj-hXp zjJ0+*-**Y(=()}RJ|M7QP$bHi|Ida&x|9-o^9tL+QJ>Sk;b6{Kc&@l9E<PV>HLBi#(d}o(quShO#8&e2()moyOe;Fyxhje(^m4>x#SIb zin91$G7Ik4M0N`;v14c;8N7|kNCREMXh2GS{P5Ng+IW*ni?OzbrES(YOAT|4FllsD z)Y7K1YCO&WXG7TT@bi zE?5j7|Ng2Pp+&KC(2DrmMxl<62EL;osr?D_6nueVY6NOPwM8ViNIBdxn2Qz8r zvCbHmz*q-?A14}Bs*;a&=B@Hg1HPI3KgnHGl;^9*uH&PDkE@!^<22c>nwHSp>F0HB z^8z=A9cv@0yyY<_+C|U1q!t^GZ+v%PVVOM@It5s;P z6hToRlwv_GwDVWJ$pB^;$IS0(Gd;)6w(%-AA$N)5r4Jt z{dxNo>-W#4c+nGGeG73HNS(5|!{5JRUGq349hm-})XPtmrAg8ME zSr$w=&OZ7&6l893_Pu7d|Er&n|Mxook7_~QLh2|^!mOLAaIx%4GG%+pU+r=HE(ERw zffJoQh8yC9axv+$mr#+;9(XU6{d>UcVk~0it?FX7IY75bbnsg^)o+ldw&*)Q9TQK@ zIG+=^dKVgZZpe4u{f28iB&=dgizxI$&v1uprr#h)(${M~se<|LL8P9{BD-W3lUR9j}$1&Esd6rP7Y!YF9i~>a?<^awYI%>h*#SZ51>ujZo2B6<6k@ zMBPP}4r`J8O0&cjNWLh_v<*4#$NOsLCn%XS>{d1nPn7oyp=sN_ux<1YQLHR2|2~$d>sWHG$aB2e%}jXyK6o9ZSaw6XXWLY z9W$@naK0rE_9K~Pip~^Ft8#XI$HCC=02++m_^h8U<>| zXURnPKF$eT<(gNu^vrW}*bU`SPlc}E-F{2VU$bU_VI3^8{Sl%GK(-*evGmHD> z94nreYaL*winEI33^z152Sb^qS(Ly`Gq^}#Z9yWvbSY6$g6x`iEIXh?%%aA(Z&AoI z+`n`})Z{K214A7Qu6gUvl-c(+iy85DQx&I+c1R?PF%p{)e%L+o#}(W*&&{(_U~6ju zSBge`wAct-;iSYEKhHd?ta=)wwg@TOB7`?_O&r%~hY)l5L{`j)2sgY+Qj1bU|8&FWQMtc-M;lv? z=-}>Qi|P(YS5~Kei5q8y5O-(o!J4*FK4NV=9|Xt3A<-S4gzmR7xh3lSJBdc<(k8f= z%kSj9bbT;bFy-BUN9+egBIhd3?)h^qfL5ZgD!xa=XKwr?U^L`Xnq#R{q$Te*=jDb8 zx{270F;E+do_qiHy{;{6bp9Y2=~(@22jUIeb*>O9-&OVyF79va6tMHzbE!KfoN zlTcQI@M&J%B0#>kU~04*V_8%sbGvF*Dz0F2=98*DNB9AXk8lTkrz|V`5(uAwl%`@l zfX$O&`L3&Qn!5_Y;{&Y;I^tSd<_Nw4q}ndWJlRaM)ikl$VVQU6%Z-aoc3=O!u=b)%#51ewJB(&E}krObKzu?`e#{)sIN9@~0rZDtECLl)ujnjBrRp zw&xm7c5tk|o0w%ZM!qj+=L#zSh+}y|4Ndh@4QBP+Q2O#u#nbQaKw`b;(MGe*+|~qJ zc}&X~g>qPU4lk!N77OkqE|SPEBMb(PUH~#Q4(@K)2DY)XTz9*viWHx&dtYj7g7|c6 z<0!f5^Mna@EFM;5!im+%*(#{05I^!8oye49nr_iJr^gERNX~NY7kP8>Sou zCtee~NIQTPOZqKn=SJsE;@H8tzDo=_CLY zvfU;$|1ogif#9ex#gRX=mDXzIM2dS?VSgCniEy4%T#3}@Rmo16QEZA~1Z?XodeAz> zf_&5|VlK}LPch7ADd@|KuQd8TV}r+!A5**>^5^wQ+-_&S5}0EN#Y;rX;s#dD=vsX< zxjd^P@2eAs6UdkuRApjY;5s?oe3IdJ!#JlqCzL3y9n1e4O(GyX832$oyWtK0Mg#q>n36K!56xYrF&Q1@Jq^(T1o2>}ca`b5+PoWfWhvIX2wjF>;|M zlH4-#fOKS}kXDB(OO{yuKpj%da^!D`l_o?TyE?hC6dILs@~>KFDe#mq(<)@Nh#Tg}neofrzXu%p5 zlV}B~mA;=u#o|LyuIg0hLTdr{*Fk?S&O>*zzhbneiCbrGdq6 zY2e+Jh!l%*QaZ|&of4u=y6_v5eMURk_~CaP!**BE-wWLKLA)FWmVrsYc+{n7w!{BeUD+pCJGl`CHcf`P$KWmba{;*Nmd$Ud5?=P5G*}{8ff;{%wiFn&NLt2*lD{ zRZc>!R1KP#xnEY^{N9wZ0TzNd#!EAzN5O;a<7tb@ zhCmEmGmYrX%VWx72%Q%-(?`Cd@S1eR!0YP#5x*=&^FljOn{F=PZtC=Fr^C+Ozxnja zVLyUc>14uT&n@=SFr5w!CKp4zV-Za?LXzUAs{b<7NFuJ2#%-qA;kDPbd!>9nM4`#t z*AmDO#S(D2A3}R20gds{{(*m48lm7rK5{>1^8>!gy9Ve7*wL+xEkmI2w?QnMR_6a^ zvyL1C+->9@Y67wD`y5?DR+Rjr5Wl5iUs3xd>)?9(tbr0uMqk$ZBC`vObLPlGBQc9v zkcO6#(OE20J=*hX$2CQ81@I>Ix^$neq4K=2^UrCf8}F!G>hvQ7T9d@-6t zsM%(*>C|Yw9#7|Xfl4&Pc6a4jcjv$#pw`5wD;wL@#p>fbN+>@?w--?To}ad#2IJfR zicFJA(jD4Z_PwpZ6x-gK%S&iZh!=73nXvv6S&n01#|4)9Q%LhkAC9fJAKo)q<2)u} z8Syfs9r@J*=ymS))u4kqqt{UNQ2hnHzNbZ19p8<-?pJFlfqda3>@th%pHl|GPF zxVXkD~P zNmM8Fd$ajt#o9T!b<0*CJrtah-a&KkVB2JoK-qzgi_Q0kLY9mG%*5V~$7C5F(!c^PBR! z%_{8>*ON9ai9KtFw_qKCAwcoPXQ8I&B0_W0wxZ9gTbGYNH!B}pcC6C=B%C&qVzmhB z#OZU{k$@MCypI}AMDfP)N-T8F@|%P`#>L%Eo*REe5tnY}%xCzm-Yya4Jk~LU0iLjd z_m2YfEiW4=Kd0gAD&)!>^;PD70lnc^#$tlU|I28HT>YO(!a7A$$jm*ArOggy~r^XA@RTp${{^p z^sMjt9h9Bxz_-@&cz~oFkqeAqu>ga@&1*RDT+r7w+0@qWEDeliGe- zTV46rPH= zCg_g#<@yJyi(u{k_)a03Hrv*QNXf+UpMnjmM;jkWKkBZq;FqxFgdWZhM3eI7;hvD- zSC9a{;v>&?7^v(w*VGa*`*MPfb;Lr`c^x_h&B_)CkV@p#(7qqC9AA%R_emfWVyXy z;$AMaB#Mlsuw%B5tZ4n^-Yh7egh&xu~!T^kEC#l zO(=>S5mQtQd@nNb>CyG()@(!euw!5mel z$&FVF`Cz+kRp?4|NlGB2te5CsR?WjaxK!0KTd?f!=a5C^aOd*zPH@uteo@14^8ddE ziJ6X^@#&on#^B3jP<{%H_yQA2^Nd)hMh;8Z)abtdrZuh1v(Y@sX~D_A5glS#e+XD~ z!PnS%r_dj%#^qZS&aRb{;$k*~;u>qxWfthqmL{A&4Hxxl#*qm$UF0qfS!$3~}&e>jLkfB79$$a@ zkIp6CL}zc5r+PZCZg3AvqrYQxUOeJAyQN#$&bpA-s`+&2$*;v66!cJiF%uW#Z^@yq zfn9xIui2C?HH-CGE^fnM3!bt z$pA}NiR%lxt>R-u=m{6I7gM--7-V-6_u0+s9KGRb8(saW`?xJs9CHQF|9!imp>kG! z=b`PNYcgKxS@*%A9J?2aZZwct;nVM1on=pyU*Tm|31uAu^%_@)&LLtfFCPi8w59T1 ze`Z7t7z&fM9sR`fwj9>q^dXsKovy1+3ru9z{JO`_um#{)Zlqav?K|*0#*kN3>;pb- zsZFf~R_U~EBMRO>^1kfZjQ5^KE+U1`@ZmTE-%cC@VUEn@t#`Ud=l;*i9$9{L%Po&~ zP^$5ttNvR&hQ}gKsCsQ12v2wZIOSRg*=UQZMXErN5;A4zshPfS}pbVoeSaQN+B=w9BN%k<35 zA|IyTgu0~VJg{UMRoc{KTX_lVJ+Yheed{Pun=Kh7YG=+}Covd-Z{T zt}VK&1UB}5Rrn_N6>FXq#CYfUIbsQu1s|=1@!jg@Zx&=UV-Tb@lS}?~tJLtkde8it zVRg1JLPg)!Eg6gpDaG4k`L%(T>a;<#aJq0O@A?=zZ@1-MVAwZEKpXv9ZzwW@u)XqY zmaEF-5lgptlLc}{{B+k%zIAbGUDVgySgFwp+Izk;UuG$JIu7cu@Uhm;(O1@8KHCtQ z-x#~sDY`jsh2YjQdXe(HzI>5*y%y)T z8Ae`wS4(!LQSZatQ(b>n@y9z@DjBRg*$Q69jX^GjU4 zFlcV(1hZ(Kzc%jLj{sVPxcL*kYvvB1JR4IYJ+}NHlP&wZi#Foedzue0*c)>e-R%6% zk3cAoZt>Ul_Io^Q!I$9$TmJ=x9kZ1`hbO7QOt%qx%dzl(&L5cC`$H0Xs9rrb<3I8` zkn|O#5tV`{fvN~-Im9`$rmg+^W;*xav$Kma`7w^#sp)EYQGRkEUrnol%gXb6vK?0T3NoD4va6^ z?zYnLx-DUTv#wmU5jv{AZX5qHWl2eqjNF+w!&TnxO4JmKnzx?ln@;NfNMauPG2s>Xs%4T<2 zEM2oRTsi}8yqV#MQPhwo@HV03OgANEuEW9+^l)1K~?Q! z(l>r>&iuKNt26BG<2gIM)K}X`x)1rG8S;^#KUM0q_vpAiXzpbTw%Sv^HD#l721nNH zfQ`B2dCZ%h5h8Vx8mQZL&!OI_kird@;)Nb8axWj}d03<0B{`ie`y}GUxap0n{XxX7 zVXuhbr=n*Ik7Y;7t1vmsSQwP1oChBz)ybo2eBP!@$Ms1LS)XY_ez~%IB@gT5*Yzh7 zP3&_TO&YQW8vIwN%8CHAfWB={yJs4KeJU%7zG0YWocUm)UR`i1MU{P7Qdk5`D;*{+5Ig@o;k|2= zVYC^H_4;exKe29)K-5dVSmO-Z?B=+Gi}y6Nrc-?1d;kvqHmqjLNA-i+tl zn2+b99Cke!<4WgPGIAQl?JO^Q%whZ&uXYn)|39jE1}Pft;YPL~nH_S_5N2WEUU1Ku z8%Uwmu0riWawxtvAjv`2>ar zcyb}85PCv>Y}&J+ciKqLOP+=F@w|jz>Zb-i^*E~ol2jV8ZFR{HA=5ZmeK)6V+2=z> zgPVeq;e`1=pHa9BLBrUL+FB!Iu-DlSvlmMM;ysz?=DNpmHhlck(?XXQhhwk)=gM4$ z>iL#ya?tYl%exowScTftt3(DO;ELqsx#un3>n>DkecY^NeEC4#cH;pe9L|Kfs3!q& z5BvwS8^x*nM(h3Fo2Q#1Cbgr#$B!@UFB6FR7H3ycu%sHMqV*xg#L0`>x_bTWDXF9G$E8M zgLv?DF)Wb2#mg(fu9SN@c<5^$2v{N?L;xb5W7q@nlM6p@pVdJL*Ke}pb)PS~qi3Nv zBh0mC1}o_U4@UsY$iu(A+boIfZJ;LXHezh;-G^$yVk}<0-AnS7CG+^4q2{iYCVAZ` zigA?LwJYacv9M7H+aqG3d>W=*N2+LQ&LK45&EL#?I+JJ;o!IIc4|1jJhcj@JBw92o z%9WQLKV9p7UhAiN7nDz{%K12X(@F}szpJSgKRJ2)?+Pr{;ekEliJgT!QWN+jC;0r0 zY}wm8Rwm_fX!_1Ti=)q`rD}+5RpsS?frTZ1|MP743UNQ_MP}2z-BNGD=J_J|mQRhs zZ}EA0!eJLZD#rV5H=o;aKJCU_JO4}4I6;G$v?|jqtetE# zwWlc@mj39~_5f1J9^043*A?=OywhivHa>fwrrYV8wbh0@7W69jR||6^{Z6+zul zs^P6*Rc%N4{rQ=&-8WmE0yS7N4$_Q|Zrt$^q2xCo%)M%~{w0D#DwgDa|q6Sc! z#5yO=e2n2d6PCg0pnI0JKm8hgSOug))KcW50YW(MiX&->mQ(FXyY_3hFgwnz(jseK z&U`|Fo^!yDrc?D}wEId=mBX>;y(p?|-+L*A9{QJS(D<(iVU&!1wgxB*k3lne50B2A z$K&bU_>|}Q=({b-yQiaqv$HGdyRJqfwH7j$ZAdGYYuOTE!AVV7D9`G-)ynJ3o?Q>W zbDi47ONjElEmL84 zrm_)RcHn#f_?~5Rt$(v14=n5v1{sAJVCo8|w_@bvV~D3w&xg*xgv#nKYV~?K%`G*& zym^Mkzp;L4Y&~B$Iq!Bf1Mf`Q{$be)$m&!=uFbi=)`=B{Ox;POa+D!Yzq;qkypG~n z{Y-i1t9cRuTb*To!n@(K7JoWhyOYnL;dq+4$^>&M(R&^~JsVOG z>C&=-WNyB?<)t!byVt>1)JEzmSPGyrr7(y`>lNP7RZfG*T-yuzQnz-Gd=vQI?R>4j z((*7z{ovzIhdq&&lJ$Zf#dELAo~$!RqK1@gk2cg3Oq9BHmHR<)G4aY{o=u({AOqd9 z0^gX&>TZyqfB+s++Hp|9B7vL;xHY($PZJ&{mGsmVfE$UkUBP*HtJy{zZ8BE*3#wNX4`6GIP+HQ5y4z?Xr&%;JL6t) z8kU7^)6MP~Kh1#sFs8Ab5$pC0olN)ifEV{j5vG|9Z~!!3i|V;Kjc;9B(RWK1t8Z zr)k9jKJAJQI~hB>Q$?9J8O*ejEH8d=Ui-EZW2D+Fl zB{}12p!0d5tb9D6JfHMHrm|^rcK=t?MTu38dq?#{d>gfOf*w) zy3jz@oGAw*lVN#SqgMhcSnD8j6OO6b%iKig^cT*R3*wF^FsM7Vg3S(-lgGzks;ff- zZD>YmH#9rz6O+XZXYDG>go)F`20VQFIwN|4cTyttMkUS6Cx(#%%#U3`0{Ak zp>4)Q_X?rB`9}QcR~MGL)Ay?Idngut^sk*0UQfT5_|iN21d)p97k4Yn3;|o!E7^sL zAE9~XlCNGCf#ziIy~nKvOHJOq3jKW9_4NUiGLP%KG6}DoqTFq~KhCOpvR*l_QB}KY zA`t2H3ku;q2vb!D9pXpDtFs!idKxu7gCBG15ELX&K=aNg!{;?N8G@(Iwct6!RsZ(L z=ZM#$Q2m>UcwU==K2Bxj;Lo*(${-t{1>OFH3a$uiFdNF#NBv*-0=yft3B9=f`5Pz+ zPZ%lO{Z}@pUSW~*AHzS4miy|Iy|lTUw(hs@@qN@JCmwkaBC?xnwOy|?;tts=6q^a} zeGz#`wtO9i+{3pyHPSkDW6ih$E-ptWj&f=~pPas{2M{Dc>`~U1+{p3BTRr$s?jMEj z%&&p;dL{aqU7LGx54x_$7)P3wCI_wl#jE11Uc-WVO**vPzE`UFHrz+@g!XzYh5Ml&Ga@v9_>TXdF~d9)wOC(9 zr{{U{Fq`M8s@+`T0=tN8%joy9CQ=cB>!!q)7-aKAH{3B^E-xIjCuz+x|7~``+i{(! z#}#+_CM}T|V%Ln{xX}Z9z>}qeEPUXQJ$Mx_>wtUM{_&ffg!!czuhr@4O1r=BsbDQ%ah18J>$O|^GMY9S7G~(L6 zT%+)wyly@p{h8LOI@Nx+&qoX1OR0K}Wk|qX#%WKg+^Z`%R8|Dq6^WArSEt2nY8&M_ z>(`cs(9Wzl1-B26GeJ~B<8!a@X-G05ql5XubSTR^13_X(ZvlJRrVFMw4Ie%bPBn7$ zvJSz|1|5508DtP28x$5kJHs8#iF(A^^J!(}{O>U3e^Vl*4Av^@C)(ms%6iua18@;> zzduKLxA${)h=lu5<*8$6l2{5$ge0JhI6}RbR$bN>OZWro7jQh_iAfOp7z8Qn^ zTI4rgT0=bNen8$}d-F}AetZDn?oX>ZwAY3;PtnztBCtI57{QM}ph6&Z*fbyii3b5C z?U4pg(52=pd4;wQ&nv0OkK35(7r*wG7uiI%XC}Oi%RA(|o9W}ofPtM1gZtzZBg3k9 zlik|a#MTkvZ$hh^zAKNsNSDh(loHxspX%?nGi&UZsO7b@G+NF(p6NO5#vPYL@YFV= z`d3hZjD>+cImD!441F_o!!Tj~1DLyZ_qy$`xs{E2XP;Lf7!~EU>)kZZE18Jg`LZHr z-(rDH7`5jL+H>PLp(gEx5L)oGqh33T<`ex3#zdW&ZdgSr{emApF9Ko^^H#hpUy(R=p2THczSyQfd6uc-~# zin^{*p&9Njq+a$nUfX+ZQ@>FqPrd0Cw6Dzozkp9#Rp1RBgK=rq%DJa3df~!1DJ%)C zzK7^8jDFQ7#60z8a}~k<3L*uSMBp5ozHnZsz-vJl*69_;5!;vG509x?Ggm`G8iwbo z^LFES?JD;)dcW|QUxwb8Z(H?O^Snl6ymG%-AB&k~goaa+hLCYH0n!^E=tqRkFhEAe z_BJ-}3c}$R&!JBXWaU*RloyU7T}O5E%I9oRbR#T%eu_r#NLOk9>Ng-UJoIOH+FTg6 z-4OyjX90MEXIHkLRc1B(V4f^6P@%bmtLV@3ntx!Dj#xc}kdNw>dL>%gY!3RV_B&*j zs9KH2n0oDdXio<{R_Z571g|326CbA~a5TIw;D8_}N)nL7iZ|cheWn+eg>K(eKVjZQ zQ8N+vftE(YHQEL<*o(`gijPw`qBRKcbOvcq4ml-e_~H2KWv;U-q#ggY7*(4%FC8DI zT^RmbV!G~I;`OJ*)?22xfQ7M?xY2KwZ<~zSB!LwQDS#MQbRi#86TOJ zTHyA>Wii}9L1$rR`jpAAzI1azmB@H-);jJlpp=!$IAn<6Ml*0ZLGfSG|CEWXg!MO5 zq|df42JN`kLU-w%g^rIQ7ERp0)EiG}y=?v~w@W4#i=rMhF)KNPKS2WBbEc9SXxYmaPJ z?*5>woz>}%^;rC>Nb@q9DAu%tP*SSdMP5pMGh2ic}CSHS0gimIz7CmwLktJ zPhTC@^!xoS@=;V$P>=?Zk`$2c?hqtKOODYgt%4xkF&bg?=o%>@HFARiqof<88=m3! zcRl-K`(xLx_s)5pbM903Ibu5&exeoUi9;KT2+_6SOMN+oGLaVN-o(WUbQP7;!ns?< z9eVif<{9ko!4`IN1CKWZLMn_n3 zo40{+aSPKwy*}{4EfQhCeLW~BAW#Hb|CXCQmiJSQGEnJz%)+W*hSvn|`G?G&GGH(w z_la_hyqxfO!BQLzD>Z=h&h@(ft}Ke7V&>6u{G`I}fpG@k*_Ghco|le$dl#zracM;l zE^?W&jbyTv`H|7_czcrN-OV7`-^@9F*(;|p0V(9{!t!2Wd-*5BeeTL0&o9LAtaki6 za*}q;9S-B3Vz2n!gSiA9zrC}7aNqfPN(G0UX-`A!EmXH|XqM)A%A1vUSIM+8j<4Dc zK#fPa73JTJZuuQAFD^bitZyvxd_|s8Ec;y<%oUwf?S1)tlh)ptV=A*n=ju{?+2eyp z-HhMnJo@5g`)&9-_tg)4?(*_7>l3ew8G$9T_4eq@kx1IadC>09HFiHEW5=dd{Fc+c z1Hr@a_+P2*X5=*DYld%yZ;lrhLFp4KSLla!Pj0Rle5`3AQfhM@yGG1raWqQ2uXoCn zrZ!q}{vrm>)e?hj20K&;#iE`gPqi-AY9Q6@uMakt@47iE+DqbTgl?b6mb^_F(K~nq zr|Eo974Z|3e)-LJ@QF@uu=g8;a52?MP4A-cZf|?T-6J`B=^))vYW&xvssDcqdI@Zf z)8QAmmB)(~&O6P8rRNaS1w0SwobooUu`^m>Qp3PoI@LDutk{teabn8Ih)6(-c#FrC zS}N@7Ahp0Gx>qPixX4XD-GYTm)ZU|s)SXfgCv6!7U(R?;w5dbGWm;ZOI_a4zp5Ro2 ziBs$z90X?u-a!QSximgy<}K0k&R!>}Rqddb4<;h!B}b%N#0T5&yjt_cjK8~f&9y;X z9PEbbOf(vxz2D-3gl!+nfZ+R}%DI{(#Tdc{v(Pp^I^Gqx=n~7%;6nNO1b%MOhr-zP zyzU+On|ef6j01(a0RgWHOe8tJB9xBAi5rF>uy;!1mfOft=r>sO6oH6Q^u0Io@8v<~ z&-)+ATH}xN+#liJ$Bgo;x!_NFxAVLp>)}kNOC%S7{~mIT+Mj#e8cdi zwuvD%e}G97j?a854qLr@=%ux^O_6pL*Nxox1K|8& zOIf1!r};&f6UtEgXA@SZsFn*%3)v_(J@r8rW@sX*8TOq$3|0W%=1wXoR0&B@$9bKZ zz(5x=WSZC0A!@mqgbRa%`7|;FA#0!0R#n@4$U9cxc!xOdj|CetL~2%|KNj&yV+CLu zH!xw7h~yA1??@XSZdOF`wWGEFf8}-9e=^^sCs{$c952AFYDdVk_OyT$yINsofOSn%?SS8 zL+V@)gw}Vmia@n)*`Iqz^pd8KAE^m%oqt`z4$4}#K`4$~8eM;!e>>=NZ2r;@w#xfM z{G$4{9ut%7O?WLOwYEnO#g9-8=&~E9DcoU2`HB2gu}CN>2Od0RA7Ho$SDhA@;ta$Q z$aa%DP~-ar^o^0TC~1F_Ea63X+dQ20_HxzyXQoD6|4(Me?sgoiqEGG9weQ6E9~oyf z?fMxV{PKOpi?P(H=I%3@-G#y}&j4i{{*l0zB_IB`I!8 zEG7Lke~9%;yr?aaGo>x8&@}q{D+#OAcA8X$kF#R(lU1a@6&7NYn2fovh34zAiN8p^ z`Km?R@N&u4EVtspyNKJZeQSjP+8J6ensP(Zb|DbD?Yji*sdDIRS)Ui%qe$gi#TX{q z+Q*uHB*rSsz2_SVx@Ja)oMl$2@76vvM z6!5hvgz@wBupTDE-yzXGjC`D*Kj(g8ao&@8kRHFbUrC0NLsQ*{UALgz@-B;wK}L>bv6~S>4Vej^!lowL*&K6Q@!pj8<+mcy`Js} z4c#&0(C-a)Cq66d%R{~MA1;xN6EDhmB|qI##uS$|P&9Opdt4SSX`_IwhR=E&>dTwj zF1l6p#l4yRwtaDRu0z_5zD`cgkl5TxWs2L9`ePJx?*3a5pa_SK#96>*I!`x70)+~5nLzE3W2Q~V_ zRh&=fyOzhlyH&aWa>grhGM!3pyWlfPUjAr*Sozaf|2Vj5_VfA!s`GTUG5xi_zpcDO zV_&>D{hq1fmMQcBr;QV5dS%`9ttv%k_J8{_`V7aRzK)ZQ%_x*s z>|uQ`=$Lz5QY%x_69M|_&BH{!$&L7yH*Qdw^)5(aA(@my9hv_|La^OipB2~h?{xFc8Qs(b>2U<{mry^L!f<(kORJk zoe=$z(8{=eoyhO7Z~vgZp{;aa(6;&2oyaZU^=E;+wil*hzcoyu@fGLJrq?UMV{gma zbWz*{*;kI&l|u(MreSyLqR){bPXe|b9S@{xA30~cOlJU7e62;8k;W}=)DOH47Gtx6 z($%kizV*|{`(mGDOVJK}>vyiv90!~JH|Z~*6`W0VMZsk6)fk@bar^?0DD2O#Lc*Kp?Y_qx<6@M7A=?KL5qPek zQuyv&(}R)Ov(7u4eYFP;A|=B6fpcC9qHn$q(laPMQR)*VmXv(+MIK9P)RCErLbfSW z!XejT#_^@$jN^=avmqdaG=oSBPnwtMtK^qAs#th3($>MjZ@9eo+ZIt?BjR2QhBldX zx)b6@fA2cr)6F3tL6ha?6D3XSe|BtcO1Ex_Hc??-%dLSPB*Xq=Y^CQGkj=;_!EJ~{ z(9vBNs3a%F{|^zncr7J!z+F42FrvA6wc+!hw6|Ax-gBWY+ns8kFVa3GxeD$vw(BJw zV2WInpSQWL1&rEf=Oe{j*Ln8Zy|~n`%TGsWZgwCuadX-n@0P`CBqkr%)-SQI&N7B2 zQf9WmK%kNL6u=PK-aH2hGKu37w!e#}pG}DypW0N^=8{4^b?S0)W+aY0mI$vY+K$dq zacOR)SNnI98r@E;L_nOY98;@gdTT0SE``)B&>#6;h9KWL0 z{UmNr!0iUc?Q6{9krpv?kyraZMNJZ$R{_uUXl5iAoLXq_PB2A6kz{n}>fW5&>#Qr@ z_V9h70BokvMjoSU5K@!;4G$Eh}fYjZN1nhUFcB7po0_qNyihPCk+C^$K*s z&cEul+r2-anLWg~)Pb#SH#N{uS{N?;Y$2$X+2rHg-PVXnxNbz_-Lg~BUf{Ba!s1-u zRafKMNk!?NgexX+I6jP7BGf%8376P|oVQ9`=5AdcLzj*RdWNPd58H=k>UA5^nRaX# z`-#p`y$2x+=d=^6aqSoU*MpeYWZCIFYU|cR;fA?oc_9Pga#x=XE85mvLE+A{t6Ulf zp3R(B>jHo>d5Xz3=Ea)i4emi81|=IfJXN3UM0@8JcRUH+`C;LcG`Jy_BOYRfZ3We zS)-Fu3B5T}U2+9@<92J{$BBNm^|mJ!I=w3JobOK>M)96GOuk|6Qr7c(#3*Wo*;IA}=tfvfecu!IE)#mLQVqG5Zsr0|#p7i_*s}9*$t;FN_;Y(o> zOeFneGs@5r2Dubn&v2`(tqq3wt4!RqLHrx9_L?UV#_nTsr#}bYQ&^nbVaJF@Dv;G% zOrr3I2;TwCVL?nn##;KG$SW!}(n6Tcf3xd;e{N3&jHymjyL^04h09J{%m``FbB>gh z^}C(XL%5zE{&P^gf}4(hgjmktMch2x)lL5r zZwh?)3!CsyWf#FV-t3Xq^&a6ZrtKSjcW&%AqIF}x*f8(Wj9)heQxf8Pakdzj5?hSGB-_~Mx0wgt9@G@<_`an?EMv{EC-y=gv+r1`(4i#(Q4`>XUI{Fhd zMS{kmA(*c7*f~k?T@z)qSlT-^Z&z3*-9f`3+nW6yt%Q1W%N+`*7G0+@m7s{vTdSu6 zcVfqV4?Xv0MJMLJ+-@i6Z+JAf@PvqcFy`2qHSoVOoSn&P_vG3!B1b+<*4vYDb*f$m zHLh{Z|M2p=-kxxns>7z#L+=G$dFh^|+)lOsCd_PiE14-=`HHh=T8tEL8~OW(M)X?q zihJf3f5v%ZAhq7?5=%^`pZCFog&cdk!L3W^q+D1VkxQ1JVAE>kYp0H!O^HVq8b()y z^agc0xpjGQ=R!r40k-aI^o_+s1IeWvr51Z$X{fvnDY9KBy+nuqP zT3cmhrRUu1o*%2Lt6Md{4_#%q1HI0sVzuuZj@RTPhCH-|&_|K7fA(D0L)-%IA10PvO*O0ivtrXA~Om$RgVrFSqk)Pc~i!kmVK$UgRHk~sx4N}Myd(4I6Cg+1V zytS5IR>gPDqMzh)ZHK3I`|j?hWmk2_LM!V0#^Rik2=i1y6(daq^0&lut`T3J{_MJ~ z!{d{F0+wv-0S*4#O0+c>`Yz36Ldd>)=bRy~m$Tw`>wI3q(dmMpwnSKoc0Z|Rq~eup+v-U0htF<3}srM zB+ZJ0_z-|qUzf31D13&N&z4z@uC748!Rt{aO}2^OAOlC zVs`e_gP5NH`#J|+p{AWXw**Z0`1UwDQ6ztBX}yOA+E4!kI4=+raN2hk{5H528w!Xj zo(OZc8e9OPwb7QvYD>vqBUCf2u9fp1s~d46=vfzBAE!`Yp!qAK($#hd~KAA{)qJM}+*2nzEpgOb9D#Q%| zD@*k|Z5H-dFY(=_Fit*Wd)IGUkB{TT#euVDETRzbncB%U9S|fa?eg3!A z95|sV3R`B-ZCCL=7uXePG*p~3;1<{AuoJGAv8=MUvY;e+M5E8$Ha_fE`Gv_PS>nJZD)rk&oYfyKSx8p z#y;cXDCLlyDg;W|;>#{_ z=8HNCFLoWvY)-XUMeuntA-<_NtKwFzl(D~hs(!N3@6N1spL@obzx*uYwGSYdJZY~@;OzU{;C zn`*>ZVwy3ZDRa&~4r;O5A@m`*ddSdWa0XO&8R72wOEF;pSq>5P-i1sa;xK2EDPSlh zdgR0dT@HHgL{5{I`>CJ(-JX>Rn;PGM@^aZ6r5f$-gLFs?pL@ZRi=vmtSQs|=Ka2c7_jGBsA@VedH=zwNo78>JG$l0KY!dq9kO$hrN-!E?Z6gZ(4gr_k&UOT#(g- z3!~MqSV&TO9=LZ}{2jqmPl%^2XkbIQNDd>`ONt@us0L77<3=a0NPO*{NZUshb1nQ6 z0$X1Ae#I?TYLp7|n;5SUoy)`bN1~H4BtN26R-K#OMf`!>7X1U=tOnMj%Fx?<0(Vgyy#a$OytJp;c zf4e5SsH^?pse?G#o6CCDMC0U`xrvdwNAA&MDk>_C=RYG*d)qQbG!fLHwQg2ew^S-2 zF&Rbag6johHQ^!Mw*XOHs;Q;z(b9Ynqo8NqCM?O#V^;WwV z2p%(A>sSN1JtZGgORTt_W)uQvRd}N75|@u7rp`7(zG>E+jVs2FG=_Da^8WC3mp6Zs z@`?;qkdq|7?l!LO4nHrT>@vyln0jl80GXrRWLF5|)da1RMjKya6e`!l3|`>d(ULQK zwAqp|JmNkaMYgLGwyLuQ`!b%hh|8Q1dMqWs5uo&7Z6Qxqfq%$^r$RsA_HY(|EfTh4 zJ8zl~F-J#7GBLF7gASQ7&&T}dam5;A;b*l$x*hZ7wAZ+{4a=Y{dh`;Xj53GC?m2^j~`RZ7b%J#GLd z&4SXwb?+)@komosSw0s(?;!lmJ0e;m60+{Wgge4Nwo@Q4%~63*pAdEG^&-AtE^mEL zwhu37=!uoJWM5(Z?FMk|fJT%wKZzmZB*lYo>YlrZjQ{Urm$cu`G&mJkv!8P8c44CE z*5tid8A2?2OKIEca>S{N%8_^IFXa@5H24_WR2})i3J1v!BZlvSX9&4mz&<>qK}Hp# z6}Oln8DwV_6V{)Y#9{-Jnf5vLJi{zBeaX^VOy;GE33Qtfmvq6g(r6ha-^#b-w_;BD zkvIb(btmrc#$IQWS^F8`<4)8-vbR}xu$t5*Ub+`Ks-0pemLJLur3nv!-JH%$mXkGq zg37%k=R$o#RA+>LM>%6I)=1getw+Cm;B5+yw9ueCQr+K`NN_7Jq=eu6@y>w8aYo_d zuMpp(bKE;jEh6;s{8|4qQF=m%mB+w*~?68+!}2; zoA*7yL?dQ*w>NbEL>3wDbhQag?<-#Zur`pZXbqkc{8Y3u473H-)iA2TzsBZ1kF0jH z;VKgaWZ+>Bj11Q5&o)+Fitbc)IUj2&K+C{a2a7n%;!~U7Tr%fFJC9qaj$Yq;Otd?*uklaC z*L`f_7>55_KFJO7UH0r^wDe2F1DT}Fj^W_%MsoQ+1beO2#;1vTBlB`_los7WZKzbR zwM+d$Pk|hz|6J$CD*8`sZz_<7xQ!PD>7}Jd!xB#K^N}U6?Q-9e?I0Y&C4>ss@3ov6=9glyn|4LWr&6T|xf*eQ)9C@%Z6hCYI-O5g%k}{0| z;%(LqS>d-@8|Diin0OMg>$5O>L-A7O>hxoF_TBZm%fA2FVxvXOBl?7Xy0a+d(>&!) zF`Cx*JjwoTDr@;_xg#ZrxSa$drXD>WQxB2;|#EV4e?VjRmSq>E*oYWG-;o z06R@ggy*mow3~I$0p1^cW-acL4bREUvg;9@e2t;SFaS3dNdWm|7=jD(`$CnL<-m9od$)g%u*g2o^TT?cbf$_r! zx8Aj}-XXKC5awq~D#Mej2=9xs&p8*cHlsOTD=g2O&-(jyvdM*kVKll|mGiC18fu!qOL|{C^wgC045Y^U$Jw+cWZSHqEIv_{ADVkg=0_p*FJ2I82-36;e#v#DG~l&tQZ1vDzWObq*R8AHait0V`0gAJb?+U1xUm%8p98t_ ziM8-Qbf5HK8J$E+o}dd8m;2R2S+|W<#9DZMk`&hIP2*V6WQ{x1DDvbQG$M?=#h@OK1%KXMEM7C~4u3OgRt<33aw2X^VTIvR*I<2UbHh9?Y z@IfM8f>omxMjEozP??~gliX<}qY z8WpaC{jvDshBk3l^5&2nk2uRgbuK4%NLpxbnG}Dy;_&2X3e#(X4McOu0L2YlIMx!v3K6dZkxGF=2%@N}d9VRqbso zPE$ql{jS@F1#zY%B+>;zuNdx)!pBJ`-2SP5wrW0&(m^QV=`od4bP18d$k3z z68a&VrqZ?-V%pk+1P*a)Ra7dxp z?W`q$$@BV}fxRz((%`AJ%A~@A!eMH%yf-D4<>wEsyxemer$~M?m<6m_A9{ovtrPPY z))IiknwIuUdK13CmzZ+aH)>uIUvM5f)vl8<^p~=E3g&FtkBZxq<%qF{8`PuSj|pg+ zUWt~CP@#MZ4Tgjq8Uh!!LojWiki}$CNr@Z?`Ky261TmHiH*&R|FKxM*n`7nfPcC?P*rmz^g2I>G8o`;qRUxy*kW)V95!(lg{1 zZJ(et+!(}u%}Xc)7GBSlY`-#C4jz2yo09B&GNGq8S(xcb!P)dznjIR9A0a1D-_4&b zC)zCDIt+a&O8%v7gu*S{AVlETW{N5Xk+SGlEkNlu3`F|9$LIz~U%5GV^M)(*uy@OSI>W#WLIQhlK1q8Yt;Uo8sOP2jS6 z#7I>+6D)t}m$iqwC4ve|_k{3sl*L8EhOUYQf^uw%F)Z)t_$l&9#c;AZ?rV#&kdmS? z($|1CEs9`jn_R6vsiJTiL0t6vInQ)rBb8A)zYZOh3nfWzc(Ct1-2zvHaF z|K40p!==h{GSx&VVtnMyjbJV}VdOb6xk*~VsxmLPAkYo3tLJo!Y=hslb)D5)Aj@8Z zivu6ezlA&J+B@zk_C^-NJq00kQZ^3rNsenk5(zU(Ic`L!5)!kUGUtu<_ga+;4mA=D zef=Wwvz@t!sECN&I!=1aE#L(#>u)f#&Lmm+dE04i0I|yt_LArr(#>m=r6*Mx4$g;> zxFa<1X&0@qglt`-=p~q*c5v(_y;y-+rtkP+zW%K)+pcB85g_5#{6^XJO2g{C?vy9C zbtAYiPk%6Y)iV=u3~XG>IgsZcF}wehPpYceBQKe$x6Z|U&;DE=jcAa#_uCr04yE?g z_qeGOX$x7779%jMx5uKdk=g`y@|E?>a2I69+&en>2L!b#*IKfht@W&VzYT>8^nI(6 zMfa%;hil)yt9on~B6q@BRK<{AXN_y_zblWd;X0)i)byV}sH<44>=g}>2vY2e92G9| z=qPDd5h;4vX?8Y8Iw2+%*08?5yW>NW$CyW(zaW#~Ks`L5wlbg32~WC$$}PK*z`tUP zgY8=!vpkCvXGilgzeXwpyv3;TJk6N%|Ema0LellB3b+Y*o$)*~FnJ7@JW!8?gYG3d zmWSO*)+pL|k)v?Jdp%Rncz>?BL1bj0JugPQsj2NgT1l$#dvtZS-#dC>^cJzZbn_^7 z)dFD&a8c{u%t}s}X{C5IFtVN1q;w5Vm8i$$s)59;< z(RB@$)x+ah7tG_y_8%IEl@$_ac{}?I10#;jLuo?tVuZsN%H;a=SzI*v$X&i1>0KMe zh+ndljk#d#di~Cby&Gtvn8l02QFlrwla9)vtlA z(IgJ&|8{_gf=%0Z5&8_#HlH6{Knm9)!<7XS1=R@d4;Dr80#NU{63#B$;(NeC<;Orc zDSd)MLS58qaM`}LciM9Ny6NgK*p_3)v*XPi35f zd$u?3W-oxQ%l@jp)kWKtr+CoqA~5#mpU{?)4Qhwdn`0nt7mW&RZ} z_IvgX2RzXV!UHLH{g!O?>uH2~Q~4A4!w1LFsV~+06f1YOVwEbQvge)YB&-Olnksh& zxH}cOY@J+m!G$)vJ!xBTP`=dM>f<Dm`h+3Do~t1ry*hiE=Z7((L4B1*t z|K~jq8CzS1ka4KNdk*|Oz9ms}GJCVkZ&XRO2Iypbvl__3?ho_whyGQKBG{68L&IV-?`85xW=c!xAzGe^r zOv7A$S3h&@aD36fZzJ3->H=HT(Z}y?1@27e~l&F6Y&ok%YZPj^N36Z{aqh7b9StdR1+{Xa<(ny z%4z4TW!7kPPX40e5=RRcaTNhqf3=vgtBefMMavxBuUp{B+5s_~+jSJ0EV#+kw|C(^-hc3f8E&=wf+kY}w7eilXmohlL zIN5o&{Y%$*1wJN%e}r&JeuE)pEouCj;MuI3)RW>ds%&(K`*2sBTk=EXzAMu`q2Pzg z0wq5DL+;IE)o+nT4D{jg(zc;vFBp%$HS|;IGL(wv8cm*g0Kf#%svH#_)ZHd(ocGiE z1-GjUm{H5h^}&ck%g-C;8mvq{z-j1^8pqrVN1*?ucD6DBNa?2wZPNKhKGM>_93pJV z>#a>?=47{~9@Ft7{hFMuAxXqZ^~jB~Yl{M6VW7EWNltX3eEb%_Ay(lzLIVyFx)6(X zM`#dcgv5cWj}w-^^Aqq{nApU`$7$9u)}l3*b7mD7D-uEdwU+B;4~m)Zky|79{hvMn z@bDjsU_QQff8Gi@OOGeSTu`B5?nqo8olLm?BGu1N(Iyx)?;R%M%+xk9#qsR_=# z4^uus%j_(R>&YX9i~H*qnN-X%4HuM72x?ClOi5fo>U$)+pf`dKDEtbz*mpLNP#wq0 zAfRM;xE332XYG$UV#_MORK?On$D6-{X>^I@z0N@@#`Z|{m-todea+*eRLTkfgrP1W zN^Hn{s1EPkdze%h96Vb+DZ6s>hDXiW65D&hkozz$5m=N2H04&k`^LN*vw3cQQYVVu z_^5fVniHktnwWeVEI?sLkfM{kcD_+44FxL{R2|Cl`P}^zQFZBF9Qvc6)zm)lAkikf zO^hmYg;?2*`mTwJVW=-W0nsHP1ZISPpEaq`EqAx`Cg3w5tB(9)twOm^J@EO$2q1z; z_DxHteC;&s0c|baNX#5yHRxO$s9ws`sz*JxY<(`>r}=79(qcC{KU)!@PZGm~@>guFR!1hr_CYg&GaQS@Fm& z!JTgfRBhF?(LMAytN8s$9|~C;%}4v~dK>{+0TkK{+liAx?G3V46~f5Hl$Z0>0jWDf zY5PO*PdDHR)7!9`?%Ehh7>(cs-thXgOt}fpbXXTfRhj!2F|?0*xNtjJasp1G@2<*G z|MnAq)ITRkm8h8`)L-RFvd{h}2cS$%>xc75KtbWRds~+O3hs{J@2XYf0gIFNRU!zZ zhC4AA)flu2n@9o9%TYuhf*U|wkEe)Gy=j-iWd%yTId$AD7u#2r0G*vg!xWH1`f7c( zGJ*AH^Dq8ix|JISenO+X{)6;uD{<6D^(AT&rLeWHJn6IN4c|oqXA0C#CIBf7zcXtz zEV-1r^6{VwQY+tIV-N5?xS%OHk>wEkBVps*$N6;KZ`CAyvzF&RQ_2HXgfEsi z@BN>y3$#!VWDu5E>d9TEJ^?e-mdA%w%&mAb!6PUm-$?i6=VY!_4L`}>vt+sP7P z{ZG!*Q2~y8S$X!(SBX%yw|wH$8ELs^?L%dK$0H(^8Qa>WI&8hMAI!@+wOUk4A zWx<8AS?_Z`ho;pA5oL*YG^+2r1^qY~RNIE6cop>z%@w-Vx|lH2bG~Lg43LO?ED7^BBMT z+xL^y{J+tGhf=GF4;jn5$rF-u`{}xvp#B$3n9@#0EyS>$MUgCN#4LYk^`yRg)w5|f zKG|>=c==-w3WAbh-O@90w7$u?%7pmz)e5nbSJSjQctcek-Y9mJxdV-p>jil1lmRHd zBwmsKTsUmDZ|(RJnZaQ7v}k#tzN2-#`KIk!DkLsS#j`B*~nY>7#vnFx0C6)ssP@8T!=Ar!%K^T%{3^w%;S)z@4d%S@YpRejo{cK>&auop=^e$q? zS3v?!jVbo0e^zm~jw^+9uwX~4j=bL#(;G}&#s}(pYg*cg8G{5^8S_;7ZDpSvT!o@& zeYvd84VZ92r0}8qVvmBT5Oi5_e|ERl2<3F$`K+qqz10uv23Ko{9?0I4d0)Hi7D=7K zig%^6O!m2ZO3#Fr&q{aZ{tc;ICzcj1tEo3>Y`}hezRqDuqn3>@E>fDyY}&1#nIv%G zD8n&Sh!c|4cvdCV;&Cq5GhrJwkN&3Kh3FCmP^e{j{puS?8K_TwaQG)#zI@s43qP`F6~j~T%~(uu21MQKU;VYzf9<*yrKGD zP~T<83#J--Fw?EtRi-u487~3M&-1y=K-uecX=Px@05fg1-~Mwr=#i0Up~0>;uhj_G zF}JsXR>IPX&jDn+pPc0EYgzKGuvVZ1T&Dd7--_Q9e|Z!e zCY#nSgw*4WTP3Y(I4Pqpi?do;`kBDli4qy&va(&=G-qbjNZ$4^+7GtUIaZOdYT|1j zfBBcN61ZO#9Pc${83r-#8ddZ4bov{D+2(DTxFypkiW$s60b+NQ@5(Avqa%sY1!3^a z$ozRo_sQP0`Kldj*Oj-4 zH&BnlZ+WQk#B#e+9Ip%=3U3ob2b8nKq-oE8eh6tnp?kUs(}Go>p#99qS#MHwQZ2b3 zMPq>q2BLO=f`7Oi3ftnJ{k1M82K{r~6J-DR{jUsm1tlWI_@nsTY6Nn3rE*$#pgF^>GO-s z9GRZZeIithl$o9bM3scja?D(^7xVN~&@QQbtQ~^Fev~j-h9FejEWc`tT%O8|mbj+= z5c%2r3;Qo|`^R}yQSt8czHz{^4ty3$zP#ANq{V)w;3->+0xAt38Onoa)j8hv{l6&v zk)K%(Tpvp@aZwr6NcaCRwHT_rHxJ|jP$$&V*Z)K6wcy$OaQv~qK{E>gAgxHc$@y`! zLL+I1Hl}c0y~#8+03`het-6nIf%g6pKgS2NNTGZSofj@LF?!o8{GX02YM1A5T~V z9dudzHHWm`Z#x*JE4hvglHY>_mOa=0@z3ZLe2**T^k_pODV}Z2WVAVDkai6kxbb>$})3kWi zbiM)#A+`seP($8ify+34A!ZsI?0Zf6pP5@U7sBXs2;cnCs(v$1a4b8jXPGD>-rT&_ zZt$I&*Vt8(T;E?-u^_rGWQ$aPf(WJgZl98nW;t`vNnu7`7a*vp(mX9_>`6itog9DV zMql+|pS4Wx9eE-?}M8M27UPncdq+CSAKl?*x(Az`3(xqDf41E8K{#}FyfUpk%45x2E>^5glOS%T)6WUkQJjto9vUD^Aa-S1mGM zd-7`?SXCtWqq2@Ac4o~|3xiF}CAvEL-|0oFTet+q_V{}py~_Tv+&Fs)_$xl$Mz z#6eI~v;+sS5pSF#?5@7bBKD{F`_fhoUni*S&4#6zL?CqX23DJG06< zfzM$Hp`P3-sCv)f_g?t)+QU3l)2K0PY9TnB`yR2#jE`>CYXOg|x-+)*0xGQEr^x?P zI#znO{arqw{6|NduS83qJku91Q@3e2&d6b=>+eb}W-I3f4H2RwNuYfrnJBM-*J=#C zT+o)Vc?V@0d+Wf*E~EK|KMv_)y&9Q@K-Bi%`b>EqVMMN$Pwmh!N<4~7=s4fF(4%O= zN_N`K0RF{D>@!Zat9IEq?-0_`=hQvXp&R6uW@3_RpAIk#j_+k7lMk2{C=*^oL=nyC zvj`DQ`-W|{KQ;)-8-1c^L$?iE#VZ=M0}CQH_1AcL%>PlrZ+;TUD`!W5S|L3K zwA2@!WUxS*#w_on=|25Fq00|4ztOBYli9I7-SL0j1w1~#)xT=B%zA|~v;n1g)oQ6W z*|;_*p)Q_EN(AL(wt{Cf3+k=i{Po!y)QX-{3{=(!*B#GGG4496I;sc?T0J=BciSU> zPoA93>*YKkQpO}ws^^Dj}H-dzWJlW=YRi%IDTCT;eaNVe5Pu$uo|gOS6mw(E>#ytoLSF$7-t*W=4ZPAg7KS=E0X)BdSi z!Lg7*y7!(5hyq+ffO&^N@ULWh@4rfGL2-oPM%$Xvd`OwEMrvfkp1JPsCuTRw+4wMD|?D!ypI=%r9mi%J13o07_JhBzjJ5p zqav#heYIKIzuqcvCUYo6jbjhIzc)vHeSPF_(oB11P3h#vgjI`C<1Iv2v1V@R=zDZaR)R13_c zmSXrHh~O!z>5PvHGP z;WC3g+bkiZ$YD2mCFrM07?2$AMrB~^(D1f#_7~O)4rbMg0Bdi8L1EovgkX$J)`AJxvym@>cDllgf%lF4LC;R^de@9~QV@ zqH0A^k?KBq?o9U`fqjxspV7;!r zmhJMlc4vE->26CAdKpRSJOMH4R|U|LJ>>~nwzA(L6RDRs9__t6SK~h8@qQgoCrfnU z%g{{GyUdd`H{q2^KkL?0B9;BiCMHYwzlg4|vn@^dc5611PjKW;yjLQUHHF|i5A@8w z?$Ix&Nf^Ju2ST(R(uYtD?Nd$&uv$eF91!^cFMSTn_|ov4X8&5IjHfUeA}Kf2OgY3f z`ER|Oe1OtYsgXE4ZP}pqvG>crDoE%8ia%oLc;V;a zzi#Zc6uhjl5swtkpBOmm+f&fpO&a>W-^mc}TjQul9Fh~NcOfkfW#($FDA)eJ)Km@= zPF55{9UI@ou!GcMrZ^-Flb@Re3-kdeEpk)F9Lt_*2vAQ9_`C_m3x)V!m0+F&dxW{! z!5l5I7#zJ>Koh>FA2xH-7mn}R&-n3tO)Z@}V*KRbBI(kWT3uxEKl6l-NyzfdVv(|s z)u~1MZXv$ZYq{hI^y`Z5)H*y#E*d2vt^S~I++b4`y=rc(Ly!GwZ=kUcZj)Iss0reV z@_(w6Dt1e&U&)N>QnmZpl`oD>pYY?oqv3Mq|KsSqU^QntN+5$XqGzg`3=4N)z`M6%;ojBJ%RQfARh??!M4UGJ>;Pdf#H^Qu6<_g)Ng|PG%TE?T@DU~d>zLK<5z*_MRoe9vwCl4@btALWyG4a?zC#UO>vlWvB z_)Ups6C0$=8FR#y8av0kDv6FY#dSd`IQ*$+crmRzCT8}A=9SR(p#SS&&#pc*SST%! zzg&8`IZgdf-b&M>oV8b)G*F>sK!tLs_p*sTqv_dWj&#OM@IxczL4QKdIV>~B@U2JO z+G%5qk0*=|G6OHE!qz7TMD=PFYSN_BBwr0&+LE!h*WPXD~SU?K>yKhV-%G4tlUJs7t zKj_i*fBaiV1!eE#KNZ4<4YPpmCh+|HLYuL|lIUr0n+KTaOCUr{{eZOJ-jy&N$yS|{wjeP% zi2@Y~J*|Zlo382x(mXv$f=)NA#GaS$eL@c`ztJ00-mi~vj}u2nRiyQ}=T92fB6#Ox z_il3b41SVXzc|1VHT}q5ufbDd)YhCemOuUGWzbChE0^egN5ca9986$AV*$O}2CePT zU!`mE^{~Iev&WBx^)7Dgyi$o4V9{>) zTcp(r@|bTW4wgG7#smqtfHH>uJE}Pw{WN>(;aYh0;`Ww7>tF#?5_I0W0s(qE(D``(r)@EZ76s z^0z3TaUgv2&*0)HOSPDte=zrV3iA(5KD%CB$n#k+QUB_L&aO=JQMtRM(4vUjwV!;B zqnOVPQ&Q)_m=|yN%_Tw~$g;~k7-1pYs&z-ZNwN{Xzbxkezq*&3D=#Lp&Xnyv-7()3 zp2Sj_qnXxu|E_0d{_E_gN~JHa;u!6e`U}e{y!8M43>tVULp@S-xe*_yL|;pB-j(8= zFk!rZFw5!`B1v0Zv*=p?AgtxVAjbuqsNGrie4c>A5oA;1dmuFpT&;(ZpkL0>vo}cU3P9%ahNOly=B=8e z*oUC}YlFN03|>eerqz59iB>b>xgl?(rlRk@JQj!$)m^=WFtx`t|F_X=3T=xxWjxdS zViLzGu7bo}TXp$n@=ZUDf3PlF($Ly~z6plEw@6=0Zu=yq3k)=gv(l-T^>vy!e>94w zr-btI3~?#O)oEe{wmhTRYerL^HMuyY{PA4m(rYtdq`8_G;?l9q%P%gWYJ#(4lH&}O zb2`N%`)z*(u7xXA7>w3E4NGaO^}auLMd6oBfZe@}w4qDW3i*XjDxTHYkI%0@FnlR7 zBJSidy(>2Hd^9a)MEM59eS4{|+B=Pu$;?mok_j53TSPp49t?}2N8qVK#t7N}#GO*U z`=0YUowW_^pk>JMwdx|>IWr)p@-V;@qmv1U9UBF)VIf-rSIYuwuUOzWg+$#%{9_xt z=t0uW7hfA?ZF4g;tM0ej!yW0ZkJdSbp&sI6U~;|?)2)b@k&k5&KO?Z?sM|!{a*J_O zlXrH-v)APZr>oPv3Ljrv{?wA{CY_kX_6g~F@igGT8;NgO4TfOb`||qr#;~?&D!uoo zgM8=oAYJu6fo2))LQgd}jhDA8M!ynfQC*Iv@(%Gku25lB%cJFTdv)V zRL7Lcn6K?$XnJ>^U+gaEV`O$>>zXwLb0LWDWe>>Ce_ZN~2;#ry{R}T{>OsL0tR*Q} zV0h~Mq>P3kC*KRCLH=vEsb|H(tMc^{(O(8|4fyYWPt9L9lHSsLVS%T19 zG5;249qH$8T$&`@Pc2Ao6j8}daZnb%=B?G49_yb0(960V8;BS-C-i|0tIJHN<^#L< zo&Xx=?)!1$%samqB99P$`%{Kf(~_W-@KV-{g-siNB71hN(M;T~Pa;G*14PaYA~e

    z=YvRe|9<{R>`eQA6AkVsz zw^C_zb0Tf8MS!6x@$p#N-T7Aon1Sl;vVDB5MB6GPzr}I&xjM_>#svO5=)dAqcqmuJ z*uQQ=^=pOpjy0PfyYwytnPgL!md4B29NyWFoZP*gY5gw3{0duwF?xT-q-W+_CJ4GJ zB0@i$Xx0Y28YniyDC~e0RYO1hoN&!k zVQ6bIJ+hqxtZPO1_)tPgL0nK$?o7#Mr+A<;-Z74dJbA?`Lqbj1o0JL^^=t2|QL>s9Ie-^!9 z@hj0mnF$@R-#<=`3o`?bsxZ%n#`1c52I!bxps13V|RXGXrLh z8w`89F7Th_<>bDiy*h@A%!A^u@HH{%yNto-6`I#FsD;{6lqsQehH}TUv8mr)2Tm#0NRv)NBu`n=0#Y1EB8*| zY6pJ18?AIX%UEjKYsUdW*#vm9y0-4za-Q`0-~&CAghgJDo4c@e_Q8kN<~JAP<|y-f z1yyzubXLNxc9lZ~hm5HR69TPaE7QQ=%G5(OL2aAG#a)&+?MJ^a>m#eg1p--!6enC=xQU_Oxz zuMzju&v>7oeo57rRmw};L0~o8^p6(15AQ1{tu&J&qr{|yMDCbcqn4u#{No9AexvlF z^uqZ1vY+%Tx}=>oN@Y6V#npm;PNzK{gt0}sP#c^gZi-qv7Iu&-5r-iHK zQUxmog$PV<-UC6>>9m*sjuxkI%TvRtKCniqx0>3nIov=;HNyV*QAFH=XCzX;B< zA>c_}AzT(VK#|VraLTC=C}CC^hjf&TgfAut|Lcnfa}Q~2u>kwwI=Tlw8=Ty&FM2g1 zRMMtFL1Uy*K(z)~nd@$Zz1nZI@KxB*n$cGoma;)kcIUh=Ll1{Fewr32_lOoEp9h&u zeP$Jlg$#ck8`UxW*y>ny$k@|*V{AWw`MjQBu|fH^6gkbb3l~ARh{k(6_sd`2@V#+9 zR7zy^#%QSRaI;~A0aF^H)01yNDzjk8^dDfhfWZJ}e(I~e=iu&LqrEhZi4uI({nQ!} zda(7tmif2yHAc8v!@HY~`_(J2`z#ahHrgL(?{Vm8hxc_CMDH z+TtoLOwAg8BdNwea@zS-;1bE@XDZ))!an>^JCQAYz3PaK)MoU7{hZW)J$$RF_IU*J zK9Kay6m9;71(<1a-!M9Q!-^&Tc|M_t(4{iK+1>nP*nt?`N~%Sf;>&0UF2`NL@ry}@ zFyk;QceUSGrPF@=0g-lwt~|`%>6L_I&W?&S&dAKO)M1TVMv8mw5oe6N0cgN798gz4 zhebphFEua~^HBD>X(aYz3JHml-`wg|W;f1mSayZ3rac*kQ;TS!f#N4XrJbpC`e>UD z0i_nMN}JB$aq2iUgnLAJvspL;tgua`Z|hLE(sJmjpV+TIy}a?N#;9cM<^<~UP8_-i z<-eaePQ75%^ShEQK6ut+oEm;&&d)q+9&ABMLsSKINxHwAhz$4ba0_0#c-$Avz8J>N zQ~$&*Y`ED-=EgKG-59olK3m!Jph?nMI<(m$h9I0J?P5jiI@>rEfg=6mtk0rf`nPvt zo~YhJo zNI8R>{la=y0WRIr9LYKdDRHrSz2o?{CG`EZRrb{4Fb%~PLl$%26wr@c_+DRQ$?xSl zxW(a?!ms$j*4V?W_S(%l^!VZV7j9^nXw-ojVjUdz`exNvl2wH4DQ>-luAfn)ln#C? zA1^D?{CsG{dcH48|06zqBfI^E7p#Bc_VZ}wrAWOP26q{vIL#yJ=L56HY{FdU#?^-3&+$)__{dP)z~Q= zcC#1}c9fe9x>DDRmItiQBDt%T(%dkk0x!M?x{guV1F}=EfS1<11d96EKb?Btm}K~& z^dnL58u<;ZUausqp!(DHuveMxSI-}O=7q!or1O2oqD%BZSfuo+q5>{LBYw23-x2@Y z-kkjYqjG2w`Neay!4u6LX>gB3kG5$3d20^AJP8@kdM9p~J3Yrh`bM0f_3S{gANQ|s zM3(&*d+--g|Jh_1eQbt@{b1|iKiL6`@5ZU%3bF*y6VGvc;!s|(y#v_3z~xD)YdF)% zLQvS-j*I2|-5D8}1)8m_Iar`&!OxaXI8mP&*yDbI(t$>7fg`WYX8@*N3l2||%V}#X z?(Ou%ae5Q=wqPM>{+&Pm=;FKC(K9<|1$TgJ zPH{`ftvD-15ucHgA>X#pr|*}J2i^DHP#nTl_UqP{UkaANOQQl+qQL-)zlFzkXqjRV zLP5*@91=wtb|i+OVF#Y46m}(^EJd~}`pu@-(zzCm3aJNuAmg??%9VkEfSv zzTqqPca|9ZR({sNVuWF{Dy97Kfnvc+stred>nnb+u`|;yOeF;GLD?I(YHVskk>vql zI`tLtS~|#9R_IBw_p$;=d9X?M0kKCYvsIkd75QGu**`rpTT`WN9yF{kX2^Mj_9aVQB{+0q&fFh< zAUNpFkOmt_CoD_m2EkfBl)qVkFYzH%p@#jwlM3Ussus!vrJ%o4<8#Rs{u0dBt2eMj zSuw0m+D^9y;80YF$WK^rCadyx2OC>N=Cv&7IY-XW%UJq?D2Xp>p`n&Afy~PthVjMQaBuR{98caR9{BNr;L?C_oLREQRSqT(h^ew< za=_CMkxbR6!}yi7_=Wg9cqJop?k^BESLc0IAGIox-Q-VSt}9INZp%Qw#gu5ViUB#w z#xNKfhdDt~MhsR~;7!~tE{?PzYB9UT7s+_%0ub6`;rNuvfAQNv^BSa|b*TlV7QQH)rMn{ft1jRW`M5cx3IC z#kVq}_QM$vlp@qFNN(*{`W}+Doik2d4_TAlr5enJhx!G5Z=%7W#G9}N;;Za{e%2Do z7}C`unv#q_cSxcGF7V9F_(pMCOvdP$*T0PzG~1$_a_;p&RX9)wpL^fMS6O4*c^db` z_Z9%&zQnI?EsiYZ)J^2d(<0?&ZRoa*tglLu!;cpWnjAN#@%d5)$x@9xbi-WDp zd)Njb`=a8o^2}p`-?Q%FU^*+??sOI6W6LxGha3&JVy9M7I%Tt zhjHwMw4la`D<}5wH0aXLWJE$TYLCT#VK{xMV4e5%Tm>}mW%VRbgf-J+j+eU)V?6PB z^<{D-S(w?JRR9in+RtRw>BkLyHBv%H?_vf{O=H8X45QT6X! zsAusDCRHe1)DTz0&e#~q^74e-GJNIf zC|s4?he7UlIKR^a2{9l9)_|nyneF(mlrF*r#G!(1B)3ePK@s>ndIAT+(Y+%*k9;=V2 zclpZwL`}%beK#(CF_W6U%x2L1onEu9zH-`^gYGzp_tOV=^Ut2d$r`02fhVl~-0)vw)usP`4_26pv&eat}#-;Kx?z6LqlK@j&ET0ky&=i<>PV|Jwe=c;_82OGnRSJ zvCQZbn`hUJ1`U+uUiN;>#!6p*gq*tX@Lo9Hcjw*rlm~k<+~FUOHuxUbKh6B}A1*54 zY;TR4t#?dKF&4mwGT~rAFpW?h6;4xuwv>0y^bz5#?41FUNfyJZt5|7kV{{%s=mzYy5Zg zvbmZ*y+JEwy{;Iz(7W+C=nZ|ZVyd#=$UH3KOtvz^k9^mU&vY5J70aB3M5f&Q6Wru> z$?oy!C_hPP0Z&`lht`xNHbx<<(Py39# zl~^OP>htgZ`jh@A8qpKmWkDC!?#cgJz00Y0gy>OEEYPK2Kv$r#=8oRTL#d})hK5dM zF~P^{6(Ma+C$sI;<27TI7$gcwT^~e~iOI$XgkqKL`J)>x+ePA?BhsHJidgZ5FcK9j z=ssd_=D~kP8Cj@)^ViV*Y-FMM2NaJ6#0b-X6&Rz z46FMYMDX3j44~>_x)Naqvpf>CCRs&8S%%J_C=4YO!#g}Zu@gb}9F#VDXBe5~FQIk| zg{PsO+c~^Xx5;{J{EmonyA9tu`_l_2OAnv9ZO9wgOD(_eGTkvY&sq(6csr_Xa03W1 zLxcM!2>Ul3@r+9LJ;<(T>(F!`6Wz629djd1@A^dz05;Z{~Q(S-d^$z+?aH)?%vYM|jJTN;a*v z=>48$-3CS$9DI>9Tl02qo_I8|@`+Wy`xa#yilaKXnfy9{lC4&R5CB#0W&ZSsXMdO) z2+amgpjgABkb4u*BU>eMLBu=sof7!{+dIni8ZZBR?>=B9)GbJn*@7rMPLPae?(zRy zp3L2=a%<4)80x>{LVr>e)S>*W&(QTQOBvpoW>%bxO*2P2d#c?(-s2V zdOuN6U(j@T{uX@ZH(z5P&)Q7h{O*rIyZ|T|4WP!1B*Nzp*PHCrr z;C6d%l6p9KKt?W!`URQ$Q1{unLYd$?&>jzB0C{tqz;H&{S>(3zKgZ&#ly?pKN7(99 zO}%ftpT~~q_T|qMz!2pSK49N-7=J| z?G%^4gtVeXn6&M)BQ|!Fz+>9eE4#l0Y2TyHmX#Siw);s-nMi0!6m*&8%t48^l?KI) zJ~`WRp>d-QkK&iYP{%3nEYsZ47{L`kpzmuoR34k}F3{qjK5K?d!@8|N3@n6f$cOc2 z$g_v@fd{0;$aFUY9tFta;nT%QyM8VF%d#ZfIurAx45uwI;xR^ zBd~3MY`bE(OnK-VU%zVH&UA1;@SR&9N8L@A+j07tks4X!byEx4*S&ZCeaPtcL*pYf zL6}~|yK>&vEqR4%2Q`e1>V;wH{t~SQ2EL$1iCCqCe8{sgRTCrm#`To_d}lrJub!fT{-*g1 z`{0^$6o_*38O3If8IC87VOAjDE?Jc*@$3NkklloFLD!wP z<(u5bgC*`s$WNi(-x#`K?%~+TJ4F0cjz&NuZArb@uQ&4qqZM zY%Dly$f@9(DS^-(lS?mt8QQi#Wc2G*5eJaX?--CKYA3UXB*D zh=iXs3MXIjK1XVyAQ6LBlugcE0)Vu-`ff9#Zut$x{cqib@<(L{i&)u(u{1W`*=P#N zpQ&y4)UZU!V0so5*rTBmjXFV4_DYT0@|yr3?DqWb_efJ*8pVWbS)j^G#06}1IGtcnv6D>%cV|Usk9S6!fUHU%9m?(oAA=D_lVQ7aj>Kg?2M^d1s5O2? z*fQt!yUmQ+jH_=c`N<@=7h_oILR`O&@MhR<=SBwC3_!==Emz>C&JM2p3tlv!(%NB! z5hiG+iC63gxOkIx<3m>WZ7<87B9JG<_FG+<(D0{o6#juz5acNzfC*f^r8S7lO!yCW zdRxe22D_Hg4jSddJjw{sSIV?8GT$;c`W!Q6zx>?-tl*EcQMVGMLz#VeFUYUBBwfv* zBqr7)-{|~jRL=M}e<~^5e1v5Z6I_DjU4q5AiHH|6< z5OGm`@;AoMjgr-Ph|nd4sHuSq`yDsU`Bw+Q&G6~tS%6I$DR{bS64{q{;nhehv< z0lWLk$9M!F%AD5SI8JRGBy{TEBA~KWDE$tLWfOB>(Qx-*AC!Byu*YGP4Q*T6$7nRd zQf{>>;%#R~t|Gg!td;EBKg~Q|k9k_b=##s*;yT09T{?H5Kd9+5y}?u+xs`ohOX{7D zLrxj|@Zh)vJ!e1+?@s{U2DjndNGlN3p*L6SqB6>Gf|I$IQP8=Y$g&L_MqQ7{AzPeo z3;;?~i9Dxw^j#;2`=Jecb32{JZKwTDw&`cJcnLa~Ma85WaI$CBj@UUCqRSpRz%X&& z)CC>rMuBKLea(5fh}(}suqpW8*ZI+-@mtSJ3+n0`v2J^#CKBhZ3lVgT;kD)!4mK57!_9l?(~gz*aa2G z6?7>hjo~|Ioq+aq@nC-7UP@jGg$a)|vL@Ko(+3WzaHdbxxps^0xI&YMB3u>jpwHOT zS5{Y@CyF_DddJBTfDkC(HWF%HAu0-mJbg6-00~$ zqo`top_fmE9zTM9tj?7E&cn+$+F9;0#aRWiq3q&et%JhWo6uNf%d*XMv)!Omn=k14 z^?mpChj);$x0aT~gNk;qIN+<=*q1tqNp2XkgtY*?gLXyOR-6*(o*daO0JmAKQlMWz zkQ}b43x4KCoA;svBQq>MH^gN~{kh5;BQRY$9{Tl8=2K}O6PCo0{nw`ltB#WLuhzbX zCK(TmdnYfwG4ft!h#?*)e?8Jx&Wolm#s`o$=D#Fzw7CQxT1Na7km-5l<(T! zCrsQJi`Udt#jw~uAgil=)mtN~nwLQzfM7VIz?%dkFttE*=3qx>r&M5p^So{RFgEg= zyYT%R0iEAJmHvKTIx2ITwZ_fQ6*UM_z=rDv0jf8Zs_y56)rS?#nOE2COM7X!DuN)= zHEJPO_<)jNCGB~=6Z7Wr=Xv9m-WP5`Uww#OxU_L>Uv~0vg1JRYCyQB1zIr(I;ejJz z7_T^OyImJ-AS?5T{@9%9OpOzH|3LGatCYvxneIjR1|MnytiL?y2hRl(xBFu_l$Tah zo205fGdwfQbGogG@Njl91H1jF<@}T2HL%L{80Mv6`;?DvEw`HS+55*LXz${24cHCg z3O@*r?@g=ZL|PpD!H1Af;TT!XDA!WCS8<)())z>ez? zh;srBgo~BJ^rQL6x9zT!mOU#BalH#3>ZYNg9aAY0y2eG>Xa^nRt zxx%MP7{tyKaa}wpzlmA{Zu?x+vb#4KunR{}44`<|Z1254k-+mBR{rwLWN~`xJ>R&a z+j87nuj=Yus*E;!+E1mY0;+Byfj+3iSsDvkE@q}qSme5I8RJ9p_yTViVdthB>Ibg!Awyf23Ox+%!kx^=iV1NyotQgplF?$%cjKwxw1WW7YalKYDE_*|I-fD_=k zcUco9cejZ9S8PRFeN)SxIs5VprH^5jbjfq3@OLO(gM^oDvl|3X;gMsH(lo(CnqWDV zj|RX%Fq#VXS9y20OWnOPs<5+Xt%XBvrbfdAK z55ap?2a=CIt63%cel4_5L_e|wbWIY=5;qs}xx$#sh?9(Rq?RLeJ#DzxwO0~FdF1>e zF!;!Tm;8tsM&-*{=xR9`4g<%d+#il8uYdAAW0{L8YCAq8?s?PlCRvdmHVY*p(p}Qa z)~!n2_`aX~sXbfd_N^X07r=QVH^(Oj@&PFR#1k>s!2uT%TjsQU9-Q< zFO_W>)N?oP{$^I{2a^{Yla+2Yy@U_c*?X4J(IvJm;Y177AMu6iW+r)8{_9x3tZ69l zWG@XD_NanS#R=D>`}4c)%@=P4d1F5NEq>-bgUlW+Kv7N94ES7F=dx@iWs=^R0X-{1 zt8H$KhZrx7>@xLQ0xeZGe;TjI(uUbRM)}3dJ7_50mYXw3c!UFt*8A?XV)oGaw4D_L zt>sfW)@s4lK|k|_5QfL8206&5Zu9(mr=|~H^k|lHpCFL0dA}Y76M0JzwBv{gYr0FI z3Y<%=fwH*BT{Na1*LZZi*y=+aHST#^g!HQiZG93n_8gfqb-VdDX=OnDNIlzgJpLWY zAcP8E97i=V&ZJLgUEV8AUrbHk!v7ZL3OO$ZI4m0{&cp>hg*Ch!Q=GexJLTvK^|Off zTR0rXpTW$5p~k0n>nHXrmjU6lmTKJ82bW~)#$XcyYXwdDl-fG8`|W5)Z21$zg^>n4 z+i|X;F|^X1e@X=#3^fY z@L}hNHi- zEJUH8gsc)u)=IAbP(7ASG2bPgixQK*qJf@jnr1c^WZLPDpzR&_ccjvOM7gnzkKe(d z1oTk`ors7@SsX80{$)oB$CJMhR&o3w0=lXdC=h?X`Z^Yh^Vv z53a7QB?jtl*D2tVic-e0x*pz!>u+y`)y7^{7AYj&hrdiqUfuc0Vv2slqCpi4uJb;5 z^oBP;JJCor68)%agu{_qX=FjYT`>uBiU)f&q;kcmP&(-@u~*nH zJv{^1v-AmX-$u>x((JNXlDi{nR4NUL;x=_FE3>RCl zn0d$@k&<*#tT9w8Hl*XV7X13bz~eX_voA_piNWPx>pC^~BmOoq7xEK1VhnUxijgN` zEg0ACiKWMy4y)0xxUPe$H;~*0uCYP@Bq{0I06{T;@5NXXhtf>FYj>>d+?S&A$@}|4 zW^i6$m8zLavIc22SYTQ%O@~D@U9a?1Cr~x86=~Dmn}R4CY4{o%=(my>OxW|-j3Z1o zoEuX}B9)yq;0j%{w(4ixDyFCDsE?@2JLd~NNR%?iZGxZk5snuBq3Zb5v%(GYWSElmSu+6ZtBm?U2q%~Po5BL5 z^j!FbIa{;g#q<$=T>kAYDbeo$oqjLHnAv-_JKU7HS#+1`5pS+j9Dt2^Y}RM%mc-hORZ z_W7YsPhj2O48K-e9iw{-a|53dHc}n4>v|HRW|n+%kh&!z6)OAy#(N|2` z4aAWENCdyY+*KSx&hFE4oKt(_PK`hLo<`3(SSURK!CfA#$qS57SSbr+a%mf1{{6f3 z@%T(2Ow5$f7dzwkA@2^agf(|Hp29TQV#6*I;j0!i=)a0EUMZV^o6JE;;P}q)xB!b^ zX_kt?4Bu8fEX0nrp)dNr+?4q+Gop&wSy_yC6?L8Z)GfW2EGzS++r@Eh*% zLhi}B{y4!ex_1k5yoZ7PtE@@|IY#U z44Eecz}NlJv(K(%ZtIN{zJosa%mRm^{8GVRy2)j(aS& zWB5jbEkAWBGvucAs7Te2=-{lg$8I@(We!DEJZ@%)Yag>B?>`|MvRt17BmtE{&chbPnfw6Oik(B$e&rO=p7tYs>G{*eLw6P|A@^{{7@^euWY z_2Q%gQ{1e?s~T0?lP9qrU$x?%n}x&+v`!9A=pZIWr+iIKIN!4;e=mK7`2PCoK=suJ z2cOoB56W{_`9k@E#fht>WZ?+JbG4nCyqkQTg|{mhG!GtqRl>FE(owcBW*?YiitLks zsaTGGLF*gEa%Fz!eU+UGB|a|C{kqZq`2XGdK1#`k`eoCnj-vMGg2l#LcA_3j!lj1; z1Nx8O=O1`a42b^8WuDn>z^};Dj#zfN5Ww1?{S3a@ZY{c6=>!=Ix@R`^YQHB&KMhw- zzNV_qTgL5lQn(-bcnqPqiGH)RaVb&o#m@CKMqz9pfB4_m1Cbl$EQ7lB({*fuSW|%p zqY2C#44CyJ5HP6TRJ+xr`xpz_krdR?5%j5^XSfa7mmHVA*Q8!#VQZ@?HHA}tkD}R4 z+L;gwaO^Rs5_Ax#VM>UkJ`QR2PuleTSm|d49*tU}5xU}b9gp+!MbM6!uQ6){sq5v? zHN=V98@9AR9gGgQ`$UCoEu21R*IbI?deIlODEboL@VKqmgd1QqTHBU5>$xyAdVE{i z>qBZ-T^D`+2l^-^aI~tz9@T|-1#ltONk-UYJWD`TL?$B2*h1zgBMI+`W!9CQ@OxiTxk@AXe zcL`sYuZi*2LudP0)nrMJiQiLzOccl@8>8AIYjodc$oxtJE9dbm1{b9X5wN09m+W{5 zKuJ0zV_*5wOLp>*5%e*H1vGtiMmIKN-&TH9J+(UX=(TA%Q3OP8r{g|Dgmu$$TV+La z?!Z-&Wz_v`vV2{}CEv%hq_r7k4JC5Mm-zs`lR7PO3US)gKZbV3dDXJh=^U@{IB5td z{QM$IRAax94sWhO_WqcJlD1%yPyskD9x;ArVrR^tMy0 z1v)KpQQseQ`qw7&$)-WuGk~-+&kYf5+AV5kBrQ^bwMd_%>a?nY(n32O17YkOk3Gh?zau!dYd>xpw9Hd|K zu{6ucQ*`DVg*r#oGFc`klKZ}?^4}x}YaFPcZW${%;N7Y}Wp-j=3R6PN+kCp=HZauh z_@jAf(=rgGbFdC$z3f?fgiBo?ZzVcE*4*j;Q{FsU7DsUnMvgvO_$B?d%I=MaOWF9( zmvr4K`;CDuZ0W&R0jVeRn_Rw+Jx7ku+`x(60r7+G@jb1vTx&)c*6hPmJ+A7bGNd*3 zdYA`>DD`k=jX=Abj!bWTF&x%}*T(P)qTyFdszVPf z@Wm`-N#-u#&%^oA!zYQE30HE*`LZuRgS1+r!Vdr#Ka%aIlwiy*b(=^y`qQcrYo07ri?WXI!Jb@zhu2a|O0WsYL4g+Xj zuc;69N+Hv=0>H=S?KVVHIpMYzcL+(l$tKRU%DCS3e1_*=d$wc@dr32J2r5x=H#+a| zJFr(4!B4{6WBM4V-LH^q(;xZRYAlT@w{y^7fCKvsTUS*mQ7V&kV7@Aob-o$Z_wOTI znddzs2fqiux!?D#g#{In5R#=|+0;EVS>?5jJcN`eTq|1C++obk^L|-;s>Alf@`v7%Z2Aw zTp+Zt9Yjqq$Jg=6U5HdpnL=2SesoQTqr!hWy4P2q+voc@b>76C3jU9zs|;xJ{n{c3 zC?(=g8bzc*V2tjN4gu+w93!N=1VN;`OJIm>^uQr0O6PzfEwRC9HbOw~o&Wdi^I^}q z@8`sQUpwczMjFEOf?>ezz7pC|mD|N0jWe6vm18?={1Y>{mX_IUM3D# zi&eTYYp%5GK)e=+Hs8pCSwGF4?l$0mu;B>3ND8i9aX{I9Vvw|U+>BIqH9S;Mz zSe=}7@xqK*3Ie#cUM5xJ)KTb4``7_ zKBCIWFPGAUZ%q%k;mBF_CD&r%f7(_9WOB{~qwfP;%(VHu5)7o}?^MY4uoi}}?Y2nW zi~5?rxi)*3X&8*TD0H_^|dKb8;-B2H-?zD#))}_1P_i*UMBQ8m~_|t zWA5m|`JB@T6~FnG@QLaBu=C!2+iF}@RX77p$wXD9@7A9}3o}AC1-RtpSv^x2P<5t* z(VH1TxGNkN@OAUUl6D#l!P;DD2RbMf(5o&J8cri9mx`!Cr%U6`iyd_KA(nl(t|*=V zoVz&a0bAto#$q@1t{Kkxi{50x>T4U%)b#MiX@b>X zcje5$j9m%#Od-<<&F-PoY{==}yX>XvEO}q1!|W;T$SKELH)b!TOK#st-p-oU*CTy- z23=urfmh`5RhyP1xY0U%fk*J<&04T_O0B z%Iq=ZK&g)w-2Ss1*-P2SgFgMZ>Qvuq~p{s5*bYp ztf@Td;-K9Al-r^_?G^O%rhl7*eWk@q&JtQty zJ$ys33l_qx8*ZWfhjiWv1>wgxRv@^c5+>`&G<#hu7JLr_^ZTte{&8780kVXOfx*u? zzW6wwl;_^5d{&8q>ED+IPF8E1y!wU=1)aGy85WDl zXl0gS-aTjwiTw2|dZ)B-Aaj3KUG)OM-KO{)7FlbZ{nMo?@gk$eu#~)04utF6N_j_^ z^r!ehz0j#c@zej)(D9?6x_DQB&xCPCe}?hLc;iSDg*jwaOQ@#aTm}FrCA^t4cz$U* zRP+)zewW=>cUL&qzpOU%K@5k)Q4lc;88jVvwAkzeNfUpOyR@a#$aNvd$axXf!TV{5 z(Be_ZZ@og%`}uMCF=nSzLn?lY2jQuEkZE@mByN+?cd< zZisGt^mpwIlhq3(IHQR;~ePu)WD9sa%W9NU0dA={)4$KPoa>9A& z1)@AvN5I+v7Omp`q*Yd9;_v&p0ivZq8Y5Ogq7`4F%klS*>Vl7&o9CDfF0VT6 z7ta?TqZ4(S35GX*L(VflhBqKZ2pKWnEVGFc&*duBYmrIBc(1_2D6dLQ)VM_$v{Jc- zs9}3LD%vI}O1UkL?Fa*~O;#_mO#LSNIl+)DEG0P7fZQtZfM64t{W=ny40l8C`^y}h zi&E@Y6wWvquBsq%j;G$w^*ez<_c->y&-(cU6%bMvJDukE>gTHFP1pWb@w+pnNEhtI zIOac(#%FzKnG>$-@kx^i|1)#f2e#Aau zC2krE9lyPAVfj0^BN3<*3Mpb`%La5xw=LvZ)t!Fiekcb$bB7~d<%r9ZaC+#~&3fMY zT1>jN^7+upc53HG0Ws8DnK`xd#(gN>pvySdraRXOe62ZMd|w%LM7q4BXf^<%qi1A* z2%3vGSdP$*xNGWuwfjEQ@TxAr3tr|r*pwp+fVnt_po6DtQ5;a|nFB#1{ld>qEIlPa z$vA^dg#19;oJ@@Ht9YlqoUXZfU@O}2rDgk_-y>zNo4QVeek*yhu9pXhp$P?C!y|Ub zk4Jy}a(e60_4QSynvljY8>{D+W{DrSD{JmDI4+ZJw3E@++@a07N>Hz*0Q0)6^Lf3C>x^f8h zNUo%dQ%wfovjZM8(c5wx(S~4)F_|lJ+9q%OMs&A0W#nG^k(?CM)rVIF7i`;G6JN?u z>8-eKdtmRScULCA;1;+(S!nUQr4cM82YjuxvgBzwxSa)FY;wOyaeO?P7F_W$KF0>q z*v}#*ui4q*0!M!PLLFyQAi&@h>hVZf{i3MJN~m;h4z_zD?|dS_$gB)WdX-|*4bTno z%C3crD0+c)x4DJb9d&}@K%O`xDK3KSK}MBBiuS6ly8zb@fcmuL!z_$$e$x*PI;5Kv zg3}mulL4|^QLnZl$fV2g8i^X+9u8SK5!TcfN%2l_So6yOw}sUUYFUej_5Rkun{9v# zY!W8~qYD6O5*?q(X~5}H&f+@x=4F0qI@co>W(UbyeO5WvJ_=s3q}~OqGZvDRbv9z^ zO6-KDCSL}9*@Ae}P#)N<<;W-y>SwO&-VrDq``W^+_OF1243n71V>v)7$)XhDp!_h0 zY<2PF9FBz37JHM;IVVcj!b)){{7pFBY0iFuEe#$u?U>V_jmb^yN=xSs^l~g|Pl0c> zA**oqo6#BERLwYzVz@XI=Kt15$e${u%S6uY1i6X?>>RmPCg^qj`VMl!;LIi#y}FwN zu#TZgdN%xe2ixYSoQv?;IHxZX2d?{Cp{pe|9;XsgU9L{IBNitcaz=3Z@UACU8Jw0j zU@Y{ex|2rN1uTnl1Z@;oTUx~BbSETPwR5!-diSH8fUa1mFxcl9m(jIdpguxLKN8C? zqK`cKw3)jmmD#4cG2{2vK+RKHbL=;;`xGkGEG3Bs`@2@Pt=xHeDPA3Ie|kM%!wyJz zGtSp5x(jpqAdwU5;O*(zbi%~!y{|x^h$#T<-1W>udkYso>_8V|Lf>Y}XJZBbK3PYG zYL9n3NV@Wi=DH3q=nfPvF#8*F-+0Hh#0-d65!HvbfJ*E(4=rXhyBG}|v~BJ6>%AK~ z+d4)`hpFLw)jlr?n9Y1Y;7Z^yl>oEjEYDFbj;twZ-UwWkAYZkuP?5j;ma{$7n~mO;1LTc`g_k$vNRRo13F|CbS<6J+Hzt+l6*<>~*bS zvu}w1c#krf!j5k@42-ZeK1qhsTs-fTXPxX!8c!xd$k!$NT3C3=9)EL;{Gd1AG%B5p z!nCw*oEm|bn)~aKfqLYOPkS$t)TE_EDl_wobOzrXkp{~7C!d||=!2zmeV~3*i1Rcf zJI_m^y(TDDUC$pR)vHlI6kT3jbWc!}B*iMjAuX=&i(91OO1m@gL5BMC$4FtpuJ24~ z4jrvov;Ejhc_#0T*myXm;HS#cC)0kbgbCu3NHu0jr;w3Bss=LWkvt5tLD#|sm9c=Y zxZStiNnD^dop0OqCxP?fcS{N{&}WT`g<6u7-adQEQ@3D)_DQwx&U(cwpf5-K5fGcx z$xFiBA+6D1ooXW3Mk~p9!uL7e!iG!tv0yi02*|bni*b&CP%*cWc|n_iDSec6{fZy< zU9b!Xpvx~EBKR7(yxFX-qUM>-*C!_@7mRXQAT_$c87-(Th$`|ds(uEH1)c{K~AntLlah4nRDfe&I0e}7D`QRY7+K4jRbYH z9pH>GST^R)Nn@*Hk`}(Y)S^`HG;Q!`iGlC*T?XmoYK?eF&_>LR{%{jcL#|S17v%+<^&B;1l#*%yr&hP~D2Svhy^=Fj}E#>*Q zK}9dd1t{}_%p<2X)VUJ88UL%`YfG?~cP;+8L)N#6s(=Ht@b7?EM4{L+K@qtYC;ac+ zd;Au$t&e1(Vsk+@@y8O=Ya%I1iF7Hdm!7~Mv4C9p zw!^y@90D!{IW0sNNm9#N{zB>WfVHY)3zXmt*GMK2)}1)Wo5e`3q%rGI;am7pkt(LMyTp7<6>D?dc>f>0ed?lxg4PIi+zQBo!AJWt1NEqa<8i~4Z(S)E z2N(8A8afrJU!_xi(2@Y_qS0E&P?E}4B2{xWDJ?M<8oS32gD+_w3K}WdmPNI1ERBZF8UnrJEdMR%4(f3wcJ>_R=Rfe6&>nga=WTs2`Va4<3FM>hxuDI zww7*|H!VQ-qt5UsL-a7sk!cBC3?_PZ<$jW1mH%KPsKv}Pnmt9*_~S|bEd36 zSmPk~=-(2$Ti(ci)qxy~J8CDLTYWM0EEwnGcic30HXAQP=_oqlg1lpZWGa1cyyzhb zP`j{X{r^10!;6M^E2@+{EW7-y4CeW%*i zbipD#V0-K$c2vx#;fPDAo&!`Y{p~S}rU>!p{*0PdzlGes+O{lBd~RCd+n98dl@Yhh zi;wBlle%|WH|-5xo9PfYA5lt?9w+HKjcQ%xdH8HpIS+#YI~^!VTYy56M^Os+F9Fv$ z9T&DOg?}#Pf`kk2sYe#rF(K(^QtQ?FL)BWX4u*odV0xQZQ!CjR8s-kt9>tZEqDJ(n zoI&Nikcqlr9w)E&N386QvLxtI%x#7zC6A%B6+5z3q9k!k)o2278T)rmo>Jufwm74a zm-^^gZz-W-qbEGugvz%C>GKzZJMgXR@^ zh_B<6KnzgNl5M7RrRXW%QdIn_Q!~4w={BzoR9jwCH@Bh5VbQc(o*nEYlWM?_ z%1_k4{sG3pqOGSvHX5ZeTg}sd68k*R#A)*IVBxZjMNPyLvrWHM{Pyx50SOZI)P0F9IoT))tplR!uNb!6= z;6x-7*-x1}Q68jj-l!QWTIY^FyA{Xb7hDAO1+^Eh45eQus?zb9VqTSBNlIkFSL=q;Su-mSYT~<3rJgzoS08xCXvHeAP3k)yClW%SY z6B~I7VlHNHg_fOku$C*vaT&d)awCXd*IDLM-#J$F+Mi{z6YJF4;jh;BG@Kru^K0Y@ zKh#|?VJaPt%Iw;-&YpQOTA2$1$^koW(pKV=SokA(5nb-^nx(ITtPXaS;E>Yk|5D@? z^F0ZJOw-cfS*ZnaM*4y81xWjAc}|8kf;SAlJVs@jgrq~n;$h2f;Ic0zo`M>irr(0i zz>q<~owe`h>o2jn-dURc(U_ftb+*a#`?BdBrdi^taV0v-scf2AarEE&J25|)a9WU`W@$zjQRov(+yrCV5*$n=Ek2=X#Mpree z`pS@kB|FpC-z{R2=GHJ-pLFk0HT69n@3en#qoG zsTcycof0RWxJZ^0-`5a2e|zvg*8lUN*lJlJh3>mIJU4^eoG&TT=#Npm9LV0G@vb#l5@P|rkJlTSB6J?d;pQlv?6z% zC=~65wznX&^)_giC)i7su1-pNMK77ZF{TkbHmYdaF(_7kb*sn&^(Vu(3q7p41(1|> zbsFA%RRZ~n0nQBLa=dNiK+=O>xSC|+AvxmVHhSM2of~D(SDsY<0LSF34SjQsOTg#` zi~EJvb+XHHk35yUK-O?cV>?0-I!%6)7Naa}Wm3*FblyU+Q2^83e9wY{zML0!g1kGD zV9#kkkXy+);O*!np! zl*~w9;fk4{_c+xtj%ui?(wzpYecbXsr;M1$e11ATT23BnkRIVSu|qZA%d<+6t6KGE z>D8K?`uGw)K>K3`*~cU{&F0e3al}88b8^P#Ql;iKjhG>L>lXA2FjC8?TX*^-mO+(Y zQqPXxsOW4~{~6yoPBgh*br4vyG%L@K*SZknJa?Pd^!7iFVPGSi<4Uj$!!h!n#1Uo# zE(MDDDoCD@Ey#~^tONe{NwvJ#emvZ8Blx}83zDitc7VR?fME;l;M3;uS#a5AVhXhs zR3ykGVf^%HtAI#jmPwDm53i&9kdt40#2^d8-8}JLKmle3`@K$t#Jvhqc4R_KFKunh z61d%+MF{2-_;2f3lm!`ibB?*uLD*k|GjV^5SjM`vr$c-ybvzEoKgTS=t5iNGaxNly z$N16aSfcCTmewb2KVxri<_;5^Y0)7mN6tBzg9a;wqNzGu))yi#>0|!*)R$%yV9x!poC^8e zT1iv{=`4fS7_e`~?4m>YsDUs#9xhpyLWYvTK4bk2y{4b|EqF=~a&mK;Xl~rUDBgqz zC`byDzUk@pb=BPzezh*Atw3}o=shJI=_=<>!jZpK_FQcjZ$XxG2kg<=uuRkG_LGJn zwA{nw1!Hd-YIsP|N63|CK;IY>O>5GA*5H1%w9sc^o5k{>NNb?Gja8NuwG+X| z|G&{G#z(^UCCgK3P;!h^s4i6skHc>&mhr)%l7@9wrnk@7^et?nIx&U+wOqrH;Y~M_ zCRcI?(!u83t{mXvGz7{`{@jEMr!+L!sJ2W*pI!pL9U@y%nY;;*O>TD1&@8XkBHW|( zI#lFxE?%yV^cmF! zFa9SLLe3~Awbh1^jC;UUd>+*$KjjGWF4?ewqyt>~TTzdc98TW(v&^jDj{E2M^u&ZY z4fBQ3f_|5LU^oIHmFT+5v!81FF>}I_J7;hdhV_Z`FyyiPeusi@yxtWWvHaPS!GUh>T85+^1!=9bqD5?OU_^JVn#-5A4F&e{L8 z%LIYMpT09pQVL9L^OG`=v(CF269j$7<1ZhOYFkWo&4& zn)nlyF|aTa^OS?3)KG#aSk_k~hc(#;dfBieBN5rFVdR!Ew#LF?duScFdWQfkI({-c zQ+n=k0M#G&MB*@e6kZ2x^pt>0hE5PHI7 z-|G@T3RJ1w?_rN^8PqMy?EiG)VL0A0y9QjJ71@o<;mPmo;EZxf&T7fvf`O(?5|dIi zAK%jI{N-5CNV#*lKX;7#mB~pl8GgU_?)gbm7}-ihGKM~%Q)|VXDF?%>Gt|oiOS36@ z?VuhSz_{YKz*R}&)fPf-7IW}L^KqoBb<%ateZwdTQjkNna}UN*!yE;%#WrNiv{VK^ zmNgP`KA94yo|a^AB5GwXwNxbGPI<^)doU_GK|%;ffValiJKG*YEt_etcr>`tnBmit zbf9@|Xu#{yO2O>?;`($f_fV-~-21j4`TbzBCgh1@8Pqt?m(14F>~@)_9i8%fy#&0Q z>-Y`(NQtWR-(bPO8o26_jGa7 z@{Lo0#VidzzPA8XC(j2Jc)Ec?DSfunHgeEES}C`dz7&eCi1o=iBb7F%kmeI~WePE9 zk?4x8XQMK{l(i*<1oY~D*6w!Yh}4jll{Csw1pW@`XDCi-E+vuS(hO>K9EXg`Wo~uo zP9r@zz*(32P?)hGwH?Q9CY+BtxwgUY{R<@)LKQlqgt7D;{m|y{Uu<UGa~qmfIELl;AjKqqkI-_JFU!1ydRWg?3FF19`Cc6-ekZQ zxGd3VlQZ%mlArI}ED{DfEzrSgEiQUy{RrTc0EY!+PKQablrmM#X5XT3;r&TTY7&cy z908oF;Z$rRAm_E}GOwsP$F(+wa^~(|ib=(mE`%5C|3@(_1b2y{b;k1VOL_{8vM=y{ zpV9W%Co!X-MbcYuD2ehbSa(6Z^r)@FEGsiX9<-f1av!#eA=0d^66GN4pg3e1LoV67 z3a<}K5vXxG*Wg==ciewSm{Vs7N5{iM>?f&w46QOZW*iK6qA2P18)(Xek~bNdy~;i- zz&hEm{O?md0di$RB$a=H-Fk7$m2)w$_&Bjz&eG5H74QK5lo2DqbG4-!0hhyu;f#1% z?!p-q8lvw@h4dsKbk!waHFP1Yje zg(RaStClRYOpA>vCSk$plE!`-GO$WJnSrBcKB~9Fv{U`Kqv**Tw(U8oac-tCQ0Tvk-| zBNh`068Yki#r-Tq(f3jZh@2)ghkSsK3|+iWdh2R6!H|Owe72kvo}X4zrfE7WUItas zuwY5LvWasXNy}6#u8QHJVeEvC$(Rd8bz)tz>F@Oo&h(i6V`t$BI(wPuN5#J{kgqm8 zg}lQpSGH)mFrJmmrWWEM!MAleEL95kaWr4Ce;%batja-uU$BKP5n)XPJ5KLPIF0=C z&cYK^-c zNxk>8QUUlk3LY_s>(?o`btNR+(!x1sg6QR0TvRD^_UWR^cYafK^29hafv(MMT2>7O ztSx4``^zUQiOi!qobtz3xa^pt+niW9r8@dvW%YlqUbFz?P1)gs($&O?ALh&kpcT76 znYgvA{{T*A(qNDgfq{|(pMiMS{DhF*kiA7tEW-3AnD)$&PUsJ^KU`n7I~H27(I4UB-!_T; zRZ%?u_~bgP$;E&9`L)E#jg{}_TIxyjlUlBREm4t5LCWm_CReN!X{M$_((`mXtI%`Q zOFB_N{7sNgtdlLbqa&fUVx)Bt_8C55=*#WsmwrWw6<)_WzY9eVhgCteKR=F*uwett zO|Eki3h(7J7cb3ti1Wk?bQF}54y8U5IMHUTho!nPvb#Qy%T@DAu z#YfpT5&1TjR!Vod<)#e6J1=Opb7rm&_0s^DM#y~oV23cY)y4-I8E~`&DOnU}!ovOD z925dL6k;TI-#mTVS;6Xx%uzjcQM@V3Zk^G}wORlfYjg81;tX7|m3j+yQrg;5V-r)0 zI4u>Fok|sQw?#zfA-k{FJM(c8<^Hi)xHeW&FP%<3fgmFI=FU5!mNs%mx<;jfA`$*+ zutU1@7p-|8mS!E&{aeQ4JbD9KJl<331ieKnj!ONXNd&)6V}Fe(fdWgycUVtwMc+_N za)SK2g>iRY)Xn_B5!AwGeZ7N1$X=KdWZl)c|GwbtL{H59ky#rbj=JSIlLS?b(7*rdfkprQ_#)GI)#PwRcZ zED3zgB`dwQz_hwpk31_ZtIT!+2e>#Vdc*m z=r3rBNiR*)bXJzlSW(SLq4K%k%=NB3Q?&Lj`wt+t8E2P8?*dEFZud-}b=qepQIGeV ztz)d@#N3JXToH}^c9hWEOIS0ZeJjV1SanP0G3Cy09+bi6|qr#_gT9jxx0s()I`M9G$?|%`XQ3%4p#$VU6x?KA{ zbS2#d=ec6aTXH#Rk%mNbrOY zD+OHzVW276|ENiA(JCYE*<|O?(|V)e5=J`8>z1omfgV+!RWa%6ivmsSu>Tas2(2xI zH9zGwH`V@%YU-1_h>E=Y_?<8S_1U+z!&xY_y~17^pxE+4|MF?&Ut|23n~?4Z#bo3( zhY0f|d3|W6y}{);7q({{O4FZt7M6*mkh+^Wq|(ge))K7KtObSDxn`Ln>D2y+zUPb~ zkr8H>>JWokse?n+{l8c}C%P<MTdF$=NZ!k`^XgC z8P*V?ORyRoLG8l@lp$1ymAxdw>DD8Fk-O~4jnuY7K(U3-;<;p6Y=X~wgpA@Wr9n+% z<~h_pkCpqu7ac+WTOMF_a}WJ8&Bph}V*J;VUXJs$Ws2)=Qpz6^zj*H*jaI9If@Vud z1x$_vO8>Oa5v{%VYf+KrT|lZa4X)Tdof}?=7TWK5nLwk+AswuJw)50o&V>kJ zntN~onxM`?g_p7=$Tz2wj@`9meXP^xs+eJ}obvR0yuYf3ex=$6N@Bl_u}tFv?lz*# zk;8maoBRcTzUF61|C$5|uvj^3EV8Iuu}!x$!Xm! zOOr{IE>lNW96CZb{sPs5b-n65tgK`Ugi(xumHS781F5zURTIOW&;eOlhv7YidV+ij z7T$uuQzE`(z3sCoG7OD5Rl8JYo6LxbYIBd)NK{P;_^nk}TAp?11^vDd5AW&sm zYy`sp3q~T(d2C1Ens~e6EwDTLhU>h+}LtTx$Sa4G}ycu_f{$@bFFNjll|`WSs!%#aKBk8J=4aL z462o*woo8bwiq>+bnz;Jjw8~98U!EgoV%$!&+~igo@r-Qt;!)tk9RC-&{G{1rITr( z1(>^%eX^*GD{@M@-A+Vr_xN+uaI2rDliOcM`7x4)aX&C=t$32#gz6w=59S|L*{BE- zqSq&;MM*YN(uN}|PuxmM(ULbWv64umy`Ky|d{!I~#edyG?VGOVcN)F2YZ$=4zi)mV zo0NhSAAh9v%$=^;f(*5~dAlpWrZ{)f(G?wx8i}F?pW>RF(Ra2|I_@JidB_j_Ev@Sm zc7^#_lYlP>*Z-HP<1uAjgg; zmCN+l)KMijm@=usO&SmJiBXL(dX@h&!U&1Eim^`Hi|~Qq_D>mbQkDPjljhYkwmdZ2 znxTu9q9ofcez!thbcY*GP&Y4CwAE!IZ@CJME#Ay@`~|F79Hp1k*rcNMy`F1zd32R4 z^>kux^1lLRn_<6{l&TWge-Lebx zHoU!f=DyxJ2Rh{KLq$%8zvYxt zt98cag-au*Z=60~_k8?zVLvQ)_sX`pY3ze{J;2ujxy~iy(|Q&zopRNt6?g8Or}-a| zY>1Lk2`KwP=T!s#m_OYbpOq{SK*ip z+`uCW2Wj3_0HBL^LbLTw8fJR@k(j@BhOw-E#2cLJW~-v6zMuQk)5w?F0lelUx!Bk& z;r&kghnF-++uo__!k@xn;#1>Ns@&GaD1eh3UE2UbPB((x=Av)gY!6x)*^&ZH$ZYsze{KJ5ph<>iRah$S1>l?j0qY?{0RFa!^@$aFE7D;0pfda`yp@m0+rUA!9-H zwhsO2D)3z|-H+)Q?ZBTcqH0!_Kt-9R3geIG-^wd>@n(qzhC1pBcTH6F*9F?%>I_Jz zwXfO9tY&rmHArE>|726?JDTtDajHH?zM4f=*%x373JS&K*icO86pa2CMJyVGxlqea zhAQN?pw!-MtY5>eJ)*nYHe|%hBhPq8q`B-^7v3863p~xuQBnAm{YYBG>}xB^P!DV# zd;c*wc6Qz6ZpweL56fXJyGJL@{i1q;^EuwRo+wu*R}H%85?kevIE9%17f3Q_`pZ3W zXcqseCG$y6g}Eh%E3T!(gu#0 z1OI-Bkpn+e*%{fYUOZpug)XYve;K-U32&y0@`MkXh{X^Nmy|(TnUtj9Zfy!YwV3(h zP66*em4IUKZtK~Y<9x{qmOIIhGX$uq;IX;liy#TM&T|rQl~Y;dMBVUdkLZ*0s^DLZ zzXgAnhAWX994GNld@aCCFjf;?wy;t$=FpTb=ckqTl`8(zHW0t=c*o~!O@OdzlM=PB`O84V$$b6a5s+vyFKd4hh*VI zBTovcHtDA{c3(8x3A6>j*?fAjX%8!(0uNMPh>UFJJY7*@_4s>FkBPBlc;;*j`KCrF z>11JOO4^zLF%lCR_<5v*kEgYy2dnMJK*9!kOK%*4Un3iC!0+$Bo*Eey^#nHOQA;a_ zd|QBi`kF2N%vG%>j;Vs#UGf-@8PwwJS+Camdor-c$(!3xI$NSa`-Cpxm8xt* zTlEbKNVZQ4D^!}m+zw9uNc`pv*QNBB#l}z=pxZx9%Tw2K4N&jjFpRXGmQY;P&$I`z z6aiYAoQpHsy`ICAPE;w4n@%BvCWDRHX=`hzZJIlg3sbfeG1}xJL&b@$lv(7<_h(Fs z45{sCcnfI1Ki3@`B+$A4E2)m_$3+<7b>z`fyUGR@)z7x)#$n{uVWPifVHK6-Tq=eoOZ9_{leGfh`6YQ!{fxqP~P z#)ldn;4MvSoRa?Z!wdEFpM$+BM+kPryz7PP*MI~?@;(dH-W0Ef zSFq#LUP~`UU0-c#i+|C^sSFa1PkKIICo%^c)SER!Z?H_Aa9<{z&4Ct3eG-15e-NiX zX%7Pxzn1GP3?M0BoKCT7uF}3&%Mn7B0gbWn86w)Uu>_Nr+m3F7vT2Khyr{tFT;hDn zLMLe8Od*NVwDII*LrUckmY<3vHYwFEcF4f(C3Qm)@r0;{F9F|vp%J4Rhc@{P@ERQ4 z9or_TXQWF?@C*Mt){U|t5$>#YO*l}gNd)#6H)+m<2A*o<15KR3{tBLVy452Vih;*i z##r`@w0U*P!QN%vfOzvsAl`3^&_v-YT>K*-DWNy9EF{=t?}^Q6YEPm|M7nfGR{%Ab zs(G!Ss4CyDf0_1+RvxfLZ@a2?+QJ*RAo>z*_ZlW)WR8e&R6KvoXl{u`MQskf^N~vo z(jLMXKICe;J)QGf*Bi)n6M1&SW}f4GfqN@gXTA2HjUQLkJy;ph?Y`HZcBIMg8JCA6 zN$qrQm0R9DkayWyv8hGj-j5DLhoKhT17}A0$7{5VjE@i44E&Q2)L-02>wNf9Sl5fJ zHIqbWqESxN^;xPAs}w!VqLm1yGUyGHLy`#QEzrBvBXzH*WN3ieg_m9fUG&#%^1L=> zb+bXkd+&vD|1&nC&#fj@cdqcI7>BRossELq^*GBWUZMI~2L9vz9$4~y;>KM)#Z_qB znK}EB2!2CcLL2lH%=4FWD4n%!KdXP{3ze;|*vr~g`p?t`#>5u0_WemiK3N~F(6#P1 zCN5kYua`&Sr@|cD%-H$kch9Uwoe1V-mZ1r+V73I@ zP)!b+EX6*iGR;6(z#*|TjKjLZWBP+6X4}+|nOX_+ma<$T{UxcoSieM*c$xv{84K=y}IYmd&_Mq5p_QDgQ4lxN65q zcc~ltu|Llm#J@f-8_gfJMdDy{?@CQc6&CSnjHa^5Fj+*XU!II$cYg4~ zEwva0fr*DL2}e`U`&|Q-f)^D69fIkq5+h3q#E`}39X>3JrWWh-^7+A>t-NE+!RPYl zALe2ES#jRW=Rd~7eEa5$R`e zSjloPOp3V8uKYJP^%5o8U%Q*CdJ*^8cJ_0CM#xNZqW#5+kQ1Fm>$SJXV9MMbUJqc{ zwXilTs^=+}T|GJ^s*`<7A9LLTwo{P=j^!`pn ztrD5z_?s&dzZew1vO0CDD0kY)pGlWn>i)d+us_d5SVk!1rbE72bZ_r#*Nu=nuUN*i!%v^i^#)W@ z;Pq5cGr^V3m9C)D&)_CpqM|uRTE;fMCxAlHME9(|hns3R3xk`Hjny^K#vw9iePkJRp+g~)1SXy359eXjEewo!9Q$M(^gGu>^=Z;c8M+8J`sCJMd%IFhd&=$ z+hws#nK7ET`nQ|U@8Z2TmK3-w+-oU6?Ulyt1`0aEblAj7T+U`DxlIBD>y2 z%kfUAGO307srgZ_Nyzo7acAHEzHBrurg{3RKX3Q-#`wPnrSE-`Dq=dM3*Vj@P)j6;kwJbY z_Q*Ed@|tq*sQun#MQ`m{5h8vn`pZD?Vba>-81^ST*aRGuln3i@``$ibQ#jYzz4J${ zN-oU0d&nNv{Jh!bW-M>m%FbEyeFGyJ`1()rgPccbmn+diO>ra1tFSGuZX&{q`}62~ z#M!&HUobh0iv4CApgKtY7bo)foHsV##D+)0^#_aQXRmlZTT^1p2kH@ILlY6cHGGd# zZ#4p;MKlsoht%A!;}sy`GnS?bAxAcziM0&i0P6hOHTh5v8~n{1xC&hOiTu{pJ-k9p z5bvJgHPCrgQs&h=2sy+Qa&Pzp!{a@li6UZ}R+v}YQ}smdF7kj^UU%C7|7`0J)RJaTVx=T$|~xEH)bO?zqi)z z{CpE~Jg>@fRiYtgzNwwkAH5%G#KrTOPPd0sPZ#rTV&u*X>W z^&6M4pV3g4gZM5ggwkv|_iWlMdyPB~_sAz|x*FRV+(@UAhXT;OJKSFV>gbmV2exi3 zNnwh?q3fvYXlj$SyuO?JF$zZ!E@zXJEL9-xEvJ?=>t_3xolo>TK2D^6j{-mH%*%4TXzbZ*a0RP`Mk@HnA*5W(gnq~KdAK5e? zVv1%?WN2m+dw|0wCUNc%fZK6mz+M_X{%fr;|F6JRⅇ_N1m+0 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 iK7Si_pJ+QBs^9= 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ɍAx3im%X_k!X*^p@+y7<952(h$hcP+F|UEMC; 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 z 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

    1FD;K(A~&|rnA@FOp6K&bmBt?G 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 QG$%g^$ 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 P00000NkvXXu0mjf=3m8I literal 0 HcmV?d00001 diff --git a/scratch/AAA03.png b/scratch/AAA03.png new file mode 100644 index 0000000000000000000000000000000000000000..2fe32277b67e8f13b3782e8fdc3596b0d385372a GIT binary patch literal 819084 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]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

  1. ->@eQvSpOSpM;Z>f0D~sBFB4qcR+`5;^!$0;Q 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

    U}<;MWdiuLgM*s( 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 literal 0 HcmV?d00001 diff --git a/scratch/AAA04.png b/scratch/AAA04.png new file mode 100644 index 0000000000000000000000000000000000000000..fc83d65d16a3dec14570a959b3842b5f1797d064 GIT binary patch literal 631922 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®tUY9=pl}I^`yMy)vNm9OKGKFeyLLje2VzyQkxPBQNG zqwMetQ)!#;dW<{fP0@PXHKppRY+{IQx+}WWnf-A`@SAURluVbW+FmaOd-M+ysz7_B z(Qjo{{cEC%$opf)P^*Yg_7+Hm0gckRn7Op^_d)Q7VY>UHn=b8%WX+@Vqw9s(&s|Y_ zSg|eG6UR*-2bBrh$y353qy;bPYI^5-@z-vTI*Q{ex?v1>03o_Jnq9xd;&g>6ZA3^| zX18l7=jDxFL7D~1vi2?z)lG2|MUlEQ`|+854wV5D!Qw!p z@H=&{rt~4t)w~#L86Fb7Y)FimDbvVCnADNRRz6`}(4IXt6@`SvDoVWX`K8 zO>;apBYv@bsWLh+7q@b{bKfvqGmcSvB(-w(a7E}wfevF2k@tvHhHJJi+blwb)N_FJ zYLVzEeF)x!dTbu3Gjlr2^qukv`*>l09xQLhR%1~Yw@1@P_=C`OJyDUcoA&s|q4m4# z?a?=$&kDLGeb0-E>-#WrqF*zws{YUz(472K75#b6)hwU({W^PXw8Ipo^46fLsIL|b!&7mqDm(|l=%5uLwWO7*oEW)SM9BK;s^!WZry_)l>RL%Tqn&P~_Yb7dn zYEISEhgThQo}3jRob1cJ<33h@UNduCRlPIQ9DDc&W|F>xO=~~t7oh9sRI!{Dx-D6j zj_|`&TddF)&d$C2cN*A&Pm|-w1`}7^1PE@bsvEP?&>Xw0myfPTov7{`&FcDKXf^ZA@gAKgw#mUX%uFG|@gy16BKY=4-qK{!-hZXNp}C`OG5I4pIi^I(?tmHlNZoVDrN(JEoIYlHllWh8s40Bp)q zW@`RKTRwG4;8?gZkjonvax`3N7DKT^)h<0X~Nu;#(I3Rc+SPzWXbOOV{iC`BQ#8q0y@ z=+ddsNa_QA=AgF#RLqZ2qy}#iy&KNL%6RDv>4eaqxlM`M*$Q$@F)oG;tL8ET(mh}S zZ_!sy)@DC^Bx}Q4(1*`K#6A|O3E-O2EEY%i1oO8V^D{JZm9iT~GH+R!(}r5_gTmVu zm7TNH-*J?%=~$6pdGQfxEWD4~7EP1J+@YiXu$oWn)y=^9TEgl>RGd&Ti{S?7!yCV; z({z3kDZ9~_HYew9Tq%;G@7a8O=GPKz0LqQ*=Lz%5CT`cwb`3g1joPk@gq5OZaSy}Q zhgrqd!9li_z4bzT3+=*tgK8V^eg+f&O)USFKD=TvhQ#dz9$*i`Z$3$yN!4QwWavX* zQXaObBJ(?70@R~jaT%jfP&A11y@!&FFl}g) zY*OXOE*1Gn5vHGzd~%5-G9;Y{XP<@0+QFzTnjS=Txv1RTq5&+QMA>#L%47dlmB;hY zMbxjGds1n5?y~vL7L9uT+)CZ?kiWP%uD&^+>yy(nkz;Dmo&C1(Y%JfU=^(X{CZx2y z{bHg$adWq6s93n2-Tvc(q%H$;c_{7HhVlblCaw9GOLv?_&`E_`cnpb7D zQ=&UyaH4pHnLy7Hs9p;LD zG+tcAbcuuuw^vxOCTMH;klbspMM1Bu=Ibnpb7p)WoV&s#zSNqv2f-~-q!EwxUo6Ou z@uq~~bg3~C@qjut_G7Izg}5hQJ5fG!(k#zh89wOZ-zrt70 z%!ckTu{tGeVnp6hSHy18@zu`)qdhbI$0Zkugy zZmw~K2v&9(X|WZNtCF}PBW`(M_--0hc}&=nwS7K^g~%pJ*}3kXRJX4i{bS$z|jPI zM5JX2{4056(RRX$mkyH09=bMr)l+6t3HBlreCnW&)+oT1S!VlqnP(yL z*cOp~Cm9IGnjT@*-BM3U(Z0jW69t~Aarz;6P%T}Wa@Rvs1f;9%&v33Tzk0we$LVWQ zCq!7T+AC;b6`7eWN$%?^j&Ukh6BT#G_9f>M(^8<4s*+UtsB0Li!KVk?t&;fU+Dr}LsxH>fek_f+)I8Cl*KB%#{nR_%LYw5jU&0nBmSyf6G`In!uWeX?^Wgsxd zS8${2|2aMXxX?Wrdp({)!|fk#E!xcr5{9kvB34Oh+FBC5X8ibDO}ouSYYH8Wh}f@N z1X-tWF(A;zoJR+PoJI!eLf2~=ss`5kl7aKuGhJ^8l2r+^oVjSm)*QcG9wBXOX@4$o zi%=P5dxF@U=Yz2E>`7yzV3H2uAb*RuCzFitaVtR2d4V|q#)m%Pcb&X2ne^KMNrodb z$Xv6)v##Czx7`7r;BlQ6ixOAr;!7!E#P;2;E^DK}OY^Ad$EbO%cutCOWmstb)B|(g z{0K!iW$%p9SA5@Mu4P*DfE?lKC0Tb#?3pR@az#WIAN^mn|Mv(1jk|@b5O-&diZ6O- zv$hSkpE;R{$V!>V;)nP?P0h)Ag`N?vFx5B_ zAFggX+A<^eL1dc!!xN^falYA={g)cAwh6F9h0U zl_;d_3@cH#=0ArxzPICO*GH*UaE%iewTh?N=Irw8|9tM~RyT&4vmbR$zf7{7fke(2 zg8~cw`yqc~MvBToH~WgQ!ILlyaW%1|=z|@- zY_BDG@T4v~Wn}Y+B9Sh_J1ds(OkKSA%lfBt7tyrUELcCAT_>DZ2cFWne~+ZZnB_Yv%_t^5m8Ueh&N-mU{I!51sngUo5$xi zV|%MjX(f&|jOS0Iys*08ZP&tr1M3eHMlB_A5LWBo|LZ2tqF{!q&-l35fKI2Ntdw=| zelebIpq|pPt3V8wNLLww|IXzSB3={Qc@&o$qDL9S16*yu%0SvN=WyrZvmSTJ0ME2= zPpj_teg{hN$%5X42eG#t*BriHdgQ^Vbf)%e_VqNe!1pEF1ScKH;!=f{=9I!(jFl_< zc-BPFA)ph{kg%1FwsvEi_+}aHtqIkzXns<&VxLp~9o`i)e++!YY_)eh@ejUjKCv&8 zTEOhbUYkhH3_p7x##ELTRI`#S`y8FPYR&HIW< zHxnA|UP$n}Lc=Tq*S9JU&5f%x25WH^@}s4UrGCq0Ytab}f{Pr@oI>&US^HxQ`y4WX zC;U_fH}-!_n9{8b8qD=IZAgm9Mp!^sccW(vU;=mIi#sQ3;;o(==5A~UA0FylQ4mL7 z#v1vCb-w8zT$s1hzIt|-R)I3+B#Q84DTn|ulylAX50>G)>zjM!Ysi!NhjuVj|h)IN99qMlw$-&+@wj^xKXi$o9Epk=6#2jc)_m_mDS}QEGG~COStD?Vzo-mFcT0AiALU(9cyh7l? zo(tzh#6180N;Kst3c7w5Uw#SlS((_f;4U1g+?H_rZ}Kh2W_KY|m%x7`YtwfSLd{!f zG-}E6xiD|&!1?F>g{WH^x^ochXu7{l83POvS6?`R8?%&9U!;D9ebNH+Lv}kFf_D{c7H7~RM7=J;k`SiiavGFxU0M&U=w}3L$ zVTv0@q#!a2@y1EJSfk+B+&wD2`u3HSXl-~o=Ci%_&o0-J*P7x^*K`uaRrZizkAhK9 zV+>d5ZW>1VfpU?+!~4+z7VAMCeahJK182PbnaNG}+p^RN=s|%SYpv)0c?QG5(^|KU z0pWblXNu94)Odx~N`k;Z3Kzu)g-8u(NdZF^w%l@GR9fbgYS)jkA{`2hJZ^wqMulSz zAc)K)aaFwB_N_->{l_+05vn=Xv%dt_s3#1x^7$*J-7-t%%4iPvAW=%L4D$8Kh?_0t3e!wXLXQUa}`-juQW^Ncc3iu5T7m zyeHV83LhPx$IjR2{VfOok38Mw{B&yyOZ+skSMXl>j|Sb90>7ifmQC98x*Xne*Q*yH z0U4uIT#;mP2meMH=@6%%oep*KBIS;@LMZ(g$AHe{eZf$}rMy~2rA6DHd*dY7VM{a- zr}43Ad+1WF1b(ca^~Prn+-6?UU_y&Hy<<0G!M<3S15ag5-ye`|K zVL7VTipdX8GcOQD$p87szXLo%_|Tt(UkZAVe?f+VvaIyaXtGSDA|}<*aDTW@iE}&C92c1FO%VVEC2_uu%A-mT&T;ry{Kza9HVicJ=RaR4{>`2IiYTCweAcDzxhxAa!6TM2yO#rYes7`1?`NZGq$ZXrhjw0c!@TN+tuH!9*MvHbh-Pi+(UWM z1KV=qR)j=4o|rtdUnA6G)=#A;P3a>&_?M7BW55f#^h@d*^w>+c#(Yeo`Eu>kj1 zy0@(pJ$yOD#MlgAaxyA2iGimVL5(yxVn3BzU;M@OTlst;IVs>f5uw+Vc9W+cVxpu@ zcdcHvD7@A)z#49EqN^U&#`nfa$#4G!liy883Wb-wh_B<`_o?H!#3}G*6u&{wD`3FG z)s(7vAM|@A$Q@)!(V7f|PXQ0Lr32V2OK><-pHV*XoxzwrBm7?56i==n$WMQ}Ho6Bc z2ywb<;@4c0yx_$c1fX5OvVqUNVdtAxJ}03V)|u|=7#dPK=59{_U)nNW&Wrsml{JTe zeXCDdtsiA}Gbm4nr*eq=-s5=_Xwkn+_FO@+{H$OE40q4Y@w*1_swkT#_u6b_P_SX& z4UpBz9Yp=J-+NE2EMJr^-@gaES3w%6)m*g}Oz~5p#{9S|I56cKxFwb}T-}Qn{e4^@ zM}%kI5TE9+{cmOCt`z`&@=;)(n}QXP5nz8&=e? zG^}6ne7QC(>deVF*)J>w%jBSBJ|S9kbT^R+Zt!h8N4($-jWFW$LrE+t9@};BZYEcD zCn$NGrHHo|-iUo?#zpiKPHI>gPrmW&@477>m1yQw2_-BrSViKZe7QXEGRG&`2^d0C z2cV|s%k+n0Xx-90jup4Ix(399>FQRDx_43^(KnACeJMZk*}tuYJKTL}*SN&AF2wFz8uzGuS_E%BCvEcfich2gd->cx`g zg7Jv62(!VL3W3hez>%eCFQy*zQ2{`nM2HCPzd6|bKQnJIENk&|!CY5al4~FbWw|!{ zkdA=vtNpr%6+Splh=qH?P(aDS6%E-zL|JdCp1( zy2~_GhIoqq;_<>j6O>@uVX_hK@Fj3J7caVz&F69mVLHcK_VJYKkoK*+pNhl|{CN8( zgeRjj#S>rbFgMV2rddAuK{wNc{LfdIYuFUA@)A$((2tkV?)ks!x1E;eOB>=(vZUqw zRi>fip%=t6GwtiT6i%hY@n)9=viGWbZ{7sG34ZnY6_WUKCe9a8u1l@DtjpCK(MRFs z;8e-6f4uJb7bP53tIywCAfZ1$4t~EJy!=DGo9&|l84B@xY@dK*4IY*KC3EjUW(|2 zWL0z3==vb7^j2O_q;v75GNtf^Q$UCo75-TWIt#EA&t z^!Hst&OyXjdc7`ASkc;VoY#LI>+317_O#Nbs5N5>L}%(TgxAknr~XTzF6BY)igfbCjYv@;80Beb;=) z#ciWW!O^0x-8cK1pn9Fa+qmpZVh*FrR1Vd>0RObmGPn%;m4Wn_paioF(}t{1uOv=1 zH$t|FV)L@8X!VrU^LDjbW5n>HoqR9;QG{(!6oDw_&PO5!#DlIEj->OliT4*cCpw($ z>fy3DR#91fPl}|X-+yHv&*%fbnB==766D*_s1j=Wh4MczYAn}-ZZl!GJco}m_t)+{ zdQVfl^;o=6_RYt8750TPJ;Mfa$#gq!p(Jib?vqwu;ojK;GlF^CKl#I{H^9Jo2VCSCJ>td6gDVT5Qo;R0nOkP@*ZL<2;r*~C`O(f#4YRnm zCwbYqo|-Pu1t94U(IrYk+zsnYC5G3g=17qyMIvSI@Z74ul7*U<{OgUUG2iJd^OxVW z{~DnvV94HvtP+tk<`LVfD)+OGN>h-?`YX;l-Xx6&2g7{MQU7|c%@50Wlb@AWZ?OuU z=>ZIpum@ylggV@lGk|eUaGu683wAG2`}t{+D6`ObB}ss8cAtM6r@9d*Tp>&hRA+^-wstadNK}XVW!+#Gifm z)ym6xUTnmZ7W}#STe_4ew)c!Nm+!(cBi!;19J{%1AW+GOP-p$0 zkZlb{&Llz2ZzHR+UXCYMr9V1YGCADx0yt7}%^WabB%1m|xA&IUms$oV4+u+SNVA97NG=N)^hdKxYPz`@Uew>NVhx)RcGD>%B{07s@$cJLyrQQI@)$lZu^;f;JkEk z#J?=^u|xP6{Ndob%3h1eBBzc|35s1rYyd%hQZwK94Nkx{w=737WIiA@K_E}+;;f^c0^*4#>ktxZq z+_ROAZlCqvT29)pYVBL+z}FkgQy1a0DajdT5h0zkm$vCo-M}1dd%D(`6yxsC>|EGp zZrgLKWE0iL6<2&$c|M%p}GFE%aEON7|1D+NPvd zteZW7b3;nwNkwh)?*X$!s*)ep*JeD8#U5O}zFPvZUfdO9H&0n?nQJ2(>xhGg49vF0 zNfx|h3|?1Y@)C#a)z0w^B;Rk@hdGi}Obts~e^ylTE!(m&q_o(_VX@h+R3RG!VX7z`Hz{K;LIrgDI0JTffWkQ?LuYQ7&OsS;A?f3U*NznRP zj=JeGOO1NCPAP!Q!|{J`%r>YDHvuufEJQm`>zMJqEQf>Y*jzY==-zdFG5U@&!K&ho z*Lyk9v+Bn=wVD1eo3-4Qg8@S`3HtvQCv1OE^@0Wkl&jO{Okz7Ka%!hy*twcfd=4*N zS0a-m;?yGS7oggG#{oif^CK1Ci!2Px#M+>`Mu@m{?(Xnke>`-1$GH#L*4bG}XFlk? zG{Z@_0FJ;_V!3dH@%yT+(yF#it$yixfwb9Lr;$;s=jwkNvrX;7H3#h(U(9wS=(Z{H zDJrVLgk=-E%DQ0+dILML3ihal1t7@eC{{)vxM-V|b>~v}F4cTItjzPYU!3VGm1~+# zBE;sYKzY_3b61adEF^j-&Zc_a@Jj_zqIvW*TzL2$OW(lTFd|FiFM;#w>D!_wOMzXu zc#|uu3?|rq9B7@O7vbzRx%Trno@W{(%pzn4W%+6d>etHEm&a@0l-Cw(`r-RE?e z0UBh9`n=D(P57jGl%^`Q-Dy@;vz$)xuOc?(xhz1ZUC^yQop@kUIH*SaN~b(a>%FIR zuM=so1=2m{eF%57oZqpIwA*YaTT8e6!??v!Y7gZL0mYJ zaAGZ-7<+qTn`DKa(^+R;YyvMDlwtRBg1rjCN>_h7_WsJ~SFW>ufd}6|BUXSoeT7O6 zDBxmQFFAV;&if$*SC|zWb~NtjdW_2IfpM7_XTk@82eqDp1+`I+q&MU>*sSnX2S%g} z%Tj(VlRCesA{@|KvbFw+kWig0wTkG0a@=%1G_(gK#b6s{InBs)(XY-$Jy?ceISR_? zU&{PPy;*rro8?`AH3fUF`$DhnbmAI|7AJsC))icezIWzmK}EdX)v<&`(aW;TsqJs^ zynZOtZ3gsQNw6=vCZYB+v3%~Dz}pE|8e^L(Wz!Id$BS% zHB`V%tBSjC)yCesTG7m*Pb@6$X4|~2;`c__+?$hamm8DbK!*};E$5mGbv&tKocJGD zuC%Huc$n0_SKZ7Xe61uD33`eAQPGEuHbLrxU>B<|Txvp;>o@rh=PZ(-;U-VX_KkElfUff(Z-jH8y z7+z5xc6T<{G~S#TdQe^!M&8gE@l<=8?4*S^y2kH8-GCvwEcRQbUDq$ZmuY(JA9!GB zQlmuNIVjwvVdoR?NM_tk+0MapzXb#!eVk9oxVGhO=6_~d(o-G)s5*pb{l&NP8$X3@ z41@9J%^qXkycB-UrTrJLp1Z?|3?r!pJgw{s z+UjvGth5l(E_tFTSW48SDCqvh+@iyI;7oEWml>0Mj;@F21}$kYipCgDJG3L5Cx@&a zTZ+_BE`0Zyd-Y1_I4Xdc;ADUxG3CVTW7*hTE6BI1A2Y&`G!j!I9P>DAKjTQV(8_Vz z*5Uu~^o`M#ZC%sdNk<)aY}>YN`^2`*j%{^p+g8U;PHfwD^5x$9yx$mS?0@^uTJy|R zRjX!g`S>~lIp(Z!y9yq*bIkKbbBMBOee%m<1R9NVSS8GbVnnefQcPSqQdXto9U?tX zHcj!}KGn|24#>?3&R4(Scs1Ze8yoy!Sa8{6e&ZzUzZ`JMsG*kt6CMyS2@J0+1Pz)| zePpazWYTE{@6S?!v%K-!*(`SN8_s&4tHo;}4YMQ$pZQM&>iu9y1FMZX=iw?~QOiBA zA>X-bYd6*HIZl~}KyCtOjX;^gFxr^5n*u_D+-kpy;MP%lU?tPSHxz9lr99WDs2Iwr zSAA$uvGGu4CNEYknpr9$8R$^L223bv!rk>RXiTrCN1c;`at8M|>y?8Lxpq}a{LLKG zw2XH~(Je20w=ig4PdE4KvEfU>4$zye!M*;#;CzB;I%Bgeyby&;KtxFXiCQ`N`C9$y zTY2jHeBvt#&-;S#&X)b|jea(QrY&dd1uQ?F>U!3{xdKdiQFY#>p#jx=Zz@^aeDAM) z%a?jDAOD=$nI_5N#E}wd5qf7!zsz=|9NoKgiWYCON0PwnOSoF%vv{O`UGtXRie2}D z8U*xDR53Y9X~q1Bx@xv{W*Qp5zaf9puX*++irMfPuufjYB#&Ak`vsw&nz=^9`T9?9 zVb>e3O~yvL79dHPLG5=_FU6ygHNQ3;kgF0mqmnYCH+&`;fQ8LS$SpQ{)Nx#buw!uh zXX4`P2ghNcv5IGApaoXEr%1o@8=rTGass5-b~Ew7MM=PMY`!F^mAK=)hi3tMGdr~m zHk`n{w2mS)tPd+l9wM<*171Emeng>9MjYQTC}nYBMV>?(kY>puZLQ1L(tKlrO|?l` z1*z$`paY1j*a{QY26uN@SUr$nYppWBw{zyH(jvhr^s|M!C7J1T9}n2l>&eQ!NCyo3Cs9n{t<}h3`CR#54E2mp-9fmgs>Z3^U$N1=5UN837ypz{%i6ZB@G z;Eel2tRk=1Sv>*%Ry^At$_ldn+u}igV7}!Jgq%T=y-N+d#b#^O;p?TFBpe)SQ%e>U z*D{+u^oz)*8c&0}tuof!CIkKhP6$6Te2}$y60_((z*mV%iO&?wY`jca=J*LqcaW?~ zG7lvm!$Jvbqan6>vLLxHvYsmw$DC){Mk$iOmX#F&+9g$pfT5Rz=^7L2`-+jafUIs6 zrsb`0Apu5t84pCrq3SU?A5w)!wWf~vpEgRXnPGAyRFKwS_SpPFt6GPT<$!#kN4o$_ z$&<=9KBOcwL<8`Ky7wriYNuOnLI6U@SP5#&s&r8|ACS^4kg?|3nT?~)X#BA^i3F#c} z`d63V`kfcm*yPa!1sFO( z&}`C#sI5c!kELV7vQUZKA)$0T zm#$rMM6q<^+VYZ!4Crwcp{p%)YRnXHH|UjGAVkKU3#hd3X2)1geb+ocwyB^Q%Y{Xe zwvd~C(F{9gQQ_KQ=}Z+bbHsz+ECLg)D5MsaFaP3W7;8u^)nme~qvVFW-p<{b=~Q`} zmqmPEGp)?F1y8w^0T016uM?W)PE4kDg5cyevdANL8_5(LZ;djP_B^GIF8=XRbt6d4 zs71)E6m^}}qB_ZNNY0E|%{BxYr9;BF=~-7iwr z-?8@!Yjh7tTpzK6g}S*XI&}!0>Eeqi{;OGk>>(F3spQd?W_YFWfD-N!enU^*CmB(0 z)i*PF!%AEe5^k-PJal4$hK@Y{S7p^wx>2To-^5?C5%p{~gC2l6$JPxnS5O3dNV_JT zFgpM&1z!!sMZL~%(ZyM(j;Y^Xj|uSR5S5IJeuk@BPY< zNyDQNWuh)V?3&7mB$+x0=mube^k#Fad~!j$C!~2owfGC>#(EXae*>LOlh+-edUp4Tzt+j!d^!h z@le#}NdyJz3t~_39?;ps%`0DUPr2Yn#cUYQ$-+a_?${eOLH;aI-sN%aF~|mc7a&iAp zHhk<;&yNvAg=;+&C@jb$k!SvJT+83y=={cd3Taa#4(XCG>i@fC$^nh8DGwg^(dW+F zEV$;VBk9|J+4k_R^x>G&`hIa<6hM!MY3ilueR5}JR*oi+sz5tdSb$<|c1*;O;8ey2 zG!zV&=BZyMn9HvWQ+G(>h)dLUT|a2Zwh zX&fP-{ahV1HNxi(O{~rKN>4l(g4cwFv#{qt;3MHiIIqUa681u`iV35C8TF2K>9DdHjuLV^85jkxy)Ga z!+ICvotJXy4UdF-dI!U3h84c}Gb^@T-1Gv5k+6KatR-1;7rUF7%{&_lXTBzek}t$X zHa-G0VPEts6(UNkvtZoUmQ!ZCz54jF*U!SecZ#|%-eq|`5cd-pJGaUX8+@`qJ`P2W zq(9G1KX`af>x!FQQ?kB__UR%!W@jb!@!RJ?wNFfz{jt*VV%AIW!-wzF8y@f-o)7;_ zn~0oh`a=W!gRx>B)ObH_HMh+VRPc@dmj@T>3k<=}>Sy;&!l1jp08MTGrQXsHd}R=a z{s)xjl0fS_65MLVSa;gh<8zZh#V_Si@^R}nm|CU;dj?+<3;N#`tuZzO6?u*@Y6aw7 z=Th>12!M)H3_0h0Ii~)(f%cGy69UDVVySc0t`KZC6*$I+e=xxR-#sC=4*1ycKyEGT z5O4r#PC>vpk)FG)YDG>efFH^||2@Sy0i18i@dTvH^_-7mO&;TGn1Oj24360iI!#J! zq4VIRQ6;9wu={3Bb%JJ?op7`UQp+;{AK0P)?4=flUCWvkgrB^hk2 z?t&@l!=#fpmqi=gH~69U1VSKZhBv)FT0eaVTueFJ%3Xazap5tLJ#2WBc)_SPpGj+= z1TG4$(wn|Dgv1!~>2^~vxv#V1LSAXn&;p`pnt%{jv~9$0g@-#aF{H`u4h|7qen4Z8 z1hd$a{zUGKexajgFAzMs?`9_@MtT}+xQ)#`%8IyMHYZFq66PO_w)KtPm_E&n9i1Ok znwMP|H0(kRjGmkq+4zIkHy>mdIZ-7NvYKdYAT z%FbYm6;Yr^R+Q`Gjlh)88(40>fud}@C#b}AWF>{L79yuvy=QY&&t?n}v-`!w^ z;w5p6@|cirnhpjVo;A!3L0E$+;c0z%00=_r=3^J3;cBzX#J!QetN9+$EO^YHhz9pT zr&kWie@&ZuG5i6by!6P1JSa{%BaTzM$*hUsv@1DiBZ|G+EBZJGKr4-8bgwVR4S4Z? z%tl~~WUSE#<&d4r92k8?8>h@ewFA-Q@M%JQU5Z&+!#;px8yaacZuXNW$!H_3s;DF` zHJ=6{UwNqhnb=2SW;!*_b9v^KTvdU!v>}KY4s?XwXkv6&0HP8IqrQ`qe6N6xy+LIC z{3_WXQ(ynHw`XFiV6@)jP^Z$eWl7K zlv<;iM*u;3?>Ed3Ai(F=Rdj^?Wh#1-*2TN)&98da?N6u)G7yjDibRqrNl|QP_qf{E z!Pk37H#>*2Vb9e_jQwIEXr@lF{V`H}KbQPXcC@ymW5Gxs8(0|u-zfpz>0KtJdpg)B zIn~;O|1KGv2n4w$ODb1A{{6=(L0{Y6sj2Q29pfKN){7dT$}^KA2lw=q(V&J!6_bqj z(<8wEFhW}zQsPsC^i+z0K8VlwUnxUAB$(UsNQhi2V^x(nyx#`z3|ai#5GS|XSoo0e zb4ca586~OXaBRFlNYNA>==ia(h+(n^Hi}SLfGw)UVj32pDW#!*UfA}){!WrU58hL* z*LiOii!$~AX1=Ew>Wp$O<$bXS?5boMRY{3(S;>8bkZL$bwMD~+EYoOePFtLt88i3K zIztE8&_7LR((_2P9@uD*Z`+hSCu9aC$_2x|`KaJTgILurJ6Ayttv7aZAfp;rTU@^R ziDdI9I#gCkpA`R6SejX_h74(h^U-)Q?i@b)tqN`!bs?X^-XFAakz}3`;&l*<-IUjy zlq)A|;h>6Pp~49c`cFaC?B_@%VM7qO;wF!M4V_~K5aBEk+m5OOs#=oPc$#wT1hjpG zH~uG2^!fyR$k3Ub5ab+(G?);2GTDk-Rh8O^pggVxV^QU&Hn2KBlo)x$i%pl>o;AAP zGCv2?-d6&$-n60w0$SP_DXg<`NcDKM^DLfM$x-W@tP<|FtP!mFoC@X?+CUk6qlPW3 z*aL8`PxdRBTkgOTJg;`gEb3siCL0D+Pb^kAQk|CxPMt5`-HEO6_$o=Es0tFX>fqd{ zT9c>yR@z*Yn?%Ymoep|`xu$(KIWy3R@+4qYgDx1}5Mdi(vu^4|m++c9F@)H@nWalJ zY7w^2Y;hJfcvxCdJnISY#^iKkk<2?zjD)w((K+9{jADosZ5M;j3P!hk;#u68cgIDI zxCn&|zX-`tC%iVxT?^Mc-8C_F&V@O5lGkM7jh@gV&CaZ;^-mM+?y9l9ukI4+bJskvi4Ov-1y2+FkhMPKA@BwNhw!wZXjY^cW6ft93_1 z*hah_V~04k^^vY!l6;d{?>!=Gra5R5?Pr`>15b;p+v-gX6E;*&z`8Xor=M~Tpfi~z z_ys^NAc@;WEil#G)fq7uHMzq^WCR|BGqIqWA67yO?p!MKaKgZCx8pyNA#vUW?H?Ge zwtD(T)Siv?0>M#9;3Vz*qmnz61Z=K=W!C88XepJGZO8u z7a)M+u6ogK$$>iw_pXSxn3CugpX*3pLd+d42GQ8U7cUfmFGbeIYZj1;zINQd^@Z>M zS$%f)J0@OZ3U})BSqc<&;haN{7%~Y#H8yQbQ}GwIbJAkq z3q`x)O$pW1DXC>5y@x^hxu)m}Ul~U6Z0NN#L=FCVmHtLK!NN;2#ffmv#{=cvMc$HS z@Ez6D+)l$l1-i-xBb)#QS^-_;o97H5WXoS-m4$jj@&GsotR|kWK_iD&r`1*~fZD2T zp+DE-VGCXog>e(2QCa(#&1Wk3>I04&6=zgd@l3mJ=zYRkFm++*-Te`)p;J*#u8}Jy zkE{kRQ1Xlut5Lz|27d|P_Ew&*eSaY)OX0&G9T|#dJeGwbK(yP_aS>l_ZyEMn3(8@$ z+@e+-*_!C;i{6>KPP0sn6NzE{Qs8vtz%}f>B4TbfxYdM!L#tu;35~j%4ol>$ua){WqU|pdf%#4zx_1Iv#)QI zUo8$XHDa?|0O}VO&KBct5wEhJ$Jf{jwUl^1<=)WEl={Zl55?7BxQzPW!GL~dEG z)R_4zvZ}89w}pS;`k-EAi~zR{McCCll#r1AB6E&a-nOOJwgOZNAU*@LRW19+aq{x`-JwFn>U44)0d*OE5o zv>amdS3_~t(VWgo>D^9BC`^q958zW8UV$J)MFWHcZqJTwa6G4!Z7OExc6g67=D~Mk zOs^06`bY_Grl)EDsL2JnzcC!wX9w(@w#!`-12V z734!R%F|;IO5$`-zRdVZ*CV=9zmo!~{d7|&6*YON+bg~lE|mmT;`+^gz5f(0d`Qkw zTT}_8js(EMeQTd^!Nmp*Xc{Y8g5^@$S*(ukM1^wcEFz#FpOFYDYAhd9EYl%5q->re zQIZv& zJG~5yQLi?>@r0=wGA>0JeyQl+DGVGSoq8f(bNjT95<g-{uK$^pEv*tu)MV84@ZxU!%8QY)JX!84%MI#AeS< z==!SB)!s(G;m5?@trlG7jJVM8WGm95>Q^)wx%qnBkJ8_&-F4JsZOz(o&8o*t+lPhk zDqW1he_^_6nu@2EZz^|m{5C6`cZtq*`$QIX_{E}&9&CeE3hK}iV<}jmPsch)VP!np zj@p?~SHC~dr(V%3X7SBCaL1cxcxx`$%lU|xcA~-ldYpxmbBA-2ct?CbsFGa(aviB0 zh6y#nTIqYZ^N!T*aJJh8o()q==gk26+ALF5pG9eIX^h9KF3?*4MOrmMPB`tXC?{J1 z{0(npeYpa}z#)h~Ka8eXX57Awu2b^}e`ug!K1sHx=r3Q1$EcZ7bpKDi!G|=v>J1-J z3f^;)ZYXj#u~wSbToX;lmr&EK(e|eLLp34M`Vi$Ab#E+7GYqUy_{ig-jV~xHtE)`sN()wb(-K*8d}Z zQvAC*){OW=f6es5jKo_;ba`{%00pupF}mWCwo)*H~2fbf-NZ3gKR z-*_?ER_Au(i$7yC#`F5-7OE5SOBY_DpRl@6I#rTdu<~VVu&o*0-ndb8PRp80HHW!|t_Uoqtd2L4-F0+kz`Xq?IrB3pkHAAOy#NQin-NvCc5x>drT^Wxj>s zWC$U&rlQ3_TxD*Op?c#EouV_$?IE1-nMe$uoBphP=|PEfK+b|C5Im%+%g?Gxs(LRZ z?Zmp*OUJI~zV&4Ka`-O$RR))5xd*A7qT*v9))lHIoW^x4ik{G8#vSCSCeSkBBCCP3 z<}(lL;)cMaCp}3t<8?tv;o|SuF2z4Wx#kOUy=`5 z7sN;7$r4nRN)|*v7FHO-vWJOZ}t}X)09GFe-7VnLngXB3+*(HJ3-O==sVI zN_sv|)-JlXGhw&ctQTt8kbFvF6#hwQ}1deGMH6kYaP^mG&0x&C8lb!HWjh6anO^(5>Pmg>gD`$8I z79Xk2sf)W%!g=&=&J~a7Q9ZVd*guBW!FdQhhnZ-6Ufo29lJ{a$%&snmXlXzJ;#$SI z?Ot5TR?2(DgbDF#-XAqB4Gx)#Uuj5RaDIub!LN)31z4ou00)7I=iAtOqn zrFR`G`(br6O487BVju|~vkA_0Xby$a<+!t(lMPGN(y|;6O35^d5vsiT{O8$3M45#1 zrkwH0{09qfW&l7~^J?@)$3CAz@VL#!8wrU~tuzlRv10QI#ILPsFoDEy2~}W=13m`L zS%=9Tir+EwsR$K$fB70;U)x&b&m->JE!Aq^RhZ5gw|7n9#jt z92K(JSue8N?RH%AYP_!NxPfB$Us`M@ez)q~m|2PRg)V-&k8(_|Q@arS8!4Y7a8a9G zg@N^ORvNb3g4yb4n1#KNP|BEh2Q`tbtmbiK+Ph09azeENS*DaeZE?lg?YK*##8`(x z6;JyvafJT@k>23n;ARddNmPF&afG`B3QZ|x1#t&r-s{(;ZDmoeX5;`F0hrEpJdwUWrnk!?87FMyaTcUlcPKLOEVp477~TH!i+6q_XnikzbPo1rCRC>h2LqvEM~ zPwM*M!aLb^Ecutbfr#pqqhX`)8c9VmpP*zQk`XKdxsuTpxHo41B04`4P2IZ#TM_YT z!#Tt)`2M|E4&nUl!*-QjR1Bh<(hQko6|!=IKgvVZs34=Ly}UvR&X8dGJLSd3YFx07 zqK;?1>T%A(QO+`VZ~hc}(SSHv{a`X%Z~)^@8`3HAmurdMwpE6_5?GnA&$wni=RhNk z`#-!=I1E+5D!zv#nzxPL!zC`f_`@kjm$q0xs5J8hr%7OvbG9AoSzS^W#_WH)(*wF0 zlJZQ>;L4}<1$OhQSf!E1!pzNiQi$EHeYo0XANMbur{W$D- z;!lwKpF;C2CO9JfxmZWUj&AEo2x*MN zLcF*xWtWNka@;{yIMir&%Ux$yz~#*+e^4_W7D#Gfa7bC-EAvYR#87z5Zb2y@J%y&_Ce@ zGo`|UF>;)C7ct+P^*H0=L+aeF!zJI$2hr#iwdYgWph}R^I-}l$@~7H-Y(W89C~&b! z3M}ou@b1}rG8_fUGNmq`AeP>8s%$OZ>>bnhU`v1|PXu%&^B#X8OV*nrZUEoc-FVFl z?oyvdN4Bt&g;+>bT_)SA!N|>Bul!vJ4#s@(hCXFscDPxHfX_*9rDb3H84S37h-XZ#&;g;%qndgi6oIC$Zp%d-()DHbuM8J{f4C>`EJm2I!uL z8IP zOO|2=V$>yXceEQE#Kbl<-F5#lj?zH@a{y=BqE z3aEy~p49Fu_l(S#n!7E}S(=wMC{3R`7xA9h-l zy}g)rL>z>l_$vT8c|74g+xAjDIalkT>m`eOV=d7a^LJ8)WkeQt4v|Srh#dN50;ynG zOX}Rh-V|2XvBXh=1Rp;YQb0C}_R1A&<7bEdgM?aG^*1fyNp2ac;ZFsY>Y2l-3I`6O ztoJ2dsBD^)PRe0xF>^J=N-fGS`Aw>@X-?(%w-N2|k~7&V?&vxA>)I&G-?&h{>!&@r94hbHY=1dL)KX0`Q`c(%|I4hl_K{nny=7P zU@mDiYxE$ZVW;^;mUcaeb&-+6%;+lv6So}nfm*#ww6@Q>68Vyq&r@b~bGL$OFQ@s5 z#$2sl=Gzt5=2E4hT+u#%M8Y}?$9qc?^B)A5%b~ucprTwGY=Fs2toM-*dVR7cg^)B> zTXQn0WzT{Q9NX0E7*!q(^iO7Il9Mpda&waHU=zQBz}W|(qRE$vC&~5iHz|xi_9{)* zkg~u0Ep$>#>tpEUL~$+_Om3A*BPewwtCGiG9%7(D;ru8XVKz+~uZ)l66TY3p?S=Z= zPebaD9#HtE?&goH_BrL2Te|Mxf5qKD!KX5;!LF1er0(hAjLBk@5f$0oT{v}Y^*WSA+) zC$YiMhWEvEKodTN@ZGAn{>YA|$QI9_=GEC-l!(#XuSh2f=p?8Zq!)yM96^RpMvU2M z-_XcVa9w^Znu6OUR%{cGNq`>R)|C%910+bVXq2))KLOUFLmB&qN>a73ZiY$9qlB5H z<7O_*J*~FYn{#%U2D_tnAQ35x(>`iUh!S&r(no4=Yg`ijhQ1W|HAL?M5{kP3$YV#U zAXTLBE-CA5%eCYdFI1~=3slO(u&ClG9AZ-YPYSBp^shv`zVY3eoqEh|t!=Vh8kX@i z?RB~--{YxWeq-CO4WSv^B*b`Rq+R}QG5}{iA#j^wZ{B2X=5BH<8FVF3o=0KtrKE(1m(DZB@`Gy9`HVV^ zdF{jq9*>?J(+k-)7rd+u8w0M`{(1hdzViGMH8K?{8&4Bi@7@V znDD@z+3E1euMl)`xa5s?P|d5?ED3fRLM$&*yQ?U*e$+%2oi`(riB*2=g`fUX*~qjDJBeR&(nqGYD? zZT7FR2*j@@m7P#e{HuVzlkb}ndBpADPph)kwYE=wA?5g6ukQ^_KHG=Sw<_F@Nj zhjt0|zL;iU`X?zawfRF1nEQ;6k^8h1ExYYVp0R&QgLOoey*d@7Kga5V1b7Iv<)bR? zo4D(;3_O}e+d%sArwQ$myozh6<#qLKuw8d;OeP_1(xE+#)6TXYNE>%ZtN*dp4T3FA z(>!&Vi1Dh9Bo(SxbTB6Fp6FjWT*&zCI4uzU7G2dl=fyE@xtG?OnG?ePm?RqgbGy(~Jd6G}e*>JxTA^RyCjjV*iC4pe{om7pM6 z1d4}YXz(fGxv$Y$EbydwZ^LBOtb$$RNspIKs%MzPI5&B|AcTgOS)Uq8eH#% zAm(yZb7G-dB@vf!J>17%x)rj<6ovIhyffK@JLH8knXN>C%Zzqd#|Q)Eo+w7{T{sC< zC?!Q#matO8zY+>0+1=w*=#tDF=GBNUv2FnV3xdC__~@gad*zw2wDlB8DX3RJ7DzS6 z^kgjJoc>ZK6R4Gx%Q&Q+wf+IQmRa9}O_eU5m)5mtu$l=RQ6fE%&@{!7I;dnq=D^zuvKkPeX&pC!CPjDg$`{UqGG_T5@nM(HB+A^q z`8lPBin?;UGbB0cV?fisV#cMh3Zgl8pDZ1mA_PIDt8O~^8v41?6{rI@f;nwi`Mk zEkMY_0^J_`VTQ+tH0kG77a%eG(>Qlz{%FZ^r*}GC_99u_wn98mAWG#>7x@#+)wl<>lmg4<6Y~byA9RDhU!HsjnMgWUXl^V&Dy8h(VA)!dGXijy*f8Bi zI~KIxqSd*KWyvhL5C!~`E%Kum_vWY%e&*eEQx=}jjj!<($vx!RB7l<_avr=B(sGO3 zxZ;YWd&RG&A!_Bcp&j4}q=+%Ul;zp|`lcUnq`_h(1^>?hNr;>SL{RH@oT2^tkL@zn z?W47mM&mvIG6te{95O6MHS-D~kMc?ka{)rwQ(XhB)PO#~fLo28ODG(xq*~TB;G5=9 zO`66=f7O zhQc@O=JP5=bVwPhdexva&-(3VTXtM*%9xG^BugXp3l3HWk;a?>727`)=Zd&GrZOQ~ zkRtYZL1Uv&Y>66WO}9C!LLD0aG$#nJJY*{Z2mIpmNSE%Hp6@itFq?Iau~;vpF4;LO z8vV1+M!z7wyK^W@GRsngiv>?HkB0@&pTV+zYsev{QZtYKr9Jji>V4Fh+Mt@eP$pBP zPehDG1ahP5nEBhroT!c_t`k2Esu=6p+_|ZMio!=?7$H<{<-&TJrdxVRv`USNh|rTo z<;BwdE1kuMsyc4MfdFtK>_S2m4YNbEi@B_5LG&N%et>Pj2mo)?lEqTKwR6ZZg|#W< zc}w|?1Js2BiQ`qg%bTFgJ5Md3H8%x1slupR9;VUPu=Gx={zd+^T`(#r`T3_F#P~vO ze4Tkjs$cI&yifN?Y{M!k-Fp>4|i3t7=#pAyG}4tJJY$fAtR2u z)yT|_i!5duQ#^lFIbP=DEm%eL^I^YaByFRDPC;Y6w`gFdNRHRgQ6-6IGi{_vZ6T%o z0g2;9i1p-od`uZ@76&z1f(w%@#i-Geqi9nRd@Ayqtvv!~EZbK}&`-03RIIAHkEz^o$-y6{TT&@_& zMbe;%^R4;J0T=m;1${i}Jp7K%SOwK$9+eTvN9CdcA7&zCUWkvy=rB)-)kFYj!H%z8 zNR5>l#?7-&HFM8({!!z_f^(X?XfY*fM{;4J!~c@MguTPMyoDmMX+oHE{SH2j|d z^o(Evs}b{}V}HnLMdJ{7e5kdwQA~7w*+AlM8iL#Qnf3583Gfj%)wWw6-K=6cuGDlq z9Eeql1KoW#4$d2J{yD{MO}v%4WzJb=1JTh)`Zx23+p0f{Z7n?$jY^=BB85#^^q*L=sa0gCPGire(shUQd>DtGto+=y~0Wv|o?<)0N)8M@^ckC|X}Fo5y9 zBph1xZzeIEsGe|51M>9kD5}6;6?xJJ23O}ARPGC^VOn=so&c%XSA8EBE%>#%LIOxt zalYWC4^GsO#(xkttiVNysYtLHcZn{HN;{aJjeXAT7`_%-9#=t9@3{MuhS15m)NO2p ze4q9yvDE=%p&w0L*X4v^{NcCh4&Ti~{E$#!hV8m>Z4-y-cquE^`BkLz(U0S!J;v?P z{`V&yiz+E9XjS9;6CkRd5$>L#dZMq!(OGO%d6KM@PQ8GXlA@6jh8d1nsS4*xA8Z>q|+iU3_6h%nxw}_iv2rOh-z0b+f|8@32{iZga^i+{Ee8p zB`e?XG)`=tvm3mMG?}I4Pl#XEa2<(xtr3sXF$ZZG4)blP#Z5YeT;&#nY)M8k?I*|h zDjbivBVqZLJi<6jOuR+*4FiR!UCz4h~dFbm~>=}0Hg6nC| zV-tP^3JiND>s}!kv%X~=`}b-}5gTK?VS!r+d`1n|AhR+^!cBuDR(+jaNq$mInGtKa zgal=P9+VC$w)RPj(sPc2rZPLp`pa{v@~__^0c>Rnv-Qz?v&k8LmUtQ}ycBSa8Z2Zn zAnLh@P7+P3+24n!l}@I_k5Se|GzOdqIb1=?8bbA~42PW(~WjYH9pDt3|zT--{CCBS5jHcO_v z7jJLXQry|qS6JhYbe;~6d@{z?^diSuvG`e+AU?JF<8IVz{w^mPWM71|bHmKVvMtmO z%ioIsUdUj-KDk+V_s;AbvuyQ0oDUEhKP#?%>BW0PPMD1h#GcR#mZl7vFNRmTi(<(~ zVW2Bj{M+86aLE!hUsgZXLRwX&GsuIu+6GW;8BI$p#<@n{9ITzI#UKOUB1DzLw5C z+(>Qv-#c#I;8kucOd>owh#qg}L>=9OTTstxTS9no^4$D}=0s0`#KQ#M<FJBSSLv+aVC&Ve_=e?Mo$Do_wgUB)EtTXZ(tKV!k zcZhdIJ^MbX32HTB9GS;i>d>iRL1Ik_@kN?E;d_ejX0r&&vn_Gj>G~!pU~)L2v!JnBLa(Qo*iuoThWHjD_j3rrecMZZ5aOz4 zf$!;j)692@dl#nV>OErh(#&?_F)n82{gIFValJch5e#D1Z5cXy^+U&XLdEH%v=|tc z`Q^R7XumA%e!DY0DoXbirs`c@;C-6zJHPyTtp%WlTcFqey!lb>)BMika)!R{aB6*b zxp|%C_xX8&_woMl_`r3UxA_Ub-{&PjZ`c9)(WcfFSk>`X_wd3{oFPpnn~}qH(bnGi zIeyqJ%;t6Z`o1$%pZ%fiaSWZ+epKh;c@cu^6X@eJW?lIS!S{gXbm(rb8}vK@X8+MTBcYqJ zbUjrUQkueb9Hp?vv259`YCmG~y(M|Mkl{Nr&c44ZK3k|gynn3cWIf$X^H`XxeZBDH zk0bf#gV{$_?WXsSO4-lc-j@&_x*ev*7AiWGiWU%*@@^E(g>MP#K9^56*{%St50bBH z_gd`voNu=tQOb7n_WcZ#^G)u$+OMAJ%E7TYo`$P5^JwAgPJvZsHHz~+UIF+rMlF6S zXbmseHyaN1Iookb^r!N((?s6G{5p>EWqb>}OTsCCi_>DYssWxH=TvkMkjN79R9l{K z``M9Cr05-ru0xtD_i?^jldILG?>O>4_#u>B8T)G0m{EF#;yp5FH0u`VuJ;G|$ z^n0^?>7@<_t*%6#2iVa`L)L$jEpFV(4<wybXv9l&FJ*R;~HRIe?UU(46ir^)yJTzP)k`M4ohoc*BA`IXzh z%Dm}*sD0jB!IeI7v;Mm3W6$-zf!7h>Ke5e1=R0zC)ob(4UHippBQJ9D#bTO#inCoP z*IkA(8<-bJ(Q``4V7nh7e1&^^ciwI%^L4+9Wc9S#>m2~veUu%*SjVJ&*JkVfUVeO1 zUX>$;=iSiR?c9vR@w}IC?0-9HeX09cmI7S&b)Z{!7^4HnO!u)Q{eP;vHGZH=xYQf&C&-G?*Gl=F8IF z?x}+&9+yxzJQYwerZE!-{UB_L`7f(fb@)xH>p2>{hqcQe*wPr&vN_V?ya2yT3rLsBX*TftE{To zBJT5A4h|z*?M9`ao40G0Qz)rWk~1z(@^S};BR+F_YH4#f&8b*{i@rqwni;rxYB6jS zgK&lURDIN{BZAefHXb1cFjzHP8!+ZQ7NF1JDH-qqG#hX=Wj<|0RandZ01WNrjZwe# zdcyfj=25{G8J;hh?BGOO>WKBp;aM<58%_p52KV&~zs-h6eBQ9vvb;%Nyjlt=xZ@I{ ztxf-4U!@+Z2lQ~&mP`!GjJtIWCiUQzMUpg`Th&-6++VQy=@Qmp3O#6&a^}pn5@`>U zTHfP-*Vde+bGCRf@{n{)_+bnCKBj^oUzOa-Ry% zinlJIB}gw^Rc??)agJW7{}%!a*y$}5Nlf+@aw*C4oQ(%$TR7OGY2ES%+^f_K`ZaqD z_d6>RuT}Q?38RJFYcY|;iz2A^Zgs~@BF9zy>{j8l5M#7PN}^2g(%ALg60qQZ^Ww4Z z94m&VlIx!n5+ic+_I=B<)%}A@XP6hght0C{lL+s!dh_ZeWfr4&YNNvWHs&iB;v=m4 zsT}Q6F#qdGn&*wG#rihxZJ6PvFY_<9A5f|Hr@L{$mT&DX0My2oVNdJ`g zG1c98F>h<9?Z(o4i}y)=w(Vv2bMvOPukOv8u8nWD(|hB2y7EP~ugUeT?hB>&^XX>6 zH^-IIm|QX~PuTrT4Y2oN-8bXxV%XxdgZ%(_p1IBLk0d(FP0p{gpt#|20?W$gr57Gz ze={#C{=nwkbkrp~E2aDC**dl9x_H?XZS!?I26!C9(>Q;8k1UT}j9m*L^uzTxD)L=GfnRNHD{D zS^CPm$o_ak{h8dmSmQjO>s~%=i1(`Q@j%B@>6~J_5Z|$_LYGfP+g|WKr`|_o?fp7q zgW+3|@+|hbbvcvix;cAddvda$qO~^4;&olVxzySH|5*A8zb4r4Z55C%0g*;j5Rgz} z^h89Op&*?i-QA25q>&Vm?(T-s-5mo)_lNgRuKS!Tese=k1CXdm z8PJ4A`=!n8RsnE6qRDB78kRwMxi-$?N=Bp-jmi#CAi%=YwE7VIn6}@(>>l9ILmds?W(r@#1|H_ zk00G0?7Kb7V)BP$}V9y0Pb5F{RZ*cLl^QL+2+Az$gV9aZ4dDw|~%98~8;NxE~W4 z4t?hiFVSB@n)OGG1+R>n2?9|`U?t$~AP9PAN{=k5@S@Ul@AQB_U=ra%ca-Wg?lv@* z?oO7k+p5r5EhvM(H{eS;SoW^O-Tp;9n?9`1?Z8;sW~Bv?iWow^tV^QgB2Rlc;h94BkM;4TXErLFroPJfS!1)E+OM3J7Ya zpMROKToyatv^Ci)->;l2m5(f$ZL}i3Ys8wgkzJ$xH7!C!ITqIa$<_SlLhi4IqYad{ zPwWS6EuPf5|KkX(#Z)dm-q>^EqS)9>RXtc|X|L&4rPk$UFJbiF95huP0V$c%U*w4M%2`>-FzaXJT4TyT-&jem9Lz)^ypl(m#*gMHuJif z^Hj6aMeZDy9hECGUwcsWI<_{(Y1yW!IE%T(noeiJnsT!=mCY>+}0kzVTd*)@vNNe_Al~q%nL<^vc?E z?!HpSsj_hK-NEq*c+K~A&J6VPNhysg9@ia_}pC~McZhZhvlHbBnH zRC|qT&JWkk56TCSyAwM!ck9|c5+yzEBZ#@Wz)~so#w~R1|CKaoshO|DPUB>* zVexTjIYiGLWzE+tOoTkwvC9eH38_iHIx;)56@NGa3CN?%<>AFzdCT!j)WO+~Qt9B zM^oW@MWAL#8+r+VPGndbIyRDgf-kL?2R*A2*(JFTJRhsYaeYopSMO zMEm3J=Wepq%_r$O4jzNsKZATWj_f_;W%lZ!c1#R&2PCOLR59m%BGk7^^f)aNT+y<_ z;n}O8|FIn%a$Vom~S)Py$D#k8JNzq}u46M^4@0 z>38(E6aB!&sFsu`Ev60Jg2r8@%d_z?ircFBY+gEOMH-m3wx+GB#UE{D1aqwl% z{{INWnA#JV$PiZnoDOsHmDi;%;iTi^)`?IHxWjKdzqzwo2zpijd|9pXK(s;de6P8= z4_v@2ZeX80f?Bt7?cIr{>ork|XkgI&TMlB%_e5_+<4r%8Qp!soHdO{T6>wW7HX3%$uIP=k!;1nr3n`gt>jM8J6wY3 z@E5qV3Yr;+OFfdz%$aj_RRqXoyR<8tSLLAuQIML%%FgBf%`xhY7{vtyJC7FMJlm;(0sLe2VDR*aYFfz+8++> zEFM|_jy4o}8nx1!41Ojz3n%e$)DNBA*<4nvcWy8z1K0<8pl9pDHsK@ce{QyS(AKXd zS)$9QozXr&n7#IUsq4O?;lvo*UTOnpNiWUArIK>%lT=8^&M^CZq?Wm3SD#Ui_)p=e z_4Pb@cEr**?5__CHWdAycaj?8jGlW&dzcv6tGad@2CQV)PLJI>yXgb-1FdOOuD>`3 zBpHHmy>2Yhk=5fXjf{sUHm?gmfP^c%To}kwx_w6dOM}nHQ!jOr3_Kk$-%FBsHZNbv z!kqPG#&yZ~RNK|~!T0l>{&QD!N<+V(nCA~53w)2 z1nS-53dWFq$H8OBkQ6~}!7tSguh+&NYFIewdWpK?=hoy8>zBl){h5~Yr;v`WA4Mf+Drjxc`&LP`0r!2FKg!!ZiD0QO{IirEL?lU5*JBGX6CE6r z9DLVl&ZCV&*sJTx{YenX^R6^y755&)DN~YClwUSw-S&*r%1g7)2Ye@OL=HGL=)P=; zSgd|oGpAf9m(e=cm-WH!=c|AI*6K%VdZeU$DSMAZV+;h3Vu-z1@4erU;m%8Kaq`3q zK0E6WPJYHlFby0kzvW z_)BJ%2so@39o7MT)@sr#$WnJ1CFx{O@HxO@VOwzw(5?AhH+b4hvU4z6|8t-It|C`6 z&aA4-P`rTn&?=CRMo){sJ#U4G`_DUckW}~YHbw1{nT%H;J(^|HH)^zaF>C`_-8IO1 z(oB;U#%1TS@#ppWe{0OY^k^2xDQ!Rq=bMOwztHsHSg(0}_#kN&^kG_|dG*KiTkH56 z-XUr-nN%KYJ=aV&;>%qAC@Zo=F*vujIdX{6`rdBt(}l+`y0g1oyO_qqRWGj_Tqf@r zS65e0^o~eXRKACoa>2nO2&{eAzbUHZ{exBWv?H*lVd9_jlwAHY`#C_k^-Q25lW+`} z6vdR$mbN1+GWFc#Zg}!`&!fr*!B;ar(RT2L#}X!pI7n*CZ381N=O;x`7Z3a*>cRyz z=a|vj(aLf2oj&V(5~nM1LbTUOi=B~ME2WLOU_#_ z-qAUx!oFKD@MP$oAJULYTp04qwz&j5_3cN)ADBEY{xk(kUyB~Mwp?0EKwTaLG%m4X zad+XHc}cnpsC1XU{g#Jue9v{KjM-JU%Sta*sG?QC-M;x+){51pWxA&oSUB$F{^N-8 z!QR2*AloJiap564HS@lQ!EHsl;driU$7!5+ba%H|M9^5BMGuW!IeEw|bBb=iEk>e< zD}03?z~~ilCIuU^NpB-TMcvs>(<7SW^6?8DfblF7+8LP-*`Y`V`AkvlE!UXYrC8p6 z>KSB96C+i)IJEQa9%%PEUorqA37uCL%_gam^p;kES6budFxISFd%0et=#-Qb_-@N7Lwms@>c_ch%**%ajGUi?iwW!n;;4zwxL zeo9%3WPk^YAqDmSS-lIduXm_=0DqMjJxsihwAmb^tEiU{1JYD0Dhoa1ZR+dEL7ugK z<1Yj557MSI1F7a`#s&Ay_ZiGHO=P9%RPeY^+t!P=-_UXVKnHwVrTHyU0|D2*hNs54#XEc)oj z946XT#k!Iv2Ja%Yt7fG)uF_9r8eF!bX#%rqq5XK-1hPTa4K`!2s<#O{t?7hSPxxG|0Ao(f zhf`9dD9kQw@8kZO^Hi%Sk{GXewqn0|1wEuj zA!_!H_{KB)4O~pTz};7-$4Ye54p5%szq`FZCinbtnanF-S6R`MzuF(@oX@1G>mis! zdkHsdPZ=*5V^M$?h^3AjBN&g~7mSc-+)t^dH$nw{=}5%3^&MGTdCFFFnt#67N(>F7 z80gpuPKC7V^ryG!^p9DeRJ3_Ew6|JJ8n}j3`a0Y(@OqyMcLSki#^^!2jQQt%Z>aTV z7*}tW0PW&Qe-jkl{7UYYm%+C!;D!gEBg`7$7xh07@MeG9+<-kYvMemvRA9yB`8p{c z>>9ebo0jo#Q849{e#S52YK=@jJ~^H%C~@o8jg?_cj&#DjX1{`BQTJ0C{lHR1iRw3_&+6sn(p(>4(#npus!$pYzfJz=B$t6TKL)dCP z7iej3l9NoN6Pw*Y$hqBOHFKHe-pb%!#(H3cYKkS73U=01(%avM)LCZK zioH>(@xK*szSszd9&%PRw))(S{qZ36*g5W-qJ|&@2zWRYN?S`r&S? z0_V$I(R|}VktjGAeX?hMRsTy&w8Le!sRkgWYk%CN>5wIGduia)y(~QKb0uC`;^b@p zBV;ctgi&4RfC+OToEP(`8$wuUQW|0#Who{W%aaW^!9LQDkQ=!O9{vKq>O zhqVy6|MYzOtx4Ghrb(42-%C25-+Tq~DX>>hP4;2peP1JnR@x zb6Zsctav-=j1k+p&kjSI=OOs^096q9$ijx^1$LivpYNkJ>24QWN}nE7s00t zEPL=7u4v8o;oB=JkjQTXpJs(1(V2-j6_rb+F+j>CJiUFi%x!&cOZx+IF?A}XyK~g2 z@Q&#(1IYuD7%(-fq4z#EqmB5(d!GQRaR=d@-;u;Dx~a=)xJ7uyq5NSM$pNc z*num0^R%Fd?y0YiyW{K)!w0gV!8gS>!v( z;9<~-xID((c8zEwi8UoQ%Ewh_N44z%gnjMF5vKW^t@;hxr;hzqoe_$hC@ zX+Q1geAJDxZ`B5Xh^5Y=4@HUm2G#nlfOjy6E-DdvvCh*tmTJ|GJpIS%I8;h# zb#+6Vtf|nuzAE!<0GM;V5pbR0{jJ=GL^le?a+`Z6EcGaU7l8 zvD^ig?ja!sWA8GGSFa?nhvL4;m?wxyiYIG1Q4#M`VU0`Qkjv-^-LP-PDfg=HGjf?l~GXeRH?Bc8C&lNV42rx z@}4^EJ8UjD*2(XGU>tQsT=QyED)}=bN(DRny4~EU=YlR$ z@^{9bF=}L0i9270iq~w4D;`}xV{GrYOf+y?%edjZ$}Q=rQHeONlUDjk?Fb5sST>Gn z&s|m!Ptkwksn9&}#9rMQ=lS;x$&q3ySG>FHsdBKMFHG;iP}kY+AX&{%RZ zM(n{i#(JJk>YeK&s(5aw>#*Mo*NIU6w_uSG*Mh;P2{#)WW*H$?tGN@cMe8Hergo_7 zF(p_|fy933w(MuvRO`#!ERXQ+D&zjW^$;f8{}v1Y4Bx#Kff&YnP>lqEkHg_?KHTjW zv8(ABFh`xcCb5Ks3uLFrHD=N-rJ?7*p5~1h#Jb`c1IoBh;!scAv|Pd?mTvPOA9P`+ z3>Z`Eq*g!L6hNJx<0MW^LkoPWZSrT_UNcYG-Iw_0hX?5z*^|>7Dq!Vh0n@dU=L)C6 zr|1@Mr0ZX&afuQiiqV|tF$uF9RJ8X$U*AKUcltC^`TtvtY_W|=c)5>hnN86d+!2VJ zUra-VQX5$Rw*xu;tGS81wDSo`KfSiHXz0xi=N4nqwk8&Srg+1m=WUk~qC_H|8+10n zB=V1DYPKpkKRwM0xd?}%X;VCrn9qu^-9LPh@6n=z*_)3EAHMTk3{Rh5g*lxZIXRC) zYnx#^eC6$pm_=moxX*e?E%}Tf%aVV@vs58QgRcAxc+~eXk#oh{8=Hn?<8@Nsi#Yhn zpB$NegaY@fje)6Mv8BZDT_Dp#VUm>uY^k;AFq_a6K9<9#JP{4P<-46R!??YH=cY5P zZ-E!5QgCQRGlrY}zz)i$YX>`_O$WzXL11J!+(Z=Fy!8yTYe@FyLwf20ktyOInQr&k zZUOFku7lEL@Ri*l@M#WHk_KsQpkSVIgj>XY$^fuk;iIzP1~w+dbFgpKveBfwe2{f5 zxGUzROcz8g<`r!}r)X6yCTWd*8$Whdq|JH(E@w=JO)!TQ%sB8rbgnLWQzreZlj|^_ zI;k&nL03h4`=f{wBIUh{iUFVUpf8%BZu?RMyd-uaLTBz&Tn}us7yzwa==p~?E|2eMH|&L(=rJW2e`e+R^BKBp^z z^_|jS<|)lK;~o~^cTJxx6-prbxxvl10g3w))hF8a(tgiBmHpBf&cH~v9@LxIq}hg~ zSwyq6JxnqcYS?Lv{&3TPIR>!na?yKkXrrx-;PY-wlWoz(NQL&8C#}OU?x#e{DIkDr zYO=w@ZNuI;@J563h!}W325>!Gh-23Tsy45U;@BY9{2x^qk8bpwGOIE+@|5qcp#OYs zKTox@A+-_U$CX5HVKHUdCcmm_45`}vlV*3?;qUBR^m4EenDzCS9TP~>P=yXe(onfvS`)iZb2u^Asv*ydqr}sN6Ro6cv_-%<8 z-Pbyi2XjoTn1?L*MnLVy?vc#iBnE#MWi;-+%+8^kn#2`kd&Y3HIOu$TSOeCy--_C# z#O`!eop!~QN@>+`fw+X!9n}y;N!rK8qIjFH5F%>fiAp@Lsnhrn18;xRn!mQViBSDE z;_RACgx+#s<$^5L@IlVsZ{Cjt!@6Xy=q&zH?+Gg^-2E-=e007Cm$gB0b&HzyBC{N-^#3SF&Fs-1^f~UyYOsAVrKqS=YUHe>xT5%JrNc21YgUi)IH3=F|w-x=<;c;u83adVSH=aKIq~oZzl(1G-Xv1qNKMB) z?JS;T6bYRh82aM7gjbHS8ks1ujmFZ34%jBcb#Ix)ohOgD_Sw)k!VZQQTDjq`TJclw z4AC;@k#N?xMEycKki}K9T4jqPCaspy;*pU-QT@TwvGgHIzP79Sb8wT~H>JID+hzmv zpGL$oTLG+9-ZRHy$__Hw&AJ&pEXC#9Tzg!K1xy6GDRi;+n+7ahn|4_s>20Szx`?wk ze~7e^4LX-#7qn!+!(Y+X$`MKIHF)BQzwrBr&4{`he?Q42p6Vv08b3fP9C>OF2%;|; z4h}{$^o$Ar2XK&o#9*3=CHp2TBDw)%(=>JIRy5zX2w?nQ!?`V#08TGUgAX(R6^RIM z-_K~)rm!e0aESkjdC`o@9m zrgdg=-+*DT1(&DeM3m~DEdF#P9Ox6Uv{#W}?Hz>U$On_@l~Dk6UoXl^PDf)4pP~X4UTHM=y=S4h2XQ9m3R2ZBMbA_b z>`FxS2OlKQl}GEynqLgiB>|91dD)W6B`H<&@7^i1X_Sh(5y^=_kiIP0-W%bqOHpKIZqobGY>~xt@r#$sgPQqJ~K26fV2LGkL8wAIJ zTs!SS%-P<{F5*W^#=F(kMt?+hs|`}4n;`j-ZO=R4i&91PtJX zJ7-nWTw4(X2slLpkK%XtCuu(oyT-!?Pv54Mx7Jo03I_^Hl=KlB!et=;J{Y5(p zFIJu(Vmr@N@u7qCD<3{cP zeA1FPxuVt9b*TlqTX^fa0%vpHl-8!VsEJkwp&bj)H6M=o6w{K_tFp<^Rap zWTj*_snXDjFHnBkmChX97tZe6g@t)oHg6Z_5g(sBW?k8b3|_tIMiKTJ&Jy2!57v4&5nS)%Hcm22M9tq)eF;xT=U^(6l$^KE0&nwbN@ zVgB%z>PXV!t$?n2+a&E2w)Mr@C}}jrJSI>oaPIU~DV@5`h|rOP z7HSH^?y10V@b+i=|9v`KL*X*!M*AQt_BdhJ&oQFeBeo)R^p_ROUVF=Ryb{5aF(D&L zd|f5=e3h2JF}T2C^8lkQ`zYeJ<)UIvOY3-58rXs@sj0w}qAnxjyB!c?YV02$iVzB) zIrYPZ`l`Lg<=f)i=exyh3%*)!n-Bn@_dTIRH8<59!_Qo*{sN0$Cy(f?cu?Im4^VIY z!%tA{4o4wOTvXIyiIfZtAcwA zV&U*T2EEB&H~GTo6|6hB@|@C(;(HocK2c%RbMU!}PS@c2R7>JqIO`wG&n?_!BUik+ zN>$vzE}s+ry(i&&#%PyC#^f(fJT`{l2Pp4XCPTT#}jw?WJ=p8ZdEGv~L= zmf+Pjr_U?WSaTYpdMkN78~3kjyUF=kxrg&g-b;UXgxGfS7J1n_XY=QID3NjaWUx)% zgLTifq9o(qL>DvN1j_Tte960c8>agF!E}GR8$)J6AAQ~IKHnL89Vf}v-%fzV4p|yT z_255FMoqgXc9oTFpSQ>4`$DY~k+L_X3;qZxt5Uf=j$YLvW4L$VOadjCFtUhnkDEfYytq4RY-$))O5Y0XHODbBF2xd(-E(Pb9igJf1#`bPp6S$18REaf zZ_~Eia`|B^clPS#bnl6zs8vj1>ysvL zmrweq98)ti7mLTdAtfd!Zh1WOo7F*y`Cse2_3V^XM{w@K&NH28~`z6^_9fcwloLGq?pAZU+zzf#1j zLU~v@`o1&w;eOpV7QNk$L1QGSar6;W1)L%rQ_lKJ0NT-1H=n{0Hj^*l@z(yA6QBD7 zb=yi_Q87F}yJqeEV(@o8k3;HJxA#M73*fnyL>_jti-Ndf?Bk#~J+rmne5&m?qlX0s z-HdBtQ(w&lpWf}e%_eWTzPrB89!lxg-hHiA79S_?6%%7r{6+umzpoFf?5j(>$`_WE zQI6!1&;_%j?X)MtJ;O(;cWS@x@Iy+^EjatFFD*-k+;l+cs1Dpt^=Eb%Ek5&tR4Z0l zZ@?gmc=Wls=*qouaB~{MFd^T^p+6}Vv1aR_V)X}*T)lA4=!@hfPxe|`abfiV>D6c* zNd4p>r4~qLCzL4pnb5r~uF##*ztd#jK1-kPF*-v~#9+9N(sHQTy6LuM2wq?3e;AyI zbbdpou5V^vA%KzMKONoVwo&4@EmSahO9$pM*cOo2VF%aNMU)234(Sblq5jJ)7;I_i<5H(fquO?}t)>!hv0 z4tDHi$6ib4IPh3BYV(D0*n89Zej+SJQum|eGv0lxqL%Tm8X9s35J4h{Mb8g=6_K4K(4) ze*Coa#{c64)`U{Dw5%`Bn9%a_j+B>DG+x+H6fB3pIg*CzMOsBR zJ3&KfhZPFN%^YIG!e4(iE`1$Q<4oIN*Veq4Qqk46OsYZ@vuob>7=*)$#BJ!Q`yanO z>2^Ak8YX;Tw{?{g-aELu=+stHGxpaO^>5+M{xTTh)fdwzESUSP!E;A&kGROOAyb zS1_6&#L-htsSyj0d`4rfJv*u2&o;u#MJ0iK&Zo$pVN1n3Ya%F{btv7?-l!+QEaOpU zhu_TiX?r$mTjT^b*UtKsBVm!Q$nuzOZOZ)H=VEuS@vv8VylMJ9318CCks2(=;C!U} zXG0*)Sm_7OeD%Iq$e@$;PGjZwyM9{zSNZ4`t7rRF zJg%*Z3;DsR+Oi656_%NzFd=puVa7Yi=$O|>vk69Y>xso@gII$XAJBhzM~EGu?@vH1rxY2&n5;JY zTlKeYt}10HfLnkkc!%}vC?LgsQ?n;IJAsWK{`9eXfigYlJvYgE2^qevL#a-#2g;`Q z$Z0c|+qar0SdEN;MRv2vMJsCW1u8788qCs9LKXJx2U&DEoyB{L4;n9H1sE-Pf1NhY zQC-b)a0C?7lS$^cW)XMM+$C^RG3cfA`p0qmvgEUk++KLPRS*{Z)~gtM;YxUxpi($y z`4uPNWjMJT8g<27h-Fzv;AcP|5qYxNdDG-j=*9#-ik|*PB;KDC2AaIXQTNX*=yW-Y z0nQQ|!yfnMP5C|I5>UJerUF1tpnhvqd_>J>kMn3~$DElnbhT7%@wWU4oU%lIA0lFm zzD@|e)p|99ckcG68S6>*mqPF{I}lUiF9w9r6dAt` ze*Y2p^AJ0{<7O2n#Jj#mWyP1CF@Xb_976r#TW8$1rVK_66k31g{4Swy& zrJ=2So7{z4-tCn3yaV>W#ec$(S7mb4j>g*L4H+JG;A4pJeA=P=<2%w5G?t>cq2;jK zRB34CAx_KU)w*%8KN!_#VSMu|4;o@;wJgLWQ9w~-w3T}2ffo5$%~ZlvzJ!QY1tuodurgGsZ8Z;MT}zNH}^ z)*Oj?kwnFuE<|6${krH{NXSRIRBeq~*tlns;DvzYYu)R)8u%R&YKzq!LK;HFIgLCG z%s@RuE*k@c&g0`s?^0oRHK2chiI%y&^RZJyONaU)yY2T{m zG^|{|uK|TD*0|Q4^sQ~I%VY%UoHXNN8|_&i9nvWkrHu8^TC%T7Nl!X`)+8k%zR)eq z*OKXpc$(hcSXsQ5_>&jRTFk=mK&-}`77sFcP7FduN}fSDSfV&?9_{BWknOpzef>Va zLHjwul8fk-e_{^H{*Py6I`6195@dBABwXY2@qdOc$y6;be6uzrV%F+Yq7nD=+=jV{ zmyKb6`wlVhKgfk#s}&JT`WqS=zrg#@$oaXPH^A&MEZ}bdVuN|rIhXR8A}*tdVqo_V zHmlKGX`bw8vg0h;|A%MxwkKnB0_?3w_d__@$$Z zI%OqWN7koQZzA@Ogh?$=;jU&E#Mds9YUy4s%$C)q*iZaFs?fyW>$BkfGFr@u*r+h2 z>Sl|N;t{)kDM0>>MHg(@hHrVjUR&v%G;P$t*&+=3$CY6&Z4x;29JQR-K8Et6?swGY zR%(rq-v1?}5BSXcbz>uI1Mg}2%%soKG>d_5Fg&f9x z-NV982!{&MaURWM`zuI(vE=*f2l1yxcm!0;Jf6sYV(+#fjtrRG*U9hxcXmKOi$^HC zvRGJgUNE*Yyx^Tzv3#Vq!=TsYZ(C-C90b))Z?YUt*D#OIESBdZhGD$oCy~LP+q3?q zP@~Ih(Co7t9bR`{Y|va+*Hiu6uGBF1x==?|(8v3xT0KBRY_AU%He#2s|E9|$A42Gd zR#%kSZaV(SOm@NimIlYo=20`DRd64`Tg5pn3!hl^FB7lDBTqMzOb$I@d@$nLL8_48 z6bnRO-s;dSG!9uO^FuNEU045E|2pw@Ik-^Vs62zvEyiJml8e`&iNAQ@+j0jkxd-8( z3PgFC*jbf?U@*|-`r^aqd`dj*fWGxPmNfRe?? zSAAEtPW$heDvu-S0D*q~e8)jDn_igU6jCyv#unQ#Po6bV@_6U zH4a(5ChUBHjfEc_%_lV4FOXF0)4fN045rkkba z+CBfN6jf3pA=U4=keguU2F6NYekhHE!>X>EqVQ#o@*A?;wWn-;_60lc4h&I;)*V4u zKE4g7r6Fx6nNNAB#kE+0S(J4uI_)6_IXo7TR=hE(eLc~ z<<(88bsIV$6}}z;8IZ@xU$-mDnP);3yTLwcXHdU zytzroFSDYdUacexj;0~05Wh}wVM5G@bSz0*8FkiKX#I8XmLU#llYnSwI}a5oI;hlA zgezd2f_kJ$@2d4n&Cf=u;BOsfse><_3{v~{*@0#3#%X%(W<+&F>0YS3XOW#UFfh5| zKVHUq>(w7C?M=6yRuRVK-}v3$%EwGiIqo+So1X|=&}w0-t%`_ z%j!>Op7uH#ELfWe-1Q@UB@^YRq%(!kOpT`|1~UmA7j{qIk1dk=A`dwYp)}KFcQX`G zfy8uxj@(d+GN`Uw)BPpDa6Zjc`>JpYdfbG5*(iEb6008-7bQ-MgqndgtNGzDPK~l4 z{XWJTSN~px#5XsJ6)pnf0GMvv%sC1fcLLt~O6DFDsS#<(V}4JFP?wBmjttvK^}2oD zQYhWbF`zP&(s#N+0+|Hj+F}k2)84?IHee`nZsT@vXc*6XmFrws`vMznDztA%! zZq#%3%O-_6)dunE4;3nJpLlX@iVINM-nWbhuKiE7iGhWj41+mlUwM*NDh8XKYyo5$ zxZo?M&vAhtA4&CThC>+&1WA3;=qu-Z7zk9r;thwKtB_aOyZt+t*I)_Gtut5^d(u)#8KUbZY9_ zpk00eoc=xuw|mG;Lz^}3DuoEj(4sedEoTz^k;ed4jY;_$Y%}UvAm=?f@L-3r!Tc<6 z6$5ReSLd4hPlOorj{te`?MAOc7I(+Y;6!u=Fg!2t54+!;mE_%q{nM^N37~>6FIxV! zg!@2HvYxlmH~IHoL?eLYlfkOJK56@oc@jUpacJFk!$o@DT;cGJ+m8E0s(^9scZzbn z-D%ZN!`~&&N+$aF#{(Tzhu!_Ugjd2Te45-?+Ps*&Um#bVNDnXBm@o(s(WBdV2g$A) z>p9yzI^WSb@oO5Fu#5ahL;}3{*m%&Kx)x6nRcC9gcFBakl=5PU@4Vw_Ce!~1VA9vB zUBJkJoZRk~Ep|wdO{SyTLgr(T(}Rt?vJoRGu0TOFxd{q`DxYeVwJQI61VeR#rkq`u zAFn#C>u4Es86UZ98R6C~Z}vs`Tc{Rv*_Ah?=fX_;oHY|@kSdy&JE@hUg3~&-x)(C9 zE!wKGtvj6MO)LhrIwTjCUC;6X{?meKG1Nt zAuQeZw`YV9APJ=8LbVB}Hz#L>akL0M$%30*mu7fBc?ctR$jIV2q&?jmYSP}8Z%_MI zIN1u;cJ+F5^=?hd9xW9u2{u~(TlFTe@scj$JrtWPNOCdHmB`H7hIDeoJ9CI}J^9rS z+piKJDw;p+G;rd}Pon5e4GEw~R4FBA09j6bGdS=SnvBXLOL~8;fO@u|*Os-$`E3aSi^1Dk7ZtN*YI#Drdu3wr$oM5lX=`_6LqyLL+99j9Wm1N4=hrKe3xM?(q3H&Z~htH zLE`X7D8ZNA*_ohB|0K{`5v*kgUbPN5Vr@^HkXaux)37#H_N0|Rdwb85nD*(@ly}|! zh*1o{<(19E@)Z&M#+044CE6TYa4<7pvhkGdmPTb*7qb02EdO;Bho=_N?|YS2KRgY! zpCDRF%D68?jUQ$tN$pmP8^(6%w32hmX|rAt;S|MayYA`1bCWLfSF!3wDCrKuvnypN z`G=$JCpv#R7Jo`vX0iNJi)d6OOp)Vcea;=V5c-theet(j)s8!<2O=;P>8I-;c03Jt z#XyzEh=DKPi*e^vO4`?IHy7T0PgwjBDmGipta+Fwxm&cRCU5~2NKhG(E7L8U11Dq> zp2_8l``zB07Hy7VR3zu>HThCda(_xLLb&njCF5JN3!318L2co;IB#pAC(T8AuC~9z zHhRyxJ$mRuAxfZ+D9y_3*$_mZsiMTACILxM9w!;mC;Js9H!91?MdE&6f;|@^j)mn&Qdc;SPJV{`1vmvip!`vosKYLz6;4sRr9cNllV4r-552%0< zK^c?N;{_ZyWEU!bV71;jdNz*}Cbb%71os&pMO3NWho!(exx#sQVaA4#(A#u+3Nxjk z!5TK|E;D*TEd6WgTL#g8wOEQkbI%8F)xsPK2ZzV^+4NDv`%?sadEBM*0sRcm@K>Cx z+>gBHmo5+2fjp>WA0TS))%pY$so!Fa>Ec=j>cH`C1mymqz>=mF^5d6}a!O44$66m( z_?p7`6h$f`E+Mh4p57H^L*00X!Y#Wi>?ZLy>JIMQlG_*XcFOP|F@;z2DUOwI>!5BA zKW2@BB?e*QT2}r}ALhHHE0!W-?rD25xR&Z#;$m;p{$3}lmd&1KWXXih-FRDGv+4)c zOs{%DTj~a&z%V z2Wt{By{A`JnrhiRzUxp!a8_`02c>#?ulIUHc`1E5w;XOWAABZs?e~yH;JRew_2NB? zUI0LYgBxrt{c>6NO=v~j5ta35Il70}MvV;Das3+g zpqjwaEyONfb8$JB-?uuAkFu}Uk*YvtMXRwdU)!F*QcJfCJeU!4G+>ojpH{C|L zkjY~Ab!F{|+47>(0Y10~P@_JwYNS@%u_{ET7b{0}(pKWzT3nSxR$krCE)Wbr3^8LZ z1K%bewZa6zcYM6^!}0X-!$UB)n~&+h@yCNDwIb%rcMMOQUn>9jy{?cd5cD{>E*6px zs4kVis|x(EGQo9EZb$=9JZ^YWOd7!O<+{Bl(!=36O<>|EhMy+Fxpb*@B2LEDk!f;J z5i|lpEnvBU@^?{3#-Y-5pW5Re(=j-{zPxa1tS?QyEv?uogHS&ja&KQ}&s{hL4&&s^m9mk4doq=TZZaWe+ZcC;#I~*#AqZ z+g!WYF*v;pi*%ewrUU!{_+1Dt9f0yu6~#YR|KygqV(QHiwePs+K6vnv$KW#``=IsO zar^D;(_EED^32jr4?s{w|BPWo$&qAS z(vELE#EVsJ%0e8HLChj$bHGz}GaQ?#nZAL)7V-4oHK>k)p*w414S>G~%|mZqf+I;r z58Z)^BVoI+;`(uawslC;CdXh3OkP`qh7M7Bvr%SPU=Do`LIL1F=rY>FjpnF{_qq+5 zQq*#Oc$1CiKszV|c=cx!7YO3Pl$OqHAvwJ0dF!=gD90x&dt$s zt7*W5D1f7DDBdAriD&2z`j<{||rHAPN=%IldPJBZkl|Pps zey8I2hBQ1xx@p9G6Q;w%836z7RJy*YfRjt9G&z0(L1XX@GT?;y8ZjpuxMBF+=SQUv z3~#Pu;tuVTMS$QzeIFnmZoE33G}O8Kv*QnjK}QBpfj}VWb8vbNCmJ*W_hf}hvnIjP zyOzR=r_&Q>j4_ijP+E51vNU|JN!Ea4)9Ot&Pb0^Vge~h*1B&5ehr`r4Q(?pF8?1Zn z!nH8{km;~#ZEBFRdf{rAu+s$4o742RZr%#R#|&>7Ic;9I8LEQa?8yQQ?@eop1~HR% zPfr3f-!yrz$t{BvLubCHzz4zPam3hk32*!3wuhC^tb|RgQvRc-jfO@M(qFmoI@33& z*J3>mr$xnA$kVqRhI#vR-Q+oI*InSX>_n?K-&_sb%$VLX*jck~EsP&OwwxBit4q?h zYGbzgP;P1XSFyfaR*?#-Jv z!y`}3ZPDjNKR-L|%NSyvcH;5yvrB)&rm@{NGhoW()PVEBM;?bNShHp={QUAO;WHn3 zzjd1vy>9%&?NwORl2R8fUSgk@UU>~nojTc`&}J}g%9NfyS<4s;zVm`}Ve;hkWH)od z+vLfU;Hl@HZ+uP|bjZplw;SkKyHU}eCGU>Xu99vvI&3^BIw!*Tk;d{ZvzDpb@5PYF zdQ{<6g*YfOW@k{L&4NZ#tB*XN zPW9HQ?Iv0X78!YpF#KItF;x9M`DUf)6lSFo40yEVxThi@a1k+(q4PrlH);A_TcYy3As8DIJO)FJ$9)pRDHc zga94RbN&v*yUQEEzqn56G5A}3!xYXNAU9P;3d-$);wKPv3`!25Itv~ID7k@?XRy3M z4R9PEpP~m)me1Tg~Ds7iX2&zV$oK6OVFhY}@Kp+qZ`V`bO+yGP{ zsm7+vE=;{D=gaAGmS~90XDSe;Jbsk8=IX7nqNVHLL|%w|_avm_$ig&=531j6yU^|i zQB$s7t|GgWz~h~u19ZEMsR%DscRD<^4}s*Fxc(-lui?vXHlgzyR;pIqxGqGx{a3@p2U8SML+efg}0bRhI@u6W$MDm^LaiGO7JP5Jj2m~S%Q zS5h=ivDlUv9-+xad{b zbJlL~_>)h!;x1dh9Jb$f8~dK0(1b9^^s_I(DaRjclUnuWo2@GwIb3<|4RF?J zC)&(?=`$aL5hI4fiWTX#g;)LlrUET4svG`r2Ym9w?}I}QOt1NT__6fL#8Xc?&OT2* z;aC_pOu_Rny=>i&KKT?>L0-Mr|KT?4y71hy5?(JsU*e57R>JSDyAcKg%*k#qB<<(p z?|(O#@-jv-k3K#ZR%F*u3OrEcD?w0gflfL9dk9(%6$p<=ES^3ZgmsoCLn46&US=GQ zuB;jn@y7sEyh*#n52PqKD(8?Z_oyrOnnHi|`UU^wk&nN<3U6ZnonpFkHiO4WeME zK@EFzb-CGZ&AhI;8sJAiN>&OMrtXtZ0r=`y%^BKlTBFeZ~&;t|Z+vo(wo!~IPZ#Ol`OftD z!;8~A{pWwC?*I1Rk`>m;0DJD4x=%^k&!;{GFflzk8;(2@;JWJpw%xYP>!xI};xGR) zeZTu|fDz7B0GC|~@an4oU;GjX1U(0;%euhbnu_nzV*ikx1C^JUA&6R>_T`zA5M#eR zM#8LPC>09#*|4ZcKE7|{Xky|B1eHNGuuvoS$tf;kWf-o5U|Juzj!3z|ldsS>b%@tq z1NhTF1^E8=Q}^hIjnS3KX6nw_rt8#XV|Ms(fH`wg_gTqC-v>XC$U~Fb^eYnjT{8Mh z5?Sl5Z!PkB=%Hk1>v!pA{{7#leoNDJKss4Ms_!GFh2Of z^m+5msrwZ=~=4_>aY~uYVoj+;ag=JP}Bk zjl^rN0l4_$)NS;RQ!<^yV4HMf($<4PUKi`vrEXKst2`Tq=DYv=>yAg(ULJikb<0Z#T&na$IpY0yzgE1 zIe)<`aLXNkgeo}m)RSP(-FLI^KmNsK@aF0@&~1G6bE*9H|GxEI=r&G0;aJ#yyL4^y zlFP1u{=l*Y+1S1F9w4X&Q+AD(o6}drS0F|#mMQ901!;{#1;QhPpeuT|I{;}mBuJo{ z7)@*zx6#4(d#g649(hm2GmiDFiBNqYm*%+m!gcX2y1J^=Yg6!-t%|8A6&fc>k1|c% zFv1Y1)HdzD135l)MrqNK{#5bid6ECW^d>!TzRqTGEcw?>psAGYkdC(_otB58&al&|J~mM zeEG}8u;I?lj4M{A21H-}Q=X=UtW$2>m~4urzqEv(C!1Z9llMzAz-3-HA+wl|68K0UU5(JM5u{0nRxa1cIJ~u1P~J%2F~N4g&~l z71|S*q5+f_Dvv(+7Q)?dikF*5PNvm?d}3OcH&wRW&vm<|HG8iX+-`p}2kMp`%C2(Z^)nE^Zlx0vS5 z1K6?!VDaMAeaR&NpZYYw4}X}t$Bs?2e{g1O^?&{kz;VZ>MqU{1XBs)yq;vY|sj<|3 z_oe<{$Yfd9IB3%*fE#W|-zQB<4WDMr01`JPa^ybyw0|7&H-D4LYUT$S2J`2ohDf;) zmC>M$thsed>R!J-O?%6hc6o7zPzI}41HAG|s&g0^zDDOTa-{j*zx}(^KR4#e>%tmq z3P%0i19`kymceW%6z6FfX5zPX@U1N`QC2 z8=_#!>w*i4e#TJF7|87M+t{>ulYM^v zlOKV{=ROU$-E|Li10Q_%g~>AXltk2DQl&@*gBcoHMp}MU+s#*@c$MaH<#EM@bOu5O ziS0l-=n=`2TJXa>D-M>Jy*JoHK+XwePjUsOKjb;5n2IIFmtW!P%0My4*Fud6u2;ay z0g)CPb?dz)L+JLiKiW_%bg^~S1t;3M;oOR9Fx@6HrnCQS!a9CGq^}Xx)oS+1j=FMx z7El8fgqOv;ikO1d@ge;({Bp{WKrnDHESj>>fuRbsZqeq5>A<1sJ2tLwwZ~mRjj=LN zOd56a<^reRMKqCJfuI+GZ5cwsl_s7lK;y!dsg#EX0(qeFs)5n|A#S+9Lm%enhI2y_ z5aHP7gGv_|8fwqV%@4&x5%H=lhKsBy=m@xz=ioXg1>CuP%9sk|0hqkt4(~%qj`0l$ zDv%E@ULT@c3u%piN?(;t%p_PXsOKPKy+9!7cf<(OzWH1Qc*oEQ1_uUdeJd#Ipa5}V zCnp}~w6VG@wM0mX=rPN6oUW@NEcVAPg{m@neQ^h8Y;Ym8>?0T=Kz+~OE&}?zqF!TL z88QW`(*63QA#3uL^$CYS#9-yFVfY65iUkr?*3B*m=rBpcs8J>*FUM2+BgKCbwUFC1 zs->YSWPx5%i0lz{*CT@K+XHlFt7#iVX-grIu@Ks6apC$1?SJ$)qP|yGk5VPZU=+Tb zdhe{-bs((27Ba(Wnz1uHe!4aj0>QureX`c1>{=Fl-QBUr0{nk}-*&(JQu=Fi_m|}t zUI=jf@#*`QzLcI8V6Fo({pFaq0Gxk*dNqu}jOolNSs4snh{jx%Xnyf;`2X@30Opro zZ@(}L%sT1e*=bR~&VISIYE}BY^G<;OaE?Vk`e=Xy4gh%UvDAIU5l~zy;dc9dej4$> zvnv+-H4_em8(Tb}B+cLS836BiN9r(F#F%R>?a63PUcdIW^l7fMG}j!C90g@$OkaN; zU|M$4gFTTTVmV?;c2br(70bOE$JEOskEEv)7?=|nZoUQJGg-TP;DPjHE%#)GKl>U8 z1pS8CZl8l&(R7Cd%*)3|0X=kt1a}SLG<|sm2?^3uL407aK{gIa+fZ~&*ee!#Bp6(OoRP6e!%1le+$)_xPiu{;rt?G78h%> z>sc%hGRRJndi?QJhJNwI)V=p!i99+T zSWKFn$bO$G`eB{J)P<=BgH~PmCSU|pKKLXpipGGVbN%ua15B4+L;2tS8eqv1fbFvD zq)hpllY2uaYvuZhIb{}KP5y^JB<uZ55vu^2@C)#J*9GUo%pG@thaZ2!x>x5{7*gtm z2S5DTub?mSAOCeR^aXzUtKWb?P=KN}T#_(SM@^|>=H6;oA3`UzO~M&RyhDmEM>GFx zDzHkTeYTL-pYl`1^^hR=nyM@%1R~hrN=&&$-6mw0F3CTt@Su|oRbQjc%M4^X z79qc;(e(nNRzk9p2e{Sbeo>{s4JinfN|anaZMr|#g;^id{_&frGdDW!+;mT^+kczt z_k9c`9)xP!AKv`;v*LeLQcdQEQpyHkeG3G@8EbKP=4pUK4{N&@y_#ON=fYfjGHX`) zZmvk#WtVi*$ROXOTDLBJUi_oBsCa0 z>@eSBjsf_@53&sy$3MSn@X$k2gSPj+k59`i%KY_Tr|)amrPt)-*S;KbXgQiOv|7GA zegExm0giMw4(BB8;+M%{&6l#PFrRx4;GhH34LXCbe;weXA4`n_P5QHEw++Pvg8o32 z^=eJ{pDOlm0g4W9t~0(9tmxOf2U&|6)D69_^G zb>N(a3&U|$z%QnwDHHE#-PjKxZ|NRo_VIIbC|lwjm=th(NBXdH?QT!TgRV}etT}LWpp89V6`Nx zliVL8zn0uwfjGiZ(Tv_=uC@Hx&r-MfQO!B$q(5pfFos(OH{Ouu&0G^{;^aTZFotm7 z_$I)0*QM_N^}mwc%l~Nef8j-dAO9HOd*5sG7YGDB2v<0bRRr8Qmzv+Pz>C8U!H?saJukcR8kz^z(+6O63j~d$ z!scp$yvt2iA$f-5 z+i6)=tPd56sZ*nuCaTvap!;(eh(ypejbPEaL;M8ZmS7GTz! z;%5VuMAWrUZRpEp!KoOKXGF)ujt6h+M|B8MMg#*FamHFpm!;3|e;?q7KWzJN+>mUT zj4RXUCn>$TI(@zm8UI|68C#uk2Ec@g01M`)?yr0$+31;(Y;qjerpsvz3|&rR`r&cM zrN8?B@}Fjmvktm=aq2WiU1qbyobY8}f03ThOrDau&B+LN+?nz*cxo=d)mJAQZu=MW z8?~AN=v_znRawEo=>%41D7MD1?a@cu#%jZI?J;wk%^YJ4ck;=pd+OA3UjFWH)6*6V zjB(t<54AV&uDLclSt7$HK9Saq`Gvm0x#t3W^rP+Y*?R!I^kRBim%&31riNNGvy&Xw zu1(rrvavPysnngRiFd|0J!t|+}t~MyB%A3cw?1|Q~i8$4F=9%OegFSELxO4 z&8blo4$X|z4>}0o8~>3S*%+8pt3og`)`}HHzs;M|=jhP@fAyCD|NPIX`{Iks@y$uH zyX>64-*HDOBbgJG46rO~(s?kE*Z$^jQ@1fH+Gd-!G1^{x6?q?h6u@@d100c^OlxGr z{1h#N0}o7g?Ji4Ci!v}qMn;Cr<;L&)XL@qjqmQK3Y)+P{f~8AS!y)&(OIfd3BH-^hk=FJgmw!7`xKGiD60doLec_n@4jJ2-4Hhq5f zvqgVnv}cR~-5)HRetOc*{*b;KV=eQ;h({hx-3K3>o`kl3ed^BZ&creJ_{RbM*FUuN ztBo7e)8UMMB@hVu0o?o<66U!z0@vTSQ3WWT0zNMktt^BNK7`~yOvfpB;Wn~%?K&7Y zZY=!uSH1w5ocalsX}VtC=WK0ZD*1JeMJF6Ju`3?;aG^}sKy z6)6Oi*6G@|SoGy(9 zC84frJOirye5*M)KIH}!hZ(im)s#L$NXVoe0zvP>?Q(7x<`fueVKuZLLeWq|1{DYA zlNcgewA7H}>$8{#^~CQ0#qv@>D}7uUQbQ;8q-Z!j8`Dzx!QjfJs=q+s1#YC&&WroZ z-*IP;nN#r~fcg8DJg5#!4K`H%Tz~HS@cTfJ5kd>&4FNZgUM`w$h~|n)q)OxlGE}F` zW8yTFy(kQXE+r5QYT!A}9RR3#lbV+~ft6BFsBq5DC-A%eBJ2)+Pzomwwco00lP=72nrgIrTt!(r|V5n7m^i96t;NeJl3}1bqobzJ`hG&=&epNFP-Z zY%Am^A*BwFQB^*vDm0l5KG%IU#zc&1%?^8=aA{f*>~%)4!fyglZ0*eW{A7w#sRE_e6TVUaGZY72(sHaE0y;5WxbA>)inE_1Z@m z{PgPO5+6ep3&Frg_+%~fYkYH>mBD}i@5NtTn`;Eutu4n{wK9E<8U=K!*)<^(vtM+Z z>p=|O|GxBerTkuG>#o+J$wwyjbN$v0>0M0lweK#kQxhHFxlh`hLH?S}#JD9jnWhZBulNs{1W?)WY zFjoYblNk(7J_Q7Veg&n&af_XpRx$6u#OK0%d^vi6aC$CnD8DKqk2t@0_@ne*4Ss!C zd+0dcDv(ECI8|miKe=BhO@V-gZ;t2W4bJU@uY)PzH)8Q%0Kj(yDlJY1;`}J|Q>V(W zB{cFbhPkRcmoLr9OXg&&-~0xm>%?3Y-a09Xh;zh|>GjVBzx!SLit!v~72L?N21b_s zmw!pGRx~ir{1jOObMn^HPp7BVy6Nw|clwS`*1G3jfc^FZ7UqPj7oKmQ6!l0Vr|r3C z`x?NpV*uvQZ=W!hpTPBtpQq1He6uy{6KK z&u6E5ye&H+P37`3LZ~^88{a;aEr-!9)_G3&FsF$vSeU+>Yc^e&c6QcTML%<`_+R`* z`u=BM1Nh?~6Pf#6se9zeRDa8_p*-j8c0BVrJMWa1r>kS_v=ayff^GuOkyx z!^sXY^Jbm-Hztl?;38Dtih1Vmcp2Z71&i(VmfP=wQ%*S6p03pmm{YY(8a)LpcH^!Z z64i4WjyENeQ+hcSk6L5kK=F#D4>c2kV4%Zk*R^L%MZMNA`6y(d;cain4uLez;?~n@ z5jr#sdA|-Hs$+s0U)T#5( za=I5P`!6@z>Z)aCZ=n7cCgoG%O3JFDRVi{Fp>=g776AJWIwGV%6Fsi;oGpv!d8gZG zsLUxfib*Lp#X32oMEF{X*F^kWf~l&-6bO0&eq*gS-vs#TSF`IlRC=w3iyd}IH-B7g z*Z}a@W9j>jJ3=Lx>tDu=t4QM;iIcD~$%fI{=cLZBe;wepWOHi!9nv_v?wW3H<+PhO z0bF>YbNvWj@z9JPekX@8-~~YJ2ZSFMCMmvwk9|ewV&K@F0^GifhWv zz?5}Wm@9T3c{qK4?zvsm10l3#Njh0Isue4U&uJ z>u?lb_nm9RoXkUoDI%QfD4}$F0AsTa#3f4{&m`YB+?X1q8=2AIKmMa=_>z&a*s>+P z^3GfnURX#$Fjom0y!Sl-fB9GCs@!e2^!cyN;?u>Os{p?8 z)%5+d$#)-eNHN^hMWG%5;wI1v$mLkq(5(*44_Wdn6mzUv<(HF#E@ZEFPw-$OuitzVz$ZT04xcm$;HV?h;<@A!2x6E_Vgf<)z$>ginvk*p z4lflEw@Uu1(4sh768G>1$6-PLVGGv=b5KeUegcFQsg&l?xlh}_urk~5T;D6;mi=7u znA35Ai3{LgdjR0|aG!|p+pxU zK8mL)#ZlF=rVB4o)V0R}Jalyxq4BmwloC{u(rSow+_2sXBoSMa6?1{=PvdYtW_&7* z%@x#o6rRwuhqft{>w>PGSl@8nYJxJVMQAs+dDZ^)tUgAQVnj1NL}v{)j+t-OHa59( z?7pv?n0jcku3FH2npy;EwxT?{+z{o`LHw6-;(sWIln4)QJ~5*%6nDMrmHVU41%l2% z8*8o2PRlaC)PC=K0S-GXb?2J~qeiDs^DAt#S#al_sr#s-(^CcBmTflVMpc(ynm*01 z?#<@Q{r9JCb7H`hsQ~j{PTfEKDZoGdb2}e~E~hatbOoBE11@?6;EF3!=V$%|;FX2h z$x#V*Og4$OZUwmM#?)<2=CZ%i&pPW?oo-I#-}~+Fq#I7tonP{|K&>A5Rxo^vSNQ20 zeJPbAu!54a+_E)2Il*k08JJVW^19##tl>%7eeLV%`=5Wkd^+0gcccbZ2BVWrr+e=O zc>M9y{WpIDm9hVv^h5}g9rMe7*DC*j15%#bZ=bsJb|4V+CwyzkT(`$U3xIzOS`qw! z@lzf?Zk!NbAowWo4>#QKh0_HhuA2|)-Is<>aCO6Rn%uBT<-wOf@VpBI(WujKsKJHe z>vj-;azj?cI{@FIVxR(kROgCO4LNiYHxl`e4)PPUEL3XjZ{*R@qahj_Hv%loPEPvK z#fb!-h~Oum+zzLzGCx_$7%zSEn*awMSPVBZu7Qzz%}Gh$`A+ISEt6$memQloezW|8 z3v;U1(MPB6M&3T=7^noJ8yNY`;IICw7-o#^%}J@DldN)>yyrTH!J&tyC*$TYBJUAtube?4^(~peSN#`-T*lL#X}+x2t1$!!z#ipCmaLtLVRex z6$m;+$MX-RJYpG^Q|xejH!cND(Db0J!-?Q^KrLa$h{BYGJIj^>7H-C}S5@Vr(F++^DP1mo{Rnsh3XPLtVdD#w+JwcqAs9pOU-#CM1$ zML4eBB4ZYw(UEL~z8U~JYyhhDUuRrZ<$x{$3%OXZjrcNZ-_WzHrz=JUPmY4Qt6VYe z_t!)98&|nK5rLq$L7%L3#~tbO7e7z`Fz$aKeeS&%z~BBY!2kS*)cxfzrN93Ei@$_I zM=-x8H<&OXJy~nPg4At(L2j-z*?<4k{pWuUu4wi58A1BkZ@&@7)*0e)O{M?!9+79oO5O#AQw@%}=*F`|MPnjXjy`{PWW*2XRv7G+TpjX0oikmN6;6cW1I} zeiGFM=hJ-8%&x}1?%L`nYnjteAIeUC!l!l_dEK1sdeA`-g*)$HbdIbo8NI{Qg{cPv zw=OIan(5P^(Dpv}d4PZX$2Q5QKABx5=(N8_A5EW4oidf5TxGuJqaSVi8-2!HfykY# z_3}%pzGB*mi~MBZGtQ*rnG?tizVyXJ2l`C=WMKnyYS_R1Tl#KJK>Kfh)4rzIUIXT(<-Ef5#p9jsgls{Gm zeQRu-!rlYu?=DJ--fkGD?*jNm^w4+ts?6o(i=WeQYYM*g4uPOQK&)d?8ZqZni9)qs zls968o*GI=$83_)bUWp*Dl}6`8{RCY*Tvx1^$ZDv;(YIz+ zAF3uRZ!Y-3rAVM1f{1+JrSiyVeUI8>if(|SOdnlFHJcW-g%Q-lK+wBT!`@syz*;Id(8WsM zoR&{5oNC}V7h`x}KWW){ZncfbNcBZ=tr1(FzD5~$geHD9DB7#c-|A`ityqZ}nZeu;(Z*hRF8#M}RL=~aj57$VIDuo;6mM2c>;uRV;4Ml`Mv z3l-wmBy`}F4sUyTE58&__q4bELY%=P?evZze6(_$4yv4*YRg1Tw0(w{!76;MN%n|5fS)*ZUAcH;XkVCc9w zR35p!yL>~m6sWq!->W^m1%hbcP6NOn( z*H@=FA*&5nBV!_fmmS1Om7GS1`S`@0QtZ4=DvvjO`X$dmZW=?V?`w}!v$5(VKS0pn zIKwr%*yRo7;a96*o2!lP3?~DxwFrg|hQWYXOy5SMa{herHTuJRe5(yEe=0pZ zb%Q4zfbzF0PngRe0(ql&Dk6{lC+Z6XeGYE8z+H{fQout4OgJU!bKMshe;m&@9C37b z(G?GImwIoJVDjUpPsvsNfx2n;Rj1bhcML*vx=Acuo&qj zgecn8nHNzbC_OEMWb)|}rM&~GvYu@fz(6&3&8Bnr>%fK2;F)WEz2>+vwqI z5IL>fx2U2$e5l186%mJv%f+GIsdNF#RuU?b2EPO2$I$@DU?dPQ@C_%vI9%7|hJ_G+ zMexAkK%~VDTij3(;^pJvG5CwwXKv1=-nKb4o5si23Oh+KnMA01tTm_voUR8)KwWJVZkDcYd|;Zz#sJco45 zxHS#hRzO#A7JaloH{I{3L^+4Zqtx{{xzaa;hS|iW5eHp(pjQahS@;UXVxZ3d>)Ke{ zy)_k8r%seFH;RlJZfeTwj6t{=cc%=!SLukk2# zvhDZ^M4EGSt03yC5Acxa&(G8N<2z{`FL z;?}K0LowzBMEXev|8&@Iz zp@E7TM5uRwaDJ%{T(>iIs}t%D!#kz#CK^`s1pCPY*f@W)STXry#&Jj?>3cf&&J2zbJEAdXLM2{nhoJOv1< zff;5L@fPI4(KljDQMb{?bULcDrm#bRj^wS1@#>&bxz|R;R8$pW9mT5uS0OrII4#6h zQB+<2aBh*fIqsE1wXdW#88y5jht}Tb(gxvAIcpeGQT41OkB| z1r{!;`B{ca|;G1h_*^MDdp!;c-7tnl_x$EB?y&eT2+nMg4?0WzC0`9 zTUFsv8{O%G?Qi6Uj?Q`ex#FQqajb$|IzbgVQ3d#vU%B|&b#`TX4(S6Oa8@xT#`lL{ z9PJJD$2Cvw@TpJ)-6<`c0u=LCAsQDHWTQQQ08r(lIT56C;uQvZ3t8>phR2n5Zd2aUCS+BD@) z!MAXVr$iMiTi?ad;9vixh7va} z6a zEvPw`lMkr*UI+XDg;R0^*BPk}j#n9|j^O53fq#X9`c{!C!stdB$>1dr2!yheL0wNlSu=d>wbpQt+ba28nAiMbb=9)HAjYxgDMq-&Y0FI zJYB)J0p8SdX$3CP`O-Q%ogmMa0bFc`QJ>cl>8WB!iH1p9NBA(=;4;yp80h*#g$7>( z!O^%Y#n+icBoK6h9y8X8)$FMmkc-O=8j5ji#!bp&JesXEx{7}O(<*z+70zqwXoy34@gw(tq+VpklLUNE#*1&ne9YI4`c5%}O2zMUe z_fYv6%n-RtAP@+e1)diT@SH>mrm;!@MA8os_?Ah0ZkeM5gAP<5*F+fg49V#bK|2W1 z$uNo4kNoMXCvF%(Sv~RbrPe({%ca1?bHiPK?Ma{F0Wjp6$e;&mr{$&=QQ?JlglJ>h zii+~`##h**RwL!()G<^E8yY|`C#owQP8ZVfLUl|)QZ>Z3BB;gTm^fTWEH4$yvH^5= zaE?3FsO|^q_Ji4*(99ptFDk=StTNyHfRaGp5%g6ptc$HIdNKwQUay7O`0+ux8uMj#Lf zngyq?<9Cdz zg?ac?7N5$aiS#*Odf&Pb7cLk$KIweSwYKSOGk1WB;%#dik>fhLbk}_ z_ynI6}K#=_U5;3wMhtL32Cw?b% z0)apvNWsmW?p(*|wbUFuK;cfWzUiIQcPJU(Czc2VLmHecjcEXAIU0ag+(iy7KtLNfQO-Tc_zRd^<`O+}P*kSmk>dSsQulQlO7xwXz&+GiY4tqZ&tLtsz{>1!95^ z_6qWgBP5fJg6@D{i$Ig!;k?9ChIwFqx^{BmI@U3SEs|i{YqV~4rJyP$ucIRL>c~L} zuvkE>lXq9JtUB*;f@!Dg<;{Xr1F{!b_W6_6-3zEs8gIcv8a>mv3sg;bgGTH)!S$gOa4U@}TnS#>MqR)dltK0zqSlou^fW zcz9rP{d@x!Apg+3PRT7?ngC^aAtc-MQirP|<8-=15=$#`mp~v8#Dki1INjMdjt_#d zm(w#ssy(+n0uV3G2n0hOvFmlzm_sSo_+1c%nBv20Ar!5Sc<0ik{IR-*)7KEU9E_V! zXdOw=zfin)r7Ejfzp56Esv02xyhp+>ys0SOiew-Bj)=lmRU>#2v)+P|s~1=;M(k2h z2~;F%j?;W})~PF{8ihe7uf~-F-?uPT6c5Z!2V>Bo_?p51Vy0RyPT#33ebK-?nMFz>Tmh|@KnaT+UDf<^?Mw&ax4pL zAXS-vGr6bsWN`fn1kGT?`Jec#e?#1T`ocm_jF^i>DH_+0`c4Fcp`gf!vL+A+1}VIHEklpNtw&N*S#WcUoBO!A*9RH91p+|~@Bqfi z?k+tZAbsOiXkZlt5j&Jq>P*$R)S9Ua?Qtu_t4drdFM|GoyN{{L-pcvEBM^2>Du&Qc z9Eiyo@NoV_(mm2P>t~~(ahWZDf8|t?YMHhe2j3b`1C>Z^*;#MxrNIGx+noAHH_+L4 zWl2S+NQnyHGA`n1sCUkQi}h2*xcOh62NIc7RWc@P2e(PH z4y+s^F_MWeEUU z5TnvmjDJY@0wNzcU0>QEo}c{EMd%U;1pNpF#i1UrBXUy>H9ctNT@mlvml@1N z6X9IOS>`Y_<|lzb&@5ud4Hbyv3s;_af=bZDQw8Wlsv7`ZMbupAn-?iiO@ZR8fuDN? z-3L+b#U@d$QdAUuMIBMa#lu?!y!_-_zu?l2fv(_N4XT1~F`N>96)BN+1C@DqGzL(0 zTp>!q>5m`Dy`O;VypM7kZE&LbxV5tC@YLWxT==w)xhDlVjj(TW-MUR16)2Pb_Lwo$Gcmq?Yv?eAcPiWXs z%XQ~Z5yAz{AvM>7ae%lbX?L<%=ws7 zU({uP*FdXeV5QJZo_(W6?v_ED`;PPF=#}(nAd5E$n5D5AK+|+^nG@|$E zB%K9YR9zQ_=}r+CS_SFu4k_vG2I-EWL%KuhE&=K82I=l@$svXw`WxTx51ebRIs2@= z;#tofnGa-in8*{&3pDDvVUlvXE`UCf6VbuA&;a}v9TSs-kckH zNa|*}h1_HOmFZpx8ia9K^eekW^5s~7tq@|;+nfhT!OxDeG<7yO^P;Z zG0+CpBTSPY|J~drm9Pfy``mYUWrQ+kXiOzlK#GNEtf!MWQ$j!Wh%OdlQ@kE;m?}nD zt)5G>*`A&-vQcpX(V3$X<*RU|92}IgLeDyaBF}?YKvfXQ&n>?FpY0h5>>UM)5q+<` z!mQR0iq{3REa1skn0=kYKxV%jmM_awN{jTT(W+ifSJmH{Iq18)E(*VcYKYFn|NY-V zuvoIVeXZc%ZcoGa4FHM=+B}O^*TY=!#yLj zd=BRlwDQtKlq!O*!PHANk?b&qN4ghLIR4pUsyiL~6q(oXhZ}TM>;_2$<{kL_u`#aj z)8+&mIcg3659O%JBvkVPVNlz={ZWHfkA5dXd1M43n92$j=bC_O#jBQzFf@sOvBe-r z0C7IOk2eQGR?VQ=U}&-0Plb(~lmXp6^dc?qcutgXt=e;2@;i{xJMKhP=Z&n5ldiJwpxmQ$cf$iZAhY1-_S_ZL$%u z&mA_&Lmzh{#l$cwD*GaHqiHlX_*UrWoi0(b>#|Soyp*5{?_ZiT=tXLQj6+&lS{p z$(J-ZF%)~V%Cf7ns66N6^$|`tdi7|+Qok=dR7^_|k?en5HquzkxBn6=w{HEqB0MZi zditS_=)_4{IURy<=A^u@@+lY0d3^@?#_Hg5L)-wXZo~@}6hm7*tc4#Ma4tf^6zIkI zgUDI_hU~(^wCg~vL&IhZcXR3vm=|qaWEg>r*%RXM^o&dEJ-18B^&4*8`N`6Q zZI~SfX%4kzX@4}*Xz=mB%(%jRj{~*#FdPyZ$Y=O6sSTvITaeY(in}r`SzSIyF{t4A z{=T8}`1W~UFQqK4+=)slc<-je_}nc$;ltu4M3HJjxlB}D!3*gtBI#xg;p=edfxL1g1!5x9VLmNhuQ1<}JlvT5XU2 z`Rot#YX{)PPw>c%pO8UI6z4s3`QP0OaC4#&kwxj_bV$3J21P(b!9Clvzpg|tkw5u~ z`j&l=;v-_DYIR&t#YoxZC8oqE{t7`?N4djW`x5OHWeB4Al{?j-;F`B=1CtpAGE3jo8Wd&KBHG^ zurMe0=eb3zBY&X5d{3GvRq_B}&%25Ih!N^tBK7i-p};~`hPX73%#QogtMBIc2+(<5RFjSD>_=qfJPhowjQw7Z0jAT|NJ^7cG=&GqG_7di1@y_ zp`!uoweZnWU+Q7caXTkeu)yhGB8q~<Kvx4d^ z!+V5pQsf{kG5s%mA@OuVjxOIH4DJ`#(uT>W-Jg6UqCte~RTdl9J|anjT5J!!3cpAy z2RWkct$);rzrL;xmsXLJ1rlG?ir`~=Nn^vd{qzvbl*L#Vdv{iyjKl*K&gP;aM@-=? zIiK8i`^wdl!^x85-(Q{);fkem?J0nJFBWv8l*cs>{kBOb>AJ9A@gPr-Yed)Z=@0~#Ey?&QUuG*%P{!(RK1f+rf{tvD1iN-K3`q0qM zx<(jp6-%5CQ~sn;)`d$hvr>n%Y|iUGu?yd?Ew!0s5u@Wnj#C81t2_5^NYTxy$!S%9iv6QQ7F? zW5b3y=ZR^|(lNy5FC})(cohb%>p1{(nZ|jJFxkcN>vHUgQe8@^xVQ*}4itFpJxvqC zxZs5}hSFKd-IVg}4TTLs1cQ-w*xfL(vERM#Zr^zlzZXMQuDxr?Hw>Rs#?dkHbljnDjJ?K7=3;0Wc9ctU4Jq$rgkuW+vF)b)v?9J@Yv2_xTU!oj)uK1;XEATl?V!g3L0ckVE(e##zaD&q>Mnbr^Z>^u+C3Y;DLS8T z71QJRXE!dTbnh=B0Wdv7Ntmiv{%o|E#$zBte9OCcC06A8UK&3R`00-%krL~)jYjqP zN5{T9@-Gl4-L>!se`@tEFYwRfkt$K;BsZ-Qq3Bmyp3KFX)wCw*N`kKVdxi-KTUqZ$ zt0#LOA^{~6`Sh|z$CMDm@f|eqyW1OZz}LtKUx5h)*tiMZ36G~NHU*yB#Uf4(k^dIiDL3By7NVjH5aYt2ly+y#SFw))JbA6qqAR0aF7^AyruA&FBmN z9u!r^!-%Pod;%S=K>u}RC#?zmEA)@K@}(S@UA90*{RW> zc_`5MVXOHFS$UBLT;TY66YBhoAeN`FG%Jv^WTv4>pM%s*j~b)rbrk{?w#=0rSJzP{25T#m&NB+DimOX`5{Ak#vVBU8K|En zE5j2N0XNUaC;gs$R~c2puNuqMHdLMN>YU*2gZOO|)Fzc<{>0AWhc}M;5Q<}aq`H)D zW$LaZkq$nUgh8?E3!Og>?pD!0M&=dk-5+{6{a;1GNrJuTd8|YS(er4Zw~1@$l4!6X z8PZ$7gX&|XNhXc{OY_Cx9aIr$m3~%b{*?3$`Vp0PUpcym`7TPB(^>8Li8#A>E!H>s zJ9Nf|L}u?y4G!7H~ltxQv=*;t(-RBJ~+ao1s41YXpB-L}U?z zWFbg#dFrPiKlyccr^qFbF!^mc5DE;1rO=%@XE{9+WHx&n)D_=M?!j zz0Yc1+*$1)tlBRJHlVKCDj(zXxv8e3`&CzL-m{QB4V_SGG1s!w%2H6&0O5t+UXnEvYS4Hs0(i} zKKw%ec`oP;YS{e4T*z#d6CiBL`@GlfUyfs0k}lA&uGj1kx=_Bf3g`XUN@(}wa=Aa{ zOS(vXYYN_=ckcT{hpM-!JlFUvm+$SHH;|y-&lphO#>uwo_G8T+ z-m^b@JK*5M<@+~TNO!HN`7z1HvxDO3-7P-DY5NFh)_iOyI`{QA@a^CPw6oITNX2^* zqh>PM<$-+E;9UD4wK96ITu!`n)=$Xi-7GOAJd15hm1{8Af>&0m zO4#53Wi6(Ghprf8my?&h469HfW#P0e*9YBLi1Q81&F*``Zfo_K6J)|Ja4B|w3!9nA zOBiMo%Ik{=OW2$eKNb|}kb?PkhppObwI)H$wSTke(ZTe?IVXH;%ccER-EZWTyxbeJ4sHjumoZDS~P?7-KOPVEyU~d8iK10&}qU*Gd;%L5jLNiF14| z_cfOzBnSj9V&;sS4czO_Yf�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

    {inyxtbsAALZwFbJ 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

    Akxv7jk8KGho9M;t)maF;G9j) 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%0An^2 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

    1TQWyW3r6aoX6teD8dky}Vn|qqWKp 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

    hIhdx8bX=s% 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

    0)L&v*e-n$p*+Y}`#H@eJw8#1 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%0DPA5c`(bsloh_53k#6lkJyY_h1&du( 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

    HRGS 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

  2. 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ᅖyMf)v$+6CtoP$jqRn<>% z(}pQ|L<9oS5$n72`>J2N1VW>|ULgPa%OT{L5ZzXVETIBljjc<*?6c5S0TaL@UEvdl zcdE>Yjm529Va7%L8;kRJME+yC;;R$$=Br%gYYttog4b&VSbmF>sp=M1|)D>(q zllHA$54xKfe^N6vqh?ivWG=*mB4qDePkQ*HN}+ns`3xY9=Dzsd{&cH{AOllYyK@3W zb>|uft$Q0^B7VgaS>X!j1l}`yC2|Z~RE4HHE9b}%9zDx;UfEtoc3t{1`k5(vcNw=> zd9$zOTDh4Ip(NKX@3?)42JC_TplbB8(~k#jM;iXPJ62K?YNoyc^+6b$#!{$K@5R%; z?4g}sF+CbQ?o_XJ1}pDM)I~!XGS_olrn0K1j@GWTSq-6<8*i}bj9RC&s>Ny9L z>}4_Ik1~fSsoLdiD`%Ilg4}-$z{I&Vpaw9Gr5u zNty9vFs0o1hHt3IBJ|iPf}L5gM>a#$aMI6`h{jPP^)|1ZFeYCd?aQ_9SpHH8<#&D> zM54fkukxB_+}3euNuien{#PokX7TY$o3&cfz24>MlAf=2+7AJwYdS_~5;tL|k{j0j z0^)jUw&8dX9`%@ ztXtkKqDD%cH1!woQMEKDKjbt`wDtCdui8x zYo;6Vqw115H_0&V-u~8Bw=`{y$?$qbRX)m^S7!P7}Au8X^Oqa7P$Vm5i)* z>y^IL_P~lmCmi7-1^U(B@~X3w|ye_0+JtpLW2*#HU1D0!n08?q}0vA>y6qii=0O zk$ZZ`lG+a{m$zIPGMzZJN@Tjaq`GC!P7l=jI5@&}lRnogVAQ6>DEU@UY>>O9MMR0g z4(!UE`S|R=Ce$gkiYUR-lCZYLRf*hz#|(Y6iZLQSl5j+(ugx>>d`vU{_a{shpJoXb zaqHbibjoUgZ{s~}PCU1Aq1+VpHXqa8*IH|4ztfw24p+SS>C4TN zmTRoUY!_=<8nVU$(k(XDE;J}?lx;AB6vYKrX#V`D?Lc7zNqyx>$9W#BmCDgIuxi4> zNC@P+;)hm`WyQg#!SaW3+M|PyZ({{ePwLh&C8@1pw~{V*VC`mlraW|Lusqi~IUQ?c zyT>Lx7Q!agxH}bgdkageUvkju*Cpjo1E4I>3F|=r*v9E^VyrN7y7;dhi zn3;Q}$7NH4@cqef-uXk_dIjK}P2IO8IBP#JdeR)RCHR!z!N=(#i_q1po~i1y9Y6%6 zzjD$qvj}TfJRE04!sXw`O1D4MkbCELUtEGcOV#1~gBB1_=AT~FQE^t%UH93&&Xc3iWec0qV zCN<7abV|AqxGBkUv(+;Y3ON@a9jTD?Qnih$E7dRM=6^=9i3O1F$j?X3Hf$jwD%;m( z{IB5c5E%Cs7R$Rh!#ob~z745t1mc3geNzSn&Rc2&Y~K{qyH&9fZId1w`P7@A%2`~Q zBHO;%>dGCeMpl^1sl#Ag)@*5 zS+dQubba-RF%g?E!t`kUl8>BCIYed6KD(7i;Q{CDSe8!c*bmm$$)5X!k0UEzCY+We z7%|Qd^ivhTZW@`@n?01-NfRLH0Jy?KH>HL2Lh9ZhD3LPQw{c^I+gfJQw#-otpsrM#B1Te|S8! zIdBhhM^TPK&dnNad0H@lR>f`~o-vp0V`!;;-*;`b%-drJV>5llZXpk4gIZyhaMvX1m>- zuc>4GQ?N0k6&<79uJ6BM((zt

    DL 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�i4Q{psS(T@|p!zAP@H*|{pvnlK>?-iR{v z;iTR92=*z*{r>j}*R+G{`zghaBmGa~7FF8EUmZ zyBc%c5JN;WU%*qAizXK|N^BXUiK~cE{9Fz?q_2gZGd^(L&D%9G+T$w_DCTn3{;*Tl z5QwiE1KkP&P&Mz1DOx{iCczNPf|=sqU?gQEl>A*H+^@W8+=p)R-)qb3DVMl$urUp6 zyxD^=Ov9&441eMWX*x`x^>pSOT(LShi8*=T*Z}Ph!rYcSi=|BYz1K+v zV|GHERy1m`HznJJ$a3-G)LEwE9LAb@TD5{OCW|b^vnl0gaM)r0;sEFvrR7-DIP$s^ z=yrcVUu5O0R!|jm&O~T_%Cnv}1-L`Xv3Nc)$QSD~8EHPJ_1j?6vW)-5-Mcq=`kq!2 zLQe)#{E<;+;wA-u{Iw4smD!lG31gmMHd_0T7EmMN{rJeS z8no1Zh3G!~1MU7{{M3$`x(D_-0X`0@pYEtSzJTb7qIdNkrU21x-)KLz)15aYImtGRLg{%*V72CAmh9bHH|LtqtBZXWnB)fdg_lAtik%z3m{n!3zLsX z1=ZrX-O>+X-R9~f3g_>!{)OJNsu zL_JaM3u~Vb`x{Q;v)L_Sj`6P-Y4R2r4#T@NW&yh{tN+~D)p^6Ghb2(58gr8}@^`}o zU0{$v@6m9Ito^d96Nf;XS?MK_L2uTp6gWa!BaEFa)M1!JL#Op0$2A7!eY#6~2~q(e zhEDQ;!xLc+*Ir?4ZxrqLmSF9Z!CLCCEhSwU3+XI^6mwjO&t0X{w9TiNkB`~00dLD<9x<3s1D^Vy>b416n04)rldc!IGWGy{Es};gk%( zP<8hS%a3}MJF@ls?e%IV#2wG8dc*6ZqLL+*ivLR9#iM?QKCVsFR~k&ST}|kel9H3h z<+KhI?d0&_>Uc_@1L)nk`ueUj0&Ly(`loIm`P*+F&a(sNcy%@a?gS^C<|{}18Iv|& z-N+KG{?pYxe4%;MosjtVFW+dFl88#235zLasvkjor=Yddud{L#uZ5>l(#F)_z;2& zIxldOQHMdf7O+Q2r+eePP18de!R%TRhm|wj;;||0{Qa?$+->@%*Y$YN>31xt)}o=v zm`uEatyUkjxb$}i)3});xhzt&Ic|lwem?6`>fXI#var0kdJOcral~8NsY%U*ButTH z#66)Oz12@M*3BmJ^s6R+gzq?1VLVHnU*b7_kv=*E46XNc5ZJbYF=Z}F(}*H$`r^jY zr@c{}x<;e3L6Z2{b+TOEc2dxlHEChVypBXzVOUv~T;y3r4t<)lK}zXPaayBfjj)G? z+ZKh6)TqZEG}5m-?joBQgU{~Yn=l^xTU}VJnG`)zJo6C-2D@2GUK(*6;#yAnswsY> zZpLt9hxWy7?#s83YvRqavYW^3C@W>|#{QganwUShPgqv)&#!2HKcLfoS3d+WA!n-J z4mV0H->A+#^Zcu0kPFP13YDO5Lo2+rW!S7C9rF+mi_>cbL6#}0k<4;hVAbje65!+k zL9*3QJgFyx>Q6nB&2PQhP3%1aC*|K4kv8`VzUUMa2JYx^$oO;SVU7C8dx`UChCjNA z4yXuKpsqp1#BcLDX;tL9uweypEa@|rZerRJQt^x~X>Nzht+=zaa1xxJrhtP@7|7g4 z9b1}6`M1n2+xkXp?i4(5E-6D3ct>~p5q%f?=7<* zUQi)hoG znwJ1xATg%$hWLPQIy#2}k7LXNv{YoARMX}}AbM9b<{zkWdJzCOS{$4DTgJ4byc3hg z)3dqp+pOY#*%d4ytzkcUq!Nk6+XP4kKU>0at!*%Q+C; zrspZUT7LE56tKiYtgu@)KBN2V=FcQg@YL(@Hvqnm?tk0-+b?&YY3+yJr@)^*+?sD0 zoX@Y#>UCgn=Jj!Q_V5l5zOFCK1y%^e+dz-YOKkkBuG?AHv}Mq*c=!;Yj#`!VVvPwq!o25ErG$tzY`t>1*f{$9C?Irw2=}*l@29k1ucs8rFQ-G%5bizNR8Dac zPc`vf=Glh=i5K>n?>D9`b2**&yKHjQmo7vnp5aGm!Zl?2=Vx8sy9HyPXVpA5uveSk ztWyu>pT|3 z<}@aMyvE!#%Z>u+%M-Wi|4JI?z=l|EE*X3oAopv^3|_(%$1cQmUV3fboBN=V5a-W- zNeS2>45;7)j^DpT>P#FQ;>1d5jouBoiyBAgJ8mWaEF|gdabrKY0*HB#<-86cnlc7= zi;a?|9vC16p4N9yU9C6A2l@lBdnwr>7Azc%EUe^slqKD~GW64bue#X1V9n*R*1mn+ zWQ6#zs(Z43v-5r$#(SD_J*$_H+r@J2HSb@i!uPf3?dIGB+bxV|xZ)pvnJmZ?J#~%L zd(}>!a&(?`@O1NJK~~1{ruYDuf6Aa&zRH%{?d!iU+DzBjzvh#t+HNmr2Y#s8&AU4< z@H6^0Z&hGgpNb1S^^!Bb;8(o%ry1A4$9bnyiVB5AHjL}qIUBLZFfvbLK-kwyv5_tETovE><{|Wf7cEC*Uz^=6wwd)?;q0K7o@@;<1Fy!BpAhd@i zLa77NWhI5v_7#9bFP-3}+Lf!-(rgZNd1Yt$kPL>BWS4W$ps#(CUC-lZ5+o&yssKZ`F3|oW&N&9RDXE1c>OZ!DB`mZ+${ztaUow-lpxJrVHgPNzTq z?fC2&l_n!$(tNcO?sB@vaXuXDHaek%eSY4)7wKmW7$( zvn011vxWAY(PD-ge;hRCIm9)l)v21@2Q=6?%^rWiQZ=_JW?rm5VJ#f=QN2|*&qQ6x z;sehip`Yoc;L~foti8YO9GAvn?K6j3wWpSAwt;)sbc{#TI|X7V2(lV&=Ke5<8{LUo zBYX1Gb>zHbW_4mwjMCR`Mij~N$F!y6(8p0sH2g^DzBlgdK7~*8y)f#Pf%W+A3Nq`JS-@6kj z7(ZIKX7~3IicxAbjNn{5prJyj~yz ztlx3~V0Gt0HmZXOKFiPHWB~FZk1_p46&OCubvd%i!ZD>?QqWPd3^nVn-~Ik>pn+0R zAE6F);p~ftmbxBXsf4_**8pI0RlWPrEx>ivRoJaoLrL-Oy7=ids`^{Jo=c*CG=cH< z##Hhes9+A@`uL`j95r2<(WAsG@NmT>fKYiWx3=Ow~77pm#NS7gg`G>x4^n60M zOkjF*h^&6?2PYreQr(O;U&Vh;z9VdQ&xClk5j0sU>2qmQKc6iraJxv}CUT@#AG;bRRn%wXcq z#v{98$I{=FTW?z3wci62o|qOe*43cLX90OZCKsI7v#dorW;z6|yfC9W_9|+Q`SN)q ziBmIvg61hex=M(rHoq8!JWDYB_U+1D0M(`GrO=n-D)i8!lT%>5H+KmInmuR?JPv!} zUrIQ%QGA1xBY_c)DVXwI;7T4~p2=CeEpX9i_wLr^v0tT7VQJ^!-a#^Kv*;+W2zQIo zt{57?gEM+u=luxf;Qnr6H23il{js^i2Zjw-pdi=~Kjx#uT7QaFarRExSh%=fenPD8 zE;5lFyloMEDA^Q?61@oTupKR~ED+=B@OnzjnExl08uvVOEJ0%zzR9#-;LO4FhA%I` zx@moB(VR72iBfV#vL<;}807 z+X3N|U-AP9DPF1%tDGhWwT3H8rA!r)WpxL4mcHRNAy;g-MUWMP8s%Rp3uSMnMw^)r z?+h7mo3Sj4>!wH$`xj62%U67cvl+1d2{IPQ_<-H5sPI3s9N(mWo74GSxOz-~gX);F#5HhqKn$t>lC657Om zZhk!XINz6*M_^dv)|?d+oH^eiofgM%TI+~6D}xE-8-NTcJsvA`V$;FZCLwl$);q$; zEDAd9c2Sfk&?ccvBq??FoO%}wwn9aed+%LgRiT{w=uQ+H>)Chka$?g}O#Uj6SZVYQ z-Ap)Qsgy)@UJA^L_rIfeYN|&71{wV*ur5zJ7#{UQu=%YPy)kQzcnb^=)fBl&^{fg! zlr8N1%TOIPm&}HoLsLpWEJwVejV3pW5 z01#Ovwq^g<%J7P@W@gALa%wNQ)6}6j*C)#ix-E;@W?qhZ^15G5t44v3(w|V1GCYx_kMMHnHnY=|Y8WhMV7nk)0RqjpMaO&_ zdZJgNk2d6I=XvO4!1_Tb@Zz-#s%6FS!)MLLz*A{LW^=zUx}B;UD}5=Oi`Z+L?zL<5}Z%BxGA{lp!r@N z%6pAeU>`ruNFMg*mez3A9Hq;a;8I@pH6q}2D!2vRw)08Xuj{W2fotpI@|W3tO8ddU zNA0pHzxH=ck^tXg0j{qgkQKyPT|mZXemws(h(~>)`sK~k_d)#yhvS=THc7)msgqg! z0n*U+Mf3F%K{39!2Bw8(7+Tq>cL8{s4HJ8%9c-WA48{&i2Mh=Al*R#fr4J1Pds%2Uq ziSTuR>t1k++SPv*@_irbawskxdA75s_f1m*j$D9IT5n6rITT79%6Nys{<5IkfNGKt zd#vsy9}v-_C2EkKy`1w3=Dm5Lu#>IsaRhNhUyIME2-v-lb(3#6DLuL0Jl#Ng)X|{x zdn`6ai=`(>f-gozT8GyEDV4?ss0l^vqj!PBr6+jfm_w!Q{_^4+@zj|*#B|?x&upDq z=R&@pOSVpaBx6zF=y;V4(OC0rW_Dw~eGu|GE6+1GPi4ja6CEMZ1Oro6sam$fgIJwG zFIR&xFrGNG158VxTsqk^;1p;9+vj_)kOo((rxB>KFRE=juhNR2=Ki*9JA*|Z)(A$A zc1H94q!uTH=H65Oz3NZ*trymtua=lkeO&Rav+-1yhn)OxQ>gaYKVa3axNDz6>ZzJW zAFX)AcoBm`n{p&l3trZ7(tS+u8T`q6DBj03!C3BC7P$>x_jLO7J06?EOU5>+e#h1( zW`L%4#8?PTi7M#UzSzw0l~lfX^PBc{PGQThe`*0Qur#*5xyCt%3{?=y?C+ye4iQo6w?JGJwU}{yAFTUkeax z5>dQgy=9^h6;`@?<&1k83cG#f`_yLS0IpujzHH@Rsvh#(wzo`?TV;E&J*J91u5=&r zt)gGHDZlA$9Kv0?&pCgf`a*zit0Q)Gv)%ANoHg+;u_V^biDVDf;GCUO)&P4?@2#s> z?hhUxZEFk@?XPDL_WaLu#2;X#|u5KQmUOD+YEQ?nLk?(54pf@ue)i4{63t=Be z;$Ha{wzjU14sN+tT%_-D#=s7C-=F9FiC)h=jOiIuf4hB~CK9iLmV{DKmAhX*^zk=6 zBOoY~!08|pCQuReQCrP`%MYaP-Ake&g4g&L{zs|K;w~)EMKjFP*iWY$M)|bi5OC%F zqVK&NRmtmk8r-$26l0A$K1l&DpW`1m) zzHFWs@mtf{;3p`AbX-B^oJW4w-eu@fjt5~4>4|2i-7r3p#E_q0YbcX>nety77~7tV zi@l9T3C+KL%j}LkfO@}XMFs)HVZ2>g6MT!G0{j;ni2*6dLeG5EFVG)F7fF#Fs6sH{ z`8)NEz5Qn;cHzYs7o1ZRLxvf1Y$-eT&q+i9p@=j$WP9bAo0|hm(lVM=qVvrfKl}g) z1j}^qrX!Z&J{LUHfZy6wDON5(H|%cVwE}>RsVGpFG~)ohWFUK`19SYT{B{b_Vk-V^J-rEY)|U@f%%s=Os?a@Y<-xk@}K$3E)PMm#2!J2-KMPj znp(=3rVJHbBl}EZ9?yG}J-3@*?2FUC@E!|cP6Y1FFh<(Iy4_509m?R3+8f?SY*Ka2 zW;ZEkAMA4l$Jg@Tvv(;X?d;+3-y-|LZjSI2GFR39?fQ6eb9gH?mmeI=jS1eip`f#L ztr|QU@wJ$Je?aYwvLEDVTEgQ;xSIZ1->>(V84-qNOBWW2OlZucHs8MZjQ8A-|E=!R zmLagU$?;6GrY!D6V1DKrz1v&^BDn>p8$uGQ*bH2Zabv-V9uewur%UjC) zfCuq0g0W{@?_lzhb=KqJv#;})Zpf_d%j`$gkNLC0fCAZc1Sl}y|Al;~+Gk7O`~gg3 zdq4bO>J1yV1;+qYR&1U)>Fg2>`g_R8)NsIKK(f#pASTV-VQ~zosO(m(s zwxkp1Mpjr%VTCpH_rZ~BXxq72@neYUsRfJ{DikQT0pgJqYPx5sbZILEM_IHWZ!d4w z$e!XRFy8*90}nh+;|NZ^^gjdn0qqGXo5t0c4A>`6_6HZT(grj`DfR1Ws@%IE+QAwn zu*pD7-C%B#yei{Z!zk?@aL*2KvI}wt*N^G34TFA@)V%n?CguiLB4Xy*_)K7+6)IaA zY((se?2;rrQnRaRG%_Y@AMyTj%2(phbG<9!QE{I&POD!O$t3$Z*yrYa@_OR+gImZ$Y%(qzT$ZirjU}EYW>hZ;HXZX(iNk*p!hA$3bs) z2(5Xo;wtw^MBm_j-UoohUWQyL53%P4jG1g?@+-qFO^za$PZlAY>!g+=Mci~M)2?oP zo_V~sj&Q$_b6_AwywNW7u;C54avOMAQRFl03;dZ7SJVx|HB|fF2 z?V%4#zGI70VCO3y69Ej(eWxsR^@G-1ntcenq?3-;rgx{f!d#lntGg~v+I1Axp8wxK z;0Jh|d8{CLSu=RMZ&J^i?)gX>s`xw=s z+P*9N16*Pz!LIjoM^)+jVvQM&N$GYzBKrEKrvt1b6q3r*uIk3TuPU>l++XX{Oz~Z6 zx;o!B0B#-7-4_dt$6Jq@pT`}Ya9ysS)u{3>pY(6Vf&`s!e4pi4?~lQY_MSViL$Asw zS#QMT+b|d|=Ng7WQ@Z{-^ke=aPxzz7T_{(vj1X_{y1RGfw3_?!xgg$GQp`M#-$B&gqjnB>)yHlDG{AN>2a~zMNLFc`L1P~xHe`!-GSR9 zbUrpp*NbFKyX zI-b74d&OxLn(4qzVV+aADt1x!W=Fe{i!%9X>eOF9FW_4U8TKK9)p9imTRbA_2`+qL z!Q>i~)~SZS=uQL|9(cZ&@=lKKQ`q2=347SBrvv0YBP5mI8nO@&$THyqB~T?;iA)zwDS z{8!l^wZYAD$!^vz1)h+PpyqNLb`X1PX?2*NP@XSJ;ck>W=|`}pWkfAPQZ5@fVOQ0& zSav5-N-EEIdAx60bC$H=z{H8h@2?y%@Jh&wCiT2z@MV)ky=k0_(%0>D=qOLhQ&M(>~ zjT$#*lg2hCwr!)aZQHi(G`4NqPGj52oBrN<>z%)6%{Ozud-u6VdzW(2@mQ5N()4Wt z3g(O}DX9FVBiXmkckR%hqGewiy1!DOK)LQ7Ks%QPWofoRJ$Z}-~86k56%u)z2sA7T(*^cobMh*8DbP~Y}q{b&bOaVCmH)ngmNCl ze0|(U3%ia~AF?8&+BdP?`@MAfc8k8?t~UT+nOZcgEyB4Nyj`t)18rv`{_P%3Pw#X+ zHziU-^NMH8fWxh8=HsBpI`T%`-to2A{jooL(>&_2RwX`dUqX1?q|pwr_RW=hO=}xA z-#u4(->w~*ewC-cRgCE^L#)`yitz|zLDoq@BE1J_h)c_DZi1Caql@yY(qwZ#sh?0bs|E7jy|syV`#ijH$pYh-2`DLaV;e_qa`5KJpd(C`T!S7bFW7?4cws`z zXwTsXm8Z!#%++0E+G^> z&EdFsZ)SwR7}a9`8Yz=A5*9-~nKcB5#S4eM4wAJy1FAC%!#SlVug&oCn=3tQJo31#?)4;ggEZz%`B8D)akcVVJ5}Oj5T0ei?8|d8)~g z7p`r5(rX2n63wXhwyQ&IHya5`co|_BeyMp2` zxA)Bfa+OU@4fFC*^crV;J8$s9#o#%U`G10{S~_^P8;G8W>~Pw;uX460txM+&n$8cG z-9esDw5uB{{6oZME>C?FnM0lo8;yEfoUg2`z3aZ=A$R&$aKbcQy-l_|oP19|gw){z zeB=UY{{HwtX>kj2?0N@L)1`#*qrL2hQgP1C#bNGUqb+BTHNgxwtNgBb8rcX(^V}3ART; z$;fXyr`K-SE#?ME^f_tLN@fKGINu-A4?^v+(8sI~i`hgu-yp+k^^Ce4wCb;ts9K|| zaYJ4qtKO8P+9!_2So2P8Lc(J12Gmr?I{LQpt_Q;Fo`Y!9iFP0Iw|T-auYR>FaliiL zI@fEJZY2;C$V(_FL1ie)z?Y&ElZwO*4@d{M&d`#7clY@!O!oh$R_@Cl7>`dRw&JHS0oU z==-m*eD%}5d?{3PG4YuS(}#2HiI46lCz{TLLHfeGGM@G&?ZNmVE%mm5= zs=nGTkiszR3`t`czhO>bgDx!<(dp}co@hXCK+;#G$6FtRi7z|v(y*iyHaoB)BczxY za&&o9;+vQdjL*n-PJ8L3aay5(*c|?&umK(vo&ra9(9{feW>)1@V@M7`Q_E|@`X32@ zB7ymF^23;1YK22W!#&Mk2M@i>6fqI{4|=J#)lcKCTO3M7s$aK=^tj!m#v4b>2vTQ4 z;~ULB_$^e_`XhfzvCxGPpcExcVPEc@@*D&CmC3z};reAHMTz=i%_k~39B3+7Sc^Br zTF)W%dHEinH&Z=>^`|bxq@d;bkx3Z2@7_4)rA}wdIIZSkjH<4G*OC0$01KzjkRC*% z(3Tz@1oGjkP>zjya3N(SAowF`VE&PC?`F;YgiXk!G7PDOye&ms<6`_dl=&8{F8_PH z&(X0oiI!C2{X}jjxPhVqiugH{mO5Z>)IMB%gwJ5l4T2kuST%&La|<&FV7-__k+_Yq zOm-|*=){PWQiCCI#`}GHCi2c7y!Y@X6-k zsBn@DO-j`813n4jRVh3fB;Z^i%7pK2Ffr_{$~Qju#i7BeTYF|m>~#!V^^G!(_^7yq zboQ)1mMGBGLy#R3z~uBn0kewO{wc{Snw|Gp))@#31mANeflZjYfE5u{aWtYGFh{_E zr+{81T{z#NbEzFdRW=TRQh#vLjE7pjEbQdSiWiIE|#G=)mQ&Vse|R zAM3?8f2OWQiOozW7hmw+Z~`oWl8;b><`IC;bn6Ft69jC~qq2qvYY<8Y{y?Sk5;b8z=XvC*_%JiWG*)@?lh}`!_Pm@b1yxDM*wDXS=5RtVpLP#LhNtZ$PTO8r(pgph|x+Dx;~kz8kV`w=hjF^6WobahyVbYN@#QFNnggJa}Z(b5Xwv<)9UYb z6?ZuC!KnihaX|}Kom(;Y(D9^Y zt?S5nTg$2sJG}Im{eEplH~6Z z6oSCPJ~gpBY_S3H7Y479gbaYP*&Hj_Wq}Sg&EBxrsjUi0d=6(36`8Q&qp%EF5iyU5 z3}cC9yaGI!oN>rtgGyl`nQQQ*S_|uqh$YnwzY^iWSuT)kBUlipon}D1NnM=la=bpK zJ-wyF)B){)L~M+(0buvv6g$RBVx0gNi!WRrRw=d`1__)4I=WI+1+06g=oAmd6>hQJ zdV2)decYn3VfX05_D?iF(4SfqG3tz({7-PL z6auk$82DW^@{>upvv&9mUidIjxvk(%Z?tbg4HXqhCHFACol+-qgrYelDS1WE*U?#L$ zF`zR9U_RRs&mLz^M)f!ErO-%o(aViPy*5}FH6F~k1 zF+(B^V*d<`w&va8Ib~TaNj9u>JhwzapGx^*7ljze@T6q_jrpN05#wn8miZK{gCrw< zg=9BzsWyyFykw~hbAsE{7H4*W%y=n>ae!H*2H~{L^>d>nv;Ey!EN_P(YRz_fHu1Z# zdz2|0v&>-npkS7<9f8oRJapRHfYDl7!+*g0t%x=}b}CH|Oz^hYb~kgjT8&0dSDub^ zH=84W%-;D*()cljvA)e7a)N!ukj?J5;p*BFbmiC*LFKjSDhlKk8(07Pz3}B=e#Z%~ zBV!~6S2?)JI%+`&KoPU#I(AJ&;}W|?4J_chPrzrto?nYWT3Dp;EChtfSx_s3vnUba z@G!H*(jPB+FeuF_$P~^}t#hdH4|QhAJ|0tAE&=XmB?_6khzwk_3G!-CrkHjKhBc>2 z(Cl!{vST>2G9#fx=?E2EC0)C5HAnD9&)VXjFCxO?)y2t>Nh+zN8;Z@KPo(UNgX&CL zZXg{nNg{vlGfC~}oC%adt%w;R_PbTQfC94TMCH9@rI4|ra8Fwjlb`p;_qEcSCV9JL zW#o#KEkI_ksQKD43GM>8vAD-jE!o6-wesa}%sIXmKV@|GxPX^P!GQYZveex}!At?r zLp;WJJJ!UQP3NA0{Yp4}Y|7;Iww_gtD9>MKiF^UoTJAC-_H9e(*VK)A^j8aihNjmW zW@{?>ue`_yzNLyh^=4Ej=*pxfS^09RO9H#?+6VxzAn8nDnSr^Ur3d3{#wSx(^8pR{ zL1Jz{be$7ailzQ*b^Sgy5IV30e7lUbA8wOC!>Q~(ziQBi8W5T;&?8p3(FjN` zBrAb@K5oNpPq$~CX%loun!80=CV)~f2YY&WRr8GF!;Vjrl1rXVycLf%JX1koPF9b| zp&>|t^dNKUhMAh*vm9?@C3kB+@edT*u0Lk%G(%>uNEOizbP&yx?`dTkw}-etmjkL` zus5(a^K?JP-lHu#l)1rogKOv19(O zs6Hj7vNi?KCKklg)BmEwC|Zle!PdeNV*yn_IIvl9{EWgGs@fG{r%Cu@P_ByxV1eDZ zBk5I`dpjA2GUbsjPkt_IQOT`D_|;qt)D!xV+b4?*t(K}ukQGiN{$u`DP$4O}8E1zr zU=T-Iw4;v|s*3#NE(E@lMk$2{X0fQjtc6r;&~9>QRRuQ->Dj(|ivHl$LUCK{;P(ga zSLzgDn=K>yq3#>E<-lURNkjb~f-fL*ys(Q{K{}3GJo8S4=~VvVSk{~pRGWX7G7u0^n<}ZmDN0H?2PPhe-epRnj-HGJYbk`lrJK zt1z4#nFW3}18l$WW3b*>!41<2GHoIXnaS8$19@UNp|DG0r^$TFWLL}{hOtI*@&Md- zv+QM9$(alkgl6?uUq+cKU-1FD095mcCZ}R}?l}jX;+AM(77L3Rw4B1EQ7tVEO1SrW zhK0On>YTkp8x8PaA`1UF1L^p}SeN<>4RO3S1n7wm+#mN}=YOfq;1kA~4PR!GiijJ>DHKtLF57BTn&~@~qXzW&_*dE6HrKKsizna=(MP(xj@QCYc&&`UVB&_-_Oce;| z3-f9Vg(i-2w&8e7oMY#~MT}+*+6c8K`UY<})}Pe$4UEBHl3NEgsot)tEs=ymU4D+K z(aa^n+|cAp-upda25Gv}WkVo2tYlhRSwM%_mU|E;^CSs{PeEG2$f0wK-Z8bBIbLMJ z0C;X&f2VrLz}@(BPQ!wK3cWM)NUB)@QjJKOY@Trmr$W?49)rVPMC>3O(5WX|9m7$z zWvV5BFZ)OELew9!lAmmv6Og8Fk+!-fEeu z+sT3Gp9FT)O);4gWY)jlKyDHGWB{YDVPuo$2I9t!sxK?)aA^+l+Dk<+NSAEG$?V30t-p2{>TvAJE~08B=9|Ti}-Z0LD^74D&)*8jZr=E$6O;mL!1rK zuT}W#ab-tG&`}$dCszK5@w@}9#DKTh0xPZ@tLp%fY>v%bdnx{|$Nc03Q3^qFfH}zA z-S>1+cPh3VwCDZiTz|Q|75ZEWn0~|CgS|4_qX9%@zy>@0oXL+9mX;+GH#o|*fp>>+g?;SdS+3T&1S$(`*+O`=z68TanQg+kI0+U?VW$Eh4Uru6 z4+@l+HVU>^cE5QC3Q3h(_Z`c0ecO2y4rQ~$A4HrFM2CP3?zjEa%~eM!$yX#Igr*ws z`4-9U*1=rOtYb&C?F=D~t}0%(3&Q>;0zA0M0N)pl5U`MOAeC(h9DCPeFw*7GMh|MH znZOkR(lSmaGh>*4NNFH3Q5)C2|3Sz?rF%WgVq<8F14Vy)>J*m(R%GTvmg<#@@=(uT zWDef>`cMpVuf}oMYYJ#J!#8$XKd2BeBwzw^!a$XxY z+a~9T;2$4H$2$3np}Bh)xfJ$_Or+8He5=$_i~!&tO)MHpq6y<23rS8$~gRbT4^@|HxnOc%KP!p+fqZutBO4nlVoX1aH#dDMymOBb%AkSX0)I`n4nH0RqUeJKePJ2W0oyk*2kH?45 zP(@93r+_YeU=fjEoZKhb@9x=tHTG~?FHbvLKPhQ@h<58N7B8CA<+hBpxHL|2jQECa zs7P&O@*lu=LLFwqA}Yjbc}iS2m;HK*olBxhDZs)KdB$n@j-n0A=vX1hKLjWK0f`(X zuhnf_Ad>cgA>7Ee}v2%Vo$JO&^AIQWOT9ft$F{ z;Wr~KCp(0Xt)ha`M9tYVO|221DRhszS5n#OKR9rmX{K$&CGG=abdleKjEtXzzwVqo zg+o+^M#eKXnpGNeJ{z?l{_#q^dAWt-8alJvpnI7**Pm=Z8_H-XU+OFdZ3z`P_) zhr_X?%M4bnJEjoy!4Qwkc6I9yp+@iF%;PXk7N_qgqZ;8{#IRX77m1{W8Q}Ql9rJ7f zjI~FQDt2*+f>=Zp`W9u2vEd33|3V=KU7(_&u0w;Gn;NF$H<<@T2@LzE@Wq~An<0#& zOekfqk9i9}%;UJDajOhc8f6F_dLqTAnk-C?Xr?F=HAu2yz73#oy|e#uw>SHP$pK+= z%S>G5Ha%ENr(ZOCnYGUj(=b7eG7MxLLW|bYO4v#^nz%K42yL*q7Z{tY7g7tqw1L^X zZf_*akwoD7>6#_tCJ_y~7QzT`$k+5IS)n5}pFCY_1)D**+Qi2AvUqI#Y(BcvEXi!f z+E-Tl$osWJ!j$c<>?dW^{7reSsjWVdX16sd(I}Tmtg2;#5aZxn-g0{^KZ{axc*CXo zIH)*_q`pAjabWaMiMO18DK^yp+)3m#!_(pkodk;Iz3-(*tM|{xt0f@dYvlL~C(l%t z#2#Sr9_He?K;=5FLUHWq{+~GWNJl>+Hn2Mmp4E*F(6Hp=ff{#n$a=XIxBo>S7_2DH zH(5I_n6gbg?Y zclc|WpwY9L+QHK5=n6Qsmd>+tFh!}B+O5z7<}icK4v%hA*Fkk~#O3m2tRwNja(W)Z z{jz?9kOMU}TBI$05Bv1tC%GeGwge*cTycz&4iUy+SWDuuCZ^cnSfC-13l=*?0fxDb zU>#LtGKHp+$SLxs91D0egGCy^{NOPp^+zeOKIMRW~{2!#It++PK44_z70^&CBV+?R>IY`Oyr~El<)U`OxDgp`8b7fNwFhqPya^l z^DrSdghH_gDKhAfa`KoLngfp3&>5NyV}_ZtYB5^yQVOn9|H@Rr z?!$oqwe*PO>%5y^iM1(wh?C!d1n~g%s0%h5N8PeY|V=mig8(~EMuIobxlR$RJEO| zO>D`x%XBDH<;2 z*5th@j)=)z1%c05^)%dL6xX>NjZn@A!b3D*+SNny7Q)Nvp-|`_136 z=S9>c#P<+Y`|hs;;AN$O|5+U2Qm7Tv!Ju)4(>mKmHfGVyHze}`)a{xiH)s(**LHM$ z{B*&A^rQX^5l*p?#$uutG(qg(-iy=c=itZDmMQ86bETnFot}@oHRL1>VDSqN<3SKgu>9bh z&WSdRm48bYj7oI^H+}gXD^_^8&dQ+MAacTNv_UaHE3k%=+{casF?>g(C4S;y*V_*m zU_xcJFKx+%bd#&i^Gbr_nobH`mHzRU=JR!@s)q@kG# zE1a$H=^QDGw&SB3_fKZv8=ru0W|pW;yQCdXm20rH?J{#~f5g#~<79$LzfE2A3%8Xe zV4~DRjYXf}`U_IFNkR-XDcu1X({vekPfgVDo0P{M&mk7Mbp5H*jcDZ`=AKo8L3dF{ z=l3X~q>S39SC-KL&%%CcF5iXaz|)__@Q)~14j=m?)iiEXPRr9>!&Z@n1} z*JI1E|F`0ZuC}>g5GL>fJ=G+IlVaE+IrrRpjK8EgG#KKH*__O`W~rqQQ1Xz-dYcO# zH_V!U0I=8s7643x%xIO8{80uVTd`4_BeS3{*aFDC!7m##zqHzk&uJEad?TB2C7<{_ zx}I$>Ze-?!&@TK9O~|WFJ_)*xfFS!!(>YDmX#Bo=N>{d4GF6vkW8X6)G- zuCM3n*5SRAl*0=9VGdgm;nmv-8UL4l|xU-|qzX=;Pm0AS3zOezD$O0)Vv1I9SNKlMwj-L61B zw@bc+qU7<$3qFg;OyUYssgg}WU)Ek(4z?>1DG`nXWSBmGqnJtQqDZep9DME}(+gvi zU*oQ#Rik)!AGgHCs{>OrpWl+*HqjY;Pj2m4tF>|bsmFKd&fZOm%Xx0|_y9%N9uX%~ zc)4v&!$d{{?xM=k6rPiUMaH!Z`!Q}s-ve{3ctOO z7xEvF;IufM&Qv62RJ^cGUTY;w#uP)#<$Qg+Y+*y#f){WE*}{`v*rw|#>t@wrGd=F&zcc}VaSiW~^;CgKD(deTiO|@c0Z+T9;2Dg0P z8SnZ%qj+5%f@OtGA~j#G14EfJj#5nHZelwLHw;-c;5*f|X|eDqhlD2_0Wr0%kJ-Qg zafD{3HX=PohPF8~sTfAcP@KTzazR;eRu@Nvrpmql*|rzPw(VGVHz|jnRiNW~x*54) zi1XFV{mY*kK-%nvZ_4d=T z_xKPrcFCe8=`Q0COzo^?SglW`CQ+qu%$nf9PHL7MLl$l<)l6wAr7xNLb@P=YO+>2C ze$F`S2or{I*wKI?N#cJ@?wy5-F%l3E=)Lv7y25bjVhE@2y#;XNd z+psGXE}GcvsLXK}sUlG(CO2PqY#ziDH|F-B5)v=eorGZU=3=~*bxhx!kvTO4qI=A6 ztt)J}An&eNwx<>_^b7x@?lTwPa^MUZdn%K?SXX~IQ9!o;=A;&56~6$HaLScR$zf+E zYasSQH6UjmZZYTjd2&Q@s@W(BV_;i!7%H`{@MG?>KQ$m+>k;YNIN;AuOBJwvYqC@u zejIQgnL37VG!`J;TM}YF2p)uFp{y&`|2Zk3aX>UT0?9h$IA@!`=k>tnLe-sDY8>d- zR=xkkiu1WpsSJhw#wzan40^2z{+#s+kNIz@K}##Tzy?HRo=g#H8vtCU0ZZKlJiid*W{!Yt4H z7*axq`B&Zj!I@#9`SX}49sN84D4!#=-36||W?=w!=t)3SE;u0TSmq#Ff?mEU>Q@DG z@k1P-%8IjUYK$hj#GkxQgp0d2)J7iJGp|9w0lm;?O<3z_*jp|L^xngsNQasl53A47 z?wja?;T&6s(8%>M!hY%EYkZjEdgbC1P_Mxno8_*l+C1l)L6Q>ln$Bkb`qDkR8rLgI zI=v$jv{apD#Q_>xFVHX=%Oif6eJtmVvib!9{X5+(eqSxNdMMdHkJ?)RoqeHocJG-5Q;} z1&=?gkRZhSTdwsF@C7_P=EJL1+dxfIi} z6dRt7MC!_9_NS&VuinN-OGT}b-_ts;uAmnVwGC@TAa%H(?3aayY8JZWx z@Et4@iBj@v$XaMWbG~!g5^W?2Se@{)8f!zRUo`J~^istYz{x5L>0vhHRXdjwhaqtf zyF<;`SlIepQZRTMVr4DaGbqa~SWV`t-+aH)V;RB$pF%U(dQ$0g_`GkTrgj;c% zL_(Ij5@O#88_H0Rvi>=w*w`O_-td|yErIZ`(qly@0Oxse>6dZ{Z&L!i>Y$xF0#;fc zu)U22hz^R&LPd;G=w&>B(7?%e;Ko++N8e&-2`08O-X(iXVJ$!QPePw_W}UDkYsjh; zk;BO6ii7^arOZAMl>8s=)ABvAEbT8K=JFWd$61m`GKm0DWX|243K9etjG<6ZBWsur z43(|h-Yk^IUDIVp2?E4|Cm2C)k#^5C-dTVX)k);BT0G@`GCcy`rY5HjoE81(5*hnr zn;OACp)u4gB0d%5SkCicA1Ns|2ba^y^!VOs2Hk9~>~Bxcq-N`NAR9AoA`}-0#Zgq8 zDD)MLV%WhbycHMPz23H%d?H;9njtJDdLiPP@D{&smDB7ip&*KOdO3petoY#Xhk+Jz zpy2SNpFS{dT2?JS*)s-Q+ZkMV!h40%>lq+gfjhGC7}Q<0$z-o7{OpeeaQG#uhG)OiU@KDL)Lt z)({-xza0_O2!FwmwDnSDvX)4o=lGGO`Dt2?Zuq6ntNcptXgXeb*{fP7@-?rDpMFnp zVF2uA(uSTBtyZli@)X@?A2$9i5kWdsCC8vQkJi9-9GYJ)%q@jLUjr)Uw;+|uaYp^& zFK(EfxGbGYuHX!Bcp!}Q>KR2%OwjavTD7ZWlBR0o%st%A?dF-$ou~x`7(<;q4#wJA?jfba&DCbX z_Fp-^;|tDE&redE=fui^Ez_HR&FqpxqeQ{db#Wo8+_hCfhguywz*r0yLWMc<){@~Z!(^IF&Q8o;r`p>KEJmb>vtCLM z-yv;v1v{gJ95}wQ3H5bg1oQO`7kw>|K0fimljjpOu5q5ACc6dbZ`Op*D^q*{)b!rP<|4jRU~>!tYoVxoS^e_PiMg6n;RD9xi$SvBaQX&rA#*XLux zYsU|&FN1XzoOR=OKjY)((+2#X>Mr+3@71D|UKpw>x!{kF;_iM7M0Ri)&X4vMliCO=r!=&p|rx+Sn$_U60F7jA*Xg z(upfoj4zmE9dk3a>ez?+oR1tSI`7gQpHY&O9?SYk$Z^_s%ORrx_@$7G=55eq9e0ZB zq^S8B!i*M}7K<)QFb7=-nMra6lH^`++QbuKe8YCMgi6^d7gU_4KD}LH79mmKY>|Jldoe@+pmu& zlS`*%Z4929Fxj3C?kpoA0M07!>+GuSmfMl>ZVcD0uG*WEMZXEp$H_$J2w{Y=>>r=U z6$2NwvSv{0gU085{I6K9(UVm8H@35V&c@rO}%N^KF9#_savqLz&!~uVt-xma2 z;i}p%IoMv03+kUTtlOYj*DaZz7fN`OT8}bZwj$SoKO(0!=4*R@H+ucb_aIr9*1_jg zF~|QPS-a}5lZwsxo1?r7x{c4<`p)xyOh|2@VL4x6JBg0#ZqT_~F9b%yY)w!jFu9u^d@ zCvCi$JOCf}e{?^}QM^Y8p!#cv@yLd{@1{6+S52}Ll+`!6BN~T@X_|Z=$Pj+nNJnMAawsS5Q6|r zOwNIoUpAMkp^!tLOidkw7oAR!Oc>< zKYK#)cpCB9OpI~wKCatLk1g~ho(KW)agS0UIs?s zibxxf^$VsX8Eeb(1cZ@mmqsBq2x|m4Qvx@8BNO+e9;XU|vMCSiFg6|tU z`}Kh>i-QP4HRooG*nbH~q7V~+VA>Wc1_?hWXGIvs)xvimllZ#J5;QA*hY8xym;+z; zvCjpCEp7ZF%hbw@Iaa$ZszfM%=xHhinB3oF!WalwGO^NxY82 zMPf*91lj|uy;?&QdDs$UPyk}9m7&|FRE(EPGyieY)jO2(w_Mj|*u0x8vd8RjtNG*7Zo77E2ZJAEy=-pv&4GG?p!TPHJas-R}@fIu@1G4;EFe zYwQ(H`%!>C_p?gXwivd(@2>ke+uxynddeMkJ!O0Re*5V>vNg@~W~uhu4?<$?DBFvc zbBD>M=>*}r2Mn=C65Ty4fvW!61R((n_c;h`H;gPh(C6c9Dl<4T;V8$4r(+MT+BXEx zo!mj!{iNvH53!@0ORQ-jUhqs{X8SmI{emSnpf^vaK`AI|QV;yi2 zHxVM*v(??7?lt?-oPCP2JZY^L{FOdi?iP<5z$3SNm$QxdxM5K}@$r5)-EYMG^LiKY zD!q03c?+wi=lw1vL;2|bewJYv7tEpaSXf=6#PehW4qVp;vQ}xCi!p;4dp~d&V`r3KJI*FH* z|6qp9b*geh_Pw@uROEVHDd=q5KcQVa$`R%U0 zvhIA@^=AG28mCJ){P)W1%ENX~oUD(><0_#Q-{ZVCo4XbRS9xg~W_7o!AZ8TN#>;zq z+CemZ*< z0&+-3-C>eteDaEASqoO@eGj95A;1RD2q!$bAW9t|c8vJXivvSlIES=>3Edtv8hLq+`v+^9UwPg`m06DIhczwqziJomE)E5AC>KJQC-{blXe?`7C_ zg&v_46C#K4yigz49H!4dN(;K;Dy1=T22g`)FP<)d16~&kxTxC?MEEDG%%aAZ4%6&V zGCT*UD_&2VdKJBsNhD$hE#bLw=y>qu3A;3%qDN@&iP8q>kNi~C=onTgS1wV(K8ZV*Hi6{iWRN-oKey6a;g6w}c zH`$scTsM86DUDObX$J!|83arKykshFgEhz8p>r1DIaUVxRb=Gg5Avr~#A=FYOcr`e zHp5Yn!gVRy!KW~p+#nZNv~c1Vr-~WDJL+JqKqlsN1JpPc zacnBys0ft0NF3p*$=<#lZ&Zv!*^gJ7eQM3ODH^U>yFw-;B~fPN%D*ZCEqs@ne<`!u z4x#ZL%O8EX^oN)Te8SzXB+&-`vZRA8SVl!JS`1P?65T#>B z7ci$1P=L;=7*P88s4mUWP6wZd$-s6~=n9-0wf1YH~I0vvBsVZ@pYY=i-z9uq~Y2TS|ariC5%i*l&h$uo{ zQwx9MjTy1mP@0v>S)zUyzPoc0XeH2yM3ZXCSNS_3NS}VnIVmFd7dkRSa|d*9c<@3& zD~DomRuAyY&GW_ZJ<^+F@48>F`{QZ6V{-8e^EsJ1V7cRv<+=d>^E=PYsBE&gs*W4U zdB-^IYI`g68TYzM4qe;hnuT71bh&I?+B)m)^p8WeXCv5tN!{1E^UV#V0Emvm>E#{` zi%MtSYD+Kkh8;CbE4v+YMR zF+TCUozI)|$?4!P)>0Z(M5S_Eksmyh>dHNhc?3I6+uF?L=RDB^8gX6D?Q9Q}RgJCh z)Z1db&J8+QYgA-r3|zKirpK+v8CnjKHFuV~KUpe(qJC*whZqavblqH@hfF!6eY`-I z(1UH!(S&+1#d$UI{P9f2J32oMaIfvz7lQpcWsCJJHxHr|RZ};cr|gjm2j|Bk5RAP) zfuEVi&D(KSRkLcG!J%h!cH-;vewVZQ_QK1F@4TWHqVqP!%T)i2EZMVhH=$VECQxmK ze9b`MI)o2>aiqkKeQFG!;1JmU5V!x7>N@be;3|nb10XYFydFHk#Jl z0xgcNiLzna4}bl-+|AQYGuyXOXUa2d^83N}!*Uxrf-bJ8Wy5~l9#2d)PEa7g$L zYpmnlEC4?QFQP|U#}v@(J^QGR`B*%z9nP@bw-EFKR|cWWyWT5;bMSD-+xeR2aq0Fu zn*DHO<51+!_Q$2mtU$VJ`+1$i6}!n{6M#iO^(H%-=@3#jz@_s{d(~mZq4wt6>iA8Z z)RBI=oMqR`A$Pm;_W6hAHV17x_jT6Q#QH}FPlMzV@42hd{k9C}1voHr3JCb9ctmt} zK9Lvw`H#l^6YIR%`{ED%n`OO8vj&bbkh&?vxH(YA$Lka8C`nZZ>oC>p(Q<+*)nJN! zm0`Ni69E{5#036ydH;R*30#V)Id!}%@2B>i0TfyPGH{Ck%ntpc4Fm?(&|VR4&e@gF zCZ356$B&0)x_#@$hox1MM&7LqChSxkXDEMk3k2#GClK>5{+^hzpqD+1vYS-|7lzir zR^fK)dBSKKMKFi`O7&`_ydalMfQpPP7q(B2u{TEr3q?c5Q14ElmbxHb~*On404Ds!+Dd_(pE zbL7g^UkZD@dN<@U0zeS@J28_w2NVBMgEAUZRFG$SO^2)@UwJit4X=4!iH(GVkMD(y z$9sPKgLHV$zQ}#t2U;#a8ge%L<+6D!h)n2o;Qk*rS^Tfmn~vWRuADj8umaFmc4jUJ zXeUQ^R{$$Bb2#bu{lNC4Y>ypTRh=}iJu1j?>Uy{h_w~wEvQW5*p$i+j535IZfq*N| zH_p}I8PB`Plvba+jP0Hho`*8Vu2ndW_v`-M0{jotL)IL^4a<6f$rYW~NuNx6>v4X> z?{S*uKw%7RW{0cJr>!YHn)+Eo9s}12KzCXz@2uwgKJN)(BT&R?Nxh`m^f~ODo3mmu zS0?FBWXMluJvi47sx;ZF)V+v1($b42_8Z-DjA1HJ;5&6X+3Pw0KQI81oy}p}dEM$d zOxE+83gWdV`>wh=4pWW|(|}2~n@V-mB~|$K2od7b-usWHHFGLcYGQwGEyuIU z=DwdUTX8={a5?EWv(~%$d#5}wh}tPi)E%bm-zQ8i&Ry-kz@AKUxZjV5Z)=BeiPzei z)g6aUUUoOWC=eXfxjvr_Y-jkPdJ|;1)1aI8s8j;8T-LBuG_8~|B?qKbK;FID1UG;$ zre>}DPm;AFufr63iJ-x$Nt|%_YwMTad5y}%Q6}32(==CSn>zP;Y!ondffu?nxn5iD zV)f{1UEzA)-g?$Uu(#5}Rm(}w;bYEyloOK0Z3Z^J!3+fhp}gDh>QHV7_yq~8O2s^r z1i?W3U;ITGqI3ieowXmomASIhd9{g-=eh&>Jmu1r;MBMu&5dq6$$|ll#92u$+RnQ0 ztf_|pz_rWX^7Lq2RGr?)vzzuD@&E=-{v^qXh%Xtk-d|_BE=E^}4o=$~pRTDAuDcNM z4pZgpp^y>x=Ryv0XP50)qZ?HDf(MX?zh)WfeB9hpEk=uy{r!H&Hemre-j-5ID~~&< zp2R#m`yD6qgW=fTc<|!_oHTNrXGwKSA=7_AvLsdDm%aU|;-pYzTCHI7%B`7aG~6J(PV%L$X$ zV?)p+rr{C)J<0=EW|o-%Tcjptq_NqkTFX48V&nHkc$S<#*9L6xWhy0_OoUguu>>v^ zr@4@{kYFoAtn`DQ^OvE!7tOwRicD1g3Uo_UWMJTEhS@~|6V-dM^Xv??rbe9%TP@A7 zH3Lw7oJ5V}GXf+lft!nd-Ey&Rjwpuf8>eNr;EDIaA06nBpU!HJ*4Ab8-I4F>+n>p; z7^yzMci&&pdJ8cNu(~Zie@rV%(cy5&=+}m&eb%pecp6jfLPpm(CRwHPhR5@Hzd6O| z7FPax>i(L{_W8WasRz?|G>%N^_)B7YN7HNw*iiGlO~?rZYOC^ke2LlAx@|fw2R(IO zeWZEJ3S)qlAmuYtA7=P?w_LuS)w$HSa`ii`$KSrd2?12N#xHsMK)V(ApIeeC`y5|% zvRdYqTV2=kH@SRXPfG4I?ZN}4))}C5Kc9zrjdyK)hB@nw*0&y;&RZi}^D0FxtnnGy zE?f5NO3c6@4~x+qd~KF0-k00ETXw#!EaQ&c!7S(uyDHy@63|f9S@?q7V(-iC;2dZ4 zKiYWsChC9oeSN-Njc3=RWw2klFSqZ)>ax`odMvkZ!^3u;8_Do*d0cf~Z&__;1Z_Vz z!)XoUN_AVoQXt*WJuK2Q&F65S)NiCvj>t8~R(=~J9 z+K&)$dwq39u8yO7W4)j5>Gu9Z7i!O@w3pPT8xb6n>738MWVZi8+BwMsgZV!?ALfY! z4w$YvQeW$nTuh&-0YgWb3EKmPHomx2Vv=-%=iN`6DNh;yQZ2SzYv(M$ECB1n-RF}L z@Pr>8PS$xF?;}hisLZ|tS1cHq;^OgWHt6i+wgG0#0#0C!H|8ftP=-*JbQs+y-z)2< z&Y0@Yvpp_p5iE+rrNl7N&k6p(vu^ybZaXPHH~WoX&iyigLJw%`9j$2Pe%iR30e3;Y zqqy5o?2ln1WCr@+mIhziMIP1*!rY6UW%+?TCt5EIWl^5K(`QW_sY!3_P$Q1JD$dYiiwL$tM}ni=Y05=-rn4!Uvx_q#A(8En za~la%?QzgoIJr28s0gYQ5tVHAXLW6r;EZcWu42E=y2|C+2e>AB7SBf()4(>q1Tp7z zWKIjH{~`dg*7{V-2|Rx3#pc2qOIbayiBsY5=&k(b75($eI*iDv{~v0Nf@LL2ND?ql zi2g~1P&p5=*_tz?tI2fKx49UaPuE>9vbS>%F+TR|pxXV(W%g=H6pLUHMJ13l#zKxQ z>bL#la4#4g;Tld|ctnI#4ofzU{x6VOsr0yEqlEomQ4@Ixf5X4XxUZ5I0C}JHMFK_% zPoan+y)>u308ep16!lk4FZL0R^;%yLIX`bc+<_P9swav&I+cxxFXRhCY`RcyBV@~e zju{_n+I<%q#M?oM#4&O54F8E_uX#DxiZFzt0ld7F$qxU{ZawmAzkGFhIiYb_4{RMB z+_=@hp7!}f>3X1X&=fIxssttkR*z8N4uKo~)|iOt$mhahIdJ=H_v!j?f-I0pSCOiv zZPKK8>vgI55J3KL-Q4}f-OfF}bKQ>^K$5KXjrMEvAZ`8q)b*@#TZPoBYEoA(2u<(h z+_-YXp=s4Pq`8~B+wP=N(+Z-y<62 zx%jWEh-;-o161Qi5J@w!ead2c1MI%!s+Bi$y^00lnyfi(*Yn;bJdnw!_;IEmk@HOR z(3q7vxYKR2iT%!uCSVe<{jI9)mQv0A~*@>V1xBZFE^LZ0vatTBr&f}pz+w3hMqV=bA z-51@;b-Zwm`$6H!-I70?vw=9_zXo^=Mji#o85|b>0YhX1LEvHQX7AmYc-p$y%Gew+ zq2GSL>+O%>g3DQdb4Yue=|>1CO3{Gve)to?^n}-b1v-r9K|R4B>YcC@q4RgE0(dp4 z0?n|zC4C0EGM!=o5)PB2cO``ZGx2{&y2kc6v@IOlw$s?Qnlx!_+qP}nXlyrDV>=V4v2F8C z&;0@OVP>Aa_sg{&)}3cU?`FO%S&_wBSP6-EWZqZ_{Bd-Wz#d)fq!&M^hvj_tPYxkj213>(=ZAM@Uwr8BV?pTt{w4zi6|=aZU0@9~m4Rj*QBM5Thfh z4z>W2M^;)Zd_c#vEhrn~g*MlXjD`TG8^oswGK`7}KaHmo7M=y2ub_6s8I1`|jeS1J zU`$vB_`Ndd9fHw^KpyzbUBIpjOGwSKibUR`NmQrtBT*7%T$~5D(8zC;=j~ud&i65f zGf3GJ4-YYcgMGb)S=VC4-!esN)`H+I$-VhPr z_OmN#-+iLL)%0TW$^yY?Utu)E+Ft`-$Hx;<@H?qNTsAYTJVy3Bq|P3!qs2Nu4jq>{ z@yrSOHs60-yX-^YiMFabhp?leq-XQ>%zOrD!ccf;%}}k$)8bX%N2vohoAgk6_q?7~ zH4bPAy{*o${=@f3(v0ojrQVK>O!?Lb> zUld&}jG)fzUukdr+w24a+6ASQWQi|@&wR2S$9CE1S~sf&!zxpUgFc+UNzacgu+B~nV>#DgYTIA4 zCIzsM3yyQc zWq#5ZC@cKOMSSHHtvZ3?IsIf72Nf(n+cxjb6e{oKUHrqavGc6g@;~WWUDtFGFV?cL zZR7Jy|BLqQ$7k1(!T3u*JX3&e>qZOzB;Oy>V_n{akQD3wm4PSAE4T_#bhNO*P;5PJ z@6RKlufTtTtzP#eYo_$m*g2G;7d z@xKw)X&<>x-|4$=W(vd-vR?Vz^^pxBb5F((Fi*yN*Pf-0kWC`qR(DeC-{fgU3)>0X%IKBFSY& z@1lt4{4P4&x)enxT3Y6uvAmRmF5>n}O5z^F$TPE!MoFP{Ay5D32H_^CQdNB5fV=fe z2#y9QdeMFq;j>mnUD|j$Ng`o3!w!oehC?`I>}FYVyT;Jjc$%ieqk-}>T698#2;O=$$ttst;OtzG=cB!Wfcly_oZBO+HbPDzOnelxz+J9U z)K*j+iuxyE_13wF-y7MJ%3QjHqob#Tq&+Dw^u5X>P!-HNc z>sG}&SQGbH=~J=VP-cD3K;M*J+BtU<>Kq{5L-6lSq6aV%zbZ&@&G5g}spt6}W}f$^ zX%=&Ooc|u#K?X`SSWiIOPrdFpLU;}I0?iE%x3T3`2uQTOYnmIxbfM}rUpO4@rnm;2 zCK$8Z&4FYP_yV~)*xRG78{7$6BnqE(A7CveU@mF<;Bb1ehP8DHdT!jK~ zr$`yB2Bg_*8@nLkx0+|-O=04VP;)H<+cvd zZ2hNoZoI0R9wZXqy+YgD*4MPCpguui;@;03GL@|i;pKC(IGB!~h^KICKY~AeF56N- zPnCs{u2$Xtp0@*C#(}~=h(XQE(_HyL=-}D5-g7`BVu)jR(Iz6!o0lc4A0Rha%-koxaY@yxcFuJ6VY>4 zMcyy>8;A7J*DL=ocs8@?Q9E#3Fz4*BzKSgY%x>5BR+7E|OOOJo&Sjs{{_m!_f ztB`Gzy#05I7`n+mTj$Qx&dra@Nn0dcUDribho=p9^GhIGrOmd^AdbMvXlHV7Ol=nO zf0=*>qAB$NWS?#D%)f#ROIqFx7Ez|&&O3BoZU~p)Pg`HYhwJWnzB?i4pIq5R_&WX@ z55loQzuY!q)vGvKmL{_Rbo%=A=bwI6aQq$k$ z{ebmBIsFj(qg<8pF!pJPiRr5gO_cq|^#;>%*V@e-LHqbpfjUGXhVcd9`PY^I+u_Rz z(`q8}LE)WVRCe-gVj19~VV%><@XZ?e7gP7XU4Q&|e@%(S;CF1W^ez16ovb#@Yv@*C z6uS)N$N!FgUr?h*y-=%l%vK3#g*aeAvS>R=CWC+b)mkTB)x=&of_YeV^an>IzOX@= zhZei}(kJCFEo2v}2Jd|S9dIqrIGvKiY31g-!O147-#>LL0j28Y5B1(#AN{DPJYcY~ z*0N4Tx?AN_0~P@>`2;z&3re>{g$j6cL8I>j7zmEii61g0%v+U6SpBU|`+LYF_Uw|6 zO3J|!i<ObISo zo`6ze%@@|P0>Mg}uu(6ozMhc3qa5k^`UGxiY)Hn5p;-JJs+hhdy-m=Z2m$(#(D!kB zF4{>tQDlnv!=r@sN*C}7L{A~YouzFOR{c;Z(5(g;JSv+BZH`jV>)fB*mOzNe!iS=d z%>D&#BY?hgFbw9RlbO$$fC69Yj8GHDgU=pDbZdUW3~HFXX5HTeKEFNWi77N8HDC&j zlSaDk%6s54b*ch6z1SYGk=VuUa0at7B_NWYoVMLY2?pW^hp$m(5e5A7bVxW5w!Feh zAW3DcV%WPXWW`>1VjHi4xk*cR$CS74g)sEj_3WzuO!R((K13sz>q0)x^;0?Usu6Pw z$7sodXP~Tu^u!f3r#ep(M!vVGv0q)4FHTi%?<-4FA8j?ty_ixT3CfQ*%Vy%);*fjm zz7ely^9|L@nTlrhYiT|GTkEgL0QcJ{C!CL`?(Yc2oNc}~i4jOnxzq*huGA6PCQu%t z$<(xxqf*;b_LC|p04~}toT;jiGA1Ml3!g3wdBz$h$w%~{c7fsd%7tDZ(b;usW1%5a zLGre-(rn(PoR{Wn-n0F@T&?RN__QXhv)Wch{>POf+y}6`nY@=wc?`TK#UDhFBfe+a z4)TxICXmk4S?HUMQ{Jpui)y-vasm%3D^3#(Lq0YQC*M|MHJ}ciV}yVam4=yYT>g)R z`AnUy=V2~Zpdv7N@tw2hnB8ebzQDF?ZrA}R+YA^@BI;ahSHZ0EbS281g2?D?|nQGr3iezZ@MnQR8p zQ(WOdeukXs4ZD-RtFtsrq;fnh3o8dM?JP*c=x0xr(DW`&-sB_+l0?S`}?V`19L_W9lw`@ z|7?2oEzdX43v2!C#RLAkN$`)By#iq^ud)s7@YYe_zLfnuM2=RaT%c-hXApm6ny#1j zC(H3MK@2Id>hr2{^3Su;pV!sC8e$%F*FKpIo8LoN*I~JT01!QNc5WJ;2db6wr*huR zm@`wd*Up7dqY%MuCme*PwkF3Y3&IfB@t53kz4GDfC|G64z8TB{*Zsgqf<0q9#3mqH z8Cdpj{shL~%&*M+Uj9LEprn}9?!M+}{%FQvOpd2>KM~F94OG2brq|6FZ3ThzDG|9$ z?Cvt##PO$Pr{3MVjizmHR2&=kZ3HwOa7x&iomuWIg~6RWA60rup^0+@zOKGL>$sL@ zY*E0i!hweVrUTFc>eutW%&Y))j=m)FJ_q$R)CjvK0Vp2$gTa-YtROOe03E^P)QY}b z?~7F5Btg1)8$hWd-deNrZ^pwV%<}F-8*G?py>9TkX+%xL5txTO?<;Asaqa-TCXjb8 zLUVhNXY5`QlrmWRvc3XYv?+SO#dqP&F~gqUyL1u%-Rxtb_Cv#5sOj%uQlVIc6+PUS zlrr>fkjE0JJn1v@*wsd`Z`NKOXy8`2S-)pg763Aq4FUG3!rjc7o)gYV{!YJdaeofr zCxdGPCQVT+7x;rCJNT%4H|+9Fr}g^N-UmXQPH80YTDxAqUuGOC$~x1KfC{IYpiEjS84IQZm;oKA%F+ z8^rjA&8u3wQxCW=%Q0gYNVQGPaEkQ&6SS^+(coLee$vY-Q5Coj6->$|Qoc%=ADw?_ znDI%t8?Y;-G^fg2cQl{4b4X>WB<`h2|!1-wK}?T3`ke&%QV_B}0c3Mn8d=HoFP znj<$I@{Lwka&Qq!wmzzmrHTOo;u``TU>M9{%-#i`-889aY&{)3&?$yeTAZwCJY zRUsiaBBKhki=L<_rDE_u4%j+)Q(T1Z^zGUrGojdXkczXLhasDOOS(a~K8xc+`+}iQ zbC_6)nr&pEY6a3INch1C>yeERDu`TYbtUDRDJ+it6QIz(;keB141=D_Ll1-a7?TmY zTegJ_k5S5Cs>JpZ37&MrA`}=t*f2O-k8#&f?o5e_gIRsEGo+){fzLWyVEj^aRku@S zXFp1DX0e$C`Df))*U&n6d5Qfoh2|SZ2E}F zGpHERK$d&}7#--;JGjzY@_4^35m5jDP`5oQ`HFs61a>Cc47b*?s@h;E7|avsE~y!j zwR@#pleV}j(%AwYF+D8|=g_ZzT=gHY=03`CCa_Bm(&BJ<08oo{_Y>)kJ!d6h9YcQ$ zX}TX1C9~kMi$iTo)isc5a4J<@8Q;scwbbP`+u`pJi9wEt9WnD4ZE$jTgE#jhm*Op7 zMCNZKXc<878B?>IM=7dg&#A4C*MP?!o{Pbtq4Oelf6;s9%MVUcAkuqdBQ<1ZZZ*i% zE}qCPMn@ZlD)8h2v1h0Dn?@d-sdTBz72XyLE0~2vF$z@uP)WP=p6~ZCq#XDE9V^&C`6K70 zq?uhf5_U7E=p@UWOx^^n>>@IW>K>2hiVVrvJqa?l*6YBSISwluFtuEe7e^xRV$nSk zF27lc;(PwKTA~4ISUWf5U<$qVw~h&meiGSnLvDS>!Bk;nTk$7<0wTmTEK;SP5s;YQ$TArZ9Ehiu_?a@ zE;l>lQQx=-YB~_j;<~0`Ts_hlRPG1$4qR!bQpC6awx=a zkXknEu&o6vs^ZGNz-D{g70`0( z@s)>BnHXjHu7XE{bFXELZzODYDq};L#=*oDgIF=r1q%6i4Tdm1UU| zVF)4+zO>g#PUyF3Ych!1lX~;llZ4mN@d({;+Y<2J1a4lrZvXQX*1V(zKTNoeRbm{^ zLCZxGdIP#lEMesOpxUj(_zmC4eQ9t%>GgRQ6;PYww~t_9i3m<+F#?g(9XDmv&n`SL zE@x{zIoAR{LJdvBKqG5egbw51moOL%&*^8?Y7x4WNFmw*Mve?mLKTnJYz0YZoFv((=75`xTG)rpt@q>9EaoA@)=xB- zC__d5i^@)%u1#rVKaY0@YyBV63=oDEh1?01wY*NY;2+a!m~G=_Cg(A#lUU7yr0WI6`AFR>PB9@2DZ1b^Pz|dyL-)#ba2KSG+-U0do$% zsMRlaM@@i^3UnzLYXnwMkuHw8KG_8aI@OvD%|;2Glq}Ikbh~nhil~xET@xiYU4neS z>|FJ>u#%}M)i)z^p{7%9$IP|usM=#h1wymvo$V(pj7=O=@UEtaQk^=t!isu*3S+6s zPZZKTCOmU5aJb}MtL^0i(KE>?Sor={(aPZ8aln*j2K%!N=H@{7&4Rm9L{D0Sn95ZvH{DOmz5fa4bFf&#sqgbriB$%1WTMrc03Dh<*TvyM5f1W z=k-(uwlv0Yw6Cg=3x&SN>Mu^*>Tu`Xpr0>9c0@~Pr6*ey!GwccJXz5eU~NkKtu=<6 zWdGm-O9o#UCcp)^qzNRas(c(z?7VBK)iE;;sJF8m9u%qsU`CrsnaGQGBq9yfTVzNt z#!<=_N_t1B;v_>+KH^hA?w&AS7qE~r<@507{q+$r9 zp3wZ_E2bZBE3n~XBeJK(fpFSgOuM<$&3sv#!FGNN>rmy@8)+5mH`S8-_-c50_ohs zDPT(WwNobYWZM*AhnPZXcYF;jR!;Cn7xa86y`Kt*U)31^MheoL>%7VK9})QF?4!04 z-T*radbv?d{)M}5u+O5BWop?~=4g)h+h#80O`{$T7knC*Nx8W?v*+{72)EveEyJrg z0f!l9eCtO2A&VTC*;#>EuzBZ)IosmFa7!13lrd;59X|oL0Ii^6>~>VWI~PjWxkk8~ ze6FE+2h?sBp8ORHH6?stC=>^Wf)BmtEP@-P)(-yU8i&WI09WvthJp6k<+qWCXADwh zD~bOWF;>{#Sez_ z+^&+;6bvEyE%h&Un!y;MxtK_g53+fS79(ZnQ!tG65N(jnEONbaO<<`K+RAF2Kq6+P z-eIU=!V-(r4U1fAhp?*EB%lYnRJxf%T_b|YmL?my860>~ zMRBp>shvkNzw{SZ?_1qwHI!xfZTm)qvlbc638uR9k^1n=;}Cd$ng#%U+rU zBNczI8jF2VVAOrEg(Bq?7I7!&9@fyZzff7Ui0@LtV||Msfj~*BjEm)H!HEZ?3Q?f0 z`q8U%FA&rMW}2Baz@L{N3Y7Wq*ClLB^%^-J;g5i>AJqF$ z($XAhI*QUeYhp*}*rq~+OL**UQAcaU%VzE3JqkmBCb6)Pef{Zj&~@wYn5+?!hpfE! zdbdgn`Y-l?xx{M3(f{84Z=fC|gTZN!vw%MI2yHm?m7nkS+ z-FUmvbVvYgiyoH5N^}{S?Ba@>#t4pNe;Go{zfV>O;TYR*B_dWC*OunRYR)_~27z~10M2ETZxx2oaN=8$&Ix(AeFE&otOF&h z8*WNp=8FqLLa9dbRt~zAMfv$Fml+xq(sX`u3LCT`BT)$qe}_WRhXn75qejzjcOHRB zEnq_Q3*npOA1dI;S#a*qzSX1@y}}(VDW7ajy!YT{_HPa+4hoZOW?c%o*WWlj=UJu( z@NhVF(9X$77nVh+YyN47I0>{tkLV1~QqfuKN$?+LNu$d4)_%)t~S_ob# zp6@tfs1*NI$&#UL_;*E+d+lMIf{AhO$7h~IH(DT)5RMLQHbTar%$eC7wDl}RmE;TO z!s>s@(pya*$F9qJgp*jWO({L%UW!eMp|}7DmR2+66^SbEhHD2l!7mK79<8_+VI7HG z=tiHV;gLn2)k)fDY9%o!iU+v?+r5n51+J7`bpcg6S+|YK{!QwJ9~B5Kxj%^le^+Bd z0n9CGRrzki8a%TVrFNW0ARmG~oY_nUIZ|EuzXwx804d8b4QKA4{n|qTBKh+T|R19 zjvaOpIt_8Ha&D`u^t)Gu4n31hv z8d8zw#DN`|`+0NvEOri=hbd`JHVzfLd; zAMeUI3ED3!zO47)VyVA&w;)UANsa&|bBp&SQf;Cn_^krfp?#sBZ`@E(t?j(ppX-*{ z$#H1iQ_=b4G_q1lobbL5HGMcr&1{}J=~OOE_$SNGdI!RTds;Wf)yz$tl)py;#lb1W zsawWvGFR$%t*C0YILUluO(PV$lBAn8^S9F2#Izoy*`Z^_IP)gP{b6kN$TPCUNX15z zOc}Ple6mF?By!(aZ54FIo}EBORU-kevLn@0^5*Ul*kdiLSN8sTo z%)*Y+$}A-=m5~&|c@gS1+h%!8vyyYXPBXmZ3WN8<3ZnM3e)Y^}4qu@%HW?ZBoiM;G zj7|_f?W3}dh6b!Is# z`EwpTZU&`*gU%tGrmrzb^95r`hDqh)oIly8<|GL%20r&`!)0_X-@R;22JP|$tNKti zykAB}gEiNlP#8Rp+xY<=zps8<3R580cG2jpV&dXgQels94W*A4k8xv)mdh9^Y(fW; ztz}1tgPD^`_A&dZ;#Os~e~OYe3mNQ&^&4AS;0SjXNc>*Znl2r-v6a{|XIGy2$fm1SWtXG4a{t#)Z@&^tF>MSWM z2?Rl=uQj%!R+l?dkW|a=QL?+#EM3Kyj-FKFMW{K$L%ypQbaH;M6mJdrhgAB^6<;wh zp7ynPE_AbYm>%HPe@>{4HQV8;q4BJALNvEnZkC3 zbfyy}7CInPeN!Rr%+seQ4L0&O}gm z*@sL^A0v36CkquX?qp0>#P?OEP=|!Qc0=Azg&u1avpeiP33fnZ>pCr0#?ZT_8DS#H znJ|7NWHTOg>~yqr)eRS*O63QuPX?sTf;1T`IxI1A6@dC76q!}*%UOgb2-f#Hi)>^8+pp8pcwY`pEwY7GW#F z3Tivt*8jDkD+yNE6y!P`Q_yFd0H*$`a@u%XVaPwLC8{sb+Fa=^VGXkkf35s6LlFk- za||P+Gy?aYTA-}l7^=EoJ}|rvdRl~P>Zx^79{sgno`rRd91Ctt&2JxajxGg7Fvn^c z#|9Km;oOYeH z1_>NK_WN=T{<0JZL5Qou6-twU#t{$1yVCK1-nO|%A-q)r#aed} z*VczvA*2 z1?PM$9SxHVp0NzCD2(hNO2*)CFXJ*=RG3Lccp{Zh1ik)@f=z;37ItuE;3$p(xel}ZnsA|F;piiZs9aXe< zk5FPsYupbJs8(v$Pt6@F$rospoPAAyI_jJrFn4M=yNT=wN?sA zAux3;WyYM(CCKB#KyspAMlhNaPFI#Bb7Nerva!BGMM|q9;`?q2)zv^W*;zS^YTaNF z?{F`T+uSRYA!}?UXsh= zH3RZEhi3;!i%8d1yknr=@rvt0fo2KqXdZ8f3pdt>b_ z>1v{GAlt?AYNlq$o48W$=F zj2s$a9DrAVSWJHHm+GIxUxXZ0iM?{9C*CH-$J8wJXXhV&HJNb}Icl^X(>=(m?M4Zo z!g{#@yfgzVN0%_Z4XTA#ZB5Y?h}LxNR++WkZv1+CCdDGogS|#HEX9z@C^%=5hTMWl zEQP&%2=l4p??^Ebf{7Z&Bgx(JNCtp1e4MC~d1N`Gz-fn99|(N{6?%1Q%@Sk$UacD%eK8FG}r zo_|$g8}w7_pB>7;@P@UOoRkJ3Tdm#{b_g_WrdoRMj*G%JI3?T;rozfLs@1uzs*1TP zOmHP2Vamwk1rl_(U{|uO*|&WT-E6Nln|aJVU-H=}8VgMg7VWTjQ5Zt>Muom=OTw*o zJM*)nhg+WC3oA;Dv$May^xxLvqJ`lX(!MwMB9{$3phxOqq7uZ`NP%HF5x0swL$Fm#b{m~|hx{e`+=SE~qjWgSt zpVHDDFb^FX1pU@Mh&^&dFL*sT_8wt=q0zbM09q5emlnB07_BF=v-0ZV~Ps1{QXCSEpYCG)a-zY)oSZ?c_8617J_R}XcJt#t;{_$iUAO( ztQ=UcHs>yt& z+jtDyQZ92Vt}yxVL}Yvk)1q6z(jF8V8qHSO8_qc&2m1UFJM8UxTQqE2O~sTIp}w|5LIo2YyZ|` zDSt(qtrV-o*pFD$=0Z`Bn#!KZo5qBycI z4i*^hy?!X&R=ao1@{(>^{zmH?ko06Rk%?uE$BLHN{6&08n?)> zSz-t!2hy8LPNl!Tn8~ck2KsAJTd;n>Wp*kioNELKqFo=1{ou=|;8&zV)mg$sT+lI? zS801ZAr0pSJm15TuW`IiryC__YB<1qA(E}lcp(&rQ}6r&=eoM2>q`Iu6w2jES?~M- zUrH+()cS24J6Hi;z&lQCrtv!m?w2!b;&R|$A(xlU-?_bRJ2=70zdI!6f=FA_xFum8 ztu+xxOAo69oJz~U3d0r@z6%WU zP=Q4^P!Z^Nu}1r|@VuPy{Yv$$%GtvmZOT1`IqUth-lt&rEjiTmmSPE?KcY@=?7LD9>S#7G4fy?-&r#~yht?#LdD7NY+8MsRuyLf7*hemhOqX5A9JHbE2; zy%K_w-}gpQ$7@oUB`W64hqQJ0k{}1H9FfHIQE_vkTcyhaBae^$Frq9mPRys7@insc z_6KhnxjjvAsgLAlg3yN!>BC-}6}K}r8TiuN^bX5VJc9INkjHE){qML)s)s5uF66p)gf~ME6RRVkW5mROsYcVyYs{SlaE2O zlf)jm3eM8M2PjD+z-0hQII-JwOaa||IVvzI-%y%W+na|$#`}`dca6&_W6_C*4wdrD3ien4+CbzvP0V1?hl2MQA>%b6q| zHTs1XNEgn z9wncv{n{jdVG0w_;qr@-wN947K8Idb;`4n6=L}CS)pVW0{&yFe`xkNZPy=#4xN|BbTPA8YW@m!+7zIvF3!#b+#}&W&=#;u|H7;*|9; z!sTmTsEZ>V@0P2yTD#MQ*c=5y^^^{uTP|zWneniSYB~I2;&Uarwu2hni~I zgF6SEW}S_U$F~DgYcIk$pA-g}Sdv~^eD3SqzIEG>S(asR>%poKtse`yW^m{evA!&} zM5Ve}N#>MvwZU4rJ5Iu^PO3Apl<439Bwg_!R=GFW#{o>60^rO?)uG7HLF;0dMm6<( zHTb7u7j8z?`kydI>v$PZK?9NyUI=VO^RBUm-qZr8QC#KL&@JU8|3|}nP=;=b`1Y#5 zrk@%iPYl?81b5_1 z3&)vkxC#_nwyL~FVOsR|yXIop+gH%cy?g_2lO8Sd4FAZ*m$-43 z5iy7UnO|TZn}O7hU@aFXpgal%|0b{vp=pVy^ zTS^6PgG{ocgfkFSg+DDIak$_TurR@MrvP9enFSkFJ<0ats`VoaQ5s*RUjkF-?S30( zsO6`4=s!`deJ|e8%@P;u%?rjLI<5IaaDoS>cKcF~~> zA3iGpZ-%QV{6WoTn~i6(0TLr*tDM5t%>h3@YyRMAra#dr&~v*i_frsm^neUFJrjHi z{;}>Tluc*%(2qNPC$NQY_Tp__BzI7M?RJLnSPCPsidbf=9IZY)(qg&K$>}ftBS-=S zBf^BdeSBff%rq{+hgyuRW^9oMoGXUT%(Te2LW&78r*ZiM!_YiY!X|oX{JfM-Mhp{Q zIw^CfJx7k7k_lUF(~N#D566q&Xark1s@=)&Ru|(oCqFs2mqnDJ&c%_AD-z4nU=&4` zd8@E+)J}kwj&8o7oT_}`=pc6z03xgoj7L}EcRl`Kvm`aBYGZG-0b+9}^bl%qQRIJG zG}AokGqtO?N{aMk}O<;wFLtL ze?_^^MB_u3Q}hEOBrc>+a4&?Zv5zo*z5OQ=iYaqNgo)Be3`7oQA^1H=Z4}hDxpOxo z?%7qc7`myNEyiD2^X^z$5j|MJKT+Z^4|w`MAl;K~cDwjSDkKco#buC0Ad7*Rg0e%m z`F`xOT6W!}z2LTY&{%B+=6fSM;! zn0?r0umb2D=DM{P^w2xmwX`6mRz9*qA7-1bAIKIs;+ld7fs_OhYq+~r2`G<^A&iKJ z$_pg633jaF2_Gq>y!_>~Tyg~I(4Uj$f`KCJZMKCzw?Z;~p^yrM8O}$DK72GDwCm3B zx#LqFCrZZ^RVno_aoo(Z!hb8`^7}xWLFbnO!H&K+k`dwnH&Jwg5{lm>FAh?7o%6`x zn148=p@9e)HSkN>n|Z?EVfHTGH}Cz)TJHG&1*HtROUf8)&f@Cj)doj=n&h#@?2TOK zyhlk{DnVq917wwVecjINS{_eBg!U%ler`WEy0_c{bB0}>!P%X zW?Uigl!)-s=uCy8bVh9&FC1i`Sb;1`TdR*;X1}boIH|uQzxUkESv}Uh*7C@UKQf{h zO!rC+RG9eFv4Wa$Xr_dqqe0V{bU}-)Y2jY0&4`t;*8x(ZPuuKHzEag)(X&WZ!*?0OG4RvKD&>Q2hmB%dnSd{nEJtElSoTQbP`72NfO^TfD&jT4lLskh|Ga)0 z3ntWDTSZHg;PM(Jc(b+B@tKaxpCYnv-Fc=>kW04fkJT>lN<4+gaF-_R(2Urt>J?IP zq6=QfqU3UM@>Fi{6p$d{kf!^UoW~gk8kE*tM`+cu*lBoQOXEc{E&x$7`&G*k#~_Oz z$J1`eO?XgTqdA?XSJaehysG9ao$6y_+RkOQ=*@B%YisS*M(>iHeh>RYMzI_AZTF?% z*Xf_1oe4EvEERIfrDe2lD>U+u&0?A^)`jb8B)fALzFs!@x6At=>5O@oYT?<)#OvCH zIG;_9mT!4(?^T?6BQ%|?Kq-r7`AB{72z){w7fYV1t_7*d4JpI2R3={%nfS0W-|7b~ z{jWc|RlDl@vAG7|DOlx7rCq;^n4LUOCbS-El&ZDGPW1QPXL6vt)bMn?s* z6E2-%C$We!;0%R?B7j+OfQ||TN9%`GH1to%O_YpTx_b4?cbGdDTC`jT zBwC&#aHzaiGKlLEfo#=xqbwQgQV?AXxC`E9JIEdSW=6UmlS%ZRCqpso8RC*N{Iz6i zVJbvEr4S`TD+jDFZ!! zl7K*V!MvAQOEQc#{4A|8gWgy-IEv;KyK5~k>41@3kRA{S{~khvvf$euyZj+X2~aMm z_C1ttd}-JVb-`W^&E8utbL2JjOr+E#7OESIxgE@83Pfm9okbtt9H4s>5Cd-}JTSZf zwtRY%KRV~BVJSM@d}RU`3)#kk@-|XQr*k0NNw8t01d4m%L+70zQu&wn_*+8`W57DQ zudLcBreHI=@;9aUJ++o%rv@MD8hN5ks43&!zj2jqSp{`HBW{irzYH65TBIti{QSf} z-PdLm@#jFjZ72+4AU8n>S649SzYch7jrgSd@+YW3?8G|uHJkmXPAMwv!P?vy81!ZL ze_#FF-pR7hDn26`tpp6U7t?gIbysdIN#hY0CRqnOF(Qu!yvYS3Z)ogJd7JE}QSgp6jsa=?R{WO{#@A3&$; z6y7=qcO(V6MJN&J`lsKiruU__)*$PAc6078)i}McJL|l(RWlRjSFb$AO}iWXiOYKw zD20^4my`gzkl;AB${#d$`KecVo_^LC2d*AxLOK9voQLbf(6i%a;nhYl5|YTZri; z4IaS`FD4&`{AT0fFiGP+luwE$ffLGrt~~T>6my`-S9I5q{=zNxQ#mSabZ=S2`>2DM zt14|>=Y8oS2R%-@yb)rb0(9luVI88bVDlbUlg3Sdr4A=%>7P~rWryrwAn5X~urRi8 z3c-3D&qwxULfS#^-X%HimiHFy;DW6$k6?3HpYRVs)2%eGI%mFbDH@-Hc@l|85YF|s z$o8t5t)g9Ll%?6Ne_3#q%A17;x^@*mL^2(A0PB_UP6|PJP@bNgaRV7*tUflwj-(VY z+fAhAzD9U~;-l1s7yg63{=7kIsbL)-eRG;Za#NPb{;zVLQf%x)*VQ*m+nZoYm+)gW zbRtj$a^4_QZ0Y`M_l}y5tmRNX!XD`hM9eO{B;YmSueO<-lUHeBTp;R1NICQc9&UV! z(g-7RPtJc3`^?D^P`h~>c08u~iO!WvhK^hLHo#?Fy+a>4q{3(2*Gf}S!XG{1bPylh zH0?{^{v7r;R7U4?b5m6>u2TJIY6;oDko=$BDhC(yxBo6~p=e>4)N({nvC4-Vb zng?nPQhusQlNCjz+r*4daSuIRh!|MKKFylsVZEc-$nUy{LybH;SUKb(-lZg12$M6Q z?UF&vDv@CFpQqB_i_$>JogEl==dxJ2A4`QV9A+M1j)Cu293#amXm)B_-gCf%0M>L+>lLd)OOz!fNJ@2xHnh*l<< z-MPxDAs8-$?@#J@piG+7X=L71riH!B4>*Q+6C;DR7(IM3Hm9L*t9BUF4D!L*Y_*oe z89EMx>cQ&;Z*`0MA2df!!;m2A8zA-jWbI!|z~uLK8c5?|byE8-6UdQXQV;QC=KIUO z^2^X#tVJD>+aNQ_p}W;)G8B_rF%F1N`b51Z8}9iZ3c&aa>!fTPOJ)XPo{fNY_{O{vUnd{Nk6!(T-8CYoHn+<#cx4s z_`$ZG_jvosUrnZWwyvQVeC>h8z2;7S_3498>Q(oC?YH8^2|;g1QaQ&FdsGD>cdHJ_ z+&fzpMf>?gX2+`2{}S@QHVu#`M!FuTJGjK28qe!_H~#E8w+avwgbEI1&tY$|l?cby z19@IO0NMJqyzD*`0>Q6?tbaple=C819In{9AFcy8B}&IO4hw7-Kdj$;cId-w_YTz) zxM+2@U)Km52J|n=#cx4xFHW@Yw0`1mS8Yvi)pej6BsY7v z^vbn+_j#VZ-@|+6F>Clq1K-koF}{yfvp@jw|n0`02T4CP&Hxd;u{inzNabeCX|^=rtyB&-|g&yQa`ko zl5Xik=bV5Wpmsy|_jfh%Du_6qN33~^=l<$f&NQeRJ`0OH(6o$mZto)>gjXhHbgiUw zsE>o^dg0;4w+=v$@zeyMp2$oy_J3}NRP26@|L}f(d1c3j&R;#B!w&Nl`@W8&C-=^( zyZ}|FG`bF?=CP8*DTO_@wRQrmR~;}+_drX#)Ie#r<0)6A>Dk%SPHtme4cc)Xke`Rm z{>imfunpZaxnv5VMTZxSBW>1GC9`-t((@CrG zz6)b|Jim%vsy;n`!v^!&p9sj`*|49?DW>HzdZ_r3zheIsJg^abIV9GvRwCze2gK~V6C_!xqxK2Ct2=6lG`98e*YIHA zV)|p2{uCEVsnMbc(23F{kt91P3q;`s?oyT=QftM!^VWGFvN2VCigXlmjB-rQp+hg> zfZGTKe*eeLO^LHr&skDpNDaq|&7cG0_P2#Q?`Z205Q27Z)KtS4AN$~kXsV+t?dmh4 zg^ry(xNe7_Fm;B3Mb!9k;;Fn&V#w=Mc@X+;hfBS#*810LO2&(;I`HQ$(MR>}b;QoX zR@AR?QzK~`_d z`0zZb8)SVPYU6o7?m1iI{!YkJO^Ef)^CNx2^kTcY?&-fQzrPek-vw*=cUP>mo!B<~ za;rbJtv%RzBdXdlPp{a7%BI`K+?vi)!(QDtp9JwZgHo_rItbSx_66I{78>24A_NH* ziJ>J*v;{!K3&37qy?MF5wy%FAL3-~k&VY2Q5_}454}jQjm2;)(?hbnw+cnvfC-XFU zvTfV8?N07w+kHLH`@Y})5ALmdueGlAyZ*JAFLqka0_Dl+5Kc&pvZ4nRSk7z#2AQM* z`-V0xQ+J~maTg=&L-)r=hiFULPI0cCvl+X3s9y+IAu~|lb@0N2TbTSXf&(#AZ zt+<3X(tW|xpAHrY)Mlk+_*y(q1rD3bf5AKD7DvS0_7~E9QFX$yub1SEc4xyIM5;5Y zSC&5c9J)SU0)OE&LXcR#<3*ro)AqvV>-BC*{Wdsj?t5*fc_3kb0lPn)HvMUFO0A^rqO+C$so2c=n5>d|mBHR$9 zHM>kJ!+L#eA`p7pNVixSxT&Ve9Gw%qi1pIOguhRH8eRs+{nVh}-WwD}c$fi)k0tfjI* z)NUkgZg$}-cLbB~glI9pa|U6klsM2wM}GnvQvITS#V!;fbc9q76b0Y%XisK5<&d04 z1P~l278RIElGzP}p%5A#{0C<7Iq--nb#zm&phOH9d^o>mWuXeJt1@L#;%5PL-i36ipdus7P(0(_O{C58l8oG5^Uln<8_iFNkjEK6>n zr0l)n>yqCaUjO}IRW+Q&lFHzFekbbZc8Yp=&~JgQ=S; z+%8_ne!aJ1ERQhHWDB2pdKqdeu{$2-xqnY9p}!)%VEX3!gymO-%Y88ZQ+;sUDD)Zj zLLBdKW#1h&Hpm31fBu`z;O#hfV8(+pa~2LiOQ@FuJ` z`@V|`cF_k&1))+m+i55!bT(xG(t_r`+V-CU!pC6Yc}it1_bX{ zK|c<+0it;H%$qQb$7!9>i^7Gfsk%KMCN{afGg>N;42LRyKlCE?8g{EOF0p#|ZQ^x< z!hVesnRKW@pz`JXW+)W$eFDC=teZVW{&P)v9Y=!jadlS68qaK-An!_IS)AkM{+vpE zf27Ks{k?I;iRpTcVR0b-P4w{!Y?g2$T31EUh57Au-8MnOCjTaUwP?-LYsy)Uz@df1 z1yqc!qJ5jz`TLqJdjHK76p=P4@oBpW%Il8b?lDf`fcq4GTxFSqfjL9?!%O9T9;GbC z>7^Bm)tLyTNez56B+%lfB$=_MY}Zt5=bOv@F1@~4G%23QR%Dz{9$i<+xtlnOoy-HO zrWlb0Quq?QM!$fjoJwX{4)Uzpy}=bQT0AY>pVzPdz_y7Kd=C*j1={oP#3hu!< z9O=Ws!?;Qxd7wpGxi) z;Zs!@(mzr^ZyGKDd>pFl^Ul8=;}#nQJ1#5g%D&VAJ4bbf;)#W)qxI8kC7ZIbox^Bt zf(d@ONdLsO(`$t223zCP_Un+hNaO4Hid);+{}~$OI!m{k&;Xy;`Rdv8Cw;Uu-Lsiz zZj3UBprE~TcR_#*_s9RF?V?)o)?zp`!bQryjoHNde_}*G*`Rq$&Uz;)0j$J*pwiS8 z->QmNq8IzN%r|bNL3H}e{KE2eL*@I%&t+$WNq0~I2Q_2XFyV4N^$5gh3rOndsf*+l?4F?%>XJ1g31jU~cZ~h9~7bE$A zCVqrfAljv%WHWaeTTrf!_{USguSru(R#P)KCDtgwE*YoHr zCsW{#2C2wvUMxQ%9yb|jkx&Xai{r#N_e1IYhzdkoHRJ}kH_f+*8>PR3jF=?}7Ap`8 zqBc6nBNhu^`nkgrfEkn?c&1v!)y8}Dx$#fTV206!qH?6nWZyGIk{vz5snB8FmzxGc zQmZ@adXyp}XF*~htS&(+EUx;lKVQz9f9BKo-1WNRXL7x=8uEB0F_USo!=QpGGA=0Y zR!55DFy}e0DZ0&RX&EVCL{(*dLaw$_izCD_1=0dfvchrr|0IqPaB^VKHt8Wn)(dwm z^3G6+;loXWCYUz`IK=a9m|5&rDC0{N2(ohEw+y%};edn_gUkNx^CjCAFsssy6vJ)v z4f%_dYASLk)=XsHT<4p!d)6Wr^Hor_@I49Kahl>C%HiDKBRrditjSF6HIPNiSJR;l zQ)GaywPhgMH|LVJ3#jIsjblkBL?^=W!p{c(pl`$Wi?y6c9zmLWge|S-_HPVvF-Yy z!5~3J@WZRKk?(-0k`-w@Z)-Iz_0xUM3F7q5|JA$89^537(JYLNQ`4wxG2w-5^!!f1 zFtR;$zuHSDJh`bLNb9>g^;KwTPK70Ns(^cUsq12Db3Ltr083JCMLx9x@`(n@n>DN0 z3tU^7)iPp}GI0IyLNaRKQL94=%z~{puVMk+0KV^zhXXe1UEl5Or+YO!%$K|_0$$(v zg-7fcYVBTHRBn#U0!@73FZ&GCUJsY|pc+-Yoj3sc6%dyUNXZ*D!3Z3f=fm0Xr0uq< zc62RGAGC@a9BBb6;Kz01VBNFR@$b$7`NoD{}AFo$H&}TV@wz*H2BVtx5{yjLmGf?A8 zexSx}HVXKmjN#^im`3MO`mya1nzclh!@bfQL$sP-@AnCbfKm(Zjb4G_M>Hd zAG1rV<+tVC>(r~MP$JXax3A(Dc7}E+Z%Z9dZBM%EZ029YB9G(a@daxQO^b==OTW`E zG1Rk)(9im%Q+$!OJNF?#`3}3L|DVVP=Fx}EfFo;o@bO|7K$9NlTRFAW@01fVlm-3x z>iE>w(lA#pc={Zrt8U`9^Uc_l@_LTn?J|cE>HMDgb$76oMI#}2DC7_3J|oiQpaoQ2 z<1gViyMHUb;RhEfZ%wpvOz0A^pAjQOk>-jLj7a?{nTTu_5sN`|K}Yp`V(QW}=gQZ& z|1`AzXL!Y^*By>$>JVoO6#J_7A|8im<0-|r%2WPDFn@J))(aV7vry-#AZ4D_^c!DX zxx`_7L9kCrzkc+u#uUgt666Me4tt=o&&0>$+n4CdC~o-7A%K$i%~ZWG5@G zLz!sUYT3;Ctm?pV*5m0!8ENT=)vle%_kG9h2{t~+#npK|YgtlAl`CO7De8hiklgOm zBE+sn|E_abY?|Qd0_ar!cKrGj!g+JRkT{aHA7^1EzI#`;_|*wH4Uy~x;Z0jb8+(fz z{ZU(jB(aJ3-RWlrWwhvBotZ>0|Ch+I<0stfgV}I^%>#~~{RgF+?|#QC7tB5X!_rd` zB8u7gFpQSz!0Xc+(jQy9$RFM8EVHar;m1e5uMAIfKG(bQ)?fuE_i@9>9hHo%M}lti zCeocEoiti_*GpoS*P^B;r`c$TpS&W4EvE#2OW42&91odyuR@;j2j%^`IH!l>o0(Hq z+>Arm?v;T~S0R|I@w#(!R3@BsZeOAM@9*uG4^K|P1=kZD%YE8Sn{mF4hiRT*ySgiR zwolltIramS(9+{ZukBD)OSq7=&=UwJJ$0wIn)Cq`#j^Q~CK1;v8qBJ;oPy0V&_3k$ z#|}X{byix1!_r;RzrL6hTm%{(1lS{_gi;)X+>tORu z?PQ&@c_L?ma)Nj9LbY}r#1ym0EUtIk<~SC(69e%7BbE?u&&L_o@9o2F}UeK!`N zALtqST^osQJFKP%i>FC-X06_afU8GaSj>^uIr}}YaUwx(Y<+Z3@Dcm-WT6?@g3_v9 z&lWf89_7;U8M53Fwk#kHQ?ECk zu=h8I>Y2Mf%XK}QaUY?9vSV9*Xc}3Z+*#%A&-Q>eA6~bQSHcz)x{)ufdShaIJjD=? zd0!+d(?p-Q)$HOmlq%Elq-vQus8wK8(* zc{Y-P^Co9ZTJ9r$_s*?hC;d<>EdOcM{2V!?7TfDmn@M!NOuUcyvPhUSGAnzK0xy%= zLk>8<3e>V|0u`pE{R`AaAp)%7hJRNvy~f@}A*YkVpKCrYa=7?S&T`nzaqP|@i?y5< zyLqsakXHly-{eZe!q|UiTbu17OJvq-b4t-J^ksh=FDL`G*2 zE8oGi0!d(!eMz`Cj9DhKXuL=ar}6-kPcG*hW|;5+%oUn8oh03GP0;QKnJq6a3{dS> z_}rB(_~8F!abA3jn`ZcAe;%N1mJDTuZ6)duMr8-7Kv6`qPf26lgquP=BVF)#91GQ- zEjLOV;Y^bLL58gYHD3i2p88Lts4`cgo{^m)k+R0qSTapJC*R)N!!EmKfjXXA&%e=4 zbj)}Px8rT)?t-p$d>7htHfPqb*1(1+H!0!$H}<{UN3M&Jj*ya8)!LEqwFip&zMp{=V0VYc0|=)L#-@ z8-KM#V~d7OU$A-;R2qctY*c0f?%fgJJc*Zh&+#l91cD^7|BAm=1kUoEA5M_>L<(ghK5bFG1+(}+oA~D%;dmO7%9HpW*WZXhwTJJbe#*-Wh9na6Cm~d zn&dXQa>F|+;amEtB_zD&t@J<2+Go9%w8na>dzA^^t^MYR%Fp@04UBH7nYm`$-Dwo` zd@NvrJ($L3jw?rXOfLP!bfPDE)=gaI2g92mC{ut;wv=!Ii1$tvU)lfkvzoNWdA(C> z`CtYDUbn^o8XJm#Em5zX;9kqi?=SzkR6YIhn^+uqvwNiJCe$Ar8n9y|1W#42CE*7i zi{$UT)XfPip?jCHRW1m@`&_Z!XYqPTUrE=H7@l^OME&Q~Id@M)`VmovPlPyLHHc7> zbTJ+NKnVirD%`K<7YJJZ*Yx?b)aMK{d9Osmhb?n~?jTDvj*Ro1ZpC_oJJPR$@|iji z#U=d>7j(9i6Ht~Xq_ti2of}&EPG+G09TeB;7L2Z-8&t1ZK!>{7CV((EybG;9^&OsQ zUg7hqHeR`}B5w_>@{FWtR_bmYbCbcJ8~?#K$SvvE`u9XJ?7NB!Mi8wxc_t9CnNX5O zboNVx)fWV@e}zJa#RTk(gHHP!6n<;o;fL+Cl|SbhQLacA0fYhdTs+QN`HMaHks@7i+PHSG6YyFg1cX5@=ghsltm#(I!}!x@l9eihk`Ku=>_YY7SAx8xuU z)!lSIPiQ|bQU&i=1CuyVW&%Kn(Cp#}7?Ozej=!+N*=CFGaxj_zvb$}1kt`^c=iXNk zk3KMzC`I1cs3CJq9!aebrD>koneal;^eJB^nM4HAKn5PGycBSP?W&#hTZI@uiOw$* z>(zdu{hsOLB&sU60VEW7(;Fh?#B)P4&HZTNn0XBQTNPCA&_O@%r&y!$B<7Wp>$Z1K zY-zaEEW_ib7&WWqdj!B*(&yFJC1`-sQ+5NhZG2iSI?!=PuvtSs$OLPCGRJ-;=Vy_ zWk+W(3&swFDM+Unq@H&nb#rBnty^~@8m+tC!yUTSYjUDN&e*HAe}cC zS*Wo1%{7mk&*%%IMc`1>P4GkvIRsT7n_K8!s}uU*~PgLK8+Y?Bo2k zn)QKd2%PXdb7NkbRT}tnhMIP=VF3QP**vb!7R8l>fk;ND#(7JVLx_ z*~FdF2wwLp3UN`7!b|b~@h7#n-t;DgCZZ?{qWOORb$uDVF#4^fT5zLA>V4c!f7)Yx z!&$0I*lQAO^os1`2-7WmQTjR&NxAPD&J;Gqm+>y)$M6n$c^~;1tvMY`p>?6u{?R^p zTVF3PfO?;G7)g1UjUSn%-)b`&Aw?^oRr>STE2xXkK4YftEexg&xi5}kPjB}O$NJlzKqA_VOg zAL#YXh_^ak_Ah|9r&CK+x?yMeFdX*5S=3+(PPwB&I$%NKTQij2?I6>62#3js{naz5 zV@V0{aJL_N@J8+S@y_QbTU9yx?Pj6Q7o~b^?f1i^&P}bLM*Ky&R(tz>xB5B6&Sx)5 zMBteYcG_1b7XnMstJW;M{2l(|m8y-UIR6eu?irkY_k-a|1F#VYhBpy1|?o9Ct&ngVua<1>;#}6y^^P z5Jb*mp9V!z5bBz>&-L+7s=dEuZ@GFj;#*QBTAH37GZI7er4-;;Cw@D9N$HHAmawd=Ut**rYTh?PyOP0U3!}#zO*n=!DPTi2ZomZjkc~%*LlLlhT|ZqJ;^!bY4U_BD{V3j{t3F zF>R5P99aQ^CmJ4KG~TfdD>V8Hw+V-vU7V0CS&6$Wpszc-TW*YiQxc1!qpzDCQB|Rte8kAs1%!xY3yO?)1|~RZGhoSkm;J~70;t-f zk<~JuR*laOx|A5|ai|*XH@~DHHfIFN5cIEkS-JVL>P!)EisbW^o>?1zql=f62Wtuk zXJ(?F#U+q1_j$1Tq^|NHA1<~=8tIzhImFdr{Ieonq| zZNm4=!#)mTH^yipZ?A}c8tv^o$n$wCrq-%BF{Gg0C;H8t%0Ao2YuUTOfw}eD(}Rq& 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