From b08c822a9bc738edc4c594d48a0136229b9889b9 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Thu, 16 Jan 2020 11:58:39 -0700 Subject: [PATCH 1/8] Update documentation based on #58 This commit contains minor text updates; it doesn't include the reorg or updates to the CMF page suggested in #58; since those are bigger, I'll handle them separately. --- docs/source/bmi.getter_setter.rst | 8 ++++---- docs/source/bmi.grid_funcs.rst | 4 ++-- docs/source/bmi.implementation.rst | 5 +++++ docs/source/bmi.info_funcs.rst | 4 +++- docs/source/bmi.time_funcs.rst | 8 +++++--- docs/source/bmi.var_funcs.rst | 3 +++ docs/source/model_grids.rst | 8 ++++---- 7 files changed, 26 insertions(+), 14 deletions(-) diff --git a/docs/source/bmi.getter_setter.rst b/docs/source/bmi.getter_setter.rst index 9a832f8..311f04c 100644 --- a/docs/source/bmi.getter_setter.rst +++ b/docs/source/bmi.getter_setter.rst @@ -27,8 +27,8 @@ state variable can be changed or check the new data for validity. int get_value(in string name, in array<> dest); The `get_value` function takes a variable name and copies values into a -provided buffer. -The type and size of the buffer depend on the variable, +provided array parameter. +The type and size of the array parameter depend on the variable, and can be determined through :ref:`get_var_type`, :ref:`get_var_nbytes`, etc. Recall that arrays are always flattened in BMI, @@ -39,7 +39,7 @@ even if the model uses dimensional variables. * The *dest* argument must be defined and allocated before calling `get_value`. Whatever values it contains are overwritten in the call to `get_value`. -* In Python, the buffer is a :term:`numpy` array. +* In Python, the array parameter is a :term:`numpy` array. * In C++, `get_value` is a void function. * Depending on how a model is written, a variable may not be accessible until after the call to :ref:`initialize`. Likewise, the @@ -59,7 +59,7 @@ even if the model uses dimensional variables. The `get_value_ptr` function takes a variable name and returns a reference to a variable. -Unlike the buffer returned from :ref:`get_value`, +Unlike the array parameter returned from :ref:`get_value`, the reference always points to the current values of the variable, even if the model's state has changed. diff --git a/docs/source/bmi.grid_funcs.rst b/docs/source/bmi.grid_funcs.rst index 885082a..98b8958 100644 --- a/docs/source/bmi.grid_funcs.rst +++ b/docs/source/bmi.grid_funcs.rst @@ -49,7 +49,6 @@ is given in the :ref:`model_grids` section. **Implementation notes** -* This function is needed for every :ref:`grid type `. * In C++ and Python, the *type* argument is omitted and the grid type name is returned from the function. @@ -66,7 +65,8 @@ is given in the :ref:`model_grids` section. /* SIDL */ int get_grid_rank(in int grid, out int rank); -Given a :term:`grid identifier`, get the :term:`rank` of that grid as an integer. +Given a :term:`grid identifier`, get the :term:`rank` (the number of +dimensions) of that grid as an integer. A grid's rank determines the length of the return value of many of the following grid functions. diff --git a/docs/source/bmi.implementation.rst b/docs/source/bmi.implementation.rst index 0a51fd4..adc799b 100644 --- a/docs/source/bmi.implementation.rst +++ b/docs/source/bmi.implementation.rst @@ -34,6 +34,11 @@ here are some tips to help when writing a BMI for a model. responsibility to ensure that array information is flattened/redimensionalized in the correct order. +* Recall that models can have mulitple grids. This can be particularly + useful for defining :term:`exchange items ` that + don't vary over the model domain; e.g., a diffusivity -- just define + the variable on a separate :ref:`scalar grid `. + * Avoid using global variables, if possible. This isn't strictly a BMI requirement, but if a model only uses local variables, its BMI will be self-contained. This may allow multiple instances of the model to diff --git a/docs/source/bmi.info_funcs.rst b/docs/source/bmi.info_funcs.rst index 5ceab74..ed50df5 100644 --- a/docs/source/bmi.info_funcs.rst +++ b/docs/source/bmi.info_funcs.rst @@ -43,6 +43,7 @@ but it should be unique to prevent conflicts with other components. The number of variables the model can use from other models implementing a BMI. +Also the number of variables that can be set with :ref:`set_value`. **Implementation notes** @@ -64,6 +65,7 @@ implementing a BMI. The number of variables the model can provide other models implementing a BMI. +Also the number of variables that can be retrieved with :ref:`get_value`. **Implementation notes** @@ -101,7 +103,7 @@ Standard Names do not have to be used within the model. function in a vector, a standard container in the language. * In Python, the argument is omitted and the names are returned from the function in a tuple, a standard container in the language. -* A model may have no input variables. +* A model might have no input variables. [:ref:`info_funcs` | :ref:`basic_model_interface`] diff --git a/docs/source/bmi.time_funcs.rst b/docs/source/bmi.time_funcs.rst index 9ce26a5..51d4d95 100644 --- a/docs/source/bmi.time_funcs.rst +++ b/docs/source/bmi.time_funcs.rst @@ -61,8 +61,9 @@ The end time of the model. **Implementation notes** -* If the model doesn't define an end time, a large number (e.g., - 1.0e6) is typically chosen. +* If the model doesn't define an end time, a large number (e.g., the + largest floating point number supported on a platform) is typically + chosen. * In C++ and Python, the argument is omitted and the time is returned from the function. @@ -87,7 +88,8 @@ It's recommended to use `time unit conventions`_ from Unidata's **Implementation notes** * Avoid using `years` as a unit, if possible, since a year is - difficult to define precisely. + difficult to define precisely. UDUNITS defines a year as 365.2422 + days or 31556926 seconds. * In C++ and Python, the argument is omitted and the units are returned from the function. diff --git a/docs/source/bmi.var_funcs.rst b/docs/source/bmi.var_funcs.rst index 6f42c2d..24c93b8 100644 --- a/docs/source/bmi.var_funcs.rst +++ b/docs/source/bmi.var_funcs.rst @@ -160,6 +160,9 @@ element the variable is defined. Valid return values are: * In C++ and Python, the *location* argument is omitted and the location is returned from the function. +* If the given variable is a scalar (i.e., defined on a :ref:`scalar + grid `), the return from this function is + ignored. [:ref:`var_funcs` | :ref:`basic_model_interface`] diff --git a/docs/source/model_grids.rst b/docs/source/model_grids.rst index c4d422e..53045b5 100644 --- a/docs/source/model_grids.rst +++ b/docs/source/model_grids.rst @@ -33,10 +33,10 @@ its length would be listed first. .. note:: - The grid shape is the number of :term:`nodes ` in the - coordinate directions, not the number of cells or - elements. It is possible for grid values to be - associated with the nodes or with the cells. + The grid shape is the number of rows and columns of :term:`nodes + `, as opposed to other types of element (such as cells or + faces). It is possible for grid values to be associated with the + nodes or with the cells. .. _uniform_rectilinear: From 0b2dc35c00d1e099e9207bd83cf89e2d7ce3b320 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Thu, 16 Jan 2020 14:43:50 -0700 Subject: [PATCH 2/8] Revise the Additional Topics section * Talk about *pymt* instead of the CMF * Moved advice on Standard Names to best practices doc * Added Help section * Added sentence in main body linking to best practices doc --- docs/source/bmi.implementation.rst | 13 +++++ docs/source/bmi.spec.rst | 3 ++ docs/source/csdms.rst | 85 +++++++++++------------------- docs/source/index.rst | 15 ++++++ 4 files changed, 62 insertions(+), 54 deletions(-) diff --git a/docs/source/bmi.implementation.rst b/docs/source/bmi.implementation.rst index adc799b..345f1ae 100644 --- a/docs/source/bmi.implementation.rst +++ b/docs/source/bmi.implementation.rst @@ -25,6 +25,18 @@ here are some tips to help when writing a BMI for a model. the BMI specifies are the names of the functions, their arguments, and their return values. +* :term:`Standard Names` are not required for naming a model's + :term:`exchange items `. However, the use of + standardized names makes it easier for a framework (or a human) to + match input and output variables between models. + +* Don't change the variable names you currently use within your model + to :term:`Standard Names`. Standard Names are too long and + cumbersome to be used within a model code. Instead, you find a + `matching`_ Standard Name for each variable in your model and then + write your BMI functions to accept the Standard Names and map them + to your model's internal names. + * Constructs and features that are natural for the language should be used when implementing a BMI. BMI strives to be developer-friendly. @@ -78,3 +90,4 @@ here are some tips to help when writing a BMI for a model. .. _C++: https://github.com/csdms/bmi-example-cxx .. _Fortran: https://github.com/csdms/bmi-example-fortran .. _Python: https://github.com/csdms/bmi-example-python +.. _matching: https://github.com/csdms/standard_names_registry diff --git a/docs/source/bmi.spec.rst b/docs/source/bmi.spec.rst index 1e53744..9a471cb 100644 --- a/docs/source/bmi.spec.rst +++ b/docs/source/bmi.spec.rst @@ -59,6 +59,9 @@ Following the table is a detailed description of each function, including the function prototype in SIDL, grouped by functional category. +Be sure to check out the collected wisdom of our :ref:`best practices +document ` for tips on implementing a BMI. + .. table:: **Table 2:** Summary of BMI functions. :align: center :widths: 30, 70 diff --git a/docs/source/csdms.rst b/docs/source/csdms.rst index 012d081..11e3a46 100644 --- a/docs/source/csdms.rst +++ b/docs/source/csdms.rst @@ -1,26 +1,24 @@ -.. _cmf: - -The CSDMS Modeling Framework -============================ - -Any model that provides the BMI functions can be easily converted -to a CSDMS plug-and-play component within the CSDMS Modeling -Framework (CMF). This conversion/wrapping process can be done -automatically using the CSDMS Babelizer tool, which generates -bindings for all of the CSDMS supported languages, so that the -model becomes a plug-in for within the CSDMS framework. - -.. - "becomes a plug-in for"? I don't understand. - -Any model that provides the BMI functions should also be -straightforward to ingest as a component into other component-based -modeling frameworks. For example, all model coupling frameworks -use Model Control Functions very similar to those of the BMI, -so providing them helps get a model ready for *plug-and-play* into -any framework. - -Within the CMF, a component automatically gains many +.. _pymt: + +The Python Modeling Toolkit (*pymt*) +==================================== + +Any model that provides the BMI functions can be converted +to a plug-and-play component +that runs in the CSDMS `Python Modeling Toolkit`_ (*pymt*). +This conversion process can be done +automatically with the CSDMS Babelizer tool, which generates +a Python package from any of the CSDMS supported languages +(currently C, C++, Fortran, and Python). +Some additional metadata is also required, +describes such things as: + +* the model author(s), license, description, web page, etc. +* how the model is built and how it can be linked +* template input files +* description of input parameters (description, units, ranges, etc.) + +Within *pymt*, a component automatically gains many new capabilities. This includes the ability to be coupled to other models even if their (1) programming language, (2) variable names, (3) variable units, (4) time-stepping scheme or (5) @@ -28,39 +26,18 @@ computational grid is different. It also gains: * the ability to write output variables to standardized NetCDF files, -* a graphical user interface (GUI), * unit conversion tools, -* time interpolation - - -CSDMS Standard Names --------------------- - -Note that the *name* parameter in many of the BMI functions -refers to a standardized variable name from the -`CSDMS_Standard_Names `_. -These names are not *required* by the BMI to be CSDMS Standard Names, -however, the use of standardized names makes it possible for a -framework (or a human) to more easily match components' input and -output variables. - -.. note: - - Note you **do not** change the variable names that you currently - use within your model. The standard names are too long to be - used within your model code. Instead, you find a matching CSDMS - Standard Name for each variable in your model and then write your - BMI functions to accept the standard names and map them to your - model's internal names. +* time interpolation, +* all the data analysis and visualization tools available in Python, +* the ability to run in a Jupyter Notebook +If you have a model with a BMI, +and would like to componentize it and add it to *pymt*, +please contact us through the `CSDMS Help Desk`_. +We'd be happy (and excited) to help! -Model metadata --------------- -For a model to be incorporated into the CSDMS framework, some additional -metadata is required. This metadata describes such things as: +.. Links: -* The model author(s), license, description, web page, etc. -* How the model is built and how it can be linked -* Template input files -* Description of input parameters (description, units, ranges, etc.) +.. _Python Modeling Toolkit: https://pymt.readthedocs.io +.. _CSDMS Help Desk: https://github.com/csdms/help-desk diff --git a/docs/source/index.rst b/docs/source/index.rst index 64b68e9..4ab6152 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -21,6 +21,16 @@ Additional Topics glossary references +Help +==== + +Adding a BMI to a model can be a daunting task. +If you'd like assistance, +CSDMS can help. +Depending on your need, we can provide advice or consulting services. +Feel free to contact us through the `CSDMS Help Desk`_. + + Project Information =================== @@ -31,3 +41,8 @@ Project Information contributing conduct credits + + +.. Links: + +.. _CSDMS Help Desk: https://github.com/csdms/help-desk From 5fc7766382a0a17b1c41806cdb9debe3ce6d5a8f Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Thu, 30 Jan 2020 15:56:55 -0700 Subject: [PATCH 3/8] Fix incorrect signature on connectivity functions The connectivity functions should take as input a 1d array of the correct size to hold the connectivity list. The array parameter had been listed as output. --- bmi.sidl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bmi.sidl b/bmi.sidl index 9023196..950451a 100644 --- a/bmi.sidl +++ b/bmi.sidl @@ -62,9 +62,9 @@ package csdms version 2.0 { int get_grid_node_count(in int grid, out int count); int get_grid_edge_count(in int grid, out int count); int get_grid_face_count(in int grid, out int count); - int get_grid_edge_nodes(in int grid, out array edge_nodes); - int get_grid_face_edges(in int grid, out array face_edges); - int get_grid_face_nodes(in int grid, out array face_nodes); - int get_grid_nodes_per_face(in int grid, out array nodes_per_face); + int get_grid_edge_nodes(in int grid, in array edge_nodes); + int get_grid_face_edges(in int grid, in array face_edges); + int get_grid_face_nodes(in int grid, in array face_nodes); + int get_grid_nodes_per_face(in int grid, in array nodes_per_face); } } From e1e1ffb7780005e2f9cd67ceb3d27bc31788acf4 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Thu, 30 Jan 2020 15:59:03 -0700 Subject: [PATCH 4/8] Update docs to show correct signature for connectivity functions Also added a more detail to the descriptions for these functions. --- docs/source/bmi.grid_funcs.rst | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docs/source/bmi.grid_funcs.rst b/docs/source/bmi.grid_funcs.rst index 98b8958..ffa39fd 100644 --- a/docs/source/bmi.grid_funcs.rst +++ b/docs/source/bmi.grid_funcs.rst @@ -366,12 +366,13 @@ Get the number of :term:`faces ` in the grid. .. code-block:: java /* SIDL */ - int get_grid_edge_nodes(in int grid, out array edge_nodes); + int get_grid_edge_nodes(in int grid, in array edge_nodes); Get the edge-node connectivity. For each edge, connectivity is given as node at edge tail, followed by -node at edge head. +node at edge head. The total length of the array is +2 * :ref:`get_grid_edge_count`. **Implementation notes** @@ -391,7 +392,7 @@ node at edge head. .. code-block:: java /* SIDL */ - int get_grid_face_edges(in int grid, out array face_edges); + int get_grid_face_edges(in int grid, in array face_edges); Get the face-edge connectivity. @@ -413,12 +414,14 @@ Get the face-edge connectivity. .. code-block:: java /* SIDL */ - int get_grid_face_nodes(in int grid, out array face_nodes); + int get_grid_face_nodes(in int grid, in array face_nodes); Get the face-node connectivity. For each face, the nodes (listed in a counter-clockwise direction) that form the boundary of the face. +For a grid of quadrilaterals, +the total length of the array is 4 * :ref:`get_grid_face_count`. **Implementation notes** @@ -438,10 +441,12 @@ that form the boundary of the face. .. code-block:: java /* SIDL */ - int get_grid_nodes_per_face(in int grid, out array nodes_per_face); + int get_grid_nodes_per_face(in int grid, in array nodes_per_face); Get the number of nodes for each face. +The number of edges per face is equal to the number of nodes per face. + **Implementation notes** * This function is used for describing :ref:`unstructured From d9a51a2b7ef4444915ba383cdcff44b1224c694b Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Tue, 11 Feb 2020 12:16:59 -0700 Subject: [PATCH 5/8] Add section on how to start writing a BMI (#63) * Add section on how to start writing a BMI This was a request from Michael Young (UT-Austin), and it was written by @gregtucker. * Link how to start guide into main text * Use sensible file and link names for getting started and best practices docs * Add getting started and best practices docs to sidebar links * Call out getting started and best practices docs more strongly in main text * Add definition for SIDL to glossary, link --- AUTHORS.rst | 1 + docs/source/_templates/links.html | 6 +- ...lementation.rst => bmi.best_practices.rst} | 2 +- docs/source/bmi.getting_started.rst | 67 +++++++++++++++++++ docs/source/bmi.grid_funcs.rst | 2 +- docs/source/bmi.spec.rst | 15 +++-- docs/source/glossary.rst | 26 ++++++- docs/source/index.rst | 3 +- 8 files changed, 111 insertions(+), 11 deletions(-) rename docs/source/{bmi.implementation.rst => bmi.best_practices.rst} (99%) create mode 100644 docs/source/bmi.getting_started.rst diff --git a/AUTHORS.rst b/AUTHORS.rst index bc1f45d..25c65c3 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -19,6 +19,7 @@ Contributors * Scott Peckham * Mark Piper * Mike Taves +* Greg Tucker If you have contributed to the BMI package and your name is missing, please send an email to the coordinators, or open a pull request diff --git a/docs/source/_templates/links.html b/docs/source/_templates/links.html index 8dedb42..886e334 100644 --- a/docs/source/_templates/links.html +++ b/docs/source/_templates/links.html @@ -1,7 +1,9 @@

Useful Links

