diff --git a/.circleci/config.yml b/.circleci/config.yml index 394627bc..1045e671 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -1,7 +1,7 @@ version: 2.1 orbs: - localstack: localstack/platform@1.0 + localstack: localstack/platform@2.1 commands: store_jacoco_site: diff --git a/docs/Introduction.adoc b/docs/Introduction.adoc index dcb95468..d95ba3a0 100644 --- a/docs/Introduction.adoc +++ b/docs/Introduction.adoc @@ -1,8 +1,176 @@ = Introduction +include::variables.adoc[] -QQQ is ... +QQQ is a Low-code Application Framework for Engineers. +Its purpose is to provide the basic structural elements of an application - things that every application needs - so that the engineers building an application on top of QQQ don't need to worry about those pieces, and can instead focus on the unique needs of the application that they are building. -- Framework -- Declarative -- Easy thing easy; Hard thing possible -- Customizable +== What makes QQQ special? + +The scope of what QQQ provides is far-reaching, and most likely goes beyond what you may initially be thinking. +That is to say, QQQ includes code all the way from the backend of an application, through its middleware layer, and including its frontend. +For example, a common set of modules deployed in a QQQ application will provide: + +* Backend RDBMS/Database connectivity and access. +* Frontend web UI (e.g., a React application) +* A java web server acting as middleware between the frontend web UI and the backend + +That is to say - as an engineer deploying a QQQ application - you do not need to write a single line of code that is concerned with any of those things. + +* You do not need to write code to connect to your database. +* You do not write any web UI code. +* You do not write any middleware code to tie together the frontend and backend. + +Instead, QQQ includes *all* of these pieces. +QQQ knows how to connect to databases (and actually, several other kinds of backend systems - but ignore that for now). +Plus it knows how to do most of what an application needs to do with a database (single-record lookups, complex queries, joins, aggregates, bulk inserts, updates, deletes). +QQQ also knows how to present the data from a database - in table views, or single-record views, or exports, or reports or widgets. +And it knows how to present a powerful ad-hoc query interface to users, and how to show screens where users can create, update, and delete records. +It also provides the connective tissue (middleware) between those backend layers where data is stored, and frontend layers were users interact with data. + +== What makes your application special? + +I've said a lot about what does QQQ knows - but let's dig a little deeper. +What does QQQ know, and what does it not know? +Well - what it doesn't know is, it doesn't know the special or unique aspects of the application that you are building. + +So, what makes your application unique? + +Is your application unique because it needs to have screens where users can search for records in a table? + +No! + +QQQ assumes (as does the author of this document) that all applications (at least of the nature that QQQ supports) need what we call Query Screens. +So QQQ gives you a Query Screen for all of your tables - with zero code from you. + +Is your application unique because you want users to be able to view, create, edit, and delete records from tables? + +No! + +QQQ assumes that all applications need these basic https://en.wikipedia.org/wiki/Create,_read,_update_and_delete[CRUD] capabilities. +So QQQ provides all of these UI screens - for view, create, edit, delete - along with the supporting middleware and backend code - all the way down to the SQL that selects & manages the data. +You get it all for free - zero code. + +Is your application unique because you have a `fiz_bar` table, with 47 columns, and a `whoz_zat` table, with 42 columns of its own, that joins to `fiz_bar` on the `zizzy_ziz_id` field? + +Yes! + +OK - we found some of it - what makes your application unique is the data that you're working with. +Your tables - their fields - the connection info for your database. +QQQ doesn't know those details. +So - that's your first job as a QQQ application engineer - to describe your data to QQQ. + +For the example above - you need to tell QQQ that you have a `fiz_bar` table, and that you have a `whoz_zat` table - and you need to tell QQQ what the fields or columns in thsoe tables are. +You can even tell QQQ how to join those tables (on that `zizzy_ziz_id` field). +And then that's it. +Once QQQ has this {link-table} meta data, it can then provide its Query screens, and full CRUD screens to your tables, in your database, with your fields. + +And at the risk of repeating myself - you can do this (get a full Query & CRUD application) with zero lines of actual procedural code. +You only need to supply meta-data (which, at the time of this writing, is done in Java, but it's just creating objects - and in the future could be done in YAML files, for example). + +== Beyond Basics +Going beyond the basic wiring as described above, QQQ also provides some of the more advanced elements needed in a modern data-driven web application, including: + +* Authentication & Authorization +* ad-hoc Query engine for access to data tables +* Full CRUD (Create, Read, Update, Delete) capabilities +* Multistep custom workflows ("Processes" in QQQ parlance) +* Scheduled jobs +* Enterprise Service Bus + +So what do we mean by all of this? +We said that basically every application needs, for example, Authentication & Authorization. +Login screens. +User & Role tables. +Permissions. +So, when it's time for you to build a new application for your _Big Tall Floor Lamp_ manufacturing business, do you need to start by writing a login screen? +And a Permissions scheme? +And throwing HTTP 401 errors? +And managing user-role relationships? +And then having a bug in the check permission logic on the _Light Bulb Inventory Edit_ screen, so Jim is always keying in bad quantities, even though he isn't supposed to have permission there? + +No! + +All of the (really important, even though application developers hate doing it) aspects of security - you don't need to write ANY code for dealing with that. +Just tell QQQ what Authentication provider you want to use (e.g., https://auth0.com/[Auth0]), and - to paraphrase the old https://www.youtube.com/watch?v=YHzM4avGrKI[iMac ad] - there's no step 2. +QQQ just does it. + +'''' + +QQQ can provide this type of application using a variety and/or combination of backend data storage types. +And, whichever type of backend is used, QQQ gives a common interface (both user-facing and programmer-facing). +Backend types include: + +* Relational Databases (RDBMS) +* File Systems +* Web APIs +* NoSQL/Document Databases (_Future_) + +In addition, out-of-the-box, QQQ also goes beyond these basics, delivering: + +* Bulk versions of all CRUD operations. +* Automatically generated JSON APIs. +* Auditing of data changes. +* End-user (e.g., non-engineer) customization via dynamic scripting capabilities + +#todo say much more# + +== QQQ Architecture + +Like a house! + +== Developing a QQQ Application +In developing an application with QQQ, engineers will generally have to define two types of code: + +. *Meta Data* - This is the code that you use to tell QQQ the shape of your application - your unique Tables, Processes, Apps, Reports, Widgets, etc. +In general, this code is 100% declarative in nature (as opposed to procedural or functional). +That is to say - it has no logic. +It is just a definition of what exists - but it has no instructions, algorithms, or business logic. + +* _In a future version of QQQ, we anticipate being able to define meta-data in a format such as YAML or JSON, or to even load it from a relational or document database. +This speaks to the fact that this "code" is not executable code - but rather is a simple declaration of (meta) data._ +* A key function of QQQ then is to drive all of its layers of functionality - frontend UIs, middleware, and core backend actions (e.g., ORM operations) - based on this meta-data. +** For example: +... You define the meta-data for a table in your application - including its fields and their data types, as well as what backend system the table exists within. +... Then, the QQQ Frontend Material Dashboard UI's Query Screen loads that table's meta-data, and uses it to control the screen that is presented. Including: +**** The data grid shown on the screen will have columns for each field in the table. +**** The Filter button in the Query Screen will present a menu listing all fields from the table for the user to build ad-hoc queries against the table. +The data-types specified for the fields (in the meta-data) dictate what operators QQQ allows the user to use against fields (e.g., Strings offer "contains" vs Numbers offer "greater than"). +**** Values for records from the table will be formatted for presentation based on the meta-data (such as a numeric field being shown with commas if it represents a quantity, or formatted as currency). +... + +[start=2] +. *Meta Data* - declarative code - java object instances (potentially which could be read from `.yaml` files or other data sources in a future version of QQQ), which tell QQQ about the backend systems, tables, processes, reports, widgets, etc, that make up the application. +For example: +* Details about the database you are using, and how to connect to it. +* A database table's name, fields, their types, its keys, and basic business rules (required fields, read-only fields, field lengths). +* The description of web API - its URL and authentication mechanism. +* A table/path within a web API, and the fields returned in the JSON at that endpoint. +* The specification of a custom workflow (process), including what screens are needed, with input & output values, and references to the custom application code for processing the data. +* Details about a chart that summarizes data from a table for presentation as a dashboard widget. +// the section below is kinda dumb. like, it says you have to write application code, but +// then it just talks about how your app code gets for-free the same shit that QQQ does. +// it should instead say more about what your custom app code is or does. +// 2. *Application code* - to customize beyond what the framework does out-of-the box, and to provide application-specific business-logic. +// QQQ provides its programmers the same classes that it internally uses for record access, resulting in a unified application model. +// For example: +// * The same record-security model that is enforced for ad-hoc user queries through the frontend is applied to custom application code. +// ** So if your table has a security key defined, which says that users can only see Order records that are associated with the user's assigned Store, then QQQ's order Query Screen will enforce that rule. +// ** And at the same time - any custom processes ran by a user will have the same security applied to any queries that they run against the Order table. +// ** And any custom dashboard widgets - will only include data that the user is allowed to see. +// * Record audits are performed in custom code the same as they are in framework-driven actions. +// ** So if a custom process edits a record, details of the changed fields show up in the record's audit, the same as if the record was edited using the standard QQQ edit action. +// * Changed records are sent through the ESB automatically regardless of whether they are updated by custom application code or standard framework code. +// ** Meaning record automations are triggered regardless of how a record is created or edited - without you, as an application engineering, needing to send records through the bus. +// * The multi-threaded, paged producer/consumer pattern used in standard framework actions is how all custom application actions are also invoked. +// ** For example, the standard QQQ Bulk Edit action uses the same streamed-ETL process that custom application processes can use. +// Meaning your custom processes can take full advantage of the same complex frontend, middleware, and backend structural pieces, and you can just focus on your unique busines logic needs. +2. *Application code* - to customize beyond what the QQQ framework does out-of-the box, and to provide application-specific business-logic. +QQQ provides its programmers the same classes that it internally uses for record access, resulting in a unified application model. +For example: + +== Lifecycle? +* define meta data +** enrichment +** validation +* start application +* for dev - hotSwap diff --git a/docs/Reports.pdf b/docs/Reports.pdf deleted file mode 100644 index 7e448538..00000000 --- a/docs/Reports.pdf +++ /dev/null @@ -1,2104 +0,0 @@ -%PDF-1.4 -% -1 0 obj -<< /Title (QQQ Reports) -/Creator (Asciidoctor PDF 2.3.3, based on Prawn 2.4.0) -/Producer (Asciidoctor PDF 2.3.3, based on Prawn 2.4.0) -/ModDate (D:20221103085718-05'00') -/CreationDate (D:20221103085721-05'00') ->> -endobj -2 0 obj -<< /Type /Catalog -/Pages 3 0 R -/Names 12 0 R -/Outlines 18 0 R -/PageLabels 21 0 R -/PageMode /UseOutlines -/OpenAction [7 0 R /FitH 841.89] -/ViewerPreferences << /DisplayDocTitle true ->> ->> -endobj -3 0 obj -<< /Type /Pages -/Count 1 -/Kids [7 0 R] ->> -endobj -4 0 obj -<< /Length 2 ->> -stream -q - -endstream -endobj -5 0 obj -<< /Type /Page -/Parent 3 0 R -/MediaBox [0 0 595.28 841.89] -/CropBox [0 0 595.28 841.89] -/BleedBox [0 0 595.28 841.89] -/TrimBox [0 0 595.28 841.89] -/ArtBox [0 0 595.28 841.89] -/Contents 4 0 R -/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] ->> ->> -endobj -6 0 obj -<< /Length 17799 ->> -stream -q -/DeviceRGB cs -0.2 0.2 0.2 scn -/DeviceRGB CS -0.2 0.2 0.2 SCN - -BT -208.9855 777.054 Td -/F2.0 27 Tf -<515151205265706f727473> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.64137 Tw - -BT -48.24 743.55743 Td -/F1.0 13 Tf -[<5151512063616e2067656e6572> 20.01953 <617465207265706f727473206261736564206f6e20>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -0.64137 Tw - -BT -274.36198 743.55743 Td -/F1.0 13 Tf -[<5151512054> 29.78516 <61626c6573>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.64137 Tw - -BT -347.00014 743.55743 Td -/F1.0 13 Tf -<20646566696e65642077697468696e20612051515120496e7374616e63652e> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.46577 Tw - -BT -48.24 724.02029 Td -/F1.0 13 Tf -[<55736572732063616e2072756e207265706f7274732c2070726f766964696e6720696e7075742076616c7565732e20416c7465726e61746976656c79> 89.84375 <2c206170706c69636174696f6e20636f6465>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 704.48314 Td -/F1.0 13 Tf -<63616e2072756e207265706f727473206173206e65656465642c20737570706c79696e6720696e7075742076616c7565732e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 659.46257 Td -/F2.0 22 Tf -<5265706f7274204d6574612044617461> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.05195 Tw - -BT -48.24 630.27457 Td -/F1.0 10.5 Tf -[<5265706f7274732061726520646566696e656420696e20612051515120496e7374616e63652062> 20.01953 <7920646566696e696e67206120>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.05195 Tw - -BT -320.67126 630.27457 Td -/F4.0 10.5 Tf -<515265706f72744d65746144617461> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.05195 Tw - -BT -399.42126 630.27457 Td -/F1.0 10.5 Tf -<206f626a6563742c20776869636820636f6e7369737473206f6620746865> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 614.49457 Td -/F1.0 10.5 Tf -<666f6c6c6f77696e672070726f706572746965733a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 586.71457 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 586.71457 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 586.71457 Td -/F3.0 10.5 Tf -<6e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -87.24 586.71457 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -95.934 586.71457 Td -/F2.0 10.5 Tf -<537472696e672c205265717569726564> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -183.3255 586.71457 Td -/F1.0 10.5 Tf -<202d20556e69717565206e616d6520666f7220746865207265706f72742077697468696e207468652051515120496e7374616e63652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 564.93457 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.32793 Tw - -BT -66.24 564.93457 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.32793 Tw - -BT -66.24 564.93457 Td -/F3.0 10.5 Tf -<6c6162656c> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.32793 Tw - -BT -92.49 564.93457 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.32793 Tw - -BT -101.83987 564.93457 Td -/F2.0 10.5 Tf -<537472696e67> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.32793 Tw - -BT -134.27437 564.93457 Td -/F1.0 10.5 Tf -<202d20557365722d666163696e67206c6162656c20666f7220746865207265706f72742c2070726573656e74656420696e205573657220496e74657266616365732e20496e6665727265642066726f6d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.32793 Tw - -BT -526.04 564.93457 Td -/F3.0 10.5 Tf -<6e616d65> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.32793 Tw - -BT -547.04 564.93457 Td -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 549.15457 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 549.15457 Td -/F1.0 10.5 Tf -<6966206e6f74207365742e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 527.37457 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 527.37457 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 527.37457 Td -/F3.0 10.5 Tf -<70726f636573734e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -123.99 527.37457 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -132.684 527.37457 Td -/F2.0 10.5 Tf -<537472696e67> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -165.1185 527.37457 Td -/F1.0 10.5 Tf -<202d204e616d65206f66206120> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -BT -227.247 527.37457 Td -/F1.0 10.5 Tf -<5151512050726f63657373> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -290.94 527.37457 Td -/F1.0 10.5 Tf -<207573656420746f2072756e20746865207265706f727420696e2061205573657220496e746572666163652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 505.59457 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 505.59457 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 505.59457 Td -/F3.0 10.5 Tf -<696e7075744669656c6473> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -123.99 505.59457 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -132.684 505.59457 Td -/F2.0 10.5 Tf -<4c697374206f6620514669656c644d65746144617461> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -255.0825 505.59457 Td -/F1.0 10.5 Tf -<202d204f7074696f6e616c206c697374206f66206669656c6473207573656420617320696e70757420746f20746865207265706f72742e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 483.81457 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -1.13019 Tw - -BT -84.24 483.81457 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.13019 Tw - -BT -84.24 483.81457 Td -/F1.0 10.5 Tf -<5468652076616c75657320696e207468657365206669656c64732063616e206265207573656420766961207468652073796e74617820> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.13019 Tw - -BT -358.98306 483.81457 Td -/F3.0 10.5 Tf -<247b696e7075742e4e414d457d> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.13019 Tw - -BT -427.23306 483.81457 Td -/F1.0 10.5 Tf -<2c20776865726520> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.13019 Tw - -BT -469.43544 483.81457 Td -/F3.0 10.5 Tf -<4e414d45> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.13019 Tw - -BT -490.43544 483.81457 Td -/F1.0 10.5 Tf -<2069732074686520> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.13019 Tw - -BT -526.04 483.81457 Td -/F3.0 10.5 Tf -<6e616d65> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.13019 Tw - -BT -547.04 483.81457 Td -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -84.24 468.03457 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 468.03457 Td -/F1.0 10.5 Tf -<617474726962757465206f662074686520> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -162.297 468.03457 Td -/F3.0 10.5 Tf -<696e7075744669656c64> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -214.797 468.03457 Td -/F1.0 10.5 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 446.25457 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 446.25457 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 446.25457 Td -/F1.0 10.5 Tf -[<46> 40.03906 <6f72206578616d706c653a>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.96078 0.96078 0.96078 scn -52.24 430.43857 m -543.04 430.43857 l -545.24914 430.43857 547.04 428.64771 547.04 426.43857 c -547.04 279.77857 l -547.04 277.56943 545.24914 275.77857 543.04 275.77857 c -52.24 275.77857 l -50.03086 275.77857 48.24 277.56943 48.24 279.77857 c -48.24 426.43857 l -48.24 428.64771 50.03086 430.43857 52.24 430.43857 c -h -f -0.8 0.8 0.8 SCN -0.75 w -52.24 430.43857 m -543.04 430.43857 l -545.24914 430.43857 547.04 428.64771 547.04 426.43857 c -547.04 279.77857 l -547.04 277.56943 545.24914 275.77857 543.04 275.77857 c -52.24 275.77857 l -50.03086 275.77857 48.24 277.56943 48.24 279.77857 c -48.24 426.43857 l -48.24 428.64771 50.03086 430.43857 52.24 430.43857 c -h -S -Q -0.6 0.6 0.6 scn -0.6 0.6 0.6 SCN - -BT -59.24 407.61357 Td -/F3.0 11 Tf -<2f2f20676976656e207468697320696e7075744669656c643a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.4 0.6 scn -0.0 0.4 0.6 SCN - -BT -59.24 392.87357 Td -/F3.0 11 Tf -<6e6577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -75.74 392.87357 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -81.24 392.87357 Td -/F3.0 11 Tf -<514669656c644d65746144617461> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -158.24 392.87357 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -163.74 392.87357 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -169.24 392.87357 Td -/F3.0 11 Tf -<73746f72654964> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -207.74 392.87357 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -213.24 392.87357 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -218.74 392.87357 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -224.24 392.87357 Td -/F3.0 11 Tf -<514669656c6454797065> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -279.24 392.87357 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -284.74 392.87357 Td -/F3.0 11 Tf -<494e5445474552> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -323.24 392.87357 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.6 0.6 0.6 scn -0.6 0.6 0.6 SCN - -BT -59.24 363.39357 Td -/F3.0 11 Tf -<2f2f206974732072756e2d74696d652076616c75652063616e2062652061636365737365642c20652e672e2c20696e20612071756572792066696c74657220756e6465722061206461746120736f757263653a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.4 0.6 scn -0.0 0.4 0.6 SCN - -BT -59.24 348.65357 Td -/F3.0 11 Tf -<6e6577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -75.74 348.65357 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -81.24 348.65357 Td -/F3.0 11 Tf -<5146696c7465724372697465726961> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -163.74 348.65357 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -169.24 348.65357 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -174.74 348.65357 Td -/F3.0 11 Tf -<73746f72654964> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -213.24 348.65357 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -218.74 348.65357 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -224.24 348.65357 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -229.74 348.65357 Td -/F3.0 11 Tf -<5143726974657269614f70657261746f72> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -323.24 348.65357 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -328.74 348.65357 Td -/F3.0 11 Tf -<455155414c53> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -361.74 348.65357 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -367.24 348.65357 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.46667 0.53333 scn -0.0 0.46667 0.53333 SCN - -BT -372.74 348.65357 Td -/F3.0 11 Tf -<4c697374> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -394.74 348.65357 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -400.24 348.65357 Td -/F3.0 11 Tf -<6f66> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -411.24 348.65357 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -416.74 348.65357 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -422.24 348.65357 Td -/F3.0 11 Tf -<247b696e7075742e73746f726549647d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -510.24 348.65357 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -515.74 348.65357 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -521.24 348.65357 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.6 0.6 0.6 scn -0.6 0.6 0.6 SCN - -BT -59.24 319.17357 Td -/F3.0 11 Tf -<2f2f206f7220696e2061207265706f727420766965772773207469746c65206f72206669656c6420666f726d756c61733a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 304.43357 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -64.74 304.43357 Td -/F3.0 11 Tf -<776974685469746c654669656c6473> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -147.24 304.43357 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.46667 0.53333 scn -0.0 0.46667 0.53333 SCN - -BT -152.74 304.43357 Td -/F3.0 11 Tf -<4c697374> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -174.74 304.43357 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -180.24 304.43357 Td -/F3.0 11 Tf -<6f66> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -191.24 304.43357 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -196.74 304.43357 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -202.24 304.43357 Td -/F3.0 11 Tf -<247b696e7075742e73746f726549647d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -290.24 304.43357 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -295.74 304.43357 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -301.24 304.43357 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.4 0.6 scn -0.0 0.4 0.6 SCN - -BT -59.24 289.69357 Td -/F3.0 11 Tf -<6e6577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -75.74 289.69357 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -81.24 289.69357 Td -/F3.0 11 Tf -<515265706f72744669656c64> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -147.24 289.69357 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -152.74 289.69357 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -158.24 289.69357 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -163.74 289.69357 Td -/F3.0 11 Tf -<776974684e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -207.74 289.69357 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -213.24 289.69357 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -218.74 289.69357 Td -/F3.0 11 Tf -<73746f72654964> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -257.24 289.69357 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -262.74 289.69357 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -268.24 289.69357 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -273.74 289.69357 Td -/F3.0 11 Tf -<77697468466f726d756c61> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -334.24 289.69357 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -339.74 289.69357 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -345.24 289.69357 Td -/F3.0 11 Tf -<247b696e7075742e73746f726549647d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -433.24 289.69357 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -438.74 289.69357 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.0 0.0 0.0 scn -0.0 0.0 0.0 SCN -1 w -0 J -0 j -[] 0 d -/Stamp1 Do -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -541.009 14.263 Td -/F1.0 9 Tf -<31> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -Q -Q - -endstream -endobj -7 0 obj -<< /Type /Page -/Parent 3 0 R -/MediaBox [0 0 595.28 841.89] -/CropBox [0 0 595.28 841.89] -/BleedBox [0 0 595.28 841.89] -/TrimBox [0 0 595.28 841.89] -/ArtBox [0 0 595.28 841.89] -/Contents 6 0 R -/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] -/Font << /F2.0 8 0 R -/F1.0 9 0 R -/F4.0 14 0 R -/F3.0 15 0 R -/F1.1 17 0 R ->> -/XObject << /Stamp1 23 0 R ->> ->> -/Annots [10 0 R 16 0 R] ->> -endobj -8 0 obj -<< /Type /Font -/BaseFont /5c9138+NotoSerif-Bold -/Subtype /TrueType -/FontDescriptor 26 0 R -/FirstChar 32 -/LastChar 255 -/Widths 28 0 R -/ToUnicode 27 0 R ->> -endobj -9 0 obj -<< /Type /Font -/BaseFont /2a0c33+NotoSerif -/Subtype /TrueType -/FontDescriptor 30 0 R -/FirstChar 32 -/LastChar 255 -/Widths 32 0 R -/ToUnicode 31 0 R ->> -endobj -10 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Tables{relfilesuffix}) ->> -/Subtype /Link -/Rect [274.36198 739.76143 347.00014 757.44143] -/Type /Annot ->> -endobj -11 0 obj -[7 0 R /XYZ 0 687.75857 null] -endobj -12 0 obj -<< /Type /Names -/Dests 13 0 R ->> -endobj -13 0 obj -<< /Names [(__anchor-top) 22 0 R (_report_meta_data) 11 0 R] ->> -endobj -14 0 obj -<< /Type /Font -/BaseFont /a5b3bd+mplus1mn-bold -/Subtype /TrueType -/FontDescriptor 34 0 R -/FirstChar 32 -/LastChar 255 -/Widths 36 0 R -/ToUnicode 35 0 R ->> -endobj -15 0 obj -<< /Type /Font -/BaseFont /760f48+mplus1mn-regular -/Subtype /TrueType -/FontDescriptor 38 0 R -/FirstChar 32 -/LastChar 255 -/Widths 40 0 R -/ToUnicode 39 0 R ->> -endobj -16 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Processes{relfilesuffix}) ->> -/Subtype /Link -/Rect [227.247 524.30857 290.94 538.58857] -/Type /Annot ->> -endobj -17 0 obj -<< /Type /Font -/BaseFont /b1eed4+NotoSerif -/Subtype /TrueType -/FontDescriptor 42 0 R -/FirstChar 32 -/LastChar 255 -/Widths 44 0 R -/ToUnicode 43 0 R ->> -endobj -18 0 obj -<< /Type /Outlines -/Count 2 -/First 19 0 R -/Last 20 0 R ->> -endobj -19 0 obj -<< /Title -/Parent 18 0 R -/Count 0 -/Next 20 0 R -/Dest [7 0 R /XYZ 0 841.89 null] ->> -endobj -20 0 obj -<< /Title -/Parent 18 0 R -/Count 0 -/Prev 19 0 R -/Dest [7 0 R /XYZ 0 687.75857 null] ->> -endobj -21 0 obj -<< /Nums [0 << /P (1) ->>] ->> -endobj -22 0 obj -[7 0 R /XYZ 0 841.89 null] -endobj -23 0 obj -<< /Type /XObject -/Subtype /Form -/BBox [0 0 595.28 841.89] -/Length 165 ->> -stream -q -/DeviceRGB cs -0.0 0.0 0.0 scn -/DeviceRGB CS -0.0 0.0 0.0 SCN -1 w -0 J -0 j -[] 0 d -q -/DeviceRGB CS -0.86667 0.86667 0.86667 SCN -0.25 w -48.24 30.0 m -547.04 30.0 l -S -Q -Q - -endstream -endobj -24 0 obj -<< /Type /XObject -/Subtype /Form -/BBox [0 0 595.28 841.89] -/Length 165 ->> -stream -q -/DeviceRGB cs -0.0 0.0 0.0 scn -/DeviceRGB CS -0.0 0.0 0.0 SCN -1 w -0 J -0 j -[] 0 d -q -/DeviceRGB CS -0.86667 0.86667 0.86667 SCN -0.25 w -48.24 30.0 m -547.04 30.0 l -S -Q -Q - -endstream -endobj -25 0 obj -<< /Length1 10064 -/Length 6276 -/Filter [/FlateDecode] ->> -stream -x: Tו͌gA 7$OH6%@pbc'iۉiI'fӳzm=IIMwOڴi랞&u#H`pmg߻gFeDcE Pa_2!hy{Gzh-ѩp˷B)_,F+05oroL4B^ |~4s9/w. [>ȄOIWpSwGLJ= *_o#Trts4Q.*>3:OBqqq✱޻}gN۟Pq׫Lrw/4 -dE@ .=>>r kZ{B"6 8EIo N @/Mɷ$=LA (nҌ6 lB4sIDG 7QH&z(ИA'YЊfGXNuh]HC݉(2b&AUԯWPP+N#-H$=fK?{ 92$J,13ܐrPn^D*q.v9C[mnY:-Z[ uRS.gTʲI8';+3#]&P$Ql*^3> , 2,IҒJb1݆t57 }or|xhCTdTBV,6gop浂̌n;A fV2\QikY (%6r۬ -ңٌgn^%+fxt3j^?rQƽ ~sΓ\-[X٪,l cZNk8}7Ĭ@-f?!p_"T8;?=y -f6l h ..9a nI93mwF٤PzVd? R9~r'q+"Aa /ye#uq+^pϳgl>8..Xdrf*?D - Z*2/쏓0@EǹNySP@j^m2N7k`rd[5@Rc L0]̲nK+fa#Kb 6+72mj/AG7ݔ2:QjMj"ʓEPj'ACrx*W]m+Њ4VѶ5% -]&PݫPzKWCN =D\zWXV 'qq/Ja4ktsq3 -T^50!%W.lV6&_E{obWssʙBBP[1-gynSVC}٥k,c%1lއ&]r_a_GBsi/xɂAKO0H$i4*I4,!ưh?Aek;E{IwEv?ZLʹŌ:3q1(~ ŖeL^|[N.Y.x/p{ _<<),>=w+r -rΔ1!O? '/=I<yd::^>y$=>yIr_:xDG?}|qQ9:Bd)9Bv.4jLּth}ӖaNC=-CX!mw/`灣GQWI[U .Y.O,k C(D#9h1qB?r yq=|q)n\c=f[2WRJbMSLF@Gj(Rv`I2"(INE2ޥSqz8,*$&J Uqj)&zs6I+#wF\|w`2t8EuUGO%i~oFht[;WM%t-NLN H5M ߈~=D7Pxd#aQNMe}*>.i:ݓޅ6alF>`o('xoKo7*}1_G 3?m/> ;o[1}y}һ_I|y,Kǯ>t>}8 qE5 MI9[oK2++vjq󈴢$7B:B*S;7T"{x!^j'ئͅm^kdm̾=;:pvUo3NbP&~_ѷVsfvI qMxgRHDňAUojoѥv;6͖/NyvcghH ةMixW/q?ѩچ ![Gymt2Z_Q_p5nkmSwM|mo?)?F\8qZ6ϙX|%&dx/anpSMm5vg켦Κ?6gתDy6:7ZWqۭN IeG:Ti^~qu2;|2qoI1lT;?H`6Nn٦rc_DFXsuݍNM"ͦ(LXkSKI$uCFN:zT~P}GO䨭PV\/є6wNӓ/^q+X!*a![$F_ޑi {A9{Wג&, y/W-.?x짏;?4u«/Ե3=5m\}j`O}OsLFM -WJX]l5:Q[r|S_W} @SRX.E%Z˯~lyr,26KaKRѺ=dJ.5?E&$KȁjQ~"g(k++=scr/no$9:57*οid+d9LiB\7ݙ*U(K!j~2y§=~K𑇊EJFU&Fݨο{=;mAp\ fe+Ufe6ȵtefV{fI&-Tvpai|\f&k)W4ɍ^WUdtk(4ẹUOcm] -~~>H BČ\4+Сf,%%FaP!%5FYy$+XhHj)Mg]EG9yG=}]}45t?m}:tٽ :یz V 킛,4I M«VbKQҖZ&Njlwk< - R^NN$ {Hivy.4tU?(m2|z[ÂK|zr2A)15·;ٍ5JYO2-d=U!ޱo]rMI\E*Je-İ4=ަv-ղ^{WA)]cqʹ| `OM KA 7l+(l::_E{:EaǴs[gH-nc}*2B1 ’NnJz'i4jK -^-+Ry͍Ta3h򻇌Ncf[TWy,L,v<)z@z6ѐIp҃${;_ѰOu yXQ;U j -SަۤTK4Nfk&zCx)ڵJ;LguƢ0gE _ 0(8&a)X?v`ڀfRI`Rp:RpңLTE,/$-g"X)vϧ`$(HD`YLR2|0S)N-/Rp:6 4FRp&HذQ')8ҞD͆qLMh̄9V{~}$dWdڿ52|7u   BN_knh36i9 ^@*>:>¾tdrYsfhg>:)zOWI8x`S`H0@8bX?qLvD&fӡL Ɯfx0@;[h`&)%)PCK2( ρ74HfhU;TtWGwmz`ڝ~z~gЁ3Kb1:2K*G ғ'h`"4}3Ss)" b#?}q p@5WW E1},4NznAQ͢BAoz&'67i}- k44^k/< h81&$~3<XF>:h@#<-Tn$|҃g5B>hqAo, 19*'`>kg%눧b^_9Ҭ3X vփ `kd @֐ֽ7~CC hs` w' ^>犋lpaU9"Mu@d{uf-4V5PGc -):}S0WގQv;a óp;}BÜa$y>p2X,+!8*ᕪfLொ+ 1I3?N˥sH"[cX*~Tü/Lt/wfuvo\ʦlYy>b.Q~MÛq -\䷠< nugVj -+H/v3@Ca9ܼV"܊q -endstream -endobj -26 0 obj -<< /Type /FontDescriptor -/FontName /5c9138+NotoSerif-Bold -/FontFile2 25 0 R -/FontBBox [-212 -250 1306 1058] -/Flags 6 -/StemV 0 -/ItalicAngle 0 -/Ascent 1068 -/Descent -292 -/CapHeight 1462 -/XHeight 1098 ->> -endobj -27 0 obj -<< /Length 1278 -/Filter [/FlateDecode] ->> -stream -xenFὮBtHs&@nu{stԒ + }ik/y_!}t~]snVyg쾝+|<.÷}v)[eO/_q9_ɯ}ഏOmt_LLv͵LJ1w9)e6=n?[i(JKiU:JSz2QeL*EJ̔Ye,*+eU(NU-уk5x5F^ky ^#k5x5F^ky ^#kxZV^kZy-^+kxZV^kZy-^+uxu:N^:y^'uxu:N^:y^'xz^^zy=^/xz^^zy=^/o xo7 Aހ7y o xo7 Aހ7y oxo7jo$JI$$*I$ITH$$QI"IDD%$JI$$*I$ITD$$III$$u>M&Iބ7ɛ&y$o›Mx o7M&Iބ7ɛ&yUoa[5joSor4ۂsޮ>,x/x;Â31x; -JJ특xxx+!ÊwBxbx+ށr;2kΜJYeY7+|x oS7+[ƛețךyޢoV浖 -㭌"RW*4XqC^J[(^1»y]k}YM-x e#e_y+h܊7k:/Z5dUluz5n[eB&Si|y(%q& %+S%*ABijPU6\h,(+L,4G5sh>:OVRP*#i|e0U,*oU/*[U,Nmlx:&\}M)L2\%CHF7էʻBL)jƻJ1:%H߯:=S۳zrmkO媳7 -endstream -endobj -28 0 obj -[259 600 600 600 600 600 600 600 600 600 600 600 293 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 767 600 621 600 600 600 600 600 653 952 600 600 600 787 707 585 600 600 600 600 600 600 600 600 600 600 600 600 600 599 600 600 648 570 407 560 600 352 600 600 352 600 666 612 645 647 522 487 404 666 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600] -endobj -29 0 obj -<< /Length1 12420 -/Length 7606 -/Filter [/FlateDecode] ->> -stream -xz t[Օ9^}?ɖ|-%ٖW%d91dK$XrI3I -!4 d/%X00a蚆kIy}LȚ2 >GWw{s0B(A,r K&4 'q]{U1s@KV5>71sG'{B oӋϖZPMz\n>pWL!M@v6ٓ3{{O<sM8q[ϸcBkƳ4r~PDƜ>a~F=su\Ǎ쎫E ѹOIisBf*G -]0N~r2xj}2;*G?D0Xα@8AL$p[$֞VdFC"@3 -2c"Et@$u3n -uK>A>P+i@(_CᎢqwH~AkCP%׍1_d6I>Ɲ*^E 4¼r}ɥ#"cHμԛ!AaVkzmt5Â0&!,AȨXaPBb"9%5-]Tj u9y~+//uab475jkUUV ]դ)bc"#2cB8\֦'kԲ';) [8!N'kQ -|M/}OZa>1SˡH Z-i>5вr관+QB'R_DFP O1!Ti~qU{Hr-0j2d)" 5`D~b`u'@/ -B?-]bW0MYhFa.IԲN 8qX@P0Z-df޺Dr#ɣ OB;>ȴޕ2^&T-DpJ3`uh*7qޡ bXpxIR7մT<:v8DCDn#8T!1N;; @[jpCp(uS-*5cI^s[X Mֆ.}ݼ81X@c@ %# | ЈΠ: ,pBw! 6:7J5mKw{_ KD -Dy{t7W%NA2FhqA@ЌYb6l!/ %aQKa9:@JDsI__?wŌx:A fMW2 -2J B$"%P|l#Ji-3!Z| ̔F.R$z+&s8J`#_4:)xQB7zC.%tdNKV4= -zِD<ON'f^XEeC 2g*_[ -[VX ݋TF' ,l8x(OÓ'Z@7 :ȁ#ˀ&CfQT=Xr8hY:}o{1fP<'+faFB \bq:HLɩЦlB r1?rqq&Yl?;~vY=cGУ3gkg uf c>ݧ?N~ӷN/t'ipz+^VlIOGƴh@;W0~xɓ)3P:83;n8@|4¾ݾ݀"_+_~. !9G((,$d:w!! -ӐTExsY(yssu :*y *_ay Q؎+]@?8{a.gu &dCf]ȋ.k471t;WL}3X@'l)L3DHU{>olxY"􄮫eN4˔6PCh/D"Q[ Z\C.H/tQ#*ҟHb2Ypy9z~-]n2L> ouT3O5jCQs~j-wd3q5Nٹ?HJ%I',3!/?,׈">l DqQ"s,y3%ht8[bdfW#yQS WIkS)bYy=./3peR5OfJJپ*J7PZ*YOՓxad76xeJ*&d|9jtxS|IB!“a>!VF($' F((|y^ni+`[א)73 S^6`SB -uzUnN4WiHMu1WV]+u{,,Dډ.nA-%l/mi Xm\ldd8Yhm؄լ1kVc0:W]Io\עӳԪ7#YRJF /wL3&1%_vhBv͝Ov@S̷!BV,,߭ JG%3ʪ׫ȴ*S |;C([rd!w6o; f%a({)ٛԦ/˞%~iVoJI@s -+X Ƀz %U K^>{᳧/w?9?XQ3ߘ~> N޽Wϳzٳ.o /xW°_ذ{rkߪ={3w7յ8tb5n^WfDؙsCCz<`MVRF4ݓZG<֒|Le; /IJ'KG.ap96n]lQȎ{4}_cڪi7M4kB.+h,aޤqTB36k$*X_E[5ޡ6͟jcm՞v=.ɒ?ڶf˂Ïy{/I9a9/n-0|\Xke|Lzf}&ԣPӬd[)A!RTғa p{8פdɞIŔVw9k=O 5T{,22\LwP)B; MƮ޽m{zz -՛sO*28RB`,~j=]摝e5-8Eз wJ/)o.7ꊦ_|׿mZ_Jհ1 ij5:޼7lM|:EZLEEȁ),p/{6uoP,;WN=WZәx}3)ou{ x -gIeZP%'U3VM԰L/l:7=v~fok/ٱ-16hq_YG:58K7Ygʐ(5ydVB-t4ַrSRE :ML`帊ѫwYhrj6xlvdC񑇜%9e|FafƐ<ڸZAd 1ʹ*FLJe!iDz4k5]V'}5PHERhCre~4N,PzwEJ"[eT}8rOx'~ -ZGLyRd5;qJJk4zu iݳTݦ5=4Vj-Jt8MJnfBtZrLtLႣrYIMW'H }U?YÜ. $69ME%jS2sLwW񺦝:!6u{@]j^xVzlMbNP`Vٺ?D5t|8'ԄAoxWϨS3_1NC͓m:`/9B8TF*GRҖJ#| JlzR"ԟi$MAZzH"A%~$1gĨa30 -* )-_6yj|am\FCN0-MDKK/\fPpWNFImWb\yux;d !;:U< }p Riq*Rcn+.ݱ.)A7\-A̅TSy"uڼ*mCj0+.mkχ]DگGl}ab䞦vrU`7w"֞ᒾTPZ|sQ+n-tA8RQx.ֽ -6?Jy{2MU3lyf=#-.<7?,O"̗:y_RRl&c-=>V&EaCPjs?> Iٙ+3i VSN}Y,`Kj[Bj¡\QYQr{dꡭm e+s %MQ;#rzܴu l3)NXNԞ9rE5dC[YqmN^$'}6?V"7Y:r_[[##PG4q#J\6dFHKAL ~n!G*WRfܦN6ѳЕS9P\WV2(X!Q,}=gʾJ>bWkĚSY\ ]ɚS<1VTX=j/] -}]U`o(=ǕdZk0]=SPR=&< -wg6\C!vp0 +S }5[{q4"Wa)+>#or@ՠV8wKmqѳS#:Ck־?b }lj%RD%Y{aXA e}\~"&#]$ӑ͖8R:&_VfbS<=4ةLiޫç 5eokB0I!o@!-`s&"i7Ui -4"O3.j"At~3:#S%RIB2mβ=mCi:3;5ThtY/t۳KSu.ӯcR Qп :w20FZ髰lo TcRzX7VnE&<JiIR5fA͠bRLO='5]֥&Q nDjFYB ֩M9;˫}9!%:9_^=PaГ~{wlwL.ԉe[,L|t==x,V-ߔ"ըR8iT!)Jcm)wO|ed8N }mJюpn`r ukosWWvtVUwju~pp_ZBOG~HdDxEA28C02Y9K%(M#PW(=-H^Hd@"Q^D8wH`첻"- eEEլZ9`",Aiː ˔"OE8pJB~FD8yDcQfĤ/-.)[މi>;f~=>~{xgba5;/y!g7K 1tsMxw=3w|*_dMM׌wS~PU{"10Uw}aNf'<~#0{g_pOy'Aײַv{ ScY̹0I?yfC]!"~#%S>XkjƁ"~}657v[~> X =ww[x3{|w"x^W~7] b3?3#@f`̔wg~kѻ0/$+ iw~҅͡E4`N"?Q)*V}ykGh *4|xԿ6G1n~y4@ShrMv蝥\GhYxH܉f`"+ `K) n?p@Kod|^ӯP_sX 0(N0@P og7JUT NP_ ]khN!> -endobj -31 0 obj -<< /Length 1278 -/Filter [/FlateDecode] ->> -stream -xenFὮBtHs&@nu{stԒ + }ik/y_!}t~]snVyg쾝+|<.÷}v)[eO/_q9_ɯ}ഏOmt_LLv͵LJ1w9)e6=n?[i(JKiU:JSz2QeL*EJ̔Ye,*+eU(NU-уk5x5F^ky ^#k5x5F^ky ^#kxZV^kZy-^+kxZV^kZy-^+uxu:N^:y^'uxu:N^:y^'xz^^zy=^/xz^^zy=^/o xo7 Aހ7y o xo7 Aހ7y oxo7jo$JI$$*I$ITH$$QI"IDD%$JI$$*I$ITD$$III$$u>M&Iބ7ɛ&y$o›Mx o7M&Iބ7ɛ&yUoa[5joSor4ۂsޮ>,x/x;Â31x; -JJ특xxx+!ÊwBxbx+ށr;2kΜJYeY7+|x oS7+[ƛețךyޢoV浖 -㭌"RW*4XqC^J[(^1»y]k}YM-x e#e_y+h܊7k:/Z5dUluz5n[eB&Si|y(%q& %+S%*ABijPU6\h,(+L,4G5sh>:OVRP*#i|e0U,*oU/*[U,Nmlx:&\}M)L2\%CHF7էʻBL)jƻJ1:%H߯:=S۳zrmkO媳7 -endstream -endobj -32 0 obj -[259 500 500 500 500 500 500 500 500 500 500 500 250 310 250 500 500 559 500 500 500 500 500 500 500 500 286 500 500 500 500 500 500 705 500 500 500 500 589 500 500 367 500 500 500 500 763 742 604 742 655 500 612 716 500 500 500 500 500 500 500 500 500 500 500 562 613 492 613 535 369 538 634 319 299 500 310 944 645 577 613 613 471 451 352 634 579 861 578 564 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 361 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500] -endobj -33 0 obj -<< /Length1 3808 -/Length 2513 -/Filter [/FlateDecode] ->> -stream -xW{l[΍c'M؉uInlǥiڦi6v:/웶أX`SCnۉ!]5ULbuGA41@8αcڽ9|8p -*;$H*nnGo8"*|3X7_Th9g V"TŒ3'#_ymZr8 _ZDV[)DGBWHCD_ -ȒA4N ݇GםY3uN`=}p %ڼG?kۏ@b+@Ji<+p|\=#}Z 8zM!! /B% -8)}$BUPC-ȰF)bjQZ -Gu8،Åc#8Lƫ!圁ho׭~۵(-sUհjߥ]jXP9RAѬjmm!.'DRI١;`!C';!3Wh; OCfѢVڂWBWi:P VrSSfFgEˢ*{nq9j;0T0,RU6X ”-9cWӛD뼜Z;u:T, t ձXڋX2cg%fL.`i(ffv].qE%`  "- 0s(ɡ24`V#n)&1<{0F;Q!kHT,T:1_A~ zIo_"x"Ȟ8ً}f؇/H(IuܲdWQ}d*9 ժB]dqH -ŮMC%*Xyt7S0\&%A$;~<9<x<c-W^-X p;|`FqmƕD|wӵF}#ݚ;zpzZg}c0 -/ý,VoD[* mlzpTH/XQtk m,umijjMn$ĽZiY%: _nϡCmS|ٓN$# 7ϓ5ϟ}VN6^MhHuDlw1RD!i|w3fmV<;_k/^4&Q7cO/ `Swɠm]^VRB5VɈGnY5t DNJchplaIZ zXyAFc&nlj+}rǶ^?rH(޼H::BwVѽ؈x#ZI>oUk[['fYpx)R|n ݎ_ǫ[.,r7O[RaϓW\{ r̪b/?3~(ރ&+,ɪkDW\&4-"y*"FLb&^ȥ׸:lb)n"u._xo#fL e6LkC5Q+Wґ2œ.5/upGF4ZrL PE. -˴2] -L׀W)u½6`4]|.+#[B8 - ߙJeLZb2u;%MKn`esD&M;wM{T69G 4Z%rqcC䝙|4}RD<*<; }gsq<h1BH}qi.軅LH_:,)[ov^ a؉7> -endobj -35 0 obj -<< /Length 1278 -/Filter [/FlateDecode] ->> -stream -xenFὮBtHs&@nu{stԒ + }ik/y_!}t~]snVyg쾝+|<.÷}v)[eO/_q9_ɯ}ഏOmt_LLv͵LJ1w9)e6=n?[i(JKiU:JSz2QeL*EJ̔Ye,*+eU(NU-уk5x5F^ky ^#k5x5F^ky ^#kxZV^kZy-^+kxZV^kZy-^+uxu:N^:y^'uxu:N^:y^'xz^^zy=^/xz^^zy=^/o xo7 Aހ7y o xo7 Aހ7y oxo7jo$JI$$*I$ITH$$QI"IDD%$JI$$*I$ITD$$III$$u>M&Iބ7ɛ&y$o›Mx o7M&Iބ7ɛ&yUoa[5joSor4ۂsޮ>,x/x;Â31x; -JJ특xxx+!ÊwBxbx+ށr;2kΜJYeY7+|x oS7+[ƛețךyޢoV浖 -㭌"RW*4XqC^J[(^1»y]k}YM-x e#e_y+h܊7k:/Z5dUluz5n[eB&Si|y(%q& %+S%*ABijPU6\h,(+L,4G5sh>:OVRP*#i|e0U,*oU/*[U,Nmlx:&\}M)L2\%CHF7էʻBL)jƻJ1:%H߯:=S۳zrmkO媳7 -endstream -endobj -36 0 obj -[500 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 500 364 364 364 364 364 364 364 364 500 364 364 364 500 500 364 364 364 364 364 364 364 364 364 364 364 364 364 364 500 364 364 364 500 364 364 364 364 364 364 364 364 364 500 500 364 500 364 500 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364] -endobj -37 0 obj -<< /Length1 6572 -/Length 4433 -/Filter [/FlateDecode] ->> -stream -xX}P[וI0$x0<@!! /!@|P 3$MǓmYo\wYf8ٴI3n7q38LƓdnIx=l6mfZ}{s=+!JCGm4Y!Og(eqLABB:OJXy! Ng @%ML"ׄ?}U-vBStWm2:|-o)iF#0O\? ^x *ن{ME%1H9YcMTAD@CBw1?`jހUd&%!a-d]qȎ8tP1CJ3swf$B*K*]BAkm.-Zܜr#2u\ɭKkZc _kIǸ2F-9 ?#P&obR3)HY֠ 2Ym^sO*,֗m(7+*TLG8opy㝻}q7ʽ>:vǽǙql8cr{[yW븸>c\i :^^/}]O_.'{>:^a12Pܱ8D Et~g(ɐ6V Y5+q!jru:_<Yp:WkjN'{9wwp^.] |kʰ47ϵ;<7x'G L]:.>nЦ_MG Sze2<CBOŽC ?JpKHuAo`NC'"d4%f ɷ~sҸ"5UJ|ج[w"U׉PBTܚ|eE_bT`Kl1k- -w+,a^UZ|`{Iů7"#. ] #peQJl\ED᫑"r W0(L͜YƆ62_}OyGED%fGffzC-3)̪ {KXXE BjnFt%xԂ,t\~ɘ5bfA)؏deI{,,(Sb@τLs&'f˙+bࢗ9".د3Kzm |a|J6lZ_'fgkzYՍ{5ndW>vJ|=߸O,ѯ p~8)ɖe65\"fDHYO#:>lnv>t9ġOoSy}tO -YkZF='_/NvQ-S7`<d>(^A?[YwtF:-#q4, *<2>m0$5Ssqav zӥ7d SZUWgj}J@F42=YA<Y~Hr AjҲDm>+2ӽZ~ -ΞEvpSO.,:>@PA&Y/f LWk*7fX͂0y62hcjsn,b\i*5wƚj뫬meQߓ\5k h"q(_isWVwU5b壇أ'҉?HAU$5%]lkwOFKM-ط[11 -5NK':٨!d =RWE5tOTډgKh蔁-hb3󸲵@`Lj}G1Zc ZGHdv z Ux%l4Rk6T|n㏻ Ѯ5kVGi؉_-=ziܨ-&k=^Q+[êY[u0(ݽŎt-߿z&.29kHIm{/ժ#o])_^ake,!4s,bo4Cjq_Lmq< ŽT2:MUt46OkcO2k?ZW^99nqZiZ2H%3S Oۿ2۫ -G~VJ~7A<\oj(]o16j=`e2?|;xkp͕"ȕ -9UiVr]``T0u/ ̵#<~Vx@"'rm[h oҔƇᓏ_kx6UCg=k%3va2 -|$n/ZH5*k`De}l먷muw{8}z^]|iyAsOۦv)[sybQ&UObBey&5MxCe)v)F=,_66ugP/LUھS ,aOlLzWu/pV~ S_Q|tJœh&Fhwۙv]gy%~^tÂ8I(;)%zg}=%O/]Z VL0PجZqn$㫭tLWSwGkb1vtta[Om ںZBoU~>ݛ+; R p_\Ȉk!$SV~H=f2JVN@ihLP6 -t -p?h5RLkP"2V;z iRK2͠42i%Jee:1LjQBʴ*W5(M)k@QV4X fXXg6r圳ǹܽWMEI393AT!p8iXm$@pf6pUYɹY4H`XlzSe%6lEt61 g92‘L0Fc{3 -?2 -ǂn:83Č?BFcQnn6h2@x66> rᘁ }GbT4cd0驩X?90GC:렮him -_m{MnwSW!E65(F ]%:A8 6ՍDyP.^'jy<_!('D~tz0{ƃ9$)ya͂Q*QE 㧺M:= :ZwU0pwx;X; 30ZIbE= a&ݦ] % S|7. @ɻ@hGxT6Fwf;ƨ6d=µR!g=a`dlP RI|Ho f`$貂rEAJpr_@H!\{BxoO=2nx% /(P ,'hJر, #~,<+L>CF_Hޥv>pF,F%p͕CƅL1w -:J<-'Qq#$ln]`_aT&s0mZCkiF7Q o\_Ćj8QݬNnlqVx|/| M:?D -endstream -endobj -38 0 obj -<< /Type /FontDescriptor -/FontName /760f48+mplus1mn-regular -/FontFile2 37 0 R -/FontBBox [0 -270 1000 1025] -/Flags 4 -/StemV 0 -/ItalicAngle 0 -/Ascent 860 -/Descent -140 -/CapHeight 860 -/XHeight 0 ->> -endobj -39 0 obj -<< /Length 1278 -/Filter [/FlateDecode] ->> -stream -xenFὮBtHs&@nu{stԒ + }ik/y_!}t~]snVyg쾝+|<.÷}v)[eO/_q9_ɯ}ഏOmt_LLv͵LJ1w9)e6=n?[i(JKiU:JSz2QeL*EJ̔Ye,*+eU(NU-уk5x5F^ky ^#k5x5F^ky ^#kxZV^kZy-^+kxZV^kZy-^+uxu:N^:y^'uxu:N^:y^'xz^^zy=^/xz^^zy=^/o xo7 Aހ7y o xo7 Aހ7y oxo7jo$JI$$*I$ITH$$QI"IDD%$JI$$*I$ITD$$III$$u>M&Iބ7ɛ&y$o›Mx o7M&Iބ7ɛ&yUoa[5joSor4ۂsޮ>,x/x;Â31x; -JJ특xxx+!ÊwBxbx+ށr;2kΜJYeY7+|x oS7+[ƛețךyޢoV浖 -㭌"RW*4XqC^J[(^1»y]k}YM-x e#e_y+h܊7k:/Z5dUluz5n[eB&Si|y(%q& %+S%*ABijPU6\h,(+L,4G5sh>:OVRP*#i|e0U,*oU/*[U,Nmlx:&\}M)L2\%CHF7էʻBL)jƻJ1:%H߯:=S۳zrmkO媳7 -endstream -endobj -40 0 obj -[500 364 500 364 500 364 364 500 500 500 364 364 500 500 500 500 364 364 364 364 364 364 364 364 364 364 500 364 364 364 364 364 364 500 364 500 500 500 500 500 364 500 364 364 500 500 500 500 364 500 500 500 500 500 364 364 364 364 364 364 364 364 364 364 364 500 500 500 500 500 500 500 500 500 364 364 500 500 500 500 500 500 500 500 500 500 500 500 364 500 364 500 364 500 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364] -endobj -41 0 obj -<< /Length1 6532 -/Length 3675 -/Filter [/FlateDecode] ->> -stream -x9l[y߽GR-)GGHKI-ű]զ$MGHڤ|4=v6/:c5Y5՞,A1,O)%:-؊a2XEe~6 gxw@=́ѠomoH -9DhBnը6Cm9P"/OIYA>yԯKN_Htϧ9^MᏰL!nm?ψOgdh1q|>'Ff?\~,U}C8=5A`s%uY[gPkV޻)d (y| Yunis9E?;9FU6SqK*r|܃˽ - Ԛ$xehtt@Q:/D*6:̉qw;/9|OdGnG[KcVZe1D@WŨMp% &BLHmiѭnL'.K%A_W'JTGxy~ælC@ mIyNbԫfSEõjkAjjEH#Ȟ%ذxiu8]~^p reP&i/ӥwW0sť\De-b[zS+y/g蝒ǫ;8!nnKt?J 0Ї-}cEy47)QT\+ar靗[uߕnccو.hJF -IChEfal@`80nDDq -7rFu!8V8Maƙpcf3uS?.y1/$THvVT@\Wx jmVTv^>n:av7ffS-hvurCA-9.s=<}Kz>[t0U 5qP62M39h -#oCOR/m腨n5-F -]VQlQb4F;] EA)0~:rp`LHֲ\J#BEA;i[݊ՎThBER1Ũ-5 Cp#(N5,؎4I,-,4")RTJQ=asc1c5, 8]AX0uusp!6-Z@ȌKA@:>O -b$ _1%8hQNjR0ǥ"k;H 4ՉD./v|^EnD D@^mNB,M bo8 Z&i -ԲP+4i2i`ZRc<4T1ek1"#:btKD52J~яF•AIWEW ߙ H#U ;)oaKF ˄;p?6V -%RKZxl+kdn#;՝( [BlCԡL-q(kI Ҫd5u>XQFV+XEƯ1bF;&E# X8﷬*∌VY"y-GovJm;$xrcmC㷉}&[=G H𿊥Ѷ$]zu׈ׄKkkDj:wT x,E[$EH[ `ze[ 3ÅoȎ6 ٧CYq'i ?Ve*YЍdJfMq)¾;F\Yg6&t&$TSoIɱhx%|+6> PM!bzZ=Mb {la -!neVl61 /[ -&\31eR(tJ{V' kue§,y#zlW4p3`f9y!Yyq'T oTZpF%g3( ¦,v(gQ+8LɆSكDH,#7?j:WJְxkZރI9Oݧ| ? | 7Xwke~ -u[/<*7Tݴ{ GB]s oSS%aR,ٶH;=siAarq* H)Y9>%8s"7STnj+zt؀En6W ،$ ؂eՀ`72l==Yc5 gwo; o#Rv -j`0F P/ X#lF1bfh -u![Z´j6Jԩ|:jz;OF}'`yHM>؏-!f> -b~|OL^Џi'ֵT)+hk8JBx1$aAF3p Gy$Q6-w}NrHEY8nMiUCITxy|/PH ʻU z~Pc?oس9&"R}=5dazZ_KVJ%(% -endstream -endobj -42 0 obj -<< /Type /FontDescriptor -/FontName /b1eed4+NotoSerif -/FontFile2 41 0 R -/FontBBox [-212 -250 1246 1047] -/Flags 6 -/StemV 0 -/ItalicAngle 0 -/Ascent 1068 -/Descent -292 -/CapHeight 1462 -/XHeight 1098 ->> -endobj -43 0 obj -<< /Length 228 -/Filter [/FlateDecode] ->> -stream -x]n <"ANi.9liD!o?CNЏyx/?r4#p>،kܲAp7Z7N7Wl9SvJ1U/}p0 -endstream -endobj -44 0 obj -[259 354 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500] -endobj -xref -0 45 -0000000000 65535 f -0000000015 00000 n -0000000243 00000 n -0000000445 00000 n -0000000502 00000 n -0000000553 00000 n -0000000825 00000 n -0000018677 00000 n -0000019078 00000 n -0000019247 00000 n -0000019411 00000 n -0000019585 00000 n -0000019631 00000 n -0000019680 00000 n -0000019760 00000 n -0000019929 00000 n -0000020101 00000 n -0000020273 00000 n -0000020438 00000 n -0000020512 00000 n -0000020662 00000 n -0000020835 00000 n -0000020880 00000 n -0000020923 00000 n -0000021196 00000 n -0000021469 00000 n -0000027836 00000 n -0000028053 00000 n -0000029407 00000 n -0000030321 00000 n -0000038018 00000 n -0000038230 00000 n -0000039584 00000 n -0000040498 00000 n -0000043101 00000 n -0000043309 00000 n -0000044663 00000 n -0000045577 00000 n -0000050100 00000 n -0000050311 00000 n -0000051665 00000 n -0000052579 00000 n -0000056344 00000 n -0000056556 00000 n -0000056859 00000 n -trailer -<< /Size 45 -/Root 2 0 R -/Info 1 0 R ->> -startxref -57773 -%%EOF diff --git a/docs/actions/QueryAction.adoc b/docs/actions/QueryAction.adoc index 13ebf822..48ab2450 100644 --- a/docs/actions/QueryAction.adoc +++ b/docs/actions/QueryAction.adoc @@ -1,34 +1,45 @@ == QueryAction include::../variables.adoc[] -The `*QueryAction*` is the basic action that is used to get records from a {link-table}. +The `*QueryAction*` is the basic action that is used to get records from a {link-table}, generally according to a <>. In SQL/RDBMS terms, it is analogous to a `SELECT` statement, where 0 or more records may be found and returned. === Examples ==== Basic Form [source,java] ---- -QueryInput input = new QueryInput(qInstance); -input.setSession(session); +QueryInput input = new QueryInput(); input.setTableName("orders"); input.setFilter(new QQueryFilter() .withCriteria(new QFilterCriteria("total", GREATER_THAN, new BigDecimal("3.50"))) - .withOrderBy(new QFilterOrderBy("orderDate", false)) -); + .withOrderBy(new QFilterOrderBy("orderDate", false))); QueryOutput output = new QueryAction.execute(input); List records = output.getRecords(); ---- +=== Details +`QueryAction`, in general, can be called in two different modes: + +. The most common use-case case, and default, fetches all records synchronously, does any post-processing (as requested in the <>), and returns all records as a list in the <>). +. The alternative use-case is meant for larger operations, where one wouldn't want all records matching a query in-memory. +For this scenario, a `RecordPipe` object can be passed in to the <>. +This causes `QueryAction` to run its post-processing action on records as they are placed into the pipe, and to potentially block (per the pipe's settings). +This method of usage needs to be done on a separate thread from another thread which would be consuming records from the pipe. +QQQ's `AsyncRecordPipeLoop` class provides an implementation of doing such a dual-threaded job. + +If the {link-table} has a `POST_QUERY_CUSTOMIZER` defined, then after records are fetched from the backend, that code is executed on the records before they leave the `QueryAction` (either through its `QueryOutput` or `RecordPipe`). + === QueryInput * `table` - *String, Required* - Name of the table being queried against. -* `filter` - *QQueryFilter object* - Specification for what records should be returned, based on *QFilterCriteria* objects, and how they should be sorted, based on *QFilterOrderBy* objects. +* `filter` - *<> object* - Specification for what records should be returned, based on *<>* objects, and how they should be sorted, based on *<>* objects. +If a `filter` is not given, then all rows in the table will be returned by the query. * `skip` - *Integer* - Optional number of records to be skipped at the beginning of the result set. e.g., for implementing pagination. * `limit` - *Integer* - Optional maximum number of records to be returned by the query. * `transaction` - *QBackendTransaction object* - Optional transaction object. ** Behavior for this object is backend-dependant. In an RDBMS backend, this object is generally needed if you want your query to see data that may have been modified within the same transaction. -* `recordPipe` - *RecordPipe object* - Optional object that records are placed into, for asynchronous processing. +* `recordPipe` - *RecordPipe object* - Optional pipe object that records are placed into, for asynchronous processing. ** If a *recordPipe* is used, then records cannot be retrieved from the *QueryOutput*. Rather, such records must be read from the pipe's `consumeAvailableRecords()` method. ** A *recordPipe* should only be used when a *QueryAction* is running in a separate Thread from the record's consumer. @@ -36,18 +47,21 @@ Rather, such records must be read from the pipe's `consumeAvailableRecords()` me (e.g., to provide text translations in the generated records' `displayValues` map). ** For example, if running a query to present results to a user, this would generally need to be *true*. But if running a query to provide data as part of a process, then this can generally be left as *false*. -* `shouldGenerateDisplayValues` - *boolean, default: false* - Controls whether if field level *displayFormats* should be used to populate the generated records' `displayValues` map. +* `shouldGenerateDisplayValues` - *boolean, default: false* - Controls whether field level *displayFormats* should be used to populate the generated records' `displayValues` map. ** For example, if running a query to present results to a user, this would generally need to be *true*. But if running a query to provide data as part of a process, then this can generally be left as *false*. -* `queryJoins` - *List of QueryJoin objects* - Optional list of tables to be joined with the main *table* specified in the *QueryInput*. +* `shouldFetchHeavyFields` - *boolean, default: true* - Controls whether or not fields marked as `isHeavy` should be fetched & returned or not. +* `shouldOmitHiddenFields` - *boolean, default: true* - Controls whether or not fields marked as `isHidden` should be included in the result or not. +* `shouldMaskPassword` - *boolean, default: true* - Controls whether or not fields with `type` = `PASSWORD` should be masked, or if their actual values should be returned. +* `queryJoins` - *List of <> objects* - Optional list of tables to be joined with the main table being queried. See QueryJoin below for further details. ==== QQueryFilter -A key component of *QueryInput*, a *QQueryFilter* defines both what records should be included in a query's results (e.g., an SQL `WHERE`), as well as how those results should be sorted (SQL `ORDER BY`). +A key component of *<>*, a *QQueryFilter* defines both what records should be included in a query's results (e.g., an SQL `WHERE`), as well as how those results should be sorted (SQL `ORDER BY`). -* `criteria` - *List of QFilterCriteria* - Individual conditions or clauses to filter records. +* `criteria` - *List of <>* - Individual conditions or clauses to filter records. They are combined using the *booleanOperator* specified in the *QQueryFilter*. See below for further details. -* `orderBys` - *List of QFilterOrderBy* - List of fields (and directions) to control the sorting of query results. +* `orderBys` - *List of <>* - List of fields (and directions) to control the sorting of query results. In general, multiple *orderBys* can be given (depending on backend implementations). * `booleanOperator` - *Enum of AND, OR, default: AND* - Specifies the logical joining operator used among individual criteria. * `subFilters` - *List of QQueryFilter* - To build arbitrarily complex queries, with nested boolean logic, 0 or more *subFilters* may be provided. @@ -69,7 +83,7 @@ In general, multiple *orderBys* can be given (depending on backend implementatio ))); // which would generate the following WHERE clause in an RDBMS backend: - WHERE (first_name='James' AND last_name='Maes') OR (first_name='Darin' AND last_name='Kelkhoff') +// WHERE (first_name='James' AND last_name='Maes') OR (first_name='Darin' AND last_name='Kelkhoff') ---- ===== QFilterCriteria @@ -79,19 +93,19 @@ In general, multiple *orderBys* can be given (depending on backend implementatio * `operator` - *Enum of QCriteriaOperator, required* - Comparison operation to be applied to the field specified as *fieldName* and the *values* or *otherFieldName*. ** e.g., `EQUALS`, `NOT_IN`, `GREATER_THAN`, `BETWEEN`, `IS_BLANK`, etc. * `values` - *List of values, conditional* - Provides the value(s) that the field is compared against. -The number of values (0, 1, 2, or more) be driven based on the *operator* being used. +The number of values (0, 1, 2, or more) required are based on the *operator* being used. If an *otherFieldName* is given, and the *operator* expects 1 value, then *values* is ignored, and *otherFieldName* is used. * `otherFieldName` - *String, conditional* - Specifies that the *fieldName* should be compared against another field in the records, rather than the values in the *values* property. Only used for *operators* that expect 1 value (e.g., `EQUALS` or `LESS_THAN_OR_EQUALS` - not `IS_NOT_BLANK` or `IN`). -QFilterCriteria definition examples: [source,java] +.QFilterCriteria definition examples: ---- -// one-liners, via constructors that take (List values) or (Serializable... values) in 3rd position -new QFilterCriteria("id", IN, List.of(1, 2, 3)) +// in-line, via constructors that take (List values) or (Serializable... values) as 3rd arg +new QFilterCriteria("id", IN, 1, 2, 3) new QFilterCriteria("name", IS_BLANK) new QFilterCriteria("orderNo", IN, orderNoList) -new QFilterCriteria("state", EQUALS, "MO"); +new QFilterCriteria("state", EQUALS, "MO") // long-form, with fluent setters new QFilterCriteria() @@ -105,7 +119,7 @@ new QFilterCriteria() .withOpeartor(QCriteriaOperator.EQUALS) .withOtherFieldName("lastName"); -// using otherFieldName to build a criterion that looks at two fields from join tables +// using otherFieldName to build a criterion that looks at two fields from two different join tables new QFilterCriteria() .withFieldName("billToCustomer.lastName") .withOpeartor(QCriteriaOperator.NOT_EQUALS) @@ -118,9 +132,9 @@ new QFilterCriteria() ** Or, in the case of a query with *queryJoins*, a qualified name of a field from a join-table (where the qualifier would be the joined table's name or alias, followed by a dot) * `isAscending` - *boolean, default: true* - Specify if the sort is ascending or descending. -QFilterCriteria definition examples: [source,java] +.QFilterOrderBy definition examples: ---- // short-form, via constructors new QFilterOrderBy("id") // isAscending defaults to true. @@ -129,7 +143,7 @@ new QFilterOrderBy("name", false) // long-form, with fluent setters new QFilterOrderBy() .withFieldName("birthDate") - .withIsAscending(true); + .withIsAscending(false); ---- ==== QueryJoin @@ -147,9 +161,8 @@ If given, must be used as the part before the dot in field name specifications t If *true*, then the `QRecord` objects returned by this query will have values with corresponding to the (table-or-alias `.` field-name) form. * `type` - *Enum of INNER, LEFT, RIGHT, FULL, default: INNER* - specifies the SQL-style type of join being performed. -QueryJoin definition examples: - [source,java] +.QueryJoin definition examples: ---- // selecting from an "orderLine" table - then join to its corresponding "order" table queryInput.withTableName("orderLine"); diff --git a/docs/docinfo.html b/docs/docinfo.html index f3e5ce05..495a77eb 100644 --- a/docs/docinfo.html +++ b/docs/docinfo.html @@ -1,27 +1,6 @@ - - \ No newline at end of file diff --git a/docs/implementations/TableSync.adoc b/docs/implementations/TableSync.adoc new file mode 100644 index 00000000..5119dae1 --- /dev/null +++ b/docs/implementations/TableSync.adoc @@ -0,0 +1,406 @@ +== TableSyncProcess +include::../variables.adoc[] + +The `TableSyncProcess` is designed to help solve the common use-case where you have a set of records in one table, +you want to apply a transformation to them, and then you want them to result in records in a different table. + +=== Sample Scenario +For example, you may be receiving an import file feed from a partner - say, a CSV file of order records +- that you need to synchronize into your local database's orders table. + +=== High Level Steps +At a high-level, the steps of this task are: + +1. Get the records from the partner's feed. +2. Decide Insert/Update - e.g., if you already have any of these orders in your database table, in which case, they need updated, versus ones +you don't have, which need inserted. +3. Map fields from the partner's order record to your own fields. +4. Store the necessary records in your database (insert or update). + +=== What you need to tell QQQ +`TableSyncProcess`, as defined by QQQ, knows how to do everything for a job like this, other than the part that's unique to your business. +Those unique parts that you need to tell QQQ are: + +* What are the source & destination tables? +* What are the criteria to identify source records to be processed? +* What are the key fields are that "link" together records from the source & destination tables? +** For the example above, imagine you have a "partnerOrderNo" field in your database's order table - then you'd need +to tell QQQ what field in the partner's table provides the value for that field in your table. +* How do fields / values from the source table map to fields & values in the destination table? + +=== Detailed Steps +To get more specific, in a QQQ `TableSyncProcess`, here's what happens for each of the high-level steps given above: + +* Getting records from the partner's feed (done by QQQ): +** Records from the source will be fetched via an Extract step, which runs a query to find the records that need processing. +** Depending on your use-case, you may use an `ExtractViaQueryStep` (maybe with a Table Automation) or `ExtractViaBasepullQueryStep` +(e.g., if you are polling a remote data source). +* Deciding Insert/Update (done by QQQ): +** Given a set of records from the source table (e.g., output of the Extract step mentioned above), get values from the "key" field in that table. +** Do a lookup in the destination table, where its corresponding "key" field has the values extracted from the source records. +** For each source record, if its "key" was found in the destination table, then plan an update to that existing corresponding +destination record; else, plan to insert a new record in the destination table. +* Mapping values (done by your custom Application code): +** Specifically, mapping is done in a subclass of `AbstractTableSyncTransformStep`, in the `populateRecordToStore` method. +Of particular interest are these two parameters to that method: +*** `QRecord destinationRecord` - as determined by the insert/update logic above, this will either be a +new empty record (e.g., for inserting), or a fully populated record from the destination table (for updating). +*** `QRecord sourceRecord` - this is the record being processed, from the source table. +** This method is responsible for setting values in the `destinationRecord`, and returning that record +(unless it has decided that for some reason the record should _not_ be stored, in which case it may return `null`). +* Storing the records (done by QQQ): +** This is typically done with the `LoadViaInsertOrUpdateStep`, though it is customizable if additional work is needed (e.g., via a +subclass of `LoadViaInsertOrUpdateStep`, or a more custom subclass of `AbstractLoadStep`). + +=== Bare-bones Example +For this example, let's assume we're setting up a partner-order-feed as described above, with the following details: + +* We have records from a partner in a table named `"partnerOrderImport"` (let's assume the records may have been created +using the QQQ `FilesystemImporter` process). +These records have the following fields: +** `orderNo, date, city, state, postal, whseNo` +* We need to synchronize those records with table in our database named `"order"`, with the following fields corresponding to those from the partner: +** `partnerOrderNo, orderDate, shipToCity, shipToState, shipToZipCode, warehouseId` +* The same conceptual order may appear in the `"partnerOrderImport"` multiple times, e.g., if they update some data on the order and re-transmit it to us. +Meaning, we need to update our `"order"` records when we receive a new version an existing order. + +To use `*TableSyncProcess*` for solving this use-case, we'll need to create 2 things: + +1. A `QProcessMetaData` object, which we can create using the builder object provided by class `TableSyncProcess`. +Note that this type of process is specialization of the standard QQQ `StreamedETLWithFrontendProcess`, as described elsewhere in this documentation. +2. A subclass of `AbstractTableSyncTransformStep`, where we implement our mapping logic. +Again, note that `AbstractTableSyncTransformStep` is a subclass of `AbstractTransformStep`, as used by `StreamedETLWithFrontendProcess`. + +And to be good programmers, we'll actually create a 3rd thing: + +[start=3] +. A unit test for our Transform step. + +Here are examples of these pieces of code: + +[source,java] +.Example of building process using the TableSyncProcess builder: +---- +// the false argument below tells the build we are not a basepull-style process +QProcessMetaData processMetaData = TableSyncProcess.processMetaDataBuilder(false) + + // give our process a unique name within our QInstance + .withName("partnerOrderToLocalOrderProcess") + + // tell the process to what class to use for transforming records from source to destination + .withSyncTransformStepClass(PartnerOrderToOrderTransformStep.class) + + .getProcessMetaData(); +---- + +[source,java] +.Example implementation of an AbstractTableSyncTransformStep +---- +public class PartnerOrderToOrderTransformStep extends AbstractTableSyncTransformStep +{ + @Override + protected SyncProcessConfig getSyncProcessConfig() + { + return (new SyncProcessConfig( + "partnerOrderImport", // source tableName + "orderNo", // source table key fieldName + "order", // destination tableName + "partnerOrderNo" // destination table foreign key fieldName + )); + } + + @Override + public QRecord populateRecordToStore(RunBackendStepInput runBackendStepInput, QRecord destinationRecord, QRecord sourceRecord) throws QException + { + // map simple values from source table to destination table + destinationRecord.setValue("orderDate", sourceRecord.get("date")); + destinationRecord.setValue("shipToAddressCity", sourceRecord.get("city")); + destinationRecord.setValue("shipToAddressState", sourceRecord.get("state")); + destinationRecord.setValue("shipToAddressZipCode", sourceRecord.get("postal")); + return (destinationRecord); + } + +} +---- + +[source,java] +.Example Unit Test for a transform step +---- + @Test + void testTransformStep() + { + // insert 1 test order, that will be updated by the transform step + Integer existingId = new InsertAction().execute(new InsertInput("order").withRecords(List.of( + new QRecord().withValue("partnerOrderNo", 101).withValue("shipToState", "IL") + ))).getRecords().get(0).getValueInteger("id"); + + // set up input for the step - a list of 2 of the partner's orders + RunBackendStepInput input = new RunBackendStepInput(); + input.setRecords(List.of( + new QRecord().withValue("orderNo", 101).withValue("state", "NY"), // will update the order above + new QRecord().withValue("orderNo", 102).withValue("state", "CA") // will insert a new order + )); + RunBackendStepOutput output = new RunBackendStepOutput(); + + // run the code under test - our transform step + new PartnerOrderToOrderTransformStep().run(input, output); + + // Note that by just running the transform step, no records have been stored. + // We can assert against the output of this step. + + assertEquals(existingId, output.getRecords().get(0).getValue("id")); + assertEquals(101, output.getRecords().get(0).getValue("partnerOrderNo")); + assertEquals("NY", output.getRecords().get(0).getValue("shipToState")); + + assertNull(output.getRecords().get(1).getValue("id")); + assertEquals(102, output.getRecords().get(1).getValue("partnerOrderNo")); + assertEquals("CA", output.getRecords().get(1).getValue("shipToState")); + } + + @Test + void testFullProcess() + { + // todo! :) + } +---- + +=== Pseudocode process flow +Now that we've seen the bare-bones example, let's see an even more detailed breakdown of how a full `TableSyncProcess` works, +by looking at its 3 "ETL" steps in pseudocode: + +==== ExtractStep (Producer Thread) + +* Queries source table for records +** Often based on Table Automations (e.g., for all newly inserted records) or Basepull pattern (polling for new/updated records). + +==== TransformStep (Consumer Thread) + +* Receives pages of records from `ExtractStep` in the `run` method. +* Makes `sourceKeyList` by getting `sourceTableKeyField` values from the records. +* Calls `initializeRecordLookupHelper(runBackendStepInput, sourceRecordList)` +** Calls `getLookupsToPreLoad` to control which lookups are performed. +* Calls `getExistingRecordsByForeignKey(runBackendStepInput, destinationTableForeignKeyField, destinationTableName, sourceKeyList);` +** Calls `getExistingRecordQueryFilter(runBackendStepInput, sourceKeyList)` as part of querying the `destinationTable` +** Returns the output of `buildExistingRecordsMap(destinationTableForeignKeyField, queryOutput.getRecords())` +* foreach input record (from `sourceTable`): +** Calls `getExistingRecord(existingRecordsByForeignKey, destinationForeignKeyField, sourceKeyValue)` +** if an existing record was returned (and if the syncConfig says `performUpdates`), this record is set as `recordToStore` +** else if no existing record was returned (and if the syncConfig says `performInserts`), a new record is set as `recordToStore` +** else continue the foreach. +** call `populateRecordToStore(runBackendStepInput, recordToStore, sourceRecord)` +** if a record is returned it is added to the process step output (to be stored in the LoadStep) + +==== LoadStep (Consumer Thread) + +* Receives records from the output of the `TransformStep`. +* Inserts and/or Updates `destinationTable`, with records returned by `populateRecordToStore` + +=== Additional Process Configuration Examples +The following examples show how to use additional settings in the `TableSyncProcess` builder. + +==== UI +While a `TableSyncProcess` will often run via a schedule and/or automation, we may also want to allow users +to manually run it in a UI. + +[source,java] +.Making our process available for a UI +---- +QProcessMetaData processMetaData = TableSyncProcess.processMetaDataBuilder(true) + .withName("partnerOrderToLocalOrderProcess") + .withSyncTransformStepClass(PartnerOrderToOrderTransformStep.class) + + // attach our process to its source table, to show up in UI + .withTableName("partnerOrderImport") + + // add some fields to display on the review screen, in UI + .withReviewStepRecordFields(List.of( + new QFieldMetaData("clientId", QFieldType.STRING).withLabel("Client"), + new QFieldMetaData("warehouseId", QFieldType.STRING).withLabel("Warehouse"), + new QFieldMetaData("partnerOrderNo", QFieldType.STRING))) + .getProcessMetaData(); +---- + +==== Basepull +The previous example would work as a Table Automation (e.g., where the list of records identified in the +Extract step were determined by the Automation system). +However, a second common pattern is to use `Basepull` (e.g., if polling for updated records from a partner API endpoint). + +[source,java] +.Configuring our process as a Basepull +---- +// the true argument below tells the build we ARE a basepull-style process +// this changes the default extract-step. +QProcessMetaData processMetaData = TableSyncProcess.processMetaDataBuilder(false) + .withName("partnerOrderToLocalOrderProcess") + .withSyncTransformStepClass(PartnerOrderToOrderTransformStep.class) + + // See Basepull documentation for details + .withBasepullConfiguration(new BasepullConfiguration()) + + // schedule our process to run automatically every minute + .withSchedule(new QScheduleMetaData().withRepeatSeconds(60)) + + .getProcessMetaData(); +---- + +=== Additional Options in the Transform Step + +==== Specifying to not perform Inserts or not perform Updates +We may have a scenario where we want our sync process to never update records if the key is already found in the destination table. +We can configure this with an additional optional parameter to the `SyncProcessConfig` constructor: + +[source,java] +.Specifying to not do updates in a TableSyncProcess +---- + @Override + protected SyncProcessConfig getSyncProcessConfig() + { + return (new SyncProcessConfig("partnerOrderImport", "orderNo", "order", "partnerOrderNo", + true, // performInserts + false // performUpdates + )); + } +---- + +Similarly, we may want to disallow inserts from a particular sync process. +The `performInserts` argument to the `SyncProcessConfig` constructor lets us do that: + +[source,java] +.Specifying to not do inserts in a TableSyncProcess +---- + @Override + protected SyncProcessConfig getSyncProcessConfig() + { + return (new SyncProcessConfig("partnerOrderImport", "orderNo", "order", "partnerOrderNo", + false, // performInserts + true // performUpdates + )); + } +---- + +==== Customizing the query for existing records + +In some cases, a specific Table Sync process may need to refine the query filter that is used +to lookup existing records in the destination table (e.g. for determining insert vs. update). + +For example, in our orders-from-a-partner scenario, if we have more than 1 partner sending us orders, +where there could be overlapping orderNo values among them - we may have an additional field in our +orders table to identify which partner an order came from. +So then when we're looking up orders by `partnerOrderNo`, we would need to also include the `partnerId` field +in our query, so that we only update orders from the specific partner that we're dealing with. + +To do this (to customize the existing record query filter), we need can just override the method `getExistingRecordQueryFilter`. +Generally we would start by calling the `super` version of the method, and then add to it additional criteria. + +[source,java] +.Customizing the query filter used to look for existing records +---- + /******************************************************************************* + ** Define the query filter to find existing records. e.g., for determining + ** insert vs. update. Subclasses may override this to customize the behavior, + ** e.g., in case an additional field is needed in the query. + *******************************************************************************/ + protected QQueryFilter getExistingRecordQueryFilter(RunBackendStepInput runBackendStepInput, List sourceKeyList) + { + QQueryFilter filter = super.getExistingRecordQueryFilter(runBackendStepInput, sourceKeyList); + filter.addCriteria(new QFilterCriteria("partnerId", EQUALS, PARTNER_ID)); + return (filter); + } +---- + +==== More efficient additional record lookups + +It is a common use-case to need to map various ids from a partner's system to ids in your own system. +For the orders example, we might need to know what warehouse the order is shipping from. +The customer may send their identifier for the warehouse, and we may need to map those identifiers to our own warehouse ids. + +The QQQ-provided class `RecordLookupHelper` exists to help with performing lookups like this, +and in particular, it can be used to execute one query to fetch a full table, storing records +by a key field, then returning those records without performing additional queries. + +`AbstractTableSyncTransformStep` has a protected `recordLookupHelper` member. +If we override the method `getLookupsToPreLoad()`, then this object is +populated by calling its `preloadRecords` method with each specified pair of tableNames and fieldNames. + +[source,java] +.Specifying tables to pre-load using a RecordLookupHelper +---- + /******************************************************************************* + ** Specify a list of tableName/keyColumnName pairs to run through + ** the preloadRecords method of the recordLookupHelper. + *******************************************************************************/ + @Override + protected List> getLookupsToPreLoad() + { + return (List.of( + Pair.of("warehouse", "partnerWarehouseNo") + )); + } +---- + +If we have preloaded some lookups, we can then use them in our `populateRecordToStore` method as follows: +[source,java] +.Using the recordLookupHelper in populateRecordToStore +---- + // lookup warehouse with partnerWarehouseNo=whseNo from partner, and use our id in destination record + String partnerWarehouseNo = sourceRecord.getValue("whseNo"); + Integer warehouseId = recordLookupHelper.getRecordId("warehouse", "partnerWarehouseNo", whseNo, Integer.class); + destinationRecord.setValue("warehouseId", warehouseId); +---- + +==== Additional override points + +There are more methods which can be overridden in your `AbstractTableSyncTransformStep` subclass, +to provide further customizations of behaviors, specifically in the area of dealing with existing +records (e.g., the insert/update use-case). +[source,java] +.Additional AbstractTableSyncTransformStep overrides +---- + + /******************************************************************************* + ** Run the existingRecordQueryFilter - to look in the destinationTable for + ** any records that may need an update (rather than an insert). + ** + ** Generally returns a Map, keyed by a Pair of the destinationTableForeignKeyField + ** and the value in that field. But, for more complex use-cases, one can override + ** the buildExistingRecordsMap method, to make different keys (e.g., if there are + ** two possible destinationTableForeignKeyFields). + *******************************************************************************/ + protected Map, QRecord> getExistingRecordsByForeignKey + ( + RunBackendStepInput runBackendStepInput, + String destinationTableForeignKeyField, + String destinationTableName, + List sourceKeyList + ) throws QException; + + + /******************************************************************************* + ** Overridable point where you can, for example, keys in the existingRecordsMap + ** with different fieldNames from the destinationTable. + ** + ** Note, if you're overriding this method, you'll likely also want & need to + ** override getExistingRecord. + *******************************************************************************/ + protected Map, QRecord> buildExistingRecordsMap + ( + String destinationTableForeignKeyField, + List existingRecordList + ); + + /******************************************************************************* + ** Given the map of existingRecordsByForeignKey (as built by + ** getExistingRecordsByForeignKey which calls buildExistingRecordsMap), + ** get one record from that map, for a given key-value from a source record. + ** + ** The destinationForeignKeyField is given as advice if needed (e.g., to see its type) + *******************************************************************************/ + protected QRecord getExistingRecord + ( + Map, QRecord> existingRecordsByForeignKey, + QFieldMetaData destinationForeignKeyField, + Serializable sourceKeyValue + ); + +---- + diff --git a/docs/index.adoc b/docs/index.adoc index 02d2e9a0..1ab41a32 100644 --- a/docs/index.adoc +++ b/docs/index.adoc @@ -1,17 +1,66 @@ = QQQ -:doctype: book +:doctype: article :toc: left +:toclevels: 2 :source-highlighter: coderay include::Introduction.adoc[leveloffset=+1] == Meta Data -include::metaData/Tables.adoc[leveloffset=+1] -'''' -include::metaData/Reports.adoc[leveloffset=+1] +// Organizational units +include::metaData/QInstance.adoc[leveloffset=+1] +include::metaData/Backends.adoc[leveloffset=+1] +include::metaData/Apps.adoc[leveloffset=+1] -== Actions +// Primary meta-data types +include::metaData/Tables.adoc[leveloffset=+1] +include::metaData/Processes.adoc[leveloffset=+1] +include::metaData/Widgets.adoc[leveloffset=+1] + +// Helper meta-data types +include::metaData/Fields.adoc[leveloffset=+1] +include::metaData/PossibleValueSources.adoc[leveloffset=+1] +include::metaData/Joins.adoc[leveloffset=+1] +include::metaData/SecurtiyKeyTypes.adoc[leveloffset=+1] +include::metaData/Reports.adoc[leveloffset=+1] +include::metaData/Icons.adoc[leveloffset=+1] +include::metaData/PermissionRules.adoc[leveloffset=+1] + +== Custom Application Code +include::misc/QContext.adoc[leveloffset=+1] +include::misc/QRecords.adoc[leveloffset=+1] +include::misc/QRecordEntities.adoc[leveloffset=+1] +include::misc/ProcessBackendSteps.adoc[leveloffset=+1] +include::misc/RenderingWidgets.adoc[leveloffset=+1] + +=== Table Customizers +#todo# + +== QQQ Core Actions include::actions/QueryAction.adoc[leveloffset=+1] -'''' -include::actions/RenderTemplateAction.adoc[leveloffset=+1] -'''' + +include::actions/GetAction.adoc[leveloffset=+1] + +=== CountAction +#todo# + +=== AggregateAction +#todo# + +include::actions/InsertAction.adoc[leveloffset=+1] + +=== UpdateAction +#todo# + +=== DeleteAction +#todo# + +=== AuditAction +#todo# + +== QQQ Default Implementations +include::implementations/TableSync.adoc[leveloffset=+1] +// later... include::actions/RenderTemplateAction.adoc[leveloffset=+1] + +== QQQ Utility Classes +include::utilities/RecordLookupHelper.adoc[leveloffset=+1] \ No newline at end of file diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 96c586e3..00000000 --- a/docs/index.html +++ /dev/null @@ -1,1396 +0,0 @@ - - - - - - - -QQQ - - - - - - - - - -
-
-

Introduction

-
-
-

QQQ is …​

-
-
-
    -
  • -

    Framework

    -
  • -
  • -

    Declarative

    -
  • -
  • -

    Easy thing easy; Hard thing possible

    -
  • -
  • -

    Customizable

    -
  • -
-
-
-
-
-

Meta Data

-
-
-

QQQ Tables

-
-

The core type of object in a QQQ Instance is the Table. -In the most common use-case, a QQQ Table may be the in-app representation of a Database table. -That is, it is a collection of records (or rows) of data, each of which has a set of fields (or columns).

-
-
-

QQQ also allows other types of data sources (QQQ Backends) to be used as tables, such as File systems, API’s, Java enums or objects, etc. -All of these backend types present the same interfaces (both user-interfaces, and application programming interfaces), regardless of their backend type.

-
-
-

QTableMetaData

-
-

Tables are defined in a QQQ Instance in a QTableMetaData object. -All tables must reference a QQQ Backend, a list of fields that define the shape of records in the table, and additional data to describe how to work with the table within its backend.

-
-
-

QTableMetaData Properties:

-
-
-
    -
  • -

    name - String, Required - Unique name for the table within the QQQ Instance.

    -
  • -
  • -

    label - String - User-facing label for the table, presented in User Interfaces. -Inferred from name if not set.

    -
  • -
  • -

    backendName - String, Required - Name of a QQQ Backend in which this table’s data is managed.

    -
  • -
  • -

    fields - Map of String → QQQ Field, Required - The columns of data that make up all records in this table.

    -
  • -
  • -

    primaryKeyField - String, Conditional - Name of a QQQ Field that serves as the primary key (e.g., unique identifier) for records in this table.

    -
  • -
  • -

    uniqueKeys - List of UniqueKey - Definition of additional unique constraints (from an RDBMS point of view) from the table. -e.g., sets of columns which must have unique values for each record in the table.

    -
  • -
  • -

    backendDetails - QTableBackendDetails or subclass - Additional data to configure the table within its QQQ Backend.

    -
  • -
  • -

    automationDetails - QTableAutomationDetails - Configuration of automated jobs that run against records in the table, e.g., upon insert or update.

    -
  • -
  • -

    customizers - Map of String → QCodeReference - References to custom code that are injected into standard table actions, that allow applications to customize certain parts of how the table works.

    -
  • -
  • -

    parentAppName - String - Name of a QQQ App that this table exists within.

    -
  • -
  • -

    icon - QIcon - Icon associated with this table in certain user interfaces.

    -
  • -
  • -

    recordLabelFormat - String - Java Format String, used with recordLabelFields to produce a label shown for records from the table.

    -
  • -
  • -

    recordLabelFields - List of String, Conditional - Used with recordLabelFormat to provide values for any format specifiers in the format string. -These strings must be field names within the table.

    -
    -
      -
    • -

      Example of using recordLabelFormat and recordLabelFields:

      -
    • -
    -
    -
  • -
-
-
-
-
// given these fields in the table:
-new QFieldMetaData("name", QFieldType.STRING)
-new QFieldMetaData("birthDate", QFieldType.DATE)
-
-// We can produce a record label such as "Darin Kelkhoff (1980-05-31)" via:
-.withRecordLabelFormat("%s (%s)")
-.withRecordLabelFields(List.of("name", "birthDate"))
-
-
-
-
    -
  • -

    sections - List of QFieldSection - Mechanism to organize fields within user interfaces, into logical sections. -If any sections are present in the table meta data, then all fields in the table must be listed in exactly 1 section. -If no sections are defined, then instance enrichment will define default sections.

    -
  • -
  • -

    associatedScripts - List of AssociatedScript - Definition of user-defined scripts that can be associated with records within the table.

    -
  • -
  • -

    enabledCapabilities and disabledCapabilities - Set of Capability enum values - Overrides from the backend level, for capabilities that this table does or does not possess.

    -
  • -
-
-
-
-
-
-

QQQ Reports

-
-

QQQ can generate reports based on QQQ Tables defined within a QQQ Instance. -Users can run reports, providing input values. -Alternatively, application code can run reports as needed, supplying input values.

-
-
-

QReportMetaData

-
-

Reports are defined in a QQQ Instance with a QReportMetaData object. -Reports are defined in terms of their sources of data (QReportDataSource), and their view(s) of that data (QReportView).

-
-
-

QReportMetaData Properties:

-
-
-
    -
  • -

    name - String, Required - Unique name for the report within the QQQ Instance.

    -
  • -
  • -

    label - String - User-facing label for the report, presented in User Interfaces. -Inferred from name if not set.

    -
  • -
  • -

    processName - String - Name of a QQQ Process used to run the report in a User Interface.

    -
  • -
  • -

    inputFields - List of QQQ Field - Optional list of fields used as input to the report.

    -
    -
      -
    • -

      The values in these fields can be used via the syntax ${input.NAME}, where NAME is the name attribute of the inputField.

      -
    • -
    • -

      For example:

      -
    • -
    -
    -
  • -
-
-
-
-
// given this inputField:
-new QFieldMetaData("storeId", QFieldType.INTEGER)
-
-// its run-time value can be accessed, e.g., in a query filter under a data source:
-new QFilterCriteria("storeId", QCriteriaOperator.EQUALS, List.of("${input.storeId}"))
-
-// or in a report view's title or field formulas:
-.withTitleFields(List.of("${input.storeId}"))
-new QReportField().withName("storeId").withFormula("${input.storeId}")
-
-
-
-
    -
  • -

    dataSources - List of QReportDataSource, Required - Definitions of the sources of data for the report. -At least one is required.

    -
  • -
-
-
-
QReportDataSource
-
-

Data sources for QQQ Reports can either reference QQQ Tables within the QQQ Instance, or they can provide custom code in the form of a CodeReference to a Supplier, for use cases such as a static data tab in an Excel report.

-
-
-

QReportDataSource Properties:

-
-
-
    -
  • -

    name - String, Required - Unique name for the data source within its containing Report.

    -
  • -
  • -

    sourceTable - String, Conditional - Reference to a QQQ Table in the QQQ Instance, which the data source queries data from.

    -
  • -
  • -

    queryFilter - QQueryFilter - If a sourceTable is defined, then the filter specified here is used to filter and sort the records queried from that table when generating the report.

    -
  • -
  • -

    staticDataSupplier - QCodeReference, Conditional - Reference to custom code which can be used to supply the data for the data source, as an alternative to querying a sourceTable.

    -
    -
      -
    • -

      Must be a JAVA code type

      -
    • -
    • -

      Must be a REPORT_STATIC_DATA_SUPPLIER code usage.

      -
    • -
    • -

      The referenced class must implement the interface: Supplier<List<List<Serializable>>>.

      -
    • -
    -
    -
  • -
-
-
-
-
QReportView
-
-

Report Views control how the source data for a report is organized and presented to the user in the output report file. -If a DataSource describes the rows for a report (e.g., what table provides what records), then a View may be thought of as describing the columns in the report. -A single report can have multiple views, specifically, for the use-case where an Excel file is being generated, in which case each View creates a tab or sheet within the xlsx file.

-
-
-

QReportView Properties:

-
-
-
    -
  • -

    name - String, Required - Unique name for the view within its containing Report.

    -
  • -
  • -

    label - String - Used as a sheet (tab) label in Excel formatted reports.

    -
  • -
  • -

    type - enum of TABLE, SUMMARY, PIVOT. Required - Defines the type of view being defined.

    -
    -
      -
    • -

      TABLE views are a simple listing of the records from the data source.

      -
    • -
    • -

      SUMMARY views are essentially pre-computed Pivot Tables. -That is to say, the aggregation done by a Pivot Table in a spreadsheet file is done by QQQ while generating the report. -In this way, a non-spreadsheet report (e.g., PDF or CSV) can have summarized data, as though it were a Pivot Table in a live spreadsheet.

      -
    • -
    • -

      PIVOT views produce actual Pivot Tables, and are only supported in Excel files (and are not supported at the time of this writing).

      -
    • -
    -
    -
  • -
  • -

    dataSourceName - String, Required - Reference to a DataSource within the report, that is used to provide the rows for the view.

    -
  • -
  • -

    varianceDataSourceName - String - Optional reference to a second DataSource within the report, that is used in SUMMARY type views for computing variances.

    -
    -
      -
    • -

      For example, given a Data Source with a filter that selects all sales records for a given year, a Variance Data Source may have a filter that selects the previous year, for doing comparissons.

      -
    • -
    -
    -
  • -
  • -

    pivotFields - List of String, Conditional - For SUMMARY or PIVOT type views, specify the field(s) used as pivot rows.

    -
    -
      -
    • -

      For example, in a summary view of orders, you may "pivot" on the customerId field, to produce one row per-customer, with aggregate data for that customer.

      -
    • -
    -
    -
  • -
  • -

    titleFormat - String - Java Format String, used with titleFields (if given), to produce a title row, e.g., first row in the view (before any rows from the data source).

    -
  • -
  • -

    titleFields - List of String, Conditional - Used with titleFormat, to provide values for any format specifiers in the format string. -Syntax to reference a field (e.g., from a report input field) is: ${input.NAME}, where NAME is the name attribute of the inputField.

    -
    -
      -
    • -

      Example of using titleFormat and titleFields:

      -
    • -
    -
    -
  • -
-
-
-
-
// given these inputFields:
-new QFieldMetaData("startDate", QFieldType.DATE)
-new QFieldMetaData("endDate", QFieldType.DATE)
-
-// a view can have a title row like this:
-.withTitleFormat("Weekly Sales Report - %s - %s")
-.withTitleFields(List.of("${input.startDate}", "${input.endDate}"))
-
-
-
-
    -
  • -

    includeHeaderRow - boolean, default true - Indication that first row of the view should be the column labels.

    -
    -
      -
    • -

      If true, then header row is put in the view.

      -
    • -
    • -

      If false, then no header row is put in the view.

      -
    • -
    -
    -
  • -
  • -

    includeTotalRow - boolean, default false - Indication that a totals row should be added to the view. -All numeric columns are summed to produce values in the totals row.

    -
    -
      -
    • -

      If true, then totals row is put in the view.

      -
    • -
    • -

      If false, then no totals row is put in the view.

      -
    • -
    -
    -
  • -
  • -

    includePivotSubTotals - boolean, default false - For a SUMMARY or PIVOT type view, if there are more than 1 pivotFields being used, this field is an indication that each higher-level pivot should include sub-totals.

    -
    -
      -
    • -

      TODO - provide example

      -
    • -
    -
    -
  • -
  • -

    columns - List of QReportField, required - Definition of the columns to appear in the view. See section on QReportField for details.

    -
  • -
  • -

    orderByFields - List of QFilterOrderBy, optional - For a SUMMARY or PIVOT type view, how to sort the rows.

    -
  • -
  • -

    recordTransformStep - QCodeReference, subclass of AbstractTransformStep - Custom code reference that can be used to transform records after they are queried from the data source, and before they are placed into the view. -Can be used to transform or customize values, or to look up additional values to add to the report.

    -
    -
      -
    • -

      TODO - provide example

      -
    • -
    -
    -
  • -
  • -

    viewCustomizer - QCodeReference, implementation of interface Function<QReportView, QReportView> - Custom code reference that can be used to customize the report view, at runtime. -Can be used, for example, to dynamically define the report’s columns.

    -
    -
      -
    • -

      TODO - provide example

      -
    • -
    -
    -
  • -
-
-
-
QReportField
- -
-
-
-
-
-
-
-

Actions

-
-
-

QueryAction

-
-

The QueryAction is the basic action that is used to get records from a QQQ Table. -In SQL/RDBMS terms, it is analogous to a SELECT statement, where 0 or more records may be found and returned.

-
-
-

Examples

-
-
Simplest Form
-
-
-
QueryInput input = new QueryInput(qInstance);
-input.setSession(session);
-input.setTableName("orders");
-input.setFilter(new QQueryFilter(new QFilterCriteria("total", GREATER_THAN, new BigDecimal("3.50"))));
-QueryOutput output = new QueryAction.execute(input);
-List<QRecord> records = output.getRecords();
-
-
-
-
-
-

QueryInput

-
-
    -
  • -

    table - String, Required - Name of the table being queried against.

    -
  • -
  • -

    filter - QQueryFilter object - Specification for what records should be returned, based on QFilterCriteria objects, and how they should be sorted, based on QFilterOrderBy objects.

    -
  • -
  • -

    skip - Integer - Optional number of records to be skipped at the beginning of the result set. -e.g., for implementing pagination.

    -
  • -
  • -

    limit - Integer - Optional maximum number of records to be returned by the query.

    -
  • -
  • -

    transaction - QBackendTransaction object - Optional transaction object.

    -
    -
      -
    • -

      Behavior for this object is backend-dependant. -In an RDBMS backend, this object is generally needed if you want your query to see data that may have been modified within the same transaction.

      -
    • -
    -
    -
  • -
  • -

    recordPipe - RecordPipe object - Optional object that records are placed into, for asynchronous processing.

    -
    -
      -
    • -

      If a recordPipe is used, then records cannot be retrieved from the QueryOutput. -Rather, such records must be read from the pipe’s consumeAvailableRecords() method.

      -
    • -
    • -

      A recordPipe should only be used when a QueryAction is running in a separate Thread from the record’s consumer.

      -
    • -
    -
    -
  • -
  • -

    shouldTranslatePossibleValues - boolean, default: false - Controls whether any fields in the table with a possibleValueSource assigned to them should have those possible values looked up -(e.g., to provide text translations in the generated records' displayValues map).

    -
    -
      -
    • -

      For example, if running a query to present results to a user, this would generally need to be true. -But if running a query to provide data as part of a process, then this can generally be left as false.

      -
    • -
    -
    -
  • -
  • -

    shouldGenerateDisplayValues - boolean, default: false - Controls whether if field level displayFormats should be used to populate the generated records' displayValues map.

    -
    -
      -
    • -

      For example, if running a query to present results to a user, this would generally need to be true. -But if running a query to provide data as part of a process, then this can generally be left as false.

      -
    • -
    -
    -
  • -
  • -

    queryJoins - List of QueryJoin objects - Optional list of tables to be joined with the main table specified in the QueryInput. -See QueryJoin below for further details.

    -
  • -
-
-
-
QQueryFilter
-
-

A key component of QueryInput, a QQueryFilter defines both what records should be included in a query’s results (e.g., an SQL WHERE), as well as how those results should be sorted (SQL ORDER BY).

-
-
-
    -
  • -

    criteria - List of QFilterCriteria - Individual conditions or clauses to filter records. -They are combined using the booleanOperator specified in the QQueryFilter. See below for further details.

    -
  • -
  • -

    orderBys - List of QFilterOrderBy - List of fields (and directions) to control the sorting of query results. -In general, multiple orderBys can be given (depending on backend implementations).

    -
  • -
  • -

    booleanOperator - Enum of AND, OR, default: AND - Specifies the logical joining operator used among individual criteria.

    -
  • -
  • -

    subFilters - List of QQueryFilter - To build arbitrarily complex queries, with nested boolean logic, 0 or more subFilters may be provided.

    -
    -
      -
    • -

      Each subFilter can include its own additional subFilters.

      -
    • -
    • -

      Each subFilter can specify a different booleanOperator.

      -
    • -
    • -

      For example, consider the following QQueryFilter, that uses two subFilters, and a mix of booleanOperators

      -
    • -
    -
    -
  • -
-
-
-
-
 queryInput.setFilter(new QQueryFilter()
-    .withBooleanOperator(OR)
-    .withSubFilters(List.of(
-       new QQueryFilter().withBooleanOperator(AND)
-          .withCriteria(new QFilterCriteria("firstName", EQUALS, "James"))
-          .withCriteria(new QFilterCriteria("lastName", EQUALS, "Maes")),
-       new QQueryFilter().withBooleanOperator(AND)
-          .withCriteria(new QFilterCriteria("firstName", EQUALS, "Darin"))
-          .withCriteria(new QFilterCriteria("lastName", EQUALS, "Kelkhoff"))
-    )));
-
-// which would generate the following WHERE clause in an RDBMS backend:
-   WHERE (first_name='James' AND last_name='Maes') OR (first_name='Darin' AND last_name='Kelkhoff')
-
-
-
-
QFilterCriteria
-
-
    -
  • -

    fieldName - String, required - Reference to a field on the table being queried.

    -
    -
      -
    • -

      Or, in the case of a query with queryJoins, a qualified name of a field from a join-table (where the qualifier would be the joined table’s name or alias, followed by a dot)

      -
      -
        -
      • -

        For example: orderLine.sku or orderBillToCustomer.firstName

        -
      • -
      -
      -
    • -
    -
    -
  • -
  • -

    operator - Enum of QCriteriaOperator, required - Comparison operation to be applied to the field specified as fieldName and the values or otherFieldName.

    -
    -
      -
    • -

      e.g., EQUALS, NOT_IN, GREATER_THAN, BETWEEN, IS_BLANK, etc.

      -
    • -
    -
    -
  • -
  • -

    values - List of values, conditional - Provides the value(s) that the field is compared against. -The number of values (0, 1, 2, or more) be driven based on the operator being used. -If an otherFieldName is given, and the operator expects 1 value, then values is ignored, and otherFieldName is used.

    -
  • -
  • -

    otherFieldName - String, conditional - Specifies that the fieldName should be compared against another field in the records, rather than the values in the values property. -Only used for operators that expect 1 value (e.g., EQUALS or LESS_THAN_OR_EQUALS - not IS_NOT_BLANK or IN).

    -
  • -
-
-
-

QFilterCriteria definition examples:

-
-
-
-
// one-liners, via constructors that take (List<Serializable> values) or (Serializable... values) in 3rd position
-new QFilterCriteria("id", IN, List.of(1, 2, 3))
-new QFilterCriteria("name", IS_BLANK)
-new QFilterCriteria("orderNo", IN, orderNoList)
-new QFilterCriteria("state", EQUALS, "MO");
-
-// long-form, with fluent setters
-new QFilterCriteria()
-   .withFieldName("quantity")
-   .withOpeartor(QCriteriaOperator.GREATER_THAN)
-   .withValues(List.of(47));
-
-// to use otherFieldName, long-form must be used
-new QFilterCriteria()
-   .withFieldName("firstName")
-   .withOpeartor(QCriteriaOperator.EQUALS)
-   .withOtherFieldName("lastName");
-
-// using otherFieldName to build a criterion that looks at two fields from join tables
-new QFilterCriteria()
-   .withFieldName("billToCustomer.lastName")
-   .withOpeartor(QCriteriaOperator.NOT_EQUALS)
-   .withOtherFieldName("shipToCustomer.lastName");
-
-
-
-
-
QFilterOrderBy
-
-
    -
  • -

    fieldName - String, required - Reference to a field on the table being queried.

    -
    -
      -
    • -

      Or, in the case of a query with queryJoins, a qualified name of a field from a join-table (where the qualifier would be the joined table’s name or alias, followed by a dot)

      -
    • -
    -
    -
  • -
  • -

    isAscending - boolean, default: true - Specify if the sort is ascending or descending.

    -
  • -
-
-
-

QFilterCriteria definition examples:

-
-
-
-
// short-form, via constructors
-new QFilterOrderBy("id") // isAscending defaults to true.
-new QFilterOrderBy("name", false)
-
-// long-form, with fluent setters
-new QFilterOrderBy()
-   .withFieldName("birthDate")
-   .withIsAscending(true);
-
-
-
-
-
-
QueryJoin
-
-
    -
  • -

    leftTableOrAlias - String, required - Name of the table on the left side of the join. -If the table to be used here was given an alias from a previous queryJoin, then that alias name should be given here.

    -
    -
      -
    • -

      Will be inferred from joinMetaData, if leftTableOrAlias is not set when joinMetaData gets set (which will only use the leftTableName from the joinMetaData - never an alias)

      -
    • -
    -
    -
  • -
  • -

    rightTable - String, required - Name of the table on the right side of the join.

    -
    -
      -
    • -

      Will be inferred from joinMetaData, if rightTable is not set when joinMetaData gets set.

      -
    • -
    -
    -
  • -
  • -

    joinMetaData - QJoinMetaData object - Optional specification of a QQQ Join in the current QInstance. -If not set, will be looked up at runtime based on leftTableOrAlias and rightTable.

    -
    -
      -
    • -

      If set before leftTableOrAlias and rightTable, then they will be set based on the leftTable and rightTable in this object.

      -
    • -
    -
    -
  • -
  • -

    alias - String - Optional (unless multiple instances of the same table are being joined together, when it becomes required). -Behavior based on SQL FROM clause aliases. -If given, must be used as the part before the dot in field name specifications throughout the rest of the query input.

    -
  • -
  • -

    select - boolean, default: false - Specify whether fields from the rightTable should be selected by the query. -If true, then the QRecord objects returned by this query will have values with corresponding to the (table-or-alias . field-name) form.

    -
  • -
  • -

    type - Enum of INNER, LEFT, RIGHT, FULL, default: INNER - specifies the SQL-style type of join being performed.

    -
  • -
-
-
-

QueryJoin definition examples:

-
-
-
-
// selecting from an "orderLine" table joined to its corresponding "order" table
-queryInput.withQueryJoin(new QueryJoin("orderLine", "order").withSelect(true));
-...
-queryOutput.getRecords().get(0).getValueBigDecimal("order.grandTotal");
-
-// given an "order" table with 2 foreign keys to a customer table (billToCustomerId and shipToCustomerId)
-// Note, we must supply the JoinMetaData to the QueryJoin, to drive what fields to join on in each case.
-queryInput.withQueryJoins(List.of(
-   new QueryJoin(instance.getJoin("orderJoinShipToCustomer")
-       .withAlias("shipToCustomer")
-       .withSelect(true)),
-   new QueryJoin(instance.getJoin("orderJoinBillToCustomer")
-       .withAlias("billToCustomer")
-       .withSelect(true))));
-...
-record.getValueString("billToCustomer.firstName")
-   + " placed an order for "
-   + record.getValueString("shipToCustomer.firstName")
-
-
-
-
-
-

QueryOutput

-
-
    -
  • -

    records - List of QRecord - List of 0 or more records that match the query filter.

    -
    -
      -
    • -

      Note: If a recordPipe was supplied to the QueryInput, then calling queryOutput.getRecords() will result in an IllegalStateException being thrown - as the records were placed into the pipe as they were fetched, and cannot all be accessed as a single list.

      -
    • -
    -
    -
  • -
-
-
-
-
-
-

RenderTemplateAction

-
-

The RenderTemplateAction performs the job of taking a template - that is, a string of code, in a templating language, such as Velocity, and merging it with a set of data (known as a context), to produce some using-facing output, such as a String of HTML.

-
-
-

Examples

-
-
Canonical Form
-
-
-
RenderTemplateInput input = new RenderTemplateInput(qInstance);
-input.setSession(session);
-input.setCode("Hello, ${name}");
-input.setTemplateType(TemplateType.VELOCITY);
-input.setContext(Map.of("name", "Darin"));
-RenderTemplateOutput output = new RenderTemplateAction.execute(input);
-String result = output.getResult();
-assertEquals("Hello, Darin", result);
-
-
-
-
-
Convenient Form
-
-
-
String result = RenderTemplateAction.renderVelocity(input, Map.of("name", "Darin"), "Hello, ${name}");
-assertEquals("Hello, Darin", result);
-
-
-
-
-
-

RenderTemplateInput

-
-
    -
  • -

    code - String, Required - String of template code to be rendered, in the templating language specified by the type parameter.

    -
  • -
  • -

    type - Enum of VELOCITY, Required - Specifies the language of the template code.

    -
  • -
  • -

    context - Map of String → Object - Data to be made available to the template during rendering.

    -
  • -
-
-
-
-

RenderTemplateOutput

-
-
    -
  • -

    result - String - Result of rendering the input template and context.

    -
  • -
-
-
-
-
-
-
-
- - - \ No newline at end of file diff --git a/docs/index.pdf b/docs/index.pdf deleted file mode 100644 index 4f4ba0a8..00000000 --- a/docs/index.pdf +++ /dev/null @@ -1,12863 +0,0 @@ -%PDF-1.4 -% -1 0 obj -<< /Title (QQQ) -/Creator (Asciidoctor PDF 2.3.3, based on Prawn 2.4.0) -/Producer (Asciidoctor PDF 2.3.3, based on Prawn 2.4.0) -/ModDate (D:20221121090342-06'00') -/CreationDate (D:20221121094618-06'00') ->> -endobj -2 0 obj -<< /Type /Catalog -/Pages 3 0 R -/Names 12 0 R -/Outlines 76 0 R -/PageLabels 85 0 R -/PageMode /UseOutlines -/OpenAction [7 0 R /FitH 841.89] -/ViewerPreferences << /DisplayDocTitle true ->> ->> -endobj -3 0 obj -<< /Type /Pages -/Count 9 -/Kids [7 0 R 10 0 R 15 0 R 19 0 R 35 0 R 43 0 R 49 0 R 52 0 R 55 0 R] ->> -endobj -4 0 obj -<< /Length 2 ->> -stream -q - -endstream -endobj -5 0 obj -<< /Type /Page -/Parent 3 0 R -/MediaBox [0 0 595.28 841.89] -/CropBox [0 0 595.28 841.89] -/BleedBox [0 0 595.28 841.89] -/TrimBox [0 0 595.28 841.89] -/ArtBox [0 0 595.28 841.89] -/Contents 4 0 R -/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] ->> ->> -endobj -6 0 obj -<< /Length 148 ->> -stream -q -/DeviceRGB cs -0.6 0.6 0.6 scn -/DeviceRGB CS -0.6 0.6 0.6 SCN - -BT -486.938 361.6965 Td -/F1.0 27 Tf -<515151> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -Q - -endstream -endobj -7 0 obj -<< /Type /Page -/Parent 3 0 R -/MediaBox [0 0 595.28 841.89] -/CropBox [0 0 595.28 841.89] -/BleedBox [0 0 595.28 841.89] -/TrimBox [0 0 595.28 841.89] -/ArtBox [0 0 595.28 841.89] -/Contents 6 0 R -/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] -/Font << /F1.0 8 0 R ->> ->> ->> -endobj -8 0 obj -<< /Type /Font -/BaseFont /3b6d06+NotoSerif -/Subtype /TrueType -/FontDescriptor 90 0 R -/FirstChar 32 -/LastChar 255 -/Widths 92 0 R -/ToUnicode 91 0 R ->> -endobj -9 0 obj -<< /Length 4880 ->> -stream -q -/DeviceRGB cs -0.2 0.2 0.2 scn -/DeviceRGB CS -0.2 0.2 0.2 SCN - -BT -48.24 782.394 Td -/F2.0 22 Tf -[<54> 29.78516 <61626c65206f6620436f6e74656e7473>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -48.24 751.856 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 751.856 Td -/F1.0 10.5 Tf -<496e74726f64756374696f6e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.66275 0.66275 0.66275 scn -0.66275 0.66275 0.66275 SCN - -BT -112.93062 751.856 Td -/F1.0 10.5 Tf -<2e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -540.49062 751.856 Td -/F1.0 2.625 Tf - Tj -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -541.1705 751.856 Td -/F1.0 10.5 Tf -<31> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -48.24 733.376 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 733.376 Td -/F1.0 10.5 Tf -<4d6574612044617461> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.66275 0.66275 0.66275 scn -0.66275 0.66275 0.66275 SCN - -BT -102.24162 733.376 Td -/F1.0 10.5 Tf -<2e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -540.49062 733.376 Td -/F1.0 2.625 Tf - Tj -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -541.1705 733.376 Td -/F1.0 10.5 Tf -<32> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -60.24 714.896 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -60.24 714.896 Td -/F1.0 10.5 Tf -[<5151512054> 29.78516 <61626c6573>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.66275 0.66275 0.66275 scn -0.66275 0.66275 0.66275 SCN - -BT -123.61962 714.896 Td -/F1.0 10.5 Tf -<2e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -540.49062 714.896 Td -/F1.0 2.625 Tf - Tj -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -541.1705 714.896 Td -/F1.0 10.5 Tf -<32> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -60.24 696.416 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -60.24 696.416 Td -/F1.0 10.5 Tf -<515151205265706f727473> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.66275 0.66275 0.66275 scn -0.66275 0.66275 0.66275 SCN - -BT -128.96412 696.416 Td -/F1.0 10.5 Tf -<2e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -540.49062 696.416 Td -/F1.0 2.625 Tf - Tj -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -541.1705 696.416 Td -/F1.0 10.5 Tf -<33> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -48.24 677.936 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 677.936 Td -/F1.0 10.5 Tf -[<41> 20.01953 <6374696f6e73>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.66275 0.66275 0.66275 scn -0.66275 0.66275 0.66275 SCN - -BT -86.20812 677.936 Td -/F1.0 10.5 Tf -<2e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -540.49062 677.936 Td -/F1.0 2.625 Tf - Tj -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -541.1705 677.936 Td -/F1.0 10.5 Tf -<37> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -60.24 659.456 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -60.24 659.456 Td -/F1.0 10.5 Tf -[<52656e64657254> 29.78516 <656d706c61746541> 20.01953 <6374696f6e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.66275 0.66275 0.66275 scn -0.66275 0.66275 0.66275 SCN - -BT -177.06462 659.456 Td -/F1.0 10.5 Tf -<2e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e202e20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -540.49062 659.456 Td -/F1.0 2.625 Tf - Tj -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -541.1705 659.456 Td -/F1.0 10.5 Tf -<37> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -Q - -endstream -endobj -10 0 obj -<< /Type /Page -/Parent 3 0 R -/MediaBox [0 0 595.28 841.89] -/CropBox [0 0 595.28 841.89] -/BleedBox [0 0 595.28 841.89] -/TrimBox [0 0 595.28 841.89] -/ArtBox [0 0 595.28 841.89] -/Contents 9 0 R -/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] -/Font << /F2.0 17 0 R -/F1.0 8 0 R ->> ->> -/Annots [64 0 R 65 0 R 66 0 R 67 0 R 68 0 R 69 0 R 70 0 R 71 0 R 72 0 R 73 0 R 74 0 R 75 0 R] ->> -endobj -11 0 obj -[10 0 R /XYZ 0 841.89 null] -endobj -12 0 obj -<< /Type /Names -/Dests 13 0 R ->> -endobj -13 0 obj -<< /Names [(__anchor-top) 86 0 R (_actions) 56 0 R (_canonical_form) 60 0 R (_convenient_form) 61 0 R (_examples) 59 0 R (_introduction) 16 0 R (_meta_data) 20 0 R (_qqq_reports) 37 0 R (_qqq_tables) 21 0 R (_qreportdatasource) 44 0 R (_qreportfield) 53 0 R (_qreportmetadata) 39 0 R (_qreportview) 47 0 R (_qtablemetadata) 23 0 R (_rendertemplateaction) 57 0 R (_rendertemplateinput) 62 0 R (_rendertemplateoutput) 63 0 R (toc) 11 0 R] ->> -endobj -14 0 obj -<< /Length 1751 ->> -stream -q -/DeviceRGB cs -0.2 0.2 0.2 scn -/DeviceRGB CS -0.2 0.2 0.2 SCN - -BT -48.24 782.394 Td -/F2.0 22 Tf -<496e74726f64756374696f6e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 753.206 Td -/F1.0 10.5 Tf -<51515120697320c9> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 725.426 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 725.426 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 725.426 Td -/F1.0 10.5 Tf -[<4672> 20.01953 <616d65776f726b>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 703.646 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 703.646 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 703.646 Td -/F1.0 10.5 Tf -[<4465636c6172> 20.01953 <6174697665>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 681.866 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 681.866 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 681.866 Td -/F1.0 10.5 Tf -<45617379207468696e6720656173793b2048617264207468696e6720706f737369626c65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 660.086 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 660.086 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 660.086 Td -/F1.0 10.5 Tf -<437573746f6d697a61626c65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.0 0.0 0.0 scn -0.0 0.0 0.0 SCN -1 w -0 J -0 j -[] 0 d -/Stamp1 Do -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -541.009 14.263 Td -/F1.0 9 Tf -<31> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -Q -Q - -endstream -endobj -15 0 obj -<< /Type /Page -/Parent 3 0 R -/MediaBox [0 0 595.28 841.89] -/CropBox [0 0 595.28 841.89] -/BleedBox [0 0 595.28 841.89] -/TrimBox [0 0 595.28 841.89] -/ArtBox [0 0 595.28 841.89] -/Contents 14 0 R -/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] -/Font << /F2.0 17 0 R -/F1.0 8 0 R ->> -/XObject << /Stamp1 87 0 R ->> ->> ->> -endobj -16 0 obj -[15 0 R /XYZ 0 841.89 null] -endobj -17 0 obj -<< /Type /Font -/BaseFont /7efbb4+NotoSerif-Bold -/Subtype /TrueType -/FontDescriptor 94 0 R -/FirstChar 32 -/LastChar 255 -/Widths 96 0 R -/ToUnicode 95 0 R ->> -endobj -18 0 obj -<< /Length 20669 ->> -stream -q -/DeviceRGB cs -0.2 0.2 0.2 scn -/DeviceRGB CS -0.2 0.2 0.2 SCN - -BT -48.24 782.394 Td -/F2.0 22 Tf -<4d6574612044617461> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 741.146 Td -/F2.0 18 Tf -[<5151512054> 29.78516 <61626c6573>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.69595 Tw - -BT -48.24 713.126 Td -/F1.0 10.5 Tf -[<54686520636f72652074797065206f66206f626a65637420696e20612051515120496e7374616e6365206973207468652054> 29.78516 <61626c652e20496e20746865206d6f737420636f6d6d6f6e207573652d636173652c2061205151512054> 29.78516 <61626c65>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.61646 Tw - -BT -48.24 697.346 Td -/F1.0 10.5 Tf -[<6d61> 20.01953 <792062652074686520696e2d61707020726570726573656e746174696f6e206f662061204461746162617365207461626c652e20546861742069732c206974206973206120636f6c6c656374696f6e206f66207265636f72647320286f7220726f777329>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 681.566 Td -/F1.0 10.5 Tf -<6f6620646174612c2065616368206f6620776869636820686173206120736574206f66206669656c647320286f7220636f6c756d6e73292e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.08072 Tw - -BT -48.24 653.786 Td -/F1.0 10.5 Tf -<51515120616c736f20616c6c6f7773206f74686572207479706573206f66206461746120736f75726365732028> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -2.08072 Tw - -BT -289.00824 653.786 Td -/F1.0 10.5 Tf -[<515151204261636b> 20.01953 <656e6473>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.08072 Tw - -BT -364.58876 653.786 Td -/F1.0 10.5 Tf -<2920746f2062652075736564206173207461626c65732c20737563682061732046696c65> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.27245 Tw - -BT -48.24 638.006 Td -/F1.0 10.5 Tf -[<73797374656d732c20415049d5732c204a61766120656e756d73206f72206f626a656374732c206574632e20416c6c206f66207468657365206261636b> 20.01953 <656e642074797065732070726573656e74207468652073616d6520696e7465726661636573>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 622.226 Td -/F1.0 10.5 Tf -[<28626f746820757365722d696e74657266616365732c20616e64206170706c69636174696f6e2070726f6772> 20.01953 <616d6d696e6720696e7465726661636573292c207265676172646c657373206f66207468656972206261636b> 20.01953 <656e6420747970652e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 587.726 Td -/F2.0 13 Tf -[<51> 20.01953 <54> 29.78516 <61626c654d65746144617461>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.15536 Tw - -BT -48.24 561.166 Td -/F1.0 10.5 Tf -[<54> 29.78516 <61626c65732061726520646566696e656420696e20612051515120496e7374616e636520696e206120>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.15536 Tw - -BT -267.67449 561.166 Td -/F4.0 10.5 Tf -<515461626c654d65746144617461> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.15536 Tw - -BT -341.17449 561.166 Td -/F1.0 10.5 Tf -<206f626a6563742e20416c6c207461626c6573206d757374207265666572656e6365206120> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -1.15536 Tw - -BT -523.667 561.166 Td -/F1.0 10.5 Tf -<515151> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -0.20871 Tw - -BT -48.24 545.386 Td -/F1.0 10.5 Tf -[<4261636b> 20.01953 <656e64>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.20871 Tw - -BT -90.91179 545.386 Td -/F1.0 10.5 Tf -<2c2061206c697374206f66206669656c6473207468617420646566696e6520746865207368617065206f66207265636f72647320696e20746865207461626c652c20616e64206164646974696f6e616c206461746120746f206465736372696265> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 529.606 Td -/F1.0 10.5 Tf -[<686f7720746f20776f726b207769746820746865207461626c652077697468696e20697473206261636b> 20.01953 <656e642e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 501.826 Td -/F2.0 10.5 Tf -[<51> 20.01953 <54> 29.78516 <61626c654d657461446174612050726f706572746965733a>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 474.046 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 474.046 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 474.046 Td -/F3.0 10.5 Tf -<6e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -87.24 474.046 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -95.934 474.046 Td -/F2.0 10.5 Tf -<537472696e672c205265717569726564> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -183.3255 474.046 Td -/F1.0 10.5 Tf -<202d20556e69717565206e616d6520666f7220746865207461626c652077697468696e207468652051515120496e7374616e63652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 452.266 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.11056 Tw - -BT -66.24 452.266 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.11056 Tw - -BT -66.24 452.266 Td -/F3.0 10.5 Tf -<6c6162656c> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.11056 Tw - -BT -92.49 452.266 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.11056 Tw - -BT -101.40513 452.266 Td -/F2.0 10.5 Tf -<537472696e67> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.11056 Tw - -BT -133.83962 452.266 Td -/F1.0 10.5 Tf -<202d20557365722d666163696e67206c6162656c20666f7220746865207461626c652c2070726573656e74656420696e205573657220496e74657266616365732e20496e6665727265642066726f6d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.11056 Tw - -BT -515.98594 452.266 Td -/F3.0 10.5 Tf -<6e616d65> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.11056 Tw - -BT -536.98594 452.266 Td -/F1.0 10.5 Tf -<206966> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 436.486 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 436.486 Td -/F1.0 10.5 Tf -<6e6f74207365742e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 414.706 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 414.706 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 414.706 Td -/F3.0 10.5 Tf -<6261636b656e644e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -123.99 414.706 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -132.684 414.706 Td -/F2.0 10.5 Tf -<537472696e672c205265717569726564> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -220.0755 414.706 Td -/F1.0 10.5 Tf -<202d204e616d65206f66206120> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -BT -282.204 414.706 Td -/F1.0 10.5 Tf -[<515151204261636b> 20.01953 <656e64>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -350.96829 414.706 Td -/F1.0 10.5 Tf -<20696e2077686963682074686973207461626c65d5732064617461206973206d616e616765642e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 392.926 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.53229 Tw - -BT -66.24 392.926 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.53229 Tw - -BT -66.24 392.926 Td -/F3.0 10.5 Tf -<6669656c6473> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.53229 Tw - -BT -97.74 392.926 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.53229 Tw - -BT -107.49858 392.926 Td -/F2.0 10.5 Tf -<4d6170206f6620537472696e6720> Tj -/F2.1 10.5 Tf -<2120> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -0.53229 Tw - -BT -197.19774 392.926 Td -/F2.0 10.5 Tf -<515151204669656c64> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.53229 Tw - -BT -251.94152 392.926 Td -/F2.0 10.5 Tf -<2c205265717569726564> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.53229 Tw - -BT -307.43081 392.926 Td -/F1.0 10.5 Tf -[<202d2054686520636f6c756d6e73206f6620646174612074686174206d616b> 20.01953 <6520757020616c6c207265636f726473>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 377.146 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 377.146 Td -/F1.0 10.5 Tf -<696e2074686973207461626c652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 355.366 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.05151 Tw - -BT -66.24 355.366 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.05151 Tw - -BT -66.24 355.366 Td -/F3.0 10.5 Tf -<7072696d6172794b65794669656c64> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.05151 Tw - -BT -144.99 355.366 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.05151 Tw - -BT -153.78703 355.366 Td -/F2.0 10.5 Tf -<537472696e672c20436f6e646974696f6e616c> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.05151 Tw - -BT -254.33404 355.366 Td -/F1.0 10.5 Tf -<202d204e616d65206f66206120> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -0.05151 Tw - -BT -316.7201 355.366 Td -/F1.0 10.5 Tf -<515151204669656c64> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.05151 Tw - -BT -367.70712 355.366 Td -/F1.0 10.5 Tf -[<20746861742073657276657320617320746865207072696d617279206b> 20.01953 <65792028652e672e2c>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 339.586 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 339.586 Td -/F1.0 10.5 Tf -<756e69717565206964656e7469666965722920666f72207265636f72647320696e2074686973207461626c652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 317.806 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -1.33069 Tw - -BT -66.24 317.806 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.33069 Tw - -BT -66.24 317.806 Td -/F3.0 10.5 Tf -<756e697175654b657973> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.33069 Tw - -BT -118.74 317.806 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.33069 Tw - -BT -130.09537 317.806 Td -/F2.0 10.5 Tf -[<4c697374206f6620556e697175654b> 20.01953 <6579>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.33069 Tw - -BT -226.65804 317.806 Td -/F1.0 10.5 Tf -[<202d20446566696e6974696f6e206f66206164646974696f6e616c20756e6971756520636f6e737472> 20.01953 <61696e7473202866726f6d20616e205244424d53>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -1.78334 Tw - -BT -66.24 302.026 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.78334 Tw - -BT -66.24 302.026 Td -/F1.0 10.5 Tf -<706f696e74206f662076696577292066726f6d20746865207461626c652e20652e672e2c2073657473206f6620636f6c756d6e73207768696368206d757374206861766520756e697175652076616c75657320666f722065616368> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 286.246 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 286.246 Td -/F1.0 10.5 Tf -<7265636f726420696e20746865207461626c652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 264.466 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -1.97049 Tw - -BT -66.24 264.466 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.97049 Tw - -BT -66.24 264.466 Td -/F3.0 10.5 Tf -<6261636b656e6444657461696c73> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.97049 Tw - -BT -139.74 264.466 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.97049 Tw - -BT -152.37497 264.466 Td -/F2.0 10.5 Tf -[<51> 20.01953 <54> 29.78516 <61626c654261636b> 20.01953 <656e6444657461696c73206f7220737562636c617373>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.97049 Tw - -BT -337.85229 264.466 Td -/F1.0 10.5 Tf -[<202d2041> 20.01953 <64646974696f6e616c206461746120746f20636f6e66696775726520746865207461626c65>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 248.686 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 248.686 Td -/F1.0 10.5 Tf -<77697468696e2069747320> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -BT -116.325 248.686 Td -/F1.0 10.5 Tf -[<515151204261636b> 20.01953 <656e64>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -185.08929 248.686 Td -/F1.0 10.5 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 226.906 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -3.44204 Tw - -BT -66.24 226.906 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -3.44204 Tw - -BT -66.24 226.906 Td -/F3.0 10.5 Tf -<6175746f6d6174696f6e44657461696c73> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -3.44204 Tw - -BT -155.49 226.906 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -3.44204 Tw - -BT -171.06808 226.906 Td -/F2.0 10.5 Tf -[<51> 20.01953 <54> 29.78516 <61626c6541> 20.01953 <75746f6d6174696f6e44657461696c73>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -3.44204 Tw - -BT -308.84043 226.906 Td -/F1.0 10.5 Tf -[<202d20436f6e6669677572> 20.01953 <6174696f6e206f66206175746f6d61746564206a6f627320746861742072756e>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 211.126 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 211.126 Td -/F1.0 10.5 Tf -<616761696e7374207265636f72647320696e20746865207461626c652c20652e672e2c2075706f6e20696e73657274206f72207570646174652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 189.346 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.95361 Tw - -BT -66.24 189.346 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.95361 Tw - -BT -66.24 189.346 Td -/F3.0 10.5 Tf -<637573746f6d697a657273> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.95361 Tw - -BT -123.99 189.346 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.95361 Tw - -BT -134.59121 189.346 Td -/F2.0 10.5 Tf -<4d6170206f6620537472696e6720> Tj -/F2.1 10.5 Tf -<2120> Tj -/F2.0 10.5 Tf -<51436f64655265666572656e6365> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.95361 Tw - -BT -314.09164 189.346 Td -/F1.0 10.5 Tf -<202d205265666572656e63657320746f20637573746f6d20636f646520746861742061726520696e6a6563746564> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.87561 Tw - -BT -66.24 173.566 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.87561 Tw - -BT -66.24 173.566 Td -/F1.0 10.5 Tf -<696e746f207374616e64617264207461626c6520616374696f6e732c207468617420616c6c6f77206170706c69636174696f6e7320746f20637573746f6d697a65206365727461696e207061727473206f6620686f7720746865207461626c65> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 157.786 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 157.786 Td -/F1.0 10.5 Tf -<776f726b732e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 136.006 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 136.006 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 136.006 Td -/F3.0 10.5 Tf -<706172656e744170704e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -134.49 136.006 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -143.184 136.006 Td -/F2.0 10.5 Tf -<537472696e67> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -175.6185 136.006 Td -/F1.0 10.5 Tf -<202d204e616d65206f66206120> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -BT -237.747 136.006 Td -/F1.0 10.5 Tf -<51515120417070> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -284.115 136.006 Td -/F1.0 10.5 Tf -<20746861742074686973207461626c65206578697374732077697468696e2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 114.226 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 114.226 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 114.226 Td -/F3.0 10.5 Tf -<69636f6e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -87.24 114.226 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -95.934 114.226 Td -/F2.0 10.5 Tf -<5149636f6e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -127.3395 114.226 Td -/F1.0 10.5 Tf -<202d2049636f6e206173736f63696174656420776974682074686973207461626c6520696e206365727461696e207573657220696e74657266616365732e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 92.446 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.74915 Tw - -BT -66.24 92.446 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.74915 Tw - -BT -66.24 92.446 Td -/F3.0 10.5 Tf -<7265636f72644c6162656c466f726d6174> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.74915 Tw - -BT -155.49 92.446 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.74915 Tw - -BT -165.68229 92.446 Td -/F2.0 10.5 Tf -<537472696e67> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.74915 Tw - -BT -198.11679 92.446 Td -/F1.0 10.5 Tf -[<202d204a6176612046> 40.03906 <6f726d617420537472696e672c2075736564207769746820>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.74915 Tw - -BT -362.47741 92.446 Td -/F3.0 10.5 Tf -<7265636f72644c6162656c4669656c6473> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.74915 Tw - -BT -451.72741 92.446 Td -/F1.0 10.5 Tf -<20746f2070726f647563652061206c6162656c> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 76.666 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 76.666 Td -/F1.0 10.5 Tf -<73686f776e20666f72207265636f7264732066726f6d20746865207461626c652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 54.886 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.56654 Tw - -BT -66.24 54.886 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.56654 Tw - -BT -66.24 54.886 Td -/F3.0 10.5 Tf -<7265636f72644c6162656c4669656c6473> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.56654 Tw - -BT -155.49 54.886 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.56654 Tw - -BT -165.31708 54.886 Td -/F2.0 10.5 Tf -<4c697374206f6620537472696e672c20436f6e646974696f6e616c> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.56654 Tw - -BT -303.55871 54.886 Td -/F1.0 10.5 Tf -<202d2055736564207769746820> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.56654 Tw - -BT -367.00838 54.886 Td -/F3.0 10.5 Tf -<7265636f72644c6162656c466f726d6174> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.56654 Tw - -BT -456.25838 54.886 Td -/F1.0 10.5 Tf -<20746f2070726f766964652076616c756573> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.0 0.0 0.0 scn -0.0 0.0 0.0 SCN -1 w -0 J -0 j -[] 0 d -/Stamp2 Do -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -49.24 14.263 Td -/F1.0 9 Tf -<32> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -Q -Q - -endstream -endobj -19 0 obj -<< /Type /Page -/Parent 3 0 R -/MediaBox [0 0 595.28 841.89] -/CropBox [0 0 595.28 841.89] -/BleedBox [0 0 595.28 841.89] -/TrimBox [0 0 595.28 841.89] -/ArtBox [0 0 595.28 841.89] -/Contents 18 0 R -/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] -/Font << /F2.0 17 0 R -/F1.0 8 0 R -/F4.0 24 0 R -/F3.0 27 0 R -/F2.1 29 0 R ->> -/XObject << /Stamp2 88 0 R ->> ->> -/Annots [22 0 R 25 0 R 26 0 R 28 0 R 30 0 R 31 0 R 32 0 R 33 0 R] ->> -endobj -20 0 obj -[19 0 R /XYZ 0 841.89 null] -endobj -21 0 obj -[19 0 R /XYZ 0 765.17 null] -endobj -22 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Backends{relfilesuffix}) ->> -/Subtype /Link -/Rect [289.00824 650.72 364.58876 665] -/Type /Annot ->> -endobj -23 0 obj -[19 0 R /XYZ 0 606.41 null] -endobj -24 0 obj -<< /Type /Font -/BaseFont /885b39+mplus1mn-bold -/Subtype /TrueType -/FontDescriptor 98 0 R -/FirstChar 32 -/LastChar 255 -/Widths 100 0 R -/ToUnicode 99 0 R ->> -endobj -25 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Backends{relfilesuffix}) ->> -/Subtype /Link -/Rect [523.667 558.1 547.04 572.38] -/Type /Annot ->> -endobj -26 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Backends{relfilesuffix}) ->> -/Subtype /Link -/Rect [48.24 542.32 90.91179 556.6] -/Type /Annot ->> -endobj -27 0 obj -<< /Type /Font -/BaseFont /be376d+mplus1mn-regular -/Subtype /TrueType -/FontDescriptor 102 0 R -/FirstChar 32 -/LastChar 255 -/Widths 104 0 R -/ToUnicode 103 0 R ->> -endobj -28 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Backends{relfilesuffix}) ->> -/Subtype /Link -/Rect [282.204 411.64 350.96829 425.92] -/Type /Annot ->> -endobj -29 0 obj -<< /Type /Font -/BaseFont /adefa7+NotoSerif-Bold -/Subtype /TrueType -/FontDescriptor 106 0 R -/FirstChar 32 -/LastChar 255 -/Widths 108 0 R -/ToUnicode 107 0 R ->> -endobj -30 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Fields{relfilesuffix}) ->> -/Subtype /Link -/Rect [197.19774 389.86 251.94152 404.14] -/Type /Annot ->> -endobj -31 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Fields{relfilesuffix}) ->> -/Subtype /Link -/Rect [316.7201 352.3 367.70712 366.58] -/Type /Annot ->> -endobj -32 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Backends{relfilesuffix}) ->> -/Subtype /Link -/Rect [116.325 245.62 185.08929 259.9] -/Type /Annot ->> -endobj -33 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Apps{relfilesuffix}) ->> -/Subtype /Link -/Rect [237.747 132.94 284.115 147.22] -/Type /Annot ->> -endobj -34 0 obj -<< /Length 22162 ->> -stream -q - -1.86515 Tw - -BT -66.24 793.926 Td -ET - - -0.0 Tw -/DeviceRGB cs -0.2 0.2 0.2 scn -/DeviceRGB CS -0.2 0.2 0.2 SCN - -1.86515 Tw - -BT -66.24 793.926 Td -/F1.0 10.5 Tf -[<666f7220616e> 20.01953 <7920666f726d6174207370656369666965727320696e2074686520666f726d617420737472696e672e20546865736520737472696e6773206d757374206265206669656c64206e616d65732077697468696e20746865>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 778.146 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 778.146 Td -/F1.0 10.5 Tf -<7461626c652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 756.366 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 756.366 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 756.366 Td -/F1.0 10.5 Tf -<4578616d706c65206f66207573696e6720> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -173.2275 756.366 Td -/F3.0 10.5 Tf -<7265636f72644c6162656c466f726d6174> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -262.4775 756.366 Td -/F1.0 10.5 Tf -<20616e6420> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -287.0265 756.366 Td -/F3.0 10.5 Tf -<7265636f72644c6162656c4669656c6473> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -376.2765 756.366 Td -/F1.0 10.5 Tf -<3a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.96078 0.96078 0.96078 scn -52.24 740.55 m -543.04 740.55 l -545.24914 740.55 547.04 738.75914 547.04 736.55 c -547.04 619.37 l -547.04 617.16086 545.24914 615.37 543.04 615.37 c -52.24 615.37 l -50.03086 615.37 48.24 617.16086 48.24 619.37 c -48.24 736.55 l -48.24 738.75914 50.03086 740.55 52.24 740.55 c -h -f -0.8 0.8 0.8 SCN -0.75 w -52.24 740.55 m -543.04 740.55 l -545.24914 740.55 547.04 738.75914 547.04 736.55 c -547.04 619.37 l -547.04 617.16086 545.24914 615.37 543.04 615.37 c -52.24 615.37 l -50.03086 615.37 48.24 617.16086 48.24 619.37 c -48.24 736.55 l -48.24 738.75914 50.03086 740.55 52.24 740.55 c -h -S -Q -0.6 0.6 0.6 scn -0.6 0.6 0.6 SCN - -BT -59.24 717.725 Td -/F3.0 11 Tf -<2f2f20676976656e207468657365206669656c647320696e20746865207461626c653a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.4 0.6 scn -0.0 0.4 0.6 SCN - -BT -59.24 702.985 Td -/F3.0 11 Tf -<6e6577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -75.74 702.985 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -81.24 702.985 Td -/F3.0 11 Tf -<514669656c644d65746144617461> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -158.24 702.985 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -163.74 702.985 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -169.24 702.985 Td -/F3.0 11 Tf -<6e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -191.24 702.985 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -196.74 702.985 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -202.24 702.985 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -207.74 702.985 Td -/F3.0 11 Tf -<514669656c6454797065> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -262.74 702.985 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -268.24 702.985 Td -/F3.0 11 Tf -<535452494e47> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -301.24 702.985 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.4 0.6 scn -0.0 0.4 0.6 SCN - -BT -59.24 688.245 Td -/F3.0 11 Tf -<6e6577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -75.74 688.245 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -81.24 688.245 Td -/F3.0 11 Tf -<514669656c644d65746144617461> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -158.24 688.245 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -163.74 688.245 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -169.24 688.245 Td -/F3.0 11 Tf -<626972746844617465> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -218.74 688.245 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -224.24 688.245 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -229.74 688.245 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -235.24 688.245 Td -/F3.0 11 Tf -<514669656c6454797065> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -290.24 688.245 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -295.74 688.245 Td -/F3.0 11 Tf -<44415445> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -317.74 688.245 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.6 0.6 0.6 scn -0.6 0.6 0.6 SCN - -BT -59.24 658.765 Td -/F3.0 11 Tf -<2f2f2057652063616e2070726f647563652061207265636f7264206c6162656c20737563682061732022446172696e204b656c6b686f66662028313938302d30352d33312922207669613a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 644.025 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -64.74 644.025 Td -/F3.0 11 Tf -<776974685265636f72644c6162656c466f726d6174> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -180.24 644.025 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -185.74 644.025 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -191.24 644.025 Td -/F3.0 11 Tf -<25732028257329> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -229.74 644.025 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -235.24 644.025 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 629.285 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -64.74 629.285 Td -/F3.0 11 Tf -<776974685265636f72644c6162656c4669656c6473> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -180.24 629.285 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.46667 0.53333 scn -0.0 0.46667 0.53333 SCN - -BT -185.74 629.285 Td -/F3.0 11 Tf -<4c697374> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -207.74 629.285 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -213.24 629.285 Td -/F3.0 11 Tf -<6f66> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -224.24 629.285 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -229.74 629.285 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -235.24 629.285 Td -/F3.0 11 Tf -<6e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -257.24 629.285 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -262.74 629.285 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -268.24 629.285 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -273.74 629.285 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -279.24 629.285 Td -/F3.0 11 Tf -<626972746844617465> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -328.74 629.285 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -334.24 629.285 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -339.74 629.285 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 591.406 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -2.05596 Tw - -BT -66.24 591.406 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -2.05596 Tw - -BT -66.24 591.406 Td -/F3.0 10.5 Tf -<73656374696f6e73> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.05596 Tw - -BT -108.24 591.406 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.05596 Tw - -BT -121.04592 591.406 Td -/F2.0 10.5 Tf -<4c697374206f6620514669656c6453656374696f6e> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.05596 Tw - -BT -235.17685 591.406 Td -/F1.0 10.5 Tf -<202d204d656368616e69736d20746f206f7267616e697a65206669656c64732077697468696e207573657220696e74657266616365732c20696e746f> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -1.44375 Tw - -BT -66.24 575.626 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.44375 Tw - -BT -66.24 575.626 Td -/F1.0 10.5 Tf -[<6c6f676963616c2073656374696f6e732e20496620616e> 20.01953 <792073656374696f6e73206172652070726573656e7420696e20746865207461626c65206d65746120646174612c207468656e20616c6c206669656c647320696e20746865207461626c65>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -1.74543 Tw - -BT -66.24 559.846 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.74543 Tw - -BT -66.24 559.846 Td -/F1.0 10.5 Tf -<6d757374206265206c697374656420696e2065786163746c7920312073656374696f6e2e204966206e6f2073656374696f6e732061726520646566696e65642c207468656e20696e7374616e636520656e726963686d656e742077696c6c> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 544.066 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 544.066 Td -/F1.0 10.5 Tf -<646566696e652064656661756c742073656374696f6e732e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 522.286 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -2.18529 Tw - -BT -66.24 522.286 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -2.18529 Tw - -BT -66.24 522.286 Td -/F3.0 10.5 Tf -<6173736f63696174656453637269707473> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.18529 Tw - -BT -155.49 522.286 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.18529 Tw - -BT -168.55458 522.286 Td -/F2.0 10.5 Tf -<4c697374206f66204173736f636961746564536372697074> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.18529 Tw - -BT -297.91717 522.286 Td -/F1.0 10.5 Tf -<202d20446566696e6974696f6e206f6620757365722d646566696e6564207363726970747320746861742063616e206265> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 506.506 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 506.506 Td -/F1.0 10.5 Tf -<6173736f6369617465642077697468207265636f7264732077697468696e20746865207461626c652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 484.726 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -2.73365 Tw - -BT -66.24 484.726 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -2.73365 Tw - -BT -66.24 484.726 Td -/F3.0 10.5 Tf -<656e61626c65644361706162696c6974696573> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.73365 Tw - -BT -165.99 484.726 Td -/F1.0 10.5 Tf -<20616e6420> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -2.73365 Tw - -BT -196.0063 484.726 Td -/F3.0 10.5 Tf -<64697361626c65644361706162696c6974696573> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.73365 Tw - -BT -301.0063 484.726 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.73365 Tw - -BT -315.1676 484.726 Td -/F2.0 10.5 Tf -<536574206f66204361706162696c69747920656e756d2076616c756573> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.73365 Tw - -BT -483.3607 484.726 Td -/F1.0 10.5 Tf -<202d204f7665727269646573> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 468.946 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 468.946 Td -/F1.0 10.5 Tf -[<66726f6d20746865206261636b> 20.01953 <656e64206c6576656c2c20666f72206361706162696c697469657320746861742074686973207461626c6520646f6573206f7220646f6573206e6f7420706f73736573732e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.93333 0.93333 0.93333 SCN -0.5 w -48.24 447.13 m -547.04 447.13 l -S -Q -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 405.106 Td -/F2.0 18 Tf -<515151205265706f727473> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.0143 Tw - -BT -48.24 377.086 Td -/F1.0 10.5 Tf -[<5151512063616e2067656e6572> 20.01953 <617465207265706f727473206261736564206f6e20>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -2.0143 Tw - -BT -239.85457 377.086 Td -/F1.0 10.5 Tf -[<5151512054> 29.78516 <61626c6573>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.0143 Tw - -BT -300.02013 377.086 Td -/F1.0 10.5 Tf -<20646566696e65642077697468696e20612051515120496e7374616e63652e2055736572732063616e2072756e> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -4.52417 Tw - -BT -48.24 361.306 Td -/F1.0 10.5 Tf -[<7265706f7274732c2070726f766964696e6720696e7075742076616c7565732e20416c7465726e61746976656c79> 89.84375 <2c206170706c69636174696f6e20636f64652063616e2072756e207265706f727473206173206e65656465642c>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 345.526 Td -/F1.0 10.5 Tf -<737570706c79696e6720696e7075742076616c7565732e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 311.026 Td -/F2.0 13 Tf -<515265706f72744d65746144617461> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.73763 Tw - -BT -48.24 284.466 Td -/F1.0 10.5 Tf -<5265706f7274732061726520646566696e656420696e20612051515120496e7374616e63652077697468206120> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.73763 Tw - -BT -282.8442 284.466 Td -/F4.0 10.5 Tf -<515265706f72744d65746144617461> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.73763 Tw - -BT -361.5942 284.466 Td -/F1.0 10.5 Tf -<206f626a6563742e205265706f7274732061726520646566696e656420696e207465726d73> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 268.686 Td -/F1.0 10.5 Tf -<6f6620746865697220736f7572636573206f6620646174612028> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -169.452 268.686 Td -/F3.0 10.5 Tf -<515265706f727444617461536f75726365> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -258.702 268.686 Td -/F1.0 10.5 Tf -<292c20616e642074686569722076696577287329206f66207468617420646174612028> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -418.911 268.686 Td -/F3.0 10.5 Tf -<515265706f727456696577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -476.661 268.686 Td -/F1.0 10.5 Tf -<292e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 240.906 Td -/F2.0 10.5 Tf -<515265706f72744d657461446174612050726f706572746965733a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 213.126 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 213.126 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 213.126 Td -/F3.0 10.5 Tf -<6e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -87.24 213.126 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -95.934 213.126 Td -/F2.0 10.5 Tf -<537472696e672c205265717569726564> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -183.3255 213.126 Td -/F1.0 10.5 Tf -<202d20556e69717565206e616d6520666f7220746865207265706f72742077697468696e207468652051515120496e7374616e63652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 191.346 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.32793 Tw - -BT -66.24 191.346 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.32793 Tw - -BT -66.24 191.346 Td -/F3.0 10.5 Tf -<6c6162656c> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.32793 Tw - -BT -92.49 191.346 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.32793 Tw - -BT -101.83987 191.346 Td -/F2.0 10.5 Tf -<537472696e67> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.32793 Tw - -BT -134.27437 191.346 Td -/F1.0 10.5 Tf -<202d20557365722d666163696e67206c6162656c20666f7220746865207265706f72742c2070726573656e74656420696e205573657220496e74657266616365732e20496e6665727265642066726f6d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.32793 Tw - -BT -526.04 191.346 Td -/F3.0 10.5 Tf -<6e616d65> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.32793 Tw - -BT -547.04 191.346 Td -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 175.566 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 175.566 Td -/F1.0 10.5 Tf -<6966206e6f74207365742e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 153.786 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 153.786 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 153.786 Td -/F3.0 10.5 Tf -<70726f636573734e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -123.99 153.786 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -132.684 153.786 Td -/F2.0 10.5 Tf -<537472696e67> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -165.1185 153.786 Td -/F1.0 10.5 Tf -<202d204e616d65206f66206120> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -BT -227.247 153.786 Td -/F1.0 10.5 Tf -<5151512050726f63657373> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -290.94 153.786 Td -/F1.0 10.5 Tf -<207573656420746f2072756e20746865207265706f727420696e2061205573657220496e746572666163652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 132.006 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 132.006 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 132.006 Td -/F3.0 10.5 Tf -<696e7075744669656c6473> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -123.99 132.006 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -132.684 132.006 Td -/F2.0 10.5 Tf -<4c697374206f6620> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -BT -168.7305 132.006 Td -/F2.0 10.5 Tf -<515151204669656c64> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -222.942 132.006 Td -/F1.0 10.5 Tf -<202d204f7074696f6e616c206c697374206f66206669656c6473207573656420617320696e70757420746f20746865207265706f72742e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 110.226 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -1.13019 Tw - -BT -84.24 110.226 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.13019 Tw - -BT -84.24 110.226 Td -/F1.0 10.5 Tf -<5468652076616c75657320696e207468657365206669656c64732063616e206265207573656420766961207468652073796e74617820> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.13019 Tw - -BT -358.98306 110.226 Td -/F3.0 10.5 Tf -<247b696e7075742e4e414d457d> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.13019 Tw - -BT -427.23306 110.226 Td -/F1.0 10.5 Tf -<2c20776865726520> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.13019 Tw - -BT -469.43544 110.226 Td -/F3.0 10.5 Tf -<4e414d45> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.13019 Tw - -BT -490.43544 110.226 Td -/F1.0 10.5 Tf -<2069732074686520> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.13019 Tw - -BT -526.04 110.226 Td -/F3.0 10.5 Tf -<6e616d65> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.13019 Tw - -BT -547.04 110.226 Td -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -84.24 94.446 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 94.446 Td -/F1.0 10.5 Tf -<617474726962757465206f662074686520> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -162.297 94.446 Td -/F3.0 10.5 Tf -<696e7075744669656c64> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -214.797 94.446 Td -/F1.0 10.5 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 72.666 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 72.666 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 72.666 Td -/F1.0 10.5 Tf -[<46> 40.03906 <6f72206578616d706c653a>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.0 0.0 0.0 scn -0.0 0.0 0.0 SCN -1 w -0 J -0 j -[] 0 d -/Stamp1 Do -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -541.009 14.263 Td -/F1.0 9 Tf -<33> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -Q -Q - -endstream -endobj -35 0 obj -<< /Type /Page -/Parent 3 0 R -/MediaBox [0 0 595.28 841.89] -/CropBox [0 0 595.28 841.89] -/BleedBox [0 0 595.28 841.89] -/TrimBox [0 0 595.28 841.89] -/ArtBox [0 0 595.28 841.89] -/Contents 34 0 R -/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] -/Font << /F1.0 8 0 R -/F1.1 36 0 R -/F3.0 27 0 R -/F2.0 17 0 R -/F4.0 24 0 R ->> -/XObject << /Stamp1 87 0 R ->> ->> -/Annots [38 0 R 40 0 R 41 0 R] ->> -endobj -36 0 obj -<< /Type /Font -/BaseFont /b1eed4+NotoSerif -/Subtype /TrueType -/FontDescriptor 110 0 R -/FirstChar 32 -/LastChar 255 -/Widths 112 0 R -/ToUnicode 111 0 R ->> -endobj -37 0 obj -[35 0 R /XYZ 0 429.13 null] -endobj -38 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Tables{relfilesuffix}) ->> -/Subtype /Link -/Rect [239.85457 374.02 300.02013 388.3] -/Type /Annot ->> -endobj -39 0 obj -[35 0 R /XYZ 0 329.71 null] -endobj -40 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Processes{relfilesuffix}) ->> -/Subtype /Link -/Rect [227.247 150.72 290.94 165] -/Type /Annot ->> -endobj -41 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Fields{relfilesuffix}) ->> -/Subtype /Link -/Rect [168.7305 128.94 222.942 143.22] -/Type /Annot ->> -endobj -42 0 obj -<< /Length 24062 ->> -stream -q -q -/DeviceRGB cs -0.96078 0.96078 0.96078 scn -52.24 805.89 m -543.04 805.89 l -545.24914 805.89 547.04 804.09914 547.04 801.89 c -547.04 655.23 l -547.04 653.02086 545.24914 651.23 543.04 651.23 c -52.24 651.23 l -50.03086 651.23 48.24 653.02086 48.24 655.23 c -48.24 801.89 l -48.24 804.09914 50.03086 805.89 52.24 805.89 c -h -f -/DeviceRGB CS -0.8 0.8 0.8 SCN -0.75 w -52.24 805.89 m -543.04 805.89 l -545.24914 805.89 547.04 804.09914 547.04 801.89 c -547.04 655.23 l -547.04 653.02086 545.24914 651.23 543.04 651.23 c -52.24 651.23 l -50.03086 651.23 48.24 653.02086 48.24 655.23 c -48.24 801.89 l -48.24 804.09914 50.03086 805.89 52.24 805.89 c -h -S -Q -/DeviceRGB cs -0.6 0.6 0.6 scn -/DeviceRGB CS -0.6 0.6 0.6 SCN - -BT -59.24 783.065 Td -/F3.0 11 Tf -<2f2f20676976656e207468697320696e7075744669656c643a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.4 0.6 scn -0.0 0.4 0.6 SCN - -BT -59.24 768.325 Td -/F3.0 11 Tf -<6e6577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -75.74 768.325 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -81.24 768.325 Td -/F3.0 11 Tf -<514669656c644d65746144617461> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -158.24 768.325 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -163.74 768.325 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -169.24 768.325 Td -/F3.0 11 Tf -<73746f72654964> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -207.74 768.325 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -213.24 768.325 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -218.74 768.325 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -224.24 768.325 Td -/F3.0 11 Tf -<514669656c6454797065> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -279.24 768.325 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -284.74 768.325 Td -/F3.0 11 Tf -<494e5445474552> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -323.24 768.325 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.6 0.6 0.6 scn -0.6 0.6 0.6 SCN - -BT -59.24 738.845 Td -/F3.0 11 Tf -<2f2f206974732072756e2d74696d652076616c75652063616e2062652061636365737365642c20652e672e2c20696e20612071756572792066696c74657220756e6465722061206461746120736f757263653a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.4 0.6 scn -0.0 0.4 0.6 SCN - -BT -59.24 724.105 Td -/F3.0 11 Tf -<6e6577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -75.74 724.105 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -81.24 724.105 Td -/F3.0 11 Tf -<5146696c7465724372697465726961> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -163.74 724.105 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -169.24 724.105 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -174.74 724.105 Td -/F3.0 11 Tf -<73746f72654964> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -213.24 724.105 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -218.74 724.105 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -224.24 724.105 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -229.74 724.105 Td -/F3.0 11 Tf -<5143726974657269614f70657261746f72> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -323.24 724.105 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -328.74 724.105 Td -/F3.0 11 Tf -<455155414c53> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -361.74 724.105 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -367.24 724.105 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.46667 0.53333 scn -0.0 0.46667 0.53333 SCN - -BT -372.74 724.105 Td -/F3.0 11 Tf -<4c697374> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -394.74 724.105 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -400.24 724.105 Td -/F3.0 11 Tf -<6f66> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -411.24 724.105 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -416.74 724.105 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -422.24 724.105 Td -/F3.0 11 Tf -<247b696e7075742e73746f726549647d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -510.24 724.105 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -515.74 724.105 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -521.24 724.105 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.6 0.6 0.6 scn -0.6 0.6 0.6 SCN - -BT -59.24 694.625 Td -/F3.0 11 Tf -<2f2f206f7220696e2061207265706f727420766965772773207469746c65206f72206669656c6420666f726d756c61733a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 679.885 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -64.74 679.885 Td -/F3.0 11 Tf -<776974685469746c654669656c6473> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -147.24 679.885 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.46667 0.53333 scn -0.0 0.46667 0.53333 SCN - -BT -152.74 679.885 Td -/F3.0 11 Tf -<4c697374> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -174.74 679.885 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -180.24 679.885 Td -/F3.0 11 Tf -<6f66> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -191.24 679.885 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -196.74 679.885 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -202.24 679.885 Td -/F3.0 11 Tf -<247b696e7075742e73746f726549647d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -290.24 679.885 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -295.74 679.885 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -301.24 679.885 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.4 0.6 scn -0.0 0.4 0.6 SCN - -BT -59.24 665.145 Td -/F3.0 11 Tf -<6e6577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -75.74 665.145 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -81.24 665.145 Td -/F3.0 11 Tf -<515265706f72744669656c64> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -147.24 665.145 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -152.74 665.145 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -158.24 665.145 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -163.74 665.145 Td -/F3.0 11 Tf -<776974684e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -207.74 665.145 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -213.24 665.145 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -218.74 665.145 Td -/F3.0 11 Tf -<73746f72654964> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -257.24 665.145 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -262.74 665.145 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -268.24 665.145 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -273.74 665.145 Td -/F3.0 11 Tf -<77697468466f726d756c61> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -334.24 665.145 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -339.74 665.145 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -345.24 665.145 Td -/F3.0 11 Tf -<247b696e7075742e73746f726549647d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -433.24 665.145 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -438.74 665.145 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 627.266 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.56136 Tw - -BT -66.24 627.266 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.56136 Tw - -BT -66.24 627.266 Td -/F3.0 10.5 Tf -<64617461536f7572636573> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.56136 Tw - -BT -123.99 627.266 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.56136 Tw - -BT -133.80671 627.266 Td -/F2.0 10.5 Tf -<4c697374206f6620515265706f727444617461536f757263652c205265717569726564> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.56136 Tw - -BT -332.51279 627.266 Td -/F1.0 10.5 Tf -<202d20446566696e6974696f6e73206f662074686520736f7572636573206f66206461746120666f7220746865> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 611.486 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 611.486 Td -/F1.0 10.5 Tf -<7265706f72742e204174206c65617374206f6e652069732072657175697265642e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 579.656 Td -/F2.0 10.5 Tf -<515265706f727444617461536f75726365> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.25128 Tw - -BT -48.24 553.826 Td -/F1.0 10.5 Tf -<4461746120736f757263657320666f7220515151205265706f7274732063616e20656974686572207265666572656e636520> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -1.25128 Tw - -BT -313.56826 553.826 Td -/F1.0 10.5 Tf -[<5151512054> 29.78516 <61626c6573>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.25128 Tw - -BT -372.9708 553.826 Td -/F1.0 10.5 Tf -<2077697468696e207468652051515120496e7374616e63652c206f722074686579> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.59339 Tw - -BT -48.24 538.046 Td -/F1.0 10.5 Tf -<63616e2070726f7669646520637573746f6d20636f646520696e2074686520666f726d206f66206120> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.59339 Tw - -BT -261.03955 538.046 Td -/F3.0 10.5 Tf -<436f64655265666572656e6365> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.59339 Tw - -BT -329.28955 538.046 Td -/F1.0 10.5 Tf -<20746f206120> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.59339 Tw - -BT -354.88374 538.046 Td -/F3.0 10.5 Tf -<537570706c696572> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.59339 Tw - -BT -396.88374 538.046 Td -/F1.0 10.5 Tf -<2c20666f72207573652063617365732073756368206173206120737461746963> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 522.266 Td -/F1.0 10.5 Tf -<646174612074616220696e20616e20457863656c207265706f72742e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 494.486 Td -/F2.0 10.5 Tf -<515265706f727444617461536f757263652050726f706572746965733a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 466.706 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 466.706 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 466.706 Td -/F3.0 10.5 Tf -<6e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -87.24 466.706 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -95.934 466.706 Td -/F2.0 10.5 Tf -<537472696e672c205265717569726564> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -183.3255 466.706 Td -/F1.0 10.5 Tf -<202d20556e69717565206e616d6520666f7220746865206461746120736f757263652077697468696e2069747320636f6e7461696e696e67205265706f72742e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 444.926 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -1.33788 Tw - -BT -66.24 444.926 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.33788 Tw - -BT -66.24 444.926 Td -/F3.0 10.5 Tf -<736f757263655461626c65> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.33788 Tw - -BT -123.99 444.926 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.33788 Tw - -BT -135.35977 444.926 Td -/F2.0 10.5 Tf -<537472696e672c20436f6e646974696f6e616c> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.33788 Tw - -BT -237.19315 444.926 Td -/F1.0 10.5 Tf -<202d205265666572656e636520746f206120> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -1.33788 Tw - -BT -326.49656 444.926 Td -/F1.0 10.5 Tf -[<5151512054> 29.78516 <61626c65>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.33788 Tw - -BT -381.2502 444.926 Td -/F1.0 10.5 Tf -<20696e207468652051515120496e7374616e63652c20776869636820746865> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 429.146 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 429.146 Td -/F1.0 10.5 Tf -<6461746120736f75726365207175657269657320646174612066726f6d2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 407.366 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.62441 Tw - -BT -66.24 407.366 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.62441 Tw - -BT -66.24 407.366 Td -/F3.0 10.5 Tf -<717565727946696c746572> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.62441 Tw - -BT -123.99 407.366 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.62441 Tw - -BT -133.93281 407.366 Td -/F2.0 10.5 Tf -<51517565727946696c746572> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.62441 Tw - -BT -204.61881 407.366 Td -/F1.0 10.5 Tf -<202d204966206120> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.62441 Tw - -BT -234.87844 407.366 Td -/F3.0 10.5 Tf -<736f757263655461626c65> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.62441 Tw - -BT -292.62844 407.366 Td -/F1.0 10.5 Tf -<20697320646566696e65642c207468656e207468652066696c746572207370656369666965642068657265206973207573656420746f> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 391.586 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 391.586 Td -/F1.0 10.5 Tf -[<66696c74657220616e6420736f727420746865207265636f72647320717565726965642066726f6d2074686174207461626c65207768656e2067656e6572> 20.01953 <6174696e6720746865207265706f72742e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 369.806 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -1.48095 Tw - -BT -66.24 369.806 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.48095 Tw - -BT -66.24 369.806 Td -/F3.0 10.5 Tf -<73746174696344617461537570706c696572> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.48095 Tw - -BT -160.74 369.806 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.48095 Tw - -BT -172.39591 369.806 Td -/F2.0 10.5 Tf -<51436f64655265666572656e63652c20436f6e646974696f6e616c> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.48095 Tw - -BT -330.05386 369.806 Td -/F1.0 10.5 Tf -<202d205265666572656e636520746f20637573746f6d20636f64652077686963682063616e206265> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 354.026 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 354.026 Td -/F1.0 10.5 Tf -<7573656420746f20737570706c7920746865206461746120666f7220746865206461746120736f757263652c20617320616e20616c7465726e617469766520746f207175657279696e67206120> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -439.3155 354.026 Td -/F3.0 10.5 Tf -<736f757263655461626c65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -497.0655 354.026 Td -/F1.0 10.5 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 332.246 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 332.246 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 332.246 Td -/F1.0 10.5 Tf -<4d757374206265206120> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -135.2805 332.246 Td -/F3.0 10.5 Tf -<4a415641> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -156.2805 332.246 Td -/F1.0 10.5 Tf -<20636f64652074797065> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 310.466 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 310.466 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 310.466 Td -/F1.0 10.5 Tf -<4d757374206265206120> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -135.2805 310.466 Td -/F3.0 10.5 Tf -<5245504f52545f5354415449435f444154415f535550504c494552> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -277.0305 310.466 Td -/F1.0 10.5 Tf -<20636f64652075736167652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 288.686 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 288.686 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 288.686 Td -/F1.0 10.5 Tf -<546865207265666572656e63656420636c617373206d75737420696d706c656d656e742074686520696e746572666163653a20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -343.863 288.686 Td -/F3.0 10.5 Tf -<537570706c6965723c4c6973743c4c6973743c53657269616c697a61626c653e3e3e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -522.363 288.686 Td -/F1.0 10.5 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 256.856 Td -/F2.0 10.5 Tf -<515265706f727456696577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.23261 Tw - -BT -48.24 231.026 Td -/F1.0 10.5 Tf -<5265706f727420566965777320636f6e74726f6c20686f772074686520736f75726365206461746120666f722061207265706f7274206973206f7267616e697a656420616e642070726573656e74656420746f20746865207573657220696e20746865> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.16009 Tw - -BT -48.24 215.246 Td -/F1.0 10.5 Tf -<6f7574707574207265706f72742066696c652e20496620612044617461536f75726365206465736372696265732074686520726f777320666f722061207265706f72742028652e672e2c2077686174207461626c652070726f76696465732077686174> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.05646 Tw - -BT -48.24 199.466 Td -/F1.0 10.5 Tf -[<7265636f726473292c207468656e20612056696577206d61> 20.01953 <792062652074686f75676874206f662061732064657363726962696e672074686520636f6c756d6e7320696e20746865207265706f72742e20412073696e676c65207265706f72742063616e>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.86774 Tw - -BT -48.24 183.686 Td -/F1.0 10.5 Tf -[<68617665206d756c7469706c652076696577732c207370656369666963616c6c79> 89.84375 <2c20666f7220746865207573652d6361736520776865726520616e20457863656c2066696c65206973206265696e672067656e6572> 20.01953 <617465642c20696e207768696368>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 167.906 Td -/F1.0 10.5 Tf -<63617365206561636820566965772063726561746573206120746162206f722073686565742077697468696e2074686520> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -289.0575 167.906 Td -/F3.0 10.5 Tf -<786c7378> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -310.0575 167.906 Td -/F1.0 10.5 Tf -<2066696c652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 140.126 Td -/F2.0 10.5 Tf -<515265706f7274566965772050726f706572746965733a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 112.346 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 112.346 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 112.346 Td -/F3.0 10.5 Tf -<6e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -87.24 112.346 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -95.934 112.346 Td -/F2.0 10.5 Tf -<537472696e672c205265717569726564> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -183.3255 112.346 Td -/F1.0 10.5 Tf -<202d20556e69717565206e616d6520666f722074686520766965772077697468696e2069747320636f6e7461696e696e67205265706f72742e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 90.566 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 90.566 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 90.566 Td -/F3.0 10.5 Tf -<6c6162656c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -92.49 90.566 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -101.184 90.566 Td -/F2.0 10.5 Tf -<537472696e67> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -133.6185 90.566 Td -/F1.0 10.5 Tf -<202d20557365642061732061207368656574202874616229206c6162656c20696e20457863656c20666f726d6174746564207265706f7274732e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 68.786 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 68.786 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 68.786 Td -/F3.0 10.5 Tf -<74797065> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -87.24 68.786 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -95.934 68.786 Td -/F2.0 10.5 Tf -[<656e756d206f662054> 60.05859 <41424c452c2053554d4d4152> 29.78516 <59> 80.07812 <2c20504956> 20.01953 <4f> 20.01953 <54> 89.84375 <2e205265717569726564>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -331.17805 68.786 Td -/F1.0 10.5 Tf -<202d20446566696e6573207468652074797065206f662076696577206265696e6720646566696e65642e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.0 0.0 0.0 scn -0.0 0.0 0.0 SCN -1 w -0 J -0 j -[] 0 d -/Stamp2 Do -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -49.24 14.263 Td -/F1.0 9 Tf -<34> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -Q -Q - -endstream -endobj -43 0 obj -<< /Type /Page -/Parent 3 0 R -/MediaBox [0 0 595.28 841.89] -/CropBox [0 0 595.28 841.89] -/BleedBox [0 0 595.28 841.89] -/TrimBox [0 0 595.28 841.89] -/ArtBox [0 0 595.28 841.89] -/Contents 42 0 R -/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] -/Font << /F3.0 27 0 R -/F1.0 8 0 R -/F2.0 17 0 R -/F1.1 36 0 R ->> -/XObject << /Stamp2 88 0 R ->> ->> -/Annots [45 0 R 46 0 R] ->> -endobj -44 0 obj -[43 0 R /XYZ 0 595.67 null] -endobj -45 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Tables{relfilesuffix}) ->> -/Subtype /Link -/Rect [313.56826 550.76 372.9708 565.04] -/Type /Annot ->> -endobj -46 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (Tables{relfilesuffix}) ->> -/Subtype /Link -/Rect [326.49656 441.86 381.2502 456.14] -/Type /Annot ->> -endobj -47 0 obj -[43 0 R /XYZ 0 272.87 null] -endobj -48 0 obj -<< /Length 25608 ->> -stream -q - --0.5 Tc - -0.0 Tc - --0.5 Tc -/DeviceRGB cs -0.2 0.2 0.2 scn -/DeviceRGB CS -0.2 0.2 0.2 SCN - -BT -74.954 793.926 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 793.926 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 793.926 Td -/F2.0 10.5 Tf -[<54> 60.05859 <41424c45>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -119.09938 793.926 Td -/F1.0 10.5 Tf -<2076696577732061726520612073696d706c65206c697374696e67206f6620746865207265636f7264732066726f6d20746865206461746120736f757263652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 772.146 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.9683 Tw - -BT -84.24 772.146 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.9683 Tw - -BT -84.24 772.146 Td -/F2.0 10.5 Tf -[<53554d4d4152> 29.78516 <59>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.9683 Tw - -BT -140.49076 772.146 Td -/F1.0 10.5 Tf -[<2076696577732061726520657373656e7469616c6c79207072652d636f6d7075746564205069766f742054> 29.78516 <61626c65732e205468617420697320746f207361> 20.01953 <79> 89.84375 <2c20746865206167677265676174696f6e>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -1.01049 Tw - -BT -84.24 756.366 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.01049 Tw - -BT -84.24 756.366 Td -/F1.0 10.5 Tf -[<646f6e652062> 20.01953 <792061205069766f742054> 29.78516 <61626c6520696e20612073707265616473686565742066696c6520697320646f6e652062> 20.01953 <7920515151207768696c652067656e6572> 20.01953 <6174696e6720746865207265706f72742e20496e>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.08405 Tw - -BT -84.24 740.586 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.08405 Tw - -BT -84.24 740.586 Td -/F1.0 10.5 Tf -[<74686973207761> 20.01953 <79> 89.84375 <2c2061206e6f6e2d7370726561647368656574207265706f72742028652e672e2c20504446206f72204353> 20.01953 <56292063616e20686176652073756d6d6172697a656420646174612c2061732074686f756768206974>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -84.24 724.806 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 724.806 Td -/F1.0 10.5 Tf -[<776572652061205069766f742054> 29.78516 <61626c6520696e2061206c6976652073707265616473686565742e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 703.026 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.50261 Tw - -BT -84.24 703.026 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.50261 Tw - -BT -84.24 703.026 Td -/F2.0 10.5 Tf -[<504956> 20.01953 <4f> 20.01953 <54>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.50261 Tw - -BT -117.15709 703.026 Td -/F1.0 10.5 Tf -[<2076696577732070726f647563652061637475616c205069766f742054> 29.78516 <61626c65732c20616e6420617265206f6e6c7920737570706f7274656420696e20457863656c2066696c657320>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.50261 Tw - -BT -486.17428 703.026 Td -/F5.0 10.5 Tf -<28616e6420617265206e6f74> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -84.24 687.246 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 687.246 Td -/F5.0 10.5 Tf -<737570706f72746564206174207468652074696d65206f6620746869732077726974696e6729> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -263.8425 687.246 Td -/F1.0 10.5 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 665.466 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.52603 Tw - -BT -66.24 665.466 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.52603 Tw - -BT -66.24 665.466 Td -/F3.0 10.5 Tf -<64617461536f757263654e616d65> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.52603 Tw - -BT -139.74 665.466 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.52603 Tw - -BT -149.48607 665.466 Td -/F2.0 10.5 Tf -<537472696e672c205265717569726564> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.52603 Tw - -BT -237.4036 665.466 Td -/F1.0 10.5 Tf -<202d205265666572656e636520746f20612044617461536f757263652077697468696e20746865207265706f72742c2074686174206973207573656420746f> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 649.686 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 649.686 Td -/F1.0 10.5 Tf -[<70726f766964652074686520726f777320666f72207468652076696577> 69.82422 <2e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 627.906 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.95067 Tw - -BT -66.24 627.906 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.95067 Tw - -BT -66.24 627.906 Td -/F3.0 10.5 Tf -<76617269616e636544617461536f757263654e616d65> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.95067 Tw - -BT -181.74 627.906 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.95067 Tw - -BT -192.33533 627.906 Td -/F2.0 10.5 Tf -<537472696e67> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.95067 Tw - -BT -224.76983 627.906 Td -/F1.0 10.5 Tf -<202d204f7074696f6e616c207265666572656e636520746f2061207365636f6e642044617461536f757263652077697468696e20746865207265706f72742c> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 612.126 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 612.126 Td -/F1.0 10.5 Tf -<74686174206973207573656420696e20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -138.7215 612.126 Td -/F4.0 10.5 Tf -<53554d4d415259> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -175.4715 612.126 Td -/F1.0 10.5 Tf -<207479706520766965777320666f7220636f6d707574696e672076617269616e6365732e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 590.346 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.06255 Tw - -BT -84.24 590.346 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.06255 Tw - -BT -84.24 590.346 Td -/F1.0 10.5 Tf -[<46> 40.03906 <6f72206578616d706c652c20676976656e2061204461746120536f75726365207769746820612066696c74657220746861742073656c6563747320616c6c2073616c6573207265636f72647320666f72206120676976656e20796561722c2061>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -5.29787 Tw - -BT -84.24 574.566 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -5.29787 Tw - -BT -84.24 574.566 Td -/F1.0 10.5 Tf -[<56> 60.05859 <617269616e6365204461746120536f75726365206d61> 20.01953 <79206861766520612066696c74657220746861742073656c65637473207468652070726576696f757320796561722c20666f7220646f696e67>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -84.24 558.786 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 558.786 Td -/F1.0 10.5 Tf -<636f6d7061726973736f6e732e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 537.006 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -2.068 Tw - -BT -66.24 537.006 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -2.068 Tw - -BT -66.24 537.006 Td -/F3.0 10.5 Tf -<7069766f744669656c6473> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.068 Tw - -BT -123.99 537.006 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.068 Tw - -BT -136.82001 537.006 Td -/F2.0 10.5 Tf -<4c697374206f6620537472696e672c20436f6e646974696f6e616c> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.068 Tw - -BT -279.56602 537.006 Td -/F1.0 10.5 Tf -[<202d2046> 40.03906 <6f7220>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.068 Tw - -BT -313.95163 537.006 Td -/F2.0 10.5 Tf -[<53554d4d4152> 29.78516 <59>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.068 Tw - -BT -370.20238 537.006 Td -/F1.0 10.5 Tf -<206f7220> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.068 Tw - -BT -390.78139 537.006 Td -/F2.0 10.5 Tf -[<504956> 20.01953 <4f> 20.01953 <54>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.068 Tw - -BT -423.69848 537.006 Td -/F1.0 10.5 Tf -<20747970652076696577732c207370656369667920746865> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 521.226 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 521.226 Td -/F1.0 10.5 Tf -<6669656c642873292075736564206173207069766f7420726f77732e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 499.446 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -1.81597 Tw - -BT -84.24 499.446 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.81597 Tw - -BT -84.24 499.446 Td -/F1.0 10.5 Tf -[<46> 40.03906 <6f72206578616d706c652c20696e20612073756d6d6172792076696577206f66206f72646572732c20796f75206d61> 20.01953 <7920227069766f7422206f6e2074686520>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.81597 Tw - -BT -441.94655 499.446 Td -/F2.0 10.5 Tf -<637573746f6d65724964> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.81597 Tw - -BT -503.05655 499.446 Td -/F1.0 10.5 Tf -<206669656c642c20746f> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -84.24 483.666 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 483.666 Td -/F1.0 10.5 Tf -<70726f64756365206f6e6520726f77207065722d637573746f6d65722c207769746820616767726567617465206461746120666f72207468617420637573746f6d65722e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 461.886 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.182 Tw - -BT -66.24 461.886 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.182 Tw - -BT -66.24 461.886 Td -/F3.0 10.5 Tf -<7469746c65466f726d6174> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.182 Tw - -BT -123.99 461.886 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.182 Tw - -BT -133.04801 461.886 Td -/F2.0 10.5 Tf -<537472696e67> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.182 Tw - -BT -165.48251 461.886 Td -/F1.0 10.5 Tf -[<202d204a6176612046> 40.03906 <6f726d617420537472696e672c2075736564207769746820>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.182 Tw - -BT -325.87313 461.886 Td -/F3.0 10.5 Tf -<7469746c654669656c6473> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.182 Tw - -BT -383.62313 461.886 Td -/F1.0 10.5 Tf -[<2028696620676976656e292c20746f2070726f647563652061207469746c6520726f77> 69.82422 <2c>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 446.106 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 446.106 Td -/F1.0 10.5 Tf -[<652e672e2c20666972737420726f7720696e20746865207669657720286265666f726520616e> 20.01953 <7920726f77732066726f6d20746865206461746120736f75726365292e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 424.326 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -2.03362 Tw - -BT -66.24 424.326 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -2.03362 Tw - -BT -66.24 424.326 Td -/F3.0 10.5 Tf -<7469746c654669656c6473> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.03362 Tw - -BT -123.99 424.326 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.03362 Tw - -BT -136.75124 424.326 Td -/F2.0 10.5 Tf -<4c697374206f6620537472696e672c20436f6e646974696f6e616c> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.03362 Tw - -BT -279.39411 424.326 Td -/F1.0 10.5 Tf -<202d2055736564207769746820> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -2.03362 Tw - -BT -348.7121 424.326 Td -/F3.0 10.5 Tf -<7469746c65466f726d6174> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.03362 Tw - -BT -406.4621 424.326 Td -/F1.0 10.5 Tf -[<2c20746f2070726f766964652076616c75657320666f7220616e> 20.01953 <79>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.27267 Tw - -BT -66.24 408.546 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.27267 Tw - -BT -66.24 408.546 Td -/F1.0 10.5 Tf -[<666f726d6174207370656369666965727320696e2074686520666f726d617420737472696e672e2053> 20.01953 <796e74617820746f207265666572656e63652061206669656c642028652e672e2c2066726f6d2061207265706f727420696e707574206669656c6429>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 392.766 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 392.766 Td -/F1.0 10.5 Tf -<69733a20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -80.0475 392.766 Td -/F3.0 10.5 Tf -<247b696e7075742e4e414d457d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -148.2975 392.766 Td -/F1.0 10.5 Tf -<2c20776865726520> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -188.2395 392.766 Td -/F3.0 10.5 Tf -<4e414d45> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -209.2395 392.766 Td -/F1.0 10.5 Tf -<2069732074686520> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -241.4535 392.766 Td -/F3.0 10.5 Tf -<6e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -262.4535 392.766 Td -/F1.0 10.5 Tf -<20617474726962757465206f662074686520696e7075744669656c642e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 370.986 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 370.986 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 370.986 Td -/F1.0 10.5 Tf -<4578616d706c65206f66207573696e6720> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -173.2275 370.986 Td -/F3.0 10.5 Tf -<7469746c65466f726d6174> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -230.9775 370.986 Td -/F1.0 10.5 Tf -<20616e6420> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -255.5265 370.986 Td -/F3.0 10.5 Tf -<7469746c654669656c6473> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -313.2765 370.986 Td -/F1.0 10.5 Tf -<3a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.96078 0.96078 0.96078 scn -52.24 355.17 m -543.04 355.17 l -545.24914 355.17 547.04 353.37914 547.04 351.17 c -547.04 233.99 l -547.04 231.78086 545.24914 229.99 543.04 229.99 c -52.24 229.99 l -50.03086 229.99 48.24 231.78086 48.24 233.99 c -48.24 351.17 l -48.24 353.37914 50.03086 355.17 52.24 355.17 c -h -f -0.8 0.8 0.8 SCN -0.75 w -52.24 355.17 m -543.04 355.17 l -545.24914 355.17 547.04 353.37914 547.04 351.17 c -547.04 233.99 l -547.04 231.78086 545.24914 229.99 543.04 229.99 c -52.24 229.99 l -50.03086 229.99 48.24 231.78086 48.24 233.99 c -48.24 351.17 l -48.24 353.37914 50.03086 355.17 52.24 355.17 c -h -S -Q -0.6 0.6 0.6 scn -0.6 0.6 0.6 SCN - -BT -59.24 332.345 Td -/F3.0 11 Tf -<2f2f20676976656e20746865736520696e7075744669656c64733a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.4 0.6 scn -0.0 0.4 0.6 SCN - -BT -59.24 317.605 Td -/F3.0 11 Tf -<6e6577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -75.74 317.605 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -81.24 317.605 Td -/F3.0 11 Tf -<514669656c644d65746144617461> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -158.24 317.605 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -163.74 317.605 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -169.24 317.605 Td -/F3.0 11 Tf -<737461727444617465> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -218.74 317.605 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -224.24 317.605 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -229.74 317.605 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -235.24 317.605 Td -/F3.0 11 Tf -<514669656c6454797065> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -290.24 317.605 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -295.74 317.605 Td -/F3.0 11 Tf -<44415445> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -317.74 317.605 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.4 0.6 scn -0.0 0.4 0.6 SCN - -BT -59.24 302.865 Td -/F3.0 11 Tf -<6e6577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -75.74 302.865 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -81.24 302.865 Td -/F3.0 11 Tf -<514669656c644d65746144617461> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -158.24 302.865 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -163.74 302.865 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -169.24 302.865 Td -/F3.0 11 Tf -<656e6444617465> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -207.74 302.865 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -213.24 302.865 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -218.74 302.865 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -224.24 302.865 Td -/F3.0 11 Tf -<514669656c6454797065> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -279.24 302.865 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -284.74 302.865 Td -/F3.0 11 Tf -<44415445> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -306.74 302.865 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.6 0.6 0.6 scn -0.6 0.6 0.6 SCN - -BT -59.24 273.385 Td -/F3.0 11 Tf -<2f2f206120766965772063616e20686176652061207469746c6520726f77206c696b6520746869733a> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 258.645 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -64.74 258.645 Td -/F3.0 11 Tf -<776974685469746c65466f726d6174> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -147.24 258.645 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -152.74 258.645 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -158.24 258.645 Td -/F3.0 11 Tf -<5765656b6c792053616c6573205265706f7274202d202573202d202573> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -317.74 258.645 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -323.24 258.645 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 243.905 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -64.74 243.905 Td -/F3.0 11 Tf -<776974685469746c654669656c6473> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -147.24 243.905 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.46667 0.53333 scn -0.0 0.46667 0.53333 SCN - -BT -152.74 243.905 Td -/F3.0 11 Tf -<4c697374> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -174.74 243.905 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -180.24 243.905 Td -/F3.0 11 Tf -<6f66> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -191.24 243.905 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -196.74 243.905 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -202.24 243.905 Td -/F3.0 11 Tf -<247b696e7075742e7374617274446174657d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -301.24 243.905 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -306.74 243.905 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -312.24 243.905 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -317.74 243.905 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -323.24 243.905 Td -/F3.0 11 Tf -<247b696e7075742e656e64446174657d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -411.24 243.905 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -416.74 243.905 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -422.24 243.905 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 206.026 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -1.27013 Tw - -BT -66.24 206.026 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.27013 Tw - -BT -66.24 206.026 Td -/F3.0 10.5 Tf -<696e636c756465486561646572526f77> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.27013 Tw - -BT -150.24 206.026 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.27013 Tw - -BT -161.47427 206.026 Td -/F2.0 10.5 Tf -<626f6f6c65616e2c2064656661756c742074727565> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.27013 Tw - -BT -276.13353 206.026 Td -/F1.0 10.5 Tf -<202d20496e6469636174696f6e207468617420666972737420726f77206f662074686520766965772073686f756c6420626520746865> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 190.246 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 190.246 Td -/F1.0 10.5 Tf -<636f6c756d6e206c6162656c732e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 168.466 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 168.466 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 168.466 Td -/F1.0 10.5 Tf -[<496620747275652c207468656e2068656164657220726f772069732070757420696e207468652076696577> 69.82422 <2e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 146.686 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 146.686 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 146.686 Td -/F1.0 10.5 Tf -[<49662066616c73652c207468656e206e6f2068656164657220726f772069732070757420696e207468652076696577> 69.82422 <2e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 124.906 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -1.22743 Tw - -BT -66.24 124.906 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.22743 Tw - -BT -66.24 124.906 Td -/F3.0 10.5 Tf -<696e636c756465546f74616c526f77> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.22743 Tw - -BT -144.99 124.906 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.22743 Tw - -BT -156.13887 124.906 Td -/F2.0 10.5 Tf -<626f6f6c65616e2c2064656661756c742066616c7365> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.22743 Tw - -BT -273.36923 124.906 Td -/F1.0 10.5 Tf -<202d20496e6469636174696f6e2074686174206120746f74616c7320726f772073686f756c6420626520616464656420746f20746865> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 109.126 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 109.126 Td -/F1.0 10.5 Tf -[<76696577> 69.82422 <2e20416c6c206e756d6572696320636f6c756d6e73206172652073756d6d656420746f2070726f647563652076616c75657320696e2074686520746f74616c7320726f77> 69.82422 <2e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 87.346 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 87.346 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 87.346 Td -/F1.0 10.5 Tf -[<496620747275652c207468656e20746f74616c7320726f772069732070757420696e207468652076696577> 69.82422 <2e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 65.566 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 65.566 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -84.24 65.566 Td -/F1.0 10.5 Tf -[<49662066616c73652c207468656e206e6f20746f74616c7320726f772069732070757420696e207468652076696577> 69.82422 <2e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.0 0.0 0.0 scn -0.0 0.0 0.0 SCN -1 w -0 J -0 j -[] 0 d -/Stamp1 Do -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -541.009 14.263 Td -/F1.0 9 Tf -<35> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -Q -Q - -endstream -endobj -49 0 obj -<< /Type /Page -/Parent 3 0 R -/MediaBox [0 0 595.28 841.89] -/CropBox [0 0 595.28 841.89] -/BleedBox [0 0 595.28 841.89] -/TrimBox [0 0 595.28 841.89] -/ArtBox [0 0 595.28 841.89] -/Contents 48 0 R -/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] -/Font << /F1.1 36 0 R -/F2.0 17 0 R -/F1.0 8 0 R -/F5.0 50 0 R -/F3.0 27 0 R -/F4.0 24 0 R ->> -/XObject << /Stamp1 87 0 R ->> ->> ->> -endobj -50 0 obj -<< /Type /Font -/BaseFont /8192eb+NotoSerif-Italic -/Subtype /TrueType -/FontDescriptor 114 0 R -/FirstChar 32 -/LastChar 255 -/Widths 116 0 R -/ToUnicode 115 0 R ->> -endobj -51 0 obj -<< /Length 10905 ->> -stream -q - --0.5 Tc - -0.0 Tc - --0.5 Tc -/DeviceRGB cs -0.2 0.2 0.2 scn -/DeviceRGB CS -0.2 0.2 0.2 SCN - -BT -56.8805 793.926 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.88437 Tw - -BT -66.24 793.926 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.88437 Tw - -BT -66.24 793.926 Td -/F3.0 10.5 Tf -<696e636c7564655069766f74537562546f74616c73> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.88437 Tw - -BT -176.49 793.926 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.88437 Tw - -BT -186.95275 793.926 Td -/F2.0 10.5 Tf -<626f6f6c65616e2c2064656661756c742066616c7365> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.88437 Tw - -BT -303.49699 793.926 Td -/F1.0 10.5 Tf -[<202d2046> 40.03906 <6f72206120>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.88437 Tw - -BT -343.83657 793.926 Td -/F2.0 10.5 Tf -[<53554d4d4152> 29.78516 <59>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.88437 Tw - -BT -400.08733 793.926 Td -/F1.0 10.5 Tf -<206f7220> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.88437 Tw - -BT -418.29907 793.926 Td -/F2.0 10.5 Tf -[<504956> 20.01953 <4f> 20.01953 <54>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.88437 Tw - -BT -451.21616 793.926 Td -/F1.0 10.5 Tf -[<20747970652076696577> 69.82422 <2c206966207468657265>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.89773 Tw - -BT -66.24 778.146 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.89773 Tw - -BT -66.24 778.146 Td -/F1.0 10.5 Tf -<617265206d6f7265207468616e203120> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.89773 Tw - -BT -152.60243 778.146 Td -/F2.0 10.5 Tf -<7069766f744669656c6473> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.89773 Tw - -BT -211.90643 778.146 Td -/F1.0 10.5 Tf -<206265696e6720757365642c2074686973206669656c6420697320616e20696e6469636174696f6e20746861742065616368206869676865722d6c6576656c207069766f74> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 762.366 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 762.366 Td -/F1.0 10.5 Tf -<73686f756c6420696e636c756465207375622d746f74616c732e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 740.586 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 740.586 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN -1.0 1.0 0.0 scn -84.24 736.52 124.57679 16.28 re -f -0.2 0.2 0.2 scn - -BT -85.24 740.586 Td -/F1.0 10.5 Tf -[<54> 20.01953 <4f444f202d2070726f76696465206578616d706c65>] TJ -ET - - -BT -84.24 740.586 Td -/F1.0 10.5 Tf -<202020> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 718.806 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.55604 Tw - -BT -66.24 718.806 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.55604 Tw - -BT -66.24 718.806 Td -/F3.0 10.5 Tf -<636f6c756d6e73> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.55604 Tw - -BT -102.99 718.806 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.55604 Tw - -BT -112.79608 718.806 Td -/F2.0 10.5 Tf -<4c697374206f6620515265706f72744669656c642c207265717569726564> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.55604 Tw - -BT -274.8202 718.806 Td -/F1.0 10.5 Tf -[<202d20446566696e6974696f6e206f662074686520636f6c756d6e7320746f2061707065617220696e207468652076696577> 69.82422 <2e20536565>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 703.026 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 703.026 Td -/F1.0 10.5 Tf -<73656374696f6e206f6e20515265706f72744669656c6420666f722064657461696c732e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 681.246 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -0.21002 Tw - -BT -66.24 681.246 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.21002 Tw - -BT -66.24 681.246 Td -/F3.0 10.5 Tf -<6f7264657242794669656c6473> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.21002 Tw - -BT -134.49 681.246 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.21002 Tw - -BT -143.60404 681.246 Td -/F2.0 10.5 Tf -[<4c697374206f66205146696c7465724f7264657242> 20.01953 <79> 89.84375 <2c206f7074696f6e616c>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.21002 Tw - -BT -312.48753 681.246 Td -/F1.0 10.5 Tf -[<202d2046> 40.03906 <6f72206120>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.21002 Tw - -BT -350.1297 681.246 Td -/F2.0 10.5 Tf -[<53554d4d4152> 29.78516 <59>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.21002 Tw - -BT -406.38045 681.246 Td -/F1.0 10.5 Tf -<206f7220> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.21002 Tw - -BT -423.24349 681.246 Td -/F2.0 10.5 Tf -[<504956> 20.01953 <4f> 20.01953 <54>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.21002 Tw - -BT -456.16058 681.246 Td -/F1.0 10.5 Tf -[<20747970652076696577> 69.82422 <2c20686f7720746f>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 665.466 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 665.466 Td -/F1.0 10.5 Tf -<736f72742074686520726f77732e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 643.686 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -4.40275 Tw - -BT -66.24 643.686 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -4.40275 Tw - -BT -66.24 643.686 Td -/F3.0 10.5 Tf -<7265636f72645472616e73666f726d53746570> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -4.40275 Tw - -BT -165.99 643.686 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -4.40275 Tw - -BT -183.4895 643.686 Td -/F2.0 10.5 Tf -<51436f64655265666572656e63652c20737562636c617373206f6620> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -4.40275 Tw - -BT -351.39425 643.686 Td -/F4.0 10.5 Tf -<41627374726163745472616e73666f726d53746570> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -4.40275 Tw - -BT -461.64425 643.686 Td -/F1.0 10.5 Tf -<202d20437573746f6d20636f6465> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -1.35345 Tw - -BT -66.24 627.906 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.35345 Tw - -BT -66.24 627.906 Td -/F1.0 10.5 Tf -[<7265666572656e636520746861742063616e206265207573656420746f207472> 20.01953 <616e73666f726d207265636f72647320616674657220746865792061726520717565726965642066726f6d20746865206461746120736f757263652c>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -1.04279 Tw - -BT -66.24 612.126 Td -ET - - -0.0 Tw -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.04279 Tw - -BT -66.24 612.126 Td -/F1.0 10.5 Tf -[<616e64206265666f726520746865792061726520706c6163656420696e746f207468652076696577> 69.82422 <2e2043616e206265207573656420746f207472> 20.01953 <616e73666f726d206f7220637573746f6d697a652076616c7565732c206f7220746f>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 596.346 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 596.346 Td -/F1.0 10.5 Tf -<6c6f6f6b207570206164646974696f6e616c2076616c75657320746f2061646420746f20746865207265706f72742e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 574.566 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 574.566 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN -1.0 1.0 0.0 scn -84.24 570.5 124.57679 16.28 re -f -0.2 0.2 0.2 scn - -BT -85.24 574.566 Td -/F1.0 10.5 Tf -[<54> 20.01953 <4f444f202d2070726f76696465206578616d706c65>] TJ -ET - - -BT -84.24 574.566 Td -/F1.0 10.5 Tf -<202020> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 552.786 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -6.90283 Tw - -BT -66.24 552.786 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -6.90283 Tw - -BT -66.24 552.786 Td -/F3.0 10.5 Tf -<76696577437573746f6d697a6572> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -6.90283 Tw - -BT -139.74 552.786 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -6.90283 Tw - -BT -162.23967 552.786 Td -/F2.0 10.5 Tf -<51436f64655265666572656e63652c20696d706c656d656e746174696f6e206f6620696e7465726661636520> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -6.90283 Tw - -BT -436.79 552.786 Td -/F4.0 10.5 Tf -<46756e6374696f6e3c515265706f7274566965772c> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.29211 Tw - -BT -66.24 537.006 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -0.29211 Tw - -BT -66.24 537.006 Td -/F4.0 10.5 Tf -<515265706f7274566965773e> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -0.29211 Tw - -BT -129.24 537.006 Td -/F1.0 10.5 Tf -[<202d20437573746f6d20636f6465207265666572656e636520746861742063616e206265207573656420746f20637573746f6d697a6520746865207265706f72742076696577> 69.82422 <2c2061742072756e74696d652e>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 521.226 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 521.226 Td -/F1.0 10.5 Tf -<43616e20626520757365642c20666f72206578616d706c652c20746f2064796e616d6963616c6c7920646566696e6520746865207265706f7274d57320> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -369.228 521.226 Td -/F2.0 10.5 Tf -<636f6c756d6e73> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -414.315 521.226 Td -/F1.0 10.5 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -74.954 499.446 Td -/F1.1 10.5 Tf -<21> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -84.24 499.446 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN -1.0 1.0 0.0 scn -84.24 495.38 124.57679 16.28 re -f -0.2 0.2 0.2 scn - -BT -85.24 499.446 Td -/F1.0 10.5 Tf -[<54> 20.01953 <4f444f202d2070726f76696465206578616d706c65>] TJ -ET - - -BT -84.24 499.446 Td -/F1.0 10.5 Tf -<202020> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 469.218 Td -/F2.0 9 Tf -<515265706f72744669656c64> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.0 0.0 0.0 scn -0.0 0.0 0.0 SCN -1 w -0 J -0 j -[] 0 d -/Stamp2 Do -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -49.24 14.263 Td -/F1.0 9 Tf -<36> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -Q -Q - -endstream -endobj -52 0 obj -<< /Type /Page -/Parent 3 0 R -/MediaBox [0 0 595.28 841.89] -/CropBox [0 0 595.28 841.89] -/BleedBox [0 0 595.28 841.89] -/TrimBox [0 0 595.28 841.89] -/ArtBox [0 0 595.28 841.89] -/Contents 51 0 R -/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] -/Font << /F1.0 8 0 R -/F3.0 27 0 R -/F2.0 17 0 R -/F1.1 36 0 R -/F4.0 24 0 R ->> -/XObject << /Stamp2 88 0 R ->> ->> ->> -endobj -53 0 obj -[52 0 R /XYZ 0 483.63 null] -endobj -54 0 obj -<< /Length 23645 ->> -stream -q -/DeviceRGB cs -0.2 0.2 0.2 scn -/DeviceRGB CS -0.2 0.2 0.2 SCN - -BT -48.24 782.394 Td -/F2.0 22 Tf -[<41> 20.01953 <6374696f6e73>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 741.146 Td -/F2.0 18 Tf -[<52656e64657254> 29.78516 <656d706c61746541> 20.01953 <6374696f6e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.26168 Tw - -BT -48.24 713.126 Td -/F1.0 10.5 Tf -<54686520> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -2.26168 Tw - -BT -71.92168 713.126 Td -/F4.0 10.5 Tf -<52656e64657254656d706c617465416374696f6e> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -2.26168 Tw - -BT -176.92168 713.126 Td -/F1.0 10.5 Tf -<20706572666f726d7320746865206a6f62206f662074616b696e6720612074656d706c617465202d20746861742069732c206120737472696e67206f6620636f64652c20696e2061> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.3896 Tw - -BT -48.24 697.346 Td -/F1.0 10.5 Tf -<74656d706c6174696e67206c616e67756167652c207375636820617320> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.25882 0.5451 0.79216 scn -0.25882 0.5451 0.79216 SCN - -1.3896 Tw - -BT -200.84038 697.346 Td -/F1.0 10.5 Tf -[<56> 60.05859 <656c6f63697479>] TJ -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.3896 Tw - -BT -240.35126 697.346 Td -/F1.0 10.5 Tf -<2c20616e64206d657267696e672069742077697468206120736574206f66206461746120286b6e6f776e206173206120636f6e74657874292c20746f> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 681.566 Td -/F1.0 10.5 Tf -<70726f6475636520736f6d65207573696e672d666163696e67206f75747075742c2073756368206173206120537472696e67206f662048544d4c2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 647.066 Td -/F2.0 13 Tf -<4578616d706c6573> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 616.456 Td -/F2.0 10.5 Tf -[<43616e6f6e6963616c2046> 40.03906 <6f726d>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.96078 0.96078 0.96078 scn -52.24 602.59 m -543.04 602.59 l -545.24914 602.59 547.04 600.79914 547.04 598.59 c -547.04 466.67 l -547.04 464.46086 545.24914 462.67 543.04 462.67 c -52.24 462.67 l -50.03086 462.67 48.24 464.46086 48.24 466.67 c -48.24 598.59 l -48.24 600.79914 50.03086 602.59 52.24 602.59 c -h -f -0.8 0.8 0.8 SCN -0.75 w -52.24 602.59 m -543.04 602.59 l -545.24914 602.59 547.04 600.79914 547.04 598.59 c -547.04 466.67 l -547.04 464.46086 545.24914 462.67 543.04 462.67 c -52.24 462.67 l -50.03086 462.67 48.24 464.46086 48.24 466.67 c -48.24 598.59 l -48.24 600.79914 50.03086 602.59 52.24 602.59 c -h -S -Q -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 579.765 Td -/F3.0 11 Tf -<52656e64657254656d706c617465496e707574> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -163.74 579.765 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -169.24 579.765 Td -/F3.0 11 Tf -<696e707574> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -196.74 579.765 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -202.24 579.765 Td -/F3.0 11 Tf -<3d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -207.74 579.765 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.4 0.6 scn -0.0 0.4 0.6 SCN - -BT -213.24 579.765 Td -/F3.0 11 Tf -<6e6577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -229.74 579.765 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -235.24 579.765 Td -/F3.0 11 Tf -<52656e64657254656d706c617465496e707574> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -339.74 579.765 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -345.24 579.765 Td -/F3.0 11 Tf -<71496e7374616e6365> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -394.74 579.765 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -400.24 579.765 Td -/F3.0 11 Tf -<3b> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 565.025 Td -/F3.0 11 Tf -<696e707574> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -86.74 565.025 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -92.24 565.025 Td -/F3.0 11 Tf -<73657453657373696f6e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -147.24 565.025 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -152.74 565.025 Td -/F3.0 11 Tf -<73657373696f6e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -191.24 565.025 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -196.74 565.025 Td -/F3.0 11 Tf -<3b> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 550.285 Td -/F3.0 11 Tf -<696e707574> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -86.74 550.285 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -92.24 550.285 Td -/F3.0 11 Tf -<736574436f6465> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -130.74 550.285 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -136.24 550.285 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -141.74 550.285 Td -/F3.0 11 Tf -<48656c6c6f2c20247b6e616d657d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -218.74 550.285 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -224.24 550.285 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -229.74 550.285 Td -/F3.0 11 Tf -<3b> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 535.545 Td -/F3.0 11 Tf -<696e707574> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -86.74 535.545 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -92.24 535.545 Td -/F3.0 11 Tf -<73657454656d706c61746554797065> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -174.74 535.545 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -180.24 535.545 Td -/F3.0 11 Tf -<54656d706c61746554797065> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -246.24 535.545 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -251.74 535.545 Td -/F3.0 11 Tf -<56454c4f43495459> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -295.74 535.545 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -301.24 535.545 Td -/F3.0 11 Tf -<3b> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 520.805 Td -/F3.0 11 Tf -<696e707574> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -86.74 520.805 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -92.24 520.805 Td -/F3.0 11 Tf -<736574436f6e74657874> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -147.24 520.805 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.46667 0.53333 scn -0.0 0.46667 0.53333 SCN - -BT -152.74 520.805 Td -/F3.0 11 Tf -<4d6170> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -169.24 520.805 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -174.74 520.805 Td -/F3.0 11 Tf -<6f66> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -185.74 520.805 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -191.24 520.805 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -196.74 520.805 Td -/F3.0 11 Tf -<6e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -218.74 520.805 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -224.24 520.805 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -229.74 520.805 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -235.24 520.805 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -240.74 520.805 Td -/F3.0 11 Tf -<446172696e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -268.24 520.805 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -273.74 520.805 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -279.24 520.805 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -284.74 520.805 Td -/F3.0 11 Tf -<3b> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 506.065 Td -/F3.0 11 Tf -<52656e64657254656d706c6174654f7574707574> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -169.24 506.065 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -174.74 506.065 Td -/F3.0 11 Tf -<6f7574707574> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -207.74 506.065 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -213.24 506.065 Td -/F3.0 11 Tf -<3d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -218.74 506.065 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.4 0.6 scn -0.0 0.4 0.6 SCN - -BT -224.24 506.065 Td -/F3.0 11 Tf -<6e6577> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -240.74 506.065 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -246.24 506.065 Td -/F3.0 11 Tf -<52656e64657254656d706c617465416374696f6e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -356.24 506.065 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -361.74 506.065 Td -/F3.0 11 Tf -<65786563757465> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -400.24 506.065 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -405.74 506.065 Td -/F3.0 11 Tf -<696e707574> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -433.24 506.065 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -438.74 506.065 Td -/F3.0 11 Tf -<3b> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.46667 0.53333 scn -0.0 0.46667 0.53333 SCN - -BT -59.24 491.325 Td -/F3.0 11 Tf -<537472696e67> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -92.24 491.325 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -97.74 491.325 Td -/F3.0 11 Tf -<726573756c74> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -130.74 491.325 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -136.24 491.325 Td -/F3.0 11 Tf -<3d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -141.74 491.325 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -147.24 491.325 Td -/F3.0 11 Tf -<6f7574707574> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -180.24 491.325 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -185.74 491.325 Td -/F3.0 11 Tf -<676574526573756c74> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -235.24 491.325 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -240.74 491.325 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -246.24 491.325 Td -/F3.0 11 Tf -<3b> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 476.585 Td -/F3.0 11 Tf -<617373657274457175616c73> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -125.24 476.585 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -130.74 476.585 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -136.24 476.585 Td -/F3.0 11 Tf -<48656c6c6f2c20446172696e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -202.24 476.585 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -207.74 476.585 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -213.24 476.585 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -218.74 476.585 Td -/F3.0 11 Tf -<726573756c74> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -251.74 476.585 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -257.24 476.585 Td -/F3.0 11 Tf -<3b> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 434.656 Td -/F2.0 10.5 Tf -[<436f6e76656e69656e742046> 40.03906 <6f726d>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.96078 0.96078 0.96078 scn -52.24 420.79 m -543.04 420.79 l -545.24914 420.79 547.04 418.99914 547.04 416.79 c -547.04 358.57 l -547.04 356.36086 545.24914 354.57 543.04 354.57 c -52.24 354.57 l -50.03086 354.57 48.24 356.36086 48.24 358.57 c -48.24 416.79 l -48.24 418.99914 50.03086 420.79 52.24 420.79 c -h -f -0.8 0.8 0.8 SCN -0.75 w -52.24 420.79 m -543.04 420.79 l -545.24914 420.79 547.04 418.99914 547.04 416.79 c -547.04 358.57 l -547.04 356.36086 545.24914 354.57 543.04 354.57 c -52.24 354.57 l -50.03086 354.57 48.24 356.36086 48.24 358.57 c -48.24 416.79 l -48.24 418.99914 50.03086 420.79 52.24 420.79 c -h -S -Q -0.0 0.46667 0.53333 scn -0.0 0.46667 0.53333 SCN - -BT -59.24 397.965 Td -/F3.0 11 Tf -<537472696e67> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -92.24 397.965 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -97.74 397.965 Td -/F3.0 11 Tf -<726573756c74> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -130.74 397.965 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -136.24 397.965 Td -/F3.0 11 Tf -<3d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -141.74 397.965 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -147.24 397.965 Td -/F3.0 11 Tf -<52656e64657254656d706c617465416374696f6e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -257.24 397.965 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -262.74 397.965 Td -/F3.0 11 Tf -<72656e64657256656c6f63697479> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -339.74 397.965 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -345.24 397.965 Td -/F3.0 11 Tf -<696e707574> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -372.74 397.965 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -378.24 397.965 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.0 0.46667 0.53333 scn -0.0 0.46667 0.53333 SCN - -BT -383.74 397.965 Td -/F3.0 11 Tf -<4d6170> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -400.24 397.965 Td -/F3.0 11 Tf -<2e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -405.74 397.965 Td -/F3.0 11 Tf -<6f66> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -416.74 397.965 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -422.24 397.965 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -427.74 397.965 Td -/F3.0 11 Tf -<6e616d65> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -449.74 397.965 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -455.24 397.965 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -460.74 397.965 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -466.24 397.965 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -471.74 397.965 Td -/F3.0 11 Tf -<446172696e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -499.24 397.965 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -504.74 397.965 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -510.24 397.965 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -515.74 397.965 Td -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -59.24 383.225 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -64.74 383.225 Td -/F3.0 11 Tf -<48656c6c6f2c20247b6e616d657d> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -141.74 383.225 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -147.24 383.225 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -152.74 383.225 Td -/F3.0 11 Tf -<3b> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -59.24 368.485 Td -/F3.0 11 Tf -<617373657274457175616c73> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -125.24 368.485 Td -/F3.0 11 Tf -<28> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -130.74 368.485 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -136.24 368.485 Td -/F3.0 11 Tf -<48656c6c6f2c20446172696e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.8 0.2 0.0 scn -0.8 0.2 0.0 SCN - -BT -202.24 368.485 Td -/F3.0 11 Tf -<22> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -207.74 368.485 Td -/F3.0 11 Tf -<2c> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -213.24 368.485 Td -/F3.0 11 Tf -<20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -218.74 368.485 Td -/F3.0 11 Tf -<726573756c74> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -251.74 368.485 Td -/F3.0 11 Tf -<29> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -257.24 368.485 Td -/F3.0 11 Tf -<3b> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 323.886 Td -/F2.0 13 Tf -[<52656e64657254> 29.78516 <656d706c617465496e707574>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 297.326 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -1.58443 Tw - -BT -66.24 297.326 Td -ET - - -0.0 Tw -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -1.58443 Tw - -BT -66.24 297.326 Td -/F3.0 10.5 Tf -<636f6465> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.58443 Tw - -BT -87.24 297.326 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.58443 Tw - -BT -99.10287 297.326 Td -/F2.0 10.5 Tf -<537472696e672c205265717569726564> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -1.58443 Tw - -BT -188.0788 297.326 Td -/F1.0 10.5 Tf -<202d20537472696e67206f662074656d706c61746520636f646520746f2062652072656e64657265642c20696e207468652074656d706c6174696e67206c616e6775616765> Tj -ET - - -0.0 Tw -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -BT -66.24 281.546 Td -ET - -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -66.24 281.546 Td -/F1.0 10.5 Tf -[<7370656369666965642062> 20.01953 <792074686520>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -147.10029 281.546 Td -/F3.0 10.5 Tf -<74797065> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -168.10029 281.546 Td -/F1.0 10.5 Tf -[<20706172> 20.01953 <616d657465722e>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 259.766 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 259.766 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 259.766 Td -/F3.0 10.5 Tf -<74797065> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -87.24 259.766 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -95.934 259.766 Td -/F2.0 10.5 Tf -[<456e756d206f662056454c4f43495459> 80.07812 <2c205265717569726564>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -251.97368 259.766 Td -/F1.0 10.5 Tf -<202d2053706563696669657320746865206c616e6775616765206f66207468652074656d706c61746520636f64652e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 237.986 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 237.986 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 237.986 Td -/F3.0 10.5 Tf -<636f6e74657874> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -102.99 237.986 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -111.684 237.986 Td -/F2.0 10.5 Tf -<4d6170206f6620537472696e6720> Tj -/F2.1 10.5 Tf -<2120> Tj -/F2.0 10.5 Tf -<4f626a656374> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -233.694 237.986 Td -/F1.0 10.5 Tf -<202d204461746120746f206265206d61646520617661696c61626c6520746f207468652074656d706c61746520647572696e672072656e646572696e672e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -48.24 203.486 Td -/F2.0 13 Tf -[<52656e64657254> 29.78516 <656d706c6174654f7574707574>] TJ -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - --0.5 Tc - -0.0 Tc - --0.5 Tc -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -56.8805 176.926 Td -/F1.0 10.5 Tf - Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn - -0.0 Tc - -BT -66.24 176.926 Td -ET - -0.69412 0.12941 0.27451 scn -0.69412 0.12941 0.27451 SCN - -BT -66.24 176.926 Td -/F3.0 10.5 Tf -<726573756c74> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -97.74 176.926 Td -/F1.0 10.5 Tf -<202d20> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -106.434 176.926 Td -/F2.0 10.5 Tf -<537472696e67> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -138.8685 176.926 Td -/F1.0 10.5 Tf -<202d20526573756c74206f662072656e646572696e672074686520696e7075742074656d706c61746520616e6420636f6e746578742e> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -q -0.93333 0.93333 0.93333 SCN -0.5 w -48.24 155.11 m -547.04 155.11 l -S -Q -q -0.0 0.0 0.0 scn -0.0 0.0 0.0 SCN -1 w -0 J -0 j -[] 0 d -/Stamp1 Do -0.2 0.2 0.2 scn -0.2 0.2 0.2 SCN - -BT -541.009 14.263 Td -/F1.0 9 Tf -<37> Tj -ET - -0.0 0.0 0.0 SCN -0.0 0.0 0.0 scn -Q -Q - -endstream -endobj -55 0 obj -<< /Type /Page -/Parent 3 0 R -/MediaBox [0 0 595.28 841.89] -/CropBox [0 0 595.28 841.89] -/BleedBox [0 0 595.28 841.89] -/TrimBox [0 0 595.28 841.89] -/ArtBox [0 0 595.28 841.89] -/Contents 54 0 R -/Resources << /ProcSet [/PDF /Text /ImageB /ImageC /ImageI] -/Font << /F2.0 17 0 R -/F1.0 8 0 R -/F4.0 24 0 R -/F3.0 27 0 R -/F2.1 29 0 R ->> -/XObject << /Stamp1 87 0 R ->> ->> -/Annots [58 0 R] ->> -endobj -56 0 obj -[55 0 R /XYZ 0 841.89 null] -endobj -57 0 obj -[55 0 R /XYZ 0 765.17 null] -endobj -58 0 obj -<< /Border [0 0 0] -/A << /Type /Action -/S /URI -/URI (https://velocity.apache.org/engine/1.7/user-guide.html) ->> -/Subtype /Link -/Rect [200.84038 694.28 240.35126 708.56] -/Type /Annot ->> -endobj -59 0 obj -[55 0 R /XYZ 0 665.75 null] -endobj -60 0 obj -[55 0 R /XYZ 0 632.47 null] -endobj -61 0 obj -[55 0 R /XYZ 0 450.67 null] -endobj -62 0 obj -[55 0 R /XYZ 0 342.57 null] -endobj -63 0 obj -[55 0 R /XYZ 0 222.17 null] -endobj -64 0 obj -<< /Border [0 0 0] -/Dest (_introduction) -/Subtype /Link -/Rect [48.24 748.79 111.702 763.07] -/Type /Annot ->> -endobj -65 0 obj -<< /Border [0 0 0] -/Dest (_introduction) -/Subtype /Link -/Rect [541.1705 748.79 547.04 763.07] -/Type /Annot ->> -endobj -66 0 obj -<< /Border [0 0 0] -/Dest (_meta_data) -/Subtype /Link -/Rect [48.24 730.31 99.144 744.59] -/Type /Annot ->> -endobj -67 0 obj -<< /Border [0 0 0] -/Dest (_meta_data) -/Subtype /Link -/Rect [541.1705 730.31 547.04 744.59] -/Type /Annot ->> -endobj -68 0 obj -<< /Border [0 0 0] -/Dest (_qqq_tables) -/Subtype /Link -/Rect [60.24 711.83 118.39126 726.11] -/Type /Annot ->> -endobj -69 0 obj -<< /Border [0 0 0] -/Dest (_qqq_tables) -/Subtype /Link -/Rect [541.1705 711.83 547.04 726.11] -/Type /Annot ->> -endobj -70 0 obj -<< /Border [0 0 0] -/Dest (_qqq_reports) -/Subtype /Link -/Rect [60.24 693.35 124.6995 707.63] -/Type /Annot ->> -endobj -71 0 obj -<< /Border [0 0 0] -/Dest (_qqq_reports) -/Subtype /Link -/Rect [541.1705 693.35 547.04 707.63] -/Type /Annot ->> -endobj -72 0 obj -<< /Border [0 0 0] -/Dest (_actions) -/Subtype /Link -/Rect [48.24 674.87 85.21029 689.15] -/Type /Annot ->> -endobj -73 0 obj -<< /Border [0 0 0] -/Dest (_actions) -/Subtype /Link -/Rect [541.1705 674.87 547.04 689.15] -/Type /Annot ->> -endobj -74 0 obj -<< /Border [0 0 0] -/Dest (_rendertemplateaction) -/Subtype /Link -/Rect [60.24 656.39 175.29055 670.67] -/Type /Annot ->> -endobj -75 0 obj -<< /Border [0 0 0] -/Dest (_rendertemplateaction) -/Subtype /Link -/Rect [541.1705 656.39 547.04 670.67] -/Type /Annot ->> -endobj -76 0 obj -<< /Type /Outlines -/Count 8 -/First 77 0 R -/Last 83 0 R ->> -endobj -77 0 obj -<< /Title -/Parent 76 0 R -/Count 0 -/Next 78 0 R -/Dest [7 0 R /XYZ 0 841.89 null] ->> -endobj -78 0 obj -<< /Title -/Parent 76 0 R -/Count 0 -/Next 79 0 R -/Prev 77 0 R -/Dest [10 0 R /XYZ 0 841.89 null] ->> -endobj -79 0 obj -<< /Title -/Parent 76 0 R -/Count 0 -/Next 80 0 R -/Prev 78 0 R -/Dest [15 0 R /XYZ 0 841.89 null] ->> -endobj -80 0 obj -<< /Title -/Parent 76 0 R -/Count 2 -/First 81 0 R -/Last 82 0 R -/Next 83 0 R -/Prev 79 0 R -/Dest [19 0 R /XYZ 0 841.89 null] ->> -endobj -81 0 obj -<< /Title -/Parent 80 0 R -/Count 0 -/Next 82 0 R -/Dest [19 0 R /XYZ 0 765.17 null] ->> -endobj -82 0 obj -<< /Title -/Parent 80 0 R -/Count 0 -/Prev 81 0 R -/Dest [35 0 R /XYZ 0 429.13 null] ->> -endobj -83 0 obj -<< /Title -/Parent 76 0 R -/Count 1 -/First 84 0 R -/Last 84 0 R -/Prev 80 0 R -/Dest [55 0 R /XYZ 0 841.89 null] ->> -endobj -84 0 obj -<< /Title -/Parent 83 0 R -/Count 0 -/Dest [55 0 R /XYZ 0 765.17 null] ->> -endobj -85 0 obj -<< /Nums [0 << /P (i) ->> 1 << /P (ii) ->> 2 << /P (1) ->> 3 << /P (2) ->> 4 << /P (3) ->> 5 << /P (4) ->> 6 << /P (5) ->> 7 << /P (6) ->> 8 << /P (7) ->>] ->> -endobj -86 0 obj -[15 0 R /XYZ 0 841.89 null] -endobj -87 0 obj -<< /Type /XObject -/Subtype /Form -/BBox [0 0 595.28 841.89] -/Length 165 ->> -stream -q -/DeviceRGB cs -0.0 0.0 0.0 scn -/DeviceRGB CS -0.0 0.0 0.0 SCN -1 w -0 J -0 j -[] 0 d -q -/DeviceRGB CS -0.86667 0.86667 0.86667 SCN -0.25 w -48.24 30.0 m -547.04 30.0 l -S -Q -Q - -endstream -endobj -88 0 obj -<< /Type /XObject -/Subtype /Form -/BBox [0 0 595.28 841.89] -/Length 165 ->> -stream -q -/DeviceRGB cs -0.0 0.0 0.0 scn -/DeviceRGB CS -0.0 0.0 0.0 SCN -1 w -0 J -0 j -[] 0 d -q -/DeviceRGB CS -0.86667 0.86667 0.86667 SCN -0.25 w -48.24 30.0 m -547.04 30.0 l -S -Q -Q - -endstream -endobj -89 0 obj -<< /Length1 15680 -/Length 9627 -/Filter [/FlateDecode] ->> -stream -x{ xSǕ̽W-[eKWOٖo˲1Ʋ-?/,` !-%$!M#$v4~YC۴%lMҐlf$4ݕ}9so9s̕0B(E,ml5fA19ܻCyhۧ骡$'b$cDAEY?xhtv! acxMreF<w -wH%eG;&CV u~1<4o@k/*|ݓS -uV$EY_oĺOA) h0C K~c} -W5|rdɑ9'+Pޅ#h(NQ~%^FV\E:cGRLjN@n?r|3ddb^ CQVw~,Q$"NdrEYbq*5Iht)izєi[_PXT̓?%t\֖Ɔ u5URKIqQaAܜ ѠOO%i:F.  - J"e0J*{ywRK.8XAu@\{)k8-^N' Q>x{VP>l:yhy-sIz1Vލ{ -wṊ^+ȻX.;B`N&/bL LrEICȰnV[p75+JS^ Snq[BE#::_H{Kᨯ7-x@ptݬαssܲ4w`u] N4"ei![  𧛫)E "JP\W9.-paBpdh5١ץŷ)ݕu{qo-uv7@A:5Býi 1J"dzc'U%Z)\8~}I $"!r*^i^ӷ+,*. &R¤[.-ٓi.nny6\_/JF+o X0XNh̋]3,i%*nurV oWjܖN)؝)A)4 EfuB]s=@qڊ5b+-Jy;d;1|%B%Z)\`J%n]V۱;pZ}|J^y_TANyRө~ 4󾁡j!j1DC) nK̍Zħ j]VV( Ԅ4e+Ӕ+뮢j3?'Zp'7"nɓ)i #T:Mg]X焚9^H!V$cE:\VOWvA6_G[o.?fLyoYDhþB "B$@EJoZK[9JKQOè㥅i 8/BiVC}$>@#X(0#v -2wPF%^⥋ ]>}\x=왥r@MXڑn  -w;f^[D0>%iݽ,EiZhoZa ޻K p, ewàq0Q 'wu .0H# K&AWbQd=MXr8x^vjŠ?KK _:\,Hh~+p݂C,^c@r4<,E7,> -j,ᬏ4b?ES}{˳aOf'`ѓON>I.} ?^9{[1cj1G蕣ܑ~ţ"Rg3 itUl,i_pj1xu_Z|``Hit2lHsD`s?bYK"dؚllI{cEMm1luU: -U8άl2+e8=T;Bφ]cJ® -c'*8(,—Z.Ia4mtGVr4wŏQ{F0*sgݽu(XHa//DN5F?صٕi姸\[B暞陙q3.y9AWfE~+\i1H,G -81\ьY*WBԴ{'7~O }J64fC>mC>WoOi8:;pX3s]CCK3Ms*~|6Y')a 0-)׊:~WƊ`?' 1,աIIԁ!zF[Q*QJE翃k%tGmA| -HK?ODbkfNs_#gbX!nfB"X .3S - -:wfRKDQrI3__??b ̃3/(sy4w^$ezE8A'>+RR-9%y_J/>0=A A}A -vG!1!|z/N3ß*+YDK8ٲ'Y,ȴfZ02 ]fk?6S7Eyьk!6@ *&Za`쬈beqmewynK$spg^k|ټn*YM>YYFb"r&KY+~@A R*Yύ7\t^kTV2> K4q HY.;+ǜb=Ξ uҝíJ](W*q)h}9`"Qq$uog ƉD(7!0``2((1Vi仓P>;YC9UhӜm,fe3.f+.J]HWTx(P$ &.Ԑ.ʐFk[nՁ6"{dV3d$` &(j:64{ I -8Z&uƜʎŤ4;;Nf=rӳ/65W:m>Oe -mfxQڬ+p֦dt>@uuM<`2S FJN3he{l̘֙ւJ :8þ*ֶ@H08ѕ@wHmʰe,a%ن2.21aÚ-nWl,Ӓݰ6bGC'QAfYa"7ۣ'('\8aE$VwQQckc7g S1Rቡ۶x:^QDtVаxui e@ I=.zfcT43u̞XR.4 4w4hIC¥5ϊԊ@OqPT w -k[sy`pm* [̮@U9/A,nVKNvVs䩠uE='l{ad=w4mL&ז(]@ѸkhssM}o}o`::3/!Q]8Ф)Nz[&:B`MB"5 -.x8<T>< ->@7*t9 ָU.[S?vS`]Mh&53=vGD|v8 y"Pp%Ofb}U0 e%j,0zuu$~4.!]\xϸ+@rϖI""ß2(2l!۷Cud6>[ FE `& 2_LSXK7hx0iۧnʩn5x=_- JCQB,1 ]?{kG:~ W]1ܐ! ߴt7ۅji{C _Ya=^A$բ -Xe⑧JSiҺ˧4V粗ʢGN=hj{+τ MVn3p߽o*IJRFQxzDk -TLP~݅+:חw~JE8|>a?v YVvyY5/n4 - eTbE[Co_M(2(Iri9'b {Nrg4tzN 0.-,[ L A鄽&Qӂ{_ Ð$x-Ǹǘ -jh]]tWMPW2'"Aɴ-P<3-{}n\ 03y05С| (8@[!:ΗuO=r*;]EB-:lRrz'xf>Yma1J ֠JS9UTdiT"19~[ʰnZY ,(Ɠ6u bn٥s ~g-@iN*h`Ǹw薮/_wh;.Yv|!)(g7CZa3M.8ҽK◙/Ѯ3?NӟiSSi=xgVK/aŏn'n'nBX tl_/roXJHzslm:{ĩm𜥋98 و˓B,ND7DG{l? l.؛{3չo9ܞ؛6a <7#KjU؏ wwv>9W*e+<|: -%_Y[fFs<ni&W<]Ti+;- -#M;Z\5>g=U_JH.+h2끧6T깧ٮ͏wqt?gαl$u;;eU=.1*d+զ^<_4' y/]*Y^e66' 7oQ\0Qb4 Yh;4m-u6mAusXGrԯs^MMO׿eoDS8A,Г-` PFŮԮ ˘vą7j`ƤlX>"t]z7_k~7|Wc5N(ls18qR0ILCZGoP,D̸Dyi\N_ Qg ðs0/@z3IY|\Z|PW:X@$s#粹>OÊ%KG޷%KV^sI]Ѿub E]b@.'UĦaM*UT L0*߽Y[{~~jUY-u'ꢌ̂^6:paH[2Ӵ撤:3+#9u.^ IƘŁ1u*мxΩÅ]Uj35X_VPdLHN%ݎ7ڲ9"!4,}hQ>on7+:H䬊o2{ [}@)&5b31ٶb˦"abUo'F<|jcW޼γ `!hjm1rͫZ <pΏIUGFSc֥t3d@QdI4UDx c_`(aQb֎OԄ -ķ#i11idljo%G 9y;)\^alrZJwM&oZa90,{BjL{I -NaI 0WlbzlA)V\:7Za?uq6/Uf ldL/=,7ɱ _)k^CY\dXqߌ].ۻROKjvSf׆HphsK#'zE|c^ -WfPӝ]_N<猶bO -BN%>yy:e _ؙѼ %ܜ -w0p+^Vrs½ϟB| [Uebt|OSqSμ25uޕ:OSB\"r>y<ky}Mr-5Rw] -xPݰYxt!2%1^c}n<]&n U꛾$r撅*a.ޑ`:֯0./3Ӑ6:%wbhDSZ|T~H -b~WtDcyF,'H[\$ -['$xurk~c}{&g9Kd ў݉muQ9ϟg^< BrbIQ`uS2{`e\$HVJ+BXU -̗Z>B㯕EApX$ YӶƚ -ΔXmL)sNk﨏hl2[)~wWW`f c$U_`^>ˣ\(1 c߱^ߜ\K9x$@_!Dj23Ux%# uDDZRAav*sny6[,*X_zJ(0-O"IչV/&GO-[6F YIIQ8H{0|HzL񭕩ѣ6vBksu~_ߏ'3{pF{}kkQ`RQ) i񼝜Q169+[8?g(=)RSXhv38|_6SHMMNa>hP*ڶUTsf z}][mg~%Ao uPaJ޷"^qo0 @-(Y|ex6"|e1 -G._YC)Ћr|@d@+A_/ V!1Xa@9c0|e̼̠P6WfQ>9$gŰYYL)JeP2X_9s}`TȽ+0ǹ}P%y|brvjdhx4edUCNf-ŷ8]ΩClq͌:6LOLNB1yK6kdb0r}94Ҹ5c9O r Vkdhos:Ƭi?<2> P}t7/1x0<==o4w}!:b86qE;epM L ʉiubp>ǔat91gSo'^z/C: wa#驑 q>iMJ[kZ6ol5m5 PK:k:8Ss'VX L\~~1>4YL:F\d"`ȴcև&;Ɖf'ffc~;F&]ȨabjXYDh -FӈGN&u 4aZzh O'lpG B3 :Nfw1hqH܍f%TfaHpMP:xSh+&@ƽfHi!"ڠ怾VOS,TƴOk G} U} &Q܈?ZNN5$O@֌,BFgC\IfA -Ѵs82(P+ SVl=<$ׯ@}NST>|^zOuJ -e:Pj̲ÓK[TA6UT+QC޶JP'<렅N@LQOpQStc@%{Y'^y*h~'O8]Q$E8Fu鷈˧\JXn'~_Z]@f|uIJ4r(Qx9A;|lSN!( r"YY Zb!SRDEIM&:уtot% )AveS 6[ZoM<<F 2 Tj1"׉ -endstream -endobj -90 0 obj -<< /Type /FontDescriptor -/FontName /3b6d06+NotoSerif -/FontFile2 89 0 R -/FontBBox [-212 -250 1246 1047] -/Flags 6 -/StemV 0 -/ItalicAngle 0 -/Ascent 1068 -/Descent -292 -/CapHeight 1462 -/XHeight 1098 ->> -endobj -91 0 obj -<< /Length 1278 -/Filter [/FlateDecode] ->> -stream -xenFὮBtHs&@nu{stԒ + }ik/y_!}t~]snVyg쾝+|<.÷}v)[eO/_q9_ɯ}ഏOmt_LLv͵LJ1w9)e6=n?[i(JKiU:JSz2QeL*EJ̔Ye,*+eU(NU-уk5x5F^ky ^#k5x5F^ky ^#kxZV^kZy-^+kxZV^kZy-^+uxu:N^:y^'uxu:N^:y^'xz^^zy=^/xz^^zy=^/o xo7 Aހ7y o xo7 Aހ7y oxo7jo$JI$$*I$ITH$$QI"IDD%$JI$$*I$ITD$$III$$u>M&Iބ7ɛ&y$o›Mx o7M&Iބ7ɛ&yUoa[5joSor4ۂsޮ>,x/x;Â31x; -JJ특xxx+!ÊwBxbx+ށr;2kΜJYeY7+|x oS7+[ƛețךyޢoV浖 -㭌"RW*4XqC^J[(^1»y]k}YM-x e#e_y+h܊7k:/Z5dUluz5n[eB&Si|y(%q& %+S%*ABijPU6\h,(+L,4G5sh>:OVRP*#i|e0U,*oU/*[U,Nmlx:&\}M)L2\%CHF7էʻBL)jƻJ1:%H߯:=S۳zrmkO媳7 -endstream -endobj -92 0 obj -[259 500 408 500 500 500 500 500 346 346 500 500 250 310 250 500 500 559 559 559 559 559 559 559 500 500 286 286 500 500 500 500 500 705 653 613 727 623 589 500 792 367 356 500 623 937 763 742 604 742 655 543 612 716 674 500 500 500 500 500 500 500 500 500 500 562 613 492 613 535 369 538 634 319 299 584 310 944 645 577 613 613 471 451 352 634 579 861 578 564 511 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 361 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 857 259 500 500 500 500 500 500 500 500 500 500 250 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500] -endobj -93 0 obj -<< /Length1 13676 -/Length 8635 -/Filter [/FlateDecode] ->> -stream -xz |[Օ=-I['=K-ke[Wk}M#ْIJ[IH K)4)e9B3eߴL04)sޓ&޹{sB!#yںlT ǁ xDB8]!zaahP@>*Byg>&w"I!~t_}w80$rtgB9s<|Q- W&#/= p{4w7B}!W4 :yBP:pj߿"$z0#vX<߶m?x!bo>^p}7yEd +D^NxlYϗ-s^vcG# q%%M"LQ2PxDhL "^HP< QC[[;AxcuT3k ^G$d4"H^?g]JOQ YuPIT߄vԱ F +-" SC + -⿽3#%LQ&h^k]@@޺b&8B(!1 %\%zuz&`4ees-V_Uhokݼ(/+-)vmVKnhd:mL*'%Ƌ>" rL=a46Z2w U^&L{81zd5HnJVJb ]-ï213@?MB"t:hAS]t{hw~} :/Q<@U9r.Hv& n/vuKnS8qqUSׅJz ,AsyäΓRs8qE*e\ҹO˭.qg0 o7HX;?_y -a`a./:\t ,`;[)[Ä]Z'XijsMu:vG.Wa(wG4V_@6@5{ؚ+5= x>L|l|? u# '}1R6Ҁ7AyF0 Z"m2/ -ID_4.a@ ͸=]㩠Qw]@T{c>r/mM8mtXԮĚeuaX$c6vϳzr?x%XBXQ1htFZrWbA )@qD]wKұ8:Z j~uT gXhA 0z rx!peúj" 0ٴɱuJyl5hESר 袗%j:1h\" 5G=*fWccy$f ?1v+1 z3\oV5n+7T7TBkU"@.i;`ܮ&<_vUZpKw%_u,TC][_PwuځLu,e-: /U#8W0LDy<*ʫx^JCw>? {G -40f*L& a 3,WE|/ -lɽ{^fj5ƀPgn'8/w}pGp1ֶ/e,YƑҾ%Rt|k ۱LJD$'bKB=8;2n`p|M@{>xІ7Ցp+5F(nU)-<D&VdN}W oEuVϧhYkhGC|ñsnOdgq?]+EotP27ӫ1»]crY[/x1o_¥H’'.rzVמ'>'MVWNc4n;$QuɧN/rh?_=N%f%^pjOZʲV@-k+cHhh(I*~}W|ox) }G$)dcFݒnOtn^Cݣp{X#q{`Ճ)u1Q%"HL>Q / ]fse2,Ղa|(lb[CaԳek8v f!9x2Z>6K~ $ -T;0;;2srͮP(D\!4whnnhBT?lfIxbf3C̳ssTطːCxxߵRH#̞<#(zlBϻ>N-nc#*EDQ 63ع 1]q|xtoxf$_Kǡ\,H*vԧe|55^" ( -Oo "v0\޹<98u -AtW+xC?!{PvT;%]0- [ G]!QSI'4'OLHd 7"dHIuNI6|qؽb87d4= $BPXIX‚"G/RgQ*t&o.v mhRlw]Q]])9 * GNFo%,ªV[+LEuVeHU6kQ*5VC)Y 5ȮUF˨l[e" e uJ‰uXC 6LZIS) u˄RJܻ4$o4b)7հ4.$ J\V'O⟅dQ +Ro4KtI@\Ff_g6ej[[3#%JCVT(Y?5\Fe(.i0BM(Nx66"?xi[iJJ3Lngb!\Z:pq[Inj]dQrֻZ@\zA.V#=~=֖`c^M~4!k@ :,P2W]}mt$) \|߲BTWTV{vd=UmbWc٫S|c]w::|ԩlb}M >+R$$@JY6}miWiLH2^s8G"]xzGɳ_}7;yɁȧcܨ;+K} -BrC)ɊrQ)< -cDnTR;EW{^eNy( L"[7yA{POv WTK)F$j|+MR[EeGLETHG/M {X#E"nB_ZU9ƺ- ^Mި=oZ9:CX].(ȀVP*ND n?XnEPPEsZ3#gq^8պknJ|wRŭqҥT-S+׫oWk"זF@$ZCg2Ɏ"_sm/baq0dݬ8j79OƩo=qGV|{sޒy$2r$&7g&D5oݸ %L2ꃛ &C %>f޳S p$% 导1ocmC<Ļ_竓0=ٱ_"={'qszh4q ɕԻ';_ɒpk=G\KCie5#҄i|ӑ -cLgIJJ&+Rsww ;t'W4?o};,{~W"_30Ɏ*`ݰ Zr ,ɬpJz XD^cWU^^AnX ClmRA6l+IK/kc[/u;T# VeK#e-;[Z'hW,@5ú 1g55])"crf4Uszqri˓;(VmRte7;'Nm3>s4*?0`їw -:UwL2d)dVZU摞T{ռ)ǼelOȗwre͆bc&[H3&F9k)JnSǷ& 3c}"Ksm -/&G:~l| c}59G:MpL/Koek23$qcL1LXhWJ6e%LR>HB* $2bqnHLJ_mW"Re78bAHyͰD@#Rdae.]ZvxuJϜ*]KWq񣰰WN=KݓfS"j:[&g*+RrNEbFT9NifA\%LN*T7k|}?Z*ɤJҖ/-*~)JBUlQP+`JW#e$y568ԃKB:qH&nGQb]/<`N֗zJ]s}g*7I]i7q^Rܞ4t,}S cY)Y]{{򴀿[ -dnK"`CQY86[E`js22EJIdORFqZ[HJ=}q(BUe2{g"ձF1dhm;r '9n^bֲ&|&pmexyC<6Z,kO8L0}wl*INKzJ,ѕYtUvMl7-RlWʆjne[Q:*ppxZt[p$EYSs#wʓ( -$V['y2Y^G"i+ֈO䩷%\&ngC%\ܹb3Qڌ* QP oiHf -d^?'*u?^vK#Յ[N εkՃ'~hS=;屲6綕g>Օ|ob+{,quMɢp3.]{rrV}TSFZRU2˪nvzH]DJu!ѥ.DTDFC]hE8#_]kxORQW0Me{ly\Vĥ@a;@Lҕ$*RSZy5*9[Hs{:5 -JjYrGD/ RP.B)[*j[gdثCM=Of:gEJb8399xqsTvZltD B+ؕruii#&|vf'iTrF8T/2Nqi6ns]o*{hf:/X0O1T{֥ظSט$HzAP ;Ò<( -k+ί7FM:S-bUX֓Q#Jm=RYռAW6W\cȕv6(5Ej8\rS_:B1THϫEZwk}ӆdmSV{۽}V@Ϗ4m2(0|ڱzCAlUd JXzRWc+zNG H3("cp8 @c!% oSܓ"nkC)MDJa,DR;iqjO[VeOxNu"65řrF#xNhVMvnKM+6vTNoUXiUݮ.kyYfu#B_=`TB%-k,]q76ZW`gVkz^3)6P*r:AAQ=9tި_ -aoP>%3˥$WEmj%B_g[,Ԭ" _gk0 ^߳ -F|Rn8T@C ̫g/q GrġΖ봚ȵǑp|ɡ'j i/9YL%Z2-],erZaz44rO̓"DzI>űQKǺ>c*&~ɐr0#3w>/.QE_No4z$?ȟU\ WWV7%?NJU-k3eFlVK @SijKN:'U0]\r6 kz̥y6m(n [#;+1o'kl|ݛbk3B{mR7dCq^צ&0H6MUOR GV$,/KH͚/L 7b'n.*EBHPdkic]X`~b;$R:Q:}큜)ڌ$͐Y;?x]ZxF$IdA(% - "!)|9ĔG7GGL5, dyZ&6C*Y.w BNq6V8ѶrrJQ@*$ңM-FP|$GwhB/8$Chx_kj)F'IHE$b3\HF -c4dz&̌Ґ1RɃ1Z2Oh8y'Fǡ,*!F UQ%!S3:?;16Ew7'B;/*ax(4]jy13H0`l Ěs9D{ BtWp4twώarb?5 }M3thOw5mۦSQMQ\Y&fC3s0$Snӵ5]M]t_Swc[O7WY:麶VWSwS[+ՕK' kz?;Kgk.ңHf##wjl;&fف|0Dc])]s3h>3?̎LLf̘~CA4v48 -!vvAO"?`!M‡Ff~е >l!i8>Fa7>S\n@@^71([ྜྷzUǟxe{aLVYњVn/!B?a^v{e/ZE %/u3atb6\/h4 hir -L)wXAȬ56(Azaxs{77|kha-_$Gڌpd}7'8[xd6f?_n,LU. 9\ St -n4ǬIxcz=w-]vn$FR2 eY2t٠6. DŰ*AwEj>6OP;8@~ vfBD,/#SQ -endstream -endobj -94 0 obj -<< /Type /FontDescriptor -/FontName /7efbb4+NotoSerif-Bold -/FontFile2 93 0 R -/FontBBox [-212 -250 1306 1058] -/Flags 6 -/StemV 0 -/ItalicAngle 0 -/Ascent 1068 -/Descent -292 -/CapHeight 1462 -/XHeight 1098 ->> -endobj -95 0 obj -<< /Length 1278 -/Filter [/FlateDecode] ->> -stream -xenFὮBtHs&@nu{stԒ + }ik/y_!}t~]snVyg쾝+|<.÷}v)[eO/_q9_ɯ}ഏOmt_LLv͵LJ1w9)e6=n?[i(JKiU:JSz2QeL*EJ̔Ye,*+eU(NU-уk5x5F^ky ^#k5x5F^ky ^#kxZV^kZy-^+kxZV^kZy-^+uxu:N^:y^'uxu:N^:y^'xz^^zy=^/xz^^zy=^/o xo7 Aހ7y o xo7 Aހ7y oxo7jo$JI$$*I$ITH$$QI"IDD%$JI$$*I$ITD$$III$$u>M&Iބ7ɛ&y$o›Mx o7M&Iބ7ɛ&yUoa[5joSor4ۂsޮ>,x/x;Â31x; -JJ특xxx+!ÊwBxbx+ށr;2kΜJYeY7+|x oS7+[ƛețךyޢoV浖 -㭌"RW*4XqC^J[(^1»y]k}YM-x e#e_y+h܊7k:/Z5dUluz5n[eB&Si|y(%q& %+S%*ABijPU6\h,(+L,4G5sh>:OVRP*#i|e0U,*oU/*[U,Nmlx:&\}M)L2\%CHF7էʻBL)jƻJ1:%H߯:=S۳zrmkO媳7 -endstream -endobj -96 0 obj -[259 600 600 600 600 600 600 600 600 600 600 600 293 600 293 600 600 600 600 600 600 600 600 600 600 600 304 600 600 600 600 600 600 752 671 667 767 652 621 600 600 400 600 733 653 952 600 787 638 787 707 585 652 747 698 600 600 692 600 600 600 600 600 600 600 599 648 526 648 570 407 560 600 352 345 636 352 985 666 612 645 647 522 487 404 666 605 855 645 579 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600] -endobj -97 0 obj -<< /Length1 5204 -/Length 3541 -/Filter [/FlateDecode] ->> -stream -xW{pSי?ʖm-Ȇ#]@_뉍؎mKmْ%dXRllHMK۹4-Y&)Ni2)I&3I0ٙXw^}{!@Ǒ u=+pf'b'^C녹m(t#T/[Lboɼ  U@B]/E-ϕ_;C+<>fÄ5`7¸1W*Q9C9%oًV'ܗ!KwaT?aH?Z6ECM }-]XYzVGs%\)4 a=!ȉ:(Y͠ v\EZuA+f6zhy1/Wohy>Am.SZmU I)4?~NO '9*&)-+@}UJ [A 7 bD)nC|"׊rwE4El 72Q ;]>ާ52C1Vtbjya4 ]֧b+1xi(7OǔFDSdxM9LHGQ,1CDY OĂ!yPbFilF;FRySf mb~Kc|xI`^r2&YXgIgx -.:A3HS,mQjȍ,oZ&Viɍqxw5ZYh$;TARQTeh~$,xއ#J}m(gD2\p9|]{S /}J xoU7ukEs[+̵wWWo"TvurEٮLX cJ^^&mo=/kϝ\9ʝu|`PkUYTI=[[ckf\ʗÛ#\ʭ(zhAKLfQ~J|B:4Cez`X^8"{t~w'}ױ[iVu-Xʴͮd 9;t~m`b@MG-M$wlշSnZrZ5]"__JF`h₿;B_ީ9v64])dx_'ok~Kw1RVr:8?@'J{PQ,>̎3d#V)ajR .V,mr~Ga6[s\u8Ͻ6zst&n۠[,_"UK'o~ҵt_+}krwTs?%Gw?;پW는/-q_jwCnh|#0AGu3.7- g]6S076gz ]+!m#i,vqIk2]NXy|umm boV.o0F16tN54pŹMCA{ޢ=*I!H?4pVuCָ -uQL΅-*F><˺.Osp}o2tOBǹ7Oˡ^yC't9z3 464yZ\ypys<]P.1 -lQۑHJEBLFb;ɘktoxO"O3T(H&tCb@d9ch5RM&Iބ7ɛ&y$o›Mx o7M&Iބ7ɛ&yUoa[5joSor4ۂsޮ>,x/x;Â31x; -JJ특xxx+!ÊwBxbx+ށr;2kΜJYeY7+|x oS7+[ƛețךyޢoV浖 -㭌"RW*4XqC^J[(^1»y]k}YM-x e#e_y+h܊7k:/Z5dUluz5n[eB&Si|y(%q& %+S%*ABijPU6\h,(+L,4G5sh>:OVRP*#i|e0U,*oU/*[U,Nmlx:&\}M)L2\%CHF7էʻBL)jƻJ1:%H߯:=S۳zrmkO媳7 -endstream -endobj -100 0 obj -[500 364 364 364 364 364 364 364 364 364 364 364 500 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 500 364 500 364 364 500 364 364 500 364 500 364 364 364 364 364 364 500 364 364 364 500 500 500 500 500 500 364 364 500 364 364 364 364 364 364 364 500 500 500 500 500 500 364 364 500 364 364 500 500 500 500 500 364 500 500 500 500 364 500 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364] -endobj -101 0 obj -<< /Length1 8256 -/Length 5624 -/Filter [/FlateDecode] ->> -stream -x9XSW@@(/<( I@ @Mb/@A%UvڪUvNkvδssnulqs{ ;?k{9_<0B(F -5d 0?!)or$-!qX0wr|v(!&ԃVHR"{}o=d 2cv3#G?ƯA3{yXS#ޭxzsk/O -NdPUzݰ~q|?cy=+vST|36QfG1KT~D}af5ԅ?Q d3Nԅ%؉%pX& -RG#Hdx!aQSǡ -ġ -3 -n~#= -$4'ThC m1Z>RhnhL%h1]4m Z/\K)O] -[˖ǵ R7tros]*K^oZ ur1KJP5" +U"Cj:0obҒ)R8}:i^"ǘ F?H(0 -V[*^YRZf/tTU7'! pu7w_Rtu;!FV(*'7DNwG ߩ )CI\աUtŒtom/;c&ɼ>:;^qqOWnHi|)ܾ2*Klb~Jmp#2yp!Efυ !O{9 -%lF"IX=P4rq\~Hqu|w$o1 inOs;;@ 4M7L^ABP,5Cȭ@_`vw'[pTm>~Z\ɯxU -;/Ƣ~Ğ>|H;ü4_89qsZO3`\x>!%|Z# ush3AhKȔjr 6خ -@'zAD"pIVR&!/D+܊͊'EeU {+~φ_RVO)/((?T~T.êSԋJuzfD$=y!&ˬ87$'fQDIxج24ENe@ptؚTӪtŐeIHaKl1u,NVKav ," ;s*|K]h]沷 5ZbSWB<:%A(%d[M Ze=2⣿^Sf=1 .8 q?v?Cf}[4݄ .P^B2Uԕ8J/M:/HjCfT:4 "#H#8]MHC=RbJz}b_YAcV^LY:2x3W=D6uzIboQU7U\ålwEl<$1(hL`*}ZhsJushӆE͏~Qtt~ZO6 [_0>V"x8K[nŏ;&n# sS!85l:ɠ@>r-j:c5oݹ'X^LO=.,~?_OZzF[t")%*-O&R4iҹ|:W[UUCHw~L! }Qm:^c5zݙO?ZBrn =$ }RAϙ -Mp}PlIcghvv椡0m}3/x|&ɦ1×g߃7=.rK|g xX| -pX. 9XX )\15  6xpc}' ؅[M \hcXSߢ5=xYnF2$o;kE<|9pπx01Y@A@}D׵x &ЭezE -4g,ɋB//+o/x8'$.!7+ f״RLwn+h&NiY *> _w'kEo^_HqHnˁg *9ӣ2L^jo3fȧrEUcl؈_qBފO6YXZtn\TѼl7//J)u-G<+֔$ŋW !zR-6wpg_0@3;TH$0ȥfDXgKGcWw*Q%=rO,\Pݱdq{¸ZkT9nO6ӇhrkJֈs%K,M⸜=G,k.sEA:8+ǁdNR]WE!eWOZwXI.]p>bĕm.vv^!퇘C&Rw?qxCiggt-& s&W]N}ݾuݩ3~Z0 -S<$S6 qib3~$X 'w)/|_=b02XkqVt7vw654w9CLJAgje,[Y]LO:GOO}aA~a1ܹT!?'q|n]|aqբ6~IuFCr^F2 ,1RM[HêJ"TzW;ۇO>~QtÞw-gz)۰Ѯ dCѣz]Fux HM2)m6d(>1rh>O.:zKwapxH1wxmΤuo*$-mB ցܻ)@V6Uz&'bͩih2ٸhu-%%c-uVCj$&K|p'0ϐІ &\\i)$l:#%$eX28e8E52/Ñ~C "%Ȱ(Pa#xJ1¯0A2_p"2R/Ñb Ǣ9| 5 ۿ0D)ΟƷM 9PP5p-͞Vni`dNԎk&)OVr"&sna./ʹ'&FʓycѼ $Gg8O@pwŸǵ >n?124wǸI뇓9﨏 M'~n(h ǦȘoh`BF =2oȣc 8O}C+STP]SͥW8[oipk*fOg -q M:(N؏#ҏ -P1@M(5#j؅0jD5#HnpA4hQI 3y@C+)K;2\TmBv0&A1Ѳ/=gY  YIFyh`x`p8xxQy'aeVa'@} (r@6?P6+^F_ *Ǥ##@(L( 2nICQ- -D5`<09cQ4Dt_|Vpae(6<50NK~jjIU^O~ @t ƕ OJ/BZQ῅1>Ux@0! -3o ?Nap_!Fl ~N8 ]zjF6?*lp/ʆ=_0Qy_Շ6S G@XM@ : lҷvVڄnR- -e τ~c2~B m$T[1K5PIC%. *4`GpPr52 Bd"9jQ3j#[hSQkP uCm6;zX -endstream -endobj -102 0 obj -<< /Type /FontDescriptor -/FontName /be376d+mplus1mn-regular -/FontFile2 101 0 R -/FontBBox [0 -270 1000 1025] -/Flags 4 -/StemV 0 -/ItalicAngle 0 -/Ascent 860 -/Descent -140 -/CapHeight 860 -/XHeight 0 ->> -endobj -103 0 obj -<< /Length 1278 -/Filter [/FlateDecode] ->> -stream -xenFὮBtHs&@nu{stԒ + }ik/y_!}t~]snVyg쾝+|<.÷}v)[eO/_q9_ɯ}ഏOmt_LLv͵LJ1w9)e6=n?[i(JKiU:JSz2QeL*EJ̔Ye,*+eU(NU-уk5x5F^ky ^#k5x5F^ky ^#kxZV^kZy-^+kxZV^kZy-^+uxu:N^:y^'uxu:N^:y^'xz^^zy=^/xz^^zy=^/o xo7 Aހ7y o xo7 Aހ7y oxo7jo$JI$$*I$ITH$$QI"IDD%$JI$$*I$ITD$$III$$u>M&Iބ7ɛ&y$o›Mx o7M&Iބ7ɛ&yUoa[5joSor4ۂsޮ>,x/x;Â31x; -JJ특xxx+!ÊwBxbx+ށr;2kΜJYeY7+|x oS7+[ƛețךyޢoV浖 -㭌"RW*4XqC^J[(^1»y]k}YM-x e#e_y+h܊7k:/Z5dUluz5n[eB&Si|y(%q& %+S%*ABijPU6\h,(+L,4G5sh>:OVRP*#i|e0U,*oU/*[U,Nmlx:&\}M)L2\%CHF7էʻBL)jƻJ1:%H߯:=S۳zrmkO媳7 -endstream -endobj -104 0 obj -[500 364 500 364 500 500 364 500 500 500 364 364 500 500 500 500 500 500 364 500 364 500 364 364 500 500 500 500 500 500 500 364 364 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 364 500 364 364 364 364 364 500 364 500 500 500 500 500 500 500 500 500 364 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 364 500 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364 364] -endobj -105 0 obj -<< /Length1 6560 -/Length 3565 -/Filter [/FlateDecode] ->> -stream -xW}pSWv?=}S2 x@!ٖd Id@GXL 1$MgHۙR ΤfaN?8ӖLƉQϽz26km={{9>jaD w,G$hd<%g[;lϫ47&@ p4#q93[h_s E -OJ PДA߻ߕHZG~"3.CϐײJ.1i9uK%m@šl&>y珠3Sr;8lOW9k#}K6Ҵ;LgkJY{,9"Ÿ ~Fm3hZDJ@`x$ %`|؉Qb?,hCi'WPPz WPYf8b& ,B#I|E} ' -0Ѐшt #ZJaq/&qgz5fw3ä^&͈lB& Å[4ؖAHV$W֕h]"_!݇pm|mP9XQV ARc8V)+p -_*q3ЄM@{bF1(r>9r8W&XYg6y5߭86bsܒyH\$N1YY-`eBUd;:}G dHObu;r{noߟmNl"ݺ{csMs';Hygz#scX%.gE,Y%t ]?w]8~ww/^e‡KsMfCɄ܉/}1Wl8&brG GF?7wn -q\UDz9=5sJ@600n:5h+H\M|z*.Zb&,wL1rm.omX0//ݸ  -W7,NrKç n'½wc6~[]_JE"svO}u;!L8|"aWy`:+ޅdZvw6lb2K;^0N9?}t#_I—7nk[2uB+@%r%Ziv·uV8F&M :mF:mA|N+>J*|[VrZkt-losCrg4zѢ#ni.6bB(NQ:mI+`Z+Acr e[n+u7% طd -;he<UJ̨WrXOf"R&Qt' -i<ŞRrd&Mw;$G|ipUdd*wh&6ߘsVx9U&iq%JǦrrGBUG .td㙔3NT8׈S9WGk4 $0do&R&^s -[Dr\IqtTQ5P$*ɒB}tcgd^%&q554>Ni_(GG>ޡA/DKt7nJQlNi&GDʯ(ώ2x2r:>)qY%JB~(?Tey%fL$z²rdVw\9= ,LA@)cO'@A·}-nD&p]sNQA_籏 Z(9 ?җpLsFP%#ߎm#t,=űT=Fa } > -endobj -107 0 obj -<< /Length 226 -/Filter [/FlateDecode] ->> -stream -x]j >E B^rШswt-0y/NX -ni/a%D6Hp֛ݮ&3Ntl1J1AV'f|`8,!.pL=\1VLkpiыɯfE;P31GF]069ܲXL\)!^3%)LI:=M(;u~xeR(R?CRKnGo -endstream -endobj -108 0 obj -[259 1000 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600] -endobj -109 0 obj -<< /Length1 6532 -/Length 3675 -/Filter [/FlateDecode] ->> -stream -x9l[y߽GR-)GGHKI-ű]զ$MGHڤ|4=v6/:c5Y5՞,A1,O)%:-؊a2XEe~6 gxw@=́ѠomoH -9DhBnը6Cm9P"/OIYA>yԯKN_Htϧ9^MᏰL!nm?ψOgdh1q|>'Ff?\~,U}C8=5A`s%uY[gPkV޻)d (y| Yunis9E?;9FU6SqK*r|܃˽ - Ԛ$xehtt@Q:/D*6:̉qw;/9|OdGnG[KcVZe1D@WŨMp% &BLHmiѭnL'.K%A_W'JTGxy~ælC@ mIyNbԫfSEõjkAjjEH#Ȟ%ذxiu8]~^p reP&i/ӥwW0sť\De-b[zS+y/g蝒ǫ;8!nnKt?J 0Ї-}cEy47)QT\+ar靗[uߕnccو.hJF -IChEfal@`80nDDq -7rFu!8V8Maƙpcf3uS?.y1/$THvVT@\Wx jmVTv^>n:av7ffS-hvurCA-9.s=<}Kz>[t0U 5qP62M39h -#oCOR/m腨n5-F -]VQlQb4F;] EA)0~:rp`LHֲ\J#BEA;i[݊ՎThBER1Ũ-5 Cp#(N5,؎4I,-,4")RTJQ=asc1c5, 8]AX0uusp!6-Z@ȌKA@:>O -b$ _1%8hQNjR0ǥ"k;H 4ՉD./v|^EnD D@^mNB,M bo8 Z&i -ԲP+4i2i`ZRc<4T1ek1"#:btKD52J~яF•AIWEW ߙ H#U ;)oaKF ˄;p?6V -%RKZxl+kdn#;՝( [BlCԡL-q(kI Ҫd5u>XQFV+XEƯ1bF;&E# X8﷬*∌VY"y-GovJm;$xrcmC㷉}&[=G H𿊥Ѷ$]zu׈ׄKkkDj:wT x,E[$EH[ `ze[ 3ÅoȎ6 ٧CYq'i ?Ve*YЍdJfMq)¾;F\Yg6&t&$TSoIɱhx%|+6> PM!bzZ=Mb {la -!neVl61 /[ -&\31eR(tJ{V' kue§,y#zlW4p3`f9y!Yyq'T oTZpF%g3( ¦,v(gQ+8LɆSكDH,#7?j:WJְxkZރI9Oݧ| ? | 7Xwke~ -u[/<*7Tݴ{ GB]s oSS%aR,ٶH;=siAarq* H)Y9>%8s"7STnj+zt؀En6W ،$ ؂eՀ`72l==Yc5 gwo; o#Rv -j`0F P/ X#lF1bfh -u![Z´j6Jԩ|:jz;OF}'`yHM>؏-!f> -b~|OL^Џi'ֵT)+hk8JBx1$aAF3p Gy$Q6-w}NrHEY8nMiUCITxy|/PH ʻU z~Pc?oس9&"R}=5dazZ_KVJ%(% -endstream -endobj -110 0 obj -<< /Type /FontDescriptor -/FontName /b1eed4+NotoSerif -/FontFile2 109 0 R -/FontBBox [-212 -250 1246 1047] -/Flags 6 -/StemV 0 -/ItalicAngle 0 -/Ascent 1068 -/Descent -292 -/CapHeight 1462 -/XHeight 1098 ->> -endobj -111 0 obj -<< /Length 228 -/Filter [/FlateDecode] ->> -stream -x]n <"ANi.9liD!o?CNЏyx/?r4#p>،kܲAp7Z7N7Wl9SvJ1U/}p0 -endstream -endobj -112 0 obj -[259 354 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500 500] -endobj -113 0 obj -<< /Length1 8496 -/Length 5159 -/Filter [/FlateDecode] ->> -stream -x8 XSwN~BR#'* jHBs@$&AիicN{[Ok[=ZvO:WۭٹuߗmwϽ'9|'@ i=< @|HuCKrֿ~'@H[%J| V@0EơknG8x/!!Ah F7 *^QPtoqDą{;tk3 -Fǽ"1J+d\l9җ)I@S|ok\A$᝸P/idXI,|mQf B3!zs3&+p)jNVMTpõe% )CQ"B)΀Qt1Փ7]U$>tqAئ-. -EWſAfV [$A͍^|e,{ #WkIӒNI =d.himi^ְj1Wc˖.Z\pd^Qa\1ߘcХMOIըUMvgLR<s-mBIiWsbL!,5u2Yy.Ĵd)T%cHt)( KE4CXEKnDj(N)-J LvaV>$$X{-d*dGKђLV ]Y\ ԖyF+ˡ:-T8U5Iy\vZ5JN,pvҍ3%dt9($Ԝzљ0[NJ*H\.߉:$qIx0JjrIraBݐ VEj&i(vrUZ![PF$Ԇ _Oqhh.sW}dnuhzXd+jMJ Ȟ@h2ɕV2p6bIb=FA@m-l^˺X&Ǝf5i/hD'&ڝ˙4>AMCij--YHv5.qnwWN ƅq܆FsѨGB2P\X:#L -RHH2Ә4؆78C™g<(Yr.A5O0BoAoF9e›T} w;~Y; >ǸCՇHC|[U%0j̋] - HcffA %z˟$DTWg4Bi[=zF +),RKs\w2eꏙlT@<?"dy\@!1ÛATɸxVi0V}}z RIO^?-7S0R hU\3_!#ĝ%?~ k~'n1%U*UWգnrY/mꧻse _Γbf>:Uaȉ:0.QUk 勪fhʊB18}ŭ{:v>0nYWoxҽ}JQ2X1U.p n\KuaP:udqeE12G:tZC^ ︱;:n `&нeLxitH"LY|$+?WQz9y{¶&Wۖ ߗ@? |󋪲pUXي"]#sgs,#7\ROg7;yd~?;Y![wܲ>>>&TgT߂b\kqe-" ɐGTQȨX\UXT2d姑,-KQ*o_Y!_?k?гf^}š#G%}zb|Ừwok4n/Os$%p`΂/T;=M;C}H6fۏE]NoZ^_'vAen _:E9? $9!KZ 𫚃WYcZ twіaW?T]һ:݇ȵif4V-܄,[}ʤDDIpOvgVuhgjZ6}tl6fu(jTk(V'9Z9ˁV'>J;*gVy33k%ff"xBqzYYv-|R!˘9@n+M+׶\j32⬶Oʱ%u?;#sm֧+d=cـTVýs]}w]ٖ<߽amg--.SG^ںֺm[Q/~#ԶOSjU2˵Z12O1l}, ݕxAU=WHާCcCXx"G=OQ .u|/w}o$ϲVcuɺs ZN/ݱyL'Md,QjbQ&`u -A*?Wyh( - -~kOIWxS - kU -+TO)p*,Wӹ(pTh_ ~_TX`"ae0?l2f`@hx`4(ؽa-j ~T."$dn"tx0 ,,[PdEޞb*DJ'#[;|M+O!Z@h-[Qt_{=BϰpMؓp/ -36mT+ Q -M؃:W+?C냁`E7^ Dp͡>`ZB@BxUBDe­yh3(5vfjk6{p.YVnڅ6bk4#V/4w -MfK;a9F"B0,C~*پ -}D$܁!w?F/Qwpk885zSuh,( M-B?X `!DnE|!TۮiEً6AfԎ-hChk5LfH1~p.Ҋ0?`tE+(&iY n(F̗0% -(Q|fzՎu-8F/>f#s< Ѓ[XLU,jEQf>M}PzdekeM{Q֤X"tkVn!!潝EC\䣬^4QB3VDռ(QBêH1Y;fv-l˫X(AʭBg6G.A n6cY PpQ?DkiñqXn RZ ^=fĹ 9TW3f;!| 8J3> -endobj -115 0 obj -<< /Length 1278 -/Filter [/FlateDecode] ->> -stream -xenFὮBtHs&@nu{stԒ + }ik/y_!}t~]snVyg쾝+|<.÷}v)[eO/_q9_ɯ}ഏOmt_LLv͵LJ1w9)e6=n?[i(JKiU:JSz2QeL*EJ̔Ye,*+eU(NU-уk5x5F^ky ^#k5x5F^ky ^#kxZV^kZy-^+kxZV^kZy-^+uxu:N^:y^'uxu:N^:y^'xz^^zy=^/xz^^zy=^/o xo7 Aހ7y o xo7 Aހ7y oxo7jo$JI$$*I$ITH$$QI"IDD%$JI$$*I$ITD$$III$$u>M&Iބ7ɛ&y$o›Mx o7M&Iބ7ɛ&yUoa[5joSor4ۂsޮ>,x/x;Â31x; -JJ특xxx+!ÊwBxbx+ށr;2kΜJYeY7+|x oS7+[ƛețךyޢoV浖 -㭌"RW*4XqC^J[(^1»y]k}YM-x e#e_y+h܊7k:/Z5dUluz5n[eB&Si|y(%q& %+S%*ABijPU6\h,(+L,4G5sh>:OVRP*#i|e0U,*oU/*[U,Nmlx:&\}M)L2\%CHF7էʻBL)jƻJ1:%H߯:=S۳zrmkO媳7 -endstream -endobj -116 0 obj -[259 600 600 600 600 600 600 600 346 346 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 579 600 600 579 493 317 556 599 304 600 600 600 895 599 574 577 600 467 463 368 599 600 818 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600 600] -endobj -xref -0 117 -0000000000 65535 f -0000000015 00000 n -0000000235 00000 n -0000000437 00000 n -0000000550 00000 n -0000000601 00000 n -0000000873 00000 n -0000001072 00000 n -0000001368 00000 n -0000001532 00000 n -0000006464 00000 n -0000006868 00000 n -0000006912 00000 n -0000006961 00000 n -0000007417 00000 n -0000009221 00000 n -0000009562 00000 n -0000009606 00000 n -0000009776 00000 n -0000030499 00000 n -0000030945 00000 n -0000030989 00000 n -0000031033 00000 n -0000031200 00000 n -0000031244 00000 n -0000031414 00000 n -0000031578 00000 n -0000031742 00000 n -0000031917 00000 n -0000032085 00000 n -0000032258 00000 n -0000032426 00000 n -0000032592 00000 n -0000032759 00000 n -0000032921 00000 n -0000055137 00000 n -0000055548 00000 n -0000055716 00000 n -0000055760 00000 n -0000055927 00000 n -0000055971 00000 n -0000056134 00000 n -0000056299 00000 n -0000080415 00000 n -0000080806 00000 n -0000080850 00000 n -0000081017 00000 n -0000081184 00000 n -0000081228 00000 n -0000106890 00000 n -0000107283 00000 n -0000107458 00000 n -0000118417 00000 n -0000118797 00000 n -0000118841 00000 n -0000142540 00000 n -0000142937 00000 n -0000142981 00000 n -0000143025 00000 n -0000143226 00000 n -0000143270 00000 n -0000143314 00000 n -0000143358 00000 n -0000143402 00000 n -0000143446 00000 n -0000143570 00000 n -0000143696 00000 n -0000143816 00000 n -0000143939 00000 n -0000144063 00000 n -0000144187 00000 n -0000144311 00000 n -0000144436 00000 n -0000144556 00000 n -0000144677 00000 n -0000144811 00000 n -0000144945 00000 n -0000145019 00000 n -0000145137 00000 n -0000145325 00000 n -0000145493 00000 n -0000145676 00000 n -0000145823 00000 n -0000145974 00000 n -0000146136 00000 n -0000146310 00000 n -0000146476 00000 n -0000146520 00000 n -0000146793 00000 n -0000147066 00000 n -0000156784 00000 n -0000156996 00000 n -0000158350 00000 n -0000159264 00000 n -0000167990 00000 n -0000168207 00000 n -0000169561 00000 n -0000170475 00000 n -0000174106 00000 n -0000174314 00000 n -0000175668 00000 n -0000176583 00000 n -0000182298 00000 n -0000182511 00000 n -0000183866 00000 n -0000184781 00000 n -0000188437 00000 n -0000188656 00000 n -0000188958 00000 n -0000189874 00000 n -0000193640 00000 n -0000193854 00000 n -0000194158 00000 n -0000195073 00000 n -0000200323 00000 n -0000200547 00000 n -0000201902 00000 n -trailer -<< /Size 117 -/Root 2 0 R -/Info 1 0 R ->> -startxref -202817 -%%EOF diff --git a/docs/metaData/Apps.adoc b/docs/metaData/Apps.adoc new file mode 100644 index 00000000..bf2f8317 --- /dev/null +++ b/docs/metaData/Apps.adoc @@ -0,0 +1,92 @@ +[#Apps] +== Apps +include::../variables.adoc[] + +QQQ User Interfaces (e.g., Material Dashboard) generally organize their contents via *Apps*. +Apps are a lightweight construct in QQQ - basically just containers for other objects. + +Specifically, Apps can contain: + +* {link-widgets} +* {link-tables} +* {link-process} +* {link-reports} +* Other {link-apps} - to create a multi-tiered navigational hierarchy. + +=== QAppMetaData +Apps are defined in a QQQ Instance in `*QAppMetaData*` objects. Apps must consist of either 1 or more {link-widgets}, or 1 or more *Sections*, which are expected to contain 1 or more {link-tables}, {link-processes}, or {link-reports}. + +*QAppMetaData Properties:* + +* `name` - *String, Required* - Unique name for the app within the QQQ Instance. +* `label` - *String* - User-facing label for the app, presented in User Interfaces. +Inferred from `name` if not set. +* `permissionRules` - *QPermissionRules* - Permissions to apply to the app. See {link-permissionRules} for details. +* `children` - *List of QAppChildMetaData* - Objects contained within the app. These can be {link-tables}, {link-processes}, {link-reports} or other {link-apps}. +** See the example below for some common patterns for how these child-meta data objects are added to an App. +* `parentAppName` - *String* - For an app which is a child of another app, the parent app's name is referenced in this field. +** Note that this is generally automatically set when the child is added to its parent, in the `addChild` method. +* `icon` - *QIcon* - An icon to display in a UI for the app. See {link-icons}. +* `widgets` - *List of String* - A list of names of {link-widgets} to include in the app. +* `sections` - *List of <>* - A list of `QAppSection` objects, to create organizational subdivisions within the app. +** As shown in the example below, the method `withSectionOfChildren` can be used to fluently add a new `QAppSection`, along with its child objects, to both an app and a section all at once. + +==== QAppSection +A `QAppSection` is an organizational subsection of a {link-app}. + +* `name` - *String, Required* - Unique name for the section within its app. +* `label` - *String* - User-facing label for the section, presented in User Interfaces. +Inferred from `name` if not set. +* `icon` - *QIcon* - An icon to display in a UI for the section. See {link-icons}. +* `tables` - *List of String* - A list of names of {link-tables} to include in the section. +* `processes` - *List of String* - A list of names of {link-processes} to include in the section. +* `reports` - *List of String* - A list of names of {link-reports} to include in the section. + +*Examples* +[source,java] +---- +/******************************************************************************* +** Full example of constructing a QAppMetaData object. +*******************************************************************************/ +public class ExampleAppMetaDataProducer extends MetaDataProducer +{ + + /******************************************************************************* + ** Produce the QAppMetaData + *******************************************************************************/ + @Override + public QAppMetaData produce(QInstance qInstance) throws QException + { + return (new QAppMetaData() + .withName("sample") + .withLabel("My Sample App") + .withIcon(new QIcon().withName("thumb_up")) + .withWidgets(List.of( + UserWelcomeWidget.NAME, + SystemHealthLineChartWidget.NAME)) + .withSectionOfChildren(new QAppSection().withName("peoplePlacesAndThings"), + qInstance.getTable(People.TABLE_NAME), + qInstance.getTable(Places.TABLE_NAME), + qInstance.getTable(Things.TABLE_NAME), + qInstance.getProcess(AssociatePeopleWithPlacesProcess.NAME)) + .withSectionOfChildren(new QAppSection().withName("math").withLabel("Mathematics"), + qInstance.getProcess(ComputePiProcess.NAME), + qInstance.getReport(PrimeNumbersReport.NAME), + qInstance.getReport(PolygonReport.NAME))); + } + + + /******************************************************************************* + ** Since this meta-data producer expects to find other meta-data objects in the + ** QInstance, give it a sortOrder higher than the default (which we'll expect + ** the other objects used). + *******************************************************************************/ + @Override + public int getSortOrder() + { + return (Integer.MAX_VALUE); + } + +} +---- + diff --git a/docs/metaData/Backends.adoc b/docs/metaData/Backends.adoc new file mode 100644 index 00000000..4cf3d575 --- /dev/null +++ b/docs/metaData/Backends.adoc @@ -0,0 +1,150 @@ +[#Backends] +== Backends +include::../variables.adoc[] + +A key component of QQQ is its ability to connect to various backend data stores, while providing the same interfaces to those backends - both User Interfaces, and Programming Interfaces. + +For example, out-of-the-box, QQQ can connect to: + +* <> (Relational Database Management Systems, such as MySQL) +* File Systems (<> or <>) +* <> (_using a custom mapping class per-API backend_). +* In-Memory data stores + +All {link-tables} in a QQQ instance must belong to a backend. As such, any instance using tables (which would be almost all instances) must define 1 or more backends. + +=== QBackendMetaData +Backends are defined in a QQQ Instance in a `*QBackendMetaData*` object. +These objects will have some common attributes, but many different attributes based on the type of backend being used. + +*QBackendMetaData Properties:* + +* `name` - *String, Required* - Unique name for the backend within the QQQ Instance. +* `backendType` - *String, Required* - Identifier for the backend type being defined. +** This attribute is typically set in the constructor of a `QBackendMetaData` subclass, and as such does not need to be set when defining a backend meta data object. +* `enabledCapabilities` and `disabledCapability` - *Sets*, containing *Capability* enum values. +Basic rules that apply to all tables in the backend, describing what actions (such as Delete, or Count) are supported in the backend. +** By default, QQQ assumes that a backend supports _most_ capabilities, with one exception being `QUERY_STATS`. +** #TODO# fully explain rules here +* `usesVariants` - *Boolean, default false* - Control whether or not the backend supports the concept of "Variants". +** Supporting variants means that tables within the backend can exist in alternative "variants" of the backend. +For example, this might mean a sharded or multi-tenant database backend (perhaps a different server or database name per-client). +Or this might mean using more than one set of credentials for connecting to an API backend - each of those credential sets would be a "variant". +** A backend that uses variants requires additional properties to be set. #TODO complete variant documentation# + +In a QQQ application, one will typically not create an instance of `QBackendMetaData` directly, but instead will create an instance of one of its subclasses, specific to the type of backend being used. +The currently available list of such classes are: + +==== RDBMSBackendMetaData +The meta data required for working with tables in an RDBMS (relational database) backend are defined in an instance of the `*RDBMSBackendMetaData*` class. + +*RDBMSBackendMetaData Properties:* + +* `vendor` - *String, Required* - Database vendor. Currently supported values are: `aurora`, `mysql`, `h2`. +* `jdbcUrl` - *String, Optional* - Full JDBC URL for connecting to the database. +** If this property is provided, then following properties (which are the components of a JDBC URL) are ignored. +In other words, you can either provide the `jdbcUrl`, or the individual components that make it up. +* `hostName` - *String, Conditionally Required* - Hostname or ip address of the RDBMS server. +* `port` - *Integer, Conditionally Required* - Port used to connect to the RDBMS server. +* `databaseName` - *String, Conditionally Required* - Name of the database being connected to, within the RDBMS server. +* `username` - *String, Conditionally Required* - Username for authenticating in the database server. +* `password` - *String, Conditionally Required* - Password for authenticating in the database server. + +*Examples* +[source,java] +---- +/******************************************************************************* +** Full example of constructing an RDBMSBackendMetaData +*******************************************************************************/ +public class ExampleDatabaseBackendMetaDataProducer extends MetaDataProducer +{ + public static final String NAME = "rdbmsBackend"; + + /******************************************************************************* + ** Produce the QBackendMetaData + *******************************************************************************/ + @Override + public QBackendMetaData produce(QInstance qInstance) + { + /////////////////////////////////////////////////////////////////////// + // read settings from either a .env file or the system's environment // + /////////////////////////////////////////////////////////////////////// + QMetaDataVariableInterpreter interpreter = new QMetaDataVariableInterpreter(); + String vendor = interpreter.interpret("${env.RDBMS_VENDOR}"); + String hostname = interpreter.interpret("${env.RDBMS_HOSTNAME}"); + String port = interpreter.interpret("${env.RDBMS_PORT}"); + String databaseName = interpreter.interpret("${env.RDBMS_DATABASE_NAME}"); + String username = interpreter.interpret("${env.RDBMS_USERNAME}"); + String password = interpreter.interpret("${env.RDBMS_PASSWORD}"); + + return (new RDBMSBackendMetaData() + .withName(NAME) + .withVendor(vendor) + .withHostName(hostname) + .withPort(ValueUtils.getValueAsInteger(port)) + .withDatabaseName(databaseName) + .withUsername(username) + .withPassword(password) + .withCapability(Capability.QUERY_STATS)); + } +} +---- + +==== S3BackendMetaData +The meta data required for working with tables in an Amazon S3 backend are defined in an instance of the `*S3BackendMetaData*` class. + +*S3BackendMetaData Properties:* + +* `bucketName` - *String, Required* - Bucket name to connect to inside AWS S3. +* `accessKey` - *String, Required* - Access key for connecting to S3 inside AWS S3. +* `secretKey` - *String, Required* - Secret key for connecting to S3 inside AWS S3. +* `region` - *String, Required* - AWS region containing the Bucket in S3. +* `basePath` - *String, Required* - Base path to the files within the S3 bucket. + +==== FilesystemBackendMetaData +The meta data required for working with tables in a (local) filesystem backend are defined in an instance of the `*FilesystemBackendMetaData*` class. + +*FilesystemBackendMetaData Properties:* + +* `basePath` - *String, Required* - Base path to the backend's files. + +==== APIBackendMetaData +The meta data required for working with tables in a web API are defined in an instance of the `*APIBackendMetaData*` class. + +QQQ provides a minimal, reasonable default implementation for working with web APIs, making assumptions such as using `POST` to insert records, and `GET` with a primary key in the URL to get a single record. +However, in our experience, almost all APIs are implemented differently enough, that a layer of custom code is required. +For example, query/search endpoints are almost always unique in how they take their search parameters, and how they wrap their output. + +To deal with this, a QQQ API Backend can define a custom class in the `actionUtil` property of the backend meta-data, as a subclass of `BaseAPIActionUtil`, which ideally can override methods at the level where unique functionality is needed. +For example, an application need not define the full method for executing a Query against an API backend (which would need to make the HTTP request (actually multiple, to deal with pagination)). +Instead, one can just override the `buildQueryStringForGet` method, where the unique details of making the request are defined, and maybe the `jsonObjectToRecord` method, where records are mapped from the API's response to a QRecord. + +#todo - full reference and examples for `BaseAPIActionUtil`# + +*APIBackendMetaData Properties:* + +* `baseUrl` - *String, Required* - Base URL for connecting to the API. +* `contentType` - *String, Required* - value of `Content-type` header included in all requests to the API. +* `actionUtil` - *QCodeReference, Required* - Reference to a class that extends `BaseAPIActionUtil`, where custom code for working with this API backend is defined. +* `customValues` - *Map of String → Serializable* - Application-defined additional name=value pairs that can +* `authorizationType` - *Enum, Required* - Specifies how authentication is provided for the API. +The value here, dictates which other authentication-related properties are required. +Possible values are: +** `API_KEY_HEADER` - Uses the `apiKey` property in an HTTP header named `API-Key`. +_In the future, when needed, QQQ will add a property, tentatively named `apiKeyHeaderName`, to allow customization of this header name._ +** `API_TOKEN` - Uses the `apiKey` property in an `Authroization` header, as: `"Token " + apiKey` +** `BASIC_AUTH_API_KEY` - Uses the `apiKey` property, Base64-encoded, in an `Authroization` header, as `"Basic " + base64(apiKey)` +** `BASIC_AUTH_USERNAME_PASSWORD` - Combines the `username` and `password` properties, Base64-encoded, in an `Authroization` header, as `"Basic " + base64(username + ":" + password)` +** `OAUTH2` - Implements an OAuth2 client credentials token grant flow, using the properties `clientId` and `clientSecret`. +By default, the id & secret are sent as query-string parameters to the API's `oauth/token` endpoint. +Alternatively, if the meta-data has a `customValue` of `setCredentialsInHeader=true`, then the id & secret are posted in an `Authorization` header (base-64 encoded, and concatenated with `":"`). +** `API_KEY_QUERY_PARAM` - Uses the `apiKey` property as a query-string parameter, with its name taken from the `apiKeyQueryParamName` property. +** `CUSTOM` - Has a no-op implementation at the QQQ layer. +Assumes that an override of `protected void handleCustomAuthorization(HttpRequestBase request)` be implemented in the backend's `actionUtil` class. +This would be +* `apiKey` - *String, Conditional* - See `authorizationType` above for details. +* `clientId` - *String, Conditional* - See `authorizationType` above for details. +* `clientSecret` - *String, Conditional* - See `authorizationType` above for details. +* `username` - *String, Conditional* - See `authorizationType` above for details. +* `password` - *String, Conditional* - See `authorizationType` above for details. +* `apiKeyQueryParamName` - *String, Conditional* - See `authorizationType` above for details. diff --git a/docs/metaData/Fields.adoc b/docs/metaData/Fields.adoc index d494ff5f..93d11dcd 100644 --- a/docs/metaData/Fields.adoc +++ b/docs/metaData/Fields.adoc @@ -1,4 +1,5 @@ -== QQQ Fields +[#Fields] +== Fields include::../variables.adoc[] QQQ Fields define diff --git a/docs/metaData/Joins.adoc b/docs/metaData/Joins.adoc new file mode 100644 index 00000000..4ce09ea3 --- /dev/null +++ b/docs/metaData/Joins.adoc @@ -0,0 +1,17 @@ +[#Joins] +== Joins +include::../variables.adoc[] + +#TODO# + +=== QJoinMetaData +Joins are defined in a QQQ Instance in a `*QJoinMetaData*` object. + +#TODO# + +*QJoinMetaData Properties:* + +* `name` - *String, Required* - Unique name for the join within the QQQ Instance. #todo infererences or conventions?# + +#TODO# + diff --git a/docs/metaData/PossibleValueSources.adoc b/docs/metaData/PossibleValueSources.adoc new file mode 100644 index 00000000..f707a7c6 --- /dev/null +++ b/docs/metaData/PossibleValueSources.adoc @@ -0,0 +1,17 @@ +[#PossibleValueSources] +== Possible Value Sources +include::../variables.adoc[] + +#TODO# + +=== QPossibleValueSource +A Possible Value Source is defined in a QQQ Instance in a `*QPossibleValueSource*` object. + +#TODO# + +*QPossibleValueSource Properties:* + +* `name` - *String, Required* - Unique name for the possible value source within the QQQ Instance. + +#TODO# + diff --git a/docs/metaData/Processes.adoc b/docs/metaData/Processes.adoc new file mode 100644 index 00000000..253f6318 --- /dev/null +++ b/docs/metaData/Processes.adoc @@ -0,0 +1,216 @@ +[#Processes] +== Processes + +include::../variables.adoc[] + +Besides {link-tables}, the other most common type of object in a QQQ Instance is the Process. +Processes are "custom" actions (e.g., defined by the application developers, rather than QQQ) that users and/or the system can execute against records. +Processes generally are made up of two types of sub-objects: + +* *Screens* - i.e., User Interfaces (e.g., for gathering input and/or showing output). +* *BackendSteps* - Java classes (of type `BackendStep`) that execute the logic of the process. + +=== QProcessMetaData + +Processes are defined in a QQQ Instance in a `*QProcessMetaData*` object. +In addition to directly building a `QProcessMetaData` object setting its properties directly, there are a few common process patterns that provide *Builder* objects for ease-of-use. +See StreamedETLWithFrontendProcess below for a common example + +*QProcessMetaData Properties:* + +* `name` - *String, Required* - Unique name for the process within the QQQ Instance. +* `label` - *String* - User-facing label for the process, presented in User Interfaces. +Inferred from `name` if not set. +* `icon` - *QIcon* - Icon associated with this process in certain user interfaces. +See {link-icons}. +* `tableName` - *String* - Name of a {link-table} that the process is associated with in User Interfaces (e.g., Action menu). +* `isHidden` - *Boolean, default false* - Option to hide the process from all User Interfaces. +* `basepullConfiguration` - *<>* - config for the common "Basepull" pattern, of identifying records with a timestamp greater than the last time the process was ran. +See below for details. +* `permissionRules` - *QPermissionRules object* - define the permission/access rules for the process. +See {link-permissionRules} for details. +* `steps` and `stepList` - *Map of String → <>* and *List of QStepMetaData* - Defines the <> and <> that makes up the process. +** `stepList` is the list of steps in the order that they will by default be executed. +** `steps` is a map, including all steps from `stepList`, but which may also include steps which can used by the process if its backend steps make the decision to do so, at run-time. +** A process's steps are normally defined in one of two was: +*** 1) by a single call to `.withStepList(List)`, which internally adds each step into the `steps` map. +*** 2) by multiple calls to `.addStep(QStepMetaData)`, which adds a step to both the `stepList` and `steps` map. +** If a process also needs optional steps, they should be added by a call to `.addOptionalStep(QStepMetaData)`, which only places them in the `steps` map. +* `schedule` - *<>* - set up the process to run automatically on the specified schedule. +See below for details. +* `minInputRecords` - *Integer* - #not used...# +* `maxInputRecords` - *Integer* - #not used...# + +#todo: supplementalMetaData (API)# + +==== QStepMetaData + +This is the base class for the two types of steps in a process - <> and <>. +There are some shared attributes of both of them, defined here. + +*QStepMetaData Properties:* + +* `name` - *String, Required* - Unique name for the step within the process. +* `label` - *String* - User-facing label for the step, presented in User Interfaces. +Inferred from `name` if not set. +* `stepType` - *String* - _Deprecated._ + +==== QFrontendStepMetaData + +For processes with a user-interface, they must define one or more "screens" in the form of `QFrontendStepMetaData` objects. + +*QFrontendStepMetaData Properties:* + +* `components` - *List of <>* - a list of components to be rendered on the screen. +* `formFields` - *List of String* - list of field names used by the screen as form-inputs. +* `viewFields` - *List of String* - list of field names used by the screen as visible outputs. +* `recordListFields` - *List of String* - list of field names used by the screen in a record listing. + +==== QFrontendComponentMetaData + +A screen in a process may consist of multiple "components" - e.g., help text, and a form, and a list of records. +Each of these components are defined in a `QFrontendComponentMetaData`. + +*QFrontendComponentMetaData Properties:* + +* `type` - *enum, Required* - The type of component to display. +Each component type works with different keys in the `values` map. +Possible values for `type` are: +** `EDIT_FORM` - Displays a list of fields for editing, similar to a record edit screen. +Requires that `formFields` be populated in the step. +** `VIEW_FORM` - Displays a list of fields for viewing (not editing), similar to a record view screen. +Requires that `viewFields` be populated in the step. +** `HELP_TEXT` - Block of help text to be display on the screen. +Requires an entry in the component's `values` map named `"text"`. +** `HTML` - Block of custom HTML, generated by the process backend. +Expects a process value named `html`. +** `DOWNLOAD_FORM` - Presentation of a link to download a file generated by the process. +Expects process values named `downloadFileName` and `serverFilePath`. +** `GOOGLE_DRIVE_SELECT_FOLDER` - Special form that presents a UI from Google Drive, where the user can select a folder (e.g., as a target for uploading files in a subsequent backend step). +** `BULK_EDIT_FORM` - For use by the standard QQQ Bulk Edit process. +** `VALIDATION_REVIEW_SCREEN` - For use by the QQQ Streamed ETL With Frontend process family of processes. +Displays a component prompting the user to run full validation or to skip it, or, if full validation has been ran, then showing the results of that validation. +** `PROCESS_SUMMARY_RESULTS` - For use by the QQQ Streamed ETL With Frontend process family of processes. +Displays the summary results of running the process. +** `RECORD_LIST` - _Deprecated. +Showed a grid with a list of records as populated by the process._ +* `values` - *Map of String → Serializable* - Key=value pairs, with different expectations based on the component's `type`. +See above for details. + +==== QBackendStepMetaData + +Process Backend Steps are where custom (at this time, Java, but in the future, potentially, from any supported language) code is executed, to provide the logic of the process. +QQQ comes with several common backend steps, such as for extracting lists of records, storing lists of records, etc. + +*QBackendStepMetaData Properties:* + +* `code` - *QCodeReference, Required* - Reference to the code to be executed for the step. +The referenced code must implement the `BackendStep` interface. +* `inputMetaData` - *QFunctionInputMetaData* - Definition of the data that the backend step expects and/or requires. +Sub-properties are: +** `fieldList` - *List of {link-fields}* - Optional list of fields used by the process step. +In general, a process does not _have to_ specify the fields that its steps use. +It can be used, however, for example, to cause a `defaultValue` to be applied to a field if it isn't specified in the process's input. +It can also be used to cause the process to throw an error, if a field is marked as `isRequired`, but a value is not present. +** `recordListMetaData` - *RecordListMetaData object* - _Not used at this time._ + +==== BasepullConfiguration + +A "Basepull" process is a common pattern where an application needs to perform some action on all new (or updated) records from a particular data source. +To implement this pattern, one needs to store the timestamp of when the action runs, then query the source for records where a date-time field is after that timestamp. + +QQQ helps facilitate this pattern by automatically retrieving and updating that timestamp field, and by building a default query filter based on that timestamp. + +This is done by adding a `BasepullConfiguration` object to a process's meta-data. + +*BasepullConfiguration Properties:* + +* `tableName` - *String, Required* - Name of a {link-table} in the QQQ Instance where the basepull timestamps are stored. +* `keyField` - *String, Required* - Name of a {link-field} in the basepull table that stores a unique identifier for the process. +* `keyValue` - *String* - Optional value to be stored in the `keyField` of the basepull table as the unique identifier for the process. +If not set, then the process's `name` is used. +* `lastRunTimeFieldName` - *String, Required* - Name of a {link-field} in the basepull table that stores the last-run time for the process. +* `hoursBackForInitialTimestamp` - *Integer* - Optional number of hours to go back in time (from `now`) for the first time that the process is executed (i.e., if there is no timestamp stored in the basepull table). +* `timestampField` - *String, Required* - Name of a {link-field} in the table being queried against the last-run timestamp. + +==== QScheduleMetaData + +QQQ can automatically run processes using an internal scheduler, if they are configured with a `QScheduleMetaData` object. + +*QScheduleMetaData Properties* + +* `repeatSeconds` - *Integer, Conditional* - How often the process should be executed, in seconds. +* `repeatMillis` - *Integer, Conditional* - How often the process should be executed, in milliseconds. +Mutually exclusive with `repeatSeconds`. +* `initialDelaySeconds` - *Integer, Conditional* - How long between when the scheduler starts and the process should first run, in seconds. +* `initialDelayMillis` - *Integer, Conditional* - How long between when the scheduler starts and the process should first run, in milliseconds. +Mutually exclusive with `initialDelaySeconds`. +* `variantRunStrategory` - *enum, Conditional* - For processes than run against {link-tables} that use a {link-backend} with Variants enabled, this property controls if the various instances of the process should run in `PARALLEL` or in `SERIAL`. +* `variantBackend` - *enum, Conditional* - For processes than run against {link-tables} that use a {link-backend} with Variants enabled, this property specifies the name of the {link-backend}. + +==== StreamedETLWithFrontendProcess + +A common pattern for QQQ processes to exhibit is called the "Streamed ETL With Frontend" process pattern. +This pattern is to do an "Extract, Transform, Load" job on a potentially large set of records. + +The records are Streamed through the process's steps, meaning, QQQ runs multiple threads - a producer, which is selecting records, and a consumer, which is processing records. +As such, in general, an unlimited number of records can be processed by a process, without worrying about exhausting server resources (e.g., OutOfMemory). + +These processes also have a standard user-interface for displaying a summary of what the process will do (and has done), with a small number of records as a preview. +The goal of the summary is to give the user the big-picture of what the process will do (e.g., X records will be inserted; Y records will be updated), along with a small view of some details on the records that will be stored (e.g., on record A field B will be set to C). + +This type of process uses 3 backend steps, and 2 frontend steps, as follows: + +* *preview* (backend) - does just a little work (limited # of rows), to give the user a preview of what the final result will be - e.g., some data to seed the review screen. +* *review* (frontend) - a review screen, which after the preview step does not have a full process summary, but can generally tell the user how many records are input to the process, and can show a preview of a small number of the records. +* *validate* (backend) - optionally (per input on review screen), does like the preview step, but does it for all records from the extract step. +* *review* (frontend) - a second view of the review screen, if the validate step was executed. +Now that the full validation was performed, a full process summary can be shown, along with a some preview records. +* *execute* (backend) - processes all the rows - does all the work - stores data in the backend. +* *result* (frontend) - a result screen, showing a "past-tense" version of the process summary. + +These backend steps are defined within QQQ, meaning they themselves do not execute any application-defined custom code. +Instead, these steps use the following secondary <>: + +* *Extract* - Fetch the rows to be processed. +Used by preview (but only for a limited number of rows), validate (without limit), and execute (without limit). +* *Transform* - Do whatever transformation is needed to the rows. +Done on preview, validate, and execute. +Always works with a page of records at a time. +Since it is called on the preview & validate steps, it should *NOT* ever store any data (unless it does a specific check to confirm that it is being used on an *execute* step). +* *Load* - Store the records into the backend, as appropriate. +Only called by the execute step. +Always works with a page of records at a time. + +The meta-data for a `StreamedETLWithFrontendProcess` uses several input fields on its steps. +As such, it can be somewhat clumsy and error-prone to fully define a `StreamedETLWithFrontendProcess`. +To improve this programmer-interface, an inner `Builder` class exists within `StreamedETLWithFrontendProcess` (generated by a call to `StreamedETLWithFrontendProcess.processMetaDataBuilder()`). + +*StreamedETLWithFrontendProcess.Builder methods:* + +* `withName(String name) - Set the name for the process. +* `withLabel(String label) - Set the label for the process. +* `withIcon(QIcon icon)` - Set an {link-icon} to be display with the process in the UI. +* `withExtractStepClass(Class)` - Define the Extract step for the process. +If no special extraction logic is needed, `ExtractViaQuery.class` is often a reasonable default. +In other cases, `ExtractViaQuery` can be a reasonable class to extend for a custom extract step. +* `withTransformStepClass(Class)` - Define the Transform step for the process. +If no transformation logic is needed, `NoopTransformStep.class` can be used (though this is not very common). +* `withLoadStepClass(Class)` - Define the Load step for the process. +Several standard implementations exist, such as: `LoadViaInsertStep.class`, `LoadViaUpdateStep.class`, and `LoadViaDeleteStep.class`. +* `withTableName(String tableName)` - Specify the name of the {link-table} that the process should be associated with in the UI. +* `withSourceTable(String sourceTable)` - Specify the name of the {link-table} to be used as the source of records for the process. +* `withDestinationTable(String destinationTable)` - Specify the name of the {link-table} to be used as the destination for records from the process. +* `withSupportsFullValidation(Boolean supportsFullValidation)` - By default, all StreamedETLWithFrontendProcesses do allow the user to choose to run the full validation step. +However, in case cases it may not make sense to do so - so this method can be used to turn off that option. +* `withDoFullValidation(Boolean doFullValidation)` - By default, all StreamedETLWithFrontendProcesses will prompt the user if they want to run the full validation step or not. +However, in case cases you may want to enforce that the validation step always be executed. +Calling this method will remove the option from the user, and always run a full validation. +* `withTransactionLevelAutoCommit()`, `withTransactionLevelPage()`, and `withTransactionLevelProcess()` - Change the transaction-level used by the process. +By default, these processes are ran with a single transaction for all pages of their execute step. +But for some cases, doing page-level transactions can reduce long-transactions and locking within the system. +* `withPreviewMessage(String previewMessage)` - Sets the message shown on the validation review screen(s) above the preview records. +* `withReviewStepRecordFields(List fieldList)` - +* `withFields(List fieldList)` - Adds additional input fields to the preview step of the process. +* `withBasepullConfiguration(BasepullConfiguration basepullConfiguration)` - Add a <> to the process. +* `withSchedule(QScheduleMetaData schedule)` - Add a <> to the process. diff --git a/docs/metaData/Reports.adoc b/docs/metaData/Reports.adoc index 5fdc8db5..26944e33 100644 --- a/docs/metaData/Reports.adoc +++ b/docs/metaData/Reports.adoc @@ -1,4 +1,5 @@ -== QQQ Reports +[#Reports] +== Reports include::../variables.adoc[] QQQ can generate reports based on {link-tables} defined within a QQQ Instance. diff --git a/docs/metaData/SecurtiyKeyTypes.adoc b/docs/metaData/SecurtiyKeyTypes.adoc new file mode 100644 index 00000000..23c4d8f3 --- /dev/null +++ b/docs/metaData/SecurtiyKeyTypes.adoc @@ -0,0 +1,80 @@ +[#SecurityKeyTypes] +== Security Key Types +include::../variables.adoc[] + +In QQQ, record-level security is provided by using a lock & key metaphor. + +The use-case being handled here is: + +* A user has full permission on a table (query, insert, update, and delete). +* However, they should only be allowed to read a sub-set of the rows in the table. +** e.g., maybe it's a multi-tenant system, or the table has user-specific records. + +The lock & key metaphor is realized by the user being associated with one or more "Keys" +(as values in their session), and records in tables being associated with one or more "Locks" +(as values in fields). +A user is only allowed to access records where the user's key(s) match the record's security lock(s). + +For a practical example, picture a multi-tenant Order Management System,where all orders are assigned to a "client". +Users (customers) should only be able to see orders associated with the client which that user works for. + +In this scenario, the `order` table would have a "lock" on its `clientId` field. +Customer-users would have a `clientId` key in their session. +When the QQQ backend did a search for records (e.g., an SQL query) it would implicitly +(without any code being written by the application developer) filter the table to only +allow the user to see records with their `clientId`. + +To implement this scenario, the application would define the following pieces of meta-data: + +* At the QQQ-Instance level, a `SecurityKeyType`, +to define a domain of possible locks & keys within an application. +** An application can define multiple Security Key Types. +For example, maybe `clientId` and `userId` as key types. +* At the per-table level, a `RecordSecurityLock`, +which references a security key type, and how that key type should be applied to the table. +** For example, what field stores the `clientId` value in the `order` table. +* Finally, when a user's session is constructed via a QQQ Authentication provider, +security key values are set, based on data from the authentication backend. + +=== Additional Scenarios + +==== All Access Key +A "super-user" may be allowed to access all records in a table regardless of their record locks, +if the Security Key Type specifies an `allAccessKeyName`, +and if the user has a key in their session with that key name, and a value of `true`. +Going back to the lock & key metaphor, this can be thought of as a "skeleton key", +that can unlock any record lock (of the security key's type). + +==== Null Value Behaviors +In a record security lock, different behaviors can be defined for handling rows with a null key value. + +For example: + +* Sometimes orders may be loaded into the OMS system described above, where the application doesn't yet know what client the order belongs to. +In this case, the application may need to ensure that such records, with a `null` value in `clientId` are hidden from customer-users, +to avoid potentially leaking a different client's data. +** This can be accomplished with a record security lock on the `order` table, with a `nullValueBehavior` of `DENY`. +** Furthermore, if internal/admin users _should_ be given access to such records, then the security key type can be +configured with a `nullValueBehaviorKeyName` (e.g., `"clientIdNullValueBehavior"`), which can be set per-user to allow +access to records, overriding the table lock's specified `nullValueBehavior`. +*** This could also be done by giving internal/admin users an `allAccessKey`, but sometimes that is not what is required. + +* Maybe a warehouse locations table is assigned a `clientId` once inventory for a client is placed in the location, +at which point in time, only the client's users should be allowed to see the record. +But, if no client has been assigned to the location, and `clientId` is `null`, +then you may want to allow any user to see such records. +** This can be accomplished with a record security lock on the Warehouse Locations table, with a `nullValueBehavior` of `ALLOW`. + +=== QSecurityKeyType +A Security Key Type is defined in a QQQ Instance in a `*QSecurityKeyType*` object. + +*QSecurityKeyType Properties:* + +* `name` - *String, Required* - Unique name for this security key type within the QQQ Instance. +* `allAccessKeyName` - *String* - Optional name of the all-access security key associated with this key type. +* `nullValueBehaviorKeyName` - *String* - Optional name of the null-value-behavior overriding security key associated with this key type. +** Note, `name`, `allAccessKeyName`, and `nullValueBehaviorKeyName` are all checked against each other for uniqueness. +A `QInstanceValidationException` will be thrown if any name collisions occur. +* `possibleValueSourceName` - *String* - Optional reference to a possible value source from which value for the key can come. + + diff --git a/docs/metaData/Tables.adoc b/docs/metaData/Tables.adoc index 644b086d..2268ce50 100644 --- a/docs/metaData/Tables.adoc +++ b/docs/metaData/Tables.adoc @@ -1,15 +1,16 @@ -== QQQ Tables +[#Tables] +== Tables include::../variables.adoc[] -The core type of object in a QQQ Instance is the Table. +One of the most common types of object in a QQQ Instance is the Table. In the most common use-case, a QQQ Table may be the in-app representation of a Database table. That is, it is a collection of records (or rows) of data, each of which has a set of fields (or columns). -QQQ also allows other types of data sources ({link-backends}) to be used as tables, such as File systems, API's, Java enums or objects, etc. +QQQ also allows other types of data sources ({link-backends}) to be used as tables, such as File systems, API's, etc. All of these backend types present the same interfaces (both user-interfaces, and application programming interfaces), regardless of their backend type. === QTableMetaData -Tables are defined in a QQQ Instance in a `*QTableMetaData*` object. +Tables are defined in a QQQ Instance in `*QTableMetaData*` objects. All tables must reference a {link-backend}, a list of fields that define the shape of records in the table, and additional data to describe how to work with the table within its backend. *QTableMetaData Properties:* @@ -19,14 +20,37 @@ All tables must reference a {link-backend}, a list of fields that define the sha Inferred from `name` if not set. * `backendName` - *String, Required* - Name of a {link-backend} in which this table's data is managed. * `fields` - *Map of String → {link-field}, Required* - The columns of data that make up all records in this table. -* `primaryKeyField` - *String, Conditional* - Name of a {link-field} that serves as the primary key (e.g., unique identifier) for records in this table. -* `uniqueKeys` - *List of UniqueKey* - Definition of additional unique constraints (from an RDBMS point of view) from the table. +* `primaryKeyField` - *String, Conditional* - Name of a {link-field} that serves as the primary key (unique identifier) for records in this table. +** Whether a primary key field is required or not depends on the backend type that the table belongs to. +* `uniqueKeys` - *List of UniqueKey* - Definition of additional unique keys or constraints (from an RDBMS point of view) from the table. e.g., sets of columns which must have unique values for each record in the table. +The properties of the `UniqueKey` object are: +** `fieldNames` - *List of String, Required* - List of field names from this table. +** `label` - *String* - Optional label to be shown to users with error messages (e.g., for violation of this unique key). * `backendDetails` - *QTableBackendDetails or subclass* - Additional data to configure the table within its {link-backend}. -* `automationDetails` - *QTableAutomationDetails* - Configuration of automated jobs that run against records in the table, e.g., upon insert or update. +** For example, for an RDBMS-type backend, the name of the table within the database. +** vs. a FileSystem backend, this may be the sub-path where files for the table are stored. +** #todo - details on these# +* `automationDetails` - *<>* - Configuration of automated jobs that run against records in the table, e.g., upon insert or update. * `customizers` - *Map of String → QCodeReference* - References to custom code that are injected into standard table actions, that allow applications to customize certain parts of how the table works. +** Allowed values for keys in this map come from the `role` property of the `TableCustomizers` enum. +** Based on the key in this map, the `QCodeReference` used as the value must be of the appropriate java type, as specified in the `expectedType` property of the `TableCustomizers` enum value corresponding to the key. +** Example: + +[source,java] +---- +// in defining a QTableMetaData, a customizer can be added as: +.withCustomizer(TableCustomizers.PRE_INSERT_RECORD, new QCodeReference(MyPreInsCustomizer.class)) + +// where MyPreInsCustomizer would be defined as: +public class MyPreInsCustomizer extends AbstractPreInsertCustomizer +---- + + +* `isHidden` - *Boolean, default false* - Option to hide the table from all User Interfaces. * `parentAppName` - *String* - Name of a {link-app} that this table exists within. -* `icon` - *QIcon* - Icon associated with this table in certain user interfaces. +** This field generally does not need to be set on the table when it is defined, but rather, is set when the table gets placed within an app. +* `icon` - *QIcon* - Icon associated with this table in certain user interfaces. See {link-icons}. * `recordLabelFormat` - *String* - Java Format String, used with `recordLabelFields` to produce a label shown for records from the table. * `recordLabelFields` - *List of String, Conditional* - Used with `recordLabelFormat` to provide values for any format specifiers in the format string. These strings must be field names within the table. @@ -42,8 +66,219 @@ new QFieldMetaData("birthDate", QFieldType.DATE) .withRecordLabelFormat("%s (%s)") .withRecordLabelFields(List.of("name", "birthDate")) ---- -* `sections` - *List of QFieldSection* - Mechanism to organize fields within user interfaces, into logical sections. + +* `sections` - *List of <>* - Mechanism to organize fields within user interfaces, into logical sections. If any sections are present in the table meta data, then all fields in the table must be listed in exactly 1 section. If no sections are defined, then instance enrichment will define default sections. -* `associatedScripts` - *List of AssociatedScript* - Definition of user-defined scripts that can be associated with records within the table. +* `associatedScripts` - *List of <>* - Definition of user-defined scripts that can be associated with records within the table. * `enabledCapabilities` and `disabledCapabilities` - *Set of Capability enum values* - Overrides from the backend level, for capabilities that this table does or does not possess. +* `associations` - *List of <>* - tables whose records can be managed along with records from this table. See below for details. +* `recordSecurityLocks` - *List of <>* - locks that apply to records in the table - e.g., to control what users can or cannot access records in the table. +See RecordSecurityLock below for details. +* `permissionRules` - *QPermissionRules object* - define the permission/access rules for the table. +See {link-permissionRules} for details. +* `auditRules` - *<> object* - define the audit rules for the table. +See QAuditRules below for details. +* `cacheOf` - *<> object* - specify that this table serves as a "cache of" another table. +See CacheOf object below for details. +* `exposedJoins` - *List of <> objects* - optional list of joined tables that are to be exposed in User Interfaces. +See ExposedJoin object below for details. + +#todo: supplementalMetaData (API)# + + +==== QFieldSection +When users view records from a QQQ Table in a UI, fields are organized on the screen based on the `QFieldSection` objects in the table's meta-data. + +*QFieldSection Properties:* + +* `name` - *String, Required* - unique identifier for the section within its table. +* `label` - *String* - User-facing label for the section, presented in User Interfaces. +Inferred from `name` if not set. +* `tier` - *enum* - importance of the fields in section for the table. +Different tiers may be presented differently in UI's. +Only a single `T1` section is allowed per-table. Possible values are: `T1`, `T2`, and `T3`. +* `icon` - *QIcon* - Icon associated with this section in certain user interfaces. See {link-icons}. +* `isHidden` - *Boolean, default false* - Option to hide the table from all User Interfaces. +* `gridColumns` - *Integer* - Option to specify how many columns in a grid layout the section should use. +For the Material-Dashboard frontend, this is a grid of 12. +* `fieldNames` - *List of String, Conditional* - List of names of {link-fields} from this table to be included in this section. +* `widgetName` - *String, Conditional* - Name of a {link-widget} to be displayed in this section. +** Note that exactly one of `fieldNames` or `widgetName` must be used. + +==== QTableAutomationDetails +Records in QQQ can have application-defined custom actions automatically asynchronously executed against them after they are inserted or updated. +The configuration to enable this functionality is assigned to a table in a `QTableAutomationDetails` object. + +*QTableAutomationDetails Properties:* + +* `statusTracking` - *AutomationStatusTracking object, Required* - define how QQQ should keep track, per record, its status (e.g., pending-insert-automations, running-update-automations, etc). +Properties of `AutomationStatusTracking` object are: +** `type` - *enum, Required* - what type of tracking is used for the table. +Possible values are: +*** `FIELD_IN_TABLE` - specifies that the table has a field which stores an `AutomationStatus` id. +*** _Additional types may be defined in the future, such as ONE_TO_ONE_TABLE or SHARED_TABLE._ +** `fieldName` - *String, Conditional* - for `type=FIELD_IN_TABLE`, this property specifies the name of the {link-field} in the table that stores the `AutomationStatus` id. +* `providerName` - *String, Required* - name of an Automation Provider within the QQQ Instance, which is responsible for running the automations on this table. +* `overrideBatchSize` - *Integer* - optional control over how many records from the table are processed in a single batch/page. +For tables with "slow" actions (e.g., one that may need to make an API call per-record), using a smaller batch size (say, 50) may be required to avoid timeout errors. +* `actions` - *List of TableAutomationAction* - list of the actions to perform on new and updated records in the table. +Properties are: +** `name` - *String, Required* - unique identifier for the action within its table. +** `triggerEvent` - *enum, Required* - indicate which event type (`POST_INSERT`, `POST_UPDATE`, or `PRE_DELETE` (which is not yet implemented)) the action applies to. +** `priority` - *Integer, default 500* - mechanism to control the order in which actions on a table are executed, if there are more than one. +Actions with a smaller value for `priority` are executed first. Ties are broken in an undefined manner. +** `filter` - *QQueryFilter* - optional filter that gets applied to records when they match the `triggerEvent`, to control which records have the action ran against them. +** `includeRecordAssociations` - *Boolean, default false* - for tables that have associations, control whether or not a record's associated records are loaded when records are fetched and passed into the action's custom code. +** `values` - *Map of String → Serializable* - optional application-defined map of name=value pairs that can be passed into the action's custom code. +** `processName` - *String, Conditional* - name of a {link-processes} in the QQQ Instance which is executed as the custom-code of the action. +** `codeReference` - *QCodeReference, Conditional* - reference to a class that extends `RecordAutomationHandler`, to be executed as the custom-code of the action. +*** Note, exactly one of `processName` or `codeReference` must be provided. + + + +==== Association +An `Association` is a way to define a relationship between tables, that facilitates, for example, a parent record having a list of its child records included in it when it is returned from a Query. +Similarly, associated records can automatically be inserted/updated/deleted if they are included in a parent record when it is stored. + +*Association Properties:* + +* `name` - *String, Required* - unique name for the association within this table. +Used as the key in the `associatedRecords` map within `QRecord` objects for this table. +* `associatedTableName` - *String, Required* - name of a {link-table}, which is the associated table. +* `joinName` - *String, Required* - name of a {link-join} in the instance, which defines how the tables are joined. + + + +==== RecordSecurityLock +A `RecordSecurityLock` is the mechanism through which users can be allowed or denied access to read and/or write records, based on values in the record, and values in the user's session. +Record security locks must correspond to a {link-securityKeyType}. + +For example: + +* An instance may have a security key type called `clientId`. +* Users may have 1 or more `clientId` values in their Session, or, they may have an "All Clients" key in their session (e.g., for internal/admin users). +* For some tables, it may be required to limit visibility to records based on a user's `clientId` key. +To do this. a *RecordSecurityLock* would be applied to the table, specifying the `clientId` field corresponds to the `clientId` security key. +* With these settings in place, QQQ will prevent users from viewing records from this table that do not have a matching key, and will similarly prevent users from writing records with an invalid key value. +** For example, in an RDBMS backend, all `SELECT` statements generated against such a table will have an implicit filter, such as `AND client_id = ?` based on the user's security key values. + +*RecordSecurityLock Properties:* + +* `securityKeyType` - *String, Required* - name of a {link-securityKeyType} in the Instance. +* `fieldName` - *String, Required* - name of a {link-field} in this table (or a joined table, if `joinNameChain` is set), where the value for the lock is stored. +* `joinNameChain` - *List of String* - if the lock value is not stored in this table, but rather comes from a joined table, then this property defines the path of joins from this table to the table with the lock field. +* `nullValueBehavior` - *enum, default: DENY* - control how records with a `null` value in the lock field should behave. +Possible values are: +** `DENY` - deny all users access to a record with a `null` value in the lock field (unless the user has an all-access key - see {link-securityKeyType}) +** `ALLOW` - allow all users access to a record with a `null` value in the lock field. +** `ALLOW_WRITE_ONLY` - allow all users to write records with `null` in the lock field, but deny reads on records with `null` in the lock field (also excepted by all-access keys). +* `lockScope` - *enum, default: READ_AND_WRITE* - control what types of operations the lock applies to. +Possible values are: +** `READ_AND_WRITE` - control both reading and writing records based on the user having an appropriate security key. +** `WRITE` - allow all users to read the record, but limit writes to users with an appropriate security key. + + + +==== QAuditRules +The audit rules on a table define the level of detail that is automatically stored in the audit table (if any) for DML actions (Insert, Update, Delete). + +*QAuditRules Properties:* + +* `auditLevel` - *enum, Required* - level of details that are audited. +Possible values are: +** `NONE` - no automatic audits are stored for the table. +** `RECORD` - only record-level audits are stored for the table (e.g., a message such as "record was edited", but without field-level details) +** `FIELD` - full field-level audits are stored (e.g., including all old & new values as audit details). + + + +==== CacheOf +One QQQ Table can be defined as a "cache of" another QQQ Table by assigning a `CacheOf` object to the table which will function as the cache. +_Note, at this time, only limited use-cases are supported._ + +*CacheOf Properties:* + +* `sourceTable` - *String, Required* - name of the other QQQ Table that is the source of data in this cache. +* `expirationSeconds` - *Integer* - optional number of seconds that a cached record is allowed to exist before it is considered expired, and must be re-fetched from the source table. +* `cachedDateFieldName` - *String, Conditional* - used with `expirationSeconds` to define the field in this table that is used for storing the timestamp for when the record was cached. +* `useCases` - *List of CacheUseCase* - what caching use-cases are to be implemented. + +Properties of *CacheUseCase* are: + +* `type` - *Enum, Required* - the type of use-case. Possible values are: +** `PRIMARY_KEY_TO_PRIMARY_KEY` - the primary key in the cache table equals the primary key in the source table. +** `UNIQUE_KEY_TO_PRIMARY_KEY` - a unique key in the cache table equals the primary key in the source table. +** `UNIQUE_KEY_TO_UNIQUE_KEY` - a unique key in the cache table equals a unique key in the source table. +* `cacheSourceMisses` - *Boolean, default false* - whether or not, if a "miss" happens in the source, if that fact gets cached. +* `cacheUniqueKey` - *UniqueKey, conditional* - define the fields in the cache table that define the unique key being used as the cache key. +* `sourceUniqueKey` - *UniqueKey, conditional* - define the fields in the source table that define the unique key being used as the cache key. +* `doCopySourcePrimaryKeyToCache` - *Boolean, default false* - specify whether or not the value of the primary key in the source table should be copied into records built in the cache table. +* `excludeRecordsMatching` - *List of QQueryFilter* - optional filter to be applied to records before they are cached. +If a record matches the filter, then it will not be cached. + + +==== ExposedJoin +Query screens in QQQ applications can potentially allow users to both display fields from joined tables, and filter by fields from joined tables, for any {link-join} explicitly defined as an *Exposed Join*. + +_The reasoning why not all joins are implicitly exposed is that in many applications, the full join-graph can sometimes be overwhelming, surprisingly broad, and not necessarily practically useful. +This could be subject to change in the future, e.g., given a UI that allowed users to more explicitly add additional join tables..._ + +*ExposedJoin Properties:* + +* `label` - *String, Required* - how the joined table should be presented in the UI. +* `joinTable` - *String, Required* - name of the QQQ Table that is joined to this table, and is being exposed as a join in the UI. +* `joinPath` - *List of String, Required* - names of 1 or more QQQ Joins that describe how to get from this table to the join table. + + + +==== AssociatedScript +A QQQ Table can have end-user defined Script records associated with individual records in the table by use of the `associatedScripts` property of the table's meta-data. + +The "types" of these scripts (e.g., how they are used in an application) are wholly application-designed & managed. +QQQ provides the mechanism for UI's to present and manage such scripts (e.g., the *Developer Mode* screen in the Material Dashboard), as well as an interface to load & execute such scripts `RunAssociatedScriptAction`). + +*AssociatedScript Properties:* + +* `fieldName` - *String, Required* - name of a {link-field} in the table which stores the id of the associated script record. +* `scriptTypeId` - *Serializable (typically Integer), Required* - primary key value from the `"scriptType"` table in the instance, to designate the type of the Script. +* `scriptTester` - *QCodeReference* - reference to a class which implements `TestScriptActionInterface`, that can be used by UI's for running an associated script to test it. + + + +=== Supplemental Meta Data +==== QQQ Frontend Material Dashboard +When running a QQQ application with the QQQ Frontend Material Dashboard module (QFMD), +there are various pieces of supplemental meta-data which can be assigned to a Table, +to modify some behaviors for the table in this UI. + +===== Default Quick Filter Field Names +QFMD's table query has a "Basic" mode, which will always display a subset of the table's fields as quick-access filters. +By default, the "Tier 1" fields on a table (e.g., fields in a Section that is marked as T1) will be used for this purpose. + +However, you can customize which fields are shown as the default quick-filter fields, by providing a list of field names in a +`MaterialDashboardTableMetaData` object, placed in the table's `supplementalMetaData`. + +[source,java] +---- +table.withSupplementalMetaData(new MaterialDashboardTableMetaData() + .withDefaultQuickFilterFieldNames(List.of("id", "warehouseId", "statusId", "orderDate"))); +---- + +===== Go To Field Names +QFMD has a feature where a table's query screen can include a "Go To" button, +which a user can hit to open a modal popup, into which the user can enter a record's identifier, +to be brought directly to the record matching that identifier. + +To use this feature, the table must have a List of `GotoFieldNames` set in its +`MaterialDashboardTableMetaData` object in the table's `supplementalMetaData`. + +Each entry in this list is actually a list of fields, e.g., to account for a multi-value unique-key. + +[source,java] +---- +table.withSupplementalMetaData(new MaterialDashboardTableMetaData() + .withGotoFieldNames(List.of( + List.of("id"), + List.of("partnerName", "partnerOrderId")))); +---- diff --git a/docs/metaData/Tables.html b/docs/metaData/Tables.html deleted file mode 100644 index 2eeb946d..00000000 --- a/docs/metaData/Tables.html +++ /dev/null @@ -1,553 +0,0 @@ - - - - - - - -QQQ Tables - - - - - -
-
-

QQQ Tables

-
-
-

The core type of object in a QQQ Instance is the Table. -In the most common use-case, a QQQ Table may be the in-app representation of a Database table. -That is, it is a collection of records (or rows) of data, each of which has a set of fields (or columns).

-
-
-

QQQ also allows other types of data sources (QQQ Backends) to be used as tables, such as File systems, API’s, Java enums or objects, etc. -All of these backend types present the same interfaces (both user-interfaces, and application programming interfaces), regardless of their backend type.

-
-
-

QTableMetaData

-
-

Tables are defined in a QQQ Instance in a QTableMetaData object. -All tables must reference a QQQ Backend, a list of fields that define the shape of records in the table, and additional data to describe how to work with the table within its backend.

-
-
-

QTableMetaData Properties:

-
-
-
    -
  • -

    name - String, Required - Unique name for the table within the QQQ Instance.

    -
  • -
  • -

    label - String - User-facing label for the table, presented in User Interfaces. -Inferred from name if not set.

    -
  • -
  • -

    backendName - String, Required - Name of a QQQ Backend in which this table’s data is managed.

    -
  • -
  • -

    fields - Map of String → QQQ Field, Required - The columns of data that make up all records in this table.

    -
  • -
  • -

    primaryKeyField - String, Conditional - Name of a QQQ Field that serves as the primary key (e.g., unique identifier) for records in this table.

    -
  • -
  • -

    uniqueKeys - List of UniqueKey - Definition of additional unique constraints (from an RDBMS point of view) from the table. -e.g., sets of columns which must have unique values for each record in the table.

    -
  • -
  • -

    backendDetails - QTableBackendDetails or subclass - Additional data to configure the table within its QQQ Backend.

    -
  • -
  • -

    automationDetails - QTableAutomationDetails - Configuration of automated jobs that run against records in the table, e.g., upon insert or update.

    -
  • -
  • -

    customizers - Map of String → QCodeReference - References to custom code that are injected into standard table actions, that allow applications to customize certain parts of how the table works.

    -
  • -
  • -

    parentAppName - String - Name of a QQQ App that this table exists within.

    -
  • -
  • -

    icon - QIcon - Icon associated with this table in certain user interfaces.

    -
  • -
  • -

    recordLabelFormat - String - Java Format String, used with recordLabelFields to produce a label shown for records from the table.

    -
  • -
  • -

    recordLabelFields - List of String, Conditional - Used with recordLabelFormat to provide values for any format specifiers in the format string. -These strings must be field names within the table.

    -
    -
      -
    • -

      Example of using recordLabelFormat and recordLabelFields:

      -
    • -
    -
    -
  • -
-
-
-
-
// given these fields in the table:
-new QFieldMetaData("name", QFieldType.STRING)
-new QFieldMetaData("birthDate", QFieldType.DATE)
-
-// We can produce a record label such as "Darin Kelkhoff (1980-05-31)" via:
-.withRecordLabelFormat("%s (%s)")
-.withRecordLabelFields(List.of("name", "birthDate"))
-
-
-
-
    -
  • -

    sections - List of QFieldSection - Mechanism to organize fields within user interfaces, into logical sections. -If any sections are present in the table meta data, then all fields in the table must be listed in exactly 1 section. -If no sections are defined, then instance enrichment will define default sections.

    -
  • -
  • -

    associatedScripts - List of AssociatedScript - Definition of user-defined scripts that can be associated with records within the table.

    -
  • -
  • -

    enabledCapabilities and disabledCapabilities - Set of Capability enum values - Overrides from the backend level, for capabilities that this table does or does not possess.

    -
  • -
-
-
-
-
-
- - - \ No newline at end of file diff --git a/docs/metaData/Widgets.adoc b/docs/metaData/Widgets.adoc new file mode 100644 index 00000000..ae793068 --- /dev/null +++ b/docs/metaData/Widgets.adoc @@ -0,0 +1,51 @@ +[#Widgets] +== Widgets +include::../variables.adoc[] + +Widgets are the most customizable UI components in QQQ. +They can be used either on App Home Screens (e.g., as Dashboard screens), +or they can be included into Record View screens. + +QQQ defines several types of widgets, such as charts (pie, bar, line), +numeric displays, application-populated tables, or even fully custom HTML. + +=== QWidgetMetaData +A Widget is defined in a QQQ Instance in a `*QWidgetMetaData*` object. + +*QWidgetMetaData Properties:* + +* `name` - *String, Required* - Unique name for the widget within the QQQ Instance. +* `type` - *String, Required* - Specifies the UI & data type for the widget. +* `label` - *String* - User-facing header or title for a widget. +* `tooltip` - *String* - Text contents to be placed in a tooltip associated with the widget's label in the UI. +** Values should come from the `WidgetType` enum's `getType()` method (e.g., `WidgetType.BAR_CHART.getType()`) +* `gridColumns` - *Integer* - for a desktop-sized screen, in a 12-based grid, +how many columns the widget should consume. +* `codeReference` - *QCodeReference, Required* - Reference to the custom code, +a subclass of `AbstractWidgetRenderer`, which is responsible for loading data to render the widget. +* `footerHTML` - *String* - HTML String, which, if present, will be displayed in the +footer of the widget (not supported by all widget types). +* `isCard` - *boolean, default false* #TODO# +* `showReloadButton` - *boolean, default true* #TODO# +* `showExportButton` - *boolean, default false* #TODO# +* `dropdowns` - #TODO# +* `storeDropdownSelections` - *boolean* #TODO# +* `icons` - *Map* #TODO# +* `defaultValues` - *Map* #TODO# + +There are also some subclasses of `QWidgetMetaData`, for some specific widget types: + +*ParentWidgetMetaData Properties:* + +* `title` - *String* #TODO - how does this differ from label?# +* `childWidgetNameList` - *List, Required* +* `childProcessNameList` - *List* #TODO appears unused - check, and delete# +* `laytoutType` - *enum of GRID or TABS, default GRID* + +*QNoCodeWidgetMetaData Properties:* + +* `values` - *List* #TODO# +* `outputs` - *List* #TODO# + +#TODO - Examples# + diff --git a/docs/misc/RenderingWidgets.adoc b/docs/misc/RenderingWidgets.adoc new file mode 100644 index 00000000..0a5386b2 --- /dev/null +++ b/docs/misc/RenderingWidgets.adoc @@ -0,0 +1,224 @@ +== Rendering Widgets +include::../variables.adoc[] + +=== WidgetRenderer classes +In general, to fully implement a Widget, you must define its `QWidgetMetaData`, +and supply a subclass of `AbstractWidgetRenderer`, to provide the data to the widget. +(Note the "No Code" category of widgets, which are an exception to this generalization). + +The only method required in a subclass of `AbstractWidgetRenderer` is: + + public RenderWidgetOutput render(RenderWidgetInput input) throws QException + +The fields available in `RenderWidgetInput` are: + +- `Map queryParams` - These are parameters supplied by the frontend, for example, +if a user selected values from dropdowns to control a dimension of your widget, those name/value +pairs would be in this map. Similarly, if your widget is being included on a record view screen, then +the record's primary key will be in this map. +- `QWidgetMetaDataInterface widgetMetaData` - This is the meta-data for the widget being +rendered. This can be useful in case you are using the same renderer class for multiple widgets. + +The only field in `RenderWidgetOutput` is: + +- `QWidgetData widgetData` - This is a base class, with several attributes, and more importantly, +several subclasses, specific to the type of widget that is being rendered. + +==== Widget-Type Specific Rendering Details +Different widget types expect & require different types of values to be set in the `RenderWidgetOutput` by their renderers. + +===== Pie Chart +The `WidgetType.PIE_CHART` requires an object of type `ChartData`. +The fields on this type are: + +* `chartData` an instance of `ChartData.Data`, which has the following fields: +** `labels` - *List, required* - the labels for the slices of the pie. +** `datasets` - *List required* - the data for each slice of the pie. +For a Pie chart, only a single entry in this list is used +(other chart types using `ChartData` may support more than 1 entry in this list). +Fields in this object are: +*** `label` - *String, required* - a label to describe the dataset as a whole. +e.g., "Orders" for a pie showing orders of different statuses. +*** `data` - *List, required* - the data points for each slice of the pie. +*** `color` - *String* - HTML color for the slice +*** `urls` - *List* - Optional URLs for slices of the pie to link to when clicked. +*** `backgroundColors` - *List* - Optional HTML color codes for each slice of the pie. + +[source,java] +.Pie chart widget example +---- +// meta data +new QWidgetMetaData() + .withName("pieChartExample") + .withType(WidgetType.PIE_CHART.getType()) + .withGridColumns(4) + .withIsCard(true) + .withLabel("Pie Chart Example") + .withCodeReference(new QCodeReference(PieChartExampleRenderer.class)); + +// renderer +private List labels = new ArrayList<>(); +private List colors = new ArrayList<>(); +private List data = new ArrayList<>(); + +/******************************************************************************* +** helper method - to add values for a slice to the lists +*******************************************************************************/ +private void addSlice(String label, String color, Number datum) +{ + labels.add(label); + colors.add(color); + data.add(datum); +} + +/******************************************************************************* +** main method of the widget renderer +*******************************************************************************/ +@Override +public RenderWidgetOutput render(RenderWidgetInput input) throws QException +{ + addSlice("Apple", "#FF0000", 100); + addSlice("Orange", "#FF8000", 150); + addSlice("Banana", "#FFFF00", 75); + addSlice("Lime", "#00FF00", 100); + addSlice("Blueberry", "#0000FF", 200); + + ChartData chartData = new ChartData() + .withChartData(new ChartData.Data() + .withLabels(labels) + .withDatasets(List.of( + new ChartData.Data.Dataset() + .withLabel("Flavor") + .withData(data) + .withBackgroundColors(colors) + .withUrls(urls)))); + + return (new RenderWidgetOutput(chartData)); +} + +---- + +===== Bar Chart +#todo# + +===== Stacked Bar Chart +#todo# + +===== Horizontal Bar Chart +#todo# + +===== Child Record List +#todo# + +===== Line Chart +#todo# + +===== Small Line Chart +#todo# + +===== Statistics +#todo# + +===== Parent Widget +#todo# + +===== Composite +A `WidgetType.COMPOSITE` is built by using one or more smaller elements, known as `Blocks`. +Note that `Blocks` can also be used in the data of some other widget types +(specifically, within a cell of a Table-type widget, or (in the future?) as a header above a pie or bar chart). + +A composite widget renderer must return data of type `CompositeWidgetData`, +which has the following fields: + +* `blocks` - *List, required* - The blocks (1 or more) being composited together to make the widget. +See below for details on the specific Block types. +* `styleOverrides` - *Map* - Optional map of CSS attributes +(named following javascriptStyleCamelCase) to apply to the `
` element that wraps the rendered blocks. +* `layout` - *Layout enum* - Optional specifier for how the blocks should be laid out. +e.g., predefined sets of CSS attributes to achieve specific layouts. +** Note that some blocks are designed to work within composites with specific layouts. +Look for matching names, such as `Layout.BADGES_WRAPPER` to go with `NumberIconBadgeBlock`. + +[source,java] +.Composite widget example - consisting of 3 Progress Bar Blocks, and one Divider Block +---- +// meta data +new QWidgetMetaData() + .withName("compositeExample") + .withType(WidgetType.COMPOSITE.getType()) + .withGridColumns(4) + .withIsCard(true) + .withLabel("Composite Example") + .withCodeReference(new QCodeReference(CompositeExampleRenderer.class)); + +// renderer +public RenderWidgetOutput render(RenderWidgetInput input) throws QException +{ + CompositeWidgetData data = new CompositeWidgetData(); + + data.addBlock(new ProgressBarBlockData() + .withValues(new ProgressBarValues() + .withHeading("Blocks") + .withPercent(new BigDecimal("78.5")))); + + data.addBlock(new ProgressBarBlockData() + .withValues(new ProgressBarValues() + .withHeading("Progress") + .withPercent(new BigDecimal(0)))); + + data.addBlock(new DividerBlockData()); + + data.addBlock(new ProgressBarBlockData() + .withStyles(new ProgressBarStyles().withBarColor("#C0C000")) + .withValues(new ProgressBarValues() + .withHeading("Custom Color") + .withPercent(new BigDecimal("75.3")))); + + return (new RenderWidgetOutput(data)); +} +---- + + +===== Table +#todo# + +===== HTML +#todo# + +===== Divider +#todo# + +===== Process +#todo# + +===== Stepper +#todo# + +===== Data Bag Viewer +#todo# + +===== Script Viewer +#todo# + +=== Block-type Specific Rendering Details +For Composite-type widgets (or other widgets which can include blocks), +there are specific data classes required to be returned by the widget renderer. + +Each block type defines a subclass of `AbstractBlockWidgetData`, +which is a generic class with 3 type parameters: + +* `V` - an implementation of `BlockValuesInterface` - to define the type of values that the block uses. +* `S` - an implementation of `BlockSlotsInterface` (expected to be an `enum`) - to define the "slots" in the block, +that can have Tooltips and/or Links applied to them. +* `SX` - an implementation of `BlockStylesInterface` - to define the types of style customizations that the block supports. + +These type parameters are designed to ensure type-safety for the application developer, +to ensure that only + +=== Additional Tips + +* To make a Dashboard page (e.g., an App consisting of Widgets) with a parent widget use the parent widget's label as the page's label: +** On the `QAppMetaData` that contains the Parent widget, call +`.withSupplementalMetaData(new MaterialDashboardAppMetaData().withShowAppLabelOnHomeScreen(false))`. +** In the Parent widget's renderer, on the `ParentWidgetData`, call `setLabel("My Label")` and +`setIsLabelPageTitle(true)`. diff --git a/docs/utilities/RecordLookupHelper.adoc b/docs/utilities/RecordLookupHelper.adoc new file mode 100644 index 00000000..5d256c4d --- /dev/null +++ b/docs/utilities/RecordLookupHelper.adoc @@ -0,0 +1,272 @@ +== RecordLookupHelper +include::../variables.adoc[] + +`RecordLookupHelper` is a utility class that exists to help you... lookup records :) + +OK, I'll try to give a little more context: + +=== Motivation 1: Performance +One of the most significant performance optimizations that the team behind QQQ has found time and time again, +is to minimize the number of times you have to perform an I/O operation. +To just say it more plainly: +Make fewer calls to your database (or other backend). + +This is part of why the DML actions in QQQ (InsertAction, UpdateAction, DeleteAction) are all written to work on multiple records: +If you've got to insert 1,000 records, the performance difference between doing that as 1,000 SQL INSERT statements vs. just 1 statement cannot be overstated. + +Similarly then, for looking up records: +If we can do 1 round-trip to the database backend - that is - 1 query to fetch _n_ records, +then in almost all cases it will be significantly faster than doing _n_ queries, one-by-one, for those _n_ records. + +The primary reason why `RecordLookupHelper` exists is to help you cut down on the number of times you have to make a round-trip to a backend data store to fetch records within a process. + +[sidebar] +This basically is version of caching, isn't it? +Take a set of data from "far away" (e.g., database), and bring it "closer" (local or instance variables), for faster access. +So we may describe this as a "cache" through the rest of this document. + +=== Motivation 2: Convenience + +So, given that one wants to try to minimize the number of queries being executed to look up data in a QQQ processes, +one can certainly do this "by-hand" in each process that they write. + +Doing this kind of record caching in a QQQ Process `BackendStep` may be done as: + +* Adding a `Map` as a field in your class. +* Setting up and running a `QueryAction`, with a filter based on the collection of the keys you need to look up, then iterating over (or streaming) the results into the map field. +* Getting values out of the map when you need to use them (dealing with missing values as needed). + +That's not so bad, but, it does get a little verbose, especially if you're going to have several such caches in your class. + +As such, the second reason that `RecordLookupHelper` exists, is to be a reusable and convenient way to do this kind of optimization, +by providing methods to perform the bulk query & map building operation described above, +while also providing some convenient methods for accessing such data after it's been fetched. +In addition, a single instance of `RecordLookupHelper` can provide this service for multiple tables at once +(e.g., so you don't need to add a field to your class for each type of data that you're trying to cache). + +=== Use Cases +==== Preload records, then access them +Scenario: + +* We're writing a process `BackendStep` that uses `shipment` records as input. +* We need to know the `order` record associated with each `shipment` (via an `orderId` foreign key), for some business logic that isn't germaine to the explanation of `RecordLookupHelper`. +* We also to access some field on the `shippingPartner` record assigned to each `shipment`. +** Note that here, the `shipment` table has a `partnerCode` field, which relates to the `code` unique-key in the `shippingPartner` table. +** It's also worth mentioning, we only have a handful of `shippingPartner` records in our database, and we never expect to have very many more than that. + +[source,java] +.Example of a process step using a RecordLookupHelper to preload records +---- +public class MyShipmentProcessStep implements BackendStep +{ + // Add a new RecordLookupHelper field, which will "cache" both orders and shippingPartners + private RecordLookupHelper recordLookupHelper = new RecordLookupHelper(); + + @Override + public void run(RunBackendStepInput input, RunBackendStepOutput output) throws QException; + { + // lookup the full shippingPartner table (because it's cheap & easy to do so) + // use the partner's "code" as the key field (e.g,. they key in the helper's internal map). + recordLookupHelper.preloadRecords("shippingPartner", "code"); + + // get all of the orderIds from the input shipments + List orderIds = input.getRecords().stream() + .map(r -> r.getValue("id")).toList(); + + // fetch the orders related to by these shipments + recordLookupHelper.preloadRecords("order", "id", orderIds); + + for(QRecord shipment : input.getRecords()) + { + // get someConfigField from the shippingPartner assigned to the shipment + Boolean someConfig = recordLookupHelper.getRecordValue("shippingPartner", "someConfigField", "code", shipment.getValue("partnerCode")); + + // get the order record assigned to the shipment + QRecord order = recordLookupHelper.getRecordByKey("order", "id", shipment.getValue("orderId")); + } + } +} +---- + +==== Lazy fetching records +Scenario: + +* We have a `BackendStep` that is taking in `purchaseOrderHeader` records, from an API partner. +* For each record, we need to make an API call to the partner to fetch the `purchaseOrderLine` records under that header. +** In this contrived example, the partner's API forces us to do these lookups order-by-order... +* Each `purchaseOrderLine` that we fetch will have a `sku` on it - a reference to our `item` table. +** We need to look up each `item` to apply some business logic. +** We assume there are very many item records in the backend database, so we don't want to pre-load the full table. +Also, we don't know what `sku` values we will need until we fetch the `purchaseOrderLine`. + +This is a situation where we can use `RecordLookupHelper` to lazily fetch the `item` records as we discover them, +and it will take care of not re-fetching ones that it has already loaded. + +[source,java] +.Example of a process step using a RecordLookupHelper to lazy fetch records +---- +public class MyPurchaseOrderProcessStep implements BackendStep +{ + // Add a new RecordLookupHelper field, which will "cache" lazy-loaded item records + private RecordLookupHelper recordLookupHelper = new RecordLookupHelper(); + + @Override + public void run(RunBackendStepInput input, RunBackendStepOutput output) throws QException; + { + for(QRecord poHeader : input.getRecords()) + { + // fetch the lines under the header + Serializable poNo = poHeader.getValue("poNo"); + List poLines = new QueryAction().execute(new QueryInput("purchaseOrderLine") + .withFilter(new QQueryFilter(new QFilterCriteria("poNo", EQUALS, poNo)))); + + for(QRecord poLine : poLines) + { + // use recordLookupHelper to lazy-load item records by SKU. + QRecord item = recordLookupHelper.getRecordByKey("item", "sku", poLine.getValue("sku")); + + // business logic related to item performed here. + } + } + } +} +---- + +In this example, we will be doing exactly 1 query on the `item` table for each unique `sku` that is found across all of the `poLine` records we process. +That is to say, if the same `sku` appears on only 1 `poLine`, or if it appears on 100 `poLines`, we will still only query once for that `sku`. + +A slight tweak could be made to the example above, to make 1 `item` table lookup for each `poHeader` record: + +[source,java] +.Tweaked example doing 1 item lookup per poLine +---- +// continuing from above, after the List poLines has been built + +// get all of the skus from the lines +List skus = poLines.stream().map(r -> r.getValue("sku")).toList(); + +// preload the items for the skus +recordLookupHelper.preloadRecords("item", "sku", new QQueryFilter(new QFilterCriteria("sku", IN, skus))); + +for(QRecord poLine : poLines) +{ + // get the items from the helper + QRecord item = recordLookupHelper.getRecordByKey("item", "sku", poLine.getValue("sku")); + +---- + +In this example, we've made a trade-off: We will query the `item` table exactly 1 time for each `poHeader` that we process. +However, if the same `sku` is on every PO that we process, we will end up fetching it multiple times. + +This could end up being better or worse than the previous example, depending on the distribution of the data we are dealing with. + +A further tweak, a hybrid approach, could potentially reap the benefits of both of these examples (at the tradeoff of, more code, more complexity): + +[source,java] +.Tweaked example doing 1 item lookup per poLine, but only for not-previously-encountered skus +---- +// Critically - we must tell our recordLookupHelper to NOT do any one-off lookups in this table +recordLookupHelper.setMayNotDoOneOffLookups("item", "sku"); + +// continuing from above, after the List poLines has been built + +// get all of the skus from the lines +List skus = poLines.stream().map(r -> r.getValue("sku")).toList(); + +// determine which skus have not yet been loaded - e.g., they are not in the recordLookupHelper. +// this is why we needed to tell it above not to do one-off lookups; else it would lazy-load each sku here. +List skusToLoad = new ArrayList<>(); +for(Serializable sku : skus) +{ + if(recordLookupHelper.getRecordByKey("item", "sku", sku) == null) + { + skusToLoad.add(sku); + } +} + +// preload the item records for any skus that are still needed +if(!skusToLoad.isEmpty()) +{ + recordLookupHelper.preloadRecords("item", "sku", + new QQueryFilter(new QFilterCriteria("sku", IN, skusToLoad))); +} + +// continue as above + +---- + +In this example, we will start by querying the `item` table once for each `poHeader`, but, +if we eventually encounter a PO where all of its `skus` have already been loaded, then we may be able to avoid any `item` queries for such a PO. + +=== Implementation Details + +* Internally, an instance of `RecordLookupHelper` maintains a number of `Maps`, +with QQQ table names and field names as keys. +* The accessing/lazy-fetching methods (e.g., any method whose name starts with `getRecord`) +all begin by looking in these internal maps for the `tableName` and `keyFieldName` that they take as parameters. +** If they find an entry in the maps, then it is used for producing a return value. +** If they do not find an entry, then they will perform the a `QueryAction`, +to try to fetch the requested record from the table's backend. +*** Unless the `setMayNotDoOneOffLookups` method has been called for the `(tableName, keyFieldName)` pair. + +=== Full API + +==== Methods for accessing and lazy-fetching +* `getRecordByKey(String tableName, String keyFieldName, Serializable key)` + +Get a `QRecord` from `tableName`, where `keyFieldName` = `key`. + +* `getRecordValue(String tableName, String requestedField, String keyFieldName, Serializable key)` + +Get the field `requestedField` from the record in `tableName`, where `keyFieldName` = `key`, as a `Serializable`. +If the record is not found, `null` is returned. + +* `getRecordValue(String tableName, String requestedField, String keyFieldName, Serializable key, Class type)` + +Get the field `requestedField` from the record in `tableName`, where `keyFieldName` = `key`, as an instance of `type`. +If the record is not found, `null` is returned. + +* `getRecordId(String tableName, String keyFieldName, Serializable key)` + +Get the primary key of the record in `tableName`, where `keyFieldName` = `key`, as a `Serializable`. +If the record is not found, `null` is returned. + +* `getRecordId(String tableName, String keyFieldName, Serializable key, Class type)` + +Get the primary key of the record in `tableName`, where `keyFieldName` = `key`, as an instance of `type`. +If the record is not found, `null` is returned. + +* `getRecordByUniqueKey(String tableName, Map uniqueKey)` + +Get a `QRecord` from `tableName`, where the record matches the field/value pairs in `uniqueKey`. + +_Note: this method does not use the same internal map as the rest of the class. +As such, it does not take advantage of any data fetched via the preload methods. +It is only used for caching lazy-fetches._ + +==== Methods for preloading +* `preloadRecords(String tableName, String keyFieldName)` + +Query for all records from `tableName`, storing them in an internal map keyed by the field `keyFieldName`. + +* `preloadRecords(String tableName, String keyFieldName, QQueryFilter filter)` + +Query for records matching `filter` from `tableName`, +storing them in an internal map keyed by the field `keyFieldName`. + +* `preloadRecords(String tableName, String keyFieldName, List inList)` + +Query for records with the field `keyFieldName` having a value in `inList` from `tableName`, +storing them in an internal map keyed by the field `keyFieldName`. + +==== Config Methods +* `setMayNotDoOneOffLookups(String tableName, String fieldName)` + +For cases where you know that you have preloaded records for `tableName`, keyed by `fieldName`, +and you know that some of the keys may not have been found, +so you want to avoid doing a query when a missed key is found in one of the `getRecord...` methods, +then if you call this method, an internal flag is set, which will prevent any such one-off lookups. + +In other words, if this method has been called for a `(tableName, fieldName)` pair, +then the `getRecord...` methods will only look in the internal map for records, +and no queries will be performed to look for records. diff --git a/docs/variables.adoc b/docs/variables.adoc index 27b56226..fcab3c03 100644 --- a/docs/variables.adoc +++ b/docs/variables.adoc @@ -1,13 +1,25 @@ -ifdef::env-name[:relfilesuffix: .adoc] -:link-backend: link:Backends{relfilesuffix}[QQQ Backend] -:link-backends: link:Backends{relfilesuffix}[QQQ Backends] -:link-table: link:Tables{relfilesuffix}[QQQ Table] -:link-tables: link:Tables{relfilesuffix}[QQQ Tables] -:link-join: link:Joins{relfilesuffix}[QQQ Join] -:link-joins: link:Joins{relfilesuffix}[QQQ Joins] -:link-field: link:Fields{relfilesuffix}[QQQ Field] -:link-fields: link:Fields{relfilesuffix}[QQQ Fields] -:link-process: link:Processes{relfilesuffix}[QQQ Process] -:link-processes: link:Processes{relfilesuffix}[QQQ Processes] -:link-app: link:Apps{relfilesuffix}[QQQ App] -:link-apps: link:Apps{relfilesuffix}[QQQ Apps] +:link-app: <> +:link-apps: <> +:link-backend: <> +:link-backends: <> +:link-field: <> +:link-fields: <> +:link-icon: <> +:link-icons: <> +:link-instance: <> +:link-join: <> +:link-joins: <> +:link-permissionRule: <> +:link-permissionRules: <> +:link-possibleValueSource: <> +:link-possibleValueSources: <> +:link-process: <> +:link-processes: <> +:link-report: <> +:link-reports: <> +:link-securityKeyType: <> +:link-securityKeyTypes: <> +:link-table: <> +:link-tables: <> +:link-widget: <> +:link-widgets: <> diff --git a/pom.xml b/pom.xml index c4e668aa..ade15061 100644 --- a/pom.xml +++ b/pom.xml @@ -33,6 +33,7 @@ qqq-backend-module-api qqq-backend-module-filesystem qqq-backend-module-rdbms + qqq-backend-module-mongodb qqq-language-support-javascript qqq-middleware-picocli qqq-middleware-javalin @@ -79,12 +80,12 @@ org.apache.logging.log4j log4j-api - 2.17.1 + 2.23.0 org.apache.logging.log4j log4j-core - 2.17.1 + 2.23.0 org.junit.jupiter @@ -108,6 +109,16 @@ + + + src/main/java + false + + + src/main/resources + false + + @@ -317,6 +328,32 @@ fi + + + + + org.apache.maven.plugins + maven-javadoc-plugin + 3.6.2 + + + aggregate + false + + aggregate + + + + default + + javadoc + + + + + + + github-qqq-maven-registry diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/QBackendTransaction.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/QBackendTransaction.java index 64a0c57e..465dae45 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/QBackendTransaction.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/QBackendTransaction.java @@ -23,6 +23,9 @@ package com.kingsrook.qqq.backend.core.actions; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.model.actions.AbstractTableActionInput; +import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleDispatcher; +import com.kingsrook.qqq.backend.core.modules.backend.QBackendModuleInterface; /******************************************************************************* @@ -30,12 +33,26 @@ import com.kingsrook.qqq.backend.core.exceptions.QException; ** part of a transaction. ** ** Most obvious use-case would be a JDBC Connection. See subclass in rdbms module. + ** Ditto MongoDB. ** ** Note: One would imagine that this class shouldn't ever implement Serializable... *******************************************************************************/ public class QBackendTransaction { + /******************************************************************************* + ** + *******************************************************************************/ + public static QBackendTransaction openFor(AbstractTableActionInput input) throws QException + { + QBackendModuleDispatcher qBackendModuleDispatcher = new QBackendModuleDispatcher(); + QBackendModuleInterface qModule = qBackendModuleDispatcher.getQBackendModule(input.getBackend()); + QBackendTransaction transaction = qModule.openTransaction(input); + return (transaction); + } + + + /******************************************************************************* ** Commit the transaction. *******************************************************************************/ diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/async/AsyncRecordPipeLoop.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/async/AsyncRecordPipeLoop.java index 22d73fb5..74430f7f 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/async/AsyncRecordPipeLoop.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/async/AsyncRecordPipeLoop.java @@ -83,6 +83,15 @@ public class AsyncRecordPipeLoop long jobStartTime = System.currentTimeMillis(); boolean everCalledConsumer = false; + //////////////////////////////////////////////////////////////////////////// + // in case the pipe capacity has been made very small (useful in tests!), // + // then make the minRecordsToConsume match it. // + //////////////////////////////////////////////////////////////////////////// + if(recordPipe.getCapacity() < minRecordsToConsume) + { + minRecordsToConsume = recordPipe.getCapacity(); + } + while(jobState.equals(AsyncJobState.RUNNING)) { if(recordPipe.countAvailableRecords() < minRecordsToConsume) diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/audits/AuditAction.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/audits/AuditAction.java index 540d0611..518718a9 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/audits/AuditAction.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/audits/AuditAction.java @@ -295,7 +295,7 @@ public class AuditAction extends AbstractQActionFunction loggedUnauditableTableNames = new HashSet<>(); + /******************************************************************************* @@ -102,6 +106,21 @@ public class DMLAuditAction extends AbstractQActionFunction + /******************************************************************************* + ** Get instance by id + ** + *******************************************************************************/ + public static AutomationStatus getById(Integer id) + { + if(id == null) + { + return (null); + } + + for(AutomationStatus value : AutomationStatus.values()) + { + if(Objects.equals(value.id, id)) + { + return (value); + } + } + + return (null); + } + + + /******************************************************************************* ** Getter for id ** @@ -106,10 +131,10 @@ public enum AutomationStatus implements PossibleValueEnum public String getInsertOrUpdate() { return switch(this) - { - case PENDING_INSERT_AUTOMATIONS, RUNNING_INSERT_AUTOMATIONS, FAILED_INSERT_AUTOMATIONS -> "Insert"; - case PENDING_UPDATE_AUTOMATIONS, RUNNING_UPDATE_AUTOMATIONS, FAILED_UPDATE_AUTOMATIONS -> "Update"; - case OK -> ""; - }; + { + case PENDING_INSERT_AUTOMATIONS, RUNNING_INSERT_AUTOMATIONS, FAILED_INSERT_AUTOMATIONS -> "Insert"; + case PENDING_UPDATE_AUTOMATIONS, RUNNING_UPDATE_AUTOMATIONS, FAILED_UPDATE_AUTOMATIONS -> "Update"; + case OK -> ""; + }; } } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/automation/RecordAutomationStatusUpdater.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/automation/RecordAutomationStatusUpdater.java index ce942c25..beef50e5 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/automation/RecordAutomationStatusUpdater.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/automation/RecordAutomationStatusUpdater.java @@ -22,30 +22,40 @@ package com.kingsrook.qqq.backend.core.actions.automation; +import java.io.Serializable; +import java.time.Duration; +import java.time.temporal.ChronoUnit; import java.util.Collections; +import java.util.HashSet; import java.util.List; +import java.util.Optional; +import java.util.Set; +import com.kingsrook.qqq.backend.core.actions.QBackendTransaction; import com.kingsrook.qqq.backend.core.actions.tables.CountAction; +import com.kingsrook.qqq.backend.core.actions.tables.QueryAction; import com.kingsrook.qqq.backend.core.actions.tables.UpdateAction; import com.kingsrook.qqq.backend.core.context.QContext; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.instances.QMetaDataVariableInterpreter; import com.kingsrook.qqq.backend.core.logging.QLogger; import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountInput; import com.kingsrook.qqq.backend.core.model.actions.tables.count.CountOutput; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QCriteriaOperator; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QFilterCriteria; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput; import com.kingsrook.qqq.backend.core.model.actions.tables.update.UpdateInput; import com.kingsrook.qqq.backend.core.model.automation.TableTrigger; import com.kingsrook.qqq.backend.core.model.data.QRecord; -import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.automation.AutomationStatusTrackingType; import com.kingsrook.qqq.backend.core.model.metadata.tables.automation.QTableAutomationDetails; import com.kingsrook.qqq.backend.core.model.metadata.tables.automation.TableAutomationAction; import com.kingsrook.qqq.backend.core.model.metadata.tables.automation.TriggerEvent; -import com.kingsrook.qqq.backend.core.model.session.QSession; import com.kingsrook.qqq.backend.core.utils.CollectionUtils; +import com.kingsrook.qqq.backend.core.utils.memoization.Memoization; import org.apache.commons.lang.NotImplementedException; +import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair; /******************************************************************************* @@ -55,19 +65,37 @@ public class RecordAutomationStatusUpdater { private static final QLogger LOG = QLogger.getLogger(RecordAutomationStatusUpdater.class); + /////////////////////////////////////////////////////////////////////////////////////////////////////// + // feature flag - by default, will be true - before setting records to PENDING_UPDATE_AUTOMATIONS, // + // we will fetch them (if we didn't take them in from the caller, which, UpdateAction does if its // + // backend supports it), to check their current automationStatus - and if they are currently PENDING // + // or RUNNING inserts or updates, we won't update them. // + /////////////////////////////////////////////////////////////////////////////////////////////////////// + private static boolean allowPreUpdateFetch = new QMetaDataVariableInterpreter().getBooleanFromPropertyOrEnvironment("qqq.recordAutomationStatusUpdater.allowPreUpdateFetch", "QQQ_RECORD_AUTOMATION_STATUS_UPDATER_ALLOW_PRE_UPDATE_FETCH", true); + + /////////////////////////////////////////////////////////////////////////////////////////////// + // feature flag - by default, we'll memoize the check for triggers - but we can turn it off. // + /////////////////////////////////////////////////////////////////////////////////////////////// + private static boolean memoizeCheckForTriggers = new QMetaDataVariableInterpreter().getBooleanFromPropertyOrEnvironment("qqq.recordAutomationStatusUpdater.memoizeCheckForTriggers", "QQQ_RECORD_AUTOMATION_STATUS_UPDATER_MEMOIZE_CHECK_FOR_TRIGGERS", true); + + private static Memoization areThereTableTriggersForTableMemoization = new Memoization().withTimeout(Duration.of(60, ChronoUnit.SECONDS)); + /******************************************************************************* ** for a list of records from a table, set their automation status - based on ** how the table is configured. *******************************************************************************/ - public static boolean setAutomationStatusInRecords(QSession session, QTableMetaData table, List records, AutomationStatus automationStatus) + public static boolean setAutomationStatusInRecords(QTableMetaData table, List records, AutomationStatus automationStatus, QBackendTransaction transaction, List oldRecordList) { if(table == null || table.getAutomationDetails() == null || CollectionUtils.nullSafeIsEmpty(records)) { return (false); } + QTableAutomationDetails automationDetails = table.getAutomationDetails(); + Set pkeysWeMayNotUpdate = new HashSet<>(); + /////////////////////////////////////////////////////////////////////////////////////////////////// // In case an automation is running, and it updates records - don't let those records be marked // // as PENDING_UPDATE_AUTOMATIONS... this is meant to avoid having a record's automation update // @@ -81,12 +109,60 @@ public class RecordAutomationStatusUpdater for(StackTraceElement stackTraceElement : e.getStackTrace()) { String className = stackTraceElement.getClassName(); - if(className.contains("com.kingsrook.qqq.backend.core.actions.automation") && !className.equals(RecordAutomationStatusUpdater.class.getName()) && !className.endsWith("Test")) + if(className.contains(RecordAutomationStatusUpdater.class.getPackageName()) && !className.equals(RecordAutomationStatusUpdater.class.getName()) && !className.endsWith("Test") && !className.contains("Test$")) { LOG.debug("Avoiding re-setting automation status to PENDING_UPDATE while running an automation"); return (false); } } + + /////////////////////////////////////////////////////////////////////////////// + // if table uses field-in-table status tracking, then check the old records, // + // before we set them to pending-updates, to avoid losing other pending or // + // running status information. We will allow moving from OK or the 2 // + // failed statuses into pending-updates - which seems right. // + // This is added to fix cases where an update that comes in before insert // + // -automations have run, will cause the pending-insert status to be missed. // + /////////////////////////////////////////////////////////////////////////////// + if(automationDetails.getStatusTracking() != null && AutomationStatusTrackingType.FIELD_IN_TABLE.equals(automationDetails.getStatusTracking().getType())) + { + try + { + if(CollectionUtils.nullSafeIsEmpty(oldRecordList)) + { + /////////////////////////////////////////////////////////////////////////////////////////////// + // if we didn't get the oldRecordList as input (though UpdateAction should usually pass it?) // + // then check feature-flag if we're allowed to do a lookup here & now. If so, then do. // + /////////////////////////////////////////////////////////////////////////////////////////////// + if(allowPreUpdateFetch) + { + List pkeysToLookup = records.stream().map(r -> r.getValue(table.getPrimaryKeyField())).toList(); + oldRecordList = new QueryAction().execute(new QueryInput(table.getName()) + .withFilter(new QQueryFilter(new QFilterCriteria(table.getPrimaryKeyField(), QCriteriaOperator.IN, pkeysToLookup))) + .withTransaction(transaction) + ).getRecords(); + } + } + + for(QRecord freshRecord : CollectionUtils.nonNullList(oldRecordList)) + { + Serializable recordStatus = freshRecord.getValue(automationDetails.getStatusTracking().getFieldName()); + if(AutomationStatus.PENDING_INSERT_AUTOMATIONS.getId().equals(recordStatus) + || AutomationStatus.PENDING_UPDATE_AUTOMATIONS.getId().equals(recordStatus) + || AutomationStatus.RUNNING_INSERT_AUTOMATIONS.getId().equals(recordStatus) + || AutomationStatus.RUNNING_UPDATE_AUTOMATIONS.getId().equals(recordStatus)) + { + Serializable primaryKey = freshRecord.getValue(table.getPrimaryKeyField()); + LOG.debug("May not update automation status", logPair("table", table.getName()), logPair("id", primaryKey), logPair("currentStatus", recordStatus), logPair("requestedStatus", automationStatus.getId())); + pkeysWeMayNotUpdate.add(primaryKey); + } + } + } + catch(QException qe) + { + LOG.error("Error checking existing automation status before setting new automation status - more records will be updated than maybe should be...", qe); + } + } } //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -98,19 +174,15 @@ public class RecordAutomationStatusUpdater automationStatus = AutomationStatus.OK; } - QTableAutomationDetails automationDetails = table.getAutomationDetails(); if(automationDetails.getStatusTracking() != null && AutomationStatusTrackingType.FIELD_IN_TABLE.equals(automationDetails.getStatusTracking().getType())) { for(QRecord record : records) { - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // todo - seems like there's some case here, where if an order was in PENDING_INSERT, but then some other job updated the record, that we'd // - // lose that pending status, which would be a Bad Thing™... // - // problem is - we may not have the full record in here, so we can't necessarily check the record to see what status it's currently in... // - /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - record.setValue(automationDetails.getStatusTracking().getFieldName(), automationStatus.getId()); - // todo - another field - for the automation timestamp?? + if(!pkeysWeMayNotUpdate.contains(record.getValue(table.getPrimaryKeyField()))) + { + record.setValue(automationDetails.getStatusTracking().getFieldName(), automationStatus.getId()); + // todo - another field - for the automation timestamp?? + } } } @@ -188,11 +260,29 @@ public class RecordAutomationStatusUpdater return (false); } + if(memoizeCheckForTriggers) + { + /////////////////////////////////////////////////////////////////////////////////////// + // as within the lookup method, error on the side of "yes, maybe there are triggers" // + /////////////////////////////////////////////////////////////////////////////////////// + Optional result = areThereTableTriggersForTableMemoization.getResult(new Key(table, triggerEvent), key -> lookupIfThereAreTriggersForTable(table, triggerEvent)); + return result.orElse(true); + } + else + { + return lookupIfThereAreTriggersForTable(table, triggerEvent); + } + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + private static Boolean lookupIfThereAreTriggersForTable(QTableMetaData table, TriggerEvent triggerEvent) + { try { - /////////////////// - // todo - cache? // - /////////////////// CountInput countInput = new CountInput(); countInput.setTableName(TableTrigger.TABLE_NAME); countInput.setFilter(new QQueryFilter( @@ -207,6 +297,7 @@ public class RecordAutomationStatusUpdater /////////////////////////////////////////////////////////////////////////////////////////////////////////// // if the count query failed, we're a bit safer to err on the side of "yeah, there might be automations" // /////////////////////////////////////////////////////////////////////////////////////////////////////////// + LOG.warn("Error looking if there are triggers for table", e, logPair("tableName", table.getName())); return (true); } } @@ -217,12 +308,12 @@ public class RecordAutomationStatusUpdater ** for a list of records, update their automation status and actually Update the ** backend as well. *******************************************************************************/ - public static void setAutomationStatusInRecordsAndUpdate(QInstance instance, QSession session, QTableMetaData table, List records, AutomationStatus automationStatus) throws QException + public static void setAutomationStatusInRecordsAndUpdate(QTableMetaData table, List records, AutomationStatus automationStatus, QBackendTransaction transaction) throws QException { QTableAutomationDetails automationDetails = table.getAutomationDetails(); if(automationDetails != null && AutomationStatusTrackingType.FIELD_IN_TABLE.equals(automationDetails.getStatusTracking().getType())) { - boolean didSetStatusField = setAutomationStatusInRecords(session, table, records, automationStatus); + boolean didSetStatusField = setAutomationStatusInRecords(table, records, automationStatus, transaction, null); if(didSetStatusField) { UpdateInput updateInput = new UpdateInput(); @@ -237,6 +328,7 @@ public class RecordAutomationStatusUpdater .withValue(table.getPrimaryKeyField(), r.getValue(table.getPrimaryKeyField())) .withValue(automationDetails.getStatusTracking().getFieldName(), r.getValue(automationDetails.getStatusTracking().getFieldName()))).toList()); updateInput.setAreAllValuesBeingUpdatedTheSame(true); + updateInput.setTransaction(transaction); updateInput.setOmitDmlAudit(true); new UpdateAction().execute(updateInput); @@ -250,4 +342,8 @@ public class RecordAutomationStatusUpdater } } + + + private record Key(QTableMetaData table, TriggerEvent triggerEvent) {} + } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/automation/polling/PollingAutomationPerTableRunner.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/automation/polling/PollingAutomationPerTableRunner.java index 8d37403e..2113facc 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/automation/polling/PollingAutomationPerTableRunner.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/automation/polling/PollingAutomationPerTableRunner.java @@ -28,6 +28,7 @@ import java.util.Comparator; import java.util.List; import java.util.Map; import java.util.Objects; +import java.util.Optional; import java.util.function.Supplier; import java.util.stream.Collectors; import com.kingsrook.qqq.backend.core.actions.async.AsyncRecordPipeLoop; @@ -43,6 +44,7 @@ import com.kingsrook.qqq.backend.core.actions.tables.GetAction; import com.kingsrook.qqq.backend.core.actions.tables.QueryAction; import com.kingsrook.qqq.backend.core.context.QContext; import com.kingsrook.qqq.backend.core.exceptions.QException; +import com.kingsrook.qqq.backend.core.logging.LogPair; import com.kingsrook.qqq.backend.core.logging.QLogger; import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessInput; import com.kingsrook.qqq.backend.core.model.actions.processes.RunProcessOutput; @@ -59,18 +61,21 @@ import com.kingsrook.qqq.backend.core.model.automation.TableTrigger; import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.metadata.QInstance; import com.kingsrook.qqq.backend.core.model.metadata.code.QCodeReference; +import com.kingsrook.qqq.backend.core.model.metadata.fields.DynamicDefaultValueBehavior; +import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.metadata.tables.automation.AutomationStatusTrackingType; import com.kingsrook.qqq.backend.core.model.metadata.tables.automation.QTableAutomationDetails; import com.kingsrook.qqq.backend.core.model.metadata.tables.automation.TableAutomationAction; import com.kingsrook.qqq.backend.core.model.metadata.tables.automation.TriggerEvent; -import com.kingsrook.qqq.backend.core.model.savedfilters.SavedFilter; +import com.kingsrook.qqq.backend.core.model.savedviews.SavedView; import com.kingsrook.qqq.backend.core.model.session.QSession; import com.kingsrook.qqq.backend.core.utils.CollectionUtils; import com.kingsrook.qqq.backend.core.utils.JsonUtils; import com.kingsrook.qqq.backend.core.utils.StringUtils; import com.kingsrook.qqq.backend.core.utils.collections.MapBuilder; import org.apache.commons.lang.NotImplementedException; +import org.json.JSONObject; import static com.kingsrook.qqq.backend.core.logging.LogUtils.logPair; @@ -87,8 +92,9 @@ public class PollingAutomationPerTableRunner implements Runnable { private static final QLogger LOG = QLogger.getLogger(PollingAutomationPerTableRunner.class); - private final TableActions tableActions; - private final String name; + private final TableActionsInterface tableActions; + + private String name; private QInstance instance; private Supplier sessionSupplier; @@ -116,10 +122,51 @@ public class PollingAutomationPerTableRunner implements Runnable /******************************************************************************* - ** + ** Interface to be used by 2 records in this class - normal TableActions, and + ** ShardedTableActions. *******************************************************************************/ - public record TableActions(String tableName, AutomationStatus status) + public interface TableActionsInterface { + /******************************************************************************* + ** + *******************************************************************************/ + String tableName(); + + /******************************************************************************* + ** + *******************************************************************************/ + AutomationStatus status(); + } + + + + /******************************************************************************* + ** Wrapper for a pair of (tableName, automationStatus) + *******************************************************************************/ + public record TableActions(String tableName, AutomationStatus status) implements TableActionsInterface + { + /******************************************************************************* + ** + *******************************************************************************/ + public void noopToFakeTestCoverage() + { + } + } + + + + /******************************************************************************* + ** extended version of TableAction, for sharding use-case - adds the shard + ** details. + *******************************************************************************/ + public record ShardedTableActions(String tableName, AutomationStatus status, String shardByFieldName, Serializable shardValue, String shardLabel) implements TableActionsInterface + { + /******************************************************************************* + ** + *******************************************************************************/ + public void noopToFakeTestCoverage() + { + } } @@ -128,16 +175,46 @@ public class PollingAutomationPerTableRunner implements Runnable ** basically just get a list of tables which at least *could* have automations ** run - either meta-data automations, or table-triggers (data/user defined). *******************************************************************************/ - public static List getTableActions(QInstance instance, String providerName) + public static List getTableActions(QInstance instance, String providerName) { - List tableActionList = new ArrayList<>(); + List tableActionList = new ArrayList<>(); for(QTableMetaData table : instance.getTables().values()) { - if(table.getAutomationDetails() != null && providerName.equals(table.getAutomationDetails().getProviderName())) + QTableAutomationDetails automationDetails = table.getAutomationDetails(); + if(automationDetails != null && providerName.equals(automationDetails.getProviderName())) { - tableActionList.add(new TableActions(table.getName(), AutomationStatus.PENDING_INSERT_AUTOMATIONS)); - tableActionList.add(new TableActions(table.getName(), AutomationStatus.PENDING_UPDATE_AUTOMATIONS)); + if(StringUtils.hasContent(automationDetails.getShardByFieldName())) + { + ////////////////////////////////////////////////////////////////////////////////////////////// + // for sharded automations, add a tableAction (of the sharded subtype) for each shard-value // + ////////////////////////////////////////////////////////////////////////////////////////////// + try + { + QueryInput queryInput = new QueryInput(); + queryInput.setTableName(automationDetails.getShardSourceTableName()); + QueryOutput queryOutput = new QueryAction().execute(queryInput); + for(QRecord record : queryOutput.getRecords()) + { + Serializable shardId = record.getValue(automationDetails.getShardIdFieldName()); + String label = record.getValueString(automationDetails.getShardLabelFieldName()); + tableActionList.add(new ShardedTableActions(table.getName(), AutomationStatus.PENDING_INSERT_AUTOMATIONS, automationDetails.getShardByFieldName(), shardId, label)); + tableActionList.add(new ShardedTableActions(table.getName(), AutomationStatus.PENDING_UPDATE_AUTOMATIONS, automationDetails.getShardByFieldName(), shardId, label)); + } + } + catch(Exception e) + { + LOG.error("Error getting sharded table automation actions for a table", e, new LogPair("tableName", table.getName())); + } + } + else + { + /////////////////////////////////////////////////////////////////// + // for non-sharded, we just need tabler name & automation status // + /////////////////////////////////////////////////////////////////// + tableActionList.add(new TableActions(table.getName(), AutomationStatus.PENDING_INSERT_AUTOMATIONS)); + tableActionList.add(new TableActions(table.getName(), AutomationStatus.PENDING_UPDATE_AUTOMATIONS)); + } } } @@ -149,12 +226,17 @@ public class PollingAutomationPerTableRunner implements Runnable /******************************************************************************* ** *******************************************************************************/ - public PollingAutomationPerTableRunner(QInstance instance, String providerName, Supplier sessionSupplier, TableActions tableActions) + public PollingAutomationPerTableRunner(QInstance instance, String providerName, Supplier sessionSupplier, TableActionsInterface tableActions) { this.instance = instance; this.sessionSupplier = sessionSupplier; this.tableActions = tableActions; this.name = providerName + ">" + tableActions.tableName() + ">" + tableActions.status().getInsertOrUpdate(); + + if(tableActions instanceof ShardedTableActions shardedTableActions) + { + this.name += ":" + shardedTableActions.shardLabel(); + } } @@ -173,12 +255,11 @@ public class PollingAutomationPerTableRunner implements Runnable try { - QSession session = sessionSupplier != null ? sessionSupplier.get() : new QSession(); - processTableInsertOrUpdate(instance.getTable(tableActions.tableName()), session, tableActions.status()); + processTableInsertOrUpdate(instance.getTable(tableActions.tableName()), tableActions.status()); } catch(Exception e) { - LOG.warn("Error running automations", e); + LOG.warn("Error running automations", e, logPair("tableName", tableActions.tableName()), logPair("status", tableActions.status())); } finally { @@ -192,7 +273,7 @@ public class PollingAutomationPerTableRunner implements Runnable /******************************************************************************* ** Query for and process records that have a PENDING_INSERT or PENDING_UPDATE status on a given table. *******************************************************************************/ - public void processTableInsertOrUpdate(QTableMetaData table, QSession session, AutomationStatus automationStatus) throws QException + public void processTableInsertOrUpdate(QTableMetaData table, AutomationStatus automationStatus) throws QException { ///////////////////////////////////////////////////////////////////////// // get the actions to run against this table in this automation status // @@ -222,19 +303,30 @@ public class PollingAutomationPerTableRunner implements Runnable AutomationStatusTrackingType statusTrackingType = automationDetails.getStatusTracking().getType(); if(AutomationStatusTrackingType.FIELD_IN_TABLE.equals(statusTrackingType)) { - queryInput.setFilter(new QQueryFilter().withCriteria(new QFilterCriteria(automationDetails.getStatusTracking().getFieldName(), QCriteriaOperator.EQUALS, List.of(automationStatus.getId())))); + QQueryFilter filter = new QQueryFilter().withCriteria(new QFilterCriteria(automationDetails.getStatusTracking().getFieldName(), QCriteriaOperator.EQUALS, List.of(automationStatus.getId()))); + addOrderByToQueryFilter(table, automationStatus, filter); + queryInput.setFilter(filter); } else { throw (new NotImplementedException("Automation Status Tracking type [" + statusTrackingType + "] is not yet implemented in here.")); } + if(tableActions instanceof ShardedTableActions shardedTableActions) + { + ////////////////////////////////////////////////////////////// + // for sharded actions, add the shardBy field as a criteria // + ////////////////////////////////////////////////////////////// + QQueryFilter filter = queryInput.getFilter(); + filter.addCriteria(new QFilterCriteria(shardedTableActions.shardByFieldName(), QCriteriaOperator.EQUALS, shardedTableActions.shardValue())); + } + queryInput.setRecordPipe(recordPipe); return (new QueryAction().execute(queryInput)); }, () -> { List records = recordPipe.consumeAvailableRecords(); - applyActionsToRecords(session, table, records, actions, automationStatus); + applyActionsToRecords(table, records, actions, automationStatus); return (records.size()); } ); @@ -242,6 +334,38 @@ public class PollingAutomationPerTableRunner implements Runnable + /******************************************************************************* + ** + *******************************************************************************/ + static void addOrderByToQueryFilter(QTableMetaData table, AutomationStatus automationStatus, QQueryFilter filter) + { + //////////////////////////////////////////////////////////////////////////////////// + // look for a field in the table with either create-date or modify-date behavior, // + // based on if doing insert or update automations // + //////////////////////////////////////////////////////////////////////////////////// + DynamicDefaultValueBehavior dynamicDefaultValueBehavior = automationStatus.equals(AutomationStatus.PENDING_INSERT_AUTOMATIONS) ? DynamicDefaultValueBehavior.CREATE_DATE : DynamicDefaultValueBehavior.MODIFY_DATE; + Optional field = table.getFields().values().stream() + .filter(f -> dynamicDefaultValueBehavior.equals(f.getBehaviorOrDefault(QContext.getQInstance(), DynamicDefaultValueBehavior.class))) + .findFirst(); + + if(field.isPresent()) + { + ////////////////////////////////////////////////////////////////////// + // if a create/modify date field was found, order by it (ascending) // + ////////////////////////////////////////////////////////////////////// + filter.addOrderBy(new QFilterOrderBy(field.get().getName())); + } + else + { + //////////////////////////////////// + // else, order by the primary key // + //////////////////////////////////// + filter.addOrderBy(new QFilterOrderBy(table.getPrimaryKeyField())); + } + } + + + /******************************************************************************* ** get the actions to run against a table in an automation status. both from ** metaData and tableTriggers/data. @@ -258,7 +382,23 @@ public class PollingAutomationPerTableRunner implements Runnable { if(action.getTriggerEvent().equals(triggerEvent)) { - rs.add(action); + /////////////////////////////////////////////////////////// + // for sharded configs, only run if the shard id matches // + /////////////////////////////////////////////////////////// + if(tableActions instanceof ShardedTableActions shardedTableActions) + { + if(shardedTableActions.shardValue().equals(action.getShardId())) + { + rs.add(action); + } + } + else + { + //////////////////////////////////////////// + // for non-sharded, always add the action // + //////////////////////////////////////////// + rs.add(action); + } } } @@ -285,13 +425,15 @@ public class PollingAutomationPerTableRunner implements Runnable if(filterId != null) { GetInput getInput = new GetInput(); - getInput.setTableName(SavedFilter.TABLE_NAME); + getInput.setTableName(SavedView.TABLE_NAME); getInput.setPrimaryKey(filterId); GetOutput getOutput = new GetAction().execute(getInput); if(getOutput.getRecord() != null) { - SavedFilter savedFilter = new SavedFilter(getOutput.getRecord()); - filter = JsonUtils.toObject(savedFilter.getFilterJson(), QQueryFilter.class); + SavedView savedView = new SavedView(getOutput.getRecord()); + JSONObject viewJson = new JSONObject(savedView.getViewJson()); + JSONObject queryFilter = viewJson.getJSONObject("queryFilter"); + filter = JsonUtils.toObject(queryFilter.toString(), QQueryFilter.class); } } @@ -324,7 +466,7 @@ public class PollingAutomationPerTableRunner implements Runnable ** table's actions against them - IF they are found to match the action's filter ** (assuming it has one - if it doesn't, then all records match). *******************************************************************************/ - private void applyActionsToRecords(QSession session, QTableMetaData table, List records, List actions, AutomationStatus automationStatus) throws QException + private void applyActionsToRecords(QTableMetaData table, List records, List actions, AutomationStatus automationStatus) throws QException { if(CollectionUtils.nullSafeIsEmpty(records)) { @@ -334,7 +476,7 @@ public class PollingAutomationPerTableRunner implements Runnable /////////////////////////////////////////////////// // mark the records as RUNNING their automations // /////////////////////////////////////////////////// - RecordAutomationStatusUpdater.setAutomationStatusInRecordsAndUpdate(instance, session, table, records, pendingToRunningStatusMap.get(automationStatus)); + RecordAutomationStatusUpdater.setAutomationStatusInRecordsAndUpdate(table, records, pendingToRunningStatusMap.get(automationStatus), null); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// // foreach action - run it against the records (but only if they match the action's filter, if there is one) // @@ -352,13 +494,15 @@ public class PollingAutomationPerTableRunner implements Runnable //////////////////////////////////////// // update status on all these records // //////////////////////////////////////// - if(anyActionsFailed) + AutomationStatus statusToUpdateTo = anyActionsFailed ? pendingToFailedStatusMap.get(automationStatus) : AutomationStatus.OK; + try { - RecordAutomationStatusUpdater.setAutomationStatusInRecordsAndUpdate(instance, session, table, records, pendingToFailedStatusMap.get(automationStatus)); + RecordAutomationStatusUpdater.setAutomationStatusInRecordsAndUpdate(table, records, statusToUpdateTo, null); } - else + catch(Exception e) { - RecordAutomationStatusUpdater.setAutomationStatusInRecordsAndUpdate(instance, session, table, records, AutomationStatus.OK); + LOG.warn("Error updating automationStatus after running automations", logPair("tableName", table), logPair("count", records.size()), logPair("status", statusToUpdateTo)); + throw (e); } } @@ -388,7 +532,7 @@ public class PollingAutomationPerTableRunner implements Runnable } catch(Exception e) { - LOG.warn("Caught exception processing records on " + table + " for action " + action, e); + LOG.warn("Caught exception processing automations", e, logPair("tableName", table), logPair("action", action.getName())); return (true); } } @@ -471,7 +615,7 @@ public class PollingAutomationPerTableRunner implements Runnable @Override public QQueryFilter getQueryFilter() { - List recordIds = records.stream().map(r -> r.getValueInteger(table.getPrimaryKeyField())).collect(Collectors.toList()); + List recordIds = records.stream().map(r -> r.getValue(table.getPrimaryKeyField())).collect(Collectors.toList()); return (new QQueryFilter().withCriteria(new QFilterCriteria(table.getPrimaryKeyField(), QCriteriaOperator.IN, recordIds))); } }); diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/AbstractHTMLWidgetRenderer.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/AbstractHTMLWidgetRenderer.java index 3705968c..26481e78 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/AbstractHTMLWidgetRenderer.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/AbstractHTMLWidgetRenderer.java @@ -41,6 +41,7 @@ import com.kingsrook.qqq.backend.core.model.actions.widgets.RenderWidgetInput; import com.kingsrook.qqq.backend.core.model.metadata.fields.DisplayFormat; import com.kingsrook.qqq.backend.core.model.metadata.processes.QProcessMetaData; import com.kingsrook.qqq.backend.core.utils.JsonUtils; +import com.kingsrook.qqq.backend.core.utils.QQueryFilterDeduper; import com.kingsrook.qqq.backend.core.utils.StringUtils; @@ -176,11 +177,13 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer { return (totalString); } + filter = QQueryFilterDeduper.dedupeFilter(filter); return ("" + totalString + ""); } + /******************************************************************************* ** *******************************************************************************/ @@ -192,6 +195,7 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer return; } + filter = QQueryFilterDeduper.dedupeFilter(filter); urls.add(tablePath + "?filter=" + JsonUtils.toJson(filter)); } @@ -208,6 +212,7 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer return (null); } + filter = QQueryFilterDeduper.dedupeFilter(filter); return (tablePath + "?filter=" + JsonUtils.toJson(filter)); } @@ -224,6 +229,7 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer return (null); } + filter = QQueryFilterDeduper.dedupeFilter(filter); return (tablePath + "?filter=" + URLEncoder.encode(JsonUtils.toJson(filter), Charset.defaultCharset())); } @@ -326,6 +332,7 @@ public abstract class AbstractHTMLWidgetRenderer extends AbstractWidgetRenderer } String tablePath = QContext.getQInstance().getTablePath(tableName); + filter = QQueryFilterDeduper.dedupeFilter(filter); return (tablePath + "/" + processName + "?recordsParam=filterJSON&filterJSON=" + URLEncoder.encode(JsonUtils.toJson(filter), StandardCharsets.UTF_8)); } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/DateTimeGroupBy.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/DateTimeGroupBy.java index f69596af..2cc0ba81 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/DateTimeGroupBy.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/dashboard/widgets/DateTimeGroupBy.java @@ -297,4 +297,21 @@ public enum DateTimeGroupBy ZonedDateTime zoned = instant.atZone(zoneId); return (zoned.plus(noOfChronoUnitsToAdd, chronoUnitToAdd).toInstant()); } + + + + /******************************************************************************* + ** + *******************************************************************************/ + public static DateTimeFormatter sqlDateFormatToSelectedDateTimeFormatter(String sqlDateFormat) + { + for(DateTimeGroupBy value : values()) + { + if(value.sqlDateFormat.equals(sqlDateFormat)) + { + return (value.selectedStringFormatter); + } + } + return null; + } } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/interfaces/InsertInterface.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/interfaces/InsertInterface.java index 3eb2738d..a1316cdf 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/interfaces/InsertInterface.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/interfaces/InsertInterface.java @@ -31,7 +31,7 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.insert.InsertOutput; ** Interface for the Insert action. ** *******************************************************************************/ -public interface InsertInterface extends QActionInterface +public interface InsertInterface { /******************************************************************************* ** diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/metadata/MetaDataAction.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/metadata/MetaDataAction.java index ef571e45..403d94e3 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/metadata/MetaDataAction.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/metadata/MetaDataAction.java @@ -23,6 +23,7 @@ package com.kingsrook.qqq.backend.core.actions.metadata; import java.util.ArrayList; +import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -150,14 +151,21 @@ public class MetaDataAction } metaDataOutput.setWidgets(widgets); + /////////////////////////////////////////////////////// + // sort apps - by sortOrder (integer), then by label // + /////////////////////////////////////////////////////// + List sortedApps = metaDataInput.getInstance().getApps().values().stream() + .sorted(Comparator.comparing((QAppMetaData a) -> a.getSortOrder()) + .thenComparing((QAppMetaData a) -> a.getLabel())) + .toList(); + /////////////////////////////////// // map apps to frontend metadata // /////////////////////////////////// Map apps = new LinkedHashMap<>(); - for(Map.Entry entry : metaDataInput.getInstance().getApps().entrySet()) + for(QAppMetaData app : sortedApps) { - String appName = entry.getKey(); - QAppMetaData app = entry.getValue(); + String appName = app.getName(); PermissionCheckResult permissionResult = PermissionsHelper.getPermissionCheckResult(metaDataInput, app); if(permissionResult.equals(PermissionCheckResult.DENY_HIDE)) @@ -191,7 +199,7 @@ public class MetaDataAction // organize app tree nodes by their hierarchy // //////////////////////////////////////////////// List appTree = new ArrayList<>(); - for(QAppMetaData appMetaData : metaDataInput.getInstance().getApps().values()) + for(QAppMetaData appMetaData : sortedApps) { if(appMetaData.getParentAppName() == null) { diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/processes/QProcessCallbackFactory.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/processes/QProcessCallbackFactory.java new file mode 100644 index 00000000..977104c0 --- /dev/null +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/processes/QProcessCallbackFactory.java @@ -0,0 +1,68 @@ +/* + * QQQ - Low-code Application Framework for Engineers. + * Copyright (C) 2021-2024. Kingsrook, LLC + * 651 N Broad St Ste 205 # 6917 | Middletown DE 19709 | United States + * contact@kingsrook.com + * https://github.com/Kingsrook/ + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package com.kingsrook.qqq.backend.core.actions.processes; + + +import java.io.Serializable; +import java.util.Collections; +import java.util.List; +import java.util.Map; +import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; +import com.kingsrook.qqq.backend.core.model.metadata.fields.QFieldMetaData; + + +/******************************************************************************* + ** Constructor for commonly used QProcessCallback's + *******************************************************************************/ +public class QProcessCallbackFactory +{ + + /******************************************************************************* + ** + *******************************************************************************/ + public static QProcessCallback forFilter(QQueryFilter filter) + { + return new QProcessCallback() + { + /******************************************************************************* + ** + *******************************************************************************/ + @Override + public QQueryFilter getQueryFilter() + { + return (filter); + } + + + + /******************************************************************************* + ** + *******************************************************************************/ + @Override + public Map getFieldValues(List fields) + { + return (Collections.emptyMap()); + } + }; + } + +} diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/processes/RunProcessAction.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/processes/RunProcessAction.java index 0fee0fcc..c9350e68 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/processes/RunProcessAction.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/processes/RunProcessAction.java @@ -72,7 +72,7 @@ import org.apache.commons.lang.BooleanUtils; /******************************************************************************* - ** Action handler for running q-processes (which are a sequence of q-functions). + ** Action handler for running q-processes (which are a sequence of q-steps). * *******************************************************************************/ public class RunProcessAction @@ -82,6 +82,7 @@ public class RunProcessAction public static final String BASEPULL_THIS_RUNTIME_KEY = "basepullThisRuntimeKey"; public static final String BASEPULL_LAST_RUNTIME_KEY = "basepullLastRuntimeKey"; public static final String BASEPULL_TIMESTAMP_FIELD = "basepullTimestampField"; + public static final String BASEPULL_CONFIGURATION = "basepullConfiguration"; //////////////////////////////////////////////////////////////////////////////////////////////// // indicator that the timestamp field should be updated - e.g., the execute step is finished. // @@ -633,5 +634,6 @@ public class RunProcessAction runProcessInput.getValues().put(BASEPULL_LAST_RUNTIME_KEY, lastRunTime); runProcessInput.getValues().put(BASEPULL_TIMESTAMP_FIELD, basepullConfiguration.getTimestampField()); + runProcessInput.getValues().put(BASEPULL_CONFIGURATION, basepullConfiguration); } } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/reporting/GenerateReportAction.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/reporting/GenerateReportAction.java index 8cc0d588..4f1fc32b 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/reporting/GenerateReportAction.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/reporting/GenerateReportAction.java @@ -274,7 +274,7 @@ public class GenerateReportAction RunBackendStepOutput transformStepOutput = null; if(tableView != null && tableView.getRecordTransformStep() != null) { - transformStep = QCodeLoader.getBackendStep(AbstractTransformStep.class, tableView.getRecordTransformStep()); + transformStep = QCodeLoader.getAdHoc(AbstractTransformStep.class, tableView.getRecordTransformStep()); transformStepInput = new RunBackendStepInput(); transformStepInput.setValues(reportInput.getInputValues()); diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/reporting/RecordPipe.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/reporting/RecordPipe.java index dff2c4de..2583855f 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/reporting/RecordPipe.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/reporting/RecordPipe.java @@ -44,7 +44,8 @@ public class RecordPipe private static final long BLOCKING_SLEEP_MILLIS = 100; private static final long MAX_SLEEP_LOOP_MILLIS = 300_000; // 5 minutes - private ArrayBlockingQueue queue = new ArrayBlockingQueue<>(1_000); + private int capacity = 1_000; + private ArrayBlockingQueue queue = new ArrayBlockingQueue<>(capacity); private boolean isTerminated = false; @@ -72,6 +73,7 @@ public class RecordPipe *******************************************************************************/ public RecordPipe(Integer overrideCapacity) { + this.capacity = overrideCapacity; queue = new ArrayBlockingQueue<>(overrideCapacity); } @@ -213,4 +215,14 @@ public class RecordPipe this.postRecordActions = postRecordActions; } + + + /******************************************************************************* + ** Getter for capacity + ** + *******************************************************************************/ + public int getCapacity() + { + return capacity; + } } diff --git a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/scripts/RunAdHocRecordScriptAction.java b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/scripts/RunAdHocRecordScriptAction.java index adad50a6..fafd48e8 100644 --- a/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/scripts/RunAdHocRecordScriptAction.java +++ b/qqq-backend-core/src/main/java/com/kingsrook/qqq/backend/core/actions/scripts/RunAdHocRecordScriptAction.java @@ -30,6 +30,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; import com.kingsrook.qqq.backend.core.actions.ActionHelper; +import com.kingsrook.qqq.backend.core.actions.audits.DMLAuditAction; import com.kingsrook.qqq.backend.core.actions.tables.GetAction; import com.kingsrook.qqq.backend.core.actions.tables.QueryAction; import com.kingsrook.qqq.backend.core.context.QContext; @@ -47,12 +48,14 @@ import com.kingsrook.qqq.backend.core.model.actions.tables.query.QQueryFilter; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryInput; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryJoin; import com.kingsrook.qqq.backend.core.model.actions.tables.query.QueryOutput; +import com.kingsrook.qqq.backend.core.model.data.QRecord; import com.kingsrook.qqq.backend.core.model.metadata.code.AdHocScriptCodeReference; import com.kingsrook.qqq.backend.core.model.metadata.tables.QTableMetaData; import com.kingsrook.qqq.backend.core.model.scripts.Script; import com.kingsrook.qqq.backend.core.model.scripts.ScriptRevision; import com.kingsrook.qqq.backend.core.model.scripts.ScriptsMetaDataProvider; import com.kingsrook.qqq.backend.core.utils.CollectionUtils; +import com.kingsrook.qqq.backend.core.utils.memoization.Memoization; /******************************************************************************* @@ -65,6 +68,8 @@ public class RunAdHocRecordScriptAction private Map scriptRevisionCacheByScriptRevisionId = new HashMap<>(); private Map scriptRevisionCacheByScriptId = new HashMap<>(); + private static Memoization scriptMemoizationById = new Memoization<>(); + /******************************************************************************* @@ -85,6 +90,12 @@ public class RunAdHocRecordScriptAction throw (new QException("Script revision was not found.")); } + Optional