From 1df78af2326ca0894adc9ede5a098e6e767c9e2e Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Mon, 29 Jun 2026 15:47:04 -0700 Subject: [PATCH 1/5] remove scripting api's marked as unused to ensure removed api's still allow the application to compile, the gradle build and github actions were added for the CI/CD check --- .github/dependabot.yml | 14 + .github/workflows/build.yml | 34 + build.gradle | 4 +- .../regi-headless.deps-conventions.gradle | 18 - gradle/libs.versions.toml | 52 +- gradle/wrapper/gradle-wrapper.jar | Bin 43462 -> 48462 bytes gradle/wrapper/gradle-wrapper.properties | 4 +- gradlew | 19 +- gradlew.bat | 58 +- regi-headless/build.gradle | 20 +- .../rowcps/headless/HeadlessMessageTaker.java | 4 +- .../headless/HeadlessRegiDomainFactory.java | 156 +-- .../usace/rowcps/headless/LoggingOptions.java | 2 +- .../rowcps/headless/PythonEvaluator.java | 13 - .../java/usace/rowcps/headless/RegiCLI.java | 17 +- .../headless/SimpleFactoryRegistry.java | 10 - .../ScriptableExportAssociations.java | 34 - .../ScriptableExportAssociationsFactory.java | 50 - .../ScriptableExportTSAssociationsImpl.java | 151 --- .../ScriptableGateSettingsImpl.java | 2 +- .../poolpercent/PoolPercentCalcFactory.java | 41 - .../ScriptablePoolPercentImpl.java | 106 -- .../HeadlessBasinPieAnnotationLayer.java | 79 -- .../status/LocationGroupFactory.java | 235 ---- .../status/ScriptableStatusGraphicImpl.java | 1151 ----------------- .../status/SimpleTemplateEngine.java | 54 - .../calculator/status/StatusCalcFactory.java | 41 - .../exportdb/ExportSigStagesCalcFactory.java | 51 - .../ScriptableExportSigStagesImpl.java | 116 -- .../exportdb/ScriptableExportSigstages.java | 21 - .../importdb/ImportSigStagesCalcFactory.java | 50 - .../ScriptableImportSigStagesImpl.java | 95 -- .../importdb/ScriptableImportSigstages.java | 17 - .../RetrieveSigStagesCalcFactory.java | 49 - .../retrieve/RetrieveSigStagesImpl.java | 488 ------- .../sigstages/retrieve/RetrieveSigstages.java | 27 - .../sigstages/retrieve/SigstageLocation.java | 70 - .../sigstages/retrieve/xmlmodel/Action.java | 98 -- .../retrieve/xmlmodel/AltRating.java | 111 -- .../sigstages/retrieve/xmlmodel/Bankfull.java | 98 -- .../sigstages/retrieve/xmlmodel/Datum.java | 268 ---- .../retrieve/xmlmodel/Disclaimers.java | 152 --- .../sigstages/retrieve/xmlmodel/Flood.java | 98 -- .../sigstages/retrieve/xmlmodel/Forecast.java | 140 -- .../sigstages/retrieve/xmlmodel/Low.java | 98 -- .../sigstages/retrieve/xmlmodel/Major.java | 98 -- .../sigstages/retrieve/xmlmodel/Moderate.java | 98 -- .../retrieve/xmlmodel/ObjectFactory.java | 252 ---- .../sigstages/retrieve/xmlmodel/Observed.java | 78 -- .../sigstages/retrieve/xmlmodel/Primary.java | 122 -- .../sigstages/retrieve/xmlmodel/Quality.java | 101 -- .../sigstages/retrieve/xmlmodel/Rating.java | 111 -- .../sigstages/retrieve/xmlmodel/Record.java | 98 -- .../retrieve/xmlmodel/Secondary.java | 122 -- .../sigstages/retrieve/xmlmodel/Sigflows.java | 239 ---- .../sigstages/retrieve/xmlmodel/Sigstage.java | 61 - .../retrieve/xmlmodel/Sigstages.java | 239 ---- .../sigstages/retrieve/xmlmodel/Site.java | 385 ------ .../sigstages/retrieve/xmlmodel/Standing.java | 159 --- .../sigstages/retrieve/xmlmodel/Valid.java | 103 -- .../retrieve/xmlmodel/Zerodatum.java | 90 -- .../usace/rowcps/headless/TestHeadless.java | 5 +- ...lyHeadlessInflowCurrentDayControlTest.java | 7 +- .../inflow/HeadlessInflowOptionsTest.java | 6 +- .../InflowComputationStorageOptionTest.java | 7 +- 65 files changed, 200 insertions(+), 6597 deletions(-) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/build.yml delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociations.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociationsFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportTSAssociationsImpl.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/PoolPercentCalcFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/ScriptablePoolPercentImpl.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/status/HeadlessBasinPieAnnotationLayer.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/status/LocationGroupFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/status/ScriptableStatusGraphicImpl.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/status/SimpleTemplateEngine.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/calculator/status/StatusCalcFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ExportSigStagesCalcFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigStagesImpl.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigstages.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ImportSigStagesCalcFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigStagesImpl.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigstages.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesCalcFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesImpl.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigstages.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/SigstageLocation.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Action.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/AltRating.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Bankfull.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Datum.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Disclaimers.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Flood.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Forecast.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Low.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Major.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Moderate.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/ObjectFactory.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Observed.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Primary.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Quality.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Rating.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Record.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Secondary.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigflows.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstage.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstages.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Site.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Standing.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Valid.java delete mode 100644 regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Zerodatum.java diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..f9bbc2e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,14 @@ +version: 2 + +updates: + - package-ecosystem: "gradle" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 5 \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 0000000..8fca131 --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,34 @@ +name: Gradle CI + +on: + push: + branches: + - main + pull_request: + +permissions: + contents: read + +jobs: + build: + name: Build and test + runs-on: ubuntu-latest + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + with: + fetch-depth: 0 + + - name: Set up Java + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: 21 + cache: gradle + + - name: Make Gradle wrapper executable + run: chmod +x ./gradlew + + - name: Build and test + run: ./gradlew clean build \ No newline at end of file diff --git a/build.gradle b/build.gradle index 33d99e9..84613dc 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { - id "com.palantir.git-version" version "3.0.0" - id "org.sonarqube" version "4.0.0.2929" + id "com.palantir.git-version" version "5.0.0" + id "org.sonarqube" version "7.3.1.8318" } def versionLabel(gitInfo) { diff --git a/buildSrc/src/main/groovy/regi-headless.deps-conventions.gradle b/buildSrc/src/main/groovy/regi-headless.deps-conventions.gradle index 9e8db3d..9f129f3 100644 --- a/buildSrc/src/main/groovy/regi-headless.deps-conventions.gradle +++ b/buildSrc/src/main/groovy/regi-headless.deps-conventions.gradle @@ -1,24 +1,6 @@ - -def checkForNexusCredentials() { - if(!project.hasProperty('nexusUser')) { - println ('Please set the nexusUser property in the GRADLE_USER_HOME ($userHome/.gradle/gradle.properties) file or via -PnexusUser= .') - } - if(!project.hasProperty('nexusPassword')) { - println ('Please set the nexusPassword property in the GRADLE_USER_HOME ($userHome/.gradle/gradle.properties) file or via -PnexusPassword= .') - } -} - repositories { maven { url 'https://www.hec.usace.army.mil/nexus/repository/maven-public' } - maven { - url 'https://www.hec.usace.army.mil/nexus/repository/hec-internal' - credentials { - checkForNexusCredentials() - username "$nexusUser" - password "$nexusPassword" - } - } mavenCentral() } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7c8dacb..fd6e634 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,14 +1,12 @@ [versions] # HEC Dependencies -service-annotations = "1.2.2" -win-java-heclib = "7-IE-win-x64" -solaris-java-heclib = "7-IE-Solaris64" -hec-core = "6.1-SNAPSHOT" # required for PasswordFileEditor +service-annotations = "2.1.0" +hec-server-suite = "8.4.5" # REGI Dependencies -regi-tools = "3.4.3" -regi = "3.4.4" +regi-tools = "9.1.1" +regi = "3.5.0-alpha001" # Third Party jython-standalone = "2.7.2" @@ -20,15 +18,16 @@ solaris-jre = "1.8.0_202-Solaris-SPARC" jython-starter = "2.2.4.0" # Test -junit4 = "4.13.2" -junit = "5.9.3" +junit = "6.1.0" [libraries] # HEC Dependencies service-annotations = { module = "mil.army.usace.hec:service-annotations", version.ref = "service-annotations" } -hec-core = { module="mil.army.usace.hec:hec-core", version.ref = "hec-core" } -win-java-heclib = {module="mil.army.usace.hec:javaHeclib", version.ref = "win-java-heclib"} -solaris-java-heclib = {module="mil.army.usace.hec:javaHeclib", version.ref = "solaris-java-heclib"} +serversuite = { module = "mil.army.usace.hec:hec-server-suite", version.ref = "hec-server-suite" } +serversuite-cda = { module = "mil.army.usace.hec:cda-server-suite", version.ref = "hec-server-suite" } +serversuite-jdbc = { module = "mil.army.usace.hec:jdbc-server-suite", version.ref = "hec-server-suite" } +hec-db-cda = { module = "mil.army.usace.hec:hec-db-cda", version = "14.1.0" } +hec-cwms-ratings-cda = { module = "mil.army.usace.hec:hec-cwms-ratings-io-cda", version = "4.2.2"} # REGI Dependencies regi-basinpie-ui = {module = "mil.army.wmist.regi:basin-pie-ui", version.ref = "regi"} @@ -42,46 +41,27 @@ regi-tools-regi-core = {module = "mil.army.wmist.regi-tools:regi-core", version. regi-tools-regi-data = {module = "mil.army.wmist.regi-tools:regi-data", version.ref = "regi-tools"} regi-tools-regi-dao = {module = "mil.army.wmist.regi-tools:regi-dao", version.ref = "regi-tools"} regi-tools-regi-cwms = {module = "mil.army.wmist.regi-tools:regi-cwms", version.ref = "regi-tools"} -# Required for reservoir status graphics -regi-tools-regi-cache-ui = {module = "mil.army.wmist.regi-tools:regi-cache-ui", version.ref = "regi-tools"} # Third Party jython-standalone = {module = "org.python:jython-standalone", version.ref = "jython-standalone"} args4j = {module = "args4j:args4j", version.ref = "args4j"} - -# Natives -windows_jre = { module = "com.oracle:oracle-jre", version.ref = "windows-jre" } -solaris_jre = { module = "com.oracle:jre", version.ref = "solaris-jre" } -jython-starter = { module = 'mil.army.usace.hec.javastarter:javastarter-Jython', version.ref = "jython-starter"} +otel = {module = "io.opentelemetry:opentelemetry-api", version="1.58.0"} # Test -junit4 = { module = "junit:junit", version.ref = "junit4" } junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } junit-jupiter-params = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "junit" } junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine", version.ref = "junit" } -junit-vintage-engine = { module = "org.junit.vintage:junit-vintage-engine", version.ref = "junit" } +junit-platform-launcher = { module = "org.junit.platform:junit-platform-launcher" } [bundles] -regi = [ - "regi-basinpie-ui", - "regi-computation", - "regi-decisionsupport-ui", - "regi-mappanel-ui", - "regi-ui"] +regi = ["regi-computation"] regi-tools = [ "regi-tools-regi-core", - "regi-tools-regi-cache-ui", "regi-tools-regi-cwms", "regi-tools-regi-dao", "regi-tools-regi-data" ] -hec = [ - "hec-core" -] -sys = [ - "args4j", - "jython-standalone" -] +serversuite = ["serversuite", "serversuite-cda", "serversuite-jdbc", "hec-db-cda"] -junit-api = ["junit-jupiter-api", "junit-jupiter-params", "junit4"] -junit-engine = ["junit-jupiter-engine", "junit-vintage-engine"] \ No newline at end of file +junit-api = ["junit-jupiter-api", "junit-jupiter-params"] +junit-engine = ["junit-jupiter-engine", "junit-platform-launcher"] \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index d64cd4917707c1f8861d8cb53dd15194d4248596..b1b8ef56b44f16b14dc800fa8103a6d89abb526f 100644 GIT binary patch delta 39897 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

Igj3NXa_|8<`c7r$X{#UWi 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[sex+d!zoXF=a?l-EdR8AUn8#-&A&o?v{ zuKJSeRZ&*SGgZKmWakNcOXE=)+IuYaY|VM1FQum*(G{3!a)!DqaL`kBPuB38CIxsL zO^w+!4qZ!=`1Ip``2I4j2#{XnlK^Zr(N{#5qq*(vb$?KLRLr;%lE3(stlrywB0#K;?J;QZN=C$I$V z_qAEsJV6esI`qB;jo)xV>o~mVfo=1iMubUx^Vz@e4>bY%TA`nE8EesIb_cviTdJ=; z!4D1)v^&dXZ%raeU_r@GH{sv_1%6{}F@Rjc#2S5+bTkhhWF71(LruY)_sdBFd0Wl~ zzD;LV7P`aH;BM)-x4$x>duJzKZu*QyfKIJXTc)dh6X+$n2U&49>$cGZqn{yPz$A8e z7RQ05>1|Y|i3>JdgONCFK)?<%VhcRkJ6jm&koP{hu@zlh>T5^p^!*7~VI)94M*8!=;6qLq!W_ku8 zc)&TYcqSMR36V|rs*PL$Qz+J`*-u#tiE_^1v@)A&UL7W-8d}K0RA&!XC78rPEYmkA zsdj+s)-$oqgH$!1sR^RF^(*tHOE%do!%B$cX7EhZ- zlfpPL-ZR57DyU2R9wB3-6c%x|w@~VlO31!+$^+XH91})bpi-znd5|-tNe~cxcUt(j z;e~$&6gp`-3s^|ty}@lH1VE`g(TTgh3CleBKTN2g6&Mb!%UzASbpA_hIFP;WA%BK{ z>#&7ni)rT`BK=K68b1zomqPYleWD{99-=VQdH8zL_BOOnNhvKm3G^IP((dzaBqb%t zE&CYvA?mqlo-%il5hVCpK$C%Y?;V_!4Wh>*v_GgC01TlJ0N|S<&n+-`ppN98r>U3P z)Az#JTC)uX@6^13uqYEOqO;0ou~R~fphW!(s{=E%0MUR&r{#*)F;}z&k&w{>q%b1o zh*Jm$)h;Kv+?Cu6>_SQd^p_TSm-KHKWr11my%p(KiGNx7q8Gl$-$WNX&*$=8&O@yN z{^K@yA+OK;wSQ9V&;OAdtB4{XS;2Wx6f=Bwu8FxqAKr1|-IAMbh)XrG8oD7L7On!T zyda;EW+sl~@}=OGl0Xsw+gn(rS%|Jr8HDMQqbdpor_jPRdeZrvdmHfibjI;R<_1!j znD8R(x;sAhiSE*mz-Z|n-zbHuePN-J@ex$5P))EviExk*`29sKukaIKmWa6{t@0-X z--!4+x9dt zBOJB7r7<|_G<<;))ruO~jG{9$Bv^}IwSo#HPt?W1K07X`6V6r1K?}3X<;S7W&aO|W z35orDqzbK9>UvZ8OC|~6$x2cGFIiNk8vOoP!dk{dCEioFz(?oK7^!TQX&hz#Pr~Vb zcAl5;R<~$P6{)(C24-#QDXCzAzbKrAc%yrPReA7se-7|#(@P1!Q9b5oh@WAoS!%eQ*cfO7>5Q0PJp}0yC-WzsG5`l64T^l*}5L ze=7gv=3a~R1VP+DqF@Re8g$JF4_Oz_uE!q^>Z%-wRaZ4~LqTb*7gvukb{&R{|H3Rg z!Vt0yygDgKK%vp}As+I~P0^$Ql#ZJOeLVbNpYOP61+cTglYOKle@dIVoBzydXs<`` zGV+7VLqY+5XFrzuXn-o2Bi3>+dkv@4Eii5uoF~NS2XjA1#fuPT{;h>r5@k)WDP?(m|5qB~|0|7wgeqXx8AAs13)=tJtrv)w z5-18utqS;(~@;%SXT9ivdY zPzWpPZ}DF-l{uctx~9VN&V?=>=boR}-OtlqKChD;VAl0xH=m&}49j(KTux4~v+UT2 zzZ|DfvNO#2=k^&t^KaVV&q$;0@A`BF^vzLHS}FQ_+vt;A(6ub~RB zUtC|1DavJ8%uGBdPPz{H=1&kK5J=?8+a?m}F?BoU@7#tbYBIxQg@5ke(e>(Z&iU_n z3-?(|Ew*kw0^a-L zlh6_tgukzOB4c524(l}BD5`BLxzLH-bLpUtGtvX_CwS#3!-o^{l@*o<2X#YSKI8*m zCjvDdjzU#k)Ask?YZw}E_zWBDKM4niuC|;!!2uk6@6CF7w&iBQO}RuvzC1*R`0pKp=+jif+w)&+3|xwK7} z>@R@e0_L|7`5FP0hUX#dk#+2+k`~rm%A^2I>Rad!8t7A)o@s01&maCJc@5Wmdf%Ds zm4v259!A;PZw>!kA;%IaT5~-+m2uSxN~gMD@cow2l;;coxXo@1#n|Lc&H3kd%J7vr z98Nisf51ts21zw*`9*IyzgEa3uu<;&v!EJ2wNTm{zC-*}53(aL7A)YWaYbaBQcy$p zN7ljU3`-s2woUOuVOCqfknIiW8dV(rP_WRXJ$o24UW#F%<5eUQkhE0B@XHD4=$5Nf z2mDV880{UqDg1l!f&O0@$`Sws*H43jC-;%TS#m6>iB5+v7e!+cCEYSR48?1a=xp4s z`K6zT`$;DJa>{|vq=s<_qW+@2WyD$3#;{#jUw7|upYfgv_$2}e{DR-3FU2$J_2bI( zE2wjESK|F1D9fYs_-)$*L2B~2=QsatNEVhw`T+J8#?h2Ji_>v<`!OIDK3BMD!chhB zbl9M)FUFN&jBF^?K2%Uj_a}d(G1EFXUYB5kF*2$0j9XY@8i?Y&BawKS+@GE;Lw5L= znIQlV+FTW9E17e+*b)I4#^64lee_+Ql82H7J6ut@jUfK=&S5v(BhNWL^`pxrVDhMk z0c(lFL+JOp;2EsQ_d|faMWjzwE(<)S+|K|7A4JE+&X;88^>I8SLMt1>2ExhS={eJ- zm%>RzGK!As|6-Y|=HMxRy z2dBzLv}Q6D!oJF(qG)A=Sk(h9@8}#MqGCsneFwM1iCFz~j)7Z0N{Tp~-+Y<)s4wtJ z@7ia)@mGlQQz1MAlZRWdcs8TN){DUM?)vj#g)HKySoF7K<3ijqyK#(vj|?T&yr28< znV}RB4XkV`k^$i%V#!dC;^x)W0-bl789`dxfgqrL+m7P%E%bDCT53oZVvRp1atbl=yShsR^?B!+V7j^bof6QG;*Gb)6!DNAm{=q_tq^$RQoK@Wn_<3tikBwff@FjZvG)UUX+2 zR@cp&8;;wDt3sVlhMgsN70)8OsSdB-rulDFcD-kwbMAAlyL#WJ^Lih!$n|D>Cp_K& zFSp&7*VQC*hY@j#g~A3TB-PFp30Y?j>?Hzn92oLha1cI|vUnYiCa$`z61S!lL2EN5 zmv1-uxs7pYZx^bxHP#Yx`=+?|Jk^Vv4Xbu63n<6xbfg!iLLMN8aYQN(peYrHL?1C5 zBZ2j|-JOowW}y_;_$84&DyuuG>1-?jPYaC(^rHGAz8yj1gXDybfZf@8wQ2LV6Y+Gh zqEJCnM8#WTkfgK1+0TNOZHS22wjwns4XFu2e0Ih;nPU@FwU{ii?B*%5$@)v#1+Umx z)Gc-#vD=~4R)SDJ=HHn6LL6h^B|;&-_za{T$-wFV2Z=y-zqBx-WXw6qRNF2+i%knM zhJSO^v<~+s(}tOIn7E7Snz)&PR-EW82F(p69HtgFHh`e9yk-_sqgtqBOEQym zZe^O+(74Y}i)gWr0SvptCV^-ewEkBDR9<);3(lpMU4@ zhOWkaBJUDEd8x9J%BjOoewr_{+nF~1KU`g-?M%zBCXVZ6JAJf+y8Ps$Dmk^=PYYC9R1j~V{s!ZYSt*lblnt#y*XGQZIrBM5JcN`WaC88F@ss%vW+14cz-F&)O7W0 z^$uI+QGFm~6a=z-WD*jZH&O5^rWj@h?2Qh#!mD{us7eSl7gqCW_SE=tjn8yqw&Be6T@Ao!seLr-h; zVWw+K<($6y5y`SMuP<7A*hdf1uQ1h3t(H<2c74o857Nh{2S7xlPoml&sb@OPOa|Em z7KOQI++k`Bw>e3teDnxC3TgC2VtPz6HO^_S*?dH%Pt#+fywgbUaeqA(&!M|8`fS76 zI;4W*aS4ucdIA++upx!^(q~aH=4PtV(_m#A&R*lboMAhKYBj>N`YlD5$n-2d=c8u` zZBPvu6?jjUVNXMsY&t`qlTDw8>eOj^qOikHzwR!5u^2NVRl2adBm&Q)Ihc8yj$AU8kTg8Xw0Mr|yH0VzM`QF7 zfHR1HzGbraMbF(SG zE|iz#XM>OOB7b0xoTAY;kv=A^5H-=y7EM{Ayl=sZFhz-`p?}Sigi*49!+(!{U+nt_ z2=pQ4A1HQC1g)#&{y!1}K0|-ZRCb_4qd$eifDBqKZ#d8)1>-yPXFfVde?F}ffWU?{ ztKUW9isvjzTP|v5m*HX|#9z{1`RIG}*C0sRT@b;ta#_bn_~~yXhkcL!ww&Z&H4%(o z%%xFBcXD>;Fn?GXN~SyR5GVKn{ezU?e=Ih7GqQ(9|BSsyEwpPWbGS#B3W0y6ANuHD z=--faiXA}ksBQ<7Q_{40>ED^qSo|29uGj`>^b?d*wBvsIFLB48(tqQ;c*?X95kHd( ze~#XequvmEqaCd&o(HE04q9d!{`YgleQ;3Kpm5M}O@AD0@S<;~d1<@R%VpvxC@c$x z5sR%^=_Vwnc)5I9b1J5eSYkXYIwWS$w2I(S1CUR1tIYVhL$;Z>S3PWDP*Z6obUpwtl;9kqt z_&VszLVqevT1JnV>A`Ew&&$~7t{C^5t9b=e{S-QxIbt3*+9G;- zAffLv9DPuaL#h#t--aeBJ%wQUR_O@^I#3LoiJf`|I<;3uO!IIqd-cX=8e#89*7)TX z-6O9~+c~9DnYR!X;a0*}DWD%w<&FXxm}f?1eA%WWkGa5*hY+<6@uh=LFI z;$j&u~`noqVa8TzrqFG0Nx4>7Z7`N+s3mz;pI-Ll$}?tQoIcbi}47W zKcL&mxG?L=44Piv>AnJr2tVJUUIE+5B8O6Jph3@wAZr2IFzL11lA~4RAp9RjhokNjCYj}n%AnX`%x{h0LviJ%73SiXfmBm8C~gg&XM-X{Sv|t%;=u4{AEHFsCWDL zIKKx!bd&tF7v)zwx7xORJu)-fEK7>j2hjX=6;ege5L`IemobiI!4I#l_*B*i+Gt)3 zxW@;t5D@C{5BvB8KZx*>_0}V3XiWt0Lxnd_YvGfkm+@9w=wi}S$dAFxOnJHO% z#Lii_NZC|_ca??)(Swk3dFic z>6$!Ue}Pc4Bh446k?Aqogh`0$WonDXc3q&gjK=Hco(r^z=~Y5zJ45qZ6a@6Hrcg_s zZrgum;+3Wsz?S(L{I-&3f@-Nuqku-Mh~A_ojoLKYJONoeE*22}h<{!O3XLnhy&&Kk zs!#&1Y>FK`I7(Za&r@g1dD=EkJ7V3Wc}7Jl)mJkvtvPm8bq&^E43l@x(bU{>eVwPSysl!D4!_VnPG+q3zNS%f zE-EHfw2soyVvQPWX@9XAmr$J=m(p@I2I*~TTt#cu=&Ha^JOL0I(SWO=9362*ocA@? zPW(VKH21DNy?cM{dwV$S;c)pFy+2PMiiIo2>A_f78>fe2Eu-|&QTjxlJ_TbmwcvkD z=suIDCu^VT&(p7+6HRG{WKN6X9fe4bv6ZK*9zmQmRO$tFkD{KKwt7gdw+6EWk=;k zZ(VtFp8g_sv#;#46dR-O=jrcG)Al9a6^nf*4tD4py({#C9gFDi)0HQmpsFR_WhYLa zrbSIFfHFGHQGaCFi6!1V{ZpORJa4ftPd@_XMsLTNi7$wNwf`Z4)M<6)P3Ney_CNFV zdY=9#PnXX|&d~Zu@eZT(X6-~#`T#SgP3ra+13V7^F4R2Ao{J@HE)gULuR4#+VE@a_ z7ionUkVEvE8XIA$71W|&83k^kHaZDd#)ko~r9K7AD1Y!>)URL}1wKUgDOg5C9U>ODe z3708YM!YioduzUk8oPg+Fjqsq7$kgbZMvrLpAkhSLA`7I_$vF}v z{Q7q%Fn=q-7q(;NwaFC?uj%Qm7OMq~zRjLVJOchQZQ$w&$!4<{lBA89=K~p_3Kt1j z(5^`HNGrvHM?oS|3z(KJflZrY1KLSOB-u-3cTp-y@v~r1fm9{wsz$zC7gA0iPQ)Xb zLh!e30j{{f{xT%WS{GcPz)Ms!&ebtNjdEa&>wnG`^$wP0%io~+ioK7@=teMW#8@LA z*W4q@HbIyQ*eKg99AaaTsTSgxrwo5l&%GD8OAf z=YM6CuYT~X^YomdU~`@$v7W+d$YUWnZQ=(=X=f(BA9|HMXL0ad0q*I~^WM`G7DaV- z%TbX4_aY&kp7S0N>-Dk0{33_jaqT%Y-)6AK(F(*xiCG z(HuI*iA%Iq)&o3<)iF*9?nSopd?e5BDt~Nk8Rz4YPmw9!o9Fl8J}r5EKL#Y!v*UaM z)E^qEUKYe= z@hFdYlZ%`{(eSuYRz$3(d2UTqA@e#dQ!a5UYIrSNVhvp4Hh9{-;Br6Q;ZZomlYgKd zL-qeQeDa5Io;RtA(J65k+^LrqumRc{`3PI^)Tha(>e?wOjLJJ7R^EwwcPsFtMKGek zj~BsR3jAad>`~y!A{h24_|ZwYyxRL^(qcH|V7OvlfIl6DpPi1DhoTjAo+uK0)Y}xT zu4s-{Yc0_LKVDZc#!tPVYIzy1s2zU!Ik$)+L(StGILP(?3s6f32;H}4Jn#=T-f!%(fSW!?^bX6z`+l``0gTw@-z(WnDwI)6_!|v^N>3(H)w}u$`A^rPKW6iLm zAohHjdQoTwkwc6t@<}GdmjjuY_JHhRk_Cye(U*RILTg6snt_Z>FV8`A|KYl9FjqBx z>HC@QGms3Vc`v7gt``z1FLW6lkxIB0G38}p(pjH$OvslBV!0e$MNz0d^YwaH#lAUUp7FgJB?re2iFM7M} zt?gESv)Ao3+r7R0XH9`>>$jql=FT1o=$p3hgzB2)d%cN$Av#!b&ish0u2`h$}XkPRmAWvrbmeLKR%XRDrqLKZ`HnX0E(dfsSGkQ@AZK z`IH}zU5-{T!6#tx3uaz@#B8 z3cOCB@B>gw2MCINWgXZ7006QAli@}jlhqCnlRZ`re^+v0aByXEO<`$nBtc_zX>V>W zV{Bn_b5&FY00961001?P!A`?442B&FbnL`4L>xdYt6(5iyK#XNLIMfSUh1aV(zHt2 zf`r(E@F*O303HhAg7CqzKmWh&ukVjf0JwmufcNe8K7W-f)En}JTuNQanbb|)T8Eu& zysDdmf0zeygpqhyVN|*zy@`Dt<+4N_64N$CqlaKcwusU^2lHhQW!(9Wda9d1qtUJ zNPYlNO9u!m)M8Ti0000ilMz-OlWSNvf6ZBWd{p(dKWDZ(xful~1Q-?>LzKxfiJ~GV zA_fv5G6~24aoFO`%uO;fGdIo>hznJ#w)R=|wYD|Z`Yg4LRk~&4GS8oy7a>HmF0kqFVEq3ry>z7BzhI^c>*NX6OO5BJRIx6YQGv!;4G{! zuRFhPxi_TtSKMGHW|I9{DjrnVe}p3{Q>7N~sqcv^p@>?)C$9AMsqy-?`fG>r)~1AG z5?PpLUaj;i^${i3Q@^3>YBiXY$i`%eVxMWYXS;8F-=7prG*)e8nlZk*I-(>J63I+u zJ!*1eTuXuoSZvk|8Wo-@gGNFPrsCn`K>b9RMh7|QG?_~2bfz<>hm~k1f759=Xf>2& zNX)cg(h=jkAnv3xna-eDOmnA#l4v$lDaiV?pl(bkCPy@;ChNCs@`2D?a>+D@<}o?) zcO+WCWKC*YHnmPdYX#bwv`D6f+$V)N4}ke=(+Vk8h$`8>_ZCsFu7k)leO5WpEPK>IKdEjY_f?Mm(3v z42Ix8oYsadiTUB)B{M+65BT4m^Ne>E7nBpeGTFP)&9 zF_(5w3$2lTqY~6XR3J@h!V9y zI(07`I0>DaJ%aHKw6T=h=?bQK<4kT!#ggHu+OjvO_8FLdrb|~Vv6z;0ht#ARk0PtM zgF>Z!P?ft|i@USOf4eVN;_mLa7Ig;^AYI61?j>g@mekp43-k!Ur~((cxQHIN7je5{ zF5N*_3O@|Uv{@*8e!j2y2VzNOZyw`25V!efZSIY0dz3Drblq&b1eH!Bls3X_v800( zVfQBLGJK(3iK-3?8Eep+ZAabJO1#oeJqY@`zPJXVlVLSsf2T0q3C52oB9X=u5OaAE zF^f1*F)4RbL`WHBT5@Vcba6DnWS^1b3~_{mIVesSiycI_JI`Z+kucI&G^)fxJ{S}T z2^C?H5|lQ|)K7a5T}mXP?b#CB9n<#2Ht1Rf6-GW7pleG2a~~sU7)FA6kfr__R ziz3^+2l~?be~g@XQPFzfo0=cvH0a_cx><1Z-f6ktkhS=&u!0irNkt+2=7By~?2No) z^)vvI@1ysZ&~0=(n7_tO|AiEMO)9J=?esycG~4Me7&kGHNUBk18$E93w5s&f9;E?wQg^7bU3I8I@mlIVrV5`7AF+^}q7)que&oW)lN*{1a2xKGn(grf{i zB7|*;e?AKVbcG~DsOEFKT8l)~T+Vxx4#@NfeU8cHDGp;qz!zkCh`uPg58ouNvmlSl zw4c7jwCrS|P`OHl35{U(r@FHH5*=b%>zT%J4eZ8=5R;Uf_P`6zxa;(Tw z5JqAV*&lY$h%ssK-z7mSO88cszET%aya%U^i!d- zpD`_c_xKY10vRpKuCQ`b91@=EIR#z{x%eghN~YK8*P!NEnW)O@b46XXoqh|IhGQXh z?}l#p43yXEpf~9ELRWtfzT7&MI{zdp~n6bYSM z!K}{fKassEQ5!@thdVWg6C(aX4tmQdbN@oB&SH3X3WR^>CIX$GrW|IrwLBrys3@PM zK@A;AIF?wi4mdDqp@n{gO-yqpin1ydj)YKs8DkZD?QE0TD%u;H=&E8NU=|gBe+n{< z4lZFCB)Am$BdHmi4n7TS3>GmeosJFxX)&i>2hXIhK{I@Yu63vpMJuT~xJ)-MWB##4 zFij?V^=#1U;MqI}R^qvkQH!-}+1|jx^MrYB&;CeX5z#u7^+e|#ut>MOmnjrY78Ctm{?!RksowFhBu`X=cfk)8!Tz zW*zL})3n_wXlgf-VROrxrY*kBoohEWHTzmRxAu&9d zp|uRTgQ-Lk!?K}Pf46XWw{UoOBzu>HF*?>A?nw#QaBLD>gWJyUM=K7|nz|BN1f#uv zdBGph2Uf;pV~%LZ{2!z>f`vQ9MbBR3Gx+D-BI7qPCYy>PQe-a>TJ-w@lr;V@L>5VV zNzrsOQHO@uAC>tY{us_Qq+lv~)sa1FbyiZvNbfwz_mu!0e-qC9B1p}cMV&1W||XGqFo`SvhZ@L@?54ni_)H8yvAZzP}8t9 zjk+6)8Goz_e{6N|=lJt7S@{byY>Y9iV*K22tY6!$*86lx+SH`dtpvf_fW(g@F+|4~ zn4Zs13|Ty2^lBlaG9@aF#8afyO@%0~0{(BC#*x$GR!!brtwbXJuxL8@ARm(XOPq#E zGE7hWzp~i7yn5Wghn+->skAn`?;h_)+~WFHzwR5ae=B;jK{@#{)4U=_wZ;-jC`#fZ zg_jXyeF>78=&hq&dOz~ifj6zrPR2|2BvkXGjEPtd##NN! zX8j)K;^{10nB^wkYx6VwtRVTE$lKvAJ3o)u2xAeBSfG8%vL7xyz#l_XBu{80T!&n6y zzvDM#{w@C=;w8ijyIyDV!>W?y+#ZQE86+5 z!fwFSN$9s6)3#07J5K&P|3hf!pLPr)`USUwryUVwp!x7@MuZh?YNrCm| z8ozUE^)PMA(DtM2#d>vyt~yF49CSJbXeZ65O7hT3GMQxY1)40Qcr{71LZZdQe-f=6 z1)%ZXL^Mh=aK#oLX9EEcJ58lJHNiZLhy7J}mc^$hLo~?+Awk`8pt>f2FnON6!0FThtu@=3_X^igCmpihh38MJGv>(7@?PdD^R~bH2OT&f0(9M z2FV392?l)4C3U9h=V|&)gLP>10QP^U@7Ia_nJd!t$7KSr9H4(OK+CO`f2;JT*V6P4 zfwTumZ|X>Hfn*s6bxF2yu#Jz?+xO920KcOH+lHugghm5sAC7u~2FM0Gq;}cUY#yXp zf)<{~c$?|X(rzdbP$fFltuE^bTLZ3=&N7xV3{*#&XJC_l4yn`Z9Hg?Gqy`@+o^fHl zyuoT+W-qt9q%^zspE&5Uf0o-VR|!$e?YgWDcAc)hkgm=SkOAYeH-N&>=n+`z`T}+Z z@u3sS)SP7@Rtl6fFA&e?yDWmOMI-b`pgqHG=iO;ue2_h9u7UBahOKF>c*s~m zpBq>v-A~XBUYDkMS;x@mOL!@lTsCvLBm}Wpt`cUpbsD>eglE^3fAR7RHx6@CgH;?E z@OHYa8E#JV+A?lUv(Gr;I63g@vJLYU9WG12xesgLtK%SdxbU!Tko+!qYg2>Gxex2` zKAq*AmYanG8825^K1Fj}HvP?<<{&5|4GfVw!fK$5dotX6)OfsFJU-4^2hJSkgnoXx z;I;w60LLXYz-PQ=f1DcTy;JPY&{u4rf~DN9A*?QE11t`yA*wFtb;n7v43WhwHXBM@ zc2`MG5BdsX&gv>L7KZsf!bCTZ@GXIMp^ZBbsyS`oVOxgZH%JS;y459E{dV2zcNm6G z^If%R{?H&bj_^G|tVT2kYDf4c`2R;TeD6WNfBgtQ5NPvOe;?$BaMmzC+?nA=YhAXQ zCwPSDi+Rbi)?da?=CUQSnVu8*E?O{3`$;l#p#IY@(SC`JN%S<)ziF97HH$7dXOx^G ztB)c*+Ka*hOn_J7?CF~!ijY1!?s2P(G*iUp8086p-4pkW&m+>eC z^A*jv2v+sFbE&8=`m1~>8o=qo2P{{T=+2MDjACuf)v001i| zli@}jlP*>llBWoh26`zT>*2<`Rq)hx@dS&CH-acAf`Z^>+)lUA?15xkFT|5gdL4gZ zR^YMMI}h&NYZ=~B(sXy+u;n(~FpV>%WvhS~3H{3wmtZ{noSsMIg~cUfpjr8|aB$yymPQ9t>0xyXy#GBv!X5|!@@%rE^l z_zy2%3Y3}jM ze%k2}?mjn>O61lsT~T*}O`dRDZ@h>4OPL&X^_Tjon&$Y(pcRXlPc!7(sZ8_WD2e{zb%|^)ljzNhe{O$Cr*ll3>N@q= zC(X-_AU@I+{uHK>8fYYq>0-J>47CL}cUnW)_Q}Ew>CoUmYNf4Ma+jHtv+bxq z-Xeawl(vg1ZvuZ`GSTay%fus~Z+!)0wBgo4&Dc;E6zj>wGPwCmmKk(~kFFH&s-J9= zRBTYLe@=o(1vkD*R*ErQ^v1p-%f~XZ)sokQD$K%u;}hY+4sq>v(qdXs!Asuw5aHlG z8`m~1U(xEJT}UUIC2Pj>nM7{5r3--#QEgpfmnqjFfh&Iob8Bx&#c|%tDy(UrLuDB- z&2CEi=xTz-?p#`eG4@o987Zi$1FiIfH%&ug#%q}7PafYqWTrL`iB$~B7Q;emRL2*C z^0?6{b8km#D4&CJW(;d?sH?Qn<(<=sFK!1TWpbd}UfSoQJv3Zgd@_SUz#;1LHiO=b z%Yh!mA6I|f8E!{!n%%bft)^VT&#qM+UBQs(rqH-UztvtdOU6UM6yrP)a^ccw|MpJ z362irI-SDai*wGUH=6sbImcbEQgnGAz28T7&yG}WF?^(Qieq1-?$ zhYvG!M)~BPff#OWPk!)>&`>6giMinrLdUSIWkt3oJF+#~C30D@_MQYB5b=Nb zARzFBuWiYva*06`;Lx-~)5B9x$E4hO$VZRRqd?w3Cq4P0p$r10iR&`Id`9W&>q(?4LYq%kP*U6A%RYLFzJdT~rgD<`nSzt>aQha02T?6$?#tN&QzJzQ zGdx4z6ZY>TFCDj?^-y!zpdUhG#D{J`06+a$;=+&US;Vht3kQiHTQf1K31fd2%#t|! zAAsfASig=hB8%zt|4{^llF!pmeDt66Q&|}Z*FCr!xCndwxfQ^Efv8(FcU!){U&6}f ze6B1%{R);saxCv;y6_**j^%=&->>N}2U?lOa)96Z=tcS+61Bz^WvaB)byl|i zv>EyL^at^dKjL63Eoji6;L3k{fk|*?e~~o%XZovr+#<7(MSXFw$(71ln7aZ*+-^}F zn0MuEzpS6^*p-oXrI`jDg9DUD8rZ?MwV7+#wxwgWpNZK^a4mKuH)mT0 znDo@T$wsT6YQu#b^6{yB8e(lOy|$;lqoc>xY_VmGC8!U&)~)a`s$bW(ts9zFdAQE9 zc-wGJ!qU7-W&zgX25x^8jl(v+69~u6KwsQa^h4Be11)WdT}61s%Wz-oIxOaDKFi0; z`D_6w@0V|_sK3iyq78WtRdpp}t>SaUHE{i_FWj!XylJ8DH+>DDRl% z<|_ay;uvANy<%*%-w-OE*#FP@=~RFc8HHsA30&)`p^=|=@>O$)81?oH9q43SR`he6 zFGWJ+KFNwm(az>%e7A>DC!E=y&I9)8#~ST|p&>nO;(>o5)Su3TjgjGfts1GfaO!WQ%GkXzHd^gKT$mJ0q8X0qd>JN zKLqfEth9SXG1MG9f)m$}Uh1=?pT0y#B^rLR{3&B|nIaFs^b?Bc znb?2Gzrp0PNe`n63Qqe#Z}7wN_?AYpJ%o~nA7NY|&lVhq)P)`%wcO8sCGzuQf~Ifg z&!8J-jhh?HTzo*h@;d5T(^g{2;6A`d??rQES0zrp_wAK4R2=1oCB z^Cmljownh?U*s?O=ng*0v@%qeG2!{L*3y5zkW_uyuvH<(QX%=-Lds3~0ZNKbaWQZW zX6rrt6dbl0fhOl+ls*1+WhJ+VpPuprGVQ}|xm$i+-0~X})mbUJ9#?Mp_*(*lz76|l z^z-G`w4c8#W!_?b2Dol*E+-H9(6t5XTJIOlq2f_3&3gFzR-7UN9Cb9O5lDXw*G_+A ztx)@%u08la{1l?o#G{^UK9w?$-gf1)v~z;qu?-xq$8Q~^KZrBe#0m)0u^6Q{QP?hk^Di&2)hDh zpxsyaPtyNqXrK?e4M(}TzrQQ%=f8hiLx1!0XZdro%fG{($d<@e=}g&MrcMtXc0V@t zIv=Z|wLA_mcl@}a7%Je7ccVb{D+el8rIZs_ETuc#h-K(7uCFsXzpU28Q9D>i4fEj((rwm>$W+=JY-X!SPO(?_7obbRNfV^Fg6n zb*fjLq82hOp9mJ^CF1mxb#PRt`P2fnNUE#SbW2rxe2GuZS4;KniS>0RQl?*>foO%! zI($e88Jq}{{Su3;s4eNiqZ)r<;dHiH?wv<9Sug1q+Yfhs)q;AS)9TD(ma~3@lK5;I zYB}=tww_WIP&S5bpRHDS)mf@lzu9)C_X0fWlHv5aA0B!8e zdK9V$Pw^)j)MDlSAU5kUugROKxI8ua)f#oa%tsO7>rJHWEZ|XXMHGLdXJMz36^qZ$ zYMs1e4-BUJJZb~N!O9gYJPP$gwIC5-q*Ma>>Y_niq@P{YCb?P_-m0vl>GG-ds$0N- z{BEP)y*iIu9DBW3T_T)YCcS&x!-m=_CO}T#kk0tkr3BV(YCF?Ob<;jMsHpH`s4q|MaMxOy~Zue#@IIPkzo*F^E*XfLoI@R3?)j%9(v-*Sk;F z{wM&kjZZDeH1*ZX>V;)?sR7_7g>u@PD9ZDz-GY~HQ-FmH6RwRL1GrKdTeV$uVGn*3s}QMP}QYFiLeDjh;jPV|KY zZ^&4)N9AG5_H-ZIdjQ)n2s1luiym zO0`Xo(!z&yZuEaj`m<*8hcM5LzP~pV=!`qbH%2X+M(BLB&Wdh&lH4QXFE<>fmC>$I zTJ`uEN2@d7tUW-r4FTu!Xv9^Z)%(d84&uxC+i!I8$oS8~n;IS?T%P?@>--!U(M^uV zo;e#D#^|C=hp98l4WqRAAXpGBocEUVY@5pCc#NWoo}hol=v*9)b~Vhoe3W)T&HYpt z)+?VDK1^4NYCF;HjdmTSS>eZ>_mMa3SUy5dezIJC-xT@st%2p6zy-ArpE2@}!~P0? z>xsr;7-i66yHO>L6}oYZW*D@RIXI5+vfeN+Y9vRPD9Ke-4Ss*8hV_KJ+5$%yQyc+ zLqVr?7LP=66on%}=TWNG>Wq-5VP}Cp({KbfnNPK}3j1A1r)wIKC&Gw>b`}NBD!>P}FCX{fKTnk0t$9J#%d|}_-9oVaAd~SpG z>a#$eh;|;OhQ`OwbF8U7n(9MhC3_6YxLq0Oqr{ z2Ua>p0fYXX`Q*Psu2;$@+k;-Q!;hSMEpR6N}*! zjZFo5Zj64WFWw9LtyB8t_L1>#z?XW%O^4~lXt(s)PWYQqdbvQaz!jZST=6cNRdj#F zzm1Ilx+!YA->djDGJeCRCZVO%$9?|$L-JAP5Y@O2GpJ2(ajvE(A&?1OL`yZTqgGAN zp*5Orz!ekP1rxVvL+_Lm#69oVbb!*D=IK^V&l6)_EoU1f!(2sxcMVL+_cUkX?mLC$mO7q7N)SX%Y`fVA8EOB#5 zs8hm=y$EDECq{Lon&NLh_*ow&+zL7y-u$}d0j~SOioBv;Y;0&e#Ez~*v=G;pjqPX@ z*pDNx;h6=V6K!?fjW9togU*14+4s; zP6u$}2M|yqE_h+YeTY{>Pz|4_!;8P^5U-6GBQ!UNzIN&3m(jN&Vl)QbK|{nfinK%A zQ4%O#C=%hvBGNd-ozaM=D6)S_M0Sr*P0&-6_-2vV-4HaI%H(aHEYJSxEQvluLCgrc z!;PQeUZPE6SDm{$5iHr%8#VMsxnIv8C{4w1v|D+b*6^O2Vk?~-aR=Q`Qjgs`&w0n)wBa!Ci$;ItSgyxj_$>u~ zn;iSwqg}|6L3h&_--8YE>_}wGq+Z1$njZi8K5<#+f7`HtZbRVTN!%abV!(;qj zmfgJ{b7b{f8<3?B%1~J!cO5Azjvd$V2lbBk6!@+hzDMk4Oxj07*jA!6E9k*~@74Ro z#1BufmKcm_7<6W-;g5edjPl2i&>Y-)Q$5S~Qqfvs;kI5wZ{x5G%$F_8L4F>4YU9_+F#AJdT?>byVk@*J*#qLm$)mshT{;bLc@G zaV{Y5@xvJN(BJILHLF}eF{N1?GJKOpLt54;;N(Hw(1}iW&PDdrod)kS_*$pI*Oiu* zOoKl8*k{Ky_XPWO7W+P%-J|257E+3#vR<)|CL}Ku$z|O(zd+_vcTvAa$<;TPy2Yek z`-!NC@iugIKdyJ|XaGvXF4lhTkwE_pbl>$6K^Z02xiGN4)RW}7u%`H%O(#h&M ztT$U;NNjMB!x{qZw>E~y_)`x>yBng1=;UHJ_;e{8)bM{p_zV{tLF+aYxL|WPfqP82 z`EY6I2=;}XKyH4}1`o(18w|8&%iEEqfm(yz`C*av+Pfqixg2W(PW{a@n_p>l);3^; zh^vN=MBIY5BZi~Za}QP3@aH4m5kjR45S~RS@T>w5KHIs4-+e0HyVGyX%_^YM_}N$(L3k`nD{ojL(})s zr!_qYw-Nd*J+JAD^gB(hgL%vsE?9We$BLe$rFJu zp^SfZ+!)sQ(pB*kpDjB@!NW+l{Ga=&F^sa}(_{RTs6c`j011u~9Ohuq^)UY`h_06k z{IVQl(0Pde7;!sV4R@=jQP1@RjQz9#;29X@FRe)bueN#{n*v4vr}!JIS{0}Y_zr*2!k`hTLIv#C8de3pLBB46t8mWG2fctj z#$yVnV|{T6xISCHc?4Z!)ZsmV_kh?>H8jdj0LzvF*o-NExS(cY zQzPu%9`Lw7On;Iz|FUdKkQc0?1-dO$`o)xLjxAHoix}GC-bxlPvI&HNd3<6X*^_?} z@CB-1pu=iDeBCC_&Lg7aY&8dZx&)#(LQj{;Ev`v5G^m14zt5llzd2zjwZ0QjKy zNGWnb#~KyJrmYKEAzJCwJ~dnc*hnDosH>u_o)7WjfN|%s#R3}ya*AJciCc6ZrPpgz z^O#!puv%GAt83JG1+`Wqsb{RBrm1b61yozh`u0O94#hn{(YCm|Q`{-;#ogUfpcE;^ zf=h4+q-cR+2bbamFD|86v7)6E{we3))64n3td+G_vVVDJ_GD&f@5#K+1Cpz^ge?Z^ zSH!Q=&B|-Wev1`$n2Hb^rI?0qJb12?^9m|f=-?@J)=`IYR`M&EP{!*m`NLU~sm zzpCXfLhh?475<$U!&z7I(_Qw)lza;eBl^Cx&+(l-;q+qouF0C&Ev4YA_~@- zteWJ>6jyJbI+YDDn3R~6QT9tIS-4bXjba^~waeTT17$us!O3h(Ih;79 zZd0E`4$_#Ex#m-C?_2qj`&d3WD;K_>d#rp-Fwb$!GNCI_wg8Nh%M?y7JJ6s(NXSeq zR~^6+n>KYZ=)&){&|(FMjfqD5PJ@O$jc)uNVgoV_R{t2G^fPkTe~E;7-wc}OWdyAQ z6^2wH&|jb!idpA;JCSnW^u!F2GnQ02Fy~y@c>-E-qEjv|7t$He>Z;SbU1j+pPh<}T z87Tm=kZ=(_h>cod?!Qt#b7)kmz;K~TKM?ZWLxp9)9BWpUr!tv3K3j4cnqS_(1Bn3& zBV#Iozi4N4YMgxTd$Sy~fJfe2`f-<&|+Stf5!sU+L*Zc@On4PkyEI|Hw?aiuMFG8%$J|ONNdi z_>qLgL0~Arb-ONCqT+ynS)AtQf%GAXn{)Ug%Nnbm%qPwP*c&v?eyoHIWP-|d;qRXG zBda4?yx@;;)|yd7if@gedd0S&@2{h!qcDb<`eV_w4sU;)z~ZvI+3xnq3>s( zaVoW0Yv$!Eo7?G8D|9D9tVJunC6U{2;r#Vr>1T~<;;T85?Izbi zpHs;^mJc~g1lz+_ACnX;IFWG57znlxWdtT#*Dq5$^h>~Oi!zDYx#^jDd7);h*)S>Vefb-&kp$SG@S`W4yVR|1Qy8*;W-h3yB zjgpT%*qB~!kmE}yxZuY2NL8w$~d9BZue_mMq z+Qji?!VA=s#c3SzhzH1UY12O`~Ec&0FVLc-g-G8YxFu3M3xklaW2cXA^MB3yO^NbxviKkJ? z@%MuGSuN;sdB;ZF>UNSwnM`?X-H8R8n?TtN5MD%v2rnW{P=cxwvJ_r~86_WApWU@V zlZMTvdY@DwCltLP3QJ0p$k>M|MX?{UlP?k-wJp^efrW4E2f$^Vd2XyAfXQW}DAm*u9D)VL^uy?Sz~cCMi^@SMFT zqYKW;`_KcBbxrQ4VZA0a_>7v&o8kE**S4kEOqAKg8=JVI8l~v>N|w54R#b-;VvBZ8 zuS4FVF2BH#&I_`>;x8a9Ry6-SCm2=XWRH1JG0a`t8S%~gQBGk|*#KhsHs@ptGPzww zU#I^EWzDK6_t4$L#d`Wc2LgT=1V_j^Y%wT)i`&t|2GEE4^=p*QC0)nT)}BnE<^Zjdb( ze3VD#0sH6YRFiwI(CHP<3ruWy*LcC-nQGEb?qlYNnmro$EgE@3bKpGydh%7ZP zduvZQdnap!mo8RL)*k=LRC}jwq(`Ykbn{4qNljY$S+Z7dUmlq>dqW*XKB-Yr7>))8 z$qNoYZXrcfCY}xBJl1-c_$B>3TJSf=TxrLdTHLlD2d+l~mllh*jSR-dne|LOwq|X? zLMzMdx1e7`RRDI&@U?;NNafG2ma>%jcm$oQXURay+l92 z)Y5Irnkbhx^8J-bnZ@eaO+1ipqBz}{Gr{-M?L8l#LAKb6Zu*TAAT zYk+^VTk#01fa1>6ZHsM_4N6fH^#+ix7*bx;sklj7ohIW&pW#flZ*% zYtSb*;SfQEhrxn{>%3RwSBUgA2det2B(%5{Po7L1paF*NQ1lMUrQsoW#OTm2dR2DivWmM|Er!PNx48T_8@bFU5pdQXonS56kA})p|+Z6QTdV1zC~7n zR07&hFJIAqJMd(t>Z(Bgw!o!#L<|4?Tfd*BS&tFY6K|o!wA3fhY{NNp6thRV1X?0O zUH9z&dc<|0um?Pw&nrvn=!tDYC#il)?7L%}D8NY}VR%qOr7vx2I>aqRfI(K^i|TJ|xURK}Yt=?i%klezZF{h<$4fi((?DU<#!K-Z4-R=m`xt_aEuXSZ zxqonNj%(^4k$7>sL|JLs#`#&N|A_?Otpc|9JMifXttm}?|M_dSW1yM%keKXK#cdAC zaZH>jX^Z-*+IRKB!@}>6odq2@o(+W1?fdHY;uUm?#Ndk-Ov!UnWYetmuP!0Q7YV?r zTqZDgwK+@7HS#n1%^Km)NzSUPxGymK38ZxCwmCWQ4mCy#^Q+}ITxrd$=`jwAFDpuVjl=EFq| zbr+*eTZ>JeTL(8M=T+@Ui=EWn9IngBF%kw(T0NLs%j<1)91tcl_WXu%Lo%g1o0KD< z^2dv$m8+q7<~e9TluWeM!hPtgXB-xBdJ3j%PjHq8MYtpJhF~nM3dZfw)B1)z0=y~z zn}#C4h7F805s2z`#u4)T+oSb~K`kybV%wQ98FTD1j}QBLJ(dWa&WsXQQm0%!6HUMU z6J6!Yh(r38&!-M?OXn?oPZG_^0(-|mew_$m&N&HxM&_3U;n;H17}6_3_R7@VpIp*5 zqpRIC=9}cpmoHJN(rNz+Oe_Nq#{BeO`CdKB`57x^FUbGQrD@4r;byz8KxN`>BYoY* zUJ2+bXA*D3=TnCdnG3{yw(Prx(;0*Ckx2}7;vDJ2m{&a$KVODdI<@OA(3>B%fe?Cx z!rhYmzILm@iz>9yM%tU;iNcDd{WP@A{fVK{pMeW9>D&ojfdXz+G+fv)_Q8p8+90Qn zsIXiLvS`tv4!bYGHs;tRr{V$$eT}EJs7!QD%NGyWPJ0a2N%Qkh7C;?Py`4Yi!rtbB{atuM@{%$uL`l$z*T}@wzb=Lgpvx( zS zTahngJp`EUmAsX38nSG&?bU`D4ok+kEUQh^*{$1-Q&)t9s;>8Ud&YKH%GlE%X#qcC zlSq%JQv|6TrFv)G)WIQZvnGN;W*ia{*RzKHrUSF}y%O5J5)-7i8rCc0gSII_FF0~_ zzOz*XsSSKQ`!2)?dM{=qm$M(;#z)QwilKTZTKZ*WHA4;Z_RDG4_z4B-&0QY)_67Zo zB0`qX@b8gElqv`UQT7tw#xVv))C$&EfLn+Q@QhMfJuH$mG6j)ToSx_lF+bsbU!2%_ ztOPr#{Ps|(F+Mem1QV$%xU^!Dsg@Qmjm22(GDU*19dG%YLaNnJ(51EQ%J9#&jh{Bl z!vYdPevdi=g8JRA=W03+M5Mb7J(9Py@>TP#go!X1N1RMS0=)79p78e>>%6Y+;g0;J zz4#+>O!9snQ|wmz<0W-AbD{);wgm=kG}93{qq8phrQYDmX_LNEtT$4G=TRgk^x7We zV*O3UTim=NeQa4l@F3sW=E?)RnD~f;(@?I<4VzA-@04EQJg-$)2#53y2Uly{m4~*P zh!;5espS1YwX5l=4>-CDy64kLcD^9|jM%)Z?VK3ag=oBdR|D(#;k1|fI;D&fl0#-!UrkqT-Hclv)O9EHZ-b}!oJ9R zE!3FI$}oq7nqAdkO09Qr)@w7064SDtf>T(?*y|fp=hZle79Gj4EB2{^iLW-|phq^u zdh5(c`l_$6eSI8B#)OhqWUVDL@QJC=vHEkcmvn?$fIC8wMnWS`Z4UxwBC+V)zpFnV zH>D#6p=dIDXvKU;CabJ8dc7N^%(dA_xF9m8%+>2wPh+CrT|NGlkA&QC-mzYGY3Ai$ z&@NOZPMzY`ccTfovz)A>Q-=6h%$3Bv^%jKP52V0W*H4ef#RYo&!z-;ruqp|MCufYD z#=Hl{b^GfSRt4smr9bntgf3$)dn1F~u5-Zsoi@kZz5x<4NUer$;7hQ3^)!9M&lh|U# zLP0YIT5D14@R+a;oalxcl#Q-S{I1U@>qY$jO;o<JKrt;m%&s`%0xh2fD(O@<5%L_Qbf#GN5GtG1K7Z^MT3dE)fk>@=2l` z3%eW1n$|C?6Fj48%FmvV(}~%1Dxi3l5E8NR=Lb5wpyl|#kW{6tlyh(e;J7FC#))w96j;xT@xQ~P0 zP#w*qM>3WZoW10M>WguQ>%TISMv4koU8gEv)QgNof;f$Js&=LiiAtZd-dfEGo1^yg z7IuVhH1iMuH|3X@QTIjFckOdZ!$1L*E`LR5d;F!271My}^R{lq#Ia?f0OexFTRZ~y zIg$iJEeq@~FJzk@lneZDjw%CwoxY6HcaxeDk@gbeeeGqLmS^z=xVe~qztn^x#$?gW zre0T%@a}Lah}jTCQ|eBGUtKgBTj#DbdbQa(`?!gv3=jruk|oI zu!U!mr9U@1#ZJxctmVTrE-{8#$KjyVxWJ(qtljOM9Lc$SS^k6^tDRrFxP{zc5qM z$%9Wv5=u=tIHZbB8spIMmgr}G>km>1Z1cHAwrO2Nc@dhZgwZ#n3VsBjD!CZHmMCzk zov4s%0G2`^*N#FVn>nfCDLO6wT&7Q@3UA~B>XU&e%85Ur z#+A+j(xG+*ng_VeV@mU&wIm z^XgxEFRqJh=cEi1+{dz{3T<$_0YoA?7F+ z5I?I-_n-_g91#RL-J-`3vA+Rvfy;Ame>fo`2t8PxkP^HK!2>$UuTE$of`HKg0MUD( zJjor{3gHDx2K2R?A^>58YLM7H2%F*#;>hI#I?z@qD0uRRl>kOCLsUrHD}MkC53cY|KpMbhC^t8e=H;b0P%a#`IHbJFaZ8BG5`QL z?g6h=z@bINV9p{w;2$0Kf7j7Z4FMSg|432;0KE62h-e`IYA}^N?OhxGQKbR^XzzhA z9Rx@PE>XH`Y?M1yBQS0W@q-iVyL#l7pn{bV)`-8m^FQi6|Igszu=@{;kBm?~0w3kj z1OMbj0RYVRij1@W56lVtC$k3;k?kH78T1?aJC*A1!SrXY8UT2FkJS$On?(cnl+pnI znPEiqKAL-6eb!yUL{LWHKXYP;g75b}E65$>0A&UKxrqe;*zZN6&HD`z|9@xE?mEDq ztMY#zSVPfWeD*RPpm)T7&r|@w(|hqPq5pxp&_+ z^zX)?GRZ%tYb1;J;3OAR4#zHr@(s9M?_&VOl9K(B;Gl?5vJF3JQ6F-eg;|sIXXC-A zP>sU>+<+b_V4sm=zEQ%rn4Rp7O2w`m(7_{AX0s2IFXuQNsh%&QcOs@dTH0i^Vd43K zf{%*7t06#dSjhOfkd2U~y>_~nHL!bgKf}jd)x@NH*)(wSHqf41WO*_>gh30d&|bt>F@WIMJ!Hpd3rnG zF-Pf?_-RMyerE7qZ#@(;q#&110RSJ-^e-eM^( z-~9Bp-5)NfVCa>}1Gtr>T9jT7#;8j;VG_nDZL1?Ix=vcJmNp0zgvzXyTf`fcwP4eU zyPBj!_XR9UP+F`Z|VD}c-dr)K1* z7R|-HIT42)S&3A|Mw?!o3#es9F=;}BpJ9><89cZ|5f!I5#urDb6Qzaa^}A?N+Eq&y zKAQu}{dRIK!d0?Kt$YJrhzo7s^lbKIT{Vsv6%-VCiBAr4U0 zu2XKtnkqNuZ!~;vMWDl_hf@h#d{~8Oo2?=PYHce_j^IuFbOicjGa!maT^K{}3zALM z_;jQQIIJ~{+n8D5XyHf07HZ0eJziZ%++#tkh|Oh8WOC2nm<@xoJvwA4?h7L@Xyfi(3!0CO zk0Zu{B}M}-1jiER?nTrvfdJEUdVnRf`tmlw=)T<}DqGc{NiHzklp^74r`2!g2g{6n zw@#8$KYLgqyU^L>55^~pYb7HR`wR<|p5})dO+cl!q?a5YpvD|d`-BLhgJ>*yP2fTk z^aVe|vY=cK#7EG*5mNKlInhIR9W+BcR zNN0@@)RZM!O9VS~s>lcz8>0gD?~Tub8!gOL$X+_mv-=Ngo%7Hr#^XMRG-_Nz z8^YSc%nd%~r!&i4BOE$&zwm0kWy7479SWsl$TxJK<6gMS339tbIFu7DFRo!JzQF&} zoBIAauR*d1mIJ_EdBFrD&`1QXg#`O*MKx%kmF?T`00xwXj0CHaA~5pE@TpPrhwd5@ zhZF!98TbfeQ)EVA)SLNS98-QCLn8CCm(>z5^OobD=kBWvcz?f#>i>R(V2T(0wc?c&b<@rW_6z2k+yE@xH_oQ_R2^2L%WvFE$kn89 zL~C=9*Q*NX69{puk^IVjsp-?;R7CT!tVLW8bvz zn9=LUIml7>^mLtKfdXahr_EEQV=E>uE0PQD>tMA--&veuc?<47Dn(O{QZ}Ezbl4U4 zG8abf`U6TX#V8}Z?NYluWv7pO6J~$U{!K@$dqN1|BetZHKY<52J|`nILCjtEp>n#q zLNM|BD2u}D={LYcf#dpF%Gg-jxI37gyplQthl5_E{lm%?ozmxdg=HMQsx4TO)C5uS z-9%VzyB6VkWKPT?uHt5TNXkCgI$eK~VjW5ik^+DMN>l0F9~2yevxIoHufWW_eWMrX zItxsKfjKRL5mw+d<2srW3rAY$%xquciP&!9Y=GPXR${Pv#5hl69-%MLH^C)K$92I& z>uPPXwaG5rEk1~m?nE5W&oIqGl)0+-n$72)U|RPH)2Ha?bU_6rTcTGP!U5f27)Hh@ z0pOk;S%y8&PD=#K%|Gb#EZMt^DG7UXJ21kZNPb^1jAZb#_WTGf*gN^iYiaw43}=kT)(_W4S8bulFF^A86wDenKjG#HOBqrJXWvv+<%Xpsdo2Pc*Rp; zMdeP9PPV<;89Xne)K8eT6dAR_L4^P2oa{;vLpH}JMn%B9xl0B|Yk%wKi1B~rLu_>2 z#s~ohW(f1Y$%_h40buKmZuzf{ve+E?iWu#6Exv<0W^puDv`9ABRLIPeRn~|alx4P^ z_FGU*E9g}Pzx7`2^^&wluSp)Z``?Bb3%XZZc*{05yXfJo!8sxWy+vXf_akrnj z@DXU`+Wg2Uf8u}ng>FZzh8Qj_)}g>reN@zWUFbN+Wz=k&;BnDf^r5oFBC~@~Jr{dF zJ{9BS=5%faEFs_UI$=s`YjJXNjJETq@TiB5A<8DE7~vqor2xzr8uo(N=GqS<*0Ur>Uu$FJd8}P?Vmu2&Mzh2 zE(kI0z4}RdPh8fEXuDEs9g3;YP2Y?r&Q|FKsRLa8QBmdv)(K@OjJ?Ou-F-Xp`?eF zB4{f1nwg_a)*FoYR@6yyYE4v#*7)!nOQCq~DJGKc6Wm}WHGmyQwZT`gF*YqsA2e-v z;C5#DLnAKz9)iQ*nBgRxaLAFhDf*!S-}V@LNOSr?iS3PFweKDuRU}gZFQn zhoTsLB49Cnt;KL8OpF#7i*THaWH@Lw(IYB&hUBMlk>HBTgk%QKROqa^P+=iQeo447 zy5J;zM}(VRWT>*XizTMCC4%L1aBpUbW#g$6M)S**0#r8+i05GRM-N&9*M3tUX^ks zPk-<>0vDQMKi-bF@}0^%XT-F@uDfvqR|0zvA-iklr}P}dB~95OU2SJReHAYuI_X8> zP_&YUV_P_}OC&k8taoelYLCBKUMl(SYv z1{etf_3`05LoBS(MVs&A8f$jlhfZW;!vZ^pj`k+Sk92IxS37~rPx`=EQGk+S3 z*s$cdg^sZ;PfD}}LB9@4aeJY0hIk61qq!Kyq7Un+qJ6UDepDUuQ!QqxVX)$qB!9AtV|i=a3=%@M78ru(IN& z@80MU3{C8fJurMY-eG`RCAM5V@xm57FKCK4j;sa!@(QEo44tZLE!i1pwPL&{9^gvY7Cu4??)tdrnM(SASL;#L^RWSfIOkx0IU*>S z-Df- zGuA2$R}YQ@tMz&ZThwLzjdy>w`ABWy_7-eIL!QL87vNKBs2Y45Y=mEj(?O#!zcw9=l| z1tF*^zMK$Bw(_LH=$FTK#)m@E%e_Jx-jm{fCzrz9DE=c=mE>Q+U|^MgQV^1wP*Aq| zMG)-Uu7&Gxble07FRX^ad;}pd0v|90eN!! zJ`8~Z<>0-ivIoHvAXfU=w7=^kvS!~WiHP0_kwDb`n-OS1n)M4uOM7g*X*lP3$2g|V zKUN#JMcX`dYs=#KoBoe6OO1o~)$#3s_$!6I9@{CO_KH6WI4h45GEWdkk$BJfI)sW3UHBQ|U3Fxk zmfc1MW$hr(PdWdXxBNKg?QZ3X7%a_%#ea1hFy~+1($PU*Qd(nUC0%V>cI8Q!E*-~= zIMW9C0-Be@5CHSL7OUz&9#m`-S#{Uz!nF_Eh9U0E*qqm+`RK7 z@{QdQGQzNCLRyI(ne1*qvhTE5FWC?J4`rs2f)@cuF{InKenGT(JhdkO{-zfQsr@ht zc*+;cxqa8(yexali!6rvTiAUtfr7is^$Z!J3-d;X2FJ335HL=dk&kIRS9#=vQ2khlOlqm|DPnekAtqM` zo!KA}2${M4pXTPNTo)AnEywA}rg?F84Rp!eA!{O9M-T zP=#P1B+NIm0p^2Wf+=F_i3>=iQh^bD1ITvm|MuhmG}eZYqTk5Hd*Qov9I!R%yS@zw zdTHltqfPsN7E3lPV}#<)W9B;hECN^-Prqmp&gL0|;5%Ivt+EP7wi~*83;kBT2ciDr zPPV-30=Xk6?k9GWugoHfn1by%SVGaGzoCe$W5DgPE|Q^T=;34$1ZtpYRNPM@n%l@T zT--wBHFVfpEx+#=lqFx`rVQnzFG8!g_=p6y(ZcaX?z!Y24Mgvft`(n%aRXXvPmZE5 zQ=hBfhUm5YKLjdt1yj$oXF;m?8^d9+q=;GkxG#1TQP2yHB4Vwfu##A6m zwcBKtj*GudQFRjLh<1$aemisgjhYEqNkb({jgeQboLk7sawxAPI_7CqFWH`6rc_9* zgt<3>0mzO7v#=3=qr8K))tpn8 z<@CDS6c!TCrp8XO0xrnQVPi^xaw;Ri@;P5_la0He) z&3gBcuZC@_x!@P-e=b{?nsiQ5a!e+5Qj|0Mzx9H7(qwogd5hW^kRO`VEOHtNQB9OY zm+h#QP}Eu_L9a<7X}eTF^yBVQiA$+xEA=8a0p)}A9bQR>;Q8A-&7x~o)dq^tv+q{6 zZ(im|oB3e&@RE!w*fV4o7}i5R)VO9rG3dr%EYCYFCJ6hFyX9 zA^Be4wvGSF%G6!wX@Y>4{A(694>l43I#VfF;!ej5MHV&3%639ifUF$87V#|iZsWn9 zSb?EUCxk5|me=@N#4Q!_c$a`&KZGviEKy~Uh@GZ|U;A7I5KfI)AsQmu@zLPE^fStj zn_W_9E$*f%pbj0{?_&BS-|>B^pL8mLmX1+PBW*y|?|yY^s1u6dv(21c^ere`S{rZo z#|x_F5gH?7wZB}n^{gA!J{h7aV6SlK79Z~y^rc2nN9E~Okxg;}s+Jd^f8k1L+vWCE zE>N+(H7TE$I&+{p6{g2_T+wF0?a#r%HE*}hp8Tk~R^%lo&F23|GW4^UW=ZlTtpz~& zKWHaz-?q3k53VIDsh!g5@sHYZnD{3QQIkm^l=WtuUV8A?8)t4l4v&4!3hz`?sh}yo zfBU4_-)tRKs1+0Mm0IV2NZ3jJDwv-TKzUYqtR^5{Rh27@_q8#Hum7W*bc zCOS0QWtuGJS-J*q)%VfB+GJAI-Vk&n);K>MMT*OFoqjX48djFG>cNDq!bp=b>b?uf z8T)_Ot<5k98nzv@_fgQunI^zo*f%blj z$CcPN>ZjEMMwprHPkrM0dqn!0vvspmf)Uyy7#|jq7j!xE_E+k6{LFR)&NcRX!kWeU zoJHpU8dngy%{bz}#wGrb>JlbrF^B+Er{o}5QSw&T>{|4`l!*)kn&&-lkfWktBt>cH zv;=%6FO}Nn9Ml@ugCm3@oOflfcOafs_DYt8X>eqEGhe8-DcGH_nCrmmk>C-Ch>51{ zz2jy=@HGmXE+7@l&mj4n;K$VqQ}NGHXq{BZloQ6Vls5{(1{CKb(XG42ErS7?<%Auq z&Rv6cq1n4@%bm&{WsjbHe-e|xWuv?74~n8f#W=(yF)oT^E3k&`tMRKjxrb`qg~4M) z3k&(F`pHQXMK!a>q7jfOe*|G{1;v@y4)W3Fx+WLseuhd-sQ(sE6FtrH?x607>Q?{4 z3*kWKh3+scl;|8KQLid={_B zT zhsfgdoDKR&(HPJ@OxFE=NKTt$v8{AE`#_?suwQlX5^IAzjX zC(4Cr2ToPU&7#)GgUH_V>(3S3aGr8kxsnxdnsm(nfBxE^g0A42~ImI9?D}8KUBL7 zI@Rg$TUQr^pMJ7hEDv@z523H1BOoVFGSh$SO@3m&0b~?wmYi}@Cun+$8fk5+FU&J0 zDh6Sg|LmpYQ=H?K^=hxb;ktncVTZwCA~IRz>3{Yvi0lfTtT_w(=RIiO+S7YOq1PC+ zrpjX?xnAhg3x=ILp4Kj$jss5KN^}ZG;qdVhV}zU&ilCkP_(N~Xf?T0YShCU3IFJ;T z9K;n>(8OTH_Wq}Euo!DY_kRi>{WqF1{Bs{MlRH__0DkC_7=huCT!^Y`DaavVwTWvS zj(F?ADQU>!G-~TqrL-nAI^|sp7VA?^tD9h$yMv?l`Qh^I_dtD2g=&GKl`WrL72Vf_N&jEnSbKHFCMwRpDV5$fVttVWrUNDM;>l@@liHtqSpi+ zNi2I+9qP~uEe$9`z@Fy%@<4r~Q&4Wuw#jt~R;aR#Bfj%@ZCP2r%I zyyQ-kK%VL)oC`A67jj|xuROk42XXWSP@+J<5maFMKMtHa|Iz_f=nMDA+I&P^E`8VW z$H2?OvJR(VALP(2U9t@yUZX+PI^rTa2M1Pri7oV=c9heR`6A?Nvd#DW26 zW@&b~D=grQ39*SJ32w`(#}3C8v!;CjhCtwFS}DS5iN@^KGZ}zTe^@a-2aon-ofCVr z2Yb(9ji?etlf-HT8gUBPovLuUaLA*Wn zQUb-ZL+m_;>Mh8^jAWg%?6TkruY_Y4coYY~JPXcUN8O!qjC`Z(S`x-qX#FupWOJz4 z=r)SicUce|Myw_`Xe0PJO>NC!2Tl87Ch#YR~OL99o({7aASaZuV0}`{+rg z<sDdp*$9rzEvBisH+PaO z1}5@XG?-}fNuHEKdoq7~P*;*41-2FbshGVY=WvA8hsNu*_2?l2V z{eNWtzhuBU7ZqUL3tbcE(<|9){#3`NKt+T?LT;S^&u?%RVs)8pwnVaMQAAL|%4^=1 zn%&iE9%_7nrjHJmigj0{?E%LMXU^2!7kCHx#;yE&9kLEwyceG_dfci_baMECnj}|3 z-Ud~Yp9crOE!b-BKCV~3u|V^hrxV6*vnWiXH0FvG?NoG*qi5MtTvo(QK4^C7XfO&& zzEC{l#sRLX-s}c7YQ)Ug+a@`c#fU+yT@)j(+C-KDs;RpYRnQE6z|8i_PJY{#=6)6( zxAsX!=O(19P|J2|6C~!fHv<3^{sFR}w4oQ=A(>>dc{`=kAJ;``S`cPpKs3e7xbO(JD{MCxQAymsK^3sdW?r&g$)|=Oc6?M z^GEd2*?eATLQFK-9wGwV#yY|`(0<(6pSTmBqS8Zs#IN9BRRgTl5uD)MZAt|enUXBT zwW2kTCrk-cd=W@j=sr#Ne1{_^(l|Ei>$rYJ&!lZJzg$RIc7*gVc{0VnIWhER?uX!j zDZqov`cFkA3<_7x5r(7nARNh{y-qw%{uc5ACIrG|bi{xSqF6N&@0Obdo(oZ)cBWSI( zhCRr@;o7(BFAVACXBoSaSth#Esz~MnIK=~;K}HAEJE$dxOVFBlEH|X0K>Ag&u$d&^hT|>_YQwsw`Q&f@(E)`~(Su0I0jDVY zl_&5DZ2sYtY-PAcX01{5e>|YBhyZ3mVE8wDJ16ln-9b88PsAn%F~VLEhc)H@E*s>V zb8Im?kF-*yfaWrC&0m%)^zFOG{z3W(r#i(Oiyb=b`e(2QGAyP*W#uU!^KXo zSouUBM7%?zGj^81P&a%_EE|8}8rUfQ{+HubJ>h;zJvEqi5&6z5YMDP5h|0zk`|(yk z%ri~6J_+)<&;x)o_>o66s>n6ysCY4U_RO}(%K%B|16@pkb8Oq?fH{SFl)`5?FF<9f zNeijp&Kv%J>%g6}bO-;xyJh$PUBfPZe!!F*NCf3`*-qVlsr7709I2?3b&;5cE*PU* zM+E~ie%&Igc9X)An>Jz<=7v!~Msxt?x^T#LAUoZ(H~+)Rst+L43r1j~zT?T(;V9fC zh>JiAyNS+y(xu2Pv!6K6rf$18Y%B8{f1ZM|fhS=Z9vTC|kx2ikgt?`(j6bSd2M{N~ zIr%+)aQQ|wzNhTtsW;z#DwI&BZa5)HhEhU`61B;kEzO#BdrNr3*^e}KGaW5d5eg?nBHj^CDGlH#x1)`LxJV~AwXSuugU@g&7UrgjhbW1zMQW%2x*)ptUKYuo3*kEGHkeOA=7GzL_siEujgVJqrX_)PO z8R73uy;fjxf$zxg5GVHGFzG=-y-(7f?P#FTcn$U>ubG~w4fm(5kEgzLXE26>ah8pZ zZe76NX5VX(5<=^7*v{!3bPHMGsE)YC<}?dJ(RPf69k~QR!>A_XN#srt9>s+2*{x0_ zZ#nTY+E$$;uk^8n_2;5kw!h^^fWJ4&C}agu-PD3siD?QPX)y|!03MK;{m!h>9$XVt1O1>e8k;|Ipao!;`dIpL$R2001P69|5n zcbu1_0*D^~`-?ZSS?Cemswi(sBKK74AwU1Jj>F~oj*7!SGllW1Tc*%-2vQ|l$-P@9 zG*iE~YKo!^G5-!>BmCxW2#-?9lCN=+?i_V7>9WAEG&Lq_$uGLh%&@?@6F@g+%@9qq zBPxyBoegh@B}!+!aUq!(!9XzHSDALn@Yt9%?<>>+*x4nv!MzcFVdx6Rv-wNI3w!fx zk(793sWE3}lt!@~mU?hdDft`R1Lw(DRm@j$;Q|b;0!SaEFome-uCG7*u7cvs`ZA#e zu%NLj(zf*wwC>c`-7u+L?ZBg-gK#{Te=mnQ%w{+~9Ee{z{!o)7w7%_3lX>`&;??MB zX%;pB_~X`tF-mrDC%4Ffu2JCU>>q_XZX zwVuCRs91donsxmcV%eIq7~}+HI{tW(zFSCKH+q_}Ip}0Y*_2C>dj0zqGjgSAFvN_R z1FAzfgx;hAZYp*PXv4_rkLh<4M&Dw1^^1H0SQPq8(s$V|@=%4Oz7)MfH^m`qTf9Rd z#5X)^n4^agSNM1a6G=zDhMMgI_=DMpqU;G7`z2TSj7Vzjr!dA+>`|8z%QKpfj7&ax zmE!9iK6F;S+5tU-9sGwYESDVePLq6qJt(cOkx~Ghq4o*C><^m>8;wyJV_0rgDIF7Z z%Eq|Dd#wL1pVc(mz;FK|3pxLT=*n^m098ZfMG*`^a`@p=y6@53WQUe>7g{RGK+awh z1qBv7E}KW!)}D3345jQ-596436abX6JXvHN)jwX90>x>wN0B@(=sqp@^xOaI=8*oU z;x9ITA%P7<;U57+gb7hSjLdjGjLZ}B1~N_(W$zr(<9k^YH^F}o6R-n0N=^!B01Jcb zcrLmslmE{ctB7tEeD?oXZM%8;)Dowt=@sC(0YGUbXoV5YDv^@XCGh8#H}xMSgs-fz z-O5cS2oFwLXAwrQvIwSS$s}_EX&5O|V8hGziq5{k3+TJR2vLUmwD=ry^}W9hQB}i@;hrdu{K8hp zzP8pVTb_!vsUY1hT%y&gSiG{or@1DzD}Hw;I4dJM@4#VnjvvVS<{JVdxvW}odeYWs zQ30^(!v7(F8QuekXBvt1Z{N_;Z9P3TJ*R#@5o@o2AzjPtPQJXX50v{z{J~up z5Q=GX-H2_f`qffcK%bqWIUUT;rI2UILz-`aK0W>Z>;7gpBj(u209#hpvj~7q^wQM* z^=?98!2Mi9JQIW3uS|0)KiN8)_QzKLJD>HjW%^FY*1{IaxGxdFNraXoeCfC4yBxmO ziAJpqymZIzeQ|N8ReGL==Cx?nO34LF0{q{+d-7j&4hptPm8AM5&Qj{rVxgX4o0L`6 z9=o=c20qbLV&bMBVXb@w^uGYj{8xH5drIi2dTa#@`+PJ4PWhiT!h9c1<~Uewyl36o zt6i{}I9a;Bbm{kx!uMqdc&pFU%dr%LX<`~`C{^04wqG;NVKA$g|jGU-_z%)Vo5DY_-(ImJjE4KUjuBzxFTtZpM4eN>y+BJNieaG)SbDP>XBy{|asf zDYhd%*;UCEpz6G!h4FbgzgTmemcpe{K~gQPi~U=h(l)Rk6XKwLDNkSOg}Ts;@4 z9Y0In@iNS8`7duN(^aZLDoDt2CSTVERZD9t&v`UYI;b8bf7guByZVzp~%Y{cnJ=uAeN|mQM3uFZY6cEpf~!{uHN?iTpwkMT0cTWLow4E%-;Ht|d;R zEhJKWMZz61_~*79&C);~MgVsN2*47Ybx#hhRs3VRqZdD5*oEUOF&OR~q0--Uv!CX_ zC@3z@;5ExU4tK%6`k^Hv4vy-UDDc+@um%-yLxYsg&jDk~UUElIANDW+uSkImI_Y9H zJXDnip%$IpX2a=KW74GWHJwV+U^m&`Qa7F&=By6* zTUoJw@XP(VM^ZAT9vsE#xW&iH9xi{rm2`UD3W%Y3{-iUlqi;M)O~+w6D)Z)Z`GkGo z4coWbv!@g@o7rfjg$_uyY?qOYpI3-W5ElP%N>KhXXNz6@pW#a-Z5U7cuU8%X zuUBcR$pWAg7)!?_q5d(K>NGL^etjs3`UvdWWqAjGmW9ni!_CX(Ka4W}denZ?j7`0S zVvKUuzkI4SqyjwTpYZWK_HEwdZ1>(w=|9RKTRC8Pp2K!T-G8=FDTG-(&FmVcK*6pVw=$Ho>_%Z1)Cm<`ITeP`3q=5zz#i z7FF9mwtTB167!6Chy@(AHSa&OcRbNsRwmvqQ5d%mM|nh{p`;J?Co3dzJEd&|?Iae0 ztM(BZ@3^8qMH(eDR+xf9=VaW48+$j&rZzn~r7$zWHe36Z9HJ+}#mozuGS8s$-_>e> zb;Z+N8a9#1KlDU>_x+nRTo_(HaL&6I62E z1+-@;*hFgWNR}74PW7T0&3fF{tpp#ztK%qxc#_5Z4aCaWD2e6;79w`1Thgi_D5#ad>n~bCtdnfU^L)C~+C8 zaZOd8hy-WqK0s^%T2DwMpoZ=V>xl5|J5+a6+T15<`4%Y7YT|@8d2nT}IqtJA!umDO zkwkT5xOK8QCGkC`0ndNb$LbMAs@QMG>9Sw(OCn(X;9gt7vSPL;aBzygR+5{guk3kW zsK#-qB=?g)@(#x}izNHwP%C6j_`hzWQSMVo{I6t+q5j9MhBcW1+OYlvnz&zm7Tisn z4)TqT5c0H0q(KHO2GP}c$H1!LNWMYD zWDnFH+GegrjF_9miEKd=gsu8Kt|I^JtQ`b;5ArP>?i3wBFn1iD9Nlp22;*x-+H7hD zB)0e;AxjBc1sc8Xo3)?-0Xtb5QySTm8y@b6zNVi)mHZmQGSq=Y-0ikrRb|7R11^@N zz?_jPMt>Dq>R$xC?nqrIws8yINm>zeY8~S)M&*v?Yij7RhH_C{jC1XrRrsJDyQFj5 z=%5z%9O5Ma=WP^b9(6%4mGa=9u(UOSTclwEx6t$%a=Ghd`C1jurL`dy1NHSQ5F5jj z87&=78fFsXE;uyu3WK@8@A3ZIEPqQ0yPI9HU)N+mqj9ii^padyZ>q4kG32S!wSMn8 z&dkgHjFFeSA=6-cKCY9mFiW7h>wL+u)DP%EPT#!+sA&`f2TK1OSn~ey#T7|9S7CnS zWMRlXe5)nMU~Ac=n(myL%&j(w9%q-92WY}oWA;&Dv|Ye zZ6+;(j+==#;82z6Jnt_j+Lb*=R^$c+%F2RbYZKX6w|@(>#1!(Ww?W-#UxOjWimuZF zrhSnEDk&XI+kHsgbNttihP51?2BOspTQ`sps7#I_p=w4Q4Z7a zTHa!j4asmfPs)B~Pmo-(Yv>mT$kC;a^yWS0^tsW5FcYWGg6bp8(8`2TOA79zWWwg8 z$s#+&xfzMQc$?FCnsYmM4={Cq2zo`Q3jVl56noE(D7*19kM5?mN{AfPZZhL0p-oFn$~{peJ*CFVSAYZwCEPPGQ3)H;=F5jYrSACMR>N$+&h@S~z+?aw zZL0VE<7JBD*JKj}$+-vlWE53()_Cz^@4-pTj3nxC;|nQza`&cJ1wnDIZ3TpF12x4} zvo+0tRh0(|uV66?!R-zNLeST$Hl=?AT?kbsFZD$AJMz8|bKDNOhQ^@Friydp#p6!k zZMZubvJjKolhE#1u?DL(R0|~y-~>%b)>3Y(r9p`=1}6l(>9VhzGU|5-&(Sc%m<2mM z1s$(M=QGfgh=AH0o=wgtg0I;nP0^y_lR4AencOpf5M-pVk4neb=vIwYdYXjx7P@fN z#Y32Vdwm8z?=_R0#=N}~0vlyfOdf<00G*F{%s1{bu;H#bRUs%jy~i~V$R@-RcqR~^ zyVQb>x8{W(PrsIoil~Y`0eQ$eFeDUq%{06O;41svQ2K|t_0@Un*N=zP@o8(Ew^No4 zM~MY)Zk~bEpF3r~oK>38@khkW$0ck;mdpwnqe^x5X}69P3ifigi!zxdyVLf6YH6y+ zxFYu^Z@*i$kic%2Vo6K^>cS@yvbDU@N{9kpcsC=+a{J<~yPt^y`(4Cq@1pEzRdmV( zs`SL+F>385vYf`P_)?4f@@fT&Vi!PSy=8sTa97eDcfH7?`v?qC`jyqeG$S3w# zMP}ur^K+L>3}9AcQ!0|th~ZxCT!|W{eU9EK;8)qHLJ>>}{GnNINu3+(@t=e;1^oGD z>H1Ku$?xXR*rt8}RRsZ&b|*Y}a>8UD;gD4I_LRb=K)4nJZ*%ehNL-}?RZlBEMlq2F++t2s5yxXr>)lq z8_9#$_78KVxK<)opPK&Tn`E(rx*@FzS2zP%oiKApZDlU%sJhEd$o<2R~iG(CDsVD|!lkJ;nuHfEMosRE{yxo61;g-I= zCYHNuQ?z@dIgjs{=(Ag(|LJiKi;afdt+1LG|m9|0^O z@vp+mq|f{x`58l@`5RogksMv`>bL@DUmiCg9}+;wXx8TE0{B;V^tDXG7rZGM^hQit zDMB7a6$UJpv&&mw+5mTY*VFuMvIS|SaTop0EkOTTD0gPEks;e5E|nKZZk=aSQH{(u zVtoyQr8b-4L)8!cI4DkjhIJYh#U~mRRRyh2%JcGoHI56lI1 zLO!k&EHl<`=Obo|eDQ>IP6`ZSQv@oz%Qk#<)K7k;*Yo2r!L|>o^%FiWhE2+yfh^U; zSHJuV4tPE@=_}1%8O3h?|9Npt7pNZE3Kk5E6YbwPMxVT0@;#YEoDQHe>4eUTAy_6` zE{nc~l7)=J<+ylC6Ck5nNmp3)OXPdP#M*vGCeMR_g*7lcaruMsgj{@y_yjCaq?uj`ddFoAvzGJFy^!&%5G_RpP7gTc3@B zuz@F)Nkv_4rB)#qzz0Yind>#C5T%P2(Z;=T72xBIS+ySpY%9x|XSk^2#^9)>oy3ft zF_?OZF1s=xjs6R(?vs>-eK|si6@0KV*A%U+C5R-fQz-n3K@7{UVSsDgJ;b(@E5~j* zOjSGB(9awX{S^-Ee^g+yu(3!By(+@3>=rW4${#99 zU{iVD_bzg9bAyL$a(hNhgY*&-3)B6y9X{h9uQduP=~f50^s-mQlncI`zZ0cL+0_xf zg2%!eAxYV|J)H>zRRDMW!d2s|ch(5DOz&E`nrB75Df@KB^+DSwNLM!sJ1}_pPMHq% zmC?rxx7g#uM;Bct@u0k2xKhPCm7)0!`nHWVHjhp zqnwW8E%&S6ZCCky;H&+O{ayR}Ui-0I>B|w|`rC^&LA_=Ag~T0s3L7je@3T}#n7$O| zdy|DRi1spoWg4Xqooxac<}yw}Hw0rTVD@1>@#;A;_bWj)Uf+Gl;$22W_`Hs_Owc~G z!~`ON)o6)X?XZ7wVBZ#t1Kzna=l38rYK2tEu3Bku`a(AaY1wu1yOtzXiHVKuekTPx z;rmKVU@-?B2{Vfy&FK8S#ZCsyhj?QWco`IyS5_BbeRDZ_%gE2KeCe+z|CE>W*N(1w z!P;xh2}Nd;H27NDVMkE50M^)&mNDG#FT#5YPr+=BZKw%h`2}1OC_9uqS0VS490@Gf&N^8=OI2_gS4x<}JQvP}5!eF8 ze`$Yu<`h?PEon2l$eo(?)6r_U!6*q&Lj~q)|15qBw=?BZ1saM)oWmV~{8N7H{1Sr# ze=xz>`EGL3P(qpadyG~v#V26#3uaz@#B8!zUP9j2r;v__lEt`apLm?1f zNu0<|uoHrEV8+te7LhbYM-tN(wzRZ`E(=|Hg|a>9VY;P-(nL165K19HOE20&>D}#3 zPkOR+m-PS5NVa9mAPy!20ye#&h~Jk>B(RVf(1WY-YNYz(DZ@y|Q~g*yVx%)T3+o#iE^gQm zj2TC2-lP&UY29Wn9W}Op#uEn9ax>lE*q_#838V37S|1!V(v91!*M0U|haOKUBs0yu zRzIRQCiGN)r5=|M|#=Tu(5L!q+jTX>(OrFU*3Z2j7 z%$j?<+NYtl18oUipwVLTm!h>RRKw)PnceV_B*d6kM4hZ{4=tw^8ZDy>VU<1@SEWFS z)oeJ0Rx!DZ>vHgaF{bK3c&b@9)$aFDJq0zYqXyW@<|J-53Yv|(_3QwQcoCBW48eZ_ zr9u>CnhX!t*3iWot){h1RnzwsS_hW0rtOjAdI5-70rm#kSV8M4RMbmhN1;oZ6yZxC z;-SlI@h=ChOXI0{_OdDBjeDhsny6W$&D3J6b+?{2QdtjwwFv^7X{$}NQ%@Qm+HSAG zUao@;*XrrzD(!>=Gz_Lq1V=V*WK`+^Uuk17p^KnOXP}i0WzH?bNjW3#qTNFCS1_$S zHzJle-Ga$Iw!_=v2nBiQO4=xP_A&V<1$s0Qhf61udMXx1$^b&fNGlY9Q3E!;0~+n8 zgRs7yNSH@|_ofb~%%iDYgTmqAH4G2AntI%Txdw0jD)qu{Ht}E%w1NX>68?u|=rRZG zC|O@NLxgAM%03Mm>7#zZ&A?e@u%Q*Y7PipS{kbGmuxDrx{!|&Bl7c`oK}k0qCa}fV zsWgb7ye=0vvMQyq(y9_nSdkgZWQ}A{7+R$xOtUS2GP!I#(HM?rko}H9sBR@L{H?5+6I-b#|beb6HUhp`l%}C3~!`2 z2|jNq#<6vJQ#!2=AqM{q+SN0H7p4^@+ARihxRhlOyouhT(VOY5({*V%L2Qyn6?z+# zH$h>4yPg?3j3rg_L_6^;@vh3wD=aonx+PT?f~K8+Bz75WbdU?~JHwJ`kEliAXHSRWUN0DyHyeFs z+79RLTyJ4tp}Uy21O{&~F0Cg8 z@A1&5=sp4WX{P$u)tCL~&gxlken0#*sSouUcu!|{6+FCbG6p-Jr3W>7fIi101%oPo zon#8W?r}|h5U`Ms6dDl$aIQLkNTX4D7+MJi4_v+ZP@PJj$4gSrqPS)}^r+ybj!vO8 zWOBWkf_qm7+RJ9^FVN!x`iscCW~xNm{pVN$URP9`;3WOx*eB_SKk!A+&+^!zb!zXN0Vx%nhI&0skxlz{Hxr4hh7xieisG8;#M$g@%nvaujQx< zqMXB>TH_fJe=!gJ&@OR5LaHuc1P=*>pA`E;i=U<@+0~tvAd-{VQ z@kiv3tZ8q0=ue`Nd5QiEW1&YtS}dy9Lw}`vg=YR{X&q`DOc+`84zJke{ajjjKhj=FKWEm?0;MSYZqhb&LUmRL0QY7|cy=D+_6Vdd9L}lFNAs zW3;%PFIi)>c?D1`oGE|HDH#r<~c(V%ij9KTZEe~c-qW+KtEn~I z*0Z;}t*dAIu8uYjH=(uTE!;fbI5&vKxxs3jxz(OA3-%d;Yo1eo3V_nL@-`70+d+2f znJVvqjX~B(9r1A32E^=ASvY^vNW;6BmIX@3uo*@Vz5)XVcQLIhqZm8BC){j10x5x1 z$9wEcfT{b_PpvK2SMrs-PvgCO6FcWR*Yi_Q;#W}DDRTxs49%UWHu)Cqh|W>o_NwQMN;8*4-fKn zZZ;Wh<^u3~1X4`5OkH3GS<6}|%Q=mcjJat|pq$jUjW(5k!ELvdcTAwe^Uo`T+@8v0 zF_Lz!<6yot5FU7^CcF2``0{ZqoRT z{1!AKvAAe3dvkWnID5){5Z}yi6J~ikjMS*|El3KOU$gCYU*+L<+C>7>6(cucno=@) zpRqR`XIe6U!?nyf={xvcLctiSW@XK$?w0oULZiU%wyseagOsDA^%9le2M;X04eKy6 z8NJ_VjrSX(q#d`Dm1UHaxMf>CbFwN=1N?k|@7DM(#w?_QR`XC+xSSlQJ<#mo5AlbE zoF73X1XKE~p;78Lt?`rmlx=S7S_T!N zWDG6b)$lX?C5;sRGTfmd5k0Ij<_%Z!a15ilhrecL@vp-LORu_85ppPBY2%;;gixUuxB`~uS) zaNX3KF%!A0VcYUW>!OgqtMT)qmrzrB$`m=)YMOU=_y_z$QEz|bB=KiX^A-p3w;n4_ z5>R&+YNMI7Eot3u^3O04r;n=q3yps+Dy$|{HK3VD0C zFA3D&FfBeSsKUR4TV~TkVMr;G$4sQfKIr~||ETfr`Q_3{{q;RlVT>P@*3Cdm!ps;~ zh)cJ`(8QGu&a*be0A@9vf91bv{1^Uv$<(lC0ER;8!(`&jBn)FvWQrXE{2z?Q@m0oT zB1hqq9zH{e?8N{7HUJysXvujIZETt!fa4{p)-o%Yo9*9W!8CVJB3&BR4Xh5%tG#2@j4B5Asb0` zQoYav<`-|7`)oyOR57qwUllrkjO>63Nw<`td|(>o$!DdFK5?_zXj8zUYov=cs*u)} z+&h#)DU$ex5>Fj54JrbHz02jzrpqN-tqfYV^bRz<11lRF7u?WaazudhFM&4Cc?8 zR{9Ttx)`HGQ5V0%INBf2_;dCr5>@KN(Gyz2z&QY2V6gVvSBVgQH)f@?Uk)N1%%jB| zh#=}hQIWct>I?PMKQXF**)>V1bz*F_MjRZpm+7(=HrQ{^VDyWD#Qt^+a zULyCO@vDMJ^;S9aG$&8hd0LdGrIB!+R#w&Ksqwh-V%;cR@(^ue3J+7&zA@Sy>8Q)o zmJw>L53i~#zHh_79aZ6~&OCLE(B3>yJoZn?_n z&QrXq?j)JT)$6c-nh~q}iYqy+92F~(sv!VYz2PL?I7&B<(c2>-d5ms}1W(XydAf6i z-aA6a$LIr*kTd9$N9cnO(Z`rVE}!cmLL+;ePy3wW_h*Bu{|)6xRgU?g#0|chN!s|BnUi8m5Xd`dMUz zets$lG(d(_NbOVe^sD1EPtX#-i@ePZ7HEgu0?KVcy~XDoqn9E+cTd%CN9cEXdO1&j z5qnQV=sf*@{Wy7xg4%4n_KXiNuZEn?b!xThgSuY3=e3hQXSFI{BP6X>Em1?NMOG~# zYcum|2p~Q+1OmfnPQgxkDYLJNQ=&8SRRCxf7GYcMBW(R0FutS5q@)Ugx?DI zNaqQDhoDbez_6EZ>)Mb;{ksv1j{S)wa%mh3&k2dvQ;LOv*6L^0^$a#j^qINK^ZbD2TMAx33(pcq)5|@! zkA)OrJoN;h02S!fN&=eC8FCN9N3de01?fF?A$QQH`rLw2P!Kx74~^3jVIhb?p@N!! z`viYJ64Hv)+&*Vmh^Q5bt*rOC>n0I8RZ6Jv(=|@>1b=aipNxck5Ys2uL!VFQ`B^Ik zM><51Tvdo2OTHZziLZ`hV>{BB=WpCatAoOrGz*V!S^302#?MCtZheoJza!#~zgNWj z{weO{5Mu1d^Y|x8FaPvreZ7-IicfieiuM*(=R4nhH*Fu|pGU0V`ei*h_*I^NYkAS1 zBArjs5`;Nuyn?@#^z_Z6{Ms;SJAF#$FwaMR>V$F6Jg{?^-9F_seWxxjF?P-Jt_R0g7CD|G z$yLR53mKRPPSHHH3$sn7!LJa2N{X2IWo;kr{imCKbK z*0V#|Z9Th`nDy*eZWK>6F;V>2Ks&9*W+O?on;f*CWHQk3#K}cNXnSr%!}BgQI`@!9 zsHOBt^3Z)Wi|(h{^fj78&(U1gsFJIwO8PW;rH5&rbc(8_$7#M}F)eWTX`y2U`5d)$ zo?{&?anl73Ov5OCrZV0Z>Z^2&?ZpApaBq0F5b=ffF17B9qai z7Jo@@b97;BY$P!*V{Bn_b5&FY009610050w3w&E;75{%p(|dcHJ=(6@(!H{7gRX7b zy;?>XkF5hKlrq+hl5J9MliT)gNp88hSvOuHA|i?cg4%&7s8nekCSg#q?9n*>jVphbUb=!yuEidjlr(h%AdNZdlSuXYJ)#`mSU&N(+e|J+PQiBi?Ps4Z}9$-L$&ZuoEPU)_<4R zEv;J~h!|TdFIOQ1v^FbghmAALs39=Zvb*cMZ9Nh->icZHx7V=io8t*bk4EP&R!|@? zd9%J%uaD~S?)q~(HydF`L7~7bxtes$XnojyP+9~J%DvD~%wN;I@TR|fUQED5{+i*%BuwV7Spx1VrYpl74GR1M1%Kpv^52xI zg)QS_NY;6CjZiROU_!UytkF4;>1a*P5@s#+;y4_yVF9WHrX6P4=5WrfN}AD#VJoQC zP{ZOCV%Mt2jPV+zj}x;1>X=zQd76C?j|c>+jy!lIZAKKaSd1ksZ7CUFXKhi@AfP%{ z`ji(Zuz(sY7nqkff@7pe*M9|BA~>sidx%U@l&)OfRhx zm_){|>`YkEq+_hnogOb%r>#3(pyKE$q2Ob5A@y+BNKi&DqMYom`p69We^z`1@%#*I z;zC2dYsOg`&cxXQ#~&k+f^$gQ^uaT&7&+ivPRLfQ8B-?OwkI4Trhi~9dCsuuUYC!m zy@s@ONLNFTkp}Cqz6fnNpYC{9|uwJwW`vf+e#1m@&T*KCPlE8?&?c)etWv5j~q zys*<&km}`!i*u6|jZzwu)P#bhK#>vab+)$<1^GB@p*+cJWMCh*Y1j(N`l2YUuz2EF zQnhg7_*!r&E@OF@XQLsxth8-ivRCj44OemX}SY z@Exk^j27?FJW4Zy*|mMO)fbOidZZ~cfCx0?xjM&EKfjM3uzvSY zHYekkn7u9B{EwE+qlOXTeb~i>KTJ1`bp70&)-y$Gb$khMM=_RC8H64+;aR~eEt2Dtv!A! z2b4`erGIqHlSA2%DR_oFlF+-1^)^+R*;V5T#dvT00?%srIes~=(PppXM>g7Db51`e zAnH`SK*o{D2`e5XC4ZBx0FrWDk8Sm(hrr)*w=kScQTO6y_QFeeg><$Ob#a;vRJ=yb zmSb*PWSB!`=eT1U0Z66S@rFj-Nrj3hZV}@kyoL=;%^$>!MkK$pBax>eF+u+AWzY#>gZ;i%IJ(- z+nRcGyUn;bX~e_n>-`@7#q|FsuXUR7Ow3ihFEITu6*-EBh0$s2Lr$q4dJ(8NNEPLT zhJOYcy~!|cWP03+o20M2P{Jh#65-}jy74Fjknm{uub}zfLtWo?xNPT|nh}1ISE!|X?kk*iiu*9CMJlDKSNqGta5ypsKt_(l$-kM49l7X@66sSWI^u7CA!`Gv&0rAh95>irLf&y5z3F ziae>f@u>G^EMrp7FXj?&QON?9kI6Nj7W(O0#mof11ruCU=)#IR7E6pBqkq-t zlas7iB!>sFn5Nak($^;Aju|sf-xfA{K(#1Z_M_-?AzuGGX4!z>jf~rrw zAD%xT$FQ?;y?}=!Jg12rg)UJ8^Vu=urG!EK{bV^eQHn{Kr8#H$j1wNYC~B=l#bG$ zks-tQRSM6SzBp=4c30@eOSX8G3QNK!< zDq&zR=K2bwR&mgzt%!t{Yu9OPnF&x48Nx&XDojTz5;HA>%t;_eh)} zFG-vs7V>3ZA+y^#Dc18$lElK|$~`-JNcu*#pV8UWk(ieI0*b zPT=w3;kB>cTd{C8PsOQpMpPRUvsF)?-W>vEA7w`FR0PbDhf7g$*S zYw#alxfCcZuUtBCFi}AnRR<#&9mNo84k{Qcs%e421AZkmxGD3`44_s}T-7WJhO^*s zFwW~Nck?K50M*s2s~1eJJ!7i=jF~5(kCyrtrB6^x2MCiS?Eq?%O@2;)rC1AmQ|EO* z2T7KE5f9rKA|8oiaF8X-<`FP438`&JVk{oT5UM~zuBB`Hf^@HY?-k%=q1{II>b9IEZgF2OS`gx?35PvYO-ZryKY^(XSX$3w{@?sdp}b8Kc6I9wq??7{P^kI@B7Yo zzVn^)KabC^ee09giD(Od=a?>@J9lWulPyDf=9FP&Te@2^!!7MC89P5_=5)`rtz_QL z8kl#CoT0l07DshAnHe=Qr`$r`ZRsA?bFR_eGB%RT>tjh%WMuEoZr-+K2)xdY%KqU( zE{6$sR8MZk(6B~K%P<_%8o}&o!*OvI=67^#?bwmb8mC*H3K27ZX@hpb$rulqIfH4n z?TmDeIC?f`be?hau`$Ex?6+J`&*g&TXIg$zKdpD>bZeyZz|ct};{~aXsV--aj2I5n znpBPbDYdwhDU`L(SUFqIGOeq{xVyXz*44(@Os?RXrI0x)VxyJX**NOVW!HO1PhWU0xWVY;1v?vQ&&nZnh_2B`%uFwUB; z=PDCD5~dB*s?mD7i>X<$7CbZ8*=Of+z!Y%m1}Vl=Z{)|k@f7wkHC9ekoHB<4;;_Z0yW4c2gzb!nXFCB*cVjeb8*bFHy=ca^Jl(XSx-|~Al1`@Kc0~7_9mBxLMm;+^Y+Bi|8aJHJ6{bD(fJVFNL8gu0A%cR` z&$K@FmWWgVG@#L5N-_Ce^9e(Nraw&k>42E;AmVsI^OddU!Z>y`|9`dJAsh*`i^u!h z=3698hv|r@A|anMheGrY!3p$jt6_{@+xDQQKDG~v4SKrc8P0~yK{}?24v$w7USGNXFm0=WlDBpu zU_ba!Pjbt)?ID5#*C-a($P^sY8}HnQ^o5MK+Z-_@NJbENFtz(a8fTXMP+JB} zW70{DM(GsOs%q`}t+9d!5r&=*QeLvdY~@RTc(XOKXsnVQur_NOijE&&$N+)Zv0j0q zM+J>sI*n*5jAeBXItQ`T-!J0M(zs~y1lTh<+cm=UT~ZNTdJ61Wr7r{`OZA57UG#3@ z{qBm^RX6S}n7OP}h40nqya1(PhNIu|3{^3{52o|%hm5nOJ@XJd9k4$@Kd907(+^31 zxkhi`jfUxm>43!Wk6=omV&Q&kV}0{?mlc7K_tKAvF7HESTi8Pj?EHZ2d=@Dj_L@6!9spxbj-1_(HoB<8pq|VQnE;vlSM~) z9mxv$2|AcAg4dDEghG&&Em7TpYUMD6!PIf(?a^V!&Lhe_r{GGKb5(EGAs35(?ykPg z5hvFjZFO6%O1wu?cF9Ji>FGRK=|j6!Zh@F+PsW2!<}HNir_i^}c=J%f^31$}ZpRoC zxk37wIR$i9!k^IS1$q&MyyRXK;Toa(2*M_(+JWZj8b2F4FVV-u@gEP<&(Y6oXqP^L zAS_rC-fGEhb5v86uhd; z`+H2cRl8~S>hEjxCGksS#gk(5|2j1%Zx4*SeD^+ z9y!#n0&5AxA4J}=ywW>!d8}%pf;Hea}8}C{=aQ z(qak+uHa^kn|S4a>}{za-v)>x`AaRaO3xr9)H(ZS)*xv$uhBTdYmox*Jn7Y4Gt*N* zH9+Dmq7M4jQ` z-l39XVZxk0bROh^RuXy7CAJlk1za5!uy7xGvyHRuI)*T@p)aXrm z5jqi~ffE53pAa8^2kOc#U3b(gxjGsP@nh27)@Y8a zBl>ZPXuO7edABXZ8K(HHp*o#KOSOg#=*`1OiPIr5Xrqc&FgcS%8F|y+XJ?TNm!(Y0 z*k8yG8O~u5MVnC-g7CJF8szUk_-c^9{wNxzC7?mTU@0v_&OC|HM)3PV*TmDuC#mro ztw;}lOj2|FDy>RfrAYf#T60;!r=Hf*y3!_o5L@a%7boIHy7Op}HeMucijo5pbbq2q zo6`fYQr*POZ^WbgK$B7%>dN6-6t;^ym# zf%wbxHl_;{^?#az=>cE+U}JB5iXIxcMtjqLDUMIlz6tsexPSovrE0dpd2C~G-^+A# z5qh2Vm|vexr{az2NqPjzUZ7Y)oquQI8XXq}AI13bbm|pambmVJj_MP>EfeJDSF4X0 zns>w!HHb3?iBG^p%%|`hhrR1yghOyoYD?f|b30VJi_~n~0=S}d{Q--pC zWuw+%T|D=>_E*V&xp8=ka{I55mG1T@Ch46G%jr|0?m)yZ7CV#PUiU0DCL;k~b6t_1 zoPf3I1I=}dE{WN{l8pF^bgoF>gZ<~Rf0CZ|Z4WdDlGmT7j%0ISYXjXpH%0GBcVqL9 z;=YR`{^gsB^!}p|kEstHJs*HWzR)gzaxSFz7wIQ1K&3>wNSEO3=Tkv3O8R)W-xnYB zCk6xUgLTQl#-EP(OBQ+|4g37;4W-2mSfH6!(>B~}Ey}adHvDdzw%1Z{1YocC!CtT7 zyI$JwGCF&);sf0tSN=+Z{DQb?gYUkz3EXC_cs8C`y9JJ&qRSU4;Ct!(BIy2q1~@Oh zR0b}ZrLv8;m!sqPYjic8-Ul^{Mf#-R?uOv*JU)Jn0h!OF_lsnhK3SySn4-@q;C%i9 zEt5xpP!&(?a6EOMdAEXT0ApJUycMO>5q!^m2Q87e~!OCLdz=tdVS*N*OTe8 zlitApiJR{ph~uO;ZnPKaFE7h~&kaPVhIs8&7Fwa`DvB!FLamC%XuG2K&@M&y&|XDT zbU@KVbX?KnbOP2T(rH-HQL+^+(0de>U*UT{eOS?wUo`jw*u?502s_$`}U| z?NjvEm(%;>=_?cwq$N%?etnYu76<``8vheA8jLG34+ zIE0g?cxjOvDmtv$FXl$(VxPE^yZzi9P%Ntu6ynwHptuzP`LcMF*9qDYSMonCalv;M zc|#N5b)v}aS9nvA?^eHmT}AHh4m8Bz{C!2fZ@a&~D^%a5MFQ;#1z|*}H^qHLe&8ZK zzEWEmY7Reryep)4;Zw)Q3VtwO|I9}zyi#lSKmE)_T9sTWlSWtQ3a2o&QY-SINU+`4 z90rg?LYLMRnz;GgKqT1hpCGqPyRXrk=_Wor$wzJ^BEd)?d4(T;ZsK>~`W4tA4~7zA zsyNJf?C51=?`;FJP3#7{Hu0mdC=voUH1P?1Ce;;(nmAjsbbOLWZd6Ntg+c=Na}mFM z!7FdXZ%~9r=p+xZspw9QIN zm9a#xjD^bh75c178Vi;2SLthNEL6sCq5+h#P>k8f4Kh|##_imt#zJMB;b)YdrMPGW z`ri($K1Pc;MLy18%qmMQBHy(;KmqFbTgc0HN6VPN>7 zO&pKNBN-DleJOxjNeT?j{|W_ z8WkQ=;J5)%=!=S*#o;;MMCj-ZP)!ZX1(J(A9eI9+mL}1INM;d=d1cnY$ml6T7BQX5T z4cz3pz+iEwv@I}DENy3z#q|s{dEQ2%_EA&Zg*7xj#tHcv zW|#?6_L=D*ZfL${eZmw;zm~-f%#C6e^8!;n1R4qgT3ZFYAd5vzXRv@Z^26~~&q~8U5XNUs|HN8FpFr7DD@{YIg-}Hh!IPjU^uF0llWjMfu$$I{ z*az_~JP96r03S-6h#s7U`S^bO%`E%*_5J|>W7uQxvf126PdpZKi6-GwF6Vr}Ws#Rk zi%JzH$cqGtThu5V(q$%GATyLpx5^!#&V_b3;AI-*q6~jjy(2kIMw4+&SsVS$&sSO# zaG3~3WYMI`AX;ToqHDB{-Xb0iPli#D;F>@Cz!-EMij|dktu!(?Dr_32RwNq3M=Qz_ zZFncD?9w^RV~w^A4F>xQu@<2gCJk@n1bYLiiZ9RVX+gsK4vi|+ax z`Y)QE>yX5GbXw0?()rHgp2v6Y?|;Ai6~Hta44Y4$EEhLYRc@>br(frOjAV;0o1acsC^@*n3r)y+I>hF1TIxce;hk#yN!}<5g)5iP-2MryPTMe;_5#3 zY?~{f39EjFts-NL=6`$fd!<&A)>c385EL}b_hc7TIt#4AVZQ2VN zn8;C%V-97h_=;pxPGBN^xZEQv^u1TyF>`Dd|Y+WNVk^$vUz2S`^>>OG|rn zzOP~h-%^w0;yXlW?LXSFFAFN=d;B0nJdh6>c=m{s`j9&f&t2!$-EFF>xC?`>kKH9& z>Z_j?I&y<UPbvwDX$1ozA=}>edT_lqch{0=l=KnAu5e7d~MWj}}oT0Cc(B(8|X zk~k+8tCgCfQd6mF$x2mXIIlC6QG;Qye@u;JvCN9+M!jN)D53-fY=h|ru7&g2`GxsxQeqA9qYnrHf4*AR zi|o0gG6K=6E~jLjN-9fT=(JX2dg`5Jx2jr6k?VSE&tC8l2%gafO{r9qQ~QN8e^xZT z&`&^+6vNb&LY?af1om1gjhU%~-0mt;?eR@KFoE#izf5_P@3>R{_W6zWe}NUTma!w& zAcT?E9qq-QVS__Pcf=Fh<%gO;=e<6rLf80(Gh93L_^e1MUFzdwUAZf=#X!!ztiEj}3Vu$A;<%UNb z{Gls8>ELO1eA2-)uK1#ZFS+B34!-P)PdWG_cYMmhv#$8GgFkl1ryYC+R$cI!&vtkX zo^;_6?2d!4!&4VL>fp~{!wt6^i}w=0J<$6HP)i30Y2wu_?*ae-0#F8%VW?DpcN0|< z{+>;n5W><>cF-6F+B9j{Et?7jw9<_RiYWq4lb2-ZWG2o`S{A`wL2+L}Tu~53ElQ^q zM1Jrbe(;a-c;8IYByH;9oSfWw@7?b%-+k}C_s_pK{{pZUw;3*+KHb}TGB_Y52DzFH zZVo0=!Ei94WplD3nX;xvvRaaV)4a|VE*YE_Gm;TWWO!oG$Y+h<=9HuuJRHoWBUvdI zk%f)q`sA7oYX?YIZ!O|ec}1ZKBO^uD(2%QXS>;@p)ilixaor$aG~e2?uBA1SR2q_^ilnBa z-2+E?!gQmKOyzWqG)*RHtLjl?Yzgd)4D;>SL&BZ0hr2Hs*TaMm-_#(VH9dyl6nZ4?fJA zfm$r^!Gjs%YmpCL%oJaLOBj6Rak#OJg5<|!!!&Hy{XX1}2fSF00CAvbQnD1D4?)cF zl9h)TX6al??j)G5?bj8ChQ_9j68$k#RCtRIE3i@kRuLf0%^peTs_F1Mw+JXQ;zJWc z!f`W0Ygx`VN3v>iU6qt#=C)^fATJUp|3n1sB~o!CLPbtE!%0ei46Caap*-S3Oe!~{ z`+M6drYKf>(SkJ$a|~W#k)gh^Qd`t*9oCB~Y@h^_Wy(9~40-Sf!@P8*6|vyMCP7mJ zHZ#l=G&zhPCmtH7hB$4|mCSF&Ho-h?y?Mq|mkjf(m=*~^~-mXX$O*ci)aJ?LOqG|BYDst;X`{ceU$_e4qmG@R@e zob-|_V_H}HoKW}ENjV|sV$@u?Q@sP!ODMvAIp-8D?!?qj(?;3!GYENkE^`za!&0$R++$U$bmN)Gq+U`Rd8KEP8Gq@Vt#l%(&ip*$_*Beto zLWxSNLKCPQ!xFOGCn<7LGWn!a;)5>Ee*+AG>lY1SEAqnl5aEnzagH{5Ifml`euA`1 zCFsqoCPlOBSc2!AX7xNnxJ}C|$$+Yv0numzh3*z8wc

yb%-OYcg6{P)b3;TV;9l88> zH7}mIwVJI>bGwUSXd1>bE7+mmCfKsNAfs{*q1f=$vJWmoDyVo4@x5=l%f2_Eq_{ z{BA6Js?P81xnJ+Xu|K?JgY)GVk*>Fsr|fExbxKT|W$*%csmL8}?)re2w_jwsE`7CN zdPumP^?|RoN!Cfca|6w7KV${y>(%{QC4POM?n_UHOT0=##V`Jg9k>(0B!2eaU70Mt zR_Bj~Kk^qU%DtC5{3lRH=IEn9ovj}pRK|3*D1BUMf2j5N#|^E=>ixJAf5l`cF5W+t zE&7nVj!oLav-`W<{Ked=|I9Uc#VNmXqrm11&+BKkv2%B~|2=<6BT!*VkaYd(wl9gW@ou&?~8$?-q>F2_DbRq&+0i&=i9=| zdF(fiTw-3{@Wxg4o$^k@66Wr|;<`1Z;`=82S1JzNrmR#H6|rl1Sd0Ao6(8e!b~+jU zH$OY&u!P=SMU}(zzr0t~{`$rC{Gh@7qW+yD1 z>Cus2cGvZ8(shp?dRd2+PwOw3=9{*7@~X_qg7bXZJaR2t55Ktr99pgi)i>(|ZaoMF zUV(X(XY%^>k({|3?Q9)@3!d#K3vO_d@z#A`qXg_^6#%gz1MmbGIM~fMS#XogMhG zY)}+k69p@36H}S&uvtI``QA=j6oqAyK!p)9@Jkkf)}fkoNC9k;tPyT2 zH7bK8`Zu#pR@|&F1HK6j=5)0^cRA1fKfSYEeB?@*l_yQ)N ziRXYO8ljjNrVUoSUq=e85Pl62(DC*t3e$AK3NP!agB2pK_dpMMe*>UGCE)c%{9uKM zv-;5$#+puU-0CO;I$}N;=(aULtb=0ZS4*G*rAgaVW#DISV?^O<>&cGW{AA!qHv>Ir zhhm7B{p9ZLkuu;zgn>550Tt+@DDZWhyl|)JWYHa_GVtS4fz~*pC~|TJD~j96F}Zn% zy$s@zNCpNI6orr7;0k~5Fp>eCUj#Y6h=D;7MPaTNRH3>I{2U#i`%t4&I|Qsq!C4a= zmhfX&fS%ArF-;^4sL(?Ov9W-GK?_AeU<6Qs^kjuy+>sXmHasH+)(LC#1^~+; yR9`KhG /dev/null && pwd -P ) || exit +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 @@ -112,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar # Determine the Java command to use to start the JVM. @@ -170,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -203,15 +203,14 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * 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" \ - -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 93e3f59..a51ec4f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -13,16 +13,18 @@ @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 Gradle startup script for Windows +@rem gradlew startup script for Windows @rem @rem ########################################################################## -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal +@rem Set local scope for the variables, and ensure extensions are enabled +setlocal EnableExtensions set DIRNAME=%~dp0 if "%DIRNAME%"=="" set DIRNAME=. @@ -43,13 +45,13 @@ set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 if %ERRORLEVEL% equ 0 goto execute -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +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 -goto fail +"%COMSPEC%" /c exit 1 :findJavaFromJavaHome set JAVA_HOME=%JAVA_HOME:"=% @@ -57,36 +59,24 @@ set JAVA_EXE=%JAVA_HOME%/bin/java.exe if exist "%JAVA_EXE%" goto execute -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. +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 -goto fail +"%COMSPEC%" /c exit 1 :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% -:mainEnd -if "%OS%"=="Windows_NT" endlocal +@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 -:omega +:exitWithErrorLevel +@rem Use "%COMSPEC%" /c exit to allow operators to work properly in scripts +"%COMSPEC%" /c exit %ERRORLEVEL% diff --git a/regi-headless/build.gradle b/regi-headless/build.gradle index e528b8c..26da9f7 100644 --- a/regi-headless/build.gradle +++ b/regi-headless/build.gradle @@ -4,21 +4,35 @@ plugins { } dependencies { - implementation(libs.bundles.hec) + implementation(libs.bundles.serversuite) implementation(libs.jython.standalone) implementation(libs.args4j) implementation(libs.bundles.regi) implementation(libs.bundles.regi) {artifact {extension = "jar"}} implementation(libs.bundles.regi.tools) implementation(libs.bundles.regi.tools) {artifact {extension = "jar"} } - + implementation(libs.otel) + runtimeOnly(libs.hec.cwms.ratings.cda) testImplementation(libs.bundles.junit.api) testRuntimeOnly(libs.bundles.junit.engine) } +configurations.configureEach { + exclude group: 'mil.army.usace.hec', module: 'hec-cwmsvue' + exclude group: 'mil.army.usace.hec', module: 'hec-gt-crs' + exclude group: 'org.openjfx', module: '*' + exclude group: 'mil.army.usace.hec.swingx', module: '*' + exclude group: 'org.swinglabs', module: '*' + exclude group: 'org.jfree', module: '*' +} + jar { manifest { attributes('Implementation-Version': project.version) } -} \ No newline at end of file +} + +test { + useJUnitPlatform() +} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/HeadlessMessageTaker.java b/regi-headless/src/main/java/usace/rowcps/headless/HeadlessMessageTaker.java index 4369a50..8ec109e 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/HeadlessMessageTaker.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/HeadlessMessageTaker.java @@ -37,13 +37,13 @@ public void addMessage(String string, Message msg) logger.log(Level.INFO, "{0} {1}", new String[]{string, msg.toString()}); } -// @Override + @Override public void addMessage(String string, String string1, boolean showProgress) { logger.log(Level.INFO, "{0} {1}", new String[]{string, string1}); } -// @Override + @Override public void addMessage(String string, Message msg, boolean showProgress) { logger.log(Level.INFO, "{0} {1}", new String[]{string, msg.toString()}); diff --git a/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java index f631bf0..494dd94 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/HeadlessRegiDomainFactory.java @@ -1,29 +1,30 @@ package usace.rowcps.headless; -import com.rma.io.FileManager; -import com.rma.io.FileManagerImpl; import com.rma.io.RmaFile; -import com.rma.model.Manager; import com.rma.model.Project; +import hec.db.DataAccessFactory; import hec.db.DbConnectionException; +import hec.db.DbIoException; import hec.db.DbPluginNotFoundException; -import hec.db.InvalidDbConnectionException; -import hec.io.Identifier; +import hec.db.cwms.CwmsSecurityDao; import hec.lang.LoginException; +import hec.serversuite.ServerSuite; import hec.serversuite.ServerSuiteUtil; -import hec.serversuite.data.DirectOracleAuthenticationSource; -import java.io.File; -import java.util.List; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import java.util.logging.Level; import java.util.logging.Logger; +import mil.army.usace.hec.serversuite.cda.CdaAuthenticationSource; +import mil.army.usace.hec.serversuite.cda.CwmsApiKeyAuthExtension; import rma.services.ServiceLookup; import rma.services.tz.TimeZoneDisplayService; +import usace.rowcps.regi.executor.ManagerIdType; import usace.rowcps.regi.factories.RegiDomainFactory; import usace.rowcps.regi.interfaces.model.ManagerIdProvider; import usace.rowcps.regi.model.DatabaseConnectionManager; import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.executor.ManagerIdType; - import usace.rowcps.regi.model.RegiDomain; /** @@ -34,121 +35,72 @@ public class HeadlessRegiDomainFactory { private static final Logger logger = Logger.getLogger(HeadlessRegiDomainFactory.class.getName()); + private final ManagerIdProvider idProvider = buildNewProvider(); - public void setPluginsDirFromClasspath() - { - String cp = System.getProperties().getProperty("java.class.path"); - String[] split = cp.split(File.pathSeparator); - final String dbiClientjar = "dbiClient-v3.1.1.jar"; - for (String cpentry : split) { - if (cpentry.endsWith(dbiClientjar)) { - String pluginDir = cpentry.split(dbiClientjar)[0]; - logger.log(Level.INFO, "Setting plugin dir to: {0}", pluginDir); - System.setProperty("PLUGINS", pluginDir); - } - } - } + public RegiDomain createDomain() throws DbConnectionException, + DbPluginNotFoundException, IOException { - public RegiDomain createDomain(CLIOptions options, ManagerId managerId) throws DbConnectionException, - DbPluginNotFoundException, InvalidDbConnectionException - { - RegiDomain regiDomain = null; - - setPluginsDirFromClasspath(); - File rowcpsPojectDir = options.getRowcpsProjectDir(); - - String rowcpsProjectName = options.getRowcpsProjectName(); - logger.log(Level.INFO, "Creating project dir: "+ (rowcpsPojectDir == null ? "null" : rowcpsPojectDir), rowcpsProjectName == null ? "null" : rowcpsProjectName); - File projectDir = new File(rowcpsPojectDir, rowcpsProjectName); - - if (projectDir == null) { - String missingProjDirMessage - = "A Rowcps Project Dir is required and must be specified on the command line or in a properties file."; - throw new IllegalArgumentException(missingProjDirMessage); - } else { - if (!projectDir.exists()) { - // If we are being run headlessly I'm not sure how much hand-holding and sanity checking we have to do. - projectDir.mkdirs(); - if (!projectDir.exists()) { - throw new IllegalArgumentException("The directory " + projectDir.getAbsolutePath() + - " did not exist and could not be created."); - } - } - - String testProjDir = projectDir.getAbsolutePath(); - FileManager fileManager = FileManagerImpl.getFileManager(); - final String projectFilePath = testProjDir + "/" + options.getRowcpsProjectName() + ".prj"; - - RmaFile prjFile; - if (!fileManager.fileExists(projectFilePath)) { - final Identifier identifier = new Identifier(projectFilePath); - Identifier prjId = fileManager.createFile(identifier); - prjFile = fileManager.getFile(prjId.getPath()); - } else { - prjFile = fileManager.getFile(projectFilePath); - } + Path projectDir = Paths.get("regi-projects", "regi-cli"); + logger.log(Level.INFO, "Creating project dir: "+ projectDir); + Files.createDirectories(projectDir); - logger.log(Level.INFO, "Temp project file: " + prjFile.getAbsolutePath()); + Path projectFile = projectDir.resolve("regi-cli.prj"); + if(!Files.exists(projectFile)) { + Files.createFile(projectFile); + } - File projReportsDir = new File(projectDir, "reports"); - File projXmlDir = new File(projectDir, "xml"); - projReportsDir.mkdir(); - projXmlDir.mkdir(); + Files.createDirectories(projectDir.resolve("reports")); + Files.createDirectories(projectDir.resolve("xml")); - String name = "Headless"; - String description = "Created for Headless execution."; - regiDomain = new RegiDomainFactory().createProject(name, description, prjFile); + String name = "Headless"; + String description = "Created for Headless execution."; + RegiDomain regiDomain = new RegiDomainFactory().createProject(name, description, new RmaFile(projectFile.toAbsolutePath().toString())); - regiDomain.loadProjectFile(); + regiDomain.loadProjectFile(); - DatabaseConnectionManager connectionManager = (DatabaseConnectionManager) regiDomain.getManager( - RegiDomain.DOMAIN_CONNECTION_MANAGER, DatabaseConnectionManager.class); + DatabaseConnectionManager connectionManager = (DatabaseConnectionManager) regiDomain.getManager( + RegiDomain.DOMAIN_CONNECTION_MANAGER, DatabaseConnectionManager.class); - if (connectionManager == null) { - connectionManager = regiDomain.buildDatabaseConnectionManager(); - } + if (connectionManager == null) { + connectionManager = regiDomain.buildDatabaseConnectionManager(); + } - //conigure the database connection. - String dbUrl = options.getOracleUrl(); - String username = options.getOracleUser(); - char[] password = options.getOraclePassword(); - String tzId = options.getRowcpsTimezone(); - String officeId = options.getOracleOfficeId(); + String cdaUrl = System.getenv("CDA_URL"); + String apiKey = System.getenv("API_KEY"); + String officeId = System.getenv("OFFICE_ID"); - DirectOracleAuthenticationSource directOracleAuthenticationSource = new DirectOracleAuthenticationSource("", dbUrl, officeId); - connectionManager.setTimeZoneId(tzId); - connectionManager.setUsername(username); + CdaAuthenticationSource cdaAuthenticationSource = new CdaAuthenticationSource("", cdaUrl, officeId, new CwmsApiKeyAuthExtension(apiKey)); + try + { + ServerSuite serverSuite = ServerSuiteUtil.login("REGI CLI", cdaAuthenticationSource, false, false, false); + DataAccessFactory dataAccessFactory = serverSuite.getDataAccessFactory(); + try(var key = dataAccessFactory.getDataAccessKey("REGI CLI")) { + String username = dataAccessFactory.getDao(CwmsSecurityDao.class).getCurrentUserId(key); + connectionManager.setUsername(username); + } + connectionManager.setTimeZoneId("UTC"); connectionManager.setUserOfficeId(officeId); connectionManager.saveData(); - TimeZoneDisplayService tsDS = ServiceLookup.getTimeZoneDisplayService(); tsDS.setTimeZone(connectionManager.getTimeZone()); - try - { - ServerSuiteUtil.login("REGI Headless", directOracleAuthenticationSource, username, password); - } - catch(LoginException ex) - { - throw new DbConnectionException(ex); - } - regiDomain.connect(ServerSuiteUtil.getServerSuite()); - List managerList = regiDomain.getManagerList(); - + regiDomain.getManagerList(); regiDomain.saveProject(); + RegiDomain.setCurrentProject(regiDomain); Project.setCurrentProject(regiDomain); + return regiDomain; + } + catch(LoginException | DbIoException ex) + { + throw new DbConnectionException(ex); } - return regiDomain; } - public ManagerId getManagerId(CLIOptions opt) + public ManagerId getManagerId() { - ManagerId retval = idProvider.getManagerId(); - - return retval; + return idProvider.getManagerId(); } - private ManagerIdProvider idProvider = buildNewProvider(); private static ManagerIdProvider buildNewProvider() { diff --git a/regi-headless/src/main/java/usace/rowcps/headless/LoggingOptions.java b/regi-headless/src/main/java/usace/rowcps/headless/LoggingOptions.java index c955c60..70c3559 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/LoggingOptions.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/LoggingOptions.java @@ -9,7 +9,7 @@ import java.util.logging.Logger; import usace.rowcps.headless.metrics.RegiHeadlessMetricsServiceProvider; import usace.rowcps.metrics.RegiMetricsService; -import wcds.dbi.DbiProperties; +import hec.db.cwms.DbiProperties; /** * diff --git a/regi-headless/src/main/java/usace/rowcps/headless/PythonEvaluator.java b/regi-headless/src/main/java/usace/rowcps/headless/PythonEvaluator.java index 32b1b74..a40a329 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/PythonEvaluator.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/PythonEvaluator.java @@ -27,22 +27,9 @@ public Object evaluateExpression(Reader reader, Map variables) // I think this would let us restrict the classes loadable by python. ClassLoader ctxtLoader = Thread.currentThread().getContextClassLoader(); -// try { -// Class aClass = ctxtLoader.loadClass("usace.rowcps.regi.model.AtLocationMananger"); -// } catch (ClassNotFoundException ex) { -// Logger.getLogger(PythonEvaluator.class.getName()).log(Level.SEVERE, null, ex); -// } ScriptEngineManager scriptManager = new ScriptEngineManager(ctxtLoader); ScriptEngine pythonEngine = scriptManager.getEngineByName(ENGINE_NAME); -// if (pythonEngine instanceof (PyScriptEngine)) { -// (PyScriptEngine) object = ((PyScriptEngine)) pythonEngine; -// -// } - - //new PythonScriptContainer() - //ScriptEngineFactory factory = pythonEngine.getFactory(); - SimpleScriptContext context = (SimpleScriptContext) pythonEngine.getContext(); Object javaValue = null; diff --git a/regi-headless/src/main/java/usace/rowcps/headless/RegiCLI.java b/regi-headless/src/main/java/usace/rowcps/headless/RegiCLI.java index b4dc93f..17dc332 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/RegiCLI.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/RegiCLI.java @@ -1,5 +1,6 @@ package usace.rowcps.headless; +import java.io.IOException; import usace.rowcps.headless.interfaces.ScriptEvaluator; import hec.db.DbConnectionException; import hec.db.DbIoException; @@ -45,7 +46,7 @@ public static void main(String[] args) { runHeadless(parser, args, opt); } - catch (DbConnectionException | DbPluginNotFoundException | InvalidDbConnectionException ex) + catch (DbConnectionException | DbPluginNotFoundException | InvalidDbConnectionException | IOException ex) { LOGGER.log(Level.SEVERE, "Headless error connecting to database.", ex); System.exit(-1); @@ -73,21 +74,23 @@ public static void main(String[] args) * @throws CmdLineException * @throws DbPluginNotFoundException */ - static void runHeadlessTest(String[] args) throws DbConnectionException, InvalidDbConnectionException, CmdLineException, DbPluginNotFoundException - { + static void runHeadlessTest(String[] args) + throws DbConnectionException, InvalidDbConnectionException, CmdLineException, DbPluginNotFoundException, + IOException { CLIOptions opt = new CLIOptions(System.getProperties()); CmdLineParser parser = new CmdLineParser(opt); runHeadless(parser, args, opt); } - private static void runHeadless(CmdLineParser parser, String[] args, CLIOptions opt) throws DbConnectionException, InvalidDbConnectionException, CmdLineException, DbPluginNotFoundException - { + private static void runHeadless(CmdLineParser parser, String[] args, CLIOptions opt) + throws DbConnectionException, InvalidDbConnectionException, CmdLineException, DbPluginNotFoundException, + IOException { parser.parseArgument(args); System.setProperties(opt.getProperties()); HeadlessRegiDomainFactory factory = new HeadlessRegiDomainFactory(); - ManagerId managerId = factory.getManagerId(opt); - RegiDomain regiDomain = factory.createDomain(opt, managerId); + ManagerId managerId = factory.getManagerId(); + RegiDomain regiDomain = factory.createDomain(); if (regiDomain != null) { diff --git a/regi-headless/src/main/java/usace/rowcps/headless/SimpleFactoryRegistry.java b/regi-headless/src/main/java/usace/rowcps/headless/SimpleFactoryRegistry.java index 2bb5d1c..c4d0368 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/SimpleFactoryRegistry.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/SimpleFactoryRegistry.java @@ -30,16 +30,6 @@ public Collection getFactories() return factories; } -// public void printNames() -// { -// CalcFactoryRegistry aDefault = getRegistry(DEFAULT_VERSION); -// Collection factories = aDefault.getFactories(); -// for (ScriptableCalcFactory factory : factories) { -// //System.out.println("Found factory:" + factory.getName()); -// logger.log(Level.FINE, "Found factory:" + factory.getName()); -// } -// } - @Override public ScriptableCalcFactory getFactory(String name) { diff --git a/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociations.java b/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociations.java deleted file mode 100644 index af029f9..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociations.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.assocexport; - -/** - * - * @author stephen - */ -public interface ScriptableExportAssociations -{ - /** - * Export all Time Series Associations in the database - * - * @param fileLoc The file to write the CSV to - * @param lineDelimiter the delimiter to use between lines (\n recommended) - * @param valueDelimiter The delimiter to use between values (\t - * recommended) - */ - public void exportAllTSAssociations(String fileLoc, String lineDelimiter, String valueDelimiter); - - /** - * Export the Time Series Associations for a given project - * - * @param project The project to export for - * @param fileLoc The file to write the CSV to - * @param lineDelimiter the delimiter to use between lines (\n recommended) - * @param valueDelimiter The delimiter to use between values (\t - * recommended) - */ - public void exportTSAssociations(String project, String fileLoc, String lineDelimiter, String valueDelimiter); -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociationsFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociationsFactory.java deleted file mode 100644 index 340e714..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportAssociationsFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.assocexport; - -import rma.services.annotations.ServiceProvider; -import usace.rowcps.headless.ScriptableCalcFactory; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.headless.sigstages.exportdb.ScriptableExportSigStagesImpl; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author stephen - */ -@ServiceProvider(service = ScriptableCalcFactory.class) -public class ScriptableExportAssociationsFactory implements ScriptableCalcFactory -{ - public ScriptableExportAssociationsFactory() - { - } - - @Override - public String getName() - { - return "Export Associations"; - } - - @Override - public String getDescription() - { - return "Exports some or all of the Associations in the database."; - } - - @Override - public String getUsage() - { - return ""; - } - - @Override - public ScriptableCalc build(RegiDomain regiDomain, ManagerId managerid) - { - return new ScriptableExportTSAssociationsImpl(regiDomain, managerid); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportTSAssociationsImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportTSAssociationsImpl.java deleted file mode 100644 index 137f348..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/assocexport/ScriptableExportTSAssociationsImpl.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.assocexport; - -import hec.data.location.LocationTemplate; -import hec.data.project.AtProjectDescriptor; -import hec.data.project.IProject; -import hec.data.project.IProjectCatalog; -import hec.db.DbConnectionException; -import hec.db.DbIoException; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.NavigableMap; -import java.util.Objects; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.stream.Collectors; -import usace.rowcps.data.association.IAssociationProvider; -import usace.rowcps.data.association.ITimeSeriesAssociation; -import usace.rowcps.data.outputformatter.CSVOutputFormatter; -import usace.rowcps.data.outputformatter.OutputFormatter; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.AtAssociationCache; -import usace.rowcps.regi.model.CacheUsage; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; -import usace.rowcps.regi.status.AtProjectManager; - -/** - * - * @author stephen - */ -public class ScriptableExportTSAssociationsImpl implements ScriptableExportAssociations, ScriptableCalc -{ - private final ManagerId _managerId; - private final RegiDomain _regiDomain; - private static final Logger LOGGER = Logger.getLogger(ScriptableExportTSAssociationsImpl.class.getSimpleName()); - private static final String GLOBAL = "?GLOBAL?"; - - public ScriptableExportTSAssociationsImpl(RegiDomain regiDomain, ManagerId managerId) - { - _managerId = managerId; - _regiDomain = regiDomain; - } - - private List getAllProjects() - { - try - { - AtProjectManager manager = _regiDomain.getAtProjectManager(_managerId); - IProjectCatalog projectCatalog = manager.getProjectCatalog(CacheUsage.NORMAL); - List projectDescriptorList = projectCatalog.getProjectDescriptorList(); - - Set templatesForDescriptors = projectDescriptorList.stream() - .map(projDesc -> projDesc.getProjectLocationRef()) - .filter(Objects::nonNull) - .collect(Collectors.toSet()); - - NavigableMap iProjects = manager.getIProjects(templatesForDescriptors, CacheUsage.NORMAL); - - return new ArrayList<>(iProjects.values()); - } - catch(DbConnectionException | DbIoException ex) - { - LOGGER.log(Level.SEVERE, "Error Retrieving Associations!", ex); - return Collections.emptyList(); - } - } - - @Override - public void exportAllTSAssociations(String fileLoc, String lineDelimiter, String valueDelimiter) - { - OutputFormatter formatter = new CSVOutputFormatter(lineDelimiter, valueDelimiter); - List allProjects = getAllProjects(); - for(IProject project : allProjects) - { - configureFormatter(formatter, project.getProjectId()); - AtAssociationCache atAssociationCache = _regiDomain.getAtAssociationCache(_managerId); - IAssociationProvider timeSeriesAssociationProvider = atAssociationCache.getTimeSeriesAssociationsProvider(project.getLocation().getLocationTemplate()); - if(timeSeriesAssociationProvider != null) - { - timeSeriesAssociationProvider.serializeToFormat(formatter); - } - } - formatter.write(fileLoc); - } - - private IProject getProject(String projName) - { - try - { - AtProjectManager manager = _regiDomain.getAtProjectManager(_managerId); - IProjectCatalog projectCatalog = manager.getProjectCatalog(CacheUsage.NORMAL); - List projectDescriptorList = projectCatalog.getProjectDescriptorList(); - - Set templatesForDescriptors = projectDescriptorList.stream() - .map(projDesc -> projDesc.getProjectLocationRef()) - .filter(Objects::nonNull) - .filter(projDesc -> projDesc.getLocationId().equals(projName)) - .collect(Collectors.toSet()); - - NavigableMap iProjects = manager.getIProjects(templatesForDescriptors, CacheUsage.NORMAL); - - return iProjects.values().stream() - .filter(project -> project.getProjectId().equals(projName)) - .findFirst() - .orElse(null); - } - catch(DbConnectionException | DbIoException ex) - { - LOGGER.log(Level.SEVERE, "Error Retrieving Associations!", ex); - return null; - } - } - - @Override - public void exportTSAssociations(String projectId, String fileLoc, String lineDelimiter, String valueDelimiter) - { - OutputFormatter formatter = new CSVOutputFormatter(lineDelimiter, valueDelimiter); - IProject project = getProject(projectId); - if(project == null) - { - LOGGER.log(Level.SEVERE, "Error: Project with name {0} unable to be retrieved.", project); - } - else - { - configureFormatter(formatter, project.getProjectId()); - AtAssociationCache atAssociationCache = _regiDomain.getAtAssociationCache(_managerId); - IAssociationProvider timeSeriesAssociationProvider = atAssociationCache.getTimeSeriesAssociationsProvider(project.getLocation().getLocationTemplate()); - if(timeSeriesAssociationProvider != null) - { - timeSeriesAssociationProvider.serializeToFormat(formatter); - } - else - { - LOGGER.log(Level.SEVERE, "Error: Project with name {0} has no TS associations provider.", project); - } - formatter.write(fileLoc); - } - } - - private void configureFormatter(OutputFormatter formatter, String projectId) - { - formatter.addReplacementString(GLOBAL, projectId); - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java index 0e9329e..544f0d9 100644 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java +++ b/regi-headless/src/main/java/usace/rowcps/headless/calculator/gatesettings/ScriptableGateSettingsImpl.java @@ -81,7 +81,6 @@ import usace.rowcps.data.project.TsUsageId; import usace.rowcps.headless.calculator.AbstractScriptableCalc; import usace.rowcps.headless.calculator.inflow.AbstractThreadedBlockRetriever; -import static usace.rowcps.headless.calculator.status.ScriptableStatusGraphicImpl.LATCH_SECONDS; import usace.rowcps.headless.interfaces.ScriptableCalc; import usace.rowcps.metrics.RegiMetricsService; import usace.rowcps.regi.event.IThreadedBlockRetriever; @@ -103,6 +102,7 @@ public class ScriptableGateSettingsImpl extends AbstractScriptableCalc implements ScriptableCalc, ScriptableGateSettings { + public final static String LATCH_SECONDS = "rowcps.latchseconds"; private static final Logger LOGGER = Logger.getLogger(ScriptableGateSettings.class.getName()); public ScriptableGateSettingsImpl(RegiDomain regiDomain, ManagerId managerId) { diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/PoolPercentCalcFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/PoolPercentCalcFactory.java deleted file mode 100644 index 724ec2b..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/PoolPercentCalcFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -package usace.rowcps.headless.calculator.poolpercent; - -import rma.services.annotations.ServiceProvider; -import usace.rowcps.headless.ScriptableCalcFactory; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author ryan - */ -@ServiceProvider(service = ScriptableCalcFactory.class) -public class PoolPercentCalcFactory implements ScriptableCalcFactory -{ - - @Override - public String getName() - { - return "Pool Percent"; - } - - @Override - public String getDescription() - { - return "Recalculates Pool Percentages at a Location"; - } - - @Override - public String getUsage() - { - return ""; - } - - @Override - public ScriptableCalc build(RegiDomain regiDomain, ManagerId managerid) - { - return new ScriptablePoolPercentImpl(regiDomain, managerid); - } - -} \ No newline at end of file diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/ScriptablePoolPercentImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/ScriptablePoolPercentImpl.java deleted file mode 100644 index c4c278c..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/poolpercent/ScriptablePoolPercentImpl.java +++ /dev/null @@ -1,106 +0,0 @@ -package usace.rowcps.headless.calculator.poolpercent; - -import hec.data.TimeWindow; -import hec.data.location.LocationTemplate; -import hec.data.project.IProject; -import hec.db.DbConnectionException; -import hec.db.DbIoException; -import usace.metrics.services.Metrics; -import usace.rowcps.computation.pool.DbCommitPoolCalc; -import usace.rowcps.data.pool.DbPool; -import usace.rowcps.data.pool.PoolTimeSeries; -import usace.rowcps.data.pool.RegiPool; -import usace.rowcps.headless.calculator.AbstractScriptableCalc; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.metrics.RegiMetricsService; -import usace.rowcps.regi.model.CacheUsage; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.OptionalParams; -import usace.rowcps.regi.model.RegiDomain; -import usace.rowcps.regi.pool.AtPoolManager; -import usace.rowcps.regi.status.AtProjectManager; - -import java.util.Date; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; - -/** - * - * @author ryan - */ -public class ScriptablePoolPercentImpl extends AbstractScriptableCalc implements ScriptableCalc -{ - - private static final Logger LOGGER = Logger.getLogger(ScriptablePoolPercentImpl.class.getName()); - - public ScriptablePoolPercentImpl(RegiDomain regiDomain, ManagerId managerId) - { - super(regiDomain, managerId); - } - - public void calculatePoolPercents(String officeId, String locationStr, Date startDate, Date endDate) - { - LocationTemplate locRef = new LocationTemplate(officeId, locationStr); - - Metrics metrics = RegiMetricsService.createMetrics(this.getClass().getSimpleName(), "calculatePoolPercents"); - OptionalParams funcParams = new OptionalParams(metrics); - - LOGGER.log(Level.INFO, "Calculating Pool Percents for {0} from: {1} to: {2}", new Object[]{locRef, startDate, endDate}); - DbCommitPoolCalc poolCalc = new DbCommitPoolCalc(); - AtPoolManager poolMan = regiDomain.getAtPoolManager(managerId); - AtProjectManager projectMan = regiDomain.getAtProjectManager(managerId); - - try - { - //Retrieval of the project also fills in the associations, this is required for the pool calculations. - IProject project = projectMan.getIProject(locRef, CacheUsage.NORMAL); - if (project == null) - { - LOGGER.log(Level.SEVERE, () -> "Unable to calculate pool time series. Project " + locRef + " does not exist."); - return; - } - - Set pools = poolMan.retrievePools(locRef, CacheUsage.NORMAL, funcParams); - pools.stream() - .filter(pool -> pool.getTsId() == null) - .filter(DbPool.class::isInstance) - .map(DbPool.class::cast) - .forEach(pool -> pool.getMetaData().setTsId(retrieveDefaultTsId(pool))); - - TimeWindow tw = new TimeWindow(startDate, true, endDate, true); - - poolCalc.calcTimeSeries(getRegiDomain(), getManagerId(), pools, tw, funcParams); - - LOGGER.log(Level.INFO, "Calculated Pool Percents for {0} from: {1} to: {2}", new Object[]{locRef, startDate, endDate}); - } - catch (DbConnectionException | DbIoException ex) - { - LOGGER.log(Level.SEVERE, "Unable to calculate pool time series data.", ex); - } - } - - // Based on method from PoolsPanel - public String retrieveDefaultTsId(RegiPool pool) - { - LocationTemplate template = pool.getLocationRef(); - String output = AtProjectManager.getDefaultPoolTimeSeriesIdMask(template); - AtProjectManager projMan = regiDomain.getAtProjectManager(managerId); - try - { - output = projMan.retrievePoolTimeSeriesIdMask(template); - } - catch (DbConnectionException | DbIoException ex) - { - LOGGER.log(Level.SEVERE, "Unable to retrieve elevation time series association for " + template.getLocationId() + ". Defaulting to " + output, ex); - } - - String poolName = pool.getPoolName(); - if (poolName.length() > PoolTimeSeries.MAX_POOL_NAME_LENGTH) - { - poolName = poolName.substring(0, PoolTimeSeries.MAX_POOL_NAME_LENGTH); - } - - return output.replace(AtProjectManager.POOL_NAME_MASK, poolName); - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/HeadlessBasinPieAnnotationLayer.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/HeadlessBasinPieAnnotationLayer.java deleted file mode 100644 index 63665cc..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/HeadlessBasinPieAnnotationLayer.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2018 - * United States Army Corps of Engineers - Hydrologic Engineering Center (USACE/HEC) - * All Rights Reserved. USACE PROPRIETARY/CONFIDENTIAL. - * Source may not be released without written approval from HEC - */ -package usace.rowcps.headless.calculator.status; - -import com.rma.ui.pinnable.IPinnableComponentContainer; -import com.rma.ui.pinnable.PinnableComponentManager; -import hec.data.location.LocationGroup; -import hec.data.location.LocationTemplate; -import java.util.List; -import usace.rowcps.basinpie.ui.annotations.BasinPieAnnotationLayer; -import usace.rowcps.data.maptemplate.annotations.AnnotationData; -import usace.rowcps.data.maptemplate.annotations.BarChartAnnotationPayload; -import usace.rowcps.data.maptemplate.annotations.PieChartAnnotationPayload; -import usace.rowcps.decisionsupport.ui.annotations.chartpanel.BarChartAnnotationPanel; -import usace.rowcps.regi.interfaces.model.ManagerIdProvider; - -/** - * - * @author josh - */ -public class HeadlessBasinPieAnnotationLayer extends BasinPieAnnotationLayer -{ - - private final List _activeLocations; - - public HeadlessBasinPieAnnotationLayer(ManagerIdProvider managerIdProvider, - LocationGroup locationGroup, List activeLocations) - { - super(managerIdProvider, locationGroup); - _activeLocations = activeLocations; - } - - @Override - protected List getActiveLocations() - { - return _activeLocations; - } - - @Override - public void addAnnotation(AnnotationData annotationData) - { - IPinnableComponentContainer iPinnableComponentContainer = createAnnotation(annotationData); - if (iPinnableComponentContainer != null) - { - PinnableComponentManager pcm = PinnableComponentManager.getManager(this); - pcm.addPinnableComponent(iPinnableComponentContainer); - - applyAnnotationData(iPinnableComponentContainer, annotationData, true); - annotationData.addPropertyChangeListener(this); - } - } - - public void updateBarChartGraphics() - { - getContainers().keySet().stream() - .filter(BarChartAnnotationPanel.class::isInstance) - .map(BarChartAnnotationPanel.class::cast) - .forEach(BarChartAnnotationPanel::updateBarChart); - } - - @Override - protected void updateAnnotationActiveProjects(AnnotationData data) - { - if (data.getPayload() instanceof PieChartAnnotationPayload) - { - PieChartAnnotationPayload payload = (PieChartAnnotationPayload) data.getPayload(); - payload.setActiveLocations(_activeLocations); - } - else if (data.getPayload() instanceof BarChartAnnotationPayload) - { - BarChartAnnotationPayload payload = (BarChartAnnotationPayload) data.getPayload(); - payload.setActiveLocations(_activeLocations); - } - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/LocationGroupFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/LocationGroupFactory.java deleted file mode 100644 index 9466111..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/LocationGroupFactory.java +++ /dev/null @@ -1,235 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.calculator.status; - -import hec.data.basin.IBasin; -import hec.data.location.AssignedLocation; -import hec.data.location.LocationCategoryRef; -import hec.data.location.LocationGroup; -import hec.data.location.LocationGroupRef; -import hec.data.location.LocationTemplate; -import hec.data.project.IProject; -import hec.db.DbConnectionException; -import hec.db.DbException; -import hec.db.DbIoException; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.NavigableMap; -import java.util.Set; -import java.util.logging.Level; -import java.util.logging.Logger; -import usace.metrics.services.Metrics; -import usace.metrics.services.Timer; -import usace.rowcps.computation.basinconnectivity.BasinConnectivityModel; -import usace.rowcps.metrics.RegiMetricsService; -import usace.rowcps.regi.basin.IBasinConnectivityLocation; -import usace.rowcps.regi.basin.IBasinConnectivityModel; -import usace.rowcps.regi.interfaces.model.ManagerIdProvider; -import usace.rowcps.regi.model.AtBasinManager; -import usace.rowcps.regi.model.CacheUsage; -import usace.rowcps.regi.model.OptionalParams; -import usace.rowcps.regi.model.RegiDomain; -import usace.rowcps.regi.status.AtProjectManager; - -/** - * - * @author josh - */ -public class LocationGroupFactory -{ - ManagerIdProvider _managerIdProvider; - NavigableMap _projectsMap; - Set _projectGroups; - final private BasinConnectivityModel _basinConnectivityModel; - RegiDomain _regiDomain; - - public LocationGroupFactory(ManagerIdProvider managerIdProvider) - { - _managerIdProvider = managerIdProvider; - _basinConnectivityModel = new BasinConnectivityModel(_managerIdProvider.getManagerId()); - _regiDomain = (RegiDomain) RegiDomain.getCurrentProject(); - loadProjectsMap(); - } - - /** - * This method returns the populated LocationGroup for "Project Group" - * with the given projectGroupId - * @param projectGroupId - * @return - */ - public LocationGroup retrieveProjectGroup(String projectGroupId) - { - OptionalParams params = OptionalParams.createForMetrics(getClass().getSimpleName(), "retrieveProjectGroup"); - LocationGroup retval = null; - Set projectGroups = getProjectGroups(params); - for(LocationGroup locGroup : projectGroups) - { - if(locGroup.getName().equalsIgnoreCase(projectGroupId)) - { - retval = locGroup; - break; - } - } - - return retval; - } - - private Set retrieveProjectGroups(OptionalParams params) - { - OptionalParams funcParams = OptionalParams.forMetrics(params, "retrieveProjectGroups"); - AtBasinManager atBasinManager = _regiDomain.getAtBasinManager(_managerIdProvider.getManagerId()); - Set projectGroups = new HashSet<>(); - - try - { - projectGroups.addAll(atBasinManager.getBasinCatalog(funcParams)); - } - catch(DbConnectionException | DbIoException ex) - { - Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Unable to retrieve ProjectGroup catalog from the database.", ex); - } - - return projectGroups; - } - - private Set getProjectGroups(OptionalParams params) - { - OptionalParams funcParams = OptionalParams.forMetrics(params, "getProjectGroups"); - if(_projectGroups != null && _projectGroups.size() > 0) - { - return _projectGroups; - } - else - { - _projectGroups = retrieveProjectGroups(funcParams); - } - - return _projectGroups; - } - - public LocationGroup retrieveLocationGroupForBasin(String basinId) - { - //try getting the IBasin from the AtBasinManager - IBasin basin = retrieveIBasin(basinId); - if(basin == null) - { - Logger.getLogger(LocationGroupFactory.class.getName()).log(Level.SEVERE, "Unable to retrieve Basin from CWMS database for BasinId: {0}", basinId); - return null; - } - - Metrics metrics = RegiMetricsService.createMetrics(getClass().getSimpleName(), "getLocationGroup"); - OptionalParams funcParams = new OptionalParams(metrics); - try(Timer.Context ctx = metrics.createTimer().start()) - { - LocationGroup lg = new LocationGroup(); - lg.setName(basin.getBasinId()); - lg.setDbOfficeId(basin.getOfficeId()); - lg.setLocationGroupRef(new LocationGroupRef(new LocationCategoryRef(AtBasinManager.BASIN_CATEGORY_REF_ID, basin.getOfficeId()), basin.getOfficeId(), basin.getBasinId())); - - //all stream locations are associated with the - LocationTemplate basinLocation = basin.getLocationTemplate(); - - if(!_basinConnectivityModel.isDataAvailableForLocation(basinLocation)) - { - _basinConnectivityModel.fillModel(basin, _projectsMap, funcParams); - } - - IBasinConnectivityLocation primaryStream = _basinConnectivityModel.getStreamBase(new LocationTemplate(basin.getOfficeId(), basin.getPrimaryStream())); - - List assignedLocations = buildAssignedLocations(primaryStream, basinLocation); - - for(int i = 0; i < assignedLocations.size(); i++) - { - assignedLocations.get(i).setAttribute(Double.valueOf(i)); - } - - lg.setAssignedLocations(new HashSet<>(assignedLocations)); - - return lg; - } - } - - /** - * This method returns the basin connectivity model that was populated - * by the retrieveLocationGroupForBasin() method. - * - * @return IBasinConnectivityModel - */ - public IBasinConnectivityModel getBasinConnectivityModel() - { - return _basinConnectivityModel; - } - - private List buildAssignedLocations(IBasinConnectivityLocation streamBase, LocationTemplate basinLocation) - { - List assignedLocations = new ArrayList<>(); - - LocationTemplate streamBaseLocation = streamBase.getLocationTemplate(); - - AssignedLocation aLoc = new AssignedLocation(streamBaseLocation, streamBase.getLocationId(), 0.0, basinLocation); - - aLoc.setDescription(" (" + streamBase.getLocationKind() + ")"); - - assignedLocations.add(aLoc); - - streamBase.getStreamBases().forEach(sbase -> assignedLocations.addAll(buildAssignedLocations(sbase, basinLocation))); - - return assignedLocations; - } - - private IBasin retrieveIBasin(String basinId) - { - IBasin retval = null; - AtBasinManager atBasinManager = _regiDomain.getAtBasinManager(_managerIdProvider.getManagerId()); - try - { - List allBasins = atBasinManager.retrieveAllBasins(CacheUsage.NORMAL, OptionalParams.createForMetrics(getClass().getSimpleName(), "retrieveIBasin", basinId)); - for(IBasin iBasin : allBasins) - { - if(iBasin.getBasinId().equalsIgnoreCase(basinId)) - { - retval = iBasin; - break; - } - } - } - catch (DbException ex) - { - Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, "Error retrieving Basin:", ex); - } - return retval; - } - - private NavigableMap getProjectsMap() - { - if(_projectsMap != null) - { - return _projectsMap; - } - else - { - loadProjectsMap(); - } - return _projectsMap; - } - - private void loadProjectsMap() - { - AtBasinManager atBasinManager = _regiDomain.getAtBasinManager(_managerIdProvider.getManagerId()); - AtProjectManager atProjectManager = _regiDomain.getAtProjectManager(_managerIdProvider.getManagerId()); - Metrics metrics = RegiMetricsService.createMetrics(getClass().getSimpleName(), "getProejcts"); - OptionalParams funcParams = new OptionalParams(metrics); - try - { - _projectsMap = IBasinConnectivityModel.retrieveAllProjects(atBasinManager, atProjectManager, funcParams); - } - catch (DbIoException | DbConnectionException ex) - { - Logger.getLogger(LocationGroupFactory.class.getName()).log(Level.SEVERE, "Error loading projects map:", ex); - } - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/ScriptableStatusGraphicImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/ScriptableStatusGraphicImpl.java deleted file mode 100644 index 72b8568..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/ScriptableStatusGraphicImpl.java +++ /dev/null @@ -1,1151 +0,0 @@ -package usace.rowcps.headless.calculator.status; - -import com.rma.ui.pinnable.PinnableComponentGlassPane; -import com.rma.ui.pinnable.PinnableComponentGlassPaneFactory; -import com.rma.ui.pinnable.PinnableContainer; -import hec.data.location.AssignedLocation; -import hec.data.location.Location; -import hec.data.location.LocationGroup; -import hec.data.location.LocationTemplate; -import hec.data.project.IProject; -import hec.db.DbConnectionException; -import hec.db.DbIoException; -import hec.heclib.util.HecTime; -import java.util.ArrayList; -import java.util.List; -import java.util.logging.Logger; -import usace.rowcps.data.maptemplate.IMapTemplate; -import usace.rowcps.data.maptemplate.streamplot.StreamGageGraphicOptionData; -import usace.rowcps.decisionsupport.ui.basintree.BasinTreeSelectionData; -import usace.rowcps.decisionsupport.ui.basintree.BasinTreeSelectionService; -import usace.rowcps.decisionsupport.ui.basintree.SimpleBasinTreeSelectionData; -import usace.rowcps.decisionsupport.ui.mappanel.template.impl.TimeInfoSource; -import usace.rowcps.decisionsupport.ui.streamplot.StreamData; -import usace.rowcps.decisionsupport.ui.streamplot.StreamPlotPanel; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.AtLocationManager; -import usace.rowcps.regi.model.AtMapTemplateManager; -import usace.rowcps.regi.model.CacheUsage; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; -import hec.map.geoui.interp.TimeInfo; -import java.awt.AlphaComposite; -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Graphics2D; -import java.awt.LayoutManager; -import java.awt.image.BufferedImage; -import java.beans.PropertyChangeEvent; -import java.beans.PropertyChangeListener; -import java.io.BufferedOutputStream; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.lang.reflect.InvocationTargetException; -import java.time.Instant; -import java.util.Arrays; -import java.util.Calendar; -import java.util.Date; -import java.util.HashSet; -import java.util.Iterator; -import java.util.ServiceLoader; -import java.util.Set; -import java.util.SortedSet; -import java.util.TimeZone; -import java.util.TreeSet; -import java.util.concurrent.Callable; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.Future; -import java.util.concurrent.FutureTask; -import java.util.concurrent.RunnableFuture; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; -import java.util.logging.Level; -import javax.imageio.IIOImage; -import javax.imageio.ImageWriteParam; -import javax.imageio.ImageWriter; -import javax.swing.JComponent; -import javax.swing.JLayer; -import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; -import rma.services.GlobalServiceLoader; -import rma.services.GlobalServiceLoaderDelegate; -import usace.metrics.services.Metrics; -import usace.rowcps.metrics.RegiMetricsService; -import usace.rowcps.basinpie.ui.BasinPieModel; -import usace.rowcps.computation.services.CalcFlowGroupTimeSeriesService; -import usace.rowcps.data.charttemplate.IChartTemplate; -import usace.rowcps.data.maptemplate.graphicoptions.ReleasesGraphicOptionData; -import usace.rowcps.data.maptemplate.reservoir.ReservoirGraphicOptionData; -import usace.rowcps.decisionsupport.ui.graphics.releases.ReleasesGraphicData; -import usace.rowcps.decisionsupport.ui.graphics.utilities.GraphicConstants; -import usace.rowcps.headless.calculator.AbstractScriptableCalc; -import usace.rowcps.regi.interfaces.model.ProjectChildLocationCacheService; -import usace.rowcps.regi.model.AtChartTemplateManager; -import usace.rowcps.regi.model.OptionalParams; -import usace.rowcps.regi.ui.gfx2d.PiePanel; -import usace.rowcps.decisionsupport.ui.basintree.OperationSupportBasinTreeModel; -import usace.rowcps.mappanel.ui.template.MapTemplateLayer; -import usace.rowcps.decisionsupport.ui.basintree.BasinTreeModel; -import usace.rowcps.decisionsupport.ui.graphics.releases.ReleasesGraphicPanel; -import usace.rowcps.decisionsupport.ui.reservoirplot.ReservoirPlotPanel; -import usace.rowcps.decisionsupport.ui.reservoirplot.ReservoirPlotPanelData; -import usace.rowcps.mappanel.ui.MapPanelDateRangeService; -import usace.rowcps.mappanel.ui.SimpleMapPanelDateRange; -import usace.rowcps.regi.basin.IBasinConnectivityModel; -import usace.rowcps.regi.executor.FutureDescriptor; -import usace.rowcps.regi.status.AtProjectManager; - -/** - * - * @author ryan - */ -public class ScriptableStatusGraphicImpl extends AbstractScriptableCalc - implements ScriptableCalc -{ - private static final Logger LOGGER = Logger.getLogger(ScriptableStatusGraphicImpl.class.getName()); - public final static String LATCH_SECONDS = "rowcps.latchseconds"; - private final BasinTreeSelectionData _selectionData = new SimpleBasinTreeSelectionData(new ArrayList<>(), new LocationGroup()); - - public ScriptableStatusGraphicImpl(RegiDomain regiDomain, ManagerId manId) - { - super(regiDomain, manId); - System.setProperty("java.awt.headless", "true"); - } - - public void generateReservoirStatusImage(String officeId, String locationId, - String templateName, Date current, - final int width, final int height, - String filename) throws DbConnectionException, DbIoException, IOException, InterruptedException, ExecutionException, TimeoutException - { - SimpleMapPanelDateRange simpleDateRange = new SimpleMapPanelDateRange(current); - MapPanelDateRangeService.registerRange(getManagerId(), simpleDateRange); - - LocationTemplate locTemp = new LocationTemplate(officeId, locationId); - - TimeInfo utcTimeInfo = getUtcTimeInfo(current, regiDomain.getTimeZone()); - - TimeInfoSource utcTimeInfoSource = () -> utcTimeInfo; - - checkForKnownNeededServices(); - - MapTemplateLayer mtl = getMapTemplateLayer(templateName); - - ReservoirGraphicOptionData optionData = mtl.getGraphicsOptions(); - - CountDownLatch cdl = new CountDownLatch(1); - PropertyChangeListener pcl = (PropertyChangeEvent evt) -> - { - if (GraphicConstants.DATA_FILLED_EVENT.equals(evt.getPropertyName())) - { - cdl.countDown(); - } - }; - - optionData.addPropertyChangeListener(pcl); - - AtProjectManager atProjectManager = this.regiDomain.getAtProjectManager(managerId); - IProject iProject = atProjectManager.getIProject(locTemp, CacheUsage.NORMAL); - - ReservoirPlotPanelData plotPanelData = new ReservoirPlotPanelData(iProject, utcTimeInfoSource, managerId, optionData); - plotPanelData.addPropertyChangeListener(pcl); - - ReservoirPlotPanel reservoirPlotPanel; - - RunnableFuture panelFuture = new FutureTask<>(() -> new ReservoirPlotPanel(iProject, managerId, utcTimeInfoSource, plotPanelData)); - SwingUtilities.invokeLater(panelFuture); - reservoirPlotPanel = panelFuture.get(1, TimeUnit.MINUTES); - - Integer seconds = Integer.getInteger(LATCH_SECONDS, 11 * 60); // This one goes to 11... - boolean normalExit = cdl.await(seconds, TimeUnit.SECONDS); - if (!normalExit) - { - LOGGER.log(Level.WARNING, "Timeout exceeded loading reservoir status graphic data."); - } - - optionData.removePropertyChangeListener(pcl); - - // This next sleep is important b/c the latch gets set after the SwingWorker doInBackground complete but before done() - // are called. We need the done() methods to execute before we proceed. - Thread.sleep(2000); - - String imageFormat = getFormatFromFile(filename); - - Dimension d = computePreferredSize(reservoirPlotPanel, width, height); - - layoutAndSave(reservoirPlotPanel, d, filename, imageFormat); - } - - private Dimension computePreferredSize(Component comp, int requestedWidth, int requestedHeight) - { - comp.setPreferredSize(null); //Causes the component to recompute its pref size - Dimension prefSize = comp.getPreferredSize(); - Dimension reqSize = new Dimension(requestedWidth, requestedHeight); - - //This should prevent most clipping issues where the size provided is too small for the data. - return computeLargestDimension(prefSize, reqSize); - } - - private Dimension computeLargestDimension(Dimension dim1, Dimension dim2) - { - return new Dimension(Math.max(dim1.width, dim2.width), Math.max(dim1.height, dim2.height)); - } - - private boolean checkForKnownNeededServices() - { - boolean hasCalcFlow = hasGlobalService(CalcFlowGroupTimeSeriesService.class); - if (!hasCalcFlow) - { - ServiceLoader serviceLoader = ServiceLoader.load(CalcFlowGroupTimeSeriesService.class); - hasCalcFlow = hasService(CalcFlowGroupTimeSeriesService.class, serviceLoader); - } - - if (!hasCalcFlow) - { - String mesg = "The CalcFlowGroupTimeSeriesService was not found and is known to be needed by Regi Headless. " - + "Without this service the headless Status Graphic generation may not generate the correct values. " - + "Even if the necessary classes are in the classpath, the services may still not be found " - + "if the jars do not include the necessary META-INF services folder. " - + "For example, public-package-jars\\usace-rowcps-computation.jar contains implementation classes " - + "but not the service definitions."; - LOGGER.warning(mesg); - } - - boolean hasProjectChild = hasGlobalService(ProjectChildLocationCacheService.class); - if (!hasProjectChild) - { - String mesg = "A ProjectChildLocationCacheService was not found and is known to be needed by Regi Headless. " - + "Without this service the headless Status Graphic generation may not generate the correct values. " - + "Even if the necessary classes are in the classpath, the services may still not be found " - + "if the jars do not include the necessary META-INF services folder. " - + "For example, public-package-jars\\usace-rowcps-regi.jar contains implementation classes " - + "but not the service definitions."; - LOGGER.warning(mesg); - } - - return hasCalcFlow && hasProjectChild; - } - - private boolean hasGlobalService(Class klass) - { - GlobalServiceLoaderDelegate instance = GlobalServiceLoader.getInstance(); - ServiceLoader serviceLoader = instance.getServiceLoader(klass); - - return hasService(klass, serviceLoader); - } - - private boolean hasService(Class klass, ServiceLoader sl) - { - boolean hasCalcFlow = false; - ServiceLoader serviceLoader; - - GlobalServiceLoaderDelegate instance = GlobalServiceLoader.getInstance(); - serviceLoader = instance.getServiceLoader(klass); - - for (Object service : serviceLoader) - { - hasCalcFlow = true; - break; - } - return hasCalcFlow; - } - - public void generateStreamStatusImage(String officeId, String locationId, - String templateName, Date current, - final int width, final int height, - String filename) throws DbConnectionException, DbIoException, IOException, InterruptedException, ExecutionException, TimeoutException - { - - LocationTemplate locTemp = new LocationTemplate(officeId, locationId); - - AtLocationManager locMan = this.regiDomain.getAtLocationManager(getManagerId()); - Location loc = locMan.retrieveLocation(locTemp, CacheUsage.NORMAL); - - final TimeInfo ti = getUtcTimeInfo(current, this.regiDomain.getTimeZone()); - - TimeInfoSource timeInfoSource = () -> ti; - - SimpleMapPanelDateRange simpleDateRange = new SimpleMapPanelDateRange(current); - MapPanelDateRangeService.registerRange(getManagerId(), simpleDateRange); - - MapTemplateLayer mapTemplateLayer = getMapTemplateLayer(templateName); - - if(mapTemplateLayer == null) - { - LOGGER.log(Level.SEVERE, "Unable to locate MapTemplateLayer with the name:{0}", templateName); - return; - } - - StreamGageGraphicOptionData sggod = mapTemplateLayer.getStreamGageGraphicOptions(); - TimeZone timeZone = this.regiDomain.getTimeZone(); - final StreamData streamData = new StreamData(loc, sggod, timeInfoSource, timeZone, getManagerId()); - - final CountDownLatch cdl = new CountDownLatch(1); - PropertyChangeListener pcl = (PropertyChangeEvent evt) -> - { - if (GraphicConstants.DATA_FILLED_EVENT.equals(evt.getPropertyName())) - { - cdl.countDown(); - } - }; - - streamData.addPropertyChangeListener(pcl); - Future future = streamData.retrieveData(); - future.get(11, TimeUnit.MINUTES); //No return from this, but we need to wait until it's done. - - String imageFormat = getFormatFromFile(filename); - - StreamPlotPanel panel = new StreamPlotPanel(streamData); // Why is this building a panel on background thread? - - Dimension d = computePreferredSize(panel, width, height); - - layoutAndSave(panel, d, filename, imageFormat); - } - - public void generateReleasesStatusImage(String officeId, String locationId, - String templateName, Date current, - final int width, final int height, - String filename) throws DbConnectionException, DbIoException, IOException, InterruptedException, TimeoutException, ExecutionException - { - Metrics metrics = RegiMetricsService.createMetrics(getClass().getSimpleName()); - - MyReleasesGraphicData data = buildReleasesGraphicData(officeId, locationId, current, metrics); - - CompletableFuture future = data.retrieveOutletGroups(new OptionalParams(metrics)); - data.updateDataScopeSynchronous(new OptionalParams(metrics)); - LOGGER.log(Level.FINE, "(Headless)Data scope retrieval complete."); - future.get(); - LOGGER.log(Level.FINE, "(Headless)Retrieval of outlet groups complete."); - - //This needs to occur *after* all of the futures have been completed. - data.fireDataUpdateEvent(); - - saveReleasesToFile(data, width, height, filename); - } - - private MyReleasesGraphicData buildReleasesGraphicData(String officeId, String locationId, Date current, Metrics metrics) throws DbConnectionException, DbIoException - { - LocationTemplate locTemp = new LocationTemplate(officeId, locationId); - AtLocationManager locMan = this.regiDomain.getAtLocationManager(getManagerId()); - Location loc = locMan.retrieveLocation(locTemp, CacheUsage.NORMAL); - TimeInfo utcTimeInfo = getUtcTimeInfo(current, this.regiDomain.getTimeZone()); - TimeInfoSource utcTimeInfoSource = () -> utcTimeInfo; - SimpleMapPanelDateRange simpleDateRange = new SimpleMapPanelDateRange(current); - MapPanelDateRangeService.registerRange(getManagerId(), simpleDateRange); - ReleasesGraphicOptionData graphicOptionData = new ReleasesGraphicOptionData(); - - return new MyReleasesGraphicData(loc, managerId, utcTimeInfoSource, graphicOptionData, new OptionalParams(metrics)); - } - - private void saveReleasesToFile(ReleasesGraphicData data, int width, int height, String filename) - { - try - { - SwingUtilities.invokeAndWait(() -> - { - ReleasesGraphicPanel releasesGraphicPanel = new ReleasesGraphicPanel(false, true); - releasesGraphicPanel.setData(data); - - //This is a bit assinine, but it's used to massage the preferred sizes - //The detail component's pref size is constantly recomputed on paint....why? because science! and my youthful ignorance. - renderGraphic(releasesGraphicPanel); - renderGraphic(releasesGraphicPanel); - renderGraphic(releasesGraphicPanel); - renderGraphic(releasesGraphicPanel); - - Dimension imageDimension = computePreferredSize(releasesGraphicPanel, width, height); - String imageFormat = getFormatFromFile(filename); - - try - { - layoutAndSave(releasesGraphicPanel, imageDimension, filename, imageFormat); - } - catch (IOException ex) - { - LOGGER.log(Level.SEVERE, "Unable to save to file " + filename, ex); - } - }); - } - catch (InterruptedException ex) - { - LOGGER.log(Level.SEVERE, "Event thread was interrupted", ex); - } - catch (InvocationTargetException ex) - { - LOGGER.log(Level.SEVERE, "An uncaught exception occurred on the Event Thread for generateReleasesStatusImage.", ex); - } - } - - private void renderGraphic(JComponent comp) - { - layoutComponent(comp, comp.getSize()); - BufferedImage img = new BufferedImage(comp.getWidth(), comp.getHeight(), BufferedImage.TYPE_INT_ARGB); - Graphics2D g = img.createGraphics(); - comp.print(g); - computePreferredSize(comp, comp.getWidth(), comp.getHeight()); - } - - private void layoutComponent(JComponent component, Dimension d) - { - LayoutManager layout = component.getLayout(); - if (layout != null) - { - layout.layoutContainer(component); - } - component.setSize(d); - component.addNotify(); - component.invalidate(); - component.validate(); - component.addNotify(); - if (layout != null) - { - layout.layoutContainer(component); - } - } - - public static class MyReleasesGraphicData extends ReleasesGraphicData - { - private boolean _hasRetrieved = false; - - public MyReleasesGraphicData(Location loc, ManagerId manId, - TimeInfoSource tis, - ReleasesGraphicOptionData options, - OptionalParams optionalParams) - { - super(loc, manId, tis, options, optionalParams); - } - - @Override - public CompletableFuture updateDataScope(OptionalParams params) - { - if (!_hasRetrieved) - { - LOGGER.log(Level.FINE, "(Headless)Updating data scope"); - _hasRetrieved = true; - return super.updateDataScope(params); - } - return CompletableFuture.completedFuture(null); - } - - public void updateDataScopeSynchronous(OptionalParams params) throws InterruptedException, ExecutionException - { - updateDataScope(params).get(); - } - - @Override - public void fireDataUpdateEvent() - { - //Exposing this publicly - super.fireDataUpdateEvent(); //To change body of generated methods, choose Tools | Templates. - } - } - - public TimeInfo getUtcTimeInfo(Date current, TimeZone displayTimeZone) - { - // The time controls internally use HecTimes with utc values and Regi formats them to the display timezone in the ui - // components. - // In headless the user is giving us a Date object and a timezone that date object is in. - // So imagine the user wants a graphic displayed at midnight on 4/18 in CDT. Say that UTC is ahead of CDT by 5 hours - // so we need hectime to actually store the time at 5AM - HecTime utcStart = new HecTime(); - utcStart.setTimeInMillis(current.getTime()); - - Calendar endCal = Calendar.getInstance(displayTimeZone); - endCal.setTime(current); - endCal.add(Calendar.DAY_OF_MONTH, 1); - //truncate down to start of day // - HecTime utcEnd = new HecTime(); - utcEnd.setTimeInMillis(endCal.getTimeInMillis()); - - HecTime utcCurrent = new HecTime(); - utcCurrent.setTimeInMillis(current.getTime()); - - utcCurrent.showTimeAsBeginningOfDay(true); - - int stepSize = 1000 * 60 * 60; // millisPerHour - TimeInfo ti = new TimeInfo(utcStart, utcEnd, utcCurrent, stepSize); - return ti; - } - - private List getMapTemplates() throws DbIoException, DbConnectionException - { - RegiDomain currentProject = (RegiDomain) RegiDomain.getCurrentProject(); - final AtMapTemplateManager tm = currentProject.getAtMapTemplateManager(getManagerId()); - final List mapTemplates = tm.retrieveMapTemplates(currentProject.getUserOfficeId(), - CacheUsage.NORMAL); - return mapTemplates; - } - - private MapTemplateLayer getMapTemplateLayer(String templateName) throws DbIoException, DbConnectionException - { - //Map template layer will require this if we have an annotation layer. - BasinTreeSelectionData selectionData = BasinTreeSelectionService.getBasinTreeSelectionData(getManagerIdProvider().getManagerId()); - if (selectionData != _selectionData) - { - //_selectionData needs to be a class member, because both key and value are weak references. - BasinTreeSelectionService.registerBasinTreeSelectionData(getManagerIdProvider().getManagerId(), _selectionData); - } - - MapTemplateLayer retval = null; - List mapTemplates = getMapTemplates(); - IMapTemplate matching = find(templateName, mapTemplates); - - if (matching != null) - { - retval = new MapTemplateLayer(matching, getManagerIdProvider()); - } - - return retval; - } - - private IMapTemplate find(String templateName, - List mapTemplates) - { - IMapTemplate retval = null; - - if (mapTemplates != null && !mapTemplates.isEmpty() && templateName != null) - { - for (IMapTemplate mapTemplate : mapTemplates) - { - if (templateName.equalsIgnoreCase(mapTemplate.getName())) - { - retval = mapTemplate; - break; - } - } - } - - return retval; - } - - public void generateBasinPieImageForGroup(final String officeId, - final String locationStr, - final String groupId, - final Date date, final int width, - final int height, final String template, - final String file) throws Exception - { - String[] locations = new String[] {locationStr}; - Date[] dates = new Date[] {date}; - String[] templates = new String[]{template}; - generateBasinPieImagesForGroup(officeId, locations, groupId, dates, width, - height, templates, file); - } - - public void generateBasinPieImageForBasin(final String officeId, - final String locationStr, - final String basinId, - final Date date, final int width, - final int height, final String template, - final String file) throws Exception - { - String[] locations = new String[] {locationStr}; - Date[] dates = new Date[] {date}; - String[] templates = new String[]{template}; - generateBasinPieImagesForBasin(officeId, locations, basinId, dates, width, - height, templates, file); - } - -/** - * This method generates a suite a basin pie images for a given basin - * 1 basin pie image for each possible assigned location as a reference. - * - * @param officeId - * @param basinId - * @param dates - * @param width - * @param height - * @param templateIds - * @param file - * @throws Exception - */ - public void generateAllBasinPieImagesForBasin(final String officeId, - final String basinId, - final Date[] dates, - final int width, final int height, - final String[] templateIds, - final String file) throws Exception - { - LocationGroupFactory locationGroupFactory = new LocationGroupFactory(getManagerIdProvider()); - LocationGroup locationGroup = locationGroupFactory.retrieveLocationGroupForBasin(basinId); - - OperationSupportBasinTreeModel basinTreeModel = new OperationSupportBasinTreeModel(); - IBasinConnectivityModel basinConnModel = locationGroupFactory.getBasinConnectivityModel(); - basinTreeModel.fillBasinTree(locationGroup, basinConnModel); - - generateAllBasinPieImages(officeId, locationGroup, basinTreeModel, dates, width, height, templateIds, file); - } - - /** - * This method generates a suite a basin pie images for a given basin - * 1 basin pie image for each possible assigned location as a reference. - * - * @param officeId - * @param groupId - * @param dates - * @param width - * @param height - * @param templateIds - * @param file - * @throws Exception - */ - public void generateAllBasinPieImagesForGroup(final String officeId, - final String groupId, - final Date[] dates, - final int width, final int height, - final String[] templateIds, - final String file) throws Exception - { - LocationGroupFactory locationGroupFactory = new LocationGroupFactory(getManagerIdProvider()); - LocationGroup locationGroup = locationGroupFactory.retrieveProjectGroup(groupId); - - BasinTreeModel basinTreeModel = new BasinTreeModel(null); - basinTreeModel.fillBasinTree(locationGroup); - - generateAllBasinPieImages(officeId, locationGroup, basinTreeModel, dates, width, height, templateIds, file); - } - - private void generateAllBasinPieImages(final String officeId, - final LocationGroup locationGroup, - final BasinTreeModel basinTreeModel, - final Date[] dates, - final int width, final int height, - final String[] templateIds, - final String file) throws Exception - { - List referenceLocations = new ArrayList<>(); - - Set assignedLocations = locationGroup.getAssignedLocations(); - for (AssignedLocation assignedLocation : assignedLocations) - { - referenceLocations.add(assignedLocation.getLocRef()); - } - - List templates = getTemplates(templateIds, officeId); - final Dimension d = new Dimension(width, height); - String imageFormat = getFormatFromFile(file); - - generateImages(officeId, referenceLocations, locationGroup, basinTreeModel, dates, d, templates, file, imageFormat); - } - - public void generateBasinPieImagesForBasin(final String officeId, - final String locationStrs[], - final String basinId, - final Date[] dates, final int width, - final int height, - final String[] templateIds, - final String filename) throws Exception - { - System.setProperty("java.awt.headless", "true"); - if (width <= 0 || height <= 0) - { // is there a max? - LOGGER.warning("Width and Height parameters must be > 0"); - return; - } - - LocationGroupFactory locationGroupFactory = new LocationGroupFactory(getManagerIdProvider()); - LocationGroup locationGroup = locationGroupFactory.retrieveLocationGroupForBasin(basinId); - - OperationSupportBasinTreeModel basinTreeModel = new OperationSupportBasinTreeModel(); - IBasinConnectivityModel basinConnModel = locationGroupFactory.getBasinConnectivityModel(); - basinTreeModel.fillBasinTree(locationGroup, basinConnModel); - - List templates = getTemplates(templateIds, officeId); - - List locs = new ArrayList<>(); - for (String locationStr : locationStrs) - { - final LocationTemplate locRef = new LocationTemplate(officeId, locationStr); - locs.add(locRef); - } - - String imageFormat = getFormatFromFile(filename); - final Dimension dimension = new Dimension(width, height); - - generateImages(officeId, locs, locationGroup, basinTreeModel, dates, dimension, templates, filename, imageFormat); - } - - public void generateBasinPieImagesForGroup(final String officeId, - final String locationStrs[], - final String groupId, - final Date[] dates, final int width, - final int height, - final String[] templateIds, - final String filename) throws Exception - { - System.setProperty("java.awt.headless", "true"); - if (width <= 0 || height <= 0) - { // is there a max? - LOGGER.warning("Width and Height parameters must be > 0"); - return; - } - - LocationGroupFactory locationGroupFactory = new LocationGroupFactory(getManagerIdProvider()); - LocationGroup locationGroup = locationGroupFactory.retrieveProjectGroup(groupId); - BasinTreeModel treeModel = new BasinTreeModel(); - treeModel.fillBasinTree(locationGroup); - - List templates = getTemplates(templateIds, officeId); - - List locs = new ArrayList<>(); - for (String locationStr : locationStrs) - { - final LocationTemplate locRef = new LocationTemplate(officeId, locationStr); - locs.add(locRef); - } - - String imageFormat = getFormatFromFile(filename); - final Dimension dimension = new Dimension(width, height); - - generateImages(officeId, locs, locationGroup, treeModel, dates, dimension, templates, filename, imageFormat); - } - - public void generateImages(String officeId, - List referenceLocations, - LocationGroup locationGroup, - BasinTreeModel treeModel, - Date[] dates, - Dimension d, - List templates, - String filePattern, String imageFormat) - throws ExecutionException, DbConnectionException, InterruptedException - { - SortedSet dateSet = new TreeSet<>(); - dateSet.addAll(Arrays.asList(dates)); - - Date startDate = dateSet.first(); - Date endDate = dateSet.last(); - - for (IChartTemplate chartTemplate : templates) - { - LOGGER.log(Level.INFO, "Generating images for template:{0}", chartTemplate.getId()); - BasinPieModel pieModel = buildAndInitializeBasinPieModel(locationGroup, chartTemplate, startDate, endDate, treeModel); - - for (Date date : dateSet) - { - for (LocationTemplate locRef : referenceLocations) - { - String file = getFileName(date, filePattern, locRef.getLocationId(), imageFormat, chartTemplate.getIdSuffix(), officeId, locationGroup.getName(), d.width, d.height); - drawImage(treeModel, locRef, pieModel, d, date, file, imageFormat); - } - } - } - } - - public List getTemplates(final String[] templateIds, - final String officeId) throws DbConnectionException, DbIoException - { - List templates = new ArrayList<>(); - AtChartTemplateManager chartTemplateManager = regiDomain.getAtChartTemplateManager(managerId); - for (String template : templateIds) - { - String templateId = IChartTemplate.CHART_TEMPLATE_CATEGORY_ID + "." + officeId + "." + template; - - IChartTemplate chartTemplate = chartTemplateManager.retrieveChartTemplate(officeId, templateId, CacheUsage.NORMAL); - if (chartTemplate == null) - { - // try again using the user-provided string. - chartTemplate = chartTemplateManager.retrieveChartTemplate(officeId, template, CacheUsage.NORMAL); - } - - if (chartTemplate == null) - { - LOGGER.log(Level.WARNING, "Could not locate chart:{0}", templateId); - } - else - { - templates.add(chartTemplate); - } - - } - return templates; - } - - public static String getFileName(Date date, final String filePattern, - final String locationStr, - String imageFormat, String chartTemplate, - String officeId, String basinId, int width, - int height) - { - - String dateStr = getDateString(date); - - SimpleTemplateEngine engine = new SimpleTemplateEngine(); - engine.addPattern("date", dateStr); - engine.addPattern("office_id", officeId); - engine.addPattern("location_id", locationStr); - engine.addPattern("chart_template_id", chartTemplate); - engine.addPattern("basin_id", basinId); - engine.addPattern("image_format", imageFormat); - engine.addPattern("width", Integer.toString(width)); - engine.addPattern("height", Integer.toString(height)); - - String filename = engine.makeReplacements(filePattern); -// Replace anything that isn't a-z or A-z or 0-9 or [:\/)(.-] with an underscore. - return filename.replaceAll("[^a-zA-Z0-9:\\\\\\/\\)\\(\\.\\- ]", "_"); - } - - public static String getDateString(Date date) - { - Instant asInstant = date.toInstant(); - String dateStr = asInstant.toString(); // like: 2017-02-24T22:23:21.149Z - dateStr = dateStr.replaceAll(":", "_"); - return dateStr; - } - - public void drawImage(BasinTreeModel treeModel, - LocationTemplate locRef, - BasinPieModel pieModel, Dimension d, - Date date, String file, - String imageFormat) throws InterruptedException, ExecutionException - { - - final CountDownLatch latch = new CountDownLatch(1); - final SwingWorker worker = new SwingWorker() - { - @Override - protected Void doInBackground() throws Exception - { - List relavantLocations = treeModel.getRelevantLocations(locRef); - LOGGER.log(Level.INFO, "Found {0} locations relevant to {1}", new Object[] - { - relavantLocations.size(), locRef - }); - pieModel.setActiveLocations(relavantLocations, true); - - return null; - } - - @Override - protected void done() - { - try - { - LOGGER.log(Level.INFO, "Creating Basin Pie Panel."); - writeBasinImage(d, pieModel, date, file, imageFormat); - latch.countDown(); - } - catch (IOException ex) - { - LOGGER.log(Level.SEVERE, null, ex); - } - } - }; - - worker.execute(); - - Void got = worker.get(); // This returns as soon as doInBackground finishes. - boolean normalExit = latch.await(Integer.getInteger(LATCH_SECONDS, 11 * 60), TimeUnit.SECONDS); - if (!normalExit) - { - LOGGER.log(Level.WARNING, "Exceeded timeout waiting for basin image to draw."); - } - - } - - public BasinPieModel buildAndInitializeBasinPieModel( - LocationGroup locationGroup, IChartTemplate chartTemplate, - Date startDate, Date endDate, - BasinTreeModel treeModel) throws InterruptedException - { - BasinPieModel pieModel = new BasinPieModel(managerId, locationGroup, chartTemplate, startDate, endDate); - CountDownLatch initlatch = new CountDownLatch(1); - pieModel.addPropertyChangeListener((PropertyChangeEvent evt) -> - { - if ("PieDataChangedProperty".equals(evt.getPropertyName())) - { - LOGGER.log(Level.FINER, "PieDataChanged edt:{0} latch:{1}", - new Object[] - { - SwingUtilities.isEventDispatchThread(), initlatch.getCount() - }); - initlatch.countDown(); - } - }); - List forInitCache = treeModel.getRelevantLocations(null); - LOGGER.log(Level.INFO, "Initializing BasinPieModel with {0} locations.", forInitCache.size()); - pieModel.initCache(forInitCache); // this can take a while but it fires a property change event when its done. - - boolean normalExit = initlatch.await(Integer.getInteger(LATCH_SECONDS, 11 * 60), TimeUnit.SECONDS); - if (!normalExit) - { - LOGGER.log(Level.WARNING, "Exceeded timeout waiting for basin pie model to load."); - } - - return pieModel; - } - - private void writeBasinImage(Dimension d, BasinPieModel pieModel, - Date date, String file, String imageFormat) throws FileNotFoundException, IOException - { - LocationGroup locationGroup = pieModel.getLocationGroup(); - PiePanel piePanel = new PiePanel(); - IChartTemplate chartTemplate = pieModel.getChartTemplate(); - List dataIdentifiers = chartTemplate.getDataIdentifiers(); - Set poolIds = new HashSet<>(); - poolIds.addAll(dataIdentifiers); - - TimeZone timezone = regiDomain.getTimeZone(); - piePanel.setTimeZone(timezone); - - JLayer piePanelJLayerWrapper = new JLayer(piePanel); - HeadlessBasinPieAnnotationLayer basinPieAnnotationLayer = new HeadlessBasinPieAnnotationLayer(getManagerIdProvider(), locationGroup, pieModel.getActiveLocations()); - basinPieAnnotationLayer.fillPanel(poolIds, date, chartTemplate); - - PinnableComponentGlassPane glassPane = PinnableComponentGlassPaneFactory.createNewGlassPane(basinPieAnnotationLayer, piePanel); - - piePanelJLayerWrapper.setGlassPane(glassPane); - glassPane.addPinnableContainer(basinPieAnnotationLayer); - PinnableContainer container = glassPane.getPinnableContainer(basinPieAnnotationLayer); - basinPieAnnotationLayer.setPinnableContainer(container); - container.setSize(d); - - List> futures = basinPieAnnotationLayer.resetFromChartTemplate(); - futures.stream().map((future) -> - { - if (future instanceof FutureDescriptor) - { - return ((FutureDescriptor) future).getFuture(); - } - return future; - }).forEach((future)-> - { - try - { - future.get(); - } - catch (InterruptedException | ExecutionException ex) - { - LOGGER.log(Level.INFO, "Well that didn't work...", ex); - } - }); - - PinnableComponentGlassPaneFactory.getGlassPane(basinPieAnnotationLayer).setVisible(true); - - LOGGER.fine("Filling panel with model."); - piePanel.fillPanel(pieModel); - LOGGER.log(Level.INFO, "Setting active date:{0}", date); - piePanel.setActiveDate(date); - - //This updates the data of bar charts. This has to happen after we've loaded the data. Otherwise it doesn't - //Load the bar chart correctly. - basinPieAnnotationLayer.updateBarChartGraphics(); - - layoutAndSave(piePanelJLayerWrapper, d, file, imageFormat); - } - - /** - * Saves a copy of the plot as a image type - * - * @param os the output stream to write to. - * @param panel - * @param imageType i.e. "png" or "jpg". - * @param compression sets the compression for the image if the image writer - * supports it - * @return - * @throws java.io.IOException - */ - protected boolean saveToStream(OutputStream os, final JComponent panel, - String imageType, float compression) throws IOException - { - // This next comment came from the source this was loosely based on. - /** - * Add a revalidate here in order for headless scripting to work. Due to - * a joining of the building and displaying of the plot in showPlot(), - * any component changes to recompute preferred sizes and exports look - * bad and components overlap. If we do this here, then we can build and - * show the plot, tweak some properties and export correctly. - */ - - BufferedImage bImage; - - if (SwingUtilities.isEventDispatchThread()) - { - bImage = saveToImage(panel.getSize(), panel); - } - else - { - Callable imageCallable = () -> saveToImage(panel.getSize(), panel); - FutureTask futureTask = new FutureTask<>(imageCallable); - - SwingUtilities.invokeLater(futureTask); - try - { - // Not sure how long to wait here. Infinite is wrong. - bImage = futureTask.get(5, TimeUnit.MINUTES); - } - catch (InterruptedException ex) - { - Thread.currentThread().interrupt(); - throw new IOException("Background paint was interrupted.", ex); - } - catch (ExecutionException ex) - { - throw new IOException("Background paint encountered ExecutionException.", ex); - } - catch (TimeoutException ex) - { - throw new IOException("Timeout waiting for paint to complete.", ex); - } - } - return writeImage(imageType, compression, os, bImage); - } - - public boolean writeImage(String imageType, float compression, - OutputStream os, BufferedImage bImage) - { - Iterator iter = javax.imageio.ImageIO.getImageWritersByFormatName(imageType); - if (!iter.hasNext()) - { - LOGGER.log(Level.WARNING, "No Image writers exist for Image Type = {0}", imageType); - return true; - } - ImageWriter next = iter.next(); - ImageWriteParam defaultWriteParam = next.getDefaultWriteParam(); - if (defaultWriteParam.canWriteCompressed() && compression != hec.lang.Const.UNDEFINED_INT) - { - defaultWriteParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); - defaultWriteParam.setCompressionQuality(compression / 100); - } - writeToStream(next, os, bImage, defaultWriteParam); - return false; - } - - public static BufferedImage saveToImage(Dimension d, JComponent panel) - { - - BufferedImage bImage = new BufferedImage(d.width, d.height, BufferedImage.TYPE_INT_RGB); - paintIntoImage(bImage, d, panel); - - return bImage; - } - - private static void paintIntoImage(BufferedImage bImage, Dimension d, - JComponent panel) - { - Graphics2D g = bImage.createGraphics(); - - boolean useTrans = false; - - if (!useTrans) - { - Color color = new Color(226, 226, 226); // make backgroup grey - g.setColor(color); - g.fillRect(0, 0, d.width, d.height); - } - else - { - // This doesn't work. - Color color = new Color(0, 0, 0, 0); - g.setColor(color); - g.setComposite(AlphaComposite.Clear); - g.fillRect(0, 0, d.width, d.height); - g.setComposite(AlphaComposite.SrcOver); - } - - panel.paint(g); - g.dispose(); - } - - public static void writeToStream(ImageWriter writer, OutputStream fs, - BufferedImage bImage, - ImageWriteParam defaultWriteParam) - { - try - { - writer.setOutput(javax.imageio.ImageIO.createImageOutputStream(fs)); - writer.write(null, new IIOImage(bImage, null, null), defaultWriteParam); - } - catch (IOException e) - { - LOGGER.log(Level.SEVERE, "Exception encountered writing image.", e); - } - finally - { - writer.dispose(); - try - { - if (fs != null) - { - fs.flush(); - fs.close(); - } - } - catch (IOException ioe) - { - LOGGER.log(Level.SEVERE, "IOException encountered while closing OutputStream.", ioe); - } - } - } - - protected String getFormatFromFile(String file) - { - String format = "png"; - - if (file != null && !file.isEmpty()) - { - String asLower = file.toLowerCase(); - - if (asLower.endsWith(".jpg") || asLower.endsWith(".jpeg")) - { - return "jpg"; - } - - } - - return format; - } - - public void layoutAndSave(final JComponent component, final Dimension d, - String file, String imageFormat) throws IOException - { - if (SwingUtilities.isEventDispatchThread()) - { - layoutComponent(component, d); - } - else - { - Callable imageCallable = () -> - { - layoutComponent(component, d); - return Boolean.TRUE; - }; - FutureTask futureTask = new FutureTask<>(imageCallable); - - SwingUtilities.invokeLater(futureTask); - try - { - // Not sure how long to wait here. Infinite is wrong. - Boolean dontcare = futureTask.get(1, TimeUnit.MINUTES); - } - catch (InterruptedException ex) - { - Thread.currentThread().interrupt(); - throw new IOException("Background layout was interrupted.", ex); - } - catch (ExecutionException ex) - { - throw new IOException("Background layout encountered ExecutionException.", ex); - } - catch (TimeoutException ex) - { - throw new IOException("Timeout waiting for layout to complete.", ex); - } - } - - File f = new File(file); - f.getParentFile().mkdirs(); - - try (FileOutputStream fos = new FileOutputStream(f); - BufferedOutputStream bos = new BufferedOutputStream(fos);) - { - LOGGER.info("Writing to output stream"); - saveToStream(bos, component, imageFormat, 100.0f); - } - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/SimpleTemplateEngine.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/SimpleTemplateEngine.java deleted file mode 100644 index 116c062..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/SimpleTemplateEngine.java +++ /dev/null @@ -1,54 +0,0 @@ -package usace.rowcps.headless.calculator.status; - -import java.util.HashMap; -import java.util.logging.Logger; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -/** - * Very simple templating system which replaces %keyword% with supplied values. - * Supported patterns look like: "J:\\temp\\headless\\%office_id%_%basin_id%_%location_id%_%chart_template_id%_%date%.png" - * @author ryan - */ -public class SimpleTemplateEngine { - private static final Logger logger = Logger.getLogger(SimpleTemplateEngine.class.getName()); - - protected HashMap replacements = new HashMap<>(); - public SimpleTemplateEngine() { - } - - static Pattern pattern = Pattern.compile("%\\w+%"); // This defines the %word% pattern we will look for. - - public void addPattern( String pattern, String value){ - if(pattern.contains("%")){ - logger.warning("Supplied pattern contained '%' character, this is unlikely to work correctly."); - } - replacements.put("%" + pattern + "%", value); - } - - public String makeReplacements(String text ){ - return makeReplacements(text, replacements); - } - - public static String makeReplacements(String text, HashMap replacements) { - Matcher matcher = pattern.matcher(text); - - StringBuffer buffer = new StringBuffer(); - - while (matcher.find()) { - String found = matcher.group(); - String replacement = replacements.get(found); - if (replacement != null) { - matcher.appendReplacement(buffer, ""); - buffer.append(replacement); - } else { - logger.info("Unrecognized replacement pattern:" + found + ". " - + " Recognized replacement patterns are:" + replacements.keySet()); - } - } - matcher.appendTail(buffer); - - return buffer.toString(); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/StatusCalcFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/StatusCalcFactory.java deleted file mode 100644 index 3865b69..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/calculator/status/StatusCalcFactory.java +++ /dev/null @@ -1,41 +0,0 @@ -package usace.rowcps.headless.calculator.status; - -import rma.services.annotations.ServiceProvider; -import usace.rowcps.headless.ScriptableCalcFactory; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author ryan - */ -@ServiceProvider(service = ScriptableCalcFactory.class) -public class StatusCalcFactory implements ScriptableCalcFactory -{ - - @Override - public String getName() - { - return "Status"; - } - - @Override - public String getDescription() - { - return "Generates Status Graphic images"; - } - - @Override - public String getUsage() - { - return ""; - } - - @Override - public ScriptableCalc build(RegiDomain regiDomain, ManagerId managerid) - { - return new ScriptableStatusGraphicImpl(regiDomain, managerid); - } - -} \ No newline at end of file diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ExportSigStagesCalcFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ExportSigStagesCalcFactory.java deleted file mode 100644 index a7b8444..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ExportSigStagesCalcFactory.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.exportdb; - -import usace.rowcps.headless.sigstages.importdb.*; -import usace.rowcps.headless.sigstages.retrieve.*; -import rma.services.annotations.ServiceProvider; -import usace.rowcps.headless.ScriptableCalcFactory; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author stephen - */ -@ServiceProvider(service = ScriptableCalcFactory.class) -public class ExportSigStagesCalcFactory implements ScriptableCalcFactory -{ - public ExportSigStagesCalcFactory() - { - } - - @Override - public String getName() - { - return "Export Sig States"; - } - - @Override - public String getDescription() - { - return "Reads the database and writes a text file that is used to retrieve NWS Gage info"; - } - - @Override - public String getUsage() - { - return ""; - } - - @Override - public ScriptableCalc build(RegiDomain regiDomain, ManagerId managerid) - { - return new ScriptableExportSigStagesImpl(regiDomain, managerid); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigStagesImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigStagesImpl.java deleted file mode 100644 index 1596d41..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigStagesImpl.java +++ /dev/null @@ -1,116 +0,0 @@ -/* -* To change this license header, choose License Headers in Project Properties. -* To change this template file, choose Tools | Templates -* and open the template in the editor. -*/ -package usace.rowcps.headless.sigstages.exportdb; - -import hec.data.location.AssignedLocation; -import hec.data.location.LocationGroup; -import hec.data.location.LocationGroupRef; -import hec.data.location.LocationTemplate; -import hec.data.meta.Catalog; -import hec.data.meta.LocationCatalogQuery; -import hec.db.DbConnectionException; -import hec.db.DbIoException; -import java.io.BufferedWriter; -import java.io.FileWriter; -import java.io.IOException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; -import java.util.logging.Level; -import java.util.logging.Logger; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.AgencyAlias; -import usace.rowcps.regi.model.AtLocationGroupManager; -import usace.rowcps.regi.model.AtLocationManager; -import usace.rowcps.regi.model.CacheUsage; -import usace.rowcps.regi.model.RegiDomain; -import usace.rowcps.regi.model.ManagerId; - -/** - * - * @author stephen - */ -public class ScriptableExportSigStagesImpl implements ScriptableExportSigstages, ScriptableCalc -{ - private RegiDomain _regiDomain; - private ManagerId _managerId; - private String _office; - - public static final String DELIMETER = System.getProperty("sigstages.delim", ";"); - public static final String CSVDELIMETER = System.getProperty("sigstages.csv.delim", "\n"); - public static final String CSVSEPARATOR = System.getProperty("sigstages.csv.separator", ","); - - public ScriptableExportSigStagesImpl(RegiDomain regiDomain, ManagerId managerId) - { - _regiDomain = regiDomain; - _managerId = managerId; - _office = "SWF"; - } - - @Override - public boolean exportSigStages(String file) - { - Path toPath = Paths.get(file); - - AtLocationManager atLocManager = _regiDomain.getAtLocationManager(_managerId); - - try (BufferedWriter writer = new BufferedWriter(new FileWriter(toPath.toFile()))) - { - Map usedIds = new HashMap<>(); - AtLocationGroupManager lgm = _regiDomain.getAtLocationGroupManager(_managerId); - LocationGroupRef lgr = AgencyAlias.Agency.NWS_HANDBOOK_5_ID.getLocationGroupRef(_regiDomain); - LocationGroup usgsAliases = lgm.retrieveLocationGroup(lgr, CacheUsage.NORMAL); - for(AssignedLocation al : usgsAliases.getAssignedLocationsSorted()) - { - String aliasId = al.getAliasId(); - LocationTemplate location = al.getLocRef(); - usedIds.put(location, aliasId); - } - - Catalog catalog = atLocManager.retrieveLocationCatalog(CacheUsage.NORMAL); - for(int i=0; i < catalog.size(); i++) - { - List rowList = catalog.getRow(i); - LocationTemplate locationTemplate = LocationCatalogQuery.convertToLocationTemplate(rowList); - if(locationTemplate != null) - { - String locationId = locationTemplate.getLocationId(); - String aliasId = usedIds.get(locationTemplate); - if(Objects.equals(aliasId, locationId) || aliasId == null || "".equals(aliasId)) - { - writer.write(locationId); - } - else - { - writer.write(locationId + DELIMETER + aliasId); - } - writer.write("\n"); - } - } - } - catch (DbConnectionException|DbIoException|IOException ex) - { - Logger.getLogger(ScriptableExportSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - return false; - } - return true; - } - - @Override - public void setOffice(String office) - { - _office = office; - } - - @Override - public String getOffice() - { - return _office; - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigstages.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigstages.java deleted file mode 100644 index dec7ac5..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/exportdb/ScriptableExportSigstages.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.exportdb; - -import usace.rowcps.headless.sigstages.importdb.*; -import usace.rowcps.headless.sigstages.retrieve.*; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Sigstage; - -/** - * - * @author stephen - */ -public interface ScriptableExportSigstages -{ - public boolean exportSigStages(String toFile); - public void setOffice(String office); - public String getOffice(); -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ImportSigStagesCalcFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ImportSigStagesCalcFactory.java deleted file mode 100644 index 72037de..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ImportSigStagesCalcFactory.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.importdb; - -import usace.rowcps.headless.sigstages.retrieve.*; -import rma.services.annotations.ServiceProvider; -import usace.rowcps.headless.ScriptableCalcFactory; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author stephen - */ -@ServiceProvider(service = ScriptableCalcFactory.class) -public class ImportSigStagesCalcFactory implements ScriptableCalcFactory -{ - public ImportSigStagesCalcFactory() - { - } - - @Override - public String getName() - { - return "Import Sig States"; - } - - @Override - public String getDescription() - { - return "Reads a CSV File and then import that data into the database."; - } - - @Override - public String getUsage() - { - return ""; - } - - @Override - public ScriptableCalc build(RegiDomain regiDomain, ManagerId managerid) - { - return new ScriptableImportSigStagesImpl(regiDomain, managerid); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigStagesImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigStagesImpl.java deleted file mode 100644 index 14ae0d6..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigStagesImpl.java +++ /dev/null @@ -1,95 +0,0 @@ -/* -* To change this license header, choose License Headers in Project Properties. -* To change this template file, choose Tools | Templates -* and open the template in the editor. -*/ -package usace.rowcps.headless.sigstages.importdb; - -import hec.data.level.ILocationLevel; -import hec.db.DbConnectionException; -import hec.db.DbIoException; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.sql.Connection; -import java.sql.SQLException; -import java.util.Date; -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.level.importer.CSVLocationLevelImportUtil; -import usace.rowcps.regi.model.AtLocationLevelManager; -import usace.rowcps.regi.model.RegiDomain; -import usace.rowcps.regi.model.ManagerId; - -/** - * - * @author stephen - */ -public class ScriptableImportSigStagesImpl implements ScriptableImportSigstages, ScriptableCalc -{ - private RegiDomain _regiDomain; - private ManagerId _managerId; - - public static final String DELIMETER = System.getProperty("sigstages.delim", ";"); - public static final String CSVDELIMETER = System.getProperty("sigstages.csv.delim", "\n"); - public static final String CSVSEPARATOR = System.getProperty("sigstages.csv.separator", ","); - - public ScriptableImportSigStagesImpl(RegiDomain regiDomain, ManagerId managerId) - { - _regiDomain = regiDomain; - _managerId = managerId; - } - - @Override - public boolean importSigStages(String file, Date effectiveDate) - { - boolean retval = true; - AtLocationLevelManager atLocLevelMgr = _regiDomain.getAtLocationLevelManager(_managerId); - Connection c = null; - try { - Path p = Paths.get(file); - c = atLocLevelMgr.getPooledConnection(); - CSVLocationLevelImportUtil importUtil = new CSVLocationLevelImportUtil(); - importUtil.setPath(p); - importUtil.readFile(true); - List locationLevels = importUtil.getLocationLevelList(); - for(int locationLevelIndex = 0; locationLevelIndex < locationLevels.size(); locationLevelIndex++) - { - ILocationLevel level = locationLevels.get(locationLevelIndex); - try { - level.setDate(effectiveDate); - atLocLevelMgr.addLocationLevel(level); - } catch (DbConnectionException | DbIoException ex) { - Logger.getLogger(ScriptableImportSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - retval = false; - break; - } - } - - if(retval) - { - try { - atLocLevelMgr.commitData(); - } catch (DbConnectionException | DbIoException ex) { - Logger.getLogger(ScriptableImportSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - retval = false; - } - } - } catch (DbConnectionException ex) { - Logger.getLogger(ScriptableImportSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - } - finally - { - try - { - if(c != null && !c.isClosed()) c.close(); - } - catch (SQLException ex) - { - Logger.getLogger(ScriptableImportSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - } - } - return retval; - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigstages.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigstages.java deleted file mode 100644 index 0883a58..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/importdb/ScriptableImportSigstages.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.importdb; - -import java.util.Date; - -/** - * - * @author stephen - */ -public interface ScriptableImportSigstages -{ - public boolean importSigStages(String file, Date effectiveDate); -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesCalcFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesCalcFactory.java deleted file mode 100644 index 063dd7e..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesCalcFactory.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.retrieve; - -import rma.services.annotations.ServiceProvider; -import usace.rowcps.headless.ScriptableCalcFactory; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author stephen - */ -@ServiceProvider(service = ScriptableCalcFactory.class) -public class RetrieveSigStagesCalcFactory implements ScriptableCalcFactory -{ - public RetrieveSigStagesCalcFactory() - { - } - - @Override - public String getName() - { - return "Retrieve Sig States"; - } - - @Override - public String getDescription() - { - return "Reads a newline delimited file containing NWS Names, then writes the sigstages to a CSV"; - } - - @Override - public String getUsage() - { - return ""; - } - - @Override - public ScriptableCalc build(RegiDomain regiDomain, ManagerId managerid) - { - return new RetrieveSigStagesImpl(regiDomain, managerid); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesImpl.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesImpl.java deleted file mode 100644 index 6a609e5..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigStagesImpl.java +++ /dev/null @@ -1,488 +0,0 @@ -/* -* To change this license header, choose License Headers in Project Properties. -* To change this template file, choose Tools | Templates -* and open the template in the editor. -*/ -package usace.rowcps.headless.sigstages.retrieve; - -import java.io.BufferedReader; -import java.io.BufferedWriter; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.FileWriter; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.text.DateFormat; -import java.text.ParseException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; -import java.util.logging.Level; -import java.util.logging.Logger; -import java.util.regex.Pattern; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.Unmarshaller; -import usace.metrics.services.Metrics; -import usace.metrics.services.Timer; -import usace.rowcps.headless.interfaces.ScriptableCalc; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Action; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Bankfull; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Flood; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Low; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Major; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Moderate; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Sigstage; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Sigstages; -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Site; -import usace.rowcps.metrics.RegiMetricsService; -import usace.rowcps.regi.model.ManagerId; -import usace.rowcps.regi.model.RegiDomain; - -/** - * - * @author stephen - */ -public class RetrieveSigStagesImpl implements RetrieveSigstages, ScriptableCalc -{ - private RegiDomain _regiDomain; - private ManagerId _managerId; - - private JAXBContext _jaxbContext = null; - - public final static String DOWNLOADURL = System.getProperty("sigstages.downloadurl", "http://water.weather.gov/ahps2/hydrograph_to_xml.php?gage=GAGENAME&output=xml"); - public static final String DELIMETER = System.getProperty("sigstages.delim", ";"); - public static final String CSVDELIMETER = System.getProperty("sigstages.csv.delim", "\n"); - public static final String CSVSEPARATOR = System.getProperty("sigstages.csv.separator", ","); - public static int THREADCOUNT = 2; - - private static final DateFormat DATE_FORMAT = new SimpleDateFormat("ddMMMyyyy HHmm"); - private static final DateFormat ISO_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm"); - - private static final int SHEF_MISSING_VALUE = -9999; - - private String _parameter; - private String _parameterType; - private String _duration; - private Map _specifiedLevelOverride; - private String _office; - private String _csvHeader; - - protected RetrieveSigStagesImpl() - { - super(); - _parameter = "Stage"; - _parameterType = "Inst"; - _duration = "0"; - _specifiedLevelOverride = new HashMap<>(); - _office = "SWF"; - _csvHeader = "Office,Location Level,Effective Date,Constant Level,Unit,Seasonal Value,Interpolate,Calendar Interval,Time Interval,Origin Date,Calendar Offset,TSID\n"; - String threadCount = System.getProperty("sigstages.threadcount", Runtime.getRuntime().availableProcessors()+"").trim(); - if(threadCount.matches("^[\\d]+$")) - { - THREADCOUNT = Integer.parseInt(threadCount); - } - } - - public void setCSVHeader(String csvHeader) - { - //TODO: Be sure this actually is a valid header - _csvHeader = csvHeader; - } - - public String getCSVHeader() - { - return _csvHeader; - } - - public RetrieveSigStagesImpl(RegiDomain regiDomain, ManagerId managerId) - { - this(); - _regiDomain = regiDomain; - _managerId = managerId; - } - - @Override - public void retrieveSigstages(String sourceFile, String outputFile, int milliDelay) - { - Path inputPath = Paths.get(sourceFile); - Path outputPath = Paths.get(outputFile); - retrieveSigstages(inputPath, outputPath, milliDelay); - } - - public void retrieveSigstages(Path source, Path outputPath, int milliDelay) - { - SigstageLocation[] locations; - try - { - locations = readLocationFile(source); - fetchSitesThreaded(milliDelay, locations); - locationsToCSV(outputPath, locations); - } - catch (IOException ex) - { - Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - } - } - - public void locationsToCSV(Path file, SigstageLocation... locations) - { - Metrics metrics = RegiMetricsService.createMetrics("locationsToCSV"); - try(Timer.Context context = metrics.createTimer().start()) - { - - StringBuilder csvBuilder = new StringBuilder(getCSVHeader()); - for(int locationIndex = 0; locationIndex < locations.length; locationIndex++) - { - if(locations[locationIndex] == null) - { - continue; - } - if(locations[locationIndex].getSite() == null) - { - continue; - } - Site site = locations[locationIndex].getSite(); - - if(site.getSigstages() == null) - { - continue; - } - Sigstages sigstages = site.getSigstages(); - - List allStages = new ArrayList<>(); - - if(sigstages.getAction() == null) - { - continue; - } - Action action = sigstages.getAction(); - allStages.add(action); - - Bankfull bankfull = sigstages.getBankfull(); - allStages.add(bankfull); - - Flood flood = sigstages.getFlood(); - allStages.add(flood); - - Low low = sigstages.getLow(); - allStages.add(low); - - Major major = sigstages.getMajor(); - allStages.add(major); - - //Record record = sigstages.getRecord(); - //allStages.add(record); - - Moderate moderate = sigstages.getModerate(); - allStages.add(moderate); - - for(int stageIndex = 0; stageIndex < allStages.size(); stageIndex++) - { - Sigstage stage = allStages.get(stageIndex); - if(stage.getValue() == 0 || stage.getValue() == SHEF_MISSING_VALUE) - { - continue; - } - String dateTime = ""; - if(site.getGenerationtime() != null && !site.getGenerationtime().isEmpty()) - { - Date generationDateTime = null; - - try { - generationDateTime = ISO_FORMAT.parse(site.getGenerationtime()); - } - catch (ParseException ex) { - Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - } - - dateTime = DATE_FORMAT.format(generationDateTime); - } - csvBuilder.append(_office); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(stage.getType().generateID(locations[locationIndex].getOriginal(), _parameter, _parameterType, _duration, getSpecifiedLevelOverride(stage.getType()))); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(dateTime); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(stage.getValue()); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(stage.getUnits()); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVSEPARATOR); - csvBuilder.append(CSVDELIMETER); - } - } - - try (BufferedWriter writer = new BufferedWriter(new FileWriter(file.toFile()))) - { - writer.write(csvBuilder.toString()); - } - catch (IOException ex) - { - Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - } - } - } - -// public void fetchSites(Location... locationNames) -// { -// for(int locationNamesIndex = 0; locationNamesIndex < locationNames.length; locationNamesIndex++) -// { -// String fullURL = DOWNLOADURL.replace("GAGENAME", locationNames[locationNamesIndex].getNWS()); -// try -// { -// Location loc = locationNames[locationNamesIndex]; -// Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.FINE, null, "Retrieving " + loc); -// loc.setSite(fetchSite(fullURL)); -// Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.FINE, null, "Retrieved " + loc); -// } catch (Exception ex) -// { -// Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); -// } -// } -// } - - public void fetchSitesThreaded(int milliDelay, SigstageLocation... locationNames) - { - Metrics metrics = RegiMetricsService.createMetrics("fetchSitesThreaded"); - try(Timer.Context context = metrics.createTimer().start()) - { - final CountDownLatch cdl = new CountDownLatch(1); - BlockingQueue threadPoolQueue = new LinkedBlockingQueue<>(); - ThreadPoolExecutor threadPool = new ThreadPoolExecutor(THREADCOUNT / 2, THREADCOUNT, 1, TimeUnit.SECONDS, threadPoolQueue){ - @Override - protected void terminated() - { - cdl.countDown(); - } - }; - - for (final SigstageLocation l : locationNames) { - - threadPool.execute(new Runnable(){ - - @Override - public void run() - { - Metrics metrics = RegiMetricsService.createMetrics("fetchSitesThreadedRunnable"); - try(Timer.Context timerContext = metrics.createTimer().start()) - { - String fullURL = DOWNLOADURL.replace("GAGENAME", l.getNWS()); - try { - Site locationSite = fetchSite(fullURL); - l.setSite(locationSite); - - // report the number of locations at this site - int sameSiteLocations = countNumStages(locationSite); - String logString = "retrieved " + sameSiteLocations + " level" - + (sameSiteLocations==1? " ":"s ") + "for " - + l.getNWS(); - Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.INFO, logString); - } - catch (Exception ex) - { - Logger logger = Logger.getLogger(RetrieveSigStagesImpl.class.getName()); - logger.isLoggable(Level.SEVERE); - if(logger.isLoggable(Level.FINE)) - { - logger.log(Level.SEVERE, "error retrieving at site " + l.getNWS(), ex); - } - else - { - String logMessage = "error retrieving at site " + l.getNWS() + " " + ex.getMessage(); - logger.log(Level.SEVERE, logMessage); - } - } - } - } - }); - - try - { - cdl.await(milliDelay, TimeUnit.MILLISECONDS); - } - catch (InterruptedException ex) - { - Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.SEVERE, "timeout while retrieving site " + l.getNWS(), ex); - } - } - threadPool.shutdown(); - try - { - cdl.await(); - } - catch (InterruptedException ex) - { - Logger.getLogger(RetrieveSigStagesImpl.class.getName()).log(Level.SEVERE, null, ex); - } - } - } - - public Site fetchSite(String fullURL) throws Exception - { - Metrics metrics = RegiMetricsService.createMetrics("fetchSite"); - try(Timer.Context context = metrics.createTimer().start()) - { - if(_jaxbContext == null) - { - _jaxbContext = JAXBContext.newInstance("usace.rowcps.headless.sigstages.retrieve.xmlmodel"); - } - Unmarshaller unmarshaller = _jaxbContext.createUnmarshaller(); - URL url = new URL(fullURL); - InputStream input = url.openStream(); - Site site = ((Site)unmarshaller.unmarshal(input)); - return site; - } - } - - private static final Pattern VALIDNWS = Pattern.compile("^[A-Za-z]{4}[\\d]$"); - - public SigstageLocation[] readLocationFile(Path source) throws FileNotFoundException, IOException - { - Metrics metrics = RegiMetricsService.createMetrics("readLocationFile"); - try(Timer.Context context = metrics.createTimer().start()) - { - List locations = new ArrayList<>(); - - try (BufferedReader reader = new BufferedReader(new FileReader(source.toFile()))) { - String line; - while((line = reader.readLine()) != null) - { - line = line.trim(); - String[] lineArray = line.split(DELIMETER); - if(lineArray.length == 0) - { - continue; - } - String nws = (lineArray.length > 1) ? lineArray[1] : lineArray[0]; - if(VALIDNWS.matcher(nws).matches()) - { - String original = lineArray[0]; - SigstageLocation location = new SigstageLocation(original, nws); - locations.add(location); - } - } - } - - SigstageLocation[] locationsArray = new SigstageLocation[locations.size()]; - locationsArray = locations.toArray(locationsArray); - return locationsArray; - } - } - - // count all valid locations at a site - private int countNumStages(Site site) - { - int numStages = 0; - - if(site == null) - return numStages; - - Sigstages stages = site.getSigstages(); - - if(stages == null) - return numStages; - - if(stages.getAction() != null && stages.getAction().getValue() != 0 && stages.getAction().getValue() != SHEF_MISSING_VALUE) - numStages++; - else - return numStages; - - if(stages.getBankfull() != null && stages.getBankfull().getValue() != 0 && stages.getBankfull().getValue() != SHEF_MISSING_VALUE) - numStages++; - - if(stages.getFlood() != null && stages.getFlood().getValue() != 0 && stages.getFlood().getValue() != SHEF_MISSING_VALUE) - numStages++; - - if(stages.getLow() != null && stages.getLow().getValue() != 0 && stages.getLow().getValue() != SHEF_MISSING_VALUE) - numStages++; - - if(stages.getMajor() != null && stages.getMajor().getValue() != 0 && stages.getMajor().getValue() != SHEF_MISSING_VALUE) - numStages++; - - if(stages.getModerate() != null && stages.getModerate().getValue() != 0 && stages.getModerate().getValue() != SHEF_MISSING_VALUE) - numStages++; - - return numStages; - } - - @Override - public void setParameter(String parameter) - { - _parameter = parameter; - } - - @Override - public String getParameter() - { - return _parameter; - } - - @Override - public void setParameterType(String parameterType) - { - _parameterType = parameterType; - } - - @Override - public String getParameterType() - { - return _parameterType; - } - - @Override - public void setDuration(String duration) - { - _duration = duration; - } - - @Override - public String getDuration() - { - return _duration; - } - - @Override - public void setSpecifiedLevelOverride(Sigstage.Type type, String overrideText) - { - _specifiedLevelOverride.put(type, overrideText); - } - - @Override - public String getSpecifiedLevelOverride(Sigstage.Type type) - { - String specifiedLevel = _specifiedLevelOverride.get(type); - if(specifiedLevel == null) - { - specifiedLevel = type.toString(); - } - return specifiedLevel; - } - - @Override - public void setOffice(String office) - { - _office = office; - } - - @Override - public String getOffice() - { - return _office; - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigstages.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigstages.java deleted file mode 100644 index 1a518a6..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/RetrieveSigstages.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.retrieve; - -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Sigstage; - -/** - * - * @author stephen - */ -public interface RetrieveSigstages -{ - public void retrieveSigstages(String sourceFile, String outputFile, int milliDelay); - public void setParameter(String parameter); - public String getParameter(); - public void setParameterType(String parameterType); - public String getParameterType(); - public void setDuration(String duration); - public String getDuration(); - public void setSpecifiedLevelOverride(Sigstage.Type type, String overrideText); - public String getSpecifiedLevelOverride(Sigstage.Type type); - public void setOffice(String office); - public String getOffice(); -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/SigstageLocation.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/SigstageLocation.java deleted file mode 100644 index 98fbeb7..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/SigstageLocation.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.retrieve; - -import usace.rowcps.headless.sigstages.retrieve.xmlmodel.Site; - -/** - * - * @author stephen - */ -public class SigstageLocation -{ - private String _originalLocation; - private String _nwsLocation; - private Site _site; - - public SigstageLocation() - { - super(); - _site = null; - _originalLocation = ""; - _nwsLocation = ""; - } - - public SigstageLocation(String orig, String nws) - { - this(); - _originalLocation = orig; - _nwsLocation = nws; - } - - public String getOriginal() - { - return _originalLocation; - } - - public String getNWS() - { - return _nwsLocation; - } - - public void setOriginal(String original) - { - _originalLocation = original; - } - - public void setNWS(String nws) - { - _nwsLocation = nws; - } - - public Site getSite() - { - return _site; - } - - public void setSite(Site site) - { - _site = site; - } - - @Override - public String toString() - { - return getOriginal() + ";" + getNWS() + " " + getSite().getName(); - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Action.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Action.java deleted file mode 100644 index 06c23fc..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Action.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "action") -public class Action implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType(){ - return Type.ACTION; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/AltRating.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/AltRating.java deleted file mode 100644 index 5e4b4c2..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/AltRating.java +++ /dev/null @@ -1,111 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}datum" maxOccurs="unbounded"/>
- *       </sequence>
- *       <attribute name="dignity" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "datum" -}) -@XmlRootElement(name = "alt_rating") -public class AltRating { - - @XmlElement(required = true) - protected List datum; - @XmlAttribute(name = "dignity", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String dignity; - - /** - * Gets the value of the datum property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the datum property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getDatum().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Datum } - * - * - */ - public List getDatum() { - if (datum == null) { - datum = new ArrayList(); - } - return this.datum; - } - - /** - * Gets the value of the dignity property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDignity() { - return dignity; - } - - /** - * Sets the value of the dignity property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDignity(String value) { - this.dignity = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Bankfull.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Bankfull.java deleted file mode 100644 index 34142cf..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Bankfull.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "bankfull") -public class Bankfull implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType() { - return Type.BANKFULL; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Datum.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Datum.java deleted file mode 100644 index ad24775..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Datum.java +++ /dev/null @@ -1,268 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence minOccurs="0">
- *         <element ref="{}valid"/>
- *         <element ref="{}primary"/>
- *         <element ref="{}secondary"/>
- *         <element ref="{}pedts"/>
- *       </sequence>
- *       <attribute name="flow" type="{http://www.w3.org/2001/XMLSchema}float" />
- *       <attribute name="flowUnits" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="stage" type="{http://www.w3.org/2001/XMLSchema}float" />
- *       <attribute name="stageUnits" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "valid", - "primary", - "secondary", - "pedts" -}) -@XmlRootElement(name = "datum") -public class Datum { - - protected Valid valid; - protected Primary primary; - protected Secondary secondary; - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String pedts; - @XmlAttribute(name = "flow") - protected Float flow; - @XmlAttribute(name = "flowUnits") - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String flowUnits; - @XmlAttribute(name = "stage") - protected Float stage; - @XmlAttribute(name = "stageUnits") - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String stageUnits; - - /** - * Gets the value of the valid property. - * - * @return - * possible object is - * {@link Valid } - * - */ - public Valid getValid() { - return valid; - } - - /** - * Sets the value of the valid property. - * - * @param value - * allowed object is - * {@link Valid } - * - */ - public void setValid(Valid value) { - this.valid = value; - } - - /** - * Gets the value of the primary property. - * - * @return - * possible object is - * {@link Primary } - * - */ - public Primary getPrimary() { - return primary; - } - - /** - * Sets the value of the primary property. - * - * @param value - * allowed object is - * {@link Primary } - * - */ - public void setPrimary(Primary value) { - this.primary = value; - } - - /** - * Gets the value of the secondary property. - * - * @return - * possible object is - * {@link Secondary } - * - */ - public Secondary getSecondary() { - return secondary; - } - - /** - * Sets the value of the secondary property. - * - * @param value - * allowed object is - * {@link Secondary } - * - */ - public void setSecondary(Secondary value) { - this.secondary = value; - } - - /** - * Gets the value of the pedts property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getPedts() { - return pedts; - } - - /** - * Sets the value of the pedts property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setPedts(String value) { - this.pedts = value; - } - - /** - * Gets the value of the flow property. - * - * @return - * possible object is - * {@link Float } - * - */ - public Float getFlow() { - return flow; - } - - /** - * Sets the value of the flow property. - * - * @param value - * allowed object is - * {@link Float } - * - */ - public void setFlow(Float value) { - this.flow = value; - } - - /** - * Gets the value of the flowUnits property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getFlowUnits() { - return flowUnits; - } - - /** - * Sets the value of the flowUnits property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setFlowUnits(String value) { - this.flowUnits = value; - } - - /** - * Gets the value of the stage property. - * - * @return - * possible object is - * {@link Float } - * - */ - public Float getStage() { - return stage; - } - - /** - * Sets the value of the stage property. - * - * @param value - * allowed object is - * {@link Float } - * - */ - public void setStage(Float value) { - this.stage = value; - } - - /** - * Gets the value of the stageUnits property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStageUnits() { - return stageUnits; - } - - /** - * Sets the value of the stageUnits property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStageUnits(String value) { - this.stageUnits = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Disclaimers.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Disclaimers.java deleted file mode 100644 index d795985..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Disclaimers.java +++ /dev/null @@ -1,152 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}AHPSXMLversion"/>
- *         <element ref="{}status"/>
- *         <element ref="{}quality"/>
- *         <element ref="{}standing"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "ahpsxmLversion", - "status", - "quality", - "standing" -}) -@XmlRootElement(name = "disclaimers") -public class Disclaimers { - - @XmlElement(name = "AHPSXMLversion") - protected float ahpsxmLversion; - @XmlElement(required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String status; - @XmlElement(required = true) - protected Quality quality; - @XmlElement(required = true) - protected Standing standing; - - /** - * Gets the value of the ahpsxmLversion property. - * - */ - public float getAHPSXMLversion() { - return ahpsxmLversion; - } - - /** - * Sets the value of the ahpsxmLversion property. - * - */ - public void setAHPSXMLversion(float value) { - this.ahpsxmLversion = value; - } - - /** - * Gets the value of the status property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getStatus() { - return status; - } - - /** - * Sets the value of the status property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setStatus(String value) { - this.status = value; - } - - /** - * Gets the value of the quality property. - * - * @return - * possible object is - * {@link Quality } - * - */ - public Quality getQuality() { - return quality; - } - - /** - * Sets the value of the quality property. - * - * @param value - * allowed object is - * {@link Quality } - * - */ - public void setQuality(Quality value) { - this.quality = value; - } - - /** - * Gets the value of the standing property. - * - * @return - * possible object is - * {@link Standing } - * - */ - public Standing getStanding() { - return standing; - } - - /** - * Sets the value of the standing property. - * - * @param value - * allowed object is - * {@link Standing } - * - */ - public void setStanding(Standing value) { - this.standing = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Flood.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Flood.java deleted file mode 100644 index da6f6fa..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Flood.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "flood") -public class Flood implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType() { - return Type.FLOOD; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Forecast.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Forecast.java deleted file mode 100644 index 1690728..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Forecast.java +++ /dev/null @@ -1,140 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import javax.xml.datatype.XMLGregorianCalendar; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}datum" maxOccurs="unbounded"/>
- *       </sequence>
- *       <attribute name="issued" use="required" type="{http://www.w3.org/2001/XMLSchema}dateTime" />
- *       <attribute name="timezone" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "datum" -}) -@XmlRootElement(name = "forecast") -public class Forecast { - - @XmlElement(required = true) - protected List datum; - @XmlAttribute(name = "issued", required = true) - @XmlSchemaType(name = "dateTime") - protected XMLGregorianCalendar issued; - @XmlAttribute(name = "timezone", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String timezone; - - /** - * Gets the value of the datum property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the datum property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getDatum().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Datum } - * - * - */ - public List getDatum() { - if (datum == null) { - datum = new ArrayList(); - } - return this.datum; - } - - /** - * Gets the value of the issued property. - * - * @return - * possible object is - * {@link XMLGregorianCalendar } - * - */ - public XMLGregorianCalendar getIssued() { - return issued; - } - - /** - * Sets the value of the issued property. - * - * @param value - * allowed object is - * {@link XMLGregorianCalendar } - * - */ - public void setIssued(XMLGregorianCalendar value) { - this.issued = value; - } - - /** - * Gets the value of the timezone property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTimezone() { - return timezone; - } - - /** - * Sets the value of the timezone property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTimezone(String value) { - this.timezone = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Low.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Low.java deleted file mode 100644 index 09ca9ff..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Low.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "low") -public class Low implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType() { - return Type.LOW; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Major.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Major.java deleted file mode 100644 index d5deb79..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Major.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "major") -public class Major implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType() { - return Type.MAJOR; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Moderate.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Moderate.java deleted file mode 100644 index 4c59bfe..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Moderate.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "moderate") -public class Moderate implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType() { - return Type.MODERATE; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/ObjectFactory.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/ObjectFactory.java deleted file mode 100644 index 0974e70..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/ObjectFactory.java +++ /dev/null @@ -1,252 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.JAXBElement; -import javax.xml.bind.annotation.XmlElementDecl; -import javax.xml.bind.annotation.XmlRegistry; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import javax.xml.namespace.QName; - - -/** - * This object contains factory methods for each - * Java content interface and Java element interface - * generated in the usace.rowcps.headless.sigstages.xmlmodel package. - *

An ObjectFactory allows you to programatically - * construct new instances of the Java representation - * for XML content. The Java representation of XML - * content can consist of schema derived interfaces - * and classes representing the binding of schema - * type definitions, element declarations and model - * groups. Factory methods for each of these are - * provided in this class. - * - */ -@XmlRegistry -public class ObjectFactory { - - private final static QName _Pedts_QNAME = new QName("", "pedts"); - private final static QName _AHPSXMLversion_QNAME = new QName("", "AHPSXMLversion"); - private final static QName _Status_QNAME = new QName("", "status"); - - /** - * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: usace.rowcps.headless.sigstages.xmlmodel - * - */ - public ObjectFactory() { - } - - /** - * Create an instance of {@link Datum } - * - */ - public Datum createDatum() { - return new Datum(); - } - - /** - * Create an instance of {@link Valid } - * - */ - public Valid createValid() { - return new Valid(); - } - - /** - * Create an instance of {@link Primary } - * - */ - public Primary createPrimary() { - return new Primary(); - } - - /** - * Create an instance of {@link Secondary } - * - */ - public Secondary createSecondary() { - return new Secondary(); - } - - /** - * Create an instance of {@link Rating } - * - */ - public Rating createRating() { - return new Rating(); - } - - /** - * Create an instance of {@link Sigstages } - * - */ - public Sigstages createSigstages() { - return new Sigstages(); - } - - /** - * Create an instance of {@link Low } - * - */ - public Low createLow() { - return new Low(); - } - - /** - * Create an instance of {@link Action } - * - */ - public Action createAction() { - return new Action(); - } - - /** - * Create an instance of {@link Bankfull } - * - */ - public Bankfull createBankfull() { - return new Bankfull(); - } - - /** - * Create an instance of {@link Flood } - * - */ - public Flood createFlood() { - return new Flood(); - } - - /** - * Create an instance of {@link Moderate } - * - */ - public Moderate createModerate() { - return new Moderate(); - } - - /** - * Create an instance of {@link Major } - * - */ - public Major createMajor() { - return new Major(); - } - - /** - * Create an instance of {@link Record } - * - */ - public Record createRecord() { - return new Record(); - } - - /** - * Create an instance of {@link Observed } - * - */ - public Observed createObserved() { - return new Observed(); - } - - /** - * Create an instance of {@link Disclaimers } - * - */ - public Disclaimers createDisclaimers() { - return new Disclaimers(); - } - - /** - * Create an instance of {@link Quality } - * - */ - public Quality createQuality() { - return new Quality(); - } - - /** - * Create an instance of {@link Standing } - * - */ - public Standing createStanding() { - return new Standing(); - } - - /** - * Create an instance of {@link Zerodatum } - * - */ - public Zerodatum createZerodatum() { - return new Zerodatum(); - } - - /** - * Create an instance of {@link Forecast } - * - */ - public Forecast createForecast() { - return new Forecast(); - } - - /** - * Create an instance of {@link Site } - * - */ - public Site createSite() { - return new Site(); - } - - /** - * Create an instance of {@link Sigflows } - * - */ - public Sigflows createSigflows() { - return new Sigflows(); - } - - /** - * Create an instance of {@link AltRating } - * - */ - public AltRating createAltRating() { - return new AltRating(); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "pedts") - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - public JAXBElement createPedts(String value) { - return new JAXBElement(_Pedts_QNAME, String.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link Float }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "AHPSXMLversion") - public JAXBElement createAHPSXMLversion(Float value) { - return new JAXBElement(_AHPSXMLversion_QNAME, Float.class, null, value); - } - - /** - * Create an instance of {@link JAXBElement }{@code <}{@link String }{@code >}} - * - */ - @XmlElementDecl(namespace = "", name = "status") - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - public JAXBElement createStatus(String value) { - return new JAXBElement(_Status_QNAME, String.class, null, value); - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Observed.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Observed.java deleted file mode 100644 index 3ce6f18..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Observed.java +++ /dev/null @@ -1,78 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}datum" maxOccurs="unbounded"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "datum" -}) -@XmlRootElement(name = "observed") -public class Observed { - - @XmlElement(required = true) - protected List datum; - - /** - * Gets the value of the datum property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the datum property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getDatum().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Datum } - * - * - */ - public List getDatum() { - if (datum == null) { - datum = new ArrayList(); - } - return this.datum; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Primary.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Primary.java deleted file mode 100644 index 4e6239c..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Primary.java +++ /dev/null @@ -1,122 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "primary") -public class Primary { - - @XmlValue - protected float value; - @XmlAttribute(name = "name", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String name; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Quality.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Quality.java deleted file mode 100644 index 90e3341..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Quality.java +++ /dev/null @@ -1,101 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="trace" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "content" -}) -@XmlRootElement(name = "quality") -public class Quality { - - @XmlValue - protected String content; - @XmlAttribute(name = "trace", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String trace; - - /** - * Gets the value of the content property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getContent() { - return content; - } - - /** - * Sets the value of the content property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setContent(String value) { - this.content = value; - } - - /** - * Gets the value of the trace property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTrace() { - return trace; - } - - /** - * Sets the value of the trace property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTrace(String value) { - this.trace = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Rating.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Rating.java deleted file mode 100644 index 0c5c09e..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Rating.java +++ /dev/null @@ -1,111 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import java.util.ArrayList; -import java.util.List; -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}datum" maxOccurs="unbounded"/>
- *       </sequence>
- *       <attribute name="dignity" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "datum" -}) -@XmlRootElement(name = "rating") -public class Rating { - - @XmlElement(required = true) - protected List datum; - @XmlAttribute(name = "dignity", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String dignity; - - /** - * Gets the value of the datum property. - * - *

- * This accessor method returns a reference to the live list, - * not a snapshot. Therefore any modification you make to the - * returned list will be present inside the JAXB object. - * This is why there is not a set method for the datum property. - * - *

- * For example, to add a new item, do as follows: - *

-     *    getDatum().add(newItem);
-     * 
- * - * - *

- * Objects of the following type(s) are allowed in the list - * {@link Datum } - * - * - */ - public List getDatum() { - if (datum == null) { - datum = new ArrayList(); - } - return this.datum; - } - - /** - * Gets the value of the dignity property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDignity() { - return dignity; - } - - /** - * Sets the value of the dignity property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDignity(String value) { - this.dignity = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Record.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Record.java deleted file mode 100644 index 2c0e70b..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Record.java +++ /dev/null @@ -1,98 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "record") -public class Record implements Sigstage{ - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - - @Override - public Type getType() { - return Type.RECORD; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Secondary.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Secondary.java deleted file mode 100644 index b49c329..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Secondary.java +++ /dev/null @@ -1,122 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "secondary") -public class Secondary { - - @XmlValue - protected float value; - @XmlAttribute(name = "name", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String name; - @XmlAttribute(name = "units", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigflows.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigflows.java deleted file mode 100644 index ef64c41..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigflows.java +++ /dev/null @@ -1,239 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}low"/>
- *         <element ref="{}action"/>
- *         <element ref="{}flood"/>
- *         <element ref="{}bankfull"/>
- *         <element ref="{}moderate"/>
- *         <element ref="{}major"/>
- *         <element ref="{}record"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "low", - "action", - "flood", - "bankfull", - "moderate", - "major", - "record" -}) -@XmlRootElement(name = "sigflows") -public class Sigflows { - - @XmlElement(required = true) - protected Low low; - @XmlElement(required = true) - protected Action action; - @XmlElement(required = true) - protected Flood flood; - @XmlElement(required = true) - protected Bankfull bankfull; - @XmlElement(required = true) - protected Moderate moderate; - @XmlElement(required = true) - protected Major major; - @XmlElement(required = true) - protected Record record; - - /** - * Gets the value of the low property. - * - * @return - * possible object is - * {@link Low } - * - */ - public Low getLow() { - return low; - } - - /** - * Sets the value of the low property. - * - * @param value - * allowed object is - * {@link Low } - * - */ - public void setLow(Low value) { - this.low = value; - } - - /** - * Gets the value of the action property. - * - * @return - * possible object is - * {@link Action } - * - */ - public Action getAction() { - return action; - } - - /** - * Sets the value of the action property. - * - * @param value - * allowed object is - * {@link Action } - * - */ - public void setAction(Action value) { - this.action = value; - } - - /** - * Gets the value of the flood property. - * - * @return - * possible object is - * {@link Flood } - * - */ - public Flood getFlood() { - return flood; - } - - /** - * Sets the value of the flood property. - * - * @param value - * allowed object is - * {@link Flood } - * - */ - public void setFlood(Flood value) { - this.flood = value; - } - - /** - * Gets the value of the bankfull property. - * - * @return - * possible object is - * {@link Bankfull } - * - */ - public Bankfull getBankfull() { - return bankfull; - } - - /** - * Sets the value of the bankfull property. - * - * @param value - * allowed object is - * {@link Bankfull } - * - */ - public void setBankfull(Bankfull value) { - this.bankfull = value; - } - - /** - * Gets the value of the moderate property. - * - * @return - * possible object is - * {@link Moderate } - * - */ - public Moderate getModerate() { - return moderate; - } - - /** - * Sets the value of the moderate property. - * - * @param value - * allowed object is - * {@link Moderate } - * - */ - public void setModerate(Moderate value) { - this.moderate = value; - } - - /** - * Gets the value of the major property. - * - * @return - * possible object is - * {@link Major } - * - */ - public Major getMajor() { - return major; - } - - /** - * Sets the value of the major property. - * - * @param value - * allowed object is - * {@link Major } - * - */ - public void setMajor(Major value) { - this.major = value; - } - - /** - * Gets the value of the record property. - * - * @return - * possible object is - * {@link Record } - * - */ - public Record getRecord() { - return record; - } - - /** - * Sets the value of the record property. - * - * @param value - * allowed object is - * {@link Record } - * - */ - public void setRecord(Record value) { - this.record = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstage.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstage.java deleted file mode 100644 index 74f51c2..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstage.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -/** - * - * @author stephen - */ -public interface Sigstage -{ - public float getValue(); - public String getUnits(); - - public Type getType(); - - public enum Type - { - ACTION ("Action"), - BANKFULL ("Bankfull"), - FLOOD ("Flood"), - LOW ("Low"), - MAJOR ("Major"), - MODERATE ("Moderate"), - RECORD ("Record"); - - private String _typeName; - - private Type(String s) - { - _typeName = s; - } - - @Override - public String toString() - { - return _typeName; - } - - public String generateID(String location, String parameter, String parameterType, String duration, String specifiedLevel) - { - StringBuilder build = new StringBuilder(); - if(specifiedLevel == null || specifiedLevel.equals("")) - { - specifiedLevel = _typeName; - } - build.append(location); - build.append("."); - build.append(parameter); - build.append("."); - build.append(parameterType); - build.append("."); - build.append(duration); - build.append("."); - build.append(specifiedLevel); - return build.toString(); - } - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstages.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstages.java deleted file mode 100644 index 540d49e..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Sigstages.java +++ /dev/null @@ -1,239 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlType; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}low"/>
- *         <element ref="{}action"/>
- *         <element ref="{}bankfull"/>
- *         <element ref="{}flood"/>
- *         <element ref="{}moderate"/>
- *         <element ref="{}major"/>
- *         <element ref="{}record"/>
- *       </sequence>
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "low", - "action", - "bankfull", - "flood", - "moderate", - "major", - "record" -}) -@XmlRootElement(name = "sigstages") -public class Sigstages { - - @XmlElement(required = true) - protected Low low = null; - @XmlElement(required = true) - protected Action action = null; - @XmlElement(required = true) - protected Bankfull bankfull = null; - @XmlElement(required = true) - protected Flood flood = null; - @XmlElement(required = true) - protected Moderate moderate = null; - @XmlElement(required = true) - protected Major major = null; - @XmlElement(required = true) - protected Record record = null; - - /** - * Gets the value of the low property. - * - * @return - * possible object is - * {@link Low } - * - */ - public Low getLow() { - return low; - } - - /** - * Sets the value of the low property. - * - * @param value - * allowed object is - * {@link Low } - * - */ - public void setLow(Low value) { - this.low = value; - } - - /** - * Gets the value of the action property. - * - * @return - * possible object is - * {@link Action } - * - */ - public Action getAction() { - return action; - } - - /** - * Sets the value of the action property. - * - * @param value - * allowed object is - * {@link Action } - * - */ - public void setAction(Action value) { - this.action = value; - } - - /** - * Gets the value of the bankfull property. - * - * @return - * possible object is - * {@link Bankfull } - * - */ - public Bankfull getBankfull() { - return bankfull; - } - - /** - * Sets the value of the bankfull property. - * - * @param value - * allowed object is - * {@link Bankfull } - * - */ - public void setBankfull(Bankfull value) { - this.bankfull = value; - } - - /** - * Gets the value of the flood property. - * - * @return - * possible object is - * {@link Flood } - * - */ - public Flood getFlood() { - return flood; - } - - /** - * Sets the value of the flood property. - * - * @param value - * allowed object is - * {@link Flood } - * - */ - public void setFlood(Flood value) { - this.flood = value; - } - - /** - * Gets the value of the moderate property. - * - * @return - * possible object is - * {@link Moderate } - * - */ - public Moderate getModerate() { - return moderate; - } - - /** - * Sets the value of the moderate property. - * - * @param value - * allowed object is - * {@link Moderate } - * - */ - public void setModerate(Moderate value) { - this.moderate = value; - } - - /** - * Gets the value of the major property. - * - * @return - * possible object is - * {@link Major } - * - */ - public Major getMajor() { - return major; - } - - /** - * Sets the value of the major property. - * - * @param value - * allowed object is - * {@link Major } - * - */ - public void setMajor(Major value) { - this.major = value; - } - - /** - * Gets the value of the record property. - * - * @return - * possible object is - * {@link Record } - * - */ - public Record getRecord() { - return record; - } - - /** - * Sets the value of the record property. - * - * @param value - * allowed object is - * {@link Record } - * - */ - public void setRecord(Record value) { - this.record = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Site.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Site.java deleted file mode 100644 index 3289619..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Site.java +++ /dev/null @@ -1,385 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <sequence>
- *         <element ref="{}disclaimers"/>
- *         <element ref="{}sigstages"/>
- *         <element ref="{}sigflows"/>
- *         <element ref="{}zerodatum"/>
- *         <element ref="{}rating"/>
- *         <element ref="{}alt_rating"/>
- *         <element ref="{}observed"/>
- *         <element ref="{}forecast"/>
- *       </sequence>
- *       <attribute name="id" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="name" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
- *       <attribute name="timezone" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="generationtime" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "disclaimers", - "sigstages", - "sigflows", - "zerodatum", - "rating", - "altRating", - "observed", - "forecast" -}) -@XmlRootElement(name = "site") -public class Site { - - @XmlElement(required = true) - protected Disclaimers disclaimers; - @XmlElement(required = true) - protected Sigstages sigstages = null; - @XmlElement(required = true) - protected Sigflows sigflows; - @XmlElement(required = true) - protected Zerodatum zerodatum; - @XmlElement(required = true) - protected Rating rating; - @XmlElement(name = "alt_rating", required = true) - protected AltRating altRating; - @XmlElement(required = true) - protected Observed observed; - @XmlElement(required = true) - protected Forecast forecast; - @XmlAttribute(name = "id", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String id; - @XmlAttribute(name = "name", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String name; - @XmlAttribute(name = "timezone", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String timezone; - @XmlAttribute(name = "generationtime", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String generationtime = ""; - - /** - * Gets the value of the disclaimers property. - * - * @return - * possible object is - * {@link Disclaimers } - * - */ - public Disclaimers getDisclaimers() { - return disclaimers; - } - - /** - * Sets the value of the disclaimers property. - * - * @param value - * allowed object is - * {@link Disclaimers } - * - */ - public void setDisclaimers(Disclaimers value) { - this.disclaimers = value; - } - - /** - * Gets the value of the sigstages property. - * - * @return - * possible object is - * {@link Sigstages } - * - */ - public Sigstages getSigstages() { - return sigstages; - } - - /** - * Sets the value of the sigstages property. - * - * @param value - * allowed object is - * {@link Sigstages } - * - */ - public void setSigstages(Sigstages value) { - this.sigstages = value; - } - - /** - * Gets the value of the sigflows property. - * - * @return - * possible object is - * {@link Sigflows } - * - */ - public Sigflows getSigflows() { - return sigflows; - } - - /** - * Sets the value of the sigflows property. - * - * @param value - * allowed object is - * {@link Sigflows } - * - */ - public void setSigflows(Sigflows value) { - this.sigflows = value; - } - - /** - * Gets the value of the zerodatum property. - * - * @return - * possible object is - * {@link Zerodatum } - * - */ - public Zerodatum getZerodatum() { - return zerodatum; - } - - /** - * Sets the value of the zerodatum property. - * - * @param value - * allowed object is - * {@link Zerodatum } - * - */ - public void setZerodatum(Zerodatum value) { - this.zerodatum = value; - } - - /** - * Gets the value of the rating property. - * - * @return - * possible object is - * {@link Rating } - * - */ - public Rating getRating() { - return rating; - } - - /** - * Sets the value of the rating property. - * - * @param value - * allowed object is - * {@link Rating } - * - */ - public void setRating(Rating value) { - this.rating = value; - } - - /** - * Gets the value of the altRating property. - * - * @return - * possible object is - * {@link AltRating } - * - */ - public AltRating getAltRating() { - return altRating; - } - - /** - * Sets the value of the altRating property. - * - * @param value - * allowed object is - * {@link AltRating } - * - */ - public void setAltRating(AltRating value) { - this.altRating = value; - } - - /** - * Gets the value of the observed property. - * - * @return - * possible object is - * {@link Observed } - * - */ - public Observed getObserved() { - return observed; - } - - /** - * Sets the value of the observed property. - * - * @param value - * allowed object is - * {@link Observed } - * - */ - public void setObserved(Observed value) { - this.observed = value; - } - - /** - * Gets the value of the forecast property. - * - * @return - * possible object is - * {@link Forecast } - * - */ - public Forecast getForecast() { - return forecast; - } - - /** - * Sets the value of the forecast property. - * - * @param value - * allowed object is - * {@link Forecast } - * - */ - public void setForecast(Forecast value) { - this.forecast = value; - } - - /** - * Gets the value of the id property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getId() { - return id; - } - - /** - * Sets the value of the id property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setId(String value) { - this.id = value; - } - - /** - * Gets the value of the name property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getName() { - return name; - } - - /** - * Sets the value of the name property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setName(String value) { - this.name = value; - } - - /** - * Gets the value of the timezone property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTimezone() { - return timezone; - } - - /** - * Sets the value of the timezone property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTimezone(String value) { - this.timezone = value; - } - - /** - * Gets the value of the generationtime property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getGenerationtime(){ - return generationtime; - } - - /** - * Sets the value of the generationtime property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setGenerationtime(String value){ - this.generationtime = value; - } -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Standing.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Standing.java deleted file mode 100644 index e326da1..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Standing.java +++ /dev/null @@ -1,159 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <complexContent>
- *     <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
- *       <attribute name="audience" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="dignity" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *       <attribute name="trace" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </restriction>
- *   </complexContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "content" -}) -@XmlRootElement(name = "standing") -public class Standing { - - @XmlValue - protected String content; - @XmlAttribute(name = "audience", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String audience; - @XmlAttribute(name = "dignity", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String dignity; - @XmlAttribute(name = "trace", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String trace; - - /** - * Gets the value of the content property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getContent() { - return content; - } - - /** - * Sets the value of the content property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setContent(String value) { - this.content = value; - } - - /** - * Gets the value of the audience property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getAudience() { - return audience; - } - - /** - * Sets the value of the audience property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setAudience(String value) { - this.audience = value; - } - - /** - * Gets the value of the dignity property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getDignity() { - return dignity; - } - - /** - * Sets the value of the dignity property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setDignity(String value) { - this.dignity = value; - } - - /** - * Gets the value of the trace property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTrace() { - return trace; - } - - /** - * Sets the value of the trace property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTrace(String value) { - this.trace = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Valid.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Valid.java deleted file mode 100644 index 0da5c47..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Valid.java +++ /dev/null @@ -1,103 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter; -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; -import javax.xml.datatype.XMLGregorianCalendar; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>dateTime">
- *       <attribute name="timezone" use="required" type="{http://www.w3.org/2001/XMLSchema}NCName" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "valid") -public class Valid { - - @XmlValue - @XmlSchemaType(name = "dateTime") - protected XMLGregorianCalendar value; - @XmlAttribute(name = "timezone", required = true) - @XmlJavaTypeAdapter(CollapsedStringAdapter.class) - @XmlSchemaType(name = "NCName") - protected String timezone; - - /** - * Gets the value of the value property. - * - * @return - * possible object is - * {@link XMLGregorianCalendar } - * - */ - public XMLGregorianCalendar getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - * @param value - * allowed object is - * {@link XMLGregorianCalendar } - * - */ - public void setValue(XMLGregorianCalendar value) { - this.value = value; - } - - /** - * Gets the value of the timezone property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getTimezone() { - return timezone; - } - - /** - * Sets the value of the timezone property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setTimezone(String value) { - this.timezone = value; - } - -} diff --git a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Zerodatum.java b/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Zerodatum.java deleted file mode 100644 index 2961f2d..0000000 --- a/regi-headless/src/main/java/usace/rowcps/headless/sigstages/retrieve/xmlmodel/Zerodatum.java +++ /dev/null @@ -1,90 +0,0 @@ -// -// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.8-b130911.1802 -// See http://java.sun.com/xml/jaxb -// Any modifications to this file will be lost upon recompilation of the source schema. -// Generated on: 2016.07.28 at 11:19:12 AM PDT -// - - -package usace.rowcps.headless.sigstages.retrieve.xmlmodel; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlSchemaType; -import javax.xml.bind.annotation.XmlType; -import javax.xml.bind.annotation.XmlValue; - - -/** - *

Java class for anonymous complex type. - * - *

The following schema fragment specifies the expected content contained within this class. - * - *

- * <complexType>
- *   <simpleContent>
- *     <extension base="<http://www.w3.org/2001/XMLSchema>float">
- *       <attribute name="units" use="required" type="{http://www.w3.org/2001/XMLSchema}anySimpleType" />
- *     </extension>
- *   </simpleContent>
- * </complexType>
- * 
- * - * - */ -@XmlAccessorType(XmlAccessType.FIELD) -@XmlType(name = "", propOrder = { - "value" -}) -@XmlRootElement(name = "zerodatum") -public class Zerodatum { - - @XmlValue - protected float value; - @XmlAttribute(name = "units", required = true) - @XmlSchemaType(name = "anySimpleType") - protected String units; - - /** - * Gets the value of the value property. - * - */ - public float getValue() { - return value; - } - - /** - * Sets the value of the value property. - * - */ - public void setValue(float value) { - this.value = value; - } - - /** - * Gets the value of the units property. - * - * @return - * possible object is - * {@link String } - * - */ - public String getUnits() { - return units; - } - - /** - * Sets the value of the units property. - * - * @param value - * allowed object is - * {@link String } - * - */ - public void setUnits(String value) { - this.units = value; - } - -} diff --git a/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java b/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java index 4c97c79..6e168d2 100644 --- a/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java +++ b/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java @@ -7,8 +7,7 @@ package usace.rowcps.headless; import java.util.TimeZone; -import org.junit.BeforeClass; -import org.junit.Test; +import org.junit.jupiter.api.BeforeAll; import usace.rowcps.cwms.Installer; import usace.rowcps.headless.tests.TestVariables; @@ -149,7 +148,7 @@ private static String[] getArgsForFileAndTimeZone(String file, TimeZone tz) return args; } - @BeforeClass + @BeforeAll public static void beforeClass() { //Sets up DB info diff --git a/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/DailyHeadlessInflowCurrentDayControlTest.java b/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/DailyHeadlessInflowCurrentDayControlTest.java index e6802b9..fa8c949 100644 --- a/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/DailyHeadlessInflowCurrentDayControlTest.java +++ b/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/DailyHeadlessInflowCurrentDayControlTest.java @@ -6,25 +6,24 @@ */ package usace.rowcps.headless.calculator.inflow; +import static org.junit.jupiter.api.Assertions.assertEquals; + import java.util.Calendar; import java.util.Date; import java.util.NavigableSet; import java.util.TimeZone; import java.util.logging.Logger; -import org.junit.Test; - import hec.data.DataSetException; import hec.data.location.LocationTemplate; import hec.data.tx.DataSetTxIllegalArgumentException; import hec.db.DbConnectionException; import hec.db.DbException; import hec.db.DbIoException; +import org.junit.jupiter.api.Test; import usace.rowcps.regi.executor.ManagerIdType; import usace.rowcps.regi.model.ManagerId; -import static org.junit.Assert.assertEquals; - /** * * @author Ryan A. Miles (ryanm@rmanet.com) diff --git a/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/HeadlessInflowOptionsTest.java b/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/HeadlessInflowOptionsTest.java index a959776..e3f2d00 100644 --- a/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/HeadlessInflowOptionsTest.java +++ b/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/HeadlessInflowOptionsTest.java @@ -6,9 +6,11 @@ */ package usace.rowcps.headless.calculator.inflow; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.util.Arrays; -import static org.junit.Assert.*; -import org.junit.Test; +import org.junit.jupiter.api.Test; import usace.rowcps.data.inflow.InflowDataType; /** diff --git a/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/InflowComputationStorageOptionTest.java b/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/InflowComputationStorageOptionTest.java index 054c918..e04155d 100644 --- a/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/InflowComputationStorageOptionTest.java +++ b/regi-headless/src/test/java/usace/rowcps/headless/calculator/inflow/InflowComputationStorageOptionTest.java @@ -6,10 +6,11 @@ */ package usace.rowcps.headless.calculator.inflow; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.util.ArrayList; import java.util.List; -import static org.junit.Assert.*; -import org.junit.Test; +import org.junit.jupiter.api.Test; import usace.rowcps.data.inflow.InflowDataType; /** @@ -38,7 +39,7 @@ public void validateUniqueInflowDataTypes() if (!nonUniqueDataTypes.isEmpty()) { - assertTrue("Non unique data types found: " + nonUniqueDataTypes.toString(), false); + assertTrue(false, "Non unique data types found: " + nonUniqueDataTypes); } } } From 2d92df33962737d9a0c4d993a281226992ded45b Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Wed, 1 Jul 2026 14:56:17 -0700 Subject: [PATCH 2/5] update README.md --- README.md | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 743cd8d..7d6b916 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,66 @@ # REGI-Headless -This is a temporary readme file and will be updated in the future. \ No newline at end of file +> [!IMPORTANT] +> **Notice: Project Refactor in Progress** +> This project is undergoing a large refactor for CWMS Data API support. +> It will transition from a Java project consuming Jython scripts to a **Python project** that +> utilizes **JPype** to call underlying REGI Java libraries. + +`REGI-Headless` is a Java-based command-line tool and library designed to run +**REGI** calculations in a headless environment. +It allows users to execute complex hydrological calculations and manage gate settings via Jython +scripts without the need for a graphical interface. + +## Features + +- **Headless Execution**: Run REGI calculations as part of automated workflows or on servers. +- **Database Integration**: Connects to CWMS data retrieval and storage. +- **Modular Calculations**: Includes support for: + - Inflow calculations (Clone, Compute, Auto-Adjust, Balance All, etc.) + - Flow Group and gate settings calculations. + +## Project Structure + +- `regi-headless/`: Core Java implementation, including `RegiCLI`. +- `district-scripts/`: Example scripts and district-specific configurations. +- `docs/`: Additional documentation. + +## Getting Started + +### Prerequisites + +- Java JDK 21 or higher. +- Access to a CWMS + +### Building + + +```powershell +./gradlew build +``` + +Details TBD. + +## Usage + +TBD + +### Command Line Options + +TBD + +### Example + +TBD + +## Testing + +TBD + +## Maintainers + +See [MAINTAINERS.md](MAINTAINERS.md) for a list of project maintainers. + +## License + +See [LICENSE](LICENSE) for licensing information. \ No newline at end of file From f39abb03fd6f2fad143f9a70c92c3b8f1265922a Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Wed, 1 Jul 2026 15:47:38 -0700 Subject: [PATCH 3/5] remove unused transitive dependencies --- gradle/libs.versions.toml | 10 ---------- regi-headless/build.gradle | 14 +++++++++++++- .../test/java/usace/rowcps/headless/TestFrame.java | 1 - .../java/usace/rowcps/headless/TestHeadless.java | 10 ---------- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index fd6e634..530fd77 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -12,11 +12,6 @@ regi = "3.5.0-alpha001" jython-standalone = "2.7.2" args4j = "2.32" -# Natives -windows-jre = "1.8.0_201" -solaris-jre = "1.8.0_202-Solaris-SPARC" -jython-starter = "2.2.4.0" - # Test junit = "6.1.0" @@ -30,11 +25,7 @@ hec-db-cda = { module = "mil.army.usace.hec:hec-db-cda", version = "14.1.0" } hec-cwms-ratings-cda = { module = "mil.army.usace.hec:hec-cwms-ratings-io-cda", version = "4.2.2"} # REGI Dependencies -regi-basinpie-ui = {module = "mil.army.wmist.regi:basin-pie-ui", version.ref = "regi"} regi-computation = {module = "mil.army.wmist.regi:computation", version.ref = "regi"} -regi-decisionsupport-ui = {module = "mil.army.wmist.regi:decision-support-ui", version.ref = "regi"} -regi-mappanel-ui = {module = "mil.army.wmist.regi:map-panel-ui", version.ref = "regi"} -regi-ui = {module = "mil.army.wmist.regi:regi-ui", version.ref = "regi"} # Regi-tools Dependencies regi-tools-regi-core = {module = "mil.army.wmist.regi-tools:regi-core", version.ref = "regi-tools"} @@ -45,7 +36,6 @@ regi-tools-regi-cwms = {module = "mil.army.wmist.regi-tools:regi-cwms", version. # Third Party jython-standalone = {module = "org.python:jython-standalone", version.ref = "jython-standalone"} args4j = {module = "args4j:args4j", version.ref = "args4j"} -otel = {module = "io.opentelemetry:opentelemetry-api", version="1.58.0"} # Test junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api", version.ref = "junit" } diff --git a/regi-headless/build.gradle b/regi-headless/build.gradle index 26da9f7..c4a6bf1 100644 --- a/regi-headless/build.gradle +++ b/regi-headless/build.gradle @@ -11,7 +11,6 @@ dependencies { implementation(libs.bundles.regi) {artifact {extension = "jar"}} implementation(libs.bundles.regi.tools) implementation(libs.bundles.regi.tools) {artifact {extension = "jar"} } - implementation(libs.otel) runtimeOnly(libs.hec.cwms.ratings.cda) testImplementation(libs.bundles.junit.api) @@ -25,6 +24,19 @@ configurations.configureEach { exclude group: 'mil.army.usace.hec.swingx', module: '*' exclude group: 'org.swinglabs', module: '*' exclude group: 'org.jfree', module: '*' + exclude group: 'org.netbeans.modules', module: '*' + exclude group: 'org.netbeans.api', module: '*' + exclude group: 'mil.army.usace.hec.map', module: 'hec-osmmap' + exclude group: 'mil.army.usace.hec', module: 'hec-geojson' + exclude group: 'mil.army.usace.hec', module: 'dssplugin-excel' + exclude group: 'mil.army.usace.hec', module: 'dssgui' + exclude group: 'com.fifesoft', module: 'rstaui' + exclude group: 'mil.army.usace.hec', module: 'rma-javafx-core' + exclude group: 'mil.army.usace.hec', module: 'hec-vrt-io' + exclude group: 'org.apache.xmlgraphics', module: '*' + exclude group: 'org.apache.poi', module: '*' + exclude group: 'javax.media', module: '*' + exclude group: 'com.vividsolutions', module: 'jts' } jar { diff --git a/regi-headless/src/test/java/usace/rowcps/headless/TestFrame.java b/regi-headless/src/test/java/usace/rowcps/headless/TestFrame.java index 8d2f38e..2b46ad7 100644 --- a/regi-headless/src/test/java/usace/rowcps/headless/TestFrame.java +++ b/regi-headless/src/test/java/usace/rowcps/headless/TestFrame.java @@ -43,7 +43,6 @@ public TestFrame() throws HeadlessException public static void main(String[] args) { - TestHeadless.beforeClass(); TestFrame frame = new TestFrame(); frame.pack(); frame.setDefaultCloseOperation(EXIT_ON_CLOSE); diff --git a/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java b/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java index 6e168d2..4cf8ac7 100644 --- a/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java +++ b/regi-headless/src/test/java/usace/rowcps/headless/TestHeadless.java @@ -7,8 +7,6 @@ package usace.rowcps.headless; import java.util.TimeZone; -import org.junit.jupiter.api.BeforeAll; -import usace.rowcps.cwms.Installer; import usace.rowcps.headless.tests.TestVariables; /** @@ -147,12 +145,4 @@ private static String[] getArgsForFileAndTimeZone(String file, TimeZone tz) return args; } - - @BeforeAll - public static void beforeClass() - { - //Sets up DB info - Installer installer = new Installer(); - installer.restored(); - } } From 65a8526abc5c7b7f103ecdf1460b5660d1fbbe06 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Wed, 1 Jul 2026 15:55:23 -0700 Subject: [PATCH 4/5] update to use gradle action for dedicated caching --- .github/workflows/build.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8fca131..4aaeeba 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,9 @@ jobs: with: distribution: temurin java-version: 21 - cache: gradle + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v6 - name: Make Gradle wrapper executable run: chmod +x ./gradlew From 80fec2cd764ad74600af3875cc720d89388b2432 Mon Sep 17 00:00:00 2001 From: Adam Korynta Date: Wed, 1 Jul 2026 16:26:18 -0700 Subject: [PATCH 5/5] add in dependency submission for gradle SBOM generation --- .github/workflows/build.yml | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4aaeeba..0be5339 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,6 +31,31 @@ jobs: - name: Make Gradle wrapper executable run: chmod +x ./gradlew - + - name: Build and test - run: ./gradlew clean build \ No newline at end of file + run: ./gradlew clean build + + dependency-submission: + name: Submit Gradle dependencies + needs: build + runs-on: ubuntu-latest + if: github.event_name == 'push' && github.ref == 'refs/heads/main' + permissions: + contents: write + + steps: + - name: Checkout repository + uses: actions/checkout@v7 + + - name: Set up Java + uses: actions/setup-java@v5 + with: + distribution: temurin + java-version: 21 + + - name: Set up Gradle + uses: gradle/actions/setup-gradle@v6 + + - name: Submit Gradle dependencies + uses: gradle/actions/dependency-submission@v6 + \ No newline at end of file