diff --git a/docs/source/bmi.implementation.rst b/docs/source/bmi.best_practices.rst similarity index 99% rename from docs/source/bmi.implementation.rst rename to docs/source/bmi.best_practices.rst index 345f1ae..dcf5209 100644 --- a/docs/source/bmi.implementation.rst +++ b/docs/source/bmi.best_practices.rst @@ -1,4 +1,4 @@ -.. _implementation: +.. _best_practices: BMI best practices ================== diff --git a/docs/source/bmi.getting_started.rst b/docs/source/bmi.getting_started.rst new file mode 100644 index 0000000..08fb683 --- /dev/null +++ b/docs/source/bmi.getting_started.rst @@ -0,0 +1,67 @@ +.. _getting_started: + +How to get started +================== + +If you want to add a Basic Model Interface (BMI) to your own model, +here are some tips on getting started. + +1. Take a look at the list of BMI +:ref:`control functions and their descriptions ` +to get an idea of what these functions are meant to do +and how they provide a standard set of controls for your model. + +2. On the theory that it's often easier to start with an example and +modify it, we recommend starting with a copy of +the :ref:`BMI example code`---look for the version +written in the language of your model---to use as a template. +Each link points to a GitHub repository that includes an +example model called "heat", and a corresponding BMI in a file called +"bmi_heat" (so, for example, the Python version is "bmi_heat.py", +the C version is "bmi_heat.c" and "bmi_heat.h", etc.). +You can grab copies by cloning the repository to your local machine +and doing a file copy from there, +or by selecting, copying, and pasting the code directly +into your favorite editor. + +3. Modify each of the BMI functions in the template file so that it works +on your model, rather than on the original "heat" example. Depending +on how your model code is structured, you may need to do some +:term:`refactoring `. +For example, if your model's initialization and main +processing are lumped together in the same body of code, you will need +to divide them into separate functions. Our experience is that codes +that are already modular usually need little or no modification, +whereas codes that are more monolithic tend to require a lot more +refactoring (but that is probably worthwhile anyway for the sake of +the quality and sustainability of the code!). +Each case is a bit different. +Be sure to check out our :ref:`BMI best practices ` document +for tips. +We encourage you to contact us with questions by posting an +issue on the `CSDMS Help Desk`_. + +4. Test it out. Try writing a program or script that initializes your +model with a simple test case using the :ref:`initialize` function, +runs it with the :ref:`update` or :ref:`update_until` functions, +and exchanges data using :ref:`get_value` and :ref:`set_value`. +Run a test to verify that you get the same output from your BMI'd model +that you got from it prior to BMI'ing. +(Note: we recommend writing a :term:`unit test` for each of your +BMI functions; to learn more about unit tests, +check out our `webinar`_). + +5. *(Optional but cool)* With a few additional steps, you can make your +model operate as a :ref:`pymt ` component, +so you can drive it directly from a Python shell, +and write Python scripts to couple it with other models. +(Learn more about *pymt* :ref:`here `, and through its `documentation`_.) +The CSDMS Integration Facility team can provide help and guidance on this +process: just contact us through the `CSDMS Help Desk`_. + + +.. Links: + +.. _CSDMS Help Desk: https://github.com/csdms/help-desk +.. _webinar: https://csdms.colorado.edu/wiki/Presenters-0478 +.. _documentation: https://pymt.readthedocs.io diff --git a/docs/source/bmi.grid_funcs.rst b/docs/source/bmi.grid_funcs.rst index ffa39fd..776f8e9 100644 --- a/docs/source/bmi.grid_funcs.rst +++ b/docs/source/bmi.grid_funcs.rst @@ -20,7 +20,7 @@ on which a constant thermal diffusivity is defined. Not all grid functions are used by each type of grid. However, all BMI grid functions must be implemented. -(See :ref:`model_grids` and :ref:`implementation`.) +(See :ref:`model_grids` and :ref:`best_practices`.) .. _get_grid_type: diff --git a/docs/source/bmi.spec.rst b/docs/source/bmi.spec.rst index 9a471cb..d51fde7 100644 --- a/docs/source/bmi.spec.rst +++ b/docs/source/bmi.spec.rst @@ -22,6 +22,8 @@ The specification for each language is given in Table 1, along with a corresponding example in which the BMI is implemented. +.. _specs_and_examples: + .. table:: **Table 1:** BMI language specifications. :align: center :widths: 20, 25, 25, 30 @@ -35,6 +37,14 @@ in which the BMI is implemented. Python `bmi.py`_ `bmi-python`_ `bmi-example-python`_ ======== ============= ============== ====================== +Along with the examples, +two documents may be particularly helpful when writing a BMI: + +* :ref:`Getting Started Guide ` --- a place to start + if you haven't written a BMI before +* :ref:`BMI Best Practices ` --- our collected wisdom on + implementing a BMI + A complete description of the functions that make up the BMI is given next. @@ -56,12 +66,9 @@ can be grouped into categories: Table 2 lists the individual BMI functions along with a brief description. Following the table is a detailed description of each function, -including the function prototype in SIDL, +including the function prototype in :term:`SIDL`, grouped by functional category. -Be sure to check out the collected wisdom of our :ref:`best practices -document ` for tips on implementing a BMI. - .. table:: **Table 2:** Summary of BMI functions. :align: center :widths: 30, 70 diff --git a/docs/source/glossary.rst b/docs/source/glossary.rst index 01a5632..7142ed9 100644 --- a/docs/source/glossary.rst +++ b/docs/source/glossary.rst @@ -16,12 +16,16 @@ A glossary of terms used with BMI. computing and a package manager. See https://www.anaconda.com/distribution for more information. - Basic Model Interface (BMI) + Basic Model Interface A set a functions that are used to interact with and control a model. See https://bmi.readthedocs.io for more information. - Community Surface Dynamics Modeling System (CSDMS) + BMI + + See :term:`Basic Model Interface`. + + Community Surface Dynamics Modeling System CSDMS is an NSF-funded program that seeks to transform the science and practice of earth-surface dynamics modeling. For @@ -56,6 +60,10 @@ A glossary of terms used with BMI. See :term:`model coupling`. + CSDMS + + See :term:`Community Surface Dynamics Modeling System`. + data Information held by an :term:`object`. @@ -161,8 +169,22 @@ A glossary of terms used with BMI. the external behaviors of the program. Refactoring is often done to clean up code and improve its performance. + Scientific Interface Definition Language + + A specification language for describing software interfaces to + scientific model codes. See :ref:`references`. + + SIDL + + See :term:`Scientific Interface Definition Language`. + Standard Names A semantic mediation technology developed at CSDMS for precisely matching variable names between models. For more information, see https://csdms.colorado.edu/wiki/CSDMS_Standard_Names. + + unit test + + A program that isolates and runs a section (a unit) of source + code to ensure that it produces an expected result. diff --git a/docs/source/index.rst b/docs/source/index.rst index 4ab6152..012a105 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -15,7 +15,8 @@ Additional Topics .. toctree:: :maxdepth: 2 - bmi.implementation + bmi.getting_started + bmi.best_practices model_grids csdms glossary From 69659d75d6e2abe720146d22b848e490083525e9 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Thu, 13 Feb 2020 14:06:38 -0700 Subject: [PATCH 6/8] Update contributor list from language specs and examples --- AUTHORS.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AUTHORS.rst b/AUTHORS.rst index 25c65c3..eeb7e71 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -15,11 +15,14 @@ Contributors * Michael Galloy * Julian Hofer * Eric Hutton +* Eric Morway * Boyana Norris * Scott Peckham * Mark Piper * Mike Taves * Greg Tucker +* Ben van Werkhoven +* Martijn Visser If you have contributed to the BMI package and your name is missing, please send an email to the coordinators, or open a pull request From 2545ecd211ab168debda324844b755c2870c3025 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Fri, 21 Feb 2020 09:28:29 -0700 Subject: [PATCH 7/8] Add explanation of BMI function output for unstructured grids (#64) * Make script to generate figure of unstructured grid * Tweak text locations * Adjust colors and fonts for text labels * Add unstructured grid figure * Note length of returned array * Add glossary to quick links * Add sample output from BMI functions for unstructured grid example --- docs/source/_templates/links.html | 1 + docs/source/bmi.grid_funcs.rst | 7 ++ docs/source/images/mesh_unstructured.png | Bin 0 -> 71392 bytes docs/source/images/visualize_grids.py | 81 +++++++++++++++++++++++ docs/source/model_grids.rst | 76 +++++++++++++++++++++ 5 files changed, 165 insertions(+) create mode 100644 docs/source/images/mesh_unstructured.png create mode 100644 docs/source/images/visualize_grids.py diff --git a/docs/source/_templates/links.html b/docs/source/_templates/links.html index 886e334..685977a 100644 --- a/docs/source/_templates/links.html +++ b/docs/source/_templates/links.html @@ -2,6 +2,7 @@

