diff --git a/public/404.html b/public/404.html deleted file mode 100644 index e43d5de..0000000 --- a/public/404.html +++ /dev/null @@ -1 +0,0 @@ -404 Page not found

Error

Woops. Looks like this page doesn't exist ¯\_(ツ)_/¯.

Go to homepage

Page not found!

\ No newline at end of file diff --git a/public/CNAME b/public/CNAME deleted file mode 100644 index 988726f..0000000 --- a/public/CNAME +++ /dev/null @@ -1 +0,0 @@ -strolch.li \ No newline at end of file diff --git a/public/api/index.html b/public/api/index.html deleted file mode 100644 index 4faa1fd..0000000 --- a/public/api/index.html +++ /dev/null @@ -1,132 +0,0 @@ -API - Strolch

API

Overview

The Strolch API revolves around the StrolchTransaction object. The main -concept is to implement your use cases in Service implementations. You -open a transaction using the openTx(String)-method and then perform the -use case by adding your Command instances to the transaction.

Transactions are opened on a StrolchRealm. The realms are used to -separate mandates in a single runtime instance of Strolch. Each realm -has its own ResourceMap, OrderMap, ActivityMap instances from which the -TX retrieves the elements.

Model

The Strolch model is implemented in the project li.strolch.model.

The Strolch model consists of three root level elements: Resource, -Order and Activity. Each element has at least the following attributes:

  • Id → the element’s id
  • Name → the element’s name
  • Type → the element’s type

Each root element can have any number of ParameterBag instances on it, -which in turn can have any number of Parameters on it. Accessing these -objects is always done by their IDs. Strolch root elements are always -stored in the respective ElementMaps in their Strolch realm. Thus -accessing a certain parameter from a Resource would look like this:

public class Test {
-  public static void main(String[] args) {
-    try (StrolchTransaction tx = openTx(realmName)) {
-      Resource resource = tx.getResourceBy("MyType", "myResource");
-      ZonedDateTime date = resource.getDate("myBag", "myParam1");
-      logger.info("myParam date has value " + date);
-    }
-  }
-}
-

XML Presentation of Strolch’s top level elements of Resources:

<!-- Resource instance -->
-<Resource Id="myResource" Name="Test Name" Type="MyType">
-  <ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
-    <Parameter Id="myParam2" Name="StringList Param" Type="StringList" Value="Hello, World" />
-    <Parameter Id="myParam1" Name="Date Param" Type="Date" Value="2012-11-30T18:12:05.628+01:00" />
-    <Parameter Id="myParam3" Name="String Param" Type="String" Value="Strolch" />
-  </ParameterBag>
-  <ParameterBag Id="additionalParameters" Name="Parameters" Type="Parameters">
-    <Parameter Id="myParam1" Name="Long Param" Type="Long" Value="4453234566" />
-    <Parameter Id="myParam2" Name="Integer Param" Type="Integer" Value="77" />
-    <Parameter Id="myParam3" Name="Float Param" Type="Float" Value="44.3" />
-    <Parameter Id="myParam4" Name="Boolean Param" Type="Boolean" Value="true" />
-  </ParameterBag>
-  <TimedState Id="myState" Name="Integer State" Type="IntegerState">
-    <Value Time="0" Value="1" />
-    <Value Time="1" Value="2" />
-    <Value Time="2" Value="3" />
-  </TimedState>
-</Resource>
-

XML Presentation of Strolch’s top level elements of Orders:

<!-- Order instance -->
-<Order Id="myOrder" Name="Test Name" Type="MyOrderType" Date="2013-11-20T07:42:57.699Z" State="CREATED">
-  <ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
-    <Parameter Id="myParam2" Name="StringList Param" Type="StringList" Value="Hello, World" />
-    <Parameter Id="myParam1" Name="Date Param" Type="Date" Value="2012-11-30T18:12:05.628+01:00" />
-    <Parameter Id="myParam3" Name="String Param" Type="String" Value="Strolch" />
-  </ParameterBag>
-  <ParameterBag Id="additionalParameters" Name="Parameters" Type="Parameters">
-    <Parameter Id="myParam1" Name="Long Param" Type="Long" Value="4453234566" />
-    <Parameter Id="myParam2" Name="Integer Param" Type="Integer" Value="77" />
-    <Parameter Id="myParam3" Name="Float Param" Type="Float" Value="44.3" />
-    <Parameter Id="myParam4" Name="Boolean Param" Type="Boolean" Value="true" />
-  </ParameterBag>
-</Order>
-

XML Presentation of Strolch’s top level elements of Activities:

<!-- Activity instance -->
-<Activity Id="bicycleProduction" Name="Bicycle Production" Type="Series">
-  <Activity Id="componentProduction" Name="Production of components" Type="Series">
-    <Action Id="consumeGears" Name="Gears" ResourceId="gears" ResourceType="Article" Type="Consume">
-      <ParameterBag Id="objectives" Name="Production goals" Type="Objectives">
-        <Parameter Id="quantity" Name="Quantity" Type="Float" Value="1"/>
-        <Parameter Id="duration" Name="Duration" Type="Duration" Value="PT0S"/>
-      </ParameterBag>
-    </Action>
-    <Activity Id="frameProduction" Name="Production frame" Type="Series">
-      <Action Id="produce" Name="Production frame" ResourceId="frameProduction" ResourceType="Machine" Type="Use">
-        <ParameterBag Id="objectives" Name="Production goals" Type="Objectives">
-          <Parameter Id="quantity" Name="Quantity" Type="Float" Value="1"/>
-          <Parameter Id="duration" Name="Duration" Type="Duration" Value="PT5M"/>
-        </ParameterBag>
-      </Action>
-      <Action Id="toStock" Name="Frame ToStock" ResourceId="frame" ResourceType="Article" Type="Produce">
-        <ParameterBag Id="objectives" Name="Production goals" Type="Objectives">
-          <Parameter Id="quantity" Name="Quantity" Type="Float" Value="1"/>
-          <Parameter Id="duration" Name="Duration" Type="Duration" Value="PT1M"/>
-        </ParameterBag>
-      </Action>
-    </Activity>
-    <Activity Id="brakeProduction" Name="Herstellen Bremsen" TimeOrdering="Series" Type="Series">
-      <Action Id="produce" Name="Production saddle" ResourceId="saddleProduction" ResourceType="Machine" Type="Use">
-        <ParameterBag Id="objectives" Name="Production goals" Type="Objectives">
-          <Parameter Id="quantity" Name="Quantity" Type="Float" Value="1"/>
-          <Parameter Id="duration" Name="Duration" Type="Duration" Value="PT5M"/>
-        </ParameterBag>
-      </Action>
-      <Action Id="toStock" Name="Saddle ToStock" ResourceId="frame" ResourceType="Article" Type="Produce">
-        <ParameterBag Id="objectives" Name="Production goals" Type="Objectives">
-          <Parameter Id="quantity" Name="Quantity" Type="Float" Value="1"/>
-          <Parameter Id="duration" Name="Duration" Type="Duration" Value="PT1M"/>
-        </ParameterBag>
-      </Action>
-    </Activity>
-  </Activity>
-  <Action Id="assembly" Name="Bicycle assemble" ResourceId="bicycleAssembly" ResourceType="Assembly" Type="Use">
-    <ParameterBag Id="objectives" Name="Production goals" Type="Objectives">
-      <Parameter Id="quantity" Name="Quantity" Type="Float" Value="1"/>
-      <Parameter Id="duration" Name="Duration" Type="Duration" Value="PT5M"/>
-    </ParameterBag>
-  </Action>
-  <Action Id="toStock" Name="Bicycle to stock" ResourceId="bicycle" ResourceType="Product" Type="Produce">
-    <ParameterBag Id="objectives" Name="Production goals" Type="Objectives">
-      <Parameter Id="quantity" Name="Quantity" Type="Float" Value="1"/>
-      <Parameter Id="duration" Name="Duration" Type="Duration" Value="PT1M"/>
-    </ParameterBag>
-  </Action>
-</Activity>
-

Realms

Strolch realms implement the multi-client capability which is thus baked right -into the Strolch runtime. When configuring a Strolch runtime, realms are -configured and for each realm the data store mode is set. Each realm has its -own persistence configuration and can thus run in one of the 4 modes that the -Strolch agent implements:

  • EMPTY -This is a transient data store mode, where no model changes are persisted, -but they are only kept in memory. When the Strolch agent is started, this -realm stays empty as no data is loaded.
  • TRANSIENT -This is the same as EMPTY, but with the difference that when the Strolch -agent is started, an XML file is parsed and the in memory realm is populated -with the elements parsed from that XML file.
  • CACHED -In this mode, all data is stored in memory, and any changes made are written -back to the persistence layer. This allows for fast in-memory quries, but -makes sure no data is lost when the agent is restarted.

Strolch Realms are also responsible for opening Transactions, as these are bound -to the persistence layer configured for this realm. At runtime, a realm is then -accessed from the ComponentContainer:

public class Example {
-  public static void main(String[] args) {
-    ComponentContainer container = getAgent().getContainer();
-    StrolchRealm realm = container.getRealm(StrolchConstants.DEFAULT_REALM);
-    try (StrolchTransaction tx = realm.openTx()) {
-      Resource resource = tx.getResourceBy("TestType", "MyTestResource");
-    }
-  }
-}
-
\ No newline at end of file diff --git a/public/api/index.xml b/public/api/index.xml deleted file mode 100644 index e95a209..0000000 --- a/public/api/index.xml +++ /dev/null @@ -1 +0,0 @@ -API on Strolchhttps://strolch.li/api/Recent content in API on StrolchHugo -- gohugo.ioen-us \ No newline at end of file diff --git a/public/assets/images/Strolch-Bird-View.svg b/public/assets/images/Strolch-Bird-View.svg deleted file mode 100644 index df7f1c5..0000000 --- a/public/assets/images/Strolch-Bird-View.svg +++ /dev/null @@ -1,2 +0,0 @@ - -
Browser / Other
Browser / Other
Strolch Agent
Strolch Agent
REST API (JSON / XML)
REST API (JSON / XML)
JDBC (JSON / XML)
JDBC (JSON / XML)
Presentation
Presentation
Business
Business
Database
Database
External Systems
(Agents, ERP, etc.)
[Not supported by viewer]
Any API, preferred REST with JSON
Any API, preferred REST with JSON
System
System
\ No newline at end of file diff --git a/public/assets/images/Strolch-PLC-Architecture-Overview.png b/public/assets/images/Strolch-PLC-Architecture-Overview.png deleted file mode 100644 index 67592f6..0000000 Binary files a/public/assets/images/Strolch-PLC-Architecture-Overview.png and /dev/null differ diff --git a/public/assets/images/Strolch-PLC-Architecture.png b/public/assets/images/Strolch-PLC-Architecture.png deleted file mode 100644 index 8913edd..0000000 Binary files a/public/assets/images/Strolch-PLC-Architecture.png and /dev/null differ diff --git a/public/assets/images/Strolch-Plc-Example.png b/public/assets/images/Strolch-Plc-Example.png deleted file mode 100644 index 9021db9..0000000 Binary files a/public/assets/images/Strolch-Plc-Example.png and /dev/null differ diff --git a/public/assets/images/Strolch-Squirrel-View.svg b/public/assets/images/Strolch-Squirrel-View.svg deleted file mode 100644 index b070992..0000000 --- a/public/assets/images/Strolch-Squirrel-View.svg +++ /dev/null @@ -1,2 +0,0 @@ - -
Strolch Agent
Strolch Agent
Services
Services
Commands
Commands
REST Endpoints
REST Endpoints
DAOs
DAOs
ResourceMap
ResourceMap
ActivityMap
ActivityMap
OrderMap
OrderMap
Realm n
Realm n
Component X
Component X
Component Y
Component Y
Component Z
Component Z
Search API
Search API
Privileges
Privileges
Transactions
Transactions
Observers
Observers
Versioning
Versioning
Policies
Policies
Audits
Audits
\ No newline at end of file diff --git a/public/assets/images/demo-app.png b/public/assets/images/demo-app.png deleted file mode 100644 index 9ba2e2c..0000000 Binary files a/public/assets/images/demo-app.png and /dev/null differ diff --git a/public/assets/images/favicon.ico b/public/assets/images/favicon.ico deleted file mode 100644 index 479df59..0000000 Binary files a/public/assets/images/favicon.ico and /dev/null differ diff --git a/public/assets/images/git-seeklogo.com.svg b/public/assets/images/git-seeklogo.com.svg deleted file mode 100644 index 5cf773f..0000000 --- a/public/assets/images/git-seeklogo.com.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/public/assets/images/intellij-idea-seeklogo.com.svg b/public/assets/images/intellij-idea-seeklogo.com.svg deleted file mode 100644 index 5fc9145..0000000 --- a/public/assets/images/intellij-idea-seeklogo.com.svg +++ /dev/null @@ -1,54 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/assets/images/logo.png b/public/assets/images/logo.png deleted file mode 100644 index 97f6427..0000000 Binary files a/public/assets/images/logo.png and /dev/null differ diff --git a/public/assets/images/maven-seeklogo.com.svg b/public/assets/images/maven-seeklogo.com.svg deleted file mode 100644 index d8c6ef7..0000000 --- a/public/assets/images/maven-seeklogo.com.svg +++ /dev/null @@ -1,110 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/assets/images/plc-server.png b/public/assets/images/plc-server.png deleted file mode 100644 index 1061530..0000000 Binary files a/public/assets/images/plc-server.png and /dev/null differ diff --git a/public/assets/images/plc.png b/public/assets/images/plc.png deleted file mode 100644 index afba5b6..0000000 Binary files a/public/assets/images/plc.png and /dev/null differ diff --git a/public/assets/images/strolch-model-example.png b/public/assets/images/strolch-model-example.png deleted file mode 100644 index f88f79b..0000000 Binary files a/public/assets/images/strolch-model-example.png and /dev/null differ diff --git a/public/assets/images/strolch_mascot.ai b/public/assets/images/strolch_mascot.ai deleted file mode 100644 index 24244f9..0000000 --- a/public/assets/images/strolch_mascot.ai +++ /dev/null @@ -1,5569 +0,0 @@ -%PDF-1.6 % -1 0 obj <>/OCGs[26 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream - - - - - 1000000/10000 - 1000000/10000 - 2 - 6 - 306 - 4465 - Adobe Illustrator 24.3 (Windows) - 2022-12-08T10:30:24+03:30 - 2022-12-08T10:30:24+04:30 - 2022-12-08T10:30:24+03:30 - - - - 256 - 204 - JPEG - /9j/4AAQSkZJRgABAgEAZABkAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAAZAAAAAEA AQBkAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAzAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FWO/mBeXVt 5XnW0nNrc3k1rYpcIeMiLeXMdvI8Z/nSORmX3GRmdmcBZQT/AJaeTUijGn2I0i8hFIdS04m1uwet WmT4pampIl5Bt6g5DhDPiKnH5k1rywywebXW70gkJD5nhTgqV2UahCvwwknb1k/dnuI8IlXNiY3y ZkrK6h0IZWAKsDUEHoQcsa28VdirsVYX528w+YxcPpfleFri7so1u9VaNoldI2P7qCNp1eMSShXY kqaKvQF1YVzkejZCIPNU8v3Ooa1o9prOieYZpbe5Sqw6hbQSojLVXjdYVtJQ6OCrAydRiCSkxANU mC6x5lsTTVNLW7gHW80xy7Ad2e1lCSAf5MbyN7YeIseEdE303U7DU7NLyxmWe3ckB1qCGU8WRlNG V1YUZWAIOx3yQNsSKROFDsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirFfzJj d9BtGUVEeqaaznwH12Jf1sMhk5NmPmpeZp2N/EoY0EKuADsCzMKj/gcxNQdw5eAbO0zXSoNrqH76 1kHAu/xUB2Iev2lPvjjzdCuTDe4QM0N95DJvNNSS98lk8rzSkBkl01TUtPZgVZrcdXg/YG8e3w5k g8PucUji97OLS7tby0hu7SVJ7W4RZYJ4yGR0cclZWGxBBqMtakHpnmPQ9UvLyz0+8juriwYJdrGS wRiWWnL7LEMhVuJNCKHfACCkxIUbvzb5athfh9Ttnn0yCW6vbWOaN5o4oF5SM0YbkAo8RjxBeEpH 5SW6s/KT6zqKhdW1tm1K8U/syXIHow/KCERxfJcpMqjbfGNyphEep6r5H1ufV7SKS+8uanL6ut2E Y5SwzNs15Ao6kj+9Qfa6jfMfHlo7uTkxWNnrOk6vpmr6fDqOmXMd3ZXCh4Z4mDKwPyzLBtwiKS60 iWw86zxQgLDrNm13Kg2H1iykjheX/WkjuI1PsgwjmiXJkWTYOxV2KuxV2KuxV2KuxV2KuxV2KuxV 2KuxV2KuxV2KuxV2KuxV2KsX/Mtf+dQnl34211p909DT4ba/gnbsduMe+QycmeP6kDrxrd2r/wA9 qo+lGNf+JZh5+Yc3ByPvS7KG5OPL+tfV5k0+5b9zJtbSH9lv99n2P7P3Zk4cvQuPmxdQxbzCmueW bt/Kfl8vFp/m2YJpM8W36Mmdi9+qfyq0AeaAD7Lhu1MvJI2HVoAB3PRNJPIt5Nr6afZudL8nWOnW 9lJb2zGOa7ZHkf0fUU844Qrr6hHxOdq0rV4d/JeLbzSrVvyz1+7t71rrUdL0vT3gNjbafbWE88dt ZPIjyQw8bi1VnnMYWVvR5MNlp0wGJUSCY32ueaLi3ihl0W8vTE7CSWzg9CJiNlZUu3glpQ9COvQk b5XkEpCm3GYx3SWbzZocDvbasz6RcKvNrXUka1ZlrSsZkokg/wCMbNmNKJHNyYyB5JLp91o0F9Zz fl/5hhtvMOq3qpeaRVpbGVXrWWWAUIdeI5PGwPjXL8VVsd2jLdmxs9U8taR5qOrzav5mayFyluLO wgsHkkjWN39SZ3aWOE8pCkfw0249TXMqMT1cSUh0ZRk2DsVdirsVdirsVdirsVdirsVdirsVdirs VdirsVdirsVdirsVdiqWeaNJOseWtV0lTxe/tJ7ZGP7LSxsqt/sSa4JCwmJosLh1Mar5V0PWiOJk RROlKFDOgYq3hwdSpzDzbgFzsWxIdmM3pXGus+Yb6Ww0COMQWcnC+1a45fV4pR/uqJVo00i1+IAq B3YHbLYYjJrnlEWcaR5du7cwS6rdQ311bNzhlht2twHKNGW4tLPuVcjrmYI04kp2nuSYJN5v82aT 5U0G41rVC/1aCgCRjk7uxoqKDQVPuaZGchEWWUIGRoPIZvOfn7zndLbtqlt5K0mY0jgWRTqMgJ+H lUoyV/2B/wAk5ERnLn6R9rYTCPL1H7E+/wCVLeRtNtI7yeCfWb2e4gSa9vpTMQJJURmaMUjIof5c sGCA6X72o55nrXuYd5s8taV5Q/O/ytfaAsVnaXt1Al3bRikcTO4RwFGy+pE+yj+OU54iEhIbBtx5 LxyEugfQn6X03/f4+5v6YfzWPvcDx4d7Y1bTj/u9fpqP4YfzOPvXxod69dQsW6XEf0sB+vJDPA9Q y8WPerJLE/2HVvkQf1ZMSB5FkJArskl2KuxV2KuxV2KuxV2KuxVjXnn0fq2miWNZVN4aI4DJUWs5 qymoalKiveh7ZVmNRbsIuSTaV5q1mG5bSdPiTWpo+BaF5xHNaxkipmkbmzqyn93yHLY1LbHIY8pI Z5cQBYtq/mu/tdam1S+tLhblCbfUreCd5YI1B4xxQXVua27r9r94qByW5inFlEpm76JjCPDXV67p TXh0y0F8Qb/0I/rdCp/e8B6n2fh+1XptmQC4pIvZFYVczBQWY0UbknoBgJpUnu/MKIxW2TnT9tth 9AzAy64DaItxZ6muSFTzFeBqsiMvcAEfjXKRrp9QGsamSdWN9DeRc49mGzoeoObDDmGQWHKx5BIb LbjU7GCoeUFh+yvxH8ME9RCPMrLLEdXmmjS21vq/mHyswK20kjanpqnY/V7yQyPxG4/c3XqCn8pX pXKYZI5AacvBmEgJDoxzz15om8t6NdQy3EcOoSRMtiW3Ys3wq4HdVO+Y8hR3dgDYsNaF51/MC706 203yD5eGn+X7KEW8Wo6v8LOxNWnYDdnY7niHBJJNaimbETI9Ioebhy4AfUbPkuvfLX5h3rMNe86X 81xTlLp2hxFCq+BMfBfvTJeCTzkfgx8UDlEfFJtQ8r695Y0Uec/L2t6odS02lxe6TqpqzQg0lDxj hVerGvUDx3yM8PCLiTY72UM3EakBR7mDalqf5xebtDn8w34ur3y5aOLmV24R2o9JqckiqgfhWh4K e9cxvWRbkDgBp6/5K86eW7i2+pfoqFbYembVTF60tx1MkssvTlT4txm18SBDqzjmCzu7tI7a2aO0 jDpCI7u2iJZU4cq8XC/a40Zht4ZEirSJXu8x/N3TltfJ6awsgmvbPUoNRkuhsXd39MBT2UB1CjwA zBzHiiWOkycWUg8iCHo43Fc1DqnYq7FXYqrR3l1H/dzOvsGNPuyyOWQ5EshOQ5FHW2v3cZAmAlXv +y33jMnHrZDnu3R1Mhz3Ty0vILqP1IjUdGU9QffNliyxmLDmQmJCwrZYzdirsVdirsVSfzNqEtna oyMURq82XY7UoK+9cwNfmMIinF1WQxDFLi51PXdLltTIEaFhLbyMOQVo/iBkNQSnZ9xVSRUZr9Pq ss9ubj6XVZCe+mE6Ro89zooiliu7jWrl5p5eInKxeqpMUsch4wxfaHxVWjBh1GbfGI8NdXdzlIyv og/KUtvfwah5duPW0RLh2JW9gmmuSswpMzM5jcelIDWRyQhZV5MxGIO3Cso729Q06KS6iK+vbNeJ JLE0Ecg5n0ZXi5hCagP6RIFduldswJaOXTd1OTSyB25Jlo93cperAzMUaqsjHoQD0r06YdLlkJ8J 5McEyJUivMN2yhLZTQMOUnuK7DLddlqohs1M+iRZrXDQ13fQ2wofikPRB/HK55BFhPIIoGDWLr60 pLlIn+F0XYUPj45TDUS4vJpjmN+Sb5lOSx7zbpeoSLa61o6hta0dmkt4SeIuIHAE9qx/4tUAqT0c Kcuw5OEuTpc3BLfkXkf5oXVlc+Z/LfnW3Vp9EmaAXaup/dzW01ZYJVP2HCihQ9wcziRxCXR38d4E PetI0+4tPLgs7RFVRNM9owIKmKaRplYUrsgkpTvTNmeTreqQ+adZ1LQNDtbPSyUu7pUnvLpRWRmk PJjyIPyqcjxcICeHjJVdT1tNatZLW7tfTjjsjfhS5dggUCaFmP2lkQuu/tkoyEgWJiYEIf8AI2NL z8v9T8raivqx6VfXulTRt+1E55kffKwzDxDaj02cvKd7HXd575ekt/JHmi78t+ZbhrePT+ZsrhlH +kW7n906klVqVPjsdu2DGYxNSPJlkEpC4jmz8/mrpl1qDt5dt73XJ2gS2itbK2aSNChJ5SztxT9r elQPfLznj039zQNPIDfb3pJP+V35keaNKjttVnttG0qCQS2+iOxndwH5CKeWHiFRRsvGtPCormPP HKXkzjGECTH6j1/UyyDVr+21GLSdesTpuoTg/VJEf1rS54jkwgnoh5ACpR1VqbgEAnNbl08oe51W bTGAsbhNsocZ2KuxV2KuxVE6ddta3SSV+AnjIPFT/TLsGXgkC2Yp8MrZbm9dm7FXYq7FXYqlPmVI 5NPVHUMpkXY/InMHXgHHv3uNqgDH4taDYWf6LdDCjRz8llQqCrKfhKsD1BHbDocYENuq6WIEdnnX nt9P8nXR02wtU/Q/mJGTUYRK3+j/ABNRUWRuCxT+owWMOiij8a70szSEPcXN8UAXJI/Lll5Jt9cS Ly1pMlw1wQurJGTI7WTE+rG7CSVmj50ekhXlwCKG5UyrHkiT6RbI6njAA+5lcnlP1orC0T1orm5u 5DaXFWiuILaF42E6gn91xjt4+CceIcrVVDFRdwG2fGACyu1HLzAaf79k/DlmDj/v/iXTw/vfiWvM AIvwT0KAj7yMGuHr+C6n6kiv7z6tFVf7xtkH8c1+XJwhw8k+EJCzMzFmNWO5JzBJtxCWsCGUCtBX r3zZuwbxVgHm3ybY3mrS2FtW3j8029xFdR1/cG+twk1vcFR0kojByPtL18czNMTIGLtdBmPI9GRf kh5jl1Xyr+h9QBj1ny+36PvoH2cCL4Y2I6/ZXif8oHNthnxQ8xs3Z4cMtuRRP5gaIs1vAZC8a2wK x3MbxKioTULOJXiUItNmB+jxs4QRu1AkHZgt95ntpdVfT/Lqf4iv5RFG9vYB5VMMZ5BHnokcSM4+ Jl5+HTKfGjEVH1H8dW4YJE8Uth+OjA49e82adda5o13qJ0y4utRuLjVbeCQQcp22cNKCrFNtlVqM D32ymIO997kEA1XclCTaVG8p9P1CoPB4aJWTs3IjlQdelf15KlfTnk/zbZWP5f8Alm+8yXkdlLfW kCLc3J4RyOUHBnlI4K0i0b4jvXbJCW27QY7mmT2uqpLevYTRmC8RPVVCeSSR1pzjfbkATQ7Ajw6Y bRSR/mgk48kaldwCL1dPT66rTfZX6v8AvPUDCpVo6c1p1Ip0JyOQXErEA7FO28uWh+zJIPnQ/wAB mOdBHvLgnSx70PJ5bkH93OD7MCP1VyqWgPQsDpT0KAutMvLYcpEqn867j+zMbJp5w5honilHmhco a3Yq7FWY2jF7WFj1aNSfpAzoMRuIPk7WBuIVcmydirsVdiqX68hbT2P8jK38P45ia0XjaNQPSlYv NRg8sahLpsXr38Cu1vFtUniDsDsW60Hc7ZDRS9BXSEEUe9AmASXlhDCVutD1lZDNfLJznmuDCXUy naqenGSpQ0FAvELTMlzeSK13R44NJnmgkNu8Co0XoqsccYSZJmfgBT/dY5E9hiQoKZaXob2l2+o3 1219qLRCAzFRHGkQbkRHECQvI0LmtTQeAyYFbtcpJBpC6hN5maZQ3pglif2eDHf275odMJy1Fh0+ ESOa0/8AMFoZIVnUVMWzj/JPf6M2WuxWOIdHN1MLF9zAdTmMl2w7J8I+jr+Oc5mlcnS5TckJlTWi LG3ae4UU+BTyc+w/rlmOHEWeONllFpZXF1JwiWtPtMdgPmc2mLFKZoOwhjMjsnltodnAvOc+qw3J bZR9H9c2WLRxjz3LmQ08Rz3YbaanoyrJ5+8x3CQWcYZPL9q1eNvaybK6RDdrm6FCaLyAIjHQ8rRQ 3c4QrYIHzp+XGjS3dz50g1a+8sX/ANXEmptZEfvQBsGjH2pCQFoD8R7VxMN7BILOM9qIBC7SvyQ8 t3ENvdeZJ9S1m84h3h1G8eVY3IrxrF6dePTqRg8IHnZ95XxiOVD3Bm8Nr5c8saPK8EFvpWl2iGWY xosUaqo3ZuIFTQdepyzYBr3JYH54/KPy155Ka/bXEmj6tcxIZJiopIOI4fWIWI+NV22Kt2PSmRIv cM4yI2YK/wCT/kjyoy6h5182RTabH8ZsYovq5nK7lK+pNI6nusY5HxyJ8yzsnkE28u+d7X83PPA0 CCzaDyPokH1yS3dVAu5Y5ESBJk3AiBJZY+/Hf+XAJcR8kzgcY35l6HrENt5W0rT542Z7bRvrMkXI lmW1WGQiGpNSqJRFqewyZ2a47qvnC8i1bTV8uWw5z67/AKJIhH2bZqfWnNeyQltztWi9WGJN7IAr dMNZ8z31rqM1jp1jFcm1ijlu57mdraJfXLCONPThuXd/3ZJ+EACm9dslPJwsIY+JK4vzPgldrOLS ri61i2/46djbS2/G2B/u2M1xJbqwmX4ohQMRWoWhoPGFWy8E3TKNG1iy1jT1vLYOEYtHLDKvCSOR CVeORT0ZSPkeoqCDlgIIapRrYpNrFkttdfAKRSDko8PEZptVi4Jbci63Pj4ZbIDMZpdirMLH/eK3 /wCMSf8AERm/w/QPcHaY/pHuVssZuxV2KuxVD6j6X1GYSusaFSObkKoPapPvleaNwIYzjYISDQtT toriSEzRgyL8PJwByHQH51zXaKfDIg9XE01g0WK6Pf6SfPi3pEkEj27m+tBDcWtvDdvxAnPrSm3k YqZV9SFdx1LVBzOvd2tbJgdYv9X0rX7Oa/t4lDTQW8jcYwFEksXpluXVvTFT74bRVMsvtasjo8d1 HKoW9iV7fkQCVlUEGlf5TkdTkqB83EzEiJUfLrWyxFzKnOdisS8hVgnWgrv1yjQxoEnq06aNC07Y KVIbdabg9KZnFynnF5pIlmeWFgvNi3Bugqa9RnK5MFmw6GeGzYUY9Flr+8kUD/JqT+NMgNOepYjA eqbWFivNLeAULmlep+ZzMw4rIiHJx4+gZlbW0VtCsUYoo6nuT4nN/jxiAoO1hARFBUdEdGRwGRgQ ynoQdiMmyecea/yu0O30y3utMsLjULyyvNPkhhnuJ7to7aG8heVLdbh5FT90hrx+Jlqtd8qljFbN schvdLNRPnzU/OOiy6xZLY+VdSv40i0+R1a5jfT0luoWmVCyH6xInIAMeIQVoTTIkG92YIrZ6oWU MFr8RBIHsKf1yxrYX56s4vMOmT6NcL6tkupWyX0Cs6M0CIk1KoQf70rX2yuW7ZAU8m86/lV50gvU uPKGr6q2h0H1vRIL6dpkCijNAJpaSA0qVLch2r0FRiejkYpQscfLyYzaeQ/Ictx6Gs2ms3GpS/bj dbkaiXIp8MLxjmeVP2fpyMRvvbuZY9J4dwkL87/Q9f8Ayw8o6b+Vnkm41HVo5lvL9/rOpukbXD28 KKxiilMCn4YUrzcDjyLb8aZdCPCHQ5p8c9uXRNbqzvfzCmjt5rOez8ngrJeS3CyW0t6qnkkEMben MsTNQySMF5D4VqCWEgOL3NZkIjbmiUg0zyfPPb+XdKk1K+CRrf319ezMVUgtFAbmYXUtaAsI1Xio oTTkKspCCxiZ9V/lrUo/MF/rl3qFjPpYJtYvqt3RHIhjLGZHUsjxF5Sisp/ZPTBYmN+SQDA0Oa3T /Ktpa3GvagLwX0l9cC8SK2QCVIobZIUtlBduVPSqG2qWO2QMIy5FmJyjzCTeXvOeu6ZoyajJoISz ui+o6lJPM8FyUYCgtrX0XLenEqovqtEX414jkCZDII0GJxGVlnfmBkkt7aVDyVqlGHcMAa5j68bB 1mqGwSPNY4TsVZhZAiytweojT/iIzf4foHuDtMf0j3K2WM3Yq7FXYqwL8zLuWDU9CVJV4OLrnbu4 j6LGPWDNRapXhSoNHPvmDrem7Tn+nnX45PKtQ84azBH5ggtr8sLQw/U2YKWQS8easBRX6tT2zX3d blphCMjDn6r+xMr7VNLnnEk8aO0MiwzymUK4RweCrQKxVnKfCWO5r22iMhHItMMswDRQ1rFCbWOw 1d7M608MyxvakrH6Ik/d/EKGillbfpXxrkzMg7HZtllIPpkeGwt1a580JpwtPL13p8ctrJLHdRyO FQQU/wBGWOgVfhh4gge3vhBBO5ZxOOUjxk10/SiotYs5fMiQ2nNLltR0cXshkYiRRexiLiteOyg1 9scUjxD3sMJlcb5er7nvt03G2lb+VGP3DNzkNRJ8nLmdiw3OfdU7FU28uxBrqSQ/7rWg+bH+zM7Q RuRPc5OljvbIM2rnOxV2Ksa8/wCm31zo8N9p0TXGo6LcpqNrbp9uXgrxTRp/lvbzSKn+URkJiwzx mix9/wAwNHNjZa4uoI9hdypbJeBlCRvICFWQGnE86KwIqCd6b5VxdW/h6LLzUTaas8r19GZVa4Kq 0oJNQrn0wzI21PiHFgBQ1FMFppNtMmlu1hlgR4Xk+KNJBwcUrSortUYQgpm7+bfUaKOOzMZPwXbt ICo94gDzP+zXJ7teyS/mfcxWf5darpslyZNQ1Wzm02wUgNLc3d1E0aRog7uW3psq1OwGCZqKxO9p 75J1u81ry3bXt9HHHfK89tdpDURetazvbu0YYsQjNFyUEnY5PHLiiC1HyQvmLTNWspbrXNHb60Sg kv8AQ5VDx3QhWlYG2aKcovEHdGoAVH2gyiyjJdqDDV9HsrzSm9eynRZovT2DRyKGRgPl2yjNEkCn IwyAJtIomuLa5UqGSeNhRSCDXwpmKLBco0QqLZzedNb1aC5mSLy7pc40+WCBKS3cnopLPHJOWNIl 9UIRGoJPIcu2ZwgJGy4JmYigyXzEFEECigAY0A8AMxtfyDrtVyCQ5q3CdirMrccbeJfBFH4Z0GMV Ee52seQVMmydirsVdiqW655b0LXYI4dXsorxIm5w+oPiRjsSjCjLXvQ5CeOMuYVBw+QvJcP1b0tE s1+qAi3pCnwhiSe25qSanvkfAh3KVH/lWvkDv5fsTsQQ0CEEGvWo367V6dsfAh3KHJ+W/kNIDCND tOBYOSYwW5AED4z8WwJoK4Py8O5aWt+WX5fsVJ0GzquxpGAGHhIB/eD/AFq4/l4dyoi08h+TLSeC 4ttFtIp7Z/UglWJQyv8AzVp1FNvDthGGA6Km9+aWNx/xjYfeDjn+g+5hk+k+5iGaF1bsVTzy2Bxu D3qv8c2XZ/IuZpeqdZsXLdirsVdir56/PXy/pC+e9OltbWOyuprOS7mu7eNFkknEyqHlqpSQ8ag8 wagkHNfrZ8FEMM2oljiCO9W8oeajo9kLQaFbvGSC0+k+hbM9BQNJa3Dw0O3+65HHh4ZDHq4Hns2Y 9bjn1o+bLrbz7ZrIrpp2pCVfiCfU5SDTenNQY9/9bLhnh3t3iQPUIrUPzO1JouOn6QLNyP8AenVZ 4kRf8pbe2a4nf/Vb0/mME9ZAOPPPjj1Yl+mYzqrarqt4bu6WN1fU7rjFHBGRVktoQSkEZ4jkal2/ aY5r8uplPYOFPVGZ4RyTn8vPNtxpFlf3+o6VqSeW9XvGvdJ1GOBrhEiMSRu0kMXO5iSV4zKhMXGj VqM2eluMAC7CGMiIHVlt/wDmRok1vHb+WbiHXNbu29K0sYH5emxG8t3xq0EUfVy4B7AFiBmQZjok QPVNfLWhRaHotvpsbmVo+TzzU4+pNKxklkCDZA8jFuI2GACmRNpV501TUbWTT9P0iKB9Y1eY2tlJ PULGRHJK8rFQzcY44mag6mgqK1yMhuyidk48q+Xbfy9okGmRStcOheW6u5ABJPcTOZJpnp3d2Jp2 6dstiKDVKVm1PzKfhtx4lz91M1/aHT4uFquiR5rXDcASQB1OKs2AoAB22zow7d2KuxV2KuxV2Kux V2KuxV2KuxVRvv8AeK4/4xv/AMROV5voPuLDJ9J9zD80Dq3Yqnflpv8Aehf9Uj8c2PZ55uXpTzTv Nk5jsVdiqV+YfMdjolrHJOrz3Vy/o2FhAOU9zNQkRxLt2FWYkKo3YgCuAmkiNvPte/KrU/MkDa1q 9+0HmqX+79EmS1toNylokbcRIi1q7/CzNUgqKLmNlwjIN2U8cJjhPJhEnl3zzo/+j3ujtfRJst1p 8iOCO1YZjFKPkA3zzXT0UhycGfZx/hKH+sasp4/oHV1b+X6lN/AZV+VydzT+Sy932o+z8u/mDqTB bHy5Lbq3/HzqMsdtGPmoMk33JlkNDM82yOgl/EQPtZd5Z/J+xa8F15qvk1m8tGVhpUamOxhcgMrN GxLTHwL/AA/5OZ+HSxh5lzcWGOP6Rv3vS0u7ZrySyRh9YgijmkjHaOVnVD9Jhb7symxWxVzEKCxN ANycVYZpkg178yJr1PisPLVq1srdje3vFmFf5ordBX/jLkY7m2U9o0znLWlIfMjfvoV8FJ+8/wBm azXncOFqjuEnzXuKq2ic7qFf5nUfecniFyA82UBcgzHOgdq7FXYq7FXYq7FXYq7FXYq7FXYqsnXl BIv8ykfeMjMXEokNiwzOedS7FU18uvS8df5kP3gjM3Qn1keTk6U+pkObZznYqx7VPNLm9l0jQIF1 PWIqC4q3G1tCwqpupQGo1DURIC58AvxZEy7mYj3u0TyylldyarqM51LXp04TahIvAJHWvo20VWEM IP7IJJ6uzHfIgMrTC71GK3urO2beS8kMaDw4xvIT90ZxJUBKfMketpfWl3aPF9UjZEdGUs6l3o8i 1IWoToT0yMrZRpOmtbeR1l/3YKEOOpAyVMbdfXcNpbPPKwVFoNzSpJoAPc4kqBaQ+WVuL7ULjV5b kTRxetZW5VQBJHzSRWZgSGKfZ2HXl45GPeyltssnvRZ+fpiSSlzpduJE26QXE9GHy9Y1xJoqBYZG l3bOvJZVI+dPwOTtjRYn5/8AME1vpyWWnGY6hfyraWUlsLdz60gPGiTyQox2PVqDqdshIs4jqU1/ L3y7deX/ACjYabeiP9JKrSajLEzP6tzKxeSV3erO7E/EfHptQZZAUGmcrLIskxY35get/T+RAP1n +OajXH1/BwNSfUxG91GWWQrGxSIbCmxPuc02TKSduTrJ5CTsraHfXMOownkXRTUoxqNhX6Ms0uUx mCzwZCJB6Rb3EdxCssZqrfgfDOpxzEhYd7GQkLCpk2TsVdirsVdirsVdirsVdirsVdirDJk4Sun8 rFfuNM56QokOpkKKzIoRujPw1GLwaqn6QcydIayBuwGphlObp2LDPzH8zz6f+i9BsrkWeoeYJXhW 8rRobeLiJni8ZSZUjTwLcui5XklTZjjaf6HpWnaVpkNjp8SRW8QNQh5cnY1d2Y1Z3ZiSzMak7nfE BJKl5h1afSbA34g9a1h+K8Zal4ou8oQA81Tq+9QtSK9MSaWIti0+p/WvN/lZUmWRbma5ug6tUPGl lKg4kGhFZ1PhkAdw2EbM5liSWNo3FVbrljUCgV0+6gk/0WWiMKOX3Ip7UyNMuIHm79CwzGM3jm49 JucakkKG8aV3O+PCvF3I+KKOKNY41CRoKKiigAHgBkmLBvN3ltNc8+6NbPqN7prfovUJobjT5hE/ KG4s1IdXWSN1pP8AZZTkTGyyEqCvF+XfmNW4yecr14ulRaWCy0/1zCyV/wBhj4fmjxfJN9F8g+X9 Lvl1JhNqOrICseo6hKbiVA2x9JTSKGvf0kWvfJiADGUyWR5Jg7FWHeYJS01446gMo/2I4/wzQayV ykXVak7liOah1qP0ZK3LN/Kp+8nL9OPU3YRuzby3I1J4/wBkcWHzNQf1ZvtBLmHbaU8wnWbFy3Yq 7FXYq7FXYq7FXYq7FXYq7FWKatH6eoTjxbl/wQr/ABzR6mNZC63MKkUJlDUqW0np3EUn8jqT9Bye OVSB82UDRBZlnQO1Yr+YOg3uoWNrqWmwQT6torz3dkk+3JmtZYuCuqSMKs6mg2NPlkJxsNmOVFE+ TtZtNX8v2d/asGiuYknjpv8ADKocfrpkYHZlMbp2QCKHpkmLzXWvyws9D1VvOnlq4a0vdKtbgxaT ccprAxmsskcSBka35mu6EqK/Y7ZWYVuGwTvYvQ7G7jvLK3vIwRHcxJMgPXi6hhX78sa1fFXYq7FW Ma2RH5/8qTbVlj1K1BK1PxxRTUDdv95sHUJ6FluWNTsVdirTMFUseiip+jATSksJuB64lDf7t5V/ 2Wc7P1X5uolvbGXRkcowoymhGa0inAIpNdCiZlkZQWZ2CqBudv8AbzK00bcjAGdaRYNaW55/3shq 48KdBnRaXDwR35l3GHHwjfmjsyW52KuxV2KuxV2KuxV2KuxV2KuxVj3mKLjdJJ2dKfSp/tzVa6NS B7w4OqHqtKswXGdirMbOX1bWKTuyAn503zf4pcUQXawNxBVcsZPM7yzv/wAvdQub22ie48mXUr3D CFS76ZJK3OUNGvxNauxL1UVjJO3HcUyjw7jk3xkJCjzZlpnmPS9QtYrmCZJIJl5RTRsJI3B7q61B GESCDAoLz3fCHyPrs1u6mVrGeK3IO3rSxmOIVHjI4GMjssRun1vCkEEcCV4RKqLXrRRQdMkxX4q7 FXYqxbzkfR1zybeVp6WsmF9zQrc6fdw9B/lsuA8wkciy/LGp2KuxVCatN6WnzHuw4D/ZbZRqZcOM tWaVRLFM0brVGa0t5jWRAx8dwfwyEoA82MoA82U6Bp1ta2EZjjCu4LFup3O259s3WjwxhAEDd2On xCMRQTPMxyHYq7FXYq7FXYq7FXYq7FXYq7FXYqlXmKHlaJIOsbb/ACb+2mYOujcQe5xtTH02x7NU 4LsVZJoE3Ox4HrExH0Hf+ObfRTuFdzn6aVxpMszHIdiry7z1+XEkF/Bq3lKwubZpfWGq2+j3SWck kjFGin9CV47WTjxcODxZuXXbKZw7m7Hk6FALNrWs65pflJ7K9tBbS2mq6xcagbdWe1t52lgRUgd+ ZlntuPQUUGtTkaN02EiretZa0rTLGH4FgGpWh22xWmzIiipYAeJOKuR1dQyGqnocVYX+Y18YbW0M i8PqOpaXfwyA7NEl/BDcA1KgFEmr8iMjJlEM7y1pdirsVSXzHP8ADFAO9Xb9Q/jmu18+UXE1UuQS PNa4a6NGkkVF+0xCj5k0wxFmkgWaZnGgRFReigAfIbZ0MRQp2oFBvCl2KuxV2KuxV2KuxV2KuxV2 KuxV2KofUIfWspo+pKkj5jcfqyrPDigQwyRuJDEc0Lq3Yqmnl+44XbRE7Srt/rLuPwrmboZ1Ou9y dNKpV3sizbOcxldY82XZmudJttPubRJ7m2EFzNPbSBrWZ4DWVIrkHk0dfsbe+Q4iz4Q1K/5jXS8E Gk6RyFDKGuNSZajfiCmnio7V+7GynhDH/Jmm3dv+YnmZrvUbjVLiKCwt5Lu54A8lSScpGkaRxxoP rQoq/TvXID6mw/S9BybWwn84bm6tPIuqXdnLJBex20gtpYmKusjUCEMKU+KmQycmzHzSvW9Ci0Dz j5chsby/kt76O/8ArMNzdz3CMYY4zGeMjMNuZwTjRCwkTdvQdOYGyiPgKfcaZMcmEubCfNug6he+ VfM19cAreNpk4sI6k0aJWljZgP2iVjDbfs5EjYsgdwz7T7yK+sLa9i/urqJJo/8AVkUMPwOXBoKv irsVYnqdx697K4+yDxX5Ltmj1GTimS6zLLikULlDWmGhwerfKxHwxAufn0GZWjhxTvub9PG5e5k2 bl2DsVdirsVdirsVdirsVdirsVdirsVdirsVYfew+jdyxdArHj8juPwzQZYcMiHV5I1IhRytgvhl aKVJF+0hDD6MlGRiQQmJo2zCGVJoklTdXAI+nN/CQkAQ7WJsWw3UNSk8o67eT3UEsnl7V3FwtxBG 8otbziElSRY1YqkwRXVztz5AkVWsZbFujuPNUt/zF0G7T1IJCkb3D2cJmR4jJcRKWkVQ4VqIqNU0 psfA5HjZ+GxTyTr/ANev9b1qwb6zFqmuNEksQ5Bo7e2hhXjSvwF7elfA198hE7s5DZ6JoVzqdxar JfQGEsiFQ1AwbiA6sv8ArCoPev32i2mQDF/ziHLyhPGSeMzwRN8pLmJCR70bIzZ41X8wGZfNXk8A 0DTXwYeI+qMf1jDk6McXVlmnKi2cfH9oVPz74QiXNXljSWN4pByjkUq6nuCKEYUMf/LGWRvImkW8 rFptOjbTZmPUyafI1o9fesG+GHJE+bKMkwQWrXotrVqH97J8MY7+5+jMfU5uCPmWnNk4Y+bFs0jr nYqyPQLb07QykfFMaj/VGwzb6LHUL73P00KjfemeZjkOxV2KuxV2KuxV2KuxV2KuxV2KuxVCanql nptpJdXcixxRqWZmIUAKKkknYADqcqy5RAWWE58Lyi5/O3V9VnlTyhoc2q20TFGv3dLS1LDskswP P5UGYMtRkPXhWUCPrkIeXMoC4/MLz9DIZ9X8oPLF/uySwvILqRVA6+lGKtt75jziZGybLTLDjkdp 7+5SsfzUvtSia50vytqFzZ82RJmaGIkrsfhLHv75X4fmxlpYx2MxaI/5WB5i/wCpPv8A/kdB/wA1 YfD80fl4fzx8imOnfmz5js4mjk8mX7xCrCk0FR4/tZl6fN4Yo7hvxCERRmK+LrL/AJyAk1WOujeU NTu5YzwufUeKGKN604+qSw7dwMyPzcXIkIR5yDH9Q8z2CS6lrGrflTayBw9xdXNxeWd0KcayuY3R ljrx5Pw+1uTvkRqIk8kxywNAT+9lvkq1sdO0/RdKF0kmrak91f6g1qVSBGZ/XuGj47cVmnSNAD0Y bbZbGm2Vsuv7j6heafB+k5Q9/O0EaSeiy8lgkn3qgfpDSgYZYSwAYV+cGuywaRBp8PpX2r3V5Zrp 9gpCCcxXUU0oIYtxQRoebHZe+VZJ0yFAWdgxvzN+a0svmPyzceZtCuPLtvZXF0Jrx5FurSk1s0aU niUCvKldtsh44kjEYn6Tb03Rdch1K1Q6Zqdu1m24uoik4oeyMG4A+5r8suiUyip2t9LcXer6eNQd NZ0+htnmkHoPHOha3lKRrGvHkGRhT7SNTamG0UkXkjzfaW3mOSwDKtjr31m/FszKZ7HUYHWO/t5F X7SPLWRXA+1y7Fch4ojz5MM1RFlPvOX5qeV/K1qsl7Kzzy1FtbRqWllP+QnX6TQe+Vy1g/h3aISM /pHx6MBuPzD/ADA1SQ3Fl5RYQneNr+9gtZCvUfuXoV+/MGYMzcju1SxYyfVPf3KE35p3ukoZPM/l q802ADa7tnjvYOXZTInAKTlZxdxYjSCX0SB+xuy/NHVL6zS9svKl/NZygtFL6kK8lBIrxLV7YPD8 0S00QaMx9qa2n/OQfl//AAncapJBJb3FjKlrJYMo9b1HDGNFWvE8gjb17HbMyOpmBQA97kDFksRF bjn0pSP51+ahZfXj5Vvvqvpibnyg+wRyrSvLp7ZH8zk7wx/5KR+TO/y88/6Z500X9I2QZCjGOaJw A6OtKqwBO4qD175mafMZbHmzqUTwy5sqzJZOxV2KuxV2KuxV2KuxV2KuxV4T/wA5D61dXV9o/lWC QpFqk/8ApRBIrDDxPE07MzV/2OarUTuZ8mOM0ZT/AJg296Okey0bSRwQRWVjGFjiQABVGwA+nqfp OYUpW6qUjI2UhsPzK8t3rOkMv7xVJVagkkdqA1/DAQRzDOeGcN5RISzy9+YvluGwdLm6QTetKWoy CtWO9GZeuHhI6MpabIP4T8maabqNtqNlHeWxJglFY2NNxWldiRTA0kVzSO6/MPyza3ElvcXHpzRn i6M0akH5FwcRfczjinIWIkj3Kf5dzRT6PNLEweN7iQqw6EV641SJxMTR57fcjLzzlodpqraVdScL nb4SV3DCteNeRH0Y7rwSrio13pZ5w8h+Wr3Qr2W10+3tb9Immgu7eNYpOaCu7IFLBhsa5bDKQ5GD VzjIWbDHvyy8j217oceqa009y0prYRNPMqxIAV5qEdd2BI+VcnPMb2cnWayQmYw2AT+a/wDInlTU GZIo47+UcJbh35y0H7HqTMXoO4BplJnKXm4Znly98qZJFNpWuaW6lUurG5XjLE4BBBFaEePcH6Rg EqaYyMTtsXi9n5Rt9G/MsaUwLWrMGhYMVYxORQFkINaGh3y6WQ8Ngu3yaoywcQ2kDTMfzL8t6TY+ W7i+tlmW7osXrNc3Eh9MByE+ORtgSSBgjlkSN3G02pySyRBO1sv8kReXfLf5cWmviygt5F05Li9u Yo0WaY8OZDuBydmbpU9cjMkypjn4p5TG+rHPy/sLrV7mbzrrf77VL5j9RDbrbwD7IiB6eA/rvhlK tgnV5eH93H6Y/aU71vzroOjzCG6nAkrQiqihHUfER+GVCzycOGOUvpBKSea/O+j3PlG9ltJRJ6qc CmxBr2qCVNSAOuEXdNmHFI5BGiDaf+Sv+UW07/jGf+JHA1z+o+94TqboNRv0LDmdQtSFruQFlqae 1RmRD6fg77T/ANyP6pe9kgeVtzT/AEKn/JLMbo870W/84u/8c3X/APmOf/iKZtNJ9X+a7zL9Uf6j 3PNgxdirsVdirsVdirsVdirsVdir55/5yT066sda0TzHHGWt7aRorhl6gScWX7+LjNVqIeuQ71wx 4uPH/OGyZ+X/ADJputWMUsMqM8i/HH47UNAeo9vvzB5OolExNHYpB5r/ACv8p6rG80KppN+wJWaG iws3+XF0/wCAp9OWxy1zczDr5w57h4Zq+lXmk6jPp94nC4t2KOBuNjSoOXg277FlGSPEHvHkjUmg 8q6NAIw3K3T4ifE06ZhyPqeY1B/eS/rH73ny+XtP17XvN9xemRX07TJdQthGwA9WOJSoaoNVy/HK oh22mymGHHXWVfaWU/lhqktr5ahiVFZTV6mtalmH8MoyGpF1uuP76X46I7U/KvlfU9cTXryS8a+U Ifq0fppCGj6fEebkfdkxljw0sNWY4zAdUz8y+arGz0G7ZlKH0iqqaU3FKf0ysG9mjHEzkIjqjvLM 1jb6JZWkcigxxheJ8TvSvzONoMrNvnrzVeT3Wv3kkzFmWQoK+C7fid8y8QqIel0MBHFGuu71T8kL qeXR7yJySkMgRPYU5f8AG2U5R6nU9pQAy7dQjvNcSD8wtBkA+IxkE+PxjIXsfg48D+6kP6v6UZ+b H/KHXH+uP+Ithj9QTpP72PvQPnK8eD8g9IjUkC6hsoWp3AHqf8y8sj9bnYI3qT5Wyzy1BHb6BZQx fYSIU+fU/jlLqSbNvnPzVeT3ev3kkzFmEhQE+C/51zKxCoh6XQwEcUa67pVU0pXY9sm5T6Y8muie VdPZ2Cr6Z3JoPtHMJ5Kf1H3oe807ycJTKNHs57gnkZPQj+14liMl4xDMaqYFA7KN3dSzQSKaLGkM gjiUUVQIyAAMquy49pn/AM4u/wDHN1//AJjn/wCIpm20n1f5rvcv1R/qPc82DF2KuxV2KuxV2Kux V2KuxV2KvIv+chPNC2Ghw6PHbQ3d1qzi0iinXko5CryUG9U+Hj4E17ZrdXO51/NYwFzs7CAt4yPy r85aXKH0HU7S86erF66Wzhx1BjuSitTxUnKDwy7mZ1WHMKmPx9jM7C11m30+FdaeJtTapmjhlWdV UUC1kQutTvsGNMxMkQDsXUZ4xEvSbDzH802ifX43T7foqr/7Hb9dcyMB2dz2UTwH3/oei+Uf+Ue0 X/mHi/Wcx5/V+O90+p/vZf1j97HfLf8Ax1fP3/gP3H/JhMuh9Mfe7LF/dYv6/wCkon8vf+Ufh/1f +N3ynL9RcHX/AN9JMpNbjj8yS6W540hilQGlCHUVI+TdfngMdrapYTwCfS6Q/nzRH1ny1J6Nfrum 1uIlH+7IhvKhHcqKuv8AsvHLcMujk9n5xCe/VW8p6lHe6JayoaOqDlTry7/8NUZVMUXG1GMwyEea Seavyrv9W1WTUtBntPRujzntLieO2eFz9qnqlFdPDiSfbMvHMEO10eujGHDLoyjyvoo8q6Ulhb3C T3jt6l9cRCsZc7BE5D4go/apv9Fcx8s99nXavP4k7DH9R11r38w9PXkHNqhJpsKkrQbf6tfpxA9J LZGBGnlLvI+xlnmm0uvM2g3GnQPBbTkhla4k4IdiOtD444zZatNMRmJHokmseX/POpeTLXyvNJon 1SyWIRTR3EhmJhFF6qVqR4DMgcIN27GGfDHIZgmz7k88qa8I9Dt7eSKs8AKSgMKA1NfuNRmITTqZ kCRphfmz8rb3V9Tk1PQbi1KXJ5zWVzNHbPE/7XFpSkbJ4UavtmXimCOf6Hb6PXRjDhl0SXUvyl1X TdEutQudQtJLm2X1PqVsxmJQGjEygCMUrsATkjMd7kDtGBkIjq9A8tknTNPBOwVaD6cwf4nQT+s+ 95pqGua9Hq86RXAWzhuY4CnCMn95UgbrXohzIjjiY27jDpMRxAkerhvq9Ri/3gP/ADDt/wAmzmMH RhPf+cXf+Obr/wDzHP8A8RTNvpPq/wA132X6o/1HuebBi7FXYq7FXYq7FXYq7FXYq7FXzd/zkKNa 03zlo+utBJNplmHo6iqpKz1qewqvGletM1GWJ4pDra4YccZwupFjln+YugzxgvJ6T91cFT+oj8cw zhkHXz7PzR6X7lmofmLokMJ9GT1ZKbKgLH9QX7ziMMinH2flkeVe9LbLynrmseWPMPnO/tnSEWvD TIyDVh6imSQV34rGG371PhmQKjQDtIShiMcUT13VvL/5haLZ6PYW0z8JrWJYypVzuvf4VYfjlM8U rtwdRoMpyEgWCe8K/kMyavd+ermxieWKXRJ4YyBuXaMIg+b8DTLRGgA5UsZx48cZcxL9KV+UfOej abpEdtcuUmT4SpVz0YmoKq382V5MUjKw0azQ5ZZDKIsFKNd8xNe+ZzrVhG7wWkcYlYKePpgiMk16 BuQXfvlsYemi5mDSkYeCfOTMrT8y9BjETtLV1A5Blk38QwCHr33ygYpA8nV/yfmB+n7Qw7RvMdxp F7d3VnBJJobTkcgp4xl6lQCdqkD7JO9Munj4h5uyz6PxYCzWSmaW35haBLGGaYI3dWqp+4jMc4pd zqpaDMD9KXax+Y1qyfV9LRrm5k+FAoalTsB0BPyUZOOAnm34ezJk3P0xST6jq/lPzJYX3mSJ4pb+ H60QRVlDOV4uB0YcRVRuARlshxRoOfmgMuEwx/wllP8Aysjy7/v3/hZf+qeUeDLudV/J2b+b9o/W 2v5leXlYMJdwaiqy0qP9hiMUu5P8n5/5v2j9bE9N85z2Gp3V0kckmlzTbPT7LEe+3xBa8a5acNgd 7sMnZ3FCI5TAZfB+YPl+SMMZ1U9waqfxGUnFLudbLQZh/CgtX/MfSI7eSO2/fu6lCqgkEMKGpIAp 9+Sjhl7m3D2dlJ39LWj/AJh6FbafbRu/CWJACrLIaMP9VSPxxOKVrk7PzcRoXv3hiNw0t1aalrMM LtYpqNpykp0PCcgH50/VmREUAPJ2+KHDGMD9XCf0MzX8xtAWz4CQ8vSKcSsld1oR9mlfpzGGGTpv 5OzXy+0PSP8AnFpJW0PWboxssU967RsR1+CPpmz0o9fwdjnFTA7ovcs2DB2KuxV2KuxV2KuxV2Ku xV2Koe90+yvoWhu4VmjYEFWFdj2yvJijPmGMoA82A6p+QP5a6hK0raYsLtUkws8QBPgsTRp/wuY5 0ndIshPIOUj96/R/yG/LbTJlmj0tJpEoQZi8wqO/GVpF+4YjSd5KmeSXOR+5nL6ZYvZ/UzCot6U4 Ae1MvOCBjw1swOONUwyT8j/y2kkZzo8ALEk0UKN/ALQD6Mo/JjvLK5/ziyLy75L8teXbSS00mxit oZq+qEUAtXxI65bDTxj52gxvmb96Q3n5K/lxd3UlzLo8HqSsWeihQSepoKDKzpB0JSDMcpFH6X+V /kjTLK6srXS4UtrxeNzHwUh18GqPiHsdsRo49SSxMSTZJJSs/kX+Wlf+OPD92D8mO8suKf8AOKe6 d5A8p6fpL6TbadCthLX1LfgvBq9eS0o1f8quSGkh13YHHZskk97Fb/8A5x5/LO7nM36O9Ek1KxSS xr8uKOqAfIZE6Tuk2jJkHKX3J15a/KXyL5dlE2naZEk6/ZmYF5BXwdy7/wDDYY6SPU2wlxS+okpl 5k8ieV/McaR6tYx3CxmsYZQeJpT4dtvoyU9LGRsbe5AjRuJ4fcx//lRf5af9WeH7sh+THeWXFP8A nF3/ACov8tP+rPD92P5Md5Xin/OKeWX5eeTrPRn0aDTIBp8hLSQFFKsx6llIo305MaSFfpYmFmyT fexW9/5x3/LO6lMn6PMJJqRHJMg+XFZAo+gZD8p3SbBkyj+L7AmOj/kj+XOlEtBpMLsQRymBmIr1 oZjKe+I0g6ksZGcucj9y1vyM/LUkn9Dw777LT9WP5Md5Xin/ADindv8Al55Qt9DfRItNhXTZN3t+ ClWJ7spFCfc5L8pCut97Ews3Z4u9I/8AlRf5af8AVnh+7I/kx3llxT/nFmOjaJpejWMdjplulrax iiRRqFUfQABmRjxCAoKBSOyxLsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirs VdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVdirsVf/9k= - - - - 1 - 1290 - 997 - application/pdf - - - eitch - - - xmp.did:be7b2f93-07f2-3948-b5fd-71d24d8d1422 - uuid:09f0d87b-93f4-4400-a832-74db1c265615 - xmp.did:c7e05c90-7445-1e47-aecc-1d2f5d61dc5f - proof:pdf - - xmp.iid:ecd0cf9d-37fe-324d-b6fa-b694457058d7 - xmp.did:ecd0cf9d-37fe-324d-b6fa-b694457058d7 - xmp.did:c7e05c90-7445-1e47-aecc-1d2f5d61dc5f - default - - - - - saved - xmp.iid:c7e05c90-7445-1e47-aecc-1d2f5d61dc5f - 2022-12-05T19:23:36+03:30 - Adobe Illustrator 24.0 (Windows) - / - - - saved - xmp.iid:be7b2f93-07f2-3948-b5fd-71d24d8d1422 - 2022-12-08T10:30:23+03:30 - Adobe Illustrator 24.3 (Windows) - / - - - - 1 - True - False - - 32.000000 - 32.000000 - Centimeters - - - - - Ubuntu-Bold - Ubuntu - Bold - TrueType - 0.83 - False - Ubuntu-Bold.ttf - - - - - - Cyan - Magenta - Yellow - Black - - - - - - Default Swatch Group - 0 - - - - R=53 G=25 B=5 1 - RGB - PROCESS - 53 - 25 - 5 - - - R=34 G=39 B=35 1 - RGB - PROCESS - 34 - 39 - 35 - - - R=156 G=212 B=132 1 - RGB - PROCESS - 156 - 212 - 132 - - - R=89 G=154 B=62 1 - RGB - PROCESS - 89 - 154 - 62 - - - R=116 G=181 B=89 1 - RGB - PROCESS - 116 - 181 - 89 - - - R=79 G=42 B=17 1 - RGB - PROCESS - 79 - 42 - 17 - - - R=186 G=239 B=160 1 - RGB - PROCESS - 186 - 239 - 160 - - - - - - - AIRobin - Document - Adobe PDF library 15.00 - - - - - - - - - - - - - - - - - - - - - - - - - -endstream endobj 3 0 obj <> endobj 5 0 obj <>/Resources<>/ExtGState<>/Font<>/ProcSet[/PDF/Text]/Properties<>/Shading<>/XObject<>>>/TrimBox[0.0 0.0 3628.35 3628.35]/Type/Page>> endobj 28 0 obj <>/Resources<>/ExtGState<>/Font<>/ProcSet[/PDF/Text]/Properties<>/Shading<>/XObject<>>>/TrimBox[0.0 0.0 907.087 907.087]/Type/Page>> endobj 103 0 obj <>stream -HtKu -^J|?Wah4 fs}du*2Oß~G xs CF62珿-_%GH?g^wȿRW+zq֫j8U k%veǙzc]f#|a_YЯObCζ|i:@+?Y% _&ffz?_oX.WJY/+G+pgOq՟ 5qbV8YDb8BĥxLţ&*9-d]V"mPddGse뇅ȟ޽f3BrO= R!!DeF/$ -Kk~X?9=o64`0`,UD0R%$}JzuQ -D5F15Nk'Qp7 U=I0נMq=.>W-<=Q7J0'ԞpVZ*Jl)fVX.+[ 8MɧLW#:=D&"q%);mfqݫII/OhsmT{7Ei5nCC<.଒"1o$ 6/Ue -j|KYVGW QNOsni&\l.:}>5P9as/|c>ɪhU s'FQ.e?7xl6b{>HV}x1%Gjr]j"+f'y$o]!NLʨKY(ILJ:EQs5AD --ZxȜ&}ƹԬE.ZMEM85@ϺPprBN˨r( oqosp};; -נyg -k:C43yo͗dltS jr]P fQҳ}IR Ȫiơt=o 4 -7 ib֨>𞛢u)/n_$MJHCKźBT|RI*HD3T ͤer|(}к(Y5Iׁ䌙JםMꎶ EީcX5Hx]oMD9H4n@/Ge)5;<Y-7Ov\+|G--+co;mK8%3*>yɾERu%2 J}*efpCBРTO*KNԹX%AECψ*MpbwZ"V4v%Vpj?Yyo7opz5D~ti=|}/Kr*+rX=,;pLy5B-! FnAg}f$*< -śu(321Vjn:jdr ?,8@٩lpr(n" A.)cac4^aQyʍ(oaAkLgcN6@&)[]69l=yk"HOBpba:U}>DوrFL"xVWމ|*x׈:{t5$ꢫ ]12 9)q@=:jVB,
SPZˎ0eoǤ;e̓Vjc!H9rv+7 ,ߚLnڠʸHÕu&TFN RDl jwi.ҲKa6!kxl&2Tj?W"%&[nX֏mL."S/t\Ek]łp&| TpwQ[^WWJevU 6Z|Ej$VEĬ{ήz->H,>X -]v~FjG&H_h,pn]~|?kK"st}Vetm -q1M)6*/m4~UsS`=2r.v*H30Oq ǒxvWi!z6n%qlqN2bAI5-{7UσLAgܧ-_ξU&jO&Pt>cfjvkbqƼlm8+٠yx.vxzke`헭f$p/H^vTڟ@n0TMvPU:!tg:4\*y د* -]E+m\cpi9б& -<9P. -JW?f"pf/D!=k{JxfcY:jrF -b;\` SK$ڮ0ɟyəu >ab{d~#zL|zBv^c ?>=&+}z|ow>HcXe.VpG??(AY DkaF\8ZfE 1Wjו#+F -RC>芜l&THs<&-9}̀:U[z -$V K.c-Uֲ3|2^T%|d "]څ#j7T" -ί!{'3K]p(ԲF%SQ<kp2xpm3. -F!M YѶBnjY|@Em~f6?X<5ۍƙEVTi.% %lVBmn-,QWݶEI\Tq -k{u[N9Bj~vc0!tLa)z 羰q3KTdgI=ʙ..x.H%RL-gZx%[dahERn=PnAnGI+GX+BQSɔKBaNf"pm_m߹-GK -ͪ`tQlZU֪ lВ֤|ps;u5N!`d[,0ݺVІWɐJ[U] 75iZ cY"O%8ݚcDQgP﫪:ⷙxm#=& -S T{}cqd &I!e%Nzu9ӐԘ -ksTazث 0XW˭:DdCMU, eHz#[4u[ef|§\-Pt-)Q~ZJGo:6 ÒY=%13㲦 xUej<}f(wK|1|kp 3;fe#}N642-W5CQ_>lY5lE|U[0]zviCpҋ|n'x%ƪp1̓=7˲Lэ91;*XdkPK8&VD Tayt5BUt.AQ -;qDe]pd P k=ܡj-G5!oX$xitMtB9 _yNՊy"I ^U[X^/<f<h,<8~C΍f'R7pF2 K.pBPow ytUR::w$V)o+ä8VI]߾u1/6TG`'`3kD(_x,^؋?exioBk oN)FKbԿ5-%}Snf1'_}TW%P#B͵}ې41 P&Qêgu*H-^m.s_ߟXhVx,^h~ -!3~8xؒ5I[8D^m:[Yy%3FT1ZERٺ>" ,f1ȇ 4'WQ{~#X#m)JuŽ+-O -9I쬚zgl{hF -~\ Ԡ74 NU.|}N *a&NmlE+*ےXMKh%np).hӸ_PvF}^}ca:ey^C2I@wwBa!eQ<ۿRyPtAC?#5ݬhp.b -tٺwR!\Z%K(<"U,u1UA QCn?#2.Nz ]w<'<~ol'(kgCBdIbKy:$2ܗ*+nem7 ->y{':+hRLP!09$=\Z%]i%%L@EXRDP,]hG!?Ul_8Ž;FLxDyYdm'3ZHNcpG4$|)&eaLKRXDw;\ т?%hgp].km$Sw XY9<+~R3zjT[sG]0 -be{bF*ą$+7wBSN9nzqbBT]E0eZ̐_UlB&[牒 -Z2E(ȢpC4t -ƴ"ְY2]UIJ=`ܦRI^19{wZ 풰(u!t)`_v% X ITnmg!10L:@D@qfrKU#y|H,T}?qbX^[C,VJ/7&)įݠhknGS4Eq*"2YKVdY'6T5jT:TVdVòw5r4i7EISz"+,k3'%pK0>ZVZTE +g`@ε< -$I%I/Z'?ΦH-msxmXRte}o=:hF%iek*mkAgǭ;T=h9(dll@m]Bstz.S҉nI+X #3 *BX/XU-Qg*~haĞS.0PJig;\MVB:3(~\N&ٴ<{VmBӝ_j37‘S#ym'\1V9\bۯPC 2 -"{J4F/T\Eؒ -UAzm', iOY2p%h#F#'%a+z~:Beka4$gHmŰx|A"~%d3^I O?{|OT'>?tQR0JSL7oj%wK X~wR\N_o%>Fӟ跿?%VMx%O߽WF?vzB{%Q68oW -/ - ^ 1ˬu*xv<OD8ԍų", XaHnlЮc\gcG'TQ܊O9K*J 啾l0ںYUB-Z3 =e?QgX禎vCdOQ~jd7$E| t*HVL' @CZq<,T}R6H ^kL/--z"үpũU2<'M K*NLWbJW9@ 309mTEflGӌ Re@NNN ^#[WBO6X9S'JKq\8#=m^XُβU4t'uR^:_[)v卆9PTkYK['zQ8<=ZRht{ө[.^m6s4 -YbA',B(VLnBդ+ kXyrZF!3CbU$?q jマUa~7Ũ[+83ЀԆ -܁ecMQW˰4 SmN: :DF]Y$GLXa4R XװCr0/ "il:\B !ҀjB5ZS_$&"u45k]o JWN@w.f{:MK}xĤH4Q5^N߸muUHkUn!tq!cqu[t+,e!1Ta_֩_+(S -<k!d ムjoQwD|oUBw8Uf{k~@k$  ?:b7L*T{q5C9_]>54O,{XCR2#]rY/1l_ej/e#mEѽ" bkxx'־aH 9Qi&3;p!XIϠ|p0WI"%èdNnY*f O\RnmU9g+Qπ^ֽ8~ #aBLpФ}lد"ѰvxH+/Ѫ՟jՂ$BuDsR4_DJjnL'±6cVK/JqR2 -rÙۑZJD^h[Z"XёWl$'Jow02`!`6Ԣ{["Mφ7Ko{{^8 Rc>3}rϔf6$TٛیEUqNE!~E@8;y葼ǗTL}q`>45;"T0؂Z; ^A3p:`ƈ/u5j8FON([I-0'B+}ﲙ4L - Sۦ Szneu0J ϻg@TJkl=POkET~عbDpGiHYmI"Ls Q/!HoQ/uR#\^ѫhN<ߌ:JdR _nfͳ񯛛swM2o즗VҾJT -jΜgw5걕JW Ԡf7+!]E[f_6>sε:}LJphva9̗ 9,np̘txe3s2Wgҋ^oDM -~O,OA?aIڹ3'a>\q `Ä7 $ha?_Ǘ_Kv<`^&i}HI bVKp?0{tp+܋y?E:*`QIyMͥ^}7=۞IkriܙVDm>bO^ˏ_[[ۿ\~h/q -ho EXѷ;Bl⌰ٓ>囔[`^ ;Uoʠ)ҟk;k4MlU63Tܑjwp5qBcޠw($SA7PRYSkc1P߬'r٪;yK8 ,ql"OerC ؓ(m ԁdWu3BwJ ־gLw6z}l^9 d^5:̧*VF"$.>I/P-V\3^F-QVদ6dV))D+sm>0˳i o1k;?ƺ߸>Fz+AbZIl#>^$g@ñW -я+Y%sSsݳN~f1Z)8ǺDӷC Z؏wky-JS,ymj{!r\@|hFA|D)oU[2Ǫ|3b)YQ$'ڷșXuK ]X\@grՁJcut1WlUPҽY:)fH+hZQʋ*f`NN\f[ /qxzdD`aK)u*Ɓ -(ƥIov^v,kk,Zbe;$Mqu^e0$֝ ]jDsqC.qcqeǼ -ھM2X׵[򹻘bH;@uSX%?LF^Fo{6:e)ҧ ~`$J/v#u)锚 Ô,.=2Qfy|)U_8gfڗF5X wþąS!T)]qyn$܄ל3MnJ-Wr6kr?wFofvA3˲x-HSZlz*P\Bw-;e_rqѴɡ#+}KXdvIŊjsid?!S Tl -rR35QoVgoԸs MhUEk\{2R1ZPE,{{7DĭȌklk|)f2IdׁOQ/ywu<[%Y@tf 7C>FvP=ͥn*դ~hv;1YѴ9}-F)'eܣ}',$I_!~FbRjlPڦ?WwuN+[lEˀZK1 Z=`MVD>Hf/>r67Y}j͚xbGxvPZy*y "`y -+,ўR zKO?iP}kwT˲ \QLc\l?N]c /|4:w=.:1ROF:"o5@^њ%&ݧ( ~peY#A'v -r1K򻀧[] mMTV=c%) {PLBܘש2Sݦr:r6 ֣j%UJQ&}<Pf9ڱJgŖ2xV -&|dߤMG%+jrn1>kFrO:OkU$ڴf 먉WӀtu: -8WKAMhY"{$t>U_ek+mm;x^Mq= -*|r9 q(B7ᲃlPImO`]f;];O¥#z*V<ۤƲ) r]C3cjfI2-Ց1׈$`ˮ۔gA -@d;{ .POpQ>jMmq -_ْ<%n4lU;D&AϿnCy83m4远)k(9%oߙQz՞e7+ĐSi\uUSLC\"Q먭ڮR<r)!Cъӝ׹@ޟq?{MFmIy%+iAHF.u%NUBRhTGƌgewR][AU^Z8F"?(6I*SOsZ?)kf{F9*1Y(Lw!G6Z(ɪI9{}ZmN3͆? XΖ>&uYn(E"Cs *T<$]Cd﾿.UDk*Q>Z_: ' p\|H(L ӒQ2-]?l# 9 M˃M_wy;>4dqD=t?*v4߁~@#XrHkA6zW14ZlyJk, 3XX&Sp1 R ?tJׯhxaDIKA9D{YZLWLOT)@1uՇ!?fO*}0+rY$2Y}F,Q1zTde'?'?#C@'Uz8f[ޘd:1V;9G:Y>M{d~-9Jm2OdlI  W#+r)Zs%M>R w~1`Gsӏۣ?]m# bGl1_ves; -O ^50 FfoVnVrKTSnX= %iݴ?YmLi;G%̡)"#h#mjgo#"V - GYf -Nh? ªrĶ6\H^Y" -[Tcz/M@ׯ\2RYK/{ҙav Z{?byU؈v ?>C\Z.;r+9e23p_GKFŌBP\kMwn;YWhV+lFUNh""jTq)BK_P)&! ]4=LF rI2ȼf:{Yzfk IQnPꪐj# .J ҦO8ϨJ;/uB5L2 -5?9|gD?ĺHrtL$(b칳7'\AϺH#?;xѯ'muqWGLz (ʯbtT "d3%D= ȽFXRa AZϞvUvWܰ&qb6|pAvl܊2;[l1G')>lu()uԒ f뽅~-\㞛3TiF,Vs΀LV*k!IqS F<(D֩(WPmY5`ZqaYrΚ3J+͑fU!V<[6d2M6* ]< DZ-;/%/v1pԐg@%cF)]~^{;\"<5- it#ˁASnHPjLNE Te4ꕠ.8T1EQ \ DI rAtT߾h?aT0kQrids6oOA=VsU3i6&gg0V1^y/e& ܧ |ڗ8c8Dq'ىWhtpG5{Q2Cb-7y=h`OTR,?8wT>hPBot>. =5׉u_kSo"h @|:U -a?H 0>'3)e [Ӭo,z^\T 0qܾ;~KZ-N;1W *rB>q&_ͨe&voZ;U@ҵFtV td:BdI؉2q dl}B_)NYrX.+ۖ3$L~'m$CdIGpy@>T'_*ϯQX tGU#%&{{_9j>sշ:J@&3D] - b腣CC.:9eH"i2CB[т ?Sݤ/r( P;]E4@ase52]“6&-UyBDq}cfъ%D'&*,_G:~/\!.(bcցz2g+l9V0p@]glN Κlb(A >LuN[.}vt -ȆrQL̼gQH>@,qÁuUnRQRrlӽ[}٥Q^mؼ["S*ׁTXT UlXa{mRcqM#iGq^iڻz[ϽVP͌l Mhq_509o]6 -TTksOijoSbm #,yr&2gضϓd3 5q;3܇" ^2 &ThMCH( l`e'M5i2ë 6Dp,Ϛ=ƥI:*C*VIδcBHi@!d2aaj%xVfѾ_lzm Y8{M@1e?Z5c^M ;!&M. -d.[L:|ӑ3_MO;E0a.…%8 L{ ԕyrphNW'P-v,RME? 蠍]i]LbS4Z 2H`x5W> .QS 1C+<2;()vhw˿dO&>oвf蔌gE1ؔm.NWA(ϒ;PW#IQ14)n=.M؋,| ^$j/㎤6Ytg *юxZQ]8sVܑzYm,+TCHc`eNLJM um(T5O\͕lh9< 1:ѥ6׃OTݔo0d85Pp9e&|%Eo=ymO@J%!k%"=kC?ZrZraAsU5GJ -N'%pbǣjkWeٮW, 7辷D?ռ6xRm ؖ_(XRIVT A -25wf頦,h} ↵c>KUlk5WnM|/KpC+#ݻtC -z^Z؆uOQBܮBYe z=FYuQZ{s"B4٬752ftV$$-Uq;Zճ8lӓVqou%P-fZå <}U E͐ѤZT*ݸUjUk" odo?7&Y(&EߊxW"0XalTS ve6 _D%6yFS-ԦCiUj^Wȫ"ѐۈ~-R(pBwM# 8Pwa9{UPcm뵕smg\="xΩoL__C极B)eMoP0 kbdy*'$-F*R"5AiEV=Y=@é -Ȯ/UٹϏUo_UULC>n@ODbH5}̞;l'Ba NDSHxcs1060M؃zPgě+AaönEj"@ΚdjOtP7 ,%SOmEsv/ygK#U橑U586D5#$` n5v4)ƠKu_lsf2ɱ8N/Cfdn m - \tKx@gZ-v3Fx:#JOl1p^ޣ:Ր.kޖ xQ퐋$A:61.[#c+:tua\nxh}[vm0 9eU'uf.* =F9CRP$9߯zR_ŘvwGZ m5Z$C<H&ɚtA#uE=M%Ȣz2i5\Ḁ̃q#OҭTDUo\pÉjb*hTUxèsu/9㺽|ՠa"\$$Զ3')ʞf7lnL)$ -'ؓ 1V@p(b/8S&COPϐ3n(eO/BnRY#0*}h^vBvxc:G+MbwV'xZma6xo2Y#醉4 *zM wOә6bwΞR~ڕ}Lӈ; -Ȝ=γ#֊/Ie$ͥe'h-wi!{w0 u2,GõYτ*M"5j- -PSs5軭'8A1UZ|j1*JiRn-Ȣ[yRC*0[SO&t -&8>6Q R =(p2bEt.&`\Z "4ǶO;V>룟wK?=~C{HP|?MM-l#|0Oկ!g,&[ [H䟽m{2;%gͥ "z YWXQwlq @ҺRw.h@\,}4)Ft8(Je<ХUOy(=*m/YKoB+6G4e_4ޢĵw-H8l>L[,nC m;" -I2NZ}IԨ,ɩ5ET_r 6]#[nXB짊#w!x"2r:(BvET7/UѢYJctHDP?V袒 -S:r zdQ$ b11CiD 4Y˯NԅMⰒ83rxU"ٱC$Q،Z3*ћS.mg6DZ JxҚE{/:¦۹2&Jy|$*XW6}|NgQ5˘jMDʵW.4ك$x'hlQuY}Fgn$6/½!ͷ=&ZG:Sa%sYׁ]-d4sǗ%O'v%YW}ni@pzI %Zq7d CIRBn![@m9&J'x&?Y^%p=(7\.L8U++䑪$hXgi"rib*]h#· ~+i2x~Yl!",OQ 0:2NS )LúmUF%F,xu QjFID DDMֻ{N ~A4)?^ --l{{0$xWsR'kmZ=ZkT6Az1uhʪB)W7ڣt$"hd4XUiEv(ɳhOb -Fdrp#鄋 ]Mq{|~3wHnH]VG:L^-Оtimy-Jh#PfXnTD~+Zu tgt50R ˍbk -$8Jm~G+z -ُ[Wϔ[ Dl%) ׽"q6B~ݷ8pGy@+Yw&SɎZIƫm%%ky.1/ⲣ9/ 6D^`?rʅ-| r؊eg;ƪ+WĤq퍘x#3q[йf'LY“ts&ҪP&*ֱJ2RZ3KB0QD8K?׷/ަG,˂vPrPZ,Ƀ𨭏O5>-{]`hmS&'b KWk=|V~ќ]MО=Nu{dr(x2r U._/PK/|,Ţ o#@ؾ F]%/u.xiC=AÀP{0syj(S6<-OAX$߫ZR -z9Ҙ[-5^N1gի̫%H$ZBw5'rUXsWyV ïRw hQM-WD צDg'ҡp?0gS :Ս71裡npn8NUR)EW}./Kz^3*ǍGҸWUbŦRT q]tRK;1Y49n c)Ee3xV!?Ovdd'KN\k%vz¹yzbԂdLʜt6arڲݟH'Ȅ$_HaM ip䀩l[wXW杙̴Lr3x?cŤ Nx| vt6u< Xt?zː꽹Hu,/Vk5/y%|^EB6O7<8j\2XYO|Daװ|96c ಜO,aʯVcْ4j><1r:1G_j5lqN:8B# # - b)ٗ. rjwUMǪ/s˚:qICj'rD;E=!͑KD 1 boҙiصGbRv.h:Wk%; t޺`.>?_; >Bꦊ%U` JatziQ'W!e-5aBgmղgd='_%  -2 o?FTLÊz|g0=*n` -pRJz -juM -fch7UJ~"M2-.7ڥ/lNjqNtDBbkx z\l$ANQ9MW(z/ܞܪh5;9񐥌ǖPuA}lUOi%φ"+nuƌhٍ4/*%OUq85MX#VH-8\ր*կ|dh\ɌA]K8!ڼμ׹w=Ja|4p+B|~y8augDV#:frujVՙjsV(0et%\5;x>1QHf4 -Ά!Ţ:H: -O= shMUy_L Am]#XXfSb)y͜T.p Qr -8\H#,:ܜA+w ?D_ -i-?%^׋ߑdRv_Cr:2\F עtwMk "O6A,svp,OvTZ’Z^Ž'^i Vv0z7@-$ d -GUe{ׁ$F7ս@̶/G:^LVjݚG,dJӄ& 8o`: ׎)9 ͶI)9Ć,KkX&A+:*367crVS5[@`p-Ͳk)~-jm^#]?4עQhBX#V}Ahr[Ö(h} VLJ?{mkj:NFKw6=r - O6^4X:lJ!Y yd:7 4iJjy:c хvD >Hba"nD:TUXrӰ/7[Fgхd8͢y -usuD0ˆB]#GYӊ{8kDu""emiX[P~#0b6EkΟb*ڢ1H)4V84{6@OD/G7\^Yu,T2p1Q2fMU k@Yۗj&0wJ̀o;8~#5t1:I%%:.CQ~su{jf{Gt5u7@]x'-3Z -=.ͽˑmcl 3 C=F/ !n!Ldz1^+_}ECμ*H=hIs"Uy^62N@^΋U"nGooM,߸,tf>)}Wvbs[cv/3Jw m84Z0W+IIr 4j@~>k"0a.K}!:| - wN)5f*UCǤpP'caVv./KK3O5"ru#o|k1RP*?JoJd8oύ ƎG$ҜD9w6'l0>}(z)AOPKxQ;Wb#]!Ү3&4ǩY>6IF _k$Q #9,26p 6&4"!7qU@ 6:/߅SD/v_Vd=N! #rLIij/R>jJ.CDÚom-6"}ׇdj+MȌ bH} T 4^iW񄦾f\׵)4mM0I\(>2Qp>=:ل;t2z4_?$o!5Q4JSVA>~##9Cvwm~GzPf&s۱W;JFթgVJZ)O{)8 V #6(z:P VJSgM\ [)fDne]jVn'X>N[d=ESk{K#M3P}SD-c[< Mdž.f nw֋T"yT$+5=|{껛aNm< ]O 1Wvi% V:͕4~ T\ϙ`՗/ϳnꓡRc>(;łnwDvu>+Oe\k@MWC%qV<35ǜbU&_rY!3Z=fYf%,QS!} m.5UbȨGN(%VO RCP+X>*rMd| -ךޅkoY=e9!"Ⱦ@+'byݮsXƋDLÑ#EftrwnE:ʻ[2M)EΌfw9/ا]j+׬&l4"q8غ&26dBOۦڳ_)A< o\AO!HHljEtQ%r2)vPW"#24W@u@E:% -h -*{(]vu$I0xSzBy(ێ?&bJTR$vQ C=*TQJyaRL8Ggo񃉢$|M3mxvEzT%`qj NiYX>V9j%x䋞f{o /@˛;7"X:\j.HV{L:vE9CY>\7VK'S,Ouw4Tl3H5V>% v#߮foցryRk3M+뭔YS܄54ʨ&OjCu=I&uni{!#,b7ʽ#+}m%bڌDO prߙ\{']bAIl&'M -}<7|VzvD8Sa䂡El10rv{}35zƜ莅HA0ce^MK)',yᶸMMUM˜b+C!KQI[NcrZkL3Ey]G}0PzE@)u`rzVU-kLm#Ѫ~r-Nj[p[5C!zg*OIAw3^0@`wmDchRt(V˰bxj$ ,uQ@8H(/a(OX+RGz2<9D"I\ $ o֔x f^M}pQדlAV< 0Rm3X[,ޡ2Ջ"گ?DSN;"galD]t7,:4|g;앭8DE]HvrL^y8ĀgMwW9 ,E1rZ:-I(;E8 _i[n-nfhBG3 SҠ%acG/$W,*LjWƃ5/VUᆀEi01\Abo/&e7BEX"=Y(g'?t̀$܇UԱjLI7˜lؾM -XD̢k%V5,nf*c!+ΐ;'w -u>ZqC*69҈- HrhqQbQg7Lײ-?5A5?!`}?T.xT%L -sq\xI׷WH[==Q2J%]Eqsl9fX MdhpX/F SN@mѿg:kHQgˆaUTjGH̬\9,вս~{Yɦ? ky Ib}֩l]uk=MgEUwg1:OFn+VLm^y2b,mϟuT~gyeЩX-@^W|~ԵhêM&S)(&/OIh0peٝ]VM#\\w*u+֛Sܚn'D^Ի䭕SO-V4!jaz0wj)\]bMVWDix3:#0Hj5zOk2`E1OlPV̦Kۙ(j6|<ˆmJŮۣ V(I2HگzY9VB3nMof^Ar'/aNF8ְ*Ty{> >Q 0(aV3{:.M[qfFMQ`@%pM2g+ -fGm֚{6c` 8te L;ɋ0!n!p@_?VXՇX9WiS Sո=R> rMF.RK搅j^w. ^]pCbѼ^jfTrJC՚R'ͳ,0ta# g:7Oϖn}B]g79&eaKi2( *kǡV$sM(Q}nW<ќ ;cGƫ"cBРMA^5R!`bhv*p_z4ᅄC#,uu?[KHvG^B4TŠ@cefhピҎlȣ3Q9+m xVxĠ8ݨ9q Aluzi"oZސmC|Q ?cW/VڋF t׊x=.YBhNڊE.5wK5POG XbUa(jl#b ("/DT!gEq{ 炗Vfq.-Anڑea5+fr%uе!>Fm%UxV3o)~ 8^ BܣLmi^L`t.jt"0cQm`/uNC rCC췌׺e~|} ^}"HM\. t0'ic?Q]k38E<?dĮLGjp V[^Xl '@HO>AmđLǜ|4$H h]9]f M0\Ӵ0԰h`ڑNlv@ֲfzKo=oTك5^6p7P僀pyr5߯"x+u(:ߏ!ȺNECaCc ;hEcM֔tBh^"_icSyrfnl?5`m%s BӺĤhUdhp\2⇪7Lh6fT`A --[2B49 F>#%0SymS IQPL![L>;te3eŞbބjwŒQCֵh8 ٨2^3 -(oY =@>M`ǣ͋:ug׋3Ugצ. zwG$0ڦ~wBjhg1&g%*p]$Nb3<`~u\ -&4OJj#JM#7fD$S-v]di%Vt烛k?r @:;x8ޚ7/ET/S+eߧ]Fq zƜagav}q<- ;ŅN޴tq/>W)}R&00b8# #3חM{O6r󴢟u󫅶_(pwֺu ~d#~da}=v:hdtаfw}ja8a1ae2jH^y 9qӿ'%.RF"?2 ,Z&/[9/d/М_?<|56*|ʕw]d5֦BOI:LW\zV59hݴU|fxU0pY~-+GE%%Lm"OO+.p6%@{&  } J>2H#ӳǷߋ7W+aj#u9|XӾuȣײ~*hޓU{݉v+R[ov1/js<6.%mlM=q[orNyxsezOhK!kT7?|(Bc4l?9+Qw?{QYOrڠ|ڍDf}OOqJnC -P pA-px{&(Kjn][tI#__| R7;HTod#VTvkVmo0ݥʺW3d9KNTY[ _P7P肍&n$蕊()aRM; -؛I -ܗ.5"Z`^{nJ?hwǴk-:3c;N1.cf!jCTT֬T\?2g6n޲nmNWkꫩO 0l/QL'SzJ *@x?m? b]m8E!^d^?6/xTZ[K(fp2 gte>[[T)&3w0Ӝ5n{ 鳕g!< L03qB<~h͛#n59?734jK'Zg7oD~+hg-a$QwFPlؚU%'5zE^!s՞)03qCzúfOU<ݳoT~ӡ+ M*wCb>|v Ҭg`h)re]cw6P^W| -lԎ9)jLgQ>aI#瞯{Zl{z:;@ߗZ}hzBLL:̔85=OI;8uQ/Jy.̜6nBV]4Mȷ?^HM:ZN<"^z -?5PՍt;5Bj=}C.{hW]Ԧ6z|U&Y& 5}7f*Ԁ@ -Jd͜:_L;d0Ę#Tc !o6)@8n&m2)~WZxCkµՉ7=/+ #2lFr[#xd9mػJ1y )sV~4&)kJkh~{Kc">-vZ -UyFV _5ׇkONdJߦq]^G@ue1D#S )%tv:|{Tdu6ѓ %etdzQ4V2,0]&ISpV CH^ABS;ovI%:Ep=(McvJ)5 -TڍL@B1|=9Q`R  ɞF -?0pKr9u|9CGfb>] :ѿxXu80f=P?`zЩ9* 9Bo}@Ÿ遪0y≠~rE+oB6P@YIMR"Ē UDOa΀lDgHkX|t!ЌV̒NZSdX (m[(m8ي-tׁzc}JqPCT6;G^&CtiOǕJ#H&3{FtcuQ>Y!D̓F,uNh|lX"v9P@{zQAЇǖ ߹ݬ"o&@05ҲlR,W_ZԢⷰ;m#{d*&CU˦[ U~xARovj̿{y; -pմ2=~ m@-鬅]p6K9_tL_]*h0~nQ.KA. $)y㑐A~{ú DSؐGU+", D̨{Pk vz->JT| a] 1RVռKg5S JR{Ӧ]w7jio>~,@<.wR+Ft$7(2\A1Rx@߷b\#VF$* -h}e~uAOҿ(ˑrpeѱ Jw*N-y\ pq_U3+sucrBgM>ރ]Kٔ"A%YZ>%YN_2~qWF -1 41F -|(; 0-}3>\8쌀:> - ^q~8JAI]#ks ܪfK9kgIAAb !$Ց,ϢG -k[1ŝM=|R||լa5zpFk3[ !dzcqUT8+,6om*{j1& W dSz1Ԩ"fI4;Qipv=BG Jjˊ }qF.3tŊŽBC^0#vQ_%xZDa@Vȉ<㛬"@f7#VB5A\3`9I8oP&k-6*͍Fa=6)͗7vBro4j $۰]s! -d}L\TuBDxtYz -"FI[8E9+#2o{3 zϋ<‰NV"|$k[Qx Ĝ}Ϡ"r8#lҒ[aJEfI+ÞJ2eh>,S|OB@\,c)`+~è)KфeLG0ާvk{YU Gس,IS~j+BSđEg7͇ff%kK<+vopH5B zW:KUcT̖UʾiQ ݺ0p"|VW>sZN4r[^v47%`KoU ¡LP`{?WI{էRFxyևz>lrZ;y洊U׌/um-7b{; -k(=g"O3}]yXeejo4lOEM~"\bq%*BNPᨉa2uuOw*(<&0_+ mc'F -Ι%4TzHk/%@"J[ч 'UMQ?y#Ǩo[ԞUa -6eV}Ycs Ƨ: [;ì͝KA@3)l+ԕנV{]n -/3 -(Y-SV*H(IezOOC6:MGRǘԆ"~)5/+AhчJ+)&un5};0nky"$$v$g*x3N1_R;yx6ɒ&9$9|(iߪzȥ,(95Ýod؄6Ԉ7tXoAk?Λ8ۏD3Axa4a)U%Ed-[ |򵲞_.ЄEVs}"X>4*M'2I-IKFP(֧R῞cUGUB)~>6,{2ֵ5z9љkvi0(·Lzjy%.#9g^{W]2j< 7A(]wR&-2hN h"M @dq'~i`nKdVjy̝!c7wFr$Qt $.A tقP~SE@*p7?Ʉc˾P2V+fGG$g,qL@|1Gu[? `L=o;H⓹8[:bӰbbRg.O`#3 V"Iafzi\|jKGW6YUۢMD)JǚJt0ll;[^"i d(+5~w܇e z(Lʌ -8F1+JuB @aI;ȄUsiMK_}' |Mb ZaM³0娆^lqE: -&i)Cbnd :APTBvɱZ4}iPYog`5vdz[ݞw_~Y?>?9>9?>?g7g7'_zܯso7!3 A;ƈ8P4AJUa}(aM?PrLڋTh55.s) -mJbI&Z豱iǃ ԚjiIr$TN1`3 -..7 ,R)^~k\*]-0F_‚YW&[SDPpUfDKarmCI5{geITkҘd7DCk9aڀ{rҦtA}Y9xL H4Ƈ!Munqe -Mh(8\$oi3 -1[>xC:H&bcf]Ut\)ưgt_(!w1zsSg5aiP YCa\SZ5 K=ִ^YB|NO4 /$QbL֣[Aԍ Gg.BShƊ"$0H5gdJo` XBw񋭩ylz -`7̃-8gb*KVm}QW -ǫA@FCgaDMh9An_0D'DMUiO$NY4ède6HHYdo+O- 5WMYF0 -jɁzvGC6 -v- O#Gwt._ -5cn -BS|cj,QcN p ˡ1Iu!)͟1<fCɡMߔk(Ⱥ@{qNjeWTgXp ="ugв&%Q_Z:JՂZQTgrkP0qͦ{Z 4PT߮H |//M\/_~/bǿvPTzڗ@$t@"l#V CNSD ܁iT@`EW'„/"!I99#dHZ.zImnM::mٸ3MߌA5 @}崖0W8a=`!V^$3HR_tHMH6Qe#@tڍq. -|z DoMMAZ{LVHwtM/AUn=A."_pU ;9#{5>EJlD c&y#4Qs);"e9Qμm =ᬳŜޅY#:t|PN7޼f?*vZоW6VL*&,h%hXD +&)ay08U k X@ř DM5q:/W OgL+̹̎,U-KH2"j&j^nޞ sXsDnwG'WT %3[e~*,3@TÂJj}7TCM(GV͘id-!^ -] }=WvvݤX36^-T<[^X jTa)D3B'gK˶I)Bv: SDәѩXzD=N-dž2j~'6>=cJk3lS:tJ[FV7%;EUNP].OP+,驢5dgC+ci>B}N6ԧs F lM_N9Dm@33.Ȳҿ%hTr5M̏Ld-vo9Wܦ<2⧎xdcx7Y-#/wcLbiBڱN}%ae -j/.4_N ?$#0QY'bm攴 '8H590V$%&ڑ^JŮBh<bԌ$6>ĉ5o~-rce Rx0r -0}QN43Z'pȣ)M4_Y rFu':fÏ9[|g:CQU{ёfDl1P7eLH*\lӞnt6 bZOltng[0_; -.ҭJ&OIpp$p…7o YL{o$B\Yr#_ z%XUմ d9\[{ffNÖ Mеʁ)q4xmϴ:PhAT40`ՏRqb& bdPHe* +SkLoǎ]lx+ lbʔ/.욞Zmt=NfT|b͡H֐ (YÚ#<)?t,<(@W( o7iLM^"jUf7D|5g2$9-EY -#Qq!BTmF+{o36="jk>kRR0}4WK˝ Q2T tVv^S>iqzf)糸|OZ/K=|]tq=JTDi@QP5}v\UPW -.HpPlrKv0Lp!kB;t:iAozs`oi;[<Ϣ!P_㹅Ɇ(bZgt֤ЗU1 cfKxS82Hh%-mPNLJ8wMAa9 x50vXI%l \sCZ""*5`ˁ|ƀVFORQ}(gnukٴJ*ҧr#p$=]`5g{,_,Jv`X0WGLC[j,--Dڀ[4Hl:)gSg\rd!m nþ0;>e~y- -endstream endobj 104 0 obj <> endobj 105 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.937 0.627 scn -/GS0 gs -q 1 0 0 1 138.7171 583.83 cm -0 0 m --32.793 14.467 -47.957 65.124 -35.724 96.113 c --25.697 121.511 0.557 138.94 27.993 138.409 c -33.074 138.311 38.201 137.643 43.067 135.967 c -57.405 131.027 67.891 117.875 74.204 103.907 c -91.177 66.352 83.891 22.69 47.3 3.37 c -33.004 -4.178 15.243 -6.724 0 0 c -f -Q - -endstream endobj 106 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.937 0.627 scn -/GS0 gs -q 1 0 0 1 767.5393 359.7269 cm -0 0 m --17.175 -5.403 -33.367 0.234 -42.18 17.417 c --46.157 25.17 -47.757 33.888 -48.296 42.483 c --49.344 59.181 -46.213 76.656 -35.924 89.304 c --19.237 109.815 4.799 107.41 22.042 88.42 c -29.385 80.333 36.274 71.353 39.217 60.896 c -42.937 47.681 39.727 33.258 32.079 22.375 c -24.431 11.492 12.702 3.996 0 0 c -f -Q - -endstream endobj 107 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.647 0.588 0.557 scn -/GS0 gs -q 1 0 0 1 526.7019 288.5623 cm -0 0 m -0.25 -4.256 0.479 -8.661 -1.027 -12.65 c --1.775 -14.629 -2.925 -16.43 -4.154 -18.152 c --4.332 -18.401 -4.52 -18.678 -4.491 -18.982 c --4.453 -19.376 -4.045 -19.651 -3.65 -19.672 c --3.255 -19.692 -2.878 -19.52 -2.528 -19.337 c -0.832 -17.578 3.298 -14.447 5.011 -11.063 c -4.782 -12.167 4.789 -13.318 5.03 -14.419 c -5.108 -14.775 5.227 -15.151 5.517 -15.372 c -6.094 -15.812 6.916 -15.388 7.476 -14.928 c -11.082 -11.964 13.128 -7.2 12.794 -2.545 c -13.175 -3.468 14.48 -3.701 15.364 -3.237 c -16.249 -2.772 16.779 -1.839 17.164 -0.917 c -18.997 3.465 18.584 8.511 17.137 13.035 c -15.242 18.959 11.61 24.316 6.809 28.27 c -8.735 26.563 10.04 24.279 11.26 22.013 c -12.632 19.465 13.952 16.86 14.699 14.065 c -15.434 11.316 15.677 7.414 14.031 4.899 c -12.722 2.898 8.98 5.103 8.502 6.954 c -9.228 4.139 9.261 1.148 8.599 -1.682 c -8.356 -2.719 8.007 -3.761 7.335 -4.588 c -6.663 -5.415 5.611 -5.996 4.553 -5.871 c -3.572 -5.755 2.751 -5.073 2.11 -4.321 c -1.059 -3.088 0.326 -1.587 0 0 c -f -Q - -endstream endobj 108 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 369.5793 389.6175 cm -0 0 m -3.598 -1.867 8.769 -3.26 12.711 -5.719 c -13.192 -5.22 13.813 -4.868 14.484 -4.738 c -14.303 -4.347 14.118 -3.946 13.928 -3.53 c -13.084 -1.688 12.702 0.327 12.37 2.326 c -8.967 22.792 11.361 43.672 11.456 64.303 c -7.349 56.065 2.368 48.263 -3.37 41.065 c --5.868 37.933 -8.419 34.354 -11.773 32.185 c --15.659 29.67 -20.698 28.312 -24.979 26.596 c --25.741 26.291 -26.774 26.129 -27.44 26.427 c --25.232 23.865 -23.023 21.304 -20.815 18.743 c --14.754 11.713 -8.368 4.342 0 0 c -f -Q - -endstream endobj 109 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.647 0.588 0.557 scn -/GS0 gs -q 1 0 0 1 398.0632 222.9117 cm -0 0 m --3.321 0.298 -6.66 0.373 -9.992 0.248 c --6.791 -0.674 -3.335 -0.352 0 0 c -f -Q - -endstream endobj 110 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.647 0.588 0.557 scn -/GS0 gs -q 1 0 0 1 524.1609 221.2496 cm -0 0 m -7.686 0.895 15.328 2.157 22.889 3.801 c -15.227 3.036 7.339 2.183 0 0 c -f -Q - -endstream endobj 111 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.647 0.588 0.557 scn -/GS0 gs -q 1 0 0 1 411.2742 215.567 cm -0 0 m --0.385 -2.486 -0.723 -5.152 -0.418 -7.623 c -0.655 -5.19 0.94 -2.503 0 0 c -f -Q - -endstream endobj 112 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 349.3113 321.6783 cm -0 0 m -0.132 -0.138 l -0.601 -0.63 1.075 -1.05 1.579 -1.421 c -2.032 -1.756 2.478 -2.118 2.925 -2.482 c -3.015 -2.556 3.104 -2.629 3.196 -2.703 c -1.564 -2.272 0.53 -1.388 0 0 c -226.6 -113.197 m -226.303 -112.472 225.919 -111.716 225.459 -110.927 c -224.929 -114.152 221.154 -116.047 217.926 -115.534 c -214.698 -115.021 212.033 -112.751 209.87 -110.301 c -207.706 -107.852 205.826 -105.105 203.246 -103.097 c -204.704 -105.475 206.915 -107.299 208.53 -109.573 c -210.146 -111.847 211.11 -114.98 209.72 -117.398 c -208.368 -119.749 205.314 -120.528 202.604 -120.43 c -193.493 -120.101 186.35 -112.831 180.237 -106.065 c -181.959 -108.292 183.732 -110.627 184.274 -113.389 c -184.817 -116.151 183.708 -119.456 181.085 -120.477 c -180.009 -120.896 178.818 -120.89 177.665 -120.82 c -172.288 -120.497 166.991 -118.902 162.33 -116.201 c -160.351 -115.055 158.272 -113.305 158.389 -111.021 c -158.486 -109.112 160.098 -107.66 161.666 -106.567 c -165.699 -103.755 170.164 -101.823 174.85 -100.429 c -169.678 -101.031 164.487 -101.471 159.286 -101.73 c -156.68 -101.86 153.877 -101.895 151.707 -100.447 c -149.375 -98.892 148.357 -96.018 147.62 -93.313 c -144.812 -83.014 143.938 -72.192 145.056 -61.575 c -145.248 -63.049 145.976 -64.446 147.072 -65.449 c -147.2 -63.189 147.328 -60.929 147.456 -58.669 c -147.661 -61.856 149.937 -64.811 152.966 -65.822 c -146.935 -53.856 144.403 -40.152 145.76 -26.821 c -143.515 -30.842 l -144.615 -24.999 145.984 -19.206 147.615 -13.488 c -142.16 -21.132 131.459 -22.364 122.071 -22.622 c -109.587 -22.966 94.713 -23.153 84.523 -14.894 c -90.949 -24.948 92.378 -37.35 92.753 -49.276 c -92.901 -53.953 92.759 -59.079 89.726 -62.642 c -89.158 -62.04 88.591 -61.438 88.024 -60.837 c -90.354 -70.459 91.021 -80.481 89.985 -90.327 c -89.542 -94.535 88.684 -98.945 85.887 -102.12 c -83.806 -104.482 80.337 -105.806 77.376 -105.194 c -78.958 -106.036 80.44 -107.027 81.59 -108.385 c -86.779 -114.513 79.463 -120.409 73.639 -121.753 c -69.931 -122.609 65.629 -121.559 63.344 -118.516 c -62.285 -117.105 61.758 -115.467 61.544 -113.734 c -60.334 -116.476 58.119 -118.894 55.474 -120.339 c -50.483 -123.066 44.481 -123.101 38.819 -122.57 c -35.211 -122.232 31.377 -121.58 28.73 -119.106 c -26.887 -117.384 26.02 -114.496 26.642 -112.169 c -25.574 -113.609 24.343 -114.908 22.812 -115.82 c -20.4 -117.258 17.068 -117.494 14.917 -115.689 c -13.164 -114.218 12.556 -111.673 13.02 -109.432 c -14.187 -103.783 20.629 -101.097 26.287 -99.969 c -30.396 -99.151 34.573 -98.674 38.76 -98.518 c -38.508 -98.446 38.254 -98.382 38.006 -98.293 c -34.599 -97.076 31.645 -93.78 32.068 -90.187 c -32.499 -86.532 36.109 -83.88 36.609 -80.234 c -36.947 -83.584 39.16 -87.06 42.497 -87.513 c -45.834 -87.967 49.146 -83.75 47.098 -81.076 c -50.379 -84.162 56.572 -82.989 58.496 -78.916 c -58.172 -79.602 52.243 -73.537 51.839 -72.901 c -50.375 -70.594 48.668 -68.115 48.063 -65.388 c -49.093 -68.643 48.278 -72.416 45.996 -74.954 c -45.197 -75.843 43.667 -76.545 42.932 -75.603 c -42.684 -75.286 42.621 -74.865 42.571 -74.465 c -41.989 -69.735 42.153 -64.914 43.057 -60.234 c -41.709 -64.847 39.375 -69.17 36.257 -72.828 c -35.744 -73.429 35.18 -74.033 34.438 -74.306 c -33.697 -74.579 32.732 -74.406 32.337 -73.722 c -32.123 -73.352 32.107 -72.902 32.11 -72.474 c -32.146 -67.729 33.857 -63.171 35.66 -58.781 c -34.764 -61.195 33.227 -63.368 31.249 -65.017 c -30.674 -65.497 30.018 -65.949 29.271 -65.999 c -27.423 -66.121 27.144 -63.6 27.056 -62.288 c -25.753 -42.895 29.368 -23.644 32.861 -4.659 c -33.708 -0.053 34.475 4.635 35.167 9.362 c -35.093 10.291 34.949 11.205 34.695 12.095 c -34.384 12.201 34.085 12.358 33.811 12.551 c -32.867 9.36 31.473 6.361 28.844 3.7 c -28.449 3.299 28 2.895 27.443 2.815 c -25.869 2.589 25.271 4.734 24.798 6.253 c -23.092 11.734 16.333 13.412 10.7 14.516 c --6.144 17.814 -22.908 24.104 -35.393 35.881 c --47.878 47.657 -55.371 65.666 -51.382 82.359 c --52.83 79.732 -55.228 76.674 -58.109 77.509 c --60.048 78.071 -61.06 80.228 -61.357 82.225 c --62.052 86.899 -59.897 91.84 -56.123 94.645 c --57.709 94.451 -59.713 95.723 -60.023 97.479 c --60.458 99.938 -58.842 102.257 -57.203 104.141 c --52.691 109.327 -47.352 113.716 -42.041 118.079 c --47.869 113.708 -53.645 110.493 -58.964 105.47 c --64.203 100.522 -68.734 94.803 -71.796 88.251 c --71.796 88.25 -71.927 87.97 y --73.23 85.168 -75.015 81.332 -74.938 78.083 c --74.921 77.254 -74.529 76.603 -73.863 76.294 c --72.903 75.851 -71.741 76.247 -71.06 76.804 c --70.54 77.234 -70.031 77.674 -69.532 78.124 c --70.741 75.096 -71.578 71.879 -71.976 69.225 c --72.054 68.731 l --72.374 66.731 -72.858 63.71 -72.282 61.32 c --71.625 58.51 -69.771 57.713 -68.331 57.538 c --66.813 57.359 -65.454 57.742 -64.289 58.688 c --63.219 59.555 -62.442 60.809 -61.88 62.134 c --59.785 46.505 -50.636 31.833 -35.649 20.298 c --27.186 13.777 -19.349 9.248 -11.688 6.449 c --7.895 5.067 -3.737 4.02 1.399 3.154 c -3.971 2.723 6.288 2.278 8.485 1.79 c -8.112 1.76 7.741 1.729 7.372 1.699 c -5.317 1.527 3.193 1.354 1.102 1.43 c -1.065 1.431 l -1.019 1.431 0.971 1.438 0.923 1.444 c --1.672 1.754 l --1.587 1.665 l --3.374 1.889 -5.28 2.285 -7.394 2.872 c --8.132 3.077 l --8.481 2.395 l --9.722 -0.024 -9.866 -2.301 -8.91 -4.372 c --6.839 -8.856 -0.238 -10.846 2.503 -11.493 c -6.404 -12.417 10.553 -12.815 14.824 -12.673 c -15.581 -12.649 16.475 -12.457 17.421 -12.252 c -19.04 -11.901 21.057 -11.466 22.003 -12.088 c -22.56 -12.453 22.775 -13.402 22.816 -14.552 c -22.393 -14.688 21.954 -14.805 21.478 -14.879 c -21.105 -14.938 20.704 -24.041 20.769 -24.914 c -21.284 -31.918 18.604 -40.377 16.799 -47.131 c -14.697 -54.993 11.917 -62.675 8.492 -70.059 c -7.958 -71.209 7.375 -72.397 6.367 -73.167 c -5.359 -73.938 3.801 -74.142 2.868 -73.282 c -1.069 -71.625 3.229 -68.723 3.091 -66.281 c -1.898 -71.226 -1.265 -75.667 -5.548 -78.41 c --6.936 -79.299 -9.189 -79.789 -9.89 -78.298 c --10.194 -77.652 -10.027 -76.892 -9.83 -76.207 c --8.883 -72.907 -7.366 -69.773 -5.367 -66.983 c --9.557 -71.52 -15.002 -74.99 -21.026 -76.347 c --27.05 -77.704 -33.645 -76.838 -38.85 -73.516 c --47.557 -67.959 -50.901 -57.078 -53.512 -47.085 c --52.571 -50.689 -53.377 -55.188 -52.592 -58.992 c --51.708 -63.274 -50.238 -67.436 -48.229 -71.319 c --44.905 -77.742 -38.639 -83.608 -31.283 -84.904 c --26.656 -85.727 -22.04 -84.367 -17.754 -82.663 c --18.338 -83.432 -18.883 -84.241 -19.354 -85.11 c --20.07 -86.433 -22.213 -90.967 -19.712 -93.818 c --18.939 -94.697 -17.808 -95.424 -16.18 -95.424 c --14.375 -95.424 -11.961 -94.53 -8.75 -91.957 c --6.738 -90.347 -5.053 -88.418 -3.561 -86.451 c --3.618 -87.141 -3.633 -87.834 -3.604 -88.522 c --3.576 -89.143 -3.49 -91.029 -2.127 -92.025 c --0.879 -92.954 0.814 -92.828 2.907 -91.649 c -6.627 -89.552 9.16 -85.339 12.729 -83.697 c -13.583 -83.304 14.469 -83.067 15.373 -82.916 c -15.205 -84.581 15.042 -86.247 14.866 -87.91 c -14.575 -90.622 14.275 -93.333 13.947 -96.035 c -13.693 -98.124 12.318 -100.392 10.988 -102.584 c -10.452 -103.468 9.946 -104.303 9.517 -105.118 c -4.13 -115.413 l -3.723 -116.199 3.262 -117.09 3.106 -118.088 c -2.547 -121.732 5.669 -122.558 7.351 -123.003 c -7.579 -123.062 7.796 -123.112 8.023 -123.162 c -9.649 -123.522 11.3 -123.653 12.896 -123.78 c -13.713 -123.844 14.53 -123.909 15.344 -124.004 c -19.745 -124.515 23.922 -124.822 28.345 -125.147 c -29.542 -125.235 30.749 -125.324 31.968 -125.418 c -35.882 -125.711 40.506 -126.052 45.122 -126.348 c -46.407 -126.434 47.696 -126.506 48.986 -126.579 c -51.587 -126.724 54.276 -126.875 56.883 -127.145 c -57.797 -127.238 58.702 -127.273 59.597 -127.273 c -60.967 -127.273 62.313 -127.191 63.632 -127.11 c -65.085 -127.022 66.587 -126.929 68.082 -126.952 c -68.571 -126.958 l -72.377 -127.013 76.313 -127.068 80.264 -126.675 c -83.074 -126.392 86.066 -125.958 89.032 -124.068 c -91.952 -122.192 94.553 -119.862 97.091 -117.588 c -99.615 -115.327 99.7 -112.388 99.783 -109.545 c -99.793 -109.19 99.803 -108.835 99.819 -108.481 c -99.824 -108.36 l -99.998 -104.373 100.178 -100.25 100.307 -96.179 c -100.542 -89.086 100.786 -81.992 101.04 -74.896 c -101.598 -59.259 102.289 -45.052 103.153 -31.462 c -103.208 -30.588 l -102.341 -30.471 l -102.027 -30.428 101.714 -30.378 101.405 -30.322 c -105.018 -29.1 109.025 -29.098 112.917 -29.095 c -113.499 -29.095 114.079 -29.095 114.655 -29.091 c -115.292 -29.085 l -120.148 -29.045 124.777 -29.003 129.332 -30.194 c -128.863 -30.249 128.38 -30.294 127.88 -30.334 c -126.803 -30.418 l -127.036 -31.474 l -128.039 -36.015 128.085 -40.952 128.128 -45.727 c -128.146 -47.569 128.163 -49.473 128.236 -51.306 c -128.373 -54.7 l -128.611 -60.578 128.857 -66.655 128.959 -72.643 c -129.09 -80.433 129.175 -88.327 129.213 -96.108 c -129.241 -100.024 129.241 -103.931 129.241 -107.848 c -129.241 -108.2 129.235 -108.548 129.229 -108.891 c -129.186 -111.395 129.141 -113.982 131.597 -116.008 c -133.979 -117.96 137.369 -119.097 140.361 -120.1 c -140.815 -120.252 141.259 -120.401 141.687 -120.548 c -146.775 -122.304 151.293 -123.614 155.498 -124.551 c -160.226 -125.61 165.057 -126.391 169.854 -126.872 c -170.995 -126.988 172.149 -127.006 173.294 -127.048 c -185.39 -127.492 197.759 -127.277 209.748 -125.531 c -214.106 -124.896 218.807 -124.297 222.768 -122.245 c -227.339 -119.876 228.134 -116.949 226.6 -113.197 c -f -Q - -endstream endobj 113 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 532.322 525.4476 cm -0 0 m --0.344 0.812 -0.682 1.592 -0.949 2.315 c --2.08 5.389 -2.773 8.583 -3.133 12.37 c --3.212 13.205 -3.266 14.042 -3.319 14.88 c --3.374 15.729 -3.428 16.578 -3.508 17.422 c --3.531 17.673 -3.55 17.931 -3.57 18.193 c --3.615 18.806 -3.663 19.439 -3.76 20.082 c --3.95 21.241 -4.272 22.128 -4.775 22.874 c --5.498 23.935 -7.643 26.055 -9.563 26.39 c --10.665 26.583 l --10.665 21.362 l --9.947 21.187 l --9.625 21.109 -9.338 20.887 -9.249 20.648 c --9.211 20.546 -9.183 20.381 -9.367 20.124 c --24.832 -1.223 -50.454 -15.081 -79.664 -17.897 c --94.809 -19.36 -109.488 -18.293 -123.297 -14.729 c --128.753 -13.314 -134.387 -11.521 -139.282 -8.662 c --141.374 -7.441 -142.854 -5.904 -144.763 -4.498 c --146.753 -3.034 -151.279 -1.908 -152.635 0.106 c --145.667 -10.24 -134.625 -17.409 -122.774 -21.298 c --97.029 -29.745 -66.899 -26.442 -42.802 -15.12 c --34.938 -11.188 -28.284 -5.633 -20.506 -1.48 c --19.155 -2.431 -19.063 -4.354 -18.98 -6.005 c --18.837 -8.881 -18.321 -11.738 -17.448 -14.482 c --16.525 -17.385 -15.186 -20.33 -15.63 -23.343 c --10.354 -20.261 -5.543 -16.386 -1.409 -11.888 c --0.214 -10.587 0.958 -9.177 1.432 -7.475 c -2.088 -5.121 1.022 -2.414 0 0 c -f -Q - -endstream endobj 114 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 521.717 533.9149 cm -0 0 m -5.995 7.492 10.391 16.272 1.042 17.923 c --0.06 18.116 l --0.06 12.895 l -0.658 12.72 l -0.98 12.642 1.267 12.42 1.356 12.181 c -1.394 12.079 1.422 11.914 1.238 11.656 c --14.227 -9.69 -39.849 -23.548 -69.059 -26.365 c --78.586 -27.283 -87.721 -26.382 -97.182 -25.856 c --107.319 -25.293 -117.338 -22.522 -126.295 -17.734 c --123.571 -22.207 -118.179 -24.179 -113.135 -25.589 c --95.885 -30.412 -77.721 -32.335 -59.945 -30.134 c --42.17 -27.932 -24.796 -21.514 -10.484 -10.745 c --8.635 -9.353 -3.967 -4.958 0 0 c -f -Q - -endstream endobj 115 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.455 0.71 0.349 scn -/GS0 gs -q 1 0 0 1 373.8054 513.994 cm -0 0 m --0.129 -2.425 -0.276 -4.853 -0.423 -7.278 c --0.432 -7.435 l --0.472 -8.099 -0.558 -8.823 -0.645 -9.57 c --0.887 -11.637 -1.161 -13.98 -0.604 -15.899 c -0.256 -18.894 3.186 -21.989 8.103 -25.097 c -8.886 -25.594 9.642 -26.034 10.309 -26.415 c -13.792 -28.415 17.601 -30.223 21.953 -31.944 c -35.701 -37.36 51.048 -40.063 66.668 -40.062 c -82.868 -40.062 99.362 -37.153 114.656 -31.346 c -124.806 -27.497 134.433 -22.211 143.06 -15.615 c -149.937 -10.357 159.798 -4.802 158.461 5.225 c -157.178 -1.518 151.687 -6.597 146.159 -10.665 c -120.259 -29.726 88.961 -36.133 57.398 -35.884 c -48.744 -35.815 39.73 -35.664 32.016 -31.741 c -24.301 -27.819 18.386 -18.897 20.837 -10.597 c -37.583 -13.59 54.596 -15.08 71.607 -15.045 c -60.311 -14.562 48.936 -13.915 37.977 -11.132 c -27.018 -8.349 16.39 -3.275 8.617 4.937 c -6.648 7.017 3.88 10.656 8.157 11.816 c -6.145 13.343 3.828 17.714 0.903 14.872 c --1.231 12.797 0.167 3.192 0 0 c -f -Q - -endstream endobj 116 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.647 0.588 0.557 scn -/GS0 gs -q 1 0 0 1 488.8264 655.2504 cm -0 0 m --1.555 -1.544 -3.811 -2.706 -5.442 -3.511 c --19.181 -10.29 -33.921 -15.757 -49.233 -16.248 c --51.248 -16.313 -53.301 -16.286 -55.224 -15.681 c --57.146 -15.075 -58.946 -13.814 -59.78 -11.979 c --59.249 -13.147 -59.878 -15.055 -59.235 -16.438 c --58.613 -17.774 -57.52 -18.807 -56.729 -20.071 c --55.941 -21.332 -55.515 -22.548 -54.508 -23.72 c --52.29 -26.307 -49.58 -28.474 -46.635 -30.181 c --41.666 -33.062 -36.117 -34.961 -30.431 -35.768 c --29.031 -35.967 -27.595 -36.066 -26.141 -36.066 c --14.057 -36.065 -0.722 -29.237 3.329 -16.201 c -4.165 -13.521 4.558 -10.789 4.719 -7.994 c -4.896 -4.927 4.79 -1.876 3.695 1.034 c -3.413 1.783 3.031 2.491 2.65 3.195 c -2.149 4.121 1.649 5.046 1.149 5.971 c -2.451 3.563 1.593 1.581 0 0 c -f -Q - -endstream endobj 117 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 380.8079 668.6239 cm -0 0 m -0.318 -1.411 -0.554 -2.81 -1.948 -3.124 c --3.342 -3.438 -4.73 -2.549 -5.048 -1.137 c --5.366 0.274 -4.494 1.673 -3.1 1.987 c --1.706 2.301 -0.318 1.411 0 0 c -f -Q - -endstream endobj 118 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 585.7224 646.2953 cm -0 0 m --0.175 0.172 l --0.246 0.24 -0.472 0.486 -0.408 0.753 c --0.342 1.021 l --0.433 1.281 l --0.531 1.565 -0.631 1.845 -0.735 2.122 c --0.134 1.006 l -0.746 2.157 0.75 2.161 v -3.876 6.248 2.08 10.245 -0.684 13.726 c -0.534 12.198 0.194 9.68 -1.385 8.53 c --2.963 7.38 -5.465 7.829 -6.545 9.456 c --4.138 7.762 -2.932 4.838 -2.191 1.99 c -1.297 -11.412 -3.495 -26.615 -14.039 -35.594 c --16.638 -37.808 -22.695 -41.693 -25.642 -38.187 c --26.314 -37.387 -26.692 -36.387 -27.058 -35.407 c --28.48 -31.597 -29.902 -27.787 -31.325 -23.976 c --31.154 -27.611 -33.562 -31.221 -36.984 -32.458 c --36.42 -25.559 -38.482 -16.991 -42.408 -11.291 c --47.131 -4.433 -52.929 -2.19 -59.993 1.284 c --54.361 -1.486 -50.186 -6.71 -47.773 -12.504 c --45.36 -18.297 -44.575 -24.648 -44.45 -30.922 c --44.26 -40.469 -46.051 -49.277 -51.757 -57.055 c --57.1 -64.338 -66.82 -67.493 -75.563 -68.53 c --73.379 -77.915 -56.602 -72.684 -51.634 -69.734 c --41.928 -63.969 -34.975 -53.025 -31.62 -42.652 c --31.885 -44.17 -32.245 -45.684 -32.696 -47.188 c --33.106 -48.555 l --31.688 -48.392 l --31.37 -48.353 -31.086 -48.459 -30.865 -48.709 c --29.075 -50.74 -26.796 -51.792 -24.091 -51.836 c --24.035 -51.837 -23.98 -51.838 -23.924 -51.838 c --18.874 -51.838 -13.196 -48.204 -9.779 -44.567 c --5.524 -40.033 -2.177 -34.057 -0.353 -27.74 c -1.682 -20.683 2.861 -9.752 0.07 -0.236 c -h -f -Q - -endstream endobj 119 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 367.7283 786.1161 cm -0 0 m -1.625 -2.284 3.24 -4.515 4.774 -6.788 c -4.333 -3.878 2.686 -1.196 0 0 c -f -Q - -endstream endobj 120 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 338.322 721.0878 cm -0 0 m -0.779 0.987 1.535 1.993 2.255 3.024 c -1.455 2.052 0.712 1.036 0 0 c -f -Q - -endstream endobj 121 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 435.7966 622.5995 cm -0 0 m -2.985 -2.979 6.604 -5.33 10.535 -6.782 c -22.881 -11.342 39.431 -8.202 48.482 1.583 c -53.08 6.554 54.271 11.816 56.33 18.053 c -54.462 11.954 50.438 6.539 45.138 2.99 c -42.575 1.274 39.068 0.02 36.529 1.77 c -34.931 2.87 34.224 4.843 33.644 6.695 c -32.083 11.675 30.755 16.729 29.664 21.833 c -22.313 17.984 13.921 16.147 5.635 16.573 c -2.77 16.72 -4.661 20.224 -6.707 18.945 c --9.666 17.095 -6.931 10.773 -5.924 8.526 c --4.504 5.357 -2.469 2.464 0 0 c -f -Q - -endstream endobj 122 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 512.637 638.7601 cm -0 0 m --1.525 0.284 -3.119 0.366 -4.773 0.21 c --2.721 -0.702 -0.313 -2.181 -0.519 -4.418 c --0.595 -5.253 -1.05 -6.001 -1.514 -6.7 c --7.617 -15.916 -17.077 -22.523 -27.232 -26.887 c --37.388 -31.251 -48.294 -33.546 -59.152 -35.617 c --67.068 -37.127 -75.429 -38.504 -83.031 -35.83 c --85.119 -35.096 -87.248 -33.916 -88.137 -31.889 c --89.026 -29.863 -87.93 -26.939 -85.726 -26.739 c --96.398 -32.507 -102.255 -45.013 -102.497 -57.142 c --102.583 -61.493 -102.143 -66.216 -104.577 -69.823 c --105 -70.45 -105.594 -71.071 -106.349 -71.097 c --107.371 -71.133 -108.073 -70.107 -108.524 -69.19 c --112.351 -61.414 -113.144 -52.192 -110.7 -43.877 c --111.948 -48.125 -114.16 -51.948 -115.129 -56.367 c --116.073 -60.668 -116.171 -65.033 -117.11 -69.325 c --118.065 -73.688 -119.321 -78.726 -123.381 -80.587 c --127.735 -82.582 -133.05 -79.42 -135.119 -75.101 c --137.187 -70.782 -136.891 -65.754 -136.55 -60.977 c --138.391 -68.951 -142.971 -76.266 -149.342 -81.404 c --150.305 -82.181 -151.372 -82.936 -152.603 -83.071 c --155.226 -83.357 -157.234 -80.83 -158.443 -78.484 c --163.483 -68.698 -164.356 -57.125 -162.418 -46.289 c --161.857 -43.152 -161.55 -40.379 -160.232 -37.393 c --157.381 -30.938 -153.924 -24.751 -149.919 -18.94 c --152.415 -22.561 -155.911 -25.176 -158.701 -28.509 c --161.335 -31.655 -163.923 -35.292 -165.852 -38.92 c --167.263 -41.574 -167.692 -44.757 -171.388 -44.996 c --173.671 -45.144 -175.025 -42.473 -175.392 -40.214 c --175.711 -38.251 -175.756 -36.246 -175.535 -34.27 c --176.735 -38.402 -178.262 -42.439 -180.114 -46.322 c --182.447 -51.212 -186.11 -56.405 -191.513 -56.8 c --192.032 -56.838 -192.591 -56.816 -193.013 -56.513 c --193.644 -56.06 -193.734 -55.172 -193.755 -54.396 c --194.092 -41.847 -190.904 -29.223 -184.649 -18.34 c --190.521 -27.157 -199.305 -33.999 -209.291 -37.533 c --211.059 -38.158 -213.486 -38.454 -214.39 -36.812 c --214.721 -36.208 -214.734 -35.486 -214.713 -34.799 c --214.465 -26.907 -210.672 -19.424 -205.408 -13.54 c --200.726 -8.307 -194.932 -4.213 -188.894 -0.599 c --190.379 -0.821 -192.091 -0.258 -193.172 0.851 c --197.513 5.307 -194.994 16.023 -193.145 21.127 c --190.62 28.1 -185.869 34.317 -179.553 38.261 c --185.166 52.608 -183.032 69.664 -174.315 82.328 c --176.997 78.933 -180.016 75.805 -183.322 73.014 c --184.673 71.874 -186.133 70.759 -187.856 70.366 c --189.58 69.973 -191.633 70.498 -192.525 72.024 c --193.247 73.26 -193.065 74.807 -192.8 76.214 c --190.284 89.596 -182.103 101.818 -170.69 109.245 c --159.277 116.672 -144.789 119.202 -131.534 116.082 c --133.674 121.434 -131.649 127.451 -129.627 132.849 c --125.891 142.823 -122.119 152.871 -116.52 161.932 c --114.86 164.617 -112.625 167.463 -109.478 167.714 c --107.735 165.355 -107.748 162.166 -107.978 159.242 c --108.766 149.212 -111.264 139.318 -115.332 130.115 c --105.614 141.929 -94.525 152.613 -82.36 161.885 c --86.257 158.915 -91.924 156.338 -96.207 153.664 c --100.891 150.739 -104.371 147.129 -108.172 143.066 c --108.953 142.232 -109.746 141.384 -110.55 140.534 c --110.326 141.398 -110.091 142.273 -109.851 143.17 c --107.757 150.986 -105.592 159.069 -108.618 167.007 c --108.742 167.333 -109.001 168.011 -109.658 168.33 c --110.236 168.619 -111.081 168.437 -111.532 168.257 c --114.302 167.129 -116.153 165.23 -118.285 162.865 c --119.992 160.966 -121.644 158.79 -123.333 156.213 c --128.852 147.837 -132.064 138.163 -134.941 128.597 c --134.891 129.339 -134.824 130.114 -134.741 130.933 c --134.721 131.129 l --134.849 131.5 l --134.894 131.56 l --136.398 134.768 -138.201 137.702 -140.135 140.568 c --139.801 138.367 -140.154 136.036 -141.278 134.118 c --143.889 129.663 -149.585 127.615 -154.693 128.369 c --156.502 128.635 -158.285 129.215 -159.803 130.235 c --161.859 131.616 -163.31 133.707 -164.761 135.715 c --180.522 157.52 -201.654 174.76 -222.53 191.732 c --210.337 181.82 -198.335 171.887 -188.288 159.709 c --183.295 153.658 -178.803 147.176 -175.139 140.232 c --172.312 134.872 -165.054 126.085 -167.997 119.859 c --168.538 118.717 -169.375 117.745 -170.201 116.789 c --179.991 105.467 -189.781 94.145 -199.571 82.823 c --200.265 82.021 -201.02 81.178 -202.043 80.897 c --202.857 80.673 -203.723 80.841 -204.543 81.039 c --209.225 82.175 -213.659 84.324 -217.451 87.296 c --227.707 95.336 -232.431 108.458 -235.565 121.108 c --241.361 144.5 -243.421 168.815 -241.643 192.849 c --245.146 180.358 -244.363 167.12 -243.552 154.173 c --242.783 141.892 -242.01 129.577 -239.788 117.475 c --237.232 103.56 -232.76 89.999 -226.537 77.294 c --231.625 77.153 -235.349 81.939 -237.792 86.404 c --247.104 103.416 -250.957 122.838 -253.654 142.043 c --256.645 163.345 -258.37 184.824 -258.815 206.33 c --258.979 214.259 -258.3 223.531 -251.714 227.948 c --259.63 226.443 -262.732 216.371 -263.729 209.469 c --264.473 204.319 -264.432 198.945 -264.396 194.203 c --264.384 192.554 -264.372 191.005 -264.396 189.607 c --264.641 175.441 -264.265 162.584 -263.247 150.299 c --262.712 143.873 -261.959 137.502 -261.012 131.365 c --258.682 116.222 -255.072 101.778 -250.284 88.434 c --245.155 74.115 -238.598 60.864 -230.797 49.047 c --226.694 42.837 -222.178 36.922 -217.375 31.467 c --214.969 28.728 -212.383 25.992 -209.686 23.334 c --209.048 22.71 -208.37 22.127 -207.714 21.563 c --207.036 20.979 -206.395 20.428 -205.791 19.833 c --204.871 18.921 -204.597 17.913 -204.389 16.259 c --203.854 11.955 -203.317 7.65 -202.773 3.349 c --202.509 1.191 -202.209 -1.255 -201.625 -3.629 c --201.528 -4.028 -201.458 -4.429 -201.387 -4.828 c --201.3 -5.323 -201.21 -5.83 -201.073 -6.346 c --202.167 -7.41 -203.274 -8.45 -204.382 -9.491 c --205.638 -10.673 -206.896 -11.854 -208.137 -13.071 c --211.428 -16.299 -214.079 -19.346 -216.241 -22.388 c --219.269 -26.642 -221.332 -30.46 -222.73 -34.397 c --223.179 -35.635 -223.492 -36.725 -223.69 -37.731 c --224.79 -43.335 -221.634 -45.204 -218.794 -45.786 c --216.885 -46.181 -214.672 -45.411 -212.896 -44.793 c --212.635 -44.703 -212.383 -44.615 -212.142 -44.535 c --205.79 -42.411 -199.107 -38.091 -191.811 -31.379 c --193.07 -34.062 -194.279 -36.845 -195.142 -39.833 c --196.574 -44.84 -197.273 -49.891 -197.217 -54.843 c --197.199 -56.923 -197.067 -59.364 -196.213 -61.692 c --195.587 -63.445 -194.588 -64.61 -193.312 -65.065 c --192.987 -65.177 -192.642 -65.253 -192.264 -65.292 c --189.039 -65.54 -185.994 -62.167 -183.981 -59.929 c --183.782 -59.708 -183.597 -59.501 -183.424 -59.313 c --180.515 -56.13 -177.914 -52.304 -175.934 -48.324 c --175.704 -49.023 l --174.44 -52.874 -173.009 -57.238 -170.114 -60.217 c --168.707 -61.665 l --168.504 -59.656 l --167.536 -50.035 -164.36 -40.73 -159.363 -32.59 c --165.38 -44.684 -169.743 -58.507 -167.465 -73.908 c --165.994 -83.864 -162.111 -92.251 -155.925 -98.837 c --153.174 -101.765 -149.832 -104.307 -146.158 -105.958 c --144.744 -106.593 -143.122 -107.281 -141.582 -107.505 c --140.699 -107.633 -135.932 -106.713 -135.575 -107.068 c --125.773 -116.838 -112.981 -123.281 -99.608 -126.844 c --86.235 -130.408 -72.258 -131.21 -58.425 -130.774 c --55.205 -130.673 -52.478 -130.784 -49.484 -129.61 c --46.434 -128.414 -43.405 -127.157 -40.373 -125.914 c --47.4 -128.243 -55.729 -123.994 -59.92 -117.64 c --64.469 -110.744 -65.38 -102.15 -66.165 -93.926 c --65.028 -96.266 -62.071 -97.543 -59.589 -96.766 c --57.106 -95.989 -55.405 -93.254 -55.805 -90.684 c --49.354 -95.566 -40.343 -96.842 -32.79 -93.942 c --25.237 -91.042 -19.395 -84.065 -17.868 -76.119 c --22.119 -84.028 -31.775 -88.128 -40.71 -87.246 c --49.646 -86.365 -57.743 -81.158 -63.68 -74.422 c --69.616 -67.686 -73.633 -59.492 -77.116 -51.216 c --65.803 -65.648 -45.147 -71.957 -27.701 -66.31 c --33.737 -67.314 -40.032 -66.716 -45.771 -64.592 c --48.824 -63.462 -51.834 -61.808 -53.673 -59.12 c --55.512 -56.432 -55.853 -52.521 -53.764 -50.024 c --52.181 -48.133 -49.625 -47.411 -47.207 -46.93 c --41.313 -45.757 -35.253 -45.423 -29.267 -45.941 c --23.584 -46.434 -16.588 -49.3 -16.726 -55.001 c --11.092 -43.747 -5.203 -32.621 0.937 -21.634 c -2.814 -18.275 4.929 -14.725 8.422 -13.111 c -11.2 -11.828 15.021 -12.557 16.755 -14.822 c -13.491 -7.837 7.599 -1.414 0 0 c -f -Q - -endstream endobj 123 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 512.8977 640.0599 cm -0 0 m --0.917 0.764 -2.029 1.24 -3.292 1.241 c --2.171 0.891 -1.073 0.474 0 0 c -f -Q - -endstream endobj 124 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 337.1018 604.4899 cm -0 0 m -0.554 1.907 1.044 3.832 1.453 5.774 c -0.708 3.928 0.221 1.979 0 0 c -f -Q - -endstream endobj 125 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 563.7473 790.4799 cm -0 0 m --0.361 0.031 -0.719 0.071 -1.071 0.117 c --15.534 2.024 -28.006 10.944 -39.388 20.07 c --51.73 29.966 -63.978 40.946 -70.289 55.453 c --71.283 57.738 -72.143 60.133 -73.702 62.078 c --75.261 64.022 -77.729 65.47 -80.183 65.031 c --82.729 64.577 -84.519 62.299 -85.794 60.048 c --87.308 57.375 -88.459 54.497 -89.207 51.517 c --88.194 54.889 -83.339 55.75 -80.411 53.796 c --77.481 51.843 -76.208 48.183 -75.671 44.703 c --74.494 37.073 -76.016 29.053 -79.908 22.385 c --77.492 25.259 -74.797 32.974 -70.28 33.231 c --68.44 33.336 -67.044 31.678 -65.944 30.2 c --56.972 18.139 -46.264 7.164 -33.385 -0.588 c --37.817 -8.88 -43.029 -16.755 -48.929 -24.075 c --59.087 -18.711 -70.064 -14.902 -81.362 -12.821 c --83.176 -12.487 -85.183 -12.088 -86.282 -10.606 c --87.122 -9.475 -87.218 -7.971 -87.229 -6.562 c --87.28 0.33 -86.012 7.229 -83.513 13.652 c --85.447 8.671 -87.527 3.479 -91.584 0.001 c --95.642 -3.477 -102.319 -4.525 -106.168 -0.819 c --110.359 3.217 -109.139 10.087 -107.606 15.7 c --108.434 12.667 -110.231 9.927 -110.941 6.79 c --111.619 3.799 -111.973 1.033 -113.057 -1.897 c --111.293 -2.543 l --111.415 -2.869 -111.691 -3.006 -111.808 -3.021 c --111.001 -2.914 -107.124 -4.117 -104.721 -4.946 c --104.541 -4.826 -104.317 -4.762 -104.053 -4.81 c --99.87 -5.569 -96.731 -10.381 -96.741 -14.571 c --96.736 -12.265 -71.956 -14.261 -70.107 -14.585 c --62.716 -15.88 -55.233 -18.582 -50.163 -24.113 c --45.093 -29.645 -43.159 -38.523 -47.238 -44.821 c --47.645 -45.448 -48.252 -46.11 -48.993 -46.011 c --45.39 -49.885 -44.809 -56.237 -47.649 -60.7 c --48.25 -61.642 -48.994 -62.53 -49.276 -63.611 c --49.518 -64.534 -49.397 -65.51 -49.245 -66.452 c --48.763 -69.445 -47.981 -72.39 -46.917 -75.229 c --46.75 -75.674 -37.503 -66.907 -36.804 -65.907 c --34.061 -61.982 -31.511 -57.657 -29.082 -53.483 c --29.939 -56.282 -33.405 -57.657 -36.248 -56.958 c --39.091 -56.259 -41.306 -53.996 -42.863 -51.517 c --45.445 -47.406 -46.623 -42.432 -46.16 -37.6 c --46.05 -36.46 -45.851 -35.321 -45.442 -34.252 c --45.003 -33.102 -44.333 -32.057 -43.674 -31.017 c --37.341 -21.005 -31.707 -10.55 -26.826 0.245 c --26.472 1.028 -26.075 1.865 -25.324 2.282 c --24.142 2.94 -22.688 2.278 -21.504 1.623 c --18.574 -0.001 -15.643 -1.624 -12.713 -3.247 c --8.655 -5.495 -4.224 -7.817 0.37 -7.177 c -5.354 -6.482 9.499 -1.88 9.67 3.15 c -7.631 0.226 3.631 -0.312 0 0 c -f -Q - -endstream endobj 126 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 544.8938 632.8973 cm -0 0 m --4.462 8.911 -12.632 15.191 -22.386 17.031 c --22.5 17.052 -22.537 16.903 -22.433 16.861 c --4.53 9.573 6.877 -10.683 -0.657 -29.492 c --0.703 -29.607 -0.507 -29.691 -0.456 -29.577 c -3.927 -19.864 4.863 -9.712 0 0 c -f -Q - -endstream endobj 127 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 415.8206 548.3712 cm -0 0 m --6.86 3.931 -11.736 8.262 -14.412 15.951 c --17.007 23.409 -17.445 31.959 -15.509 39.633 c --15.481 39.744 -15.642 39.786 -15.679 39.68 c --18.731 31.057 -19.038 22.321 -15.502 13.73 c --12.927 7.474 -7.619 -0.355 -0.156 -0.574 c -0.152 -0.584 0.261 -0.15 0 0 c -f -Q - -endstream endobj 128 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 387.8728 672.4423 cm -0 0 m --3.997 -1.234 -7.947 -2.748 -11.225 -5.046 c --16.228 -8.554 -16.421 -14.655 -11.433 -18.378 c --8.992 -20.2 -5.91 -20.972 -2.874 -21.212 c -2.797 -21.66 8.647 -20.327 13.392 -17.187 c -18.135 -14.047 21.697 -9.067 22.82 -3.49 c -24.391 4.308 19.015 4.675 12.992 3.407 c -8.61 2.485 4.281 1.321 0 0 c -f -Q - -endstream endobj 129 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 428.5378 546.3112 cm -0 0 m --0.065 0.261 -0.492 0.212 -0.476 -0.064 c --0.271 -3.568 -4.2 -5.433 -7.028 -6.056 c --9.955 -6.701 -13.284 -6.189 -16.078 -5.217 c --21.121 -3.463 -25.313 -0.125 -29.501 3.069 c --29.556 3.111 -29.623 3.031 -29.592 2.978 c --25.517 -3.974 -18.685 -9.344 -10.401 -9.79 c --4.102 -10.129 1.783 -7.147 0 0 c -f -Q - -endstream endobj 130 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 494.7913 561.2992 cm -0 0 m --2.736 -5.27 -8.814 -9.734 -14.557 -11.209 c --21.509 -12.995 -27.505 -10.208 -33.694 -7.363 c --33.731 -7.346 -33.78 -7.383 -33.754 -7.423 c --29.836 -13.599 -21.32 -15.322 -14.524 -13.879 c --6.854 -12.25 -2.446 -7.137 0.282 -0.119 c -0.345 0.044 0.08 0.154 0 0 c -f -Q - -endstream endobj 131 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 416.3733 454.1502 cm -0 0 m --2.091 -0.802 -4.312 -1.246 -6.435 -1.971 c --8.937 -2.825 -11.949 -4.531 -10.625 -0.123 c --9.365 4.072 -5.642 7.996 -2.132 10.323 c --2.074 10.362 -2.11 10.475 -2.183 10.444 c --4.718 9.392 -6.676 7.677 -8.401 5.549 c --10.012 3.563 -13.337 -0.219 -13.311 -2.898 c --13.264 -7.564 -6.67 -5.495 -2.402 -3.549 c --3.574 -4.083 -2.802 -8.887 -2.507 -9.784 c --1.979 -11.392 -0.959 -13.332 0.295 -14.48 c --1.031 -13.256 -0.807 -9 -0.754 -7.363 c --0.658 -4.417 0.266 -1.562 1.92 0.879 c -1.297 0.538 0.655 0.251 0 0 c -f -Q - -endstream endobj 132 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 498.3889 472.0877 cm -0 0 m --0.103 0.076 -0.219 -0.086 -0.133 -0.173 c -2.643 -2.994 5.789 -6.268 7.692 -9.743 c -9.111 -12.333 10 -15.165 8.061 -17.684 c -7.372 -18.581 6.854 -19.103 5.73 -19.325 c -4.748 -19.519 1.835 -19.552 1.1 -18.714 c -3.062 -20.951 4.701 -22.127 7.697 -21.216 c -9.918 -20.54 11.613 -18.816 11.791 -16.435 c -12.335 -9.163 5.045 -3.752 0 0 c -f -Q - -endstream endobj 133 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 492.8147 456.9122 cm -0 0 m --0.16 0.097 -0.29 -0.113 -0.187 -0.242 c -2.291 -3.34 3.989 -6.812 4.713 -10.717 c -5.167 -13.163 5.059 -15.969 4.642 -18.407 c -4.485 -19.324 4.269 -21.009 3.383 -21.57 c -1.963 -22.47 1.212 -20.427 0.009 -19.856 c --0.134 -22.176 -1.004 -24.446 -2.449 -26.267 c --1.548 -25.131 0.312 -24.324 1.36 -23.157 c -2.812 -26.177 5.734 -22.829 6.423 -21.299 c -7.536 -18.825 7.814 -16.002 7.573 -13.321 c -7.106 -8.14 4.548 -2.777 0 0 c -f -Q - -endstream endobj 134 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 486.5007 439.0467 cm -0 0 m --1.407 -2.267 -2.957 -4.601 -4.619 -6.686 c --6.313 -8.811 -8.453 -10.492 -10.19 -12.571 c --10.363 -12.778 -10.206 -13.217 -9.891 -13.087 c --4.788 -10.986 -1.1 -5.201 0.121 -0.051 c -0.138 0.022 0.04 0.064 0 0 c -f -Q - -endstream endobj 135 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 385.3572 242.2022 cm -0 0 m --0.895 -1.234 -1.796 -2.461 -2.741 -3.656 c --3.673 -4.835 -4.708 -6.026 -6.11 -6.569 c --6.349 -6.661 -6.622 -6.732 -6.854 -6.624 c --7.14 -6.491 -7.248 -6.146 -7.314 -5.838 c --8.107 -2.165 -6.969 1.331 -6.015 4.851 c --5.07 8.336 -3.857 11.746 -2.365 15.034 c --2.342 15.085 -2.417 15.13 -2.441 15.079 c --4.417 10.802 -6.987 6.635 -8.303 2.105 c --8.974 -0.203 -10.521 -4.628 -8.972 -6.914 c --7.318 -9.356 -4.943 -7.969 -3.383 -6.226 c --2.501 -5.241 -1.839 -4.142 -1.199 -3.002 c --0.559 -1.861 -0.158 -0.219 0.58 0.802 c -0.387 0.535 0.193 0.267 0 0 c -f -Q - -endstream endobj 136 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 395.2859 239.6393 cm -0 0 m -0.118 0.906 -0.004 1.927 -0.113 2.567 c --0.357 1.613 -0.824 0.717 -1.464 -0.031 c --1.581 -0.168 -1.715 -0.306 -1.891 -0.345 c --2.118 -0.395 -2.343 -0.264 -2.527 -0.122 c --5.105 1.857 -5.065 5.306 -5.048 8.223 c --5.035 10.551 -4.808 12.888 -4.707 15.214 c --4.702 15.316 -4.85 15.329 -4.879 15.237 c --6.373 10.571 -7.357 4.68 -4.743 0.181 c --4.132 -0.871 -2.623 -2.198 -1.289 -1.872 c --0.465 -1.671 -0.116 -0.89 0 0 c -f -Q - -endstream endobj 137 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 405.3152 244.4266 cm -0 0 m --1.293 1.092 -2.53 2.996 -3.128 3.904 c --4.493 5.975 -5.525 8.244 -6.538 10.501 c --6.369 8.098 -5.852 5.586 -4.61 3.494 c --3.345 1.361 -0.933 -0.651 1.63 -0.812 c -1.106 -0.779 0.548 -0.462 0 0 c -f -Q - -endstream endobj 138 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 541.7224 304.3641 cm -0 0 m --2.193 4.58 -4.974 9.385 -8.329 13.205 c --8.387 13.271 -8.503 13.201 -8.477 13.119 c --7.067 8.757 -4.51 5.048 -2.483 0.975 c --1.166 -1.673 -0.109 -4.563 -0.822 -7.559 c --2.253 -13.581 -6.853 -6.997 -8.783 -5.226 c --7.455 -7.997 -6.24 -10.862 -5.734 -13.894 c --5.159 -17.34 -5.63 -20.888 -7.509 -23.876 c --6.633 -23.727 -5.882 -23.133 -5.354 -22.418 c --3.745 -20.24 -3.274 -16.87 -3.699 -14.271 c --3.761 -13.892 -3.846 -13.513 -3.939 -13.136 c --2.14 -13.583 -0.342 -12.663 0.806 -9.43 c -1.948 -6.215 1.442 -3.012 0 0 c -f -Q - -endstream endobj 139 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 465.425 696.7894 cm -0 0 m -0.29 -1.284 -0.504 -2.557 -1.772 -2.843 c --3.041 -3.128 -4.303 -2.319 -4.592 -1.035 c --4.882 0.249 -4.088 1.522 -2.82 1.808 c --1.552 2.093 -0.289 1.284 0 0 c -f -Q - -endstream endobj 140 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 527.4568 288.8685 cm -0 0 m --0.408 1.003 -0.919 1.949 -1.52 2.799 c -0.971 -2.472 -0.083 -8 -2.422 -13.113 c --2.533 -13.356 -2.253 -13.603 -2.042 -13.406 c -1.578 -10.041 1.81 -4.453 0 0 c -f -Q - -endstream endobj 141 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 428.5193 216.0067 cm -0 0 m --17.176 8.498 -37.882 9.569 -56.495 6.479 c --56.567 6.467 -56.551 6.342 -56.477 6.349 c --37.031 8.281 -18.767 4.82 -0.102 -0.242 c -0.039 -0.28 0.137 -0.068 0 0 c -f -Q - -endstream endobj 142 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 558.5676 222.4176 cm -0 0 m --16.012 5.171 -36.603 1.976 -50.383 -7.631 c --50.44 -7.67 -50.407 -7.781 -50.332 -7.751 c --42.594 -4.634 -34.679 -1.751 -26.415 -0.392 c --17.62 1.054 -8.87 0.414 -0.047 -0.346 c -0.159 -0.364 0.181 -0.059 0 0 c -f -Q - -endstream endobj 143 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.812 0.89 1 scn -/GS0 gs -q 1 0 0 1 429.4827 666.8031 cm -0 0 m -0 0.002 l --1.899 15.277 -5.832 30.233 -11.69 44.455 c --13.617 49.123 -17.098 55.523 -25.047 57.199 c --28.399 57.907 -31.799 57.73 -34.995 57.488 c --56.345 55.873 -84.076 48.209 -107.369 37.489 c --112.255 35.237 -113.996 32.795 -114.53 27.442 c --115.368 19.079 -112.029 9.838 -109.083 1.685 c --108.632 0.437 -108.193 -0.776 -107.788 -1.942 c --105.728 -7.875 -103.322 -13.793 -100.638 -19.533 c --100.34 -20.17 -100.045 -20.807 -99.751 -21.444 c --98.132 -24.947 -96.458 -28.57 -94.24 -31.927 c --93.417 -33.172 -92.528 -34.357 -91.597 -35.453 c --90.62 -36.6 -89.265 -38.034 -87.439 -38.953 c --86.149 -39.598 -84.772 -39.91 -83.581 -40.132 c --81.522 -40.502 -79.416 -40.662 -77.285 -40.662 c --69.903 -40.662 -62.231 -38.743 -55.28 -37.005 c --52.881 -36.408 l --44.197 -34.271 -15.508 -23.573 -9.004 -18.796 c --1.726 -13.454 0.967 -7.833 0 0 c -f -Q -q 1 0 0 1 550.4016 705.2531 cm -0 0 m -0 0.008 l --0.124 3.759 -0.798 7.433 -1.451 10.987 c --1.572 11.648 -1.693 12.31 -1.812 12.975 c --2.858 18.814 -4.21 24.66 -5.83 30.355 c --6.152 31.482 -6.474 32.662 -6.806 33.875 c --8.95 41.729 -11.381 50.631 -16.488 56.689 c --19.786 60.607 -22.439 61.603 -27.403 60.793 c --48.321 57.385 -68.573 50.061 -87.594 39.025 c --90.159 37.537 -92.844 35.891 -94.999 33.589 c --100.157 28.078 -99.354 21.243 -98.3 16.581 c --95.119 2.503 -90.081 -11.155 -83.326 -24.016 c --79.527 -31.241 -75.009 -34.188 -67.215 -34.526 c --66.638 -34.551 -66.064 -34.563 -65.489 -34.563 c --58.548 -34.563 -51.707 -32.806 -44.741 -30.841 c --37.474 -28.793 -29.76 -26.518 -22.372 -23.216 c --16.638 -20.647 -8.785 -17.131 -3.701 -12.037 c --2.979 -11.304 -2.065 -10.306 -1.39 -9.062 c --0.492 -7.367 -0.235 -5.53 -0.112 -4.134 c -0.007 -2.867 0.044 -1.515 0 0 c -f -Q - -endstream endobj 144 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 CS 0.812 0.89 1 SCN -15.975 w 10 M 0 j 0 J []0 d -/GS0 gs -q 1 0 0 1 429.4827 666.8031 cm -0 0 m -0 0.002 l --1.899 15.277 -5.832 30.233 -11.69 44.455 c --13.617 49.123 -17.098 55.523 -25.047 57.199 c --28.399 57.907 -31.799 57.73 -34.995 57.488 c --56.345 55.873 -84.076 48.209 -107.369 37.489 c --112.255 35.237 -113.996 32.795 -114.53 27.442 c --115.368 19.079 -112.029 9.838 -109.083 1.685 c --108.632 0.437 -108.193 -0.776 -107.788 -1.942 c --105.728 -7.875 -103.322 -13.793 -100.638 -19.533 c --100.34 -20.17 -100.045 -20.807 -99.751 -21.444 c --98.132 -24.947 -96.458 -28.57 -94.24 -31.927 c --93.417 -33.172 -92.528 -34.357 -91.597 -35.453 c --90.62 -36.6 -89.265 -38.034 -87.439 -38.953 c --86.149 -39.598 -84.772 -39.91 -83.581 -40.132 c --81.522 -40.502 -79.416 -40.662 -77.285 -40.662 c --69.903 -40.662 -62.231 -38.743 -55.28 -37.005 c --52.881 -36.408 l --44.197 -34.271 -15.508 -23.573 -9.004 -18.796 c --1.726 -13.454 0.967 -7.833 0 0 c -h -S -Q -q 1 0 0 1 550.4016 705.2531 cm -0 0 m -0 0.008 l --0.124 3.759 -0.798 7.433 -1.451 10.987 c --1.572 11.648 -1.693 12.31 -1.812 12.975 c --2.858 18.814 -4.21 24.66 -5.83 30.355 c --6.152 31.482 -6.474 32.662 -6.806 33.875 c --8.95 41.729 -11.381 50.631 -16.488 56.689 c --19.786 60.607 -22.439 61.603 -27.403 60.793 c --48.321 57.385 -68.573 50.061 -87.594 39.025 c --90.159 37.537 -92.844 35.891 -94.999 33.589 c --100.157 28.078 -99.354 21.243 -98.3 16.581 c --95.119 2.503 -90.081 -11.155 -83.326 -24.016 c --79.527 -31.241 -75.009 -34.188 -67.215 -34.526 c --66.638 -34.551 -66.064 -34.563 -65.489 -34.563 c --58.548 -34.563 -51.707 -32.806 -44.741 -30.841 c --37.474 -28.793 -29.76 -26.518 -22.372 -23.216 c --16.638 -20.647 -8.785 -17.131 -3.701 -12.037 c --2.979 -11.304 -2.065 -10.306 -1.39 -9.062 c --0.492 -7.367 -0.235 -5.53 -0.112 -4.134 c -0.007 -2.867 0.044 -1.515 0 0 c -h -S -Q - -endstream endobj 145 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 395.1042 692.004 cm -0 0 m --1.043 -8.793 -2.045 -17.588 -3.219 -26.365 c --4.267 -34.21 -5.56 -42.023 -6.652 -49.86 c --4.388 -49.038 -2.035 -48.156 0.309 -47.251 c -2.9 -36.638 5.108 -25.93 7.86 -15.355 c -10.487 -5.258 13.84 4.641 16.383 14.746 c -16.165 15.291 15.963 15.842 15.74 16.385 c -13.626 21.504 11.32 23.896 7.778 24.643 c -6.696 24.871 5.458 24.982 3.996 24.982 c -3.474 24.982 2.939 24.959 2.406 24.936 c -1.856 16.602 0.983 8.293 0 0 c -f -Q -q 1 0 0 1 359.5554 710.0402 cm -0 0 m --1.244 -4.235 -2.576 -8.446 -3.943 -12.643 c --5.224 -16.578 -6.572 -20.494 -7.806 -24.443 c --9.076 -28.509 -10.145 -32.65 -11.248 -36.764 c --13.427 -44.894 -15.449 -53.066 -17.34 -61.268 c --17.953 -63.927 -18.531 -66.593 -19.117 -69.258 c --18.77 -69.854 -18.419 -70.447 -18.042 -71.017 c --17.385 -72.011 -16.677 -72.956 -15.949 -73.814 c --15.644 -74.171 -14.833 -75.122 -14.149 -75.466 c --13.629 -75.727 -12.681 -75.903 -12.322 -75.97 c --10.806 -76.243 -9.135 -76.381 -7.358 -76.381 c --2.995 -76.381 1.604 -75.579 6.213 -74.542 c -8.408 -66.252 10.596 -57.961 12.766 -49.666 c -15.412 -39.548 17.836 -29.348 20.86 -19.335 c -23.435 -10.808 26.348 -2.389 29.071 6.09 c -20.026 4.96 10.083 2.854 0 0 c -f -Q -q 1 0 0 1 518.8674 753.1073 cm -0 0 m --0.722 -14.188 -1.417 -28.352 -1.541 -42.562 c --1.612 -50.75 -1.533 -58.942 -1.263 -67.126 c --0.73 -66.937 -0.198 -66.744 0.333 -66.546 c -0.476 -65.653 0.61 -64.758 0.76 -63.866 c -4.207 -43.379 9.354 -23.223 13.263 -2.828 c -12.156 -0.228 10.866 2.13 9.295 3.994 c -7.874 5.682 7.54 5.682 6.986 5.682 c -6.558 5.682 6.003 5.627 5.34 5.519 c -3.624 5.24 1.915 4.922 0.208 4.588 c -0.148 3.058 0.078 1.529 0 0 c -f -Q -q 1 0 0 1 488.595 748.5773 cm -0 0 m --2.301 -13.261 -4.346 -26.566 -6.344 -39.875 c --7.8 -49.568 -9.242 -59.264 -10.74 -68.951 c --9.29 -69.851 -7.533 -70.233 -5.08 -70.34 c --4.612 -70.36 -4.148 -70.37 -3.683 -70.37 c -1.774 -70.37 7.438 -69.028 13.241 -67.426 c -13.774 -63.831 14.369 -60.242 14.915 -56.651 c -16.481 -46.355 18.088 -36.065 19.812 -25.795 c -21.411 -16.275 22.954 -6.722 25.204 2.669 c -25.649 4.526 26.112 6.405 26.556 8.297 c -17.541 6.297 8.673 3.522 0 0 c -f -Q - -endstream endobj 146 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 429.0129 666.7445 cm -0 0 m -0.946 -7.636 -1.688 -13.126 -8.808 -18.355 c --15.277 -23.106 -43.862 -33.761 -52.519 -35.892 c --54.906 -36.487 l --61.732 -38.194 -69.468 -40.129 -76.828 -40.129 c --79.023 -40.129 -81.111 -39.954 -83.032 -39.607 c --84.164 -39.404 -85.492 -39.109 -86.761 -38.472 c --88.509 -37.593 -89.822 -36.204 -90.77 -35.092 c --91.33 -34.434 -91.862 -33.738 -92.386 -33.018 c --92.309 -33.139 -92.242 -33.265 -92.163 -33.385 c --91.332 -34.653 -90.486 -35.792 -89.579 -36.867 c --88.638 -37.979 -87.335 -39.368 -85.601 -40.247 c --84.342 -40.884 -83.024 -41.178 -81.901 -41.382 c --79.995 -41.729 -77.923 -41.904 -75.746 -41.904 c --68.443 -41.904 -60.768 -39.969 -53.995 -38.261 c --51.626 -37.667 l --43.037 -35.536 -14.676 -24.881 -8.258 -20.13 c --1.193 -14.901 1.42 -9.412 0.482 -1.775 c --0.725 8.04 -2.783 17.721 -5.639 27.165 c --3.037 18.284 -1.14 9.201 0 0 c -f -Q - -endstream endobj 147 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 309.0198 671.9906 cm -0 0 m --2.36 4.997 -4.073 10.301 -5.09 15.764 c --5.189 16.296 -5.295 16.822 -5.398 17.341 c --6.366 22.173 -6.711 24.793 -3.273 26.918 c -2.12 30.253 7.708 33.181 15.411 36.708 c -35.24 45.791 62.935 53.396 84.326 55.633 c -85.068 55.711 l -87.593 55.979 90.735 56.311 93.898 56.311 c -99.297 56.311 102.995 55.307 104.888 53.326 c -106.776 51.349 108.542 48.863 110.442 45.505 c -111.885 42.954 l -113.579 45.343 l -117.287 50.573 125.349 52.914 131.694 52.914 c -133.33 52.914 134.89 52.769 136.329 52.483 c -138.765 52 l -138.547 54.492 l -138.258 57.795 138.289 60.438 138.64 62.81 c -139.401 67.928 147.746 72.477 152.229 74.921 c -152.827 75.247 l -172.893 86.225 192.012 93.303 209.654 96.286 c -217.332 97.584 223.095 98.24 228.922 98.479 c -229.039 98.484 229.152 98.486 229.265 98.486 c -232.649 98.486 233.736 96.331 235.516 92.203 c -235.712 91.745 235.913 91.282 236.12 90.818 c -238.251 86.049 239.773 81.042 240.646 75.933 c -240.841 74.786 240.914 73.536 240.811 72.468 c -241.429 73.62 241.439 75.804 241.111 77.708 c -240.232 82.816 238.698 87.824 236.55 92.593 c -236.341 93.057 236.139 93.52 235.941 93.978 c -234.147 98.106 233.052 100.261 229.641 100.261 c -229.527 100.261 229.413 100.259 229.295 100.254 c -223.422 100.015 217.614 99.359 209.875 98.061 c -192.094 95.078 172.825 88 152.601 77.022 c -151.998 76.696 l -147.479 74.252 139.069 69.703 138.301 64.585 c -137.947 62.213 137.917 59.57 138.208 56.267 c -138.427 53.775 l -135.972 54.258 l -134.521 54.544 132.95 54.688 131.301 54.688 c -124.906 54.688 116.78 52.347 113.043 47.118 c -111.336 44.729 l -109.881 47.28 l -107.966 50.638 106.187 53.124 104.283 55.101 c -102.375 57.082 98.649 58.086 93.207 58.086 c -90.02 58.086 86.852 57.754 84.307 57.486 c -83.56 57.408 l -62 55.171 34.086 47.566 14.101 38.483 c -6.337 34.956 0.705 32.028 -4.73 28.693 c --8.195 26.568 -7.848 23.948 -6.873 19.116 c --6.768 18.597 -6.662 18.071 -6.562 17.539 c --5.536 12.076 -3.81 6.772 -1.431 1.775 c --0.782 0.411 0.105 -0.958 1.04 -1.868 c -0.655 -1.275 0.301 -0.637 0 0 c -f -Q - -endstream endobj 148 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 554.3157 705.7198 cm -0 0 m --0.031 0.774 -0.064 1.58 -0.086 2.431 c --0.24 8.169 -1.584 15.659 -2.664 21.677 c --2.794 22.404 l --2.877 22.863 -3.624 25.888 -4.284 28.557 c --4.728 30.352 -5.183 32.194 -5.52 33.591 c --5.768 34.615 -5.945 35.368 -6.026 35.96 c --6.803 35.3 -6.583 34.353 -5.975 31.816 c --5.641 30.419 -5.189 28.577 -4.749 26.782 c --4.094 24.113 -3.353 21.088 -3.271 20.629 c --3.142 19.902 l --2.07 13.884 -0.736 6.395 -0.584 0.656 c --0.562 -0.195 -0.529 -1 -0.499 -1.775 c --0.368 -5.014 -0.278 -7.504 -0.988 -10.502 c --0.986 -10.498 -0.984 -10.494 -0.983 -10.49 c -0.27 -6.637 0.157 -3.853 0 0 c -f -Q - -endstream endobj 149 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 467.6726 679.6827 cm -0 0 m -3.677 -7.054 8.05 -9.931 15.594 -10.262 c -16.164 -10.287 16.732 -10.299 17.3 -10.299 c -24.13 -10.299 30.868 -8.545 37.744 -6.591 c -44.951 -4.544 52.596 -2.271 59.875 1.009 c -65.521 3.553 73.256 7.039 78.247 12.085 c -78.995 12.842 79.845 13.775 80.467 14.949 c -80.991 15.939 81.285 16.988 81.463 17.968 c -81.316 17.549 81.138 17.132 80.921 16.724 c -80.293 15.55 79.438 14.617 78.683 13.86 c -73.653 8.813 65.857 5.328 60.166 2.783 c -52.83 -0.496 45.124 -2.77 37.861 -4.816 c -30.931 -6.77 24.14 -8.524 17.256 -8.524 c -16.684 -8.524 16.111 -8.512 15.537 -8.487 c -7.933 -8.156 3.526 -5.279 -0.181 1.775 c --6.908 14.579 -11.934 28.198 -15.115 42.257 c --15.194 42.605 -15.27 42.97 -15.344 43.341 c --15.204 42.326 -15.016 41.364 -14.817 40.482 c --11.661 26.424 -6.675 12.804 0 0 c -f -Q - -endstream endobj 150 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 471.8523 700.2631 cm -0 0 m --3.636 -1.122 -7.229 -2.5 -10.212 -4.591 c --14.764 -7.782 -14.939 -13.332 -10.401 -16.719 c --8.181 -18.377 -5.377 -19.08 -2.614 -19.298 c -2.545 -19.705 7.868 -18.493 12.184 -15.636 c -16.5 -12.78 19.74 -8.248 20.762 -3.175 c -22.191 3.919 17.299 4.253 11.82 3.1 c -7.833 2.261 3.895 1.202 0 0 c -f -Q - -endstream endobj 151 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 332.3298 631.0533 cm -0 0 m --0.448 0.695 -0.913 1.417 -1.416 2.173 c --4.81 7.282 -8.217 14.634 -10.954 20.542 c --11.287 21.259 l --11.498 21.714 -12.697 24.823 -13.755 27.566 c --16.549 34.805 -17.013 36 -17.872 36.198 c --17.297 34.957 -16.487 32.877 -15.111 29.341 c --14.045 26.598 -12.836 23.489 -12.623 23.034 c --12.288 22.317 l --9.529 16.409 -6.095 9.057 -2.674 3.948 c --2.167 3.192 -1.699 2.47 -1.248 1.775 c --0.394 0.46 0.372 -0.716 1.184 -1.813 c -0.799 -1.234 0.411 -0.637 0 0 c -f -Q - -endstream endobj 152 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 486.4407 655.0448 cm -0 0 m --0.088 0.033 -0.184 0.049 -0.277 0.046 c --0.53 0.038 -0.767 -0.076 -0.993 -0.189 c --3.419 -1.394 -5.744 -2.824 -8.191 -3.977 c --8.621 -4.179 -9.043 -4.393 -9.471 -4.599 c --10.021 -4.864 -10.806 -5.444 -10.525 -6.174 c --10.221 -6.962 -9.14 -6.727 -8.514 -6.584 c --8.051 -6.478 -7.608 -6.338 -7.166 -6.164 c --6.236 -5.798 -5.348 -5.363 -4.481 -4.868 c --3.598 -4.363 -2.739 -3.816 -1.893 -3.251 c --0.916 -2.599 -0.179 -1.991 0.265 -0.859 c -0.333 -0.686 0.39 -0.494 0.332 -0.317 c -0.281 -0.165 0.152 -0.057 0 0 c -f -Q - -endstream endobj 153 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 456.7913 642.496 cm -0 0 m --0.197 0.156 -0.442 0.261 -0.689 0.29 c --1.456 0.379 -2.271 0.011 -3.002 -0.164 c --3.787 -0.353 -4.576 -0.579 -5.379 -0.719 c --7.106 -1.019 -8.886 -1.115 -10.542 -1.733 c --10.721 -1.8 -10.903 -1.876 -11.031 -2.017 c --11.159 -2.158 -11.217 -2.38 -11.117 -2.542 c --11.046 -2.655 -10.916 -2.716 -10.792 -2.766 c --7.64 -4.044 -3.896 -3.153 -0.822 -2 c --0.282 -1.797 0.327 -1.483 0.416 -0.912 c -0.472 -0.556 0.286 -0.226 0 0 c -f -Q - -endstream endobj 154 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 462.3577 643.7882 cm -0 0 m --0.432 1.038 -2.57 0.113 -3.284 -0.152 c --3.552 -0.252 -3.823 -0.368 -4.027 -0.569 c --4.23 -0.771 -4.354 -1.076 -4.268 -1.349 c --4.19 -1.595 -3.957 -1.768 -3.708 -1.836 c --3.459 -1.905 -3.195 -1.885 -2.939 -1.85 c --2.149 -1.745 0.534 -1.284 0 0 c -f -Q - -endstream endobj 155 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 488.8245 584.1515 cm -0 0 m --0.669 1.449 -1.706 2.611 -3.09 3.417 c --4.352 4.152 -6.407 4.735 -7.722 3.783 c --8.552 3.182 -8.875 2.229 -8.378 1.278 c --7.802 0.174 -6.513 -0.396 -5.719 -1.318 c --5.317 -1.784 -5.159 -1.962 -4.845 -2.453 c --4.447 -3.078 -4.055 -3.478 -3.555 -3.735 c --3.341 -3.943 -3.134 -4.16 -2.931 -4.372 c --2.242 -5.092 -0.927 -4.937 -0.446 -4.052 c --0.288 -3.76 -0.123 -3.443 -0.02 -3.13 c -0.006 -3.039 0.033 -2.948 0.059 -2.856 c -0.079 -2.746 0.094 -2.654 0.106 -2.576 c -0.567 -1.782 0.359 -0.778 0 0 c -f -Q - -endstream endobj 156 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 478.8357 588.9525 cm -0 0 m --0.214 0.248 -0.433 0.523 -0.8 0.673 c --1.178 0.827 -1.616 0.843 -2.021 0.864 c --2.585 0.893 -3.094 0.544 -3.38 0.075 c --3.553 -0.118 -3.66 -0.344 -3.844 -0.524 c --4.334 -1.004 -3.977 -1.925 -3.273 -1.903 c --3.217 -1.901 -3.069 -1.952 -2.922 -2.005 c --2.548 -2.281 -2.092 -2.415 -1.599 -2.263 c --0.992 -2.077 -0.451 -1.96 -0.059 -1.465 c -0.357 -1.057 0.417 -0.482 0 0 c -f -Q - -endstream endobj 157 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 424.7092 688.0753 cm -0 0 m --0.387 1.469 -0.831 2.919 -1.324 4.342 c --4.049 12.197 -8.261 19.614 -14.14 25.492 c --20.019 31.371 -27.624 35.65 -35.838 36.938 c --46.747 38.649 -57.956 34.847 -66.458 28.016 c --70.266 24.957 -73.919 21.519 -76.596 17.385 c --84.984 4.43 -83.023 -13.528 -76.117 -26.781 c --72.071 -34.545 -65.724 -41.177 -57.902 -45.111 c --55.261 -46.438 -52.389 -47.473 -49.434 -47.428 c --46.479 -47.384 -43.424 -46.107 -41.814 -43.628 c --45.071 -44.039 -48.766 -43.012 -51.604 -41.432 c --57.81 -37.977 -62.311 -33.451 -64.983 -27.98 c --68.075 -21.643 -69.194 -14.273 -68.633 -7.275 c --68.145 -1.191 -64.61 4.29 -60.522 8.753 c --52.573 17.431 -39.891 23.288 -28.169 19.393 c --16.873 15.639 -8.475 5.311 -5.706 -8.235 c --4.154 -15.841 -4.7 -22.391 -7.328 -27.703 c --9.022 -31.127 -11.491 -33.519 -14.288 -36.033 c --11.99 -35.194 -9.792 -36.427 -7.632 -35.984 c --5.272 -35.5 -3.515 -32.894 -2.447 -30.944 c -2.65 -21.634 2.727 -10.351 0 0 c -f -Q - -endstream endobj 158 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 502.0042 687.5743 cm -0 0 m --2.37 -3.324 l --2.486 -3.398 -2.602 -3.474 -2.717 -3.551 c --6.117 -5.821 -9.203 -7.84 -12.527 -9.547 c --17.561 -12.122 -23.59 -11.767 -30.454 -8.492 c --37.996 -4.913 -42.168 2.442 -44.341 7.982 c --46.783 14.205 -53.758 35.326 -41.009 45.856 c --37.017 49.151 -32.033 50.134 -28.552 50.379 c --27.803 50.434 -27.049 50.46 -26.29 50.46 c --19.048 50.46 -11.434 48.031 -5.191 43.731 c --5.467 43.744 -5.748 43.754 -6.032 43.766 c --7.477 43.822 -8.971 43.88 -10.088 44.133 c --14.809 45.202 l --10.832 42.444 l --2.103 36.392 0.797 26.811 2.483 18.235 c -3.17 14.764 4.305 6.038 0 0 c -5.664 0.613 m -8.186 3.623 8.243 10.917 8.361 14.624 c -8.684 24.684 5.893 34.71 1.855 43.699 c -0.611 46.468 -0.768 49.187 -2.479 51.693 c --6.692 57.867 -12.93 62.635 -19.993 65.081 c --25.645 67.038 -31.921 67.503 -37.618 65.678 c --51.084 61.365 -54.994 46.079 -55.033 33.471 c --55.075 20.135 -50.537 6.729 -41.965 -3.542 c --40.383 -5.437 -38.655 -7.248 -36.573 -8.575 c --33.9 -10.278 -30.768 -11.107 -27.65 -11.675 c --24.355 -12.274 -20.947 -12.607 -17.671 -11.911 c --14.223 -11.178 -11.121 -9.353 -8.088 -7.556 c --5.714 -6.149 -3.34 -4.742 -0.967 -3.335 c -0.877 -2.242 4.063 -1.118 5.5 0.428 c -5.556 0.488 5.61 0.549 5.664 0.613 c -f -Q - -endstream endobj 159 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 395.0432 469.7684 cm -0 0 m -2.094 -0.864 4.235 -1.611 6.415 -2.232 c -9.495 -3.111 12.768 -3.748 15.887 -3.017 c -11.358 -6.692 7.931 -11.707 6.152 -17.261 c -5.79 -18.395 5.491 -19.586 5.649 -20.765 c -6.296 -25.591 15.029 -26.902 15.414 -21.484 c -14.725 -31.178 18.779 -41.098 26.061 -47.534 c -27.926 -49.183 30.076 -50.65 32.531 -51.065 c -34.985 -51.48 37.785 -50.615 39.065 -48.48 c -39.313 -51.389 40.512 -54.209 42.434 -56.407 c -43.418 -57.532 44.622 -58.516 46.047 -58.969 c -47.838 -59.538 49.793 -59.216 51.59 -58.663 c -55.774 -57.374 59.563 -54.828 62.339 -51.441 c -62.706 -52.77 63.072 -54.098 63.438 -55.426 c -71.794 -53.396 80.387 -49.365 86.448 -43.147 c -85.513 -43.925 86.11 -45.621 87.24 -46.07 c -88.37 -46.519 89.656 -46.084 90.721 -45.498 c -92.809 -44.346 94.559 -42.592 95.705 -40.501 c -95.627 -41.208 96.059 -41.942 96.715 -42.217 c -103.699 -37.905 107.318 -28.789 105.195 -20.861 c -107.147 -23.324 111.362 -22.918 113.485 -20.6 c -115.609 -18.283 115.934 -14.772 115.238 -11.706 c -113.616 -4.552 107.437 0.601 101.214 4.487 c -104.762 1.447 112.416 -10.591 103.845 -11.31 c -99.71 -11.656 95.501 -11.082 91.611 -9.642 c -95.747 -13.569 99.813 -19.248 97.64 -24.521 c -97.165 -25.674 96.083 -26.84 94.873 -26.542 c -94.314 -26.404 93.877 -25.98 93.49 -25.554 c -91.369 -23.215 89.904 -20.287 89.304 -17.187 c -91.661 -22.494 88.46 -28.558 84.907 -33.152 c -81.632 -37.387 77.822 -41.419 72.94 -43.615 c -71.94 -44.065 70.862 -44.439 69.77 -44.344 c -67.044 -44.107 65.393 -40.354 67.058 -38.184 c -63.31 -42.676 58.737 -47.567 52.888 -47.459 c -46.968 -47.35 42.069 -40.875 43.574 -35.149 c -43.53 -38.59 39.529 -40.965 36.144 -40.347 c -32.758 -39.729 30.132 -37.002 28.351 -34.058 c -26.062 -30.273 24.826 -26.231 25.225 -21.861 c -25.442 -19.472 26.496 -11.386 29.203 -10.323 c -26.419 -11.416 23.636 -12.508 20.853 -13.599 c -19.595 -14.093 18.266 -14.595 16.928 -14.406 c -15.59 -14.217 14.286 -13.065 14.438 -11.722 c -14.508 -11.11 14.856 -10.57 15.208 -10.064 c -18.797 -4.908 26.37 -1.259 32.593 -0.913 c -35.137 -0.772 37.711 -1.023 40.225 -0.603 c -37.833 -0.76 36.063 -3.415 36.519 -5.768 c -36.975 -8.121 39.273 -9.865 41.664 -10.046 c -44.053 -10.226 46.415 -9.035 48.023 -7.259 c -46.561 -10.609 48.237 -16.316 52.373 -16.65 c -55.793 -16.927 58.975 -13.765 59.055 -10.334 c -58.521 -11.418 57.712 -12.509 56.529 -12.756 c -54.99 -13.076 53.488 -11.731 53.108 -10.205 c -52.729 -8.678 53.189 -7.075 53.76 -5.609 c -54.257 -4.33 54.842 -3.083 55.508 -1.883 c -56.212 -0.613 62.757 -0 64.667 0.47 c -69.405 1.639 74.29 2.174 79.026 3.437 c -98.493 8.475 117.232 17.677 131.61 31.937 c -138.995 39.261 140.862 45.978 137.21 55.649 c -136.922 56.411 136.626 57.189 136.33 57.995 c -136.145 58.497 135.976 59.005 135.813 59.516 c -130.236 52.59 122.553 47.025 115.16 42.595 c -90.619 27.892 62.231 21.821 33.823 21.751 c -15.596 21.707 -5.782 24.344 -21.926 34.227 c --21.481 33.953 -22.363 27.867 -22.759 27.155 c --23.693 25.477 -26.251 23.844 -27.575 22.425 c --20.852 12.46 -11.105 4.583 0 0 c -f -Q - -endstream endobj 160 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 688.6355 572.0026 cm -0 0 m --0.105 0.778 -0.218 1.578 -0.318 2.406 c -1.009 -3.083 -2.934 -8.524 -7.506 -11.838 c --12.404 -15.388 -18.294 -17.556 -24.326 -18.03 c --23.08 -34.075 -35.414 -50.042 -51.254 -52.888 c --49.527 -54.215 -49.371 -56.724 -49.467 -58.9 c --50.469 -81.62 -63.261 -103.5 -82.569 -115.517 c --80.384 -115.633 -78.08 -115.787 -76.259 -117.001 c --74.438 -118.216 -73.395 -120.883 -74.67 -122.662 c --75.348 -123.609 -76.493 -124.088 -77.596 -124.461 c --82.092 -125.986 -86.92 -126.523 -91.641 -126.026 c --90.244 -127.984 -86.236 -127.156 -85.666 -129.493 c --85.296 -131.006 -86.896 -132.22 -88.301 -132.892 c --100.926 -138.936 -116.383 -138.682 -128.802 -132.227 c --140.168 -126.319 -150.055 -114.873 -151.134 -101.798 c --150.219 -110.523 -150.084 -119.272 -149.295 -128.006 c --149.186 -129.222 -148.178 -144.426 -148.865 -144.282 c --144.37 -145.223 -140.417 -145.226 -136.061 -146.86 c --134.009 -147.631 -132.236 -148.296 -131.071 -148.532 c --122.668 -150.244 -114.102 -150.633 -105.616 -149.692 c --98.589 -148.918 -91.103 -146.755 -83.963 -143.436 c --81.055 -142.084 -78.369 -140.622 -75.977 -139.089 c --71.527 -136.23 -72.017 -133.635 -72.709 -132.331 c --73.197 -131.444 -73.994 -130.855 -74.711 -130.393 c --75.131 -130.126 -75.56 -129.873 -75.995 -129.635 c --71.776 -129.381 -67.298 -128.676 -63.934 -126.758 c --62.296 -125.822 -60.104 -124.364 -59.96 -122.546 c --59.892 -121.832 -60.113 -120.796 -61.559 -119.907 c --62.626 -119.253 -64.109 -119.294 -65.417 -119.325 c --65.916 -119.34 -66.389 -119.351 -66.758 -119.321 c --67.528 -119.259 -68.313 -119.227 -69.103 -119.195 c --69.438 -119.181 -69.776 -119.167 -70.113 -119.151 c --69.223 -118.467 -68.188 -117.572 -66.979 -116.486 c --66.642 -116.183 -66.369 -115.938 -66.193 -115.79 c --64.148 -114.08 -62.556 -112.226 -60.872 -110.263 c --59.94 -109.183 l --55.932 -104.556 -53.257 -98.888 -51.168 -93.954 c --48.95 -88.708 -46.975 -82.835 -45.13 -75.998 c --44.389 -73.251 -43.638 -70.244 -42.764 -66.53 c --42.525 -65.495 -42.248 -64.465 -41.97 -63.432 c --41.702 -62.43 l --41.572 -61.951 -41.454 -61.444 -41.334 -60.935 c --41.156 -60.175 -40.972 -59.39 -40.751 -58.727 c --40.492 -57.966 -40.086 -57.754 -39.112 -57.305 c --38.932 -57.223 -38.744 -57.137 -38.551 -57.042 c --37.156 -56.363 -35.779 -55.542 -34.346 -54.533 c --30.942 -52.156 -28.715 -48.101 -26.987 -44.451 c --25.167 -40.625 -23.759 -36.602 -22.472 -32.806 c --22.121 -31.758 -21.685 -30.667 -21.222 -29.513 c --20.123 -26.767 -18.986 -23.927 -18.798 -21.154 c --18.773 -20.783 l --18.277 -20.535 -17.704 -20.222 -17.031 -19.844 c --16.732 -19.675 -16.492 -19.539 -16.358 -19.474 c --15.029 -18.832 -13.594 -18.284 -12.207 -17.754 c --8.952 -16.51 -5.587 -15.225 -2.979 -12.568 c -0.995 -8.524 0.63 -4.669 0 0 c -f -Q - -endstream endobj 217 0 obj <> endobj 32 0 obj <> endobj 31 0 obj [/ICCBased 218 0 R] endobj 218 0 obj <>stream -HyTSwoɞc [5, BHBK!aPVX=u:XKèZ\;v^N߽~w.MhaUZ>31[_& (DԬlK/jq'VOV?:OsRUzdWRab5? Ζ&VϳS7Trc3MQ]Ymc:B :Ŀ9ᝩ*UUZ<"2V[4ZLOMa?\⎽"?.KH6|zӷJ.Hǟy~Nϳ}Vdfc -n~Y&+`;A4I d|(@zPZ@;=`=v0v <\$ x -^AD W P$@P>T !-dZP C; t -@A/a<v}a1'X Mp'G}a|OY 48"BDH4)EH+ҍ "~rL"(*DQ)*E]a4zBgE#jB=0HIpp0MxJ$D1(%ˉ^Vq%],D"y"Hi$9@"m!#}FL&='dr%w{ȟ/_QXWJ%4R(cci+**FPvu? 6 Fs2hriStݓ.ҍu_џ0 7F4a`cfb|xn51)F]6{̤0]1̥& "rcIXrV+kuu5E4v}}Cq9JN')].uJ - - wG x2^9{oƜchk`>b$eJ~ :Eb~,m,-Uݖ,Y¬*6X[ݱF=3뭷Y~dó Qti zf6~`{v.Ng#{}}c1X%6fmFN9NN8SΥ'g\\R]Z\t]\7u}&ps[6v_`) {Q5W=b -_zžAe#``/VKPo !]#N}R|:|}n=/ȯo#JuW_ `$ 6+P-AܠԠUA' %8佐b8]+<q苰0C +_ XZ0nSPEUJ#JK#ʢi$aͷ**>2@ꨖОnu&kj6;k%G PApѳqM㽦5͊---SbhZKZO9uM/O\^W8i׹ĕ{̺]7Vھ]Y=&`͖5_ Ыbhו ۶^ Mw7n<< t|hӹ훩' ZL$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! -zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km  -endstream endobj 216 0 obj <> endobj 215 0 obj <> endobj 214 0 obj <> endobj 213 0 obj <> endobj 212 0 obj <> endobj 211 0 obj <> endobj 210 0 obj <> endobj 209 0 obj <> endobj 208 0 obj <> endobj 207 0 obj <> endobj 206 0 obj <> endobj 205 0 obj <> endobj 204 0 obj <> endobj 203 0 obj <> endobj 202 0 obj <> endobj 201 0 obj <> endobj 200 0 obj <> endobj 199 0 obj <> endobj 198 0 obj <> endobj 197 0 obj <> endobj 196 0 obj <> endobj 195 0 obj <> endobj 194 0 obj <> endobj 193 0 obj <> endobj 192 0 obj <> endobj 191 0 obj <> endobj 190 0 obj <> endobj 189 0 obj <> endobj 188 0 obj <> endobj 187 0 obj <> endobj 186 0 obj <> endobj 185 0 obj <> endobj 184 0 obj <> endobj 183 0 obj <> endobj 182 0 obj <> endobj 181 0 obj <> endobj 180 0 obj <> endobj 179 0 obj <> endobj 178 0 obj <> endobj 177 0 obj <> endobj 176 0 obj <> endobj 175 0 obj <> endobj 174 0 obj <> endobj 173 0 obj <> endobj 172 0 obj <> endobj 171 0 obj <> endobj 170 0 obj <> endobj 169 0 obj <> endobj 168 0 obj <> endobj 167 0 obj <> endobj 166 0 obj <> endobj 165 0 obj <> endobj 164 0 obj <> endobj 163 0 obj <> endobj 162 0 obj <> endobj 44 0 obj <> endobj 45 0 obj <> endobj 46 0 obj <> endobj 221 0 obj <> endobj 222 0 obj <> endobj 220 0 obj <> endobj 223 0 obj <> endobj 219 0 obj <> endobj 224 0 obj <> endobj 26 0 obj <> endobj 225 0 obj [/View/Design] endobj 226 0 obj <>>> endobj 43 0 obj <> endobj 227 0 obj <> endobj 228 0 obj <>stream -HW}p{+_H5 -=r!`׵Pld%He8@H&2mi>a&)SK)mJ':-%540΄t}w=6!I']޽}~=@6BRO5('*N+"@Zڱ5 @+]ʌ9m@Kƹ @Pa䧵wv>-L:~Cs . }kў=hǟNܿcãr 0}E߱1ر<5c~(; ih{ EoI@7: rĀ끭p_2m ^C-.f ]]`h(b&`V62#n@~_gffU2`.vʎ$a` -Ja3g֚'s"7-on7aYVS0xXIYHF'M^ݏh*T4E2y gs'oj@Ӥ٨  -nyƻ5|?Ɵ/Wl3Sq*D$q`-x|0///ߎ5H_lJDZ #^k|2ybFtt_t@tw'ttstuG ){-gBDO_wchj֟>~?J gFS}چ67`l`w-'+C xU.۴wzCB/GG`4C|`#n =d ݤ!a -9D^%Gr8sN L2e'=~ ~kJ5N[zV`Ş.LPbk#yBjX1|n̒酖i733&ҵi(v.? -PtK^ 0F\m$WxKZeiKZF-UAUI1sLs8YEzC1iHPe\69%WW[wHf]3J!d&Rt#BW;+#貕m%jqZa*Kڥt[ YTEY-bK^pQ:ᝒH!:[FES*Yݲ fы,< 8tm$h-aPHhP?BƆ">APb}MHogd9J|W4F4MhD3/ -JfBM^P$ZojnS`Xt8ykJ6@ -3RV?X+RX4@SjUIyv ?RRC9~G2@ŗ=Xd3b64َE)t-7`2Il>LO}JD4# *v<ݢc^D}JP\xkPrR*%&1]R -52bw+*,MOHɔ)"ң`4>ZZ hsc4-`۽\6:EnTRE#yŠl^kuaWvKqI}Ũ.EIUd/PQ}zሚub'xSJ-kY;'u~]z]+8.-U*~ą-a2-n5mQ˅:RX[R/ڈHz"6Y=Fo#>m_vN֢$q_[SZ&c""AYR2ZE^kr"ODzɤ83 -u,LflL77! (+#>@Q߬eV5q~'ʅt)tV& D(d3A#X.yZaQ2"YkfY>1=[O[g Ωf[ )3h -M!H˧Jiι,tq]$tv*|(1t$;U&ѡm&IhHwO2VvPd)w΢@J5^MNSX%ID䕕Zd-/w0/Ph̞tD&= K.KO2t+xY%ϝ}hî Sϴ8ˋ C^oS+;΋ ?КSnf=۟WaN]I[,<,zŒQ88;:FFYR#Z呺PTj~(bB!^擸(ǹ*-XlY9ڙYX:\t/G;4>_XuT7z m{e@wZR }r XǝjyVUZ-b aT7BFƿU :+ψ3c3ϷC f#YDZ.hU؞ۑ܏@|~h},ϲ%[.YP~!dc|K2 c]fNq̛h r@(8C\%ϲ=Q -ЯпҼ m'Osक़?b.;!9sȟ},dIg/.Q݇q958c byUC(0. 'Y/zE; g()A:h@Q ÿ]m!:̖ wa7XX?´fut ~3AtX|1{F]Gg(%YXnlآ|' VX3Y^%%|b'o۫+8{TNoxWu}Kkl"#.ɷW! r4_g|] -/f6-sxL~o$3J8 p(8gupGp :&a ` x\π [v -r- G -G`B)쥀~aI;xZXߝLT6n&xfvO}s9a]SKq\us' -_A=׹EE Waু'A,BܐǾI@n ^cd^y8uxyAYeYx^e9gi*G~oAClG.ԼHYLOgLC{#2+qؽ9^d‹vD _MwA޻Ȗ*9#r&-e3*GPFVyr.ʕ*#.ԻyWܗ3X[[ުMlW g]TYS`cpUUGkwj83e)`arXl-yEa0cIuwfqŸcY5;7$ΰ@~+ v;0z]͠iv1X h5tZC,eFo*A6sz+eN^w -ڞ7\nu6jar,>u ȉ|1jwlYk;'}Il~r3W ~$-̃ě*wŅDH+LgY1 :޹4Hd K1~ *w!V @EkbudAB"d2 -mBC-xLDĚ62ajVm9}=I7r"ի:k])w(թOc,,jz3VuLw: _./&韸8ƈATk~fWZ׆}Muꄪ%%O} (UOFDj.NN!,Cr#Qz[/ԝx*-w⎟oF9J߼ ~7b sfwuw!w3-~ގ|]}Bd |+7wq/>} x^i9HĤmF}6?IM4Q#h B@w9w̜{̙a)D5w\\'U*ԻQOR>XN><}v[ ߅Zvܮ }Vԉ+m[aU;"ac~;T0wg:?+%FW˷9f&H3gPW||D W~Y|w1N".jw9~g}+7·8Ytcx 6 tc`3N^/]&b|󵜵*3E邝J*,}я_<@[bd(4eqy]䜍xxy pm*nss_cbg -OO߰lݙ`]SnDPFGjG֌5os(_ܦnߏ8ǫ5M;_߀T{)+rWvYT%_yl!ģ|C}Gx.5@p7j6jyTSqsP0b1UoZŜQ1wSЏB icn:}8w|\ǝigѧn" -y.Rt#KYR,e)K#Ej=LZH%-"w+ / m WC *CC`^)h %Cp_u#N}OhIS*6F |dEټ-~O !Iׁ֤6%O駨/wzVP%꩖(oۃNHz0qYZmf?3W5/i?%Ŕz՛15U:6FҚTi5Q0Tz Y0TV5A-K}` F -endstream endobj 33 0 obj <> endobj 34 0 obj <> endobj 35 0 obj <> endobj 36 0 obj <> endobj 37 0 obj <> endobj 38 0 obj <> endobj 39 0 obj <> endobj 40 0 obj <> endobj 41 0 obj <> endobj 42 0 obj <> endobj 8 0 obj <> endobj 18 0 obj <> endobj 19 0 obj <>stream -%!PS-Adobe-3.0 -%%Creator: Adobe Illustrator(R) 24.0 -%%AI8_CreatorVersion: 24.3.0 -%%For: (User2) () -%%Title: (eitch.eps) -%%CreationDate: 12/8/2022 10:30 AM -%%Canvassize: 16383 -%%BoundingBox: -5801 2759 -1571 6136 -%%HiResBoundingBox: -5800.49560546875 2759.20654296875 -1571.767578125 6135.71199896902 -%%DocumentProcessColors: Cyan Magenta Yellow Black -%AI5_FileFormat 14.0 -%AI12_BuildNumber: 569 -%AI3_ColorUsage: Color -%AI7_ImageSettings: 0 -%%RGBProcessColor: 0 0 0 ([Registration]) -%AI3_Cropmarks: -2395.87574191154 4868.54751328918 -1488.78912773831 5775.63412746241 -%AI3_TemplateBox: 420.5 297.5 420.5 297.5 -%AI3_TileBox: -2225.57022207163 4915.75573736799 -1659.17023389719 5728.63570601117 -%AI3_DocumentPreview: None -%AI5_ArtSize: 14400 14400 -%AI5_RulerUnits: 4 -%AI24_LargeCanvasScale: 1 -%AI9_ColorModel: 1 -%AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 -%AI5_TargetResolution: 800 -%AI5_NumLayers: 1 -%AI9_OpenToView: -11429.3092210648 9579.11221309952 0.101707666848696 1797 914 18 1 0 78 121 0 0 0 1 1 0 1 1 0 1 -%AI5_OpenViewLayers: 7 -%%PageOrigin:0 0 -%AI7_GridSettings: 72 8 72 8 1 0 0.800000011920929 0.800000011920929 0.800000011920929 0.899999976158142 0.899999976158142 0.899999976158142 -%AI9_Flatten: 1 -%AI12_CMSettings: 00.MS -%%EndComments - -endstream endobj 20 0 obj <>stream -%AI24_ZStandard_Data(/XtNu(@л[0( "t)MJЀs'u1k{o7m8`{_ڥ7ݵY֚e\p sʹz=l[=sL :5t ri-۝q8v?v3mZp~ufm5=fKf];v̭ݎu ew466-h}ZPYzѷaKvo^a2 {ð˭ò(?wz3bs^#54Ks[.͹_o縕kǯU(_"zxZ@HkP6ٲdƚbC-.7E,~òC?(z8tVk:Ln -$/,GuqGdh~=}g'^4Co}t|NdQln@G24GEDy819q>U3ё5,q|qG9Ynxp7W5Jϵ*lE$Ulpq半:zWXT -ܺFAUWLv3wkʹ_3|mWTnnߺnA_܂e-Y vB  Tu{KfUm3=Qad0HG({#=B2Q#滏PQ?3ћ?-\8I7G([?7n^,?XGd)d(pdH>Bپ( €vhI1fY>G3db'}hv?vOk]O ں?8v?_zq,?N\Jye'2$C$9ne230K{ ?%͏o'I3,3]z %Ќyl);x~14}X'~wr4?sQb8bcǷ8v_~#}n[޵T 0H{&tVd8lvn]wm ӳ:Ɋ-omoG5zce.zokܸ-w>-ul-|iK%-Ïo7/}X9)dː|eIG24?MӈF-WƕuUtΔ r<}K1,ˏo܇'?ܛe缇fC ˧Һ!MR_ CEh 8ҏdH~N~|@lPǷ0 ?"Y7,M4"Knr<*WY{]c;^hG{: ly?͎]kg{۹{>I_қOUzֳ?4T]/Gտ~<b(cHeXfijlȆmE.v^Cq@EQQER$R,ES4Q1Sue[ljhZc*?EQDItDC(GYS5U5M4Is4C34Mne[倰jhieIalIdUMTUՕ}_*Zfꊮj: kI븖kY"k4L˔,S25tLTL4L0i>iOyS{-gSr#y?{An~ۀ~mwʲH=n]nMKfUm7nwvf6Ϭ.[FnG怶K1k3=u+vxC<]ӭhq쪥ݸs˰]ٍmnza{[/mo7m v?Ŷp˭Cb[ܭ\;R Kе0wT%eFE :d08T&î%jvHuE64  .8gp@g/ _u]]ЎY.ٝ/ 9M"Hl7960v h,8 0QEQp@@Ao~ng~ڭ^y2lwgy7aےߖ ej3k-} 3\t͞pvMgv-&5(u˝~kP~cxr`+2<{_Z=@P,5 Ǿ ho]Z`8m n6l L) 7g68 jw_W ߳ٮK~z@_o,}c9z@ytɮ]cw`oZ5c~a06lp, s_e߷`pk8d~F? v uGa}l6.8ר*ݸU>G4ɽ;/r )*҂ N $^x$4w߷,vs#Mo9a9#7/&?ͭ G޽7L!9*Ӯ_nfV۔w-s mf=m^XfT}ò~ڇ05_ylpғfv,)ݱ&9~H~b7폝{Nwİďݘ1$}$)n$}7K+˰;]$C+2BwHh~vg\/a#| ~A/̝YTxa-R} (nejW Ro;V%ZPzߍ+SGk,oyne-7N7q6_dW=zgն\wnZuh;{IH~őO$1(Wn@Nݱ"Kѱ=S ڜv݀?m t=` =]^Z7*pb[EQB=w*-h  (vۮűe|ov݀;^B[Pp@xC[Pd~|yanݘE2{~ k.n8[k.c nn}6·~t4>:GPt@ǟMׯˍٟM߯4s˖e׮]?G*kRV[Y+v߬us 7I4Mx)vM˚7\zeg.˅gh7sr3i5M^\$iÚj6ǐO4EgӟnWMǮ_?{k.in}uj1r<4}/Iǚ X~Xsc\uKnրzp\u[ sipz]5YsAz{fƬO65nta{m7@]8F7͂n# y n׎bpkJ ^[ݚ cۭؕ_pH0Fqf pkJծ~o}IYvYsBplps/ouY\nl ߊϝ-[ y}gsk]}xnm'Mus%[^ik^mnz3wr Cv5k%7Ȼ7N; -]U݂'`erm׼vm]YʖvXfo-8iwk7Mޖ|o,ɰ M7ٍ6 xm[}[vdw&L&1lؽ )ܻrs {* 5o H+VnaSH|>W\ & Λ -ԡ iIrldTOrT$KSH`2;g5S\zXإ l#+FF<݀ldy`u-c؉AdϏq- KHWVDt yE~ i4sռq˵`֩۠V7 M53rXt,5ԙ DXۺOf +/VjȮXS$z patf #"`=6n@@|IPSQ\+@딂}̉a)`gdbr?X"DVJ)T{jR+H %uBJiΘf#)q$jg=0Td"놅8G'$ !UB> $B ">}Ȃ/,FNar<-=SSCI,󝄌q‰yj@ZYQ 6'vD71m8HZ(QSԌF M2݀zU$cKE1(5's؅ ]<{^6N"KbZNLaŌYdccJhM#tYX(!R"GoMk@HkiƀYCLYD,HW4F"XsY \]aQX/r xTͧvת@ISiiL:y̴@&Hcn}`$fr(|r?*#Hq(-&\MD' NL%ku% ͑ԛS"S H̀00FCi_ab&p1Έj8"M`*]K+ ԉhPpwoHBrA2kb'R2ǘH~бH -Wh f<%mޕ)c=&=BfzO8` (TŔt"P8G\6ɘk),aRZ$ &6Ɗ5@vz9JRc$ a"SUX Ix3dhF),xK "` C*%,S'_RE+QE8~.~y̡!VGc$uᐅ䂃$c_C`j68FjP)݀@~ - W4$/^W*T j.G[,j'X@1zgÝ{,H`dN֎!1m  /0ܼZKi}(NIg&C.: -.ZoX0y+2ťh(Cs4ewYQGs=sj?n - m3{T":jaƑcil4 6it5R -4#؈\ )a)BSJK ȓKT ,8.Ip\}9p܀n@Pyq -a@x7`;g10up09B# >Ј>}aoY}3^7 ԯa֮xǁ(8glٴqgH2Ck@[!ǁq@ॶ3q MDf|*ǹ -ڹb"Z-َϷ5a848YG85/APdqܫS - -)֣5p$򧐋b 4D8!8;I)e8Oq\ # q\}8[oorze9gn%n]TPܯkkW Z]c}5,y]&)-x}cZ-{mּ͙n%~A b߯morz` rpMo z h8n.k Ò$ip[ts} CI1L2۽A0ٰGtl|oڬoжS ZѽxCo('+$3* a}c悼᪨CVIX值. -*dD0_ՔɓIF?4 &].̀n`bP0D >K!}j]bhňY7NAe`>-09r~{"_΄x.4qRiOTejS/T4 E* -nWZTZhpE=ⴉr&ʨDK8xqs@2{yD9E.*:I< N$C$chI>!ɿ.!<.2(0]r˿̾RNbwūJDGrPvz醉nNM(a*8Ll$78~sYkm_-%BS胱\`Qe)?rࡌʴZ7a:>IX#ȄN`˒ (n (SHèaǪVwBia:RvL#lJ;aXUZ8բJ'YGo5GB O.a%]T5U$U'Q;ӋL}G0J#>$įx`(:/nLw)*l%UJRQ$ZU(]$FOK8-✖x&b'UBٯ~AE] #\Jk..4vn@/qY%w^- -*$Fb)`6W$TRU)BrwgQ$GH;F)S*w)P\F'pۂg2ϞŦ<6`W醉MP()M ͈_O_O4Dǯ'9eo" -!5 -aKMBW B~)Qf0DV+ -LVJ{صlr50!)9;Oy6q0`/U[~OXCv`5P&npvP̖ ŔkUU8B6|7 ,fa .8cRVWKN՟م --kT"?@fQT?UsRTSfʹ\Pb*\UzJxB1b'pCcK"<0!MFy_2Cxyvϣ<$ L\fL\@y?fxO ~$rK<-`X(gc^c>+0oS%^s҂bԧbϩ >\ѵB(݀ fJ'G`(b}zY)ge@OR).OOl<[CtUHEF7Jwo]F_+Zr+XhgS,1[QlO?.CфFϦ(iByzm^l곾1Q[PgS9y@xq‴)ϳH徜a(K{b $|CIDMe1e$VNpي蜞QSUxXUxG$(魜n}c`jϩǝ5=OA!Y7by*hEa *ázu==|X(F9%6E3򬖚ԅ0rȮ7 Um&0)? ㆛-(4-biv(ݔv7 @zA[L)Ey -[j2AF P׵R ԀJi_κvDP686X ɼ88Uvz,Iw5ιꕓM*lR?'0o5 Dh>n?f+͒WDCpF< 04.z}:Fa?O,U -)BFā5VQC@hhD.qל݀1i@sʥ -}2|* A kD'#簴>u@X)VSY4$iJMK ~@2UM@YI_ .n@𬛰3gm#i50uBfv ճ1M |VT?NBrVѪ(vB"IyC/z|&h>AL,^ԅMXz÷CB2:TvjV`I.hlOOrYU%q&&I FD8x6eM*&8m秉V71TdwH!^1j<#Wa uF |ַ+#ʤ+/Ip+Ocfuz`1Y-;! !:4/&Cnmbֵ_[=s`Ǵ,iޚ$%1#0S-Yr~MyՈ fIj9arPQZpuZ)I #,7ʫ)JL%gbN1`W|?S +`m:90G/Ai]t9a 5dx;8-T-7I9rzfJe:+6M]f99dO\yM5 -(_yt`,J2|] -.d,KZZk6J / e(݀:B&?zHjx$VK7Ezc >h\x7k@ Aۻx٠+bgD((pM^MV> -J4 ر06?_@ C@삫i  kՔE|Nbz4Q)()` >@B+ɱrYJX0XZ끁~ƙ/O|" -w(=MIϸ:0Yod.dX7 3Y,QVg`^ P 3"kd%ʅG`įpNTPdF7$| jOw"daaODZP3 -' \ 2bett-|Ax!R~L?WgqTz켜W Pt1QO - DgAM\V~=uJӓD..|,R^B]8$4"|P6cG \hO+*_+dsGӬ:0x|և⨨c~IʧO.E*xzY=_y}VhV$aXU8 W|NN_ Zۗ.`O Og1O]#K" D- 3_9kTӻ8V RyZpZ3ULBLd L_KsR^QQIeٳNr13 & ^]7((;>,`j-zH<=!\IL~cu -Xg -ny<SGF .F SNps - {!Rf~7 TH03WE%ݐ?Rs*T61uk膓-G>tF<=Zxtd/$ -v)ƔZXx9rxOѠ=t̢N^_,h.:~qRp'fj2x̋sJi R5qRpk4-l^Vf@Q3`j@M^2;fzM(˴%2L - -i%TMc3Mx9RN7 :)TL:)yZݯfQ %<%dW'SZ̕F̧hKE~}b^{8w|GP1ԴC nGjSZqjv8=ljb4NoaXU8(yQq.~aEvk,$:0)[UΪ=bA0 Q#y±8qH4dfU[n@(pce2UűLl*$4SzyC?R -1'S0'Y7 tC݀0V\kԨ=68Ltp |XlZүqqfu?[ktڮM>gJ}@:}'pOGwBژh$FH'2v岓;$݀ ݀HR5865jpk8A -D?,h9lRD4BSi`P?I}2CJ:zΊJ%n@X pcY~>?f kVFZ?Mi  ݀8!`(9!KU6vzӣPReOaeUB9= x> d nUKՓ4ťCv$n8ll_xmmxfYQM:ܩBU(t]7 P6NX r]Nǭ+9,Сׄsk+ "zxZ tcJI_V*FgDͲI7 sɬl x_񲏉 K<*0sz䶟.|[7`(WПfX/΅3.k]y5L\ -? pW#'D ) "N Qb&mdր15(_tWGpրakUQV5 뼫+eбjUoӬ.@@Fݬ|u_,sb]j1A^ب.^6G$ exGK9v&5r!Ncy_{݁OeJ1CpTJ"xfy.~#ό>CtNoDp#Ǧ(-d(suQթn@`dWs6I8P+o6OLD>"I4Fñ\rH) B30C$@0 eٶJ<,VBL.0"0, Q AdN1eFRQ7 "8/9%Yl12^8?5,o k bϓ!OY)vrFn@볘ܠ#Lp\vY7sL>8wo騝$"0 0`J"U+$܈@ 8> ?CNC`e#*0GB>A`-N:.%AF.i|еG[  +Ook%(P*@$-|8^\kK=c1vk.F d)>Dq3iSYv vDUg 3A\-\҈u<7@5 Nꁁ~j]⮴DKcV }n Oyh,nt !ʪuAfƛmzNL$@2Ni! eLS0syLq饿yZ):p@+hkp'6k-ƨ%Pln. *HWu>U: 1lYj[E^@Q#6٢J IB0,8g}dizLS> 8xu $@%NQSBӇeO6Lwa -&hBσkl_ySI ?+.kX&yDlZ0@\x:7U90?u% [ضJg.'v_2|$e`OȌ.7ߐ i]Z& :G[5r`^ٛ_Xu26ar1 *`{9u]PHn[jKE(p'V:ϵtх')ύ|XUWR4i*yVLE7|#NʄBYybQؒ$S'iCpAԙeC7LDDlquuVFe]>؟Zq9VV_B`޷s~S >qÁ9NOTB]Oę ꒐B2`Nmŕ,U -瓞Mo747/N>WO -V}j')V]m+]>bG DNc}jkj3Qh0Ml#}> -戮 -mx8th/;blBi!E44!"EKC?,ΨC8@k-,u(SZE2Dqރ.Dadmu_0@'٪jlCQa BjR@: !PgSXÊ-dR)>#ۂeU箵+ n\4g$x! v 熷a5-@&,EV=Bi}oha݊,x Au~׃ߢeo=2jzJMdvGc%Lv:͡N58︶z:Ǯ2:4)/ T J*-[/XIF;|G}l4tK[BATh!!B$z)lLul3k)ߒ{݆tA}:ي;qfK9, cmFgiKXaUbѿ}@ -V{ӡʨEfme\K6gDž_Rz7}sDSiG[Y%|,5k5n<@׭!?bso -1YlɺeR(\|~%g6;(ZAh-v\%}G+}zd^*S80 --Ao;uT~]>BSLdyR4 yW AAU=Kv6w5 Zk̅ zQh`V?*^ohhz{9*З^[# A&|/VB7x!j:3u[s!m]%݂T0*J]c9x3Ag:}MhXm|\ξeb){j>pyE8z5Efѽ *TGX=?,n"Džmց9m5/6]ʛ @j/Q]_2ܩٝ'!nfKZ7 #p3k܊Ƃg+G̥ }Jmeʖ"-AMf9UdFfN4 NL9t^Qt,?ף߂J,vH|K X6R{5@̅rz9ߜ-U& Ȉ;5_@\};a|GRtAƖ;%|@_BzV W`iF)ִ}#@%2A*Mܸ^ʸ^lrB:?ONqeOLeQߝ.ȯ"܁h ˼n=.DS'cbvX1N1aTu$h&@w# (MPn(q{ y]O^T+ ݝvL}ZmK8 ~k.{|@t-LջJ̒ݎp&XY0FZ6P֚QO,+V+S:@-v^o's٨3ޗ0P ѿd{!.H>Cԩ.kΧ`Gbt2I4| ]ɒ/X"5$$]Rn6t%%G%iK92`泂ȗԏ>!n8L 3%0<C,)a] 2ہzTA5d)WEOX]tկٖC`e,Ar_WnX ^EQK7C;Y>;OBTD= -WhGQ̂4 B?W֚#dFlߑh'9ǷKnkϼEIƶX3x]QVA?. eLxFHj}ڳ9k'"1;]O$B_PĨ_ !혙"\3(]$XbޠUeK[ MQtʿk@sm#u;!e @ SޛltgGIaq8TIX8X;IӨ^T{/ƤVfA;e4jKY&%PDL%f&e#P 1uiFf{\E8uBg| j*cvg}e -bԁ+ryt|IHлj ˊLѭ6bRfԬQN%]hdgAl8W |-̬4 ~|=Uht]o]\YG:jӠ}Gr~@TD,;w"zAځ%hFќY1VtB. - kƳUpf49(WUe~K]_[fTmnvbo?as_d\qcl&*ܜy^ '?oRy*HR;Zu.'%|0b5.E-̾\XmW\,XU\&~} -N^1ZFtJ S>*JUNarB\zlfQ(qQL/HԴ`-NjAM -{4q'|F噺w~1鿴-oqF !|wX Ö>R]@U'NΤ˧PXF7Ar` p&7O}[՞@MUof 9Z@йQ"V_ BDpf$(0sZiɱPC6>?x2pb1!>:AzE1emQ]皑+KƸޛx05 Q?DT'bcq1e63qFx.cz틞&v] H/΄xFqe*ͮQQ+D#*ׇp{b!~sjB͙KNkLBܿ='x`ђ+d>A"u~Y<5kkBWj.Ӵ=8SSNLeԋ[?_Y"nbN,nATvۮu) XvȌ`gm@ K!ġUhhh;'Vy,`iPvχ| _>hN'D]HdrCj` 2R]MWi_?(KeEk.1GW}U2[}_bdX{p9̂MS퓕b_L&ρw-ʎ| jd{ӻbR{+9Sz2n\Q -]@$a4Yax,|Bjd-2;*pi8`uRNAr~ SE? v1NJ䢖 G.Y@ӤZ d#7%C`O}\5h8@CK[ < -в\)j3AczT5 ugrB8   y3Q&0- g0~<'TS'>dO85`H,V'bs)3KjvmxAP7ѱ 0oq)#a= \PJx~IX tQ oen8*$z25t 4qhp$&PP6SHekh53`IgPrt,4" "$ʝ r lf;ikrri |$?,6?+5f[F2f:FZ#U$lɀ2_#s>9,RAQ:trP8n`6id`C`{^XDi x2@, t`G mK  dL;0͎a\Lb]l0j m27 Ĺw`q7`f2zg `mB! 6T`AsQ;6xFxΝ ~ٵq<`CiUbznX58Ðsdol -QP(igxW#9:vA/`pbevF*N -l"UrH -jDuhn$5IDUg+ ƃQ.~R-z5 uӵ%FjPo\w Lߠ^!=B|7]ʉxXh62N+<@(]Sha\/fyn"F$e ieH˝U].IZSG7"vRqͽ(n\ L+cR]&?')|J'{RR9FJ&ɁSa $xJ׺5[>a<A&Ҙ~97[v'n -ሱ& 9 rPl1RB &NmCeX=缍\@'M>~Ee4fIӝ[.$tp|".LڑytSzIyt m?mMa[C_5x[PHWiz)d 2HUY1E{1$ih?K4rsx`* -c2;CM*O~%3GK|s+KC$p{'q6Ҕ@4umrԝkCD ߛ,@Y>=q-la_HfwLVY +?{'U.x3Dsp2(3GG/:!ŰP:G,wR;T-Qd6o_7?/bJ-t}W(_(inc̸Fc-vkC#*tQyvnBJR I8' -ǎ=9ay+dѓ|&IƸY7LY6xX ^4$Ȣ"5IR^{^r[R6Tm1|s\_<o4 ׮JӨy_YG[9hqDe1 -͏NhDAEx/#M^+:$8ly$7^_E,zdZB?HVB:88-8ᗶKCҡK5 \2Zg݅-p8.#Eї8p1QN:{:@$>L p5a+&rEut. -AhPPV#??o|`#G=Rji,k5 1ȩ䲆H>$%=.~S9EmqbRɜeTi:I8`.a D1~Su+'/1`APdz'|Աbk+BBd ?mmL[aB05v:=xM}p eQ\@Q-e@`!JeviuJbک<Pcd[v~#Lɝ\1ʼ,)1ڙj$~3795j:zõ|%%PJ?z\@eCc{Z:NM$:ɘB4'q.*5ihZ1y2`9s٨Tãf_`B l7p+:B",b OCNŐ&&4v4pgj=Oލ޷Ǒ7bbMAy_ⰨQR6>;U֭KDQm}a>ܻp5|vE$\)ƍwj?mlaD$^?9u acۉkW64ղyF4AL#DɏQ[?d<_Q4[J\CdO>r(4>%G.@on;!0q9~$^7lG:h~|ox[(W6'^lǚ}f nP>A'm8rـoˢptLF,Y%¡%x䆓vpE߁öasv8fx]Wv-]@Wg&\ԏug jMYƆshegN - al+,+ky$ Yj(Mj%=RXkRR-L@ -lac)I[.&JNNj%Xp0N_Co" $,v{<|v>YPT~&\^PX(bĬ/-`skČ.mccq`RR>M:`s|0Kq1j@]GkhOx;d2p:p M{s?43q2x n Nh9# -EU!#ڐI!#~.s50<9,iiGw_VA i{fG=z\#p{T&f Bo]qĞo@UV O'kB՝KhhC>8<0J|#h͕<2OCݙ1}G\Le:9.m5(p_,30'pWRd ptBQ}pՃ3t֙_,s\\BHZ[N ěQ`M]b!'`CĦ+stc^8޳XL˺ -28Hf>FQ&/Ԝ4&@,I'qdt1XNK4̾%8f𠅔*~gCwsrxLivV6U ]%4g}ᇞ.CCVᩗH|!MGף6-͑1yW\Lp8K-*Z1;:>/gn$ a:@ɂ$ʭsy~;,J&mex {ʰyaĀ_zﱏ+Ճ:I䐕 a+Hë`o| -$Px{/(īLpzA!eF1aE}C -jd|feYD:P&>8DHJ gA-ny9A q*7P$3T:6 >,Y;|>:P6%LdT9+lT᫶J#[.ҜHC!/!$R|bo|<65L@j@ɪbeX(?G z2HC'<[hgF ސW%)v!{Fa -iH(uFR?)%0FhoS%W:P{s)\-pAD0ҧWl)ڔ*0!S G)$疹c0Qu*bfTK|K4tD|R-0V^.UaG л dm^rM'5aQZ"}dt'eBbr\ ~:F{~Z > ,$vNKV_@'JNyc R3x ntD]4W@?ALy]y>VsÈj%}?#ogz4~C=Ll-O=G4UOœBKž'9zƕI?6_X,7DV2zʼL(B6В A*1moy%Uk1/ -1wPL 2 nqs`X42vYENG;cc^ْiҗͫ,~!GX*FwwzSkf7H"G .{OAJ s?$cn1{11^Dts3>}uwY F+ %5κ% Ձm>5uߠL@TP/`Xu*GH'K$XYvTz-:iYم1R('qpimGs\ŦHe9kv|s8V'T -MwAc& Y"EFɑcf6-=B ђ2zU%1љ42pl3br\yMbV-A.͡vV2Dc,oJ5Gj kJ(|w{vvQ'KsCq5u?V!ŤOZªp䖕ȆbLDi33I-FImP_E*ޔ2Th곡*F!Bq`IX@.2&L.1S3?sIE?X],+A"MJ+'OE`k"o,MXocRbҭ}$1Sz{1Hf 6a#^# L$]oBUsbEjlW1u NuD1.jRU3d/'P [Y]$1$=Jq_ Lns&wl=?`> A~Fօ8>&CIMI]}ʡ *~F(rQTI۟dsqGj -&eXb}e*U=hۀom}eh%;4oDzG!'`!%*%7^%SX%Eq@ap -y@+^ܫE>K -e<٘*\WeJ]pd K{Ulfjj9JX$~FvDd9+rʄX肔8҅SQ&tġ-%@O**4-V/#.XPY<}[a>P9~-}hYnK/ ZW-OO{V'7K(/c}E*\O/=A@ ICն^/vLUˣ2ѵӥ_뗯UN2A:"gj7*/ ͈9&s2g@B5* {l 8B5*d{٬ʷ!7N9%B̝XB :u9_!$ZPl?FT81hsQ㞍GxĜ_#c8- [@:p\KJ3^/GTE0,qI~qֺ>[s_i?a\Xtqx%%EqY\?HLrFdx䇜M:m -z$sZ}_[?jH@zea ?8AbLR$fj:Kz#Ξ.g$65Vjy\l3}lc* @k"+ - FO}@-.|/鵚uO_%b r0MҎRFs6^ Zy $?!X{5JWPEۨS#jʇ|q+CņqERN#~{vm - 9bXL6~w9׉W6txk.םb y~9K?0Iӄ JUKXK)+E23:&wX ^VkԮA#\Xo -!rZkqD/gni3AӠDd2n\'Osv]RcbӴ%S DEl,i@C?7 -9 -Nl5쌨#sh8SUX@}Ր\p% -{Q#/ n Υ͘a7_G?_He[_n)!أ.솈#5lIf)m D/HI4a[q5U҃?h…zgLSq[U@r mCDIeB;@(^I$*T󗸈NYe$+WGgؠ3^ -v\[=b8nՙEKsWAޞb;,¾fuX壋-a X,뵕cJ<q7U#H̲O2+͛1eZpQZ*N;MKMZρXG2$ڰl)zZŁeXpԴEsȶpk7I>ј9O63 `"jl=!=vY{5{Pۋ>+nv(J-sj=M.ZdyXs}h: ՞9qYi_4ZV0dt0R@3{JF5/@E1Uo{4;F -Y޾~΂dpP[u˝:R{-<h\Ra@ ($rPj6?H#VuVAϩ 1qH:>4вcnM)]8pjB:s41ћYY[#ɛSRR)M4YZJ‡{Ta=2tq_ODFsu- )鳀$X X1Kա 0S6iŊB!I`(8`* ,REM+>kq* h`BHcJ Q>O `Om%ж2N*ox}y&AyB?FP6p ;"D ڰ'>_E%N>VV0bJ0cdfp中t -O=v_KỶrqqf(f(CQԚaB@tA bs>D!u'LDZ,MУ%RLhj~ 뜛 0D?V:+Ck4r(V!j Vk3W{i$pLcBmstw<)WB4P3bx+ `F]WUuMfa 3/xьHhTx(tn29Isnߴ(nv!:(8b -U{rDIճG%i;96fT=z -kXډ8sxbOꦂ{l^If#J+]UL!\i+?X&YT\Q\&K^NMYGXCkY&n<'hԣ?K2BoҪ.*74cS$y#2jqhvcFb+X<ݞ3 ~N-wQ.3LO0Ê2kc;a3==*?`UYKz0:{nCXؗr۵|y<{S#'728vЍ#8yރLǎ˖nj2Oa5ۄn$UYw0LFo ʙ÷CǑ w1ۍO'6@ۍxS K|xXUvn*GÒʆe2qܜ類d|pNǚݔ_GYcCVF+˫Ɓ4mS-e5_`3rU]Mms!B; g:=˔vI>U'=+2*U=GAU!$_u7W{j)$ RVGGJŲ|]rvWqJ4B!ueL.U3h5SfrI>>4F/CBH8 -krC>IǙ"ɑjd},Qdxe96,\l2},|"3띏M K Hq!v'wugXu;3jJtNXʧ-ژV2Ū4U!d e ]"%Ω$9T]vX9єnoL̎XfyCST8UWU*J6Y2Qe`aMd×oSrYv_qMѹϑtf-Wp5R",4̿aǧgX$3NƑIC,vVUʰGLKr8%CLimDd=gB`Ih,}8x33ۭ$m,h_XK7Yv._$En('4(N8<뽅gA2U-&!F#nhʒhw{.5?|SzH%)1f^ eG?j|56(#OW QL;L,J#9Ƴ.v*M:OMJ8 md*ddYyw<S1or5nrU -MdVNɸ8_QX?>kVnNՏ4)37;L)-q\}bobι3"LT f2C?J&#k٣Ф\of~|XVW%$UEe[ed]Z{1iveb]G#0o4vcD:#qH/3AHvAW/jzX"9%D֩QVH+IW$mhs2C*l獃waBn]wR}qMFXNjPfЍ+-GAu;-9QĴT>O̥!yn8?+Yg -q=#ygGe7˚$ L <>,(˺ż8͇t~ZDw~\yJ(wgC?jĶrџ#<яߟ[,sQVVy'o!be?NXT"9oGXTYy:ē4[(5~@AOi#z S^Md9&2wnQ-%~3K 8*mA~؝iv'r~lZ eGnlĵE,F^3N'֣ޔs%qmc?~^olHѱlF6c=cd4u=H&ߣL;;16̹ {P͇mx?c3_%#zg^~hhRGV'k~榬-9Skit)ZsyBD=hJ8v5=np#qxr -t*Z&:}tQZnyUM?xnϡ#jTcS>#Y>)wi˛¼P#2+%8.Ħ52KvaUM})gLcKzܪCte8U5C+=?]_+AN}eVdcoOLIUYB7JHp[;$!C\(Ђ `%.V`-B.\@c -pA !c(@ @2!H#a d!DA(c,:NA聆8؀Dy , -dB Én|6x -0+lX\p -xũ, .+Ȁ1 N<@` E| l(@0 \ćÆ`\)$P#TA-DhtplNE|hA">tF .F L-e4F%tpE3`qvTXA.CÍ ,ha!paXpF "1@ ">ȇH">RQp@#H'C^ N(FXȐ HA)qqtQ@.d -+D|A&0FKqp -TB=d8I0HxP0Lc -"&ʃ `F )PT -x5É f -$8P@P+B@Ap)VmТC`*Ta0l( -V022<ЈDHQ:P -6D6@-Q -8"1 01dz!p// @ @@("8ЂV x$: (\T .`DF| eB)\L0.ЬE NH0 8LF"> u <#Xa,BXVaC32  Ft((6c dD -">T`PA-H$A t`‰ @d|pD00a -m" 0Zp!, CF+Р' - & Nぼ +D0.h@h 6 QxHZP -<(48aœ0F(j PFJ `T >T#T"F x?H%XA ѡj dyf1">4&xB L'L`CK$#?h@(R\ЂB0CʨPm@ (`A2a#R -? fLh B!L pA ^0*8Fhp0`^a!FC^t8@#4Xa4bD `((,'NPf  \d @ -B@ r*@#^`@P)2g -E -#P`#T\D5H!YICB -">XaLЂu, :xC 0`@R((0p`">|0&qA Hj\P` -l0A !l ƈA(Rp@r@h@@@^ 8Q"* ( REE LTHx#dT"(L` Gq@ t@!P0FP-` (aJhD%H+h\PB@A'Fp16 &q&hR@$B0F^0B , Np"(`񪠅 ( k`(aB101*PHP" P+Ň~@#RP„AQ (1t*@ 0T8H!HX! -A &b$PLD0&. 0a lZh( P`L '6á`P &D@@ ^P%8 -Q @AFIԀx8Q#B8C!"-B Z^`L  -` -JBcD+PXP/6@C0Xf( T ƒ m6 Q&J b /@*@`E (dl20 -&^da x! -)%P" PA (bB-Pa h!)`'2A2P!% 1Pd @@*P"|p[IKr4P !@ d 28a.p 44R`H  - - :O@BB@A8d*PP -&^ ^( x 1 4 H}Py!;0 @̈L0b& !4P@#,4t A 4|`0p "'2   -HrjPxb `F D#:T -DR D(  ("Naa[ *L>tB"NԆ+0a. - -@PQ@Sf # -P*#LP@ -pJP( (ACk`@P+*0C*ؠ+pZpa @D dhH@ѡ̃YȠ!F 00A8A ċ`Hb$(a#TC4@`A#DX!P(b .@X͠(HQ Ȁ+:x0aHA"\hD,! l(Nb0 0,Xa#*X!#4@Ձ -@*a -LP`&NC $0p2bPAF!B.@ւ PX-`C#t"`ᄌx`!$HP`p8  AFQ2 C(PF (b2``_ -,q 1@*!T .@ZX ݠŇTQ +0`X48l @0 x0CihaT -"QFbD -2AƊL||CX ` T `#d6x(`D0AEAP $6L@G(\ Š Y+dPl V`*x0! F +L@$ -1%PX! 0t`&Lc B0 `p RRpA"> %  4P Pp.F  &P! - - 2H @ FX`ht`">$@(X@XPA(`AA - $@'#XA60,@ a`*d! -%FX`C%B4MpPB :B*`*AIC p"!j.XHT("e`b*# -@?<M(0Bh<"#Ph !P!BPb8 p`q!8P #>xC HT4@#dp190a 5-p 2@A$j&H1BFI(0D @1`^`(&ѡ2h@ddHE #T 4@U`A2F&j 蠄&J ATqFH1,@!hpNd q 0 -(\A xq[A@b44 a - N|0^':*0@ -Zрu…T0).jÈn*+B&j\>4i "A.!` A\ć -N $PB [T TP^` 2a  -PPB - -008L :=8q'rƁb Ap! -Z(x1:8AT0(X`P F -)P ^ޱ4,LnPOD?LGO*=zX4yXYQeHZ;]RY%>wY LsIV6igG/fMjdžVw9SqLTSK+쑥/R?ۨ7&g~ޑ ߨ(TB/&1 1ͤL(]Udݥ]B2w۶z\uٜw#u֧\sAP%A9^ty`9a^2btmm''Q!+vƝ"7IEk⥮L=2SJFX$jqՓvTEX^7Z*-d2ݬףšo7+2S` ->Y%#v/n]ƌBc[IO 7\mϐ\/Sw#+I&7cGv1 CC)O)FP\22wmmVnΪ/v攊d!ӜX(Sn#HӣyWk _Kq'+edN3q&${.g,abu#S4˜n*P*I:]ߐ]K -&vF1GX0;wB6IOWj|WϒL]5 R Jo61IaY%ik5$;m=_LE6gR-߲joJwkccGFՍ2/ޘ'f_!ƑZ?<532Н(y -RX!wg7$y=rN=%u֦)SWN!XRV>5{s䲖\ĬR ]+:FewOn5MǕ[ʧ'feao#D˴^aZɱ4l:#}ЈhX8%Ah|/d/Ylգ>)Kh̄^F<[RfS -k<:rSVeJaKhjt}(0m)ۓ-oСkFJ1L'օ>ⷧ3IS#(7XP.F2 uN`?3\~G[`ެ葢[T_gi2f} oY6Hl*"K"yM^{Wdo険db$cT7HF^;ꧢw ݪOfsf4TY>Jq - ,M͘ [v$H(L4%8j_2#TƁEۘƎ6.qf\ $zbpqq@ 0dP@|s-Bŵ6 -1lUT%vT45sr4ɠۘDkز.KSӣ{!S/FeU T쐔QR[DqHVCTBHQZL&?'T zD:zd|A#c1CbFq)B|(K(_*O|&< -6 Z'*eP$gTY%"kHZXYNdVSr$vI,_s#euZ^%foRO6lpR?< z )7Yub[D-xd/I릉Ur#˹!mHblMKy!:R$Fn uH#{[2j,NbĦߴ Y巎ݬdʓڰQLkml Ad+l]eub2O's&%WD$P^'Fg]ͲzI*7kbemP -R|Kݾ [ 02$+I3BfVfTr#7T d8 UyaQL=֬SǑyoR[2GvbWgB&Xd|!\1צunUzFnUQ҄U;螓ºA7>mpN&sdNˤpH(&n)%#]*k YUN~ b\9T(7v;5$h_IJΩQ4[Vn`uyúQ¦X&NLjr9)maTarG̥'۷nNfH|B\R7ҬZW|*rVRmKWOEYȍjjSn[ݒ}2Wnҩld'%y*JN4!ZSÜݤ]шM9jcJ.+$ kPz:V̆)'ib7S]K)O]2j\#;&HSJY:\enSbP J2-huFĿY!ߵMĒU|'M|ӢԎWIȗ!w'S+1{4%Fؘ٘Ӧv+Y*%K{d椒*E -MF>V7g&D&wc.,n1)VfJHGl*F~n 8`J/iXLHW_賔% RNl)xj$LOsyHy0Q QjYXUY e2KJ.yY3V,A;7NRBN9U%5%Γ)tNTHTsQψoZverJUas\_a,GYF)Ve*㣠cb[)C#v ?- -S=K' M<3r#HUvS߸4Y5+ֶ8Zz<VIYxךR{Uyb㞤%sʪ|J̌җcm;#W1s88%3'1jroY^t5=~bz՛F+2v oɟCש؝FϾRclfJյZ=kų. R/%] -[՚!rF_b?ÓR/;#h#WTUraiHUW8hȮN!|]6ՋVY$rGT;=gsiރ?**ⴄ.qϭc$ ktxK%q]I(5U覴. Psz[eVΑ[q=Tc]5ytQVL#?䔳iP\wJ9vVoe ȫ=JaLt4wQL~큘vVs1x))l[&:z2ƚl^hrjbFW9.f ]f6䢧a IlSG7UdCW2ƦyUKl p'8]~:x="A>Gug?ѵ\2pj>Dw5~ط|^΅/Ӝܭ$qa}8l즤>Kokb'q$=a/Z2D_Ct>jو%tsDv{)9 F3V^>裆e5>ц'3MKNs5L%94<3zIFvˢ sG^G,ιUÐ$Iv4$Xlè}u6[met}d] 658Uҏ%DQ!O6f4tW! ={F~W0OFN{-9>UvuǙI"lNS3ysfYJIq렟<#,ͪΥ(wWZ%d?b.Qեe<>\\iJauodv$kY e QfJ?L[~=4s$hkD?zcD<k-+ljd#vČHtɞ[MƆ~!T=kÒjYQzzrEsǒa{l|r7?3ͥ "˫ F{IUCϳ"s~\]ʚ~Ώt%5V2Q8Ut^!*uiя#n=TJ5y~8M\3+aYe c& &1MIHFBV>jdf~JHCG$竎OƳiٲ*m7\KCvXO_7YUݍ%4غzfT!`(ӏ=ץPc*޲Z{[3$ϗVhUG:RJxޥ9]4*Ȟr[nv͐\ALHFhrg^.G3~(; }N먜SJ=snTEt M5mRlɮG } -|1KG%<5, -4x=I+?<<*4hZ=M#`Μ5ün"*{ec-iy,k$tD: e69h92͜\IJˤ3*3Uiԡ,פ:roWK:Fv6|=s>iKR~IɳBr1%S؛616AgѳgkRaޛJ^ WV:7d;Ī9GK`/)3,+,%^=)SM'ћ 訐oJNgY:IM7>)^ôUR>g,]c+Y }*Yܩ%2r9Iu Y~|+KO$dʶ8RT4fz9u>Ի97Os ^W#A9]_q,}TB3Ɇ.H^<96Q#uettWInVIm*S2w;CK<2XV,]UƧ -p!8iѝ2b*RL?.br\Bxcv(ϲZp"M)jum?7$8F CUՈNwv4ryBGyv;ե(NV6Q{L򏛩_f*dq,I9wUV*AkS%)4p;]a] ]x$sy3͘Vi/K=^ˌ,'L@$]nuiOLZӤEgw#Cz<&D *,,$pdg>WrTrX"<[],5"F:9K7FI7ˡ&v-o#cN8+*9{4b>Ok;yWGRTős2X{ sNlZRXV62cI#Ɵ5+N9X>(72tQƩ|ݳM^f+Xx4t.-5GGyP9K1=GWO"'tGήGYNGzy#3,ބg%X*};4$,˖2㭖gG9TsXRE%'̖Ws{U:mTIEJ3GX|!^Sdecͬ*JgI1gIծ:F|zA"j9鵣]r#1",٨(3oʍ~kK)骄YeD<= цRW6tg[C%$誛gUx{TcS]8hrV~{LBFyvKj%Y.|͔p}khBCyRNW{0՜1\b&au%t# ݊j=bZYTyzҲ~(guIB$ʚPE6"v~ubݍa+Y49l.yx%Ws#Q_>'l::X${cU:u+񡥉OŬolw6H.ޙNĪZ2_{]f}N$u*"2#Ubu˦U_CwWT^shR%ZmolSqstMks!,鍧;[Iw3|%ݫ!i=FbimJ+cx)ٕt*ݔ}^ɺ>UuړdVSO秔2\yjdxNy&-f :~YiJ-IbQGLHwy,?#34KLf݉Ô`LVQZ62x {aJr$/krdP)E Qdd%wI5=\~ʤ~*~i~cqu5AX0b]սǷ.MvB)|JCYR6IT2WLHS#YfI>g Qn=hngwuH>C䟺Қxvu')29NrPN~f/}<){xJNY,Wz2὆ -/вyL]hX%汖ys%)vqa%W$2;c=:E7r=d=ЃM(W++ŌdɤqnRcfªIS.;Uw7DǛ7Jt()NZ69% -QyzGc1Z90-{WKXΚuetjy -Ta]fʖ6kd;2m,z{$%5zv0RUcx4GETf̡-4:uzv 9(̹լGVѬrC{6:4;$4̟ѢPbD3< +#m4SlFThF#OLfyKe=J+ s*5g<яã JuHF<4 YҺ) эH>Ajg'+*uj,e>7j({A7gUF۔RxhS>P4yU>o\gZ>nXP։?wJW2%]>~UBVxc򲫘<}5_92V6%Va?X=BX:SUR,k7,v.ˊS$lXx瘇I?rV}`\Cf|34M\NCǕ)F[kVu$͜l#7\D>R~|g>xϱV&Ɇ^ƳL vLzF}Y>TGM {tsTS0˘_z>'ћk2.]<_U"W'hitf,tRNR&ziE(Y,,"lvhKBxXSU־0mߥ]+L7=:=A%&RV%5sHf8Ll4ݣlfC1g;ru KpN5Il"ae":ks3?Y?'vkuՉns.]Tݾ93R)+]ɺ<9Ѧ%$3icg.e6MړR5\΂Hx;&b%OB̢CNIK4_YzNН#J *3KϢ~޺;JY.BCIK,"SOYYKwhNrF4l ڌb:$$cՈsrG`kYDG33?\i˱WybOG?(<"Iҏ{e׻ ,MF\wyS?*S'6sF N(AY+Ug2T?o9_DD3DORXNmVىHҍ#[?YB.5 -%_9ahd2OxWSB-bRS:*2'ٺ]鞃4IR_ә%1e,oGYv4ZW? fM&oBI3m8?2dr$~Dwjz<:qqt4Ò/8cq#ׄNĬ_(V#f km%1&[?uYwێɶcҨctۺQHtyOEFuVv`-W]Vvw(JT?~lچ"9}3UEF#Q,j6MbyFjCj z?͙N|GUUf7#u&ǨRPj k҉ X' !>U?һH8GR|I?;ѥ\%܌z}&-eǚLR=+.rOόZW%AZL8ړr&;|dG245%ô%qsYG4i>aQnRVq21Gh"#8NC:luڳᏻRш9sf$s3OMUd]Kcl݇V 6"<긓Lɘ,zN~qym#o,S,JTPKI \ͪCu7ﱲBT - !jKtUHETéʮߑF xjR R$c݌7;hnd -[,3KfUS%UZ:L4f&L̜WQ53;GFJŚ5khZ9cGiJc&bTtݥVKb]+S t#fG+^VlԤ2c/;J5qcB2v5IC[rl%gB9va_IG:ЍOK3q>vUU9/)o@ o.Ȍ?j3و+Q\cG~x&WOzx?gwZ|O -T]6f{${?>Tc[{>GռеE%|(kx%6JnVFy"F5]&G&[JB-UY5W -i%+'X˚KGV5Qe0 -TjBmmw 4Λfg2 ޏ' -r 8KԼVvg揬#c -q,, 8+ړFּlc?̮9n/lz=CwPΉē#_%5̩e~*9,;_svӺUH/`a_&Ȝ~\%݈@UȄٹVzn.4c:YH753Vֆcme%!HVNY& K\rd!;LWd&~԰(+lk&ن5nj5=m*My=^͒ޘvC!}a,cHB٢OV23vogiba6W$m<gP&3tۉc*xI8m(} Me! ԬfT$Y:jD8P  Xw. Q8)e لbo ~j7\=KjKYGޘ<4c~52蠃yL^>U3}.yUoju-cJ 41?#Bj4%H̗EIٯF{m`5 N]deUK -{h&dsi*@)x0a7Cް(>C5-^"L @i=ujꥌwyn JRNĬɵ^\NW⃉ 79A %({@5ȏ֠An-[j{Xzgӎ,Jl|]Q5\2x{JLR2 ٕ0F7l-M×hO"^ABe=wmA#|k_(>lbcIU95⏻"rz3^ɐnu?ܦiwHvꎽo-s0 \@:={U*]C߽pR=H,xTrMI}`ڂTZՙz?L30KB8Jz6 ucm1xnr^d(TWb(NV7 i| &l?NQ8Ej8T 6cKYwwhFRma6!܏ByέuwÛ}L9ڨ zD;Qyj\o6Z0PYKuqL/Y6LP[?2qwO/0&u&YLqQlnTݬ'0sXiŮӺ$e -b󁱷H?_bdjfe,HRrjԓvN1R9|U!tzcY{iawClE [4)Hx\-xHߺ`@FƼy*zݨ/N*i7+6ʞv(#{PƖ􁑝Ꚅĥۥ<錛`㢃 *]DЪ*>$Xqn?E 2X!u9vw+3Iw/.iXjOp*wKL@ei?XcfSva~1ڛo@Ƣ2Tf/XHJX wӍwyRX8Ì*8Bˋhp{zwxEXf3aA;ݸIQ/[74d|ZBqaÒ}=ޙk]EuKIN$"Y\/t0?0!pdj`|[[sxMƄBH7@u]grd1n++%/A3kֶU7zx+3Xẖ(GLqf=pbF!]5MFЏEX*]U]BxݴG֧q3c#R M%2ڳI*L>a׻fQh9'4m5Qr*+C͸JnM\#yz ~Kk sСC= j:PXZ%' ƽKB2 P2*^a]Cg*>,Z Җl!]mZY0D2Hdim߮Xj)V@Az[ %,K9B~t$P+|!$ֵ^{a4x4kȔ͗A 1u!dD61̶1!LXۂC,8c\-F YG~QFT]`aqE5Ɵ@clY$6Y60k#q*= -z`3ZƣSL@#eTG=/QjV z_!*@ -' u՘Kt[ OHKRU}Yy]Ka:I <5`r93>?N#}jAͲ2:PGqޯn{^kr/7|zMȝ>Nkʑ19lHPgrˮ#D("1 N'MeZ0 iK!&@Z6" -\('?TD+HUr‰|Dy@do"OJK40:T^(̓wc'x)a.pi(3jFV`1iY0OD\*a2n2 -:ub2'#Eݵ>IރLDT7{TPSUdgY?s|DY`nxB[!\ )mb?^y-[Ȇf|VO/L,k=5ǖa%!BVۥd0ť #uar\X֜w ֠sfSC7 AfJȰ5wgDn>3=ǚ N$-~-G}WY-JnqSWHCB80E lw4[w ܃T]JDAo+d5-I~‚(,"NȒ 7U5e\"\c@HwF`Tq#fĈT 1a*)|7;"_~ef &@y/dlL_r)ب!PAͲdvPn?kT8rnwuAO!!6#[#ݜ蕏8%'v9DEbM'"o @E޲љ:?-Y_;1ZVh.l,75 W}ƣF#i/TEPRK&\gx&%N:Aj*7TIdAk]읃گysGސg|tAFV=Οb(ۥx9P 6 Hdo8dKd~6f8:6GHQ)/ -|5? -<$t?yTN8 T -F xd>TPsvL ݬ9Q-/{ԇd JkCbx݈x՞oϾ~B2^,xu׏",bj˹'2{QUTqF-WVG1cwqȽz0{1p - -0 ]'倠@7+tD_8*,bVPh^).Lj 0oQxqs0i%*A픦!T$[䍧]^+V`1܋UBXι40M&!oarqO$:Ƴx)Iyk"Pcq$,"?̛Bc>I!w|(-%5 ՗-" ;) rߨ]>dJw^:ŎZy+fd&bLLSaXsBV]WM,+IDwF4bzc -tw"2>0h4T049 H=8ڧӆ4; }l'{H6knLH6n=VNbs3IO{lmIaȏ;GB, R gpG{,Z&d%Fx6(ks;&Wr"rڮşiÑAJF6L -F֔~>~{ɦm#{ؤU&9sbk䚤F3s& 8 Iwa``3uN :=TIyu:$/W1姝|I?\WiGd$o| ,:2ٕ.c:[gN1[# @{50T3 .: H,L[qq!z?/V|IS-^1yB!q`0C?QA)zzĨ)D4+pa!ӚQ1!α j8XABM אBc,ikLlr#b2,h8a&C 5|^Nii^󤊄5{l½jq]DШR`p0+/3(6۸NKy`#6:Fyƃ[M B*GGNS?'JWJeh°|P:7ޒZW=J!K+Rh'5`wн̔Ӝn(hK+$ks -as·ahUR@[ZH94{y'MJiTM)Dp3SOmEqf$L5@`w˺qOAFRb\ߗ(fUW#CW0bWֱBD yH `~49In/-IP/rD7Jb"gi3C lR@ |+{o*-=& +A&Z@A"NN1+mF<[ ]]4o ]ȠS7wi8 -k͍<CB*|8fx>pc@\1.kdl>5E řCN -boDyI]c@gպ A$k´mB櫚yp(Adzw^$"%HD<#vBhx2̍5r]0L7xof},{76of >5@iw29Q"vk:6Pnmɯbp)t/&G٦8&㭘, BNFp"t@_Xk@(Ėb!!P%)Xu 20aY=K2ٔr26&g-J,x4 -\Jf-hk]/dvwPՒ$~v[3IhGUߛPT">fuҫ1D e[!0QD X{ɦDN)0t@RHWDB,Iil%wyef(<#=nh{W+E}LiѾ_YtG{;+aΫ)2˼;䕾Oy? $B=>ӨدU%ǛGحsyo$3H07 AB uk:D:zU;17RG@t_5s:{qNdhS?+ jNBz1ʅZB.$n -6m91^SxLYLPqt3l]Kz"&ۘu'k_kR|K|"%at#E5Γ7+86=KqW~ǚJlO;d91Z. -rT]$3~2qz)ƟsXܽmAp>&5L3ӸQq8zELPm:#, _j U5%L gTd2L]2OeR'[!g^ݥ} 2[1o ĽVg<(qyBWoK9iJ?ˏe -]ϙ^4ܙӲgSI^w2\Fy8u˸X_Zq6 H1gHf$^hPiyABM^/0JxXSgBavsDV\!Y],D fl^3// 5eH#J%ȦSF b8DWmm|^5 ~N`P,RQ{-E7O)dWW1To@'eܥ߬>۟xW_BqQ_1~I-5N&jBT+Pbanc^ikJam(l21!K@m7Lb` N -*(P}33& q%.ǘ L9Z~FJhv-&:qz#"΀[$`-Y ľOuojꂋh0 YმrFN;# [6 1ic'xYwsYu>j  -7tQUn; w[)a>igu~AqQ%2U*ĜSx@ct8hem\?5&nћsy*k1Z)Jh# Z#{^2mbIizC,&*^a}jBVzT*Ew3%y$O}0ַki6PƊūq{|SHbE45>pe GO|\6ç fZxox\P:t|c1._/F^ -3E4;Yc:82X+00'V}z41,[aad`|SCʗ9XD n~0]i6}n/AKh&:RPR@T/՞u~ ^{>Fzb`wAsmjB]J-ߟҍvP[θϤg7*G&Ɍ4;_f-&l+{ۖS3<b2pXƙK5iyv!dL,UQ~ 4O9Cj|fkFw 'Dgw-C} -Nd],gDrKF/==+$,[C`)x{Mgb-͚i\m//܀M2:7aKL8$Vbi%x%[z -T~hKf{%刊N -Hػ ètb3(G4Aݦd -9@TGPLp -Ql0Ex:/@>/E8wes'#2 (Ƞw;8%?NZ&#V)#&fbN^~Z<6~R72OʧjeU)C$$׼@!Rޡ '|squޞ:ۂYVҏ%0\oݳ#|1HQ?QEiBOq%Jsg!ӹ vHU/jJ:_QppbPɍk590e?ЖGї/VHindni/Hq6V1N}^ %pj}k4Q؉*I3.%% b-(p[j,ˉaɆkt]Z(ܯ+|_CgRL z_cReq'nnڭ - -G3#- =ɊOK Jv:-Wx\ۆ#%i[iΏ%Q#P[Tr@ݤE:ڝ{WDWh5 wQcıO#eHxU΃ _ZZ&_.q7B;FO'IdUJLor/.ǔ"F}ǀa8{Fpu-ϟCJ~`XDgb(~BgWfnrM)'lEhUe{wdA>3E>@x{pB ͂/?\dntw;0TWgq@Cx0\͍s/Ϭ F<׋ؖPebREpe_[V1EEPBQz>Dj HvI6;Be/pL^^r=`7yX X"9 `ٻema>stream -m/JPRG]]A"كVŢܶvIA9{V7T"0c0ƒVHl.ɲ.)g97gzVDVurH,QwN&Y -6XL⡘4nK HS;Hzu0{hį^RFr &UJa!{ftHp= PJ\ԔVZ)V/pӾ{ތgClJ[l21Z济%37 2$L! -Ѐ;ьGCƷyC w;}I]fNzoN7!8SL`xEKVl0#ȝ+z4jRƙTA_S'R7rpV .*CVdlm>JGʈct:q:T.ؓӱFLl UJX&)\D3U΅f!7;:)Iϵj}7DZ 4ZtY Ip5ZbΠ2 *Ǡ4s8ȴ@̽^\uEVF6?@CJɣ͗X%Rx%%qUkoGҪ8PJ 2z)D pjLej ( 'u@#tRuL+l'@3˅2*FPy`>6yN?8^0Hl $X)HjǟIo t+D(Ex$l9žbi$$ 9y?_`T~:3ځ :;QYr=ӼLXm'؂oقY#. w5#K3Jܥ/3gݴ%х.ZIKHK *`{ڏ_B-q5I:>vM= -vc,ީ=btE[Ш& zmYqrxug\=4t1 -w9?"U5xB7 -fBiܨ*~5yj00O1y3ŽH_5'r›ތI -+(l΢z3Gs E3 yuIlA(s)u>T-@nI ƌC: -a"nm\oY2 '-C8I$)KקGgjjw*R]tfՔXs ~U'#+Y$ЖwYT7BbRDe-a܋^d{jAB'b kގ؃|V72=Fωgi2mZ8T{E7m_pM| %RD'eS=6[3.ar=l2G -LTvٜ/bD@I(hI(c'aGp#FBR0RIMDg2`S@ÆH!cw"g*.BF9oncFjq(BBmp6,X+!1VT_z-lBlC\Ǒ?F'sznF\XtK[uE@|g L^wђvHyP#f|vfzV !ATBL"8s_iFHm#T ]nnYYwYs^g<?+J 9 x;Dlh*ɻv1gTAQsP,ӂ Dw)F,n(zV=_K~IWŦi9Rv(|ƒk6L+Э'SuH8OG{!'BBBY.yȆׯ("$+$ݢQeYшfw -0||w06%Õ+D¡M,fEV1$cՐ,˅+pm(:ͩ5OqI -hˇ P0CCHr+< VA!F;VG' - f/.JN>Ė تX3NR@%F8;nyƇsTx_}>/Aάiۤ_L X$0MaBhpA PROׁ[4<[h\# Npr nju:xy-JizҜ~MGd"cYAEް2&τZAQ0ϕU^(L`HƅCOb&yE"䤍b^0/Haq+Aܦ !9W>6k) -Rѳ1_r#+a*[yK *ĂD°I"d!^=xi*Rىy˲,.jA2j kS&u,C`UБ &aM$9S|q$/vx:[ F\>Vl w"b;ϱ>nx!QckU_N/m@fU+4xGtEd_G"<}x:CRJ#7D$g߂FQR;;hYEC3```'ZNdТA{F3KGQw"H!%Kdƨ3 lo2[-No)36#d 9)B>0ӷc`v@ףǏ zr?X!㥊|#Idj"og(V1 &Ruv nMf4#@(M$ddbAl[Hup hK % dXJXLRfԡLYﮪ\7 -$T#,m0p_lhu3J6Չ(V2%c_S1J`$A&,%΢X$ʾż a H}֤ FWK+4(Ѕxo504;4,W)˩]۾&6̓ܤKXWUH@PHo%>.#uok\Ky_AVwuӡr;kQrSŞr# %E [NF;0e)@""_͂^aќP9Rl!AҝA7l -$kIAP`[Ȁr,,3I q8a}KG=ŪU}#]Ɓn#pߔ*JZPd$ؙC',;{HRO?n+)ǗBSFd}E0JFm5脉 -9V0V$-9Q02t˕=ĉ:[8FjB %[̚gBjcCJ2|!glk4K!bP3p4dJrAJH -ڎ$YE6VS]ϗ9V,CIJx1q4Qд̭VF)?mMj֔23Ll߅ԘLOeV0ݛoR] s> e1ri;*j e$l}1'$Cȉ?`*q+?=-~E>eujz4pX\X3c?)mجL~9/#8#*:O8d#c{'ͱx&FjL++8Gx`/ĤkVΦ!%ռKJ5BoNj]8Czpy=pnyEV*6bMZPEz# :6 Af7 ^؂݂Pq* mODNWeLgz9G؄P0ᡬvmg̽cFJvwgpК_Z kFm y4˻t8} xî7c%08;ѵXXk -Eꕏr#4(uu\5װLQ8G(b4(%u_S)1Dۄc:N!DZBÆt4K`lXT򙂬iĴ9N)-UQ5I@$ludAD?t{k> QHsdt` "-f@Q"a$ZzJgN,?J2vt$jiTuɫ|V,&Fp/t# -972 M?>P_pŲ qUVf*c?I D&h7"k1 jȚb^z0*C4%ms4kk{1.@ORe+G g~?c8kj]xúYEǏu(*0?]&5bCϊ4B m k;#(&Lrp0WK_t4'ddkU 4g@M#=?aɝnk1Xvu4;trߢqyY]=;t+oYT -g9^%dBDhS2)~Y!%*7vU+ .&Wcdu^HyqbU$DHlZ_‰P _ F+RdBXt^39 D@/"KNzaxBW+p)qw5 r\fk`AvldP5#EE6䰾7ɥ(L {!z=oz|L?dYeo9l˺?>ɜpZR4lF`'/ -CVUHpӤЛOe - e^" Hb4:xKOꆏn&T0ݽq̕yXz ITȓV7ظb޺܄iN@*n$-_dO|HY`-vhʲt49 ւ|P7z8IlF':ږ~G S\R$>M80 ھ#1cr/6z5mGxE5NI%MiԛL4}C8TEόj(rompIk@GͿF{ |bȜNs,sHr$6>9Z> -#ޥ$ݿ&Ot6=#aGJ~fM#4(4@pK܊" lQS 8n6*,ͲnM93sF/p9 THT[Vn2CJY.#,)"iPVN!ycǖ{^&Tu,h6DyQtFIwCV8M 1C:^?0i6+ž,+UMeSdCō,BPdJ݄yȚbd";D@^,-|5qpYBGhyʦRFݻ-fuμ(cڣF"r!*ήшׁy׌U`ɞMp"AEc^n/ecD5WV*X g||lH5=lf%J- 2P;c{Z6t>岁ӣ$,YO\DϮlb@, -C%_dE6Vq~崛{?#{l n6#K5-ݾgMgJwz~B0.#jO&sR=&E'y$ɳ~N4r+iEp7"?6$!|LY9{m;*N%/zUO g#^۷._OQӈ UHz H1_'HT{._BsXX<38&iVS"~X#x۫ -ifJ󛫐"Md_} -Nh<' -}͊ -VbS&D:Mج= NDċꑫ;vWDuwqVH3(M qէ-Qk¯ n% d'M; A˒HM0ۆ69`yߝhS -p/| ekܑ,N&"x~̻N3PvUNI91pЍԚWGbD,ڄh,*J `8ÿefEeLЙ(SDخ+zw1@B/6E_ Z=덁 -J,,R XQH$Ǟ;`i'AkD|<pwFX (f/$8eUmB ֩%ԡ MYJxKH8HÏ1Y> Z`T:}}D>:+@AlzO1D4*.7i3|mUe~lv^7lbu$Nh.{gpMGRg=Pۙ„%0!]Wۉ;Sldx+ m?mnjގ q;&՝K^tBMJEź)N qv M._Qffr 2U JL{&P]싻;5'OGLeuR\1&,U -ѽ77T.`bL#E!o&B+h6c,WS$S[06eӠ3TenP<R\7;\[+-=PkRiX pMp$oֱ^eVWwPXIŨ9.*3:3]AO@1=/qE%`~=w'$B1݈¨ƄP`XvK;<11D}"yѰ6=ZJ$/Z}lev,0cl$@5[Uz4u4E%Jz뾇nŹϯ U>#VrhpO1&t4dBx'S|.pԯp[)%ʾ.W#~K,h{.Bٍ5 *K45>4ctI%0C 3v L}VHL&# <^wc ^;U3}ֱDdIͽV1@B^!S"33ۦ/;e4w&tč]J_K{zhh ]k'Q&ٕ̎B/'YL"3lS G( ?’9Omiv+MbBlq_]@*q38jl-Xn{n)$37nzQxv|[<:roۄz':㊧ƖlLܙ3d"Y?ΦA~8"l~e0 8v*?zd$j> - F!4 (`VE@GnC3tƌ OZVnf 7yrsA*< !Ml0#rVDvMK - c7w -mI1 -8"5F6`?Rv dq9z~J%p_jy} Ng/,&;EP 2Q#1lr7Rn=܂Vܱ &7_.*2Q%$[\&c_7)5 V4Д\V{]i鯘'\:!YGFbRUx7>S~|nGu;` ~@RQ(!l rf_<šaL6H{I}8}-]CZ3ڪ(|\KϠC15GA,<=#EՎ-MbJ4njj,(H `df @u)qxmURoT?+M'"xARԱJ\saOO*0DyBwz6]!gXs(I5\bUttקhqo=n!0&=pʓ3<5&M+ -MTծz3JHïI_#h k5^Si -'dn  -iw"JH -ҒpVw-gP q&Fv](# -z/p FG(G)u`LfZ&? ['_ -8Iڒsi@x;H%2';"Y::#ѫ΍-0H0u^_Dy;BFF%69`9K9Smqh8g:P-{2b0bڻ%NB[:uS!2A28~HX/TDdS)" Eb6Qh'·+ Txq_^3%SH +s E -.0_D N ɁGD$'iOhا3h/Iۦ_.#Nɠ ##LgM͸V:7 ^J(A^ ?5~ ,6ޔl -8GDci`UТ7e3J^7녝/Tx kQ&C??k9%B> JLJB(*t6Y&e_0$E\?+(ePX(LJ7(Vt[LbQSM|4 ٲDZB 7A@e77 - -%d( ŮrFRpji%݅ϣ5KY8 xǕGzUoALS2I)pqa{r]tw9]]B -wƈM[B_.w!Tt)2ȊGWlvpfZw!:.I%t] -YeEK$oUrHOޥ+wA|bKxV!||z:|rh.a}X2 -;Bw*w=RBȬ@wL2Opw bw^AT5wj][9.û(abv0vS5y $O]iH O'i]X.vi˻~i~|$eG=0H %!.#LE3v/t䩷υ]&i9u&#.vBB8;tv8 tQ[.,}d4jDJm+4$ uD=>A:3UM0-zzAx"T=ﻖ>kn"d@Tkh`8KZѮg9gHim"8"|jäė $DhX f2z]C7Un0Uc4/ό 5Wk|-Ԉ$U0n#ܸijDn#07pYh@Pm' T]6rT"tr{g@$! `bD0='J YZ|Br4c|:\)`*>PP88;2gGMAę(fD:z!E8>pI #L*ϢD E dwqj Zd.lYN/cnt"0n$y\Ċ -($H4U4 r4D[¨ ^r>@[1VV Σp7|+k19Xv qTPi(T^8qr܆7`V*k|PgB`@m6V eZ ׬i.ÜMF$&F?ЕT({)T9+L -;)eǾ)0өtA't5m1g:AON5ց>bcWOf,0$i|^@=)R~$}Z1}C $-|'z^$%=uÇ;v8* ]J["+Q'bƘ=M(ls7 &)曘c7L<8݀[|% >b76n{)w G`7r!tPBRX7qksS=~!&4+d.Y;'p#Г<ɯ\^7Y7VlPrAE62jhwfy]a2KΟOXdG$@!d2EvX|2֊ZU莲>k/Q :i/B_m*1 [hhrN1r̃ )s<9fv=YO-JՍ=Hujg|IR9tAQ- ~MO*b'T4#cUH *^RPX\#Ѯ8}g>+"Rp 8٠ -pH#T:8RjCHi≚ )TfEƄpB$D QE s*͐i.KEV*qC0ԝ7ݣ.aQi!T,FB*#ՉЋ#cĝdjZE!+"t Syj%ePtz  tNpP)Fua'HQ~*!ZIh}65Ou0BdBZ"O%>wa n43R]:`yAjVi;@:jQ"CE#ᩋmb0W3`U" C"xf<Ü:ʀ7`5IԴB1&M]X>[ T{b"\;G -,iu5 TdTުӅ%aKUP<, -m1xS)$L j*hdC, -jKPb܌  u.&5"Y sV^t T;(@E~J!B Rk$*n"9⪄l]EZ9IH&ov&ʍðøGR" '&~)I1*\ۋt.Z"Vjv*i٣C_n BBr\$XmLU20 5et娪Q/TIq1z= 0EUU۠+ߤS|yOJE\QHItf 3Av@ |J/AvpamD\P΄IY#A?1hlHSVX"Jz#41<}/7%\PPInIMR?FRdځL4*yyub2.%׈iU2ˆ\!"2/#$gjX@z:Ac@JTQj%- U~ tvIPtGg/eP*Ɂ -f?MyiɈ*TbiCtGM z2KEcch^t1 zHEd<6!) ,+,Rߋe- -1Q~rO*r2UHh$N@BD$T -w;0; -RzZqyu)B%G*Xt$H::ȩOxYEinYAQ.SN-)ȧ@P9 - f#&V*P9G4h#hFES^^# -]4J |ilRf00,~S/tԂ̘o {'r1\Ôǩ"B&_M0/{DIώ g4LU@3djM9B]@r:yr'0$Mrs%MS_ՄQR}6ey*.& f&<;ޮ ρMd51dR0-H螦B,ZjJ#1Ct\r -KA -\pk# GHO$xmFzTF[yhcQ)) #.@D&t -GxFP+%:nMJYLUh9$#5z@_%d~"R~#+AT4Q"tX:9XTi'шkI5A_1x1dINE+CIUS5oi8(땁0N!2בK46RWn]:TYF3J -sC ΁*S -:'tF=3{׋`Ϩbj6tIk*3 -V1 Y2=lRP qq[J*)nŁ?5iH Q>9GLG,!ڗJڮ*oMN(ViS6SU"J ꀄsypdIi -sLQΔƬAE:")YZ$& 8$67SQl"(aO*uHAP[!: KVQăSfSTMC*pGE}Ĵ#Qˌ'ܖȸ2&Q%e nШ:, ,EQ^H)H)'<.`"|%"zQ+w@B.i?e1^H5;M9CC3AA񉰐 r+E7%c -w$.?QT-Ap}P5Lqq -coL"0'.sߠ$E니u'>D{y<;8H|7oDz H=Bz{G9h asVUYôv~JLy%"2U*;oZh]Wb/"&V"CSn%bNʐCC& -v@o4ښr DI;Rne"b}La8d`lD4N*`DjY #Uj #IUL;([#H/$U~h(Iu ;9)daZT?xQ㖢#@aygI~ - b|1E 5E^eu :`:+R -PL%DA:t aؒbhu@ ^S* 2:\ҙFU_IJS-_:htF: Ȅ -u@36ǧ.OJŇ(upH 86Ƭg$L9=eh PGrE`'N 8sh#9L(l䑚U*5A_{O8R۴^=F.n W\6kHE D :h<_M #LȌC -UTd*oa:x "q_bDMt's"!OA5pn^RQySE"s_%.D*Ba-QഁeB IAԙ~A1Z9c)RÃH4DM+3>BFf񔇈Rt@τG&-D<8ӓ`<<>x,8b~JE"IICLR1c̓OL@fRC-a߭PH5-CIȓ0 J! L=!l,d`DA 㸄ꔡ00P8Eʐ݃h#ˀn 4yڧ1™9V4O=)%<m g^[b "Aaf`0CGxWG p2y@C3DOCGņDw_LeQ*)D\4A$(C#>N=!-Vy-2ǟPBJS'=d\)P*-H Q*uc 5Ғ)^I)P,Bl.$mUE*ǃyɊAf<ΆSG+lB4AD1h|E)#xNGWBOX yPe.#'KE"XM -y0,r#f$H -@J-הyHQEqXzbS7dD%t/Mo]rZEpψXӜ#:ȉUR)"05%᭤ &XK!^hrЁZ-)軂?ăo:ќ -#]O& YQaB$&C^bp+"&!"F((# >Q00N  Q,Ae -30c``Y08Y -@)'v?D|O]SqQ6QRǜ1D ʩ%X͉ *8(;dG U~9K#}sz?1b\ūEeː*'Ԥvp,d:H*T[L8b(Б |,5T7$BkʋtHy G?̼TRMEnt^'ypPvrcFUmJ.7)PGMμd|rPau^4CHGxP4R#Kכ<5##&D2+ܢz[4~,.uڎـ -(P}'6MSM23hL#3TyhH8T79 NlH#|꬈Ps~TQ!"Q d%™4@;25 䪳Ud]~pB<l}5L!oUbBA6hHaS)UBD èͣ/I 9؇E4Vxf1 QDH 7d"r1%&BʰM*8/L'Q&̦xF$yo1xpB/ۄCb3 3l´fFİMrWI4PX$F -+O#7Zsa'g)ab>F0HFTU>tF)Fq/%CEbWirIvmK: !oYn,ĝb"W#DbrTȀ)##1UA1sf!/FhȊf BE Q(41Ȗio%88y@W]] ęs"j1exM"5񄹌Hpqbm,!tnqVܴPxp0Q7a:/8ĩ܇pZ8g8mX-8;Jk"6Jh]j%U"NO;:Ah)x__B!v<n$;5LyIdʌ9ؔHMj#Jf\ -B!GB]((*c7g1U\%t,"lYs!BCXr6i [#>GpLc18q %(NXQD" (8frQ"Qfר 74$ōgXd0:A\s[-bG! )}E~- G'Y#F## sfXA%-f#E#F\A> BKdMR\tb|b1Z0O[c.ǫ0,]0F8(hlVjA='YtI|ZNhxL)#}4iXXHiႜJfP"iC)27 TAΉ)^B@tFyI zªZ ×uvR 5x)+\tj(5\# V0 -QƢJTD_,BFh]L59UY$V) %Sz*^yIL=6DZaAIpx|æHeIi0AT -@`9_8h$7"A)2rC2*c.c_c$ %"R'N O0A1&ķƃcÓin2a3uOns- (gA]rSjAĭx}V0)~B'>D&"?<`J:YY^5$D2=x")fTts %{ ;CvmXfeK,ŸW-U{5DXE4OqqL,AkD&)NjFh<:74 Tw J:\+%Pl -TƬWX4E{%nm!=MT 6DݜcTO$.ـ L]VFHhĒ u`0yP# S"B(=MsLz΄;S@YE$Ρ!K(Ctte`C; T8 V3jcDYGmSdJҗ3 )[q9_`BEG,aDF3Y庅"c!un mȃ2!SS!քj=x \$F7EÛA2$dtx։^!ĜE)T<+W+IHFCnȮ&LrUD(AAD=وO ".MJ< % AcQE9F!婐`O,Hl G0bCht8FЌF,oaEn:8SW3""1%qdN+oh&az@L5ţ"C"sE%*$o GfCI#F=A+PD‰~]4xFIO}pTKѥFxRPvK]Z4xDK#5a(Ui-|F|p>Bu6"!8^sG+f$: ̄fbr9$HgbP^UhTp63r̈́i \#hptz ACo{[:`-A)\)-p`*Q5q\U,pj%IL=<:M"ƘBQ f0=daA(XHB9HT#M#`zgLE" ȷAV=!yƞdX#ah W;DEjE9e/;Hz(&KZ$͈=!^ "c}~ؔPYQA2:kJ""e1Cb4ZlQEP5jhc$qge-"rIDF'"XpNDX`DMRh;Ib 02`=$4{D9 -AtgQژUxv2DE%T)T?CI -&C&QI(K^KU*) =p>yȦPɈbLTbFaBCI`ۤ&*(֙ˀ`X@A&*HAC8jg(c@.Q"(f+7 rg|v04偋VstڎιZjL lf\ -W󙁦H#0N\eC"ɸ.%CrZHMCT6Q:gHIq$BDy#j+DyP$4t"K* T1Д6J8)1@$BAxZr g#W04Q@5M hX@Rh-*^JԪ*LKp*̱T4bIuOZZ¶<8̄9 E@PNpN#I* -%3T #Z J'OI{#5W'ZQx#/q&)!fT!NJidNEharHj;Y#{tq27҃f Bd$F}/*Aͤs _x;qQ03bjO#z`.$P$A!p&R -҈YƆa×{B|B3$+"abTXğC^8J6>(™ixH'HeKx*4 UbF"W:Pf.‘?U S! D'<#2BJω5qFQz@Sgǵ0šҍ!A5|H&J=BPJ3؆7s2|PڐXP!#:p5j3 AX< -+%2{=^֘V_C(#y̏%N7Ka }^n.3 ;Ì?!Bj> -!FL[Bf?~5D gT5Vw]ќ $RQTvq桤5aSi:~afHZj4)^3N/ ( -DERD SX~ΥlG :8c>(C,`ڦA/RuR#{NYCU -Q2RơScw(µmD${`:he.B?|+x`o*" -wS!GHH%Xw#BI1Eɦ@Zx+|mSf#ePԬ;*O=^՜њ%dzaGO pZ}tZRg3ĄL5{GZZ Dw⡢ r|<Ʋ?MX,0H3Z؂ 2M:(b }\H#&lUj"b#A p *]jŒBØXSV ͥ+o*XlmʦJHh-Av2@a6wbtV{s -K(jEr2%B -!lMEj\ʫM5Rc|< ?/aYWPJVUф(uq)C…x^ -cE P4atթ#'Q<?H3VRrdb(%5-JQ V##%i!SM %J$P?&LFRKH3 Haz T%>D93 -!"M%(4vz֭Ӎ21;Q}K! K͙ӁS!EKԦ ~FDq!%>!h&޹d$a!{8a %pn"]O&ArYQg `{0)ֱ4!+?Lk-ifMcCqLVjJ҃u pam:9b'Ԝ{Yfv|H!P NI2SQ%-ۉ i(H55,QG#B#!Q2q#?A"aE#'mq ثJaǞ{scY?)/$#<*r.!%ejBmkQ-F%2Q{Dݧ*".{+Z76xbDU^!W,ăPP5/Ʃf!Tq| ކSWO\QtT oCbBd&]-Hd@&ZSJV7HE[m^(чQd@DS$xv d*>,B CDUB "Yy<̐K H1:eP3$HX3EG`k$;V5:VP<)4RYr7+ ̵n+HGA z5Q!". -.| y}Puf>`|"|L1J궒)q31M66t!|@&I)"<(Iu+bm&4Dh PYVĈKqšͥUW;*HHƌƘ ;~݃hȸewVV֢}p7 ]eRh&T7)Ѯ@! -=*H{S  oJb!*VZN&@өx40iyћVa,oSHOdV8Ǒ5pȃT1bgRDl5x"#PCC9Cȱw6l=s8̴D M;\H2L6Eg/@"?c]j,І1*H"$XH!.ĸ3z C-flCz^R$I}WC8qh* S bL -h>TgH(XuC - f+˪BhTʲzr}!%Cd$4aQF %2C{ݡRʉ Pv u~D<%3SqM)L1"dЪ='|XY$'aS\ -U TKF$,*J!&66&yQPmj#*l@3X`yp&:/Zk\A* -ERJfW.)MsEzCib2D8Ql x[K0Ւ;0Z!bJa#0Vx=Af~u:.;Kd5նBhR𨱨$s,L|P+N/gT8a36\uZ>eƂ" kˊ5>ܝmQh ^G(ȝԡ: -fWMdab 1*JG=xDԁd 5^!3)2*XDJ jw>ڜr",Tx(8ͼ!0HH"9:d5h'MpnMAeoAhqj&TFN>+Qg%T,Oۻbbi;j'Y`Eσ 1"lAd;FXRfdԸ9ڊs,xÃjR58 hL)pIyMjmP(X$Џ灤 -yr(N*,ZᄌZHucV$'U(/HÆ5 F?bLsL/+4LѰwN1R/}򘦺p}@}gU~QDjϷLdd}pܾ uARNsO2DDe@*TC|bl(x755aD$ -" -,h <@J 0 HA PB3rz|:B!ӌ(z 0%4l{8ljC -9$nBn!y)|&kxg&ʜpKJ1jEDoJS'9@g^ZՄx0GJ7hƃ#* t$3ajjb1t<:Q`B`h6]yNrB"Ҟ< פWH5B7#qVmeJ3Y_6MJ@D`~@q*/F\C'$d%PA4}|%`6pz؍9N(VO -%[P9VDnB)NZpYBh!1rl.\l;0ƞbh: E1H4Jތ'xx*%Qg Z믛\ ɦg%3"C 0 &KR.  sr(Ufx -rl@!ڕ)Eԁ(ԶeX8"q4 Q뀱ق2GR 4" _y ,Ӄ2Cf?@R+ $u2*nгF3N%g0*Fj|7[-MyCUTk]'-oW\RtC>sQG \V,t:," tݜ+F4c#w\ B""S-*_~}Aɗ.K0\}RZ^.ne~g'Ɵdg+sB՜_PNY3.)"- &xCsAzc˧s S+W]#|EcW cmXݒ "rDN0wB4u7-5&TL:L -Qv.1X5JV!-8\*1@\ӖI׳R|)}*޵/8XlUTMl6񿈽F!5p=_^ԾM_LΔH*Ҵ7-3= ?t6(hk+| !:Hr7 IA6fxT&X<Ź#zP3L kV?Y-7FL/nWvcdcMsU.zK2%`2eR|wL>*-Vf+ȡL/`8[l~A[w[1OL@0&Gxp m -mHl*5Qb F>fO09qlm!'cmQS#[?xL2gGG8$;64vG Bգ1E!X -z9\Q²B+@A1Aj1Watc5)ة#*A谺mڷd}7z9kʾ-$"Mm B12OΧϧ.\* -T"+ -l40rێ8荆TO&#;Vˠy2WJRmcsJIE]UKq##3g`P(׆;MVEb B(ƿw9bFi\s!~)r)i𫸌-`@>$3U5'⊷?UrU!xN$tKxB(3˞A@dgmxh7 dV@aN2rz2 4@Ss,!"q]J]>@ 2H/1^gyK] _ZH`N7H>xϑCfǜCRծ NBc𺫲F=0*2*ZhjN/ 4eVߦI9'f<1E/8"t`˹͟~DJ&0Tl0GQp& -Tb"Th)z+]7y #d8W{j mբ_> 9l]$K]  b][u|aa#4C:}"O %T3W^ɧ q?ٛlzq$ƭ!ŀ{Q7xi}{]TWֵ;vLXyGd>&Dtv5>Oe7 VF" -.@ͣ< z.c˒6۵]i"-]Uo y][$;LHr/cb bA9v!S=Mn0KTc]s"bʴ!:g.axvYБ~2H0%o Dj^zF1Pk R"뙆D ;L]7eT{?xJyhUMϡoN C7;~.嘤!Clpez Wd}\c h'L(6n:uW;4hzey=7mt^^Lշ0ȓ sPFy@Y*yf7\غbQk/rrfP$"N41s/X,x}֚ޠGNK2 &Z#F+t/?4E(c}5 -h,ꭆp"vzr)\rY6/< ut+[Hf"@S .(XW`Zkf÷&=$M_JXݹNv>~a-C )n),[4ġ2?~'8Sf,Rg "<iəau:1*hOٛ OPbg\~(qi2bwS -kk+n`p~iD(A*'D_ǹμ¯2{mkj&Rѵdd&( êz9FlÛ"$ca1th=”IAmMʿ6aߡ,4cN 59v9R^`|.Юu+)|ZD҄chx`JPƥED 6fMpGHj+DuРeZ@ŷH)>@>/ŤkǴL{"Fgta] h8uU W9dDpɓ7ROeVdWa31Uh AS0%3A>9l9>y_84PҰ?U BR熓 pšɶMj 4]l*aTƐ4aQk -hL:JrF(na3#,҃/Ka߷AːVě;%BQf7e)ǁ?\^d 7{*4JmU%1ZTp}'I\|ˤ8#g/oJPIS`PRq{xy ]!*`k i?pwՎnCR\z@ zIq -.G8]4.fߓq:]g6XwcvN [U:@oZw-iox%y&tۆ9}i^ Tr{MwXWzC-`L"02TON kWQ v\>(*^2b=Cm@*\Lɮ>q~CU&@$fg"(,]`dVu.vOcdBR0'%&{P^vW*R׈BNRbe䰔9Jۥ., -0|G4ظ=;)XEr0-Er*,\-b')CgB|j>`lX7!:!;X[+W3҆cଊ͛;'k:/cWץpJ50{EBFm=ꈂۧ,FkR`mk^tp鹅7~S 80ŶӆZQ8)sJ$-p j! K^Y~#Ơb #e ^OZCekՄZ2723lAR,2fԑyO0nT&5Bc@ 5µO +%I^>yy>-! 8ձ[8Nk"!]8ȕX*3?/c8tρA4)=YKj9b~-px,MԭܲaG!BSX }7J0Vv&XTgDhu|aؒf hN%;SbXͧ%IuoBOV>*eKlgUMa{>fdn9){ya92[qUx3_#[66FgstmΛ^?$3u(` !YCUň R HO\wqSϊ('(AeD&Madp%6$؈W?Ka#Wl2/Q$u+` {G:j}m.e/6!BF.5  ϶1$@D4+8fUZ& 總'x}&[)?l ̆u{k%#ĿkT9ȿh:XG Q$N0Q@!j4RMJYg(\ļPt+ej֖rp0!VRj8DЌzdžj`:f*Ϭ̹▬$X_6ocڕ-XKt -B/louKk(|DuqKvMtYgmagRE [Lt ?h_UzR./ʹ ט|"l]I^$u%>d$+ǜ~8&\2LMJ)uS--igEXj&V1 `%~_]x/PR`tj :(nꭐvɐ&Bhį#').Ц3yֲA,E(P|ʍhV(y_vGrl&~#޼ -+(lk]_!=("_R3> -WꏹNֶ⇡TS#i:nц,zic -=$|,jϖdNʜp[ȓ.~ަX(n1p{QbXņ2dZu7Jk -XijbV*[8Lo׀;$M$'1`O -h4P&}FyY#kJ<}@Z'>*i&N8f2#DI2 s -*cH}80C ^j -^s%΋XAYL*u&IĒ -Xv j6/LN?È\ 4zp՝ݠ\$~.: -*Uݏ1ն•?" -Q>I[r"xr)A-#pc B ?%$I|t@wƋRDҐړ ?l؝@NJ - 68FpwDkb_06.pd4 q*!KpɏP}DR:0q1?O;s 7GObrpͣdPd" - aib&S)싚 E,OWo{+ƭsvE E=^&^L*zAl:I>k߷CEx=/Gb|cV@ @--h#=zK ,g 3!,2 T:alV00*[hp36KsTKwiq+WO3Fu d'S+B%wkQeьIIx C2a7?/$2D/XL?oJ~1az5:}Rj=AՍ$.چo3j re -/#V̳̦,vgTqhuV5kwZd8p$_ BMF\`4#ۊTӏ& ˀ7Iβ˪StKQI A`9o Xtk#)X  A'?|rhT4&.wI[62sȕ!]Ep~yΆ"f~b;H#13([Cz(be fz d6/3I2QFCSSԋMY/0ї'$6Qw >(F؞ x iٳ7WVҵL^)~=Z]EE' SrtrW͠TVwF'=/)WEƀtU|Y~]sˀj2NF2I6nr -Bx{ֵFq,ܢ!g [p+HcSZ -Ϯ di=x&Z2~DH3eOS8E@r+&2I`[.y=^pn\g 'Lأ-]K!*> exbaY5d/E%1  ƺW-fHE(NOq1Gp?͸# xl ])U֛Λ)+r L3+MKMEvY},8Y+F$^u(d)uf`~X|r?$}6BG.ɟKaIu'CEi$S=e3~(t~EgsvhVYLX<;y,i#ܴ>EcR}Q8cRGrtJK>=kbtH2 r?Cҿu֧i SW.ķA@mRK}sQSfƆQS.)[ jl[GVcc^K\`ہcio4z6뢯XtGŀ)sޠ@p F_5P z&i\ZcY9oܕB+! -hl8ѪtTqsU:(p!ܰùR@HdrUcLEeۭaSCjz'd/^0)d^_+r9gC1C*U!M,YIC$ GX7RRoV' -硹?Ʈ\A( -2_#7k=e\ rBȉV`J 'zge3lf|z|bKc=T-Jϒ二=}dKLLR?]A"pBVOڣn- 1NĚ -M~8 Fhe]yݐQ'N(ΛCw`+mx&^<+uK -ンt -C`1m)+N+*p9FbjW^ HOK ^j,"cCDH`:VaDLK2p8bw{m)+JpB3D=PNYz߅oOF,@tx?_UztzLFefn܊Q$ō#J3AJA121aȍ֊ `Hm'홴a1eqUYK,B_>1[p${ -WqEvLtBVmN:z^~/s4)^zr Qb5-:"_[^~UcIM]`ޖ" -?'jWy\U8R?cun,)iA2Ђ+]tj'&-l -\ ^eqe]ląȽó -gYȿƒ˹jVqQoLt}5#xOjL=թg bIŹ88WSdkmq~ٵK -# EU+@L#vgڍQCLYpui5 ~ޭ?*p| %yQ<&yrVMtaqljwXͻp,yG̓dg`*6eP -! Lq,V<]t7nˏXb:Oؗn#o E?A6NN)/θJEYNd]7>[Ҡ[H*Rj8*SL&nrO ] 9 '~WC*UJGeMNiT>+?{F;m;xUFcKe ď-~7z.7'H|t:i꫈R8p̝Kx9MR㹵NtS ނ;;,XͺZG'418C"!8Gb Lц0JA ͥ -ׇkDB12sFj.b"1tu#]s\`7xŐo.;P3'fዉR @'FI`{j܏3lXzit7-Gqp߻<%b[]~ut1L$WOo}#0˄$&Nˤ w/nu 3vȎrJ{DPۈ0ӦnNYۜ`ɘ`uvi""3}?&dGW .` u^If7֊)&e'CydWPCcd!O1L; _l5]>H48+ۤi.&%IJk&V#'[In[Ǘ%P)D:s3ӝ1"vI$4S<$!⑿]tx2/Zڵ5ԤRM."8Fؼ#{!VZRC^nzCއ\&6:w+xRf(y萟:01k@۱~NJBS8_:~uz*<4n?HŏPHzVQ.߬^99?_5('e1 =b5^O.˪ ou4<̡s8ZB.Cgc0hD2 ˮc`A!C-`AxΧ㳪HQzH_yT8%"v& Du:{Pp3Ϲ>.5#絋ET@ jև=wҡ^&$\3!TJi -ӥ +D 'bҿ0y,SxЊDUX)^ c9/"b^@9gp}U+hnl۰#k $ $+4&LM>οb@ T/ۥ -d|N ]ܶ"sI#nϺ!']jyXzZ؀0))RE6?vp#yՔa&j gw -znQdJik1DU0¯5BQQ d<; 7l4/qUɞPEFh3l4t#x1ԗD^tr K=w9E{i^G1/6Yz+Sz4htJȥ0)ZWje;bVMBp sO1ߎH`ݜQD~hws!V: l `Y1Umr$"P,sEl;҂`'@<269,X6~|!AꊵS_ⷃ>DWɕT8;TCL9Ktpel`:뫺;Yf;htN!.琘y7j;qol]JTt&%(%;C ߮v1kCX!*my_:RRe@H5m &8Һ||pCriL+ |<11gEV*|hD (>FxIp ܸ;G9r XoJ^[p"!=4nh5DE-༭ζbp p"gr|KMPݤ'/&trp%6FTbC.S3qا[Pu?Gyi022ml8,L qOTPܤgˊ~tW)*5dٟ "~,gmذwLo&oSN U46?oIDC[ +].e%EIQrB-dW2#{["JO  )ܗV&8hٺ?C*o !xzmVk%Sv̺I͔Xnvg'c5+Ԭ - MBYn;2>4PZ'G6ܻ :8`Wfz:{@{`KA3:&:n(sWjc H ,bS",n1ָ3FS5L֝;CdWkP[_P(/+׈A%/wJ0@)pM^Aՠ>sT]~ Oܠ!4ɢOTL~@;t$m_ \ _jhg,s_#jD;u: AЮa,S*6!|/"s -9Nk:;7<x"kzЏk′lb̃{,^hoJHaO/xFekl_w`F -Q7viw ^ZRFd(X>ԍt+\VDEP,vh4hQEƮ"D{nvKWR@:䲤4@JJdXPmU=t~ AAC;&m/cwV\ zDAIUah_2@'Ⱦ1vxv@RS!c.;’PaiwI'm6+uZnuiICߺJ{Bi®z:bpߢ7z pjтbM7@H4ope/^+M =C pHUfteNxlF<'E,fK$։`!SeOՖPe: ͉ŏpxk4 +)s#bws3WgTʀ!CFP13ZoiZC(=.{{zG-&Շ5 -!1gT,zJC,.}bO -s_)&"ʹ s0ٟOn -Ͱ05ތL/ _sqKdQ?|)\zCXI$=xmGn.z}SeDžcp3/#@hbaza5Djkk%tsUಕRٖv88tzV༲ zW_;z^[IąCuWZ]4ڳB~(lP$ `sV[0{;QKyK5nBb ~LGb c@OFu0 eA PgoѷaCCiZqؒx}MeM7-mFR2vNi,ze3 :IWOȒPGEad"Ψ+=Qc|#Gt zpr jiMZTջ}pO>ovJ.]TE-نiP˓ O"Fzn #=tRAL\jbUz:`{!fĩ7&Yto;O^wš>8m0ߓ^Z ]]Re >T -c?E|\"lVyBىiU]XIx^C[-w -XnwRT:$~L$U +eN/ -mdWNG}")T6S\YvHCq1 -.A0CaK3p+wWQf6c7B"X6(B -$?ؖv)e~KB@m~"7#srQ3z(/G]lF2L5q&n׋.9#2W̼ , ;yFzPԈ x5)ٍ}|KPW@s!<7!xkn1Jҍ-)"Ԗ&?a݁˱;oyEr_O[S8t/ƙɆ;׋5XV]2ģbϲEA\'e}4|'!bh0ByBA?Nvj#H(hE6;m7|~o"T]"dcATyS.*{Z!]' tGf0 ͅ&tCQpz5}M+f<.¹-*\p{ wAUeTjLVBK.rw}Kd sZ'XijW0^hҾ!zD+Eo3z'浤yjV#~MRORT&DT5O#w%5v,,-)DU.yyVO"*2TS'eYõ8zR%M?^R"zOhbDH'.%Ȁ "F_U5vDS/{QLT>$TZ )ԋ|OltgfNU%jn.*WnjDNQ2o!gXd|w;mI8499iq$Z?^ &SASa>/Nfn OTycv *s! YeD++Ax_)'4^+s)U(# - 'H4G6͉E'&cE CDi0 $5gB(ohͬ7Bnc[t މ[1mQGw S3tpdbW4 a(]"` @BOf1=,(0 GT N;_ͪ=#AyTXtaEy֪DٝgБu'd%E]Ƚ"-}tCf==?L`d)͍(Yt9.KnL>Kj93tob}쥑NveUC REϻ.n7,V -9,?6&Kgh  COy$ZDX;¾mCe@H*luBd?i .)A]fmN2{bK:w 7ʫ27\-Ԛ&%:g$N'{) h1HY}2;Rʩap`g!*q_8Jn$@*-Kq̳}5P# - 1J@yJ޹^ _r|PA6`Y%1Pzx`C/ SIz qAdᡆe5OTnq)`V-"u_cuCW5&y jFT-JQai%wV@?87zہyMoOeg>x`cC{G H## ]ugW`c ߺNyGq4v?:owB\E -׽Q 1_7!PG m@Uc V)oig$h6Q/Aѣ.35 i|}qv!SHoƗj:x oLHxqAl?D8 -i $T=6]?gHTdPzeٞxy8}&^!(p<@0Zfy*:C3€c]>zf2~w*͏ɡL)˕ȌƅYa>rpJ&UT3K>Àwt@(92wt[#NDYM/3BΏ)OA?-s~)FL0%Wr@X` g6iQKxyB,,vOL!HtkPqqMʋ -D,+0bG#&9Zdbs*)Aꐪr!>.~5iD-N ?-ޔ&D_{H!:ξB7e7&UsVD>wJ>-{-EOK=wmr#Y]up`hsKQ7>v:}pYF¿829'sPd5/\5bycc`1bmGBÉ~ sЊ|32]l̺9 zFhPL+ ln -9Z#.}BJ)l\Jj04BmO5ÒJyOQis2+DA$'?!97 {a=rZAP=$f+b茟k46ru'sHqtrr/م,YTfqZm3I `;G|=ϓ5"M-ltA -!mR;X~m3 ň#ȽG ީ,!QE-W[$ $9K$5??".Ub`Vz G,`"gQOԟƹm0v:;-N'Zd[zcaF.DY6ܴ'[Fd5J)6`dӋnO숌g4#s. h%HAM|>ƻeC -- * ?q8BUq~ Q T o/# \v|s({IkfSFW ҰVQAqy_ߗ#׏G&>xўQ@@Q3L$ I(YW[VRhӚV?|[k{o55 -P&~X$z##7;j#TՏD?mNFuFȓ[_ Լ.?6WgaعZT&iqVR2T}xDMV%gB/bz@*VqLT,! -/#ZӅyQ>fAm(1i 'j(.V±,Z=b$2V5Iݷ^aw4Ac(块:5vqOvߗ>i&z|?k<2x2`(j8fga`ܨ!4!Q*< @%5)*-w”pZ[U-w1G)W!"t!,:Uf~swј3yqt+BErr]VJpd\ObROC -5F܎rH07ŕ{-sO'+x.HqdJHd[9YeT0ɢf]~T=óL\o(nҽ-6ΫG^S̋0fӱɄ;'DRƧpUSӸM}}6q$[)bDz|kΐB{k7պ}03Sch5~.#![`k u[HA6#F\ؔGBSrXK9Д+?R&_N_Xx9bz9VC4lRXGjgD~s0G0Z'.']g|E| l4 ;;D6+L`A ~nM<T^d66#KUwY#(d@/fdfyha荮Ky>ÆhX Q(LQ{ <5.W㸠?|3NsOcc4UJS*9M -Q~\Ls|sq Xr6K>6QK,hL ,ӹ; yQ2A qϲ?{|oxD3@.IOyZ@6C P2'"&{DK, YE&\YBOWEq,F*XqBlfUya'+Vc؁%ع0|*XtA4T] -=[i Yخ/bK2aIX"y=WQ57~l [*B\)W߼Rk5ͫ5 oc"9ӸW4(,[葮ǀ2[6jec0đa80Z\T ^ҦƔX4G"+?1 40V4v̺\\4$Ս*$!#֭8 P,>\#ُL D쉪(V}:yk0-Aj~qW~RA-$m [tGÐH gNW` Z8Pp3% ySu%[keQZtHA?*:޴?+]vmv>|ps`}T鶓\sB -x FDp7lHRB MkLcyyt - }{ -K#oc<<aS(GK{m740OKsc;.?iO_"u*B|[э+FqFG2bb|iH"ETH1]5?5yj҉p+NO0ft B4T.38,,ΩpMOkǍSwJ/ n0K_PW^L켇şF?l"|`! 1?^m_۷QFjB4Y.f=4]&#ķsخtV[JfAZuV{mX#6jYzdv 8o7#<@Y]k&ԣ0A&v$e yS W#p ,6% gL04ImUm=Iܣq=36Fr.J<è RT#S[jZ@[Ō|wNwp όx:+~W^1jQُrSna¨ı_g`A(Vrpæ/ՄF<_A-dtxj5a,mA|v -9.8ΞUQƔn8*MUGA0㄃SNmb;g&17#Q -At,ofm(5:,ĄtV=U>A VءRϓ6őj<_7q?N2UEzD&^")HܦF{K+rB1eiĶw dx'(aѩ 5|B -pB_d=U\TK}ng/@M뎻}6^-P7RQR[P2n?Jf,P%9x(<5hd -›y}hoCde0Ѥ\Z Cv= {A@7++U:"i9C -/:߁^٥Ą3 (E I3Sm=WΪOpGR-Oz=O4QBrB1=v%݇w-'7Gb(4`"{440ƿ(vfyR=W|5[ܢmBUq/!Lx47T.:Qh kJB֓3='xHi^}at/i{}qʷ Zק;W8Fm;^x((wvzmu8)JzEHд!N;K:ۅcQ'r/O6W -eXh\}PZ)%VaH:L4 -K0<ӂϻ -xiFͳ9,j5uek 8d҈ ڵk*~FlEh]Ҿ,DopQ;ĻLV%qBk`g`t+ oY0*ʃn6I./ "u ews)UzX :?R\XbpcmO(fudd.͂ȜQA 7yg"ZcXHck{VC|l!ytq -68*r`TDW\AWji;߷5i9_*)萅;9 S~8^ĎA Cy>A8GY9^\T 7DV=+[,m#jT%AC`Cp{@PZ$CiMW_LfIz̚m3Xx=0f,7ROb)A(^a'S ,@ڗ@mH}:V^%2%#қ֋K's "(&*ڢ4TBݟC8Rdw &"D/ RvOl`Zs}F;3ٍ5б~b >^| Zn/:K!ЪmUV4K2d޾1D|(ˀԮFV䧏 x=Im$3NH1pp]btRy{ MWf:%ZbK$_AH ] ~kڎ ȥ:ԁ9)H5ia%ysT#, XZ94kR C^U%*&<ΉD9?Rg,mͦLk(^h6'(٣ IyDI YַZA-484<2ȗG.k35H^,`"Pm2*"Ԃv OO'B1#swJdj8x?4*ύ2k3.8I玝`Kmm@gn3F"5ğCؙƕIlYσ_Lbӈ4*PA%?!آU),V=0XjpѰ(6u +|TQ8B 0 Mq.W6ڽz$UmVؿw[X<5-I|hU{ONܣ5=bE6@>} 1Db|[+ŮW%Ws`I3s'Y05_mQ;t|>"H'\X>~X\t *(n @jЉ=I eį$6j~@f Vݠ7Ln *t%!lߺJ 7x J<8tSC6jz |l]͎d.O[2c}_mnf<{#OTv~Hboz؁6JpUw>[+l,ӧ`hkk]KD }\H6[U,}kM8m% -!HKhlczq;I>`)pJLJ@W9N%`a_2hJ[ P嗸ΡN>* [݋j+%Y[ -.d͉[F#ŗ`Eb<T| !*ש+@o Gs^Q_pR'Hp;`'$CLEl0N -&P8 (":Y|>#fDafd{ڀŰAM1Q!S4'7TGP1ؕ\K #±5[on&o.ns:y!Ÿ+8I -Q$$ p8YH?o:ͦ]G2`JUҺ(ct,tKd+`.Q%nKIm<2,!4Wg{E o l@z1C#n2CghUu9 -7ѹ"݁ȅ .r&kohT:DQ(`tr -/1܈\WHQ#=XeAVDnhz\u6nlcx.8:TDD7%h -Ghw_l;~ڀ&Oi3m}]SĆ \@t,IGe'#$-wD1yik2hr%x&83lT5:eyO[1lRI1ͳ'0M5o%uaQeYkG -JM2Mk>Q[)219X~=Vhy5)tfm"\࣠V7~ߺ-[,fc~,~]x{tfs΍;UpXz7Bɿ¼;RcY{r/"ZVnr"U$;г$eތ5K(#Aʍ;XK_!h<=_~X"K(9MYHI5M\2 ddK#Kݪ9oɸ<#+, 4(2ɬ/.McPӝK1(g= 6[9KЦ94λv,h,E΢9;#SݚNZOCQ&*/ -L w: 2ݑ*,"# - ц]S/A'Y"6ΤFq) `eÄ>3O _nyڜ&N!~4cq:ߖN%:=S7j~^zjh-ȂolaݑJ ~%8 l0aq*1h iGJ NN6B~Mb!ěDU! -$8\O%{K϶Tkō}~[Š;tHKHj=ǥSU`O!y+Qρg28QRQ Q -iۖC8F9:&[ -kZ,&EROEL7uQD/ve"{x B\.s0P=!Qmӽ>M73pFQuMs< IL+LkӆN,%e '`~8T1t@Đ݆My1NBt B5}c*rvãF|'#=#GAcucJ& MhPdhZA(suAOZ,W)᭸h.!Ȃyۄ9~[x-fy3w!>M#C0sCII0*h|m7C)JRTul&ͮ_e|"'jH$H oU0Ån$tL4WT$;N0 qX.< L$ǙO[|+I9`UG}8rf0 v6N  yBQ1 7(.]^(8 :E H6`SIJ Gj$Uh}(2<1TT糨bʮŷ,H^ݸN,y$9VB<)=yzl_!n{\pT&8p$N&n)b)ɭ׻AcG!\?ފt,y^xm#xK:%m*T )h44Z>ADT!Y75Faa> R3zbpɌ,q&X^A))K{.2J_gx`GSZS:7P)Ryܕgٰr+-~d̦[<NqxCǦ/Y.Vғ1f9/H5Nl]z?oJ+AMp(LA |W>e펜<ѦER5Z&)ai mpG(sάk-B`I LhԲw Un* g+u+LjI!] 0v9c6BVrC\za{t$Ws0CÇ ~# ^ -cQ5̜CP1̈́*:]ZQY~,u]Y{x}wx;Odfp%l4ݶ Jm.[РZ$얬b @`& bMŁtXI|nV˛G,YՇB3 ڛDkp$n_3 +ԀmT];X§keRn_}vڙ==1/ wu0Ylϰl"h/A|4chثZ).k9#m$&᭕超c'h,NbWixo?/LfhBʣJ9a}^r#G(X-!)cLĦ;ŀebXDbZ'׍>#GtfM또֛F!`Ihy_;ٕ9q^oN |Ix&s/Nf.S 7D6R>$4F#V!f:O48=GO ~HDa#[q -j:ͯ"O?`\̒nkd 7\x]i@Ww50 Z;;q9HBN0 V-g7oVfbl +]!t)+\>Ƣ!.3u|5*[CIT?F> T*/TakQYSo8.fhZ*HS-XY$QڙGFZwpR!bht^$p&^g\֑AB*]ozmMIN^ WZGhJ\Z)e:Ó:& -t#tJlnӲ:2"S+4e\t2`[zwq͍EbszlVZ莊[?%اnN8Xߍ_C$S4s;\tvr17 -Ifiᥛq!ʔ@YcX H' Ү\մj+ -tnW:[vU<z&})7;DxUYxs҉$UAY@8aMDLv۾o exny‚"653QD0C_Ɖb,g?pl4j0*]! 3p{m{FRWjlkj Tqq,[Xk9i33+פ=BhQ=ڃ~z8q.lJCт%Ɯ6 -l'D:!R3ncgYI@09`(4?Eעu<Cm,r"ʹМf9i -WN- x҈x9[wLÚzذ;誓SuE55J`q_Gs_f8Қ%M; >J$i,() J^;_Gnd!nуa;sM̈́hxhy k -ak'}S{m@j ~**D $U XFl[ tPkC 0Q`6-u_AP(q]@DY1s~ B4&Y!o=Ζ?/pb]ưd꺯ڵ0AR@^ط[~~sg|)ڤPo=Gy~4ȭ^T_VG\b3xK`+ɠn1אH3lA=#Hc!*ҎM;{V^ -i] =aO0%rN}@yg΄}Rpq weV [ɳ=aCQ?&ޞBR,6BDzbQ^I?G7:b(޿Rڰ$J *^yiJ:dmï Q hO0)"LoW;ʼX&(AAs]w!N qnXu9mF!$ĪAIWcȃ#Egr@g~=Zqd3( &N͍Z1[\j<^bpێ -9[q -*@HQNCt"h@@V9pA[CK a*IW6Ζ0꾡\Fz7\6+Pٱ o`J^.cHS$Ł`v9$( ^ lw?gD#84S8ދ$yKeV=_?5Qځ⨬;,NOKvBaXKFۿV+W -9+R҉ SM0qڲE8ڌB^4H - elcT(5ƄD5H ;e4B -ہr{?f`k֟\^V)"6(6ё@$%w*:&ybRaO?U NB+dbII - T_Wer{A>MFI8|" ` <c$L)%@O}1 jCWuZUȄ,T̩ؑjfN4Ж!ND v}J !Is8qᩞDaLTW3L N9)5J 6LmLkR դFЙKlסP@R*Z+o4S_M߁8ϓ 292!A4_B'v2A2ZabRM SgvO`e -7 -pH#9/wyU4TTM"e4,V$VG3"Xe)O[bF$a:3D (3Úcv͆ ok~>DEgiEKaVìNI%31GPT}] -TpQ-$³lZ(ʈTeZUqG~s4K(6 - ]wt -A!?ы1Ȝ Yha+B~bzq9Ӂ8?& GՇ6X4Q6-*mP WSyъn)Ll|J1jQ+fr*kU-jߝ4Ul0IN%P("5,u7H|WCCJA(&mD8'`1xTSA&UrZ-skHalE{M@S(s>I$ 4aT.0ct{O3e@KG|CT<_}V#"jhaCH̙ -AKu(: -|'߳46:9A cAk8J%Dz hp5z"DyyU>lE  p)ف -c&<_4׈H *İWj|b`f.C?""8rZBRYT!1/hk!Dq -4KL2.S@rM463B vL_rLP3a8-UYT%pD .,E4 rHĐvˌ45dTŽOt2ȐC;r&,DBX ac&5YQ --_ -䤆 Z%gI(JaeVoJ!9Lzu 1sKCC9FZK֌CTET'7S Ay4e|0:3Xc^#/Y!X]6M< Cb0MTlhWG"uVsI<ظa65h"Y LV| h9j—@r(*ˈĸ?XF27ШY}`P!KQ_̭Q -endstream endobj 22 0 obj <>stream -O"$( hh D>bY$A6$R dв[]jRDKmy&&Q1]\,o561Gyh6x]YqBh5&&F$SVC4![pFmU&KVME"̔X5 -j SC(TJU3e:9TR4ZX܉;3Q#eaf3ȿ2T*XK - Y&HőHhf^QHGك~D54d24S">>Ć.U]~HG̽f /2R8?9# 緛,eͪ822%!e¡49kUs [(23 5б}P Ƙ'ЪDGSPМ[]519B8 Fb?UtE1JfUׂXpK0!Jce'Z,*BC\be8Oj:5BhJjYq+Rw6&Eb#1A DN6af|DvHħ ԡL3ɸA [AE ²f ؏rTDqQ.NU," -4)Nȩl}rH< - -c$f1_M$*B42ou7AIcׄy(1M? )Yx\".dEGKj)4܈2^}RmI.:z`hJ~8㺫g s/T=[5'"p%˪*1`LIu6 vL%`BKQ\"&&(5S&X0gWR3. -qaM T! -g$pw_T,Rcjrb[&\Mĩ#|::q˂DEb qGljSPXLI@:jeQD:P f.lN7`b >S7&8kzi̼v+( INeLBc-0C5nH9Ƣ`GS2 -UP-r bQ".hv &O/N&"tOi:BI}5\ c7n`XCDїjCc)մe}1vO^٥bwD5@Px:75o L -] YRSbܘ\B!xjI-$T?/-hiHy8sV CIϸUf*LI" ahCT< !  - I@,;QxlȌPX2#&/ FZ !ok'wlx赁`Z"f -UI|8*E*< -Yk*4P̈`6v.BMM(Zt.kJuOǵXO:5*#x -@4z-{;?9ycI("dw@hr`5'B' Rh& )]رփ{3CjBOcU(s Kw sHTjC);'wW+S$s76Js"W·Jd4R}I0pNůY,%bfT y afj7m Urn<#sXioQ|:CI3/31xi$FHr"6"$ӏT~b¸qaXR1,b~dȫW@uaLLٓ&hT],׏a4`js0wαtrtpGJw0]D2#Lܢ0uQtbN%1dlSR8~b4:^=Ad4>}h t3ˏ"4P EB|]D --Ҵr\C&!/b?>, " -TB #K,2E~k"ᅋvcayw|r1JGX1}6:8LYԏ -!ɥmagT"8u$fT(T̉K,T p`ȌL斉͍G#މF#.a&c&T9Gpc!B]%Q(bsO,sxQcVwX٪}L0e¹I@j F z-GPU_L.bL tTAh(4b Z ʮ) gDŽL$j -8!ZT*R->el0<+}0}v6]P+!lHFB'4CKHꊠ<]s8e)y[+ (DN󩗂G:ܮCz8#i(DZGPh6`H萃h4'/. hJ儸"@)F|5H*jRY(m* F5|xI -: -$GB8,ee"rEt]+OCGTPd4 c43ƶN(IPF)-U.W3ֲb"un,HR)ă?C_ajߦ5u<5H"d"Ylgf&ւ=))kLό :uE+MU7@bv1pJJX!w Bp )5ah7f&`,XV)i8., 0%\>Dfm! UjBxD@328KM(/ኍNQR:,UPp#5 -˄ -*)GWdT (Y WQZ&}Ew(sH/I-}̦.|ETsO"DtJG}u&j(^/ 5Hy!e] M_2u?,jq8p"H,Q"1˜FT6gh‹Pbұ9(44ޢ)&+p Txpu_L"ZJQW񹩈S$uX\ ˜[Qᙈx. KdT5WuwU5%(FG̠ǃ2%e1PaQP-bĚ:!& kLb#PL vҩy6:z?ƄpZZ.ֈ#H -EB*;uUp91ct8Cn„[?(Z5.&!*HCd-]aDc V%m;g]Va--[>VEͷE>c4S= 7RR2:ثCψ 20\U25.~B6B3?Q#ᾩ<Y'zE-DS PΪkx\Šu94D}zj X-rQR`$U+1f%=xk[h$6U k%ϙqJs Gp^N0uB\0$*^V+LTܫ#:| |Rˬvh5t_Te=BSx!,mf2!c7CE<:"∲A—Ry^áAEhoM4J1Z-t^FB  }ܑpBbc7CxH&&N2pÿ=f k)mXIeU]42_wɌDK&$Ik! ^> SGI<GK髣2ɩˁ@T(B* ELP%XBV3FRE555T'tF`Ë%#+bpdx*M6#DP~4hjH%j5Fc D~5<A s1Db)ܖg'0\'aP̾YɔGKEuFDOj:eS Sqr_!?S#AZ$D\L9=OeML)zi@ި4EBD8ӄzጃҊJ @gZrX}≓MZK"eTrB\|bp%A&و¸*tlʸNLzN"6+*j6״}M2V']VN 㡃hr01AŰ ZpQED2w$7"329&T2[!sCDfmo#N4Y$zA -HL DWuQ5ZQ*(a^Q(kH#yFN6CEX'r"~9žMT o`/BE:Q5^Pn9hEZpWOd3UG_1[#'{cj`" -1әQ8S DzX+mF"K8D&XJ0PvOmb U*A {ZAa *Bb 䆒5:׈eJpe*àQ -f" -(xE`}:զ84fF!EhQׅfgh!BlDźzDE^Ԥ' 3ƏDh!qzuf:".; 'd$=x8%a$ԓkmDr8TUc8"HP^":&2-;Ŋ≥XHu[7UAc8[fNj40`LuUT`!dO475)"NHp^ 74P]PWu L;t&*SWZ(6(86aMgY f&ߖRH+dLA\2l'{X5Dġ@Ma(쪤^X/ؕq*Kqf^^R/hjq]zH1om0)#R,(@"A0? S-\F(|U+3::qzK C1jiLtSLh - 2C$jՁyj☕׊6k4QsII<9:LJh#!nk/\J}Mk{E>AZc}9<ĪJ3*P%еUzS8Jl8i9ՁDDe:F1? *:"f?[N8If %S||˅* 7 "| /(ZHk[|93d[͊eH+J% -sPU/9QP%&3Uҩk*: [.J ЈVp>*Xزꌂ˔0xQc?d ՕJ4Ɔ' *EP4"IUߋID8ޢF-/uSY>Srr!eڑς(©@RNM8B̔"H)=1p'#1mЌlb^RQSW-bGF #iAV60C6LCiH vHΰ2e'h^oBaY D``8ɦ# ,PaH $ }x'aiLF!HYH cкa Ԋ3L44ڄVFBM;% \PP%,Lʌ…HH$XDta.)ɀe|"Y>V(K&XQ&HNRU$|B쒁UTI0L eX`t0@@P2 RJDh.ݞRSb(Rz[X^"4!,*M!yCcKSF2P3Qd v(C_LKŚTy4/z{er <_=AR4dᅄm`V)6`60-\.aF E=u _u#2`+љozl~ -kc J倰'5Dvll b{, x58 t;` FP  BiZrlU"W%"rKF.C\/H2cBTRՆVn([b)s)o^m 67dClfnj#Pй%Įm4,@BQwnߦS䚾\NDT8mCσ/)EV F@"uKxqR8(9HB D vO杁䜙 3@/`pß*BPɔFaw=H6ጂd =@Xjh%dhzFHu+P"46):LNG&&Yry D#р!!)daCS' |(SҙѨLI|ԜWP0P\>v@0咹E.b_H7- -_Pv^j$( /XщHP4Gԇ\"JKhq2Pd2[Z4^9bR|$9`DT u~YZcD ̂:3+'8&hd`#n,F}OZu UժD4tV#J3K6FŖmF2|`aZڊSotj"Ԅ@tJV˴$DRT"3KS!~)G=Q[N2T(6agAL Ud.f\as)qCHLeL$(U#sߨZ+ZQCZd0tdRb ЦJ6N<>C̦c gDY!(s>5qy4{X@p ;8F.42\Q!;L*Z%UU%BTe*FNqdcq$\/phy -rk^`#:A8֖ TLufAB `!*1#B2F20Te)"gRh@PR<*dDiM(TabsÌtJʞYŵ *cX"@4`0 z@Ʋ D8BC`倪D`:h:Ҁ`A* 9LކwZ1T%lpƮda9jd(ߦWXzY(6ͦZh w 01X`*d-ln1"5:~EoE qtOCjSHͳ1Eѫ{'*1**򺾖l0Qc:,NNZ$. r,*PUB"DhJE$jΌeӈ8)p"⎰M 'Y!g,>Sσ}>j"k '̎RLB'qUժQqH觧)mǫU"J3-+&^g(L`ӻNϙjIMFКx]}!_ԄgrQ u(cH5 -AwѰ[0#1Sdv***'!3ˁNAO]=wQhPQb:w;Бd%) OQ,EmPӉiX+Ẋ֦(DEdsO1JmT3BK9=S)u U(}7ǨDn (f@3`@  RL1D  -Ł8>kp/Y"U5"H1cNu PkA4)$A GpF>M((4PŰ aj,ВOZ0DMM'(.)])y[ -W6k@ߤn @MuhvW32bvuБue@̛_+EY7·Ys!=ag4Hb{ȫ{#Ec"q^k'85.dH}[ǖy[C^Hތ؋%\H/Fq1@fWNdm!5b7R/mU!%Mc#]?Jjy=Z8ut^G8Iwu'`]>6b\R?>_Ap|uWl\ +?^S@ wdʮ!+}]jLR4E[ :y[f"E R->Qe/[i:)섂t E!#c'ǩԓԔ݂*}U 93%$<5CvPO}ִf@1c0F,RaN Hic1C-s)c,[4 /|ɏ@p=-3ԫX0QiE^]?s;+}!Y S`6j6T kO> Lj}?_T,Ni&"2X1lN4fKiU!9g=Mib[J4Kj3/!l?.?lD$vqF'&'Bd[[TWy+iv=?Jeş։cLE3AǶ5*Cz%A~vb6`p_ Gvy%z;0E@^G s%dm~XiKQZe誹?d ] @mC?"P$@,t6ƙqsd? cO)<+ϼt5;B~EzG|/8dǭFzb yFCeOpR'RǬF4ݿI8A;p4gdUk8ܟ:nhpؓ(Qn{I7:[g%k#X#'XRPU|/khrvG. ujn] ?\Z!;tf3^6lht*q95b~S{?GդQc@M)V$HFaP0PGmOiM*w{OAk -yH`E/eBM^=:33fn*Ad|9ԒFAsDǗ~mc"Ymދd3ܐMvr z!Z>ćb 1wѴ_(mVw(I3A49{&0WZNr] 4(P‡OQ_x 㪠BG*쫆hgYCf_膹( )JM|~27{{ P^^E~\y"'a jIeڣ!B.dCgR쁷ep\΅QS{ݕH M"D~mi(/w/ybxFB5+Wء| -ki763ðS)\$’JI?ʼұ_RRi{Il2~xz0^I>r6spb/=2Oehl0qz9&/%NmTC50F9գ#gՂ0[uR5H %J2|X(B7jg AYsD?+0&zDŽ[ڷ..T Q֧:W~b>]`YDFE# }̝UVv*a9b5+(ZI.cPxc_Z6`}D bӲΔQtĤri00`pI'].g1 9lga[涇M@L_x_C:25aVpn:.W]r>- #CRjgڳFƄx Nt9+KoSQ1!ݎ1b :(_6\Q\t2FrKt,3U",ƙRb!]_-sU,RbiznSKo ip}A52{VjY'L(P&>ѮD<&W?ʥ"~Zh(u"QAE|T$겠T -!ǘFb'z/N9p{)X@(tG!;hĎhe{OvQ%Gp52Tn&ڊM^nEh Zܺ:ʥ[]D!ο׻҃h~L ckF: EVW=xч zH!'dTy4O—&zDg-Nfgi5l*&3w"ޱ"KJ EUpCM`b1mf_4 }ӕ8C} LjN ռRe$[g!* ȵ{Cz0UI+ EO ol0&b 9m W@mD堠ͣZ (x]"#'$1НiUqbI]>(mOz@ԤY>RECw&+8s:m R)PWl RDz= OofGћmUDW3zތvlX4@U$ND5$9/C - ZT"Xzo:4Z ԇS*τ 묢 -aœ͇р[ HbB! "Ye$p r4u.Kf8Uq"#[8&|TnRQݢS{հ) )RrLI&=fzId7I)Jbii8V ZŠYv(F0g]EBi1ͪ!2 ?4r2 y(w"<CX)tN\h_gufmJ>Li;́tC$^2ڸnV]3M"Gd(a"\ذJLK<[n:gE^xeuMxl;,P4Io8I-#`ԉ+,nTYuqVf_Vu3qb~96t:.2ԑ==.4 ,6j7YQevqt^xDvY@Rrcmnr}iv1. -ņ B1$rW\S\wy$Zzٶ;[݌g$Z#C`]PrmoEvAgR7JӷX/|:%n,?]U&ɸ;ЇT"jN`r8-p_.DE8ZIr8v  D݄^f̈KDK-p4ՇK3eK6aiRo+{>[;KxA\ީ5FE:`22Qkcl62M_FUrZ1}'k7%v_? \Ħ 0֕p!ѷyMnUqq;n4{tf4iPKX~jB_,>,'U놆ZN];0tЕ+H)ga?(-FݷZA=w}0g`#81>& c<)\fp͆ !!lKhQe(Y٬zouK$kfoZP2=:bo,, np1O=xn8"j4$u]s@C%щ aZFfZ߲~x7\ x/I,EO -:c_3j6]7_z=? \$z(ELK-H9}CAK S>d#-b R!n>ܳKCmҾ~Vd~j?.[ ->™N&+ cX+]-că1|v/Piκ淐 qܗ=&z]vX "+eZN_$^3v gx.>``@ه8aA8?aovO:p갷2,VIUGR}w![59Y?gX\y;tZs pb9i2t/wNJ\Eka '5ߝwO -G^Sqϣy{gܖ}@:]ֆEO -q,Ԝޘ>͆sH1JPkṉhxĔQΰy$[18 c4xsh;6Ƃe=}$45`_7Wʣ65cU`15@zAhuެW 24Iac2&ʔ ڐ}+ m cB -*BOR^>ͻ'xܨ?l)$SV]V} dQ o;tFm}Y+X{%vC)6@Z`;MXH35J? -[*MB-<#0\ea{X#. ÚjW׼ YOq8O9Q]{WHz4 a\^4J&S (Znش1);qEW^P0ǵbRzU޹X/8]gGN"+ӳYY P7Ka ->h? 5YCX9FڦdHLczeeӘ LڼuQ9lVEzq/bP JQ|CA|-+#[8tsWY/FENr֫V#~a,ƘD %%+A:a\+*+e3xnP̸Y2hZBfcN_ThNi,LBb3&M-H( >AW l35r@ͮ*בo R#SUA"xxg?_Bi:>FM ®s$rȁprNᅒA176X+GKg+0hd:<8ɾw˞0lPqsG}StM?C^j\Ndt>`"ڵ( r5H#$R!1 -[c^G~*yXB=;%ұSvSPoI`ݫF -LnݰBCk!`PL|K w5]اـf1Dsmh]#Բ}UrhHkղ02`JJ6a!Z dp6ON"t46J|,*ixnNQ@kX -'/[jU]쨖W@hz|zY1?1Od-,$V1ɀY!wg(+bq{۟Lw4Z1=k(fI\ӡ;W~.Zn-EG>]$0VYRZFW4W2cwơ# n.FV}:{RKx8OZ-K9loMs}kb -6V &йa&WqQI$ume8^[GK7*[!-o>N{V7zpĸ;"6&XT <3R?ajr|[ta(UNPj"qe {+-M%ՙw7LhP!@~`V6tF8h`17]cnÅԱkGU"{#2pO,RKb&5WV98=LmqXEI(;Uw_kگyRǒ6i"Jzbⱇ=(Nx_vIH{ۇqY^>uGPKˠx} 9@#.wY@Vcnd#ST&86^ށoȋ_UGq5ʴTRbkb貜vVdžzEeANO{_yU0*VmT1!ŝ*s:JX=c2J[m4R\z$ Ioyq?G+7uG(Ou;wyq3z^^pCV|h{旞md'J޿68^ O& !נB*$Js 5l>7!ji _OipTHu=2"CH]b -lnܞsPQ^nAj؋P6ؓh5 = OA(뫪Y*WtZNYQR61rTPÈjfTW,-X/iN>Nxo : -Ϩmğ`1\c= -L]_z{YkkA_*I Ua b;T%;ǼGwQbBWQƌN T3 .D%CZou18"1":cϘٻټϲƣm‰O(G4ZR V)ˤKu֯ZZqtʡQ9% NoJg!6_MS k6W.'8'p:ki89_ +"r!<|[Q$yrdC'skFm}sck{dH# hgUx"*նqnQ=R%,Uid&ȶʊflnmrXt3b^d"ɑ -yr_5Ptc L450t|4n,yxY},4TGט\$Y"yj(==LǴsIU&dG*B?ҎEBՔ9VCUaViD6tV1+tM!W1>.[IcMպu[qe1 r8 =brWYefaO+hK6pY9 wsi*Dm. s+jHz :e0hrȚu3W"\Vx4ĥ -!IqS,]Yd$|]\Ji(aMʐB8_x<>q XsESb:|Bh%_}eX]\H@ &\-[5)h /ʄ p ^y΀ZbL'j/nم^18x(,"NbZ3]k^_=hjc62GX@p [hCEZCH_x-۝,Zy&"*~6Ju7&U`o졼[wZnbiG^l3>udP0)+027y|X;[G_YVgc2 -$E$2©01 {npu=l/+Ps 3I>ECCiRƕ$S11; Ț3 ـRem'#^f`=#t՜ 2+M m*fH`zP -P!W# rV2clt6QB;\+;-|vBvp=lB}װ!?Dڕp~>3R|Kղ]>@i{А2Q|1C%CgQo0 sJ=kC1v(ykX%q 2*0;10t^rr<'< ߒ2c0 ޻ǧKuryz0K%Eho+KC3^P|TLK!^4PtX[*R!10%>qx1V K TBYBX,OXD(Rh8(?jb\b`˰-}}2@X8FSM[s cY`bN&4m_=2W 6ᎅ͠ 35%,(\y9uޒV=INN~m˞'8L9e fǰUҹCL p2ƣﷳ$w̜IN?X<4-?랝GKDl!66+$ c$gf \=QO&xW9<3 \15z=Oj8B.V]ꘜ+Y*$ |z&%by%0_<!,͒t"jH #`ML`F{O&bm2}Вݞ5KȀPyNxqzM?'n&KЀI{2C ۵^#l5l("6_}I.*58)*mgj,oO5pO@(.)f`e1Xqv -M/1C rH T۸ҽ500J:wB"d̋0rS,iV+JĉiVSqbH$Lbs'ǖa?RYBZ\i ,uj~b{hYs8tOԻ{\٠1" @43m=_Vwn)U1[@+D#Kn67%Latslsߗ*rT"#ekkǵorrr-BLHpz&Y[," 0KEqGJLB|#/_P؝"?`cGhNU (}5\G#gщniuNŠO^JgcJjx]c⩏omϛ_TU Ĝ<6$ܹD=.WX"EQ(0מ;;y=Äo( -M{ض 㙐=D9X\2#Z+*'UFɭχXX!iz3c-jWk|W`_R{z;?&$o3-5{pӟU2PmopQ(ghRf֨{ ؓҺdҵ.d"*ALU nRar僗;ȂU6xwژ)Sz,ڠGXd㸹{N ٿY.;jl - (0r˺itv>Ua(qKU): -m@Ǧk6^rf*eB -nE1B불a QRkߙUOw^sWxG( 됍U;RM"t5cÇhbnդhabh۫.3F9IOy s/p{E'>1 㟙XDGu}^iX! UDР6!H[/8M\Z,5 EF!  W040 &̍ m7tfRD5> $ˌIS፿|SֵS, d4@[}JJ\B I"JLV-RD -BHfɰx;8**kbPZBZ -͛vNp*B6dg-rE ѡ1!/fnc]@-)::mk]2 %< ,ŠVQ LD![9v uhR>R@ \{QE.c{G ]2!FmZ 4kM=vr(^K}Xԑ;Vjhæ CuzTk\KhOWC'[6}~NOG݂/0Iֆ?m6!xHRt{[ؘMWDk"k?RB4P~5/<*GG#4[Q[74 - kwq?D_x'GHʀw?HzpN;FGwGa&2)By#~@qv+ͥ E`lݓGLBB>Eo8[²[y$щUٗƆ#iz  %!zjse50c |L[FPIMC0զ&#mLe2j姨`|xac P§^ -M:HF~3RemN glktlahIqݨPM$4 -&#Mڌ#s"ҕ4;}OwAR>uxKϣd AT6/;#o2-Y"[(%څ(%͞:ՌK^*ÕU 36܄YE}bY!ю@`Y̨ [@{+7cHqG)>]\KB/+5`=9ο3Re[\ԭ?2H[ýeA~oOw/H UO0M_{[_k&ȟa;t\.;Zhhxㅤ q vpfW|(H#lb3)"牼Npn9Y%"TS1!`8"! MNcndΔxx1S\,xHImH\r{[[il!$RPrmqqoDNtq@]b)ǯ8C -WL=%^c@p`I3f>y 풴lcɕ#B(Xi(cq_RUr֦tʤf(VB\,;`4&vqPE%c!HĽ]uc~b Jȋ!g.6u؄6&pռu!ܮo헌o0%b4Ҵ;r"ZrV,t&)1t_p~"Ït?.,rrhSV4AJDT=ꭿBTfM!w_ݵf肓I_SNBwJMٖVsmlAU!.˂Mt)?.d'L!B '8Ut9OP@iA%[20ø' _+'Kyb1my=7VK'wof#J&O¤~{wJGMls͇4p:ig NWѣƉ9E>>;G=+ D}|ک/'y iN% % vvZԮr㔜'pXE-7,V0"B4`!薧ݐ{]ni`7 S"b|5E3NM,I@P*Kq8v2 8)v-c+C}Ѱ0,q|>,|F`MY.:d3j~PUL }Vr /[}Z=r"SǢ ~95fHϷ=㩰ZIcԏ -B:?`79Ȱw.Fi$qnM7pm`~$z -!C0zOY[Aܗ@:Sq,~ -~h9j9a)S'%XK6<7V~z#_m7ENyS- VvĻo|9s}RrXd/& ^&X  _4be ,J9K)DLP6w;%S / -RoL<)Jܒ(lX Y!s:0Nv!? ߾k4<6j?~VԏT[VѨ״_gYPs.Xvn(NCOaKjp=0c({Rzͣ -k5Dm`F}]sr!VѠvtӥM!i }XV!3}'eLb6#MeB 42[8əTH'(r%fS/ -omD|dsة_qVC;6Znb;p`* ûtpdNӔLcHoνd9&UH AAjE[vrU:@&lazdw)<*5eR:69# S g7/A |[m%lz! ^"Ejw$vIb=Rl<2 t> )3NKf 2[6U+CEƠ@bs(CRЮई0֏_!R[z-E% @`n `JLWTm3r|Ay%sԙm7Ye{NAσk;x )/MK; ڟy< Pgp$wV89.*w\m:; -IN~n,25;=KR3Xmy}{WE"M C{+!Ŵgn;3N#|}p\)͞7c\& GuqU`rPli c]i_揄>Ddt eLlݛ>Ž]"^q~JwfLDLBkq m&A^@bTeRP{ u*Sׯ)]zblz[]z+ -?,q.C<ǦM\0yz |0E8Qt؉ Ǐ3!M9;|94Y+0 jkU[7V?$ șc'd6bC$b_M=rP.,d}:mBy4`K0Sz7 U[x͠J u -!dVj>uȴ\xzeعx=moVDƐFk.it]jNР03cfwL!f`N5PɁh9-%'fLVP DՓ5,nvS(l[ ќ1f -Υ/qAED5ulUMeX h)~& 5e޹G}D<뽡vFOג'ݐUd "4Q!:OoR=Y.JRɅ|BdLATs -t:6we"@JoPjs|_H `fy=z.K5 YN:fj/LI/${44~}wE(>Q{X40[<0\W#á̙.j۟9au 5>U0hljKlj*e>dL:v2AqH-U7n/嘢W*sg'3uUכհA.*SvM6-)ٔZ Rr&J|&BX6R ctB?pfn("${saˊYYEcG=)q5j-5 -ԯ#a0/|Vr1[A?rUA]/ZȘ6'qb]DЯ/koPmP ޱ2Sp1񥕈f< @5PoOnjȘuc -ڶG"3/ߨ+ ۝)hwŬIC{f\uU.Lf (9Z9aoO[QTi IeWT4rG-t/9O*vhJwȐ6.zAspb=N>Ո ˫;j!>NSh9Ipp ߌU/ܬMƫڴDg>M\*`!W(築Bm(<,- _ DX]!`ĮrG\I.38J|@tjyFD8y=JxEd\"'iZ~;{(³4b -W4, :Ca;2b;MoFӸҳq55Xuܵ3#ۖeOE%=9byV?AY+*62ft7-6E eX>=m~_,mBI8eSbW/ъ!_C kz)cU؊=Ц8J ω+i:[Hjȹqә~Ro\Vtg=CLw{$C&8CUHqPo٬Ͱ'vuƯj[BC$odkb`7#U>1{[Q̹PP}zcbA(o9W^ %W?M&UϦexOpH61_|gZL>4 tYEE4*FdBꍤr_WtP};q;O{$D5uOVxTLf <@Nc_v 煺#csHt2jc\˙x$BQV;%"xbeĚ}'&4KҹEEmɴ܅k.v2>~w/Z  ehh})yrB6LhjR*~̦x{SH)_t' X2BQXx"Q?G|,wt*$==ْm`0]R   -MSB>O3<'w?L5ɵjyMZ7ŕ;!R9mCyXXpZGsAA=@a02)с,Uriah/d0# ̨g}>Z؋$i܍O՗BqN-6rknV63YEZ{MQi8~"Mbs(`*8NDINLtzNT -wQ[C׸`q4`/q}P T$&ЕD_ʷ~|]iIV+ݱ'_/3At8y1DfqInKћ}i.s.revV: ܊N%em"DӁ<|a שf1D _֎3ˆ赃ɀ 0&6*wl -Ϸ BŻ0$LpecyH'14rǝb6\(fz5;Дru_`Êe@ʹIl %O%F&ǖsIɹl5anvs1Qf@"ɖMꀐG;sf`.ŗ -Hjܜt9ɝZ@ m+%dV'b4WtY+0dɂHh8q0LJXKd9)87rӢu@O/?3WNt1, bE 3#J{AV@쳿6?nUx"CV) Ods򴼙 6Rk̬[E9A%oAe- '3CqnАY_κTptOg}),T*C2P6d>E)?,9r&ꬿ28nu#xzD~`^(\ӲywxE6ɴ!R)I8 -ީHNsX{!Y{Gf&}*aa!»"8?o*䨔&z2@/NϩerGip^34 |_]aUfOX{`PGIN?U­D,z|V_ -1]5wv4 -go Ƥtc E*}\NZxx#`੘M& d$D;Ӊڔt*^7RǗуdLmTA pXinO? ؜(q_6wW9%rF] D7}qI[lCLmOa fڍFM" 03FP!xQ יry`RSB|nzܐe\Q=Tq<=X6*)st٣D\$Qf'wi)ҫ̐U k V !PYbd7̟C-&b 'sՔ'++h#heFOki`9#E1tU0it57/iBG,vq/ÝF7JҊ? 9w9g=i.'65AqT4]_HR Foɽ:nhs wΐqs}bĮh!Uh=+;tA& (7.++ `NiCFXC?Z xj  Ļ TX.m $hHvSÁvS2B8  (cNWc~͆; &Y;+s |V# Ш=Ƅhji;v 5,B/-eTk(i.tN '9©M'E]-[Ge_tB̦ӁiIr]M#/\Ô$ ꘨*JMS;dY `: -Q3Ek<vS_\Ȣ(2AvC&bar3_Oeͭmm~l0W3pjzAsRte?o6 -z獃ưUK3|NK~Օ=d9W'mTދ0XXN]lfheYDFƉ/hvCp5C`:h-FrTjz-ҖM,\PiDV_D)ǯw|qP65X߯Ձw拎,dQ讧h^]s|KQT9+5:Qf^ _Fw0fwhp>|ِs9fz@BwKKR2qGڗ;`Mt^SyPrϢAs18?#W - -AdہYU#U%~nZe- ht(Q`Jh;|x'-y \0V^16WGϰ8%-{%3-y2"|gL)4.sh aۈpge%h$I޻XtMbVo~ĸ"o4suaˤLз:J1\rޅ:Pg?+yf7W,;%5"l.K }n F"SᵍpDC&=V1e[~E^G&ߍ^Nn :pɅ5&k@MIۊ>\!InMQ&6Rc'ހ/)" -+gQQe%.(ngM -նK&e}hFJg^Š6Qiꚦ>ȸ]qs k1`x@FʎaȔ .(M(|9Z"RF T hŧCF 8rhluZٷAc.u<'v3-PUq?G5wsx`CZj: -e $wWJp$,OhVBYwg? o5b7 W@8C~c73 VȑtE~l$d(φnA"yN UY-ME4y3k7.Z)tNn$)X8{ Z-j of]܃p[IQlWʱ#9\/5O@_5#Ӂfr*!!*b5Ʒ쇦uVm+}a0&,c5@.z<)5~PL\5:xP 6v8@ 0R&PTzT6U&_/|o}е)ˠUKq0$ тrH$@X x8+I}=J,RHk`Ҡ&osm l3vLq'K} {<9 wʁLL?&~\j5e$h߮]N -GaB9oՅvH6i) (Aɪ4v)s7D/v- ңea,МQHcɤ-;m_h`xjW?F>M.٫DDV"aBa#Rr/,}[C+ɕϮlπ=: -7ShZ?U}.=(ٚJ -$/_=I=|z\6ZzcR ?E‡mr'bU;!,z rG7cnmEP8pC2\w>ʙ֖W;Sv< 蠗7t:B8V&Qek dߟ>/L$2X-ɸ cjVT{e7PI/6&yX{m ڑ6@tAK[i$+1`2o<4A=$$ie%`"0t$Mg ؇@PcsƊ.RE`Xv=v0Ox )MK(Ƙ)CΊDƎd ?kڼlaX 0eu}7  5)j}+A"tgMZ g"dJ'/I .ޚ q(0֑%y _ͫ~Y8$֠ڂ}~i2(l  KwG)YK;ڃbXڗ(F\D5M .?1Sq։C`Vԁ8EW-%uK4,WUL< "_D_7Lu:EԄ - PHOY7sOPx%A0Xdr#EPw﵊Ԥ:-Z U`QA) -T0^6:t/= Ҭ2Mw;irk]f9] 0b1yl9" dh< )kYx!zjCYlA@iD763GSf)/&㔿Y#TVt klh3_&b+엲 ̿5.װb@W>kJ62 @*ϝpH11DG64vq$B) - -쵞YMϮ/nY8Xtg/7FzۣE7o!V'/\bXDr ."X;w#6Q) Iѵib}Grͫ2".NbߛqG6`0-KȲ~mf0N f,\ItH1؜W,b+Xka|9.v7`JU8Lȓe]1\#Վy [X?xf.#e4hnx@0E$Pf5=QsdUB}j&x%r/ԩ}-&C2ԁ De!K , T=_`h⻎B4gLa j~E/…~ʤ6R2BSrf ǟ$S -]@H!vG9-OVv8j-)seun~:\| USIlJ+(I1H/z{<qF/;Yw6cBc&Š@Z8z&5&Dɿ 5F3z˚m*  3rix,rᅞv2%]~)#qI|I9LZ^az]Ǻ|qv6U'RZ$g6O;-"x)$onѥM/g8]p8B;+sf TOb5$GuF1 ߪ955n$NvcUQ`.oTLp&vhPbxY^I e*u.{4t@dmA\aĹ't~`/6fV[Bq:1zVq0@%]TQpZ8hF7odg"MTk:aNZw mUn CW&/xOtԫ< bbF ^-B]~BS3ϯVG4d u,%&m|۽:7 jWv~E>64SE03=|Tg- '.34("%CU }QG K@韸F_N 'Ƃu$F0MӋj#kvn@I);nz9ZvMGvN9!b˴up(]W`=#r)s!SGc#JuEA<킵C]YiyA?.s"D,N=}Q].$Nh@솹I W2!t&8A3 "1:zniB}GΝwf94Mk!* *D5r62Cz|R_<^o#q}|)#/˵,V䑁g (XiUJVu]-?;|#s+ b b˧ -^9n_#FX4zg݊&*5 Xyjzk^-Obbbw\ƀ%e -nkPHD;bIi5)HgGVkVk -SZ2z\::p>^L& fN*l?q 8&d@ \͎'w!ތl&|rˎ|8S uQiJںFÕn}Э+f6ps3EqZmM%Z28\vpճlNV]ƣV!/u ҳS7a͆?=_u-؁1أ72(('X@b^#^UU.;Q? c]J1/ D/Ӟ3:V+ 1H ͫ)jO} %O_d1_(:À] J|e{K&^ -Pl2Wؒ)]6$]DrsNJYL{=-WάO (FAi%ؐ0ٺ4@mvP C^)#Lyzg@aO |/O&R&qװC)4L"n,MEПn_E^< g@iB26 \+ީ%fGhR{]ת>ʪb 6(nfq.* S!jE++iwXbD]K 77rAYe* 3 `tO5̦/G`- -N#nZ֢^.b%P焱gO5pcb#kL -bAoȋ!hE x{J8J/-ax!4͑ % -#q.zC>&Pn1鑰j$իjLGf!}puLS6eibP [ 0=p=fYӥ)OO#on$A( ZƴK'>/*p t.8XT݀&ʼn.V(=}k9j!s7d;# d9Lꀿ 0g -oEED9NN[1dP("2H>hӨfΑvbO1 }&j.bZwNAb@bS`5Dg@b14:n@zwZHmcNf@5^I|^@H2p=ׅ}|Z=QWjoN(eҰrd# -dk1C,aFm2h0s~1^Ə~PGD"c;ҠP7.q(I-b魀5y68!0a6g@} EPj]摠Zqn+"N@¯a)tV cTyߕJtGY]_Q{3"֗u{ֲ%Vf8f|+BY.F5[}+h2$Sע$Ng"bQ6LqV0i:cMLJ\B[WdWteq7٤dP2h(6^,.{2#JrzۮVTW!WXd T uAmM̒w{d&X5?%5z:'zN#C#ܼqu4JtķHSOn< >GQEaP&}#iHƷ -E]E3T7#X*jzKgtsbA؎K8`ap -&4 rǧH6qCCaSО$eU&9Cܝ!riQybb䢴q!C6ӸW :S9gkڃ7CZ"#'ܤL0"9筷 -e"K$3 ~8K`HKH2?#T\"-F):pyybBl+'ˀwr1>g/j2C7CS 79VrO] c0^X?u^+j7g'cKl;$B@rn{$^+GPE3̙hK 6=q{-_q|RD19Pvz];r5/`N~@ sVZmKf9fk*:p̗7R[Fc\}OcLgɒ9^~.+ϝف -SQ5Dw~&ޒ#5v(%4HzWV$)}ߎp. Hd]iDC-K+XW aQ \0erc|DT*9ZsPC@ЭGY=8T]ߠdV\iVkA=$OmkJ%cyIvS&kb6W|ēPJܽVp"1T>yIJ-Hu'sjZjk[Ί* rRތG :yK)Hט}# d#,Z-mGoS'KܕUcX -sK4ֳCd:ƚb߃MRb<{K` Avw@ W"|}=ONU`Ӱ54.zݟ+gN3k<F)aTHțX/-gSY_Cka"q^ p悉܇>oE{QSU>cJksJpfolzF8qek:-eH.&/~opE|8ݎQhF!58XȊiԥ^8G4EHwn5 9/Oh MOK-Z_xZ=﹉@3 SWe( ![(E^a{{$%Q8Z2o3!8hk}Ar+]vGjs%r5x$~B' -Ze'yEO֊dc(kSζۆ){")YEm^u_u#ӻ4A9@bFK40g}>Ñ z-F" qCD]&qȧ3q.'TŹs !S]6aU0U@&cIЬdK ػaT`dA3(RC#r<>ҝBe"1 -*qEbPc7=њA`YCu'cZ":LKmU}>q|Ա"3fC iHlV.!V›[/d8/x'!}oa 9 - X"fVlx4 7T$ q)V -uq @'-;\꣡AGpkyA@L0 uq0/E;2D"xgFaO+)[=1#+42@Wi` 0hmz9Pz1N-'%;:ayrp5%B/uTbx.@tnɼ[/=#zM1QyС0ޭYH70"k)` ü"kD)`-'b8x"X&~+%$W<ҙ>KSܚa KT)OhW- l4jVa}젯<v¡ LY^N!B樂?$AlP$+~Wˈ/ cs}6 ,v;/HJE#&!j͓,"ȑ>f7BJQYP%feY%Df-иu=05X .0L:4BkscĤ=[=Yn}ǚeӥDہ;6衤oJܝ~J{n<+U)B~)s\yS"Q8ddPFE C0Fϒz)J_}toI -e(ޫQM5;IwݦRi(Op2ju/H:k9xL^^/ah)>U{Ө۲Nx[K H2Czs{[7&~ڞXf*v&g,v -W~$k½Ud 4\,odh -'%|ygFRCG$~k4_b]WD+}Fo, -IbRWVŸ!8N 7 Ha"˧}aT D6FEIHO4v@5-ҲNzq+&,#4{3 Ȗ82F&xy`4J' -sTDh:'0gkD#.99Z9[s*Ȕ -缁#%YNj^rv:<2aw X8c"wDCܾzR]Pc(*O o4}CߪM(`MJ!<Zp7)ȋٟ`fd{<ISMYk%MmfS~seCҶi؏վEAAC9QO0k֜Z*Y#h" 6@5,RHs"TV%9'f=д\͚jWV'dN7fK QP3K֟;niyA6y४oRv+xKxY[1sLݔjn 6*զz`/32``YR -t@ X%/Ex- l#QIh>o(X<ڦ_<؁]Ý-,1*}_賀LXDz$2fSĔaS+iTK)̜^: T?z=#/L)yHH&i7 /܂wF%v=ъ("Ct 0y`V`K>_Ϛ{;dzL" y4 ~1W8/=Is׸+s\+vLE(wb=3A"|٩HrYa2J{mTДBJX,6ڻhG<^\FO -1H]@q9{xB 1b@o03H+N#^h>6k +hM> /md”2F _p:f{oϦJaw3XSEdX+[@qխEiW -HMXF˱fG]4ͧ CxsRUA  /˭9g<1`F_2I{R [L׷lf]FCQ]|H8yb1= _ti Únu!.Lq=-(S;]MjtQ46^,Eܗ+d!kW;#(;Nlx<o+(ݰe-lG: ->I~PShVFn]k;6<.jB SM ]ı"2w-8osFt 2q!jĕ -IFŗ:B9`2' Zū&%6Jr;T*^BA6ux-T=CE~ Ys~gIG yTD?4L^ސyW! -s,! Z88pnm4IrWZlB|^اX-HqwjtnM +0ެ@5]3bVZs$mL7A-޻rO1k.}L?8or+\)z(3}%2R,o+QR0f):A0 ;s vG4]QëUqp -DC)s3p0\#ٱ3 /@, -[xԁ"Ǝ[$HzvƯ#!7SUv`n`g䧒]#7%Φ<-6bt|>>h=0pboG%.n;Wrꇫ,cVrI`Q[xNA9Ri!_̱{kRqgR`? .U 7Rǝ1ܱ~Z5R) A YOݱ43ԑߡC! "Tʈc\nqpoyȀ Rf(v6$kUm.2D -7;^g/)#qdϐ@^Bm),ۧ]%;dd= -b$$-t[23ey&!*2-lJuXNͲexD}n뎭Aȧ2§:ֻN~䓧X .|8%AȵJ+xyZ+#TĿ=`T.2lH% k$]_>C.75T6%JcC~79L -/-o.0[9:Q%yY6Ov=2c`q5@N\"d&# 2lr TZR:f al3a| ?nfebER( e!ŊfR7wp nIHo\jڌtcx ٷ;h|,OJ* 9#4ga]"5غNm.w"Lp>K#Z˨%PɾwW{:pjr  QSxY"ҹ>n$Kz?I$y, -hnJlˌ4JVqf*!n1)˰SF yuay{ҨQմ@Qg jJa.|ਭE~cJNA_Gn8@j'(1,z?{<7<%&gϑh"֑ -ay6T>P˕9ok͢0 -esl]Qt9O8R9v .cũZ3&\9lp" -'d aJ+/칶/350f1kG8p1 P^s(稇͜`əCX:_*WG1@(>Dp,T@蒫{K`f"%H*F.':b#/60dYJ2YXf :A*k6\Zk]@_Wo.}d_҇MO*o( ejpt P1R|?m#ѯ<,nG?7ÄnaSpy =p\`N3bǂ:5o n3vqkv64j.F\>ā`M]OI⦿zI$S"Z*t"#NA*fJ$T8~}Wj$qujc%㦵I n!Qbsu;=iK(YeBTB3 -r,1*1I-LFa)GY YC7qpg^.g}K L W;ʙO+*3R2P'BDs -]ޟ -#&LKތ@ѸIB/(g롺n#L5EF+FmQ }-#2S1P0PI Kb@o**/[3% -EΨ %lIP 2=P\4„&/ϹaeᚽTg`Y&̇RjA;bTCw546@ pHᩅ׈/5#[:ZUŒYsq<*J1;M(s s/h^7.z# AUZTQr-ZÂ_+[;DT5#=ş)kf&e&hÑPD/y!߳ N -~\(;DBqXUSURf2z^A@_:5YeB-t~tISCHHIdlȵYNĪ,7‹Ψ*1eT(sc\rqZU![-MCޫ3o4rWʟ DA:dJ (\ڠqfsKf0.D QZ"4$Bf(JʐrihHV"շaK k>tOʞu#N]>R*^AD|&/eFcJVxIX - ^O@dC؟*PD8N1<:NN4\U `QՃEd5`<.82VhTC cdCTQBQHBV rK'ͦZ8TgMԏhj:M", dR"aDJBs!EbBS*BHx!Ӱ{&L kgTDE?,MF'e؍@ E>6*y1dђP-rs -TCU1BƊHH ;,VIp`% @jhh@w}p "ɠ\4AX2`؀ '@ T jY5dUhBc&a*U:Dg+&cCqgDA[qhHJLe]&%42ڀ2!}jڀ -6~Ak-%#:e8 3 1ڠ.†6r&lhhC6"ja~߄)WNs5,p+ ߠ‹D0i8Tldb~ZDjjΜ0qu!^rHLkL@rYhj 23%1V@kR]6 t>hju\hr29 1:CuC)X :J,ZÐeGbXHbUB-(hh P]CHHV0ES0BJ#齣0Q2R^h"DS͟oNЍd0 y$| ̈́o{y)#Cz:I`1*Ё4Vy18R̬L=5I V[PFWZ)ŲͤUܖY$L#2 syhxnj* A2.CB.cypJg 7*X25vB=DL MAdLjNuK\Կj*l*WNȸ,/j4jF|I?U[3IRڂ1h6P {In'e9)1z^Bf -d+Ț*AC&aQj,}JdȲ}USׄ03/w `j%(#<Y/T"iB&V/A3~XD+N$&UpVy*jjL*Q(ˆlES+T8D&3P ]\! q1Iph=LމSu %u*wUSKĔAVIO~Ih9CI"Qby;Yxeѱ4$^4X -ۂ=QxLXPO EK$4F5=O [8v2]!l_J?02 !ү8||lѱj_B'X M zvPjH  %&XDu Nu4GMCCxa,q:'-H̓ER:.?JHFTqꜬz" -])-crȼHvDI(fk2 ~BK%:lHRJ*PHg:BlB!%oGDcZYP(dhQc6p]>i(ggD:1HǙ1a:]W0#OYJJ'˜ʴp %BX_Ψ(&`qY)lXˆ Fӏ"UsRܳx,stkhh$G$J:MF"6!MȎbP# H=}U}45M! 7kFlx9&+i$qM{Ժq8ɐ(x\L0*CV4{Aٜ#/:ESjf#zfu?W*%~ B -h-W[(ZZCF 2YbD%QXNG\ R"zz1cCD9"ORU !˄D̿4EuLwњ7J#,bY,BйEIEu*<)yX93!SV -cKL$,!DS]()h!`FʉD=[a/T*TDQREٌpI_D(]xX|"zbGh?b3,;5nTӡS7U&TVqj3@Q5x-1 -2d T-(QG*҄ w -*'h: k‰j$Gtu݂@ "#8޳0gKL#XjѩSHaG)FƱWg&Ҷ6MM@'=t|O=IvxЧZt=EY+aX$XEC?fjU,k )x-_(ƴ0aL!18bC. !I19Tu2/.V|:b"82Ɯhc©͎9Em(_,,{Uu<]n@F$K妄 Q*><&Ds,^n&|P x|0(rDZB֢ p\؟@#)"#Xtlůa bR Ў]hJ&%J%AՉ -ME>eEh^Py= -Zܙ6%3qdahvhSpȾ"PkeZw%"(Z?e!ZI,E -6oxg%0pՐא4d36MtZQ5!!?"b3E6%IMJ$& Ӫ,s4Ҹ5 -V22YAplRMRSF \q@͓_+/(X(C\.6eZ1AT6UƕXa(Jκ;&#&0=?3,1h;˜N"? S -Td1CA"ٔ"R)DžNQcch:xZ+~D:;Lv'zO1C4ATTf+$S1Tp͓Q0AD`E$FB1\1 -s"erF>E^VUKc2뇈94u*ǡނ&'11 qWhTpՈD -n{HH]EFUCa) -$uDCH,Jod" -qҔT"ƒ#h@[񹴅!?%#kHpv}È-;DAHDHFU:_qz*Ƣq+84PЌPp¹pdF-:^ -$YJ"hOzм)gRQe)Wփy2N%$S!%{!DTKaJS$ޘu) -UsQ7?Mi*ȤB ț_Ra>7lZ5adSNM5-XQTM3<-xGU-i7}9^x!Ѣ*VM䗐:bp -щÍK)@ʣPA䥢 +K$!RT̂OY@1ˆeh~Vc=°}$VݍKF&Fj|UB QP)d8KTPDDUcK<5f)?""w|rfjr<-ATQf)nk!DEU($# 2Iۣb|OsW}5 /vm E+ԪGQ|h4+DBчfd:Q'"gc G'e48y -lBBV [|aGm(6^a󚪢 - ï"mSĂ~ TR+ME$) obb7 $痢0Bhà*$vf - "헡Y0£2? CN 䎡3V,a:F T}D8bf\i(>ّmFw߅ IRڄ@|YGQ^Fكn_ q0QeڋAf^x%I]eb̐,4d!eNBV -L5cwAFVE$lm,of+Rd1BT2[)$bFuQ6."8gQ4= c3ddM4v -=Z₋BSgG!XTU Uh+mIdDa\*8Ab7T"cB2/&jZahAdX=hXA%1Hny[Iø18NXU/76FWLՈ#QE} -,jm -ĩfVQ ;&K pxb Y"JhR$"к-AH}Q.i[.̸&FW@{MMxXHhv"wd^G-"<7?q #1!t"Pzbe_nPρ)*Q%oSѵ/#G&CPxtL I2A)(! -qDG=Z t?T(&ĝTCd>lf,[QiU-!WxG5QVK5L($Za$1 &1 rO?%2 Ut58CUNRŁ #4,W CP( Ń!Z9$)d 2 7u"JW0s)/Uݷ />Fۉ )dYS NXцGz- R -(@&f:foq%ڑ?fu؂ƂA4obhYE`͢ {H#&06j*T04$HVAðbƪƲ\jw [韸 ,”iE>8 RũUThs+'&'[ -lT$^ d=F]x/>stream -ЕE R%N ՚aYד2/ df$mF/(8'l}RObl&P?ۻ\q TA;R TP*7 +bYa)AP4Q|pt,󤉎wIs0tI5mOg^R)"gIcӃmfE$ WQ.&\t;]s N<)9TRwX̂8X)&}__~p6HA$?}\BxL-%ӂ[zUa-mn%IVlKgYɝʄTS #PH8 u c|2 -C=P2FjIvv;)oGEzlc $FtgC@BmY/:C:.Hxtס@Ve!faL(n2̫:D;m@x4t,:OK-$z!wO#C f_D2i}E=iz%Z$"{b;q Ib=C)He9|B?[qy<;ˊ5_=-?J&@6fK&5!sgG'MjlH- -<%:uqiSoR41xg3p@l'7V{*0 r>5xm -Z(ژ.PƗŕ=#nKr dXeg oWpS*u'mx%`TSH_kk,Z5-'9ܣA Lџ;C:\$@NQ:NZ SsxJ<3 -E;Q6dF,$mp `ku7I2U(M (_ffꭑkNvW֪34a DiJ:jD6DMĹ.!uD࠴QKIð'UytlGkUá!.Jhf<|7N2Qkָwͯa^mpiHN yޫgԞ;M[.+/(Faς.7z؃U\lfOYHr l` -f! WcԗH-,Dm=xM.w(da%<*^YN ΫR-:v&^|\D~%%rBφkw8"jgލMOF)cF%ތΝQcGwG콎S4x= =C(Ѫ9RzautNCYƞ+N *&\_1`Q߀45aL*F' N$?`z1%߯c5k_Iŕ+"vSQU;/`raGlhfJ -#uN -"gͩloǦN AkIVUh1ytmN,rĎ" ltb# B+aR/׾Sxε>(3qۂ_P1Vj#DQWxl_a&1Ȇ2+U1hC]}U+wtM:1=\pb9#Lje[u˿G>-[}fbRHn4EVs* -*u|{Cp}:Q,Я; -}P OM^-X,Wp!5?T}&)M^ -ֈ|T{؃GK+[ 4M:z8u6bgJ&<2E2AJAFT@< ^9HBG2쎾%#/=Eǧ.ch|8 j 3- N8q"kHKLSt(m9C&\Lda8Ej}kz0\]& ǝ왵hmD};V]X~iͷP=9|8S(;T}P>[K/V]516!& -% YP ECC:WxlGdEc[w)P碃?{U -IuTm 6C6r cTa<4 Nrr}g'Gn2k^BU¬$+r &=11XQR_!,D[i7yyڜm#vSW1TMF#%S+eT.1E/\61 odKwEΛ<ಙ$1qjɴR-YirA: h㼁#AҀ:+1[|D (7^Jmk.1 -3i(2|t8hMMzy]з}JY]ޕ2_@fbƲ__*cG#Z)hhMd]-76]~y&)6R6P -젼]JrZS?=j@]p --#^^f&#BgH;LE' j@K༝!sƓ͇ӪP,g|y 9?|Lw^A'De@ՠ Hzb=dGpX2۲okmT/rqL]]}n(3*.,#X6 |]8R[P*!`;Cw3f(iq9dYzGyҺ<'673#*>@l[܌ jba 0aڄa'Z?̑KEY t8gW %Vj2a3~}seӍu܃WXkdIchfţJ%]YaBa1 -A$̒l/X6g"; 0{b7AZ"DC~B reJX =R3U.}if( n|Ԑ+bsegb2Ɉ)ܔrgrm;'4u];NLp3H9FyY>A<r+ ՏB$6;~*tW" FLX(xRxsį]{ez]Pj7[}RWEaHD0 ug9!^a=俞~[ɶf'5+%`[v@Mp퍁eWKZ:w_&@dR1oG:'%2rش;HAbx%C,HW>qeBm4aKi J-Y^\yRx_ʮŽZ۰F1_zzߏEqlt8k -. +vZ:U_}$U'S&5VZ9Hགk.? ?^ y@3HQiHff*5 -½):ôSM 5*%ܸf#IbzHa,yY O(njK!yx4 V4\~QoW/&HR-VQ׻z).5>#)xߌ?x#)p`.!S^ B"wܲC om"ٍvm=ED N?pT5Hy)W7U 4钻2pV%fO'՛o -f7xEij2Oγe$Tt&޶*wx `u/ -`'D}-"Ihsp,n 2;. JB~Gx4A;3I(:F͛BW [fB Ѻjd.Q d -]!mG\{ ˱~=>ˆF=\3x4g?2guT^l,3DtL: DQ-w3' ˪؜V"&sz!~\ır̸V*00zkmw-,3SsfU 9CIrn "Lmfi{co˺7clPB׶dVzLP)jaICp_O U6EA;}[TANFZ91[ը#: oPB1yуUePv f I0P+1\NR]`^Pz=5)kQK$Cn".uHHDd<έ5ܸٶJɂRBDWO9 4(o[ux{r׃p`SPmbODޒ;9csQ׸]h5Ҝ!, -tID Bn1e -&ǟψF!D6#g`?O=Hg㿗OߖvФA+\3:KwDض.s񘜁>N qi${3#d|]:2,l"1"+N(6(ElK_J^ƶl%>u =xw;PT#3Ւǡ־Kb>5e1D]<4hapufCt%/7]c󠪽z_ʯS]8bZU8]5=vg&$ -ѐТz:u`,?X($j*1c8j6GGV}%v{:蹎Av#z^{`2wR#,Y4,?ne M!]#N 3g{pN՛#UN;+^xuFNdo>t@Ya}T$j4*N4H ~25=&L?m9cdzaK@+TFƍf 9DT$X`;^~f R3a]!*v,׿?ϑh̜AchUn9@3ˡ  TH؛\P`{w9ڿ3d!/]vɡ4d=ѽw'YKiJVdY1ħ+c#a -@*\oNzQnasO~2ZtWӕ #T3.;EXNYNli%T ݯ0"$^TNF KW0b<-"YЎlP%U4UK;o~6JHg q(;2l,GȊڛ -yǒa|*|mÿk춛rBE[YH\O; #3x;uFY&A}kFHn&;.ɟ&JK#>YYW޷$!?{p8rA*b5V_m. -9jm%z/v+TbϜ< r3tb(s5<2TmwM;UPD`s暮h}آbI,}gss}d2Pđ>Qm&:KnW4@D*MV1 -0%dQ\, 1Ç>qAt?1vpE59yomeôy֘ti&wPm5w -=Å2~$/&K)0NP' _`+k L"kF/#d7".TAͥ=R玂%O=`9^UD&["GB"ҰFWaKw.G=bvFĘ' -~Hg3HPnbiIYB8%V-̴dCP]@Uv<5"S+#P8Xaђe)loSO[o;\IM}K*\lhY9;IBmS;D{qf61}sF$L98"0 =Xp)z(ߩ{]Ux&GK2?F$-]Oi?nm4 '5'E=0\+* N{ev@<_3&+81pϋ@kBd_Yd^MGթO/~9zKyElG@e/G??#ݵ'3v/SNѮ'ݲo~%8733UЊ ?9Q)br9O_I"=B)~}Nx_fɟh<*v=4wrJPs~*x 1pxB b*w*&N٥N=?n;K:MycyYIGhKǚs0Au8XZuv3Y j ;jT Zwp1o,B$BQi.Eմ=5wuuY҂2c@j ֏Es5.K`6\O3CK#;{;c#yFGq@+Sb`A@F4 "prvAsauKWud4ީ`@Iza2fzmTt k뒘^zYOyFm޼0ZaߝZxfKhK -W1ݪ]|W:F\Έ"6}9Sdء9:Y:y#=!q\M*Q9Ȟ0hQ,TwlNzD90Ox0g. 6Td -05t_3 'F!'@ 1YÃ>};Z9>RG}6] 6.\ibcXV[tlY=pKLN*~jWU/fRd>봧:#]EpgHpPOE4;QciD!`5 8 hIK)JhU]7{E58k.=C<]wcŇMyJJeê4kOuMis7$Nݹnś⫴7G1*4nCn4%Z8~Wt[s2B<ytmx.TqX 7x'*=]2T:C>K*d[xc[ eKHlj0w+O_H IegSG -4D"cc`)Mcp*Cذrn `EpoG֑׻Ք:ӥ7I~c ev )U!l=WEцGz\m3fsl{@HI!1FY& |͇_L L~%9Gjt!Γ˅FEiGKCk~k:q#5?idH#2"C3)_35iuΚ&5z#K%I8H& 4nsVV"Zn -WP.!s~n6h=p7 +D\nl7kyU<f duC6=|4j5#8i -=1*5wF r>":*C$qh7F\EZ At6GO[);>dW*%wl//bw!ۉiSY PaKXP) +&qΰM})Fk(7NK0n_MA'b`8B\^;9a"\_B[t5b?^@Ib]4D&ؤ[D0YsKU4km;C 1g٘rs -"LDf̏Z4D*J -ڻc ԩdEH8o)^\T~fW@U*LIZ;=@4Tw,\p@DBD-wpmΫ~H髸W']QWzoH%xڇ&N'Ɉ -c(\x!>@0kEEu~V ;$?cc7zrv;>ȴ= -A_Cی(tɤZ>FW Y!\/y5I@: )HU~Z<$;J=xM*gx/^ C.WdmhmT8 ҰKX,'utzD߀e>uZAx[oRX݅w0 -95 8őj ?*b[sz|t~JOgZYE,oZPf{yLX"L%Ღ=/JѨR!E}怚s1xhnxX[-ss)de5NuKFuR10'$Ne%p"\;HN=`bY` 4A2uU8ƞ48"zЧχng@3ͦ&쒱"^DSY<PCnV0B'c1P-~}ݢ_|̫0$H6H79Bdy°bQfwSqtvL>0 6{z&;ggeqkuEh3v0 !PfpY׿yn6XtgT ;3:~0^BXD92FϺ`B$p@"JN'Wuli@$M")2fc @:]Nm\D55̌g^0!Td\Fqdiihկm|`p}ԿyԜNޯ̿M- ,ӟW8.NLskSgQ?|/տt@qO';oajd 0@ϙ!] =;M*i6m< bY`ȥ|KO(6 3N~>dġWCe֡9Ru};GĻ!Mn8xNbqg g C4릓IF~]>-z/ZQ0fW8y_<89~'#1uwVնH_50!2S{V/t3)ZK!2] o#,ɼЕl ]gv~%^#핻UpVHH8ztݬ{VuI'!6bT#uje4{> X*!!dPynV:(>;K Lۚpܔefsjo𬋠QY kxeb-YP<;PVYb`ߊy6R6SnD$f\ֵ>gphfYe0N0f"V4$թbDPoٸ~xbM$ -{X:5S+m2dq`KydpfNRDQ!,phb6,!,|.j1G`UmX~߷iaɅyd46q2^>v%@nD4*m LWnEնj}XRij-4f8.egyP&<lԡRb fb]6+gCnbeǛcoAQgXb" I<ճ)?ͦ, |f[o{=v١A'@=qB#v_yu3ry=)_ - y%+I-SDe\ԖЗT(,{ ^TrVWamȩP0K>Q*rImE~@_.0^׶y32Gz+Y+]ȃ?BWrIՊ>:".?O~uBf%Q=4q2'^TЛtlOzmh@Y0א F!?!@?ljv H2523فQɑ cL3ȼHWţ&m?C?ݞ"'*HǯcplكxƧ%mq"$"y[C/n8?:= q9pkYYr[^s0z&2"O"z-u-ڋ>Ibt]p@T5l]tʡJckIŃ"$\/ <vm5bSZlIؖ&]M:!@̄%7Gq% -']!ڱZ!CƉULF&Ns o|πt2-$e]V~($4Bą@CATΘ+ 3">A`9cQʄ/rS[{ ڋLs.KR}Brmϑ~Z0yjf AL'f V@gΠ# "e[1>$=,(+ڋWծ>|i?'r#_ߨ`ulQ[! -l"D %xxP?K]`J9u[M)`A^_$ EY}0n -# -ɗƆ^-KtL֑ZQ -T#nȼL>of"~P7Mx,yh.؁ĈSh*hVHGiz &{{Kӽɥ^]@ 6Pw{Q"A@Mٵ.V+aBh6|Y4h1K56ѠIs8|)]ws6C@+HQ5Lsi73AM8.7~nQ4+XKhfⷫ!BX[<;nfbUsV U>^9Gl7QUnItR&Kj9K 5ѽma܎`N @4瘪bN 9;3QV<#-cKW6-_0BdDWuz:^;LdwZhBwlO9Ϲݜ氾R +rv䰬ˈQgqN *Uo~&Ps=3cxhw7- uVc?q8mK$:Y*)9eg颡Ωx7 !?>Dmz,$wf! $SfcpM._ a<\^0Nlf_] PMg5OgMDۅC"kl&~DEiZ8s@!;$:LDUNӢR";/9fxKޓT>3N:eL5j[yh9*@(ՈIb8·nIRsXKYUs޳=q`-7 )`j@1#1]f?x9rA@K 9}|бU$p;'ҝnoނ.; 2'̼Nmr|1] ɁTߖ1V{T>uoFp Wo ,ڏ%NVR粢I%'=֜J6ԣw쿂%eQ7^-ʒےH};,JҴ0ZsX9m6S FЀRܙcf_r-EQJ>.BVxv+ƭ*֚780cJ(Z=c9#@}QӑW5O@n9Ik#Fkx_,mG0fahL#Cu?wLtHG-˝&Xwz5"ڪDDKEMFuZO }PAPr& NqY..Χ&ޥ<+*ԮN@8)[,IHkM¤ܨ(&4o!fQ;aj0l?xbЄu#%fs^T$+=D@<:߷'LK땙 *6)A1qXUN -r x>}h/|#0N!}P[Cp'IN FctV$#E;O( GF(SxH:"߳Yd94senc0vMSfť!l is%E{C*|%ԂT6s`B%2.)03Οig4sfN¬)*C"PJϼ꺿w @.| sv -{5@8VadԹz7 ҳx#A"3Y@%<(Bq11ޒh2 ]`$e D57meJSF&lH4H: }}A804ٷ>бKa)0x߃I$]N[`\9{ yKɋHr LsU"@cT P4FPLWmR9VB\ԥZ3?iU.Za#pFAU1A/8~"ȭ [:$@D>t=>b_@"LCx4/XRmj=Tn3YxhwZ{ [ ?鿣_ǩv!ܤDQBc!Жv-RAx􅅂H+E`FM%47ki3˅M@rMd.:k6ll;Lo.`o yihw:FFuSXI!aCg:J>0/V%, _?fGFq51톜P!E^L} DrUݩ6uo=^}P2S>tx}BBnkK?d,.kAZ͏sVz;Y%(SH'"4Oq2mxDl0mY#l2 mvjJd!H -/xMd#玞+#kZâwHEuqn,ug -ţuU L֎M]{y"jv(9CjqD4/(H4|Pt - DH0hbЪ*JwXuɠ!f -[.7 W kZXwѵ3JjYna=.”y -61Nk~@IHcEIITLA9V`j2xs뀡<OScߧڗZBM ]0C%Q\]9ɻzx#޼H!J]Q4@\/EOi=L@F"ް, _YnFGdm߷k)c{TmtFTd]D"GLz>: -чEhn\ -JltlOMyba&BOÀLf?)LVfA^3T͕*OU^e:7]D :#+ >*f;?L ]~! Kj!}fDXL>29IsRtJpB{&iY1Qgs+n\-?W(ݟ%& -kV5 崖!"22JrX Yo:=T3# -%BKW.OۜL8S;F70Fat[n@Efu$j8m֓ {`89AKfF Am'40S2>60$͉/ⰢM?ZԦۃ܍Y-e | \05i  -ډ4)D4o H}[@!%8Ӑ#1a ~Js7Yw/4)C8;-i Kx4)0"u&)y:,`T[b -e~Y)}w)̻Ծ(_*ڜ?B*7ܔ.%eI# {:'2Kz9+?#:9Fڌ3%85ÒcL|Iɼz+$w{n^͇mfw`FlvW@QMPs[+(YEǠ9lv럶/CF8 !Bː ͍x2 -/wBÂ]9a 02;a@WFu+`o 2=h;Abܿnaq $oT>M?]Lw!{Is%#LNp%(s Y =@v TB8QpJ-NyvI&Kfx^O0՗;lLf;{}%0\|)CkWPV4&d"N<_P}Aɀb5xl"LTIb7 &=Θ_ІwQpV}'HleC.5Wd{*gdTmK/e SvjOL~yi8`]%KX4$, uGlvqtB{t]Xwb*.E4'+PE)o^5vq9w_Qc/Gv+2!8u]g#@F&s!o\OVN./e9k8RgRC1ծ=Qۭsz!"F`u!009QGruݾyNT͗`F 1π+0HբxU̮XN&Z%GwDd+-B;BLRIE'4fnFp4E]fT%'Ss'vw`ma]Lq5C/ǿb1B,=YznXXz'Z+}愒F` U}.1Ӣ}%?0=c)|G_bFq}'|-˂0R5*86B Nƿ3bcc5s4ub'M\U">$.;~t#L2* eF$gT^4HM쵴9胻تJˑ{y[_ie孜1BI y\tEg~%=P{E2YuR=Z)Nz0<D foК;WVy|2#X?A*R<]i耠 -i*#SKk_XyL}ϣ,zj[G5b*{i&!y~m[ˆ&+"2ҒIﭺhxN$I $kz|w\uYJ \:P\VKx .}/#2FC\YCr]zަV1n]{ό&c*bk?߽ٔ~-RH$yy#:QZuۧH+9+="Nlk ἇdWdX=(pN [c\KoX&X{sEc`nҽ0?צKkfʻzMt&HtO fBf / 2@c_A4Q[6MEєBAdSj:YT֎,|kOE*<%һ ej=a :"\,a`-!6l6|pĠZ@_(#ml>LZ|RvFV:@!RX7ZA;VabpA'2sL>$%F].p [pOx,6RqmŠɾ8 2cPx\iF|qi,>yFԻIf(>3{ovܵZy(Q2Srڃ${ -B¨$ 5%Mr["$rbp^)h'sPk#_V=G;5? -X2{Qz{%quMvza>w<਌i0Ӑ7̪DW@[nJPɫA^eŷaxV8%{z!Q1jJ"iuB@5biϘh.Uu9ު>VJ2 J ]搢 -C٘tWD e ,3ϼJMF:7>~a`KK9j2'U9*=e w0 -EΟ$P?@tq}$n>fّ2(ռL -^ec T8]~r|"Z3@2vh C"Ev.]}"ߧc9[]^_3^C;g>ۏ@G ё 9t'gBFS, ;]dCbiĽe&b@ɑj[kǘ*jl=~G\+;pځ#Ca-}5N}pd2kw< rix? inv)TrʛxQ#v7m5) 7R2ՔdbE8Xs>q6Eo6u4WYnߧ#r6-`Fv8)WpmeAEb=fRWm[ej !S-Y5x -'w%#pM1ʙYm)n~zH᪕nٕȲ )Р2MX\x`ğ14-+ TV`8k6VV7yYր mH7b̈E‡~ -yLӦ2ZJmR$Awf?@7RR$z*E99~hS719i:=:TlG -FDN~OPT^gV-eY_jL|L}bbCR@yJߋӮVV -S!:;S\YP0I!q4k)#ɢWdu7j{*v=T@V׉Ѓy gQQi>)JҐRt}8`Z4m$GPhCͺgKֽ\AܗaN.-OAD;,0N8q-u)!\xM9 M 1`ꞍBO!(VIHpjHGer3)..*t]xwr2xs1A|E5A#! AwBPMSI8o11pKpa 2PAES+S$1BT6-ބPZ+//d&*l0}%#Z̢D;v;+i_a&:Y=!w,"9}jVµ.^20gg`LDugYysPOŷs=q$<V?P*[/JJ% jȔ7m&@ImP֚Y$0/*4QE#(?JZڀ=$TVH*d9 ★|{Qfg܂'jf7YHbL:P5'Iq*ffg)c7inwhjղ~*Vb̛>x2#K;||̃Ŭiצ>z DldiM%P,,U,T&Al75y>|&qvQQ҄чdß'I~Y"Xx"3[U%F`su+툓 $9gcBH$ŜES:=:%I -+٢eL&ĉ \{h*Q)+{ѱm_ 'aBB8lz$h&{I茶>6`(nnNp: XPB^-fVa~CK,SkIL K1^J } I/ Y1Cj]oG.]z3ّ#U+9,;h`NHthCt~rf j"ԵH?AGXcJU) $;tpQBAbPJ-2A*p44m`vzdHY&=/쑯2{;F\d沖S% m<&OeqZKp@HN'Sqm0 -^bS~4}z#F|hYH#n5Ubqs6ln7Rhkmpr.5Ъgc}"q^WLձjIzR6»5ˈě9KߤVC>ir8rz / -Fcf9ā Ҟ)]m10XXP$?UDD̓UgA8Yec}"YM7&v&F P[^.Rkw!~ԍ^R3r/<@;a ĝDI"GCh_OAN^*rlOüz CuE+|ܸai0ȞU{O+/lf胿!.u lhMlo0jһ4\RX3#Ll5Ai ',+ᅋb)Dr&}ChRmZZ`qFج " c -:4Qa-)0C?`S@QAW+y3Y -[,`YmbF:8C"ՓM$7 Vp`=XW;wBvhP-< "^<;JZ^O6%h>KZz]DI%R' &e8l Hr?=lMcӽ_Up;%2sO8V)ҤDV]'Fi|x[_ug5u ^o_՗O2޳V٧^T-aOsQ;܀󛊧+/YR흤%cm:Q_O5Uw5 є_3WߔXL=ªØL@#Iqkbutm Pǟ&"d3JE͈eq!F7^)A`:`Ԣf¦>mG_JZO+z\,lpڊZ,'}UwlX\J|W0f;#qyA!aI##u&Z_I!Nqd ɏQR7~;dβ'JwF8EXlJ~1n8U9:U(E* M"BhW֤q,;V\jUw'`:5$_g@RM뽁SJK$ucGVfVz%O;6%TZk&_f<Fm43#aj i֜3$]gFtiVl߯WsE T @`Ii~9u&hfEb)ʉqd T(z#Xx!CY7FjrVza+} :'p;R?ZߍSO1dXG&NRᗏ^\GNb╉鶘W7em:g7n}ɄFO`YpY`VGqz[ryLlҖd.s p>%o hۤ*(ys1=jv,0QZZP?5[L8LU6T淚:lX $ Ҏa0 6^V pĸ^SN nFK:#@N2$鑱`:kSXt9z*w3ʻ fWJtz_ÐTNfÀpiuI}2-iBa; boOK?pJQ49"@M^Q؀8%#RaiJخ=iz%f&(D\;]SH߈˔o= -. 6SH HĦ֯dȃ0O^'tWgWn|v|FWdrt=p{ PvC&O+`־!*~'[lsek\Sj;^ũ3"m -ݔ[F9–0P-E^ՠ8SO:oKVaW̸rm' 8]l;>*mJߠWё7L4/d zYYuo° -e=՚ @i n<CKآ&,c1(\B!t`%X)pq˰=/X"AaTnI|/ڧjld 8D@Y@S%,-%b9 cb% [sUM iA4f_2hKNʩc?cOS [.xw\BB5q$jPиAK -P*xPѶ! F3īXт+p!z+nMNǏM^i=h41bQ9JݓӘ@b1].BWScz!?u<&FmELlvdrg] w Ix)S9Qo5YK|ڻ`JOC 6]";ܰMT1)t V4JX",QՎK>3)C~[#Ew $4*(El:8 QXȦܾ?ߩ`~W&"~PDzf]dU6cf#;Wk0H8JVJO -5C'irϹޅ"7iS| -c%a?4Kj-C%זDεFG-whTlo~o=&G M-:ޫh*S'Dwh !msu5EBRPB"R0vJ[}G%e]|8*r"}YhҹWJ`p_ԃ@B+D[ita:IJE(zw(v0=:K=JHi -(%a5.`m B 1|]*`ݱUS5 DWKW36,34,.0j-b)}T(njA o}g֡ˀ8)h,b1!VF?Z;W - -TeUa_;q5d,/3 [~OIr@oGy(AkX3bc59(SR/N5fg~rH)mLY[JZ0߯ EaL^%6G.nTx9Z -.uj.XRH @I7ydGDV] CAjJeȗ.7աi~lɊ3w!HO`ukhfջ염Pʠ#$a-l. ~s'93 z^=ܿ%s -kgWx>FC̘^ ] -$¿tQnd{AYsy7 SR+Wc3 -g2JUI{0.&kxH]i? }EdD;N'\Xt^C.HT-hLAs #e7#OA)jg - Y0WL(~:((!sz@nea@W _ܜ]ّy.:R8'q \ Fivnp-@tjΕFvG\:oΝ -T>,aڒ{7xĆE72qɍpbq= ٩?N. y;{!aηd(hz*%b^tỵ(ť-7!󀎜Thh 9E> -C!g!ztbY#x\ITJlT7o򵊈VjW(HRN6c. N>i^-kΈ1uR$DI4m}=J^3ܱ- :7]ݍ d_/צbL̶ߗY1!Yv^.Af4]DAzJA"kw#wkT/~Ɉj&Lzxr2뒮_i:-cJS|G9s*sKϻk{כUhH2VZ1 -@W]?׊+3)3/#At "Xo4Q#Viab4V^%YXp~\в8VJIW:Bv/ne:2jZm@J] k}xEd"фp>0EaD6d,?;mWPl `G;m 1.,9rW**/i_HG7xV:+<rp? 5?wkz%]_f -U٫n?QQu{U)(b"pY=TՂ0B >.$poMs.۳8MEѕ;\hCkuIѬ\m`Sr JfA1Q>2{ vL(qHS(t5K!Nx<&wS^*b6/LtR@1YejqP4%USp9Yp|zW.Gxϭ?t 3#1D>#kC;lJ U̿ nBxn-3j [ވ>pӽX{̽O]G҈YE N9J#;Kb8@;42Wƪ&4;x9Gcnlu;hVVolI *o8 [fs_X?QC?Bl[, -#MV=#"Hl̪h޶%p-@}rkW(f9(BS%dLyL{ 0k1GQw(hW|iMuN*fRڮ̛fLҺed)/mVYHD1{wD)uA48 -KU9#uuW|8aϨ(Hj[0$Ncz$[7 _ڛH75weitօVsTHAʀ,|9TtަB; 1881U D2,% H5-,s/4(dӾ0r CXqL"-w*@r'n a;ErD A q9zeZz&qbq:8W̤Aiypѳ_QJm,pǂ}k'pcHv\qiȥOJ@!v&)t r1f;o6jJqƛ81Dc~HuGnm>WHS1y!R;+MpE[\}нW0;B-~Ch.z ->:2;(!e-1ob\Wæb&SJHm>+KpjYCaD~Qv@*g:9 -†o߫j*s;fICJ+p+}h)CXcǾ60~tWJNfxT -~W.X}Z6SQ߈G)K1TNfa궫>ҏ=f)@o}'~/{i4Kq1lXwc~cGDp=Xd4śkzA4oWq"}wvq:J/$S B1h麰SapdloAX;ט覬Wb 8_ -W88 -r00lS/VlΚ.B41RyN2,?JՄJFuŲEJ2/ yӾstRte 3rw,`J!lێ&(w%8eh- bMfV]uh(HDd0B?~I?cv{!3{,鸰IE9\Ln{Y&C:(0 YÆò Xv?GC!xT h(SԾ Lpƺ^ް)4ܝjsyLa[>h!>VMc^FJK!l# )Śs4ESy.m/jAwbsXgxfġPĶv'e ۠ϷA$DPLrrGj4`zp ʕR9Ip.*Ek (<OXgeqX ÚnE`@Dل r[/Kµ!}wDX4(5"J(r5ʅ$-WXxUAu2lH$eLi-PR?\ կZs:~"ϵJ+ Yeջ[X-?H<8
*f_c -SE^dڡ)C j\3. uzUQ؞H-/WBէ#jHL!> ىJEO eBA.KF~=CfވW )\DN24ri'Ԇ2C݄5~B#:N#JHkK˨jڲq>DN&ƆS>h-J-߄xI=+\Ùx> --JC/lip(l)p5N5HN%D!}&D$h(yz/*{*T_$#mM4qBb]LA#C Өpb|#&~tDCh %O/f2Ȥ MQj3>-Z<mp3Y}Q3QoF8H!/ԳTQTB7+D I5zI0<4j``@ָ.PTe~c"jCd'{줣+qi!! ~z8QK"S*#9I;; 7ʗ0(7U1ًD sV^w -+!<$]3_X Q3IjSj,3F2ҥr2G<_ QX &{M0jT5+V>fQw"B ʸ0b_,&570OcmQq !eYأƐYM@0*$ƟzM%=v%FRJTR͜, q,)ց2]qbZxe<?:;ئ)iq7pIp΢0l\q#f -]jAD*i߆9s -Sߊorj#F[a!9Fia3$35G\Y1C!& :ͰȜ8heAL_ -1vffb%=)a~(IEqYI4+PQմxJ%EЂ\NcT:c`s$SBu ׄ Ҭ i\B:׏ء rg:[QJAtv1DhD{Y=? - IY;Y)u\! DT#% -o%V3yM2z#FzN>aTQӌ"RN-Hl5"CZè(#<#SE#Y.VB./Ni1='HT({d(։劚+tk Ҟ21QkuC#U2!dAql'PFM֊9*:A1T(EϟZo㪛0S9CmHVe+Hп] -SndjV֩LMh/‘>ja=*Z>%\]r>BH;kV{4c,Qb$B#>+|"p-t?*, bnF^92y G._uBuJ$H=/\V #ʼn3! ''kFy}X*%lx{i*)j0/@w:d\0$-hԱ(9?xA.*=I:LO`Wc% -#T -R! RIQ#"h .wXͨBfDU $,$*(0̃)KO~BM(r*J5D5*hJDQ=nʈO!0Ai92 -޿Ce3L}~8ֶa"Ɖ!| PFۻf>|gTDEQCDU+,y FSFG|ULעuͤʏdҬ4fFބԆHtz [86CgrivJ5rtS  .f'"D*g&ϒy0фb/D"8)V{ ;0E C:``0g@blhH`3\.:U ℄±ӌ4' 6>IJD5/˺L/X$#y= !iqW UׅWJEB:ِG̟ -$P9!jmɔR -@{WHFBK($Hr1%bU#ZY d.J0,""b>#s9àO!'`dQAuq;QYhP C!abkmE"B\%ɓXFq\X ~C0Bjj$8;Jkv܈5b:J* 2P ,qNH˩O~ʸ!sC߼B^qjcnʉ%LټF"4M)l&b@yT^(Ac@C%!уX¶BV˝UŔJ,ʰ'k3Ti1U!D' C1ī -zX4!HDX ".JmI;̎%%nx1yBO2t#z$S?kd8A>PT<}BpĞI,RgBE{6@T鰏9"+P_?T)ԭ*!1FʩtL,>4mO%4o="T+VRL&F'i1A5$CYT6\r7^u!k%%_ґDHV!YͰOT&I6a9Usi4xFjqiˍ!ۯC8!(Y&l) ",?HL<@z2)\fjf_K4[# ܡ0K -i3S4gKSE`wVHC> -/ZQࡴXY o̟’ *}|QJܶp{Y^2qFDS?Ȧ+T3"欰yj& ;I^ 1:TaViLk'(D Q1L灵`41uɂ݌pr"^b&'w. 1;"!z*\J2nX3@B>4X25(D,:S3J=KG1שQ;R/3ES0$ĸz,Tv0ЉLbɪ\K&Z -UkVѷJ&9UCoWnTJJ0cOMpFktJf9Fs󋿶u($Ze~*Z"2Pto%fr83 -'yTPI ׅZKcOhNWzd<#o)+ @{#D{R& -Q -$ȋGEF]=LTSMYrEŐWt`9C(oRC9s(j"C5U&7JHŋ*U&U)T<\ -"QZʩ1TOz^j܁8sq|%)K5c 09^K:|H\(CPEp Z_DSN G枒)DkRTBľ2cN'c2JL(#P W},EyifҨ}YTIPhCe J|ӍLtab)$ ;! -W:P,u\szfA'W8dC{аLJקJ "L%Xƻ74d1n7B%Fio) QQN{t! Ԉ_A^TaY&|(\*~(CF4pNJf@~릢^Bb|SBRLm8Lz?06ZЄP+\hwLΤ%$F!Tj*#y -]f cHDCY?awWz Y -V )#5) ‹Lc)~&!G*E2 2ڪ{.rv&z{gz - -S5E|,h3ZQ|! VʩI{g"^ -Ð NFQ!0$thOǴM0=["-nG>B2ScP5]Gc#26[g*F[#AE~WyL}C%/t1UB/>}E?aŒy=Rt^!}78GÔ5&>42owS5ku4[Tbfv~q?Mҕ -GyHU^ IaK"3hPg$ /eF* :68ΨAXhVI5PSB#2%[VSPR YA]  -"3ĸQGv* N +kFC^YCRh#!$D,pK؃7ۦ(?d#b⾧vq^ C46-55z|vj$\YbI'UTʷ51'u2R -!c+=$ rEDw*kFjlOTC _gzU TJUP(Rg؅Vϐ80#CS-"j[XMQt^2 h -Ygrl"XQBw,$|4~TCA$#Tfi3 z] ac,K"(OL5JF(#EU2!&*G;vGLq\ giLghJF"ĈV"UqNJTHNLq|bt )hU(9D"&^4"ewNO ӪY MBjEh(jbŎ(:SRvڴ$s5D"B<I1qcZѷOeZtyVq %έm24ZhFo/\SCzQ^#h3 'Ԅ#r "nW#pJF᭶ʨ"*P,UQՂQ"ֆ`r,(Kf"TZZFx1T)|$Ht0D쟾G]BKц[3nEZ(/5΃Dj/U&PDvR ΅3D;s,\nK$(fG)1aq!_"M+ĸNĐPםNkň~y]:L.{aQ^M=Q 08SN/)6:)Q$J}.0]r]DӦ">i 2CBb.ډ(4ax""Nqi4M_S/,qQ*ʄi>tBtCZ"qHtM0¾G+x8(xuT͡$"$D[B9 -" ;g;4{jC9>R$Mu"<(<|L>K(ʺf8LAIabd"ϑPt)U$EBIMR)fI/r!oPr owq H2%ɏ bHԈO˜4PMG\23 @AP8 *~D"SHAntV`3}ZI5PYD ǑyEL=1(8@ªJ|):0|ż:j$z#4fiRjR 0 /\Ii`:! YƟl=&q$S ԻB}uxf4vh&:`Lg,S䒫i~ KV,?WܑV$xΥWdBU_ e@÷olNTDz=1u,`hy' sACFb|,3DE%)JWOxI^&T2-G#LwxP91/rA7ž1!;0*Jն쀐oX-)\2+oplUIAVΥ ~@+?b9aXIdz?Z\~_a~>*jxX;@>ذNVn -\;]} ZW\4'W˗i30(Z :YÖ>a[V0m+S 3WT8cW$tI^(ֻ3"bѼ<}LDOSaNg'6-J[m>oq-uQ%;-K" _eEgD*O-$>r1@- /֣'=Oo(+r%8yt5u ~|(NS:@Jig>1EԁSc[:D>x!^H&`t(dVv |UPݘL$bmON9?dbnƓ1Sbwڊp3(w9k#䈌Ҿe嗤G Bͫ+N Nbj uyޛS8p9,&dZbf4ŰA orDbn}R5ʗgH=4|}.lNIӢ)Z7<OV&yJ1mNT 㞘^$7s -'Ml1l0cXk!j$С :7yT;mLPJT zsgɲ|^hћ@8z8/ Yƴ6y8Sуgnz#qhd۳.t!-2#!]Q'aj#RYR{7ԥr=[t0Muk B6 ɎQ[O8{aa~:(#k ]&!@_$IH'= oBv4& N">BC2٩*0WY7DqE+)@"ܠ -r<`tZ=n#&m nG 5)Bg}UO*B'r7pc0cWE)EB>IoZ=׏{MT-=lR!WJGh']G3*TRm(;8y}xUC#1a_1z%e >7NVXL0,+5d+d!(*xa8YO4zwd$L%1!s>vAt96}Gyk:mTc'<R_uz!3MRB.vB~.,B"l-aGMN0ic݄-fX?_lץq?2,q˾w3.|v$RYlӸi~^N Q 7yi=1[oG *N059 -/mZb% zy:<ҡe<:$jhG@tH-('=νZ` H5[? -N 3Bߨ b{&0.Ÿ -b|2A"bT xR 8DwC*.RYPGh!fK)p,NOPm(1s微<+Nu-փ+X˜f^Pcp:k[ -*Y%t7SB:0v3zƭ2̃^0ܩp+?me=Z`Ί:0xqХ> ۾H,!)`ϗO|>ԍ*_sBv=:5G]~+%Ffm#o=d@z3WT7u\l~oK @M,.fVamD fL:|(E9PT&e44c.h#BIL@W2єb7zPY+ź27 eQD:I9}igls -hnHaf}t?1\ -EW]e gt oW]zX 6ر, @hnQipM8JJq6q4na\^U-I)Vxy) G 5}8V4ўe~D~?;xtĻc ?Vi6P*˃7VM2}gtkOLp?IšTyoLj/DPF3LtO.ʻoG)GKSٱTa4^<[/İ44*>Єb),&<4> -k; -zD7\"^{"8ȩIg樍ER!"XIr -lE9VjJ!]PV?K ML4c%Y-$t F?l-{TG*=8+1!vJ?B*+gu=[N DABqMLDWc!#+:h`#]frjPDMvn>ŋh6lăxZ5#,k$ufn}oȁSv\E\ZKL|C/10%~p#G#gqRoY ++ (Fy(!=Aas,dҐtکQֲ5PazBKߟ!d OyOK{^ZHn{,eM';_aFB+*|]U@ -8-QQ$zb͓oHJq52ez`͟U1I5fգBcQ -CY&5l^Njd <1HOY rXșI-vQҐw,ƒrޢM j -@WK :8k\2 ܚ).3IHGT|{}.xZz܀^ean*=L$f -Cp,Vi=0Z0"Ѹ%۔A[[`emR6 6i$ND^?+ȥF<B.e 1#oUqH4;ֲm؈;浽6y7]=Y+nzVq5O?$bHPvWOFtl.1.hu]YG%Y5(%a{V.<.y-9-PH3Kdֈb̭a _vSȒiQ lWڵSU?$up`s*ګmoF}(ɿ9AP/||>I<|[t'd]Q_k\=us͉ɗVm0)yu*;)&5j5BupTZ_U߭?pi -b土* Q@S]L+ї= =K،ڌj(NJb2PZj(vkK)W*®Pt(Y1`QMZ|tUۑ8WSWC˚u '-7ĹFd׾ 5CRjUI]ҭE# -/y5w[x KZbIs/9ݬ\MR&YY{X?T!#;!N2k3SU&L(?q9QTf( dqGTj˺m @<6"R|fU": @_ck**LA[$4+%維} -9[:PGZ>oCH0Ơ~e2^Z$l_i h 9ƍi8~@1.SЍ[W'7*)MpO#&%Z|F.ԶBAKspc-)Zmu>ҧ"0+7'қ@lf1Dco+DkK8lseI:ZZV2h#eν1; !1ߚe>dgTҳ&r0>-(NEu&{A緫f40s@%X %Uʭ$V l\]+Y7D6{)m9dsqN"^pTzIL݊MydӐ Eb#V+F_ms),xS{ !&E fG8,L& bel'V 9G޶[2mGW|[ 7'f$xg(KvM%^TҞ$wM!?tC3S-&wHӝ  ńiFc`ٺ$Qo_VNNZ7RNzX; 7 /Q.EtE>7U,'M -Q{*˒U~F?1ȩoJn fq2ۺ2zxi֔~o#"n!PWd', seπBR;ȋ;ďf4}/M+;N@T &P=G@+XQ~ 0g!C+8#镵.aN"u)򜍨9C@ei{ g!I]TI#3Vp?,Q'n\Y!ænfn8{zngN(WOq]h~qtΏ+ITwE - -5U*;IB~er^h, )ɻ~doj Pϛ -'N24F0UFAv IYآNFa[htcY(_pA:i/wS5)# D8#X_q}Sv N5LpJG(K:n/l27g]՜c>Y!%w) ZdeΨM9kMA&7ۍĉ"KM -) 2Oꓱ$5GhwZ - ]0o +o:{7|DN>_R -ZORYN4V%K&-)WȒfd[)2jkl4*j _bbIN?*h,77S CU<8X3.20ޞ j80a[yH^"pUHON`CMÁpگ꽨%-g7Kiu=vH~a׊zPsOex4f{:;?5qϕ$e,A4W.m5ݶOjr$>.9]-fD`ܥ{*xCEB^<{*qN_HlDc߰T]_{MK{rNEZI.P[!b!zcS2 UNw8.]ߚ~/I4_fH$ -ȴnt~Ľza 5gs(Ÿ裐ع/̑ٗE\AQDMA{: -Jy&uhAZsJ*7g I%3" Pq9$f LF]'v W^.zBKm=؍!0τKxVMX\Dz.P 䉼fx='5_1vȴ)W;!gd6Cxt:^S E͹Xm0ʕ# &FfxZ#n2 49yQE&d[GR5`+xo{!9P: FehjX=u[jX'7b [BvdF8p|:xm,SUe\f jZ3T&`;# -u=d{Yr?K'5 J:o~kJ |ȬBZNnҡ%1H>wv}sfr.Ehq Y -9C^[ U#j_8ADɣ^C|f023N2xcǰږk[ ݵSA.)u *<{$T;,+Γ) MmM= - O?:H2JvE=R; -~#셻I6] B]:\z  -o-@CkGmpwT5AQS\g(dZ=" ~L op- GH!ʼn.(=lkoύw=֠[<$ -Y*$֝=~I#4"j' d7ZzsL ^(voAu5m|µt9&Z` ZM1;B#ޥzŽ(D^Női:JR!A_  M[ -pp.ώ"RfAPYyl[*a$(" :@j=XUcOߐFA7Q -4֍>qzY0^_hn\)]Jg0qm5 }k; #3P]*<*p"MDSQ^Z -v^eJLxD $J6*?,rC0;t=qS0E5].,nj0*7ongkK;p:eC_l)ycW.X~ T%fjW,c{0u. -pT^4#LxĪVX)nȇβ`:Gd+7#?rJ`LSs:LhT mOTߘD-q婽 -uT 2jv!项ǥ )ܐ\W91Ƌ4O@8|&I'!Z2d ?Noy^G#:x/dbJRÚ(*=A+uEE0:+" yD%0;s7Dc Ю^J#o:>D9)! :I-3S3-Y%]j~&tC4acʻb(l$=`86$CkU;]3fΓZ*BpWQ4]YFj~< 'wb0 -`t TRTբ(Y!W&s<۱۽LaV.3a;+͋t1ҘTC]>wRQI.!9=D_ 9Pu6ŋAݽəIY <ZQ[o!4 -hWWV*k}OI"M(׎ׄt3zG@aۚB"wxNB4Ycy7-MxxQYk5P?&m6WJGfG9_cp9͎{r[oP'u(|yw9 ~ aSk,8m|Waj ǁ팴t$M;uJ ݡp^:_ :@f?SL[|3uTCώ"=Tu:c$K d2IwP$ -=5Ezu%mp -]"#H:ChU&'/#l"F(> -, vUFT35+qR?T$JH;[sсZz7[rp4ދ8zLT<7P{tJh8xc|/C,]*t@l+[w8Nz3ٽ`8l5֩Ȧ-jba"wSY -9TaH1r&:艍/hiDѫ!c>KXǓ'yhz.I&@lh[gI +0<p2W$&^ccӧ! *n`,=r+'${)-5ov4ỳLlX A%9P3z-&L[ -Cۂ庮Ӳ@տ(;ե52W_XZ׬4@6;Ș \+_:LUZj&$=Hd_c Va%k0 $êz迡%;m$܀|I qH! hڷS j -M5_3nE|+J).#4=(/|ܼt0!+@$@$O1R(50۳6B ]e4G/.N$j~}LNsx,eoNa;*ٜ-9oֻ"^GJ'W~0D0F5gd@٣@lB>8]x` #_c4`V3TF+BCn`A_FD;0Ujjy} - -Է `OBU?e<)@{CnN]Wޥ]?Ӌ7^IbvY@JޮnE# p#dV2HSŘu5s6y|ҡxnL*Q}E5V`;gaw8sľ ΋kډmf)&tfVLMަ+NBj\&2 È R^'V(%R{"SrMOT+y2%9D #& >sp@yr?l;sp -Cq!+P8[z$nȲ2jX tS/7 -%+璾98.>EH硜 t6r=E0*3< -E}0!V[7YЬ0 &a qkw]5&mYoB7̾Z;⫣/>%l7-heӏ;)!Š͇ -[6FJqMEcw/[L94rM -ןH\xYXTP:v# BifTqJ=.+J:߼=)#=p.*hoᲉ' 1M4E8 qu>@jj?m<^iw I@Ig3& ^N#nR̶ƴ8rdP/_R4UnM [#%5"rà*:~23Ǟzْ4h%&zXIZ.k -9- -Z+hV P_I;N--GԌ vA`akA85HH؛>k¨dArǔ'(A0\+P}Ι>򵛱L4) `ڒ,R'BI," ײGK@F:(_# - -]h6Eey}f6gQtÃ~K0D\/ %*B`^S.Ac+ 0|lUv;e^ۈwʲu`Q66YpZBIP RkJS8Ȃyz^g-4N]>݃>\0VY;(]?5#Ÿ?~}8%j(-9fm4zjGU\C4:1Inpa; edK#!3r, -Z~wx i^S"a??0ȗ"qϳGT&eSBsg/Hؕ r7;^(kYqF쁴xlvNn)Ł\t0ɷW4^E7Az6w P–mvtg@P$CVٱ͒7#XAQǘUS6x-ߣ0)/W0VG5+7dj%^8yEJ#_ -IikZꏆaRz^\RQh]:'bijƭq/6@%XעOwN8d^&?o봵nAd:X:{S[iIX)MJ`Xkdn:#Qi9Җ,z_cf'RVYI+ 9bj^6\>stream -6;j_\1*g"fo8]2VoyuˍƮ##"ѿ~qVGH:4ͲͲǑJ7Ib؋u ̽!v(LB׋{ACf:>x'-#mGVmILu*Q'N\"=Lxws50کP:t^yMMENep%k}yǍ5܅FyieS:mknn8;Ś۬# хX;:]N]ќicV7 &cM=O1$Dꨑc™;BF%E 8B$' HqM8RSϢk"DYGFmM A*32XI}Apگgq%0mqi*Ljn-n" -N@udGYY'CM -` w&93fnh d - tC>=R;@4&0ɪZqg+ X*d!oiPU(dʤ" a(v&j]|{:4mUe88Y.(wOM>5I m)Wnu3c|#Az)ƷLyđX){ݬ.1[YLMrE?| GM`~)/$<ڎR6isT0zd ҒAOKl? rAgF>XNK0hp[ODYQ 'nH}/XjLZ]ZXM,?|fF D-$~ VG_;2 (Psz6w&AEPn)r,/)m -C sA<-PY~G'_{K$aط{[?/cZ/LT=GzΈy[2~Vp,ݠ & ͜[J| O ^l/g Nmnzwwxփ\$jpL~3ĈS^8Kkpyme9d>wtqSKoed ")W$}ĜD3U!?1,_آ1#18(|.C ZaU->;ExoYی>x@f "a - iYS??*^~R@3r8*$$*!z4I&E?MP1ޛ} $4r8ُ`¤zj blғaf^0QfZ]=O bt}UT]?"(?*_D8fsI* 0f,xѯJ׷~gV赕s3`f*'ŢT9dzL9 c5xWH l:Υbqi-0ъygWbU}Mk5" 0]YZyhRWy׮{7z~vۛ#*8ikQ𷲣 -904t2nvš+*aH_խKbb~=1m |m՛:+ \sk2Wv"x"%AqF|fHϊyZNKeYPX60 .r1 tDa ʃŁgN CLגނ9!kʫ^*]Yڊ(jU`F +1jH扩*b3/Y98-RDzh+~p5jBN4ft!x *& wq7Dn^::nY\ I!%11;+[Gq^) i00ePJA׹@MT. -\Jc[I]d xpiݥ(lS^",zT=H#JM n ͋w'<}U2C0y%.i=1D"ry 0$0CO|f;Yz೧ Wޤ5h0h&S_{&6^[@7L-Aj|JUi9.\[2iŠ>t{/h0`M`b\~͆jq]<'L[\0?LޏJVO%5;3֐kօv+R熵Zb]ݠ'QF_@ -+Gt`-L,'Ks{6fDR -{*)F=A*rhxsH@lsGӶ`%O2qh] -x F˔&| s4/J}%aY=8FWoף$ja&Q1I[V{ -lGլO(wph>}` KMeYbfѠ[~+&I>vJS,a̙etK)ۋve)R'AK#R71 -[N(I򡰳`*|qtcI7tt^}y*qx-OJ:3,1շUq<@^r|QO*9s`[+m_.1%7p"^NS220ϖvO~ŖUx4:\I&gܪ%ӐdZb F&|93Aō;k$+j2V[Ch#{{2u&hyH=0 -Gzm9s)޺8d^}WC)'>\%cćZ phۏ\(DF]( n8l "Lga1+V6 ٕ._+GJ^Ӊ\c,d16DyO1sp)5-$1k $ݠt 1g-v%J"ª29ϳt[bu2;K}~נu{D"}.d i -mNX҃TpdT|+?ATز+i 2<1R 8FJWC0ƆʸllFt9d%+oPz=u) $~y2O|S -8W6=xF`o(SJkP8uЈ  >T8~ʞg n+B@wT',ο8H)Qu}Z|dfG,5ph(Zaiw?i32u;Fb־$rާu?P(r+?֕,j"<+Ȥ2O@ZgU;b#vco*nb>'|%[jwY_\>MYkhULF=Q~[)?&>`Xb3_4[J :K-FԗlZd [.1+oQ׫Z Gq^ t6Ue 3oB4F^p.q+F5H2ľg{+> TݳƵd7̥ WX؅o0{WJҕ+$3*CjbPsf Ga^k׏+ïEn8l*bwνbs?`SƲY@$E Wi:ڔʼc%Dd tߠHai͗B)948It2?& +7njfc f} ڤdN^RD:yՐB>pNOY^l/ф BV] !frq.5q$!hxw(ywκbdyp'Mȸf h ,EjꅺIY׾X9zD*0mVDbZCwRD12">D^)j`.^Ss=[٣Zz -Jb^tͲIi0FMb= -2kK f7ppǬ%:<>ȰhMPTC h+Sks_ zJ~{i<0"ޡ1o%{J0 `{*ln+jó_Dσj?Ɗx70!uO&!] MXi*H/ -X) ->1E1;Iwa%Bo#/M`#X4fywrV P/%fSOuuix"Wj5k]tmAI ''aĐ<YLlj)$25?ˡٳ#`ǻJ+чU1 jLBP:hf]yݯ*3n>0DȜHIYK5Rx5Xes9D_Qn)_THb ΋@IPgʁ4ʒi{+ !tZngZ|7Pk,kEjR`6fe"UZfY|Dr{fW[ r(샓`06vmUתl٥]Ng1nQGQ!qبsKƺ 3gɫܨ6u^a`; TzVpkD?猹;zhҚ'c'|,pmcPˆ[NOPMD5D+9^Ru) FpuNJ4L|)s>^Ճԉ!ةڼpB<8ɯ #R=ub諥{ͼeepOU{P=#*.kIjͬe6jpUM2A.}dDV -J  ZˮMx" !zH罝U߅2>Xuh]6q'}=YbRi/ȗ3z{/%s0̪AC6ޞɞЭi1p+5Lߠ48 Zq\ -r+qS ;\E«Xl!|p[c/ &Ua,㼨Cߠ_O\XsIͤ`u2|VnOT;4Fczx$g)n=l(vL*;pEk I6řv7/H*Ds6Ty#,h=RG;49~\BՂeH jL4Ql"Ʈ?$l_ b/a_a7*`'BA>5 / -_U/M.jjyuÐF#;uU ϗmG׈zI3?.'FF.Q#2^ySN@cӾEЮdj3M0zpq5Ԥ8vZW@K~-.ϸ n46oa l 8mrr_Gͺً|Œ+5Lrٚ$9>+--&6`L?>Rb)TkyrTuxŊsհ't`P2>@;^ִxCנl/±R]L3TaRƑlٺ׳K؀}"BB+l@;)>!dBJsnp~-^;_fyHjL7YgywG(8Mۘ?_uo(iWϚܲ'V>] cT7hdn[}AuxI$x .XnQ1эz<d"x]S m^e5>q֎)DX&6jwYTc3NRޅhґ`n;%0AX'V%|DJ%@`?ȗfpdk0f ?0lK-h<ƽ,bYOeo0:Pd!wrUesSU,8N4Y[uPԸ f,͸?<ƌv񔴍yB^ur4PN1Ι;oWa!|'ݽDx'ŪxFl-PDrM$mq)Xdm2=&%J1ȜKPi]wu'CwIKFN>:R!WF=|pDJK6g;ɽQl}̈́.TJ5&fڱ~щ%M^څ_L3%A(el5 f#aD-Hly쯪07B!p]Xi{cQg/qk=ߥq>jJD:_q?IQ8c ~| ɍJS*%u|@Щ%^Ci -ۯQNpU[y1GK0-$Y:_@c4VDN)==nHK PQ!De`MWta/&DpiI~| } [VPsx&ߛP'$Qv6mlݴ-C ]_Gt,%_(U]UaNT!@rj6RtlPd 6eR~ 6tՈv`ъR Y͞`6=]'b l!́,>yvC#δecGݖe #2GD7|ޣ&6Yl|i/&p۠qgEsѨUZTȥJYf `\&fA(x4ҚS"Vqφ2Px*FRXsI-WJ\ -S4hيϊIx I`Kl6ϻ4dPZyj"y8Vf)*N -}4R5 -Q"x3<ƌ ќ찰ζCb:͎c[OS[eyy.-r[R?ir~B>verQz4^,"xv{O"DZ6""A!W kw-aa_c~.s6 uG5Y\Vj;Q%V' @PJ+Ӄ(}n9IK 0(r&r9 |;w}%e"f^=fsRS-2'ܾ_2KrUS%GKf}γ _52,qN+Rco.a>5\8p}cm V=a }Tng|ZhjRe(*435h}I;Yp ,M祫ALA~vԍ=u+%77;n e%ЁM ZҊ*uy6YQV*^Y]MUrt -6g$ț>D- -]ۍL2u,q(gڲeZEx>3#\ J:vJTQ|N6w;G : GBr*?Y90 -=NB(`1cL-Y9vsYUPNP`JaGA3 -'Ce#ۦ?!}ÞX-Gp4 yMQEÍ*#],;V~eiѦ.R reKÚ[Fmwb -JĽ2RfK>99ǴS(4KGY:\h& /֔@5hۓTϞT|noaVcfNˤ+0%D*kN>G1BRĂb(\J!Նzg\$ϯ1:O@>IJkƑb*hMNG^FMcuw g D6cmv4pmyE@lM:N'8q!i~zdHD O {ֱx)]Ы(xZ'ɱo(htF?v_t-rxVZQ)t" -GVEէheJ}6Y40!(n~`΂}YQI3|# _yK9B_[+'XBr,Kcqu=]b71L?׮AQ=~Z18sDqr@F=GבcH^~taڒ}s QZ@"Rvqy{]G`)h32-w9 Jo[Uf:dNT>e7b "[2RPt~]86m (BxL h:R6@ #io\HXM;ީcvk? 귥R%J[ş33]j^cWr1+ٰe0^{D3igIk^j)QsknoZLKH{Kbm5',zqiYƪDݜeELj*hѶ $o؅wz -#lH-CFVPaFjKD.o.i'Km'97X27)  [bJhX֋'$*a/N$jB°-".IyE6d#b+Ga ~D `mH2B1zbm'w߻`G_ @&ȧ2PJH2/|' ^goѯ1?B,H/ exS 9ZeN:J '{0{ -2?/Lб}WY n3!5(rJ 4t_CZehȅ|?xJ"$9 -.PTD>߆1c^}ǂ{Bz%1zߗgr*dž8JK0~E!>XE)$b8+ M[YL늁\ʅ~OBV#܍;ޓjHOZ*x$h"W2FR 6NsRo9/=kK9x0l}" _ -ƈƘ %HZ}͗?K#OAkWVuLd::Z8g /TŴ4ߦB?+AH.EdjbiDg)D%W|*J\@SŧIoTKqz4}ic¥Ny 8-"G$WBפKєnn{oBךOso9&~F'5+W{+^U?H/y7-k 1h]QuJʂ2^_,sI&Rva%$KP3P_Z; „Jhq;uŤU!nU.⪥YhJie1LHb+aC*B S#Qܵ.8!ڞH|%if =9S=Z!pߘqk#tG"UHl`Pnxo > - -hK遃MZ-ZlsQ@q!=׶2x Ï= ):(̑2fj>Z*w}gEԮ!9a>ZI'f"@Ĕ,x?xh|11FaMb49?'Zkjz#@ )r?]|z?qo8E{#`}P!Y4g< -8̙ȂerSAp` "`C>/t{̽.󔝏$HJ=\S@,\BCiW)&l/l#ے09XbMD/ϑ),F:tU+l+ͺ3f-3yi$Wa, >ίng,L~vSvXr]uf U5$Rp$$!QM]z{W <(Z*3 -ۧ ӛNѢE - -_O'6CTWU%w,`.:2wm ]^h -c'E|`.&Nll8E:GM#ނvä7'WwT -Z-  Iq,w73R},|5ha$O#%{<3)%sY3yᇭ:櫀Ә~N6lQ5qϟ56WKpD)O5`^ruTdO Ӊ499Mn_FoZigY&0˾v2*4ʋVOQܔ6cڦ`?.X*;A1&>p&1ùn9in ~`m\OLi.C I=@|a 52'{S{{D>QnTyt4zu pdWX|.iYʕCi ySOkڿqd@D$[1 -uk̀_Ðw[_S,OԆCSP!`7)+>D4h2V8÷wvvh7M -\G)tnYxznzžl_6&5,]ޟ:O.ej草tq䌓/z~kR( W8p"Ǡi -ez]ȟee#F(+zֻ=eo=CA yñhG+􉃜rEUk&[;JeI}ZD0 m6BŽ#U#EBPɊy:G3akؐ1(eqjeNS~8(篛B =Grه rOH꺏 \pjlyvb?d .ATqo=^A oy .Ts-19]x[ĀG) -) R\qWv%/HKr|ntLO_:yM)nr@*7hkpc8m䢼TRF|Ic;4`c[oXu ]F4Hxv\a"`gϺoZX+r~WGM)<@7,qC\Y!(z2" `)XOCXQ~G68d/.baH 1{ - pPslo3d*3%.nA0t6 `LZyA'rMj/XdEIO(HƂER ߹8tXtat k%GOj٪P56/|K`G8ҩWG+5b񬟠 GAuwiBl3b"qhT#_>D4uA>V;B])i2PlI. |”3B{fYyx0>M^pX~B@ONr7q=[1jLedJ9ET W &G $pY^BH+g #r!JƱ@W^㶖g C_2=S|Q5 Y8h\ CNc3;-hX% ́)p ˘*ό!չ@ -GZX:biA2efi44aVdmD*DKh{sl#$KF-/.0!LLZ.C3#juAy{!= -"٥$[Mxv]̋{]49xDool8@0"zE?[ -P YrָГ^*FW%z*"ڸ0rhK`Σ7*i>t?NϠE(HR#$r˾oJ ]jdM0@ۇ0^y0<ߍ -HnPSNׅ }rH5=p$uCuxVyş[9MpJf@j]v.hð:fq/i?L4wERQiBYj̵k3łٛyE>7bzgKS a8{AbB~V0&9zkh0R^h_LlnAd@B.vL[9A?@c |gOH -7Zu8:LʗKCiFfv$&e bOFI*f0ߺo9$)Md!C, V1hR~APm~/c= ˏ kŘOb26u<06iV_&%BVz/wOXa Cኀ WFD]Tk{F<^nӥ` oe/}tii7(c,{(hyG" -I -F<2ؤÜ,#o }қL9?x<*!Ebx̖}]\KPSn]eh#ݩ q^ t{t˟y|mF~fLVRwV$ Կ"ʜ&zfPעaߐX=:)O\Xӄz2ujCt_zU~5z1򗈩U!U*$$ )-lʿnzBVs -:|xhQ0P!30hg|;?E*IjAB+J@SR`owx]QX6I0;:X3mdOLȱFMgRiX]ohYaw|ޟo ze5IhO^´ϖPuS9!=)4WkcT7`qTS1]-jgG @]6LZ՘P,Е[ujaĖIt8&|:s8Xz76is0P)&gy/$̡nU -T/U3z2!;/vԩpwh jdJ?Q`ihpq Cו~,1 rg^@wx靅C \|ܽ -s{> 2υTR5"Αc gZ!vp.`,J"^&"굎tVci-͞[Xˣ<R%7/ -bl: 6+.&x%$ zwίK1bq$—{@uE4MO,nJ`};0ypc_9C"L2"Mv9b溮k81O-}ZYTc&?gX-zMK(UySauӲ^=3\gIm:u(Џx:rqXb2!KNZ@9Y ¶aWd>W\MTd4v@hԬ%#$855Yq 4 %5c,(,y`"-ib ܁ {d.OtC]\ƞuJд2!AE+)\EwZHIZ&`c@|k7*kh)!(؝mNE/9!uLU5*Jr +Fg.O)mޭ5◮ܺdԫ,\d%h\l*ۋW)$}KcC!b; ۦvH'8 PcaIԗƿ2.ߦϯi2bf= F`>8e|\]>I`wv=Fm#/$oi_Y Y.`r;Wt^1SE/NP.~+wp5`Zekޗ'׈uOrVo#0Ű!g4J(6D eLVyR乻u} 4(4ě. Ëcp.Kбւfꎫgƴa4<Cgɚ?!īҾ0NPޖutDclX,h\cC+ՃX:CL6%RH֘,},o`+E3 -MޭÁ3$|A9 p&O {[*㸡}~Gazigm6-eÃ^ VFT{)IvWlxh8/%G NaUs}ɟ/@83im55WP2+6iҶ-dG+lNYo.<s8ͥ"t+Q6 U_]YL?7zphBP~ HC -Т.dpfUҁY"P80<B푺`d\-۲ͫ{gĎ2XF1UnkE~O|q]Ͼ\ޫk NrP¨UK;UճK=ШIFj\iVaÒ}7Ā 82[YFJ`C֐ 9"Ӟz9< ECTTax^%QBF]XMh*?lw4F(fGHj]M_ B  %.^C[` Xlz-G#~L>Ͷ*NJX'%/Q/O(/$]xK{_&̝S\Y_7b˚%S/z" S(lA)o;a )EhVhxoG8y=mf3}a ̨-~8aƚ>Gxt8)ݰ\hW_>/{4Kv1b0. ɔ @27Nycu_:%VkӢ*(3bD ɀ-Xi7O;Wl*3eh/svy ʐBOkzqתrFaҗʼn%Mx~À~@ -DYÿ^V㟀慉 v/&v$GB ۬E:‘+7,:6~#3 9(AR AJf=MهVöDQ@`^.[2"IG@%0}Tǧm`t[w CIsXl.s)Aͺ=m̿ 5>i'۾뉄I=ďSI~#tC(W(v~RZiPH,RZƂ٦A*PBVFzg[)$$IU -Em!JG"%tsR%щ\/hG|y쥥O 2ʻ) !O -Pߧ-߉͐&-"fުX0/~֙h]ly|ofRaNBBx G:0><}?4";e?Sabz;{ 1z"b(|, :f'.ygg> E"*)/% 6`g@#'ў6SWCsȌpiIv,f$ޏ{G5띡@9YJvuua(eL\I嚽OUi'BpU ;,pKm% qBQ}ߙTAo)whd@0]/(+Vx78` ==ϛ}G - JDoL91 ߍ1/H/-pq+{} VD vB`jè"YͺU0D: {ސ0^h~dRu큀!aϧ9W57B|ơ@ 'c?,ny5D6kFg|mSX=VmbN4 -cB 4_iҢ b`/0/?6Đeupg-$6]qpX (U,:X"rd |;17ؤf6e_zݦ1@|.'ҧe:QyK19 -#6Acfw_-;&I#Zڜ:XuF;%J'ΙBD<HZ> \lXТyxO6tN1SC7 -CO+Ur ޵3-mY(HL"h -Iɛ85 5IB!m&3*U3 DoS1TPlTRE}SwP!x㟱ʾ'Iف0jی!vMP1ϺYću&,lKvЏ -,(nJs%p/" +8#+(")Ո\ >zS$= -cXRنٙ%=aDT1vpC]WJa -|1W y:#}G:S$_Mێr6ujJ?n)8)Ea8op h."J:Ѷ_ 93wx婘PeyZ@"d)N ;a_\u<|șnx\yT;t1[Ɠ; ^B a@.H.6LBrG/9L)sAec.:[̓/ê,?[H $H?DkD5Sk\d@M䏂h"|m@s`}1npnN Ҫ [~[s*8 a+ԅ]kxbzjZc LЕgvF!ܢ)*^IHw> o~F_#"=c\qk-A !>-w9AzxĎ?$ߣcgV;GfFUpUjm#H;kKvܢ[a=A43ƊNuS%01#@. - {Xr> [r8 Ёybc%<|n|qm۳AyG$Л?Q{F&RJ Q.& D0uaa _k4:똸l7^`Qupn qoQkP'[5a5 -%YH -Mm L;ų :9 FUI 5^6qǍK7 ]Cbτpi<ٟF]߀gWfLG0ǏWpaR/<1 ^*㽂+>>IQA[5,;#wTsGu+Fns+|̥}bFWzdqp"G&]nD ~ )nXӦulMgf*N5:A7h찉 (9+k$F,Sd0BL>Gn_SfޢqDжu[S&KSw-wkeO BўMl|yƓba:YM_pp^QxqrR;to.p$l2e%Th7xZx0jv\-ej{7BqL!x -6J-_TS;HΔ@.kp߶3ppI&-Q1ڀP]KVx?S7 v%I`.;יSaYW3S?.tv[DwFΣ;њpTL ) cR:\+hcjSEh-K̗/ 4{0^BT?1p'|~`EJxϒ#և"5r}Z: vo:>AOO} aPUuX/nwJd.:DՏbRGt&#ZD|&s!& !g,Fu6I  ]$lrK \SK3kz({V>zsLҏ_3ގ` JNt(,"‰ѣ\s)ӻ&6\32Pel*jaE7FW%qئRY1"b xCڮx/IQJ`qG`t~Ü'ˌ,dG6k" QMYgӫwu3p(~Q"$$m -]r09:7y6 #S)p09 kr$<ZtHy9\ḙbN;} (m93Pۂ%J.VtްL~ {۱IǁnQD[qg?9%r- n2Ԓ 逪RG:kJs2#30߶/˽_MHP7xf]i ~O"h P` SyD ,ۼSATqKV;aFAX+MR2`dFSA^R dFҠ+`ًf'N\T8=q^>LQub!1+m3QkA'{O_%0ߩ1d$R3E_W-x5u($2HQ\4}ƖnMTl6Vkm \CToEۭ#Es6,}`WjQ]H")x ΢[{|FR|XDqwOYgՓbN6)NHu|j]Ld s46pM/FO6T\xXA[ʡ,(-v]K0C)9} 䇗A} {ȥےNf>7 )e;IgyΰcY-:N撸 ʚ-Jq E^,|ʇ+Rwv#gfnYFTPv'SnOlYw..oBq^O;M@]pY#*1/ B ,4쉶 -ƎlJ@ISaD\'*tSΝWPhQ?qMGܞSݱ0zVΝb#P]sHQð\VGj1ZR NN -jCJdbYŵÉ&cɪF]&s(8LnML'U%k,@œdZ!TܖiD5CZ?V Ut6*HT">'dLx1 @W FHS*] -v[ASX_G^4ʮXW7 !D -.( c7 -cqqS -`W -iͱwjR'>t~vfBUK~Q_@na X7d޷!ɄP1.leޛs?qhH?⩌9_m,9|p<ʨ,i6JXbYQ78/ONRfd6?͙yQk%^#Ak=!!?ɎIn4"VǽT^jd ٪ _ D9ɉePfUP}p[vG57IN$ -Y@YC/kXgǘA4+X#&*Ȧ$Hb&BxF)mX5T|_`] ->Kr%|tSӔF mvQş!nH %M:9vGFh$([Z|OPTO6I6-"vʒrSkg ۿ o7g9B=2t'„P)4߄Z\L!CPCEe)",4G<-TZQZ^XԞ%)?hz*Pe8^OZpTC:V$)H} PՋILIgϠ? 7]iZ}U4GYuڐXn&Mljrtl#hfk>Ȗ\ysU>(hbE~s6sreT"#}˒ӚEF @ ;0qSŕ!ҧ!&raR=/0 =`gyR. Vv]25˿uqDW6sG%Cf%)f2r= ;C+̟F^ F2HUl;SzGUX0;)SC[+Ʋ"q̀(5M*a-K.496P 8*nM>}WzݳJpxAHy~9ɌMp7ßՏ$ rJ3c'.1sGwn78#6\A6\G 4"ݎ. ugɃcتc2b!$C=c*3q/m DYNq9{4,JC.Ю R)H%2ۑ/qJ+A0@L0螧7J3O^0S0]X,{3,{|w -#AVG>Ԅ5󓛑a͕<ϯ"\ N*x?? Ir ܗ RP65/"`Ұ3UlYLI+H!0ʧђ' 9۝%Vϯ $G[e9(q|GuLj%q[ ^J$E@_9dCʘ! -L<AIXr zq3J,}52#"Fi5-7 -<"5U>VmGe,VGha`/6-c9[ Ű# tMZ]$Qwücc+hg 1Lf_\ -b-Zz\=i qZն!oEC:A fV~x8$G)8NS/$,Li!} HĒ,]YW R$k%sivYBߣ'*X1 v(w(JA1b̠cдh ȓ.bhˋ.itRcG/.UU'ND -SQէ9%Pv~SЅ}2(RF8*{ylѦ=C).djOsGf5d@eXr$S  8s*35Cskdp9YZ=FGQ֯X#x+ߊV{Z -G -ǭy ?jG i^3gu +^u禹 -:MB~&LGV]SVB7N ֖gG)Rs*vre|Zὔ<ҶV!F5Ǡ{#lTJ+RYR Ii1W-ƥCuPXQ~c AO[ Y޶)Ĕfc7J總DZt]\EjH72FTAMVjV't3h)4!5BbNbO,&y3+`e ΐS0 -֧>R&]$7.\;mzAӥU1Z4KM\^}1 -x1X]*<GL1C -JZXͷmSu:+t^Y~G9<@[Բ}y#E72?ܙC3 :aZPH?0bV`Z-+VXl8B:,'!vUic42S 褗9): 1y1e<>—x -P 9a!:m G/)A2Y` >2a.i+f2E:O)xZXgd2[Z'WmYA:d0װA+}l 1g݀Wm0%h^h}L ɷӼ/E[!hcFO 6:*f -ΟYCd3e"12꫷cњ: #V$]؄K2BLf\p)'0hTٔ[wʑ,UllNeUˠ:La ?4Y`_)XGӂc"#ԡXQ\Ol$- \^]y2 |l;=cA .׸5Fʙ#WE_%۪E5N*uplxJURV5$wdP?*`XBh-]2Q}}G F-}˥q/DA;Zm#Px$ ? rIׁ}%`DN͋!{U2[Es?_[2ߏVILˬ!;eUaL` -1}絠z og4B#-c,Pph܏v}j'r攄$X3F6I9el\^BzXfbNF"=e{P- -^TOTı$!g&QAV]Ov!Ƿ6z)d!Qkk$,s|Z%#ya(R%2l0vóM<P@k6SM`5D؆tD=b+ZR6@jzrD ^a"zDJM-ԆB( x]Wf*|Ǭ -ŻvC0CuN1x \*zEs>ϟ5?%-7U&"_K}i݈!IM4CM墅nQ%s`q=+qlvE=oiґ&c!&{;Wb Ɛ N*Y*r!+ou9VujǪvi4hbf+3V44!V8/#fсcltm(w=jgDc4w}i>d0&F:vR7AC0PE~"2Qq29ݼ<#t)\]Ҳ @(q=nC&E` #ԡt:\>&06|f24k.gn*Jō潴Eڹn[t:i[6"qhfƼՁTdtWǃzGM}]o#'^דu#aOG{ ^|a*؉xq@|)(s\C -L/Ef1[K3[ʃ>+õ3:FEϲ= -w6 p,fDNWiQ4#ZfCo^ -2+v(ě ".9$})ʺualG3Y8dXyOCLPanj|qdހy&><xߣfx;G2(G/iBm?l)Yz{t}l?(( YCx7<"}ԁ*"r8]|P5Nf|Re 35 FӜXEWܞ@CLJгiF2j%+N5| @|p[,@u!s5L3 -YJMrd jU%RY]L `uPgG*ؠʓ-QOKd4PF2'c$0:Dxwk0f!ØvFy@d}0А%ȭSH -L8 eF@H\24U(/Q -~`xpq`|Zm} ( H6zFRCYjVdVus^JfW|Ԣ7 CԈjLa' +O֥o!?+W OZ+^çe'݈p_1K)T C}\(J` +u;Vߪ4-QK3+я_5V$ϕ vbn:&Εjx "1l<}CCEГZ5hϪff!(E.>nmsJ߇V0)wVز|j@ѧ0r(ǐBFboۼXMO|`h\Qf#$SrbakB_)ЄqoQ6( Ȉk8я{$}om9B%Qhu3(Pì1_^"Fe=rNKV7IKC79 xB[35j֚6ʇX}z{+wbZ=Q*l5aHwfA:c1;6&'[~0s24oIN8?S_;8.:eRbL(n}gC[zG=JwE1WtVyf,ca2epW7i1J.Tt< $ -^Q(Ĝ5@eݴlREKbJ=M 4G(6}Nhn[5.492XM䛣t9-:Kv1fT*Ť?5^^o50+ZjjB hr̄Ǔ݃c˯]|ӈ!dU.>EkG=QI\r?,'?I$ʎìԬ=@{N}}v\ g;_^U5}`KsC7?(@8"X09HufױH:׃j眥z+7,uu6 Y1HʝC\SZӞOg;%)M=1!ԝNj]IȻ}mΤ[ ۣu*L+HRc(1.34F͠ ha}8@g)|[.l > /2KAMbNGפ}M1ߜR^em+S~w/]h - D5]VyJb–qn - ( agm߽wZ")[c$4Oua$E#,MW $k!r.Ɖ%$zk]Z J)R'ݺ8>,5~ֻ(T[[s;Q7D{ԢMN6#ؖȀІM'8=ػVnR['1?o*Ƞ ݝu>91/D4G%m (pi߲6[3mJ5{&$g/]zQ.~zofo7n"D;"Z\]ʪ -wˑ MΓB5o͡`e6֏ހ) -vr\5IP^q?^1, -gQ6˨ڎƝDkc ƓAx*҇>b{c*=^wRљ$H/mF1Az C3f_ 4FI~.o箖tlkLX079aQDҿeDJ7d'&hP]Ym5MIM[FJ3ϝ%uΟV+='ƩT,* @Hk+DLϐ͵LpFNR·l,C+㡰[J[wjVk."x*pVjJnSe ,^rAt֊%#}GSP$< ٴ;FZ~5p l'p"PCK#pC.Qf k{72_t|>eټEGv[?|ҖvA -XB1'eI y/ARgǽs\[~L_%{!z -kh >{ hJ!43WZ@BǍӭa6&Ui>˃5)Z "LHH >-&=T϶4)# :`g}ۧ `r9sΓy3Cb&M@.jC1PV3OPt;#č 2#|!C̸3 ̈O+g'ߦԹב Vch;%KL<0iCq \:\ u &uc"hEjd-18 %+Ldn%cJl;gZ,r98Hv5$y eLEc „F)#$ -;bL"=l-^gc)eݿg[kFBƀR hkm`pU `vc71UMⲯ5=7JD.̡ƈ#!\axH<lW#KYm@E !L1ucHce~g`y=M+tʈC"k@#CXfRc]u  (l?(}\kNh|,ʌhj^'[֟~+LM& {@\gD.WqYӲ4 -Sቚ%y_Ώ!'nԍy1%}!^ - o_Te)D - -J+H'ngʹT'S˗#J2xBO -݂q^bn -#]XW7ǩ1m`.N5Ul6yM:jHKKdO\.9kan$?NaC`y^ fH&:IF _:or ˊ}SvzBeG4nYru  V*}H[kkgrKLwOW?)q^G-h! (ChhםzDr -Zɹ=6,JbqTY ++Iw10T<HZF!ҧ ~q>(BGvVD ώHNܜ ->${*z:R5JR+V4 -"]Tg} 6c2p2s\TX?r-MFu^&ykL,q"i6ܼ1~tLXȨFT~Wf?8[mc@qx8.Tr5 Azl^FWQn)aỉi_̯8 $q{,"{=u5ʋN/{)XEJקе*Uv7~Ƞ‡G xbgg -u9<߾vNdHW aO d'^>яm'gBgqP˘$fg ePd2=d"H@p4 ̱we]6ٕ<9Tp+e Fz@a7Y\)"C ?;)Id`P`O EEg.uO }_w9$|DyϚzl=4U_>B6om9DCN:."4C%s /K΃]Gqٲ7ƿ 6%XN)!($t9DUf?SO{Y+P jfD^ꭱa/:ڼvל%FbO0So5zT%6)yVj2Nz{wHJZE+Ug[ -?*DQ|6ej8DnCQkX{|LYcx]@ë C?Bt\-'N[ɤ -p Wx%BT.Ȣx۾OO^'70յwQ ?dWFthP/`UhwT? U![g@K_ -ۑ˿L+ U">`G:vAΗG\\<6Uf4JJ)*B& K)+sĆD)WgqWiYS"= S6҄@#B$y4.~|UBLt$l@D@#YfW|>l;nCsMѳN;c7; &ttC8>~"Fg({q:&GTo㣔[ -"/}`ZA&|T&ԒTm, CAܢK(W Eyd|{ ̞;`Xr -~ڻR:*O'x}gl!3XǮOMt6HPpim5 %dUq*һCI^4At*%ie,°R9O!H9V=AQ+hU1,R!+86( BmcRk%Rrҋ=R_>{Vp|;K^f2 գ򬴪hG|ѝtò|IX:t9+Yy@D*pj#WtfTK YkΟC~Hf2rZ -߆gO h[}`PjC_ƽڍvѳ)N.[4ـukbb@4#pSzҷB%B0!ȩd[f D2IC@4`Le(w9wr%,|0`5i4|q-tһ~dq5/!aK#,kmS^ [3ro4w- -R sju ̯w!{:4k^݈Z;hI%y`ۦUkϛg9 zAstMoLٔu/Xj@षQ#T}&KOE?3]dZ -fz>÷ DMtܖ&J6@?(,Z89+s6j(|t4e#4){-St$ddlXz)'1#ܮs -NG' Î>([ZKdqǿq[X'[ TXz aWp{7;ZD /zYڙr|>SؖʶqCyKp1 %]^_'m6DkJ!j KW& /WlTVP#>_4$m qN3hOhY^lT UЇHvZ\6 -*ls'2|;ښU0/϶ jdϙa]e\;za;\n99HrFCmk݃Nw~@ΈW%_Rȓ! ^*d J}ɐ]V H+RntoH#faBo"hn -@Nx5Gcu㛑I[!9,03L|c>W?4u[)n3jcPB yzCx^M-L{m%t@Z&(_lK%;˪:~8qYhU[:dSXKtHdWIQЦi L\B<"fezedA*!Zg=sϲ'6GJICrxS8艢uS@ᬧ&c]g+ - -d1r\z̕ɣ1/hh y5gepQǡ'4M*1k9 ؙ cT3Jz2)e^ v̳&aBO4i#pSY(̮7`xW ?ؕٞ2E%u% C,(z{l* -_, R zzP;h:l -Ӯ.xFZZm3%Q$ KbmYL76X^1BwZT`̽Ⱦ'Vv>m1 ܢ@!rzb֙Hg㍪x?,H; fC4|2*oeܟ錗n*jA_! |h*'%2'l&Hwޮ\`T 4MwQD_8Ʊ؊; O&Ak^\jtI3=& zaB{pgtCh#fB[P P3jLes+ -~]Q%A|!}Qδh,EPq0=~Ojo2M)b+wX} 5&Tf_]* U5r[D]dGVyxCE`19uBi;6kAyMN`+h&]XQ<1D,P$U/OEb{s?)E>u$\H%%7E-_.=sSN1伕}^b0YwJh D/Tfԝ'p"ꃡ6ira -}yv,Ġl@wctvg*AwԴB/% $̶z_vvxoJQkѬ o'mUE V')0IWoa7KcnϘ,t9;{،#KU;}ݜԚ -zṛ^q/޿fdKDg->v^nˑ9p|PB>6J~OnJDhK -G{*ߘ"o\HYk=pzҞ":~pMii$t0O(9 xPޣd@Xx9(7Ƒ[%*~YYA,BLu|l[A([A`~tuUpܘTX8尧qS: (.ΖXuZ?{µ 8QfJhr7:k93෰d}8<߯pgb=}N5ƅeezLnPH&j -?ԊJ-bL6+E,wA]ySJ 6FإlfXD]JC [5y%iQ*-t9g5)X'F$}}96]n8jQ6O(N"u8tFn.z++Eb -VIA oп̂JhU8RTd]% 5C}/3YG 逌 4 ]݋p@z'R!aZ,:}N@[c-tZl vBftdb#Lq FhL#LjɫW>! dʼͷqi*sOcq0nFFnM+lNcV 5xwKٹpcRn=jm -nNni9Lu#iiD_ d4Tm0jRmH+m{3.EryY S'Mw"Cq]%\73tJbLaJڹ"J:i׋z{j0JzLa+hy# h85*fW={վ#(HVES wK^3/8@pufS# $6xKFo >hlȕ÷|VSWܼEl׎࿥Gh?X m,7Y=G9D{ AT_7ODݏQ(Kzj^7/cl ^HHiRs_9:BxK8j$= 1AZK'{GBݳ;_=@NZ|ڧD6 -#'(nd_Cj zp\m\q0#ZD^Ť e]|>Bfҽ+.hWpb/KA;8/t$0FԼb#ogApH0&=)bRTΜ2a}q:=? !'I4B hwO(gNI37&M_VbIUN77"y|*kOsxdf|#YNތWT,юU)D Efiz)pT2fe(p@̿oP1߼8N -vA ՍCS[7,5wB aT@ywwyr(tڦ2)rX,: -:ig=-[P)Q1+=P(.ްr -D<*E\B,yP'f'fgR) _ل" ")1{jK}O}f8V2ݜaj=̙Dnc0t#Vnzd.Eگ&=jI.`=\t @v_AƀSHQEgC& <">+S*e% j;<")ݭV՝^@#ƶ R^V?8'',{8I=TZyc% ]~ftDB>L]ڂ?I"FG7%Eb"F0l\.p$=uGY\fR>81\zfV=1^G9ERe <ĥ6})^څ7S20㩮U~ykjS=ON#bv4 gP"aT%WT1}8 S-1!o@OBOІr%Mă@iIVP`Jb[UCL:Ego -E2 3^f rVxKCbOIL:_'AS(HzXQ=OI#g#! -endstream endobj 161 0 obj [/ICCBased 218 0 R] endobj 29 0 obj <>stream -HtK%KD繊@f{#@,@5҃GfޫZ[{|i?-8si?m|}̝}S;n?Xl2LvRbuˏqRv^7n QYf=us; Z放k~Ζ|ӊƅ#\G|&Kg -n̉w?Sbw>'LlwM?v2`yB3&:Ƿ] 9Ǝ9{55;G黍qٻ{:~QD, ψb5岏tא{ݔvSQk̯)__-qv -;&F:%OHC"&`P\m3&H[eǀ6 -s=geP, -,;YL s̱n|j9gb F>-C Gx&8褳 <}B '~%cB'i%$n:Sx --0@gJT<$Urg'☱N%w -$>q[^s(&4#COG? >C#xG<1첑 KI{S -09%قLIcP#G2з$ Ti?RNr7.ϐgO|ȋ,= -dAPrbN'0ФL39Z6FbۦYo~' ...|n -i#ԋv 0DSP! S&'\\h& r9 ˔Ygt ˩$*3 35Z.0`$.g.*OEp&b<\t֖U BJU>l߷;$NVSR,d  ~sٖ\N$L WV]% fR0 -3UhTbQJ <4/ _gT˾NU_3#/re Z]ˮ#,g G җU{Z[x֩>Ңg:{ЗXʷ,09Ӏ.*󵹇j3&X*17.SaKFB6J1<:Q_e:A%^UIb`͉ 8$ssRKMѮ.#rН tB]qQ7]$Ig=.:= gb,I#bUCr[KQup4URs] -uɎ6]S-s:DEP 񯷰 \L a]cԞ=y &!JI:/\MR+bUK rP-(3"+HIqmdL-h,,K~W6|yQ%s9Qאqi=Im uGқ2_]@~0TrF)z~WĘW/ƣ q L5d3v5XTSLc:E=3!8g; -}?[5s)?R(ޥ=> b)IM-T'dMrL9=htezr$Aj,8TUrցU.q*'F6ѥI!ytޜ0T)wȨL}/ĮgksgAV4޷:pTX㉉,-+-ʪg3s%1jVגB[1{qzxhdAיcyhi( Ѡ]<_ ,K2. S`&Ҫ4hKg'A0u|.XDUj -a,]OAX%&GcTďU㻤_Daɢ̹hפ:UrfzȮ|؃0ޡnHj^~ -ɾwId%mNP)ےccJ#uJbjL^3IBi - k1vbvÍ7%2>`)aFWwX{(zЫz7Oڝӗޤ⫕gR# )j.?  BJl6M8B5#G:dR]˹ 0)_wj -at|MxvW\kPY풿׺B -8 ؏ A*4x+"Z;€ͮVc&["Ӗ a'iۚ2NXBBv ѼN`xD1 -]U$q": Z4PSf0RܑoR(KlFŜW@-#í/QKW;A9^DWa%D) -EUaXW=j䴝*\ꛘ *a;pOcq$uy4kwL !vٰ&Z֜$4x}S4F&R4r -!XZB6kq YҀnRxB +6v& @J @>B4 RJ[Bx&IcbU_^O|a%Y0RyzP3}xv 4G*Z10޸rZuaNW1uթPYB(Ln/Nd3pA9؜#m\0545z%Cs GiS==I: -h ˨jv#~$1GC+DZM\EEDĴ,6tJb5wfX/l1/_Gl,p#h#iT3 )8λ5E űAPZy3b~o,|ndH!5JԾ8z yK*u$PtZ3YP@8.WCѹ.i +,(cgw|N’6g¶rlJdU%:}_AUsdz׮AGx&ng g5Pw> n2WME>GI8;ɇe:&]jr=f#5L$rѩPa@ˡ7e* b.H#߃ɸʀ[v|J:dS 룃_Fntsj {8=5lqzi]/&g - 9];TCwi+qCy(ZH٧r|QmS׵&1+{^6M2.&̝ 40:)$?m7u_d+mn[do qPV(30\;0h6`*D3 -I ?wg觘Z:3 -q0d]4ýe)J2I5a8j3H\^)xZR,Q0QB瑕egj=@w.-³{iՂQhL)sǩ&#hƄ Ŧ`nLtNV -}J6x0w'AE`ucVqq&iC \B Nyrc=.ީ8ǃ3(cO );TyD1ڬ;iӣnDê9. *2&W;xp; h96G`kgn -Erj%rZIWPoB p:nVU|-I3h 3 a)%2=yGk91f|A\D ׺_k-~vX3-Vv5Be!vYifdɰuِv@C:$9Ff( nVx:o-Pj^V̞,f7,|/]@ -k1etZsUAF'YPl`JACvtNpPh:jy\':d2 |$ll)GoQZ0G / hANWGbxVi R#c.i&%DR|R F ss_h+T:&l/ugy}{Ń4E2 )W^|<^mro_] .dor[9 X8KkRO 0@9*rc bme㩒g"Ve\O~T6KHs:ӋL B@&#LSÌD)ЗRudO_Pֺ3HBیpV(!6{q+!x:%]͈#ʺɻ#1RSmH1v&X+uVNxjNHW kA\aqM"j[c)n5GVuWV*s 3݃VtfW=Kw|7,l"2OاkP U -:cޗH<3|vN5W>;*{[읊;h u0;voٸH_D}j *.B_?|ЂfGS捤A4r -!IG -"~tLWfbR,7\*:$g{>8-rpmI&Ic@ mr(1*yECz1R,e |6G1#Ka*qc bne4:+:H -rmߟ7_m.o\i\dNU#"3gJHgTb&3dHgV0UE`'0=QvnVBՌ{@*ݶ+QzSѬ!~?D2?v\('(t\37Nʍ+uen7TFi۴ѵ_mJaJ)TM5lD䪴 mMf&5 Ե*~(ZZ]2x#tJp{&ճKż[y|y -72U4N_ϝSv5P][g}s+J8Ҕ?~5E^CL8Yq|#d>}u|iaf[jB;{ ~EcڪڜPeAm6mJ@*##9<*x9|;_MT%@J'aPƲ:r܁CaᣮIk7o}].8C b=껑|@@sz@}iG8:ff5=w(!{BT<;7MFݢjY?Z<޸M^QQjhsr$W~VWa* CE3JVI3cO0\&4j {%s0w|6* NnȧcHH#3 i7HH~4^hӦ:ݻICZgsWuUCޢx:<<KfT_"SHiLj(\K#G-cBSWa)GcO_H~Ni?Z^jV>Ѩ=l Y{gk9*=N9k;E$Grw"J\ &|2 mmiiUs{U_Y?W5Hٷ[ Os*!%F ټ BX߷2rG5E> OFhQH`pl?tpFB"WKc+y& (5~tU*7LfL# -5s̋7M}@RVsp-]d*VYIGWx*&Oa4C.gA_M]#ZdLJ9:Q={tc{jW׊auvo.L6<=QSccL:HjXyFFVZB Bgr>:q~Kq 'o:6{WFMj܆*&5VCF^N6sC!΁&z3 "[nص"ʽ|JʽCd|O,s ΔNycءv[_꧷4Q:>{NϽ,lsKr>Vu61VҘ^.cf9\G刷ouM_LUB(NIg@㼴? Z<)5cWKD@L@h7}ڏ<6&a6ԼqT&fЉ&@ZFT虼bEu9l]ƿĦ1Jt{|g!,A4Q /a*D (:7PԺ%^ҍx+KO𮇮J9 W"kEC TޭO@OwH<@b9E{$PH>g@U3 I9xIIL۰%\{dk ֲZ?ƣք[ JR&9ДegMZD R.alp\Pk&{҇%2jD&dGSaSF3z;׭G=/=Z|mjqʫ܍<~é ySq jfPڤ\idω]*[g*FGi5v+sޮgAx%Sчcß&O7mR+tw,^[o0j -1ٲ}B—Pgl6Rv?nJ2eC\3d*/%3-bO(MM3J@wָ jƏ(g -;JՉ(7܅NQN'?}Äi:w1(G]i9gsŽ1kL?׎V~)aigw>{ڹǟd:qy]_bSХݱـBU*$)v2 .,Hdj -ǯ*L2"iNx઎2i_:)5Gֵ1Yc^~ۺqʚ+3/uJ -ixC83V :fI?}z&OX;x&J;D,&ݨI#R3/]9;ˍ>|jDާԳv;|`6qڭ]?T*m{ۺo7uV?Loq1_>m_?Hz:lQ)i=t(8)@EW ^ W6XB”$T I OCEQ(eʃ05'ؤN ѕ{^o-!zv4(yL`؎8R$*TTI =|ktj:[# 3t'dBKUV;!I wXxAM^?LHW=!-" )0C_+o2epb j9zj$hb-&KSaWרȵvfmigі;#(Z{俺Q"eh8.Χvz8ˣ+0%1*;@}bU!iU2ױp/PNę X`h XnX&og-X =)g*StIRZR7M/wVbf553$V "WϱeצyW=,JmRDsûKL@9ֽV{7=LnF!) 1c,·yq~ RɨښfNJW.@I-W6u5o -cV}[|-"EPɈ\Jn" a›[ے>.U?;n$sPFw逗9J^k;‧ƣi>_ug/SŧFRncɴ.]`}FV)HUqQ = XNsxX< ~%ؘc݊.ͨ\&2ɯ .EB897 -EǺ4*gṡ:RD6#Jpx9mw%DϬ#=6*-H&xm ÚAqz$8\VzBhв*z?Dorlyw؝y`Ch+\+kx @A^GP3yؚY@%F d~XHҷ0z "*I~C(񣶐(G guQ(';buaكKS7hrŸQވ0ٳYL<*BNccxF/J +N#wM^e%?5],J-s6$Fhx1Fv.c8|$Y5 ,x~(?ɴ9q%75Y9mkRmQl |"f̚}>G*5N[9wE)F -JmH=\D -8BA4)s@Bι]PJ> -0cJ26AY?Jp=E<>\0 - `=z[}aEe[t;UOa|(:gUvT6tA#ev4T )C|g 3BDpfU˓pWk)f:xfBl3B. O tVʇ7H2brŭ҈)4'Q@]Dvo4~?/a>9C;Wb6T0' -;~ .M2PwV-ZS=U3+Y& [h̎JJ`#Rl&MhGTJ RzH -ug3wpJW7mzcgrnh ŽK{+O`҈׈B5b$1xlqAB SI6̫QN7nIUゔV(g -W$̔l;X7jv#:ٵ +_:jNMP;BMIފaabLFP&OТvo,eDVjQS!8dhlB65xb[% BLљb;JQG$z7րKx@Q\=VX!|n6!)!Q17M=kJ]ւ!$IK8^h>F'avm\T%CAZO#Ag4<$GɃFm'̙3O] -oO cUu늯]qBlL40P1$>\d#sP6qc[|QyygԷ!V:Cc8;j{qq"eԙޔCoHw] 3U=Cdl.)žk1V8?:xHӷ09Dᶨ -):{FeD7_~ :H JՒ%"VC |";2xjښcF+E28CzB'W - ҆S:mHF0bɳQ""G \GҼLۀt7% Pܱp$],R=aP=ȇ=ZS[<*rVl#!x a/bZh/дn;?72©^=rʕwI"D=G -$ -s[hZQ$`}oqzD\-DĬ"=4@ Pd$ߓ4*{HבkeJL)Ԋ T)mjvO-qf Dۿ*ZQE_vJfCQ>s -|U]S/I+(,g8MM~Lu.-̐n %PˀNh%Un27+l5:1*Т UKBٮ.x~I,D 3a -FPڿ2ɒ#Ţ\ xZ֓SiӺaYur$7m}l)w4nCAX3E{"a(WD*209Nt+6{_yJ~Գ5 -[ F\1d+O҈[eJ0 e)VͲm+vu3Y/G6cN[Z^݇Bml/~cr}KlD3ONw>j3E;u;Q]W褠|>o6znO"\l -6i>q^Nc TWS}噃Kq!/|Lz&x]־S:,JeV#MYwQ}᪐^7>xAAsμzp\{l:+~c(IKr9īv -~O5o&|{4b)QId:ܗzt3_<=D_,%;`)мIо0J`#fw-- @ G^JOOFf̊6fLkP8[m)^+uXkҏ4os'v-K$Ši܋[ޠ#9!#VPv\W&KPqu̓VGԴtq:$zdR`(QeD9icp25]H ƥ<A$}Ob}a4{p41GAR-YܲaD^["bt3eJˬK |#O -gy3|/5z2SC[#SJ!QDH,kaE*ӠpA|n9Y=Ǚ HWdH Ebu:ȼcĽ{%if]Rޥ)4sZ30t$ڶ5l=_BaWLw.L:ֵk#%dJ_kNZL|dwU/YTe (s=:&2z)DrUAXo7r*}'BxH< 10T: z&bK<(H y-(j+.WWWS>'F( -m;F{+~m&^}ՖoA-C?"gaál/-c!;6(A {' _o.;Dͬj$D)5k@bL0r܈Aϒ>9F+#ʔ$ SlT $m5;H_nk`FHkMfqTrIx(,qdPZB̕)Ȇ[zKp轚h=7ֈie bEaͳ/Ŝ۵5(ێv&f.x -z;4:--L[N[+y^(TW OBb!|`?v1rFofe769d} d)A)~ds{s+O\0L=9,Gt[!Ѿ!nk`8G!Bgh[-t/^v܀" s.Ыu[u~p7sϙG1Xl2iWh*vQsƌ&,sߠw~mR8UpB#Mn 7Pcqꌬ[,ۢmt`~$3-g.&R$ { ^CƩT(H;40*yPS$9O{lY|Ss754Z*B20ѯ%`HK )s6歨G,8L6b#f6`&d3&Z(ᓒF Hdg:7aǧi![~SJ{95U,Nt 'njWt۫T]aJø9Sޣ|ABLp?<)6-cɘdNgՈQEm/gA^P$2GFCCKdPMC7:::!o}%4R$$+!/~j_-C#nE~PWEqr*[f(B{=i2eb\ -T*#gQxꜗJAr[FvѾUuSpCl+'M*5;kI)~SnOLc%Hܧ2M%`8OPpl/ͪ3mI;K <˺H CJ>/yY] m{*'yPltn~k/Fָ$߫Y4$n5}GzM -|TT|Oi|4<t:63ӊUMЄR0 E}^zJD.~_SjV\ Vh%[˵W|Pn/iFWpDaHW%̱ q()'3nߞeBro&Q-bfdQՑ-7h:eH`TIuy/Yڢ<%a}";*0-|ETr'b~k\xcu=]wFQQSIJT/@RhR0 䓭ceBό³QO z~9~KrGmObC mƂPuhQFy%?L>{ qGr#̘E;;P."+ٯQW3RJkd7^bh|w -ELULZgݴG=$9p9EIcER -#6qד {[ G4ڳ2^FLēݰVx^PY'Y‡j^? MITcVޙŧE6yFj3,z ?f&{@&gd̫`0NzzS(I@|ֈK`JDaGN6k C@5FL~~Nw5Sm(3něz\v:dt sZa)db!_o*h=fE^Gֶy9y2Vd@'(rxxMTw4}*(EMPE@.Vyn'oma!>׭ "^BQV;)vT`w7*fۈw@-eXr1@H4:OܓG)Qx: - JS9gHJңJG>DfG`(÷*}hzA9Jz:p7OHw&)j>M+e:t1sf IZ]1OA:oB+4@̿-JNcjZTYq;V~<0Xuy+lH{cE + -asZ}2nz;n-?P }z$rLpzJ\:㚿T&{~Tqc5BO7V8{О;Ĩay-ڼ-JY5J&n]Q?G5Uz޲V)!z;==vJP٩!3$A?"1Ҭ)y姗JODب&E %!~G2!7v"bkj -ܿ'C}P ->Uwh[~*Jn#vÐ5~qͳz>pg`bQ6׶)F~H-TpU0N*(D/&> -"rw ,1(Ӌ>P $ᭈ4ZUT%iQ<8ҽ0^_(4 Iy(2Hw7*:d4=V$gOw082ɵh?G&#[ٷC R";bkcG h'|Sb$V 1EP %GMIGY>BLƮ+ߕ;f]tOټʢEZ:sE iI3% 2{JVyLnp4rہg.WinY, 0$_I&Q&N?K'YGʼ e=KH*9q -pt٧Jjp( - 0^yU4-BzJlr)8n(ty]_rzՃm<իde-WoEjEK? 7uZu|ոv"J\IBbub:4TSM{TlsDG[8vqdjuu0asttYVsGT]:~%JQ·Xӵ -aUY٥$/4m_GIj-\uq-"A>6lX -:=EQQVomg4Y/#*~!0cHTőHdV驖LOpLhWuib| LFI^$T8J$Z|^"wkyP \-hku?%V $ލ\%6DS`>Jq[%StNq5 tК\O̪IRnb} Vp|YzQq آoHأdi=3G70xr hʳҡ oW0%Z0o֌U~'"BF0v'09 .JKrx"Wȩ3CSD?FF= PB ]A##L) <3{b-H$pAZWۑƐdJPJ^+X1r[ -# -_WZDw tMF e).5Eq4$ U6|?b,kګEN{ Iy]& Vv@tꑍHHOqC1,~w@q_y Vdv:_o3PG}7S<7hŃVs>85} W-OϘq:ۑ(c?7$u<2p:ULܳ͠# -z@.096TIg7'SyqDtz]a>nB)RT`ŶK5u;@.<>C^G.r6~݁D8@9q6Ob|4Ahj,뺘*iȅV섩HQw>,>|o/&;AQH'e/xi9Fð~?~ -p -ES߾-EPX{RB`~hn/1 Nj&e KTEڪⰬjNo.-[!!ƒrYw h,*q8s/#.%ROkeutef9Q~uy9tig jϱ#[I[Ph]v* 5S> h01`^J -Wf>Ͻ[}"/}nIIAΫ`0N$\|CJ0˭r`Z%tFD*L@5Zt,I9)>Dɐ72f+kbVz0,e3VbdZ ;{[ K۾Eql7nJԈ04wfzGc T%soH!B&=DLJ^ .+oTn&!R@}"_SLGΥU نlf -ݖe,[Nys>'nIrIY@")&)fT[qN<~M6}#O&LLlkk<Oѯ8RЋhZfw.FjH6 ~̵4ol5mV!E%$l݆#C/w9[kHqp 0Y'lc"8x:{FPe_j ye]zPCϛL×p -~M^K@!]NI?r+.2ۣB{U -;mVW^/QKŗQDQw$;F&_Så;Hph69gqf'QQd,VQ%6 -eU7N,ydK'%DhdX=-JpF'sVmEfS>Wrҝ-i0 0hk,0cajÏƙȸ+ML.tm0y'|+ܭDDYTGL_3[%"L} s4GvbJcj8-KiA~3ƓE8-uhVv*#(vbOd+ɶ;{EUݗE-y[M[S,#CF䚪lz+tQc";9[\ha'4tPNwPM`Cսp#8+<0)?t|~?u|~7?rٱ㶢輿,5 d8@<{ %@@ڧZjeA@؏{׻{ͽ}E;oܿws|oY7w!Qk%n3?{H-α[ڧ|vd}qڅDgr~ FvV+vgnSz]&rў_Wwkq}6߻,|?wyжT-e}o|sFq -܀*U??O܍Hx~' :<8\Dל-Л_u~g/֦=̀,8$btObVׁ.?#C,t+Oq@C PZGo~>+nK@(%e+fS+T_sQPL=@dTǗ7-]3-iEɸe>vUܗ(cEF Pkђ?2;4mCe$'f5ĞSӂAZPׇo'S= #sN9?_l-Qھ&"BWHdM(R$bRݡg_Rj,%6*g{zjX\=ڹa8C0W \4 r&2M+#fi);۱f6=ߝ3:}K62 -@ $G[qFR:c>hnL5XO-3p=Nz.tgIFI:90! JRK:6` $nl1_hixJ}&AOA\Mƌ4rdETaY" Ps]7]![b64*j2|1c0Pom7ʂ q^3uWFY)TGcE4+y - 1;*1ˏB(mJW\}o$K*nO{"HȌ$Vy›ᤡy,G/n:}Q~ڽ.'=2ΤK7$$f =ˬ=GD4^4Zuvs)5\|s"ӁseolUn&|m~h@/,GP((CYAMsl K|Zͥ!ob|;SӒAg Ih]HI`e96 -E4(}rs*9%yOj4[91XMh]sSwpmn ۻ*b| *Ak'"jxfT WlI[< 5z.bS"#KBa3^(VoVoxhLSi{# q">ݫ%.6qjǥFCxŮ0miX]/mPvjKF\(ZJ[l=T 3t) &to>W.gwcN\sysuZW~_g+=MMA;NΛ@b!0#|tMj*Ff֣xٍ"0M$ ?B,K¯+28܂ [N GjB|mC+ڶv͔^/NDԊL9sǾ!\h|9w& D%_O?_Տ~AUt|ꇃvZ D.{I5|%Kv;Npmeݔ!|OReܧ|( ;0ݜI$ YVc=#S&ڻŷ=FpWmA9l1OרO;s7ޠ9+Ʉkg+~p&!^įIZhw|?MW3M[ M$;N- vp|bӟ&0)G\/$ a?x̋%yI34nFF'ǙlM-8@ eQ< -(A>>lN&kKM kkUᱧ>JBͳ71+5XQUA:֙c>HJm- 20ZF+ٵt,@!L`'lVsZ)Uqh(pL/9cg{؞\2@L z$'vC6J(8(԰x 0Èwu' -5Sr8QLsʗ>>HͷwD9x唅._{&>*xe3)8!(Yf[C6 @a$<;9Vkwi׽,2 y|?O}!_$wi]s -qY̮ꤟ D'bY3 0wf~.q?Zsi#𡻴m - դ SzםbvWóbt0݂XDI#65$?J#.En_@oDd"]c/Xlz#xhtroGڣ'' { f]S=`Rwz ?,LTgh@#ɺzk'VJY5hQG^3e8R_is#O`LX0uW)0mH&-gcn, S7]i4W 8c :fC,PSHkRD-#JnosԂjW6[ ,gT9J"VPȖtOO>,YjN(l*Vfsz<puڙ:ް LݑèTDĄe ^Ӛ&516Ni w+#ScD Q [`~B`V KO2˄)Vj6-&%'er,Sьq-2buuەxw ض=PsQާ$-?eMTuN7Jaev* e -RApuNjD(z# -a2.ׂb3vM!Py'p,̢L}[/. -a*yN*v PN݊Xp.IS -/TYt)|40h -6mxȑz2:CbP& GSs:qroCmoC"Y?,Cه -C<(c!gD-yvV}0ɔBYZWB6,z -BR W= GnXϯm6&7Ƣz("M8>zVxjI6T^R0m/-|SdT_Y恪hdN:@I8^G­&/y_})\l8Vڭ֢PIL vP.@r`I=~HsegY[Οg2ޭAAφh҃5k_/h7sM_Hn0!M w1dV"\<_P߉?bɜ6-Oq%6?3l$4^:XƣJłuD֩O|ѶvKm bt99#3[kwΗSJ]? ^ctbV\0Eʙ_Uk!*7*X嵇N%ZcUujMbKvj5;+n5\ɑ,9 CоʞVR E:]{ǣg3(i?`GԫÁcĶC)+@#[j0a\bךvC:ВP0bY\Mzz_7kA:S"S*<]s/Ki)p}8j"En>i1^z1Q=,{q\'+4Y1W\|P`=a֧6*' fNL(T `j`Fj?al)>Fl=DhH.G1>,3#w!;N3qS<#$8N"zԳoC]@":}DvN"o -B\4+RIMrO5R-T6ﲈ >Po3iݝURHݴO 6w]ȑN74m\O \%NVc$r"PSM&p3ى=wNdH2)p%!{hJv`$@ -8u?QN=U52Y-_s/B5mL#RRx47vUO8P @k/2=1&Zߓ!Lf*P4ԶutTbIyRܽ/鱰vf@ijW:d8nAhڼ[HiWSI.oo+ѡ֐ -@Nɯn~7+ڜ"l1@hVBilk-k=bnH.R&Wo ۞R Xdrg ;/hԌ![PE kfKm*Lv?~ %s^eVry/z(M$$;GCn>6_>7lh`)^&1gώCO ̯E'x.+*vXKlqSr2+T:D=e .&`\fmRjt{%HpC`}-?YfLo=?nbC~/RSW;|w~H.b5F >oL3Gs_q^hevsnenkq[f@WC,7fg3{@6^t s:/Sedg5DӉW/Oΰ+(w0D후mY3Y;0{\EWпDRr)/"y~ۢG%D?Fh*q{ӞҵU2x?ш2ۛ+V͎^j㠩 Z:.>%ڲ U$l~n :~c)H1όG05Lbp<(HtۻCm|ôRjPƷyA8x1Dv?1H'Sܸuk1ЃdW%bKZYTҪY"3Kx XzxZSƀn|SۑӀ3JRs:st# E$Qk4 tBK.y8;b7_hF;_vB?Sˮ鹯\}ِ(As1i术`xseՔ?Ũnhjל|cbpAFٰ[ 4=j>܌:Ix#T*w | Vks9#W{nY!jvc2/-U6%2US yd)Lߡ*בlExrXH)^{Y=-<Ļb#4P[u1 -^у%.ZkޭrT>FQCcĚݲfEjv0bL{/zꂾ>BtTB!,dѵ<{/ :Pd&}sa Dm%ݶip',D&ׇǺ4PB TN^WU[lU}A!{NOQ}-Z FRV /$m=j,HkSLs1Bk6kPt*;s"8񦰼qZ}ovV>ć ٳWYd1}O5Ⴐ,]G9%Qx֢W\Ko4J~*xH+OyUi h΀Ga.i}UpwF:nz);.fي?jK+sdz%L:ή"YҺDNl8rIaI`Qk'R}3 ->IS91Q*cXS^@A>eoQv=F 1!DA萴cѷYMaPzHDs1=PIp=_|v$fr%]zߌCxbo* mK.{ $:u?#}3pbǂi2m̝ -ti7j>ON9@\7uG1Я_DŜqܚ`?\xL`)I[֍ -Oz`@H,R/ kv㽎 D)$&{;[RCw-{Tpn?*±F-衝;'8\ҟ GFl X -=@x <x[D?VDE1|N?r {@ uY#iL -+oaC?ZvMY?XHui/i#?߽7z]*(R馠^} [Z3VP]')M4|4aZjo_ ~(q*VaƃUW3<@d&1M]PbLUc'C hMQ,WH?@lz)bu8ܔfLMiͳ\Wwͦ 0Z9߿D!ܯ' Dww*9  (E|;}}[ <󋛅~{1kϫ]m;-$Puhԣ4P' Gvh%wذ+A{l\|ѓ$;m5J -F hᙆ7 Hhe7\kOcљ ]@H8'P7T(}dLR2;tZ8(.rM]N&ʌZ1Fv\JԮHLml!nxw~Ě`sŹS20~j Ot%29uԂD$X)˃^&OUx:ݭŷdKybŴu *( n7 C)']WY@~dI*)ZN4ƕ7-_Ȋftpu6L۟֩毟7[Yx4du05sȫx``¾Oz?G)ى7`ȬE*$[1l<ʀ~5> Xd -43]>ZQ2!ԭgEpfg}R<$Ν/:&qD]w}NR4ٕYӕ5* uSQkoQ^AMhћa+}dQKsu3ZϦͤ3湝c3G-o)9p,%JLAnwЩ]}av!"İhMV_CatXǔc^؜O@ Ua_jR[*RȎi׌xw]BV3Suz;u.Ν]Fp2_g*8x o DaFm'քV!x4jzM'$uu_-)j{(Jq<6DDҦ= JF4'bAMOOJʸʍ6C1b> bO۪t`Zx_dުU0{pdIx8/]m92>AO#w6}oQl^UKCaPW綴9H.#Qyͣ;qҏE y0gvռW6g3Lo@3=b`Dm{DXn̵Qrߺ4sTտwDf3C%<='W\Ʉ`4@p(>OteV*.>-uC(/IB!EΈhj {iÒc%vќcg搜45gM-EԝF7罹מd9+?_# ]9pI}W&Os&0=5m3 j@7֛.JyZhTJr 9v*P`dm#d͓%=+`8 l|U}{qV@ږF*dxGѴA|ү4 g~f-3n=ט3N(eZKEX8Q5/q:ǰ]$mV_RZmީc Y -/:шk_ PUX Nc_ H`ZKW.2Q9=]CC~Cj,6:٫U۫g]hwfĎb"6^'*uègB2/'wȟ9م6T_(Uނyݻ(N `'52zkmvb~%l$z^N2ܦX3T\e 0;Etx=u&b/C'{fUg+d:Va }X|z'o(vhS%A ͝XsĐ62oADMAB[teb7xW&] )J,`4{aAlJ?(?oYXz(jy)kIe2 ]C_cݯ6p囸rJ(s~ -> U6'Uu$-q<0Vw -FB<LSn[؉edH)MJ'82S'm]'$o>i6E/n }|NBk=EHY3~ݗf.PaoPZ|jWx3*ph˭.aڴjx[{ROq?9p%9"M 3nd6Qؤs -1l1M!N"-F"}HR/1x7TOLF95O@`(AݸVy*By zZ=s'q֏|OHƘdUQ2)REE?܆42qZr{18.hsxIXnkr9Tnݑsmޡ2oT:@DIZ"Ryco3?S+qC65׶i ~ Ӻ U:ɤ+Ë}rwPu(vs)C -&,fq?MIV(5َp%^rs[uz*8Nߢ) +ħ&Ķ4lx-IdFwy}Np!úܑ 6,~ύ͢fP'R o`wd½0FS4w -PD) -e*hdۄ dg&/{>T%ږI,h; mP@dγR M9u -S;XC$Ph  _{mrNӗyU!{A2\bE)6mt@Zח<=NuAcTJğ;P;pb`lI"oKc%'=GKӪgWMXq([@ Nw8_95UvX4 O42TNDV^< L=@s^JɑEۀ]hɾ!7zKx[ϙ2T2o皐6Ԩ'!*/)Ჯ&' ZxY*[EdV+)R`oA1K;QQ촫C?_#~j?|s9uR2\<4 -6 -2*ΏFvJ7Ѿ͎";i֘}YTA0( -fg`(763@'/dk 7<L Rc|)SPv`>U -Br\S)\I -=ծ3Hn/2!;$@dC5@DRnmm*ieMGoŒKî'\MTI!\x`2:C,3jnu;ʉ_CeϹ`V?*e<`od`9dJ7!0ST 8Gwt G01PDA)Q[݉C8?Y3K"$AI:nZcZWT|'̐6X|%gX˿;LL~H^"+}U -ȁ]ZYakz7:)> G̟DOCfZ%j" -mpJ:~O`P`ʻMK9B+D0t%X@#괧ɚ?b!yJ)Qe+ΙדBݟ#6l!*gkHUt|/Rqe [V@G -ݯz|KD>F4"tSE663*3òV>ߌXrJT\N3gQQ.p^C"՝;'ovzq𾇮b9/G%X (|Y:qz#VILn/TOLC>=u'omA8-T9nv}Dv$?QSOʾ{inSbI1>hFJ@i&Y%Y*O/r7esn{uƟ^M|?[z0ir3sGȉ~iZf$9NBtJ䋣v2Me iZrE3(x`Mu,Y'Լ~om릌h`LU;ˀmVb| }_27rc/54=UKg MWKN,J#Fx|A|Ȳ] C~3%=s36$wxjAboم -dQwF uR8\ꔥ`Yԣ;7 hzY$~ӼoZ;tx]H> ^L; W4 (%n>O0kYZԞ"O`A،lILrt} naNPsw{s앳ѫvSɨGUx}v2۹Ki) Ԭ]OmvKí{uqU[NfIk:izh[ӢK1Xdj͓kHi42nKhmG0902>F5Cc!TXؿԚb$TrOzoCͭ$@!"z%mݕltC6K:.<[Ԣ'8S]޴+I.p&HiA t+g1tTK*'35~Rd ]~dX&PGq*H?!ZY}{i  ١7߀C9rLߕj}E7%z0>\ RrLjGh[ͷkhu?2z%E٦҇͜'|;=\x>s$ We&rH#5O+iJ]8.EHo˱{vSMݥ_lοX2CnnƧ|}YD7~;XcbfV=c6olei点ľq\<_R^ 3ľ;g}wi?'P{BfoSoNO⊦t`g)2O-/h9~Ӭ]Q5À]{nhn' JKO$b'v}OW@g $;|(L_BSFwm]!/*hC7,xu)7&(k /xsP{վd;^k>DQUq?FE((z*2ṯߋkה/Woz(D";V=1+Ax~@͹KYh3UV\K2$(Zp°Ībir*x{c͕./0CuJ㔓36Qy鎳K "|.Ko1kz]7f7iYQpc[]r Mq?1CZ-1n&<nl=a+ -ؗ4?(lkYAk-Xn[iUf.!iNHJ`*HyЮHY?1rB:}i&lJ> !QU;Gk!ۻ%uRJ<ɑ6OQh)$0`o BȖ4b3ɈG۞ovq P_jf6,9WNedk6~U'7qe.i*<ü,a7r)x.*alj5W~uk.KOlG kf+U)]+szVr}M?+Κ,0}Z*)WZl ]cqNUݳhwz0'Y@8㧙غy-|ᴝI6W>!+ CNk*WQ$zV<ԯBOyxW=s%yZmg:Ek08"[1wge(d<; ]$=JINмʵۇ4Lx#p+P9zI|rngtU[yWEgBuTb ٤.œ40<#X'̐03,>bMڼTh#5swZT:s;gX]^s*j y֩S j{Ӻ$SN*+Oʧ{.3Aw8.Zy8]QBֳM[}*Zȁh)݇}diЕM< j'( q'eXeo.V\޻G+˛nq"D-&Y(PoOt_v~~O_?~ٗ/Ͼ\}?q|eˏ -B̓X̀?}{oCٺŐ;BR!KAaF CX Lai >8ۓ+y4(75HF,N=zotʨ.h4 CBD2028w&zma ,kW0QL"2|-JK -ֲJ@nÛ,d"sƭPH''lJ~1~M[xSy9 m< % %AӆHt=,=9)7xء͹42jMo5!]\I[{WDwp8j$c': .;W+pA\BpNJO'*AS2( -3SKP0z5I,%!od^5!#LPJb?q!֮'%N*&^LY`M/+$m.52lg9"e]WF~Ew_S|)v[HotIMөSG:Q-Ezg=7w/:g~y[ばYRGo`g\o~W - 3OԺha뎤8BæJ=qʁP'#8r)p4٪" yWyJd7~[A49_us(CKwy8 =z&-n9GiۨI3/d_u\Èd*ɊLJ<[)}u?EW=tZx0uc7=F,OI= =ȃcDG/t?cEVp iVVXu?W|IAkzߚVx:0|бoY헙MC@Q]X\hQpCPEKpJ@%iј!dZ(]1=KWj댢bQ[( -;r-<f&ppHo=#D KkLFU ~׿o_U?%>. '  ـI{~~I M LRLYrL -mc:,WDjZ:K0䣌EOg؎P iNg2ݔ>K!q=cPZ1aꑑaSjgO@znEA?'yi촂zym-BhS49-3:vt !HX tpE 1R }QZ -(WlA2L!:E w ^Un{T -V>Z]W_{ {,Bv7x'D∛ÎjH[XHuoDT8GUIF3omrdʮ&NdՠqbO ՂbAO,qE~\)}^+}^qlor T]Z -endstream endobj 30 0 obj <> endobj 47 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.937 0.627 scn -/GS0 gs -q 1 0 0 1 572.2049 2328.1455 cm -0 0 m --129.367 57.072 -189.186 256.91 -140.928 379.157 c --101.374 479.354 2.196 548.107 110.429 546.016 c -130.474 545.629 150.701 542.993 169.896 536.38 c -226.459 516.894 267.824 465.01 292.728 409.908 c -359.688 261.752 330.946 89.51 186.595 13.293 c -130.199 -16.484 60.131 -26.527 0 0 c -f -Q - -endstream endobj 48 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.937 0.627 scn -/GS0 gs -q 1 0 0 1 3052.8657 1444.0741 cm -0 0 m --67.755 -21.314 -131.628 0.923 -166.397 68.709 c --182.085 99.295 -188.398 133.685 -190.525 167.593 c --194.657 233.465 -182.309 302.404 -141.716 352.299 c --75.888 433.213 18.932 423.724 86.955 348.809 c -115.921 316.907 143.098 281.482 154.708 240.23 c -169.382 188.097 156.72 131.201 126.55 88.268 c -96.38 45.334 50.107 15.763 0 0 c -f -Q - -endstream endobj 49 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.647 0.588 0.557 scn -/GS0 gs -q 1 0 0 1 2102.7786 1163.3348 cm -0 0 m -0.987 -16.791 1.892 -34.167 -4.052 -49.902 c --7.001 -57.709 -11.541 -64.814 -16.389 -71.607 c --17.089 -72.589 -17.831 -73.684 -17.716 -74.884 c --17.568 -76.436 -15.956 -77.523 -14.399 -77.604 c --12.842 -77.684 -11.354 -77.007 -9.973 -76.284 c -3.28 -69.344 13.012 -56.99 19.767 -43.642 c -18.866 -47.997 18.893 -52.541 19.845 -56.884 c -20.153 -58.288 20.621 -59.771 21.764 -60.643 c -24.039 -62.377 27.283 -60.706 29.493 -58.89 c -43.718 -47.198 51.789 -28.404 50.473 -10.039 c -51.975 -13.682 57.122 -14.602 60.611 -12.769 c -64.1 -10.937 66.191 -7.255 67.711 -3.62 c -74.941 13.667 73.315 33.577 67.605 51.424 c -60.129 74.794 45.802 95.927 26.861 111.524 c -34.46 104.791 39.606 95.778 44.42 86.839 c -49.833 76.79 55.041 66.513 57.988 55.485 c -60.885 44.641 61.844 29.246 55.353 19.325 c -50.189 11.433 35.426 20.129 33.542 27.432 c -36.404 16.328 36.536 4.53 33.922 -6.635 c -32.964 -10.729 31.589 -14.838 28.937 -18.1 c -26.284 -21.361 22.137 -23.652 17.962 -23.16 c -14.093 -22.703 10.853 -20.012 8.325 -17.047 c -4.178 -12.184 1.286 -6.26 0 0 c -f -Q - -endstream endobj 50 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 1482.941 1561.9911 cm -0 0 m -14.193 -7.365 34.594 -12.86 50.146 -22.563 c -52.041 -20.592 54.493 -19.203 57.137 -18.689 c -56.424 -17.148 55.694 -15.566 54.944 -13.927 c -51.618 -6.659 50.11 1.291 48.799 9.175 c -35.373 89.913 44.819 172.283 45.193 253.671 c -28.991 221.171 9.342 190.394 -13.295 162 c --23.148 149.642 -33.214 135.525 -46.443 126.965 c --61.774 117.045 -81.654 111.689 -98.539 104.92 c --101.545 103.715 -105.622 103.077 -108.251 104.252 c --99.539 94.147 -90.826 84.042 -82.114 73.938 c --58.202 46.205 -33.012 17.129 0 0 c -f -Q - -endstream endobj 51 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.647 0.588 0.557 scn -/GS0 gs -q 1 0 0 1 1595.3082 904.3475 cm -0 0 m --13.1 1.177 -26.273 1.469 -39.416 0.979 c --26.788 -2.658 -13.157 -1.389 0 0 c -f -Q - -endstream endobj 52 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.647 0.588 0.557 scn -/GS0 gs -q 1 0 0 1 2092.7556 897.7904 cm -0 0 m -30.319 3.529 60.469 8.511 90.296 14.993 c -60.068 11.978 28.952 8.613 0 0 c -f -Q - -endstream endobj 53 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.647 0.588 0.557 scn -/GS0 gs -q 1 0 0 1 1647.4249 875.3724 cm -0 0 m --1.519 -9.808 -2.853 -20.322 -1.652 -30.07 c -2.583 -20.474 3.709 -9.872 0 0 c -f -Q - -endstream endobj 54 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 1402.986 1293.975 cm -0 0 m -0.519 -0.546 l -2.369 -2.487 4.239 -4.142 6.227 -5.604 c -8.015 -6.925 9.773 -8.355 11.537 -9.792 c -11.892 -10.082 12.247 -10.372 12.605 -10.662 c -6.17 -8.963 2.089 -5.477 0 0 c -893.918 -446.555 m -892.748 -443.694 891.235 -440.711 889.42 -437.599 c -887.327 -450.322 872.437 -457.798 859.703 -455.775 c -846.969 -453.751 836.455 -444.795 827.92 -435.131 c -819.384 -425.467 811.966 -414.631 801.792 -406.711 c -807.542 -416.093 816.264 -423.288 822.637 -432.258 c -829.01 -441.229 832.813 -453.589 827.329 -463.128 c -821.997 -472.403 809.951 -475.476 799.26 -475.089 c -763.315 -473.789 735.135 -445.11 711.022 -418.421 c -717.816 -427.204 724.81 -436.417 726.949 -447.312 c -729.089 -458.207 724.714 -471.246 714.368 -475.272 c -710.121 -476.925 705.424 -476.902 700.875 -476.628 c -679.663 -475.354 658.768 -469.061 640.381 -458.407 c -632.573 -453.883 624.374 -446.981 624.833 -437.969 c -625.217 -430.439 631.575 -424.713 637.76 -420.4 c -653.671 -409.307 671.283 -401.684 689.77 -396.185 c -669.366 -398.56 648.888 -400.295 628.371 -401.318 c -618.092 -401.831 607.034 -401.968 598.472 -396.257 c -589.273 -390.121 585.257 -378.783 582.349 -368.115 c -571.274 -327.485 567.825 -284.791 572.235 -242.911 c -572.993 -248.723 575.862 -254.236 580.187 -258.192 c -580.692 -249.277 581.197 -240.362 581.702 -231.447 c -582.512 -244.017 591.492 -255.673 603.439 -259.664 c -579.647 -212.459 569.659 -158.397 575.014 -105.807 c -572.061 -111.095 569.108 -116.382 566.155 -121.67 c -570.497 -98.618 575.896 -75.766 582.33 -53.208 c -560.812 -83.365 518.596 -88.223 481.562 -89.242 c -432.314 -90.597 373.636 -91.338 333.437 -58.756 c -358.788 -98.418 364.424 -147.342 365.906 -194.391 c -366.487 -212.84 365.928 -233.064 353.96 -247.117 c -351.722 -244.744 349.484 -242.371 347.247 -239.998 c -356.439 -277.955 359.069 -317.493 354.984 -356.333 c -353.238 -372.933 349.849 -390.33 338.818 -402.855 c -330.61 -412.175 316.925 -417.397 305.244 -414.981 c -311.481 -418.304 317.329 -422.215 321.866 -427.573 c -342.336 -451.746 313.474 -475.007 290.499 -480.309 c -275.872 -483.684 258.903 -479.541 249.887 -467.538 c -245.707 -461.973 243.629 -455.509 242.787 -448.673 c -238.013 -459.491 229.275 -469.027 218.842 -474.728 c -199.154 -485.486 175.476 -485.625 153.138 -483.532 c -138.905 -482.198 123.782 -479.626 113.336 -469.867 c -106.065 -463.073 102.646 -451.678 105.1 -442.499 c -100.888 -448.182 96.031 -453.304 89.991 -456.903 c -80.474 -462.574 67.332 -463.508 58.846 -456.385 c -51.931 -450.581 49.533 -440.544 51.36 -431.702 c -55.966 -409.416 81.379 -398.819 103.698 -394.373 c -119.912 -391.143 136.385 -389.264 152.906 -388.648 c -151.912 -388.361 150.91 -388.111 149.93 -387.76 c -136.49 -382.958 124.834 -369.956 126.506 -355.782 c -128.206 -341.365 142.445 -330.9 144.42 -316.518 c -145.754 -329.735 154.484 -343.444 167.647 -345.233 c -180.811 -347.021 193.877 -330.386 185.799 -319.84 c -198.74 -332.015 223.17 -327.385 230.76 -311.319 c -229.483 -314.023 206.095 -290.1 204.502 -287.591 c -198.722 -278.491 191.992 -268.707 189.605 -257.951 c -193.669 -270.791 190.453 -285.674 181.45 -295.69 c -178.298 -299.197 172.265 -301.966 169.362 -298.25 c -168.383 -296.997 168.134 -295.339 167.94 -293.761 c -165.642 -275.101 166.292 -256.081 169.857 -237.621 c -164.538 -255.819 155.329 -272.871 143.029 -287.3 c -141.007 -289.672 138.782 -292.057 135.856 -293.132 c -132.931 -294.208 129.126 -293.529 127.567 -290.83 c -126.723 -289.367 126.659 -287.595 126.672 -285.907 c -126.811 -267.186 133.563 -249.204 140.676 -231.886 c -137.141 -241.411 131.077 -249.984 123.274 -256.489 c -121.005 -258.38 118.419 -260.166 115.472 -260.361 c -108.181 -260.845 107.081 -250.896 106.734 -245.72 c -101.595 -169.218 115.855 -93.272 129.632 -18.381 c -132.975 -0.208 136.002 18.286 138.731 36.933 c -138.437 40.597 137.872 44.205 136.867 47.712 c -135.643 48.132 134.464 48.752 133.38 49.512 c -129.657 36.923 124.157 25.095 113.787 14.596 c -112.227 13.016 110.456 11.421 108.259 11.105 c -102.048 10.213 99.689 18.676 97.825 24.666 c -91.095 46.289 64.432 52.911 42.208 57.263 c --24.237 70.275 -90.371 95.09 -139.625 141.547 c --188.878 188.005 -218.435 259.049 -202.702 324.902 c --208.412 314.536 -217.869 302.474 -229.237 305.768 c --236.887 307.985 -240.88 316.496 -242.051 324.374 c --244.793 342.809 -236.293 362.301 -221.401 373.366 c --227.662 372.604 -235.567 377.62 -236.79 384.548 c --238.504 394.25 -232.127 403.398 -225.661 410.831 c --207.863 431.287 -186.802 448.603 -165.85 465.814 c --188.842 448.57 -211.625 435.889 -232.609 416.073 c --253.277 396.555 -271.151 373.993 -283.231 348.143 c --283.231 348.142 -283.749 347.035 y --288.889 335.983 -295.931 320.85 -295.625 308.031 c --295.558 304.762 -294.014 302.192 -291.384 300.976 c --287.599 299.227 -283.014 300.787 -280.326 302.988 c --278.277 304.683 -276.268 306.42 -274.3 308.194 c --279.07 296.248 -282.371 283.559 -283.941 273.089 c --284.25 271.138 l --285.512 263.25 -287.421 251.332 -285.148 241.905 c --282.556 230.82 -275.243 227.674 -269.56 226.982 c --263.575 226.276 -258.212 227.79 -253.616 231.519 c --249.395 234.939 -246.332 239.888 -244.113 245.116 c --235.846 183.46 -199.755 125.577 -140.634 80.075 c --107.246 54.35 -76.33 36.481 -46.11 25.443 c --31.146 19.987 -14.743 15.856 5.517 12.443 c -15.665 10.741 24.804 8.985 33.472 7.06 c -32 6.943 30.536 6.82 29.079 6.701 c -20.975 6.024 12.594 5.34 4.344 5.64 c -4.203 5.644 l -4.017 5.644 3.828 5.673 3.642 5.695 c --6.596 6.918 l --6.263 6.567 l --13.312 7.45 -20.831 9.014 -29.17 11.331 c --32.082 12.139 l --33.46 9.449 l --38.354 -0.094 -38.923 -9.076 -35.148 -17.247 c --26.979 -34.938 -0.939 -42.787 9.874 -45.339 c -25.263 -48.985 41.63 -50.556 58.48 -49.995 c -61.465 -49.901 64.991 -49.141 68.726 -48.333 c -75.112 -46.95 83.067 -45.234 86.801 -47.685 c -88.996 -49.125 89.846 -52.869 90.009 -57.407 c -88.339 -57.941 86.606 -58.403 84.729 -58.698 c -83.257 -58.93 81.676 -94.841 81.929 -98.283 c -83.963 -125.914 73.391 -159.285 66.269 -185.927 c -57.978 -216.945 47.011 -247.25 33.501 -276.377 c -31.396 -280.916 29.091 -285.601 25.116 -288.64 c -21.142 -291.678 14.993 -292.483 11.313 -289.093 c -4.217 -282.556 12.74 -271.107 12.194 -261.474 c -7.487 -280.981 -4.991 -298.5 -21.889 -309.323 c --27.361 -312.828 -36.253 -314.761 -39.018 -308.881 c --40.215 -306.333 -39.556 -303.335 -38.78 -300.629 c --35.045 -287.615 -29.061 -275.249 -21.171 -264.245 c --37.702 -282.14 -59.182 -295.83 -82.947 -301.184 c --106.712 -306.538 -132.727 -303.12 -153.262 -290.014 c --187.609 -268.095 -200.804 -225.168 -211.104 -185.747 c --207.389 -199.964 -210.57 -217.714 -207.472 -232.72 c --203.985 -249.611 -198.187 -266.03 -190.26 -281.349 c --177.149 -306.686 -152.427 -329.83 -123.411 -334.94 c --105.157 -338.187 -86.946 -332.822 -70.038 -326.1 c --72.344 -329.133 -74.493 -332.326 -76.35 -335.754 c --79.176 -340.971 -87.63 -358.858 -77.764 -370.106 c --74.714 -373.571 -70.252 -376.442 -63.83 -376.442 c --56.712 -376.442 -47.186 -372.916 -34.517 -362.765 c --26.581 -356.415 -19.935 -348.802 -14.048 -341.043 c --14.274 -343.766 -14.333 -346.499 -14.217 -349.214 c --14.106 -351.662 -13.77 -359.104 -8.392 -363.033 c --3.468 -366.696 3.213 -366.2 11.467 -361.548 c -26.142 -353.277 36.136 -336.655 50.213 -330.179 c -53.583 -328.628 57.078 -327.694 60.645 -327.099 c -59.98 -333.666 59.34 -340.237 58.645 -346.8 c -57.498 -357.498 56.314 -368.191 55.018 -378.853 c -54.017 -387.092 48.594 -396.038 43.346 -404.687 c -41.232 -408.173 39.234 -411.467 37.543 -414.686 c -16.292 -455.297 l -14.687 -458.396 12.868 -461.911 12.254 -465.85 c -10.046 -480.226 22.364 -483.483 29 -485.239 c -29.897 -485.471 30.755 -485.667 31.651 -485.866 c -38.066 -487.285 44.577 -487.802 50.873 -488.302 c -54.096 -488.556 57.32 -488.812 60.531 -489.189 c -77.89 -491.202 94.369 -492.415 111.817 -493.696 c -116.543 -494.043 121.3 -494.395 126.111 -494.764 c -141.551 -495.922 159.793 -497.266 178.003 -498.435 c -183.073 -498.775 188.157 -499.058 193.246 -499.344 c -203.505 -499.919 214.116 -500.513 224.397 -501.577 c -228.005 -501.947 231.574 -502.084 235.104 -502.084 c -240.509 -502.084 245.82 -501.758 251.024 -501.44 c -256.755 -501.092 262.679 -500.727 268.578 -500.817 c -270.506 -500.842 l -285.521 -501.06 301.048 -501.273 316.636 -499.724 c -327.721 -498.609 339.523 -496.896 351.224 -489.439 c -362.745 -482.039 373.004 -472.848 383.018 -463.876 c -392.973 -454.957 393.31 -443.365 393.636 -432.149 c -393.676 -430.748 393.716 -429.347 393.777 -427.95 c -393.799 -427.472 l -394.483 -411.742 395.193 -395.48 395.703 -379.421 c -396.63 -351.437 397.593 -323.453 398.595 -295.462 c -400.797 -233.774 403.523 -177.726 406.933 -124.115 c -407.15 -120.668 l -403.729 -120.205 l -402.487 -120.038 401.253 -119.839 400.036 -119.618 c -414.285 -114.796 430.095 -114.789 445.448 -114.778 c -447.743 -114.778 450.031 -114.778 452.305 -114.76 c -454.821 -114.738 l -473.975 -114.579 492.235 -114.416 510.206 -119.115 c -508.356 -119.329 506.452 -119.51 504.479 -119.666 c -500.229 -119.999 l -501.148 -124.162 l -505.105 -142.078 505.286 -161.555 505.456 -180.391 c -505.525 -187.656 505.594 -195.168 505.884 -202.397 c -506.423 -215.789 l -507.361 -238.976 508.331 -262.949 508.736 -286.571 c -509.25 -317.302 509.587 -348.443 509.735 -379.139 c -509.848 -394.59 509.848 -410.001 509.848 -425.452 c -509.848 -426.842 509.822 -428.214 509.801 -429.568 c -509.627 -439.444 509.449 -449.653 519.141 -457.643 c -528.535 -465.343 541.912 -469.828 553.713 -473.785 c -555.505 -474.386 557.258 -474.973 558.945 -475.555 c -579.019 -482.481 596.841 -487.647 613.428 -491.347 c -632.08 -495.524 651.136 -498.605 670.063 -500.502 c -674.564 -500.958 679.116 -501.029 683.633 -501.194 c -731.35 -502.947 780.145 -502.099 827.439 -495.212 c -844.635 -492.708 863.176 -490.344 878.804 -482.247 c -896.835 -472.904 899.971 -461.358 893.918 -446.555 c -f -Q - -endstream endobj 55 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 2124.9507 2097.8308 cm -0 0 m --1.356 3.205 -2.693 6.28 -3.746 9.134 c --8.206 21.258 -10.94 33.862 -12.359 48.801 c --12.674 52.093 -12.884 55.396 -13.094 58.7 c --13.311 62.051 -13.524 65.401 -13.839 68.728 c --13.93 69.718 -14.006 70.737 -14.086 71.771 c --14.263 74.187 -14.451 76.685 -14.835 79.221 c --15.584 83.795 -16.855 87.292 -18.839 90.235 c --21.688 94.42 -30.152 102.785 -37.729 104.108 c --42.073 104.868 l --42.073 84.271 l --39.242 83.583 l --37.972 83.274 -36.838 82.398 -36.487 81.455 c --36.339 81.053 -36.227 80.401 -36.954 79.387 c --97.962 -4.825 -199.037 -59.494 -314.268 -70.604 c --374.016 -76.375 -431.924 -72.165 -486.399 -58.104 c --507.923 -52.521 -530.15 -45.448 -549.461 -34.172 c --557.71 -29.355 -563.551 -23.289 -571.083 -17.745 c --578.931 -11.968 -596.788 -7.526 -602.135 0.417 c --574.646 -40.394 -531.089 -68.679 -484.336 -84.018 c --382.774 -117.341 -263.914 -104.311 -168.852 -59.649 c --137.826 -44.136 -111.578 -22.219 -80.897 -5.84 c --75.564 -9.591 -75.202 -17.177 -74.878 -23.689 c --74.313 -35.035 -72.275 -46.306 -68.833 -57.132 c --65.192 -68.581 -59.908 -80.199 -61.662 -92.084 c --40.849 -79.929 -21.87 -64.641 -5.56 -46.896 c --0.844 -41.765 3.776 -36.2 5.646 -29.488 c -8.235 -20.201 4.03 -9.524 0 0 c -f -Q - -endstream endobj 56 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 2083.114 2131.2344 cm -0 0 m -23.649 29.557 40.99 64.191 4.108 70.704 c --0.237 71.465 l --0.237 50.868 l -2.594 50.18 l -3.865 49.87 4.998 48.994 5.349 48.051 c -5.498 47.649 5.61 46.998 4.882 45.984 c --56.125 -38.229 -157.201 -92.898 -272.431 -104.008 c --310.018 -107.632 -346.053 -104.077 -383.375 -102.002 c --423.368 -99.778 -462.89 -88.848 -498.225 -69.959 c --487.479 -87.604 -466.206 -95.386 -446.309 -100.949 c --378.26 -119.974 -306.604 -127.56 -236.481 -118.876 c --166.358 -110.192 -97.82 -84.872 -41.36 -42.387 c --34.063 -36.896 -15.65 -19.56 0 0 c -f -Q - -endstream endobj 57 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.455 0.71 0.349 scn -/GS0 gs -q 1 0 0 1 1499.6124 2052.6477 cm -0 0 m --0.509 -9.568 -1.088 -19.144 -1.667 -28.712 c --1.703 -29.331 l --1.863 -31.952 -2.199 -34.805 -2.543 -37.752 c --3.497 -45.908 -4.578 -55.15 -2.382 -62.72 c -1.012 -74.536 12.569 -86.744 31.964 -99.005 c -35.056 -100.967 38.035 -102.701 40.667 -104.207 c -54.41 -112.096 69.435 -119.228 86.604 -126.016 c -140.838 -147.382 201.38 -158.047 263.003 -158.043 c -326.909 -158.043 391.978 -146.567 452.312 -123.659 c -492.35 -108.473 530.33 -87.62 564.359 -61.601 c -591.489 -40.859 630.392 -18.944 625.117 20.612 c -620.057 -5.987 598.396 -26.026 576.589 -42.074 c -474.413 -117.269 350.947 -142.543 226.431 -141.559 c -192.29 -141.289 156.734 -140.691 126.301 -125.217 c -95.867 -109.743 72.533 -74.55 82.2 -41.805 c -148.26 -53.611 215.378 -59.491 282.484 -59.351 c -237.921 -57.447 193.047 -54.894 149.815 -43.915 c -106.583 -32.936 64.656 -12.919 33.994 19.478 c -26.229 27.683 15.308 42.035 32.178 46.613 c -24.242 52.638 15.101 69.882 3.563 58.667 c --4.857 50.483 0.661 12.591 0 0 c -f -Q - -endstream endobj 58 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.647 0.588 0.557 scn -/GS0 gs -q 1 0 0 1 1953.3632 2609.8938 cm -0 0 m --6.135 -6.09 -15.033 -10.675 -21.469 -13.85 c --75.667 -40.591 -133.817 -62.159 -194.222 -64.098 c --202.17 -64.354 -210.27 -64.246 -217.855 -61.859 c --225.44 -59.471 -232.539 -54.496 -235.828 -47.256 c --233.735 -51.865 -236.215 -59.391 -233.677 -64.845 c --231.223 -70.119 -226.91 -74.19 -223.794 -79.178 c --220.686 -84.153 -219.001 -88.95 -215.033 -93.575 c --206.279 -103.778 -195.589 -112.328 -183.974 -119.061 c --164.368 -130.425 -142.478 -137.921 -120.047 -141.102 c --114.526 -141.885 -108.861 -142.276 -103.123 -142.276 c --55.452 -142.275 -2.847 -115.337 13.133 -63.91 c -16.429 -53.338 17.981 -42.562 18.616 -31.536 c -19.312 -19.437 18.896 -7.4 14.576 4.079 c -13.463 7.036 11.955 9.826 10.453 12.605 c -8.479 16.256 6.506 19.906 4.532 23.556 c -9.668 14.057 6.284 6.239 0 0 c -f -Q - -endstream endobj 59 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1527.2374 2662.6516 cm -0 0 m -1.254 -5.568 -2.187 -11.086 -7.686 -12.325 c --13.185 -13.564 -18.659 -10.055 -19.914 -4.487 c --21.168 1.081 -17.728 6.599 -12.229 7.838 c --6.729 9.077 -1.255 5.568 0 0 c -f -Q - -endstream endobj 60 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 2335.6101 2574.5669 cm -0 0 m --0.691 0.677 l --0.97 0.948 -1.861 1.919 -1.607 2.97 c --1.35 4.027 l --1.705 5.054 l --2.093 6.172 -2.491 7.278 -2.9 8.37 c --0.529 3.968 l -2.945 8.508 2.958 8.525 v -15.291 24.649 8.205 40.417 -2.697 54.146 c -2.105 48.122 0.765 38.186 -5.462 33.65 c --11.689 29.114 -21.558 30.885 -25.819 37.302 c --16.324 30.622 -11.566 19.086 -8.642 7.851 c -5.119 -45.018 -13.787 -104.995 -55.38 -140.418 c --65.636 -149.15 -89.531 -164.476 -101.154 -150.646 c --103.807 -147.49 -105.297 -143.543 -106.739 -139.68 c --112.351 -124.648 -117.962 -109.616 -123.574 -94.584 c --122.898 -108.923 -132.399 -123.163 -145.898 -128.045 c --143.676 -100.829 -151.811 -67.027 -167.296 -44.542 c --185.93 -17.487 -208.802 -8.641 -236.666 5.066 c --214.45 -5.863 -197.979 -26.47 -188.461 -49.326 c --178.943 -72.181 -175.845 -97.233 -175.352 -121.986 c --174.602 -159.65 -181.666 -194.394 -204.178 -225.08 c --225.255 -253.809 -263.599 -266.257 -298.092 -270.347 c --289.475 -307.37 -223.29 -286.733 -203.694 -275.095 c --165.403 -252.353 -137.973 -209.18 -124.737 -168.258 c --125.783 -174.247 -127.203 -180.219 -128.984 -186.152 c --130.602 -191.546 l --125.009 -190.902 l --123.752 -190.75 -122.63 -191.166 -121.761 -192.153 c --114.698 -200.168 -105.709 -204.318 -95.037 -204.49 c --94.816 -204.494 -94.599 -204.496 -94.378 -204.496 c --74.456 -204.496 -52.058 -190.163 -38.577 -175.815 c --21.793 -157.927 -8.587 -134.353 -1.39 -109.431 c -6.636 -81.594 11.288 -38.47 0.275 -0.93 c -h -f -Q - -endstream endobj 61 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 1475.6381 3126.1506 cm -0 0 m -6.413 -9.009 12.782 -17.811 18.833 -26.779 c -17.092 -15.299 10.597 -4.717 0 0 c -f -Q - -endstream endobj 62 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 1359.6322 2869.6179 cm -0 0 m -3.076 3.894 6.055 7.864 8.897 11.931 c -5.739 8.093 2.812 4.085 0 0 c -f -Q - -endstream endobj 63 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 1744.1642 2481.0889 cm -0 0 m -11.774 -11.75 26.05 -21.025 41.56 -26.754 c -90.263 -44.743 155.553 -32.357 191.258 6.244 c -209.397 25.856 214.093 46.612 222.219 71.22 c -214.849 47.157 198.975 25.794 178.064 11.793 c -167.956 5.024 154.121 0.08 144.103 6.981 c -137.8 11.323 135.01 19.106 132.722 26.409 c -126.567 46.058 121.326 65.993 117.021 86.128 c -88.022 70.946 54.918 63.7 22.229 65.379 c -10.925 65.959 -18.388 79.781 -26.46 74.735 c --38.132 67.44 -27.342 42.5 -23.371 33.635 c --17.77 21.135 -9.741 9.72 0 0 c -f -Q - -endstream endobj 64 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 2047.2933 2544.8413 cm -0 0 m --6.015 1.119 -12.302 1.442 -18.831 0.828 c --10.733 -2.771 -1.235 -8.603 -2.044 -17.427 c --2.347 -20.723 -4.143 -23.673 -5.97 -26.432 c --30.049 -62.787 -67.366 -88.85 -107.429 -106.068 c --147.492 -123.285 -190.519 -132.335 -233.352 -140.506 c --264.577 -146.463 -297.562 -151.895 -327.55 -141.347 c --335.786 -138.451 -344.187 -133.797 -347.695 -125.801 c --351.202 -117.806 -346.875 -106.275 -338.18 -105.483 c --380.282 -128.238 -403.389 -177.574 -404.343 -225.422 c --404.685 -242.586 -402.945 -261.219 -412.55 -275.448 c --414.219 -277.92 -416.56 -280.368 -419.541 -280.474 c --423.572 -280.616 -426.339 -276.568 -428.12 -272.949 c --443.217 -242.273 -446.343 -205.895 -436.703 -173.093 c --441.628 -189.852 -450.352 -204.933 -454.176 -222.363 c --457.898 -239.33 -458.285 -256.552 -461.991 -273.482 c --465.758 -290.694 -470.713 -310.57 -486.731 -317.91 c --503.906 -325.779 -524.871 -313.306 -533.032 -296.268 c --541.194 -279.229 -540.025 -259.394 -538.681 -240.549 c --545.941 -272.008 -564.011 -300.866 -589.142 -321.134 c --592.944 -324.2 -597.151 -327.177 -602.007 -327.708 c --612.354 -328.839 -620.279 -318.868 -625.045 -309.615 c --644.928 -271.008 -648.375 -225.356 -640.729 -182.608 c --638.516 -170.23 -637.305 -159.292 -632.104 -147.514 c --620.859 -122.048 -607.218 -97.64 -591.419 -74.718 c --601.265 -89.003 -615.057 -99.319 -626.064 -112.464 c --636.457 -124.877 -646.666 -139.224 -654.274 -153.537 c --659.84 -164.007 -661.533 -176.563 -676.112 -177.506 c --685.12 -178.089 -690.463 -167.552 -691.91 -158.642 c --693.167 -150.9 -693.344 -142.988 -692.474 -135.194 c --697.207 -151.493 -703.229 -167.418 -710.538 -182.737 c --719.74 -202.027 -734.19 -222.515 -755.507 -224.071 c --757.552 -224.22 -759.758 -224.137 -761.422 -222.941 c --763.911 -221.153 -764.269 -217.651 -764.352 -214.588 c --765.68 -165.085 -753.102 -115.284 -728.428 -72.349 c --751.59 -107.132 -786.243 -134.123 -825.638 -148.065 c --832.612 -150.532 -842.186 -151.7 -845.752 -145.219 c --847.061 -142.841 -847.113 -139.992 -847.028 -137.279 c --846.048 -106.147 -831.087 -76.628 -810.319 -53.416 c --791.848 -32.772 -768.991 -16.619 -745.174 -2.362 c --751.031 -3.24 -757.787 -1.019 -762.051 3.358 c --779.176 20.937 -769.236 63.21 -761.944 83.345 c --751.98 110.852 -733.241 135.379 -708.323 150.936 c --730.466 207.534 -722.05 274.818 -687.661 324.777 c --698.24 311.385 -710.15 299.045 -723.192 288.037 c --728.521 283.539 -734.28 279.14 -741.08 277.589 c --747.879 276.039 -755.978 278.109 -759.497 284.129 c --762.347 289.005 -761.628 295.109 -760.584 300.659 c --750.658 353.452 -718.384 401.666 -673.36 430.965 c --628.336 460.264 -571.183 470.244 -518.894 457.937 c --527.336 479.048 -519.345 502.787 -511.37 524.078 c --496.63 563.428 -481.752 603.065 -459.661 638.809 c --453.114 649.404 -444.297 660.628 -431.882 661.62 c --425.008 652.313 -425.057 639.733 -425.963 628.199 c --429.073 588.63 -438.927 549.599 -454.974 513.297 c --416.64 559.9 -372.896 602.049 -324.903 638.627 c --340.279 626.908 -362.633 616.741 -379.529 606.192 c --398.008 594.655 -411.735 580.413 -426.73 564.386 c --429.809 561.097 -432.941 557.75 -436.11 554.396 c --435.227 557.804 -434.302 561.258 -433.354 564.797 c --425.094 595.63 -416.552 627.515 -428.49 658.831 c --428.98 660.116 -430.003 662.792 -432.592 664.05 c --434.874 665.192 -438.206 664.472 -439.986 663.76 c --450.913 659.311 -458.215 651.823 -466.627 642.49 c --473.36 635 -479.875 626.414 -486.538 616.249 c --508.311 583.206 -520.986 545.042 -532.333 507.305 c --532.136 510.232 -531.872 513.291 -531.544 516.522 c --531.464 517.296 l --531.971 518.761 l --532.147 518.994 -532.147 518.994 v --538.08 531.65 -545.193 543.225 -552.822 554.53 c --551.505 545.849 -552.899 536.655 -557.333 529.087 c --567.632 511.511 -590.102 503.432 -610.254 506.405 c --617.389 507.458 -624.423 509.746 -630.41 513.768 c --638.522 519.217 -644.245 527.465 -649.97 535.385 c --712.147 621.405 -795.51 689.414 -877.865 756.369 c --829.766 717.265 -782.42 678.085 -742.781 630.041 c --723.088 606.172 -705.364 580.599 -690.912 553.207 c --679.756 532.062 -651.126 497.396 -662.737 472.837 c --664.868 468.329 -668.17 464.496 -671.432 460.724 c --710.052 416.06 -748.672 371.397 -787.292 326.733 c --790.03 323.566 -793.011 320.242 -797.048 319.132 c --800.257 318.25 -803.672 318.91 -806.907 319.695 c --825.378 324.174 -842.869 332.652 -857.828 344.378 c --898.288 376.095 -916.923 427.861 -929.288 477.762 c --952.153 570.044 -960.279 665.962 -953.264 760.776 c --967.083 711.501 -963.997 659.278 -960.797 608.201 c --957.763 559.755 -954.713 511.173 -945.944 463.43 c --935.863 408.539 -918.22 355.041 -893.671 304.92 c --913.743 304.363 -928.434 323.244 -938.075 340.858 c --974.811 407.97 -990.007 484.586 -1000.647 560.351 c --1012.447 644.384 -1019.25 729.119 -1021.007 813.958 c --1021.655 845.237 -1018.975 881.813 -992.995 899.241 c --1024.222 893.302 -1036.46 853.569 -1040.393 826.339 c --1043.327 806.025 -1043.166 784.825 -1043.024 766.117 c --1042.976 759.614 -1042.928 753.503 -1043.026 747.988 c --1043.989 692.104 -1042.507 641.382 -1038.49 592.92 c --1036.379 567.568 -1033.413 542.437 -1029.675 518.227 c --1020.483 458.488 -1006.243 401.506 -987.351 348.867 c --967.118 292.379 -941.254 240.104 -910.478 193.489 c --894.294 168.989 -876.478 145.655 -857.53 124.136 c --848.039 113.33 -837.837 102.538 -827.198 92.051 c --824.68 89.589 -822.004 87.288 -819.418 85.064 c --816.741 82.76 -814.212 80.586 -811.832 78.241 c --808.203 74.641 -807.122 70.666 -806.3 64.141 c --804.188 47.16 -802.073 30.178 -799.927 13.212 c --798.882 4.697 -797.7 -4.952 -795.398 -14.318 c --795.012 -15.891 -794.735 -17.471 -794.458 -19.047 c --794.115 -20.999 -793.761 -22.999 -793.219 -25.035 c --797.534 -29.231 -801.902 -33.334 -806.273 -37.443 c --811.229 -42.103 -816.189 -46.764 -821.085 -51.566 c --834.069 -64.298 -844.526 -76.321 -853.057 -88.318 c --865.001 -105.101 -873.138 -120.161 -878.657 -135.694 c --880.424 -140.577 -881.662 -144.878 -882.442 -148.846 c --886.779 -170.952 -874.331 -178.327 -863.128 -180.622 c --855.598 -182.18 -846.868 -179.145 -839.857 -176.707 c --838.831 -176.35 -837.837 -176.004 -836.885 -175.688 c --811.826 -167.307 -785.462 -150.267 -756.682 -123.787 c --761.647 -134.372 -766.418 -145.352 -769.82 -157.138 c --775.472 -176.89 -778.227 -196.817 -778.007 -216.353 c --777.938 -224.557 -777.415 -234.186 -774.048 -243.373 c --771.577 -250.285 -767.635 -254.881 -762.604 -256.679 c --761.321 -257.12 -759.96 -257.417 -758.468 -257.573 c --745.745 -258.55 -733.733 -245.244 -725.794 -236.417 c --725.009 -235.544 -724.278 -234.729 -723.593 -233.987 c --712.117 -221.429 -701.858 -206.334 -694.045 -190.634 c --693.138 -193.392 l --688.155 -208.583 -682.508 -225.8 -671.086 -237.553 c --665.536 -243.264 l --664.738 -235.341 l --660.917 -197.385 -648.389 -160.677 -628.677 -128.565 c --652.411 -176.274 -669.625 -230.807 -660.638 -291.563 c --654.835 -330.838 -639.518 -363.925 -615.113 -389.907 c --604.261 -401.455 -591.076 -411.485 -576.583 -417.996 c --571.004 -420.502 -564.605 -423.215 -558.529 -424.099 c --555.048 -424.605 -536.24 -420.975 -534.835 -422.375 c --496.167 -460.918 -445.704 -486.333 -392.948 -500.392 c --340.192 -514.45 -285.052 -517.617 -230.483 -515.897 c --217.777 -515.496 -207.021 -515.934 -195.211 -511.303 c --183.177 -506.584 -171.23 -501.626 -159.266 -496.723 c --186.991 -505.909 -219.848 -489.147 -236.381 -464.082 c --254.324 -436.877 -257.918 -402.975 -261.016 -370.532 c --256.532 -379.763 -244.867 -384.8 -235.074 -381.734 c --225.28 -378.669 -218.569 -367.88 -220.147 -357.74 c --194.697 -377.001 -159.151 -382.033 -129.354 -370.595 c --99.558 -359.156 -76.511 -331.63 -70.488 -300.286 c --87.257 -331.486 -125.349 -347.659 -160.599 -344.181 c --195.849 -340.702 -227.79 -320.165 -251.211 -293.592 c --274.632 -267.018 -290.477 -234.691 -304.218 -202.044 c --259.588 -258.976 -178.102 -283.866 -109.278 -261.589 c --133.089 -265.551 -157.922 -263.19 -180.56 -254.812 c --192.608 -250.354 -204.484 -243.828 -211.737 -233.225 c --218.99 -222.621 -220.337 -207.194 -212.093 -197.341 c --205.852 -189.881 -195.768 -187.033 -186.228 -185.134 c --162.978 -180.507 -139.072 -179.19 -115.454 -181.236 c --93.039 -183.178 -65.438 -194.485 -65.983 -216.977 c --43.758 -172.579 -20.523 -128.687 3.697 -85.345 c -11.101 -72.094 19.445 -58.091 33.224 -51.723 c -44.182 -46.659 59.26 -49.538 66.1 -58.472 c -53.221 -30.917 29.977 -5.577 0 0 c -f -Q - -endstream endobj 65 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 2048.323 2549.969 cm -0 0 m --3.618 3.015 -8.003 4.891 -12.986 4.896 c --8.564 3.515 -4.232 1.868 0 0 c -f -Q - -endstream endobj 66 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 1354.8192 2409.6477 cm -0 0 m -2.184 7.521 4.119 15.115 5.731 22.779 c -2.792 15.495 0.871 7.806 0 0 c -f -Q - -endstream endobj 67 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 2248.9202 3143.365 cm -0 0 m --1.426 0.123 -2.837 0.278 -4.225 0.461 c --61.28 7.987 -110.483 43.174 -155.381 79.175 c --204.071 118.214 -252.387 161.53 -277.283 218.757 c --281.206 227.774 -284.599 237.22 -290.749 244.892 c --296.9 252.565 -306.635 258.274 -316.315 256.545 c --326.361 254.75 -333.422 245.765 -338.45 236.885 c --344.421 226.339 -348.964 214.985 -351.913 203.231 c --347.92 216.533 -328.768 219.928 -317.213 212.223 c --305.658 204.518 -300.637 190.077 -298.519 176.352 c --293.873 146.25 -299.878 114.614 -315.23 88.308 c --305.699 99.643 -295.069 130.079 -277.248 131.095 c --269.992 131.508 -264.483 124.969 -260.145 119.137 c --224.751 71.556 -182.509 28.263 -131.702 -2.321 c --149.187 -35.031 -169.746 -66.097 -193.021 -94.975 c --233.094 -73.813 -276.399 -58.785 -320.968 -50.577 c --328.124 -49.259 -336.042 -47.687 -340.377 -41.842 c --343.688 -37.377 -344.07 -31.444 -344.112 -25.885 c --344.315 1.302 -339.311 28.519 -329.451 53.856 c --337.082 34.207 -345.289 13.723 -361.294 0.004 c --377.298 -13.714 -403.641 -17.851 -418.826 -3.229 c --435.359 12.691 -430.544 39.794 -424.499 61.936 c --427.765 49.972 -434.853 39.163 -437.656 26.785 c --440.328 14.988 -441.725 4.074 -446.003 -7.484 c --439.043 -10.03 l --439.522 -11.316 -440.612 -11.858 -441.072 -11.917 c --437.891 -11.496 -422.596 -16.243 -413.118 -19.51 c --412.406 -19.038 -411.523 -18.785 -410.483 -18.974 c --393.981 -21.97 -381.599 -40.95 -381.636 -57.481 c --381.616 -48.385 -283.862 -56.26 -276.567 -57.538 c --247.41 -62.646 -217.889 -73.303 -197.889 -95.125 c --177.888 -116.947 -170.258 -151.972 -186.351 -176.816 c --187.954 -179.291 -190.349 -181.901 -193.272 -181.511 c --179.06 -196.793 -176.769 -221.851 -187.974 -239.457 c --190.34 -243.175 -193.276 -246.677 -194.391 -250.941 c --195.344 -254.583 -194.867 -258.432 -194.268 -262.148 c --192.365 -273.956 -189.283 -285.574 -185.084 -296.773 c --184.426 -298.527 -147.948 -263.944 -145.19 -259.997 c --134.366 -244.514 -124.307 -227.454 -114.726 -210.986 c --118.109 -222.029 -131.78 -227.453 -142.995 -224.695 c --154.211 -221.937 -162.947 -213.011 -169.09 -203.231 c --179.275 -187.015 -183.925 -167.39 -182.096 -148.329 c --181.666 -143.833 -180.877 -139.34 -179.265 -135.121 c --177.532 -130.584 -174.888 -126.463 -172.292 -122.359 c --147.308 -82.862 -125.081 -41.62 -105.826 0.965 c --104.429 4.054 -102.865 7.356 -99.903 9.004 c --95.238 11.598 -89.502 8.987 -84.833 6.401 c --73.272 -0.003 -61.711 -6.406 -50.15 -12.81 c --34.144 -21.676 -16.664 -30.839 1.458 -28.312 c -21.122 -25.572 37.473 -7.416 38.149 12.426 c -30.105 0.892 14.323 -1.231 0 0 c -f -Q - -endstream endobj 68 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 2174.5457 2521.7129 cm -0 0 m --17.603 35.154 -49.834 59.929 -88.313 67.186 c --88.76 67.27 -88.908 66.683 -88.498 66.515 c --17.872 37.762 27.13 -42.142 -2.594 -116.344 c --2.776 -116.798 -2.002 -117.128 -1.8 -116.679 c -15.491 -78.362 19.185 -38.314 0 0 c -f -Q - -endstream endobj 69 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 1665.3597 2188.2632 cm -0 0 m --27.064 15.509 -46.297 32.592 -56.853 62.927 c --67.092 92.348 -68.822 126.077 -61.183 156.35 c --61.072 156.788 -61.705 156.953 -61.853 156.535 c --73.895 122.516 -75.104 88.056 -61.154 54.165 c --50.995 29.485 -30.058 -1.4 -0.614 -2.267 c -0.601 -2.302 1.031 -0.591 0 0 c -f -Q - -endstream endobj 70 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1555.1075 2677.7146 cm -0 0 m --15.766 -4.866 -31.349 -10.839 -44.282 -19.906 c --64.019 -33.743 -64.779 -57.811 -45.103 -72.498 c --35.474 -79.686 -23.316 -82.732 -11.337 -83.678 c -11.036 -85.445 34.114 -80.19 52.829 -67.802 c -71.543 -55.415 85.593 -35.767 90.025 -13.766 c -96.222 16.993 75.012 18.441 51.251 13.44 c -33.965 9.802 16.887 5.212 0 0 c -f -Q - -endstream endobj 71 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 1715.5292 2180.1365 cm -0 0 m --0.257 1.028 -1.941 0.837 -1.878 -0.254 c --1.073 -14.076 -16.57 -21.434 -27.728 -23.893 c --39.271 -26.436 -52.406 -24.415 -63.428 -20.581 c --83.323 -13.661 -99.858 -0.492 -116.382 12.106 c --116.598 12.271 -116.861 11.958 -116.738 11.749 c --100.662 -15.679 -73.711 -36.862 -41.032 -38.621 c --16.182 -39.959 7.034 -28.196 0 0 c -f -Q - -endstream endobj 72 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 1976.8932 2239.2632 cm -0 0 m --10.792 -20.79 -34.772 -38.401 -57.426 -44.221 c --84.852 -51.266 -108.505 -40.271 -132.919 -29.045 c --133.065 -28.978 -133.258 -29.124 -133.157 -29.283 c --117.7 -53.647 -84.105 -60.446 -57.295 -54.751 c --27.036 -48.324 -9.648 -28.154 1.112 -0.469 c -1.362 0.174 0.315 0.607 0 0 c -f -Q - -endstream endobj 73 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 1667.5397 1816.568 cm -0 0 m --8.249 -3.165 -17.01 -4.916 -25.385 -7.775 c --35.254 -11.145 -47.139 -17.877 -41.915 -0.485 c --36.945 16.062 -22.258 31.542 -8.41 40.725 c --8.18 40.878 -8.323 41.321 -8.611 41.202 c --18.613 37.049 -26.335 30.286 -33.142 21.89 c --39.494 14.055 -52.615 -0.863 -52.509 -11.433 c --52.326 -29.84 -26.315 -21.678 -9.476 -13.999 c --14.097 -16.106 -11.052 -35.059 -9.89 -38.598 c --7.808 -44.94 -3.783 -52.596 1.167 -57.125 c --4.065 -52.296 -3.183 -35.505 -2.973 -29.048 c --2.595 -17.425 1.048 -6.16 7.575 3.468 c -5.119 2.122 2.584 0.991 0 0 c -f -Q - -endstream endobj 74 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 1991.0861 1887.3295 cm -0 0 m --0.404 0.301 -0.863 -0.341 -0.527 -0.682 c -10.424 -11.811 22.836 -24.728 30.345 -38.434 c -35.943 -48.65 39.448 -59.824 31.801 -69.762 c -29.08 -73.299 27.04 -75.36 22.605 -76.235 c -18.732 -76.999 7.24 -77.132 4.34 -73.824 c -12.077 -82.65 18.543 -87.288 30.363 -83.695 c -39.129 -81.03 45.812 -74.229 46.515 -64.834 c -48.663 -36.146 19.904 -14.8 0 0 c -f -Q - -endstream endobj 75 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 1969.0963 1827.463 cm -0 0 m --0.63 0.385 -1.144 -0.447 -0.737 -0.955 c -9.037 -13.174 15.737 -26.873 18.592 -42.275 c -20.381 -51.925 19.958 -62.996 18.313 -72.614 c -17.695 -76.231 16.841 -82.876 13.345 -85.092 c -7.744 -88.641 4.783 -80.583 0.036 -78.331 c --0.529 -87.483 -3.963 -96.438 -9.663 -103.62 c --6.107 -99.14 1.231 -95.955 5.367 -91.352 c -11.091 -103.267 22.621 -90.056 25.337 -84.023 c -29.73 -74.265 30.828 -63.125 29.875 -52.548 c -28.032 -32.11 17.94 -10.954 0 0 c -f -Q - -endstream endobj 76 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 1944.1888 1756.985 cm -0 0 m --5.55 -8.942 -11.665 -18.151 -18.22 -26.374 c --24.905 -34.758 -33.347 -41.391 -40.201 -49.593 c --40.882 -50.407 -40.262 -52.138 -39.018 -51.625 c --18.89 -43.337 -4.341 -20.519 0.476 -0.201 c -0.544 0.086 0.158 0.254 0 0 c -f -Q - -endstream endobj 77 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 1545.1827 980.4476 cm -0 0 m --3.527 -4.867 -7.085 -9.711 -10.813 -14.425 c --14.491 -19.075 -18.573 -23.773 -24.102 -25.913 c --25.043 -26.277 -26.123 -26.557 -27.037 -26.13 c --28.164 -25.606 -28.59 -24.247 -28.852 -23.032 c --31.983 -8.541 -27.491 5.252 -23.727 19.138 c --20.001 32.886 -15.215 46.336 -9.328 59.308 c --9.237 59.51 -9.534 59.687 -9.628 59.483 c --17.425 42.612 -27.561 26.173 -32.754 8.306 c --35.4 -0.801 -41.502 -18.257 -35.393 -27.276 c --28.868 -36.908 -19.499 -31.436 -13.344 -24.56 c --9.868 -20.675 -7.255 -16.34 -4.729 -11.843 c --2.202 -7.343 -0.621 -0.863 2.289 3.164 c -1.526 2.109 0.764 1.054 0 0 c -f -Q - -endstream endobj 78 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 1584.3512 970.3363 cm -0 0 m -0.467 3.576 -0.017 7.602 -0.446 10.126 c --1.41 6.363 -3.249 2.827 -5.776 -0.124 c --6.237 -0.662 -6.765 -1.208 -7.458 -1.36 c --8.353 -1.557 -9.242 -1.041 -9.969 -0.482 c --20.14 7.327 -19.981 20.932 -19.916 32.438 c --19.863 41.623 -18.967 50.842 -18.566 60.018 c --18.548 60.422 -19.133 60.473 -19.249 60.11 c --25.141 41.702 -29.024 18.464 -18.711 0.712 c --16.301 -3.436 -10.346 -8.668 -5.083 -7.384 c --1.835 -6.591 -0.459 -3.513 0 0 c -f -Q - -endstream endobj 79 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 1623.9156 989.2225 cm -0 0 m --5.102 4.306 -9.979 11.818 -12.338 15.4 c --17.722 23.571 -21.797 32.521 -25.79 41.426 c --25.123 31.947 -23.083 22.038 -18.185 13.783 c --13.194 5.37 -3.679 -2.57 6.433 -3.203 c -4.365 -3.074 2.162 -1.825 0 0 c -f -Q - -endstream endobj 80 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 2162.0334 1225.6722 cm -0 0 m --8.651 18.066 -19.623 37.025 -32.858 52.092 c --33.087 52.352 -33.543 52.077 -33.439 51.753 c --27.881 34.545 -17.793 19.912 -9.797 3.844 c --4.598 -6.602 -0.432 -18.001 -3.241 -29.82 c --8.89 -53.578 -27.034 -27.604 -34.648 -20.616 c --29.408 -31.549 -24.616 -42.852 -22.621 -54.811 c --20.353 -68.404 -22.211 -82.403 -29.624 -94.192 c --26.166 -93.6 -23.205 -91.259 -21.121 -88.437 c --14.775 -79.846 -12.915 -66.553 -14.593 -56.3 c --14.838 -54.805 -15.171 -53.311 -15.539 -51.82 c --8.443 -53.584 -1.35 -49.954 3.179 -37.201 c -7.684 -24.519 5.69 -11.884 0 0 c -f -Q - -endstream endobj 81 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1861.0463 2773.7625 cm -0 0 m -1.141 -5.065 -1.989 -10.086 -6.992 -11.213 c --11.995 -12.34 -16.976 -9.147 -18.117 -4.082 c --19.259 0.983 -16.128 6.004 -11.125 7.131 c --6.122 8.258 -1.141 5.065 0 0 c -f -Q - -endstream endobj 82 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 2105.7563 1164.5428 cm -0 0 m --1.609 3.958 -3.627 7.689 -5.994 11.042 c -3.83 -9.751 -0.326 -31.558 -9.554 -51.729 c --9.993 -52.689 -8.887 -53.663 -8.053 -52.887 c -6.223 -39.61 7.141 -17.568 0 0 c -f -Q - -endstream endobj 83 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 1715.4545 877.1073 cm -0 0 m --67.759 33.522 -149.441 37.748 -222.867 25.56 c --223.155 25.512 -223.091 25.019 -222.798 25.048 c --146.083 32.67 -74.033 19.015 -0.402 -0.953 c -0.153 -1.104 0.543 -0.269 0 0 c -f -Q - -endstream endobj 84 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.208 0.098 0.02 scn -/GS0 gs -q 1 0 0 1 2228.4875 902.3978 cm -0 0 m --63.168 20.399 -144.397 7.795 -198.758 -30.102 c --198.982 -30.257 -198.851 -30.696 -198.557 -30.578 c --168.033 -18.281 -136.807 -6.907 -104.207 -1.547 c --69.509 4.158 -34.993 1.634 -0.185 -1.365 c -0.626 -1.435 0.714 -0.23 0 0 c -f -Q - -endstream endobj 85 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.812 0.89 1 scn -/GS0 gs -q 1 0 0 1 1719.2548 2655.469 cm -0 0 m -0 0.007 l --7.492 60.267 -23.006 119.267 -46.116 175.371 c --53.718 193.787 -67.449 219.034 -98.81 225.646 c --112.031 228.438 -125.445 227.741 -138.051 226.785 c --222.274 220.414 -331.673 190.183 -423.561 147.89 c --442.84 139.006 -449.706 129.375 -451.812 108.258 c --455.119 75.264 -441.948 38.81 -430.325 6.647 c --428.545 1.725 -426.815 -3.061 -425.213 -7.66 c --417.088 -31.065 -407.599 -54.411 -397.01 -77.058 c --395.833 -79.57 -394.671 -82.084 -393.511 -84.597 c --387.125 -98.415 -380.522 -112.706 -371.768 -125.952 c --368.521 -130.861 -365.017 -135.536 -361.344 -139.861 c --357.487 -144.386 -352.141 -150.041 -344.943 -153.666 c --339.851 -156.213 -334.42 -157.442 -329.72 -158.318 c --321.6 -159.779 -313.29 -160.409 -304.883 -160.409 c --275.761 -160.409 -245.498 -152.841 -218.075 -145.982 c --208.61 -143.627 l --174.354 -135.196 -61.176 -92.992 -35.521 -74.149 c --6.806 -53.075 3.817 -30.902 0 0 c -f -Q -q 1 0 0 1 2196.2727 2807.1514 cm -0 0 m -0 0.033 l --0.489 14.828 -3.15 29.323 -5.724 43.343 c --6.201 45.949 -6.679 48.561 -7.146 51.186 c --11.277 74.219 -16.609 97.284 -22.999 119.749 c --24.27 124.196 -25.541 128.85 -26.847 133.636 c --35.308 164.619 -44.898 199.735 -65.044 223.634 c --78.055 239.092 -88.521 243.018 -108.103 239.825 c --190.625 226.381 -270.515 197.489 -345.551 153.952 c --355.669 148.08 -366.262 141.589 -374.762 132.508 c --395.111 110.765 -391.943 83.802 -387.787 65.411 c --375.236 9.874 -355.361 -44.007 -328.713 -94.74 c --313.729 -123.246 -295.907 -134.87 -265.157 -136.202 c --262.884 -136.302 -260.618 -136.349 -258.351 -136.349 c --230.968 -136.349 -203.98 -129.418 -176.499 -121.666 c --147.831 -113.587 -117.403 -104.611 -88.257 -91.583 c --65.634 -81.452 -34.656 -67.58 -14.6 -47.484 c --11.751 -44.595 -8.146 -40.658 -5.485 -35.749 c --1.94 -29.063 -0.927 -21.813 -0.442 -16.309 c -0.029 -11.309 0.174 -5.975 0 0 c -f -Q - -endstream endobj 86 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 CS 0.812 0.89 1 SCN -63.02 w 10 M 0 j 0 J []0 d -/GS0 gs -q 1 0 0 1 1719.2548 2655.469 cm -0 0 m -0 0.007 l --7.492 60.267 -23.006 119.267 -46.116 175.371 c --53.718 193.787 -67.449 219.034 -98.81 225.646 c --112.031 228.438 -125.445 227.741 -138.051 226.785 c --222.274 220.414 -331.673 190.183 -423.561 147.89 c --442.84 139.006 -449.706 129.375 -451.812 108.258 c --455.119 75.264 -441.948 38.81 -430.325 6.647 c --428.545 1.725 -426.815 -3.061 -425.213 -7.66 c --417.088 -31.065 -407.599 -54.411 -397.01 -77.058 c --395.833 -79.57 -394.671 -82.084 -393.511 -84.597 c --387.125 -98.415 -380.522 -112.706 -371.768 -125.952 c --368.521 -130.861 -365.017 -135.536 -361.344 -139.861 c --357.487 -144.386 -352.141 -150.041 -344.943 -153.666 c --339.851 -156.213 -334.42 -157.442 -329.72 -158.318 c --321.6 -159.779 -313.29 -160.409 -304.883 -160.409 c --275.761 -160.409 -245.498 -152.841 -218.075 -145.982 c --208.61 -143.627 l --174.354 -135.196 -61.176 -92.992 -35.521 -74.149 c --6.806 -53.075 3.817 -30.902 0 0 c -h -S -Q -q 1 0 0 1 2196.2727 2807.1514 cm -0 0 m -0 0.033 l --0.489 14.828 -3.15 29.323 -5.724 43.343 c --6.201 45.949 -6.679 48.561 -7.146 51.186 c --11.277 74.219 -16.609 97.284 -22.999 119.749 c --24.27 124.196 -25.541 128.85 -26.847 133.636 c --35.308 164.619 -44.898 199.735 -65.044 223.634 c --78.055 239.092 -88.521 243.018 -108.103 239.825 c --190.625 226.381 -270.515 197.489 -345.551 153.952 c --355.669 148.08 -366.262 141.589 -374.762 132.508 c --395.111 110.765 -391.943 83.802 -387.787 65.411 c --375.236 9.874 -355.361 -44.007 -328.713 -94.74 c --313.729 -123.246 -295.907 -134.87 -265.157 -136.202 c --262.884 -136.302 -260.618 -136.349 -258.351 -136.349 c --230.968 -136.349 -203.98 -129.418 -176.499 -121.666 c --147.831 -113.587 -117.403 -104.611 -88.257 -91.583 c --65.634 -81.452 -34.656 -67.58 -14.6 -47.484 c --11.751 -44.595 -8.146 -40.658 -5.485 -35.749 c --1.94 -29.063 -0.927 -21.813 -0.442 -16.309 c -0.029 -11.309 0.174 -5.975 0 0 c -h -S -Q - -endstream endobj 87 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1583.6351 2754.8848 cm -0 0 m --4.114 -34.688 -8.069 -69.384 -12.698 -104.01 c --16.834 -134.957 -21.932 -165.778 -26.242 -196.695 c --17.311 -193.452 -8.026 -189.973 1.219 -186.403 c -11.44 -144.533 20.153 -102.293 31.006 -60.575 c -41.369 -20.742 54.6 18.309 64.629 58.172 c -63.77 60.323 62.974 62.497 62.092 64.639 c -53.756 84.83 44.659 94.266 30.685 97.213 c -26.415 98.115 21.533 98.552 15.764 98.552 c -13.705 98.552 11.595 98.463 9.492 98.372 c -7.321 65.495 3.88 32.715 0 0 c -f -Q -q 1 0 0 1 1443.3973 2826.0364 cm -0 0 m --4.908 -16.708 -10.162 -33.318 -15.555 -49.877 c --20.609 -65.398 -25.927 -80.846 -30.794 -96.427 c --35.804 -112.466 -40.022 -128.804 -44.371 -145.032 c --52.968 -177.105 -60.946 -209.341 -68.406 -241.697 c --70.824 -252.186 -73.103 -262.707 -75.417 -273.219 c --74.043 -275.568 -72.663 -277.907 -71.176 -280.158 c --68.582 -284.08 -65.791 -287.805 -62.916 -291.19 c --61.713 -292.6 -58.518 -296.351 -55.819 -297.71 c --53.766 -298.737 -50.027 -299.433 -48.611 -299.698 c --42.629 -300.773 -36.038 -301.32 -29.026 -301.32 c --11.816 -301.32 6.329 -298.155 24.509 -294.061 c -33.17 -261.362 41.801 -228.654 50.361 -195.928 c -60.801 -156.014 70.364 -115.775 82.292 -76.274 c -92.449 -42.636 103.942 -9.426 114.682 24.026 c -79.003 19.567 39.777 11.259 0 0 c -f -Q -q 1 0 0 1 2071.8723 2995.9331 cm -0 0 m --2.849 -55.969 -5.588 -111.848 -6.078 -167.903 c --6.36 -200.208 -6.046 -232.521 -4.982 -264.809 c --2.88 -264.06 -0.781 -263.3 1.312 -262.521 c -1.875 -258.997 2.406 -255.467 2.998 -251.947 c -16.597 -171.127 36.902 -91.614 52.321 -11.158 c -47.954 -0.9 42.865 8.404 36.669 15.755 c -31.061 22.415 29.743 22.415 27.56 22.415 c -25.87 22.415 23.683 22.199 21.066 21.772 c -14.297 20.67 7.553 19.418 0.822 18.098 c -0.586 12.063 0.307 6.03 0 0 c -f -Q -q 1 0 0 1 1952.4493 2978.062 cm -0 0 m --9.075 -52.313 -17.144 -104.8 -25.027 -157.304 c --30.769 -195.543 -36.458 -233.792 -42.368 -272.007 c --36.646 -275.558 -29.715 -277.065 -20.038 -277.485 c --18.195 -277.565 -16.363 -277.603 -14.528 -277.603 c -7 -277.603 29.345 -272.312 52.234 -265.991 c -54.339 -251.807 56.683 -237.652 58.839 -223.482 c -65.019 -182.867 71.358 -142.275 78.159 -101.759 c -84.463 -64.203 90.55 -26.519 99.429 10.53 c -101.185 17.856 103.012 25.269 104.763 32.732 c -69.198 24.843 34.214 13.893 0 0 c -f -Q - -endstream endobj 88 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1717.403 2655.2373 cm -0 0 m -3.732 -30.125 -6.659 -51.78 -34.748 -72.409 c --60.269 -91.151 -173.032 -133.183 -207.183 -141.593 c --216.601 -143.937 l --243.528 -150.672 -274.048 -158.307 -303.082 -158.307 c --311.742 -158.307 -319.978 -157.614 -327.555 -156.247 c --332.02 -155.444 -337.26 -154.281 -342.265 -151.769 c --349.164 -148.303 -354.341 -142.824 -358.082 -138.434 c --360.291 -135.84 -362.392 -133.095 -364.458 -130.252 c --364.152 -130.73 -363.888 -131.228 -363.577 -131.703 c --360.297 -136.704 -356.962 -141.197 -353.381 -145.436 c --349.669 -149.826 -344.533 -155.305 -337.688 -158.771 c --332.723 -161.284 -327.523 -162.446 -323.093 -163.25 c --315.575 -164.616 -307.403 -165.309 -298.812 -165.309 c --270.005 -165.309 -239.723 -157.674 -213.007 -150.939 c --203.663 -148.595 l --169.779 -140.185 -57.897 -98.153 -32.576 -79.411 c --4.707 -58.782 5.603 -37.127 1.9 -7.002 c --2.861 31.716 -10.979 69.908 -22.245 107.165 c --11.979 72.129 -4.499 36.297 0 0 c -f -Q - -endstream endobj 89 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1244.0387 2675.9333 cm -0 0 m --9.312 19.714 -16.068 40.636 -20.082 62.189 c --20.474 64.285 -20.888 66.36 -21.298 68.409 c --25.115 87.469 -26.476 97.807 -12.915 106.191 c -8.362 119.345 30.405 130.895 60.792 144.811 c -139.018 180.642 248.272 210.644 332.66 219.467 c -335.585 219.774 l -345.547 220.832 357.945 222.144 370.419 222.144 c -391.721 222.144 406.306 218.182 413.773 210.367 c -421.225 202.568 428.187 192.762 435.685 179.512 c -441.379 169.45 l -448.061 178.875 l -462.689 199.505 494.493 208.74 519.523 208.74 c -525.978 208.74 532.129 208.17 537.808 207.042 c -547.416 205.136 l -546.558 214.969 l -545.419 227.996 545.538 238.422 546.924 247.782 c -549.927 267.97 582.846 285.917 600.533 295.558 c -602.893 296.845 l -682.051 340.151 757.473 368.076 827.068 379.843 c -857.359 384.964 880.092 387.55 903.08 388.492 c -903.54 388.511 903.989 388.521 904.434 388.521 c -917.785 388.521 922.07 380.021 929.092 363.733 c -929.868 361.928 930.658 360.102 931.477 358.27 c -939.882 339.458 945.888 319.703 949.329 299.551 c -950.101 295.026 950.387 290.095 949.981 285.879 c -952.419 290.426 952.459 299.042 951.166 306.553 c -947.698 326.705 941.645 346.46 933.174 365.272 c -932.348 367.104 931.552 368.931 930.77 370.735 c -923.692 387.022 919.373 395.523 905.917 395.523 c -905.468 395.523 905.016 395.514 904.552 395.494 c -881.383 394.552 858.471 391.966 827.942 386.845 c -757.797 375.078 681.781 347.153 601.999 303.847 c -599.62 302.56 l -581.794 292.919 548.615 274.972 545.589 254.784 c -544.192 245.424 544.072 234.998 545.22 221.971 c -546.085 212.138 l -536.401 214.044 l -530.677 215.172 524.478 215.742 517.972 215.742 c -492.745 215.742 460.69 206.507 445.947 185.877 c -439.211 176.452 l -433.473 186.515 l -425.916 199.765 418.899 209.57 411.388 217.37 c -403.862 225.184 389.162 229.146 367.693 229.146 c -355.12 229.146 342.625 227.834 332.584 226.777 c -329.635 226.469 l -244.583 217.646 134.468 187.644 55.625 151.813 c -24.998 137.897 2.781 126.347 -18.663 113.193 c --32.331 104.809 -30.959 94.471 -27.113 75.411 c --26.7 73.362 -26.282 71.288 -25.887 69.191 c --21.842 47.639 -15.032 26.716 -5.646 7.002 c --3.085 1.619 0.416 -3.778 4.101 -7.369 c -2.583 -5.03 1.187 -2.515 0 0 c -f -Q - -endstream endobj 90 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 2211.7126 2808.9922 cm -0 0 m --0.123 3.055 -0.253 6.234 -0.34 9.592 c --0.945 32.229 -6.248 61.775 -10.509 85.514 c --11.023 88.382 l --11.349 90.194 -14.296 102.127 -16.899 112.657 c --18.651 119.738 -20.447 127.004 -21.775 132.513 c --22.751 136.555 -23.453 139.526 -23.772 141.863 c --26.836 139.255 -25.97 135.522 -23.571 125.511 c --22.253 120.001 -20.472 112.736 -18.733 105.655 c --16.15 95.125 -13.227 83.191 -12.903 81.379 c --12.393 78.512 l --8.166 54.773 -2.904 25.227 -2.304 2.59 c --2.218 -0.768 -2.088 -3.947 -1.966 -7.002 c --1.45 -19.778 -1.097 -29.601 -3.896 -41.428 c --3.891 -41.412 -3.882 -41.398 -3.877 -41.382 c -1.064 -26.183 0.619 -15.199 0 0 c -f -Q - -endstream endobj 91 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1869.9122 2706.2778 cm -0 0 m -14.508 -27.827 31.756 -39.176 61.518 -40.481 c -63.766 -40.581 66.008 -40.628 68.249 -40.628 c -95.192 -40.628 121.771 -33.709 148.897 -26.002 c -177.327 -17.927 207.488 -8.96 236.201 3.979 c -258.478 14.017 288.991 27.767 308.678 47.676 c -311.631 50.663 314.982 54.343 317.439 58.975 c -319.504 62.879 320.664 67.018 321.367 70.881 c -320.787 69.23 320.085 67.583 319.229 65.977 c -316.752 61.345 313.375 57.665 310.399 54.678 c -290.557 34.769 259.803 21.02 237.351 10.981 c -208.411 -1.958 178.012 -10.925 149.359 -19 c -122.019 -26.707 95.229 -33.625 68.074 -33.625 c -65.815 -33.625 63.556 -33.578 61.29 -33.479 c -31.293 -32.174 13.909 -20.824 -0.713 7.002 c --27.252 57.513 -47.077 111.242 -59.628 166.701 c --59.939 168.076 -60.239 169.513 -60.529 170.979 c --59.976 166.973 -59.236 163.177 -58.454 159.699 c --46.001 104.24 -26.332 50.51 0 0 c -f -Q - -endstream endobj 92 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1886.402 2787.4666 cm -0 0 m --14.343 -4.427 -28.521 -9.861 -40.287 -18.11 c --58.243 -30.699 -58.934 -52.595 -41.033 -65.958 c --32.273 -72.497 -21.212 -75.268 -10.314 -76.129 c -10.041 -77.736 31.036 -72.955 48.062 -61.685 c -65.088 -50.416 77.87 -32.54 81.903 -12.524 c -87.541 15.46 68.244 16.777 46.627 12.228 c -30.901 8.918 15.363 4.741 0 0 c -f -Q - -endstream endobj 93 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1335.9943 2514.4385 cm -0 0 m --1.765 2.74 -3.601 5.59 -5.583 8.571 c --18.974 28.728 -32.415 57.731 -43.214 81.036 c --44.525 83.865 l --45.358 85.661 -50.091 97.924 -54.264 108.745 c --65.284 137.304 -67.114 142.017 -70.503 142.799 c --68.237 137.904 -65.04 129.699 -59.614 115.747 c --55.407 104.927 -50.637 92.663 -49.798 90.867 c --48.476 88.038 l --37.592 64.733 -24.045 35.73 -10.549 15.573 c --8.551 12.592 -6.701 9.742 -4.922 7.002 c --1.552 1.815 1.466 -2.823 4.67 -7.152 c -3.153 -4.867 1.621 -2.515 0 0 c -f -Q - -endstream endobj 94 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1943.9508 2609.083 cm -0 0 m --0.348 0.13 -0.726 0.192 -1.093 0.181 c --2.092 0.151 -3.023 -0.3 -3.918 -0.745 c --13.488 -5.498 -22.66 -11.141 -32.314 -15.689 c --34.007 -16.487 -35.676 -17.329 -37.363 -18.143 c --39.531 -19.188 -42.629 -21.476 -41.52 -24.355 c --40.322 -27.464 -36.057 -26.538 -33.588 -25.974 c --31.759 -25.556 -30.012 -25.004 -28.266 -24.316 c --24.602 -22.872 -21.099 -21.156 -17.679 -19.204 c --14.192 -17.213 -10.805 -15.055 -7.466 -12.826 c --3.611 -10.253 -0.706 -7.854 1.046 -3.388 c -1.313 -2.706 1.537 -1.947 1.307 -1.251 c -1.109 -0.651 0.6 -0.224 0 0 c -f -Q - -endstream endobj 95 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1826.9872 2559.5784 cm -0 0 m --0.779 0.615 -1.747 1.031 -2.721 1.144 c --5.744 1.495 -8.961 0.045 -11.845 -0.648 c --14.941 -1.392 -18.052 -2.283 -21.223 -2.835 c --28.035 -4.02 -35.057 -4.398 -41.59 -6.837 c --42.293 -7.1 -43.012 -7.402 -43.517 -7.957 c --44.022 -8.511 -44.25 -9.388 -43.855 -10.026 c --43.577 -10.474 -43.064 -10.713 -42.574 -10.911 c --30.139 -15.955 -15.371 -12.436 -3.245 -7.889 c --1.112 -7.09 1.29 -5.848 1.641 -3.597 c -1.86 -2.195 1.128 -0.89 0 0 c -f -Q - -endstream endobj 96 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1848.9452 2564.6763 cm -0 0 m --1.702 4.096 -10.139 0.444 -12.953 -0.601 c --14.012 -0.994 -15.082 -1.452 -15.885 -2.246 c --16.689 -3.04 -17.177 -4.246 -16.836 -5.322 c --16.529 -6.292 -15.608 -6.974 -14.627 -7.244 c --13.646 -7.514 -12.604 -7.434 -11.595 -7.299 c --8.479 -6.884 2.105 -5.066 0 0 c -f -Q - -endstream endobj 97 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1953.3546 2329.4141 cm -0 0 m --2.639 5.717 -6.727 10.301 -12.188 13.482 c --17.166 16.381 -25.276 18.679 -30.461 14.925 c --33.739 12.551 -35.01 8.792 -33.052 5.042 c --30.777 0.688 -25.691 -1.565 -22.562 -5.199 c --20.977 -7.04 -20.349 -7.739 -19.114 -9.676 c --17.541 -12.142 -15.996 -13.722 -14.023 -14.734 c --13.181 -15.554 -12.365 -16.41 -11.563 -17.248 c --8.843 -20.089 -3.655 -19.477 -1.76 -15.985 c --1.135 -14.833 -0.485 -13.584 -0.077 -12.346 c -0.026 -11.987 0.13 -11.628 0.233 -11.268 c -0.31 -10.834 0.372 -10.47 0.421 -10.162 c -2.236 -7.029 1.416 -3.068 0 0 c -f -Q - -endstream endobj 98 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 1 1 1 scn -/GS0 gs -q 1 0 0 1 1913.9501 2348.3535 cm -0 0 m --0.846 0.979 -1.708 2.064 -3.157 2.655 c --4.645 3.262 -6.376 3.326 -7.975 3.409 c --10.198 3.524 -12.206 2.145 -13.334 0.297 c --14.015 -0.467 -14.44 -1.355 -15.165 -2.066 c --17.097 -3.959 -15.687 -7.595 -12.911 -7.507 c --12.69 -7.5 -12.108 -7.702 -11.529 -7.91 c --10.053 -8.997 -8.254 -9.526 -6.306 -8.928 c --3.913 -8.194 -1.777 -7.733 -0.233 -5.778 c -1.408 -4.169 1.645 -1.903 0 0 c -f -Q - -endstream endobj 99 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 1700.4244 2739.3857 cm -0 0 m --1.527 5.794 -3.276 11.515 -5.223 17.128 c --15.972 48.115 -32.587 77.375 -55.781 100.566 c --78.974 123.757 -108.975 140.637 -141.377 145.718 c --184.412 152.467 -228.631 137.469 -262.17 110.523 c --277.192 98.454 -291.606 84.893 -302.167 68.581 c --335.255 17.475 -327.519 -53.365 -300.275 -105.647 c --284.314 -136.278 -259.276 -162.442 -228.418 -177.958 c --218.002 -183.196 -206.67 -187.277 -195.012 -187.101 c --183.355 -186.926 -171.306 -181.887 -164.954 -172.111 c --177.802 -173.73 -192.376 -169.679 -203.576 -163.444 c --228.055 -149.818 -245.811 -131.963 -256.353 -110.378 c --268.55 -85.38 -272.967 -56.306 -270.753 -28.698 c --268.828 -4.696 -254.882 16.926 -238.757 34.53 c --207.397 68.764 -157.368 91.87 -111.126 76.504 c --66.56 61.696 -33.432 20.951 -22.507 -32.485 c --16.389 -62.492 -18.541 -88.331 -28.907 -109.284 c --35.591 -122.796 -45.332 -132.229 -56.363 -142.149 c --47.299 -138.835 -38.629 -143.702 -30.108 -141.954 c --20.798 -140.044 -13.865 -129.763 -9.654 -122.071 c -10.453 -85.345 10.758 -40.833 0 0 c -f -Q - -endstream endobj 100 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 2005.3475 2737.4102 cm -0 0 m --9.347 -13.112 l --9.807 -13.407 -10.263 -13.706 -10.719 -14.008 c --24.132 -22.965 -36.303 -30.927 -49.419 -37.664 c --69.276 -47.821 -93.061 -46.422 -120.136 -33.501 c --149.89 -19.381 -166.351 9.635 -174.92 31.49 c --184.554 56.039 -212.071 139.359 -161.775 180.899 c --146.028 193.896 -126.366 197.777 -112.635 198.743 c --109.681 198.957 -106.705 199.062 -103.711 199.062 c --75.144 199.062 -45.104 189.479 -20.479 172.517 c --21.565 172.565 -22.673 172.607 -23.795 172.652 c --29.494 172.873 -35.391 173.103 -39.797 174.101 c --58.419 178.32 l --42.729 167.439 l --8.294 143.562 3.146 105.766 9.796 71.937 c -12.508 58.243 16.982 23.821 0 0 c -22.343 2.417 m -32.293 14.292 32.517 43.065 32.986 57.689 c -34.259 97.375 23.246 136.927 7.317 172.39 c -2.412 183.312 -3.028 194.037 -9.777 203.926 c --26.398 228.282 -51.006 247.091 -78.87 256.739 c --101.167 264.459 -125.927 266.293 -148.398 259.096 c --201.525 242.08 -216.946 181.779 -217.101 132.041 c --217.265 79.431 -199.362 26.544 -165.549 -13.971 c --159.308 -21.448 -152.49 -28.594 -144.277 -33.828 c --133.735 -40.547 -121.376 -43.816 -109.078 -46.055 c --96.08 -48.421 -82.633 -49.734 -69.709 -46.988 c --56.106 -44.098 -43.869 -36.899 -31.906 -29.808 c --22.541 -24.258 -13.177 -18.708 -3.813 -13.158 c -3.463 -8.846 16.03 -4.41 21.7 1.689 c -21.918 1.924 22.133 2.167 22.343 2.417 c -f -Q - -endstream endobj 101 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 1583.3954 1878.1808 cm -0 0 m -8.259 -3.408 16.708 -6.354 25.303 -8.806 c -37.457 -12.273 50.365 -14.785 62.67 -11.901 c -44.807 -26.4 31.287 -46.184 24.271 -68.095 c -22.839 -72.566 21.661 -77.266 22.285 -81.919 c -24.836 -100.954 59.287 -106.126 60.806 -84.755 c -58.087 -122.997 74.082 -162.131 102.807 -187.521 c -110.166 -194.025 118.647 -199.81 128.33 -201.448 c -138.013 -203.087 149.059 -199.674 154.109 -191.251 c -155.088 -202.726 159.815 -213.852 167.397 -222.522 c -171.279 -226.962 176.029 -230.844 181.65 -232.63 c -188.718 -234.875 196.43 -233.605 203.517 -231.421 c -220.025 -226.335 234.972 -216.294 245.923 -202.933 c -247.368 -208.174 248.813 -213.413 250.259 -218.653 c -283.222 -210.645 317.12 -194.743 341.029 -170.215 c -337.342 -173.283 339.698 -179.973 344.155 -181.744 c -348.613 -183.516 353.685 -181.801 357.885 -179.485 c -366.122 -174.944 373.028 -168.022 377.549 -159.775 c -377.242 -162.565 378.944 -165.458 381.532 -166.545 c -409.084 -149.534 423.363 -113.572 414.985 -82.295 c -422.687 -92.013 439.314 -90.411 447.692 -81.268 c -456.069 -72.125 457.35 -58.274 454.607 -46.18 c -448.205 -17.958 423.83 2.372 399.283 17.699 c -413.277 5.708 443.47 -41.781 409.66 -44.617 c -393.35 -45.983 376.746 -43.719 361.397 -38.037 c -377.714 -53.53 393.754 -75.93 385.182 -96.735 c -383.307 -101.283 379.042 -105.881 374.265 -104.705 c -372.062 -104.163 370.336 -102.489 368.812 -100.808 c -360.445 -91.581 354.666 -80.03 352.299 -67.8 c -361.595 -88.74 348.967 -112.659 334.952 -130.784 c -322.033 -147.491 307.001 -163.395 287.742 -172.06 c -283.797 -173.835 279.546 -175.311 275.238 -174.936 c -264.485 -174 257.969 -159.196 264.54 -150.634 c -249.754 -168.355 231.714 -187.648 208.638 -187.222 c -185.286 -186.792 165.96 -161.251 171.894 -138.661 c -171.724 -152.236 155.938 -161.603 142.583 -159.165 c -129.227 -156.727 118.867 -145.973 111.841 -134.356 c -102.813 -119.427 97.937 -103.482 99.509 -86.242 c -100.368 -76.817 104.522 -44.917 115.203 -40.726 c -104.222 -45.034 93.242 -49.342 82.262 -53.649 c -77.299 -55.596 72.058 -57.579 66.78 -56.832 c -61.502 -56.085 56.356 -51.541 56.958 -46.244 c -57.232 -43.83 58.607 -41.698 59.995 -39.704 c -74.153 -19.363 104.025 -4.967 128.575 -3.604 c -138.614 -3.047 148.766 -4.036 158.683 -2.378 c -149.249 -2.998 142.263 -13.473 144.063 -22.755 c -145.863 -32.037 154.931 -38.917 164.359 -39.63 c -173.786 -40.343 183.101 -35.645 189.446 -28.635 c -183.676 -41.851 190.29 -64.365 206.604 -65.684 c -220.098 -66.775 232.649 -54.302 232.965 -40.767 c -230.859 -45.044 227.671 -49.349 223.003 -50.321 c -216.93 -51.585 211.004 -46.278 209.509 -40.258 c -208.013 -34.237 209.828 -27.911 212.077 -22.129 c -214.041 -17.08 216.347 -12.165 218.974 -7.427 c -221.754 -2.417 247.571 -0.002 255.105 1.855 c -273.799 6.463 293.066 8.576 311.753 13.559 c -388.547 33.434 462.474 69.734 519.193 125.989 c -548.324 154.881 555.689 181.379 541.284 219.53 c -540.149 222.537 538.978 225.606 537.809 228.784 c -537.08 230.766 536.413 232.77 535.775 234.786 c -513.771 207.463 483.46 185.509 454.295 168.035 c -357.485 110.031 245.499 86.08 133.428 85.807 c -61.522 85.631 -22.809 96.036 -86.5 135.021 c --84.741 133.943 -88.22 109.933 -89.782 107.125 c --93.467 100.502 -103.558 94.064 -108.781 88.464 c --82.261 49.154 -43.812 18.078 0 0 c -f -Q - -endstream endobj 102 0 obj <>/ExtGState<>>>/Subtype/Form>>stream -/CS0 cs 0.729 0.596 0.533 scn -/GS0 gs -q 1 0 0 1 2741.5947 2281.4868 cm -0 0 m --0.414 3.069 -0.857 6.227 -1.255 9.492 c -3.981 -12.16 -11.571 -33.625 -29.608 -46.698 c --48.934 -60.705 -72.168 -69.258 -95.962 -71.125 c --91.047 -134.424 -139.703 -197.41 -202.191 -208.639 c --195.382 -213.875 -194.764 -223.774 -195.142 -232.355 c --199.094 -321.985 -249.559 -408.298 -325.729 -455.705 c --317.107 -456.165 -308.018 -456.773 -300.835 -461.563 c --293.651 -466.353 -289.537 -476.876 -294.566 -483.894 c --297.242 -487.628 -301.759 -489.517 -306.11 -490.992 c --323.847 -497.005 -342.891 -499.126 -361.517 -497.164 c --356.006 -504.889 -340.193 -501.623 -337.944 -510.841 c --336.488 -516.811 -342.799 -521.598 -348.342 -524.251 c --398.145 -548.094 -459.122 -547.091 -508.115 -521.625 c --552.952 -498.319 -591.953 -453.165 -596.214 -401.585 c --592.603 -436.005 -592.069 -470.521 -588.958 -504.974 c --588.525 -509.77 -584.55 -569.751 -587.261 -569.183 c --569.528 -572.895 -553.932 -572.906 -536.75 -579.354 c --528.655 -582.394 -521.66 -585.019 -517.066 -585.949 c --483.917 -592.701 -450.122 -594.236 -416.646 -590.526 c --388.926 -587.47 -359.393 -578.937 -331.228 -565.847 c --319.755 -560.51 -309.159 -554.743 -299.721 -548.698 c --282.167 -537.417 -284.1 -527.179 -286.833 -522.035 c --288.756 -518.538 -291.898 -516.214 -294.729 -514.393 c --296.387 -513.336 -298.078 -512.34 -299.793 -511.399 c --283.152 -510.4 -265.485 -507.619 -252.213 -500.053 c --245.751 -496.357 -237.103 -490.608 -236.538 -483.436 c --236.267 -480.62 -237.143 -476.533 -242.844 -473.025 c --247.055 -470.443 -252.905 -470.607 -258.067 -470.73 c --260.033 -470.787 -261.897 -470.831 -263.356 -470.712 c --266.394 -470.469 -269.489 -470.342 -272.606 -470.215 c --273.927 -470.161 -275.26 -470.103 -276.592 -470.042 c --273.08 -467.345 -268.993 -463.811 -264.225 -459.529 c --262.896 -458.334 -261.821 -457.368 -261.126 -456.785 c --253.061 -450.036 -246.78 -442.724 -240.133 -434.98 c --236.458 -430.719 l --220.646 -412.466 -210.092 -390.108 -201.853 -370.642 c --193.103 -349.946 -185.312 -326.776 -178.036 -299.806 c --175.11 -288.971 -172.146 -277.107 -168.699 -262.456 c --167.758 -258.373 -166.665 -254.311 -165.568 -250.235 c --164.511 -246.281 l --163.997 -244.392 -163.53 -242.393 -163.059 -240.384 c --162.356 -237.387 -161.629 -234.288 -160.76 -231.674 c --159.736 -228.673 -158.135 -227.836 -154.294 -226.066 c --153.581 -225.74 -152.839 -225.4 -152.079 -225.027 c --146.576 -222.348 -141.146 -219.108 -135.491 -215.13 c --122.064 -205.75 -113.278 -189.756 -106.461 -175.354 c --99.278 -160.264 -93.725 -144.393 -88.649 -129.418 c --87.263 -125.282 -85.543 -120.981 -83.719 -116.427 c --79.382 -105.594 -74.896 -94.391 -74.154 -83.449 c --74.057 -81.988 l --72.102 -81.009 -69.839 -79.772 -67.186 -78.283 c --66.005 -77.617 -65.057 -77.079 -64.532 -76.824 c --59.286 -74.292 -53.628 -72.128 -48.154 -70.038 c --35.313 -65.132 -22.038 -60.061 -11.749 -49.58 c -3.924 -33.627 2.487 -18.42 0 0 c -f -Q - -endstream endobj 285 0 obj <
> endobj 284 0 obj <> endobj 283 0 obj <> endobj 282 0 obj <> endobj 281 0 obj <> endobj 280 0 obj <> endobj 279 0 obj <> endobj 278 0 obj <> endobj 277 0 obj <> endobj 276 0 obj <> endobj 275 0 obj <> endobj 274 0 obj <> endobj 273 0 obj <> endobj 272 0 obj <> endobj 271 0 obj <> endobj 270 0 obj <> endobj 269 0 obj <> endobj 268 0 obj <> endobj 267 0 obj <> endobj 266 0 obj <> endobj 265 0 obj <> endobj 264 0 obj <> endobj 263 0 obj <> endobj 262 0 obj <> endobj 261 0 obj <> endobj 260 0 obj <> endobj 259 0 obj <> endobj 258 0 obj <> endobj 257 0 obj <> endobj 256 0 obj <> endobj 255 0 obj <> endobj 254 0 obj <> endobj 253 0 obj <> endobj 252 0 obj <> endobj 251 0 obj <> endobj 250 0 obj <> endobj 249 0 obj <> endobj 248 0 obj <> endobj 247 0 obj <> endobj 246 0 obj <> endobj 245 0 obj <> endobj 244 0 obj <> endobj 243 0 obj <> endobj 242 0 obj <> endobj 241 0 obj <> endobj 240 0 obj <> endobj 239 0 obj <> endobj 238 0 obj <> endobj 237 0 obj <> endobj 236 0 obj <> endobj 235 0 obj <> endobj 234 0 obj <> endobj 233 0 obj <> endobj 232 0 obj <> endobj 231 0 obj <> endobj 230 0 obj <> endobj 229 0 obj [/ICCBased 218 0 R] endobj 27 0 obj [26 0 R] endobj 286 0 obj <> endobj xref -0 287 -0000000004 65535 f -0000000016 00000 n -0000000147 00000 n -0000034409 00000 n -0000000000 00000 f -0000034467 00000 n -0000000000 00000 f -0000000000 00000 f -0000163044 00000 n -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000000000 00000 f -0000163117 00000 n -0000163357 00000 n -0000164680 00000 n -0000230269 00000 n -0000295858 00000 n -0000361447 00000 n -0000427036 00000 n -0000000000 00000 f -0000155027 00000 n -0000598472 00000 n -0000035745 00000 n -0000476371 00000 n -0000522511 00000 n -0000147728 00000 n -0000147615 00000 n -0000161852 00000 n -0000161967 00000 n -0000162081 00000 n -0000162204 00000 n -0000162328 00000 n -0000162453 00000 n -0000162578 00000 n -0000162702 00000 n -0000162817 00000 n -0000162930 00000 n -0000155218 00000 n -0000153935 00000 n -0000154087 00000 n -0000154239 00000 n -0000522574 00000 n -0000523149 00000 n -0000523775 00000 n -0000525108 00000 n -0000525906 00000 n -0000526278 00000 n -0000526646 00000 n -0000527018 00000 n -0000536984 00000 n -0000538464 00000 n -0000539268 00000 n -0000540529 00000 n -0000541601 00000 n -0000542053 00000 n -0000543784 00000 n -0000544159 00000 n -0000544523 00000 n -0000545299 00000 n -0000553878 00000 n -0000554245 00000 n -0000554611 00000 n -0000557438 00000 n -0000557954 00000 n -0000558516 00000 n -0000559115 00000 n -0000559735 00000 n -0000560308 00000 n -0000561136 00000 n -0000561779 00000 n -0000562517 00000 n -0000563031 00000 n -0000563913 00000 n -0000564639 00000 n -0000565139 00000 n -0000565987 00000 n -0000566438 00000 n -0000566897 00000 n -0000567365 00000 n -0000567884 00000 n -0000570011 00000 n -0000572170 00000 n -0000574686 00000 n -0000575894 00000 n -0000578314 00000 n -0000579223 00000 n -0000580343 00000 n -0000580938 00000 n -0000581696 00000 n -0000582519 00000 n -0000583238 00000 n -0000583784 00000 n -0000584602 00000 n -0000585268 00000 n -0000586581 00000 n -0000588199 00000 n -0000591701 00000 n -0000037079 00000 n -0000078905 00000 n -0000078969 00000 n -0000079521 00000 n -0000080118 00000 n -0000081383 00000 n -0000082147 00000 n -0000082515 00000 n -0000082877 00000 n -0000083244 00000 n -0000092570 00000 n -0000093994 00000 n -0000094777 00000 n -0000095978 00000 n -0000096994 00000 n -0000097432 00000 n -0000099050 00000 n -0000099416 00000 n -0000099777 00000 n -0000100520 00000 n -0000108719 00000 n -0000109084 00000 n -0000109445 00000 n -0000112047 00000 n -0000112550 00000 n -0000113100 00000 n -0000113676 00000 n -0000114269 00000 n -0000114822 00000 n -0000115618 00000 n -0000116243 00000 n -0000116958 00000 n -0000117461 00000 n -0000118301 00000 n -0000119010 00000 n -0000119498 00000 n -0000120309 00000 n -0000120747 00000 n -0000121198 00000 n -0000121653 00000 n -0000122156 00000 n -0000124150 00000 n -0000126178 00000 n -0000128532 00000 n -0000129655 00000 n -0000131925 00000 n -0000132783 00000 n -0000133838 00000 n -0000134412 00000 n -0000135149 00000 n -0000135940 00000 n -0000136643 00000 n -0000137172 00000 n -0000137949 00000 n -0000138600 00000 n -0000139817 00000 n -0000141314 00000 n -0000144557 00000 n -0000476334 00000 n -0000153871 00000 n -0000153807 00000 n -0000153743 00000 n -0000153679 00000 n -0000153615 00000 n -0000153551 00000 n -0000153487 00000 n -0000153423 00000 n -0000153359 00000 n -0000153295 00000 n -0000153231 00000 n -0000153167 00000 n -0000153103 00000 n -0000153039 00000 n -0000152975 00000 n -0000152911 00000 n -0000152847 00000 n -0000152783 00000 n -0000152719 00000 n -0000152655 00000 n -0000152591 00000 n -0000152527 00000 n -0000152463 00000 n -0000152399 00000 n -0000152335 00000 n -0000152271 00000 n -0000152207 00000 n -0000152143 00000 n -0000152079 00000 n -0000152015 00000 n -0000151951 00000 n -0000151887 00000 n -0000151823 00000 n -0000151759 00000 n -0000151695 00000 n -0000151631 00000 n -0000151567 00000 n -0000151503 00000 n -0000151439 00000 n -0000151375 00000 n -0000151311 00000 n -0000151247 00000 n -0000151183 00000 n -0000151119 00000 n -0000151055 00000 n -0000150991 00000 n -0000150927 00000 n -0000150863 00000 n -0000150799 00000 n -0000150735 00000 n -0000150671 00000 n -0000150607 00000 n -0000150543 00000 n -0000150479 00000 n -0000150415 00000 n -0000147551 00000 n -0000147764 00000 n -0000154804 00000 n -0000154581 00000 n -0000154383 00000 n -0000154480 00000 n -0000154678 00000 n -0000154901 00000 n -0000155100 00000 n -0000155132 00000 n -0000155425 00000 n -0000155678 00000 n -0000598435 00000 n -0000598371 00000 n -0000598307 00000 n -0000598243 00000 n -0000598179 00000 n -0000598115 00000 n -0000598051 00000 n -0000597987 00000 n -0000597923 00000 n -0000597859 00000 n -0000597795 00000 n -0000597731 00000 n -0000597667 00000 n -0000597603 00000 n -0000597539 00000 n -0000597475 00000 n -0000597411 00000 n -0000597347 00000 n -0000597283 00000 n -0000597219 00000 n -0000597155 00000 n -0000597091 00000 n -0000597027 00000 n -0000596963 00000 n -0000596899 00000 n -0000596835 00000 n -0000596771 00000 n -0000596707 00000 n -0000596643 00000 n -0000596579 00000 n -0000596515 00000 n -0000596451 00000 n -0000596387 00000 n -0000596323 00000 n -0000596259 00000 n -0000596195 00000 n -0000596131 00000 n -0000596067 00000 n -0000596003 00000 n -0000595939 00000 n -0000595875 00000 n -0000595811 00000 n -0000595747 00000 n -0000595683 00000 n -0000595619 00000 n -0000595555 00000 n -0000595491 00000 n -0000595427 00000 n -0000595363 00000 n -0000595299 00000 n -0000595235 00000 n -0000595171 00000 n -0000595107 00000 n -0000595043 00000 n -0000594979 00000 n -0000594915 00000 n -0000594851 00000 n -0000598497 00000 n -trailer -<]>> -startxref -598681 -%%EOF diff --git a/public/assets/images/strolch_mascot.eps b/public/assets/images/strolch_mascot.eps deleted file mode 100644 index 9d291da..0000000 Binary files a/public/assets/images/strolch_mascot.eps and /dev/null differ diff --git a/public/assets/images/strolch_mascot.png b/public/assets/images/strolch_mascot.png deleted file mode 100644 index a9c6c89..0000000 Binary files a/public/assets/images/strolch_mascot.png and /dev/null differ diff --git a/public/assets/images/strolch_mascot.svg b/public/assets/images/strolch_mascot.svg deleted file mode 100644 index 74d917a..0000000 --- a/public/assets/images/strolch_mascot.svg +++ /dev/null @@ -1,701 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/assets/images/strolch_mascot_head.png b/public/assets/images/strolch_mascot_head.png deleted file mode 100644 index bd5175f..0000000 Binary files a/public/assets/images/strolch_mascot_head.png and /dev/null differ diff --git a/public/assets/images/strolch_mascot_head.svg b/public/assets/images/strolch_mascot_head.svg deleted file mode 100644 index 1e9cf92..0000000 --- a/public/assets/images/strolch_mascot_head.svg +++ /dev/null @@ -1,602 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/assets/images/strolch_mascot_hero.png b/public/assets/images/strolch_mascot_hero.png deleted file mode 100644 index a85ef0c..0000000 Binary files a/public/assets/images/strolch_mascot_hero.png and /dev/null differ diff --git a/public/assets/images/strolch_mascot_hero.svg b/public/assets/images/strolch_mascot_hero.svg deleted file mode 100644 index b3783d0..0000000 --- a/public/assets/images/strolch_mascot_hero.svg +++ /dev/null @@ -1,771 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Strolch - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/assets/images/strolch_mascot_huge.png b/public/assets/images/strolch_mascot_huge.png deleted file mode 100644 index 6dc9437..0000000 Binary files a/public/assets/images/strolch_mascot_huge.png and /dev/null differ diff --git a/public/assets/images/strolch_mascot_logo.png b/public/assets/images/strolch_mascot_logo.png deleted file mode 100644 index 8d03bb1..0000000 Binary files a/public/assets/images/strolch_mascot_logo.png and /dev/null differ diff --git a/public/assets/images/strolch_mascot_logo.svg b/public/assets/images/strolch_mascot_logo.svg deleted file mode 100644 index f000d1d..0000000 --- a/public/assets/images/strolch_mascot_logo.svg +++ /dev/null @@ -1,730 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Strolch - - diff --git a/public/assets/images/strolch_mascot_original.svg b/public/assets/images/strolch_mascot_original.svg deleted file mode 100644 index a6dbd7f..0000000 --- a/public/assets/images/strolch_mascot_original.svg +++ /dev/null @@ -1,327 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - STROLCH - - - - - - - - - STROLCH - - - - - - - - - - - - - - - - - - - STROLCH - STROLCH - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/assets/images/strolch_mascot_small.png b/public/assets/images/strolch_mascot_small.png deleted file mode 100644 index 48fe36b..0000000 Binary files a/public/assets/images/strolch_mascot_small.png and /dev/null differ diff --git a/public/assets/xsd/StrolchModel-1.6.xsd b/public/assets/xsd/StrolchModel-1.6.xsd deleted file mode 100644 index 0375feb..0000000 --- a/public/assets/xsd/StrolchModel-1.6.xsd +++ /dev/null @@ -1,201 +0,0 @@ - - - - - This is Version 1.6.x of the StrolchModel XSD. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/public/blog/index.html b/public/blog/index.html deleted file mode 100644 index d8cad25..0000000 --- a/public/blog/index.html +++ /dev/null @@ -1,7 +0,0 @@ -Blog - Strolch

Blog

About

The official Strolch blog with news, ideas, and thoughts on using Strolch.

Strolch is an open source component based software agent written in Java and can -be compared, in a light sense, with the Java EE stack: Strolch takes care of -persistence, implements Services for use cases, Commands as re-usable algorithms -and has a parameterized data model.

Entries

\ No newline at end of file diff --git a/public/blog/index.xml b/public/blog/index.xml deleted file mode 100644 index 112d90e..0000000 --- a/public/blog/index.xml +++ /dev/null @@ -1,38 +0,0 @@ -Blog on Strolchhttps://strolch.li/blog/Recent content in Blog on StrolchHugo -- gohugo.ioen-usMon, 29 Aug 2022 09:10:00 +0200Strolch PLC 1.2.3 releasedhttps://strolch.li/blog/post-00018/Mon, 29 Aug 2022 09:10:00 +0200https://strolch.li/blog/post-00018/Strolch PLC 1.2.3 released Strolch PLC version 1.2.3 has been deployed to Maven Central' -This is a maintenance release, as 1.2.2 pointed to Strolch 1.8.4 which was not released to Maven Central.Strolch 1.8.5 and PLC 1.2.2 are outhttps://strolch.li/blog/post-00017/Wed, 17 Aug 2022 15:50:00 +0200https://strolch.li/blog/post-00017/Strolch 1.8.5 and PLC 1.2.2 are out JDK 17 ready! -Unbelievable, but the entire 1.7.x branch was never blogged about or deployed to Maven. We did do quite a few releases of the Java 11 version, but never got around to releasing to Maven. -Now we have released the 1.8.x branch of Strolch and deployed to Maven Central. -The 1.8.x branch requires JDK 17, but is still on Tomcat 9.Strolch PLC now also on Maven Centralhttps://strolch.li/blog/post-00016/Fri, 01 Jan 2021 00:00:00 +0100https://strolch.li/blog/post-00016/Strolch PLC now also on Maven Central Strolch PLC version 1.0.7 has been deployed to Maven Central for easier integration into your projects -To more easily use Strolch PLC in your project, we have now deployed the latest Strolch PLC version to Maven Central. This version 1.0.7 depends on Strolch version 1.6.100. -Enjoy coding!Release of Strolch 1.6.100https://strolch.li/blog/post-00015/Wed, 14 Jul 2021 20:25:11 +0200https://strolch.li/blog/post-00015/Release of Strolch 1.6.100 The 100. Strolch release of the 1.6 branch and a brand new website! -Ok, so Maven doesn&rsquo;t exactly have 100 releases on it, but even though we have been quiet on public releases, Strolch has seen many refactorings, fixes, new features etc. over the past three years of its last release. -Some notable changes: -I18n Support for StrolchExceptions. Better performance for reports on large joins.Strolch Reportshttps://strolch.li/blog/post-00014/Fri, 30 Jun 2017 00:00:00 +0100https://strolch.li/blog/post-00014/Strolch Reports Strolch can do reports! -A feature we haven&rsquo;t written about yet is the report API. Strolch has it&rsquo;s own API to generate reports of data, and since we have a generic model, we use Resource of type Report to define them. -Go check out the documentation and then enjoy using this easy way to deliver the reports your peers require.Strolch Searcheshttps://strolch.li/blog/post-00013/Fri, 30 Jun 2017 00:00:00 +0100https://strolch.li/blog/post-00013/Strolch Searches Strolch queries are deprecated! -Strolch has had once again many changes, and fixes etc. One important thing to note is that we have removed support for transactional mode and have rewritten how models are searched. Thus the search API was born. -Go check out the Strolch Search documentation and then go rewrite your searches =)). -Strolch tag 1.6.51 has all those juicy changes!Wow, the many changes!https://strolch.li/blog/post-00012/Tue, 21 Mar 2017 00:00:00 +0100https://strolch.li/blog/post-00012/Wow, the many changes! So many changes, and so long no update - not good! -Oh boy, have we forgotten to update you all on the latest awesome features in Strolch! There are over 123 commits since the last tag 1.3.0, so that alone merits a new blog post. -Currently the latest tag is 1.5.5, but this version is actually already quite old, as it was created on 31. January 2017 and there are 53 new commits ahead of the tag.Strolch now on Maven Centralhttps://strolch.li/blog/post-00011/Thu, 22 Sep 2016 00:00:00 +0100https://strolch.li/blog/post-00011/Strolch now on Maven Central Release Version 1.3.0 released and deployed to Maven Central -We have released a new version of Strolch so that you can now go and use the the latest features in Strolch. -Further we have now deployed Strolch to Maven Central, so it is easier than ever to use Strolch in your projects. No need to download first or use a special repository - just define the dependencies as you would any other dependency.Versioning of objectshttps://strolch.li/blog/post-00010/Mon, 08 Aug 2016 00:00:00 +0100https://strolch.li/blog/post-00010/Versioning of objects Opt-In versioning of objects -A major new feature has landed in Strolch. Now, using opt-in, it is possible to have all changes to the object model be versioned. This means that any change to Order, Resource or Activity is automatically versioned and one can then revert to this version later on. -This will make it far easier to implement undo operations in applications since it is an inherent part of the lifecycle of objects in Strolch.Release 1.2.0https://strolch.li/blog/post-00009/Mon, 04 Jul 2016 00:00:00 +0100https://strolch.li/blog/post-00009/Release 1.2.0 Release of Strolch 1.2.0 -A few months ago we informed of the soon to be released version 1.1.0. Well, we decided to jump to 1.2.0 because we did some refactorings. All the eitchnet projects have been melted into Strolch and thus now it&rsquo;s all one nice package. This will result in simpler development and less constraints on APIs between the two projects. -Other than that, not much changed, but we are continually working on Strolch, so go grab your latest copy and have fun coding!Strolch Updatehttps://strolch.li/blog/post-00008/Sat, 09 Apr 2016 00:00:00 +0100https://strolch.li/blog/post-00008/Strolch Update Long due update on Strolch development. -Although we have been rather quiet in the last couple of months, anyone viewing Strolch&rsquo;s commit log, will see that we certainly didn&rsquo;t halt Strolch development. -We have been hard at work, using Strolch in projects, which required many new features and fixes. The commit log shows as of today over 180 commits since the release tag 1.0.0. -Some of the most exciting changes are:Activities: Beginning of the planning enginehttps://strolch.li/blog/post-00007/Wed, 08 Jul 2015 00:00:00 +0100https://strolch.li/blog/post-00007/Activities: Beginning of the planning engine The ground work of the Strolch planning engine has been laid. -One of the core ideas in building Strolch was to create a planning engine. The planning engine would work in combination of Order objects representing customer orders, Resource objects representing machines, human resources, etc., and Activity/Action hierarchies defining a workflow. -With the latest couple of commits to Strolch we have now added Activities and a basic planning of Actions onto Resources.Strolch Documentationhttps://strolch.li/blog/post-00006/Mon, 06 Apr 2015 00:00:00 +0100https://strolch.li/blog/post-00006/Strolch Documentation Any good software has some decent documentation explaining concepts, best practices and gives examples. -So this post is to announce that there is now a new page on Strolch&rsquo;s website with a bit of documentation. This first documentation explains the Strolch runtime and some of the do and don&rsquo;t in Strolch code. -Bear with us, writing documentation takes time and can be outdated quickly, so we will make an effort to keep everything up to date and add more documentation, but this is a start.Strolch Release 1.0.0https://strolch.li/blog/post-00005/Tue, 31 Mar 2015 00:00:00 +0100https://strolch.li/blog/post-00005/Strolch Release 1.0.0 Finally Version 1.0.0 of Strolch has been released and can be downloaded immediately. -Before 1.0.0 could be released, some major changes were decided, all driven by the first big project using Strolch as its underlying stack. Those changes were minor, and really major, but should make Strolch better and was important for the first release. -Here is a list of the most interesting changes: -Java 8 - Strolch was ported to Java 8.DurationParameter and other minor changes: Release 1.0.0-RC4https://strolch.li/blog/post-00004/Thu, 09 Oct 2014 00:00:00 +0100https://strolch.li/blog/post-00004/DurationParameter and other minor changes: Release 1.0.0-RC4 New DurationParameter and additional minor changes: Release of 1.0.0-RC4 which can be downloaded on the download page. -While implementing a use case in a Strolch based application it was detected that an essential parameter type was missing, the DurationParameter. This parameter currently stores the value as a long in memory and serializes to ISO8601. As soon as we move Strolch to Java8, we will change this to use the Period class in the new Java8 date and time API.DB Initialization: Release 1.0.0-RC3https://strolch.li/blog/post-00003/Sun, 24 Aug 2014 00:00:00 +0100https://strolch.li/blog/post-00003/DB Initialization: Release 1.0.0-RC3 Important feature Database Initialization added: Release of 1.0.0-RC3 which can be downloaded on the download page. -When living continuous integration and continuous delivery, it is vital that things like database migrations and initialization are performed in a controlled, but automatic way. -A Strolch-based application is using the PostgreSQL persistence layer. The implementation understands the concepts of migration, and validating the database schema, but currently a mechanism to automatically initialize the database with a minimal set of data was missing.Release 1.0.0-RC2https://strolch.li/blog/post-00002/Fri, 22 Aug 2014 00:00:00 +0100https://strolch.li/blog/post-00002/Release 1.0.0-RC2 Scratch that RC1, here is the brand new 1.0.0-RC2 which can be downloaded on the download page. -So, as expected there were a few bugs, for instance the Strolch tutorial apps didn&rsquo;t start, so now i fixed those and released an RC2. Go get it and give it a try!Release 1.0.0-RC1https://strolch.li/blog/post-00001/Wed, 20 Aug 2014 00:00:00 +0100https://strolch.li/blog/post-00001/Release 1.0.0-RC1 With the Go-Live of a Strolch-based application around the corner, it is time to release Version 1.0.0 of Strolch. To this affect we have now released version 1.0.0-RC1 which can be downloaded on the download page. -Story Strolch as a component based software agent has been two years in the making. The concepts in Strolch have been taken from a proprietary planning, scheduling and controlling software agent, which was, and is been, used in industrial automation, logistics and production. \ No newline at end of file diff --git a/public/blog/post-00001/index.html b/public/blog/post-00001/index.html deleted file mode 100644 index 2b15bf8..0000000 --- a/public/blog/post-00001/index.html +++ /dev/null @@ -1,5 +0,0 @@ -Release 1.0.0-RC1 - Strolch

Release 1.0.0-RC1

Release 1.0.0-RC1

With the Go-Live of a Strolch-based application around the corner, it is time to release Version 1.0.0 of Strolch. To this affect we have now released version 1.0.0-RC1 which can be downloaded on the download page.


Story

Strolch as a component based software agent has been two years in the making. The concepts in Strolch have been taken from a proprietary planning, scheduling and controlling software agent, which was, and is been, used in industrial automation, logistics and production. Strolch was created to bring the concepts, which were working well for small teams to go-live with large projects in short to medium time-frames to the open source world.

Strolch was completely rewritten using the key concepts of a parameterized object model and a component based agent but remembering which clutches the original implementation had, thus trying to eradicate those without bringing in new ones. It might not be perfect in version 1.0.0, but it is a starting point form which to carry on from.

Features

Strolch isn’t feature complete by a long shot, but it sure has got many features which make it useable in a concrete project, thus making sure it is not vaporware =)

The following is a list of key features, many of which were driven by concrete project requirements:

  • Separate containers for models (mandates)
  • Parameterized model with full CRUD for Resource and Order objects
  • Timed values on Resources to map values by time
  • Built-in versioning of model - configurable by Realm
  • Transparent runtime modes: TRANSIENT, CACHED, TRANSACTIONAL*
  • Service and Command pattern for reusing functionality
  • XML File based persistence layer*
  • PostgreSQL persistence layer*
  • Querying using a fluent API
  • Services to import and export a model to XML
  • Integrated authentication and authorization to validate user privileges using Privilege
  • Ready to use Observer pattern
  • (currently) Read-only REST API to access the agent model remotely
  • Configurable environments
  • Opt-in audit trail (including read access, and the audits themselves)
  • Basic components required to communicate with external devices using TCP/IP
  • With the light weight implementation, where there are basically no third party libraries required for the normal runtime, Strolch has a minimal foot print which allows it to run on small devices for instance a BeagleBone Black. Using the in-memory mode, it is an easy feat to set up test environments with little to no further requirements than the JVM.

Future

So what is planned for the future? Although Strolch has quite a few interesting features, it is by no way feature complete. The greatest wish is for Strolch to become a community driven platform, so many new features will arise in the future, but at least one major future feature which will be tackled in the near future and will certainly drive the next major release is a planning and scheduling engine using a Gantt chart to visualize the schedule.

The planning engine will use the timed values on Resources extensively to create a planning engine on which Workflows can be placed and allowing to detect violations and bottlenecks.

An extension of the planning of the scheduling engine will allow more than just placing Workflows on Resources, but actually searching groups of Resources for a time slot of when to place tasks. This will allow to use capacity constraints to plan and schedule workflows using different algorithms, and respecting calendars etc.

Further time will be spent on giving Strolch it’s own UI. Currently the idea is to use Google’s Polymer to implement the UI, thus creating reusable widgets that can be used in projects.

Take it for a spin

So, now the important part is for new users to start using Strolch for their own projects. Go ahead, check out the Downloads page for the latest release and then checkout the two tutorial applications to get yourself up to speed!

Don’t hesitate to send us feedback or questions, we will be delighted to help you get your Strolch-based application up and running, or provide feedback to your concerns!

Developers

Robert von Burg -Reto Breitenmoser -Dr. Martin Smock

*Currently Transactional mode is missing concrete implementation for querying for the XML persistence

\ No newline at end of file diff --git a/public/blog/post-00002/index.html b/public/blog/post-00002/index.html deleted file mode 100644 index aa3b5db..0000000 --- a/public/blog/post-00002/index.html +++ /dev/null @@ -1,6 +0,0 @@ -Release 1.0.0-RC2 - Strolch

Release 1.0.0-RC2

Release 1.0.0-RC2

Scratch that RC1, here is the brand new 1.0.0-RC2 which can be downloaded on the -download page.


So, as expected there were a few bugs, for instance the Strolch tutorial apps -didn’t start, so now i fixed those and released an RC2. Go get it and give it a -try!

\ No newline at end of file diff --git a/public/blog/post-00003/index.html b/public/blog/post-00003/index.html deleted file mode 100644 index e6fe15c..0000000 --- a/public/blog/post-00003/index.html +++ /dev/null @@ -1,22 +0,0 @@ -DB Initialization: Release 1.0.0-RC3 - Strolch

DB Initialization: Release 1.0.0-RC3

DB Initialization: Release 1.0.0-RC3

Important feature Database Initialization added: Release of 1.0.0-RC3 which can -be downloaded on the download page.


When living continuous integration and continuous delivery, it is vital that -things like database migrations and initialization are performed in a -controlled, but automatic way.

A Strolch-based application is using the PostgreSQL persistence layer. The -implementation understands the concepts of migration, and validating the -database schema, but currently a mechanism to automatically initialize the -database with a minimal set of data was missing.

Migrating a database for Strolch is mostly a one time thing. The object model in -Strolch is quite static, so there is seldom a need to migrate the database. -Domain specific changes, i.e. new Resources, or adding Parameters to Resources, -is not a schema change. Thus, instead of going the way other frameworks go, e.g. -Ruby on Rails, we built the data initialization right into the -PersistenceHandler.

Now if the PostgreSQL PersistenceHandler creates the schema, then it might also -initialize the minimal set of data. For this to work, the PersistenceHandler -checks if the flags allowSchemaCreation, allowSchemaDrop and -allowDbInitOnSchemaCreate. If those flags are enabled, and the schema was -created during initialization, then the database is also initialized with the -contents of the XML file configured under key dataStoreFile of the relevant -Realm.

The database initialization is done as a system user action which must have the -name db_initializer. This is another fail-safe, so that on a production system, -this user can simply be deleted.

So, Strolch 1.0.0-RC3 is out the door, go ahead and try it out.

\ No newline at end of file diff --git a/public/blog/post-00004/index.html b/public/blog/post-00004/index.html deleted file mode 100644 index d2a75e4..0000000 --- a/public/blog/post-00004/index.html +++ /dev/null @@ -1,9 +0,0 @@ -DurationParameter and other minor changes: Release 1.0.0-RC4 - Strolch

DurationParameter and other minor changes: Release 1.0.0-RC4

DurationParameter and other minor changes: Release 1.0.0-RC4

New DurationParameter and additional minor changes: Release of 1.0.0-RC4 which -can be downloaded on the download page.


While implementing a use case in a Strolch based application it was detected -that an essential parameter type was missing, the DurationParameter. This -parameter currently stores the value as a long in memory and serializes to -ISO8601. -As soon as we move Strolch to Java8, we will change this to use the -Period class in the new Java8 date and time API.

In addition to the new parameter, a couple of other changes were made:

  • 32c1785 [Major] Added Session timeout handling
  • d55371e [Minor] fixed component version descriptions
  • c1cdfbb [Bugfix] added missing cloning of StringSetTimedState in Resources
  • 8f50a15 [Major] changed XML format of time value of TimedStates to be ISO8601
  • 5fbbe50 [Bugfix] fix NPE when cloning Resources with no state vars
  • b77f4b2 [New] added TimeVariable.clear()-method
  • Updated sub-module ch.eitchnet.utils to 906d24d
  • Updated sub-module ch.eitchnet.privilege to aa16887

So, Strolch 1.0.0-RC4 is out the door, go ahead and try it out.

\ No newline at end of file diff --git a/public/blog/post-00005/index.html b/public/blog/post-00005/index.html deleted file mode 100644 index 530183c..0000000 --- a/public/blog/post-00005/index.html +++ /dev/null @@ -1,20 +0,0 @@ -Strolch Release 1.0.0 - Strolch

Strolch Release 1.0.0

Strolch Release 1.0.0

Finally Version 1.0.0 of Strolch has been released and can be downloaded immediately.


Before 1.0.0 could be released, some major changes were decided, all driven by -the first big project using Strolch as its underlying stack. Those changes were -minor, and really major, but should make Strolch better and was important for -the first release.

Here is a list of the most interesting changes:

  • Java 8 - Strolch was ported to Java 8. This gives a lot of cool features: The -stream API, lambdas, the new time API, etc.
  • TX refactoring: Strolch transactions are instances of Closeable so that they -are closed using a try-with-resource block in Java7. The change that was -required was to not auto commit. Now a TX is read-only and one has to set the -auto commit as the last statement. See this commit for more information.
  • Added a tx.flush() to allow an implementation to flush part of a transaction, -this feature is vital to perform parts of a transaction before deciding if the -TX should be committed.
  • Fixed the issue where data store mode CACHED performed TRANSACTIONAL queries, -instead of staying in-memory.
  • ParameterSelection.stringListSelection() uses a StringMatchMode instead of -just equals()
  • ParameterSelection.dateRangeSelection() uses a DateRange instead of just -equals()
  • Added the MigrationsHandler to use to perform code migrations of production -data bases where data shouldn’t go lost.
  • And many more…

Strolch 1.1.0 is already in development and can also be downloaded from the -download page. Here you can see the current change list -on GitHub. For -instance heavy work has been done to implement privilege management by adding a -REST API. Looking forward to a wonderful next Strolch release.

\ No newline at end of file diff --git a/public/blog/post-00006/index.html b/public/blog/post-00006/index.html deleted file mode 100644 index 56e0572..0000000 --- a/public/blog/post-00006/index.html +++ /dev/null @@ -1,10 +0,0 @@ -Strolch Documentation - Strolch

Strolch Documentation

Strolch Documentation

Any good software has some decent documentation explaining concepts, best -practices and gives examples.


So this post is to announce that there is now a new page on Strolch’s website -with a bit of documentation. This first documentation explains the Strolch -runtime and some of the do and don’t in Strolch code.

Bear with us, writing documentation takes time and can be outdated quickly, so -we will make an effort to keep everything up to date and add more documentation, -but this is a start.

So go ahead and read the documentation , and if you haven’t already, also read -the rest of the website which should give some more insight into the what, why -and how of Strolch.

\ No newline at end of file diff --git a/public/blog/post-00007/index.html b/public/blog/post-00007/index.html deleted file mode 100644 index fd37514..0000000 --- a/public/blog/post-00007/index.html +++ /dev/null @@ -1,19 +0,0 @@ -Activities: Beginning of the planning engine - Strolch

Activities: Beginning of the planning engine

Activities: Beginning of the planning engine

The ground work of the Strolch planning engine has been laid.


One of the core ideas in building Strolch was to create a planning engine. The -planning engine would work in combination of Order objects representing customer -orders, Resource objects representing machines, human resources, etc., and -Activity/Action hierarchies defining a workflow.

With the latest couple of commits to Strolch we have now added Activities and a -basic planning of Actions onto Resources. Activities have an ordered list of -IActivityElement which allows creating an arbitrary deep tree structure of -Activity and Action elements.

Action objects have a list of IValueChange objects which define the start, end -and further value changes over time on a referenced Resource. Thus planning an -Activity is done by iterating the Activity hierarchy and for every Action -selecting a relevant Resource and then then applying the changes of the Action -on to the referenced TimeState on the Resource.

This implementation is currently very simple as it ignores all constraints which -a Resource might have. In further development we shall implement a Violation -model so that UIs can be built to visualize the over-use of Resources.

In even further steps we would then start implementing algorithms to not just -apply the changes onto a Resource, but to actually search the Resource for time -slots when the value changes would not violate any constraints applied to the -resource.

We are very much looking forward to these new features. Stay tuned for your -updates - even though they do take their time to arrive =).

\ No newline at end of file diff --git a/public/blog/post-00008/index.html b/public/blog/post-00008/index.html deleted file mode 100644 index c92837b..0000000 --- a/public/blog/post-00008/index.html +++ /dev/null @@ -1,17 +0,0 @@ -Strolch Update - Strolch

Strolch Update

Strolch Update

Long due update on Strolch development.


Although we have been rather quiet in the last couple of months, anyone viewing -Strolch’s commit log, will see that we certainly didn’t halt Strolch -development.

We have been hard at work, using Strolch in projects, which required many new -features and fixes. The commit log shows as of today over 180 commits since the -release tag 1.0.0.

Some of the most exciting changes are:

  • REST API to query model, incl. privilege management.
  • JSON marshalling of all elements.
  • Added Policies
  • Added persisting of user sessions.
  • New JavaScript based UI to view Strolch’s model. This is an initial version -and more UI elements and functions will follow.
  • Basic planning engine functionality.

Further new features and changes are:

  • Implemented a REST API to the privilege management - Now users can be added, -changed, etc. via call to the appropriate URL under ../strolch/privilege/*.
  • Implemented a REST API to query the user sessions. Incl. invalidating sessions -to forcefully logout users.
  • Implemented a REST API to query Audits.
  • Implemented REST API to query Orders, Resources and Activities/Actions
  • Implemented REST API to update Resources and Orders from XML
  • REST API to authenticate now adds a cookie, so authorization is much simpler.
  • Added convenience methods in Service and Command to easily perform system user -actions.
  • Added audits for login/logout of users.
  • Added audits for changes to privilege management.
  • PostgreSQL persistence layer now -uses HikariCP -for connection pooling.
  • Implemented a performance test project
  • Added new Parameters of type IntegerList, FloatList and LongList.
  • Added feature to ignore a realm on DB init.
  • Implemented core planning functionality.
  • Added strolch_minimal and strolch_minimal_rest projects to easily get started.
  • Query API now has built in ordering.
  • Added Policy to all root elements.
  • Added new planning web app project. This is a test application for demoing the -planning engine functionality of Strolch.
  • Adding the persisting and reloading of user sessions, so that a new start of -Strolch does not logout users.
  • Implemented to JSON visitors for all root elements.

So, although we’ve been rather quiet on the blog and on social media, we have -not been quiet in Strolch’s development. We are planning to release version -1.1.0 soon, so stay tuned!

\ No newline at end of file diff --git a/public/blog/post-00009/index.html b/public/blog/post-00009/index.html deleted file mode 100644 index c1cde10..0000000 --- a/public/blog/post-00009/index.html +++ /dev/null @@ -1,8 +0,0 @@ -Release 1.2.0 - Strolch

Release 1.2.0

Release 1.2.0

Release of Strolch 1.2.0


A few months ago we informed of the soon to be released version 1.1.0. Well, we -decided to jump to 1.2.0 because we did some refactorings. All the eitchnet -projects have been melted into Strolch and thus now it’s all one nice package. -This will result in simpler development and less constraints on APIs between the -two projects.

Other than that, not much changed, but we are continually working on Strolch, so -go grab your latest copy and have fun coding!

\ No newline at end of file diff --git a/public/blog/post-00010/index.html b/public/blog/post-00010/index.html deleted file mode 100644 index 9d5f3f7..0000000 --- a/public/blog/post-00010/index.html +++ /dev/null @@ -1,11 +0,0 @@ -Versioning of objects - Strolch

Versioning of objects

Versioning of objects

Opt-In versioning of objects


A major new feature has landed in Strolch. Now, using opt-in, it is possible to -have all changes to the object model be versioned. This means that any change to -Order, Resource or Activity is automatically versioned and one can then revert -to this version later on.

This will make it far easier to implement undo operations in applications since -it is an inherent part of the lifecycle of objects in Strolch.

Since Strolch is supposed to be used also in small footprint hardware, this -option is opt-in.

A side affect of this new feature is that we have for the time being not ported -the XML persistence layer. If this is required, then someone drop us a note and -we’ll check on it.

So now go ahead and add <enableVersioning>true</enableVersioning> to your Realm -so that versioning is enabled.

\ No newline at end of file diff --git a/public/blog/post-00011/index.html b/public/blog/post-00011/index.html deleted file mode 100644 index e45bed4..0000000 --- a/public/blog/post-00011/index.html +++ /dev/null @@ -1,9 +0,0 @@ -Strolch now on Maven Central - Strolch

Strolch now on Maven Central

Strolch now on Maven Central

Release Version 1.3.0 released and deployed to Maven Central


We have released a new version of Strolch so that you can now go and use the the -latest features in Strolch.

Further we have now deployed Strolch to Maven Central, so it is easier than ever -to use Strolch in your projects. No need to download first or use a special -repository - just define the dependencies as you would any other dependency.

Some of the new features:

  • Marshallers for JSON
  • Versioning built into Strolch
  • Implemented password reset API for Privilege
  • New Component MailHandler
  • New ToFlatJsonVisitor for simple marshalling in REST APIs
  • Added CRUD Commands and Services for Activities
  • Further additional bugfixes

Strolch has also been moved to -another organisation on GitHub, so if -you’re compiling Strolch from source, please update your GIT remote -configurations.

Have fun using the latest and greatest version of Strolch!

\ No newline at end of file diff --git a/public/blog/post-00012/index.html b/public/blog/post-00012/index.html deleted file mode 100644 index 6c39e1f..0000000 --- a/public/blog/post-00012/index.html +++ /dev/null @@ -1,27 +0,0 @@ -Wow, the many changes! - Strolch

Wow, the many changes!

Wow, the many changes!

So many changes, and so long no update - not good!


Oh boy, have we forgotten to update you all on the latest awesome features in -Strolch! There are -over 123 commits -since the last tag 1.3.0, so that alone merits a new blog post.

Currently the latest tag is 1.5.5, but this version is actually already quite -old, as it was created on 31. January 2017 and there are 53 new commits ahead of -the tag.

Enough of all the commits, lets get to the new features:

  • Added new generic report creator
  • Added Activity.TimeOrdering and updated Model XSD
  • Implemented State Model on Activity/Actions
  • Implemented execution of Activities
  • Implemented EventBasedExecutionHandler
  • Added StrolchXmlParser to quickly parse from a file
  • Add Activity.remove(String) to remove an element
  • Refactored LockHandler to use Locator
  • Added Activity.getActionsWithState(State)
  • Moved *ToFlat and *FromFlat Json Visitors to strolch model
  • Added StrolchElementQuery.internal()
  • Added Parameter.clearValue() and list parameters use , as sep
  • Json Tags are now in Tags.Json and are drinking camel-case
  • Moved PrivilegeAddUserService to command, added tests
  • Lots of JavaDoc updates
  • Refactored code for REST Inspector to use gson
  • Added inspector REST api for activities
  • Inspector now has offset/limit for queries
  • Added new StringMapArgument for StrolchServices
  • Added missing activity observer calls in AbstractTransaction
  • Added StringMapResult to use as a ServiceResult
  • Removed many visitors and implemented proper visitor pattern…
  • Don’t log stack trace if certificate does not exist
  • SmtpMailer now understands whitelists for override
  • Fixed locator finding for Activity and Action
  • Fixed undo logic for general commands

To summarize, execution and reporting are the two new features that make -Strolch really awesome! We use execution to perform a number of actions on a -remote device connected to a Strolch agent through WebSockets. This allows -serial and parallel execution of actions and of course locking of concurrently -used resources.

In an enterprise world reports can never be missed, so we needed an API to -create reports. Of course that API was created in a way that all things are done -in Strolch: generically. Thus a report is created as a Resource, defining the -report object, columns and any relevant joins.

And one of the really cool things is that we have started with a UI for Strolch. -There is now an Inspector -with which the entire data model of a running agent can be seen. This inspector -is built using Polymer and WebComponents and thus can be easily embedded in your -application.

To facilitate the authentication of a user for the inspector, -an authentication component was -created as well. And of course i18n can’t be forgotten, so there is a component -for that too.

To simplify tasks in a web project, there is also -a StrolchJs repository where certain -Strolch specific things are handled e.g. querying the authenticated user’s roles -etc.

The release of the next Strolch version isn’t defined yet, as we are internally -building a project on all these changes and with the release 1.0.0 of that -project (which will be soon), we shall perform the next release of Strolch.

Until then, happy coding!

\ No newline at end of file diff --git a/public/blog/post-00013/index.html b/public/blog/post-00013/index.html deleted file mode 100644 index cdea435..0000000 --- a/public/blog/post-00013/index.html +++ /dev/null @@ -1,7 +0,0 @@ -Strolch Searches - Strolch

Strolch Searches

Strolch Searches

Strolch queries are deprecated!


Strolch has had once again many changes, and fixes etc. One important thing to -note is that we have removed support for transactional mode and have rewritten -how models are searched. Thus the search API was born.

Go check out the Strolch Search documentation and -then go rewrite your searches =)).

Strolch tag 1.6.51 has all -those juicy changes!

\ No newline at end of file diff --git a/public/blog/post-00014/index.html b/public/blog/post-00014/index.html deleted file mode 100644 index 1f48876..0000000 --- a/public/blog/post-00014/index.html +++ /dev/null @@ -1,6 +0,0 @@ -Strolch Reports - Strolch

Strolch Reports

Strolch Reports

Strolch can do reports!


A feature we haven’t written about yet is the report API. Strolch has it’s own -API to generate reports of data, and since we have a generic model, we use -Resource of type Report to define them.

Go check out the documentation and then enjoy using this easy way to deliver the -reports your peers require.

\ No newline at end of file diff --git a/public/blog/post-00015/index.html b/public/blog/post-00015/index.html deleted file mode 100644 index 2a8ff5f..0000000 --- a/public/blog/post-00015/index.html +++ /dev/null @@ -1,10 +0,0 @@ -Release of Strolch 1.6.100 - Strolch

Release of Strolch 1.6.100

Release of Strolch 1.6.100

The 100. Strolch release of the 1.6 branch and a brand new website!


Ok, so Maven doesn’t exactly have 100 releases on it, but even though we have -been quiet on public releases, Strolch has seen many refactorings, fixes, new -features etc. over the past three years of its last release.

Some notable changes:

  • I18n Support for StrolchExceptions.
  • Better performance for reports on large joins.
  • Move to JDK 11+.
  • Refactoring to use of Java 9 LocalDateTime and ZonedDateTime where applicable.
  • Added Controllers for better execution handling.
  • Significantly simplified the methods to change the model.
  • Simpler methods to retrieve relationship entities.
  • Updated most libraries to their latest versions.
  • Added a DataArchiveHandler to archive entities.
  • Added require password change feature, and storing of login and password change history
  • LDAP integration
  • Added session keep alive
  • Search expression simplifications
  • New TextParameter for when persisting large values with whitespace and special characters
  • Basic Auth for REST APIs, if no UI needed for scripting
  • Many additional fixes, tweaks and helper functions

Another new addition to the Strolch family is Strolch PLC. The Strolch -PLC code allows one to use the same model but on a device acting as a soft PLC, -e.g. a Raspberry Pi. This PLC code can then communicate using WebSockets with a -Strolch instance, having quite seamless interaction with Activities which really -shows the potential of using Strolch’s model in the shop floor.

We’ve been running the Strolch PLC in a mission critical shop floor application -to control conveyors which are filled by a dispensing robot.

So, Strolch 1.6.100 is out the door, go ahead and try it out.

\ No newline at end of file diff --git a/public/blog/post-00016/index.html b/public/blog/post-00016/index.html deleted file mode 100644 index f9dcc8e..0000000 --- a/public/blog/post-00016/index.html +++ /dev/null @@ -1,4 +0,0 @@ -Strolch PLC now also on Maven Central - Strolch

Strolch PLC now also on Maven Central

Strolch PLC now also on Maven Central

Strolch PLC version 1.0.7 has been deployed to Maven Central for easier integration into your projects


To more easily use Strolch PLC in your project, we have now deployed the latest Strolch PLC version to Maven Central. -This version 1.0.7 depends on Strolch version 1.6.100.

Enjoy coding!

\ No newline at end of file diff --git a/public/blog/post-00017/index.html b/public/blog/post-00017/index.html deleted file mode 100644 index c2dbee5..0000000 --- a/public/blog/post-00017/index.html +++ /dev/null @@ -1,6 +0,0 @@ -Strolch 1.8.5 and PLC 1.2.2 are out - Strolch

Strolch 1.8.5 and PLC 1.2.2 are out

Strolch 1.8.5 and PLC 1.2.2 are out

JDK 17 ready!


Unbelievable, but the entire 1.7.x branch was never blogged about or deployed to Maven. We did do quite a few releases -of the Java 11 version, but never got around to releasing to Maven.

Now we have released the 1.8.x branch of Strolch and deployed -to Maven Central.

The 1.8.x branch requires JDK 17, but is still on Tomcat 9.x. We will create a new branch for Tomcat 10.x and release -that at a later date.

We also just released the Strolch PLC 1.2.x branch. This branch uses Strolch 1.8.x and is production ready.

So, Strolch 1.8.5 is out the door, go ahead and try it out.

\ No newline at end of file diff --git a/public/blog/post-00018/index.html b/public/blog/post-00018/index.html deleted file mode 100644 index a4ceda0..0000000 --- a/public/blog/post-00018/index.html +++ /dev/null @@ -1,3 +0,0 @@ -Strolch PLC 1.2.3 released - Strolch

Strolch PLC 1.2.3 released

Strolch PLC 1.2.3 released

Strolch PLC version 1.2.3 has been deployed to Maven Central'


This is a maintenance release, as 1.2.2 pointed to Strolch 1.8.4 which was not released to Maven Central.

\ No newline at end of file diff --git a/public/categories/index.html b/public/categories/index.html deleted file mode 100644 index 1250245..0000000 --- a/public/categories/index.html +++ /dev/null @@ -1,3 +0,0 @@ -Categories - Strolch

category :: -Categories

    \ No newline at end of file diff --git a/public/categories/index.xml b/public/categories/index.xml deleted file mode 100644 index 98eb24f..0000000 --- a/public/categories/index.xml +++ /dev/null @@ -1 +0,0 @@ -Categories on Strolchhttps://strolch.li/categories/Recent content in Categories on StrolchHugo -- gohugo.ioen-us \ No newline at end of file diff --git a/public/css/atom-one-dark-reasonable.css b/public/css/atom-one-dark-reasonable.css deleted file mode 100644 index fd41c99..0000000 --- a/public/css/atom-one-dark-reasonable.css +++ /dev/null @@ -1,77 +0,0 @@ -/* - -Atom One Dark With support for ReasonML by Gidi Morris, based off work by Daniel Gamage - -Original One Dark Syntax theme from https://github.com/atom/one-dark-syntax - -*/ -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - line-height: 1.3em; - color: #abb2bf; - background: #282c34; - border-radius: 5px; -} -.hljs-keyword, .hljs-operator { - color: #F92672; -} -.hljs-pattern-match { - color: #F92672; -} -.hljs-pattern-match .hljs-constructor { - color: #61aeee; -} -.hljs-function { - color: #61aeee; -} -.hljs-function .hljs-params { - color: #A6E22E; -} -.hljs-function .hljs-params .hljs-typing { - color: #FD971F; -} -.hljs-module-access .hljs-module { - color: #7e57c2; -} -.hljs-constructor { - color: #e2b93d; -} -.hljs-constructor .hljs-string { - color: #9CCC65; -} -.hljs-comment, .hljs-quote { - color: #b18eb1; - font-style: italic; -} -.hljs-doctag, .hljs-formula { - color: #c678dd; -} -.hljs-section, .hljs-name, .hljs-selector-tag, .hljs-deletion, .hljs-subst { - color: #e06c75; -} -.hljs-literal { - color: #56b6c2; -} -.hljs-string, .hljs-regexp, .hljs-addition, .hljs-attribute, .hljs-meta-string { - color: #98c379; -} -.hljs-built_in, .hljs-class .hljs-title { - color: #e6c07b; -} -.hljs-attr, .hljs-variable, .hljs-template-variable, .hljs-type, .hljs-selector-class, .hljs-selector-attr, .hljs-selector-pseudo, .hljs-number { - color: #d19a66; -} -.hljs-symbol, .hljs-bullet, .hljs-link, .hljs-meta, .hljs-selector-id, .hljs-title { - color: #61aeee; -} -.hljs-emphasis { - font-style: italic; -} -.hljs-strong { - font-weight: bold; -} -.hljs-link { - text-decoration: underline; -} diff --git a/public/css/auto-complete.css b/public/css/auto-complete.css deleted file mode 100644 index ac6979a..0000000 --- a/public/css/auto-complete.css +++ /dev/null @@ -1,47 +0,0 @@ -.autocomplete-suggestions { - text-align: left; - cursor: default; - border: 1px solid #ccc; - border-top: 0; - background: #fff; - box-shadow: -1px 1px 3px rgba(0,0,0,.1); - - /* core styles should not be changed */ - position: absolute; - display: none; - z-index: 9999; - max-height: 254px; - overflow: hidden; - overflow-y: auto; - box-sizing: border-box; - -} -.autocomplete-suggestion { - position: relative; - cursor: pointer; - padding: 7px; - line-height: 23px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - color: #333; -} - -.autocomplete-suggestion b { - font-weight: normal; - color: #1f8dd6; -} - -.autocomplete-suggestion.selected { - background: #333; - color: #fff; -} - -.autocomplete-suggestion:hover { - background: #444; - color: #fff; -} - -.autocomplete-suggestion > .context { - font-size: 12px; -} diff --git a/public/css/featherlight.min.css b/public/css/featherlight.min.css deleted file mode 100644 index 058487f..0000000 --- a/public/css/featherlight.min.css +++ /dev/null @@ -1,8 +0,0 @@ -/** - * Featherlight - ultra slim jQuery lightbox - * Version 1.7.13 - http://noelboss.github.io/featherlight/ - * - * Copyright 2018, Noël Raoul Bossart (http://www.noelboss.com) - * MIT Licensed. -**/ -html.with-featherlight{overflow:hidden}.featherlight{display:none;position:fixed;top:0;right:0;bottom:0;left:0;z-index:2147483647;text-align:center;white-space:nowrap;cursor:pointer;background:#333;background:rgba(0,0,0,0)}.featherlight:last-of-type{background:rgba(0,0,0,.8)}.featherlight:before{content:'';display:inline-block;height:100%;vertical-align:middle}.featherlight .featherlight-content{position:relative;text-align:left;vertical-align:middle;display:inline-block;overflow:auto;padding:25px 25px 0;border-bottom:25px solid transparent;margin-left:5%;margin-right:5%;max-height:95%;background:#fff;cursor:auto;white-space:normal}.featherlight .featherlight-inner{display:block}.featherlight link.featherlight-inner,.featherlight script.featherlight-inner,.featherlight style.featherlight-inner{display:none}.featherlight .featherlight-close-icon{position:absolute;z-index:9999;top:0;right:0;line-height:25px;width:25px;cursor:pointer;text-align:center;font-family:Arial,sans-serif;background:#fff;background:rgba(255,255,255,.3);color:#000;border:0;padding:0}.featherlight .featherlight-close-icon::-moz-focus-inner{border:0;padding:0}.featherlight .featherlight-image{width:100%}.featherlight-iframe .featherlight-content{border-bottom:0;padding:0;-webkit-overflow-scrolling:touch}.featherlight iframe{border:0}.featherlight *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}@media only screen and (max-width:1024px){.featherlight .featherlight-content{margin-left:0;margin-right:0;max-height:98%;padding:10px 10px 0;border-bottom:10px solid transparent}}@media print{html.with-featherlight>*>:not(.featherlight){display:none}} \ No newline at end of file diff --git a/public/css/fontawesome-all.min.css b/public/css/fontawesome-all.min.css deleted file mode 100644 index de56473..0000000 --- a/public/css/fontawesome-all.min.css +++ /dev/null @@ -1 +0,0 @@ -.fa,.fab,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{animation:fa-spin 2s infinite linear}.fa-pulse{animation:fa-spin 1s infinite steps(8)}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\f26e"}.fa-accessible-icon:before{content:"\f368"}.fa-accusoft:before{content:"\f369"}.fa-acquisitions-incorporated:before{content:"\f6af"}.fa-ad:before{content:"\f641"}.fa-address-book:before{content:"\f2b9"}.fa-address-card:before{content:"\f2bb"}.fa-adjust:before{content:"\f042"}.fa-adn:before{content:"\f170"}.fa-adobe:before{content:"\f778"}.fa-adversal:before{content:"\f36a"}.fa-affiliatetheme:before{content:"\f36b"}.fa-air-freshener:before{content:"\f5d0"}.fa-algolia:before{content:"\f36c"}.fa-align-center:before{content:"\f037"}.fa-align-justify:before{content:"\f039"}.fa-align-left:before{content:"\f036"}.fa-align-right:before{content:"\f038"}.fa-alipay:before{content:"\f642"}.fa-allergies:before{content:"\f461"}.fa-amazon:before{content:"\f270"}.fa-amazon-pay:before{content:"\f42c"}.fa-ambulance:before{content:"\f0f9"}.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-amilia:before{content:"\f36d"}.fa-anchor:before{content:"\f13d"}.fa-android:before{content:"\f17b"}.fa-angellist:before{content:"\f209"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-down:before{content:"\f107"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angry:before{content:"\f556"}.fa-angrycreative:before{content:"\f36e"}.fa-angular:before{content:"\f420"}.fa-ankh:before{content:"\f644"}.fa-app-store:before{content:"\f36f"}.fa-app-store-ios:before{content:"\f370"}.fa-apper:before{content:"\f371"}.fa-apple:before{content:"\f179"}.fa-apple-alt:before{content:"\f5d1"}.fa-apple-pay:before{content:"\f415"}.fa-archive:before{content:"\f187"}.fa-archway:before{content:"\f557"}.fa-arrow-alt-circle-down:before{content:"\f358"}.fa-arrow-alt-circle-left:before{content:"\f359"}.fa-arrow-alt-circle-right:before{content:"\f35a"}.fa-arrow-alt-circle-up:before{content:"\f35b"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-down:before{content:"\f063"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrows-alt:before{content:"\f0b2"}.fa-arrows-alt-h:before{content:"\f337"}.fa-arrows-alt-v:before{content:"\f338"}.fa-artstation:before{content:"\f77a"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asterisk:before{content:"\f069"}.fa-asymmetrik:before{content:"\f372"}.fa-at:before{content:"\f1fa"}.fa-atlas:before{content:"\f558"}.fa-atlassian:before{content:"\f77b"}.fa-atom:before{content:"\f5d2"}.fa-audible:before{content:"\f373"}.fa-audio-description:before{content:"\f29e"}.fa-autoprefixer:before{content:"\f41c"}.fa-avianex:before{content:"\f374"}.fa-aviato:before{content:"\f421"}.fa-award:before{content:"\f559"}.fa-aws:before{content:"\f375"}.fa-baby:before{content:"\f77c"}.fa-baby-carriage:before{content:"\f77d"}.fa-backspace:before{content:"\f55a"}.fa-backward:before{content:"\f04a"}.fa-balance-scale:before{content:"\f24e"}.fa-ban:before{content:"\f05e"}.fa-band-aid:before{content:"\f462"}.fa-bandcamp:before{content:"\f2d5"}.fa-barcode:before{content:"\f02a"}.fa-bars:before{content:"\f0c9"}.fa-baseball-ball:before{content:"\f433"}.fa-basketball-ball:before{content:"\f434"}.fa-bath:before{content:"\f2cd"}.fa-battery-empty:before{content:"\f244"}.fa-battery-full:before{content:"\f240"}.fa-battery-half:before{content:"\f242"}.fa-battery-quarter:before{content:"\f243"}.fa-battery-three-quarters:before{content:"\f241"}.fa-bed:before{content:"\f236"}.fa-beer:before{content:"\f0fc"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-bell:before{content:"\f0f3"}.fa-bell-slash:before{content:"\f1f6"}.fa-bezier-curve:before{content:"\f55b"}.fa-bible:before{content:"\f647"}.fa-bicycle:before{content:"\f206"}.fa-bimobject:before{content:"\f378"}.fa-binoculars:before{content:"\f1e5"}.fa-biohazard:before{content:"\f780"}.fa-birthday-cake:before{content:"\f1fd"}.fa-bitbucket:before{content:"\f171"}.fa-bitcoin:before{content:"\f379"}.fa-bity:before{content:"\f37a"}.fa-black-tie:before{content:"\f27e"}.fa-blackberry:before{content:"\f37b"}.fa-blender:before{content:"\f517"}.fa-blender-phone:before{content:"\f6b6"}.fa-blind:before{content:"\f29d"}.fa-blog:before{content:"\f781"}.fa-blogger:before{content:"\f37c"}.fa-blogger-b:before{content:"\f37d"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-bold:before{content:"\f032"}.fa-bolt:before{content:"\f0e7"}.fa-bomb:before{content:"\f1e2"}.fa-bone:before{content:"\f5d7"}.fa-bong:before{content:"\f55c"}.fa-book:before{content:"\f02d"}.fa-book-dead:before{content:"\f6b7"}.fa-book-open:before{content:"\f518"}.fa-book-reader:before{content:"\f5da"}.fa-bookmark:before{content:"\f02e"}.fa-bowling-ball:before{content:"\f436"}.fa-box:before{content:"\f466"}.fa-box-open:before{content:"\f49e"}.fa-boxes:before{content:"\f468"}.fa-braille:before{content:"\f2a1"}.fa-brain:before{content:"\f5dc"}.fa-briefcase:before{content:"\f0b1"}.fa-briefcase-medical:before{content:"\f469"}.fa-broadcast-tower:before{content:"\f519"}.fa-broom:before{content:"\f51a"}.fa-brush:before{content:"\f55d"}.fa-btc:before{content:"\f15a"}.fa-bug:before{content:"\f188"}.fa-building:before{content:"\f1ad"}.fa-bullhorn:before{content:"\f0a1"}.fa-bullseye:before{content:"\f140"}.fa-burn:before{content:"\f46a"}.fa-buromobelexperte:before{content:"\f37f"}.fa-bus:before{content:"\f207"}.fa-bus-alt:before{content:"\f55e"}.fa-business-time:before{content:"\f64a"}.fa-buysellads:before{content:"\f20d"}.fa-calculator:before{content:"\f1ec"}.fa-calendar:before{content:"\f133"}.fa-calendar-alt:before{content:"\f073"}.fa-calendar-check:before{content:"\f274"}.fa-calendar-day:before{content:"\f783"}.fa-calendar-minus:before{content:"\f272"}.fa-calendar-plus:before{content:"\f271"}.fa-calendar-times:before{content:"\f273"}.fa-calendar-week:before{content:"\f784"}.fa-camera:before{content:"\f030"}.fa-camera-retro:before{content:"\f083"}.fa-campground:before{content:"\f6bb"}.fa-canadian-maple-leaf:before{content:"\f785"}.fa-candy-cane:before{content:"\f786"}.fa-cannabis:before{content:"\f55f"}.fa-capsules:before{content:"\f46b"}.fa-car:before{content:"\f1b9"}.fa-car-alt:before{content:"\f5de"}.fa-car-battery:before{content:"\f5df"}.fa-car-crash:before{content:"\f5e1"}.fa-car-side:before{content:"\f5e4"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-caret-square-down:before{content:"\f150"}.fa-caret-square-left:before{content:"\f191"}.fa-caret-square-right:before{content:"\f152"}.fa-caret-square-up:before{content:"\f151"}.fa-caret-up:before{content:"\f0d8"}.fa-carrot:before{content:"\f787"}.fa-cart-arrow-down:before{content:"\f218"}.fa-cart-plus:before{content:"\f217"}.fa-cash-register:before{content:"\f788"}.fa-cat:before{content:"\f6be"}.fa-cc-amazon-pay:before{content:"\f42d"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-apple-pay:before{content:"\f416"}.fa-cc-diners-club:before{content:"\f24c"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-cc-visa:before{content:"\f1f0"}.fa-centercode:before{content:"\f380"}.fa-centos:before{content:"\f789"}.fa-certificate:before{content:"\f0a3"}.fa-chair:before{content:"\f6c0"}.fa-chalkboard:before{content:"\f51b"}.fa-chalkboard-teacher:before{content:"\f51c"}.fa-charging-station:before{content:"\f5e7"}.fa-chart-area:before{content:"\f1fe"}.fa-chart-bar:before{content:"\f080"}.fa-chart-line:before{content:"\f201"}.fa-chart-pie:before{content:"\f200"}.fa-check:before{content:"\f00c"}.fa-check-circle:before{content:"\f058"}.fa-check-double:before{content:"\f560"}.fa-check-square:before{content:"\f14a"}.fa-chess:before{content:"\f439"}.fa-chess-bishop:before{content:"\f43a"}.fa-chess-board:before{content:"\f43c"}.fa-chess-king:before{content:"\f43f"}.fa-chess-knight:before{content:"\f441"}.fa-chess-pawn:before{content:"\f443"}.fa-chess-queen:before{content:"\f445"}.fa-chess-rook:before{content:"\f447"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-down:before{content:"\f078"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-chevron-up:before{content:"\f077"}.fa-child:before{content:"\f1ae"}.fa-chrome:before{content:"\f268"}.fa-church:before{content:"\f51d"}.fa-circle:before{content:"\f111"}.fa-circle-notch:before{content:"\f1ce"}.fa-city:before{content:"\f64f"}.fa-clipboard:before{content:"\f328"}.fa-clipboard-check:before{content:"\f46c"}.fa-clipboard-list:before{content:"\f46d"}.fa-clock:before{content:"\f017"}.fa-clone:before{content:"\f24d"}.fa-closed-captioning:before{content:"\f20a"}.fa-cloud:before{content:"\f0c2"}.fa-cloud-download-alt:before{content:"\f381"}.fa-cloud-meatball:before{content:"\f73b"}.fa-cloud-moon:before{content:"\f6c3"}.fa-cloud-moon-rain:before{content:"\f73c"}.fa-cloud-rain:before{content:"\f73d"}.fa-cloud-showers-heavy:before{content:"\f740"}.fa-cloud-sun:before{content:"\f6c4"}.fa-cloud-sun-rain:before{content:"\f743"}.fa-cloud-upload-alt:before{content:"\f382"}.fa-cloudscale:before{content:"\f383"}.fa-cloudsmith:before{content:"\f384"}.fa-cloudversify:before{content:"\f385"}.fa-cocktail:before{content:"\f561"}.fa-code:before{content:"\f121"}.fa-code-branch:before{content:"\f126"}.fa-codepen:before{content:"\f1cb"}.fa-codiepie:before{content:"\f284"}.fa-coffee:before{content:"\f0f4"}.fa-cog:before{content:"\f013"}.fa-cogs:before{content:"\f085"}.fa-coins:before{content:"\f51e"}.fa-columns:before{content:"\f0db"}.fa-comment:before{content:"\f075"}.fa-comment-alt:before{content:"\f27a"}.fa-comment-dollar:before{content:"\f651"}.fa-comment-dots:before{content:"\f4ad"}.fa-comment-slash:before{content:"\f4b3"}.fa-comments:before{content:"\f086"}.fa-comments-dollar:before{content:"\f653"}.fa-compact-disc:before{content:"\f51f"}.fa-compass:before{content:"\f14e"}.fa-compress:before{content:"\f066"}.fa-compress-arrows-alt:before{content:"\f78c"}.fa-concierge-bell:before{content:"\f562"}.fa-confluence:before{content:"\f78d"}.fa-connectdevelop:before{content:"\f20e"}.fa-contao:before{content:"\f26d"}.fa-cookie:before{content:"\f563"}.fa-cookie-bite:before{content:"\f564"}.fa-copy:before{content:"\f0c5"}.fa-copyright:before{content:"\f1f9"}.fa-couch:before{content:"\f4b8"}.fa-cpanel:before{content:"\f388"}.fa-creative-commons:before{content:"\f25e"}.fa-creative-commons-by:before{content:"\f4e7"}.fa-creative-commons-nc:before{content:"\f4e8"}.fa-creative-commons-nc-eu:before{content:"\f4e9"}.fa-creative-commons-nc-jp:before{content:"\f4ea"}.fa-creative-commons-nd:before{content:"\f4eb"}.fa-creative-commons-pd:before{content:"\f4ec"}.fa-creative-commons-pd-alt:before{content:"\f4ed"}.fa-creative-commons-remix:before{content:"\f4ee"}.fa-creative-commons-sa:before{content:"\f4ef"}.fa-creative-commons-sampling:before{content:"\f4f0"}.fa-creative-commons-sampling-plus:before{content:"\f4f1"}.fa-creative-commons-share:before{content:"\f4f2"}.fa-creative-commons-zero:before{content:"\f4f3"}.fa-credit-card:before{content:"\f09d"}.fa-critical-role:before{content:"\f6c9"}.fa-crop:before{content:"\f125"}.fa-crop-alt:before{content:"\f565"}.fa-cross:before{content:"\f654"}.fa-crosshairs:before{content:"\f05b"}.fa-crow:before{content:"\f520"}.fa-crown:before{content:"\f521"}.fa-css3:before{content:"\f13c"}.fa-css3-alt:before{content:"\f38b"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-cut:before{content:"\f0c4"}.fa-cuttlefish:before{content:"\f38c"}.fa-d-and-d:before{content:"\f38d"}.fa-d-and-d-beyond:before{content:"\f6ca"}.fa-dashcube:before{content:"\f210"}.fa-database:before{content:"\f1c0"}.fa-deaf:before{content:"\f2a4"}.fa-delicious:before{content:"\f1a5"}.fa-democrat:before{content:"\f747"}.fa-deploydog:before{content:"\f38e"}.fa-deskpro:before{content:"\f38f"}.fa-desktop:before{content:"\f108"}.fa-dev:before{content:"\f6cc"}.fa-deviantart:before{content:"\f1bd"}.fa-dharmachakra:before{content:"\f655"}.fa-dhl:before{content:"\f790"}.fa-diagnoses:before{content:"\f470"}.fa-diaspora:before{content:"\f791"}.fa-dice:before{content:"\f522"}.fa-dice-d20:before{content:"\f6cf"}.fa-dice-d6:before{content:"\f6d1"}.fa-dice-five:before{content:"\f523"}.fa-dice-four:before{content:"\f524"}.fa-dice-one:before{content:"\f525"}.fa-dice-six:before{content:"\f526"}.fa-dice-three:before{content:"\f527"}.fa-dice-two:before{content:"\f528"}.fa-digg:before{content:"\f1a6"}.fa-digital-ocean:before{content:"\f391"}.fa-digital-tachograph:before{content:"\f566"}.fa-directions:before{content:"\f5eb"}.fa-discord:before{content:"\f392"}.fa-discourse:before{content:"\f393"}.fa-divide:before{content:"\f529"}.fa-dizzy:before{content:"\f567"}.fa-dna:before{content:"\f471"}.fa-dochub:before{content:"\f394"}.fa-docker:before{content:"\f395"}.fa-dog:before{content:"\f6d3"}.fa-dollar-sign:before{content:"\f155"}.fa-dolly:before{content:"\f472"}.fa-dolly-flatbed:before{content:"\f474"}.fa-donate:before{content:"\f4b9"}.fa-door-closed:before{content:"\f52a"}.fa-door-open:before{content:"\f52b"}.fa-dot-circle:before{content:"\f192"}.fa-dove:before{content:"\f4ba"}.fa-download:before{content:"\f019"}.fa-draft2digital:before{content:"\f396"}.fa-drafting-compass:before{content:"\f568"}.fa-dragon:before{content:"\f6d5"}.fa-draw-polygon:before{content:"\f5ee"}.fa-dribbble:before{content:"\f17d"}.fa-dribbble-square:before{content:"\f397"}.fa-dropbox:before{content:"\f16b"}.fa-drum:before{content:"\f569"}.fa-drum-steelpan:before{content:"\f56a"}.fa-drumstick-bite:before{content:"\f6d7"}.fa-drupal:before{content:"\f1a9"}.fa-dumbbell:before{content:"\f44b"}.fa-dumpster:before{content:"\f793"}.fa-dumpster-fire:before{content:"\f794"}.fa-dungeon:before{content:"\f6d9"}.fa-dyalog:before{content:"\f399"}.fa-earlybirds:before{content:"\f39a"}.fa-ebay:before{content:"\f4f4"}.fa-edge:before{content:"\f282"}.fa-edit:before{content:"\f044"}.fa-eject:before{content:"\f052"}.fa-elementor:before{content:"\f430"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-ello:before{content:"\f5f1"}.fa-ember:before{content:"\f423"}.fa-empire:before{content:"\f1d1"}.fa-envelope:before{content:"\f0e0"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-text:before{content:"\f658"}.fa-envelope-square:before{content:"\f199"}.fa-envira:before{content:"\f299"}.fa-equals:before{content:"\f52c"}.fa-eraser:before{content:"\f12d"}.fa-erlang:before{content:"\f39d"}.fa-ethereum:before{content:"\f42e"}.fa-ethernet:before{content:"\f796"}.fa-etsy:before{content:"\f2d7"}.fa-euro-sign:before{content:"\f153"}.fa-exchange-alt:before{content:"\f362"}.fa-exclamation:before{content:"\f12a"}.fa-exclamation-circle:before{content:"\f06a"}.fa-exclamation-triangle:before{content:"\f071"}.fa-expand:before{content:"\f065"}.fa-expand-arrows-alt:before{content:"\f31e"}.fa-expeditedssl:before{content:"\f23e"}.fa-external-link-alt:before{content:"\f35d"}.fa-external-link-square-alt:before{content:"\f360"}.fa-eye:before{content:"\f06e"}.fa-eye-dropper:before{content:"\f1fb"}.fa-eye-slash:before{content:"\f070"}.fa-facebook:before{content:"\f09a"}.fa-facebook-f:before{content:"\f39e"}.fa-facebook-messenger:before{content:"\f39f"}.fa-facebook-square:before{content:"\f082"}.fa-fantasy-flight-games:before{content:"\f6dc"}.fa-fast-backward:before{content:"\f049"}.fa-fast-forward:before{content:"\f050"}.fa-fax:before{content:"\f1ac"}.fa-feather:before{content:"\f52d"}.fa-feather-alt:before{content:"\f56b"}.fa-fedex:before{content:"\f797"}.fa-fedora:before{content:"\f798"}.fa-female:before{content:"\f182"}.fa-fighter-jet:before{content:"\f0fb"}.fa-figma:before{content:"\f799"}.fa-file:before{content:"\f15b"}.fa-file-alt:before{content:"\f15c"}.fa-file-archive:before{content:"\f1c6"}.fa-file-audio:before{content:"\f1c7"}.fa-file-code:before{content:"\f1c9"}.fa-file-contract:before{content:"\f56c"}.fa-file-csv:before{content:"\f6dd"}.fa-file-download:before{content:"\f56d"}.fa-file-excel:before{content:"\f1c3"}.fa-file-export:before{content:"\f56e"}.fa-file-image:before{content:"\f1c5"}.fa-file-import:before{content:"\f56f"}.fa-file-invoice:before{content:"\f570"}.fa-file-invoice-dollar:before{content:"\f571"}.fa-file-medical:before{content:"\f477"}.fa-file-medical-alt:before{content:"\f478"}.fa-file-pdf:before{content:"\f1c1"}.fa-file-powerpoint:before{content:"\f1c4"}.fa-file-prescription:before{content:"\f572"}.fa-file-signature:before{content:"\f573"}.fa-file-upload:before{content:"\f574"}.fa-file-video:before{content:"\f1c8"}.fa-file-word:before{content:"\f1c2"}.fa-fill:before{content:"\f575"}.fa-fill-drip:before{content:"\f576"}.fa-film:before{content:"\f008"}.fa-filter:before{content:"\f0b0"}.fa-fingerprint:before{content:"\f577"}.fa-fire:before{content:"\f06d"}.fa-fire-alt:before{content:"\f7e4"}.fa-fire-extinguisher:before{content:"\f134"}.fa-firefox:before{content:"\f269"}.fa-first-aid:before{content:"\f479"}.fa-first-order:before{content:"\f2b0"}.fa-first-order-alt:before{content:"\f50a"}.fa-firstdraft:before{content:"\f3a1"}.fa-fish:before{content:"\f578"}.fa-fist-raised:before{content:"\f6de"}.fa-flag:before{content:"\f024"}.fa-flag-checkered:before{content:"\f11e"}.fa-flag-usa:before{content:"\f74d"}.fa-flask:before{content:"\f0c3"}.fa-flickr:before{content:"\f16e"}.fa-flipboard:before{content:"\f44d"}.fa-flushed:before{content:"\f579"}.fa-fly:before{content:"\f417"}.fa-folder:before{content:"\f07b"}.fa-folder-minus:before{content:"\f65d"}.fa-folder-open:before{content:"\f07c"}.fa-folder-plus:before{content:"\f65e"}.fa-font:before{content:"\f031"}.fa-font-awesome:before{content:"\f2b4"}.fa-font-awesome-alt:before{content:"\f35c"}.fa-font-awesome-flag:before{content:"\f425"}.fa-font-awesome-logo-full:before{content:"\f4e6"}.fa-fonticons:before{content:"\f280"}.fa-fonticons-fi:before{content:"\f3a2"}.fa-football-ball:before{content:"\f44e"}.fa-fort-awesome:before{content:"\f286"}.fa-fort-awesome-alt:before{content:"\f3a3"}.fa-forumbee:before{content:"\f211"}.fa-forward:before{content:"\f04e"}.fa-foursquare:before{content:"\f180"}.fa-free-code-camp:before{content:"\f2c5"}.fa-freebsd:before{content:"\f3a4"}.fa-frog:before{content:"\f52e"}.fa-frown:before{content:"\f119"}.fa-frown-open:before{content:"\f57a"}.fa-fulcrum:before{content:"\f50b"}.fa-funnel-dollar:before{content:"\f662"}.fa-futbol:before{content:"\f1e3"}.fa-galactic-republic:before{content:"\f50c"}.fa-galactic-senate:before{content:"\f50d"}.fa-gamepad:before{content:"\f11b"}.fa-gas-pump:before{content:"\f52f"}.fa-gavel:before{content:"\f0e3"}.fa-gem:before{content:"\f3a5"}.fa-genderless:before{content:"\f22d"}.fa-get-pocket:before{content:"\f265"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-ghost:before{content:"\f6e2"}.fa-gift:before{content:"\f06b"}.fa-gifts:before{content:"\f79c"}.fa-git:before{content:"\f1d3"}.fa-git-square:before{content:"\f1d2"}.fa-github:before{content:"\f09b"}.fa-github-alt:before{content:"\f113"}.fa-github-square:before{content:"\f092"}.fa-gitkraken:before{content:"\f3a6"}.fa-gitlab:before{content:"\f296"}.fa-gitter:before{content:"\f426"}.fa-glass-cheers:before{content:"\f79f"}.fa-glass-martini:before{content:"\f000"}.fa-glass-martini-alt:before{content:"\f57b"}.fa-glass-whiskey:before{content:"\f7a0"}.fa-glasses:before{content:"\f530"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-globe:before{content:"\f0ac"}.fa-globe-africa:before{content:"\f57c"}.fa-globe-americas:before{content:"\f57d"}.fa-globe-asia:before{content:"\f57e"}.fa-globe-europe:before{content:"\f7a2"}.fa-gofore:before{content:"\f3a7"}.fa-golf-ball:before{content:"\f450"}.fa-goodreads:before{content:"\f3a8"}.fa-goodreads-g:before{content:"\f3a9"}.fa-google:before{content:"\f1a0"}.fa-google-drive:before{content:"\f3aa"}.fa-google-play:before{content:"\f3ab"}.fa-google-plus:before{content:"\f2b3"}.fa-google-plus-g:before{content:"\f0d5"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-wallet:before{content:"\f1ee"}.fa-gopuram:before{content:"\f664"}.fa-graduation-cap:before{content:"\f19d"}.fa-gratipay:before{content:"\f184"}.fa-grav:before{content:"\f2d6"}.fa-greater-than:before{content:"\f531"}.fa-greater-than-equal:before{content:"\f532"}.fa-grimace:before{content:"\f57f"}.fa-grin:before{content:"\f580"}.fa-grin-alt:before{content:"\f581"}.fa-grin-beam:before{content:"\f582"}.fa-grin-beam-sweat:before{content:"\f583"}.fa-grin-hearts:before{content:"\f584"}.fa-grin-squint:before{content:"\f585"}.fa-grin-squint-tears:before{content:"\f586"}.fa-grin-stars:before{content:"\f587"}.fa-grin-tears:before{content:"\f588"}.fa-grin-tongue:before{content:"\f589"}.fa-grin-tongue-squint:before{content:"\f58a"}.fa-grin-tongue-wink:before{content:"\f58b"}.fa-grin-wink:before{content:"\f58c"}.fa-grip-horizontal:before{content:"\f58d"}.fa-grip-lines:before{content:"\f7a4"}.fa-grip-lines-vertical:before{content:"\f7a5"}.fa-grip-vertical:before{content:"\f58e"}.fa-gripfire:before{content:"\f3ac"}.fa-grunt:before{content:"\f3ad"}.fa-guitar:before{content:"\f7a6"}.fa-gulp:before{content:"\f3ae"}.fa-h-square:before{content:"\f0fd"}.fa-hacker-news:before{content:"\f1d4"}.fa-hacker-news-square:before{content:"\f3af"}.fa-hackerrank:before{content:"\f5f7"}.fa-hammer:before{content:"\f6e3"}.fa-hamsa:before{content:"\f665"}.fa-hand-holding:before{content:"\f4bd"}.fa-hand-holding-heart:before{content:"\f4be"}.fa-hand-holding-usd:before{content:"\f4c0"}.fa-hand-lizard:before{content:"\f258"}.fa-hand-paper:before{content:"\f256"}.fa-hand-peace:before{content:"\f25b"}.fa-hand-point-down:before{content:"\f0a7"}.fa-hand-point-left:before{content:"\f0a5"}.fa-hand-point-right:before{content:"\f0a4"}.fa-hand-point-up:before{content:"\f0a6"}.fa-hand-pointer:before{content:"\f25a"}.fa-hand-rock:before{content:"\f255"}.fa-hand-scissors:before{content:"\f257"}.fa-hand-spock:before{content:"\f259"}.fa-hands:before{content:"\f4c2"}.fa-hands-helping:before{content:"\f4c4"}.fa-handshake:before{content:"\f2b5"}.fa-hanukiah:before{content:"\f6e6"}.fa-hashtag:before{content:"\f292"}.fa-hat-wizard:before{content:"\f6e8"}.fa-haykal:before{content:"\f666"}.fa-hdd:before{content:"\f0a0"}.fa-heading:before{content:"\f1dc"}.fa-headphones:before{content:"\f025"}.fa-headphones-alt:before{content:"\f58f"}.fa-headset:before{content:"\f590"}.fa-heart:before{content:"\f004"}.fa-heart-broken:before{content:"\f7a9"}.fa-heartbeat:before{content:"\f21e"}.fa-helicopter:before{content:"\f533"}.fa-highlighter:before{content:"\f591"}.fa-hiking:before{content:"\f6ec"}.fa-hippo:before{content:"\f6ed"}.fa-hips:before{content:"\f452"}.fa-hire-a-helper:before{content:"\f3b0"}.fa-history:before{content:"\f1da"}.fa-hockey-puck:before{content:"\f453"}.fa-holly-berry:before{content:"\f7aa"}.fa-home:before{content:"\f015"}.fa-hooli:before{content:"\f427"}.fa-hornbill:before{content:"\f592"}.fa-horse:before{content:"\f6f0"}.fa-horse-head:before{content:"\f7ab"}.fa-hospital:before{content:"\f0f8"}.fa-hospital-alt:before{content:"\f47d"}.fa-hospital-symbol:before{content:"\f47e"}.fa-hot-tub:before{content:"\f593"}.fa-hotel:before{content:"\f594"}.fa-hotjar:before{content:"\f3b1"}.fa-hourglass:before{content:"\f254"}.fa-hourglass-end:before{content:"\f253"}.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-start:before{content:"\f251"}.fa-house-damage:before{content:"\f6f1"}.fa-houzz:before{content:"\f27c"}.fa-hryvnia:before{content:"\f6f2"}.fa-html5:before{content:"\f13b"}.fa-hubspot:before{content:"\f3b2"}.fa-i-cursor:before{content:"\f246"}.fa-icicles:before{content:"\f7ad"}.fa-id-badge:before{content:"\f2c1"}.fa-id-card:before{content:"\f2c2"}.fa-id-card-alt:before{content:"\f47f"}.fa-igloo:before{content:"\f7ae"}.fa-image:before{content:"\f03e"}.fa-images:before{content:"\f302"}.fa-imdb:before{content:"\f2d8"}.fa-inbox:before{content:"\f01c"}.fa-indent:before{content:"\f03c"}.fa-industry:before{content:"\f275"}.fa-infinity:before{content:"\f534"}.fa-info:before{content:"\f129"}.fa-info-circle:before{content:"\f05a"}.fa-instagram:before{content:"\f16d"}.fa-intercom:before{content:"\f7af"}.fa-internet-explorer:before{content:"\f26b"}.fa-invision:before{content:"\f7b0"}.fa-ioxhost:before{content:"\f208"}.fa-italic:before{content:"\f033"}.fa-itunes:before{content:"\f3b4"}.fa-itunes-note:before{content:"\f3b5"}.fa-java:before{content:"\f4e4"}.fa-jedi:before{content:"\f669"}.fa-jedi-order:before{content:"\f50e"}.fa-jenkins:before{content:"\f3b6"}.fa-jira:before{content:"\f7b1"}.fa-joget:before{content:"\f3b7"}.fa-joint:before{content:"\f595"}.fa-joomla:before{content:"\f1aa"}.fa-journal-whills:before{content:"\f66a"}.fa-js:before{content:"\f3b8"}.fa-js-square:before{content:"\f3b9"}.fa-jsfiddle:before{content:"\f1cc"}.fa-kaaba:before{content:"\f66b"}.fa-kaggle:before{content:"\f5fa"}.fa-key:before{content:"\f084"}.fa-keybase:before{content:"\f4f5"}.fa-keyboard:before{content:"\f11c"}.fa-keycdn:before{content:"\f3ba"}.fa-khanda:before{content:"\f66d"}.fa-kickstarter:before{content:"\f3bb"}.fa-kickstarter-k:before{content:"\f3bc"}.fa-kiss:before{content:"\f596"}.fa-kiss-beam:before{content:"\f597"}.fa-kiss-wink-heart:before{content:"\f598"}.fa-kiwi-bird:before{content:"\f535"}.fa-korvue:before{content:"\f42f"}.fa-landmark:before{content:"\f66f"}.fa-language:before{content:"\f1ab"}.fa-laptop:before{content:"\f109"}.fa-laptop-code:before{content:"\f5fc"}.fa-laravel:before{content:"\f3bd"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-laugh:before{content:"\f599"}.fa-laugh-beam:before{content:"\f59a"}.fa-laugh-squint:before{content:"\f59b"}.fa-laugh-wink:before{content:"\f59c"}.fa-layer-group:before{content:"\f5fd"}.fa-leaf:before{content:"\f06c"}.fa-leanpub:before{content:"\f212"}.fa-lemon:before{content:"\f094"}.fa-less:before{content:"\f41d"}.fa-less-than:before{content:"\f536"}.fa-less-than-equal:before{content:"\f537"}.fa-level-down-alt:before{content:"\f3be"}.fa-level-up-alt:before{content:"\f3bf"}.fa-life-ring:before{content:"\f1cd"}.fa-lightbulb:before{content:"\f0eb"}.fa-line:before{content:"\f3c0"}.fa-link:before{content:"\f0c1"}.fa-linkedin:before{content:"\f08c"}.fa-linkedin-in:before{content:"\f0e1"}.fa-linode:before{content:"\f2b8"}.fa-linux:before{content:"\f17c"}.fa-lira-sign:before{content:"\f195"}.fa-list:before{content:"\f03a"}.fa-list-alt:before{content:"\f022"}.fa-list-ol:before{content:"\f0cb"}.fa-list-ul:before{content:"\f0ca"}.fa-location-arrow:before{content:"\f124"}.fa-lock:before{content:"\f023"}.fa-lock-open:before{content:"\f3c1"}.fa-long-arrow-alt-down:before{content:"\f309"}.fa-long-arrow-alt-left:before{content:"\f30a"}.fa-long-arrow-alt-right:before{content:"\f30b"}.fa-long-arrow-alt-up:before{content:"\f30c"}.fa-low-vision:before{content:"\f2a8"}.fa-luggage-cart:before{content:"\f59d"}.fa-lyft:before{content:"\f3c3"}.fa-magento:before{content:"\f3c4"}.fa-magic:before{content:"\f0d0"}.fa-magnet:before{content:"\f076"}.fa-mail-bulk:before{content:"\f674"}.fa-mailchimp:before{content:"\f59e"}.fa-male:before{content:"\f183"}.fa-mandalorian:before{content:"\f50f"}.fa-map:before{content:"\f279"}.fa-map-marked:before{content:"\f59f"}.fa-map-marked-alt:before{content:"\f5a0"}.fa-map-marker:before{content:"\f041"}.fa-map-marker-alt:before{content:"\f3c5"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-markdown:before{content:"\f60f"}.fa-marker:before{content:"\f5a1"}.fa-mars:before{content:"\f222"}.fa-mars-double:before{content:"\f227"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mask:before{content:"\f6fa"}.fa-mastodon:before{content:"\f4f6"}.fa-maxcdn:before{content:"\f136"}.fa-medal:before{content:"\f5a2"}.fa-medapps:before{content:"\f3c6"}.fa-medium:before{content:"\f23a"}.fa-medium-m:before{content:"\f3c7"}.fa-medkit:before{content:"\f0fa"}.fa-medrt:before{content:"\f3c8"}.fa-meetup:before{content:"\f2e0"}.fa-megaport:before{content:"\f5a3"}.fa-meh:before{content:"\f11a"}.fa-meh-blank:before{content:"\f5a4"}.fa-meh-rolling-eyes:before{content:"\f5a5"}.fa-memory:before{content:"\f538"}.fa-mendeley:before{content:"\f7b3"}.fa-menorah:before{content:"\f676"}.fa-mercury:before{content:"\f223"}.fa-meteor:before{content:"\f753"}.fa-microchip:before{content:"\f2db"}.fa-microphone:before{content:"\f130"}.fa-microphone-alt:before{content:"\f3c9"}.fa-microphone-alt-slash:before{content:"\f539"}.fa-microphone-slash:before{content:"\f131"}.fa-microscope:before{content:"\f610"}.fa-microsoft:before{content:"\f3ca"}.fa-minus:before{content:"\f068"}.fa-minus-circle:before{content:"\f056"}.fa-minus-square:before{content:"\f146"}.fa-mitten:before{content:"\f7b5"}.fa-mix:before{content:"\f3cb"}.fa-mixcloud:before{content:"\f289"}.fa-mizuni:before{content:"\f3cc"}.fa-mobile:before{content:"\f10b"}.fa-mobile-alt:before{content:"\f3cd"}.fa-modx:before{content:"\f285"}.fa-monero:before{content:"\f3d0"}.fa-money-bill:before{content:"\f0d6"}.fa-money-bill-alt:before{content:"\f3d1"}.fa-money-bill-wave:before{content:"\f53a"}.fa-money-bill-wave-alt:before{content:"\f53b"}.fa-money-check:before{content:"\f53c"}.fa-money-check-alt:before{content:"\f53d"}.fa-monument:before{content:"\f5a6"}.fa-moon:before{content:"\f186"}.fa-mortar-pestle:before{content:"\f5a7"}.fa-mosque:before{content:"\f678"}.fa-motorcycle:before{content:"\f21c"}.fa-mountain:before{content:"\f6fc"}.fa-mouse-pointer:before{content:"\f245"}.fa-mug-hot:before{content:"\f7b6"}.fa-music:before{content:"\f001"}.fa-napster:before{content:"\f3d2"}.fa-neos:before{content:"\f612"}.fa-network-wired:before{content:"\f6ff"}.fa-neuter:before{content:"\f22c"}.fa-newspaper:before{content:"\f1ea"}.fa-nimblr:before{content:"\f5a8"}.fa-nintendo-switch:before{content:"\f418"}.fa-node:before{content:"\f419"}.fa-node-js:before{content:"\f3d3"}.fa-not-equal:before{content:"\f53e"}.fa-notes-medical:before{content:"\f481"}.fa-npm:before{content:"\f3d4"}.fa-ns8:before{content:"\f3d5"}.fa-nutritionix:before{content:"\f3d6"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-oil-can:before{content:"\f613"}.fa-old-republic:before{content:"\f510"}.fa-om:before{content:"\f679"}.fa-opencart:before{content:"\f23d"}.fa-openid:before{content:"\f19b"}.fa-opera:before{content:"\f26a"}.fa-optin-monster:before{content:"\f23c"}.fa-osi:before{content:"\f41a"}.fa-otter:before{content:"\f700"}.fa-outdent:before{content:"\f03b"}.fa-page4:before{content:"\f3d7"}.fa-pagelines:before{content:"\f18c"}.fa-paint-brush:before{content:"\f1fc"}.fa-paint-roller:before{content:"\f5aa"}.fa-palette:before{content:"\f53f"}.fa-palfed:before{content:"\f3d8"}.fa-pallet:before{content:"\f482"}.fa-paper-plane:before{content:"\f1d8"}.fa-paperclip:before{content:"\f0c6"}.fa-parachute-box:before{content:"\f4cd"}.fa-paragraph:before{content:"\f1dd"}.fa-parking:before{content:"\f540"}.fa-passport:before{content:"\f5ab"}.fa-pastafarianism:before{content:"\f67b"}.fa-paste:before{content:"\f0ea"}.fa-patreon:before{content:"\f3d9"}.fa-pause:before{content:"\f04c"}.fa-pause-circle:before{content:"\f28b"}.fa-paw:before{content:"\f1b0"}.fa-paypal:before{content:"\f1ed"}.fa-peace:before{content:"\f67c"}.fa-pen:before{content:"\f304"}.fa-pen-alt:before{content:"\f305"}.fa-pen-fancy:before{content:"\f5ac"}.fa-pen-nib:before{content:"\f5ad"}.fa-pen-square:before{content:"\f14b"}.fa-pencil-alt:before{content:"\f303"}.fa-pencil-ruler:before{content:"\f5ae"}.fa-penny-arcade:before{content:"\f704"}.fa-people-carry:before{content:"\f4ce"}.fa-percent:before{content:"\f295"}.fa-percentage:before{content:"\f541"}.fa-periscope:before{content:"\f3da"}.fa-person-booth:before{content:"\f756"}.fa-phabricator:before{content:"\f3db"}.fa-phoenix-framework:before{content:"\f3dc"}.fa-phoenix-squadron:before{content:"\f511"}.fa-phone:before{content:"\f095"}.fa-phone-slash:before{content:"\f3dd"}.fa-phone-square:before{content:"\f098"}.fa-phone-volume:before{content:"\f2a0"}.fa-php:before{content:"\f457"}.fa-pied-piper:before{content:"\f2ae"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-pied-piper-hat:before{content:"\f4e5"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-piggy-bank:before{content:"\f4d3"}.fa-pills:before{content:"\f484"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-p:before{content:"\f231"}.fa-pinterest-square:before{content:"\f0d3"}.fa-place-of-worship:before{content:"\f67f"}.fa-plane:before{content:"\f072"}.fa-plane-arrival:before{content:"\f5af"}.fa-plane-departure:before{content:"\f5b0"}.fa-play:before{content:"\f04b"}.fa-play-circle:before{content:"\f144"}.fa-playstation:before{content:"\f3df"}.fa-plug:before{content:"\f1e6"}.fa-plus:before{content:"\f067"}.fa-plus-circle:before{content:"\f055"}.fa-plus-square:before{content:"\f0fe"}.fa-podcast:before{content:"\f2ce"}.fa-poll:before{content:"\f681"}.fa-poll-h:before{content:"\f682"}.fa-poo:before{content:"\f2fe"}.fa-poo-storm:before{content:"\f75a"}.fa-poop:before{content:"\f619"}.fa-portrait:before{content:"\f3e0"}.fa-pound-sign:before{content:"\f154"}.fa-power-off:before{content:"\f011"}.fa-pray:before{content:"\f683"}.fa-praying-hands:before{content:"\f684"}.fa-prescription:before{content:"\f5b1"}.fa-prescription-bottle:before{content:"\f485"}.fa-prescription-bottle-alt:before{content:"\f486"}.fa-print:before{content:"\f02f"}.fa-procedures:before{content:"\f487"}.fa-product-hunt:before{content:"\f288"}.fa-project-diagram:before{content:"\f542"}.fa-pushed:before{content:"\f3e1"}.fa-puzzle-piece:before{content:"\f12e"}.fa-python:before{content:"\f3e2"}.fa-qq:before{content:"\f1d6"}.fa-qrcode:before{content:"\f029"}.fa-question:before{content:"\f128"}.fa-question-circle:before{content:"\f059"}.fa-quidditch:before{content:"\f458"}.fa-quinscape:before{content:"\f459"}.fa-quora:before{content:"\f2c4"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-quran:before{content:"\f687"}.fa-r-project:before{content:"\f4f7"}.fa-radiation:before{content:"\f7b9"}.fa-radiation-alt:before{content:"\f7ba"}.fa-rainbow:before{content:"\f75b"}.fa-random:before{content:"\f074"}.fa-raspberry-pi:before{content:"\f7bb"}.fa-ravelry:before{content:"\f2d9"}.fa-react:before{content:"\f41b"}.fa-reacteurope:before{content:"\f75d"}.fa-readme:before{content:"\f4d5"}.fa-rebel:before{content:"\f1d0"}.fa-receipt:before{content:"\f543"}.fa-recycle:before{content:"\f1b8"}.fa-red-river:before{content:"\f3e3"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-alien:before{content:"\f281"}.fa-reddit-square:before{content:"\f1a2"}.fa-redhat:before{content:"\f7bc"}.fa-redo:before{content:"\f01e"}.fa-redo-alt:before{content:"\f2f9"}.fa-registered:before{content:"\f25d"}.fa-renren:before{content:"\f18b"}.fa-reply:before{content:"\f3e5"}.fa-reply-all:before{content:"\f122"}.fa-replyd:before{content:"\f3e6"}.fa-republican:before{content:"\f75e"}.fa-researchgate:before{content:"\f4f8"}.fa-resolving:before{content:"\f3e7"}.fa-restroom:before{content:"\f7bd"}.fa-retweet:before{content:"\f079"}.fa-rev:before{content:"\f5b2"}.fa-ribbon:before{content:"\f4d6"}.fa-ring:before{content:"\f70b"}.fa-road:before{content:"\f018"}.fa-robot:before{content:"\f544"}.fa-rocket:before{content:"\f135"}.fa-rocketchat:before{content:"\f3e8"}.fa-rockrms:before{content:"\f3e9"}.fa-route:before{content:"\f4d7"}.fa-rss:before{content:"\f09e"}.fa-rss-square:before{content:"\f143"}.fa-ruble-sign:before{content:"\f158"}.fa-ruler:before{content:"\f545"}.fa-ruler-combined:before{content:"\f546"}.fa-ruler-horizontal:before{content:"\f547"}.fa-ruler-vertical:before{content:"\f548"}.fa-running:before{content:"\f70c"}.fa-rupee-sign:before{content:"\f156"}.fa-sad-cry:before{content:"\f5b3"}.fa-sad-tear:before{content:"\f5b4"}.fa-safari:before{content:"\f267"}.fa-sass:before{content:"\f41e"}.fa-satellite:before{content:"\f7bf"}.fa-satellite-dish:before{content:"\f7c0"}.fa-save:before{content:"\f0c7"}.fa-schlix:before{content:"\f3ea"}.fa-school:before{content:"\f549"}.fa-screwdriver:before{content:"\f54a"}.fa-scribd:before{content:"\f28a"}.fa-scroll:before{content:"\f70e"}.fa-sd-card:before{content:"\f7c2"}.fa-search:before{content:"\f002"}.fa-search-dollar:before{content:"\f688"}.fa-search-location:before{content:"\f689"}.fa-search-minus:before{content:"\f010"}.fa-search-plus:before{content:"\f00e"}.fa-searchengin:before{content:"\f3eb"}.fa-seedling:before{content:"\f4d8"}.fa-sellcast:before{content:"\f2da"}.fa-sellsy:before{content:"\f213"}.fa-server:before{content:"\f233"}.fa-servicestack:before{content:"\f3ec"}.fa-shapes:before{content:"\f61f"}.fa-share:before{content:"\f064"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-share-square:before{content:"\f14d"}.fa-shekel-sign:before{content:"\f20b"}.fa-shield-alt:before{content:"\f3ed"}.fa-ship:before{content:"\f21a"}.fa-shipping-fast:before{content:"\f48b"}.fa-shirtsinbulk:before{content:"\f214"}.fa-shoe-prints:before{content:"\f54b"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-shopping-cart:before{content:"\f07a"}.fa-shopware:before{content:"\f5b5"}.fa-shower:before{content:"\f2cc"}.fa-shuttle-van:before{content:"\f5b6"}.fa-sign:before{content:"\f4d9"}.fa-sign-in-alt:before{content:"\f2f6"}.fa-sign-language:before{content:"\f2a7"}.fa-sign-out-alt:before{content:"\f2f5"}.fa-signal:before{content:"\f012"}.fa-signature:before{content:"\f5b7"}.fa-sim-card:before{content:"\f7c4"}.fa-simplybuilt:before{content:"\f215"}.fa-sistrix:before{content:"\f3ee"}.fa-sitemap:before{content:"\f0e8"}.fa-sith:before{content:"\f512"}.fa-skating:before{content:"\f7c5"}.fa-sketch:before{content:"\f7c6"}.fa-skiing:before{content:"\f7c9"}.fa-skiing-nordic:before{content:"\f7ca"}.fa-skull:before{content:"\f54c"}.fa-skull-crossbones:before{content:"\f714"}.fa-skyatlas:before{content:"\f216"}.fa-skype:before{content:"\f17e"}.fa-slack:before{content:"\f198"}.fa-slack-hash:before{content:"\f3ef"}.fa-slash:before{content:"\f715"}.fa-sleigh:before{content:"\f7cc"}.fa-sliders-h:before{content:"\f1de"}.fa-slideshare:before{content:"\f1e7"}.fa-smile:before{content:"\f118"}.fa-smile-beam:before{content:"\f5b8"}.fa-smile-wink:before{content:"\f4da"}.fa-smog:before{content:"\f75f"}.fa-smoking:before{content:"\f48d"}.fa-smoking-ban:before{content:"\f54d"}.fa-sms:before{content:"\f7cd"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-snowboarding:before{content:"\f7ce"}.fa-snowflake:before{content:"\f2dc"}.fa-snowman:before{content:"\f7d0"}.fa-snowplow:before{content:"\f7d2"}.fa-socks:before{content:"\f696"}.fa-solar-panel:before{content:"\f5ba"}.fa-sort:before{content:"\f0dc"}.fa-sort-alpha-down:before{content:"\f15d"}.fa-sort-alpha-up:before{content:"\f15e"}.fa-sort-amount-down:before{content:"\f160"}.fa-sort-amount-up:before{content:"\f161"}.fa-sort-down:before{content:"\f0dd"}.fa-sort-numeric-down:before{content:"\f162"}.fa-sort-numeric-up:before{content:"\f163"}.fa-sort-up:before{content:"\f0de"}.fa-soundcloud:before{content:"\f1be"}.fa-sourcetree:before{content:"\f7d3"}.fa-spa:before{content:"\f5bb"}.fa-space-shuttle:before{content:"\f197"}.fa-speakap:before{content:"\f3f3"}.fa-spider:before{content:"\f717"}.fa-spinner:before{content:"\f110"}.fa-splotch:before{content:"\f5bc"}.fa-spotify:before{content:"\f1bc"}.fa-spray-can:before{content:"\f5bd"}.fa-square:before{content:"\f0c8"}.fa-square-full:before{content:"\f45c"}.fa-square-root-alt:before{content:"\f698"}.fa-squarespace:before{content:"\f5be"}.fa-stack-exchange:before{content:"\f18d"}.fa-stack-overflow:before{content:"\f16c"}.fa-stamp:before{content:"\f5bf"}.fa-star:before{content:"\f005"}.fa-star-and-crescent:before{content:"\f699"}.fa-star-half:before{content:"\f089"}.fa-star-half-alt:before{content:"\f5c0"}.fa-star-of-david:before{content:"\f69a"}.fa-star-of-life:before{content:"\f621"}.fa-staylinked:before{content:"\f3f5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-steam-symbol:before{content:"\f3f6"}.fa-step-backward:before{content:"\f048"}.fa-step-forward:before{content:"\f051"}.fa-stethoscope:before{content:"\f0f1"}.fa-sticker-mule:before{content:"\f3f7"}.fa-sticky-note:before{content:"\f249"}.fa-stop:before{content:"\f04d"}.fa-stop-circle:before{content:"\f28d"}.fa-stopwatch:before{content:"\f2f2"}.fa-store:before{content:"\f54e"}.fa-store-alt:before{content:"\f54f"}.fa-strava:before{content:"\f428"}.fa-stream:before{content:"\f550"}.fa-street-view:before{content:"\f21d"}.fa-strikethrough:before{content:"\f0cc"}.fa-stripe:before{content:"\f429"}.fa-stripe-s:before{content:"\f42a"}.fa-stroopwafel:before{content:"\f551"}.fa-studiovinari:before{content:"\f3f8"}.fa-stumbleupon:before{content:"\f1a4"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-subscript:before{content:"\f12c"}.fa-subway:before{content:"\f239"}.fa-suitcase:before{content:"\f0f2"}.fa-suitcase-rolling:before{content:"\f5c1"}.fa-sun:before{content:"\f185"}.fa-superpowers:before{content:"\f2dd"}.fa-superscript:before{content:"\f12b"}.fa-supple:before{content:"\f3f9"}.fa-surprise:before{content:"\f5c2"}.fa-suse:before{content:"\f7d6"}.fa-swatchbook:before{content:"\f5c3"}.fa-swimmer:before{content:"\f5c4"}.fa-swimming-pool:before{content:"\f5c5"}.fa-synagogue:before{content:"\f69b"}.fa-sync:before{content:"\f021"}.fa-sync-alt:before{content:"\f2f1"}.fa-syringe:before{content:"\f48e"}.fa-table:before{content:"\f0ce"}.fa-table-tennis:before{content:"\f45d"}.fa-tablet:before{content:"\f10a"}.fa-tablet-alt:before{content:"\f3fa"}.fa-tablets:before{content:"\f490"}.fa-tachometer-alt:before{content:"\f3fd"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-tape:before{content:"\f4db"}.fa-tasks:before{content:"\f0ae"}.fa-taxi:before{content:"\f1ba"}.fa-teamspeak:before{content:"\f4f9"}.fa-teeth:before{content:"\f62e"}.fa-teeth-open:before{content:"\f62f"}.fa-telegram:before{content:"\f2c6"}.fa-telegram-plane:before{content:"\f3fe"}.fa-temperature-high:before{content:"\f769"}.fa-temperature-low:before{content:"\f76b"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-tenge:before{content:"\f7d7"}.fa-terminal:before{content:"\f120"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-th:before{content:"\f00a"}.fa-th-large:before{content:"\f009"}.fa-th-list:before{content:"\f00b"}.fa-the-red-yeti:before{content:"\f69d"}.fa-theater-masks:before{content:"\f630"}.fa-themeco:before{content:"\f5c6"}.fa-themeisle:before{content:"\f2b2"}.fa-thermometer:before{content:"\f491"}.fa-thermometer-empty:before{content:"\f2cb"}.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-think-peaks:before{content:"\f731"}.fa-thumbs-down:before{content:"\f165"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbtack:before{content:"\f08d"}.fa-ticket-alt:before{content:"\f3ff"}.fa-times:before{content:"\f00d"}.fa-times-circle:before{content:"\f057"}.fa-tint:before{content:"\f043"}.fa-tint-slash:before{content:"\f5c7"}.fa-tired:before{content:"\f5c8"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-toilet:before{content:"\f7d8"}.fa-toilet-paper:before{content:"\f71e"}.fa-toolbox:before{content:"\f552"}.fa-tools:before{content:"\f7d9"}.fa-tooth:before{content:"\f5c9"}.fa-torah:before{content:"\f6a0"}.fa-torii-gate:before{content:"\f6a1"}.fa-tractor:before{content:"\f722"}.fa-trade-federation:before{content:"\f513"}.fa-trademark:before{content:"\f25c"}.fa-traffic-light:before{content:"\f637"}.fa-train:before{content:"\f238"}.fa-tram:before{content:"\f7da"}.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-trash:before{content:"\f1f8"}.fa-trash-alt:before{content:"\f2ed"}.fa-tree:before{content:"\f1bb"}.fa-trello:before{content:"\f181"}.fa-tripadvisor:before{content:"\f262"}.fa-trophy:before{content:"\f091"}.fa-truck:before{content:"\f0d1"}.fa-truck-loading:before{content:"\f4de"}.fa-truck-monster:before{content:"\f63b"}.fa-truck-moving:before{content:"\f4df"}.fa-truck-pickup:before{content:"\f63c"}.fa-tshirt:before{content:"\f553"}.fa-tty:before{content:"\f1e4"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-tv:before{content:"\f26c"}.fa-twitch:before{content:"\f1e8"}.fa-twitter:before{content:"\f099"}.fa-twitter-square:before{content:"\f081"}.fa-typo3:before{content:"\f42b"}.fa-uber:before{content:"\f402"}.fa-ubuntu:before{content:"\f7df"}.fa-uikit:before{content:"\f403"}.fa-umbrella:before{content:"\f0e9"}.fa-umbrella-beach:before{content:"\f5ca"}.fa-underline:before{content:"\f0cd"}.fa-undo:before{content:"\f0e2"}.fa-undo-alt:before{content:"\f2ea"}.fa-uniregistry:before{content:"\f404"}.fa-universal-access:before{content:"\f29a"}.fa-university:before{content:"\f19c"}.fa-unlink:before{content:"\f127"}.fa-unlock:before{content:"\f09c"}.fa-unlock-alt:before{content:"\f13e"}.fa-untappd:before{content:"\f405"}.fa-upload:before{content:"\f093"}.fa-ups:before{content:"\f7e0"}.fa-usb:before{content:"\f287"}.fa-user:before{content:"\f007"}.fa-user-alt:before{content:"\f406"}.fa-user-alt-slash:before{content:"\f4fa"}.fa-user-astronaut:before{content:"\f4fb"}.fa-user-check:before{content:"\f4fc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-clock:before{content:"\f4fd"}.fa-user-cog:before{content:"\f4fe"}.fa-user-edit:before{content:"\f4ff"}.fa-user-friends:before{content:"\f500"}.fa-user-graduate:before{content:"\f501"}.fa-user-injured:before{content:"\f728"}.fa-user-lock:before{content:"\f502"}.fa-user-md:before{content:"\f0f0"}.fa-user-minus:before{content:"\f503"}.fa-user-ninja:before{content:"\f504"}.fa-user-plus:before{content:"\f234"}.fa-user-secret:before{content:"\f21b"}.fa-user-shield:before{content:"\f505"}.fa-user-slash:before{content:"\f506"}.fa-user-tag:before{content:"\f507"}.fa-user-tie:before{content:"\f508"}.fa-user-times:before{content:"\f235"}.fa-users:before{content:"\f0c0"}.fa-users-cog:before{content:"\f509"}.fa-usps:before{content:"\f7e1"}.fa-ussunnah:before{content:"\f407"}.fa-utensil-spoon:before{content:"\f2e5"}.fa-utensils:before{content:"\f2e7"}.fa-vaadin:before{content:"\f408"}.fa-vector-square:before{content:"\f5cb"}.fa-venus:before{content:"\f221"}.fa-venus-double:before{content:"\f226"}.fa-venus-mars:before{content:"\f228"}.fa-viacoin:before{content:"\f237"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-vial:before{content:"\f492"}.fa-vials:before{content:"\f493"}.fa-viber:before{content:"\f409"}.fa-video:before{content:"\f03d"}.fa-video-slash:before{content:"\f4e2"}.fa-vihara:before{content:"\f6a7"}.fa-vimeo:before{content:"\f40a"}.fa-vimeo-square:before{content:"\f194"}.fa-vimeo-v:before{content:"\f27d"}.fa-vine:before{content:"\f1ca"}.fa-vk:before{content:"\f189"}.fa-vnv:before{content:"\f40b"}.fa-volleyball-ball:before{content:"\f45f"}.fa-volume-down:before{content:"\f027"}.fa-volume-mute:before{content:"\f6a9"}.fa-volume-off:before{content:"\f026"}.fa-volume-up:before{content:"\f028"}.fa-vote-yea:before{content:"\f772"}.fa-vr-cardboard:before{content:"\f729"}.fa-vuejs:before{content:"\f41f"}.fa-walking:before{content:"\f554"}.fa-wallet:before{content:"\f555"}.fa-warehouse:before{content:"\f494"}.fa-water:before{content:"\f773"}.fa-weebly:before{content:"\f5cc"}.fa-weibo:before{content:"\f18a"}.fa-weight:before{content:"\f496"}.fa-weight-hanging:before{content:"\f5cd"}.fa-weixin:before{content:"\f1d7"}.fa-whatsapp:before{content:"\f232"}.fa-whatsapp-square:before{content:"\f40c"}.fa-wheelchair:before{content:"\f193"}.fa-whmcs:before{content:"\f40d"}.fa-wifi:before{content:"\f1eb"}.fa-wikipedia-w:before{content:"\f266"}.fa-wind:before{content:"\f72e"}.fa-window-close:before{content:"\f410"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-windows:before{content:"\f17a"}.fa-wine-bottle:before{content:"\f72f"}.fa-wine-glass:before{content:"\f4e3"}.fa-wine-glass-alt:before{content:"\f5ce"}.fa-wix:before{content:"\f5cf"}.fa-wizards-of-the-coast:before{content:"\f730"}.fa-wolf-pack-battalion:before{content:"\f514"}.fa-won-sign:before{content:"\f159"}.fa-wordpress:before{content:"\f19a"}.fa-wordpress-simple:before{content:"\f411"}.fa-wpbeginner:before{content:"\f297"}.fa-wpexplorer:before{content:"\f2de"}.fa-wpforms:before{content:"\f298"}.fa-wpressr:before{content:"\f3e4"}.fa-wrench:before{content:"\f0ad"}.fa-x-ray:before{content:"\f497"}.fa-xbox:before{content:"\f412"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-y-combinator:before{content:"\f23b"}.fa-yahoo:before{content:"\f19e"}.fa-yandex:before{content:"\f413"}.fa-yandex-international:before{content:"\f414"}.fa-yarn:before{content:"\f7e3"}.fa-yelp:before{content:"\f1e9"}.fa-yen-sign:before{content:"\f157"}.fa-yin-yang:before{content:"\f6ad"}.fa-yoast:before{content:"\f2b1"}.fa-youtube:before{content:"\f167"}.fa-youtube-square:before{content:"\f431"}.fa-zhihu:before{content:"\f63f"}.sr-only{border:0;clip:rect(0,0,0,0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sr-only-focusable:active,.sr-only-focusable:focus{clip:auto;height:auto;margin:0;overflow:visible;position:static;width:auto}@font-face{font-family:"Font Awesome 5 Brands";font-style:normal;font-weight:normal;src:url(../webfonts/fa-brands-400.eot);src:url(../webfonts/fa-brands-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-brands-400.woff2) format("woff2"),url(../webfonts/fa-brands-400.woff) format("woff"),url(../webfonts/fa-brands-400.ttf) format("truetype"),url(../webfonts/fa-brands-400.svg#fontawesome) format("svg")}.fab{font-family:"Font Awesome 5 Brands"}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:400;src:url(../webfonts/fa-regular-400.eot);src:url(../webfonts/fa-regular-400.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-regular-400.woff2) format("woff2"),url(../webfonts/fa-regular-400.woff) format("woff"),url(../webfonts/fa-regular-400.ttf) format("truetype"),url(../webfonts/fa-regular-400.svg#fontawesome) format("svg")}.far{font-weight:400}@font-face{font-family:"Font Awesome 5 Free";font-style:normal;font-weight:900;src:url(../webfonts/fa-solid-900.eot);src:url(../webfonts/fa-solid-900.eot?#iefix) format("embedded-opentype"),url(../webfonts/fa-solid-900.woff2) format("woff2"),url(../webfonts/fa-solid-900.woff) format("woff"),url(../webfonts/fa-solid-900.ttf) format("truetype"),url(../webfonts/fa-solid-900.svg#fontawesome) format("svg")}.fa,.far,.fas{font-family:"Font Awesome 5 Free"}.fa,.fas{font-weight:900} \ No newline at end of file diff --git a/public/css/hugo-easy-gallery.css b/public/css/hugo-easy-gallery.css deleted file mode 100644 index d78dfec..0000000 --- a/public/css/hugo-easy-gallery.css +++ /dev/null @@ -1,159 +0,0 @@ -/* -Put this file in /static/css/hugo-easy-gallery.css -Documentation and licence at https://github.com/liwenyip/hugo-easy-gallery/ -*/ - - -/* -Grid Layout Styles -*/ -.gallery { - overflow: hidden; - margin: 10px; - max-width: 768px; -} -.gallery .box { - float: left; - position: relative; - /* Default: 1 tile wide */ - width: 100%; - padding-bottom: 100%; -} -@media only screen and (min-width : 365px) { - /* Tablet view: 2 tiles */ - .gallery .box { - width: 50%; - padding-bottom: 50%; - } -} -@media only screen and (min-width : 480px) { - /* Small desktop / ipad view: 3 tiles */ - .gallery .box { - width: 33.3%; - padding-bottom: 33.3%; /* */ - } -} -@media only screen and (min-width : 9999px) { - /* Medium desktop: 4 tiles */ - .box { - width: 25%; - padding-bottom: 25%; - } -} - -/* -Transition styles -*/ -.gallery.hover-transition figure, -.gallery.hover-effect-zoom .img, -.gallery:not(.caption-effect-appear) figcaption, -.fancy-figure:not(.caption-effect-appear) figcaption { - -webkit-transition: all 0.3s ease-in-out; - -moz-transition: all 0.3s ease-in-out; - -o-transition: all 0.3s ease-in-out; - transition: all 0.3s ease-in-out; -} -/* -figure styles -*/ -figure { - position:relative; /* purely to allow absolution positioning of figcaption */ - overflow: hidden; -} -.gallery figure { - position: absolute; - left: 5px; - right: 5px; - top: 5px; - bottom: 5px; -} -.gallery.hover-effect-grow figure:hover { - transform: scale(1.05); -} -.gallery.hover-effect-shrink figure:hover { - transform: scale(0.95); -} -.gallery.hover-effect-slidedown figure:hover { - transform: translateY(5px); -} -.gallery.hover-effect-slideup figure:hover { - transform: translateY(-5px); -} - -/* -img / a styles -*/ - -.gallery .img { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - background-size: cover; - background-position: 50% 50%; - background-repeat: no-repeat; -} -.gallery.hover-effect-zoom figure:hover .img { - transform: scale(1.05); -} -.gallery img { - display: none; /* only show the img if not inside a gallery */ -} -figure a { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; -} - -/* -figcaption styles -*/ -.gallery figcaption, -.fancy-figure figcaption { - position: absolute; - bottom: 0; - left: 0; - right: 0; - background: #000; - color: #FFF; - text-align: center; - font-size: 75%; /* change this if you want bigger text */ - background: rgba(0, 0, 0, 0.5); - opacity: 1; - cursor: pointer; -} -.gallery.caption-position-none figcaption, -.fancy-figure.caption-position-none figcaption { - display: none; -} -.gallery.caption-position-center figcaption, -.fancy-figure.caption-position-center figcaption { - top: 0; - padding: 40% 5px; -} -.gallery.caption-position-bottom figcaption, -.fancy-figure.caption-position-bottom figcaption { - padding: 5px; -} -.gallery.caption-effect-fade figure:not(:hover) figcaption, -.gallery.caption-effect-appear figure:not(:hover) figcaption, -.fancy-figure.caption-effect-fade figure:not(:hover) figcaption, -.fancy-figure.caption-effect-appear figure:not(:hover) figcaption { - background: rgba(0, 0, 0, 0); - opacity: 0; -} -.gallery.caption-effect-slide.caption-position-bottom figure:not(:hover) figcaption, -.fancy-figure.caption-effect-slide.caption-position-bottom figure:not(:hover) figcaption { - margin-bottom: -100%; -} -.gallery.caption-effect-slide.caption-position-center figure:not(:hover) figcaption, -.fancy-figure.caption-effect-slide.caption-position-center figure:not(:hover) figcaption { - top: 100%; -} -figcaption p { - margin: auto; /* override style in theme */ -} - diff --git a/public/css/hugo-theme.css b/public/css/hugo-theme.css deleted file mode 100644 index 741cab1..0000000 --- a/public/css/hugo-theme.css +++ /dev/null @@ -1,254 +0,0 @@ -/* Insert here special css for hugo theme, on top of any other imported css */ - - -/* Table of contents */ - -.progress ul { - list-style: none; - margin: 0; - padding: 0 5px; -} - -#TableOfContents { - font-size: 13px !important; - max-height: 85vh; - overflow: auto; - padding: 15px !important; -} - - -#TableOfContents > ul > li > ul > li > ul li { - margin-right: 8px; -} - -#TableOfContents > ul > li > a { - font-weight: bold; padding: 0 18px; margin: 0 2px; -} - -#TableOfContents > ul > li > ul > li > a { - font-weight: bold; -} - -#TableOfContents > ul > li > ul > li > ul > li > ul > li > ul > li { - display: none; -} - -body { - font-size: 16px !important; - color: #323232 !important; -} - -#body a.highlight, #body a.highlight:hover, #body a.highlight:focus { - text-decoration: none; - outline: none; - outline: 0; -} -#body a.highlight { - line-height: 1.1; - display: inline-block; -} -#body a.highlight:after { - display: block; - content: ""; - height: 1px; - width: 0%; - background-color: #0082a7; /*#CE3B2F*/ - -webkit-transition: width 0.5s ease; - -moz-transition: width 0.5s ease; - -ms-transition: width 0.5s ease; - transition: width 0.5s ease; -} -#body a.highlight:hover:after, #body a.highlight:focus:after { - width: 100%; -} -.progress { - position:absolute; - background-color: rgba(246, 246, 246, 0.97); - width: auto; - border: thin solid #ECECEC; - display:none; - z-index:200; -} - -#toc-menu { - border-right: thin solid #DAD8D8 !important; - padding-right: 1rem !important; - margin-right: 0.5rem !important; -} - -#sidebar-toggle-span { - border-right: thin solid #DAD8D8 !important; - padding-right: 0.5rem !important; - margin-right: 1rem !important; -} - -.btn { - display: inline-block !important; - padding: 6px 12px !important; - margin-bottom: 0 !important; - font-size: 14px !important; - font-weight: normal !important; - line-height: 1.42857143 !important; - text-align: center !important; - white-space: nowrap !important; - vertical-align: middle !important; - -ms-touch-action: manipulation !important; - touch-action: manipulation !important; - cursor: pointer !important; - -webkit-user-select: none !important; - -moz-user-select: none !important; - -ms-user-select: none !important; - user-select: none !important; - background-image: none !important; - border: 1px solid transparent !important; - border-radius: 4px !important; - -webkit-transition: all 0.15s !important; - -moz-transition: all 0.15s !important; - transition: all 0.15s !important; -} -.btn:focus { - /*outline: thin dotted; - outline: 5px auto -webkit-focus-ring-color; - outline-offset: -2px;*/ - outline: none !important; -} -.btn:hover, -.btn:focus { - color: #2b2b2b !important; - text-decoration: none !important; -} - -.btn-default { - color: #333 !important; - background-color: #fff !important; - border-color: #ccc !important; -} -.btn-default:hover, -.btn-default:focus, -.btn-default:active { - color: #fff !important; - background-color: #9e9e9e !important; - border-color: #9e9e9e !important; -} -.btn-default:active { - background-image: none !important; -} - -/* anchors */ -.anchor { - color: #00bdf3; - font-size: 0.5em; - cursor:pointer; - visibility:hidden; - margin-left: 0.5em; - position: absolute; - margin-top:0.1em; -} - -h2:hover .anchor, h3:hover .anchor, h4:hover .anchor, h5:hover .anchor, h6:hover .anchor { - visibility:visible; -} - -/* Redfines headers style */ - -h2, h3, h4, h5, h6 { - font-weight: 400; - line-height: 1.1; -} - -h1 a, h2 a, h3 a, h4 a, h5 a, h6 a { - font-weight: inherit; -} - -h2 { - font-size: 2.5rem; - line-height: 110% !important; - margin: 2.5rem 0 1.5rem 0; -} - -h3 { - font-size: 2rem; - line-height: 110% !important; - margin: 2rem 0 1rem 0; -} - -h4 { - font-size: 1.5rem; - line-height: 110% !important; - margin: 1.5rem 0 0.75rem 0; -} - -h5 { - font-size: 1rem; - line-height: 110% !important; - margin: 1rem 0 0.2rem 0; -} - -h6 { - font-size: 0.5rem; - line-height: 110% !important; - margin: 0.5rem 0 0.2rem 0; -} - -p { - margin: 1rem 0; -} - -figcaption h4 { - font-weight: 300 !important; - opacity: .85; - font-size: 1em; - text-align: center; - margin-top: -1.5em; -} - -.select-style { - border: 0; - width: 150px; - border-radius: 0px; - overflow: hidden; - display: inline-flex; -} - -.select-style svg { - fill: #ccc; - width: 14px; - height: 14px; - pointer-events: none; - margin: auto; -} - -.select-style svg:hover { - fill: #e6e6e6; -} - -.select-style select { - padding: 0; - width: 130%; - border: none; - box-shadow: none; - background: transparent; - background-image: none; - -webkit-appearance: none; - margin: auto; - margin-left: 0px; - margin-right: -20px; -} - -.select-style select:focus { - outline: none; -} - -.select-style :hover { - cursor: pointer; -} - -@media only all and (max-width: 47.938em) { - #breadcrumbs .links, #top-github-link-text { - display: none; - } -} - -.is-sticky #top-bar { - box-shadow: -1px 2px 5px 1px rgba(0, 0, 0, 0.1); -} \ No newline at end of file diff --git a/public/css/hybrid.css b/public/css/hybrid.css deleted file mode 100644 index 29735a1..0000000 --- a/public/css/hybrid.css +++ /dev/null @@ -1,102 +0,0 @@ -/* - -vim-hybrid theme by w0ng (https://github.com/w0ng/vim-hybrid) - -*/ - -/*background color*/ -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #1d1f21; -} - -/*selection color*/ -.hljs::selection, -.hljs span::selection { - background: #373b41; -} - -.hljs::-moz-selection, -.hljs span::-moz-selection { - background: #373b41; -} - -/*foreground color*/ -.hljs { - color: #c5c8c6; -} - -/*color: fg_yellow*/ -.hljs-title, -.hljs-name { - color: #f0c674; -} - -/*color: fg_comment*/ -.hljs-comment, -.hljs-meta, -.hljs-meta .hljs-keyword { - color: #707880; -} - -/*color: fg_red*/ -.hljs-number, -.hljs-symbol, -.hljs-literal, -.hljs-deletion, -.hljs-link { - color: #cc6666 -} - -/*color: fg_green*/ -.hljs-string, -.hljs-doctag, -.hljs-addition, -.hljs-regexp, -.hljs-selector-attr, -.hljs-selector-pseudo { - color: #b5bd68; -} - -/*color: fg_purple*/ -.hljs-attribute, -.hljs-code, -.hljs-selector-id { - color: #b294bb; -} - -/*color: fg_blue*/ -.hljs-keyword, -.hljs-selector-tag, -.hljs-bullet, -.hljs-tag { - color: #81a2be; -} - -/*color: fg_aqua*/ -.hljs-subst, -.hljs-variable, -.hljs-template-tag, -.hljs-template-variable { - color: #8abeb7; -} - -/*color: fg_orange*/ -.hljs-type, -.hljs-built_in, -.hljs-builtin-name, -.hljs-quote, -.hljs-section, -.hljs-selector-class { - color: #de935f; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} diff --git a/public/css/nucleus.css b/public/css/nucleus.css deleted file mode 100644 index 1897fc5..0000000 --- a/public/css/nucleus.css +++ /dev/null @@ -1,615 +0,0 @@ -*, *::before, *::after { - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; } - -@-webkit-viewport { - width: device-width; } -@-moz-viewport { - width: device-width; } -@-ms-viewport { - width: device-width; } -@-o-viewport { - width: device-width; } -@viewport { - width: device-width; } -html { - font-size: 100%; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; } - -body { - margin: 0; } - -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -nav, -section, -summary { - display: block; } - -audio, -canvas, -progress, -video { - display: inline-block; - vertical-align: baseline; } - -audio:not([controls]) { - display: none; - height: 0; } - -[hidden], -template { - display: none; } - -a { - background: transparent; - text-decoration: none; } - -a:active, -a:hover { - outline: 0; } - -abbr[title] { - border-bottom: 1px dotted; } - -b, -strong { - font-weight: bold; } - -dfn { - font-style: italic; } - -mark { - background: #FFFF27; - color: #333; } - -sub, -sup { - font-size: 0.8rem; - line-height: 0; - position: relative; - vertical-align: baseline; } - -sup { - top: -0.5em; } - -sub { - bottom: -0.25em; } - -img { - border: 0; - max-width: 100%; } - -svg:not(:root) { - overflow: hidden; } - -figure { - margin: 1em 40px; } - -hr { - height: 0; } - -pre { - overflow: auto; } - -button, -input, -optgroup, -select, -textarea { - color: inherit; - font: inherit; - margin: 0; } - -button { - overflow: visible; } - -button, -select { - text-transform: none; } - -button, -html input[type="button"], -input[type="reset"], -input[type="submit"] { - -webkit-appearance: button; - cursor: pointer; } - -button[disabled], -html input[disabled] { - cursor: default; } - -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; } - -input { - line-height: normal; } - -input[type="checkbox"], -input[type="radio"] { - padding: 0; } - -input[type="number"]::-webkit-inner-spin-button, -input[type="number"]::-webkit-outer-spin-button { - height: auto; } - -input[type="search"] { - -webkit-appearance: textfield; } - -input[type="search"]::-webkit-search-cancel-button, -input[type="search"]::-webkit-search-decoration { - -webkit-appearance: none; } - -legend { - border: 0; - padding: 0; } - -textarea { - overflow: auto; } - -optgroup { - font-weight: bold; } - -table { - border-collapse: collapse; - border-spacing: 0; - table-layout: fixed; - width: 100%; } - -tr, td, th { - vertical-align: middle; } - -th, td { - padding: 0.425rem 0; } - -th { - text-align: left; } - -.container { - width: 75em; - margin: 0 auto; - padding: 0; } - @media only all and (min-width: 60em) and (max-width: 74.938em) { - .container { - width: 60em; } } - @media only all and (min-width: 48em) and (max-width: 59.938em) { - .container { - width: 48em; } } - @media only all and (min-width: 30.063em) and (max-width: 47.938em) { - .container { - width: 30em; } } - @media only all and (max-width: 30em) { - .container { - width: 100%; } } - -.grid { - display: -webkit-box; - display: -moz-box; - display: box; - display: -webkit-flex; - display: -moz-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-flow: row; - -moz-flex-flow: row; - flex-flow: row; - list-style: none; - margin: 0; - padding: 0; } - @media only all and (max-width: 47.938em) { - .grid { - -webkit-flex-flow: row wrap; - -moz-flex-flow: row wrap; - flex-flow: row wrap; } } - -.block { - -webkit-box-flex: 1; - -moz-box-flex: 1; - box-flex: 1; - -webkit-flex: 1; - -moz-flex: 1; - -ms-flex: 1; - flex: 1; - min-width: 0; - min-height: 0; } - @media only all and (max-width: 47.938em) { - .block { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 100%; - -moz-flex: 0 100%; - -ms-flex: 0 100%; - flex: 0 100%; } } - -.content { - margin: 0.625rem; - padding: 0.938rem; } - -@media only all and (max-width: 47.938em) { - body [class*="size-"] { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 100%; - -moz-flex: 0 100%; - -ms-flex: 0 100%; - flex: 0 100%; } } - -.size-1-2 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 50%; - -moz-flex: 0 50%; - -ms-flex: 0 50%; - flex: 0 50%; } - -.size-1-3 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 33.33333%; - -moz-flex: 0 33.33333%; - -ms-flex: 0 33.33333%; - flex: 0 33.33333%; } - -.size-1-4 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 25%; - -moz-flex: 0 25%; - -ms-flex: 0 25%; - flex: 0 25%; } - -.size-1-5 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 20%; - -moz-flex: 0 20%; - -ms-flex: 0 20%; - flex: 0 20%; } - -.size-1-6 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 16.66667%; - -moz-flex: 0 16.66667%; - -ms-flex: 0 16.66667%; - flex: 0 16.66667%; } - -.size-1-7 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 14.28571%; - -moz-flex: 0 14.28571%; - -ms-flex: 0 14.28571%; - flex: 0 14.28571%; } - -.size-1-8 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 12.5%; - -moz-flex: 0 12.5%; - -ms-flex: 0 12.5%; - flex: 0 12.5%; } - -.size-1-9 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 11.11111%; - -moz-flex: 0 11.11111%; - -ms-flex: 0 11.11111%; - flex: 0 11.11111%; } - -.size-1-10 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 10%; - -moz-flex: 0 10%; - -ms-flex: 0 10%; - flex: 0 10%; } - -.size-1-11 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 9.09091%; - -moz-flex: 0 9.09091%; - -ms-flex: 0 9.09091%; - flex: 0 9.09091%; } - -.size-1-12 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 8.33333%; - -moz-flex: 0 8.33333%; - -ms-flex: 0 8.33333%; - flex: 0 8.33333%; } - -@media only all and (min-width: 48em) and (max-width: 59.938em) { - .size-tablet-1-2 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 50%; - -moz-flex: 0 50%; - -ms-flex: 0 50%; - flex: 0 50%; } - - .size-tablet-1-3 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 33.33333%; - -moz-flex: 0 33.33333%; - -ms-flex: 0 33.33333%; - flex: 0 33.33333%; } - - .size-tablet-1-4 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 25%; - -moz-flex: 0 25%; - -ms-flex: 0 25%; - flex: 0 25%; } - - .size-tablet-1-5 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 20%; - -moz-flex: 0 20%; - -ms-flex: 0 20%; - flex: 0 20%; } - - .size-tablet-1-6 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 16.66667%; - -moz-flex: 0 16.66667%; - -ms-flex: 0 16.66667%; - flex: 0 16.66667%; } - - .size-tablet-1-7 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 14.28571%; - -moz-flex: 0 14.28571%; - -ms-flex: 0 14.28571%; - flex: 0 14.28571%; } - - .size-tablet-1-8 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 12.5%; - -moz-flex: 0 12.5%; - -ms-flex: 0 12.5%; - flex: 0 12.5%; } - - .size-tablet-1-9 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 11.11111%; - -moz-flex: 0 11.11111%; - -ms-flex: 0 11.11111%; - flex: 0 11.11111%; } - - .size-tablet-1-10 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 10%; - -moz-flex: 0 10%; - -ms-flex: 0 10%; - flex: 0 10%; } - - .size-tablet-1-11 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 9.09091%; - -moz-flex: 0 9.09091%; - -ms-flex: 0 9.09091%; - flex: 0 9.09091%; } - - .size-tablet-1-12 { - -webkit-box-flex: 0; - -moz-box-flex: 0; - box-flex: 0; - -webkit-flex: 0 8.33333%; - -moz-flex: 0 8.33333%; - -ms-flex: 0 8.33333%; - flex: 0 8.33333%; } } -@media only all and (max-width: 47.938em) { - @supports not (flex-wrap: wrap) { - .grid { - display: block; - -webkit-box-lines: inherit; - -moz-box-lines: inherit; - box-lines: inherit; - -webkit-flex-wrap: inherit; - -moz-flex-wrap: inherit; - -ms-flex-wrap: inherit; - flex-wrap: inherit; } - - .block { - display: block; - -webkit-box-flex: inherit; - -moz-box-flex: inherit; - box-flex: inherit; - -webkit-flex: inherit; - -moz-flex: inherit; - -ms-flex: inherit; - flex: inherit; } } } -.first-block { - -webkit-box-ordinal-group: 0; - -webkit-order: -1; - -ms-flex-order: -1; - order: -1; } - -.last-block { - -webkit-box-ordinal-group: 2; - -webkit-order: 1; - -ms-flex-order: 1; - order: 1; } - -.fixed-blocks { - -webkit-flex-flow: row wrap; - -moz-flex-flow: row wrap; - flex-flow: row wrap; } - .fixed-blocks .block { - -webkit-box-flex: inherit; - -moz-box-flex: inherit; - box-flex: inherit; - -webkit-flex: inherit; - -moz-flex: inherit; - -ms-flex: inherit; - flex: inherit; - width: 25%; } - @media only all and (min-width: 60em) and (max-width: 74.938em) { - .fixed-blocks .block { - width: 33.33333%; } } - @media only all and (min-width: 48em) and (max-width: 59.938em) { - .fixed-blocks .block { - width: 50%; } } - @media only all and (max-width: 47.938em) { - .fixed-blocks .block { - width: 100%; } } - -body { - font-size: 1.05rem; - line-height: 1.7; } - -h1, h2, h3, h4, h5, h6 { - margin: 0.85rem 0 1.7rem 0; - text-rendering: optimizeLegibility; } - -h1 { - font-size: 3.25rem; } - -h2 { - font-size: 2.55rem; } - -h3 { - font-size: 2.15rem; } - -h4 { - font-size: 1.8rem; } - -h5 { - font-size: 1.4rem; } - -h6 { - font-size: 0.9rem; } - -p { - margin: 1.7rem 0; } - -ul, ol { - margin-top: 1.7rem; - margin-bottom: 1.7rem; } - ul ul, ul ol, ol ul, ol ol { - margin-top: 0; - margin-bottom: 0; } - -blockquote { - margin: 1.7rem 0; - padding-left: 0.85rem; } - -cite { - display: block; - font-size: 0.925rem; } - cite:before { - content: "\2014 \0020"; } - -pre { - margin: 1.7rem 0; - padding: 0.938rem; } - -code { - vertical-align: bottom; } - -small { - font-size: 0.925rem; } - -hr { - border-left: none; - border-right: none; - border-top: none; - margin: 1.7rem 0; } - -fieldset { - border: 0; - padding: 0.938rem; - margin: 0 0 1.7rem 0; } - -input, -label, -select { - display: block; } - -label { - margin-bottom: 0.425rem; } - label.required:after { - content: "*"; } - label abbr { - display: none; } - -textarea, input[type="email"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="url"], input[type="color"], input[type="date"], input[type="datetime"], input[type="datetime-local"], input[type="month"], input[type="time"], input[type="week"], select[multiple=multiple] { - -webkit-transition: border-color; - -moz-transition: border-color; - transition: border-color; - border-radius: 0.1875rem; - margin-bottom: 0.85rem; - padding: 0.425rem 0.425rem; - width: 100%; } - textarea:focus, input[type="email"]:focus, input[type="number"]:focus, input[type="password"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="text"]:focus, input[type="url"]:focus, input[type="color"]:focus, input[type="date"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="month"]:focus, input[type="time"]:focus, input[type="week"]:focus, select[multiple=multiple]:focus { - outline: none; } - -textarea { - resize: vertical; } - -input[type="checkbox"], input[type="radio"] { - display: inline; - margin-right: 0.425rem; } - -input[type="file"] { - width: 100%; } - -select { - width: auto; - max-width: 100%; - margin-bottom: 1.7rem; } - -button, -input[type="submit"] { - cursor: pointer; - user-select: none; - vertical-align: middle; - white-space: nowrap; - border: inherit; } diff --git a/public/css/perfect-scrollbar.min.css b/public/css/perfect-scrollbar.min.css deleted file mode 100644 index ebd2cb4..0000000 --- a/public/css/perfect-scrollbar.min.css +++ /dev/null @@ -1,2 +0,0 @@ -/* perfect-scrollbar v0.6.13 */ -.ps-container{-ms-touch-action:auto;touch-action:auto;overflow:hidden !important;-ms-overflow-style:none}@supports (-ms-overflow-style: none){.ps-container{overflow:auto !important}}@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none){.ps-container{overflow:auto !important}}.ps-container.ps-active-x>.ps-scrollbar-x-rail,.ps-container.ps-active-y>.ps-scrollbar-y-rail{display:block;background-color:transparent}.ps-container.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail{background-color:#eee;opacity:.9}.ps-container.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail>.ps-scrollbar-x{background-color:#999;height:11px}.ps-container.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail{background-color:#eee;opacity:.9}.ps-container.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail>.ps-scrollbar-y{background-color:#999;width:11px}.ps-container>.ps-scrollbar-x-rail{display:none;position:absolute;opacity:0;-webkit-transition:background-color .2s linear, opacity .2s linear;-o-transition:background-color .2s linear, opacity .2s linear;-moz-transition:background-color .2s linear, opacity .2s linear;transition:background-color .2s linear, opacity .2s linear;bottom:0px;height:15px}.ps-container>.ps-scrollbar-x-rail>.ps-scrollbar-x{position:absolute;background-color:#aaa;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;-o-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;-moz-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;bottom:2px;height:6px}.ps-container>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x,.ps-container>.ps-scrollbar-x-rail:active>.ps-scrollbar-x{height:11px}.ps-container>.ps-scrollbar-y-rail{display:none;position:absolute;opacity:0;-webkit-transition:background-color .2s linear, opacity .2s linear;-o-transition:background-color .2s linear, opacity .2s linear;-moz-transition:background-color .2s linear, opacity .2s linear;transition:background-color .2s linear, opacity .2s linear;right:0;width:15px}.ps-container>.ps-scrollbar-y-rail>.ps-scrollbar-y{position:absolute;background-color:#aaa;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, -webkit-border-radius .2s ease-in-out;-o-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;-moz-transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out;transition:background-color .2s linear, height .2s linear, width .2s ease-in-out, border-radius .2s ease-in-out, -webkit-border-radius .2s ease-in-out, -moz-border-radius .2s ease-in-out;right:2px;width:6px}.ps-container>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y,.ps-container>.ps-scrollbar-y-rail:active>.ps-scrollbar-y{width:11px}.ps-container:hover.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail{background-color:#eee;opacity:.9}.ps-container:hover.ps-in-scrolling.ps-x>.ps-scrollbar-x-rail>.ps-scrollbar-x{background-color:#999;height:11px}.ps-container:hover.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail{background-color:#eee;opacity:.9}.ps-container:hover.ps-in-scrolling.ps-y>.ps-scrollbar-y-rail>.ps-scrollbar-y{background-color:#999;width:11px}.ps-container:hover>.ps-scrollbar-x-rail,.ps-container:hover>.ps-scrollbar-y-rail{opacity:.6}.ps-container:hover>.ps-scrollbar-x-rail:hover{background-color:#eee;opacity:.9}.ps-container:hover>.ps-scrollbar-x-rail:hover>.ps-scrollbar-x{background-color:#999}.ps-container:hover>.ps-scrollbar-y-rail:hover{background-color:#eee;opacity:.9}.ps-container:hover>.ps-scrollbar-y-rail:hover>.ps-scrollbar-y{background-color:#999} diff --git a/public/css/tags.css b/public/css/tags.css deleted file mode 100644 index 495d2f9..0000000 --- a/public/css/tags.css +++ /dev/null @@ -1,49 +0,0 @@ -/* Tags */ - -#head-tags{ - margin-left:1em; - margin-top:1em; -} - -#body .tags a.tag-link { - display: inline-block; - line-height: 2em; - font-size: 0.8em; - position: relative; - margin: 0 16px 8px 0; - padding: 0 10px 0 12px; - background: #8451a1; - - -webkit-border-bottom-right-radius: 3px; - border-bottom-right-radius: 3px; - -webkit-border-top-right-radius: 3px; - border-top-right-radius: 3px; - - -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.2); - box-shadow: 0 1px 2px rgba(0,0,0,0.2); - color: #fff; -} - -#body .tags a.tag-link:before { - content: ""; - position: absolute; - top:0; - left: -1em; - width: 0; - height: 0; - border-color: transparent #8451a1 transparent transparent; - border-style: solid; - border-width: 1em 1em 1em 0; -} - -#body .tags a.tag-link:after { - content: ""; - position: absolute; - top: 10px; - left: 1px; - width: 5px; - height: 5px; - -webkit-border-radius: 50%; - border-radius: 100%; - background: #fff; -} diff --git a/public/css/theme-blue.css b/public/css/theme-blue.css deleted file mode 100644 index 1ee1423..0000000 --- a/public/css/theme-blue.css +++ /dev/null @@ -1,128 +0,0 @@ - -:root{ - - --MAIN-TEXT-color:#323232; /* Color of text by default */ - --MAIN-TITLES-TEXT-color: #5e5e5e; /* Color of titles h2-h3-h4-h5 */ - --MAIN-LINK-color:#1C90F3; /* Color of links */ - --MAIN-LINK-HOVER-color:#167ad0; /* Color of hovered links */ - --MAIN-ANCHOR-color: #1C90F3; /* color of anchors on titles */ - - --MENU-HOME-LINK-color: #323232; /* Color of the home button text */ - --MENU-HOME-LINK-HOVER-color: #5e5e5e; /* Color of the hovered home button text */ - - --MENU-HEADER-BG-color:#1C90F3; /* Background color of menu header */ - --MENU-HEADER-BORDER-color:#33a1ff; /*Color of menu header border */ - - --MENU-SEARCH-BG-color:#167ad0; /* Search field background color (by default borders + icons) */ - --MENU-SEARCH-BOX-color: #33a1ff; /* Override search field border color */ - --MENU-SEARCH-BOX-ICONS-color: #a1d2fd; /* Override search field icons color */ - - --MENU-SECTIONS-ACTIVE-BG-color:#20272b; /* Background color of the active section and its childs */ - --MENU-SECTIONS-BG-color:#252c31; /* Background color of other sections */ - --MENU-SECTIONS-LINK-color: #ccc; /* Color of links in menu */ - --MENU-SECTIONS-LINK-HOVER-color: #e6e6e6; /* Color of links in menu, when hovered */ - --MENU-SECTION-ACTIVE-CATEGORY-color: #777; /* Color of active category text */ - --MENU-SECTION-ACTIVE-CATEGORY-BG-color: #fff; /* Color of background for the active category (only) */ - - --MENU-VISITED-color: #33a1ff; /* Color of 'page visited' icons in menu */ - --MENU-SECTION-HR-color: #20272b; /* Color of
    separator in menu */ - -} - -body { - color: var(--MAIN-TEXT-color) !important; -} - -textarea:focus, input[type="email"]:focus, input[type="number"]:focus, input[type="password"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="text"]:focus, input[type="url"]:focus, input[type="color"]:focus, input[type="date"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="month"]:focus, input[type="time"]:focus, input[type="week"]:focus, select[multiple=multiple]:focus { - border-color: none; - box-shadow: none; -} - -h2, h3, h4, h5 { - color: var(--MAIN-TITLES-TEXT-color) !important; -} - -a { - color: var(--MAIN-LINK-color); -} - -.anchor { - color: var(--MAIN-ANCHOR-color); -} - -a:hover { - color: var(--MAIN-LINK-HOVER-color); -} - -#sidebar ul li.visited > a .read-icon { - color: var(--MENU-VISITED-color); -} - -#body a.highlight:after { - display: block; - content: ""; - height: 1px; - width: 0%; - -webkit-transition: width 0.5s ease; - -moz-transition: width 0.5s ease; - -ms-transition: width 0.5s ease; - transition: width 0.5s ease; - background-color: var(--MAIN-LINK-HOVER-color); -} -#sidebar { - background-color: var(--MENU-SECTIONS-BG-color); -} -#sidebar #header-wrapper { - background: var(--MENU-HEADER-BG-color); - color: var(--MENU-SEARCH-BOX-color); - border-color: var(--MENU-HEADER-BORDER-color); -} -#sidebar .searchbox { - border-color: var(--MENU-SEARCH-BOX-color); - background: var(--MENU-SEARCH-BG-color); -} -#sidebar ul.topics > li.parent, #sidebar ul.topics > li.active { - background: var(--MENU-SECTIONS-ACTIVE-BG-color); -} -#sidebar .searchbox * { - color: var(--MENU-SEARCH-BOX-ICONS-color); -} - -#sidebar a { - color: var(--MENU-SECTIONS-LINK-color); -} - -#sidebar a:hover { - color: var(--MENU-SECTIONS-LINK-HOVER-color); -} - -#sidebar ul li.active > a { - background: var(--MENU-SECTION-ACTIVE-CATEGORY-BG-color); - color: var(--MENU-SECTION-ACTIVE-CATEGORY-color) !important; -} - -#sidebar hr { - border-color: var(--MENU-SECTION-HR-color); -} - -#body .tags a.tag-link { - background-color: var(--MENU-HEADER-BG-color); -} - -#body .tags a.tag-link:before { - border-right-color: var(--MENU-HEADER-BG-color); -} - -#homelinks { - background: var(--MENU-HEADER-BG-color); - background-color: var(--MENU-HEADER-BORDER-color); - border-bottom-color: var(--MENU-HEADER-BORDER-color); -} - -#homelinks a { - color: var(--MENU-HOME-LINK-color); -} - -#homelinks a:hover { - color: var(--MENU-HOME-LINK-HOVERED-color); -} \ No newline at end of file diff --git a/public/css/theme-green.css b/public/css/theme-green.css deleted file mode 100644 index c074679..0000000 --- a/public/css/theme-green.css +++ /dev/null @@ -1,128 +0,0 @@ - -:root{ - - --MAIN-TEXT-color:#323232; /* Color of text by default */ - --MAIN-TITLES-TEXT-color: #5e5e5e; /* Color of titles h2-h3-h4-h5 */ - --MAIN-LINK-color:#599a3e; /* Color of links */ - --MAIN-LINK-HOVER-color:#3f6d2c; /* Color of hovered links */ - --MAIN-ANCHOR-color: #599a3e; /* color of anchors on titles */ - - --MENU-HOME-LINK-color: #323232; /* Color of the home button text */ - --MENU-HOME-LINK-HOVER-color: #5e5e5e; /* Color of the hovered home button text */ - - --MENU-HEADER-BG-color:#74b559; /* Background color of menu header */ - --MENU-HEADER-BORDER-color:#9cd484; /*Color of menu header border */ - - --MENU-SEARCH-BG-color:#599a3e; /* Search field background color (by default borders + icons) */ - --MENU-SEARCH-BOX-color: #84c767; /* Override search field border color */ - --MENU-SEARCH-BOX-ICONS-color: #c7f7c4; /* Override search field icons color */ - - --MENU-SECTIONS-ACTIVE-BG-color:#1b211c; /* Background color of the active section and its childs */ - --MENU-SECTIONS-BG-color:#222723; /* Background color of other sections */ - --MENU-SECTIONS-LINK-color: #ccc; /* Color of links in menu */ - --MENU-SECTIONS-LINK-HOVER-color: #e6e6e6; /* Color of links in menu, when hovered */ - --MENU-SECTION-ACTIVE-CATEGORY-color: #777; /* Color of active category text */ - --MENU-SECTION-ACTIVE-CATEGORY-BG-color: #fff; /* Color of background for the active category (only) */ - - --MENU-VISITED-color: #599a3e; /* Color of 'page visited' icons in menu */ - --MENU-SECTION-HR-color: #18211c; /* Color of
    separator in menu */ - -} - -body { - color: var(--MAIN-TEXT-color) !important; -} - -textarea:focus, input[type="email"]:focus, input[type="number"]:focus, input[type="password"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="text"]:focus, input[type="url"]:focus, input[type="color"]:focus, input[type="date"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="month"]:focus, input[type="time"]:focus, input[type="week"]:focus, select[multiple=multiple]:focus { - border-color: none; - box-shadow: none; -} - -h2, h3, h4, h5 { - color: var(--MAIN-TITLES-TEXT-color) !important; -} - -a { - color: var(--MAIN-LINK-color); -} - -.anchor { - color: var(--MAIN-ANCHOR-color); -} - -a:hover { - color: var(--MAIN-LINK-HOVER-color); -} - -#sidebar ul li.visited > a .read-icon { - color: var(--MENU-VISITED-color); -} - -#body a.highlight:after { - display: block; - content: ""; - height: 1px; - width: 0%; - -webkit-transition: width 0.5s ease; - -moz-transition: width 0.5s ease; - -ms-transition: width 0.5s ease; - transition: width 0.5s ease; - background-color: var(--MAIN-LINK-HOVER-color); -} -#sidebar { - background-color: var(--MENU-SECTIONS-BG-color); -} -#sidebar #header-wrapper { - background: var(--MENU-HEADER-BG-color); - color: var(--MENU-SEARCH-BOX-color); - border-color: var(--MENU-HEADER-BORDER-color); -} -#sidebar .searchbox { - border-color: var(--MENU-SEARCH-BOX-color); - background: var(--MENU-SEARCH-BG-color); -} -#sidebar ul.topics > li.parent, #sidebar ul.topics > li.active { - background: var(--MENU-SECTIONS-ACTIVE-BG-color); -} -#sidebar .searchbox * { - color: var(--MENU-SEARCH-BOX-ICONS-color); -} - -#sidebar a { - color: var(--MENU-SECTIONS-LINK-color); -} - -#sidebar a:hover { - color: var(--MENU-SECTIONS-LINK-HOVER-color); -} - -#sidebar ul li.active > a { - background: var(--MENU-SECTION-ACTIVE-CATEGORY-BG-color); - color: var(--MENU-SECTION-ACTIVE-CATEGORY-color) !important; -} - -#sidebar hr { - border-color: var(--MENU-SECTION-HR-color); -} - -#body .tags a.tag-link { - background-color: var(--MENU-HEADER-BG-color); -} - -#body .tags a.tag-link:before { - border-right-color: var(--MENU-HEADER-BG-color); -} - -#homelinks { - background: var(--MENU-HEADER-BG-color); - background-color: var(--MENU-HEADER-BORDER-color); - border-bottom-color: var(--MENU-HEADER-BORDER-color); -} - -#homelinks a { - color: var(--MENU-HOME-LINK-color); -} - -#homelinks a:hover { - color: var(--MENU-HOME-LINK-HOVERED-color); -} \ No newline at end of file diff --git a/public/css/theme-red.css b/public/css/theme-red.css deleted file mode 100644 index c5f2674..0000000 --- a/public/css/theme-red.css +++ /dev/null @@ -1,128 +0,0 @@ - -:root{ - - --MAIN-TEXT-color:#323232; /* Color of text by default */ - --MAIN-TITLES-TEXT-color: #5e5e5e; /* Color of titles h2-h3-h4-h5 */ - --MAIN-LINK-color:#f31c1c; /* Color of links */ - --MAIN-LINK-HOVER-color:#d01616; /* Color of hovered links */ - --MAIN-ANCHOR-color: #f31c1c; /* color of anchors on titles */ - - --MENU-HOME-LINK-color: #ccc; /* Color of the home button text */ - --MENU-HOME-LINK-HOVER-color: #e6e6e6; /* Color of the hovered home button text */ - - --MENU-HEADER-BG-color:#dc1010; /* Background color of menu header */ - --MENU-HEADER-BORDER-color:#e23131; /*Color of menu header border */ - - --MENU-SEARCH-BG-color:#b90000; /* Search field background color (by default borders + icons) */ - --MENU-SEARCH-BOX-color: #ef2020; /* Override search field border color */ - --MENU-SEARCH-BOX-ICONS-color: #fda1a1; /* Override search field icons color */ - - --MENU-SECTIONS-ACTIVE-BG-color:#2b2020; /* Background color of the active section and its childs */ - --MENU-SECTIONS-BG-color:#312525; /* Background color of other sections */ - --MENU-SECTIONS-LINK-color: #ccc; /* Color of links in menu */ - --MENU-SECTIONS-LINK-HOVER-color: #e6e6e6; /* Color of links in menu, when hovered */ - --MENU-SECTION-ACTIVE-CATEGORY-color: #777; /* Color of active category text */ - --MENU-SECTION-ACTIVE-CATEGORY-BG-color: #fff; /* Color of background for the active category (only) */ - - --MENU-VISITED-color: #ff3333; /* Color of 'page visited' icons in menu */ - --MENU-SECTION-HR-color: #2b2020; /* Color of
    separator in menu */ - -} - -body { - color: var(--MAIN-TEXT-color) !important; -} - -textarea:focus, input[type="email"]:focus, input[type="number"]:focus, input[type="password"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="text"]:focus, input[type="url"]:focus, input[type="color"]:focus, input[type="date"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="month"]:focus, input[type="time"]:focus, input[type="week"]:focus, select[multiple=multiple]:focus { - border-color: none; - box-shadow: none; -} - -h2, h3, h4, h5 { - color: var(--MAIN-TITLES-TEXT-color) !important; -} - -a { - color: var(--MAIN-LINK-color); -} - -.anchor { - color: var(--MAIN-ANCHOR-color); -} - -a:hover { - color: var(--MAIN-LINK-HOVER-color); -} - -#sidebar ul li.visited > a .read-icon { - color: var(--MENU-VISITED-color); -} - -#body a.highlight:after { - display: block; - content: ""; - height: 1px; - width: 0%; - -webkit-transition: width 0.5s ease; - -moz-transition: width 0.5s ease; - -ms-transition: width 0.5s ease; - transition: width 0.5s ease; - background-color: var(--MAIN-LINK-HOVER-color); -} -#sidebar { - background-color: var(--MENU-SECTIONS-BG-color); -} -#sidebar #header-wrapper { - background: var(--MENU-HEADER-BG-color); - color: var(--MENU-SEARCH-BOX-color); - border-color: var(--MENU-HEADER-BORDER-color); -} -#sidebar .searchbox { - border-color: var(--MENU-SEARCH-BOX-color); - background: var(--MENU-SEARCH-BG-color); -} -#sidebar ul.topics > li.parent, #sidebar ul.topics > li.active { - background: var(--MENU-SECTIONS-ACTIVE-BG-color); -} -#sidebar .searchbox * { - color: var(--MENU-SEARCH-BOX-ICONS-color); -} - -#sidebar a { - color: var(--MENU-SECTIONS-LINK-color); -} - -#sidebar a:hover { - color: var(--MENU-SECTIONS-LINK-HOVER-color); -} - -#sidebar ul li.active > a { - background: var(--MENU-SECTION-ACTIVE-CATEGORY-BG-color); - color: var(--MENU-SECTION-ACTIVE-CATEGORY-color) !important; -} - -#sidebar hr { - border-color: var(--MENU-SECTION-HR-color); -} - -#body .tags a.tag-link { - background-color: var(--MENU-HEADER-BG-color); -} - -#body .tags a.tag-link:before { - border-right-color: var(--MENU-HEADER-BG-color); -} - -#homelinks { - background: var(--MENU-HEADER-BG-color); - background-color: var(--MENU-HEADER-BORDER-color); - border-bottom-color: var(--MENU-HEADER-BORDER-color); -} - -#homelinks a { - color: var(--MENU-HOME-LINK-color); -} - -#homelinks a:hover { - color: var(--MENU-HOME-LINK-HOVERED-color); -} \ No newline at end of file diff --git a/public/css/theme.css b/public/css/theme.css deleted file mode 100644 index fb3bcd3..0000000 --- a/public/css/theme.css +++ /dev/null @@ -1,1151 +0,0 @@ -@charset "UTF-8"; - -/* Tags */ -@import "tags.css"; - -#top-github-link, #body #breadcrumbs { - position: relative; - top: 50%; - -webkit-transform: translateY(-50%); - -moz-transform: translateY(-50%); - -o-transform: translateY(-50%); - -ms-transform: translateY(-50%); - transform: translateY(-50%); -} -.button, .button-secondary { - display: inline-block; - padding: 7px 12px; -} -.button:active, .button-secondary:active { - margin: 2px 0 -2px 0; -} -@font-face { - font-family: 'Novacento Sans Wide'; - src: url("../fonts/Novecentosanswide-UltraLight-webfont.eot"); - src: url("../fonts/Novecentosanswide-UltraLight-webfont.eot?#iefix") format("embedded-opentype"), url("../fonts/Novecentosanswide-UltraLight-webfont.woff2") format("woff2"), url("../fonts/Novecentosanswide-UltraLight-webfont.woff") format("woff"), url("../fonts/Novecentosanswide-UltraLight-webfont.ttf") format("truetype"), url("../fonts/Novecentosanswide-UltraLight-webfont.svg#novecento_sans_wideultralight") format("svg"); - font-style: normal; - font-weight: 200; -} -@font-face { - font-family: 'Work Sans'; - font-style: normal; - font-weight: 300; - src: url("../fonts/Work_Sans_300.eot?#iefix") format("embedded-opentype"), url("../fonts/Work_Sans_300.woff") format("woff"), url("../fonts/Work_Sans_300.woff2") format("woff2"), url("../fonts/Work_Sans_300.svg#WorkSans") format("svg"), url("../fonts/Work_Sans_300.ttf") format("truetype"); -} -@font-face { - font-family: 'Work Sans'; - font-style: normal; - font-weight: 500; - src: url("../fonts/Work_Sans_500.eot?#iefix") format("embedded-opentype"), url("../fonts/Work_Sans_500.woff") format("woff"), url("../fonts/Work_Sans_500.woff2") format("woff2"), url("../fonts/Work_Sans_500.svg#WorkSans") format("svg"), url("../fonts/Work_Sans_500.ttf") format("truetype"); -} -body { - background: #fff; - color: #777; -} -body #chapter h1 { - font-size: 3.5rem; -} -@media only all and (min-width: 48em) and (max-width: 59.938em) { - body #chapter h1 { - font-size: 3rem; - } -} -@media only all and (max-width: 47.938em) { - body #chapter h1 { - font-size: 2rem; - } -} -a { - color: #00bdf3; -} -a:hover { - color: #0082a7; -} -pre { - position: relative; - color: #ffffff; -} -.bg { - background: #fff; - border: 1px solid #eaeaea; -} -b, strong, label, th { - font-weight: 600; -} -.default-animation, #header #logo-svg, #header #logo-svg path, #sidebar, #sidebar ul, #body, #body .padding, #body .nav { - -webkit-transition: all 0.5s ease; - -moz-transition: all 0.5s ease; - transition: all 0.5s ease; -} -#grav-logo { - max-width: 60%; -} -#grav-logo path { - fill: #fff !important; -} -#sidebar { - font-weight: 300 !important; -} -fieldset { - border: 1px solid #ddd; -} -textarea, input[type="email"], input[type="number"], input[type="password"], input[type="search"], input[type="tel"], input[type="text"], input[type="url"], input[type="color"], input[type="date"], input[type="datetime"], input[type="datetime-local"], input[type="month"], input[type="time"], input[type="week"], select[multiple=multiple] { - background-color: white; - border: 1px solid #ddd; - box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.06); -} -textarea:hover, input[type="email"]:hover, input[type="number"]:hover, input[type="password"]:hover, input[type="search"]:hover, input[type="tel"]:hover, input[type="text"]:hover, input[type="url"]:hover, input[type="color"]:hover, input[type="date"]:hover, input[type="datetime"]:hover, input[type="datetime-local"]:hover, input[type="month"]:hover, input[type="time"]:hover, input[type="week"]:hover, select[multiple=multiple]:hover { - border-color: #c4c4c4; -} -textarea:focus, input[type="email"]:focus, input[type="number"]:focus, input[type="password"]:focus, input[type="search"]:focus, input[type="tel"]:focus, input[type="text"]:focus, input[type="url"]:focus, input[type="color"]:focus, input[type="date"]:focus, input[type="datetime"]:focus, input[type="datetime-local"]:focus, input[type="month"]:focus, input[type="time"]:focus, input[type="week"]:focus, select[multiple=multiple]:focus { - border-color: #00bdf3; - box-shadow: inset 0 1px 3px rgba(0,0,0,.06),0 0 5px rgba(0,169,218,.7) -} -#header-wrapper { - background: #8451a1; - color: #fff; - text-align: center; - border-bottom: 4px solid #9c6fb6; - padding: 1rem; -} -#header a { - display: inline-block; -} -#header #logo-svg { - width: 8rem; - height: 2rem; -} -#header #logo-svg path { - fill: #fff; -} -.searchbox { - margin-top: 1rem; - position: relative; - border: 1px solid #915eae; - background: #764890; - border-radius: 4px; -} -.searchbox label { - color: rgba(255, 255, 255, 0.8); - position: absolute; - left: 10px; - top: 3px; -} -.searchbox span { - color: rgba(255, 255, 255, 0.6); - position: absolute; - right: 10px; - top: 3px; - cursor: pointer; -} -.searchbox span:hover { - color: rgba(255, 255, 255, 0.9); -} -.searchbox input { - display: inline-block; - color: #fff; - width: 100%; - height: 30px; - background: transparent; - border: 0; - padding: 0 25px 0 30px; - margin: 0; - font-weight: 300; -} -.searchbox input::-webkit-input-placeholder { - color: rgba(255, 255, 255, 0.6); -} -.searchbox input::-moz-placeholder { - color: rgba(255, 255, 255, 0.6); -} -.searchbox input:-moz-placeholder { - color: rgba(255, 255, 255, 0.6); -} -.searchbox input:-ms-input-placeholder { - color: rgba(255, 255, 255, 0.6); -} -#sidebar-toggle-span { - display: none; -} -@media only all and (max-width: 47.938em) { - #sidebar-toggle-span { - display: inline; - } -} -#sidebar { - background-color: #322A38; - position: fixed; - top: 0; - width: 300px; - bottom: 0; - left: 0; - font-weight: 400; - font-size: 15px; -} -#sidebar a { - color: #ccc; -} -#sidebar a:hover { - color: #e6e6e6; -} -#sidebar a.subtitle { - color: rgba(204, 204, 204, 0.6); -} -#sidebar hr { - border-bottom: 1px solid #2a232f; -} -#sidebar a.padding { - padding: 0 1rem; -} -#sidebar h5 { - margin: 2rem 0 0; - position: relative; - line-height: 2; -} -#sidebar h5 a { - display: block; - margin-left: 0; - margin-right: 0; - padding-left: 1rem; - padding-right: 1rem; -} -#sidebar h5 i { - color: rgba(204, 204, 204, 0.6); - position: absolute; - right: 0.6rem; - top: 0.7rem; - font-size: 80%; -} -#sidebar h5.parent a { - background: #201b24; - color: #d9d9d9 !important; -} -#sidebar h5.active a { - background: #fff; - color: #777 !important; -} -#sidebar h5.active i { - color: #777 !important; -} -#sidebar h5 + ul.topics { - display: none; - margin-top: 0; -} -#sidebar h5.parent + ul.topics, #sidebar h5.active + ul.topics { - display: block; -} -#sidebar ul { - list-style: none; - padding: 0; - margin: 0; -} -#sidebar ul.searched a { - color: #999999; -} -#sidebar ul.searched .search-match a { - color: #e6e6e6; -} -#sidebar ul.searched .search-match a:hover { - color: white; -} -#sidebar ul.topics { - margin: 0 1rem; -} -#sidebar ul.topics.searched ul { - display: block; -} -#sidebar ul.topics ul { - display: none; - padding-bottom: 1rem; -} -#sidebar ul.topics ul ul { - padding-bottom: 0; -} -#sidebar ul.topics li.parent ul, #sidebar ul.topics > li.active ul { - display: block; -} -#sidebar ul.topics > li > a { - line-height: 2rem; - font-size: 1.1rem; -} -#sidebar ul.topics > li > a b { - opacity: 0.5; - font-weight: normal; -} -#sidebar ul.topics > li > a .fa { - margin-top: 9px; -} -#sidebar ul.topics > li.parent, #sidebar ul.topics > li.active { - background: #251f29; - margin-left: -1rem; - margin-right: -1rem; - padding-left: 1rem; - padding-right: 1rem; -} -#sidebar ul li.active > a { - background: #fff; - color: #777 !important; - margin-left: -1rem; - margin-right: -1rem; - padding-left: 1rem; - padding-right: 1rem; -} -#sidebar ul li { - padding: 0; -} -#sidebar ul li.visited + span { - margin-right: 16px; -} -#sidebar ul li a { - display: block; - padding: 2px 0; -} -#sidebar ul li a span { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - display: block; -} -#sidebar ul li > a { - padding: 4px 0; -} -#sidebar ul li.visited > a .read-icon { - color: #9c6fb6; - display: inline; -} -#sidebar ul li li { - padding-left: 1rem; - text-indent: 0.2rem; -} -#main { - background: #f7f7f7; - margin: 0 0 1.563rem 0; -} -#body { - position: relative; - margin-left: 300px; - min-height: 100%; -} -#body img, #body .video-container { - margin: 3rem auto; - display: block; - text-align: center; -} -#body img.border, #body .video-container.border { - border: 2px solid #e6e6e6 !important; - padding: 2px; -} -#body img.shadow, #body .video-container.shadow { - box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1); -} -#body img.inline { - display: inline !important; - margin: 0 !important; - vertical-align: bottom; -} -#body .bordered { - border: 1px solid #ccc; -} -#body .padding { - padding: 3rem 6rem; -} -@media only all and (max-width: 59.938em) { - #body .padding { - position: static; - padding: 15px 3rem; - } -} -@media only all and (max-width: 47.938em) { - #body .padding { - padding: 5px 1rem; - } -} -#body h1 + hr { - margin-top: -1.7rem; - margin-bottom: 3rem; -} -@media only all and (max-width: 59.938em) { - #body #navigation { - position: static; - margin-right: 0 !important; - width: 100%; - display: table; - } -} -#body .nav { - position: fixed; - top: 0; - bottom: 0; - width: 4rem; - font-size: 50px; - height: 100%; - cursor: pointer; - display: table; - text-align: center; -} -#body .nav > i { - display: table-cell; - vertical-align: middle; - text-align: center; -} -@media only all and (max-width: 59.938em) { - #body .nav { - display: table-cell; - position: static; - top: auto; - width: 50%; - text-align: center; - height: 100px; - line-height: 100px; - padding-top: 0; - } - #body .nav > i { - display: inline-block; - } -} -#body .nav:hover { - background: #F6F6F6; -} -#body .nav.nav-pref { - left: 0; -} -#body .nav.nav-next { - right: 0; -} -#body-inner { - margin-bottom: 5rem; -} -#chapter { - display: flex; - align-items: center; - justify-content: center; - height: 100%; - padding: 2rem 0; -} -#chapter #body-inner { - padding-bottom: 3rem; - max-width: 80%; -} -#chapter h3 { - font-family: "Work Sans", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif; - font-weight: 300; - text-align: center; -} -#chapter h1 { - font-size: 5rem; - border-bottom: 4px solid #F0F2F4; -} -#chapter p { - text-align: center; - font-size: 1.2rem; -} -#footer { - padding: 3rem 1rem; - color: #b3b3b3; - font-size: 13px; -} -#footer p { - margin: 0; -} -body { - font-family: "Work Sans", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif; - font-weight: 300; - line-height: 1.6; - font-size: 18px !important; -} -h2, h3, h4, h5, h6 { - font-family: "Work Sans", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif; - text-rendering: optimizeLegibility; - color: #5e5e5e; - font-weight: 400; - letter-spacing: -1px; -} -h1 { - font-family: "Novacento Sans Wide", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif; - text-align: center; - text-transform: uppercase; - color: #222; - font-weight: 200; -} -blockquote { - border-left: 10px solid #F0F2F4; -} -blockquote p { - font-size: 1.1rem; - color: #999; -} -blockquote cite { - display: block; - text-align: right; - color: #666; - font-size: 1.2rem; -} -div.notices { - margin: 2rem 0; - position: relative; -} -div.notices p { - padding: 15px; - display: block; - font-size: 1rem; - margin-top: 0rem; - margin-bottom: 0rem; - color: #666; -} -div.notices p:first-child:before { - position: absolute; - top: 2px; - color: #fff; - font-family: "Font Awesome 5 Free"; - font-weight: 900; - content: "\f06a"; - left: 10px; -} -div.notices p:first-child:after { - position: absolute; - top: 2px; - color: #fff; - left: 2rem; -} -div.notices.info p { - border-top: 30px solid #F0B37E; - background: #FFF2DB; -} -div.notices.info p:first-child:after { - content: 'Info'; -} -div.notices.warning p { - border-top: 30px solid rgba(217, 83, 79, 0.8); - background: #FAE2E2; -} -div.notices.warning p:first-child:after { - content: 'Warning'; -} -div.notices.note p { - border-top: 30px solid #6AB0DE; - background: #E7F2FA; -} -div.notices.note p:first-child:after { - content: 'Note'; -} -div.notices.tip p { - border-top: 30px solid rgba(92, 184, 92, 0.8); - background: #E6F9E6; -} -div.notices.tip p:first-child:after { - content: 'Tip'; -} - -/* attachments shortcode */ - -section.attachments { - margin: 2rem 0; - position: relative; -} - -section.attachments label { - font-weight: 400; - padding-left: 0.5em; - padding-top: 0.2em; - padding-bottom: 0.2em; - margin: 0; -} - -section.attachments .attachments-files { - padding: 15px; - display: block; - font-size: 1rem; - margin-top: 0rem; - margin-bottom: 0rem; - color: #666; -} - -section.attachments.orange label { - color: #fff; - background: #F0B37E; -} - -section.attachments.orange .attachments-files { - background: #FFF2DB; -} - -section.attachments.green label { - color: #fff; - background: rgba(92, 184, 92, 0.8); -} - -section.attachments.green .attachments-files { - background: #E6F9E6; -} - -section.attachments.blue label { - color: #fff; - background: #6AB0DE; -} - -section.attachments.blue .attachments-files { - background: #E7F2FA; -} - -section.attachments.grey label { - color: #fff; - background: #505d65; -} - -section.attachments.grey .attachments-files { - background: #f4f4f4; -} - -/* Children shortcode */ - -/* Children shortcode */ -.children p { - font-size: small; - margin-top: 0px; - padding-top: 0px; - margin-bottom: 0px; - padding-bottom: 0px; -} -.children-li p { - font-size: small; - font-style: italic; - -} -.children-h2 p, .children-h3 p { - font-size: small; - margin-top: 0px; - padding-top: 0px; - margin-bottom: 0px; - padding-bottom: 0px; -} -.children h3,.children h2 { - margin-bottom: 0px; - margin-top: 5px; -} - -code, kbd, pre, samp { - font-family: "Consolas", menlo, monospace; - font-size: 92%; -} -code { - border-radius: 2px; - white-space: nowrap; - color: #5e5e5e; - background: #FFF7DD; - border: 1px solid #fbf0cb; - padding: 0px 2px; -} -code + .copy-to-clipboard { - margin-left: -1px; - border-left: 0 !important; - font-size: inherit !important; - vertical-align: middle; - height: 21px; - top: 0; -} -pre { - padding: 1rem; - margin: 2rem 0; - background: #282c34; - border: 0; - border-radius: 2px; - line-height: 1.15; -} -pre code { - color: whitesmoke; - background: inherit; - white-space: inherit; - border: 0; - padding: 0; - margin: 0; - font-size: 15px; -} -hr { - border-bottom: 4px solid #F0F2F4; -} -.page-title { - margin-top: -25px; - padding: 25px; - float: left; - clear: both; - background: #9c6fb6; - color: #fff; -} -#body a.anchor-link { - color: #ccc; -} -#body a.anchor-link:hover { - color: #9c6fb6; -} -#body-inner .tabs-wrapper.ui-theme-badges { - background: #1d1f21; -} -#body-inner .tabs-wrapper.ui-theme-badges .tabs-nav li { - font-size: 0.9rem; - text-transform: uppercase; -} -#body-inner .tabs-wrapper.ui-theme-badges .tabs-nav li a { - background: #35393c; -} -#body-inner .tabs-wrapper.ui-theme-badges .tabs-nav li.current a { - background: #4d5257; -} -#body-inner pre { - white-space: pre-wrap; -} -.tabs-wrapper pre { - margin: 1rem 0; - border: 0; - padding: 0; - background: inherit; -} -table { - border: 1px solid #eaeaea; - table-layout: auto; -} -th { - background: #f7f7f7; - padding: 0.5rem; -} -td { - padding: 0.5rem; - border: 1px solid #eaeaea; -} -.button { - background: #9c6fb6; - color: #fff; - box-shadow: 0 3px 0 #00a5d4; -} -.button:hover { - background: #00a5d4; - box-shadow: 0 3px 0 #008db6; - color: #fff; -} -.button:active { - box-shadow: 0 1px 0 #008db6; -} -.button-secondary { - background: #F8B450; - color: #fff; - box-shadow: 0 3px 0 #f7a733; -} -.button-secondary:hover { - background: #f7a733; - box-shadow: 0 3px 0 #f69b15; - color: #fff; -} -.button-secondary:active { - box-shadow: 0 1px 0 #f69b15; -} -.bullets { - margin: 1.7rem 0; - margin-left: -0.85rem; - margin-right: -0.85rem; - overflow: auto; -} -.bullet { - float: left; - padding: 0 0.85rem; -} -.two-column-bullet { - width: 50%; -} -@media only all and (max-width: 47.938em) { - .two-column-bullet { - width: 100%; - } -} -.three-column-bullet { - width: 33.33333%; -} -@media only all and (max-width: 47.938em) { - .three-column-bullet { - width: 100%; - } -} -.four-column-bullet { - width: 25%; -} -@media only all and (max-width: 47.938em) { - .four-column-bullet { - width: 100%; - } -} -.bullet-icon { - float: left; - background: #9c6fb6; - padding: 0.875rem; - width: 3.5rem; - height: 3.5rem; - border-radius: 50%; - color: #fff; - font-size: 1.75rem; - text-align: center; -} -.bullet-icon-1 { - background: #9c6fb6; -} -.bullet-icon-2 { - background: #00f3d8; -} -.bullet-icon-3 { - background: #e6f300; -} -.bullet-content { - margin-left: 4.55rem; -} -.tooltipped { - position: relative; -} -.tooltipped:after { - position: absolute; - z-index: 1000000; - display: none; - padding: 5px 8px; - font: normal normal 11px/1.5 "Work Sans", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif; - color: #fff; - text-align: center; - text-decoration: none; - text-shadow: none; - text-transform: none; - letter-spacing: normal; - word-wrap: break-word; - white-space: pre; - pointer-events: none; - content: attr(aria-label); - background: rgba(0, 0, 0, 0.8); - border-radius: 3px; - -webkit-font-smoothing: subpixel-antialiased; -} -.tooltipped:before { - position: absolute; - z-index: 1000001; - display: none; - width: 0; - height: 0; - color: rgba(0, 0, 0, 0.8); - pointer-events: none; - content: ""; - border: 5px solid transparent; -} -.tooltipped:hover:before, .tooltipped:hover:after, .tooltipped:active:before, .tooltipped:active:after, .tooltipped:focus:before, .tooltipped:focus:after { - display: inline-block; - text-decoration: none; -} -.tooltipped-s:after, .tooltipped-se:after, .tooltipped-sw:after { - top: 100%; - right: 50%; - margin-top: 5px; -} -.tooltipped-s:before, .tooltipped-se:before, .tooltipped-sw:before { - top: auto; - right: 50%; - bottom: -5px; - margin-right: -5px; - border-bottom-color: rgba(0, 0, 0, 0.8); -} -.tooltipped-se:after { - right: auto; - left: 50%; - margin-left: -15px; -} -.tooltipped-sw:after { - margin-right: -15px; -} -.tooltipped-n:after, .tooltipped-ne:after, .tooltipped-nw:after { - right: 50%; - bottom: 100%; - margin-bottom: 5px; -} -.tooltipped-n:before, .tooltipped-ne:before, .tooltipped-nw:before { - top: -5px; - right: 50%; - bottom: auto; - margin-right: -5px; - border-top-color: rgba(0, 0, 0, 0.8); -} -.tooltipped-ne:after { - right: auto; - left: 50%; - margin-left: -15px; -} -.tooltipped-nw:after { - margin-right: -15px; -} -.tooltipped-s:after, .tooltipped-n:after { - transform: translateX(50%); -} -.tooltipped-w:after { - right: 100%; - bottom: 50%; - margin-right: 5px; - transform: translateY(50%); -} -.tooltipped-w:before { - top: 50%; - bottom: 50%; - left: -5px; - margin-top: -5px; - border-left-color: rgba(0, 0, 0, 0.8); -} -.tooltipped-e:after { - bottom: 50%; - left: 100%; - margin-left: 5px; - transform: translateY(50%); -} -.tooltipped-e:before { - top: 50%; - right: -5px; - bottom: 50%; - margin-top: -5px; - border-right-color: rgba(0, 0, 0, 0.8); -} -.highlightable { - padding: 1rem 0 1rem; - overflow: auto; - position: relative; -} -.hljs::selection, .hljs span::selection { - background: #b7b7b7; -} -.lightbox-active #body { - overflow: visible; -} -.lightbox-active #body .padding { - overflow: visible; -} -#github-contrib i { - vertical-align: middle; -} -.featherlight img { - margin: 0 !important; -} -.lifecycle #body-inner ul { - list-style: none; - margin: 0; - padding: 2rem 0 0; - position: relative; -} -.lifecycle #body-inner ol { - margin: 1rem 0 1rem 0; - padding: 2rem; - position: relative; -} -.lifecycle #body-inner ol li { - margin-left: 1rem; -} -.lifecycle #body-inner ol strong, .lifecycle #body-inner ol label, .lifecycle #body-inner ol th { - text-decoration: underline; -} -.lifecycle #body-inner ol ol { - margin-left: -1rem; -} -.lifecycle #body-inner h3[class*='level'] { - font-size: 20px; - position: absolute; - margin: 0; - padding: 4px 10px; - right: 0; - z-index: 1000; - color: #fff; - background: #1ABC9C; -} -.lifecycle #body-inner ol h3 { - margin-top: 1rem !important; - right: 2rem !important; -} -.lifecycle #body-inner .level-1 + ol { - background: #f6fefc; - border: 4px solid #1ABC9C; - color: #16A085; -} -.lifecycle #body-inner .level-1 + ol h3 { - background: #2ECC71; -} -.lifecycle #body-inner .level-2 + ol { - background: #f7fdf9; - border: 4px solid #2ECC71; - color: #27AE60; -} -.lifecycle #body-inner .level-2 + ol h3 { - background: #3498DB; -} -.lifecycle #body-inner .level-3 + ol { - background: #f3f9fd; - border: 4px solid #3498DB; - color: #2980B9; -} -.lifecycle #body-inner .level-3 + ol h3 { - background: #34495E; -} -.lifecycle #body-inner .level-4 + ol { - background: #e4eaf0; - border: 4px solid #34495E; - color: #2C3E50; -} -.lifecycle #body-inner .level-4 + ol h3 { - background: #34495E; -} -#top-bar { - background: #F6F6F6; - border-radius: 2px; - padding: 0 1rem; - height: 0; - min-height: 3rem; -} -#top-github-link { - position: relative; - z-index: 1; - float: right; - display: block; -} -#body #breadcrumbs { - height: auto; - margin-bottom: 0; - padding-left: 0; - line-height: 1.4; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - width: 70%; - display: inline-block; - float: left; -} -#body #breadcrumbs span { - padding: 0 0.1rem; -} -@media only all and (max-width: 59.938em) { - #sidebar { - width: 230px; - } - #body { - margin-left: 230px; - } -} -@media only all and (max-width: 47.938em) { - #sidebar { - width: 230px; - left: -230px; - } - #body { - margin-left: 0; - width: 100%; - } - .sidebar-hidden { - overflow: hidden; - } - .sidebar-hidden #sidebar { - left: 0; - } - .sidebar-hidden #body { - margin-left: 230px; - overflow: hidden; - } - .sidebar-hidden #overlay { - position: absolute; - left: 0; - right: 0; - top: 0; - bottom: 0; - z-index: 10; - background: rgba(255, 255, 255, 0.5); - cursor: pointer; - } -} -.copy-to-clipboard { - background-image: url(../images/clippy.svg); - background-position: 50% 50%; - background-size: 16px 16px; - background-repeat: no-repeat; - width: 27px; - height: 1.45rem; - top: -1px; - display: inline-block; - vertical-align: middle; - position: relative; - color: #5e5e5e; - background-color: #FFF7DD; - margin-left: -.2rem; - cursor: pointer; - border-radius: 0 2px 2px 0; - margin-bottom: 1px; -} -.copy-to-clipboard:hover { - background-color: #E8E2CD; -} -pre .copy-to-clipboard { - position: absolute; - right: 4px; - top: 4px; - background-color: #C1C4C6; - color: #ccc; - border-radius: 2px; -} -pre .copy-to-clipboard:hover { - background-color: #00bdf3; - color: #fff; -} -.parent-element { - -webkit-transform-style: preserve-3d; - -moz-transform-style: preserve-3d; - transform-style: preserve-3d; -} - -#sidebar ul.topics > li > a .read-icon { - margin-top: 9px; -} - -#sidebar ul { - list-style: none; - padding: 0; - margin: 0; -} - -#sidebar #shortcuts li { - padding: 2px 0; - list-style: none; -} - -#sidebar ul li .read-icon { - display: none; - float: right; - font-size: 13px; - min-width: 16px; - margin: 4px 0 0 0; - text-align: right; -} -#sidebar ul li.visited > a .read-icon { - color: #00bdf3; - display: inline; -} - -#sidebar #shortcuts h3 { - font-family: "Novacento Sans Wide", "Helvetica", "Tahoma", "Geneva", "Arial", sans-serif; - color: white ; - margin-top:1rem; - padding-left: 1rem; -} - -#homelinks { - background-color: #9c6fb6; - color: #fff; - padding: 7px 0; - border-bottom: 4px solid #9c6fb6; -} - -#searchResults { - text-align: left; -} - -option { - color: initial; -} - -.fa-github, .fa-twitter, .fa-home, .fa-mastodon { - margin-right: 10px; -} - -.fa-tags { - margin-right: 7px; -} diff --git a/public/development/building/index.html b/public/development/building/index.html deleted file mode 100644 index 6fd0c98..0000000 --- a/public/development/building/index.html +++ /dev/null @@ -1,12 +0,0 @@ -Building Strolch - Strolch

    Building Strolch

    Building Strolch

    Note: You don’t have to build Strolch if you want to use the -version on Maven central. If you need a snapshot version, the release you -want isn’t on Maven central or you want to use the Strolch Maven archetypes, then go ahead and build Strolch.

    Building Strolch is just a few lines:

    git clone https://github.com/strolch-li/strolch.git
    -cd strolch
    -mvn clean install -DskipTests
    -

    Note: To run the tests you will need to configure the PostgreSQL Databases. See -the README in the module.

    After running the Maven build, you will have a full build of all Strolch -modules. Now you can start modifying the modules, and add your own features, -or, far more interesting, start developing your projects using the Strolch -agent.

    \ No newline at end of file diff --git a/public/development/converting-existing/index.html b/public/development/converting-existing/index.html deleted file mode 100644 index ea51eb1..0000000 --- a/public/development/converting-existing/index.html +++ /dev/null @@ -1,5 +0,0 @@ -Converting Existing App - Strolch

    Converting Existing App

    Converting an existing application

    You can convert an existing application to a Strolch agent, but this might be a -bit daunting in the beginning. If you are planning on doing this, first create a -test application using the maven archetypes, so that you can get a feel for the configuration.

    Once that works, use the archetypes configuration to reconfigure your project to start as a Strolch agent.

    Note: Beware to select the archetype pertaining to your use case:

    \ No newline at end of file diff --git a/public/development/index.html b/public/development/index.html deleted file mode 100644 index 58d7c65..0000000 --- a/public/development/index.html +++ /dev/null @@ -1,4 +0,0 @@ -Development - Strolch
    \ No newline at end of file diff --git a/public/development/index.xml b/public/development/index.xml deleted file mode 100644 index 462356b..0000000 --- a/public/development/index.xml +++ /dev/null @@ -1,13 +0,0 @@ -Development on Strolchhttps://strolch.li/development/Recent content in Development on StrolchHugo -- gohugo.ioen-usPrerequisiteshttps://strolch.li/development/prerequisites/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/development/prerequisites/Prerequisites To start developing Strolch you need an installed: -Java JDK 17 Apache Maven 3.x You can install these using the awesome SDKMAN!: -$ curl -s &#34;https://get.sdkman.io&#34; | bash source &#34;$HOME/.sdkman/bin/sdkman-init.sh&#34; sdk version sdk install java sdk install maven sdk install mvnd Test your Java installation: -$ java -version openjdk version &#34;17.0.4&#34; 2022-07-19 OpenJDK Runtime Environment Temurin-17.0.4+8 (build 17.0.4+8) OpenJDK 64-Bit Server VM Temurin-17.0.4+8 (build 17.0.4+8, mixed mode, sharing) Test your Maven installation:Building Strolchhttps://strolch.li/development/building/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/development/building/Building Strolch Note: You don&rsquo;t have to build Strolch if you want to use the version on Maven central. If you need a snapshot version, the release you want isn&rsquo;t on Maven central or you want to use the Strolch Maven archetypes, then go ahead and build Strolch. -Building Strolch is just a few lines: -git clone https://github.com/strolch-li/strolch.git cd strolch mvn clean install -DskipTests Note: To run the tests you will need to configure the PostgreSQL Databases.Maven Archetypeshttps://strolch.li/development/maven-archetypes/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/development/maven-archetypes/Maven Archetypes Maven offers archetypes to generate new projects. Strolch offers the following archetypes, to create new projects: -strolch.mvn.archetype.main for Java main class applications strolch.mvn.archetype.webapp for Java Web based applications using REST and Polymer 1.x as the frontend. strolch.mvn.archetype.plc for Strolch PLC projects. To use the archetypes, clone the archetypes repository and install it locally: -git clone https://github.com/strolch-li/strolch-maven-archetypes.git cd strolch-maven-archetypes git checkout 0.1.0 mvn clean install Then follow one of the next steps to create the type of application you want.Web Apphttps://strolch.li/development/web-app/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/development/web-app/Prerequisites To start developing web-based Strolch apps you need the following: -Apache Tomcat 9.x (10.x isn&rsquo;t supported yet). Just unpack it somewhere, to be used later, when running the application. NodeJS v11.x (other versions don&rsquo;t work with Bower, the installation is described below. Note: Strolch&rsquo;s Web UI is still using Polymer 1.x. This isn&rsquo;t a big concern, as thanks to the polyfills, it works on all browsers, including Internet Explorer 11.Main Class Apphttps://strolch.li/development/main-class-app/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/development/main-class-app/Creating a Strolch App The following shows the maven command to create the new maven project using Strolch&rsquo;s main maven archetype. Note that you should replace the placeholders in the brackets: -Note: you need to have the Strolch Maven archetypes installed to your local maven repo, otherwise the following command will fail. -mvn archetype:generate \ -DarchetypeGroupId=li.strolch \ -DarchetypeArtifactId=strolch.mvn.archetype.main \ -DarchetypeVersion=0.1.0-SNAPSHOT \ -DgroupId=&lt;my.groupid&gt; \ -DartifactId=&lt;my-artifactId&gt; \ -Dversion=&lt;my.Converting Existing Apphttps://strolch.li/development/converting-existing/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/development/converting-existing/Converting an existing application You can convert an existing application to a Strolch agent, but this might be a bit daunting in the beginning. If you are planning on doing this, first create a test application using the maven archetypes, so that you can get a feel for the configuration. -Once that works, use the archetypes configuration to reconfigure your project to start as a Strolch agent. -Note: Beware to select the archetype pertaining to your use case: \ No newline at end of file diff --git a/public/development/main-class-app/index.html b/public/development/main-class-app/index.html deleted file mode 100644 index 6abc39e..0000000 --- a/public/development/main-class-app/index.html +++ /dev/null @@ -1,16 +0,0 @@ -Main Class App - Strolch

    Main Class App

    Creating a Strolch App

    The following shows the maven command to create the new maven project using Strolch’s main maven archetype. Note that -you should replace the placeholders in the brackets:

    Note: you need to have the Strolch Maven archetypes installed to your local maven repo, otherwise the -following command will fail.

    mvn archetype:generate \
    -  -DarchetypeGroupId=li.strolch \
    -  -DarchetypeArtifactId=strolch.mvn.archetype.main \
    -  -DarchetypeVersion=0.1.0-SNAPSHOT \
    -  -DgroupId=<my.groupid> \
    -  -DartifactId=<my-artifactId> \
    -  -Dversion=<my.version> \
    -  -DappName="<my app name>"
    -

    You change into the directory of the new project and then build the project by calling:

    cd <my-artifactId>
    -mvn clean package
    -

    Start the program using:

    mvn exec:java
    -

    Happy coding =))

    \ No newline at end of file diff --git a/public/development/maven-archetypes/index.html b/public/development/maven-archetypes/index.html deleted file mode 100644 index 7631950..0000000 --- a/public/development/maven-archetypes/index.html +++ /dev/null @@ -1,8 +0,0 @@ -Maven Archetypes - Strolch

    Maven Archetypes

    Maven Archetypes

    Maven offers archetypes to generate new projects. Strolch offers the following archetypes, to create new projects:

    To use the archetypes, clone the archetypes repository and install it locally:

    git clone https://github.com/strolch-li/strolch-maven-archetypes.git
    -cd strolch-maven-archetypes
    -git checkout 0.1.0
    -mvn clean install
    -

    Then follow one of the next steps to create the type of application you want.

    \ No newline at end of file diff --git a/public/development/prerequisites/index.html b/public/development/prerequisites/index.html deleted file mode 100644 index 0fea31f..0000000 --- a/public/development/prerequisites/index.html +++ /dev/null @@ -1,20 +0,0 @@ -Prerequisites - Strolch

    Prerequisites

    Prerequisites

    To start developing Strolch you need an installed:

    • Java JDK 17
    • Apache Maven 3.x

    You can install these using the awesome SDKMAN!:

    $ curl -s "https://get.sdkman.io" | bash
    -source "$HOME/.sdkman/bin/sdkman-init.sh"
    -sdk version
    -
    -sdk install java
    -sdk install maven
    -sdk install mvnd
    -

    Test your Java installation:

    $ java -version
    -openjdk version "17.0.4" 2022-07-19
    -OpenJDK Runtime Environment Temurin-17.0.4+8 (build 17.0.4+8)
    -OpenJDK 64-Bit Server VM Temurin-17.0.4+8 (build 17.0.4+8, mixed mode, sharing)
    -

    Test your Maven installation:

    $ mvn --version
    -Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63)
    -Maven home: /home/user/.sdkman/candidates/maven/current
    -Java version: 17.0.4, vendor: Eclipse Adoptium, runtime: /home/user/.sdkman/candidates/java/17.0.4-tem
    -Default locale: en_US, platform encoding: UTF-8
    -OS name: "linux", version: "5.18.11-051811-generic", arch: "amd64", family: "unix"
    -
    \ No newline at end of file diff --git a/public/development/web-app/index.html b/public/development/web-app/index.html deleted file mode 100644 index 8cb64f8..0000000 --- a/public/development/web-app/index.html +++ /dev/null @@ -1,67 +0,0 @@ -Web App - Strolch

    Web App

    Prerequisites

    To start developing web-based Strolch apps you need the following:

    • Apache Tomcat 9.x (10.x isn’t supported yet). Just unpack it somewhere, to be used later, when running the -application.
    • NodeJS v11.x (other versions don’t work with Bower, the installation is described below.

    Note: Strolch’s Web UI is still using -Polymer 1.x. This isn’t a big -concern, as thanks to the polyfills, it works on all browsers, including Internet Explorer 11.

    Install the web dependencies

    The Strolch Web App uses NodeJS v11.x to build the web dependencies. -Please -download the relevant platform’s package, unpack it, and add the bin directory -to your path variable and add a NODE_HOME variable pointing to the root directory of the NodeJS folder.

    Test that NodeJS is working properly:

    $ npm --version
    -6.8.0
    -

    Once NodeJS is installed, then you can prepare the web dependencies:

    npm install -g bower
    -npm install -g gulp
    -

    And then check that both bower and gulp work as expected:

    $ bower --version
    -1.8.14
    -
    -$ gulp --version
    -[17:22:56] CLI version 2.0.1
    -

    Creating a Strolch Web App

    The following shows the maven command to create the new maven project using Strolch’s webapp maven archetype. Note that -you should replace the placeholders in the brackets:

    Note: you need to have the Strolch Maven archetypes installed to your local maven repo, otherwise the -following command will fail.

    mvn archetype:generate \
    -  -DarchetypeGroupId=li.strolch \
    -  -DarchetypeArtifactId=strolch.mvn.archetype.webapp \
    -  -DarchetypeVersion=0.1.0-SNAPSHOT \
    -  -DgroupId=<my.groupid> \
    -  -DartifactId=<my-artifactId> \
    -  -Dversion=<my.version> \
    -  -Dpackage=<my.package> \
    -  -DappName="<my app name>"
    -

    Installing the web dependencies

    In the newly generated artifact, change to the webapp folder, and then run npm install:

    cd <my-artifactId>/src/main/webapp
    -npm install
    -

    This will first install the NodeJS modules, and then call bower to install the bower packages.

    Note: Whenever the bower.json is changed, e.g. updating a version or adding a package, then you -should -again call npm install inside the webapp folder.

    Building and running the WAR locally

    Once the web dependencies are installed, all components are available to finally build the WAR and run it on a servlet -container. The archetype is pre-configured to run using the dev-local Strolch runtime environment configuration. This -can be achieved by compiling using the following command:

    mvn clean package -Prelease -Dstrolch.env=dev.local
    -

    Building the WAR uses the package maven goal, but to have the optimized WAR use the release profile. The environment -variable strolch.env=dev.local configures the WAR to have its runtime point to the absolute path where the sources are -located.

    After the build is complete, the WAR will be located in the target/ directory. Copy it to Tomcat’s webapps/ -directory and then start tomcat with the -following command:

    cd tomcat9/bin
    -./catalina.sh run
    -

    Tomcat should then see the WAR and deploy it. If everything was setup correctly, then you should see the following in -the logs after startup:

    INFO  l.s.a.impl.ComponentContainerImpl:283 start - System: OS: Linux 5.16.15 Arch: amd64 on Java Azul Systems, Inc. 17 CPU Cores: 32
    -INFO  l.s.a.impl.ComponentContainerImpl:284 start - Memory: Memory available 16.8 GB / Used: 604.0 MB / Free: 540.6 MB
    -INFO  l.s.a.impl.ComponentContainerImpl:285 start - Using locale en with timezone Europe/Zurich
    -INFO  l.s.a.impl.ComponentContainerImpl:288 start - file.encoding: UTF-8 / sun.jnu.encoding UTF-8
    -INFO  l.s.a.impl.ComponentContainerImpl:307 start - <my-artifactId>:dev All 12 Strolch Components started. Took 120ms. Strolch is now ready to be used. Have fun =))
    -INFO  li.strolch.test.web.StartupListener:43 contextInitialized - Started <my app name> in 557ms
    -

    And now you can open a browser and login: http://localhost:8080/<my-artifactId>

    The default username and password are admin / admin. After logging in, you should be greeted with the following -screen: -Strolch Demo App

    Running the WAR on a remote system

    The sources currently are configured for the dev.local environment. To use the WAR on a remote system, we need to -configure another environment, and have the path of the runtime updated in the StrolchBootstrap.xml file. Open the -file src/main/resources/StrolchBootstrap.xml and modify the root path in the test environment:

    
    -<env id="test" default="true">
    -    <root>/absolute/path/to/runtime</root>
    -    <environment>test</environment>
    -</env>
    -

    Now you need to copy the existing runtime directory to the remote machine at the above location.

    Now we can build the project using the test environment:

    mvn clean package -Prelease -Dstrolch.env=test
    -

    Now copy the WAR from the target/ directory to the webapps/ directory of your Tomcat 9.x installation. Now you can -start tomcat using:

    catalina.sh run
    -

    In the console you’ll then see something like this:

    INFO  l.s.a.impl.ComponentContainerImpl:283 start - System: OS: Linux 5.16.15 Arch: amd64 on Java Azul Systems, Inc. 17 CPU Cores: 32
    -INFO  l.s.a.impl.ComponentContainerImpl:284 start - Memory: Memory available 16.8 GB / Used: 604.0 MB / Free: 540.6 MB
    -INFO  l.s.a.impl.ComponentContainerImpl:285 start - Using locale en with timezone Europe/Zurich
    -INFO  l.s.a.impl.ComponentContainerImpl:288 start - file.encoding: UTF-8 / sun.jnu.encoding UTF-8
    -INFO  l.s.a.impl.ComponentContainerImpl:307 start - <my-artifactId>:test All 12 Strolch Components started. Took 43ms. Strolch is now ready to be used. Have fun =))
    -INFO  c.atexxi.esytest.web.StartupListener:43 contextInitialized - Started <my app name> in 244ms
    -

    And now you can open a browser and login: http://remove-server:8080/<my-artifactId>

    The default username and password are admin / admin. After logging you, you should see the following view:

    Strolch Demo App

    Happy coding =))

    \ No newline at end of file diff --git a/public/documentation/architecture/index.html b/public/documentation/architecture/index.html deleted file mode 100644 index e85c019..0000000 --- a/public/documentation/architecture/index.html +++ /dev/null @@ -1,19 +0,0 @@ -Architecture - Strolch

    Architecture

    Architecture

    Birds View

    A Strolch agent’s architecture can be seen as a simple three-tier architecture. -The presentation layer is mostly a web frontend, where the communication with -the agent is done via REST API calls.

    The agent itself implements the business logic using Services, Commands, -Queries etc.

    The agent can communicate with other 3rd systems using any API, where it is -preferred to use JSON over REST.

    The agent can use a standard RDBMS as a storage system, where currently DAOs -have been implemented only for PostgreSQL. Should it be required, then any -JDBC cabable RDBMS can be used, as no PostgreSQL specific SQL commands are used.

    The following diagram helps visualize this:

    Strolch Architecture Birds View

    Squirrel View

    The following diagram shows a more detailed view of the architecture of a -Strolch Agent:

    Strolch Architecture Squirrel View

    A Strolch agent consists of the following main parts:

    • REST Endpoints → expose an API to access the Strolch agent outside of the -Java VM
    • Services and Commands → implements business logic
    • Searches → implements specific queries against the Strolch model
    • Components → Implements additional logic, which is best implement as a -component. E.g. active components which have threads, etc.
    • Realms → implements multi-tenant capabilities

    In addition to the main parts, Strolch contains inherit capabilities, which -gives Strolch unique features when compared to other Java Frameworks:

    • Policies → Policies allow injecting different algorithms. All root elements -can store Policy definitions, so that a service can delegate to a Policy and -thus behave differently, depending on the element being accessed.
    • Transactions → Transactions handle locking/unlocking of objects, updating the -model and are the central API for the developer.
    • Privileges → Strolch is user agnostic and any action, i.e. Service, Query, -etc. is authorized against the authenticated user.
    • Observers → modifications to the model are propagated to listeners using the -observer pattern.
    • Audits → Every access (read, modify) of the model are audited
    • Versioning → modifications to objects are versioned and thus can be rolled -back at a later time.
    \ No newline at end of file diff --git a/public/documentation/components/index.html b/public/documentation/components/index.html deleted file mode 100644 index ac55a73..0000000 --- a/public/documentation/components/index.html +++ /dev/null @@ -1,68 +0,0 @@ -Components - Strolch

    Components

    Components

    A Strolch agent can be easily extended with arbitrary components. An agent -is basically a container for classes extending StrolchComponent with a life -cycle. These classes mostly implement an interface which describes the -operations that are supported by the component.

    The following represents a list of the most used components:

    • RealmHandler: li.strolch.agent.impl.DefaultRealmHandler
    • PrivilegeHandler: li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler
    • EnumHandler: li.strolch.runtime.query.enums.DefaultEnumHandler
    • PolicyHandler: li.strolch.policy.DefaultPolicyHandler
    • ServiceHandler: li.strolch.service.api.DefaultServiceHandler
    • StrolchSessionHandler: li.strolch.rest.DefaultStrolchSessionHandler
    • PersistenceHandler: multiple implementations
    • PostInitializer: project specific implementation
    • MailHandler: li.strolch.handler.mail.SmtpMailHandler

    A component has a life-cycle, which is governed by the Agent’s own life-cycle. -The life-cycle is as follows:

    setup -> initialize -> start <-> stop -> destroy
    -

    The setup step is used to instantiate the component, the initialize step is -used to validate configuration parameters, and the run step is used to start -the component, i.e. start threads, etc. The stop step stops these threads and -also allows the component to be started again. The destroy step destroys the -instance and makes it unusable anymore, i.e. shutdown of the agent.

    Each component has its own configuration parameters. A component is -registered in the StrolchConfiguration.xml file with a

    • name
    • api class name
    • implementation class name
    • configuration parameters
    • any required dependencies

    The dependencies is an important feature as the dependencies of a component -are always started before the actual component.

    Example Component implementation and configuration

    By example of the MailHandler we shall show how a strolch component would -be implemented.

    First define an interface:

    public interface MailHandler {
    -    void sendMail(String subject, String text, String recipient);
    -}
    -

    Then implement a concrete MailHandler:

    public class SmtpMailHandler extends StrolchComponent implements MailHandler {
    -
    -  // TODO instance fields with configuration properties to send the mail
    -
    -  public SmtpMailHandler(ComponentContainer container, String componentName) {
    -    super(container, componentName);
    -  }
    -
    -  @Override
    -  public void initialize(ComponentConfiguration configuration) throws Exception {
    -
    -    // TODO store any properties needed from the configuration
    -
    -    super.initialize(configuration);
    -  }
    -
    -  @Override
    -  public void sendMail(String subject, String text, String recipient) {
    -
    -    // TODO send the e-mail using SMTP, or send asynchronously
    -  }
    -}
    -

    Now that the component is written, it must be registered on the component, so -that it is loaded when the agent is started. For this the -StrolchConfiguration.xml file must be modified to include a component -element:

    <StrolchConfiguration>
    -  <env id="dev">
    -    ...
    -    <Component>
    -      <name>MailHandler</name>
    -      <api>li.strolch.handler.mail.MailHandler</api>
    -      <impl>li.strolch.handler.mail.SmtpMailHandler</impl>
    -      <Properties>
    -        <username>test</username>
    -        <password>test</password>
    -        <hostName>localhost</hostName>
    -        ...
    -      </Properties>
    -    </Component>
    -    ...
    -  </env>
    -</StrolchConfiguration>
    -

    Now when the agent is started, the component can be retrieved and used. -E.g from inside a Service:

    public class MyService extends AbstractService<ServiceArgument, ServiceResult> {
    -	@Override
    -	protected ServiceResult internalDoService(ServiceArgument arg) throws Exception {
    -		MailHandler mailHandler = getComponent(MailHandler.class);
    -		mailHandler.sendMail("My Subject", "Hello World", "test@test.ch");
    -    }
    -}
    -
    \ No newline at end of file diff --git a/public/documentation/do-and-donts/index.html b/public/documentation/do-and-donts/index.html deleted file mode 100644 index fe9bef4..0000000 --- a/public/documentation/do-and-donts/index.html +++ /dev/null @@ -1,3 +0,0 @@ -Do and Don't - Strolch

    Do and Don't

    This page discusses things you should and shouldn’t do when using Strolch

    The following is a simple list of do’s and don’ts:

    • 1 Service per use-case, should mostly delegate to Commands.

    • Commands implement use-cases or parts of it, and are thus reusable.

    • Subclass ResourceSearch, OrderSearch and ActivitySearch when implementing use-case specific search - this allows privilege checking.

    • One Transaction at a time - no TX inside of another TX.

    • Commands are added to TXs and performed on close: tx.addCommand(Command) and then tx.commitOnClose()

    • Only access ElementMaps if really no other way, mostly use tx.get*By(), tx.findBy() and searches - if a specific get is missing, then add the method to StrolchTransaction and send a pull request!

    • Use tx.stream*() methods to iterate over all elements, if you don’t want to use a search.

    • Don’t write logic in REST API beans. Delegate to other services, making your code reusable!

    • Marshall to JSON using the StrolchElementToJsonVisitor.

    • Unmarshall JSON using FromFlatJsonVisitor or if needed StrolchElementFromJsonVisitor

    • References between objects is done by adding a ParameterBag with the id relations to the object and then StringParameters with the value being the ID, the UOM set to the type of element being referenced and the Interpretation set to the class type being referenced.

    • Very seldom and sparingly use tx.flush() if you need to perform first some work and then as late as possible call tx.commitOnClose()

      The flush()-method flushes everything, i.e. rollback isn’t possible anymore.

    \ No newline at end of file diff --git a/public/documentation/index.html b/public/documentation/index.html deleted file mode 100644 index af25670..0000000 --- a/public/documentation/index.html +++ /dev/null @@ -1,6 +0,0 @@ -Documentation - Strolch

    Documentation

    Overview

    Strolch’s documentation has only just begun, but as more and more details of -the implementation in Strolch are fixed, more documentation can be created and -will be available here.

    Currently, we have the following topics of discussion:

    \ No newline at end of file diff --git a/public/documentation/index.xml b/public/documentation/index.xml deleted file mode 100644 index 17d5329..0000000 --- a/public/documentation/index.xml +++ /dev/null @@ -1,28 +0,0 @@ -Documentation on Strolchhttps://strolch.li/documentation/Recent content in Documentation on StrolchHugo -- gohugo.ioen-usArchitecturehttps://strolch.li/documentation/architecture/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/architecture/Architecture Birds View A Strolch agent&rsquo;s architecture can be seen as a simple three-tier architecture. The presentation layer is mostly a web frontend, where the communication with the agent is done via REST API calls. -The agent itself implements the business logic using Services, Commands, Queries etc. -The agent can communicate with other 3rd systems using any API, where it is preferred to use JSON over REST. -The agent can use a standard RDBMS as a storage system, where currently DAOs have been implemented only for PostgreSQL.Modelhttps://strolch.li/documentation/model/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/model/Model Before we dive into the entire model, let&rsquo;s show an example and how it would be modelled in Strolch and use in Strolch: -The model has four entities, which will be modelled using 3 Resources and 1 Order object. The objects have numerous fields and the following relationships: -Bidirectional between Article &lt;-&gt; Product Unidirectional from Order -&gt; Article Unidirectional from Order -&gt; Customer A possible model would look as follows:Do and Don'thttps://strolch.li/documentation/do-and-donts/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/do-and-donts/This page discusses things you should and shouldn&rsquo;t do when using Strolch The following is a simple list of do&rsquo;s and don&rsquo;ts: -1 Service per use-case, should mostly delegate to Commands. -Commands implement use-cases or parts of it, and are thus reusable. -Subclass ResourceSearch, OrderSearch and ActivitySearch when implementing use-case specific search - this allows privilege checking. -One Transaction at a time - no TX inside of another TX.Runtime Configurationhttps://strolch.li/documentation/runtime-configuration/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/runtime-configuration/Runtime Configuration A Strolch runtime configuration comprises two parts: a configuration part, and a model part. The configuration are files located in the ..config/ folder, and the model are files located in the ../data folder. -In an absolute minimal configuration, the Strolch runtime requires the following folder structure: -../config/ ../StrolchConfiguration.xml → configures the Strolch agent ../PrivilegeConfig.xml → configures user management ../PrivilegeUsers.xml → contains the users in an XML based user management file .Realmshttps://strolch.li/documentation/realms/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/realms/Realms Realms implement multi-tenant capabilities. A Strolch agent can have an arbitrary number of realms configured and each realm has its own persistence configuration, allowing to separate mandates completely. -A realm can run in one of the following modes: -EMPTY This is a transient data store mode, where no model changes are persisted - they are only kept in memory. When the Strolch agent is started, this realm is empty as no data is loaded.Componentshttps://strolch.li/documentation/components/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/components/Components A Strolch agent can be easily extended with arbitrary components. An agent is basically a container for classes extending StrolchComponent with a life cycle. These classes mostly implement an interface which describes the operations that are supported by the component. -The following represents a list of the most used components: -RealmHandler: li.strolch.agent.impl.DefaultRealmHandler PrivilegeHandler: li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler EnumHandler: li.strolch.runtime.query.enums.DefaultEnumHandler PolicyHandler: li.strolch.policy.DefaultPolicyHandler ServiceHandler: li.strolch.service.api.DefaultServiceHandler StrolchSessionHandler: li.strolch.rest.DefaultStrolchSessionHandler PersistenceHandler: multiple implementations PostInitializer: project specific implementation MailHandler: li.Services and Commandshttps://strolch.li/documentation/services-and-commands/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/services-and-commands/Services and Commands Services are written to implement a specific use-case. Commands are written to implement re-usable parts of a use-case. The use-case can be abstract e.g., AddResourceService or very specific e.g. CreatePatientService. -Should the use-case be re-usable in different scenarios, then commands should implement the logic, and the services should then execute the commands. E.g. The CreatePatientService would use a CreatePatientResourceCommand and then use an AddResourceCommand in a single transaction, so that the task of creating the actual Patient Resource can be re-used somewhere else.Searcheshttps://strolch.li/documentation/searches/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/searches/Searches As is custom for every framework, querying, or searching, the model must be possible. Strolch searches are implemented using the StrolchSearch class and one of its concrete implementations: ResourceSearch, OrderSearch, ActivitySearch. -A Strolch element always has two identifiers: Type and Id. The type is important as it classifies an element. So if a car and a house would be modelled in Strolch, then those would both be a Resource, but one of type Car and the other of type House.Querieshttps://strolch.li/documentation/queries/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/queries/Queries The Query API is deprecated and the search API should be used instead. -As is custom for every framework, querying the model must be possible. Strolch queries are implemented using the StrolchQuery interface and one of its concrete implementations: ResourceQuery, OrderQuery, ActivityQuery. -A Strolch element always has two identifiers: Type and Id. The type is important as it classifies an element. So if a car and a house would be modelled in Strolch, then those would both be a Resource, but one of type Car and the other of type House.Transactionshttps://strolch.li/documentation/transactions/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/transactions/Transactions Strolch Transactions play a central role in a Strolch agent. A transaction is opened for a realm, and grants access to the model of the agent. Transactions are implemented as a Java try-with-resources by implementing the AutoCloseable interface. This makes it trivial to understand the scope of a transaction. -Transactions handle the following: -Opening and closing database connections Releasing locks to strolch elements, if tx.lock(StrolchRootElement) or tx.lock(Locator) was called Performing Commands by executing them in the added order, and validating them first.Policieshttps://strolch.li/documentation/policies/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/policies/Policies Policies are an integral part when writing business logic in Strolch. In many cases it would suffice to write all such logic in Services and Commands, but as soon as behaviour can change, depending on the element being accessed, then this would quickly lead to many if/else blocks. -Since writing large if/else blocks is not maintanable in the long run, Strolch offers a different approach. All Strolch elements can store Policy definitions.Observershttps://strolch.li/documentation/observers/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/observers/Observers All changes done in a Strolch transaction are recorded and then propagated to any registered observers. -The observer feature is opt-in and is configured for each realm. In the StrolchConfiguration.xml file enable observers by adding the enableObserverUpdates property per realm: -&lt;StrolchConfiguration&gt; &lt;env id=&#34;dev&#34;&gt; ... &lt;Component&gt; &lt;name&gt;RealmHandler&lt;/name&gt; &lt;api&gt;li.strolch.agent.api.RealmHandler&lt;/api&gt; &lt;impl&gt;li.strolch.agent.impl.DefaultRealmHandler&lt;/impl&gt; &lt;depends&gt;PrivilegeHandler&lt;/depends&gt; &lt;Properties&gt; &lt;realms&gt;defaultRealm, otherRealm&lt;/realms&gt; &lt;enableObserverUpdates&gt;true&lt;/enableObserverUpdates&gt; &lt;dataStoreMode&gt;TRANSIENT&lt;/dataStoreMode&gt; &lt;dataStoreFile&gt;StrolchModel.xml&lt;/dataStoreFile&gt; &lt;enableObserverUpdates.otherRealm&gt;true&lt;/enableObserverUpdates.otherRealm&gt; &lt;dataStoreMode.otherRealm&gt;TRANSIENT&lt;/dataStoreMode.otherRealm&gt; &lt;dataStoreFile.otherRealm&gt;StrolchModel.xml&lt;/dataStoreFile.otherRealm&gt; &lt;/Properties&gt; &lt;/Component&gt; &lt;/env&gt; ... &lt;/StrolchConfiguration&gt; Registering for updates is done by registering an Observer on the ObserverHandler of the realm itself:Versioninghttps://strolch.li/documentation/versioning/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/versioning/Versioning One of Strolch&rsquo;s features that sets it apart from other frameworks, is that versioning is baked into Strolch&rsquo;s fabric. The feature is opt-in, as it is not required in all projects, but it only needs enabling, for all modifications to objects to be versioned, so that rollbacks can be done when needed. -The feature is enabled for each realm. In the StrolchConfiguration.xml file enable it by adding the enableVersioning propery per realm:Reportshttps://strolch.li/documentation/reports/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/reports/Reports Since Strolch has a generic model, it was rather straight forward to create a simple API for writing reports. In Strolch a report is defined by using its own model, i.e. a Report is a Resource of type Report. -A report consists of the following parts: -policy definition, thus allowing extensions basic configuration like base object type, order direction, etc. column definitions joins ordering definition filters An example of a report is as follows:Privilegeshttps://strolch.li/documentation/priviles/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/priviles/Privileges No framework is complete without user management and privilege validation. The basic form would be Users and Roles, and then validating that an authenticated user has a given role. In Strolch we go a step further: A User has roles assigned, and each role has a set of Privileges. The privileges can overlap, a validation is performed to make sure that the one role doesn&rsquo;t deny and another role allows a specific action. \ No newline at end of file diff --git a/public/documentation/model/index.html b/public/documentation/model/index.html deleted file mode 100644 index 985d8ca..0000000 --- a/public/documentation/model/index.html +++ /dev/null @@ -1,287 +0,0 @@ -Model - Strolch

    Model

    Model

    Before we dive into the entire model, let’s show an example and how it would -be modelled in Strolch and use in Strolch:

    Strolch model example

    The model has four entities, which will be modelled using 3 Resources and 1 Order object. The objects have numerous fields and the following relationships:

    • Bidirectional between Article <-> Product
    • Unidirectional from Order -> Article
    • Unidirectional from Order -> Customer

    A possible model would look as follows:

    <?xml version="1.0" encoding="UTF-8" ?>
    -<StrolchModel xmlns="https://strolch.li/xsd/StrolchModel-1.6.xsd">
    -
    -    <Resource Id="Product" Name="Product Template" Type="Template">
    -        <ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
    -            <Parameter Id="description" Name="Description" Type="String" Value=""/>
    -            <Parameter Id="color" Name="Color" Type="String" Value=""/>
    -            <Parameter Id="form" Name="Form" Type="String" Value=""/>
    -        </ParameterBag>
    -        <ParameterBag Id="relations" Name="Relations" Type="Relations">
    -            <Parameter Id="articles" Name="Articles" Type="StringList" Interpretation="Resource-Ref" Uom="Article" Value=""/>
    -        </ParameterBag>
    -    </Resource>
    -
    -    <Resource Id="Article" Name="Article Template" Type="Template">
    -        <ParameterBag Id="parameters" Name="Parameters" Type="Parameters">
    -            <Parameter Id="description" Name="Description" Type="String" Value=""/>
    -            <Parameter Id="barcode" Name="Barcode" Type="String" Value=""/>
    -        </ParameterBag>
    -        <ParameterBag Id="relations" Name="Relations" Type="Relations">
    -            <Parameter Id="product" Name="Product" Type="String" Interpretation="Resource-Ref" Uom="Product" Value=""/>
    -        </ParameterBag>
    -    </Resource>
    -
    -    <Resource Id="Customer" Name="Customer Template" Type="Template">
    -        <ParameterBag Id="address" Name="Address" Type="Address">
    -            <Parameter Id="street" Name="Street" Type="String" Value=""/>
    -            <Parameter Id="zip" Name="Zip" Type="String" Value=""/>
    -            <Parameter Id="city" Name="City" Type="String" Value=""/>
    -            <Parameter Id="country" Name="Country" Type="String" Value=""/>
    -        </ParameterBag>
    -    </Resource>
    -
    -    <Order Id="Order" Name="Order" Type="Template">
    -        <ParameterBag Id="quantities" Name="Quantities per Article Id" Type="Quantities">
    -            <Parameter Id="quantity" Name="Quantity" Type="Float" Value="0"/>
    -        </ParameterBag>
    -        <ParameterBag Id="relations" Name="Relations" Type="Relations">
    -            <Parameter Id="articles" Name="Articles" Type="StringList" Interpretation="Resource-Ref" Uom="Article" Value=""/>
    -            <Parameter Id="customer" Name="Customer" Type="String" Interpretation="Resource-Ref" Uom="Customer" Value=""/>
    -        </ParameterBag>
    -    </Order>
    -
    -</StrolchModel>
    -

    Let’s go through this model:

    • In the above model we see that the id and name fields are always on the -element, and thus aren’t added as parameters. Further best practice is to use -a parameters ParameterBag, with one or more parameters, modelling the -fields. There is API support to not have to always type the parameters bag -id.
    • Note that in this example the Type of all the elements is Template. Strolch -has API support to create a clone of these elements, so that they have a -unique id, and the proper type for persistence.
    • The Product element has three parameters: description, color and form. In this -case they are all of type String. Further the relations ParameterBag defines -the relationships, i.e. the product knows its articles. Note how the relation -is first defined in a relations ParameterBag and that the Parameter has -Interpretation="Resource-Ref" Uom="Product" attributes. Strolch has API -support for this, making it trivial to retrieve a dependency.
    • The Article element has two parameters description and barcode. Further it has -a reference to its Product.
    • The Order element doesn’t model the date and state fields as parameters, as -these are inherently part of an Order element. The Order does define two -references to customer and articles. A special case is the quantities -ParameterBag. This bag of parameters is used to store the per article quantity -for this order. With ParameterBags, you can eliminate the use of simple -aggregate classes, as is commonly used in object-oriented programming.
    • The Customer element models an address ParameterBag to store the address of a -customer. Using a separate bag allows for further more direct fields to stored -on the default parameters bag.

    Now that we have a basic understanding of te model, it is of far more interest -in how to create and interact with these elements at runtime. The following -listing will perform simple operations:

    public class Example {
    -  public static void main(String[] args) {
    -
    -    // keep IDs for later use
    -    String dafalganId;
    -    String dafalgan1Id;
    -    String dafalgan2Id;
    -    String customerId;
    -    String orderId;
    -
    -    // first transaction to create the data
    -    try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, false)) {
    -
    -      /*
    -       * create a new product
    -       */
    -      Resource dafalgan = tx.getResourceTemplate("Product", true);
    -      dafalgan.setName("Dafalgan 100mg");
    -      dafalgan.setString("description", "Dafalgan is for pain.");
    -      dafalgan.setString("color", "Yellow");
    -      dafalgan.setString("form", "flat");
    -
    -      /*
    -       * create articles
    -       */
    -      Resource dafalgan1 = tx.getResourceTemplate("Article", true);
    -      dafalgan1.setName("Dafalgan 100mg 10 pce");
    -      dafalgan1.setString("description", "This is pack with 10 pieces.");
    -      dafalgan1.setString("barcode", "654654");
    -
    -      Resource dafalgan2 = tx.getResourceTemplate("Article", true);
    -      dafalgan2.setName("Dafalgan 100mg 20 pce");
    -      dafalgan2.setString("description", "This is pack with 20 pieces.");
    -      dafalgan2.setString("barcode", "654655");
    -
    -      /*
    -       * add reference to product
    -       */
    -      dafalgan1.setRelation("product", dafalgan);
    -      dafalgan2.setRelation("product", dafalgan);
    -
    -      dafalgan.addRelation("articles", dafalgan1);
    -      dafalgan.addRelation("articles", dafalgan2);
    -
    -      /*
    -       * create a new customer
    -       */
    -      Resource customer1 = tx.getResourceTemplate("Customer", true);
    -      customer1.setName("John Doe");
    -
    -      // set address
    -      ParameterBag addressBag = customer1.getParameterBag("address", true);
    -      addressBag.setString("street", "Main Str. 1");
    -      addressBag.setString("zip", "1234");
    -      addressBag.setString("city", "Hometown");
    -      addressBag.setString("country", "Switzerland");
    -
    -      /*
    -       * create a new order
    -       */
    -      Order order = tx.getOrderTemplate("Order", true);
    -      order.setName("Order for " + customer1.getName());
    -      order.setDate(LocalDate.of(2021, 2, 1));
    -      order.setState(State.PLANNED);
    -
    -      // store reference to customer
    -      order.setRelation("customer", customer1);
    -
    -      StringListParameter orderArticlesP = order.getRelationsParam("articles", true);
    -      ParameterBag quantitiesBag = order.getParameterBag("quantities", true);
    -      FloatParameter quantityT = quantitiesBag.removeParameter("quantity");
    -
    -      // order quantity of 20 for Dafalgan 1
    -      quantitiesBag.setDouble(dafalgan1.getId(), 20);
    -      order.addRelation("articles", dafalgan1);
    -
    -      // set order quantity of 10 for Dafalgan 2
    -      quantitiesBag.setDouble(dafalgan2.getId(), 20);
    -      order.addRelation("articles", dafalgan2);
    -
    -      // keep IDs for later use
    -      dafalganId = dafalgan.getId();
    -      dafalgan1Id = dafalgan1.getId();
    -      dafalgan2Id = dafalgan2.getId();
    -      customerId = customer1.getId();
    -      orderId = order.getId();
    -
    -      /*
    -       * persist
    -       */
    -      tx.add(dafalgan);
    -      tx.add(dafalgan1);
    -      tx.add(dafalgan2);
    -      tx.add(customer1);
    -      tx.add(order);
    -
    -      // commit
    -      tx.commitOnClose();
    -    }
    -  }
    -}
    -
    class Scratch {
    -  public static void main(String[] args) {
    -
    -    // keep IDs for later use
    -    String dafalganId;
    -    String dafalgan1Id;
    -    String dafalgan2Id;
    -    String customerId;
    -    String orderId;
    -    
    -    //
    -    // .. snip ...
    -    // 
    -
    -    // second transaction to query the data
    -    try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true)) {
    -
    -      // get order
    -      Order order = tx.getOrderBy("Order", orderId, true);
    -      assertEquals("Order for John Doe", order.getName());
    -
    -      // get customer
    -      Resource customer = tx.getResourceByRelation(order, "customer", true);
    -      assertEquals("John Doe", customer.getName());
    -
    -      // get articles
    -      List<Resource> articles = tx.getResourcesByRelation(order, "articles", true);
    -      assertEquals(2, articles.size());
    -
    -      // get products by stream
    -      List<Resource> products = articles.stream().map(a -> tx.getResourceByRelation(a, "product", true))
    -              .distinct().collect(Collectors.toList());
    -      assertEquals(1, products.size());
    -
    -      // search for all orders in state PLANNED and with customer
    -      List<Order> orders = new OrderSearch().types("Order").stateIsIn(State.PLANNED)
    -              .where(ExpressionsSupport.relationParam("customer").isEqualTo(customerId)).search(tx).toList();
    -      assertEquals(1, orders.size());
    -    }
    -  }
    -}
    -

    Note: Checkout example-model.xml and SimpleModelTest.java for these examples.

    There is an XML Schema which defines the model in XML: StrolchModel-1.6.xsd

    Here is an example of all the possible elements in Strolch:

    <StrolchModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    -xmlns="https://strolch.li/xsd/StrolchModel-1.6.xsd"
    -xsi:schemaLocation="https://strolch.li/xsd/StrolchModel-1.6.xsd StrolchModel-1.6.xsd">
    -
    -  <IncludeFile file="Include1.xml"/>
    -
    -  <Order Id="@test1" Name="Test Order" Type="Order">
    -    <Version Version="0" CreatedBy="test" Created="2012-11-30T18:12:05.628+01:00" UpdatedBy="test" Updated="2012-11-30T18:12:05.628+01:00" Deleted="false"/>
    -    <ParameterBag Id="@bag01" Name="Test Bag" Type="TestBag">
    -      <Parameter Id="@param1" Name="Boolean Param" Type="Boolean" Value="true"/>
    -    </ParameterBag>
    -    <ParameterBag Id="@bag01" Name="Test Bag" Type="TestBag">
    -      <Parameter Id="@param1" Name="Boolean Param" Type="Boolean" Value="true"/>
    -    </ParameterBag>
    -    <Policies>
    -      <Policy Type="PlanningPolicy" Value="key:SimplePlanning"/>
    -      <Policy Type="ConfirmationPolicy" Value="key:NoConfirmation"/>
    -    </Policies>
    -  </Order>
    -
    -  <Resource Id="MyTestResource" Name="Test Name" Type="TestType">
    -    <Version Version="0" CreatedBy="test" Created="2012-11-30T18:12:05.628+01:00" UpdatedBy="test" Updated="2012-11-30T18:12:05.628+01:00" Deleted="false"/>
    -    <ParameterBag Id="@bag01" Name="Test Bag 01" Type="TestBag">
    -      <Parameter Id="@param1" Name="Boolean Param" Type="Boolean" Value="true"/>
    -    </ParameterBag>
    -    <ParameterBag Id="@bag02" Name="Test Bag 02" Type="TestBag">
    -      <Parameter Id="@param1" Name="Boolean Param" Type="Boolean" Value="true"/>
    -    </ParameterBag>
    -    <TimedState Id="@booleanState" Name="Boolean State" Type="Boolean">
    -      <Value Time="1970-01-01T00:02:00.000+01:00" Value="false"/>
    -    </TimedState>
    -    <Policies>
    -      <Policy Type="PlanningPolicy" Value="key:SimplePlanning"/>
    -      <Policy Type="ConfirmationPolicy" Value="key:NoConfirmation"/>
    -    </Policies>
    -  </Resource>
    -
    -  <Activity Id="activity_1" Name="Activity" Type="parentType" TimeOrdering="Series">
    -    <Version Version="0" CreatedBy="test" Created="2012-11-30T18:12:05.628+01:00" UpdatedBy="test" Updated="2012-11-30T18:12:05.628+01:00" Deleted="false"/>
    -    <ParameterBag Id="@bag01" Name="Test Bag" Type="TestBag">
    -      <Parameter Id="@param1" Name="Boolean Param" Type="Boolean" Value="true"/>
    -    </ParameterBag>
    -    <Policies>
    -      <Policy Type="PlanningPolicy" Value="key:SimplePlanning"/>
    -      <Policy Type="ConfirmationPolicy" Value="key:NoConfirmation"/>
    -    </Policies>
    -    <Action Id="action_1" Name="Action 1" ResourceId="dummyId" ResourceType="dummyType" State="Created" Type="Use">
    -      <ParameterBag Id="@bag01" Name="Test Bag" Type="TestBag">
    -        <Parameter Id="@param1" Name="Boolean Param" Type="Boolean" Value="true"/>
    -      </ParameterBag>
    -      <Policies>
    -        <Policy Type="PlanningPolicy" Value="key:SimplePlanning"/>
    -        <Policy Type="ConfirmationPolicy" Value="key:NoConfirmation"/>
    -      </Policies>
    -      <ValueChange StateId="dummyId" Time="2012-11-30T18:12:05.628+01:00" Value="5" Type="Integer"/>
    -      <ValueChange StateId="dummyId" Time="2012-11-30T18:12:06.628+01:00" Value="6" Type="Integer"/>
    -    </Action>
    -    <Activity Id="child_activity" Name="Child Activity" Type="childType" TimeOrdering="Series">
    -      <ParameterBag Id="@bag01" Name="Test Bag" Type="TestBag">
    -        <Parameter Id="@param1" Name="Boolean Param" Type="Boolean" Value="true"/>
    -      </ParameterBag>
    -      <Policies>
    -        <Policy Type="PlanningPolicy" Value="key:SimplePlanning"/>
    -        <Policy Type="ConfirmationPolicy" Value="key:NoConfirmation"/>
    -      </Policies>
    -      <Action Id="action_2" Name="Action 2" ResourceId="dummyId" ResourceType="dummyType" State="Planned"
    -          Type="Use">
    -        <ValueChange StateId="dummyId" Time="2012-11-30T18:12:05.628+01:00" Value="5" Type="Integer"/>
    -        <ValueChange StateId="dummyId" Time="2012-11-30T18:12:06.628+01:00" Value="6" Type="Integer"/>
    -      </Action>
    -      <Action Id="action_3" Name="Action 3" ResourceId="dummyId" ResourceType="dummyType" State="Created"
    -          Type="Use"/>
    -    </Activity>
    -  </Activity>
    -
    -</StrolchModel>
    -
    \ No newline at end of file diff --git a/public/documentation/observers/index.html b/public/documentation/observers/index.html deleted file mode 100644 index 4bb41d4..0000000 --- a/public/documentation/observers/index.html +++ /dev/null @@ -1,52 +0,0 @@ -Observers - Strolch

    Observers

    Observers

    All changes done in a Strolch transaction are recorded and then propagated to -any registered observers.

    The observer feature is opt-in and is configured for each realm. In the -StrolchConfiguration.xml file enable observers by adding the -enableObserverUpdates property per realm:

    <StrolchConfiguration>
    -  <env id="dev">
    -    ...
    -    <Component>
    -      <name>RealmHandler</name>
    -      <api>li.strolch.agent.api.RealmHandler</api>
    -      <impl>li.strolch.agent.impl.DefaultRealmHandler</impl>
    -      <depends>PrivilegeHandler</depends>
    -      <Properties>
    -        <realms>defaultRealm, otherRealm</realms>
    -        <enableObserverUpdates>true</enableObserverUpdates>
    -        <dataStoreMode>TRANSIENT</dataStoreMode>
    -        <dataStoreFile>StrolchModel.xml</dataStoreFile>
    -        <enableObserverUpdates.otherRealm>true</enableObserverUpdates.otherRealm>
    -        <dataStoreMode.otherRealm>TRANSIENT</dataStoreMode.otherRealm>
    -        <dataStoreFile.otherRealm>StrolchModel.xml</dataStoreFile.otherRealm>
    -      </Properties>
    -    </Component>
    -  </env>
    -  ...
    -</StrolchConfiguration>
    -

    Registering for updates is done by registering an Observer on the -ObserverHandler of the realm itself:

    public class Example {
    -	public static void main(String[] args) {
    -
    -		ObserverHandler observerHandler = container
    -				.getRealm(StrolchConstants.DEFAULT_REALM).getObserverHandler();
    -		observerHandler.registerObserver(Tags.RESOURCE, new Observer() {
    -
    -			@Override
    -			public void update(String key, List<StrolchRootElement> elements) {
    -				logger.info(elements.size() + " resources were updated!");
    -			}
    -
    -			@Override
    -			public void remove(String key, List<StrolchRootElement> elements) {
    -				logger.info(elements.size() + " resources were removed!");
    -			}
    -
    -			@Override
    -			public void add(String key, List<StrolchRootElement> elements) {
    -				logger.info(elements.size() + " resources were added!");
    -			}
    -		});
    -	}
    -}
    -
    \ No newline at end of file diff --git a/public/documentation/policies/index.html b/public/documentation/policies/index.html deleted file mode 100644 index 461b61f..0000000 --- a/public/documentation/policies/index.html +++ /dev/null @@ -1,70 +0,0 @@ -Policies - Strolch

    Policies

    Policies

    Policies are an integral part when writing business logic in Strolch. In many -cases it would suffice to write all such logic in Services and Commands, but -as soon as behaviour can change, depending on the element being accessed, then -this would quickly lead to many if/else blocks.

    Since writing large if/else blocks is not maintanable in the long run, Strolch -offers a different approach. All Strolch elements can store Policy definitions. -This is a simple key/value store where the key defines the type of policy, and -the value references the policy to use.

    Currently there are two ways to reference a policy in Strolch, either via a key -which defines a further lookup in the PolicyHandler, or directly as the name -of the class to instantiate.

    Using policies in Strolch gives the additional possibility of easily changing -the behaviour at runtime, as a Service and/or Command would delegate the -behaviour to the currently configured policy on the releveant element.

    Policies are implemented by defining an abstract class and extends -StrolchPolicy. This abstract class then defines the API of the actual policy. A -concrete class then extends this abstract class and implements the concrete -methods.

    Policies are registered on Resources, Orders, Activities and Actions. The -following shows defining two policies on a Resource, a PlanningPolicy, an -ExecutionPolicy in XML:

    <Resource Id="myResource" Name="My Resource" Type="MyType">
    -  ...
    -  <Policies>
    -    <Policy Type="PlanningPolicy" Value="key:SimplePlanning" />
    -    <Policy Type="ExecutionPolicy" Value="java:li.strolch.policytest.TestSimulatedExecutionPolicy" />
    -  </Policies>
    -</Resource>
    -

    Note how the PlanningPolicy has a value of key:SimplePlanning -and the ExecutionPolicy defines a reference to an actual class.

    To use the PolicyHandler, it must be configured in the StrolchConfiguration.xml -as follows:

    <StrolchConfiguration>
    -    <env id="dev">
    -        <Component>
    -            <name>PolicyHandler</name>
    -            <api>li.strolch.policy.PolicyHandler</api>
    -            <impl>li.strolch.policy.DefaultPolicyHandler</impl>
    -            <Properties>
    -                <readPolicyFile>true</readPolicyFile>
    -                <policyConfigFile>StrolchPolicies.xml</policyConfigFile>
    -            </Properties>
    -        </Component>
    -    </env>
    -</StrolchConfiguration>
    -

    And this policy handler implementation requires a file where the lookups for the -policies is defined, e.g.:

    <StrolchPolicies>
    -    <PolicyType Type="PlanningPolicy" Api="li.strolch.policytest.TestPlanningPolicy">
    -        <Policy Key="SimplePlanning" Class="li.strolch.policytest.TestSimplePlanningPolicy"/>
    -    </PolicyType>
    -    <PolicyType Type="ExecutionPolicy" Api="li.strolch.execution.policy.ExecutionPolicy">
    -        <Policy Key="SimulatedExecution" Class="li.strolch.execution.policy.RandomDurationExecution"/>
    -    </PolicyType>
    -    <PolicyType Type="ConfirmationPolicy" Api="li.strolch.policytest.TestConfirmationPolicy">
    -        <Policy Key="NoConfirmation" Class="li.strolch.policytest.TestNoConfirmationPolicy"/>
    -    </PolicyType>
    -</StrolchPolicies>
    -

    Now at runtime we can access the policies:

    public class MyService extends AbstractService<ServiceArgument, ServiceResult> {
    -	@Override
    -	protected ServiceResult internalDoService(ServiceArgument arg) throws Exception {
    -		try (StrolchTransaction tx = openArgOrUserTx(arg)) {
    -			Resource res = tx.getResourceBy("MyType", "myTestResource");
    -
    -			PlanningPolicy planningPolicy = tx.getPolicy(res, PlanningPolicy.class);
    -			planningPolicy.plan(...);
    -
    -			ExecutionPolicy executionPolicy = tx.getPolicy(res, ExecutionPolicy.class);
    -			executionPolicy.toExecution(...);
    -
    -			tx.commitOnClose();
    -		}
    -
    -		return ServiceResult.success();
    -	}
    -}
    -
    \ No newline at end of file diff --git a/public/documentation/priviles/index.html b/public/documentation/priviles/index.html deleted file mode 100644 index 2a55130..0000000 --- a/public/documentation/priviles/index.html +++ /dev/null @@ -1,73 +0,0 @@ -Privileges - Strolch

    Privileges

    Privileges

    No framework is complete without user management and privilege validation. The -basic form would be Users and Roles, and then validating that an authenticated -user has a given role. In Strolch we go a step further: A User has roles -assigned, and each role has a set of Privileges. The privileges can overlap, a -validation is performed to make sure that the one role doesn’t deny and another -role allows a specific action.

    As explained in -the Privilege Configuration section, -users are defined in the PrivilegeUsers.xml file, and roles are defined in the -PrivilegeRoles.xml file.

    Let’s assume the following user and role definition:

    <Users>
    -  <User userId="1" username="jill" password="$PBKDF2WithHmacSHA512,10000,256$61646d696e$cb69962946617da006a2f95776d78b49e5ec7941d2bdb2d25cdb05f957f64344">
    -    <Firstname>Jill</Firstname>
    -    <Lastname>Someone</Lastname>
    -    <State>ENABLED</State>
    -    <Locale>en-GB</Locale>
    -    <Roles>
    -      <Role>AppUser</Role>
    -    </Roles>
    -    <Properties>
    -      <Property name="realm" value="execution" />
    -    </Properties>
    -  </User>
    -</Users>
    -
    <Roles>
    -  <Role name="AppUser">
    -    <Privilege name="li.strolch.service.api.Service" policy="DefaultPrivilege">
    -      <AllAllowed>true</AllAllowed>
    -    </Privilege>
    -    <Privilege name="li.strolch.model.query.StrolchQuery" policy="DefaultPrivilege">
    -      <AllAllowed>true</AllAllowed>
    -    </Privilege>
    -    <Privilege name="li.strolch.search.StrolchSearch" policy="DefaultPrivilege">
    -      <AllAllowed>true</AllAllowed>
    -    </Privilege>
    -  </Role>
    -</Roles>
    -

    This configuration contains one user and one role. The user jill has the role -AppUser and the role AppUser has three privileges assigned.

    Note how the user’s password is configured similar to a unix password -definition: Using the dollar sign & first the hashing algorithm is configured ( -algorithm, iterations, key length), then the salt, followed by the password -hash.

    Note: The password can also still be saved using two separate fields: a salt and -password field. This configuration will be immediately changed to the unix form, -so won’t be described further here.

    Further a user always has a firstname and last name. Optionally a locale can be -set, otherwise the system locale is used. The user’s state must be defined as -one of NEW, ENABLED, DISABLED, EXPIRED or SYSTEM. A user can only -authenticate/login with the state ENABLED. A user can have any number of -properties, which can then be used at runtime. A user can also reference any -number of roles, the assigned privilege can overlap, a global configuration mode -defines how duplicate privileges are handled.

    Roles have a name and any number of Privilege definitions. A Privilege has a -name, which in many cases is the name of Java class/interface on which an action -is being invoked. The policy value defines which policy to use when evaluating -the privilege access. The privilege definition is defined in the -PrivilegeConfig.xml and is the name of a class to call for privilege validation.

    Further the privilege definitions can have a AllAllowed boolean flag, or any -number of Allow or Deny values. How these values are interpreted is defined in -the policy implementation. A policy takes three input parameters:

    • PrivilegeContext → supplied by privilege and gives access to the Certificate, -thus identifying the user for which privilege access is to be validated.
    • IPrivilege → Contains the privilege values: AllAllowed, Allow and Deny
    • Restrictable → An interface from which the privilege name is retrieved, and -the associated value. The value is an object, and is cast to the relevant -input in the concrete privilege policy.

    The following privilege policies are already implemented:

    • DefaultPrivilege → simple policy where the passed Restrictable is expected to -return a String value, which is compared with allow and deny values.
    • Internal: RoleAccessPrivilege → policy used for the internal privileges -PrivilegeGetRole, PrivilegeAddRole, PrivilegeModifyRole or PrivilegeModifyRole
    • Internal: UserAccessPrivilege → policy used for the internal privileges -PrivilegeGetUser, PrivilegeAddUser, PrivilegeRemoveUser, PrivilegeModifyUser, -PrivilegeAddRoleToUser, PrivilegeRemoveRoleFromUser, PrivilegeSetUserState, -PrivilegeSetUserLocale or PrivilegeSetUserPassword
    • Internal: UserAccessWithSameOrganisationPrivilege → Same as the -UserAccessPrivilege but expects the authenticated user to have a property -organisation and validates that the user being modified is in the same -organisation.
    • Internal: UsernameFromCertificatePrivilege → This policy expects a -Restrictable to return the certificate of another authenticated user and is -used when modifying an authenticated user, i.e. killing a session, or -modifying its current state, e.g. locale etc.
    • Internal: UsernameFromCertificateWithSameOrganisationPrivilege → Same as -UsernameFromCertificatePrivilege but expects the authenticated user to have a -property organisation and validates that the user being modified is in the -same organisation.

    Note: As a rule, the sequence is AllAllowed → Allow → Deny → default deny

    \ No newline at end of file diff --git a/public/documentation/queries/index.html b/public/documentation/queries/index.html deleted file mode 100644 index ee3fc25..0000000 --- a/public/documentation/queries/index.html +++ /dev/null @@ -1,61 +0,0 @@ -Queries - Strolch

    Queries

    Queries

    The Query API is deprecated and the search API should be used instead.

    As is custom for every framework, querying the model must be possible. Strolch -queries are implemented using the StrolchQuery interface and one of its concrete -implementations: ResourceQuery, OrderQuery, ActivityQuery.

    A Strolch element always has two identifiers: Type and Id. The type is important -as it classifies an element. So if a car and a house would be modelled in -Strolch, then those would both be a Resource, but one of type Car and the other -of type House. Both would have different parameters.

    Thus one of the inputs for every query is it’s type, which is defined as the -navigation. It is said that we navigate to the Cars, or Houses. Thus when -instantiating a ResourceQuery, pass the navigation to the type of Resource as -well. Same applies for Orders and Activities.

    Further input for a StrolchQuery are the selections. These selections get -translated into RDBMS WHERE clauses. Selections support boolean operations thus -allowing for complex querying.

    StrolchQueries also support Ordering and object transformation. Following -classes provide the most used scenarios:

    • OrderById
    • OrderByName
    • OrderByParameter
    • *ToDomVisitor
    • *ToSaxVisitor
    • *ToJsonVisitor
    • *ToFlatJsonVisitor

    Example: Query all resources of type Car:

    try (StrolchTransaction tx = openTx()) {
    -  ResourceQuery<Resource> query = ResourceQuery.query("Car");
    -  query.withAny();
    -  List<Resource> cars = tx.doQuery(query);
    -}
    -

    Example: Query all resources of type Car, order by Name and transform to JSON:

    try (StrolchTransaction tx = openTx()) {
    -  ResourceQuery<JsonObject> query = ResourceQuery.query("Car", new ResourceToJsonVisitor(),
    -      new OrderByName());
    -  query.withAny();
    -  List<JsonObject> cars = tx.doQuery(query);
    -}
    -

    the previous example can also be written as follows:

    try (StrolchTransaction tx = openTx()) {
    -  ResourceQuery<JsonObject> query = new ResourceQuery<>();
    -  query.setNavigation(new StrolchTypeNavigation("Car"));
    -  query.setResourceVisitor(new ResourceToJsonVisitor());
    -  query.withAny();
    -  List<JsonObject> cars = tx.doQuery(query);
    -}
    -

    Example: Query all resources of type Car with color blue:

    try (StrolchTransaction tx = openTx()) {
    -    ResourceQuery<Resource> query = ResourceQuery.query("Car");
    -    query.with(ParameterSelection.stringSelection("parameters", "color", "blue", StringMatchMode.es()));
    -    List<Resource> cars = tx.doQuery(query);
    -}
    -

    Example: Query all resources of type Car which are not blue:

    try (StrolchTransaction tx = openTx()) {
    -  ResourceQuery<Resource> query = ResourceQuery.query("Car");
    -  query.not(ParameterSelection.stringSelection("parameters", "color", "blue", StringMatchMode.es()));
    -  List<Resource> cars = tx.doQuery(query);
    -}
    -

    Example: Query all resources of type Car with color blue or yellow:

    try (StrolchTransaction tx = openTx()) {
    -  ResourceQuery<Resource> query = ResourceQuery.query("Car");
    -  query.or().with(
    -      ParameterSelection.stringSelection("parameters", "color", "blue", StringMatchMode.es()),
    -      ParameterSelection.stringSelection("parameters", "color", "yellow", StringMatchMode.es()));
    -  List<Resource> cars = tx.doQuery(query);
    -}
    -

    Example: Query all resources of type Car with color blue or yellow owned by Jill:

    try (StrolchTransaction tx = openTx()) {
    -  ResourceQuery<Resource> query = ResourceQuery.query("Car");
    -
    -  StringParameterSelection owner = ParameterSelection.stringSelection("parameters", "owner", "Jill", StringMatchMode.es());
    -  OrSelection colors = new OrSelection().with(
    -      ParameterSelection.stringSelection("parameters", "color", "blue", StringMatchMode.es()),
    -      ParameterSelection.stringSelection("parameters", "color", "yellow", StringMatchMode.es()));
    -
    -  query.and().with(owner, colors);
    -
    -  List<Resource> cars = tx.doQuery(query);
    -}
    -
    \ No newline at end of file diff --git a/public/documentation/realms/index.html b/public/documentation/realms/index.html deleted file mode 100644 index d85cf40..0000000 --- a/public/documentation/realms/index.html +++ /dev/null @@ -1,86 +0,0 @@ -Realms - Strolch

    Realms

    Realms

    Realms implement multi-tenant capabilities. A Strolch agent can have an -arbitrary number of realms configured and each realm has its own persistence -configuration, allowing to separate mandates completely.

    A realm can run in one of the following modes:

    • EMPTY -This is a transient data store mode, where no model changes are -persisted - they are only kept in memory. When the Strolch agent is -started, this realm is empty as no data is loaded.
    • TRANSIENT -This is the same as EMPTY, but with the difference that when the Strolch -agent is started, a model file is parsed and the in-memory realm is -populated with the elements parsed from the model file.
    • CACHED -In this mode, all data is stored in-memory, and any changes made are -written back to the persistence layer. This allows for fast in-memory -qeuries, but makes sure no data is lost when the agent is restarted.

    Realms are mostly hidden from a developer as a StrolchTransaction exposes -all important operations needed to access Strolch objects. A developer will -however need to configure the realms for their specific project. If the -project only requires one realm, then the defaultRealm can be used, where the -developer only is required to configure the mode and any relevant model file.

    If the mode is CACHED, then the PersistenceHandler component is required to -be configured, so that the DAOs know how to access the underlying database.

    The configuration in the StrolchConfiguration.xml file is as follows:

    <StrolchConfiguration>
    -  <env id="dev">
    -    ...
    -    <Component>
    -      <name>RealmHandler</name>
    -      <api>li.strolch.agent.api.RealmHandler</api>
    -      <impl>li.strolch.agent.impl.DefaultRealmHandler</impl>
    -      <depends>PrivilegeHandler</depends>
    -      <!-- if CACHED: -->
    -      <!--depends>PersistenceHandler</depends-->
    -      <Properties>
    -        <!-- one of EMPTY, TRANSIENT, CACHED-->
    -        <dataStoreMode>TRANSIENT</dataStoreMode>
    -        <dataStoreFile>StrolchModel.xml</dataStoreFile>
    -      </Properties>
    -    </Component>
    -    ...
    -  </env>
    -</StrolchConfiguration>
    -

    Multi-Realm

    A multi-realm configuration would be as follows.

    Note how the defaultRealm is still enabled, and has its configuration as -before. Further the PostgreSQL PersistenceHandler is configured to show how the -realms are connected to the persistence handler:

    <StrolchConfiguration>
    -  <env id="dev">
    -    ...
    -    <Component>
    -      <name>RealmHandler</name>
    -      <api>li.strolch.agent.api.RealmHandler</api>
    -      <impl>li.strolch.agent.impl.DefaultRealmHandler</impl>
    -      <depends>PrivilegeHandler</depends>
    -      <depends>PersistenceHandler</depends>
    -      <Properties>
    -        <realms>defaultRealm, cachedRealm</realms>
    -        <dataStoreMode>TRANSIENT</dataStoreMode>
    -        <dataStoreFile>DefaultRealm.xml</dataStoreFile>
    -        <dataStoreMode.cachedRealm>CACHED</dataStoreMode.cachedRealm>
    -        <dataStoreMode.emptyRealm>EMPTY</dataStoreMode.emptyRealm>
    -      </Properties>
    -    </Component>
    -
    -    <Component>
    -      <name>PersistenceHandler</name>
    -      <api>li.strolch.persistence.api.PersistenceHandler</api>
    -      <impl>li.strolch.persistence.postgresql.PostgreSqlPersistenceHandler</impl>
    -      <Properties>
    -        <allowSchemaCreation>true</allowSchemaCreation>
    -        <allowSchemaDrop>true</allowSchemaDrop>
    -
    -        <db.url.cachedRealm>jdbc:postgresql://localhost/testdb2</db.url.cachedRealm>
    -        <db.username.cachedRealm>testuser2</db.username.cachedRealm>
    -        <db.password.cachedRealm>test</db.password.cachedRealm>
    -        <db.pool.maximumPoolSize.cachedRealm>1</db.pool.maximumPoolSize.cachedRealm>
    -      </Properties>
    -    </Component>
    -    ...
    -  </env>
    -</StrolchConfiguration>
    -

    Access realm

    Accessing a realm is done in multiple ways. Important is to note, that a user -should use the StrolchTransaction object, instead of accessing the Realm directly.

    Opening a transaction is done from a Service by calling one of the -openTx()-methods. Nevertheless, the realm can be accessed as follows:

    public class Example {
    -  public static void main(String[] args) {
    -    ComponentContainer container = getAgent().getContainer();
    -    StrolchRealm realm = container.getRealm(StrolchConstants.DEFAULT_REALM);
    -    try (StrolchTransaction tx = realm.openTx()) {
    -      Resource resource = tx.getResourceBy("TestType", "MyTestResource");
    -    }
    -  }
    -}
    -
    \ No newline at end of file diff --git a/public/documentation/reports/index.html b/public/documentation/reports/index.html deleted file mode 100644 index 508c510..0000000 --- a/public/documentation/reports/index.html +++ /dev/null @@ -1,159 +0,0 @@ -Reports - Strolch

    Reports

    Reports

    Since Strolch has a generic model, it was rather straight forward to create a -simple API for writing reports. In Strolch a report is defined by using its own -model, i.e. a Report is a Resource of type Report.

    A report consists of the following parts:

    • policy definition, thus allowing extensions
    • basic configuration like base object type, order direction, etc.
    • column definitions
    • joins
    • ordering definition
    • filters

    An example of a report is as follows:

    
    -<Resource Id="stockReport" Name="Stock Report" Type="Report">
    -
    -    <ParameterBag Id="parameters" Name="parameters" Type="Parameters">
    -        <Parameter Id="objectType" Index="20" Hidden="false" Name="Object Type"
    -                   Type="String" Interpretation="Resource-Ref" Uom="Player"
    -                   Value="Player"/>
    -        <Parameter Id="descending" Name="Descending order" Type="Boolean"
    -                   Value="true"/>
    -    </ParameterBag>
    -
    -    <ParameterBag Id="ordering" Name="Ordering" Type="Ordering">
    -        <Parameter Id="name" Name="Name" Type="String"
    -                   Interpretation="Resource-Ref" Uom="Player" Value="$name"/>
    -    </ParameterBag>
    -
    -    <ParameterBag Id="noTeamFilter" Name="Filter" Type="Filter">
    -        <Parameter Id="policy" Name="Filter Policy" Type="String"
    -                   Interpretation="ReportFilterPolicy" Uom="key:Equals"
    -                   Value="!"/>
    -        <Parameter Id="fieldRef" Name="Field reference" Type="String"
    -                   Interpretation="Resource-Ref" Uom="Slot"
    -                   Value="Bags/relations/team"/>
    -    </ParameterBag>
    -
    -    <ParameterBag Id="columns" Name="Display Columns" Type="Display">
    -        <Parameter Id="name" Name="Player" Type="String"
    -                   Interpretation="Resource-Ref" Uom="Player" Value="$name"/>
    -        <Parameter Id="birthDate" Name="Birth date" Type="String"
    -                   Interpretation="Resource-Ref" Uom="Player"
    -                   Value="Bags/parameters/birthDate"/>
    -        <Parameter Id="team" Name="Team" Type="String"
    -                   Interpretation="Resource-Ref" Uom="Team" Value="$name"/>
    -    </ParameterBag>
    -
    -    <ParameterBag Id="joins" Name="Joins" Type="Joins">
    -        <Parameter Id="Team" Index="10" Hidden="false" Name="Team" Type="String"
    -                   Interpretation="Resource-Ref" Uom="Team" Value="Player"/>
    -    </ParameterBag>
    -
    -    <Policies>
    -        <Policy Type="ReportPolicy"
    -                Value="java:li.strolch.report.policy.GenericReport"/>
    -    </Policies>
    -
    -</Resource>
    -

    This report

    • shows all Resources of type player (parameter objectType) → marks the object -type to be show in the filter criteria (default), and that its sorting index -is at 20.
    • orders the report by player’s name (parameter bag ordering)
    • filters out all players with no team assigned (parameter bag noTeamFilter)
    • defines three columns: Player, Birth date, Team (paramger bag columns)
    • joins in the resource of type Team
    • Uses the GenericReport class to generate the report

    GenericReport

    The default generic report implemented in Strolch has the following features and -options:

    Parameters

    The parameters bag can contain the following parameters:

    • objectType → the base type of object to get the input for the report. This -means that the Interpretation is set to one of:

      • Resource-Ref
      • Order-Ref
      • Activity-Ref

      and that the UOM and value of the parameter is set to the type of element with -which to retrieve the elements from the strolch model.

    • descending → boolean flag to define if sorting is in descending order

    • allowMissingColumns → flag to define if no exception should be thrown if a -column is missing

    • dateRangeSel → defines a lookup parameter to use as a date range selector. -This requires input when executing the report

    Note: that the attributes Hidden and Index define the -visibility and sorting index as filter criteria respectively.

    Lookups

    Many of the features of the generic report rely on looking up a value on the -referenced element. The following shows the ways that a lookup can be performed:

    • $id → lookup the ID of the element
    • $name → lookup the name of the element
    • $type → lookup the type of the element
    • $date → lookup the date of the element (only possible on Order -and Activity elements)
    • $state → lookup the state of the element (only possible on Order -and Activity elements)
    • Bags/<bag_id>/<param_id> → a lookup on the selected element by bag ID and -parameter ID
    • $search:<parent_ref_id>:Bags/<bag_id>/<param_id> → searches for a parameter -with the given bag and parameter, and if it does not exist, looks for the -parent with the given parent_ref_id on the element. This allows a recursive -search up a tree of elements which all have the same parameter referencing a -parent. relations bag

    Note: these definitions are set as the value of a -Parameter, and the Interpretation and UOM of the parameter is used to find the -element on which to perform the lookup. I.e. the following definition:

    <Parameter Id="name" Name="Player" Type="String" Interpretation="Resource-Ref" Uom="Player" Value="$name"/>
    -

    defines that we want to lookup the name of the resource of type Player.

    Ordering

    Ordering, i.e sorting is done by adding the parameter bag with the id ordering -and each parameter defines a column to order by. The sequence of the ordering is -defined by the index value assigned to each parameter.

    Filtering

    Filtering use additional Strolch Policies which implement the operator function. -I.e. performing an equals, etc. The following ReportFilterPolicy are available -and should be added in your StrolchPolicies.xml file:

    <StrolchPolicies>
    -  ...
    -  <PolicyType Type="ReportFilterPolicy" Api="li.strolch.report.policy.ReportFilterPolicy">
    -    <Policy Key="GreaterThan" Class="li.strolch.report.policy.GreaterThanReportFilter"/>
    -    <Policy Key="LessThan" Class="li.strolch.report.policy.LessThanReportFilter"/>
    -    <Policy Key="Equals" Class="li.strolch.report.policy.EqualsReportFilter"/>
    -    <Policy Key="Contains" Class="li.strolch.report.policy.ContainsReportFilter"/>
    -    <Policy Key="IsIn" Class="li.strolch.report.policy.IsInReportFilter"/>
    -    <Policy Key="ValueRef" Class="li.strolch.report.policy.ValueRefReportFilter"/>
    -  </PolicyType>
    -  ...
    -</StrolchPolicies>
    -

    From this we can see that we can perform a GreaterThan, LessThan and Equals -filtering. These filters can also be negated by prefixing the filter value with -an exclamation mark (!).

    A special case for the filter values are filters on dates. If you are filtering -on a date, then you can use the special operator now(). This filter will use the -current date and time and will add/subtract the ISO8601 period passed as an -argument to the operator.

    The following shows examples of these filters:

    <ParameterBag Id="minQtyFilter" Name="Filter" Type="Filter">
    -  <Parameter Id="policy" Name="Filter Policy" Type="String" Interpretation="ReportFilterPolicy" Uom="key:GreaterThan" Value="10"/>
    -  <Parameter Id="fieldRef" Name="Field reference" Type="String" Interpretation="Resource-Ref" Uom="Product" Value="Bags/parameters/quantity"/>
    -</ParameterBag>
    -
    -<ParameterBag Id="notEmptyFilter" Name="Filter" Type="Filter">
    -  <Parameter Id="policy" Name="Filter Policy" Type="String" Interpretation="ReportFilterPolicy" Uom="key:Equals" Value="!"/>
    -  <Parameter Id="fieldRef" Name="Field reference" Type="String" Interpretation="Resource-Ref" Uom="Team" Value="Bags/relations/team"/>
    -</ParameterBag>
    -
    -<ParameterBag Id="threeMonthsAgoFilter" Name="Filter" Type="Filter">
    -  <Parameter Id="policy" Name="Filter Policy" Type="String" Interpretation="ReportFilterPolicy" Uom="key:LessThan" Value="now(-P3M)"/>
    -  <Parameter Id="fieldRef" Name="Field reference" Type="String" Interpretation="Resource-Ref" Uom="FromStock" Value="$date"/>
    -</ParameterBag>
    -

    Note: One parameter defines which policy gets used and the key:<name> value -references a policy defined in the StrolchPolicies.xml file. Further the lookup -is defined in the fieldRef parameter.

    Joins

    To add columns from data which is not on the element denoted by the base object -type, we can join further elements. This is done by adding the parameter bag -joins and then each parameter references an element to join. The joining is done -as follows:

    • The Intepretation and UOM define which object we want to join, i.e. resource -of type foo
    • The value of the parameter defines the type of element on which to find the -reference
    • The join ordering is not relevant, as the tree is traversed accordingly
    • At least one join must reference the base object type
    • The lookup of the join is done by finding a parameter with any ID, which has -the same Interpretation and UOM as the join definition
    • The attributes Hidden and Index define the visibility and sorting index as -filter criteria respectively.

    Thus the following:

    <ParameterBag Id="joins" Name="Joins" Type="Joins">
    -  <Parameter Id="Team" Index="10" Hidden="false" Name="Team" Type="String" Interpretation="Resource-Ref" Uom="Team" Value="Player"/>
    -  <Parameter Id="Country" Index="5" Hidden="false" Name="Team" Type="String" Interpretation="Resource-Ref" Uom="Country" Value="Team"/>
    -</ParameterBag>
    -

    Performs two joins: First we join a resource of type Team by finding the -relevant parameter on the Player resource, and then we lookup a resource of type -Country on the previously joined Team resource.

    Execution of Reports

    To execute a reports, we must instantiate the Report and can then directly -generate a JsonObject stream, which we can then pipe to a browser, file, etc.:

    Stream<JsonObject> jsonObjectStream = new Report(tx, reportId).doReportAsJson();
    -

    If you prefer a CSV report:

    try (CSVPrinter csvP = new CSVPrinter(new OutputStreamWriter(out),
    -        CSVFormat.DEFAULT.withHeader(headers).withDelimiter(';'))) {
    -
    -  // do report without AsJson, and then iterating each row and sending to a CSV writer
    -  report.doReport().forEach(row -> {
    -    try {
    -      csvP.printRecord(row.valueStream().collect(Collectors.toList())); // add to CSV
    -    } catch (Exception e) {
    -      logger.error("Could not write CSV row", e);
    -    }
    -  });
    -}
    -

    Filter Criteria

    Predefining filters is a good start, but in some case you only want a portion of -the actual filtered data. For instance if you make a stock report, you might -only want one location. This information is dynamic and thus not stored on the -report definition.

    To perform these dynamic filterings, one would call the filter()-method on the -report, passing the type of element to be filtered, and to which element IDs to -reduce the report data to. The following reduces the report to only return the -rows with the product01 Product and location02 Location elements:

    new Report(tx, "stockReport")
    -        .filter("Product", "product01")
    -        .filter("Location", "location02")
    -        .doReportAsJson()
    -

    It is possible to find the possible filter criteria dynamically using the -generateFilterCriteria() method.

    Date Range Filtering

    The last option to filter dynamically is using a date range selector. Define the -dateRangeSel lookup parameter, and then set the date range on the instantiated -report:

    Model the report in XML:

    <ParameterBag Id="parameters" Name="parameters" Type="Parameters">
    -    ...
    -    <Parameter Id="dateRangeSel" Name="Date Range Selector" Type="String" Interpretation="Resource-Ref" Uom="Product" Value="Bags/parameters/expirationDate"/>
    -    ...
    -</ParameterBag>
    -

    And now call the report in Java:

    Date from = new Date(LocalDate.of(2016, 1, 1).toEpochDay() * 86400000);
    -Date to = new Date(LocalDate.of(2017, 1, 1).toEpochDay() * 86400000);
    -DateRange dateRange = new DateRange().from(from, true).to(to, false);
    -List<JsonObject> result = new Report(tx, "stockReport") //
    -    .filter("Product", "product01") //
    -    .dateRange(dateRange) //
    -    .doReportAsJson()
    -

    Note: See the GenericReportTest for examples.

    \ No newline at end of file diff --git a/public/documentation/runtime-configuration/index.html b/public/documentation/runtime-configuration/index.html deleted file mode 100644 index 9af8758..0000000 --- a/public/documentation/runtime-configuration/index.html +++ /dev/null @@ -1,111 +0,0 @@ -Runtime Configuration - Strolch

    Runtime Configuration

    Runtime Configuration

    A Strolch runtime configuration comprises two parts: a configuration part, and -a model part. The configuration are files located in the ..config/ folder, -and the model are files located in the ../data folder.

    In an absolute minimal configuration, the Strolch runtime requires the -following folder structure:

    • ../config/
      • ../StrolchConfiguration.xml → configures the Strolch agent
      • ../PrivilegeConfig.xml → configures user management
      • ../PrivilegeUsers.xml → contains the users in an XML based user management file
      • ../PrivilegeRoles.xml → contains the roles and privileges in an XML based user management

    StrolchConfiguration.xml

    The StrolchConfiguration.xml file configures the Strolch agent. The StrolchConfiguration.xml defines the following:

    • <StrolchConfiguration> root element
    • <env id="xxx"> different environments with the possibility of having a -global environment for configuration valid in multiple environments.
      • <Runtime> element which defines the agents name and a few other -properties e.g. locale and verbose:
      • <applicationName> the agent’s name
      • <Properties>
        • <locale> the agent’s internal locale for log messages etc.
        • <verbose> the logging level for some internal logging. (Logging is -mostly done using log4j over slf4j)
      • <Component> elements for each component used in the agent. A component -is configured by defining the following child elements:
        • <name> the name of the component, use when defining dependencies -between components. The name is mostly set to the simple name of the -interface of the component

        • <api> the full class name to the interface of the component. During -runtime this interface will be used to access the component e.g.:

          ServiceHandler svcHandler = agent.getContainer().getComponent(ServiceHandler.class);

        • <impl> the full class name of the concrete implementation of the -component. During initialization this class will be instantiated and -registered under the component name and interface. This class must -extend the class li.strolch.agent.api.StrolchComponent

        • <depends> any number of these elements, where the content is the name -of another component, on which this component depends. Depending -components are initialized and started after the component they depend -on and are stopped and destroyed before

        • <Properties>

        • <...> any number of properties which the component requires. The -element’s name will be the key with which the value can be accessed at -runtime.

    When a property is missing, and the component has a hard coded default value, then when the component is initialized, the use of the default value and its key is logged. This makes it easy to see which new properties can be configured. Should the component not define a default value, then the component will thrown an exception on initialization. In this case it can be a good moment to read the JavaDoc (or source code) for the component in question to see how it is configured.

    Privilege Configuration

    In Strolch authentication and authorization is baked in. To open a transaction, -and thus access the Strolch model, a Certificate object is required, which -means the user has been authenticated and possibly authorized.

    The PrivilegeConfig.xml defines the following:

    • <Privilege> root element
      • <Container> configures the individual Privilege components
        • <Parameters> base configuration properties for Privilege
        • <EncryptionHandler> configures the hashing algorithms and other -encryption specific configuration
        • <PersistenceHandler> configures the persistence of the roles and users
        • <UserChallengeHandler> configures a challenge handler so that a user -can reset their password. The default challenge handler is the -li.strolch.privilege.handler.MailUserChallengeHandler which sends a -challenge to the user’s defined e-mail address.
        • <SsoHandler> the SSO Handler is used to implement a SingleSignOn and -can be used to start a session using a LDAP token, etc. There is no -default implementation as this is project specific.
      • <Policies> configures the available privilege policies at runtime, the -name is referenced from the model file

    The PrivilegeUsers.xml and PrivilegeRoles.xml define the users and roles -and is used when in PrvilegeConfig.xml the PersistenceHandler is set to -ch.eitchnet.privilege.handler.XmlPersistenceHandler:

    • <Users> configures all users
      • <User> configures a specific user
        • <Firstname> configures a user’s first name
        • <Lastname> configure a user’s last name
        • <State> configures the user’s state, see li.strolch.privilege.model.UserState
        • <Locale> configure the user’s locale
        • <Roles> configures the user’s roles
          • <Role> adds a role to the user
          • <Properties> configures user specific properties. What properties -are used is not specified and is dependent on the concrete agent
            • <Property> defines a single property
      • <Roles> configures all roles
        • <Role> configures a specific role
          • <Privilege> configures a specific privilege for this role
            • <AllAllowed> if set to true, then defines that all values -associated with this privilege are allowed
            • <Allow> defines one allowed value for this privilege
            • <Deny> defines one denied value for this privilege

    Implementing a StrolchComponent

    Implementing a strolch component requires an interface, which defines the -component’s API and a concrete class which implements the interface and -extends the class StrolchComponent.

    The StrolchComponent class adds the state model to the class, which -transitions as follows:

    UNDEFINED => SETUP => INITIALIZED => STARTED <=> STOPPED => DESTROYED

    Components can switch between STARTED and STOPPED, but once DESTROYED no -further state change is possible. The component’s state is changed by changes -to the agent’s lifecycle.

    A component’s state is changed by a call to the appropriate method on the -component, override the methods as necessary. Note that it is good practice -that the initialize()-method is used to get all the configuration properties, -and that they should there be evaluated and that the method so return quickly. -The start()-method is called after the agent’s initialization and should be -where additional threads are started. Correctly implementing these methods -allows to quickly detect a wrongly configured agent, which might take longer -to start for whatever reason.

    The following shows a basic implementation of a component on the basis of a -post initializer (a component which performs some actions in its -start()-method which should be done after everything else is started in the -agent).

    public class SimplePostInitializer
    -        extends StrolchComponent
    -        implements PostInitializer {
    -
    -  public SimplePostInitializer(ComponentContainer container,
    -        String componentName) {
    -    super(container, componentName);
    -  }
    -
    -  @Override
    -  public void initialize(ComponentConfiguration configuration) {
    -    // do some initialization, validate configuration values, etc.
    -    // now call super, to update state
    -    super.initialize(configuration);
    -  }
    -
    -  @Override
    -  public void start() {
    -    // start any threads, or perform long running start work
    -    // now call super, to update state
    -    super.start();
    -  }
    -
    -  @Override
    -  public void stop() {
    -    // stop threads and timers, but be ready to start again
    -    // now call super, to update state
    -    super.stop();
    -  }
    -
    -  @Override
    -  public void destroy() {
    -    // destroy this component, release all resources and don't worry about
    -    // being called to start again now call super, to update state
    -    super.destroy();
    -  }
    -}
    -

    The new component would then be registered in the StrolchConfiguration.xml -as follows:

    <StrolchConfiguration>
    -  <env id="...">
    -    ...
    -    <Component>
    -      <name>SimplePostInitializer</name>
    -      <api>li.strolch.agent.api.PostInitializer</api>
    -      <impl>li.strolch.documentation.SimplePostInitializer</impl>
    -    </Component>
    -    ...
    -  </env>
    -</StrolchConfiguration>
    -

    And can be access at runtime using:

    PostInitializer postInitializer = getContainer().getComponent(PostInitializer.class);
    -

    Starting the agent

    When a Strolch runtime is started, then the root path to the runtime configuration must be passed. In Java this is done by calling:

    StrolchAgent agent = new StrolchAgent();
    -agent.setup(environment, rootPath);
    -agent.initialize();
    -agent.start();
    -

    In Servlet 3.0 applications one would implement the -javax.servlet.ServletContextListener interface, add the @WebListener -annotation to the class and in the contextInitialized()-method start Strolch:

    String realPath = sce.getServletContext().getRealPath("/WEB-INF");
    -String environment = StrolchEnvironment.getEnvironmentFromEnvProperties(pathF);
    -this.agent = new StrolchAgent();
    -this.agent.setup(environment, new File(realPath));
    -this.agent.initialize();
    -this.agent.start();
    -
    \ No newline at end of file diff --git a/public/documentation/searches/index.html b/public/documentation/searches/index.html deleted file mode 100644 index 87ab4ab..0000000 --- a/public/documentation/searches/index.html +++ /dev/null @@ -1,53 +0,0 @@ -Searches - Strolch

    Searches

    Searches

    As is custom for every framework, querying, or searching, the model must be -possible. Strolch searches are implemented using the StrolchSearch class and -one of its concrete implementations: ResourceSearch, OrderSearch, -ActivitySearch.

    A Strolch element always has two identifiers: Type and Id. The type is -important as it classifies an element. So if a car and a house would be modelled -in Strolch, then those would both be a Resource, but one of type Car -and the other of type House. Both would have different parameters. Thus when -searching for objects, the first thing to do is define the type of object being -searched.

    The Strolch search API is very expressive and offers multiple ways to perform -the same search. The search API consists of three components: The search -classes, the search expressions and the search predicates. The concept was taken -from the Apache Camel project.

    There are four main search classes:

    • RootElementSearch - search for any of Resource, Order or Activity elements
    • ResourceSearch - search for Resources
    • OrderSearch - search for Orders
    • ActivitySearch - search for Activities

    No search is useful without a where clause, which are called search -expressions. When writing a search, there are multiple ways to add such where -clauses. Either

    • override the define()-method in your sub class and add the where clauses by -calling the where() method, or
    • define special methods on the class e.g. byColor() which also calls the -where()-method to add a search expression, or
    • directly call the where()-method after instantiating a search.

    When extending the class, then the search expressions are available as methods -on the super class, otherwise you can statically import them from -ExpressionsSupport -.

    And of course a where clause needs operators, which are called search -predicates. Just as search expressions are available in sub classes, so are -search predicates and can also be statically imported through -PredicatesSupport -.

    Examples of search expressions with search predicates follow:

    ResourceSearch search=new ResourceSearch();
    -
    -// predicate either as parameter, or chained
    -search.where(id().isEqualTo("myId"));
    -search.where(id(isEqualTo("myId")));
    -
    -// negating
    -search.where(id(isEqualTo("myId")).not());
    -
    -search.where(param("bagId","paramId").isIn(Arrays.asList("red","blue","green")));
    -
    -search.where(paramNull("bagId","paramId")));
    -
    -// boolean operations
    -search.where(id(isEqualTo("myId")) //
    -		.or(name(isEqualTo("myName"))));
    -

    Note how the predicates can be chained to the search expression, or passed as a -parameter to the expression.

    In addition to using predefined search search expressions, one can also just -pass a lambda expression which performs a custom filter:

    personSearch.where(person -> person.getName().length() == 3);
    -

    See -the StrolchSearchTest -for many ways in which you can implement tests.

    Note that strolch searches requires privileges, thus when you -use a strolch search, add it to the role of the user in PrivilegeRoles.xml:

    
    -<Privilege name="li.strolch.search.StrolchSearch" policy="DefaultPrivilege">
    -    <Allow>internal
    -    </Allow> <!-- internal used for when the search is done in an internal service -->
    -    <Allow>li.strolch.bookshop.search.BookSearch</Allow>
    -</Privilege>
    -
    \ No newline at end of file diff --git a/public/documentation/services-and-commands/index.html b/public/documentation/services-and-commands/index.html deleted file mode 100644 index 4bbd554..0000000 --- a/public/documentation/services-and-commands/index.html +++ /dev/null @@ -1,78 +0,0 @@ -Services and Commands - Strolch

    Services and Commands

    Services and Commands

    Services are written to implement a specific use-case. Commands are written to -implement re-usable parts of a use-case. The use-case can be abstract -e.g., AddResourceService or very specific e.g. CreatePatientService.

    Should the use-case be re-usable in different scenarios, then commands should -implement the logic, and the services should then execute the commands. E.g. -The CreatePatientService would use a CreatePatientResourceCommand and then -use an AddResourceCommand in a single transaction, so that the task of -creating the actual Patient Resource can be re-used somewhere else.

    Services extend the abstract class AbstractService and then implement the -method internalDoService(ServiceArgument). AbstractService defines generic -template arguments with which the concrete service can define a specific -input ServiceArgument class and output ServiceResult class.

    The AbstractService class has multiple helper methods:

    • openTx():StrolchTransaction - to open a transaction
    • runPrivileged() - to perform a SystemUserAction
    • getComponent():V - to retrieve a specific StrolchComponent

    there are more - check the JavaDocs.

    Commands extend the Command class and then implement the method doCommand(). -Commands have helper methods:

    • tx() - to get the current transaction
    • getPolicy() - to retrieve a StrolchPolicy instance
    • runPrivileged() - to perform a SystemUserAction

    there are more - check the JavaDocs.

    The following code snippets shows how a Service and Command are used to -perform the task of adding a new Order. Note how:

    • the Service opens the transaction
    • adds the command to the TX
    • calls tx.commitOnClose()
    • the command validates its input
    • locks the object
    • performs the work
    • and implements an undo

    AddOrderService:

    public class AddOrderService extends AbstractService<AddOrderService.AddOrderArg, ServiceResult> {
    -
    -  @Override
    -  protected ServiceResult getResultInstance() {
    -    return new ServiceResult();
    -  }
    -
    -  @Override
    -  protected ServiceResult internalDoService(AddOrderArg arg) {
    -
    -    try (StrolchTransaction tx = openTx(arg.realm)) {
    -      AddOrderCommand command = new AddOrderCommand(getContainer(), tx);
    -      command.setOrder(arg.order);
    -      tx.addCommand(command);
    -      tx.commitOnClose();
    -    }
    -
    -    return ServiceResult.success();
    -  }
    -
    -  public static class AddOrderArg extends ServiceArgument {
    -    public Order order;
    -  }
    -}
    -

    AddOrderCommand:

    public class AddOrderCommand extends Command {
    -
    -  private Order order;
    -
    -  public AddOrderCommand(ComponentContainer container, StrolchTransaction tx) {
    -    super(container, tx);
    -  }
    -
    -  public void setOrder(Order order) {
    -    this.order = order;
    -  }
    -
    -  @Override
    -  public void validate() {
    -    DBC.PRE.assertNotNull("Order may not be null!", this.order);
    -  }
    -
    -  @Override
    -  public void doCommand() {
    -
    -    tx().lock(this.order);
    -
    -    OrderMap orderMap = tx().getOrderMap();
    -    if (orderMap.hasElement(tx(), this.order.getType(), this.order.getId())) {
    -      String msg = MessageFormat.format("The Order {0} already exists!", this.order.getLocator());
    -      throw new StrolchException(msg);
    -    }
    -
    -    orderMap.add(tx(), this.order);
    -  }
    -
    -  @Override
    -  public void undo() {
    -    if (this.order != null && tx().isRollingBack()) {
    -      OrderMap orderMap = tx().getOrderMap();
    -      if (orderMap.hasElement(tx(), this.order.getType(), this.order.getId()))
    -        orderMap.remove(tx(), this.order);
    -    }
    -  }
    -}
    -
    \ No newline at end of file diff --git a/public/documentation/transactions/index.html b/public/documentation/transactions/index.html deleted file mode 100644 index 34be352..0000000 --- a/public/documentation/transactions/index.html +++ /dev/null @@ -1,59 +0,0 @@ -Transactions - Strolch

    Transactions

    Transactions

    Strolch Transactions play a central role in a Strolch agent. A transaction is -opened for a realm, and grants access to the model of the agent. Transactions -are implemented as a Java try-with-resources by implementing -the AutoCloseable -interface. This makes it trivial to understand the scope of a transaction.

    Transactions handle the following:

    • Opening and closing database connections
    • Releasing locks to strolch elements, if tx.lock(StrolchRootElement) or -tx.lock(Locator) was called
    • Performing Commands by executing them in the added order, and validating them -first.
    • Exception handling
    • Auditing
    • Updating observers

    When a transaction is opened, it is by default read-only, i.e. does not perform -any commands when it is closed. Should the TX perform commands, then it is -important to call tx.commitOnClose(), but only at the end of the work, so that -exception handling can properly work if something goes wrong.

    StrolchTransaction offers a myriad of methods:

    • find element by its Locator
    • get methods for elements by type and id, or using a StringParameter or -StringListParameter references
    • methods to add, update or remove elements
    • assert privilege access
    • get a new element by its template
    • check if an element exists by type and id
    • get streams for elements
    • add commands for execution

    Transactions are opened by accessing the realm, but there are convenience -methods depending on the use-case:

    • In Services: by calling one of the openTx()-methods
    • In Commands: Transactions are already open, use method tx() to get instance.
    • REST API: RestfulStrolchComponent.openTx()

    Note: don’t open a new TX inside a TX for the same realm!

    Important is to always open the transaction as a try-with-resource block and to -define if the TX should commit, or not:

    try (StrolchTransaction tx = openTx(...)) {
    -
    -  // read lock our object
    -  Locator ferrariLoc = Resource.locatorFor("Car", "ferrari");
    -  tx.lock(ferrariLoc);
    -
    -  // find a car by locator
    -  Resource ferrari = tx.findElement(ferrariLoc);
    -
    -  // get a car by ID
    -  Resource opel = tx.getResourceBy("Car", "opel", true);
    -
    -  // modify ball
    -  opel.setName("Opel Corsa");
    -  tx.update(opel);
    -
    -  // get by string reference
    -  StringParameter ownerP = ferrari.getParameter("relations", "owner", true);
    -  Resource owner = tx.getResourceBy(ownerP, true);
    -
    -  // get by string list reference
    -  StringListParameter previousOwnersP = opel.getParameter("relations", "previousOwners", true);
    -  List<Resource> previousOwners = tx.getResourcesBy(previousOwnersP, true);
    -
    -  // check resource exists
    -  if (tx.hasResource("Car", "audi")) {
    -    Resource audi = tx.getResourceBy("Car", "audi", true);
    -
    -    // assert has privilege to remove a car
    -    tx.assertHasPrivilege(Operation.REMOVE, audi);
    -
    -    // remove the car
    -    tx.remove(audi);
    -  }
    -
    -  // iterate all cars
    -  tx.streamResources("Car").forEach(car -> {
    -  	logger.info("Car: " + car.getId());
    -  });
    -
    -  // commit if TX was changed
    -  if (tx.needsCommit())
    -    tx.commitOnClose();
    -}
    -
    \ No newline at end of file diff --git a/public/documentation/versioning/index.html b/public/documentation/versioning/index.html deleted file mode 100644 index 4887eed..0000000 --- a/public/documentation/versioning/index.html +++ /dev/null @@ -1,39 +0,0 @@ -Versioning - Strolch

    Versioning

    Versioning

    One of Strolch’s features that sets it apart from other frameworks, is that -versioning is baked into Strolch’s fabric. The feature is opt-in, as it is not -required in all projects, but it only needs enabling, for all modifications to -objects to be versioned, so that rollbacks can be done when needed.

    The feature is enabled for each realm. In the StrolchConfiguration.xml file -enable it by adding the enableVersioning propery per realm:

    <StrolchConfiguration>
    -  <env id="dev">
    -    ...
    -    <Component>
    -      <name>RealmHandler</name>
    -      <api>li.strolch.agent.api.RealmHandler</api>
    -      <impl>li.strolch.agent.impl.DefaultRealmHandler</impl>
    -      <depends>PrivilegeHandler</depends>
    -      <Properties>
    -        <realms>defaultRealm, otherRealm</realms>
    -        <enableVersioning>true</enableVersioning>
    -        <dataStoreMode>TRANSIENT</dataStoreMode>
    -        <dataStoreFile>StrolchModel.xml</dataStoreFile>
    -        <enableVersioning.otherRealm>true</enableVersioning.otherRealm>
    -        <dataStoreMode.otherRealm>TRANSIENT</dataStoreMode.otherRealm>
    -        <dataStoreFile.otherRealm>StrolchModel.xml</dataStoreFile.otherRealm>
    -      </Properties>
    -    </Component>
    -  </env>
    -  ...
    -</StrolchConfiguration>
    -

    Once versioning is enabled, versioning is handled automatically. The API for versioning is implemented on the ElementMaps.

    Example: Revert to previous version of a Resource:

    Resource res = tx.getResourceBy("TestType", "MyTestResource");
    -ResourceMap resourceMap = tx.getResourceMap();
    -Resource previousVersion = resourceMap.revertToVersion(tx, res);
    -// or
    -Resource previousVersion = resourceMap.revertToVersion(tx, "TestType", "MyTestResource", 1);
    -

    Example: Retrieve all versions of a Resource:

    List<Resource> versions = resourceMap.getVersionsFor(tx, "TestType", "MyTestResource");
    -

    Note: When reverting to a previous version, it is important to remember, that -any references on an element to other elements will also be restored. As long as -the relationship is to the same element, then this is not an issue, but should -the relationship have changed, then it this must be handled and the user -performing a revert be allowed to decided which element to reference in the -reverted version.

    \ No newline at end of file diff --git a/public/download/index.html b/public/download/index.html deleted file mode 100644 index 298bd1c..0000000 --- a/public/download/index.html +++ /dev/null @@ -1,27 +0,0 @@ -Download - Strolch

    Download

    Download

    Strolch is -on Maven central -, but if the latest version is not there, then build it locally. A guide can be -found on the development page.

    Strolch is also built on Jenkins, so you can see if the -latest version passes all tests.

    Include as Maven dependency

    The easiest way to include strolch in your project is to use the following maven dependency:

    
    -<project>
    -    
    -    <properties>
    -        <strolch.version>1.8.5</strolch.version>
    -    </properties>
    -    
    -    <dependencies>
    -        <dependency>
    -            <groupId>li.strolch</groupId>
    -            <artifactId>li.strolch.bom</artifactId>
    -            <type>pom</type>
    -            <version>${strolch.version}</version>
    -            <scope>import</scope>
    -        </dependency>
    -    </dependencies>
    -</project>
    -
    -

    The bom will include all Strolch modules, you can always exclude a dependency, -or only include the dependencies you really want, e.g. model, etc.

    After including the dependency, checkout development on how to turn your project into a Strolch agent.

    \ No newline at end of file diff --git a/public/download/index.xml b/public/download/index.xml deleted file mode 100644 index b3be9fa..0000000 --- a/public/download/index.xml +++ /dev/null @@ -1 +0,0 @@ -Download on Strolchhttps://strolch.li/download/Recent content in Download on StrolchHugo -- gohugo.ioen-us \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 479df59..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/fonts/Inconsolata.eot b/public/fonts/Inconsolata.eot deleted file mode 100644 index 0a705d6..0000000 Binary files a/public/fonts/Inconsolata.eot and /dev/null differ diff --git a/public/fonts/Inconsolata.svg b/public/fonts/Inconsolata.svg deleted file mode 100644 index 36775f0..0000000 --- a/public/fonts/Inconsolata.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/fonts/Inconsolata.ttf b/public/fonts/Inconsolata.ttf deleted file mode 100644 index 4b8a36d..0000000 Binary files a/public/fonts/Inconsolata.ttf and /dev/null differ diff --git a/public/fonts/Inconsolata.woff b/public/fonts/Inconsolata.woff deleted file mode 100644 index 6f39625..0000000 Binary files a/public/fonts/Inconsolata.woff and /dev/null differ diff --git a/public/fonts/Novecentosanswide-Normal-webfont.eot b/public/fonts/Novecentosanswide-Normal-webfont.eot deleted file mode 100644 index 9984682..0000000 Binary files a/public/fonts/Novecentosanswide-Normal-webfont.eot and /dev/null differ diff --git a/public/fonts/Novecentosanswide-Normal-webfont.svg b/public/fonts/Novecentosanswide-Normal-webfont.svg deleted file mode 100644 index 6fa1a66..0000000 --- a/public/fonts/Novecentosanswide-Normal-webfont.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/fonts/Novecentosanswide-Normal-webfont.ttf b/public/fonts/Novecentosanswide-Normal-webfont.ttf deleted file mode 100644 index 8cfb62d..0000000 Binary files a/public/fonts/Novecentosanswide-Normal-webfont.ttf and /dev/null differ diff --git a/public/fonts/Novecentosanswide-Normal-webfont.woff b/public/fonts/Novecentosanswide-Normal-webfont.woff deleted file mode 100644 index d5c4290..0000000 Binary files a/public/fonts/Novecentosanswide-Normal-webfont.woff and /dev/null differ diff --git a/public/fonts/Novecentosanswide-Normal-webfont.woff2 b/public/fonts/Novecentosanswide-Normal-webfont.woff2 deleted file mode 100644 index eefb4a3..0000000 Binary files a/public/fonts/Novecentosanswide-Normal-webfont.woff2 and /dev/null differ diff --git a/public/fonts/Novecentosanswide-UltraLight-webfont.eot b/public/fonts/Novecentosanswide-UltraLight-webfont.eot deleted file mode 100644 index 2a26561..0000000 Binary files a/public/fonts/Novecentosanswide-UltraLight-webfont.eot and /dev/null differ diff --git a/public/fonts/Novecentosanswide-UltraLight-webfont.svg b/public/fonts/Novecentosanswide-UltraLight-webfont.svg deleted file mode 100644 index c4e903b..0000000 --- a/public/fonts/Novecentosanswide-UltraLight-webfont.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/fonts/Novecentosanswide-UltraLight-webfont.ttf b/public/fonts/Novecentosanswide-UltraLight-webfont.ttf deleted file mode 100644 index 9ce9c7f..0000000 Binary files a/public/fonts/Novecentosanswide-UltraLight-webfont.ttf and /dev/null differ diff --git a/public/fonts/Novecentosanswide-UltraLight-webfont.woff b/public/fonts/Novecentosanswide-UltraLight-webfont.woff deleted file mode 100644 index 381650c..0000000 Binary files a/public/fonts/Novecentosanswide-UltraLight-webfont.woff and /dev/null differ diff --git a/public/fonts/Novecentosanswide-UltraLight-webfont.woff2 b/public/fonts/Novecentosanswide-UltraLight-webfont.woff2 deleted file mode 100644 index 7e65954..0000000 Binary files a/public/fonts/Novecentosanswide-UltraLight-webfont.woff2 and /dev/null differ diff --git a/public/fonts/Work_Sans_200.eot b/public/fonts/Work_Sans_200.eot deleted file mode 100644 index 4052e4f..0000000 Binary files a/public/fonts/Work_Sans_200.eot and /dev/null differ diff --git a/public/fonts/Work_Sans_200.svg b/public/fonts/Work_Sans_200.svg deleted file mode 100644 index 0ffbd3a..0000000 --- a/public/fonts/Work_Sans_200.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/fonts/Work_Sans_200.ttf b/public/fonts/Work_Sans_200.ttf deleted file mode 100644 index 68019e1..0000000 Binary files a/public/fonts/Work_Sans_200.ttf and /dev/null differ diff --git a/public/fonts/Work_Sans_200.woff b/public/fonts/Work_Sans_200.woff deleted file mode 100644 index a1bd9e4..0000000 Binary files a/public/fonts/Work_Sans_200.woff and /dev/null differ diff --git a/public/fonts/Work_Sans_200.woff2 b/public/fonts/Work_Sans_200.woff2 deleted file mode 100644 index 20c68a7..0000000 Binary files a/public/fonts/Work_Sans_200.woff2 and /dev/null differ diff --git a/public/fonts/Work_Sans_300.eot b/public/fonts/Work_Sans_300.eot deleted file mode 100644 index ace7993..0000000 Binary files a/public/fonts/Work_Sans_300.eot and /dev/null differ diff --git a/public/fonts/Work_Sans_300.svg b/public/fonts/Work_Sans_300.svg deleted file mode 100644 index 7d29367..0000000 --- a/public/fonts/Work_Sans_300.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/fonts/Work_Sans_300.ttf b/public/fonts/Work_Sans_300.ttf deleted file mode 100644 index 35387c2..0000000 Binary files a/public/fonts/Work_Sans_300.ttf and /dev/null differ diff --git a/public/fonts/Work_Sans_300.woff b/public/fonts/Work_Sans_300.woff deleted file mode 100644 index 8d789ea..0000000 Binary files a/public/fonts/Work_Sans_300.woff and /dev/null differ diff --git a/public/fonts/Work_Sans_300.woff2 b/public/fonts/Work_Sans_300.woff2 deleted file mode 100644 index f6e216d..0000000 Binary files a/public/fonts/Work_Sans_300.woff2 and /dev/null differ diff --git a/public/fonts/Work_Sans_500.eot b/public/fonts/Work_Sans_500.eot deleted file mode 100644 index 9df6929..0000000 Binary files a/public/fonts/Work_Sans_500.eot and /dev/null differ diff --git a/public/fonts/Work_Sans_500.svg b/public/fonts/Work_Sans_500.svg deleted file mode 100644 index 90a91c1..0000000 --- a/public/fonts/Work_Sans_500.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/fonts/Work_Sans_500.ttf b/public/fonts/Work_Sans_500.ttf deleted file mode 100644 index 5b8cc53..0000000 Binary files a/public/fonts/Work_Sans_500.ttf and /dev/null differ diff --git a/public/fonts/Work_Sans_500.woff b/public/fonts/Work_Sans_500.woff deleted file mode 100644 index df05851..0000000 Binary files a/public/fonts/Work_Sans_500.woff and /dev/null differ diff --git a/public/fonts/Work_Sans_500.woff2 b/public/fonts/Work_Sans_500.woff2 deleted file mode 100644 index b06c54d..0000000 Binary files a/public/fonts/Work_Sans_500.woff2 and /dev/null differ diff --git a/public/google052dbec2d053a4e1.html b/public/google052dbec2d053a4e1.html deleted file mode 100644 index c2d9222..0000000 --- a/public/google052dbec2d053a4e1.html +++ /dev/null @@ -1 +0,0 @@ -google-site-verification: google052dbec2d053a4e1.html \ No newline at end of file diff --git a/public/history/index.html b/public/history/index.html deleted file mode 100644 index ec2130b..0000000 --- a/public/history/index.html +++ /dev/null @@ -1,3 +0,0 @@ -History - Strolch

    History

    Overview

    Strolch is an open source component based software agent written in Java and can be compared, in a light sense, with the Java EE stack: Strolch takes care of persistence, implements Services for use cases, Commands as re-usable algorithms and has a parameterized data model.

    Strolch has an intrinsic understanding for mandates, which are called realms so that a single agent can be used to implement applications with multiple users/customers for instance in SaaS environments.

    The parameterized data model consists of three top level objects, Resources, Orders and Activities. These objects can have any number of ParameterBags which in turn can have any number of Parameters on them. This allows for a very dynamic modelling of data structures including modification at run time. Multiple ready to use Parameter types are already implemented which handle the primitive types in Java including ListParameters for collections of these primitive types.

    One of the main features of the Strolch agent, is that persistence is handled transparently and the user must not be worried about databases and the likes. Currently there are two implementations for persisting the Strolch model, a PostgreSQL and an XML file persistence. Currently both persistence layers persist the data by converting to XML and storing it into the database. The XML file persistence stores each object in its own file.

    The agent itself has a small memory footprint and requires very few components to start. For the agent to be useful it needs additional functionality which is implemented in StrolchComponents. Each component is registered via its Java interface on the agent and is bound to the life cycle of the agent. When the agent is started, these components can be retrieved and used to perform any number of functionalities. This is the preferred way to extend the Strolch agent. There are a number of components already implemented, e.g. the ServiceHandler which executes Services in a controlled fashion and can validate authorized access to these services.

    No software product is complete without a system for authentication and authorization. Strolch implements this by using the Privilege framework which has been written by Robert von Burg. The standard ServiceHandler detects the existence of the PrivilegeHandler and then validates that the user has authorization to perform the service. This framework is implemented as its own Strolch component, thus can be retrieved at any time during execution to perform fine grained and special authorization validation.

    Motivation

    A question often asked is why create Strolch. What are its benefits in contrast to using Java SE with an OR-Mapper like Hibernate, or using Java EE on JBoss or Glassfish? Especially since many of the features existing in those stacks needed to be re-created in Strolch.

    The first answer to this question is that those systems are often overly complicated and bloated. Java SE with Hibernate certainly is a viable option when it comes to being light-weightier but Hibernate, even though it is supposed to, often fails to truly help remove the need to really understand an RDBMS. Often enough Hibernate will just get in the way of the most important part of development: writing the business code. Being an OR-Mapper which is supposed to implement all the nitty-gritty details of an RDBMS system, Hibernate, and JPA for that matter, still often has the developer go back to understanding these details.

    Strolch tries a different approach to persistence. Instead of writing pojos/entities, Strolch’s model has the concept that each element’s attributes are part of a composition pattern: each attribute is its own object and thus can be dynamically changed at runtime, but also makes persistence of such an element generic. Instead of having fixed attributes for a concrete class, these parameters are stored in a map and are accessed through the parameter’s ID.

    Assigning an ID to an attribute for accessing of course brings its own downsides, i.e. the parameter might simply not be there, when being accessed. This is certainly an issue that the developer must handle, when implementing a project using Strolch, but allows the developer to not need to worry about persistence, as this is generically handled.

    Since the persistence is generically handled, and Strolch stays lightweight on its requirements at runtime, the developer can quickly get down to what is important for business value: Writing the business logic and the presentation layer. Here too Strolch tries to help the developer by bringing in concepts which are easy to follow: Use cases are implemented as Services, and re-usable business logic is put into Commands.

    There will be reasons against using Strolch, as there will be against using the Java EE stack, or an OR-Mapper or even the Java ecosystem for that fact. Important is to note, that the concepts behind Strolch are nothing new, but have been implemented in at least two previous proprietary products. Since those products are not accessible to the public, it was decided that a re-implementation might be of use to the programming community at large.

    Currently, there is at least one company using Strolch in a commercial project which helps drive Strolch’s development and further motivates its existence.

    Strolch is an open source project and licensed under the Apache License 2.0.

    ##Technology -Strolch is written in Java and is programmed against the JDK 8. Strolch runs on any JRE 8 compliant environment. Strolch is tested on the Oracle JRE 8.

    \ No newline at end of file diff --git a/public/history/index.xml b/public/history/index.xml deleted file mode 100644 index 8a3a7a4..0000000 --- a/public/history/index.xml +++ /dev/null @@ -1 +0,0 @@ -History on Strolchhttps://strolch.li/history/Recent content in History on StrolchHugo -- gohugo.ioen-us \ No newline at end of file diff --git a/public/images/clippy.svg b/public/images/clippy.svg deleted file mode 100644 index f455173..0000000 --- a/public/images/clippy.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/public/images/favicon.png b/public/images/favicon.png deleted file mode 100644 index df06e35..0000000 Binary files a/public/images/favicon.png and /dev/null differ diff --git a/public/images/gopher-404.jpg b/public/images/gopher-404.jpg deleted file mode 100644 index 2a50543..0000000 Binary files a/public/images/gopher-404.jpg and /dev/null differ diff --git a/public/index.html b/public/index.html deleted file mode 100644 index 616188c..0000000 --- a/public/index.html +++ /dev/null @@ -1,28 +0,0 @@ -Strolch Overview - Strolch
    navigation

    strolch_mascot_head.png

    Strolch Overview

    Strolch is framework for developing Software. It’s main features are:

    • Complete persisted data model:
      • Parameters and values by time
      • Resources, Orders with arbitrary parameter grouping
      • Activity/Action hierarchy with arbitrary depth
      • Policies for delegation
      • JSON as well as XML transformation
      • Locator API
    • Transactions with pessimistic locking and optional read-locking
    • Search API
    • Component based
    • Deeply integrated privilege handling
    • Fully in-memory
    • Persisted auditing, versioning, operations log
    • DAOs for file system or PostgreSQL, easily extended
    • Execution framework
    • Service / Command oriented
    • Reporting API configured by Resource objects
    • REST API for data access
    • WebComponents UI for
      • Inspector
      • Users
      • Roles
      • Operations Log
      • Login Screen
      • Jobs
    • runs on plain old Java SE

    Strolch Intro

    It is a different framework to Spring and other similar type of Java -frameworks, as the model is defined as an abstract model, where you -always have the same three types of objects: Resources, Orders and -Activities. The fields are mapped as Parameter objects, of which the -important primitives are available.

    The nice part about this framework is, that you can be up and ready in -a matter of minutes, and start building your project immediately in -that you open your favourite XML editor and start modelling your data.

    Once your data is defined, you write your business logic in the form -of Services, Commands and Searches. There are many predefined services -and commands to manipulate the object model, so that you write your own -services when you need to enforce special business rules.

    Through the use of Policy objects, you decouple algorithms from your -object model, so that at runtime you can change the behaviour, or -easily implement different behaviour depending on your use-case. For -instance you might have a simple billing service which performs a few -preparatory steps, and then calls the configured billing policy to -execute the billing depending on the customer, the warehouse, etc.

    And of course persistence is as simple as configuring the persistence -handler, pointing to your RDBMS and then setting the mode to CACHED. -For you as a developer there is no more thinking in terms of SQL etc., -as this is completely hidden from the developer. There is even a simple -file persistence layer if you are running IoT devices.

    The runtime can be just about anything. Usually it is run inside an -Apache Tomcat instance as a webapp, as a WEB UI has been required for -all current Strolch projects. You could just as well use a main class. -Accessing the Strolch Agent remotely is usually done through REST.

    Strolch is being actively developed, and customers constantly give us -reasons to improve and extend the framework. There is a Polymer -Inspector component which makes it easy to see and manipulate the -actual data. The new Search API makes it really easy to query your data.

    Yes, Strolch is different, but the concept has come out of the planning -and execution segment, and has been refined over the years until it has -become what it is today.

    API

    Check out the API page to see how to use Strolch.

    More to motivation etc.

    \ No newline at end of file diff --git a/public/index.json b/public/index.json deleted file mode 100644 index 17c9de0..0000000 --- a/public/index.json +++ /dev/null @@ -1 +0,0 @@ -[{"uri":"https://strolch.li/blog/post-00018/","title":"Strolch PLC 1.2.3 released","tags":[],"description":"Strolch PLC version 1.2.3 has been deployed to Maven Central","content":"Strolch PLC 1.2.3 released Strolch PLC version 1.2.3 has been deployed to Maven Central'\n This is a maintenance release, as 1.2.2 pointed to Strolch 1.8.4 which was not released to Maven Central.\n"},{"uri":"https://strolch.li/blog/post-00017/","title":"Strolch 1.8.5 and PLC 1.2.2 are out","tags":[],"description":"JDK 17 ready","content":"Strolch 1.8.5 and PLC 1.2.2 are out JDK 17 ready!\n Unbelievable, but the entire 1.7.x branch was never blogged about or deployed to Maven. We did do quite a few releases of the Java 11 version, but never got around to releasing to Maven.\nNow we have released the 1.8.x branch of Strolch and deployed to Maven Central.\nThe 1.8.x branch requires JDK 17, but is still on Tomcat 9.x. We will create a new branch for Tomcat 10.x and release that at a later date.\nWe also just released the Strolch PLC 1.2.x branch. This branch uses Strolch 1.8.x and is production ready.\nSo, Strolch 1.8.5 is out the door, go ahead and try it out.\n"},{"uri":"https://strolch.li/blog/post-00016/","title":"Strolch PLC now also on Maven Central","tags":[],"description":"Strolch PLC version 1.0.7 has been deployed to Maven Central for easier integration into your projects","content":"Strolch PLC now also on Maven Central Strolch PLC version 1.0.7 has been deployed to Maven Central for easier integration into your projects\n To more easily use Strolch PLC in your project, we have now deployed the latest Strolch PLC version to Maven Central. This version 1.0.7 depends on Strolch version 1.6.100.\nEnjoy coding!\n"},{"uri":"https://strolch.li/blog/post-00015/","title":"Release of Strolch 1.6.100","tags":[],"description":"The 100. release of the 1.6 branch and a brand new website!","content":"Release of Strolch 1.6.100 The 100. Strolch release of the 1.6 branch and a brand new website!\n Ok, so Maven doesn\u0026rsquo;t exactly have 100 releases on it, but even though we have been quiet on public releases, Strolch has seen many refactorings, fixes, new features etc. over the past three years of its last release.\nSome notable changes:\n I18n Support for StrolchExceptions. Better performance for reports on large joins. Move to JDK 11+. Refactoring to use of Java 9 LocalDateTime and ZonedDateTime where applicable. Added Controllers for better execution handling. Significantly simplified the methods to change the model. Simpler methods to retrieve relationship entities. Updated most libraries to their latest versions. Added a DataArchiveHandler to archive entities. Added require password change feature, and storing of login and password change history LDAP integration Added session keep alive Search expression simplifications New TextParameter for when persisting large values with whitespace and special characters Basic Auth for REST APIs, if no UI needed for scripting Many additional fixes, tweaks and helper functions Another new addition to the Strolch family is Strolch PLC. The Strolch PLC code allows one to use the same model but on a device acting as a soft PLC, e.g. a Raspberry Pi. This PLC code can then communicate using WebSockets with a Strolch instance, having quite seamless interaction with Activities which really shows the potential of using Strolch\u0026rsquo;s model in the shop floor.\nWe\u0026rsquo;ve been running the Strolch PLC in a mission critical shop floor application to control conveyors which are filled by a dispensing robot.\nSo, Strolch 1.6.100 is out the door, go ahead and try it out.\n"},{"uri":"https://strolch.li/blog/post-00014/","title":"Strolch Reports","tags":[],"description":"Strolch can do reports!","content":"Strolch Reports Strolch can do reports!\n A feature we haven\u0026rsquo;t written about yet is the report API. Strolch has it\u0026rsquo;s own API to generate reports of data, and since we have a generic model, we use Resource of type Report to define them.\nGo check out the documentation and then enjoy using this easy way to deliver the reports your peers require.\n"},{"uri":"https://strolch.li/blog/post-00013/","title":"Strolch Searches","tags":[],"description":"Strolch queries are deprecated!","content":"Strolch Searches Strolch queries are deprecated!\n Strolch has had once again many changes, and fixes etc. One important thing to note is that we have removed support for transactional mode and have rewritten how models are searched. Thus the search API was born.\nGo check out the Strolch Search documentation and then go rewrite your searches =)).\nStrolch tag 1.6.51 has all those juicy changes!\n"},{"uri":"https://strolch.li/blog/post-00012/","title":"Wow, the many changes!","tags":[],"description":"So many changes, and so long no update - not good!","content":"Wow, the many changes! So many changes, and so long no update - not good!\n Oh boy, have we forgotten to update you all on the latest awesome features in Strolch! There are over 123 commits since the last tag 1.3.0, so that alone merits a new blog post.\nCurrently the latest tag is 1.5.5, but this version is actually already quite old, as it was created on 31. January 2017 and there are 53 new commits ahead of the tag.\nEnough of all the commits, lets get to the new features:\n Added new generic report creator Added Activity.TimeOrdering and updated Model XSD Implemented State Model on Activity/Actions Implemented execution of Activities Implemented EventBasedExecutionHandler Added StrolchXmlParser to quickly parse from a file Add Activity.remove(String) to remove an element Refactored LockHandler to use Locator Added Activity.getActionsWithState(State) Moved *ToFlat and *FromFlat Json Visitors to strolch model Added StrolchElementQuery.internal() Added Parameter.clearValue() and list parameters use , as sep Json Tags are now in Tags.Json and are drinking camel-case Moved PrivilegeAddUserService to command, added tests Lots of JavaDoc updates Refactored code for REST Inspector to use gson Added inspector REST api for activities Inspector now has offset/limit for queries Added new StringMapArgument for StrolchServices Added missing activity observer calls in AbstractTransaction Added StringMapResult to use as a ServiceResult Removed many visitors and implemented proper visitor pattern\u0026hellip; Don\u0026rsquo;t log stack trace if certificate does not exist SmtpMailer now understands whitelists for override Fixed locator finding for Activity and Action Fixed undo logic for general commands To summarize, execution and reporting are the two new features that make Strolch really awesome! We use execution to perform a number of actions on a remote device connected to a Strolch agent through WebSockets. This allows serial and parallel execution of actions and of course locking of concurrently used resources.\nIn an enterprise world reports can never be missed, so we needed an API to create reports. Of course that API was created in a way that all things are done in Strolch: generically. Thus a report is created as a Resource, defining the report object, columns and any relevant joins.\nAnd one of the really cool things is that we have started with a UI for Strolch. There is now an Inspector with which the entire data model of a running agent can be seen. This inspector is built using Polymer and WebComponents and thus can be easily embedded in your application.\nTo facilitate the authentication of a user for the inspector, an authentication component was created as well. And of course i18n can\u0026rsquo;t be forgotten, so there is a component for that too.\nTo simplify tasks in a web project, there is also a StrolchJs repository where certain Strolch specific things are handled e.g. querying the authenticated user\u0026rsquo;s roles etc.\nThe release of the next Strolch version isn\u0026rsquo;t defined yet, as we are internally building a project on all these changes and with the release 1.0.0 of that project (which will be soon), we shall perform the next release of Strolch.\nUntil then, happy coding!\n"},{"uri":"https://strolch.li/blog/post-00011/","title":"Strolch now on Maven Central","tags":[],"description":"Release Version 1.3.0 released and deployed to Maven Central","content":"Strolch now on Maven Central Release Version 1.3.0 released and deployed to Maven Central\n We have released a new version of Strolch so that you can now go and use the the latest features in Strolch.\nFurther we have now deployed Strolch to Maven Central, so it is easier than ever to use Strolch in your projects. No need to download first or use a special repository - just define the dependencies as you would any other dependency.\nSome of the new features:\n Marshallers for JSON Versioning built into Strolch Implemented password reset API for Privilege New Component MailHandler New ToFlatJsonVisitor for simple marshalling in REST APIs Added CRUD Commands and Services for Activities Further additional bugfixes Strolch has also been moved to another organisation on GitHub, so if you\u0026rsquo;re compiling Strolch from source, please update your GIT remote configurations.\nHave fun using the latest and greatest version of Strolch!\n"},{"uri":"https://strolch.li/blog/post-00010/","title":"Versioning of objects","tags":[],"description":"Opt-In versioning of objects","content":"Versioning of objects Opt-In versioning of objects\n A major new feature has landed in Strolch. Now, using opt-in, it is possible to have all changes to the object model be versioned. This means that any change to Order, Resource or Activity is automatically versioned and one can then revert to this version later on.\nThis will make it far easier to implement undo operations in applications since it is an inherent part of the lifecycle of objects in Strolch.\nSince Strolch is supposed to be used also in small footprint hardware, this option is opt-in.\nA side affect of this new feature is that we have for the time being not ported the XML persistence layer. If this is required, then someone drop us a note and we\u0026rsquo;ll check on it.\nSo now go ahead and add \u0026lt;enableVersioning\u0026gt;true\u0026lt;/enableVersioning\u0026gt; to your Realm so that versioning is enabled.\n"},{"uri":"https://strolch.li/blog/post-00009/","title":"Release 1.2.0","tags":[],"description":"Release of Strolch 1.2.0","content":"Release 1.2.0 Release of Strolch 1.2.0\n A few months ago we informed of the soon to be released version 1.1.0. Well, we decided to jump to 1.2.0 because we did some refactorings. All the eitchnet projects have been melted into Strolch and thus now it\u0026rsquo;s all one nice package. This will result in simpler development and less constraints on APIs between the two projects.\nOther than that, not much changed, but we are continually working on Strolch, so go grab your latest copy and have fun coding!\n"},{"uri":"https://strolch.li/blog/post-00008/","title":"Strolch Update","tags":[],"description":"Long due update on Strolch development.","content":"Strolch Update Long due update on Strolch development.\n Although we have been rather quiet in the last couple of months, anyone viewing Strolch\u0026rsquo;s commit log, will see that we certainly didn\u0026rsquo;t halt Strolch development.\nWe have been hard at work, using Strolch in projects, which required many new features and fixes. The commit log shows as of today over 180 commits since the release tag 1.0.0.\nSome of the most exciting changes are:\n REST API to query model, incl. privilege management. JSON marshalling of all elements. Added Policies Added persisting of user sessions. New JavaScript based UI to view Strolch\u0026rsquo;s model. This is an initial version and more UI elements and functions will follow. Basic planning engine functionality. Further new features and changes are:\n Implemented a REST API to the privilege management - Now users can be added, changed, etc. via call to the appropriate URL under ../strolch/privilege/*. Implemented a REST API to query the user sessions. Incl. invalidating sessions to forcefully logout users. Implemented a REST API to query Audits. Implemented REST API to query Orders, Resources and Activities/Actions Implemented REST API to update Resources and Orders from XML REST API to authenticate now adds a cookie, so authorization is much simpler. Added convenience methods in Service and Command to easily perform system user actions. Added audits for login/logout of users. Added audits for changes to privilege management. PostgreSQL persistence layer now uses HikariCP for connection pooling. Implemented a performance test project Added new Parameters of type IntegerList, FloatList and LongList. Added feature to ignore a realm on DB init. Implemented core planning functionality. Added strolch_minimal and strolch_minimal_rest projects to easily get started. Query API now has built in ordering. Added Policy to all root elements. Added new planning web app project. This is a test application for demoing the planning engine functionality of Strolch. Adding the persisting and reloading of user sessions, so that a new start of Strolch does not logout users. Implemented to JSON visitors for all root elements. So, although we\u0026rsquo;ve been rather quiet on the blog and on social media, we have not been quiet in Strolch\u0026rsquo;s development. We are planning to release version 1.1.0 soon, so stay tuned!\n"},{"uri":"https://strolch.li/blog/post-00007/","title":"Activities: Beginning of the planning engine","tags":[],"description":"The ground work of the Strolch planning engine has been laid.","content":"Activities: Beginning of the planning engine The ground work of the Strolch planning engine has been laid.\n One of the core ideas in building Strolch was to create a planning engine. The planning engine would work in combination of Order objects representing customer orders, Resource objects representing machines, human resources, etc., and Activity/Action hierarchies defining a workflow.\nWith the latest couple of commits to Strolch we have now added Activities and a basic planning of Actions onto Resources. Activities have an ordered list of IActivityElement which allows creating an arbitrary deep tree structure of Activity and Action elements.\nAction objects have a list of IValueChange objects which define the start, end and further value changes over time on a referenced Resource. Thus planning an Activity is done by iterating the Activity hierarchy and for every Action selecting a relevant Resource and then then applying the changes of the Action on to the referenced TimeState on the Resource.\nThis implementation is currently very simple as it ignores all constraints which a Resource might have. In further development we shall implement a Violation model so that UIs can be built to visualize the over-use of Resources.\nIn even further steps we would then start implementing algorithms to not just apply the changes onto a Resource, but to actually search the Resource for time slots when the value changes would not violate any constraints applied to the resource.\nWe are very much looking forward to these new features. Stay tuned for your updates - even though they do take their time to arrive =).\n"},{"uri":"https://strolch.li/blog/post-00006/","title":"Strolch Documentation","tags":[],"description":"Any good software has some decent documentation explaining concepts, best practices and gives examples.","content":"Strolch Documentation Any good software has some decent documentation explaining concepts, best practices and gives examples.\n So this post is to announce that there is now a new page on Strolch\u0026rsquo;s website with a bit of documentation. This first documentation explains the Strolch runtime and some of the do and don\u0026rsquo;t in Strolch code.\nBear with us, writing documentation takes time and can be outdated quickly, so we will make an effort to keep everything up to date and add more documentation, but this is a start.\nSo go ahead and read the documentation , and if you haven\u0026rsquo;t already, also read the rest of the website which should give some more insight into the what, why and how of Strolch.\n"},{"uri":"https://strolch.li/blog/post-00005/","title":"Strolch Release 1.0.0","tags":[],"description":"Finally Version 1.0.0 of Strolch has been released and can be downloaded immediately.","content":"Strolch Release 1.0.0 Finally Version 1.0.0 of Strolch has been released and can be downloaded immediately.\n Before 1.0.0 could be released, some major changes were decided, all driven by the first big project using Strolch as its underlying stack. Those changes were minor, and really major, but should make Strolch better and was important for the first release.\nHere is a list of the most interesting changes:\n Java 8 - Strolch was ported to Java 8. This gives a lot of cool features: The stream API, lambdas, the new time API, etc. TX refactoring: Strolch transactions are instances of Closeable so that they are closed using a try-with-resource block in Java7. The change that was required was to not auto commit. Now a TX is read-only and one has to set the auto commit as the last statement. See this commit for more information. Added a tx.flush() to allow an implementation to flush part of a transaction, this feature is vital to perform parts of a transaction before deciding if the TX should be committed. Fixed the issue where data store mode CACHED performed TRANSACTIONAL queries, instead of staying in-memory. ParameterSelection.stringListSelection() uses a StringMatchMode instead of just equals() ParameterSelection.dateRangeSelection() uses a DateRange instead of just equals() Added the MigrationsHandler to use to perform code migrations of production data bases where data shouldn\u0026rsquo;t go lost. And many more\u0026hellip; Strolch 1.1.0 is already in development and can also be downloaded from the download page. Here you can see the current change list on GitHub. For instance heavy work has been done to implement privilege management by adding a REST API. Looking forward to a wonderful next Strolch release.\n"},{"uri":"https://strolch.li/blog/post-00004/","title":"DurationParameter and other minor changes: Release 1.0.0-RC4","tags":[],"description":"New DurationParameter and additional minor changes: Release of 1.0.0-RC4 which can be downloaded on the download page.","content":"DurationParameter and other minor changes: Release 1.0.0-RC4 New DurationParameter and additional minor changes: Release of 1.0.0-RC4 which can be downloaded on the download page.\n While implementing a use case in a Strolch based application it was detected that an essential parameter type was missing, the DurationParameter. This parameter currently stores the value as a long in memory and serializes to ISO8601. As soon as we move Strolch to Java8, we will change this to use the Period class in the new Java8 date and time API.\nIn addition to the new parameter, a couple of other changes were made:\n 32c1785 [Major] Added Session timeout handling d55371e [Minor] fixed component version descriptions c1cdfbb [Bugfix] added missing cloning of StringSetTimedState in Resources 8f50a15 [Major] changed XML format of time value of TimedStates to be ISO8601 5fbbe50 [Bugfix] fix NPE when cloning Resources with no state vars b77f4b2 [New] added TimeVariable.clear()-method Updated sub-module ch.eitchnet.utils to 906d24d Updated sub-module ch.eitchnet.privilege to aa16887 So, Strolch 1.0.0-RC4 is out the door, go ahead and try it out.\n"},{"uri":"https://strolch.li/blog/post-00003/","title":"DB Initialization: Release 1.0.0-RC3","tags":[],"description":"Important feature Database Initialization added: Release of 1.0.0-RC3 which can be downloaded on the download page.","content":"DB Initialization: Release 1.0.0-RC3 Important feature Database Initialization added: Release of 1.0.0-RC3 which can be downloaded on the download page.\n When living continuous integration and continuous delivery, it is vital that things like database migrations and initialization are performed in a controlled, but automatic way.\nA Strolch-based application is using the PostgreSQL persistence layer. The implementation understands the concepts of migration, and validating the database schema, but currently a mechanism to automatically initialize the database with a minimal set of data was missing.\nMigrating a database for Strolch is mostly a one time thing. The object model in Strolch is quite static, so there is seldom a need to migrate the database. Domain specific changes, i.e. new Resources, or adding Parameters to Resources, is not a schema change. Thus, instead of going the way other frameworks go, e.g. Ruby on Rails, we built the data initialization right into the PersistenceHandler.\nNow if the PostgreSQL PersistenceHandler creates the schema, then it might also initialize the minimal set of data. For this to work, the PersistenceHandler checks if the flags allowSchemaCreation, allowSchemaDrop and allowDbInitOnSchemaCreate. If those flags are enabled, and the schema was created during initialization, then the database is also initialized with the contents of the XML file configured under key dataStoreFile of the relevant Realm.\nThe database initialization is done as a system user action which must have the name db_initializer. This is another fail-safe, so that on a production system, this user can simply be deleted.\nSo, Strolch 1.0.0-RC3 is out the door, go ahead and try it out.\n"},{"uri":"https://strolch.li/blog/post-00002/","title":"Release 1.0.0-RC2","tags":[],"description":"Scratch that RC1, here is the brand new 1.0.0-RC2 which can be downloaded on the download page.","content":"Release 1.0.0-RC2 Scratch that RC1, here is the brand new 1.0.0-RC2 which can be downloaded on the download page.\n So, as expected there were a few bugs, for instance the Strolch tutorial apps didn\u0026rsquo;t start, so now i fixed those and released an RC2. Go get it and give it a try!\n"},{"uri":"https://strolch.li/blog/post-00001/","title":"Release 1.0.0-RC1","tags":[],"description":"With the Go-Live of a Strolch-based application around the corner, it is time to release Version 1.0.0 of Strolch. To this affect we have now released version 1.0.0-RC1 which can be downloaded on the download page.","content":"Release 1.0.0-RC1 With the Go-Live of a Strolch-based application around the corner, it is time to release Version 1.0.0 of Strolch. To this affect we have now released version 1.0.0-RC1 which can be downloaded on the download page.\n Story Strolch as a component based software agent has been two years in the making. The concepts in Strolch have been taken from a proprietary planning, scheduling and controlling software agent, which was, and is been, used in industrial automation, logistics and production. Strolch was created to bring the concepts, which were working well for small teams to go-live with large projects in short to medium time-frames to the open source world.\nStrolch was completely rewritten using the key concepts of a parameterized object model and a component based agent but remembering which clutches the original implementation had, thus trying to eradicate those without bringing in new ones. It might not be perfect in version 1.0.0, but it is a starting point form which to carry on from.\nFeatures Strolch isn\u0026rsquo;t feature complete by a long shot, but it sure has got many features which make it useable in a concrete project, thus making sure it is not vaporware =)\nThe following is a list of key features, many of which were driven by concrete project requirements:\n Separate containers for models (mandates) Parameterized model with full CRUD for Resource and Order objects Timed values on Resources to map values by time Built-in versioning of model - configurable by Realm Transparent runtime modes: TRANSIENT, CACHED, TRANSACTIONAL* Service and Command pattern for reusing functionality XML File based persistence layer* PostgreSQL persistence layer* Querying using a fluent API Services to import and export a model to XML Integrated authentication and authorization to validate user privileges using Privilege Ready to use Observer pattern (currently) Read-only REST API to access the agent model remotely Configurable environments Opt-in audit trail (including read access, and the audits themselves) Basic components required to communicate with external devices using TCP/IP With the light weight implementation, where there are basically no third party libraries required for the normal runtime, Strolch has a minimal foot print which allows it to run on small devices for instance a BeagleBone Black. Using the in-memory mode, it is an easy feat to set up test environments with little to no further requirements than the JVM. Future So what is planned for the future? Although Strolch has quite a few interesting features, it is by no way feature complete. The greatest wish is for Strolch to become a community driven platform, so many new features will arise in the future, but at least one major future feature which will be tackled in the near future and will certainly drive the next major release is a planning and scheduling engine using a Gantt chart to visualize the schedule.\nThe planning engine will use the timed values on Resources extensively to create a planning engine on which Workflows can be placed and allowing to detect violations and bottlenecks.\nAn extension of the planning of the scheduling engine will allow more than just placing Workflows on Resources, but actually searching groups of Resources for a time slot of when to place tasks. This will allow to use capacity constraints to plan and schedule workflows using different algorithms, and respecting calendars etc.\nFurther time will be spent on giving Strolch it\u0026rsquo;s own UI. Currently the idea is to use Google\u0026rsquo;s Polymer to implement the UI, thus creating reusable widgets that can be used in projects.\nTake it for a spin So, now the important part is for new users to start using Strolch for their own projects. Go ahead, check out the Downloads page for the latest release and then checkout the two tutorial applications to get yourself up to speed!\nDon\u0026rsquo;t hesitate to send us feedback or questions, we will be delighted to help you get your Strolch-based application up and running, or provide feedback to your concerns!\nDevelopers Robert von Burg Reto Breitenmoser Dr. Martin Smock\n*Currently Transactional mode is missing concrete implementation for querying for the XML persistence\n"},{"uri":"https://strolch.li/api/","title":"API","tags":[],"description":"","content":"Overview The Strolch API revolves around the StrolchTransaction object. The main concept is to implement your use cases in Service implementations. You open a transaction using the openTx(String)-method and then perform the use case by adding your Command instances to the transaction.\nTransactions are opened on a StrolchRealm. The realms are used to separate mandates in a single runtime instance of Strolch. Each realm has its own ResourceMap, OrderMap, ActivityMap instances from which the TX retrieves the elements.\nModel The Strolch model is implemented in the project li.strolch.model.\nThe Strolch model consists of three root level elements: Resource, Order and Activity. Each element has at least the following attributes:\n Id → the element\u0026rsquo;s id Name → the element\u0026rsquo;s name Type → the element\u0026rsquo;s type Each root element can have any number of ParameterBag instances on it, which in turn can have any number of Parameters on it. Accessing these objects is always done by their IDs. Strolch root elements are always stored in the respective ElementMaps in their Strolch realm. Thus accessing a certain parameter from a Resource would look like this:\npublic class Test { public static void main(String[] args) { try (StrolchTransaction tx = openTx(realmName)) { Resource resource = tx.getResourceBy(\u0026#34;MyType\u0026#34;, \u0026#34;myResource\u0026#34;); ZonedDateTime date = resource.getDate(\u0026#34;myBag\u0026#34;, \u0026#34;myParam1\u0026#34;); logger.info(\u0026#34;myParam date has value \u0026#34; + date); } } } XML Presentation of Strolch\u0026rsquo;s top level elements of Resources:\n\u0026lt;!-- Resource instance --\u0026gt; \u0026lt;Resource Id=\u0026#34;myResource\u0026#34; Name=\u0026#34;Test Name\u0026#34; Type=\u0026#34;MyType\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;parameters\u0026#34; Name=\u0026#34;Parameters\u0026#34; Type=\u0026#34;Parameters\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam2\u0026#34; Name=\u0026#34;StringList Param\u0026#34; Type=\u0026#34;StringList\u0026#34; Value=\u0026#34;Hello, World\u0026#34; /\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam1\u0026#34; Name=\u0026#34;Date Param\u0026#34; Type=\u0026#34;Date\u0026#34; Value=\u0026#34;2012-11-30T18:12:05.628+01:00\u0026#34; /\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam3\u0026#34; Name=\u0026#34;String Param\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;Strolch\u0026#34; /\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;additionalParameters\u0026#34; Name=\u0026#34;Parameters\u0026#34; Type=\u0026#34;Parameters\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam1\u0026#34; Name=\u0026#34;Long Param\u0026#34; Type=\u0026#34;Long\u0026#34; Value=\u0026#34;4453234566\u0026#34; /\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam2\u0026#34; Name=\u0026#34;Integer Param\u0026#34; Type=\u0026#34;Integer\u0026#34; Value=\u0026#34;77\u0026#34; /\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam3\u0026#34; Name=\u0026#34;Float Param\u0026#34; Type=\u0026#34;Float\u0026#34; Value=\u0026#34;44.3\u0026#34; /\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam4\u0026#34; Name=\u0026#34;Boolean Param\u0026#34; Type=\u0026#34;Boolean\u0026#34; Value=\u0026#34;true\u0026#34; /\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;TimedState Id=\u0026#34;myState\u0026#34; Name=\u0026#34;Integer State\u0026#34; Type=\u0026#34;IntegerState\u0026#34;\u0026gt; \u0026lt;Value Time=\u0026#34;0\u0026#34; Value=\u0026#34;1\u0026#34; /\u0026gt; \u0026lt;Value Time=\u0026#34;1\u0026#34; Value=\u0026#34;2\u0026#34; /\u0026gt; \u0026lt;Value Time=\u0026#34;2\u0026#34; Value=\u0026#34;3\u0026#34; /\u0026gt; \u0026lt;/TimedState\u0026gt; \u0026lt;/Resource\u0026gt; XML Presentation of Strolch\u0026rsquo;s top level elements of Orders:\n\u0026lt;!-- Order instance --\u0026gt; \u0026lt;Order Id=\u0026#34;myOrder\u0026#34; Name=\u0026#34;Test Name\u0026#34; Type=\u0026#34;MyOrderType\u0026#34; Date=\u0026#34;2013-11-20T07:42:57.699Z\u0026#34; State=\u0026#34;CREATED\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;parameters\u0026#34; Name=\u0026#34;Parameters\u0026#34; Type=\u0026#34;Parameters\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam2\u0026#34; Name=\u0026#34;StringList Param\u0026#34; Type=\u0026#34;StringList\u0026#34; Value=\u0026#34;Hello, World\u0026#34; /\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam1\u0026#34; Name=\u0026#34;Date Param\u0026#34; Type=\u0026#34;Date\u0026#34; Value=\u0026#34;2012-11-30T18:12:05.628+01:00\u0026#34; /\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam3\u0026#34; Name=\u0026#34;String Param\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;Strolch\u0026#34; /\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;additionalParameters\u0026#34; Name=\u0026#34;Parameters\u0026#34; Type=\u0026#34;Parameters\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam1\u0026#34; Name=\u0026#34;Long Param\u0026#34; Type=\u0026#34;Long\u0026#34; Value=\u0026#34;4453234566\u0026#34; /\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam2\u0026#34; Name=\u0026#34;Integer Param\u0026#34; Type=\u0026#34;Integer\u0026#34; Value=\u0026#34;77\u0026#34; /\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam3\u0026#34; Name=\u0026#34;Float Param\u0026#34; Type=\u0026#34;Float\u0026#34; Value=\u0026#34;44.3\u0026#34; /\u0026gt; \u0026lt;Parameter Id=\u0026#34;myParam4\u0026#34; Name=\u0026#34;Boolean Param\u0026#34; Type=\u0026#34;Boolean\u0026#34; Value=\u0026#34;true\u0026#34; /\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Order\u0026gt; XML Presentation of Strolch\u0026rsquo;s top level elements of Activities:\n\u0026lt;!-- Activity instance --\u0026gt; \u0026lt;Activity Id=\u0026#34;bicycleProduction\u0026#34; Name=\u0026#34;Bicycle Production\u0026#34; Type=\u0026#34;Series\u0026#34;\u0026gt; \u0026lt;Activity Id=\u0026#34;componentProduction\u0026#34; Name=\u0026#34;Production of components\u0026#34; Type=\u0026#34;Series\u0026#34;\u0026gt; \u0026lt;Action Id=\u0026#34;consumeGears\u0026#34; Name=\u0026#34;Gears\u0026#34; ResourceId=\u0026#34;gears\u0026#34; ResourceType=\u0026#34;Article\u0026#34; Type=\u0026#34;Consume\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;objectives\u0026#34; Name=\u0026#34;Production goals\u0026#34; Type=\u0026#34;Objectives\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;quantity\u0026#34; Name=\u0026#34;Quantity\u0026#34; Type=\u0026#34;Float\u0026#34; Value=\u0026#34;1\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;duration\u0026#34; Name=\u0026#34;Duration\u0026#34; Type=\u0026#34;Duration\u0026#34; Value=\u0026#34;PT0S\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Action\u0026gt; \u0026lt;Activity Id=\u0026#34;frameProduction\u0026#34; Name=\u0026#34;Production frame\u0026#34; Type=\u0026#34;Series\u0026#34;\u0026gt; \u0026lt;Action Id=\u0026#34;produce\u0026#34; Name=\u0026#34;Production frame\u0026#34; ResourceId=\u0026#34;frameProduction\u0026#34; ResourceType=\u0026#34;Machine\u0026#34; Type=\u0026#34;Use\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;objectives\u0026#34; Name=\u0026#34;Production goals\u0026#34; Type=\u0026#34;Objectives\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;quantity\u0026#34; Name=\u0026#34;Quantity\u0026#34; Type=\u0026#34;Float\u0026#34; Value=\u0026#34;1\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;duration\u0026#34; Name=\u0026#34;Duration\u0026#34; Type=\u0026#34;Duration\u0026#34; Value=\u0026#34;PT5M\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Action\u0026gt; \u0026lt;Action Id=\u0026#34;toStock\u0026#34; Name=\u0026#34;Frame ToStock\u0026#34; ResourceId=\u0026#34;frame\u0026#34; ResourceType=\u0026#34;Article\u0026#34; Type=\u0026#34;Produce\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;objectives\u0026#34; Name=\u0026#34;Production goals\u0026#34; Type=\u0026#34;Objectives\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;quantity\u0026#34; Name=\u0026#34;Quantity\u0026#34; Type=\u0026#34;Float\u0026#34; Value=\u0026#34;1\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;duration\u0026#34; Name=\u0026#34;Duration\u0026#34; Type=\u0026#34;Duration\u0026#34; Value=\u0026#34;PT1M\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Action\u0026gt; \u0026lt;/Activity\u0026gt; \u0026lt;Activity Id=\u0026#34;brakeProduction\u0026#34; Name=\u0026#34;Herstellen Bremsen\u0026#34; TimeOrdering=\u0026#34;Series\u0026#34; Type=\u0026#34;Series\u0026#34;\u0026gt; \u0026lt;Action Id=\u0026#34;produce\u0026#34; Name=\u0026#34;Production saddle\u0026#34; ResourceId=\u0026#34;saddleProduction\u0026#34; ResourceType=\u0026#34;Machine\u0026#34; Type=\u0026#34;Use\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;objectives\u0026#34; Name=\u0026#34;Production goals\u0026#34; Type=\u0026#34;Objectives\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;quantity\u0026#34; Name=\u0026#34;Quantity\u0026#34; Type=\u0026#34;Float\u0026#34; Value=\u0026#34;1\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;duration\u0026#34; Name=\u0026#34;Duration\u0026#34; Type=\u0026#34;Duration\u0026#34; Value=\u0026#34;PT5M\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Action\u0026gt; \u0026lt;Action Id=\u0026#34;toStock\u0026#34; Name=\u0026#34;Saddle ToStock\u0026#34; ResourceId=\u0026#34;frame\u0026#34; ResourceType=\u0026#34;Article\u0026#34; Type=\u0026#34;Produce\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;objectives\u0026#34; Name=\u0026#34;Production goals\u0026#34; Type=\u0026#34;Objectives\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;quantity\u0026#34; Name=\u0026#34;Quantity\u0026#34; Type=\u0026#34;Float\u0026#34; Value=\u0026#34;1\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;duration\u0026#34; Name=\u0026#34;Duration\u0026#34; Type=\u0026#34;Duration\u0026#34; Value=\u0026#34;PT1M\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Action\u0026gt; \u0026lt;/Activity\u0026gt; \u0026lt;/Activity\u0026gt; \u0026lt;Action Id=\u0026#34;assembly\u0026#34; Name=\u0026#34;Bicycle assemble\u0026#34; ResourceId=\u0026#34;bicycleAssembly\u0026#34; ResourceType=\u0026#34;Assembly\u0026#34; Type=\u0026#34;Use\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;objectives\u0026#34; Name=\u0026#34;Production goals\u0026#34; Type=\u0026#34;Objectives\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;quantity\u0026#34; Name=\u0026#34;Quantity\u0026#34; Type=\u0026#34;Float\u0026#34; Value=\u0026#34;1\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;duration\u0026#34; Name=\u0026#34;Duration\u0026#34; Type=\u0026#34;Duration\u0026#34; Value=\u0026#34;PT5M\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Action\u0026gt; \u0026lt;Action Id=\u0026#34;toStock\u0026#34; Name=\u0026#34;Bicycle to stock\u0026#34; ResourceId=\u0026#34;bicycle\u0026#34; ResourceType=\u0026#34;Product\u0026#34; Type=\u0026#34;Produce\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;objectives\u0026#34; Name=\u0026#34;Production goals\u0026#34; Type=\u0026#34;Objectives\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;quantity\u0026#34; Name=\u0026#34;Quantity\u0026#34; Type=\u0026#34;Float\u0026#34; Value=\u0026#34;1\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;duration\u0026#34; Name=\u0026#34;Duration\u0026#34; Type=\u0026#34;Duration\u0026#34; Value=\u0026#34;PT1M\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Action\u0026gt; \u0026lt;/Activity\u0026gt; Realms Strolch realms implement the multi-client capability which is thus baked right into the Strolch runtime. When configuring a Strolch runtime, realms are configured and for each realm the data store mode is set. Each realm has its own persistence configuration and can thus run in one of the 4 modes that the Strolch agent implements:\n EMPTY This is a transient data store mode, where no model changes are persisted, but they are only kept in memory. When the Strolch agent is started, this realm stays empty as no data is loaded. TRANSIENT This is the same as EMPTY, but with the difference that when the Strolch agent is started, an XML file is parsed and the in memory realm is populated with the elements parsed from that XML file. CACHED In this mode, all data is stored in memory, and any changes made are written back to the persistence layer. This allows for fast in-memory quries, but makes sure no data is lost when the agent is restarted. Strolch Realms are also responsible for opening Transactions, as these are bound to the persistence layer configured for this realm. At runtime, a realm is then accessed from the ComponentContainer:\npublic class Example { public static void main(String[] args) { ComponentContainer container = getAgent().getContainer(); StrolchRealm realm = container.getRealm(StrolchConstants.DEFAULT_REALM); try (StrolchTransaction tx = realm.openTx()) { Resource resource = tx.getResourceBy(\u0026#34;TestType\u0026#34;, \u0026#34;MyTestResource\u0026#34;); } } } "},{"uri":"https://strolch.li/documentation/architecture/","title":"Architecture","tags":[],"description":"","content":"Architecture Birds View A Strolch agent\u0026rsquo;s architecture can be seen as a simple three-tier architecture. The presentation layer is mostly a web frontend, where the communication with the agent is done via REST API calls.\nThe agent itself implements the business logic using Services, Commands, Queries etc.\nThe agent can communicate with other 3rd systems using any API, where it is preferred to use JSON over REST.\nThe agent can use a standard RDBMS as a storage system, where currently DAOs have been implemented only for PostgreSQL. Should it be required, then any JDBC cabable RDBMS can be used, as no PostgreSQL specific SQL commands are used.\nThe following diagram helps visualize this:\nSquirrel View The following diagram shows a more detailed view of the architecture of a Strolch Agent:\nA Strolch agent consists of the following main parts:\n REST Endpoints → expose an API to access the Strolch agent outside of the Java VM Services and Commands → implements business logic Searches → implements specific queries against the Strolch model Components → Implements additional logic, which is best implement as a component. E.g. active components which have threads, etc. Realms → implements multi-tenant capabilities In addition to the main parts, Strolch contains inherit capabilities, which gives Strolch unique features when compared to other Java Frameworks:\n Policies → Policies allow injecting different algorithms. All root elements can store Policy definitions, so that a service can delegate to a Policy and thus behave differently, depending on the element being accessed. Transactions → Transactions handle locking/unlocking of objects, updating the model and are the central API for the developer. Privileges → Strolch is user agnostic and any action, i.e. Service, Query, etc. is authorized against the authenticated user. Observers → modifications to the model are propagated to listeners using the observer pattern. Audits → Every access (read, modify) of the model are audited Versioning → modifications to objects are versioned and thus can be rolled back at a later time. "},{"uri":"https://strolch.li/tutorial/configuration/","title":"Configuration","tags":[],"description":"","content":"Configuration Let\u0026rsquo;s start by creating a new Apache Maven project. We\u0026rsquo;ll need a POM with the proper dependencies. We expect you to be familiar with Apache Maven, so we\u0026rsquo;ll just show you a working POM file:\npom.xml\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34;?\u0026gt; \u0026lt;project xmlns=\u0026#34;http://maven.apache.org/POM/4.0.0\u0026#34; xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34; xsi:schemaLocation=\u0026#34;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\u0026#34;\u0026gt; \u0026lt;modelVersion\u0026gt;4.0.0\u0026lt;/modelVersion\u0026gt; \u0026lt;groupId\u0026gt;li.strolch\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;strolch-bookshop\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;0.1.0-SNAPSHOT\u0026lt;/version\u0026gt; \u0026lt;packaging\u0026gt;war\u0026lt;/packaging\u0026gt; \u0026lt;name\u0026gt;strolch-bookshop\u0026lt;/name\u0026gt; \u0026lt;description\u0026gt;Bookshop built on Strolch\u0026lt;/description\u0026gt; \u0026lt;inceptionYear\u0026gt;2017\u0026lt;/inceptionYear\u0026gt; \u0026lt;properties\u0026gt; \u0026lt;project.build.sourceEncoding\u0026gt;UTF-8\u0026lt;/project.build.sourceEncoding\u0026gt; \u0026lt;maven.build.timestamp.format\u0026gt;yyyy-MM-dd HH:mm:ss\u0026lt;/maven.build.timestamp.format\u0026gt; \u0026lt;buildTimestamp\u0026gt;${maven.build.timestamp}\u0026lt;/buildTimestamp\u0026gt; \u0026lt;jdk.version\u0026gt;1.8\u0026lt;/jdk.version\u0026gt; \u0026lt;jersey.version\u0026gt;2.25.1\u0026lt;/jersey.version\u0026gt; \u0026lt;slf4j.version\u0026gt;1.7.25\u0026lt;/slf4j.version\u0026gt; \u0026lt;logback.version\u0026gt;1.2.3\u0026lt;/logback.version\u0026gt; \u0026lt;petitparser.version\u0026gt;2.1.0\u0026lt;/petitparser.version\u0026gt; \u0026lt;hikaricp.version\u0026gt;4.0.3\u0026lt;/hikaricp.version\u0026gt; \u0026lt;postgresql.version\u0026gt;42.1.4\u0026lt;/postgresql.version\u0026gt; \u0026lt;gson.version\u0026gt;2.8.2\u0026lt;/gson.version\u0026gt; \u0026lt;annotation.version\u0026gt;1.3.1\u0026lt;/annotation.version\u0026gt; \u0026lt;javaxmail.version\u0026gt;1.6.0\u0026lt;/javaxmail.version\u0026gt; \u0026lt;serverlet.version\u0026gt;3.1.0\u0026lt;/serverlet.version\u0026gt; \u0026lt;jaxrs.api.version\u0026gt;2.1\u0026lt;/jaxrs.api.version\u0026gt; \u0026lt;junit.version\u0026gt;4.12\u0026lt;/junit.version\u0026gt; \u0026lt;hamcrest.version\u0026gt;1.3\u0026lt;/hamcrest.version\u0026gt; \u0026lt;mockito.version\u0026gt;2.0.8-beta\u0026lt;/mockito.version\u0026gt; \u0026lt;maven-compiler-plugin.version\u0026gt;3.7.0\u0026lt;/maven-compiler-plugin.version\u0026gt; \u0026lt;maven-source-plugin.version\u0026gt;3.0.1\u0026lt;/maven-source-plugin.version\u0026gt; \u0026lt;maven-jar-plugin.version\u0026gt;3.0.2\u0026lt;/maven-jar-plugin.version\u0026gt; \u0026lt;maven-war-plugin.version\u0026gt;3.1.0\u0026lt;/maven-war-plugin.version\u0026gt; \u0026lt;strolch.version\u0026gt;1.8.5\u0026lt;/strolch.version\u0026gt; \u0026lt;warFinalName\u0026gt;bookshop\u0026lt;/warFinalName\u0026gt; \u0026lt;m2eclipse.wtp.contextRoot\u0026gt;${warFinalName}\u0026lt;/m2eclipse.wtp.contextRoot\u0026gt; \u0026lt;/properties\u0026gt; \u0026lt;dependencies\u0026gt; \u0026lt;!-- base --\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.slf4j\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;slf4j-api\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${slf4j.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;ch.qos.logback\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;logback-classic\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${logback.version}\u0026lt;/version\u0026gt; \u0026lt;scope\u0026gt;runtime\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;!-- strolch --\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;li.strolch\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;li.strolch.utils\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${strolch.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;li.strolch\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;li.strolch.privilege\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${strolch.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;li.strolch\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;li.strolch.model\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${strolch.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;li.strolch\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;li.strolch.agent\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${strolch.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;li.strolch\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;li.strolch.rest\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${strolch.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;li.strolch\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;li.strolch.service\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${strolch.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;li.strolch\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;li.strolch.testbase\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${strolch.version}\u0026lt;/version\u0026gt; \u0026lt;scope\u0026gt;test\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;!-- utils --\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;com.google.code.gson\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;gson\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${gson.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;!-- web --\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;javax.servlet\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;javax.servlet-api\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${serverlet.version}\u0026lt;/version\u0026gt; \u0026lt;scope\u0026gt;provided\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;javax.ws.rs\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;javax.ws.rs-api\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${jaxrs.api.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.glassfish.jersey.core\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;jersey-common\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${jersey.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.glassfish.jersey.core\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;jersey-server\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${jersey.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.glassfish.jersey.containers\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;jersey-container-servlet\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${jersey.version}\u0026lt;/version\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;!-- testing --\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;junit\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;junit\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${junit.version}\u0026lt;/version\u0026gt; \u0026lt;scope\u0026gt;test\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.hamcrest\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;hamcrest-core\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${hamcrest.version}\u0026lt;/version\u0026gt; \u0026lt;scope\u0026gt;test\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;org.hamcrest\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;hamcrest-library\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${hamcrest.version}\u0026lt;/version\u0026gt; \u0026lt;scope\u0026gt;test\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;/dependencies\u0026gt; \u0026lt;build\u0026gt; \u0026lt;resources\u0026gt; \u0026lt;!-- filter properties files, and copy the rest --\u0026gt; \u0026lt;resource\u0026gt; \u0026lt;directory\u0026gt;src/main/resources\u0026lt;/directory\u0026gt; \u0026lt;filtering\u0026gt;true\u0026lt;/filtering\u0026gt; \u0026lt;includes\u0026gt; \u0026lt;include\u0026gt;**/*.properties\u0026lt;/include\u0026gt; \u0026lt;/includes\u0026gt; \u0026lt;/resource\u0026gt; \u0026lt;resource\u0026gt; \u0026lt;directory\u0026gt;src/main/resources\u0026lt;/directory\u0026gt; \u0026lt;filtering\u0026gt;false\u0026lt;/filtering\u0026gt; \u0026lt;excludes\u0026gt; \u0026lt;exclude\u0026gt;**/*.properties\u0026lt;/exclude\u0026gt; \u0026lt;/excludes\u0026gt; \u0026lt;/resource\u0026gt; \u0026lt;/resources\u0026gt; \u0026lt;plugins\u0026gt; \u0026lt;plugin\u0026gt; \u0026lt;groupId\u0026gt;org.apache.maven.plugins\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;maven-compiler-plugin\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${maven-compiler-plugin.version}\u0026lt;/version\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;source\u0026gt;${jdk.version}\u0026lt;/source\u0026gt; \u0026lt;target\u0026gt;${jdk.version}\u0026lt;/target\u0026gt; \u0026lt;/configuration\u0026gt; \u0026lt;/plugin\u0026gt; \u0026lt;plugin\u0026gt; \u0026lt;groupId\u0026gt;org.apache.maven.plugins\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;maven-war-plugin\u0026lt;/artifactId\u0026gt; \u0026lt;version\u0026gt;${maven-war-plugin.version}\u0026lt;/version\u0026gt; \u0026lt;configuration\u0026gt; \u0026lt;failOnMissingWebXml\u0026gt;false\u0026lt;/failOnMissingWebXml\u0026gt; \u0026lt;warName\u0026gt;${warFinalName}\u0026lt;/warName\u0026gt; \u0026lt;/configuration\u0026gt; \u0026lt;/plugin\u0026gt; \u0026lt;/plugins\u0026gt; \u0026lt;/build\u0026gt; \u0026lt;profiles\u0026gt; \u0026lt;!-- active when building on eitch\u0026#39;s machines --\u0026gt; \u0026lt;profile\u0026gt; \u0026lt;id\u0026gt;m2e.eitchpc\u0026lt;/id\u0026gt; \u0026lt;activation\u0026gt; \u0026lt;property\u0026gt; \u0026lt;name\u0026gt;user.name\u0026lt;/name\u0026gt; \u0026lt;value\u0026gt;eitch\u0026lt;/value\u0026gt; \u0026lt;/property\u0026gt; \u0026lt;os\u0026gt; \u0026lt;family\u0026gt;unix\u0026lt;/family\u0026gt; \u0026lt;/os\u0026gt; \u0026lt;/activation\u0026gt; \u0026lt;properties\u0026gt; \u0026lt;strolch.env\u0026gt;dev.eitchpc\u0026lt;/strolch.env\u0026gt; \u0026lt;/properties\u0026gt; \u0026lt;/profile\u0026gt; \u0026lt;/profiles\u0026gt; \u0026lt;/project\u0026gt; Now we need the rest of the directory structure:\n../strolch-bookshop/ - src/main/java/ - li/strolch/bookshop/ - \u0026lt;!-- java classes --\u0026gt; - src/main/resources/ - ENV.properties - appVersion.properties - logback.xml - src/main/webapp/WEB-INF/ - StrolchBootstrap.xml - runtime - config/ - PrivilegeConfig.xml - PrivilegeRoles.xml - PrivilegeUsers.xml - StrolchConfiguration.xml - StrolchPolicies.xml - data/ - StrolchModel.xsd - defaultModel.xml - templates.xml - temp/ A few notes to the resource files:\n The ENV.properties file is filtered by maven and the environment to load is written in it using the environment variable strolch.env. The appVersion.properties file is also filtered by maven and allows to reflect on the version of this app at runtime. The logback.xml file configures logging using SLF4j and Logback. The StrolchBootstrap.xml file is used to configure Strolch\u0026rsquo;s environment and root directory. For a webapp it can be annoying to store Strolch\u0026rsquo;s configuration inside the webapp, which is why we can define an absolute path where the configuration is kept. In the following example we keep it in the root of the sources:\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34;?\u0026gt; \u0026lt;StrolchBootstrap\u0026gt; \u0026lt;env id=\u0026#34;dev.eitchpc\u0026#34; default=\u0026#34;true\u0026#34;\u0026gt; \u0026lt;root\u0026gt;/home/eitch/src/git/strolch-bookshop/runtime\u0026lt;/root\u0026gt; \u0026lt;environment\u0026gt;dev\u0026lt;/environment\u0026gt; \u0026lt;/env\u0026gt; \u0026lt;/StrolchBootstrap\u0026gt; Here we define two environments, but the both redefine the environment to dev. This is because we want this app to start on two different machines with different user home directories. See the profiles in the POM as to how these environments are activated using a environment property strolch.env.\nIn this next step we\u0026rsquo;ll create Strolch\u0026rsquo;s configuration at the location we defined in the StrolchBootstrap.xml file. Strolch\u0026rsquo;s configuration contains of three directories: config, data and temp. config contains static files which usually aren\u0026rsquo;t changed, data contains model files in XML format and temp is used at runtime for any temporary files, e.g. storing active sessions.\nThe configuration as well as the model has been described on Strolch\u0026rsquo;s documentation web page, we\u0026rsquo;ll just provide you with the files for the bookshop:\nPrivilegeConfig.xml\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34;?\u0026gt; \u0026lt;Privilege\u0026gt; \u0026lt;Container\u0026gt; \u0026lt;Parameters\u0026gt; \u0026lt;!-- parameters for the container itself --\u0026gt; \u0026lt;Parameter name=\u0026#34;secretKey\u0026#34; value=\u0026#34;45f251ce-d51f-4624-990a-8dcd5b181f0e\u0026#34;/\u0026gt; \u0026lt;Parameter name=\u0026#34;secretSalt\u0026#34; value=\u0026#34;4770a32d-1512-4891-9a63-362504932500\u0026#34;/\u0026gt; \u0026lt;Parameter name=\u0026#34;persistSessions\u0026#34; value=\u0026#34;true\u0026#34;/\u0026gt; \u0026lt;Parameter name=\u0026#34;autoPersistOnUserChangesData\u0026#34; value=\u0026#34;false\u0026#34;/\u0026gt; \u0026lt;Parameter name=\u0026#34;privilegeConflictResolution\u0026#34; value=\u0026#34;MERGE\u0026#34;/\u0026gt; \u0026lt;/Parameters\u0026gt; \u0026lt;EncryptionHandler class=\u0026#34;li.strolch.privilege.handler.DefaultEncryptionHandler\u0026#34;\u0026gt; \u0026lt;Parameters\u0026gt; \u0026lt;Parameter name=\u0026#34;hashAlgorithm\u0026#34; value=\u0026#34;PBKDF2WithHmacSHA512\u0026#34;/\u0026gt; \u0026lt;Parameter name=\u0026#34;hashIterations\u0026#34; value=\u0026#34;10000\u0026#34;/\u0026gt; \u0026lt;Parameter name=\u0026#34;hashKeyLength\u0026#34; value=\u0026#34;256\u0026#34;/\u0026gt; \u0026lt;/Parameters\u0026gt; \u0026lt;/EncryptionHandler\u0026gt; \u0026lt;PersistenceHandler class=\u0026#34;li.strolch.privilege.handler.XmlPersistenceHandler\u0026#34;\u0026gt; \u0026lt;Parameters\u0026gt; \u0026lt;Parameter name=\u0026#34;usersXmlFile\u0026#34; value=\u0026#34;PrivilegeUsers.xml\u0026#34;/\u0026gt; \u0026lt;Parameter name=\u0026#34;rolesXmlFile\u0026#34; value=\u0026#34;PrivilegeRoles.xml\u0026#34;/\u0026gt; \u0026lt;/Parameters\u0026gt; \u0026lt;/PersistenceHandler\u0026gt; \u0026lt;UserChallengeHandler class=\u0026#34;li.strolch.privilege.handler.MailUserChallengeHandler\u0026#34;\u0026gt; \u0026lt;/UserChallengeHandler\u0026gt; \u0026lt;/Container\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;Policy name=\u0026#34;DefaultPrivilege\u0026#34; class=\u0026#34;li.strolch.privilege.policy.DefaultPrivilege\u0026#34;/\u0026gt; \u0026lt;Policy name=\u0026#34;RoleAccessPrivilege\u0026#34; class=\u0026#34;li.strolch.privilege.policy.RoleAccessPrivilege\u0026#34;/\u0026gt; \u0026lt;Policy name=\u0026#34;UserAccessPrivilege\u0026#34; class=\u0026#34;li.strolch.privilege.policy.UserAccessPrivilege\u0026#34;/\u0026gt; \u0026lt;Policy name=\u0026#34;UserSessionAccessPrivilege\u0026#34; class=\u0026#34;li.strolch.privilege.policy.UsernameFromCertificatePrivilege\u0026#34;/\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;/Privilege\u0026gt; PrivilegeRoles.xml\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34;?\u0026gt; \u0026lt;Roles\u0026gt; \u0026lt;Role name=\u0026#34;User\u0026#34;\u0026gt; \u0026lt;Privilege name=\u0026#34;li.strolch.service.api.Service\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;li.strolch.search.StrolchSearch\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;Allow\u0026gt;li.strolch.bookshop.search.BookSearch\u0026lt;/Allow\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;GetResource\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;GetOrder\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;GetActivity\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;AddResource\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;AddOrder\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;AddActivity\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;UpdateResource\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;UpdateOrder\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;UpdateActivity\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;RemoveResource\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;RemoveOrder\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;RemoveActivity\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;/Role\u0026gt; \u0026lt;Role name=\u0026#34;UserPrivileges\u0026#34;\u0026gt; \u0026lt;Privilege name=\u0026#34;PrivilegeSetUserLocale\u0026#34; policy=\u0026#34;UserAccessPrivilege\u0026#34; /\u0026gt; \u0026lt;Privilege name=\u0026#34;PrivilegeSetUserPassword\u0026#34; policy=\u0026#34;UserAccessPrivilege\u0026#34; /\u0026gt; \u0026lt;/Role\u0026gt; \u0026lt;!-- Internal --\u0026gt; \u0026lt;Role name=\u0026#34;StrolchAdmin\u0026#34;\u0026gt; \u0026lt;Privilege name=\u0026#34;li.strolch.service.api.Service\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;li.strolch.search.StrolchSearch\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;GetResource\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;GetOrder\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;GetActivity\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;AddResource\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;AddOrder\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;AddActivity\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;UpdateResource\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;UpdateOrder\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;UpdateActivity\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;RemoveResource\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;RemoveOrder\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;RemoveActivity\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;PrivilegeAddUser\u0026#34; policy=\u0026#34;UserAccessPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;PrivilegeSetUserPassword\u0026#34; policy=\u0026#34;UserAccessPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;/Role\u0026gt; \u0026lt;Role name=\u0026#34;agent\u0026#34;\u0026gt; \u0026lt;Privilege name=\u0026#34;li.strolch.privilege.handler.SystemAction\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;Allow\u0026gt;li.strolch.runtime.privilege.StrolchSystemAction\u0026lt;/Allow\u0026gt; \u0026lt;Allow\u0026gt;li.strolch.runtime.privilege.StrolchSystemActionWithResult\u0026lt;/Allow\u0026gt; \u0026lt;Allow\u0026gt;li.strolch.persistence.postgresql.PostgreSqlSchemaInitializer\u0026lt;/Allow\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;li.strolch.service.api.Service\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;li.strolch.model.query.StrolchQuery\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;li.strolch.search.StrolchSearch\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;GetResource\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;GetOrder\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;GetActivity\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;AddResource\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;AddOrder\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;AddActivity\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;UpdateResource\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;UpdateOrder\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;UpdateActivity\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;RemoveResource\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;RemoveOrder\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;RemoveActivity\u0026#34; policy=\u0026#34;ModelPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;PrivilegeAction\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;Allow\u0026gt;Persist\u0026lt;/Allow\u0026gt; \u0026lt;Allow\u0026gt;PersistSessions\u0026lt;/Allow\u0026gt; \u0026lt;Allow\u0026gt;GetCertificates\u0026lt;/Allow\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;PrivilegeAddUser\u0026#34; policy=\u0026#34;UserAccessPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;PrivilegeModifyUser\u0026#34; policy=\u0026#34;UserAccessPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;PrivilegeGetUser\u0026#34; policy=\u0026#34;UserAccessPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;/Role\u0026gt; \u0026lt;/Roles\u0026gt; PrivilegeUsers.xml\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34;?\u0026gt; \u0026lt;Users\u0026gt; \u0026lt;User userId=\u0026#34;U10\u0026#34; username=\u0026#34;jill\u0026#34; password=\u0026#34;8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918\u0026#34;\u0026gt; \u0026lt;Firstname\u0026gt;Jill\u0026lt;/Firstname\u0026gt; \u0026lt;Lastname\u0026gt;Someone\u0026lt;/Lastname\u0026gt; \u0026lt;State\u0026gt;ENABLED\u0026lt;/State\u0026gt; \u0026lt;Locale\u0026gt;en-GB\u0026lt;/Locale\u0026gt; \u0026lt;Roles\u0026gt; \u0026lt;Role\u0026gt;User\u0026lt;/Role\u0026gt; \u0026lt;Role\u0026gt;UserPrivileges\u0026lt;/Role\u0026gt; \u0026lt;/Roles\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;Property name=\u0026#34;email\u0026#34; value=\u0026#34;eitch+jill@eitchnet.ch\u0026#34; /\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/User\u0026gt; \u0026lt;User userId=\u0026#34;U01\u0026#34; username=\u0026#34;admin\u0026#34; password=\u0026#34;8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918\u0026#34;\u0026gt; \u0026lt;Firstname\u0026gt;Jill\u0026lt;/Firstname\u0026gt; \u0026lt;Lastname\u0026gt;Someone\u0026lt;/Lastname\u0026gt; \u0026lt;State\u0026gt;ENABLED\u0026lt;/State\u0026gt; \u0026lt;Locale\u0026gt;en-GB\u0026lt;/Locale\u0026gt; \u0026lt;Roles\u0026gt; \u0026lt;Role\u0026gt;StrolchAdmin\u0026lt;/Role\u0026gt; \u0026lt;Role\u0026gt;UserPrivileges\u0026lt;/Role\u0026gt; \u0026lt;/Roles\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;Property name=\u0026#34;email\u0026#34; value=\u0026#34;eitch+admin@eitchnet.ch\u0026#34; /\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/User\u0026gt; \u0026lt;!-- Internal --\u0026gt; \u0026lt;User userId=\u0026#34;S01\u0026#34; username=\u0026#34;agent\u0026#34;\u0026gt; \u0026lt;State\u0026gt;SYSTEM\u0026lt;/State\u0026gt; \u0026lt;Roles\u0026gt; \u0026lt;Role\u0026gt;agent\u0026lt;/Role\u0026gt; \u0026lt;/Roles\u0026gt; \u0026lt;/User\u0026gt; \u0026lt;/Users\u0026gt; StrolchConfiguration.xml\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34;?\u0026gt; \u0026lt;StrolchConfiguration\u0026gt; \u0026lt;env id=\u0026#34;global\u0026#34;\u0026gt; \u0026lt;Runtime\u0026gt; \u0026lt;applicationName\u0026gt;Bookshop\u0026lt;/applicationName\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;locale\u0026gt;en\u0026lt;/locale\u0026gt; \u0026lt;verbose\u0026gt;true\u0026lt;/verbose\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Runtime\u0026gt; \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;PrivilegeHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.runtime.privilege.PrivilegeHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler\u0026lt;/impl\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;privilegeConfigFile\u0026gt;PrivilegeConfig.xml\u0026lt;/privilegeConfigFile\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;RealmHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.agent.api.RealmHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.agent.impl.DefaultRealmHandler\u0026lt;/impl\u0026gt; \u0026lt;depends\u0026gt;PrivilegeHandler\u0026lt;/depends\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;realms\u0026gt;defaultRealm\u0026lt;/realms\u0026gt; \u0026lt;dataStoreMode\u0026gt;TRANSIENT\u0026lt;/dataStoreMode\u0026gt; \u0026lt;dataStoreFile\u0026gt;defaultModel.xml\u0026lt;/dataStoreFile\u0026gt; \u0026lt;enableObserverUpdates\u0026gt;true\u0026lt;/enableObserverUpdates\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;ServiceHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.service.api.ServiceHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.service.api.DefaultServiceHandler\u0026lt;/impl\u0026gt; \u0026lt;depends\u0026gt;RealmHandler\u0026lt;/depends\u0026gt; \u0026lt;depends\u0026gt;PrivilegeHandler\u0026lt;/depends\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;verbose\u0026gt;true\u0026lt;/verbose\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;PolicyHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.policy.PolicyHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.policy.DefaultPolicyHandler\u0026lt;/impl\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;readPolicyFile\u0026gt;true\u0026lt;/readPolicyFile\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;ExecutionHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.execution.ExecutionHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.execution.EventBasedExecutionHandler\u0026lt;/impl\u0026gt; \u0026lt;depends\u0026gt;RealmHandler\u0026lt;/depends\u0026gt; \u0026lt;depends\u0026gt;PrivilegeHandler\u0026lt;/depends\u0026gt; \u0026lt;/Component\u0026gt; \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;RestfulHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.rest.RestfulStrolchComponent\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.rest.RestfulStrolchComponent\u0026lt;/impl\u0026gt; \u0026lt;depends\u0026gt;SessionHandler\u0026lt;/depends\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;secureCookie\u0026gt;false\u0026lt;/secureCookie\u0026gt; \u0026lt;restLogging\u0026gt;false\u0026lt;/restLogging\u0026gt; \u0026lt;restLoggingEntity\u0026gt;false\u0026lt;/restLoggingEntity\u0026gt; \u0026lt;restTracing\u0026gt;ALL\u0026lt;/restTracing\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;SessionHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.rest.StrolchSessionHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.rest.DefaultStrolchSessionHandler\u0026lt;/impl\u0026gt; \u0026lt;depends\u0026gt;PrivilegeHandler\u0026lt;/depends\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;session.ttl.minutes\u0026gt;30\u0026lt;/session.ttl.minutes\u0026gt; \u0026lt;session.reload\u0026gt;true\u0026lt;/session.reload\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;MailHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.handler.mail.MailHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.handler.mail.SmtpMailHandler\u0026lt;/impl\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;fromAddr\u0026gt;relayer@eitchnet.ch\u0026lt;/fromAddr\u0026gt; \u0026lt;fromName\u0026gt;Susi\u0026lt;/fromName\u0026gt; \u0026lt;overrideRecipients\u0026gt;\u0026lt;![CDATA[IPSC Test \u0026lt;eitch@eitchnet.ch\u0026gt;]]\u0026gt;\u0026lt;/overrideRecipients\u0026gt; \u0026lt;recipientWhitelist\u0026gt;eitch@eitchnet.ch\u0026lt;/recipientWhitelist\u0026gt; \u0026lt;username\u0026gt;test\u0026lt;/username\u0026gt; \u0026lt;password\u0026gt;test\u0026lt;/password\u0026gt; \u0026lt;auth\u0026gt;true\u0026lt;/auth\u0026gt; \u0026lt;startTls\u0026gt;true\u0026lt;/startTls\u0026gt; \u0026lt;host\u0026gt;smtp.gmail.com\u0026lt;/host\u0026gt; \u0026lt;port\u0026gt;587\u0026lt;/port\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; \u0026lt;/env\u0026gt; \u0026lt;env id=\u0026#34;dev\u0026#34;\u0026gt; \u0026lt;!-- overrides go here --\u0026gt; \u0026lt;/env\u0026gt; \u0026lt;/StrolchConfiguration\u0026gt; StrolchPolicies.xml\n\u0026lt;StrolchPolicies\u0026gt; \u0026lt;PolicyType Type=\u0026#34;ExecutionPolicy\u0026#34; Api=\u0026#34;li.strolch.execution.policy.ExecutionPolicy\u0026#34;\u0026gt; \u0026lt;Policy Key=\u0026#34;DurationExecution\u0026#34; Class=\u0026#34;li.strolch.execution.policy.DurationExecution\u0026#34; /\u0026gt; \u0026lt;Policy Key=\u0026#34;ReservationExection\u0026#34; Class=\u0026#34;li.strolch.execution.policy.ReservationExecution\u0026#34; /\u0026gt; \u0026lt;/PolicyType\u0026gt; \u0026lt;PolicyType Type=\u0026#34;ConfirmationPolicy\u0026#34; Api=\u0026#34;li.strolch.execution.policy.ConfirmationPolicy\u0026#34;\u0026gt; \u0026lt;Policy Key=\u0026#34;DefaultConfirmation\u0026#34; Class=\u0026#34;li.strolch.execution.policy.ConfirmationPolicy\u0026#34; /\u0026gt; \u0026lt;/PolicyType\u0026gt; \u0026lt;PolicyType Type=\u0026#34;ActivityArchivalPolicy\u0026#34; Api=\u0026#34;li.strolch.execution.policy.ActivityArchivalPolicy\u0026#34;\u0026gt; \u0026lt;Policy Key=\u0026#34;DefaultActivityArchival\u0026#34; Class=\u0026#34;li.strolch.execution.policy.ActivityArchivalPolicy\u0026#34; /\u0026gt; \u0026lt;/PolicyType\u0026gt; \u0026lt;/StrolchPolicies\u0026gt; A few notes on the configuration:\n Note how there are three users. Jill is a user with currently no privileges as it\u0026rsquo;s role definition is empty. Admin can do everything, and the agent user is a system user which can also do everything.\n There is one realm defined in the RealmHandler component which references the defaultModel.xml file in the data directory. This file then includes the currently still empty templates.xml file.\n We have defined a global environment, but are using the dev environment. The dev environment includes the definitions in the global environment.\n In PrivilegeConfig.xml we have enabled persistence of sessions, so you will be needing the unlimited JCE libraries for your JVM.\nWhen you restart the server, you don\u0026rsquo;t need to log back in, if your session is still alive.\n In PrivilegeRoles.xml there seems to be a lot of boilerplate. One thing about a highly configurable system is that sometimes the configuration is bigger. In this case we have opted to have the configuration shown and not use default values which you don\u0026rsquo;t see, so that privilege access is clearly seen.\n Your project is now ready to be imported into your favourite IDE. We have used both IntelliJ and Eclipse so this is up to you.\nNow that we have a configuration, it is time to have Strolch started when the WAR is deployed and started. In your IDE create a new class as follows:\nStartupListener.java\npackage li.strolch.bookshop.web; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import javax.servlet.annotation.WebListener; import java.io.InputStream; import li.strolch.agent.api.StrolchAgent; import li.strolch.agent.api.StrolchBootstrapper; import li.strolch.utils.helper.StringHelper; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @WebListener public class StartupListener implements ServletContextListener { private static final Logger logger = LoggerFactory.getLogger(StartupListener.class); private static final String APP_NAME = \u0026#34;Bookshop\u0026#34;; private StrolchAgent agent; @Override public void contextInitialized(ServletContextEvent sce) { logger.info(\u0026#34;Starting \u0026#34; + APP_NAME + \u0026#34;...\u0026#34;); long start = System.currentTimeMillis(); try { String boostrapFileName = \u0026#34;/WEB-INF/\u0026#34; + StrolchBootstrapper.FILE_BOOTSTRAP; InputStream bootstrapFile = sce.getServletContext().getResourceAsStream(boostrapFileName); StrolchBootstrapper bootstrapper = new StrolchBootstrapper(StartupListener.class); this.agent = bootstrapper.setupByBoostrapFile(StartupListener.class, bootstrapFile); this.agent.initialize(); this.agent.start(); } catch (Throwable e) { logger.error(\u0026#34;Failed to start \u0026#34; + APP_NAME + \u0026#34; due to: \u0026#34; + e.getMessage(), e); throw e; } long took = System.currentTimeMillis() - start; logger.info(\u0026#34;Started \u0026#34; + APP_NAME + \u0026#34; in \u0026#34; + (StringHelper.formatMillisecondsDuration(took))); } @Override public void contextDestroyed(ServletContextEvent sce) { if (this.agent != null) { logger.info(\u0026#34;Destroying \u0026#34; + APP_NAME + \u0026#34;...\u0026#34;); try { this.agent.stop(); this.agent.destroy(); } catch (Throwable e) { logger.error(\u0026#34;Failed to stop \u0026#34; + APP_NAME + \u0026#34; due to: \u0026#34; + e.getMessage(), e); throw e; } } logger.info(\u0026#34;Destroyed \u0026#34; + APP_NAME); } } Now configure your IDE to start the web project, and then once it has started, you should see the following in the logs:\nBookshop:dev All 8 Strolch Components started. Took 44ms. Strolch is now ready to be used. Have fun =)) This log tells us the name of the app as defined in the StrolchConfiguration.xml file as well as which environment was loaded. Further we can see that 8 components were configured and started.\nThis concludes the initial setup of a new Strolch project. We can now go ahead and start building the business logic.\n"},{"uri":"https://strolch.li/development/prerequisites/","title":"Prerequisites","tags":[],"description":"","content":"Prerequisites To start developing Strolch you need an installed:\n Java JDK 17 Apache Maven 3.x You can install these using the awesome SDKMAN!:\n$ curl -s \u0026#34;https://get.sdkman.io\u0026#34; | bash source \u0026#34;$HOME/.sdkman/bin/sdkman-init.sh\u0026#34; sdk version sdk install java sdk install maven sdk install mvnd Test your Java installation:\n$ java -version openjdk version \u0026#34;17.0.4\u0026#34; 2022-07-19 OpenJDK Runtime Environment Temurin-17.0.4+8 (build 17.0.4+8) OpenJDK 64-Bit Server VM Temurin-17.0.4+8 (build 17.0.4+8, mixed mode, sharing) Test your Maven installation:\n$ mvn --version Apache Maven 3.8.6 (84538c9988a25aec085021c365c560670ad80f63) Maven home: /home/user/.sdkman/candidates/maven/current Java version: 17.0.4, vendor: Eclipse Adoptium, runtime: /home/user/.sdkman/candidates/java/17.0.4-tem Default locale: en_US, platform encoding: UTF-8 OS name: \u0026#34;linux\u0026#34;, version: \u0026#34;5.18.11-051811-generic\u0026#34;, arch: \u0026#34;amd64\u0026#34;, family: \u0026#34;unix\u0026#34; "},{"uri":"https://strolch.li/development/building/","title":"Building Strolch","tags":[],"description":"","content":"Building Strolch Note: You don\u0026rsquo;t have to build Strolch if you want to use the version on Maven central. If you need a snapshot version, the release you want isn\u0026rsquo;t on Maven central or you want to use the Strolch Maven archetypes, then go ahead and build Strolch.\n Building Strolch is just a few lines:\ngit clone https://github.com/strolch-li/strolch.git cd strolch mvn clean install -DskipTests Note: To run the tests you will need to configure the PostgreSQL Databases. See the README in the module.\n After running the Maven build, you will have a full build of all Strolch modules. Now you can start modifying the modules, and add your own features, or, far more interesting, start developing your projects using the Strolch agent.\n"},{"uri":"https://strolch.li/documentation/","title":"Documentation","tags":[],"description":"","content":"Overview Strolch\u0026rsquo;s documentation has only just begun, but as more and more details of the implementation in Strolch are fixed, more documentation can be created and will be available here.\nCurrently, we have the following topics of discussion:\n Architecture Model Do and Don\u0026#39;t Runtime Configuration Realms Components Services and Commands Searches Queries Transactions Policies Observers Versioning Reports Privileges "},{"uri":"https://strolch.li/documentation/model/","title":"Model","tags":[],"description":"","content":"Model Before we dive into the entire model, let\u0026rsquo;s show an example and how it would be modelled in Strolch and use in Strolch:\nThe model has four entities, which will be modelled using 3 Resources and 1 Order object. The objects have numerous fields and the following relationships:\n Bidirectional between Article \u0026lt;-\u0026gt; Product Unidirectional from Order -\u0026gt; Article Unidirectional from Order -\u0026gt; Customer A possible model would look as follows:\n\u0026lt;?xml version=\u0026#34;1.0\u0026#34; encoding=\u0026#34;UTF-8\u0026#34; ?\u0026gt; \u0026lt;StrolchModel xmlns=\u0026#34;https://strolch.li/xsd/StrolchModel-1.6.xsd\u0026#34;\u0026gt; \u0026lt;Resource Id=\u0026#34;Product\u0026#34; Name=\u0026#34;Product Template\u0026#34; Type=\u0026#34;Template\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;parameters\u0026#34; Name=\u0026#34;Parameters\u0026#34; Type=\u0026#34;Parameters\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;description\u0026#34; Name=\u0026#34;Description\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;color\u0026#34; Name=\u0026#34;Color\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;form\u0026#34; Name=\u0026#34;Form\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;relations\u0026#34; Name=\u0026#34;Relations\u0026#34; Type=\u0026#34;Relations\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;articles\u0026#34; Name=\u0026#34;Articles\u0026#34; Type=\u0026#34;StringList\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Article\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Resource\u0026gt; \u0026lt;Resource Id=\u0026#34;Article\u0026#34; Name=\u0026#34;Article Template\u0026#34; Type=\u0026#34;Template\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;parameters\u0026#34; Name=\u0026#34;Parameters\u0026#34; Type=\u0026#34;Parameters\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;description\u0026#34; Name=\u0026#34;Description\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;barcode\u0026#34; Name=\u0026#34;Barcode\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;relations\u0026#34; Name=\u0026#34;Relations\u0026#34; Type=\u0026#34;Relations\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;product\u0026#34; Name=\u0026#34;Product\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Product\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Resource\u0026gt; \u0026lt;Resource Id=\u0026#34;Customer\u0026#34; Name=\u0026#34;Customer Template\u0026#34; Type=\u0026#34;Template\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;address\u0026#34; Name=\u0026#34;Address\u0026#34; Type=\u0026#34;Address\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;street\u0026#34; Name=\u0026#34;Street\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;zip\u0026#34; Name=\u0026#34;Zip\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;city\u0026#34; Name=\u0026#34;City\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;country\u0026#34; Name=\u0026#34;Country\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Resource\u0026gt; \u0026lt;Order Id=\u0026#34;Order\u0026#34; Name=\u0026#34;Order\u0026#34; Type=\u0026#34;Template\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;quantities\u0026#34; Name=\u0026#34;Quantities per Article Id\u0026#34; Type=\u0026#34;Quantities\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;quantity\u0026#34; Name=\u0026#34;Quantity\u0026#34; Type=\u0026#34;Float\u0026#34; Value=\u0026#34;0\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;relations\u0026#34; Name=\u0026#34;Relations\u0026#34; Type=\u0026#34;Relations\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;articles\u0026#34; Name=\u0026#34;Articles\u0026#34; Type=\u0026#34;StringList\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Article\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;customer\u0026#34; Name=\u0026#34;Customer\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Customer\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Order\u0026gt; \u0026lt;/StrolchModel\u0026gt; Let\u0026rsquo;s go through this model:\n In the above model we see that the id and name fields are always on the element, and thus aren\u0026rsquo;t added as parameters. Further best practice is to use a parameters ParameterBag, with one or more parameters, modelling the fields. There is API support to not have to always type the parameters bag id. Note that in this example the Type of all the elements is Template. Strolch has API support to create a clone of these elements, so that they have a unique id, and the proper type for persistence. The Product element has three parameters: description, color and form. In this case they are all of type String. Further the relations ParameterBag defines the relationships, i.e. the product knows its articles. Note how the relation is first defined in a relations ParameterBag and that the Parameter has Interpretation=\u0026quot;Resource-Ref\u0026quot; Uom=\u0026quot;Product\u0026quot; attributes. Strolch has API support for this, making it trivial to retrieve a dependency. The Article element has two parameters description and barcode. Further it has a reference to its Product. The Order element doesn\u0026rsquo;t model the date and state fields as parameters, as these are inherently part of an Order element. The Order does define two references to customer and articles. A special case is the quantities ParameterBag. This bag of parameters is used to store the per article quantity for this order. With ParameterBags, you can eliminate the use of simple aggregate classes, as is commonly used in object-oriented programming. The Customer element models an address ParameterBag to store the address of a customer. Using a separate bag allows for further more direct fields to stored on the default parameters bag. Now that we have a basic understanding of te model, it is of far more interest in how to create and interact with these elements at runtime. The following listing will perform simple operations:\npublic class Example { public static void main(String[] args) { // keep IDs for later use String dafalganId; String dafalgan1Id; String dafalgan2Id; String customerId; String orderId; // first transaction to create the data try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, false)) { /* * create a new product */ Resource dafalgan = tx.getResourceTemplate(\u0026#34;Product\u0026#34;, true); dafalgan.setName(\u0026#34;Dafalgan 100mg\u0026#34;); dafalgan.setString(\u0026#34;description\u0026#34;, \u0026#34;Dafalgan is for pain.\u0026#34;); dafalgan.setString(\u0026#34;color\u0026#34;, \u0026#34;Yellow\u0026#34;); dafalgan.setString(\u0026#34;form\u0026#34;, \u0026#34;flat\u0026#34;); /* * create articles */ Resource dafalgan1 = tx.getResourceTemplate(\u0026#34;Article\u0026#34;, true); dafalgan1.setName(\u0026#34;Dafalgan 100mg 10 pce\u0026#34;); dafalgan1.setString(\u0026#34;description\u0026#34;, \u0026#34;This is pack with 10 pieces.\u0026#34;); dafalgan1.setString(\u0026#34;barcode\u0026#34;, \u0026#34;654654\u0026#34;); Resource dafalgan2 = tx.getResourceTemplate(\u0026#34;Article\u0026#34;, true); dafalgan2.setName(\u0026#34;Dafalgan 100mg 20 pce\u0026#34;); dafalgan2.setString(\u0026#34;description\u0026#34;, \u0026#34;This is pack with 20 pieces.\u0026#34;); dafalgan2.setString(\u0026#34;barcode\u0026#34;, \u0026#34;654655\u0026#34;); /* * add reference to product */ dafalgan1.setRelation(\u0026#34;product\u0026#34;, dafalgan); dafalgan2.setRelation(\u0026#34;product\u0026#34;, dafalgan); dafalgan.addRelation(\u0026#34;articles\u0026#34;, dafalgan1); dafalgan.addRelation(\u0026#34;articles\u0026#34;, dafalgan2); /* * create a new customer */ Resource customer1 = tx.getResourceTemplate(\u0026#34;Customer\u0026#34;, true); customer1.setName(\u0026#34;John Doe\u0026#34;); // set address ParameterBag addressBag = customer1.getParameterBag(\u0026#34;address\u0026#34;, true); addressBag.setString(\u0026#34;street\u0026#34;, \u0026#34;Main Str. 1\u0026#34;); addressBag.setString(\u0026#34;zip\u0026#34;, \u0026#34;1234\u0026#34;); addressBag.setString(\u0026#34;city\u0026#34;, \u0026#34;Hometown\u0026#34;); addressBag.setString(\u0026#34;country\u0026#34;, \u0026#34;Switzerland\u0026#34;); /* * create a new order */ Order order = tx.getOrderTemplate(\u0026#34;Order\u0026#34;, true); order.setName(\u0026#34;Order for \u0026#34; + customer1.getName()); order.setDate(LocalDate.of(2021, 2, 1)); order.setState(State.PLANNED); // store reference to customer order.setRelation(\u0026#34;customer\u0026#34;, customer1); StringListParameter orderArticlesP = order.getRelationsParam(\u0026#34;articles\u0026#34;, true); ParameterBag quantitiesBag = order.getParameterBag(\u0026#34;quantities\u0026#34;, true); FloatParameter quantityT = quantitiesBag.removeParameter(\u0026#34;quantity\u0026#34;); // order quantity of 20 for Dafalgan 1 quantitiesBag.setDouble(dafalgan1.getId(), 20); order.addRelation(\u0026#34;articles\u0026#34;, dafalgan1); // set order quantity of 10 for Dafalgan 2 quantitiesBag.setDouble(dafalgan2.getId(), 20); order.addRelation(\u0026#34;articles\u0026#34;, dafalgan2); // keep IDs for later use dafalganId = dafalgan.getId(); dafalgan1Id = dafalgan1.getId(); dafalgan2Id = dafalgan2.getId(); customerId = customer1.getId(); orderId = order.getId(); /* * persist */ tx.add(dafalgan); tx.add(dafalgan1); tx.add(dafalgan2); tx.add(customer1); tx.add(order); // commit tx.commitOnClose(); } } } class Scratch { public static void main(String[] args) { // keep IDs for later use String dafalganId; String dafalgan1Id; String dafalgan2Id; String customerId; String orderId; // // .. snip ... // // second transaction to query the data try (StrolchTransaction tx = runtimeMock.openUserTx(certificate, true)) { // get order Order order = tx.getOrderBy(\u0026#34;Order\u0026#34;, orderId, true); assertEquals(\u0026#34;Order for John Doe\u0026#34;, order.getName()); // get customer Resource customer = tx.getResourceByRelation(order, \u0026#34;customer\u0026#34;, true); assertEquals(\u0026#34;John Doe\u0026#34;, customer.getName()); // get articles List\u0026lt;Resource\u0026gt; articles = tx.getResourcesByRelation(order, \u0026#34;articles\u0026#34;, true); assertEquals(2, articles.size()); // get products by stream List\u0026lt;Resource\u0026gt; products = articles.stream().map(a -\u0026gt; tx.getResourceByRelation(a, \u0026#34;product\u0026#34;, true)) .distinct().collect(Collectors.toList()); assertEquals(1, products.size()); // search for all orders in state PLANNED and with customer List\u0026lt;Order\u0026gt; orders = new OrderSearch().types(\u0026#34;Order\u0026#34;).stateIsIn(State.PLANNED) .where(ExpressionsSupport.relationParam(\u0026#34;customer\u0026#34;).isEqualTo(customerId)).search(tx).toList(); assertEquals(1, orders.size()); } } } Note: Checkout example-model.xml and SimpleModelTest.java for these examples.\n There is an XML Schema which defines the model in XML: StrolchModel-1.6.xsd\n Here is an example of all the possible elements in Strolch:\n\u0026lt;StrolchModel xmlns:xsi=\u0026#34;http://www.w3.org/2001/XMLSchema-instance\u0026#34; xmlns=\u0026#34;https://strolch.li/xsd/StrolchModel-1.6.xsd\u0026#34; xsi:schemaLocation=\u0026#34;https://strolch.li/xsd/StrolchModel-1.6.xsd StrolchModel-1.6.xsd\u0026#34;\u0026gt; \u0026lt;IncludeFile file=\u0026#34;Include1.xml\u0026#34;/\u0026gt; \u0026lt;Order Id=\u0026#34;@test1\u0026#34; Name=\u0026#34;Test Order\u0026#34; Type=\u0026#34;Order\u0026#34;\u0026gt; \u0026lt;Version Version=\u0026#34;0\u0026#34; CreatedBy=\u0026#34;test\u0026#34; Created=\u0026#34;2012-11-30T18:12:05.628+01:00\u0026#34; UpdatedBy=\u0026#34;test\u0026#34; Updated=\u0026#34;2012-11-30T18:12:05.628+01:00\u0026#34; Deleted=\u0026#34;false\u0026#34;/\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;@bag01\u0026#34; Name=\u0026#34;Test Bag\u0026#34; Type=\u0026#34;TestBag\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;@param1\u0026#34; Name=\u0026#34;Boolean Param\u0026#34; Type=\u0026#34;Boolean\u0026#34; Value=\u0026#34;true\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;@bag01\u0026#34; Name=\u0026#34;Test Bag\u0026#34; Type=\u0026#34;TestBag\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;@param1\u0026#34; Name=\u0026#34;Boolean Param\u0026#34; Type=\u0026#34;Boolean\u0026#34; Value=\u0026#34;true\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;Policy Type=\u0026#34;PlanningPolicy\u0026#34; Value=\u0026#34;key:SimplePlanning\u0026#34;/\u0026gt; \u0026lt;Policy Type=\u0026#34;ConfirmationPolicy\u0026#34; Value=\u0026#34;key:NoConfirmation\u0026#34;/\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;/Order\u0026gt; \u0026lt;Resource Id=\u0026#34;MyTestResource\u0026#34; Name=\u0026#34;Test Name\u0026#34; Type=\u0026#34;TestType\u0026#34;\u0026gt; \u0026lt;Version Version=\u0026#34;0\u0026#34; CreatedBy=\u0026#34;test\u0026#34; Created=\u0026#34;2012-11-30T18:12:05.628+01:00\u0026#34; UpdatedBy=\u0026#34;test\u0026#34; Updated=\u0026#34;2012-11-30T18:12:05.628+01:00\u0026#34; Deleted=\u0026#34;false\u0026#34;/\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;@bag01\u0026#34; Name=\u0026#34;Test Bag 01\u0026#34; Type=\u0026#34;TestBag\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;@param1\u0026#34; Name=\u0026#34;Boolean Param\u0026#34; Type=\u0026#34;Boolean\u0026#34; Value=\u0026#34;true\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;@bag02\u0026#34; Name=\u0026#34;Test Bag 02\u0026#34; Type=\u0026#34;TestBag\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;@param1\u0026#34; Name=\u0026#34;Boolean Param\u0026#34; Type=\u0026#34;Boolean\u0026#34; Value=\u0026#34;true\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;TimedState Id=\u0026#34;@booleanState\u0026#34; Name=\u0026#34;Boolean State\u0026#34; Type=\u0026#34;Boolean\u0026#34;\u0026gt; \u0026lt;Value Time=\u0026#34;1970-01-01T00:02:00.000+01:00\u0026#34; Value=\u0026#34;false\u0026#34;/\u0026gt; \u0026lt;/TimedState\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;Policy Type=\u0026#34;PlanningPolicy\u0026#34; Value=\u0026#34;key:SimplePlanning\u0026#34;/\u0026gt; \u0026lt;Policy Type=\u0026#34;ConfirmationPolicy\u0026#34; Value=\u0026#34;key:NoConfirmation\u0026#34;/\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;/Resource\u0026gt; \u0026lt;Activity Id=\u0026#34;activity_1\u0026#34; Name=\u0026#34;Activity\u0026#34; Type=\u0026#34;parentType\u0026#34; TimeOrdering=\u0026#34;Series\u0026#34;\u0026gt; \u0026lt;Version Version=\u0026#34;0\u0026#34; CreatedBy=\u0026#34;test\u0026#34; Created=\u0026#34;2012-11-30T18:12:05.628+01:00\u0026#34; UpdatedBy=\u0026#34;test\u0026#34; Updated=\u0026#34;2012-11-30T18:12:05.628+01:00\u0026#34; Deleted=\u0026#34;false\u0026#34;/\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;@bag01\u0026#34; Name=\u0026#34;Test Bag\u0026#34; Type=\u0026#34;TestBag\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;@param1\u0026#34; Name=\u0026#34;Boolean Param\u0026#34; Type=\u0026#34;Boolean\u0026#34; Value=\u0026#34;true\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;Policy Type=\u0026#34;PlanningPolicy\u0026#34; Value=\u0026#34;key:SimplePlanning\u0026#34;/\u0026gt; \u0026lt;Policy Type=\u0026#34;ConfirmationPolicy\u0026#34; Value=\u0026#34;key:NoConfirmation\u0026#34;/\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;Action Id=\u0026#34;action_1\u0026#34; Name=\u0026#34;Action 1\u0026#34; ResourceId=\u0026#34;dummyId\u0026#34; ResourceType=\u0026#34;dummyType\u0026#34; State=\u0026#34;Created\u0026#34; Type=\u0026#34;Use\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;@bag01\u0026#34; Name=\u0026#34;Test Bag\u0026#34; Type=\u0026#34;TestBag\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;@param1\u0026#34; Name=\u0026#34;Boolean Param\u0026#34; Type=\u0026#34;Boolean\u0026#34; Value=\u0026#34;true\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;Policy Type=\u0026#34;PlanningPolicy\u0026#34; Value=\u0026#34;key:SimplePlanning\u0026#34;/\u0026gt; \u0026lt;Policy Type=\u0026#34;ConfirmationPolicy\u0026#34; Value=\u0026#34;key:NoConfirmation\u0026#34;/\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;ValueChange StateId=\u0026#34;dummyId\u0026#34; Time=\u0026#34;2012-11-30T18:12:05.628+01:00\u0026#34; Value=\u0026#34;5\u0026#34; Type=\u0026#34;Integer\u0026#34;/\u0026gt; \u0026lt;ValueChange StateId=\u0026#34;dummyId\u0026#34; Time=\u0026#34;2012-11-30T18:12:06.628+01:00\u0026#34; Value=\u0026#34;6\u0026#34; Type=\u0026#34;Integer\u0026#34;/\u0026gt; \u0026lt;/Action\u0026gt; \u0026lt;Activity Id=\u0026#34;child_activity\u0026#34; Name=\u0026#34;Child Activity\u0026#34; Type=\u0026#34;childType\u0026#34; TimeOrdering=\u0026#34;Series\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;@bag01\u0026#34; Name=\u0026#34;Test Bag\u0026#34; Type=\u0026#34;TestBag\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;@param1\u0026#34; Name=\u0026#34;Boolean Param\u0026#34; Type=\u0026#34;Boolean\u0026#34; Value=\u0026#34;true\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;Policy Type=\u0026#34;PlanningPolicy\u0026#34; Value=\u0026#34;key:SimplePlanning\u0026#34;/\u0026gt; \u0026lt;Policy Type=\u0026#34;ConfirmationPolicy\u0026#34; Value=\u0026#34;key:NoConfirmation\u0026#34;/\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;Action Id=\u0026#34;action_2\u0026#34; Name=\u0026#34;Action 2\u0026#34; ResourceId=\u0026#34;dummyId\u0026#34; ResourceType=\u0026#34;dummyType\u0026#34; State=\u0026#34;Planned\u0026#34; Type=\u0026#34;Use\u0026#34;\u0026gt; \u0026lt;ValueChange StateId=\u0026#34;dummyId\u0026#34; Time=\u0026#34;2012-11-30T18:12:05.628+01:00\u0026#34; Value=\u0026#34;5\u0026#34; Type=\u0026#34;Integer\u0026#34;/\u0026gt; \u0026lt;ValueChange StateId=\u0026#34;dummyId\u0026#34; Time=\u0026#34;2012-11-30T18:12:06.628+01:00\u0026#34; Value=\u0026#34;6\u0026#34; Type=\u0026#34;Integer\u0026#34;/\u0026gt; \u0026lt;/Action\u0026gt; \u0026lt;Action Id=\u0026#34;action_3\u0026#34; Name=\u0026#34;Action 3\u0026#34; ResourceId=\u0026#34;dummyId\u0026#34; ResourceType=\u0026#34;dummyType\u0026#34; State=\u0026#34;Created\u0026#34; Type=\u0026#34;Use\u0026#34;/\u0026gt; \u0026lt;/Activity\u0026gt; \u0026lt;/Activity\u0026gt; \u0026lt;/StrolchModel\u0026gt; "},{"uri":"https://strolch.li/tutorial/model/","title":"Model","tags":[],"description":"","content":"Model Looking back at our functionality, we can list the following entities that need to be modelled (We\u0026rsquo;ll go into detail further down):\n Book → books can be orderd UserCart → we want to store the cart of the user Account → we need to know where to send the orders PurchaseOrder → we need to know what was ordered and keep track of its state FromStock → we want to use activities to implement the process of an order In Strolch we model entities by defining the element as a template. Thus in the templates.xml file we can add the templates with the following content:\nBook\n\u0026lt;Resource Id=\u0026#34;Book\u0026#34; Name=\u0026#34;Book Template\u0026#34; Type=\u0026#34;Template\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;parameters\u0026#34; Name=\u0026#34;Parameters\u0026#34; Type=\u0026#34;Parameters\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;description\u0026#34; Name=\u0026#34;Description\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;quantity\u0026#34; Name=\u0026#34;Quantity in Stock\u0026#34; Type=\u0026#34;Integer\u0026#34; Value=\u0026#34;0\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Resource\u0026gt; Account\n\u0026lt;Resource Id=\u0026#34;Account\u0026#34; Name=\u0026#34;Account Template\u0026#34; Type=\u0026#34;Template\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;parameters\u0026#34; Name=\u0026#34;Parameters\u0026#34; Type=\u0026#34;Parameters\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;user\u0026#34; Name=\u0026#34;User\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;firstName\u0026#34; Name=\u0026#34;First Name\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;lastName\u0026#34; Name=\u0026#34;Last Name\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;email\u0026#34; Name=\u0026#34;E-Mail\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Name=\u0026#34;Address\u0026#34; Id=\u0026#34;address\u0026#34; Type=\u0026#34;Address\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;phone\u0026#34; Name=\u0026#34;Telephone Number\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;street\u0026#34; Name=\u0026#34;Street\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;city\u0026#34; Name=\u0026#34;City\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;zip\u0026#34; Name=\u0026#34;Postal Code\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;country\u0026#34; Name=\u0026#34;Country\u0026#34; Type=\u0026#34;String\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Resource\u0026gt; UserCart\n\u0026lt;Resource Id=\u0026#34;UserCart\u0026#34; Name=\u0026#34;UserCart Template\u0026#34; Type=\u0026#34;Template\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;books\u0026#34; Name=\u0026#34;Books\u0026#34; Type=\u0026#34;Book\u0026#34;\u0026gt; \u0026lt;!-- Parameter Id=\u0026#34;bookId\u0026#34; Name=\u0026#34;Book reference\u0026#34; Type=\u0026#34;Float\u0026#34; Value=\u0026#34;0\u0026#34; / --\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;relations\u0026#34; Name=\u0026#34;Relations\u0026#34; Type=\u0026#34;Parameters\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;account\u0026#34; Name=\u0026#34;Account\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Account\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Resource\u0026gt; PurchaseOrder\n\u0026lt;Order Id=\u0026#34;PurchaseOrder\u0026#34; Name=\u0026#34;PurchaseOrder Template\u0026#34; Type=\u0026#34;Template\u0026#34; State=\u0026#34;Created\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;books\u0026#34; Name=\u0026#34;Books\u0026#34; Type=\u0026#34;Book\u0026#34;\u0026gt; \u0026lt;!-- Parameter Id=\u0026#34;bookId\u0026#34; Name=\u0026#34;Book reference\u0026#34; Type=\u0026#34;Float\u0026#34; Value=\u0026#34;0\u0026#34; / --\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;relations\u0026#34; Name=\u0026#34;Relations\u0026#34; Type=\u0026#34;Parameters\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;account\u0026#34; Name=\u0026#34;Account\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Account\u0026#34; Value=\u0026#34;\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Order\u0026gt; FromStock\n\u0026lt;Activity Id=\u0026#34;FromStock\u0026#34; Name=\u0026#34;From Stock Template\u0026#34; Type=\u0026#34;FromStock\u0026#34; TimeOrdering=\u0026#34;Series\u0026#34;\u0026gt; \u0026lt;ParameterBag Name=\u0026#34;objectives\u0026#34; Id=\u0026#34;Objectives\u0026#34; Type=\u0026#34;Objectives\u0026#34;\u0026gt; \u0026lt;Parameter Name=\u0026#34;Duration\u0026#34; Id=\u0026#34;duration\u0026#34; Value=\u0026#34;PT1MS\u0026#34; Type=\u0026#34;Duration\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;Action Id=\u0026#34;validate\u0026#34; Name=\u0026#34;Validation of order\u0026#34; Type=\u0026#34;Use\u0026#34; ResourceType=\u0026#34;Validation\u0026#34; ResourceId=\u0026#34;validation\u0026#34;/\u0026gt; \u0026lt;!-- for each book we do a consume, i.e. reduce the stock quantity --\u0026gt; \u0026lt;Action Id=\u0026#34;Consume\u0026#34; Name=\u0026#34;Consume Template for book\u0026#34; Type=\u0026#34;Template\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;parameters\u0026#34; Name=\u0026#34;Parameters\u0026#34; Type=\u0026#34;Parameters\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;quantity\u0026#34; Name=\u0026#34;Quantity\u0026#34; Type=\u0026#34;Float\u0026#34; Value=\u0026#34;0\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;/Action\u0026gt; \u0026lt;Action Id=\u0026#34;package\u0026#34; Name=\u0026#34;Packaging of PurchaseOrder\u0026#34; Type=\u0026#34;Use\u0026#34; ResourceType=\u0026#34;Packaging\u0026#34; ResourceId=\u0026#34;packaging\u0026#34;/\u0026gt; \u0026lt;Action Id=\u0026#34;send\u0026#34; Name=\u0026#34;Sending of package\u0026#34; Type=\u0026#34;Use\u0026#34; ResourceType=\u0026#34;Sending\u0026#34; ResourceId=\u0026#34;sending\u0026#34;/\u0026gt; \u0026lt;/Activity\u0026gt; Let\u0026rsquo;s explain a few things:\n The Book entity is a Resource object and only contains the description and the current quantity in stock.\n The Account entity is a Resource and contains the address and further details of the user, and with the user parameter the username is defined, thus referencing the real user.\n The UserCart entity is a Resource and has a reference to the account Resource.\nNote how the reference is done using a StringParameter, where Interpretation, UOM and the value is set in a specific manner.\n The UserCart entity is a Resource and references books using a special ParameterBag with the type set to Book, the actual type of the book entity. Each Parameter is of type Float and the ID of the parameter is the ID of the book, and the value is the quantity that the user would like to purchase.\nThere will only be one cart per user/account.\n The PurchaseOrder entity is an Order object, and is basically a copy of the UserCart entity. This is the confirmed purchase order for the contents of a cart, and can then be used for reports on how much of which book was sold.\n The FromStock entity is an Activity object and defines the process we will go through when delivering a purchase to a user.\nNote how the activity has a ParameterBag objectives with a duration parameter. This defines for this activity how long each Action should execute. This can be overridden in each Action and can help to plan how much effort goes into the delivering of each PurchaseOrder.\n Further note how the activity has three special actions (validate, package and send) on which a ResourceType and ResourceId are defined. Actions are always performed on a Resource, as the referenced Resource defines the behaviour of the action through defined Policy objects.\n For each book which will be purchased, an Action will be created of type Consume. In the template this is defined by a template Action with the id Consume and will later be changed accordingly.\n Since we are referencing resources from actions in the activity, we need to add these as well, but not as templates. They can be added to the defaultModel.xml file:\n\u0026lt;Resource Id=\u0026#34;validation\u0026#34; Name=\u0026#34;Validation Resource\u0026#34; Type=\u0026#34;Validation\u0026#34;\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;Policy Type=\u0026#34;ExecutionPolicy\u0026#34; Value=\u0026#34;key:ValidationExecution\u0026#34; /\u0026gt; \u0026lt;Policy Type=\u0026#34;ConfirmationPolicy\u0026#34; Value=\u0026#34;key:DefaultConfirmation\u0026#34; /\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;/Resource\u0026gt; \u0026lt;Resource Id=\u0026#34;packaging\u0026#34; Name=\u0026#34;Packaging Resource\u0026#34; Type=\u0026#34;Packaging\u0026#34;\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;Policy Type=\u0026#34;ExecutionPolicy\u0026#34; Value=\u0026#34;key:PackagingExecution\u0026#34; /\u0026gt; \u0026lt;Policy Type=\u0026#34;ConfirmationPolicy\u0026#34; Value=\u0026#34;key:DefaultConfirmation\u0026#34; /\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;/Resource\u0026gt; \u0026lt;Resource Id=\u0026#34;sending\u0026#34; Name=\u0026#34;Sending Resource\u0026#34; Type=\u0026#34;Sending\u0026#34;\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;Policy Type=\u0026#34;ExecutionPolicy\u0026#34; Value=\u0026#34;key:SendingExecution\u0026#34; /\u0026gt; \u0026lt;Policy Type=\u0026#34;ConfirmationPolicy\u0026#34; Value=\u0026#34;key:DefaultConfirmation\u0026#34; /\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;/Resource\u0026gt; What should now be noted by these three new Resources is that they have Policy definitions:\n ExecutionPolicy → defines how an action on this resource is executed by referencing an ExecutionPolicy implementation. ConfirmationPolicy → defines behaviour to be performed on every state change of an action being performed on this resource by referencing an ConfirmationPolicy implementation. Currently these resources reference policies which don\u0026rsquo;t exist. We will resolve this issue later, when we implement the execution of the activity.\nThis concludes the model definition. In the next step we\u0026rsquo;ll start creating services and commands for our model.\n"},{"uri":"https://strolch.li/plc/","title":"PLC","tags":[],"description":"","content":"Overview Using Strolch as a PLC has certain advantages and disadvantages. The following is a list of advantages:\n Same programming model and language for server and PLC PLC has the same privilege handling as in Strolch Simulating down to the PLC level is easily possible for easier testing of server logic Of course using the Java language as a PLC has its limitations, we have manage to use it for customers and are satisfied with the result. What follows is a description in how to set up your own Strolch based PLC.\nCheckout the code at GitHub\nStrolch PLC is also deployed to Maven Central. Current version is 1.2.2 and is using Strolch version 1.8.5.\nCurrently, we have the following topics of discussion:\n Architecture Example Set-Up "},{"uri":"https://strolch.li/tutorial/crud-book/","title":"CRUD Book","tags":[],"description":"","content":"Preparation Since Books are central to the bookshop, we\u0026rsquo;ll first create the CRUD REST API for them. The API will be as follows:\nGET ../rest/books?query=,offset=,limit= GET ../rest/books/{id} POST ../rest/books PUT ../rest/books/{id} DELETE ../rest/books/{id} Thus corresponding with querying, getting, creating, updating and removing of books. So let\u0026rsquo;s go ahead and add these REST APIs to our project.\nOur project is using JAX-RS 2.0 as the API and Jersey 2.x as the implementation, thus first we need to configure JAX-RS. Thus create the following class:\n@ApplicationPath(\u0026#34;rest\u0026#34;) public class RestfulApplication extends ResourceConfig { public RestfulApplication() { // add strolch resources register(AuthenticationService.class); register(ModelQuery.class); register(Inspector.class); // add project resources by package name packages(BooksResource.class.getPackage().getName()); // filters register(AuthenticationRequestFilter.class, Priorities.AUTHENTICATION); register(AccessControlResponseFilter.class); register(AuthenticationResponseFilter.class); register(HttpCacheResponseFilter.class); // log exceptions and return them as plain text to the caller register(StrolchRestfulExceptionMapper.class); // the JSON generated is in UTF-8 register(CharsetResponseFilter.class); RestfulStrolchComponent restfulComponent = RestfulStrolchComponent.getInstance(); if (restfulComponent.isRestLogging()) { register(new LoggingFeature(java.util.logging.Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME), Level.SEVERE, LoggingFeature.Verbosity.PAYLOAD_ANY, Integer.MAX_VALUE)); property(ServerProperties.TRACING, \u0026#34;ALL\u0026#34;); property(ServerProperties.TRACING_THRESHOLD, \u0026#34;TRACE\u0026#34;); } } } As we add new resources they will be automatically since we register the entire package.\nNow add the books resource class:\n@Path(\u0026#34;books\u0026#34;) public class BooksResource { } Search The first service we\u0026rsquo;ll add is to query, or search for the existing books. The API defines three parameters, with which the result can be controlled. The method can be defined as follows:\n@Path(\u0026#34;books\u0026#34;) public class BooksResource { @GET @Produces(MediaType.APPLICATION_JSON) public Response query(@Context HttpServletRequest request, @QueryParam(\u0026#34;query\u0026#34;) String queryS, @QueryParam(\u0026#34;offset\u0026#34;) String offsetS, @QueryParam(\u0026#34;limit\u0026#34;) String limitS) { // TODO } } To fill this method we need a few things. First let\u0026rsquo;s define a constants class where we keep String constants which we used in the model file:\npublic class BookShopConstants { public static final String TYPE_BOOK = \u0026#34;Book\u0026#34;; } As this tutorial progresses, more and more constants will be added here. This class helps with two issues: Through the constants we can easily reason over where certain fields, and types are used and of course String literals in code are a rather bad thing.\nIn Strolch there are multiple way to access objects. The old way was using Queries, the new search API is much more fluent and easier to read and write. The search API, as well as the deprecated query API allows us to implement privilege validation and thus one should create corresponding classes for each type of search. Book entities are Resources, thus we will be creating a ResourceSearch. The search is for Resources of type Book thus the resulting search looks as follows:\npublic class BooksSearch\u0026lt;U\u0026gt; extends ResourceSearch\u0026lt;U\u0026gt; { public BookSearch() { types(TYPE_BOOK); } public BookSearch stringQuery(String value) { if (isEmpty(value)) return this; // split by spaces value = value.trim(); String[] values = value.split(\u0026#34; \u0026#34;); // add where clauses for id, name and description where(id().containsIgnoreCase(values) // .or(name().containsIgnoreCase(values)) // .or(param(BAG_PARAMETERS, PARAM_DESCRIPTION).containsIgnoreCase(values))); return this; } } Note how we added a special stringQuery(String)-method. This method defines where a search string entered by the user will be used to match a book. In this case for id, name and the description parameter.\nSo that our users can call this query, we must give them this as a privilege. This is done by adding the full class name to the PrivilegeRoles.xml file as follows:\n... \u0026lt;Role name=\u0026#34;User\u0026#34;\u0026gt; \u0026lt;Privilege name=\u0026#34;li.strolch.search.StrolchSearch\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;Allow\u0026gt;internal\u0026lt;/Allow\u0026gt; \u0026lt;Allow\u0026gt;li.strolch.bookshop.search.BookSearch\u0026lt;/Allow\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;/Role\u0026gt; ... Note: The internal allow value is a special privilege which is used internally when a service or something performs internal queries. This means that a service can perform a query for object to which the user might not have access, but without which the service could not be completed. We will use this in a later stage.\n Now we have all parts we need to implement the query method. The method will include opening a transaction, instantiating the search, executing the search, and returning the result:\n@Path(\u0026#34;books\u0026#34;) public class BooksResource { @GET @Produces(MediaType.APPLICATION_JSON) public Response query(@Context HttpServletRequest request, @QueryParam(\u0026#34;query\u0026#34;) String queryS, @QueryParam(\u0026#34;offset\u0026#34;) String offsetS, @QueryParam(\u0026#34;limit\u0026#34;) String limitS) { // this is an authenticated method call, thus we can get the certificate from the request: Certificate cert = (Certificate) request .getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); int offset = StringHelper.isNotEmpty(offsetS) ? Integer.parseInt(offsetS) : 0; int limit = StringHelper.isNotEmpty(limitS) ? Integer.parseInt(limitS) : 0; // open the TX with the certificate, using this class as context Paging\u0026lt;Resource\u0026gt; paging; try (StrolchTransaction tx = RestfulStrolchComponent.getInstance() .openTx(cert, getClass())) { // perform a book search paging = new BookSearch() // .stringQuery(queryS) // .search(tx) // .orderByName(false) // .toPaging(offset, limit); } ResourceVisitor\u0026lt;JsonObject\u0026gt; visitor = new StrolchRootElementToJsonVisitor() .flat().asResourceVisitor(); return ResponseUtil.toResponse(paging, e -\u0026gt; e.accept(visitor)); } } Note: We automatically transform the Resource objects to JSON using the StrolchElementToJsonVisitor. By calling the method .flat()-method we have a more compact JSON format. Paging is handled by a util class.\n The helper class ResponseUtil takes care of creating the JsonObject and the proper page. As a rule we use the format where we return two fields: msg is a dash if all is ok, otherwise an error message will be present. Data is always in the data field. This is just a personal taste, and can be changed to one\u0026rsquo;s own taste.\nGet We have all we need now to implement the GET method:\n@GET @Path(\u0026#34;{id}\u0026#34;) @Produces(MediaType.APPLICATION_JSON) public Response get(@Context HttpServletRequest request, @PathParam(\u0026#34;id\u0026#34;) String id) { // this is an authenticated method call, thus we can get the certificate from the request: Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); // open the TX with the certificate, using this class as context try (StrolchTransaction tx = RestfulStrolchComponent.getInstance().openTx(cert, getClass())) { // get the book Resource book = tx.getResourceBy(BookShopConstants.TYPE_BOOK, id); if (book == null) return ResponseUtil.toResponse(Status.NOT_FOUND, \u0026#34;Book \u0026#34; + id + \u0026#34; does not exist!\u0026#34;); // transform to JSON JsonObject bookJ = book.accept(new StrolchRootElementToJsonVisitor().flat()); // return return ResponseUtil.toResponse(StrolchRestfulConstants.DATA, bookJ); } } Note how we simply retrieve the book as a Resource from the TX. This is a good moment to familiarize yourself with the API of the StrolchTransaction. There are methods to retrieve elements, and also perform searches. We will use more of these methods later.\n Further it can be noted that a simple retrieval isn\u0026rsquo;t validated against the user\u0026rsquo;s privileges, the user is authenticated, which is enough for the moment.\nCreate To create a new book we need to implement a Service. This service will be called CreateBookService. A Service always has a ServiceArgument and a ServiceResult. Our service will use the JsonServiceArgument and the JsonServiceResult. The implementation of the POST method is as follows:\n@POST @Produces(MediaType.APPLICATION_JSON) public Response create(@Context HttpServletRequest request, String data) { // this is an authenticated method call, thus we can get the certificate from the request: Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); // parse data to JSON JsonObject jsonData = JsonParser.parseString(data).getAsJsonObject(); // instantiate the service with the argument CreateBookService svc = new CreateBookService(); JsonServiceArgument arg = svc.getArgumentInstance(); arg.jsonElement = jsonData; // perform the service ServiceHandler serviceHandler = RestfulStrolchComponent.getInstance().getServiceHandler(); JsonServiceResult result = serviceHandler.doService(cert, svc, arg); // return depending on the result state if (result.isOk()) return ResponseUtil.toResponse(StrolchRestfulConstants.DATA, result.getResult()); return ResponseUtil.toResponse(result); } Note: We return the created object again as JSON in its own data field.\n The service is implemented as follows:\npublic class CreateBookService extends AbstractService\u0026lt;JsonServiceArgument, JsonServiceResult\u0026gt; { @Override protected JsonServiceResult getResultInstance() { return new JsonServiceResult(); } @Override public JsonServiceArgument getArgumentInstance() { return new JsonServiceArgument(); } @Override protected JsonServiceResult internalDoService(JsonServiceArgument arg) throws Exception { // open a new transaction, using the realm from the argument, or the certificate Resource book; try (StrolchTransaction tx = openArgOrUserTx(arg)) { // get a new book \u0026#34;instance\u0026#34; from the template book = tx.getResourceTemplate(BookShopConstants.TYPE_BOOK); // map all values from the JSON object into the new book element book.accept(new FromFlatJsonVisitor(arg.jsonElement.getAsJsonObject()).ignoreBag(BAG_RELATIONS)); // save changes tx.add(book); // notify the TX that it should commit on close tx.commitOnClose(); } // map the return value to JSON JsonObject result = book.accept(new StrolchElementToJsonVisitor().flat()); // and return the result return new JsonServiceResult(result); } } Note: For the authenticated user to be able to perform this service, we must add it to their privileges:\n ... \u0026lt;Role name=\u0026#34;User\u0026#34;\u0026gt; ... \u0026lt;Privilege name=\u0026#34;li.strolch.service.api.Service\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;Allow\u0026gt;li.strolch.bookshop.service.CreateBookService\u0026lt;/Allow\u0026gt; \u0026lt;/Privilege\u0026gt; ... \u0026lt;/Role\u0026gt; ... Update Updating of a book is basically the same as the creation, we just use PUT, verify that the book exists and give the user the privilege.\nPUT Method:\n@PUT @Path(\u0026#34;{id}\u0026#34;) @Produces(MediaType.APPLICATION_JSON) public Response update(@Context HttpServletRequest request, @PathParam(\u0026#34;id\u0026#34;) String id, String data) { // this is an authenticated method call, thus we can get the certificate from the request: Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); // parse data to JSON JsonObject jsonData = JsonParser.parseString(data).getAsJsonObject(); // instantiate the service with the argument UpdateBookService svc = new UpdateBookService(); JsonServiceArgument arg = svc.getArgumentInstance(); arg.objectId = id; arg.jsonElement = jsonData; // perform the service ServiceHandler serviceHandler = RestfulStrolchComponent.getInstance().getServiceHandler(); JsonServiceResult result = serviceHandler.doService(cert, svc, arg); // return depending on the result state if (result.isOk()) return ResponseUtil.toResponse(StrolchRestfulConstants.DATA, result.getResult()); return ResponseUtil.toResponse(result); } Update Service:\npublic class UpdateBookService extends AbstractService\u0026lt;JsonServiceArgument, JsonServiceResult\u0026gt; { @Override protected JsonServiceResult getResultInstance() { return new JsonServiceResult(); } @Override public JsonServiceArgument getArgumentInstance() { return new JsonServiceArgument(); } @Override protected JsonServiceResult internalDoService(JsonServiceArgument arg) throws Exception { // verify same book DBC.PRE.assertEquals(\u0026#34;ObjectId and given Id must be same!\u0026#34;, arg.objectId, arg.jsonElement.getAsJsonObject().get(Json.ID).getAsString()); // open a new transaction, using the realm from the argument, or the certificate Resource book; try (StrolchTransaction tx = openArgOrUserTx(arg)) { // get the existing book book = tx.getResourceBy(BookShopConstants.TYPE_BOOK, arg.objectId, true); // map all values from the JSON object into the new book element book.accept(new FromFlatJsonVisitor(arg.jsonElement.getAsJsonObject()).ignoreBag(BAG_RELATIONS)); // save changes tx.update(book); // notify the TX that it should commit on close tx.commitOnClose(); } // map the return value to JSON JsonObject result = book.accept(new StrolchElementToJsonVisitor().flat()); // and return the result return new JsonServiceResult(result); } } Privilege\n... \u0026lt;Role name=\u0026#34;User\u0026#34;\u0026gt; ... \u0026lt;Privilege name=\u0026#34;li.strolch.service.api.Service\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; ... \u0026lt;Allow\u0026gt;li.strolch.bookshop.service.UpdateBookService\u0026lt;/Allow\u0026gt; ... \u0026lt;/Privilege\u0026gt; ... \u0026lt;/Role\u0026gt; ... Remove To remove a book, we need a DELETE method, a remove service and the associated privilege.\nDELETE Method:\n@DELETE @Path(\u0026#34;{id}\u0026#34;) @Produces(MediaType.APPLICATION_JSON) public Response update(@Context HttpServletRequest request, @PathParam(\u0026#34;id\u0026#34;) String id) { // this is an authenticated method call, thus we can get the certificate from the request: Certificate cert = (Certificate) request.getAttribute(StrolchRestfulConstants.STROLCH_CERTIFICATE); // instantiate the service with the argument RemoveBookService svc = new RemoveBookService(); StringServiceArgument arg = svc.getArgumentInstance(); arg.value = id; // perform the service ServiceHandler serviceHandler = RestfulStrolchComponent.getInstance().getServiceHandler(); ServiceResult result = serviceHandler.doService(cert, svc, arg); // return depending on the result state return ResponseUtil.toResponse(result); } Remove Service:\npublic class RemoveBookService extends AbstractService\u0026lt;StringServiceArgument, ServiceResult\u0026gt; { @Override protected ServiceResult getResultInstance() { return new ServiceResult(); } @Override public StringServiceArgument getArgumentInstance() { return new StringServiceArgument(); } @Override protected ServiceResult internalDoService(StringServiceArgument arg) throws Exception { // open a new transaction, using the realm from the argument, or the certificate try (StrolchTransaction tx = openArgOrUserTx(arg)) { // get the existing book Resource book = tx.getResourceBy(BookShopConstants.TYPE_BOOK, arg.value, true); // save changes tx.remove(book); // notify the TX that it should commit on close tx.commitOnClose(); } // and return the result return ServiceResult.success(); } } Privilege:\n... \u0026lt;Role name=\u0026#34;User\u0026#34;\u0026gt; ... \u0026lt;Privilege name=\u0026#34;li.strolch.service.api.Service\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; ... \u0026lt;Allow\u0026gt;li.strolch.bookshop.service.RemoveBookService\u0026lt;/Allow\u0026gt; ... \u0026lt;/Privilege\u0026gt; ... \u0026lt;/Role\u0026gt; ... Notes One should now see a pattern emerge:\n The REST API delegates to the Services, or Searches, with the exception of the retrieval of a single object by id. Services should do initial validation of the input. Not much validation was done here, but more could be done. Commands are reusable objects to perform recurring work. Searches and Services are privileged actions for which a user must have the privilege to perform the action. The book services are quite simple, but as more requirements arise, it should be easy to implement them in the service layer. Thus should a service be required to be performed by an integration layer, then they can simply call the services, since the input is defined and validation is done there (i.e. NOT in the REST API).\nThis concludes the CRUD of books.\n"},{"uri":"https://strolch.li/documentation/do-and-donts/","title":"Do and Don't","tags":[],"description":"","content":"This page discusses things you should and shouldn\u0026rsquo;t do when using Strolch The following is a simple list of do\u0026rsquo;s and don\u0026rsquo;ts:\n 1 Service per use-case, should mostly delegate to Commands.\n Commands implement use-cases or parts of it, and are thus reusable.\n Subclass ResourceSearch, OrderSearch and ActivitySearch when implementing use-case specific search - this allows privilege checking.\n One Transaction at a time - no TX inside of another TX.\n Commands are added to TXs and performed on close: tx.addCommand(Command) and then tx.commitOnClose()\n Only access ElementMaps if really no other way, mostly use tx.get*By(), tx.findBy() and searches - if a specific get is missing, then add the method to StrolchTransaction and send a pull request!\n Use tx.stream*() methods to iterate over all elements, if you don\u0026rsquo;t want to use a search.\n Don\u0026rsquo;t write logic in REST API beans. Delegate to other services, making your code reusable!\n Marshall to JSON using the StrolchElementToJsonVisitor.\n Unmarshall JSON using FromFlatJsonVisitor or if needed StrolchElementFromJsonVisitor\n References between objects is done by adding a ParameterBag with the id relations to the object and then StringParameters with the value being the ID, the UOM set to the type of element being referenced and the Interpretation set to the class type being referenced.\n Very seldom and sparingly use tx.flush() if you need to perform first some work and then as late as possible call tx.commitOnClose()\nThe flush()-method flushes everything, i.e. rollback isn\u0026rsquo;t possible anymore.\n "},{"uri":"https://strolch.li/development/maven-archetypes/","title":"Maven Archetypes","tags":[],"description":"","content":"Maven Archetypes Maven offers archetypes to generate new projects. Strolch offers the following archetypes, to create new projects:\n strolch.mvn.archetype.main for Java main class applications strolch.mvn.archetype.webapp for Java Web based applications using REST and Polymer 1.x as the frontend. strolch.mvn.archetype.plc for Strolch PLC projects. To use the archetypes, clone the archetypes repository and install it locally:\ngit clone https://github.com/strolch-li/strolch-maven-archetypes.git cd strolch-maven-archetypes git checkout 0.1.0 mvn clean install Then follow one of the next steps to create the type of application you want.\n"},{"uri":"https://strolch.li/documentation/runtime-configuration/","title":"Runtime Configuration","tags":[],"description":"","content":"Runtime Configuration A Strolch runtime configuration comprises two parts: a configuration part, and a model part. The configuration are files located in the ..config/ folder, and the model are files located in the ../data folder.\nIn an absolute minimal configuration, the Strolch runtime requires the following folder structure:\n ../config/ ../StrolchConfiguration.xml → configures the Strolch agent ../PrivilegeConfig.xml → configures user management ../PrivilegeUsers.xml → contains the users in an XML based user management file ../PrivilegeRoles.xml → contains the roles and privileges in an XML based user management StrolchConfiguration.xml The StrolchConfiguration.xml file configures the Strolch agent. The StrolchConfiguration.xml defines the following:\n \u0026lt;StrolchConfiguration\u0026gt; root element \u0026lt;env id=\u0026quot;xxx\u0026quot;\u0026gt; different environments with the possibility of having a global environment for configuration valid in multiple environments. \u0026lt;Runtime\u0026gt; element which defines the agents name and a few other properties e.g. locale and verbose: \u0026lt;applicationName\u0026gt; the agent\u0026rsquo;s name \u0026lt;Properties\u0026gt; \u0026lt;locale\u0026gt; the agent\u0026rsquo;s internal locale for log messages etc. \u0026lt;verbose\u0026gt; the logging level for some internal logging. (Logging is mostly done using log4j over slf4j) \u0026lt;Component\u0026gt; elements for each component used in the agent. A component is configured by defining the following child elements: \u0026lt;name\u0026gt; the name of the component, use when defining dependencies between components. The name is mostly set to the simple name of the interface of the component\n \u0026lt;api\u0026gt; the full class name to the interface of the component. During runtime this interface will be used to access the component e.g.:\nServiceHandler svcHandler = agent.getContainer().getComponent(ServiceHandler.class);\n \u0026lt;impl\u0026gt; the full class name of the concrete implementation of the component. During initialization this class will be instantiated and registered under the component name and interface. This class must extend the class li.strolch.agent.api.StrolchComponent\n \u0026lt;depends\u0026gt; any number of these elements, where the content is the name of another component, on which this component depends. Depending components are initialized and started after the component they depend on and are stopped and destroyed before\n \u0026lt;Properties\u0026gt;\n \u0026lt;...\u0026gt; any number of properties which the component requires. The element\u0026rsquo;s name will be the key with which the value can be accessed at runtime.\n When a property is missing, and the component has a hard coded default value, then when the component is initialized, the use of the default value and its key is logged. This makes it easy to see which new properties can be configured. Should the component not define a default value, then the component will thrown an exception on initialization. In this case it can be a good moment to read the JavaDoc (or source code) for the component in question to see how it is configured.\n Privilege Configuration In Strolch authentication and authorization is baked in. To open a transaction, and thus access the Strolch model, a Certificate object is required, which means the user has been authenticated and possibly authorized.\nThe PrivilegeConfig.xml defines the following:\n \u0026lt;Privilege\u0026gt; root element \u0026lt;Container\u0026gt; configures the individual Privilege components \u0026lt;Parameters\u0026gt; base configuration properties for Privilege \u0026lt;EncryptionHandler\u0026gt; configures the hashing algorithms and other encryption specific configuration \u0026lt;PersistenceHandler\u0026gt; configures the persistence of the roles and users \u0026lt;UserChallengeHandler\u0026gt; configures a challenge handler so that a user can reset their password. The default challenge handler is the li.strolch.privilege.handler.MailUserChallengeHandler which sends a challenge to the user\u0026rsquo;s defined e-mail address. \u0026lt;SsoHandler\u0026gt; the SSO Handler is used to implement a SingleSignOn and can be used to start a session using a LDAP token, etc. There is no default implementation as this is project specific. \u0026lt;Policies\u0026gt; configures the available privilege policies at runtime, the name is referenced from the model file The PrivilegeUsers.xml and PrivilegeRoles.xml define the users and roles and is used when in PrvilegeConfig.xml the PersistenceHandler is set to ch.eitchnet.privilege.handler.XmlPersistenceHandler:\n \u0026lt;Users\u0026gt; configures all users \u0026lt;User\u0026gt; configures a specific user \u0026lt;Firstname\u0026gt; configures a user\u0026rsquo;s first name \u0026lt;Lastname\u0026gt; configure a user\u0026rsquo;s last name \u0026lt;State\u0026gt; configures the user\u0026rsquo;s state, see li.strolch.privilege.model.UserState \u0026lt;Locale\u0026gt; configure the user\u0026rsquo;s locale \u0026lt;Roles\u0026gt; configures the user\u0026rsquo;s roles \u0026lt;Role\u0026gt; adds a role to the user \u0026lt;Properties\u0026gt; configures user specific properties. What properties are used is not specified and is dependent on the concrete agent \u0026lt;Property\u0026gt; defines a single property \u0026lt;Roles\u0026gt; configures all roles \u0026lt;Role\u0026gt; configures a specific role \u0026lt;Privilege\u0026gt; configures a specific privilege for this role \u0026lt;AllAllowed\u0026gt; if set to true, then defines that all values associated with this privilege are allowed \u0026lt;Allow\u0026gt; defines one allowed value for this privilege \u0026lt;Deny\u0026gt; defines one denied value for this privilege Implementing a StrolchComponent Implementing a strolch component requires an interface, which defines the component\u0026rsquo;s API and a concrete class which implements the interface and extends the class StrolchComponent.\nThe StrolchComponent class adds the state model to the class, which transitions as follows:\nUNDEFINED =\u0026gt; SETUP =\u0026gt; INITIALIZED =\u0026gt; STARTED \u0026lt;=\u0026gt; STOPPED =\u0026gt; DESTROYED\nComponents can switch between STARTED and STOPPED, but once DESTROYED no further state change is possible. The component\u0026rsquo;s state is changed by changes to the agent\u0026rsquo;s lifecycle.\nA component\u0026rsquo;s state is changed by a call to the appropriate method on the component, override the methods as necessary. Note that it is good practice that the initialize()-method is used to get all the configuration properties, and that they should there be evaluated and that the method so return quickly. The start()-method is called after the agent\u0026rsquo;s initialization and should be where additional threads are started. Correctly implementing these methods allows to quickly detect a wrongly configured agent, which might take longer to start for whatever reason.\nThe following shows a basic implementation of a component on the basis of a post initializer (a component which performs some actions in its start()-method which should be done after everything else is started in the agent).\npublic class SimplePostInitializer extends StrolchComponent implements PostInitializer { public SimplePostInitializer(ComponentContainer container, String componentName) { super(container, componentName); } @Override public void initialize(ComponentConfiguration configuration) { // do some initialization, validate configuration values, etc. // now call super, to update state super.initialize(configuration); } @Override public void start() { // start any threads, or perform long running start work // now call super, to update state super.start(); } @Override public void stop() { // stop threads and timers, but be ready to start again // now call super, to update state super.stop(); } @Override public void destroy() { // destroy this component, release all resources and don\u0026#39;t worry about // being called to start again now call super, to update state super.destroy(); } } The new component would then be registered in the StrolchConfiguration.xml as follows:\n\u0026lt;StrolchConfiguration\u0026gt; \u0026lt;env id=\u0026#34;...\u0026#34;\u0026gt; ... \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;SimplePostInitializer\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.agent.api.PostInitializer\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.documentation.SimplePostInitializer\u0026lt;/impl\u0026gt; \u0026lt;/Component\u0026gt; ... \u0026lt;/env\u0026gt; \u0026lt;/StrolchConfiguration\u0026gt; And can be access at runtime using:\nPostInitializer postInitializer = getContainer().getComponent(PostInitializer.class); Starting the agent When a Strolch runtime is started, then the root path to the runtime configuration must be passed. In Java this is done by calling:\nStrolchAgent agent = new StrolchAgent(); agent.setup(environment, rootPath); agent.initialize(); agent.start(); In Servlet 3.0 applications one would implement the javax.servlet.ServletContextListener interface, add the @WebListener annotation to the class and in the contextInitialized()-method start Strolch:\nString realPath = sce.getServletContext().getRealPath(\u0026#34;/WEB-INF\u0026#34;); String environment = StrolchEnvironment.getEnvironmentFromEnvProperties(pathF); this.agent = new StrolchAgent(); this.agent.setup(environment, new File(realPath)); this.agent.initialize(); this.agent.start(); "},{"uri":"https://strolch.li/tutorial/","title":"Tutorial","tags":[],"description":"","content":"Let\u0026rsquo;s build a bookshop! In this tutorial we will build a book store using Strolch. This book store will be without a UI, but we will do everything using REST APIs, which should make it easy to add a UI later using whatever framework suits one most.\nThe book store will have the following features:\n The store owner can add, update and remove books The store owner can edit the stock quantity Users can view a list of books Users can add books to a virtual cart Users can create and verify an account using an e-mail address Users can submit an order for the books in their cart The store owner can see the orders by state (pending, preparing, sent) The store owner can update the state of an order (preparing, sent) Notify the user when the order is sent The code to the book can be downloaded from GitHub and will be updated as this tutorial is updated.\nThe tutorial consists of the following parts: Configuration Model CRUD Book "},{"uri":"https://strolch.li/development/web-app/","title":"Web App","tags":[],"description":"","content":"Prerequisites To start developing web-based Strolch apps you need the following:\n Apache Tomcat 9.x (10.x isn\u0026rsquo;t supported yet). Just unpack it somewhere, to be used later, when running the application. NodeJS v11.x (other versions don\u0026rsquo;t work with Bower, the installation is described below. Note: Strolch\u0026rsquo;s Web UI is still using Polymer 1.x. This isn\u0026rsquo;t a big concern, as thanks to the polyfills, it works on all browsers, including Internet Explorer 11.\n Install the web dependencies The Strolch Web App uses NodeJS v11.x to build the web dependencies. Please download the relevant platform\u0026rsquo;s package, unpack it, and add the bin directory to your path variable and add a NODE_HOME variable pointing to the root directory of the NodeJS folder.\nTest that NodeJS is working properly:\n$ npm --version 6.8.0 Once NodeJS is installed, then you can prepare the web dependencies:\nnpm install -g bower npm install -g gulp And then check that both bower and gulp work as expected:\n$ bower --version 1.8.14 $ gulp --version [17:22:56] CLI version 2.0.1 Creating a Strolch Web App The following shows the maven command to create the new maven project using Strolch\u0026rsquo;s webapp maven archetype. Note that you should replace the placeholders in the brackets:\nNote: you need to have the Strolch Maven archetypes installed to your local maven repo, otherwise the following command will fail.\n mvn archetype:generate \\ -DarchetypeGroupId=li.strolch \\ -DarchetypeArtifactId=strolch.mvn.archetype.webapp \\ -DarchetypeVersion=0.1.0-SNAPSHOT \\ -DgroupId=\u0026lt;my.groupid\u0026gt; \\ -DartifactId=\u0026lt;my-artifactId\u0026gt; \\ -Dversion=\u0026lt;my.version\u0026gt; \\ -Dpackage=\u0026lt;my.package\u0026gt; \\ -DappName=\u0026#34;\u0026lt;my app name\u0026gt;\u0026#34; Installing the web dependencies In the newly generated artifact, change to the webapp folder, and then run npm install:\ncd \u0026lt;my-artifactId\u0026gt;/src/main/webapp npm install This will first install the NodeJS modules, and then call bower to install the bower packages.\nNote: Whenever the bower.json is changed, e.g. updating a version or adding a package, then you should again call npm install inside the webapp folder.\n Building and running the WAR locally Once the web dependencies are installed, all components are available to finally build the WAR and run it on a servlet container. The archetype is pre-configured to run using the dev-local Strolch runtime environment configuration. This can be achieved by compiling using the following command:\nmvn clean package -Prelease -Dstrolch.env=dev.local Building the WAR uses the package maven goal, but to have the optimized WAR use the release profile. The environment variable strolch.env=dev.local configures the WAR to have its runtime point to the absolute path where the sources are located.\nAfter the build is complete, the WAR will be located in the target/ directory. Copy it to Tomcat\u0026rsquo;s webapps/ directory and then start tomcat with the following command:\ncd tomcat9/bin ./catalina.sh run Tomcat should then see the WAR and deploy it. If everything was setup correctly, then you should see the following in the logs after startup:\nINFO l.s.a.impl.ComponentContainerImpl:283 start - System: OS: Linux 5.16.15 Arch: amd64 on Java Azul Systems, Inc. 17 CPU Cores: 32 INFO l.s.a.impl.ComponentContainerImpl:284 start - Memory: Memory available 16.8 GB / Used: 604.0 MB / Free: 540.6 MB INFO l.s.a.impl.ComponentContainerImpl:285 start - Using locale en with timezone Europe/Zurich INFO l.s.a.impl.ComponentContainerImpl:288 start - file.encoding: UTF-8 / sun.jnu.encoding UTF-8 INFO l.s.a.impl.ComponentContainerImpl:307 start - \u0026lt;my-artifactId\u0026gt;:dev All 12 Strolch Components started. Took 120ms. Strolch is now ready to be used. Have fun =)) INFO li.strolch.test.web.StartupListener:43 contextInitialized - Started \u0026lt;my app name\u0026gt; in 557ms And now you can open a browser and login: http://localhost:8080/\u0026lt;my-artifactId\u0026gt;\nThe default username and password are admin / admin. After logging in, you should be greeted with the following screen: Running the WAR on a remote system The sources currently are configured for the dev.local environment. To use the WAR on a remote system, we need to configure another environment, and have the path of the runtime updated in the StrolchBootstrap.xml file. Open the file src/main/resources/StrolchBootstrap.xml and modify the root path in the test environment:\n\u0026lt;env id=\u0026#34;test\u0026#34; default=\u0026#34;true\u0026#34;\u0026gt; \u0026lt;root\u0026gt;/absolute/path/to/runtime\u0026lt;/root\u0026gt; \u0026lt;environment\u0026gt;test\u0026lt;/environment\u0026gt; \u0026lt;/env\u0026gt; Now you need to copy the existing runtime directory to the remote machine at the above location.\nNow we can build the project using the test environment:\nmvn clean package -Prelease -Dstrolch.env=test Now copy the WAR from the target/ directory to the webapps/ directory of your Tomcat 9.x installation. Now you can start tomcat using:\ncatalina.sh run In the console you\u0026rsquo;ll then see something like this:\nINFO l.s.a.impl.ComponentContainerImpl:283 start - System: OS: Linux 5.16.15 Arch: amd64 on Java Azul Systems, Inc. 17 CPU Cores: 32 INFO l.s.a.impl.ComponentContainerImpl:284 start - Memory: Memory available 16.8 GB / Used: 604.0 MB / Free: 540.6 MB INFO l.s.a.impl.ComponentContainerImpl:285 start - Using locale en with timezone Europe/Zurich INFO l.s.a.impl.ComponentContainerImpl:288 start - file.encoding: UTF-8 / sun.jnu.encoding UTF-8 INFO l.s.a.impl.ComponentContainerImpl:307 start - \u0026lt;my-artifactId\u0026gt;:test All 12 Strolch Components started. Took 43ms. Strolch is now ready to be used. Have fun =)) INFO c.atexxi.esytest.web.StartupListener:43 contextInitialized - Started \u0026lt;my app name\u0026gt; in 244ms And now you can open a browser and login: http://remove-server:8080/\u0026lt;my-artifactId\u0026gt;\nThe default username and password are admin / admin. After logging you, you should see the following view:\nHappy coding =))\n"},{"uri":"https://strolch.li/plc/architecture/","title":"Architecture","tags":[],"description":"","content":"Architecture Overview The Strolch PLC architecture sees the Strolch Agent as the server, managing logical devices, i.e. multiple sensors and actors together and thus deciding on further steps. With this architecture multiple PLCs can be combined in one agent for flow control.\nPLC Architecture On the agent side the two main classes are the PlcGwServerHandler and the PlcGwService\nThe PlcGwServerHandler handles connections from remote PLCs over WebSockets and sends the requests to these PLCs. A PlcGwService instance will be notified and can then decide on an action. In an execution model with Activities, the PlcNotificationListener interface can be implemented, or the PlcExecutionPolicy can be directly extended.\nOn the PLC side, the PlcGwClientHandler is optional if no agent is required. The PlcHandler initializes the model and connections. The Plc class is Strolch agnostic and manages the connections and notifies PlcListener instances on changes coming from the underlying connections. The PlcService implementations implement business logic, and can also be notified on updates from connections.\n"},{"uri":"https://strolch.li/development/main-class-app/","title":"Main Class App","tags":[],"description":"","content":"Creating a Strolch App The following shows the maven command to create the new maven project using Strolch\u0026rsquo;s main maven archetype. Note that you should replace the placeholders in the brackets:\nNote: you need to have the Strolch Maven archetypes installed to your local maven repo, otherwise the following command will fail.\n mvn archetype:generate \\ -DarchetypeGroupId=li.strolch \\ -DarchetypeArtifactId=strolch.mvn.archetype.main \\ -DarchetypeVersion=0.1.0-SNAPSHOT \\ -DgroupId=\u0026lt;my.groupid\u0026gt; \\ -DartifactId=\u0026lt;my-artifactId\u0026gt; \\ -Dversion=\u0026lt;my.version\u0026gt; \\ -DappName=\u0026#34;\u0026lt;my app name\u0026gt;\u0026#34; You change into the directory of the new project and then build the project by calling:\ncd \u0026lt;my-artifactId\u0026gt; mvn clean package Start the program using:\nmvn exec:java Happy coding =))\n"},{"uri":"https://strolch.li/documentation/realms/","title":"Realms","tags":[],"description":"","content":"Realms Realms implement multi-tenant capabilities. A Strolch agent can have an arbitrary number of realms configured and each realm has its own persistence configuration, allowing to separate mandates completely.\nA realm can run in one of the following modes:\n EMPTY This is a transient data store mode, where no model changes are persisted - they are only kept in memory. When the Strolch agent is started, this realm is empty as no data is loaded. TRANSIENT This is the same as EMPTY, but with the difference that when the Strolch agent is started, a model file is parsed and the in-memory realm is populated with the elements parsed from the model file. CACHED In this mode, all data is stored in-memory, and any changes made are written back to the persistence layer. This allows for fast in-memory qeuries, but makes sure no data is lost when the agent is restarted. Realms are mostly hidden from a developer as a StrolchTransaction exposes all important operations needed to access Strolch objects. A developer will however need to configure the realms for their specific project. If the project only requires one realm, then the defaultRealm can be used, where the developer only is required to configure the mode and any relevant model file.\nIf the mode is CACHED, then the PersistenceHandler component is required to be configured, so that the DAOs know how to access the underlying database.\nThe configuration in the StrolchConfiguration.xml file is as follows:\n\u0026lt;StrolchConfiguration\u0026gt; \u0026lt;env id=\u0026#34;dev\u0026#34;\u0026gt; ... \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;RealmHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.agent.api.RealmHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.agent.impl.DefaultRealmHandler\u0026lt;/impl\u0026gt; \u0026lt;depends\u0026gt;PrivilegeHandler\u0026lt;/depends\u0026gt; \u0026lt;!-- if CACHED: --\u0026gt; \u0026lt;!--depends\u0026gt;PersistenceHandler\u0026lt;/depends--\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;!-- one of EMPTY, TRANSIENT, CACHED--\u0026gt; \u0026lt;dataStoreMode\u0026gt;TRANSIENT\u0026lt;/dataStoreMode\u0026gt; \u0026lt;dataStoreFile\u0026gt;StrolchModel.xml\u0026lt;/dataStoreFile\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; ... \u0026lt;/env\u0026gt; \u0026lt;/StrolchConfiguration\u0026gt; Multi-Realm A multi-realm configuration would be as follows.\nNote how the defaultRealm is still enabled, and has its configuration as before. Further the PostgreSQL PersistenceHandler is configured to show how the realms are connected to the persistence handler:\n \u0026lt;StrolchConfiguration\u0026gt; \u0026lt;env id=\u0026#34;dev\u0026#34;\u0026gt; ... \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;RealmHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.agent.api.RealmHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.agent.impl.DefaultRealmHandler\u0026lt;/impl\u0026gt; \u0026lt;depends\u0026gt;PrivilegeHandler\u0026lt;/depends\u0026gt; \u0026lt;depends\u0026gt;PersistenceHandler\u0026lt;/depends\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;realms\u0026gt;defaultRealm, cachedRealm\u0026lt;/realms\u0026gt; \u0026lt;dataStoreMode\u0026gt;TRANSIENT\u0026lt;/dataStoreMode\u0026gt; \u0026lt;dataStoreFile\u0026gt;DefaultRealm.xml\u0026lt;/dataStoreFile\u0026gt; \u0026lt;dataStoreMode.cachedRealm\u0026gt;CACHED\u0026lt;/dataStoreMode.cachedRealm\u0026gt; \u0026lt;dataStoreMode.emptyRealm\u0026gt;EMPTY\u0026lt;/dataStoreMode.emptyRealm\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;PersistenceHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.persistence.api.PersistenceHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.persistence.postgresql.PostgreSqlPersistenceHandler\u0026lt;/impl\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;allowSchemaCreation\u0026gt;true\u0026lt;/allowSchemaCreation\u0026gt; \u0026lt;allowSchemaDrop\u0026gt;true\u0026lt;/allowSchemaDrop\u0026gt; \u0026lt;db.url.cachedRealm\u0026gt;jdbc:postgresql://localhost/testdb2\u0026lt;/db.url.cachedRealm\u0026gt; \u0026lt;db.username.cachedRealm\u0026gt;testuser2\u0026lt;/db.username.cachedRealm\u0026gt; \u0026lt;db.password.cachedRealm\u0026gt;test\u0026lt;/db.password.cachedRealm\u0026gt; \u0026lt;db.pool.maximumPoolSize.cachedRealm\u0026gt;1\u0026lt;/db.pool.maximumPoolSize.cachedRealm\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; ... \u0026lt;/env\u0026gt; \u0026lt;/StrolchConfiguration\u0026gt; Access realm Accessing a realm is done in multiple ways. Important is to note, that a user should use the StrolchTransaction object, instead of accessing the Realm directly.\nOpening a transaction is done from a Service by calling one of the openTx()-methods. Nevertheless, the realm can be accessed as follows:\npublic class Example { public static void main(String[] args) { ComponentContainer container = getAgent().getContainer(); StrolchRealm realm = container.getRealm(StrolchConstants.DEFAULT_REALM); try (StrolchTransaction tx = realm.openTx()) { Resource resource = tx.getResourceBy(\u0026#34;TestType\u0026#34;, \u0026#34;MyTestResource\u0026#34;); } } } "},{"uri":"https://strolch.li/documentation/components/","title":"Components","tags":[],"description":"","content":"Components A Strolch agent can be easily extended with arbitrary components. An agent is basically a container for classes extending StrolchComponent with a life cycle. These classes mostly implement an interface which describes the operations that are supported by the component.\nThe following represents a list of the most used components:\n RealmHandler: li.strolch.agent.impl.DefaultRealmHandler PrivilegeHandler: li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler EnumHandler: li.strolch.runtime.query.enums.DefaultEnumHandler PolicyHandler: li.strolch.policy.DefaultPolicyHandler ServiceHandler: li.strolch.service.api.DefaultServiceHandler StrolchSessionHandler: li.strolch.rest.DefaultStrolchSessionHandler PersistenceHandler: multiple implementations PostInitializer: project specific implementation MailHandler: li.strolch.handler.mail.SmtpMailHandler A component has a life-cycle, which is governed by the Agent\u0026rsquo;s own life-cycle. The life-cycle is as follows:\nsetup -\u0026gt; initialize -\u0026gt; start \u0026lt;-\u0026gt; stop -\u0026gt; destroy The setup step is used to instantiate the component, the initialize step is used to validate configuration parameters, and the run step is used to start the component, i.e. start threads, etc. The stop step stops these threads and also allows the component to be started again. The destroy step destroys the instance and makes it unusable anymore, i.e. shutdown of the agent.\nEach component has its own configuration parameters. A component is registered in the StrolchConfiguration.xml file with a\n name api class name implementation class name configuration parameters any required dependencies The dependencies is an important feature as the dependencies of a component are always started before the actual component.\nExample Component implementation and configuration By example of the MailHandler we shall show how a strolch component would be implemented.\nFirst define an interface:\npublic interface MailHandler { void sendMail(String subject, String text, String recipient); } Then implement a concrete MailHandler:\npublic class SmtpMailHandler extends StrolchComponent implements MailHandler { // TODO instance fields with configuration properties to send the mail public SmtpMailHandler(ComponentContainer container, String componentName) { super(container, componentName); } @Override public void initialize(ComponentConfiguration configuration) throws Exception { // TODO store any properties needed from the configuration super.initialize(configuration); } @Override public void sendMail(String subject, String text, String recipient) { // TODO send the e-mail using SMTP, or send asynchronously } } Now that the component is written, it must be registered on the component, so that it is loaded when the agent is started. For this the StrolchConfiguration.xml file must be modified to include a component element:\n\u0026lt;StrolchConfiguration\u0026gt; \u0026lt;env id=\u0026#34;dev\u0026#34;\u0026gt; ... \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;MailHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.handler.mail.MailHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.handler.mail.SmtpMailHandler\u0026lt;/impl\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;username\u0026gt;test\u0026lt;/username\u0026gt; \u0026lt;password\u0026gt;test\u0026lt;/password\u0026gt; \u0026lt;hostName\u0026gt;localhost\u0026lt;/hostName\u0026gt; ... \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; ... \u0026lt;/env\u0026gt; \u0026lt;/StrolchConfiguration\u0026gt; Now when the agent is started, the component can be retrieved and used. E.g from inside a Service:\npublic class MyService extends AbstractService\u0026lt;ServiceArgument, ServiceResult\u0026gt; { @Override protected ServiceResult internalDoService(ServiceArgument arg) throws Exception { MailHandler mailHandler = getComponent(MailHandler.class); mailHandler.sendMail(\u0026#34;My Subject\u0026#34;, \u0026#34;Hello World\u0026#34;, \u0026#34;test@test.ch\u0026#34;); } } "},{"uri":"https://strolch.li/documentation/services-and-commands/","title":"Services and Commands","tags":[],"description":"","content":"Services and Commands Services are written to implement a specific use-case. Commands are written to implement re-usable parts of a use-case. The use-case can be abstract e.g., AddResourceService or very specific e.g. CreatePatientService.\nShould the use-case be re-usable in different scenarios, then commands should implement the logic, and the services should then execute the commands. E.g. The CreatePatientService would use a CreatePatientResourceCommand and then use an AddResourceCommand in a single transaction, so that the task of creating the actual Patient Resource can be re-used somewhere else.\nServices extend the abstract class AbstractService and then implement the method internalDoService(ServiceArgument). AbstractService defines generic template arguments with which the concrete service can define a specific input ServiceArgument class and output ServiceResult class.\nThe AbstractService class has multiple helper methods:\n openTx():StrolchTransaction - to open a transaction runPrivileged() - to perform a SystemUserAction getComponent():V - to retrieve a specific StrolchComponent there are more - check the JavaDocs.\nCommands extend the Command class and then implement the method doCommand(). Commands have helper methods:\n tx() - to get the current transaction getPolicy() - to retrieve a StrolchPolicy instance runPrivileged() - to perform a SystemUserAction there are more - check the JavaDocs.\nThe following code snippets shows how a Service and Command are used to perform the task of adding a new Order. Note how:\n the Service opens the transaction adds the command to the TX calls tx.commitOnClose() the command validates its input locks the object performs the work and implements an undo AddOrderService:\npublic class AddOrderService extends AbstractService\u0026lt;AddOrderService.AddOrderArg, ServiceResult\u0026gt; { @Override protected ServiceResult getResultInstance() { return new ServiceResult(); } @Override protected ServiceResult internalDoService(AddOrderArg arg) { try (StrolchTransaction tx = openTx(arg.realm)) { AddOrderCommand command = new AddOrderCommand(getContainer(), tx); command.setOrder(arg.order); tx.addCommand(command); tx.commitOnClose(); } return ServiceResult.success(); } public static class AddOrderArg extends ServiceArgument { public Order order; } } AddOrderCommand:\npublic class AddOrderCommand extends Command { private Order order; public AddOrderCommand(ComponentContainer container, StrolchTransaction tx) { super(container, tx); } public void setOrder(Order order) { this.order = order; } @Override public void validate() { DBC.PRE.assertNotNull(\u0026#34;Order may not be null!\u0026#34;, this.order); } @Override public void doCommand() { tx().lock(this.order); OrderMap orderMap = tx().getOrderMap(); if (orderMap.hasElement(tx(), this.order.getType(), this.order.getId())) { String msg = MessageFormat.format(\u0026#34;The Order {0} already exists!\u0026#34;, this.order.getLocator()); throw new StrolchException(msg); } orderMap.add(tx(), this.order); } @Override public void undo() { if (this.order != null \u0026amp;\u0026amp; tx().isRollingBack()) { OrderMap orderMap = tx().getOrderMap(); if (orderMap.hasElement(tx(), this.order.getType(), this.order.getId())) orderMap.remove(tx(), this.order); } } } "},{"uri":"https://strolch.li/download/","title":"Download","tags":[],"description":"","content":"Download Strolch is on Maven central , but if the latest version is not there, then build it locally. A guide can be found on the development page.\nStrolch is also built on Jenkins, so you can see if the latest version passes all tests.\nInclude as Maven dependency The easiest way to include strolch in your project is to use the following maven dependency:\n\u0026lt;project\u0026gt; \u0026lt;properties\u0026gt; \u0026lt;strolch.version\u0026gt;1.8.5\u0026lt;/strolch.version\u0026gt; \u0026lt;/properties\u0026gt; \u0026lt;dependencies\u0026gt; \u0026lt;dependency\u0026gt; \u0026lt;groupId\u0026gt;li.strolch\u0026lt;/groupId\u0026gt; \u0026lt;artifactId\u0026gt;li.strolch.bom\u0026lt;/artifactId\u0026gt; \u0026lt;type\u0026gt;pom\u0026lt;/type\u0026gt; \u0026lt;version\u0026gt;${strolch.version}\u0026lt;/version\u0026gt; \u0026lt;scope\u0026gt;import\u0026lt;/scope\u0026gt; \u0026lt;/dependency\u0026gt; \u0026lt;/dependencies\u0026gt; \u0026lt;/project\u0026gt; The bom will include all Strolch modules, you can always exclude a dependency, or only include the dependencies you really want, e.g. model, etc.\nAfter including the dependency, checkout development on how to turn your project into a Strolch agent.\n"},{"uri":"https://strolch.li/documentation/searches/","title":"Searches","tags":[],"description":"","content":"Searches As is custom for every framework, querying, or searching, the model must be possible. Strolch searches are implemented using the StrolchSearch class and one of its concrete implementations: ResourceSearch, OrderSearch, ActivitySearch.\nA Strolch element always has two identifiers: Type and Id. The type is important as it classifies an element. So if a car and a house would be modelled in Strolch, then those would both be a Resource, but one of type Car and the other of type House. Both would have different parameters. Thus when searching for objects, the first thing to do is define the type of object being searched.\nThe Strolch search API is very expressive and offers multiple ways to perform the same search. The search API consists of three components: The search classes, the search expressions and the search predicates. The concept was taken from the Apache Camel project.\nThere are four main search classes:\n RootElementSearch - search for any of Resource, Order or Activity elements ResourceSearch - search for Resources OrderSearch - search for Orders ActivitySearch - search for Activities No search is useful without a where clause, which are called search expressions. When writing a search, there are multiple ways to add such where clauses. Either\n override the define()-method in your sub class and add the where clauses by calling the where() method, or define special methods on the class e.g. byColor() which also calls the where()-method to add a search expression, or directly call the where()-method after instantiating a search. When extending the class, then the search expressions are available as methods on the super class, otherwise you can statically import them from ExpressionsSupport .\nAnd of course a where clause needs operators, which are called search predicates. Just as search expressions are available in sub classes, so are search predicates and can also be statically imported through PredicatesSupport .\nExamples of search expressions with search predicates follow:\nResourceSearch search=new ResourceSearch(); // predicate either as parameter, or chained search.where(id().isEqualTo(\u0026#34;myId\u0026#34;)); search.where(id(isEqualTo(\u0026#34;myId\u0026#34;))); // negating search.where(id(isEqualTo(\u0026#34;myId\u0026#34;)).not()); search.where(param(\u0026#34;bagId\u0026#34;,\u0026#34;paramId\u0026#34;).isIn(Arrays.asList(\u0026#34;red\u0026#34;,\u0026#34;blue\u0026#34;,\u0026#34;green\u0026#34;))); search.where(paramNull(\u0026#34;bagId\u0026#34;,\u0026#34;paramId\u0026#34;))); // boolean operations search.where(id(isEqualTo(\u0026#34;myId\u0026#34;)) // \t.or(name(isEqualTo(\u0026#34;myName\u0026#34;)))); Note how the predicates can be chained to the search expression, or passed as a parameter to the expression.\nIn addition to using predefined search search expressions, one can also just pass a lambda expression which performs a custom filter:\npersonSearch.where(person -\u0026gt; person.getName().length() == 3); See the StrolchSearchTest for many ways in which you can implement tests.\nNote that strolch searches requires privileges, thus when you use a strolch search, add it to the role of the user in PrivilegeRoles.xml:\n \u0026lt;Privilege name=\u0026#34;li.strolch.search.StrolchSearch\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;Allow\u0026gt;internal \u0026lt;/Allow\u0026gt; \u0026lt;!-- internal used for when the search is done in an internal service --\u0026gt; \u0026lt;Allow\u0026gt;li.strolch.bookshop.search.BookSearch\u0026lt;/Allow\u0026gt; \u0026lt;/Privilege\u0026gt; "},{"uri":"https://strolch.li/documentation/queries/","title":"Queries","tags":[],"description":"","content":"Queries The Query API is deprecated and the search API should be used instead.\n As is custom for every framework, querying the model must be possible. Strolch queries are implemented using the StrolchQuery interface and one of its concrete implementations: ResourceQuery, OrderQuery, ActivityQuery.\nA Strolch element always has two identifiers: Type and Id. The type is important as it classifies an element. So if a car and a house would be modelled in Strolch, then those would both be a Resource, but one of type Car and the other of type House. Both would have different parameters.\nThus one of the inputs for every query is it\u0026rsquo;s type, which is defined as the navigation. It is said that we navigate to the Cars, or Houses. Thus when instantiating a ResourceQuery, pass the navigation to the type of Resource as well. Same applies for Orders and Activities.\nFurther input for a StrolchQuery are the selections. These selections get translated into RDBMS WHERE clauses. Selections support boolean operations thus allowing for complex querying.\nStrolchQueries also support Ordering and object transformation. Following classes provide the most used scenarios:\n OrderById OrderByName OrderByParameter *ToDomVisitor *ToSaxVisitor *ToJsonVisitor *ToFlatJsonVisitor Example: Query all resources of type Car:\ntry (StrolchTransaction tx = openTx()) { ResourceQuery\u0026lt;Resource\u0026gt; query = ResourceQuery.query(\u0026#34;Car\u0026#34;); query.withAny(); List\u0026lt;Resource\u0026gt; cars = tx.doQuery(query); } Example: Query all resources of type Car, order by Name and transform to JSON:\ntry (StrolchTransaction tx = openTx()) { ResourceQuery\u0026lt;JsonObject\u0026gt; query = ResourceQuery.query(\u0026#34;Car\u0026#34;, new ResourceToJsonVisitor(), new OrderByName()); query.withAny(); List\u0026lt;JsonObject\u0026gt; cars = tx.doQuery(query); } the previous example can also be written as follows:\ntry (StrolchTransaction tx = openTx()) { ResourceQuery\u0026lt;JsonObject\u0026gt; query = new ResourceQuery\u0026lt;\u0026gt;(); query.setNavigation(new StrolchTypeNavigation(\u0026#34;Car\u0026#34;)); query.setResourceVisitor(new ResourceToJsonVisitor()); query.withAny(); List\u0026lt;JsonObject\u0026gt; cars = tx.doQuery(query); } Example: Query all resources of type Car with color blue:\ntry (StrolchTransaction tx = openTx()) { ResourceQuery\u0026lt;Resource\u0026gt; query = ResourceQuery.query(\u0026#34;Car\u0026#34;); query.with(ParameterSelection.stringSelection(\u0026#34;parameters\u0026#34;, \u0026#34;color\u0026#34;, \u0026#34;blue\u0026#34;, StringMatchMode.es())); List\u0026lt;Resource\u0026gt; cars = tx.doQuery(query); } Example: Query all resources of type Car which are not blue:\ntry (StrolchTransaction tx = openTx()) { ResourceQuery\u0026lt;Resource\u0026gt; query = ResourceQuery.query(\u0026#34;Car\u0026#34;); query.not(ParameterSelection.stringSelection(\u0026#34;parameters\u0026#34;, \u0026#34;color\u0026#34;, \u0026#34;blue\u0026#34;, StringMatchMode.es())); List\u0026lt;Resource\u0026gt; cars = tx.doQuery(query); } Example: Query all resources of type Car with color blue or yellow:\ntry (StrolchTransaction tx = openTx()) { ResourceQuery\u0026lt;Resource\u0026gt; query = ResourceQuery.query(\u0026#34;Car\u0026#34;); query.or().with( ParameterSelection.stringSelection(\u0026#34;parameters\u0026#34;, \u0026#34;color\u0026#34;, \u0026#34;blue\u0026#34;, StringMatchMode.es()), ParameterSelection.stringSelection(\u0026#34;parameters\u0026#34;, \u0026#34;color\u0026#34;, \u0026#34;yellow\u0026#34;, StringMatchMode.es())); List\u0026lt;Resource\u0026gt; cars = tx.doQuery(query); } Example: Query all resources of type Car with color blue or yellow owned by Jill:\ntry (StrolchTransaction tx = openTx()) { ResourceQuery\u0026lt;Resource\u0026gt; query = ResourceQuery.query(\u0026#34;Car\u0026#34;); StringParameterSelection owner = ParameterSelection.stringSelection(\u0026#34;parameters\u0026#34;, \u0026#34;owner\u0026#34;, \u0026#34;Jill\u0026#34;, StringMatchMode.es()); OrSelection colors = new OrSelection().with( ParameterSelection.stringSelection(\u0026#34;parameters\u0026#34;, \u0026#34;color\u0026#34;, \u0026#34;blue\u0026#34;, StringMatchMode.es()), ParameterSelection.stringSelection(\u0026#34;parameters\u0026#34;, \u0026#34;color\u0026#34;, \u0026#34;yellow\u0026#34;, StringMatchMode.es())); query.and().with(owner, colors); List\u0026lt;Resource\u0026gt; cars = tx.doQuery(query); } "},{"uri":"https://strolch.li/development/converting-existing/","title":"Converting Existing App","tags":[],"description":"","content":"Converting an existing application You can convert an existing application to a Strolch agent, but this might be a bit daunting in the beginning. If you are planning on doing this, first create a test application using the maven archetypes, so that you can get a feel for the configuration.\nOnce that works, use the archetypes configuration to reconfigure your project to start as a Strolch agent.\nNote: Beware to select the archetype pertaining to your use case:\n For a web app use the strolch.mvn.archetype.webapp For an application with a main method use strolch.mvn.archetype.main "},{"uri":"https://strolch.li/development/","title":"Development","tags":[],"description":"","content":" Prerequisites Building Strolch Maven Archetypes Web App Main Class App Converting Existing App "},{"uri":"https://strolch.li/plc/example-set-up/","title":"Example Set-Up","tags":[],"description":"","content":"Example Set-Up This example setup describes the movement of containers over conveyors. The conveyors have motors which can be started and stopped by a GPIO output pin controlled on a Raspberry Pi and each conveyor has a light barrier to detect the occupancy of a container and the Raspberry Pi detects this on GPIO input pins.\nFurther at each conveyor location is a barcode reader to read the ID of a container.\nThe general idea is that the PLC notifies a Strolch agent of changes, and only turns conveyors on, when the agent gives the command. Thus the agent handles business logic and the PLC controls the I/Os.\nNew Project Create a new project using the PLC Strolch Maven Archetype:\nmvn archetype:generate \\ -DarchetypeGroupId=li.strolch \\ -DarchetypeArtifactId=strolch.mvn.archetype.plc \\ -DarchetypeVersion=0.1.0-SNAPSHOT \\ -DgroupId=\u0026lt;my.groupid\u0026gt; \\ -DartifactId=\u0026lt;my-artifactId\u0026gt; \\ -Dversion=\u0026lt;my.version\u0026gt; \\ -Dpackage=\u0026lt;my.package\u0026gt; \\ -DappName=\u0026#34;\u0026lt;my app name\u0026gt;\u0026#34; This will create a multi-module project:\n The \u0026lt;my-artifactId\u0026gt;-web module contains the server code, which handles notifications from the PLC, and can send telegrams to the PLC. The \u0026lt;my-artifactId\u0026gt;-plc-web module contains the PLC code, which connects to the server and communicates with the low-level hardware. The shared modules contains classes shared by both projects (e.g. constants, etc.). This project already contains a default PLC model in \u0026lt;my-artifactId\u0026gt;-plc-web/runtime/data/.\nThe following sections explains these files:\nstrolch-plc-example-connections.xml This file defines the hardware connections. The following connections are implemented:\n li.strolch.plc.core.hw.i2c.RSL366OverHorterI2c li.strolch.plc.core.hw.i2c.PCF8574InputConnection li.strolch.plc.core.hw.gpio.RaspiBcmGpioInputConnection li.strolch.plc.core.hw.gpio.RaspiBcmGpioOutputConnection li.strolch.plc.core.hw.i2c.Multi8BitI2cOutputConnection li.strolch.plc.core.hw.connections.DataLogicScannerConnection li.strolch.plc.core.hw.connections.LoggerOutConnection li.strolch.plc.core.hw.connections.RandomStringConnection See their respective classes for details.\nstrolch-plc-example.csv This file maps I/Os to Resources and Actions and is converted into Strolch Resource objects using the PlcAddressGenerator class.\nIn this example we will use simple Raspberry Pi GPIOs. For convenience, and also when sharing I/O definitions with external partners, it is easier to use a CSV file to define the I/Os and then use the PlcAddressGenerator to generate and validate the model.\nFor easier handling, use the following Google Sheet as a starting point: https://docs.google.com/spreadsheets/d/10fgTfR3FZCVbQ5bbh0xB1u8rLIaw2KEyO45VMv7y5ho/edit?usp=sharing\nThe CSV headers are as follows:\n Description → a simple description for this PlcAddress Type → Group → Must be the first line and generates a PlcLogicalDevice, all succeeding lines are grouped to this device. Add additional to group further devices Input → defines a boolean input Output → defines a boolean output Virtual → defines a virtual address which has no corresponding hardware connection. Used for internal communication. DataLogicScanner → defines an address to read barcodes from a DataLogic Scanner. The actions must be left empty as the keys Barcode (address), On and Off (telegrams) will be generated. SubType → For Input and Output types → DevPin, DevPin0 → Generates the address as \u0026lt;Connection\u0026gt;.\u0026lt;Device\u0026gt;.\u0026lt;Pin\u0026gt;. DevPin0 decrements the Device and Pin values by one for zero-indexed addressing. Pin → Generates the address as \u0026lt;Connection\u0026gt;.\u0026lt;Pin\u0026gt;. For Virtual types → Boolean String Integer Device → Device number Pin → The pin number on the device Resource → The resource ID with which to notify the agent Action1 → The action ID Action2 → The second action ID if required Connection → The ID of the PlcConnection with which this I/O is attached DeviceId → For type Group: Set the ID of this PlcLogicalDevice being generated Interted → For boolean inputs or outputs, if true, inverts the value Value → A default value, often used for virtual integer addresses Remote → if true, then the server will be notified of changes to this address When you use this file as input for the PlcAddressGenerator, then it will generate PlcLogicalDevice, PlcAddress and PlcTelegram elements. See the file strolch-plc-example.xml for an example.\nThe PlcLogicalDevice references the PlcAddress and PlcTelegram objects, and is then used in the UI for grouping.\nThe PlcAddress is used to store the current value and defines the keys with which the agent will be notified\nThe PlcTelegram is used to store default values to send, for specific keys. E.g. The action On would send true, and Off would send false. This is semantics, and is defined in each project depending on the hardware.\nRunning the example Once you have both the server and PLC instances running, you can login. The default username and password are admin / admin.\nAfter logging in to the PLC you should be greeted with the following screen: And after logging in to the server you should be greeted with the following screen: If the PLC could connect to the server, then the PLC Control icon should be activated. The actions Enable, Disable and Stop All send telegrams to the PLC, thus showing how the server would communicate with the PLC.\nCustomization PLC Now that the server and PLC are running, we can customize the code. On the PLC side you will want to create new li.strolch.plc.core.PlcService services by extending the class and then registering the service in CustomPlcServiceInitializer.\nSee the example StartupPlcService.\nServer On the server side, to register for notifications from the PLC, one would implement li.strolch.plc.gw.server.PlcGwService services and register them on the PlcHandler in the PostInitializer class.\nSee the example ModePlcSrvService.\n"},{"uri":"https://strolch.li/documentation/transactions/","title":"Transactions","tags":[],"description":"","content":"Transactions Strolch Transactions play a central role in a Strolch agent. A transaction is opened for a realm, and grants access to the model of the agent. Transactions are implemented as a Java try-with-resources by implementing the AutoCloseable interface. This makes it trivial to understand the scope of a transaction.\nTransactions handle the following:\n Opening and closing database connections Releasing locks to strolch elements, if tx.lock(StrolchRootElement) or tx.lock(Locator) was called Performing Commands by executing them in the added order, and validating them first. Exception handling Auditing Updating observers When a transaction is opened, it is by default read-only, i.e. does not perform any commands when it is closed. Should the TX perform commands, then it is important to call tx.commitOnClose(), but only at the end of the work, so that exception handling can properly work if something goes wrong.\nStrolchTransaction offers a myriad of methods:\n find element by its Locator get methods for elements by type and id, or using a StringParameter or StringListParameter references methods to add, update or remove elements assert privilege access get a new element by its template check if an element exists by type and id get streams for elements add commands for execution Transactions are opened by accessing the realm, but there are convenience methods depending on the use-case:\n In Services: by calling one of the openTx()-methods In Commands: Transactions are already open, use method tx() to get instance. REST API: RestfulStrolchComponent.openTx() Note: don\u0026rsquo;t open a new TX inside a TX for the same realm!\n Important is to always open the transaction as a try-with-resource block and to define if the TX should commit, or not:\ntry (StrolchTransaction tx = openTx(...)) { // read lock our object Locator ferrariLoc = Resource.locatorFor(\u0026#34;Car\u0026#34;, \u0026#34;ferrari\u0026#34;); tx.lock(ferrariLoc); // find a car by locator Resource ferrari = tx.findElement(ferrariLoc); // get a car by ID Resource opel = tx.getResourceBy(\u0026#34;Car\u0026#34;, \u0026#34;opel\u0026#34;, true); // modify ball opel.setName(\u0026#34;Opel Corsa\u0026#34;); tx.update(opel); // get by string reference StringParameter ownerP = ferrari.getParameter(\u0026#34;relations\u0026#34;, \u0026#34;owner\u0026#34;, true); Resource owner = tx.getResourceBy(ownerP, true); // get by string list reference StringListParameter previousOwnersP = opel.getParameter(\u0026#34;relations\u0026#34;, \u0026#34;previousOwners\u0026#34;, true); List\u0026lt;Resource\u0026gt; previousOwners = tx.getResourcesBy(previousOwnersP, true); // check resource exists if (tx.hasResource(\u0026#34;Car\u0026#34;, \u0026#34;audi\u0026#34;)) { Resource audi = tx.getResourceBy(\u0026#34;Car\u0026#34;, \u0026#34;audi\u0026#34;, true); // assert has privilege to remove a car tx.assertHasPrivilege(Operation.REMOVE, audi); // remove the car tx.remove(audi); } // iterate all cars tx.streamResources(\u0026#34;Car\u0026#34;).forEach(car -\u0026gt; { logger.info(\u0026#34;Car: \u0026#34; + car.getId()); }); // commit if TX was changed if (tx.needsCommit()) tx.commitOnClose(); } "},{"uri":"https://strolch.li/documentation/policies/","title":"Policies","tags":[],"description":"","content":"Policies Policies are an integral part when writing business logic in Strolch. In many cases it would suffice to write all such logic in Services and Commands, but as soon as behaviour can change, depending on the element being accessed, then this would quickly lead to many if/else blocks.\nSince writing large if/else blocks is not maintanable in the long run, Strolch offers a different approach. All Strolch elements can store Policy definitions. This is a simple key/value store where the key defines the type of policy, and the value references the policy to use.\nCurrently there are two ways to reference a policy in Strolch, either via a key which defines a further lookup in the PolicyHandler, or directly as the name of the class to instantiate.\nUsing policies in Strolch gives the additional possibility of easily changing the behaviour at runtime, as a Service and/or Command would delegate the behaviour to the currently configured policy on the releveant element.\nPolicies are implemented by defining an abstract class and extends StrolchPolicy. This abstract class then defines the API of the actual policy. A concrete class then extends this abstract class and implements the concrete methods.\nPolicies are registered on Resources, Orders, Activities and Actions. The following shows defining two policies on a Resource, a PlanningPolicy, an ExecutionPolicy in XML:\n\u0026lt;Resource Id=\u0026#34;myResource\u0026#34; Name=\u0026#34;My Resource\u0026#34; Type=\u0026#34;MyType\u0026#34;\u0026gt; ... \u0026lt;Policies\u0026gt; \u0026lt;Policy Type=\u0026#34;PlanningPolicy\u0026#34; Value=\u0026#34;key:SimplePlanning\u0026#34; /\u0026gt; \u0026lt;Policy Type=\u0026#34;ExecutionPolicy\u0026#34; Value=\u0026#34;java:li.strolch.policytest.TestSimulatedExecutionPolicy\u0026#34; /\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;/Resource\u0026gt; Note how the PlanningPolicy has a value of key:SimplePlanning and the ExecutionPolicy defines a reference to an actual class.\n To use the PolicyHandler, it must be configured in the StrolchConfiguration.xml as follows:\n\u0026lt;StrolchConfiguration\u0026gt; \u0026lt;env id=\u0026#34;dev\u0026#34;\u0026gt; \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;PolicyHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.policy.PolicyHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.policy.DefaultPolicyHandler\u0026lt;/impl\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;readPolicyFile\u0026gt;true\u0026lt;/readPolicyFile\u0026gt; \u0026lt;policyConfigFile\u0026gt;StrolchPolicies.xml\u0026lt;/policyConfigFile\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; \u0026lt;/env\u0026gt; \u0026lt;/StrolchConfiguration\u0026gt; And this policy handler implementation requires a file where the lookups for the policies is defined, e.g.:\n\u0026lt;StrolchPolicies\u0026gt; \u0026lt;PolicyType Type=\u0026#34;PlanningPolicy\u0026#34; Api=\u0026#34;li.strolch.policytest.TestPlanningPolicy\u0026#34;\u0026gt; \u0026lt;Policy Key=\u0026#34;SimplePlanning\u0026#34; Class=\u0026#34;li.strolch.policytest.TestSimplePlanningPolicy\u0026#34;/\u0026gt; \u0026lt;/PolicyType\u0026gt; \u0026lt;PolicyType Type=\u0026#34;ExecutionPolicy\u0026#34; Api=\u0026#34;li.strolch.execution.policy.ExecutionPolicy\u0026#34;\u0026gt; \u0026lt;Policy Key=\u0026#34;SimulatedExecution\u0026#34; Class=\u0026#34;li.strolch.execution.policy.RandomDurationExecution\u0026#34;/\u0026gt; \u0026lt;/PolicyType\u0026gt; \u0026lt;PolicyType Type=\u0026#34;ConfirmationPolicy\u0026#34; Api=\u0026#34;li.strolch.policytest.TestConfirmationPolicy\u0026#34;\u0026gt; \u0026lt;Policy Key=\u0026#34;NoConfirmation\u0026#34; Class=\u0026#34;li.strolch.policytest.TestNoConfirmationPolicy\u0026#34;/\u0026gt; \u0026lt;/PolicyType\u0026gt; \u0026lt;/StrolchPolicies\u0026gt; Now at runtime we can access the policies:\npublic class MyService extends AbstractService\u0026lt;ServiceArgument, ServiceResult\u0026gt; { @Override protected ServiceResult internalDoService(ServiceArgument arg) throws Exception { try (StrolchTransaction tx = openArgOrUserTx(arg)) { Resource res = tx.getResourceBy(\u0026#34;MyType\u0026#34;, \u0026#34;myTestResource\u0026#34;); PlanningPolicy planningPolicy = tx.getPolicy(res, PlanningPolicy.class); planningPolicy.plan(...); ExecutionPolicy executionPolicy = tx.getPolicy(res, ExecutionPolicy.class); executionPolicy.toExecution(...); tx.commitOnClose(); } return ServiceResult.success(); } } "},{"uri":"https://strolch.li/documentation/observers/","title":"Observers","tags":[],"description":"","content":"Observers All changes done in a Strolch transaction are recorded and then propagated to any registered observers.\nThe observer feature is opt-in and is configured for each realm. In the StrolchConfiguration.xml file enable observers by adding the enableObserverUpdates property per realm:\n\u0026lt;StrolchConfiguration\u0026gt; \u0026lt;env id=\u0026#34;dev\u0026#34;\u0026gt; ... \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;RealmHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.agent.api.RealmHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.agent.impl.DefaultRealmHandler\u0026lt;/impl\u0026gt; \u0026lt;depends\u0026gt;PrivilegeHandler\u0026lt;/depends\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;realms\u0026gt;defaultRealm, otherRealm\u0026lt;/realms\u0026gt; \u0026lt;enableObserverUpdates\u0026gt;true\u0026lt;/enableObserverUpdates\u0026gt; \u0026lt;dataStoreMode\u0026gt;TRANSIENT\u0026lt;/dataStoreMode\u0026gt; \u0026lt;dataStoreFile\u0026gt;StrolchModel.xml\u0026lt;/dataStoreFile\u0026gt; \u0026lt;enableObserverUpdates.otherRealm\u0026gt;true\u0026lt;/enableObserverUpdates.otherRealm\u0026gt; \u0026lt;dataStoreMode.otherRealm\u0026gt;TRANSIENT\u0026lt;/dataStoreMode.otherRealm\u0026gt; \u0026lt;dataStoreFile.otherRealm\u0026gt;StrolchModel.xml\u0026lt;/dataStoreFile.otherRealm\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; \u0026lt;/env\u0026gt; ... \u0026lt;/StrolchConfiguration\u0026gt; Registering for updates is done by registering an Observer on the ObserverHandler of the realm itself:\npublic class Example { public static void main(String[] args) { ObserverHandler observerHandler = container .getRealm(StrolchConstants.DEFAULT_REALM).getObserverHandler(); observerHandler.registerObserver(Tags.RESOURCE, new Observer() { @Override public void update(String key, List\u0026lt;StrolchRootElement\u0026gt; elements) { logger.info(elements.size() + \u0026#34; resources were updated!\u0026#34;); } @Override public void remove(String key, List\u0026lt;StrolchRootElement\u0026gt; elements) { logger.info(elements.size() + \u0026#34; resources were removed!\u0026#34;); } @Override public void add(String key, List\u0026lt;StrolchRootElement\u0026gt; elements) { logger.info(elements.size() + \u0026#34; resources were added!\u0026#34;); } }); } } "},{"uri":"https://strolch.li/documentation/versioning/","title":"Versioning","tags":[],"description":"","content":"Versioning One of Strolch\u0026rsquo;s features that sets it apart from other frameworks, is that versioning is baked into Strolch\u0026rsquo;s fabric. The feature is opt-in, as it is not required in all projects, but it only needs enabling, for all modifications to objects to be versioned, so that rollbacks can be done when needed.\nThe feature is enabled for each realm. In the StrolchConfiguration.xml file enable it by adding the enableVersioning propery per realm:\n\u0026lt;StrolchConfiguration\u0026gt; \u0026lt;env id=\u0026#34;dev\u0026#34;\u0026gt; ... \u0026lt;Component\u0026gt; \u0026lt;name\u0026gt;RealmHandler\u0026lt;/name\u0026gt; \u0026lt;api\u0026gt;li.strolch.agent.api.RealmHandler\u0026lt;/api\u0026gt; \u0026lt;impl\u0026gt;li.strolch.agent.impl.DefaultRealmHandler\u0026lt;/impl\u0026gt; \u0026lt;depends\u0026gt;PrivilegeHandler\u0026lt;/depends\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;realms\u0026gt;defaultRealm, otherRealm\u0026lt;/realms\u0026gt; \u0026lt;enableVersioning\u0026gt;true\u0026lt;/enableVersioning\u0026gt; \u0026lt;dataStoreMode\u0026gt;TRANSIENT\u0026lt;/dataStoreMode\u0026gt; \u0026lt;dataStoreFile\u0026gt;StrolchModel.xml\u0026lt;/dataStoreFile\u0026gt; \u0026lt;enableVersioning.otherRealm\u0026gt;true\u0026lt;/enableVersioning.otherRealm\u0026gt; \u0026lt;dataStoreMode.otherRealm\u0026gt;TRANSIENT\u0026lt;/dataStoreMode.otherRealm\u0026gt; \u0026lt;dataStoreFile.otherRealm\u0026gt;StrolchModel.xml\u0026lt;/dataStoreFile.otherRealm\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/Component\u0026gt; \u0026lt;/env\u0026gt; ... \u0026lt;/StrolchConfiguration\u0026gt; Once versioning is enabled, versioning is handled automatically. The API for versioning is implemented on the ElementMaps.\nExample: Revert to previous version of a Resource:\nResource res = tx.getResourceBy(\u0026#34;TestType\u0026#34;, \u0026#34;MyTestResource\u0026#34;); ResourceMap resourceMap = tx.getResourceMap(); Resource previousVersion = resourceMap.revertToVersion(tx, res); // or Resource previousVersion = resourceMap.revertToVersion(tx, \u0026#34;TestType\u0026#34;, \u0026#34;MyTestResource\u0026#34;, 1); Example: Retrieve all versions of a Resource:\nList\u0026lt;Resource\u0026gt; versions = resourceMap.getVersionsFor(tx, \u0026#34;TestType\u0026#34;, \u0026#34;MyTestResource\u0026#34;); Note: When reverting to a previous version, it is important to remember, that any references on an element to other elements will also be restored. As long as the relationship is to the same element, then this is not an issue, but should the relationship have changed, then it this must be handled and the user performing a revert be allowed to decided which element to reference in the reverted version.\n "},{"uri":"https://strolch.li/documentation/reports/","title":"Reports","tags":[],"description":"","content":"Reports Since Strolch has a generic model, it was rather straight forward to create a simple API for writing reports. In Strolch a report is defined by using its own model, i.e. a Report is a Resource of type Report.\nA report consists of the following parts:\n policy definition, thus allowing extensions basic configuration like base object type, order direction, etc. column definitions joins ordering definition filters An example of a report is as follows:\n\u0026lt;Resource Id=\u0026#34;stockReport\u0026#34; Name=\u0026#34;Stock Report\u0026#34; Type=\u0026#34;Report\u0026#34;\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;parameters\u0026#34; Name=\u0026#34;parameters\u0026#34; Type=\u0026#34;Parameters\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;objectType\u0026#34; Index=\u0026#34;20\u0026#34; Hidden=\u0026#34;false\u0026#34; Name=\u0026#34;Object Type\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Player\u0026#34; Value=\u0026#34;Player\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;descending\u0026#34; Name=\u0026#34;Descending order\u0026#34; Type=\u0026#34;Boolean\u0026#34; Value=\u0026#34;true\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;ordering\u0026#34; Name=\u0026#34;Ordering\u0026#34; Type=\u0026#34;Ordering\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;name\u0026#34; Name=\u0026#34;Name\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Player\u0026#34; Value=\u0026#34;$name\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;noTeamFilter\u0026#34; Name=\u0026#34;Filter\u0026#34; Type=\u0026#34;Filter\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;policy\u0026#34; Name=\u0026#34;Filter Policy\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;ReportFilterPolicy\u0026#34; Uom=\u0026#34;key:Equals\u0026#34; Value=\u0026#34;!\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;fieldRef\u0026#34; Name=\u0026#34;Field reference\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Slot\u0026#34; Value=\u0026#34;Bags/relations/team\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;columns\u0026#34; Name=\u0026#34;Display Columns\u0026#34; Type=\u0026#34;Display\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;name\u0026#34; Name=\u0026#34;Player\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Player\u0026#34; Value=\u0026#34;$name\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;birthDate\u0026#34; Name=\u0026#34;Birth date\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Player\u0026#34; Value=\u0026#34;Bags/parameters/birthDate\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;team\u0026#34; Name=\u0026#34;Team\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Team\u0026#34; Value=\u0026#34;$name\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;joins\u0026#34; Name=\u0026#34;Joins\u0026#34; Type=\u0026#34;Joins\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;Team\u0026#34; Index=\u0026#34;10\u0026#34; Hidden=\u0026#34;false\u0026#34; Name=\u0026#34;Team\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Team\u0026#34; Value=\u0026#34;Player\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;Policies\u0026gt; \u0026lt;Policy Type=\u0026#34;ReportPolicy\u0026#34; Value=\u0026#34;java:li.strolch.report.policy.GenericReport\u0026#34;/\u0026gt; \u0026lt;/Policies\u0026gt; \u0026lt;/Resource\u0026gt; This report\n shows all Resources of type player (parameter objectType) → marks the object type to be show in the filter criteria (default), and that its sorting index is at 20. orders the report by player\u0026rsquo;s name (parameter bag ordering) filters out all players with no team assigned (parameter bag noTeamFilter) defines three columns: Player, Birth date, Team (paramger bag columns) joins in the resource of type Team Uses the GenericReport class to generate the report GenericReport The default generic report implemented in Strolch has the following features and options:\nParameters The parameters bag can contain the following parameters:\n objectType → the base type of object to get the input for the report. This means that the Interpretation is set to one of:\n Resource-Ref Order-Ref Activity-Ref and that the UOM and value of the parameter is set to the type of element with which to retrieve the elements from the strolch model.\n descending → boolean flag to define if sorting is in descending order\n allowMissingColumns → flag to define if no exception should be thrown if a column is missing\n dateRangeSel → defines a lookup parameter to use as a date range selector. This requires input when executing the report\n Note: that the attributes Hidden and Index define the visibility and sorting index as filter criteria respectively.\n Lookups Many of the features of the generic report rely on looking up a value on the referenced element. The following shows the ways that a lookup can be performed:\n $id → lookup the ID of the element $name → lookup the name of the element $type → lookup the type of the element $date → lookup the date of the element (only possible on Order and Activity elements) $state → lookup the state of the element (only possible on Order and Activity elements) Bags/\u0026lt;bag_id\u0026gt;/\u0026lt;param_id\u0026gt; → a lookup on the selected element by bag ID and parameter ID $search:\u0026lt;parent_ref_id\u0026gt;:Bags/\u0026lt;bag_id\u0026gt;/\u0026lt;param_id\u0026gt; → searches for a parameter with the given bag and parameter, and if it does not exist, looks for the parent with the given parent_ref_id on the element. This allows a recursive search up a tree of elements which all have the same parameter referencing a parent. relations bag Note: these definitions are set as the value of a Parameter, and the Interpretation and UOM of the parameter is used to find the element on which to perform the lookup. I.e. the following definition:\n \u0026lt;Parameter Id=\u0026#34;name\u0026#34; Name=\u0026#34;Player\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Player\u0026#34; Value=\u0026#34;$name\u0026#34;/\u0026gt; defines that we want to lookup the name of the resource of type Player.\nOrdering Ordering, i.e sorting is done by adding the parameter bag with the id ordering and each parameter defines a column to order by. The sequence of the ordering is defined by the index value assigned to each parameter.\nFiltering Filtering use additional Strolch Policies which implement the operator function. I.e. performing an equals, etc. The following ReportFilterPolicy are available and should be added in your StrolchPolicies.xml file:\n\u0026lt;StrolchPolicies\u0026gt; ... \u0026lt;PolicyType Type=\u0026#34;ReportFilterPolicy\u0026#34; Api=\u0026#34;li.strolch.report.policy.ReportFilterPolicy\u0026#34;\u0026gt; \u0026lt;Policy Key=\u0026#34;GreaterThan\u0026#34; Class=\u0026#34;li.strolch.report.policy.GreaterThanReportFilter\u0026#34;/\u0026gt; \u0026lt;Policy Key=\u0026#34;LessThan\u0026#34; Class=\u0026#34;li.strolch.report.policy.LessThanReportFilter\u0026#34;/\u0026gt; \u0026lt;Policy Key=\u0026#34;Equals\u0026#34; Class=\u0026#34;li.strolch.report.policy.EqualsReportFilter\u0026#34;/\u0026gt; \u0026lt;Policy Key=\u0026#34;Contains\u0026#34; Class=\u0026#34;li.strolch.report.policy.ContainsReportFilter\u0026#34;/\u0026gt; \u0026lt;Policy Key=\u0026#34;IsIn\u0026#34; Class=\u0026#34;li.strolch.report.policy.IsInReportFilter\u0026#34;/\u0026gt; \u0026lt;Policy Key=\u0026#34;ValueRef\u0026#34; Class=\u0026#34;li.strolch.report.policy.ValueRefReportFilter\u0026#34;/\u0026gt; \u0026lt;/PolicyType\u0026gt; ... \u0026lt;/StrolchPolicies\u0026gt; From this we can see that we can perform a GreaterThan, LessThan and Equals filtering. These filters can also be negated by prefixing the filter value with an exclamation mark (!).\nA special case for the filter values are filters on dates. If you are filtering on a date, then you can use the special operator now(). This filter will use the current date and time and will add/subtract the ISO8601 period passed as an argument to the operator.\nThe following shows examples of these filters:\n\u0026lt;ParameterBag Id=\u0026#34;minQtyFilter\u0026#34; Name=\u0026#34;Filter\u0026#34; Type=\u0026#34;Filter\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;policy\u0026#34; Name=\u0026#34;Filter Policy\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;ReportFilterPolicy\u0026#34; Uom=\u0026#34;key:GreaterThan\u0026#34; Value=\u0026#34;10\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;fieldRef\u0026#34; Name=\u0026#34;Field reference\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Product\u0026#34; Value=\u0026#34;Bags/parameters/quantity\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;notEmptyFilter\u0026#34; Name=\u0026#34;Filter\u0026#34; Type=\u0026#34;Filter\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;policy\u0026#34; Name=\u0026#34;Filter Policy\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;ReportFilterPolicy\u0026#34; Uom=\u0026#34;key:Equals\u0026#34; Value=\u0026#34;!\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;fieldRef\u0026#34; Name=\u0026#34;Field reference\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Team\u0026#34; Value=\u0026#34;Bags/relations/team\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; \u0026lt;ParameterBag Id=\u0026#34;threeMonthsAgoFilter\u0026#34; Name=\u0026#34;Filter\u0026#34; Type=\u0026#34;Filter\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;policy\u0026#34; Name=\u0026#34;Filter Policy\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;ReportFilterPolicy\u0026#34; Uom=\u0026#34;key:LessThan\u0026#34; Value=\u0026#34;now(-P3M)\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;fieldRef\u0026#34; Name=\u0026#34;Field reference\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;FromStock\u0026#34; Value=\u0026#34;$date\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; Note: One parameter defines which policy gets used and the key:\u0026lt;name\u0026gt; value references a policy defined in the StrolchPolicies.xml file. Further the lookup is defined in the fieldRef parameter.\n Joins To add columns from data which is not on the element denoted by the base object type, we can join further elements. This is done by adding the parameter bag joins and then each parameter references an element to join. The joining is done as follows:\n The Intepretation and UOM define which object we want to join, i.e. resource of type foo The value of the parameter defines the type of element on which to find the reference The join ordering is not relevant, as the tree is traversed accordingly At least one join must reference the base object type The lookup of the join is done by finding a parameter with any ID, which has the same Interpretation and UOM as the join definition The attributes Hidden and Index define the visibility and sorting index as filter criteria respectively. Thus the following:\n\u0026lt;ParameterBag Id=\u0026#34;joins\u0026#34; Name=\u0026#34;Joins\u0026#34; Type=\u0026#34;Joins\u0026#34;\u0026gt; \u0026lt;Parameter Id=\u0026#34;Team\u0026#34; Index=\u0026#34;10\u0026#34; Hidden=\u0026#34;false\u0026#34; Name=\u0026#34;Team\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Team\u0026#34; Value=\u0026#34;Player\u0026#34;/\u0026gt; \u0026lt;Parameter Id=\u0026#34;Country\u0026#34; Index=\u0026#34;5\u0026#34; Hidden=\u0026#34;false\u0026#34; Name=\u0026#34;Team\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Country\u0026#34; Value=\u0026#34;Team\u0026#34;/\u0026gt; \u0026lt;/ParameterBag\u0026gt; Performs two joins: First we join a resource of type Team by finding the relevant parameter on the Player resource, and then we lookup a resource of type Country on the previously joined Team resource.\nExecution of Reports To execute a reports, we must instantiate the Report and can then directly generate a JsonObject stream, which we can then pipe to a browser, file, etc.:\nStream\u0026lt;JsonObject\u0026gt; jsonObjectStream = new Report(tx, reportId).doReportAsJson(); If you prefer a CSV report:\ntry (CSVPrinter csvP = new CSVPrinter(new OutputStreamWriter(out), CSVFormat.DEFAULT.withHeader(headers).withDelimiter(\u0026#39;;\u0026#39;))) { // do report without AsJson, and then iterating each row and sending to a CSV writer report.doReport().forEach(row -\u0026gt; { try { csvP.printRecord(row.valueStream().collect(Collectors.toList())); // add to CSV } catch (Exception e) { logger.error(\u0026#34;Could not write CSV row\u0026#34;, e); } }); } Filter Criteria Predefining filters is a good start, but in some case you only want a portion of the actual filtered data. For instance if you make a stock report, you might only want one location. This information is dynamic and thus not stored on the report definition.\nTo perform these dynamic filterings, one would call the filter()-method on the report, passing the type of element to be filtered, and to which element IDs to reduce the report data to. The following reduces the report to only return the rows with the product01 Product and location02 Location elements:\nnew Report(tx, \u0026#34;stockReport\u0026#34;) .filter(\u0026#34;Product\u0026#34;, \u0026#34;product01\u0026#34;) .filter(\u0026#34;Location\u0026#34;, \u0026#34;location02\u0026#34;) .doReportAsJson() It is possible to find the possible filter criteria dynamically using the generateFilterCriteria() method.\nDate Range Filtering The last option to filter dynamically is using a date range selector. Define the dateRangeSel lookup parameter, and then set the date range on the instantiated report:\nModel the report in XML:\n\u0026lt;ParameterBag Id=\u0026#34;parameters\u0026#34; Name=\u0026#34;parameters\u0026#34; Type=\u0026#34;Parameters\u0026#34;\u0026gt; ... \u0026lt;Parameter Id=\u0026#34;dateRangeSel\u0026#34; Name=\u0026#34;Date Range Selector\u0026#34; Type=\u0026#34;String\u0026#34; Interpretation=\u0026#34;Resource-Ref\u0026#34; Uom=\u0026#34;Product\u0026#34; Value=\u0026#34;Bags/parameters/expirationDate\u0026#34;/\u0026gt; ... \u0026lt;/ParameterBag\u0026gt; And now call the report in Java:\nDate from = new Date(LocalDate.of(2016, 1, 1).toEpochDay() * 86400000); Date to = new Date(LocalDate.of(2017, 1, 1).toEpochDay() * 86400000); DateRange dateRange = new DateRange().from(from, true).to(to, false); List\u0026lt;JsonObject\u0026gt; result = new Report(tx, \u0026#34;stockReport\u0026#34;) // .filter(\u0026#34;Product\u0026#34;, \u0026#34;product01\u0026#34;) // .dateRange(dateRange) // .doReportAsJson() Note: See the GenericReportTest for examples.\n "},{"uri":"https://strolch.li/documentation/priviles/","title":"Privileges","tags":[],"description":"","content":"Privileges No framework is complete without user management and privilege validation. The basic form would be Users and Roles, and then validating that an authenticated user has a given role. In Strolch we go a step further: A User has roles assigned, and each role has a set of Privileges. The privileges can overlap, a validation is performed to make sure that the one role doesn\u0026rsquo;t deny and another role allows a specific action.\nAs explained in the Privilege Configuration section, users are defined in the PrivilegeUsers.xml file, and roles are defined in the PrivilegeRoles.xml file.\nLet\u0026rsquo;s assume the following user and role definition:\n\u0026lt;Users\u0026gt; \u0026lt;User userId=\u0026#34;1\u0026#34; username=\u0026#34;jill\u0026#34; password=\u0026#34;$PBKDF2WithHmacSHA512,10000,256$61646d696e$cb69962946617da006a2f95776d78b49e5ec7941d2bdb2d25cdb05f957f64344\u0026#34;\u0026gt; \u0026lt;Firstname\u0026gt;Jill\u0026lt;/Firstname\u0026gt; \u0026lt;Lastname\u0026gt;Someone\u0026lt;/Lastname\u0026gt; \u0026lt;State\u0026gt;ENABLED\u0026lt;/State\u0026gt; \u0026lt;Locale\u0026gt;en-GB\u0026lt;/Locale\u0026gt; \u0026lt;Roles\u0026gt; \u0026lt;Role\u0026gt;AppUser\u0026lt;/Role\u0026gt; \u0026lt;/Roles\u0026gt; \u0026lt;Properties\u0026gt; \u0026lt;Property name=\u0026#34;realm\u0026#34; value=\u0026#34;execution\u0026#34; /\u0026gt; \u0026lt;/Properties\u0026gt; \u0026lt;/User\u0026gt; \u0026lt;/Users\u0026gt; \u0026lt;Roles\u0026gt; \u0026lt;Role name=\u0026#34;AppUser\u0026#34;\u0026gt; \u0026lt;Privilege name=\u0026#34;li.strolch.service.api.Service\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;li.strolch.model.query.StrolchQuery\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;Privilege name=\u0026#34;li.strolch.search.StrolchSearch\u0026#34; policy=\u0026#34;DefaultPrivilege\u0026#34;\u0026gt; \u0026lt;AllAllowed\u0026gt;true\u0026lt;/AllAllowed\u0026gt; \u0026lt;/Privilege\u0026gt; \u0026lt;/Role\u0026gt; \u0026lt;/Roles\u0026gt; This configuration contains one user and one role. The user jill has the role AppUser and the role AppUser has three privileges assigned.\nNote how the user\u0026rsquo;s password is configured similar to a unix password definition: Using the dollar sign \u0026amp; first the hashing algorithm is configured ( algorithm, iterations, key length), then the salt, followed by the password hash.\nNote: The password can also still be saved using two separate fields: a salt and password field. This configuration will be immediately changed to the unix form, so won\u0026rsquo;t be described further here.\n Further a user always has a firstname and last name. Optionally a locale can be set, otherwise the system locale is used. The user\u0026rsquo;s state must be defined as one of NEW, ENABLED, DISABLED, EXPIRED or SYSTEM. A user can only authenticate/login with the state ENABLED. A user can have any number of properties, which can then be used at runtime. A user can also reference any number of roles, the assigned privilege can overlap, a global configuration mode defines how duplicate privileges are handled.\nRoles have a name and any number of Privilege definitions. A Privilege has a name, which in many cases is the name of Java class/interface on which an action is being invoked. The policy value defines which policy to use when evaluating the privilege access. The privilege definition is defined in the PrivilegeConfig.xml and is the name of a class to call for privilege validation.\nFurther the privilege definitions can have a AllAllowed boolean flag, or any number of Allow or Deny values. How these values are interpreted is defined in the policy implementation. A policy takes three input parameters:\n PrivilegeContext → supplied by privilege and gives access to the Certificate, thus identifying the user for which privilege access is to be validated. IPrivilege → Contains the privilege values: AllAllowed, Allow and Deny Restrictable → An interface from which the privilege name is retrieved, and the associated value. The value is an object, and is cast to the relevant input in the concrete privilege policy. The following privilege policies are already implemented:\n DefaultPrivilege → simple policy where the passed Restrictable is expected to return a String value, which is compared with allow and deny values. Internal: RoleAccessPrivilege → policy used for the internal privileges PrivilegeGetRole, PrivilegeAddRole, PrivilegeModifyRole or PrivilegeModifyRole Internal: UserAccessPrivilege → policy used for the internal privileges PrivilegeGetUser, PrivilegeAddUser, PrivilegeRemoveUser, PrivilegeModifyUser, PrivilegeAddRoleToUser, PrivilegeRemoveRoleFromUser, PrivilegeSetUserState, PrivilegeSetUserLocale or PrivilegeSetUserPassword Internal: UserAccessWithSameOrganisationPrivilege → Same as the UserAccessPrivilege but expects the authenticated user to have a property organisation and validates that the user being modified is in the same organisation. Internal: UsernameFromCertificatePrivilege → This policy expects a Restrictable to return the certificate of another authenticated user and is used when modifying an authenticated user, i.e. killing a session, or modifying its current state, e.g. locale etc. Internal: UsernameFromCertificateWithSameOrganisationPrivilege → Same as UsernameFromCertificatePrivilege but expects the authenticated user to have a property organisation and validates that the user being modified is in the same organisation. Note: As a rule, the sequence is AllAllowed → Allow → Deny → default deny\n "},{"uri":"https://strolch.li/history/","title":"History","tags":[],"description":"","content":"Overview Strolch is an open source component based software agent written in Java and can be compared, in a light sense, with the Java EE stack: Strolch takes care of persistence, implements Services for use cases, Commands as re-usable algorithms and has a parameterized data model.\nStrolch has an intrinsic understanding for mandates, which are called realms so that a single agent can be used to implement applications with multiple users/customers for instance in SaaS environments.\nThe parameterized data model consists of three top level objects, Resources, Orders and Activities. These objects can have any number of ParameterBags which in turn can have any number of Parameters on them. This allows for a very dynamic modelling of data structures including modification at run time. Multiple ready to use Parameter types are already implemented which handle the primitive types in Java including ListParameters for collections of these primitive types.\nOne of the main features of the Strolch agent, is that persistence is handled transparently and the user must not be worried about databases and the likes. Currently there are two implementations for persisting the Strolch model, a PostgreSQL and an XML file persistence. Currently both persistence layers persist the data by converting to XML and storing it into the database. The XML file persistence stores each object in its own file.\nThe agent itself has a small memory footprint and requires very few components to start. For the agent to be useful it needs additional functionality which is implemented in StrolchComponents. Each component is registered via its Java interface on the agent and is bound to the life cycle of the agent. When the agent is started, these components can be retrieved and used to perform any number of functionalities. This is the preferred way to extend the Strolch agent. There are a number of components already implemented, e.g. the ServiceHandler which executes Services in a controlled fashion and can validate authorized access to these services.\nNo software product is complete without a system for authentication and authorization. Strolch implements this by using the Privilege framework which has been written by Robert von Burg. The standard ServiceHandler detects the existence of the PrivilegeHandler and then validates that the user has authorization to perform the service. This framework is implemented as its own Strolch component, thus can be retrieved at any time during execution to perform fine grained and special authorization validation.\nMotivation A question often asked is why create Strolch. What are its benefits in contrast to using Java SE with an OR-Mapper like Hibernate, or using Java EE on JBoss or Glassfish? Especially since many of the features existing in those stacks needed to be re-created in Strolch.\nThe first answer to this question is that those systems are often overly complicated and bloated. Java SE with Hibernate certainly is a viable option when it comes to being light-weightier but Hibernate, even though it is supposed to, often fails to truly help remove the need to really understand an RDBMS. Often enough Hibernate will just get in the way of the most important part of development: writing the business code. Being an OR-Mapper which is supposed to implement all the nitty-gritty details of an RDBMS system, Hibernate, and JPA for that matter, still often has the developer go back to understanding these details.\nStrolch tries a different approach to persistence. Instead of writing pojos/entities, Strolch\u0026rsquo;s model has the concept that each element\u0026rsquo;s attributes are part of a composition pattern: each attribute is its own object and thus can be dynamically changed at runtime, but also makes persistence of such an element generic. Instead of having fixed attributes for a concrete class, these parameters are stored in a map and are accessed through the parameter\u0026rsquo;s ID.\nAssigning an ID to an attribute for accessing of course brings its own downsides, i.e. the parameter might simply not be there, when being accessed. This is certainly an issue that the developer must handle, when implementing a project using Strolch, but allows the developer to not need to worry about persistence, as this is generically handled.\nSince the persistence is generically handled, and Strolch stays lightweight on its requirements at runtime, the developer can quickly get down to what is important for business value: Writing the business logic and the presentation layer. Here too Strolch tries to help the developer by bringing in concepts which are easy to follow: Use cases are implemented as Services, and re-usable business logic is put into Commands.\nThere will be reasons against using Strolch, as there will be against using the Java EE stack, or an OR-Mapper or even the Java ecosystem for that fact. Important is to note, that the concepts behind Strolch are nothing new, but have been implemented in at least two previous proprietary products. Since those products are not accessible to the public, it was decided that a re-implementation might be of use to the programming community at large.\nCurrently, there is at least one company using Strolch in a commercial project which helps drive Strolch\u0026rsquo;s development and further motivates its existence.\nStrolch is an open source project and licensed under the Apache License 2.0.\n##Technology Strolch is written in Java and is programmed against the JDK 8. Strolch runs on any JRE 8 compliant environment. Strolch is tested on the Oracle JRE 8.\n"},{"uri":"https://strolch.li/blog/","title":"Blog","tags":[],"description":"","content":"About The official Strolch blog with news, ideas, and thoughts on using Strolch.\nStrolch is an open source component based software agent written in Java and can be compared, in a light sense, with the Java EE stack: Strolch takes care of persistence, implements Services for use cases, Commands as re-usable algorithms and has a parameterized data model.\nEntries Strolch PLC 1.2.3 released Strolch PLC version 1.2.3 has been deployed to Maven Central\n Strolch 1.8.5 and PLC 1.2.2 are out JDK 17 ready\n Strolch PLC now also on Maven Central Strolch PLC version 1.0.7 has been deployed to Maven Central for easier integration into your projects\n Release of Strolch 1.6.100 The 100. release of the 1.6 branch and a brand new website!\n Strolch Reports Strolch can do reports!\n Strolch Searches Strolch queries are deprecated!\n Wow, the many changes! So many changes, and so long no update - not good!\n Strolch now on Maven Central Release Version 1.3.0 released and deployed to Maven Central\n Versioning of objects Opt-In versioning of objects\n Release 1.2.0 Release of Strolch 1.2.0\n Strolch Update Long due update on Strolch development.\n Activities: Beginning of the planning engine The ground work of the Strolch planning engine has been laid.\n Strolch Documentation Any good software has some decent documentation explaining concepts, best practices and gives examples.\n Strolch Release 1.0.0 Finally Version 1.0.0 of Strolch has been released and can be downloaded immediately.\n DurationParameter and other minor changes: Release 1.0.0-RC4 New DurationParameter and additional minor changes: Release of 1.0.0-RC4 which can be downloaded on the download page.\n DB Initialization: Release 1.0.0-RC3 Important feature Database Initialization added: Release of 1.0.0-RC3 which can be downloaded on the download page.\n Release 1.0.0-RC2 Scratch that RC1, here is the brand new 1.0.0-RC2 which can be downloaded on the download page.\n Release 1.0.0-RC1 With the Go-Live of a Strolch-based application around the corner, it is time to release Version 1.0.0 of Strolch. To this affect we have now released version 1.0.0-RC1 which can be downloaded on the download page.\n "},{"uri":"https://strolch.li/","title":"Strolch Overview","tags":[],"description":"","content":"Strolch Overview Strolch is framework for developing Software. It\u0026rsquo;s main features are:\n Complete persisted data model: Parameters and values by time Resources, Orders with arbitrary parameter grouping Activity/Action hierarchy with arbitrary depth Policies for delegation JSON as well as XML transformation Locator API Transactions with pessimistic locking and optional read-locking Search API Component based Deeply integrated privilege handling Fully in-memory Persisted auditing, versioning, operations log DAOs for file system or PostgreSQL, easily extended Execution framework Service / Command oriented Reporting API configured by Resource objects REST API for data access WebComponents UI for Inspector Users Roles Operations Log Login Screen Jobs runs on plain old Java SE Strolch Intro It is a different framework to Spring and other similar type of Java frameworks, as the model is defined as an abstract model, where you always have the same three types of objects: Resources, Orders and Activities. The fields are mapped as Parameter objects, of which the important primitives are available.\nThe nice part about this framework is, that you can be up and ready in a matter of minutes, and start building your project immediately in that you open your favourite XML editor and start modelling your data.\nOnce your data is defined, you write your business logic in the form of Services, Commands and Searches. There are many predefined services and commands to manipulate the object model, so that you write your own services when you need to enforce special business rules.\nThrough the use of Policy objects, you decouple algorithms from your object model, so that at runtime you can change the behaviour, or easily implement different behaviour depending on your use-case. For instance you might have a simple billing service which performs a few preparatory steps, and then calls the configured billing policy to execute the billing depending on the customer, the warehouse, etc.\nAnd of course persistence is as simple as configuring the persistence handler, pointing to your RDBMS and then setting the mode to CACHED. For you as a developer there is no more thinking in terms of SQL etc., as this is completely hidden from the developer. There is even a simple file persistence layer if you are running IoT devices.\nThe runtime can be just about anything. Usually it is run inside an Apache Tomcat instance as a webapp, as a WEB UI has been required for all current Strolch projects. You could just as well use a main class. Accessing the Strolch Agent remotely is usually done through REST.\nStrolch is being actively developed, and customers constantly give us reasons to improve and extend the framework. There is a Polymer Inspector component which makes it easy to see and manipulate the actual data. The new Search API makes it really easy to query your data.\nYes, Strolch is different, but the concept has come out of the planning and execution segment, and has been refined over the years until it has become what it is today.\nAPI Check out the API page to see how to use Strolch.\nMore to motivation etc.\n"},{"uri":"https://strolch.li/categories/","title":"Categories","tags":[],"description":"","content":""},{"uri":"https://strolch.li/tags/","title":"Tags","tags":[],"description":"","content":""}] \ No newline at end of file diff --git a/public/index.xml b/public/index.xml deleted file mode 100644 index 58ec4d3..0000000 --- a/public/index.xml +++ /dev/null @@ -1,85 +0,0 @@ -Strolch Overview on Strolchhttps://strolch.li/Recent content in Strolch Overview on StrolchHugo -- gohugo.ioen-usMon, 29 Aug 2022 09:10:00 +0200Strolch PLC 1.2.3 releasedhttps://strolch.li/blog/post-00018/Mon, 29 Aug 2022 09:10:00 +0200https://strolch.li/blog/post-00018/Strolch PLC 1.2.3 released Strolch PLC version 1.2.3 has been deployed to Maven Central' -This is a maintenance release, as 1.2.2 pointed to Strolch 1.8.4 which was not released to Maven Central.Strolch 1.8.5 and PLC 1.2.2 are outhttps://strolch.li/blog/post-00017/Wed, 17 Aug 2022 15:50:00 +0200https://strolch.li/blog/post-00017/Strolch 1.8.5 and PLC 1.2.2 are out JDK 17 ready! -Unbelievable, but the entire 1.7.x branch was never blogged about or deployed to Maven. We did do quite a few releases of the Java 11 version, but never got around to releasing to Maven. -Now we have released the 1.8.x branch of Strolch and deployed to Maven Central. -The 1.8.x branch requires JDK 17, but is still on Tomcat 9.Strolch PLC now also on Maven Centralhttps://strolch.li/blog/post-00016/Fri, 01 Jan 2021 00:00:00 +0100https://strolch.li/blog/post-00016/Strolch PLC now also on Maven Central Strolch PLC version 1.0.7 has been deployed to Maven Central for easier integration into your projects -To more easily use Strolch PLC in your project, we have now deployed the latest Strolch PLC version to Maven Central. This version 1.0.7 depends on Strolch version 1.6.100. -Enjoy coding!Release of Strolch 1.6.100https://strolch.li/blog/post-00015/Wed, 14 Jul 2021 20:25:11 +0200https://strolch.li/blog/post-00015/Release of Strolch 1.6.100 The 100. Strolch release of the 1.6 branch and a brand new website! -Ok, so Maven doesn&rsquo;t exactly have 100 releases on it, but even though we have been quiet on public releases, Strolch has seen many refactorings, fixes, new features etc. over the past three years of its last release. -Some notable changes: -I18n Support for StrolchExceptions. Better performance for reports on large joins.Strolch Reportshttps://strolch.li/blog/post-00014/Fri, 30 Jun 2017 00:00:00 +0100https://strolch.li/blog/post-00014/Strolch Reports Strolch can do reports! -A feature we haven&rsquo;t written about yet is the report API. Strolch has it&rsquo;s own API to generate reports of data, and since we have a generic model, we use Resource of type Report to define them. -Go check out the documentation and then enjoy using this easy way to deliver the reports your peers require.Strolch Searcheshttps://strolch.li/blog/post-00013/Fri, 30 Jun 2017 00:00:00 +0100https://strolch.li/blog/post-00013/Strolch Searches Strolch queries are deprecated! -Strolch has had once again many changes, and fixes etc. One important thing to note is that we have removed support for transactional mode and have rewritten how models are searched. Thus the search API was born. -Go check out the Strolch Search documentation and then go rewrite your searches =)). -Strolch tag 1.6.51 has all those juicy changes!Wow, the many changes!https://strolch.li/blog/post-00012/Tue, 21 Mar 2017 00:00:00 +0100https://strolch.li/blog/post-00012/Wow, the many changes! So many changes, and so long no update - not good! -Oh boy, have we forgotten to update you all on the latest awesome features in Strolch! There are over 123 commits since the last tag 1.3.0, so that alone merits a new blog post. -Currently the latest tag is 1.5.5, but this version is actually already quite old, as it was created on 31. January 2017 and there are 53 new commits ahead of the tag.Strolch now on Maven Centralhttps://strolch.li/blog/post-00011/Thu, 22 Sep 2016 00:00:00 +0100https://strolch.li/blog/post-00011/Strolch now on Maven Central Release Version 1.3.0 released and deployed to Maven Central -We have released a new version of Strolch so that you can now go and use the the latest features in Strolch. -Further we have now deployed Strolch to Maven Central, so it is easier than ever to use Strolch in your projects. No need to download first or use a special repository - just define the dependencies as you would any other dependency.Versioning of objectshttps://strolch.li/blog/post-00010/Mon, 08 Aug 2016 00:00:00 +0100https://strolch.li/blog/post-00010/Versioning of objects Opt-In versioning of objects -A major new feature has landed in Strolch. Now, using opt-in, it is possible to have all changes to the object model be versioned. This means that any change to Order, Resource or Activity is automatically versioned and one can then revert to this version later on. -This will make it far easier to implement undo operations in applications since it is an inherent part of the lifecycle of objects in Strolch.Release 1.2.0https://strolch.li/blog/post-00009/Mon, 04 Jul 2016 00:00:00 +0100https://strolch.li/blog/post-00009/Release 1.2.0 Release of Strolch 1.2.0 -A few months ago we informed of the soon to be released version 1.1.0. Well, we decided to jump to 1.2.0 because we did some refactorings. All the eitchnet projects have been melted into Strolch and thus now it&rsquo;s all one nice package. This will result in simpler development and less constraints on APIs between the two projects. -Other than that, not much changed, but we are continually working on Strolch, so go grab your latest copy and have fun coding!Strolch Updatehttps://strolch.li/blog/post-00008/Sat, 09 Apr 2016 00:00:00 +0100https://strolch.li/blog/post-00008/Strolch Update Long due update on Strolch development. -Although we have been rather quiet in the last couple of months, anyone viewing Strolch&rsquo;s commit log, will see that we certainly didn&rsquo;t halt Strolch development. -We have been hard at work, using Strolch in projects, which required many new features and fixes. The commit log shows as of today over 180 commits since the release tag 1.0.0. -Some of the most exciting changes are:Activities: Beginning of the planning enginehttps://strolch.li/blog/post-00007/Wed, 08 Jul 2015 00:00:00 +0100https://strolch.li/blog/post-00007/Activities: Beginning of the planning engine The ground work of the Strolch planning engine has been laid. -One of the core ideas in building Strolch was to create a planning engine. The planning engine would work in combination of Order objects representing customer orders, Resource objects representing machines, human resources, etc., and Activity/Action hierarchies defining a workflow. -With the latest couple of commits to Strolch we have now added Activities and a basic planning of Actions onto Resources.Strolch Documentationhttps://strolch.li/blog/post-00006/Mon, 06 Apr 2015 00:00:00 +0100https://strolch.li/blog/post-00006/Strolch Documentation Any good software has some decent documentation explaining concepts, best practices and gives examples. -So this post is to announce that there is now a new page on Strolch&rsquo;s website with a bit of documentation. This first documentation explains the Strolch runtime and some of the do and don&rsquo;t in Strolch code. -Bear with us, writing documentation takes time and can be outdated quickly, so we will make an effort to keep everything up to date and add more documentation, but this is a start.Strolch Release 1.0.0https://strolch.li/blog/post-00005/Tue, 31 Mar 2015 00:00:00 +0100https://strolch.li/blog/post-00005/Strolch Release 1.0.0 Finally Version 1.0.0 of Strolch has been released and can be downloaded immediately. -Before 1.0.0 could be released, some major changes were decided, all driven by the first big project using Strolch as its underlying stack. Those changes were minor, and really major, but should make Strolch better and was important for the first release. -Here is a list of the most interesting changes: -Java 8 - Strolch was ported to Java 8.DurationParameter and other minor changes: Release 1.0.0-RC4https://strolch.li/blog/post-00004/Thu, 09 Oct 2014 00:00:00 +0100https://strolch.li/blog/post-00004/DurationParameter and other minor changes: Release 1.0.0-RC4 New DurationParameter and additional minor changes: Release of 1.0.0-RC4 which can be downloaded on the download page. -While implementing a use case in a Strolch based application it was detected that an essential parameter type was missing, the DurationParameter. This parameter currently stores the value as a long in memory and serializes to ISO8601. As soon as we move Strolch to Java8, we will change this to use the Period class in the new Java8 date and time API.DB Initialization: Release 1.0.0-RC3https://strolch.li/blog/post-00003/Sun, 24 Aug 2014 00:00:00 +0100https://strolch.li/blog/post-00003/DB Initialization: Release 1.0.0-RC3 Important feature Database Initialization added: Release of 1.0.0-RC3 which can be downloaded on the download page. -When living continuous integration and continuous delivery, it is vital that things like database migrations and initialization are performed in a controlled, but automatic way. -A Strolch-based application is using the PostgreSQL persistence layer. The implementation understands the concepts of migration, and validating the database schema, but currently a mechanism to automatically initialize the database with a minimal set of data was missing.Release 1.0.0-RC2https://strolch.li/blog/post-00002/Fri, 22 Aug 2014 00:00:00 +0100https://strolch.li/blog/post-00002/Release 1.0.0-RC2 Scratch that RC1, here is the brand new 1.0.0-RC2 which can be downloaded on the download page. -So, as expected there were a few bugs, for instance the Strolch tutorial apps didn&rsquo;t start, so now i fixed those and released an RC2. Go get it and give it a try!Release 1.0.0-RC1https://strolch.li/blog/post-00001/Wed, 20 Aug 2014 00:00:00 +0100https://strolch.li/blog/post-00001/Release 1.0.0-RC1 With the Go-Live of a Strolch-based application around the corner, it is time to release Version 1.0.0 of Strolch. To this affect we have now released version 1.0.0-RC1 which can be downloaded on the download page. -Story Strolch as a component based software agent has been two years in the making. The concepts in Strolch have been taken from a proprietary planning, scheduling and controlling software agent, which was, and is been, used in industrial automation, logistics and production.Architecturehttps://strolch.li/documentation/architecture/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/architecture/Architecture Birds View A Strolch agent&rsquo;s architecture can be seen as a simple three-tier architecture. The presentation layer is mostly a web frontend, where the communication with the agent is done via REST API calls. -The agent itself implements the business logic using Services, Commands, Queries etc. -The agent can communicate with other 3rd systems using any API, where it is preferred to use JSON over REST. -The agent can use a standard RDBMS as a storage system, where currently DAOs have been implemented only for PostgreSQL.Configurationhttps://strolch.li/tutorial/configuration/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/tutorial/configuration/Configuration Let&rsquo;s start by creating a new Apache Maven project. We&rsquo;ll need a POM with the proper dependencies. We expect you to be familiar with Apache Maven, so we&rsquo;ll just show you a working POM file: -pom.xml -&lt;?xml version=&#34;1.0&#34;?&gt; &lt;project xmlns=&#34;http://maven.apache.org/POM/4.0.0&#34; xmlns:xsi=&#34;http://www.w3.org/2001/XMLSchema-instance&#34; xsi:schemaLocation=&#34;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd&#34;&gt; &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt; &lt;groupId&gt;li.strolch&lt;/groupId&gt; &lt;artifactId&gt;strolch-bookshop&lt;/artifactId&gt; &lt;version&gt;0.1.0-SNAPSHOT&lt;/version&gt; &lt;packaging&gt;war&lt;/packaging&gt; &lt;name&gt;strolch-bookshop&lt;/name&gt; &lt;description&gt;Bookshop built on Strolch&lt;/description&gt; &lt;inceptionYear&gt;2017&lt;/inceptionYear&gt; &lt;properties&gt; &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt; &lt;maven.build.timestamp.format&gt;yyyy-MM-dd HH:mm:ss&lt;/maven.build.timestamp.format&gt; &lt;buildTimestamp&gt;${maven.build.timestamp}&lt;/buildTimestamp&gt; &lt;jdk.version&gt;1.8&lt;/jdk.version&gt; &lt;jersey.version&gt;2.25.1&lt;/jersey.version&gt; &lt;slf4j.version&gt;1.7.25&lt;/slf4j.version&gt; &lt;logback.version&gt;1.2.3&lt;/logback.version&gt; &lt;petitparser.version&gt;2.1.0&lt;/petitparser.version&gt; &lt;hikaricp.version&gt;4.0.3&lt;/hikaricp.version&gt; &lt;postgresql.version&gt;42.1.4&lt;/postgresql.version&gt; &lt;gson.version&gt;2.8.2&lt;/gson.version&gt; &lt;annotation.version&gt;1.3.1&lt;/annotation.version&gt; &lt;javaxmail.version&gt;1.6.0&lt;/javaxmail.version&gt; &lt;serverlet.Prerequisiteshttps://strolch.li/development/prerequisites/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/development/prerequisites/Prerequisites To start developing Strolch you need an installed: -Java JDK 17 Apache Maven 3.x You can install these using the awesome SDKMAN!: -$ curl -s &#34;https://get.sdkman.io&#34; | bash source &#34;$HOME/.sdkman/bin/sdkman-init.sh&#34; sdk version sdk install java sdk install maven sdk install mvnd Test your Java installation: -$ java -version openjdk version &#34;17.0.4&#34; 2022-07-19 OpenJDK Runtime Environment Temurin-17.0.4+8 (build 17.0.4+8) OpenJDK 64-Bit Server VM Temurin-17.0.4+8 (build 17.0.4+8, mixed mode, sharing) Test your Maven installation:Building Strolchhttps://strolch.li/development/building/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/development/building/Building Strolch Note: You don&rsquo;t have to build Strolch if you want to use the version on Maven central. If you need a snapshot version, the release you want isn&rsquo;t on Maven central or you want to use the Strolch Maven archetypes, then go ahead and build Strolch. -Building Strolch is just a few lines: -git clone https://github.com/strolch-li/strolch.git cd strolch mvn clean install -DskipTests Note: To run the tests you will need to configure the PostgreSQL Databases.Modelhttps://strolch.li/documentation/model/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/model/Model Before we dive into the entire model, let&rsquo;s show an example and how it would be modelled in Strolch and use in Strolch: -The model has four entities, which will be modelled using 3 Resources and 1 Order object. The objects have numerous fields and the following relationships: -Bidirectional between Article &lt;-&gt; Product Unidirectional from Order -&gt; Article Unidirectional from Order -&gt; Customer A possible model would look as follows:Modelhttps://strolch.li/tutorial/model/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/tutorial/model/Model Looking back at our functionality, we can list the following entities that need to be modelled (We&rsquo;ll go into detail further down): -Book → books can be orderd UserCart → we want to store the cart of the user Account → we need to know where to send the orders PurchaseOrder → we need to know what was ordered and keep track of its state FromStock → we want to use activities to implement the process of an order In Strolch we model entities by defining the element as a template.CRUD Bookhttps://strolch.li/tutorial/crud-book/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/tutorial/crud-book/Preparation Since Books are central to the bookshop, we&rsquo;ll first create the CRUD REST API for them. The API will be as follows: -GET ../rest/books?query=,offset=,limit= GET ../rest/books/{id} POST ../rest/books PUT ../rest/books/{id} DELETE ../rest/books/{id} Thus corresponding with querying, getting, creating, updating and removing of books. So let&rsquo;s go ahead and add these REST APIs to our project. -Our project is using JAX-RS 2.0 as the API and Jersey 2.x as the implementation, thus first we need to configure JAX-RS.Do and Don'thttps://strolch.li/documentation/do-and-donts/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/do-and-donts/This page discusses things you should and shouldn&rsquo;t do when using Strolch The following is a simple list of do&rsquo;s and don&rsquo;ts: -1 Service per use-case, should mostly delegate to Commands. -Commands implement use-cases or parts of it, and are thus reusable. -Subclass ResourceSearch, OrderSearch and ActivitySearch when implementing use-case specific search - this allows privilege checking. -One Transaction at a time - no TX inside of another TX.Maven Archetypeshttps://strolch.li/development/maven-archetypes/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/development/maven-archetypes/Maven Archetypes Maven offers archetypes to generate new projects. Strolch offers the following archetypes, to create new projects: -strolch.mvn.archetype.main for Java main class applications strolch.mvn.archetype.webapp for Java Web based applications using REST and Polymer 1.x as the frontend. strolch.mvn.archetype.plc for Strolch PLC projects. To use the archetypes, clone the archetypes repository and install it locally: -git clone https://github.com/strolch-li/strolch-maven-archetypes.git cd strolch-maven-archetypes git checkout 0.1.0 mvn clean install Then follow one of the next steps to create the type of application you want.Runtime Configurationhttps://strolch.li/documentation/runtime-configuration/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/runtime-configuration/Runtime Configuration A Strolch runtime configuration comprises two parts: a configuration part, and a model part. The configuration are files located in the ..config/ folder, and the model are files located in the ../data folder. -In an absolute minimal configuration, the Strolch runtime requires the following folder structure: -../config/ ../StrolchConfiguration.xml → configures the Strolch agent ../PrivilegeConfig.xml → configures user management ../PrivilegeUsers.xml → contains the users in an XML based user management file .Web Apphttps://strolch.li/development/web-app/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/development/web-app/Prerequisites To start developing web-based Strolch apps you need the following: -Apache Tomcat 9.x (10.x isn&rsquo;t supported yet). Just unpack it somewhere, to be used later, when running the application. NodeJS v11.x (other versions don&rsquo;t work with Bower, the installation is described below. Note: Strolch&rsquo;s Web UI is still using Polymer 1.x. This isn&rsquo;t a big concern, as thanks to the polyfills, it works on all browsers, including Internet Explorer 11.Architecturehttps://strolch.li/plc/architecture/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/plc/architecture/Architecture Overview The Strolch PLC architecture sees the Strolch Agent as the server, managing logical devices, i.e. multiple sensors and actors together and thus deciding on further steps. With this architecture multiple PLCs can be combined in one agent for flow control. -PLC Architecture On the agent side the two main classes are the PlcGwServerHandler and the PlcGwService -The PlcGwServerHandler handles connections from remote PLCs over WebSockets and sends the requests to these PLCs.Main Class Apphttps://strolch.li/development/main-class-app/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/development/main-class-app/Creating a Strolch App The following shows the maven command to create the new maven project using Strolch&rsquo;s main maven archetype. Note that you should replace the placeholders in the brackets: -Note: you need to have the Strolch Maven archetypes installed to your local maven repo, otherwise the following command will fail. -mvn archetype:generate \ -DarchetypeGroupId=li.strolch \ -DarchetypeArtifactId=strolch.mvn.archetype.main \ -DarchetypeVersion=0.1.0-SNAPSHOT \ -DgroupId=&lt;my.groupid&gt; \ -DartifactId=&lt;my-artifactId&gt; \ -Dversion=&lt;my.Realmshttps://strolch.li/documentation/realms/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/realms/Realms Realms implement multi-tenant capabilities. A Strolch agent can have an arbitrary number of realms configured and each realm has its own persistence configuration, allowing to separate mandates completely. -A realm can run in one of the following modes: -EMPTY This is a transient data store mode, where no model changes are persisted - they are only kept in memory. When the Strolch agent is started, this realm is empty as no data is loaded.Componentshttps://strolch.li/documentation/components/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/components/Components A Strolch agent can be easily extended with arbitrary components. An agent is basically a container for classes extending StrolchComponent with a life cycle. These classes mostly implement an interface which describes the operations that are supported by the component. -The following represents a list of the most used components: -RealmHandler: li.strolch.agent.impl.DefaultRealmHandler PrivilegeHandler: li.strolch.runtime.privilege.DefaultStrolchPrivilegeHandler EnumHandler: li.strolch.runtime.query.enums.DefaultEnumHandler PolicyHandler: li.strolch.policy.DefaultPolicyHandler ServiceHandler: li.strolch.service.api.DefaultServiceHandler StrolchSessionHandler: li.strolch.rest.DefaultStrolchSessionHandler PersistenceHandler: multiple implementations PostInitializer: project specific implementation MailHandler: li.Services and Commandshttps://strolch.li/documentation/services-and-commands/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/services-and-commands/Services and Commands Services are written to implement a specific use-case. Commands are written to implement re-usable parts of a use-case. The use-case can be abstract e.g., AddResourceService or very specific e.g. CreatePatientService. -Should the use-case be re-usable in different scenarios, then commands should implement the logic, and the services should then execute the commands. E.g. The CreatePatientService would use a CreatePatientResourceCommand and then use an AddResourceCommand in a single transaction, so that the task of creating the actual Patient Resource can be re-used somewhere else.Searcheshttps://strolch.li/documentation/searches/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/searches/Searches As is custom for every framework, querying, or searching, the model must be possible. Strolch searches are implemented using the StrolchSearch class and one of its concrete implementations: ResourceSearch, OrderSearch, ActivitySearch. -A Strolch element always has two identifiers: Type and Id. The type is important as it classifies an element. So if a car and a house would be modelled in Strolch, then those would both be a Resource, but one of type Car and the other of type House.Querieshttps://strolch.li/documentation/queries/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/queries/Queries The Query API is deprecated and the search API should be used instead. -As is custom for every framework, querying the model must be possible. Strolch queries are implemented using the StrolchQuery interface and one of its concrete implementations: ResourceQuery, OrderQuery, ActivityQuery. -A Strolch element always has two identifiers: Type and Id. The type is important as it classifies an element. So if a car and a house would be modelled in Strolch, then those would both be a Resource, but one of type Car and the other of type House.Converting Existing Apphttps://strolch.li/development/converting-existing/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/development/converting-existing/Converting an existing application You can convert an existing application to a Strolch agent, but this might be a bit daunting in the beginning. If you are planning on doing this, first create a test application using the maven archetypes, so that you can get a feel for the configuration. -Once that works, use the archetypes configuration to reconfigure your project to start as a Strolch agent. -Note: Beware to select the archetype pertaining to your use case:Example Set-Uphttps://strolch.li/plc/example-set-up/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/plc/example-set-up/Example Set-Up This example setup describes the movement of containers over conveyors. The conveyors have motors which can be started and stopped by a GPIO output pin controlled on a Raspberry Pi and each conveyor has a light barrier to detect the occupancy of a container and the Raspberry Pi detects this on GPIO input pins. -Further at each conveyor location is a barcode reader to read the ID of a container.Transactionshttps://strolch.li/documentation/transactions/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/transactions/Transactions Strolch Transactions play a central role in a Strolch agent. A transaction is opened for a realm, and grants access to the model of the agent. Transactions are implemented as a Java try-with-resources by implementing the AutoCloseable interface. This makes it trivial to understand the scope of a transaction. -Transactions handle the following: -Opening and closing database connections Releasing locks to strolch elements, if tx.lock(StrolchRootElement) or tx.lock(Locator) was called Performing Commands by executing them in the added order, and validating them first.Policieshttps://strolch.li/documentation/policies/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/policies/Policies Policies are an integral part when writing business logic in Strolch. In many cases it would suffice to write all such logic in Services and Commands, but as soon as behaviour can change, depending on the element being accessed, then this would quickly lead to many if/else blocks. -Since writing large if/else blocks is not maintanable in the long run, Strolch offers a different approach. All Strolch elements can store Policy definitions.Observershttps://strolch.li/documentation/observers/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/observers/Observers All changes done in a Strolch transaction are recorded and then propagated to any registered observers. -The observer feature is opt-in and is configured for each realm. In the StrolchConfiguration.xml file enable observers by adding the enableObserverUpdates property per realm: -&lt;StrolchConfiguration&gt; &lt;env id=&#34;dev&#34;&gt; ... &lt;Component&gt; &lt;name&gt;RealmHandler&lt;/name&gt; &lt;api&gt;li.strolch.agent.api.RealmHandler&lt;/api&gt; &lt;impl&gt;li.strolch.agent.impl.DefaultRealmHandler&lt;/impl&gt; &lt;depends&gt;PrivilegeHandler&lt;/depends&gt; &lt;Properties&gt; &lt;realms&gt;defaultRealm, otherRealm&lt;/realms&gt; &lt;enableObserverUpdates&gt;true&lt;/enableObserverUpdates&gt; &lt;dataStoreMode&gt;TRANSIENT&lt;/dataStoreMode&gt; &lt;dataStoreFile&gt;StrolchModel.xml&lt;/dataStoreFile&gt; &lt;enableObserverUpdates.otherRealm&gt;true&lt;/enableObserverUpdates.otherRealm&gt; &lt;dataStoreMode.otherRealm&gt;TRANSIENT&lt;/dataStoreMode.otherRealm&gt; &lt;dataStoreFile.otherRealm&gt;StrolchModel.xml&lt;/dataStoreFile.otherRealm&gt; &lt;/Properties&gt; &lt;/Component&gt; &lt;/env&gt; ... &lt;/StrolchConfiguration&gt; Registering for updates is done by registering an Observer on the ObserverHandler of the realm itself:Versioninghttps://strolch.li/documentation/versioning/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/versioning/Versioning One of Strolch&rsquo;s features that sets it apart from other frameworks, is that versioning is baked into Strolch&rsquo;s fabric. The feature is opt-in, as it is not required in all projects, but it only needs enabling, for all modifications to objects to be versioned, so that rollbacks can be done when needed. -The feature is enabled for each realm. In the StrolchConfiguration.xml file enable it by adding the enableVersioning propery per realm:Reportshttps://strolch.li/documentation/reports/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/reports/Reports Since Strolch has a generic model, it was rather straight forward to create a simple API for writing reports. In Strolch a report is defined by using its own model, i.e. a Report is a Resource of type Report. -A report consists of the following parts: -policy definition, thus allowing extensions basic configuration like base object type, order direction, etc. column definitions joins ordering definition filters An example of a report is as follows:Privilegeshttps://strolch.li/documentation/priviles/Mon, 01 Jan 0001 00:00:00 +0000https://strolch.li/documentation/priviles/Privileges No framework is complete without user management and privilege validation. The basic form would be Users and Roles, and then validating that an authenticated user has a given role. In Strolch we go a step further: A User has roles assigned, and each role has a set of Privileges. The privileges can overlap, a validation is performed to make sure that the one role doesn&rsquo;t deny and another role allows a specific action. \ No newline at end of file diff --git a/public/js/auto-complete.js b/public/js/auto-complete.js deleted file mode 100644 index 0b46054..0000000 --- a/public/js/auto-complete.js +++ /dev/null @@ -1,3 +0,0 @@ -// JavaScript autoComplete v1.0.4 -// https://github.com/Pixabay/JavaScript-autoComplete -var autoComplete=function(){function e(e){function t(e,t){return e.classList?e.classList.contains(t):new RegExp("\\b"+t+"\\b").test(e.className)}function o(e,t,o){e.attachEvent?e.attachEvent("on"+t,o):e.addEventListener(t,o)}function s(e,t,o){e.detachEvent?e.detachEvent("on"+t,o):e.removeEventListener(t,o)}function n(e,s,n,l){o(l||document,s,function(o){for(var s,l=o.target||o.srcElement;l&&!(s=t(l,e));)l=l.parentElement;s&&n.call(l,o)})}if(document.querySelector){var l={selector:0,source:0,minChars:3,delay:150,offsetLeft:0,offsetTop:1,cache:1,menuClass:"",renderItem:function(e,t){t=t.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&");var o=new RegExp("("+t.split(" ").join("|")+")","gi");return'
    '+e.replace(o,"$1")+"
    "},onSelect:function(){}};for(var c in e)e.hasOwnProperty(c)&&(l[c]=e[c]);for(var a="object"==typeof l.selector?[l.selector]:document.querySelectorAll(l.selector),u=0;u0?i.sc.scrollTop=n+i.sc.suggestionHeight+s-i.sc.maxHeight:0>n&&(i.sc.scrollTop=n+s)}else i.sc.scrollTop=0},o(window,"resize",i.updateSC),document.body.appendChild(i.sc),n("autocomplete-suggestion","mouseleave",function(){var e=i.sc.querySelector(".autocomplete-suggestion.selected");e&&setTimeout(function(){e.className=e.className.replace("selected","")},20)},i.sc),n("autocomplete-suggestion","mouseover",function(){var e=i.sc.querySelector(".autocomplete-suggestion.selected");e&&(e.className=e.className.replace("selected","")),this.className+=" selected"},i.sc),n("autocomplete-suggestion","mousedown",function(e){if(t(this,"autocomplete-suggestion")){var o=this.getAttribute("data-val");i.value=o,l.onSelect(e,o,this),i.sc.style.display="none"}},i.sc),i.blurHandler=function(){try{var e=document.querySelector(".autocomplete-suggestions:hover")}catch(t){var e=0}e?i!==document.activeElement&&setTimeout(function(){i.focus()},20):(i.last_val=i.value,i.sc.style.display="none",setTimeout(function(){i.sc.style.display="none"},350))},o(i,"blur",i.blurHandler);var r=function(e){var t=i.value;if(i.cache[t]=e,e.length&&t.length>=l.minChars){for(var o="",s=0;st||t>40)&&13!=t&&27!=t){var o=i.value;if(o.length>=l.minChars){if(o!=i.last_val){if(i.last_val=o,clearTimeout(i.timer),l.cache){if(o in i.cache)return void r(i.cache[o]);for(var s=1;s https://github.com/noelboss/featherlight/issues/317 -!function(u){"use strict";if(void 0!==u)if(u.fn.jquery.match(/-ajax/))"console"in window&&window.console.info("Featherlight needs regular jQuery, not the slim version.");else{var r=[],i=function(t){return r=u.grep(r,function(e){return e!==t&&0','
    ','",'
    '+n.loading+"
    ","
    ",""].join("")),o="."+n.namespace+"-close"+(n.otherClose?","+n.otherClose:"");return n.$instance=i.clone().addClass(n.variant),n.$instance.on(n.closeTrigger+"."+n.namespace,function(e){if(!e.isDefaultPrevented()){var t=u(e.target);("background"===n.closeOnClick&&t.is("."+n.namespace)||"anywhere"===n.closeOnClick||t.closest(o).length)&&(n.close(e),e.preventDefault())}}),this},getContent:function(){if(!1!==this.persist&&this.$content)return this.$content;var t=this,e=this.constructor.contentFilters,n=function(e){return t.$currentTarget&&t.$currentTarget.attr(e)},r=n(t.targetAttr),i=t.target||r||"",o=e[t.type];if(!o&&i in e&&(o=e[i],i=t.target&&r),i=i||n("href")||"",!o)for(var a in e)t[a]&&(o=e[a],i=t[a]);if(!o){var s=i;if(i=null,u.each(t.contentFilters,function(){return(o=e[this]).test&&(i=o.test(s)),!i&&o.regex&&s.match&&s.match(o.regex)&&(i=s),!i}),!i)return"console"in window&&window.console.error("Featherlight: no content filter found "+(s?' for "'+s+'"':" (no target specified)")),!1}return o.process.call(t,i)},setContent:function(e){return this.$instance.removeClass(this.namespace+"-loading"),this.$instance.toggleClass(this.namespace+"-iframe",e.is("iframe")),this.$instance.find("."+this.namespace+"-inner").not(e).slice(1).remove().end().replaceWith(u.contains(this.$instance[0],e[0])?"":e),this.$content=e.addClass(this.namespace+"-inner"),this},open:function(t){var n=this;if(n.$instance.hide().appendTo(n.root),!(t&&t.isDefaultPrevented()||!1===n.beforeOpen(t))){t&&t.preventDefault();var e=n.getContent();if(e)return r.push(n),s(!0),n.$instance.fadeIn(n.openSpeed),n.beforeContent(t),u.when(e).always(function(e){n.setContent(e),n.afterContent(t)}).then(n.$instance.promise()).done(function(){n.afterOpen(t)})}return n.$instance.detach(),u.Deferred().reject().promise()},close:function(e){var t=this,n=u.Deferred();return!1===t.beforeClose(e)?n.reject():(0===i(t).length&&s(!1),t.$instance.fadeOut(t.closeSpeed,function(){t.$instance.detach(),t.afterClose(e),n.resolve()})),n.promise()},resize:function(e,t){if(e&&t&&(this.$content.css("width","").css("height",""),this.$content.parent().width()');return n.onload=function(){r.naturalWidth=n.width,r.naturalHeight=n.height,t.resolve(r)},n.onerror=function(){t.reject(r)},n.src=e,t.promise()}},html:{regex:/^\s*<[\w!][^<]*>/,process:function(e){return u(e)}},ajax:{regex:/./,process:function(e){var n=u.Deferred(),r=u("
    ").load(e,function(e,t){"error"!==t&&n.resolve(r.contents()),n.fail()});return n.promise()}},iframe:{process:function(e){var t=new u.Deferred,n=u("