Useful Links

  • Getting Started Guide
  • BMI Best Practices
  • +
  • Glossary
  • BMI @ GitHub
  • Issue Tracker
  • CSDMS Homepage
  • diff --git a/docs/source/bmi.grid_funcs.rst b/docs/source/bmi.grid_funcs.rst index 776f8e9..fbaa43b 100644 --- a/docs/source/bmi.grid_funcs.rst +++ b/docs/source/bmi.grid_funcs.rst @@ -396,6 +396,9 @@ node at edge head. The total length of the array is Get the face-edge connectivity. +The length of the array returned is the sum of the values of +:ref:`get_grid_nodes_per_face`. + **Implementation notes** * This function is used for describing :ref:`unstructured @@ -422,6 +425,9 @@ For each face, the nodes (listed in a counter-clockwise direction) that form the boundary of the face. For a grid of quadrilaterals, the total length of the array is 4 * :ref:`get_grid_face_count`. +More generally, +the length of the array is the sum of the values of +:ref:`get_grid_nodes_per_face`. **Implementation notes** @@ -445,6 +451,7 @@ the total length of the array is 4 * :ref:`get_grid_face_count`. Get the number of nodes for each face. +The returned array has a length of :ref:`get_grid_face_count`. The number of edges per face is equal to the number of nodes per face. **Implementation notes** diff --git a/docs/source/images/mesh_unstructured.png b/docs/source/images/mesh_unstructured.png new file mode 100644 index 0000000000000000000000000000000000000000..5cbed743f7bca8c3107d9067d66d2a166b1c3468 GIT binary patch literal 71392 zcmeFZc{J5u|2O=hP*D;^8B<6yhs;WnBBTfzGH0G=&MB24Qz-KgWy%m`9*)WoGDT!O zGS9~`9h~XjpVRfdp5J=z>sjkr_h0uPS8JX1J>Pxy@SgYU{oZ>E*SVv9^vIbb5Ck37 zxOx391koWOh$ib0Eoec#G93p0Ip}dslKj$Gw8c*db@>RQkhIM|*kVkf)gKp7;5u%UwTz^{eN= z0ME3woi2M>OTmNdoOsELMtRR8qQlwj(*^qrPE_a%M{8;}vuC>(Qy<|!nElLEGuc%-^q& ziqoN{e|>#^97*-}>yfk2fxq8au0gQ4z`qO6Acnu+bPiFm{r#48oLcPfH#PHwXKoP@#gTr4j{GSAeg?#@5O$$!wMn#!1*Kee@ zo}e`kN$ZY;BR&Tylm1#>Tx>tUsPK`DUChhOI2U~-`zz;F;^C&=XU^4sUeuGeOH2LP zDP4Pe8?jL?GhU?uCcj3JweE-Q{*v`StL|p1ot1cyxAy^um4IYskc~(s7v7Mi-oMtXKtl!G9T0 zdNn2!S3f_Spm(RhPDVv|duz*TSXTDjx7yKZI&cJ?ibl3A9ehc%2WU z|4M_F(0`=x|JGgG^Iijh6Zr)tB{LHN@pN1_gK>3M^WE?2MNwYJW=8o=MQyAj}K2acBNWOZN2U*H$RQWHePxqy*yX@LbB{ zmN9&#ep(x!GWkS(uS((RzywIQ696;WnL0V)EmntZ1#Ht_*H4{nFER`bHu3S<81CU0 z(m!A4tys}$slKsOC7?|B(`X4pE0uUA%0MuaJ8nD&G5+~+`};)x(m-qXx#ae>acxE1 zG`E2A?p62w#fnh@nAm~v0D#JRYfZNcXBse^wT(7fL>x8zixdz1!^p(`;9Ccu2}5!a z+^BLC#$lf;=M`NRMnV_|5!`UA&H-3p#ZE&dZynOpx6v>Y&;SyayaRr(C$!|K%t;E& z(^7#YQ$g%RF_;+FSCjB?N8}mU*zB|dcFrU4RqZ1cAww~87yU*@3x}EE-y`+Ze*xD* z*4APgXAoqWy%pPdG{I)w0|@w+fj}sye)}NY&%7Q+iyfOC2K*)_+KOu!?TkQ);aaKT z8jsx}AbA6m*Y#^&+rt2cLy#r};3jfo%&o0)QvR-O+N+0dYVISCnX4#L$v*)9I=KCn zl|K{zaHG)ReglP+{P4dR_jS#5^vti)JKc&hHN>4l9}2FW<_7}P$q>l+?Sn=?F$3%{ zDyNNk8@q4+YM*M+Fdl7GuJdszx6#_LMZ5`|V*a&82^g&!uuK9uIonr;+Y9peF}~^> z;~4&`v2qL+IWaNwjr)#BV|8s1tdyoJhns--bNlby4&KU{u@+^oCoO7YQYqO7lK(tK zl{PZ1RCgw&(5&w zP$QWr&h6Z?e=>Qyz|e0xMP{zGOU7oj#3^LTC2lKEdDPpfGb+{P$4`euo54Jr*&H-^ zA*tsum<fbuBOGoaD;S~I}=S*ZpxrtxYKjqlA<(t;! z*sAM~edOINNlOgiYOo!chw~2Pb?C*_30xy?7Kb7S#aYe$NIr?7h4NDi^g>Hk$7Bmt z1Gl?NZAcw^!&|$#Zcf(y)2R}OSwi4ycWKn}6_|?8{8Vft^VN}xJsg6JJFlUxuCBCG z7IVM;9F*l;>C9Ox9k3H-M*1a>O7R#5G7E2Dn#gUcEB7&LZC8_`W%su7_( z3T9}^KhzXE6T(d}hZT0dJzO9o>7u* zn$=nmBizuNI2~!lMnR#$(xhIH&;rLl2Id&-?~kV!spbg^!smK-E0YOnese&eM5TSzz_G7xT-@lf78ALsFT%$--~c%_+{p@6+!?ljuC9?-9a z59aPJGHjP=EW>z(y0%1Z6Tg&oBHaBZK29F>QltcsE_EoEZ+mBF?kT;P(rg%E~HoSrGiJtD`MgfmfM?||-Ko^)|0aI_^NRPc~hJebLB^fPEYM&KKQ+oNs1BVnsPIcknU63EzSV(;VK@QOVx; z)y1)oXPttALIWS82MUJ0Hrj{%c82{3X&yg)W?r>_W5nR4sEunY-zgKPiAQd{S0?W5 znJD-4^~aPf`#n+J{2#!`fBg&HhY9L?-Dtbd35|`7^~6;dG?_U_G#LAGGXqzjH)TQv zS^n~AW*YYEmW4kWag`+{p3Wl)?Wr<()34NjPW*aZnUS%jm6_4_?bvPfpU}MdXUyez zzn>H_KnyMCuT52RwIAvZR0jF#qBz+Iy2t0mnEI1Z=W|+WM0l zl2tCwBaOfGah)on#&wrm9<0B(l#aTb$Bpop8wrwUjA}xobwn^O7ZQQQma%QzrT+9f zvYBjsC-(99&2FDYNfQ$jjW}j)1#uz$qI_>XgzHwH`usvpn~x}}yZa70>)O?f;GVaF zdbz#`)et$0C8ps@2V;|-y$3y(ds9wkKUiJx7BF+laZH5Iq%Uvg~iL+gt``3~% zdL0-ZHiT_x^}Y+V^k?ZqX?LyH@{Tg;D{Euy}B8x9Cnzm&S8K+GfcfbLsJqIs02Z zImF>&SC&*YEr;+U{LX4la2ME%i1quwN+-y^YhyK`^)6yi?-_spfO5yK^1x*obV~2$ z=R8Gn*@Ch}v8Bl(x^{*e7@J+2Q< zmswm|?bwQ5lzrT-@i=oVBfdm-@pMcOkvL?F#lCDKKPNotybeR8gq}Q!b%s+S50gkF zQehPpbkC|Di&I%$U6r+8(hcF#cFs(b%nYy@RQl-sd+3rGN`buxePzEZ21${U4u2w& z7D65vkRx&ZD183m*gnB`jYi?F2s6BegY6TTK}K!{R;HaKIB9$LLjYAw0%c(D7|j1} zh<_WJDoTt-;a>)`2gC2!r74%6zIsjH{u*OS2n@74KS+>{*$oIz{t5d6riP+!!?5zb z)HQ-uiscdCD}QBTNl6e4qfQ{`F88ynyEcPGAmkDSRld9N5~Z_g$2_kRApbp$hqvneK%XiY5L%!3xZ6#9$;==5g1*S;#pD1L`81DAWNXzkgV0dJC_`QZPL2 zVsT{G{4WE4C~bMqcIBH`*58Ix1fUJGdf}D^Rz{pg!HB|s?-FGhT_Xag`4L}7%Gj)v zl(BCIc2kq6OK2z#V0RLxT&r{jp3ilaB2blfcx;N1P&2xjW&Juu^vIvEIxZLMhocT? zQfXhJ48HILmXMx(1!Y2kzZ2?HCd@lIje+!s!mMjj$mx5!Oy(R|Az$`C#$$|7;c{fce4;~6- zMlWF*nS`U5J6Xi&C}yd$2a99r2BDZyuPO2wWqxZ|9QpLvs$fkj$-nwfPz6hxe+@@% z+a5_OI{^zfs|H>`^8&W&OfItEuliG98*h5Xg!o{6B+2M+H(8i8%|qBK|6FA91q!v7 zMPLb~FeBJQ1Ddx>JN)U>KsX$U$5!jRak0Bdw8~iXS<`- znpApH6t0%kVcN#PNI=_-v#_d~nqd~$Sg}>INz}Pa6tmW$IF%(oNt#u!>9Pc6s6B-( z&1UqR<&h+tze9h+Y(=K*j@D~Z_5ZbWHcpscT_!|os-SsFGKJnyIA;~Jm~uG{2%)CT z_Cf$|;+=Al1x;tflWutI41?sgnY7;*Q%Jf<1?-Uz^l-g7<>Ci=Tm(JVUz%yIU2ka9 z(3Un@d)a8Grc2JHz50|9pl|BGbz8t3cR4b=HMFYTc3-g2@+RtZF0 zkhej|N8zYh_9SXkeACFIOtZ#dKj{oqS$EyjaDz>@G2+dVaaSk!6P@O6^+x1D$|h;6 z{!&_%80RW!c--D}Gi9c7v=xzt$7r9r#8yjc*XD2IkR-tw^(>{9_To6gI5dE&f5|>5 zdBI6>bfaaoaY3Rla#W3#&%`8Th_uoZ=hN^Zg$PklAW-{pY*j@ytC&KIV#s3_^uGQ^ zm&-9z2N&&|^BZ((BuaN{z*PTgrU<((IYfzW%O!Jg7=rb+ef&{5Wq9wpL>rce%fK7)tiox0c_=jJ==|R$;No?wEgh< zxfs*<$MKr9lG2!9A2tO7l7n^lc-;`o~2E+93QRT-Q@G6$whkUz zgXwmGcoZ4`b{T^}Y&>Nhpjh)TtU7)H(p|<}B zSndGs>@224x2?cTe6-qWW+aK4jgGg=LI(W(tve`?FHB}pCgLOAbpaDeg?*{$M`u3t zee^S+DRIA5h9BhR6b*O4aqse3Y+@lGeUO(nrYEs6fv}(+GGx=u5zGsKT9!U#rgNmb zu$XF_C;R+X%4UAv4lO~fShjm)=#gQME{3DA9q*KAR1=FB4=wiysKCZ3NcgUT8u3e! zLW*ZB!yqW-+3xKeF&YMibT);7C>ee;!qj9%WhE#z$7#e5t{k;nS43)Aw_D(jNop~i_KB;3QMT^+^)V^B9 zXetj%<+@cD0mThBn*`RoWA#FvpFDx0vEmbNq0ezRmp*Oc%(jjv0>oV?rkBU&C7By zwHFL2HEX+*6%i;!#dac2yBmX07GzW$cqNcwr|sioJTek@T5^A*$ab}huovL|^>Bd1 z>Lv9Y2B0=^fQ3Ifn4eKoUn$Ei_f5oY38!DNupQk(EGZo zfB`s-`ru-iKHP6>yGVF%=-pBNce7G@0p!b{f$#%RHtX4`j;&V}7=_ z(vC@K6BCuH8Jp|haC0l4>NYB?R(}ZQt#ILnpqw)MKZR+YT^c>R1dzsMwzP?sOh-e< zC@}Tbq!}n(Gdn6^aozIr9^JBS(Tnx+-kKc-jS`X$gFn94%qzV*Da6&8AV{>7I~Dmx z&^&7x){e?2cSa!h!Uf-v%+ofJ}mdff720KqhUz+st8Ng zW=dU?3gW*hytWsB8&416>PZ_;)Vs6TUhmhCEbpTYj^RWlZMOI{yjSdcDEy6y38RQk z^RbrWftv$?gz26RWnzEM^lqU!fVKztBu<0e^|Bl}4uX=PiZGOhJEkFivpjLNW2(i( zZ?CgX5<$xN%sq8RguELwTJF92IdJm8r_F_&cv?lD)e1@XKDAMgm9hZ!?d_%qHLPMf z6a;2>U4-f=q+K9F3r!zr=-T_wwyd2db0{J>@akP zd-!S=Ep09`vwdT`bGe!w89pu12LzM@M+W=+H&_{sTy2cwhOmI-RpgHmYtf{8!Fqmk4`)V39*A>6< zjr$ns_}+8TmG*Xlx=WXT0Yev4fDJt#P7}-{&&ZN?wm#2tlm6td3~vtbWsQ#FH@`3{ z=??`pf!&|>%4N7Sn<(6w0d$@~Ak@LhlBIjUmL6R(sC;*MX{+gNqse&Z5odBYnMY`@{NF+&PmP>q=_CE44W>`>E5iqX{X zJgNAmgbE~XI4U44(|u@qcWEuwd<_x){yo1oY&&oD%Um^`~+8;cD9BM z#DU3t`Tj=TNl3~nP8n5^uEbmh}|4Niz-DMnK4*J0+Ib40ay(ogag%{&;q*1jtHzrV zYPxzElnCO~UeTFXW&FH5)W}`tmJ85WimD&U}*P&fNXdk=KktcE*FH=rmBo z3_pul+sw>-J?hN9cTjxbC9t)9N!TH0VJ!EeZvpFbMbdU>-i*Bc3RJ>OLI&~p(T(?_ zoThyxlapX4$dZGjasqr{c11<96-@}axT9A?9wyo4BB{=V!1A7j4Ll<^ zc^ZSHq2HMq?wOFca~iGG@LLf_@AoBvSaA6iY?3Ld+Ei2!DGQViCcmG<9WxxQ>8}dD z3}7~>pa3UB&Q0s7K*)rXi1;986kUp31?p*f)AuB5T02U%dzlWHw4LAk7BrA~XQfjJ zs%v>=h1=cG&h9)Q=CAT8wHPC#$H1uvOF@0PvGS_J<~-((y1E+sQzn4jdeh*&#qJW= zfqKhtMWQq|GRd+Y-$%05Oir#Gya8LqCNr!uIG5~=yA_2ZZz_k*=BDNzGXl%?lv``x z`+Sa#6Hq-1`*+qExSu=dr;Hy?03oc0tDH1gwf0@St(q*_^##nA46m5a4O1@|#fIPx zC{koK@w~TIW4nG6lkYR(r zgUyeH%rK{K&p^oPm7@^T5Di}-)M1P|gNUCoK&8Z;UtD(R#5Kw&qVW@3!0r>{wI|X+ zJRgT+|1sry(f-_R+xhMt$I-zIGot-1Q0x~3W%FH^`HbzNhP|JOTpjeLAM-NIjts!X zH}{`X0*cd{Luf?MDQ;ACv^=$W_R;3a|5!#W+lDxIyscz$> zXm9RtDo95Jy-E$WIDj(PdDQ-W5I{}pMm#!&_27?sP(3Tk*Px_+;}3^V8lLpC9t8R! zxIj3cSZbCLHSbciSpwy=!uHqN&6h=m%$D*8J{ZcCaxZ>bVP3WYK-f@ljB*N_$P3&Y z3WsZvO?G=s>QL5$uH!&DBMwzF(eiSe4H&JSo?vOID)dCMN!>A`hrg2((XZRXe{&wu zD1^YWYR}DzqF;L}PpDr7Ht)(44`REkU1K~A6ftlK*du@;dfMaZ@aO#Es+P1J)NGFH-g?aWoH|71(K})5#UoCSRc}{a)=H^I%xF1%_jY$5oDWnQ z`la0ciI9s8!FL-rg?G5v zq*~0tl|Lo|&2_EyLjLNQO9YS>sLZjQI0T))RThd;G2Wr3&61aBuw8GhjdJU8z%|d4 z@tfj1Z_0K+2*{c|j0B4uCtZ`M@TBswY9*YOEuuwQ#4U>Xsycbtt`8XMSq?DXI1Iev z!cA&(h==JJD%PDiEu0k&*`n|(5E*Z^+sU$eg+7YhJ-c(^Zam;eUko}qM7 zZ0;nVX138EVFuTS6(N05c)nvAUX$_NwvplDc|w9+Yr?=++C zsLtr>w$azg(aZ+L7dTF?JZ?{a&CDx`xsmB7PR=TUQvn_iPk=1c)OYFM-v)Br(;5FD z7d?uvu3lV7jRe8|uSBwW2{bD-3@S>)lAxw?O#tTR#X4(PFKGL79N=@Eu!BvIitcd| zb-+*1_Ld25y8yR+VJ1;y-T@A;@xu&d!fjVU8)qNrCk~H|bpV3QGCz!X(!Btb^ZO7G z?spnkh_TO5Di=Me4(Jp;1A?`B39&&Ju6#A)xeo+;lNuIm@_9hYk%)EH1rd`b=zO>s zATQ$t;D|vPgs99UxVqs%l{GW)dSOA;QI=UOzs?* zZsXQ2y;TIz)2&zVbUyHOe&+}@5*lE-_jh33J%fib{}GKn3WjDSgKk-#u;ruy#)g49 zp^+1Sv4m5AiC8^A@F-wHr444H9hRN@ja~Ygr(lJfQDSUzSRVwduKt^31US{lkk3H3 zBH`H&gV}Gxvjl#dNvjyTmRkf`*ew*G3xf8R< zoY$66rk9;Prv94cV@F3=2;&{h1a?}|m>%-{;&LBS83f`Bv|psosIzyjo45Uu$<*0x z@@Bda%JMxNBKR1;!d&M1sPO~XLD>LAwtBwKdf_1OHsp#J{~0LD6_!sVkk9k4rcF?6 z5D+)=D=*+m0*IUC4A5SzJlsZL2I4*q#C_xy;Pg8q(6UM}>?)DKxSneQ70e_8?saB@R3??>d}PyC*~!QCCQ z;!aziIrI-gpY!+_l>AoOfupf+8uY}3>MO8p>i4`Hc`@Q#I&^{-Op?{qOQy)j13-w$eG80 z(T)Pr%YaWoE$X&nYPMgVhUsZXU0E&)>q^};ISTRJ1bMONOF*GFEbA#g27b(oV^O~m zWS~H2F7iXeVQd9%g5B-+qb|;`P^>C72wK*_BoD(TDRC&IJsj-1QxQVEb6qdN33YZZ z|I{yobEbjfQ&BR!m5$-N{h7QX4VSYK8xBsBHg^4yD~4gn^Z2_|)JPAr0?-Mlf*`cb;$7JpE4uy zE%O~vp$A^l%LmN;GB9_ZnrC0Enzt62xOY`>Yp10zO+BIGCH>(Z$*5bc3>z}-)O3P+ z;o#6K2u9q4N9;ZOGSlKzC50i@rMh%$D?$kzaG$fFj}`1hp8=!E5fNdSz`Ru~ znka&+fOO(u%cuk56$CK>dauEzImn3!Y&H$3P^$EN+`RN_uYe922b<^!FunKJfa&ot z@C$Wx@J7q#u3}#cd6>~de0jWR8c1cL*o+&y)z4Jgc&5zHFVEJ_=^Ti$7SiF?{vHg+CF zJ_Xj4sjxGX@01_4_hG(GRfsFX@58(raP6ughr=N*h@Bm_2_N6I;NC^?psB4S3GZ9? z67Y7?*c(yy0glA|u^}pzcC0Zi^xk1-B`noB!k2&z%gx;>JuSvFRrHBh1f^hct?iG> zU7*mr13zgLe1462_w*zwpL>&Dcd6~ZS4pGN6oQl|cj{7pG!6ZJbGF+3G7nqBJa83N zQGR;mlT6!Up3BRL2Kn6@I%tKTA-8RR+aaK+5>G}`A=f0R&mezp?k_Xx#JalXMxI0OQKADLhn-KSyn|x6H z(I@eb%k}1|miunAufI*t#N)zQP4hdhRzR^Ft=HqK@GWG;<{?-3`>&2g8?eXVG zcvPJax;vf8jO^cRtIS^JVBl@vdG3#>&QgT6=;Ue18?6XJ8}j$(0)r8U`W+){%}k|> zq}{e927MqeRW{9zQ=-lRj?G~dA&MIxME=y(V;1+aZ%&bN>f!W$&|HvrBa(ecA^I^` zunrULI~_GRMBGSZI;VbP%-7P{zMJZgsLH2nX!_mlp@5dws8u=?er@!4C}-t4Pzc^< zlk+rSI5WUzT$#`Yh}CMTY09x-^`` z&cqkT+&4&U-nk3SWTMYN7dS!o$|Ph^sU&T#(p+TN^#>y#v~1i(E@`OT#sZaJ`SUC+ z{!WKcK@Hf?cR#@7w6Ge-I0cjO%Toz@m960d&M~??HdaBDJ4zs>UnUQO^%L)s_ z{5E-&)}QQP3W_4D=TgGHgq#zpdAD8jQpBEX_MUFN@~!76$mygz>-tO4o#i@>N>GifWez2aR|w<%Evzyz(G&ebrI%yEMDBhyL++g1Fl|!j&}FAT zRTSY+;wLn_?xUS(S}T4d+A#o~6SLEG-49ZsTRHvE>W%QrY7la2Yq!=A`-@>QK}CK6 z1&Ufp$KBRy6iXSQyF3sr&)zBF2oNESxY?Byra&UMEd`RJ$~JKEDdX2`0kB|qSDM79 z{!I`4?si?i;-CdpFL76My%8L4jZ@tE)@XFjY^T>zDwUE$AupRoUDN}yFPZQdZny1U zOg+k(BSFhUGG>SYU8d!UvX&cueje(sOxjEbvZ{B(52$Pa19OTY645e<6B&iyjyaHU zKO_-~J2UZJh|>zr4|^PbFafI@Iuay0nep49v@(EZXke>Dl@CIKy>JbLcW`@s4uM}~ zbz6ALgb6Tf&evrMp_M}9esr^JUM^L?^q`jzIxp}288xUSqn74**Lj&P>)l>EBUqY* zbBcNY3DccyTX_s=Jg7t_Y%O(&gXNZv_`%E7R;(V+R|@)xxd?W6Rknwd`lZe!T+@N^ zy3$&?DLgu+dh+SY01d<`1_FcCXr=Jfu&puo@~Di(&v$F3+kY6V6nDD&e$oJN(5v{o zp4C;GFe`fBDLRVFBs26Dgp6imPCu^BJx)-c`DzAjs6Y%V<-!ly`hNf3|4pZKT-R`z zSi!ID9DtUWe@Y*_&dQ_syq49qcEUHuKw(pJbd~X#e31y_F9<3)PCNhQZ0L0YHil`) zgjL+hs5y+O04;B$+05G5OECPBNn&wZ|1$i68IpT6K?k*0T4{`0(s9I27~Q|$g(qDa zwM4fWm_^yyh2>xP!Ce4!zQyMxI%({Dnj^$uFmV@nVVq za#fbbu`2~^XfGdBT(ltWhpmpDTUtIx%MivU@lN)<(pGO+!%m0UIP@{}1WDtVipGP+ z`qeUV%b#X0TML6!>m??@(QmAv5c>``;p?nf^Ks>@>rZKZx%DU#M>)uKs8NplPI=b= z5Wd5fW|?zCihKac`v{zZwO4vOjap*-4fdBSd@!|Mi=~NtfaV`J0WABVf4{kfHO8)= zSl6R;6rA6tZr(cy#R|59oD>6)HqY>c|A*Bwl9PPa-NA_lDJd|R1|EEIt^tV-{A7?8 zux48JNVQbIP3U6E6rJ+#<3V`o*#ZfOhaI3;7&ar{jaC+~mMJYZU{}{CR!95IM87>l zLCFS1CQS~5TM^m_f6Rl*qVleq52e9E;P8jjFaHSi{Um^a2_j%iZ`U_N?>zAG0@SlY zn6YG%|LOAtn(rAF%haZ|pC!7lSl$Bxd~_YR(J9j^JMY-83Xp3fNGSjW04QJ4+St%Hg6BC+61&!N$F=qi&=-l!=m?xh#1&*O-{wiScW|(5kK-$|Xogp5V!8)02DGwuU)$08qnd(m<>l;Z@m zz@5m5BWC;WkDJp1^4A6l#SAhF~^gt`&*XH!wlZ-9(zc#Zg-{LVj#{ZwWq00fJ<3{|OICpSk zytUqMbE+UOBf`KeNa_qbyL>|P?I{Py!+)ven~gk zbQ@B^-nz?{){S?8F5HN_bjt|c7-UJ<#ftlHEwEj2HNPw^-D(W>X;7#ovpWoxj0cUE znAAuxQv&$tzY6utTiYN>&xjkS{m6KYGusa zf8W z>A-YW$gzm{J92{23LD?A%*3i@*VosNJ7flKv{x?`ewgZ0=XUZU)S-#afwMwp?P@ig z{@^nEbgb&JVdDO z3UB!Y4FQkFMS+7*-+{qOl1XJ@p6}qfQDxq%BM&O<@7H5n z*~>r~_;+Jaz`(CxYN%kMMH7-r+^#nZ=GAg*p-*>ClzVPoMhBY`62Man=LTH|N5@Fe zMTSH~lY?+&S3_u9z;#!UQBDkB5a**dUwGj(%1e7J^0!A1CYZ=8?G&-Fb`wWK&l@dQ zxLu|lba5&XrRf(w{L-dPz!o8KCRGj{qG0mX?7~AOl{;_tTleqOAzkEmDvP|R$TI>5 zrt8q0C$zMRzmP%TPH);;5t6sJnG(&EE;&~}vP)g}8LQr} zCX=MTnnnB+t{OW5-z%S9|Hc?23Iy#oWa87Z2{4fRE<011b?2KT85h%sAhC2C&{b~% zSEboW6P!HCMy=P$3+I$0Y?byj$M#P%J z3cyt3Ca9dc0obc>BNH7gR(?k-AAEkz8)hk6?WIJesg{-&cziJHwli$oHdt&dSt$aI zC&q|fF~*=$vjw|Tg7oVjZo1zXqCq+yhg6TeIL0}$wEafdc;nvT*f-jU+SM|7Hgy6L zRDURc7Xafp(Jyl!*eOUsi(@#0eVeP@1jm)U1_z3~NH?x;6|V?^J+kbf7Zqy9NG;8K zB;R+bU`cwuTh8J3nAcD(+vN)Z%9dFV6iK_&Zr!r;zGPY*9`}>9_QW!ecR6!*KJl)vEQDL?_#KU&XteT5N6_k0ng2`*xML1PEL3&)iRst63OnIf7n>} zT3bfITFvepIG4gmK)#`lFTMz&O_TrF8yjPHBC5Sf6^22y&{hIa+DFgDpMaMnR9+chi-P>H>gnb?vi5aQ5xNDP~O*V#vsu9ze#xYz&S}l#r;t2S^lI3kG^zS zzhe;Mb(hFwz}h1BeA*`i$B}^#zpzR{XDsJ_Y{L*BuR)q69vFU0wcGU6$8X18f|sFU zg@uK+USvhw7;}#z?%|ul16g?zoV4>_qqN79FejiaJ>d2rHFU7p-&!n#BY#`B!sZV) zd2dHj1ocmkuZNlPGDh|vn3yz|wcP*@MOM*zX51hFW@0rN*ct1RQNJi`fD^72l^$}s zlQX$CdKbmVWr}sZlR?vDW}QR7`-1&NvjIv@VQIP3h?85k{48l&c@R$CFgqzan#Yt0 z>$@XEji(ru39bM&Bf|YQ=UTvaGY!9i0vjZ~+h&(c9-*ZpHN>()T~^1}E61uWP2Tl=*v&dVr#ihYCndt~)t3cZ#YLrdXLuQ4>2Oi2b}U zV`q)USLzdPRtjbN;asOOYE{)a&fwAm&AKz_-jy^qD%soHd!x9d9Ut6F8Bb-K?~)gt zD@hssvu8aoa@()?*N1?XP-Q}icTdzAa36~f=crxBeCPKmR`b-2fTIpn*<}=}kZDuwhmq>Xo^!n~E=H=9np}+JiHa5N$ z``@9HG@7sF6`u2S41$CWOr-ieT{EBYQk7BB6Ss^4A{Td?YF5xcSYz-CL(P*Z0?tsY z7jskZ*6#eajEOS*WHYNspz$}~T@RD>;Ek3Su~;1$oF@_H=MW~cpt8rV$G!d8>RX)i zsbR^|Mxyib922LBfDbeSvB#M?0PjMT+h{QmYbtE6prq-Bhvw6xR6z+#0D~BI93JWgCG&-^f_Z5tSRcAx)l7XeLgzicJ(udz3MQ-b>Jcif z|GBi?oi3kKQX&#>ebs#xg=n^nQJa;WzrOdBMi4!C&+v2|s495}tvWCrJ=#UC?FD!+ z)!UQw$ST)qqDFRUY00xng~}dePOYu2`lT9grg4f&TtUP>@18EW?i6hE_||g$`nA#$ z(WNK2MjwZPp&{Gt)9+h{e0qKW_rhJ7Un3ztnW2K+fWF##f_FZNl$wA?)(l(eJUI~IIqkt4_pL5{RHkZZ~TZ|#Ms*BUKXt~&#s?ry2W)gN4fwa z%&y!i9X|}5t?z?@cZibv@<>SOsu&a94wmminPVc8nf?gxzloVzuZXK7`o zY@F3ww7B^D{7r~TjBj-rRKp&E7j|`KLxY1i!1^$1SVNIX@Ky^%-R6S8kM6FzAlP9G z81wAcnpnAdBH?w*oA^5s!UE|m4fgig`_Eak?YEaMplhX4E?%@4n*37cLDf`w4cyGpeD-oID5%IWf^7Tp%LAqn}GkxSF1p2r?S$ zvs_$t!^z1Bl&d&vL{5IsHUYU*C2%%Pl+!ZEJ-!L$=DMh%>lIj$VJ;11W9%PwrLjMI z%8h$%3AM;41Mh$S>8k>2^FarB=p2RiVoPyo;>G=0KzHv+DlyL~c-g(p`8E(ld}7Xn zSA@Z*^3vRIrTH%voc3!?Y}|UEq!i>|wdMz~!xVGoZu8nu&W)%Dx9L{vcU(LkAomF` zM<>jBGI$y$v^>*gUb%XZCjaf*v(nCE)%fk$v#QzIUrVPo28Knb?auSt|x+ z+}#J)K3UBIv1^uS@W4#+6cocDTi%A(xqtt@8fKzF@-AbnA)NKJaP>0K z-^bynh;>%Fl`J(6xrF^xhss35yVQoG0cFsMNx90-0R~X}b?G%10puDu$VuJ?FZNpD?Sr0GWM!*1A|j$1q*BwC z-1rC47Z30l9}(V-3S*PB(|jm7n*#PeC>=mTRxtha{&J~{*Ge<9b|m0c;r>CE95|8c z=q%r~tWxNhE-CP_wswO2Z?KA4wZ>~JorZT|@SwC1$mYWb0JxGtfrED_e$waqcG!iU zpKTMf*0b2}!!cH1)c5lsWKF*@b`Fy+G9;_m))>Gn-18X$&h^Bd(R5Q8u-RAR*Xk^n z1`1>g8IYRG8td|fn0(*4_?~8R;09t!T`xG{H4cqS^V6;m_+2MiD*{=CfC>Z%G(OF{ z*y(8x@Mi-6hC_ve2Z^4(AO<-RHWE>hAQx_d--uSofoJfxZSY_Dn6-a$UJfK!Qxl6g zno^=mPc$^PC-tK)GxNcRmLtXfNZkfYh%NUUY2dqQGhy8eyx;*oDS&w zJI#YA`drblx4%@+@lL%H7icNgbMAT|;Ob}SHzrS~UGI-eDqK(+^SGafV ze9LLNOs3l+4^I5e(n}ZmjI{bdvF!r2ut}4LL6;Mb5V{_rGACD2IqMu(8) z&dRWfsl4CD45*%uT6~W^E1M7GYET5n$lo@jo!$2Wfc8gH1m1c&5EWdUJ$B-E!2;RM? zT3$|9fci4{e?{;= zR6|7si|;AM=VTZ17B=es`a`U3g(5;k%ooP!MeC27?S5qiCF|{UQ-k~WPolx=_NmYP zcRE4r*}7LE7mQx~^O{lJQqQt(o=bTiYxnzi?-J1`6C4HfJp z3)o-zo2aY5hI*O7dH%{4u!n?fc}%?|{I?85zM)~?2*QmEz(!ufwLO;6-Kwmu?CYQK z`gH|(#}ubRCkC-lfx8OrS@dipwQIG@cWa&ZHfG%j*tR@k+Dp;KD=^sqjG@bN*jw8j z*R!3@%+pTGcx4Nzy!{ETzpH^$WEBZ;%>|0fJq|=w@Cn-!zmt(rHV>(s1s6?JUfC^D zuYCu8<^JF(vEj zM}m#n$P5tE$vqJWT4)4!%+-I%6v`3wZ<20Cluc9GRU|ppWt8SvXa4tn24l*Xq~zH^C|ieVA@<8X4>MP6=LZ%z(x)8fZ&5@ zk-Xqu2+wJ7QV0#l&HPg-ybL3fCs>b8_0t|5P!w0dExcHC`thG5TJ#UyGMi1MIvaCJK&Ik=PX$CJn$BX=l**RLZuk#G`J50 z^!60!{U$9K1a^89!WwAjGfe2gf2(unP_VHi+#6gHLO%O<^QoukozsBIRd6*%Lh+Nc z|I9KIIw^yIX&HcNY5s?n*#AY>d&hJAz5nA6qCpvzlwDFGR6=A`B4lP|7s^&4n`c8x zp_HtUm6e&jo_Yzrl58@cM#$cKeXsLS@9+Eb{e6Cabh~w{=Q)q-T<1F1ykF;>e@I$G zY*9z+-y8dPp$oe_sUIOhl|Zyy_&bZKPfuP3qNNMqV}!i`cEjaP`WF2B^?!b@_V?#= z?|Sm?puOnAXOI8;^A!rBcP(P0B%F^or~dM*P;N?39ML#|wrZ4mxrna9A|IAFUpH~rc%e3gPQv$4n@vI%kf){cdv#s5G5 zym#&Gb|e(w>|)Zqe|aK*WQmUzNpmd%6>0qy+d%0lJy*2$NJNUw-~HLo``K>z4D639 z62xpoAv)-)))d6}8sOm9-LUpLga|}>nsAe2i3{n@ulxVUKVLkyWQO#V^eqH0qxpL# z_A`AJm^6iTn)-tX{eJmJgruYC)*9#$2kjB%34ckPk)Kl3MkIa*LBt~d9-*&0J_{tF zlYd4LNOS<`Abuz~v?+)VK4^Qc1GnBIfFG`~+m0=9;p@MJ*8k@3LQNm_1Un#62?bHX z)B#zDFZ8ASLnGI3Xhq_%qL*j>E;MrQS|B%C(I7s{-xb9vPAMKkv$Ux}J_;lBodHvr zxFW0RGc@$^-M&UymFgRpUwR1%31vD@_o3p6b$2oHKo5DW%so4N>B*On((#cSs{YO`xD^&IuCov%_}cQ1rq+qXh%R|d_0v*$SRhsKl_u&U8P?U%K)F_?NSp2E z2}s(^u}(A5G^%^)P;x?P#|k^o*>LCK_~4kNq@;2yUS8gQlwj?L4oPJ|s-ObUjrh9K zxBNW?DTBFgU~#Y`6hzZt#64D7>1|jS;Di;fgX7u>Ui01Wr>nleMNcI`_S zD0Ft84JW-AZcM0(4Ui0rwT!k$@Lx_@iPtuWO-Nf4Y(FuciXW*FA-xc+6&LheDrc`; zfV#A~%sJ{bVDkn{05 zUf|<@c_&(`^;H0*Azp4uQ4-&AFfdrd2kH>@sRl)X3InIE<^jjX4@%EbE(6_00|l7X zez;HSY1^mURgZV=D=c1wFfIV1+pBM=fzI8kVid&vF0Y0+thUhf<_J9rz_sHJhTR7p{fs5?L$>E69- z>L2m7An`jC4{J$GN*bOC(9 zK|J~lZN46CK1aU;Tqgk0-5F0Cr0Enr=h{mi@>d)F|&mpF|s81fPsRpL9c?w1Q85 z-(n>|29$ufbXLSFtBYx%Zoi6u7Kq1}}NCTxBbDCmZi47mD}B{&fb zKtw3#Qv4gV@?{*F4PI-7B^3V+3_n58{B)T= zNe2#S{@6fyHIqro(;eC%5~@cHA$9ns#cg>YxTtur2hi6Rd|!9Khlc6b)W4zCt|2+R zo&c*w@zd*Lj_c7)5OIJU;z}Wm)^q9+$l)^Lw&O!11$^mJXz8P{^pF1MC-V8zL#4bt zgIiHe7!Q9PtJuBV6&x>=0tcyGbJDi-#EO!I`&EBYLxA6whGAY5PBHJkbm+^8;5Nx$SE>TZ4;2Fn^=b8 z^Or39;DLOe-<@vVvyn@kLz0Y6U5=o@Y9h{y4Az7*#>xfwe}1&1sy)Zb1n&Cdmgt8x zm_H<>K@Exm4s8n#yXr}Ev@Ot2v4P5iGwcy*ht$UVy5KL!Q=CzR(C{U65^&3E!~K#h z&OHwd3|pb#Q5`H0;7!f=fn~!J@}ItN^Hyd8*To-Tn-yw!^$efwa#E?ArZzyX!VL1l ze!VGyIhvcB?;_w0s?lSL6dd6%?yi4)> z@r^@X!aX>I73NKeYIjK$EcvBfd0M6y`@?r(3%y z@;?V#f|&cGv=cwH{r_%EP|>w|aq#q!w4#Z^r3oh@Gw1;@hWDUf_+k?faDD+bg(&oaCcn5-8Qq}3f#IR#KattgluIcgSI~Xr`xsuN!Jnv->ZM! zV^9XrW6$UzBnJPe;(kg4z>xnx?t{9B`_dGE2dVquzP+b=n1um|{QTzpNHdfq2Y(jW z-$pf?y68(L-$PELG90)OFF?__2k$x5`d{0)zmSVLIF4aO_UsNKt>@b3H5eFvKkdx@J!ye2hn4d0(a3cfg0!sEV%M{GZR z{-3hkK*o_PwNt(2{UIj)!*gMf6l2lcRv-c(fsj)v{kG1e+6Nckr1UH{YxDMN6Gzws z#2ZB33Z#$CwI?Tka3-ye^gZ5}Tg9DV{rnZDQ@keoFBEU6o_j%nzLZMvKK?ZpFn%90 zXWBH|?E$)|Y1S%T^NU+g>=O*z!UDJq`MpTGw)hM#s!+wT(mx{1riY}ot3-&RXD130 zyz)jLxg+11$_E^aue^W4@CO%B;?;Ei>rz)H@wt>|Ux2}OqLLDQUbol@Wibm<$oV|G zvqJH$^UhxnpKmOrovA>(&4S!87c&9KB4j{^bfW8-5tqqQx2gyq(xFEw+Y=nt7sk!* z{>#PL_eyRhSG1MrW#T^d=zO2u#s~fnjzf#NdsL5gkO4oV7}X9{mU~) zi{{<91GFFSqHzMp?aFo_*8Au_w>6sILL5*IRxi9=<(~!FDA~$=DsvW&?%zXJ@~8e$ zy8Dg0BPQ!PcO3#Wrh7I^K{?M8bp2|qLo^+db?=Iu<`~B$9Hp1LVPdKaDzXv*keVEj z@LX(a+JCp#n-f|_097^!aOT$j7lMT}UYtj|=hL3#k7X$VJUiVf&*3XC7|Hh;NDdyt zuHY&&4w zS(%f%8iz!>np^{VR6Oq~uJudVDqBgM5JvW*7wJ_>&~bPWaqlqcvz^TB?;+lF7PdWm zyvFaah@?rT74heIJUYA!KR`%>Q$6_;x|m)&3>5)3*F-zYFqUTzWF*yS`xc zw49bie>|#K;+S%0Xb#iiaGVRsC!tdQU(5hjm=aIzJds>59tkmwxk~g7=tbzr4XP-1 z@z7-r7t0Y&P6@x+RcLs(e9xsmsm)JDXN7Y1l(nR$Jaru9=?lG`4CRW?cgHe2`k6_I z&pZ~|f||n)H{u^P1CXui%fF(fu9+Ac*&*oV8I_n~wVv62x~i!%-K$H$|GX^;eD96% zC&cmeW)aDaX%9d^yWNh}_{xOD3U8NsX!=L2>Vi;u4xn@%dL{h4R=&Z8$uFw;nb|t> z@;35QohB=P+7VX{p3jwBnX@43&7|hJRv2)B3_l^Zux{UvKk=B84)|>%Re}-7sKz)(A|Ob|tIRM}WOp7fnv;+06rL z{@-;k>NphTov;RN|K9jdoLLs>D+;9{ouXXrkA?0Mj%f5W2<8<9<>!Lym|5paIVN)n1dH5&ic*)|5C1j*) zL^`%-BMAi{uwq^-lSo==O(vh7yS`j6(!jotNGG5L6wVQf>Mz~nf}HJii=NH4o}_De za->qFF2fWfV(#MHMAy0_2cBf;gQf$_7g`7LwC%swcs|=bhYJ(#pJTiG#Xq~Hy|`dp z&c56yA=l^BmgQhUoT&ek9y@$Ufp5u1O}kYXV-x%^equ-?TSVD)bG=cIIt%4ZPOzbs zoBzo^sCFs{!LJRv?#s;9MUMx38UF_D7DY9g@~=l4bpLxq;@=VO3b2IJ=Bgc-wRYIG z@XaY7$yCE&0C&~PwSLGuXc~$(M;wu)_9wd;?F{;|!)@}3aFwvN`T1`JyaJ^<3@Vas zVpybj0slfrEnC@sHpJk3q-bOQ8yS!&5siw=3cOQJZUn z*`p7wasJ{Bqhfz@Ec+odI^=)urd+tmB8f!QvjQAb88kt)bP>H~MI28%jx4Y>Z*Rlp zj}gh=n?Le*f(3G?(A`5P$5QVa)y<`t+&58ljrxJt#w^)%*JSR*M(RgvUpo)0OCd3e zhw%>wfNA|t>ibtzPu?mN7{-OG(n{{@tW|kAu#l%4k$CwFOr7=J#xu+eBs_|04(UR^xY3 z0t8R!P=*Qx2nFYi8*M4V(rwl?~s^W z6*Ya^BO;hq>S}V*$Pn7MNtd6yLL*a2Q86(lh8ymM7O7+;=8NiaT@1iy{TIyd`@}XR z_@F4;Za3NAnxE*}@6=tuFF6~^r>51?lph5gR971`T__QyYgbQs@uayPIGXQop@a0<>NZ~H%BfXj(K>NS%=ft%tl95 znsN7$T!!_6iR7nWb?@7pu)46Ho}SW?^37!m8I6-1d>W_e^e>q|pty2|dv>+oeVb@# zsOhaU^WRq;4GQMO6U0?wUYbrUyR#(|$jX=!$+wGNnxf`VHHW>HHbq_o_Vxn9DNJXZ zW|{Q(PERrlrtv5;?5Q=Z7b{bT-(yzqsSe(eg+T}LLBF;JUHmhs>@)=td-!aj7QX#al?y7XtzQ!N;D(HjlY*#_LfGLHTsPxkELB}zKWY_IKD z851Y~jKHM^<*F8GhEp+Qp9KhaF09_hu#XRbb(qcp%`(h*j|N$JG7$cFU%S*c%$OA? zJnJvvT4=Q_^}udy6sc0|t?VBfGRPkqVZASK8g}3`oc&9~QBI&?0ufHgK`}U19ZPi( zKFVV(!vup~J;Vp0HdZV{{O_PR4j5$de+Ll~fo7bqJE8i69ic~j%|Hqlqht6>UhmT$ zM(Lxm>w*~8atTfz7PI}&nmG08*2pu+@ij@HHE~#~{$a#LzaB<{W*u6S73x;S)Vz6& zv5f7>1bQm?(#Iz_dHWD~PkH`shVhXlN@Go&uVIL<(oNBS)@y)QprAY1h zAHsY2fUoubIN{7V;g)|0-wp99Ifl#Rc6_$vzq47w)?!sS8%DQg3-~je+CEs(xvdo; zeTK!b{UI)v3jQZw7RgWyE_ejA6DjYh&K1(HkxP%`!s>tv3LP54pg|^g97vnmjZ;8_ zD8M#-{(L7Ea{ibzPPGgz+E~KoUkPsk*~hwZ66zlzVSUf^M^JK)q4`+x`PlIJn*VHU zMh+}hdL6BZ@cSa7TNO?vF5z;LXb>%8DxCq^KFktMB@)S=ufSAn<1)S^TqFt9e^|$I z9d@E@6JOIDN?KueK!kBY;oJt4Q_$cRRfF=AzV{!mUM1=2;w zf@Fw83E{Sz28ecbN3!QnlC{--#C{@Ag4JWAxc!3U?iZjyl;lC*N+RKm;qR}^HY&QJQfJTAq0j{g^t&hL|{mOj-) z6^KXW990x8zxS}1XL4=Ds<_*gS7~-gL__V>sO+gd%vvLT&jWrx*g@s6HqCIs@Gy4n zIVo33zWOcqa?#|QrTze4zLOv4SH5lEqtTEafO@iA`3`hrc{qkP!`+h6>r~TnR-aDVPv;g3NN2uz0qd-)ydLurm|)-f>oy5 zV)8V#fHUhx%bN_d=l(?ty79{4x0r4V^sJZ!7-2i@aPAeV0UiSD@xB79BT8O?-m#{Q z^&f6G7A6d0?0;};b>t3Yb=Z9Sp zzK`KzY4{Y?KILcOnVa`ss1`4QvG{x`G;#tQO*~+)>o3& zzU<@5WX#Bev&V4{*G_fd7hq+IpVFfYMwh({s2^qTZ5_MM&70!AFd^ha+_r8{%e(%h1>R|h<%9&G63t9oC*p5sFd+|QVB zNu(>T7-+bx8#er=##S3>Ipe1!X?HI*fO?)Z)JxE+#pqnn`NwdbQM`Y`jf}W-vk)%N zJ?l3=q8YYrOF%hp5iRo!uF|jI43^y0%G1-?c}^*`;p^F!L^bbYD&47H zWJE-oq2J~P*U^wieNmn>Q@60GN8e=qG}_aRN+R#VMVn?)%chMXsWBJ-RSXWROe7Zu z8%+3$YibT$H!L01PazmNA2u*E8+4lAoKL5;?CzX@E}a(lL98k1b%D~{TfSXcMH4K0 zup22$#k21!`|eMiWxYme4Tc$<7^Hw+;%sm~V5?acE>bo6sg^0Mvd|%ObY+y*W&I-! z>-SYGIH+xIb@J}KE;~k{=Q7%&Y?A4=aL(_tJ;NzbnL0a=ij!u*&mp_F9s_i;e@Mw{ zSc~}~vB;wOf>vre{)3qIZbpXbSWd#%o4ow@ne2~piTYhO*&0u~HQulSv}dBvoh0&Z zqLl3O145_#Se^6>w$q6BHO}tc$Es`s%sisB<_~{ks0lAB7S>HB>;i3Gi0@|d6b~DQ zNlQFdWSD}(qG@QGw!tdC^zx>Ohnt~AlD%8LFBK`05<9GBnD$G6=)ja4bw8}SI@OT! zDxB~ZoU5v=$j(Yjcwb_;Q&Zx_HSEhvv$|FsxOa&0X<*>Hl!s&-`a(L{SMCZetfpR3 z(Uwm)w4Kbni7!KD2eL$j5uBYP+)bKg#7(vo&6K@LCJ|z7&6y^lwY8l@Qh~!cE^q9h zv}s1r+vMp_wPJqkg%e`j{6EG$w35k>!3O`ni0sxDDFpV%SyW4->C9hyPic?Q98}d$ zzdbl~en%OfZrwH}Y11oS3!ou?g;eq|2{n9HiybKzX-Gj#;aI_sS(6MhnLRtAKay_@ zC&(mZmU<|T%zu~KIHmoyqUwB8HaFQR!c=R|bAcxF5sifDhjMIcW{n>lyV;X8%aA21 z!Fg+myHr!JRW->rXP(<*ohjN$wYAmN&o$LvEmr~9_2jkPQljKL?RSl~rnLRcRPOiL zLDLld`H_UD@=;B)ec-KZ&C_Ql4$4|;*JWH;k9S(6wb<0h==(7jrD0QFKv2`V+-SlTU?bmVsepB~Q?p7XS@FAof zab1{(yR}Pd87YL>nZ9?G{!*pIhP41{JDQN$T{4=N07NN#?=G=)spj(~6*QhTtp6B# zzhp6z$6u;DVd#k-E(T=`NDMITcSffvVq`8~_V!$#*S7hYaRHt$@u6W8PyF&lM##2P z2O!QG>4qgu88^yR1@>Wd4{kwg!mfSqI!l?Wscgchr?s?Je96aJ zx1?R4tTWrf`^=d!NvVApIoF5x(y6uumv?pKhF0>1ovlwhB&gxp_iWyE+102JaZ^pJ9-?ZxPZlamQj9c!W0 zv)2`~-Uyzo60m0#`?VIM{Q6kwjxxpIW7W1IQnOjrG`uaMx3?2s`ieTM^4XPW?g|$P zujFlL%&}T=2y(p3-szg0Oyykv<1&A3Q7ZYy=OwvE`P&QU=TuJR4DD1bKiPQBgav2gbZ7HLCUOG;iL|wJ1Kqr?fm-nv!MPwI-}>;6~Ou zcx9QsByzn_?CR+I@B^K{>Ls#Ww`0z}$O$Wh<{%kA06gcj*foCegO`HDy8uI5xX^CZ z94kj#@g-!_98m8n>#K{c(BbkhQv)MVQdkM}gd7~o5IOug4|A@KJm@j6xvf!Wv}ItV zIi)FKh)kN}r>}35=iy}ctKwnHZ1 z(!l3w#0^(bmQrm^GAu^%R5Ib(wFte^X6xRuq)@?Ynp(F?7sIS*p0)a8kEuJNFIkFO zhwN?rc-l|lh&?P>9y|m<>Bo{Sw{Ar;r)&4W7E_aZtfEIFq9=WR{AktDxn}QK}XA3 zcz{x@oHQaEz?KT#1}$fWJysmN1omLYHy)&sPt-+sTAVyywYs>Z6!|Xg(GC+O6HZwc z4cEfaWO8ihv5r@qmM$GO3c3XiXARrlKbT2S)=XlQ>UT3~+k9*Bt&*F}C0C$VfPn}v zx#9a{OHr11O;+{^$`C(U5o z*H6e!WvW`>nW2P9f2Ffh=*_eZo6h`;c_ig|0Ycp;2F8?%sLhXYQJ!b~w2vL<-Av8X zXircn8!TN<>DablZHI!zWIT9DgkVTK%ew6hg4m1oKHfL?l{3H`-s6cjRIi&$tXD|O z&)3;O!?Ls962o4dc&S1<+-R@&7weoiB% zt<(Zz^DcZ?597dq<>^~5m`)m4GNoO;+BDH>r2TK(?Hvv)&!m)g|DNrF%nsIs2Qp>* zBImcuXsj*|MdesF^C(4%Lyu%lLvOiH!1m9;Drn7X0{p>;>HaEc6-iUq(t3+7dZ0^h z_qtUpOf)8?XbV()nd;sJxApzMDmmeHLcHckx))zvIc+%U{aHs#PCmmCIn9agb7 zNyVKXBF^{E4FvDWzH9QZ(Y`&0x3R-+h?lQso>~E;JGp15=Gr6VGC3VRmi%v{ilU0t z`0OXeBB$2U+mT80VTbf?Ev>m5r54}diWb1$E92%gk^_4p=ejVK1kY&wh8r^KvMn0t z;NAyw0L=%!NH+E!8RFA{2*8ULR>{9b;hI2lwTu-=drx!dy7=v8lDZoY+2Zn_u zpEjv9htfGjJ$CbOv4>jf3lGXb}H1L z^^6#r(QgSnX;a|x9BwyV85ZX{F4Fov)Nx0tW?&$X&^^-!6UFw#zP?|%W@kszi;MLE z!SKNZOAFH0X!3X!z_U47lVUqW^Epb%hlPiqUrV2b7_+VS$s}p#@u(s9iQM&B&4~2A zMLB`#RS{!@`$ZB>ir7Ve5`XWfPqmVIx1&6A4Lz65lp@45?MjzF0M3bLSV!}Yy!^8d zDp6^G%SmxtoM4i0&4zZe7{CBMah`Wv1yIb~H{SG+%1GA{ZXt_4lGC6Hh^z{{8(0$g zDmXYn){kk~;xcwI3Frlta>{S|W=77{vD5W7*h%>)>ou8my}8BZ<;BiVDnpUs$s#22 z3sx<0$yp7K4ALoD@r6r$C563D3@qETukN5-5$6)uP*aQU>+6fHg2RxRnR!^Bp04yJ z4J*~pPu11mvh7HcaEUX^Pr8f(t69t5mtK$^!S4kq_h)ywxAO1dP-cRg`=;!<&?1|( z>gil=o95qFI0t?$<;Gvl?pw4gLwLfAB@`ULmi(W%S~bKygQ9#2^g@92l{UbQ-FASI z(FSe(A-N~Vs&xd+ebXaa$wWQyzd(nGf#SGS?Ai*DoY?3~K4Fz-1O*)dyz<2SGKQr* z4S3eNoLbu&DD^g9d~?%t*=uEEZ>vq0I5-NgAQ*hVZAV}BEv4jzaYfY|H$Lv&$J_kz zdT618=tn@A$@rYZdM#_;UuYLJSG_VQX)L9>c$qANR4R3JmK-~B=|PD!?_#Qh%S7Nl zemwbj>e;S&a$`PtF*F)bn5mte`hM(EhHwo?PSYWJ4qAd17Sl)_c@M6YD?nhDZZLrs6Np$>PaO&#HyjLhX=tn#GM0V-FPRvX z`)o#s+qTC)7wAs7KMv=pEMktLw&VBewbv9VRg%BxxY3&YW^|!8n8i!}r8fA*|3uWN zNknX0``&xUd}D2yN$}PSz}Q+a1v{Kog_lhWDqkFm1=NiSH#hg;>nWyVRd5NykY)8- zlU0FS%Vq_*DCpYIkBDu;2?B1|CNv+3xfb87po)M)vth_YpgRF)%hq^U`^; zotHpN@(-3e=a+WOM>H-y8$Ql+o;N&(l6?vtAMj(e;2sr!HbC1M9y)Xg$)Wq&7heMR zi4%3uMiVR2?OeWpL!oM6=i3*joEIm$Tp@-4wInbKU0f~5&zYN_AQ6qA#pxCInoY~c z&;xwB`!lAr19h{_qv7vOqlb3w+OiS#w%^{ZrLM02 zQrnbuZDWtlwTll|TlEO$7pTpbx}f7X0i-q=T2hgAgEzU|=iZg~zAW!mMXrk2=*eqb z8Rflo@aU$H=~p@lxFO_%!7M<mU^|~K{d6{{AE3$` z`t;V6@~#j>#Y|s>GUnVd!q*v6=Vo$4Z{hmv{GrwzE8*Fa8pzh^mnml=g_j8 zQ-#M}#l_yfeft57dY#rGj84^ldu`JE+CQD%7j$=F?+XtbJfUzb)l)9yN}MIbj#LkI zNI8jiXWo^YH*e0}fH_Tsi*-gC69V84o8)pI+VFq$z?hP4+y1+pR;tOL_52*PB_{!*+BT{!+u|D1 z>u~EzSG{mO$!l`ON6(9!pT7lUF%52DVrR9gd;egtHY)wo4>8{N_Hbh{DxB<8kqBSh z{Y`vbcY*qwIBc5?%1QK4lN&o*1I`;ATira{)Q=xers@|oWc#F>YSj9(N$8HYrlX+4 z0UmAV78Y*l7tPA@*AyFX`&31Yk{06P;wpsh$Q-z@B-TV;UVdflQ|(oTZ;*y$f}B2` zCzS$Kwq}v= z-16JD@17bJOwrKLFo%B96@&qGILXhijGRQ+OtzPzWZ=LcKI(p^@nRodzoI%wj>+)j zKCclyR?Z2si(*j_g?O-OV#Yy*5WF_Qc9GAFb=VON*gcn`Ev%u%VWd9R2PAo-`4dEq zz}BNuX*3w!ICzyqwxOdl?%=Bo?5^H5lMFQvXQqvI)7O`1qK2O3R9FJflHf7erma{< zawkD8K`mBx7&xUaD=V8AtS$hZ-)W6M;g*m%xKHZq=xxM6u#=JOT9jDXX{droPq{E{ zbl+>>bIl^XF1+!1&&ugdx%8po)~u*oH1CG1_mW|1Pw`Mn^5?dLj$z_1_rCZ*cqKy) z)nr1?jPP1e-1Tj@xo_+EXPwDvI+Ye}eb3;5*=wae{Y*T(<-dERm#DF+?Rd`7Llvdp z>13hcMd+F0T1%biHKZMdKZ=3A&!5kO>yS+S& zFT_GaS{xyVh!o1`7re$Ak1W$V7qy zeu2t|rH5hTWSDSq@xm)(J55kgY7vq13a_7*MQxG8g2)j?pFO(eHy_{ntQ>sS8LmXf z=#pT1ijbOH8wW-Bn|R3y1U!NG6hr%q90lyvRtklLPk01F6S5(C1Gi2)UhkBCjOu0Y z=r_R2!E1vABA)e@*@=p8FVJ^}@nw+XrEiXhs9d)l$RaS{tEM2wv$+(gsEfYYg4fCE zcH+FFe*(O#N0S&c;PJ`>yt+tt17v|N75!Wb&%@H83*0e`9*sqJM=0Sx z%G@+H%k1;MJGw|($-lk#WPrj&6Qer_dxfQdH%9&;Uq?6dVtckc&xx0Tuj2=6;;$*c zQa-OVv$&~O+DS_Y$}H!1nBEl0J>kT!&pldrm`|L1pK_ zK&2Py&Hmw~{`iIQcz%Ppb2lM>k1xjRM~|pN$jhDuWEQ_!hadXFKt|X^jQ$8mYpOl} zZo@v6kSZ2`lg(0_@Uu4_&h`2zX}RwoSeKNojg~zK-hvgGI|pi)Nl# zvE=8^U;hxl#w4lFB>a7+&nWm0AC!ZRsR$1`atUh{{ys8n=k@xBM4sntfx0eF$?}J3 z$Bhj)&c}`kdLqMb_2P;qg)izFS+^Z2SxKJG`B9s`y7J4E)1B>{DkR7`>9*4anZuRp z7+o}+H9|8^EC|t5infsuk2}ew%43Q55LsV;0CTHt*GLB>mEPHM9)QPME?d!8s4_i?!qk`dGCe_)(E14Dz?rj@>1twd!e@q5S(_X#JGjk{rv zH!(2##v{m*G(0=bWF%sDj-??sK%uKhQGhsh9lqDQCPF$$=DfMlU9+o9eM^`jf3+=x z2Z^C32(#xr3=TOhyLv;#hQuFX?_V$3#;hXA-Q^s+xG1lFKi6TpqG5H?&1=$*2s-{s zb+DTgDNep2HLrzD-7O|dy>QbrHq2>Ad2*8UscNZEVk3WOaX0fV4Tp~L?%Ew#3?)43 zCoN+lV2o+WfM&}$(=JtRXXs_HQYGcjDq_cP;F{D_ls7%e#nq5bREToFNs-Y!-pyxb zCO(iv;U;W% z;lZ@K_GhaElrUX*yf4vbr0jW_aq1+LGx8X+So&*Ev4+4qq4p>ScPFv%_#=oJ|bRD6-#(~|0U zzqX=6UG0_H;fM&E?0EhYQ|tDW#)q~f*B>;b4m=Bhm5spBCl*Xf_D4-m%jP?iJY;uX zZ(N$Lj4WB~x~=g^D^!ZK(_(c##Us*=2nhk5Gs#a$uGRCBpS(7U=w-V-iy$A7dDrJs zVLuHzTLwjiQdO&yPBiMwLV=N9-Ol%w7Q1=JyR5RkB1Ibyy3N%W4&5E{W_(vp>JJbZ zBn~nyt}+D&GxHTp5{<+he*awBMtgAeNb3Owl@Mb|e?Osz8*US?_U^MXvb*d(O`7X+ zicc?1Ue^V%4YfJw=$)vI?&CwGP@w$q#3<;^!3RBzMptO1#>Ccwj)vF#%v+FWl#)^k zRbOSH@yYbDt0{31DEhwhpn*40^M`oj&VV8(kpOma9Vdp5relZ1ZNgkma$VNVD05uW zi@z=y+dL<+c(AIX!m)PX+sb^y=Bn2qG&sGO9!+;*-%yYZnte(y+cA=zZPE{0>|gXc z!bZbJd+~Q{!z0=j)(wTqupg2gi8OFE|HLSn4uYRU_8Rc*ge&k&2KID2&`gq8d{_VE z=RR6V^K6SWxHKtsJ#u+Az9ziJ#HK@m-SY%j{-lhf#_MAZUK=LaylJBaLM3y7qnU*~ zZ&QkwVjNnoM;eTNliD~O6vTR7a^hTUj$^EBq*Q-)W8A;5YfPvQTuIR`D&5E0%uty}M%5$^pC+*J& zZNs~4t3y)pPxeSea4Yz< zr=ihg%AvYQPuF!_9;e^Nk{bhzt*!GD<18ZqEEZ#Xc4LN9y>^fS#vZ5OPV&Q5kB|d{ z{2I49zH_AQ#Ps213Jk%S$|o&z85SO=tXo-86Rc+9!*UfSyBiwftNdAMICqx(J~Cvb zopzQz&w?|@dbp$b_PgG736iIko=j?@$t*02QW30>+yObwSzC;EpkZ?A0-V*ESpZI<#ohMxP3R-L35COBioBOs=6Ar`Q|O3pid>( zfhu-p_RLK60JetE+f31}n;Ysy_csif2~XwFxy7E}08QJAJ0E`NqjwkvSFT-nFstKQ zI9Y4e`P1d&Ei>z&up22U-^^58+|rA3n>Muc$6Sj|_tTEEg<&Gz2>X}$H}XTZ3zEQ4m!mEhs*FdpD>^9bzB`8w`rk<#xn_W&WvnP+9|b6f;hM zh(F$jL_8Y`7e};a2Y;9_i>z!E?_qvdrSF{@*c9Wv>^ysmG}M*-Z_y~!t}Zp_Sb0Q| zNPT^Ah9z;Ulfi?v!S^TM8oDW2cD1`3T=t&pc@%w}lkjru4B;POLLO&37-{;{gy&KH zo*Qk8L+f*|mw(=}m+&ziGt=wZ+&Dfkv?@ILEvTCW0r&E`;|ZRJ9XR6Su3W#~kgWM* zm2z__HrxKTc?%^++!n)M0K=mZO8}rp-wTI3Fz~xcl&7V}TUTBwqm@DC*`M;q3+%|c z(xYa79*=UCNXz(YRx%;kG03aeeL$8?6j($_|1n)uAk zH4dH*ubKap0*`yy?<~3(f7T{!XjY7+q07n5)5Ec==zOh_&WSG96pi7+WT}(C21El2 z+N%!{25@Ix2L%fc;T;@|U;-9fF@NmLP;$d~M|`;5{j}eX@$aPzM|g(HmV9~R_zf(H zi`{M!RTBkOE&?~4D*c1r3M`K4YF7pX-!!Q)iSpv_x*x8g-q#`c=~I04CBO9Nyim%o z3GLSlAI~~tF=INbbM=M8H|}mJYUwZdK0hS~9li4`2om-keLbTsF0cC@&Be`G_E_)P zbYdZK(T6?G{>Q79kEa6?5)@w_YnE`@+-S(SF_;;1#H72O=fUE*Adh2|SNAz({q(kplCq&Gsj{%hDfokm6Z=$}A)kR$1i)|L=qRRWx#YI6 zo`2yx5Z1eNnNdDf*JWWh_I9uKA{4f;rw;#1@PIo7m>_6Z^&eu2u4{LPGpoM$E55zb zRVdGBc*5Y$gQgFD^wy9y)%fPQ7-27M`AI&V$e&{~+SVyhZ2bLoxSRD@8JWe>o#CW} zIIFZ*Voq<>)#KLOhgT=#U1sAh`S=@b{(3Ddlp(M&!)Q^yos%NnwuXuGj!j3)&*RH; zjqx9p;^U5*)OI~2w`e>TYvXu7_jYqbvkl4C-BU%vEW3Q7tuZ9l(TY=A<;p3^DzKR8 zvkmdGly@ATJ!>Ft40H_b;pp3n)Smq>IhHai6kXkcz*px-Yyi`ZiT;4_s_JiXl+-T* z3cpk-+7bEou#GJj`!Op%XH*=DIKIA7wA|T}+8|il!;?|5&Kp|?aP;gd`XM~Zw)<~T_*ch&TYDz1atvM z?&P@G*G`PqectIIwQ{9Br+SGcFi_uU^($wk(6t1n8!kRHku~(}0^sG-JEt4kWRGvB zYu<{JE~7X}3U23z&>B<`U4P{v_W9=0lG)PYZUyDHZ0>bSUu#7!)^`7Qj1+lFYpCTodgcb;kl9K26nG2moKYZCe!a-96c^%HRx{VAvH9@U+`t=&bb%s z5Av*EEsP6F^6>iQ#3e8XRUePC&dyu_2v>tm-XZqD>CRNWc#`Mqg$apV;$6$+rnqNK zIVo>m-N^RX4(MRy&C!_wvC1sLXtLT@7lj zcn0Dh^coW;y&o{~1YZ2-J}61V@owwqqVRJK40|M?sExikY(PVSdbT8B;< zHz5ckkN+c{bfrVLD8Sqdr|1UIdbVKF()oCbh5$VR56qFbu!WJv9y6m<40Z)FJx^s3 zAx&H8x^uXyFH?i%*FQqacm)Rp?3BZoe-4(!ZRw5 zdGXmpAkm`3h?uysMRyubV$Wk9<1$yAMuDxpz)|qnaWo6Ehy*V@yYm>`h65)NoCo7Q zh{h%Mtu4Y&5kV1t{we^`ScWIHpjDs@etrjV@f`QiPSYLSqLCj`!tfu`OUcRb9-CR( zUj)+euPNkfv2kBMD24Y00d8SzjKb{par4Fx6m8>!j5bvPqy#-XKB{^i543~QJzGmV zj}z5o`M;z_O51Yzlof-8&oM37b{t6e^)2LeP!_FVd)&NC3tT9(oG8f)m0UepAyBKJ zl-d*~RFJIliXUH7KE5XD)I{i87i_j`whpz!bVXbacM`1P*B zHpn11pbiE|Wg=mfjsPLn>ZyKS#d`iNH}}8vgytob)GLEpiFJEvmzU7Vgm>z?>8qgV zFzg5!17cI+KFzYH4&L6U+cV48MgwXFRRKdh(o&Q5Vt0|R@6EZDQNOFLrlvBo^8ic1 z%967_?Hjlgl41!h`B$GkD=oPI7xxCbrf!KZRAwM^S;jd=`Ql3MU6bNM2kvXKPYmFz z$+lf%Xx64C69G2joH}R1>X93pMj*C?pj3m=HFUGeP?8#Ft7iU#EivZak`a37$oO|< zfv@=?rB{<{&C2`_z8JwXBdy2I)FH{y%JVD{#Uy(lXTiINdvO;2GNv_#g*m?{A>1%) zYa3(?u@RQj$s-&?LC7P=(eHM3RAx>zxWrw#fV2q~ps7h#^g8D#@6!~rwcDE;2L}d1 znUBI{EopD|lNK0vBZolx?1_`v7F9H}i$fD#m-bRGiv~yY-0~rz(e6?Jbg&`m03h+jDk(tA5`2VB2XPfjn-Bl8ZIr z+KF-j>hq)8G0z1gV<;A-KDdGeLo`{Q^)M9`Iq3kk-<9kg`yF=uk8*0snw?ml#RW*=f=r zay?2y?#_w~2U;cvRM7avYJovGTEkF@|8xM$;K8?YDQ76!0yHs>1pwb%=R(aoWqh4B z2Cpz;F;G5w#$OdKoT|FIU^dd(mUe*e8^gZ-((g`fS*B)YLct|$q!u_{OGY(RfW?ac z^{eh9CHB!*0;yzG0dy{g3d!@&Qt+Ne+S6DAJAU+BQ=Z+kAEF65C2qlq_Csgl<3hHP zVvdA+u5il>-iouF?%S?hdp+~W^;#*C4y}}a&pZ>z6NPLImGQzRCAJxhvv(fE>d5uG znM%a<19nVSZCUyNdA6NDXpR)-6*IGjr}W-Xic0AA5HWJ-oI}!OYH)fWOTI2O6e-a_D|N+d?eKUPFT{AqqfSD?w(0$Y*?A#e zf?LyUKqKVV2Wu+V4ry$TN{4d5LPvZRdvMs<)0N+< zO5UEv~&o{>Cyc?#gULqEow{?Dt)uU|tl_$7bgmBJNEIFKGu z%+jWKsv28^A{V`UuC@HjE?ZAB5l+r?%}Bvw6hA&c`XS)*A;B#Y>Ec)Kv(&@R%8%4t zU^;zKH$P(m@Dai`fwF#Ql1)VH7Hql!<@c}xmS|SpNi68AJ3KrP?8oy{$m&I=A9H*I zQ&Fn(J}fv`vA+_P0R)PBPz_+@CvojE=p7TX@j}NztG>QsTG`E2qyE|2?{99^Bul_g zX7?RuVkm&rxJa<6#!|OO9=NJ=0bb4rptyTClm15l^Kpawp^LNRPu+31WQuozTsH1b z*M{iSmfX_mEH49UJ3=hT#a#*{ZenIO{=v3*w~5ob>~2=;u8?dVvg|Cp8h#8C?z57m zIc)`vi5F{X9BnsGy0Br42NWJ{msb%#%qlsyyvD0_@P>{2GkfeEc+1KQGS@@Z)F3Yi zsfWl~qj-p&XB1-ZwO=bJP=~x5Z~7I6d2{uql;Ful@~8UQ1n?mUMwyJKj#Pk|CA;%} z>qzV@o-9?o&otUx{Yk_H9J1btJW|}ox*t_**pGAN=UQ`8G8gUcW~y-&IV5G9KFc(+ z33{}{@BUY-R)wS_$J*6&FL{$Hv4E;7W`++QD_3kfm>53mfnq`BW3T z?veIfp@na$iZ`Oq8WTo)mLKnn<4t>6=qRXr5|+rTt?=nK^Q=OpM}MX0jDg$ROtan6k_^ss_DHTfm~7tgxdb84&Pb`%@A-MYcG}w_LT(Tv@&S_*1bs6e}XiNkC+ztHMZk*Str7q~+r%z;az`f)LjjUg~Kd ziV(f#I(1=ax<1xV!c#B%j--fZ@m$~YN{^r*S!dm5szL=?TB;FVo;a&?M;b4cbDzzh z0n%2z=Krww=HXO#@BipqsWc}_ks*piB$?+Tk*S2t9x9cP%;Vm98qAam8I#ET$UIYq zN^JAY7BaIl&zyU`J>T#7e1GS6o%6@JuJhOFx;~%w^KS3=y4PCwx~FyD_iOQv-?5WY zvwn8Nk#O0=WERYMT&t+X`7ow)^J<&nFjQSV_7SKqdvfK>_>bOVbYGM_au(w9ar}mQ zt3`xmU)v?uCe=o`tYMaDEuI2;+}|5JKigvhrK6~l3iE*L1R6&OU&gBrVWQ_!FIjfI z-E~_Uxe=ZN!Rm|;YL3n>E=5UQYfcR}KNoX<)9;a%5#N56ht#f+V;HyCD|lA52QC&0 z97QfwTlM@LfJjKMk<-8x4vkbJsfY+(_l^9yvE($!vZqnloM9LpO$hX#>@qK@3SJ-$ zRA2Kw8dkkB_tIlSm+?Y{*jnnVw|CtvcOJMH5O`wx9JbL#j$59sHG`X(tjv;$3yZ%X zVT76#!QJ!N*BR7;h4qKX5c90AwEO_*GR_M(_;6$Sg5|>5D$tRcuGqi(xXlyxu?~Qi zbZjz~+uqA&6Y$*>otZJ6pKJ1utfJ%(6BQRhdi+vp%@8@Pu`>ls5wDLwSiRQM_e~1l9?QaUU^%;8zoDENw_(jd( z=D;ASW1gu5*L~ur0(@<)lnk5tD;qOO@2WXff{dKX^T>3<;d71GZv4&YzxycfBLXQx ztg5XXd$KMn(81$`Y@)dle@l3YW@n5N8g0nxAkzw{xX8rr@vZ-m@ zUtbNPlXY>5F7* zPAa4$^^%~icb(Zey{oDEg{9^V?4#kpHx|i} zgd+gUW>>u7!oi@!WaMg@TkT4XEWW<{H#~HZQG3lEvb6ikU%U=;mY?iwS(kFG4iH^m zCHsRCuh!PD@KKB2L{UD5dug; zNiHl6)TR1K{W?36n!K`Tym^6@>(teQ(j)8Luf`o3vUijnIZ~GzO(`T5{up>Cx%^H? zNlAcpc<`!Y@BN8!A>15a(}LALC*N<{^YNorQtX%b^;I(n zQx}zNN-IH?ALOTPc#xrzC|<2rC)er@OFHDV(CAQ#%&ab-pfkJqrM23+G%S!w!a6cF zQM0ysbQJ0{R)nLI>p$mUPHlXnHT<<^Ute6a>|7EqOnUZS&|o_(Vx zQM*1bR66u3>y9sFwy;0xZ2k{b5v9$wgeZfoYv_nXoEZMm zAUo38;#TC8kw13p)rIkftnV!zxxg2`4B>%IO@1P-3`eo!ky7C+)BUJf6(dB`pydB7A+!g>UsHv?D>GXU47Ux1tQL;Mn z!BDS6Qi)86PRX{QdmTRB!5NaOACl}yIc(@Uc{0*g&AUc8JqnEYFD*Vto z41Q}R9b|mHG*0NU^j;5Q;Cr~-sbi$%W=L?acp($f&au*N)>L2+gFyo#?Asn!XuStE zWxd$nyV@!{%&omLNxg??X(`2Rr-w-CUZ<~}HEl_nX)ns>9UJ=*TTpP)W&VMep<`;` zOOD(tr5@iecP-r5R4D-uDn2?n3GfP)ZyqzBEq0|u(pXB2edh}IkdAvp)(#gwefE=M z*5(E?Ve#!b=;S9N)!MmHDzVwgaoCl@VyjZ!R)77?8*gs%HGWmMgRCxRGDK!3I%>JH za-I9VN72WcGuaB&WN& zGXmGqtC&K2dmaw+Q_D#?lJehw5Mn z6$4ur=O(*ymor3qN7`5U^W&UDd-T?AY(ZUFnsX~$UwLrotGE=TlvbKWT`gm<1tDVNIQVa7u zC7QQ(2ZPF>?93yMkEpu_9rt zmuM_sG}a55?zMLNwrrVwmg%=oj`lbvco0-oEAB(X&A!NN?adP}+dnK`W_{rDu+qoN zc>V1BqRf(s>552L&bB^|K);dB?9mM9UK}bTGru_eC02n}&|Fw5XIB2a1^|A-%+P55 z|Bkk&JfoU(!KtSqIsJ-((_f~Hc^uI2!DjRGopZ*)yiO&f@m?b2hpWp>!txRJ+7-d- zoHAr>>;x_JCaevF_&(sXr;^+1gKiCnnRAkBa<7E|(_5_{?ZEjeZ z%(mcwrq-KvDSCk7UJ!g>!NKBus()>kpa&`Q8Cw~E+Vy2$)8iwc0pt9;r0WVtQwq%sF|wQal_T>OssqB z41<1a$!UUJe@1OAnw#EuRj-2L5kkX;xW;?kE>M)6)^94;*i)sFLkKhjEh8RV-GSNwE^fyvnqKI8K$3|dJ5$0rLB$n zT{mWGyzAYq$CHd(m3r;n0*-$FHRRaSVk6hOc>tuwC zae*DKHRryQO4l7`mHNEopUnmmB0`ILoPCx#Sd}JwXuTIpR;?;tpOQ(JgxMrZT?q{M zbnm2pm>}13Ngbt#4!VzWmE5qOYw#`=mU7Lpc9)&L4%v*dbs%2dAWlZ?|F{u$N$`zO%YSFJ6%&UM1qUcieZ&2 zO4s!(!mT+y+Xn)!J^cl0@%xDTf>N`JdPL|awT&JM`||^;-MO=aQ-6M?Qp&?sKy9>@ zMuje{!-*+PyGa3t^4d+u4v2TOe*&z3n}=`yHa?tPcTn=s^hf^FQ>v#AO*NhtsCA#M z^)}x89g-_~XWwfUf&|2V6DD@3NW;z1Xbzx@hYFgj6)pAq3b-yzgi5(O@b)a1dU0i# zJRvN|aegAi*E74^t6+9KRRWTXb}Y>xteudP#wV~_&oGh(>WkC}$+yg}%zK-)w0N`bY&VbgI_RO%B3OR`-5iLS^P9{(`NMGa#Ty=-DyRb~lA4GF z2*ZmPFAlosmTg|&R1r8XEjj(>9P~o&+$hg?fMp7D3IFkJg%`%s5!i9JQ5(_^-1(rbMUJYg3 zRxpCg*nDIwG{$Tk_vxDGpap=$4EyobYL~?T=y&`$my>9K9GxJB9962^+iO|Vx(53{ zqN~A=m)8XcOC5WasB@S^;yu*O%qmC(7Qi_MYtPZ{>;8DclSaU&!Pu-rw{eCe7S#hP zAjLA@D>=>Q*o9N3YfD~=EZ(ynl?Jl4!w=G?RBOF6sD?>y+OH1KMub6Zmt%PWRa{VDPup~ zENb(|Ti1ZL5-w41scTJ9a?Ac` zPLlt#x=c!NG{l}=LEB&?utSA&H{pp2)T|l&d@x#Sv|a4O#_>I0gHD2R*&6Q}JlZAF z4~M^G=8c!!-xo54iI>oYFB=6`iwfM>JV0|exbKcaamjFYG*ccBNYiEQ|2xO))hr92sU$n5a zZ}NK$uybRw5}^x`@=N^9clLzVp-YspXe#23t-TK07XJbETK4IRITmvfx9u(BiTBa< z#G&`-wTAd>-*KCCqO078uqN0UE&N#&x5*7u(clpGKc00W*K+IG9rV3Dp4=vS_%oc$ z|9ojo&+u(qU<$y zUn82q4K!0Wbg?NbcVUMCBU+FoM8&C_gDzAUR)0O16mdeUO*`AkW2`^XroWFaGmpJd zX=yKgEHwQFxNwHfqWE(p$zV4hn{beTl~aY3-n4AF3{AK<4nmQi7!%9?tCjKcz!&2f zjnrEi?9h&qWVa$_DK!uuZspUYE>qk@d18vl>T^FELxr8Wx3G;5#TsLZ5nV;7g}ba= zCc`5ew2I7IU&QAW#ogDBvMj_e!TQK*{@1fFz$low@_#?`@#OCNf^Lt*K`g-cj^v}8 zp17~TKHSzSN-iECIWqdXcjy`&v4kNi??TlolHk3v_=?`EqXv89(nQ_7M}J8IN^`!^PHaakdmE%c5LH6|H)hWpKEzK}U?mDc`+Doy zchHPJ4?>j#2!C1HedXe+99Y}ZqL%?35U;~IqudowOehjKJ-Q5pS9{tr+;-Obh|*SW zdm`e)txGzFgf;>0mqo|e-TtWdcG(h5WW+RlW_VxhSgtvhc$x8a7jGduI zo9y$pm}rZ?3B;;$1Aq;572O3`l&x>zJoI2;Tb(qbSZOT!q%AZyH~sbH*)&w(S3}_^ z!lA)?+e4ke>yQvdK>0Pz?Q!r0_;JAnG64ErxP7&%tr?&O5IjTC@=$oj-P(7z00y}T zG71}@i1Slg8jfuMZRyRH{`|Uci8-xK<|3fRj0Y`Aw}58+n^4``ZkgK?OW547X$M~z zA@(hlSi*joLb)=u#ZRvWz&CK1{Sgky2#{t+>6LO>oMMJPCq4*7f;ce>jV^l9GEJBxQGx}Zu^5{h1@q4`85KteD8dWb)O z(WGYklg9DvmYxwT9dN1M2yYMlv? zce(oEUH-)joyk3vbut*_c~CFgk6>rvy}2%yA$*3W(BS|e5!~2Iz%Q*PQf=>CFR_H; ze@56BW63{d+ovIHmT+;Jnf5wBZE#%i^ZNUM_?ZCdl@ZaYya7`{&1N>*g*P(B=%qBv zI*_copt>#?M*@(8{+uqW@n%8oG=t+%J5Rw;*Y_R2a0)PEjzzCDCy1{>Dz9(_K-Dk- zZm(;KZf3mUB6P_SW^o>T3H|035!6zKiQJgX2*k1itI%RO0fwk%Ndf>0A?z3gv~C7p zvgvgmu0&PU0FGkSR*;|)cG!5OF~oGbzjCsGpFK7wM;KudA(#c%5~pGwum|y607|h4 zJG=DysCqR5x^|G+dxj5X-NcN*cFm&g68=PZzLtHjAyyQyZ3cXJ(njjnNs_ZFC*1y& z+YI=Nm-_(}{n~O#msR08 zHL>5X4?HV9r)2MP?2HvU7Rp}+1-Wuvkl5DMQ<_G?ssl`?JzohM!-Oh;W9m+Gohn(K z0!3_Q+FRs&Tu;kZKj)!0oto%LkGT)5A1A~19_95i3lQUkRt>#F+5FJ^$ZfgCIN2mr$nu%8~7`GoSHkYbps-QJTds^`eiR6q7fjY6_2YYWQr@;WAmRQagPynRzy1st+!s2#$6a^(7Hs$Y|Lo%xa^y_B;4q?dvP$00Q zq)Y*E-5WBL09(f!YLF|@>4ma=OX&{)UytB35Y()G@f7Rkk|F|}=hhKcl%JdE5Zrl? zZg-c$mxv}vH!f)}8r-YWHQPtniid&{faIK)V7 z1jIiq=Jx-_#XiD`M3E{kJmXa@W|p5bS$TmOpPt$~TS#8#1JLoHxo(6^G6!jw#r*@U zn@$K(^nlFTA5nlfLej}%ni(LorV-{;I$(V*Et3enW6e_t@e6%s0gk!m+h*Xg{2L(; z9VJ;q5cep;1IDpkIRZr4&z^mEg$eC2!ug&mnynLF?1RP(mIi>^Vp%c^V8_sjKA$r{ zW@G6LKR?;S?d$XXHc;SO3A@%a)(P0xl{j`efH;_kN3K@OY|w@aTRxcX{rveej$(pz zQDZ4fc6K)OT(_>A=*Tn!RS4QeJxk1H-)p?==X53gqhTc7A8La70VOBhI5^8sSgsMK zh|PTC(BJ10oIjS7+>gLWZ)#<)4S$G)mI~GHU$8JjiSNCAfc}FH$I*0<;TCHErH-SU zjV?o1F+sp;?H-bFog1M=LMP(!5AJhDf(VXyB-Xb-)|b!cep7s3i>pKsGI9*VH7^S0_K_&8S-$(0=pK`6y= zW~PhxG?EFF0??cT&^_#7Tkkha;s#Rm-!m8Q1(8cx+AKtglc$0{v}^eBR&H!EFV@I|{I_I}@Mgo%Ki{%%y3h%WQ;LH1lQ z8*Th(GnSZ81q>0A;h05_@f#J1KCrORFV2Pj1kwN)kzg-n4UrqY=nx-hdB7#L(UR^V zgk+sI#W3fg?iw6MD~BQg#1a6&CQ;z&0nmJbfKns?9a3Jto!?d|hpH^`agmJP8W$7{ z_@|0@F0T1|9lhKOes_+uHP{QW(4FDFq54^hYVOwMQSk5?^pnCu)9f)+4FFQUn>;Ou0{WC|iY zBZPJjji>esc&sfUV5EeoTtFQX1sJM<#Dpm2raezCAWM_sNxl6 z->N$eEg!0!ha(vfe}d^$+<|Bw`@;xEPTP~D|CpGkN`nxNl%JShuKdvaJ*sqkUcSq{qTN=%-&5{!4BPXvL z8L_ag)W0zO@^rTi$f#;$!2=4Hmp_w86^P4$Qs}$i576SK0J)UA5`m1Jh3(G|v>#rj@d);!V6}H zTj6a8$r_lrX{H3Ja>)c}!GyR`6f8YJGgwkUfP2@qv|7fb)MeJ~^m_N>2sYSh5_FOQ z_TfiHbZeSn*Vr;FEHWfVS1nPW889=|6IyNHSmrv{0t+w_z)+W%k7D*`krH13PS8%* zg)@QBBqLoQnZdR{C9}?l4B+mOE^61HsnZcagnKam4o;>B2W96TypeZoRs!)Em`o+O zSV&Nh)+Sj)LzotKPXvFM5b2-?V4C@wB>n|Uyyq^$x6a{IJfMtv$Oqj9y0>bzO1R3X0 z%*9UIn5#8y0M@|N@U}|4sNi~mW*Io8Y^;fd=RcM1uy*si{n~3&b1wH{;-$3o^g!sO zQbDVDf)+YxjLnIIr%{SdWoMBUXwhkY00^26Be`*+R$r(0Ymq%xC-b0rML!3?o}936 zzK-;I_EJ$gDC-7j2&GNd)zM*yUjAv`4^jL;#7vdSBS^=Aw_TD40Y@{E)S@3U>;iVN zII%G@F?Frk7thv7K%7dX^4m)eGiWY?&J;qUG^>jcyRNAjJQoGKk1R64tJsZP8trIu zYn-4)_gOsL@{M83_0K5^Y;3O79H=Pgx@)5lhCJt)mn-JqQi9dQxud|_g-r#^2Pq+F zjHy$Bpuv!t24-M#ZGA>DvdROcSMGr#dfze*qz!DWQUc+K${_WM0OkOGMFQ01A%x@x zMjO{}$0=}jrv0tmIMVWm-U+8iLLUyqvjz6!M`8VZ!BkUJRaH&V%RZ}}a*Gxu3x_nSG0>pKci(zYbhV}wXTLa41BKPt7#|ee_mfq0Rud5GN;RQ zqCG>`oj-_xzdqPBa@$cPkJLaODT4A)3A=DwdNH4rJzfGDwklX%`Z!pc4?Ei~f=opY z7Va#RxUV{l=_c+>2h-CZS>n?WL8ug{KGBruXr*ar$PC~{n~a(XYW}v6_FOrBKx{DR zQ&N(0jRXh#0r8O-C+L4Q06=wDy9A$n!BsPYo;dWJ&4c!;1JLg#;POGsRnie=Ef^mylqs~$ zv>8v$MHW%S<73@m3yC6w2W(y&aCAQyQr1E4L*t^KUeH&u@^py7VGv|Ke1=b&zGwNn!;i()H zPv+*&1gBOzRWEye7TnCE&<&8AOg{d__*;s>#>UPIH5AH(UiKZW69S`Nadc(IGArXY z>$}^AO|vvp`6CAk6OnV_=;VNi_dK9_=-UZK` z6Z8lZG&u?c|NII#JEm|*1E9-QHE^Tm0ZYvcFd#z#WPsPWL=t@!jCAj+swxz50RtDk z`oyC$DgmcIeOcO4{Q5b(NDl#AX8_XVU~-tv4%LDxJA#-T{QzP)_zxcSm1Py@h9X-- z)kEVi5Qzeh2fv+2qxqb^74}lgpRMy^-4vY+>=E7}`P-jci4+LI<)abdrtJ}zQ9M!u zIH|i6!XyK)HPyb)UwFsO!{bZKaRq`G9G_Qu(ZPY`n@;;zO58K z>3@$-xt_+z)+xUfi-NE?=m>oRTq<8a=np=Mm$bY1oY$pZ{Ls?B($d$i6s(C-a+&fw z81b^zMGGUE;)cKp-{tBIcarVUR^?gZnk115Q042wgkd66%=M&L2{N&VOe+wFDQ^b zkq~qz&LMPJS)ZBvTLgkB2Lz%y5goq0;5Gp#Sz{lH`QCmGfo-hwWZTvWzJ&tYI08AA zrI{9w6C(h|0Ty%|5pyrWKm{kp6kk?bL`*$ZM+7dNDpBlQb_kinG21^2;l%iWHp8~i z#btNhaoHk<0}&I31PbxMkHM`~&_)Y%0bhm4pfUPK0F2Gs{m*$LquIyk@3HaVO+^w7 zA{(wafoyGsGzKjHA~cY8f<}X;pf#pJlT-rNn?j$`F494WSsmpw2rb;P4Rf~cqW|++ zB>t3?j7KLp+&t>yzi$|6v#b})`}$rnq8|>Flwn7aBO5%h?!3)JxekeCgy@Xye(3OQ zTYLhGp;3{xeSFhUzomcq?b!q4OydJRwUnyGyB_={n`?^$amDIBibrJ{htRdP?A8`K zpN-)bgT8U5fHkcJoD!$14_%UD-)G1nwvoaYf(v`T3Ei~YjtM`!l@>yU(SQ1|C@nrf zK^ExN20MHr#-GyC)~*6;1BV$u=st28g*hvseHk*|eZYL_+F&Mkq*p0WIYr95;`IKc|i}EM9PLMCGpz@}F`QZf?`l>0{nry%i zUJd(zM`XuB(9Gw@=nH@Fl@CPMa4~<^ZG7#>NOaJ=LcUJE#cJ$4!*kqy7bY8zE{47# zghY{$6>gR0A*dD1Hj|=;LptQGY32fj=f{&lJ!#v((^=3GYcjeyIo=ZB(g@) zTILSwvLM^irAq#Oh)7u_L`_3aQh9KxnzGp0LQupSgu7~h*3G4Ap{zT%3=MC_FNa-w z%j?})RTVcplo}o~l>2e$<7xiNps34_XRKoGAd?4NxyfiICZ_d&cGB-IEtR0CZ!T&2 z&XW|iS&u^`>f4MDTX}TpdnaVM<{NDrj3C5P!Iln5Z8&L@b4wiD;s0x0vnjs^;XaUg zUWT%v-Z=2L>w$oSbL+Bib>OOtu>ile(zutzlWaTFYxJi0@r)5h47inPuliF@if1%G zctM)`$B)Kh?_JP%i<5YAm=Cg}MFD}d)1IVnU3??~0!0g??Yj>6fz=Z4dSCXyMA2|P zSa=`6e-zW(U;nCn{%;PJ+6~u(jCMhtO5ZNq+uI}Sc`_Q>114WO?DLdNj+|}R56r%` z>9#>TTwPDKp}#YK0Ih2)q)CpSmaSVB(f*dPvA(Lfxv?%W@0XNxcGGi@!tLtKm}V#> zEG<2$u4R|#1sj-BoL-b733l(>>_w`{rjIqNJM@nnL75{{k>8&fOs^IWY^(&9a!N_3 zQ2r4${R1=lE=JgR-hWd|>kS$yk%*YN{X;d2E@a=Bxf_Vg7Tn5rzN1avi`CO6=cM?U zzm)=G_Bg93y5$U#Ln3s9xZ8~D_Ijk_&ti^%NVgO=z_E2D7_PM)9gij*>nKV62gEEZ zetycHX3)hJ@vg2;TP2d&X#hmG_v>C(H5a#AfE`1`ZNr=W1Y+iKH%7))}*Fyo4z222*sHu&9okmB!9b3ll z_NX{eclLIV{C|H5(8Ssp=qzN^llmNUR(Ux&5Q&$3V(U^Ga*!`Ec!Y ze5LRkPY(^$*6jX5R}+EBo}A_zu3jLvkkrd_w&2ueevJ>`kqn)ABb!+z5yhU|@y>k& z$2dkt?3)N8XXfwSzzW}j(wUdDmpWe>`+9kyYoTDVxs~=Z@cDt2rsj^ex${F&k>tW?w)%-~N?&_In>55dqFRT;Vcj1?asnp1 zfo`c~X=!19^Wla9V z2grYLD+$yiXi7{u2w3+jq|<)LS)Mp!Y{Ux z5xyDYzxWD+YPjHJiy*S=@53w3FypU47=_qXCZK{|2B!ky%3^Vm@J^p#oNQzuVHd8z zJSr9N)k9VkcASf5C$S%2y-l3X6j)B#Uug9-j^SjqA~OCU!f_07jLjU8A&SVL--*Zw zvIR1}StBxV=xWGgK@Zgb$V@Cn8kC z4k)j8#>ogq>vcvC$QTht>xIK7gVh3LWCh}6AR7)-Mr7PTk_89;#fYz9Ux}@VJ!toVeV}%DeRd(nH#7Lm(j22ErG$JBq2N0p`kB^D((Y?Rf zjuG($3mm%^!)~0S*%=dxk9h!pg~MU$?HYdg#BfAJ*=eWagY0>O2IVr8EqJU_~*aBo_^zp+&2m_dp<-=lOx2gpM{XoyoV!cc>I(5qC@< zMr=$^Blie;;dA@?@{O_XJ$jQ;8W zo(Q(Qyl!{Lbhtk3rKJUQ)ME^WS!o?Y5Tz0-aIj?Aw>=J5JT^Ed(C?Oe^viYd<<#^# zWwB>td8VeV%E+}vsIYFMRMs445&Q<0$j(8-rvg=GaDkg*d=WB0b=1Y~TsCkSEdcQH zq>gN}DjMRG0OY!8tl_JspnS+c6jc%MyS*ngH=o)F^%!}t-~XKHFnLkTwm`VhV{YVK zO4`9QEI5yB@!hxGp0iy)-Wc}JMw2;OQ@CNW#S2NkT~_)m;8QoZC=@N|-3cD&;b9se zZdbv!Gvmi#37@(0Q#R4fhrI?z84UhWx~~Gnx&a+m#6S7pg=~jz3Kf!I2^Dd+*^jf$ zVJ@1w5`F8*Ba1z47OTTe>c*@C)un9{1^KqYJIXkTPZn^_7RQ%Q9%iEt8PzP)f3wcP z#$0CYJPh|-xOj}w^6abAFDa6&ldukS zq7=_~c|qO>L}~|)WNdC^pX&|g#aN^YIL$1meL`@G@t?7s_UsGj$jjiZlPM*D4^p{c z22u2P$3(1blNW0v!+9}bs{fke);NaL<%!A3zIlVMHUu24+9s>(#4X$n9+kUV_OAZm zQQh8`lvLGDAW)sJm&Rv@0G7dIqovNB)F*eIi*kD$G8r8x`PkNt;+ou9WZe+!Gil$@ z<##MY=qyiDiG0jAeAA@RreWd=ha$SwJsKrARg-!*oWBKi=KX$qg!@?@f9bT(A z8*u*%yML0#gFN_Ms(&ba)oRngu;-9tPqrkWtY017VCMOdo3Y7XZ-i5XOL}6~*?Bgn z>HZ&Zr@3OeX<*cQ45FMf$AnXaf1CddYjWG>)O?1nOm-DNg{oV*U0CIP{X=fke=$_2 z3R?R!MHdLXwKnJ-a_{o&b2Tm$sT2DXk#}!Up}{)D!?HJo|8CvH(d=xBdW-#J=P`gk zx9D~<8zY5^q&ut6J>6ZX7!v8>x0=)Swz}7~&E76i_9f1N?{E&heKT=KIe%$)>i1#Q z@B%2{5RM+POm8!`Uh$jiVKOC2Ju8)cj87+I59;{$Ire7Kd&dJr!8^^LQm-3Dz0slC zaTSTfQCu7bX;q$}Zfki{2_?TCogzneG2d1*{+Q89Epv0Q3D8K#MvS5zJPY;(mqJZF^zVIEY2}} zQ}8=b%vtWxiRr1r-x)6UP5$lxBj0LNDqDyzsU^O_Gs@h%$|ck{ugITp>T5lbLVe~Y zq6t?(K_SWlG-^k&z+-T@ZX|$?z>qw~oKs(W_URa>K6Frl;|HZH{~|=vKfOWY8LW=A z4Vj#lJ&Ei9S-iIiahqm}+#^+0UEW*ucH5jtQsc2Y>CaE3(ww=7#`3}k(}?joM*}Em zKR%^fi$^;4JsFFB(u_Ef4ez)t`-JB$o72zG)C`mIFPz4RwGu40?ZF4n!8Mr%y${$Q zBQ!|aJ;W`-m`^mGPi`PFN5tWDG5XVT=QYlv<@tvLpNWF%p?&lc=ob@Lk##1kbclL; zC9=0M34Gf$ZcvxY;vuQBI-D(D$Jy;D2WRWYA7v^%6eA->;^Ozr{mA{E)l#B-9xE&A zX7;sX`_k#RjF1UfBv`bDe72?By#%HNDQCU4x%udKG&?^dWsiNwC9ugZ=KY=)j1T(J zcLrEam;hWInA7-q9qkyNm(xBR1Gsf zGLl@_WbsWtQ1V0me2@*=t9$-9HH{`AK8F28+v|MWN|xS9c|P&OciRGAqM$3a3p7Wm zx8KKCJ_o0SZ9A+ZWjlsU9a-0{^}=X8-`nA9g~xC)4O!}PltR88tH;Bm*cn+*lQa8qvT@r4 zqdzZqo?ZlhC2rARK18--KFD6(%8iG-P5DFnDp7(e#=JE#_ER*^zo64Z48S>GmX?nC z@?ZD@D&o8pLk(p7gD=(xd_^@b0U5_|GOpuOKO^U9^352LF|rS5ulA7ym&$n0b$Jsv>c-8q))+CU7FmaUzJqyFE|N;v9GY zACv74jCleL5rbfRX$T62@4Q{&YyeU_%r&L%l2uS3J4>fFS z){q!`^`o)*%bi}aSFiW%bW+uzm8YhsmEZB?upHm^pXX;+zea}(GlV@UUKE_2XtPMw ztsyzekcXGE^a2H^7JC85j~D?o@ymx)1O(7J zxZyjF*$2Q+Owdo3QDQZQjq%EzzkdgRu(fn!;I!N~`_Bja;lW@3`G8sO{CpTr2d+@D zPr20P&5Bh>X5juTbnKy{){H)eW-Gll+vY>mnr%2`CI3F4rPkE>9}f=0H}IeQ*EirD z4ETeSTa$@BNyDjxM$w?b`66b7##6}?(Ls-Q!^3^JJ(Wwq7kh9|68GVj?;_HlZB1@z zle&D+7ypS5zJw+`o+gjK<3GWDb?l$*@SyxZAJBQ4IK04r@(TY+%yXFSTl~S+HpIMz z2l&3wZ#^(!*zMVI9PQkhi}=o!SskX%l)@K?8h?P?qh-hc@nE;7_j$BYxADnhGxCQF ziu{lk;>IUSl%%6(U`6k|xmNQla>h|pJCb31ch?ok20qOb6?i|wYRP6$SHp4ysP z5c&eXp#Ofs{wZ7Dh9DX=4&M}P?3mo6b(|TLa4!XGzV6w#QjHI?#bKWYs3CTVUfR54 zi!PT-hYWJ@VGXx9>JtP7?D28``zzp*IN}2v;(`eKG)!Io9Ur&=*Rfd8Vb8w7|NO?) z<8qJw+Is8O?5=XdgJ$n(QcDZ%`ijEq*AG{l(vAOe0jF7Qi?!n-*hEXmDwc-HYn=TZ z=6h|=0e5e$zwFCH)Wb%R$2N;hq_? z(hYl$^xe=M5BK0PHg@Xr>^CDz!*DD2{xZjpn%oqB7UqVGyPL3=TX$bz!_jzJa5hYn zM0)52?8n}^^p$y86C_I8sIeHMt=au!=-J17&2DYB$eH%*3+qJvY@fXKg*C&27|~^m z*~^9xQ(N<7Oq0Sz2;wWwU!R||fY)VEN|pfx$y9+?n^D&d!n7}~%=-PQbO;JQ*g8<(lC!AG zc|=lpCzgi81Uatwcis@OS{of1e!kzu7@Pgpkn}g*_j_^`iTqVK?tFYx^6~A8i4Og-C@GG#g0s18;JLkFJl%se z9|3?`pEe`cb8qmKT6HI zNT{y-H2R_6`1j@y7x&&D&Ne@mG#$j&)_<;NQUbqP$?)Fgk1p09hG;4Dh}E=18JKVj z6y^fygaVMa!puT0a-KaVcvnSR)D0yPetEWcwv!8n3py7f_owL1Z2yF}dG*Z9Z?RF! z(RUwhzJ$^}Ed$-6hN)cV=I0LtD8jp`2-jGm$FW{+S0%Kui%R6-;X$cdBxeG=sH|?% z>QJ}iL-HBd&%D~!dXY^f(!GCd_T^d2x@B#AFqHY8ntSD@4rPTDtI!oS`;;z+zzckF z3XA`w5+N$knrq?^|yvAWMSL@XdfrnwF{nJHPgYURhggv=ub zUc=0b9v6QpI*WA|*zBDYeshcc?u2PdkEIaApICM`M5eHGu z+F2f+%m-}D-Q*ynDeF(HNy*7(t)F#w6b~g|Gxmpa8F|1=`^8saV|KCUK_Xm8o?R>4 z{dsA9|7bSk^Tz2DD_~_9^>>v4EM4-vSk3`ruJmx)QV+$00no&{Q*GUre!W14eaeAf zb_NE^4ZBtU>7{X7(9S9AtNe>1%?B-bTC1v=r1?gKWPo#iI=ia97EbG-{@l~x^!?RH zNlPcdfA$wE`0i=l-n`3$aM{HjUa6FedCxNW$7b_Hmz*2na)2{Sj7a>Hbak*GJV{vL zK0P0nHqtHD8zGWzg7nwa^ga`xD^R16IR-Mz9qXBBm?;siKpK+?}0T@R!m^0p*NLx?u53*eWa-Bc7_PSDv z^&(MTqVD{YT`YNB?yzFmGn<>kANIHwyYF%Rm;G*|M7k6gm~eJy>7!p?NK&luJq^dm zp4o{nM(H|#rSF3K@ogqPDx@f>%&|nxgjOdC%%Ok2&3LnW7QNJ7C%xFE(q@%eC&+@C z{CjDnqhS>eGkp{~t|n!~l$9_*@SW}*jwV3+ZXQ86ehx`w5_&*?`T4%@xD1osSRZ;#u8?+} z2oABOWL8U0k5iS_)#SrnGADHzeI(>=$wMui;5;P7Ldo~Egro4|!C+XdA=_l0(@DCU)i zbDhaLYIU$9g~}k&0J@f`ALX1igAzcQp;d&nYC;8fLd0S7DCfJ77Q}^W3yy3E-)}qx z%fJvRZm*21S+*B0lPx?(n;YW-acxslL-((ypPYuCVhoVRqrpW(er;0IL_qM*nl zvP(dwgr5KFk|dNZOaoT!6}T23$_5a~DgcW<3Rsl}@4HZY(U~|yUk4kq2*tNFay?hH zq-Hw1)733xU|{-WV6{8Bh|~_A&Y0g7B@s;NKH$Skf)aq**rSlaY^wrnTUecK*(Ho@ z2aqLx2bjg_^RB^bV-D?Pxp*G^ulLsU70L6fPn?`bYo^Bw;^oWnm|-Rj~DpJbJ{3|aViW6NuTPeEG^ zq2Uwp^_HUmALF(fJHsco)6`|~7y84!<$A%V|NoW$uh+8S%;-*HXIGw$nf5x$YJxJO z!(%(YeMH#}yI9?V5^HK|ddNYCxAazA$SPA~4d}sn`0ni%{nF?Im2iJFUk`VK(OS`v z@x9v~om-HHZSaUy@q~?hqou6eajO0E^+{UEudI-)1h$Z*Bxw3kmuVby2T2EN4gX^w zwb;ac<%;ZOsb;8bNP#AHtdM*xb@9Cw(LnDX6S)Wg9}ZiAg1BoaYjw8+^`Otcj7leW+ixFiqS|$$Z{zuE^!+XEg^Yl! z>8WJ(7p5lEP=18|{C~%z{;#aCPsMP~QO^1QX_X)|;lGy~=I8Ya9EP#D@GbH%lSNq5 zt;Q79eUN?zMT#~Ax+~{4gFRBXmc0kFF9Q=`;H|!uH)vR^#rYh|t}0Yb z@XjL5dttJRAx{G9BO}M^DDSO9sB#-57s~bg07h8@D5VjwPm#O_8#366?$dje@-J}b z$7@t2*B|NF>kUO!B&iZ8J+K)HGq3s>V#J7Q;GPsvW5jnniD_wRY6ZL5O2HZ&NX_l_ z(J^v9jcQ&(rQKan^&C`X1c?oyt_Gl3IP*E*UrmKFYQBPzSm^Gy%ffCAl_H|5p9r^^ z@6J>E+6^J|=jU3l`|me8xX^{XxS!*O1$N%3q$hvp6Fq0h@9sw~Csf*0&XQzUqv4ka z0xiLHim+=`5`ZcZl+;aCNbOJw#mP*NQim+vYYc7he`NBOpZT3`L+4NtJuu5T|-UVdHywV4_N10vSFC+Ij; zpp6hGG(?L$3T3o96HtThJaOpTN61Qt&T&0>y&)L>3R+rP$YDUm<6x`SoIq7>aN(>! z0Cj2p;Ei1Y!-H;uv0V$Q^vF_yP^nbQAv?(P$205@*yM|E@s``M}im$|fOzAjRt8tlYl@J~9>$E6B9M>D{g*Bvn1 zgxaLa>1tM1lJx3Bq&1&CIR5EbV`JmeN?R!lq)95DaGl6N<@?n(34u#r{r&_9<-FJ1`S^BAk``Rcud$5^V{F49rk(=Net>QTRqe8#|I>|z zh8tZcTu0u&s2cnpJOK5=KcAL?uXx?>gxCcuu*5y*_D)0r^H(7Tp%l%kHKt;Pi4bgn z9QfgCWCryVI+BOxPhWdm0T9h}s95oW#VmyR1fe}3xG4FcvAJ&-%I+_ku3~C{Bz;C^ zz+hCYh63Cpc(NT7ZPul1Ldu;VD^zwg0Ggv)_U^%QR4ja}!0x`h`~(z@aE{1HEtG9P zSOM&8I4}Sem|@jcY|dSqq8vetaQ1yS*GQXw*UEi;!B0HWt0XUXlP~|&#$197s)dHe z$#)!jLGU=jquO!$k!Sl6!P~atjlEmAjpL7Bcy3GlX zrC&DCcBKm1g1mI5{|bo9Z|p3}_|Ae6@?`t2yHUeZaE2zIm(oUi@GL>Wh!<)PV6hIR z_~(rdk9~UgyfpegtZ=tOm*sUmy?46$(4GPn{N-Ei|Mmf$N+_PM_VT(1WhDl-wL-fc zsV4$Z?}-AyM<0j=p~Tg5VepMLcG<_!zC{Zan1M5HW&i0Kh(9w_5@excU{k5K$ZS_H zhn%TuXc%>ZmKN+^o6Yq_R4yGE0&|f7u`#ep-t@R=(aJljO+4WO5tLZ4g|j~{&I8g*|3`c08V%*X$MMId+MQEcO3B?W z$*wj@QZtolZ>8IoE^_EX7ncZ$CI>M^H%gAJi^QmuF2u%YZ}-C1g^}GfiA1LDF3Fi( z<9vTl>#TELoHu8kwa%;Ei&m>;%*^xr|G&%k_y2yLM$N8eSUQ>Q)_O-4rW7dTr6B!3 zbXtA27S{(Sg4bnwG^m98?}PBR)ysdLL=U0SrMcQ2DL#};-qj(DJ_(_=&e-#h?hN6v z7P11Wh^6DWuHq{i@Um5*&*7=aVQ#x?42=c6f?1M@(Vj4;i0|~haubGg6g*^Q>P{7b zTS|!WQWR-@&U|2I25zY0_HH`^Q?H46gePaNZc7qb~uWDa@;Jr7s} zpdfEH?;iC!I|JKptlzO|)8yG#4t#e^N5Px`B8x|dd#|IDpRxQ%_)~jWj>7X41+Ot1 z;2p(VncQ6tlz@k*2nRSFx4XiSsF}5O>(-p7 zvZkXCHDGnmN4Qe$X}kX1yKta6oU14pMh(kTz%$zyKwFFx<-pbWqFsBN-YDFU-Fzp8 z_nt(}yYFG^UFhCuS#q`Tc4{h2i@ieD7J;)0q2oLr`N@>++PaLg{y>LO=uC2r6SKNUXR6rf_FRVBU%UhPT5WYhL$wXT%OOUAd{2d3& zIG>(6jT|JqSl#eh70I`>k`ZXg<7Q)bs;YY9#*H5Aqvda-1P1Gc%a;xIb?f2j7Iu&)X4k9GPQ_jE(qSxM zoszcHaF{oPR~TL_1(>NNUQpuQxs#`+^j z9)YeF$*b`ZWCVb@9>tkMDuO%q$U^sL`hd4wCp#&NVW9mPl@6B{9??$OZhPow`FOs{ z0LI1w<@2$zYI`T)U@G1yf(R)No_KitIr3zVKcp;?ngBl7-vbIFmEtlOiCGbzI$1Kp z!G6fP{*ar_twThGuS^GR>-r2&=OFTs!wpCd>Qz>y@G_U-JX%OB-5v7Pn))`Cl5>yW zzw;Fqix!zlDVu}h(FDa#oX;T=Fv!McXfrE0Ca z??b;0XbSBr%h6!^Nxxw*fu>OkKc=I^U4YL05;Cck)j|)6(fiyEV?C)LmS`#9=#7{U za`QF_mz#RkW-o3{3d@v+e##P-K?>}BF~fk4GmHV-OyG}ax2&XUiae$jwfJBzw4I@qSswm_T=7uW0=ldGT~9=xddyjYZ_t- z5d{_l|1+g?!lR4$xiY%dsUm`GAl&Rv%gyCbASaXxk}Sj%!!`w97^$sbl*p1AuD=v* zYZ2{~s4(HL^HFsW!l5@L0Upxk&zd}MY<=U}?0r-8LWg}_yO6UYzgJn3{Ahoa3={bXJGGc^df$>dQ662hcqn`Wsf<^sS6Hx5|GPM zaE1syF{?(yb~Uz<_zpzmOSZF%i{_e`;FEw{p$hE-8ZdkknU#ewpAANKNQ0ngs zb>dwP7)$93ZpX}aGz}2lg}`?JT2&z-_cEwabM4a<7;{?~l*znL4$L?a>f=(`IZIt? zsE#El9M6UZ)Bmz)iPY+$zp|qV!u^w4@IpT$I`ySqdAK)ZMoLF!O)4glxsnAt3 zofYdq9kuHQ`vL7d8>JN4Tyg%qOIm$^>@2t50zN(*u-tyr8xfswQ!Sqrn7aFD#QK{p ziZq}iJV`b8s$GbHT2y*^cH$*xH{Mm;%QEx;@uEe}#Z1-M;~cQT?KZ-)bytX46sJQQ zz0s@Y=`!Kfkh+Xr-!DZ7MJybYue+)7$P63Iz!_(09jgAUh1t#-J$M?DRY(hv5HKoh%1%jN^FUJ3%HEP`)JF{(#{| z6xuj~eZv>|>{miG;8R-9+y3)>a=l}k8g~S$;AzxPD^qL|Vmx&Ewe^BOtUzz%omII1 zRc2~#X6C_@ML{U{H306evJNUXrbt3o@TOBn_7J2H?L1Ze(gTrmW0EG&z3N1Dbxf2Qr%sq z;dVup)p$EznxKEWAJmENpB&&0=j*mW}8l{?ivD1^??{FkUxEn>kAJnQ%+B4!UR8{De(&G9RF2M_jG z$lVe{2KQBIgmKsq42l$UIcg>yYe_rQ5A2*+398f`o}BSlPGb;|c^1TVJL- zEd}QxE_X%PSYO=YRS>*cUco{C(>j^yUy7Z{VyWQy6FuL9nRO}Vr)L`8CMV*oMY{k?-3WH>m66lR;9cJh4iGuf z@eJhxz;KMgeLVtgcwdY^#Hr{xMT}D3y{S5?7P{D|`Q|1=PC`<^YvD0&v;^+qC_<%}UoN&otxvTO6*jcJ6#c(?Y{ou?2P$!(8={A)oA^oq zIw?#(S+*Bw2oXrW^c#T{S2%}d!0%K!i_l5wCn_h~|;F%4euN_YA54m*}p?LfF+7y?$?8{kRp$y?EidN%h zOZ3}4y~5Gplp&Jd$YMLsG21AM|KyvLQak${=PxdYYOFuwS~A>+oHj%Jk|g7Jz(c5r zrGG;Qd^Y4<#U8}6jWAr#*uV_&aEs)CNq=cotl8MsbmLLl$s)@&RyWyFd#nM6x1-Z zbH$J{zF5E)Syu!_QI9OfGN;i&d)F>hmZzyV=y4jAI}v@uRT?C3pGu_}ss)4UIrwxd z+4I+o2;x^V0TS7EcgAH4A6;tKhnv)k9%(;^2p<4FvMDJ{W$hgr_C!Rp$Eo-a018vL z937}S+&@S%?6!u%tqNQc^VxHLog_aKwFi^B#F}Q&QePN0 zemHKjH%*Q*5_+hJl#}mv;QrZGXd2Yxw=oiHL>n5^d1s9@$NT(Bt)(*O-`i#vmth7-eJ$)!&>09BifBITHxs3 zJZA|X37m9Wmv%(Ua?DAmql}xoI-Py#m)leNX%*M#5PfR1zac(K05l*o zPta0!N$-czF48+Apm(aGeM9W0^W#Hj&bSA!j}AmKRZ8}V-v;Q&AvF=m6btXMC%sXl zRx$qmu%z&Fmrpr39~W;!=20gq9TL}j|87E&QX^b7@;ndvE!&lKW|VxCvKOV2y(rG( zu!I|2ju&AD8-dG_v5F1|5eo$KRI%g>BzPJ`@HOHfj8X+(v6lsJ%dDRGuYdkANBsW{ lr`YX=>;GTOWKWNdvtFFn)ob+$r` of the grid, labeled in the figure in red, +are given by coordinates + +.. code-block:: python + + x = [0, 1, 2, 1, 3, 4] + y = [3, 1, 2, 4, 0, 3] + +These will be the outputs of the :ref:`get_grid_x` and +:ref:`get_grid_y` functions, respectively. +The nodes are indexed, so +node 0 is at *(x, y) = (0, 3)*, +node 1 is at *(x, y) = (1, 1)*, etc. + +As with the grid nodes, +the grid :term:`edges ` and :term:`faces ` are indexed. +In the figure, +the edges are depicted in blue italics, +while the faces are boldfaced. +The outputs from :ref:`get_grid_node_count`, :ref:`get_grid_edge_count`, +and :ref:`get_grid_face_count` are: + +.. code-block:: python + + node_count = 6 + edge_count = 8 + face_count = 3 + +Note that the number of nodes is the length of the *x* and *y* vectors above. + +The :ref:`get_grid_nodes_per_face` function returns a vector +of length `face_count`. +The first two faces are quadrilaterals, +while the third is a triangle, so + +.. code-block:: python + + nodes_per_face = [4, 4, 3] + +The :ref:`get_grid_edge_nodes` function returns a vector +of length `2*edge_count`. +The vector is formed, pairwise, +by the node index at the tail of the edge, +followed by the node index at the head of the edge. +For the grid in the figure, this is + +.. code-block:: python + + edge_nodes = [0, 1, 1, 2, 2, 3, 3, 0, 1, 4, 4, 5, 5, 2, 5, 3] + +The :ref:`get_grid_face_edges` function returns a vector +of length `sum(nodes_per_face)`. +The vector is formed from the edge indices as displayed in the figure: + +.. code-block:: python + + face_edges = [0, 1, 2, 3, 4, 5, 6, 1, 6, 7, 2] + +Likewise, the :ref:`get_grid_face_nodes` function returns a vector +of length `sum(nodes_per_face)`. +The vector is formed from the node indices as displayed in the figure: + +.. code-block:: python + + face_nodes = [0, 1, 2, 3, 1, 4, 5, 2, 2, 5, 3] + + .. Links From 656d78fa1c87759e8debbed49b8e2123f72d2640 Mon Sep 17 00:00:00 2001 From: Mark Piper Date: Tue, 7 Apr 2020 16:55:35 -0600 Subject: [PATCH 8/8] Touch docs (#67) * Suggest use of native type names * Update intro paragraphs This excellent contribution is from @gregtucker. --- docs/source/bmi.spec.rst | 47 +++++++++++++++++++++++------------ docs/source/bmi.var_funcs.rst | 6 +++-- 2 files changed, 35 insertions(+), 18 deletions(-) diff --git a/docs/source/bmi.spec.rst b/docs/source/bmi.spec.rst index d51fde7..dbfe599 100644 --- a/docs/source/bmi.spec.rst +++ b/docs/source/bmi.spec.rst @@ -1,19 +1,34 @@ -The *Basic Model Interface* (BMI) is a library specification -created by the `Community Surface Dynamics Modeling System`_ (CSDMS) -to facilitate the conversion of a model or dataset -into a reusable, plug-and-play component. -Recall that, in this context, an interface is a named set of functions -with prescribed arguments and return values. -The BMI functions make a model self-describing and fully controllable -by a modeling framework or application. -By design, the BMI functions are straightforward to implement in -any language, using only simple data types from standard language libraries. -Also by design, the BMI functions are noninvasive. -This means that a model's BMI does not make calls to other -components or tools and is not modified to use any -framework-specific data structures. A BMI, therefore, introduces no -dependencies into a model, so the model can still be used -in a stand-alone manner. +When you climb in the driver's seat of an unfamiliar car, +you are nonetheless presented with a familiar sight. +Whatever the make or model may be, +we take it for granted that the vehicle will provide +a steering wheel, brake pedal, and speedometer, +alongside the various other controls and readouts +that are common to essentially all cars and trucks on the planet. +Although we don't usually think of it this way, +drivers across the globe benefit from a standard interface: +a set of control mechanisms and information displays +that have essentially the same design regardless of whether the vehicle +is a tiny electric two-seater or a giant stretch limousine. +This standard interface makes the job of operating a vehicle much easier +than it would be if each one presented a radically different interface. +Imagine a world where switching from a sports car to a pickup truck +required months of study and practice! +Similarly, railroads benefit from a standard for coupling rail cars together. +The result: trains can be assembled from combinations of all sorts +of different rail cars, built by different companies, +in different places, and with different purposes. + +We believe that numerical models, +and the sub-components that make up those models, +should offer a similar kind of standardization. +To this end, +the `Community Surface Dynamics Modeling System`_ (CSDMS) +has developed the *Basic Model Interface* (BMI): +a set of standard control and query functions that, +when added to a model code, +make that model both easier to learn +and easier to couple with other software elements. While a BMI can be written for any language, CSDMS currently supports four languages: diff --git a/docs/source/bmi.var_funcs.rst b/docs/source/bmi.var_funcs.rst index 24c93b8..73759db 100644 --- a/docs/source/bmi.var_funcs.rst +++ b/docs/source/bmi.var_funcs.rst @@ -52,8 +52,10 @@ A model can have one or more grids. The `get_var_type` function provides the data type of the variable as it's stored in memory by the model. -The data type is returned as a string following the :term:`numpy` convention -used by the `dtype`_ attribute; e.g., `int32`, `float`, etc. +The data type is returned as a string. +Use of native language type names is encouraged; +e.g., in C, use `int`, `float`, and `double`, +while in Fortran, use `integer`, `real`, and `double precision`. **Implementation notes**